mmc subsystem系列(持续更新中):
[mmc subsystem] 概念与框架
[mmc subsystem] mmc core(第一章)——概述
[mmc subsystem] mmc core(第二章)——数据结构和宏定义说明
[mmc subsystem] mmc core(第三章)——bus模块说明
[mmc subsystem] mmc core(第四章)——host模块说明
[mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)
[mmc subsystem] mmc core(第六章)——mmc core主模块
[mmc subsystem] host(第一章)——概述
[mmc subsystem] host(第二章)——sdhci
[mmc subsystem] host(第三章)——sdhci-pltfm说明
[mmc subsystem] host(第四章)——host实例(sdhci-msm说明)
建议先参考《[mmc subsystem] 概念与框架》对整体有一个了解。
==========================================================================================================
一、sdhci core说明
1、sdhci说明
具体参考《host(第一章)——概述》
SDHC:Secure Digital(SD) Host Controller,是指一套sd host控制器的设计标准,其寄存器偏移以及意义都有一定的规范,并且提供了对应的驱动程序,方便vendor进行host controller的开发。
vendor按照这套标准设计host controller之后,可以直接使用sdhci driver来实现host controller的使用,(qcom和samsung都使用了这套标准)。而vendor只需要实现平台相关的部分、如clock、pinctrl、power等等的部分即可。
关于这个标准,我们可以参考《SDHC_Ver3.00_Final_110225》。
注意,强调一下,这是一种mmc host controller的设计标准,其本质上还是属于mmc host。并且,其兼容mmc type card,而不是说只能使用于sd type card。
2、sdhci core
因为sdhci driver并不是某个特定host的driver,而是提供了一些接口和操作集方法给对应的host driver使用。
因此,我们将sdhci.c的代码部分称之为sdhci core用以和host driver区分。
其主要功能如下:
- 为host driver提供分配、释放sdhci_host的接口
- 为host driver提供注册、卸载sdhci_host的接口
- 实现sdhci_host和mmc_host的对接(也就是mmc core的对接)
- 实现host关于SDHCI标准的通用操作(sdhci_ops)
- 实现host的通用电源管理操作
注意,clock和pinctrl是由host driver自己管理,sdhci core并不参与。
3、代码位置
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
二、数据结构
1、struct sdhci_host
sdhci core将host抽象出struct sdhci_host来进行管理和维护。
- 数据结构如下:
struct sdhci_host {
/* Data set by hardware interface driver */
const char *hw_name; /* Hardware bus name */ // 名称
unsigned int quirks; /* Deviations from spec. */ // 癖好,可以理解为硬件sdhci controller和标准sdhci规范不符合的地方。
unsigned int quirks2; /* More deviations from spec. */ // 癖好2,可以理解为硬件sdhci controller和标准sdhci规范不符合的地方。
int irq; /* Device IRQ */ // sdhci的中断
void __iomem *ioaddr; /* Mapped address */ // sdhci寄存器的基地址
const struct sdhci_ops *ops; /* Low level hw interface */ // 底层硬件的操作接口
struct regulator *vmmc; /* Power regulator (vmmc) */ // sdhci core的LDO
struct regulator *vqmmc; /* Signaling regulator (vccq) */ // 给sdhci io供电的LDO
/* Internal data */
struct mmc_host *mmc; /* MMC structure */ // struct mmc_host,用于注册到mmc subsystem中
u64 dma_mask; /* custom DMA mask */
spinlock_t lock; /* Mutex */ // 自旋锁
int flags; /* Host attributes */ // sdhci的一些标识
unsigned int version; /* SDHCI spec. version */ // 当前sdhci的硬件版本
unsigned int max_clk; /* Max possible freq (MHz) */ // 该sdhci支持的最大电压
unsigned int timeout_clk; /* Timeout freq (KHz) */ // 超时频率
unsigned int clk_mul; /* Clock Muliplier value */ // 当前倍频值
unsigned int clock; /* Current clock (MHz) */ // 当前工作频率
u8 pwr; /* Current voltage */ // 当前工作电压
bool runtime_suspended; /* Host is runtime suspended */ // 是否处于runtime suspend状态
struct mmc_request *mrq; /* Current request */ // 当前正在处理的请求
struct mmc_command *cmd; /* Current command */ // 当前的命令请求
struct mmc_data *data; /* Current data request */ // 当前的数据请求
unsigned int data_early:1; /* Data finished before cmd */ // 表示在CMD处理完成前,data已经处理完成
struct sg_mapping_iter sg_miter; /* SG state for PIO */
unsigned int blocks; /* remaining PIO blocks */
int sg_count; /* Mapped sg entries */
u8 *adma_desc; /* ADMA descriptor table */
u8 *align_buffer; /* Bounce buffer */
unsigned int adma_desc_sz; /* ADMA descriptor table size */
unsigned int adma_desc_line_sz; /* ADMA descriptor line size */
unsigned int align_buf_sz; /* Bounce buffer size */
unsigned int align_bytes; /* Alignment bytes (4/8 for 32-bit/64-bit) */
unsigned int adma_max_desc; /* Max ADMA descriptos (max sg segments) */
dma_addr_t adma_addr; /* Mapped ADMA descr. table */
dma_addr_t align_addr; /* Mapped bounce buffer */
struct tasklet_struct card_tasklet; /* Tasklet structures */ // card tasklet,用于处理card的插入或者拔出事件
struct tasklet_struct finish_tasklet; // finsh tasklet,用来通知上层一个请求处理完成(包括出错的情况)
struct timer_list timer; /* Timer for timeouts */ // 超时定时器链表
u32 caps; /* Alternative CAPABILITY_0 */ // 表示该sdhci controller的属性
u32 caps1; /* Alternative CAPABILITY_1 */ // 表示该sdhci controller的属性
unsigned int ocr_avail_sdio; /* OCR bit masks */ // 在该sdhci controller上可用的sdio card的ocr值掩码(代表了其可用电压)
unsigned int ocr_avail_sd; // 在该sdhci controller上可用的sd card的ocr值掩码(代表了其可用电压)
unsigned int ocr_avail_mmc; /// 在该sdhci controller上可用的mmc card的ocr值掩码(代表了其可用电压)
/* 以下和mmc的tuning相关 */
wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read Ready interrupt */
unsigned int tuning_done; /* Condition flag set when CMD19 succeeds */
unsigned int tuning_count; /* Timer count for re-tuning */
unsigned int tuning_mode; /* Re-tuning mode supported by host */
#define SDHCI_TUNING_MODE_1 0
struct timer_list tuning_timer; /* Timer for tuning */
/* 以下和sdhci的qos相关 */
struct sdhci_host_qos host_qos[SDHCI_QOS_MAX_POLICY];
enum sdhci_host_qos_policy last_qos_policy;
bool host_use_default_qos;
unsigned int pm_qos_timeout_us; /* timeout for PM QoS request */
struct device_attribute pm_qos_tout;
struct delayed_work pm_qos_work;
struct sdhci_next next_data;
ktime_t data_start_time;
struct mutex ios_mutex;
enum sdhci_power_policy power_policy;
bool irq_enabled; /* host irq status flag */ // 表示中断是否使能?
bool async_int_supp; /* async support to rxv int, when clks are off */
bool disable_sdio_irq_deferred; /* status of disabling sdio irq */
u32 auto_cmd_err_sts;
struct ratelimit_state dbg_dump_rs;
int reset_wa_applied; /* reset workaround status */
ktime_t reset_wa_t; /* time when the reset workaround is applied */
int reset_wa_cnt; /* total number of times workaround is used */
unsigned long privat