Index: emcore/trunk/target/ipodclassic/storage_ata.c |
— | — | @@ -68,9 +68,10 @@ |
69 | 69 | uint32_t ata_last_offset; |
70 | 70 | uint64_t ata_last_phys; |
71 | 71 | |
| 72 | +static uint16_t ata_read_cbr(uint32_t volatile* reg); |
72 | 73 | int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer) |
73 | 74 | { |
74 | | - if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset(); |
| 75 | + if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_reset(); |
75 | 76 | int rc = ata_rw_sectors_internal(sector, count, buffer, false); |
76 | 77 | if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false); |
77 | 78 | ata_last_phys = sector + count - 1; |
— | — | @@ -89,7 +90,7 @@ |
90 | 91 | #ifdef ATA_HAVE_BBT |
91 | 92 | .bbt_translate = ata_bbt_translate, |
92 | 93 | .bbt_reload = ata_bbt_reload, |
93 | | - .bbt_disable = ata_bbt_disable |
| 94 | + .bbt_disable = ata_bbt_disable, |
94 | 95 | #endif |
95 | 96 | }; |
96 | 97 | |
— | — | @@ -107,7 +108,7 @@ |
108 | 109 | static uint16_t ata_read_cbr(uint32_t volatile* reg) |
109 | 110 | { |
110 | 111 | while (!(ATA_PIO_READY & 2)) yield(); |
111 | | - volatile uint32_t dummy = *reg; |
| 112 | + uint32_t dummy = *reg; |
112 | 113 | while (!(ATA_PIO_READY & 1)) yield(); |
113 | 114 | return ATA_PIO_RDATA; |
114 | 115 | } |
— | — | @@ -492,20 +493,20 @@ |
493 | 494 | | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype |
494 | 495 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, |
495 | 496 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), |
496 | | - NULL, CEATA_COMMAND_TIMEOUT), 4, 0); |
| 497 | + NULL, CEATA_COMMAND_TIMEOUT), 3, 0); |
497 | 498 | if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; |
498 | 499 | if (wakeup_wait(&mmc_wakeup, timeout) == THREAD_TIMEOUT) |
499 | 500 | { |
500 | | - PASS_RC(ceata_cancel_command(), 4, 1); |
| 501 | + PASS_RC(ceata_cancel_command(), 3, 1); |
501 | 502 | RET_ERR(2); |
502 | 503 | } |
503 | | - PASS_RC(mmc_dsta_check_data_success(), 4, 3); |
| 504 | + PASS_RC(mmc_dsta_check_data_success(), 3, 3); |
504 | 505 | if (wakeup_wait(&mmc_comp_wakeup, timeout) == THREAD_TIMEOUT) |
505 | 506 | { |
506 | | - PASS_RC(ceata_cancel_command(), 4, 4); |
507 | | - RET_ERR(4); |
| 507 | + PASS_RC(ceata_cancel_command(), 3, 4); |
| 508 | + RET_ERR(5); |
508 | 509 | } |
509 | | - PASS_RC(ceata_check_error(), 4, 5); |
| 510 | + PASS_RC(ceata_check_error(), 3, 6); |
510 | 511 | return 0; |
511 | 512 | } |
512 | 513 | |
— | — | @@ -543,12 +544,25 @@ |
544 | 545 | |
545 | 546 | int ata_set_feature(uint32_t feature, uint32_t param) |
546 | 547 | { |
547 | | - PASS_RC(ata_wait_for_rdy(500000), 1, 0); |
548 | | - ata_write_cbr(&ATA_PIO_DVR, 0); |
549 | | - ata_write_cbr(&ATA_PIO_FED, 3); |
550 | | - ata_write_cbr(&ATA_PIO_SCR, param); |
551 | | - ata_write_cbr(&ATA_PIO_CSD, feature); |
552 | | - PASS_RC(ata_wait_for_rdy(500000), 1, 1); |
| 548 | + if (ceata) |
| 549 | + { |
| 550 | + memset(ceata_taskfile, 0, 16); |
| 551 | + ceata_taskfile[0x1] = feature; |
| 552 | + ceata_taskfile[0x2] = param; |
| 553 | + ceata_taskfile[0xf] = 0xef; |
| 554 | + PASS_RC(ceata_wait_idle(), 2, 0); |
| 555 | + PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
| 556 | + PASS_RC(ceata_wait_idle(), 2, 2); |
| 557 | + } |
| 558 | + else |
| 559 | + { |
| 560 | + PASS_RC(ata_wait_for_rdy(2000000), 2, 0); |
| 561 | + ata_write_cbr(&ATA_PIO_DVR, 0); |
| 562 | + ata_write_cbr(&ATA_PIO_FED, feature); |
| 563 | + ata_write_cbr(&ATA_PIO_SCR, param); |
| 564 | + ata_write_cbr(&ATA_PIO_CSD, 0xef); |
| 565 | + PASS_RC(ata_wait_for_rdy(2000000), 2, 1); |
| 566 | + } |
553 | 567 | return 0; |
554 | 568 | } |
555 | 569 | |
— | — | @@ -555,10 +569,16 @@ |
556 | 570 | int ata_power_up() |
557 | 571 | { |
558 | 572 | ata_set_active(); |
559 | | - if (ata_powered) return 0; |
560 | 573 | i2c_sendbyte(0, 0xe6, 0x1b, 1); |
561 | 574 | if (ceata) |
562 | 575 | { |
| 576 | + ata_lba48 = true; |
| 577 | + ata_dma = true; |
| 578 | + PCON(8) = 0x33333333; |
| 579 | + PCON(9) = 0x00000033; |
| 580 | + PCON(11) |= 0xf; |
| 581 | + *((uint32_t volatile*)0x38a00000) = 0; |
| 582 | + *((uint32_t volatile*)0x38700000) = 0; |
563 | 583 | clockgate_enable(9, true); |
564 | 584 | SDCI_RESET = 0xa5; |
565 | 585 | sleep(1000); |
— | — | @@ -569,18 +589,21 @@ |
570 | 590 | SDCI_CDIV = SDCI_CDIV_CLKDIV(260); |
571 | 591 | *((uint32_t volatile*)0x3cf00200) = 0xb000f; |
572 | 592 | SDCI_IRQ_MASK = SDCI_IRQ_MASK_MASK_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT; |
573 | | - PASS_RC(mmc_init(), 2, 0); |
| 593 | + PASS_RC(mmc_init(), 3, 0); |
574 | 594 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); |
575 | 595 | sleep(10000); |
576 | | - PASS_RC(ceata_init(8), 2, 1); |
577 | | - PASS_RC(ata_identify(ata_identify_data), 2, 2); |
| 596 | + PASS_RC(ceata_init(8), 3, 1); |
| 597 | + PASS_RC(ata_identify(ata_identify_data), 3, 2); |
578 | 598 | } |
579 | 599 | else |
580 | 600 | { |
581 | | - sleep(1000); |
| 601 | + PCON(7) = 0x44444444; |
| 602 | + PCON(8) = 0x44444444; |
| 603 | + PCON(9) = 0x44444444; |
| 604 | + PCON(10) = (PCON(10) & ~0xffff) | 0x4444; |
582 | 605 | clockgate_enable(5, true); |
583 | 606 | ATA_CFG = BIT(0); |
584 | | - sleep(1000); |
| 607 | + sleep(10000); |
585 | 608 | ATA_CFG = 0; |
586 | 609 | sleep(6000); |
587 | 610 | ATA_SWRST = BIT(0); |
— | — | @@ -593,7 +616,7 @@ |
594 | 617 | ATA_PIO_LHR = 0; |
595 | 618 | ATA_CFG = BIT(6); |
596 | 619 | while (!(ATA_PIO_READY & BIT(1))) sleep(100); |
597 | | - PASS_RC(ata_identify(ata_identify_data), 2, 0); |
| 620 | + PASS_RC(ata_identify(ata_identify_data), 3, 3); |
598 | 621 | uint32_t piotime = 0x11f3; |
599 | 622 | uint32_t mdmatime = 0x1c175; |
600 | 623 | uint32_t udmatime = 0x5071152; |
— | — | @@ -649,13 +672,14 @@ |
650 | 673 | } |
651 | 674 | } |
652 | 675 | ata_dma = param ? true : false; |
653 | | - PASS_RC(ata_set_feature(0xef, param), 2, 1); |
654 | | - if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2); |
655 | | - if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3); |
| 676 | + PASS_RC(ata_set_feature(0x03, param), 3, 4); |
656 | 677 | ATA_PIO_TIME = piotime; |
657 | 678 | ATA_MDMA_TIME = mdmatime; |
658 | 679 | ATA_UDMA_TIME = udmatime; |
659 | 680 | } |
| 681 | + if (ata_identify_data[82] & BIT(5)) |
| 682 | + PASS_RC(ata_set_feature(ata_bbt ? 0x82 : 0x02, 0), 3, 5); |
| 683 | + if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0xaa, 0), 3, 6); |
660 | 684 | if (ata_lba48) |
661 | 685 | ata_total_sectors = ata_identify_data[100] |
662 | 686 | | (((uint64_t)ata_identify_data[101]) << 16) |
— | — | @@ -678,7 +702,8 @@ |
679 | 703 | ceata_taskfile[0xf] = 0xe0; |
680 | 704 | ceata_wait_idle(); |
681 | 705 | ceata_write_multiple_register(0, ceata_taskfile, 16); |
682 | | - sleep(1000000); |
| 706 | + ceata_wait_idle(); |
| 707 | + sleep(100000); |
683 | 708 | clockgate_enable(9, false); |
684 | 709 | } |
685 | 710 | else |
— | — | @@ -692,6 +717,11 @@ |
693 | 718 | while (!(ATA_CONTROL & BIT(1))) yield(); |
694 | 719 | clockgate_enable(5, false); |
695 | 720 | } |
| 721 | + PCON(7) = 0; |
| 722 | + PCON(8) = 0; |
| 723 | + PCON(9) = 0; |
| 724 | + PCON(10) &= ~0xffff; |
| 725 | + PCON(11) &= ~0xf; |
696 | 726 | i2c_sendbyte(0, 0xe6, 0x1b, 0); |
697 | 727 | } |
698 | 728 | |
— | — | @@ -863,7 +893,7 @@ |
864 | 894 | uint32_t cnt; |
865 | 895 | PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0); |
866 | 896 | uint32_t offset = phys - sector; |
867 | | - if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset(); |
| 897 | + if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_reset(); |
868 | 898 | ata_last_offset = offset; |
869 | 899 | ata_last_phys = phys + cnt; |
870 | 900 | PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0); |
— | — | @@ -889,7 +919,7 @@ |
890 | 920 | uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count); |
891 | 921 | int rc = -1; |
892 | 922 | rc = ata_rw_chunk(sector, cnt, buffer, write); |
893 | | - if (rc && ata_error_srst) ata_soft_reset(); |
| 923 | + if (rc && ata_error_srst) ata_reset(); |
894 | 924 | if (rc && ata_retries) |
895 | 925 | { |
896 | 926 | void* buf = buffer; |
— | — | @@ -901,7 +931,7 @@ |
902 | 932 | while (tries-- && rc) |
903 | 933 | { |
904 | 934 | rc = ata_rw_chunk(sect, 1, buf, write); |
905 | | - if (rc && ata_error_srst) ata_soft_reset(); |
| 935 | + if (rc && ata_error_srst) ata_reset(); |
906 | 936 | } |
907 | 937 | if (rc) break; |
908 | 938 | buf += SECTOR_SIZE; |
— | — | @@ -941,17 +971,46 @@ |
942 | 972 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); |
943 | 973 | sleep(10); |
944 | 974 | ata_write_cbr(&ATA_PIO_DAD, 0); |
945 | | - rc = ata_wait_for_rdy(20000000); |
| 975 | + rc = ata_wait_for_rdy(3000000); |
946 | 976 | } |
| 977 | + ata_set_active(); |
| 978 | + mutex_unlock(&ata_mutex); |
| 979 | + PASS_RC(rc, 1, 1); |
| 980 | + return 0; |
| 981 | +} |
| 982 | + |
| 983 | +int ata_hard_reset() |
| 984 | +{ |
| 985 | + mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| 986 | + PASS_RC(ata_power_up(), 0, 0); |
| 987 | + ata_set_active(); |
| 988 | + mutex_unlock(&ata_mutex); |
| 989 | + return 0; |
| 990 | +} |
| 991 | + |
| 992 | +int ata_reset() |
| 993 | +{ |
| 994 | + int rc; |
| 995 | + mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| 996 | + if (!ata_powered) PASS_RC(ata_power_up(), 2, 0); |
| 997 | + ata_set_active(); |
| 998 | + rc = ata_soft_reset(); |
947 | 999 | if (IS_ERR(rc)) |
948 | 1000 | { |
949 | | - ata_power_down(); |
950 | | - sleep(3000000); |
951 | | - ata_power_up(); |
| 1001 | + rc = ata_hard_reset(); |
| 1002 | + if (IS_ERR(rc)) |
| 1003 | + { |
| 1004 | + rc = ERR_RC((rc << 2) | 1); |
| 1005 | + ata_power_down(); |
| 1006 | + sleep(3000000); |
| 1007 | + int rc2 = ata_power_up(); |
| 1008 | + if (IS_ERR(rc2)) rc = ERR_RC((rc << 2) | 2); |
| 1009 | + } |
| 1010 | + else rc = 1; |
952 | 1011 | } |
953 | 1012 | ata_set_active(); |
954 | 1013 | mutex_unlock(&ata_mutex); |
955 | | - PASS_RC(rc, 1, 1); |
| 1014 | + return rc; |
956 | 1015 | } |
957 | 1016 | |
958 | 1017 | int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount, |
— | — | @@ -1032,7 +1091,7 @@ |
1033 | 1092 | { |
1034 | 1093 | mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
1035 | 1094 | ata_bbt_disable(); |
1036 | | - PASS_RC(ata_power_up(), 0, 0); |
| 1095 | + PASS_RC(ata_power_up(), 1, 0); |
1037 | 1096 | uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000); |
1038 | 1097 | if (buf) |
1039 | 1098 | { |
— | — | @@ -1040,6 +1099,7 @@ |
1041 | 1100 | ata_virtual_sectors = ata_total_sectors; |
1042 | 1101 | else if (!memcmp(buf, "emBIbbth", 8)) |
1043 | 1102 | { |
| 1103 | + if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 1, 1); |
1044 | 1104 | ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc]; |
1045 | 1105 | uint32_t count = buf[0x1ff]; |
1046 | 1106 | ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count); |
— | — | @@ -1074,6 +1134,7 @@ |
1075 | 1135 | } |
1076 | 1136 | else ata_virtual_sectors = ata_total_sectors; |
1077 | 1137 | mutex_unlock(&ata_mutex); |
| 1138 | + return 0; |
1078 | 1139 | } |
1079 | 1140 | #endif |
1080 | 1141 | |
— | — | @@ -1084,23 +1145,6 @@ |
1085 | 1146 | wakeup_init(&mmc_wakeup); |
1086 | 1147 | wakeup_init(&mmc_comp_wakeup); |
1087 | 1148 | ceata = PDAT(11) & BIT(1); |
1088 | | - if (ceata) |
1089 | | - { |
1090 | | - ata_lba48 = true; |
1091 | | - ata_dma = true; |
1092 | | - PCON(8) = 0x33333333; |
1093 | | - PCON(9) = (PCON(9) & ~0xff) | 0x33; |
1094 | | - PCON(11) |= 0xf; |
1095 | | - *((uint32_t volatile*)0x38a00000) = 0; |
1096 | | - *((uint32_t volatile*)0x38700000) = 0; |
1097 | | - } |
1098 | | - else |
1099 | | - { |
1100 | | - PCON(7) = 0x44444444; |
1101 | | - PCON(8) = 0x44444444; |
1102 | | - PCON(9) = 0x44444444; |
1103 | | - PCON(10) = (PCON(10) & ~0xffff) | 0x4444; |
1104 | | - } |
1105 | 1149 | ata_powered = false; |
1106 | 1150 | ata_total_sectors = 0; |
1107 | 1151 | #ifdef ATA_HAVE_BBT |
Index: emcore/trunk/storage.c |
— | — | @@ -334,7 +334,7 @@ |
335 | 335 | int rc=0; |
336 | 336 | |
337 | 337 | #if (CONFIG_STORAGE & STORAGE_ATA) |
338 | | - if ((rc=ata_soft_reset())) return rc; |
| 338 | + if ((rc=ata_reset())) return rc; |
339 | 339 | #endif |
340 | 340 | |
341 | 341 | #if (CONFIG_STORAGE & STORAGE_MMC) |