Skip to content

Commit 8097dbd

Browse files
committed
spi: Add RZ/V2M CSI target support
Merge series from Fabrizio Castro <[email protected]>: The CSI IP found inside the Renesas RZ/V2M SoC supports both SPI host and target. This series extends the CSI dt-bindings and driver to add SPI target support.
2 parents 9aaa25d + a4f7ef6 commit 8097dbd

File tree

3 files changed

+94
-45
lines changed

3 files changed

+94
-45
lines changed

Documentation/devicetree/bindings/spi/renesas,rzv2m-csi.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ properties:
3939
power-domains:
4040
maxItems: 1
4141

42+
renesas,csi-no-ss:
43+
type: boolean
44+
description:
45+
The CSI Slave Selection (SS) pin won't be used to enable transmission and
46+
reception. Only available when in target mode.
47+
4248
required:
4349
- compatible
4450
- reg
@@ -50,6 +56,9 @@ required:
5056
- '#address-cells'
5157
- '#size-cells'
5258

59+
dependencies:
60+
renesas,csi-no-ss: [ spi-slave ]
61+
5362
unevaluatedProperties: false
5463

5564
examples:

drivers/spi/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,8 @@ config SPI_RZV2M_CSI
862862
tristate "Renesas RZ/V2M CSI controller"
863863
depends on ARCH_RENESAS || COMPILE_TEST
864864
help
865-
SPI driver for Renesas RZ/V2M Clocked Serial Interface (CSI)
865+
SPI driver for Renesas RZ/V2M Clocked Serial Interface (CSI).
866+
CSI supports both SPI host and SPI target roles.
866867

867868
config SPI_QCOM_QSPI
868869
tristate "QTI QSPI controller"

drivers/spi/spi-rzv2m-csi.c

Lines changed: 83 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/interrupt.h>
1212
#include <linux/iopoll.h>
1313
#include <linux/log2.h>
14+
#include <linux/of.h>
1415
#include <linux/platform_device.h>
1516
#include <linux/property.h>
1617
#include <linux/reset.h>
@@ -38,6 +39,9 @@
3839
#define CSI_MODE_SETUP 0x00000040
3940

4041
/* CSI_CLKSEL */
42+
#define CSI_CLKSEL_SS_ENA BIT(19)
43+
#define CSI_CLKSEL_SS_POL BIT(18)
44+
#define CSI_CLKSEL_SS (CSI_CLKSEL_SS_ENA | CSI_CLKSEL_SS_POL)
4145
#define CSI_CLKSEL_CKP BIT(17)
4246
#define CSI_CLKSEL_DAP BIT(16)
4347
#define CSI_CLKSEL_MODE (CSI_CLKSEL_CKP|CSI_CLKSEL_DAP)
@@ -82,6 +86,10 @@
8286

8387
#define CSI_MAX_SPI_SCKO (8 * HZ_PER_MHZ)
8488

89+
#define CSI_CLKSEL_SS_DISABLED 0
90+
#define CSI_CLKSEL_SS_ENABLED_ACTIVE_LOW BIT(1)
91+
#define CSI_CLKSEL_SS_ENABLED_ACTIVE_HIGH GENMASK(1, 0)
92+
8593
struct rzv2m_csi_priv {
8694
void __iomem *base;
8795
struct clk *csiclk;
@@ -99,6 +107,8 @@ struct rzv2m_csi_priv {
99107
wait_queue_head_t wait;
100108
u32 errors;
101109
u32 status;
110+
bool target_aborted;
111+
bool use_ss_pin;
102112
};
103113

104114
static void rzv2m_csi_reg_write_bit(const struct rzv2m_csi_priv *csi,
@@ -193,6 +203,14 @@ static int rzv2m_csi_read_rxfifo(struct rzv2m_csi_priv *csi)
193203
return 0;
194204
}
195205

206+
static inline void rzv2m_csi_empty_rxfifo(struct rzv2m_csi_priv *csi)
207+
{
208+
unsigned int i;
209+
210+
for (i = 0; i < csi->words_to_transfer; i++)
211+
readl(csi->base + CSI_IFIFO);
212+
}
213+
196214
static inline void rzv2m_csi_calc_current_transfer(struct rzv2m_csi_priv *csi)
197215
{
198216
unsigned int bytes_transferred = max(csi->bytes_received, csi->bytes_sent);
@@ -279,40 +297,31 @@ static int rzv2m_csi_wait_for_interrupt(struct rzv2m_csi_priv *csi,
279297

280298
rzv2m_csi_enable_irqs(csi, enable_bits);
281299

282-
ret = wait_event_timeout(csi->wait,
283-
((csi->status & wait_mask) == wait_mask) ||
284-
csi->errors, HZ);
300+
if (spi_controller_is_target(csi->controller)) {
301+
ret = wait_event_interruptible(csi->wait,
302+
((csi->status & wait_mask) == wait_mask) ||
303+
csi->errors || csi->target_aborted);
304+
if (ret || csi->target_aborted)
305+
ret = -EINTR;
306+
} else {
307+
ret = wait_event_timeout(csi->wait,
308+
((csi->status & wait_mask) == wait_mask) ||
309+
csi->errors, HZ) == 0 ? -ETIMEDOUT : 0;
310+
}
285311

286312
rzv2m_csi_disable_irqs(csi, enable_bits);
287313

288314
if (csi->errors)
289315
return -EIO;
290316

291-
if (!ret)
292-
return -ETIMEDOUT;
293-
294-
return 0;
295-
}
296-
297-
static int rzv2m_csi_wait_for_tx_empty(struct rzv2m_csi_priv *csi)
298-
{
299-
int ret;
300-
301-
if (readl(csi->base + CSI_OFIFOL) == 0)
302-
return 0;
303-
304-
ret = rzv2m_csi_wait_for_interrupt(csi, CSI_INT_TREND, CSI_CNT_TREND_E);
305-
if (ret == -ETIMEDOUT)
306-
csi->errors |= TX_TIMEOUT_ERROR;
307-
308317
return ret;
309318
}
310319

311320
static inline int rzv2m_csi_wait_for_rx_ready(struct rzv2m_csi_priv *csi)
312321
{
313322
int ret;
314323

315-
if (readl(csi->base + CSI_IFIFOL) == csi->bytes_to_transfer)
324+
if (readl(csi->base + CSI_IFIFOL) >= csi->bytes_to_transfer)
316325
return 0;
317326

318327
ret = rzv2m_csi_wait_for_interrupt(csi, CSI_INT_R_TRGR,
@@ -388,6 +397,7 @@ static void rzv2m_csi_setup_operating_mode(struct rzv2m_csi_priv *csi,
388397
static int rzv2m_csi_setup(struct spi_device *spi)
389398
{
390399
struct rzv2m_csi_priv *csi = spi_controller_get_devdata(spi->controller);
400+
u32 slave_selection = CSI_CLKSEL_SS_DISABLED;
391401
int ret;
392402

393403
rzv2m_csi_sw_reset(csi, 0);
@@ -402,8 +412,17 @@ static int rzv2m_csi_setup(struct spi_device *spi)
402412
rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_DIR,
403413
!!(spi->mode & SPI_LSB_FIRST));
404414

405-
/* Set the operation mode as master */
406-
rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SLAVE, 0);
415+
/* Set the role, 1 for target and 0 for host */
416+
rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SLAVE,
417+
!!spi_controller_is_target(csi->controller));
418+
419+
if (csi->use_ss_pin)
420+
slave_selection = spi->mode & SPI_CS_HIGH ?
421+
CSI_CLKSEL_SS_ENABLED_ACTIVE_HIGH :
422+
CSI_CLKSEL_SS_ENABLED_ACTIVE_LOW;
423+
424+
/* Configure the slave selection (SS) pin */
425+
rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SS, slave_selection);
407426

408427
/* Give the IP a SW reset */
409428
ret = rzv2m_csi_sw_reset(csi, 1);
@@ -431,9 +450,13 @@ static int rzv2m_csi_pio_transfer(struct rzv2m_csi_priv *csi)
431450
/* Make sure the TX FIFO is empty */
432451
writel(0, csi->base + CSI_OFIFOL);
433452

453+
/* Make sure the RX FIFO is empty */
454+
writel(0, csi->base + CSI_IFIFOL);
455+
434456
csi->bytes_sent = 0;
435457
csi->bytes_received = 0;
436458
csi->errors = 0;
459+
csi->target_aborted = false;
437460

438461
rzv2m_csi_disable_all_irqs(csi);
439462
rzv2m_csi_clear_all_irqs(csi);
@@ -452,28 +475,21 @@ static int rzv2m_csi_pio_transfer(struct rzv2m_csi_priv *csi)
452475

453476
rzv2m_csi_enable_irqs(csi, CSI_INT_OVERF | CSI_INT_UNDER);
454477

455-
/* Make sure the RX FIFO is empty */
456-
writel(0, csi->base + CSI_IFIFOL);
457-
458478
writel(readl(csi->base + CSI_INT), csi->base + CSI_INT);
459479
csi->status = 0;
460480

461-
rzv2m_csi_start_stop_operation(csi, 1, false);
462-
463481
/* TX */
464482
if (csi->txbuf) {
465483
ret = rzv2m_csi_fill_txfifo(csi);
466484
if (ret)
467485
break;
468486

469-
ret = rzv2m_csi_wait_for_tx_empty(csi);
470-
if (ret)
471-
break;
472-
473487
if (csi->bytes_sent == csi->buffer_len)
474488
tx_completed = true;
475489
}
476490

491+
rzv2m_csi_start_stop_operation(csi, 1, false);
492+
477493
/*
478494
* Make sure the RX FIFO contains the desired number of words.
479495
* We then either flush its content, or we copy it onto
@@ -483,31 +499,28 @@ static int rzv2m_csi_pio_transfer(struct rzv2m_csi_priv *csi)
483499
if (ret)
484500
break;
485501

486-
/* RX */
487-
if (csi->rxbuf) {
502+
if (!spi_controller_is_target(csi->controller))
488503
rzv2m_csi_start_stop_operation(csi, 0, false);
489504

505+
/* RX */
506+
if (csi->rxbuf) {
490507
ret = rzv2m_csi_read_rxfifo(csi);
491508
if (ret)
492509
break;
493510

494511
if (csi->bytes_received == csi->buffer_len)
495512
rx_completed = true;
513+
} else {
514+
rzv2m_csi_empty_rxfifo(csi);
496515
}
497516

498-
ret = rzv2m_csi_start_stop_operation(csi, 0, true);
499-
if (ret)
500-
goto pio_quit;
501-
502517
if (csi->errors) {
503518
ret = -EIO;
504-
goto pio_quit;
519+
break;
505520
}
506521
}
507522

508523
rzv2m_csi_start_stop_operation(csi, 0, true);
509-
510-
pio_quit:
511524
rzv2m_csi_disable_all_irqs(csi);
512525
rzv2m_csi_enable_rx_trigger(csi, false);
513526
rzv2m_csi_clear_all_irqs(csi);
@@ -529,7 +542,8 @@ static int rzv2m_csi_transfer_one(struct spi_controller *controller,
529542

530543
rzv2m_csi_setup_operating_mode(csi, transfer);
531544

532-
rzv2m_csi_setup_clock(csi, transfer->speed_hz);
545+
if (!spi_controller_is_target(csi->controller))
546+
rzv2m_csi_setup_clock(csi, transfer->speed_hz);
533547

534548
ret = rzv2m_csi_pio_transfer(csi);
535549
if (ret) {
@@ -546,24 +560,48 @@ static int rzv2m_csi_transfer_one(struct spi_controller *controller,
546560
return ret;
547561
}
548562

563+
static int rzv2m_csi_target_abort(struct spi_controller *ctlr)
564+
{
565+
struct rzv2m_csi_priv *csi = spi_controller_get_devdata(ctlr);
566+
567+
csi->target_aborted = true;
568+
wake_up(&csi->wait);
569+
570+
return 0;
571+
}
572+
549573
static int rzv2m_csi_probe(struct platform_device *pdev)
550574
{
575+
struct device_node *np = pdev->dev.of_node;
551576
struct spi_controller *controller;
552577
struct device *dev = &pdev->dev;
553578
struct rzv2m_csi_priv *csi;
554579
struct reset_control *rstc;
580+
bool target_mode;
555581
int irq;
556582
int ret;
557583

558-
controller = devm_spi_alloc_host(dev, sizeof(*csi));
584+
target_mode = of_property_read_bool(np, "spi-slave");
585+
586+
if (target_mode)
587+
controller = devm_spi_alloc_target(dev, sizeof(*csi));
588+
else
589+
controller = devm_spi_alloc_host(dev, sizeof(*csi));
590+
559591
if (!controller)
560592
return -ENOMEM;
561593

562594
csi = spi_controller_get_devdata(controller);
563595
platform_set_drvdata(pdev, csi);
564596

597+
csi->use_ss_pin = false;
598+
if (spi_controller_is_target(controller) &&
599+
!of_property_read_bool(np, "renesas,csi-no-ss"))
600+
csi->use_ss_pin = true;
601+
565602
csi->dev = dev;
566603
csi->controller = controller;
604+
csi->target_aborted = false;
567605

568606
csi->base = devm_platform_ioremap_resource(pdev, 0);
569607
if (IS_ERR(csi->base))
@@ -589,11 +627,12 @@ static int rzv2m_csi_probe(struct platform_device *pdev)
589627

590628
init_waitqueue_head(&csi->wait);
591629

592-
controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
630+
controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_CS_HIGH;
593631
controller->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
594632
controller->setup = rzv2m_csi_setup;
595633
controller->transfer_one = rzv2m_csi_transfer_one;
596634
controller->use_gpio_descriptors = true;
635+
controller->target_abort = rzv2m_csi_target_abort;
597636

598637
device_set_node(&controller->dev, dev_fwnode(dev));
599638

0 commit comments

Comments
 (0)