7.10.6.1. 如何添加新的 SPI NAND 设备¶
7.10.6.1.1. 驱动层次关系¶
SPI NAND 属于 SPI 的从设备,在内核中相关驱动通过 SPI MEM 对接到 SPI
子系统,如 图 7.40 所示。
在 SPI 控制器初始化时,SPI 驱动会检查该控制器下是否有挂载的 SPI NAND,有则添加到 SPI BUS 中。
aic_spi_probe(dev);
|-> spi_register_controller(ctlr);/spi_register_master(ctlr);
    |   // spi_register_master 是一个宏
    |
    |-> of_register_spi_devices(ctlr);
        |-> spi = of_register_spi_device(ctlr, nc);
            |-> spi = spi_alloc_device(ctlr);
            |-> of_spi_parse_dt(ctlr, spi, nc);
            |-> rc = spi_add_device(spi);
                // 将 SPI device 添加到 SPI 总线 spi_bus_type 中
在调用 spi_add_device 的过程中,会查找和匹配对应设备的驱动程序(如果这时候对
应的驱动程序还没有被添加到系统中,则在这里先将设备添加到 Bus,等到对应驱动程序
被添加进来时,再进行匹配。)
| 模块 | 驱动源码路径 | 
|---|---|
| SPI NAND | source/linux-5.10/drivers/mtd/nand/spi/ | 
7.10.6.1.2. 检查和添加新设备¶
内核中所支持的 SPI NAND 设备通过两级列表进行设置。
首先检查 source/linux-5.10/drivers/mtd/nand/spi/core.c 中的 spinand_manufacturers,
查看新设备的厂商是否在列表之中:
static const struct spinand_manufacturer *spinand_manufacturers[] = {
    &gigadevice_spinand_manufacturer,
    ¯onix_spinand_manufacturer,
    µn_spinand_manufacturer,
    ¶gon_spinand_manufacturer,
    &toshiba_spinand_manufacturer,
    &winbond_spinand_manufacturer,
};
再检查具体的设备厂商文件,具体的型号是否在列表之中( 以gigadevice 为例):
static const struct spinand_info gigadevice_spinand_table[] = {
    SPINAND_INFO("GD5F1GQ4UExxG",
             SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
             NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
             NAND_ECCREQ(8, 512),
             SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                          &write_cache_variants,
                          &update_cache_variants),
             SPINAND_HAS_QE_BIT,
             SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
                     gd5fxgq4uexxg_ecc_get_status)),
    ......
};
此处检查,需要查找新设备的 Datasheet,找到该设备的 Device ID(可在 Datasheet 中直接搜索 “Device ID”)。
并查看该 Device ID 是否出现在列表中。例如此处 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1), 的最后一个数值 0xd1 就是 一个 Device ID 值。
如果不存在,则参考上述例子,添加一个新的设备记录。
7.10.6.1.3. 修改 DTS¶
要在实际项目中使用 SPI NAND 设备,还需要修改 DTS 配置。
board.dts 应在具体的 SPI 控制器下添加 spi-nand 设备。
&spi1 {
    pinctrl-names = "default";
    pinctrl-0 = <&spi1_pins_a>;
    status = "okay";
    spi-max-frequency = <100000000>;
    spi-flash@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "spi-nand";
        spi-max-frequency = <100000000>;
        spi-tx-bus-width = <4>;
        spi-rx-bus-width = <4>;
        reg = <0>;
        status = "okay";
    };
};
同时还需在 board-u-boot.dtsi 文件中,将该设备标记为 u-boot,dm-pre-reloc ,不然 SPL 无法识别和使用。
&spi1 {
    u-boot,dm-pre-reloc;
    spi-flash@0 {
        u-boot,dm-pre-reloc;
    };
};