1 // SPDX-License-Identifier: GPL-2.0
3 * (C) Copyright 2018 Xilinx
5 * Cadence QSPI controller DMA operations
14 #include <asm/cache.h>
16 #include <zynqmp_firmware.h>
17 #include <asm/arch/hardware.h>
18 #include "cadence_qspi.h"
19 #include <dt-bindings/power/xlnx-versal-power.h>
21 #define CMD_4BYTE_READ 0x13
22 #define CMD_4BYTE_FAST_READ 0x0C
24 int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
25 const struct spi_mem_op *op)
27 u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
28 u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
30 n_rx = op->data.nbytes;
31 rxbuf = op->data.buf.in;
33 bytes_to_dma = n_rx - rx_rem;
36 cadence_qspi_apb_enable_linear_mode(false);
37 reg = readl(priv->regbase + CQSPI_REG_CONFIG);
38 reg |= CQSPI_REG_CONFIG_ENBL_DMA;
39 writel(reg, priv->regbase + CQSPI_REG_CONFIG);
41 writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES);
43 writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE,
44 priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE);
45 writel(CQSPI_DFLT_DMA_PERIPH_CFG,
46 priv->regbase + CQSPI_REG_DMA_PERIPH_CFG);
47 writel((unsigned long)rxbuf, priv->regbase +
48 CQSPI_DMA_DST_ADDR_REG);
49 writel(priv->trigger_address, priv->regbase +
50 CQSPI_DMA_SRC_RD_ADDR_REG);
51 writel(bytes_to_dma, priv->regbase +
52 CQSPI_DMA_DST_SIZE_REG);
53 flush_dcache_range((unsigned long)rxbuf,
54 (unsigned long)rxbuf + bytes_to_dma);
55 writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
56 priv->regbase + CQSPI_DMA_DST_CTRL_REG);
58 /* Start the indirect read transfer */
59 writel(CQSPI_REG_INDIRECTRD_START, priv->regbase +
60 CQSPI_REG_INDIRECTRD);
61 /* Wait for dma to complete transfer */
62 ret = cadence_qspi_apb_wait_for_dma_cmplt(priv);
66 /* Clear indirect completion status */
67 writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase +
68 CQSPI_REG_INDIRECTRD);
69 rxbuf += bytes_to_dma;
73 reg = readl(priv->regbase + CQSPI_REG_CONFIG);
74 reg &= ~CQSPI_REG_CONFIG_ENBL_DMA;
75 writel(reg, priv->regbase + CQSPI_REG_CONFIG);
77 reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
79 writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS);
81 addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) &
82 CQSPI_REG_SIZE_ADDRESS_MASK;
84 opcode = CMD_4BYTE_FAST_READ;
86 writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
87 priv->regbase + CQSPI_REG_RD_INSTR);
89 reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
90 reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
91 reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
92 CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
93 reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
94 dummy_cycles = (readl(priv->regbase + CQSPI_REG_RD_INSTR) >>
95 CQSPI_REG_RD_INSTR_DUMMY_LSB) &
96 CQSPI_REG_RD_INSTR_DUMMY_MASK;
97 reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) <<
98 CQSPI_REG_CMDCTRL_DUMMY_LSB;
99 reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) <<
100 CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
101 ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg);
105 data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER);
106 memcpy(rxbuf, &data, rx_rem);
112 int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv)
114 u32 timeout = CQSPI_DMA_TIMEOUT;
116 while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) &
117 CQSPI_DMA_DST_I_STS_DONE) && timeout--)
121 printf("DMA timeout\n");
125 writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG),
126 priv->regbase + CQSPI_DMA_DST_I_STS_REG);
130 #if defined(CONFIG_DM_GPIO)
131 int cadence_qspi_versal_flash_reset(struct udevice *dev)
133 #ifndef CONFIG_ARCH_VERSAL_NET
134 struct gpio_desc gpio;
138 /* request gpio and set direction as output set to 1 */
139 ret = gpio_request_by_name(dev, "reset-gpios", 0, &gpio,
140 GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
142 printf("%s: unable to reset ospi flash device", __func__);
146 reset_gpio = PMIO_NODE_ID_BASE + gpio.offset;
148 /* Request for pin */
149 xilinx_pm_request(PM_PINCTRL_REQUEST, reset_gpio, 0, 0, 0, NULL);
151 /* Enable hysteresis in cmos receiver */
152 xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
153 PM_PINCTRL_CONFIG_SCHMITT_CMOS,
154 PM_PINCTRL_INPUT_TYPE_SCHMITT, 0, NULL);
156 /* Disable Tri-state */
157 xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
158 PM_PINCTRL_CONFIG_TRI_STATE,
159 PM_PINCTRL_TRI_STATE_DISABLE, 0, NULL);
162 /* Set value 0 to pin */
163 dm_gpio_set_value(&gpio, 0);
166 /* Set value 1 to pin */
167 dm_gpio_set_value(&gpio, 1);
173 int cadence_qspi_versal_flash_reset(struct udevice *dev)
176 writel(0, WPROT_CRP);
180 /* disable IOU write protection */
181 writel(0, WPROT_LPD_MIO);
183 /* set direction as output */
184 writel((readl(BOOT_MODE_DIR) | BIT(FLASH_RESET_GPIO)),
187 /* Data output enable */
188 writel((readl(BOOT_MODE_OUT) | BIT(FLASH_RESET_GPIO)),
191 /* IOU SLCR write enable */
192 writel(0, WPROT_PMC_MIO);
194 /* set MIO as GPIO */
195 writel(0x60, MIO_PIN_12);
197 /* Set value 1 to pin */
198 writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
201 /* Disable Tri-state */
202 writel((readl(BANK0_TRI) & ~BIT(FLASH_RESET_GPIO)), BANK0_TRI);
205 /* Set value 0 to pin */
206 writel((readl(BANK0_OUTPUT) & ~BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
209 /* Set value 1 to pin */
210 writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
217 void cadence_qspi_apb_enable_linear_mode(bool enable)
219 if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE)) {
222 xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
223 IOCTL_OSPI_MUX_SELECT,
224 PM_OSPI_MUX_SEL_LINEAR, 0, NULL);
227 xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
228 IOCTL_OSPI_MUX_SELECT,
229 PM_OSPI_MUX_SEL_DMA, 0, NULL);
232 writel(readl(VERSAL_AXI_MUX_SEL) |
233 VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
235 writel(readl(VERSAL_AXI_MUX_SEL) &
236 ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);