工具/软件:
您好:
我们正在使用一款具有 AM623 处理器和 FPGA(通过 QSPI 连接)的定制电路板。
AM623 运行的是 Linux 内核版本 6.6.87、可从以下位置获取: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/log/?h=ti-linux-6.6.y-cicd
在内核中、我检查了 TI 的低级 OSPI 驱动程序、该驱动程序位于:linux-kernel/drivers/spi/ spi-cadence-quadspi.c
基于这个驱动器、我为 FPGA 开发了一个更高级别的驱动器。 我正在使用 spi_mem_exec_op () 来自 Linux 内核的 API、用于发送和接收 QSPI 帧。
每次我打电话 spi_mem_exec_op () 、它从调用函数 spi-cadence-quadspi.c 它通过 QSPI 执行实际数据传输。
根据我的测试、我可以使用以下代码在 4-4-4 模式下成功从 FPGA 读取数据:
static int fpga_qspi_read(struct spi_mem *mem)
{
struct spi_mem_op op;
u8 *rx_buf;
int ret;
// Allocate RX buffer
rx_buf = devm_kzalloc(&mem->spi->dev, 16, GFP_KERNEL);
if (!rx_buf)
return -ENOMEM;
op = (struct spi_mem_op)SPI_MEM_OP(
SPI_MEM_OP_CMD(READ_OPCODE, 4), // Command 2 clock
SPI_MEM_OP_ADDR(3, 0x00AA55, 4), // 3-byte address 6 clocks
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_IN(2, rx_buf, 4) // 16-byte read, 4-bit bus 4 clocks
);
if (!spi_mem_supports_op(mem, &op))
{
dev_err(&mem->spi->dev, "Controller does not support this Quad Read op\n");
return -EOPNOTSUPP;
}
ret = spi_mem_exec_op(mem, &op);
if (ret)
{
dev_err(&mem->spi->dev, "Quad read failed: %d\n", ret);
return ret;
}
dev_info(&mem->spi->dev, "Read data:");
print_hex_dump(KERN_INFO, "FPGA: ", DUMP_PREFIX_OFFSET, 16, 1, rx_buf, 16, true);
return 0;
}
下面是示波器输出、用于确认通信正常工作且所有信号均按预期显示:

我还可以一次读取 16 个字节、而不会出现任何故障。
但是、这一问题出现在写入问题上。 每次我尝试写入操作(无论是在 4-4-4-4、1-4-4、1-1-4、甚至 1-1-1 模式下)都会失败、并返回一个错误、指出该操作不受支持。
此错误消息源自 spi-cadence-quadspi.c 司机、但我没能理解背后的确切原因。
在器件树中、OSPI 模块绑定如下:
ospi0: spi@fc40000 {
compatible = "ti,am654-ospi", "cdns,qspi-nor";
reg = <0x00 0x0fc40000 0x00 0x100>,
<0x05 0x00000000 0x01 0x00000000>;
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
cdns,fifo-depth = <256>;
cdns,fifo-width = <4>;
cdns,trigger-address = <0x0>;
cdns,phase-detect-selector = <2>;
clocks = <&k3_clks 75 7>;
assigned-clocks = <&k3_clks 75 7>;
assigned-clock-parents = <&k3_clks 75 8>;
assigned-clock-rates = <166666666>;
power-domains = <&k3_pds 75 TI_SCI_PD_EXCLUSIVE>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
因此、它 首先与兼容字符串“ti、am654-ospi“匹配。
然后、在此基础上、我将自定义驱动程序绑定如下:
&ospi0 {
status = "okay";
fpga@0{
compatible = "XYZ,fpga-qspi";
reg = <0x0>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
spi-max-frequency = <25000000>;
};
};
这是写入测试函数、但失败了:
static int fpga_qspi_write(struct spi_mem *mem)
{
u8 tx_buf[16] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
int ret;
struct spi_mem_op op = (struct spi_mem_op)SPI_MEM_OP(
SPI_MEM_OP_CMD(0x55, 4), // CMD
SPI_MEM_OP_ADDR(3, 0x00AA55, 4), // 3-byte address (1-bit lines)
SPI_MEM_OP_NO_DUMMY,
SPI_MEM_OP_DATA_OUT(16, tx_buf, 4) // 16-byte write over 4-bit bus
);
if (!spi_mem_supports_op(mem, &op))
{
dev_err(&mem->spi->dev, "spi_mem_supports_op() for writing failed!\n");
return -EOPNOTSUPP;
}
ret = spi_mem_exec_op(mem, &op);
if (ret)
{
dev_err(&mem->spi->dev, "spi_mem_exec_op() failed for write operation: %d\n", ret);
return ret;
}
return 0;
}
最后在这里我的问题:
1. spi-cadence-quadspi.c 支持哪些传输模式?
2.为什么你认为读操作成功,而类似的写操作失败?
3.比较 TI 时 spi-cadence-quadspi TI 存储库中的驱动程序与主线 Linux 内核中的驱动程序相比、哪个存储库提供更广泛的功能支持? 我们应该使用 Linux 主流而不是 TI 的下游器件吗?
谢谢。




