10.1.4. 适配说明

10.1.4.1. 相关文件

  • bsp/zx/drv_bare/spinor/aic_flash_xip_def.c //关于 NOR Flash 的 XIP 配置信息

  • bsp/zx/include/drv_bare/aic_flash_xip_def.h //关于 aic_flash_xip_def 相关结构体和接口声明

  • bsp/zx/include/hal/hal_qspi.h //关于 QSPI 控制器相关接口头文件

10.1.4.2. 相关结构体

struct xip_device {
    const char *name;
    u32 flash_id;
    u32 proto_support;
    struct qspi_xip_burst_cfg burst_cfg;
    struct qspi_xip_read_cfg read_cfg;
};
struct qspi_xip_burst_cfg {
    u8 cmd_set_burst;   /* CMD to set burst with wrap or linear, 77h or C0h */
    u8 cmd_dummy_byte;  /* Dummy byte fot set burst command */
    u8 cmd_bits_width;  /* When CMD is C0h, bits width is needed to set */
    u8 wrap_en;         /* 00: disable, 01 wrap with fixed len, 02 wrap with auto len */
    struct qspi_xip_wrap_bits wrap;
};
struct qspi_xip_wrap_bits {
    /*
    * When config SPI controller select to use fixed wrap length, should
    * set the selected wrap bits value to it.
    */
    u8 fixed_len;
    /*
    * Wrap bits value to disable wrap length
    */
    u8 disable;
    /*
    * Wrap bits value to select wrap length 64bytes
    */
    u8 auto_wl64;
    /*
    * Wrap bits value to select wrap length 32bytes
    */
    u8 auto_wl32;
    /*
    * Wrap bits value to select wrap length 16bytes
    */
    u8 auto_wl16;
    /*
    * Wrap bits value to select wrap length 8bytes
    */
    u8 auto_wl8;
};
struct qspi_xip_read_cfg {
    /*
    * QIO or QPI read command value
    */
    u8 read_cmd;
    /*
    * Read command's dummy byte.
    * User should check SPI NOR datasheet and set it.
    */
    u8 dummy_byte;
    u8 addr_mode; /* 0: 3byte address, 1: 4byte address */
    /*
    * When CPU cache is disabled, user can select to enable read command bypass mode
    */
    u8 read_cmd_bypass_en;
    struct qspi_xip_read_cmd_mode_byte mode;
};
struct qspi_xip_read_cmd_mode_byte {
    /*
    * Mode byte code value to set read command bypass mode,
    * User should check SPI NOR datasheet and set it.
    */
    u8 bypass;
    /*
    * Mode byte code value to set read command normal mode,
    * User should check SPI NOR datasheet and set it.
    */
    u8 normal;
};

10.1.4.3. 适配方法

XIP 相关的 NOR Flash 信息配置在 bsp/zx/drv_bare/spinor/aic_flash_xip_def.c 中, 主要在 struct xip_device 添加节点信息,每个节点代表一颗 NOR Flash 。

ZB25VQ128 为例:

{
    .name = "ZB25VQ128", // verify ok.
    .flash_id = 0X5E4018,
    .proto_support = CMD_PROTO_QIO|CMD_PROTO_CACHE_EN|CMD_PROTO_CACHE_DIS,
    .burst_cfg = {
            .cmd_set_burst = 0x77,
            .cmd_dummy_byte = 3,
            .cmd_bits_width = XIP_C0_BITS_WIDTH_4,
            .wrap_en = XIP_BURST_WRAPPED_WITH_FIXED_LEN,
            .wrap = {
                    .fixed_len = 0x40,
                    .disable = 0x10,
                    .auto_wl64 = 0x60,
                    .auto_wl32 = 0x40,
                    .auto_wl16 = 0x20,
                    .auto_wl8 = 0x00,
            },
    },
    .read_cfg = {
            .read_cmd = 0xEB,
            .dummy_byte = 2,
            .addr_mode = SPINOR_ADDR_MODE_3BYTE,
            .read_cmd_bypass_en = 0,
            .mode = {
                    .bypass = 0xf0,
                    .normal = 0x00,
            },
    },
}, //.name = "ZB25VQ128",

.flash_id = 0X5E4018:

一般地,读取设备 ID 都是通过 SPI 模式,根据手册说明,ZB25VQ128 ID 应该为 0x5E4018

../../../_images/flash_id.png

图 10.3 Flash ID

.burst_cfg:

struct qspi_xip_burst_cfg 需要填充 Set Burst with Wrap 指令配置,根据手册可知, .cmd_set_burst = 0x77 .wrap_en = XIP_BURST_WRAPPED_WITH_FIXED_LEN 使能即使用 struct qspi_xip_wrap_bits.fixed_len 配置 其中 .fixed_len = 0x40 意为 bit6 = 1, bit5=0 , 即 0x40.

注意 .cmd_dummy_byte 是以 Byte 为单位,手册中描述需要 24 Dummy Bits,即 3 Bytes。

../../../_images/burst_cfg.png

图 10.4 Burst CFG

.read_cfg =:

struct qspi_xip_read_cfg 是填充 Fast Read Quad I/O指令配置,从 Set Burst with Wrap 指令的描述可知, The Set Burst with Wrap (77h) command is used in conjunction with ― Fast Read Quad I/O commands to access a fixed length and alignment of 8/16/32/64-bytes of data.

10.1.4.4. 注意事项

10.1.4.4.1. Cache 关闭,QIO/QPI 模式

10.1.4.4.1.1. 要点

QIO:

  • CPU 只发 Linear 访问

  • Read Command Bypass 可以使能

  • SPINOR 需要使能 QE Bit

QPI:

  • CPU 只发 Linear 访问

  • Read Command Bypass 可以使能

  • SPINOR 需要使能 QE Bit

  • SPINOR 需要进入 QPI 模式

10.1.4.4.1.2. 为什么 Cache Enable 时,必须使能 Wrap

CPU Cache 使能时,CPU 发起的访问可能是 Wrap burst,如果 SPI 控制器的 Wrap enable 没有使能, 则 SPI 控制器的 XIP 模块不会发送设置 SPINOR Wrap 模式的命令。 结果会导致 CPU 的访问类型与 SPINOR 返回数据的方式不匹配,读取数据出错。

10.1.4.4.2. Cache 使能,QIO/QPI 模式

10.1.4.4.2.1. 要点

QIO:

  • SPI 控制器的 Wrap burst 必须使能

  • Read Command Bypass 不可以使能

  • CPU 可能发 Linear/Wrap burst 访问

  • SPINOR 需要使能 QE Bit

QPI:

  • SPI 控制器的 Wrap burst 必须使能

  • Read Command Bypass 不可以使能

  • CPU 可能发 Linear/Wrap burst 访问

  • SPINOR 需要使能 QE Bit

  • SPINOR 需要进入 QPI 模式

10.1.4.4.2.2. 为什么 Cache Enable 时,不可以使能 Read Command Bypass

CPU Cache 使能时,CPU 发起的访问可能是 Linear 访问,也可能是 Wrap burst 访问,SPI XIP 控制器需要根据接收到的 CPU 访问类型,发送命令对 SPINOR 进行切换。

Cache 使能时,同时使能 Read Command Bypass 会导致上述的切换失败。

具体场景如下:

  1. CPU 进行 Linear 访问时,设置了 Read Command Bypass

  2. CPU 切换到了 Wrap burst 访问

  3. 此时 SPI XIP 模块需要发送切换命令到 SPINOR

  4. 问题:SPINOR 还在 Read Command ByPass 模式下,需要退出该模式才能接收命令,因此切换命令发送会失败

  5. CPU Wrap burst 访问也会跟着失败