Lines Matching +full:csi +full:- +full:no +full:- +full:ss
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Renesas RZ/V2M Clocked Serial Interface (CSI) driver
22 #define CSI_MODE 0x00 /* CSI mode control */
23 #define CSI_CLKSEL 0x04 /* CSI clock select */
24 #define CSI_CNT 0x08 /* CSI control */
25 #define CSI_INT 0x0C /* CSI interrupt status */
26 #define CSI_IFIFOL 0x10 /* CSI receive FIFO level display */
27 #define CSI_OFIFOL 0x14 /* CSI transmit FIFO level display */
28 #define CSI_IFIFO 0x18 /* CSI receive window */
29 #define CSI_OFIFO 0x1C /* CSI transmit window */
30 #define CSI_FIFOTRG 0x20 /* CSI FIFO trigger level */
114 static void rzv2m_csi_reg_write_bit(const struct rzv2m_csi_priv *csi, in rzv2m_csi_reg_write_bit() argument
123 tmp = (readl(csi->base + reg_offs) & ~bit_mask) | value; in rzv2m_csi_reg_write_bit()
124 writel(tmp, csi->base + reg_offs); in rzv2m_csi_reg_write_bit()
127 static int rzv2m_csi_sw_reset(struct rzv2m_csi_priv *csi, int assert) in rzv2m_csi_sw_reset() argument
131 rzv2m_csi_reg_write_bit(csi, CSI_CNT, CSI_CNT_CSIRST, assert); in rzv2m_csi_sw_reset()
136 return readl_poll_timeout(csi->base + CSI_MODE, reg, in rzv2m_csi_sw_reset()
141 static int rzv2m_csi_start_stop_operation(const struct rzv2m_csi_priv *csi, in rzv2m_csi_start_stop_operation() argument
146 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_CSIE, enable); in rzv2m_csi_start_stop_operation()
151 return readl_poll_timeout(csi->base + CSI_MODE, reg, in rzv2m_csi_start_stop_operation()
156 static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi) in rzv2m_csi_fill_txfifo() argument
160 if (readl(csi->base + CSI_OFIFOL)) in rzv2m_csi_fill_txfifo()
161 return -EIO; in rzv2m_csi_fill_txfifo()
163 if (csi->bytes_per_word == 2) { in rzv2m_csi_fill_txfifo()
164 const u16 *buf = csi->txbuf; in rzv2m_csi_fill_txfifo()
166 for (i = 0; i < csi->words_to_transfer; i++) in rzv2m_csi_fill_txfifo()
167 writel(buf[i], csi->base + CSI_OFIFO); in rzv2m_csi_fill_txfifo()
169 const u8 *buf = csi->txbuf; in rzv2m_csi_fill_txfifo()
171 for (i = 0; i < csi->words_to_transfer; i++) in rzv2m_csi_fill_txfifo()
172 writel(buf[i], csi->base + CSI_OFIFO); in rzv2m_csi_fill_txfifo()
175 csi->txbuf += csi->bytes_to_transfer; in rzv2m_csi_fill_txfifo()
176 csi->bytes_sent += csi->bytes_to_transfer; in rzv2m_csi_fill_txfifo()
181 static int rzv2m_csi_read_rxfifo(struct rzv2m_csi_priv *csi) in rzv2m_csi_read_rxfifo() argument
185 if (readl(csi->base + CSI_IFIFOL) != csi->bytes_to_transfer) in rzv2m_csi_read_rxfifo()
186 return -EIO; in rzv2m_csi_read_rxfifo()
188 if (csi->bytes_per_word == 2) { in rzv2m_csi_read_rxfifo()
189 u16 *buf = csi->rxbuf; in rzv2m_csi_read_rxfifo()
191 for (i = 0; i < csi->words_to_transfer; i++) in rzv2m_csi_read_rxfifo()
192 buf[i] = (u16)readl(csi->base + CSI_IFIFO); in rzv2m_csi_read_rxfifo()
194 u8 *buf = csi->rxbuf; in rzv2m_csi_read_rxfifo()
196 for (i = 0; i < csi->words_to_transfer; i++) in rzv2m_csi_read_rxfifo()
197 buf[i] = (u8)readl(csi->base + CSI_IFIFO); in rzv2m_csi_read_rxfifo()
200 csi->rxbuf += csi->bytes_to_transfer; in rzv2m_csi_read_rxfifo()
201 csi->bytes_received += csi->bytes_to_transfer; in rzv2m_csi_read_rxfifo()
206 static inline void rzv2m_csi_empty_rxfifo(struct rzv2m_csi_priv *csi) in rzv2m_csi_empty_rxfifo() argument
210 for (i = 0; i < csi->words_to_transfer; i++) in rzv2m_csi_empty_rxfifo()
211 readl(csi->base + CSI_IFIFO); in rzv2m_csi_empty_rxfifo()
214 static inline void rzv2m_csi_calc_current_transfer(struct rzv2m_csi_priv *csi) in rzv2m_csi_calc_current_transfer() argument
216 unsigned int bytes_transferred = max(csi->bytes_received, csi->bytes_sent); in rzv2m_csi_calc_current_transfer()
217 unsigned int bytes_remaining = csi->buffer_len - bytes_transferred; in rzv2m_csi_calc_current_transfer()
220 if (csi->txbuf) in rzv2m_csi_calc_current_transfer()
230 if (csi->bytes_per_word == 2) in rzv2m_csi_calc_current_transfer()
239 csi->words_to_transfer = rounddown_pow_of_two(to_transfer); in rzv2m_csi_calc_current_transfer()
241 if (csi->bytes_per_word == 2) in rzv2m_csi_calc_current_transfer()
242 csi->bytes_to_transfer = csi->words_to_transfer << 1; in rzv2m_csi_calc_current_transfer()
244 csi->bytes_to_transfer = csi->words_to_transfer; in rzv2m_csi_calc_current_transfer()
247 static inline void rzv2m_csi_set_rx_fifo_trigger_level(struct rzv2m_csi_priv *csi) in rzv2m_csi_set_rx_fifo_trigger_level() argument
249 rzv2m_csi_reg_write_bit(csi, CSI_FIFOTRG, CSI_FIFOTRG_R_TRG, in rzv2m_csi_set_rx_fifo_trigger_level()
250 ilog2(csi->words_to_transfer)); in rzv2m_csi_set_rx_fifo_trigger_level()
253 static inline void rzv2m_csi_enable_rx_trigger(struct rzv2m_csi_priv *csi, in rzv2m_csi_enable_rx_trigger() argument
256 rzv2m_csi_reg_write_bit(csi, CSI_CNT, CSI_CNT_R_TRGEN, enable); in rzv2m_csi_enable_rx_trigger()
259 static void rzv2m_csi_disable_irqs(const struct rzv2m_csi_priv *csi, in rzv2m_csi_disable_irqs() argument
262 u32 cnt = readl(csi->base + CSI_CNT); in rzv2m_csi_disable_irqs()
264 writel(cnt & ~enable_bits, csi->base + CSI_CNT); in rzv2m_csi_disable_irqs()
267 static void rzv2m_csi_disable_all_irqs(struct rzv2m_csi_priv *csi) in rzv2m_csi_disable_all_irqs() argument
269 rzv2m_csi_disable_irqs(csi, CSI_CNT_R_TRGR_E | CSI_CNT_T_TRGR_E | in rzv2m_csi_disable_all_irqs()
274 static inline void rzv2m_csi_clear_irqs(struct rzv2m_csi_priv *csi, u32 irqs) in rzv2m_csi_clear_irqs() argument
276 writel(irqs, csi->base + CSI_INT); in rzv2m_csi_clear_irqs()
279 static void rzv2m_csi_clear_all_irqs(struct rzv2m_csi_priv *csi) in rzv2m_csi_clear_all_irqs() argument
281 rzv2m_csi_clear_irqs(csi, CSI_INT_UNDER | CSI_INT_OVERF | in rzv2m_csi_clear_all_irqs()
286 static void rzv2m_csi_enable_irqs(struct rzv2m_csi_priv *csi, u32 enable_bits) in rzv2m_csi_enable_irqs() argument
288 u32 cnt = readl(csi->base + CSI_CNT); in rzv2m_csi_enable_irqs()
290 writel(cnt | enable_bits, csi->base + CSI_CNT); in rzv2m_csi_enable_irqs()
293 static int rzv2m_csi_wait_for_interrupt(struct rzv2m_csi_priv *csi, in rzv2m_csi_wait_for_interrupt() argument
298 rzv2m_csi_enable_irqs(csi, enable_bits); in rzv2m_csi_wait_for_interrupt()
300 if (spi_controller_is_target(csi->controller)) { in rzv2m_csi_wait_for_interrupt()
301 ret = wait_event_interruptible(csi->wait, in rzv2m_csi_wait_for_interrupt()
302 ((csi->status & wait_mask) == wait_mask) || in rzv2m_csi_wait_for_interrupt()
303 csi->errors || csi->target_aborted); in rzv2m_csi_wait_for_interrupt()
304 if (ret || csi->target_aborted) in rzv2m_csi_wait_for_interrupt()
305 ret = -EINTR; in rzv2m_csi_wait_for_interrupt()
307 ret = wait_event_timeout(csi->wait, in rzv2m_csi_wait_for_interrupt()
308 ((csi->status & wait_mask) == wait_mask) || in rzv2m_csi_wait_for_interrupt()
309 csi->errors, HZ) == 0 ? -ETIMEDOUT : 0; in rzv2m_csi_wait_for_interrupt()
312 rzv2m_csi_disable_irqs(csi, enable_bits); in rzv2m_csi_wait_for_interrupt()
314 if (csi->errors) in rzv2m_csi_wait_for_interrupt()
315 return -EIO; in rzv2m_csi_wait_for_interrupt()
320 static inline int rzv2m_csi_wait_for_rx_ready(struct rzv2m_csi_priv *csi) in rzv2m_csi_wait_for_rx_ready() argument
324 if (readl(csi->base + CSI_IFIFOL) >= csi->bytes_to_transfer) in rzv2m_csi_wait_for_rx_ready()
327 ret = rzv2m_csi_wait_for_interrupt(csi, CSI_INT_R_TRGR, in rzv2m_csi_wait_for_rx_ready()
329 if (ret == -ETIMEDOUT) in rzv2m_csi_wait_for_rx_ready()
330 csi->errors |= RX_TIMEOUT_ERROR; in rzv2m_csi_wait_for_rx_ready()
337 struct rzv2m_csi_priv *csi = data; in rzv2m_csi_irq_handler() local
339 csi->status = readl(csi->base + CSI_INT); in rzv2m_csi_irq_handler()
340 rzv2m_csi_disable_irqs(csi, csi->status); in rzv2m_csi_irq_handler()
342 if (csi->status & CSI_INT_OVERF) in rzv2m_csi_irq_handler()
343 csi->errors |= OVERFLOW_ERROR; in rzv2m_csi_irq_handler()
344 if (csi->status & CSI_INT_UNDER) in rzv2m_csi_irq_handler()
345 csi->errors |= UNDERRUN_ERROR; in rzv2m_csi_irq_handler()
347 wake_up(&csi->wait); in rzv2m_csi_irq_handler()
352 static void rzv2m_csi_setup_clock(struct rzv2m_csi_priv *csi, u32 spi_hz) in rzv2m_csi_setup_clock() argument
354 unsigned long csiclk_rate = clk_get_rate(csi->csiclk); in rzv2m_csi_setup_clock()
355 unsigned long pclk_rate = clk_get_rate(csi->pclk); in rzv2m_csi_setup_clock()
364 clk_set_rate(csi->csiclk, csiclk_rate >> 1); in rzv2m_csi_setup_clock()
365 csiclk_rate = clk_get_rate(csi->csiclk); in rzv2m_csi_setup_clock()
367 clk_set_rate(csi->csiclk, csiclk_rate << 1); in rzv2m_csi_setup_clock()
368 csiclk_rate = clk_get_rate(csi->csiclk); in rzv2m_csi_setup_clock()
377 dev_dbg(csi->dev, "SPI clk rate is %ldHz\n", csiclk_rate / (cks << 1)); in rzv2m_csi_setup_clock()
379 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_CKS, cks); in rzv2m_csi_setup_clock()
382 static void rzv2m_csi_setup_operating_mode(struct rzv2m_csi_priv *csi, in rzv2m_csi_setup_operating_mode() argument
385 if (t->rx_buf && !t->tx_buf) in rzv2m_csi_setup_operating_mode()
386 /* Reception-only mode */ in rzv2m_csi_setup_operating_mode()
387 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_TRMD, 0); in rzv2m_csi_setup_operating_mode()
390 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_TRMD, 1); in rzv2m_csi_setup_operating_mode()
392 csi->bytes_per_word = t->bits_per_word / 8; in rzv2m_csi_setup_operating_mode()
393 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_CCL, in rzv2m_csi_setup_operating_mode()
394 csi->bytes_per_word == 2); in rzv2m_csi_setup_operating_mode()
399 struct rzv2m_csi_priv *csi = spi_controller_get_devdata(spi->controller); in rzv2m_csi_setup() local
403 rzv2m_csi_sw_reset(csi, 0); in rzv2m_csi_setup()
405 writel(CSI_MODE_SETUP, csi->base + CSI_MODE); in rzv2m_csi_setup()
408 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_MODE, in rzv2m_csi_setup()
409 ~spi->mode & SPI_MODE_X_MASK); in rzv2m_csi_setup()
412 rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_DIR, in rzv2m_csi_setup()
413 !!(spi->mode & SPI_LSB_FIRST)); in rzv2m_csi_setup()
416 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SLAVE, in rzv2m_csi_setup()
417 !!spi_controller_is_target(csi->controller)); in rzv2m_csi_setup()
419 if (csi->use_ss_pin) in rzv2m_csi_setup()
420 slave_selection = spi->mode & SPI_CS_HIGH ? in rzv2m_csi_setup()
424 /* Configure the slave selection (SS) pin */ in rzv2m_csi_setup()
425 rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SS, slave_selection); in rzv2m_csi_setup()
428 ret = rzv2m_csi_sw_reset(csi, 1); in rzv2m_csi_setup()
431 rzv2m_csi_sw_reset(csi, 0); in rzv2m_csi_setup()
437 rzv2m_csi_start_stop_operation(csi, 1, false); in rzv2m_csi_setup()
439 rzv2m_csi_start_stop_operation(csi, 0, false); in rzv2m_csi_setup()
444 static int rzv2m_csi_pio_transfer(struct rzv2m_csi_priv *csi) in rzv2m_csi_pio_transfer() argument
446 bool tx_completed = !csi->txbuf; in rzv2m_csi_pio_transfer()
447 bool rx_completed = !csi->rxbuf; in rzv2m_csi_pio_transfer()
451 writel(0, csi->base + CSI_OFIFOL); in rzv2m_csi_pio_transfer()
454 writel(0, csi->base + CSI_IFIFOL); in rzv2m_csi_pio_transfer()
456 csi->bytes_sent = 0; in rzv2m_csi_pio_transfer()
457 csi->bytes_received = 0; in rzv2m_csi_pio_transfer()
458 csi->errors = 0; in rzv2m_csi_pio_transfer()
459 csi->target_aborted = false; in rzv2m_csi_pio_transfer()
461 rzv2m_csi_disable_all_irqs(csi); in rzv2m_csi_pio_transfer()
462 rzv2m_csi_clear_all_irqs(csi); in rzv2m_csi_pio_transfer()
463 rzv2m_csi_enable_rx_trigger(csi, true); in rzv2m_csi_pio_transfer()
469 * level accordingly. No need to set a trigger level for the in rzv2m_csi_pio_transfer()
473 rzv2m_csi_calc_current_transfer(csi); in rzv2m_csi_pio_transfer()
474 rzv2m_csi_set_rx_fifo_trigger_level(csi); in rzv2m_csi_pio_transfer()
476 rzv2m_csi_enable_irqs(csi, CSI_INT_OVERF | CSI_INT_UNDER); in rzv2m_csi_pio_transfer()
478 writel(readl(csi->base + CSI_INT), csi->base + CSI_INT); in rzv2m_csi_pio_transfer()
479 csi->status = 0; in rzv2m_csi_pio_transfer()
482 if (csi->txbuf) { in rzv2m_csi_pio_transfer()
483 ret = rzv2m_csi_fill_txfifo(csi); in rzv2m_csi_pio_transfer()
487 if (csi->bytes_sent == csi->buffer_len) in rzv2m_csi_pio_transfer()
491 rzv2m_csi_start_stop_operation(csi, 1, false); in rzv2m_csi_pio_transfer()
496 * csi->rxbuf. in rzv2m_csi_pio_transfer()
498 ret = rzv2m_csi_wait_for_rx_ready(csi); in rzv2m_csi_pio_transfer()
502 if (!spi_controller_is_target(csi->controller)) in rzv2m_csi_pio_transfer()
503 rzv2m_csi_start_stop_operation(csi, 0, false); in rzv2m_csi_pio_transfer()
506 if (csi->rxbuf) { in rzv2m_csi_pio_transfer()
507 ret = rzv2m_csi_read_rxfifo(csi); in rzv2m_csi_pio_transfer()
511 if (csi->bytes_received == csi->buffer_len) in rzv2m_csi_pio_transfer()
514 rzv2m_csi_empty_rxfifo(csi); in rzv2m_csi_pio_transfer()
517 if (csi->errors) { in rzv2m_csi_pio_transfer()
518 ret = -EIO; in rzv2m_csi_pio_transfer()
523 rzv2m_csi_start_stop_operation(csi, 0, true); in rzv2m_csi_pio_transfer()
524 rzv2m_csi_disable_all_irqs(csi); in rzv2m_csi_pio_transfer()
525 rzv2m_csi_enable_rx_trigger(csi, false); in rzv2m_csi_pio_transfer()
526 rzv2m_csi_clear_all_irqs(csi); in rzv2m_csi_pio_transfer()
535 struct rzv2m_csi_priv *csi = spi_controller_get_devdata(controller); in rzv2m_csi_transfer_one() local
536 struct device *dev = csi->dev; in rzv2m_csi_transfer_one()
539 csi->txbuf = transfer->tx_buf; in rzv2m_csi_transfer_one()
540 csi->rxbuf = transfer->rx_buf; in rzv2m_csi_transfer_one()
541 csi->buffer_len = transfer->len; in rzv2m_csi_transfer_one()
543 rzv2m_csi_setup_operating_mode(csi, transfer); in rzv2m_csi_transfer_one()
545 if (!spi_controller_is_target(csi->controller)) in rzv2m_csi_transfer_one()
546 rzv2m_csi_setup_clock(csi, transfer->speed_hz); in rzv2m_csi_transfer_one()
548 ret = rzv2m_csi_pio_transfer(csi); in rzv2m_csi_transfer_one()
550 if (csi->errors & UNDERRUN_ERROR) in rzv2m_csi_transfer_one()
552 if (csi->errors & OVERFLOW_ERROR) in rzv2m_csi_transfer_one()
554 if (csi->errors & TX_TIMEOUT_ERROR) in rzv2m_csi_transfer_one()
556 if (csi->errors & RX_TIMEOUT_ERROR) in rzv2m_csi_transfer_one()
565 struct rzv2m_csi_priv *csi = spi_controller_get_devdata(ctlr); in rzv2m_csi_target_abort() local
567 csi->target_aborted = true; in rzv2m_csi_target_abort()
568 wake_up(&csi->wait); in rzv2m_csi_target_abort()
575 struct device_node *np = pdev->dev.of_node; in rzv2m_csi_probe()
577 struct device *dev = &pdev->dev; in rzv2m_csi_probe()
578 struct rzv2m_csi_priv *csi; in rzv2m_csi_probe() local
584 target_mode = of_property_read_bool(np, "spi-slave"); in rzv2m_csi_probe()
587 controller = devm_spi_alloc_target(dev, sizeof(*csi)); in rzv2m_csi_probe()
589 controller = devm_spi_alloc_host(dev, sizeof(*csi)); in rzv2m_csi_probe()
592 return -ENOMEM; in rzv2m_csi_probe()
594 csi = spi_controller_get_devdata(controller); in rzv2m_csi_probe()
595 platform_set_drvdata(pdev, csi); in rzv2m_csi_probe()
597 csi->use_ss_pin = false; in rzv2m_csi_probe()
599 !of_property_read_bool(np, "renesas,csi-no-ss")) in rzv2m_csi_probe()
600 csi->use_ss_pin = true; in rzv2m_csi_probe()
602 csi->dev = dev; in rzv2m_csi_probe()
603 csi->controller = controller; in rzv2m_csi_probe()
604 csi->target_aborted = false; in rzv2m_csi_probe()
606 csi->base = devm_platform_ioremap_resource(pdev, 0); in rzv2m_csi_probe()
607 if (IS_ERR(csi->base)) in rzv2m_csi_probe()
608 return PTR_ERR(csi->base); in rzv2m_csi_probe()
614 csi->csiclk = devm_clk_get(dev, "csiclk"); in rzv2m_csi_probe()
615 if (IS_ERR(csi->csiclk)) in rzv2m_csi_probe()
616 return dev_err_probe(dev, PTR_ERR(csi->csiclk), in rzv2m_csi_probe()
619 csi->pclk = devm_clk_get(dev, "pclk"); in rzv2m_csi_probe()
620 if (IS_ERR(csi->pclk)) in rzv2m_csi_probe()
621 return dev_err_probe(dev, PTR_ERR(csi->pclk), in rzv2m_csi_probe()
628 init_waitqueue_head(&csi->wait); in rzv2m_csi_probe()
630 controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH; in rzv2m_csi_probe()
631 controller->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8); in rzv2m_csi_probe()
632 controller->setup = rzv2m_csi_setup; in rzv2m_csi_probe()
633 controller->transfer_one = rzv2m_csi_transfer_one; in rzv2m_csi_probe()
634 controller->use_gpio_descriptors = true; in rzv2m_csi_probe()
635 controller->target_abort = rzv2m_csi_target_abort; in rzv2m_csi_probe()
637 device_set_node(&controller->dev, dev_fwnode(dev)); in rzv2m_csi_probe()
640 dev_name(dev), csi); in rzv2m_csi_probe()
652 ret = rzv2m_csi_sw_reset(csi, 1); in rzv2m_csi_probe()
656 ret = clk_prepare_enable(csi->csiclk); in rzv2m_csi_probe()
662 clk_disable_unprepare(csi->csiclk); in rzv2m_csi_probe()
671 struct rzv2m_csi_priv *csi = platform_get_drvdata(pdev); in rzv2m_csi_remove() local
673 spi_unregister_controller(csi->controller); in rzv2m_csi_remove()
674 rzv2m_csi_sw_reset(csi, 1); in rzv2m_csi_remove()
675 clk_disable_unprepare(csi->csiclk); in rzv2m_csi_remove()
679 { .compatible = "renesas,rzv2m-csi" },