Lines Matching +full:clock +full:- +full:master
1 // SPDX-License-Identifier: GPL-2.0
2 // spi-uniphier.c - Socionext UniPhier SPI controller driver
4 // Copyright 2016-2018 Socionext Inc.
29 struct spi_master *master; member
113 val = readl(priv->base + SSI_IE); in uniphier_spi_irq_enable()
115 writel(val, priv->base + SSI_IE); in uniphier_spi_irq_enable()
123 val = readl(priv->base + SSI_IE); in uniphier_spi_irq_disable()
125 writel(val, priv->base + SSI_IE); in uniphier_spi_irq_disable()
130 struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); in uniphier_spi_set_mode()
134 * clock setting in uniphier_spi_set_mode()
136 * CKINIT clock initial level. 0:low, 1:high in uniphier_spi_set_mode()
137 * CKDLY clock delay. 0:no delay, 1:delay depending on FSTRT in uniphier_spi_set_mode()
138 * (FSTRT=0: 1 clock, FSTRT=1: 0.5 clock) in uniphier_spi_set_mode()
143 * 0: rising edge of clock, 1: falling edge of clock in uniphier_spi_set_mode()
145 switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { in uniphier_spi_set_mode()
168 if (!(spi->mode & SPI_CS_HIGH)) in uniphier_spi_set_mode()
171 writel(val1, priv->base + SSI_CKS); in uniphier_spi_set_mode()
172 writel(val2, priv->base + SSI_FPS); in uniphier_spi_set_mode()
175 if (spi->mode & SPI_LSB_FIRST) in uniphier_spi_set_mode()
177 writel(val1, priv->base + SSI_TXWDS); in uniphier_spi_set_mode()
178 writel(val1, priv->base + SSI_RXWDS); in uniphier_spi_set_mode()
183 struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); in uniphier_spi_set_transfer_size()
186 val = readl(priv->base + SSI_TXWDS); in uniphier_spi_set_transfer_size()
190 writel(val, priv->base + SSI_TXWDS); in uniphier_spi_set_transfer_size()
192 val = readl(priv->base + SSI_RXWDS); in uniphier_spi_set_transfer_size()
195 writel(val, priv->base + SSI_RXWDS); in uniphier_spi_set_transfer_size()
201 struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); in uniphier_spi_set_baudrate()
208 ckdiv = DIV_ROUND_UP(clk_get_rate(priv->clk), speed); in uniphier_spi_set_baudrate()
211 val = readl(priv->base + SSI_CKS); in uniphier_spi_set_baudrate()
214 writel(val, priv->base + SSI_CKS); in uniphier_spi_set_baudrate()
220 struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); in uniphier_spi_setup_transfer()
223 priv->error = 0; in uniphier_spi_setup_transfer()
224 priv->tx_buf = t->tx_buf; in uniphier_spi_setup_transfer()
225 priv->rx_buf = t->rx_buf; in uniphier_spi_setup_transfer()
226 priv->tx_bytes = priv->rx_bytes = t->len; in uniphier_spi_setup_transfer()
228 if (!priv->is_save_param || priv->mode != spi->mode) { in uniphier_spi_setup_transfer()
230 priv->mode = spi->mode; in uniphier_spi_setup_transfer()
231 priv->is_save_param = false; in uniphier_spi_setup_transfer()
234 if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) { in uniphier_spi_setup_transfer()
235 uniphier_spi_set_transfer_size(spi, t->bits_per_word); in uniphier_spi_setup_transfer()
236 priv->bits_per_word = t->bits_per_word; in uniphier_spi_setup_transfer()
239 if (!priv->is_save_param || priv->speed_hz != t->speed_hz) { in uniphier_spi_setup_transfer()
240 uniphier_spi_set_baudrate(spi, t->speed_hz); in uniphier_spi_setup_transfer()
241 priv->speed_hz = t->speed_hz; in uniphier_spi_setup_transfer()
244 priv->is_save_param = true; in uniphier_spi_setup_transfer()
248 writel(val, priv->base + SSI_FC); in uniphier_spi_setup_transfer()
256 wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes); in uniphier_spi_send()
257 priv->tx_bytes -= wsize; in uniphier_spi_send()
259 if (priv->tx_buf) { in uniphier_spi_send()
262 val = *priv->tx_buf; in uniphier_spi_send()
265 val = get_unaligned_le16(priv->tx_buf); in uniphier_spi_send()
268 val = get_unaligned_le32(priv->tx_buf); in uniphier_spi_send()
272 priv->tx_buf += wsize; in uniphier_spi_send()
275 writel(val, priv->base + SSI_TXDR); in uniphier_spi_send()
283 rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes); in uniphier_spi_recv()
284 priv->rx_bytes -= rsize; in uniphier_spi_recv()
286 val = readl(priv->base + SSI_RXDR); in uniphier_spi_recv()
288 if (priv->rx_buf) { in uniphier_spi_recv()
291 *priv->rx_buf = val; in uniphier_spi_recv()
294 put_unaligned_le16(val, priv->rx_buf); in uniphier_spi_recv()
297 put_unaligned_le32(val, priv->rx_buf); in uniphier_spi_recv()
301 priv->rx_buf += rsize; in uniphier_spi_recv()
310 val = readl(priv->base + SSI_FC); in uniphier_spi_set_fifo_threshold()
312 val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold); in uniphier_spi_set_fifo_threshold()
314 writel(val, priv->base + SSI_FC); in uniphier_spi_set_fifo_threshold()
320 unsigned int bpw = bytes_per_word(priv->bits_per_word); in uniphier_spi_fill_tx_fifo()
322 fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, bpw); in uniphier_spi_fill_tx_fifo()
327 fill_words = fifo_threshold - in uniphier_spi_fill_tx_fifo()
328 DIV_ROUND_UP(priv->rx_bytes - priv->tx_bytes, bpw); in uniphier_spi_fill_tx_fifo()
330 while (fill_words--) in uniphier_spi_fill_tx_fifo()
336 struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master); in uniphier_spi_set_cs()
339 val = readl(priv->base + SSI_FPS); in uniphier_spi_set_cs()
346 writel(val, priv->base + SSI_FPS); in uniphier_spi_set_cs()
349 static bool uniphier_spi_can_dma(struct spi_master *master, in uniphier_spi_can_dma() argument
353 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_can_dma()
354 unsigned int bpw = bytes_per_word(priv->bits_per_word); in uniphier_spi_can_dma()
356 if ((!master->dma_tx && !master->dma_rx) in uniphier_spi_can_dma()
357 || (!master->dma_tx && t->tx_buf) in uniphier_spi_can_dma()
358 || (!master->dma_rx && t->rx_buf)) in uniphier_spi_can_dma()
361 return DIV_ROUND_UP(t->len, bpw) > SSI_FIFO_DEPTH; in uniphier_spi_can_dma()
366 struct spi_master *master = data; in uniphier_spi_dma_rxcb() local
367 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_dma_rxcb()
368 int state = atomic_fetch_andnot(SSI_DMA_RX_BUSY, &priv->dma_busy); in uniphier_spi_dma_rxcb()
373 spi_finalize_current_transfer(master); in uniphier_spi_dma_rxcb()
378 struct spi_master *master = data; in uniphier_spi_dma_txcb() local
379 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_dma_txcb()
380 int state = atomic_fetch_andnot(SSI_DMA_TX_BUSY, &priv->dma_busy); in uniphier_spi_dma_txcb()
385 spi_finalize_current_transfer(master); in uniphier_spi_dma_txcb()
388 static int uniphier_spi_transfer_one_dma(struct spi_master *master, in uniphier_spi_transfer_one_dma() argument
392 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_transfer_one_dma()
396 atomic_set(&priv->dma_busy, 0); in uniphier_spi_transfer_one_dma()
400 if (priv->bits_per_word <= 8) in uniphier_spi_transfer_one_dma()
402 else if (priv->bits_per_word <= 16) in uniphier_spi_transfer_one_dma()
407 if (priv->rx_buf) { in uniphier_spi_transfer_one_dma()
410 .src_addr = priv->base_dma_addr + SSI_RXDR, in uniphier_spi_transfer_one_dma()
415 dmaengine_slave_config(master->dma_rx, &rxconf); in uniphier_spi_transfer_one_dma()
418 master->dma_rx, in uniphier_spi_transfer_one_dma()
419 t->rx_sg.sgl, t->rx_sg.nents, in uniphier_spi_transfer_one_dma()
424 rxdesc->callback = uniphier_spi_dma_rxcb; in uniphier_spi_transfer_one_dma()
425 rxdesc->callback_param = master; in uniphier_spi_transfer_one_dma()
428 atomic_or(SSI_DMA_RX_BUSY, &priv->dma_busy); in uniphier_spi_transfer_one_dma()
431 dma_async_issue_pending(master->dma_rx); in uniphier_spi_transfer_one_dma()
434 if (priv->tx_buf) { in uniphier_spi_transfer_one_dma()
437 .dst_addr = priv->base_dma_addr + SSI_TXDR, in uniphier_spi_transfer_one_dma()
442 dmaengine_slave_config(master->dma_tx, &txconf); in uniphier_spi_transfer_one_dma()
445 master->dma_tx, in uniphier_spi_transfer_one_dma()
446 t->tx_sg.sgl, t->tx_sg.nents, in uniphier_spi_transfer_one_dma()
451 txdesc->callback = uniphier_spi_dma_txcb; in uniphier_spi_transfer_one_dma()
452 txdesc->callback_param = master; in uniphier_spi_transfer_one_dma()
455 atomic_or(SSI_DMA_TX_BUSY, &priv->dma_busy); in uniphier_spi_transfer_one_dma()
458 dma_async_issue_pending(master->dma_tx); in uniphier_spi_transfer_one_dma()
462 return (priv->tx_buf || priv->rx_buf); in uniphier_spi_transfer_one_dma()
466 dmaengine_terminate_sync(master->dma_rx); in uniphier_spi_transfer_one_dma()
468 return -EINVAL; in uniphier_spi_transfer_one_dma()
471 static int uniphier_spi_transfer_one_irq(struct spi_master *master, in uniphier_spi_transfer_one_irq() argument
475 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_transfer_one_irq()
476 struct device *dev = master->dev.parent; in uniphier_spi_transfer_one_irq()
479 reinit_completion(&priv->xfer_done); in uniphier_spi_transfer_one_irq()
485 time_left = wait_for_completion_timeout(&priv->xfer_done, in uniphier_spi_transfer_one_irq()
492 return -ETIMEDOUT; in uniphier_spi_transfer_one_irq()
495 return priv->error; in uniphier_spi_transfer_one_irq()
498 static int uniphier_spi_transfer_one_poll(struct spi_master *master, in uniphier_spi_transfer_one_poll() argument
502 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_transfer_one_poll()
505 while (priv->tx_bytes) { in uniphier_spi_transfer_one_poll()
508 while ((priv->rx_bytes - priv->tx_bytes) > 0) { in uniphier_spi_transfer_one_poll()
509 while (!(readl(priv->base + SSI_SR) & SSI_SR_RNE) in uniphier_spi_transfer_one_poll()
510 && loop--) in uniphier_spi_transfer_one_poll()
513 if (loop == -1) in uniphier_spi_transfer_one_poll()
523 return uniphier_spi_transfer_one_irq(master, spi, t); in uniphier_spi_transfer_one_poll()
526 static int uniphier_spi_transfer_one(struct spi_master *master, in uniphier_spi_transfer_one() argument
530 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_transfer_one()
535 if (!t->len) in uniphier_spi_transfer_one()
540 use_dma = master->can_dma ? master->can_dma(master, spi, t) : false; in uniphier_spi_transfer_one()
542 return uniphier_spi_transfer_one_dma(master, spi, t); in uniphier_spi_transfer_one()
548 threshold = DIV_ROUND_UP(SSI_POLL_TIMEOUT_US * priv->speed_hz, in uniphier_spi_transfer_one()
550 if (t->len > threshold) in uniphier_spi_transfer_one()
551 return uniphier_spi_transfer_one_irq(master, spi, t); in uniphier_spi_transfer_one()
553 return uniphier_spi_transfer_one_poll(master, spi, t); in uniphier_spi_transfer_one()
556 static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master) in uniphier_spi_prepare_transfer_hardware() argument
558 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_prepare_transfer_hardware()
560 writel(SSI_CTL_EN, priv->base + SSI_CTL); in uniphier_spi_prepare_transfer_hardware()
565 static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master) in uniphier_spi_unprepare_transfer_hardware() argument
567 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_unprepare_transfer_hardware()
569 writel(0, priv->base + SSI_CTL); in uniphier_spi_unprepare_transfer_hardware()
574 static void uniphier_spi_handle_err(struct spi_master *master, in uniphier_spi_handle_err() argument
577 struct uniphier_spi_priv *priv = spi_master_get_devdata(master); in uniphier_spi_handle_err()
581 writel(0, priv->base + SSI_CTL); in uniphier_spi_handle_err()
585 writel(val, priv->base + SSI_FC); in uniphier_spi_handle_err()
589 if (atomic_read(&priv->dma_busy) & SSI_DMA_TX_BUSY) { in uniphier_spi_handle_err()
590 dmaengine_terminate_async(master->dma_tx); in uniphier_spi_handle_err()
591 atomic_andnot(SSI_DMA_TX_BUSY, &priv->dma_busy); in uniphier_spi_handle_err()
594 if (atomic_read(&priv->dma_busy) & SSI_DMA_RX_BUSY) { in uniphier_spi_handle_err()
595 dmaengine_terminate_async(master->dma_rx); in uniphier_spi_handle_err()
596 atomic_andnot(SSI_DMA_RX_BUSY, &priv->dma_busy); in uniphier_spi_handle_err()
605 stat = readl(priv->base + SSI_IS); in uniphier_spi_handler()
607 writel(val, priv->base + SSI_IC); in uniphier_spi_handler()
611 priv->error = -EIO; in uniphier_spi_handler()
617 while ((readl(priv->base + SSI_SR) & SSI_SR_RNE) && in uniphier_spi_handler()
618 (priv->rx_bytes - priv->tx_bytes) > 0) in uniphier_spi_handler()
621 if ((readl(priv->base + SSI_SR) & SSI_SR_RNE) || in uniphier_spi_handler()
622 (priv->rx_bytes != priv->tx_bytes)) { in uniphier_spi_handler()
623 priv->error = -EIO; in uniphier_spi_handler()
625 } else if (priv->rx_bytes == 0) in uniphier_spi_handler()
637 complete(&priv->xfer_done); in uniphier_spi_handler()
644 struct spi_master *master; in uniphier_spi_probe() local
652 master = spi_alloc_master(&pdev->dev, sizeof(*priv)); in uniphier_spi_probe()
653 if (!master) in uniphier_spi_probe()
654 return -ENOMEM; in uniphier_spi_probe()
656 platform_set_drvdata(pdev, master); in uniphier_spi_probe()
658 priv = spi_master_get_devdata(master); in uniphier_spi_probe()
659 priv->master = master; in uniphier_spi_probe()
660 priv->is_save_param = false; in uniphier_spi_probe()
662 priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in uniphier_spi_probe()
663 if (IS_ERR(priv->base)) { in uniphier_spi_probe()
664 ret = PTR_ERR(priv->base); in uniphier_spi_probe()
667 priv->base_dma_addr = res->start; in uniphier_spi_probe()
669 priv->clk = devm_clk_get(&pdev->dev, NULL); in uniphier_spi_probe()
670 if (IS_ERR(priv->clk)) { in uniphier_spi_probe()
671 dev_err(&pdev->dev, "failed to get clock\n"); in uniphier_spi_probe()
672 ret = PTR_ERR(priv->clk); in uniphier_spi_probe()
676 ret = clk_prepare_enable(priv->clk); in uniphier_spi_probe()
686 ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler, in uniphier_spi_probe()
687 0, "uniphier-spi", priv); in uniphier_spi_probe()
689 dev_err(&pdev->dev, "failed to request IRQ\n"); in uniphier_spi_probe()
693 init_completion(&priv->xfer_done); in uniphier_spi_probe()
695 clk_rate = clk_get_rate(priv->clk); in uniphier_spi_probe()
697 master->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER); in uniphier_spi_probe()
698 master->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER); in uniphier_spi_probe()
699 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; in uniphier_spi_probe()
700 master->dev.of_node = pdev->dev.of_node; in uniphier_spi_probe()
701 master->bus_num = pdev->id; in uniphier_spi_probe()
702 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); in uniphier_spi_probe()
704 master->set_cs = uniphier_spi_set_cs; in uniphier_spi_probe()
705 master->transfer_one = uniphier_spi_transfer_one; in uniphier_spi_probe()
706 master->prepare_transfer_hardware in uniphier_spi_probe()
708 master->unprepare_transfer_hardware in uniphier_spi_probe()
710 master->handle_err = uniphier_spi_handle_err; in uniphier_spi_probe()
711 master->can_dma = uniphier_spi_can_dma; in uniphier_spi_probe()
713 master->num_chipselect = 1; in uniphier_spi_probe()
714 master->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX; in uniphier_spi_probe()
716 master->dma_tx = dma_request_chan(&pdev->dev, "tx"); in uniphier_spi_probe()
717 if (IS_ERR_OR_NULL(master->dma_tx)) { in uniphier_spi_probe()
718 if (PTR_ERR(master->dma_tx) == -EPROBE_DEFER) { in uniphier_spi_probe()
719 ret = -EPROBE_DEFER; in uniphier_spi_probe()
722 master->dma_tx = NULL; in uniphier_spi_probe()
725 ret = dma_get_slave_caps(master->dma_tx, &caps); in uniphier_spi_probe()
727 dev_err(&pdev->dev, "failed to get TX DMA capacities: %d\n", in uniphier_spi_probe()
734 master->dma_rx = dma_request_chan(&pdev->dev, "rx"); in uniphier_spi_probe()
735 if (IS_ERR_OR_NULL(master->dma_rx)) { in uniphier_spi_probe()
736 if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) { in uniphier_spi_probe()
737 ret = -EPROBE_DEFER; in uniphier_spi_probe()
740 master->dma_rx = NULL; in uniphier_spi_probe()
743 ret = dma_get_slave_caps(master->dma_rx, &caps); in uniphier_spi_probe()
745 dev_err(&pdev->dev, "failed to get RX DMA capacities: %d\n", in uniphier_spi_probe()
752 master->max_dma_len = min(dma_tx_burst, dma_rx_burst); in uniphier_spi_probe()
754 ret = devm_spi_register_master(&pdev->dev, master); in uniphier_spi_probe()
761 clk_disable_unprepare(priv->clk); in uniphier_spi_probe()
764 spi_master_put(master); in uniphier_spi_probe()
772 if (priv->master->dma_tx) in uniphier_spi_remove()
773 dma_release_channel(priv->master->dma_tx); in uniphier_spi_remove()
774 if (priv->master->dma_rx) in uniphier_spi_remove()
775 dma_release_channel(priv->master->dma_rx); in uniphier_spi_remove()
777 clk_disable_unprepare(priv->clk); in uniphier_spi_remove()
783 { .compatible = "socionext,uniphier-scssi" },
792 .name = "uniphier-spi",