1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2018 Cisco Systems, Inc.
5 * Author: Thomas Fitzsimmons <fitzsim@fitzsim.org>
14 #include <linux/bitops.h>
15 #include <linux/delay.h>
21 DECLARE_GLOBAL_DATA_PTR
;
24 #define BITS_PER_WORD 8
30 /* hif_mspi register structure. */
31 struct bcmstb_hif_mspi_regs
{
32 u32 spcr0_lsb
; /* 0x000 */
33 u32 spcr0_msb
; /* 0x004 */
34 u32 spcr1_lsb
; /* 0x008 */
35 u32 spcr1_msb
; /* 0x00c */
36 u32 newqp
; /* 0x010 */
37 u32 endqp
; /* 0x014 */
38 u32 spcr2
; /* 0x018 */
39 u32 reserved0
; /* 0x01c */
40 u32 mspi_status
; /* 0x020 */
41 u32 cptqp
; /* 0x024 */
42 u32 spcr3
; /* 0x028 */
43 u32 revision
; /* 0x02c */
44 u32 reserved1
[4]; /* 0x030 */
45 u32 txram
[NUM_TXRAM
]; /* 0x040 */
46 u32 rxram
[NUM_RXRAM
]; /* 0x0c0 */
47 u32 cdram
[NUM_CDRAM
]; /* 0x140 */
48 u32 write_lock
; /* 0x180 */
52 #define HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK 0x00000080
53 #define HIF_MSPI_SPCR2_SPE_MASK 0x00000040
54 #define HIF_MSPI_SPCR2_SPIFIE_MASK 0x00000020
55 #define HIF_MSPI_WRITE_LOCK_WRITE_LOCK_MASK 0x00000001
58 #define BSPI_MAST_N_BOOT_CTRL 0x008
60 /* bspi_raf is not used in this driver. */
62 /* hif_spi_intr2 offsets and masks. */
63 #define HIF_SPI_INTR2_CPU_CLEAR 0x08
64 #define HIF_SPI_INTR2_CPU_MASK_SET 0x10
65 #define HIF_SPI_INTR2_CPU_MASK_CLEAR 0x14
66 #define HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK 0x00000020
68 /* SPI transfer timeout in milliseconds. */
69 #define HIF_MSPI_WAIT 10
71 enum bcmstb_base_type
{
79 struct bcmstb_spi_platdata
{
83 struct bcmstb_spi_priv
{
84 struct bcmstb_hif_mspi_regs
*regs
;
92 u8 saved_cmd
[NUM_CDRAM
];
97 static int bcmstb_spi_ofdata_to_platdata(struct udevice
*bus
)
99 struct bcmstb_spi_platdata
*plat
= dev_get_platdata(bus
);
100 const void *fdt
= gd
->fdt_blob
;
101 int node
= dev_of_offset(bus
);
104 struct fdt_resource resource
= { 0 };
105 char *names
[BASE_LAST
] = { "hif_mspi", "bspi", "hif_spi_intr2",
107 const phys_addr_t defaults
[BASE_LAST
] = { BCMSTB_HIF_MSPI_BASE
,
109 BCMSTB_HIF_SPI_INTR2
,
112 for (i
= 0; i
< BASE_LAST
; i
++) {
113 plat
->base
[i
] = (void *)defaults
[i
];
115 ret
= fdt_get_named_resource(fdt
, node
, "reg", "reg-names",
116 names
[i
], &resource
);
118 printf("%s: Assuming BCMSTB SPI %s address 0x0x%p\n",
119 __func__
, names
[i
], (void *)defaults
[i
]);
121 plat
->base
[i
] = (void *)resource
.start
;
122 debug("BCMSTB SPI %s address: 0x0x%p\n",
123 names
[i
], (void *)plat
->base
[i
]);
130 static void bcmstb_spi_hw_set_parms(struct bcmstb_spi_priv
*priv
)
132 writel(SPBR_MIN
, &priv
->regs
->spcr0_lsb
);
133 writel(BITS_PER_WORD
<< 2 | SPI_MODE_3
, &priv
->regs
->spcr0_msb
);
136 static void bcmstb_spi_enable_interrupt(void *base
, u32 mask
)
138 void *reg
= base
+ HIF_SPI_INTR2_CPU_MASK_CLEAR
;
140 writel(readl(reg
) | mask
, reg
);
144 static void bcmstb_spi_disable_interrupt(void *base
, u32 mask
)
146 void *reg
= base
+ HIF_SPI_INTR2_CPU_MASK_SET
;
148 writel(readl(reg
) | mask
, reg
);
152 static void bcmstb_spi_clear_interrupt(void *base
, u32 mask
)
154 void *reg
= base
+ HIF_SPI_INTR2_CPU_CLEAR
;
156 writel(readl(reg
) | mask
, reg
);
160 static int bcmstb_spi_probe(struct udevice
*bus
)
162 struct bcmstb_spi_platdata
*plat
= dev_get_platdata(bus
);
163 struct bcmstb_spi_priv
*priv
= dev_get_priv(bus
);
165 priv
->regs
= plat
->base
[HIF_MSPI
];
166 priv
->bspi
= plat
->base
[BSPI
];
167 priv
->hif_spi_intr2
= plat
->base
[HIF_SPI_INTR2
];
168 priv
->cs_reg
= plat
->base
[CS_REG
];
169 priv
->default_cs
= 0;
173 memset(priv
->saved_cmd
, 0, NUM_CDRAM
);
174 priv
->saved_cmd_len
= 0;
175 priv
->saved_din_addr
= NULL
;
177 debug("spi_xfer: tx regs: 0x%p\n", &priv
->regs
->txram
[0]);
178 debug("spi_xfer: rx regs: 0x%p\n", &priv
->regs
->rxram
[0]);
181 writel(1, priv
->bspi
+ BSPI_MAST_N_BOOT_CTRL
);
182 readl(priv
->bspi
+ BSPI_MAST_N_BOOT_CTRL
);
184 /* Set up interrupts. */
185 bcmstb_spi_disable_interrupt(priv
->hif_spi_intr2
, 0xffffffff);
186 bcmstb_spi_clear_interrupt(priv
->hif_spi_intr2
, 0xffffffff);
187 bcmstb_spi_enable_interrupt(priv
->hif_spi_intr2
,
188 HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK
);
190 /* Set up control registers. */
191 writel(0, &priv
->regs
->spcr1_lsb
);
192 writel(0, &priv
->regs
->spcr1_msb
);
193 writel(0, &priv
->regs
->newqp
);
194 writel(0, &priv
->regs
->endqp
);
195 writel(HIF_MSPI_SPCR2_SPIFIE_MASK
, &priv
->regs
->spcr2
);
196 writel(0, &priv
->regs
->spcr3
);
198 bcmstb_spi_hw_set_parms(priv
);
203 static void bcmstb_spi_submit(struct bcmstb_spi_priv
*priv
, bool done
)
205 debug("WR NEWQP: %d\n", 0);
206 writel(0, &priv
->regs
->newqp
);
208 debug("WR ENDQP: %d\n", priv
->tx_slot
- 1);
209 writel(priv
->tx_slot
- 1, &priv
->regs
->endqp
);
212 debug("WR CDRAM[%d]: %02x\n", priv
->tx_slot
- 1,
213 readl(&priv
->regs
->cdram
[priv
->tx_slot
- 1]) & ~0x80);
214 writel(readl(&priv
->regs
->cdram
[priv
->tx_slot
- 1]) & ~0x80,
215 &priv
->regs
->cdram
[priv
->tx_slot
- 1]);
218 /* Force chip select first time. */
219 if (priv
->curr_cs
!= priv
->default_cs
) {
220 debug("spi_xfer: switching chip select to %d\n",
222 writel((readl(priv
->cs_reg
) & ~0xff) | (1 << priv
->default_cs
),
226 priv
->curr_cs
= priv
->default_cs
;
229 debug("WR WRITE_LOCK: %02x\n", 1);
230 writel((readl(&priv
->regs
->write_lock
) &
231 ~HIF_MSPI_WRITE_LOCK_WRITE_LOCK_MASK
) | 1,
232 &priv
->regs
->write_lock
);
233 readl(&priv
->regs
->write_lock
);
235 debug("WR SPCR2: %02x\n",
236 HIF_MSPI_SPCR2_SPIFIE_MASK
|
237 HIF_MSPI_SPCR2_SPE_MASK
|
238 HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK
);
239 writel(HIF_MSPI_SPCR2_SPIFIE_MASK
|
240 HIF_MSPI_SPCR2_SPE_MASK
|
241 HIF_MSPI_SPCR2_CONT_AFTER_CMD_MASK
,
245 static int bcmstb_spi_wait(struct bcmstb_spi_priv
*priv
)
247 u32 start_time
= get_timer(0);
248 u32 status
= readl(&priv
->regs
->mspi_status
);
250 while (!(status
& 1)) {
251 if (get_timer(start_time
) > HIF_MSPI_WAIT
)
253 status
= readl(&priv
->regs
->mspi_status
);
256 writel(readl(&priv
->regs
->mspi_status
) & ~1, &priv
->regs
->mspi_status
);
257 bcmstb_spi_clear_interrupt(priv
->hif_spi_intr2
,
258 HIF_SPI_INTR2_CPU_SET_MSPI_DONE_MASK
);
263 static int bcmstb_spi_xfer(struct udevice
*dev
, unsigned int bitlen
,
264 const void *dout
, void *din
, unsigned long flags
)
266 uint len
= bitlen
/ 8;
269 const u8
*out_bytes
= (u8
*)dout
;
270 u8
*in_bytes
= (u8
*)din
;
271 struct udevice
*bus
= dev_get_parent(dev
);
272 struct bcmstb_spi_priv
*priv
= dev_get_priv(bus
);
273 struct bcmstb_hif_mspi_regs
*regs
= priv
->regs
;
275 debug("spi_xfer: %d, t: 0x%p, r: 0x%p, f: %lx\n",
276 len
, dout
, din
, flags
);
277 debug("spi_xfer: chip select: %x\n", readl(priv
->cs_reg
) & 0xff);
278 debug("spi_xfer: tx addr: 0x%p\n", ®s
->txram
[0]);
279 debug("spi_xfer: rx addr: 0x%p\n", ®s
->rxram
[0]);
280 debug("spi_xfer: cd addr: 0x%p\n", ®s
->cdram
[0]);
282 if (flags
& SPI_XFER_END
) {
283 debug("spi_xfer: clearing saved din address: 0x%p\n",
284 priv
->saved_din_addr
);
285 priv
->saved_din_addr
= NULL
;
286 priv
->saved_cmd_len
= 0;
287 memset(priv
->saved_cmd
, 0, NUM_CDRAM
);
294 printf("%s: Non-byte-aligned transfer\n", __func__
);
298 if (flags
& ~(SPI_XFER_BEGIN
| SPI_XFER_END
)) {
299 printf("%s: Unsupported flags: %lx\n", __func__
, flags
);
303 if (flags
& SPI_XFER_BEGIN
) {
307 if (out_bytes
&& len
> NUM_CDRAM
) {
308 printf("%s: Unable to save transfer\n", __func__
);
312 if (out_bytes
&& !(flags
& SPI_XFER_END
)) {
314 * This is the start of a transmit operation
315 * that will need repeating if the calling
316 * code polls for the result. Save it for
317 * subsequent transmission.
319 debug("spi_xfer: saving command: %x, %d\n",
321 priv
->saved_cmd_len
= len
;
322 memcpy(priv
->saved_cmd
, out_bytes
, priv
->saved_cmd_len
);
326 if (!(flags
& (SPI_XFER_BEGIN
| SPI_XFER_END
))) {
327 if (priv
->saved_din_addr
== din
) {
329 * The caller is polling for status. Repeat
330 * the last transmission.
334 debug("spi_xfer: Making recursive call\n");
335 ret
= bcmstb_spi_xfer(dev
, priv
->saved_cmd_len
* 8,
336 priv
->saved_cmd
, NULL
,
339 printf("%s: Recursive call failed\n", __func__
);
343 debug("spi_xfer: saving din address: 0x%p\n", din
);
344 priv
->saved_din_addr
= din
;
349 priv
->rx_slot
= priv
->tx_slot
;
351 while (priv
->tx_slot
< NUM_CDRAM
&& tx_len
> 0) {
352 bcmstb_spi_hw_set_parms(priv
);
353 debug("WR TXRAM[%d]: %02x\n", priv
->tx_slot
,
354 out_bytes
? out_bytes
[len
- tx_len
] : 0xff);
355 writel(out_bytes
? out_bytes
[len
- tx_len
] : 0xff,
356 ®s
->txram
[priv
->tx_slot
<< 1]);
357 debug("WR CDRAM[%d]: %02x\n", priv
->tx_slot
, 0x8e);
358 writel(0x8e, ®s
->cdram
[priv
->tx_slot
]);
365 debug("spi_xfer: early return clauses: %d, %d, %d\n",
368 (flags
& (SPI_XFER_BEGIN
|
369 SPI_XFER_END
)) == SPI_XFER_BEGIN
);
370 if (len
<= NUM_CDRAM
&&
372 (flags
& (SPI_XFER_BEGIN
| SPI_XFER_END
)) == SPI_XFER_BEGIN
)
375 bcmstb_spi_submit(priv
, tx_len
== 0);
377 if (bcmstb_spi_wait(priv
) == -ETIMEDOUT
) {
378 printf("%s: Timed out\n", __func__
);
382 priv
->tx_slot
%= NUM_CDRAM
;
385 while (priv
->rx_slot
< NUM_CDRAM
&& rx_len
> 0) {
386 in_bytes
[len
- rx_len
] =
387 readl(®s
->rxram
[(priv
->rx_slot
<< 1)
390 debug("RD RXRAM[%d]: %02x\n",
391 priv
->rx_slot
, in_bytes
[len
- rx_len
]);
398 if (flags
& SPI_XFER_END
) {
399 debug("WR WRITE_LOCK: %02x\n", 0);
400 writel((readl(&priv
->regs
->write_lock
) &
401 ~HIF_MSPI_WRITE_LOCK_WRITE_LOCK_MASK
) | 0,
402 &priv
->regs
->write_lock
);
403 readl(&priv
->regs
->write_lock
);
409 static int bcmstb_spi_set_speed(struct udevice
*dev
, uint speed
)
414 static int bcmstb_spi_set_mode(struct udevice
*dev
, uint mode
)
419 static const struct dm_spi_ops bcmstb_spi_ops
= {
420 .xfer
= bcmstb_spi_xfer
,
421 .set_speed
= bcmstb_spi_set_speed
,
422 .set_mode
= bcmstb_spi_set_mode
,
425 static const struct udevice_id bcmstb_spi_id
[] = {
426 { .compatible
= "brcm,spi-brcmstb" },
430 U_BOOT_DRIVER(bcmstb_spi
) = {
431 .name
= "bcmstb_spi",
433 .of_match
= bcmstb_spi_id
,
434 .ops
= &bcmstb_spi_ops
,
435 .ofdata_to_platdata
= bcmstb_spi_ofdata_to_platdata
,
436 .probe
= bcmstb_spi_probe
,
437 .platdata_auto_alloc_size
= sizeof(struct bcmstb_spi_platdata
),
438 .priv_auto_alloc_size
= sizeof(struct bcmstb_spi_priv
),