diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c index 38ee09e389c9..f45af5884638 100644 --- a/drivers/spi/spi-rzv2h-rspi.c +++ b/drivers/spi/spi-rzv2h-rspi.c @@ -50,7 +50,6 @@ /* Register SPBR */ #define RSPI_SPBR_SPR_MIN 0 -#define RSPI_SPBR_SPR_PCLK_MIN 1 #define RSPI_SPBR_SPR_MAX 255 /* Register SPCMD */ @@ -77,6 +76,8 @@ #define RSPI_RESET_NUM 2 +#define RSPI_MAX_SPEED_HZ 50000000 + struct rzv2h_rspi_best_clock { struct clk *clk; unsigned long clk_rate; @@ -87,9 +88,9 @@ struct rzv2h_rspi_best_clock { }; struct rzv2h_rspi_info { - void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max, + void (*find_tclk_rate)(struct clk *clk, u32 hz, struct rzv2h_rspi_best_clock *best_clk); - void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high, + void (*find_pclk_rate)(struct clk *clk, u32 hz, struct rzv2h_rspi_best_clock *best_clk); const char *tclk_name; unsigned int fifo_size; @@ -412,7 +413,6 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr, } static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz, - u8 spr_min, u8 spr_max, struct rzv2h_rspi_best_clock *best) { 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, * minimum SPR that is in the valid range. */ min_rate_spr = DIV_ROUND_CLOSEST(clk_min_rate, rate_div) - 1; - if (min_rate_spr > spr_max) + if (min_rate_spr > RSPI_SPBR_SPR_MAX) continue; /* @@ -473,14 +473,14 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz, * maximum SPR that is in the valid range. */ max_rate_spr = DIV_ROUND_CLOSEST(clk_max_rate, rate_div) - 1; - if (max_rate_spr < spr_min) + if (max_rate_spr < RSPI_SPBR_SPR_MIN) break; - if (min_rate_spr < spr_min) - min_rate_spr = spr_min; + if (min_rate_spr < RSPI_SPBR_SPR_MIN) + min_rate_spr = RSPI_SPBR_SPR_MIN; - if (max_rate_spr > spr_max) - max_rate_spr = spr_max; + if (max_rate_spr > RSPI_SPBR_SPR_MAX) + max_rate_spr = RSPI_SPBR_SPR_MAX; for (spr = min_rate_spr; spr <= max_rate_spr; spr++) { clk_rate = (spr + 1) * rate_div; @@ -511,7 +511,6 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz, } static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz, - u8 spr_min, u8 spr_max, struct rzv2h_rspi_best_clock *best) { unsigned long clk_rate; @@ -533,7 +532,18 @@ static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz, for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) { spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1))); spr--; - if (spr >= spr_min && spr <= spr_max) + /* + * Skip SPR=0 and BRDV=0 as it is not a valid combination: + * - On RZ/G3E, RZ/G3L, RZ/V2H(P) and RZ/V2N, RSPI_n_TCLK is + * fixed at 200MHz and SPR=0 and BRDV=0 results in the maximum + * bit rate of 100Mbps which is prohibited. + * - On RZ/T2H and RZ/N2H, when PCLK (125MHz) is used as + * the clock source, SPR=0 and BRDV=0 is explicitly listed + * as unsupported in the hardware manual (Table 36.7). + */ + if (!spr && !brdv) + continue; + if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX) goto clock_found; } @@ -563,16 +573,10 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz) }; int ret; - rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN, - RSPI_SPBR_SPR_MAX, &best_clock); + rspi->info->find_tclk_rate(rspi->tclk, hz, &best_clock); - /* - * T2H and N2H can also use PCLK as a source, which is 125MHz, but not - * when both SPR and BRDV are 0. - */ if (best_clock.error && rspi->info->find_pclk_rate) - rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN, - RSPI_SPBR_SPR_MAX, &best_clock); + rspi->info->find_pclk_rate(rspi->pclk, hz, &best_clock); if (!best_clock.clk_rate) return -EINVAL; @@ -771,13 +775,7 @@ static int rzv2h_rspi_probe(struct platform_device *pdev) RSPI_SPBR_SPR_MAX, RSPI_SPCMD_BRDV_MAX); - tclk_rate = clk_round_rate(rspi->tclk, ULONG_MAX); - if (tclk_rate < 0) - return tclk_rate; - - controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate, - RSPI_SPBR_SPR_MIN, - RSPI_SPCMD_BRDV_MIN); + controller->max_speed_hz = RSPI_MAX_SPEED_HZ; controller->dma_tx = devm_dma_request_chan(dev, "tx"); if (IS_ERR(controller->dma_tx)) {