Home | History | Annotate | Download | only in mmc
      1 /*
      2  *  This is a driver for the SDHC controller found in Freescale MX2/MX3
      3  *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
      4  *  Unlike the hardware found on MX1, this hardware just works and does
      5  *  not need all the quirks found in imxmmc.c, hence the seperate driver.
      6  *
      7  *  Copyright (C) 2009 Ilya Yanok, <yanok (at) emcraft.com>
      8  *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer (at) pengutronix.de>
      9  *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa (at) pikron.com>
     10  *
     11  *  derived from pxamci.c by Russell King
     12  *
     13  * This program is free software; you can redistribute it and/or modify
     14  * it under the terms of the GNU General Public License version 2 as
     15  * published by the Free Software Foundation.
     16  *
     17  */
     18 
     19 #include <config.h>
     20 #include <common.h>
     21 #include <command.h>
     22 #include <mmc.h>
     23 #include <part.h>
     24 #include <malloc.h>
     25 #include <mmc.h>
     26 #include <linux/errno.h>
     27 #include <asm/io.h>
     28 #include <asm/arch/clock.h>
     29 
     30 #define DRIVER_NAME "mxc-mmc"
     31 
     32 struct mxcmci_regs {
     33 	u32 str_stp_clk;
     34 	u32 status;
     35 	u32 clk_rate;
     36 	u32 cmd_dat_cont;
     37 	u32 res_to;
     38 	u32 read_to;
     39 	u32 blk_len;
     40 	u32 nob;
     41 	u32 rev_no;
     42 	u32 int_cntr;
     43 	u32 cmd;
     44 	u32 arg;
     45 	u32 pad;
     46 	u32 res_fifo;
     47 	u32 buffer_access;
     48 };
     49 
     50 #define STR_STP_CLK_RESET               (1 << 3)
     51 #define STR_STP_CLK_START_CLK           (1 << 1)
     52 #define STR_STP_CLK_STOP_CLK            (1 << 0)
     53 
     54 #define STATUS_CARD_INSERTION		(1 << 31)
     55 #define STATUS_CARD_REMOVAL		(1 << 30)
     56 #define STATUS_YBUF_EMPTY		(1 << 29)
     57 #define STATUS_XBUF_EMPTY		(1 << 28)
     58 #define STATUS_YBUF_FULL		(1 << 27)
     59 #define STATUS_XBUF_FULL		(1 << 26)
     60 #define STATUS_BUF_UND_RUN		(1 << 25)
     61 #define STATUS_BUF_OVFL			(1 << 24)
     62 #define STATUS_SDIO_INT_ACTIVE		(1 << 14)
     63 #define STATUS_END_CMD_RESP		(1 << 13)
     64 #define STATUS_WRITE_OP_DONE		(1 << 12)
     65 #define STATUS_DATA_TRANS_DONE		(1 << 11)
     66 #define STATUS_READ_OP_DONE		(1 << 11)
     67 #define STATUS_WR_CRC_ERROR_CODE_MASK	(3 << 10)
     68 #define STATUS_CARD_BUS_CLK_RUN		(1 << 8)
     69 #define STATUS_BUF_READ_RDY		(1 << 7)
     70 #define STATUS_BUF_WRITE_RDY		(1 << 6)
     71 #define STATUS_RESP_CRC_ERR		(1 << 5)
     72 #define STATUS_CRC_READ_ERR		(1 << 3)
     73 #define STATUS_CRC_WRITE_ERR		(1 << 2)
     74 #define STATUS_TIME_OUT_RESP		(1 << 1)
     75 #define STATUS_TIME_OUT_READ		(1 << 0)
     76 #define STATUS_ERR_MASK			0x2f
     77 
     78 #define CMD_DAT_CONT_CMD_RESP_LONG_OFF	(1 << 12)
     79 #define CMD_DAT_CONT_STOP_READWAIT	(1 << 11)
     80 #define CMD_DAT_CONT_START_READWAIT	(1 << 10)
     81 #define CMD_DAT_CONT_BUS_WIDTH_4	(2 << 8)
     82 #define CMD_DAT_CONT_INIT		(1 << 7)
     83 #define CMD_DAT_CONT_WRITE		(1 << 4)
     84 #define CMD_DAT_CONT_DATA_ENABLE	(1 << 3)
     85 #define CMD_DAT_CONT_RESPONSE_48BIT_CRC	(1 << 0)
     86 #define CMD_DAT_CONT_RESPONSE_136BIT	(2 << 0)
     87 #define CMD_DAT_CONT_RESPONSE_48BIT	(3 << 0)
     88 
     89 #define INT_SDIO_INT_WKP_EN		(1 << 18)
     90 #define INT_CARD_INSERTION_WKP_EN	(1 << 17)
     91 #define INT_CARD_REMOVAL_WKP_EN		(1 << 16)
     92 #define INT_CARD_INSERTION_EN		(1 << 15)
     93 #define INT_CARD_REMOVAL_EN		(1 << 14)
     94 #define INT_SDIO_IRQ_EN			(1 << 13)
     95 #define INT_DAT0_EN			(1 << 12)
     96 #define INT_BUF_READ_EN			(1 << 4)
     97 #define INT_BUF_WRITE_EN		(1 << 3)
     98 #define INT_END_CMD_RES_EN		(1 << 2)
     99 #define INT_WRITE_OP_DONE_EN		(1 << 1)
    100 #define INT_READ_OP_EN			(1 << 0)
    101 
    102 struct mxcmci_host {
    103 	struct mmc		*mmc;
    104 	struct mxcmci_regs	*base;
    105 	int			irq;
    106 	int			detect_irq;
    107 	int			dma;
    108 	int			do_dma;
    109 	unsigned int		power_mode;
    110 
    111 	struct mmc_cmd		*cmd;
    112 	struct mmc_data		*data;
    113 
    114 	unsigned int		dma_nents;
    115 	unsigned int		datasize;
    116 	unsigned int		dma_dir;
    117 
    118 	u16			rev_no;
    119 	unsigned int		cmdat;
    120 
    121 	int			clock;
    122 };
    123 
    124 static struct mxcmci_host mxcmci_host;
    125 
    126 /* maintainer note: do we really want to have a global host pointer? */
    127 static struct mxcmci_host *host = &mxcmci_host;
    128 
    129 static inline int mxcmci_use_dma(struct mxcmci_host *host)
    130 {
    131 	return host->do_dma;
    132 }
    133 
    134 static void mxcmci_softreset(struct mxcmci_host *host)
    135 {
    136 	int i;
    137 
    138 	/* reset sequence */
    139 	writel(STR_STP_CLK_RESET, &host->base->str_stp_clk);
    140 	writel(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
    141 			&host->base->str_stp_clk);
    142 
    143 	for (i = 0; i < 8; i++)
    144 		writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
    145 
    146 	writel(0xff, &host->base->res_to);
    147 }
    148 
    149 static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
    150 {
    151 	unsigned int nob = data->blocks;
    152 	unsigned int blksz = data->blocksize;
    153 	unsigned int datasize = nob * blksz;
    154 
    155 	host->data = data;
    156 
    157 	writel(nob, &host->base->nob);
    158 	writel(blksz, &host->base->blk_len);
    159 	host->datasize = datasize;
    160 }
    161 
    162 static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_cmd *cmd,
    163 		unsigned int cmdat)
    164 {
    165 	if (host->cmd != NULL)
    166 		printf("mxcmci: error!\n");
    167 	host->cmd = cmd;
    168 
    169 	switch (cmd->resp_type) {
    170 	case MMC_RSP_R1: /* short CRC, OPCODE */
    171 	case MMC_RSP_R1b:/* short CRC, OPCODE, BUSY */
    172 		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
    173 		break;
    174 	case MMC_RSP_R2: /* long 136 bit + CRC */
    175 		cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
    176 		break;
    177 	case MMC_RSP_R3: /* short */
    178 		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
    179 		break;
    180 	case MMC_RSP_NONE:
    181 		break;
    182 	default:
    183 		printf("mxcmci: unhandled response type 0x%x\n",
    184 				cmd->resp_type);
    185 		return -EINVAL;
    186 	}
    187 
    188 	writel(cmd->cmdidx, &host->base->cmd);
    189 	writel(cmd->cmdarg, &host->base->arg);
    190 	writel(cmdat, &host->base->cmd_dat_cont);
    191 
    192 	return 0;
    193 }
    194 
    195 static void mxcmci_finish_request(struct mxcmci_host *host,
    196 		struct mmc_cmd *cmd, struct mmc_data *data)
    197 {
    198 	host->cmd = NULL;
    199 	host->data = NULL;
    200 }
    201 
    202 static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
    203 {
    204 	int data_error = 0;
    205 
    206 	if (stat & STATUS_ERR_MASK) {
    207 		printf("request failed. status: 0x%08x\n",
    208 				stat);
    209 		if (stat & STATUS_CRC_READ_ERR) {
    210 			data_error = -EILSEQ;
    211 		} else if (stat & STATUS_CRC_WRITE_ERR) {
    212 			u32 err_code = (stat >> 9) & 0x3;
    213 			if (err_code == 2) /* No CRC response */
    214 				data_error = -ETIMEDOUT;
    215 			else
    216 				data_error = -EILSEQ;
    217 		} else if (stat & STATUS_TIME_OUT_READ) {
    218 			data_error = -ETIMEDOUT;
    219 		} else {
    220 			data_error = -EIO;
    221 		}
    222 	}
    223 
    224 	host->data = NULL;
    225 
    226 	return data_error;
    227 }
    228 
    229 static int mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
    230 {
    231 	struct mmc_cmd *cmd = host->cmd;
    232 	int i;
    233 	u32 a, b, c;
    234 	u32 *resp = (u32 *)cmd->response;
    235 
    236 	if (!cmd)
    237 		return 0;
    238 
    239 	if (stat & STATUS_TIME_OUT_RESP) {
    240 		printf("CMD TIMEOUT\n");
    241 		return -ETIMEDOUT;
    242 	} else if (stat & STATUS_RESP_CRC_ERR && cmd->resp_type & MMC_RSP_CRC) {
    243 		printf("cmd crc error\n");
    244 		return -EILSEQ;
    245 	}
    246 
    247 	if (cmd->resp_type & MMC_RSP_PRESENT) {
    248 		if (cmd->resp_type & MMC_RSP_136) {
    249 			for (i = 0; i < 4; i++) {
    250 				a = readl(&host->base->res_fifo) & 0xFFFF;
    251 				b = readl(&host->base->res_fifo) & 0xFFFF;
    252 				resp[i] = a << 16 | b;
    253 			}
    254 		} else {
    255 			a = readl(&host->base->res_fifo) & 0xFFFF;
    256 			b = readl(&host->base->res_fifo) & 0xFFFF;
    257 			c = readl(&host->base->res_fifo) & 0xFFFF;
    258 			resp[0] = a << 24 | b << 8 | c >> 8;
    259 		}
    260 	}
    261 	return 0;
    262 }
    263 
    264 static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
    265 {
    266 	u32 stat;
    267 	unsigned long timeout = get_ticks() + CONFIG_SYS_HZ;
    268 
    269 	do {
    270 		stat = readl(&host->base->status);
    271 		if (stat & STATUS_ERR_MASK)
    272 			return stat;
    273 		if (timeout < get_ticks())
    274 			return STATUS_TIME_OUT_READ;
    275 		if (stat & mask)
    276 			return 0;
    277 	} while (1);
    278 }
    279 
    280 static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
    281 {
    282 	unsigned int stat;
    283 	u32 *buf = _buf;
    284 
    285 	while (bytes > 3) {
    286 		stat = mxcmci_poll_status(host,
    287 				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
    288 		if (stat)
    289 			return stat;
    290 		*buf++ = readl(&host->base->buffer_access);
    291 		bytes -= 4;
    292 	}
    293 
    294 	if (bytes) {
    295 		u8 *b = (u8 *)buf;
    296 		u32 tmp;
    297 
    298 		stat = mxcmci_poll_status(host,
    299 				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
    300 		if (stat)
    301 			return stat;
    302 		tmp = readl(&host->base->buffer_access);
    303 		memcpy(b, &tmp, bytes);
    304 	}
    305 
    306 	return 0;
    307 }
    308 
    309 static int mxcmci_push(struct mxcmci_host *host, const void *_buf, int bytes)
    310 {
    311 	unsigned int stat;
    312 	const u32 *buf = _buf;
    313 
    314 	while (bytes > 3) {
    315 		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
    316 		if (stat)
    317 			return stat;
    318 		writel(*buf++, &host->base->buffer_access);
    319 		bytes -= 4;
    320 	}
    321 
    322 	if (bytes) {
    323 		const u8 *b = (u8 *)buf;
    324 		u32 tmp;
    325 
    326 		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
    327 		if (stat)
    328 			return stat;
    329 
    330 		memcpy(&tmp, b, bytes);
    331 		writel(tmp, &host->base->buffer_access);
    332 	}
    333 
    334 	stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
    335 	if (stat)
    336 		return stat;
    337 
    338 	return 0;
    339 }
    340 
    341 static int mxcmci_transfer_data(struct mxcmci_host *host)
    342 {
    343 	struct mmc_data *data = host->data;
    344 	int stat;
    345 	unsigned long length;
    346 
    347 	length = data->blocks * data->blocksize;
    348 	host->datasize = 0;
    349 
    350 	if (data->flags & MMC_DATA_READ) {
    351 		stat = mxcmci_pull(host, data->dest, length);
    352 		if (stat)
    353 			return stat;
    354 		host->datasize += length;
    355 	} else {
    356 		stat = mxcmci_push(host, (const void *)(data->src), length);
    357 		if (stat)
    358 			return stat;
    359 		host->datasize += length;
    360 		stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
    361 		if (stat)
    362 			return stat;
    363 	}
    364 	return 0;
    365 }
    366 
    367 static int mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
    368 {
    369 	int datastat;
    370 	int ret;
    371 
    372 	ret = mxcmci_read_response(host, stat);
    373 
    374 	if (ret) {
    375 		mxcmci_finish_request(host, host->cmd, host->data);
    376 		return ret;
    377 	}
    378 
    379 	if (!host->data) {
    380 		mxcmci_finish_request(host, host->cmd, host->data);
    381 		return 0;
    382 	}
    383 
    384 	datastat = mxcmci_transfer_data(host);
    385 	ret = mxcmci_finish_data(host, datastat);
    386 	mxcmci_finish_request(host, host->cmd, host->data);
    387 	return ret;
    388 }
    389 
    390 static int mxcmci_request(struct mmc *mmc, struct mmc_cmd *cmd,
    391 		struct mmc_data *data)
    392 {
    393 	struct mxcmci_host *host = mmc->priv;
    394 	unsigned int cmdat = host->cmdat;
    395 	u32 stat;
    396 	int ret;
    397 
    398 	host->cmdat &= ~CMD_DAT_CONT_INIT;
    399 	if (data) {
    400 		mxcmci_setup_data(host, data);
    401 
    402 		cmdat |= CMD_DAT_CONT_DATA_ENABLE;
    403 
    404 		if (data->flags & MMC_DATA_WRITE)
    405 			cmdat |= CMD_DAT_CONT_WRITE;
    406 	}
    407 
    408 	if ((ret = mxcmci_start_cmd(host, cmd, cmdat))) {
    409 		mxcmci_finish_request(host, cmd, data);
    410 		return ret;
    411 	}
    412 
    413 	do {
    414 		stat = readl(&host->base->status);
    415 		writel(stat, &host->base->status);
    416 	} while (!(stat & STATUS_END_CMD_RESP));
    417 
    418 	return mxcmci_cmd_done(host, stat);
    419 }
    420 
    421 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
    422 {
    423 	unsigned int divider;
    424 	int prescaler = 0;
    425 	unsigned long clk_in = mxc_get_clock(MXC_ESDHC_CLK);
    426 
    427 	while (prescaler <= 0x800) {
    428 		for (divider = 1; divider <= 0xF; divider++) {
    429 			int x;
    430 
    431 			x = (clk_in / (divider + 1));
    432 
    433 			if (prescaler)
    434 				x /= (prescaler * 2);
    435 
    436 			if (x <= clk_ios)
    437 				break;
    438 		}
    439 		if (divider < 0x10)
    440 			break;
    441 
    442 		if (prescaler == 0)
    443 			prescaler = 1;
    444 		else
    445 			prescaler <<= 1;
    446 	}
    447 
    448 	writel((prescaler << 4) | divider, &host->base->clk_rate);
    449 }
    450 
    451 static int mxcmci_set_ios(struct mmc *mmc)
    452 {
    453 	struct mxcmci_host *host = mmc->priv;
    454 	if (mmc->bus_width == 4)
    455 		host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
    456 	else
    457 		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;
    458 
    459 	if (mmc->clock) {
    460 		mxcmci_set_clk_rate(host, mmc->clock);
    461 		writel(STR_STP_CLK_START_CLK, &host->base->str_stp_clk);
    462 	} else {
    463 		writel(STR_STP_CLK_STOP_CLK, &host->base->str_stp_clk);
    464 	}
    465 
    466 	host->clock = mmc->clock;
    467 
    468 	return 0;
    469 }
    470 
    471 static int mxcmci_init(struct mmc *mmc)
    472 {
    473 	struct mxcmci_host *host = mmc->priv;
    474 
    475 	mxcmci_softreset(host);
    476 
    477 	host->rev_no = readl(&host->base->rev_no);
    478 	if (host->rev_no != 0x400) {
    479 		printf("wrong rev.no. 0x%08x. aborting.\n",
    480 			host->rev_no);
    481 		return -ENODEV;
    482 	}
    483 
    484 	/* recommended in data sheet */
    485 	writel(0x2db4, &host->base->read_to);
    486 
    487 	writel(0, &host->base->int_cntr);
    488 
    489 	return 0;
    490 }
    491 
    492 static const struct mmc_ops mxcmci_ops = {
    493 	.send_cmd	= mxcmci_request,
    494 	.set_ios	= mxcmci_set_ios,
    495 	.init		= mxcmci_init,
    496 };
    497 
    498 static struct mmc_config mxcmci_cfg = {
    499 	.name		= "MXC MCI",
    500 	.ops		= &mxcmci_ops,
    501 	.host_caps	= MMC_MODE_4BIT,
    502 	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
    503 	.b_max		= CONFIG_SYS_MMC_MAX_BLK_COUNT,
    504 };
    505 
    506 static int mxcmci_initialize(bd_t *bis)
    507 {
    508 	host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
    509 
    510 	mxcmci_cfg.f_min = mxc_get_clock(MXC_ESDHC_CLK) >> 7;
    511 	mxcmci_cfg.f_max = mxc_get_clock(MXC_ESDHC_CLK) >> 1;
    512 
    513 	host->mmc = mmc_create(&mxcmci_cfg, host);
    514 	if (host->mmc == NULL)
    515 		return -1;
    516 
    517 	return 0;
    518 }
    519 
    520 int mxc_mmc_init(bd_t *bis)
    521 {
    522 	return mxcmci_initialize(bis);
    523 }
    524