Rockchip RK3399 - MMC&SD&SDIO基础

----------------------------------------------------------------------------------------------------------------------------

开发板 :NanoPC-T4开发板eMMC16GBLPDDR34GB
显示屏 :15.6英寸HDMI接口显示屏u-boot2023.04linux6.3
----------------------------------------------------------------------------------------------------------------------------

MMCMultiMedia Card的简称,从本质上看,它是一种用于固态非易失性存储的内存卡规范,定义了诸如卡的形态、尺寸、容量、电气信号、和主机之间的通信协议等方方面面的内容。

1997MMC规范发布至今,基于不同的考量(物理尺寸、电压范围、管脚数量、最大容量、数据位宽、clock频率、安全特性、是否支持SPI mode、是否支持DDR mode等等),进化出了MMCSDmicro SDSDIOeMMC等不同的规范;

Rockchip RK3399 - MMC&SD&SDIO基础_第1张图片

需要注意的是:这张图只供参考,2012年之后的规范并没有绘制。

SD卡基于MMC发展而来,二者最初的外观尺寸也很类似,SD卡比MMC卡厚0.7mm

早期SD卡对MMC卡的兼容性较强,多数支持SD卡插槽的设备都可以同时支持MMC卡,反之只有MMC卡插槽的设备不能够支持SD卡。

随着MMC卡和 SD卡的发展竞争,二者之间的差异越来越大,走向了截然不同的发展方向。

发展到今天, MMC卡基本退出了历史舞台,转而走向了嵌入式领域,推出了eMMC(embedded MMC) 标准,在嵌入式存储方面应用广泛。

SD卡在移动存储卡领域的地位越发稳固,不断向大容量和高速度方向发展,推出了一系列接口标准,目前最新的理论传输速率已达 985MB/s

从二者目前的发展趋势看,eMMC正在被更先进的UFS技术标准取代,SD的发展前景似乎更为广阔。

一、MMC发展历史

MMC卡的全称是MultiMedia Card,中文翻译为“多媒体卡”。

MMC卡的设计目标是提供一种“广泛应用于电子玩具、pda、照相机、智能手机、数字录音机、MP3播放器、寻呼机等等领域”的通用低成本数据存储和通信媒体。

1.1 MMC 1.x/2.x版本阶段

从目前可检索到的MMC技术文档来看,MMC初始1.0版本的Spec1996年就已经制定完成,1997年推出相关产品。

1.02.0版本的发展阶段在1996-2000年,该阶段MMC卡的形态及技术规格没有大的变化,主要是一些内部功能性的演进。

这个阶段MMC卡的主要特性:

  • Size24mm x 32mm x 1.4mm
  • Pins7pins
  • Bus Width1bit
  • Bus ModeMMC mode& SPI mode
  • Voltage2.7 - 3.6V
  • Clock0 – 20MHz
1.2 MMC v3.x版本阶段

v3.0版本是MMC发展历史上一个重要的版本,该版本相对于1.0/2.0版本有重大变化。

但是由于v3.0版本在内部寄存器定义中有严重错误,v3.0版本很快被更新为v3.1,并且v3.0版本被废弃。

v3.1版本新增了两个重要特性:

  • 引入Low Voltage规格,支持1.65 - 1.95V工作电压;
  • 增加multiple block read/write特性,提升Performance

v3.3版本也是一个重要的版本,该版本新增RS-MMC(Reduced Size MMC)规格,制定24mm x 18mm x 1.4mm尺寸规格,将MMC 卡的大小减少近一半。

RS-MMC只是物理尺寸的定义,硬件接口没有变化。

1.3 MMC v4.x版本阶段

v4.x系列版本从2004年开始发布,v4.xMMC最为流行的版本,也是目前为止持续时间最长的版本,从2004年v4.1发布到2013 v5.0 发布共持续了9年。

其间,JEDEC (Joint Electron Device Engineering Council电子元件工业联合会)采用MMC4.1标准作为JEDEC的闪存卡标准;

随后MMCA(Multi Media Card Association快闪记忆卡标准组织)正式并入 JEDECMMC标准由JEDEC主导推进。

目前,从JEDEC官方站点可以下载到的MMC最早版本为v4.1,其直接继承自MMCAMMC v4.1版本。

1.3.1 MMC v4.1版本

鉴于之前版本的MMC卡性能较差,v4.1版本增加了以下重要的特性以提升性能并做到向后兼容:

  • 工作频率支持三种模式:0-20MHz0-26MHz0-52MHz
  • Bus Width支持三种模式:1/4/8bits
  • 定义了最低Performance标准:2.4MB/s
  • 向后兼容v3.x版本MMC(1 bit data busmulticard systems);
  • MMC mode只支持one card per MMC bus;
  • SPI mode支持MMC Chip Select Signal,可实现multiple cards per MMC bus
  • 提升MMC卡的存储容量;

符合v4.1版本规格的MMC卡称为HS MMC(High Speed MMC),由于bus width变化,所以HS MMC卡的接口增加了6pins,变成 13pins

v4.1版本对市场上的MMC产品进行了明确的划分,定义了两种MMC卡类型:MMC plusMMC mobile,只有符合相应规格的卡片才能使用 MMC plusMMC mobile logo

MMC plusMMC mobile应用于不同的使用场景,均向后兼容v3.x 20MHz clock的工作模式.

(1 )MMC plus规格:

  • size24mm x 32mm x 1.4mm,全尺寸;
  • Voltage2.7 - 3.6V
  • Pins13pins
  • bus width1/4/8bits
  • Bus ModeMMC mode & SPI mode
  • Clock26MHz(52MHz可选);
  • Performance:不低于2.4MB/s

(2) MMC mobile规格:

  • size24mm x 18mm x 1.4mm,符合RS-MMC标准;
  • Voltage2.7 - 3.6V/1.65 - 1.95V,支持Low Voltage模式;
  • Pins13pins
  • bus width1/4/8bits
  • Bus ModeMMC mode & SPI mode
  • Clock26MHz(52MHz可选);
  • Performance:不低于2.4MB/s

(3) MMC mirco规格:

Samsung2004年底发布了一款MMC mirco卡,该卡不同于MMC Spec中定义的MMC plusMMC mobile规格,其尺寸降低至:12mm x 14mm x 1.1mm,大概为RS-MMC1/3

MMC microSamsung发布的第三方规格,初期并没有收录到MMC标准中,依靠Samsung自身的影响力及其轻巧的尺寸占有一定的市场地位。

随后,MMCA协会也正式发布了MMCmicro的技术规范。在20056月底于瑞士苏黎世举行的MMCA夏季大会上,MMCA全体参会成员一致同意将MMC micro卡确立为MMCA新一代标准。

2004年底MMCA发布MMC plus卡和MMC mobile卡之后,全新的微小尺寸的MMC micro卡可谓是MMC技术的新一代标准。

1.3.2 MMC v4.2版本

v4.1版本定义的寻址方式为Byte寻址,理论上可以支持最大容量为4GB

v4.2版本增加了sector寻址模式,每个sector512Byte,小于2GB容量的卡采用Byte寻址模式,大于2GB容量的卡采用sector 寻址模式。

同时v4.2版本将Low Voltage工作电压范围修改为1.7 - 1.95V

1.3.3 MMC v4.3版本

v4.3版本也是MMC发展史上一个具有里程碑式意义的版本,该版本引入了eMMC规格定义,支持eMMC boot启动功能,进入嵌入式领域。

重新定义了CID寄存器的格式,以区分DeviceeMMC还是MMC卡。

虽然MMC Spec并没有正式收录MMC micro卡的规格,但是在v4.3 Spec还是增加定义了MMC microsignal input capacitance(信号输入电容标准)。

1.3.4 MMC v4.4x版本

v4.4版本一个重要的改动是加入了DDR(Dual Data Rate)模式,即信号的双边采样,在clock的上升沿和下降沿都会采样一次数据。

DDR mode将理论传输速率提升了一倍,达到104MB/s

v4.4版本还新增了RPMB(Replay Protected Memory Block)功能,用于实现数据的加密读写。RPMB主要用于系统一些关键私密的数据的存储。

接下来的v4.41版本主要增加了Background Operations 和 High Priority Interrupt两个可选的功能,不强制要求实现。

  • Background Operations赋予MMC/eMMC执行后台操作的能力;
  • High Priority Interrupt允许MMC/eMMC的某些命令执行允许被更高优先级的任务中断;
1.3.5 eMMC v4.5x版本

v4.5版本是MMC发展史上另一个里程碑式的版本,该版本封面正式移除了MMCAlogo,只保留了JEDEClogoMMCA退出历史舞台。

同时v4.5版本移除了MMC卡的支持,只保留eMMC的规格定义,MMC 卡也退出了历史舞台,进入了eMMC标准时代。

v4.5版本其他重要的改进包括:

  • 增加HS200 mode,将工作频率提高到200MHz,理论传输速率可达200MB/s

  • 增加Cache功能,进一步提升eMMC的性能;

1.4 eMMC v5.x 版本阶段

该阶段eMMC的发展的主要方向在于提升性能。

2013年发布的v5.0版本增加了HS400 mode,在HS200的基础上增加DDR mode(信号双边采样),将理论传输速率提升至400MB/s

2015年发布的v5.1版本增加了Command Queue功能,优化eMMC内部的操作效率,提升eMMC整体的Performance

v5.1版本同时发布了一个Command Queue Host Controller Interface(CQHCI)标准,用于Host端实现Command Queue硬件支持的设计标准。

另外v5.1版本新增了HS400ES mode,在HS400 mode的基础上提高了CMD Responce接收到可靠性。

1.5 总结

MMC发展到今天,只剩下嵌入式应用的eMMC标准,但是在2015v5.1版本发布后,已经有4年没有更新标准了。

eMMC如果想进一步提升性能,就需要采用更高频率的clock,对于eMMC使用的并行接口而言,可能会遇到信号完整性等方面的瓶颈。

2016JEDEC发布的UFS存储标准采用差分串行总线取代了eMMC的并行接口,可以达到远超eMMC的性能,有替代eMMC的趋势。

目前在高端手持移动设备领域,UFS正在逐步替代eMMC;在车机、低成本/低端的手持设备以及其他一些嵌入式设备中,eMMC还占有较高的应用比例。

eMMCUFS目前都是JEDEC在维护开发,不存在竞争关系,从现状看,eMMC再推出革命性的版本升级的可能性不大。

因此,可以猜测未来的发展趋势:eMMC可能会逐步被UFS取代,成为过时的技术;eMMC也会长期存在于一些低成本或对存储性能要求不高的设备上。

二、SD发展历史

SD(Secure Digital Memory Card) 卡是在MMC卡基础 上发展起来的,中文名称为:安全数字存储卡。

SD卡发布之初,与MMC卡的最大区别就在安全(Secure)上,其支持SDMI标准,可提供保护SD卡上存储的音乐版权等功能。

SD卡于1999年开发研制,PanasonicSandiskToshiba2000年成立了 SDA(SD Association) 协会主导SD卡的标准制定。

到目前为止,SD卡的标准已经发展到v7.0,在移动存储卡领域已经占据主导性地位。

2.1 v1.xx版本阶段

v1.xx版本阶段从2000年开始,持续到2006v2.xx版本发布。

也许是受益于后发优势,SD卡在初始v1.00版本就支持了双电压操作模式和1/4bits bus width,上市之初其被市场接纳程度就超过同期的MMC卡。

SD卡初始发布的v1.00版本规格的主要特性有:

  • Size24mm x 32mm x 2.1mm(Normal)/24mm x 32mm x 1.4mm(Thin);
  • Pins9pins;
  • Bus Width1/4bits;
  • Bus ModeSD mode & SPI mode;
  • Voltage2.0 - 3.6V/1.6 - 3.6V;
  • Clock0 – 25MHz;
  • Performance10MB/s;

为了应对RS-MMC的市场竞争,2003年由SanDisk率先推出了miniSD,尺寸为:21.5mm x 20mm x 1.4mm,号称当时最小尺寸的 Nand存储卡。

SD卡和MMC卡在竞争中向前发展,2004年发布的SD v1.10版本的主要竞争对手是MMC v4.x标准。

SD v1.10引入了High Speed mode,将Clock频率提升到0 - 50MHz,最大理论Performance25MB/s,兼容MMC v2.11标准。

同时推出TransFlash Card,又称 T-Flash 或者TF卡,后来统一为microSD卡。

microSD的尺寸只有:11mm x15mm x 1mm

至此,SD的物理尺寸一共有三种:SDminiSDmicroSD,在后来的市场筛选中只保留了SDmircoSD两种标准,也就是现在可以买到的两种SD卡(如下图所示);

Rockchip RK3399 - MMC&SD&SDIO基础_第2张图片
2.2 v2.xx版本阶段

SD卡和MMC卡类似,在三个方向发展进化:速度,容量,尺寸。

v1.xx版本阶段,SD卡的尺寸规格已基本定型,2006年推出的v2.00标准将SD卡的容量扩展到32GB,将SD卡容量分为SD/SDHC两种规格:

  • SDStandard Capacity SD Memory Card,指2GB及以下容量的SD卡;
  • SDHCHigh Capacity SD Memory Card,指2GB – 32GB容量的SD卡;
2.3 v3.xx版本阶段

2009年开始发布的v3.xx版本是SD卡发展历史上很重要的一个阶段,虽然现在SD卡标准已发展到v7.xx,但是v3.xx依然非常流行。

v3.xxv2.xx版本的基础上有如下重大更新:

  • 新增SDXC容量标准,SDXC规格的SD卡容量为32GB – 2TB
  • 引入UHS-I(Ultra High Speed)总线标准,将Clock提升到208MHz,最高理论传输速率为104MB/s

v3.xx版本,SD卡基本分类:

  • 容量:SD(0-2GB),SDHC(2 - 32GB),SDXC(32GB – 2TB);
  • 速度:Default(0 - 25MHz),High Speed mode (0 - 50MHz),UHS - I(0 -208MHz);
2.4 v4.xx版本阶段

v3.xx版本到v4.xx版本,可以算作SD卡发展到一个分水岭。

v3.xx版本,SD卡支持的Bus规格都是4bits宽度的并行总线,最高工作频率达到208MHz,理论传输速率可达104MB/s

eMMC遇到的问题一样,v3.xx版本的SD标准想进一步提高传输速率的话,4bits的并行总线会成为其阻力。

因此v4.xx版本引入了UHS-II mode,该mode使用了低电压串行差分总线技术,将理论传输速率提升至312MB/s,支持全双工模式,单路理论速率为1.56Gbps

2.5 快速发展阶段

v4.20版本之后,SD标准进入了一个快速发展阶段,下面这张SD技术演进图可以很好地展示其发展脉络;

Rockchip RK3399 - MMC&SD&SDIO基础_第3张图片

v5.xx版本统一了SD卡容量和速度的分类规范;

v6.xx版本引入了新的速度模式,UHS-III,将理论传输速率提升至524MB/s

v7.xx版本在速度和容量都有升级,推出了SDUC容量规格,总线传输支持PCIe,理论传输速率提升到940MB/s

2.6 总结

SD标准的技术发展现状和市场现有的SD卡产品来看,标准的制定已经远远领先于产品技术的发展。

当下SD卡的发展方向无非就是更大的容量和更快的速度,这两个发展方向都依赖于固态存储的技术进步。

SD标准已经将传输管道做得足够粗,接下来就看各SD卡厂商如何填满这个粗管道,有效利用其传输性能。

三、SDIO

SDIO是在SD卡接口的基础上发展起来的外设接口,SDIO接口兼容以前的SD卡,并且可以连接SDIO接口的设备,目前根据SDIO协议的SPECSDIO接口支持的设备总类有WIFIBluetoothGPS等等。

3.1 SDIO总线引脚定义

SDIO是Host (主机)和SDIO接口设备 (比如SD卡) 之间的通信总线,包括6根信号 ,这些信号的电平标准为3.3V ;

名称 方向 描述
SDCMD 当发起命令时Host输出;当响应时SDIO接口设备输出 传输命令和响应
SDCLK 由主机产生 时钟信号
SDDAT0 当写数据时Host输出;当读数据时SDIO接口设备输出 Data line 0
SDDAT1 当写数据时Host输出;当读数据时SDIO接口设备输出 Data line 1
SDDAT2 当写数据时Host输出;当读数据时SDIO接口设备输出 Data line 2
SDDAT3 当写数据时Host输出;当读数据时SDIO接口设备输出 Data line 3

下图展示了SD卡 和microSD卡的SDIO信号定义。SD卡(9个引脚)和microSD卡(8个引脚)除了外形尺寸外,功能上没有差别。

Rockchip RK3399 - MMC&SD&SDIO基础_第4张图片

下图是SD卡接口电路设计示意图。其中sdcmdsddat0~3是双向信号,需要通过电阻上拉到3.3V 。当HostSD卡都不驱动时,这些信号为弱上拉的高电平。除了SDIO的6根信号外,SD卡还需要3.3V的电源供电。

Rockchip RK3399 - MMC&SD&SDIO基础_第5张图片

3.2 信号时序

SDIO是同步总线,信号 (sdcmd, sddat) 的置位和采样都要和时钟 (sdclk) 同步,每个时钟周期中的每个信号可以传输1bit,需要满足一定的时序来保证信号的接收端能够正确的采样数据。SD2.0版本(SDSDHC,它们都遵循SD 2.0协议)规范规定SD卡需要满足如下时序;

Rockchip RK3399 - MMC&SD&SDIO基础_第6张图片

3.2.1 时钟要求

对于时钟 (sdclk)):

  • SD卡初始化过程中,时钟频率最低是100kHz (周期10000ns) ,最高不能超过400kHz (周期2500ns);。
  • 初始化完成后,时钟频率最低不限,最高不能超过25MHz (周期40ns))。
  • 时钟的上升和下降时间不能超过10ns

初始化操作是通过向 card 发送一个命令序列来实现的,后文会讲到。

3.2.2 HostSD卡时序要求

sdcmdsddat都是双向信号,在两个方向上都要满足上面图中的时序要求。

SD卡输入时HostSD卡,例如Host通过sdcmd发送命令给SD卡,这些信号会在sdclk的上升沿被输入端采样。

建立时间\(t_{ISU}\)和保持时间\(t_{IH}\)的最小要求5ns ,换句话说,上升沿之前5ns到之后5ns这段时间之间要让信号稳定下来,避免SD采到不稳定的数据。

考虑到时钟周期最小为40ns ,从下降沿到上升沿之间有20ns的时间,我们可以让Host在下降沿置位(更新)数据,很容易满足这个要求。

3.2.3 SD卡→Host时序要求

SD卡输出时 (SD卡→Host,例如 SD卡通过sdcmd发送响应给Host) ,这些信号会在sdclk的下降沿被更新。此时需要分别考虑初始化前后两种情况:

在初始化过程中,SD卡端的输出延迟 \(t_{ODLY,OD}\) (从时钟下降沿到信号稳定))最大为50ns 。考虑到在初始化过程中的时钟周期最小为2500ns ,从下降沿到上升沿之间有1250ns的时间,因此可以让Host在时钟上升沿采样数据,可以采样到稳定的数据。

在初始化后,SD卡端的输出延迟\(t_{ODLY,PP}\)最大为14ns 。考虑到此时的时钟周期最小为40ns ,从下降沿到上升沿只有20ns的时间,我们讨论Host的采样时机的3种方案:

  • Host在下降沿后的上升沿采样数据,则建立时间只有20-14=6ns 。考虑到从HostSD卡一个来回的走线延迟 (Host发出时钟下降沿→SD卡收到时钟下降沿并更新信号→更新的信号传回Host),6ns的时间可能不够宽裕;
  • Host在下降沿后的下一个下降沿采样数据,则建立时间有40-14=26ns ,非常宽裕。但有可能违反Host采样所需的保持时间 (取决于Host IO的保持时间要求) ,虽然一般来讲违反的概率不大;
  • 如果Host内部有一个比sdclk更快的时钟 (一般是整个Host控制器的驱动时钟) ,可以在上升沿到下降沿的中点采样数据 ,则建立时间有30-14=16ns,比较宽裕,同时保证保持时间不被违反;
Rockchip RK3399 - MMC&SD&SDIO基础_第7张图片

为了满足SDIO总线的时序,Host输出时应该在sdclk的下降沿将信号 (sdcmd, sddat) 置位。Host输入时应该在sdclk的下降沿采样 (SD卡置位的下降沿的下一个下降沿);或者在上升沿到下降沿的中点采样 (SD卡置位的下降沿的下一个上升沿到下一个下降沿)。。

四、NanoPC-T4 SDMMC配置

4.1硬件原理图

NanoPC-T4开发板带有一个microSD卡槽,microSD卡槽接线图如下所示:

Rockchip RK3399 - MMC&SD&SDIO基础_第8张图片

注意:这里sdcmdsddat0~3通过电阻下拉到GND,为啥不是上拉我也有点不是特别明白。

RK3399 SDMMC引脚接线如下图所示:

Rockchip RK3399 - MMC&SD&SDIO基础_第9张图片

补充:实际上并没有SDMMC卡或者是SDMMC接口;这里SDMMC就是SD卡。

需要注意的是:RK3399的电源域包含了sdmmc,如果要使用SDMM0必须要配置电源域,SDMMC0_VDD引脚连接的电源VCC_SDIO是由rk808下12号引脚VLDO4输出的。

RK3399引脚 方向 描述
GPIO4_B4/SDMMC0_CLKOUT O SDMMC card clock
GPIO4_B5/SDMMC0_CMD I/O SDMMC card command output and response input
GPIO4_B0/SDMMC0_D0 I/O SDMMC card data input and output line 0
GPIO4_B1/SDMMC0_D1 I/O SDMMC card data input and output line 1
GPIO4_B2/SDMMC0_D2 I/O SDMMC card data input and output line 2
GPIO4_B3/SDMMC0_D3 I/O SDMMC card data input and output line 3
GPIO0_B0/SDMMC0_WRPRT I SDMMC card protect
GPIO0_A7/SDMMC0_DET I SDMMC card detect signal, a 0 represents presence of card
SDMMC0_VDDPST O Pin out to external capacitor
4.2 设备树配置

设备节点配置可以参考官方文档:Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml

arch/arm64/boot/dts/rockchip/rk3399-evb.dtssdmmc设备节点追加属性;

&sdmmc {
	bus-width = <4>;
	cap-sd-highspeed;
	cap-mmc-highspeed;
	cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
	disable-wp;
	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc0_det_l>;
	sd-uhs-sdr104;
	vmmc-supply = <&vcc3v0_sd>;
	vqmmc-supply = <&vcc_sdio>;
	status = "okay";
};

其中:

  • bus-width:配置SD卡的线宽,SD卡最大支持4线模式,如果不配置就默认使用1线模式。另外,这个位只支持的数值为14,配置其他数值会认为是非法数值,强制按照1线模式进行使用;
  • cap-sd-highspeedcap-mmc-highspeed:此配置为标识此卡槽支持 SDHC )。 如果不配置,表示不支持SDHC卡;
  • cd-gpios:配置SD卡热插拔检测引脚,这里配置为GPIO0_A7SD卡插入为低电平,拔出为高电平,因此有效点评配置为GPIO_ACTIVE_LOW
  • pinctrl-namespinctrl-0:引脚配置节点,后面单独介绍;
  • sd-uhs-sdr104:配置SD3.0的速度模式,需要根据使用的芯片是否支持SD3.0协议来决定是否要配置 ;
    • sd-uhs-sdr12: 时钟频率不超过24M
    • sd-uhs-sdr25: 时钟频率不超过50M
    • sd-uhs-sdr50: 时钟频率不超过100M
    • sd-uhs-ddr50: 时钟频率不超过50M,并且采用双沿采样;
    • sd-uhs-sdr104: 时钟频率不超过208M
  • vmmc-supply:这里我们使用VCC3V0_SD作为SD卡设备的3V3电源控制引脚;
  • vqmmc-supplySD3.0 协议,需要配置vqmmc这一路的SDMMC控制器的IO电源:配置SDMMC0_VDD引脚电源供应;这里我们使用rk808电源管理芯片12号引脚VLDO4输出作为SDMMC0_VDD的电源控制引脚;

sdmmc设备节点定义在arch/arm64/boot/dts/rockchip/rk3399.dtsi

sdmmc: mmc@fe320000 {
		compatible = "rockchip,rk3399-dw-mshc",
					 "rockchip,rk3288-dw-mshc";
		reg = <0x0 0xfe320000 0x0 0x4000>;
		interrupts = ;
		max-frequency = <150000000>;  /*  SD卡的运行频率,虽然设置为 150M,但是还要根据SD卡的不同模式进行调整 */
		assigned-clocks = <&cru HCLK_SD>;
		assigned-clock-rates = <200000000>;
		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
				 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
		fifo-depth = <0x100>;
		power-domains = <&power RK3399_PD_SD>;
		resets = <&cru SRST_SDMMC>;
		reset-names = "reset";
		status = "disabled";
};

其对应驱动程序位于drivers/mmc/host/dw_mmc-rockchip.c文件。

4.2.1 电源配置

(1)VCC3V0_SD是由RT9193稳压管输出;由引脚SDMMC0_PWR_H(连接到RK3399GPIO0_A1)来控制使能;

Rockchip RK3399 - MMC&SD&SDIO基础_第10张图片

arch/arm64/boot/dts/rockchip/rk3399-evb.dts中配置;

vcc3v0_sd: vcc3v0-sd {
	compatible = "regulator-fixed";
	enable-active-high;
	gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;  /* GPIO0_A1使能,高电平有效 */
	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc0_pwr_h>;
	regulator-always-on;
	regulator-min-microvolt = <3000000>;
	regulator-max-microvolt = <3000000>;
	regulator-name = "vcc3v0_sd";
	vin-supply = <&vcc3v3_sys>;
};

并添加引脚配置节点sdmmc0_pwr_h

&pinctrl {
	......
	sdmmc {
		sdmmc0_det_l: sdmmc0-det-l {
			rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
		};

		sdmmc0_pwr_h: sdmmc0-pwr-h {
			rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;   /* 配置为GPIO口 */
		};
	};
};

(2) SDMMC0_VDD连接rk808电源管理芯片12号引脚VLDO4,在arch/arm64/boot/dts/rockchip/rk3399-evb.dts中配置;

&i2c0 {
	......

	rk808: pmic@1b {
		......
		
		regulators {
			......
			
			vcc_sdio: LDO_REG4 {
				regulator-always-on;
				regulator-boot-on;
				regulator-init-microvolt = <3000000>;
				regulator-min-microvolt = <1800000>;
				regulator-max-microvolt = <3300000>;
				regulator-name = "vcc_sdio";

				regulator-state-mem {
					regulator-on-in-suspend;
					regulator-suspend-microvolt = <3000000>;
				};
			};
		};
	};
};
4.2.2 引脚配置节点

引脚配置节点共有4个sdmmc_bus4sdmmc_clksdmmc_cmdsdmmc0_det_l,其中前三个已经在arch/arm64/boot/dts/rockchip/rk3399.dtsi中配置了;

pinctrl: pinctrl {
	......
	sdmmc {
			sdmmc_bus1: sdmmc-bus1 {
					rockchip,pins =
							<4 RK_PB0 1 &pcfg_pull_up>;
			};

			sdmmc_bus4: sdmmc-bus4 {        /* 数据引脚功能复用为sdmmc */
					rockchip,pins =
							<4 RK_PB0 1 &pcfg_pull_up>,
							<4 RK_PB1 1 &pcfg_pull_up>,
							<4 RK_PB2 1 &pcfg_pull_up>,
							<4 RK_PB3 1 &pcfg_pull_up>;
			};

			sdmmc_clk: sdmmc-clk {          /* 时钟引脚功能复用为sdmmc */
					rockchip,pins =
							<4 RK_PB4 1 &pcfg_pull_none>;
			};

			sdmmc_cmd: sdmmc-cmd {          /* 命令引脚功能复用为sdmmc */
					rockchip,pins =
							<4 RK_PB5 1 &pcfg_pull_up>;
			};

			sdmmc_cd: sdmmc-cd {
					rockchip,pins =
							<0 RK_PA7 1 &pcfg_pull_up>;
			};

			sdmmc_wp: sdmmc-wp {
					rockchip,pins =
							<0 RK_PB0 1 &pcfg_pull_up>;
			};
	};
};

我们需要在arch/arm64/boot/dts/rockchip/rk3399-evb.dts中配置sdmmc0_det_l

&pinctrl {
	......
	sdmmc {
		sdmmc0_det_l: sdmmc0-det-l {
			rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;    /* GPIO0_A7配置为GPIO口 */
		};

		sdmmc0_pwr_h: sdmmc0-pwr-h {
			rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;   /* GPIO0_A1配置为GPIO口 */
		};
	};
};
4.3 配置内核

执行make menuconfig配置内核:

Device Drivers   --->     
	<*> MMC/SD/SDIO card support  ---> 
	    <*> Synopsys DesignWare Memory Card Interface
	    <*>     Rockchip specific extensions for Synopsys DW Memory Card Interface

配置完内核之后记得保存配置:

Rockchip RK3399 - MMC&SD&SDIO基础_第11张图片

存档:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# mv rk3399_defconfig ./arch/arm64/configs/

重新配置内核(如果不想重新编译内核,可以存档一份到.config):

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make rk3399_defconfig
4.3.1 编译内核

linux内核根目录下执行如下命令进行编译内核:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# make -j8

u-boot-2023.04路径下的mkimage工具拷贝过来,然后在命令行使用mkimage工具编译即可:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp ../u-boot-2023.04/tools/mkimage ./
root@zhengyang:/work/sambashare/rk3399/linux-6.3# ./mkimage -f kernel.its kernel.itb
4.3.2 通过tftp烧录内核

给开发板上电,同时连接上网线,进入uboot命令行。我们将内核拷贝到tftp文件目录:

root@zhengyang:/work/sambashare/rk3399/linux-6.3# cp kernel.itb /work/tftpboot/

接着给开发板上电。通过uboot命令行将kernel.itb下到内存地址0x10000000处:

=> tftp 0x10000000 kernel.itb

通过mmc write命令将内核镜像烧录到eMMC0x8000个扇区处:

=> mmc erase 0x8000 0xA000
=> mmc write 0x10000000 0x8000 0xA000
4.4 测试

内核启动完成后,将microSD卡插入开发板后,内核输出日志信息如下:

[   88.515351] mmc_host mmc2: Bus speed (slot 0) = 148500000Hz (slot req 150000000Hz, actual 148500000HZ div = 0)
[   88.759085] dwmmc_rockchip fe320000.mmc: Successfully tuned phase to 202
[   88.759152] mmc2: new ultra high speed SDR104 SDHC card at address 0001
[   88.760468] mmcblk2: mmc2:0001 00000 14.9 GiB
[   88.763893]  mmcblk2: p1 p2
[   89.955393] EXT4-fs (mmcblk2p1): mounted filesystem ff313567-e9f1-5a5d-9895-3ba130b4a864 with ordered data mode. Quota mode: none.
[   89.966431] EXT4-fs (mmcblk2p2): recovery complete
[   89.966472] EXT4-fs (mmcblk2p2): mounted filesystem 269e9152-5cb6-035b-9c34-e1ed87cca310 with ordered data mode. Quota mode: none.

在输出信息中,我们了解到总线速度为148.5Mhz,并且识别到一个ultra high speed SDR104 SDHC card,地址为0001

设备名称为mmcblk2,因此我们可以在/dev下看到整个设备节点,/dev/mmcblk2表示的是microSD这个设备,其主设备号为179,次设备号为96;并且该设备被划分了2个分区,p1p2, 文件系统类型为ext4

root@rk3399:/# ll /dev/mmcblk2*
brw-rw---- 1 root disk 179, 96 Sep 23 15:25 /dev/mmcblk2
brw-rw---- 1 root disk 179, 97 Sep 23 15:25 /dev/mmcblk2p1
brw-rw---- 1 root disk 179, 98 Sep 23 15:25 /dev/mmcblk2p2
4.4.1 查看设备容量

这里我们可以通过df -hT查看磁盘空间信息;

root@rk3399:/# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4       15G  5.4G  8.2G  40% /
devtmpfs       devtmpfs  1.9G     0  1.9G   0% /dev
tmpfs          tmpfs     1.9G     0  1.9G   0% /dev/shm
tmpfs          tmpfs     386M  1.9M  384M   1% /run
tmpfs          tmpfs     5.0M  4.0K  5.0M   1% /run/lock
tmpfs          tmpfs     1.9G     0  1.9G   0% /sys/fs/cgroup
tmpfs          tmpfs     386M   12K  386M   1% /run/user/0
tmpfs          tmpfs     386M  4.0K  386M   1% /run/user/1000
/dev/mmcblk2p1 ext4      4.5G  4.4G   35M 100% /media/root/rootfs
/dev/mmcblk2p2 ext4       11G  263M  9.8G   3% /media/root/userdata

可以看到:

  • 设备节点/dev/mmcblk2p1被挂载到了/media/root/rootfs路径下,大小为4.5G;
  • 设备节点/dev/mmcblk2p2被挂载到了/media/root/userdata路径下,大小为4.5G;
4.4.2 读写测试

我们进入/media/root/rootfs目录,查看目录内容:

root@rk3399:/# cd /media/root/rootfs
root@rk3399:/media/root/rootfs# ll
total 92
drwxr-xr-x   23 root root 4096 Jan  1  1970 ./
drwxr-x---+   4 root root 4096 Sep 23 15:25 ../
drwxr-xr-x    2 root root 4096 May  8  2019 bin/
drwxr-xr-x    2 root root 4096 Oct 19  2015 boot/
drwxr-xr-x    4 root root 4096 Jun 25  2018 dev/
drwxr-xr-x  103 root root 4096 Aug 19  2022 etc/
drwxr-xr-x    4 root root 4096 Jul 17  2019 home/
drwxr-xr-x   18 root root 4096 Jul 17  2019 lib/
drwx--S---    2 root root 4096 Jan  1  1970 lost+found/
drwxr-xr-x    3 root root 4096 Dec  9  2020 man/
drwxr-xr-x    2 root root 4096 Oct 21  2015 media/
drwxr-xr-x    4 root root 4096 Jul 29  2016 mnt/
drwxr-xr-x   10 root root 4096 Oct 15  2020 opt/
drwxr-xr-x    2 root root 4096 Oct 19  2015 proc/
drwxr-xr-x    9 root root 4096 Aug 19  2022 root/
drwxr-xr-x    9 root root 4096 Mar 15  2017 run/
drwxr-xr-x    2 root root 4096 Mar 24  2020 sbin/
drwxr-xr-x    2 root root 4096 Oct 21  2015 srv/
drwxr-xr-x    2 root root 4096 Oct 16  2015 sys/
drwxr-xr-x    4 root root 4096 Jul 17  2019 system/
drwxrwxrwt    2 root root 4096 Aug 19  2022 tmp/
drwxr-xr-x   13 root root 4096 Dec  9  2020 usr/
drwxr-xr-x   12 root root 4096 Jul 17  2019 var/

这个目录下我存放的开发板SD启动时烧录的系统固件,这里我们不去修改它,我们使用/media/root/userdata做测试;

/media/root/userdata目录下创建一个test.txt文件;

root@rk3399:/media/root# cd /media/root/userdata
root@rk3399:/media/root/userdata# touch test.txt

写入内容:

root@rk3399:/media/root/userdata# echo 'hello rk3399' > test.txt

读取内容:

root@rk3399:/media/root/userdata# cat test.txt
hello rk3399

删除该文件:

root@rk3399:/media/root/userdata# rm -rf test.txt

参考文章

[1] SD卡、TF卡、MMC卡、emmc、sdio扫盲

[2] 芯片的SD/MMC控制器以及SD卡介绍

[3] MMC、SD、TF、SDIO、SDMMC简介

[4] MMC/SD/SDIO介绍

[5] STM32——SDIO的学习(驱动SD卡)

[6] 详谈SD卡/微型SD卡的引脚定义与连接

[7] MMC & SD 发展历史

[8] SD2.0协议详解:命令格式、初始化/读取/写入

[9] Notice of SD Simplified Specifications

你可能感兴趣的:(Rockchip RK3399 - MMC&SD&SDIO基础)