3.8.4. SPI 驱动
SPI 在 U-Boot 中主要用于支持 SPI NAND/NOR 存储设备。目前 ZX 平台上 SPI 的实现只支持半双工模式(Half-duplex)。
3.8.4.1. 驱动框架
U-Boot 驱动模型支持 SPI,ZX 平台中 SPI 驱动基于该框架进行实现。 相关配置为:
CONFIG_DM_SPI
CONFIG_SPI
CONFIG_SPL_SPI_SUPPORT
CONFIG_ZX_SPI
相关源码有:
drivers/spi/spi-uclass.c
include/spi.h
drivers/spi/zx_spi.c
3.8.4.2. 驱动接口
常用接口:
int dm_spi_claim_bus(struct udevice *dev);
void dm_spi_release_bus(struct udevice *dev);
int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags);
int spi_claim_bus(struct spi_slave *slave);
void spi_release_bus(struct spi_slave *slave);
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
void *din, unsigned long flags);
3.8.4.3. 初始化流程
SPI 设备挂载在 SPI 总线上,当 SPI 设备初始化时,如果父设备还没有被初始化, 则会自动触发父设备的初始化。下面是 SPI NAND 初始化时触发 SPI 初始化的流程。
mtd_probe(dev)
|-> device_probe(dev)
| // 此时 SPI 还没有 probe,则先 probe SPI
|-> device_probe(dev->parent); // drivers/core/device.c
| |-> drv->probe(dev);
| aic_spi_probe(dev); // drivers/spi/zx_spi.c
|
|-> drv->probe(dev);
spinand_probe(dev) // drivers/mtd/nand/spi/core.c
3.8.4.4. DMA 的支持
ZX SPI 驱动支持使用 DMA 收发数据和使用 FIFO 通过 CPU 读写的方式收发数据,
在 DMA 使能的情况下,对于数据长度大于等于 SPI_FIFO_DEPTH
的传输,驱动自动切换使用 DMA
进行传输,否则默认使用 FIFO 模式。
如果系统没有使能 DMA,则所有传输都使用 FIFO 模式。
使能 DMA 的 Kconfig 配置为:
CONFIG_ZX_DMA
3.8.4.5. QUAD SPI 的支持
对于非存储 SPI 设备,SPI 驱动只支持标准 SPI 模式,即 Single Mode,数据传输都使用一根线进行(MOSI 和 MISO)。
对于 SPI 存储设备(SPI NAND/SPI NOR),通过对接 spi-mem
框架,可以支持 DUAL SPI 和 QUAD SPI。
相关代码:
static const struct spi_controller_mem_ops aic_spi_mem_ops = {
.supports_op = aic_spi_mem_supports_op,
.exec_op = aic_spi_mem_exec_op,
};
static const struct dm_spi_ops aic_spi_ops = {
.claim_bus = aic_spi_claim_bus,
.release_bus = aic_spi_release_bus,
.xfer = aic_spi_xfer,
.set_speed = aic_spi_set_speed,
.set_mode = aic_spi_set_mode,
.mem_ops = &aic_spi_mem_ops,
};
通过设置 .exec_op
,SPI MEM 设备的所有操作都由 aic_spi_mem_exec_op
进行处理。
由于该接口可以获取到 SPI 操作的数据位宽等详细信息,驱动可以为每一个传输操作设置准确的模式(Single/Dual/Quad)。