Lines Matching +full:tx +full:- +full:fifo +full:- +full:depth
1 // SPDX-License-Identifier: GPL-2.0+
19 #include <dt-bindings/clock/microchip,clock.h>
36 #define PIC32_SPI_CTRL_CKE BIT(8) /* Tx on falling edge */
37 #define PIC32_SPI_CTRL_SMP BIT(9) /* Rx at middle or end of tx */
61 u32 fifo_depth; /* FIFO depth in bytes */
62 u32 fifo_n_word; /* FIFO depth in words */
67 u32 speed_hz; /* spi-clk rate */
71 const void *tx; member
77 /* SPI FiFo accessor */
84 writel(PIC32_SPI_CTRL_ON, &priv->regs->ctrl.set); in pic32_spi_enable()
89 writel(PIC32_SPI_CTRL_ON, &priv->regs->ctrl.clr); in pic32_spi_disable()
94 u32 sr = readl(&priv->regs->status.raw); in pic32_spi_rx_fifo_level()
101 u32 sr = readl(&priv->regs->status.raw); in pic32_spi_tx_fifo_level()
106 /* Return the max entries we can fill into tx fifo */
111 tx_left = (priv->tx_end - priv->tx) / n_bytes; in pic32_tx_max()
112 tx_room = priv->fifo_n_word - pic32_spi_tx_fifo_level(priv); in pic32_tx_max()
114 rxtx_gap = (priv->rx_end - priv->rx) - (priv->tx_end - priv->tx); in pic32_tx_max()
116 return min3(tx_left, tx_room, (u32)(priv->fifo_n_word - rxtx_gap)); in pic32_tx_max()
119 /* Return the max entries we should read out of rx fifo */
122 u32 rx_left = (priv->rx_end - priv->rx) / n_bytes; in pic32_rx_max()
133 for (; mx; mx--) { \
134 val = read##__bwl(&priv->regs->buf.raw); \
135 if (priv->rx_end - priv->len) \
136 *(__type *)(priv->rx) = val; \
137 priv->rx += sizeof(__type); \
146 for (; mx ; mx--) { \
148 if (priv->tx_end - priv->len) \
149 val = *(__type *)(priv->tx); \
150 write##__bwl(val, &priv->regs->buf.raw); \
151 priv->tx += sizeof(__type); \
166 priv->rx_fifo = pic32_spi_rx_byte; in pic32_spi_set_word_size()
167 priv->tx_fifo = pic32_spi_tx_byte; in pic32_spi_set_word_size()
171 priv->rx_fifo = pic32_spi_rx_word; in pic32_spi_set_word_size()
172 priv->tx_fifo = pic32_spi_tx_word; in pic32_spi_set_word_size()
176 priv->rx_fifo = pic32_spi_rx_dword; in pic32_spi_set_word_size()
177 priv->tx_fifo = pic32_spi_tx_dword; in pic32_spi_set_word_size()
181 printf("pic32-spi: unsupported wordlen\n"); in pic32_spi_set_word_size()
182 return -EINVAL; in pic32_spi_set_word_size()
185 /* set bits-per-word */ in pic32_spi_set_word_size()
186 val = readl(&priv->regs->ctrl.raw); in pic32_spi_set_word_size()
189 writel(val, &priv->regs->ctrl.raw); in pic32_spi_set_word_size()
191 /* calculate maximum number of words fifo can hold */ in pic32_spi_set_word_size()
192 priv->fifo_n_word = DIV_ROUND_UP(priv->fifo_depth, wordlen / 8); in pic32_spi_set_word_size()
199 struct pic32_spi_priv *priv = dev_get_priv(slave->parent); in pic32_spi_claim_bus()
209 struct pic32_spi_priv *priv = dev_get_priv(slave->parent); in pic32_spi_release_bus()
219 if (!dm_gpio_is_valid(&priv->cs_gpio)) in spi_cs_activate()
222 dm_gpio_set_value(&priv->cs_gpio, 1); in spi_cs_activate()
227 if (!dm_gpio_is_valid(&priv->cs_gpio)) in spi_cs_deactivate()
230 dm_gpio_set_value(&priv->cs_gpio, 0); in spi_cs_deactivate()
238 struct udevice *bus = slave->parent; in pic32_spi_xfer()
248 bus->seq, slave_plat->cs, flags); in pic32_spi_xfer()
249 debug("msg tx %p, rx %p submitted of %d byte(s)\n", in pic32_spi_xfer()
257 priv->tx = tx_buf; in pic32_spi_xfer()
258 priv->rx = rx_buf; in pic32_spi_xfer()
259 priv->tx_end = priv->tx + len; in pic32_spi_xfer()
260 priv->rx_end = priv->rx + len; in pic32_spi_xfer()
261 priv->len = len; in pic32_spi_xfer()
266 priv->tx_fifo(priv); in pic32_spi_xfer()
267 priv->rx_fifo(priv); in pic32_spi_xfer()
270 if (priv->rx >= priv->rx_end) { in pic32_spi_xfer()
278 ret = -ETIMEDOUT; in pic32_spi_xfer()
295 debug("%s: %s, speed %u\n", __func__, bus->name, speed); in pic32_spi_set_speed()
297 /* div = [clk_in / (2 * spi_clk)] - 1 */ in pic32_spi_set_speed()
298 div = (priv->clk_rate / 2 / speed) - 1; in pic32_spi_set_speed()
300 writel(div, &priv->regs->baud.raw); in pic32_spi_set_speed()
302 priv->speed_hz = speed; in pic32_spi_set_speed()
312 debug("%s: %s, mode %d\n", __func__, bus->name, mode); in pic32_spi_set_mode()
314 /* set spi-clk mode */ in pic32_spi_set_mode()
315 val = readl(&priv->regs->ctrl.raw); in pic32_spi_set_mode()
322 /* TX at idle-to-active clk transition */ in pic32_spi_set_mode()
328 /* RX at end of tx */ in pic32_spi_set_mode()
330 writel(val, &priv->regs->ctrl.raw); in pic32_spi_set_mode()
332 priv->mode = mode; in pic32_spi_set_mode()
339 struct pic32_spi_priv *priv = dev_get_priv(slave->parent); in pic32_spi_set_wordlen()
351 val = readl(&priv->regs->ctrl); in pic32_spi_hw_init()
353 /* enable enhanced fifo of 128bit deep */ in pic32_spi_hw_init()
355 priv->fifo_depth = 16; in pic32_spi_hw_init()
369 writel(val, &priv->regs->ctrl); in pic32_spi_hw_init()
372 writel(PIC32_SPI_STAT_RX_OV, &priv->regs->status.clr); in pic32_spi_hw_init()
385 debug("%s: %d, bus: %i\n", __func__, __LINE__, bus->seq); in pic32_spi_probe()
386 addr = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size); in pic32_spi_probe()
388 return -EINVAL; in pic32_spi_probe()
390 priv->regs = ioremap(addr, size); in pic32_spi_probe()
391 if (!priv->regs) in pic32_spi_probe()
392 return -EINVAL; in pic32_spi_probe()
394 dm_spi->max_hz = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", in pic32_spi_probe()
399 printf("pic32-spi: error, clk not found\n"); in pic32_spi_probe()
402 priv->clk_rate = clk_get_periph_rate(clkdev, ret); in pic32_spi_probe()
411 * depending on fifo fill-level. /CS will stay asserted as long as in pic32_spi_probe()
412 * TX fifo is non-empty, else will be deasserted confirming completion in pic32_spi_probe()
414 * /CS manually by toggling cs-gpio pins. in pic32_spi_probe()
416 ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "cs-gpios", 0, in pic32_spi_probe()
417 &priv->cs_gpio, GPIOD_IS_OUT); in pic32_spi_probe()
419 printf("pic32-spi: error, cs-gpios not found\n"); in pic32_spi_probe()
436 { .compatible = "microchip,pic32mzda-spi" },