spi: zynqmp_gqspi: Fix issue of reading more than 32bits length
[platform/kernel/u-boot.git] / drivers / spi / cadence_ospi_versal.c
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
21 #define CMD_4BYTE_READ  0x13
22 #define CMD_4BYTE_FAST_READ  0x0C
23
24 int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv,
25                               const struct spi_mem_op *op)
26 {
27         u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data;
28         u8 opcode, addr_bytes, *rxbuf, dummy_cycles;
29
30         n_rx = op->data.nbytes;
31         rxbuf = op->data.buf.in;
32         rx_rem = n_rx % 4;
33         bytes_to_dma = n_rx - rx_rem;
34
35         if (bytes_to_dma) {
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);
40
41                 writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES);
42
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);
57
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);
63                 if (ret)
64                         return ret;
65
66                 /* Clear indirect completion status */
67                 writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase +
68                        CQSPI_REG_INDIRECTRD);
69                 rxbuf += bytes_to_dma;
70         }
71
72         if (rx_rem) {
73                 reg = readl(priv->regbase + CQSPI_REG_CONFIG);
74                 reg &= ~CQSPI_REG_CONFIG_ENBL_DMA;
75                 writel(reg, priv->regbase + CQSPI_REG_CONFIG);
76
77                 reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
78                 reg += bytes_to_dma;
79                 writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS);
80
81                 addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) &
82                                    CQSPI_REG_SIZE_ADDRESS_MASK;
83
84                 opcode = CMD_4BYTE_FAST_READ;
85                 dummy_cycles = 8;
86                 writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode,
87                        priv->regbase + CQSPI_REG_RD_INSTR);
88
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);
102                 if (ret)
103                         return ret;
104
105                 data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER);
106                 memcpy(rxbuf, &data, rx_rem);
107         }
108
109         return 0;
110 }
111
112 int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv)
113 {
114         u32 timeout = CQSPI_DMA_TIMEOUT;
115
116         while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) &
117                  CQSPI_DMA_DST_I_STS_DONE) && timeout--)
118                 udelay(1);
119
120         if (!timeout) {
121                 printf("DMA timeout\n");
122                 return -ETIMEDOUT;
123         }
124
125         writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG),
126                priv->regbase + CQSPI_DMA_DST_I_STS_REG);
127         return 0;
128 }
129
130 #if defined(CONFIG_DM_GPIO)
131 int cadence_qspi_versal_flash_reset(struct udevice *dev)
132 {
133         struct gpio_desc gpio;
134         u32 reset_gpio;
135         int ret;
136
137         /* request gpio and set direction as output set to 1 */
138         ret = gpio_request_by_name(dev, "reset-gpios", 0, &gpio,
139                                    GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
140         if (ret) {
141                 printf("%s: unable to reset ospi flash device", __func__);
142                 return ret;
143         }
144
145         reset_gpio = PMIO_NODE_ID_BASE + gpio.offset;
146
147         /* Request for pin */
148         xilinx_pm_request(PM_PINCTRL_REQUEST, reset_gpio, 0, 0, 0, NULL);
149
150         /* Enable hysteresis in cmos receiver */
151         xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
152                           PM_PINCTRL_CONFIG_SCHMITT_CMOS,
153                           PM_PINCTRL_INPUT_TYPE_SCHMITT, 0, NULL);
154
155         /* Disable Tri-state */
156         xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, reset_gpio,
157                           PM_PINCTRL_CONFIG_TRI_STATE,
158                           PM_PINCTRL_TRI_STATE_DISABLE, 0, NULL);
159         udelay(1);
160
161         /* Set value 0 to pin */
162         dm_gpio_set_value(&gpio, 0);
163         udelay(1);
164
165         /* Set value 1 to pin */
166         dm_gpio_set_value(&gpio, 1);
167         udelay(1);
168
169         return 0;
170 }
171 #else
172 int cadence_qspi_versal_flash_reset(struct udevice *dev)
173 {
174         /* CRP WPROT */
175         writel(0, WPROT_CRP);
176         /* GPIO Reset */
177         writel(0, RST_GPIO);
178
179         /* disable IOU write protection */
180         writel(0, WPROT_LPD_MIO);
181
182         /* set direction as output */
183         writel((readl(BOOT_MODE_DIR) | BIT(FLASH_RESET_GPIO)),
184                BOOT_MODE_POR_0);
185
186         /* Data output enable */
187         writel((readl(BOOT_MODE_OUT) | BIT(FLASH_RESET_GPIO)),
188                BOOT_MODE_POR_1);
189
190         /* IOU SLCR write enable */
191         writel(0, WPROT_PMC_MIO);
192
193         /* set MIO as GPIO */
194         writel(0x60, MIO_PIN_12);
195
196         /* Set value 1 to pin */
197         writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
198         udelay(10);
199
200         /* Disable Tri-state */
201         writel((readl(BANK0_TRI) & ~BIT(FLASH_RESET_GPIO)), BANK0_TRI);
202         udelay(1);
203
204         /* Set value 0 to pin */
205         writel((readl(BANK0_OUTPUT) & ~BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
206         udelay(10);
207
208         /* Set value 1 to pin */
209         writel((readl(BANK0_OUTPUT) | BIT(FLASH_RESET_GPIO)), BANK0_OUTPUT);
210         udelay(10);
211
212         return 0;
213 }
214 #endif
215
216 void cadence_qspi_apb_enable_linear_mode(bool enable)
217 {
218         if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE)) {
219                 if (enable)
220                         /* ahb read mode */
221                         xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
222                                           IOCTL_OSPI_MUX_SELECT,
223                                           PM_OSPI_MUX_SEL_LINEAR, 0, NULL);
224                 else
225                         /* DMA mode */
226                         xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
227                                           IOCTL_OSPI_MUX_SELECT,
228                                           PM_OSPI_MUX_SEL_DMA, 0, NULL);
229         } else {
230                 if (enable)
231                         writel(readl(VERSAL_AXI_MUX_SEL) |
232                                VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
233                 else
234                         writel(readl(VERSAL_AXI_MUX_SEL) &
235                                ~VERSAL_OSPI_LINEAR_MODE, VERSAL_AXI_MUX_SEL);
236         }
237 }