Sigmastar eMMC使用参考

Sigmastar eMMC使用参考

Sigmastar eMMC使用参考

REVISION HISTORY¶

Revision No.

Description

Date

1.0

Initial release

06/27/2023

2.0

Update emmc driver framework/device tree source/api information

12/13/2023

1. 概述¶

Kernel下MMC采用标准的Linux框架,能够使用标准接口驱动MMC Device(eMMC card,SD card或SDIO device)。

MMC子系统由card层,core层和host层构成。Card层将整个MMC Device注册成MMC Block Device,可支持上层的数据请求工作;Core层实现MMC/SD/SDIO协议中初始化流程和读写等工作。Host层可以调动硬件,把core层传下来的cmd或data request通过FCIE/SDIO Engine与eMMC/SD/SDIO card进行数据通信。

图1-1 eMMC Host层框架

eMMC host层的整体框架共有三层,分别是MDrv层,Hal层和Support层,以及接在Support层上的MMC设备,各个层次的作用如下:

Mdrv层:

eMMC的Mdrv层主要完成向core层注册Host的操作,也会额外提供一些封装接口来给用户层设置或获得Engine和卡的状态,比如:eMMC_bootbus,set_sdmmc_driving_control,并完成保证后续信号正常接收发送的MIE中断注册等。

Hal层:

eMMC的Hal层中通过读写寄存器来实现信号传输的文件是hal_sdmmc_v5.c,决定Host Engine接哪组pad pin,并对其进行上下拉操作的在hal_sdmmc_platform_common.c文件,中断和时间处理相关的接口在hal_sdmmc_intr.c文件。

Support层:

该层属于硬件支持层,驱动相关的最终实现都需要硬件的支持。

MMC device:

MMC设备,比如eMMC卡,直接接在驱动的硬件支持上,是驱动的最终操作对象。

2. 关键字说明¶

IP:连接eMMC设备的Host Engine

IP bank:驱动访问eMMC设备所使用的Host Engine的寄存器地址

HS: 可达25MB/S的高速接口时序模式,50MHz单数据速率总线,需要3.3V电压支持。

HS200:高达200MB/S的高速接口时序模式,200MHz单数据速率总线,需要1.8V电压支持。

HS400:高达400MB/s的高速DDR接口时序模式,200MHz双数据速率总线,需要1.8V电压支持。

3. 功能描述¶

封装

EMMC数量

总线带宽

时钟范围

uboot数据传输模式

Kernel数据传输模式

IP bank

产品

BGA

1

1,4,8

300k-200M

DMA

ADMA

0x1410

souffle

BGA

2(外挂)

1,4

300k-48M

DMA

ADMA

0x1413(non-pm)/0x42(pm)

iford

总线带宽设置:

eMMC支持配置1 -1bit mode/4 – 4bit mode / 8 – 8bit mode三种总线带宽,配置方式是通过修改设备树bus-width参数。

时钟设置:

eMMC驱动支持配置300KHz-200MHz范围内的时钟频率,可以通过修改设备树中的max-frequency参数来设置最大时钟大小,最终设置的clock频率是当前bus speed支持的最大频率。

图3-1 eMMC 总线速率模式

配置不同的总线带宽及时钟频率会影响数据传输速率,eMMC 5.0支持使用HS200和HS400速率模式,若要使用需要在设备树中使能mmc-hs200-1_8v/mmc-hs400-1_8v;

数据传输模式设置:

eMMC在kernel下支持配置DMA和ADMA两种数据传输模式,默认使用ADMA模式。

4. 硬件连接介绍¶

4.1. souffle¶

图4-1 EMMC 硬件原理图

4.2. iford¶

图4-2 eMMC 4bit boot mode硬件原理图

图4-3 eMMC 4bit mode硬件原理图

5. Uboot用法介绍¶

5.1. uboot config配置¶

1. make menuconfig

2. # SigmaStar drivers -->

3. # <*> SigmaStar mmc host

uboot下eMMC驱动所在目录为drivers/sstar/mmc_host/,编译需要开启SSTAR_MMC_HOST编译选项,打开方式如上。

5.2. Dts参数配置说明¶

可以通过配置dtsi中sstar_mmc1项设定Host层driver的基本参数。dtsi的参数展示如下:

sstar_mmc1: sstar_mmc1 {

compatible = "sstar-mmc";

bus-width = <4>;

max-frequency = <48000000>;

cap-mmc-highspeed = <1>;

ip-order = <0>;

pad-orders = <3>;

pwr-on-delay = <10>;

pwr-off-delay = <50>;

fack-cdz = <0>;

rev-cdz = <0>;

clk-driving = <1>; //0~7

cmd-driving = <1>; //0~7

data-driving = <1>; //0~7

en-clk-phase = <0>; //0/1

rx-clk-phase = <0>; //0-3

tx-clk-phase = <0>; //0-3

non-removable = <1>;

status = "okay";

};

释义如下:

参数

释义

备注

bus-width

配置卡槽的buswidth

4 – 4bit mode

max-frequency

配置对应卡槽支持的最大时钟频率

iford最大可支持48MHz

ip-order

配置对应卡槽的IP编号

pad-order

指定卡接哪组pad

取值范围:(0,1,2), iford emmc mode取值范围:(3,4,5)

pwr-on-delay

配置每个卡槽的power-on delay时间,以ms为单位

SDIO设备一般需要配置delay时间以便SDIO设备加载固件及状态ready,具体时间以SDIO设备厂家的建议为准

pwr-off-delay

配置每个卡槽的power-off delay时间,以ms为单位

fake-cdz

配置是否忽视Card detect,置1表示默认认为该槽有卡接入

针对固定在板上的设备,如部分SDIO设备,建议将卡槽对应项配置为1

rev-cdz

该参数可配置是否颠倒当前Board的Card detect条件

clk-driving

配置对应卡槽的clock pad pin的driving能力

档位:0-7,(iford: 0-3)

cmd-driving

配置对应卡槽的command pad pin的driving能力

档位:0-7,(iford: 0-3)

data-driving

配置对应卡槽的data[3:0] pad pin的driving能力

档位:0-7,(iford: 0-3)

en-clk_phase

配置对应卡槽是否使能 clock phase tuning

rx-clk_phase

配置对应卡槽的clock tx相位

档位:0-3,需en-clk_phase置1此参数才有效

tx-clk_phase

配置对应卡槽的clock rx相位

档位:0-3,需en-clk_phase置1此参数才有效

non-removable

配置是否不可移除设备

置1表示该设备不可移除

5.3. Uboot cmd参数说明¶

(1) emmc create

格式:

emmc create [name] [size]

说明:创建分区,name 表示分区名称,size 代表大小(Bytes)

示例:创建名为 p1 的分区,大小为 10M

emmc create p1 0xA00000

(2) emmc part

说明:显示分区,格式如下: #分区名# #分区号# #大小@偏移 (占用空间),大小和偏移的单位为 block # #占用空间,单位为 MBytes#

示例:

SigmaStar # emmc part

U-Boot kernela 1 20480 @ 615200 ( 10M)

U-Boot rootfsa 2 409600 @ 635680 (200M)

U-Boot usera 3 614400 @ 1045280 (300M)

U-Boot data 4 4298752 @ 1659680 ( 2G)

(3) emmc remove

格式:

emmc remove [name]

说明:删除指定名称的分区

示例:删除 p1 分区

emmc remove p1

(4) emmc rmgpt

格式:

emmc rmgpt

说明:删除 UDA 的所有分区,从分区表去除分区信息,不会擦除 UDA 分区

(5) emmc read.p

格式:

emmc read.p [addr][partition_name][size]

说明:把分区数据读到内存,addr 为内存地址,partition_nam 为分区名称,size 为拷贝的数据大小(Bytes)

示例:把 p1 起始处的 0x1000Bytes 数据拷贝到内存 0x21000000

emmc read.p 0x21000000 p1 0x1000

(6) emmc write.p

格式:

emmc write.p [addr][partition_name][size]

说明:把内存数据写到eMMC分区中,addr 为内存地址,partition_nam 为分区名称,size 为拷贝的数据大小(Bytes)

示例:把内存 0x21000000起始处的0x1000Bytes的数据拷贝到eMMC p1分区

emmc write.p 0x21000000 p1 0x1000

(7) emmc write.p.continue

格式:

emmc write.p.continue [addr] [partition_name] [offset] [size]

说明:把内存数据写到分区的偏移地址处,offset 为分区偏移地址(block 单位),size 为拷贝数据大小(Bytes)

示例:把分割的三个文件(分别为 10M,20M,10M)连续地拷贝到分区 p1

emmc write.p.continue 0x21000000 p1 0x0 0xA00000 //拷贝0xA00000 Bytes数据到p1的起始地址

emmc write.p.continue 0x21000000 p1 0x5000 0x1400000 //0x5000=0xA00000/512

emmc write.p.continue 0x21000000 p1 0xF000 0xA00000 //0xF000=0x5000+0x1400000/512

(8) emmc read.p.continue

格式:

emmc read.p.continue [addr] [partition_name] [offset] [size]

说明:把分区偏移 offset 处的数据拷贝到内存

emmc read.p.continue 0x21000000 p1 0x0 0xA00000

(9) emmc erase.p

格式:

emmc erase.p [name]

说明:格式化指定分区

示例:格式化 p1 分区的数据,格式化后分区数据都为 0

emmc erase.p p1

(10) emmc erase

格式:

emmc erase

说明:擦除当前整个分区,例如当前在 UDA 分区,则擦除整个 UDA 分区,慎用!

5.4. Uboot cmd使用实例¶

(1) 创建一个新分区p1,大小为10M

(2) 把 p1 起始处的 0x1000Bytes 数据拷贝到内存 0x21000000

(3) 把分区p1偏移 0x0 处的数据拷贝0xA00000字节到内存0x21000000

(4) 擦除分区p1的数据

(5) 删除分区p1

6. Kernel用法介绍¶

6.1. Kernel Config配置¶

1. 关联到的驱动模块

Card层(mmc_block.ko)与Core层(mmc_host.ko)使用linux标准code,Host层(kdrv_sdmmc.ko)由Sigmastar维护,在menuconfig可将它们选择编译进kernel或编译为ko。

2. enable 对应的驱动模块

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. # <*> SStar SD/MMC Card Interface Support (kdrv_sdmmc.ko)

7. # [ ] Support SD30

8. # [ ] Support EMMC50

9. # [*] Support SDMMC Command

10.# [*] Support SDMMC UT verify

6.2. Dts配置参数说明¶

可以通过配置dtsi中sstar_sdmmc0项设定Host层driver的基本参数。dtsi的参数展示如下:

sstar_sdmmc0: sstar_sdmmc0 {

compatible = "sstar,sdmmc";

bus-width = <4>;

max-frequency = <48000000>;

non-removable;

broken-cd;

cap-mmc-highspeed;

mmc-hs200-1_8v;

mmc-hs400-1_8v;

no-sdio;

no-sd;

//no-mmc;

reg = <0x1F008400 0x200>;

pll-reg = <0x1F283200 0x200>;

cifd-reg = <0x1F008600 0x200>;

pwr-save-reg = <0x1F008800 0x200>;

ip-order = /bits/ 8 <1>;

pad-order = /bits/ 8 <0>;

trans-mode = /bits/ 8 <1>;

fake-cdz = /bits/ 8 <0>;

rev-cdz = /bits/ 8 <0>;

pwr-on-delay = <1>;

pwr-off-delay = <30>;

support-cmd23 = /bits/ 8 <1>;

clk-driving = <2>;

cmd-driving = <2>;

data-driving = <2>;

en-clk-phase = /bits/ 8 <0>; //0/1

rx-clk-phase = <0>; //0-3

tx-clk-phase = <0>; //0-3

en-eight-phase = /bits/ 8 <0>; //0/1

rx-eight-phase = /bits/ 8 <0>; //0/1

tx-eight-phase = /bits/ 8 <0>; //0/1

interrupts = ,

;

interrupt-names = "mie0_irq", "mie1_irq";

clocks = <&CLK_sd>;

clock-names = "clk_sdmmc1";

status = "ok";

};

如上图所示,eMMC设备树配置节点释义分别为:

参数

释义

备注

bus-width

配置对应卡槽的buswidth

4 - 4bit mode

max-frequency

配置对应卡槽支持的最大时钟频率

iford最大时钟频率支持到48MHz

non-removable

配置是否不可移除设备,置1表示默认该设备不可移除

eMMC/SDIO设备一般设置为不可移除属性

broken-cd

配置是否使用cdz中断

eMMC设备不使用

cap-mmc-highspeed

配置设备是否支持highspeed总线速率模式

默认开启支持highspeed mode

mmc-hs200-1_8v

配置是否启用hs200总线速率模式

iford未使用

mmc-hs400-1_8v

配置是否启用hs400总线速率模式

iford未使用

no-sdio

配置设备不支持SDIO协议

eMMC设备不支持SDIO协议

no-sd

配置设备不支持SD协议

eMMC设备不支持SD协议

reg

配置eMMC Host Engine Bank地址

根据'功能描述'使用

pll-reg

配置eMMC Host Engine PLL Bank地址

iford未使用,保持默认值即可

cifd-reg

配置eMMC Host Engine CIFD Bank地址

eMMC Host支持adma/dma/cifd数据传输模式,推荐使用adma

pwr-save-reg

配置eMMC Host Engine PSM Bank地址

eMMC Host支持IP层面的掉电保护功能

ip-order

配置对应卡槽的IP编号

iford当前支持0, 1两个槽位

pad-order

配置对应卡槽的padmux mode编号

根据实际硬件配置对应padmux mode

trans-mode

配置对应的卡槽的数据传输模式

iford未使用,默认使用adma

fake-cdz

配置对应卡槽是否忽视Card Detect

eMMC未使用,保持默认值即可

rev-cdz

配置CDZ检测方向

eMMC未使用,保持默认值即可

pwr-on-delay

配置对应卡槽的上电延迟时间

eMMC未使用,保持默认值即可

pwr-off-delay

配置对应卡槽的下电延迟时间

eMMC未使用,保持默认值即可

support-cmd23

配置是否支持预设传输Block数功能

默认开启支持cmd23

clk-driving

配置对应卡槽的clock line的driving

档位:0-7,(iford: 0-3)

cmd-driving

配置对应卡槽的cmd line的driving

档位:0-7,(iford: 0-3)

data-driving

配置对应卡槽的data line的driving

档位:0-7,(iford: 0-3)

en-clk-phase

配置对应卡槽是否使能clock phase tuning

0 - 禁用 / 1 - 使能

rx-clk-phase

配置对应卡槽的clock rx phase

档位:0-3,en-clk-phase置1此参数有效

tx-clk-phase

配置对应卡槽的clock tx phase

档位:0-3,en-clk-phase置1此参数有效

en-eight-phase

配置对应卡槽是否使能clock 8 phase tuning

0 - 禁用 / 1 - 使能, iford暂未启用

rx-eight-phase

配置对应卡槽的clock rx phase

档位:0-5,en-eight-phase置1此参数有效

tx-eight-phase

配置对应卡槽的clock tx phase

档位:0-5,en-eight-phase置1此参数有效

interrupts

配置中断信息

保持默认值即可

interrupt-names

配置中断名称

与interrupts配对使用

clocks

配置eMMC Host Engine时钟源

保持默认值即可

clock-names

配置时钟源名称

与clocks配合使用

另外,为了方便padmux同一管理,eMMC driver还支持使用padmux.dtsi配置要使用的pad组,当padmux.dtsi中有关于eMMC或SDMMC的PUSE时,driver将优先使用该种方式配置padmux。该方式能直观得与其他模块是否存在pad冲突。实例如下:

1. padmux {

2. compatible = "sstar-padmux";

3. schematic =

4. //EMMC0

5. ,

6. ,

7. ,

8. ,

9. ,

10. ,

11. ,

12. ,

13. };

依据客户实际情况,替换第一栏PAD名以及该pad对应的第二组pad mode即可。

6.3. Sample code¶

无。

6.4. 模块使用介绍¶

linux系统启动后,正常加载eMMC驱动,并识别eMMC Card后,会创建对应的块设备节点/dev/mmcblk*。使用fdisk、mkfs、mount、dd工具可对MMC设备申请分区、格式化分区、挂载分区并对挂载分区进行读写等操作。

另外驱动提供sysfs进行debug,进入/sys/devices/soc0/soc/{reg}.sstar_sdmmc0目录下可进行操作:

1. cd /sys/devices/soc0/soc/{reg}.sstar_sdmmc0

2.

3. # 查看eMMC Host时钟频率

4. cat debug_get_sdmmc_clock

5.

6. # 查看eMMC Host与Device上一次通信状态

7. cat debug_get_sdmmc_status

8.

9. # 设置[slotNo] emmc的bootbus值

10. echo [slotNo] [bootbus] > eMMC_bootbus

11. # 查看所有slot的emmc的bootbus值。

12. cat eMMC_bootbus

13.

14. # 指定起始位置和Block数对eMMC Device进行擦除

15. echo [startblkAddr] [blkcnt] > eMMC_erase

16.

17. # 设置[slotNo] eMMC Device支持HW reset

18. echo [slotNo] > eMMC_hwreset

19. # 查看eMMC Device是否开启HW reset支持

20. cat eMMC_hwreset

21.

22. # 设置 eMMC Device的boot启动分区

23. echo [partconf] > eMMC_partconf

24. #[partconf] -0: don't support boot

25. # -1: boot0 partition

26. # -2: boot1 partition

27. # -7: UDA

28. # 查看eMMC Device的boot启动分区

29. cat eMMC_partconf

30.

31. # 设置eMMC 写保护范围(按group设置)

32. echo [otption] [address] > eMMC_write_protect

33. #[option] -0: Set the eMMC address of the group to be 'write protect'

34. # -1: Clear the eMMC address of the group remove 'write protect'

35. # -2: Ask the eMMC address of the group whether it's in 'write protect'?

36. # -3: ASK the eMMC address of the group about the 'write protect' type

37. #[address] 单位:block

38. #[size] 单位: block

39.

40. # 设置eMMC总线宽度

41. echo [buswidth] > sdmmc_bus_width_set

42. #[buswidth] -2: 4bit buswidth

43. # -3: 8bit buswidth(iford not support)

44. # -others: invalid

45.

46. # 设置eMMC clock和Timing mode

47. echo [clk_freq] > sdmmc_clk_timing_set

48. #[clk_freq] 单位:Hz

49. # -[0,12MHz): set clock only

50. # -[12MHz, 26MHz]: set timing to MMC_TIMING_LEGACY and set clock

51. # -(26MHz, 50MHz): set timing to MMC_TIMING_MMC_HS and set clock

52.

53. # 设置eMMC Host使用中断或polling模式

54. echo [intr_en] > sdmmc_inter_polling_set

55. #[intr_en] -0: polling mode

56. # -1: interrupt mode

57. # Tips: 如果eMMC Host已经工作在polling模式,则无法切换到interrupt模式

58.

59. # 对[slotNo] eMMC Device进行硬复位

60. echo [slotNo] > sdmmc_reset

61. # iford not support

62.

63. # 设置eMMC pin的驱动能力

64. echo [slotIndex] [signalLine] [drvLevel] > set_sdmmc_driving_control

65. echo [slotIndex] [drvLevel] > set_sdmmc_driving_control

66. echo [signalLine] [drvLevel] > set_sdmmc_driving_control

67. echo [drvLevel] > set_sdmmc_driving_control

68. #[slotIndex]: 0-1

69. #[signalLine]: "clk"/"cmd"/"data"/"all"

70. #[drvLevel]: 0-7 (iford support 0-3)

7. API参考¶

该功能模块需打开CONFIG_SUPPORT_SDMMC_COMMAND配置项,提供以下接口:

API名称

功能

SDMMC_Init

初始化eMMC驱动并识别设备

SDMMC_WriteData

写数据到eMMC设备

SDMMC_ReadData

从eMMC设备读取数据

eMMC_EraseBlock

擦除eMMC设备中的指定数据

eMMC_GetExtCSD

获取eMMC设备的ExtCSD寄存器内容

7.1. SDMMC_Init¶

目的

初始化eMMC驱动并识别设备

语法

U16_T SDMMC_Init(struct sstar_sdmmc_slot *p_sdmmc_slot)

参数

参数名称

描述

p_sdmmc_slot

eMMC对应的控制块,驱动注册时生成并添加到mmc_host私有变量中

返回值

返回值

描述

0

成功

other

失败

7.2. SDMMC_WriteData¶

目的

写数据到eMMC设备

语法

U16_T SDMMC_WriteData(struct sstar_sdmmc_slot *p_sdmmc_slot, U32_T u32CardBlkAddr, U16_T u16BlkCnt, U8_T *pu8DataBuf)

参数

参数名称

描述

p_sdmmc_slot

eMMC对应的控制块,驱动注册时生成并添加到mmc_host私有变量中

u32CardBlkAddr

写入eMMC的Block地址

u16BlkCnt

写入的Block数

pu8DataBuf

待写入的数据缓存地址

返回值

返回值

描述

0

成功

other

失败

7.3. SDMMC_ReadData¶

目的

读EMMC中的数据。

语法

U16_T SDMMC_ReadData(struct sstar_sdmmc_slot *p_sdmmc_slot, U32_T u32CardBlkAddr, U16_T u16BlkCnt, U8_T *pu8DataBuf)

参数

参数名称

描述

p_sdmmc_slot

eMMC对应的控制块,驱动注册时生成并添加到mmc_host私有变量中

u32CardBlkAddr

读取eMMC的Block地址

u16BlkCnt

读取的Block数

pu8DataBuf

存放数据的缓存地址

返回值

返回值

描述

0

成功

other

失败

7.4. eMMC_EraseBlock¶

目的

擦除eMMC中指定地址的数据。

语法

U16_T eMMC_EraseBlock(struct sstar_sdmmc_slot *p_sdmmc_slot, U32_T u32BlkAddrStart, U32_T u32BlkAddrEnd)

参数

参数名称

描述

p_sdmmc_slot

eMMC对应的控制块,驱动注册时生成并添加到mmc_host私有变量中

u32BlkAddrStart

擦除的起始地址

u32BlkAddrEnd

擦除的结束地址

返回值

返回值

描述

0

成功

other

失败

7.5. eMMC_GetExtCSD¶

目的

获取eMMC设备的ExtCSD寄存器内容。

语法

U16_T eMMC_GetExtCSD(struct sstar_sdmmc_slot *p_sdmmc_slot, U8_T *pu8DataBuf)

参数

参数名称

描述

p_sdmmc_slot

eMMC对应的控制块,驱动注册时生成并添加到mmc_host私有变量中

pu8DataBuf

保存ExtCSD内容的缓存地址

返回值

返回值

描述

0

成功

other

失败

8. Debug & FAQ¶

根据eMMC卡实际可能遇到的问题,分为以下几个类型:

1. 识别卡失败

若卡识别失败,需要确定是响应获取失败还是传输信号不好有CRC问题,区分问题可以通过抓波形确定,具体区别以及debug方法如下:

响应获取失败

现象:波形上只有host发出去的command,没有device返回的response

debug方法:首先确定电压和clock是否正常,其次看波形上是否有command发出去,若前面两个都没有问题,再确定卡是否有回复响应,若没有响应检查device状态。

信号不好有CRC问题

现象:从波形看command和response都正常,则考虑CRC问题

debug方法:若有CRC问题,先需要排除硬件问题,比如:device接触是否良好,是否有外接干扰等。然后再尝试更改dts里的driving档位,若还有问题则需要考虑调整clock phase。

2. 读写失败

若是在正常读写过程中遇到问题,需要确定是读写超时问题,还是信号不好有CRC问题,区分问题可以通过log确定,超时问题有timeout的字眼,debug方法如下:

读写超时

现象:报错log里有timeout的字眼

debug方法:首先需要确定当前clock频率以及bus width是否是期望配置的值,其次可以将驱动里的超时时间再加大试试,若还有超时问题,则需要抓波形详细分析。

信号不好有CRC问题

现象:排除以上问题,则可能是CRC问题

debug方法:debug方法见前文,另外读写过程中的CRC问题,若对速率要求不是很高,可以考虑降频或者降bus width。

相关尊享内容