1 /* 2 * TI FlashMedia driver 3 * 4 * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Special thanks to Carlos Corbacho for providing various MemoryStick cards 11 * that made this driver possible. 12 * 13 */ 14 15 #include <linux/tifm.h> 16 #include <linux/memstick.h> 17 #include <linux/highmem.h> 18 #include <linux/scatterlist.h> 19 #include <linux/log2.h> 20 #include <asm/io.h> 21 22 #define DRIVER_NAME "tifm_ms" 23 24 static int no_dma; 25 module_param(no_dma, bool, 0644); 26 27 /* 28 * Some control bits of TIFM appear to conform to Sony's reference design, 29 * so I'm just assuming they all are. 30 */ 31 32 #define TIFM_MS_STAT_DRQ 0x04000 33 #define TIFM_MS_STAT_MSINT 0x02000 34 #define TIFM_MS_STAT_RDY 0x01000 35 #define TIFM_MS_STAT_CRC 0x00200 36 #define TIFM_MS_STAT_TOE 0x00100 37 #define TIFM_MS_STAT_EMP 0x00020 38 #define TIFM_MS_STAT_FUL 0x00010 39 #define TIFM_MS_STAT_CED 0x00008 40 #define TIFM_MS_STAT_ERR 0x00004 41 #define TIFM_MS_STAT_BRQ 0x00002 42 #define TIFM_MS_STAT_CNK 0x00001 43 44 #define TIFM_MS_SYS_DMA 0x10000 45 #define TIFM_MS_SYS_RESET 0x08000 46 #define TIFM_MS_SYS_SRAC 0x04000 47 #define TIFM_MS_SYS_INTEN 0x02000 48 #define TIFM_MS_SYS_NOCRC 0x01000 49 #define TIFM_MS_SYS_INTCLR 0x00800 50 #define TIFM_MS_SYS_MSIEN 0x00400 51 #define TIFM_MS_SYS_FCLR 0x00200 52 #define TIFM_MS_SYS_FDIR 0x00100 53 #define TIFM_MS_SYS_DAM 0x00080 54 #define TIFM_MS_SYS_DRM 0x00040 55 #define TIFM_MS_SYS_DRQSL 0x00020 56 #define TIFM_MS_SYS_REI 0x00010 57 #define TIFM_MS_SYS_REO 0x00008 58 #define TIFM_MS_SYS_BSY_MASK 0x00007 59 60 #define TIFM_MS_SYS_FIFO (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \ 61 | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK) 62 63 /* Hardware flags */ 64 enum { 65 CMD_READY = 0x01, 66 FIFO_READY = 0x02, 67 CARD_INT = 0x04 68 }; 69 70 struct tifm_ms { 71 struct tifm_dev *dev; 72 struct timer_list timer; 73 struct memstick_request *req; 74 unsigned int mode_mask; 75 unsigned int block_pos; 76 unsigned long timeout_jiffies; 77 unsigned char eject:1, 78 use_dma:1; 79 unsigned char cmd_flags; 80 unsigned char io_pos; 81 unsigned int io_word; 82 }; 83 84 static unsigned int tifm_ms_read_data(struct tifm_ms *host, 85 unsigned char *buf, unsigned int length) 86 { 87 struct tifm_dev *sock = host->dev; 88 unsigned int off = 0; 89 90 while (host->io_pos && length) { 91 buf[off++] = host->io_word & 0xff; 92 host->io_word >>= 8; 93 length--; 94 host->io_pos--; 95 } 96 97 if (!length) 98 return off; 99 100 while (!(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) { 101 if (length < 4) 102 break; 103 *(unsigned int *)(buf + off) = __raw_readl(sock->addr 104 + SOCK_MS_DATA); 105 length -= 4; 106 off += 4; 107 } 108 109 if (length 110 && !(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) { 111 host->io_word = readl(sock->addr + SOCK_MS_DATA); 112 for (host->io_pos = 4; host->io_pos; --host->io_pos) { 113 buf[off++] = host->io_word & 0xff; 114 host->io_word >>= 8; 115 length--; 116 if (!length) 117 break; 118 } 119 } 120 121 return off; 122 } 123 124 static unsigned int tifm_ms_write_data(struct tifm_ms *host, 125 unsigned char *buf, unsigned int length) 126 { 127 struct tifm_dev *sock = host->dev; 128 unsigned int off = 0; 129 130 if (host->io_pos) { 131 while (host->io_pos < 4 && length) { 132 host->io_word |= buf[off++] << (host->io_pos * 8); 133 host->io_pos++; 134 length--; 135 } 136 } 137 138 if (host->io_pos == 4 139 && !(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) { 140 writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM), 141 sock->addr + SOCK_MS_SYSTEM); 142 writel(host->io_word, sock->addr + SOCK_MS_DATA); 143 host->io_pos = 0; 144 host->io_word = 0; 145 } else if (host->io_pos) { 146 return off; 147 } 148 149 if (!length) 150 return off; 151 152 while (!(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) { 153 if (length < 4) 154 break; 155 writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM), 156 sock->addr + SOCK_MS_SYSTEM); 157 __raw_writel(*(unsigned int *)(buf + off), 158 sock->addr + SOCK_MS_DATA); 159 length -= 4; 160 off += 4; 161 } 162 163 switch (length) { 164 case 3: 165 host->io_word |= buf[off + 2] << 16; 166 host->io_pos++; 167 case 2: 168 host->io_word |= buf[off + 1] << 8; 169 host->io_pos++; 170 case 1: 171 host->io_word |= buf[off]; 172 host->io_pos++; 173 } 174 175 off += host->io_pos; 176 177 return off; 178 } 179 180 static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) 181 { 182 struct tifm_dev *sock = host->dev; 183 unsigned int length; 184 unsigned int off; 185 unsigned int t_size, p_cnt; 186 unsigned char *buf; 187 struct page *pg; 188 unsigned long flags = 0; 189 190 if (host->req->long_data) { 191 length = host->req->sg.length - host->block_pos; 192 off = host->req->sg.offset + host->block_pos; 193 } else { 194 length = host->req->data_len - host->block_pos; 195 off = 0; 196 } 197 dev_dbg(&sock->dev, "fifo data transfer, %d, %d\n", length, 198 host->block_pos); 199 200 while (length) { 201 unsigned int uninitialized_var(p_off); 202 203 if (host->req->long_data) { 204 pg = nth_page(sg_page(&host->req->sg), 205 off >> PAGE_SHIFT); 206 p_off = offset_in_page(off); 207 p_cnt = PAGE_SIZE - p_off; 208 p_cnt = min(p_cnt, length); 209 210 local_irq_save(flags); 211 buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off; 212 } else { 213 buf = host->req->data + host->block_pos; 214 p_cnt = host->req->data_len - host->block_pos; 215 } 216 217 t_size = host->req->data_dir == WRITE 218 ? tifm_ms_write_data(host, buf, p_cnt) 219 : tifm_ms_read_data(host, buf, p_cnt); 220 221 if (host->req->long_data) { 222 kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ); 223 local_irq_restore(flags); 224 } 225 226 if (!t_size) 227 break; 228 host->block_pos += t_size; 229 length -= t_size; 230 off += t_size; 231 } 232 233 dev_dbg(&sock->dev, "fifo data transfer, %d remaining\n", length); 234 if (!length && (host->req->data_dir == WRITE)) { 235 if (host->io_pos) { 236 writel(TIFM_MS_SYS_FDIR 237 | readl(sock->addr + SOCK_MS_SYSTEM), 238 sock->addr + SOCK_MS_SYSTEM); 239 writel(host->io_word, sock->addr + SOCK_MS_DATA); 240 } 241 writel(TIFM_MS_SYS_FDIR 242 | readl(sock->addr + SOCK_MS_SYSTEM), 243 sock->addr + SOCK_MS_SYSTEM); 244 writel(0, sock->addr + SOCK_MS_DATA); 245 } else { 246 readl(sock->addr + SOCK_MS_DATA); 247 } 248 249 return length; 250 } 251 252 static int tifm_ms_issue_cmd(struct tifm_ms *host) 253 { 254 struct tifm_dev *sock = host->dev; 255 unsigned char *data; 256 unsigned int data_len, cmd, sys_param; 257 258 host->cmd_flags = 0; 259 host->block_pos = 0; 260 host->io_pos = 0; 261 host->io_word = 0; 262 host->cmd_flags = 0; 263 264 data = host->req->data; 265 266 host->use_dma = !no_dma; 267 268 if (host->req->long_data) { 269 data_len = host->req->sg.length; 270 if (!is_power_of_2(data_len)) 271 host->use_dma = 0; 272 } else { 273 data_len = host->req->data_len; 274 host->use_dma = 0; 275 } 276 277 writel(TIFM_FIFO_INT_SETALL, 278 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); 279 writel(TIFM_FIFO_ENABLE, 280 sock->addr + SOCK_FIFO_CONTROL); 281 282 if (host->use_dma) { 283 if (1 != tifm_map_sg(sock, &host->req->sg, 1, 284 host->req->data_dir == READ 285 ? PCI_DMA_FROMDEVICE 286 : PCI_DMA_TODEVICE)) { 287 host->req->error = -ENOMEM; 288 return host->req->error; 289 } 290 data_len = sg_dma_len(&host->req->sg); 291 292 writel(ilog2(data_len) - 2, 293 sock->addr + SOCK_FIFO_PAGE_SIZE); 294 writel(TIFM_FIFO_INTMASK, 295 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); 296 sys_param = TIFM_DMA_EN | (1 << 8); 297 if (host->req->data_dir == WRITE) 298 sys_param |= TIFM_DMA_TX; 299 300 writel(TIFM_FIFO_INTMASK, 301 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); 302 303 writel(sg_dma_address(&host->req->sg), 304 sock->addr + SOCK_DMA_ADDRESS); 305 writel(sys_param, sock->addr + SOCK_DMA_CONTROL); 306 } else { 307 writel(host->mode_mask | TIFM_MS_SYS_FIFO, 308 sock->addr + SOCK_MS_SYSTEM); 309 310 writel(TIFM_FIFO_MORE, 311 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); 312 } 313 314 mod_timer(&host->timer, jiffies + host->timeout_jiffies); 315 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), 316 sock->addr + SOCK_CONTROL); 317 host->req->error = 0; 318 319 sys_param = readl(sock->addr + SOCK_MS_SYSTEM); 320 sys_param |= TIFM_MS_SYS_INTCLR; 321 322 if (host->use_dma) 323 sys_param |= TIFM_MS_SYS_DMA; 324 else 325 sys_param &= ~TIFM_MS_SYS_DMA; 326 327 writel(sys_param, sock->addr + SOCK_MS_SYSTEM); 328 329 cmd = (host->req->tpc & 0xf) << 12; 330 cmd |= data_len; 331 writel(cmd, sock->addr + SOCK_MS_COMMAND); 332 333 dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, sys_param); 334 return 0; 335 } 336 337 static void tifm_ms_complete_cmd(struct tifm_ms *host) 338 { 339 struct tifm_dev *sock = host->dev; 340 struct memstick_host *msh = tifm_get_drvdata(sock); 341 int rc; 342 343 del_timer(&host->timer); 344 345 host->req->int_reg = readl(sock->addr + SOCK_MS_STATUS) & 0xff; 346 host->req->int_reg = (host->req->int_reg & 1) 347 | ((host->req->int_reg << 4) & 0xe0); 348 349 writel(TIFM_FIFO_INT_SETALL, 350 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); 351 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); 352 353 if (host->use_dma) { 354 tifm_unmap_sg(sock, &host->req->sg, 1, 355 host->req->data_dir == READ 356 ? PCI_DMA_FROMDEVICE 357 : PCI_DMA_TODEVICE); 358 } 359 360 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 361 sock->addr + SOCK_CONTROL); 362 363 dev_dbg(&sock->dev, "TPC complete\n"); 364 do { 365 rc = memstick_next_req(msh, &host->req); 366 } while (!rc && tifm_ms_issue_cmd(host)); 367 } 368 369 static int tifm_ms_check_status(struct tifm_ms *host) 370 { 371 if (!host->req->error) { 372 if (!(host->cmd_flags & CMD_READY)) 373 return 1; 374 if (!(host->cmd_flags & FIFO_READY)) 375 return 1; 376 if (host->req->need_card_int 377 && !(host->cmd_flags & CARD_INT)) 378 return 1; 379 } 380 return 0; 381 } 382 383 /* Called from interrupt handler */ 384 static void tifm_ms_data_event(struct tifm_dev *sock) 385 { 386 struct tifm_ms *host; 387 unsigned int fifo_status = 0, host_status = 0; 388 int rc = 1; 389 390 spin_lock(&sock->lock); 391 host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock)); 392 fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); 393 host_status = readl(sock->addr + SOCK_MS_STATUS); 394 dev_dbg(&sock->dev, 395 "data event: fifo_status %x, host_status %x, flags %x\n", 396 fifo_status, host_status, host->cmd_flags); 397 398 if (host->req) { 399 if (host->use_dma && (fifo_status & 1)) { 400 host->cmd_flags |= FIFO_READY; 401 rc = tifm_ms_check_status(host); 402 } 403 if (!host->use_dma && (fifo_status & TIFM_FIFO_MORE)) { 404 if (!tifm_ms_transfer_data(host)) { 405 host->cmd_flags |= FIFO_READY; 406 rc = tifm_ms_check_status(host); 407 } 408 } 409 } 410 411 writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); 412 if (!rc) 413 tifm_ms_complete_cmd(host); 414 415 spin_unlock(&sock->lock); 416 } 417 418 419 /* Called from interrupt handler */ 420 static void tifm_ms_card_event(struct tifm_dev *sock) 421 { 422 struct tifm_ms *host; 423 unsigned int host_status = 0; 424 int rc = 1; 425 426 spin_lock(&sock->lock); 427 host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock)); 428 host_status = readl(sock->addr + SOCK_MS_STATUS); 429 dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n", 430 host_status, host->cmd_flags); 431 432 if (host->req) { 433 if (host_status & TIFM_MS_STAT_TOE) 434 host->req->error = -ETIME; 435 else if (host_status & TIFM_MS_STAT_CRC) 436 host->req->error = -EILSEQ; 437 438 if (host_status & TIFM_MS_STAT_RDY) 439 host->cmd_flags |= CMD_READY; 440 441 if (host_status & TIFM_MS_STAT_MSINT) 442 host->cmd_flags |= CARD_INT; 443 444 rc = tifm_ms_check_status(host); 445 446 } 447 448 writel(TIFM_MS_SYS_INTCLR | readl(sock->addr + SOCK_MS_SYSTEM), 449 sock->addr + SOCK_MS_SYSTEM); 450 451 if (!rc) 452 tifm_ms_complete_cmd(host); 453 454 spin_unlock(&sock->lock); 455 return; 456 } 457 458 static void tifm_ms_request(struct memstick_host *msh) 459 { 460 struct tifm_ms *host = memstick_priv(msh); 461 struct tifm_dev *sock = host->dev; 462 unsigned long flags; 463 int rc; 464 465 spin_lock_irqsave(&sock->lock, flags); 466 if (host->req) { 467 printk(KERN_ERR "%s : unfinished request detected\n", 468 sock->dev.bus_id); 469 spin_unlock_irqrestore(&sock->lock, flags); 470 tifm_eject(host->dev); 471 return; 472 } 473 474 if (host->eject) { 475 do { 476 rc = memstick_next_req(msh, &host->req); 477 if (!rc) 478 host->req->error = -ETIME; 479 } while (!rc); 480 spin_unlock_irqrestore(&sock->lock, flags); 481 return; 482 } 483 484 do { 485 rc = memstick_next_req(msh, &host->req); 486 } while (!rc && tifm_ms_issue_cmd(host)); 487 488 spin_unlock_irqrestore(&sock->lock, flags); 489 return; 490 } 491 492 static void tifm_ms_set_param(struct memstick_host *msh, 493 enum memstick_param param, 494 int value) 495 { 496 struct tifm_ms *host = memstick_priv(msh); 497 struct tifm_dev *sock = host->dev; 498 unsigned long flags; 499 500 spin_lock_irqsave(&sock->lock, flags); 501 502 switch (param) { 503 case MEMSTICK_POWER: 504 /* also affected by media detection mechanism */ 505 if (value == MEMSTICK_POWER_ON) { 506 host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI; 507 writel(TIFM_MS_SYS_RESET, sock->addr + SOCK_MS_SYSTEM); 508 writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, 509 sock->addr + SOCK_MS_SYSTEM); 510 writel(0xffffffff, sock->addr + SOCK_MS_STATUS); 511 } else if (value == MEMSTICK_POWER_OFF) { 512 writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, 513 sock->addr + SOCK_MS_SYSTEM); 514 writel(0xffffffff, sock->addr + SOCK_MS_STATUS); 515 } 516 break; 517 case MEMSTICK_INTERFACE: 518 if (value == MEMSTICK_SERIAL) { 519 host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI; 520 writel((~TIFM_CTRL_FAST_CLK) 521 & readl(sock->addr + SOCK_CONTROL), 522 sock->addr + SOCK_CONTROL); 523 } else if (value == MEMSTICK_PAR4) { 524 host->mode_mask = 0; 525 writel(TIFM_CTRL_FAST_CLK 526 | readl(sock->addr + SOCK_CONTROL), 527 sock->addr + SOCK_CONTROL); 528 } 529 break; 530 }; 531 532 spin_unlock_irqrestore(&sock->lock, flags); 533 } 534 535 static void tifm_ms_abort(unsigned long data) 536 { 537 struct tifm_ms *host = (struct tifm_ms *)data; 538 539 dev_dbg(&host->dev->dev, "status %x\n", 540 readl(host->dev->addr + SOCK_MS_STATUS)); 541 printk(KERN_ERR 542 "%s : card failed to respond for a long period of time " 543 "(%x, %x)\n", 544 host->dev->dev.bus_id, host->req ? host->req->tpc : 0, 545 host->cmd_flags); 546 547 tifm_eject(host->dev); 548 } 549 550 static int tifm_ms_probe(struct tifm_dev *sock) 551 { 552 struct memstick_host *msh; 553 struct tifm_ms *host; 554 int rc = -EIO; 555 556 if (!(TIFM_SOCK_STATE_OCCUPIED 557 & readl(sock->addr + SOCK_PRESENT_STATE))) { 558 printk(KERN_WARNING "%s : card gone, unexpectedly\n", 559 sock->dev.bus_id); 560 return rc; 561 } 562 563 msh = memstick_alloc_host(sizeof(struct tifm_ms), &sock->dev); 564 if (!msh) 565 return -ENOMEM; 566 567 host = memstick_priv(msh); 568 tifm_set_drvdata(sock, msh); 569 host->dev = sock; 570 host->timeout_jiffies = msecs_to_jiffies(1000); 571 572 setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); 573 574 msh->request = tifm_ms_request; 575 msh->set_param = tifm_ms_set_param; 576 sock->card_event = tifm_ms_card_event; 577 sock->data_event = tifm_ms_data_event; 578 if (tifm_has_ms_pif(sock)) 579 msh->caps |= MEMSTICK_CAP_PAR4; 580 581 rc = memstick_add_host(msh); 582 if (!rc) 583 return 0; 584 585 memstick_free_host(msh); 586 return rc; 587 } 588 589 static void tifm_ms_remove(struct tifm_dev *sock) 590 { 591 struct memstick_host *msh = tifm_get_drvdata(sock); 592 struct tifm_ms *host = memstick_priv(msh); 593 int rc = 0; 594 unsigned long flags; 595 596 spin_lock_irqsave(&sock->lock, flags); 597 host->eject = 1; 598 if (host->req) { 599 del_timer(&host->timer); 600 writel(TIFM_FIFO_INT_SETALL, 601 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); 602 writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); 603 if (host->use_dma) 604 tifm_unmap_sg(sock, &host->req->sg, 1, 605 host->req->data_dir == READ 606 ? PCI_DMA_TODEVICE 607 : PCI_DMA_FROMDEVICE); 608 host->req->error = -ETIME; 609 610 do { 611 rc = memstick_next_req(msh, &host->req); 612 if (!rc) 613 host->req->error = -ETIME; 614 } while (!rc); 615 } 616 spin_unlock_irqrestore(&sock->lock, flags); 617 618 memstick_remove_host(msh); 619 memstick_free_host(msh); 620 } 621 622 #ifdef CONFIG_PM 623 624 static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state) 625 { 626 struct memstick_host *msh = tifm_get_drvdata(sock); 627 628 memstick_suspend_host(msh); 629 return 0; 630 } 631 632 static int tifm_ms_resume(struct tifm_dev *sock) 633 { 634 struct memstick_host *msh = tifm_get_drvdata(sock); 635 636 memstick_resume_host(msh); 637 return 0; 638 } 639 640 #else 641 642 #define tifm_ms_suspend NULL 643 #define tifm_ms_resume NULL 644 645 #endif /* CONFIG_PM */ 646 647 static struct tifm_device_id tifm_ms_id_tbl[] = { 648 { TIFM_TYPE_MS }, { 0 } 649 }; 650 651 static struct tifm_driver tifm_ms_driver = { 652 .driver = { 653 .name = DRIVER_NAME, 654 .owner = THIS_MODULE 655 }, 656 .id_table = tifm_ms_id_tbl, 657 .probe = tifm_ms_probe, 658 .remove = tifm_ms_remove, 659 .suspend = tifm_ms_suspend, 660 .resume = tifm_ms_resume 661 }; 662 663 static int __init tifm_ms_init(void) 664 { 665 return tifm_register_driver(&tifm_ms_driver); 666 } 667 668 static void __exit tifm_ms_exit(void) 669 { 670 tifm_unregister_driver(&tifm_ms_driver); 671 } 672 673 MODULE_AUTHOR("Alex Dubov"); 674 MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver"); 675 MODULE_LICENSE("GPL"); 676 MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl); 677 678 module_init(tifm_ms_init); 679 module_exit(tifm_ms_exit); 680