summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2011-02-27 22:47:55 +0000
committerMichael Sparmann <theseven@rockbox.org>2011-02-27 22:47:55 +0000
commit30fb680a4dc7b8f1fed9002a47dc2154c7f72d0a (patch)
tree3f685583a92719314cf722fb8a8737947bb968c1
parent59c5e791a13765e75dacc2b97e93450c374b3b14 (diff)
downloadrockbox-30fb680a4dc7b8f1fed9002a47dc2154c7f72d0a.tar.gz
rockbox-30fb680a4dc7b8f1fed9002a47dc2154c7f72d0a.zip
iPod Classic CE-ATA Support (Part 4 of 4: S5L8702 ATA driver)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29448 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/export/config/ipod6g.h11
-rw-r--r--firmware/export/s5l8702.h210
-rw-r--r--firmware/target/arm/s5l8700/app.lds2
-rw-r--r--firmware/target/arm/s5l8702/app.lds2
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/ata-ipod6g.c197
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/ata-target.h47
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h345
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c1142
-rw-r--r--firmware/target/arm/s5l8702/system-s5l8702.c6
10 files changed, 1702 insertions, 264 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b2b353bda2..e0186af966 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -209,7 +209,7 @@ target/arm/ata-nand-telechips.c
209#if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_SAMSUNG) 209#if (CONFIG_STORAGE & STORAGE_NAND) && (CONFIG_NAND == NAND_SAMSUNG)
210target/arm/s5l8700/ata-nand-s5l8700.c 210target/arm/s5l8700/ata-nand-s5l8700.c
211#endif 211#endif
212#if (CONFIG_STORAGE & STORAGE_ATA) 212#if (CONFIG_STORAGE & STORAGE_ATA) && !defined(IPOD_6G)
213drivers/ata.c 213drivers/ata.c
214#endif 214#endif
215#if (CONFIG_STORAGE & STORAGE_SD) 215#if (CONFIG_STORAGE & STORAGE_SD)
@@ -1551,6 +1551,7 @@ target/arm/s5l8700/ipodnano2g/adc-nano2g.c
1551#ifdef IPOD_6G 1551#ifdef IPOD_6G
1552#ifndef SIMULATOR 1552#ifndef SIMULATOR
1553target/arm/ipod/button-clickwheel.c 1553target/arm/ipod/button-clickwheel.c
1554target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
1554target/arm/s5l8702/ipod6g/cscodec-ipod6g.c 1555target/arm/s5l8702/ipod6g/cscodec-ipod6g.c
1555target/arm/s5l8702/ipod6g/backlight-ipod6g.c 1556target/arm/s5l8702/ipod6g/backlight-ipod6g.c
1556target/arm/s5l8702/ipod6g/powermgmt-ipod6g.c 1557target/arm/s5l8702/ipod6g/powermgmt-ipod6g.c
@@ -1559,7 +1560,6 @@ target/arm/s5l8702/kernel-s5l8702.c
1559target/arm/s5l8702/system-s5l8702.c 1560target/arm/s5l8702/system-s5l8702.c
1560target/arm/s5l8702/ipod6g/lcd-ipod6g.c 1561target/arm/s5l8702/ipod6g/lcd-ipod6g.c
1561target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S 1562target/arm/s5l8702/ipod6g/lcd-asm-ipod6g.S
1562target/arm/s5l8702/ipod6g/ata-ipod6g.c
1563#if 0 //TODO 1563#if 0 //TODO
1564target/arm/s5l8702/postmortemstub.S 1564target/arm/s5l8702/postmortemstub.S
1565#endif 1565#endif
diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h
index 6ab89e5869..e783612364 100644
--- a/firmware/export/config/ipod6g.h
+++ b/firmware/export/config/ipod6g.h
@@ -185,13 +185,20 @@
185/* Define this if you can read an absolute wheel position */ 185/* Define this if you can read an absolute wheel position */
186#define HAVE_WHEEL_POSITION 186#define HAVE_WHEEL_POSITION
187 187
188//#define HAVE_ATA_BBT
189//#define ATA_BBT_PAGES 3072
190
191#define SECTOR_SIZE 4096
192
193#define STORAGE_NEEDS_ALIGN
194
188/* define this if the device has larger sectors when accessed via USB */ 195/* define this if the device has larger sectors when accessed via USB */
189/* (only relevant in disk.c, fat.c now always supports large virtual sectors) */ 196/* (only relevant in disk.c, fat.c now always supports large virtual sectors) */
190#define MAX_LOG_SECTOR_SIZE 4096 197//#define MAX_LOG_SECTOR_SIZE 4096
191 198
192/* define this if the hard drive uses large physical sectors (ATA-7 feature) */ 199/* define this if the hard drive uses large physical sectors (ATA-7 feature) */
193/* and doesn't handle them in the drive firmware */ 200/* and doesn't handle them in the drive firmware */
194#define MAX_PHYS_SECTOR_SIZE 4096 201//#define MAX_PHYS_SECTOR_SIZE 4096
195 202
196/* Define this if you have adjustable CPU frequency */ 203/* Define this if you have adjustable CPU frequency */
197#define HAVE_ADJUSTABLE_CPU_FREQ 204#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/s5l8702.h b/firmware/export/s5l8702.h
index 076e661fa4..ebd3eda2bb 100644
--- a/firmware/export/s5l8702.h
+++ b/firmware/export/s5l8702.h
@@ -568,9 +568,9 @@ struct dma_lli
568 568
569 569
570/////ATA///// 570/////ATA/////
571#define ATA_CCONTROL (*((uint32_t volatile*)(0x38700000))) 571#define ATA_CONTROL (*((uint32_t volatile*)(0x38700000)))
572#define ATA_CSTATUS (*((uint32_t volatile*)(0x38700004))) 572#define ATA_STATUS (*((uint32_t volatile*)(0x38700004)))
573#define ATA_CCOMMAND (*((uint32_t volatile*)(0x38700008))) 573#define ATA_COMMAND (*((uint32_t volatile*)(0x38700008)))
574#define ATA_SWRST (*((uint32_t volatile*)(0x3870000c))) 574#define ATA_SWRST (*((uint32_t volatile*)(0x3870000c)))
575#define ATA_IRQ (*((uint32_t volatile*)(0x38700010))) 575#define ATA_IRQ (*((uint32_t volatile*)(0x38700010)))
576#define ATA_IRQ_MASK (*((uint32_t volatile*)(0x38700014))) 576#define ATA_IRQ_MASK (*((uint32_t volatile*)(0x38700014)))
@@ -586,15 +586,15 @@ struct dma_lli
586#define ATA_SBUF_SIZE (*((uint32_t volatile*)(0x38700048))) 586#define ATA_SBUF_SIZE (*((uint32_t volatile*)(0x38700048)))
587#define ATA_CADR_TBUF (*((void* volatile*)(0x3870004c))) 587#define ATA_CADR_TBUF (*((void* volatile*)(0x3870004c)))
588#define ATA_CADR_SBUF (*((void* volatile*)(0x38700050))) 588#define ATA_CADR_SBUF (*((void* volatile*)(0x38700050)))
589#define ATA_DATA ((uint32_t volatile*)(0x38700054)) 589#define ATA_PIO_DTR (*((uint32_t volatile*)(0x38700054)))
590#define ATA_ERROR ((uint32_t volatile*)(0x38700058)) 590#define ATA_PIO_FED (*((uint32_t volatile*)(0x38700058)))
591#define ATA_NSECTOR ((uint32_t volatile*)(0x3870005c)) 591#define ATA_PIO_SCR (*((uint32_t volatile*)(0x3870005c)))
592#define ATA_SECTOR ((uint32_t volatile*)(0x38700060)) 592#define ATA_PIO_LLR (*((uint32_t volatile*)(0x38700060)))
593#define ATA_LCYL ((uint32_t volatile*)(0x38700064)) 593#define ATA_PIO_LMR (*((uint32_t volatile*)(0x38700064)))
594#define ATA_HCYL ((uint32_t volatile*)(0x38700068)) 594#define ATA_PIO_LHR (*((uint32_t volatile*)(0x38700068)))
595#define ATA_SELECT ((uint32_t volatile*)(0x3870006c)) 595#define ATA_PIO_DVR (*((uint32_t volatile*)(0x3870006c)))
596#define ATA_COMMAND ((uint32_t volatile*)(0x38700070)) 596#define ATA_PIO_CSD (*((uint32_t volatile*)(0x38700070)))
597#define ATA_CONTROL ((uint32_t volatile*)(0x38700074)) 597#define ATA_PIO_DAD (*((uint32_t volatile*)(0x38700074)))
598#define ATA_PIO_READY (*((uint32_t volatile*)(0x38700078))) 598#define ATA_PIO_READY (*((uint32_t volatile*)(0x38700078)))
599#define ATA_PIO_RDATA (*((uint32_t volatile*)(0x3870007c))) 599#define ATA_PIO_RDATA (*((uint32_t volatile*)(0x3870007c)))
600#define ATA_BUS_FIFO_STATUS (*((uint32_t volatile*)(0x38700080))) 600#define ATA_BUS_FIFO_STATUS (*((uint32_t volatile*)(0x38700080)))
@@ -602,6 +602,190 @@ struct dma_lli
602#define ATA_DMA_ADDR (*((void* volatile*)(0x38700088))) 602#define ATA_DMA_ADDR (*((void* volatile*)(0x38700088)))
603 603
604 604
605/////SDCI/////
606#define SDCI_CTRL (*((uint32_t volatile*)(0x38b00000)))
607#define SDCI_DCTRL (*((uint32_t volatile*)(0x38b00004)))
608#define SDCI_CMD (*((uint32_t volatile*)(0x38b00008)))
609#define SDCI_ARGU (*((uint32_t volatile*)(0x38b0000c)))
610#define SDCI_STATE (*((uint32_t volatile*)(0x38b00010)))
611#define SDCI_STAC (*((uint32_t volatile*)(0x38b00014)))
612#define SDCI_DSTA (*((uint32_t volatile*)(0x38b00018)))
613#define SDCI_FSTA (*((uint32_t volatile*)(0x38b0001c)))
614#define SDCI_RESP0 (*((uint32_t volatile*)(0x38b00020)))
615#define SDCI_RESP1 (*((uint32_t volatile*)(0x38b00024)))
616#define SDCI_RESP2 (*((uint32_t volatile*)(0x38b00028)))
617#define SDCI_RESP3 (*((uint32_t volatile*)(0x38b0002c)))
618#define SDCI_CDIV (*((uint32_t volatile*)(0x38b00030)))
619#define SDCI_SDIO_CSR (*((uint32_t volatile*)(0x38b00034)))
620#define SDCI_IRQ (*((uint32_t volatile*)(0x38b00038)))
621#define SDCI_IRQ_MASK (*((uint32_t volatile*)(0x38b0003c)))
622#define SDCI_DATA (*((uint32_t volatile*)(0x38b00040)))
623#define SDCI_DMAADDR (*((void* volatile*)(0x38b00044)))
624#define SDCI_DMASIZE (*((uint32_t volatile*)(0x38b00048)))
625#define SDCI_DMACOUNT (*((uint32_t volatile*)(0x38b0004c)))
626#define SDCI_RESET (*((uint32_t volatile*)(0x38b0006c)))
627
628#define SDCI_CTRL_SDCIEN BIT(0)
629#define SDCI_CTRL_CARD_TYPE_MASK BIT(1)
630#define SDCI_CTRL_CARD_TYPE_SD 0
631#define SDCI_CTRL_CARD_TYPE_MMC BIT(1)
632#define SDCI_CTRL_BUS_WIDTH_MASK BITRANGE(2, 3)
633#define SDCI_CTRL_BUS_WIDTH_1BIT 0
634#define SDCI_CTRL_BUS_WIDTH_4BIT BIT(2)
635#define SDCI_CTRL_BUS_WIDTH_8BIT BIT(3)
636#define SDCI_CTRL_DMA_EN BIT(4)
637#define SDCI_CTRL_L_ENDIAN BIT(5)
638#define SDCI_CTRL_DMA_REQ_CON_MASK BIT(6)
639#define SDCI_CTRL_DMA_REQ_CON_NEMPTY 0
640#define SDCI_CTRL_DMA_REQ_CON_FULL BIT(6)
641#define SDCI_CTRL_CLK_SEL_MASK BIT(7)
642#define SDCI_CTRL_CLK_SEL_PCLK 0
643#define SDCI_CTRL_CLK_SEL_SDCLK BIT(7)
644#define SDCI_CTRL_BIT_8 BIT(8)
645#define SDCI_CTRL_BIT_14 BIT(14)
646
647#define SDCI_DCTRL_TXFIFORST BIT(0)
648#define SDCI_DCTRL_RXFIFORST BIT(1)
649#define SDCI_DCTRL_TRCONT_MASK BITRANGE(4, 5)
650#define SDCI_DCTRL_TRCONT_TX BIT(4)
651#define SDCI_DCTRL_BUS_TEST_MASK BITRANGE(6, 7)
652#define SDCI_DCTRL_BUS_TEST_TX BIT(6)
653#define SDCI_DCTRL_BUS_TEST_RX BIT(7)
654
655#define SDCI_CDIV_CLKDIV_MASK BITRANGE(0, 7)
656#define SDCI_CDIV_CLKDIV(x) ((x) >> 1)
657#define SDCI_CDIV_CLKDIV_2 BIT(0)
658#define SDCI_CDIV_CLKDIV_4 BIT(1)
659#define SDCI_CDIV_CLKDIV_8 BIT(2)
660#define SDCI_CDIV_CLKDIV_16 BIT(3)
661#define SDCI_CDIV_CLKDIV_32 BIT(4)
662#define SDCI_CDIV_CLKDIV_64 BIT(5)
663#define SDCI_CDIV_CLKDIV_128 BIT(6)
664#define SDCI_CDIV_CLKDIV_256 BIT(7)
665
666#define SDCI_CMD_CMD_NUM_MASK BITRANGE(0, 5)
667#define SDCI_CMD_CMD_NUM_SHIFT 0
668#define SDCI_CMD_CMD_NUM(x) (x)
669#define SDCI_CMD_CMD_TYPE_MASK BITRANGE(6, 7)
670#define SDCI_CMD_CMD_TYPE_BC 0
671#define SDCI_CMD_CMD_TYPE_BCR BIT(6)
672#define SDCI_CMD_CMD_TYPE_AC BIT(7)
673#define SDCI_CMD_CMD_TYPE_ADTC (BIT(6) | BIT(7))
674#define SDCI_CMD_CMD_RD_WR BIT(8)
675#define SDCI_CMD_RES_TYPE_MASK BITRANGE(16, 18)
676#define SDCI_CMD_RES_TYPE_NONE 0
677#define SDCI_CMD_RES_TYPE_R1 BIT(16)
678#define SDCI_CMD_RES_TYPE_R2 BIT(17)
679#define SDCI_CMD_RES_TYPE_R3 (BIT(16) | BIT(17))
680#define SDCI_CMD_RES_TYPE_R4 BIT(18)
681#define SDCI_CMD_RES_TYPE_R5 (BIT(16) | BIT(18))
682#define SDCI_CMD_RES_TYPE_R6 (BIT(17) | BIT(18))
683#define SDCI_CMD_RES_BUSY BIT(19)
684#define SDCI_CMD_RES_SIZE_MASK BIT(20)
685#define SDCI_CMD_RES_SIZE_48 0
686#define SDCI_CMD_RES_SIZE_136 BIT(20)
687#define SDCI_CMD_NCR_NID_MASK BIT(21)
688#define SDCI_CMD_NCR_NID_NCR 0
689#define SDCI_CMD_NCR_NID_NID BIT(21)
690#define SDCI_CMD_CMDSTR BIT(31)
691
692#define SDCI_STATE_DAT_STATE_MASK BITRANGE(0, 3)
693#define SDCI_STATE_DAT_STATE_IDLE 0
694#define SDCI_STATE_DAT_STATE_DAT_RCV BIT(0)
695#define SDCI_STATE_DAT_STATE_CRC_RCV BIT(1)
696#define SDCI_STATE_DAT_STATE_DAT_END (BIT(0) | BIT(1))
697#define SDCI_STATE_DAT_STATE_DAT_SET BIT(2)
698#define SDCI_STATE_DAT_STATE_DAT_OUT (BIT(0) | BIT(2))
699#define SDCI_STATE_DAT_STATE_CRC_TIME (BIT(1) | BIT(2))
700#define SDCI_STATE_DAT_STATE_CRC_OUT (BIT(0) | BIT(1) | BIT(2))
701#define SDCI_STATE_DAT_STATE_ENDB_OUT BIT(3)
702#define SDCI_STATE_DAT_STATE_ENDB_STOD (BIT(0) | BIT(3))
703#define SDCI_STATE_DAT_STATE_DAT_CRCR (BIT(1) | BIT(3))
704#define SDCI_STATE_DAT_STATE_CARD_PRG (BIT(0) | BIT(1) | BIT(3))
705#define SDCI_STATE_DAT_STATE_DAT_BUSY (BIT(2) | BIT(3))
706#define SDCI_STATE_CMD_STATE_MASK (BIT(4) | BIT(5) | BIT(6))
707#define SDCI_STATE_CMD_STATE_CMD_IDLE 0
708#define SDCI_STATE_CMD_STATE_CMD_CMDO BIT(4)
709#define SDCI_STATE_CMD_STATE_CMD_CRCO BIT(5)
710#define SDCI_STATE_CMD_STATE_CMD_TOUT (BIT(4) | BIT(5))
711#define SDCI_STATE_CMD_STATE_CMD_RESR BIT(6)
712#define SDCI_STATE_CMD_STATE_CMD_INTV (BIT(4) | BIT(6))
713
714#define SDCI_STAC_CLR_CMDEND BIT(2)
715#define SDCI_STAC_CLR_BIT_3 BIT(3)
716#define SDCI_STAC_CLR_RESEND BIT(4)
717#define SDCI_STAC_CLR_DATEND BIT(6)
718#define SDCI_STAC_CLR_DAT_CRCEND BIT(7)
719#define SDCI_STAC_CLR_CRC_STAEND BIT(8)
720#define SDCI_STAC_CLR_RESTOUTE BIT(15)
721#define SDCI_STAC_CLR_RESENDE BIT(16)
722#define SDCI_STAC_CLR_RESINDE BIT(17)
723#define SDCI_STAC_CLR_RESCRCE BIT(18)
724#define SDCI_STAC_CLR_WR_DATCRCE BIT(22)
725#define SDCI_STAC_CLR_RD_DATCRCE BIT(23)
726#define SDCI_STAC_CLR_RD_DATENDE0 BIT(24)
727#define SDCI_STAC_CLR_RD_DATENDE1 BIT(25)
728#define SDCI_STAC_CLR_RD_DATENDE2 BIT(26)
729#define SDCI_STAC_CLR_RD_DATENDE3 BIT(27)
730#define SDCI_STAC_CLR_RD_DATENDE4 BIT(28)
731#define SDCI_STAC_CLR_RD_DATENDE5 BIT(29)
732#define SDCI_STAC_CLR_RD_DATENDE6 BIT(30)
733#define SDCI_STAC_CLR_RD_DATENDE7 BIT(31)
734
735#define SDCI_DSTA_CMDRDY BIT(0)
736#define SDCI_DSTA_CMDPRO BIT(1)
737#define SDCI_DSTA_CMDEND BIT(2)
738#define SDCI_DSTA_RESPRO BIT(3)
739#define SDCI_DSTA_RESEND BIT(4)
740#define SDCI_DSTA_DATPRO BIT(5)
741#define SDCI_DSTA_DATEND BIT(6)
742#define SDCI_DSTA_DAT_CRCEND BIT(7)
743#define SDCI_DSTA_CRC_STAEND BIT(8)
744#define SDCI_DSTA_DAT_BUSY BIT(9)
745#define SDCI_DSTA_SDCLK_HOLD BIT(12)
746#define SDCI_DSTA_DAT0_STATUS BIT(13)
747#define SDCI_DSTA_WP_DECT_INPUT BIT(14)
748#define SDCI_DSTA_RESTOUTE BIT(15)
749#define SDCI_DSTA_RESENDE BIT(16)
750#define SDCI_DSTA_RESINDE BIT(17)
751#define SDCI_DSTA_RESCRCE BIT(18)
752#define SDCI_DSTA_WR_CRC_STATUS_MASK BITRANGE(19, 21)
753#define SDCI_DSTA_WR_CRC_STATUS_OK BIT(20)
754#define SDCI_DSTA_WR_CRC_STATUS_TXERR (BIT(19) | BIT(21))
755#define SDCI_DSTA_WR_CRC_STATUS_CARDERR (BIT(19) | BIT(20) | BIT(21))
756#define SDCI_DSTA_WR_DATCRCE BIT(22)
757#define SDCI_DSTA_RD_DATCRCE BIT(23)
758#define SDCI_DSTA_RD_DATENDE0 BIT(24)
759#define SDCI_DSTA_RD_DATENDE1 BIT(25)
760#define SDCI_DSTA_RD_DATENDE2 BIT(26)
761#define SDCI_DSTA_RD_DATENDE3 BIT(27)
762#define SDCI_DSTA_RD_DATENDE4 BIT(28)
763#define SDCI_DSTA_RD_DATENDE5 BIT(29)
764#define SDCI_DSTA_RD_DATENDE6 BIT(30)
765#define SDCI_DSTA_RD_DATENDE7 BIT(31)
766
767#define SDCI_FSTA_RX_FIFO_EMPTY BIT(0)
768#define SDCI_FSTA_RX_FIFO_FULL BIT(1)
769#define SDCI_FSTA_TX_FIFO_EMPTY BIT(2)
770#define SDCI_FSTA_TX_FIFO_FULL BIT(3)
771
772#define SDCI_SDIO_CSR_SDIO_RW_EN BIT(0)
773#define SDCI_SDIO_CSR_SDIO_INT_EN BIT(1)
774#define SDCI_SDIO_CSR_SDIO_RW_REQ BIT(2)
775#define SDCI_SDIO_CSR_SDIO_RW_STOP BIT(3)
776#define SDCI_SDIO_CSR_SDIO_INT_PERIOD_MASK BIT(4)
777#define SDCI_SDIO_CSR_SDIO_INT_PERIOD_MORE 0
778#define SDCI_SDIO_CSR_SDIO_INT_PERIOD_XACT BIT(4)
779
780#define SDCI_IRQ_DAT_DONE_INT BIT(0)
781#define SDCI_IRQ_IOCARD_IRQ_INT BIT(1)
782#define SDCI_IRQ_READ_WAIT_INT BIT(2)
783
784#define SDCI_IRQ_MASK_MASK_DAT_DONE_INT BIT(0)
785#define SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT BIT(1)
786#define SDCI_IRQ_MASK_MASK_READ_WAIT_INT BIT(2)
787
788
605/////CLICKWHEEL///// 789/////CLICKWHEEL/////
606#define WHEEL00 (*((uint32_t volatile*)(0x3C200000))) 790#define WHEEL00 (*((uint32_t volatile*)(0x3C200000)))
607#define WHEEL04 (*((uint32_t volatile*)(0x3C200004))) 791#define WHEEL04 (*((uint32_t volatile*)(0x3C200004)))
@@ -638,6 +822,8 @@ struct dma_lli
638#define IRQ_DMAC1 17 822#define IRQ_DMAC1 17
639#define IRQ_WHEEL 23 823#define IRQ_WHEEL 23
640#define IRQ_ATA 29 824#define IRQ_ATA 29
825#define IRQ_MMC 44
641 826
642 827
643#endif 828#endif
829
diff --git a/firmware/target/arm/s5l8700/app.lds b/firmware/target/arm/s5l8700/app.lds
index 2f8ef6a40f..aa37addbf6 100644
--- a/firmware/target/arm/s5l8700/app.lds
+++ b/firmware/target/arm/s5l8700/app.lds
@@ -100,7 +100,7 @@ SECTIONS
100 *(.stack) 100 *(.stack)
101 stackbegin = .; 101 stackbegin = .;
102 _stackbegin = .; 102 _stackbegin = .;
103 . += 0x4000; 103 . += 0x2000;
104 stackend = .; 104 stackend = .;
105 _stackend = .; 105 _stackend = .;
106 _irqstackbegin = .; 106 _irqstackbegin = .;
diff --git a/firmware/target/arm/s5l8702/app.lds b/firmware/target/arm/s5l8702/app.lds
index fafdea4cd9..ec66e5d969 100644
--- a/firmware/target/arm/s5l8702/app.lds
+++ b/firmware/target/arm/s5l8702/app.lds
@@ -95,7 +95,7 @@ SECTIONS
95 *(.stack) 95 *(.stack)
96 stackbegin = .; 96 stackbegin = .;
97 _stackbegin = .; 97 _stackbegin = .;
98 . += 0x4000; 98 . += 0x2000;
99 stackend = .; 99 stackend = .;
100 _stackend = .; 100 _stackend = .;
101 _irqstackbegin = .; 101 _irqstackbegin = .;
diff --git a/firmware/target/arm/s5l8702/ipod6g/ata-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/ata-ipod6g.c
deleted file mode 100644
index f1577ee857..0000000000
--- a/firmware/target/arm/s5l8702/ipod6g/ata-ipod6g.c
+++ /dev/null
@@ -1,197 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: ata-meg-fx.c 27935 2010-08-28 23:12:11Z funman $
9 *
10 * Copyright (C) 2011 by Michael Sparmann
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23#include "kernel.h"
24#include "thread.h"
25#include "system.h"
26#include "power.h"
27#include "panic.h"
28#include "pmu-target.h"
29#include "ata.h"
30#include "ata-target.h"
31#include "s5l8702.h"
32
33
34static struct wakeup ata_wakeup;
35
36#ifdef HAVE_ATA_DMA
37static uint32_t ata_dma_flags;
38#endif
39
40
41void ata_reset(void)
42{
43 ATA_SWRST = 1;
44 sleep(HZ / 100);
45 ATA_SWRST = 0;
46 sleep(HZ / 10);
47}
48
49void ata_enable(bool on)
50{
51 if (on)
52 {
53 PWRCON(0) &= ~(1 << 5);
54 ATA_CFG = 0x41;
55 sleep(HZ / 100);
56 ATA_CFG = 0x40;
57 sleep(HZ / 20);
58 ata_reset();
59 ATA_CCONTROL = 1;
60 sleep(HZ / 5);
61 ATA_PIO_TIME = 0x191f7;
62 *ATA_HCYL = 0;
63 while (!(ATA_PIO_READY & 2)) yield();
64 }
65 else
66 {
67 ATA_CCONTROL = 0;
68 while (!(ATA_CCONTROL & 2)) yield();
69 PWRCON(1) |= 1 << 5;
70 }
71}
72
73bool ata_is_coldstart(void)
74{
75 return false;
76}
77
78void ata_device_init(void)
79{
80 VIC0INTENABLE = 1 << IRQ_ATA;
81}
82
83uint16_t ata_read_cbr(uint32_t volatile* reg)
84{
85 while (!(ATA_PIO_READY & 2));
86 volatile uint32_t __attribute__((unused)) dummy = *reg;
87 while (!(ATA_PIO_READY & 1));
88 return ATA_PIO_RDATA;
89}
90
91void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
92{
93 while (!(ATA_PIO_READY & 2));
94 *reg = data;
95}
96
97void ata_set_pio_timings(int mode)
98{
99 if (mode >= 4) ATA_PIO_TIME = 0x7083;
100 if (mode >= 3) ATA_PIO_TIME = 0x2072;
101 else ATA_PIO_TIME = 0x11f3;
102}
103
104#ifdef HAVE_ATA_DMA
105static void ata_set_mdma_timings(unsigned int mode)
106{
107 if (mode >= 2) ATA_MDMA_TIME = 0x5072;
108 if (mode >= 1) ATA_MDMA_TIME = 0x7083;
109 else ATA_MDMA_TIME = 0x1c175;
110}
111
112static void ata_set_udma_timings(unsigned int mode)
113{
114 if (mode >= 4) ATA_UDMA_TIME = 0x2010a52;
115 if (mode >= 3) ATA_UDMA_TIME = 0x2020a52;
116 if (mode >= 2) ATA_UDMA_TIME = 0x3030a52;
117 if (mode >= 1) ATA_UDMA_TIME = 0x3050a52;
118 else ATA_UDMA_TIME = 0x5071152;
119}
120
121void ata_dma_set_mode(unsigned char mode)
122{
123 unsigned int modeidx = mode & 0x07;
124 unsigned int dmamode = mode & 0xf8;
125
126 if (dmamode == 0x40 && modeidx <= ATA_MAX_UDMA)
127 {
128 /* Using Ultra DMA */
129 ata_set_udma_timings(dmamode);
130 ata_dma_flags = 0x60c;
131 }
132 else if (dmamode == 0x20 && modeidx <= ATA_MAX_MWDMA)
133 {
134 /* Using Multiword DMA */
135 ata_set_mdma_timings(dmamode);
136 ata_dma_flags = 0x408;
137 }
138 else
139 {
140 /* Don't understand this - force PIO. */
141 ata_dma_flags = 0;
142 }
143}
144
145bool ata_dma_setup(void *addr, unsigned long bytes, bool write)
146{
147 if ((((int)addr) & 0xf) || (((int)bytes) & 0xf) || !ata_dma_flags)
148 return false;
149
150 if (write) clean_dcache();
151 else invalidate_dcache();
152 ATA_CCOMMAND = 2;
153
154 if (write)
155 {
156 ATA_SBUF_START = addr;
157 ATA_SBUF_SIZE = bytes;
158 ATA_CFG |= 0x10;
159 }
160 else
161 {
162 ATA_TBUF_START = addr;
163 ATA_TBUF_SIZE = bytes;
164 ATA_CFG &= ~0x10;
165 }
166 ATA_XFR_NUM = bytes - 1;
167
168 return true;
169}
170
171bool ata_dma_finish(void)
172{
173 ATA_CFG |= ata_dma_flags;
174 ATA_CFG &= ~0x180;
175 wakeup_wait(&ata_wakeup, TIMEOUT_NOBLOCK);
176 ATA_IRQ = 0x1f;
177 ATA_IRQ_MASK = 1;
178 ATA_CCOMMAND = 1;
179 if (wakeup_wait(&ata_wakeup, HZ / 2) != OBJ_WAIT_SUCCEEDED)
180 {
181 ATA_CCOMMAND = 2;
182 ATA_CFG &= ~0x100c;
183 return false;
184 }
185 ATA_CCOMMAND = 2;
186 ATA_CFG &= ~0x100c;
187 return true;
188}
189#endif /* HAVE_ATA_DMA */
190
191void INT_ATA(void)
192{
193 uint32_t ata_irq = ATA_IRQ;
194 ATA_IRQ = ata_irq;
195 if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
196 ATA_IRQ_MASK = 0;
197}
diff --git a/firmware/target/arm/s5l8702/ipod6g/ata-target.h b/firmware/target/arm/s5l8702/ipod6g/ata-target.h
deleted file mode 100644
index e2e7bd298c..0000000000
--- a/firmware/target/arm/s5l8702/ipod6g/ata-target.h
+++ /dev/null
@@ -1,47 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: ata-target.h 25525 2010-04-07 20:01:21Z torne $
9 *
10 * Copyright (C) 2011 by Michael Sparmann
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef ATA_TARGET_H
22#define ATA_TARGET_H
23
24#include "inttypes.h"
25#include "s5l8702.h"
26
27#ifdef BOOTLOADER
28#define ATA_DRIVER_CLOSE
29#endif
30
31#define ATA_SWAP_IDENTIFY(word) (swap16(word))
32
33void ata_reset(void);
34void ata_device_init(void);
35bool ata_is_coldstart(void);
36uint16_t ata_read_cbr(uint32_t volatile* reg);
37void ata_write_cbr(uint32_t volatile* reg, uint16_t data);
38
39#define ATA_OUT8(reg, data) ata_write_cbr(reg, data)
40#define ATA_OUT16(reg, data) ata_write_cbr(reg, data)
41#define ATA_IN8(reg) ata_read_cbr(reg)
42#define ATA_IN16(reg) ata_read_cbr(reg)
43
44#define ATA_SET_DEVICE_FEATURES
45void ata_set_pio_timings(int mode);
46
47#endif
diff --git a/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h b/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h
new file mode 100644
index 0000000000..50e591253e
--- /dev/null
+++ b/firmware/target/arm/s5l8702/ipod6g/mmcdefs-target.h
@@ -0,0 +1,345 @@
1//
2//
3// Copyright 2010 TheSeven
4//
5//
6// This file is part of emCORE.
7//
8// emCORE is free software: you can redistribute it and/or
9// modify it under the terms of the GNU General Public License as
10// published by the Free Software Foundation, either version 2 of the
11// License, or (at your option) any later version.
12//
13// emCORE is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16// See the GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License along
19// with emCORE. If not, see <http://www.gnu.org/licenses/>.
20//
21//
22
23
24#ifndef __CONSTANTS_MMC_H__
25#define __CONSTANTS_MMC_H__
26
27
28#ifndef MIN
29#define MIN(a, b) (((a)<(b))?(a):(b))
30#endif
31
32#ifndef MAX
33#define MAX(a, b) (((a)>(b))?(a):(b))
34#endif
35
36#define BIT(x) (1 << (x))
37#define BITRANGE(x, y) ((0xfffffffful >> (31 + (x) - (y))) << (x))
38
39#define ERR_RC(val) (BIT(31) | (val))
40#define IS_ERR(val) (val & BIT(31))
41#define RET_ERR(val) \
42{ \
43 return ERR_RC(val); \
44}
45#define RET_ERR_MTX(val, mutex) \
46{ \
47 mutex_unlock(mutex); \
48 return ERR_RC(val); \
49}
50#define PASS_RC(expr, bits, val) \
51{ \
52 int PASS_RC_rc = (expr); \
53 if (IS_ERR(PASS_RC_rc)) \
54 return ERR_RC((PASS_RC_rc << (bits)) | (val)); \
55}
56#define PASS_RC_MTX(expr, bits, val, mutex) \
57{ \
58 int PASS_RC_MTX_rc = (expr); \
59 if (IS_ERR(PASS_RC_MTX_rc)) \
60 { \
61 mutex_unlock(mutex); \
62 return ERR_RC((PASS_RC_MTX_rc << (bits)) | (val)); \
63 } \
64}
65
66#define TIMEOUT_EXPIRED(a,b) TIME_AFTER(USEC_TIMER,a + b)
67#define udelay(duration) \
68{ \
69 long timestamp = USEC_TIMER; \
70 while (!TIMEOUT_EXPIRED(timestamp, (long)(duration))); \
71}
72
73
74#define MMC_CMD_GO_IDLE_STATE 0
75#define MMC_CMD_SEND_OP_COND 1
76#define MMC_CMD_ALL_SEND_CID 2
77#define MMC_CMD_SET_RELATIVE_ADDR 3
78#define MMC_CMD_SET_DSR 4
79#define MMC_CMD_SLEEP_AWAKE 5
80#define MMC_CMD_SWITCH 6
81#define MMC_CMD_SELECT_CARD 7
82#define MMC_CMD_SEND_EXT_CSD 8
83#define MMC_CMD_SEND_CSD 9
84#define MMC_CMD_SEND_CID 10
85#define MMC_CMD_READ_DAT_UNTIL_STOP 11
86#define MMC_CMD_STOP_TRANSMISSION 12
87#define MMC_CMD_SEND_STATUS 13
88#define MMC_CMD_BUSTEST_R 14
89#define MMC_CMD_GO_INAVTIVE_STATE 15
90#define MMC_CMD_SET_BLOCKLEN 16
91#define MMC_CMD_READ_SINGLE_BLOCK 17
92#define MMC_CMD_READ_MULTIPLE_BLOCK 18
93#define MMC_CMD_BUSTEST_W 19
94#define MMC_CMD_WRITE_DAT_UNTIL_STOP 20
95#define MMC_CMD_SET_BLOCK_COUNT 23
96#define MMC_CMD_WRITE_BLOCK 24
97#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
98#define MMC_CMD_PROGRAM_CID 26
99#define MMC_CMD_PROGRAM_CSD 27
100#define MMC_CMD_SET_WRITE_PROT 28
101#define MMC_CMD_CLR_WRITE_PROT 29
102#define MMC_CMD_SEND_WRITE_PROT 30
103#define MMC_CMD_ERASE_GROUP_START 35
104#define MMC_CMD_ERASE_GROUP_END 36
105#define MMC_CMD_ERASE 38
106#define MMC_CMD_FAST_IO 39
107#define MMC_CMD_GO_IRQ_STATE 40
108#define MMC_CMD_LOCK_UNLOCK 42
109#define MMC_CMD_APP_CMD 55
110#define MMC_CMD_GEN_CMD 56
111#define MMC_CMD_CEATA_RW_MULTIPLE_REG 60
112#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK 61
113
114#define MMC_CMD_SEND_OP_COND_OCR_MASK BITRANGE(0, 31)
115#define MMC_CMD_SEND_OP_COND_OCR_SHIFT 0
116#define MMC_CMD_SEND_OP_COND_OCR(x) (x)
117
118#define MMC_CMD_SET_RELATIVE_ADDR_RCA_MASK BITRANGE(16, 31)
119#define MMC_CMD_SET_RELATIVE_ADDR_RCA_SHIFT 16
120#define MMC_CMD_SET_RELATIVE_ADDR_RCA(x) ((x) << 16)
121
122#define MMC_CMD_SET_DSR_DSR_MASK BITRANGE(16, 31)
123#define MMC_CMD_SET_DSR_DSR_SHIFT 16
124#define MMC_CMD_SET_DSR_DSR(x) ((x) << 16)
125
126#define MMC_CMD_SLEEP_AWAKE_SLEEP_AWAKE_MASK BIT(15)
127#define MMC_CMD_SLEEP_AWAKE_SLEEP_AWAKE_AWAKE 0
128#define MMC_CMD_SLEEP_AWAKE_SLEEP_AWAKE_SLEEP BIT(15)
129#define MMC_CMD_SLEEP_AWAKE_RCA_MASK BITRANGE(16, 31)
130#define MMC_CMD_SLEEP_AWAKE_RCA_SHIFT 16
131#define MMC_CMD_SLEEP_AWAKE_RCA(x) ((x) << 16)
132
133#define MMC_CMD_SWITCH_ACCESS_MASK BITRANGE(24, 25);
134#define MMC_CMD_SWITCH_ACCESS_CMDSET 0
135#define MMC_CMD_SWITCH_ACCESS_SET_BITS BIT(24)
136#define MMC_CMD_SWITCH_ACCESS_CLEAR_BITS BIT(25)
137#define MMC_CMD_SWITCH_ACCESS_WRITE_BYTE (BIT(24) | BIT(25))
138#define MMC_CMD_SWTICH_INDEX_MASK BITRANGE(16, 23);
139#define MMC_CMD_SWITCH_INDEX_SHIFT 16
140#define MMC_CMD_SWITCH_INDEX(x) ((x) << 16)
141#define MMC_CMD_SWTICH_VALUE_MASK BITRANGE(8, 15);
142#define MMC_CMD_SWITCH_VALUE_SHIFT 8
143#define MMC_CMD_SWITCH_VALUE(x) ((x) << 8)
144#define MMC_CMD_SWTICH_CMDSET_MASK BITRANGE(0, 2);
145#define MMC_CMD_SWITCH_CMDSET_STANDARD_MMC 0
146
147#define MMC_CMD_SELECT_CARD_RCA_MASK BITRANGE(16, 31)
148#define MMC_CMD_SELECT_CARD_RCA_SHIFT 16
149#define MMC_CMD_SELECT_CARD_RCA(x) ((x) << 16)
150
151#define MMC_CMD_SEND_CSD_RCA_MASK BITRANGE(16, 31)
152#define MMC_CMD_SEND_CSD_RCA_SHIFT 16
153#define MMC_CMD_SEND_CSD_RCA(x) ((x) << 16)
154
155#define MMC_CMD_SEND_CID_RCA_MASK BITRANGE(16, 31)
156#define MMC_CMD_SEND_CID_RCA_SHIFT 16
157#define MMC_CMD_SEND_CID_RCA(x) ((x) << 16)
158
159#define MMC_CMD_READ_DAT_UNTIL_STOP_ADDRESS_MASK BITRANGE(0, 31)
160#define MMC_CMD_READ_DAT_UNTIL_STOP_ADDRESS_SHIFT 0
161#define MMC_CMD_READ_DAT_UNTIL_STOP_ADDRESS(x) (x)
162
163#define MMC_CMD_SEND_STATUS_RCA_MASK BITRANGE(16, 31)
164#define MMC_CMD_SEND_STATUS_RCA_SHIFT 16
165#define MMC_CMD_SEND_STATUS_RCA(x) ((x) << 16)
166
167#define MMC_CMD_GO_INACTIVE_STATE_RCA_MASK BITRANGE(16, 31)
168#define MMC_CMD_GO_INACTIVE_STATE_RCA_SHIFT 16
169#define MMC_CMD_GO_INACTIVE_STATE_RCA(x) ((x) << 16)
170
171#define MMC_CMD_SET_BLOCKLEN_LENGTH_MASK BITRANGE(0, 31)
172#define MMC_CMD_SET_BLOCKLEN_LENGTH_SHIFT 0
173#define MMC_CMD_SET_BLOCKLEN_LENGTH(x) (x)
174
175#define MMC_CMD_READ_SINGLE_BLOCK_ADDRESS_MASK BITRANGE(0, 31)
176#define MMC_CMD_READ_SINGLE_BLOCK_ADDRESS_SHIFT 0
177#define MMC_CMD_READ_SINGLE_BLOCK_ADDRESS(x) (x)
178
179#define MMC_CMD_READ_MULTIPLE_BLOCK_ADDRESS_MASK BITRANGE(0, 31)
180#define MMC_CMD_READ_MULTIPLE_BLOCK_ADDRESS_SHIFT 0
181#define MMC_CMD_READ_MULTIPLE_BLOCK_ADDRESS(x) (x)
182
183#define MMC_CMD_WRITE_DAT_UNTIL_STOP_ADDRESS_MASK BITRANGE(0, 31)
184#define MMC_CMD_WRITE_DAT_UNTIL_STOP_ADDRESS_SHIFT 0
185#define MMC_CMD_WRITE_DAT_UNTIL_STOP_ADDRESS(x) (x)
186
187#define MMC_CMD_SET_BLOCK_COUNT_RELIABLE BIT(31)
188#define MMC_CMD_SET_BLOCK_COUNT_COUNT_MASK BITRANGE(0, 15)
189#define MMC_CMD_SET_BLOCK_COUNT_COUNT_SHIFT 0
190#define MMC_CMD_SET_BLOCK_COUNT_COUNT(x) (x)
191
192#define MMC_CMD_WRITE_BLOCK_ADDRESS_MASK BITRANGE(0, 31)
193#define MMC_CMD_WRITE_BLOCK_ADDRESS_SHIFT 0
194#define MMC_CMD_WRITE_BLOCK_ADDRESS(x) (x)
195
196#define MMC_CMD_WRITE_MULTIPLE_BLOCK_ADDRESS_MASK BITRANGE(0, 31)
197#define MMC_CMD_WRITE_MULTIPLE_BLOCK_ADDRESS_SHIFT 0
198#define MMC_CMD_WRITE_MULTIPLE_BLOCK_ADDRESS(x) (x)
199
200#define MMC_CMD_SET_WRITE_PROT_ADDRESS_MASK BITRANGE(0, 31)
201#define MMC_CMD_SET_WRITE_PROT_ADDRESS_SHIFT 0
202#define MMC_CMD_SET_WRITE_PROT_ADDRESS(x) (x)
203
204#define MMC_CMD_CLR_WRITE_PROT_ADDRESS_MASK BITRANGE(0, 31)
205#define MMC_CMD_CLR_WRITE_PROT_ADDRESS_SHIFT 0
206#define MMC_CMD_CLR_WRITE_PROT_ADDRESS(x) (x)
207
208#define MMC_CMD_SEND_WRITE_PROT_ADDRESS_MASK BITRANGE(0, 31)
209#define MMC_CMD_SEND_WRITE_PROT_ADDRESS_SHIFT 0
210#define MMC_CMD_SEND_WRITE_PROT_ADDRESS(x) (x)
211
212#define MMC_CMD_ERASE_GROUP_START_ADDRESS_MASK BITRANGE(0, 31)
213#define MMC_CMD_ERASE_GROUP_START_ADDRESS_SHIFT 0
214#define MMC_CMD_ERASE_GROUP_START_ADDRESS(x) (x)
215
216#define MMC_CMD_ERASE_GROUP_END_ADDRESS_MASK BITRANGE(0, 31)
217#define MMC_CMD_ERASE_GROUP_END_ADDRESS_SHIFT 0
218#define MMC_CMD_ERASE_GROUP_END_ADDRESS(x) (x)
219
220#define MMC_CMD_FAST_IO_RCA_MASK BITRANGE(16, 31)
221#define MMC_CMD_FAST_IO_RCA_SHIFT 16
222#define MMC_CMD_FAST_IO_RCA(x) ((x) << 16)
223#define MMC_CMD_FAST_IO_DIRECTION_MASK BIT(15)
224#define MMC_CMD_FAST_IO_DIRECTION_READ 0
225#define MMC_CMD_FAST_IO_DIRECTION_WRITE BIT(15)
226#define MMC_CMD_FAST_IO_ADDRESS_MASK BITRANGE(8, 14)
227#define MMC_CMD_FAST_IO_ADDRESS_SHIFT 8
228#define MMC_CMD_FAST_IO_ADDRESS(x) ((x) << 8)
229#define MMC_CMD_FAST_IO_DATA_MASK BITRANGE(0, 7)
230#define MMC_CMD_FAST_IO_DATA_SHIFT 0
231#define MMC_CMD_FAST_IO_DATA(x) (x)
232
233#define MMC_CMD_APP_CMD_RCA_MASK BITRANGE(16, 31)
234#define MMC_CMD_APP_CMD_RCA_SHIFT 16
235#define MMC_CMD_APP_CMD_RCA(x) ((x) << 16)
236
237#define MMC_CMD_GEN_CMD_DIRECTION_MASK BIT(0)
238#define MMC_CMD_GEN_CMD_DIRECTION_READ 0
239#define MMC_CMD_GEN_CMD_DIRECTION_WRITE BIT(0)
240
241#define MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_MASK BIT(31)
242#define MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_READ 0
243#define MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_WRITE BIT(31)
244#define MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS_MASK BITRANGE(16, 23)
245#define MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS_SHIFT 16
246#define MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(x) ((x) << 16)
247#define MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT_MASK BITRANGE(0, 7)
248#define MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT_SHIFT 0
249#define MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(x) (x)
250
251#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_MASK BIT(31)
252#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_READ 0
253#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_WRITE BIT(31)
254#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT_MASK BITRANGE(0, 15)
255#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT_SHIFT 0
256#define MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(x) (x)
257
258#define MMC_CMD_SWITCH_FIELD_ERASE_GROUP_DEF 175
259#define MMC_CMD_SWITCH_FIELD_BOOT_BUS_WIDTH 177
260#define MMC_CMD_SWITCH_FIELD_BOOT_CONFIG 179
261#define MMC_CMD_SWITCH_FIELD_ERASED_MEM_CONT 181
262#define MMC_CMD_SWITCH_FIELD_BUS_WIDTH 183
263#define MMC_CMD_SWITCH_FIELD_HS_TIMING 185
264#define MMC_CMD_SWITCH_FIELD_POWER_CLASS 187
265#define MMC_CMD_SWITCH_FIELD_CMD_SET_REV 189
266#define MMC_CMD_SWITCH_FIELD_CMD_SET 191
267#define MMC_CMD_SWITCH_FIELD_EXT_CSD_REV 192
268#define MMC_CMD_SWITCH_FIELD_CSD_STRUCTURE 194
269#define MMC_CMD_SWITCH_FIELD_CARD_TYPE 196
270#define MMC_CMD_SWITCH_FIELD_PWR_CL_52_195 200
271#define MMC_CMD_SWITCH_FIELD_PWR_CL_26_195 201
272#define MMC_CMD_SWITCH_FIELD_PWR_CL_52_360 202
273#define MMC_CMD_SWITCH_FIELD_PWR_CL_26_360 203
274#define MMC_CMD_SWITCH_FIELD_MIN_PERF_R_4_26 205
275#define MMC_CMD_SWITCH_FIELD_MIN_PERF_W_4_26 206
276#define MMC_CMD_SWITCH_FIELD_MIN_PERF_R_8_26_4_52 207
277#define MMC_CMD_SWITCH_FIELD_MIN_PERF_W_8_26_4_52 208
278#define MMC_CMD_SWITCH_FIELD_MIN_PERF_R_8_52 209
279#define MMC_CMD_SWITCH_FIELD_MIN_PERF_W_8_52 210
280#define MMC_CMD_SWITCH_FIELD_SEC_COUNT_0 212
281#define MMC_CMD_SWITCH_FIELD_SEC_COUNT_1 213
282#define MMC_CMD_SWITCH_FIELD_SEC_COUNT_2 214
283#define MMC_CMD_SWITCH_FIELD_SEC_COUNT_3 215
284#define MMC_CMD_SWITCH_FIELD_S_A_TIMEOUT 217
285#define MMC_CMD_SWITCH_FIELD_S_C_VCCQ 219
286#define MMC_CMD_SWITCH_FIELD_S_C_VCC 220
287#define MMC_CMD_SWITCH_FIELD_HC_WP_GRP_SIZE 221
288#define MMC_CMD_SWITCH_FIELD_REL_WR_SEC_C 222
289#define MMC_CMD_SWITCH_FIELD_ERASE_TIMEOUT_MULT 223
290#define MMC_CMD_SWITCH_FIELD_HC_ERASE_GRP_SIZE 224
291#define MMC_CMD_SWITCH_FIELD_ACC_SIZE 225
292#define MMC_CMD_SWITCH_FIELD_BOOT_SIZE_MULTI 226
293#define MMC_CMD_SWITCH_FIELD_S_CMD_SET 504
294
295#define MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT 0
296#define MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT 1
297#define MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT 2
298
299#define MMC_CMD_SWITCH_FIELD_HS_TIMING_LOW_SPEED 0
300#define MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED 1
301
302#define MMC_STATUS_APP_CMD BIT(5)
303#define MMC_STATUS_SWITCH_ERROR BIT(7)
304#define MMC_STATUS_READY_FOR_DATA BIT(8)
305#define MMC_STATUS_CURRENT_STATE_MASK BITRANGE(9, 12)
306#define MMC_STATUS_CURRENT_STATE_IDLE 0
307#define MMC_STATUS_CURRENT_STATE_READY BIT(9)
308#define MMC_STATUS_CURRENT_STATE_IDENT BIT(10)
309#define MMC_STATUS_CURRENT_STATE_STBY (BIT(9) | BIT(10))
310#define MMC_STATUS_CURRENT_STATE_TRAN BIT(11)
311#define MMC_STATUS_CURRENT_STATE_DATA (BIT(9) | BIT(11))
312#define MMC_STATUS_CURRENT_STATE_RCV (BIT(10) | BIT(11))
313#define MMC_STATUS_CURRENT_STATE_PRG (BIT(9) | BIT(10) | BIT(11))
314#define MMC_STATUS_CURRENT_STATE_DIS BIT(12)
315#define MMC_STATUS_CURRENT_STATE_BTST (BIT(9) | BIT(12))
316#define MMC_STATUS_CURRENT_STATE_SLP (BIT(10) | BIT(12))
317#define MMC_STATUS_ERASE_RESET BIT(13)
318#define MMC_STATUS_WP_ERASE_SKIP BIT(15)
319#define MMC_STATUS_CID_CSD_OVERWRITE BIT(16)
320#define MMC_STATUS_OVERRUN BIT(17)
321#define MMC_STATUS_UNDERRUN BIT(18)
322#define MMC_STATUS_ERROR BIT(19)
323#define MMC_STATUS_CC_ERROR BIT(20)
324#define MMC_STATUS_CARD_ECC_FAILED BIT(21)
325#define MMC_STATUS_ILLEGAL_COMMAND BIT(22)
326#define MMC_STATUS_COM_CRC_ERROR BIT(23)
327#define MMC_STATUS_LOCK_UNLOCK_FAILED BIT(24)
328#define MMC_STATUS_CARD_IS_LOCKED BIT(25)
329#define MMC_STATUS_WP_VIOLATION BIT(26)
330#define MMC_STATUS_ERASE_PARAM BIT(27)
331#define MMC_STATUS_ERASE_SEQ_ERROR BIT(28)
332#define MMC_STATUS_BLOCK_LEN_ERROR BIT(29)
333#define MMC_STATUS_ADDRESS_MISALIGN BIT(30)
334#define MMC_STATUS_ADDRESS_OUT_OF_RANGE BIT(31)
335
336#define MMC_OCR_170_195 BIT(7)
337#define MMC_OCR_200_260 BITRANGE(8, 14)
338#define MMC_OCR_270_360 BITRANGE(15, 23)
339#define MMC_OCR_ACCESS_MODE_MASK BITRANGE(29, 30)
340#define MMC_OCR_ACCESS_MODE_BYTE 0
341#define MMC_OCR_ACCESS_MODE_SECTOR BIT(30)
342#define MMC_OCR_POWER_UP_DONE BIT(31)
343
344
345#endif
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
new file mode 100644
index 0000000000..66e02d65bb
--- /dev/null
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
@@ -0,0 +1,1142 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "thread.h"
23#include "disk.h"
24#include "storage.h"
25#include "timer.h"
26#include "kernel.h"
27#include "string.h"
28#include "power.h"
29#include "panic.h"
30#include "mmu-arm.h"
31#include "mmcdefs-target.h"
32#include "s5l8702.h"
33#include "led.h"
34#include "ata_idle_notify.h"
35
36
37#ifndef ATA_RETRIES
38#define ATA_RETRIES 3
39#endif
40
41
42#define CEATA_POWERUP_TIMEOUT 20000000
43#define CEATA_COMMAND_TIMEOUT 1000000
44#define CEATA_DAT_NONBUSY_TIMEOUT 5000000
45#define CEATA_MMC_RCA 1
46
47
48/** static, private data **/
49static uint8_t ceata_taskfile[16] __attribute__((aligned(16)));
50uint16_t ata_identify_data[0x100] __attribute__((aligned(16)));
51bool ceata;
52bool ata_lba48;
53bool ata_dma;
54uint64_t ata_total_sectors;
55struct mutex ata_mutex;
56static struct wakeup ata_wakeup;
57static uint32_t ata_dma_flags;
58static long ata_last_activity_value = -1;
59static long ata_sleep_timeout = 20 * HZ;
60static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4];
61static bool ata_powered;
62static const int ata_retries = ATA_RETRIES;
63static const bool ata_error_srst = true;
64static struct wakeup mmc_wakeup;
65static struct wakeup mmc_comp_wakeup;
66static int spinup_time = 0;
67static int dma_mode = 0;
68
69
70#ifdef ATA_HAVE_BBT
71char ata_bbtbuf[ATA_BBT_PAGES * 64];
72uint16_t (*ata_bbt)[0x20];
73uint64_t ata_virtual_sectors;
74uint32_t ata_last_offset;
75uint64_t ata_last_phys;
76
77int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
78{
79 if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset();
80 int rc = ata_rw_sectors_internal(sector, count, buffer, false);
81 if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false);
82 ata_last_phys = sector + count - 1;
83 ata_last_offset = 0;
84 if (IS_ERR(rc))
85 panicf("ATA: Error %08X while reading BBT (sector %d, count %d)\n",
86 rc, sector, count);
87 return rc;
88}
89#endif
90
91
92static uint16_t ata_read_cbr(uint32_t volatile* reg)
93{
94 while (!(ATA_PIO_READY & 2));
95 volatile uint32_t dummy __attribute__((unused)) = *reg;
96 while (!(ATA_PIO_READY & 1));
97 return ATA_PIO_RDATA;
98}
99
100static void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
101{
102 while (!(ATA_PIO_READY & 2));
103 *reg = data;
104}
105
106static int ata_wait_for_not_bsy(long timeout)
107{
108 long startusec = USEC_TIMER;
109 while (true)
110 {
111 uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
112 if (!(csd & BIT(7))) return 0;
113 if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0);
114 }
115}
116
117static int ata_wait_for_rdy(long timeout)
118{
119 long startusec = USEC_TIMER;
120 PASS_RC(ata_wait_for_not_bsy(timeout), 1, 0);
121 while (true)
122 {
123 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
124 if (dad & BIT(6)) return 0;
125 if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1);
126 }
127}
128
129static int ata_wait_for_start_of_transfer(long timeout)
130{
131 long startusec = USEC_TIMER;
132 PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
133 while (true)
134 {
135 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
136 if (dad & BIT(0)) RET_ERR(1);
137 if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0;
138 if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2);
139 }
140}
141
142static int ata_wait_for_end_of_transfer(long timeout)
143{
144 PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
145 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
146 if (dad & BIT(0)) RET_ERR(1);
147 if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0;
148 RET_ERR(2);
149}
150
151int mmc_dsta_check_command_success(bool disable_crc)
152{
153 int rc = 0;
154 uint32_t dsta = SDCI_DSTA;
155 if (dsta & SDCI_DSTA_RESTOUTE) rc |= 1;
156 if (dsta & SDCI_DSTA_RESENDE) rc |= 2;
157 if (dsta & SDCI_DSTA_RESINDE) rc |= 4;
158 if (!disable_crc)
159 if (dsta & SDCI_DSTA_RESCRCE)
160 rc |= 8;
161 if (rc) RET_ERR(rc);
162 return 0;
163}
164
165bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int timeout)
166{
167 long starttime = USEC_TIMER;
168 while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE)
169 {
170 if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(0);
171 yield();
172 }
173 SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3
174 | SDCI_STAC_CLR_RESEND | SDCI_STAC_CLR_DATEND
175 | SDCI_STAC_CLR_DAT_CRCEND | SDCI_STAC_CLR_CRC_STAEND
176 | SDCI_STAC_CLR_RESTOUTE | SDCI_STAC_CLR_RESENDE
177 | SDCI_STAC_CLR_RESINDE | SDCI_STAC_CLR_RESCRCE
178 | SDCI_STAC_CLR_WR_DATCRCE | SDCI_STAC_CLR_RD_DATCRCE
179 | SDCI_STAC_CLR_RD_DATENDE0 | SDCI_STAC_CLR_RD_DATENDE1
180 | SDCI_STAC_CLR_RD_DATENDE2 | SDCI_STAC_CLR_RD_DATENDE3
181 | SDCI_STAC_CLR_RD_DATENDE4 | SDCI_STAC_CLR_RD_DATENDE5
182 | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7;
183 SDCI_ARGU = arg;
184 SDCI_CMD = cmd;
185 if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) RET_ERR(1);
186 SDCI_CMD = cmd | SDCI_CMD_CMDSTR;
187 long sleepbase = USEC_TIMER;
188 while (TIMEOUT_EXPIRED(sleepbase, 1000)) yield();
189 while (!(SDCI_DSTA & SDCI_DSTA_CMDEND))
190 {
191 if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(2);
192 yield();
193 }
194 if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE)
195 {
196 while (!(SDCI_DSTA & SDCI_DSTA_RESEND))
197 {
198 if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(3);
199 yield();
200 }
201 if (cmd & SDCI_CMD_RES_BUSY)
202 while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY)
203 {
204 if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(4);
205 yield();
206 }
207 }
208 bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136;
209 PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5);
210 if (result) *result = SDCI_RESP0;
211 return 0;
212}
213
214int mmc_get_card_status(uint32_t* result)
215{
216 return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_STATUS)
217 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
218 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
219 MMC_CMD_SEND_STATUS_RCA(CEATA_MMC_RCA), result, CEATA_COMMAND_TIMEOUT);
220}
221
222int mmc_init(void)
223{
224 sleep(HZ / 10);
225 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_GO_IDLE_STATE)
226 | SDCI_CMD_CMD_TYPE_BC | SDCI_CMD_RES_TYPE_NONE
227 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NID,
228 0, NULL, CEATA_COMMAND_TIMEOUT), 3, 0);
229 long startusec = USEC_TIMER;
230 uint32_t result;
231 do
232 {
233 if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(1);
234 sleep(HZ / 100);
235 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND)
236 | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3
237 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NID,
238 MMC_CMD_SEND_OP_COND_OCR(MMC_OCR_270_360),
239 NULL, CEATA_COMMAND_TIMEOUT), 3, 2);
240 result = SDCI_RESP0;
241 }
242 while (!(result & MMC_OCR_POWER_UP_DONE));
243 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_ALL_SEND_CID)
244 | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R2
245 | SDCI_CMD_RES_SIZE_136 | SDCI_CMD_NCR_NID_NID,
246 0, NULL, CEATA_COMMAND_TIMEOUT), 3, 3);
247 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SET_RELATIVE_ADDR)
248 | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R1
249 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
250 MMC_CMD_SET_RELATIVE_ADDR_RCA(CEATA_MMC_RCA),
251 NULL, CEATA_COMMAND_TIMEOUT), 3, 4);
252 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SELECT_CARD)
253 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
254 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
255 MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA),
256 NULL, CEATA_COMMAND_TIMEOUT), 3, 5);
257 PASS_RC(mmc_get_card_status(&result), 3, 6);
258 if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) RET_ERR(7);
259 return 0;
260}
261
262int mmc_fastio_write(uint32_t addr, uint32_t data)
263{
264 return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_FAST_IO)
265 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R4
266 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
267 MMC_CMD_FAST_IO_RCA(CEATA_MMC_RCA) | MMC_CMD_FAST_IO_DIRECTION_WRITE
268 | MMC_CMD_FAST_IO_ADDRESS(addr) | MMC_CMD_FAST_IO_DATA(data),
269 NULL, CEATA_COMMAND_TIMEOUT);
270}
271
272int mmc_fastio_read(uint32_t addr, uint32_t* data)
273{
274 return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_FAST_IO)
275 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R4
276 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
277 MMC_CMD_FAST_IO_RCA(CEATA_MMC_RCA) | MMC_CMD_FAST_IO_DIRECTION_READ
278 | MMC_CMD_FAST_IO_ADDRESS(addr), data, CEATA_COMMAND_TIMEOUT);
279}
280
281int ceata_soft_reset(void)
282{
283 PASS_RC(mmc_fastio_write(6, 4), 2, 0);
284 sleep(HZ / 100);
285 PASS_RC(mmc_fastio_write(6, 0), 2, 1);
286 sleep(HZ / 100);
287 long startusec = USEC_TIMER;
288 uint32_t status;
289 do
290 {
291 PASS_RC(mmc_fastio_read(0xf, &status), 2, 2);
292 if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(3);
293 sleep(HZ / 100);
294 }
295 while (status & 0x80);
296 return 0;
297}
298
299int mmc_dsta_check_data_success(void)
300{
301 int rc = 0;
302 uint32_t dsta = SDCI_DSTA;
303 if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE))
304 {
305 if (dsta & SDCI_DSTA_WR_DATCRCE) rc |= 1;
306 if (dsta & SDCI_DSTA_RD_DATCRCE) rc |= 2;
307 if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) rc |= 4;
308 else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) rc |= 8;
309 }
310 if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2
311 | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5
312 | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7))
313 rc |= 16;
314 if (rc) RET_ERR(rc);
315 return 0;
316}
317
318void mmc_discard_irq(void)
319{
320 SDCI_IRQ = SDCI_IRQ_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT
321 | SDCI_IRQ_MASK_MASK_READ_WAIT_INT;
322 wakeup_wait(&mmc_wakeup, 0);
323}
324
325int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
326{
327 if (size > 0x10) RET_ERR(0);
328 mmc_discard_irq();
329 SDCI_DMASIZE = size;
330 SDCI_DMACOUNT = 1;
331 SDCI_DMAADDR = dest;
332 SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
333 invalidate_dcache();
334 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
335 | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_RES_TYPE_R1
336 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
337 MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_READ
338 | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
339 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
340 NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
341 if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
342 PASS_RC(mmc_dsta_check_data_success(), 2, 3);
343 return 0;
344}
345
346int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size)
347{
348 uint32_t i;
349 if (size > 0x10) RET_ERR(0);
350 mmc_discard_irq();
351 SDCI_DMASIZE = size;
352 SDCI_DMACOUNT = 0;
353 SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
354 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
355 | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR
356 | SDCI_CMD_RES_BUSY | SDCI_CMD_RES_TYPE_R1
357 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
358 MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_WRITE
359 | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
360 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
361 NULL, CEATA_COMMAND_TIMEOUT), 3, 1);
362 SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
363 for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i];
364 long startusec = USEC_TIMER;
365 if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
366 while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE)
367 {
368 if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3);
369 yield();
370 }
371 PASS_RC(mmc_dsta_check_data_success(), 3, 4);
372 return 0;
373}
374
375int ceata_init(int buswidth)
376{
377 uint32_t result;
378 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
379 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
380 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
381 MMC_CMD_SWITCH_ACCESS_WRITE_BYTE
382 | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING)
383 | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED),
384 &result, CEATA_COMMAND_TIMEOUT), 3, 0);
385 if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(1);
386 if (buswidth > 1)
387 {
388 int setting;
389 if (buswidth == 4) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT;
390 else if (buswidth == 8) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT;
391 else setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT;
392 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
393 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
394 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
395 MMC_CMD_SWITCH_ACCESS_WRITE_BYTE
396 | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH)
397 | MMC_CMD_SWITCH_VALUE(setting),
398 &result, CEATA_COMMAND_TIMEOUT), 3, 2);
399 if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(3);
400 if (buswidth == 4)
401 SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT;
402 else if (buswidth == 8)
403 SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_8BIT;
404 }
405 PASS_RC(ceata_soft_reset(), 3, 4);
406 PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5);
407 if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) RET_ERR(6);
408 PASS_RC(mmc_fastio_write(6, 0), 3, 7);
409 return 0;
410}
411
412int ceata_check_error(void)
413{
414 uint32_t status, error;
415 PASS_RC(mmc_fastio_read(0xf, &status), 2, 0);
416 if (status & 1)
417 {
418 PASS_RC(mmc_fastio_read(0x9, &error), 2, 1);
419 RET_ERR((error << 2) | 2);
420 }
421 return 0;
422}
423
424int ceata_wait_idle(void)
425{
426 long startusec = USEC_TIMER;
427 while (true)
428 {
429 uint32_t status;
430 PASS_RC(mmc_fastio_read(0xf, &status), 1, 0);
431 if (!(status & 0x88)) return 0;
432 if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(1);
433 sleep(HZ / 20);
434 }
435}
436
437int ceata_cancel_command(void)
438{
439 *((uint32_t volatile*)0x3cf00200) = 0x9000e;
440 udelay(1);
441 *((uint32_t volatile*)0x3cf00200) = 0x9000f;
442 udelay(1);
443 *((uint32_t volatile*)0x3cf00200) = 0x90003;
444 udelay(1);
445 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_STOP_TRANSMISSION)
446 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY
447 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
448 0, NULL, CEATA_COMMAND_TIMEOUT), 1, 0);
449 PASS_RC(ceata_wait_idle(), 1, 1);
450 return 0;
451}
452
453int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long timeout)
454{
455 mmc_discard_irq();
456 uint32_t responsetype;
457 uint32_t cmdtype;
458 uint32_t direction;
459 if (write)
460 {
461 cmdtype = SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR;
462 responsetype = SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY;
463 direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_WRITE;
464 }
465 else
466 {
467 cmdtype = SDCI_CMD_CMD_TYPE_ADTC;
468 responsetype = SDCI_CMD_RES_TYPE_R1;
469 direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_READ;
470 }
471 SDCI_DMASIZE = 0x200;
472 SDCI_DMAADDR = buf;
473 SDCI_DMACOUNT = count;
474 SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
475 invalidate_dcache();
476 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_BLOCK)
477 | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype
478 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
479 direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
480 NULL, CEATA_COMMAND_TIMEOUT), 4, 0);
481 if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
482 if (wakeup_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
483 {
484 PASS_RC(ceata_cancel_command(), 4, 1);
485 RET_ERR(2);
486 }
487 PASS_RC(mmc_dsta_check_data_success(), 4, 3);
488 if (wakeup_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
489 {
490 PASS_RC(ceata_cancel_command(), 4, 4);
491 RET_ERR(4);
492 }
493 PASS_RC(ceata_check_error(), 4, 5);
494 return 0;
495}
496
497int ata_identify(uint16_t* buf)
498{
499 int i;
500 if (ceata)
501 {
502 memset(ceata_taskfile, 0, 16);
503 ceata_taskfile[0xf] = 0xec;
504 PASS_RC(ceata_wait_idle(), 2, 0);
505 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
506 PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2);
507 }
508 else
509 {
510 PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
511 ata_write_cbr(&ATA_PIO_DVR, 0);
512 ata_write_cbr(&ATA_PIO_CSD, 0xec);
513 PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
514 for (i = 0; i < 0x100; i++)
515 {
516 uint16_t word = ata_read_cbr(&ATA_PIO_DTR);
517 buf[i] = (word >> 8) | (word << 8);
518 }
519 }
520 return 0;
521}
522
523void ata_set_active(void)
524{
525 ata_last_activity_value = current_tick;
526}
527
528bool ata_disk_is_active(void)
529{
530 return ata_powered;
531}
532
533int ata_set_feature(uint32_t feature, uint32_t param)
534{
535 PASS_RC(ata_wait_for_rdy(500000), 1, 0);
536 ata_write_cbr(&ATA_PIO_DVR, 0);
537 ata_write_cbr(&ATA_PIO_FED, 3);
538 ata_write_cbr(&ATA_PIO_SCR, param);
539 ata_write_cbr(&ATA_PIO_CSD, feature);
540 PASS_RC(ata_wait_for_rdy(500000), 1, 1);
541 return 0;
542}
543
544int ata_power_up(void)
545{
546 ata_set_active();
547 if (ata_powered) return 0;
548 ide_power_enable(true);
549 long spinup_start = current_tick;
550 if (ceata)
551 {
552 PWRCON(0) &= ~(1 << 9);
553 SDCI_RESET = 0xa5;
554 sleep(HZ / 100);
555 *((uint32_t volatile*)0x3cf00380) = 0;
556 *((uint32_t volatile*)0x3cf0010c) = 0xff;
557 SDCI_CTRL = SDCI_CTRL_SDCIEN | SDCI_CTRL_CLK_SEL_SDCLK
558 | SDCI_CTRL_BIT_8 | SDCI_CTRL_BIT_14;
559 SDCI_CDIV = SDCI_CDIV_CLKDIV(260);
560 *((uint32_t volatile*)0x3cf00200) = 0xb000f;
561 SDCI_IRQ_MASK = SDCI_IRQ_MASK_MASK_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT;
562 PASS_RC(mmc_init(), 2, 0);
563 SDCI_CDIV = SDCI_CDIV_CLKDIV(4);
564 sleep(HZ / 100);
565 PASS_RC(ceata_init(8), 2, 1);
566 PASS_RC(ata_identify(ata_identify_data), 2, 2);
567 dma_mode = 0x44;
568 }
569 else
570 {
571 PWRCON(0) &= ~(1 << 5);
572 ATA_CFG = BIT(0);
573 sleep(HZ / 100);
574 ATA_CFG = 0;
575 sleep(HZ / 100);
576 ATA_SWRST = BIT(0);
577 sleep(HZ / 100);
578 ATA_SWRST = 0;
579 sleep(HZ / 10);
580 ATA_CONTROL = BIT(0);
581 sleep(HZ / 5);
582 ATA_PIO_TIME = 0x191f7;
583 ATA_PIO_LHR = 0;
584 while (!(ATA_PIO_READY & BIT(1))) yield();
585 PASS_RC(ata_identify(ata_identify_data), 2, 0);
586 uint32_t piotime = 0x11f3;
587 uint32_t mdmatime = 0x1c175;
588 uint32_t udmatime = 0x5071152;
589 uint32_t param = 0;
590 ata_dma_flags = 0;
591 ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
592 if (ata_identify_data[53] & BIT(1))
593 {
594 if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
595 else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
596 }
597 if (ata_identify_data[63] & BIT(2))
598 {
599 mdmatime = 0x5072;
600 param = 0x22;
601 }
602 else if (ata_identify_data[63] & BIT(1))
603 {
604 mdmatime = 0x7083;
605 param = 0x21;
606 }
607 if (ata_identify_data[63] & BITRANGE(0, 2))
608 {
609 ata_dma_flags = BIT(3) | BIT(10);
610 param |= 0x20;
611 }
612 if (ata_identify_data[53] & BIT(2))
613 {
614 if (ata_identify_data[88] & BIT(4))
615 {
616 udmatime = 0x2010a52;
617 param = 0x44;
618 }
619 else if (ata_identify_data[88] & BIT(3))
620 {
621 udmatime = 0x2020a52;
622 param = 0x43;
623 }
624 else if (ata_identify_data[88] & BIT(2))
625 {
626 udmatime = 0x3030a52;
627 param = 0x42;
628 }
629 else if (ata_identify_data[88] & BIT(1))
630 {
631 udmatime = 0x3050a52;
632 param = 0x41;
633 }
634 if (ata_identify_data[88] & BITRANGE(0, 4))
635 {
636 ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
637 param |= 0x40;
638 }
639 }
640 ata_dma = param ? true : false;
641 dma_mode = param;
642 PASS_RC(ata_set_feature(0xef, param), 2, 1);
643 if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
644 if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
645 ATA_PIO_TIME = piotime;
646 ATA_MDMA_TIME = mdmatime;
647 ATA_UDMA_TIME = udmatime;
648 }
649 spinup_time = current_tick - spinup_start;
650 if (ata_lba48)
651 ata_total_sectors = ata_identify_data[100]
652 | (((uint64_t)ata_identify_data[101]) << 16)
653 | (((uint64_t)ata_identify_data[102]) << 32)
654 | (((uint64_t)ata_identify_data[103]) << 48);
655 else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
656 ata_total_sectors >>= 3;
657 ata_powered = true;
658 ata_set_active();
659 return 0;
660}
661
662void ata_power_down(void)
663{
664 if (!ata_powered) return;
665 ata_powered = false;
666 if (ceata)
667 {
668 memset(ceata_taskfile, 0, 16);
669 ceata_taskfile[0xf] = 0xe0;
670 ceata_wait_idle();
671 ceata_write_multiple_register(0, ceata_taskfile, 16);
672 sleep(HZ);
673 PWRCON(0) |= (1 << 9);
674 }
675 else
676 {
677 ata_wait_for_rdy(1000000);
678 ata_write_cbr(&ATA_PIO_DVR, 0);
679 ata_write_cbr(&ATA_PIO_CSD, 0xe0);
680 ata_wait_for_rdy(1000000);
681 sleep(HZ / 30);
682 ATA_CONTROL = 0;
683 while (!(ATA_CONTROL & BIT(1))) yield();
684 PWRCON(0) |= (1 << 5);
685 }
686 ide_power_enable(false);
687}
688
689int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bool write)
690{
691 if (ceata)
692 {
693 memset(ceata_taskfile, 0, 16);
694 ceata_taskfile[0x2] = cnt >> 5;
695 ceata_taskfile[0x3] = sector >> 21;
696 ceata_taskfile[0x4] = sector >> 29;
697 ceata_taskfile[0x5] = sector >> 37;
698 ceata_taskfile[0xa] = cnt << 3;
699 ceata_taskfile[0xb] = sector << 3;
700 ceata_taskfile[0xc] = sector >> 5;
701 ceata_taskfile[0xd] = sector >> 13;
702 ceata_taskfile[0xf] = write ? 0x35 : 0x25;
703 PASS_RC(ceata_wait_idle(), 2, 0);
704 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
705 PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2);
706 }
707 else
708 {
709 PASS_RC(ata_wait_for_rdy(100000), 2, 0);
710 ata_write_cbr(&ATA_PIO_DVR, 0);
711 if (ata_lba48)
712 {
713 ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
714 ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
715 ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
716 ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
717 ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
718 ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
719 ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
720 ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
721 ata_write_cbr(&ATA_PIO_DVR, BIT(6));
722 if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
723 else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
724 }
725 else
726 {
727 ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
728 ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
729 ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
730 ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
731 ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
732 if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
733 else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
734 }
735 if (ata_dma)
736 {
737 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
738 if (write)
739 {
740 ATA_SBUF_START = buffer;
741 ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
742 ATA_CFG |= BIT(4);
743 }
744 else
745 {
746 ATA_TBUF_START = buffer;
747 ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
748 ATA_CFG &= ~BIT(4);
749 }
750 ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
751 ATA_CFG |= ata_dma_flags;
752 ATA_CFG &= ~(BIT(7) | BIT(8));
753 wakeup_wait(&ata_wakeup, 0);
754 ATA_IRQ = BITRANGE(0, 4);
755 ATA_IRQ_MASK = BIT(0);
756 ATA_COMMAND = BIT(0);
757 if (wakeup_wait(&ata_wakeup, 500000 * HZ / 1000000) == OBJ_WAIT_TIMEDOUT)
758 {
759 ATA_COMMAND = BIT(1);
760 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
761 RET_ERR(2);
762 }
763 ATA_COMMAND = BIT(1);
764 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
765 }
766 else
767 {
768 cnt *= SECTOR_SIZE / 512;
769 while (cnt--)
770 {
771 int i;
772 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
773 if (write)
774 for (i = 0; i < 256; i++)
775 ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
776 else
777 for (i = 0; i < 256; i++)
778 ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
779 buffer += 512;
780 }
781 }
782 PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
783 }
784 return 0;
785}
786
787int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
788{
789 led(true);
790 int rc = ata_rw_chunk_internal(sector, cnt, buffer, write);
791 led(false);
792 return rc;
793}
794
795#ifdef ATA_HAVE_BBT
796int ata_bbt_translate(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount)
797{
798 if (sector + count > ata_virtual_sectors) RET_ERR(0);
799 if (!ata_bbt)
800 {
801 *phys = sector;
802 *physcount = count;
803 return 0;
804 }
805 if (!count)
806 {
807 *phys = 0;
808 *physcount = 0;
809 return 0;
810 }
811 uint32_t offset;
812 uint32_t l0idx = sector >> 15;
813 uint32_t l0offs = sector & 0x7fff;
814 *physcount = MIN(count, 0x8000 - l0offs);
815 uint32_t l0data = ata_bbt[0][l0idx << 1];
816 uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
817 if (l0data < 0x8000) offset = l0data + base;
818 else
819 {
820 uint32_t l1idx = (sector >> 10) & 0x1f;
821 uint32_t l1offs = sector & 0x3ff;
822 *physcount = MIN(count, 0x400 - l1offs);
823 uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
824 if (l1data < 0x8000) offset = l1data + base;
825 else
826 {
827 uint32_t l2idx = (sector >> 5) & 0x1f;
828 uint32_t l2offs = sector & 0x1f;
829 *physcount = MIN(count, 0x20 - l2offs);
830 uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
831 if (l2data < 0x8000) offset = l2data + base;
832 else
833 {
834 uint32_t l3idx = sector & 0x1f;
835 uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
836 for (*physcount = 1; *physcount < count && l3idx + *physcount < 0x20; *physcount++)
837 if (ata_bbt[l2data & 0x7fff][l3idx + *physcount] != l3data)
838 break;
839 offset = l3data + base;
840 }
841 }
842 }
843 *phys = sector + offset;
844 return 0;
845}
846#endif
847
848int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
849{
850 if (((uint32_t)buffer) & 0xf)
851 panicf("ATA: Misaligned data buffer at %08X (sector %lu, count %lu)",
852 (unsigned int)buffer, (long unsigned int)sector, (long unsigned int)count);
853#ifdef ATA_HAVE_BBT
854 if (sector + count > ata_virtual_sectors) RET_ERR(0);
855 if (ata_bbt)
856 while (count)
857 {
858 uint64_t phys;
859 uint32_t cnt;
860 PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0);
861 uint32_t offset = phys - sector;
862 if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
863 ata_last_offset = offset;
864 ata_last_phys = phys + cnt;
865 PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
866 buffer += cnt * SECTOR_SIZE;
867 sector += cnt;
868 count -= cnt;
869 }
870 else PASS_RC(ata_rw_sectors_internal(sector, count, buffer, write), 0, 0);
871 return 0;
872}
873
874int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write)
875{
876#endif
877 if (sector + count > ata_total_sectors) RET_ERR(0);
878 if (!ata_powered) ata_power_up();
879 ata_set_active();
880 if (ata_dma && write) clean_dcache();
881 else if (ata_dma) invalidate_dcache();
882 if (!ceata) ATA_COMMAND = BIT(1);
883 while (count)
884 {
885 uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
886 int rc = -1;
887 rc = ata_rw_chunk(sector, cnt, buffer, write);
888 if (rc && ata_error_srst) ata_soft_reset();
889 if (rc && ata_retries)
890 {
891 void* buf = buffer;
892 uint64_t sect;
893 for (sect = sector; sect < sector + cnt; sect++)
894 {
895 rc = -1;
896 int tries = ata_retries;
897 while (tries-- && rc)
898 {
899 rc = ata_rw_chunk(sect, 1, buf, write);
900 if (rc && ata_error_srst) ata_soft_reset();
901 }
902 if (rc) break;
903 buf += SECTOR_SIZE;
904 }
905 }
906 PASS_RC(rc, 1, 1);
907 buffer += SECTOR_SIZE * cnt;
908 sector += cnt;
909 count -= cnt;
910 }
911 ata_set_active();
912 return 0;
913}
914
915static void ata_thread(void)
916{
917 while (true)
918 {
919 mutex_lock(&ata_mutex);
920 if (TIME_AFTER(current_tick, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
921 {
922 call_storage_idle_notifys(false);
923 ata_power_down();
924 }
925 mutex_unlock(&ata_mutex);
926 sleep(HZ / 2);
927 }
928}
929
930/* API Functions */
931int ata_soft_reset(void)
932{
933 int rc;
934 mutex_lock(&ata_mutex);
935 if (!ata_powered) ata_power_up();
936 ata_set_active();
937 if (ceata) rc = ceata_soft_reset();
938 else
939 {
940 ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
941 udelay(10);
942 ata_write_cbr(&ATA_PIO_DAD, 0);
943 rc = ata_wait_for_rdy(20000000);
944 }
945 if (IS_ERR(rc))
946 {
947 ata_power_down();
948 sleep(HZ * 3);
949 ata_power_up();
950 }
951 ata_set_active();
952 mutex_unlock(&ata_mutex);
953 return rc;
954}
955
956int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
957 void* inbuf)
958{
959 mutex_lock(&ata_mutex);
960 int rc = ata_rw_sectors(start, incount, inbuf, false);
961 mutex_unlock(&ata_mutex);
962 return rc;
963}
964
965int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
966 const void* outbuf)
967{
968 mutex_lock(&ata_mutex);
969 int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
970 mutex_unlock(&ata_mutex);
971 return rc;
972}
973
974void ata_spindown(int seconds)
975{
976 ata_sleep_timeout = seconds * HZ;
977}
978
979void ata_sleep(void)
980{
981 ata_last_activity_value = current_tick - ata_sleep_timeout + HZ / 5;
982}
983
984void ata_sleepnow(void)
985{
986 mutex_lock(&ata_mutex);
987 ata_power_down();
988 mutex_unlock(&ata_mutex);
989}
990
991void ata_close(void)
992{
993 ata_sleepnow();
994}
995
996void ata_spin(void)
997{
998 ata_set_active();
999}
1000
1001void ata_get_info(IF_MD2(int drive,) struct storage_info *info)
1002{
1003 (*info).sector_size = SECTOR_SIZE;
1004#ifdef ATA_HAVE_BBT
1005 (*info).num_sectors = ata_virtual_sectors;
1006#else
1007 (*info).num_sectors = ata_total_sectors;
1008#endif
1009 (*info).vendor = "Apple";
1010 (*info).product = "iPod Classic";
1011 (*info).revision = "1.0";
1012}
1013
1014long ata_last_disk_activity(void)
1015{
1016 return ata_last_activity_value;
1017}
1018
1019#ifdef ATA_HAVE_BBT
1020void ata_bbt_disable(void)
1021{
1022 mutex_lock(&ata_mutex);
1023 if (ata_bbt) free(ata_bbt);
1024 ata_bbt = NULL;
1025 ata_virtual_sectors = ata_total_sectors;
1026 mutex_unlock(&ata_mutex);
1027}
1028
1029void ata_bbt_reload(void)
1030{
1031 mutex_lock(&ata_mutex);
1032 ata_bbt_disable();
1033 ata_power_up();
1034 uint32_t* buf = (uint32_t*)(ata_bbt_buf + sizeof(ata_bbt_buf) - SECTOR_SIZE);
1035 if (buf)
1036 {
1037 if (IS_ERR(ata_bbt_read_sectors(0, 1, buf)))
1038 ata_virtual_sectors = ata_total_sectors;
1039 else if (!memcmp(buf, "emBIbbth", 8))
1040 {
1041 ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
1042 uint32_t count = buf[0x1ff];
1043 if (count > ATA_BBT_PAGES / 64)
1044 panicf("ATA: BBT too big! (space: %d, size: %d)", ATA_BBT_PAGES, count * 64);
1045 uint32_t i;
1046 uint32_t cnt;
1047 ata_bbt = (typeof(ata_bbt))ata_bbt_buf;
1048 for (i = 0; i < count; i += cnt)
1049 {
1050 uint32_t phys = buf[0x200 + i];
1051 for (cnt = 1; cnt < count; cnt++)
1052 if (buf[0x200 + i + cnt] != phys + cnt)
1053 break;
1054 if (IS_ERR(ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6])))
1055 {
1056 ata_virtual_sectors = ata_total_sectors;
1057 break;
1058 }
1059 }
1060 }
1061 else ata_virtual_sectors = ata_total_sectors;
1062 }
1063 else ata_virtual_sectors = ata_total_sectors;
1064 mutex_unlock(&ata_mutex);
1065}
1066#endif
1067
1068int ata_init(void)
1069{
1070 mutex_init(&ata_mutex);
1071 wakeup_init(&ata_wakeup);
1072 wakeup_init(&mmc_wakeup);
1073 wakeup_init(&mmc_comp_wakeup);
1074 ceata = PDAT(11) & BIT(1);
1075 if (ceata)
1076 {
1077 ata_lba48 = true;
1078 ata_dma = true;
1079 PCON(8) = 0x33333333;
1080 PCON(9) = (PCON(9) & ~0xff) | 0x33;
1081 PCON(11) |= 0xf;
1082 *((uint32_t volatile*)0x38a00000) = 0;
1083 *((uint32_t volatile*)0x38700000) = 0;
1084 }
1085 else
1086 {
1087 PCON(7) = 0x44444444;
1088 PCON(8) = 0x44444444;
1089 PCON(9) = 0x44444444;
1090 PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
1091 }
1092 ata_powered = false;
1093 ata_total_sectors = 0;
1094 ata_power_up();
1095#ifdef ATA_HAVE_BBT
1096 ata_bbt_reload();
1097#endif
1098 create_thread(ata_thread, ata_stack,
1099 sizeof(ata_stack), 0, "ATA idle monitor"
1100 IF_PRIO(, PRIORITY_USER_INTERFACE)
1101 IF_COP(, CPU));
1102 return 0;
1103}
1104
1105int ata_num_drives(int first_drive)
1106{
1107 /* We don't care which logical drive number(s) we have been assigned */
1108 (void)first_drive;
1109
1110 return 1;
1111}
1112
1113unsigned short* ata_get_identify(void)
1114{
1115 return ata_identify_data;
1116}
1117
1118int ata_spinup_time(void)
1119{
1120 return spinup_time;
1121}
1122
1123int ata_get_dma_mode(void)
1124{
1125 return dma_mode;
1126}
1127
1128void INT_ATA(void)
1129{
1130 uint32_t ata_irq = ATA_IRQ;
1131 ATA_IRQ = ata_irq;
1132 if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
1133 ATA_IRQ_MASK = 0;
1134}
1135
1136void INT_MMC(void)
1137{
1138 uint32_t irq = SDCI_IRQ;
1139 if (irq & SDCI_IRQ_DAT_DONE_INT) wakeup_signal(&mmc_wakeup);
1140 if (irq & SDCI_IRQ_IOCARD_IRQ_INT) wakeup_signal(&mmc_comp_wakeup);
1141 SDCI_IRQ = irq;
1142}
diff --git a/firmware/target/arm/s5l8702/system-s5l8702.c b/firmware/target/arm/s5l8702/system-s5l8702.c
index 4a8f47e59e..e264e61e22 100644
--- a/firmware/target/arm/s5l8702/system-s5l8702.c
+++ b/firmware/target/arm/s5l8702/system-s5l8702.c
@@ -97,7 +97,7 @@ default_interrupt(INT_IRQ40);
97default_interrupt(INT_IRQ41); 97default_interrupt(INT_IRQ41);
98default_interrupt(INT_IRQ42); 98default_interrupt(INT_IRQ42);
99default_interrupt(INT_IRQ43); 99default_interrupt(INT_IRQ43);
100default_interrupt(INT_IRQ44); 100default_interrupt(INT_MMC);
101default_interrupt(INT_IRQ45); 101default_interrupt(INT_IRQ45);
102default_interrupt(INT_IRQ46); 102default_interrupt(INT_IRQ46);
103default_interrupt(INT_IRQ47); 103default_interrupt(INT_IRQ47);
@@ -169,7 +169,7 @@ static void (* const irqvector[])(void) =
169 INT_DMAC0,INT_DMAC1,INT_IRQ18,INT_USB_FUNC,INT_IRQ20,INT_IRQ21,INT_IRQ22,INT_WHEEL, 169 INT_DMAC0,INT_DMAC1,INT_IRQ18,INT_USB_FUNC,INT_IRQ20,INT_IRQ21,INT_IRQ22,INT_WHEEL,
170 INT_IRQ24,INT_IRQ25,INT_IRQ26,INT_IRQ27,INT_IRQ28,INT_ATA,INT_IRQ30,INT_IRQ31, 170 INT_IRQ24,INT_IRQ25,INT_IRQ26,INT_IRQ27,INT_IRQ28,INT_ATA,INT_IRQ30,INT_IRQ31,
171 INT_IRQ32,INT_IRQ33,INT_IRQ34,INT_IRQ35,INT_IRQ36,INT_IRQ37,INT_IRQ38,INT_IRQ39, 171 INT_IRQ32,INT_IRQ33,INT_IRQ34,INT_IRQ35,INT_IRQ36,INT_IRQ37,INT_IRQ38,INT_IRQ39,
172 INT_IRQ40,INT_IRQ41,INT_IRQ42,INT_IRQ43,INT_IRQ55,INT_IRQ56,INT_IRQ57,INT_IRQ58, 172 INT_IRQ40,INT_IRQ41,INT_IRQ42,INT_IRQ43,INT_MMC,INT_IRQ45,INT_IRQ46,INT_IRQ47,
173 INT_IRQ48,INT_IRQ49,INT_IRQ50,INT_IRQ51,INT_IRQ52,INT_IRQ53,INT_IRQ54,INT_IRQ55, 173 INT_IRQ48,INT_IRQ49,INT_IRQ50,INT_IRQ51,INT_IRQ52,INT_IRQ53,INT_IRQ54,INT_IRQ55,
174 INT_IRQ56,INT_IRQ57,INT_IRQ58,INT_IRQ59,INT_IRQ60,INT_IRQ61,INT_IRQ62,INT_IRQ63 174 INT_IRQ56,INT_IRQ57,INT_IRQ58,INT_IRQ59,INT_IRQ60,INT_IRQ61,INT_IRQ62,INT_IRQ63
175}; 175};
@@ -218,6 +218,8 @@ void system_init(void)
218{ 218{
219 pmu_init(); 219 pmu_init();
220 VIC0INTENABLE = 1 << IRQ_WHEEL; 220 VIC0INTENABLE = 1 << IRQ_WHEEL;
221 VIC0INTENABLE = 1 << IRQ_ATA;
222 VIC1INTENABLE = 1 << (IRQ_MMC - 32);
221} 223}
222 224
223void system_reboot(void) 225void system_reboot(void)