Skip to content

Commit 77d9315

Browse files
Demon000broonie
authored andcommitted
spi: rzv2h-rspi: make transfer clock rate finding chip-specific
The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs have a more complicated clocking setup for the SPI transfer clock than RZ/V2H, as the clock from which it is generated supports multiple dividers. To prepare for adding support for these SoCs, split out the logic for finding the SPR and BRDV for a fixed clock into rzv2h_rspi_find_rate_fixed(), and add and use a .find_tclk_rate() callback into the chip-specific structure. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Link: https://patch.msgid.link/20251119161434.595677-7-cosmin-gabriel.tanislav.xa@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 8878249 commit 77d9315

1 file changed

Lines changed: 53 additions & 9 deletions

File tree

drivers/spi/spi-rzv2h-rspi.c

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,18 @@
6767

6868
#define RSPI_RESET_NUM 2
6969

70+
struct rzv2h_rspi_best_clock {
71+
struct clk *clk;
72+
unsigned long clk_rate;
73+
unsigned long error;
74+
u32 actual_hz;
75+
u8 brdv;
76+
u8 spr;
77+
};
78+
7079
struct rzv2h_rspi_info {
80+
void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
81+
struct rzv2h_rspi_best_clock *best_clk);
7182
const char *tclk_name;
7283
unsigned int fifo_size;
7384
unsigned int num_clks;
@@ -240,9 +251,13 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
240251
return DIV_ROUND_UP(tclk_rate, (2 * (spr + 1) * (1 << brdv)));
241252
}
242253

243-
static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
254+
static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
255+
u8 spr_min, u8 spr_max,
256+
struct rzv2h_rspi_best_clock *best)
244257
{
245-
unsigned long tclk_rate;
258+
unsigned long clk_rate;
259+
unsigned long error;
260+
u32 actual_hz;
246261
int spr;
247262
u8 brdv;
248263

@@ -255,21 +270,49 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
255270
* * n = SPR - is RSPI_SPBR.SPR (from 0 to 255)
256271
* * N = BRDV - is RSPI_SPCMD.BRDV (from 0 to 3)
257272
*/
258-
tclk_rate = clk_get_rate(rspi->tclk);
273+
clk_rate = clk_get_rate(clk);
259274
for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
260-
spr = DIV_ROUND_UP(tclk_rate, hz * (1 << (brdv + 1)));
275+
spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1)));
261276
spr--;
262-
if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
277+
if (spr >= spr_min && spr <= spr_max)
263278
goto clock_found;
264279
}
265280

266-
return 0;
281+
return;
267282

268283
clock_found:
269-
rspi->spr = spr;
270-
rspi->brdv = brdv;
284+
actual_hz = rzv2h_rspi_calc_bitrate(clk_rate, spr, brdv);
285+
error = abs((long)hz - (long)actual_hz);
286+
287+
if (error >= best->error)
288+
return;
289+
290+
*best = (struct rzv2h_rspi_best_clock) {
291+
.clk = clk,
292+
.clk_rate = clk_rate,
293+
.error = error,
294+
.actual_hz = actual_hz,
295+
.brdv = brdv,
296+
.spr = spr,
297+
};
298+
}
299+
300+
static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
301+
{
302+
struct rzv2h_rspi_best_clock best_clock = {
303+
.error = ULONG_MAX,
304+
};
305+
306+
rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
307+
RSPI_SPBR_SPR_MAX, &best_clock);
308+
309+
if (!best_clock.clk_rate)
310+
return -EINVAL;
311+
312+
rspi->spr = best_clock.spr;
313+
rspi->brdv = best_clock.brdv;
271314

272-
return rzv2h_rspi_calc_bitrate(tclk_rate, spr, brdv);
315+
return best_clock.actual_hz;
273316
}
274317

275318
static int rzv2h_rspi_prepare_message(struct spi_controller *ctlr,
@@ -463,6 +506,7 @@ static void rzv2h_rspi_remove(struct platform_device *pdev)
463506
}
464507

465508
static const struct rzv2h_rspi_info rzv2h_info = {
509+
.find_tclk_rate = rzv2h_rspi_find_rate_fixed,
466510
.tclk_name = "tclk",
467511
.fifo_size = 16,
468512
.num_clks = 3,

0 commit comments

Comments
 (0)