@@ -527,7 +527,15 @@ fn read();
527
527
/// Card Detect
528
528
///
529
529
*/
530
+
531
+ /// Implementation Switch
530
532
fn smhc_init ( smhc0 : SMHC0 ) {
533
+ unsafe { sunxi_mmc_init_host ( smhc0) }
534
+ //smhc_init_old(smhc0)
535
+ }
536
+
537
+ /// Prior work from Danial and Ben hacking
538
+ fn smhc_init_old ( smhc0 : SMHC0 ) {
531
539
let div = smhc0. smhc_clkdiv . read ( ) . cclk_div ( ) . bits ( ) ;
532
540
println ! ( "smhc0 clk div {:x}" , div) ;
533
541
// STEP 0: celebration of calibration
@@ -622,6 +630,132 @@ fn smhc_init(smhc0: SMHC0) {
622
630
println ! ( "SD card {:02x}{:02x}{:02x}{:02x}" , r0, r1, r2, r3) ;
623
631
}
624
632
633
+ // ************** Begin port *******
634
+ // Port from https://github.com/orangecms/linux/blob/5.19-smaeul-plus-dts/drivers/mmc/host/sunxi-mmc.c
635
+ // at 1875b10fc1e966475949782610ca578a87ee3d06
636
+
637
+ /// Read from a host at register
638
+ /// TODO: lock down type to enum registers/offsets
639
+ fn mmc_readl ( host : SMHC0 , reg : u32 ) {
640
+ /*
641
+ #define mmc_readl(host, reg) \
642
+ readl((host)->reg_base + SDXC_##reg)
643
+ */
644
+ }
645
+
646
+ fn mmc_writel ( host : SMHC0 , reg : u32 , value : u32 ) {
647
+ /*
648
+ #define mmc_writel(host, reg, value) \
649
+ writel((value), (host)->reg_base + SDXC_##reg)
650
+ */
651
+ }
652
+
653
+ unsafe fn sunxi_mmc_reset_host ( host : SMHC0 ) -> Result < ( ) , & ' static str > {
654
+ host. smhc_ctrl
655
+ . write ( |w| w. soft_rst ( ) . reset ( ) . fifo_rst ( ) . reset ( ) . dma_rst ( ) . set_bit ( ) ) ;
656
+ while host. smhc_ctrl . read ( ) . soft_rst ( ) . is_reset ( )
657
+ || host. smhc_ctrl . read ( ) . fifo_rst ( ) . is_reset ( )
658
+ || host. smhc_ctrl . read ( ) . dma_rst ( ) . bit_is_set ( )
659
+ {
660
+ println ! ( "Print shit or whatevere" ) ;
661
+ }
662
+
663
+ Ok ( ( ) )
664
+ /*
665
+ unsigned long expire = jiffies + msecs_to_jiffies(250);
666
+ u32 rval;
667
+
668
+ #define SDXC_HARDWARE_RESET \
669
+ (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET)
670
+ #define SDXC_SOFT_RESET BIT(0)
671
+ #define SDXC_FIFO_RESET BIT(1)
672
+ #define SDXC_DMA_RESET BIT(2)
673
+
674
+ mmc_writel(host, REG_GCTRL, SDXC_HARDWARE_RESET);
675
+ do {
676
+ rval = mmc_readl(host, REG_GCTRL);
677
+ } while (time_before(jiffies, expire) && (rval & SDXC_HARDWARE_RESET));
678
+
679
+ if (rval & SDXC_HARDWARE_RESET) {
680
+ dev_err(mmc_dev(host->mmc), "fatal err reset timeout\n");
681
+ return -EIO;
682
+ }
683
+
684
+ return 0
685
+ */
686
+ }
687
+
688
+ unsafe fn sunxi_mmc_init_host( host : SMHC0 ) {
689
+ /*
690
+ u32 rval;
691
+
692
+ if (sunxi_mmc_reset_host(host))
693
+ return -EIO;
694
+ print!("=========== init smhc ...");
695
+ //if let Err(msg) = sunxi_mmc_reset_host(host) {
696
+ // println!("failed to reset smhc host: {}", msg);
697
+ //}
698
+ host.smhc_ctrl
699
+ .write(|w| w.soft_rst().reset().fifo_rst().reset().dma_rst().set_bit());
700
+ while host.smhc_ctrl.read().soft_rst().is_reset()
701
+ || host.smhc_ctrl.read().fifo_rst().is_reset()
702
+ || host.smhc_ctrl.read().dma_rst().bit_is_set()
703
+ {
704
+ println!("...Resetting controller");
705
+ }
706
+ */
707
+ println ! ( "Done!" ) ;
708
+
709
+ /* SMC FIFO Threshold Watermark Register
710
+ *
711
+ * From linux we have:
712
+ * /*
713
+ * * Burst 8 transfers, RX trigger level: 7, TX trigger level: 8
714
+ * *
715
+ * * TODO: sun9i has a larger FIFO and supports higher trigger values
716
+ * */
717
+ * mmc_writel(host, REG_FTRGL, 0x20070008)
718
+ *
719
+ * D1 has 1024 bytes Rx & TX FIFO
720
+ *
721
+ * Decode of magic value from linux:
722
+ * 0x20070008 = 0010 0000 0000 0111 0000 0000 0000 1000
723
+ * x xxxx xxxx xxxx Reserved
724
+ * yyy BSIZE_OF_TRANS = 8 transfers
725
+ * zzzz zzzz RX_TL (Trigger Level)
726
+ * aaaa aaaa = TX_TL TX Trigger Level
727
+ */
728
+ host. smhc_fifoth
729
+ . write ( |w| w. bsize_of_trans ( ) . t8 ( ) . rx_tl ( ) . bits ( 7 ) . tx_tl ( ) . bits ( 8 ) ) ;
730
+ /*
731
+ mmc_writel(host, REG_FTRGL, 0x20070008);
732
+ /* Maximum timeout value */
733
+ // mmc_writel(host, REG_TMOUT, 0xffffffff);
734
+
735
+ /*
736
+ /* Unmask SDIO interrupt if needed */
737
+ mmc_writel(host, REG_IMASK, host->sdio_imask);
738
+ /* Clear all pending interrupts */
739
+ mmc_writel(host, REG_RINTR, 0xffffffff);
740
+ /* Debug register? undocumented */
741
+ mmc_writel(host, REG_DBGC, 0xdeb);
742
+ /* Enable CEATA support */
743
+ mmc_writel(host, REG_FUNS, SDXC_CEATA_ON);
744
+ /* Set DMA descriptor list base address */
745
+ mmc_writel(host, REG_DLBA, host->sg_dma >> host->cfg->idma_des_shift);
746
+
747
+ rval = mmc_readl(host, REG_GCTRL);
748
+ rval |= SDXC_INTERRUPT_ENABLE_BIT;
749
+ /* Undocumented, but found in Allwinner code */
750
+ rval &= ~SDXC_ACCESS_DONE_DIRECT;
751
+ mmc_writel(host, REG_GCTRL, rval);
752
+
753
+ return 0;
754
+ */
755
+ }
756
+
757
+ // ************** End port *******
758
+
625
759
extern "C" fn main() -> usize {
626
760
// there was configure_ccu_clocks, but ROM code have already done configuring for us
627
761
let p = Peripherals::take().unwrap();
0 commit comments