Skip to content

Commit 6dd1302

Browse files
committed
spi: rzv2h-rspi: Fix max_speed_hz and clock configuration issues
Prabhakar <prabhakar.csengg@gmail.com> says: This patch series addresses three issues in the RZV2H RSPI driver: 1. The max_speed_hz field was advertising a prohibited bit rate, which could lead to incorrect behavior when userspace applications attempt to set the SPI clock speed. 2. The clock configuration logic allowed for an invalid combination of SPR=0 and BRDV=0, which is not supported by the hardware. 3. Simplified the clock rate search function as min/max speed parameters are not needed. Note, patches apply on top of next-20260409.
2 parents 9b7abfe + c958bb6 commit 6dd1302

1 file changed

Lines changed: 25 additions & 27 deletions

File tree

drivers/spi/spi-rzv2h-rspi.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050

5151
/* Register SPBR */
5252
#define RSPI_SPBR_SPR_MIN 0
53-
#define RSPI_SPBR_SPR_PCLK_MIN 1
5453
#define RSPI_SPBR_SPR_MAX 255
5554

5655
/* Register SPCMD */
@@ -77,6 +76,8 @@
7776

7877
#define RSPI_RESET_NUM 2
7978

79+
#define RSPI_MAX_SPEED_HZ 50000000
80+
8081
struct rzv2h_rspi_best_clock {
8182
struct clk *clk;
8283
unsigned long clk_rate;
@@ -87,9 +88,9 @@ struct rzv2h_rspi_best_clock {
8788
};
8889

8990
struct rzv2h_rspi_info {
90-
void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
91+
void (*find_tclk_rate)(struct clk *clk, u32 hz,
9192
struct rzv2h_rspi_best_clock *best_clk);
92-
void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high,
93+
void (*find_pclk_rate)(struct clk *clk, u32 hz,
9394
struct rzv2h_rspi_best_clock *best_clk);
9495
const char *tclk_name;
9596
unsigned int fifo_size;
@@ -412,7 +413,6 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
412413
}
413414

414415
static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
415-
u8 spr_min, u8 spr_max,
416416
struct rzv2h_rspi_best_clock *best)
417417
{
418418
long clk_rate, clk_min_rate, clk_max_rate;
@@ -463,7 +463,7 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
463463
* minimum SPR that is in the valid range.
464464
*/
465465
min_rate_spr = DIV_ROUND_CLOSEST(clk_min_rate, rate_div) - 1;
466-
if (min_rate_spr > spr_max)
466+
if (min_rate_spr > RSPI_SPBR_SPR_MAX)
467467
continue;
468468

469469
/*
@@ -473,14 +473,14 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
473473
* maximum SPR that is in the valid range.
474474
*/
475475
max_rate_spr = DIV_ROUND_CLOSEST(clk_max_rate, rate_div) - 1;
476-
if (max_rate_spr < spr_min)
476+
if (max_rate_spr < RSPI_SPBR_SPR_MIN)
477477
break;
478478

479-
if (min_rate_spr < spr_min)
480-
min_rate_spr = spr_min;
479+
if (min_rate_spr < RSPI_SPBR_SPR_MIN)
480+
min_rate_spr = RSPI_SPBR_SPR_MIN;
481481

482-
if (max_rate_spr > spr_max)
483-
max_rate_spr = spr_max;
482+
if (max_rate_spr > RSPI_SPBR_SPR_MAX)
483+
max_rate_spr = RSPI_SPBR_SPR_MAX;
484484

485485
for (spr = min_rate_spr; spr <= max_rate_spr; spr++) {
486486
clk_rate = (spr + 1) * rate_div;
@@ -511,7 +511,6 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
511511
}
512512

513513
static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
514-
u8 spr_min, u8 spr_max,
515514
struct rzv2h_rspi_best_clock *best)
516515
{
517516
unsigned long clk_rate;
@@ -533,7 +532,18 @@ static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
533532
for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
534533
spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1)));
535534
spr--;
536-
if (spr >= spr_min && spr <= spr_max)
535+
/*
536+
* Skip SPR=0 and BRDV=0 as it is not a valid combination:
537+
* - On RZ/G3E, RZ/G3L, RZ/V2H(P) and RZ/V2N, RSPI_n_TCLK is
538+
* fixed at 200MHz and SPR=0 and BRDV=0 results in the maximum
539+
* bit rate of 100Mbps which is prohibited.
540+
* - On RZ/T2H and RZ/N2H, when PCLK (125MHz) is used as
541+
* the clock source, SPR=0 and BRDV=0 is explicitly listed
542+
* as unsupported in the hardware manual (Table 36.7).
543+
*/
544+
if (!spr && !brdv)
545+
continue;
546+
if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
537547
goto clock_found;
538548
}
539549

@@ -563,16 +573,10 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
563573
};
564574
int ret;
565575

566-
rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
567-
RSPI_SPBR_SPR_MAX, &best_clock);
576+
rspi->info->find_tclk_rate(rspi->tclk, hz, &best_clock);
568577

569-
/*
570-
* T2H and N2H can also use PCLK as a source, which is 125MHz, but not
571-
* when both SPR and BRDV are 0.
572-
*/
573578
if (best_clock.error && rspi->info->find_pclk_rate)
574-
rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN,
575-
RSPI_SPBR_SPR_MAX, &best_clock);
579+
rspi->info->find_pclk_rate(rspi->pclk, hz, &best_clock);
576580

577581
if (!best_clock.clk_rate)
578582
return -EINVAL;
@@ -771,13 +775,7 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
771775
RSPI_SPBR_SPR_MAX,
772776
RSPI_SPCMD_BRDV_MAX);
773777

774-
tclk_rate = clk_round_rate(rspi->tclk, ULONG_MAX);
775-
if (tclk_rate < 0)
776-
return tclk_rate;
777-
778-
controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
779-
RSPI_SPBR_SPR_MIN,
780-
RSPI_SPCMD_BRDV_MIN);
778+
controller->max_speed_hz = RSPI_MAX_SPEED_HZ;
781779

782780
controller->dma_tx = devm_dma_request_chan(dev, "tx");
783781
if (IS_ERR(controller->dma_tx)) {

0 commit comments

Comments
 (0)