Linux内核eMMC

eMMC(Embedded Multi Media Card)MMC协会订立的内嵌式存储器标准规格。

eMMC在封装中集成了一个控制器,并提供标准接口管理闪存。

从开发者角度看,只要遵循eMMC协议,既可以对eMMC芯片进行读写操作。

下面介绍RK3568 eMMC控制器驱动和调试方法。

一、eMMC驱动

1、eMMC控制器

RK3568 eMMC主机控制器框图如下:

image.png

RK3568 eMMC主机控制器特性如下:

1)、支持eMMC 5.1协议

2)、支持自动tuning

3)、支持4/8-bit接口

4)、支持 legacy、High Speed SDR、High Speed DDR、HS200/HS400速度模式

5)、AHB从接口:支持32bit数据和地址宽度

6)、AXI主接口:支持32bit地址宽度和64bit数据宽度

7)、时钟调整:支持transmit clock、sample clok和data strobe相位自动调整

2、eMMC原理图

预调驱动,先看原理图。

RK3568eMMC之间的连接方式见下图:

image.png

注:

1)eMMC D0~D8/CMD电压需一致,为3.3V1.8V

2)Data Strobe时钟信号由eMMC发给RK3568,频率与CLK 信号相同。用于RK3568侧数据接收的同步。Data Strobe信号只能在HS400模式下配置启用,启用后可以提高数据传输的稳定性,省去总线 tuning过程。

3、eMMC配置

RK3568 eMMC配置文件:

1)arch/arm64/boot/dts/rockchip/rk3568.dtsi

    sdhci: sdhci@fe310000 {
            compatible = "rockchip,dwcmshc-sdhci", "snps,dwcmshc-sdhci";
            reg = <0x0 0xfe310000 0x0 0x10000>;
            interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
            assigned-clocks = <&cru BCLK_EMMC>, <&cru TCLK_EMMC>,
                              <&cru CCLK_EMMC>;
            assigned-clock-rates = <200000000>, <24000000>, <200000000>;
            clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
                     <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
                     <&cru TCLK_EMMC>;
            clock-names = "core", "bus", "axi", "block", "timer";
            status = "disabled";
    };

2)arch/arm64/boot/dts/rockchip/rk3568-firefly-core.dtsi

    &sdhci {
        bus-width = <8>;
        supports-emmc;
        non-removable;
        max-frequency = <200000000>;
        status = "okay";
    };

其中:

max-frequencyeMMC在该模式下支持的最大运行频率,单位HZ

                **注:根据不同的模式进行调整该值,注意和数据传输速率(`Max Data Transfer rate,MB/s`)区别。**

supports-emmc:表示为emmc功能,必须添加。否则无法初始化eMMC卡。

bus-widtheMMC使用8线模式。

non-removable:表示该卡槽为不可移动设备,必须添加。

4、eMMC驱动

RK3568 eMMC控制器使用Synopsys IP

RK3568驱动文件:drivers/mmc/host/sdhci-of-dwcmshc.c,主要关注:

static const struct sdhci_ops sdhci_dwcmshc_ops = {
        .set_clock              = sdhci_set_clock,
        .set_bus_width          = sdhci_set_bus_width,
        .set_uhs_signaling      = dwcmshc_set_uhs_signaling,
        .get_max_clock          = sdhci_pltfm_clk_get_max_clock,
        .reset                  = sdhci_reset,
        .adma_write_desc        = dwcmshc_adma_write_desc,
};

static const struct sdhci_ops sdhci_dwcmshc_rk_ops = {
        .set_clock              = dwcmshc_rk_set_clock,
        .set_bus_width          = sdhci_set_bus_width,
        .set_uhs_signaling      = dwcmshc_set_uhs_signaling,
        .get_max_clock          = sdhci_pltfm_clk_get_max_clock,
        .reset                  = sdhci_reset,
        .adma_write_desc        = dwcmshc_adma_write_desc,
};

二、eMMC调试

1、U-Boot阶段

1.1、查看U-Boot支持的mmc命令

=> mmc
mmc - MMC sub system

Usage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
...

1.2、显示mmc设备信息

=> mmc info
Device: sdhci@fe310000
Manufacturer ID: 9b
OEM: 100
Name: Y2P03
Timing Interface: HS200     ## EMMC支持的速度模式 
Tran Speed: 200000000       ## EMMC速度
Rd Block Len: 512           ## block大小512字节
MMC version 5.1
High Capacity: Yes
Capacity: 29.1 GiB          ## EMMC容量
Bus Width: 8-bit            ## EMMC总线宽度8bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 29.1 GiB
Boot Capacity: 4 MiB ENH
RPMB Capacity: 16 MiB ENH

1.3、查看mmc设备列表

=> mmc list
dwmmc@fe2b0000: 1           ## SDCard
dwmmc@fe2c0000: 2           ## SDIO
sdhci@fe310000: 0 (eMMC)    ## eMMC设备,当前设备

1.4、查看mmc设备分区

当前是eMMC设备,查看的eMMC分区如下:

=> mmc part

Partition Map for MMC device 0  --   Partition Type: EFI

Part    Start LBA       End LBA         Name
        Attributes
        Type GUID
        Partition GUID
  1     0x00004000      0x00005fff      "uboot"
        attrs:  0x0000000000000000
        type:   3e240000-0000-4719-8000-1de100003030
        guid:   cb6b0000-0000-4224-8000-356000002c8d
  ...
  3     0x00008000      0x00027fff      "boot"
        attrs:  0x0000000000000000
        type:   32410000-0000-487f-8000-685e0000531d
        guid:   a2570000-0000-4e68-8000-720100007df8
 ...
  7     0x00098000      0x00497fff      "rootfs"
        attrs:  0x0000000000000000
        type:   be090000-0000-487c-8000-551300005560
        guid:   614e0000-0000-4b53-8000-1d28000054a9
  8     0x00498000      0x03a3dfde      "userdata"
        attrs:  0x0000000000000000
        type:   323c0000-0000-4345-8000-065600004955
        guid:   7d060000-0000-4411-8000-53ba000044af

1.5、eMMC读/写和擦除命令

mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt

注:

addr:内存地址,内存中保存的内容可以通过md命令查看

blk#eMMC sector地址,sector大小一般为512,eMMC的实际地址为512 * blk#

cnteMMC sector个数

注:配合eMMC读/写和擦除命令,可以实现映像更新等调试功能。

2、内核阶段

在加载Linux内核时,eMMC驱动加载信息如下:

[    1.187234] mmc0: new HS200 MMC card at address 0001
[    1.188078] mmcblk0: mmc0:0001 Y2P032 29.1 GiB
[    1.188559] mmcblk0boot0: mmc0:0001 Y2P032 partition 1 4.00 MiB
[    1.189039] mmcblk0boot1: mmc0:0001 Y2P032 partition 2 4.00 MiB
[    1.189273] mmcblk0rpmb: mmc0:0001 Y2P032 partition 3 16.0 MiB, chardev (240:0)
[    1.192329]  mmcblk0: p1 p2 p3 p4 p5 p6 p7 p8

2.1、查看eMMC属性

[root@xiaotianbsp:/sys/kernel/debug/mmc0]# cat ios
clock:          198000000 Hz        ## eMMC时钟频率
vdd:            18 (3.0 ~ 3.1 V)
bus mode:       2 (push-pull)
chip select:    0 (don't care)
power mode:     2 (on)
bus width:      3 (8 bits)          ## eMMC数据位宽
timing spec:    9 (mmc HS200)       ## eMMC速度模式
signal voltage: 1 (1.80 V)          ## eMMC引脚电平
driver type:    0 (driver type B)

2.2、查看eMMC分区名

[root@xiaotianbsp:/dev/block/by-name]# ls -l
total 0
lrwxrwxrwx 1 root root 15 Jan  1 19:32 backup -> ../../mmcblk0p5
lrwxrwxrwx 1 root root 15 Jan  1 19:32 boot -> ../../mmcblk0p3
lrwxrwxrwx 1 root root 15 Jan  1 19:32 misc -> ../../mmcblk0p2
lrwxrwxrwx 1 root root 15 Jan  1 19:32 oem -> ../../mmcblk0p6
lrwxrwxrwx 1 root root 15 Jan  1 19:32 recovery -> ../../mmcblk0p4
lrwxrwxrwx 1 root root 15 Jan  1 19:32 rootfs -> ../../mmcblk0p7
lrwxrwxrwx 1 root root 15 Jan  1 19:32 uboot -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 15 Jan  1 19:32 userdata -> ../../mmcblk0p8

2.3、查看eMMC分区

[root@xiaotianbsp:/]# cat /proc/partitions
major minor  #blocks  name

   1        0       4096 ram0
 179        0   30535680 mmcblk0
 179        1       4096 mmcblk0p1
 179        2       4096 mmcblk0p2
 179        3      65536 mmcblk0p3
 179        4      65536 mmcblk0p4
 179        5      32768 mmcblk0p5
 179        6     131072 mmcblk0p6
 179        7    2097152 mmcblk0p7
 179        8   28127215 mmcblk0p8
 179       96   31166976 mmcblk1
 179       97   31166968 mmcblk1p1

2.4、查看eMMC已挂载分区

[root@xiaotianbsp:/]# mount
/dev/mmcblk0p7 on / type ext4 (rw,relatime)
...
/dev/mmcblk0p6 on /oem type ext2 (rw,relatime)
/dev/mmcblk0p8 on /userdata type ext4 (rw,relatime)
...

2.5、查看挂载的eMMC分区大小

[root@xiaotianbsp:/]# df -h
Filesystem      Size  Used Avail Use% Mounted on
...
/dev/mmcblk0p6  126M   13M  107M  11% /oem
/dev/mmcblk0p8   27G   45M   27G   1% /userdata

2.6、按不同方式查看eMMC分区

# 可以按照id/label等方式查看EMMC各分区
[root@xiaotianbsp:/dev/disk]# ls
by-id  by-label  by-partlabel  by-partuuid  by-path  by-uuid
[root@xiaotianbsp:/dev/disk/by-id]# ls
mmc-SD32G_0x54c496d5         mmc-Y2P032_0x745a16bb-part4
mmc-SD32G_0x54c496d5-part1   mmc-Y2P032_0x745a16bb-part5
mmc-Y2P032_0x745a16bb        mmc-Y2P032_0x745a16bb-part6
mmc-Y2P032_0x745a16bb-part1  mmc-Y2P032_0x745a16bb-part7
mmc-Y2P032_0x745a16bb-part2  mmc-Y2P032_0x745a16bb-part8
mmc-Y2P032_0x745a16bb-part3
[root@xiaotianbsp:/dev/disk/by-path]# ls
platform-fe2b0000.dwmmc        platform-fe310000.sdhci-part3
platform-fe2b0000.dwmmc-part1  platform-fe310000.sdhci-part4
platform-fe310000.sdhci        platform-fe310000.sdhci-part5
platform-fe310000.sdhci-boot0  platform-fe310000.sdhci-part6
platform-fe310000.sdhci-boot1  platform-fe310000.sdhci-part7
platform-fe310000.sdhci-part1  platform-fe310000.sdhci-part8
platform-fe310000.sdhci-part2

2.7、查看eMMC时钟关系

1)逐级查找父时钟

# 1.sdmmc0_drv的父时钟是clk_sdmmc0
[root@xiaotianbsp:/sys/kernel/debug/clk/sdmmc0_drv]# cat clk_phase
180
[root@xiaotianbsp:/sys/kernel/debug/clk/sdmmc0_drv]# cat clk_rate
148500000
[root@xiaotianbsp:/sys/kernel/debug/clk/sdmmc0_drv]# cat clk_parent
clk_sdmmc0
# 2.sdmmc0_sample的父时钟是clk_sdmmc0
[root@xiaotianbsp:/sys/kernel/debug/clk/sdmmc0_sample]# cat clk_phase
264
[root@xiaotianbsp:/sys/kernel/debug/clk/sdmmc0_sample]# cat clk_rate
148500000
[root@xiaotianbsp:/sys/kernel/debug/clk/sdmmc0_sample]# cat clk_parent
clk_sdmmc0
# 3.clk_sdmmc0的父时钟是gpll_300m
[root@xiaotianbsp:/sys/kernel/debug/clk/clk_sdmmc0]# cat clk_rate
297000000
[root@xiaotianbsp:/sys/kernel/debug/clk/clk_sdmmc0]# cat clk_parent
gpll_300m
# 4.gpll_300m的父时钟是gpll
[root@xiaotianbsp:/sys/kernel/debug/clk/gpll_300m]# cat clk_rate
297000000
[root@xiaotianbsp:/sys/kernel/debug/clk/gpll_300m]# cat clk_parent
gpll
# 5.gpll的父时钟是pll_gpll
[root@xiaotianbsp:/sys/kernel/debug/clk/gpll]# cat clk_rate
1188000000
[root@xiaotianbsp:/sys/kernel/debug/clk/gpll]# cat clk_parent
pll_gpll
# 5.pll_gpll的父时钟是xin24m
[root@xiaotianbsp:/sys/kernel/debug/clk/pll_gpll]# cat clk_parent
xin24m
[root@xiaotianbsp:/sys/kernel/debug/clk/pll_gpll]# cat clk_rate
1188000000

2)直接查找时钟树

[root@xiaotianbsp:/sys/kernel/debug/clk]# cat clk_summary
                                 enable  prepare  protect                                duty
   clock                          count    count    count        rate   accuracy phase  cycle
---------------------------------------------------------------------------------------------
...
 xin24m                              22       24        0    24000000          0     0  50000
    ...
    pll_gpll                          1        1        0  1188000000          0     0  50000
       gpll                           6       14        0  1188000000          0     0  50000
          ...
          gpll_300m                   5        9        0   297000000          0     0  50000
             clk_sdmmc0               1        1        0   297000000          0     0  50000
                sdmmc0_sample         0        0        0   148500000          0   263  50000
                sdmmc0_drv            0        0        0   148500000          0   180  50000
    ...

2.8、eMMC读写测试

## eMMC读
echo 3 > /proc/sys/vm/drop_caches
time dd if=/dev/mmcblk0p8 of=/dev/null bs=1M count=300
## eMMC写,test是eMMC某个分区内的文件夹
time dd if=/dev/zero of=test bs=1M count=300 conv=fsync

注:转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容