0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/dmaengine.h>
0013 #include <linux/dma-mapping.h>
0014 #include <linux/clk.h>
0015 #include <linux/mmc/host.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/cpufreq.h>
0018 #include <linux/debugfs.h>
0019 #include <linux/seq_file.h>
0020 #include <linux/gpio/consumer.h>
0021 #include <linux/interrupt.h>
0022 #include <linux/irq.h>
0023 #include <linux/io.h>
0024 #include <linux/of.h>
0025 #include <linux/of_device.h>
0026 #include <linux/mmc/slot-gpio.h>
0027 #include <linux/platform_data/mmc-s3cmci.h>
0028
0029 #include "s3cmci.h"
0030
0031 #define DRIVER_NAME "s3c-mci"
0032
0033 #define S3C2410_SDICON (0x00)
0034 #define S3C2410_SDIPRE (0x04)
0035 #define S3C2410_SDICMDARG (0x08)
0036 #define S3C2410_SDICMDCON (0x0C)
0037 #define S3C2410_SDICMDSTAT (0x10)
0038 #define S3C2410_SDIRSP0 (0x14)
0039 #define S3C2410_SDIRSP1 (0x18)
0040 #define S3C2410_SDIRSP2 (0x1C)
0041 #define S3C2410_SDIRSP3 (0x20)
0042 #define S3C2410_SDITIMER (0x24)
0043 #define S3C2410_SDIBSIZE (0x28)
0044 #define S3C2410_SDIDCON (0x2C)
0045 #define S3C2410_SDIDCNT (0x30)
0046 #define S3C2410_SDIDSTA (0x34)
0047 #define S3C2410_SDIFSTA (0x38)
0048
0049 #define S3C2410_SDIDATA (0x3C)
0050 #define S3C2410_SDIIMSK (0x40)
0051
0052 #define S3C2440_SDIDATA (0x40)
0053 #define S3C2440_SDIIMSK (0x3C)
0054
0055 #define S3C2440_SDICON_SDRESET (1 << 8)
0056 #define S3C2410_SDICON_SDIOIRQ (1 << 3)
0057 #define S3C2410_SDICON_FIFORESET (1 << 1)
0058 #define S3C2410_SDICON_CLOCKTYPE (1 << 0)
0059
0060 #define S3C2410_SDICMDCON_LONGRSP (1 << 10)
0061 #define S3C2410_SDICMDCON_WAITRSP (1 << 9)
0062 #define S3C2410_SDICMDCON_CMDSTART (1 << 8)
0063 #define S3C2410_SDICMDCON_SENDERHOST (1 << 6)
0064 #define S3C2410_SDICMDCON_INDEX (0x3f)
0065
0066 #define S3C2410_SDICMDSTAT_CRCFAIL (1 << 12)
0067 #define S3C2410_SDICMDSTAT_CMDSENT (1 << 11)
0068 #define S3C2410_SDICMDSTAT_CMDTIMEOUT (1 << 10)
0069 #define S3C2410_SDICMDSTAT_RSPFIN (1 << 9)
0070
0071 #define S3C2440_SDIDCON_DS_WORD (2 << 22)
0072 #define S3C2410_SDIDCON_TXAFTERRESP (1 << 20)
0073 #define S3C2410_SDIDCON_RXAFTERCMD (1 << 19)
0074 #define S3C2410_SDIDCON_BLOCKMODE (1 << 17)
0075 #define S3C2410_SDIDCON_WIDEBUS (1 << 16)
0076 #define S3C2410_SDIDCON_DMAEN (1 << 15)
0077 #define S3C2410_SDIDCON_STOP (1 << 14)
0078 #define S3C2440_SDIDCON_DATSTART (1 << 14)
0079
0080 #define S3C2410_SDIDCON_XFER_RXSTART (2 << 12)
0081 #define S3C2410_SDIDCON_XFER_TXSTART (3 << 12)
0082
0083 #define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF)
0084
0085 #define S3C2410_SDIDSTA_SDIOIRQDETECT (1 << 9)
0086 #define S3C2410_SDIDSTA_FIFOFAIL (1 << 8)
0087 #define S3C2410_SDIDSTA_CRCFAIL (1 << 7)
0088 #define S3C2410_SDIDSTA_RXCRCFAIL (1 << 6)
0089 #define S3C2410_SDIDSTA_DATATIMEOUT (1 << 5)
0090 #define S3C2410_SDIDSTA_XFERFINISH (1 << 4)
0091 #define S3C2410_SDIDSTA_TXDATAON (1 << 1)
0092 #define S3C2410_SDIDSTA_RXDATAON (1 << 0)
0093
0094 #define S3C2440_SDIFSTA_FIFORESET (1 << 16)
0095 #define S3C2440_SDIFSTA_FIFOFAIL (3 << 14)
0096 #define S3C2410_SDIFSTA_TFDET (1 << 13)
0097 #define S3C2410_SDIFSTA_RFDET (1 << 12)
0098 #define S3C2410_SDIFSTA_COUNTMASK (0x7f)
0099
0100 #define S3C2410_SDIIMSK_RESPONSECRC (1 << 17)
0101 #define S3C2410_SDIIMSK_CMDSENT (1 << 16)
0102 #define S3C2410_SDIIMSK_CMDTIMEOUT (1 << 15)
0103 #define S3C2410_SDIIMSK_RESPONSEND (1 << 14)
0104 #define S3C2410_SDIIMSK_SDIOIRQ (1 << 12)
0105 #define S3C2410_SDIIMSK_FIFOFAIL (1 << 11)
0106 #define S3C2410_SDIIMSK_CRCSTATUS (1 << 10)
0107 #define S3C2410_SDIIMSK_DATACRC (1 << 9)
0108 #define S3C2410_SDIIMSK_DATATIMEOUT (1 << 8)
0109 #define S3C2410_SDIIMSK_DATAFINISH (1 << 7)
0110 #define S3C2410_SDIIMSK_TXFIFOHALF (1 << 4)
0111 #define S3C2410_SDIIMSK_RXFIFOLAST (1 << 2)
0112 #define S3C2410_SDIIMSK_RXFIFOHALF (1 << 0)
0113
0114 enum dbg_channels {
0115 dbg_err = (1 << 0),
0116 dbg_debug = (1 << 1),
0117 dbg_info = (1 << 2),
0118 dbg_irq = (1 << 3),
0119 dbg_sg = (1 << 4),
0120 dbg_dma = (1 << 5),
0121 dbg_pio = (1 << 6),
0122 dbg_fail = (1 << 7),
0123 dbg_conf = (1 << 8),
0124 };
0125
0126 static const int dbgmap_err = dbg_fail;
0127 static const int dbgmap_info = dbg_info | dbg_conf;
0128 static const int dbgmap_debug = dbg_err | dbg_debug;
0129
0130 #define dbg(host, channels, args...) \
0131 do { \
0132 if (dbgmap_err & channels) \
0133 dev_err(&host->pdev->dev, args); \
0134 else if (dbgmap_info & channels) \
0135 dev_info(&host->pdev->dev, args); \
0136 else if (dbgmap_debug & channels) \
0137 dev_dbg(&host->pdev->dev, args); \
0138 } while (0)
0139
0140 static void finalize_request(struct s3cmci_host *host);
0141 static void s3cmci_send_request(struct mmc_host *mmc);
0142 static void s3cmci_reset(struct s3cmci_host *host);
0143
0144 #ifdef CONFIG_MMC_DEBUG
0145
0146 static void dbg_dumpregs(struct s3cmci_host *host, char *prefix)
0147 {
0148 u32 con, pre, cmdarg, cmdcon, cmdsta, r0, r1, r2, r3, timer;
0149 u32 datcon, datcnt, datsta, fsta;
0150
0151 con = readl(host->base + S3C2410_SDICON);
0152 pre = readl(host->base + S3C2410_SDIPRE);
0153 cmdarg = readl(host->base + S3C2410_SDICMDARG);
0154 cmdcon = readl(host->base + S3C2410_SDICMDCON);
0155 cmdsta = readl(host->base + S3C2410_SDICMDSTAT);
0156 r0 = readl(host->base + S3C2410_SDIRSP0);
0157 r1 = readl(host->base + S3C2410_SDIRSP1);
0158 r2 = readl(host->base + S3C2410_SDIRSP2);
0159 r3 = readl(host->base + S3C2410_SDIRSP3);
0160 timer = readl(host->base + S3C2410_SDITIMER);
0161 datcon = readl(host->base + S3C2410_SDIDCON);
0162 datcnt = readl(host->base + S3C2410_SDIDCNT);
0163 datsta = readl(host->base + S3C2410_SDIDSTA);
0164 fsta = readl(host->base + S3C2410_SDIFSTA);
0165
0166 dbg(host, dbg_debug, "%s CON:[%08x] PRE:[%08x] TMR:[%08x]\n",
0167 prefix, con, pre, timer);
0168
0169 dbg(host, dbg_debug, "%s CCON:[%08x] CARG:[%08x] CSTA:[%08x]\n",
0170 prefix, cmdcon, cmdarg, cmdsta);
0171
0172 dbg(host, dbg_debug, "%s DCON:[%08x] FSTA:[%08x]"
0173 " DSTA:[%08x] DCNT:[%08x]\n",
0174 prefix, datcon, fsta, datsta, datcnt);
0175
0176 dbg(host, dbg_debug, "%s R0:[%08x] R1:[%08x]"
0177 " R2:[%08x] R3:[%08x]\n",
0178 prefix, r0, r1, r2, r3);
0179 }
0180
0181 static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
0182 int stop)
0183 {
0184 snprintf(host->dbgmsg_cmd, 300,
0185 "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u",
0186 host->ccnt, (stop ? " (STOP)" : ""),
0187 cmd->opcode, cmd->arg, cmd->flags, cmd->retries);
0188
0189 if (cmd->data) {
0190 snprintf(host->dbgmsg_dat, 300,
0191 "#%u bsize:%u blocks:%u bytes:%u",
0192 host->dcnt, cmd->data->blksz,
0193 cmd->data->blocks,
0194 cmd->data->blocks * cmd->data->blksz);
0195 } else {
0196 host->dbgmsg_dat[0] = '\0';
0197 }
0198 }
0199
0200 static void dbg_dumpcmd(struct s3cmci_host *host, struct mmc_command *cmd,
0201 int fail)
0202 {
0203 unsigned int dbglvl = fail ? dbg_fail : dbg_debug;
0204
0205 if (!cmd)
0206 return;
0207
0208 if (cmd->error == 0) {
0209 dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n",
0210 host->dbgmsg_cmd, cmd->resp[0]);
0211 } else {
0212 dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n",
0213 cmd->error, host->dbgmsg_cmd, host->status);
0214 }
0215
0216 if (!cmd->data)
0217 return;
0218
0219 if (cmd->data->error == 0) {
0220 dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat);
0221 } else {
0222 dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n",
0223 cmd->data->error, host->dbgmsg_dat,
0224 readl(host->base + S3C2410_SDIDCNT));
0225 }
0226 }
0227 #else
0228 static void dbg_dumpcmd(struct s3cmci_host *host,
0229 struct mmc_command *cmd, int fail) { }
0230
0231 static void prepare_dbgmsg(struct s3cmci_host *host, struct mmc_command *cmd,
0232 int stop) { }
0233
0234 static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
0235
0236 #endif
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 static inline bool s3cmci_host_usedma(struct s3cmci_host *host)
0247 {
0248 #ifdef CONFIG_MMC_S3C_PIO
0249 return false;
0250 #else
0251 return true;
0252 #endif
0253 }
0254
0255 static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
0256 {
0257 u32 newmask;
0258
0259 newmask = readl(host->base + host->sdiimsk);
0260 newmask |= imask;
0261
0262 writel(newmask, host->base + host->sdiimsk);
0263
0264 return newmask;
0265 }
0266
0267 static inline u32 disable_imask(struct s3cmci_host *host, u32 imask)
0268 {
0269 u32 newmask;
0270
0271 newmask = readl(host->base + host->sdiimsk);
0272 newmask &= ~imask;
0273
0274 writel(newmask, host->base + host->sdiimsk);
0275
0276 return newmask;
0277 }
0278
0279 static inline void clear_imask(struct s3cmci_host *host)
0280 {
0281 u32 mask = readl(host->base + host->sdiimsk);
0282
0283
0284 mask &= S3C2410_SDIIMSK_SDIOIRQ;
0285 writel(mask, host->base + host->sdiimsk);
0286 }
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
0301 {
0302 if (host->sdio_irqen) {
0303 if (host->pdata->bus[3] &&
0304 gpiod_get_value(host->pdata->bus[3]) == 0) {
0305 pr_debug("%s: signalling irq\n", __func__);
0306 mmc_signal_sdio_irq(host->mmc);
0307 }
0308 }
0309 }
0310
0311 static inline int get_data_buffer(struct s3cmci_host *host,
0312 u32 *bytes, u32 **pointer)
0313 {
0314 struct scatterlist *sg;
0315
0316 if (host->pio_active == XFER_NONE)
0317 return -EINVAL;
0318
0319 if ((!host->mrq) || (!host->mrq->data))
0320 return -EINVAL;
0321
0322 if (host->pio_sgptr >= host->mrq->data->sg_len) {
0323 dbg(host, dbg_debug, "no more buffers (%i/%i)\n",
0324 host->pio_sgptr, host->mrq->data->sg_len);
0325 return -EBUSY;
0326 }
0327 sg = &host->mrq->data->sg[host->pio_sgptr];
0328
0329 *bytes = sg->length;
0330 *pointer = sg_virt(sg);
0331
0332 host->pio_sgptr++;
0333
0334 dbg(host, dbg_sg, "new buffer (%i/%i)\n",
0335 host->pio_sgptr, host->mrq->data->sg_len);
0336
0337 return 0;
0338 }
0339
0340 static inline u32 fifo_count(struct s3cmci_host *host)
0341 {
0342 u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
0343
0344 fifostat &= S3C2410_SDIFSTA_COUNTMASK;
0345 return fifostat;
0346 }
0347
0348 static inline u32 fifo_free(struct s3cmci_host *host)
0349 {
0350 u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
0351
0352 fifostat &= S3C2410_SDIFSTA_COUNTMASK;
0353 return 63 - fifostat;
0354 }
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369 static void s3cmci_enable_irq(struct s3cmci_host *host, bool more)
0370 {
0371 unsigned long flags;
0372 bool enable = false;
0373
0374 local_irq_save(flags);
0375
0376 host->irq_enabled = more;
0377 host->irq_disabled = false;
0378
0379 enable = more | host->sdio_irqen;
0380
0381 if (host->irq_state != enable) {
0382 host->irq_state = enable;
0383
0384 if (enable)
0385 enable_irq(host->irq);
0386 else
0387 disable_irq(host->irq);
0388 }
0389
0390 local_irq_restore(flags);
0391 }
0392
0393 static void s3cmci_disable_irq(struct s3cmci_host *host, bool transfer)
0394 {
0395 unsigned long flags;
0396
0397 local_irq_save(flags);
0398
0399
0400
0401 host->irq_disabled = transfer;
0402
0403 if (transfer && host->irq_state) {
0404 host->irq_state = false;
0405 disable_irq(host->irq);
0406 }
0407
0408 local_irq_restore(flags);
0409 }
0410
0411 static void do_pio_read(struct s3cmci_host *host)
0412 {
0413 int res;
0414 u32 fifo;
0415 u32 *ptr;
0416 u32 fifo_words;
0417 void __iomem *from_ptr;
0418
0419
0420 writel(host->prescaler, host->base + S3C2410_SDIPRE);
0421
0422 from_ptr = host->base + host->sdidata;
0423
0424 while ((fifo = fifo_count(host))) {
0425 if (!host->pio_bytes) {
0426 res = get_data_buffer(host, &host->pio_bytes,
0427 &host->pio_ptr);
0428 if (res) {
0429 host->pio_active = XFER_NONE;
0430 host->complete_what = COMPLETION_FINALIZE;
0431
0432 dbg(host, dbg_pio, "pio_read(): "
0433 "complete (no more data).\n");
0434 return;
0435 }
0436
0437 dbg(host, dbg_pio,
0438 "pio_read(): new target: [%i]@[%p]\n",
0439 host->pio_bytes, host->pio_ptr);
0440 }
0441
0442 dbg(host, dbg_pio,
0443 "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",
0444 fifo, host->pio_bytes,
0445 readl(host->base + S3C2410_SDIDCNT));
0446
0447
0448
0449
0450
0451
0452 if (fifo >= host->pio_bytes)
0453 fifo = host->pio_bytes;
0454 else
0455 fifo -= fifo & 3;
0456
0457 host->pio_bytes -= fifo;
0458 host->pio_count += fifo;
0459
0460 fifo_words = fifo >> 2;
0461 ptr = host->pio_ptr;
0462 while (fifo_words--)
0463 *ptr++ = readl(from_ptr);
0464 host->pio_ptr = ptr;
0465
0466 if (fifo & 3) {
0467 u32 n = fifo & 3;
0468 u32 data = readl(from_ptr);
0469 u8 *p = (u8 *)host->pio_ptr;
0470
0471 while (n--) {
0472 *p++ = data;
0473 data >>= 8;
0474 }
0475 }
0476 }
0477
0478 if (!host->pio_bytes) {
0479 res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr);
0480 if (res) {
0481 dbg(host, dbg_pio,
0482 "pio_read(): complete (no more buffers).\n");
0483 host->pio_active = XFER_NONE;
0484 host->complete_what = COMPLETION_FINALIZE;
0485
0486 return;
0487 }
0488 }
0489
0490 enable_imask(host,
0491 S3C2410_SDIIMSK_RXFIFOHALF | S3C2410_SDIIMSK_RXFIFOLAST);
0492 }
0493
0494 static void do_pio_write(struct s3cmci_host *host)
0495 {
0496 void __iomem *to_ptr;
0497 int res;
0498 u32 fifo;
0499 u32 *ptr;
0500
0501 to_ptr = host->base + host->sdidata;
0502
0503 while ((fifo = fifo_free(host)) > 3) {
0504 if (!host->pio_bytes) {
0505 res = get_data_buffer(host, &host->pio_bytes,
0506 &host->pio_ptr);
0507 if (res) {
0508 dbg(host, dbg_pio,
0509 "pio_write(): complete (no more data).\n");
0510 host->pio_active = XFER_NONE;
0511
0512 return;
0513 }
0514
0515 dbg(host, dbg_pio,
0516 "pio_write(): new source: [%i]@[%p]\n",
0517 host->pio_bytes, host->pio_ptr);
0518
0519 }
0520
0521
0522
0523
0524
0525 if (fifo >= host->pio_bytes)
0526 fifo = host->pio_bytes;
0527 else
0528 fifo -= fifo & 3;
0529
0530 host->pio_bytes -= fifo;
0531 host->pio_count += fifo;
0532
0533 fifo = (fifo + 3) >> 2;
0534 ptr = host->pio_ptr;
0535 while (fifo--)
0536 writel(*ptr++, to_ptr);
0537 host->pio_ptr = ptr;
0538 }
0539
0540 enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
0541 }
0542
0543 static void pio_tasklet(struct tasklet_struct *t)
0544 {
0545 struct s3cmci_host *host = from_tasklet(host, t, pio_tasklet);
0546
0547 s3cmci_disable_irq(host, true);
0548
0549 if (host->pio_active == XFER_WRITE)
0550 do_pio_write(host);
0551
0552 if (host->pio_active == XFER_READ)
0553 do_pio_read(host);
0554
0555 if (host->complete_what == COMPLETION_FINALIZE) {
0556 clear_imask(host);
0557 if (host->pio_active != XFER_NONE) {
0558 dbg(host, dbg_err, "unfinished %s "
0559 "- pio_count:[%u] pio_bytes:[%u]\n",
0560 (host->pio_active == XFER_READ) ? "read" : "write",
0561 host->pio_count, host->pio_bytes);
0562
0563 if (host->mrq->data)
0564 host->mrq->data->error = -EINVAL;
0565 }
0566
0567 s3cmci_enable_irq(host, false);
0568 finalize_request(host);
0569 } else
0570 s3cmci_enable_irq(host, true);
0571 }
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600 static irqreturn_t s3cmci_irq(int irq, void *dev_id)
0601 {
0602 struct s3cmci_host *host = dev_id;
0603 struct mmc_command *cmd;
0604 u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
0605 u32 mci_cclear = 0, mci_dclear;
0606 unsigned long iflags;
0607
0608 mci_dsta = readl(host->base + S3C2410_SDIDSTA);
0609 mci_imsk = readl(host->base + host->sdiimsk);
0610
0611 if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
0612 if (mci_imsk & S3C2410_SDIIMSK_SDIOIRQ) {
0613 mci_dclear = S3C2410_SDIDSTA_SDIOIRQDETECT;
0614 writel(mci_dclear, host->base + S3C2410_SDIDSTA);
0615
0616 mmc_signal_sdio_irq(host->mmc);
0617 return IRQ_HANDLED;
0618 }
0619 }
0620
0621 spin_lock_irqsave(&host->complete_lock, iflags);
0622
0623 mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
0624 mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
0625 mci_fsta = readl(host->base + S3C2410_SDIFSTA);
0626 mci_dclear = 0;
0627
0628 if ((host->complete_what == COMPLETION_NONE) ||
0629 (host->complete_what == COMPLETION_FINALIZE)) {
0630 host->status = "nothing to complete";
0631 clear_imask(host);
0632 goto irq_out;
0633 }
0634
0635 if (!host->mrq) {
0636 host->status = "no active mrq";
0637 clear_imask(host);
0638 goto irq_out;
0639 }
0640
0641 cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd;
0642
0643 if (!cmd) {
0644 host->status = "no active cmd";
0645 clear_imask(host);
0646 goto irq_out;
0647 }
0648
0649 if (!s3cmci_host_usedma(host)) {
0650 if ((host->pio_active == XFER_WRITE) &&
0651 (mci_fsta & S3C2410_SDIFSTA_TFDET)) {
0652
0653 disable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
0654 tasklet_schedule(&host->pio_tasklet);
0655 host->status = "pio tx";
0656 }
0657
0658 if ((host->pio_active == XFER_READ) &&
0659 (mci_fsta & S3C2410_SDIFSTA_RFDET)) {
0660
0661 disable_imask(host,
0662 S3C2410_SDIIMSK_RXFIFOHALF |
0663 S3C2410_SDIIMSK_RXFIFOLAST);
0664
0665 tasklet_schedule(&host->pio_tasklet);
0666 host->status = "pio rx";
0667 }
0668 }
0669
0670 if (mci_csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
0671 dbg(host, dbg_err, "CMDSTAT: error CMDTIMEOUT\n");
0672 cmd->error = -ETIMEDOUT;
0673 host->status = "error: command timeout";
0674 goto fail_transfer;
0675 }
0676
0677 if (mci_csta & S3C2410_SDICMDSTAT_CMDSENT) {
0678 if (host->complete_what == COMPLETION_CMDSENT) {
0679 host->status = "ok: command sent";
0680 goto close_transfer;
0681 }
0682
0683 mci_cclear |= S3C2410_SDICMDSTAT_CMDSENT;
0684 }
0685
0686 if (mci_csta & S3C2410_SDICMDSTAT_CRCFAIL) {
0687 if (cmd->flags & MMC_RSP_CRC) {
0688 if (host->mrq->cmd->flags & MMC_RSP_136) {
0689 dbg(host, dbg_irq,
0690 "fixup: ignore CRC fail with long rsp\n");
0691 } else {
0692
0693
0694
0695
0696
0697
0698
0699
0700 }
0701 }
0702
0703 mci_cclear |= S3C2410_SDICMDSTAT_CRCFAIL;
0704 }
0705
0706 if (mci_csta & S3C2410_SDICMDSTAT_RSPFIN) {
0707 if (host->complete_what == COMPLETION_RSPFIN) {
0708 host->status = "ok: command response received";
0709 goto close_transfer;
0710 }
0711
0712 if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
0713 host->complete_what = COMPLETION_XFERFINISH;
0714
0715 mci_cclear |= S3C2410_SDICMDSTAT_RSPFIN;
0716 }
0717
0718
0719
0720
0721 if (!cmd->data)
0722 goto clear_status_bits;
0723
0724
0725 if (host->is2440) {
0726 if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
0727 dbg(host, dbg_err, "FIFO failure\n");
0728 host->mrq->data->error = -EILSEQ;
0729 host->status = "error: 2440 fifo failure";
0730 goto fail_transfer;
0731 }
0732 } else {
0733 if (mci_dsta & S3C2410_SDIDSTA_FIFOFAIL) {
0734 dbg(host, dbg_err, "FIFO failure\n");
0735 cmd->data->error = -EILSEQ;
0736 host->status = "error: fifo failure";
0737 goto fail_transfer;
0738 }
0739 }
0740
0741 if (mci_dsta & S3C2410_SDIDSTA_RXCRCFAIL) {
0742 dbg(host, dbg_err, "bad data crc (outgoing)\n");
0743 cmd->data->error = -EILSEQ;
0744 host->status = "error: bad data crc (outgoing)";
0745 goto fail_transfer;
0746 }
0747
0748 if (mci_dsta & S3C2410_SDIDSTA_CRCFAIL) {
0749 dbg(host, dbg_err, "bad data crc (incoming)\n");
0750 cmd->data->error = -EILSEQ;
0751 host->status = "error: bad data crc (incoming)";
0752 goto fail_transfer;
0753 }
0754
0755 if (mci_dsta & S3C2410_SDIDSTA_DATATIMEOUT) {
0756 dbg(host, dbg_err, "data timeout\n");
0757 cmd->data->error = -ETIMEDOUT;
0758 host->status = "error: data timeout";
0759 goto fail_transfer;
0760 }
0761
0762 if (mci_dsta & S3C2410_SDIDSTA_XFERFINISH) {
0763 if (host->complete_what == COMPLETION_XFERFINISH) {
0764 host->status = "ok: data transfer completed";
0765 goto close_transfer;
0766 }
0767
0768 if (host->complete_what == COMPLETION_XFERFINISH_RSPFIN)
0769 host->complete_what = COMPLETION_RSPFIN;
0770
0771 mci_dclear |= S3C2410_SDIDSTA_XFERFINISH;
0772 }
0773
0774 clear_status_bits:
0775 writel(mci_cclear, host->base + S3C2410_SDICMDSTAT);
0776 writel(mci_dclear, host->base + S3C2410_SDIDSTA);
0777
0778 goto irq_out;
0779
0780 fail_transfer:
0781 host->pio_active = XFER_NONE;
0782
0783 close_transfer:
0784 host->complete_what = COMPLETION_FINALIZE;
0785
0786 clear_imask(host);
0787 tasklet_schedule(&host->pio_tasklet);
0788
0789 goto irq_out;
0790
0791 irq_out:
0792 dbg(host, dbg_irq,
0793 "csta:0x%08x dsta:0x%08x fsta:0x%08x dcnt:0x%08x status:%s.\n",
0794 mci_csta, mci_dsta, mci_fsta, mci_dcnt, host->status);
0795
0796 spin_unlock_irqrestore(&host->complete_lock, iflags);
0797 return IRQ_HANDLED;
0798
0799 }
0800
0801 static void s3cmci_dma_done_callback(void *arg)
0802 {
0803 struct s3cmci_host *host = arg;
0804 unsigned long iflags;
0805
0806 BUG_ON(!host->mrq);
0807 BUG_ON(!host->mrq->data);
0808
0809 spin_lock_irqsave(&host->complete_lock, iflags);
0810
0811 dbg(host, dbg_dma, "DMA FINISHED\n");
0812
0813 host->dma_complete = 1;
0814 host->complete_what = COMPLETION_FINALIZE;
0815
0816 tasklet_schedule(&host->pio_tasklet);
0817 spin_unlock_irqrestore(&host->complete_lock, iflags);
0818
0819 }
0820
0821 static void finalize_request(struct s3cmci_host *host)
0822 {
0823 struct mmc_request *mrq = host->mrq;
0824 struct mmc_command *cmd;
0825 int debug_as_failure = 0;
0826
0827 if (host->complete_what != COMPLETION_FINALIZE)
0828 return;
0829
0830 if (!mrq)
0831 return;
0832 cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
0833
0834 if (cmd->data && (cmd->error == 0) &&
0835 (cmd->data->error == 0)) {
0836 if (s3cmci_host_usedma(host) && (!host->dma_complete)) {
0837 dbg(host, dbg_dma, "DMA Missing (%d)!\n",
0838 host->dma_complete);
0839 return;
0840 }
0841 }
0842
0843
0844 cmd->resp[0] = readl(host->base + S3C2410_SDIRSP0);
0845 cmd->resp[1] = readl(host->base + S3C2410_SDIRSP1);
0846 cmd->resp[2] = readl(host->base + S3C2410_SDIRSP2);
0847 cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
0848
0849 writel(host->prescaler, host->base + S3C2410_SDIPRE);
0850
0851 if (cmd->error)
0852 debug_as_failure = 1;
0853
0854 if (cmd->data && cmd->data->error)
0855 debug_as_failure = 1;
0856
0857 dbg_dumpcmd(host, cmd, debug_as_failure);
0858
0859
0860 writel(0, host->base + S3C2410_SDICMDARG);
0861 writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
0862 writel(0, host->base + S3C2410_SDICMDCON);
0863 clear_imask(host);
0864
0865 if (cmd->data && cmd->error)
0866 cmd->data->error = cmd->error;
0867
0868 if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) {
0869 host->cmd_is_stop = 1;
0870 s3cmci_send_request(host->mmc);
0871 return;
0872 }
0873
0874
0875 if (!mrq->data)
0876 goto request_done;
0877
0878
0879 if (mrq->data->error == 0) {
0880 mrq->data->bytes_xfered =
0881 (mrq->data->blocks * mrq->data->blksz);
0882 } else {
0883 mrq->data->bytes_xfered = 0;
0884 }
0885
0886
0887
0888 if (mrq->data->error != 0) {
0889 if (s3cmci_host_usedma(host))
0890 dmaengine_terminate_all(host->dma);
0891
0892 if (host->is2440) {
0893
0894 writel(S3C2440_SDIFSTA_FIFORESET |
0895 S3C2440_SDIFSTA_FIFOFAIL,
0896 host->base + S3C2410_SDIFSTA);
0897 } else {
0898 u32 mci_con;
0899
0900
0901 mci_con = readl(host->base + S3C2410_SDICON);
0902 mci_con |= S3C2410_SDICON_FIFORESET;
0903
0904 writel(mci_con, host->base + S3C2410_SDICON);
0905 }
0906 }
0907
0908 request_done:
0909 host->complete_what = COMPLETION_NONE;
0910 host->mrq = NULL;
0911
0912 s3cmci_check_sdio_irq(host);
0913 mmc_request_done(host->mmc, mrq);
0914 }
0915
0916 static void s3cmci_send_command(struct s3cmci_host *host,
0917 struct mmc_command *cmd)
0918 {
0919 u32 ccon, imsk;
0920
0921 imsk = S3C2410_SDIIMSK_CRCSTATUS | S3C2410_SDIIMSK_CMDTIMEOUT |
0922 S3C2410_SDIIMSK_RESPONSEND | S3C2410_SDIIMSK_CMDSENT |
0923 S3C2410_SDIIMSK_RESPONSECRC;
0924
0925 enable_imask(host, imsk);
0926
0927 if (cmd->data)
0928 host->complete_what = COMPLETION_XFERFINISH_RSPFIN;
0929 else if (cmd->flags & MMC_RSP_PRESENT)
0930 host->complete_what = COMPLETION_RSPFIN;
0931 else
0932 host->complete_what = COMPLETION_CMDSENT;
0933
0934 writel(cmd->arg, host->base + S3C2410_SDICMDARG);
0935
0936 ccon = cmd->opcode & S3C2410_SDICMDCON_INDEX;
0937 ccon |= S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
0938
0939 if (cmd->flags & MMC_RSP_PRESENT)
0940 ccon |= S3C2410_SDICMDCON_WAITRSP;
0941
0942 if (cmd->flags & MMC_RSP_136)
0943 ccon |= S3C2410_SDICMDCON_LONGRSP;
0944
0945 writel(ccon, host->base + S3C2410_SDICMDCON);
0946 }
0947
0948 static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
0949 {
0950 u32 dcon, imsk, stoptries = 3;
0951
0952 if ((data->blksz & 3) != 0) {
0953
0954
0955
0956 if (data->blocks > 1) {
0957 pr_warn("%s: can't do non-word sized block transfers (blksz %d)\n",
0958 __func__, data->blksz);
0959 return -EINVAL;
0960 }
0961 }
0962
0963 while (readl(host->base + S3C2410_SDIDSTA) &
0964 (S3C2410_SDIDSTA_TXDATAON | S3C2410_SDIDSTA_RXDATAON)) {
0965
0966 dbg(host, dbg_err,
0967 "mci_setup_data() transfer stillin progress.\n");
0968
0969 writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
0970 s3cmci_reset(host);
0971
0972 if ((stoptries--) == 0) {
0973 dbg_dumpregs(host, "DRF");
0974 return -EINVAL;
0975 }
0976 }
0977
0978 dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
0979
0980 if (s3cmci_host_usedma(host))
0981 dcon |= S3C2410_SDIDCON_DMAEN;
0982
0983 if (host->bus_width == MMC_BUS_WIDTH_4)
0984 dcon |= S3C2410_SDIDCON_WIDEBUS;
0985
0986 dcon |= S3C2410_SDIDCON_BLOCKMODE;
0987
0988 if (data->flags & MMC_DATA_WRITE) {
0989 dcon |= S3C2410_SDIDCON_TXAFTERRESP;
0990 dcon |= S3C2410_SDIDCON_XFER_TXSTART;
0991 }
0992
0993 if (data->flags & MMC_DATA_READ) {
0994 dcon |= S3C2410_SDIDCON_RXAFTERCMD;
0995 dcon |= S3C2410_SDIDCON_XFER_RXSTART;
0996 }
0997
0998 if (host->is2440) {
0999 dcon |= S3C2440_SDIDCON_DS_WORD;
1000 dcon |= S3C2440_SDIDCON_DATSTART;
1001 }
1002
1003 writel(dcon, host->base + S3C2410_SDIDCON);
1004
1005
1006
1007 writel(data->blksz, host->base + S3C2410_SDIBSIZE);
1008
1009
1010 imsk = S3C2410_SDIIMSK_FIFOFAIL | S3C2410_SDIIMSK_DATACRC |
1011 S3C2410_SDIIMSK_DATATIMEOUT | S3C2410_SDIIMSK_DATAFINISH;
1012
1013 enable_imask(host, imsk);
1014
1015
1016
1017 if (host->is2440) {
1018 writel(0x007FFFFF, host->base + S3C2410_SDITIMER);
1019 } else {
1020 writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
1021
1022
1023 if (data->flags & MMC_DATA_READ)
1024 writel(0xFF, host->base + S3C2410_SDIPRE);
1025 }
1026
1027 return 0;
1028 }
1029
1030 #define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ)
1031
1032 static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
1033 {
1034 int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
1035
1036 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
1037
1038 host->pio_sgptr = 0;
1039 host->pio_bytes = 0;
1040 host->pio_count = 0;
1041 host->pio_active = rw ? XFER_WRITE : XFER_READ;
1042
1043 if (rw) {
1044 do_pio_write(host);
1045 enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
1046 } else {
1047 enable_imask(host, S3C2410_SDIIMSK_RXFIFOHALF
1048 | S3C2410_SDIIMSK_RXFIFOLAST);
1049 }
1050
1051 return 0;
1052 }
1053
1054 static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
1055 {
1056 int rw = data->flags & MMC_DATA_WRITE;
1057 struct dma_async_tx_descriptor *desc;
1058 struct dma_slave_config conf = {
1059 .src_addr = host->mem->start + host->sdidata,
1060 .dst_addr = host->mem->start + host->sdidata,
1061 .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
1062 .dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
1063 };
1064
1065 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
1066
1067
1068 writel(host->prescaler, host->base + S3C2410_SDIPRE);
1069
1070 if (!rw)
1071 conf.direction = DMA_DEV_TO_MEM;
1072 else
1073 conf.direction = DMA_MEM_TO_DEV;
1074
1075 dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
1076 mmc_get_dma_dir(data));
1077
1078 dmaengine_slave_config(host->dma, &conf);
1079 desc = dmaengine_prep_slave_sg(host->dma, data->sg, data->sg_len,
1080 conf.direction,
1081 DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
1082 if (!desc)
1083 goto unmap_exit;
1084 desc->callback = s3cmci_dma_done_callback;
1085 desc->callback_param = host;
1086 dmaengine_submit(desc);
1087 dma_async_issue_pending(host->dma);
1088
1089 return 0;
1090
1091 unmap_exit:
1092 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
1093 mmc_get_dma_dir(data));
1094 return -ENOMEM;
1095 }
1096
1097 static void s3cmci_send_request(struct mmc_host *mmc)
1098 {
1099 struct s3cmci_host *host = mmc_priv(mmc);
1100 struct mmc_request *mrq = host->mrq;
1101 struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
1102
1103 host->ccnt++;
1104 prepare_dbgmsg(host, cmd, host->cmd_is_stop);
1105
1106
1107
1108
1109 writel(0xFFFFFFFF, host->base + S3C2410_SDICMDSTAT);
1110 writel(0xFFFFFFFF, host->base + S3C2410_SDIDSTA);
1111 writel(0xFFFFFFFF, host->base + S3C2410_SDIFSTA);
1112
1113 if (cmd->data) {
1114 int res = s3cmci_setup_data(host, cmd->data);
1115
1116 host->dcnt++;
1117
1118 if (res) {
1119 dbg(host, dbg_err, "setup data error %d\n", res);
1120 cmd->error = res;
1121 cmd->data->error = res;
1122
1123 mmc_request_done(mmc, mrq);
1124 return;
1125 }
1126
1127 if (s3cmci_host_usedma(host))
1128 res = s3cmci_prepare_dma(host, cmd->data);
1129 else
1130 res = s3cmci_prepare_pio(host, cmd->data);
1131
1132 if (res) {
1133 dbg(host, dbg_err, "data prepare error %d\n", res);
1134 cmd->error = res;
1135 cmd->data->error = res;
1136
1137 mmc_request_done(mmc, mrq);
1138 return;
1139 }
1140 }
1141
1142
1143 s3cmci_send_command(host, cmd);
1144
1145
1146 s3cmci_enable_irq(host, true);
1147 }
1148
1149 static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1150 {
1151 struct s3cmci_host *host = mmc_priv(mmc);
1152
1153 host->status = "mmc request";
1154 host->cmd_is_stop = 0;
1155 host->mrq = mrq;
1156
1157 if (mmc_gpio_get_cd(mmc) == 0) {
1158 dbg(host, dbg_err, "%s: no medium present\n", __func__);
1159 host->mrq->cmd->error = -ENOMEDIUM;
1160 mmc_request_done(mmc, mrq);
1161 } else
1162 s3cmci_send_request(mmc);
1163 }
1164
1165 static void s3cmci_set_clk(struct s3cmci_host *host, struct mmc_ios *ios)
1166 {
1167 u32 mci_psc;
1168
1169
1170 for (mci_psc = 0; mci_psc < 255; mci_psc++) {
1171 host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));
1172
1173 if (host->real_rate <= ios->clock)
1174 break;
1175 }
1176
1177 if (mci_psc > 255)
1178 mci_psc = 255;
1179
1180 host->prescaler = mci_psc;
1181 writel(host->prescaler, host->base + S3C2410_SDIPRE);
1182
1183
1184 if (ios->clock == 0)
1185 host->real_rate = 0;
1186 }
1187
1188 static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1189 {
1190 struct s3cmci_host *host = mmc_priv(mmc);
1191 u32 mci_con;
1192
1193
1194
1195 mci_con = readl(host->base + S3C2410_SDICON);
1196
1197 switch (ios->power_mode) {
1198 case MMC_POWER_ON:
1199 case MMC_POWER_UP:
1200 if (!host->is2440)
1201 mci_con |= S3C2410_SDICON_FIFORESET;
1202 break;
1203
1204 case MMC_POWER_OFF:
1205 default:
1206 if (host->is2440)
1207 mci_con |= S3C2440_SDICON_SDRESET;
1208 break;
1209 }
1210
1211 if (host->pdata->set_power)
1212 host->pdata->set_power(ios->power_mode, ios->vdd);
1213
1214 s3cmci_set_clk(host, ios);
1215
1216
1217 if (ios->clock)
1218 mci_con |= S3C2410_SDICON_CLOCKTYPE;
1219 else
1220 mci_con &= ~S3C2410_SDICON_CLOCKTYPE;
1221
1222 writel(mci_con, host->base + S3C2410_SDICON);
1223
1224 if ((ios->power_mode == MMC_POWER_ON) ||
1225 (ios->power_mode == MMC_POWER_UP)) {
1226 dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",
1227 host->real_rate/1000, ios->clock/1000);
1228 } else {
1229 dbg(host, dbg_conf, "powered down.\n");
1230 }
1231
1232 host->bus_width = ios->bus_width;
1233 }
1234
1235 static void s3cmci_reset(struct s3cmci_host *host)
1236 {
1237 u32 con = readl(host->base + S3C2410_SDICON);
1238
1239 con |= S3C2440_SDICON_SDRESET;
1240 writel(con, host->base + S3C2410_SDICON);
1241 }
1242
1243 static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1244 {
1245 struct s3cmci_host *host = mmc_priv(mmc);
1246 unsigned long flags;
1247 u32 con;
1248
1249 local_irq_save(flags);
1250
1251 con = readl(host->base + S3C2410_SDICON);
1252 host->sdio_irqen = enable;
1253
1254 if (enable == host->sdio_irqen)
1255 goto same_state;
1256
1257 if (enable) {
1258 con |= S3C2410_SDICON_SDIOIRQ;
1259 enable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
1260
1261 if (!host->irq_state && !host->irq_disabled) {
1262 host->irq_state = true;
1263 enable_irq(host->irq);
1264 }
1265 } else {
1266 disable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
1267 con &= ~S3C2410_SDICON_SDIOIRQ;
1268
1269 if (!host->irq_enabled && host->irq_state) {
1270 disable_irq_nosync(host->irq);
1271 host->irq_state = false;
1272 }
1273 }
1274
1275 writel(con, host->base + S3C2410_SDICON);
1276
1277 same_state:
1278 local_irq_restore(flags);
1279
1280 s3cmci_check_sdio_irq(host);
1281 }
1282
1283 static const struct mmc_host_ops s3cmci_ops = {
1284 .request = s3cmci_request,
1285 .set_ios = s3cmci_set_ios,
1286 .get_ro = mmc_gpio_get_ro,
1287 .get_cd = mmc_gpio_get_cd,
1288 .enable_sdio_irq = s3cmci_enable_sdio_irq,
1289 };
1290
1291 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ
1292
1293 static int s3cmci_cpufreq_transition(struct notifier_block *nb,
1294 unsigned long val, void *data)
1295 {
1296 struct s3cmci_host *host;
1297 struct mmc_host *mmc;
1298 unsigned long newclk;
1299 unsigned long flags;
1300
1301 host = container_of(nb, struct s3cmci_host, freq_transition);
1302 newclk = clk_get_rate(host->clk);
1303 mmc = host->mmc;
1304
1305 if ((val == CPUFREQ_PRECHANGE && newclk > host->clk_rate) ||
1306 (val == CPUFREQ_POSTCHANGE && newclk < host->clk_rate)) {
1307 spin_lock_irqsave(&mmc->lock, flags);
1308
1309 host->clk_rate = newclk;
1310
1311 if (mmc->ios.power_mode != MMC_POWER_OFF &&
1312 mmc->ios.clock != 0)
1313 s3cmci_set_clk(host, &mmc->ios);
1314
1315 spin_unlock_irqrestore(&mmc->lock, flags);
1316 }
1317
1318 return 0;
1319 }
1320
1321 static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)
1322 {
1323 host->freq_transition.notifier_call = s3cmci_cpufreq_transition;
1324
1325 return cpufreq_register_notifier(&host->freq_transition,
1326 CPUFREQ_TRANSITION_NOTIFIER);
1327 }
1328
1329 static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
1330 {
1331 cpufreq_unregister_notifier(&host->freq_transition,
1332 CPUFREQ_TRANSITION_NOTIFIER);
1333 }
1334
1335 #else
1336 static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)
1337 {
1338 return 0;
1339 }
1340
1341 static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
1342 {
1343 }
1344 #endif
1345
1346
1347 #ifdef CONFIG_DEBUG_FS
1348
1349 static int s3cmci_state_show(struct seq_file *seq, void *v)
1350 {
1351 struct s3cmci_host *host = seq->private;
1352
1353 seq_printf(seq, "Register base = 0x%p\n", host->base);
1354 seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
1355 seq_printf(seq, "Prescale = %d\n", host->prescaler);
1356 seq_printf(seq, "is2440 = %d\n", host->is2440);
1357 seq_printf(seq, "IRQ = %d\n", host->irq);
1358 seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
1359 seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
1360 seq_printf(seq, "IRQ state = %d\n", host->irq_state);
1361 seq_printf(seq, "CD IRQ = %d\n", host->irq_cd);
1362 seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host));
1363 seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk);
1364 seq_printf(seq, "SDIDATA at %d\n", host->sdidata);
1365
1366 return 0;
1367 }
1368
1369 DEFINE_SHOW_ATTRIBUTE(s3cmci_state);
1370
1371 #define DBG_REG(_r) { .addr = S3C2410_SDI##_r, .name = #_r }
1372
1373 struct s3cmci_reg {
1374 unsigned short addr;
1375 unsigned char *name;
1376 };
1377
1378 static const struct s3cmci_reg debug_regs[] = {
1379 DBG_REG(CON),
1380 DBG_REG(PRE),
1381 DBG_REG(CMDARG),
1382 DBG_REG(CMDCON),
1383 DBG_REG(CMDSTAT),
1384 DBG_REG(RSP0),
1385 DBG_REG(RSP1),
1386 DBG_REG(RSP2),
1387 DBG_REG(RSP3),
1388 DBG_REG(TIMER),
1389 DBG_REG(BSIZE),
1390 DBG_REG(DCON),
1391 DBG_REG(DCNT),
1392 DBG_REG(DSTA),
1393 DBG_REG(FSTA),
1394 {}
1395 };
1396
1397 static int s3cmci_regs_show(struct seq_file *seq, void *v)
1398 {
1399 struct s3cmci_host *host = seq->private;
1400 const struct s3cmci_reg *rptr = debug_regs;
1401
1402 for (; rptr->name; rptr++)
1403 seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name,
1404 readl(host->base + rptr->addr));
1405
1406 seq_printf(seq, "SDIIMSK\t=0x%08x\n", readl(host->base + host->sdiimsk));
1407
1408 return 0;
1409 }
1410
1411 DEFINE_SHOW_ATTRIBUTE(s3cmci_regs);
1412
1413 static void s3cmci_debugfs_attach(struct s3cmci_host *host)
1414 {
1415 struct device *dev = &host->pdev->dev;
1416 struct dentry *root;
1417
1418 root = debugfs_create_dir(dev_name(dev), NULL);
1419 host->debug_root = root;
1420
1421 debugfs_create_file("state", 0444, root, host, &s3cmci_state_fops);
1422 debugfs_create_file("regs", 0444, root, host, &s3cmci_regs_fops);
1423 }
1424
1425 static void s3cmci_debugfs_remove(struct s3cmci_host *host)
1426 {
1427 debugfs_remove_recursive(host->debug_root);
1428 }
1429
1430 #else
1431 static inline void s3cmci_debugfs_attach(struct s3cmci_host *host) { }
1432 static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
1433
1434 #endif
1435
1436 static int s3cmci_probe_pdata(struct s3cmci_host *host)
1437 {
1438 struct platform_device *pdev = host->pdev;
1439 struct mmc_host *mmc = host->mmc;
1440 struct s3c24xx_mci_pdata *pdata;
1441 int i, ret;
1442
1443 host->is2440 = platform_get_device_id(pdev)->driver_data;
1444 pdata = pdev->dev.platform_data;
1445 if (!pdata) {
1446 dev_err(&pdev->dev, "need platform data");
1447 return -ENXIO;
1448 }
1449
1450 for (i = 0; i < 6; i++) {
1451 pdata->bus[i] = devm_gpiod_get_index(&pdev->dev, "bus", i,
1452 GPIOD_OUT_LOW);
1453 if (IS_ERR(pdata->bus[i])) {
1454 dev_err(&pdev->dev, "failed to get gpio %d\n", i);
1455 return PTR_ERR(pdata->bus[i]);
1456 }
1457 }
1458
1459 if (pdata->no_wprotect)
1460 mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
1461
1462 if (pdata->no_detect)
1463 mmc->caps |= MMC_CAP_NEEDS_POLL;
1464
1465 if (pdata->wprotect_invert)
1466 mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
1467
1468
1469 ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0);
1470 if (ret != -ENOENT) {
1471 dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
1472 ret);
1473 return ret;
1474 }
1475
1476 ret = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0);
1477 if (ret != -ENOENT) {
1478 dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
1479 ret);
1480 return ret;
1481 }
1482
1483 return 0;
1484 }
1485
1486 static int s3cmci_probe_dt(struct s3cmci_host *host)
1487 {
1488 struct platform_device *pdev = host->pdev;
1489 struct s3c24xx_mci_pdata *pdata;
1490 struct mmc_host *mmc = host->mmc;
1491 int ret;
1492
1493 host->is2440 = (long) of_device_get_match_data(&pdev->dev);
1494
1495 ret = mmc_of_parse(mmc);
1496 if (ret)
1497 return ret;
1498
1499 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
1500 if (!pdata)
1501 return -ENOMEM;
1502
1503 pdev->dev.platform_data = pdata;
1504
1505 return 0;
1506 }
1507
1508 static int s3cmci_probe(struct platform_device *pdev)
1509 {
1510 struct s3cmci_host *host;
1511 struct mmc_host *mmc;
1512 int ret;
1513
1514 mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
1515 if (!mmc) {
1516 ret = -ENOMEM;
1517 goto probe_out;
1518 }
1519
1520 host = mmc_priv(mmc);
1521 host->mmc = mmc;
1522 host->pdev = pdev;
1523
1524 if (pdev->dev.of_node)
1525 ret = s3cmci_probe_dt(host);
1526 else
1527 ret = s3cmci_probe_pdata(host);
1528
1529 if (ret)
1530 goto probe_free_host;
1531
1532 host->pdata = pdev->dev.platform_data;
1533
1534 spin_lock_init(&host->complete_lock);
1535 tasklet_setup(&host->pio_tasklet, pio_tasklet);
1536
1537 if (host->is2440) {
1538 host->sdiimsk = S3C2440_SDIIMSK;
1539 host->sdidata = S3C2440_SDIDATA;
1540 host->clk_div = 1;
1541 } else {
1542 host->sdiimsk = S3C2410_SDIIMSK;
1543 host->sdidata = S3C2410_SDIDATA;
1544 host->clk_div = 2;
1545 }
1546
1547 host->complete_what = COMPLETION_NONE;
1548 host->pio_active = XFER_NONE;
1549
1550 host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1551 if (!host->mem) {
1552 dev_err(&pdev->dev,
1553 "failed to get io memory region resource.\n");
1554
1555 ret = -ENOENT;
1556 goto probe_free_host;
1557 }
1558
1559 host->mem = request_mem_region(host->mem->start,
1560 resource_size(host->mem), pdev->name);
1561
1562 if (!host->mem) {
1563 dev_err(&pdev->dev, "failed to request io memory region.\n");
1564 ret = -ENOENT;
1565 goto probe_free_host;
1566 }
1567
1568 host->base = ioremap(host->mem->start, resource_size(host->mem));
1569 if (!host->base) {
1570 dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
1571 ret = -EINVAL;
1572 goto probe_free_mem_region;
1573 }
1574
1575 host->irq = platform_get_irq(pdev, 0);
1576 if (host->irq <= 0) {
1577 ret = -EINVAL;
1578 goto probe_iounmap;
1579 }
1580
1581 if (request_irq(host->irq, s3cmci_irq, IRQF_NO_AUTOEN, DRIVER_NAME, host)) {
1582 dev_err(&pdev->dev, "failed to request mci interrupt.\n");
1583 ret = -ENOENT;
1584 goto probe_iounmap;
1585 }
1586
1587 host->irq_state = false;
1588
1589
1590
1591 if (s3cmci_host_usedma(host)) {
1592 host->dma = dma_request_chan(&pdev->dev, "rx-tx");
1593 ret = PTR_ERR_OR_ZERO(host->dma);
1594 if (ret) {
1595 dev_err(&pdev->dev, "cannot get DMA channel.\n");
1596 goto probe_free_irq;
1597 }
1598 }
1599
1600 host->clk = clk_get(&pdev->dev, "sdi");
1601 if (IS_ERR(host->clk)) {
1602 dev_err(&pdev->dev, "failed to find clock source.\n");
1603 ret = PTR_ERR(host->clk);
1604 host->clk = NULL;
1605 goto probe_free_dma;
1606 }
1607
1608 ret = clk_prepare_enable(host->clk);
1609 if (ret) {
1610 dev_err(&pdev->dev, "failed to enable clock source.\n");
1611 goto clk_free;
1612 }
1613
1614 host->clk_rate = clk_get_rate(host->clk);
1615
1616 mmc->ops = &s3cmci_ops;
1617 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1618 #ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
1619 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
1620 #else
1621 mmc->caps = MMC_CAP_4_BIT_DATA;
1622 #endif
1623 mmc->f_min = host->clk_rate / (host->clk_div * 256);
1624 mmc->f_max = host->clk_rate / host->clk_div;
1625
1626 if (host->pdata->ocr_avail)
1627 mmc->ocr_avail = host->pdata->ocr_avail;
1628
1629 mmc->max_blk_count = 4095;
1630 mmc->max_blk_size = 4095;
1631 mmc->max_req_size = 4095 * 512;
1632 mmc->max_seg_size = mmc->max_req_size;
1633
1634 mmc->max_segs = 128;
1635
1636 dbg(host, dbg_debug,
1637 "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%p.\n",
1638 (host->is2440?"2440":""),
1639 host->base, host->irq, host->irq_cd, host->dma);
1640
1641 ret = s3cmci_cpufreq_register(host);
1642 if (ret) {
1643 dev_err(&pdev->dev, "failed to register cpufreq\n");
1644 goto free_dmabuf;
1645 }
1646
1647 ret = mmc_add_host(mmc);
1648 if (ret) {
1649 dev_err(&pdev->dev, "failed to add mmc host.\n");
1650 goto free_cpufreq;
1651 }
1652
1653 s3cmci_debugfs_attach(host);
1654
1655 platform_set_drvdata(pdev, mmc);
1656 dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),
1657 s3cmci_host_usedma(host) ? "dma" : "pio",
1658 mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
1659
1660 return 0;
1661
1662 free_cpufreq:
1663 s3cmci_cpufreq_deregister(host);
1664
1665 free_dmabuf:
1666 clk_disable_unprepare(host->clk);
1667
1668 clk_free:
1669 clk_put(host->clk);
1670
1671 probe_free_dma:
1672 if (s3cmci_host_usedma(host))
1673 dma_release_channel(host->dma);
1674
1675 probe_free_irq:
1676 free_irq(host->irq, host);
1677
1678 probe_iounmap:
1679 iounmap(host->base);
1680
1681 probe_free_mem_region:
1682 release_mem_region(host->mem->start, resource_size(host->mem));
1683
1684 probe_free_host:
1685 mmc_free_host(mmc);
1686
1687 probe_out:
1688 return ret;
1689 }
1690
1691 static void s3cmci_shutdown(struct platform_device *pdev)
1692 {
1693 struct mmc_host *mmc = platform_get_drvdata(pdev);
1694 struct s3cmci_host *host = mmc_priv(mmc);
1695
1696 if (host->irq_cd >= 0)
1697 free_irq(host->irq_cd, host);
1698
1699 s3cmci_debugfs_remove(host);
1700 s3cmci_cpufreq_deregister(host);
1701 mmc_remove_host(mmc);
1702 clk_disable_unprepare(host->clk);
1703 }
1704
1705 static int s3cmci_remove(struct platform_device *pdev)
1706 {
1707 struct mmc_host *mmc = platform_get_drvdata(pdev);
1708 struct s3cmci_host *host = mmc_priv(mmc);
1709
1710 s3cmci_shutdown(pdev);
1711
1712 clk_put(host->clk);
1713
1714 tasklet_disable(&host->pio_tasklet);
1715
1716 if (s3cmci_host_usedma(host))
1717 dma_release_channel(host->dma);
1718
1719 free_irq(host->irq, host);
1720
1721 iounmap(host->base);
1722 release_mem_region(host->mem->start, resource_size(host->mem));
1723
1724 mmc_free_host(mmc);
1725 return 0;
1726 }
1727
1728 static const struct of_device_id s3cmci_dt_match[] = {
1729 {
1730 .compatible = "samsung,s3c2410-sdi",
1731 .data = (void *)0,
1732 },
1733 {
1734 .compatible = "samsung,s3c2412-sdi",
1735 .data = (void *)1,
1736 },
1737 {
1738 .compatible = "samsung,s3c2440-sdi",
1739 .data = (void *)1,
1740 },
1741 { },
1742 };
1743 MODULE_DEVICE_TABLE(of, s3cmci_dt_match);
1744
1745 static const struct platform_device_id s3cmci_driver_ids[] = {
1746 {
1747 .name = "s3c2410-sdi",
1748 .driver_data = 0,
1749 }, {
1750 .name = "s3c2412-sdi",
1751 .driver_data = 1,
1752 }, {
1753 .name = "s3c2440-sdi",
1754 .driver_data = 1,
1755 },
1756 { }
1757 };
1758
1759 MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
1760
1761 static struct platform_driver s3cmci_driver = {
1762 .driver = {
1763 .name = "s3c-sdi",
1764 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
1765 .of_match_table = s3cmci_dt_match,
1766 },
1767 .id_table = s3cmci_driver_ids,
1768 .probe = s3cmci_probe,
1769 .remove = s3cmci_remove,
1770 .shutdown = s3cmci_shutdown,
1771 };
1772
1773 module_platform_driver(s3cmci_driver);
1774
1775 MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
1776 MODULE_LICENSE("GPL v2");
1777 MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");