clk: renesas: rcar-gen3: Extend SDnH divider table
authorDirk Behme <dirk.behme@de.bosch.com>
Thu, 28 Sep 2023 08:03:17 +0000 (10:03 +0200)
committerGeert Uytterhoeven <geert+renesas@glider.be>
Thu, 5 Oct 2023 11:44:34 +0000 (13:44 +0200)
The clock dividers might be used with clock stop bit enabled or not.
Current tables only support recommended values from the datasheet.  This
might result in warnings like below because no valid clock divider is
found. Resulting in a 0 divider.

There are Renesas ARM Trusted Firmware version out there which e.g.
configure 0x201 (shifted logical right by 2: 0x80) and with this match
the added { STPnHCK | 0, 1 }:

https://github.com/renesas-rcar/arm-trusted-firmware/blob/rcar_gen3_v2.3/drivers/renesas/rcar/emmc/emmc_init.c#L108

------------[ cut here ]------------
sd1h: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set
WARNING: CPU: 1 PID: 1 at drivers/clk/clk-divider.c:141 divider_recalc_rate+0x48/0x70
Modules linked in:
CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.1.52 #1
Hardware name: Custom board based on r8a7796 (DT)
pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : divider_recalc_rate+0x48/0x70
...
------------[ cut here ]------------

Fixes: bb6d3fa98a41 ("clk: renesas: rcar-gen3: Switch to new SD clock handling")
Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
[wsa: extended the table to 5 entries, added comments, reword commit message a little]
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Dirk Behme <dirk.behme@de.bosch.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20230928080317.28224-1-wsa+renesas@sang-engineering.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
drivers/clk/renesas/rcar-cpg-lib.c

index e2e0447de1901d06a9e04ffa7cbbfcb0b7a6a1f2..5a15f8788b9227d90a6a1020a555fa09b1951beb 100644 (file)
@@ -70,8 +70,21 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,
 #define STPnHCK        BIT(9 - SDnSRCFC_SHIFT)
 
 static const struct clk_div_table cpg_sdh_div_table[] = {
+       /*
+        * These values are recommended by the datasheet.  Because they come
+        * first, Linux will only use these.
+        */
        { 0, 1 }, { 1, 2 }, { STPnHCK | 2, 4 }, { STPnHCK | 3, 8 },
-       { STPnHCK | 4, 16 }, { 0, 0 },
+       { STPnHCK | 4, 16 },
+       /*
+        * These values are not recommended because STPnHCK is wrong.  But they
+        * have been seen because of broken firmware.  So, we support reading
+        * them but Linux will sanitize them when initializing through
+        * recalc_rate.
+        */
+       { STPnHCK | 0, 1 }, { STPnHCK | 1, 2 },  { 2, 4 }, { 3, 8 }, { 4, 16 },
+       /* Sentinel */
+       { 0, 0 }
 };
 
 struct clk * __init cpg_sdh_clk_register(const char *name,