Lines Matching +full:spi +full:- +full:cpha

1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
12 #include <linux/qcom-geni-se.h>
13 #include <linux/spi/spi.h>
16 /* SPI SE specific registers and respective register fields */
18 #define CPHA BIT(0) macro
52 /* M_CMD OP codes for SPI */
60 /* M_CMD params for SPI */
99 struct geni_se *se = &mas->se; in get_spi_clk_cfg()
102 ret = geni_se_clk_freq_match(&mas->se, in get_spi_clk_cfg()
103 speed_hz * mas->oversampling, in get_spi_clk_cfg()
106 dev_err(mas->dev, "Failed(%d) to find src clk for %dHz\n", in get_spi_clk_cfg()
111 *clk_div = DIV_ROUND_UP(sclk_freq, mas->oversampling * speed_hz); in get_spi_clk_cfg()
112 actual_hz = sclk_freq / (mas->oversampling * *clk_div); in get_spi_clk_cfg()
114 dev_dbg(mas->dev, "req %u=>%u sclk %lu, idx %d, div %d\n", speed_hz, in get_spi_clk_cfg()
116 ret = clk_set_rate(se->clk, sclk_freq); in get_spi_clk_cfg()
118 dev_err(mas->dev, "clk_set_rate failed %d\n", ret); in get_spi_clk_cfg()
122 static void handle_fifo_timeout(struct spi_master *spi, in handle_fifo_timeout() argument
125 struct spi_geni_master *mas = spi_master_get_devdata(spi); in handle_fifo_timeout()
127 struct geni_se *se = &mas->se; in handle_fifo_timeout()
129 spin_lock_irqsave(&mas->lock, flags); in handle_fifo_timeout()
130 reinit_completion(&mas->xfer_done); in handle_fifo_timeout()
131 mas->cur_mcmd = CMD_CANCEL; in handle_fifo_timeout()
133 writel(0, se->base + SE_GENI_TX_WATERMARK_REG); in handle_fifo_timeout()
134 spin_unlock_irqrestore(&mas->lock, flags); in handle_fifo_timeout()
135 time_left = wait_for_completion_timeout(&mas->xfer_done, HZ); in handle_fifo_timeout()
139 spin_lock_irqsave(&mas->lock, flags); in handle_fifo_timeout()
140 reinit_completion(&mas->xfer_done); in handle_fifo_timeout()
142 spin_unlock_irqrestore(&mas->lock, flags); in handle_fifo_timeout()
143 time_left = wait_for_completion_timeout(&mas->xfer_done, HZ); in handle_fifo_timeout()
145 dev_err(mas->dev, "Failed to cancel/abort m_cmd\n"); in handle_fifo_timeout()
150 struct spi_geni_master *mas = spi_master_get_devdata(slv->master); in spi_geni_set_cs()
151 struct spi_master *spi = dev_get_drvdata(mas->dev); in spi_geni_set_cs() local
152 struct geni_se *se = &mas->se; in spi_geni_set_cs()
155 reinit_completion(&mas->xfer_done); in spi_geni_set_cs()
156 pm_runtime_get_sync(mas->dev); in spi_geni_set_cs()
157 if (!(slv->mode & SPI_CS_HIGH)) in spi_geni_set_cs()
160 mas->cur_mcmd = CMD_CS; in spi_geni_set_cs()
166 time_left = wait_for_completion_timeout(&mas->xfer_done, HZ); in spi_geni_set_cs()
168 handle_fifo_timeout(spi, NULL); in spi_geni_set_cs()
170 pm_runtime_put(mas->dev); in spi_geni_set_cs()
178 struct geni_se *se = &mas->se; in spi_setup_word_len()
181 word_len = readl(se->base + SE_SPI_WORD_LEN); in spi_setup_word_len()
185 * 1 SPI word per FIFO word. in spi_setup_word_len()
187 if (!(mas->fifo_width_bits % bits_per_word)) in spi_setup_word_len()
188 pack_words = mas->fifo_width_bits / bits_per_word; in spi_setup_word_len()
192 word_len |= ((bits_per_word - MIN_WORD_LEN) & WORD_LEN_MSK); in spi_setup_word_len()
193 geni_se_config_packing(&mas->se, bits_per_word, pack_words, msb_first, in spi_setup_word_len()
195 writel(word_len, se->base + SE_SPI_WORD_LEN); in spi_setup_word_len()
199 struct spi_master *spi) in setup_fifo_params() argument
201 struct spi_geni_master *mas = spi_master_get_devdata(spi); in setup_fifo_params()
202 struct geni_se *se = &mas->se; in setup_fifo_params()
203 u32 loopback_cfg, cpol, cpha, demux_output_inv; in setup_fifo_params() local
207 loopback_cfg = readl(se->base + SE_SPI_LOOPBACK); in setup_fifo_params()
208 cpol = readl(se->base + SE_SPI_CPOL); in setup_fifo_params()
209 cpha = readl(se->base + SE_SPI_CPHA); in setup_fifo_params()
213 cpha &= ~CPHA; in setup_fifo_params()
215 if (spi_slv->mode & SPI_LOOP) in setup_fifo_params()
218 if (spi_slv->mode & SPI_CPOL) in setup_fifo_params()
221 if (spi_slv->mode & SPI_CPHA) in setup_fifo_params()
222 cpha |= CPHA; in setup_fifo_params()
224 if (spi_slv->mode & SPI_CS_HIGH) in setup_fifo_params()
225 demux_output_inv = BIT(spi_slv->chip_select); in setup_fifo_params()
227 demux_sel = spi_slv->chip_select; in setup_fifo_params()
228 mas->cur_speed_hz = spi_slv->max_speed_hz; in setup_fifo_params()
229 mas->cur_bits_per_word = spi_slv->bits_per_word; in setup_fifo_params()
231 ret = get_spi_clk_cfg(mas->cur_speed_hz, mas, &idx, &div); in setup_fifo_params()
233 dev_err(mas->dev, "Err setting clks ret(%d) for %ld\n", in setup_fifo_params()
234 ret, mas->cur_speed_hz); in setup_fifo_params()
240 spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word); in setup_fifo_params()
241 writel(loopback_cfg, se->base + SE_SPI_LOOPBACK); in setup_fifo_params()
242 writel(demux_sel, se->base + SE_SPI_DEMUX_SEL); in setup_fifo_params()
243 writel(cpha, se->base + SE_SPI_CPHA); in setup_fifo_params()
244 writel(cpol, se->base + SE_SPI_CPOL); in setup_fifo_params()
245 writel(demux_output_inv, se->base + SE_SPI_DEMUX_OUTPUT_INV); in setup_fifo_params()
246 writel(clk_sel, se->base + SE_GENI_CLK_SEL); in setup_fifo_params()
247 writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG); in setup_fifo_params()
251 static int spi_geni_prepare_message(struct spi_master *spi, in spi_geni_prepare_message() argument
255 struct spi_geni_master *mas = spi_master_get_devdata(spi); in spi_geni_prepare_message()
256 struct geni_se *se = &mas->se; in spi_geni_prepare_message()
259 ret = setup_fifo_params(spi_msg->spi, spi); in spi_geni_prepare_message()
261 dev_err(mas->dev, "Couldn't select mode %d\n", ret); in spi_geni_prepare_message()
267 struct geni_se *se = &mas->se; in spi_geni_init()
270 pm_runtime_get_sync(mas->dev); in spi_geni_init()
274 dev_err(mas->dev, "Invalid proto %d\n", proto); in spi_geni_init()
275 pm_runtime_put(mas->dev); in spi_geni_init()
276 return -ENXIO; in spi_geni_init()
278 mas->tx_fifo_depth = geni_se_get_tx_fifo_depth(se); in spi_geni_init()
281 mas->fifo_width_bits = geni_se_get_tx_fifo_width(se); in spi_geni_init()
285 * RX FIFO RFR level to fifo_depth-2. in spi_geni_init()
287 geni_se_init(se, 0x0, mas->tx_fifo_depth - 2); in spi_geni_init()
289 mas->tx_wm = 1; in spi_geni_init()
295 mas->oversampling = 2; in spi_geni_init()
297 mas->oversampling = 1; in spi_geni_init()
299 pm_runtime_put(mas->dev); in spi_geni_init()
305 u16 mode, struct spi_master *spi) in setup_fifo_xfer() argument
309 struct geni_se *se = &mas->se; in setup_fifo_xfer()
311 spi_tx_cfg = readl(se->base + SE_SPI_TRANS_CFG); in setup_fifo_xfer()
312 if (xfer->bits_per_word != mas->cur_bits_per_word) { in setup_fifo_xfer()
313 spi_setup_word_len(mas, mode, xfer->bits_per_word); in setup_fifo_xfer()
314 mas->cur_bits_per_word = xfer->bits_per_word; in setup_fifo_xfer()
318 if (xfer->speed_hz != mas->cur_speed_hz) { in setup_fifo_xfer()
323 ret = get_spi_clk_cfg(xfer->speed_hz, mas, &idx, &div); in setup_fifo_xfer()
325 dev_err(mas->dev, "Err setting clks:%d\n", ret); in setup_fifo_xfer()
329 * SPI core clock gets configured with the requested frequency in setup_fifo_xfer()
335 mas->cur_speed_hz = xfer->speed_hz; in setup_fifo_xfer()
338 writel(clk_sel, se->base + SE_GENI_CLK_SEL); in setup_fifo_xfer()
339 writel(m_clk_cfg, se->base + GENI_SER_M_CLK_CFG); in setup_fifo_xfer()
342 mas->tx_rem_bytes = 0; in setup_fifo_xfer()
343 mas->rx_rem_bytes = 0; in setup_fifo_xfer()
344 if (xfer->tx_buf && xfer->rx_buf) in setup_fifo_xfer()
346 else if (xfer->tx_buf) in setup_fifo_xfer()
348 else if (xfer->rx_buf) in setup_fifo_xfer()
353 if (!(mas->cur_bits_per_word % MIN_WORD_LEN)) in setup_fifo_xfer()
354 len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word; in setup_fifo_xfer()
356 len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1); in setup_fifo_xfer()
359 mas->cur_xfer = xfer; in setup_fifo_xfer()
361 mas->tx_rem_bytes = xfer->len; in setup_fifo_xfer()
362 writel(len, se->base + SE_SPI_TX_TRANS_LEN); in setup_fifo_xfer()
366 writel(len, se->base + SE_SPI_RX_TRANS_LEN); in setup_fifo_xfer()
367 mas->rx_rem_bytes = xfer->len; in setup_fifo_xfer()
369 writel(spi_tx_cfg, se->base + SE_SPI_TRANS_CFG); in setup_fifo_xfer()
370 mas->cur_mcmd = CMD_XFER; in setup_fifo_xfer()
374 * TX_WATERMARK_REG should be set after SPI configuration and in setup_fifo_xfer()
379 writel(mas->tx_wm, se->base + SE_GENI_TX_WATERMARK_REG); in setup_fifo_xfer()
382 static int spi_geni_transfer_one(struct spi_master *spi, in spi_geni_transfer_one() argument
386 struct spi_geni_master *mas = spi_master_get_devdata(spi); in spi_geni_transfer_one()
389 if (!xfer->len) in spi_geni_transfer_one()
392 setup_fifo_xfer(xfer, mas, slv->mode, spi); in spi_geni_transfer_one()
403 if (mas->fifo_width_bits % mas->cur_bits_per_word) in geni_byte_per_fifo_word()
404 return roundup_pow_of_two(DIV_ROUND_UP(mas->cur_bits_per_word, in geni_byte_per_fifo_word()
407 return mas->fifo_width_bits / BITS_PER_BYTE; in geni_byte_per_fifo_word()
412 struct geni_se *se = &mas->se; in geni_spi_handle_tx()
418 max_bytes = (mas->tx_fifo_depth - mas->tx_wm) * bytes_per_fifo_word; in geni_spi_handle_tx()
419 if (mas->tx_rem_bytes < max_bytes) in geni_spi_handle_tx()
420 max_bytes = mas->tx_rem_bytes; in geni_spi_handle_tx()
422 tx_buf = mas->cur_xfer->tx_buf + mas->cur_xfer->len - mas->tx_rem_bytes; in geni_spi_handle_tx()
429 bytes_to_write = min(bytes_per_fifo_word, max_bytes - i); in geni_spi_handle_tx()
432 iowrite32_rep(se->base + SE_GENI_TX_FIFOn, &fifo_word, 1); in geni_spi_handle_tx()
434 mas->tx_rem_bytes -= max_bytes; in geni_spi_handle_tx()
435 if (!mas->tx_rem_bytes) in geni_spi_handle_tx()
436 writel(0, se->base + SE_GENI_TX_WATERMARK_REG); in geni_spi_handle_tx()
441 struct geni_se *se = &mas->se; in geni_spi_handle_rx()
449 rx_fifo_status = readl(se->base + SE_GENI_RX_FIFO_STATUS); in geni_spi_handle_rx()
455 rx_bytes -= bytes_per_fifo_word - rx_last_byte_valid; in geni_spi_handle_rx()
457 if (mas->rx_rem_bytes < rx_bytes) in geni_spi_handle_rx()
458 rx_bytes = mas->rx_rem_bytes; in geni_spi_handle_rx()
460 rx_buf = mas->cur_xfer->rx_buf + mas->cur_xfer->len - mas->rx_rem_bytes; in geni_spi_handle_rx()
467 bytes_to_read = min(bytes_per_fifo_word, rx_bytes - i); in geni_spi_handle_rx()
468 ioread32_rep(se->base + SE_GENI_RX_FIFOn, &fifo_word, 1); in geni_spi_handle_rx()
472 mas->rx_rem_bytes -= rx_bytes; in geni_spi_handle_rx()
477 struct spi_master *spi = data; in geni_spi_isr() local
478 struct spi_geni_master *mas = spi_master_get_devdata(spi); in geni_spi_isr()
479 struct geni_se *se = &mas->se; in geni_spi_isr()
483 if (mas->cur_mcmd == CMD_NONE) in geni_spi_isr()
486 spin_lock_irqsave(&mas->lock, flags); in geni_spi_isr()
487 m_irq = readl(se->base + SE_GENI_M_IRQ_STATUS); in geni_spi_isr()
496 if (mas->cur_mcmd == CMD_XFER) in geni_spi_isr()
497 spi_finalize_current_transfer(spi); in geni_spi_isr()
498 else if (mas->cur_mcmd == CMD_CS) in geni_spi_isr()
499 complete(&mas->xfer_done); in geni_spi_isr()
500 mas->cur_mcmd = CMD_NONE; in geni_spi_isr()
512 if (mas->tx_rem_bytes) { in geni_spi_isr()
513 writel(0, se->base + SE_GENI_TX_WATERMARK_REG); in geni_spi_isr()
514 dev_err(mas->dev, "Premature done. tx_rem = %d bpw%d\n", in geni_spi_isr()
515 mas->tx_rem_bytes, mas->cur_bits_per_word); in geni_spi_isr()
517 if (mas->rx_rem_bytes) in geni_spi_isr()
518 dev_err(mas->dev, "Premature done. rx_rem = %d bpw%d\n", in geni_spi_isr()
519 mas->rx_rem_bytes, mas->cur_bits_per_word); in geni_spi_isr()
523 mas->cur_mcmd = CMD_NONE; in geni_spi_isr()
524 complete(&mas->xfer_done); in geni_spi_isr()
527 writel(m_irq, se->base + SE_GENI_M_IRQ_CLEAR); in geni_spi_isr()
528 spin_unlock_irqrestore(&mas->lock, flags); in geni_spi_isr()
535 struct spi_master *spi; in spi_geni_probe() local
548 clk = devm_clk_get(&pdev->dev, "se"); in spi_geni_probe()
550 dev_err(&pdev->dev, "Err getting SE Core clk %ld\n", in spi_geni_probe()
555 spi = spi_alloc_master(&pdev->dev, sizeof(*mas)); in spi_geni_probe()
556 if (!spi) in spi_geni_probe()
557 return -ENOMEM; in spi_geni_probe()
559 platform_set_drvdata(pdev, spi); in spi_geni_probe()
560 mas = spi_master_get_devdata(spi); in spi_geni_probe()
561 mas->irq = irq; in spi_geni_probe()
562 mas->dev = &pdev->dev; in spi_geni_probe()
563 mas->se.dev = &pdev->dev; in spi_geni_probe()
564 mas->se.wrapper = dev_get_drvdata(pdev->dev.parent); in spi_geni_probe()
565 mas->se.base = base; in spi_geni_probe()
566 mas->se.clk = clk; in spi_geni_probe()
568 spi->bus_num = -1; in spi_geni_probe()
569 spi->dev.of_node = pdev->dev.of_node; in spi_geni_probe()
570 spi->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP | SPI_CS_HIGH; in spi_geni_probe()
571 spi->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); in spi_geni_probe()
572 spi->num_chipselect = 4; in spi_geni_probe()
573 spi->max_speed_hz = 50000000; in spi_geni_probe()
574 spi->prepare_message = spi_geni_prepare_message; in spi_geni_probe()
575 spi->transfer_one = spi_geni_transfer_one; in spi_geni_probe()
576 spi->auto_runtime_pm = true; in spi_geni_probe()
577 spi->handle_err = handle_fifo_timeout; in spi_geni_probe()
578 spi->set_cs = spi_geni_set_cs; in spi_geni_probe()
580 init_completion(&mas->xfer_done); in spi_geni_probe()
581 spin_lock_init(&mas->lock); in spi_geni_probe()
582 pm_runtime_enable(&pdev->dev); in spi_geni_probe()
588 ret = request_irq(mas->irq, geni_spi_isr, in spi_geni_probe()
589 IRQF_TRIGGER_HIGH, "spi_geni", spi); in spi_geni_probe()
593 ret = spi_register_master(spi); in spi_geni_probe()
599 free_irq(mas->irq, spi); in spi_geni_probe()
601 pm_runtime_disable(&pdev->dev); in spi_geni_probe()
602 spi_master_put(spi); in spi_geni_probe()
608 struct spi_master *spi = platform_get_drvdata(pdev); in spi_geni_remove() local
609 struct spi_geni_master *mas = spi_master_get_devdata(spi); in spi_geni_remove()
612 spi_unregister_master(spi); in spi_geni_remove()
614 free_irq(mas->irq, spi); in spi_geni_remove()
615 pm_runtime_disable(&pdev->dev); in spi_geni_remove()
621 struct spi_master *spi = dev_get_drvdata(dev); in spi_geni_runtime_suspend() local
622 struct spi_geni_master *mas = spi_master_get_devdata(spi); in spi_geni_runtime_suspend()
624 return geni_se_resources_off(&mas->se); in spi_geni_runtime_suspend()
629 struct spi_master *spi = dev_get_drvdata(dev); in spi_geni_runtime_resume() local
630 struct spi_geni_master *mas = spi_master_get_devdata(spi); in spi_geni_runtime_resume()
632 return geni_se_resources_on(&mas->se); in spi_geni_runtime_resume()
637 struct spi_master *spi = dev_get_drvdata(dev); in spi_geni_suspend() local
640 ret = spi_master_suspend(spi); in spi_geni_suspend()
646 spi_master_resume(spi); in spi_geni_suspend()
653 struct spi_master *spi = dev_get_drvdata(dev); in spi_geni_resume() local
660 ret = spi_master_resume(spi); in spi_geni_resume()
674 { .compatible = "qcom,geni-spi" },
690 MODULE_DESCRIPTION("SPI driver for GENI based QUP cores");