概述
QSPI Flash驱动代码分析 (QSPI控制器初始化)
1. 函数cqspi_controller_enable()
该函数主要使能和去能QSPI控制器。QSPI配置寄存器(偏移量0x00)的bit[0]位为可读写QSPI使能位。1表示并行SPI使能;当该位设置为0时,所有SPI信号输出使能全部无效,SPI信号的所有接口被设置为输入模式。
参数enable,0为去能;1为使能。
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模式关闭特征。
static const struct cqspi_driver_platdata cdns_qspi = {
.quirks = CQSPI_DISABLE_DAC_MODE,
};
函数of_device_get_match_data()获取了quirks变量,并根据quirks变量设置核心结构的相关变量。
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表示使能。
/* 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控制器进行初始化操作。
- AHB总线地址重映射地址为0x0。
- 写全零关闭中断。
- 配置内部SDRAM的读缓冲大小。注意:写缓冲大小就是SDRAM剩余部分。
- 配置内部SDRAM在AHB总线上的物理起始地址。
- 定义间接模式的读/写水印寄存器。
- 关闭DAC模式。
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 Flash驱动代码分析 (QSPI控制器初始化)QSPI Flash驱动代码分析 (QSPI控制器初始化)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复