@@ -549,6 +549,281 @@ rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr)
549549 return ocr ;
550550}
551551
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+
552827static void mmcsd_power_up (struct rt_mmcsd_host * host )
553828{
554829 int bit = __rt_fls (host -> valid_ocr ) - 1 ;
@@ -568,6 +843,8 @@ static void mmcsd_power_up(struct rt_mmcsd_host *host)
568843 host -> io_cfg .bus_width = MMCSD_BUS_WIDTH_1 ;
569844 mmcsd_set_iocfg (host );
570845
846+ mmcsd_set_initial_signal_voltage (host );
847+
571848 /*
572849 * This delay should be sufficient to allow the power supply
573850 * to reach the minimum voltage.
@@ -599,6 +876,17 @@ static void mmcsd_power_off(struct rt_mmcsd_host *host)
599876 mmcsd_set_iocfg (host );
600877}
601878
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+
602890int mmcsd_wait_cd_changed (rt_int32_t timeout )
603891{
604892 struct rt_mmcsd_host * host ;
0 commit comments