2 * Copyright (C) 2011 Andes Technology Corporation
3 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #include <faraday/ftsdc010.h>
33 * setting the number CONFIG_FTSDC010_NUMBER in your configuration file.
35 static struct mmc ftsdc010_dev[CONFIG_FTSDC010_NUMBER];
36 static struct mmc_host ftsdc010_host[CONFIG_FTSDC010_NUMBER];
38 static struct ftsdc010_mmc *ftsdc010_get_base_mmc(int dev_index)
40 return (struct ftsdc010_mmc *)CONFIG_FTSDC010_BASE + dev_index;
44 static void ftsdc010_dump_reg(struct mmc_host *host)
46 debug("cmd: %08x\n", readl(&host->reg->cmd));
47 debug("argu: %08x\n", readl(&host->reg->argu));
48 debug("rsp0: %08x\n", readl(&host->reg->rsp0));
49 debug("rsp1: %08x\n", readl(&host->reg->rsp1));
50 debug("rsp2: %08x\n", readl(&host->reg->rsp2));
51 debug("rsp3: %08x\n", readl(&host->reg->rsp3));
52 debug("rsp_cmd: %08x\n", readl(&host->reg->rsp_cmd));
53 debug("dcr: %08x\n", readl(&host->reg->dcr));
54 debug("dtr: %08x\n", readl(&host->reg->dtr));
55 debug("dlr: %08x\n", readl(&host->reg->dlr));
56 debug("status: %08x\n", readl(&host->reg->status));
57 debug("clr: %08x\n", readl(&host->reg->clr));
58 debug("int_mask: %08x\n", readl(&host->reg->int_mask));
59 debug("pcr: %08x\n", readl(&host->reg->pcr));
60 debug("ccr: %08x\n", readl(&host->reg->ccr));
61 debug("bwr: %08x\n", readl(&host->reg->bwr));
62 debug("dwr: %08x\n", readl(&host->reg->dwr));
63 debug("feature: %08x\n", readl(&host->reg->feature));
64 debug("rev: %08x\n", readl(&host->reg->rev));
68 static unsigned int enable_imask(struct ftsdc010_mmc *reg, unsigned int imask)
72 newmask = readl(®->int_mask);
75 writel(newmask, ®->int_mask);
80 static void ftsdc010_pio_read(struct mmc_host *host, char *buf, unsigned int size)
83 unsigned int fifo_words;
86 unsigned int retry = 0;
89 ptr = (unsigned int *)buf;
92 status = readl(&host->reg->status);
93 debug("%s: size: %08x\n", __func__, size);
95 if (status & FTSDC010_STATUS_FIFO_ORUN) {
97 debug("%s: FIFO OVERRUN: sta: %08x\n",
100 fifo = host->fifo_len > size ?
101 size : host->fifo_len;
105 fifo_words = fifo >> 2;
108 *ptr++ = readl(&host->reg->dwr);
111 * for adding some delays for SD card to put
112 * data into FIFO again
114 udelay(4*FTSDC010_DELAY_UNIT);
116 #ifdef CONFIG_FTSDC010_SDIO
117 /* sdio allow non-power-of-2 blksz */
119 unsigned int n = fifo & 3;
120 unsigned int data = readl(&host->reg->dwr);
122 unsigned char *p = (unsigned char *)ptr;
132 if (++retry >= FTSDC010_PIO_RETRY) {
133 debug("%s: PIO_RETRY timeout\n", __func__);
140 static void ftsdc010_pio_write(struct mmc_host *host, const char *buf,
146 unsigned int retry = 0;
148 /* get data buffer */
149 ptr = (unsigned int *)buf;
152 status = readl(&host->reg->status);
154 if (status & FTSDC010_STATUS_FIFO_URUN) {
155 fifo = host->fifo_len > size ?
156 size : host->fifo_len;
160 fifo = (fifo + 3) >> 2;
163 writel(*ptr, &host->reg->dwr);
168 if (++retry >= FTSDC010_PIO_RETRY) {
169 debug("%s: PIO_RETRY timeout\n", __func__);
176 static int ftsdc010_check_rsp(struct mmc *mmc, struct mmc_cmd *cmd,
177 struct mmc_data *data)
179 struct mmc_host *host = mmc->priv;
180 unsigned int sta, clear;
182 sta = readl(&host->reg->status);
183 debug("%s: sta: %08x cmd %d\n", __func__, sta, cmd->cmdidx);
185 /* check RSP TIMEOUT or FAIL */
186 if (sta & FTSDC010_STATUS_RSP_TIMEOUT) {
188 debug("%s: RSP timeout: sta: %08x\n", __func__, sta);
190 clear |= FTSDC010_CLR_RSP_TIMEOUT;
191 writel(clear, &host->reg->clr);
194 } else if (sta & FTSDC010_STATUS_RSP_CRC_FAIL) {
195 /* clear response fail bit */
196 debug("%s: RSP CRC FAIL: sta: %08x\n", __func__, sta);
198 clear |= FTSDC010_CLR_RSP_CRC_FAIL;
199 writel(clear, &host->reg->clr);
202 } else if (sta & FTSDC010_STATUS_RSP_CRC_OK) {
204 /* clear response CRC OK bit */
205 clear |= FTSDC010_CLR_RSP_CRC_OK;
208 writel(clear, &host->reg->clr);
212 static int ftsdc010_check_data(struct mmc *mmc, struct mmc_cmd *cmd,
213 struct mmc_data *data)
215 struct mmc_host *host = mmc->priv;
216 unsigned int sta, clear;
218 sta = readl(&host->reg->status);
219 debug("%s: sta: %08x cmd %d\n", __func__, sta, cmd->cmdidx);
221 /* check DATA TIMEOUT or FAIL */
224 /* Transfer Complete */
225 if (sta & FTSDC010_STATUS_DATA_END)
226 clear |= FTSDC010_STATUS_DATA_END;
229 if (sta & FTSDC010_STATUS_DATA_CRC_OK)
230 clear |= FTSDC010_STATUS_DATA_CRC_OK;
232 /* DATA TIMEOUT or DATA CRC FAIL */
233 if (sta & FTSDC010_STATUS_DATA_TIMEOUT) {
235 debug("%s: DATA TIMEOUT: sta: %08x\n", __func__, sta);
237 clear |= FTSDC010_STATUS_DATA_TIMEOUT;
238 writel(clear, &host->reg->clr);
241 } else if (sta & FTSDC010_STATUS_DATA_CRC_FAIL) {
243 debug("%s: DATA CRC FAIL: sta: %08x\n", __func__, sta);
245 clear |= FTSDC010_STATUS_DATA_CRC_FAIL;
246 writel(clear, &host->reg->clr);
250 writel(clear, &host->reg->clr);
255 static int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
256 struct mmc_data *data)
258 struct mmc_host *host = mmc->priv;
260 #ifdef CONFIG_FTSDC010_SDIO
264 unsigned int mask, tmpmask;
271 mask = FTSDC010_INT_MASK_RSP_TIMEOUT;
272 else if (cmd->resp_type & MMC_RSP_PRESENT)
273 mask = FTSDC010_INT_MASK_RSP_TIMEOUT;
275 mask = FTSDC010_INT_MASK_CMD_SEND;
278 debug("%s: argu: %08x\n", __func__, host->reg->argu);
279 writel(cmd->cmdarg, &host->reg->argu);
282 ccon = FTSDC010_CMD_IDX(cmd->cmdidx);
284 /* setup command flags */
285 ccon |= FTSDC010_CMD_CMD_EN;
288 * This hardware didn't support specific commands for mapping
289 * MMC_RSP_BUSY and MMC_RSP_OPCODE. Hence we don't deal with it.
291 if (cmd->resp_type & MMC_RSP_PRESENT) {
292 ccon |= FTSDC010_CMD_NEED_RSP;
293 mask |= FTSDC010_INT_MASK_RSP_CRC_OK |
294 FTSDC010_INT_MASK_RSP_CRC_FAIL;
297 if (cmd->resp_type & MMC_RSP_136)
298 ccon |= FTSDC010_CMD_LONG_RSP;
300 /* In Linux driver, MMC_CMD_APP_CMD is checked in last_opcode */
301 if (host->last_opcode == MMC_CMD_APP_CMD)
302 ccon |= FTSDC010_CMD_APP_CMD;
304 #ifdef CONFIG_FTSDC010_SDIO
305 scon = readl(&host->reg->sdio_ctrl1);
306 if (host->card_type == MMC_TYPE_SDIO)
307 scon |= FTSDC010_SDIO_CTRL1_SDIO_ENABLE;
309 scon &= ~FTSDC010_SDIO_CTRL1_SDIO_ENABLE;
310 writel(scon, &host->reg->sdio_ctrl1);
313 /* record last opcode for specifing the command type to hardware */
314 host->last_opcode = cmd->cmdidx;
316 /* write int_mask reg */
317 tmpmask = readl(&host->reg->int_mask);
319 writel(tmpmask, &host->reg->int_mask);
322 debug("%s: ccon: %08x\n", __func__, ccon);
323 writel(ccon, &host->reg->cmd);
326 for (i = 0; i < FTSDC010_CMD_RETRY; i++) {
328 * If we read status register too fast
329 * will lead hardware error and the RSP_TIMEOUT
330 * flag will be raised incorrectly.
332 udelay(16*FTSDC010_DELAY_UNIT);
333 sta = readl(&host->reg->status);
335 /* Command Complete */
338 * Do not clear FTSDC010_CLR_CMD_SEND flag.
339 * (by writing FTSDC010_CLR_CMD_SEND bit to clear register)
340 * It will make the driver becomes very slow.
341 * If the operation hasn't been finished, hardware will
342 * clear this bit automatically.
343 * In origin, the driver will clear this flag if there is
344 * no data need to be read.
346 if (sta & FTSDC010_STATUS_CMD_SEND)
350 if (i > FTSDC010_CMD_RETRY) {
351 printf("%s: send command timeout\n", __func__);
355 /* check rsp status */
356 ret = ftsdc010_check_rsp(mmc, cmd, data);
360 /* read response if we have RSP_OK */
361 if (ccon & FTSDC010_CMD_LONG_RSP) {
362 cmd->response[0] = readl(&host->reg->rsp3);
363 cmd->response[1] = readl(&host->reg->rsp2);
364 cmd->response[2] = readl(&host->reg->rsp1);
365 cmd->response[3] = readl(&host->reg->rsp0);
367 cmd->response[0] = readl(&host->reg->rsp0);
370 /* read/write data */
371 if (data && (data->flags & MMC_DATA_READ)) {
372 ftsdc010_pio_read(host, data->dest,
373 data->blocksize * data->blocks);
374 } else if (data && (data->flags & MMC_DATA_WRITE)) {
375 ftsdc010_pio_write(host, data->src,
376 data->blocksize * data->blocks);
379 /* check data status */
381 ret = ftsdc010_check_data(mmc, cmd, data);
386 udelay(FTSDC010_DELAY_UNIT);
390 static unsigned int cal_blksz(unsigned int blksz)
392 unsigned int blksztwo = 0;
400 static int ftsdc010_setup_data(struct mmc *mmc, struct mmc_data *data)
402 struct mmc_host *host = mmc->priv;
403 unsigned int dcon, newmask;
405 /* configure data transfer paramter */
409 if (((data->blocksize - 1) & data->blocksize) != 0) {
410 printf("%s: can't do non-power-of 2 sized block transfers"
411 " (blksz %d)\n", __func__, data->blocksize);
416 * We cannot deal with unaligned blocks with more than
417 * one block being transfered.
419 if ((data->blocksize <= 2) && (data->blocks > 1)) {
420 printf("%s: can't do non-word sized block transfers"
421 " (blksz %d)\n", __func__, data->blocksize);
426 dcon = data->blocksize * data->blocks;
427 writel(dcon, &host->reg->dlr);
429 /* write data control */
430 dcon = cal_blksz(data->blocksize);
432 /* add to IMASK register */
433 newmask = (FTSDC010_STATUS_RSP_CRC_FAIL | FTSDC010_STATUS_DATA_TIMEOUT);
436 * enable UNDERRUN will trigger interrupt immediatedly
437 * So setup it when rsp is received successfully
439 if (data->flags & MMC_DATA_WRITE) {
440 dcon |= FTSDC010_DCR_DATA_WRITE;
442 dcon &= ~FTSDC010_DCR_DATA_WRITE;
443 newmask |= FTSDC010_STATUS_FIFO_ORUN;
445 enable_imask(host->reg, newmask);
447 #ifdef CONFIG_FTSDC010_SDIO
448 /* always reset fifo since last transfer may fail */
449 dcon |= FTSDC010_DCR_FIFO_RST;
451 if (data->blocks > 1)
452 dcon |= FTSDC010_SDIO_CTRL1_SDIO_BLK_MODE;
455 /* enable data transfer which will be pended until cmd is send */
456 dcon |= FTSDC010_DCR_DATA_EN;
457 writel(dcon, &host->reg->dcr);
462 static int ftsdc010_send_request(struct mmc *mmc, struct mmc_cmd *cmd,
463 struct mmc_data *data)
468 ret = ftsdc010_setup_data(mmc, data);
471 printf("%s: setup data error\n", __func__);
475 if ((data->flags & MMC_DATA_BOTH_DIR) == MMC_DATA_BOTH_DIR) {
476 printf("%s: data is both direction\n", __func__);
482 ret = ftsdc010_send_cmd(mmc, cmd, data);
486 static int ftsdc010_card_detect(struct mmc *mmc)
488 struct mmc_host *host = mmc->priv;
491 sta = readl(&host->reg->status);
492 debug("%s: card status: %08x\n", __func__, sta);
494 return (sta & FTSDC010_STATUS_CARD_DETECT) ? 0 : 1;
497 static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
498 struct mmc_data *data)
502 if (ftsdc010_card_detect(mmc) == 0) {
503 printf("%s: no medium present\n", __func__);
506 ret = ftsdc010_send_request(mmc, cmd, data);
511 static void ftsdc010_set_clk(struct mmc *mmc)
513 struct mmc_host *host = mmc->priv;
514 unsigned char clk_div;
515 unsigned int real_rate;
518 debug("%s: mmc_set_clock: %x\n", __func__, mmc->clock);
519 clock = readl(&host->reg->ccr);
521 if (mmc->clock == 0) {
523 clock |= FTSDC010_CCR_CLK_DIS;
525 debug("%s, mmc->clock: %08x, origin clock: %08x\n",
526 __func__, mmc->clock, clock);
528 for (clk_div = 0; clk_div <= 127; clk_div++) {
529 real_rate = (CONFIG_SYS_CLK_FREQ / 2) /
532 if (real_rate <= mmc->clock)
536 debug("%s: computed real_rate: %x, clk_div: %x\n",
537 __func__, real_rate, clk_div);
540 debug("%s: no match clock rate, %x\n",
541 __func__, mmc->clock);
543 clock = (clock & ~FTSDC010_CCR_CLK_DIV(0x7f)) |
544 FTSDC010_CCR_CLK_DIV(clk_div);
546 clock &= ~FTSDC010_CCR_CLK_DIS;
549 debug("%s, set clock: %08x\n", __func__, clock);
550 writel(clock, &host->reg->ccr);
553 static void ftsdc010_set_ios(struct mmc *mmc)
555 struct mmc_host *host = mmc->priv;
558 unsigned int bus_width;
560 debug("%s: bus_width: %x, clock: %d\n",
561 __func__, mmc->bus_width, mmc->clock);
563 /* set pcr: power on */
564 power = readl(&host->reg->pcr);
565 power |= FTSDC010_PCR_POWER_ON;
566 writel(power, &host->reg->pcr);
569 ftsdc010_set_clk(mmc);
571 /* set bwr: bus width reg */
572 bus_width = readl(&host->reg->bwr);
573 bus_width &= ~(FTSDC010_BWR_WIDE_8_BUS | FTSDC010_BWR_WIDE_4_BUS |
574 FTSDC010_BWR_SINGLE_BUS);
576 if (mmc->bus_width == 8)
577 bus_width |= FTSDC010_BWR_WIDE_8_BUS;
578 else if (mmc->bus_width == 4)
579 bus_width |= FTSDC010_BWR_WIDE_4_BUS;
581 bus_width |= FTSDC010_BWR_SINGLE_BUS;
583 writel(bus_width, &host->reg->bwr);
586 val = readl(&host->reg->feature);
587 host->fifo_len = FTSDC010_FEATURE_FIFO_DEPTH(val) * 4; /* 4 bytes */
589 /* set data timeout register */
591 writel(val, &host->reg->dtr);
594 static void ftsdc010_reset(struct mmc_host *host)
596 unsigned int timeout;
599 /* Do SDC_RST: Software reset for all register */
600 writel(FTSDC010_CMD_SDC_RST, &host->reg->cmd);
604 /* this hardware has no reset finish flag to read */
605 /* wait 100ms maximum */
608 /* hw clears the bit when it's done */
609 while (readl(&host->reg->dtr) != 0) {
611 printf("%s: reset timeout error\n", __func__);
615 udelay(10*FTSDC010_DELAY_UNIT);
618 sta = readl(&host->reg->status);
619 if (sta & FTSDC010_STATUS_CARD_CHANGE)
620 writel(FTSDC010_CLR_CARD_CHANGE, &host->reg->clr);
623 static int ftsdc010_core_init(struct mmc *mmc)
625 struct mmc_host *host = mmc->priv;
627 unsigned int major, minor, revision;
629 /* get hardware version */
630 host->version = readl(&host->reg->rev);
632 major = FTSDC010_REV_MAJOR(host->version);
633 minor = FTSDC010_REV_MINOR(host->version);
634 revision = FTSDC010_REV_REVISION(host->version);
636 printf("ftsdc010 hardware ver: %d_%d_r%d\n", major, minor, revision);
638 /* Interrupt MASK register init - mask all */
639 writel(0x0, &host->reg->int_mask);
641 mask = FTSDC010_INT_MASK_CMD_SEND |
642 FTSDC010_INT_MASK_DATA_END |
643 FTSDC010_INT_MASK_CARD_CHANGE;
644 #ifdef CONFIG_FTSDC010_SDIO
645 mask |= FTSDC010_INT_MASK_CP_READY |
646 FTSDC010_INT_MASK_CP_BUF_READY |
647 FTSDC010_INT_MASK_PLAIN_TEXT_READY |
648 FTSDC010_INT_MASK_SDIO_IRPT;
651 writel(mask, &host->reg->int_mask);
656 int ftsdc010_mmc_init(int dev_index)
659 struct mmc_host *host;
661 mmc = &ftsdc010_dev[dev_index];
663 sprintf(mmc->name, "FTSDC010 SD/MMC");
664 mmc->priv = &ftsdc010_host[dev_index];
665 mmc->send_cmd = ftsdc010_request;
666 mmc->set_ios = ftsdc010_set_ios;
667 mmc->init = ftsdc010_core_init;
670 mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
672 mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
674 mmc->f_min = CONFIG_SYS_CLK_FREQ / 2 / (2*128);
675 mmc->f_max = CONFIG_SYS_CLK_FREQ / 2 / 2;
677 ftsdc010_host[dev_index].clock = 0;
678 ftsdc010_host[dev_index].reg = ftsdc010_get_base_mmc(dev_index);
682 host = (struct mmc_host *)mmc->priv;
683 ftsdc010_reset(host);