SPI NAND 移植
SPI NAND 移植工作需要 SoC 端 SPI 模块的驱动能力以及对 SPI NAND 模块的正确配置。
准备文件
-
在下列目录中创建带相应公司标识的文件,如 foresee.c。如果该公司的文件已经存在,则略过此步,直接添加新器件支持即可。
bsp/peripheral/spinand/
一般情况下,同一个公司的 SPI NAND 的操作接口类似,创建一个文件可方便管理公司的接口配置。
-
在 bsp/peripheral/spinand/inc/spinand.h 中声明如下:
extern const struct spinand_manufacturer foresee_spinand_manufacturer;
添加驱动索引
-
检查 bsp/peripheral/spinand/spinand.c 中的 spinand_manufacturers 信息,查看新设备的厂商是否在列表之中,示例如下:
static const struct spinand_manufacturer *spinand_manufacturers[] = { &gigadevice_spinand_manufacturer, &toshiba_spinand_manufacturer, &winbond_spinand_manufacturer, &xtx_spinand_manufacturer, &foresee_spinand_manufacturer, };
spinand_manufacturer
数据结构为第一级索引,用来描述厂商的系列器件信息,是 SPI NAND 驱动的核心。 -
检查具体的设备厂商文件,具体的型号是否在列表之中,以 Fudan Micro 为例:
const struct aic_spinand_info foresee_spinand_table[] = { /*devid page_size oob_size block_per_lun pages_per_eraseblock is_die_select*/ /*F35SQA512M*/ { DEVID(0x70), PAGESIZE(2048), OOBSIZE(64), BPL(512), PPB(64), PLANENUM(1), DIE(0), "foresee 64MB: 2048+64@64@512", cmd_cfg_table }, /*F35SQA001G*/ { DEVID(0x71), PAGESIZE(2048), OOBSIZE(64), BPL(1024), PPB(64), PLANENUM(1), DIE(0), "foresee 128MB: 2048+64@64@1024", cmd_cfg_table }, /*F35SQA002G*/ { DEVID(0x72), PAGESIZE(2048), OOBSIZE(64), BPL(2048), PPB(64), PLANENUM(1), DIE(0), "foresee 256MB: 2048+64@64@2048", cmd_cfg_table }, /*FS35ND04G*/ { DEVID(0xEC), PAGESIZE(2048), OOBSIZE(64), BPL(4096), PPB(64), PLANENUM(1), DIE(0), "foresee 512MB: 2048+64@64@4096", cmd_cfg_table }, };
一般 SPI NAND 都采用标准操作接口,接口比较固定但参数可能会有差别,而参数主要由 SPINAND_INFO 描述。
配置 xxx_cmd_cfg_table
SPI NAND 的接口和操作命令基本统一,一般无需特殊处理。驱动上为了更好的兼容性,预留了部分接口方便配置使用。如无需自定义配置,可略过此步。
配置 FORESEE 参数
-
配置 F35SQA001G 相关参数:
#define SPINAND_MFR_FORESEE 0xCD /*F35SQA001G*/ { DEVID(0x71), PAGESIZE(2048), OOBSIZE(64), BPL(1024), PPB(64), PLANENUM(1), DIE(0), "foresee 128MB: 2048+64@64@1024", cmd_cfg_table },
表 1. F35SQA001G 参数描述 参数 ID
参数名字
说明
1
devid
设备 id
2
page_size
page 大小
3
oob_size
oob 大小
4
block_per_lun
一个目标节点内包含 block 个数
5
pages_per_eraseblock
一个 block 里包含 page 个数
6
is_die_select
是否需要选择目标节点,一般单 die,设置为 0 即可 rtt spinand
不需要太大容量,128MB 即可满足要求。因此一般只有一个目标节点,is_die_select 设置为 0。7
sz_description
spinand 芯片描述信息
8
cmd
特定芯片操作命令组合
-
在 BootLoader 和 RTOS 使能 Foresee 厂家的配置:
Drivers options ---> Peripheral ---> -*- SPINAND Driver library [*] Support Foresee SPI NAND
配置状态寄存器 ECC Status
按照本节描述配置状态寄存器 ECC Status,并处理函数替换。
spinand_check_ecc_status
处理函数。如果 ECC
Status 打印错误信息:-
返回如下信息,表示发现了新的坏块:
ECC status error[0x20].
-
返回如下信息,表示需要单独适配 ECC Status Bit 返回值:
ECC status error[0x30].
-
对于 0x30 Bit 返回值,厂家一般不会使用,因此也不会打印该值。如果厂家使用,则表示检测了 1 ~ 4 位 ecc 位校验纠正情况,具体需以用户手册为准。
-
以 ETRON EM73C044VCF 为例,在对应 SPINAND 厂家文件 bsp/peripheral/spinand/etron.c 里面,添加 ECC Status 处理函数:
static int em73c044vcf_ecc_get_status(struct aic_spinand *flash, u8 status) { switch (status & STATUS_ECC_MASK) { case STATUS_ECC_NO_BITFLIPS: return 0; //没有检测到 ecc 位校验纠正情况 case STATUS_ECC_HAS_1_4_BITFLIPS: return 4; //检测了 1 ~ 4 位 ecc 位校验纠正情况 case STATUS_ECC_UNCOR_ERROR: return -SPINAND_ERR_ECC; //ecc 位校验纠正失败,错误 bit 超过 4 位,需要标记坏块 case STATUS_ECC_MASK: return 4; //检测了 1 ~ 4 位 ecc 位校验纠正情况 default: break; } return -SPINAND_ERR; }
-
将功能函数地址添加到对应 SPINAND 配置上,以替换 ECC Status 通用处理函数。
{ DEVID(0x25), PAGESIZE(2048), OOBSIZE(64), BPL(1024), PPB(64), PLANENUM(1), DIE(0), "etron 128MB: 2048+64@64@1024", cmd_cfg_table, em73c044vcf_ecc_get_status},