Lines Matching +full:exynos5433 +full:- +full:spi

1 // SPDX-License-Identifier: GPL-2.0+
11 #include <linux/dma-mapping.h>
15 #include <linux/spi/spi.h>
18 #include <linux/platform_data/spi-s3c64xx.h>
24 /* Registers and bit-fields */
106 #define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
108 (1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
110 #define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
121 #define is_polling(x) (x->cntrlr_info->polling)
133 * struct s3c64xx_spi_port_config - SPI Controller hardware info
134 * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
145 * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
146 * differ in some aspects such as the size of the fifo and spi bus clock
163 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
164 * @clk: Pointer to the spi clock.
165 * @src_clk: Pointer to the clock used to generate SPI signals.
168 * @host: Pointer to the SPI Protocol host.
172 * @sfr_start: BUS address of SPI controller regs.
180 * @port_conf: Local SPI port configuartion data
205 void __iomem *regs = sdd->regs; in s3c64xx_flush_fifo()
224 } while (TX_FIFO_LVL(val, sdd) && loops--); in s3c64xx_flush_fifo()
227 dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); in s3c64xx_flush_fifo()
237 } while (loops--); in s3c64xx_flush_fifo()
240 dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); in s3c64xx_flush_fifo()
257 if (dma->direction == DMA_DEV_TO_MEM) in s3c64xx_spi_dmacb()
264 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_dmacb()
266 if (dma->direction == DMA_DEV_TO_MEM) { in s3c64xx_spi_dmacb()
267 sdd->state &= ~RXBUSY; in s3c64xx_spi_dmacb()
268 if (!(sdd->state & TXBUSY)) in s3c64xx_spi_dmacb()
269 complete(&sdd->xfer_completion); in s3c64xx_spi_dmacb()
271 sdd->state &= ~TXBUSY; in s3c64xx_spi_dmacb()
272 if (!(sdd->state & RXBUSY)) in s3c64xx_spi_dmacb()
273 complete(&sdd->xfer_completion); in s3c64xx_spi_dmacb()
276 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_dmacb()
289 if (dma->direction == DMA_DEV_TO_MEM) { in prepare_dma()
292 config.direction = dma->direction; in prepare_dma()
293 config.src_addr = sdd->sfr_start + S3C64XX_SPI_RX_DATA; in prepare_dma()
294 config.src_addr_width = sdd->cur_bpw / 8; in prepare_dma()
296 dmaengine_slave_config(dma->ch, &config); in prepare_dma()
300 config.direction = dma->direction; in prepare_dma()
301 config.dst_addr = sdd->sfr_start + S3C64XX_SPI_TX_DATA; in prepare_dma()
302 config.dst_addr_width = sdd->cur_bpw / 8; in prepare_dma()
304 dmaengine_slave_config(dma->ch, &config); in prepare_dma()
307 desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, in prepare_dma()
308 dma->direction, DMA_PREP_INTERRUPT); in prepare_dma()
310 dev_err(&sdd->pdev->dev, "unable to prepare %s scatterlist", in prepare_dma()
311 dma->direction == DMA_DEV_TO_MEM ? "rx" : "tx"); in prepare_dma()
312 return -ENOMEM; in prepare_dma()
315 desc->callback = s3c64xx_spi_dmacb; in prepare_dma()
316 desc->callback_param = dma; in prepare_dma()
318 dma->cookie = dmaengine_submit(desc); in prepare_dma()
319 ret = dma_submit_error(dma->cookie); in prepare_dma()
321 dev_err(&sdd->pdev->dev, "DMA submission failed"); in prepare_dma()
322 return -EIO; in prepare_dma()
325 dma_async_issue_pending(dma->ch); in prepare_dma()
329 static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable) in s3c64xx_spi_set_cs() argument
332 spi_controller_get_devdata(spi->controller); in s3c64xx_spi_set_cs()
334 if (sdd->cntrlr_info->no_cs) in s3c64xx_spi_set_cs()
338 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) { in s3c64xx_spi_set_cs()
339 writel(0, sdd->regs + S3C64XX_SPI_CS_REG); in s3c64xx_spi_set_cs()
341 u32 ssel = readl(sdd->regs + S3C64XX_SPI_CS_REG); in s3c64xx_spi_set_cs()
345 writel(ssel, sdd->regs + S3C64XX_SPI_CS_REG); in s3c64xx_spi_set_cs()
348 if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) in s3c64xx_spi_set_cs()
350 sdd->regs + S3C64XX_SPI_CS_REG); in s3c64xx_spi_set_cs()
354 static int s3c64xx_spi_prepare_transfer(struct spi_controller *spi) in s3c64xx_spi_prepare_transfer() argument
356 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(spi); in s3c64xx_spi_prepare_transfer()
362 sdd->rx_dma.ch = dma_request_chan(&sdd->pdev->dev, "rx"); in s3c64xx_spi_prepare_transfer()
363 if (IS_ERR(sdd->rx_dma.ch)) { in s3c64xx_spi_prepare_transfer()
364 dev_err(&sdd->pdev->dev, "Failed to get RX DMA channel\n"); in s3c64xx_spi_prepare_transfer()
365 sdd->rx_dma.ch = NULL; in s3c64xx_spi_prepare_transfer()
369 sdd->tx_dma.ch = dma_request_chan(&sdd->pdev->dev, "tx"); in s3c64xx_spi_prepare_transfer()
370 if (IS_ERR(sdd->tx_dma.ch)) { in s3c64xx_spi_prepare_transfer()
371 dev_err(&sdd->pdev->dev, "Failed to get TX DMA channel\n"); in s3c64xx_spi_prepare_transfer()
372 dma_release_channel(sdd->rx_dma.ch); in s3c64xx_spi_prepare_transfer()
373 sdd->tx_dma.ch = NULL; in s3c64xx_spi_prepare_transfer()
374 sdd->rx_dma.ch = NULL; in s3c64xx_spi_prepare_transfer()
378 spi->dma_rx = sdd->rx_dma.ch; in s3c64xx_spi_prepare_transfer()
379 spi->dma_tx = sdd->tx_dma.ch; in s3c64xx_spi_prepare_transfer()
384 static int s3c64xx_spi_unprepare_transfer(struct spi_controller *spi) in s3c64xx_spi_unprepare_transfer() argument
386 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(spi); in s3c64xx_spi_unprepare_transfer()
392 if (sdd->rx_dma.ch && sdd->tx_dma.ch) { in s3c64xx_spi_unprepare_transfer()
393 dma_release_channel(sdd->rx_dma.ch); in s3c64xx_spi_unprepare_transfer()
394 dma_release_channel(sdd->tx_dma.ch); in s3c64xx_spi_unprepare_transfer()
395 sdd->rx_dma.ch = NULL; in s3c64xx_spi_unprepare_transfer()
396 sdd->tx_dma.ch = NULL; in s3c64xx_spi_unprepare_transfer()
403 struct spi_device *spi, in s3c64xx_spi_can_dma() argument
408 if (sdd->rx_dma.ch && sdd->tx_dma.ch) { in s3c64xx_spi_can_dma()
409 return xfer->len > (FIFO_LVL_MASK(sdd) >> 1) + 1; in s3c64xx_spi_can_dma()
419 void __iomem *regs = sdd->regs; in s3c64xx_enable_datapath()
437 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) in s3c64xx_enable_datapath()
442 if (xfer->tx_buf != NULL) { in s3c64xx_enable_datapath()
443 sdd->state |= TXBUSY; in s3c64xx_enable_datapath()
447 ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg); in s3c64xx_enable_datapath()
449 switch (sdd->cur_bpw) { in s3c64xx_enable_datapath()
452 xfer->tx_buf, xfer->len / 4); in s3c64xx_enable_datapath()
456 xfer->tx_buf, xfer->len / 2); in s3c64xx_enable_datapath()
460 xfer->tx_buf, xfer->len); in s3c64xx_enable_datapath()
466 if (xfer->rx_buf != NULL) { in s3c64xx_enable_datapath()
467 sdd->state |= RXBUSY; in s3c64xx_enable_datapath()
469 if (sdd->port_conf->high_speed && sdd->cur_speed >= 30000000UL in s3c64xx_enable_datapath()
470 && !(sdd->cur_mode & SPI_CPHA)) in s3c64xx_enable_datapath()
476 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) in s3c64xx_enable_datapath()
479 ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg); in s3c64xx_enable_datapath()
495 void __iomem *regs = sdd->regs; in s3c64xx_spi_wait_for_timeout()
507 } while (RX_FIFO_LVL(status, sdd) < max_fifo && --val); in s3c64xx_spi_wait_for_timeout()
516 void __iomem *regs = sdd->regs; in s3c64xx_wait_for_dma()
522 ms = xfer->len * 8 * 1000 / sdd->cur_speed; in s3c64xx_wait_for_dma()
527 val = wait_for_completion_timeout(&sdd->xfer_completion, val); in s3c64xx_wait_for_dma()
531 * proceed further else return -EIO. in s3c64xx_wait_for_dma()
538 if (val && !xfer->rx_buf) { in s3c64xx_wait_for_dma()
543 && --val) { in s3c64xx_wait_for_dma()
552 return -EIO; in s3c64xx_wait_for_dma()
560 void __iomem *regs = sdd->regs; in s3c64xx_wait_for_pio()
570 time_us = (xfer->len * 8 * 1000 * 1000) / sdd->cur_speed; in s3c64xx_wait_for_pio()
576 if (RX_FIFO_LVL(status, sdd) < xfer->len) in s3c64xx_wait_for_pio()
581 if (!wait_for_completion_timeout(&sdd->xfer_completion, val)) in s3c64xx_wait_for_pio()
582 return -EIO; in s3c64xx_wait_for_pio()
588 } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); in s3c64xx_wait_for_pio()
591 return -EIO; in s3c64xx_wait_for_pio()
594 if (!xfer->rx_buf) { in s3c64xx_wait_for_pio()
595 sdd->state &= ~TXBUSY; in s3c64xx_wait_for_pio()
607 loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1); in s3c64xx_wait_for_pio()
608 buf = xfer->rx_buf; in s3c64xx_wait_for_pio()
614 switch (sdd->cur_bpw) { in s3c64xx_wait_for_pio()
630 } while (loops--); in s3c64xx_wait_for_pio()
631 sdd->state &= ~RXBUSY; in s3c64xx_wait_for_pio()
638 void __iomem *regs = sdd->regs; in s3c64xx_spi_config()
641 int div = sdd->port_conf->clk_div; in s3c64xx_spi_config()
644 if (!sdd->port_conf->clk_from_cmu) { in s3c64xx_spi_config()
656 if (sdd->cur_mode & SPI_CPOL) in s3c64xx_spi_config()
659 if (sdd->cur_mode & SPI_CPHA) in s3c64xx_spi_config()
669 switch (sdd->cur_bpw) { in s3c64xx_spi_config()
684 if ((sdd->cur_mode & SPI_LOOP) && sdd->port_conf->has_loopback) in s3c64xx_spi_config()
691 if (sdd->port_conf->clk_from_cmu) { in s3c64xx_spi_config()
692 ret = clk_set_rate(sdd->src_clk, sdd->cur_speed * div); in s3c64xx_spi_config()
695 sdd->cur_speed = clk_get_rate(sdd->src_clk) / div; in s3c64xx_spi_config()
700 val |= ((clk_get_rate(sdd->src_clk) / sdd->cur_speed / div - 1) in s3c64xx_spi_config()
719 struct spi_device *spi = msg->spi; in s3c64xx_spi_prepare_message() local
720 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in s3c64xx_spi_prepare_message()
725 writel(0, sdd->regs + S3C64XX_SPI_FB_CLK); in s3c64xx_spi_prepare_message()
727 writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); in s3c64xx_spi_prepare_message()
732 static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi) in s3c64xx_spi_max_transfer_size() argument
734 struct spi_controller *ctlr = spi->controller; in s3c64xx_spi_max_transfer_size()
736 return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX; in s3c64xx_spi_max_transfer_size()
740 struct spi_device *spi, in s3c64xx_spi_transfer_one() argument
757 reinit_completion(&sdd->xfer_completion); in s3c64xx_spi_transfer_one()
760 bpw = xfer->bits_per_word; in s3c64xx_spi_transfer_one()
761 speed = xfer->speed_hz; in s3c64xx_spi_transfer_one()
763 if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { in s3c64xx_spi_transfer_one()
764 sdd->cur_bpw = bpw; in s3c64xx_spi_transfer_one()
765 sdd->cur_speed = speed; in s3c64xx_spi_transfer_one()
766 sdd->cur_mode = spi->mode; in s3c64xx_spi_transfer_one()
772 if (!is_polling(sdd) && (xfer->len > fifo_len) && in s3c64xx_spi_transfer_one()
773 sdd->rx_dma.ch && sdd->tx_dma.ch) { in s3c64xx_spi_transfer_one()
776 } else if (xfer->len >= fifo_len) { in s3c64xx_spi_transfer_one()
777 tx_buf = xfer->tx_buf; in s3c64xx_spi_transfer_one()
778 rx_buf = xfer->rx_buf; in s3c64xx_spi_transfer_one()
779 origin_len = xfer->len; in s3c64xx_spi_transfer_one()
780 target_len = xfer->len; in s3c64xx_spi_transfer_one()
781 xfer->len = fifo_len - 1; in s3c64xx_spi_transfer_one()
786 if (!use_dma && xfer->len > S3C64XX_SPI_POLLING_SIZE) in s3c64xx_spi_transfer_one()
790 reinit_completion(&sdd->xfer_completion); in s3c64xx_spi_transfer_one()
792 rdy_lv = xfer->len; in s3c64xx_spi_transfer_one()
795 * fifo_lvl up to 64 byte -> N bytes in s3c64xx_spi_transfer_one()
796 * 128 byte -> RDY_LVL * 2 bytes in s3c64xx_spi_transfer_one()
797 * 256 byte -> RDY_LVL * 4 bytes in s3c64xx_spi_transfer_one()
804 val = readl(sdd->regs + S3C64XX_SPI_MODE_CFG); in s3c64xx_spi_transfer_one()
807 writel(val, sdd->regs + S3C64XX_SPI_MODE_CFG); in s3c64xx_spi_transfer_one()
810 val = readl(sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_transfer_one()
812 sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_transfer_one()
816 spin_lock_irqsave(&sdd->lock, flags); in s3c64xx_spi_transfer_one()
819 sdd->state &= ~RXBUSY; in s3c64xx_spi_transfer_one()
820 sdd->state &= ~TXBUSY; in s3c64xx_spi_transfer_one()
823 s3c64xx_spi_set_cs(spi, true); in s3c64xx_spi_transfer_one()
827 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_transfer_one()
830 dev_err(&spi->dev, "failed to enable data path for transfer: %d\n", status); in s3c64xx_spi_transfer_one()
840 dev_err(&spi->dev, in s3c64xx_spi_transfer_one()
841 "I/O Error: rx-%d tx-%d rx-%c tx-%c len-%d dma-%d res-(%d)\n", in s3c64xx_spi_transfer_one()
842 xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, in s3c64xx_spi_transfer_one()
843 (sdd->state & RXBUSY) ? 'f' : 'p', in s3c64xx_spi_transfer_one()
844 (sdd->state & TXBUSY) ? 'f' : 'p', in s3c64xx_spi_transfer_one()
845 xfer->len, use_dma ? 1 : 0, status); in s3c64xx_spi_transfer_one()
850 if (xfer->tx_buf && (sdd->state & TXBUSY)) { in s3c64xx_spi_transfer_one()
851 dmaengine_pause(sdd->tx_dma.ch); in s3c64xx_spi_transfer_one()
852 dmaengine_tx_status(sdd->tx_dma.ch, sdd->tx_dma.cookie, &s); in s3c64xx_spi_transfer_one()
853 dmaengine_terminate_all(sdd->tx_dma.ch); in s3c64xx_spi_transfer_one()
854 dev_err(&spi->dev, "TX residue: %d\n", s.residue); in s3c64xx_spi_transfer_one()
857 if (xfer->rx_buf && (sdd->state & RXBUSY)) { in s3c64xx_spi_transfer_one()
858 dmaengine_pause(sdd->rx_dma.ch); in s3c64xx_spi_transfer_one()
859 dmaengine_tx_status(sdd->rx_dma.ch, sdd->rx_dma.cookie, &s); in s3c64xx_spi_transfer_one()
860 dmaengine_terminate_all(sdd->rx_dma.ch); in s3c64xx_spi_transfer_one()
861 dev_err(&spi->dev, "RX residue: %d\n", s.residue); in s3c64xx_spi_transfer_one()
868 target_len -= xfer->len; in s3c64xx_spi_transfer_one()
870 if (xfer->tx_buf) in s3c64xx_spi_transfer_one()
871 xfer->tx_buf += xfer->len; in s3c64xx_spi_transfer_one()
873 if (xfer->rx_buf) in s3c64xx_spi_transfer_one()
874 xfer->rx_buf += xfer->len; in s3c64xx_spi_transfer_one()
877 xfer->len = fifo_len - 1; in s3c64xx_spi_transfer_one()
879 xfer->len = target_len; in s3c64xx_spi_transfer_one()
885 xfer->tx_buf = tx_buf; in s3c64xx_spi_transfer_one()
886 xfer->rx_buf = rx_buf; in s3c64xx_spi_transfer_one()
887 xfer->len = origin_len; in s3c64xx_spi_transfer_one()
894 struct spi_device *spi) in s3c64xx_get_target_ctrldata() argument
900 target_np = spi->dev.of_node; in s3c64xx_get_target_ctrldata()
902 dev_err(&spi->dev, "device node not found\n"); in s3c64xx_get_target_ctrldata()
903 return ERR_PTR(-EINVAL); in s3c64xx_get_target_ctrldata()
908 return ERR_PTR(-ENOMEM); in s3c64xx_get_target_ctrldata()
910 data_np = of_get_child_by_name(target_np, "controller-data"); in s3c64xx_get_target_ctrldata()
912 dev_info(&spi->dev, "feedback delay set to default (0)\n"); in s3c64xx_get_target_ctrldata()
916 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay); in s3c64xx_get_target_ctrldata()
917 cs->fb_delay = fb_delay; in s3c64xx_get_target_ctrldata()
924 * and save the configuration in a local data-structure.
928 static int s3c64xx_spi_setup(struct spi_device *spi) in s3c64xx_spi_setup() argument
930 struct s3c64xx_spi_csinfo *cs = spi->controller_data; in s3c64xx_spi_setup()
935 sdd = spi_controller_get_devdata(spi->controller); in s3c64xx_spi_setup()
936 if (spi->dev.of_node) { in s3c64xx_spi_setup()
937 cs = s3c64xx_get_target_ctrldata(spi); in s3c64xx_spi_setup()
938 spi->controller_data = cs; in s3c64xx_spi_setup()
943 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi_get_chipselect(spi, 0)); in s3c64xx_spi_setup()
944 return -ENODEV; in s3c64xx_spi_setup()
947 if (!spi_get_ctldata(spi)) in s3c64xx_spi_setup()
948 spi_set_ctldata(spi, cs); in s3c64xx_spi_setup()
950 pm_runtime_get_sync(&sdd->pdev->dev); in s3c64xx_spi_setup()
952 div = sdd->port_conf->clk_div; in s3c64xx_spi_setup()
955 if (!sdd->port_conf->clk_from_cmu) { in s3c64xx_spi_setup()
959 speed = clk_get_rate(sdd->src_clk) / div / (0 + 1); in s3c64xx_spi_setup()
961 if (spi->max_speed_hz > speed) in s3c64xx_spi_setup()
962 spi->max_speed_hz = speed; in s3c64xx_spi_setup()
964 psr = clk_get_rate(sdd->src_clk) / div / spi->max_speed_hz - 1; in s3c64xx_spi_setup()
967 psr--; in s3c64xx_spi_setup()
969 speed = clk_get_rate(sdd->src_clk) / div / (psr + 1); in s3c64xx_spi_setup()
970 if (spi->max_speed_hz < speed) { in s3c64xx_spi_setup()
974 err = -EINVAL; in s3c64xx_spi_setup()
979 speed = clk_get_rate(sdd->src_clk) / div / (psr + 1); in s3c64xx_spi_setup()
980 if (spi->max_speed_hz >= speed) { in s3c64xx_spi_setup()
981 spi->max_speed_hz = speed; in s3c64xx_spi_setup()
983 dev_err(&spi->dev, "Can't set %dHz transfer speed\n", in s3c64xx_spi_setup()
984 spi->max_speed_hz); in s3c64xx_spi_setup()
985 err = -EINVAL; in s3c64xx_spi_setup()
990 pm_runtime_mark_last_busy(&sdd->pdev->dev); in s3c64xx_spi_setup()
991 pm_runtime_put_autosuspend(&sdd->pdev->dev); in s3c64xx_spi_setup()
992 s3c64xx_spi_set_cs(spi, false); in s3c64xx_spi_setup()
997 pm_runtime_mark_last_busy(&sdd->pdev->dev); in s3c64xx_spi_setup()
998 pm_runtime_put_autosuspend(&sdd->pdev->dev); in s3c64xx_spi_setup()
999 /* setup() returns with device de-selected */ in s3c64xx_spi_setup()
1000 s3c64xx_spi_set_cs(spi, false); in s3c64xx_spi_setup()
1002 spi_set_ctldata(spi, NULL); in s3c64xx_spi_setup()
1005 if (spi->dev.of_node) in s3c64xx_spi_setup()
1011 static void s3c64xx_spi_cleanup(struct spi_device *spi) in s3c64xx_spi_cleanup() argument
1013 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi); in s3c64xx_spi_cleanup()
1016 if (spi->dev.of_node) in s3c64xx_spi_cleanup()
1019 spi_set_ctldata(spi, NULL); in s3c64xx_spi_cleanup()
1025 struct spi_controller *spi = sdd->host; in s3c64xx_spi_irq() local
1028 val = readl(sdd->regs + S3C64XX_SPI_STATUS); in s3c64xx_spi_irq()
1032 dev_err(&spi->dev, "RX overrun\n"); in s3c64xx_spi_irq()
1036 dev_err(&spi->dev, "RX underrun\n"); in s3c64xx_spi_irq()
1040 dev_err(&spi->dev, "TX overrun\n"); in s3c64xx_spi_irq()
1044 dev_err(&spi->dev, "TX underrun\n"); in s3c64xx_spi_irq()
1048 complete(&sdd->xfer_completion); in s3c64xx_spi_irq()
1049 /* No pending clear irq, turn-off INT_EN_RX_FIFO_RDY */ in s3c64xx_spi_irq()
1050 val = readl(sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_irq()
1052 sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_irq()
1056 writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); in s3c64xx_spi_irq()
1057 writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); in s3c64xx_spi_irq()
1064 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_hwinit()
1065 void __iomem *regs = sdd->regs; in s3c64xx_spi_hwinit()
1068 sdd->cur_speed = 0; in s3c64xx_spi_hwinit()
1070 if (sci->no_cs) in s3c64xx_spi_hwinit()
1071 writel(0, sdd->regs + S3C64XX_SPI_CS_REG); in s3c64xx_spi_hwinit()
1072 else if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO)) in s3c64xx_spi_hwinit()
1073 writel(S3C64XX_SPI_CS_SIG_INACT, sdd->regs + S3C64XX_SPI_CS_REG); in s3c64xx_spi_hwinit()
1075 /* Disable Interrupts - we use Polling if not DMA mode */ in s3c64xx_spi_hwinit()
1078 if (!sdd->port_conf->clk_from_cmu) in s3c64xx_spi_hwinit()
1079 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, in s3c64xx_spi_hwinit()
1111 return ERR_PTR(-ENOMEM); in s3c64xx_spi_parse_dt()
1113 if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) { in s3c64xx_spi_parse_dt()
1114 dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n"); in s3c64xx_spi_parse_dt()
1115 sci->src_clk_nr = 0; in s3c64xx_spi_parse_dt()
1117 sci->src_clk_nr = temp; in s3c64xx_spi_parse_dt()
1120 if (of_property_read_u32(dev->of_node, "num-cs", &temp)) { in s3c64xx_spi_parse_dt()
1122 sci->num_cs = 1; in s3c64xx_spi_parse_dt()
1124 sci->num_cs = temp; in s3c64xx_spi_parse_dt()
1127 sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback"); in s3c64xx_spi_parse_dt()
1128 sci->polling = !of_property_present(dev->of_node, "dmas"); in s3c64xx_spi_parse_dt()
1143 if (pdev->dev.of_node) in s3c64xx_spi_get_port_config()
1144 return of_device_get_match_data(&pdev->dev); in s3c64xx_spi_get_port_config()
1146 return (const struct s3c64xx_spi_port_config *)platform_get_device_id(pdev)->driver_data; in s3c64xx_spi_get_port_config()
1153 struct s3c64xx_spi_info *sci = dev_get_platdata(&pdev->dev); in s3c64xx_spi_probe()
1158 if (!sci && pdev->dev.of_node) { in s3c64xx_spi_probe()
1159 sci = s3c64xx_spi_parse_dt(&pdev->dev); in s3c64xx_spi_probe()
1165 return dev_err_probe(&pdev->dev, -ENODEV, in s3c64xx_spi_probe()
1172 host = devm_spi_alloc_host(&pdev->dev, sizeof(*sdd)); in s3c64xx_spi_probe()
1174 return dev_err_probe(&pdev->dev, -ENOMEM, in s3c64xx_spi_probe()
1175 "Unable to allocate SPI Host\n"); in s3c64xx_spi_probe()
1180 sdd->port_conf = s3c64xx_spi_get_port_config(pdev); in s3c64xx_spi_probe()
1181 sdd->host = host; in s3c64xx_spi_probe()
1182 sdd->cntrlr_info = sci; in s3c64xx_spi_probe()
1183 sdd->pdev = pdev; in s3c64xx_spi_probe()
1184 if (pdev->dev.of_node) { in s3c64xx_spi_probe()
1185 ret = of_alias_get_id(pdev->dev.of_node, "spi"); in s3c64xx_spi_probe()
1187 return dev_err_probe(&pdev->dev, ret, in s3c64xx_spi_probe()
1189 sdd->port_id = ret; in s3c64xx_spi_probe()
1191 sdd->port_id = pdev->id; in s3c64xx_spi_probe()
1194 sdd->cur_bpw = 8; in s3c64xx_spi_probe()
1196 sdd->tx_dma.direction = DMA_MEM_TO_DEV; in s3c64xx_spi_probe()
1197 sdd->rx_dma.direction = DMA_DEV_TO_MEM; in s3c64xx_spi_probe()
1199 host->dev.of_node = pdev->dev.of_node; in s3c64xx_spi_probe()
1200 host->bus_num = sdd->port_id; in s3c64xx_spi_probe()
1201 host->setup = s3c64xx_spi_setup; in s3c64xx_spi_probe()
1202 host->cleanup = s3c64xx_spi_cleanup; in s3c64xx_spi_probe()
1203 host->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; in s3c64xx_spi_probe()
1204 host->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; in s3c64xx_spi_probe()
1205 host->prepare_message = s3c64xx_spi_prepare_message; in s3c64xx_spi_probe()
1206 host->transfer_one = s3c64xx_spi_transfer_one; in s3c64xx_spi_probe()
1207 host->max_transfer_size = s3c64xx_spi_max_transfer_size; in s3c64xx_spi_probe()
1208 host->num_chipselect = sci->num_cs; in s3c64xx_spi_probe()
1209 host->use_gpio_descriptors = true; in s3c64xx_spi_probe()
1210 host->dma_alignment = 8; in s3c64xx_spi_probe()
1211 host->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | in s3c64xx_spi_probe()
1213 /* the spi->mode bits understood by this driver: */ in s3c64xx_spi_probe()
1214 host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in s3c64xx_spi_probe()
1215 if (sdd->port_conf->has_loopback) in s3c64xx_spi_probe()
1216 host->mode_bits |= SPI_LOOP; in s3c64xx_spi_probe()
1217 host->auto_runtime_pm = true; in s3c64xx_spi_probe()
1219 host->can_dma = s3c64xx_spi_can_dma; in s3c64xx_spi_probe()
1221 sdd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res); in s3c64xx_spi_probe()
1222 if (IS_ERR(sdd->regs)) in s3c64xx_spi_probe()
1223 return PTR_ERR(sdd->regs); in s3c64xx_spi_probe()
1224 sdd->sfr_start = mem_res->start; in s3c64xx_spi_probe()
1226 if (sci->cfg_gpio && sci->cfg_gpio()) in s3c64xx_spi_probe()
1227 return dev_err_probe(&pdev->dev, -EBUSY, in s3c64xx_spi_probe()
1231 sdd->clk = devm_clk_get_enabled(&pdev->dev, "spi"); in s3c64xx_spi_probe()
1232 if (IS_ERR(sdd->clk)) in s3c64xx_spi_probe()
1233 return dev_err_probe(&pdev->dev, PTR_ERR(sdd->clk), in s3c64xx_spi_probe()
1234 "Unable to acquire clock 'spi'\n"); in s3c64xx_spi_probe()
1236 sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr); in s3c64xx_spi_probe()
1237 sdd->src_clk = devm_clk_get_enabled(&pdev->dev, clk_name); in s3c64xx_spi_probe()
1238 if (IS_ERR(sdd->src_clk)) in s3c64xx_spi_probe()
1239 return dev_err_probe(&pdev->dev, PTR_ERR(sdd->src_clk), in s3c64xx_spi_probe()
1243 if (sdd->port_conf->clk_ioclk) { in s3c64xx_spi_probe()
1244 sdd->ioclk = devm_clk_get_enabled(&pdev->dev, "spi_ioclk"); in s3c64xx_spi_probe()
1245 if (IS_ERR(sdd->ioclk)) in s3c64xx_spi_probe()
1246 return dev_err_probe(&pdev->dev, PTR_ERR(sdd->ioclk), in s3c64xx_spi_probe()
1250 pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); in s3c64xx_spi_probe()
1251 pm_runtime_use_autosuspend(&pdev->dev); in s3c64xx_spi_probe()
1252 pm_runtime_set_active(&pdev->dev); in s3c64xx_spi_probe()
1253 pm_runtime_enable(&pdev->dev); in s3c64xx_spi_probe()
1254 pm_runtime_get_sync(&pdev->dev); in s3c64xx_spi_probe()
1259 spin_lock_init(&sdd->lock); in s3c64xx_spi_probe()
1260 init_completion(&sdd->xfer_completion); in s3c64xx_spi_probe()
1262 ret = devm_request_irq(&pdev->dev, irq, s3c64xx_spi_irq, 0, in s3c64xx_spi_probe()
1263 "spi-s3c64xx", sdd); in s3c64xx_spi_probe()
1265 dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n", in s3c64xx_spi_probe()
1272 sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_probe()
1274 ret = devm_spi_register_controller(&pdev->dev, host); in s3c64xx_spi_probe()
1276 dev_err(&pdev->dev, "cannot register SPI host: %d\n", ret); in s3c64xx_spi_probe()
1280 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Targets attached\n", in s3c64xx_spi_probe()
1281 sdd->port_id, host->num_chipselect); in s3c64xx_spi_probe()
1282 dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\n", in s3c64xx_spi_probe()
1285 pm_runtime_mark_last_busy(&pdev->dev); in s3c64xx_spi_probe()
1286 pm_runtime_put_autosuspend(&pdev->dev); in s3c64xx_spi_probe()
1291 pm_runtime_put_noidle(&pdev->dev); in s3c64xx_spi_probe()
1292 pm_runtime_disable(&pdev->dev); in s3c64xx_spi_probe()
1293 pm_runtime_set_suspended(&pdev->dev); in s3c64xx_spi_probe()
1303 pm_runtime_get_sync(&pdev->dev); in s3c64xx_spi_remove()
1305 writel(0, sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_remove()
1308 dma_release_channel(sdd->rx_dma.ch); in s3c64xx_spi_remove()
1309 dma_release_channel(sdd->tx_dma.ch); in s3c64xx_spi_remove()
1312 pm_runtime_put_noidle(&pdev->dev); in s3c64xx_spi_remove()
1313 pm_runtime_disable(&pdev->dev); in s3c64xx_spi_remove()
1314 pm_runtime_set_suspended(&pdev->dev); in s3c64xx_spi_remove()
1331 sdd->cur_speed = 0; /* Output Clock is stopped */ in s3c64xx_spi_suspend()
1340 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_resume()
1343 if (sci->cfg_gpio) in s3c64xx_spi_resume()
1344 sci->cfg_gpio(); in s3c64xx_spi_resume()
1360 clk_disable_unprepare(sdd->clk); in s3c64xx_spi_runtime_suspend()
1361 clk_disable_unprepare(sdd->src_clk); in s3c64xx_spi_runtime_suspend()
1362 clk_disable_unprepare(sdd->ioclk); in s3c64xx_spi_runtime_suspend()
1373 if (sdd->port_conf->clk_ioclk) { in s3c64xx_spi_runtime_resume()
1374 ret = clk_prepare_enable(sdd->ioclk); in s3c64xx_spi_runtime_resume()
1379 ret = clk_prepare_enable(sdd->src_clk); in s3c64xx_spi_runtime_resume()
1383 ret = clk_prepare_enable(sdd->clk); in s3c64xx_spi_runtime_resume()
1391 sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_runtime_resume()
1396 clk_disable_unprepare(sdd->src_clk); in s3c64xx_spi_runtime_resume()
1398 clk_disable_unprepare(sdd->ioclk); in s3c64xx_spi_runtime_resume()
1490 .name = "s3c2443-spi",
1493 .name = "s3c6410-spi",
1500 { .compatible = "samsung,s3c2443-spi",
1503 { .compatible = "samsung,s3c6410-spi",
1506 { .compatible = "samsung,s5pv210-spi",
1509 { .compatible = "samsung,exynos4210-spi",
1512 { .compatible = "samsung,exynos7-spi",
1515 { .compatible = "samsung,exynos5433-spi",
1518 { .compatible = "samsung,exynosautov9-spi",
1521 { .compatible = "tesla,fsd-spi",
1530 .name = "s3c64xx-spi",
1538 MODULE_ALIAS("platform:s3c64xx-spi");
1543 MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");