1、获取csd,也就是DSR寄存器
说是应该可以获取块长度、卡存储容量等,但是在8953上,没看到这个日志
参考:
Bit31 --- 卡上电状态位,如果卡上电过程完成,这个状态置位
Bit30 ---- 卡容量状态位,如果卡是SDHC卡,这个状态置位,0表示这个卡是SDSC卡
卡的识别寄存器CID是 128 Bit 的宽度
包括了卡的鉴别信息,每个读写卡都有一个唯一的鉴别号,主要也就是卡厂家、产品名、版本、厂家日期等的组合
卡特殊数据寄存器 提供访问卡的信息内容, CSD定义数据格式,错误校准类型,最大数据访问时间,是都DSR 寄存器可用等,有挺多内容
C_SIZE
这个参数用于计算用户数据卡容量(不包括安全保护区)。卡的容量通过 C_SIZE, C_SIZE_Mult
和 Read_BL_Len 来计算,如下
可写的 16-Bit ,存放卡的地址,是地址寄存器,这个地址用于在卡鉴别过程后的寻址Host-通讯,默认值为0x0000 ,0x0000保留给使用CMD7设置卡进入stand_by状态
16-Bit驱动阶段寄存器,可选,用于提高总线性能,默认0x404
卡配置寄存器,这个寄存器在工厂中设置
SD_Bus_Widths 描述卡支持的所有数据总线宽度
Cmd_Support 定义了支持的新命令
SD_SPEC 定义支持的CMD
mmc_sd_runtime_suspend 和 mmc_sd_runtime_resume (sd.c)
在 mmc_sd_runtime_resume 会再次调用mmc_sd_init_card (CONFIG_MMC_PARANOID_SD_INIT)初始化sd卡
sdhci_msm_populate_pdata (sdhci-msm.c)这个是在sdhci_msm_probe里调用的,用于配置msm_host (这个应该是控制器)
通过"cd-gpios" 可以解析 插入监测的gpio
通过 “qcom,bus-width” 解析的bus_width = 4
通过“qcom,bus-speed-mode” 解析的是支持的电压和总线速度
通过 "qcom,core_3_0v_support" 解析的是支持3.0v
sdhci_msm_probe (mmc/host/sdhci-msm.c)
通过"qcom,sdhci-msm-v5" 知道走的不是这个,随后调用sdhci_msm_populate_pdata
通过这个msm_host->ice.pdev 区分是都有ice,ice个人理解应该是emmc有的东西,普通的sdcard没有, gpio_is_valid 这个是普通sdcard走的流程
后面就是 sdhci_add_host (mmc/host/sdhci.c)这里面对capability进行处理
sdhci_setup_host 里的mmc_regulator_get_supply还对vmmc和vqmmc进行处理
sdhci_setup_host里的 host->caps & SDHCI_CAN_VDD_330 对 电压进行处理,这儿也有1.8V的电压, 会有 mmc->ocr_avail 和 host->ocr_avail_sd ,这个在后续初始化sd卡时有用
随后会调用到 __sdhci_add_host -->mmc_add_host-->mmc_start_host
mmc_start_host 里会调用mmc_power_up 和 _mmc_detect_change
mmc_power_up会调用__mmc_set_signal_voltage 设置 电压为3.3V
在mmc_alloc_host 里 设置了定时监测函数 INIT_DELAYED_WORK(&host->detect, mmc_rescan);
所以隔一段时间就会调用 mmc_rescan---->mmc_rescan_try_freq
在 mmc_rescan_try_freq 里
第一步mmc_power_up直接返回了
然后mmc_go_idle 先进入空闲状态
然后会在mmc_attach_sdio 、mmc_attach_sd、mmc_attach_mmc,一个一个进函数里匹配
emmc的卡会最后进入mmc_attach_mmc 并return 0,
sd卡的会进入mmc_attach_sd 并return 0返回
首先会发送mmc_send_app_op_cond ,第一次的ocr为0,并为了获取rocr,也就是response,拿到支持的电压范围,msm8953拿到的这值为40ff8000
然后mmc_select_voltage,此时会通过host->ocr_avail 对ocr 处理,拿到的数值rocr,作为参数给到mmc_sd_init_card (CONFIG_MMC_PARANOID_SD_INIT)
当 mmc_sd_init_card 成功后, 调用mmc_add_card (bus.c), 这里主要是识别卡是SD、SDXC 还是SDHC的卡,通过mmc_card_blockaddr 和 mmc_card_ext_capacity状态来分辨
之后有类似打印“new high speed SDXC card at address b36f”
紧接着调用 mmc_add_card_debugfs (CONFIG_DEBUG_FS),并将设备添加到块设备device_add
随后是块设备驱动的发现 mmc_blk_probe (mmc/card/block.c),通过string_get_size 可以获取块设备的大小
首先mmc_sd_get_cid
mmc_go_idle 先进入空闲状态, mmc_send_if_cond 指示card是否支持SD2.0接口(支持的话,ocr bit 30置位, 代表可以处理block-addressed SDHC cards, 40040000)
mmc_host_uhs的意思是,如果host支持UHS-I ,需要card切换到1.8V (但是好像支不支持都行的样子)
然后mmc_send_app_op_cond(能识别到sd卡),ocr为51040000, rocr = c0ff8000
然后mmc_send_relative_addr, &card->rca获取地址
然后mmc_sd_get_csd ---> mmc_decode_csd (能识别到sd卡的容量)
case 1: mmc_card_set_blockaddr、mmc_card_set_ext_capacity 分别是设置block 和 capacity的, csd->capacity = 0x7482400
csd_struct 这个拿的是csd寄存器的最高两位,显示的是CSD结构的版本,0 代表CSD version 1.0 (standard capacity), 1代表CSD version 2.0 (High Capacity and Extended Capacity)
mmc_sd_setup_card:
这里主要处理SCR寄存器,这里的SD_SPEC有不同的硬件版本,可以支持不同的容量的sdcard,暂时没仔细看
如果不支持SD_ROCR_S18A, 下面的就该mmc_sd_switch_hs (通过scr等寄存器看是否要切换high-speed mode)、 mmc_set_timing