Lines Matching +full:fifo +full:- +full:depth
7 * drivers/spi/spi-dw.c, which is:
10 * SPDX-License-Identifier: GPL-2.0
13 #include <asm-generic/gpio.h>
91 s32 frequency; /* Default clock frequency, -1 for none */
102 struct gpio_desc cs_gpio; /* External chip-select gpio */
110 u32 fifo_len; /* depth of the FIFO buffer */
119 return __raw_readl(priv->regs + offset); in dw_read()
124 __raw_writel(val, priv->regs + offset); in dw_write()
134 ret = gpio_request_by_name(bus, "cs-gpio", 0, &priv->cs_gpio, 0); in request_gpio_cs()
135 if (ret == -ENOENT) in request_gpio_cs()
139 printf("Error: %d: Can't get %s gpio!\n", ret, bus->name); in request_gpio_cs()
143 if (dm_gpio_is_valid(&priv->cs_gpio)) { in request_gpio_cs()
144 dm_gpio_set_dir_flags(&priv->cs_gpio, in request_gpio_cs()
155 struct dw_spi_platdata *plat = bus->platdata; in dw_spi_ofdata_to_platdata()
156 const void *blob = gd->fdt_blob; in dw_spi_ofdata_to_platdata()
159 plat->regs = (struct dw_spi *)devfdt_get_addr(bus); in dw_spi_ofdata_to_platdata()
162 plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", in dw_spi_ofdata_to_platdata()
164 debug("%s: regs=%p max-frequency=%d\n", __func__, plat->regs, in dw_spi_ofdata_to_platdata()
165 plat->frequency); in dw_spi_ofdata_to_platdata()
175 /* Restart the controller, disable all interrupts, clean rx fifo */
183 * Try to detect the FIFO depth if not set by interface driver, in spi_hw_init()
184 * the depth could be from 2 to 256 from HW spec in spi_hw_init()
186 if (!priv->fifo_len) { in spi_hw_init()
187 u32 fifo; in spi_hw_init() local
189 for (fifo = 1; fifo < 256; fifo++) { in spi_hw_init()
190 dw_write(priv, DW_SPI_TXFLTR, fifo); in spi_hw_init()
191 if (fifo != dw_read(priv, DW_SPI_TXFLTR)) in spi_hw_init()
195 priv->fifo_len = (fifo == 1) ? 0 : fifo; in spi_hw_init()
198 debug("%s: fifo_len=%d\n", __func__, priv->fifo_len); in spi_hw_init()
211 ret = clk_get_by_index(bus, 0, &priv->clk); in dw_spi_get_clk()
215 ret = clk_enable(&priv->clk); in dw_spi_get_clk()
216 if (ret && ret != -ENOSYS && ret != -ENOTSUPP) in dw_spi_get_clk()
219 *rate = clk_get_rate(&priv->clk); in dw_spi_get_clk()
229 clk_disable(&priv->clk); in dw_spi_get_clk()
230 clk_free(&priv->clk); in dw_spi_get_clk()
232 return -EINVAL; in dw_spi_get_clk()
241 priv->regs = plat->regs; in dw_spi_probe()
242 priv->freq = plat->frequency; in dw_spi_probe()
244 ret = dw_spi_get_clk(bus, &priv->bus_clk_rate); in dw_spi_probe()
249 priv->bits_per_word = 8; in dw_spi_probe()
251 priv->tmode = 0; /* Tx & Rx */ in dw_spi_probe()
259 /* Return the max entries we can fill into tx fifo */
264 tx_left = (priv->tx_end - priv->tx) / (priv->bits_per_word >> 3); in tx_max()
265 tx_room = priv->fifo_len - dw_read(priv, DW_SPI_TXFLR); in tx_max()
269 * thought about using (priv->fifo_len - rxflr - txflr) as in tx_max()
271 * data which is out of tx/rx fifo and inside the in tx_max()
275 rxtx_gap = ((priv->rx_end - priv->rx) - (priv->tx_end - priv->tx)) / in tx_max()
276 (priv->bits_per_word >> 3); in tx_max()
278 return min3(tx_left, tx_room, (u32)(priv->fifo_len - rxtx_gap)); in tx_max()
281 /* Return the max entries we should read out of rx fifo */
284 u32 rx_left = (priv->rx_end - priv->rx) / (priv->bits_per_word >> 3); in rx_max()
294 while (max--) { in dw_writer()
296 if (priv->tx_end - priv->len) { in dw_writer()
297 if (priv->bits_per_word == 8) in dw_writer()
298 txw = *(u8 *)(priv->tx); in dw_writer()
300 txw = *(u16 *)(priv->tx); in dw_writer()
304 priv->tx += priv->bits_per_word >> 3; in dw_writer()
313 while (max--) { in dw_reader()
318 if (priv->rx_end - priv->len) { in dw_reader()
319 if (priv->bits_per_word == 8) in dw_reader()
320 *(u8 *)(priv->rx) = rxw; in dw_reader()
322 *(u16 *)(priv->rx) = rxw; in dw_reader()
324 priv->rx += priv->bits_per_word >> 3; in dw_reader()
333 } while (priv->rx_end > priv->rx); in poll_transfer()
341 struct dw_spi_priv *priv = dev_get_priv(dev->parent); in external_cs_manage()
343 if (!dm_gpio_is_valid(&priv->cs_gpio)) in external_cs_manage()
346 dm_gpio_set_value(&priv->cs_gpio, on ? 1 : 0); in external_cs_manage()
353 struct udevice *bus = dev->parent; in dw_spi_xfer()
365 return -1; in dw_spi_xfer()
372 cr0 = (priv->bits_per_word - 1) | (priv->type << SPI_FRF_OFFSET) | in dw_spi_xfer()
373 (priv->mode << SPI_MODE_OFFSET) | in dw_spi_xfer()
374 (priv->tmode << SPI_TMOD_OFFSET); in dw_spi_xfer()
377 priv->tmode = SPI_TMOD_TR; in dw_spi_xfer()
379 priv->tmode = SPI_TMOD_RO; in dw_spi_xfer()
382 * In transmit only mode (SPI_TMOD_TO) input FIFO never gets in dw_spi_xfer()
385 priv->tmode = SPI_TMOD_TR; in dw_spi_xfer()
388 cr0 |= (priv->tmode << SPI_TMOD_OFFSET); in dw_spi_xfer()
390 priv->len = bitlen >> 3; in dw_spi_xfer()
391 debug("%s: rx=%p tx=%p len=%d [bytes]\n", __func__, rx, tx, priv->len); in dw_spi_xfer()
393 priv->tx = (void *)tx; in dw_spi_xfer()
394 priv->tx_end = priv->tx + priv->len; in dw_spi_xfer()
395 priv->rx = rx; in dw_spi_xfer()
396 priv->rx_end = priv->rx + priv->len; in dw_spi_xfer()
422 * Otherwise if some data still exists in Tx FIFO it can be in dw_spi_xfer()
427 if (readl_poll_timeout(priv->regs + DW_SPI_SR, val, in dw_spi_xfer()
430 ret = -ETIMEDOUT; in dw_spi_xfer()
442 struct dw_spi_platdata *plat = bus->platdata; in dw_spi_set_speed()
446 if (speed > plat->frequency) in dw_spi_set_speed()
447 speed = plat->frequency; in dw_spi_set_speed()
453 clk_div = priv->bus_clk_rate / speed; in dw_spi_set_speed()
460 priv->freq = speed; in dw_spi_set_speed()
461 debug("%s: regs=%p speed=%d clk_div=%d\n", __func__, priv->regs, in dw_spi_set_speed()
462 priv->freq, clk_div); in dw_spi_set_speed()
476 priv->mode = mode; in dw_spi_set_mode()
477 debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode); in dw_spi_set_mode()
493 { .compatible = "snps,dw-apb-ssi" },