@@ -549,6 +549,147 @@ rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr)
549
549
return ocr ;
550
550
}
551
551
552
+ static const rt_uint8_t tuning_blk_pattern_4bit [] =
553
+ {
554
+ 0xff , 0x0f , 0xff , 0x00 , 0xff , 0xcc , 0xc3 , 0xcc ,
555
+ 0xc3 , 0x3c , 0xcc , 0xff , 0xfe , 0xff , 0xfe , 0xef ,
556
+ 0xff , 0xdf , 0xff , 0xdd , 0xff , 0xfb , 0xff , 0xfb ,
557
+ 0xbf , 0xff , 0x7f , 0xff , 0x77 , 0xf7 , 0xbd , 0xef ,
558
+ 0xff , 0xf0 , 0xff , 0xf0 , 0x0f , 0xfc , 0xcc , 0x3c ,
559
+ 0xcc , 0x33 , 0xcc , 0xcf , 0xff , 0xef , 0xff , 0xee ,
560
+ 0xff , 0xfd , 0xff , 0xfd , 0xdf , 0xff , 0xbf , 0xff ,
561
+ 0xbb , 0xff , 0xf7 , 0xff , 0xf7 , 0x7f , 0x7b , 0xde ,
562
+ };
563
+
564
+ static const rt_uint8_t tuning_blk_pattern_8bit [] =
565
+ {
566
+ 0xff , 0xff , 0x00 , 0xff , 0xff , 0xff , 0x00 , 0x00 ,
567
+ 0xff , 0xff , 0xcc , 0xcc , 0xcc , 0x33 , 0xcc , 0xcc ,
568
+ 0xcc , 0x33 , 0x33 , 0xcc , 0xcc , 0xcc , 0xff , 0xff ,
569
+ 0xff , 0xee , 0xff , 0xff , 0xff , 0xee , 0xee , 0xff ,
570
+ 0xff , 0xff , 0xdd , 0xff , 0xff , 0xff , 0xdd , 0xdd ,
571
+ 0xff , 0xff , 0xff , 0xbb , 0xff , 0xff , 0xff , 0xbb ,
572
+ 0xbb , 0xff , 0xff , 0xff , 0x77 , 0xff , 0xff , 0xff ,
573
+ 0x77 , 0x77 , 0xff , 0x77 , 0xbb , 0xdd , 0xee , 0xff ,
574
+ 0xff , 0xff , 0xff , 0x00 , 0xff , 0xff , 0xff , 0x00 ,
575
+ 0x00 , 0xff , 0xff , 0xcc , 0xcc , 0xcc , 0x33 , 0xcc ,
576
+ 0xcc , 0xcc , 0x33 , 0x33 , 0xcc , 0xcc , 0xcc , 0xff ,
577
+ 0xff , 0xff , 0xee , 0xff , 0xff , 0xff , 0xee , 0xee ,
578
+ 0xff , 0xff , 0xff , 0xdd , 0xff , 0xff , 0xff , 0xdd ,
579
+ 0xdd , 0xff , 0xff , 0xff , 0xbb , 0xff , 0xff , 0xff ,
580
+ 0xbb , 0xbb , 0xff , 0xff , 0xff , 0x77 , 0xff , 0xff ,
581
+ 0xff , 0x77 , 0x77 , 0xff , 0x77 , 0xbb , 0xdd , 0xee ,
582
+ };
583
+
584
+ rt_err_t mmcsd_send_tuning (struct rt_mmcsd_host * host , rt_uint32_t opcode , rt_err_t * cmd_error )
585
+ {
586
+ rt_err_t err = RT_EOK ;
587
+ int size ;
588
+ rt_uint8_t * data_buf ;
589
+ const rt_uint8_t * tuning_block_pattern ;
590
+ struct rt_mmcsd_req req = {};
591
+ struct rt_mmcsd_cmd cmd = {};
592
+ struct rt_mmcsd_data data = {};
593
+ struct rt_mmcsd_io_cfg * io_cfg = & host -> io_cfg ;
594
+
595
+ if (io_cfg -> bus_width == MMCSD_BUS_WIDTH_8 )
596
+ {
597
+ tuning_block_pattern = tuning_blk_pattern_8bit ;
598
+ size = sizeof (tuning_blk_pattern_8bit );
599
+ }
600
+ else if (io_cfg -> bus_width == MMCSD_BUS_WIDTH_4 )
601
+ {
602
+ tuning_block_pattern = tuning_blk_pattern_4bit ;
603
+ size = sizeof (tuning_blk_pattern_4bit );
604
+ }
605
+ else
606
+ {
607
+ return - RT_EINVAL ;
608
+ }
609
+
610
+ data_buf = rt_malloc (size );
611
+ if (!data_buf )
612
+ {
613
+ return - RT_ENOMEM ;
614
+ }
615
+
616
+ rt_memset (data_buf , 0 , size );
617
+ rt_memset (& req , 0 , sizeof (struct rt_mmcsd_req ));
618
+ rt_memset (& cmd , 0 , sizeof (struct rt_mmcsd_cmd ));
619
+ rt_memset (& data , 0 , sizeof (struct rt_mmcsd_data ));
620
+
621
+ req .cmd = & cmd ;
622
+ req .data = & data ;
623
+
624
+ cmd .cmd_code = opcode ;
625
+ cmd .flags = RESP_R1 | CMD_ADTC ;
626
+
627
+ data .blksize = size ;
628
+ data .blks = 1 ;
629
+ data .flags = DATA_DIR_READ ;
630
+
631
+ /*
632
+ * According to the tuning specs, Tuning process
633
+ * is normally shorter 40 executions of CMD19,
634
+ * and timeout value should be shorter than 150 ms
635
+ */
636
+ data .timeout_ns = 150 * 1000000 ;
637
+
638
+ mmcsd_send_request (host , & req );
639
+
640
+ if (cmd_error )
641
+ {
642
+ * cmd_error = cmd .err ;
643
+ }
644
+
645
+ if (cmd .err )
646
+ {
647
+ err = cmd .err ;
648
+ goto out_free ;
649
+ }
650
+
651
+ if (data .err )
652
+ {
653
+ err = data .err ;
654
+ goto out_free ;
655
+ }
656
+
657
+ if (rt_memcmp (data_buf , tuning_block_pattern , size ))
658
+ {
659
+ err = - RT_EIO ;
660
+ }
661
+
662
+ out_free :
663
+ rt_free (data_buf );
664
+
665
+ return err ;
666
+ }
667
+
668
+ rt_err_t mmcsd_send_abort_tuning (struct rt_mmcsd_host * host , rt_uint32_t opcode )
669
+ {
670
+ struct rt_mmcsd_cmd cmd = {};
671
+
672
+ /*
673
+ * eMMC specification specifies that CMD12 can be used to stop a tuning
674
+ * command, but SD specification does not, so do nothing unless it is eMMC.
675
+ */
676
+ if (opcode != SEND_TUNING_BLOCK_HS200 )
677
+ {
678
+ return 0 ;
679
+ }
680
+
681
+ cmd .cmd_code = STOP_TRANSMISSION ;
682
+ cmd .flags = RESP_SPI_R1 | RESP_R1 | CMD_AC ;
683
+
684
+ /*
685
+ * For drivers that override R1 to R1b, set an arbitrary timeout based
686
+ * on the tuning timeout i.e. 150ms.
687
+ */
688
+ cmd .busy_timeout = 150 ;
689
+
690
+ return mmcsd_send_cmd (host , & cmd , 0 );
691
+ }
692
+
552
693
static void mmcsd_power_up (struct rt_mmcsd_host * host )
553
694
{
554
695
int bit = __rt_fls (host -> valid_ocr ) - 1 ;
0 commit comments