1// SPDX-License-Identifier: GPL-2.0
2/*
3 * (C) Copyright 2018 Xilinx
4 *
5 * Cadence QSPI controller DMA operations
6 */
7
8#include <clk.h>
9#include <common.h>
10#include <memalign.h>
11#include <wait_bit.h>
12#include <asm/io.h>
13#include <asm/gpio.h>
14#include <asm/cache.h>
15#include <cpu_func.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>
20
21int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
22			      const struct spi_mem_op *op)
23{
24	u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
25	u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
26
27	n_rx = op->data.nbytes;
28	rxbuf = op->data.buf.in;
29	rx_rem = n_rx % 4;
30	bytes_to_dma = n_rx - rx_rem;
31
32	if (bytes_to_dma) {
33		cadence_qspi_apb_enable_linear_mode(false);
34		reg = readl(priv->regbase + CQSPI_REG_CONFIG);
35		reg |= CQSPI_REG_CONFIG_ENBL_DMA;
36		writel(reg, priv->regbase + CQSPI_REG_CONFIG);
37
38		writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES);
39
40		writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE,
41		       priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE);
42		writel(CQSPI_DFLT_DMA_PERIPH_CFG,
43		       priv->regbase + CQSPI_REG_DMA_PERIPH_CFG);
44		writel(lower_32_bits((unsigned long)rxbuf), priv->regbase +
45		       CQSPI_DMA_DST_ADDR_REG);
46		writel(upper_32_bits((unsigned long)rxbuf), priv->regbase +
47		       CQSPI_DMA_DST_ADDR_MSB_REG);
48		writel(priv->trigger_address, priv->regbase +
49		       CQSPI_DMA_SRC_RD_ADDR_REG);
50		writel(bytes_to_dma, priv->regbase +
51		       CQSPI_DMA_DST_SIZE_REG);
52		flush_dcache_range((unsigned long)rxbuf,
53				   (unsigned long)rxbuf + bytes_to_dma);
54		writel(CQSPI_DFLT_DST_CTRL_REG_VAL,
55		       priv->regbase + CQSPI_DMA_DST_CTRL_REG);
56
57		/* Start the indirect read transfer */
58		writel(CQSPI_REG_INDIRECTRD_START, priv->regbase +
59		       CQSPI_REG_INDIRECTRD);
60		/* Wait for dma to complete transfer */
61		ret = cadence_qspi_apb_wait_for_dma_cmplt(priv);
62		if (ret)
63			return ret;
64
65		/* Clear indirect completion status */
66		writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase +
67		       CQSPI_REG_INDIRECTRD);
68		rxbuf += bytes_to_dma;
69	}
70
71	if (rx_rem) {
72		reg = readl(priv->regbase + CQSPI_REG_CONFIG);
73		reg &= ~CQSPI_REG_CONFIG_ENBL_DMA;
74		writel(reg, priv->regbase + CQSPI_REG_CONFIG);
75
76		reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
77		reg += bytes_to_dma;
78		writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS);
79
80		addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) &
81				   CQSPI_REG_SIZE_ADDRESS_MASK;
82
83		opcode = CMD_4BYTE_FAST_READ;
84		dummy_cycles = 8;
85		writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
86		       priv->regbase + CQSPI_REG_RD_INSTR);
87
88		reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
89		reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
90		reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
91			CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
92		reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
93		dummy_cycles = (readl(priv->regbase + CQSPI_REG_RD_INSTR) >>
94				CQSPI_REG_RD_INSTR_DUMMY_LSB) &
95				CQSPI_REG_RD_INSTR_DUMMY_MASK;
96		reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) <<
97			CQSPI_REG_CMDCTRL_DUMMY_LSB;
98		reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) <<
99			CQSPI_REG_CMDCTRL_RD_BYTES_LSB);
100		ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg);
101		if (ret)
102			return ret;
103
104		data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER);
105		memcpy(rxbuf, &data, rx_rem);
106	}
107
108	return 0;
109}
110
111int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv)
112{
113	u32 timeout = CQSPI_DMA_TIMEOUT;
114
115	while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) &
116		 CQSPI_DMA_DST_I_STS_DONE) && timeout--)
117		udelay(1);
118
119	if (!timeout) {
120		printf("DMA timeout\n");
121		return -ETIMEDOUT;
122	}
123
124	writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG),
125	       priv->regbase + CQSPI_DMA_DST_I_STS_REG);
126	return 0;
127}
128
129#if defined(CONFIG_DM_GPIO)
130int cadence_qspi_versal_flash_reset(struct udevice *dev)
131{
132	struct gpio_desc gpio;
133	u32 reset_gpio;
134	int ret;
135
136	/* request gpio and set direction as output set to 1 */
137	ret = gpio_request_by_name(dev, "reset-gpios", 0, &gpio,
138				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
139	if (ret) {
140		printf("%s: unable to reset ospi flash device", __func__);
141		return ret;
142	}
143
144	reset_gpio = PMIO_NODE_ID_BASE + gpio.offset;
145
146	/* Request for pin */
147	xilinx_pm_request(PM_PINCTRL_REQUEST, reset_gpio, 0, 0, 0, NULL);
148
149	/* Enable hysteresis in cmos receiver */
150	xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
151			  PM_PINCTRL_CONFIG_SCHMITT_CMOS,
152			  PM_PINCTRL_INPUT_TYPE_SCHMITT, 0, NULL);
153
154	/* Disable Tri-state */
155	xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
156			  PM_PINCTRL_CONFIG_TRI_STATE,
157			  PM_PINCTRL_TRI_STATE_DISABLE, 0, NULL);
158	udelay(1);
159
160	/* Set value 0 to pin */
161	dm_gpio_set_value(&gpio, 0);
162	udelay(1);
163
164	/* Set value 1 to pin */
165	dm_gpio_set_value(&gpio, 1);
166	udelay(1);
167
168	return 0;
169}
170#else
171int cadence_qspi_versal_flash_reset(struct udevice *dev)
172{
173	/* CRP WPROT */
174	writel(0, WPROT_CRP);
175	/* GPIO Reset */
176	writel(0, RST_GPIO);
177
178	/* disable IOU write protection */
179	writel(0, WPROT_LPD_MIO);
180
181	/* set direction as output */
182	writel((readl(BOOT_MODE_DIR) | BIT(FLASH_RESET_GPIO)),
183	       BOOT_MODE_DIR);
184
185	/* Data output enable */
186	writel((readl(BOOT_MODE_OUT) | BIT(FLASH_RESET_GPIO)),
187	       BOOT_MODE_OUT);
188
189	/* IOU SLCR write enable */
190	writel(0, WPROT_PMC_MIO);
191
192	/* set MIO as GPIO */
193	writel(0x60, MIO_PIN_12);
194
195	/* Set value 1 to pin */
196	writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
197	udelay(10);
198
199	/* Disable Tri-state */
200	writel((readl(BANK0_TRI) & ~BIT(FLASH_RESET_GPIO)), BANK0_TRI);
201	udelay(1);
202
203	/* Set value 0 to pin */
204	writel((readl(BANK0_OUTPUT) & ~BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
205	udelay(10);
206
207	/* Set value 1 to pin */
208	writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
209	udelay(10);
210
211	return 0;
212}
213#endif
214
215void cadence_qspi_apb_enable_linear_mode(bool enable)
216{
217	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
218		if (enable)
219			/* ahb read mode */
220			xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
221					  IOCTL_OSPI_MUX_SELECT,
222					  PM_OSPI_MUX_SEL_LINEAR, 0, NULL);
223		else
224			/* DMA mode */
225			xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
226					  IOCTL_OSPI_MUX_SELECT,
227					  PM_OSPI_MUX_SEL_DMA, 0, NULL);
228	} else {
229		if (enable)
230			writel(readl(VERSAL_AXI_MUX_SEL) |
231			       VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
232		else
233			writel(readl(VERSAL_AXI_MUX_SEL) &
234			       ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
235	}
236}
237