Lines Matching full:sdd
203 static void s3c64xx_flush_fifo(struct s3c64xx_spi_driver_data *sdd) in s3c64xx_flush_fifo() argument
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()
233 if (RX_FIFO_LVL(val, sdd)) in s3c64xx_flush_fifo()
240 dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); in s3c64xx_flush_fifo()
253 struct s3c64xx_spi_driver_data *sdd; in s3c64xx_spi_dmacb() local
258 sdd = container_of(data, in s3c64xx_spi_dmacb()
261 sdd = container_of(data, in s3c64xx_spi_dmacb()
264 spin_lock_irqsave(&sdd->lock, flags); 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()
282 struct s3c64xx_spi_driver_data *sdd; in prepare_dma() local
290 sdd = container_of((void *)dma, 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()
298 sdd = container_of((void *)dma, 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()
310 dev_err(&sdd->pdev->dev, "unable to prepare %s scatterlist", in prepare_dma()
321 dev_err(&sdd->pdev->dev, "DMA submission failed"); in prepare_dma()
331 struct s3c64xx_spi_driver_data *sdd = in s3c64xx_spi_set_cs() local
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()
356 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(spi); in s3c64xx_spi_prepare_transfer() local
358 if (is_polling(sdd)) 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()
386 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(spi); in s3c64xx_spi_unprepare_transfer() local
388 if (is_polling(sdd)) 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()
406 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_can_dma() local
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()
416 static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, in s3c64xx_enable_datapath() argument
419 void __iomem *regs = sdd->regs; in s3c64xx_enable_datapath()
437 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) 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()
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()
492 static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, in s3c64xx_spi_wait_for_timeout() argument
495 void __iomem *regs = sdd->regs; in s3c64xx_spi_wait_for_timeout()
500 u32 max_fifo = (FIFO_LVL_MASK(sdd) >> 1) + 1; in s3c64xx_spi_wait_for_timeout()
507 } while (RX_FIFO_LVL(status, sdd) < max_fifo && --val); in s3c64xx_spi_wait_for_timeout()
510 return RX_FIFO_LVL(status, sdd); in s3c64xx_spi_wait_for_timeout()
513 static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, in s3c64xx_wait_for_dma() argument
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()
541 while ((TX_FIFO_LVL(status, sdd) in s3c64xx_wait_for_dma()
542 || !S3C64XX_SPI_ST_TX_DONE(status, sdd)) in s3c64xx_wait_for_dma()
557 static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, in s3c64xx_wait_for_pio() argument
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()
588 } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); 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()
611 cpy_len = s3c64xx_spi_wait_for_timeout(sdd, in s3c64xx_wait_for_pio()
614 switch (sdd->cur_bpw) { in s3c64xx_wait_for_pio()
631 sdd->state &= ~RXBUSY; in s3c64xx_wait_for_pio()
636 static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) in s3c64xx_spi_config() argument
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()
718 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_prepare_message() local
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()
743 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_transfer_one() local
744 const unsigned int fifo_len = (FIFO_LVL_MASK(sdd) >> 1) + 1; in s3c64xx_spi_transfer_one()
757 reinit_completion(&sdd->xfer_completion); 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()
767 status = s3c64xx_spi_config(sdd); 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()
790 reinit_completion(&sdd->xfer_completion); 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()
825 status = s3c64xx_enable_datapath(sdd, xfer, use_dma); in s3c64xx_spi_transfer_one()
827 spin_unlock_irqrestore(&sdd->lock, flags); in s3c64xx_spi_transfer_one()
835 status = s3c64xx_wait_for_dma(sdd, xfer); in s3c64xx_spi_transfer_one()
837 status = s3c64xx_wait_for_pio(sdd, xfer, use_irq); 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()
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()
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()
865 s3c64xx_flush_fifo(sdd); in s3c64xx_spi_transfer_one()
931 struct s3c64xx_spi_driver_data *sdd; in s3c64xx_spi_setup() local
935 sdd = spi_controller_get_devdata(spi->controller); 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()
964 psr = clk_get_rate(sdd->src_clk) / div / spi->max_speed_hz - 1; in s3c64xx_spi_setup()
969 speed = clk_get_rate(sdd->src_clk) / div / (psr + 1); in s3c64xx_spi_setup()
979 speed = clk_get_rate(sdd->src_clk) / div / (psr + 1); 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()
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()
1024 struct s3c64xx_spi_driver_data *sdd = data; in s3c64xx_spi_irq() local
1025 struct spi_controller *spi = sdd->host; in s3c64xx_spi_irq()
1028 val = readl(sdd->regs + S3C64XX_SPI_STATUS); in s3c64xx_spi_irq()
1048 complete(&sdd->xfer_completion); 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()
1062 static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd) in s3c64xx_spi_hwinit() argument
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()
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()
1078 if (!sdd->port_conf->clk_from_cmu) in s3c64xx_spi_hwinit()
1100 s3c64xx_flush_fifo(sdd); in s3c64xx_spi_hwinit()
1152 struct s3c64xx_spi_driver_data *sdd; in s3c64xx_spi_probe() local
1172 host = devm_spi_alloc_host(&pdev->dev, sizeof(*sdd)); in s3c64xx_spi_probe()
1179 sdd = spi_controller_get_devdata(host); 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()
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()
1200 host->bus_num = sdd->port_id; in s3c64xx_spi_probe()
1215 if (sdd->port_conf->has_loopback) in s3c64xx_spi_probe()
1218 if (!is_polling(sdd)) 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()
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()
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()
1257 s3c64xx_spi_hwinit(sdd); in s3c64xx_spi_probe()
1259 spin_lock_init(&sdd->lock); in s3c64xx_spi_probe()
1260 init_completion(&sdd->xfer_completion); in s3c64xx_spi_probe()
1263 "spi-s3c64xx", sdd); in s3c64xx_spi_probe()
1272 sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_probe()
1281 sdd->port_id, host->num_chipselect); in s3c64xx_spi_probe()
1283 mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1); in s3c64xx_spi_probe()
1301 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_remove() local
1305 writel(0, sdd->regs + S3C64XX_SPI_INT_EN); in s3c64xx_spi_remove()
1307 if (!is_polling(sdd)) { 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()
1321 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_suspend() local
1331 sdd->cur_speed = 0; /* Output Clock is stopped */ in s3c64xx_spi_suspend()
1339 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_resume() local
1340 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; in s3c64xx_spi_resume()
1358 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_runtime_suspend() local
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()
1370 struct s3c64xx_spi_driver_data *sdd = spi_controller_get_devdata(host); in s3c64xx_spi_runtime_resume() local
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()
1387 s3c64xx_spi_hwinit(sdd); 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()