Fuchsia MMC框架简析

老子叫甜甜 提交于 2020-04-19 17:29:51

 

本文简单分析下Fuchsia的MMC框架,主要是基于mmc协议的初始化流程进行说明。至于mmc框架中的SD以及SDIO协议流程本文不涉及。另外,Fuchsia块设备层以及文件系统层的分析,本文也不涉及。

下表为目前rcar-M3单板系统的“设备树”(为描述方便,省略了部分设备树节点)。

root$ dm dump

[root]

   <root> pid=2524

      [null] pid=2524 /boot/driver/builtin.so

      [zero] pid=2524 /boot/driver/builtin.so

   [misc]

      <misc> pid=2607

         [console] pid=2607 /boot/driver/console.so

         ……

   [sys]

      <sys> pid=2439 /boot/driver/platform-bus.so

         [platform] pid=2439 /boot/driver/platform-bus.so

            [rcar-m3] pid=2439 /boot/driver/rcar-m3.so

            [16:01:1] pid=2439 /boot/driver/platform-bus.so

               <16:01:1> pid=2958 /boot/driver/platform-bus.proxy.so

                  [sh_mobile_sdhi] pid=2958 /boot/driver/sh-mobile-sdhi.so

                     [sdmmc] pid=2958 /boot/driver/sdmmc.so

                        [sdmmc-mmc] pid=2958 /boot/driver/sdmmc.so

                           [block] pid=2958 /boot/driver/block.core.so

                              [part-000] pid=2958 /boot/driver/mbr.so

                                 [block] pid=2958 /boot/driver/block.core.so

                                    [fvm] pid=2958 /boot/driver/fvm.so

                                       [blobfs-p-1] pid=2958 /boot/driver/fvm.so

                                          [block] pid=2958 /boot/driver/block.core.so

                                       [minfs-p-2] pid=2958 /boot/driver/fvm.so

                                          [block] pid=2958 /boot/driver/block.core.so

[part-001]

……

            [16:01:2] pid=2439 /boot/driver/platform-bus.so

               <16:01:2> pid=3131 /boot/driver/platform-bus.proxy.so

                  [ravb-ethernet] pid=3131 /boot/driver/ethernetAVB-IF.so

                     [ethernet] pid=3131 /boot/driver/ethernet.so

         [cpu-trace] pid=2439 /boot/driver/platform-bus.so

   [test]

      <test> pid=2471

         ……

我们可以看到,这实际上是一颗“倒置”的“树”,设备硬件相关的信息在上面的“树干”,而层层抽象的驱动则是挂在设备下的“树枝”和“树叶”。以mmc块设备为例,其board级驱动([rcar-m3] pid=2439 /boot/driver/rcar-m3.so)设备挂在系统的永久设备sys的platform总线设备下面。而board设备下面则是挂载的emmc驱动(sh-mobile-sdhi.so)设备。Emmc驱动设备下面层层的挂载了系统的软件抽象层设备,包括mmc抽象层设备、block块抽象层设备、分区设备以及文件系统抽象层设备。更详细的驱动框架DDK相关细节,请参考我的“DDK驱动框架分析”文档。

从上面的这颗“倒置树”可以看出mmc框架抽象层是挂载在emmc驱动([sh_mobile_sdhi] )下面的,也就是emmc驱动初始化完成并发布设备后,才能触发mmc框架层驱动的初始化。如下图所示,mmc框架层的初始化入口为SdmmcRootDevice::Bind。其在Init函数中会新启动一个线程(SdmmcRootDevice::WorkerThread)来执行mmc协议层的probe流程。

在SdmmcRootDevice::WorkerThread流程中,首先调用emmc host驱动的reset接口,执行卡的reset初始化操作。接下来不管卡处于什么状态,都先发送CMD0命令,让其进入idle态,以保证后面的初始化流程正常进行下去。接下来会依次进行SDIO、SD以及MMC子协议的probe操作,前面的probe成功,后面的就不会再执行。这里我们选择MMC子协议的probe流程进行展开分析。

  1. 发送CMD1命令获取卡OCR寄存器值
  2. 设置OCR寄存器的bit30位,使能sector模式(不使能位byte模式)
  3. 发送CMD2命令获取CID寄存器值
  4. 解析CID值,获取mmc序列号、版本信息等
  5. 发送CMD3命令,为卡分配mmc总线上的相对地址,写入RCA寄存器。初始化时,RCA寄存器值为0,这里如果mmc总线上只有一个设备,该地址将会是0001。
  6. 发送CMD9命令,获取CSD寄存器值
  7. 解析CSD寄存器值,获取卡容量、扇区大小等信息
  8. 发送CMD7命令选中该卡(arg参数带上卡地址0001)
  9. 发送CMD8命令读取ext CSD寄存器值;该寄存器为512字节大小,储存了丰富的信息,包括支持的总线位宽、高速模式、CMDQ、超时值等等;详情请参考emmc协议手册
  10. 解析ext CSD寄存器值,获取卡的相关特性支持情况
  11. 如果支持高速模式(HS、HSDDR、HS200),进行下面的初始化操作
  12. 高速模式首先需要将总线接口电平设置为1.8V(低速模式为3.3V)
  13. 然后通过CMD6和CMD13命令选择并设置emmc支持的最大总线位宽(HS200支持4-bit和8-bit两种总线位宽,但HS400只支持8-bit位宽)
  14. 更进一步,如果支持高速模式中的HS200模式,进行下面的初始化操作
  15. 通过CMD6和CMD13命令设置HS200模式
  16. 切换host时钟频率为200MHz
  17. 执行mmc总线tuning过程(发送CMD21命令,根据host寄存器值确定需要进行的tuning次数,rcar-M3需要进行16次,然后根据结果则有选择最佳采样点)
  18. 再进一步,如果支持HS400模式,则进行下面的初始化操作
  19. 通过CMD6和CMD13命令,将模式切换回普通高速模式
  20. 时钟频率设置为52MHz(普通高速模式)
  21. 通过CMD6和CMD13命令设置总线位宽为8bit DDR(Dual Data Rate)
  22. 通过CMD6和CMD13命令切换模式为HS400
  23. 最后一步是将时钟频率设置为200MHz,完成HS400模式的切换

请结合下图及具体代码,来理解fuchsia的MMC协议框架初始化流程。

 

发布了80 篇原创文章 · 获赞 31 · 访问量 10万+
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!