@@ -549,6 +549,281 @@ rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr)
549
549
return ocr ;
550
550
}
551
551
552
+ rt_err_t mmcsd_set_signal_voltage (struct rt_mmcsd_host * host , unsigned char signal_voltage )
553
+ {
554
+ rt_err_t err = RT_EOK ;
555
+ unsigned char old_signal_voltage = host -> io_cfg .signal_voltage ;
556
+
557
+ host -> io_cfg .signal_voltage = signal_voltage ;
558
+ if (host -> ops -> signal_voltage_switch )
559
+ {
560
+ err = host -> ops -> signal_voltage_switch (host , & host -> io_cfg );
561
+ }
562
+
563
+ if (err )
564
+ {
565
+ host -> io_cfg .signal_voltage = old_signal_voltage ;
566
+ }
567
+
568
+ return err ;
569
+ }
570
+
571
+ void mmcsd_set_initial_signal_voltage (struct rt_mmcsd_host * host )
572
+ {
573
+ /* 3.3V -> 1.8v -> 1.2v */
574
+ if (!mmcsd_set_signal_voltage (host , MMCSD_SIGNAL_VOLTAGE_330 ))
575
+ {
576
+ LOG_D ("Initial signal voltage of %sv" , "3.3" );
577
+ }
578
+ else if (!mmcsd_set_signal_voltage (host , MMCSD_SIGNAL_VOLTAGE_180 ))
579
+ {
580
+ LOG_D ("Initial signal voltage of %sv" , "1.8" );
581
+ }
582
+ else if (!mmcsd_set_signal_voltage (host , MMCSD_SIGNAL_VOLTAGE_120 ))
583
+ {
584
+ LOG_D ("Initial signal voltage of %sv" , "1.2" );
585
+ }
586
+ }
587
+
588
+ rt_err_t mmcsd_host_set_uhs_voltage (struct rt_mmcsd_host * host )
589
+ {
590
+ rt_uint32_t old_clock = host -> io_cfg .clock ;
591
+
592
+ host -> io_cfg .clock = 0 ;
593
+ mmcsd_set_iocfg (host );
594
+
595
+ if (mmcsd_set_signal_voltage (host , MMCSD_SIGNAL_VOLTAGE_180 ))
596
+ {
597
+ return - RT_ERROR ;
598
+ }
599
+
600
+ /* Keep clock gated for at least 10 ms, though spec only says 5 ms */
601
+ rt_thread_mdelay (10 );
602
+
603
+ host -> io_cfg .clock = old_clock ;
604
+ mmcsd_set_iocfg (host );
605
+
606
+ return RT_EOK ;
607
+ }
608
+
609
+ static void mmcsd_power_cycle (struct rt_mmcsd_host * host , rt_uint32_t ocr );
610
+
611
+ rt_err_t mmcsd_set_uhs_voltage (struct rt_mmcsd_host * host , rt_uint32_t ocr )
612
+ {
613
+ rt_err_t err = RT_EOK ;
614
+ struct rt_mmcsd_cmd cmd ;
615
+
616
+ if (!host -> ops -> signal_voltage_switch )
617
+ {
618
+ return - RT_EINVAL ;
619
+ }
620
+
621
+ if (!host -> ops -> card_busy )
622
+ {
623
+ LOG_W ("%s: Cannot verify signal voltage switch" , host -> name );
624
+ }
625
+
626
+ rt_memset (& cmd , 0 , sizeof (struct rt_mmcsd_cmd ));
627
+
628
+ cmd .cmd_code = VOLTAGE_SWITCH ;
629
+ cmd .arg = 0 ;
630
+ cmd .flags = RESP_R1 | CMD_AC ;
631
+
632
+ err = mmcsd_send_cmd (host , & cmd , 0 );
633
+ if (err )
634
+ {
635
+ goto power_cycle ;
636
+ }
637
+
638
+ if (!controller_is_spi (host ) && (cmd .resp [0 ] & R1_ERROR ))
639
+ {
640
+ return - RT_EIO ;
641
+ }
642
+
643
+ /*
644
+ * The card should drive cmd and dat[0:3] low immediately
645
+ * after the response of cmd11, but wait 1 ms to be sure
646
+ */
647
+ rt_thread_mdelay (1 );
648
+ if (host -> ops -> card_busy && !host -> ops -> card_busy (host ))
649
+ {
650
+ err = - RT_ERROR ;
651
+ goto power_cycle ;
652
+ }
653
+
654
+ if (mmcsd_host_set_uhs_voltage (host ))
655
+ {
656
+ /*
657
+ * Voltages may not have been switched, but we've already
658
+ * sent CMD11, so a power cycle is required anyway
659
+ */
660
+ err = - RT_ERROR ;
661
+ goto power_cycle ;
662
+ }
663
+
664
+ /* Wait for at least 1 ms according to spec */
665
+ rt_thread_mdelay (1 );
666
+
667
+ /*
668
+ * Failure to switch is indicated by the card holding
669
+ * dat[0:3] low
670
+ */
671
+ if (host -> ops -> card_busy && host -> ops -> card_busy (host ))
672
+ {
673
+ err = - RT_ERROR ;
674
+ }
675
+
676
+ power_cycle :
677
+ if (err )
678
+ {
679
+ LOG_D ("%s: Signal voltage switch failed, power cycling card" , host -> name );
680
+ mmcsd_power_cycle (host , ocr );
681
+ }
682
+
683
+ return err ;
684
+ }
685
+
686
+ static const rt_uint8_t tuning_blk_pattern_4bit [] =
687
+ {
688
+ 0xff , 0x0f , 0xff , 0x00 , 0xff , 0xcc , 0xc3 , 0xcc ,
689
+ 0xc3 , 0x3c , 0xcc , 0xff , 0xfe , 0xff , 0xfe , 0xef ,
690
+ 0xff , 0xdf , 0xff , 0xdd , 0xff , 0xfb , 0xff , 0xfb ,
691
+ 0xbf , 0xff , 0x7f , 0xff , 0x77 , 0xf7 , 0xbd , 0xef ,
692
+ 0xff , 0xf0 , 0xff , 0xf0 , 0x0f , 0xfc , 0xcc , 0x3c ,
693
+ 0xcc , 0x33 , 0xcc , 0xcf , 0xff , 0xef , 0xff , 0xee ,
694
+ 0xff , 0xfd , 0xff , 0xfd , 0xdf , 0xff , 0xbf , 0xff ,
695
+ 0xbb , 0xff , 0xf7 , 0xff , 0xf7 , 0x7f , 0x7b , 0xde ,
696
+ };
697
+
698
+ static const rt_uint8_t tuning_blk_pattern_8bit [] =
699
+ {
700
+ 0xff , 0xff , 0x00 , 0xff , 0xff , 0xff , 0x00 , 0x00 ,
701
+ 0xff , 0xff , 0xcc , 0xcc , 0xcc , 0x33 , 0xcc , 0xcc ,
702
+ 0xcc , 0x33 , 0x33 , 0xcc , 0xcc , 0xcc , 0xff , 0xff ,
703
+ 0xff , 0xee , 0xff , 0xff , 0xff , 0xee , 0xee , 0xff ,
704
+ 0xff , 0xff , 0xdd , 0xff , 0xff , 0xff , 0xdd , 0xdd ,
705
+ 0xff , 0xff , 0xff , 0xbb , 0xff , 0xff , 0xff , 0xbb ,
706
+ 0xbb , 0xff , 0xff , 0xff , 0x77 , 0xff , 0xff , 0xff ,
707
+ 0x77 , 0x77 , 0xff , 0x77 , 0xbb , 0xdd , 0xee , 0xff ,
708
+ 0xff , 0xff , 0xff , 0x00 , 0xff , 0xff , 0xff , 0x00 ,
709
+ 0x00 , 0xff , 0xff , 0xcc , 0xcc , 0xcc , 0x33 , 0xcc ,
710
+ 0xcc , 0xcc , 0x33 , 0x33 , 0xcc , 0xcc , 0xcc , 0xff ,
711
+ 0xff , 0xff , 0xee , 0xff , 0xff , 0xff , 0xee , 0xee ,
712
+ 0xff , 0xff , 0xff , 0xdd , 0xff , 0xff , 0xff , 0xdd ,
713
+ 0xdd , 0xff , 0xff , 0xff , 0xbb , 0xff , 0xff , 0xff ,
714
+ 0xbb , 0xbb , 0xff , 0xff , 0xff , 0x77 , 0xff , 0xff ,
715
+ 0xff , 0x77 , 0x77 , 0xff , 0x77 , 0xbb , 0xdd , 0xee ,
716
+ };
717
+
718
+ rt_err_t mmcsd_send_tuning (struct rt_mmcsd_host * host , rt_uint32_t opcode , rt_err_t * cmd_error )
719
+ {
720
+ rt_err_t err = RT_EOK ;
721
+ int size ;
722
+ rt_uint8_t * data_buf ;
723
+ const rt_uint8_t * tuning_block_pattern ;
724
+ struct rt_mmcsd_req req = {};
725
+ struct rt_mmcsd_cmd cmd = {};
726
+ struct rt_mmcsd_data data = {};
727
+ struct rt_mmcsd_io_cfg * io_cfg = & host -> io_cfg ;
728
+
729
+ if (io_cfg -> bus_width == MMCSD_BUS_WIDTH_8 )
730
+ {
731
+ tuning_block_pattern = tuning_blk_pattern_8bit ;
732
+ size = sizeof (tuning_blk_pattern_8bit );
733
+ }
734
+ else if (io_cfg -> bus_width == MMCSD_BUS_WIDTH_4 )
735
+ {
736
+ tuning_block_pattern = tuning_blk_pattern_4bit ;
737
+ size = sizeof (tuning_blk_pattern_4bit );
738
+ }
739
+ else
740
+ {
741
+ return - RT_EINVAL ;
742
+ }
743
+
744
+ data_buf = rt_malloc (size );
745
+ if (!data_buf )
746
+ {
747
+ return - RT_ENOMEM ;
748
+ }
749
+
750
+ rt_memset (data_buf , 0 , size );
751
+ rt_memset (& req , 0 , sizeof (struct rt_mmcsd_req ));
752
+ rt_memset (& cmd , 0 , sizeof (struct rt_mmcsd_cmd ));
753
+ rt_memset (& data , 0 , sizeof (struct rt_mmcsd_data ));
754
+
755
+ req .cmd = & cmd ;
756
+ req .data = & data ;
757
+
758
+ cmd .cmd_code = opcode ;
759
+ cmd .flags = RESP_R1 | CMD_ADTC ;
760
+
761
+ data .blksize = size ;
762
+ data .blks = 1 ;
763
+ data .flags = DATA_DIR_READ ;
764
+
765
+ /*
766
+ * According to the tuning specs, Tuning process
767
+ * is normally shorter 40 executions of CMD19,
768
+ * and timeout value should be shorter than 150 ms
769
+ */
770
+ data .timeout_ns = 150 * 1000000 ;
771
+
772
+ mmcsd_send_request (host , & req );
773
+
774
+ if (cmd_error )
775
+ {
776
+ * cmd_error = cmd .err ;
777
+ }
778
+
779
+ if (cmd .err )
780
+ {
781
+ err = cmd .err ;
782
+ goto out_free ;
783
+ }
784
+
785
+ if (data .err )
786
+ {
787
+ err = data .err ;
788
+ goto out_free ;
789
+ }
790
+
791
+ if (rt_memcmp (data_buf , tuning_block_pattern , size ))
792
+ {
793
+ err = - RT_EIO ;
794
+ }
795
+
796
+ out_free :
797
+ rt_free (data_buf );
798
+
799
+ return err ;
800
+ }
801
+
802
+ rt_err_t mmcsd_send_abort_tuning (struct rt_mmcsd_host * host , rt_uint32_t opcode )
803
+ {
804
+ struct rt_mmcsd_cmd cmd = {};
805
+
806
+ /*
807
+ * eMMC specification specifies that CMD12 can be used to stop a tuning
808
+ * command, but SD specification does not, so do nothing unless it is eMMC.
809
+ */
810
+ if (opcode != SEND_TUNING_BLOCK_HS200 )
811
+ {
812
+ return 0 ;
813
+ }
814
+
815
+ cmd .cmd_code = STOP_TRANSMISSION ;
816
+ cmd .flags = RESP_SPI_R1 | RESP_R1 | CMD_AC ;
817
+
818
+ /*
819
+ * For drivers that override R1 to R1b, set an arbitrary timeout based
820
+ * on the tuning timeout i.e. 150ms.
821
+ */
822
+ cmd .busy_timeout = 150 ;
823
+
824
+ return mmcsd_send_cmd (host , & cmd , 0 );
825
+ }
826
+
552
827
static void mmcsd_power_up (struct rt_mmcsd_host * host )
553
828
{
554
829
int bit = __rt_fls (host -> valid_ocr ) - 1 ;
@@ -568,6 +843,8 @@ static void mmcsd_power_up(struct rt_mmcsd_host *host)
568
843
host -> io_cfg .bus_width = MMCSD_BUS_WIDTH_1 ;
569
844
mmcsd_set_iocfg (host );
570
845
846
+ mmcsd_set_initial_signal_voltage (host );
847
+
571
848
/*
572
849
* This delay should be sufficient to allow the power supply
573
850
* to reach the minimum voltage.
@@ -599,6 +876,17 @@ static void mmcsd_power_off(struct rt_mmcsd_host *host)
599
876
mmcsd_set_iocfg (host );
600
877
}
601
878
879
+ static void mmcsd_power_cycle (struct rt_mmcsd_host * host , rt_uint32_t ocr )
880
+ {
881
+ mmcsd_power_off (host );
882
+
883
+ /* Wait at least 1 ms according to SD spec */
884
+ rt_thread_mdelay (1 );
885
+
886
+ mmcsd_power_up (host );
887
+ mmcsd_select_voltage (host , ocr );
888
+ }
889
+
602
890
int mmcsd_wait_cd_changed (rt_int32_t timeout )
603
891
{
604
892
struct rt_mmcsd_host * host ;
0 commit comments