SPI
芯片名称与内核版本
芯片名称 | 内核版本 |
---|---|
采用 Linux 4.4 的所有芯片 | Linux 4.4 |
采用 Linux 4.19 及以上内核的所有芯片 | Linux 4.19 及以上内核 |
前言
概述
本文介绍 Linux SPI 驱动原理和基本调试方法。
读者对象
本文档主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
1. Rockchip SPI 功能特点
SPI (serial peripheral interface),以下是 linux 4.4 SPI 驱动支持的一些特性︰
- 默认采用摩托罗拉 SPI 协议
- 支持 8 位和 16 位
- 软件可编程时钟频率
- 支持 SPI 4 种传输模式配置
- 每个 SPI 控制器支持一个到两个片选
- 支持 spi slave mode,有且仅有 SPI_CS0N 作为 CS 输入脚:
- 传输过程不允许切换为 GPIO function
- 不支持 CS1N 替代 除以上支持,linux 4.19 新增以下特性:
- 框架支持 slave 和 master 两种模式
1.1 SPI 接口速率
芯片名称 | Master Mode 接口最高速率 | Slave Mode 接口最高速率 |
---|---|---|
RK3506 | 50MHz | 50MHz |
RV1106B/RV1103B | 50MHz | 33MHz |
RK3576 | 50MHz | 33MHz |
RK3562 | 50MHz | 33MHz |
RK3528 | 50MHz | 33MHz |
RV1106/RV1103 | 50MHz | 33MHz |
RK3588 | 50MHz | 33MHz |
RV1126/RV1109 | 50MHz | 16MHz |
RK3568 | 50MHz | 33MHz |
RK1808 | 50MHz | 16MHz |
RK3308 | 50MHz | 16MHz |
其他芯片平台 | 50MHz | 16MHz |
说明:
- 接口最高速率为理论速率,受设备走线 PCB 质量影响,以实测为准。
- 部分平台由于 PLL 策略原因无法准确分频到上限值,实际以最大分频值为准。
2. 内核软件
2.1 代码路径
drivers/spi/spi.c
:SPI 驱动框架drivers/spi/spi-rockchip.c
:RK SPI 各接口实现drivers/spi/spi-rockchip-slave.c
:RK SPI slave 各接口实现drivers/spi/spidev.c
:创建 SPI 设备节点,用户态使用drivers/spi/spi-rockchip-test.c
:SPI 测试驱动,需要手动添加到 Makefile 编译Documentation/spi/spidev_test.c
:用户态 SPI 测试工具
2.2 SPI 设备配置 —— RK 芯片作 Master 端
内核配置
Device Drivers --->
[*] SPI support --->
<*> Rockchip SPI controller driver
DTS 节点配置
&spi1 {
status = "okay";
// assigned-clocks = <CLK_SPI1>; // 默认不用配置,CLK_SPIn 请从 soc 对应的 dtsi 里确认
// assigned-clock-rates = <200000000>; // 默认不用配置,SPI 设备工作时钟值
// dma-names; // 默认不用配置,关闭 DMA 支持,仅支持 IRQ 传输
// rockchip,poll-only; // 默认不用配置,开启后强制使用 CPU 传输,仅支持 master mode 下配置
// rx-sample-delay-ns = <10>; // 默认不用配置,读采样延时,详细参考 “常见问题”“延时采样时钟配置方案” 章节
// rockchip,autosuspend-delay-ms = <500>; // 默认不用配置,Runtime PM autosuspend 延时,详细参考 “SPI 传输速率及 CPU 负载优化”
// rockchip,rt; // 默认不用配置,将 spi 数据传输进程放到 SCHED_FIFO 类中,其优先级为 50
spi_test@10 {
compatible = "rockchip,spi_test_bus1_cs0"; // 与驱动对应的名字
reg = <0>; // 片选 0 或者 1
spi-cpha; // 设置 CPHA = 1,不配置则为 0
spi-cpol; // 设置 CPOL = 1,不 配置则为 0
spi-lsb-first; // IO 先传输 lsb
spi-max-frequency = <24000000>; // spi clk 输出的时钟频率,不超过 50M
status = "okay"; // 使能设备节点
};
};
spiclk assigned-clock-rates 和 spi-max-frequency 的配置说明::
spi-max-frequency
是 SPI 的输出时钟,由 SPI 工作时钟spiclk assigned-clock-rates
内部分频后输出,由于内部至少 2 分频,所以关系是spiclk assigned-clock-rates >= 2 * spi-max-frequency
。- 假定需要 50MHz 的 SPI IO 速率,可以考虑配置(记住内部分频为偶数分频)
spi_clk assigned-clock-rates = <100000000>
,spi-max-frequency = <50000000>
,即工作时钟 100MHz(PLL 分频到一个不大于 100MHz 但最接近的值),然后内部二分频最终 IO 接近 50MHz。 spiclk assigned-clock-rates
不要低于 24M,否则可能有问题。
2.3 SPI 设备配置 —— RK 芯片作 Slave 端
关键补丁
推荐使用 SPI slave 源码 spi-rockchip-slave.c,由于 SDK 版本问题,建议先确认 SDK 是否有以下补丁:
commit 10cbf3c2c93fca6e5ec6c99b5bdb319ca0494d45
Author: Jon Lin <jon.lin@rock-chips.com>
Date: Tue Nov 21 10:58:57 2023 +0800
spi: rockchip-slave: Add code
1. Implement one msg mechanism
2. Support SRAM extension by dts rockchip,sram property
Change-Id: I0fccc5d4347294488b5382ad3ba5ae72b35610f2
Signed-Off-By: Jon Lin <jon.lin@rock-chips.com>
说明:
- 如无该补丁,客户可直接通过 Redmine -> FAE 项目 -> 文档 -> 开发配置文档 -> SPI 路径获取。
内核配置
Device Drivers --->
[*] SPI support --->
[*] SPI slave protocol handlers
[*] Rockchip SPI Slave controller driver
DTS 节点配置
&spi1 {
compatible = "rockchip,spi-slave"; // 优先使用 SPI slave 专用驱动
status = "okay";
// ready-gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_LOW>; // 建议配置,SPI slave 完成传输配置的信号,详细参考 “内核 SPI Slave 软件” 章节
// rockchip,cs-inactive-disable; // 默认不用配置,当 SPI master 时序 tod_cs(Clk Rise To CS Rise Time) 超过多个 io 时钟周期,应开启配置来屏蔽检测 cs 释放动作
slave { // 按照框架要求,SPI slave 子节点的命名需以 "slave" 开始
compatible = "rockchip,spi_test_bus1_cs0";
reg = <0>; // 片选仅支持 0
spi-cpha; // 设置 CPHA = 1,不配置则为 0
spi-cpol; // 设置 CPOL = 1,不配置则为 0
spi-lsb-first; // IO 先传输 lsb
status = "okay"; // 使能设备节点
};
};
说明:
- RK SPI 默认使能 DMA 传输,slave mode 不建议关闭 DMA 传输。当一笔传输超过控制器缓存数量,软件会配置为 DMA 传输,来避免中断传输相应不及时。