diff options
author | Marcin Bukat <marcin.bukat@gmail.com> | 2011-09-06 12:38:41 +0000 |
---|---|---|
committer | Marcin Bukat <marcin.bukat@gmail.com> | 2011-09-06 12:38:41 +0000 |
commit | 7d33d832189f6a48d82fc6d19b18459aa49a6a85 (patch) | |
tree | a0879bc3dfa5816b3d4210196978e1c73375f43f | |
parent | 52c72fa185e656cc1e54545052d5bbddb194fbc6 (diff) | |
download | rockbox-7d33d832189f6a48d82fc6d19b18459aa49a6a85.tar.gz rockbox-7d33d832189f6a48d82fc6d19b18459aa49a6a85.zip |
rk27xx - tweak a bit sd driver and add some debuging code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30447 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/target/arm/rk27xx/sd-rk27xx.c | 141 |
1 files changed, 92 insertions, 49 deletions
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c index 57c315adb0..1742852c16 100644 --- a/firmware/target/arm/rk27xx/sd-rk27xx.c +++ b/firmware/target/arm/rk27xx/sd-rk27xx.c | |||
@@ -49,6 +49,11 @@ | |||
49 | 49 | ||
50 | #define RES_NO (-1) | 50 | #define RES_NO (-1) |
51 | 51 | ||
52 | #define RK27XX_SD_DEBUG | ||
53 | /* debug stuff */ | ||
54 | unsigned long sd_debug_time_rd = 0; | ||
55 | unsigned long sd_debug_time_wr = 0; | ||
56 | |||
52 | static tCardInfo card_info; | 57 | static tCardInfo card_info; |
53 | 58 | ||
54 | /* for compatibility */ | 59 | /* for compatibility */ |
@@ -275,8 +280,6 @@ static int sd_init_card(void) | |||
275 | 280 | ||
276 | /* End of Card Identification Mode ************************************/ | 281 | /* End of Card Identification Mode ************************************/ |
277 | 282 | ||
278 | /* Card back to full speed 25MHz*/ | ||
279 | SD_CTRL = (SD_CTRL & ~0x7FF) | 1; /* FIXME check this divider - OF uses 0 here*/ | ||
280 | 283 | ||
281 | /* CMD9 send CSD */ | 284 | /* CMD9 send CSD */ |
282 | if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd)) | 285 | if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd)) |
@@ -290,6 +293,13 @@ static int sd_init_card(void) | |||
290 | if (!sd_wait_card_busy()) | 293 | if (!sd_wait_card_busy()) |
291 | return -21; | 294 | return -21; |
292 | 295 | ||
296 | /* CMD6 */ | ||
297 | if(!send_cmd(SD_SWITCH_FUNC, 0x80fffff1, RES_R1, &response)) | ||
298 | return -8; | ||
299 | sleep(HZ/10); | ||
300 | |||
301 | /* Card back to full speed 25MHz*/ | ||
302 | SD_CTRL = (SD_CTRL & ~0x7FF); | ||
293 | card_info.initialized = 1; | 303 | card_info.initialized = 1; |
294 | 304 | ||
295 | return 0; | 305 | return 0; |
@@ -399,6 +409,23 @@ static void init_controller(void) | |||
399 | MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET | | 409 | MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET | |
400 | MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD; | 410 | MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD; |
401 | 411 | ||
412 | /* setup A2A DMA CH0 for SD reads */ | ||
413 | A2A_ISRC0 = (unsigned long)(&MMU_DATA); | ||
414 | A2A_ICNT0 = 512; | ||
415 | A2A_LCNT0 = 1; | ||
416 | |||
417 | /* setup A2A DMA CH1 for SD writes */ | ||
418 | A2A_IDST1 = (unsigned long)(&MMU_DATA); | ||
419 | A2A_ICNT1 = 512; | ||
420 | A2A_LCNT1 = 1; | ||
421 | |||
422 | /* src and dst for CH0 and CH1 is AHB0 */ | ||
423 | A2A_DOMAIN = 0; | ||
424 | |||
425 | #ifdef RK27XX_SD_DEBUG | ||
426 | /* setup Timer1 for profiling purposes */ | ||
427 | TMR1CON = (1<<8)|(1<<3); | ||
428 | #endif | ||
402 | } | 429 | } |
403 | 430 | ||
404 | int sd_init(void) | 431 | int sd_init(void) |
@@ -424,6 +451,40 @@ int sd_init(void) | |||
424 | return 0; | 451 | return 0; |
425 | } | 452 | } |
426 | 453 | ||
454 | static inline void read_sd_data(unsigned char **dst) | ||
455 | { | ||
456 | commit_discard_dcache_range((const void *)*dst, 512); | ||
457 | |||
458 | A2A_IDST0 = (unsigned long)*dst; | ||
459 | A2A_CON0 = (3<<9) | /* burst 16 */ | ||
460 | (1<<6) | /* fixed src */ | ||
461 | (1<<3) | /* DMA start */ | ||
462 | (2<<1) | /* word transfer size */ | ||
463 | (1<<0); /* software mode */ | ||
464 | |||
465 | /* wait for DMA engine to finish transfer */ | ||
466 | while (A2A_DMA_STS & 1); | ||
467 | |||
468 | *dst += 512; | ||
469 | } | ||
470 | |||
471 | static inline void write_sd_data(unsigned char **src) | ||
472 | { | ||
473 | commit_discard_dcache_range((const void *)*src, 512); | ||
474 | |||
475 | A2A_ISRC1 = (unsigned long)*src; | ||
476 | A2A_CON1 = (3<<9) | /* burst 16 */ | ||
477 | (1<<5) | /* fixed dst */ | ||
478 | (1<<3) | /* DMA start */ | ||
479 | (2<<1) | /* word transfer size */ | ||
480 | (1<<0); /* software mode */ | ||
481 | |||
482 | /* wait for DMA engine to finish transfer */ | ||
483 | while (A2A_DMA_STS & 2); | ||
484 | |||
485 | *src += 512; | ||
486 | } | ||
487 | |||
427 | int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | 488 | int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, |
428 | void* buf) | 489 | void* buf) |
429 | { | 490 | { |
@@ -444,12 +505,6 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
444 | if(!(card_info.ocr & (1<<30))) | 505 | if(!(card_info.ocr & (1<<30))) |
445 | start <<= 9; /* not SDHC */ | 506 | start <<= 9; /* not SDHC */ |
446 | 507 | ||
447 | /* setup A2A DMA CH0 */ | ||
448 | A2A_ISRC0 = (unsigned long)(&MMU_DATA); | ||
449 | A2A_ICNT0 = 512; | ||
450 | A2A_LCNT0 = 1; | ||
451 | A2A_DOMAIN = 0; | ||
452 | |||
453 | while (retry_cnt++ < 20) | 508 | while (retry_cnt++ < 20) |
454 | { | 509 | { |
455 | cnt = count; | 510 | cnt = count; |
@@ -484,9 +539,17 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
484 | 539 | ||
485 | while (cnt > 0) | 540 | while (cnt > 0) |
486 | { | 541 | { |
542 | #ifdef RK27XX_SD_DEBUG | ||
543 | /* debug stuff */ | ||
544 | TMR1LR = 0xffffffff; | ||
545 | #endif | ||
487 | /* wait for transfer completion */ | 546 | /* wait for transfer completion */ |
488 | semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); | 547 | semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); |
489 | 548 | ||
549 | #ifdef RK27XX_DEBUG | ||
550 | /* debug stuff */ | ||
551 | sd_debug_time_rd = 0xffffffff - TMR1CVR; | ||
552 | #endif | ||
490 | if (retry) | 553 | if (retry) |
491 | { | 554 | { |
492 | /* data transfer error */ | 555 | /* data transfer error */ |
@@ -497,17 +560,6 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
497 | /* exchange buffers */ | 560 | /* exchange buffers */ |
498 | mmu_switch_buff(); | 561 | mmu_switch_buff(); |
499 | 562 | ||
500 | A2A_IDST0 = (unsigned long)dst; | ||
501 | A2A_CON0 = (3<<9) | /* burst 16 */ | ||
502 | (1<<6) | /* fixed src */ | ||
503 | (1<<3) | /* DMA start */ | ||
504 | (2<<1) | /* word transfer size */ | ||
505 | (1<<0); /* software mode */ | ||
506 | |||
507 | /* wait for DMA engine to finish transfer */ | ||
508 | while (A2A_DMA_STS & 1); | ||
509 | |||
510 | dst += 512; | ||
511 | cnt--; | 563 | cnt--; |
512 | 564 | ||
513 | if (cnt == 0) | 565 | if (cnt == 0) |
@@ -515,6 +567,8 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
515 | if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) | 567 | if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) |
516 | ret = -4; | 568 | ret = -4; |
517 | 569 | ||
570 | read_sd_data(&dst); | ||
571 | |||
518 | break; | 572 | break; |
519 | } | 573 | } |
520 | else if (cnt == 1) | 574 | else if (cnt == 1) |
@@ -523,6 +577,9 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
523 | SD_DATAT = DATA_XFER_START | DATA_XFER_READ | | 577 | SD_DATAT = DATA_XFER_START | DATA_XFER_READ | |
524 | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | | 578 | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | |
525 | DATA_XFER_SINGLE; | 579 | DATA_XFER_SINGLE; |
580 | |||
581 | read_sd_data(&dst); | ||
582 | |||
526 | } | 583 | } |
527 | else | 584 | else |
528 | { | 585 | { |
@@ -530,6 +587,8 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
530 | SD_DATAT = DATA_XFER_START | DATA_XFER_READ | | 587 | SD_DATAT = DATA_XFER_START | DATA_XFER_READ | |
531 | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | | 588 | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | |
532 | DATA_XFER_MULTI; | 589 | DATA_XFER_MULTI; |
590 | |||
591 | read_sd_data(&dst); | ||
533 | } | 592 | } |
534 | 593 | ||
535 | last_disk_activity = current_tick; | 594 | last_disk_activity = current_tick; |
@@ -561,6 +620,12 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
561 | (void) buf; | 620 | (void) buf; |
562 | return -1; | 621 | return -1; |
563 | #else | 622 | #else |
623 | |||
624 | #ifdef RK27XX_SD_DEBUG | ||
625 | /* debug stuff */ | ||
626 | TMR1LR = 0xffffffff; | ||
627 | #endif | ||
628 | |||
564 | unsigned long response; | 629 | unsigned long response; |
565 | unsigned int retry_cnt = 0; | 630 | unsigned int retry_cnt = 0; |
566 | int cnt, ret = 0; | 631 | int cnt, ret = 0; |
@@ -576,12 +641,6 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
576 | if(!(card_info.ocr & (1<<30))) | 641 | if(!(card_info.ocr & (1<<30))) |
577 | start <<= 9; /* not SDHC */ | 642 | start <<= 9; /* not SDHC */ |
578 | 643 | ||
579 | /* setup A2A DMA CH0 */ | ||
580 | A2A_IDST0 = (unsigned long)(&MMU_DATA); | ||
581 | A2A_ICNT0 = 512; | ||
582 | A2A_LCNT0 = 1; | ||
583 | A2A_DOMAIN = 0; | ||
584 | |||
585 | while (retry_cnt++ < 20) | 644 | while (retry_cnt++ < 20) |
586 | { | 645 | { |
587 | cnt = count; | 646 | cnt = count; |
@@ -591,17 +650,7 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
591 | retry = false; /* reset retry flag */ | 650 | retry = false; /* reset retry flag */ |
592 | mmu_buff_reset(); /* reset recive buff state */ | 651 | mmu_buff_reset(); /* reset recive buff state */ |
593 | 652 | ||
594 | /* transfer data from receive buffer to the dest | 653 | write_sd_data(&src); /* put data into transfer buffer */ |
595 | * for (i=0; i<(512/4); i++) | ||
596 | * MMU_DATA = *src++; | ||
597 | * | ||
598 | * Below is DMA version in software mode. | ||
599 | */ | ||
600 | |||
601 | A2A_ISRC0 = (unsigned long)src; | ||
602 | A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0); | ||
603 | |||
604 | while (A2A_DMA_STS & 1); | ||
605 | 654 | ||
606 | if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) | 655 | if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) |
607 | { | 656 | { |
@@ -629,20 +678,9 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
629 | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | | 678 | DATA_BUS_1LINE | DATA_XFER_DMA_DIS | |
630 | DATA_XFER_MULTI; | 679 | DATA_XFER_MULTI; |
631 | 680 | ||
632 | /* transfer data from receive buffer to the dest | 681 | /* put more data */ |
633 | * for (i=0; i<(512/4); i++) | 682 | write_sd_data(&src); |
634 | * MMU_DATA = *src++; | ||
635 | * | ||
636 | * Below is DMA version in software mode. | ||
637 | */ | ||
638 | src += 512; | ||
639 | |||
640 | A2A_ISRC0 = (unsigned long)src; | ||
641 | A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0); | ||
642 | |||
643 | while (A2A_DMA_STS & 1); | ||
644 | } | 683 | } |
645 | |||
646 | /* wait for transfer completion */ | 684 | /* wait for transfer completion */ |
647 | semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); | 685 | semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); |
648 | 686 | ||
@@ -670,6 +708,11 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count, | |||
670 | sd_enable(false); | 708 | sd_enable(false); |
671 | mutex_unlock(&sd_mtx); | 709 | mutex_unlock(&sd_mtx); |
672 | 710 | ||
711 | #ifdef RK27XX_SD_DEBUG | ||
712 | /* debug stuff */ | ||
713 | sd_debug_time_wr = 0xffffffff - TMR1CVR; | ||
714 | #endif | ||
715 | |||
673 | return ret; | 716 | return ret; |
674 | 717 | ||
675 | #endif /* defined(BOOTLOADER) */ | 718 | #endif /* defined(BOOTLOADER) */ |