1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2022 Nuvoton Technology Corp.
4 * NPCM Flash Interface Unit(FIU) SPI master controller driver.
11 #include <linux/bitfield.h>
12 #include <linux/log2.h>
13 #include <linux/iopoll.h>
14 #include <power/regulator.h>
18 #define XFER_TIMEOUT 1000000
20 /* FIU UMA Configuration Register (UMA_CFG) */
21 #define UMA_CFG_RDATSIZ_MASK GENMASK(28, 24)
22 #define UMA_CFG_DBSIZ_MASK GENMASK(23, 21)
23 #define UMA_CFG_WDATSIZ_MASK GENMASK(20, 16)
24 #define UMA_CFG_ADDSIZ_MASK GENMASK(13, 11)
25 #define UMA_CFG_RDBPCK_MASK GENMASK(9, 8)
26 #define UMA_CFG_DBPCK_MASK GENMASK(7, 6)
27 #define UMA_CFG_WDBPCK_MASK GENMASK(5, 4)
28 #define UMA_CFG_ADBPCK_MASK GENMASK(3, 2)
29 #define UMA_CFG_CMBPCK_MASK GENMASK(1, 0)
30 #define UMA_CFG_CMDSIZ_SHIFT 10
32 /* FIU UMA Control and Status Register (UMA_CTS) */
33 #define UMA_CTS_SW_CS BIT(16)
34 #define UMA_CTS_EXEC_DONE BIT(0)
35 #define UMA_CTS_RDYST BIT(24)
36 #define UMA_CTS_DEV_NUM_MASK GENMASK(9, 8)
38 /* Direct Write Configuration Register */
39 #define DWR_CFG_WBURST_MASK GENMASK(25, 24)
40 #define DWR_CFG_ADDSIZ_MASK GENMASK(17, 16)
41 #define DWR_CFG_ABPCK_MASK GENMASK(11, 10)
42 #define DRW_CFG_DBPCK_MASK GENMASK(9, 8)
43 #define DRW_CFG_WRCMD 2
46 DWR_WBURST_16_BYTE = 3,
55 DWR_ABPCK_BIT_PER_CLK,
56 DWR_ABPCK_2_BIT_PER_CLK,
57 DWR_ABPCK_4_BIT_PER_CLK,
61 DWR_DBPCK_BIT_PER_CLK,
62 DWR_DBPCK_2_BIT_PER_CLK,
63 DWR_DBPCK_4_BIT_PER_CLK,
66 struct npcm_fiu_regs {
72 unsigned int uma_addr;
74 unsigned char res1[4];
83 unsigned int prt_cmd0;
84 unsigned int prt_cmd1;
85 unsigned int prt_cmd2;
86 unsigned int prt_cmd3;
87 unsigned int prt_cmd4;
88 unsigned int prt_cmd5;
89 unsigned int prt_cmd6;
90 unsigned int prt_cmd7;
91 unsigned int prt_cmd8;
92 unsigned int prt_cmd9;
93 unsigned int stuff[4];
97 struct npcm_fiu_priv {
98 struct npcm_fiu_regs *regs;
101 static int npcm_fiu_spi_set_speed(struct udevice *bus, uint speed)
106 static int npcm_fiu_spi_set_mode(struct udevice *bus, uint mode)
111 static inline void activate_cs(struct npcm_fiu_regs *regs, int cs)
113 writel(FIELD_PREP(UMA_CTS_DEV_NUM_MASK, cs), ®s->uma_cts);
116 static inline void deactivate_cs(struct npcm_fiu_regs *regs, int cs)
118 writel(FIELD_PREP(UMA_CTS_DEV_NUM_MASK, cs) | UMA_CTS_SW_CS, ®s->uma_cts);
121 static int fiu_uma_read(struct udevice *bus, u8 *buf, u32 size)
123 struct npcm_fiu_priv *priv = dev_get_priv(bus);
124 struct npcm_fiu_regs *regs = priv->regs;
130 writel(FIELD_PREP(UMA_CFG_RDATSIZ_MASK, size), ®s->uma_cfg);
132 /* Initiate the read */
133 writel(readl(®s->uma_cts) | UMA_CTS_EXEC_DONE, ®s->uma_cts);
135 /* Wait for completion */
136 ret = readl_poll_timeout(®s->uma_cts, val,
137 !(val & UMA_CTS_EXEC_DONE), XFER_TIMEOUT);
139 printf("npcm_fiu: read timeout\n");
143 /* Copy data from data registers */
145 data_reg[0] = readl(®s->uma_dr0);
147 data_reg[1] = readl(®s->uma_dr1);
148 if (size > DW_SIZE * 2)
149 data_reg[2] = readl(®s->uma_dr2);
150 if (size > DW_SIZE * 3)
151 data_reg[3] = readl(®s->uma_dr3);
152 memcpy(buf, data_reg, size);
157 static int fiu_uma_write(struct udevice *bus, const u8 *buf, u32 size)
159 struct npcm_fiu_priv *priv = dev_get_priv(bus);
160 struct npcm_fiu_regs *regs = priv->regs;
166 writel(FIELD_PREP(UMA_CFG_WDATSIZ_MASK, size), ®s->uma_cfg);
168 /* Write data to data registers */
169 memcpy(data_reg, buf, size);
171 writel(data_reg[0], ®s->uma_dw0);
173 writel(data_reg[1], ®s->uma_dw1);
174 if (size > DW_SIZE * 2)
175 writel(data_reg[2], ®s->uma_dw2);
176 if (size > DW_SIZE * 3)
177 writel(data_reg[3], ®s->uma_dw3);
179 /* Initiate the transaction */
180 writel(readl(®s->uma_cts) | UMA_CTS_EXEC_DONE, ®s->uma_cts);
182 /* Wait for completion */
183 ret = readl_poll_timeout(®s->uma_cts, val,
184 !(val & UMA_CTS_EXEC_DONE), XFER_TIMEOUT);
186 printf("npcm_fiu: write timeout\n");
191 static int npcm_fiu_spi_xfer(struct udevice *dev, unsigned int bitlen,
192 const void *dout, void *din, unsigned long flags)
194 struct udevice *bus = dev->parent;
195 struct npcm_fiu_priv *priv = dev_get_priv(bus);
196 struct npcm_fiu_regs *regs = priv->regs;
197 struct dm_spi_slave_plat *slave_plat =
198 dev_get_parent_plat(dev);
201 int bytes = bitlen / 8;
205 if (flags & SPI_XFER_BEGIN)
206 activate_cs(regs, slave_plat->cs);
209 len = (bytes > CHUNK_SIZE) ? CHUNK_SIZE : bytes;
211 ret = fiu_uma_write(bus, tx, len);
216 ret = fiu_uma_read(bus, rx, len);
224 if (flags & SPI_XFER_END)
225 deactivate_cs(regs, slave_plat->cs);
230 static int npcm_fiu_uma_operation(struct npcm_fiu_priv *priv, const struct spi_mem_op *op,
231 u32 addr, const u8 *tx, u8 *rx, u32 nbytes, bool started)
233 struct npcm_fiu_regs *regs = priv->regs;
234 u32 uma_cfg = 0, val;
238 debug("fiu_uma: opcode 0x%x, dir %d, addr 0x%x, %d bytes\n",
239 op->cmd.opcode, op->data.dir, addr, nbytes);
240 debug(" buswidth cmd:%d, addr:%d, dummy:%d, data:%d\n",
241 op->cmd.buswidth, op->addr.buswidth, op->dummy.buswidth,
243 debug(" size cmd:%d, addr:%d, dummy:%d, data:%d\n",
244 1, op->addr.nbytes, op->dummy.nbytes, op->data.nbytes);
245 debug(" tx %p, rx %p\n", tx, rx);
248 /* Send cmd/addr in the begin of an transaction */
249 writel(op->cmd.opcode, ®s->uma_cmd);
251 uma_cfg |= FIELD_PREP(UMA_CFG_CMBPCK_MASK, ilog2(op->cmd.buswidth)) |
252 (1 << UMA_CFG_CMDSIZ_SHIFT);
253 /* Configure addr bytes */
254 if (op->addr.nbytes) {
255 uma_cfg |= FIELD_PREP(UMA_CFG_ADBPCK_MASK, ilog2(op->addr.buswidth)) |
256 FIELD_PREP(UMA_CFG_ADDSIZ_MASK, op->addr.nbytes);
257 writel(addr, ®s->uma_addr);
259 /* Configure dummy bytes */
260 if (op->dummy.nbytes)
261 uma_cfg |= FIELD_PREP(UMA_CFG_DBPCK_MASK, ilog2(op->dummy.buswidth)) |
262 FIELD_PREP(UMA_CFG_DBSIZ_MASK, op->dummy.nbytes);
264 /* Set data bus width and data size */
265 if (op->data.dir == SPI_MEM_DATA_IN && nbytes)
266 uma_cfg |= FIELD_PREP(UMA_CFG_RDBPCK_MASK, ilog2(op->data.buswidth)) |
267 FIELD_PREP(UMA_CFG_RDATSIZ_MASK, nbytes);
268 else if (op->data.dir == SPI_MEM_DATA_OUT && nbytes)
269 uma_cfg |= FIELD_PREP(UMA_CFG_WDBPCK_MASK, ilog2(op->data.buswidth)) |
270 FIELD_PREP(UMA_CFG_WDATSIZ_MASK, nbytes);
271 writel(uma_cfg, ®s->uma_cfg);
273 if (op->data.dir == SPI_MEM_DATA_OUT && nbytes) {
274 memcpy(data_reg, tx, nbytes);
277 writel(data_reg[0], ®s->uma_dw0);
278 if (nbytes > DW_SIZE)
279 writel(data_reg[1], ®s->uma_dw1);
280 if (nbytes > DW_SIZE * 2)
281 writel(data_reg[2], ®s->uma_dw2);
282 if (nbytes > DW_SIZE * 3)
283 writel(data_reg[3], ®s->uma_dw3);
285 /* Initiate the transaction */
286 writel(readl(®s->uma_cts) | UMA_CTS_EXEC_DONE, ®s->uma_cts);
288 /* Wait for completion */
289 ret = readl_poll_timeout(®s->uma_cts, val,
290 !(val & UMA_CTS_EXEC_DONE), XFER_TIMEOUT);
292 printf("npcm_fiu: UMA op timeout\n");
296 if (op->data.dir == SPI_MEM_DATA_IN && nbytes) {
298 data_reg[0] = readl(®s->uma_dr0);
299 if (nbytes > DW_SIZE)
300 data_reg[1] = readl(®s->uma_dr1);
301 if (nbytes > DW_SIZE * 2)
302 data_reg[2] = readl(®s->uma_dr2);
303 if (nbytes > DW_SIZE * 3)
304 data_reg[3] = readl(®s->uma_dr3);
306 memcpy(rx, data_reg, nbytes);
312 static int npcm_fiu_exec_op(struct spi_slave *slave,
313 const struct spi_mem_op *op)
315 struct udevice *bus = slave->dev->parent;
316 struct npcm_fiu_priv *priv = dev_get_priv(bus);
317 struct npcm_fiu_regs *regs = priv->regs;
318 struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(slave->dev);
319 u32 bytes, len, addr;
322 bool started = false;
325 bytes = op->data.nbytes;
326 addr = (u32)op->addr.val;
328 activate_cs(regs, slave_plat->cs);
329 ret = npcm_fiu_uma_operation(priv, op, addr, NULL, NULL, 0, false);
330 deactivate_cs(regs, slave_plat->cs);
334 tx = op->data.buf.out;
335 rx = op->data.buf.in;
337 * Use SW-control CS for write to extend the transaction and
338 * keep the Write Enable state.
339 * Use HW-control CS for read to avoid clock and timing issues.
341 if (op->data.dir == SPI_MEM_DATA_OUT)
342 activate_cs(regs, slave_plat->cs);
344 writel(FIELD_PREP(UMA_CTS_DEV_NUM_MASK, slave_plat->cs) | UMA_CTS_SW_CS,
347 len = (bytes > CHUNK_SIZE) ? CHUNK_SIZE : bytes;
348 ret = npcm_fiu_uma_operation(priv, op, addr, tx, rx, len, started);
352 /* CS is kept low for uma write, extend the transaction */
353 if (op->data.dir == SPI_MEM_DATA_OUT)
363 if (op->data.dir == SPI_MEM_DATA_OUT)
364 deactivate_cs(regs, slave_plat->cs);
369 static int npcm_fiu_spi_probe(struct udevice *bus)
371 struct npcm_fiu_priv *priv = dev_get_priv(bus);
372 struct udevice *vqspi_supply;
375 priv->regs = (struct npcm_fiu_regs *)dev_read_addr_ptr(bus);
377 if (IS_ENABLED(CONFIG_DM_REGULATOR)) {
378 device_get_supply_regulator(bus, "vqspi-supply", &vqspi_supply);
379 vqspi_uv = dev_read_u32_default(bus, "vqspi-microvolt", 0);
381 if (vqspi_supply && vqspi_uv)
382 regulator_set_value(vqspi_supply, vqspi_uv);
388 static int npcm_fiu_spi_bind(struct udevice *bus)
390 struct npcm_fiu_regs *regs;
392 if (dev_read_bool(bus, "nuvoton,spix-mode")) {
393 regs = dev_read_addr_ptr(bus);
397 /* Setup direct write cfg for SPIX */
398 writel(FIELD_PREP(DWR_CFG_WBURST_MASK, DWR_WBURST_16_BYTE) |
399 FIELD_PREP(DWR_CFG_ADDSIZ_MASK, DWR_ADDSIZ_24_BIT) |
400 FIELD_PREP(DWR_CFG_ABPCK_MASK, DWR_ABPCK_4_BIT_PER_CLK) |
401 FIELD_PREP(DRW_CFG_DBPCK_MASK, DWR_DBPCK_4_BIT_PER_CLK) |
402 DRW_CFG_WRCMD, ®s->dwr_cfg);
408 static const struct spi_controller_mem_ops npcm_fiu_mem_ops = {
409 .exec_op = npcm_fiu_exec_op,
412 static const struct dm_spi_ops npcm_fiu_spi_ops = {
413 .xfer = npcm_fiu_spi_xfer,
414 .set_speed = npcm_fiu_spi_set_speed,
415 .set_mode = npcm_fiu_spi_set_mode,
416 .mem_ops = &npcm_fiu_mem_ops,
419 static const struct udevice_id npcm_fiu_spi_ids[] = {
420 { .compatible = "nuvoton,npcm845-fiu" },
421 { .compatible = "nuvoton,npcm750-fiu" },
425 U_BOOT_DRIVER(npcm_fiu_spi) = {
426 .name = "npcm_fiu_spi",
428 .of_match = npcm_fiu_spi_ids,
429 .ops = &npcm_fiu_spi_ops,
430 .priv_auto = sizeof(struct npcm_fiu_priv),
431 .probe = npcm_fiu_spi_probe,
432 .bind = npcm_fiu_spi_bind,