Lines Matching +full:tx +full:- +full:fifo +full:- +full:depth
7 * SPDX-License-Identifier: GPL-2.0+
20 #include <dt-bindings/clock/microchip,clock.h>
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 */
62 u32 fifo_depth; /* FIFO depth in bytes */
63 u32 fifo_n_word; /* FIFO depth in words */
68 u32 speed_hz; /* spi-clk rate */
72 const void *tx; member
78 /* SPI FiFo accessor */
85 writel(PIC32_SPI_CTRL_ON, &priv->regs->ctrl.set); in pic32_spi_enable()
90 writel(PIC32_SPI_CTRL_ON, &priv->regs->ctrl.clr); in pic32_spi_disable()
95 u32 sr = readl(&priv->regs->status.raw); in pic32_spi_rx_fifo_level()
102 u32 sr = readl(&priv->regs->status.raw); in pic32_spi_tx_fifo_level()
107 /* Return the max entries we can fill into tx fifo */
112 tx_left = (priv->tx_end - priv->tx) / n_bytes; in pic32_tx_max()
113 tx_room = priv->fifo_n_word - pic32_spi_tx_fifo_level(priv); in pic32_tx_max()
115 rxtx_gap = (priv->rx_end - priv->rx) - (priv->tx_end - priv->tx); in pic32_tx_max()
117 return min3(tx_left, tx_room, (u32)(priv->fifo_n_word - rxtx_gap)); in pic32_tx_max()
120 /* Return the max entries we should read out of rx fifo */
123 u32 rx_left = (priv->rx_end - priv->rx) / n_bytes; in pic32_rx_max()
134 for (; mx; mx--) { \
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); \
147 for (; mx ; mx--) { \
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); \
167 priv->rx_fifo = pic32_spi_rx_byte; in pic32_spi_set_word_size()
168 priv->tx_fifo = pic32_spi_tx_byte; in pic32_spi_set_word_size()
172 priv->rx_fifo = pic32_spi_rx_word; in pic32_spi_set_word_size()
173 priv->tx_fifo = pic32_spi_tx_word; in pic32_spi_set_word_size()
177 priv->rx_fifo = pic32_spi_rx_dword; in pic32_spi_set_word_size()
178 priv->tx_fifo = pic32_spi_tx_dword; in pic32_spi_set_word_size()
182 printf("pic32-spi: unsupported wordlen\n"); in pic32_spi_set_word_size()
183 return -EINVAL; in pic32_spi_set_word_size()
186 /* set bits-per-word */ in pic32_spi_set_word_size()
187 val = readl(&priv->regs->ctrl.raw); in pic32_spi_set_word_size()
190 writel(val, &priv->regs->ctrl.raw); in pic32_spi_set_word_size()
192 /* calculate maximum number of words fifo can hold */ in pic32_spi_set_word_size()
193 priv->fifo_n_word = DIV_ROUND_UP(priv->fifo_depth, wordlen / 8); in pic32_spi_set_word_size()
200 struct pic32_spi_priv *priv = dev_get_priv(slave->parent); in pic32_spi_claim_bus()
210 struct pic32_spi_priv *priv = dev_get_priv(slave->parent); in pic32_spi_release_bus()
220 if (!dm_gpio_is_valid(&priv->cs_gpio)) in spi_cs_activate()
223 dm_gpio_set_value(&priv->cs_gpio, 1); in spi_cs_activate()
228 if (!dm_gpio_is_valid(&priv->cs_gpio)) in spi_cs_deactivate()
231 dm_gpio_set_value(&priv->cs_gpio, 0); in spi_cs_deactivate()
239 struct udevice *bus = slave->parent; in pic32_spi_xfer()
249 bus->seq, slave_plat->cs, flags); in pic32_spi_xfer()
250 debug("msg tx %p, rx %p submitted of %d byte(s)\n", in pic32_spi_xfer()
258 priv->tx = tx_buf; in pic32_spi_xfer()
259 priv->rx = rx_buf; in pic32_spi_xfer()
260 priv->tx_end = priv->tx + len; in pic32_spi_xfer()
261 priv->rx_end = priv->rx + len; in pic32_spi_xfer()
262 priv->len = len; in pic32_spi_xfer()
267 priv->tx_fifo(priv); in pic32_spi_xfer()
268 priv->rx_fifo(priv); in pic32_spi_xfer()
271 if (priv->rx >= priv->rx_end) { in pic32_spi_xfer()
279 ret = -ETIMEDOUT; in pic32_spi_xfer()
296 debug("%s: %s, speed %u\n", __func__, bus->name, speed); in pic32_spi_set_speed()
298 /* div = [clk_in / (2 * spi_clk)] - 1 */ in pic32_spi_set_speed()
299 div = (priv->clk_rate / 2 / speed) - 1; in pic32_spi_set_speed()
301 writel(div, &priv->regs->baud.raw); in pic32_spi_set_speed()
303 priv->speed_hz = speed; in pic32_spi_set_speed()
313 debug("%s: %s, mode %d\n", __func__, bus->name, mode); in pic32_spi_set_mode()
315 /* set spi-clk mode */ in pic32_spi_set_mode()
316 val = readl(&priv->regs->ctrl.raw); in pic32_spi_set_mode()
323 /* TX at idle-to-active clk transition */ in pic32_spi_set_mode()
329 /* RX at end of tx */ in pic32_spi_set_mode()
331 writel(val, &priv->regs->ctrl.raw); in pic32_spi_set_mode()
333 priv->mode = mode; in pic32_spi_set_mode()
340 struct pic32_spi_priv *priv = dev_get_priv(slave->parent); in pic32_spi_set_wordlen()
352 val = readl(&priv->regs->ctrl); in pic32_spi_hw_init()
354 /* enable enhanced fifo of 128bit deep */ in pic32_spi_hw_init()
356 priv->fifo_depth = 16; in pic32_spi_hw_init()
370 writel(val, &priv->regs->ctrl); in pic32_spi_hw_init()
373 writel(PIC32_SPI_STAT_RX_OV, &priv->regs->status.clr); in pic32_spi_hw_init()
386 debug("%s: %d, bus: %i\n", __func__, __LINE__, bus->seq); in pic32_spi_probe()
387 addr = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size); in pic32_spi_probe()
389 return -EINVAL; in pic32_spi_probe()
391 priv->regs = ioremap(addr, size); in pic32_spi_probe()
392 if (!priv->regs) in pic32_spi_probe()
393 return -EINVAL; in pic32_spi_probe()
395 dm_spi->max_hz = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", in pic32_spi_probe()
400 printf("pic32-spi: error, clk not found\n"); in pic32_spi_probe()
403 priv->clk_rate = clk_get_periph_rate(clkdev, ret); in pic32_spi_probe()
412 * depending on fifo fill-level. /CS will stay asserted as long as in pic32_spi_probe()
413 * TX fifo is non-empty, else will be deasserted confirming completion in pic32_spi_probe()
415 * /CS manually by toggling cs-gpio pins. in pic32_spi_probe()
417 ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "cs-gpios", 0, in pic32_spi_probe()
418 &priv->cs_gpio, GPIOD_IS_OUT); in pic32_spi_probe()
420 printf("pic32-spi: error, cs-gpios not found\n"); in pic32_spi_probe()
437 { .compatible = "microchip,pic32mzda-spi" },