Lines Matching +full:tx +full:- +full:fifo +full:- +full:max +full:- +full:num

1 // SPDX-License-Identifier: GPL-2.0-only
8 // This code is based on spi-dw-core.c.
26 #define HISI_SPI_FIFOC 0x0c /* fifo level control register */
57 #define SR_TXE BIT(0) /* Transmit FIFO empty */
58 #define SR_TXNF BIT(1) /* Transmit FIFO not full */
59 #define SR_RXNE BIT(2) /* Receive FIFO not empty */
60 #define SR_RXF BIT(3) /* Receive FIFO full */
129 u32 fifo_len; /* depth of the FIFO buffer */
132 const void *tx; member
167 host = container_of(hs->dev, struct spi_controller, dev); in hisi_spi_debugfs_init()
168 snprintf(name, 32, "hisi_spi%d", host->bus_num); in hisi_spi_debugfs_init()
169 hs->debugfs = debugfs_create_dir(name, NULL); in hisi_spi_debugfs_init()
170 if (IS_ERR(hs->debugfs)) in hisi_spi_debugfs_init()
171 return -ENOMEM; in hisi_spi_debugfs_init()
173 hs->regset.regs = hisi_spi_regs; in hisi_spi_debugfs_init()
174 hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs); in hisi_spi_debugfs_init()
175 hs->regset.base = hs->regs; in hisi_spi_debugfs_init()
176 debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset); in hisi_spi_debugfs_init()
183 return readl(hs->regs + HISI_SPI_SR) & SR_BUSY; in hisi_spi_busy()
188 return readl(hs->regs + HISI_SPI_SR) & SR_RXNE; in hisi_spi_rx_not_empty()
193 return readl(hs->regs + HISI_SPI_SR) & SR_TXNF; in hisi_spi_tx_not_full()
202 readl(hs->regs + HISI_SPI_DOUT); in hisi_spi_flush_fifo()
203 } while (hisi_spi_busy(hs) && limit--); in hisi_spi_flush_fifo()
209 writel(0, hs->regs + HISI_SPI_ENR); in hisi_spi_disable()
210 writel(IMR_MASK, hs->regs + HISI_SPI_IMR); in hisi_spi_disable()
211 writel(ICR_MASK, hs->regs + HISI_SPI_ICR); in hisi_spi_disable()
216 if (transfer->bits_per_word <= 8) in hisi_spi_n_bytes()
218 else if (transfer->bits_per_word <= 16) in hisi_spi_n_bytes()
226 u32 max = min_t(u32, hs->rx_len, hs->fifo_len); in hisi_spi_reader() local
229 while (hisi_spi_rx_not_empty(hs) && max--) { in hisi_spi_reader()
230 rxw = readl(hs->regs + HISI_SPI_DOUT); in hisi_spi_reader()
232 if (hs->rx) { in hisi_spi_reader()
233 switch (hs->n_bytes) { in hisi_spi_reader()
235 *(u8 *)(hs->rx) = rxw; in hisi_spi_reader()
238 *(u16 *)(hs->rx) = rxw; in hisi_spi_reader()
241 *(u32 *)(hs->rx) = rxw; in hisi_spi_reader()
244 hs->rx += hs->n_bytes; in hisi_spi_reader()
246 --hs->rx_len; in hisi_spi_reader()
252 u32 max = min_t(u32, hs->tx_len, hs->fifo_len); in hisi_spi_writer() local
255 while (hisi_spi_tx_not_full(hs) && max--) { in hisi_spi_writer()
256 /* Check the transfer's original "tx" is not null */ in hisi_spi_writer()
257 if (hs->tx) { in hisi_spi_writer()
258 switch (hs->n_bytes) { in hisi_spi_writer()
260 txw = *(u8 *)(hs->tx); in hisi_spi_writer()
263 txw = *(u16 *)(hs->tx); in hisi_spi_writer()
266 txw = *(u32 *)(hs->tx); in hisi_spi_writer()
269 hs->tx += hs->n_bytes; in hisi_spi_writer()
271 writel(txw, hs->regs + HISI_SPI_DIN); in hisi_spi_writer()
272 --hs->tx_len; in hisi_spi_writer()
278 chip->div_pre = DIV_PRE_MAX; in __hisi_calc_div_reg()
279 while (chip->div_pre >= DIV_PRE_MIN) { in __hisi_calc_div_reg()
280 if (chip->clk_div % chip->div_pre == 0) in __hisi_calc_div_reg()
283 chip->div_pre -= 2; in __hisi_calc_div_reg()
286 if (chip->div_pre > chip->clk_div) in __hisi_calc_div_reg()
287 chip->div_pre = chip->clk_div; in __hisi_calc_div_reg()
289 chip->div_post = (chip->clk_div / chip->div_pre) - 1; in __hisi_calc_div_reg()
298 chip->clk_div = DIV_ROUND_UP(host->max_speed_hz, speed_hz) + 1; in hisi_calc_effective_speed()
299 chip->clk_div &= 0xfffe; in hisi_calc_effective_speed()
300 if (chip->clk_div > CLK_DIV_MAX) in hisi_calc_effective_speed()
301 chip->clk_div = CLK_DIV_MAX; in hisi_calc_effective_speed()
303 effective_speed = host->max_speed_hz / chip->clk_div; in hisi_calc_effective_speed()
304 if (chip->speed_hz != effective_speed) { in hisi_calc_effective_speed()
306 chip->speed_hz = effective_speed; in hisi_calc_effective_speed()
316 cr |= FIELD_PREP(CR_CPHA_MASK, (spi->mode & SPI_CPHA) ? 1 : 0); in hisi_spi_prepare_cr()
317 cr |= FIELD_PREP(CR_CPOL_MASK, (spi->mode & SPI_CPOL) ? 1 : 0); in hisi_spi_prepare_cr()
318 cr |= FIELD_PREP(CR_LOOP_MASK, (spi->mode & SPI_LOOP) ? 1 : 0); in hisi_spi_prepare_cr()
327 /* FIFO default config */ in hisi_spi_hw_init()
330 hs->regs + HISI_SPI_FIFOC); in hisi_spi_hw_init()
332 hs->fifo_len = 256; in hisi_spi_hw_init()
339 u32 irq_status = readl(hs->regs + HISI_SPI_ISR) & ISR_MASK; in hisi_spi_irq()
344 if (!host->cur_msg) in hisi_spi_irq()
349 dev_err(hs->dev, "interrupt_transfer: fifo overflow\n"); in hisi_spi_irq()
350 host->cur_msg->status = -EIO; in hisi_spi_irq()
355 * Read data from the Rx FIFO every time. If there is in hisi_spi_irq()
359 if (!hs->rx_len) in hisi_spi_irq()
362 /* Send data out when Tx FIFO IRQ triggered */ in hisi_spi_irq()
379 u32 cr = chip->cr; in hisi_spi_transfer_one()
382 transfer->effective_speed_hz = in hisi_spi_transfer_one()
383 hisi_calc_effective_speed(host, chip, transfer->speed_hz); in hisi_spi_transfer_one()
384 cr |= FIELD_PREP(CR_DIV_PRE_MASK, chip->div_pre); in hisi_spi_transfer_one()
385 cr |= FIELD_PREP(CR_DIV_POST_MASK, chip->div_post); in hisi_spi_transfer_one()
386 cr |= FIELD_PREP(CR_BPW_MASK, transfer->bits_per_word - 1); in hisi_spi_transfer_one()
387 writel(cr, hs->regs + HISI_SPI_CR); in hisi_spi_transfer_one()
391 hs->n_bytes = hisi_spi_n_bytes(transfer); in hisi_spi_transfer_one()
392 hs->tx = transfer->tx_buf; in hisi_spi_transfer_one()
393 hs->tx_len = transfer->len / hs->n_bytes; in hisi_spi_transfer_one()
394 hs->rx = transfer->rx_buf; in hisi_spi_transfer_one()
395 hs->rx_len = hs->tx_len; in hisi_spi_transfer_one()
404 writel(~(u32)IMR_MASK, hs->regs + HISI_SPI_IMR); in hisi_spi_transfer_one()
405 writel(1, hs->regs + HISI_SPI_ENR); in hisi_spi_transfer_one()
433 return -ENOMEM; in hisi_spi_setup()
437 chip->cr = hisi_spi_prepare_cr(spi); in hisi_spi_setup()
452 struct device *dev = &pdev->dev; in hisi_spi_probe()
463 return -ENOMEM; in hisi_spi_probe()
468 hs->dev = dev; in hisi_spi_probe()
469 hs->irq = irq; in hisi_spi_probe()
471 hs->regs = devm_platform_ioremap_resource(pdev, 0); in hisi_spi_probe()
472 if (IS_ERR(hs->regs)) in hisi_spi_probe()
473 return PTR_ERR(hs->regs); in hisi_spi_probe()
476 ret = device_property_read_u32(dev, "spi-max-frequency", in hisi_spi_probe()
477 &host->max_speed_hz); in hisi_spi_probe()
479 dev_err(dev, "failed to get max SPI clocking speed, ret=%d\n", in hisi_spi_probe()
481 return -EINVAL; in hisi_spi_probe()
484 if (host->max_speed_hz == 0) in hisi_spi_probe()
485 return dev_err_probe(dev, -EINVAL, "spi-max-frequency can't be 0\n"); in hisi_spi_probe()
487 ret = device_property_read_u16(dev, "num-cs", in hisi_spi_probe()
488 &host->num_chipselect); in hisi_spi_probe()
490 host->num_chipselect = DEFAULT_NUM_CS; in hisi_spi_probe()
492 host->use_gpio_descriptors = true; in hisi_spi_probe()
493 host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; in hisi_spi_probe()
494 host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); in hisi_spi_probe()
495 host->bus_num = pdev->id; in hisi_spi_probe()
496 host->setup = hisi_spi_setup; in hisi_spi_probe()
497 host->cleanup = hisi_spi_cleanup; in hisi_spi_probe()
498 host->transfer_one = hisi_spi_transfer_one; in hisi_spi_probe()
499 host->handle_err = hisi_spi_handle_err; in hisi_spi_probe()
500 host->dev.fwnode = dev->fwnode; in hisi_spi_probe()
501 host->min_speed_hz = DIV_ROUND_UP(host->max_speed_hz, CLK_DIV_MAX); in hisi_spi_probe()
505 ret = devm_request_irq(dev, hs->irq, hisi_spi_irq, 0, dev_name(dev), in hisi_spi_probe()
508 dev_err(dev, "failed to get IRQ=%d, ret=%d\n", hs->irq, ret); in hisi_spi_probe()
521 dev_info(dev, "hw version:0x%x max-freq:%u kHz\n", in hisi_spi_probe()
522 readl(hs->regs + HISI_SPI_VERSION), in hisi_spi_probe()
523 host->max_speed_hz / 1000); in hisi_spi_probe()
533 debugfs_remove_recursive(hs->debugfs); in hisi_spi_remove()
547 .name = "hisi-kunpeng-spi",