EMMC使用参考
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 10/30/2022 |
1. 概述¶
Kernel下MMC采用标准的LINUX框架,能够使用标准接口驱动mmc device(emmc card,sd card或sdio device)。
Mmc子系统由card层,core层和host层构成。Card层将整个mmc device注册成mmc block device,可支持上层的数据请求工作;Core层实现mmc协议中初始化流程和读写等工作。Host层可以调动硬件,把core层传下来的cmd或data request通过fcie engine与emmc card device进行数据通信。
2. LINUX配置使用MMC device¶
2.1. 编译MMC相关driver¶
Card层(mmc_block.ko)与Core层(mmc_host.ko)使用linux标准code,Host层(kdrv_emmc.ko)由我们自己维护,在menuconfig可将它们选择编译进kernel或编译为模块。
1. make menuconfig 2. # Device Drivers --> 3. # <*> MMC/SD/SDIO card support --> (mmc_core.ko) 4. # <*> MMC block device driver (mmc_block.ko) 5. # [*] SStar SoC platform drivers --> 6. # <*> EMMC driver (kdrv_emmc.ko) 7. # [*] UNIFY EMMC DRIVER
2.2. dts配置¶
可以通过配置dts中emmc项设定host层driver的基本参数。适配ssc028a的dts参数展示如下:
1. emmc { 2. compatible = "sstar_mci"; 3. clocks = <&CLK_sd>,<&CLK_fcie>,<&CLK_sdio>; 4. clock-names = “clk_fcie0”, “clk_fcie1”, “clk_fcie2”; 5. interrupts = <GIC_SPI INT_IRQ_SD IRQ_TYPE_LEVEL_HIGH>, 6. < GIC_SPI INT_IRQ_SDIO IRQ_TYPE_LEVEL_HIGH>; 7. 8. slot-num = <1>; 9. adma-mode = <1>,<1>,<1>; 10. ip-select = <1>,<1>,<2>; 11. pad-select = <0>,<0>,<0>; 12. support-emmc50 = <0>,<0>,<0>; 13. bus-width = <8>,<4>,<4>; 14. max-clks = <48000000>,<48000000>,<48000000>; 15. status = "ok"; 16. };
如上图展示,emmc节点下几乎所有的属性都有三组value,分别代表最多三个emmc slot口的属性参数。释义分别为:
参数 | 释义 | 备注 |
---|---|---|
clocks | 配置对应卡槽的clock source | 根据实际使用情况配置该项。 |
clock-names | 配置clock source名称 | 与clocks配合使用 |
interrupts | 配置中断信息 | code中可以根据ip自动匹配中断号 |
slotnum | 当前board正在使用的SD/SDIO/FCIE IP个数,driver根据该值读取相应列的参数。 | 根据实际使用情况配置该项。 |
adma-mode | 配置对应的卡槽的data传输模式 | 0 – dma / 1 – adma |
ip-select | 配置对应卡槽的IP编号 | |
pad-select | 配置对应卡槽的padmux mode编号 | |
support-emmc50 | 配置卡槽是否支持emm5.0 | |
bus-width | 配置对应卡槽的buswidth | 4 – 4bit mode / 8 – 8bit mode |
max-clks | 配置对应卡槽支持的最大时钟频率 |
2.3. Linux下使用mmc device¶
开发板启动进入到kernel命令行后,会生成emmc card的设备分区节点/dev/mmcblk*。使用fdisk、mkfs、mount、dd等工具操作该节点即可实现访问mmc block device,这与其他linux是没有差异的。
另外我们也提供sysfs进行debug,进入kernel命令行后,在/sys/device/platform/soc/soc:emmc目录下可以查看到所有支持的sysfs。
1. cd /sys/device/platform/soc/soc:emmc 2. 3. # 关闭/【开启或重置】读写监控 4. echo [0/1] > eMMC_monitor_count_enable 5. # 查看从【开启或重置】起的读写监控信息。 6. cat eMMC_monitor_count_enable 7. 8. # 写操作log打印开关。 9. echo [0/1] > eMMC_write_log_enable 10. # 查看写打印开关状态。 11. cat eMMC_write_log_enable 12. 13. # 读操作log打印开关。 14. echo [0/1] > eMMC_read_log_enable 15. # 查看读打印开关状态。 16. cat eMMC_read_log_enable 17. 18. # 设置[slotNo] emmc的bootbus值 19. echo [slotNo] [bootbus] > eMMC_bootbus 20. # 查看所有slot的emmc的bootbus值。 21. cat eMMC_bootbus 22. 23. #设置[slotNo] emmc的partconf值 24. echo [slotNo] [bootbus] > eMMC_partconf 25. # 查看所有slot的emmc的partconf值。 26. cat eMMC_ partconf 27. 28. # 查看所有slot的emmc的工作clock频率。 29. cat eMMC_get_clock 30. 31. # 启动对[slotNo] emmc的ipverify测试,包括1/4/8 bit、cifd/dma/bdma、signle/muilt、imi/miu rw、error status int、power save mode测试验证。 32. echo [slotNo] > eMMC_run_ipverifys
2.4. EMMC UDA分区划分¶
UDA分区设计如下:
partition table:
第一个block存储分区标识信息,标识创建的分区类型为EMMC类型,第1~64共63个block,每个block存储创建的对应分区的信息,包括分区名称,起始地址以及大小等。
reserved:
reserve区域是预留出来做其他用途的。
env:
env区域是在reserve区域中划分出来保存启动Linux需要的环境变量的,其大小可以根据实际需求划分。
partition:
partition是保存partition table对应的分区数据的地方,默认从第615424个block开始,但是也可以通过修改uboot的CONFIG_SSTAR_EMMC_PARTTION_START值来修改partition start offset。为了避免破坏DDR OTT数据,这个值不能小于0x1E02,又因为要和erase group即512K对齐,所以CONFIG_SSTAR_EMMC_PARTTION_START的值不能小于0x2000。partition start offset加第一个分区大小就是第二个分区的起始地址,以此类推,共允许存储63个分区的数据。
另外uboot还支持将emmc剩余空间全部重新分配给最后一个分区即customer分区,但需要手动将SSTAR_EMMC_PDB_RESIZE_CUSTOMER_PARTITION打开,否则默认不扩容。