我是靠谱客的博主 顺心万宝路,这篇文章主要介绍QSPI Flash驱动代码分析 (QSPI控制器初始化)QSPI Flash驱动代码分析 (QSPI控制器初始化),现在分享给大家,希望可以做个参考。

QSPI Flash驱动代码分析 (QSPI控制器初始化)

1. 函数cqspi_controller_enable()

        该函数主要使能和去能QSPI控制器。QSPI配置寄存器(偏移量0x00)的bit[0]位为可读写QSPI使能位。1表示并行SPI使能;当该位设置为0时,所有SPI信号输出使能全部无效,SPI信号的所有接口被设置为输入模式。

        参数enable,0为去能;1为使能。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable) { void __iomem *reg_base = cqspi->iobase; unsigned int reg; reg = readl(reg_base + CQSPI_REG_CONFIG); if (enable) reg |= CQSPI_REG_CONFIG_ENABLE_MASK; else reg &= ~CQSPI_REG_CONFIG_ENABLE_MASK; writel(reg, reg_base + CQSPI_REG_CONFIG); }

        QSPI控制器的初始化一开始需要关闭QSPI控制器,初始化结束后将QSPI使能。

2. 当前驱动关闭了直接访问模式

        quirk是驱动特征调整标志变量,quirks仅仅定义了DAC模式关闭特征。

复制代码
1
2
3
static const struct cqspi_driver_platdata cdns_qspi = { .quirks = CQSPI_DISABLE_DAC_MODE, };

        函数of_device_get_match_data()获取了quirks变量,并根据quirks变量设置核心结构的相关变量。

复制代码
1
2
3
4
5
6
7
8
9
10
ddata = of_device_get_match_data(dev); if (ddata) { if (ddata->quirks & CQSPI_NEEDS_WR_DELAY) cqspi->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, cqspi->master_ref_clk_hz); if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL) master->mode_bits |= SPI_RX_OCTAL | SPI_TX_OCTAL; if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) cqspi->use_direct_mode = true; }

        其中,根据当前quirks变量,cqspi->use_direct_mode 并没有被设置为true。

        QSPI配置寄存器的bit[7]是可读写的DAC使能,0表示关闭(如果当前正在传输数据,当前传输结束后再关闭);1表示使能。

复制代码
1
2
3
4
5
6
/* Disable direct access controller */ if (!cqspi->use_direct_mode) { reg = readl(cqspi->iobase + CQSPI_REG_CONFIG); reg &= ~CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL; writel(reg, cqspi->iobase + CQSPI_REG_CONFIG); }

3. 函数cqspi_controller_init()

        驱动程序首次对qspi控制器进行初始化操作。

  1. AHB总线地址重映射地址为0x0。
  2. 写全零关闭中断。
  3. 配置内部SDRAM的读缓冲大小。注意:写缓冲大小就是SDRAM剩余部分。
  4. 配置内部SDRAM在AHB总线上的物理起始地址。
  5. 定义间接模式的读/写水印寄存器。
  6. 关闭DAC模式。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static void cqspi_controller_init(struct cqspi_st *cqspi) { u32 reg; cqspi_controller_enable(cqspi, 0); /* Configure the remap address register, no remap */ writel(0, cqspi->iobase + CQSPI_REG_REMAP); /* Disable all interrupts. */ writel(0, cqspi->iobase + CQSPI_REG_IRQMASK); /* Configure the SRAM split to 1:1 . */ writel(cqspi->fifo_depth / 2, cqspi->iobase + CQSPI_REG_SRAMPARTITION); /* Load indirect trigger address. */ writel(cqspi->trigger_address, cqspi->iobase + CQSPI_REG_INDIRECTTRIGGER); /* Program read watermark -- 1/2 of the FIFO. */ writel(cqspi->fifo_depth * cqspi->fifo_width / 2, cqspi->iobase + CQSPI_REG_INDIRECTRDWATERMARK); /* Program write watermark -- 1/8 of the FIFO. */ writel(cqspi->fifo_depth * cqspi->fifo_width / 8, cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK); /* Disable direct access controller */ if (!cqspi->use_direct_mode) { reg = readl(cqspi->iobase + CQSPI_REG_CONFIG); reg &= ~CQSPI_REG_CONFIG_ENB_DIR_ACC_CTRL; writel(reg, cqspi->iobase + CQSPI_REG_CONFIG); } cqspi_controller_enable(cqspi, 1); }

注意:

设备树需要定义"cdns,fifo-depth" 、"cdns,fifo-width" 和"cdns,trigger-address"三个量,这直接定义了cqspi->fifo_depth/fifo_width/trigger_address。

最后

以上就是顺心万宝路最近收集整理的关于QSPI Flash驱动代码分析 (QSPI控制器初始化)QSPI Flash驱动代码分析 (QSPI控制器初始化)的全部内容,更多相关QSPI内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(112)

评论列表共有 0 条评论

立即
投稿
返回
顶部