SPI
SPI 在 U-Boot 中主要用于支持 SPI NAND/NOR 存储设备。目前 ArtInChip 平台上 SPI 的实现只支持半双工模式(Half-duplex)。
驱动框架
U-Boot 驱动模型支持 SPI,ArtInChip 平台中 SPI 驱动基于该框架进行实现。 相关配置为:
-
CONFIG_DM_SPI
-
CONFIG_SPI
-
CONFIG_SPL_SPI_SUPPORT
-
CONFIG_ARTINCHIP_SPI
相关源码有:
-
drivers/spi/spi-uclass.c
-
include/spi.h
-
drivers/spi/artinchip_spi.c
驱动接口
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);
初始化流程
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/artinchip_spi.c
|
|-> drv->probe(dev);
spinand_probe(dev) // drivers/mtd/nand/spi/core.c
DMA 的支持
ArtInChip SPI 驱动支持使用 DMA 收发数据和使用 FIFO 通过 CPU 读写的方式收发数据, 在 DMA 使能的情况下,对于数据长度大于等于 SPI_FIFO_DEPTH 的传输,驱动自动切换使用 DMA 进行传输,否则默认使用 FIFO 模式。
如果系统没有使能 DMA,则所有传输都使用 FIFO 模式。
使能 DMA 的 Kconfig 配置为:
-
CONFIG_ARTINCHIP_DMA
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)。