1de941241SSukumar Ghorai /* 2de941241SSukumar Ghorai * (C) Copyright 2008 3de941241SSukumar Ghorai * Texas Instruments, <www.ti.com> 4de941241SSukumar Ghorai * Sukumar Ghorai <s-ghorai@ti.com> 5de941241SSukumar Ghorai * 6de941241SSukumar Ghorai * See file CREDITS for list of people who contributed to this 7de941241SSukumar Ghorai * project. 8de941241SSukumar Ghorai * 9de941241SSukumar Ghorai * This program is free software; you can redistribute it and/or 10de941241SSukumar Ghorai * modify it under the terms of the GNU General Public License as 11de941241SSukumar Ghorai * published by the Free Software Foundation's version 2 of 12de941241SSukumar Ghorai * the License. 13de941241SSukumar Ghorai * 14de941241SSukumar Ghorai * This program is distributed in the hope that it will be useful, 15de941241SSukumar Ghorai * but WITHOUT ANY WARRANTY; without even the implied warranty of 16de941241SSukumar Ghorai * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17de941241SSukumar Ghorai * GNU General Public License for more details. 18de941241SSukumar Ghorai * 19de941241SSukumar Ghorai * You should have received a copy of the GNU General Public License 20de941241SSukumar Ghorai * along with this program; if not, write to the Free Software 21de941241SSukumar Ghorai * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22de941241SSukumar Ghorai * MA 02111-1307 USA 23de941241SSukumar Ghorai */ 24de941241SSukumar Ghorai 25de941241SSukumar Ghorai #include <config.h> 26de941241SSukumar Ghorai #include <common.h> 27de941241SSukumar Ghorai #include <mmc.h> 28de941241SSukumar Ghorai #include <part.h> 29de941241SSukumar Ghorai #include <i2c.h> 30de941241SSukumar Ghorai #include <twl4030.h> 31de941241SSukumar Ghorai #include <asm/io.h> 32de941241SSukumar Ghorai #include <asm/arch/mmc_host_def.h> 3396e0e7b3SDirk Behme #include <asm/arch/sys_proto.h> 34de941241SSukumar Ghorai 35eb9a28f6SNishanth Menon /* If we fail after 1 second wait, something is really bad */ 36eb9a28f6SNishanth Menon #define MAX_RETRY_MS 1000 37eb9a28f6SNishanth Menon 38de941241SSukumar Ghorai static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size); 39de941241SSukumar Ghorai static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int siz); 40de941241SSukumar Ghorai static struct mmc hsmmc_dev[2]; 41de941241SSukumar Ghorai unsigned char mmc_board_init(hsmmc_t *mmc_base) 42de941241SSukumar Ghorai { 43de941241SSukumar Ghorai #if defined(CONFIG_TWL4030_POWER) 44de941241SSukumar Ghorai twl4030_power_mmc_init(); 45de941241SSukumar Ghorai #endif 46de941241SSukumar Ghorai 47de941241SSukumar Ghorai #if defined(CONFIG_OMAP34XX) 48de941241SSukumar Ghorai t2_t *t2_base = (t2_t *)T2_BASE; 49de941241SSukumar Ghorai struct prcm *prcm_base = (struct prcm *)PRCM_BASE; 50de941241SSukumar Ghorai 51de941241SSukumar Ghorai writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 | 52de941241SSukumar Ghorai PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0, 53de941241SSukumar Ghorai &t2_base->pbias_lite); 54de941241SSukumar Ghorai 55de941241SSukumar Ghorai writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL, 56de941241SSukumar Ghorai &t2_base->devconf0); 57de941241SSukumar Ghorai 58de941241SSukumar Ghorai writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL, 59de941241SSukumar Ghorai &t2_base->devconf1); 60de941241SSukumar Ghorai 61de941241SSukumar Ghorai writel(readl(&prcm_base->fclken1_core) | 62de941241SSukumar Ghorai EN_MMC1 | EN_MMC2 | EN_MMC3, 63de941241SSukumar Ghorai &prcm_base->fclken1_core); 64de941241SSukumar Ghorai 65de941241SSukumar Ghorai writel(readl(&prcm_base->iclken1_core) | 66de941241SSukumar Ghorai EN_MMC1 | EN_MMC2 | EN_MMC3, 67de941241SSukumar Ghorai &prcm_base->iclken1_core); 68de941241SSukumar Ghorai #endif 69de941241SSukumar Ghorai 70de941241SSukumar Ghorai /* TODO add appropriate OMAP4 init - none currently necessary */ 71de941241SSukumar Ghorai 72de941241SSukumar Ghorai return 0; 73de941241SSukumar Ghorai } 74de941241SSukumar Ghorai 75de941241SSukumar Ghorai void mmc_init_stream(hsmmc_t *mmc_base) 76de941241SSukumar Ghorai { 77eb9a28f6SNishanth Menon ulong start; 78de941241SSukumar Ghorai 79de941241SSukumar Ghorai writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con); 80de941241SSukumar Ghorai 81de941241SSukumar Ghorai writel(MMC_CMD0, &mmc_base->cmd); 82eb9a28f6SNishanth Menon start = get_timer(0); 83eb9a28f6SNishanth Menon while (!(readl(&mmc_base->stat) & CC_MASK)) { 84eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 85eb9a28f6SNishanth Menon printf("%s: timedout waiting for cc!\n", __func__); 86eb9a28f6SNishanth Menon return; 87eb9a28f6SNishanth Menon } 88eb9a28f6SNishanth Menon } 89de941241SSukumar Ghorai writel(CC_MASK, &mmc_base->stat) 90de941241SSukumar Ghorai ; 91de941241SSukumar Ghorai writel(MMC_CMD0, &mmc_base->cmd) 92de941241SSukumar Ghorai ; 93eb9a28f6SNishanth Menon start = get_timer(0); 94eb9a28f6SNishanth Menon while (!(readl(&mmc_base->stat) & CC_MASK)) { 95eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 96eb9a28f6SNishanth Menon printf("%s: timedout waiting for cc2!\n", __func__); 97eb9a28f6SNishanth Menon return; 98eb9a28f6SNishanth Menon } 99eb9a28f6SNishanth Menon } 100de941241SSukumar Ghorai writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con); 101de941241SSukumar Ghorai } 102de941241SSukumar Ghorai 103de941241SSukumar Ghorai 104de941241SSukumar Ghorai static int mmc_init_setup(struct mmc *mmc) 105de941241SSukumar Ghorai { 106de941241SSukumar Ghorai hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv; 107de941241SSukumar Ghorai unsigned int reg_val; 108de941241SSukumar Ghorai unsigned int dsor; 109eb9a28f6SNishanth Menon ulong start; 110de941241SSukumar Ghorai 111de941241SSukumar Ghorai mmc_board_init(mmc_base); 112de941241SSukumar Ghorai 113de941241SSukumar Ghorai writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET, 114de941241SSukumar Ghorai &mmc_base->sysconfig); 115eb9a28f6SNishanth Menon start = get_timer(0); 116eb9a28f6SNishanth Menon while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) { 117eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 118eb9a28f6SNishanth Menon printf("%s: timedout waiting for cc2!\n", __func__); 119eb9a28f6SNishanth Menon return TIMEOUT; 120eb9a28f6SNishanth Menon } 121eb9a28f6SNishanth Menon } 122de941241SSukumar Ghorai writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl); 123eb9a28f6SNishanth Menon start = get_timer(0); 124eb9a28f6SNishanth Menon while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) { 125eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 126eb9a28f6SNishanth Menon printf("%s: timedout waiting for softresetall!\n", 127eb9a28f6SNishanth Menon __func__); 128eb9a28f6SNishanth Menon return TIMEOUT; 129eb9a28f6SNishanth Menon } 130eb9a28f6SNishanth Menon } 131de941241SSukumar Ghorai writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl); 132de941241SSukumar Ghorai writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP, 133de941241SSukumar Ghorai &mmc_base->capa); 134de941241SSukumar Ghorai 135de941241SSukumar Ghorai reg_val = readl(&mmc_base->con) & RESERVED_MASK; 136de941241SSukumar Ghorai 137de941241SSukumar Ghorai writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH | 138de941241SSukumar Ghorai MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK | 139de941241SSukumar Ghorai HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con); 140de941241SSukumar Ghorai 141de941241SSukumar Ghorai dsor = 240; 142de941241SSukumar Ghorai mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), 143de941241SSukumar Ghorai (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); 144de941241SSukumar Ghorai mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, 145de941241SSukumar Ghorai (dsor << CLKD_OFFSET) | ICE_OSCILLATE); 146eb9a28f6SNishanth Menon start = get_timer(0); 147eb9a28f6SNishanth Menon while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { 148eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 149eb9a28f6SNishanth Menon printf("%s: timedout waiting for ics!\n", __func__); 150eb9a28f6SNishanth Menon return TIMEOUT; 151eb9a28f6SNishanth Menon } 152eb9a28f6SNishanth Menon } 153de941241SSukumar Ghorai writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); 154de941241SSukumar Ghorai 155de941241SSukumar Ghorai writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl); 156de941241SSukumar Ghorai 157de941241SSukumar Ghorai writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE | 158de941241SSukumar Ghorai IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC, 159de941241SSukumar Ghorai &mmc_base->ie); 160de941241SSukumar Ghorai 161de941241SSukumar Ghorai mmc_init_stream(mmc_base); 162de941241SSukumar Ghorai 163de941241SSukumar Ghorai return 0; 164de941241SSukumar Ghorai } 165de941241SSukumar Ghorai 166de941241SSukumar Ghorai 167de941241SSukumar Ghorai static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, 168de941241SSukumar Ghorai struct mmc_data *data) 169de941241SSukumar Ghorai { 170de941241SSukumar Ghorai hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv; 171de941241SSukumar Ghorai unsigned int flags, mmc_stat; 172eb9a28f6SNishanth Menon ulong start; 173de941241SSukumar Ghorai 174eb9a28f6SNishanth Menon start = get_timer(0); 175eb9a28f6SNishanth Menon while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) { 176eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 177eb9a28f6SNishanth Menon printf("%s: timedout waiting for cmddis!\n", __func__); 178eb9a28f6SNishanth Menon return TIMEOUT; 179eb9a28f6SNishanth Menon } 180eb9a28f6SNishanth Menon } 181de941241SSukumar Ghorai writel(0xFFFFFFFF, &mmc_base->stat); 182eb9a28f6SNishanth Menon start = get_timer(0); 183eb9a28f6SNishanth Menon while (readl(&mmc_base->stat)) { 184eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 185eb9a28f6SNishanth Menon printf("%s: timedout waiting for stat!\n", __func__); 186eb9a28f6SNishanth Menon return TIMEOUT; 187eb9a28f6SNishanth Menon } 188eb9a28f6SNishanth Menon } 189de941241SSukumar Ghorai /* 190de941241SSukumar Ghorai * CMDREG 191de941241SSukumar Ghorai * CMDIDX[13:8] : Command index 192de941241SSukumar Ghorai * DATAPRNT[5] : Data Present Select 193de941241SSukumar Ghorai * ENCMDIDX[4] : Command Index Check Enable 194de941241SSukumar Ghorai * ENCMDCRC[3] : Command CRC Check Enable 195de941241SSukumar Ghorai * RSPTYP[1:0] 196de941241SSukumar Ghorai * 00 = No Response 197de941241SSukumar Ghorai * 01 = Length 136 198de941241SSukumar Ghorai * 10 = Length 48 199de941241SSukumar Ghorai * 11 = Length 48 Check busy after response 200de941241SSukumar Ghorai */ 201de941241SSukumar Ghorai /* Delay added before checking the status of frq change 202de941241SSukumar Ghorai * retry not supported by mmc.c(core file) 203de941241SSukumar Ghorai */ 204de941241SSukumar Ghorai if (cmd->cmdidx == SD_CMD_APP_SEND_SCR) 205de941241SSukumar Ghorai udelay(50000); /* wait 50 ms */ 206de941241SSukumar Ghorai 207de941241SSukumar Ghorai if (!(cmd->resp_type & MMC_RSP_PRESENT)) 208de941241SSukumar Ghorai flags = 0; 209de941241SSukumar Ghorai else if (cmd->resp_type & MMC_RSP_136) 210de941241SSukumar Ghorai flags = RSP_TYPE_LGHT136 | CICE_NOCHECK; 211de941241SSukumar Ghorai else if (cmd->resp_type & MMC_RSP_BUSY) 212de941241SSukumar Ghorai flags = RSP_TYPE_LGHT48B; 213de941241SSukumar Ghorai else 214de941241SSukumar Ghorai flags = RSP_TYPE_LGHT48; 215de941241SSukumar Ghorai 216de941241SSukumar Ghorai /* enable default flags */ 217de941241SSukumar Ghorai flags = flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK | 218de941241SSukumar Ghorai MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE); 219de941241SSukumar Ghorai 220de941241SSukumar Ghorai if (cmd->resp_type & MMC_RSP_CRC) 221de941241SSukumar Ghorai flags |= CCCE_CHECK; 222de941241SSukumar Ghorai if (cmd->resp_type & MMC_RSP_OPCODE) 223de941241SSukumar Ghorai flags |= CICE_CHECK; 224de941241SSukumar Ghorai 225de941241SSukumar Ghorai if (data) { 226de941241SSukumar Ghorai if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) || 227de941241SSukumar Ghorai (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) { 228de941241SSukumar Ghorai flags |= (MSBS_MULTIBLK | BCE_ENABLE); 229de941241SSukumar Ghorai data->blocksize = 512; 230de941241SSukumar Ghorai writel(data->blocksize | (data->blocks << 16), 231de941241SSukumar Ghorai &mmc_base->blk); 232de941241SSukumar Ghorai } else 233de941241SSukumar Ghorai writel(data->blocksize | NBLK_STPCNT, &mmc_base->blk); 234de941241SSukumar Ghorai 235de941241SSukumar Ghorai if (data->flags & MMC_DATA_READ) 236de941241SSukumar Ghorai flags |= (DP_DATA | DDIR_READ); 237de941241SSukumar Ghorai else 238de941241SSukumar Ghorai flags |= (DP_DATA | DDIR_WRITE); 239de941241SSukumar Ghorai } 240de941241SSukumar Ghorai 241de941241SSukumar Ghorai writel(cmd->cmdarg, &mmc_base->arg); 242de941241SSukumar Ghorai writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd); 243de941241SSukumar Ghorai 244eb9a28f6SNishanth Menon start = get_timer(0); 245de941241SSukumar Ghorai do { 246de941241SSukumar Ghorai mmc_stat = readl(&mmc_base->stat); 247eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 248de941241SSukumar Ghorai printf("%s : timeout: No status update\n", __func__); 249de941241SSukumar Ghorai return TIMEOUT; 250de941241SSukumar Ghorai } 251eb9a28f6SNishanth Menon } while (!mmc_stat); 252de941241SSukumar Ghorai 253de941241SSukumar Ghorai if ((mmc_stat & IE_CTO) != 0) 254de941241SSukumar Ghorai return TIMEOUT; 255de941241SSukumar Ghorai else if ((mmc_stat & ERRI_MASK) != 0) 256de941241SSukumar Ghorai return -1; 257de941241SSukumar Ghorai 258de941241SSukumar Ghorai if (mmc_stat & CC_MASK) { 259de941241SSukumar Ghorai writel(CC_MASK, &mmc_base->stat); 260de941241SSukumar Ghorai if (cmd->resp_type & MMC_RSP_PRESENT) { 261de941241SSukumar Ghorai if (cmd->resp_type & MMC_RSP_136) { 262de941241SSukumar Ghorai /* response type 2 */ 263de941241SSukumar Ghorai cmd->response[3] = readl(&mmc_base->rsp10); 264de941241SSukumar Ghorai cmd->response[2] = readl(&mmc_base->rsp32); 265de941241SSukumar Ghorai cmd->response[1] = readl(&mmc_base->rsp54); 266de941241SSukumar Ghorai cmd->response[0] = readl(&mmc_base->rsp76); 267de941241SSukumar Ghorai } else 268de941241SSukumar Ghorai /* response types 1, 1b, 3, 4, 5, 6 */ 269de941241SSukumar Ghorai cmd->response[0] = readl(&mmc_base->rsp10); 270de941241SSukumar Ghorai } 271de941241SSukumar Ghorai } 272de941241SSukumar Ghorai 273de941241SSukumar Ghorai if (data && (data->flags & MMC_DATA_READ)) { 274de941241SSukumar Ghorai mmc_read_data(mmc_base, data->dest, 275de941241SSukumar Ghorai data->blocksize * data->blocks); 276de941241SSukumar Ghorai } else if (data && (data->flags & MMC_DATA_WRITE)) { 277de941241SSukumar Ghorai mmc_write_data(mmc_base, data->src, 278de941241SSukumar Ghorai data->blocksize * data->blocks); 279de941241SSukumar Ghorai } 280de941241SSukumar Ghorai return 0; 281de941241SSukumar Ghorai } 282de941241SSukumar Ghorai 283de941241SSukumar Ghorai static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size) 284de941241SSukumar Ghorai { 285de941241SSukumar Ghorai unsigned int *output_buf = (unsigned int *)buf; 286de941241SSukumar Ghorai unsigned int mmc_stat; 287de941241SSukumar Ghorai unsigned int count; 288de941241SSukumar Ghorai 289de941241SSukumar Ghorai /* 290de941241SSukumar Ghorai * Start Polled Read 291de941241SSukumar Ghorai */ 292de941241SSukumar Ghorai count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size; 293de941241SSukumar Ghorai count /= 4; 294de941241SSukumar Ghorai 295de941241SSukumar Ghorai while (size) { 296eb9a28f6SNishanth Menon ulong start = get_timer(0); 297de941241SSukumar Ghorai do { 298de941241SSukumar Ghorai mmc_stat = readl(&mmc_base->stat); 299eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 300eb9a28f6SNishanth Menon printf("%s: timedout waiting for status!\n", 301eb9a28f6SNishanth Menon __func__); 302eb9a28f6SNishanth Menon return TIMEOUT; 303eb9a28f6SNishanth Menon } 304de941241SSukumar Ghorai } while (mmc_stat == 0); 305de941241SSukumar Ghorai 306de941241SSukumar Ghorai if ((mmc_stat & ERRI_MASK) != 0) 307de941241SSukumar Ghorai return 1; 308de941241SSukumar Ghorai 309de941241SSukumar Ghorai if (mmc_stat & BRR_MASK) { 310de941241SSukumar Ghorai unsigned int k; 311de941241SSukumar Ghorai 312de941241SSukumar Ghorai writel(readl(&mmc_base->stat) | BRR_MASK, 313de941241SSukumar Ghorai &mmc_base->stat); 314de941241SSukumar Ghorai for (k = 0; k < count; k++) { 315de941241SSukumar Ghorai *output_buf = readl(&mmc_base->data); 316de941241SSukumar Ghorai output_buf++; 317de941241SSukumar Ghorai } 318de941241SSukumar Ghorai size -= (count*4); 319de941241SSukumar Ghorai } 320de941241SSukumar Ghorai 321de941241SSukumar Ghorai if (mmc_stat & BWR_MASK) 322de941241SSukumar Ghorai writel(readl(&mmc_base->stat) | BWR_MASK, 323de941241SSukumar Ghorai &mmc_base->stat); 324de941241SSukumar Ghorai 325de941241SSukumar Ghorai if (mmc_stat & TC_MASK) { 326de941241SSukumar Ghorai writel(readl(&mmc_base->stat) | TC_MASK, 327de941241SSukumar Ghorai &mmc_base->stat); 328de941241SSukumar Ghorai break; 329de941241SSukumar Ghorai } 330de941241SSukumar Ghorai } 331de941241SSukumar Ghorai return 0; 332de941241SSukumar Ghorai } 333de941241SSukumar Ghorai 334de941241SSukumar Ghorai static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int size) 335de941241SSukumar Ghorai { 336de941241SSukumar Ghorai unsigned int *input_buf = (unsigned int *)buf; 337de941241SSukumar Ghorai unsigned int mmc_stat; 338de941241SSukumar Ghorai unsigned int count; 339de941241SSukumar Ghorai 340de941241SSukumar Ghorai /* 341de941241SSukumar Ghorai * Start Polled Read 342de941241SSukumar Ghorai */ 343de941241SSukumar Ghorai count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size; 344de941241SSukumar Ghorai count /= 4; 345de941241SSukumar Ghorai 346de941241SSukumar Ghorai while (size) { 347eb9a28f6SNishanth Menon ulong start = get_timer(0); 348de941241SSukumar Ghorai do { 349de941241SSukumar Ghorai mmc_stat = readl(&mmc_base->stat); 350eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 351eb9a28f6SNishanth Menon printf("%s: timedout waiting for status!\n", 352eb9a28f6SNishanth Menon __func__); 353eb9a28f6SNishanth Menon return TIMEOUT; 354eb9a28f6SNishanth Menon } 355de941241SSukumar Ghorai } while (mmc_stat == 0); 356de941241SSukumar Ghorai 357de941241SSukumar Ghorai if ((mmc_stat & ERRI_MASK) != 0) 358de941241SSukumar Ghorai return 1; 359de941241SSukumar Ghorai 360de941241SSukumar Ghorai if (mmc_stat & BWR_MASK) { 361de941241SSukumar Ghorai unsigned int k; 362de941241SSukumar Ghorai 363de941241SSukumar Ghorai writel(readl(&mmc_base->stat) | BWR_MASK, 364de941241SSukumar Ghorai &mmc_base->stat); 365de941241SSukumar Ghorai for (k = 0; k < count; k++) { 366de941241SSukumar Ghorai writel(*input_buf, &mmc_base->data); 367de941241SSukumar Ghorai input_buf++; 368de941241SSukumar Ghorai } 369de941241SSukumar Ghorai size -= (count*4); 370de941241SSukumar Ghorai } 371de941241SSukumar Ghorai 372de941241SSukumar Ghorai if (mmc_stat & BRR_MASK) 373de941241SSukumar Ghorai writel(readl(&mmc_base->stat) | BRR_MASK, 374de941241SSukumar Ghorai &mmc_base->stat); 375de941241SSukumar Ghorai 376de941241SSukumar Ghorai if (mmc_stat & TC_MASK) { 377de941241SSukumar Ghorai writel(readl(&mmc_base->stat) | TC_MASK, 378de941241SSukumar Ghorai &mmc_base->stat); 379de941241SSukumar Ghorai break; 380de941241SSukumar Ghorai } 381de941241SSukumar Ghorai } 382de941241SSukumar Ghorai return 0; 383de941241SSukumar Ghorai } 384de941241SSukumar Ghorai 385de941241SSukumar Ghorai static void mmc_set_ios(struct mmc *mmc) 386de941241SSukumar Ghorai { 387de941241SSukumar Ghorai hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv; 388de941241SSukumar Ghorai unsigned int dsor = 0; 389eb9a28f6SNishanth Menon ulong start; 390de941241SSukumar Ghorai 391de941241SSukumar Ghorai /* configue bus width */ 392de941241SSukumar Ghorai switch (mmc->bus_width) { 393de941241SSukumar Ghorai case 8: 394de941241SSukumar Ghorai writel(readl(&mmc_base->con) | DTW_8_BITMODE, 395de941241SSukumar Ghorai &mmc_base->con); 396de941241SSukumar Ghorai break; 397de941241SSukumar Ghorai 398de941241SSukumar Ghorai case 4: 399de941241SSukumar Ghorai writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, 400de941241SSukumar Ghorai &mmc_base->con); 401de941241SSukumar Ghorai writel(readl(&mmc_base->hctl) | DTW_4_BITMODE, 402de941241SSukumar Ghorai &mmc_base->hctl); 403de941241SSukumar Ghorai break; 404de941241SSukumar Ghorai 405de941241SSukumar Ghorai case 1: 406de941241SSukumar Ghorai default: 407de941241SSukumar Ghorai writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, 408de941241SSukumar Ghorai &mmc_base->con); 409de941241SSukumar Ghorai writel(readl(&mmc_base->hctl) & ~DTW_4_BITMODE, 410de941241SSukumar Ghorai &mmc_base->hctl); 411de941241SSukumar Ghorai break; 412de941241SSukumar Ghorai } 413de941241SSukumar Ghorai 414de941241SSukumar Ghorai /* configure clock with 96Mhz system clock. 415de941241SSukumar Ghorai */ 416de941241SSukumar Ghorai if (mmc->clock != 0) { 417de941241SSukumar Ghorai dsor = (MMC_CLOCK_REFERENCE * 1000000 / mmc->clock); 418de941241SSukumar Ghorai if ((MMC_CLOCK_REFERENCE * 1000000) / dsor > mmc->clock) 419de941241SSukumar Ghorai dsor++; 420de941241SSukumar Ghorai } 421de941241SSukumar Ghorai 422de941241SSukumar Ghorai mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), 423de941241SSukumar Ghorai (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); 424de941241SSukumar Ghorai 425de941241SSukumar Ghorai mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, 426de941241SSukumar Ghorai (dsor << CLKD_OFFSET) | ICE_OSCILLATE); 427de941241SSukumar Ghorai 428eb9a28f6SNishanth Menon start = get_timer(0); 429eb9a28f6SNishanth Menon while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { 430eb9a28f6SNishanth Menon if (get_timer(0) - start > MAX_RETRY_MS) { 431eb9a28f6SNishanth Menon printf("%s: timedout waiting for ics!\n", __func__); 432eb9a28f6SNishanth Menon return; 433eb9a28f6SNishanth Menon } 434eb9a28f6SNishanth Menon } 435de941241SSukumar Ghorai writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); 436de941241SSukumar Ghorai } 437de941241SSukumar Ghorai 438de941241SSukumar Ghorai int omap_mmc_init(int dev_index) 439de941241SSukumar Ghorai { 440de941241SSukumar Ghorai struct mmc *mmc; 441de941241SSukumar Ghorai 442de941241SSukumar Ghorai mmc = &hsmmc_dev[dev_index]; 443de941241SSukumar Ghorai 444de941241SSukumar Ghorai sprintf(mmc->name, "OMAP SD/MMC"); 445de941241SSukumar Ghorai mmc->send_cmd = mmc_send_cmd; 446de941241SSukumar Ghorai mmc->set_ios = mmc_set_ios; 447de941241SSukumar Ghorai mmc->init = mmc_init_setup; 448de941241SSukumar Ghorai 449de941241SSukumar Ghorai switch (dev_index) { 450de941241SSukumar Ghorai case 0: 451de941241SSukumar Ghorai mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE; 452de941241SSukumar Ghorai break; 453de941241SSukumar Ghorai case 1: 454de941241SSukumar Ghorai mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE; 455de941241SSukumar Ghorai break; 456de941241SSukumar Ghorai case 2: 457de941241SSukumar Ghorai mmc->priv = (hsmmc_t *)OMAP_HSMMC3_BASE; 458de941241SSukumar Ghorai break; 459de941241SSukumar Ghorai default: 460de941241SSukumar Ghorai mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE; 461de941241SSukumar Ghorai return 1; 462de941241SSukumar Ghorai } 463de941241SSukumar Ghorai mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; 464*ecd9af88SBalaji T K mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS | 465*ecd9af88SBalaji T K MMC_MODE_HC; 466de941241SSukumar Ghorai 467de941241SSukumar Ghorai mmc->f_min = 400000; 468de941241SSukumar Ghorai mmc->f_max = 52000000; 469de941241SSukumar Ghorai 4708feafcc4SJohn Rigby mmc->b_max = 0; 4718feafcc4SJohn Rigby 4724ca9244dSJohn Rigby #if defined(CONFIG_OMAP34XX) 4734ca9244dSJohn Rigby /* 4744ca9244dSJohn Rigby * Silicon revs 2.1 and older do not support multiblock transfers. 4754ca9244dSJohn Rigby */ 4764ca9244dSJohn Rigby if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21)) 4774ca9244dSJohn Rigby mmc->b_max = 1; 4784ca9244dSJohn Rigby #endif 4794ca9244dSJohn Rigby 480de941241SSukumar Ghorai mmc_register(mmc); 481de941241SSukumar Ghorai 482de941241SSukumar Ghorai return 0; 483de941241SSukumar Ghorai } 484