一、说明

sdhci-msm是指高通的mmc host,其使用了标准SDHC标准。故可以使用前面说的《host(第二章)——sdhci》和《host(第三章)——sdhci-pltfm说明》的接口。

后续代码以msm8916平台的host实现以及linux 4.6.0版本中的sdhci-msm的实现为例,这部分代码都是开源的。

由于有一些寄存器内容需要文档的支撑但我们并没有,所以这里只是简单地介绍一下设计思想和代码结构。

二、dtsi节点

msm8916有两个sdhci host,我们以第一个host为例,默认接的是emmc

arch/arm64/boot/dts/qcom/msm8916.dtsi

    aliases {
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
}; sdhc_1: sdhci@07824000 {
compatible = "qcom,sdhci-msm-v4";
// 会和sdhci-msm.c的driver匹配 reg = <0x07824900 0x11c>, <0x07824000 0x800>;
reg-names = "hc_mem", "core_mem";
// 两部分寄存器,hc_mem表示sdhci使用的寄存器,core_mem表示msm host独立于sdhci标准之外的、自己需要使用的寄存器
// 因为驱动里面会使用sdhci-pltfm来进行解析,所以这里必须把hc_mem放在寄存器的第一个属性,具体参考《host(第三章)——sdhci-pltfm说明》 interrupts = <0 123 0>, <0 138 0>;
interrupt-names = "hc_irq", "pwr_irq";
// 两部分中断,hc_irq表示sdhci使用的中断,core_mem表示msm host检测host电源状态的中断、独立于sdhci标准
// 因为驱动里面会使用sdhci-pltfm来进行解析,所以这里必须把hc_irq放在中断的第一个属性,具体参考《host(第三章)——sdhci-pltfm说明》 clocks = <&gcc GCC_SDCC1_APPS_CLK>,
<&gcc GCC_SDCC1_AHB_CLK>;
clock-names = "core", "iface";
// 两个时钟
// core->GCC_SDCC1_APPS_CLK,工作时钟,也就是输出时钟
// iface->GCC_SDCC1_AHB_CLK,总线时钟 bus-width = <8>;
// 总线宽度设置为8
non-removable;
// 设置为不可移除
status = "disabled";
};

三、数据结构

1、struct sdhci_msm_host

sdhci-msm host driver根据自身资源定制的host结构体。

struct sdhci_msm_host {
struct platform_device *pdev; // 对应dtsi节点解析出来的平台设备
void __iomem *core_mem; /* MSM SDCC mapped address */ // host自身的寄存器基地址
struct clk *clk; /* main SD/MMC bus clock */ // 工作时钟,对应
struct clk *pclk; /* SDHC peripheral bus clock */
struct clk *bus_clk; /* SDHC bus voter clock */
struct mmc_host *mmc; // 对应的mmc_host结构体,具体参考《mmc core》
};

2、sdhci_msm_pdata

struct sdhci_pltfm_data类型。

提供给sdhci-pltfm接口使用的平台数据结构体,定义了sdhci_host的ops、quirks和quirks2。会在调用sdhci_pltfm_init生成sdhci_host的时候使用。

具体参考《host(第三章)——sdhci-pltfm说明》

static const struct sdhci_pltfm_data sdhci_msm_pdata = {
.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
SDHCI_QUIRK_SINGLE_POWER_WRITE,
.ops = &sdhci_msm_ops,
};

3、sdhci_msm_ops

struct sdhci_ops类型。

为sdhci_host提供出sdhci标准之外的一些实际的硬件操作方法的操作集给sdhci core。

具体参考《host(第二章)——sdhci》

static const struct sdhci_ops sdhci_msm_ops = {
.platform_execute_tuning = sdhci_msm_execute_tuning,
.reset = sdhci_reset,
.set_clock = sdhci_set_clock,
.set_bus_width = sdhci_set_bus_width,
.set_uhs_signaling = sdhci_set_uhs_signaling,
};

具体后面说明。这个操作集的内容也是sdhci host要实现的核心内容。

四、代码说明

1、设备驱动模型相关代码

static struct platform_driver sdhci_msm_driver = {
.probe = sdhci_msm_probe, // probe方法,也就是后面代码的介绍核心
.remove = sdhci_msm_remove, // remove方法
.driver = {
.name = "sdhci_msm",
.of_match_table = sdhci_msm_dt_match,
},
}; static const struct of_device_id sdhci_msm_dt_match[] = {
{ .compatible = "qcom,sdhci-msm-v4" }, // 以此来和dtsi节点匹配
{},
}; module_platform_driver(sdhci_msm_driver);

2、sdhci_msm_probe

  • 主要工作

    • 调用调用sdhci_pltfm_init为sdhci_host、sdhci_pltfm_host、sdhci_msm_host分配内存、设置
    • 关联mmc_host、sdhci_host、sdhci_pltfm_host、sdhci_msm_host
    • 解析dtsi属性设置到mmc_host和sdhci_host中
    • 获取各种时钟
    • 获取host独立于sdhci的寄存器基地址
    • 调用sdhci_add_host将sdhci_host注册到sdhci core中,相应的mmc_host也会被调用到mmc core中了。host的注册就完成了。
  • 代码如下

static int sdhci_msm_probe(struct platform_device *pdev)
{
struct sdhci_host *host;
struct sdhci_pltfm_host *pltfm_host;
struct sdhci_msm_host *msm_host;
struct resource *core_memres;
int ret;
u16 host_version, core_minor;
u32 core_version, caps;
u8 core_major; host = sdhci_pltfm_init(pdev, &sdhci_msm_pdata, sizeof(*msm_host));
// 调用sdhci_pltfm_init为sdhci_host、sdhci_pltfm_host、sdhci_msm_host分配内存
// 并对sdhci_host进行设置,具体可以参考《host(第三章)——sdhci-pltfm说明》
// 这里传入了sdhci_msm_pdata会用来设置sdhci_host的相关成员。
// 注意由于和前面文章的kernel版本的差异,这边的接口可能有点出入 pltfm_host = sdhci_priv(host);
msm_host = sdhci_pltfm_priv(pltfm_host);
msm_host->mmc = host->mmc;
msm_host->pdev = pdev;
// 关联mmc_host、sdhci_host、sdhci_pltfm_host、sdhci_msm_host
// 几个结构体之间的关系可以参考《host(第一章)——概述》 ret = mmc_of_parse(host->mmc);
// 调用mmc_of_parse解析host的dtsi节点属性,设置到mmc_host的caps属性中
// mmc_of_parse属于mmc core提供的标准接口,具体参考《mmc core——host模块说明》 sdhci_get_of_property(pdev);
// 调用sdhci_get_of_property解析host的dtsi节点属性,设置到sdhci_host的quirks和quirks2中 /* Setup SDCC bus voter clock. */
msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus");
// 获取bus时钟 /* Setup main peripheral bus clock */
msm_host->pclk = devm_clk_get(&pdev->dev, "iface");
// 获取iface时钟到msm_host->pclk中(GCC_SDCC1_AHB_CLK) ret = clk_prepare_enable(msm_host->pclk); /* Setup SDC MMC clock */
msm_host->clk = devm_clk_get(&pdev->dev, "core");
// 获取core时钟到msm_host->clk中(GCC_SDCC1_AHB_CLK) core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres);
// 获取msm host的寄存器基地址 /* Reset the core and Enable SDHC mode */
writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) |
CORE_SW_RST, msm_host->core_mem + CORE_POWER);
//.......以下过滤一下msm host的复位操作和初始化操作 ret = sdhci_add_host(host);
// 调用sdhci_add_host将得到的sdhci_host注册到sdhci core中。 return 0;
}

10. [mmc subsystem] host(第四章)——host实例(sdhci-msm说明)的更多相关文章

  1. 4. [mmc subsystem] mmc core(第四章)——host模块说明

    零.说明 对应代码drivers/mmc/core/host.c,drivers/mmc/core/host.h. 为底层host controller driver实现mmc host的申请以及注册 ...

  2. 8. [mmc subsystem] host(第二章)——sdhci

    一.sdhci core说明 1.sdhci说明 具体参考<host(第一章)--概述> SDHC:Secure Digital(SD) Host Controller,是指一套sd ho ...

  3. 7. [mmc subsystem] host(第一章)——概述

    一.host简单说明 host,也可以理解为host controller,是指mmc总线上的主机端,mmc总线的控制器,每个host controller对应一条mmc总线. host contro ...

  4. 9. [mmc subsystem] host(第三章)——sdhci-pltfm说明

    一.sdhci-pltfm说明 sdhci-pltfm并不是实际某个host的driver. sdhci-pltfm是指在sdhci core的基础上,提供了统一对sdhci_host的必要属性进行解 ...

  5. 5. [mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)

    零.说明(重要,需要先搞清楚概念有助于后面的理解) 1.mmc core card相关模块为对应card实现相应的操作,包括初始化操作.以及对应的总线操作集合.负责和对应card协议层相关的东西. 这 ...

  6. 6. [mmc subsystem] mmc core(第六章)——mmc core主模块

    一.说明 1.mmc core概述 mmc core主模块是mmc core的实现核心.也是本章的重点内容. 对应代码位置drivers/mmc/core/core.c. 其主要负责如下功能: mmc ...

  7. 《算法》第四章部分程序 part 10

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...

  8. [uboot] (第四章)uboot流程——uboot编译流程

    http://blog.csdn.net/ooonebook/article/details/53000893 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...

  9. [uboot] (第四章)uboot流程——uboot编译流程 (转)

    以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为例 [uboot] uboot流程系列:[project X] tiny210(s5pv210)上电启动流程(B ...

随机推荐

  1. [日常] 免费的文本比较工具Meld使用

    需要在linux桌面环境进行文件比较的时候,发现的一款文本比较工具,并且还有windows版本.之前一直在windows下使用的是beyond compare这个的破解版,这个软件本身是收费的而且还非 ...

  2. Python xlwt模块写Excel问题集合

    1.数字转换成汉字 数据库查询返回结果为多元组,在写入Excel需要判断,数据库查询结果是否为数字,为数字的话需要将其转换成对应的汉字,此时元组不可修改,所以需要将返回结果修改成列表.实现可以在数据库 ...

  3. cannot resolve symbol 'XXX'

    原因:出现这种情况的原因是在IDEA或者myeclipse编译器中没有导入相关的jar包(jar包相当于类的集合,可以使用其中的类): 针对IDEA出现cannot resolve symbol 'X ...

  4. nginx配置中root和alias的区别

    例:访问http://127.0.0.1/download/*这个目录时候让他去/opt/app/code这个目录找. 方法一(使用root关键字): location / { root /usr/s ...

  5. 04webpack--webpack-dev-server 时时跟新

    <!-- 如何添加npm run dev 启动程序 下载npm i webpack-dev-server -S 在pack.json中添加 "dev": "webp ...

  6. 201871010116-祁英红《面向对象程序设计(java)》第四周学习总结

    博文正文开头格式:(2分) 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://ww ...

  7. LG2444/BZOJ2938 「POI2000」病毒 AC自动机

    问题描述 LG2444 BZOJ2938 I \(\mathrm{AC}\)自动机 \(\mathrm{AC}\)自动机是一种多模式串匹配算法,本萌新今天刚学了它qwq 约定在构造\(\mathrm{ ...

  8. 【ECNU620】数学题(结论题)

    点此看题面 大致题意: 求\((n-1)!\ mod\ n\)的值. 大力猜结论 首先,看到样例,我们可以猜测: 当\(n\)为质数时,答案为\(n-1\). 当\(n\)为合数时,答案为\(0\). ...

  9. Xshell删除键不好使:删除显示退格^H

    Xshell删除键不好使:删除显示退格^H 1.问题: Xshell不能删除,删除时出现 退格^H 2.解决方案: 点击上方:文件→属性→终端→键盘,把 delete 和 backspace 序列改为 ...

  10. CSP-S 2019 AFO记

    DAY -1 上午并没有改出题,然而调出了动态$dp$,于是顺便$AC$了保卫王国,于是就很愉悦. 下午考前自闭赛,把会的题和原题写了出来,然后就$rank1$了,感觉自己$rp--$. 晚上发现$T ...