diff options
Diffstat (limited to 'firmware/target')
58 files changed, 1252 insertions, 811 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c index 70e0778d2b..df39cba495 100644 --- a/firmware/target/arm/as3525/sd-as3525.c +++ b/firmware/target/arm/as3525/sd-as3525.c | |||
@@ -446,7 +446,7 @@ static int sd_init_card(const int drive) | |||
446 | sd_parse_csd(&card_info[drive]); | 446 | sd_parse_csd(&card_info[drive]); |
447 | 447 | ||
448 | #if defined(HAVE_MULTIDRIVE) | 448 | #if defined(HAVE_MULTIDRIVE) |
449 | hs_card = (card_info[drive].speed == 50000000); | 449 | hs_card = (card_info[drive].speed >= 50000000); |
450 | #endif | 450 | #endif |
451 | 451 | ||
452 | /* Boost MCICLK to operating speed */ | 452 | /* Boost MCICLK to operating speed */ |
@@ -455,7 +455,7 @@ static int sd_init_card(const int drive) | |||
455 | #if defined(HAVE_MULTIDRIVE) | 455 | #if defined(HAVE_MULTIDRIVE) |
456 | else | 456 | else |
457 | /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ | 457 | /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ |
458 | MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) | | 458 | MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) | |
459 | MCI_CLOCK_POWERSAVE; /* SD supports powersave */ | 459 | MCI_CLOCK_POWERSAVE; /* SD supports powersave */ |
460 | #endif | 460 | #endif |
461 | 461 | ||
@@ -680,7 +680,7 @@ static int sd_select_bank(signed char bank) | |||
680 | return 0; | 680 | return 0; |
681 | } | 681 | } |
682 | 682 | ||
683 | static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | 683 | static int sd_transfer_sectors(IF_MD(int drive,) sector_t start, |
684 | int count, void* buf, const bool write) | 684 | int count, void* buf, const bool write) |
685 | { | 685 | { |
686 | #ifndef HAVE_MULTIDRIVE | 686 | #ifndef HAVE_MULTIDRIVE |
@@ -735,7 +735,8 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | |||
735 | unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ | 735 | unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ |
736 | void *dma_buf; | 736 | void *dma_buf; |
737 | 737 | ||
738 | unsigned long bank_start = start; | 738 | sector_t bank_start = start; |
739 | // XXX 64-bit sectors? | ||
739 | 740 | ||
740 | /* Only switch banks for internal storage */ | 741 | /* Only switch banks for internal storage */ |
741 | if(drive == INTERNAL_AS3525) | 742 | if(drive == INTERNAL_AS3525) |
@@ -869,7 +870,7 @@ sd_transfer_error_nodma: | |||
869 | return ret; | 870 | return ret; |
870 | } | 871 | } |
871 | 872 | ||
872 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | 873 | int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, |
873 | void* buf) | 874 | void* buf) |
874 | { | 875 | { |
875 | int ret; | 876 | int ret; |
@@ -881,11 +882,11 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | |||
881 | return ret; | 882 | return ret; |
882 | } | 883 | } |
883 | 884 | ||
884 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 885 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, |
885 | const void* buf) | 886 | const void* buf) |
886 | { | 887 | { |
887 | #ifdef VERIFY_WRITE | 888 | #ifdef VERIFY_WRITE |
888 | unsigned long saved_start = start; | 889 | sector_t saved_start = start; |
889 | int saved_count = count; | 890 | int saved_count = count; |
890 | void *saved_buf = (void*)buf; | 891 | void *saved_buf = (void*)buf; |
891 | #endif | 892 | #endif |
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index b512cc2ea4..f9ef7d9c97 100644 --- a/firmware/target/arm/as3525/sd-as3525v2.c +++ b/firmware/target/arm/as3525/sd-as3525v2.c | |||
@@ -677,7 +677,7 @@ int sd_init(void) | |||
677 | return 0; | 677 | return 0; |
678 | } | 678 | } |
679 | 679 | ||
680 | static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | 680 | static int sd_transfer_sectors(IF_MD(int drive,) sector_t start, |
681 | int count, void* buf, bool write) | 681 | int count, void* buf, bool write) |
682 | { | 682 | { |
683 | unsigned long response; | 683 | unsigned long response; |
@@ -776,7 +776,7 @@ retry_with_reinit: | |||
776 | 776 | ||
777 | MCI_BYTCNT = transfer * SD_BLOCK_SIZE; | 777 | MCI_BYTCNT = transfer * SD_BLOCK_SIZE; |
778 | 778 | ||
779 | int arg = start; | 779 | sector_t arg = start; // XXX 64-bit |
780 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | 780 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ |
781 | arg *= SD_BLOCK_SIZE; | 781 | arg *= SD_BLOCK_SIZE; |
782 | 782 | ||
@@ -858,13 +858,13 @@ exit: | |||
858 | return ret; | 858 | return ret; |
859 | } | 859 | } |
860 | 860 | ||
861 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | 861 | int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, |
862 | void* buf) | 862 | void* buf) |
863 | { | 863 | { |
864 | return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); | 864 | return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); |
865 | } | 865 | } |
866 | 866 | ||
867 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 867 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, |
868 | const void* buf) | 868 | const void* buf) |
869 | { | 869 | { |
870 | return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); | 870 | return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); |
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 0450c8b410..26a228cddf 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c | |||
@@ -92,7 +92,7 @@ void INT_GPIOA(void); | |||
92 | default_interrupt(INT_GPIOB); | 92 | default_interrupt(INT_GPIOB); |
93 | default_interrupt(INT_GPIOC); | 93 | default_interrupt(INT_GPIOC); |
94 | 94 | ||
95 | static const char const irqname[][9] = | 95 | static const char irqname[][9] = |
96 | { | 96 | { |
97 | "WATCHDOG", "TIMER1", "TIMER2", "USB", "DMAC", "NAND", | 97 | "WATCHDOG", "TIMER1", "TIMER2", "USB", "DMAC", "NAND", |
98 | "IDE", "MCI0", "MCI1", "AUDIO", "SSP", "I2C_MS", | 98 | "IDE", "MCI0", "MCI1", "AUDIO", "SSP", "I2C_MS", |
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c index d61c223219..453a51ed1b 100644 --- a/firmware/target/arm/ata-nand-telechips.c +++ b/firmware/target/arm/ata-nand-telechips.c | |||
@@ -179,7 +179,7 @@ static int phys_segment_to_page_addr(int phys_segment, int page_in_seg) | |||
179 | break; | 179 | break; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | page_addr += (page_in_seg / nand_data->planes); | 183 | page_addr += (page_in_seg / nand_data->planes); |
184 | 184 | ||
185 | return page_addr; | 185 | return page_addr; |
@@ -222,7 +222,7 @@ static void nand_chip_select(int bank) | |||
222 | static void nand_read_id(int bank, unsigned char* id_buf) | 222 | static void nand_read_id(int bank, unsigned char* id_buf) |
223 | { | 223 | { |
224 | int i; | 224 | int i; |
225 | 225 | ||
226 | /* Enable NFC bus clock */ | 226 | /* Enable NFC bus clock */ |
227 | BCLKCTR |= DEV_NAND; | 227 | BCLKCTR |= DEV_NAND; |
228 | 228 | ||
@@ -358,7 +358,7 @@ static void nand_setup_read(int bank, int row, int column) | |||
358 | static void nand_end_read(void) | 358 | static void nand_end_read(void) |
359 | { | 359 | { |
360 | nand_chip_select(-1); | 360 | nand_chip_select(-1); |
361 | 361 | ||
362 | /* Disable NFC bus clock */ | 362 | /* Disable NFC bus clock */ |
363 | BCLKCTR &= ~DEV_NAND; | 363 | BCLKCTR &= ~DEV_NAND; |
364 | } | 364 | } |
@@ -367,7 +367,7 @@ static void nand_end_read(void) | |||
367 | static void nand_read_raw(int bank, int row, int column, int size, void* buf) | 367 | static void nand_read_raw(int bank, int row, int column, int size, void* buf) |
368 | { | 368 | { |
369 | int i; | 369 | int i; |
370 | 370 | ||
371 | nand_setup_read(bank, row, column); | 371 | nand_setup_read(bank, row, column); |
372 | 372 | ||
373 | /* Read data into page buffer */ | 373 | /* Read data into page buffer */ |
@@ -388,7 +388,7 @@ static void nand_read_raw(int bank, int row, int column, int size, void* buf) | |||
388 | ((unsigned int*)buf)[i] = NFC_WDATA; | 388 | ((unsigned int*)buf)[i] = NFC_WDATA; |
389 | } | 389 | } |
390 | } | 390 | } |
391 | 391 | ||
392 | nand_end_read(); | 392 | nand_end_read(); |
393 | } | 393 | } |
394 | 394 | ||
@@ -422,7 +422,7 @@ static void nand_get_chip_info(void) | |||
422 | sectors_per_page = nand_data->page_size / SECTOR_SIZE; | 422 | sectors_per_page = nand_data->page_size / SECTOR_SIZE; |
423 | 423 | ||
424 | sectors_per_segment = bytes_per_segment / SECTOR_SIZE; | 424 | sectors_per_segment = bytes_per_segment / SECTOR_SIZE; |
425 | 425 | ||
426 | pages_per_segment = sectors_per_segment / sectors_per_page; | 426 | pages_per_segment = sectors_per_segment / sectors_per_page; |
427 | 427 | ||
428 | /* Establish how many banks are present */ | 428 | /* Establish how many banks are present */ |
@@ -494,7 +494,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page, | |||
494 | 494 | ||
495 | #ifdef USE_ECC_CORRECTION | 495 | #ifdef USE_ECC_CORRECTION |
496 | unsigned long spare_buf[4]; | 496 | unsigned long spare_buf[4]; |
497 | 497 | ||
498 | /* Set up the ECC controller to monitor reads from NFC_WDATA */ | 498 | /* Set up the ECC controller to monitor reads from NFC_WDATA */ |
499 | BCLKCTR |= DEV_ECC; | 499 | BCLKCTR |= DEV_ECC; |
500 | ECC_BASE = (unsigned long)&NFC_WDATA; | 500 | ECC_BASE = (unsigned long)&NFC_WDATA; |
@@ -514,27 +514,27 @@ static bool nand_read_sector_of_phys_page(int bank, int page, | |||
514 | This way, reads are always done through NFC_WDATA - otherwise they | 514 | This way, reads are always done through NFC_WDATA - otherwise they |
515 | would not be 'seen' by the ECC controller. */ | 515 | would not be 'seen' by the ECC controller. */ |
516 | static char temp_buf[SECTOR_SIZE]; | 516 | static char temp_buf[SECTOR_SIZE]; |
517 | 517 | ||
518 | unsigned int* ptr = (unsigned int*) temp_buf; | 518 | unsigned int* ptr = (unsigned int*) temp_buf; |
519 | 519 | ||
520 | for (i = 0; i < (SECTOR_SIZE/4); i++) | 520 | for (i = 0; i < (SECTOR_SIZE/4); i++) |
521 | { | 521 | { |
522 | *ptr++ = NFC_WDATA; | 522 | *ptr++ = NFC_WDATA; |
523 | } | 523 | } |
524 | 524 | ||
525 | memcpy(buf, temp_buf, SECTOR_SIZE); | 525 | memcpy(buf, temp_buf, SECTOR_SIZE); |
526 | } | 526 | } |
527 | else | 527 | else |
528 | { | 528 | { |
529 | /* Use straight word copy as buffer and size are both word-aligned */ | 529 | /* Use straight word copy as buffer and size are both word-aligned */ |
530 | unsigned int* ptr = (unsigned int*) buf; | 530 | unsigned int* ptr = (unsigned int*) buf; |
531 | 531 | ||
532 | for (i = 0; i < (SECTOR_SIZE/4); i++) | 532 | for (i = 0; i < (SECTOR_SIZE/4); i++) |
533 | { | 533 | { |
534 | *ptr++ = NFC_WDATA; | 534 | *ptr++ = NFC_WDATA; |
535 | } | 535 | } |
536 | } | 536 | } |
537 | 537 | ||
538 | #ifdef USE_ECC_CORRECTION | 538 | #ifdef USE_ECC_CORRECTION |
539 | /* Stop monitoring before we read the OOB data */ | 539 | /* Stop monitoring before we read the OOB data */ |
540 | ECC_CTRL &= ~ECC_M4EN; | 540 | ECC_CTRL &= ~ECC_M4EN; |
@@ -549,29 +549,29 @@ static bool nand_read_sector_of_phys_page(int bank, int page, | |||
549 | /* Calculate MLC4 ECC using bytes 0,1,8-15 */ | 549 | /* Calculate MLC4 ECC using bytes 0,1,8-15 */ |
550 | BCLKCTR |= DEV_ECC; | 550 | BCLKCTR |= DEV_ECC; |
551 | ECC_CTRL |= ECC_M4EN; | 551 | ECC_CTRL |= ECC_M4EN; |
552 | 552 | ||
553 | MLC_ECC0W = *(unsigned short*)spare_buf; | 553 | MLC_ECC0W = *(unsigned short*)spare_buf; |
554 | MLC_ECC1W = spare_buf[2]; | 554 | MLC_ECC1W = spare_buf[2]; |
555 | MLC_ECC2W = spare_buf[3]; | 555 | MLC_ECC2W = spare_buf[3]; |
556 | 556 | ||
557 | while (!(ECC_CTRL & ECC_READY)) {}; | 557 | while (!(ECC_CTRL & ECC_READY)) {}; |
558 | 558 | ||
559 | int errors = ECC_ERR_NUM & 7; | 559 | int errors = ECC_ERR_NUM & 7; |
560 | 560 | ||
561 | switch (errors) | 561 | switch (errors) |
562 | { | 562 | { |
563 | case 4: /* nothing to correct */ | 563 | case 4: /* nothing to correct */ |
564 | break; | 564 | break; |
565 | 565 | ||
566 | case 7: /* fail, can't correct */ | 566 | case 7: /* fail, can't correct */ |
567 | ret = false; | 567 | ret = false; |
568 | break; | 568 | break; |
569 | 569 | ||
570 | default: /* between 1 and 4 errors */ | 570 | default: /* between 1 and 4 errors */ |
571 | { | 571 | { |
572 | int i; | 572 | int i; |
573 | unsigned char* char_buf = (unsigned char*)buf; | 573 | unsigned char* char_buf = (unsigned char*)buf; |
574 | 574 | ||
575 | for (i = 0; i < errors + 1; i++) | 575 | for (i = 0; i < errors + 1; i++) |
576 | { | 576 | { |
577 | int offset = 0x207 - ECC_ERRADDR(i); | 577 | int offset = 0x207 - ECC_ERRADDR(i); |
@@ -584,7 +584,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page, | |||
584 | ECC_CTRL &= ~ECC_M4EN; | 584 | ECC_CTRL &= ~ECC_M4EN; |
585 | BCLKCTR &= ~DEV_ECC; | 585 | BCLKCTR &= ~DEV_ECC; |
586 | #endif | 586 | #endif |
587 | 587 | ||
588 | nand_end_read(); | 588 | nand_end_read(); |
589 | 589 | ||
590 | return ret; | 590 | return ret; |
@@ -619,7 +619,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector, | |||
619 | 619 | ||
620 | int cache_num = 0; | 620 | int cache_num = 0; |
621 | bool found = false; | 621 | bool found = false; |
622 | 622 | ||
623 | while (!found && cache_num < write_caches_in_use) | 623 | while (!found && cache_num < write_caches_in_use) |
624 | { | 624 | { |
625 | if (write_caches[cache_num].log_segment == log_segment) | 625 | if (write_caches[cache_num].log_segment == log_segment) |
@@ -628,10 +628,10 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector, | |||
628 | { | 628 | { |
629 | /* data is located in random pages cache */ | 629 | /* data is located in random pages cache */ |
630 | found = true; | 630 | found = true; |
631 | 631 | ||
632 | bank = write_caches[cache_num].random_bank; | 632 | bank = write_caches[cache_num].random_bank; |
633 | phys_segment = write_caches[cache_num].random_phys_segment; | 633 | phys_segment = write_caches[cache_num].random_phys_segment; |
634 | 634 | ||
635 | page_in_segment = | 635 | page_in_segment = |
636 | write_caches[cache_num].page_map[page_in_segment]; | 636 | write_caches[cache_num].page_map[page_in_segment]; |
637 | } | 637 | } |
@@ -640,7 +640,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector, | |||
640 | { | 640 | { |
641 | /* data is located in in-place pages cache */ | 641 | /* data is located in in-place pages cache */ |
642 | found = true; | 642 | found = true; |
643 | 643 | ||
644 | bank = write_caches[cache_num].inplace_bank; | 644 | bank = write_caches[cache_num].inplace_bank; |
645 | phys_segment = write_caches[cache_num].inplace_phys_segment; | 645 | phys_segment = write_caches[cache_num].inplace_phys_segment; |
646 | } | 646 | } |
@@ -664,7 +664,7 @@ static inline unsigned char get_sector_type(char* spare_buf) | |||
664 | static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf) | 664 | static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf) |
665 | { | 665 | { |
666 | (void)phys_seg; | 666 | (void)phys_seg; |
667 | 667 | ||
668 | return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) | | 668 | return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) | |
669 | spare_buf[OFF_LOG_SEG_LOBYTE]) | 669 | spare_buf[OFF_LOG_SEG_LOBYTE]) |
670 | #if defined(FTL_V1) | 670 | #if defined(FTL_V1) |
@@ -702,7 +702,7 @@ static void read_random_writes_cache(int bank, int phys_segment) | |||
702 | 16, spare_buf); | 702 | 16, spare_buf); |
703 | 703 | ||
704 | log_segment = get_log_segment_id(phys_segment, spare_buf); | 704 | log_segment = get_log_segment_id(phys_segment, spare_buf); |
705 | 705 | ||
706 | if (log_segment == -1) | 706 | if (log_segment == -1) |
707 | return; | 707 | return; |
708 | 708 | ||
@@ -734,13 +734,13 @@ static void read_random_writes_cache(int bank, int phys_segment) | |||
734 | page++) | 734 | page++) |
735 | { | 735 | { |
736 | unsigned short cached_page; | 736 | unsigned short cached_page; |
737 | 737 | ||
738 | nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page), | 738 | nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page), |
739 | SECTOR_SIZE, /* offset to first sector's spare */ | 739 | SECTOR_SIZE, /* offset to first sector's spare */ |
740 | 16, spare_buf); | 740 | 16, spare_buf); |
741 | 741 | ||
742 | cached_page = get_cached_page_id(spare_buf); | 742 | cached_page = get_cached_page_id(spare_buf); |
743 | 743 | ||
744 | if (cached_page != 0xFFFF) | 744 | if (cached_page != 0xFFFF) |
745 | write_caches[cache_no].page_map[cached_page] = page; | 745 | write_caches[cache_no].page_map[cached_page] = page; |
746 | } | 746 | } |
@@ -759,10 +759,10 @@ static void read_inplace_writes_cache(int bank, int phys_segment) | |||
759 | 16, spare_buf); | 759 | 16, spare_buf); |
760 | 760 | ||
761 | log_segment = get_log_segment_id(phys_segment, spare_buf); | 761 | log_segment = get_log_segment_id(phys_segment, spare_buf); |
762 | 762 | ||
763 | if (log_segment == -1) | 763 | if (log_segment == -1) |
764 | return; | 764 | return; |
765 | 765 | ||
766 | /* Find which cache this is related to */ | 766 | /* Find which cache this is related to */ |
767 | int cache_no = find_write_cache(log_segment); | 767 | int cache_no = find_write_cache(log_segment); |
768 | 768 | ||
@@ -780,7 +780,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment) | |||
780 | } | 780 | } |
781 | 781 | ||
782 | write_caches[cache_no].log_segment = log_segment; | 782 | write_caches[cache_no].log_segment = log_segment; |
783 | 783 | ||
784 | /* Find how many pages have been written to the new segment */ | 784 | /* Find how many pages have been written to the new segment */ |
785 | while (log_segment != -1 && | 785 | while (log_segment != -1 && |
786 | page < (nand_data->pages_per_block * nand_data->planes) - 1) | 786 | page < (nand_data->pages_per_block * nand_data->planes) - 1) |
@@ -791,7 +791,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment) | |||
791 | 791 | ||
792 | log_segment = get_log_segment_id(phys_segment, spare_buf); | 792 | log_segment = get_log_segment_id(phys_segment, spare_buf); |
793 | } | 793 | } |
794 | 794 | ||
795 | if (page != 0) | 795 | if (page != 0) |
796 | { | 796 | { |
797 | write_caches[cache_no].inplace_bank = bank; | 797 | write_caches[cache_no].inplace_bank = bank; |
@@ -801,7 +801,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment) | |||
801 | } | 801 | } |
802 | 802 | ||
803 | 803 | ||
804 | int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | 804 | int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount, |
805 | void* inbuf) | 805 | void* inbuf) |
806 | { | 806 | { |
807 | #ifdef HAVE_MULTIDRIVE | 807 | #ifdef HAVE_MULTIDRIVE |
@@ -809,15 +809,15 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | |||
809 | #endif | 809 | #endif |
810 | 810 | ||
811 | int ret = 0; | 811 | int ret = 0; |
812 | 812 | ||
813 | mutex_lock(&ata_mtx); | 813 | mutex_lock(&ata_mtx); |
814 | 814 | ||
815 | led(true); | 815 | led(true); |
816 | 816 | ||
817 | while (incount > 0) | 817 | while (incount > 0) |
818 | { | 818 | { |
819 | int done = 0; | 819 | int done = 0; |
820 | int segment = start / sectors_per_segment; | 820 | sector_t segment = start / sectors_per_segment; |
821 | int secmod = start % sectors_per_segment; | 821 | int secmod = start % sectors_per_segment; |
822 | 822 | ||
823 | while (incount > 0 && secmod < sectors_per_segment) | 823 | while (incount > 0 && secmod < sectors_per_segment) |
@@ -839,7 +839,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | |||
839 | secmod++; | 839 | secmod++; |
840 | done++; | 840 | done++; |
841 | } | 841 | } |
842 | 842 | ||
843 | if (done < 0) | 843 | if (done < 0) |
844 | { | 844 | { |
845 | ret = -1; | 845 | ret = -1; |
@@ -852,11 +852,11 @@ nand_read_error: | |||
852 | 852 | ||
853 | mutex_unlock(&ata_mtx); | 853 | mutex_unlock(&ata_mtx); |
854 | led(false); | 854 | led(false); |
855 | 855 | ||
856 | return ret; | 856 | return ret; |
857 | } | 857 | } |
858 | 858 | ||
859 | int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 859 | int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, |
860 | const void* outbuf) | 860 | const void* outbuf) |
861 | { | 861 | { |
862 | #ifdef HAVE_MULTIDRIVE | 862 | #ifdef HAVE_MULTIDRIVE |
@@ -903,7 +903,7 @@ int nand_init(void) | |||
903 | unsigned char spare_buf[16]; | 903 | unsigned char spare_buf[16]; |
904 | 904 | ||
905 | if (initialized) return 0; | 905 | if (initialized) return 0; |
906 | 906 | ||
907 | mutex_init(&ata_mtx); | 907 | mutex_init(&ata_mtx); |
908 | 908 | ||
909 | /* Set GPIO direction for chip select & write protect */ | 909 | /* Set GPIO direction for chip select & write protect */ |
@@ -924,7 +924,7 @@ int nand_init(void) | |||
924 | 924 | ||
925 | memset(lpt_lookup, 0xff, lptbuf_size); | 925 | memset(lpt_lookup, 0xff, lptbuf_size); |
926 | memset(write_caches, 0xff, sizeof(write_caches)); | 926 | memset(write_caches, 0xff, sizeof(write_caches)); |
927 | 927 | ||
928 | write_caches_in_use = 0; | 928 | write_caches_in_use = 0; |
929 | 929 | ||
930 | /* Scan banks to build up block translation table */ | 930 | /* Scan banks to build up block translation table */ |
@@ -936,7 +936,7 @@ int nand_init(void) | |||
936 | nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0), | 936 | nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0), |
937 | SECTOR_SIZE, /* offset */ | 937 | SECTOR_SIZE, /* offset */ |
938 | 16, spare_buf); | 938 | 16, spare_buf); |
939 | 939 | ||
940 | int type = get_sector_type(spare_buf); | 940 | int type = get_sector_type(spare_buf); |
941 | 941 | ||
942 | #ifdef FTL_V2 | 942 | #ifdef FTL_V2 |
@@ -948,7 +948,7 @@ int nand_init(void) | |||
948 | nand_read_raw(bank, phys_segment_to_page_addr | 948 | nand_read_raw(bank, phys_segment_to_page_addr |
949 | (phys_segment, pages_per_segment - 1), | 949 | (phys_segment, pages_per_segment - 1), |
950 | SECTOR_SIZE, 16, spare_buf); | 950 | SECTOR_SIZE, 16, spare_buf); |
951 | 951 | ||
952 | if (get_sector_type(spare_buf) != 0xff) | 952 | if (get_sector_type(spare_buf) != 0xff) |
953 | { | 953 | { |
954 | type = SECTYPE_MAIN_DATA; | 954 | type = SECTYPE_MAIN_DATA; |
@@ -982,14 +982,14 @@ int nand_init(void) | |||
982 | } | 982 | } |
983 | break; | 983 | break; |
984 | } | 984 | } |
985 | 985 | ||
986 | case SECTYPE_MAIN_RANDOM_CACHE: | 986 | case SECTYPE_MAIN_RANDOM_CACHE: |
987 | { | 987 | { |
988 | /* Newly-written random page data (Main data area) */ | 988 | /* Newly-written random page data (Main data area) */ |
989 | read_random_writes_cache(bank, phys_segment); | 989 | read_random_writes_cache(bank, phys_segment); |
990 | break; | 990 | break; |
991 | } | 991 | } |
992 | 992 | ||
993 | case SECTYPE_MAIN_INPLACE_CACHE: | 993 | case SECTYPE_MAIN_INPLACE_CACHE: |
994 | { | 994 | { |
995 | /* Newly-written sequential page data (Main data area) */ | 995 | /* Newly-written sequential page data (Main data area) */ |
@@ -999,7 +999,7 @@ int nand_init(void) | |||
999 | } | 999 | } |
1000 | } | 1000 | } |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | initialized = true; | 1003 | initialized = true; |
1004 | 1004 | ||
1005 | return 0; | 1005 | return 0; |
@@ -1029,7 +1029,7 @@ int nand_num_drives(int first_drive) | |||
1029 | { | 1029 | { |
1030 | /* We don't care which logical drive number we have been assigned */ | 1030 | /* We don't care which logical drive number we have been assigned */ |
1031 | (void)first_drive; | 1031 | (void)first_drive; |
1032 | 1032 | ||
1033 | return 1; | 1033 | return 1; |
1034 | } | 1034 | } |
1035 | 1035 | ||
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c index 59c23c1a76..1a8f523d5a 100644 --- a/firmware/target/arm/imx233/clkctrl-imx233.c +++ b/firmware/target/arm/imx233/clkctrl-imx233.c | |||
@@ -87,7 +87,9 @@ void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div) | |||
87 | case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV(div)); break; | 87 | case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV(div)); break; |
88 | #endif | 88 | #endif |
89 | case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV(div)); break; | 89 | case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV(div)); break; |
90 | case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV(div)); break; | 90 | case CLK_HBUS: |
91 | /* make sure to switch to integer divide mode simulteanously */ | ||
92 | BF_WR(CLKCTRL_HBUS, DIV_FRAC_EN(0), DIV(div)); break; | ||
91 | case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV(div)); break; | 93 | case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV(div)); break; |
92 | default: return; | 94 | default: return; |
93 | } | 95 | } |
@@ -107,7 +109,12 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk) | |||
107 | case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV); | 109 | case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV); |
108 | #endif | 110 | #endif |
109 | case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV); | 111 | case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV); |
110 | case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV); | 112 | case CLK_HBUS: |
113 | /* since fractional and integer divider share the same field, clain it is disabled in frac mode */ | ||
114 | if(BF_RD(CLKCTRL_HBUS, DIV_FRAC_EN)) | ||
115 | return 0; | ||
116 | else | ||
117 | return BF_RD(CLKCTRL_HBUS, DIV); | ||
111 | case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV); | 118 | case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV); |
112 | default: return 0; | 119 | default: return 0; |
113 | } | 120 | } |
@@ -130,6 +137,14 @@ void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv) | |||
130 | handle_frac(IO) | 137 | handle_frac(IO) |
131 | handle_frac(CPU) | 138 | handle_frac(CPU) |
132 | handle_frac(EMI) | 139 | handle_frac(EMI) |
140 | case CLK_HBUS: | ||
141 | if(fracdiv == 0) | ||
142 | panicf("Don't set hbus fracdiv to 0!"); | ||
143 | /* value 0 is forbidden because we can't simply disabble the divider, it's always | ||
144 | * active but either in integer or fractional mode | ||
145 | * make sure we write both the value and frac_en bit at the same time */ | ||
146 | BF_WR(CLKCTRL_HBUS, DIV_FRAC_EN(1), DIV(fracdiv)); | ||
147 | break; | ||
133 | default: break; | 148 | default: break; |
134 | } | 149 | } |
135 | #undef handle_frac | 150 | #undef handle_frac |
@@ -151,6 +166,11 @@ int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk) | |||
151 | handle_frac(IO) | 166 | handle_frac(IO) |
152 | handle_frac(CPU) | 167 | handle_frac(CPU) |
153 | handle_frac(EMI) | 168 | handle_frac(EMI) |
169 | case CLK_HBUS: | ||
170 | if(BF_RD(CLKCTRL_HBUS, DIV_FRAC_EN)) | ||
171 | return BF_RD(CLKCTRL_HBUS, DIV); | ||
172 | else | ||
173 | return 0; | ||
154 | default: return 0; | 174 | default: return 0; |
155 | } | 175 | } |
156 | #undef handle_frac | 176 | #undef handle_frac |
@@ -303,8 +323,12 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk) | |||
303 | /* Derived from clk_p via integer/fractional div */ | 323 | /* Derived from clk_p via integer/fractional div */ |
304 | unsigned ref = imx233_clkctrl_get_freq(CLK_CPU); | 324 | unsigned ref = imx233_clkctrl_get_freq(CLK_CPU); |
305 | #if IMX233_SUBTARGET >= 3700 | 325 | #if IMX233_SUBTARGET >= 3700 |
326 | /* if divider is in fractional mode, integer divider does not take effect (in fact it's | ||
327 | * the same divider but in a different mode ). Also the fractiona value is encoded as | ||
328 | * a fraction, not a divider */ | ||
306 | if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0) | 329 | if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0) |
307 | ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32; | 330 | ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32; |
331 | else | ||
308 | #endif | 332 | #endif |
309 | if(imx233_clkctrl_get_div(CLK_HBUS) != 0) | 333 | if(imx233_clkctrl_get_div(CLK_HBUS) != 0) |
310 | ref /= imx233_clkctrl_get_div(CLK_HBUS); | 334 | ref /= imx233_clkctrl_get_div(CLK_HBUS); |
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h index f12d181c50..d150912cfe 100644 --- a/firmware/target/arm/imx233/clkctrl-imx233.h +++ b/firmware/target/arm/imx233/clkctrl-imx233.h | |||
@@ -68,7 +68,7 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk); | |||
68 | #if IMX233_SUBTARGET >= 3700 | 68 | #if IMX233_SUBTARGET >= 3700 |
69 | /* call with fracdiv=0 to disable it */ | 69 | /* call with fracdiv=0 to disable it */ |
70 | void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv); | 70 | void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv); |
71 | /* 0 means fractional dividor disable */ | 71 | /* 0 means fractional dividor disabled */ |
72 | int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk); | 72 | int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk); |
73 | void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass); | 73 | void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass); |
74 | bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk); | 74 | bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk); |
diff --git a/firmware/target/arm/imx233/nand-imx233.c b/firmware/target/arm/imx233/nand-imx233.c index a7afba7d43..22da408e05 100644 --- a/firmware/target/arm/imx233/nand-imx233.c +++ b/firmware/target/arm/imx233/nand-imx233.c | |||
@@ -36,13 +36,13 @@ int nand_init(void) | |||
36 | { | 36 | { |
37 | return -1; | 37 | return -1; |
38 | } | 38 | } |
39 | int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, | 39 | int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, |
40 | void* buf) | 40 | void* buf) |
41 | { | 41 | { |
42 | return -1; | 42 | return -1; |
43 | } | 43 | } |
44 | 44 | ||
45 | int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 45 | int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, |
46 | const void* buf) | 46 | const void* buf) |
47 | { | 47 | { |
48 | return -1; | 48 | return -1; |
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c index 83a0bf8b42..69d0ba4199 100644 --- a/firmware/target/arm/imx233/partitions-imx233.c +++ b/firmware/target/arm/imx233/partitions-imx233.c | |||
@@ -71,7 +71,7 @@ static const char *creative_part_name(enum imx233_part_t part) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, | 73 | static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, |
74 | enum imx233_part_t part, unsigned *start, unsigned *end) | 74 | enum imx233_part_t part, sector_t *start, sector_t *end) |
75 | { | 75 | { |
76 | uint8_t mblk[512]; | 76 | uint8_t mblk[512]; |
77 | int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk); | 77 | int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk); |
@@ -99,7 +99,7 @@ static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, | |||
99 | } | 99 | } |
100 | else | 100 | else |
101 | *end = *start + ent[i].size * hdr->block_size / 512; | 101 | *end = *start + ent[i].size * hdr->block_size / 512; |
102 | 102 | ||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | } | 105 | } |
@@ -109,7 +109,7 @@ static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, | |||
109 | 109 | ||
110 | #if (IMX233_PARTITIONS & IMX233_FREESCALE) | 110 | #if (IMX233_PARTITIONS & IMX233_FREESCALE) |
111 | static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn, | 111 | static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn, |
112 | enum imx233_part_t part, unsigned *start, unsigned *end) | 112 | enum imx233_part_t part, sector_t *start, sector_t *end) |
113 | { | 113 | { |
114 | uint8_t mbr[512]; | 114 | uint8_t mbr[512]; |
115 | int ret = read_fn(user, 0, 1, mbr); | 115 | int ret = read_fn(user, 0, 1, mbr); |
@@ -179,7 +179,7 @@ static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn, | |||
179 | #endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */ | 179 | #endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */ |
180 | 180 | ||
181 | int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, | 181 | int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, |
182 | enum imx233_part_t part, unsigned *start, unsigned *end) | 182 | enum imx233_part_t part, sector_t *start, sector_t *end) |
183 | { | 183 | { |
184 | int ret = -1; | 184 | int ret = -1; |
185 | #if (IMX233_PARTITIONS & IMX233_CREATIVE) | 185 | #if (IMX233_PARTITIONS & IMX233_CREATIVE) |
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h index e5378dadbb..edc6c1b2f4 100644 --- a/firmware/target/arm/imx233/partitions-imx233.h +++ b/firmware/target/arm/imx233/partitions-imx233.h | |||
@@ -45,7 +45,7 @@ enum imx233_part_t | |||
45 | /** The computation function can be called very early in the boot, at which point | 45 | /** The computation function can be called very early in the boot, at which point |
46 | * usual storage read/write function may not be available. To workaround this | 46 | * usual storage read/write function may not be available. To workaround this |
47 | * issue, one must provide a read function. */ | 47 | * issue, one must provide a read function. */ |
48 | typedef int (*part_read_fn_t)(intptr_t user, unsigned long start, int count, void* buf); | 48 | typedef int (*part_read_fn_t)(intptr_t user, sector_t start, int count, void* buf); |
49 | /* Enable/Disable window computations for internal storage following the | 49 | /* Enable/Disable window computations for internal storage following the |
50 | * Freescale/Creative convention */ | 50 | * Freescale/Creative convention */ |
51 | void imx233_partitions_enable_window(bool enable); | 51 | void imx233_partitions_enable_window(bool enable); |
@@ -55,6 +55,6 @@ bool imx233_partitions_is_window_enabled(void); | |||
55 | * for a whole disk, *end should be the size of the disk when the function is | 55 | * for a whole disk, *end should be the size of the disk when the function is |
56 | * called */ | 56 | * called */ |
57 | int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, | 57 | int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, |
58 | enum imx233_part_t part, unsigned *start, unsigned *end); | 58 | enum imx233_part_t part, sector_t *start, sector_t *end); |
59 | 59 | ||
60 | #endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file | 60 | #endif /* __PARTITIONS_IMX233__ */ |
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c index af090e8a07..02f59a50f4 100644 --- a/firmware/target/arm/imx233/sdmmc-imx233.c +++ b/firmware/target/arm/imx233/sdmmc-imx233.c | |||
@@ -203,8 +203,8 @@ struct sdmmc_status_t | |||
203 | * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */ | 203 | * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */ |
204 | 204 | ||
205 | /* common */ | 205 | /* common */ |
206 | static unsigned window_start[SDMMC_NUM_DRIVES]; | 206 | static sector_t window_start[SDMMC_NUM_DRIVES]; |
207 | static unsigned window_end[SDMMC_NUM_DRIVES]; | 207 | static sector_t window_end[SDMMC_NUM_DRIVES]; |
208 | static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR; | 208 | static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR; |
209 | static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; | 209 | static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; |
210 | static struct mutex mutex[SDMMC_NUM_DRIVES]; | 210 | static struct mutex mutex[SDMMC_NUM_DRIVES]; |
@@ -648,7 +648,7 @@ int mmc_event(long id, intptr_t data) | |||
648 | #endif /* CONFIG_STORAGE & STORAGE_MMC */ | 648 | #endif /* CONFIG_STORAGE & STORAGE_MMC */ |
649 | 649 | ||
650 | /* low-level function, don't call directly! */ | 650 | /* low-level function, don't call directly! */ |
651 | static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) | 651 | static int __xfer_sectors(int drive, sector_t start, int count, void *buf, bool read) |
652 | { | 652 | { |
653 | uint32_t resp; | 653 | uint32_t resp; |
654 | int ret = 0; | 654 | int ret = 0; |
@@ -660,7 +660,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, | |||
660 | need_stop = false; | 660 | need_stop = false; |
661 | /* Set bank_start to the correct unit (blocks or bytes). | 661 | /* Set bank_start to the correct unit (blocks or bytes). |
662 | * MMC drives use block addressing, SD cards bytes or blocks */ | 662 | * MMC drives use block addressing, SD cards bytes or blocks */ |
663 | int bank_start = start; | 663 | sector_t bank_start = start; |
664 | if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */ | 664 | if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */ |
665 | bank_start *= SD_BLOCK_SIZE; | 665 | bank_start *= SD_BLOCK_SIZE; |
666 | /* issue read/write | 666 | /* issue read/write |
@@ -686,7 +686,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, | |||
686 | return ret; | 686 | return ret; |
687 | } | 687 | } |
688 | 688 | ||
689 | static int transfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) | 689 | static int transfer_sectors(int drive, sector_t start, int count, void *buf, bool read) |
690 | { | 690 | { |
691 | int ret = 0; | 691 | int ret = 0; |
692 | /* the function doesn't work when count is 0 */ | 692 | /* the function doesn't work when count is 0 */ |
@@ -806,7 +806,7 @@ static int transfer_sectors(int drive, unsigned long start, int count, void *buf | |||
806 | } | 806 | } |
807 | 807 | ||
808 | /* user specifies the sdmmc drive */ | 808 | /* user specifies the sdmmc drive */ |
809 | static int part_read_fn(intptr_t user, unsigned long start, int count, void* buf) | 809 | static int part_read_fn(intptr_t user, sector_t start, int count, void* buf) |
810 | { | 810 | { |
811 | return transfer_sectors(user, start, count, buf, true); | 811 | return transfer_sectors(user, start, count, buf, true); |
812 | } | 812 | } |
@@ -917,7 +917,7 @@ void sd_enable(bool on) | |||
917 | (void) on; | 917 | (void) on; |
918 | } | 918 | } |
919 | 919 | ||
920 | int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *buf) | 920 | int sd_read_sectors(IF_MD(int sd_drive,) sector_t start, int count, void *buf) |
921 | { | 921 | { |
922 | #ifndef HAVE_MULTIDRIVE | 922 | #ifndef HAVE_MULTIDRIVE |
923 | int sd_drive = 0; | 923 | int sd_drive = 0; |
@@ -925,7 +925,7 @@ int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *b | |||
925 | return transfer_sectors(sd_map[sd_drive], start, count, buf, true); | 925 | return transfer_sectors(sd_map[sd_drive], start, count, buf, true); |
926 | } | 926 | } |
927 | 927 | ||
928 | int sd_write_sectors(IF_MD(int sd_drive,) unsigned long start, int count, const void* buf) | 928 | int sd_write_sectors(IF_MD(int sd_drive,) sector_t start, int count, const void* buf) |
929 | { | 929 | { |
930 | #ifndef HAVE_MULTIDRIVE | 930 | #ifndef HAVE_MULTIDRIVE |
931 | int sd_drive = 0; | 931 | int sd_drive = 0; |
@@ -1039,7 +1039,7 @@ int mmc_spinup_time(void) | |||
1039 | return 0; | 1039 | return 0; |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void *buf) | 1042 | int mmc_read_sectors(IF_MD(int mmc_drive,) sector_t start, int count, void *buf) |
1043 | { | 1043 | { |
1044 | #ifndef HAVE_MULTIDRIVE | 1044 | #ifndef HAVE_MULTIDRIVE |
1045 | int mmc_drive = 0; | 1045 | int mmc_drive = 0; |
@@ -1047,7 +1047,7 @@ int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void | |||
1047 | return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true); | 1047 | return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true); |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | int mmc_write_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, const void* buf) | 1050 | int mmc_write_sectors(IF_MD(int mmc_drive,) sector_t start, int count, const void* buf) |
1051 | { | 1051 | { |
1052 | #ifndef HAVE_MULTIDRIVE | 1052 | #ifndef HAVE_MULTIDRIVE |
1053 | int mmc_drive = 0; | 1053 | int mmc_drive = 0; |
diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c index 8f238936e7..9308b7664e 100644 --- a/firmware/target/arm/ipod/button-clickwheel.c +++ b/firmware/target/arm/ipod/button-clickwheel.c | |||
@@ -327,7 +327,13 @@ void ipod_4g_button_int(void) | |||
327 | void button_init_device(void) | 327 | void button_init_device(void) |
328 | { | 328 | { |
329 | opto_i2c_init(); | 329 | opto_i2c_init(); |
330 | 330 | ||
331 | /* fixes first button press being ignored */ | ||
332 | #if defined(IPOD_4G) || defined(IPOD_COLOR) | ||
333 | outl(inl(0x7000c100) & ~0x60000000, 0x7000c100); | ||
334 | outl(inl(0x7000c104) | 0x04000000, 0x7000c104); | ||
335 | outl(inl(0x7000c100) | 0x60000000, 0x7000c100); | ||
336 | #endif | ||
331 | /* hold button - enable as input */ | 337 | /* hold button - enable as input */ |
332 | GPIOA_ENABLE |= 0x20; | 338 | GPIOA_ENABLE |= 0x20; |
333 | GPIOA_OUTPUT_EN &= ~0x20; | 339 | GPIOA_OUTPUT_EN &= ~0x20; |
diff --git a/firmware/target/arm/pp/ata-pp5020.c b/firmware/target/arm/pp/ata-pp5020.c index 176e74993c..7351215693 100644 --- a/firmware/target/arm/pp/ata-pp5020.c +++ b/firmware/target/arm/pp/ata-pp5020.c | |||
@@ -48,8 +48,8 @@ bool ata_is_coldstart() | |||
48 | rest are the same. They go in IDE0_PRI_TIMING0. | 48 | rest are the same. They go in IDE0_PRI_TIMING0. |
49 | 49 | ||
50 | Rockbox used to use 0x10, and test_disk shows that leads to faster PIO. | 50 | Rockbox used to use 0x10, and test_disk shows that leads to faster PIO. |
51 | However on some disks connected with mSATA adapters this causes corrupt data | 51 | However when used with mSATA and some SD adapters this causes corrupt data |
52 | so we now just use these timings from the OF. | 52 | so we now unconditionally use these timings from the OF. |
53 | */ | 53 | */ |
54 | static const unsigned long pio80mhz[] = { | 54 | static const unsigned long pio80mhz[] = { |
55 | 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131 | 55 | 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131 |
@@ -83,10 +83,7 @@ void ata_device_init() | |||
83 | /* Setup the timing for PIO mode */ | 83 | /* Setup the timing for PIO mode */ |
84 | void ata_set_pio_timings(int mode) | 84 | void ata_set_pio_timings(int mode) |
85 | { | 85 | { |
86 | if (ata_disk_isssd()) | 86 | IDE0_PRI_TIMING0 = pio80mhz[mode]; |
87 | IDE0_PRI_TIMING0 = pio80mhz[mode]; | ||
88 | else | ||
89 | IDE0_PRI_TIMING0 = 0x10; | ||
90 | } | 87 | } |
91 | 88 | ||
92 | #ifdef HAVE_ATA_DMA | 89 | #ifdef HAVE_ATA_DMA |
@@ -109,6 +106,8 @@ static bool dma_boosted = false; | |||
109 | static bool dma_needs_boost; | 106 | static bool dma_needs_boost; |
110 | #endif | 107 | #endif |
111 | 108 | ||
109 | static int ata_is_ssd = 0; | ||
110 | |||
112 | /* This function sets up registers for 80 Mhz. | 111 | /* This function sets up registers for 80 Mhz. |
113 | Ultra DMA mode 2 works at 30 Mhz. | 112 | Ultra DMA mode 2 works at 30 Mhz. |
114 | */ | 113 | */ |
@@ -136,6 +135,8 @@ void ata_dma_set_mode(unsigned char mode) { | |||
136 | #if !defined(IPOD_NANO) | 135 | #if !defined(IPOD_NANO) |
137 | IDE0_CFG |= 0x20000000; /* >= 50 Mhz */ | 136 | IDE0_CFG |= 0x20000000; /* >= 50 Mhz */ |
138 | #endif | 137 | #endif |
138 | |||
139 | ata_is_ssd = ata_disk_isssd(); | ||
139 | } | 140 | } |
140 | 141 | ||
141 | #define IDE_CFG_INTRQ 8 | 142 | #define IDE_CFG_INTRQ 8 |
@@ -175,11 +176,12 @@ bool ata_dma_setup(void *addr, unsigned long bytes, bool write) { | |||
175 | /* Writes only need to be word-aligned, but by default DMA | 176 | /* Writes only need to be word-aligned, but by default DMA |
176 | * is not used for writing on non-SSDs as it appears to be slower. | 177 | * is not used for writing on non-SSDs as it appears to be slower. |
177 | */ | 178 | */ |
178 | if (!ata_disk_isssd()) | 179 | if (write) { |
179 | return false; | 180 | if ((unsigned long)addr & 3) |
180 | 181 | return false; | |
181 | if (write && ((unsigned long)addr & 3)) | 182 | if (!ata_is_ssd) |
182 | return false; | 183 | return false; |
184 | } | ||
183 | 185 | ||
184 | #if ATA_MAX_UDMA > 2 | 186 | #if ATA_MAX_UDMA > 2 |
185 | if (dma_needs_boost && !dma_boosted) { | 187 | if (dma_needs_boost && !dma_boosted) { |
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c index fb0a9e150e..b998afd21e 100644 --- a/firmware/target/arm/pp/ata-sd-pp.c +++ b/firmware/target/arm/pp/ata-sd-pp.c | |||
@@ -82,7 +82,7 @@ | |||
82 | #define STAT_TIME_OUT_RES (1 << 1) | 82 | #define STAT_TIME_OUT_RES (1 << 1) |
83 | #define STAT_TIME_OUT_READ (1) | 83 | #define STAT_TIME_OUT_READ (1) |
84 | #define STAT_ERROR_BITS (0x3f) | 84 | #define STAT_ERROR_BITS (0x3f) |
85 | 85 | ||
86 | /* MMC_CMDAT bits */ | 86 | /* MMC_CMDAT bits */ |
87 | /* Some of the bits used by the OF don't make much sense with these */ | 87 | /* Some of the bits used by the OF don't make much sense with these */ |
88 | /* definitions. So they're probably different between PXA and PP502x */ | 88 | /* definitions. So they're probably different between PXA and PP502x */ |
@@ -101,7 +101,7 @@ | |||
101 | #define CMDAT_RES_TYPE3 (3) | 101 | #define CMDAT_RES_TYPE3 (3) |
102 | #define CMDAT_RES_TYPE2 (2) | 102 | #define CMDAT_RES_TYPE2 (2) |
103 | #define CMDAT_RES_TYPE1 (1) | 103 | #define CMDAT_RES_TYPE1 (1) |
104 | 104 | ||
105 | /* MMC_I_MASK bits */ | 105 | /* MMC_I_MASK bits */ |
106 | /* PP502x apparently only has bits 0-3 */ | 106 | /* PP502x apparently only has bits 0-3 */ |
107 | #define I_MASK_SDIO_SUSPEND_ACK (1 << 12) | 107 | #define I_MASK_SDIO_SUSPEND_ACK (1 << 12) |
@@ -499,18 +499,18 @@ static inline void copy_write_sectors(const unsigned char** buf) | |||
499 | { | 499 | { |
500 | asm volatile ( | 500 | asm volatile ( |
501 | "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" | 501 | "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" |
502 | "mov r4, r3, lsr #16 \r\n" | 502 | "mov r4, r3, lsr #16 \r\n" |
503 | "mov r6, r5, lsr #16 \r\n" | 503 | "mov r6, r5, lsr #16 \r\n" |
504 | "mov r8, r7, lsr #16 \r\n" | 504 | "mov r8, r7, lsr #16 \r\n" |
505 | "mov r10, r9, lsr #16 \r\n" | 505 | "mov r10, r9, lsr #16 \r\n" |
506 | "stmia %[data], { r3-r10 } \r\n" | 506 | "stmia %[data], { r3-r10 } \r\n" |
507 | "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" | 507 | "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" |
508 | "mov r4, r3, lsr #16 \r\n" | 508 | "mov r4, r3, lsr #16 \r\n" |
509 | "mov r6, r5, lsr #16 \r\n" | 509 | "mov r6, r5, lsr #16 \r\n" |
510 | "mov r8, r7, lsr #16 \r\n" | 510 | "mov r8, r7, lsr #16 \r\n" |
511 | "mov %[t], r9, lsr #16 \r\n" | 511 | "mov %[t], r9, lsr #16 \r\n" |
512 | "stmia %[data], { r3-r9 } \r\n" | 512 | "stmia %[data], { r3-r9 } \r\n" |
513 | : [buf]"+&r"(*buf), [t]"=&r"(t) | 513 | : [buf]"+&r"(*buf), [t]"=&r"(t) |
514 | : [data]"r"(&MMC_DATA_FIFO) | 514 | : [data]"r"(&MMC_DATA_FIFO) |
515 | : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" | 515 | : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" |
516 | ); | 516 | ); |
@@ -760,7 +760,7 @@ static void sd_init_device(int card_no) | |||
760 | currcard->csd[i] = temp_reg[3-i]; | 760 | currcard->csd[i] = temp_reg[3-i]; |
761 | 761 | ||
762 | sd_parse_csd(currcard); | 762 | sd_parse_csd(currcard); |
763 | 763 | ||
764 | MMC_CLKRT = 0; /* switch to highest clock rate */ | 764 | MMC_CLKRT = 0; /* switch to highest clock rate */ |
765 | 765 | ||
766 | ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL, | 766 | ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL, |
@@ -849,7 +849,7 @@ static void sd_select_device(int card_no) | |||
849 | 849 | ||
850 | /* API Functions */ | 850 | /* API Functions */ |
851 | 851 | ||
852 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | 852 | int sd_read_sectors(IF_MD(int drive,) sector_t start, int incount, |
853 | void* inbuf) | 853 | void* inbuf) |
854 | { | 854 | { |
855 | #ifndef HAVE_MULTIDRIVE | 855 | #ifndef HAVE_MULTIDRIVE |
@@ -857,8 +857,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | |||
857 | #endif | 857 | #endif |
858 | int ret; | 858 | int ret; |
859 | unsigned char *buf, *buf_end; | 859 | unsigned char *buf, *buf_end; |
860 | unsigned int bank; | 860 | sector_t bank; |
861 | 861 | ||
862 | /* TODO: Add DMA support. */ | 862 | /* TODO: Add DMA support. */ |
863 | 863 | ||
864 | mutex_lock(&sd_mtx); | 864 | mutex_lock(&sd_mtx); |
@@ -894,7 +894,7 @@ sd_read_retry: | |||
894 | if (ret < 0) | 894 | if (ret < 0) |
895 | goto sd_read_error; | 895 | goto sd_read_error; |
896 | } | 896 | } |
897 | 897 | ||
898 | start -= bank * BLOCKS_PER_BANK; | 898 | start -= bank * BLOCKS_PER_BANK; |
899 | } | 899 | } |
900 | 900 | ||
@@ -904,6 +904,8 @@ sd_read_retry: | |||
904 | 904 | ||
905 | MMC_NUMBLK = incount; | 905 | MMC_NUMBLK = incount; |
906 | 906 | ||
907 | // XXX 64-bit addresses.. | ||
908 | |||
907 | #ifdef HAVE_HOTSWAP | 909 | #ifdef HAVE_HOTSWAP |
908 | if(currcard->ocr & (1<<30) ) | 910 | if(currcard->ocr & (1<<30) ) |
909 | { | 911 | { |
@@ -966,7 +968,7 @@ sd_read_error: | |||
966 | } | 968 | } |
967 | } | 969 | } |
968 | 970 | ||
969 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 971 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, |
970 | const void* outbuf) | 972 | const void* outbuf) |
971 | { | 973 | { |
972 | /* Write support is not finished yet */ | 974 | /* Write support is not finished yet */ |
@@ -1010,7 +1012,7 @@ sd_write_retry: | |||
1010 | if (ret < 0) | 1012 | if (ret < 0) |
1011 | goto sd_write_error; | 1013 | goto sd_write_error; |
1012 | } | 1014 | } |
1013 | 1015 | ||
1014 | start -= bank * BLOCKS_PER_BANK; | 1016 | start -= bank * BLOCKS_PER_BANK; |
1015 | } | 1017 | } |
1016 | 1018 | ||
@@ -1250,7 +1252,7 @@ int sd_num_drives(int first_drive) | |||
1250 | #else | 1252 | #else |
1251 | (void)first_drive; | 1253 | (void)first_drive; |
1252 | #endif | 1254 | #endif |
1253 | 1255 | ||
1254 | #ifdef HAVE_MULTIDRIVE | 1256 | #ifdef HAVE_MULTIDRIVE |
1255 | return 2; | 1257 | return 2; |
1256 | #else | 1258 | #else |
diff --git a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c index e257416cd0..54a1223cfc 100644 --- a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c +++ b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c | |||
@@ -31,18 +31,18 @@ | |||
31 | 31 | ||
32 | /* This file provides only STUBS for now */ | 32 | /* This file provides only STUBS for now */ |
33 | 33 | ||
34 | /** static, private data **/ | 34 | /** static, private data **/ |
35 | static bool initialized = false; | 35 | static bool initialized = false; |
36 | 36 | ||
37 | /* API Functions */ | 37 | /* API Functions */ |
38 | int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | 38 | int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount, |
39 | void* inbuf) | 39 | void* inbuf) |
40 | { | 40 | { |
41 | (void)drive; | 41 | (void)drive; |
42 | return ftl_read(start, incount, inbuf); | 42 | return ftl_read(start, incount, inbuf); |
43 | } | 43 | } |
44 | 44 | ||
45 | int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 45 | int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, |
46 | const void* outbuf) | 46 | const void* outbuf) |
47 | { | 47 | { |
48 | (void)drive; | 48 | (void)drive; |
@@ -112,7 +112,7 @@ int nand_num_drives(int first_drive) | |||
112 | { | 112 | { |
113 | /* We don't care which logical drive number(s) we have been assigned */ | 113 | /* We don't care which logical drive number(s) we have been assigned */ |
114 | (void)first_drive; | 114 | (void)first_drive; |
115 | 115 | ||
116 | return 1; | 116 | return 1; |
117 | } | 117 | } |
118 | #endif | 118 | #endif |
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c index 2ddf91a67e..e082a8bf2e 100644 --- a/firmware/target/arm/rk27xx/sd-rk27xx.c +++ b/firmware/target/arm/rk27xx/sd-rk27xx.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "panic.h" | 35 | #include "panic.h" |
36 | #include "stdbool.h" | 36 | #include "stdbool.h" |
37 | #include "storage.h" | 37 | #include "storage.h" |
38 | 38 | #include "timeout.h" | |
39 | #include "lcd.h" | 39 | #include "lcd.h" |
40 | #include <stdarg.h> | 40 | #include <stdarg.h> |
41 | #include "sysfont.h" | 41 | #include "sysfont.h" |
@@ -453,7 +453,7 @@ static inline void write_sd_data(unsigned char **src) | |||
453 | *src += 512; | 453 | *src += 512; |
454 | } | 454 | } |
455 | 455 | ||
456 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | 456 | int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, |
457 | void* buf) | 457 | void* buf) |
458 | { | 458 | { |
459 | #ifdef HAVE_MULTIDRIVE | 459 | #ifdef HAVE_MULTIDRIVE |
@@ -498,6 +498,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | |||
498 | DATA_XFER_MULTI; | 498 | DATA_XFER_MULTI; |
499 | } | 499 | } |
500 | 500 | ||
501 | // XXX 64-bit | ||
502 | |||
501 | /* issue read command to the card */ | 503 | /* issue read command to the card */ |
502 | if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) | 504 | if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) |
503 | { | 505 | { |
@@ -576,7 +578,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, | |||
576 | } | 578 | } |
577 | 579 | ||
578 | /* Not tested */ | 580 | /* Not tested */ |
579 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 581 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, |
580 | const void* buf) | 582 | const void* buf) |
581 | { | 583 | { |
582 | #ifdef HAVE_MULTIDRIVE | 584 | #ifdef HAVE_MULTIDRIVE |
@@ -620,6 +622,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, | |||
620 | 622 | ||
621 | write_sd_data(&src); /* put data into transfer buffer */ | 623 | write_sd_data(&src); /* put data into transfer buffer */ |
622 | 624 | ||
625 | // XXX 64-bit | ||
623 | if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) | 626 | if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) |
624 | { | 627 | { |
625 | ret = -3; | 628 | ret = -3; |
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c index 2ff68aa4ee..82fd60c711 100644 --- a/firmware/target/arm/s3c2440/sd-s3c2440.c +++ b/firmware/target/arm/s3c2440/sd-s3c2440.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | //#define SD_DEBUG | 22 | //#define SD_DEBUG |
23 | 23 | ||
24 | #include "system.h" | 24 | #include "system.h" |
@@ -33,7 +33,7 @@ | |||
33 | #include "sdmmc.h" | 33 | #include "sdmmc.h" |
34 | #endif | 34 | #endif |
35 | #include "storage.h" | 35 | #include "storage.h" |
36 | #include "dma-target.h" | 36 | #include "dma-target.h" |
37 | #include "system-target.h" | 37 | #include "system-target.h" |
38 | #include "led-mini2440.h" | 38 | #include "led-mini2440.h" |
39 | 39 | ||
@@ -83,7 +83,7 @@ struct sd_card_status | |||
83 | int retry_max; | 83 | int retry_max; |
84 | }; | 84 | }; |
85 | 85 | ||
86 | /** static, private data **/ | 86 | /** static, private data **/ |
87 | 87 | ||
88 | /* for compatibility */ | 88 | /* for compatibility */ |
89 | static long last_disk_activity = -1; | 89 | static long last_disk_activity = -1; |
@@ -117,13 +117,13 @@ static struct mutex sd_mtx SHAREDBSS_ATTR; | |||
117 | static struct semaphore transfer_completion_signal; | 117 | static struct semaphore transfer_completion_signal; |
118 | static volatile unsigned int transfer_error[NUM_DRIVES]; | 118 | static volatile unsigned int transfer_error[NUM_DRIVES]; |
119 | /* align on cache line size */ | 119 | /* align on cache line size */ |
120 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] | 120 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] |
121 | __attribute__((aligned(32))); | 121 | __attribute__((aligned(32))); |
122 | static unsigned char * uncached_buffer; | 122 | static unsigned char * uncached_buffer; |
123 | 123 | ||
124 | static inline void mci_delay(void) | 124 | static inline void mci_delay(void) |
125 | { | 125 | { |
126 | int i = 0xffff; | 126 | int i = 0xffff; |
127 | while (i--) | 127 | while (i--) |
128 | asm volatile ("nop\n"); | 128 | asm volatile ("nop\n"); |
129 | } | 129 | } |
@@ -146,7 +146,7 @@ static void get_regs (unsigned *regs) | |||
146 | { | 146 | { |
147 | unsigned j; | 147 | unsigned j; |
148 | volatile unsigned long *sdi_reg = &SDICON; | 148 | volatile unsigned long *sdi_reg = &SDICON; |
149 | 149 | ||
150 | for (j=0; j < 16;j++) | 150 | for (j=0; j < 16;j++) |
151 | { | 151 | { |
152 | *regs++ = *sdi_reg++; | 152 | *regs++ = *sdi_reg++; |
@@ -158,7 +158,7 @@ static void dump_regs (unsigned *regs1, unsigned *regs2) | |||
158 | unsigned j; | 158 | unsigned j; |
159 | volatile unsigned long*sdi_reg = &SDICON; | 159 | volatile unsigned long*sdi_reg = &SDICON; |
160 | unsigned long diff; | 160 | unsigned long diff; |
161 | 161 | ||
162 | for (j=0; j < 16;j++) | 162 | for (j=0; j < 16;j++) |
163 | { | 163 | { |
164 | diff = *regs1 ^ *regs2; | 164 | diff = *regs1 ^ *regs2; |
@@ -174,23 +174,23 @@ static void dump_regs (unsigned *regs1, unsigned *regs2) | |||
174 | static void debug_r1(int cmd) | 174 | static void debug_r1(int cmd) |
175 | { | 175 | { |
176 | #if defined(SD_DEBUG) | 176 | #if defined(SD_DEBUG) |
177 | dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n", | 177 | dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n", |
178 | cmd, | 178 | cmd, |
179 | SDICSTA, | 179 | SDICSTA, |
180 | (SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ', | 180 | (SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ', |
181 | (SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ', | 181 | (SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ', |
182 | (SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ', | 182 | (SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ', |
183 | (SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ', | 183 | (SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ', |
184 | (SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ', | 184 | (SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ', |
185 | 185 | ||
186 | (SDICSTA & 0x40) ? 'P' : ' ', | 186 | (SDICSTA & 0x40) ? 'P' : ' ', |
187 | (SDICSTA & 0x20) ? 'A' : ' ', | 187 | (SDICSTA & 0x20) ? 'A' : ' ', |
188 | (SDICSTA & 0x10) ? 'E' : ' ', | 188 | (SDICSTA & 0x10) ? 'E' : ' ', |
189 | (SDICSTA & 0x08) ? 'C' : ' ', | 189 | (SDICSTA & 0x08) ? 'C' : ' ', |
190 | (SDICSTA & 0x04) ? 'I' : ' ', | 190 | (SDICSTA & 0x04) ? 'I' : ' ', |
191 | (SDICSTA & 0x02) ? 'R' : ' ', | 191 | (SDICSTA & 0x02) ? 'R' : ' ', |
192 | (SDICSTA & 0x01) ? 'Z' : ' ', | 192 | (SDICSTA & 0x01) ? 'Z' : ' ', |
193 | 193 | ||
194 | SDIRSP0, | 194 | SDIRSP0, |
195 | SD_R1_CURRENT_STATE(SDIRSP0), | 195 | SD_R1_CURRENT_STATE(SDIRSP0), |
196 | (SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " " | 196 | (SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " " |
@@ -205,8 +205,8 @@ void SDI (void) | |||
205 | int status = SDIDSTA; | 205 | int status = SDIDSTA; |
206 | #ifndef HAVE_MULTIDRIVE | 206 | #ifndef HAVE_MULTIDRIVE |
207 | const int curr_card = 0; | 207 | const int curr_card = 0; |
208 | #endif | 208 | #endif |
209 | 209 | ||
210 | transfer_error[curr_card] = status | 210 | transfer_error[curr_card] = status |
211 | #if 0 | 211 | #if 0 |
212 | & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL | | 212 | & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL | |
@@ -217,7 +217,7 @@ void SDI (void) | |||
217 | SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ | 217 | SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ |
218 | 218 | ||
219 | dbgprintf ("SDI %x\n", transfer_error[curr_card]); | 219 | dbgprintf ("SDI %x\n", transfer_error[curr_card]); |
220 | 220 | ||
221 | semaphore_release(&transfer_completion_signal); | 221 | semaphore_release(&transfer_completion_signal); |
222 | 222 | ||
223 | /* Ack the interrupt */ | 223 | /* Ack the interrupt */ |
@@ -229,13 +229,13 @@ void SDI (void) | |||
229 | void dma_callback (void) | 229 | void dma_callback (void) |
230 | { | 230 | { |
231 | const int status = SDIDSTA; | 231 | const int status = SDIDSTA; |
232 | 232 | ||
233 | transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL | | 233 | transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL | |
234 | S3C2410_SDIDSTA_RXCRCFAIL | | 234 | S3C2410_SDIDSTA_RXCRCFAIL | |
235 | S3C2410_SDIDSTA_DATATIMEOUT ); | 235 | S3C2410_SDIDSTA_DATATIMEOUT ); |
236 | 236 | ||
237 | SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ | 237 | SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ |
238 | 238 | ||
239 | dbgprintf ("dma_cb\n"); | 239 | dbgprintf ("dma_cb\n"); |
240 | semaphore_release(&transfer_completion_signal); | 240 | semaphore_release(&transfer_completion_signal); |
241 | } | 241 | } |
@@ -248,14 +248,14 @@ static void init_sdi_controller(const int card_no) | |||
248 | /*****************************************************************************/ | 248 | /*****************************************************************************/ |
249 | #ifdef MINI2440 | 249 | #ifdef MINI2440 |
250 | /* Specific to Mini2440 */ | 250 | /* Specific to Mini2440 */ |
251 | 251 | ||
252 | /* Enable pullups on SDCMD and SDDAT pins */ | 252 | /* Enable pullups on SDCMD and SDDAT pins */ |
253 | S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE); | 253 | S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE); |
254 | S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE); | 254 | S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE); |
255 | S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE); | 255 | S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE); |
256 | S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE); | 256 | S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE); |
257 | S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE); | 257 | S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE); |
258 | 258 | ||
259 | /* Enable special function for SDCMD, SDCLK and SDDAT pins */ | 259 | /* Enable special function for SDCMD, SDCLK and SDDAT pins */ |
260 | S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION); | 260 | S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION); |
261 | S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION); | 261 | S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION); |
@@ -263,15 +263,15 @@ static void init_sdi_controller(const int card_no) | |||
263 | S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION); | 263 | S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION); |
264 | S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION); | 264 | S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION); |
265 | S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION); | 265 | S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION); |
266 | 266 | ||
267 | /* Card Detect input */ | 267 | /* Card Detect input */ |
268 | S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT); | 268 | S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT); |
269 | /* enable external irq 8-23 on the internal interrupt controller */ | 269 | /* enable external irq 8-23 on the internal interrupt controller */ |
270 | INTMSK &= ~1<<5; | 270 | INTMSK &= ~1<<5; |
271 | /* enable GPG8 IRQ on the external interrupt controller */ | 271 | /* enable GPG8 IRQ on the external interrupt controller */ |
272 | EINTMASK &= ~(1<<16); | 272 | EINTMASK &= ~(1<<16); |
273 | 273 | ||
274 | 274 | ||
275 | /* Write Protect input */ | 275 | /* Write Protect input */ |
276 | S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT); | 276 | S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT); |
277 | /*****************************************************************************/ | 277 | /*****************************************************************************/ |
@@ -279,11 +279,11 @@ static void init_sdi_controller(const int card_no) | |||
279 | #error Unsupported target | 279 | #error Unsupported target |
280 | #endif | 280 | #endif |
281 | /*****************************************************************************/ | 281 | /*****************************************************************************/ |
282 | 282 | ||
283 | /* About 400KHz for initial comms with card */ | 283 | /* About 400KHz for initial comms with card */ |
284 | SDIPRE = PCLK / INITIAL_CLK - 1; | 284 | SDIPRE = PCLK / INITIAL_CLK - 1; |
285 | /* Byte order=Type A (Little Endian), clock enable */ | 285 | /* Byte order=Type A (Little Endian), clock enable */ |
286 | SDICON = S3C2410_SDICON_CLOCKTYPE; | 286 | SDICON = S3C2410_SDICON_CLOCKTYPE; |
287 | SDIFSTA |= S3C2440_SDIFSTA_FIFORESET; | 287 | SDIFSTA |= S3C2440_SDIFSTA_FIFORESET; |
288 | SDIBSIZE = SD_BLOCK_SIZE; | 288 | SDIBSIZE = SD_BLOCK_SIZE; |
289 | SDIDTIMER= 0x7fffff; /* Set timeout count - max value */ | 289 | SDIDTIMER= 0x7fffff; /* Set timeout count - max value */ |
@@ -297,11 +297,11 @@ static void init_sdi_controller(const int card_no) | |||
297 | /* Enable interrupt in controller */ | 297 | /* Enable interrupt in controller */ |
298 | bitclr32(&INTMOD, SDI_MASK); | 298 | bitclr32(&INTMOD, SDI_MASK); |
299 | bitclr32(&INTMSK, SDI_MASK); | 299 | bitclr32(&INTMSK, SDI_MASK); |
300 | 300 | ||
301 | SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH | 301 | SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH |
302 | | S3C2410_SDIIMSK_DATATIMEOUT | 302 | | S3C2410_SDIIMSK_DATATIMEOUT |
303 | | S3C2410_SDIIMSK_DATACRC | 303 | | S3C2410_SDIIMSK_DATACRC |
304 | | S3C2410_SDIIMSK_CRCSTATUS | 304 | | S3C2410_SDIIMSK_CRCSTATUS |
305 | | S3C2410_SDIIMSK_FIFOFAIL | 305 | | S3C2410_SDIIMSK_FIFOFAIL |
306 | ; | 306 | ; |
307 | #endif | 307 | #endif |
@@ -325,18 +325,18 @@ static bool send_cmd(const int card_no, const int cmd, const int arg, | |||
325 | get_regs (reg_copy2); | 325 | get_regs (reg_copy2); |
326 | dump_regs (reg_copy, reg_copy2); | 326 | dump_regs (reg_copy, reg_copy2); |
327 | #endif | 327 | #endif |
328 | 328 | ||
329 | #if 0 | 329 | #if 0 |
330 | while (SDICSTA & S3C2410_SDICMDSTAT_XFERING) | 330 | while (SDICSTA & S3C2410_SDICMDSTAT_XFERING) |
331 | ; /* wait ?? */ | 331 | ; /* wait ?? */ |
332 | #endif | 332 | #endif |
333 | /* set up new command */ | 333 | /* set up new command */ |
334 | 334 | ||
335 | if (flags & MCI_ARG) | 335 | if (flags & MCI_ARG) |
336 | SDICARG = arg; | 336 | SDICARG = arg; |
337 | else | 337 | else |
338 | SDICARG = 0; | 338 | SDICARG = 0; |
339 | 339 | ||
340 | val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST; | 340 | val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST; |
341 | if(flags & MCI_RESP) | 341 | if(flags & MCI_RESP) |
342 | { | 342 | { |
@@ -344,27 +344,27 @@ static bool send_cmd(const int card_no, const int cmd, const int arg, | |||
344 | if(flags & MCI_LONG_RESP) | 344 | if(flags & MCI_LONG_RESP) |
345 | val |= S3C2410_SDICMDCON_LONGRSP; | 345 | val |= S3C2410_SDICMDCON_LONGRSP; |
346 | } | 346 | } |
347 | 347 | ||
348 | /* Clear command/data status flags */ | 348 | /* Clear command/data status flags */ |
349 | SDICSTA |= 0x0f << 9; | 349 | SDICSTA |= 0x0f << 9; |
350 | SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; | 350 | SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; |
351 | 351 | ||
352 | /* Initiate the command */ | 352 | /* Initiate the command */ |
353 | SDICCON = val; | 353 | SDICCON = val; |
354 | 354 | ||
355 | if (flags & MCI_RESP) | 355 | if (flags & MCI_RESP) |
356 | { | 356 | { |
357 | /* wait for response or timeout */ | 357 | /* wait for response or timeout */ |
358 | do | 358 | do |
359 | { | 359 | { |
360 | status = SDICSTA; | 360 | status = SDICSTA; |
361 | } while ( (status & (S3C2410_SDICMDSTAT_RSPFIN | | 361 | } while ( (status & (S3C2410_SDICMDSTAT_RSPFIN | |
362 | S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0); | 362 | S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0); |
363 | debug_r1(cmd); | 363 | debug_r1(cmd); |
364 | if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT) | 364 | if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT) |
365 | ret = false; | 365 | ret = false; |
366 | else if (status & (S3C2410_SDICMDSTAT_RSPFIN)) | 366 | else if (status & (S3C2410_SDICMDSTAT_RSPFIN)) |
367 | { | 367 | { |
368 | /* resp received */ | 368 | /* resp received */ |
369 | if(flags & MCI_LONG_RESP) | 369 | if(flags & MCI_LONG_RESP) |
370 | { | 370 | { |
@@ -381,10 +381,10 @@ static bool send_cmd(const int card_no, const int cmd, const int arg, | |||
381 | else | 381 | else |
382 | ret = true; | 382 | ret = true; |
383 | } | 383 | } |
384 | else | 384 | else |
385 | { | 385 | { |
386 | /* wait for command completion or timeout */ | 386 | /* wait for command completion or timeout */ |
387 | do | 387 | do |
388 | { | 388 | { |
389 | status = SDICSTA; | 389 | status = SDICSTA; |
390 | } while ( (status & (S3C2410_SDICMDSTAT_CMDSENT | | 390 | } while ( (status & (S3C2410_SDICMDSTAT_CMDSENT | |
@@ -395,12 +395,12 @@ static bool send_cmd(const int card_no, const int cmd, const int arg, | |||
395 | else | 395 | else |
396 | ret = true; | 396 | ret = true; |
397 | } | 397 | } |
398 | 398 | ||
399 | /* Clear Command status flags */ | 399 | /* Clear Command status flags */ |
400 | SDICSTA |= 0x0f << 9; | 400 | SDICSTA |= 0x0f << 9; |
401 | 401 | ||
402 | mci_delay(); | 402 | mci_delay(); |
403 | 403 | ||
404 | return ret; | 404 | return ret; |
405 | } | 405 | } |
406 | 406 | ||
@@ -558,7 +558,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no)) | |||
558 | const int card_no = 0; | 558 | const int card_no = 0; |
559 | #endif | 559 | #endif |
560 | (void)card_no; | 560 | (void)card_no; |
561 | 561 | ||
562 | /* not applicable */ | 562 | /* not applicable */ |
563 | dbgprintf ("sd_remov"); | 563 | dbgprintf ("sd_remov"); |
564 | return false; | 564 | return false; |
@@ -596,7 +596,7 @@ static int sd_wait_for_state(const int card_no, unsigned int state) | |||
596 | } | 596 | } |
597 | } | 597 | } |
598 | 598 | ||
599 | static int sd_transfer_sectors(int card_no, unsigned long start, | 599 | static int sd_transfer_sectors(int card_no, sector_t start, |
600 | int count, void* buf, const bool write) | 600 | int count, void* buf, const bool write) |
601 | { | 601 | { |
602 | int ret = EC_OK; | 602 | int ret = EC_OK; |
@@ -636,7 +636,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start, | |||
636 | void *dma_buf; | 636 | void *dma_buf; |
637 | const int cmd = | 637 | const int cmd = |
638 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | 638 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; |
639 | unsigned long start_addr = start; | 639 | sector_t start_addr = start; |
640 | 640 | ||
641 | dma_buf = aligned_buffer; | 641 | dma_buf = aligned_buffer; |
642 | if(transfer > UNALIGNED_NUM_SECTORS) | 642 | if(transfer > UNALIGNED_NUM_SECTORS) |
@@ -650,10 +650,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start, | |||
650 | 650 | ||
651 | /* TODO? */ | 651 | /* TODO? */ |
652 | SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET; | 652 | SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET; |
653 | SDIDCON = S3C2440_SDIDCON_DS_WORD | | 653 | SDIDCON = S3C2440_SDIDCON_DS_WORD | |
654 | S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS | | 654 | S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS | |
655 | S3C2410_SDIDCON_DMAEN | | 655 | S3C2410_SDIDCON_DMAEN | |
656 | S3C2440_SDIDCON_DATSTART | | 656 | S3C2440_SDIDCON_DATSTART | |
657 | ( transfer << 0); | 657 | ( transfer << 0); |
658 | if (write) | 658 | if (write) |
659 | SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART; | 659 | SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART; |
@@ -665,6 +665,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start, | |||
665 | INTPND = SDI_MASK; | 665 | INTPND = SDI_MASK; |
666 | 666 | ||
667 | /* Initiate read/write command */ | 667 | /* Initiate read/write command */ |
668 | // XXX 64-bit | ||
668 | if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL)) | 669 | if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL)) |
669 | { | 670 | { |
670 | ret -= 3*20; | 671 | ret -= 3*20; |
@@ -674,32 +675,32 @@ static int sd_transfer_sectors(int card_no, unsigned long start, | |||
674 | if(write) | 675 | if(write) |
675 | { | 676 | { |
676 | request.source_addr = dma_buf; | 677 | request.source_addr = dma_buf; |
677 | request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; | 678 | request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; |
678 | request.dest_addr = &SDIDAT_LLE; | 679 | request.dest_addr = &SDIDAT_LLE; |
679 | request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; | 680 | request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; |
680 | request.count = transfer * SD_BLOCK_SIZE / sizeof(long); | 681 | request.count = transfer * SD_BLOCK_SIZE / sizeof(long); |
681 | request.source_map = DMA_SRC_MAP_SDI; | 682 | request.source_map = DMA_SRC_MAP_SDI; |
682 | request.control = DCON_DMD_HS | DCON_SYNC_APB | | 683 | request.control = DCON_DMD_HS | DCON_SYNC_APB | |
683 | DCON_HW_SEL | | 684 | DCON_HW_SEL | |
684 | DCON_NO_RELOAD | DCON_DSZ_WORD; | 685 | DCON_NO_RELOAD | DCON_DSZ_WORD; |
685 | request.callback = NULL; | 686 | request.callback = NULL; |
686 | 687 | ||
687 | dma_enable_channel(0, &request); | 688 | dma_enable_channel(0, &request); |
688 | } | 689 | } |
689 | else | 690 | else |
690 | { | 691 | { |
691 | request.source_addr = &SDIDAT_LLE; | 692 | request.source_addr = &SDIDAT_LLE; |
692 | request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; | 693 | request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; |
693 | request.dest_addr = dma_buf; | 694 | request.dest_addr = dma_buf; |
694 | request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; | 695 | request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; |
695 | request.count = transfer * SD_BLOCK_SIZE / sizeof(long); | 696 | request.count = transfer * SD_BLOCK_SIZE / sizeof(long); |
696 | request.source_map = DMA_SRC_MAP_SDI; | 697 | request.source_map = DMA_SRC_MAP_SDI; |
697 | request.control = DCON_DMD_HS | DCON_SYNC_APB | | 698 | request.control = DCON_DMD_HS | DCON_SYNC_APB | |
698 | DCON_HW_SEL | | 699 | DCON_HW_SEL | |
699 | DCON_NO_RELOAD | DCON_DSZ_WORD; | 700 | DCON_NO_RELOAD | DCON_DSZ_WORD; |
700 | request.callback = NULL; | 701 | request.callback = NULL; |
701 | 702 | ||
702 | dma_enable_channel(0, &request); | 703 | dma_enable_channel(0, &request); |
703 | } | 704 | } |
704 | 705 | ||
705 | #if 0 | 706 | #if 0 |
@@ -716,12 +717,12 @@ static int sd_transfer_sectors(int card_no, unsigned long start, | |||
716 | #endif | 717 | #endif |
717 | 718 | ||
718 | semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/); | 719 | semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/); |
719 | 720 | ||
720 | /* wait for DMA to finish */ | 721 | /* wait for DMA to finish */ |
721 | while (DSTAT0 & DSTAT_STAT_BUSY) | 722 | while (DSTAT0 & DSTAT_STAT_BUSY) |
722 | ; | 723 | ; |
723 | 724 | ||
724 | #if 0 | 725 | #if 0 |
725 | status = SDIDSTA; | 726 | status = SDIDSTA; |
726 | while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0) | 727 | while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0) |
727 | { | 728 | { |
@@ -738,10 +739,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start, | |||
738 | count -= transfer; | 739 | count -= transfer; |
739 | loops = 0; /* reset errors counter */ | 740 | loops = 0; /* reset errors counter */ |
740 | } | 741 | } |
741 | else | 742 | else |
742 | { | 743 | { |
743 | dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]); | 744 | dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]); |
744 | 745 | ||
745 | if(loops++ > MAX_TRANSFER_ERRORS) | 746 | if(loops++ > MAX_TRANSFER_ERRORS) |
746 | { | 747 | { |
747 | led_flash(LED1|LED2, LED3|LED4); | 748 | led_flash(LED1|LED2, LED3|LED4); |
@@ -783,11 +784,11 @@ sd_transfer_error: | |||
783 | return ret; | 784 | return ret; |
784 | } | 785 | } |
785 | 786 | ||
786 | int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, | 787 | int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount, |
787 | void* inbuf) | 788 | void* inbuf) |
788 | { | 789 | { |
789 | int ret; | 790 | int ret; |
790 | 791 | ||
791 | #ifdef HAVE_MULTIDRIVE | 792 | #ifdef HAVE_MULTIDRIVE |
792 | dbgprintf ("sd_read %d %x %d\n", card_no, start, incount); | 793 | dbgprintf ("sd_read %d %x %d\n", card_no, start, incount); |
793 | #else | 794 | #else |
@@ -804,7 +805,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, | |||
804 | } | 805 | } |
805 | 806 | ||
806 | /*****************************************************************************/ | 807 | /*****************************************************************************/ |
807 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 808 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, |
808 | const void* outbuf) | 809 | const void* outbuf) |
809 | { | 810 | { |
810 | #ifdef BOOTLOADER /* we don't need write support in bootloader */ | 811 | #ifdef BOOTLOADER /* we don't need write support in bootloader */ |
@@ -835,7 +836,7 @@ void sd_enable(bool on) | |||
835 | { | 836 | { |
836 | dbgprintf ("sd_enable %d\n", on); | 837 | dbgprintf ("sd_enable %d\n", on); |
837 | /* TODO: enable/disable SDI clock */ | 838 | /* TODO: enable/disable SDI clock */ |
838 | 839 | ||
839 | if (sd_enabled == on) | 840 | if (sd_enabled == on) |
840 | return; /* nothing to do */ | 841 | return; /* nothing to do */ |
841 | if (on) | 842 | if (on) |
@@ -847,14 +848,14 @@ void sd_enable(bool on) | |||
847 | sd_enabled = false; | 848 | sd_enabled = false; |
848 | } | 849 | } |
849 | } | 850 | } |
850 | 851 | ||
851 | int sd_init(void) | 852 | int sd_init(void) |
852 | { | 853 | { |
853 | int ret = EC_OK; | 854 | int ret = EC_OK; |
854 | dbgprintf ("\n==============================\n"); | 855 | dbgprintf ("\n==============================\n"); |
855 | dbgprintf (" sd_init\n"); | 856 | dbgprintf (" sd_init\n"); |
856 | dbgprintf ("==============================\n"); | 857 | dbgprintf ("==============================\n"); |
857 | 858 | ||
858 | init_sdi_controller (0); | 859 | init_sdi_controller (0); |
859 | #ifndef BOOTLOADER | 860 | #ifndef BOOTLOADER |
860 | sd_enabled = true; | 861 | sd_enabled = true; |
@@ -893,7 +894,7 @@ long sd_last_disk_activity(void) | |||
893 | } | 894 | } |
894 | 895 | ||
895 | tCardInfo *card_get_info_target(int card_no) | 896 | tCardInfo *card_get_info_target(int card_no) |
896 | { | 897 | { |
897 | return &card_info[card_no]; | 898 | return &card_info[card_no]; |
898 | } | 899 | } |
899 | 900 | ||
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c index 7f68b82a0d..34a1c46043 100644 --- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c +++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c | |||
@@ -29,17 +29,17 @@ | |||
29 | #include "ftl-target.h" | 29 | #include "ftl-target.h" |
30 | #include "nand-target.h" | 30 | #include "nand-target.h" |
31 | 31 | ||
32 | /** static, private data **/ | 32 | /** static, private data **/ |
33 | static bool initialized = false; | 33 | static bool initialized = false; |
34 | 34 | ||
35 | /* API Functions */ | 35 | /* API Functions */ |
36 | int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | 36 | int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount, |
37 | void* inbuf) | 37 | void* inbuf) |
38 | { | 38 | { |
39 | return ftl_read(start, incount, inbuf); | 39 | return ftl_read(start, incount, inbuf); |
40 | } | 40 | } |
41 | 41 | ||
42 | int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 42 | int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, |
43 | const void* outbuf) | 43 | const void* outbuf) |
44 | { | 44 | { |
45 | return ftl_write(start, count, outbuf); | 45 | return ftl_write(start, count, outbuf); |
@@ -106,7 +106,7 @@ int nand_num_drives(int first_drive) | |||
106 | { | 106 | { |
107 | /* We don't care which logical drive number(s) we have been assigned */ | 107 | /* We don't care which logical drive number(s) we have been assigned */ |
108 | (void)first_drive; | 108 | (void)first_drive; |
109 | 109 | ||
110 | return 1; | 110 | return 1; |
111 | } | 111 | } |
112 | #endif | 112 | #endif |
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c index 0d831a7167..7071d411b5 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | |||
@@ -186,7 +186,6 @@ struct ftl_cxt_type | |||
186 | There is one of these per bank. */ | 186 | There is one of these per bank. */ |
187 | struct ftl_vfl_cxt_type | 187 | struct ftl_vfl_cxt_type |
188 | { | 188 | { |
189 | |||
190 | /* Cross-bank update sequence number, incremented on every VFL | 189 | /* Cross-bank update sequence number, incremented on every VFL |
191 | context commit on any bank. */ | 190 | context commit on any bank. */ |
192 | uint32_t usn; | 191 | uint32_t usn; |
@@ -525,18 +524,24 @@ static uint32_t ftl_vfl_verify_checksum(uint32_t bank) | |||
525 | return 1; | 524 | return 1; |
526 | } | 525 | } |
527 | 526 | ||
528 | |||
529 | #ifndef FTL_READONLY | 527 | #ifndef FTL_READONLY |
528 | |||
529 | #if __GNUC__ >= 9 | ||
530 | #pragma GCC diagnostic push | ||
531 | #pragma GCC diagnostic ignored "-Waddress-of-packed-member" | ||
532 | #endif | ||
533 | |||
530 | /* Updates the checksums of the VFL context of the specified bank */ | 534 | /* Updates the checksums of the VFL context of the specified bank */ |
531 | static void ftl_vfl_update_checksum(uint32_t bank) | 535 | static void ftl_vfl_update_checksum(uint32_t bank) |
532 | { | 536 | { |
533 | ftl_vfl_calculate_checksum(bank, &ftl_vfl_cxt[bank].checksum1, | 537 | ftl_vfl_calculate_checksum(bank, &ftl_vfl_cxt[bank].checksum1, |
534 | &ftl_vfl_cxt[bank].checksum2); | 538 | &ftl_vfl_cxt[bank].checksum2); |
535 | } | 539 | } |
536 | #endif | ||
537 | 540 | ||
541 | #if __GNUC__ >= 9 | ||
542 | #pragma GCC diagnostic pop | ||
543 | #endif | ||
538 | 544 | ||
539 | #ifndef FTL_READONLY | ||
540 | /* Writes 8 copies of the VFL context of the specified bank to flash, | 545 | /* Writes 8 copies of the VFL context of the specified bank to flash, |
541 | and succeeds if at least 4 can be read back properly. */ | 546 | and succeeds if at least 4 can be read back properly. */ |
542 | static uint32_t ftl_vfl_store_cxt(uint32_t bank) | 547 | static uint32_t ftl_vfl_store_cxt(uint32_t bank) |
@@ -2107,7 +2112,7 @@ uint32_t ftl_sync(void) | |||
2107 | if (ftl_cxt.clean_flag == 1) return 0; | 2112 | if (ftl_cxt.clean_flag == 1) return 0; |
2108 | 2113 | ||
2109 | mutex_lock(&ftl_mtx); | 2114 | mutex_lock(&ftl_mtx); |
2110 | 2115 | ||
2111 | #ifdef FTL_TRACE | 2116 | #ifdef FTL_TRACE |
2112 | DEBUGF("FTL: Syncing\n"); | 2117 | DEBUGF("FTL: Syncing\n"); |
2113 | #endif | 2118 | #endif |
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c index 7a3be20577..8cc5b44aca 100644 --- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | |||
@@ -29,6 +29,9 @@ | |||
29 | #include "mmcdefs-target.h" | 29 | #include "mmcdefs-target.h" |
30 | #include "s5l8702.h" | 30 | #include "s5l8702.h" |
31 | #include "led.h" | 31 | #include "led.h" |
32 | #include "debug.h" | ||
33 | #include "panic.h" | ||
34 | #include "fs_defines.h" | ||
32 | 35 | ||
33 | #ifndef ATA_RETRIES | 36 | #ifndef ATA_RETRIES |
34 | #define ATA_RETRIES 3 | 37 | #define ATA_RETRIES 3 |
@@ -58,10 +61,9 @@ | |||
58 | #define CEATA_DAT_NONBUSY_TIMEOUT 5000000 | 61 | #define CEATA_DAT_NONBUSY_TIMEOUT 5000000 |
59 | #define CEATA_MMC_RCA 1 | 62 | #define CEATA_MMC_RCA 1 |
60 | 63 | ||
61 | |||
62 | /** static, private data **/ | 64 | /** static, private data **/ |
63 | static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; | 65 | static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; |
64 | static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR; | 66 | static uint16_t identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR; |
65 | static bool ceata; | 67 | static bool ceata; |
66 | static bool ata_lba48; | 68 | static bool ata_lba48; |
67 | static bool ata_dma; | 69 | static bool ata_dma; |
@@ -70,18 +72,18 @@ static struct mutex ata_mutex; | |||
70 | static struct semaphore ata_wakeup; | 72 | static struct semaphore ata_wakeup; |
71 | static uint32_t ata_dma_flags; | 73 | static uint32_t ata_dma_flags; |
72 | static long ata_last_activity_value = -1; | 74 | static long ata_last_activity_value = -1; |
73 | static long ata_sleep_timeout = 20 * HZ; | 75 | static long ata_sleep_timeout = 7 * HZ; |
74 | static bool ata_powered; | 76 | static bool ata_powered; |
75 | static const int ata_retries = ATA_RETRIES; | 77 | static bool canflush = true; |
76 | static const bool ata_error_srst = true; | ||
77 | static struct semaphore mmc_wakeup; | 78 | static struct semaphore mmc_wakeup; |
78 | static struct semaphore mmc_comp_wakeup; | 79 | static struct semaphore mmc_comp_wakeup; |
79 | static int spinup_time = 0; | 80 | static int spinup_time = 0; |
80 | static int dma_mode = 0; | 81 | static int dma_mode = 0; |
81 | static char aligned_buffer[SECTOR_SIZE] STORAGE_ALIGN_ATTR; | ||
82 | 82 | ||
83 | static int ata_reset(void); | 83 | static const int ata_retries = ATA_RETRIES; |
84 | static const bool ata_error_srst = true; | ||
84 | 85 | ||
86 | static int ata_reset(void); | ||
85 | 87 | ||
86 | static uint16_t ata_read_cbr(uint32_t volatile* reg) | 88 | static uint16_t ata_read_cbr(uint32_t volatile* reg) |
87 | { | 89 | { |
@@ -103,8 +105,10 @@ static int ata_wait_for_not_bsy(long timeout) | |||
103 | while (true) | 105 | while (true) |
104 | { | 106 | { |
105 | uint8_t csd = ata_read_cbr(&ATA_PIO_CSD); | 107 | uint8_t csd = ata_read_cbr(&ATA_PIO_CSD); |
106 | if (!(csd & BIT(7))) return 0; | 108 | if (!(csd & BIT(7))) |
107 | if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0); | 109 | return 0; |
110 | if (TIMEOUT_EXPIRED(startusec, timeout)) | ||
111 | RET_ERR(0); | ||
108 | yield(); | 112 | yield(); |
109 | } | 113 | } |
110 | } | 114 | } |
@@ -116,8 +120,10 @@ static int ata_wait_for_rdy(long timeout) | |||
116 | while (true) | 120 | while (true) |
117 | { | 121 | { |
118 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); | 122 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); |
119 | if (dad & BIT(6)) return 0; | 123 | if (dad & BIT(6)) |
120 | if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1); | 124 | return 0; |
125 | if (TIMEOUT_EXPIRED(startusec, timeout)) | ||
126 | RET_ERR(1); | ||
121 | yield(); | 127 | yield(); |
122 | } | 128 | } |
123 | } | 129 | } |
@@ -129,9 +135,12 @@ static int ata_wait_for_start_of_transfer(long timeout) | |||
129 | while (true) | 135 | while (true) |
130 | { | 136 | { |
131 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); | 137 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); |
132 | if (dad & BIT(0)) RET_ERR(1); | 138 | if (dad & BIT(0)) |
133 | if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0; | 139 | RET_ERR(1); |
134 | if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2); | 140 | if ((dad & (BIT(7) | BIT(3))) == BIT(3)) |
141 | return 0; | ||
142 | if (TIMEOUT_EXPIRED(startusec, timeout)) | ||
143 | RET_ERR(2); | ||
135 | yield(); | 144 | yield(); |
136 | } | 145 | } |
137 | } | 146 | } |
@@ -140,8 +149,10 @@ static int ata_wait_for_end_of_transfer(long timeout) | |||
140 | { | 149 | { |
141 | PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0); | 150 | PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0); |
142 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); | 151 | uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); |
143 | if (dad & BIT(0)) RET_ERR(1); | 152 | if (dad & BIT(0)) |
144 | if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0; | 153 | RET_ERR(1); |
154 | if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) | ||
155 | return 0; | ||
145 | RET_ERR(2); | 156 | RET_ERR(2); |
146 | } | 157 | } |
147 | 158 | ||
@@ -149,13 +160,17 @@ static int mmc_dsta_check_command_success(bool disable_crc) | |||
149 | { | 160 | { |
150 | int rc = 0; | 161 | int rc = 0; |
151 | uint32_t dsta = SDCI_DSTA; | 162 | uint32_t dsta = SDCI_DSTA; |
152 | if (dsta & SDCI_DSTA_RESTOUTE) rc |= 1; | 163 | if (dsta & SDCI_DSTA_RESTOUTE) |
153 | if (dsta & SDCI_DSTA_RESENDE) rc |= 2; | 164 | rc |= 1; |
154 | if (dsta & SDCI_DSTA_RESINDE) rc |= 4; | 165 | if (dsta & SDCI_DSTA_RESENDE) |
166 | rc |= 2; | ||
167 | if (dsta & SDCI_DSTA_RESINDE) | ||
168 | rc |= 4; | ||
155 | if (!disable_crc) | 169 | if (!disable_crc) |
156 | if (dsta & SDCI_DSTA_RESCRCE) | 170 | if (dsta & SDCI_DSTA_RESCRCE) |
157 | rc |= 8; | 171 | rc |= 8; |
158 | if (rc) RET_ERR(rc); | 172 | if (rc) |
173 | RET_ERR(rc); | ||
159 | return 0; | 174 | return 0; |
160 | } | 175 | } |
161 | 176 | ||
@@ -164,7 +179,8 @@ static bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int t | |||
164 | long starttime = USEC_TIMER; | 179 | long starttime = USEC_TIMER; |
165 | while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE) | 180 | while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE) |
166 | { | 181 | { |
167 | if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(0); | 182 | if (TIMEOUT_EXPIRED(starttime, timeout)) |
183 | RET_ERR(0); | ||
168 | yield(); | 184 | yield(); |
169 | } | 185 | } |
170 | SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3 | 186 | SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3 |
@@ -179,32 +195,38 @@ static bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int t | |||
179 | | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7; | 195 | | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7; |
180 | SDCI_ARGU = arg; | 196 | SDCI_ARGU = arg; |
181 | SDCI_CMD = cmd; | 197 | SDCI_CMD = cmd; |
182 | if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) RET_ERR(1); | 198 | if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) |
199 | RET_ERR(1); | ||
183 | SDCI_CMD = cmd | SDCI_CMD_CMDSTR; | 200 | SDCI_CMD = cmd | SDCI_CMD_CMDSTR; |
184 | long sleepbase = USEC_TIMER; | 201 | long sleepbase = USEC_TIMER; |
185 | while (TIMEOUT_EXPIRED(sleepbase, 1000)) yield(); | 202 | while (TIMEOUT_EXPIRED(sleepbase, 1000)) |
203 | yield(); | ||
186 | while (!(SDCI_DSTA & SDCI_DSTA_CMDEND)) | 204 | while (!(SDCI_DSTA & SDCI_DSTA_CMDEND)) |
187 | { | 205 | { |
188 | if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(2); | 206 | if (TIMEOUT_EXPIRED(starttime, timeout)) |
207 | RET_ERR(2); | ||
189 | yield(); | 208 | yield(); |
190 | } | 209 | } |
191 | if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE) | 210 | if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE) |
192 | { | 211 | { |
193 | while (!(SDCI_DSTA & SDCI_DSTA_RESEND)) | 212 | while (!(SDCI_DSTA & SDCI_DSTA_RESEND)) |
194 | { | 213 | { |
195 | if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(3); | 214 | if (TIMEOUT_EXPIRED(starttime, timeout)) |
215 | RET_ERR(3); | ||
196 | yield(); | 216 | yield(); |
197 | } | 217 | } |
198 | if (cmd & SDCI_CMD_RES_BUSY) | 218 | if (cmd & SDCI_CMD_RES_BUSY) |
199 | while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY) | 219 | while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY) |
200 | { | 220 | { |
201 | if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(4); | 221 | if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) |
222 | RET_ERR(4); | ||
202 | yield(); | 223 | yield(); |
203 | } | 224 | } |
204 | } | 225 | } |
205 | bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136; | 226 | bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136; |
206 | PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5); | 227 | PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5); |
207 | if (result) *result = SDCI_RESP0; | 228 | if (result) |
229 | *result = SDCI_RESP0; | ||
208 | return 0; | 230 | return 0; |
209 | } | 231 | } |
210 | 232 | ||
@@ -227,7 +249,8 @@ static int mmc_init(void) | |||
227 | uint32_t result; | 249 | uint32_t result; |
228 | do | 250 | do |
229 | { | 251 | { |
230 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(1); | 252 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) |
253 | RET_ERR(1); | ||
231 | sleep(HZ / 100); | 254 | sleep(HZ / 100); |
232 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND) | 255 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND) |
233 | | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3 | 256 | | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3 |
@@ -252,7 +275,8 @@ static int mmc_init(void) | |||
252 | MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA), | 275 | MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA), |
253 | NULL, CEATA_COMMAND_TIMEOUT), 3, 5); | 276 | NULL, CEATA_COMMAND_TIMEOUT), 3, 5); |
254 | PASS_RC(mmc_get_card_status(&result), 3, 6); | 277 | PASS_RC(mmc_get_card_status(&result), 3, 6); |
255 | if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) RET_ERR(7); | 278 | if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) |
279 | RET_ERR(7); | ||
256 | return 0; | 280 | return 0; |
257 | } | 281 | } |
258 | 282 | ||
@@ -286,7 +310,8 @@ static int ceata_soft_reset(void) | |||
286 | do | 310 | do |
287 | { | 311 | { |
288 | PASS_RC(mmc_fastio_read(0xf, &status), 2, 2); | 312 | PASS_RC(mmc_fastio_read(0xf, &status), 2, 2); |
289 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(3); | 313 | if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) |
314 | RET_ERR(3); | ||
290 | sleep(HZ / 100); | 315 | sleep(HZ / 100); |
291 | } | 316 | } |
292 | while (status & 0x80); | 317 | while (status & 0x80); |
@@ -299,16 +324,21 @@ static int mmc_dsta_check_data_success(void) | |||
299 | uint32_t dsta = SDCI_DSTA; | 324 | uint32_t dsta = SDCI_DSTA; |
300 | if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE)) | 325 | if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE)) |
301 | { | 326 | { |
302 | if (dsta & SDCI_DSTA_WR_DATCRCE) rc |= 1; | 327 | if (dsta & SDCI_DSTA_WR_DATCRCE) |
303 | if (dsta & SDCI_DSTA_RD_DATCRCE) rc |= 2; | 328 | rc |= 1; |
304 | if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) rc |= 4; | 329 | if (dsta & SDCI_DSTA_RD_DATCRCE) |
305 | else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) rc |= 8; | 330 | rc |= 2; |
331 | if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) | ||
332 | rc |= 4; | ||
333 | else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) | ||
334 | rc |= 8; | ||
306 | } | 335 | } |
307 | if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2 | 336 | if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2 |
308 | | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5 | 337 | | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5 |
309 | | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7)) | 338 | | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7)) |
310 | rc |= 16; | 339 | rc |= 16; |
311 | if (rc) RET_ERR(rc); | 340 | if (rc) |
341 | RET_ERR(rc); | ||
312 | return 0; | 342 | return 0; |
313 | } | 343 | } |
314 | 344 | ||
@@ -321,7 +351,8 @@ static void mmc_discard_irq(void) | |||
321 | 351 | ||
322 | static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) | 352 | static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) |
323 | { | 353 | { |
324 | if (size > 0x10) RET_ERR(0); | 354 | if (size > 0x10) |
355 | RET_ERR(0); | ||
325 | mmc_discard_irq(); | 356 | mmc_discard_irq(); |
326 | SDCI_DMASIZE = size; | 357 | SDCI_DMASIZE = size; |
327 | SDCI_DMACOUNT = 1; | 358 | SDCI_DMACOUNT = 1; |
@@ -335,8 +366,8 @@ static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size | |||
335 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) | 366 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) |
336 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), | 367 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), |
337 | NULL, CEATA_COMMAND_TIMEOUT), 2, 1); | 368 | NULL, CEATA_COMMAND_TIMEOUT), 2, 1); |
338 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) | 369 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) |
339 | == OBJ_WAIT_TIMEDOUT) RET_ERR(2); | 370 | RET_ERR(2); |
340 | PASS_RC(mmc_dsta_check_data_success(), 2, 3); | 371 | PASS_RC(mmc_dsta_check_data_success(), 2, 3); |
341 | return 0; | 372 | return 0; |
342 | } | 373 | } |
@@ -344,7 +375,8 @@ static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size | |||
344 | static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size) | 375 | static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size) |
345 | { | 376 | { |
346 | uint32_t i; | 377 | uint32_t i; |
347 | if (size > 0x10) RET_ERR(0); | 378 | if (size > 0x10) |
379 | RET_ERR(0); | ||
348 | mmc_discard_irq(); | 380 | mmc_discard_irq(); |
349 | SDCI_DMASIZE = size; | 381 | SDCI_DMASIZE = size; |
350 | SDCI_DMACOUNT = 0; | 382 | SDCI_DMACOUNT = 0; |
@@ -358,13 +390,15 @@ static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t siz | |||
358 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), | 390 | | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), |
359 | NULL, CEATA_COMMAND_TIMEOUT), 3, 1); | 391 | NULL, CEATA_COMMAND_TIMEOUT), 3, 1); |
360 | SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | 392 | SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; |
361 | for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i]; | 393 | for (i = 0; i < size / 4; i++) |
394 | SDCI_DATA = ((uint32_t*)dest)[i]; | ||
362 | long startusec = USEC_TIMER; | 395 | long startusec = USEC_TIMER; |
363 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) | 396 | if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) |
364 | == OBJ_WAIT_TIMEDOUT) RET_ERR(2); | 397 | RET_ERR(2); |
365 | while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE) | 398 | while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE) |
366 | { | 399 | { |
367 | if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3); | 400 | if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) |
401 | RET_ERR(3); | ||
368 | yield(); | 402 | yield(); |
369 | } | 403 | } |
370 | PASS_RC(mmc_dsta_check_data_success(), 3, 4); | 404 | PASS_RC(mmc_dsta_check_data_success(), 3, 4); |
@@ -381,13 +415,17 @@ static int ceata_init(int buswidth) | |||
381 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING) | 415 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING) |
382 | | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED), | 416 | | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED), |
383 | &result, CEATA_COMMAND_TIMEOUT), 3, 0); | 417 | &result, CEATA_COMMAND_TIMEOUT), 3, 0); |
384 | if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(1); | 418 | if (result & MMC_STATUS_SWITCH_ERROR) |
419 | RET_ERR(1); | ||
385 | if (buswidth > 1) | 420 | if (buswidth > 1) |
386 | { | 421 | { |
387 | int setting; | 422 | int setting; |
388 | if (buswidth == 4) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT; | 423 | if (buswidth == 4) |
389 | else if (buswidth == 8) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT; | 424 | setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT; |
390 | else setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT; | 425 | else if (buswidth == 8) |
426 | setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT; | ||
427 | else | ||
428 | setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT; | ||
391 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY | 429 | PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY |
392 | | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 | 430 | | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 |
393 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, | 431 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, |
@@ -395,7 +433,8 @@ static int ceata_init(int buswidth) | |||
395 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH) | 433 | | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH) |
396 | | MMC_CMD_SWITCH_VALUE(setting), | 434 | | MMC_CMD_SWITCH_VALUE(setting), |
397 | &result, CEATA_COMMAND_TIMEOUT), 3, 2); | 435 | &result, CEATA_COMMAND_TIMEOUT), 3, 2); |
398 | if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(3); | 436 | if (result & MMC_STATUS_SWITCH_ERROR) |
437 | RET_ERR(3); | ||
399 | if (buswidth == 4) | 438 | if (buswidth == 4) |
400 | SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT; | 439 | SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT; |
401 | else if (buswidth == 8) | 440 | else if (buswidth == 8) |
@@ -403,7 +442,8 @@ static int ceata_init(int buswidth) | |||
403 | } | 442 | } |
404 | PASS_RC(ceata_soft_reset(), 3, 4); | 443 | PASS_RC(ceata_soft_reset(), 3, 4); |
405 | PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5); | 444 | PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5); |
406 | if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) RET_ERR(6); | 445 | if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) |
446 | RET_ERR(6); | ||
407 | PASS_RC(mmc_fastio_write(6, 0), 3, 7); | 447 | PASS_RC(mmc_fastio_write(6, 0), 3, 7); |
408 | return 0; | 448 | return 0; |
409 | } | 449 | } |
@@ -427,8 +467,10 @@ static int ceata_wait_idle(void) | |||
427 | { | 467 | { |
428 | uint32_t status; | 468 | uint32_t status; |
429 | PASS_RC(mmc_fastio_read(0xf, &status), 1, 0); | 469 | PASS_RC(mmc_fastio_read(0xf, &status), 1, 0); |
430 | if (!(status & 0x88)) return 0; | 470 | if (!(status & 0x88)) |
431 | if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(1); | 471 | return 0; |
472 | if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) | ||
473 | RET_ERR(1); | ||
432 | sleep(HZ / 20); | 474 | sleep(HZ / 20); |
433 | } | 475 | } |
434 | } | 476 | } |
@@ -477,7 +519,8 @@ static int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long t | |||
477 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, | 519 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, |
478 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), | 520 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), |
479 | NULL, CEATA_COMMAND_TIMEOUT), 3, 0); | 521 | NULL, CEATA_COMMAND_TIMEOUT), 3, 0); |
480 | if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | 522 | if (write) |
523 | SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; | ||
481 | if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) | 524 | if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) |
482 | { | 525 | { |
483 | PASS_RC(ceata_cancel_command(), 3, 1); | 526 | PASS_RC(ceata_cancel_command(), 3, 1); |
@@ -510,7 +553,8 @@ static int ata_identify(uint16_t* buf) | |||
510 | ata_write_cbr(&ATA_PIO_DVR, 0); | 553 | ata_write_cbr(&ATA_PIO_DVR, 0); |
511 | ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); | 554 | ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); |
512 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); | 555 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); |
513 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); | 556 | for (i = 0; i < ATA_IDENTIFY_WORDS; i++) |
557 | buf[i] = ata_read_cbr(&ATA_PIO_DTR); | ||
514 | } | 558 | } |
515 | return 0; | 559 | return 0; |
516 | } | 560 | } |
@@ -549,6 +593,41 @@ static int ata_set_feature(uint32_t feature, uint32_t param) | |||
549 | return 0; | 593 | return 0; |
550 | } | 594 | } |
551 | 595 | ||
596 | #ifdef HAVE_ATA_DMA | ||
597 | static int udmatimes[ATA_MAX_UDMA + 1] = { | ||
598 | 0x4071152, | ||
599 | 0x2050d52, | ||
600 | #if ATA_MAX_UDMA >= 2 | ||
601 | 0x2030a52, | ||
602 | #endif | ||
603 | #if ATA_MAX_UDMA >= 3 | ||
604 | 0x1020a52, | ||
605 | #endif | ||
606 | #if ATA_MAX_UDMA >= 4 | ||
607 | 0x1010a52, | ||
608 | #endif | ||
609 | }; | ||
610 | static int mwdmatimes[ATA_MAX_MWDMA + 1] = { | ||
611 | 0x1c175, | ||
612 | 0x7083, | ||
613 | 0x5072, | ||
614 | }; | ||
615 | |||
616 | static int ata_get_best_mode(unsigned short identword, int max, int modetype) | ||
617 | { | ||
618 | unsigned short testbit = BIT_N(max); | ||
619 | |||
620 | while (1) { | ||
621 | if (identword & testbit) | ||
622 | return max | modetype; | ||
623 | testbit >>= 1; | ||
624 | if (!testbit) | ||
625 | return 0; | ||
626 | max--; | ||
627 | } | ||
628 | } | ||
629 | #endif | ||
630 | |||
552 | /* | 631 | /* |
553 | * ATA_UDMA_TIME register is documented on s3c6400 datasheet, information | 632 | * ATA_UDMA_TIME register is documented on s3c6400 datasheet, information |
554 | * included in s5l8700 datasheet is wrong or not valid for s5l8702. | 633 | * included in s5l8700 datasheet is wrong or not valid for s5l8702. |
@@ -573,10 +652,10 @@ static int ata_power_up(void) | |||
573 | ata_set_active(); | 652 | ata_set_active(); |
574 | ide_power_enable(true); | 653 | ide_power_enable(true); |
575 | long spinup_start = current_tick; | 654 | long spinup_start = current_tick; |
576 | if (ceata) | 655 | if (ceata) { |
577 | { | ||
578 | ata_lba48 = true; | 656 | ata_lba48 = true; |
579 | ata_dma = true; | 657 | ata_dma = true; |
658 | dma_mode = 0xff; /* Canary */ | ||
580 | PCON(8) = 0x33333333; | 659 | PCON(8) = 0x33333333; |
581 | PCON(9) = 0x00000033; | 660 | PCON(9) = 0x00000033; |
582 | PCON(11) |= 0xf; | 661 | PCON(11) |= 0xf; |
@@ -596,11 +675,8 @@ static int ata_power_up(void) | |||
596 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); | 675 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); |
597 | sleep(HZ / 100); | 676 | sleep(HZ / 100); |
598 | PASS_RC(ceata_init(8), 3, 1); | 677 | PASS_RC(ceata_init(8), 3, 1); |
599 | PASS_RC(ata_identify(ata_identify_data), 3, 2); | 678 | PASS_RC(ata_identify(identify_info), 3, 2); |
600 | dma_mode = 0x44; | 679 | } else { |
601 | } | ||
602 | else | ||
603 | { | ||
604 | PCON(7) = 0x44444444; | 680 | PCON(7) = 0x44444444; |
605 | PCON(8) = 0x44444444; | 681 | PCON(8) = 0x44444444; |
606 | PCON(9) = 0x44444444; | 682 | PCON(9) = 0x44444444; |
@@ -620,88 +696,71 @@ static int ata_power_up(void) | |||
620 | ATA_PIO_LHR = 0; | 696 | ATA_PIO_LHR = 0; |
621 | ATA_CFG = BIT(6); | 697 | ATA_CFG = BIT(6); |
622 | while (!(ATA_PIO_READY & BIT(1))) yield(); | 698 | while (!(ATA_PIO_READY & BIT(1))) yield(); |
623 | PASS_RC(ata_identify(ata_identify_data), 3, 3); | 699 | |
624 | uint32_t piotime = 0x11f3; | 700 | PASS_RC(ata_identify(identify_info), 3, 3); |
625 | uint32_t mdmatime = 0x1c175; | 701 | |
626 | uint32_t udmatime = 0x4071152; | 702 | uint32_t piotime = 0x11f3; /* PIO0-2? */ |
627 | uint32_t param = 0; | 703 | if (identify_info[53] & BIT(1)) /* Word 64..70 valid */ |
628 | ata_dma_flags = 0; | ||
629 | ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false; | ||
630 | if (ata_identify_data[53] & BIT(1)) | ||
631 | { | ||
632 | if (ata_identify_data[64] & BIT(1)) piotime = 0x2072; | ||
633 | else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083; | ||
634 | } | ||
635 | if (ata_identify_data[63] & BIT(2)) | ||
636 | { | 704 | { |
637 | mdmatime = 0x5072; | 705 | if (identify_info[64] & BIT(1)) |
638 | param = 0x22; | 706 | piotime = 0x2072; /* PIO mode 4 */ |
707 | else if (identify_info[64] & BIT(0)) | ||
708 | piotime = 0x7083; /* PIO mode 3 */ | ||
639 | } | 709 | } |
640 | else if (ata_identify_data[63] & BIT(1)) | 710 | ATA_PIO_TIME = piotime; |
711 | |||
712 | uint32_t param = 0; | ||
713 | ata_dma_flags = 0; | ||
714 | #ifdef HAVE_ATA_DMA | ||
715 | if ((identify_info[53] & BIT(2)) && (identify_info[88] & BITRANGE(0, 4))) /* Any UDMA */ | ||
641 | { | 716 | { |
642 | mdmatime = 0x7083; | 717 | int max_udma = ATA_MAX_UDMA; |
643 | param = 0x21; | 718 | #if ATA_MAX_UDMA > 2 |
719 | if (!(identify_info[93] & BIT(13))) | ||
720 | max_udma = 2; | ||
721 | #endif | ||
722 | param = ata_get_best_mode(identify_info[88], max_udma, 0x40); | ||
723 | ATA_UDMA_TIME = udmatimes[param & 0xf]; | ||
724 | ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10); | ||
644 | } | 725 | } |
645 | if (ata_identify_data[63] & BITRANGE(0, 2)) | 726 | if (!param && identify_info[63] & BITRANGE(0, 2)) /* Fall back to any MWDMA */ |
646 | { | 727 | { |
728 | param = ata_get_best_mode(identify_info[63], ATA_MAX_MWDMA, 0x20); | ||
729 | ATA_MDMA_TIME = mwdmatimes[param & 0xf]; | ||
647 | ata_dma_flags = BIT(3) | BIT(10); | 730 | ata_dma_flags = BIT(3) | BIT(10); |
648 | param |= 0x20; | ||
649 | } | ||
650 | if (ata_identify_data[53] & BIT(2)) | ||
651 | { | ||
652 | if (ata_identify_data[88] & BIT(4)) | ||
653 | { | ||
654 | udmatime = 0x1010a52; | ||
655 | param = 0x44; | ||
656 | } | ||
657 | else if (ata_identify_data[88] & BIT(3)) | ||
658 | { | ||
659 | udmatime = 0x1020a52; | ||
660 | param = 0x43; | ||
661 | } | ||
662 | else if (ata_identify_data[88] & BIT(2)) | ||
663 | { | ||
664 | udmatime = 0x2030a52; | ||
665 | param = 0x42; | ||
666 | } | ||
667 | else if (ata_identify_data[88] & BIT(1)) | ||
668 | { | ||
669 | udmatime = 0x2050d52; | ||
670 | param = 0x41; | ||
671 | } | ||
672 | else if (ata_identify_data[88] & BIT(0)) | ||
673 | { | ||
674 | param = 0x40; | ||
675 | } | ||
676 | if (ata_identify_data[88] & BITRANGE(0, 4)) | ||
677 | { | ||
678 | ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10); | ||
679 | } | ||
680 | } | 731 | } |
732 | #endif /* HAVE_ATA_DMA */ | ||
681 | ata_dma = param ? true : false; | 733 | ata_dma = param ? true : false; |
682 | dma_mode = param; | 734 | dma_mode = param; |
683 | PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ | 735 | PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ |
684 | if (ata_identify_data[82] & BIT(5)) | 736 | |
737 | /* SET_FEATURE only supported on PATA, not CE-ATA */ | ||
738 | if (identify_info[82] & BIT(5)) | ||
685 | PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ | 739 | PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ |
686 | if (ata_identify_data[82] & BIT(6)) | 740 | if (identify_info[82] & BIT(6)) |
687 | PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ | 741 | PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ |
688 | if (ata_identify_data[83] & BIT(3)) | 742 | if (identify_info[83] & BIT(3)) |
689 | PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ | 743 | PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ |
690 | if (ata_identify_data[83] & BIT(9)) | 744 | if (identify_info[83] & BIT(9)) |
691 | PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ | 745 | PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ |
692 | ATA_PIO_TIME = piotime; | 746 | |
693 | ATA_MDMA_TIME = mdmatime; | 747 | PASS_RC(ata_identify(identify_info), 3, 9); /* Finally, re-read identify info */ |
694 | ATA_UDMA_TIME = udmatime; | ||
695 | } | 748 | } |
749 | |||
696 | spinup_time = current_tick - spinup_start; | 750 | spinup_time = current_tick - spinup_start; |
697 | if (ata_lba48) | 751 | |
698 | ata_total_sectors = ata_identify_data[100] | 752 | ata_total_sectors = (identify_info[61] << 16) | identify_info[60]; |
699 | | (((uint64_t)ata_identify_data[101]) << 16) | 753 | if ( identify_info[83] & BIT(10) && ata_total_sectors == 0x0FFFFFFF) |
700 | | (((uint64_t)ata_identify_data[102]) << 32) | 754 | { |
701 | | (((uint64_t)ata_identify_data[103]) << 48); | 755 | ata_total_sectors = ((uint64_t)identify_info[103] << 48) | |
702 | else | 756 | ((uint64_t)identify_info[102] << 32) | |
703 | ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); | 757 | ((uint64_t)identify_info[101] << 16) | |
704 | ata_total_sectors >>= 3; | 758 | identify_info[100]; |
759 | ata_lba48 = true; | ||
760 | } else { | ||
761 | ata_lba48 = false; | ||
762 | } | ||
763 | |||
705 | ata_powered = true; | 764 | ata_powered = true; |
706 | ata_set_active(); | 765 | ata_set_active(); |
707 | return 0; | 766 | return 0; |
@@ -709,28 +768,8 @@ static int ata_power_up(void) | |||
709 | 768 | ||
710 | static void ata_power_down(void) | 769 | static void ata_power_down(void) |
711 | { | 770 | { |
712 | if (!ata_powered) return; | 771 | if (!ata_powered) |
713 | if (ceata) | 772 | return; |
714 | { | ||
715 | memset(ceata_taskfile, 0, 16); | ||
716 | ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE; | ||
717 | ceata_wait_idle(); | ||
718 | ceata_write_multiple_register(0, ceata_taskfile, 16); | ||
719 | ceata_wait_idle(); | ||
720 | sleep(HZ); | ||
721 | PWRCON(0) |= (1 << 9); | ||
722 | } | ||
723 | else | ||
724 | { | ||
725 | ata_wait_for_rdy(1000000); | ||
726 | ata_write_cbr(&ATA_PIO_DVR, 0); | ||
727 | ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE); | ||
728 | ata_wait_for_rdy(1000000); | ||
729 | sleep(HZ / 30); | ||
730 | ATA_CONTROL = 0; | ||
731 | while (!(ATA_CONTROL & BIT(1))) yield(); | ||
732 | PWRCON(0) |= (1 << 5); | ||
733 | } | ||
734 | PCON(7) = 0; | 773 | PCON(7) = 0; |
735 | PCON(8) = 0; | 774 | PCON(8) = 0; |
736 | PCON(9) = 0; | 775 | PCON(9) = 0; |
@@ -745,18 +784,18 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
745 | if (ceata) | 784 | if (ceata) |
746 | { | 785 | { |
747 | memset(ceata_taskfile, 0, 16); | 786 | memset(ceata_taskfile, 0, 16); |
748 | ceata_taskfile[0x2] = cnt >> 5; | 787 | ceata_taskfile[0x2] = cnt >> 8; |
749 | ceata_taskfile[0x3] = sector >> 21; | 788 | ceata_taskfile[0x3] = sector >> 24; |
750 | ceata_taskfile[0x4] = sector >> 29; | 789 | ceata_taskfile[0x4] = sector >> 32; |
751 | ceata_taskfile[0x5] = sector >> 37; | 790 | ceata_taskfile[0x5] = sector >> 40; |
752 | ceata_taskfile[0xa] = cnt << 3; | 791 | ceata_taskfile[0xa] = cnt; |
753 | ceata_taskfile[0xb] = sector << 3; | 792 | ceata_taskfile[0xb] = sector; |
754 | ceata_taskfile[0xc] = sector >> 5; | 793 | ceata_taskfile[0xc] = sector >> 8; |
755 | ceata_taskfile[0xd] = sector >> 13; | 794 | ceata_taskfile[0xd] = sector >> 16; |
756 | ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; | 795 | ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; |
757 | PASS_RC(ceata_wait_idle(), 2, 0); | 796 | PASS_RC(ceata_wait_idle(), 2, 0); |
758 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); | 797 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
759 | PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); | 798 | PASS_RC(ceata_rw_multiple_block(write, buffer, cnt, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); |
760 | } | 799 | } |
761 | else | 800 | else |
762 | { | 801 | { |
@@ -764,14 +803,14 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
764 | ata_write_cbr(&ATA_PIO_DVR, 0); | 803 | ata_write_cbr(&ATA_PIO_DVR, 0); |
765 | if (ata_lba48) | 804 | if (ata_lba48) |
766 | { | 805 | { |
767 | ata_write_cbr(&ATA_PIO_SCR, cnt >> 5); | 806 | ata_write_cbr(&ATA_PIO_SCR, (cnt >> 8) & 0xff); |
768 | ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff); | 807 | ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff); |
769 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff); | 808 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 40) & 0xff); |
770 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff); | 809 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 32) & 0xff); |
771 | ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff); | 810 | ata_write_cbr(&ATA_PIO_LLR, (sector >> 24) & 0xff); |
772 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff); | 811 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff); |
773 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); | 812 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff); |
774 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); | 813 | ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff); |
775 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); | 814 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); |
776 | if (write) | 815 | if (write) |
777 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); | 816 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); |
@@ -780,16 +819,17 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
780 | } | 819 | } |
781 | else | 820 | else |
782 | { | 821 | { |
783 | ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff); | 822 | ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff); |
784 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff); | 823 | ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff); |
785 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); | 824 | ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff); |
786 | ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); | 825 | ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff); |
787 | ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf)); | 826 | ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 24) & 0xf)); /* LBA28, mask off upper 4 bits of 32-bit sector address */ |
788 | if (write) | 827 | if (write) |
789 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); | 828 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); |
790 | else | 829 | else |
791 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE); | 830 | ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE); |
792 | } | 831 | } |
832 | #ifdef HAVE_ATA_DMA | ||
793 | if (ata_dma) | 833 | if (ata_dma) |
794 | { | 834 | { |
795 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); | 835 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); |
@@ -812,8 +852,7 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
812 | ATA_IRQ = BITRANGE(0, 4); | 852 | ATA_IRQ = BITRANGE(0, 4); |
813 | ATA_IRQ_MASK = BIT(0); | 853 | ATA_IRQ_MASK = BIT(0); |
814 | ATA_COMMAND = BIT(0); | 854 | ATA_COMMAND = BIT(0); |
815 | if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000) | 855 | if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) |
816 | == OBJ_WAIT_TIMEDOUT) | ||
817 | { | 856 | { |
818 | ATA_COMMAND = BIT(1); | 857 | ATA_COMMAND = BIT(1); |
819 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); | 858 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); |
@@ -823,19 +862,19 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo | |||
823 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); | 862 | ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); |
824 | } | 863 | } |
825 | else | 864 | else |
865 | #endif // HAVE_ATA_DMA | ||
826 | { | 866 | { |
827 | cnt *= SECTOR_SIZE / 512; | ||
828 | while (cnt--) | 867 | while (cnt--) |
829 | { | 868 | { |
830 | int i; | 869 | int i; |
831 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); | 870 | PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); |
832 | if (write) | 871 | if (write) |
833 | for (i = 0; i < 256; i++) | 872 | for (i = 0; i < SECTOR_SIZE/2; i++) |
834 | ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]); | 873 | ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]); |
835 | else | 874 | else |
836 | for (i = 0; i < 256; i++) | 875 | for (i = 0; i < SECTOR_SIZE/2; i++) |
837 | ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR); | 876 | ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR); |
838 | buffer += 512; | 877 | buffer += SECTOR_SIZE; |
839 | } | 878 | } |
840 | } | 879 | } |
841 | PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3); | 880 | PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3); |
@@ -851,40 +890,27 @@ static int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write) | |||
851 | return rc; | 890 | return rc; |
852 | } | 891 | } |
853 | 892 | ||
854 | static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write) | 893 | static int ata_transfer_sectors(uint64_t sector, uint32_t count, void* buffer, bool write) |
855 | { | 894 | { |
856 | if (STORAGE_OVERLAP((uint32_t)buffer)) | 895 | if (!ata_powered) |
857 | { | 896 | ata_power_up(); |
858 | while (count) | 897 | if (sector + count > ata_total_sectors) |
859 | { | 898 | RET_ERR(0); |
860 | if (write) | ||
861 | memcpy(aligned_buffer, buffer, SECTOR_SIZE); | ||
862 | |||
863 | PASS_RC(ata_rw_sectors(sector, 1, aligned_buffer, write), 0, 0); | ||
864 | |||
865 | if (!write) | ||
866 | memcpy(buffer, aligned_buffer, SECTOR_SIZE); | ||
867 | |||
868 | buffer += SECTOR_SIZE; | ||
869 | sector++; | ||
870 | count--; | ||
871 | } | ||
872 | |||
873 | return 0; | ||
874 | } | ||
875 | |||
876 | if (!ata_powered) ata_power_up(); | ||
877 | if (sector + count > ata_total_sectors) RET_ERR(0); | ||
878 | ata_set_active(); | 899 | ata_set_active(); |
879 | if (ata_dma && write) commit_dcache(); | 900 | if (ata_dma && write) |
880 | else if (ata_dma) commit_discard_dcache(); | 901 | commit_dcache(); |
881 | if (!ceata) ATA_COMMAND = BIT(1); | 902 | else if (ata_dma) |
903 | commit_discard_dcache(); | ||
904 | if (!ceata) | ||
905 | ATA_COMMAND = BIT(1); | ||
906 | |||
882 | while (count) | 907 | while (count) |
883 | { | 908 | { |
884 | uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count); | 909 | uint32_t cnt = MIN(ata_lba48 ? 65536 : 256, count); |
885 | int rc = -1; | 910 | int rc = -1; |
886 | rc = ata_rw_chunk(sector, cnt, buffer, write); | 911 | rc = ata_rw_chunk(sector, cnt, buffer, write); |
887 | if (rc && ata_error_srst) ata_reset(); | 912 | if (rc && ata_error_srst) |
913 | ata_reset(); | ||
888 | if (rc && ata_retries) | 914 | if (rc && ata_retries) |
889 | { | 915 | { |
890 | void* buf = buffer; | 916 | void* buf = buffer; |
@@ -896,9 +922,11 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr | |||
896 | while (tries-- && rc) | 922 | while (tries-- && rc) |
897 | { | 923 | { |
898 | rc = ata_rw_chunk(sect, 1, buf, write); | 924 | rc = ata_rw_chunk(sect, 1, buf, write); |
899 | if (rc && ata_error_srst) ata_reset(); | 925 | if (rc && ata_error_srst) |
926 | ata_reset(); | ||
900 | } | 927 | } |
901 | if (rc) break; | 928 | if (rc) |
929 | break; | ||
902 | buf += SECTOR_SIZE; | 930 | buf += SECTOR_SIZE; |
903 | } | 931 | } |
904 | } | 932 | } |
@@ -916,9 +944,13 @@ int ata_soft_reset(void) | |||
916 | { | 944 | { |
917 | int rc; | 945 | int rc; |
918 | mutex_lock(&ata_mutex); | 946 | mutex_lock(&ata_mutex); |
919 | if (!ata_powered) PASS_RC(ata_power_up(), 1, 0); | 947 | if (!ata_powered) |
948 | PASS_RC(ata_power_up(), 1, 0); | ||
920 | ata_set_active(); | 949 | ata_set_active(); |
921 | if (ceata) rc = ceata_soft_reset(); | 950 | if (ceata) |
951 | { | ||
952 | rc = ceata_soft_reset(); | ||
953 | } | ||
922 | else | 954 | else |
923 | { | 955 | { |
924 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); | 956 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); |
@@ -945,7 +977,8 @@ static int ata_reset(void) | |||
945 | { | 977 | { |
946 | int rc; | 978 | int rc; |
947 | mutex_lock(&ata_mutex); | 979 | mutex_lock(&ata_mutex); |
948 | if (!ata_powered) PASS_RC(ata_power_up(), 2, 0); | 980 | if (!ata_powered) |
981 | PASS_RC(ata_power_up(), 2, 0); | ||
949 | ata_set_active(); | 982 | ata_set_active(); |
950 | rc = ata_soft_reset(); | 983 | rc = ata_soft_reset(); |
951 | if (IS_ERR(rc)) | 984 | if (IS_ERR(rc)) |
@@ -957,7 +990,8 @@ static int ata_reset(void) | |||
957 | ata_power_down(); | 990 | ata_power_down(); |
958 | sleep(HZ * 3); | 991 | sleep(HZ * 3); |
959 | int rc2 = ata_power_up(); | 992 | int rc2 = ata_power_up(); |
960 | if (IS_ERR(rc2)) rc = ERR_RC((rc << 2) | 2); | 993 | if (IS_ERR(rc2)) |
994 | rc = ERR_RC((rc << 2) | 2); | ||
961 | } | 995 | } |
962 | else rc = 1; | 996 | else rc = 1; |
963 | } | 997 | } |
@@ -966,23 +1000,35 @@ static int ata_reset(void) | |||
966 | return rc; | 1000 | return rc; |
967 | } | 1001 | } |
968 | 1002 | ||
969 | int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount, | 1003 | #include "ata-common.c" |
1004 | |||
1005 | #ifndef MAX_PHYS_SECTOR_SIZE | ||
1006 | int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount, | ||
970 | void* inbuf) | 1007 | void* inbuf) |
971 | { | 1008 | { |
1009 | #ifdef HAVE_MULTIDRIVE | ||
1010 | (void)drive; /* unused for now */ | ||
1011 | #endif | ||
1012 | |||
972 | mutex_lock(&ata_mutex); | 1013 | mutex_lock(&ata_mutex); |
973 | int rc = ata_rw_sectors(start, incount, inbuf, false); | 1014 | int rc = ata_transfer_sectors(start, incount, inbuf, false); |
974 | mutex_unlock(&ata_mutex); | 1015 | mutex_unlock(&ata_mutex); |
975 | return rc; | 1016 | return rc; |
976 | } | 1017 | } |
977 | 1018 | ||
978 | int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, | 1019 | int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, |
979 | const void* outbuf) | 1020 | const void* outbuf) |
980 | { | 1021 | { |
1022 | #ifdef HAVE_MULTIDRIVE | ||
1023 | (void)drive; /* unused for now */ | ||
1024 | #endif | ||
1025 | |||
981 | mutex_lock(&ata_mutex); | 1026 | mutex_lock(&ata_mutex); |
982 | int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true); | 1027 | int rc = ata_transfer_sectors(start, count, (void*)((uint32_t)outbuf), true); |
983 | mutex_unlock(&ata_mutex); | 1028 | mutex_unlock(&ata_mutex); |
984 | return rc; | 1029 | return rc; |
985 | } | 1030 | } |
1031 | #endif /* ndef MAX_PHYS_SECTOR_SIZE */ | ||
986 | 1032 | ||
987 | void ata_spindown(int seconds) | 1033 | void ata_spindown(int seconds) |
988 | { | 1034 | { |
@@ -993,26 +1039,27 @@ static void ata_flush_cache(void) | |||
993 | { | 1039 | { |
994 | uint8_t cmd; | 1040 | uint8_t cmd; |
995 | 1041 | ||
996 | if (ata_identify_data[83] & BIT(13)) { | 1042 | if (ceata) { |
997 | cmd = CMD_FLUSH_CACHE_EXT; | ||
998 | } else if (ata_identify_data[83] & BIT(12)) { | ||
999 | cmd = CMD_FLUSH_CACHE; | ||
1000 | } else { | ||
1001 | /* If neither (mandatory!) command is supported | ||
1002 | then don't issue it. */ | ||
1003 | return; | ||
1004 | } | ||
1005 | |||
1006 | if (ceata) | ||
1007 | { | ||
1008 | memset(ceata_taskfile, 0, 16); | 1043 | memset(ceata_taskfile, 0, 16); |
1009 | ceata_taskfile[0xf] = cmd; | 1044 | ceata_taskfile[0xf] = CMD_FLUSH_CACHE_EXT; /* CE-ATA only supports EXT */ |
1010 | ceata_wait_idle(); | 1045 | ceata_wait_idle(); |
1011 | ceata_write_multiple_register(0, ceata_taskfile, 16); | 1046 | ceata_write_multiple_register(0, ceata_taskfile, 16); |
1012 | ceata_wait_idle(); | 1047 | ceata_wait_idle(); |
1013 | } | 1048 | } else { |
1014 | else | 1049 | if (!canflush) { |
1015 | { | 1050 | return; |
1051 | } else if (ata_lba48 && identify_info[83] & BIT(13)) { | ||
1052 | cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices. Mandatory for CE-ATA */ | ||
1053 | } else if (identify_info[83] & BIT(12)) { | ||
1054 | cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */ | ||
1055 | } else if (identify_info[80] >= BIT(5)) { /* Use >= instead of '&' because bits lower than the latest standard we support don't have to be set */ | ||
1056 | cmd = CMD_FLUSH_CACHE; /* No flag, mandatory, ATA-5 (Optional for ATA-4) */ | ||
1057 | } else { | ||
1058 | /* If neither command is supported then don't issue it. */ | ||
1059 | canflush = 0; | ||
1060 | return; | ||
1061 | } | ||
1062 | |||
1016 | ata_wait_for_rdy(1000000); | 1063 | ata_wait_for_rdy(1000000); |
1017 | ata_write_cbr(&ATA_PIO_DVR, 0); | 1064 | ata_write_cbr(&ATA_PIO_DVR, 0); |
1018 | ata_write_cbr(&ATA_PIO_CSD, cmd); | 1065 | ata_write_cbr(&ATA_PIO_CSD, cmd); |
@@ -1020,14 +1067,46 @@ static void ata_flush_cache(void) | |||
1020 | } | 1067 | } |
1021 | } | 1068 | } |
1022 | 1069 | ||
1070 | int ata_flush(void) | ||
1071 | { | ||
1072 | if (ata_powered) { | ||
1073 | mutex_lock(&ata_mutex); | ||
1074 | ata_flush_cache(); | ||
1075 | mutex_unlock(&ata_mutex); | ||
1076 | } | ||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1023 | void ata_sleepnow(void) | 1080 | void ata_sleepnow(void) |
1024 | { | 1081 | { |
1025 | mutex_lock(&ata_mutex); | 1082 | mutex_lock(&ata_mutex); |
1026 | 1083 | ||
1027 | if (ata_disk_can_poweroff()) | 1084 | ata_flush_cache(); |
1028 | ata_power_down(); | 1085 | |
1029 | else | 1086 | if (ata_disk_can_sleep()) { |
1030 | ata_flush_cache(); | 1087 | if (ceata) { |
1088 | memset(ceata_taskfile, 0, 16); | ||
1089 | ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE; | ||
1090 | ceata_wait_idle(); | ||
1091 | ceata_write_multiple_register(0, ceata_taskfile, 16); | ||
1092 | ceata_wait_idle(); | ||
1093 | sleep(HZ); | ||
1094 | PWRCON(0) |= (1 << 9); | ||
1095 | } else { | ||
1096 | ata_wait_for_rdy(1000000); | ||
1097 | ata_write_cbr(&ATA_PIO_DVR, 0); | ||
1098 | ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE); | ||
1099 | ata_wait_for_rdy(1000000); | ||
1100 | sleep(HZ / 30); | ||
1101 | ATA_CONTROL = 0; | ||
1102 | while (!(ATA_CONTROL & BIT(1))) | ||
1103 | yield(); | ||
1104 | PWRCON(0) |= (1 << 5); | ||
1105 | } | ||
1106 | } | ||
1107 | |||
1108 | if (ata_disk_can_sleep() || canflush) | ||
1109 | ata_power_down(); // XXX add a powerdown delay similar to main ATA driver? | ||
1031 | 1110 | ||
1032 | mutex_unlock(&ata_mutex); | 1111 | mutex_unlock(&ata_mutex); |
1033 | } | 1112 | } |
@@ -1037,14 +1116,21 @@ void ata_spin(void) | |||
1037 | ata_set_active(); | 1116 | ata_set_active(); |
1038 | } | 1117 | } |
1039 | 1118 | ||
1119 | #ifdef STORAGE_GET_INFO | ||
1040 | void ata_get_info(IF_MD(int drive,) struct storage_info *info) | 1120 | void ata_get_info(IF_MD(int drive,) struct storage_info *info) |
1041 | { | 1121 | { |
1042 | (*info).sector_size = SECTOR_SIZE; | 1122 | /* Logical sector size */ |
1123 | if ((identify_info[106] & 0xd000) == 0x5000) /* B14, B12 */ | ||
1124 | info->sector_size = (identify_info[117] | (identify_info[118] << 16)) * 2; | ||
1125 | else | ||
1126 | info->sector_size = SECTOR_SIZE; | ||
1127 | |||
1043 | (*info).num_sectors = ata_total_sectors; | 1128 | (*info).num_sectors = ata_total_sectors; |
1044 | (*info).vendor = "Apple"; | 1129 | (*info).vendor = "Apple"; |
1045 | (*info).product = "iPod Classic"; | 1130 | (*info).product = "iPod Classic"; |
1046 | (*info).revision = "1.0"; | 1131 | (*info).revision = "1.0"; |
1047 | } | 1132 | } |
1133 | #endif | ||
1048 | 1134 | ||
1049 | long ata_last_disk_activity(void) | 1135 | long ata_last_disk_activity(void) |
1050 | { | 1136 | { |
@@ -1061,11 +1147,18 @@ int ata_init(void) | |||
1061 | ata_powered = false; | 1147 | ata_powered = false; |
1062 | ata_total_sectors = 0; | 1148 | ata_total_sectors = 0; |
1063 | 1149 | ||
1064 | /* get ata_identify_data */ | 1150 | /* get identify_info */ |
1065 | mutex_lock(&ata_mutex); | 1151 | mutex_lock(&ata_mutex); |
1066 | int rc = ata_power_up(); | 1152 | int rc = ata_power_up(); |
1067 | mutex_unlock(&ata_mutex); | 1153 | mutex_unlock(&ata_mutex); |
1068 | if (IS_ERR(rc)) return rc; | 1154 | if (IS_ERR(rc)) |
1155 | return rc; | ||
1156 | |||
1157 | #ifdef MAX_PHYS_SECTOR_SIZE | ||
1158 | rc = ata_get_phys_sector_mult(); | ||
1159 | if (IS_ERR(rc)) | ||
1160 | return rc; | ||
1161 | #endif | ||
1069 | 1162 | ||
1070 | return 0; | 1163 | return 0; |
1071 | } | 1164 | } |
@@ -1082,7 +1175,7 @@ static int ata_smart(uint16_t* buf) | |||
1082 | ceata_taskfile[0xe] = BIT(6); | 1175 | ceata_taskfile[0xe] = BIT(6); |
1083 | ceata_taskfile[0xf] = CMD_SMART; | 1176 | ceata_taskfile[0xf] = CMD_SMART; |
1084 | PASS_RC(ceata_wait_idle(), 3, 1); | 1177 | PASS_RC(ceata_wait_idle(), 3, 1); |
1085 | if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */ | 1178 | if (((uint8_t*)identify_info)[54] != 'A') /* Model != aAmsung */ |
1086 | { | 1179 | { |
1087 | ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */ | 1180 | ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */ |
1088 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2); | 1181 | PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2); |
@@ -1102,7 +1195,8 @@ static int ata_smart(uint16_t* buf) | |||
1102 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); | 1195 | ata_write_cbr(&ATA_PIO_DVR, BIT(6)); |
1103 | ata_write_cbr(&ATA_PIO_CSD, CMD_SMART); | 1196 | ata_write_cbr(&ATA_PIO_CSD, CMD_SMART); |
1104 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); | 1197 | PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); |
1105 | for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); | 1198 | for (i = 0; i < 0x100; i++) |
1199 | buf[i] = ata_read_cbr(&ATA_PIO_DTR); | ||
1106 | } | 1200 | } |
1107 | ata_set_active(); | 1201 | ata_set_active(); |
1108 | return 0; | 1202 | return 0; |
@@ -1129,7 +1223,7 @@ static int ata_num_drives(int first_drive) | |||
1129 | 1223 | ||
1130 | unsigned short* ata_get_identify(void) | 1224 | unsigned short* ata_get_identify(void) |
1131 | { | 1225 | { |
1132 | return ata_identify_data; | 1226 | return identify_info; |
1133 | } | 1227 | } |
1134 | 1228 | ||
1135 | int ata_spinup_time(void) | 1229 | int ata_spinup_time(void) |
@@ -1137,24 +1231,29 @@ int ata_spinup_time(void) | |||
1137 | return spinup_time; | 1231 | return spinup_time; |
1138 | } | 1232 | } |
1139 | 1233 | ||
1234 | #ifdef HAVE_ATA_DMA | ||
1140 | int ata_get_dma_mode(void) | 1235 | int ata_get_dma_mode(void) |
1141 | { | 1236 | { |
1142 | return dma_mode; | 1237 | return dma_mode; |
1143 | } | 1238 | } |
1239 | #endif | ||
1144 | 1240 | ||
1145 | void INT_ATA(void) | 1241 | void INT_ATA(void) |
1146 | { | 1242 | { |
1147 | uint32_t ata_irq = ATA_IRQ; | 1243 | uint32_t ata_irq = ATA_IRQ; |
1148 | ATA_IRQ = ata_irq; | 1244 | ATA_IRQ = ata_irq; |
1149 | if (ata_irq & ATA_IRQ_MASK) semaphore_release(&ata_wakeup); | 1245 | if (ata_irq & ATA_IRQ_MASK) |
1246 | semaphore_release(&ata_wakeup); | ||
1150 | ATA_IRQ_MASK = 0; | 1247 | ATA_IRQ_MASK = 0; |
1151 | } | 1248 | } |
1152 | 1249 | ||
1153 | void INT_MMC(void) | 1250 | void INT_MMC(void) |
1154 | { | 1251 | { |
1155 | uint32_t irq = SDCI_IRQ; | 1252 | uint32_t irq = SDCI_IRQ; |
1156 | if (irq & SDCI_IRQ_DAT_DONE_INT) semaphore_release(&mmc_wakeup); | 1253 | if (irq & SDCI_IRQ_DAT_DONE_INT) |
1157 | if (irq & SDCI_IRQ_IOCARD_IRQ_INT) semaphore_release(&mmc_comp_wakeup); | 1254 | semaphore_release(&mmc_wakeup); |
1255 | if (irq & SDCI_IRQ_IOCARD_IRQ_INT) | ||
1256 | semaphore_release(&mmc_comp_wakeup); | ||
1158 | SDCI_IRQ = irq; | 1257 | SDCI_IRQ = irq; |
1159 | } | 1258 | } |
1160 | 1259 | ||
diff --git a/firmware/target/arm/tcc780x/sd-tcc780x.c b/firmware/target/arm/tcc780x/sd-tcc780x.c index c80c3b746f..3ef8972ee9 100644 --- a/firmware/target/arm/tcc780x/sd-tcc780x.c +++ b/firmware/target/arm/tcc780x/sd-tcc780x.c | |||
@@ -104,19 +104,19 @@ static bool sd_poll_status(unsigned int trigger, long timeout) | |||
104 | return true; | 104 | return true; |
105 | } | 105 | } |
106 | 106 | ||
107 | static int sd_command(unsigned int cmd, unsigned int arg, | 107 | static int sd_command(unsigned int cmd, unsigned int arg, |
108 | unsigned long* response, unsigned int resp_type) | 108 | unsigned long* response, unsigned int resp_type) |
109 | { | 109 | { |
110 | int sdi_cmd = cmd; | 110 | int sdi_cmd = cmd; |
111 | 111 | ||
112 | sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */ | 112 | sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */ |
113 | 113 | ||
114 | if (resp_type) | 114 | if (resp_type) |
115 | { | 115 | { |
116 | /* response type & response required flag */ | 116 | /* response type & response required flag */ |
117 | sdi_cmd |= (resp_type<<7) | (1<<6); | 117 | sdi_cmd |= (resp_type<<7) | (1<<6); |
118 | } | 118 | } |
119 | 119 | ||
120 | if (cmd == SD_READ_SINGLE_BLOCK || | 120 | if (cmd == SD_READ_SINGLE_BLOCK || |
121 | cmd == SD_READ_MULTIPLE_BLOCK || | 121 | cmd == SD_READ_MULTIPLE_BLOCK || |
122 | cmd == SD_WRITE_BLOCK || | 122 | cmd == SD_WRITE_BLOCK || |
@@ -124,18 +124,18 @@ static int sd_command(unsigned int cmd, unsigned int arg, | |||
124 | { | 124 | { |
125 | sdi_cmd |= (1<<10); /* request data transfer */ | 125 | sdi_cmd |= (1<<10); /* request data transfer */ |
126 | } | 126 | } |
127 | 127 | ||
128 | if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) | 128 | if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) |
129 | return -EC_COMMAND; | 129 | return -EC_COMMAND; |
130 | 130 | ||
131 | SDIARGU = arg; | 131 | SDIARGU = arg; |
132 | SDICMD = sdi_cmd; | 132 | SDICMD = sdi_cmd; |
133 | 133 | ||
134 | udelay(10); | 134 | udelay(10); |
135 | 135 | ||
136 | if (response == NULL) | 136 | if (response == NULL) |
137 | return 0; | 137 | return 0; |
138 | 138 | ||
139 | if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000)) | 139 | if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000)) |
140 | return -EC_COMMAND; | 140 | return -EC_COMMAND; |
141 | 141 | ||
@@ -150,7 +150,7 @@ static int sd_command(unsigned int cmd, unsigned int arg, | |||
150 | { | 150 | { |
151 | response[0] = SDIRSPARGU0; | 151 | response[0] = SDIRSPARGU0; |
152 | } | 152 | } |
153 | 153 | ||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
@@ -220,7 +220,7 @@ static int sd1_oneshot_callback(struct timeout *tmo) | |||
220 | void EXT0(void) | 220 | void EXT0(void) |
221 | { | 221 | { |
222 | static struct timeout sd1_oneshot; | 222 | static struct timeout sd1_oneshot; |
223 | 223 | ||
224 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); | 224 | timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); |
225 | } | 225 | } |
226 | 226 | ||
@@ -248,7 +248,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no)) | |||
248 | const int card_no = 0; | 248 | const int card_no = 0; |
249 | #endif | 249 | #endif |
250 | (void)card_no; | 250 | (void)card_no; |
251 | 251 | ||
252 | return false; | 252 | return false; |
253 | } | 253 | } |
254 | 254 | ||
@@ -259,7 +259,7 @@ static void sd_init_device(int card_no) | |||
259 | { | 259 | { |
260 | int ret; | 260 | int ret; |
261 | unsigned long response; | 261 | unsigned long response; |
262 | 262 | ||
263 | /* Initialise card data as blank */ | 263 | /* Initialise card data as blank */ |
264 | memset(currcard, 0, sizeof(*currcard)); | 264 | memset(currcard, 0, sizeof(*currcard)); |
265 | 265 | ||
@@ -282,7 +282,7 @@ static void sd_init_device(int card_no) | |||
282 | #endif | 282 | #endif |
283 | 283 | ||
284 | ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1); | 284 | ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1); |
285 | 285 | ||
286 | if (ret < 0) | 286 | if (ret < 0) |
287 | goto card_init_error; | 287 | goto card_init_error; |
288 | 288 | ||
@@ -290,30 +290,30 @@ static void sd_init_device(int card_no) | |||
290 | SDICLK = (1<<12) | 59; | 290 | SDICLK = (1<<12) | 59; |
291 | 291 | ||
292 | sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3); | 292 | sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3); |
293 | 293 | ||
294 | if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) | 294 | if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) |
295 | goto card_init_error; | 295 | goto card_init_error; |
296 | 296 | ||
297 | currcard->ocr = 0; | 297 | currcard->ocr = 0; |
298 | 298 | ||
299 | long start_tick = current_tick; | 299 | long start_tick = current_tick; |
300 | 300 | ||
301 | while ((currcard->ocr & (1<<31)) == 0 | 301 | while ((currcard->ocr & (1<<31)) == 0 |
302 | && TIME_BEFORE(current_tick, start_tick + HZ)) | 302 | && TIME_BEFORE(current_tick, start_tick + HZ)) |
303 | { | 303 | { |
304 | udelay(100); | 304 | udelay(100); |
305 | sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1); | 305 | sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1); |
306 | 306 | ||
307 | int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0); | 307 | int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0); |
308 | sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3); | 308 | sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3); |
309 | } | 309 | } |
310 | 310 | ||
311 | if ((currcard->ocr & (1<<31)) == 0) | 311 | if ((currcard->ocr & (1<<31)) == 0) |
312 | { | 312 | { |
313 | ret = -EC_POWER_UP; | 313 | ret = -EC_POWER_UP; |
314 | goto card_init_error; | 314 | goto card_init_error; |
315 | } | 315 | } |
316 | 316 | ||
317 | ret = sd_command | 317 | ret = sd_command |
318 | (SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2); | 318 | (SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2); |
319 | 319 | ||
@@ -322,39 +322,39 @@ static void sd_init_device(int card_no) | |||
322 | 322 | ||
323 | ret = sd_command | 323 | ret = sd_command |
324 | (SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1); | 324 | (SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1); |
325 | 325 | ||
326 | if (ret < 0) | 326 | if (ret < 0) |
327 | goto card_init_error; | 327 | goto card_init_error; |
328 | 328 | ||
329 | ret = sd_command | 329 | ret = sd_command |
330 | (SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2); | 330 | (SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2); |
331 | 331 | ||
332 | if (ret < 0) | 332 | if (ret < 0) |
333 | goto card_init_error; | 333 | goto card_init_error; |
334 | 334 | ||
335 | sd_parse_csd(currcard); | 335 | sd_parse_csd(currcard); |
336 | 336 | ||
337 | ret = sd_command | 337 | ret = sd_command |
338 | (SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1); | 338 | (SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1); |
339 | 339 | ||
340 | if (ret < 0) | 340 | if (ret < 0) |
341 | goto card_init_error; | 341 | goto card_init_error; |
342 | 342 | ||
343 | ret = sd_command | 343 | ret = sd_command |
344 | (SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1); | 344 | (SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1); |
345 | 345 | ||
346 | if (ret < 0) | 346 | if (ret < 0) |
347 | goto card_init_error; | 347 | goto card_init_error; |
348 | 348 | ||
349 | ret = sd_command /* 4 bit */ | 349 | ret = sd_command /* 4 bit */ |
350 | (SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1); | 350 | (SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1); |
351 | 351 | ||
352 | if (ret < 0) | 352 | if (ret < 0) |
353 | goto card_init_error; | 353 | goto card_init_error; |
354 | 354 | ||
355 | ret = sd_command | 355 | ret = sd_command |
356 | (SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1); | 356 | (SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1); |
357 | 357 | ||
358 | if (ret < 0) | 358 | if (ret < 0) |
359 | goto card_init_error; | 359 | goto card_init_error; |
360 | 360 | ||
@@ -386,7 +386,7 @@ static void sd_select_device(int card_no) | |||
386 | } | 386 | } |
387 | } | 387 | } |
388 | 388 | ||
389 | int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, | 389 | int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount, |
390 | void* inbuf) | 390 | void* inbuf) |
391 | { | 391 | { |
392 | #ifndef HAVE_MULTIDRIVE | 392 | #ifndef HAVE_MULTIDRIVE |
@@ -416,23 +416,24 @@ sd_read_retry: | |||
416 | ret = currcard->initialized; | 416 | ret = currcard->initialized; |
417 | goto sd_read_error; | 417 | goto sd_read_error; |
418 | } | 418 | } |
419 | 419 | ||
420 | last_disk_activity = current_tick; | 420 | last_disk_activity = current_tick; |
421 | 421 | ||
422 | ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY); | 422 | ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY); |
423 | 423 | ||
424 | if (ret < 0) | 424 | if (ret < 0) |
425 | goto sd_read_error; | 425 | goto sd_read_error; |
426 | 426 | ||
427 | /* Use full SD clock for data transfer (PCK_SDMMC) */ | 427 | /* Use full SD clock for data transfer (PCK_SDMMC) */ |
428 | SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ | 428 | SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ |
429 | 429 | ||
430 | /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ | 430 | /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ |
431 | SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2); | 431 | SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2); |
432 | SDIDCTRL |= (1<<12); /* nReset */ | 432 | SDIDCTRL |= (1<<12); /* nReset */ |
433 | 433 | ||
434 | SDIDCTRL2 = (1<<2); /* multi block, read */ | 434 | SDIDCTRL2 = (1<<2); /* multi block, read */ |
435 | 435 | ||
436 | // XXX 64-bit | ||
436 | if (currcard->ocr & (1<<30)) | 437 | if (currcard->ocr & (1<<30)) |
437 | ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); | 438 | ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); |
438 | else | 439 | else |
@@ -500,7 +501,7 @@ sd_read_error: | |||
500 | } | 501 | } |
501 | } | 502 | } |
502 | 503 | ||
503 | int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, | 504 | int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count, |
504 | const void* outbuf) | 505 | const void* outbuf) |
505 | { | 506 | { |
506 | /* Write support is not finished yet */ | 507 | /* Write support is not finished yet */ |
@@ -538,21 +539,22 @@ sd_write_retry: | |||
538 | ret = currcard->initialized; | 539 | ret = currcard->initialized; |
539 | goto sd_write_error; | 540 | goto sd_write_error; |
540 | } | 541 | } |
541 | 542 | ||
542 | ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY); | 543 | ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY); |
543 | 544 | ||
544 | if (ret < 0) | 545 | if (ret < 0) |
545 | goto sd_write_error; | 546 | goto sd_write_error; |
546 | 547 | ||
547 | /* Use full SD clock for data transfer (PCK_SDMMC) */ | 548 | /* Use full SD clock for data transfer (PCK_SDMMC) */ |
548 | SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ | 549 | SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ |
549 | 550 | ||
550 | /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ | 551 | /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ |
551 | SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2); | 552 | SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2); |
552 | SDIDCTRL |= (1<<12); /* nReset */ | 553 | SDIDCTRL |= (1<<12); /* nReset */ |
553 | 554 | ||
554 | SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */ | 555 | SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */ |
555 | 556 | ||
557 | // XXX 64-bit | ||
556 | if (currcard->ocr & (1<<30)) | 558 | if (currcard->ocr & (1<<30)) |
557 | ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); | 559 | ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); |
558 | else | 560 | else |
@@ -578,7 +580,7 @@ sd_write_retry: | |||
578 | else | 580 | else |
579 | { | 581 | { |
580 | int tmp_buf[4]; | 582 | int tmp_buf[4]; |
581 | 583 | ||
582 | memcpy(tmp_buf, outbuf, 16); | 584 | memcpy(tmp_buf, outbuf, 16); |
583 | 585 | ||
584 | SDIWDATA = tmp_buf[0]; | 586 | SDIWDATA = tmp_buf[0]; |
@@ -646,12 +648,12 @@ void sd_enable(bool on) | |||
646 | PCLK_SDMMC &= ~PCK_EN; | 648 | PCLK_SDMMC &= ~PCK_EN; |
647 | } | 649 | } |
648 | } | 650 | } |
649 | 651 | ||
650 | int sd_init(void) | 652 | int sd_init(void) |
651 | { | 653 | { |
652 | static bool initialized = false; | 654 | static bool initialized = false; |
653 | int ret = 0; | 655 | int ret = 0; |
654 | 656 | ||
655 | if (!initialized) | 657 | if (!initialized) |
656 | mutex_init(&sd_mtx); | 658 | mutex_init(&sd_mtx); |
657 | 659 | ||
@@ -678,7 +680,7 @@ int sd_init(void) | |||
678 | GPIOC_DIR |= (1<<24); | 680 | GPIOC_DIR |= (1<<24); |
679 | 681 | ||
680 | sleep(HZ/10); | 682 | sleep(HZ/10); |
681 | 683 | ||
682 | #ifdef HAVE_HOTSWAP | 684 | #ifdef HAVE_HOTSWAP |
683 | /* Configure interrupts for the card slot */ | 685 | /* Configure interrupts for the card slot */ |
684 | TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */ | 686 | TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */ |
@@ -696,7 +698,7 @@ long sd_last_disk_activity(void) | |||
696 | } | 698 | } |
697 | 699 | ||
698 | tCardInfo *card_get_info_target(int card_no) | 700 | tCardInfo *card_get_info_target(int card_no) |
699 | { | 701 | { |
700 | return &card_info[card_no]; | 702 | return &card_info[card_no]; |
701 | } | 703 | } |
702 | 704 | ||
@@ -706,7 +708,7 @@ int sd_num_drives(int first_drive) | |||
706 | { | 708 | { |
707 | /* Store which logical drive number(s) we have been assigned */ | 709 | /* Store which logical drive number(s) we have been assigned */ |
708 | sd_first_drive = first_drive; | 710 | sd_first_drive = first_drive; |
709 | 711 | ||
710 | #if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP) | 712 | #if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP) |
711 | return 2; | 713 | return 2; |
712 | #else | 714 | #else |
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c index a1985472a0..76929e603e 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c +++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c | |||
@@ -126,8 +126,10 @@ void GIO2(void) | |||
126 | 126 | ||
127 | #define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */ | 127 | #define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */ |
128 | 128 | ||
129 | extern int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); | 129 | extern int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf); |
130 | extern int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); | 130 | extern int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf); |
131 | |||
132 | // XXX 64-bit: Due to this it's not likely that this target will ever handle 64-bit storage. | ||
131 | 133 | ||
132 | struct main_header | 134 | struct main_header |
133 | { | 135 | { |
@@ -253,9 +255,9 @@ static void cfs_init(void) | |||
253 | /* Read root inode */ | 255 | /* Read root inode */ |
254 | _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, §or2); | 256 | _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, §or2); |
255 | root_inode = (struct cfs_inode*)§or2; | 257 | root_inode = (struct cfs_inode*)§or2; |
256 | 258 | ||
257 | logf("Root inode = 0x%x", root_inode); | 259 | logf("Root inode = 0x%x", root_inode); |
258 | 260 | ||
259 | logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]); | 261 | logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]); |
260 | 262 | ||
261 | /* Read root inode's first sector */ | 263 | /* Read root inode's first sector */ |
@@ -277,9 +279,9 @@ static void cfs_init(void) | |||
277 | vfat_inode_nr = root_direntry_items[i].inode_number; | 279 | vfat_inode_nr = root_direntry_items[i].inode_number; |
278 | } | 280 | } |
279 | } | 281 | } |
280 | 282 | ||
281 | logf("VFAT inode = 0x%x", vfat_inode_nr); | 283 | logf("VFAT inode = 0x%x", vfat_inode_nr); |
282 | 284 | ||
283 | if(vfat_inode_nr != 0) | 285 | if(vfat_inode_nr != 0) |
284 | { | 286 | { |
285 | /* Read VFAT inode */ | 287 | /* Read VFAT inode */ |
@@ -384,19 +386,19 @@ static void cfs_init(void) | |||
384 | cfs_inited = true; | 386 | cfs_inited = true; |
385 | } | 387 | } |
386 | 388 | ||
387 | static inline unsigned long map_sector(unsigned long sector) | 389 | static inline sector_t map_sector(sector_t sector) |
388 | { | 390 | { |
389 | /* | 391 | /* |
390 | * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part | 392 | * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part |
391 | * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes. | 393 | * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes. |
392 | */ | 394 | */ |
393 | #ifndef BOOTLOADER | 395 | #ifndef BOOTLOADER |
394 | unsigned long *sectors = core_get_data(sectors_handle); | 396 | sector_t *sectors = core_get_data(sectors_handle); |
395 | #endif | 397 | #endif |
396 | return cfs_start+sectors[sector/64]*64+sector%64; | 398 | return cfs_start+sectors[sector/64]*64+sector%64; |
397 | } | 399 | } |
398 | 400 | ||
399 | int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) | 401 | int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf) |
400 | { | 402 | { |
401 | if(!cfs_inited) | 403 | if(!cfs_inited) |
402 | cfs_init(); | 404 | cfs_init(); |
@@ -423,7 +425,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf | |||
423 | } | 425 | } |
424 | } | 426 | } |
425 | 427 | ||
426 | int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) | 428 | int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf) |
427 | { | 429 | { |
428 | if(!cfs_inited) | 430 | if(!cfs_inited) |
429 | cfs_init(); | 431 | cfs_init(); |
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h index d0aa12e040..41b8e73ad4 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h +++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h | |||
@@ -36,8 +36,8 @@ | |||
36 | /* Nasty hack, but Creative is nasty... */ | 36 | /* Nasty hack, but Creative is nasty... */ |
37 | #define ata_read_sectors _ata_read_sectors | 37 | #define ata_read_sectors _ata_read_sectors |
38 | #define ata_write_sectors _ata_write_sectors | 38 | #define ata_write_sectors _ata_write_sectors |
39 | extern int _ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); | 39 | extern int _ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf); |
40 | extern int _ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); | 40 | extern int _ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf); |
41 | 41 | ||
42 | /* General purpose memory region #1 */ | 42 | /* General purpose memory region #1 */ |
43 | #define ATA_IOBASE 0x50FEE000 | 43 | #define ATA_IOBASE 0x50FEE000 |
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c index e66a4cb3c7..17cb239374 100644 --- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c +++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "system.h" | 22 | #include "system.h" |
23 | #include <string.h> | 23 | #include <string.h> |
24 | #include "gcc_extensions.h" | 24 | #include "gcc_extensions.h" |
@@ -97,7 +97,7 @@ struct sd_card_status | |||
97 | int retry_max; | 97 | int retry_max; |
98 | }; | 98 | }; |
99 | 99 | ||
100 | /** static, private data **/ | 100 | /** static, private data **/ |
101 | 101 | ||
102 | /* for compatibility */ | 102 | /* for compatibility */ |
103 | static long last_disk_activity = -1; | 103 | static long last_disk_activity = -1; |
@@ -123,7 +123,7 @@ static struct mutex sd_mtx SHAREDBSS_ATTR; | |||
123 | static struct semaphore data_done SHAREDBSS_ATTR; | 123 | static struct semaphore data_done SHAREDBSS_ATTR; |
124 | static volatile unsigned int transfer_error[NUM_DRIVES]; | 124 | static volatile unsigned int transfer_error[NUM_DRIVES]; |
125 | /* align on cache line size */ | 125 | /* align on cache line size */ |
126 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] | 126 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] |
127 | __attribute__((aligned(32))); | 127 | __attribute__((aligned(32))); |
128 | 128 | ||
129 | static void sd_card_mux(int card_no) | 129 | static void sd_card_mux(int card_no) |
@@ -397,7 +397,7 @@ static int sd_init_card(const int card_no) | |||
397 | SDHC_RESP_FMT_1, &currcard->rca); | 397 | SDHC_RESP_FMT_1, &currcard->rca); |
398 | if (ret < 0) | 398 | if (ret < 0) |
399 | { | 399 | { |
400 | dbgprintf("SD_SEND_RELATIVE_ADDR failed"); | 400 | dbgprintf("SD_SEND_RELATIVE_ADDR failed"); |
401 | return -1; | 401 | return -1; |
402 | } | 402 | } |
403 | 403 | ||
@@ -559,7 +559,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no)) | |||
559 | #ifdef HAVE_MULTIDRIVE | 559 | #ifdef HAVE_MULTIDRIVE |
560 | (void)card_no; | 560 | (void)card_no; |
561 | #endif | 561 | #endif |
562 | 562 | ||
563 | /* not applicable */ | 563 | /* not applicable */ |
564 | return false; | 564 | return false; |
565 | } | 565 | } |
@@ -597,17 +597,17 @@ static int sd_wait_for_state(unsigned int state) | |||
597 | } | 597 | } |
598 | } | 598 | } |
599 | 599 | ||
600 | static int sd_transfer_sectors(int card_no, unsigned long start, | 600 | static int sd_transfer_sectors(int card_no, sector_t start, |
601 | int count, void *buffer, bool write) | 601 | int count, void *buffer, bool write) |
602 | { | 602 | { |
603 | int ret; | 603 | int ret; |
604 | unsigned long start_addr; | 604 | sector_t start_addr; |
605 | int dma_channel = -1; | 605 | int dma_channel = -1; |
606 | bool use_direct_dma; | 606 | bool use_direct_dma; |
607 | int count_per_dma; | 607 | int count_per_dma; |
608 | unsigned long rel_addr; | 608 | unsigned long rel_addr; |
609 | 609 | ||
610 | dbgprintf("transfer %d %d %d", card_no, start, count); | 610 | dbgprintf("transfer %d %lu %d", card_no, start, count); |
611 | mutex_lock(&sd_mtx); | 611 | mutex_lock(&sd_mtx); |
612 | enable_controller(true); | 612 | enable_controller(true); |
613 | 613 | ||
@@ -673,6 +673,7 @@ sd_transfer_retry: | |||
673 | if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS)) | 673 | if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS)) |
674 | start_addr *= SD_BLOCK_SIZE; /* not SDHC */ | 674 | start_addr *= SD_BLOCK_SIZE; /* not SDHC */ |
675 | 675 | ||
676 | // XXX 64-bit | ||
676 | ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK, | 677 | ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK, |
677 | start_addr, MMC_CMD_DCLR | MMC_CMD_DATA | | 678 | start_addr, MMC_CMD_DCLR | MMC_CMD_DATA | |
678 | SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0), | 679 | SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0), |
@@ -765,7 +766,7 @@ sd_transfer_error: | |||
765 | } | 766 | } |
766 | } | 767 | } |
767 | 768 | ||
768 | int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, | 769 | int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount, |
769 | void* inbuf) | 770 | void* inbuf) |
770 | { | 771 | { |
771 | #ifndef HAVE_MULTIDRIVE | 772 | #ifndef HAVE_MULTIDRIVE |
@@ -774,7 +775,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, | |||
774 | return sd_transfer_sectors(card_no, start, incount, inbuf, false); | 775 | return sd_transfer_sectors(card_no, start, incount, inbuf, false); |
775 | } | 776 | } |
776 | 777 | ||
777 | int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, | 778 | int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count, |
778 | const void* outbuf) | 779 | const void* outbuf) |
779 | { | 780 | { |
780 | #ifndef HAVE_MULTIDRIVE | 781 | #ifndef HAVE_MULTIDRIVE |
@@ -862,7 +863,7 @@ long sd_last_disk_activity(void) | |||
862 | } | 863 | } |
863 | 864 | ||
864 | tCardInfo *card_get_info_target(int card_no) | 865 | tCardInfo *card_get_info_target(int card_no) |
865 | { | 866 | { |
866 | return &card_info[card_no]; | 867 | return &card_info[card_no]; |
867 | } | 868 | } |
868 | 869 | ||
diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c index 6cf616184d..62eaf1f8ce 100644 --- a/firmware/target/arm/tms320dm320/system-dm320.c +++ b/firmware/target/arm/tms320dm320/system-dm320.c | |||
@@ -100,7 +100,7 @@ default_interrupt(RESERVED); | |||
100 | * change the offset for the interrupt in the entry table. | 100 | * change the offset for the interrupt in the entry table. |
101 | */ | 101 | */ |
102 | 102 | ||
103 | static const unsigned short const irqpriority[] = | 103 | static const unsigned short irqpriority[] = |
104 | { | 104 | { |
105 | IRQ_TIMER0,IRQ_TIMER1,IRQ_TIMER2,IRQ_TIMER3,IRQ_CCD_VD0,IRQ_CCD_VD1, | 105 | IRQ_TIMER0,IRQ_TIMER1,IRQ_TIMER2,IRQ_TIMER3,IRQ_CCD_VD0,IRQ_CCD_VD1, |
106 | IRQ_CCD_WEN,IRQ_VENC,IRQ_SERIAL0,IRQ_SERIAL1,IRQ_EXT_HOST,IRQ_DSPHINT, | 106 | IRQ_CCD_WEN,IRQ_VENC,IRQ_SERIAL0,IRQ_SERIAL1,IRQ_EXT_HOST,IRQ_DSPHINT, |
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c index ed130fca1f..2f2f2cb45b 100644 --- a/firmware/target/coldfire/system-coldfire.c +++ b/firmware/target/coldfire/system-coldfire.c | |||
@@ -26,6 +26,11 @@ | |||
26 | #include "lcd.h" | 26 | #include "lcd.h" |
27 | #include "font.h" | 27 | #include "font.h" |
28 | 28 | ||
29 | #if __GNUC__ >= 9 | ||
30 | #pragma GCC diagnostic push | ||
31 | #pragma GCC diagnostic ignored "-Wmissing-attributes" | ||
32 | #endif | ||
33 | |||
29 | #define default_interrupt(name) \ | 34 | #define default_interrupt(name) \ |
30 | extern __attribute__((weak,alias("UIE"))) void name (void) | 35 | extern __attribute__((weak,alias("UIE"))) void name (void) |
31 | 36 | ||
diff --git a/firmware/target/hosted/agptek/debug-agptek.c b/firmware/target/hosted/agptek/debug-agptek.c index a9b829f7ec..de4bc946bc 100644 --- a/firmware/target/hosted/agptek/debug-agptek.c +++ b/firmware/target/hosted/agptek/debug-agptek.c | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | static int line = 0; | 38 | static int line = 0; |
39 | 39 | ||
40 | extern int hwver; | ||
41 | |||
40 | bool dbg_hw_info(void) | 42 | bool dbg_hw_info(void) |
41 | { | 43 | { |
42 | int btn = 0; | 44 | int btn = 0; |
@@ -61,6 +63,10 @@ bool dbg_hw_info(void) | |||
61 | lcd_putsf(0, line++, "Boot ver: %s", verstr); | 63 | lcd_putsf(0, line++, "Boot ver: %s", verstr); |
62 | } | 64 | } |
63 | 65 | ||
66 | #ifdef EROS_Q | ||
67 | lcd_putsf(0, line++, "hwver: %d", hwver); | ||
68 | #endif | ||
69 | |||
64 | lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate()); | 70 | lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate()); |
65 | lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns()); | 71 | lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns()); |
66 | #ifdef HAVE_HEADPHONE_DETECTION | 72 | #ifdef HAVE_HEADPHONE_DETECTION |
diff --git a/firmware/target/hosted/aigo/power-erosq.c b/firmware/target/hosted/aigo/power-erosq.c index 73fa5fe972..7c4515f616 100644 --- a/firmware/target/hosted/aigo/power-erosq.c +++ b/firmware/target/hosted/aigo/power-erosq.c | |||
@@ -28,17 +28,34 @@ | |||
28 | #include "power.h" | 28 | #include "power.h" |
29 | #include "panic.h" | 29 | #include "panic.h" |
30 | #include "sysfs.h" | 30 | #include "sysfs.h" |
31 | #include "tick.h" | ||
31 | 32 | ||
32 | const char * const sysfs_bat_voltage = | 33 | const char * const sysfs_bat_voltage[2] = { |
33 | "/sys/class/power_supply/battery/voltage_now"; | 34 | "/sys/class/power_supply/battery/voltage_now", |
35 | "/sys/class/power_supply/axp_battery/voltage_now", | ||
36 | }; | ||
34 | 37 | ||
35 | const char * const sysfs_bat_capacity = | 38 | const char * const sysfs_bat_capacity[2] = { |
36 | "/sys/class/power_supply/battery/capacity"; | 39 | "/sys/class/power_supply/battery/capacity", |
40 | "/sys/class/power_supply/axp_battery/capacity", | ||
41 | }; | ||
42 | |||
43 | const char * const sysfs_bat_status[2] = { | ||
44 | "/sys/class/power_supply/battery/status", | ||
45 | "/sys/class/power_supply/axp_battery/status", | ||
46 | }; | ||
47 | |||
48 | int hwver = 1; /* Exported */ | ||
37 | 49 | ||
38 | unsigned int erosq_power_get_battery_voltage(void) | 50 | unsigned int erosq_power_get_battery_voltage(void) |
39 | { | 51 | { |
40 | int battery_voltage; | 52 | int battery_voltage; |
41 | sysfs_get_int(sysfs_bat_voltage, &battery_voltage); | 53 | int x = sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage); |
54 | |||
55 | if (!x && hwver != 4) { | ||
56 | hwver = 4; | ||
57 | sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage); | ||
58 | } | ||
42 | 59 | ||
43 | return battery_voltage/1000; | 60 | return battery_voltage/1000; |
44 | } | 61 | } |
@@ -46,7 +63,33 @@ unsigned int erosq_power_get_battery_voltage(void) | |||
46 | unsigned int erosq_power_get_battery_capacity(void) | 63 | unsigned int erosq_power_get_battery_capacity(void) |
47 | { | 64 | { |
48 | int battery_capacity; | 65 | int battery_capacity; |
49 | sysfs_get_int(sysfs_bat_capacity, &battery_capacity); | 66 | int x = sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity); |
67 | |||
68 | if (!x && hwver != 4) { | ||
69 | hwver = 4; | ||
70 | sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity); | ||
71 | } | ||
50 | 72 | ||
51 | return battery_capacity; | 73 | return battery_capacity; |
52 | } | 74 | } |
75 | |||
76 | /* We get called multiple times per tick, let's cut that back! */ | ||
77 | static long last_tick = 0; | ||
78 | static bool last_power = false; | ||
79 | |||
80 | bool charging_state(void) | ||
81 | { | ||
82 | if ((current_tick - last_tick) > HZ/2 ) { | ||
83 | char buf[12] = {0}; | ||
84 | int x = sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf)); | ||
85 | |||
86 | if (!x && hwver != 4) { | ||
87 | hwver = 4; | ||
88 | sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf)); | ||
89 | } | ||
90 | |||
91 | last_tick = current_tick; | ||
92 | last_power = (strncmp(buf, "Charging", 8) == 0); | ||
93 | } | ||
94 | return last_power; | ||
95 | } | ||
diff --git a/firmware/target/hosted/alsa-controls.h b/firmware/target/hosted/alsa-controls.h index af3e584cd9..b868ef52fb 100644 --- a/firmware/target/hosted/alsa-controls.h +++ b/firmware/target/hosted/alsa-controls.h | |||
@@ -36,6 +36,8 @@ void alsa_controls_close(void); | |||
36 | 36 | ||
37 | /* check wether a control exists */ | 37 | /* check wether a control exists */ |
38 | bool alsa_has_control(const char *name); | 38 | bool alsa_has_control(const char *name); |
39 | /* find a control element ID by name, return -1 of not found or index into array */ | ||
40 | int alsa_controls_find(const char *name); | ||
39 | /* find a control element enum index by name, return -1 if not found */ | 41 | /* find a control element enum index by name, return -1 if not found */ |
40 | int alsa_controls_find_enum(const char *name, const char *enum_name); | 42 | int alsa_controls_find_enum(const char *name, const char *enum_name); |
41 | /* set a control, potentially supports several values */ | 43 | /* set a control, potentially supports several values */ |
diff --git a/firmware/target/hosted/filesystem-hosted.h b/firmware/target/hosted/filesystem-hosted.h index b9c7ce648a..348a921f82 100644 --- a/firmware/target/hosted/filesystem-hosted.h +++ b/firmware/target/hosted/filesystem-hosted.h | |||
@@ -21,9 +21,6 @@ | |||
21 | #ifndef _FILESYSTEM_HOSTED_H_ | 21 | #ifndef _FILESYSTEM_HOSTED_H_ |
22 | #define _FILESYSTEM_HOSTED_H_ | 22 | #define _FILESYSTEM_HOSTED_H_ |
23 | 23 | ||
24 | #include "mv.h" | ||
25 | |||
26 | int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize); | ||
27 | void * os_lc_open(const char *ospath); | 24 | void * os_lc_open(const char *ospath); |
28 | 25 | ||
29 | #endif /* _FILESYSTEM_HOSTED_H_ */ | 26 | #endif /* _FILESYSTEM_HOSTED_H_ */ |
diff --git a/firmware/target/hosted/filesystem-unix.c b/firmware/target/hosted/filesystem-unix.c index f0d7de640d..4869d07263 100644 --- a/firmware/target/hosted/filesystem-unix.c +++ b/firmware/target/hosted/filesystem-unix.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include "pathfuncs.h" | 33 | #include "pathfuncs.h" |
34 | #include "string-extra.h" | 34 | #include "string-extra.h" |
35 | 35 | ||
36 | int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize); | ||
37 | |||
36 | #define SAME_FILE_INFO(sb1p, sb2p) \ | 38 | #define SAME_FILE_INFO(sb1p, sb2p) \ |
37 | ((sb1p)->st_dev == (sb2p)->st_dev && (sb1p)->st_ino == (sb2p)->st_ino) | 39 | ((sb1p)->st_dev == (sb2p)->st_dev && (sb1p)->st_ino == (sb2p)->st_ino) |
38 | 40 | ||
@@ -207,9 +209,9 @@ int os_opendir_and_fd(const char *osdirname, DIR **osdirpp, int *osfdp) | |||
207 | } | 209 | } |
208 | 210 | ||
209 | /* do we really need this in the app? (in the sim, yes) */ | 211 | /* do we really need this in the app? (in the sim, yes) */ |
210 | void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) | 212 | void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep) |
211 | { | 213 | { |
212 | unsigned long size = 0, free = 0; | 214 | sector_t size = 0, free = 0; |
213 | char volpath[MAX_PATH]; | 215 | char volpath[MAX_PATH]; |
214 | struct statfs fs; | 216 | struct statfs fs; |
215 | 217 | ||
diff --git a/firmware/target/hosted/filesystem-win32.c b/firmware/target/hosted/filesystem-win32.c index fac10d003b..ebb7f283ac 100644 --- a/firmware/target/hosted/filesystem-win32.c +++ b/firmware/target/hosted/filesystem-win32.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "debug.h" | 30 | #include "debug.h" |
31 | #include "pathfuncs.h" | 31 | #include "pathfuncs.h" |
32 | #include "string-extra.h" | 32 | #include "string-extra.h" |
33 | #include "mv.h" | ||
33 | 34 | ||
34 | #define SAME_FILE_INFO(lpInfo1, lpInfo2) \ | 35 | #define SAME_FILE_INFO(lpInfo1, lpInfo2) \ |
35 | ((lpInfo1)->dwVolumeSerialNumber == (lpInfo2)->dwVolumeSerialNumber && \ | 36 | ((lpInfo1)->dwVolumeSerialNumber == (lpInfo2)->dwVolumeSerialNumber && \ |
@@ -469,7 +470,9 @@ int os_modtime(const char *path, time_t modtime) | |||
469 | return 0; | 470 | return 0; |
470 | } | 471 | } |
471 | 472 | ||
472 | void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) | 473 | int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize); |
474 | |||
475 | void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep) | ||
473 | { | 476 | { |
474 | ULARGE_INTEGER free = { .QuadPart = 0 }, | 477 | ULARGE_INTEGER free = { .QuadPart = 0 }, |
475 | size = { .QuadPart = 0 }; | 478 | size = { .QuadPart = 0 }; |
diff --git a/firmware/target/hosted/lcd-linuxfb.c b/firmware/target/hosted/lcd-linuxfb.c index 14c8c30f89..5dda5cf1cc 100644 --- a/firmware/target/hosted/lcd-linuxfb.c +++ b/firmware/target/hosted/lcd-linuxfb.c | |||
@@ -59,14 +59,21 @@ void lcd_init_device(void) | |||
59 | panicf("Cannot read framebuffer fixed information"); | 59 | panicf("Cannot read framebuffer fixed information"); |
60 | } | 60 | } |
61 | 61 | ||
62 | #if 0 | 62 | if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) |
63 | /* check resolution and framebuffer size */ | ||
64 | if(vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT || vinfo.bits_per_pixel != LCD_DEPTH) | ||
65 | { | 63 | { |
66 | panicf("Unexpected framebuffer resolution: %dx%dx%d\n", vinfo.xres, | 64 | panicf("Cannot read framebuffer variable information"); |
67 | vinfo.yres, vinfo.bits_per_pixel); | 65 | } |
66 | |||
67 | /* Make sure we match our desired bitdepth */ | ||
68 | if (vinfo.bits_per_pixel != LCD_DEPTH || vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT) { | ||
69 | vinfo.bits_per_pixel = LCD_DEPTH; | ||
70 | vinfo.xres = LCD_WIDTH; | ||
71 | vinfo.yres = LCD_HEIGHT; | ||
72 | if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) { | ||
73 | panicf("Cannot set framebuffer to %dx%dx%d", | ||
74 | vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); | ||
75 | } | ||
68 | } | 76 | } |
69 | #endif | ||
70 | /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the | 77 | /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the |
71 | * values returned by the driver for line_length */ | 78 | * values returned by the driver for line_length */ |
72 | 79 | ||
@@ -77,11 +84,6 @@ void lcd_init_device(void) | |||
77 | panicf("Cannot map framebuffer"); | 84 | panicf("Cannot map framebuffer"); |
78 | } | 85 | } |
79 | 86 | ||
80 | if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) | ||
81 | { | ||
82 | panicf("Cannot read framebuffer variable information"); | ||
83 | } | ||
84 | |||
85 | memset(framebuffer, 0, finfo.smem_len); | 87 | memset(framebuffer, 0, finfo.smem_len); |
86 | 88 | ||
87 | #ifdef HAVE_LCD_ENABLE | 89 | #ifdef HAVE_LCD_ENABLE |
diff --git a/firmware/target/hosted/power-linux.c b/firmware/target/hosted/power-linux.c index ddd7ad63e3..8d263eebec 100644 --- a/firmware/target/hosted/power-linux.c +++ b/firmware/target/hosted/power-linux.c | |||
@@ -33,9 +33,13 @@ | |||
33 | #include "usb.h" | 33 | #include "usb.h" |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #ifdef BATTERY_DEV_NAME | ||
36 | #define BATTERY_STATUS_PATH "/sys/class/power_supply/" BATTERY_DEV_NAME "/status" | 37 | #define BATTERY_STATUS_PATH "/sys/class/power_supply/" BATTERY_DEV_NAME "/status" |
38 | #endif | ||
39 | |||
37 | #define POWER_STATUS_PATH "/sys/class/power_supply/" POWER_DEV_NAME "/online" | 40 | #define POWER_STATUS_PATH "/sys/class/power_supply/" POWER_DEV_NAME "/online" |
38 | 41 | ||
42 | #ifdef BATTERY_DEV_NAME | ||
39 | /* We get called multiple times per tick, let's cut that back! */ | 43 | /* We get called multiple times per tick, let's cut that back! */ |
40 | static long last_tick = 0; | 44 | static long last_tick = 0; |
41 | static bool last_power = false; | 45 | static bool last_power = false; |
@@ -51,6 +55,7 @@ bool charging_state(void) | |||
51 | } | 55 | } |
52 | return last_power; | 56 | return last_power; |
53 | } | 57 | } |
58 | #endif | ||
54 | 59 | ||
55 | unsigned int power_input_status(void) | 60 | unsigned int power_input_status(void) |
56 | { | 61 | { |
diff --git a/firmware/target/hosted/sdl/app/button-application.c b/firmware/target/hosted/sdl/app/button-application.c index 9c313b76b1..8071df201a 100644 --- a/firmware/target/hosted/sdl/app/button-application.c +++ b/firmware/target/hosted/sdl/app/button-application.c | |||
@@ -40,23 +40,23 @@ int key_to_button(int keyboard_key) | |||
40 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) | 40 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) |
41 | case SDLK_ESCAPE: | 41 | case SDLK_ESCAPE: |
42 | #endif | 42 | #endif |
43 | case SDLK_KP7: | 43 | case SDLK_KP_7: |
44 | new_btn = BUTTON_TOPLEFT; | 44 | new_btn = BUTTON_TOPLEFT; |
45 | break; | 45 | break; |
46 | case SDLK_KP8: | 46 | case SDLK_KP_8: |
47 | case SDLK_UP: | 47 | case SDLK_UP: |
48 | new_btn = BUTTON_TOPMIDDLE; | 48 | new_btn = BUTTON_TOPMIDDLE; |
49 | break; | 49 | break; |
50 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) | 50 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) |
51 | case SDLK_F7: | 51 | case SDLK_F7: |
52 | #endif | 52 | #endif |
53 | case SDLK_KP9: | 53 | case SDLK_KP_9: |
54 | new_btn = BUTTON_TOPRIGHT; | 54 | new_btn = BUTTON_TOPRIGHT; |
55 | break; | 55 | break; |
56 | #if (CONFIG_PLATFORM & PLATFORM_PANDORA) | 56 | #if (CONFIG_PLATFORM & PLATFORM_PANDORA) |
57 | case SDLK_RSHIFT: | 57 | case SDLK_RSHIFT: |
58 | #endif | 58 | #endif |
59 | case SDLK_KP4: | 59 | case SDLK_KP_4: |
60 | case SDLK_LEFT: | 60 | case SDLK_LEFT: |
61 | new_btn = BUTTON_MIDLEFT; | 61 | new_btn = BUTTON_MIDLEFT; |
62 | break; | 62 | break; |
@@ -64,40 +64,32 @@ int key_to_button(int keyboard_key) | |||
64 | case SDLK_RETURN: | 64 | case SDLK_RETURN: |
65 | case SDLK_KP_ENTER: | 65 | case SDLK_KP_ENTER: |
66 | #endif | 66 | #endif |
67 | case SDLK_KP5: | 67 | case SDLK_KP_5: |
68 | new_btn = BUTTON_CENTER; | 68 | new_btn = BUTTON_CENTER; |
69 | break; | 69 | break; |
70 | #if (CONFIG_PLATFORM & PLATFORM_PANDORA) | 70 | #if (CONFIG_PLATFORM & PLATFORM_PANDORA) |
71 | case SDLK_RCTRL: | 71 | case SDLK_RCTRL: |
72 | #endif | 72 | #endif |
73 | case SDLK_KP6: | 73 | case SDLK_KP_6: |
74 | case SDLK_RIGHT: | 74 | case SDLK_RIGHT: |
75 | new_btn = BUTTON_MIDRIGHT; | 75 | new_btn = BUTTON_MIDRIGHT; |
76 | break; | 76 | break; |
77 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) | 77 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) |
78 | case SDLK_F6: | 78 | case SDLK_F6: |
79 | #endif | 79 | #endif |
80 | case SDLK_KP1: | 80 | case SDLK_KP_1: |
81 | new_btn = BUTTON_BOTTOMLEFT; | 81 | new_btn = BUTTON_BOTTOMLEFT; |
82 | break; | 82 | break; |
83 | case SDLK_KP2: | 83 | case SDLK_KP_2: |
84 | case SDLK_DOWN: | 84 | case SDLK_DOWN: |
85 | new_btn = BUTTON_BOTTOMMIDDLE; | 85 | new_btn = BUTTON_BOTTOMMIDDLE; |
86 | break; | 86 | break; |
87 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) | 87 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO4) |
88 | case SDLK_F8: | 88 | case SDLK_F8: |
89 | #endif | 89 | #endif |
90 | case SDLK_KP3: | 90 | case SDLK_KP_3: |
91 | new_btn = BUTTON_BOTTOMRIGHT; | 91 | new_btn = BUTTON_BOTTOMRIGHT; |
92 | break; | 92 | break; |
93 | #ifdef HAVE_SCROLLWHEEL | ||
94 | case SDL_BUTTON_WHEELUP: | ||
95 | new_btn = BUTTON_SCROLL_BACK; | ||
96 | break; | ||
97 | case SDL_BUTTON_WHEELDOWN: | ||
98 | new_btn = BUTTON_SCROLL_FWD; | ||
99 | break; | ||
100 | #endif | ||
101 | case SDL_BUTTON_RIGHT: | 93 | case SDL_BUTTON_RIGHT: |
102 | new_btn = BUTTON_MIDLEFT; | 94 | new_btn = BUTTON_MIDLEFT; |
103 | break; | 95 | break; |
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c index 1055d7e0b9..8af6f3ffaf 100644 --- a/firmware/target/hosted/sdl/button-sdl.c +++ b/firmware/target/hosted/sdl/button-sdl.c | |||
@@ -107,6 +107,30 @@ static void touchscreen_event(int x, int y) | |||
107 | } | 107 | } |
108 | #endif | 108 | #endif |
109 | 109 | ||
110 | #if defined(HAVE_SCROLLWHEEL) || ((defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK))) | ||
111 | static void scrollwheel_event(int x, int y) | ||
112 | { | ||
113 | int new_btn = 0; | ||
114 | if (y > 0) | ||
115 | new_btn = BUTTON_SCROLL_BACK; | ||
116 | else if (y < 0) | ||
117 | new_btn = BUTTON_SCROLL_FWD; | ||
118 | else | ||
119 | return; | ||
120 | |||
121 | #ifdef HAVE_BACKLIGHT | ||
122 | backlight_on(); | ||
123 | #endif | ||
124 | #ifdef HAVE_BUTTON_LIGHT | ||
125 | buttonlight_on(); | ||
126 | #endif | ||
127 | reset_poweroff_timer(); | ||
128 | if (new_btn && !queue_full(&button_queue)) | ||
129 | queue_post(&button_queue, new_btn, 1<<24); | ||
130 | |||
131 | (void)x; | ||
132 | } | ||
133 | #endif | ||
110 | static void mouse_event(SDL_MouseButtonEvent *event, bool button_up) | 134 | static void mouse_event(SDL_MouseButtonEvent *event, bool button_up) |
111 | { | 135 | { |
112 | #define SQUARE(x) ((x)*(x)) | 136 | #define SQUARE(x) ((x)*(x)) |
@@ -118,10 +142,6 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up) | |||
118 | if(button_up) { | 142 | if(button_up) { |
119 | switch ( event->button ) | 143 | switch ( event->button ) |
120 | { | 144 | { |
121 | #ifdef HAVE_SCROLLWHEEL | ||
122 | case SDL_BUTTON_WHEELUP: | ||
123 | case SDL_BUTTON_WHEELDOWN: | ||
124 | #endif | ||
125 | case SDL_BUTTON_MIDDLE: | 145 | case SDL_BUTTON_MIDDLE: |
126 | case SDL_BUTTON_RIGHT: | 146 | case SDL_BUTTON_RIGHT: |
127 | button_event( event->button, false ); | 147 | button_event( event->button, false ); |
@@ -145,13 +165,9 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up) | |||
145 | #endif | 165 | #endif |
146 | break; | 166 | break; |
147 | } | 167 | } |
148 | } else { /* button down */ | 168 | } else { /* button down */ |
149 | switch ( event->button ) | 169 | switch ( event->button ) |
150 | { | 170 | { |
151 | #ifdef HAVE_SCROLLWHEEL | ||
152 | case SDL_BUTTON_WHEELUP: | ||
153 | case SDL_BUTTON_WHEELDOWN: | ||
154 | #endif | ||
155 | case SDL_BUTTON_MIDDLE: | 171 | case SDL_BUTTON_MIDDLE: |
156 | case SDL_BUTTON_RIGHT: | 172 | case SDL_BUTTON_RIGHT: |
157 | button_event( event->button, true ); | 173 | button_event( event->button, true ); |
@@ -215,18 +231,15 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up) | |||
215 | 231 | ||
216 | static bool event_handler(SDL_Event *event) | 232 | static bool event_handler(SDL_Event *event) |
217 | { | 233 | { |
218 | SDLKey ev_key; | 234 | SDL_Keycode ev_key; |
219 | 235 | ||
220 | switch(event->type) | 236 | switch(event->type) |
221 | { | 237 | { |
222 | case SDL_ACTIVEEVENT: | 238 | case SDL_WINDOWEVENT: |
223 | if (event->active.state & SDL_APPINPUTFOCUS) | 239 | if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) |
224 | { | 240 | sdl_app_has_input_focus = 1; |
225 | if (event->active.gain == 1) | 241 | else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) |
226 | sdl_app_has_input_focus = 1; | 242 | sdl_app_has_input_focus = 0; |
227 | else | ||
228 | sdl_app_has_input_focus = 0; | ||
229 | } | ||
230 | break; | 243 | break; |
231 | case SDL_KEYDOWN: | 244 | case SDL_KEYDOWN: |
232 | case SDL_KEYUP: | 245 | case SDL_KEYUP: |
@@ -275,6 +288,13 @@ static bool event_handler(SDL_Event *event) | |||
275 | mouse_event(mev, event->type == SDL_MOUSEBUTTONUP); | 288 | mouse_event(mev, event->type == SDL_MOUSEBUTTONUP); |
276 | break; | 289 | break; |
277 | } | 290 | } |
291 | #ifdef HAVE_SCROLLWHEEL | ||
292 | case SDL_MOUSEWHEEL: | ||
293 | { | ||
294 | scrollwheel_event(event->wheel.x, event->wheel.y); | ||
295 | break; | ||
296 | } | ||
297 | #endif | ||
278 | case SDL_QUIT: | 298 | case SDL_QUIT: |
279 | /* Will post SDL_USEREVENT in shutdown_hw() if successful. */ | 299 | /* Will post SDL_USEREVENT in shutdown_hw() if successful. */ |
280 | sdl_sys_quit(); | 300 | sdl_sys_quit(); |
@@ -340,7 +360,7 @@ static void button_event(int key, bool pressed) | |||
340 | } | 360 | } |
341 | return; | 361 | return; |
342 | #endif | 362 | #endif |
343 | #ifdef HAVE_MULTIDRIVE | 363 | #ifdef HAVE_HOTSWAP |
344 | case EXT_KEY: | 364 | case EXT_KEY: |
345 | if (!pressed) | 365 | if (!pressed) |
346 | sim_trigger_external(!storage_present(1)); | 366 | sim_trigger_external(!storage_present(1)); |
@@ -362,7 +382,7 @@ static void button_event(int key, bool pressed) | |||
362 | } | 382 | } |
363 | return; | 383 | return; |
364 | #endif | 384 | #endif |
365 | 385 | ||
366 | #ifdef HAS_REMOTE_BUTTON_HOLD | 386 | #ifdef HAS_REMOTE_BUTTON_HOLD |
367 | case SDLK_j: | 387 | case SDLK_j: |
368 | if(pressed) | 388 | if(pressed) |
@@ -379,7 +399,7 @@ static void button_event(int key, bool pressed) | |||
379 | if(pressed) | 399 | if(pressed) |
380 | switch(_remote_type) | 400 | switch(_remote_type) |
381 | { | 401 | { |
382 | case REMOTETYPE_UNPLUGGED: | 402 | case REMOTETYPE_UNPLUGGED: |
383 | _remote_type=REMOTETYPE_H100_LCD; | 403 | _remote_type=REMOTETYPE_H100_LCD; |
384 | DEBUGF("Changed remote type to H100\n"); | 404 | DEBUGF("Changed remote type to H100\n"); |
385 | break; | 405 | break; |
@@ -399,7 +419,7 @@ static void button_event(int key, bool pressed) | |||
399 | break; | 419 | break; |
400 | #endif | 420 | #endif |
401 | #ifndef APPLICATION | 421 | #ifndef APPLICATION |
402 | case SDLK_KP0: | 422 | case SDLK_KP_0: |
403 | case SDLK_F5: | 423 | case SDLK_F5: |
404 | if(pressed) | 424 | if(pressed) |
405 | { | 425 | { |
@@ -430,32 +450,17 @@ static void button_event(int key, bool pressed) | |||
430 | #endif | 450 | #endif |
431 | break; | 451 | break; |
432 | } | 452 | } |
433 | /* Call to make up for scrollwheel target implementation. This is | 453 | |
434 | * not handled in the main button.c driver, but on the target | ||
435 | * implementation (look at button-e200.c for example if you are trying to | ||
436 | * figure out why using button_get_data needed a hack before). | ||
437 | */ | ||
438 | #if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK) | 454 | #if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK) |
439 | if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) && | 455 | if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) && |
440 | pressed) | 456 | pressed) |
441 | { | 457 | { |
442 | /* Clear these buttons from the data - adding them to the queue is | 458 | scrollwheel_event(0, new_btn == BUTTON_SCROLL_FWD ? -1 : 1); |
443 | * handled in the scrollwheel drivers for the targets. They do not | ||
444 | * store the scroll forward/back buttons in their button data for | ||
445 | * the button_read call. | ||
446 | */ | ||
447 | #ifdef HAVE_BACKLIGHT | ||
448 | backlight_on(); | ||
449 | #endif | ||
450 | #ifdef HAVE_BUTTON_LIGHT | ||
451 | buttonlight_on(); | ||
452 | #endif | ||
453 | reset_poweroff_timer(); | ||
454 | queue_post(&button_queue, new_btn, 1<<24); | ||
455 | new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK); | 459 | new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK); |
456 | } | 460 | } |
457 | #endif | 461 | #endif |
458 | 462 | ||
463 | /* Update global button press state */ | ||
459 | if (pressed) | 464 | if (pressed) |
460 | btn |= new_btn; | 465 | btn |= new_btn; |
461 | else | 466 | else |
@@ -496,5 +501,4 @@ int button_read_device(void) | |||
496 | 501 | ||
497 | void button_init_device(void) | 502 | void button_init_device(void) |
498 | { | 503 | { |
499 | SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); | ||
500 | } | 504 | } |
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c index 5c16f86749..bcad39b4d8 100644 --- a/firmware/target/hosted/sdl/kernel-sdl.c +++ b/firmware/target/hosted/sdl/kernel-sdl.c | |||
@@ -153,7 +153,7 @@ void sim_kernel_shutdown(void) | |||
153 | SDL_Delay(10); | 153 | SDL_Delay(10); |
154 | 154 | ||
155 | SDL_DestroyMutex(sim_irq_mtx); | 155 | SDL_DestroyMutex(sim_irq_mtx); |
156 | SDL_DestroyCond(sim_thread_cond); | 156 | SDL_DestroyCond(sim_thread_cond); |
157 | } | 157 | } |
158 | 158 | ||
159 | Uint32 tick_timer(Uint32 interval, void *param) | 159 | Uint32 tick_timer(Uint32 interval, void *param) |
@@ -162,9 +162,9 @@ Uint32 tick_timer(Uint32 interval, void *param) | |||
162 | 162 | ||
163 | (void) interval; | 163 | (void) interval; |
164 | (void) param; | 164 | (void) param; |
165 | 165 | ||
166 | new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); | 166 | new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); |
167 | 167 | ||
168 | while(new_tick != current_tick) | 168 | while(new_tick != current_tick) |
169 | { | 169 | { |
170 | sim_enter_irq_handler(); | 170 | sim_enter_irq_handler(); |
@@ -175,7 +175,7 @@ Uint32 tick_timer(Uint32 interval, void *param) | |||
175 | 175 | ||
176 | sim_exit_irq_handler(); | 176 | sim_exit_irq_handler(); |
177 | } | 177 | } |
178 | 178 | ||
179 | return interval; | 179 | return interval; |
180 | } | 180 | } |
181 | 181 | ||
@@ -187,10 +187,10 @@ void tick_start(unsigned int interval_in_ms) | |||
187 | exit(-1); | 187 | exit(-1); |
188 | } | 188 | } |
189 | 189 | ||
190 | if (tick_timer_id != NULL) | 190 | if (tick_timer_id != 0) |
191 | { | 191 | { |
192 | SDL_RemoveTimer(tick_timer_id); | 192 | SDL_RemoveTimer(tick_timer_id); |
193 | tick_timer_id = NULL; | 193 | tick_timer_id = 0; |
194 | } | 194 | } |
195 | else | 195 | else |
196 | { | 196 | { |
diff --git a/firmware/target/hosted/sdl/key_to_touch-sdl.c b/firmware/target/hosted/sdl/key_to_touch-sdl.c index d56d06ba74..b7052e043f 100644 --- a/firmware/target/hosted/sdl/key_to_touch-sdl.c +++ b/firmware/target/hosted/sdl/key_to_touch-sdl.c | |||
@@ -52,12 +52,12 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords) | |||
52 | } | 52 | } |
53 | break; | 53 | break; |
54 | #ifndef APPLICATION | 54 | #ifndef APPLICATION |
55 | case SDLK_KP7: | 55 | case SDLK_KP_7: |
56 | case SDLK_7: | 56 | case SDLK_7: |
57 | case SDLK_HOME: | 57 | case SDLK_HOME: |
58 | new_btn = BUTTON_TOPLEFT; | 58 | new_btn = BUTTON_TOPLEFT; |
59 | break; | 59 | break; |
60 | case SDLK_KP8: | 60 | case SDLK_KP_8: |
61 | case SDLK_8: | 61 | case SDLK_8: |
62 | case SDLK_UP: | 62 | case SDLK_UP: |
63 | #ifdef HAVE_SCROLLWHEEL | 63 | #ifdef HAVE_SCROLLWHEEL |
@@ -65,32 +65,32 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords) | |||
65 | #endif | 65 | #endif |
66 | new_btn = BUTTON_TOPMIDDLE; | 66 | new_btn = BUTTON_TOPMIDDLE; |
67 | break; | 67 | break; |
68 | case SDLK_KP9: | 68 | case SDLK_KP_9: |
69 | case SDLK_9: | 69 | case SDLK_9: |
70 | case SDLK_PAGEUP: | 70 | case SDLK_PAGEUP: |
71 | new_btn = BUTTON_TOPRIGHT; | 71 | new_btn = BUTTON_TOPRIGHT; |
72 | break; | 72 | break; |
73 | case SDLK_KP4: | 73 | case SDLK_KP_4: |
74 | case SDLK_u: | 74 | case SDLK_u: |
75 | case SDLK_LEFT: | 75 | case SDLK_LEFT: |
76 | new_btn = BUTTON_MIDLEFT; | 76 | new_btn = BUTTON_MIDLEFT; |
77 | break; | 77 | break; |
78 | case SDLK_KP5: | 78 | case SDLK_KP_5: |
79 | case SDLK_i: | 79 | case SDLK_i: |
80 | case SDL_BUTTON_MIDDLE: | 80 | case SDL_BUTTON_MIDDLE: |
81 | new_btn = BUTTON_CENTER; | 81 | new_btn = BUTTON_CENTER; |
82 | break; | 82 | break; |
83 | case SDLK_KP6: | 83 | case SDLK_KP_6: |
84 | case SDLK_o: | 84 | case SDLK_o: |
85 | case SDLK_RIGHT: | 85 | case SDLK_RIGHT: |
86 | new_btn = BUTTON_MIDRIGHT; | 86 | new_btn = BUTTON_MIDRIGHT; |
87 | break; | 87 | break; |
88 | case SDLK_KP1: | 88 | case SDLK_KP_1: |
89 | case SDLK_j: | 89 | case SDLK_j: |
90 | case SDLK_END: | 90 | case SDLK_END: |
91 | new_btn = BUTTON_BOTTOMLEFT; | 91 | new_btn = BUTTON_BOTTOMLEFT; |
92 | break; | 92 | break; |
93 | case SDLK_KP2: | 93 | case SDLK_KP_2: |
94 | case SDLK_k: | 94 | case SDLK_k: |
95 | #ifdef HAVE_SCROLLWHEEL | 95 | #ifdef HAVE_SCROLLWHEEL |
96 | case SDL_BUTTON_WHEELDOWN: | 96 | case SDL_BUTTON_WHEELDOWN: |
@@ -98,7 +98,7 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords) | |||
98 | case SDLK_DOWN: | 98 | case SDLK_DOWN: |
99 | new_btn = BUTTON_BOTTOMMIDDLE; | 99 | new_btn = BUTTON_BOTTOMMIDDLE; |
100 | break; | 100 | break; |
101 | case SDLK_KP3: | 101 | case SDLK_KP_3: |
102 | case SDLK_l: | 102 | case SDLK_l: |
103 | case SDLK_PAGEDOWN: | 103 | case SDLK_PAGEDOWN: |
104 | new_btn = BUTTON_BOTTOMRIGHT; | 104 | new_btn = BUTTON_BOTTOMRIGHT; |
@@ -106,4 +106,5 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords) | |||
106 | #endif | 106 | #endif |
107 | } | 107 | } |
108 | return new_btn; | 108 | return new_btn; |
109 | |||
109 | } | 110 | } |
diff --git a/firmware/target/hosted/sdl/lcd-bitmap.c b/firmware/target/hosted/sdl/lcd-bitmap.c index ea30afea3b..ef284eeb48 100644 --- a/firmware/target/hosted/sdl/lcd-bitmap.c +++ b/firmware/target/hosted/sdl/lcd-bitmap.c | |||
@@ -164,12 +164,12 @@ void sim_backlight(int value) | |||
164 | #else /* LCD_DEPTH > 8 */ | 164 | #else /* LCD_DEPTH > 8 */ |
165 | #if defined(HAVE_TRANSFLECTIVE_LCD) && defined(HAVE_LCD_SLEEP) | 165 | #if defined(HAVE_TRANSFLECTIVE_LCD) && defined(HAVE_LCD_SLEEP) |
166 | if (!lcd_active()) | 166 | if (!lcd_active()) |
167 | SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, 0); | 167 | SDL_SetSurfaceAlphaMod(lcd_surface, 0); |
168 | else | 168 | else |
169 | SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, | 169 | SDL_SetSurfaceAlphaMod(lcd_surface, |
170 | MAX(BACKLIGHT_OFF_ALPHA, (value * 255) / 100)); | 170 | MAX(BACKLIGHT_OFF_ALPHA, (value * 255) / 100)); |
171 | #else | 171 | #else |
172 | SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, (value * 255) / 100); | 172 | SDL_SetSurfaceAlphaMod(lcd_surface, (value * 255) / 100); |
173 | #endif | 173 | #endif |
174 | #endif /* LCD_DEPTH */ | 174 | #endif /* LCD_DEPTH */ |
175 | 175 | ||
@@ -187,6 +187,7 @@ void lcd_init_device(void) | |||
187 | SIM_LCD_WIDTH * display_zoom, | 187 | SIM_LCD_WIDTH * display_zoom, |
188 | SIM_LCD_HEIGHT * display_zoom, | 188 | SIM_LCD_HEIGHT * display_zoom, |
189 | LCD_DEPTH, 0, 0, 0, 0); | 189 | LCD_DEPTH, 0, 0, 0, 0); |
190 | SDL_SetSurfaceBlendMode(lcd_surface, SDL_BLENDMODE_BLEND); | ||
190 | #elif LCD_DEPTH <= 8 | 191 | #elif LCD_DEPTH <= 8 |
191 | lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, | 192 | lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
192 | SIM_LCD_WIDTH * display_zoom, | 193 | SIM_LCD_WIDTH * display_zoom, |
@@ -222,7 +223,7 @@ void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height) | |||
222 | if (lcd_ex_getpixel) { | 223 | if (lcd_ex_getpixel) { |
223 | sdl_update_rect(lcd_surface, x_start, y_start, width, height, | 224 | sdl_update_rect(lcd_surface, x_start, y_start, width, height, |
224 | LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel); | 225 | LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel); |
225 | sdl_gui_update(lcd_surface, x_start, y_start, width, | 226 | sdl_gui_update(lcd_surface, x_start, y_start, width, |
226 | height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT, | 227 | height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT, |
227 | background ? UI_LCD_POSX : 0, | 228 | background ? UI_LCD_POSX : 0, |
228 | background ? UI_LCD_POSY : 0); | 229 | background ? UI_LCD_POSY : 0); |
diff --git a/firmware/target/hosted/sdl/lcd-sdl.c b/firmware/target/hosted/sdl/lcd-sdl.c index 8cbb6c5651..1e9daeffd3 100644 --- a/firmware/target/hosted/sdl/lcd-sdl.c +++ b/firmware/target/hosted/sdl/lcd-sdl.c | |||
@@ -115,12 +115,17 @@ void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width, | |||
115 | (ui_y + y_start) * display_zoom, | 115 | (ui_y + y_start) * display_zoom, |
116 | width * display_zoom, height * display_zoom}; | 116 | width * display_zoom, height * display_zoom}; |
117 | 117 | ||
118 | if (surface->flags & SDL_SRCALPHA) /* alpha needs a black background */ | 118 | uint8_t alpha; |
119 | if (SDL_GetSurfaceAlphaMod(surface,&alpha) == 0 && alpha < 255) | ||
119 | SDL_FillRect(gui_surface, &dest, 0); | 120 | SDL_FillRect(gui_surface, &dest, 0); |
120 | 121 | ||
121 | SDL_BlitSurface(surface, &src, gui_surface, &dest); | 122 | SDL_BlitSurface(surface, &src, gui_surface, &dest); /* alpha needs a black background */ |
122 | 123 | ||
123 | SDL_Flip(gui_surface); | 124 | SDL_Texture *sdlTexture = SDL_CreateTextureFromSurface(sdlRenderer, gui_surface); |
125 | SDL_RenderClear(sdlRenderer); | ||
126 | SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL); | ||
127 | SDL_RenderPresent(sdlRenderer); | ||
128 | SDL_DestroyTexture(sdlTexture); | ||
124 | } | 129 | } |
125 | 130 | ||
126 | /* set a range of bitmap indices to a gradient from startcolour to endcolour */ | 131 | /* set a range of bitmap indices to a gradient from startcolour to endcolour */ |
@@ -136,7 +141,7 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, | |||
136 | palette[i].b = start->b + (end->b - start->b) * i / (steps - 1); | 141 | palette[i].b = start->b + (end->b - start->b) * i / (steps - 1); |
137 | } | 142 | } |
138 | 143 | ||
139 | SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, first, steps); | 144 | SDL_SetPaletteColors(surface->format->palette, palette, first , steps); |
140 | } | 145 | } |
141 | 146 | ||
142 | int lcd_get_dpi(void) | 147 | int lcd_get_dpi(void) |
diff --git a/firmware/target/hosted/sdl/lcd-sdl.h b/firmware/target/hosted/sdl/lcd-sdl.h index a964c9bc40..3f1334e4a2 100644 --- a/firmware/target/hosted/sdl/lcd-sdl.h +++ b/firmware/target/hosted/sdl/lcd-sdl.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | /* Default display zoom level */ | 28 | /* Default display zoom level */ |
29 | extern SDL_Surface *gui_surface; | 29 | extern SDL_Surface *gui_surface; |
30 | extern SDL_Renderer *sdlRenderer; | ||
30 | 31 | ||
31 | void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width, | 32 | void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width, |
32 | int height, int max_x, int max_y, | 33 | int height, int max_x, int max_y, |
@@ -39,4 +40,3 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, | |||
39 | int first, int steps); | 40 | int first, int steps); |
40 | 41 | ||
41 | #endif /* #ifndef __LCDSDL_H__ */ | 42 | #endif /* #ifndef __LCDSDL_H__ */ |
42 | |||
diff --git a/firmware/target/hosted/sdl/pcm-sdl.c b/firmware/target/hosted/sdl/pcm-sdl.c index 940403002f..dec12af2f1 100644 --- a/firmware/target/hosted/sdl/pcm-sdl.c +++ b/firmware/target/hosted/sdl/pcm-sdl.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * __________ __ ___. | 2 | * __________ __ ___. |
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2005 by Nick Lanham | 10 | * Copyright (C) 2005 by Nick Lanham |
@@ -85,8 +85,43 @@ void pcm_play_unlock(void) | |||
85 | SDL_UnlockMutex(audio_lock); | 85 | SDL_UnlockMutex(audio_lock); |
86 | } | 86 | } |
87 | 87 | ||
88 | static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len); | ||
88 | static void pcm_dma_apply_settings_nolock(void) | 89 | static void pcm_dma_apply_settings_nolock(void) |
89 | { | 90 | { |
91 | SDL_AudioSpec wanted_spec; | ||
92 | wanted_spec.freq = pcm_sampr; | ||
93 | wanted_spec.format = AUDIO_S16SYS; | ||
94 | wanted_spec.channels = 2; | ||
95 | wanted_spec.samples = 2048; | ||
96 | wanted_spec.callback = | ||
97 | (void (SDLCALL *)(void *userdata, | ||
98 | Uint8 *stream, int len))sdl_audio_callback; | ||
99 | wanted_spec.userdata = &udata; | ||
100 | SDL_CloseAudio(); | ||
101 | /* Open the audio device and start playing sound! */ | ||
102 | if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) { | ||
103 | DEBUGF("Unable to open audio: %s\n", SDL_GetError()); | ||
104 | return; | ||
105 | } | ||
106 | switch (obtained.format) | ||
107 | { | ||
108 | case AUDIO_U8: | ||
109 | case AUDIO_S8: | ||
110 | pcm_channel_bytes = 1; | ||
111 | break; | ||
112 | case AUDIO_U16LSB: | ||
113 | case AUDIO_S16LSB: | ||
114 | case AUDIO_U16MSB: | ||
115 | case AUDIO_S16MSB: | ||
116 | pcm_channel_bytes = 2; | ||
117 | break; | ||
118 | default: | ||
119 | DEBUGF("Unknown sample format obtained: %u\n", | ||
120 | (unsigned)obtained.format); | ||
121 | return; | ||
122 | } | ||
123 | pcm_sample_bytes = obtained.channels * pcm_channel_bytes; | ||
124 | |||
90 | cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr, | 125 | cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr, |
91 | obtained.format, obtained.channels, obtained.freq); | 126 | obtained.format, obtained.channels, obtained.freq); |
92 | 127 | ||
@@ -104,7 +139,6 @@ void pcm_dma_apply_settings(void) | |||
104 | 139 | ||
105 | void pcm_play_dma_start(const void *addr, size_t size) | 140 | void pcm_play_dma_start(const void *addr, size_t size) |
106 | { | 141 | { |
107 | pcm_dma_apply_settings_nolock(); | ||
108 | 142 | ||
109 | pcm_data = addr; | 143 | pcm_data = addr; |
110 | pcm_data_size = size; | 144 | pcm_data_size = size; |
@@ -257,9 +291,7 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len) | |||
257 | 291 | ||
258 | if (delay > 0) | 292 | if (delay > 0) |
259 | { | 293 | { |
260 | SDL_UnlockMutex(audio_lock); | ||
261 | SDL_Delay(delay); | 294 | SDL_Delay(delay); |
262 | SDL_LockMutex(audio_lock); | ||
263 | 295 | ||
264 | if (!pcm_is_playing()) | 296 | if (!pcm_is_playing()) |
265 | break; | 297 | break; |
@@ -340,7 +372,6 @@ void pcm_play_dma_init(void) | |||
340 | return; | 372 | return; |
341 | } | 373 | } |
342 | 374 | ||
343 | SDL_AudioSpec wanted_spec; | ||
344 | #ifdef DEBUG | 375 | #ifdef DEBUG |
345 | udata.debug = NULL; | 376 | udata.debug = NULL; |
346 | if (debug_audio) { | 377 | if (debug_audio) { |
@@ -348,43 +379,6 @@ void pcm_play_dma_init(void) | |||
348 | DEBUGF("Audio debug file open\n"); | 379 | DEBUGF("Audio debug file open\n"); |
349 | } | 380 | } |
350 | #endif | 381 | #endif |
351 | /* Set 16-bit stereo audio at 44Khz */ | ||
352 | wanted_spec.freq = 44100; | ||
353 | wanted_spec.format = AUDIO_S16SYS; | ||
354 | wanted_spec.channels = 2; | ||
355 | wanted_spec.samples = 2048; | ||
356 | wanted_spec.callback = | ||
357 | (void (SDLCALL *)(void *userdata, | ||
358 | Uint8 *stream, int len))sdl_audio_callback; | ||
359 | wanted_spec.userdata = &udata; | ||
360 | |||
361 | /* Open the audio device and start playing sound! */ | ||
362 | if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) { | ||
363 | DEBUGF("Unable to open audio: %s\n", SDL_GetError()); | ||
364 | return; | ||
365 | } | ||
366 | |||
367 | switch (obtained.format) | ||
368 | { | ||
369 | case AUDIO_U8: | ||
370 | case AUDIO_S8: | ||
371 | pcm_channel_bytes = 1; | ||
372 | break; | ||
373 | case AUDIO_U16LSB: | ||
374 | case AUDIO_S16LSB: | ||
375 | case AUDIO_U16MSB: | ||
376 | case AUDIO_S16MSB: | ||
377 | pcm_channel_bytes = 2; | ||
378 | break; | ||
379 | default: | ||
380 | DEBUGF("Unknown sample format obtained: %u\n", | ||
381 | (unsigned)obtained.format); | ||
382 | return; | ||
383 | } | ||
384 | |||
385 | pcm_sample_bytes = obtained.channels * pcm_channel_bytes; | ||
386 | |||
387 | pcm_dma_apply_settings_nolock(); | ||
388 | } | 382 | } |
389 | 383 | ||
390 | void pcm_play_dma_postinit(void) | 384 | void pcm_play_dma_postinit(void) |
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c index e53643f449..56cff3f1be 100644 --- a/firmware/target/hosted/sdl/system-sdl.c +++ b/firmware/target/hosted/sdl/system-sdl.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /*************************************************************************** | 1 | /*************************************************************************** |
2 | * __________ __ ___. | 2 | * __________ __ ___. |
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2006 by Daniel Everton <dan@iocaine.org> | 10 | * Copyright (C) 2006 by Daniel Everton <dan@iocaine.org> |
@@ -50,6 +50,8 @@ | |||
50 | #define SIMULATOR_DEFAULT_ROOT "simdisk" | 50 | #define SIMULATOR_DEFAULT_ROOT "simdisk" |
51 | 51 | ||
52 | SDL_Surface *gui_surface; | 52 | SDL_Surface *gui_surface; |
53 | SDL_Window *window; | ||
54 | SDL_Renderer *sdlRenderer; | ||
53 | 55 | ||
54 | bool background = true; /* use backgrounds by default */ | 56 | bool background = true; /* use backgrounds by default */ |
55 | #ifdef HAVE_REMOTE_LCD | 57 | #ifdef HAVE_REMOTE_LCD |
@@ -72,26 +74,12 @@ bool debug_audio = false; | |||
72 | bool debug_wps = false; | 74 | bool debug_wps = false; |
73 | int wps_verbose_level = 3; | 75 | int wps_verbose_level = 3; |
74 | 76 | ||
75 | /* | 77 | static void sdl_window_setup(void) |
76 | * This thread will read the buttons in an interrupt like fashion, and | ||
77 | * also initializes SDL_INIT_VIDEO and the surfaces | ||
78 | * | ||
79 | * it must be done in the same thread (at least on windows) because events only | ||
80 | * work in the thread which called SDL_Init(SubSystem) with SDL_INIT_VIDEO | ||
81 | * | ||
82 | * This is an SDL thread and relies on preemptive behavoir of the host | ||
83 | **/ | ||
84 | static int sdl_event_thread(void * param) | ||
85 | { | 78 | { |
86 | SDL_InitSubSystem(SDL_INIT_VIDEO); | ||
87 | |||
88 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO) | ||
89 | SDL_sem *wait_for_maemo_startup; | ||
90 | #endif | ||
91 | SDL_Surface *picture_surface = NULL; | 79 | SDL_Surface *picture_surface = NULL; |
92 | int width, height; | 80 | int width, height; |
93 | int depth; | 81 | int depth; |
94 | Uint32 flags; | 82 | Uint32 flags = 0; |
95 | 83 | ||
96 | /* Try and load the background image. If it fails go without */ | 84 | /* Try and load the background image. If it fails go without */ |
97 | if (background) { | 85 | if (background) { |
@@ -101,14 +89,14 @@ static int sdl_event_thread(void * param) | |||
101 | DEBUGF("warn: %s\n", SDL_GetError()); | 89 | DEBUGF("warn: %s\n", SDL_GetError()); |
102 | } | 90 | } |
103 | } | 91 | } |
104 | 92 | ||
105 | /* Set things up */ | 93 | /* Set things up */ |
106 | if (background) | 94 | if (background) |
107 | { | 95 | { |
108 | width = UI_WIDTH; | 96 | width = UI_WIDTH; |
109 | height = UI_HEIGHT; | 97 | height = UI_HEIGHT; |
110 | } | 98 | } |
111 | else | 99 | else |
112 | { | 100 | { |
113 | #ifdef HAVE_REMOTE_LCD | 101 | #ifdef HAVE_REMOTE_LCD |
114 | if (showremote) | 102 | if (showremote) |
@@ -128,17 +116,47 @@ static int sdl_event_thread(void * param) | |||
128 | if (depth < 8) | 116 | if (depth < 8) |
129 | depth = 16; | 117 | depth = 16; |
130 | 118 | ||
131 | flags = SDL_HWSURFACE|SDL_DOUBLEBUF; | ||
132 | #if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) | 119 | #if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) |
133 | /* Fullscreen mode for maemo app */ | 120 | /* Fullscreen mode for maemo app */ |
134 | flags |= SDL_FULLSCREEN; | 121 | flags |= SDL_WINDOW_FULLSCREEN; |
135 | #endif | 122 | #endif |
136 | 123 | ||
137 | SDL_WM_SetCaption(UI_TITLE, NULL); | 124 | if ((window = SDL_CreateWindow(UI_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, |
138 | 125 | width * display_zoom, height * display_zoom , flags)) == NULL) | |
139 | if ((gui_surface = SDL_SetVideoMode(width * display_zoom, height * display_zoom, depth, flags)) == NULL) { | 126 | panicf("%s", SDL_GetError()); |
127 | if ((sdlRenderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC)) == NULL) | ||
140 | panicf("%s", SDL_GetError()); | 128 | panicf("%s", SDL_GetError()); |
129 | if ((gui_surface = SDL_CreateRGBSurface(0, width * display_zoom, height * display_zoom, depth, | ||
130 | 0, 0, 0, 0)) == NULL) | ||
131 | panicf("%s", SDL_GetError()); | ||
132 | |||
133 | /* If we have a background, blit it over to the display surface */ | ||
134 | if (background && picture_surface) | ||
135 | { | ||
136 | SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL); | ||
137 | SDL_FreeSurface(picture_surface); | ||
141 | } | 138 | } |
139 | } | ||
140 | |||
141 | /* | ||
142 | * This thread will read the buttons in an interrupt like fashion, and | ||
143 | * also initializes SDL_INIT_VIDEO and the surfaces | ||
144 | * | ||
145 | * it must be done in the same thread (at least on windows) because events only | ||
146 | * work in the thread that called SDL_InitSubSystem(SDL_INIT_VIDEO) | ||
147 | * | ||
148 | * This is an SDL thread and relies on preemptive behavoir of the host | ||
149 | **/ | ||
150 | static int sdl_event_thread(void * param) | ||
151 | { | ||
152 | #ifdef __WIN32 /* Fails on Linux and MacOS */ | ||
153 | SDL_InitSubSystem(SDL_INIT_VIDEO); | ||
154 | sdl_window_setup(); | ||
155 | #endif | ||
156 | |||
157 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO) | ||
158 | SDL_sem *wait_for_maemo_startup; | ||
159 | #endif | ||
142 | 160 | ||
143 | #if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) | 161 | #if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) |
144 | /* SDL touch screen fix: Work around a SDL assumption that returns | 162 | /* SDL touch screen fix: Work around a SDL assumption that returns |
@@ -152,14 +170,10 @@ static int sdl_event_thread(void * param) | |||
152 | SDL_SetCursor(hiddenCursor); | 170 | SDL_SetCursor(hiddenCursor); |
153 | #endif | 171 | #endif |
154 | 172 | ||
155 | if (background && picture_surface != NULL) | ||
156 | SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL); | ||
157 | |||
158 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO) | 173 | #if (CONFIG_PLATFORM & PLATFORM_MAEMO) |
159 | /* start maemo thread: Listen to display on/off events and battery monitoring */ | 174 | /* start maemo thread: Listen to display on/off events and battery monitoring */ |
160 | wait_for_maemo_startup = SDL_CreateSemaphore(0); /* 0-count so it blocks */ | 175 | wait_for_maemo_startup = SDL_CreateSemaphore(0); /* 0-count so it blocks */ |
161 | SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, wait_for_maemo_startup); | 176 | SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, NULL, wait_for_maemo_startup); |
162 | |||
163 | SDL_SemWait(wait_for_maemo_startup); | 177 | SDL_SemWait(wait_for_maemo_startup); |
164 | SDL_DestroySemaphore(wait_for_maemo_startup); | 178 | SDL_DestroySemaphore(wait_for_maemo_startup); |
165 | #endif | 179 | #endif |
@@ -184,9 +198,6 @@ static int sdl_event_thread(void * param) | |||
184 | SDL_FreeCursor(hiddenCursor); | 198 | SDL_FreeCursor(hiddenCursor); |
185 | #endif | 199 | #endif |
186 | 200 | ||
187 | if(picture_surface) | ||
188 | SDL_FreeSurface(picture_surface); | ||
189 | |||
190 | /* Order here is relevent to prevent deadlocks and use of destroyed | 201 | /* Order here is relevent to prevent deadlocks and use of destroyed |
191 | sync primitives by kernel threads */ | 202 | sync primitives by kernel threads */ |
192 | #ifdef HAVE_SDL_THREADS | 203 | #ifdef HAVE_SDL_THREADS |
@@ -251,15 +262,16 @@ void system_init(void) | |||
251 | g_type_init(); | 262 | g_type_init(); |
252 | #endif | 263 | #endif |
253 | 264 | ||
254 | if (SDL_Init(SDL_INIT_TIMER)) | 265 | if (SDL_InitSubSystem(SDL_INIT_TIMER)) |
255 | panicf("%s", SDL_GetError()); | 266 | panicf("%s", SDL_GetError()); |
256 | 267 | ||
257 | s = SDL_CreateSemaphore(0); /* 0-count so it blocks */ | 268 | #ifndef __WIN32 /* Fails on Windows */ |
258 | 269 | SDL_InitSubSystem(SDL_INIT_VIDEO); | |
259 | evt_thread = SDL_CreateThread(sdl_event_thread, s); | 270 | sdl_window_setup(); |
271 | #endif | ||
260 | 272 | ||
261 | /* wait for sdl_event_thread to run so that it can initialize the surfaces | 273 | s = SDL_CreateSemaphore(0); /* 0-count so it blocks */ |
262 | * and video subsystem needed for SDL events */ | 274 | evt_thread = SDL_CreateThread(sdl_event_thread, NULL, s); |
263 | SDL_SemWait(s); | 275 | SDL_SemWait(s); |
264 | /* cleanup */ | 276 | /* cleanup */ |
265 | SDL_DestroySemaphore(s); | 277 | SDL_DestroySemaphore(s); |
@@ -303,29 +315,29 @@ int hostfs_flush(void) | |||
303 | 315 | ||
304 | void sys_handle_argv(int argc, char *argv[]) | 316 | void sys_handle_argv(int argc, char *argv[]) |
305 | { | 317 | { |
306 | if (argc >= 1) | 318 | if (argc >= 1) |
307 | { | 319 | { |
308 | int x; | 320 | int x; |
309 | for (x = 1; x < argc; x++) | 321 | for (x = 1; x < argc; x++) |
310 | { | 322 | { |
311 | #ifdef DEBUG | 323 | #ifdef DEBUG |
312 | if (!strcmp("--debugaudio", argv[x])) | 324 | if (!strcmp("--debugaudio", argv[x])) |
313 | { | 325 | { |
314 | debug_audio = true; | 326 | debug_audio = true; |
315 | printf("Writing debug audio file.\n"); | 327 | printf("Writing debug audio file.\n"); |
316 | } | 328 | } |
317 | else | 329 | else |
318 | #endif | 330 | #endif |
319 | if (!strcmp("--debugwps", argv[x])) | 331 | if (!strcmp("--debugwps", argv[x])) |
320 | { | 332 | { |
321 | debug_wps = true; | 333 | debug_wps = true; |
322 | printf("WPS debug mode enabled.\n"); | 334 | printf("WPS debug mode enabled.\n"); |
323 | } | 335 | } |
324 | else if (!strcmp("--nobackground", argv[x])) | 336 | else if (!strcmp("--nobackground", argv[x])) |
325 | { | 337 | { |
326 | background = false; | 338 | background = false; |
327 | printf("Disabling background image.\n"); | 339 | printf("Disabling background image.\n"); |
328 | } | 340 | } |
329 | #ifdef HAVE_REMOTE_LCD | 341 | #ifdef HAVE_REMOTE_LCD |
330 | else if (!strcmp("--noremote", argv[x])) | 342 | else if (!strcmp("--noremote", argv[x])) |
331 | { | 343 | { |
@@ -346,7 +358,7 @@ void sys_handle_argv(int argc, char *argv[]) | |||
346 | display_zoom=atof(argv[x]); | 358 | display_zoom=atof(argv[x]); |
347 | else | 359 | else |
348 | display_zoom = 2; | 360 | display_zoom = 2; |
349 | printf("Window zoom is %d\n", display_zoom); | 361 | printf("Window zoom is %f\n", display_zoom); |
350 | } | 362 | } |
351 | else if (!strcmp("--alarm", argv[x])) | 363 | else if (!strcmp("--alarm", argv[x])) |
352 | { | 364 | { |
@@ -372,7 +384,7 @@ void sys_handle_argv(int argc, char *argv[]) | |||
372 | debug_buttons = true; | 384 | debug_buttons = true; |
373 | printf("Printing background button clicks.\n"); | 385 | printf("Printing background button clicks.\n"); |
374 | } | 386 | } |
375 | else | 387 | else |
376 | { | 388 | { |
377 | printf("rockboxui\n"); | 389 | printf("rockboxui\n"); |
378 | printf("Arguments:\n"); | 390 | printf("Arguments:\n"); |
diff --git a/firmware/target/hosted/sdl/thread-sdl.c b/firmware/target/hosted/sdl/thread-sdl.c index 17a0f847b5..abd6339cee 100644 --- a/firmware/target/hosted/sdl/thread-sdl.c +++ b/firmware/target/hosted/sdl/thread-sdl.c | |||
@@ -340,7 +340,7 @@ unsigned int create_thread(void (*function)(void), | |||
340 | return 0; | 340 | return 0; |
341 | } | 341 | } |
342 | 342 | ||
343 | SDL_Thread *t = SDL_CreateThread(runthread, thread); | 343 | SDL_Thread *t = SDL_CreateThread(runthread, NULL, thread); |
344 | if (t == NULL) | 344 | if (t == NULL) |
345 | { | 345 | { |
346 | DEBUGF("Failed to create SDL thread\n"); | 346 | DEBUGF("Failed to create SDL thread\n"); |
@@ -447,7 +447,7 @@ void init_threads(void) | |||
447 | thread->context.s = SDL_CreateSemaphore(0); | 447 | thread->context.s = SDL_CreateSemaphore(0); |
448 | thread->context.t = NULL; /* NULL for the implicit main thread */ | 448 | thread->context.t = NULL; /* NULL for the implicit main thread */ |
449 | __running_self_entry() = thread; | 449 | __running_self_entry() = thread; |
450 | 450 | ||
451 | if (thread->context.s == NULL) | 451 | if (thread->context.s == NULL) |
452 | { | 452 | { |
453 | fprintf(stderr, "Failed to create main semaphore\n"); | 453 | fprintf(stderr, "Failed to create main semaphore\n"); |
diff --git a/firmware/target/mips/ingenic_jz47xx/app.lds b/firmware/target/mips/ingenic_jz47xx/app.lds index 1d300fed82..29a973a0ca 100644 --- a/firmware/target/mips/ingenic_jz47xx/app.lds +++ b/firmware/target/mips/ingenic_jz47xx/app.lds | |||
@@ -37,15 +37,11 @@ SECTIONS | |||
37 | { | 37 | { |
38 | . = DRAMORIG; | 38 | . = DRAMORIG; |
39 | 39 | ||
40 | .startup : | 40 | .text : |
41 | { | 41 | { |
42 | loadaddress = .; | 42 | loadaddress = .; |
43 | _loadaddress = .; | 43 | _loadaddress = .; |
44 | *(.startup.text); | 44 | *(.init.text); |
45 | } > DRAM | ||
46 | |||
47 | .text : | ||
48 | { | ||
49 | *(.text*); | 45 | *(.text*); |
50 | #ifndef HAVE_INIT_ATTR | 46 | #ifndef HAVE_INIT_ATTR |
51 | *(.init*); | 47 | *(.init*); |
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c index 5f320f8e9b..77fd5c013b 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c | |||
@@ -84,7 +84,7 @@ struct nand_param | |||
84 | * | 84 | * |
85 | */ | 85 | */ |
86 | 86 | ||
87 | static volatile unsigned long nand_address; | 87 | static volatile sector_t nand_address; |
88 | #define NAND_DATAPORT (nand_address) | 88 | #define NAND_DATAPORT (nand_address) |
89 | #define NAND_ADDRPORT (nand_address+0x10000) | 89 | #define NAND_ADDRPORT (nand_address+0x10000) |
90 | #define NAND_COMMPORT (nand_address+0x08000) | 90 | #define NAND_COMMPORT (nand_address+0x08000) |
@@ -111,7 +111,7 @@ static volatile unsigned long nand_address; | |||
111 | static struct nand_info* chip_info = NULL; | 111 | static struct nand_info* chip_info = NULL; |
112 | static struct nand_info* banks[4]; | 112 | static struct nand_info* banks[4]; |
113 | static unsigned int nr_banks = 1; | 113 | static unsigned int nr_banks = 1; |
114 | static unsigned long bank_size; | 114 | static sector_t bank_size; |
115 | static struct nand_param internal_param; | 115 | static struct nand_param internal_param; |
116 | static struct mutex nand_mtx; | 116 | static struct mutex nand_mtx; |
117 | #ifdef USE_DMA | 117 | #ifdef USE_DMA |
@@ -282,7 +282,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask) | |||
282 | /* | 282 | /* |
283 | * Read oob | 283 | * Read oob |
284 | */ | 284 | */ |
285 | static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) | 285 | static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size) |
286 | { | 286 | { |
287 | struct nand_param *nandp = &internal_param; | 287 | struct nand_param *nandp = &internal_param; |
288 | int page_size, row_cycle, bus_width; | 288 | int page_size, row_cycle, bus_width; |
@@ -338,7 +338,7 @@ static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int siz | |||
338 | * page - page number within a block: 0, 1, 2, ... | 338 | * page - page number within a block: 0, 1, 2, ... |
339 | * dst - pointer to target buffer | 339 | * dst - pointer to target buffer |
340 | */ | 340 | */ |
341 | static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) | 341 | static int jz_nand_read_page(sector_t page_addr, unsigned char *dst) |
342 | { | 342 | { |
343 | struct nand_param *nandp = &internal_param; | 343 | struct nand_param *nandp = &internal_param; |
344 | int page_size, oob_size; | 344 | int page_size, oob_size; |
@@ -611,7 +611,7 @@ int nand_init(void) | |||
611 | return res; | 611 | return res; |
612 | } | 612 | } |
613 | 613 | ||
614 | static inline int read_sector(unsigned long start, unsigned int count, | 614 | static inline int read_sector(sector_t start, unsigned int count, |
615 | void* buf, unsigned int chip_size) | 615 | void* buf, unsigned int chip_size) |
616 | { | 616 | { |
617 | register int ret; | 617 | register int ret; |
@@ -627,14 +627,14 @@ static inline int read_sector(unsigned long start, unsigned int count, | |||
627 | return ret; | 627 | return ret; |
628 | } | 628 | } |
629 | 629 | ||
630 | int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) | 630 | int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf) |
631 | { | 631 | { |
632 | #ifdef HAVE_MULTIVOLUME | 632 | #ifdef HAVE_MULTIDRIVE |
633 | (void)drive; | 633 | (void)drive; |
634 | #endif | 634 | #endif |
635 | int ret = 0; | 635 | int ret = 0; |
636 | unsigned int i, _count, chip_size = chip_info->page_size; | 636 | unsigned int i, _count, chip_size = chip_info->page_size; |
637 | unsigned long _start; | 637 | sector_t _start; |
638 | 638 | ||
639 | logf("start"); | 639 | logf("start"); |
640 | mutex_lock(&nand_mtx); | 640 | mutex_lock(&nand_mtx); |
@@ -670,12 +670,12 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu | |||
670 | } | 670 | } |
671 | 671 | ||
672 | /* TODO */ | 672 | /* TODO */ |
673 | int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) | 673 | int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf) |
674 | { | 674 | { |
675 | (void)start; | 675 | (void)start; |
676 | (void)count; | 676 | (void)count; |
677 | (void)buf; | 677 | (void)buf; |
678 | #ifdef HAVE_MULTIVOLUME | 678 | #ifdef HAVE_MULTIDRIVE |
679 | (void)drive; | 679 | (void)drive; |
680 | #endif | 680 | #endif |
681 | 681 | ||
@@ -727,9 +727,9 @@ void nand_sleepnow(void) | |||
727 | } | 727 | } |
728 | 728 | ||
729 | #ifdef STORAGE_GET_INFO | 729 | #ifdef STORAGE_GET_INFO |
730 | void nand_get_info(IF_MV(int drive,) struct storage_info *info) | 730 | void nand_get_info(IF_MD(int drive,) struct storage_info *info) |
731 | { | 731 | { |
732 | #ifdef HAVE_MULTIVOLUME | 732 | #ifdef HAVE_MULTIDRIVE |
733 | (void)drive; | 733 | (void)drive; |
734 | #endif | 734 | #endif |
735 | 735 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c index efce5742d0..ff9b7e419e 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c | |||
@@ -110,7 +110,7 @@ struct nand_param { | |||
110 | 110 | ||
111 | static struct nand_info* chip_info = NULL; | 111 | static struct nand_info* chip_info = NULL; |
112 | static struct nand_info* bank; | 112 | static struct nand_info* bank; |
113 | static unsigned long nand_size; | 113 | static sector_t nand_size; |
114 | static struct nand_param internal_param; | 114 | static struct nand_param internal_param; |
115 | static struct mutex nand_mtx; | 115 | static struct mutex nand_mtx; |
116 | #ifdef USE_DMA | 116 | #ifdef USE_DMA |
@@ -281,7 +281,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask) | |||
281 | /* | 281 | /* |
282 | * Read oob | 282 | * Read oob |
283 | */ | 283 | */ |
284 | static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) | 284 | static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size) |
285 | { | 285 | { |
286 | struct nand_param *nandp = &internal_param; | 286 | struct nand_param *nandp = &internal_param; |
287 | int page_size, row_cycle, bus_width; | 287 | int page_size, row_cycle, bus_width; |
@@ -337,7 +337,7 @@ static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int siz | |||
337 | * page - page number within a block: 0, 1, 2, ... | 337 | * page - page number within a block: 0, 1, 2, ... |
338 | * dst - pointer to target buffer | 338 | * dst - pointer to target buffer |
339 | */ | 339 | */ |
340 | static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) | 340 | static int jz_nand_read_page(sector_t page_addr, unsigned char *dst) |
341 | { | 341 | { |
342 | struct nand_param *nandp = &internal_param; | 342 | struct nand_param *nandp = &internal_param; |
343 | int page_size, oob_size; | 343 | int page_size, oob_size; |
@@ -532,7 +532,7 @@ int nand_init(void) | |||
532 | return res; | 532 | return res; |
533 | } | 533 | } |
534 | 534 | ||
535 | static inline int read_sector(unsigned long start, unsigned int count, | 535 | static inline int read_sector(sector_t start, unsigned int count, |
536 | void* buf, unsigned int chip_size) | 536 | void* buf, unsigned int chip_size) |
537 | { | 537 | { |
538 | register int ret; | 538 | register int ret; |
@@ -548,7 +548,7 @@ static inline int read_sector(unsigned long start, unsigned int count, | |||
548 | return ret; | 548 | return ret; |
549 | } | 549 | } |
550 | 550 | ||
551 | static inline int write_sector(unsigned long start, unsigned int count, | 551 | static inline int write_sector(sector_t start, unsigned int count, |
552 | const void* buf, unsigned int chip_size) | 552 | const void* buf, unsigned int chip_size) |
553 | { | 553 | { |
554 | int ret = 0; | 554 | int ret = 0; |
@@ -563,14 +563,14 @@ static inline int write_sector(unsigned long start, unsigned int count, | |||
563 | return ret; | 563 | return ret; |
564 | } | 564 | } |
565 | 565 | ||
566 | int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) | 566 | int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf) |
567 | { | 567 | { |
568 | #ifdef HAVE_MULTIVOLUME | 568 | #ifdef HAVE_MULTIDRIVE |
569 | (void)drive; | 569 | (void)drive; |
570 | #endif | 570 | #endif |
571 | int ret = 0; | 571 | int ret = 0; |
572 | unsigned int _count, chip_size = chip_info->page_size; | 572 | unsigned int _count, chip_size = chip_info->page_size; |
573 | unsigned long _start; | 573 | sector_t _start; |
574 | 574 | ||
575 | logf("start"); | 575 | logf("start"); |
576 | mutex_lock(&nand_mtx); | 576 | mutex_lock(&nand_mtx); |
@@ -590,14 +590,14 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu | |||
590 | return ret; | 590 | return ret; |
591 | } | 591 | } |
592 | 592 | ||
593 | int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) | 593 | int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf) |
594 | { | 594 | { |
595 | #ifdef HAVE_MULTIVOLUME | 595 | #ifdef HAVE_MULTIDRIVE |
596 | (void)drive; | 596 | (void)drive; |
597 | #endif | 597 | #endif |
598 | int ret = 0; | 598 | int ret = 0; |
599 | unsigned int _count, chip_size = chip_info->page_size; | 599 | unsigned int _count, chip_size = chip_info->page_size; |
600 | unsigned long _start; | 600 | sector_t _start; |
601 | 601 | ||
602 | logf("start"); | 602 | logf("start"); |
603 | mutex_lock(&nand_mtx); | 603 | mutex_lock(&nand_mtx); |
@@ -662,9 +662,9 @@ void nand_sleepnow(void) | |||
662 | } | 662 | } |
663 | 663 | ||
664 | #ifdef STORAGE_GET_INFO | 664 | #ifdef STORAGE_GET_INFO |
665 | void nand_get_info(IF_MV(int drive,) struct storage_info *info) | 665 | void nand_get_info(IF_MD(int drive,) struct storage_info *info) |
666 | { | 666 | { |
667 | #ifdef HAVE_MULTIVOLUME | 667 | #ifdef HAVE_MULTIDRIVE |
668 | (void)drive; | 668 | (void)drive; |
669 | #endif | 669 | #endif |
670 | 670 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c index 56dd50814a..066be4e987 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c | |||
@@ -42,7 +42,6 @@ static struct mutex sd_mtx; | |||
42 | 42 | ||
43 | static int use_4bit; | 43 | static int use_4bit; |
44 | static int num_6; | 44 | static int num_6; |
45 | static int sd2_0; | ||
46 | 45 | ||
47 | //#define SD_DMA_ENABLE | 46 | //#define SD_DMA_ENABLE |
48 | #define SD_DMA_INTERRUPT 0 | 47 | #define SD_DMA_INTERRUPT 0 |
@@ -598,7 +597,7 @@ static int jz_sd_transmit_data(struct sd_request *req) | |||
598 | static inline unsigned int jz_sd_calc_clkrt(unsigned int rate) | 597 | static inline unsigned int jz_sd_calc_clkrt(unsigned int rate) |
599 | { | 598 | { |
600 | unsigned int clkrt; | 599 | unsigned int clkrt; |
601 | unsigned int clk_src = sd2_0 ? SD_CLOCK_HIGH : SD_CLOCK_FAST; | 600 | unsigned int clk_src = card.sd2plus ? SD_CLOCK_HIGH : SD_CLOCK_FAST; |
602 | 601 | ||
603 | clkrt = 0; | 602 | clkrt = 0; |
604 | while (rate < clk_src) | 603 | while (rate < clk_src) |
@@ -716,7 +715,7 @@ static int jz_sd_exec_cmd(struct sd_request *request) | |||
716 | events = SD_EVENT_RX_DATA_DONE; | 715 | events = SD_EVENT_RX_DATA_DONE; |
717 | break; | 716 | break; |
718 | 717 | ||
719 | case 6: | 718 | case SD_SWITCH_FUNC: |
720 | if (num_6 < 2) | 719 | if (num_6 < 2) |
721 | { | 720 | { |
722 | #if defined(SD_DMA_ENABLE) | 721 | #if defined(SD_DMA_ENABLE) |
@@ -1086,7 +1085,6 @@ static int sd_init_card_state(struct sd_request *request) | |||
1086 | (request->response[3+i*4]<< 8) | request->response[4+i*4]); | 1085 | (request->response[3+i*4]<< 8) | request->response[4+i*4]); |
1087 | 1086 | ||
1088 | sd_parse_csd(&card); | 1087 | sd_parse_csd(&card); |
1089 | sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1); | ||
1090 | 1088 | ||
1091 | logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]); | 1089 | logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]); |
1092 | DEBUG("SD card is ready"); | 1090 | DEBUG("SD card is ready"); |
@@ -1155,7 +1153,7 @@ static int sd_select_card(void) | |||
1155 | if (retval) | 1153 | if (retval) |
1156 | return retval; | 1154 | return retval; |
1157 | 1155 | ||
1158 | if (sd2_0) | 1156 | if (card.sd2plus) |
1159 | { | 1157 | { |
1160 | retval = sd_read_switch(&request); | 1158 | retval = sd_read_switch(&request); |
1161 | if (!retval) | 1159 | if (!retval) |
@@ -1188,7 +1186,6 @@ static int __sd_init_device(void) | |||
1188 | /* Initialise card data as blank */ | 1186 | /* Initialise card data as blank */ |
1189 | memset(&card, 0, sizeof(tCardInfo)); | 1187 | memset(&card, 0, sizeof(tCardInfo)); |
1190 | 1188 | ||
1191 | sd2_0 = 0; | ||
1192 | num_6 = 0; | 1189 | num_6 = 0; |
1193 | use_4bit = 0; | 1190 | use_4bit = 0; |
1194 | 1191 | ||
@@ -1250,9 +1247,9 @@ static inline void sd_stop_transfer(void) | |||
1250 | mutex_unlock(&sd_mtx); | 1247 | mutex_unlock(&sd_mtx); |
1251 | } | 1248 | } |
1252 | 1249 | ||
1253 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) | 1250 | int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf) |
1254 | { | 1251 | { |
1255 | #ifdef HAVE_MULTIVOLUME | 1252 | #ifdef HAVE_MULTIDRIVE |
1256 | (void)drive; | 1253 | (void)drive; |
1257 | #endif | 1254 | #endif |
1258 | sd_start_transfer(); | 1255 | sd_start_transfer(); |
@@ -1276,7 +1273,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) | |||
1276 | if ((retval = sd_unpack_r1(&request, &r1))) | 1273 | if ((retval = sd_unpack_r1(&request, &r1))) |
1277 | goto err; | 1274 | goto err; |
1278 | 1275 | ||
1279 | if (sd2_0) | 1276 | // XXX 64-bit |
1277 | if (card.sd2plus) | ||
1280 | { | 1278 | { |
1281 | sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start, | 1279 | sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start, |
1282 | count, SD_BLOCK_SIZE, RESPONSE_R1, buf); | 1280 | count, SD_BLOCK_SIZE, RESPONSE_R1, buf); |
@@ -1292,21 +1290,20 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) | |||
1292 | goto err; | 1290 | goto err; |
1293 | } | 1291 | } |
1294 | 1292 | ||
1295 | last_disk_activity = current_tick; | ||
1296 | |||
1297 | sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); | 1293 | sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); |
1298 | if ((retval = sd_unpack_r1(&request, &r1))) | 1294 | if ((retval = sd_unpack_r1(&request, &r1))) |
1299 | goto err; | 1295 | goto err; |
1300 | 1296 | ||
1301 | err: | 1297 | err: |
1298 | last_disk_activity = current_tick; | ||
1302 | sd_stop_transfer(); | 1299 | sd_stop_transfer(); |
1303 | 1300 | ||
1304 | return retval; | 1301 | return retval; |
1305 | } | 1302 | } |
1306 | 1303 | ||
1307 | int sd_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) | 1304 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf) |
1308 | { | 1305 | { |
1309 | #ifdef HAVE_MULTIVOLUME | 1306 | #ifdef HAVE_MULTIDRIVE |
1310 | (void)drive; | 1307 | (void)drive; |
1311 | #endif | 1308 | #endif |
1312 | sd_start_transfer(); | 1309 | sd_start_transfer(); |
@@ -1330,7 +1327,8 @@ int sd_write_sectors(IF_MV(int drive,) unsigned long start, int count, const voi | |||
1330 | if ((retval = sd_unpack_r1(&request, &r1))) | 1327 | if ((retval = sd_unpack_r1(&request, &r1))) |
1331 | goto err; | 1328 | goto err; |
1332 | 1329 | ||
1333 | if (sd2_0) | 1330 | // XXX 64-bit |
1331 | if (card.sd2plus) | ||
1334 | { | 1332 | { |
1335 | sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start, | 1333 | sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start, |
1336 | count, SD_BLOCK_SIZE, RESPONSE_R1, | 1334 | count, SD_BLOCK_SIZE, RESPONSE_R1, |
@@ -1387,7 +1385,7 @@ int sd_soft_reset(void) | |||
1387 | #ifdef HAVE_HOTSWAP | 1385 | #ifdef HAVE_HOTSWAP |
1388 | bool sd_removable(IF_MD_NONVOID(int drive)) | 1386 | bool sd_removable(IF_MD_NONVOID(int drive)) |
1389 | { | 1387 | { |
1390 | #ifdef HAVE_MULTIVOLUME | 1388 | #ifdef HAVE_MULTIDRIVE |
1391 | (void)drive; | 1389 | (void)drive; |
1392 | #endif | 1390 | #endif |
1393 | return true; | 1391 | return true; |
@@ -1415,7 +1413,7 @@ void MMC_CD_IRQ(void) | |||
1415 | } | 1413 | } |
1416 | #endif | 1414 | #endif |
1417 | 1415 | ||
1418 | bool sd_present(IF_MV_NONVOID(int drive)) | 1416 | bool sd_present(IF_MD_NONVOID(int drive)) |
1419 | { | 1417 | { |
1420 | #ifdef HAVE_MULTIDRIVE | 1418 | #ifdef HAVE_MULTIDRIVE |
1421 | (void)drive; | 1419 | (void)drive; |
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c index 1960fcbd35..3810852686 100644 --- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c +++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c | |||
@@ -57,8 +57,6 @@ static struct semaphore sd_wakeup[NUM_DRIVES]; | |||
57 | 57 | ||
58 | static int use_4bit[NUM_DRIVES]; | 58 | static int use_4bit[NUM_DRIVES]; |
59 | static int num_6[NUM_DRIVES]; | 59 | static int num_6[NUM_DRIVES]; |
60 | static int sd2_0[NUM_DRIVES]; | ||
61 | |||
62 | 60 | ||
63 | //#define DEBUG(x...) logf(x) | 61 | //#define DEBUG(x...) logf(x) |
64 | #define DEBUG(x, ...) | 62 | #define DEBUG(x, ...) |
@@ -698,7 +696,7 @@ static inline unsigned int jz_sd_calc_clkrt(const int drive, unsigned int rate) | |||
698 | unsigned int clkrt = 0; | 696 | unsigned int clkrt = 0; |
699 | unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */ | 697 | unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */ |
700 | 698 | ||
701 | if (!sd2_0[drive] && rate > SD_CLOCK_FAST) | 699 | if (!card[drive].sd2plus && rate > SD_CLOCK_FAST) |
702 | rate = SD_CLOCK_FAST; | 700 | rate = SD_CLOCK_FAST; |
703 | 701 | ||
704 | while (rate < clk_src) | 702 | while (rate < clk_src) |
@@ -1192,7 +1190,6 @@ static int sd_init_card_state(const int drive, struct sd_request *request) | |||
1192 | (request->response[3+i*4]<< 8) | request->response[4+i*4]); | 1190 | (request->response[3+i*4]<< 8) | request->response[4+i*4]); |
1193 | 1191 | ||
1194 | sd_parse_csd(&card[drive]); | 1192 | sd_parse_csd(&card[drive]); |
1195 | sd2_0[drive] = (card_extract_bits(card[drive].csd, 127, 2) == 1); | ||
1196 | 1193 | ||
1197 | logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]); | 1194 | logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]); |
1198 | DEBUG("SD card is ready"); | 1195 | DEBUG("SD card is ready"); |
@@ -1261,7 +1258,7 @@ static int sd_select_card(const int drive) | |||
1261 | if (retval) | 1258 | if (retval) |
1262 | return retval; | 1259 | return retval; |
1263 | 1260 | ||
1264 | if (sd2_0[drive]) | 1261 | if (card[drive].sd2plus) |
1265 | { | 1262 | { |
1266 | retval = sd_read_switch(drive, &request); | 1263 | retval = sd_read_switch(drive, &request); |
1267 | if (!retval) | 1264 | if (!retval) |
@@ -1292,7 +1289,6 @@ static int __sd_init_device(const int drive) | |||
1292 | /* Initialise card data as blank */ | 1289 | /* Initialise card data as blank */ |
1293 | memset(&card[drive], 0, sizeof(tCardInfo)); | 1290 | memset(&card[drive], 0, sizeof(tCardInfo)); |
1294 | 1291 | ||
1295 | sd2_0[drive] = 0; | ||
1296 | num_6[drive] = 0; | 1292 | num_6[drive] = 0; |
1297 | use_4bit[drive] = 0; | 1293 | use_4bit[drive] = 0; |
1298 | active[drive] = 0; | 1294 | active[drive] = 0; |
@@ -1402,7 +1398,7 @@ static inline void sd_stop_transfer(const int drive) | |||
1402 | mutex_unlock(&sd_mtx[drive]); | 1398 | mutex_unlock(&sd_mtx[drive]); |
1403 | } | 1399 | } |
1404 | 1400 | ||
1405 | int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count, void* buf, bool write) | 1401 | int sd_transfer_sectors(IF_MD(const int drive,) sector_t start, int count, void* buf, bool write) |
1406 | { | 1402 | { |
1407 | struct sd_request request; | 1403 | struct sd_request request; |
1408 | struct sd_response_r1 r1; | 1404 | struct sd_response_r1 r1; |
@@ -1427,11 +1423,12 @@ int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count, | |||
1427 | if ((retval = sd_unpack_r1(&request, &r1))) | 1423 | if ((retval = sd_unpack_r1(&request, &r1))) |
1428 | goto err; | 1424 | goto err; |
1429 | 1425 | ||
1426 | // XXX 64-bit | ||
1430 | sd_send_cmd(drive, &request, | 1427 | sd_send_cmd(drive, &request, |
1431 | (count > 1) ? | 1428 | (count > 1) ? |
1432 | (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) : | 1429 | (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) : |
1433 | (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK), | 1430 | (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK), |
1434 | sd2_0[drive] ? start : (start * SD_BLOCK_SIZE), | 1431 | card[drive].sd2plus ? start : (start * SD_BLOCK_SIZE), |
1435 | count, SD_BLOCK_SIZE, RESPONSE_R1, buf); | 1432 | count, SD_BLOCK_SIZE, RESPONSE_R1, buf); |
1436 | if ((retval = sd_unpack_r1(&request, &r1))) | 1433 | if ((retval = sd_unpack_r1(&request, &r1))) |
1437 | goto err; | 1434 | goto err; |
@@ -1451,12 +1448,12 @@ err: | |||
1451 | return retval; | 1448 | return retval; |
1452 | } | 1449 | } |
1453 | 1450 | ||
1454 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) | 1451 | int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf) |
1455 | { | 1452 | { |
1456 | return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); | 1453 | return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); |
1457 | } | 1454 | } |
1458 | 1455 | ||
1459 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) | 1456 | int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf) |
1460 | { | 1457 | { |
1461 | return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); | 1458 | return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); |
1462 | } | 1459 | } |
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S index b73a43d8f2..ee203b3b4d 100644 --- a/firmware/target/mips/ingenic_jz47xx/crt0.S +++ b/firmware/target/mips/ingenic_jz47xx/crt0.S | |||
@@ -44,7 +44,7 @@ | |||
44 | .extern main | 44 | .extern main |
45 | .global _start | 45 | .global _start |
46 | 46 | ||
47 | .section .startup.text,"ax",%progbits | 47 | .section .init.text |
48 | .set push | 48 | .set push |
49 | .set mips32 | 49 | .set mips32 |
50 | .set noreorder | 50 | .set noreorder |
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c index 9ae602ba56..c9bcb47fcd 100644 --- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c +++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c | |||
@@ -23,15 +23,19 @@ | |||
23 | #include "power.h" | 23 | #include "power.h" |
24 | #include "cpu.h" | 24 | #include "cpu.h" |
25 | 25 | ||
26 | #define CHARGE_STAT_GPIO (32*1+6) /* STAT port */ | 26 | #define CHARGE_STAT_GPIO (32*1+6) /* STAT port */ |
27 | #define PIN_USB_DET (32*4+19) /* USB connected */ | ||
27 | 28 | ||
28 | /* Detect which power sources are present. */ | 29 | /* Detect which power sources are present. */ |
29 | unsigned int power_input_status(void) | 30 | unsigned int power_input_status(void) |
30 | { | 31 | { |
32 | int rval = POWER_INPUT_NONE; | ||
33 | if(!__gpio_get_pin(PIN_USB_DET)) | ||
34 | rval |= POWER_INPUT_USB; | ||
31 | if(!__gpio_get_pin(CHARGE_STAT_GPIO)) | 35 | if(!__gpio_get_pin(CHARGE_STAT_GPIO)) |
32 | return POWER_INPUT_USB_CHARGER; | 36 | rval |= POWER_INPUT_USB_CHARGER; |
33 | 37 | ||
34 | return POWER_INPUT_NONE; | 38 | return rval; |
35 | } | 39 | } |
36 | 40 | ||
37 | void power_init(void) | 41 | void power_init(void) |
@@ -42,5 +46,5 @@ void power_init(void) | |||
42 | 46 | ||
43 | bool charging_state(void) | 47 | bool charging_state(void) |
44 | { | 48 | { |
45 | return (power_input_status() == POWER_INPUT_USB_CHARGER); | 49 | return (power_input_status() & POWER_INPUT_USB_CHARGER); |
46 | } | 50 | } |
diff --git a/firmware/target/mips/ingenic_x1000/crt0.S b/firmware/target/mips/ingenic_x1000/crt0.S index 6c0942b0db..23daaefb5e 100644 --- a/firmware/target/mips/ingenic_x1000/crt0.S +++ b/firmware/target/mips/ingenic_x1000/crt0.S | |||
@@ -23,6 +23,10 @@ | |||
23 | #include "mips.h" | 23 | #include "mips.h" |
24 | #include "bootdata.h" | 24 | #include "bootdata.h" |
25 | 25 | ||
26 | #if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER) | ||
27 | #include "devicedata.h" | ||
28 | #endif | ||
29 | |||
26 | .text | 30 | .text |
27 | .extern main | 31 | .extern main |
28 | .extern system_early_init | 32 | .extern system_early_init |
@@ -52,6 +56,9 @@ _header: | |||
52 | #ifndef BOOTLOADER | 56 | #ifndef BOOTLOADER |
53 | /* Multiboot support header; this is not part of the above header. */ | 57 | /* Multiboot support header; this is not part of the above header. */ |
54 | put_boot_data_here | 58 | put_boot_data_here |
59 | #ifdef HAVE_DEVICEDATA | ||
60 | put_device_data_here | ||
61 | #endif | ||
55 | #endif | 62 | #endif |
56 | 63 | ||
57 | _realstart: | 64 | _realstart: |
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c index df97aba0c8..6968a19a1c 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c | |||
@@ -104,6 +104,30 @@ void audiohw_postinit(void) | |||
104 | * for 24-bit data... */ | 104 | * for 24-bit data... */ |
105 | // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data | 105 | // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data |
106 | 106 | ||
107 | /* Datasheet: Sets the number os FSR edges that must occur before * | ||
108 | * the DPLL and ASRC can lock on to the the incoming Signal. * | ||
109 | * When Samplerates >= 96khz could be used, STOP_DIV should be set * | ||
110 | * to 0 (= 16384 FSR Edges). * | ||
111 | * Reg #10 [3:0] (0x05 default, 2730 FSR Edges) */ | ||
112 | es9018k2m_write_reg(ES9018K2M_REG10_MASTER_MODE_CTRL, 0x00); | ||
113 | |||
114 | /* Datasheet: The ES90x8Q2M/K2M contains a Jitter Eliminator block, * | ||
115 | * which employs the use of a digital phase locked loop (DPLL) to * | ||
116 | * lock to the incoming audio clock rate. When in I2S or SPDIF mode, * | ||
117 | * the DPLL will lock to the frame clock (1 x fs). However, when in * | ||
118 | * DSD mode, the DPLL has no frame clock information, and must in- * | ||
119 | * stead lock to the bit clock rate (BCK). For this reason, there are * | ||
120 | * two bandwidth settings for the DPLL. * | ||
121 | Reg #12 [7:4] (0x05 default) bandwidth for I2S / SPDIF mode. | ||
122 | Reg #12 [3:0] (0x0A default) bandwidth for DSD mode. | ||
123 | * The DPLL bandwidth sets how quickly the DPLL can adjust its intern * | ||
124 | * representation of the audio clock. The higher the jitter or * | ||
125 | * frequency drift on the audio clock, the higher the bandwidth must * | ||
126 | * be so that the DPLL can react. * | ||
127 | * ! If the bandwidth is “too low”, the DPLL will loose lock and you * | ||
128 | * ! will hear random dropouts. (Fixed my SurfansF20 v3.2 dropouts) */ | ||
129 | es9018k2m_write_reg(ES9018K2M_REG12_DPLL_SETTINGS, 0xda); | ||
130 | |||
107 | } else { /* Default to SWVOL for PCM5102A DAC */ | 131 | } else { /* Default to SWVOL for PCM5102A DAC */ |
108 | logf("Default to SWVOL: ret=%d", ret); | 132 | logf("Default to SWVOL: ret=%d", ret); |
109 | } | 133 | } |
@@ -139,17 +163,19 @@ void audiohw_set_volume(int vol_l, int vol_r) | |||
139 | r = vol_r; | 163 | r = vol_r; |
140 | 164 | ||
141 | #if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) | 165 | #if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) |
142 | /* make sure headphones aren't present - don't want to | 166 | /* Due to the hardware's detection method, make the Line-Out |
143 | * blow out our eardrums cranking it to full */ | 167 | * the default. The LO can only be detected if it is active |
144 | if (lineout_inserted() && !headphones_inserted()) | 168 | * (assuming a high-impedance device is attached). HP takes priority |
169 | * if both are present. */ | ||
170 | if (headphones_inserted()) | ||
145 | { | 171 | { |
146 | eros_qn_switch_output(1); | 172 | eros_qn_switch_output(0); |
147 | |||
148 | l = r = eros_qn_get_volume_limit(); | ||
149 | } | 173 | } |
150 | else | 174 | else |
151 | { | 175 | { |
152 | eros_qn_switch_output(0); | 176 | eros_qn_switch_output(1); |
177 | |||
178 | l = r = eros_qn_get_volume_limit(); | ||
153 | } | 179 | } |
154 | #endif | 180 | #endif |
155 | 181 | ||
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c index 0d2207af2a..707dc372a8 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c | |||
@@ -75,12 +75,26 @@ volatile signed int enc_position = 0; | |||
75 | /* Value of headphone detect register */ | 75 | /* Value of headphone detect register */ |
76 | static uint8_t hp_detect_reg = 0x00; | 76 | static uint8_t hp_detect_reg = 0x00; |
77 | static uint8_t hp_detect_reg_old = 0x00; | 77 | static uint8_t hp_detect_reg_old = 0x00; |
78 | static uint8_t hp_detect_debounce1 = 0x00; | ||
79 | static uint8_t hp_detect_debounce2 = 0x00; | ||
80 | static uint8_t debounce_count = 0; | ||
78 | 81 | ||
79 | /* Interval to poll the register */ | 82 | /* Interval to poll the register */ |
80 | #define HPD_POLL_TIME (HZ/2) | 83 | #define HPD_POLL_TIME (HZ/4) |
81 | 84 | ||
82 | static int hp_detect_tmo_cb(struct timeout* tmo) | 85 | static int hp_detect_tmo_cb(struct timeout* tmo) |
83 | { | 86 | { |
87 | if (hp_detect_debounce1 == hp_detect_debounce2){ | ||
88 | if (debounce_count >= 2){ | ||
89 | debounce_count = 2; | ||
90 | } else { | ||
91 | debounce_count = debounce_count + 1; | ||
92 | } | ||
93 | } else { | ||
94 | debounce_count = 0; | ||
95 | hp_detect_debounce2 = hp_detect_debounce1; | ||
96 | } | ||
97 | |||
84 | i2c_descriptor* d = (i2c_descriptor*)tmo->data; | 98 | i2c_descriptor* d = (i2c_descriptor*)tmo->data; |
85 | i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); | 99 | i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); |
86 | return HPD_POLL_TIME; | 100 | return HPD_POLL_TIME; |
@@ -96,7 +110,7 @@ static void hp_detect_init(void) | |||
96 | .tran_mode = I2C_READ, | 110 | .tran_mode = I2C_READ, |
97 | .buffer[0] = (void*)&gpio_reg, | 111 | .buffer[0] = (void*)&gpio_reg, |
98 | .count[0] = 1, | 112 | .count[0] = 1, |
99 | .buffer[1] = &hp_detect_reg, | 113 | .buffer[1] = &hp_detect_debounce1, |
100 | .count[1] = 1, | 114 | .count[1] = 1, |
101 | .callback = NULL, | 115 | .callback = NULL, |
102 | .arg = 0, | 116 | .arg = 0, |
@@ -113,6 +127,8 @@ static void hp_detect_init(void) | |||
113 | if(r >= 0) | 127 | if(r >= 0) |
114 | { | 128 | { |
115 | hp_detect_reg = r; | 129 | hp_detect_reg = r; |
130 | hp_detect_debounce1 = r; | ||
131 | hp_detect_debounce2 = r; | ||
116 | hp_detect_reg_old = hp_detect_reg; | 132 | hp_detect_reg_old = hp_detect_reg; |
117 | } | 133 | } |
118 | 134 | ||
@@ -122,6 +138,9 @@ static void hp_detect_init(void) | |||
122 | 138 | ||
123 | bool headphones_inserted(void) | 139 | bool headphones_inserted(void) |
124 | { | 140 | { |
141 | if (debounce_count > 1){ | ||
142 | hp_detect_reg = hp_detect_debounce2; | ||
143 | } | ||
125 | /* if the status has changed, set the output volume accordingly */ | 144 | /* if the status has changed, set the output volume accordingly */ |
126 | if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) | 145 | if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) |
127 | { | 146 | { |
@@ -135,6 +154,9 @@ bool headphones_inserted(void) | |||
135 | 154 | ||
136 | bool lineout_inserted(void) | 155 | bool lineout_inserted(void) |
137 | { | 156 | { |
157 | if (debounce_count > 1){ | ||
158 | hp_detect_reg = hp_detect_debounce2; | ||
159 | } | ||
138 | /* if the status has changed, set the output volume accordingly */ | 160 | /* if the status has changed, set the output volume accordingly */ |
139 | if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) | 161 | if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) |
140 | { | 162 | { |
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c index 0d43a3f010..bcc30a71bd 100644 --- a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c +++ b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c | |||
@@ -25,11 +25,138 @@ | |||
25 | #include "lcd-x1000.h" | 25 | #include "lcd-x1000.h" |
26 | #include "gpio-x1000.h" | 26 | #include "gpio-x1000.h" |
27 | #include "system.h" | 27 | #include "system.h" |
28 | #include "devicedata.h" | ||
28 | 29 | ||
29 | /* for reference on these command/data hex values, see the mipi dcs lcd spec. * | 30 | /* for reference on these command/data hex values, see the mipi dcs lcd spec. * |
30 | * Not everything here is there, but all the standard stuff is. */ | 31 | * Not everything here is there, but all the standard stuff is. */ |
31 | 32 | ||
32 | static const uint32_t erosqnative_lcd_cmd_enable[] = { | 33 | /* New Display Eroq 2.1 / Hifiwalker 1.7+ / Surfans v3.2, unknown Controller * |
34 | * (partially GC9A01 register compatible) * | ||
35 | * https://espruino.microcosm.app/api/v1/files/ \ * | ||
36 | * 9dc1b976d621a2ab3854312cce862c4a9a50dc1b.html#GC9A01 , * | ||
37 | * https://www.buydisplay.com/download/ic/GC9A01A.pdf , * | ||
38 | * https://lcddisplay.co/wp-content/uploads/2023/02/GC9A01.pdf * | ||
39 | * Init sequence From 'EROS Q (c口)_V2.1_20231209固件.zip' * | ||
40 | * update.upt/.iso -> In 'uboot.bin' at 0x52da0-0x5305f * | ||
41 | * http://www.eroshifi.com/download/firmware/122.html */ | ||
42 | static const uint32_t erosqnative_lcd_cmd_enable_v3[] = { | ||
43 | |||
44 | /* Unlock EXTC? */ | ||
45 | LCD_INSTR_CMD, 0xfe, // Inter Register Enable1 | ||
46 | LCD_INSTR_CMD, 0xef, // Inter Register Enable2 | ||
47 | |||
48 | LCD_INSTR_CMD, 0x36, // Memory Access Control | ||
49 | /* Bit7 1:vertical flip 0:no vertical flip | ||
50 | Bit6 1:horizontal flip 0:no horizontal flip | ||
51 | Bit3 1:BGR 0:RGB */ | ||
52 | LCD_INSTR_DAT, 0x90, | ||
53 | /* Pixel Format Set */ | ||
54 | LCD_INSTR_CMD, 0x3a, | ||
55 | LCD_INSTR_DAT, 0x55, /* Rockbox uses 16pp, OF specified 18 bpp */ | ||
56 | |||
57 | LCD_INSTR_CMD, 0x84, // ?? (undocumented) | ||
58 | LCD_INSTR_DAT, 0x04, | ||
59 | LCD_INSTR_CMD, 0x86, // ?? | ||
60 | LCD_INSTR_DAT, 0xfb, | ||
61 | LCD_INSTR_CMD, 0x87, // ?? | ||
62 | LCD_INSTR_DAT, 0x79, | ||
63 | LCD_INSTR_CMD, 0x89, // ?? | ||
64 | LCD_INSTR_DAT, 0x0b, | ||
65 | LCD_INSTR_CMD, 0x8a, // ?? | ||
66 | LCD_INSTR_DAT, 0x20, | ||
67 | LCD_INSTR_CMD, 0x8b, // ?? | ||
68 | LCD_INSTR_DAT, 0x80, | ||
69 | LCD_INSTR_CMD, 0x8d, // ?? | ||
70 | LCD_INSTR_DAT, 0x3b, | ||
71 | LCD_INSTR_CMD, 0x8e, // ?? | ||
72 | LCD_INSTR_DAT, 0xcf, | ||
73 | |||
74 | LCD_INSTR_CMD, 0xec, // Charge Pump Frequent Control | ||
75 | LCD_INSTR_DAT, 0x33, | ||
76 | LCD_INSTR_DAT, 0x02, | ||
77 | LCD_INSTR_DAT, 0x4c, | ||
78 | |||
79 | LCD_INSTR_CMD, 0x98, // ?? (undocumented) | ||
80 | LCD_INSTR_DAT, 0x3e, | ||
81 | LCD_INSTR_CMD, 0x9c, // ?? | ||
82 | LCD_INSTR_DAT, 0x4b, | ||
83 | LCD_INSTR_CMD, 0x99, // ?? | ||
84 | LCD_INSTR_DAT, 0x3e, | ||
85 | LCD_INSTR_CMD, 0x9d, // ?? | ||
86 | LCD_INSTR_DAT, 0x4b, | ||
87 | LCD_INSTR_CMD, 0x9b, // ?? | ||
88 | LCD_INSTR_DAT, 0x55, | ||
89 | |||
90 | LCD_INSTR_CMD, 0xe8, // Frame Rate | ||
91 | LCD_INSTR_DAT, 0x11, | ||
92 | LCD_INSTR_DAT, 0x00, | ||
93 | |||
94 | LCD_INSTR_CMD, 0xff, // ?? (Adafruit & Co lib. C:0xFF, D:0x60, D:0x01, D:0x04) | ||
95 | LCD_INSTR_DAT, 0x62, // LCD_INSTR_DAT, 0x01, LCD_INSTR_DAT, 0x04, | ||
96 | LCD_INSTR_CMD, 0xc3, // Vreg1a voltage Control | ||
97 | LCD_INSTR_DAT, 0x20, | ||
98 | LCD_INSTR_CMD, 0xc4, // Vreg1b voltage Control | ||
99 | LCD_INSTR_DAT, 0x03, | ||
100 | LCD_INSTR_CMD, 0xc9, // Vreg2a voltage Control | ||
101 | LCD_INSTR_DAT, 0x2a, | ||
102 | |||
103 | LCD_INSTR_CMD, 0xf0, // SET_GAMMA1 | ||
104 | LCD_INSTR_DAT, 0x4a, | ||
105 | LCD_INSTR_DAT, 0x10, | ||
106 | LCD_INSTR_DAT, 0x0a, | ||
107 | LCD_INSTR_DAT, 0x0a, | ||
108 | LCD_INSTR_DAT, 0x26, | ||
109 | LCD_INSTR_DAT, 0x39, | ||
110 | |||
111 | LCD_INSTR_CMD, 0xf2, // SET_GAMMA3 | ||
112 | LCD_INSTR_DAT, 0x4a, | ||
113 | LCD_INSTR_DAT, 0x10, | ||
114 | LCD_INSTR_DAT, 0x0a, | ||
115 | LCD_INSTR_DAT, 0x0a, | ||
116 | LCD_INSTR_DAT, 0x26, | ||
117 | LCD_INSTR_DAT, 0x39, | ||
118 | |||
119 | LCD_INSTR_CMD, 0xf1, // SET_GAMMA2 | ||
120 | LCD_INSTR_DAT, 0x50, | ||
121 | LCD_INSTR_DAT, 0x8f, | ||
122 | LCD_INSTR_DAT, 0xaf, | ||
123 | LCD_INSTR_DAT, 0x3b, | ||
124 | LCD_INSTR_DAT, 0x3f, | ||
125 | LCD_INSTR_DAT, 0x7f, | ||
126 | |||
127 | LCD_INSTR_CMD, 0xf3, // SET_GAMMA4 | ||
128 | LCD_INSTR_DAT, 0x50, | ||
129 | LCD_INSTR_DAT, 0x8f, | ||
130 | LCD_INSTR_DAT, 0xaf, | ||
131 | LCD_INSTR_DAT, 0x3b, | ||
132 | LCD_INSTR_DAT, 0x3f, | ||
133 | LCD_INSTR_DAT, 0x7f, | ||
134 | |||
135 | LCD_INSTR_CMD, 0xba, // TE Control | ||
136 | LCD_INSTR_DAT, 0x0a, | ||
137 | |||
138 | #ifdef BOOTLOADER | ||
139 | LCD_INSTR_CMD, 0x35, // Tearing Effect Line ON | ||
140 | LCD_INSTR_DAT, 0x00, | ||
141 | #endif | ||
142 | |||
143 | LCD_INSTR_CMD, 0x21, /* Invert */ | ||
144 | |||
145 | /* Lock EXTC? */ | ||
146 | LCD_INSTR_CMD, 0xfe, // Inter Register Enable1 | ||
147 | LCD_INSTR_CMD, 0xee, | ||
148 | |||
149 | /* Exit Sleep */ | ||
150 | LCD_INSTR_CMD, 0x11, | ||
151 | LCD_INSTR_UDELAY, 120000, | ||
152 | /* Display On */ | ||
153 | LCD_INSTR_CMD, 0x29, | ||
154 | LCD_INSTR_UDELAY, 20000, | ||
155 | LCD_INSTR_END, | ||
156 | }; | ||
157 | |||
158 | /* Original Display / Hifiwalker -1.5 / Surfans -2.7 */ | ||
159 | static const uint32_t erosqnative_lcd_cmd_enable_v1[] = { | ||
33 | /* Set EXTC? */ | 160 | /* Set EXTC? */ |
34 | LCD_INSTR_CMD, 0xc8, | 161 | LCD_INSTR_CMD, 0xc8, |
35 | LCD_INSTR_DAT, 0xff, | 162 | LCD_INSTR_DAT, 0xff, |
@@ -179,7 +306,22 @@ void lcd_tgt_enable(bool enable) | |||
179 | mdelay(5); | 306 | mdelay(5); |
180 | gpio_set_level(GPIO_LCD_CE, 0); | 307 | gpio_set_level(GPIO_LCD_CE, 0); |
181 | 308 | ||
182 | lcd_exec_commands(&erosqnative_lcd_cmd_enable[0]); | 309 | #ifdef BOOTLOADER |
310 | # if EROSQN_VER == 3 | ||
311 | lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]); | ||
312 | # else | ||
313 | lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]); | ||
314 | # endif | ||
315 | #else | ||
316 | if (device_data.lcd_version == 3) | ||
317 | { | ||
318 | lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]); | ||
323 | } | ||
324 | #endif | ||
183 | } else { | 325 | } else { |
184 | /* doesn't flash white if we don't do anything... */ | 326 | /* doesn't flash white if we don't do anything... */ |
185 | #if 0 | 327 | #if 0 |
diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.c b/firmware/target/mips/ingenic_x1000/msc-x1000.c index 62172fa213..f0d417e4f7 100644 --- a/firmware/target/mips/ingenic_x1000/msc-x1000.c +++ b/firmware/target/mips/ingenic_x1000/msc-x1000.c | |||
@@ -844,7 +844,7 @@ int msc_cmd_send_csd(msc_drv* d) | |||
844 | d->cardinfo.csd[i] = req.response[i]; | 844 | d->cardinfo.csd[i] = req.response[i]; |
845 | sd_parse_csd(&d->cardinfo); | 845 | sd_parse_csd(&d->cardinfo); |
846 | 846 | ||
847 | if((req.response[0] >> 30) == 1) | 847 | if(d->cardinfo.sd2plus) |
848 | d->driver_flags |= MSC_DF_V2_CARD; | 848 | d->driver_flags |= MSC_DF_V2_CARD; |
849 | 849 | ||
850 | return 0; | 850 | return 0; |
diff --git a/firmware/target/mips/ingenic_x1000/sd-x1000.c b/firmware/target/mips/ingenic_x1000/sd-x1000.c index 679a25a222..c1aec59aa3 100644 --- a/firmware/target/mips/ingenic_x1000/sd-x1000.c +++ b/firmware/target/mips/ingenic_x1000/sd-x1000.c | |||
@@ -51,7 +51,7 @@ static int sd_init_card(msc_drv* d) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | static int sd_transfer(msc_drv* d, bool write, | 53 | static int sd_transfer(msc_drv* d, bool write, |
54 | unsigned long start, int count, void* buf) | 54 | sector_t start, int count, void* buf) |
55 | { | 55 | { |
56 | int status = -1; | 56 | int status = -1; |
57 | 57 | ||
@@ -114,6 +114,7 @@ static int sd_transfer(msc_drv* d, bool write, | |||
114 | : SD_READ_MULTIPLE_BLOCK; | 114 | : SD_READ_MULTIPLE_BLOCK; |
115 | } | 115 | } |
116 | 116 | ||
117 | // XXX 64-bit | ||
117 | if(d->driver_flags & MSC_DF_V2_CARD) | 118 | if(d->driver_flags & MSC_DF_V2_CARD) |
118 | req.argument = start; | 119 | req.argument = start; |
119 | else | 120 | else |
@@ -142,14 +143,14 @@ static int sd_transfer(msc_drv* d, bool write, | |||
142 | return status; | 143 | return status; |
143 | } | 144 | } |
144 | 145 | ||
145 | int sd_read_sectors(IF_MD(int drive,) unsigned long start, | 146 | int sd_read_sectors(IF_MD(int drive,) sector_t start, |
146 | int count, void* buf) | 147 | int count, void* buf) |
147 | { | 148 | { |
148 | return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false, | 149 | return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false, |
149 | start, count, buf); | 150 | start, count, buf); |
150 | } | 151 | } |
151 | 152 | ||
152 | int sd_write_sectors(IF_MD(int drive,) unsigned long start, | 153 | int sd_write_sectors(IF_MD(int drive,) sector_t start, |
153 | int count, const void* buf) | 154 | int count, const void* buf) |
154 | { | 155 | { |
155 | return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true, | 156 | return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true, |
@@ -187,6 +188,9 @@ long sd_last_disk_activity(void) | |||
187 | 188 | ||
188 | bool sd_present(IF_MD_NONVOID(int drive)) | 189 | bool sd_present(IF_MD_NONVOID(int drive)) |
189 | { | 190 | { |
191 | #ifndef HAVE_MULTIDRIVE | ||
192 | int drive = 0; | ||
193 | #endif | ||
190 | /* Seems that volume_properties() in firmware/common/disk.c may pass | 194 | /* Seems that volume_properties() in firmware/common/disk.c may pass |
191 | * drive = -1 when the SD card is not inserted, so just return false. | 195 | * drive = -1 when the SD card is not inserted, so just return false. |
192 | */ | 196 | */ |
@@ -198,6 +202,10 @@ bool sd_present(IF_MD_NONVOID(int drive)) | |||
198 | 202 | ||
199 | bool sd_removable(IF_MD_NONVOID(int drive)) | 203 | bool sd_removable(IF_MD_NONVOID(int drive)) |
200 | { | 204 | { |
205 | #ifndef HAVE_MULTIDRIVE | ||
206 | int drive = 0; | ||
207 | #endif | ||
208 | |||
201 | /* Same reason as sd_present() */ | 209 | /* Same reason as sd_present() */ |
202 | if(drive < 0) | 210 | if(drive < 0) |
203 | return false; | 211 | return false; |
diff --git a/firmware/target/mips/ingenic_x1000/system-x1000.c b/firmware/target/mips/ingenic_x1000/system-x1000.c index 64890a6c3a..1c850736b6 100644 --- a/firmware/target/mips/ingenic_x1000/system-x1000.c +++ b/firmware/target/mips/ingenic_x1000/system-x1000.c | |||
@@ -20,6 +20,7 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "system.h" | 22 | #include "system.h" |
23 | #include <string.h> | ||
23 | #include "mips.h" | 24 | #include "mips.h" |
24 | #include "panic.h" | 25 | #include "panic.h" |
25 | #include "button.h" | 26 | #include "button.h" |
@@ -36,6 +37,10 @@ | |||
36 | #include "x1000/msc.h" | 37 | #include "x1000/msc.h" |
37 | #include "x1000/aic.h" | 38 | #include "x1000/aic.h" |
38 | 39 | ||
40 | #if defined(HAVE_DEVICEDATA) | ||
41 | #include "devicedata.h" | ||
42 | #endif | ||
43 | |||
39 | #ifdef X1000_CPUIDLE_STATS | 44 | #ifdef X1000_CPUIDLE_STATS |
40 | int __cpu_idle_avg = 0; | 45 | int __cpu_idle_avg = 0; |
41 | int __cpu_idle_cur = 0; | 46 | int __cpu_idle_cur = 0; |
@@ -81,6 +86,20 @@ void system_early_init(void) | |||
81 | clk_init(); | 86 | clk_init(); |
82 | } | 87 | } |
83 | 88 | ||
89 | #if defined (HAVE_DEVICEDATA) && defined(EROS_QN) | ||
90 | void fill_devicedata(struct device_data_t *data) | ||
91 | { | ||
92 | #ifdef BOOTLOADER | ||
93 | memset(data->payload, 0xff, data->length); | ||
94 | data->lcd_version = EROSQN_VER; | ||
95 | #else | ||
96 | uint8_t lcd_version = device_data.lcd_version; | ||
97 | memset(data->payload, 0xff, data->length); | ||
98 | data->lcd_version = lcd_version; | ||
99 | #endif | ||
100 | } | ||
101 | #endif | ||
102 | |||
84 | /* First thing called from Rockbox main() */ | 103 | /* First thing called from Rockbox main() */ |
85 | void system_init(void) | 104 | void system_init(void) |
86 | { | 105 | { |
diff --git a/firmware/target/mips/ingenic_x1000/x1000boot.make b/firmware/target/mips/ingenic_x1000/x1000boot.make index 0bdf5cf7b4..7a861b0a3d 100644 --- a/firmware/target/mips/ingenic_x1000/x1000boot.make +++ b/firmware/target/mips/ingenic_x1000/x1000boot.make | |||
@@ -12,7 +12,7 @@ include $(ROOTDIR)/lib/microtar/microtar.make | |||
12 | INCLUDES += -I$(APPSDIR) | 12 | INCLUDES += -I$(APPSDIR) |
13 | SRC += $(call preprocess, $(APPSDIR)/SOURCES) | 13 | SRC += $(call preprocess, $(APPSDIR)/SOURCES) |
14 | 14 | ||
15 | LDSDEP := $(FIRMDIR)/export/cpu.h $(FIRMDIR)/export/config/$(MODELNAME).h | 15 | LDSDEP := $(FIRMDIR)/export/cpu.h $(FIRMDIR)/export/config.h |
16 | 16 | ||
17 | BOOTLDS := $(FIRMDIR)/target/$(CPU)/$(MANUFACTURER)/boot.lds | 17 | BOOTLDS := $(FIRMDIR)/target/$(CPU)/$(MANUFACTURER)/boot.lds |
18 | BOOTLINK := $(BUILDDIR)/boot.link | 18 | BOOTLINK := $(BUILDDIR)/boot.link |