主题中讨论的其他器件:AM67、 AM68
工具与软件:
您好!
在我们的器件树中配置 SPI 器件时、我注意到示波器上显示的 SPI 时钟大约比我为 SPI 器件节点中的 spi-max-frequency 参数指定的值小3倍。 为什么会这样? 我是否还需要在器件树中配置其他时钟?
我在定制电路板上使用 Linux SDK v 10.00.00.08。
谢谢!
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
尊敬的 Amandio:
最大值与使用的实际时钟不同。 我在过去的 E2E 主题中发现此类似行为: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1365643/tda4vh-q1-vh-change-spi-max-frequency-of-ospi/5286765?tisearch=e2e-sitesearch&keymatch=spi-max-frequency#5286765
此外、通过分频器值可以实现的时钟速率存在硬件限制。 附件是 TRM 的屏幕截图:

此致、
Takuma
你好、Takuma、
感谢您的回复! 我通过你链接的帖子阅读,如果我理解正确,体验是不同的。 在您链接的帖子中、用户看到时钟速率被强制达到最接近的支持速率。 我看到的是、在我为 SPI-max-frequency 指定的任何速率下、该速率除以大约3。
例如、当我将 spi-max-frequency 设置为48 MHz 时、我会测量约16.6 MHz 的时钟速率、该速率约低3倍。 我看到您在 TRM 中发布的同一个表、16.6MHz 也未在其中列出。 听起来时钟速率应该被强制采用50MHz 或25MHz、但事实并非如此。
以下是我为 dev id 341转储时钟时的 k3conf 输出、在本例中、当 spi-max-frequency 为48000000 (48MHz)时、此时钟为 MAIN_SPI2:
|------------------------------------------------------------------------------| | VERSION INFO | |------------------------------------------------------------------------------| | K3CONF | (version 0.3-nogit built Thu Jul 25 14:13:02 UTC 2024) | | SoC | J721S2 SR1.0 | | SYSFW | ABI: 4.0 (firmware version 0x000a '10.0.8--v10.00.08 (Fiery Fox))') | |------------------------------------------------------------------------------| |---------------------------------------------------------------------------------------------------------------------------| | Device ID | Clock ID | Clock Name | Status | Clock Frequency | |---------------------------------------------------------------------------------------------------------------------------| | 341 | 0 | DEV_MCSPI2_IO_CLKSPIO_CLK | CLK_STATE_READY | 0 | | 341 | 1 | DEV_MCSPI2_VBUSP_CLK | CLK_STATE_READY | 125000000 | | 341 | 2 | DEV_MCSPI2_CLKSPIREF_CLK | CLK_STATE_READY | 50000000 | | 341 | 3 | DEV_MCSPI2_IO_CLKSPII_CLK | CLK_STATE_READY | 0 | | 341 | 4 | DEV_MCSPI2_IO_CLKSPII_CLK_PARENT_BOARD_0_SPI2_CLK_OUT | CLK_STATE_READY | 0 | | 341 | 5 | DEV_MCSPI2_IO_CLKSPII_CLK_PARENT_SPI_MAIN_2_IO_CLKSPIO_CLK | CLK_STATE_NOT_READY | 0 | |---------------------------------------------------------------------------------------------------------------------------|
您能否对此提供更深入的见解?
谢谢!
尊敬的 Amandio:
感谢 k3conf 转储。 看起来 SPI 时钟设置为50MHz、最靠近48MHz。 16.6MHz 是其中的1/3、因此听到这种情况很奇怪。
3个问题:
此致、
Takuma
你好、Takuma、
我已经在 MAIN_SPI2和 MAIN_spi5时钟引脚上测量了时钟。 那么、AB25用于 SPI2_CLK、T27用于 SPI5_CLK。 我可以在 mcspi 实例中重现相同的行为、并且每个实例的 k3conf 时钟输出也是相同的。
在 MAIN_SPI2上、我们已连接了来自 Microchip 的 ATWILC3000。 我们不使用树驱动器中的电流、而是使用 Microchip 通过其自己的 Linux 分支主动维护的驱动器。 您可以在以下位置找到它: https://github.com/linux4microchip/linux/tree/linux-6.6-mchp/drivers/net/wireless/microchip/wilc1000
在 main_spi5中、我们只使用 spi-dev 进行 SPI 通信。
以下是您在使用定义的调试宏重新构建 mcspi 驱动程序后请求的日志。 日志中需要注意的是、spi1.0是连接到 Microchip ATWILC3000的 MAIN_SPI2、spi2.0是使用 SPI-dev 的 MAIN_spi5。
e2e.ti.com/.../dmesg_5F00_spi_5F00_debug.txt
感谢您的参与和帮助!
尊敬的 Amandio:
通过驱动器、我没有看到任何会设置软限制的东西。 我也看不到对测量信号有任何特殊之处。
是否可以添加此调试打印文件:
e2e.ti.com/.../0001_2D00_adding_2D00_debug_2D00_logs_2D00_to_2D00_spi_2D00_omap2_2D00_mcspi.c.patch
并且还使用 devmem2或其他工具转储以下寄存器:
此致、
Takuma
你好、Takuma、
以下是使用补丁重新编译后的 dmesg 日志:
e2e.ti.com/.../dmesg_5F00_spi_5F00_debug_5F00_patch.txt
您需要的寄存器值如下:
再次感谢您的帮助!
尊敬的 Amandio:
感谢您提供日志和寄存器转储。
问题可能是、我们使用的48MHz 不完全是50MHz、并导致分频器值出现一些问题。 您是否还可以尝试将时钟速率设置为50MHz 和25MHz 并进行测量(如果尚未设置)?
下面是我发现的有关此建议的信息。
看起来我们处于粒度模式、CLKD (时钟分频)字段的值为2、然后将其加1以获得 SPICLK 分频比。 具体细节如下:

突出显示的行是输出的内容、即16.6MHz:

问题可能在于我们的驱动程序是如何计算除数值的、因此尝试一个不需要除数值(50MHz)的值、尝试一个明确除数值为2 (25MHz)的值会很有趣。
此致、
Takuma
你好、Takuma、
感谢您提供这些信息。
在 MAIN_spi5 (spidev 器件)上将 SPI-max-frequency 设置为恰好50000000 (50 MHz)后、我可以使用示波器16.61 MHz 测量时钟输出上的相同速率。
下面是 k3conf 时钟转储:
root@am68-sk:~# k3conf dump clock 344 |------------------------------------------------------------------------------| | VERSION INFO | |------------------------------------------------------------------------------| | K3CONF | (version 0.3-nogit built Thu Jul 25 14:13:02 UTC 2024) | | SoC | J721S2 SR1.0 | | SYSFW | ABI: 4.0 (firmware version 0x000a '10.0.8--v10.00.08 (Fiery Fox))') | |------------------------------------------------------------------------------| |---------------------------------------------------------------------------------------------------------------------------| | Device ID | Clock ID | Clock Name | Status | Clock Frequency | |---------------------------------------------------------------------------------------------------------------------------| | 344 | 0 | DEV_MCSPI5_IO_CLKSPIO_CLK | CLK_STATE_READY | 0 | | 344 | 1 | DEV_MCSPI5_VBUSP_CLK | CLK_STATE_READY | 125000000 | | 344 | 2 | DEV_MCSPI5_CLKSPIREF_CLK | CLK_STATE_READY | 50000000 | | 344 | 3 | DEV_MCSPI5_IO_CLKSPII_CLK | CLK_STATE_READY | 0 | | 344 | 4 | DEV_MCSPI5_IO_CLKSPII_CLK_PARENT_BOARD_0_SPI5_CLK_OUT | CLK_STATE_READY | 0 | | 344 | 5 | DEV_MCSPI5_IO_CLKSPII_CLK_PARENT_SPI_MAIN_5_IO_CLKSPIO_CLK | CLK_STATE_NOT_READY | 0 | |---------------------------------------------------------------------------------------------------------------------------|
这是 dmesg 输出。 SPI 驱动程序仍在使用您之前给我提供的调试补丁。
e2e.ti.com/.../dmesg_5F00_spidev_5F00_debug_5F00_patch_5F00_50MHz.txt
在 MAIN_spi5上的 SPI-max 频率恰好设置为25000000 MHz 的情况下、我几乎在 SPI 时钟输出的点测量10MHz。
下面是使用此时钟设置时的 k3conf 时钟转储:
root@am68-sk:/opt/edgeai-gst-apps# k3conf dump clock 344 |------------------------------------------------------------------------------| | VERSION INFO | |------------------------------------------------------------------------------| | K3CONF | (version 0.3-nogit built Thu Jul 25 14:13:02 UTC 2024) | | SoC | J721S2 SR1.0 | | SYSFW | ABI: 4.0 (firmware version 0x000a '10.0.8--v10.00.08 (Fiery Fox))') | |------------------------------------------------------------------------------| |---------------------------------------------------------------------------------------------------------------------------| | Device ID | Clock ID | Clock Name | Status | Clock Frequency | |---------------------------------------------------------------------------------------------------------------------------| | 344 | 0 | DEV_MCSPI5_IO_CLKSPIO_CLK | CLK_STATE_READY | 0 | | 344 | 1 | DEV_MCSPI5_VBUSP_CLK | CLK_STATE_READY | 125000000 | | 344 | 2 | DEV_MCSPI5_CLKSPIREF_CLK | CLK_STATE_READY | 50000000 | | 344 | 3 | DEV_MCSPI5_IO_CLKSPII_CLK | CLK_STATE_READY | 0 | | 344 | 4 | DEV_MCSPI5_IO_CLKSPII_CLK_PARENT_BOARD_0_SPI5_CLK_OUT | CLK_STATE_READY | 0 | | 344 | 5 | DEV_MCSPI5_IO_CLKSPII_CLK_PARENT_SPI_MAIN_5_IO_CLKSPIO_CLK | CLK_STATE_NOT_READY | 0 | |---------------------------------------------------------------------------------------------------------------------------|
这是相关的 dmesg 输出。 同样、正在使用的 SPI 驱动程序就是您之前给我的调试补丁:
e2e.ti.com/.../dmesg_5F00_spidev_5F00_debug_5F00_patch_5F00_25MHz.txt
我没有对 MAIN_SPI2进行任何测量、只是因为 MAIN_spi5更容易访问、并且在 MAIN_SPI2和 MAIN_spi5之间移动探针可能会导致一些测试引线断开。
我忘记的其他一些信息可能很有用。
以下是 SPI-max-frequency 为50 MHz 时的寄存器值:
和在25 MHz 处:
尊敬的 Amandio:
感谢您的实验、日志和寄存器转储。 您在示波器上测量的内容似乎与在寄存器中编程的内容一致。 也就是说、对于50MHz、编程了一个2+1的分频器值、而25MHz 的分频器值为4+1 -这非常奇怪。
我最后做了一些实验、但到目前为止一直无法重现该问题。 设置上存在一些差异、例如使用10.1 SDK 而非10.0和 AM67而非 AM68、但差异不大。 如果我们在下面的实验中看到差异、那么我们可以更改 SDK 版本并重复该实验
2件事:
1.您是否可以添加额外的补丁并再次共享 dmesg 日志:
e2e.ti.com/.../0001_2D00_print_2D00_out_2D00_spi_2D00_related_2D00_settings.patch
我最后尝试将 spi-max-frequency 设置为50000000和48000000、以下是50MHz 的对应值:
root@j722s-evm:/opt/edgeai-gst-apps# dmesg | grep DEBUG [ 8.720694] DEBUG: max_speed_hz is 50000000, min_speed_hz is 1525 [ 8.745969] DEBUG: clock granularity bit set [ 8.763414] DEBUG: ref_clk_hz is 50000000, div is 1, speed_hz is 50000000, clkd is 0, extclk is 0, and clkg is 0x20000000 root@j722s-evm:/opt/edgeai-gst-apps#
对于48MHz:
root@j722s-evm:/opt/edgeai-gst-apps# dmesg | grep DEBUG [ 8.664938] DEBUG: max_speed_hz is 50000000, min_speed_hz is 1525 [ 8.710022] DEBUG: clock granularity bit set [ 8.710036] DEBUG: ref_clk_hz is 50000000, div is 2, speed_hz is 25000000, clkd is 1, extclk is 0, and clkg is 0x20000000 root@j722s-evm:/opt/edgeai-gst-apps#
因此、如上述日志所示、尽管无法获得48MHz 存在限制、但驱动器的行为应该是尝试在不超过最大 SPI 频率的情况下将时钟设置为可能的最高时钟速率。 因此、如果设置为48MHz、应该看到25MHz 而不是16.6MHz。
2.在我的第二个问题中、您可以共享用于设置 SPI 节点的 devicetree 文件吗?
此致、
Takuma
你好、Takuma、
我应用了补丁、但由于我在使用一些 SPI 模块、因此我添加了一个额外的 printk 来打印 SPI 模块的物理地址、这样我们就知道 dmesg 日志的哪些详细信息属于哪个 SPI 模块。
以下是 MAIN_spi5设置为50MHz 时的相关 dmesg 输出:
[ 6.135466] DEBUG: spi address: 0x2150100. [ 6.145518] DEBUG: max_speed_hz is 125000000, min_speed_hz is 3814 [ 6.147018] DEBUG: clock granularity bit set [ 6.178927] DEBUG: ref_clk_hz is 125000000, div is 3, speed_hz is 41666666, clkd is 2, extclk is 0, and clkg is 0x20000000
这是完整的 dmesg 输出:
e2e.ti.com/.../dmesg_5F00_spi_5F00_debug_5F00_patch2_5F00_50MHz.txt
当 main_spi5恰好设置为48MHz 时、以下是 dmesg 输出的调试部分:
[ 6.055457] DEBUG: spi address: 0x2150100. [ 6.076326] DEBUG: max_speed_hz is 125000000, min_speed_hz is 3814 [ 6.108907] DEBUG: clock granularity bit set [ 6.108918] DEBUG: ref_clk_hz is 125000000, div is 3, speed_hz is 41666666, clkd is 2, extclk is 0, and clkg is 0x20000000
这是完整的 dmesg 输出:
e2e.ti.com/.../dmesg_5F00_spi_5F00_debug_5F00_patch2_5F00_48MHz.txt
我即将完成问题的第2部分、当时我对 SDK 版本很有兴趣。 我找到该主题:
DRA821U:SPI 无法工作、因为为 OMAP 加载 McSPI 驱动程序失败-处理器论坛-处理器- TI E2E 支持论坛
这为我提供了以下资源:
TDA4VM:启用 SPI 后内核崩溃-处理器论坛-处理器- TI E2E 支持论坛
这些都描述了如何将 j7200平台的"main"dtsi 中的时钟 ID 从1更正为4。 由于这些平台有很多共同点、我在 ti-linux 存储库的10.01.08版标签中查看了 j721s2的"main"dtsi。 果然、 根据该提交、时钟 ID 在这里更正为、但从1 (DEV_MCSPI5_VBUSP_CLK)更正为2 (DEV_MCSPI5_CLKSPIREF_CLK):
我想这是有道理的、因为 TRM 提到 SPICLKREF 是进入分频器的时钟、而 DEV_MCSPI5_CLKSPIREF_CLK 似乎与该名称非常接近。 什么是 VBUSP_CLK?为什么可以选择 VBUSP_CLK? 事实上、如果可能导致这样的问题、为什么先更改 SPI 时钟源呢?
我更新了本地时钟 ID 副本、并且可以观察到 预期的行为。 当 SPI-max-frequency 设置为 50 MHz 时、我会测量约50 MHz。 如果我将其设置为48 MHz、则我仅测量25 MHz 左右的值。
我会注意到的另一件事是、mcspi 似乎始终选择时钟粒度模式。 我想知道这是否是错误? 请参阅中的此部分
if (speed_hz < (ref_clk_hz / OMAP2_MCSPI_MAX_DIVIDER)) {
clkd = omap2_mcspi_calc_divisor(speed_hz, ref_clk_hz);
speed_hz = ref_clk_hz >> clkd;
clkg = 0;
printk("DEBUG: omap2_mcspi_calc_divisor is used");
} else {
div = (ref_clk_hz + speed_hz - 1) / speed_hz;
speed_hz = ref_clk_hz / div;
clkd = (div - 1) & 0xf;
extclk = (div - 1) >> 4;
clkg = OMAP2_MCSPI_CHCONF_CLKG;
printk("DEBUG: clock granularity bit set");
printk("DEBUG: ref_clk_hz is %d, div is %d, speed_hz is %d, clkd is %d, extclk is %d, and clkg is 0x%x", ref_clk_hz, div, speed_hz, clkd, extclk, clkg);
}尊敬的 Amandio:
在 devicetree 中看到 McSPI 时钟变化时的好发现! 我以为 J721S2/AM68 能够安全地避免这个错误、但我错了。
VBUSP_CLK 应为用于将外设互连到系统其余部分的内部总线时钟。 devicetree 时钟错误是由于 假设来自类似 SoC 的时钟 ID 相同、 但在 实践中、基准时钟不可配置。 我想我们的实验就证明了这一点、因为越野软件报告在41.6MHz 上以3分频运行、但实际测量的时钟为16.6、因为 实际参考时钟是50MHz 而不是125MHz。
至于粒度、您 说得非常好。 粒度模式为除数提供了更多位。 然而、尽管非粒度模式产生的位较少、但时钟分频比以2的幂次(因此粒度较小、但可能的分频器较大)计算、因此从理论上讲、非粒度应该会提供更大的时钟范围。 但是、对于当前 SoC、粒度和非粒度模式的最大除数为4096。
此致、
Takuma
至于粒度、您可以 提出一个好主意。 粒度模式为除数提供了更多位。 然而、尽管非粒度模式产生的位较少、但时钟分频比以2的幂次(因此粒度较小、但可能的分频器较大)计算、因此从理论上讲、非粒度应该会提供更大的时钟范围。 但是、对于当前 SoC、粒度模式和非粒度模式的最大分频值均为4096。
我懂了。 我想我不明白驱动程序如何使用当前代码选择非粒度模式。 您必须请求一个小于模块可以生成的最小时钟频率的时钟频率。 但 无论如何、分频值始终是 OMAP2_MCSPI_MAX_DIVIDER、因为我们不能小于它。 此外、时钟粒度模式可以为我们提供非粒度模式可以提供的所有频率、因此我不确定选择非粒度模式时的重点是什么。
不管怎么说,我开始控制原来的主题。 我的问题现已解决、因此、感谢您的投入和努力! 非常感谢!