Skip to content

Commit 7b54d91

Browse files
ambaruskrzk
authored andcommitted
clk: samsung: gs101: propagate PERIC0 USI SPI clock rate
Introduce nMUX() for MUX clocks that can be reparented on clock rate change. "nMUX" comes from "n-to-1 selector", hopefully emphasising that the selector can change on clock rate changes. Ideally MUX/MUX_F() should change to not have the CLK_SET_RATE_NO_REPARENT flag set by default, and all their users to be updated to add the flag back (like in the case of DIV and GATE). But this is a very intrusive change and because for now only GS101 allows MUX reparenting on clock rate change, stick with nMUX(). GS101 defines MUX clocks that are dedicated for each instance of the IP. One example is USI IP (SPI, I2C, serial). The reparenting of these MUX clocks will not affect other instances of the same IP or different IPs altogether. When SPI transfer is being prepared, the spi-s3c64xx driver will call clk_set_rate() to change the rate of SPI source clock (IPCLK). But IPCLK is a gate (leaf) clock, so it must propagate the rate change up the clock tree, so that corresponding MUX/DIV clocks can actually change their values. Add CLK_SET_RATE_PARENT flag to corresponding clocks for all USI instances in GS101 PERIC0: USI{1-8, 14}. This change involves the following clocks: PERIC0 USI*: Clock Div range MUX Selection ------------------------------------------------------------------- gout_peric0_peric0_top0_ipclk_* - - dout_peric0_usi*_usi /1..16 - mout_peric0_usi*_usi_user - {24.5 MHz, 400 MHz} With input clock of 400 MHz this scheme provides the following IPCLK rate range, for each USI block: PERIC0 USI*: 1.5 MHz ... 400 MHz Accounting for internal /4 divider in SPI blocks, and because the max SPI frequency is limited at 50 MHz, it gives us next SPI SCK rates: PERIC0 USI_SPI*: 384 KHz ... 49.9 MHz Fixes: 893f133 ("clk: samsung: gs101: add support for cmu_peric0") Reviewed-by: Peter Griffin <peter.griffin@linaro.org> Acked-by: André Draszik <andre.draszik@linaro.org> Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org> Link: https://lore.kernel.org/r/20240419100915.2168573-2-tudor.ambarus@linaro.org Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
1 parent 04ee3a0 commit 7b54d91

File tree

2 files changed

+81
-65
lines changed

2 files changed

+81
-65
lines changed

drivers/clk/samsung/clk-gs101.c

Lines changed: 72 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,33 +2763,33 @@ static const struct samsung_mux_clock peric0_mux_clks[] __initconst = {
27632763
MUX(CLK_MOUT_PERIC0_USI0_UART_USER,
27642764
"mout_peric0_usi0_uart_user", mout_peric0_usi0_uart_user_p,
27652765
PLL_CON0_MUX_CLKCMU_PERIC0_USI0_UART_USER, 4, 1),
2766-
MUX(CLK_MOUT_PERIC0_USI14_USI_USER,
2767-
"mout_peric0_usi14_usi_user", mout_peric0_usi_usi_user_p,
2768-
PLL_CON0_MUX_CLKCMU_PERIC0_USI14_USI_USER, 4, 1),
2769-
MUX(CLK_MOUT_PERIC0_USI1_USI_USER,
2770-
"mout_peric0_usi1_usi_user", mout_peric0_usi_usi_user_p,
2771-
PLL_CON0_MUX_CLKCMU_PERIC0_USI1_USI_USER, 4, 1),
2772-
MUX(CLK_MOUT_PERIC0_USI2_USI_USER,
2773-
"mout_peric0_usi2_usi_user", mout_peric0_usi_usi_user_p,
2774-
PLL_CON0_MUX_CLKCMU_PERIC0_USI2_USI_USER, 4, 1),
2775-
MUX(CLK_MOUT_PERIC0_USI3_USI_USER,
2776-
"mout_peric0_usi3_usi_user", mout_peric0_usi_usi_user_p,
2777-
PLL_CON0_MUX_CLKCMU_PERIC0_USI3_USI_USER, 4, 1),
2778-
MUX(CLK_MOUT_PERIC0_USI4_USI_USER,
2779-
"mout_peric0_usi4_usi_user", mout_peric0_usi_usi_user_p,
2780-
PLL_CON0_MUX_CLKCMU_PERIC0_USI4_USI_USER, 4, 1),
2781-
MUX(CLK_MOUT_PERIC0_USI5_USI_USER,
2782-
"mout_peric0_usi5_usi_user", mout_peric0_usi_usi_user_p,
2783-
PLL_CON0_MUX_CLKCMU_PERIC0_USI5_USI_USER, 4, 1),
2784-
MUX(CLK_MOUT_PERIC0_USI6_USI_USER,
2785-
"mout_peric0_usi6_usi_user", mout_peric0_usi_usi_user_p,
2786-
PLL_CON0_MUX_CLKCMU_PERIC0_USI6_USI_USER, 4, 1),
2787-
MUX(CLK_MOUT_PERIC0_USI7_USI_USER,
2788-
"mout_peric0_usi7_usi_user", mout_peric0_usi_usi_user_p,
2789-
PLL_CON0_MUX_CLKCMU_PERIC0_USI7_USI_USER, 4, 1),
2790-
MUX(CLK_MOUT_PERIC0_USI8_USI_USER,
2791-
"mout_peric0_usi8_usi_user", mout_peric0_usi_usi_user_p,
2792-
PLL_CON0_MUX_CLKCMU_PERIC0_USI8_USI_USER, 4, 1),
2766+
nMUX(CLK_MOUT_PERIC0_USI14_USI_USER,
2767+
"mout_peric0_usi14_usi_user", mout_peric0_usi_usi_user_p,
2768+
PLL_CON0_MUX_CLKCMU_PERIC0_USI14_USI_USER, 4, 1),
2769+
nMUX(CLK_MOUT_PERIC0_USI1_USI_USER,
2770+
"mout_peric0_usi1_usi_user", mout_peric0_usi_usi_user_p,
2771+
PLL_CON0_MUX_CLKCMU_PERIC0_USI1_USI_USER, 4, 1),
2772+
nMUX(CLK_MOUT_PERIC0_USI2_USI_USER,
2773+
"mout_peric0_usi2_usi_user", mout_peric0_usi_usi_user_p,
2774+
PLL_CON0_MUX_CLKCMU_PERIC0_USI2_USI_USER, 4, 1),
2775+
nMUX(CLK_MOUT_PERIC0_USI3_USI_USER,
2776+
"mout_peric0_usi3_usi_user", mout_peric0_usi_usi_user_p,
2777+
PLL_CON0_MUX_CLKCMU_PERIC0_USI3_USI_USER, 4, 1),
2778+
nMUX(CLK_MOUT_PERIC0_USI4_USI_USER,
2779+
"mout_peric0_usi4_usi_user", mout_peric0_usi_usi_user_p,
2780+
PLL_CON0_MUX_CLKCMU_PERIC0_USI4_USI_USER, 4, 1),
2781+
nMUX(CLK_MOUT_PERIC0_USI5_USI_USER,
2782+
"mout_peric0_usi5_usi_user", mout_peric0_usi_usi_user_p,
2783+
PLL_CON0_MUX_CLKCMU_PERIC0_USI5_USI_USER, 4, 1),
2784+
nMUX(CLK_MOUT_PERIC0_USI6_USI_USER,
2785+
"mout_peric0_usi6_usi_user", mout_peric0_usi_usi_user_p,
2786+
PLL_CON0_MUX_CLKCMU_PERIC0_USI6_USI_USER, 4, 1),
2787+
nMUX(CLK_MOUT_PERIC0_USI7_USI_USER,
2788+
"mout_peric0_usi7_usi_user", mout_peric0_usi_usi_user_p,
2789+
PLL_CON0_MUX_CLKCMU_PERIC0_USI7_USI_USER, 4, 1),
2790+
nMUX(CLK_MOUT_PERIC0_USI8_USI_USER,
2791+
"mout_peric0_usi8_usi_user", mout_peric0_usi_usi_user_p,
2792+
PLL_CON0_MUX_CLKCMU_PERIC0_USI8_USI_USER, 4, 1),
27932793
};
27942794

27952795
static const struct samsung_div_clock peric0_div_clks[] __initconst = {
@@ -2798,33 +2798,42 @@ static const struct samsung_div_clock peric0_div_clks[] __initconst = {
27982798
DIV(CLK_DOUT_PERIC0_USI0_UART,
27992799
"dout_peric0_usi0_uart", "mout_peric0_usi0_uart_user",
28002800
CLK_CON_DIV_DIV_CLK_PERIC0_USI0_UART, 0, 4),
2801-
DIV(CLK_DOUT_PERIC0_USI14_USI,
2802-
"dout_peric0_usi14_usi", "mout_peric0_usi14_usi_user",
2803-
CLK_CON_DIV_DIV_CLK_PERIC0_USI14_USI, 0, 4),
2804-
DIV(CLK_DOUT_PERIC0_USI1_USI,
2805-
"dout_peric0_usi1_usi", "mout_peric0_usi1_usi_user",
2806-
CLK_CON_DIV_DIV_CLK_PERIC0_USI1_USI, 0, 4),
2807-
DIV(CLK_DOUT_PERIC0_USI2_USI,
2808-
"dout_peric0_usi2_usi", "mout_peric0_usi2_usi_user",
2809-
CLK_CON_DIV_DIV_CLK_PERIC0_USI2_USI, 0, 4),
2810-
DIV(CLK_DOUT_PERIC0_USI3_USI,
2811-
"dout_peric0_usi3_usi", "mout_peric0_usi3_usi_user",
2812-
CLK_CON_DIV_DIV_CLK_PERIC0_USI3_USI, 0, 4),
2813-
DIV(CLK_DOUT_PERIC0_USI4_USI,
2814-
"dout_peric0_usi4_usi", "mout_peric0_usi4_usi_user",
2815-
CLK_CON_DIV_DIV_CLK_PERIC0_USI4_USI, 0, 4),
2816-
DIV(CLK_DOUT_PERIC0_USI5_USI,
2817-
"dout_peric0_usi5_usi", "mout_peric0_usi5_usi_user",
2818-
CLK_CON_DIV_DIV_CLK_PERIC0_USI5_USI, 0, 4),
2819-
DIV(CLK_DOUT_PERIC0_USI6_USI,
2820-
"dout_peric0_usi6_usi", "mout_peric0_usi6_usi_user",
2821-
CLK_CON_DIV_DIV_CLK_PERIC0_USI6_USI, 0, 4),
2822-
DIV(CLK_DOUT_PERIC0_USI7_USI,
2823-
"dout_peric0_usi7_usi", "mout_peric0_usi7_usi_user",
2824-
CLK_CON_DIV_DIV_CLK_PERIC0_USI7_USI, 0, 4),
2825-
DIV(CLK_DOUT_PERIC0_USI8_USI,
2826-
"dout_peric0_usi8_usi", "mout_peric0_usi8_usi_user",
2827-
CLK_CON_DIV_DIV_CLK_PERIC0_USI8_USI, 0, 4),
2801+
DIV_F(CLK_DOUT_PERIC0_USI14_USI,
2802+
"dout_peric0_usi14_usi", "mout_peric0_usi14_usi_user",
2803+
CLK_CON_DIV_DIV_CLK_PERIC0_USI14_USI, 0, 4,
2804+
CLK_SET_RATE_PARENT, 0),
2805+
DIV_F(CLK_DOUT_PERIC0_USI1_USI,
2806+
"dout_peric0_usi1_usi", "mout_peric0_usi1_usi_user",
2807+
CLK_CON_DIV_DIV_CLK_PERIC0_USI1_USI, 0, 4,
2808+
CLK_SET_RATE_PARENT, 0),
2809+
DIV_F(CLK_DOUT_PERIC0_USI2_USI,
2810+
"dout_peric0_usi2_usi", "mout_peric0_usi2_usi_user",
2811+
CLK_CON_DIV_DIV_CLK_PERIC0_USI2_USI, 0, 4,
2812+
CLK_SET_RATE_PARENT, 0),
2813+
DIV_F(CLK_DOUT_PERIC0_USI3_USI,
2814+
"dout_peric0_usi3_usi", "mout_peric0_usi3_usi_user",
2815+
CLK_CON_DIV_DIV_CLK_PERIC0_USI3_USI, 0, 4,
2816+
CLK_SET_RATE_PARENT, 0),
2817+
DIV_F(CLK_DOUT_PERIC0_USI4_USI,
2818+
"dout_peric0_usi4_usi", "mout_peric0_usi4_usi_user",
2819+
CLK_CON_DIV_DIV_CLK_PERIC0_USI4_USI, 0, 4,
2820+
CLK_SET_RATE_PARENT, 0),
2821+
DIV_F(CLK_DOUT_PERIC0_USI5_USI,
2822+
"dout_peric0_usi5_usi", "mout_peric0_usi5_usi_user",
2823+
CLK_CON_DIV_DIV_CLK_PERIC0_USI5_USI, 0, 4,
2824+
CLK_SET_RATE_PARENT, 0),
2825+
DIV_F(CLK_DOUT_PERIC0_USI6_USI,
2826+
"dout_peric0_usi6_usi", "mout_peric0_usi6_usi_user",
2827+
CLK_CON_DIV_DIV_CLK_PERIC0_USI6_USI, 0, 4,
2828+
CLK_SET_RATE_PARENT, 0),
2829+
DIV_F(CLK_DOUT_PERIC0_USI7_USI,
2830+
"dout_peric0_usi7_usi", "mout_peric0_usi7_usi_user",
2831+
CLK_CON_DIV_DIV_CLK_PERIC0_USI7_USI, 0, 4,
2832+
CLK_SET_RATE_PARENT, 0),
2833+
DIV_F(CLK_DOUT_PERIC0_USI8_USI,
2834+
"dout_peric0_usi8_usi", "mout_peric0_usi8_usi_user",
2835+
CLK_CON_DIV_DIV_CLK_PERIC0_USI8_USI, 0, 4,
2836+
CLK_SET_RATE_PARENT, 0),
28282837
};
28292838

28302839
static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
@@ -2857,11 +2866,11 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
28572866
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0,
28582867
"gout_peric0_peric0_top0_ipclk_0", "dout_peric0_usi1_usi",
28592868
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_0,
2860-
21, 0, 0),
2869+
21, CLK_SET_RATE_PARENT, 0),
28612870
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1,
28622871
"gout_peric0_peric0_top0_ipclk_1", "dout_peric0_usi2_usi",
28632872
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_1,
2864-
21, 0, 0),
2873+
21, CLK_SET_RATE_PARENT, 0),
28652874
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_10,
28662875
"gout_peric0_peric0_top0_ipclk_10", "dout_peric0_i3c",
28672876
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_10,
@@ -2889,27 +2898,27 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
28892898
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2,
28902899
"gout_peric0_peric0_top0_ipclk_2", "dout_peric0_usi3_usi",
28912900
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_2,
2892-
21, 0, 0),
2901+
21, CLK_SET_RATE_PARENT, 0),
28932902
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3,
28942903
"gout_peric0_peric0_top0_ipclk_3", "dout_peric0_usi4_usi",
28952904
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_3,
2896-
21, 0, 0),
2905+
21, CLK_SET_RATE_PARENT, 0),
28972906
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4,
28982907
"gout_peric0_peric0_top0_ipclk_4", "dout_peric0_usi5_usi",
28992908
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_4,
2900-
21, 0, 0),
2909+
21, CLK_SET_RATE_PARENT, 0),
29012910
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5,
29022911
"gout_peric0_peric0_top0_ipclk_5", "dout_peric0_usi6_usi",
29032912
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_5,
2904-
21, 0, 0),
2913+
21, CLK_SET_RATE_PARENT, 0),
29052914
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6,
29062915
"gout_peric0_peric0_top0_ipclk_6", "dout_peric0_usi7_usi",
29072916
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_6,
2908-
21, 0, 0),
2917+
21, CLK_SET_RATE_PARENT, 0),
29092918
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7,
29102919
"gout_peric0_peric0_top0_ipclk_7", "dout_peric0_usi8_usi",
29112920
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_7,
2912-
21, 0, 0),
2921+
21, CLK_SET_RATE_PARENT, 0),
29132922
GATE(CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_8,
29142923
"gout_peric0_peric0_top0_ipclk_8", "dout_peric0_i3c",
29152924
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_IPCLK_8,
@@ -2990,7 +2999,7 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
29902999
GATE(CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2,
29913000
"gout_peric0_peric0_top1_ipclk_2", "dout_peric0_usi14_usi",
29923001
CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP1_IPCLKPORT_IPCLK_2,
2993-
21, 0, 0),
3002+
21, CLK_SET_RATE_PARENT, 0),
29943003
/* Disabling this clock makes the system hang. Mark the clock as critical. */
29953004
GATE(CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_0,
29963005
"gout_peric0_peric0_top1_pclk_0", "mout_peric0_bus_user",

drivers/clk/samsung/clk.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,24 @@ struct samsung_mux_clock {
133133
.name = cname, \
134134
.parent_names = pnames, \
135135
.num_parents = ARRAY_SIZE(pnames), \
136-
.flags = (f) | CLK_SET_RATE_NO_REPARENT, \
136+
.flags = f, \
137137
.offset = o, \
138138
.shift = s, \
139139
.width = w, \
140140
.mux_flags = mf, \
141141
}
142142

143143
#define MUX(_id, cname, pnames, o, s, w) \
144-
__MUX(_id, cname, pnames, o, s, w, 0, 0)
144+
__MUX(_id, cname, pnames, o, s, w, CLK_SET_RATE_NO_REPARENT, 0)
145145

146146
#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
147+
__MUX(_id, cname, pnames, o, s, w, (f) | CLK_SET_RATE_NO_REPARENT, mf)
148+
149+
/* Used by MUX clocks where reparenting on clock rate change is allowed. */
150+
#define nMUX(_id, cname, pnames, o, s, w) \
151+
__MUX(_id, cname, pnames, o, s, w, 0, 0)
152+
153+
#define nMUX_F(_id, cname, pnames, o, s, w, f, mf) \
147154
__MUX(_id, cname, pnames, o, s, w, f, mf)
148155

149156
/**

0 commit comments

Comments
 (0)