Lines Matching +full:r9a09g057 +full:- +full:rspi

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Renesas RZ/V2H Renesas Serial Peripheral Interface (RSPI)
84 static inline void rzv2h_rspi_tx_##type(struct rzv2h_rspi_priv *rspi, \
92 func(buf, rspi->base + RSPI_SPDR); \
96 static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi, \
99 type buf = func(rspi->base + RSPI_SPDR); \
112 static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi, in RZV2H_RSPI_TX()
118 tmp = (readl(rspi->base + reg_offs) & ~bit_mask) | value; in RZV2H_RSPI_TX()
119 writel(tmp, rspi->base + reg_offs); in RZV2H_RSPI_TX()
122 static inline void rzv2h_rspi_spe_disable(const struct rzv2h_rspi_priv *rspi) in rzv2h_rspi_spe_disable() argument
124 rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 0); in rzv2h_rspi_spe_disable()
127 static inline void rzv2h_rspi_spe_enable(const struct rzv2h_rspi_priv *rspi) in rzv2h_rspi_spe_enable() argument
129 rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 1); in rzv2h_rspi_spe_enable()
132 static inline void rzv2h_rspi_clear_fifos(const struct rzv2h_rspi_priv *rspi) in rzv2h_rspi_clear_fifos() argument
134 writeb(1, rspi->base + RSPI_SPFCR); in rzv2h_rspi_clear_fifos()
137 static inline void rzv2h_rspi_clear_all_irqs(struct rzv2h_rspi_priv *rspi) in rzv2h_rspi_clear_all_irqs() argument
139 writew(RSPI_SPSRC_CLEAR, rspi->base + RSPI_SPSRC); in rzv2h_rspi_clear_all_irqs()
140 rspi->status = 0; in rzv2h_rspi_clear_all_irqs()
145 struct rzv2h_rspi_priv *rspi = data; in rzv2h_rx_irq_handler() local
147 rspi->status = readw(rspi->base + RSPI_SPSR); in rzv2h_rx_irq_handler()
148 wake_up(&rspi->wait); in rzv2h_rx_irq_handler()
153 static inline int rzv2h_rspi_wait_for_interrupt(struct rzv2h_rspi_priv *rspi, in rzv2h_rspi_wait_for_interrupt() argument
156 return wait_event_timeout(rspi->wait, (rspi->status & wait_mask), in rzv2h_rspi_wait_for_interrupt()
157 HZ) == 0 ? -ETIMEDOUT : 0; in rzv2h_rspi_wait_for_interrupt()
160 static void rzv2h_rspi_send(struct rzv2h_rspi_priv *rspi, const void *txbuf, in rzv2h_rspi_send() argument
163 switch (rspi->bytes_per_word) { in rzv2h_rspi_send()
165 rzv2h_rspi_tx_u32(rspi, txbuf, index); in rzv2h_rspi_send()
168 rzv2h_rspi_tx_u16(rspi, txbuf, index); in rzv2h_rspi_send()
171 rzv2h_rspi_tx_u8(rspi, txbuf, index); in rzv2h_rspi_send()
175 static int rzv2h_rspi_receive(struct rzv2h_rspi_priv *rspi, void *rxbuf, in rzv2h_rspi_receive() argument
180 ret = rzv2h_rspi_wait_for_interrupt(rspi, RSPI_SPSR_SPRF); in rzv2h_rspi_receive()
184 switch (rspi->bytes_per_word) { in rzv2h_rspi_receive()
186 rzv2h_rspi_rx_u32(rspi, rxbuf, index); in rzv2h_rspi_receive()
189 rzv2h_rspi_rx_u16(rspi, rxbuf, index); in rzv2h_rspi_receive()
192 rzv2h_rspi_rx_u8(rspi, rxbuf, index); in rzv2h_rspi_receive()
202 struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(controller); in rzv2h_rspi_transfer_one() local
206 transfer->effective_speed_hz = rspi->freq; in rzv2h_rspi_transfer_one()
207 words_to_transfer = transfer->len / rspi->bytes_per_word; in rzv2h_rspi_transfer_one()
210 rzv2h_rspi_clear_all_irqs(rspi); in rzv2h_rspi_transfer_one()
212 rzv2h_rspi_send(rspi, transfer->tx_buf, i); in rzv2h_rspi_transfer_one()
214 ret = rzv2h_rspi_receive(rspi, transfer->rx_buf, i); in rzv2h_rspi_transfer_one()
219 rzv2h_rspi_clear_all_irqs(rspi); in rzv2h_rspi_transfer_one()
222 transfer->error = SPI_TRANS_FAIL_IO; in rzv2h_rspi_transfer_one()
235 static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz) in rzv2h_rspi_setup_clock() argument
247 * * n = SPR - is RSPI_SPBR.SPR (from 0 to 255) in rzv2h_rspi_setup_clock()
248 * * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3) in rzv2h_rspi_setup_clock()
250 tclk_rate = clk_get_rate(rspi->tclk); in rzv2h_rspi_setup_clock()
253 spr--; in rzv2h_rspi_setup_clock()
261 rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_BRDV, brdv); in rzv2h_rspi_setup_clock()
262 writeb(spr, rspi->base + RSPI_SPBR); in rzv2h_rspi_setup_clock()
270 struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr); in rzv2h_rspi_prepare_message() local
271 const struct spi_device *spi = message->spi; in rzv2h_rspi_prepare_message()
279 rzv2h_rspi_spe_disable(rspi); in rzv2h_rspi_prepare_message()
284 /* Auto-stop function */ in rzv2h_rspi_prepare_message()
290 writel(conf32, rspi->base + RSPI_SPCR); in rzv2h_rspi_prepare_message()
293 writeb(0x0, rspi->base + RSPI_SPSCR); in rzv2h_rspi_prepare_message()
296 conf32 = FIELD_PREP(RSPI_SPCMD_CPOL, !!(spi->mode & SPI_CPOL)); in rzv2h_rspi_prepare_message()
297 conf32 |= FIELD_PREP(RSPI_SPCMD_CPHA, !!(spi->mode & SPI_CPHA)); in rzv2h_rspi_prepare_message()
298 conf32 |= FIELD_PREP(RSPI_SPCMD_LSBF, !!(spi->mode & SPI_LSB_FIRST)); in rzv2h_rspi_prepare_message()
301 writel(conf32, rspi->base + RSPI_SPCMD); in rzv2h_rspi_prepare_message()
302 if (spi->mode & SPI_CS_HIGH) in rzv2h_rspi_prepare_message()
303 writeb(BIT(spi_get_chipselect(spi, 0)), rspi->base + RSPI_SSLP); in rzv2h_rspi_prepare_message()
305 writeb(0, rspi->base + RSPI_SSLP); in rzv2h_rspi_prepare_message()
308 conf16 = FIELD_PREP(RSPI_SPDCR2_TTRG, RSPI_FIFO_SIZE - 1); in rzv2h_rspi_prepare_message()
310 writew(conf16, rspi->base + RSPI_SPDCR2); in rzv2h_rspi_prepare_message()
312 rzv2h_rspi_clear_fifos(rspi); in rzv2h_rspi_prepare_message()
314 list_for_each_entry(xfer, &message->transfers, transfer_list) { in rzv2h_rspi_prepare_message()
315 if (!xfer->speed_hz) in rzv2h_rspi_prepare_message()
318 speed_hz = min(xfer->speed_hz, speed_hz); in rzv2h_rspi_prepare_message()
319 bits_per_word = xfer->bits_per_word; in rzv2h_rspi_prepare_message()
323 return -EINVAL; in rzv2h_rspi_prepare_message()
325 rspi->bytes_per_word = roundup_pow_of_two(BITS_TO_BYTES(bits_per_word)); in rzv2h_rspi_prepare_message()
326 rzv2h_rspi_reg_rmw(rspi, RSPI_SPCMD, RSPI_SPCMD_SPB, bits_per_word - 1); in rzv2h_rspi_prepare_message()
328 rspi->freq = rzv2h_rspi_setup_clock(rspi, speed_hz); in rzv2h_rspi_prepare_message()
329 if (!rspi->freq) in rzv2h_rspi_prepare_message()
330 return -EINVAL; in rzv2h_rspi_prepare_message()
332 rzv2h_rspi_spe_enable(rspi); in rzv2h_rspi_prepare_message()
340 struct rzv2h_rspi_priv *rspi = spi_controller_get_devdata(ctlr); in rzv2h_rspi_unprepare_message() local
342 rzv2h_rspi_spe_disable(rspi); in rzv2h_rspi_unprepare_message()
350 struct device *dev = &pdev->dev; in rzv2h_rspi_probe()
351 struct rzv2h_rspi_priv *rspi; in rzv2h_rspi_probe() local
356 controller = devm_spi_alloc_host(dev, sizeof(*rspi)); in rzv2h_rspi_probe()
358 return -ENOMEM; in rzv2h_rspi_probe()
360 rspi = spi_controller_get_devdata(controller); in rzv2h_rspi_probe()
361 platform_set_drvdata(pdev, rspi); in rzv2h_rspi_probe()
363 rspi->controller = controller; in rzv2h_rspi_probe()
365 rspi->base = devm_platform_ioremap_resource(pdev, 0); in rzv2h_rspi_probe()
366 if (IS_ERR(rspi->base)) in rzv2h_rspi_probe()
367 return PTR_ERR(rspi->base); in rzv2h_rspi_probe()
371 return dev_err_probe(dev, ret >= 0 ? -EINVAL : ret, in rzv2h_rspi_probe()
375 rspi->tclk = clks[i].clk; in rzv2h_rspi_probe()
380 if (!rspi->tclk) in rzv2h_rspi_probe()
381 return dev_err_probe(dev, -EINVAL, "Failed to get tclk\n"); in rzv2h_rspi_probe()
383 tclk_rate = clk_get_rate(rspi->tclk); in rzv2h_rspi_probe()
385 rspi->resets[0].id = "presetn"; in rzv2h_rspi_probe()
386 rspi->resets[1].id = "tresetn"; in rzv2h_rspi_probe()
388 rspi->resets); in rzv2h_rspi_probe()
396 ret = reset_control_bulk_deassert(RSPI_RESET_NUM, rspi->resets); in rzv2h_rspi_probe()
400 init_waitqueue_head(&rspi->wait); in rzv2h_rspi_probe()
403 dev_name(dev), rspi); in rzv2h_rspi_probe()
409 controller->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | in rzv2h_rspi_probe()
411 controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); in rzv2h_rspi_probe()
412 controller->prepare_message = rzv2h_rspi_prepare_message; in rzv2h_rspi_probe()
413 controller->unprepare_message = rzv2h_rspi_unprepare_message; in rzv2h_rspi_probe()
414 controller->num_chipselect = 4; in rzv2h_rspi_probe()
415 controller->transfer_one = rzv2h_rspi_transfer_one; in rzv2h_rspi_probe()
416 controller->min_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate, in rzv2h_rspi_probe()
419 controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate, in rzv2h_rspi_probe()
423 device_set_node(&controller->dev, dev_fwnode(dev)); in rzv2h_rspi_probe()
434 reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets); in rzv2h_rspi_probe()
441 struct rzv2h_rspi_priv *rspi = platform_get_drvdata(pdev); in rzv2h_rspi_remove() local
443 spi_unregister_controller(rspi->controller); in rzv2h_rspi_remove()
445 reset_control_bulk_assert(RSPI_RESET_NUM, rspi->resets); in rzv2h_rspi_remove()
449 { .compatible = "renesas,r9a09g057-rspi" },