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_plat {
83 struct bcmstb_spi_priv {
84 struct bcmstb_hif_mspi_regs *regs;
92 u8 saved_cmd[NUM_CDRAM];
97 static int bcmstb_spi_of_to_plat(struct udevice *bus)
99 struct bcmstb_spi_plat *plat = dev_get_plat(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_plat *plat = dev_get_plat(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 .of_to_plat = bcmstb_spi_of_to_plat,
436 .probe = bcmstb_spi_probe,
437 .plat_auto = sizeof(struct bcmstb_spi_plat),
438 .priv_auto = sizeof(struct bcmstb_spi_priv),