1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2022 Jonathan Neuschäfer
5 #include <linux/mfd/syscon.h>
6 #include <linux/mod_devicetable.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10 #include <linux/spi/spi-mem.h>
13 #define FIU_BURST_BFG 0x01
14 #define FIU_RESP_CFG 0x02
15 #define FIU_CFBB_PROT 0x03
16 #define FIU_FWIN1_LOW 0x04
17 #define FIU_FWIN1_HIGH 0x06
18 #define FIU_FWIN2_LOW 0x08
19 #define FIU_FWIN2_HIGH 0x0a
20 #define FIU_FWIN3_LOW 0x0c
21 #define FIU_FWIN3_HIGH 0x0e
22 #define FIU_PROT_LOCK 0x10
23 #define FIU_PROT_CLEAR 0x11
24 #define FIU_SPI_FL_CFG 0x14
25 #define FIU_UMA_CODE 0x16
26 #define FIU_UMA_AB0 0x17
27 #define FIU_UMA_AB1 0x18
28 #define FIU_UMA_AB2 0x19
29 #define FIU_UMA_DB0 0x1a
30 #define FIU_UMA_DB1 0x1b
31 #define FIU_UMA_DB2 0x1c
32 #define FIU_UMA_DB3 0x1d
33 #define FIU_UMA_CTS 0x1e
34 #define FIU_UMA_ECTS 0x1f
36 #define FIU_BURST_CFG_R16 3
38 #define FIU_UMA_CTS_D_SIZE(x) (x)
39 #define FIU_UMA_CTS_A_SIZE BIT(3)
40 #define FIU_UMA_CTS_WR BIT(4)
41 #define FIU_UMA_CTS_CS(x) ((x) << 5)
42 #define FIU_UMA_CTS_EXEC_DONE BIT(7)
44 #define SHM_FLASH_SIZE 0x02
45 #define SHM_FLASH_SIZE_STALL_HOST BIT(6)
48 * I observed a typical wait time of 16 iterations for a UMA transfer to
49 * finish, so this should be a safe limit.
51 #define UMA_WAIT_ITERATIONS 100
53 /* The memory-mapped view of flash is 16 MiB long */
54 #define MAX_MEMORY_SIZE_PER_CS (16 << 20)
55 #define MAX_MEMORY_SIZE_TOTAL (4 * MAX_MEMORY_SIZE_PER_CS)
63 struct regmap
*shm_regmap
;
66 static void wpcm_fiu_set_opcode(struct wpcm_fiu_spi
*fiu
, u8 opcode
)
68 writeb(opcode
, fiu
->regs
+ FIU_UMA_CODE
);
71 static void wpcm_fiu_set_addr(struct wpcm_fiu_spi
*fiu
, u32 addr
)
73 writeb((addr
>> 0) & 0xff, fiu
->regs
+ FIU_UMA_AB0
);
74 writeb((addr
>> 8) & 0xff, fiu
->regs
+ FIU_UMA_AB1
);
75 writeb((addr
>> 16) & 0xff, fiu
->regs
+ FIU_UMA_AB2
);
78 static void wpcm_fiu_set_data(struct wpcm_fiu_spi
*fiu
, const u8
*data
, unsigned int nbytes
)
82 for (i
= 0; i
< nbytes
; i
++)
83 writeb(data
[i
], fiu
->regs
+ FIU_UMA_DB0
+ i
);
86 static void wpcm_fiu_get_data(struct wpcm_fiu_spi
*fiu
, u8
*data
, unsigned int nbytes
)
90 for (i
= 0; i
< nbytes
; i
++)
91 data
[i
] = readb(fiu
->regs
+ FIU_UMA_DB0
+ i
);
95 * Perform a UMA (User Mode Access) operation, i.e. a software-controlled SPI transfer.
97 static int wpcm_fiu_do_uma(struct wpcm_fiu_spi
*fiu
, unsigned int cs
,
98 bool use_addr
, bool write
, int data_bytes
)
101 u8 cts
= FIU_UMA_CTS_EXEC_DONE
| FIU_UMA_CTS_CS(cs
);
104 cts
|= FIU_UMA_CTS_A_SIZE
;
106 cts
|= FIU_UMA_CTS_WR
;
107 cts
|= FIU_UMA_CTS_D_SIZE(data_bytes
);
109 writeb(cts
, fiu
->regs
+ FIU_UMA_CTS
);
111 for (i
= 0; i
< UMA_WAIT_ITERATIONS
; i
++)
112 if (!(readb(fiu
->regs
+ FIU_UMA_CTS
) & FIU_UMA_CTS_EXEC_DONE
))
115 dev_info(fiu
->dev
, "UMA transfer has not finished in %d iterations\n", UMA_WAIT_ITERATIONS
);
119 static void wpcm_fiu_ects_assert(struct wpcm_fiu_spi
*fiu
, unsigned int cs
)
121 u8 ects
= readb(fiu
->regs
+ FIU_UMA_ECTS
);
124 writeb(ects
, fiu
->regs
+ FIU_UMA_ECTS
);
127 static void wpcm_fiu_ects_deassert(struct wpcm_fiu_spi
*fiu
, unsigned int cs
)
129 u8 ects
= readb(fiu
->regs
+ FIU_UMA_ECTS
);
132 writeb(ects
, fiu
->regs
+ FIU_UMA_ECTS
);
135 struct wpcm_fiu_op_shape
{
136 bool (*match
)(const struct spi_mem_op
*op
);
137 int (*exec
)(struct spi_mem
*mem
, const struct spi_mem_op
*op
);
140 static bool wpcm_fiu_normal_match(const struct spi_mem_op
*op
)
142 // Opcode 0x0b (FAST READ) is treated differently in hardware
143 if (op
->cmd
.opcode
== 0x0b)
146 return (op
->addr
.nbytes
== 0 || op
->addr
.nbytes
== 3) &&
147 op
->dummy
.nbytes
== 0 && op
->data
.nbytes
<= 4;
150 static int wpcm_fiu_normal_exec(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
152 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(mem
->spi
->controller
);
155 wpcm_fiu_set_opcode(fiu
, op
->cmd
.opcode
);
156 wpcm_fiu_set_addr(fiu
, op
->addr
.val
);
157 if (op
->data
.dir
== SPI_MEM_DATA_OUT
)
158 wpcm_fiu_set_data(fiu
, op
->data
.buf
.out
, op
->data
.nbytes
);
160 ret
= wpcm_fiu_do_uma(fiu
, spi_get_chipselect(mem
->spi
, 0), op
->addr
.nbytes
== 3,
161 op
->data
.dir
== SPI_MEM_DATA_OUT
, op
->data
.nbytes
);
163 if (op
->data
.dir
== SPI_MEM_DATA_IN
)
164 wpcm_fiu_get_data(fiu
, op
->data
.buf
.in
, op
->data
.nbytes
);
169 static bool wpcm_fiu_fast_read_match(const struct spi_mem_op
*op
)
171 return op
->cmd
.opcode
== 0x0b && op
->addr
.nbytes
== 3 &&
172 op
->dummy
.nbytes
== 1 &&
173 op
->data
.nbytes
>= 1 && op
->data
.nbytes
<= 4 &&
174 op
->data
.dir
== SPI_MEM_DATA_IN
;
177 static int wpcm_fiu_fast_read_exec(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
185 * Flash view: [ C A A A A D D D D]
186 * bytes: 13 aa bb cc dd -> 5a a5 f0 0f
187 * FIU's view: [ C A A A][ C D D D D]
188 * FIU mode: [ read/write][ read ]
190 static bool wpcm_fiu_4ba_match(const struct spi_mem_op
*op
)
192 return op
->addr
.nbytes
== 4 && op
->dummy
.nbytes
== 0 && op
->data
.nbytes
<= 4;
195 static int wpcm_fiu_4ba_exec(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
197 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(mem
->spi
->controller
);
198 int cs
= spi_get_chipselect(mem
->spi
, 0);
200 wpcm_fiu_ects_assert(fiu
, cs
);
202 wpcm_fiu_set_opcode(fiu
, op
->cmd
.opcode
);
203 wpcm_fiu_set_addr(fiu
, op
->addr
.val
>> 8);
204 wpcm_fiu_do_uma(fiu
, cs
, true, false, 0);
206 wpcm_fiu_set_opcode(fiu
, op
->addr
.val
& 0xff);
207 wpcm_fiu_set_addr(fiu
, 0);
208 if (op
->data
.dir
== SPI_MEM_DATA_OUT
)
209 wpcm_fiu_set_data(fiu
, op
->data
.buf
.out
, op
->data
.nbytes
);
210 wpcm_fiu_do_uma(fiu
, cs
, false, op
->data
.dir
== SPI_MEM_DATA_OUT
, op
->data
.nbytes
);
212 wpcm_fiu_ects_deassert(fiu
, cs
);
214 if (op
->data
.dir
== SPI_MEM_DATA_IN
)
215 wpcm_fiu_get_data(fiu
, op
->data
.buf
.in
, op
->data
.nbytes
);
221 * RDID (Read Identification) needs special handling because Linux expects to
222 * be able to read 6 ID bytes and FIU can only read up to 4 at once.
224 * We're lucky in this case, because executing the RDID instruction twice will
225 * result in the same result.
227 * What we do is as follows (C: write command/opcode byte, D: read data byte,
228 * A: write address byte):
233 static bool wpcm_fiu_rdid_match(const struct spi_mem_op
*op
)
235 return op
->cmd
.opcode
== 0x9f && op
->addr
.nbytes
== 0 &&
236 op
->dummy
.nbytes
== 0 && op
->data
.nbytes
== 6 &&
237 op
->data
.dir
== SPI_MEM_DATA_IN
;
240 static int wpcm_fiu_rdid_exec(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
242 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(mem
->spi
->controller
);
243 int cs
= spi_get_chipselect(mem
->spi
, 0);
246 wpcm_fiu_set_opcode(fiu
, op
->cmd
.opcode
);
247 wpcm_fiu_set_addr(fiu
, 0);
248 wpcm_fiu_do_uma(fiu
, cs
, false, false, 3);
249 wpcm_fiu_get_data(fiu
, op
->data
.buf
.in
, 3);
251 /* Second transfer */
252 wpcm_fiu_set_opcode(fiu
, op
->cmd
.opcode
);
253 wpcm_fiu_set_addr(fiu
, 0);
254 wpcm_fiu_do_uma(fiu
, cs
, true, false, 3);
255 wpcm_fiu_get_data(fiu
, op
->data
.buf
.in
+ 3, 3);
261 * With some dummy bytes.
263 * C A A A X* X D D D D
264 * [C A A A D*][C D D D D]
266 static bool wpcm_fiu_dummy_match(const struct spi_mem_op
*op
)
268 // Opcode 0x0b (FAST READ) is treated differently in hardware
269 if (op
->cmd
.opcode
== 0x0b)
272 return (op
->addr
.nbytes
== 0 || op
->addr
.nbytes
== 3) &&
273 op
->dummy
.nbytes
>= 1 && op
->dummy
.nbytes
<= 5 &&
274 op
->data
.nbytes
<= 4;
277 static int wpcm_fiu_dummy_exec(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
279 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(mem
->spi
->controller
);
280 int cs
= spi_get_chipselect(mem
->spi
, 0);
282 wpcm_fiu_ects_assert(fiu
, cs
);
285 wpcm_fiu_set_opcode(fiu
, op
->cmd
.opcode
);
286 wpcm_fiu_set_addr(fiu
, op
->addr
.val
);
287 wpcm_fiu_do_uma(fiu
, cs
, op
->addr
.nbytes
!= 0, true, op
->dummy
.nbytes
- 1);
289 /* Second transfer */
290 wpcm_fiu_set_opcode(fiu
, 0);
291 wpcm_fiu_set_addr(fiu
, 0);
292 wpcm_fiu_do_uma(fiu
, cs
, false, false, op
->data
.nbytes
);
293 wpcm_fiu_get_data(fiu
, op
->data
.buf
.in
, op
->data
.nbytes
);
295 wpcm_fiu_ects_deassert(fiu
, cs
);
300 static const struct wpcm_fiu_op_shape wpcm_fiu_op_shapes
[] = {
301 { .match
= wpcm_fiu_normal_match
, .exec
= wpcm_fiu_normal_exec
},
302 { .match
= wpcm_fiu_fast_read_match
, .exec
= wpcm_fiu_fast_read_exec
},
303 { .match
= wpcm_fiu_4ba_match
, .exec
= wpcm_fiu_4ba_exec
},
304 { .match
= wpcm_fiu_rdid_match
, .exec
= wpcm_fiu_rdid_exec
},
305 { .match
= wpcm_fiu_dummy_match
, .exec
= wpcm_fiu_dummy_exec
},
308 static const struct wpcm_fiu_op_shape
*wpcm_fiu_find_op_shape(const struct spi_mem_op
*op
)
312 for (i
= 0; i
< ARRAY_SIZE(wpcm_fiu_op_shapes
); i
++) {
313 const struct wpcm_fiu_op_shape
*shape
= &wpcm_fiu_op_shapes
[i
];
315 if (shape
->match(op
))
322 static bool wpcm_fiu_supports_op(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
324 if (!spi_mem_default_supports_op(mem
, op
))
327 if (op
->cmd
.dtr
|| op
->addr
.dtr
|| op
->dummy
.dtr
|| op
->data
.dtr
)
330 if (op
->cmd
.buswidth
> 1 || op
->addr
.buswidth
> 1 ||
331 op
->dummy
.buswidth
> 1 || op
->data
.buswidth
> 1)
334 return wpcm_fiu_find_op_shape(op
) != NULL
;
338 * In order to ensure the integrity of SPI transfers performed via UMA,
339 * temporarily disable (stall) memory accesses coming from the host CPU.
341 static void wpcm_fiu_stall_host(struct wpcm_fiu_spi
*fiu
, bool stall
)
343 if (fiu
->shm_regmap
) {
344 int res
= regmap_update_bits(fiu
->shm_regmap
, SHM_FLASH_SIZE
,
345 SHM_FLASH_SIZE_STALL_HOST
,
346 stall
? SHM_FLASH_SIZE_STALL_HOST
: 0);
348 dev_warn(fiu
->dev
, "Failed to (un)stall host memory accesses: %d\n", res
);
352 static int wpcm_fiu_exec_op(struct spi_mem
*mem
, const struct spi_mem_op
*op
)
354 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(mem
->spi
->controller
);
355 const struct wpcm_fiu_op_shape
*shape
= wpcm_fiu_find_op_shape(op
);
357 wpcm_fiu_stall_host(fiu
, true);
360 return shape
->exec(mem
, op
);
362 wpcm_fiu_stall_host(fiu
, false);
367 static int wpcm_fiu_adjust_op_size(struct spi_mem
*mem
, struct spi_mem_op
*op
)
369 if (op
->data
.nbytes
> 4)
375 static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc
*desc
)
377 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(desc
->mem
->spi
->controller
);
378 int cs
= spi_get_chipselect(desc
->mem
->spi
, 0);
380 if (desc
->info
.op_tmpl
.data
.dir
!= SPI_MEM_DATA_IN
)
384 * Unfortunately, FIU only supports a 16 MiB direct mapping window (per
385 * attached flash chip), but the SPI MEM core doesn't support partial
386 * direct mappings. This means that we can't support direct mapping on
387 * flashes that are bigger than 16 MiB.
389 if (desc
->info
.offset
+ desc
->info
.length
> MAX_MEMORY_SIZE_PER_CS
)
392 /* Don't read past the memory window */
393 if (cs
* MAX_MEMORY_SIZE_PER_CS
+ desc
->info
.offset
+ desc
->info
.length
> fiu
->memory_size
)
399 static ssize_t
wpcm_fiu_direct_read(struct spi_mem_dirmap_desc
*desc
, u64 offs
, size_t len
, void *buf
)
401 struct wpcm_fiu_spi
*fiu
= spi_controller_get_devdata(desc
->mem
->spi
->controller
);
402 int cs
= spi_get_chipselect(desc
->mem
->spi
, 0);
404 if (offs
>= MAX_MEMORY_SIZE_PER_CS
)
407 offs
+= cs
* MAX_MEMORY_SIZE_PER_CS
;
409 if (!fiu
->memory
|| offs
>= fiu
->memory_size
)
412 len
= min_t(size_t, len
, fiu
->memory_size
- offs
);
413 memcpy_fromio(buf
, fiu
->memory
+ offs
, len
);
418 static const struct spi_controller_mem_ops wpcm_fiu_mem_ops
= {
419 .adjust_op_size
= wpcm_fiu_adjust_op_size
,
420 .supports_op
= wpcm_fiu_supports_op
,
421 .exec_op
= wpcm_fiu_exec_op
,
422 .dirmap_create
= wpcm_fiu_dirmap_create
,
423 .dirmap_read
= wpcm_fiu_direct_read
,
426 static void wpcm_fiu_hw_init(struct wpcm_fiu_spi
*fiu
)
428 /* Configure memory-mapped flash access */
429 writeb(FIU_BURST_CFG_R16
, fiu
->regs
+ FIU_BURST_BFG
);
430 writeb(MAX_MEMORY_SIZE_TOTAL
/ (512 << 10), fiu
->regs
+ FIU_CFG
);
431 writeb(MAX_MEMORY_SIZE_PER_CS
/ (512 << 10) | BIT(6), fiu
->regs
+ FIU_SPI_FL_CFG
);
433 /* Deassert all manually asserted chip selects */
434 writeb(0x0f, fiu
->regs
+ FIU_UMA_ECTS
);
437 static int wpcm_fiu_probe(struct platform_device
*pdev
)
439 struct device
*dev
= &pdev
->dev
;
440 struct spi_controller
*ctrl
;
441 struct wpcm_fiu_spi
*fiu
;
442 struct resource
*res
;
444 ctrl
= devm_spi_alloc_host(dev
, sizeof(*fiu
));
448 fiu
= spi_controller_get_devdata(ctrl
);
451 fiu
->regs
= devm_platform_ioremap_resource_byname(pdev
, "control");
452 if (IS_ERR(fiu
->regs
))
453 return dev_err_probe(dev
, PTR_ERR(fiu
->regs
),
454 "Failed to map registers\n");
456 fiu
->clk
= devm_clk_get_enabled(dev
, NULL
);
457 if (IS_ERR(fiu
->clk
))
458 return PTR_ERR(fiu
->clk
);
460 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "memory");
461 fiu
->memory
= devm_ioremap_resource(dev
, res
);
462 fiu
->memory_size
= min_t(size_t, resource_size(res
), MAX_MEMORY_SIZE_TOTAL
);
463 if (IS_ERR(fiu
->memory
))
464 return dev_err_probe(dev
, PTR_ERR(fiu
->memory
),
465 "Failed to map flash memory window\n");
467 fiu
->shm_regmap
= syscon_regmap_lookup_by_phandle_optional(dev
->of_node
, "nuvoton,shm");
469 wpcm_fiu_hw_init(fiu
);
472 ctrl
->mem_ops
= &wpcm_fiu_mem_ops
;
473 ctrl
->num_chipselect
= 4;
474 ctrl
->dev
.of_node
= dev
->of_node
;
477 * The FIU doesn't include a clock divider, the clock is entirely
478 * determined by the AHB3 bus clock.
480 ctrl
->min_speed_hz
= clk_get_rate(fiu
->clk
);
481 ctrl
->max_speed_hz
= clk_get_rate(fiu
->clk
);
483 return devm_spi_register_controller(dev
, ctrl
);
486 static const struct of_device_id wpcm_fiu_dt_ids
[] = {
487 { .compatible
= "nuvoton,wpcm450-fiu", },
490 MODULE_DEVICE_TABLE(of
, wpcm_fiu_dt_ids
);
492 static struct platform_driver wpcm_fiu_driver
= {
494 .name
= "wpcm450-fiu",
495 .bus
= &platform_bus_type
,
496 .of_match_table
= wpcm_fiu_dt_ids
,
498 .probe
= wpcm_fiu_probe
,
500 module_platform_driver(wpcm_fiu_driver
);
502 MODULE_DESCRIPTION("Nuvoton WPCM450 FIU SPI controller driver");
503 MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>");
504 MODULE_LICENSE("GPL");