在下面的sdmmc info命令中,我们看到时序规范是“mmc DDR52”,
而SDMMC_CK引脚上的时钟频率仅为12.5MHz
为什么?

 
root@stm32mp151c-oeswa63:~#cat/sys/kernel/debug/mmc0/ios
时钟:25000000赫兹>>是SDMMC内核时钟

实际时钟:12500000 Hz>>是驱动器选择的SDMMC_CK引脚上的时钟频率
vdd:21(3.3~3.4伏)
总线模式:2(推挽式)
芯片选择:0(不在乎)
电源模式:2(打开)
总线宽度:3(8位)
时序规格:8(mmc DDR52)
信号电压:0(3.30V)
驱动程序类型:0(驱动程序类型B)

Linux SDMMC驱动程序决定尽可能采用SDMMC_CK引脚的最高频率
在SDMMC模式定义的最大频率内(在设备树绑定文件和下表中)
 
SDMMC_CK引脚上的频率取决于SDMMC内核时钟和SDMMC分频器。
当SDMMC处于DDR模式时,该除法器最小值=2,或当处于SDR模式时为1
(RM0436rv5图693)
 
  • 让我们以上面命令的RCC设置为例,其中:

SDMMC以DDR模式“eMMC高速”(见下表)连接到eMMC,SDMMC内核时钟源=PLL4P。
 
TF-A设备树中的PLL4P设置:
 
cfg=<1 42207 7个PQR(1,0,1)>;
frac=<0x1800>;
 
让我们从这两条设备树线中解码PLL设置,
看见
https://wiki.st.com/stm32mpu/wiki/Clock_device_tree_configuration_-_Bootloader_specific#Defining_per...
 
HSE=24兆赫
PLL4频率=HSE/2*(42+1+0x1800/8192)=12*43.75=525兆赫
 
20=>分区P=21->525/21=25兆赫
0x1800=6144
来自RefMan FRACV定义的8192值
FracN提供十进制值,介于0分钟和几乎1之间(8191/8192))

所以在目前的情况下,PLL4P是25MHz。
驱动程序设置DDR模式“eMMC高速”(“mmc-DDR-3_3v”在sdmmc设备树节点中)
并且以div=2选择低于52MHz频率的最高时钟。它将SDMMC_CK设置为PLL4P/2=12.5兆赫
 
  • SDMMC内核时钟PLL频率的选择  

假设PLL3R(104.5 MHz)用于SDMMC,PLL4P(89.57 MHz)用于以太网。事实上,在104.5 MHz下对SDMMC使用PLL3R比在89.5 MHz下使用PLL4更差
 
设备树中的SDMMC模式:mmc-ddr-3_3v(参见绑定和下表)=>最大SDMMC_CK=52 MHz
最好设置PLL4P=89.57MHz->SDMMC_CK=44.785
因为如果我们设置104.5/2=52.25>52MHz,那么驱动程序将不会使用div=2。
它将使用div=4104.5/4=26.125 MHz
 
SDMMC内核时钟可能的“父时钟”列表
看见https://github.com/STMicroelectronics/u-boot/blob/v2020.10-stm32mp/include/dt-bindings/clock/stm32mp...
 
父时钟由设备树“st,pkcs”属性选择
看见https://wiki.st.com/stm32mpu/wiki/Clock_device_tree_configuration_-_Bootloader_specific#Defining_per...
 

背景信息


SMMDC模式是根据闪光设备和预期速度设置的。
硬件不支持所有模式(例如eMMC上的HS400)
 
驱动程序模式在设备树文件中定义:
https://github.com/STMicroelectronics/linux/blob/v5.10-stm32mp/Documentation/devicetree/bindings/mmc...
 
SDMMC_CK时钟最大频率在RM0436rv5“SDMMC操作模式”的表格中
这是一个最大值,因此例如“eMMC高速DDR”模式下的SDMMC可以具有0到52MHz之间的任何SDMMC_CK频率值。


在RefMan0436表格中,HS200、200MHz是最大时钟。此处定义的最大时钟来自JDEC标准。
在STM32MP1上,eMMC和SDCard的SDMMC_CK有限制:最大值不是130MHz,而是100MHZ。
I/O最大速度是限制。