diff options
Diffstat (limited to 'firmware/target/arm/s5l8702')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c index 36d119aff3..72c7cc78c7 100644 --- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | |||
@@ -30,11 +30,26 @@ | |||
30 | #include "s5l8702.h" | 30 | #include "s5l8702.h" |
31 | #include "led.h" | 31 | #include "led.h" |
32 | 32 | ||
33 | |||
34 | #ifndef ATA_RETRIES | 33 | #ifndef ATA_RETRIES |
35 | #define ATA_RETRIES 3 | 34 | #define ATA_RETRIES 3 |
36 | #endif | 35 | #endif |
37 | 36 | ||
37 | #define CMD_READ_SECTORS 0x20 | ||
38 | #define CMD_READ_DMA_EXT 0x25 | ||
39 | #define CMD_READ_MULTIPLE_EXT 0x29 | ||
40 | #define CMD_WRITE_SECTORS 0x30 | ||
41 | #define CMD_WRITE_DMA_EXT 0x35 | ||
42 | #define CMD_WRITE_MULTIPLE_EXT 0x39 | ||
43 | #ifdef HAVE_ATA_SMART | ||
44 | #define CMD_SMART 0xB0 | ||
45 | #endif | ||
46 | #define CMD_READ_MULTIPLE 0xC4 | ||
47 | #define CMD_WRITE_MULTIPLE 0xC5 | ||
48 | #define CMD_READ_DMA 0xC8 | ||
49 | #define CMD_WRITE_DMA 0xCA | ||
50 | #define CMD_STANDBY_IMMEDIATE 0xE0 | ||
51 | #define CMD_IDENTIFY 0xEC | ||
52 | #define CMD_SET_FEATURES 0xEF | ||
38 | 53 | ||
39 | #define CEATA_POWERUP_TIMEOUT 20000000 | 54 | #define CEATA_POWERUP_TIMEOUT 20000000 |
40 | #define CEATA_COMMAND_TIMEOUT 1000000 | 55 | #define CEATA_COMMAND_TIMEOUT 1000000 |
@@ -482,7 +497,7 @@ static int ata_identify(uint16_t* buf) | |||
482 | if (ceata) | 497 | if (ceata) |
483 | { | 498 | { |
484 | memset(ceata_taskfile, 0, 16); | 499 | memset(ceata_taskfile, 0, 16); |
485 | ceata_taskfile[0xf] = 0xec; | 500 | ceata_taskfile[0xf] = CMD_IDENTIFY; |
486 | PASS_RC(ceata_wait_idle(), 2, 0); | 501 | PASS_RC(ceata_wait_idle(), 2, 0); |
487 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); | 502 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
488 | PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); | 503 | PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); |
@@ -491,7 +506,7 @@ static int ata_identify(uint16_t* buf) | |||
491 | { | 506 | { |
492 | PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0); | 507 | PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0); |
493 | ata_write_cbr(&ATA_PIO_DVR, 0); | 508 | ata_write_cbr(&ATA_PIO_DVR, 0); |
494 | ata_write_cbr(&ATA_PIO_CSD, 0xec); | 509 | ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); |
495 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); | 510 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); |
496 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); | 511 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); |
497 | } | 512 | } |
@@ -515,7 +530,7 @@ static int ata_set_feature(uint32_t feature, uint32_t param) | |||
515 | memset(ceata_taskfile, 0, 16); | 530 | memset(ceata_taskfile, 0, 16); |
516 | ceata_taskfile[0x1] = feature; | 531 | ceata_taskfile[0x1] = feature; |
517 | ceata_taskfile[0x2] = param; | 532 | ceata_taskfile[0x2] = param; |
518 | ceata_taskfile[0xf] = 0xef; | 533 | ceata_taskfile[0xf] = CMD_SET_FEATURES; |
519 | PASS_RC(ceata_wait_idle(), 2, 0); | 534 | PASS_RC(ceata_wait_idle(), 2, 0); |
520 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); | 535 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
521 | PASS_RC(ceata_wait_idle(), 2, 2); | 536 | PASS_RC(ceata_wait_idle(), 2, 2); |
@@ -526,7 +541,7 @@ static int ata_set_feature(uint32_t feature, uint32_t param) | |||
526 | ata_write_cbr(&ATA_PIO_DVR, 0); | 541 | ata_write_cbr(&ATA_PIO_DVR, 0); |
527 | ata_write_cbr(&ATA_PIO_FED, feature); | 542 | ata_write_cbr(&ATA_PIO_FED, feature); |
528 | ata_write_cbr(&ATA_PIO_SCR, param); | 543 | ata_write_cbr(&ATA_PIO_SCR, param); |
529 | ata_write_cbr(&ATA_PIO_CSD, 0xef); | 544 | ata_write_cbr(&ATA_PIO_CSD, CMD_SET_FEATURES); |
530 | PASS_RC(ata_wait_for_rdy(2000000), 2, 1); | 545 | PASS_RC(ata_wait_for_rdy(2000000), 2, 1); |
531 | } | 546 | } |
532 | return 0; | 547 | return 0; |
@@ -690,7 +705,7 @@ static void ata_power_down(void) | |||
690 | if (ceata) | 705 | if (ceata) |
691 | { | 706 | { |
692 | memset(ceata_taskfile, 0, 16); | 707 | memset(ceata_taskfile, 0, 16); |
693 | ceata_taskfile[0xf] = 0xe0; | 708 | ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE; |
694 | ceata_wait_idle(); | 709 | ceata_wait_idle(); |
695 | ceata_write_multiple_register(0, ceata_taskfile, 16); | 710 | ceata_write_multiple_register(0, ceata_taskfile, 16); |
696 | ceata_wait_idle(); | 711 | ceata_wait_idle(); |
@@ -701,7 +716,7 @@ static void ata_power_down(void) | |||
701 | { | 716 | { |
702 | ata_wait_for_rdy(1000000); | 717 | ata_wait_for_rdy(1000000); |
703 | ata_write_cbr(&ATA_PIO_DVR, 0); | 718 | ata_write_cbr(&ATA_PIO_DVR, 0); |
704 | ata_write_cbr(&ATA_PIO_CSD, 0xe0); | 719 | ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE); |
705 | ata_wait_for_rdy(1000000); | 720 | ata_wait_for_rdy(1000000); |
706 | sleep(HZ / 30); | 721 | sleep(HZ / 30); |
707 | ATA_CONTROL = 0; | 722 | ATA_CONTROL = 0; |
@@ -730,7 +745,7 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
730 | ceata_taskfile[0xb] = sector << 3; | 745 | ceata_taskfile[0xb] = sector << 3; |
731 | ceata_taskfile[0xc] = sector >> 5; | 746 | ceata_taskfile[0xc] = sector >> 5; |
732 | ceata_taskfile[0xd] = sector >> 13; | 747 | ceata_taskfile[0xd] = sector >> 13; |
733 | ceata_taskfile[0xf] = write ? 0x35 : 0x25; | 748 | ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; |
734 | PASS_RC(ceata_wait_idle(), 2, 0); | 749 | PASS_RC(ceata_wait_idle(), 2, 0); |
735 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); | 750 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
736 | PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); | 751 | PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); |
@@ -750,8 +765,10 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
750 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); | 765 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); |
751 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); | 766 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); |
752 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); | 767 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); |
753 | if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39); | 768 | if (write) |
754 | else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29); | 769 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); |
770 | else | ||
771 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA_EXT : CMD_READ_MULTIPLE_EXT); | ||
755 | } | 772 | } |
756 | else | 773 | else |
757 | { | 774 | { |
@@ -760,8 +777,10 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
760 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); | 777 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); |
761 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); | 778 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); |
762 | ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf)); | 779 | ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf)); |
763 | if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30); | 780 | if (write) |
764 | else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4); | 781 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); |
782 | else | ||
783 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE); | ||
765 | } | 784 | } |
766 | if (ata_dma) | 785 | if (ata_dma) |
767 | { | 786 | { |
@@ -1017,7 +1036,7 @@ static int ata_smart(uint16_t* buf) | |||
1017 | ceata_taskfile[0xc] = 0x4f; | 1036 | ceata_taskfile[0xc] = 0x4f; |
1018 | ceata_taskfile[0xd] = 0xc2; | 1037 | ceata_taskfile[0xd] = 0xc2; |
1019 | ceata_taskfile[0xe] = BIT(6); | 1038 | ceata_taskfile[0xe] = BIT(6); |
1020 | ceata_taskfile[0xf] = 0xb0; | 1039 | ceata_taskfile[0xf] = CMD_SMART; |
1021 | PASS_RC(ceata_wait_idle(), 3, 1); | 1040 | PASS_RC(ceata_wait_idle(), 3, 1); |
1022 | if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */ | 1041 | if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */ |
1023 | { | 1042 | { |
@@ -1037,7 +1056,7 @@ static int ata_smart(uint16_t* buf) | |||
1037 | ata_write_cbr(&ATA_PIO_LMR, 0x4f); | 1056 | ata_write_cbr(&ATA_PIO_LMR, 0x4f); |
1038 | ata_write_cbr(&ATA_PIO_LHR, 0xc2); | 1057 | ata_write_cbr(&ATA_PIO_LHR, 0xc2); |
1039 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); | 1058 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); |
1040 | ata_write_cbr(&ATA_PIO_CSD, 0xb0); | 1059 | ata_write_cbr(&ATA_PIO_CSD, CMD_SMART); |
1041 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); | 1060 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); |
1042 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); | 1061 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); |
1043 | } | 1062 | } |