2 * Microchip PIC32 SPI controller driver.
4 * Copyright (c) 2015, Microchip Technology Inc.
5 * Purna Chandra Mandal <purna.mandal@microchip.com>
7 * SPDX-License-Identifier: GPL-2.0+
13 #include <linux/compat.h>
17 #include <asm/types.h>
20 #include <dt-bindings/clock/microchip,clock.h>
21 #include <mach/pic32.h>
23 DECLARE_GLOBAL_DATA_PTR
;
25 /* PIC32 SPI controller registers */
26 struct pic32_reg_spi
{
27 struct pic32_reg_atomic ctrl
;
28 struct pic32_reg_atomic status
;
29 struct pic32_reg_atomic buf
;
30 struct pic32_reg_atomic baud
;
31 struct pic32_reg_atomic ctrl2
;
34 /* Bit fields in SPI Control Register */
35 #define PIC32_SPI_CTRL_MSTEN BIT(5) /* Enable SPI Master */
36 #define PIC32_SPI_CTRL_CKP BIT(6) /* active low */
37 #define PIC32_SPI_CTRL_CKE BIT(8) /* Tx on falling edge */
38 #define PIC32_SPI_CTRL_SMP BIT(9) /* Rx at middle or end of tx */
39 #define PIC32_SPI_CTRL_BPW_MASK 0x03 /* Bits per word */
40 #define PIC32_SPI_CTRL_BPW_8 0x0
41 #define PIC32_SPI_CTRL_BPW_16 0x1
42 #define PIC32_SPI_CTRL_BPW_32 0x2
43 #define PIC32_SPI_CTRL_BPW_SHIFT 10
44 #define PIC32_SPI_CTRL_ON BIT(15) /* Macro enable */
45 #define PIC32_SPI_CTRL_ENHBUF BIT(16) /* Enable enhanced buffering */
46 #define PIC32_SPI_CTRL_MCLKSEL BIT(23) /* Select SPI Clock src */
47 #define PIC32_SPI_CTRL_MSSEN BIT(28) /* SPI macro will drive SS */
48 #define PIC32_SPI_CTRL_FRMEN BIT(31) /* Enable framing mode */
50 /* Bit fields in SPI Status Register */
51 #define PIC32_SPI_STAT_RX_OV BIT(6) /* err, s/w needs to clear */
52 #define PIC32_SPI_STAT_TF_LVL_MASK 0x1f
53 #define PIC32_SPI_STAT_TF_LVL_SHIFT 16
54 #define PIC32_SPI_STAT_RF_LVL_MASK 0x1f
55 #define PIC32_SPI_STAT_RF_LVL_SHIFT 24
57 /* Bit fields in SPI Baud Register */
58 #define PIC32_SPI_BAUD_MASK 0x1ff
60 struct pic32_spi_priv
{
61 struct pic32_reg_spi
*regs
;
62 u32 fifo_depth
; /* FIFO depth in bytes */
63 u32 fifo_n_word
; /* FIFO depth in words */
64 struct gpio_desc cs_gpio
;
66 /* Current SPI slave specific */
68 u32 speed_hz
; /* spi-clk rate */
71 /* Current message/transfer state */
78 /* SPI FiFo accessor */
79 void (*rx_fifo
)(struct pic32_spi_priv
*);
80 void (*tx_fifo
)(struct pic32_spi_priv
*);
83 static inline void pic32_spi_enable(struct pic32_spi_priv
*priv
)
85 writel(PIC32_SPI_CTRL_ON
, &priv
->regs
->ctrl
.set
);
88 static inline void pic32_spi_disable(struct pic32_spi_priv
*priv
)
90 writel(PIC32_SPI_CTRL_ON
, &priv
->regs
->ctrl
.clr
);
93 static inline u32
pic32_spi_rx_fifo_level(struct pic32_spi_priv
*priv
)
95 u32 sr
= readl(&priv
->regs
->status
.raw
);
97 return (sr
>> PIC32_SPI_STAT_RF_LVL_SHIFT
) & PIC32_SPI_STAT_RF_LVL_MASK
;
100 static inline u32
pic32_spi_tx_fifo_level(struct pic32_spi_priv
*priv
)
102 u32 sr
= readl(&priv
->regs
->status
.raw
);
104 return (sr
>> PIC32_SPI_STAT_TF_LVL_SHIFT
) & PIC32_SPI_STAT_TF_LVL_MASK
;
107 /* Return the max entries we can fill into tx fifo */
108 static u32
pic32_tx_max(struct pic32_spi_priv
*priv
, int n_bytes
)
110 u32 tx_left
, tx_room
, rxtx_gap
;
112 tx_left
= (priv
->tx_end
- priv
->tx
) / n_bytes
;
113 tx_room
= priv
->fifo_n_word
- pic32_spi_tx_fifo_level(priv
);
115 rxtx_gap
= (priv
->rx_end
- priv
->rx
) - (priv
->tx_end
- priv
->tx
);
117 return min3(tx_left
, tx_room
, (u32
)(priv
->fifo_n_word
- rxtx_gap
));
120 /* Return the max entries we should read out of rx fifo */
121 static u32
pic32_rx_max(struct pic32_spi_priv
*priv
, int n_bytes
)
123 u32 rx_left
= (priv
->rx_end
- priv
->rx
) / n_bytes
;
125 return min_t(u32
, rx_left
, pic32_spi_rx_fifo_level(priv
));
128 #define BUILD_SPI_FIFO_RW(__name, __type, __bwl) \
129 static void pic32_spi_rx_##__name(struct pic32_spi_priv *priv) \
132 u32 mx = pic32_rx_max(priv, sizeof(__type)); \
135 val = read##__bwl(&priv->regs->buf.raw); \
136 if (priv->rx_end - priv->len) \
137 *(__type *)(priv->rx) = val; \
138 priv->rx += sizeof(__type); \
142 static void pic32_spi_tx_##__name(struct pic32_spi_priv *priv) \
145 u32 mx = pic32_tx_max(priv, sizeof(__type)); \
147 for (; mx ; mx--) { \
148 val = (__type) ~0U; \
149 if (priv->tx_end - priv->len) \
150 val = *(__type *)(priv->tx); \
151 write##__bwl(val, &priv->regs->buf.raw); \
152 priv->tx += sizeof(__type); \
155 BUILD_SPI_FIFO_RW(byte
, u8
, b
);
156 BUILD_SPI_FIFO_RW(word
, u16
, w
);
157 BUILD_SPI_FIFO_RW(dword
, u32
, l
);
159 static int pic32_spi_set_word_size(struct pic32_spi_priv
*priv
,
160 unsigned int wordlen
)
167 priv
->rx_fifo
= pic32_spi_rx_byte
;
168 priv
->tx_fifo
= pic32_spi_tx_byte
;
169 bits_per_word
= PIC32_SPI_CTRL_BPW_8
;
172 priv
->rx_fifo
= pic32_spi_rx_word
;
173 priv
->tx_fifo
= pic32_spi_tx_word
;
174 bits_per_word
= PIC32_SPI_CTRL_BPW_16
;
177 priv
->rx_fifo
= pic32_spi_rx_dword
;
178 priv
->tx_fifo
= pic32_spi_tx_dword
;
179 bits_per_word
= PIC32_SPI_CTRL_BPW_32
;
182 printf("pic32-spi: unsupported wordlen\n");
186 /* set bits-per-word */
187 val
= readl(&priv
->regs
->ctrl
.raw
);
188 val
&= ~(PIC32_SPI_CTRL_BPW_MASK
<< PIC32_SPI_CTRL_BPW_SHIFT
);
189 val
|= bits_per_word
<< PIC32_SPI_CTRL_BPW_SHIFT
;
190 writel(val
, &priv
->regs
->ctrl
.raw
);
192 /* calculate maximum number of words fifo can hold */
193 priv
->fifo_n_word
= DIV_ROUND_UP(priv
->fifo_depth
, wordlen
/ 8);
198 static int pic32_spi_claim_bus(struct udevice
*slave
)
200 struct pic32_spi_priv
*priv
= dev_get_priv(slave
->parent
);
203 pic32_spi_enable(priv
);
208 static int pic32_spi_release_bus(struct udevice
*slave
)
210 struct pic32_spi_priv
*priv
= dev_get_priv(slave
->parent
);
213 pic32_spi_disable(priv
);
218 static void spi_cs_activate(struct pic32_spi_priv
*priv
)
220 if (!dm_gpio_is_valid(&priv
->cs_gpio
))
223 dm_gpio_set_value(&priv
->cs_gpio
, 1);
226 static void spi_cs_deactivate(struct pic32_spi_priv
*priv
)
228 if (!dm_gpio_is_valid(&priv
->cs_gpio
))
231 dm_gpio_set_value(&priv
->cs_gpio
, 0);
234 static int pic32_spi_xfer(struct udevice
*slave
, unsigned int bitlen
,
235 const void *tx_buf
, void *rx_buf
,
238 struct dm_spi_slave_platdata
*slave_plat
;
239 struct udevice
*bus
= slave
->parent
;
240 struct pic32_spi_priv
*priv
;
241 int len
= bitlen
/ 8;
245 priv
= dev_get_priv(bus
);
246 slave_plat
= dev_get_parent_platdata(slave
);
248 debug("spi_xfer: bus:%i cs:%i flags:%lx\n",
249 bus
->seq
, slave_plat
->cs
, flags
);
250 debug("msg tx %p, rx %p submitted of %d byte(s)\n",
251 tx_buf
, rx_buf
, len
);
254 if (flags
& SPI_XFER_BEGIN
)
255 spi_cs_activate(priv
);
257 /* set current transfer information */
260 priv
->tx_end
= priv
->tx
+ len
;
261 priv
->rx_end
= priv
->rx
+ len
;
264 /* transact by polling */
265 tbase
= get_timer(0);
270 /* received sufficient data */
271 if (priv
->rx
>= priv
->rx_end
) {
276 if (get_timer(tbase
) > 5 * CONFIG_SYS_HZ
) {
277 printf("pic32_spi: error, xfer timedout.\n");
278 flags
|= SPI_XFER_END
;
285 if (flags
& SPI_XFER_END
)
286 spi_cs_deactivate(priv
);
291 static int pic32_spi_set_speed(struct udevice
*bus
, uint speed
)
293 struct pic32_spi_priv
*priv
= dev_get_priv(bus
);
296 debug("%s: %s, speed %u\n", __func__
, bus
->name
, speed
);
298 /* div = [clk_in / (2 * spi_clk)] - 1 */
299 div
= (priv
->clk_rate
/ 2 / speed
) - 1;
300 div
&= PIC32_SPI_BAUD_MASK
;
301 writel(div
, &priv
->regs
->baud
.raw
);
303 priv
->speed_hz
= speed
;
308 static int pic32_spi_set_mode(struct udevice
*bus
, uint mode
)
310 struct pic32_spi_priv
*priv
= dev_get_priv(bus
);
313 debug("%s: %s, mode %d\n", __func__
, bus
->name
, mode
);
315 /* set spi-clk mode */
316 val
= readl(&priv
->regs
->ctrl
.raw
);
319 val
|= PIC32_SPI_CTRL_CKP
;
321 val
&= ~PIC32_SPI_CTRL_CKP
;
323 /* TX at idle-to-active clk transition */
325 val
&= ~PIC32_SPI_CTRL_CKE
;
327 val
|= PIC32_SPI_CTRL_CKE
;
329 /* RX at end of tx */
330 val
|= PIC32_SPI_CTRL_SMP
;
331 writel(val
, &priv
->regs
->ctrl
.raw
);
338 static int pic32_spi_set_wordlen(struct udevice
*slave
, unsigned int wordlen
)
340 struct pic32_spi_priv
*priv
= dev_get_priv(slave
->parent
);
342 return pic32_spi_set_word_size(priv
, wordlen
);
345 static void pic32_spi_hw_init(struct pic32_spi_priv
*priv
)
350 pic32_spi_disable(priv
);
352 val
= readl(&priv
->regs
->ctrl
);
354 /* enable enhanced fifo of 128bit deep */
355 val
|= PIC32_SPI_CTRL_ENHBUF
;
356 priv
->fifo_depth
= 16;
358 /* disable framing mode */
359 val
&= ~PIC32_SPI_CTRL_FRMEN
;
361 /* enable master mode */
362 val
|= PIC32_SPI_CTRL_MSTEN
;
364 /* select clk source */
365 val
&= ~PIC32_SPI_CTRL_MCLKSEL
;
367 /* set manual /CS mode */
368 val
&= ~PIC32_SPI_CTRL_MSSEN
;
370 writel(val
, &priv
->regs
->ctrl
);
372 /* clear rx overflow indicator */
373 writel(PIC32_SPI_STAT_RX_OV
, &priv
->regs
->status
.clr
);
376 static int pic32_spi_probe(struct udevice
*bus
)
378 struct pic32_spi_priv
*priv
= dev_get_priv(bus
);
379 struct dm_spi_bus
*dm_spi
= dev_get_uclass_priv(bus
);
380 struct udevice
*clkdev
;
385 debug("%s: %d, bus: %i\n", __func__
, __LINE__
, bus
->seq
);
386 addr
= fdtdec_get_addr_size(gd
->fdt_blob
, bus
->of_offset
, "reg", &size
);
387 if (addr
== FDT_ADDR_T_NONE
)
390 priv
->regs
= ioremap(addr
, size
);
394 dm_spi
->max_hz
= fdtdec_get_int(gd
->fdt_blob
, bus
->of_offset
,
395 "spi-max-frequency", 250000000);
397 ret
= clk_get_by_index(bus
, 0, &clkdev
);
399 printf("pic32-spi: error, clk not found\n");
402 priv
->clk_rate
= clk_get_periph_rate(clkdev
, ret
);
405 pic32_spi_hw_init(priv
);
408 pic32_spi_set_word_size(priv
, SPI_DEFAULT_WORDLEN
);
410 /* PIC32 SPI controller can automatically drive /CS during transfer
411 * depending on fifo fill-level. /CS will stay asserted as long as
412 * TX fifo is non-empty, else will be deasserted confirming completion
413 * of the ongoing transfer. To avoid this sort of error we will drive
414 * /CS manually by toggling cs-gpio pins.
416 ret
= gpio_request_by_name_nodev(gd
->fdt_blob
, bus
->of_offset
,
418 &priv
->cs_gpio
, GPIOD_IS_OUT
);
420 printf("pic32-spi: error, cs-gpios not found\n");
427 static const struct dm_spi_ops pic32_spi_ops
= {
428 .claim_bus
= pic32_spi_claim_bus
,
429 .release_bus
= pic32_spi_release_bus
,
430 .xfer
= pic32_spi_xfer
,
431 .set_speed
= pic32_spi_set_speed
,
432 .set_mode
= pic32_spi_set_mode
,
433 .set_wordlen
= pic32_spi_set_wordlen
,
436 static const struct udevice_id pic32_spi_ids
[] = {
437 { .compatible
= "microchip,pic32mzda-spi" },
441 U_BOOT_DRIVER(pic32_spi
) = {
444 .of_match
= pic32_spi_ids
,
445 .ops
= &pic32_spi_ops
,
446 .priv_auto_alloc_size
= sizeof(struct pic32_spi_priv
),
447 .probe
= pic32_spi_probe
,