From b6297d9e078a4127fb608ede4d0944855dde667d Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Fri, 24 May 2019 11:15:32 +0200 Subject: [PATCH 01/62] clk: meson: g12a: fix hifi typo in mali parent_names Replace hihi by hifi in the mali parent_names of the g12a SoC family. Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller") Signed-off-by: Alexandre Mergnat Acked-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index db1c4ed9d54e..7bc5566b66f7 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -2888,7 +2888,7 @@ static struct clk_regmap g12a_hdmi = { */ static const char * const g12a_mali_0_1_parent_names[] = { - IN_PREFIX "xtal", "gp0_pll", "hihi_pll", "fclk_div2p5", + IN_PREFIX "xtal", "gp0_pll", "hifi_pll", "fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7" }; From 282420eed23f237963f2033b2f2bedb90fbcc5e1 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:40:23 +0200 Subject: [PATCH 02/62] clk: meson: axg-audio: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. A recent patch [0] allows parents to be specified without string names or with device-tree clock name by using a new assignment structure. Migrate to the new way by using .parent_hws where possible (when parent clocks are localy declared in the controller) and use .parent_data otherwise. Remove clk input helper and all bypass clocks (declared in probe function) which are no longer used since we are able to use device-tree clock name directly. [0] commit fc0c209c147f ("clk: Allow parents to be specified without string names") Signed-off-by: Alexandre Mergnat [jbrunet@baylibre.com: remove CLK_SET_RATE_PARENT from mst muxes] Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 1 - drivers/clk/meson/axg-audio.c | 257 ++++++++++++++++------------------ 2 files changed, 118 insertions(+), 140 deletions(-) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index a6b20e123e0c..ee0b84b6b329 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -86,7 +86,6 @@ config COMMON_CLK_AXG config COMMON_CLK_AXG_AUDIO tristate "Meson AXG Audio Clock Controller Driver" depends on ARCH_MESON - select COMMON_CLK_MESON_INPUT select COMMON_CLK_MESON_REGMAP select COMMON_CLK_MESON_PHASE select COMMON_CLK_MESON_SCLK_DIV diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 8028ff6f6610..741df7e955ca 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -15,7 +15,6 @@ #include #include "axg-audio.h" -#include "clk-input.h" #include "clk-regmap.h" #include "clk-phase.h" #include "sclk-div.h" @@ -24,7 +23,7 @@ #define AUD_SLV_SCLK_COUNT 10 #define AUD_SLV_LRCLK_COUNT 10 -#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) \ +#define AUD_GATE(_name, _reg, _bit, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (_reg), \ @@ -33,13 +32,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } -#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \ +#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_mux_data){ \ .offset = (_reg), \ @@ -50,13 +49,13 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data){ \ .name = "aud_"#_name, \ .ops = &clk_regmap_mux_ops, \ - .parent_names = (_pnames), \ - .num_parents = ARRAY_SIZE(_pnames), \ + .parent_data = _pdata, \ + .num_parents = ARRAY_SIZE(_pdata), \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ } -#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \ +#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct clk_regmap_div_data){ \ .offset = (_reg), \ @@ -67,15 +66,27 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data){ \ .name = "aud_"#_name, \ .ops = &clk_regmap_divider_ops, \ - .parent_names = (const char *[]) { _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ } #define AUD_PCLK_GATE(_name, _bit) \ - AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "audio_pclk", 0) - +struct clk_regmap aud_##_name = { \ + .data = &(struct clk_regmap_gate_data){ \ + .offset = (AUDIO_CLK_GATE_EN), \ + .bit_idx = (_bit), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = "aud_"#_name, \ + .ops = &clk_regmap_gate_ops, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "pclk", \ + }, \ + .num_parents = 1, \ + }, \ +} /* Audio peripheral clocks */ static AUD_PCLK_GATE(ddr_arb, 0); static AUD_PCLK_GATE(pdm, 1); @@ -100,14 +111,20 @@ static AUD_PCLK_GATE(power_detect, 19); static AUD_PCLK_GATE(spdifout_b, 21); /* Audio Master Clocks */ -static const char * const mst_mux_parent_names[] = { - "aud_mst_in0", "aud_mst_in1", "aud_mst_in2", "aud_mst_in3", - "aud_mst_in4", "aud_mst_in5", "aud_mst_in6", "aud_mst_in7", +static const struct clk_parent_data mst_mux_parent_data[] = { + { .fw_name = "mst_in0", }, + { .fw_name = "mst_in1", }, + { .fw_name = "mst_in2", }, + { .fw_name = "mst_in3", }, + { .fw_name = "mst_in4", }, + { .fw_name = "mst_in5", }, + { .fw_name = "mst_in6", }, + { .fw_name = "mst_in7", }, }; #define AUD_MST_MUX(_name, _reg, _flag) \ AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ - mst_mux_parent_names, CLK_SET_RATE_PARENT) + mst_mux_parent_data, 0) #define AUD_MST_MCLK_MUX(_name, _reg) \ AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) @@ -129,7 +146,7 @@ static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); #define AUD_MST_DIV(_name, _reg, _flag) \ AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ - "aud_"#_name"_sel", CLK_SET_RATE_PARENT) \ + aud_##_name##_sel, CLK_SET_RATE_PARENT) \ #define AUD_MST_MCLK_DIV(_name, _reg) \ AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) @@ -150,7 +167,7 @@ static AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); #define AUD_MST_MCLK_GATE(_name, _reg) \ - AUD_GATE(_name, _reg, 31, "aud_"#_name"_div", \ + AUD_GATE(_name, _reg, 31, aud_##_name##_div, \ CLK_SET_RATE_PARENT) static AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); @@ -168,7 +185,7 @@ static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL); /* Sample Clocks */ #define AUD_MST_SCLK_PRE_EN(_name, _reg) \ AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ - "aud_mst_"#_name"_mclk", 0) + aud_mst_##_name##_mclk, 0) static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); @@ -178,7 +195,7 @@ static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ - _hi_shift, _hi_width, _pname, _iflags) \ + _hi_shift, _hi_width, _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct meson_sclk_div_data) { \ .div = { \ @@ -195,7 +212,7 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_sclk_div_ops, \ - .parent_names = (const char *[]) { _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = (_iflags), \ }, \ @@ -203,7 +220,7 @@ struct clk_regmap aud_##_name = { \ #define AUD_MST_SCLK_DIV(_name, _reg) \ AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ - "aud_mst_"#_name"_sclk_pre_en", \ + aud_mst_##_name##_sclk_pre_en, \ CLK_SET_RATE_PARENT) static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); @@ -214,8 +231,8 @@ static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_MST_SCLK_POST_EN(_name, _reg) \ - AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ - "aud_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT) + AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ + aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT) static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); @@ -224,8 +241,8 @@ static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); -#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ - _pname, _iflags) \ +#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ + _phws, _iflags) \ struct clk_regmap aud_##_name = { \ .data = &(struct meson_clk_triphase_data) { \ .ph0 = { \ @@ -247,7 +264,7 @@ struct clk_regmap aud_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "aud_"#_name, \ .ops = &meson_clk_triphase_ops, \ - .parent_names = (const char *[]) { _pname }, \ + .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ }, \ @@ -255,7 +272,7 @@ struct clk_regmap aud_##_name = { \ #define AUD_MST_SCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ - "aud_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT) + aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT) static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); @@ -266,7 +283,7 @@ static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); #define AUD_MST_LRCLK_DIV(_name, _reg) \ AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ - "aud_mst_"#_name"_sclk_post_en", 0) \ + aud_mst_##_name##_sclk_post_en, 0) \ static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); @@ -277,7 +294,7 @@ static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); #define AUD_MST_LRCLK(_name, _reg) \ AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ - "aud_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT) + aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT) static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); @@ -286,19 +303,29 @@ static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); -static const char * const tdm_sclk_parent_names[] = { - "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk", - "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk", - "aud_slv_sclk0", "aud_slv_sclk1", "aud_slv_sclk2", - "aud_slv_sclk3", "aud_slv_sclk4", "aud_slv_sclk5", - "aud_slv_sclk6", "aud_slv_sclk7", "aud_slv_sclk8", - "aud_slv_sclk9" +static const struct clk_parent_data tdm_sclk_parent_data[] = { + { .hw = &aud_mst_a_sclk.hw, }, + { .hw = &aud_mst_b_sclk.hw, }, + { .hw = &aud_mst_c_sclk.hw, }, + { .hw = &aud_mst_d_sclk.hw, }, + { .hw = &aud_mst_e_sclk.hw, }, + { .hw = &aud_mst_f_sclk.hw, }, + { .fw_name = "slv_sclk0", }, + { .fw_name = "slv_sclk1", }, + { .fw_name = "slv_sclk2", }, + { .fw_name = "slv_sclk3", }, + { .fw_name = "slv_sclk4", }, + { .fw_name = "slv_sclk5", }, + { .fw_name = "slv_sclk6", }, + { .fw_name = "slv_sclk7", }, + { .fw_name = "slv_sclk8", }, + { .fw_name = "slv_sclk9", }, }; #define AUD_TDM_SCLK_MUX(_name, _reg) \ AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ CLK_MUX_ROUND_CLOSEST, \ - tdm_sclk_parent_names, 0) + tdm_sclk_parent_data, 0) static AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -310,7 +337,7 @@ static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); #define AUD_TDM_SCLK_PRE_EN(_name, _reg) \ AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ - "aud_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT) + aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT) static AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -322,7 +349,7 @@ static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); #define AUD_TDM_SCLK_POST_EN(_name, _reg) \ AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ - "aud_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT) + aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT) static AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -344,8 +371,9 @@ static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); .hw.init = &(struct clk_init_data) { \ .name = "aud_tdm"#_name"_sclk", \ .ops = &meson_clk_phase_ops, \ - .parent_names = (const char *[]) \ - { "aud_tdm"#_name"_sclk_post_en" }, \ + .parent_hws = (const struct clk_hw *[]) { \ + &aud_tdm##_name##_sclk_post_en.hw \ + }, \ .num_parents = 1, \ .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ }, \ @@ -359,19 +387,29 @@ static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); -static const char * const tdm_lrclk_parent_names[] = { - "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk", - "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk", - "aud_slv_lrclk0", "aud_slv_lrclk1", "aud_slv_lrclk2", - "aud_slv_lrclk3", "aud_slv_lrclk4", "aud_slv_lrclk5", - "aud_slv_lrclk6", "aud_slv_lrclk7", "aud_slv_lrclk8", - "aud_slv_lrclk9" +static const struct clk_parent_data tdm_lrclk_parent_data[] = { + { .hw = &aud_mst_a_lrclk.hw, }, + { .hw = &aud_mst_b_lrclk.hw, }, + { .hw = &aud_mst_c_lrclk.hw, }, + { .hw = &aud_mst_d_lrclk.hw, }, + { .hw = &aud_mst_e_lrclk.hw, }, + { .hw = &aud_mst_f_lrclk.hw, }, + { .fw_name = "slv_lrclk0", }, + { .fw_name = "slv_lrclk1", }, + { .fw_name = "slv_lrclk2", }, + { .fw_name = "slv_lrclk3", }, + { .fw_name = "slv_lrclk4", }, + { .fw_name = "slv_lrclk5", }, + { .fw_name = "slv_lrclk6", }, + { .fw_name = "slv_lrclk7", }, + { .fw_name = "slv_lrclk8", }, + { .fw_name = "slv_lrclk9", }, }; -#define AUD_TDM_LRLCK(_name, _reg) \ - AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ - CLK_MUX_ROUND_CLOSEST, \ - tdm_lrclk_parent_names, 0) +#define AUD_TDM_LRLCK(_name, _reg) \ + AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ + CLK_MUX_ROUND_CLOSEST, \ + tdm_lrclk_parent_data, 0) static AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); static AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); @@ -386,39 +424,51 @@ static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \ CLK_SET_RATE_NO_REPARENT) -static const char * const mclk_pad_ctrl_parent_names[] = { - "aud_mst_a_mclk", "aud_mst_b_mclk", "aud_mst_c_mclk", - "aud_mst_d_mclk", "aud_mst_e_mclk", "aud_mst_f_mclk", +static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = { + { .hw = &aud_mst_a_mclk.hw }, + { .hw = &aud_mst_b_mclk.hw }, + { .hw = &aud_mst_c_mclk.hw }, + { .hw = &aud_mst_d_mclk.hw }, + { .hw = &aud_mst_e_mclk.hw }, + { .hw = &aud_mst_f_mclk.hw }, }; static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0, - mclk_pad_ctrl_parent_names); + mclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4, - mclk_pad_ctrl_parent_names); + mclk_pad_ctrl_parent_data); -static const char * const lrclk_pad_ctrl_parent_names[] = { - "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk", - "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk", +static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = { + { .hw = &aud_mst_a_lrclk.hw }, + { .hw = &aud_mst_b_lrclk.hw }, + { .hw = &aud_mst_c_lrclk.hw }, + { .hw = &aud_mst_d_lrclk.hw }, + { .hw = &aud_mst_e_lrclk.hw }, + { .hw = &aud_mst_f_lrclk.hw }, }; static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16, - lrclk_pad_ctrl_parent_names); + lrclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20, - lrclk_pad_ctrl_parent_names); + lrclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24, - lrclk_pad_ctrl_parent_names); + lrclk_pad_ctrl_parent_data); -static const char * const sclk_pad_ctrl_parent_names[] = { - "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk", - "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk", +static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = { + { .hw = &aud_mst_a_sclk.hw }, + { .hw = &aud_mst_b_sclk.hw }, + { .hw = &aud_mst_c_sclk.hw }, + { .hw = &aud_mst_d_sclk.hw }, + { .hw = &aud_mst_e_sclk.hw }, + { .hw = &aud_mst_f_sclk.hw }, }; static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0, - sclk_pad_ctrl_parent_names); + sclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4, - sclk_pad_ctrl_parent_names); + sclk_pad_ctrl_parent_data); static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, - sclk_pad_ctrl_parent_names); + sclk_pad_ctrl_parent_data); /* * Array of all clocks provided by this provider @@ -868,54 +918,6 @@ static int devm_clk_get_enable(struct device *dev, char *id) return 0; } -static int axg_register_clk_hw_input(struct device *dev, - const char *name) -{ - char *clk_name; - struct clk_hw *hw; - int err = 0; - - clk_name = kasprintf(GFP_KERNEL, "aud_%s", name); - if (!clk_name) - return -ENOMEM; - - hw = meson_clk_hw_register_input(dev, name, clk_name, 0); - if (IS_ERR(hw)) { - /* It is ok if an input clock is missing */ - if (PTR_ERR(hw) == -ENOENT) { - dev_dbg(dev, "%s not provided", name); - } else { - err = PTR_ERR(hw); - if (err != -EPROBE_DEFER) - dev_err(dev, "failed to get %s clock", name); - } - } - - kfree(clk_name); - return err; -} - -static int axg_register_clk_hw_inputs(struct device *dev, - const char *basename, - unsigned int count) -{ - char *name; - int i, ret; - - for (i = 0; i < count; i++) { - name = kasprintf(GFP_KERNEL, "%s%d", basename, i); - if (!name) - return -ENOMEM; - - ret = axg_register_clk_hw_input(dev, name); - kfree(name); - if (ret) - return ret; - } - - return 0; -} - static const struct regmap_config axg_audio_regmap_cfg = { .reg_bits = 32, .val_bits = 32, @@ -963,29 +965,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) return ret; } - /* Register the peripheral input clock */ - hw = meson_clk_hw_register_input(dev, "pclk", "audio_pclk", 0); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - /* Register optional input master clocks */ - ret = axg_register_clk_hw_inputs(dev, "mst_in", - AUD_MST_IN_COUNT); - if (ret) - return ret; - - /* Register optional input slave sclks */ - ret = axg_register_clk_hw_inputs(dev, "slv_sclk", - AUD_SLV_SCLK_COUNT); - if (ret) - return ret; - - /* Register optional input slave lrclks */ - ret = axg_register_clk_hw_inputs(dev, "slv_lrclk", - AUD_SLV_LRCLK_COUNT); - if (ret) - return ret; - /* Populate regmap for the regmap backed clocks */ for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++) aud_clk_regmaps[i]->map = map; From ba626081107dceacff554e5ca2efc7cea7326b6e Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:41:23 +0200 Subject: [PATCH 03/62] clk: meson: g12a-aoclk: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (when parent clocks are localy declared in the controller) and use .parent_data otherwise. Remove clk input helper and all bypass clocks (declared in probe function) which are no longer used since we are able to use device-tree clock name directly. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a-aoclk.c | 81 +++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c index 1994e735396b..62499563e4f5 100644 --- a/drivers/clk/meson/g12a-aoclk.c +++ b/drivers/clk/meson/g12a-aoclk.c @@ -18,8 +18,6 @@ #include "clk-regmap.h" #include "clk-dualdiv.h" -#define IN_PREFIX "ao-in-" - /* * AO Configuration Clock registers offsets * Register offsets from the data sheet must be multiplied by 4. @@ -51,7 +49,9 @@ static struct clk_regmap g12a_aoclk_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "g12a_ao_" #_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "mpeg-clk", \ + }, \ .num_parents = 1, \ .flags = CLK_IGNORE_UNUSED, \ }, \ @@ -81,7 +81,9 @@ static struct clk_regmap g12a_aoclk_cts_oscin = { .hw.init = &(struct clk_init_data){ .name = "cts_oscin", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -106,7 +108,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cts_oscin.hw + }, .num_parents = 1, }, }; @@ -143,7 +147,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_div = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_32k_by_oscin_pre.hw + }, .num_parents = 1, }, }; @@ -158,8 +164,10 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_div", - "g12a_ao_32k_by_oscin_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_32k_by_oscin_div.hw, + &g12a_aoclk_32k_by_oscin_pre.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -173,7 +181,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_32k_by_oscin", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_32k_by_oscin_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -189,7 +199,9 @@ static struct clk_regmap g12a_aoclk_cec_pre = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cts_oscin.hw + }, .num_parents = 1, }, }; @@ -226,7 +238,9 @@ static struct clk_regmap g12a_aoclk_cec_div = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "g12a_ao_cec_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cec_pre.hw + }, .num_parents = 1, }, }; @@ -241,8 +255,10 @@ static struct clk_regmap g12a_aoclk_cec_sel = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "g12a_ao_cec_div", - "g12a_ao_cec_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cec_div.hw, + &g12a_aoclk_cec_pre.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -256,7 +272,9 @@ static struct clk_regmap g12a_aoclk_cec = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cec", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "g12a_ao_cec_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_cec_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -272,8 +290,10 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin", - IN_PREFIX "ext_32k-0" }, + .parent_data = (const struct clk_parent_data []) { + { .hw = &g12a_aoclk_32k_by_oscin.hw }, + { .fw_name = "ext-32k-0", }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -289,8 +309,10 @@ static struct clk_regmap g12a_aoclk_clk81 = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_clk81", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk", - "g12a_ao_cts_rtc_oscin"}, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "mpeg-clk", }, + { .hw = &g12a_aoclk_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -305,8 +327,10 @@ static struct clk_regmap g12a_aoclk_saradc_mux = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_saradc_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "g12a_ao_clk81" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_aoclk_clk81.hw }, + }, .num_parents = 2, }, }; @@ -320,7 +344,9 @@ static struct clk_regmap g12a_aoclk_saradc_div = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_saradc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "g12a_ao_saradc_mux" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_saradc_mux.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -334,7 +360,9 @@ static struct clk_regmap g12a_aoclk_saradc_gate = { .hw.init = &(struct clk_init_data){ .name = "g12a_ao_saradc_gate", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "g12a_ao_saradc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_aoclk_saradc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -417,12 +445,6 @@ static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = { .num = NR_CLKS, }; -static const struct meson_aoclk_input g12a_aoclk_inputs[] = { - { .name = "xtal", .required = true }, - { .name = "mpeg-clk", .required = true }, - { .name = "ext-32k-0", .required = false }, -}; - static const struct meson_aoclk_data g12a_aoclkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, .num_reset = ARRAY_SIZE(g12a_aoclk_reset), @@ -430,9 +452,6 @@ static const struct meson_aoclk_data g12a_aoclkc_data = { .num_clks = ARRAY_SIZE(g12a_aoclk_regmap), .clks = g12a_aoclk_regmap, .hw_data = &g12a_aoclk_onecell_data, - .inputs = g12a_aoclk_inputs, - .num_inputs = ARRAY_SIZE(g12a_aoclk_inputs), - .input_prefix = IN_PREFIX, }; static const struct of_device_id g12a_aoclkc_match_table[] = { From 6e2bfc352e7a3a9b22f13c36627545d5f4caf3e9 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:41:24 +0200 Subject: [PATCH 04/62] clk: meson: gxbb-aoclk: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (when parent clocks are localy declared in the controller) and use .parent_data otherwise. Remove clk input helper and all bypass clocks (declared in probe function) which are no longer used since we are able to use device-tree clock name directly. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb-aoclk.c | 55 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index 449f6ac189d8..e940861a396b 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c @@ -11,8 +11,6 @@ #include "clk-regmap.h" #include "clk-dualdiv.h" -#define IN_PREFIX "ao-in-" - /* AO Configuration Clock registers offsets */ #define AO_RTI_PWR_CNTL_REG1 0x0c #define AO_RTI_PWR_CNTL_REG0 0x10 @@ -31,7 +29,9 @@ static struct clk_regmap _name##_ao = { \ .hw.init = &(struct clk_init_data) { \ .name = #_name "_ao", \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "mpeg-clk", \ + }, \ .num_parents = 1, \ .flags = CLK_IGNORE_UNUSED, \ }, \ @@ -52,7 +52,9 @@ static struct clk_regmap ao_cts_oscin = { .hw.init = &(struct clk_init_data){ .name = "ao_cts_oscin", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -65,7 +67,7 @@ static struct clk_regmap ao_32k_pre = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "ao_cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { &ao_cts_oscin.hw }, .num_parents = 1, }, }; @@ -112,7 +114,7 @@ static struct clk_regmap ao_32k_div = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { &ao_32k_pre.hw }, .num_parents = 1, }, }; @@ -127,8 +129,10 @@ static struct clk_regmap ao_32k_sel = { .hw.init = &(struct clk_init_data){ .name = "ao_32k_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "ao_32k_div", - "ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &ao_32k_div.hw, + &ao_32k_pre.hw + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -142,7 +146,7 @@ static struct clk_regmap ao_32k = { .hw.init = &(struct clk_init_data){ .name = "ao_32k", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "ao_32k_sel" }, + .parent_hws = (const struct clk_hw *[]) { &ao_32k_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -159,10 +163,12 @@ static struct clk_regmap ao_cts_rtc_oscin = { .hw.init = &(struct clk_init_data){ .name = "ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ IN_PREFIX "ext-32k-0", - IN_PREFIX "ext-32k-1", - IN_PREFIX "ext-32k-2", - "ao_32k" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "ext-32k-0", }, + { .fw_name = "ext-32k-1", }, + { .fw_name = "ext-32k-2", }, + { .hw = &ao_32k.hw }, + }, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, }, @@ -178,8 +184,10 @@ static struct clk_regmap ao_clk81 = { .hw.init = &(struct clk_init_data){ .name = "ao_clk81", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk", - "ao_cts_rtc_oscin" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "mpeg-clk", }, + { .hw = &ao_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -208,8 +216,10 @@ static struct clk_regmap ao_cts_cec = { * Until CCF gets fixed, adding this fake parent that won't * ever be registered should work around the problem */ - .parent_names = (const char *[]){ "fixme", - "ao_cts_rtc_oscin" }, + .parent_data = (const struct clk_parent_data []) { + { .name = "fixme", .index = -1, }, + { .hw = &ao_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -261,14 +271,6 @@ static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { .num = NR_CLKS, }; -static const struct meson_aoclk_input gxbb_aoclk_inputs[] = { - { .name = "xtal", .required = true, }, - { .name = "mpeg-clk", .required = true, }, - {. name = "ext-32k-0", .required = false, }, - {. name = "ext-32k-1", .required = false, }, - {. name = "ext-32k-2", .required = false, }, -}; - static const struct meson_aoclk_data gxbb_aoclkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, .num_reset = ARRAY_SIZE(gxbb_aoclk_reset), @@ -276,9 +278,6 @@ static const struct meson_aoclk_data gxbb_aoclkc_data = { .num_clks = ARRAY_SIZE(gxbb_aoclk), .clks = gxbb_aoclk, .hw_data = &gxbb_aoclk_onecell_data, - .inputs = gxbb_aoclk_inputs, - .num_inputs = ARRAY_SIZE(gxbb_aoclk_inputs), - .input_prefix = IN_PREFIX, }; static const struct of_device_id gxbb_aoclkc_match_table[] = { From b90ec1e344a2dd4c1afebd75c1ce05afaf9e116b Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:41:25 +0200 Subject: [PATCH 05/62] clk: meson: axg-aoclk: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (when parent clocks are localy declared in the controller) and use .parent_data otherwise. Remove clk input helper and all bypass clocks (declared in probe function) which are no longer used since we are able to use device-tree clock name directly. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-aoclk.c | 63 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c index 0086f31288eb..b488b40c9d0e 100644 --- a/drivers/clk/meson/axg-aoclk.c +++ b/drivers/clk/meson/axg-aoclk.c @@ -18,8 +18,6 @@ #include "clk-regmap.h" #include "clk-dualdiv.h" -#define IN_PREFIX "ao-in-" - /* * AO Configuration Clock registers offsets * Register offsets from the data sheet must be multiplied by 4. @@ -42,7 +40,9 @@ static struct clk_regmap axg_aoclk_##_name = { \ .hw.init = &(struct clk_init_data) { \ .name = "axg_ao_" #_name, \ .ops = &clk_regmap_gate_ops, \ - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \ + .parent_data = &(const struct clk_parent_data) { \ + .fw_name = "mpeg-clk", \ + }, \ .num_parents = 1, \ .flags = CLK_IGNORE_UNUSED, \ }, \ @@ -64,7 +64,9 @@ static struct clk_regmap axg_aoclk_cts_oscin = { .hw.init = &(struct clk_init_data){ .name = "cts_oscin", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -77,7 +79,9 @@ static struct clk_regmap axg_aoclk_32k_pre = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k_pre", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_oscin" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_cts_oscin.hw + }, .num_parents = 1, }, }; @@ -124,7 +128,9 @@ static struct clk_regmap axg_aoclk_32k_div = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k_div", .ops = &meson_clk_dualdiv_ops, - .parent_names = (const char *[]){ "axg_ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_32k_pre.hw + }, .num_parents = 1, }, }; @@ -139,8 +145,10 @@ static struct clk_regmap axg_aoclk_32k_sel = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "axg_ao_32k_div", - "axg_ao_32k_pre" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_32k_div.hw, + &axg_aoclk_32k_pre.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -154,7 +162,9 @@ static struct clk_regmap axg_aoclk_32k = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_32k", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "axg_ao_32k_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_32k_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -170,8 +180,10 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_cts_rtc_oscin", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "axg_ao_32k", - IN_PREFIX "ext_32k-0" }, + .parent_data = (const struct clk_parent_data []) { + { .hw = &axg_aoclk_32k.hw }, + { .fw_name = "ext_32k-0", }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -187,8 +199,10 @@ static struct clk_regmap axg_aoclk_clk81 = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_clk81", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk", - "axg_ao_cts_rtc_oscin"}, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "mpeg-clk", }, + { .hw = &axg_aoclk_cts_rtc_oscin.hw }, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -203,8 +217,10 @@ static struct clk_regmap axg_aoclk_saradc_mux = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_saradc_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "axg_ao_clk81" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &axg_aoclk_clk81.hw }, + }, .num_parents = 2, }, }; @@ -218,7 +234,9 @@ static struct clk_regmap axg_aoclk_saradc_div = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_saradc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "axg_ao_saradc_mux" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_saradc_mux.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -232,7 +250,9 @@ static struct clk_regmap axg_aoclk_saradc_gate = { .hw.init = &(struct clk_init_data){ .name = "axg_ao_saradc_gate", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "axg_ao_saradc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_aoclk_saradc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -290,12 +310,6 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = { .num = NR_CLKS, }; -static const struct meson_aoclk_input axg_aoclk_inputs[] = { - { .name = "xtal", .required = true }, - { .name = "mpeg-clk", .required = true }, - { .name = "ext-32k-0", .required = false }, -}; - static const struct meson_aoclk_data axg_aoclkc_data = { .reset_reg = AO_RTI_GEN_CNTL_REG0, .num_reset = ARRAY_SIZE(axg_aoclk_reset), @@ -303,9 +317,6 @@ static const struct meson_aoclk_data axg_aoclkc_data = { .num_clks = ARRAY_SIZE(axg_aoclk_regmap), .clks = axg_aoclk_regmap, .hw_data = &axg_aoclk_onecell_data, - .inputs = axg_aoclk_inputs, - .num_inputs = ARRAY_SIZE(axg_aoclk_inputs), - .input_prefix = IN_PREFIX, }; static const struct of_device_id axg_aoclkc_match_table[] = { From 072a043f5a2e02441002fff34e3885e6026714eb Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:41:26 +0200 Subject: [PATCH 06/62] clk: meson: remove ao input bypass clocks During probe, bypass clocks (i.e. ao-in-xtal) are made from device-tree inputs to provide input clocks which can be access through global name. The cons of this method are the duplicated clocks, means more string comparison. Specify parent directly with device-tree clock name. Function to regiter bypass clocks is removed. Input parameters from meson aoclk data structure are deprecated and then deleted since all aoclk files are migrated. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 1 - drivers/clk/meson/meson-aoclk.c | 37 --------------------------------- drivers/clk/meson/meson-aoclk.h | 8 ------- 3 files changed, 46 deletions(-) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index ee0b84b6b329..178ee72ba4bc 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -33,7 +33,6 @@ config COMMON_CLK_MESON_VID_PLL_DIV config COMMON_CLK_MESON_AO_CLKC tristate select COMMON_CLK_MESON_REGMAP - select COMMON_CLK_MESON_INPUT select RESET_CONTROLLER config COMMON_CLK_MESON_EE_CLKC diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c index b67951909e04..bf8bea675d24 100644 --- a/drivers/clk/meson/meson-aoclk.c +++ b/drivers/clk/meson/meson-aoclk.c @@ -17,8 +17,6 @@ #include #include "meson-aoclk.h" -#include "clk-input.h" - static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev, unsigned long id) { @@ -33,37 +31,6 @@ static const struct reset_control_ops meson_aoclk_reset_ops = { .reset = meson_aoclk_do_reset, }; -static int meson_aoclkc_register_inputs(struct device *dev, - struct meson_aoclk_data *data) -{ - struct clk_hw *hw; - char *str; - int i; - - for (i = 0; i < data->num_inputs; i++) { - const struct meson_aoclk_input *in = &data->inputs[i]; - - str = kasprintf(GFP_KERNEL, "%s%s", data->input_prefix, - in->name); - if (!str) - return -ENOMEM; - - hw = meson_clk_hw_register_input(dev, in->name, str, 0); - kfree(str); - - if (IS_ERR(hw)) { - if (!in->required && PTR_ERR(hw) == -ENOENT) - continue; - else if (PTR_ERR(hw) != -EPROBE_DEFER) - dev_err(dev, "failed to register input %s\n", - in->name); - return PTR_ERR(hw); - } - } - - return 0; -} - int meson_aoclkc_probe(struct platform_device *pdev) { struct meson_aoclk_reset_controller *rstc; @@ -86,10 +53,6 @@ int meson_aoclkc_probe(struct platform_device *pdev) return PTR_ERR(regmap); } - ret = meson_aoclkc_register_inputs(dev, data); - if (ret) - return ret; - /* Reset Controller */ rstc->data = data; rstc->regmap = regmap; diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h index 999cde3868f7..605b43855a69 100644 --- a/drivers/clk/meson/meson-aoclk.h +++ b/drivers/clk/meson/meson-aoclk.h @@ -18,20 +18,12 @@ #include "clk-regmap.h" -struct meson_aoclk_input { - const char *name; - bool required; -}; - struct meson_aoclk_data { const unsigned int reset_reg; const int num_reset; const unsigned int *reset; const int num_clks; struct clk_regmap **clks; - const int num_inputs; - const struct meson_aoclk_input *inputs; - const char *input_prefix; const struct clk_hw_onecell_data *hw_data; }; From 25e682a02d91e2d09f47c089a4b42bba726106b9 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:31 +0200 Subject: [PATCH 07/62] clk: meson: g12a: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (ie. when all clocks are local to the controller) and use .parent_data otherwise. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 1673 ++++++++++++++++++++++---------------- 1 file changed, 986 insertions(+), 687 deletions(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 7bc5566b66f7..8cc7f5acf7ab 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -15,7 +15,6 @@ #include #include -#include "clk-input.h" #include "clk-mpll.h" #include "clk-pll.h" #include "clk-regmap.h" @@ -61,7 +60,9 @@ static struct clk_regmap g12a_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -76,7 +77,9 @@ static struct clk_regmap g12a_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -130,7 +133,9 @@ static struct clk_regmap g12a_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -145,7 +150,9 @@ static struct clk_regmap g12a_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sys_pll_dco.hw + }, .num_parents = 1, }, }; @@ -181,7 +188,9 @@ static struct clk_regmap g12b_sys1_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys1_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -196,7 +205,9 @@ static struct clk_regmap g12b_sys1_pll = { .hw.init = &(struct clk_init_data){ .name = "sys1_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys1_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_sys1_pll_dco.hw + }, .num_parents = 1, }, }; @@ -209,7 +220,7 @@ static struct clk_regmap g12a_sys_pll_div16_en = { .hw.init = &(struct clk_init_data) { .name = "sys_pll_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "sys_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_sys_pll.hw }, .num_parents = 1, /* * This clock is used to debug the sys_pll range @@ -226,7 +237,9 @@ static struct clk_regmap g12b_sys1_pll_div16_en = { .hw.init = &(struct clk_init_data) { .name = "sys1_pll_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "sys1_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_sys1_pll.hw + }, .num_parents = 1, /* * This clock is used to debug the sys_pll range @@ -241,7 +254,9 @@ static struct clk_fixed_factor g12a_sys_pll_div16 = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "sys_pll_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sys_pll_div16_en.hw + }, .num_parents = 1, }, }; @@ -252,11 +267,75 @@ static struct clk_fixed_factor g12b_sys1_pll_div16 = { .hw.init = &(struct clk_init_data){ .name = "sys1_pll_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "sys1_pll_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_sys1_pll_div16_en.hw + }, .num_parents = 1, }, }; +static struct clk_fixed_factor g12a_fclk_div2_div = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div2_div.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor g12a_fclk_div3_div = { + .mult = 1, + .div = 3, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3_div", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, + .num_parents = 1, + }, +}; + +static struct clk_regmap g12a_fclk_div3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_FIX_PLL_CNTL1, + .bit_idx = 20, + }, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div3_div.hw + }, + .num_parents = 1, + /* + * This clock is used by the resident firmware and is required + * by the platform to operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, + }, +}; + /* Datasheet names this field as "premux0" */ static struct clk_regmap g12a_cpu_clk_premux0 = { .data = &(struct clk_regmap_mux_data){ @@ -267,9 +346,30 @@ static struct clk_regmap g12a_cpu_clk_premux0 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, + .num_parents = 3, + }, +}; + +/* Datasheet names this field as "premux1" */ +static struct clk_regmap g12a_cpu_clk_premux1 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu_clk_dyn1_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, }, }; @@ -284,7 +384,9 @@ static struct clk_regmap g12a_cpu_clk_mux0_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux0.hw + }, .num_parents = 1, }, }; @@ -299,29 +401,14 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn0_sel", - "cpu_clk_dyn0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux0.hw, + &g12a_cpu_clk_mux0_div.hw, + }, .num_parents = 2, }, }; -/* Datasheet names this field as "premux1" */ -static struct clk_regmap g12a_cpu_clk_premux1 = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_SYS_CPU_CLK_CNTL0, - .mask = 0x3, - .shift = 16, - }, - .hw.init = &(struct clk_init_data){ - .name = "cpu_clk_dyn1_sel", - .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, - .num_parents = 3, - }, -}; - /* Datasheet names this field as "Mux1_divn_tcnt" */ static struct clk_regmap g12a_cpu_clk_mux1_div = { .data = &(struct clk_regmap_div_data){ @@ -332,7 +419,9 @@ static struct clk_regmap g12a_cpu_clk_mux1_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux1.hw + }, .num_parents = 1, }, }; @@ -347,8 +436,10 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn1_sel", - "cpu_clk_dyn1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_premux1.hw, + &g12a_cpu_clk_mux1_div.hw, + }, .num_parents = 2, }, }; @@ -363,8 +454,10 @@ static struct clk_regmap g12a_cpu_clk_dyn = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn0", - "cpu_clk_dyn1" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_postmux0.hw, + &g12a_cpu_clk_postmux1.hw, + }, .num_parents = 2, }, }; @@ -379,8 +472,10 @@ static struct clk_regmap g12a_cpu_clk = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn", - "sys_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_dyn.hw, + &g12a_sys_pll.hw, + }, .num_parents = 2, }, }; @@ -395,8 +490,10 @@ static struct clk_regmap g12b_cpu_clk = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_dyn", - "sys1_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_dyn.hw, + &g12b_sys1_pll.hw + }, .num_parents = 2, }, }; @@ -411,9 +508,11 @@ static struct clk_regmap g12b_cpub_clk_premux0 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, }, }; @@ -428,7 +527,9 @@ static struct clk_regmap g12b_cpub_clk_mux0_div = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux0.hw + }, .num_parents = 1, }, }; @@ -443,8 +544,10 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn0_sel", - "cpub_clk_dyn0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux0.hw, + &g12b_cpub_clk_mux0_div.hw + }, .num_parents = 2, }, }; @@ -459,9 +562,11 @@ static struct clk_regmap g12b_cpub_clk_premux1 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "fclk_div2", - "fclk_div3" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + }, .num_parents = 3, }, }; @@ -476,7 +581,9 @@ static struct clk_regmap g12b_cpub_clk_mux1_div = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux1.hw + }, .num_parents = 1, }, }; @@ -491,8 +598,10 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn1_sel", - "cpub_clk_dyn1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_premux1.hw, + &g12b_cpub_clk_mux1_div.hw + }, .num_parents = 2, }, }; @@ -507,8 +616,10 @@ static struct clk_regmap g12b_cpub_clk_dyn = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn0", - "cpub_clk_dyn1" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_postmux0.hw, + &g12b_cpub_clk_postmux1.hw + }, .num_parents = 2, }, }; @@ -523,8 +634,10 @@ static struct clk_regmap g12b_cpub_clk = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_dyn", - "sys_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_dyn.hw, + &g12a_sys_pll.hw + }, .num_parents = 2, }, }; @@ -537,7 +650,9 @@ static struct clk_regmap g12a_cpu_clk_div16_en = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk.hw + }, .num_parents = 1, /* * This clock is used to debug the cpu_clk range @@ -554,7 +669,9 @@ static struct clk_regmap g12b_cpub_clk_div16_en = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_div16_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, /* * This clock is used to debug the cpu_clk range @@ -569,7 +686,9 @@ static struct clk_fixed_factor g12a_cpu_clk_div16 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_div16_en.hw + }, .num_parents = 1, }, }; @@ -580,7 +699,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div16 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div16", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk_div16_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div16_en.hw + }, .num_parents = 1, }, }; @@ -595,7 +716,7 @@ static struct clk_regmap g12a_cpu_clk_apb_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_apb_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, .num_parents = 1, }, }; @@ -608,7 +729,9 @@ static struct clk_regmap g12a_cpu_clk_apb = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_apb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_apb_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_apb_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -627,7 +750,7 @@ static struct clk_regmap g12a_cpu_clk_atb_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_atb_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, .num_parents = 1, }, }; @@ -640,7 +763,9 @@ static struct clk_regmap g12a_cpu_clk_atb = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_atb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_atb_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_atb_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -659,7 +784,7 @@ static struct clk_regmap g12a_cpu_clk_axi_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_axi_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw }, .num_parents = 1, }, }; @@ -672,7 +797,9 @@ static struct clk_regmap g12a_cpu_clk_axi = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_axi", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_axi_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_axi_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -691,7 +818,17 @@ static struct clk_regmap g12a_cpu_clk_trace_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_trace_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * G12A and G12B have different cpu_clks (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so cpu_clk_trace_div picks + * up the appropriate one. + */ + .name = "cpu_clk", + .index = -1, + }, .num_parents = 1, }, }; @@ -704,7 +841,9 @@ static struct clk_regmap g12a_cpu_clk_trace = { .hw.init = &(struct clk_init_data) { .name = "cpu_clk_trace", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpu_clk_trace_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk_trace_div.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -719,7 +858,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div2 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -730,7 +871,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div3 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div3", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -741,7 +884,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div4 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -752,7 +897,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div5 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div5", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -763,7 +910,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div6 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -774,7 +923,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div7 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div7", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -785,7 +936,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div8 = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_div8", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpub_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk.hw + }, .num_parents = 1, }, }; @@ -801,13 +954,15 @@ static struct clk_regmap g12b_cpub_clk_apb_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_apb_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -821,7 +976,9 @@ static struct clk_regmap g12b_cpub_clk_apb = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_apb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_apb_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_apb_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -840,13 +997,15 @@ static struct clk_regmap g12b_cpub_clk_atb_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_atb_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -860,7 +1019,9 @@ static struct clk_regmap g12b_cpub_clk_atb = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_atb", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_atb_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_atb_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -879,13 +1040,15 @@ static struct clk_regmap g12b_cpub_clk_axi_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_axi_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -899,7 +1062,9 @@ static struct clk_regmap g12b_cpub_clk_axi = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_axi", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_axi_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_axi_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -918,13 +1083,15 @@ static struct clk_regmap g12b_cpub_clk_trace_sel = { .hw.init = &(struct clk_init_data){ .name = "cpub_clk_trace_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_div2", - "cpub_clk_div3", - "cpub_clk_div4", - "cpub_clk_div5", - "cpub_clk_div6", - "cpub_clk_div7", - "cpub_clk_div8" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_div2.hw, + &g12b_cpub_clk_div3.hw, + &g12b_cpub_clk_div4.hw, + &g12b_cpub_clk_div5.hw, + &g12b_cpub_clk_div6.hw, + &g12b_cpub_clk_div7.hw, + &g12b_cpub_clk_div8.hw + }, .num_parents = 7, }, }; @@ -938,7 +1105,9 @@ static struct clk_regmap g12b_cpub_clk_trace = { .hw.init = &(struct clk_init_data) { .name = "cpub_clk_trace", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cpub_clk_trace_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12b_cpub_clk_trace_sel.hw + }, .num_parents = 1, /* * This clock is set by the ROM monitor code, @@ -1003,7 +1172,9 @@ static struct clk_regmap g12a_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -1019,7 +1190,9 @@ static struct clk_regmap g12a_gp0_pll = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp0_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_gp0_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1077,7 +1250,9 @@ static struct clk_regmap g12a_hifi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -1093,7 +1268,9 @@ static struct clk_regmap g12a_hifi_pll = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hifi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hifi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1164,7 +1341,9 @@ static struct clk_regmap g12a_pcie_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco", .ops = &meson_clk_pcie_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -1175,7 +1354,9 @@ static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "pcie_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1193,7 +1374,9 @@ static struct clk_regmap g12a_pcie_pll_od = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_od", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "pcie_pll_dco_div2" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_dco_div2.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1205,7 +1388,9 @@ static struct clk_fixed_factor g12a_pcie_pll = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_pll", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "pcie_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_pcie_pll_od.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1247,7 +1432,9 @@ static struct clk_regmap g12a_hdmi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, /* * Display directly handle hdmi pll registers ATM, we need @@ -1267,7 +1454,9 @@ static struct clk_regmap g12a_hdmi_pll_od = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -1283,7 +1472,9 @@ static struct clk_regmap g12a_hdmi_pll_od2 = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_od.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -1299,77 +1490,21 @@ static struct clk_regmap g12a_hdmi_pll = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_pll_od2.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, }; -static struct clk_fixed_factor g12a_fclk_div2_div = { - .mult = 1, - .div = 2, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div2_div", - .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div2 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div2", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, - .num_parents = 1, - }, -}; - -static struct clk_fixed_factor g12a_fclk_div3_div = { - .mult = 1, - .div = 3, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div3_div", - .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, - .num_parents = 1, - }, -}; - -static struct clk_regmap g12a_fclk_div3 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_FIX_PLL_CNTL1, - .bit_idx = 20, - }, - .hw.init = &(struct clk_init_data){ - .name = "fclk_div3", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, - .num_parents = 1, - /* - * This clock is used by the resident firmware and is required - * by the platform to operate correctly. - * Until the following condition are met, we need this clock to - * be marked as critical: - * a) Mark the clock used by a firmware resource, if possible - * b) CCF has a clock hand-off mechanism to make the sure the - * clock stays on until the proper driver comes along - */ - .flags = CLK_IS_CRITICAL, - }, -}; - static struct clk_fixed_factor g12a_fclk_div4_div = { .mult = 1, .div = 4, .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, .num_parents = 1, }, }; @@ -1382,7 +1517,9 @@ static struct clk_regmap g12a_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -1393,7 +1530,7 @@ static struct clk_fixed_factor g12a_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, .num_parents = 1, }, }; @@ -1406,7 +1543,9 @@ static struct clk_regmap g12a_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -1417,7 +1556,7 @@ static struct clk_fixed_factor g12a_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw }, .num_parents = 1, }, }; @@ -1430,7 +1569,9 @@ static struct clk_regmap g12a_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -1441,7 +1582,9 @@ static struct clk_fixed_factor g12a_fclk_div2p5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2p5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, }, }; @@ -1454,7 +1597,9 @@ static struct clk_regmap g12a_fclk_div2p5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2p5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2p5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fclk_div2p5_div.hw + }, .num_parents = 1, }, }; @@ -1465,7 +1610,9 @@ static struct clk_fixed_factor g12a_mpll_50m_div = { .hw.init = &(struct clk_init_data){ .name = "mpll_50m_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, }, }; @@ -1479,8 +1626,10 @@ static struct clk_regmap g12a_mpll_50m = { .hw.init = &(struct clk_init_data){ .name = "mpll_50m", .ops = &clk_regmap_mux_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal", - "mpll_50m_div" }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_mpll_50m_div.hw }, + }, .num_parents = 2, }, }; @@ -1491,7 +1640,9 @@ static struct clk_fixed_factor g12a_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_fixed_pll_dco.hw + }, .num_parents = 1, }, }; @@ -1529,7 +1680,9 @@ static struct clk_regmap g12a_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1542,7 +1695,7 @@ static struct clk_regmap g12a_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1581,7 +1734,9 @@ static struct clk_regmap g12a_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1594,7 +1749,7 @@ static struct clk_regmap g12a_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1633,7 +1788,9 @@ static struct clk_regmap g12a_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1646,7 +1803,7 @@ static struct clk_regmap g12a_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1685,7 +1842,9 @@ static struct clk_regmap g12a_mpll3_div = { .hw.init = &(struct clk_init_data){ .name = "mpll3_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -1698,16 +1857,21 @@ static struct clk_regmap g12a_mpll3 = { .hw.init = &(struct clk_init_data){ .name = "mpll3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll3_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_mpll3_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const char * const clk81_parent_names[] = { - IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", - "fclk_div3", "fclk_div5" +static const struct clk_parent_data clk81_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div7.hw }, + { .hw = &g12a_mpll1.hw }, + { .hw = &g12a_mpll2.hw }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, }; static struct clk_regmap g12a_mpeg_clk_sel = { @@ -1720,8 +1884,8 @@ static struct clk_regmap g12a_mpeg_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = clk81_parent_names, - .num_parents = ARRAY_SIZE(clk81_parent_names), + .parent_data = clk81_parent_data, + .num_parents = ARRAY_SIZE(clk81_parent_data), }, }; @@ -1734,7 +1898,9 @@ static struct clk_regmap g12a_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpeg_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1748,15 +1914,20 @@ static struct clk_regmap g12a_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mpeg_clk_div.hw + }, .num_parents = 1, .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; -static const char * const g12a_sd_emmc_clk0_parent_names[] = { - IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", - +static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, + { .hw = &g12a_fclk_div7.hw }, /* * Following these parent clocks, we should also have had mpll2, mpll3 * and gp0_pll but these clocks are too precious to be used here. All @@ -1775,8 +1946,8 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names), + .parent_data = g12a_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1790,7 +1961,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_a_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1804,7 +1977,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_a_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_a_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1820,8 +1995,8 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names), + .parent_data = g12a_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1835,7 +2010,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_b_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1849,7 +2026,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_b_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_b_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1865,8 +2044,8 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names), + .parent_data = g12a_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1880,7 +2059,9 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_c_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1894,399 +2075,14 @@ static struct clk_regmap g12a_sd_emmc_c_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_c_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_sd_emmc_c_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -/* VPU Clock */ - -static const char * const g12a_vpu_parent_names[] = { - "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7", - "mpll1", "vid_pll", "hifi_pll", "gp0_pll", -}; - -static struct clk_regmap g12a_vpu_0_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VPU_CLK_CNTL, - .mask = 0x7, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_0_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vpu_parent_names, - .num_parents = ARRAY_SIZE(g12a_vpu_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vpu_0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VPU_CLK_CNTL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_0_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_0_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vpu_0 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VPU_CLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vpu_0", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_0_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vpu_1_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VPU_CLK_CNTL, - .mask = 0x7, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vpu_parent_names, - .num_parents = ARRAY_SIZE(g12a_vpu_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vpu_1_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VPU_CLK_CNTL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu_1_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_1_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vpu_1 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VPU_CLK_CNTL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vpu_1", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_1_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vpu = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VPU_CLK_CNTL, - .mask = 1, - .shift = 31, - }, - .hw.init = &(struct clk_init_data){ - .name = "vpu", - .ops = &clk_regmap_mux_ops, - /* - * bit 31 selects from 2 possible parents: - * vpu_0 or vpu_1 - */ - .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, - .num_parents = 2, - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -/* VDEC clocks */ - -static const char * const g12a_vdec_parent_names[] = { - "fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7", - "hifi_pll", "gp0_pll", -}; - -static struct clk_regmap g12a_vdec_1_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VDEC_CLK_CNTL, - .mask = 0x7, - .shift = 9, - .flags = CLK_MUX_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vdec_parent_names, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_names), - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_1_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VDEC_CLK_CNTL, - .shift = 0, - .width = 7, - .flags = CLK_DIVIDER_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_1_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_1 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VDEC_CLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vdec_1", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevcf_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .mask = 0x7, - .shift = 9, - .flags = CLK_MUX_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevcf_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vdec_parent_names, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_names), - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevcf_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .shift = 0, - .width = 7, - .flags = CLK_DIVIDER_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevcf_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevcf_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevcf = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vdec_hevcf", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevcf_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevc_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .mask = 0x7, - .shift = 25, - .flags = CLK_MUX_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevc_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vdec_parent_names, - .num_parents = ARRAY_SIZE(g12a_vdec_parent_names), - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevc_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .shift = 16, - .width = 7, - .flags = CLK_DIVIDER_ROUND_CLOSEST, - }, - .hw.init = &(struct clk_init_data){ - .name = "vdec_hevc_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevc_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vdec_hevc = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VDEC2_CLK_CNTL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vdec_hevc", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevc_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -/* VAPB Clock */ - -static const char * const g12a_vapb_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", - "mpll1", "vid_pll", "mpll2", "fclk_div2p5", -}; - -static struct clk_regmap g12a_vapb_0_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VAPBCLK_CNTL, - .mask = 0x3, - .shift = 9, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_0_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vapb_parent_names, - .num_parents = ARRAY_SIZE(g12a_vapb_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vapb_0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VAPBCLK_CNTL, - .shift = 0, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_0_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_0_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vapb_0 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VAPBCLK_CNTL, - .bit_idx = 8, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb_0", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_0_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vapb_1_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VAPBCLK_CNTL, - .mask = 0x3, - .shift = 25, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_1_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vapb_parent_names, - .num_parents = ARRAY_SIZE(g12a_vapb_parent_names), - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vapb_1_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_VAPBCLK_CNTL, - .shift = 16, - .width = 7, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_1_div", - .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_1_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static struct clk_regmap g12a_vapb_1 = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VAPBCLK_CNTL, - .bit_idx = 24, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb_1", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_1_div" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - -static struct clk_regmap g12a_vapb_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_VAPBCLK_CNTL, - .mask = 1, - .shift = 31, - }, - .hw.init = &(struct clk_init_data){ - .name = "vapb_sel", - .ops = &clk_regmap_mux_ops, - /* - * bit 31 selects from 2 possible parents: - * vapb_0 or vapb_1 - */ - .parent_names = (const char *[]){ "vapb_0", "vapb_1" }, - .num_parents = 2, - .flags = CLK_SET_RATE_NO_REPARENT, - }, -}; - -static struct clk_regmap g12a_vapb = { - .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VAPBCLK_CNTL, - .bit_idx = 30, - }, - .hw.init = &(struct clk_init_data) { - .name = "vapb", - .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_sel" }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, -}; - /* Video Clocks */ static struct clk_regmap g12a_vid_pll_div = { @@ -2305,14 +2101,16 @@ static struct clk_regmap g12a_vid_pll_div = { .hw.init = &(struct clk_init_data) { .name = "vid_pll_div", .ops = &meson_vid_pll_div_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_pll.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; -static const char * const g12a_vid_pll_parent_names[] = { "vid_pll_div", - "hdmi_pll" }; +static const struct clk_hw *g12a_vid_pll_parent_hws[] = { + &g12a_vid_pll_div.hw, + &g12a_hdmi_pll.hw, +}; static struct clk_regmap g12a_vid_pll_sel = { .data = &(struct clk_regmap_mux_data){ @@ -2327,8 +2125,8 @@ static struct clk_regmap g12a_vid_pll_sel = { * bit 18 selects from 2 possible parents: * vid_pll_div or hdmi_pll */ - .parent_names = g12a_vid_pll_parent_names, - .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_names), + .parent_hws = g12a_vid_pll_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2341,15 +2139,453 @@ static struct clk_regmap g12a_vid_pll = { .hw.init = &(struct clk_init_data) { .name = "vid_pll", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vid_pll_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vid_pll_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, }; -static const char * const g12a_vclk_parent_names[] = { - "vid_pll", "gp0_pll", "hifi_pll", "mpll1", "fclk_div3", "fclk_div4", - "fclk_div5", "fclk_div7" +/* VPU Clock */ + +static const struct clk_hw *g12a_vpu_parent_hws[] = { + &g12a_fclk_div3.hw, + &g12a_fclk_div4.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, + &g12a_mpll1.hw, + &g12a_vid_pll.hw, + &g12a_hifi_pll.hw, + &g12a_gp0_pll.hw, +}; + +static struct clk_regmap g12a_vpu_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x7, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vpu_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vpu_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VPU_CLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vpu_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VPU_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vpu_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vpu_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vpu_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VPU_CLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vpu_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VPU_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vpu = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu", + .ops = &clk_regmap_mux_ops, + /* + * bit 31 selects from 2 possible parents: + * vpu_0 or vpu_1 + */ + .parent_hws = (const struct clk_hw *[]) { + &g12a_vpu_0.hw, + &g12a_vpu_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +/* VDEC clocks */ + +static const struct clk_hw *g12a_vdec_parent_hws[] = { + &g12a_fclk_div2p5.hw, + &g12a_fclk_div3.hw, + &g12a_fclk_div4.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, + &g12a_hifi_pll.hw, + &g12a_gp0_pll.hw, +}; + +static struct clk_regmap g12a_vdec_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vdec_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC_CLK_CNTL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevcf_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevcf_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vdec_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevcf_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .shift = 0, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevcf_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevcf_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevcf = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_hevcf", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevcf_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevc_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .mask = 0x7, + .shift = 25, + .flags = CLK_MUX_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vdec_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevc_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .shift = 16, + .width = 7, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vdec_hevc_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevc_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vdec_hevc = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VDEC2_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vdec_hevc", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vdec_hevc_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* VAPB Clock */ + +static const struct clk_hw *g12a_vapb_parent_hws[] = { + &g12a_fclk_div4.hw, + &g12a_fclk_div3.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, + &g12a_mpll1.hw, + &g12a_vid_pll.hw, + &g12a_mpll2.hw, + &g12a_fclk_div2p5.hw, +}; + +static struct clk_regmap g12a_vapb_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VAPBCLK_CNTL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vapb_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vapb_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VAPBCLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_0_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_0_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vapb_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VAPBCLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_0_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vapb_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VAPBCLK_CNTL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = g12a_vapb_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vapb_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VAPBCLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_1_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_1_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_vapb_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VAPBCLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_1_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static struct clk_regmap g12a_vapb_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VAPBCLK_CNTL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vapb_sel", + .ops = &clk_regmap_mux_ops, + /* + * bit 31 selects from 2 possible parents: + * vapb_0 or vapb_1 + */ + .parent_hws = (const struct clk_hw *[]) { + &g12a_vapb_0.hw, + &g12a_vapb_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap g12a_vapb = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VAPBCLK_CNTL, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "vapb", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &g12a_vapb_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, +}; + +static const struct clk_hw *g12a_vclk_parent_hws[] = { + &g12a_vid_pll.hw, + &g12a_gp0_pll.hw, + &g12a_hifi_pll.hw, + &g12a_mpll1.hw, + &g12a_fclk_div3.hw, + &g12a_fclk_div4.hw, + &g12a_fclk_div5.hw, + &g12a_fclk_div7.hw, }; static struct clk_regmap g12a_vclk_sel = { @@ -2361,8 +2597,8 @@ static struct clk_regmap g12a_vclk_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vclk_parent_names, - .num_parents = ARRAY_SIZE(g12a_vclk_parent_names), + .parent_hws = g12a_vclk_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2376,8 +2612,8 @@ static struct clk_regmap g12a_vclk2_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_vclk_parent_names, - .num_parents = ARRAY_SIZE(g12a_vclk_parent_names), + .parent_hws = g12a_vclk_parent_hws, + .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2390,7 +2626,7 @@ static struct clk_regmap g12a_vclk_input = { .hw.init = &(struct clk_init_data) { .name = "vclk_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2404,7 +2640,7 @@ static struct clk_regmap g12a_vclk2_input = { .hw.init = &(struct clk_init_data) { .name = "vclk2_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_sel" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2419,7 +2655,9 @@ static struct clk_regmap g12a_vclk_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk_input" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2434,7 +2672,9 @@ static struct clk_regmap g12a_vclk2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk2_input" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2448,7 +2688,7 @@ static struct clk_regmap g12a_vclk = { .hw.init = &(struct clk_init_data) { .name = "vclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2462,7 +2702,7 @@ static struct clk_regmap g12a_vclk2 = { .hw.init = &(struct clk_init_data) { .name = "vclk2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2476,7 +2716,7 @@ static struct clk_regmap g12a_vclk_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2490,7 +2730,7 @@ static struct clk_regmap g12a_vclk_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2504,7 +2744,7 @@ static struct clk_regmap g12a_vclk_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2518,7 +2758,7 @@ static struct clk_regmap g12a_vclk_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2532,7 +2772,7 @@ static struct clk_regmap g12a_vclk_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2546,7 +2786,7 @@ static struct clk_regmap g12a_vclk2_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2560,7 +2800,7 @@ static struct clk_regmap g12a_vclk2_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2574,7 +2814,7 @@ static struct clk_regmap g12a_vclk2_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2588,7 +2828,7 @@ static struct clk_regmap g12a_vclk2_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2602,7 +2842,7 @@ static struct clk_regmap g12a_vclk2_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2614,7 +2854,9 @@ static struct clk_fixed_factor g12a_vclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div2_en.hw + }, .num_parents = 1, }, }; @@ -2625,7 +2867,9 @@ static struct clk_fixed_factor g12a_vclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div4_en.hw + }, .num_parents = 1, }, }; @@ -2636,7 +2880,9 @@ static struct clk_fixed_factor g12a_vclk_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div6_en.hw + }, .num_parents = 1, }, }; @@ -2647,7 +2893,9 @@ static struct clk_fixed_factor g12a_vclk_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk_div12_en.hw + }, .num_parents = 1, }, }; @@ -2658,7 +2906,9 @@ static struct clk_fixed_factor g12a_vclk2_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div2_en.hw + }, .num_parents = 1, }, }; @@ -2669,7 +2919,9 @@ static struct clk_fixed_factor g12a_vclk2_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div4_en.hw + }, .num_parents = 1, }, }; @@ -2680,7 +2932,9 @@ static struct clk_fixed_factor g12a_vclk2_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div6_en.hw + }, .num_parents = 1, }, }; @@ -2691,16 +2945,25 @@ static struct clk_fixed_factor g12a_vclk2_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_vclk2_div12_en.hw + }, .num_parents = 1, }, }; static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const g12a_cts_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *g12a_cts_parent_hws[] = { + &g12a_vclk_div1.hw, + &g12a_vclk_div2.hw, + &g12a_vclk_div4.hw, + &g12a_vclk_div6.hw, + &g12a_vclk_div12.hw, + &g12a_vclk2_div1.hw, + &g12a_vclk2_div2.hw, + &g12a_vclk2_div4.hw, + &g12a_vclk2_div6.hw, + &g12a_vclk2_div12.hw, }; static struct clk_regmap g12a_cts_enci_sel = { @@ -2713,8 +2976,8 @@ static struct clk_regmap g12a_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_parent_names), + .parent_hws = g12a_cts_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2729,8 +2992,8 @@ static struct clk_regmap g12a_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_parent_names), + .parent_hws = g12a_cts_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2745,18 +3008,25 @@ static struct clk_regmap g12a_cts_vdac_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_parent_names), + .parent_hws = g12a_cts_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; /* TOFIX: add support for cts_tcon */ static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const g12a_cts_hdmi_tx_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *g12a_cts_hdmi_tx_parent_hws[] = { + &g12a_vclk_div1.hw, + &g12a_vclk_div2.hw, + &g12a_vclk_div4.hw, + &g12a_vclk_div6.hw, + &g12a_vclk_div12.hw, + &g12a_vclk2_div1.hw, + &g12a_vclk2_div2.hw, + &g12a_vclk2_div4.hw, + &g12a_vclk2_div6.hw, + &g12a_vclk2_div12.hw, }; static struct clk_regmap g12a_hdmi_tx_sel = { @@ -2769,8 +3039,8 @@ static struct clk_regmap g12a_hdmi_tx_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_cts_hdmi_tx_parent_names, - .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_names), + .parent_hws = g12a_cts_hdmi_tx_parent_hws, + .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2783,7 +3053,9 @@ static struct clk_regmap g12a_cts_enci = { .hw.init = &(struct clk_init_data) { .name = "cts_enci", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_enci_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cts_enci_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2797,7 +3069,9 @@ static struct clk_regmap g12a_cts_encp = { .hw.init = &(struct clk_init_data) { .name = "cts_encp", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_encp_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cts_encp_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2811,7 +3085,9 @@ static struct clk_regmap g12a_cts_vdac = { .hw.init = &(struct clk_init_data) { .name = "cts_vdac", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_vdac_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cts_vdac_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2825,7 +3101,9 @@ static struct clk_regmap g12a_hdmi_tx = { .hw.init = &(struct clk_init_data) { .name = "hdmi_tx", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_tx_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_hdmi_tx_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2833,8 +3111,11 @@ static struct clk_regmap g12a_hdmi_tx = { /* HDMI Clocks */ -static const char * const g12a_hdmi_parent_names[] = { - IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5" +static const struct clk_parent_data g12a_hdmi_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, }; static struct clk_regmap g12a_hdmi_sel = { @@ -2847,8 +3128,8 @@ static struct clk_regmap g12a_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_hdmi_parent_names, - .num_parents = ARRAY_SIZE(g12a_hdmi_parent_names), + .parent_data = g12a_hdmi_parent_data, + .num_parents = ARRAY_SIZE(g12a_hdmi_parent_data), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2862,7 +3143,7 @@ static struct clk_regmap g12a_hdmi_div = { .hw.init = &(struct clk_init_data){ .name = "hdmi_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hdmi_sel" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_sel.hw }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2876,7 +3157,7 @@ static struct clk_regmap g12a_hdmi = { .hw.init = &(struct clk_init_data) { .name = "hdmi", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_div" }, + .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2886,10 +3167,15 @@ static struct clk_regmap g12a_hdmi = { * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) * muxed by a glitch-free switch. */ - -static const char * const g12a_mali_0_1_parent_names[] = { - IN_PREFIX "xtal", "gp0_pll", "hifi_pll", "fclk_div2p5", - "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7" +static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_gp0_pll.hw }, + { .hw = &g12a_hifi_pll.hw }, + { .hw = &g12a_fclk_div2p5.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div5.hw }, + { .hw = &g12a_fclk_div7.hw }, }; static struct clk_regmap g12a_mali_0_sel = { @@ -2901,7 +3187,7 @@ static struct clk_regmap g12a_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_mali_0_1_parent_names, + .parent_data = g12a_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2916,7 +3202,9 @@ static struct clk_regmap g12a_mali_0_div = { .hw.init = &(struct clk_init_data){ .name = "mali_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2930,7 +3218,9 @@ static struct clk_regmap g12a_mali_0 = { .hw.init = &(struct clk_init_data){ .name = "mali_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2945,7 +3235,7 @@ static struct clk_regmap g12a_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_mali_0_1_parent_names, + .parent_data = g12a_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2960,7 +3250,9 @@ static struct clk_regmap g12a_mali_1_div = { .hw.init = &(struct clk_init_data){ .name = "mali_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -2974,14 +3266,17 @@ static struct clk_regmap g12a_mali_1 = { .hw.init = &(struct clk_init_data){ .name = "mali_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_mali_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const g12a_mali_parent_names[] = { - "mali_0", "mali_1" +static const struct clk_hw *g12a_mali_parent_hws[] = { + &g12a_mali_0.hw, + &g12a_mali_1.hw, }; static struct clk_regmap g12a_mali = { @@ -2993,7 +3288,7 @@ static struct clk_regmap g12a_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_names = g12a_mali_parent_names, + .parent_hws = g12a_mali_parent_hws, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -3008,7 +3303,9 @@ static struct clk_regmap g12a_ts_div = { .hw.init = &(struct clk_init_data){ .name = "ts_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -3021,7 +3318,9 @@ static struct clk_regmap g12a_ts = { .hw.init = &(struct clk_init_data){ .name = "ts", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "ts_div" }, + .parent_hws = (const struct clk_hw *[]) { + &g12a_ts_div.hw + }, .num_parents = 1, }, }; From 0dea3f35996f4571eacbf6cac889d57bfd20822a Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:33 +0200 Subject: [PATCH 08/62] clk: meson: gxbb: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (ie. when all clocks are local to the controller) and use .parent_data otherwise. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/gxbb.c | 654 +++++++++++++++++++++++++++------------ 1 file changed, 451 insertions(+), 203 deletions(-) diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index dab16d9b1af8..67e466356d4b 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -10,15 +10,12 @@ #include #include "gxbb.h" -#include "clk-input.h" #include "clk-regmap.h" #include "clk-pll.h" #include "clk-mpll.h" #include "meson-eeclk.h" #include "vid-pll-div.h" -#define IN_PREFIX "ee-in-" - static DEFINE_SPINLOCK(meson_clk_lock); static const struct pll_params_table gxbb_gp0_pll_params_table[] = { @@ -121,7 +118,9 @@ static struct clk_regmap gxbb_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -136,7 +135,9 @@ static struct clk_regmap gxbb_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -151,7 +152,9 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_pre_mult", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -192,7 +195,9 @@ static struct clk_regmap gxbb_hdmi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_pre_mult.hw + }, .num_parents = 1, /* * Display directly handle hdmi pll registers ATM, we need @@ -244,7 +249,9 @@ static struct clk_regmap gxl_hdmi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, /* * Display directly handle hdmi pll registers ATM, we need @@ -264,7 +271,9 @@ static struct clk_regmap gxbb_hdmi_pll_od = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -280,7 +289,9 @@ static struct clk_regmap gxbb_hdmi_pll_od2 = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_od.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -296,7 +307,9 @@ static struct clk_regmap gxbb_hdmi_pll = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_pll_od2.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -312,7 +325,9 @@ static struct clk_regmap gxl_hdmi_pll_od = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxl_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -328,7 +343,9 @@ static struct clk_regmap gxl_hdmi_pll_od2 = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &gxl_hdmi_pll_od.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -344,7 +361,9 @@ static struct clk_regmap gxl_hdmi_pll = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxl_hdmi_pll_od2.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, }, @@ -381,7 +400,9 @@ static struct clk_regmap gxbb_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -396,7 +417,9 @@ static struct clk_regmap gxbb_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sys_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -442,7 +465,9 @@ static struct clk_regmap gxbb_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -494,7 +519,9 @@ static struct clk_regmap gxl_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -509,7 +536,17 @@ static struct clk_regmap gxbb_gp0_pll = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp0_pll_dco" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * GXL and GXBB have different gp0_pll_dco (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so gp0_pll picks up the + * appropriate one. + */ + .name = "gp0_pll_dco", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -521,7 +558,9 @@ static struct clk_fixed_factor gxbb_fclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -534,7 +573,9 @@ static struct clk_regmap gxbb_fclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div2_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -546,7 +587,7 @@ static struct clk_fixed_factor gxbb_fclk_div3_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -559,7 +600,9 @@ static struct clk_regmap gxbb_fclk_div3 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div3_div.hw + }, .num_parents = 1, /* * FIXME: @@ -582,7 +625,7 @@ static struct clk_fixed_factor gxbb_fclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -595,7 +638,9 @@ static struct clk_regmap gxbb_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -606,7 +651,7 @@ static struct clk_fixed_factor gxbb_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -619,7 +664,9 @@ static struct clk_regmap gxbb_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -630,7 +677,7 @@ static struct clk_fixed_factor gxbb_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -643,7 +690,9 @@ static struct clk_regmap gxbb_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -657,7 +706,7 @@ static struct clk_regmap gxbb_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw }, .num_parents = 1, }, }; @@ -684,7 +733,9 @@ static struct clk_regmap gxbb_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -697,7 +748,7 @@ static struct clk_regmap gxbb_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -725,7 +776,9 @@ static struct clk_regmap gxbb_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -738,7 +791,7 @@ static struct clk_regmap gxbb_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -766,7 +819,9 @@ static struct clk_regmap gxbb_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -779,16 +834,21 @@ static struct clk_regmap gxbb_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const char * const clk81_parent_names[] = { - IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", - "fclk_div3", "fclk_div5" +static const struct clk_parent_data clk81_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_fclk_div7.hw }, + { .hw = &gxbb_mpll1.hw }, + { .hw = &gxbb_mpll2.hw }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, }; static struct clk_regmap gxbb_mpeg_clk_sel = { @@ -806,8 +866,8 @@ static struct clk_regmap gxbb_mpeg_clk_sel = { * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = clk81_parent_names, - .num_parents = ARRAY_SIZE(clk81_parent_names), + .parent_data = clk81_parent_data, + .num_parents = ARRAY_SIZE(clk81_parent_data), }, }; @@ -820,7 +880,9 @@ static struct clk_regmap gxbb_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpeg_clk_sel.hw + }, .num_parents = 1, }, }; @@ -834,7 +896,9 @@ static struct clk_regmap gxbb_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpeg_clk_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -850,7 +914,10 @@ static struct clk_regmap gxbb_sar_adc_clk_sel = { .name = "sar_adc_clk_sel", .ops = &clk_regmap_mux_ops, /* NOTE: The datasheet doesn't list the parents for bit 10 */ - .parent_names = (const char *[]){ IN_PREFIX "xtal", "clk81", }, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &gxbb_clk81.hw }, + }, .num_parents = 2, }, }; @@ -864,7 +931,9 @@ static struct clk_regmap gxbb_sar_adc_clk_div = { .hw.init = &(struct clk_init_data){ .name = "sar_adc_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sar_adc_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sar_adc_clk_sel.hw + }, .num_parents = 1, }, }; @@ -877,7 +946,9 @@ static struct clk_regmap gxbb_sar_adc_clk = { .hw.init = &(struct clk_init_data){ .name = "sar_adc_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sar_adc_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sar_adc_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -888,9 +959,15 @@ static struct clk_regmap gxbb_sar_adc_clk = { * muxed by a glitch-free switch. */ -static const char * const gxbb_mali_0_1_parent_names[] = { - IN_PREFIX "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7", - "fclk_div4", "fclk_div3", "fclk_div5" +static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_gp0_pll.hw }, + { .hw = &gxbb_mpll2.hw }, + { .hw = &gxbb_mpll1.hw }, + { .hw = &gxbb_fclk_div7.hw }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, }; static struct clk_regmap gxbb_mali_0_sel = { @@ -907,7 +984,7 @@ static struct clk_regmap gxbb_mali_0_sel = { * xtal, gp0_pll, mpll2, mpll1, fclk_div7, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = gxbb_mali_0_1_parent_names, + .parent_data = gxbb_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -922,7 +999,9 @@ static struct clk_regmap gxbb_mali_0_div = { .hw.init = &(struct clk_init_data){ .name = "mali_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -936,7 +1015,9 @@ static struct clk_regmap gxbb_mali_0 = { .hw.init = &(struct clk_init_data){ .name = "mali_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -956,7 +1037,7 @@ static struct clk_regmap gxbb_mali_1_sel = { * xtal, gp0_pll, mpll2, mpll1, fclk_div7, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = gxbb_mali_0_1_parent_names, + .parent_data = gxbb_mali_0_1_parent_data, .num_parents = 8, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -971,7 +1052,9 @@ static struct clk_regmap gxbb_mali_1_div = { .hw.init = &(struct clk_init_data){ .name = "mali_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -985,14 +1068,17 @@ static struct clk_regmap gxbb_mali_1 = { .hw.init = &(struct clk_init_data){ .name = "mali_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mali_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const gxbb_mali_parent_names[] = { - "mali_0", "mali_1" +static const struct clk_hw *gxbb_mali_parent_hws[] = { + &gxbb_mali_0.hw, + &gxbb_mali_1.hw, }; static struct clk_regmap gxbb_mali = { @@ -1004,7 +1090,7 @@ static struct clk_regmap gxbb_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_mali_parent_names, + .parent_hws = gxbb_mali_parent_hws, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1021,7 +1107,11 @@ static struct clk_regmap gxbb_cts_amclk_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll0.hw, + &gxbb_mpll1.hw, + &gxbb_mpll2.hw, + }, .num_parents = 3, }, }; @@ -1036,7 +1126,9 @@ static struct clk_regmap gxbb_cts_amclk_div = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_amclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_amclk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1050,7 +1142,9 @@ static struct clk_regmap gxbb_cts_amclk = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_amclk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_amclk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1067,7 +1161,11 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll0.hw, + &gxbb_mpll1.hw, + &gxbb_mpll2.hw, + }, .num_parents = 3, }, }; @@ -1082,7 +1180,9 @@ static struct clk_regmap gxbb_cts_mclk_i958_div = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_mclk_i958_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1096,7 +1196,9 @@ static struct clk_regmap gxbb_cts_mclk_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_mclk_i958", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_mclk_i958_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1111,7 +1213,10 @@ static struct clk_regmap gxbb_cts_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_i958", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_amclk.hw, + &gxbb_cts_mclk_i958.hw + }, .num_parents = 2, /* *The parent is specific to origin of the audio data. Let the @@ -1121,6 +1226,33 @@ static struct clk_regmap gxbb_cts_i958 = { }, }; +static const struct clk_parent_data gxbb_32k_clk_parent_data[] = { + { .fw_name = "xtal", }, + /* + * FIXME: This clock is provided by the ao clock controller but the + * clock is not yet part of the binding of this controller, so string + * name must be use to set this parent. + */ + { .name = "cts_slow_oscin", .index = -1 }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, +}; + +static struct clk_regmap gxbb_32k_clk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_32K_CLK_CNTL, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "32k_clk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = gxbb_32k_clk_parent_data, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap gxbb_32k_clk_div = { .data = &(struct clk_regmap_div_data){ .offset = HHI_32K_CLK_CNTL, @@ -1130,7 +1262,9 @@ static struct clk_regmap gxbb_32k_clk_div = { .hw.init = &(struct clk_init_data){ .name = "32k_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "32k_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_32k_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, }, @@ -1144,34 +1278,20 @@ static struct clk_regmap gxbb_32k_clk = { .hw.init = &(struct clk_init_data){ .name = "32k_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "32k_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_32k_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const gxbb_32k_clk_parent_names[] = { - IN_PREFIX "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5" -}; - -static struct clk_regmap gxbb_32k_clk_sel = { - .data = &(struct clk_regmap_mux_data){ - .offset = HHI_32K_CLK_CNTL, - .mask = 0x3, - .shift = 16, - }, - .hw.init = &(struct clk_init_data){ - .name = "32k_clk_sel", - .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_32k_clk_parent_names, - .num_parents = 4, - .flags = CLK_SET_RATE_PARENT, - }, -}; - -static const char * const gxbb_sd_emmc_clk0_parent_names[] = { - IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", - +static const struct clk_parent_data gxbb_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_fclk_div2.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, + { .hw = &gxbb_fclk_div7.hw }, /* * Following these parent clocks, we should also have had mpll2, mpll3 * and gp0_pll but these clocks are too precious to be used here. All @@ -1190,8 +1310,8 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), + .parent_data = gxbb_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1206,7 +1326,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_a_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_a_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1220,7 +1342,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_a_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_a_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1236,8 +1360,8 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), + .parent_data = gxbb_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1252,7 +1376,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_b_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1266,7 +1392,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_b_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_b_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1282,8 +1410,8 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), + .parent_data = gxbb_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1298,7 +1426,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_c_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1312,7 +1442,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_c_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_sd_emmc_c_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1320,8 +1452,11 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = { /* VPU Clock */ -static const char * const gxbb_vpu_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *gxbb_vpu_parent_hws[] = { + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_fclk_div7.hw, }; static struct clk_regmap gxbb_vpu_0_sel = { @@ -1337,8 +1472,8 @@ static struct clk_regmap gxbb_vpu_0_sel = { * bits 9:10 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vpu_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names), + .parent_hws = gxbb_vpu_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1352,7 +1487,7 @@ static struct clk_regmap gxbb_vpu_0_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1366,7 +1501,7 @@ static struct clk_regmap gxbb_vpu_0 = { .hw.init = &(struct clk_init_data) { .name = "vpu_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_0_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1385,8 +1520,8 @@ static struct clk_regmap gxbb_vpu_1_sel = { * bits 25:26 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vpu_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names), + .parent_hws = gxbb_vpu_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1400,7 +1535,7 @@ static struct clk_regmap gxbb_vpu_1_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1414,7 +1549,7 @@ static struct clk_regmap gxbb_vpu_1 = { .hw.init = &(struct clk_init_data) { .name = "vpu_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_1_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1433,7 +1568,10 @@ static struct clk_regmap gxbb_vpu = { * bit 31 selects from 2 possible parents: * vpu_0 or vpu_1 */ - .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vpu_0.hw, + &gxbb_vpu_1.hw + }, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1441,8 +1579,11 @@ static struct clk_regmap gxbb_vpu = { /* VAPB Clock */ -static const char * const gxbb_vapb_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *gxbb_vapb_parent_hws[] = { + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_fclk_div7.hw, }; static struct clk_regmap gxbb_vapb_0_sel = { @@ -1458,8 +1599,8 @@ static struct clk_regmap gxbb_vapb_0_sel = { * bits 9:10 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vapb_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names), + .parent_hws = gxbb_vapb_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1473,7 +1614,9 @@ static struct clk_regmap gxbb_vapb_0_div = { .hw.init = &(struct clk_init_data){ .name = "vapb_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1487,7 +1630,9 @@ static struct clk_regmap gxbb_vapb_0 = { .hw.init = &(struct clk_init_data) { .name = "vapb_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1506,8 +1651,8 @@ static struct clk_regmap gxbb_vapb_1_sel = { * bits 25:26 selects from 4 possible parents: * fclk_div4, fclk_div3, fclk_div5, fclk_div7, */ - .parent_names = gxbb_vapb_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names), + .parent_hws = gxbb_vapb_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -1521,7 +1666,9 @@ static struct clk_regmap gxbb_vapb_1_div = { .hw.init = &(struct clk_init_data){ .name = "vapb_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vapb_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1535,7 +1682,9 @@ static struct clk_regmap gxbb_vapb_1 = { .hw.init = &(struct clk_init_data) { .name = "vapb_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1554,7 +1703,10 @@ static struct clk_regmap gxbb_vapb_sel = { * bit 31 selects from 2 possible parents: * vapb_0 or vapb_1 */ - .parent_names = (const char *[]){ "vapb_0", "vapb_1" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vapb_0.hw, + &gxbb_vapb_1.hw + }, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1568,7 +1720,7 @@ static struct clk_regmap gxbb_vapb = { .hw.init = &(struct clk_init_data) { .name = "vapb", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vapb_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vapb_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1592,13 +1744,33 @@ static struct clk_regmap gxbb_vid_pll_div = { .hw.init = &(struct clk_init_data) { .name = "vid_pll_div", .ops = &meson_vid_pll_div_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * GXL and GXBB have different hdmi_plls (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vid_pll_div picks up the + * appropriate one. + */ + .name = "hdmi_pll", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, }, }; -static const char * const gxbb_vid_pll_parent_names[] = { "vid_pll_div", "hdmi_pll" }; +static const struct clk_parent_data gxbb_vid_pll_parent_data[] = { + { .hw = &gxbb_vid_pll_div.hw }, + /* + * Note: + * GXL and GXBB have different hdmi_plls (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vid_pll_div picks up the + * appropriate one. + */ + { .name = "hdmi_pll", .index = -1 }, +}; static struct clk_regmap gxbb_vid_pll_sel = { .data = &(struct clk_regmap_mux_data){ @@ -1613,8 +1785,8 @@ static struct clk_regmap gxbb_vid_pll_sel = { * bit 18 selects from 2 possible parents: * vid_pll_div or hdmi_pll */ - .parent_names = gxbb_vid_pll_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_names), + .parent_data = gxbb_vid_pll_parent_data, + .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_data), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1627,15 +1799,22 @@ static struct clk_regmap gxbb_vid_pll = { .hw.init = &(struct clk_init_data) { .name = "vid_pll", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vid_pll_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vid_pll_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, }; -static const char * const gxbb_vclk_parent_names[] = { - "vid_pll", "fclk_div4", "fclk_div3", "fclk_div5", "vid_pll", - "fclk_div7", "mpll1", +static const struct clk_hw *gxbb_vclk_parent_hws[] = { + &gxbb_vid_pll.hw, + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_vid_pll.hw, + &gxbb_fclk_div7.hw, + &gxbb_mpll1.hw, }; static struct clk_regmap gxbb_vclk_sel = { @@ -1652,8 +1831,8 @@ static struct clk_regmap gxbb_vclk_sel = { * vid_pll, fclk_div4, fclk_div3, fclk_div5, * vid_pll, fclk_div7, mp1 */ - .parent_names = gxbb_vclk_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names), + .parent_hws = gxbb_vclk_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1672,8 +1851,8 @@ static struct clk_regmap gxbb_vclk2_sel = { * vid_pll, fclk_div4, fclk_div3, fclk_div5, * vid_pll, fclk_div7, mp1 */ - .parent_names = gxbb_vclk_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names), + .parent_hws = gxbb_vclk_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -1686,7 +1865,7 @@ static struct clk_regmap gxbb_vclk_input = { .hw.init = &(struct clk_init_data) { .name = "vclk_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1700,7 +1879,7 @@ static struct clk_regmap gxbb_vclk2_input = { .hw.init = &(struct clk_init_data) { .name = "vclk2_input", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_sel.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1715,7 +1894,9 @@ static struct clk_regmap gxbb_vclk_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk_input" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -1730,7 +1911,9 @@ static struct clk_regmap gxbb_vclk2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vclk2_input" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_input.hw + }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -1744,7 +1927,7 @@ static struct clk_regmap gxbb_vclk = { .hw.init = &(struct clk_init_data) { .name = "vclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1758,7 +1941,7 @@ static struct clk_regmap gxbb_vclk2 = { .hw.init = &(struct clk_init_data) { .name = "vclk2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1772,7 +1955,7 @@ static struct clk_regmap gxbb_vclk_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1786,7 +1969,7 @@ static struct clk_regmap gxbb_vclk_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1800,7 +1983,7 @@ static struct clk_regmap gxbb_vclk_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1814,7 +1997,7 @@ static struct clk_regmap gxbb_vclk_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1828,7 +2011,7 @@ static struct clk_regmap gxbb_vclk_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1842,7 +2025,7 @@ static struct clk_regmap gxbb_vclk2_div1 = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1856,7 +2039,7 @@ static struct clk_regmap gxbb_vclk2_div2_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div2_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1870,7 +2053,7 @@ static struct clk_regmap gxbb_vclk2_div4_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div4_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1884,7 +2067,7 @@ static struct clk_regmap gxbb_vclk2_div6_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div6_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1898,7 +2081,7 @@ static struct clk_regmap gxbb_vclk2_div12_en = { .hw.init = &(struct clk_init_data) { .name = "vclk2_div12_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vclk2" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -1910,7 +2093,9 @@ static struct clk_fixed_factor gxbb_vclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div2_en.hw + }, .num_parents = 1, }, }; @@ -1921,7 +2106,9 @@ static struct clk_fixed_factor gxbb_vclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div4_en.hw + }, .num_parents = 1, }, }; @@ -1932,7 +2119,9 @@ static struct clk_fixed_factor gxbb_vclk_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div6_en.hw + }, .num_parents = 1, }, }; @@ -1943,7 +2132,9 @@ static struct clk_fixed_factor gxbb_vclk_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk_div12_en.hw + }, .num_parents = 1, }, }; @@ -1954,7 +2145,9 @@ static struct clk_fixed_factor gxbb_vclk2_div2 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div2_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div2_en.hw + }, .num_parents = 1, }, }; @@ -1965,7 +2158,9 @@ static struct clk_fixed_factor gxbb_vclk2_div4 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div4_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div4_en.hw + }, .num_parents = 1, }, }; @@ -1976,7 +2171,9 @@ static struct clk_fixed_factor gxbb_vclk2_div6 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div6_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div6_en.hw + }, .num_parents = 1, }, }; @@ -1987,16 +2184,25 @@ static struct clk_fixed_factor gxbb_vclk2_div12 = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_div12_en" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vclk2_div12_en.hw + }, .num_parents = 1, }, }; static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const gxbb_cts_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *gxbb_cts_parent_hws[] = { + &gxbb_vclk_div1.hw, + &gxbb_vclk_div2.hw, + &gxbb_vclk_div4.hw, + &gxbb_vclk_div6.hw, + &gxbb_vclk_div12.hw, + &gxbb_vclk2_div1.hw, + &gxbb_vclk2_div2.hw, + &gxbb_vclk2_div4.hw, + &gxbb_vclk2_div6.hw, + &gxbb_vclk2_div12.hw, }; static struct clk_regmap gxbb_cts_enci_sel = { @@ -2009,8 +2215,8 @@ static struct clk_regmap gxbb_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_cts_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_names), + .parent_hws = gxbb_cts_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2025,8 +2231,8 @@ static struct clk_regmap gxbb_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_cts_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_names), + .parent_hws = gxbb_cts_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2041,18 +2247,25 @@ static struct clk_regmap gxbb_cts_vdac_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_cts_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_parent_names), + .parent_hws = gxbb_cts_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; /* TOFIX: add support for cts_tcon */ static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; -static const char * const gxbb_cts_hdmi_tx_parent_names[] = { - "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6", - "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4", - "vclk2_div6", "vclk2_div12" +static const struct clk_hw *gxbb_cts_hdmi_tx_parent_hws[] = { + &gxbb_vclk_div1.hw, + &gxbb_vclk_div2.hw, + &gxbb_vclk_div4.hw, + &gxbb_vclk_div6.hw, + &gxbb_vclk_div12.hw, + &gxbb_vclk2_div1.hw, + &gxbb_vclk2_div2.hw, + &gxbb_vclk2_div4.hw, + &gxbb_vclk2_div6.hw, + &gxbb_vclk2_div12.hw, }; static struct clk_regmap gxbb_hdmi_tx_sel = { @@ -2071,8 +2284,8 @@ static struct clk_regmap gxbb_hdmi_tx_sel = { * vclk2_div1, vclk2_div2, vclk2_div4, vclk2_div6, vclk2_div12, * cts_tcon */ - .parent_names = gxbb_cts_hdmi_tx_parent_names, - .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_names), + .parent_hws = gxbb_cts_hdmi_tx_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_hws), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2085,7 +2298,9 @@ static struct clk_regmap gxbb_cts_enci = { .hw.init = &(struct clk_init_data) { .name = "cts_enci", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_enci_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_enci_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2099,7 +2314,9 @@ static struct clk_regmap gxbb_cts_encp = { .hw.init = &(struct clk_init_data) { .name = "cts_encp", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_encp_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_encp_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2113,7 +2330,9 @@ static struct clk_regmap gxbb_cts_vdac = { .hw.init = &(struct clk_init_data) { .name = "cts_vdac", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_vdac_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_cts_vdac_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2127,7 +2346,9 @@ static struct clk_regmap gxbb_hdmi_tx = { .hw.init = &(struct clk_init_data) { .name = "hdmi_tx", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_tx_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_hdmi_tx_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2135,8 +2356,11 @@ static struct clk_regmap gxbb_hdmi_tx = { /* HDMI Clocks */ -static const char * const gxbb_hdmi_parent_names[] = { - IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5" +static const struct clk_parent_data gxbb_hdmi_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, }; static struct clk_regmap gxbb_hdmi_sel = { @@ -2149,8 +2373,8 @@ static struct clk_regmap gxbb_hdmi_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_hdmi_parent_names, - .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_names), + .parent_data = gxbb_hdmi_parent_data, + .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_data), .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, }, }; @@ -2164,7 +2388,7 @@ static struct clk_regmap gxbb_hdmi_div = { .hw.init = &(struct clk_init_data){ .name = "hdmi_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hdmi_sel" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_sel.hw }, .num_parents = 1, .flags = CLK_GET_RATE_NOCACHE, }, @@ -2178,7 +2402,7 @@ static struct clk_regmap gxbb_hdmi = { .hw.init = &(struct clk_init_data) { .name = "hdmi", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "hdmi_div" }, + .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_div.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, }, @@ -2186,8 +2410,11 @@ static struct clk_regmap gxbb_hdmi = { /* VDEC clocks */ -static const char * const gxbb_vdec_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *gxbb_vdec_parent_hws[] = { + &gxbb_fclk_div4.hw, + &gxbb_fclk_div3.hw, + &gxbb_fclk_div5.hw, + &gxbb_fclk_div7.hw, }; static struct clk_regmap gxbb_vdec_1_sel = { @@ -2200,8 +2427,8 @@ static struct clk_regmap gxbb_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_vdec_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names), + .parent_hws = gxbb_vdec_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2216,7 +2443,9 @@ static struct clk_regmap gxbb_vdec_1_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2230,7 +2459,9 @@ static struct clk_regmap gxbb_vdec_1 = { .hw.init = &(struct clk_init_data) { .name = "vdec_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2246,8 +2477,8 @@ static struct clk_regmap gxbb_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_names = gxbb_vdec_parent_names, - .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names), + .parent_hws = gxbb_vdec_parent_hws, + .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2262,7 +2493,9 @@ static struct clk_regmap gxbb_vdec_hevc_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevc_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_hevc_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2276,7 +2509,9 @@ static struct clk_regmap gxbb_vdec_hevc = { .hw.init = &(struct clk_init_data) { .name = "vdec_hevc", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_vdec_hevc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2284,9 +2519,18 @@ static struct clk_regmap gxbb_vdec_hevc = { static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, }; -static const char * const gen_clk_parent_names[] = { - IN_PREFIX "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2", - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", +static const struct clk_parent_data gen_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &gxbb_vdec_1.hw }, + { .hw = &gxbb_vdec_hevc.hw }, + { .hw = &gxbb_mpll0.hw }, + { .hw = &gxbb_mpll1.hw }, + { .hw = &gxbb_mpll2.hw }, + { .hw = &gxbb_fclk_div4.hw }, + { .hw = &gxbb_fclk_div3.hw }, + { .hw = &gxbb_fclk_div5.hw }, + { .hw = &gxbb_fclk_div7.hw }, + { .hw = &gxbb_gp0_pll.hw }, }; static struct clk_regmap gxbb_gen_clk_sel = { @@ -2305,8 +2549,8 @@ static struct clk_regmap gxbb_gen_clk_sel = { * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4, * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll */ - .parent_names = gen_clk_parent_names, - .num_parents = ARRAY_SIZE(gen_clk_parent_names), + .parent_data = gen_clk_parent_data, + .num_parents = ARRAY_SIZE(gen_clk_parent_data), }, }; @@ -2319,7 +2563,9 @@ static struct clk_regmap gxbb_gen_clk_div = { .hw.init = &(struct clk_init_data){ .name = "gen_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gen_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_gen_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2333,7 +2579,9 @@ static struct clk_regmap gxbb_gen_clk = { .hw.init = &(struct clk_init_data){ .name = "gen_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "gen_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_gen_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, From cc132d113dc589d8449fe2b53043b0f17029acac Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:34 +0200 Subject: [PATCH 09/62] clk: meson: axg: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (ie. when all clocks are local to the controller) and use .parent_data otherwise. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 204 ++++++++++++++++++++++++++++------------ 1 file changed, 144 insertions(+), 60 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 3ddd0efc9ee0..7a3d795cc614 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -14,7 +14,6 @@ #include #include -#include "clk-input.h" #include "clk-regmap.h" #include "clk-pll.h" #include "clk-mpll.h" @@ -59,7 +58,9 @@ static struct clk_regmap axg_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -74,7 +75,9 @@ static struct clk_regmap axg_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -114,7 +117,9 @@ static struct clk_regmap axg_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -129,7 +134,9 @@ static struct clk_regmap axg_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sys_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -215,7 +222,9 @@ static struct clk_regmap axg_gp0_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -230,7 +239,9 @@ static struct clk_regmap axg_gp0_pll = { .hw.init = &(struct clk_init_data){ .name = "gp0_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp0_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_gp0_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -284,7 +295,9 @@ static struct clk_regmap axg_hifi_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -299,7 +312,9 @@ static struct clk_regmap axg_hifi_pll = { .hw.init = &(struct clk_init_data){ .name = "hifi_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "hifi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_hifi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -311,7 +326,7 @@ static struct clk_fixed_factor axg_fclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -324,7 +339,9 @@ static struct clk_regmap axg_fclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div2_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -336,7 +353,7 @@ static struct clk_fixed_factor axg_fclk_div3_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -349,7 +366,9 @@ static struct clk_regmap axg_fclk_div3 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div3_div.hw + }, .num_parents = 1, /* * FIXME: @@ -372,7 +391,7 @@ static struct clk_fixed_factor axg_fclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -385,7 +404,9 @@ static struct clk_regmap axg_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -396,7 +417,7 @@ static struct clk_fixed_factor axg_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw }, .num_parents = 1, }, }; @@ -409,7 +430,9 @@ static struct clk_regmap axg_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -420,7 +443,9 @@ static struct clk_fixed_factor axg_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -433,7 +458,9 @@ static struct clk_regmap axg_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -447,7 +474,9 @@ static struct clk_regmap axg_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -480,7 +509,9 @@ static struct clk_regmap axg_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -493,7 +524,9 @@ static struct clk_regmap axg_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -527,7 +560,9 @@ static struct clk_regmap axg_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -540,7 +575,9 @@ static struct clk_regmap axg_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -579,7 +616,9 @@ static struct clk_regmap axg_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -592,7 +631,9 @@ static struct clk_regmap axg_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -626,7 +667,9 @@ static struct clk_regmap axg_mpll3_div = { .hw.init = &(struct clk_init_data){ .name = "mpll3_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -639,7 +682,9 @@ static struct clk_regmap axg_mpll3 = { .hw.init = &(struct clk_init_data){ .name = "mpll3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpll3_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -702,7 +747,9 @@ static struct clk_regmap axg_pcie_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ IN_PREFIX "xtal" }, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, .num_parents = 1, }, }; @@ -717,7 +764,9 @@ static struct clk_regmap axg_pcie_pll_od = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll_od", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "pcie_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_pcie_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -733,7 +782,9 @@ static struct clk_regmap axg_pcie_pll = { .hw.init = &(struct clk_init_data){ .name = "pcie_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "pcie_pll_od" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_pcie_pll_od.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -750,7 +801,7 @@ static struct clk_regmap axg_pcie_mux = { .hw.init = &(struct clk_init_data){ .name = "pcie_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "pcie_pll" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_pll.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -767,7 +818,7 @@ static struct clk_regmap axg_pcie_ref = { .hw.init = &(struct clk_init_data){ .name = "pcie_ref", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "pcie_mux" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_mux.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -781,7 +832,7 @@ static struct clk_regmap axg_pcie_cml_en0 = { .hw.init = &(struct clk_init_data) { .name = "pcie_cml_en0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "pcie_ref" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -796,16 +847,21 @@ static struct clk_regmap axg_pcie_cml_en1 = { .hw.init = &(struct clk_init_data) { .name = "pcie_cml_en1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "pcie_ref" }, + .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; -static const char * const clk81_parent_names[] = { - IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", - "fclk_div3", "fclk_div5" +static const struct clk_parent_data clk81_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &axg_fclk_div7.hw }, + { .hw = &axg_mpll1.hw }, + { .hw = &axg_mpll2.hw }, + { .hw = &axg_fclk_div4.hw }, + { .hw = &axg_fclk_div3.hw }, + { .hw = &axg_fclk_div5.hw }, }; static struct clk_regmap axg_mpeg_clk_sel = { @@ -818,8 +874,8 @@ static struct clk_regmap axg_mpeg_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = clk81_parent_names, - .num_parents = ARRAY_SIZE(clk81_parent_names), + .parent_data = clk81_parent_data, + .num_parents = ARRAY_SIZE(clk81_parent_data), }, }; @@ -832,7 +888,9 @@ static struct clk_regmap axg_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpeg_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -846,15 +904,20 @@ static struct clk_regmap axg_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_mpeg_clk_div.hw + }, .num_parents = 1, .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL), }, }; -static const char * const axg_sd_emmc_clk0_parent_names[] = { - IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", - +static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &axg_fclk_div2.hw }, + { .hw = &axg_fclk_div3.hw }, + { .hw = &axg_fclk_div5.hw }, + { .hw = &axg_fclk_div7.hw }, /* * Following these parent clocks, we should also have had mpll2, mpll3 * and gp0_pll but these clocks are too precious to be used here. All @@ -873,8 +936,8 @@ static struct clk_regmap axg_sd_emmc_b_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = axg_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), + .parent_data = axg_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -889,7 +952,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_b_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_b_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -903,7 +968,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_b_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_b_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -919,8 +986,8 @@ static struct clk_regmap axg_sd_emmc_c_clk0_sel = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = axg_sd_emmc_clk0_parent_names, - .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names), + .parent_data = axg_sd_emmc_clk0_parent_data, + .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data), .flags = CLK_SET_RATE_PARENT, }, }; @@ -935,7 +1002,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0_div = { .hw.init = &(struct clk_init_data) { .name = "sd_emmc_c_clk0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_c_clk0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -949,7 +1018,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = { .hw.init = &(struct clk_init_data){ .name = "sd_emmc_c_clk0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_sd_emmc_c_clk0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -957,9 +1028,18 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = { static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, }; -static const char * const gen_clk_parent_names[] = { - IN_PREFIX "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", +static const struct clk_parent_data gen_clk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &axg_hifi_pll.hw }, + { .hw = &axg_mpll0.hw }, + { .hw = &axg_mpll1.hw }, + { .hw = &axg_mpll2.hw }, + { .hw = &axg_mpll3.hw }, + { .hw = &axg_fclk_div4.hw }, + { .hw = &axg_fclk_div3.hw }, + { .hw = &axg_fclk_div5.hw }, + { .hw = &axg_fclk_div7.hw }, + { .hw = &axg_gp0_pll.hw }, }; static struct clk_regmap axg_gen_clk_sel = { @@ -978,8 +1058,8 @@ static struct clk_regmap axg_gen_clk_sel = { * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll */ - .parent_names = gen_clk_parent_names, - .num_parents = ARRAY_SIZE(gen_clk_parent_names), + .parent_data = gen_clk_parent_data, + .num_parents = ARRAY_SIZE(gen_clk_parent_data), }, }; @@ -992,7 +1072,9 @@ static struct clk_regmap axg_gen_clk_div = { .hw.init = &(struct clk_init_data){ .name = "gen_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gen_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_gen_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1006,7 +1088,9 @@ static struct clk_regmap axg_gen_clk = { .hw.init = &(struct clk_init_data){ .name = "gen_clk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "gen_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &axg_gen_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, From 4b5b85c0e6505c50d4a986f75effe5b88d923737 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:35 +0200 Subject: [PATCH 10/62] clk: meson: meson8b: migrate to the new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (ie. when all clocks are local to the controller) and use .parent_data otherwise. Signed-off-by: Alexandre Mergnat Reviewed-by: Martin Blumenstingl Tested-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 707 +++++++++++++++++++++++++----------- 1 file changed, 496 insertions(+), 211 deletions(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 537219fa573e..b30279a5bfcc 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -97,7 +97,9 @@ static struct clk_regmap meson8b_fixed_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -112,7 +114,9 @@ static struct clk_regmap meson8b_fixed_pll = { .hw.init = &(struct clk_init_data){ .name = "fixed_pll", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll_dco.hw + }, .num_parents = 1, /* * This clock won't ever change at runtime so @@ -158,7 +162,9 @@ static struct clk_regmap meson8b_hdmi_pll_dco = { /* sometimes also called "HPLL" or "HPLL PLL" */ .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -173,7 +179,9 @@ static struct clk_regmap meson8b_hdmi_pll_lvds_out = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_lvds_out", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -189,7 +197,9 @@ static struct clk_regmap meson8b_hdmi_pll_hdmi_out = { .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_hdmi_out", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -227,7 +237,9 @@ static struct clk_regmap meson8b_sys_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -242,7 +254,9 @@ static struct clk_regmap meson8b_sys_pll = { .hw.init = &(struct clk_init_data){ .name = "sys_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "sys_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_sys_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -254,7 +268,9 @@ static struct clk_fixed_factor meson8b_fclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -267,7 +283,9 @@ static struct clk_regmap meson8b_fclk_div2 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div2_div.hw + }, .num_parents = 1, /* * FIXME: Ethernet with a RGMII PHYs is not working if @@ -285,7 +303,9 @@ static struct clk_fixed_factor meson8b_fclk_div3_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -298,7 +318,9 @@ static struct clk_regmap meson8b_fclk_div3 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div3", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div3_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div3_div.hw + }, .num_parents = 1, }, }; @@ -309,7 +331,9 @@ static struct clk_fixed_factor meson8b_fclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -322,7 +346,9 @@ static struct clk_regmap meson8b_fclk_div4 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div4", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div4_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div4_div.hw + }, .num_parents = 1, }, }; @@ -333,7 +359,9 @@ static struct clk_fixed_factor meson8b_fclk_div5_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -346,7 +374,9 @@ static struct clk_regmap meson8b_fclk_div5 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div5", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div5_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div5_div.hw + }, .num_parents = 1, }, }; @@ -357,7 +387,9 @@ static struct clk_fixed_factor meson8b_fclk_div7_div = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7_div", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -370,7 +402,9 @@ static struct clk_regmap meson8b_fclk_div7 = { .hw.init = &(struct clk_init_data){ .name = "fclk_div7", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "fclk_div7_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div7_div.hw + }, .num_parents = 1, }, }; @@ -384,7 +418,9 @@ static struct clk_regmap meson8b_mpll_prediv = { .hw.init = &(struct clk_init_data){ .name = "mpll_prediv", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "fixed_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fixed_pll.hw + }, .num_parents = 1, }, }; @@ -416,7 +452,9 @@ static struct clk_regmap meson8b_mpll0_div = { .hw.init = &(struct clk_init_data){ .name = "mpll0_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -429,7 +467,9 @@ static struct clk_regmap meson8b_mpll0 = { .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -457,7 +497,9 @@ static struct clk_regmap meson8b_mpll1_div = { .hw.init = &(struct clk_init_data){ .name = "mpll1_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -470,7 +512,9 @@ static struct clk_regmap meson8b_mpll1 = { .hw.init = &(struct clk_init_data){ .name = "mpll1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -498,7 +542,9 @@ static struct clk_regmap meson8b_mpll2_div = { .hw.init = &(struct clk_init_data){ .name = "mpll2_div", .ops = &meson_clk_mpll_ops, - .parent_names = (const char *[]){ "mpll_prediv" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll_prediv.hw + }, .num_parents = 1, }, }; @@ -511,7 +557,9 @@ static struct clk_regmap meson8b_mpll2 = { .hw.init = &(struct clk_init_data){ .name = "mpll2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpll2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpll2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -533,8 +581,11 @@ static struct clk_regmap meson8b_mpeg_clk_sel = { * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, * fclk_div4, fclk_div3, fclk_div5 */ - .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", - "fclk_div5" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div3.hw, + &meson8b_fclk_div4.hw, + &meson8b_fclk_div5.hw, + }, .num_parents = 3, }, }; @@ -548,7 +599,9 @@ static struct clk_regmap meson8b_mpeg_clk_div = { .hw.init = &(struct clk_init_data){ .name = "mpeg_clk_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpeg_clk_sel.hw + }, .num_parents = 1, }, }; @@ -561,7 +614,9 @@ static struct clk_regmap meson8b_clk81 = { .hw.init = &(struct clk_init_data){ .name = "clk81", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mpeg_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mpeg_clk_div.hw + }, .num_parents = 1, .flags = CLK_IS_CRITICAL, }, @@ -576,7 +631,10 @@ static struct clk_regmap meson8b_cpu_in_sel = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "xtal", "sys_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw, + &meson8b_sys_pll.hw, + }, .num_parents = 2, .flags = (CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), @@ -589,7 +647,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div2 = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -601,7 +661,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div3 = { .hw.init = &(struct clk_init_data){ .name = "cpu_in_div3", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -630,7 +692,9 @@ static struct clk_regmap meson8b_cpu_scale_div = { .hw.init = &(struct clk_init_data){ .name = "cpu_scale_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cpu_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -649,13 +713,15 @@ static struct clk_regmap meson8b_cpu_scale_out_sel = { .ops = &clk_regmap_mux_ops, /* * NOTE: We are skipping the parent with value 0x2 (which is - * "cpu_in_div3") because it results in a duty cycle of 33% - * which makes the system unstable and can result in a lockup - * of the whole system. + * meson8b_cpu_in_div3) because it results in a duty cycle of + * 33% which makes the system unstable and can result in a + * lockup of the whole system. */ - .parent_names = (const char *[]) { "cpu_in_sel", - "cpu_in_div2", - "cpu_scale_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_in_sel.hw, + &meson8b_cpu_in_div2.hw, + &meson8b_cpu_scale_div.hw, + }, .num_parents = 3, .flags = CLK_SET_RATE_PARENT, }, @@ -670,8 +736,10 @@ static struct clk_regmap meson8b_cpu_clk = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "xtal", - "cpu_scale_out_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw, + &meson8b_cpu_scale_out_sel.hw, + }, .num_parents = 2, .flags = (CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT | @@ -690,8 +758,13 @@ static struct clk_regmap meson8b_nand_clk_sel = { .name = "nand_clk_sel", .ops = &clk_regmap_mux_ops, /* FIXME all other parents are unknown: */ - .parent_names = (const char *[]){ "fclk_div4", "fclk_div3", - "fclk_div5", "fclk_div7", "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_fclk_div7.hw, + &meson8b_xtal.hw, + }, .num_parents = 5, .flags = CLK_SET_RATE_PARENT, }, @@ -707,7 +780,9 @@ static struct clk_regmap meson8b_nand_clk_div = { .hw.init = &(struct clk_init_data){ .name = "nand_clk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "nand_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_nand_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -721,7 +796,9 @@ static struct clk_regmap meson8b_nand_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "nand_clk_gate", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "nand_clk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_nand_clk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -733,7 +810,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div2 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -744,7 +823,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div3 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div3", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -755,7 +836,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div4 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -766,7 +849,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div5 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div5", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -777,7 +862,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div6 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -788,7 +875,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div7 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div7", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -799,7 +888,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div8 = { .hw.init = &(struct clk_init_data){ .name = "cpu_clk_div8", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "cpu_clk" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk.hw + }, .num_parents = 1, }, }; @@ -815,13 +906,15 @@ static struct clk_regmap meson8b_apb_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "apb_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -835,7 +928,9 @@ static struct clk_regmap meson8b_apb_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "apb_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "apb_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_apb_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -850,13 +945,15 @@ static struct clk_regmap meson8b_periph_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "periph_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -870,7 +967,9 @@ static struct clk_regmap meson8b_periph_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "periph_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "periph_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_periph_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -887,13 +986,15 @@ static struct clk_regmap meson8b_axi_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "axi_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -907,7 +1008,9 @@ static struct clk_regmap meson8b_axi_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "axi_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "axi_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_axi_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -922,13 +1025,15 @@ static struct clk_regmap meson8b_l2_dram_clk_sel = { .hw.init = &(struct clk_init_data){ .name = "l2_dram_clk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cpu_clk_div2", - "cpu_clk_div3", - "cpu_clk_div4", - "cpu_clk_div5", - "cpu_clk_div6", - "cpu_clk_div7", - "cpu_clk_div8", }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cpu_clk_div2.hw, + &meson8b_cpu_clk_div3.hw, + &meson8b_cpu_clk_div4.hw, + &meson8b_cpu_clk_div5.hw, + &meson8b_cpu_clk_div6.hw, + &meson8b_cpu_clk_div7.hw, + &meson8b_cpu_clk_div8.hw, + }, .num_parents = 7, }, }; @@ -942,7 +1047,9 @@ static struct clk_regmap meson8b_l2_dram_clk_gate = { .hw.init = &(struct clk_init_data){ .name = "l2_dram_clk_dis", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "l2_dram_clk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_l2_dram_clk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -963,7 +1070,9 @@ static struct clk_regmap meson8b_vid_pll_in_sel = { * Meson8b: hdmi_pll_dco * Meson8m2: vid2_pll */ - .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -977,7 +1086,9 @@ static struct clk_regmap meson8b_vid_pll_in_en = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_in_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vid_pll_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -992,7 +1103,9 @@ static struct clk_regmap meson8b_vid_pll_pre_div = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_pre_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "vid_pll_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1007,7 +1120,9 @@ static struct clk_regmap meson8b_vid_pll_post_div = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_post_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "vid_pll_pre_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_pre_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1023,8 +1138,10 @@ static struct clk_regmap meson8b_vid_pll = { .name = "vid_pll", .ops = &clk_regmap_mux_ro_ops, /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */ - .parent_names = (const char *[]){ "vid_pll_pre_div", - "vid_pll_post_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll_pre_div.hw, + &meson8b_vid_pll_post_div.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -1039,15 +1156,22 @@ static struct clk_regmap meson8b_vid_pll_final_div = { .hw.init = &(struct clk_init_data){ .name = "vid_pll_final_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "vid_pll" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vid_pll.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vclk_mux_parents[] = { - "vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5", - "vid_pll_final_div", "fclk_div7", "mpll1" +static const struct clk_hw *meson8b_vclk_mux_parent_hws[] = { + &meson8b_vid_pll_final_div.hw, + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_vid_pll_final_div.hw, + &meson8b_fclk_div7.hw, + &meson8b_mpll1.hw, }; static struct clk_regmap meson8b_vclk_in_sel = { @@ -1059,8 +1183,8 @@ static struct clk_regmap meson8b_vclk_in_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk_in_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents), + .parent_hws = meson8b_vclk_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1073,7 +1197,9 @@ static struct clk_regmap meson8b_vclk_in_en = { .hw.init = &(struct clk_init_data){ .name = "vclk_in_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1087,7 +1213,9 @@ static struct clk_regmap meson8b_vclk_div1_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div1_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1099,7 +1227,9 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1113,7 +1243,9 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div2_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div2" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1125,7 +1257,9 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1139,7 +1273,9 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div4_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div4" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div4_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1151,7 +1287,9 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1165,7 +1303,9 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div6_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div6" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div6_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1177,7 +1317,9 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1191,7 +1333,9 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk_div12_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk_div12" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk_div12_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1206,8 +1350,8 @@ static struct clk_regmap meson8b_vclk2_in_sel = { .hw.init = &(struct clk_init_data){ .name = "vclk2_in_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents), + .parent_hws = meson8b_vclk_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1220,7 +1364,9 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = { .hw.init = &(struct clk_init_data){ .name = "vclk2_in_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_in_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_in_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1234,7 +1380,9 @@ static struct clk_regmap meson8b_vclk2_div1_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div1_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1246,7 +1394,9 @@ static struct clk_fixed_factor meson8b_vclk2_div2_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1260,7 +1410,9 @@ static struct clk_regmap meson8b_vclk2_div2_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div2_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div2" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1272,7 +1424,9 @@ static struct clk_fixed_factor meson8b_vclk2_div4_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1286,7 +1440,9 @@ static struct clk_regmap meson8b_vclk2_div4_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div4_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div4" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div4_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1298,7 +1454,9 @@ static struct clk_fixed_factor meson8b_vclk2_div6_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1312,7 +1470,9 @@ static struct clk_regmap meson8b_vclk2_div6_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div6_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div6" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div6_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1324,7 +1484,9 @@ static struct clk_fixed_factor meson8b_vclk2_div12_div = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12", .ops = &clk_fixed_factor_ops, - .parent_names = (const char *[]){ "vclk2_in_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_clk_in_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, } @@ -1338,15 +1500,20 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = { .hw.init = &(struct clk_init_data){ .name = "vclk2_div12_en", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "vclk2_div12" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vclk2_div12_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vclk_enc_mux_parents[] = { - "vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en", - "vclk_div12_en", +static const struct clk_hw *meson8b_vclk_enc_mux_parent_hws[] = { + &meson8b_vclk_div1_gate.hw, + &meson8b_vclk_div2_div_gate.hw, + &meson8b_vclk_div4_div_gate.hw, + &meson8b_vclk_div6_div_gate.hw, + &meson8b_vclk_div12_div_gate.hw, }; static struct clk_regmap meson8b_cts_enct_sel = { @@ -1358,8 +1525,8 @@ static struct clk_regmap meson8b_cts_enct_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enct_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1372,7 +1539,9 @@ static struct clk_regmap meson8b_cts_enct = { .hw.init = &(struct clk_init_data){ .name = "cts_enct", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_enct_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_enct_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1387,8 +1556,8 @@ static struct clk_regmap meson8b_cts_encp_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encp_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1401,7 +1570,9 @@ static struct clk_regmap meson8b_cts_encp = { .hw.init = &(struct clk_init_data){ .name = "cts_encp", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_encp_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_encp_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1416,8 +1587,8 @@ static struct clk_regmap meson8b_cts_enci_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_enci_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1430,7 +1601,9 @@ static struct clk_regmap meson8b_cts_enci = { .hw.init = &(struct clk_init_data){ .name = "cts_enci", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_enci_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_enci_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1445,8 +1618,8 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents), + .parent_hws = meson8b_vclk_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1459,15 +1632,20 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = { .hw.init = &(struct clk_init_data){ .name = "hdmi_tx_pixel", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "hdmi_tx_pixel_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_tx_pixel_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vclk2_enc_mux_parents[] = { - "vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en", - "vclk2_div12_en", +static const struct clk_hw *meson8b_vclk2_enc_mux_parent_hws[] = { + &meson8b_vclk2_div1_gate.hw, + &meson8b_vclk2_div2_div_gate.hw, + &meson8b_vclk2_div4_div_gate.hw, + &meson8b_vclk2_div6_div_gate.hw, + &meson8b_vclk2_div12_div_gate.hw, }; static struct clk_regmap meson8b_cts_encl_sel = { @@ -1479,8 +1657,8 @@ static struct clk_regmap meson8b_cts_encl_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_encl_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk2_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents), + .parent_hws = meson8b_vclk2_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1493,7 +1671,9 @@ static struct clk_regmap meson8b_cts_encl = { .hw.init = &(struct clk_init_data){ .name = "cts_encl", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_encl_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_encl_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1508,8 +1688,8 @@ static struct clk_regmap meson8b_cts_vdac0_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac0_sel", .ops = &clk_regmap_mux_ro_ops, - .parent_names = meson8b_vclk2_enc_mux_parents, - .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents), + .parent_hws = meson8b_vclk2_enc_mux_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1522,7 +1702,9 @@ static struct clk_regmap meson8b_cts_vdac0 = { .hw.init = &(struct clk_init_data){ .name = "cts_vdac0", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "cts_vdac0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_vdac0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1539,7 +1721,9 @@ static struct clk_regmap meson8b_hdmi_sys_sel = { .name = "hdmi_sys_sel", .ops = &clk_regmap_mux_ro_ops, /* FIXME: all other parents are unknown */ - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_NO_REPARENT, }, @@ -1554,7 +1738,9 @@ static struct clk_regmap meson8b_hdmi_sys_div = { .hw.init = &(struct clk_init_data){ .name = "hdmi_sys_div", .ops = &clk_regmap_divider_ro_ops, - .parent_names = (const char *[]){ "hdmi_sys_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_sys_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1568,7 +1754,9 @@ static struct clk_regmap meson8b_hdmi_sys = { .hw.init = &(struct clk_init_data) { .name = "hdmi_sys", .ops = &clk_regmap_gate_ro_ops, - .parent_names = (const char *[]){ "hdmi_sys_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_hdmi_sys_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1579,9 +1767,14 @@ static struct clk_regmap meson8b_hdmi_sys = { * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only * has mali_0 and no glitch-free mux. */ -static const char * const meson8b_mali_0_1_parent_names[] = { - "xtal", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3", - "fclk_div5" +static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = { + &meson8b_xtal.hw, + &meson8b_mpll2.hw, + &meson8b_mpll1.hw, + &meson8b_fclk_div7.hw, + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, }; static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 }; @@ -1596,8 +1789,8 @@ static struct clk_regmap meson8b_mali_0_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_mali_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names), + .parent_hws = meson8b_mali_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1617,7 +1810,9 @@ static struct clk_regmap meson8b_mali_0_div = { .hw.init = &(struct clk_init_data){ .name = "mali_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_0_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_0_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1631,7 +1826,9 @@ static struct clk_regmap meson8b_mali_0 = { .hw.init = &(struct clk_init_data){ .name = "mali_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1647,8 +1844,8 @@ static struct clk_regmap meson8b_mali_1_sel = { .hw.init = &(struct clk_init_data){ .name = "mali_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_mali_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names), + .parent_hws = meson8b_mali_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws), /* * Don't propagate rate changes up because the only changeable * parents are mpll1 and mpll2 but we need those for audio and @@ -1668,7 +1865,9 @@ static struct clk_regmap meson8b_mali_1_div = { .hw.init = &(struct clk_init_data){ .name = "mali_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "mali_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1682,7 +1881,9 @@ static struct clk_regmap meson8b_mali_1 = { .hw.init = &(struct clk_init_data){ .name = "mali_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "mali_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1697,7 +1898,10 @@ static struct clk_regmap meson8b_mali = { .hw.init = &(struct clk_init_data){ .name = "mali", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mali_0", "mali_1" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_mali_0.hw, + &meson8b_mali_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -1740,7 +1944,9 @@ static struct clk_regmap meson8m2_gp_pll_dco = { .hw.init = &(struct clk_init_data){ .name = "gp_pll_dco", .ops = &meson_clk_pll_ops, - .parent_names = (const char *[]){ "xtal" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_xtal.hw + }, .num_parents = 1, }, }; @@ -1755,18 +1961,26 @@ static struct clk_regmap meson8m2_gp_pll = { .hw.init = &(struct clk_init_data){ .name = "gp_pll", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "gp_pll_dco" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8m2_gp_pll_dco.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; -static const char * const meson8b_vpu_0_1_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +static const struct clk_hw *meson8b_vpu_0_1_parent_hws[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_fclk_div7.hw, }; -static const char * const mmeson8m2_vpu_0_1_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "gp_pll" +static const struct clk_hw *mmeson8m2_vpu_0_1_parent_hws[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8m2_gp_pll.hw, }; static struct clk_regmap meson8b_vpu_0_sel = { @@ -1778,8 +1992,8 @@ static struct clk_regmap meson8b_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names), + .parent_hws = meson8b_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1793,8 +2007,8 @@ static struct clk_regmap meson8m2_vpu_0_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_sel", .ops = &clk_regmap_mux_ops, - .parent_names = mmeson8m2_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names), + .parent_hws = mmeson8m2_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1808,7 +2022,17 @@ static struct clk_regmap meson8b_vpu_0_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_0_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_0_sel" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * meson8b and meson8m2 have different vpu_0_sels (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vpu_0_div picks up the + * appropriate one. + */ + .name = "vpu_0_sel", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1822,7 +2046,9 @@ static struct clk_regmap meson8b_vpu_0 = { .hw.init = &(struct clk_init_data) { .name = "vpu_0", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_0_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vpu_0_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1837,8 +2063,8 @@ static struct clk_regmap meson8b_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names), + .parent_hws = meson8b_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1852,8 +2078,8 @@ static struct clk_regmap meson8m2_vpu_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = mmeson8m2_vpu_0_1_parent_names, - .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names), + .parent_hws = mmeson8m2_vpu_0_1_parent_hws, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1867,7 +2093,17 @@ static struct clk_regmap meson8b_vpu_1_div = { .hw.init = &(struct clk_init_data){ .name = "vpu_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vpu_1_sel" }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * meson8b and meson8m2 have different vpu_1_sels (with + * different struct clk_hw). We fallback to the global + * naming string mechanism so vpu_1_div picks up the + * appropriate one. + */ + .name = "vpu_1_sel", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1881,7 +2117,9 @@ static struct clk_regmap meson8b_vpu_1 = { .hw.init = &(struct clk_init_data) { .name = "vpu_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vpu_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vpu_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1896,14 +2134,22 @@ static struct clk_regmap meson8b_vpu = { .hw.init = &(struct clk_init_data){ .name = "vpu", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vpu_0.hw, + &meson8b_vpu_1.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_NO_REPARENT, }, }; -static const char * const meson8b_vdec_parent_names[] = { - "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll1" +static const struct clk_hw *meson8b_vdec_parent_hws[] = { + &meson8b_fclk_div4.hw, + &meson8b_fclk_div3.hw, + &meson8b_fclk_div5.hw, + &meson8b_fclk_div7.hw, + &meson8b_mpll2.hw, + &meson8b_mpll1.hw, }; static struct clk_regmap meson8b_vdec_1_sel = { @@ -1916,8 +2162,8 @@ static struct clk_regmap meson8b_vdec_1_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -1932,7 +2178,9 @@ static struct clk_regmap meson8b_vdec_1_1_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_1_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1946,7 +2194,9 @@ static struct clk_regmap meson8b_vdec_1_1 = { .hw.init = &(struct clk_init_data) { .name = "vdec_1_1", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_1_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_1_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1962,7 +2212,9 @@ static struct clk_regmap meson8b_vdec_1_2_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_1_2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_1_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1976,7 +2228,9 @@ static struct clk_regmap meson8b_vdec_1_2 = { .hw.init = &(struct clk_init_data) { .name = "vdec_1_2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_1_2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -1992,7 +2246,10 @@ static struct clk_regmap meson8b_vdec_1 = { .hw.init = &(struct clk_init_data){ .name = "vdec_1", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "vdec_1_1", "vdec_1_2" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_1_1.hw, + &meson8b_vdec_1_2.hw, + }, .num_parents = 2, .flags = CLK_SET_RATE_PARENT, }, @@ -2008,8 +2265,8 @@ static struct clk_regmap meson8b_vdec_hcodec_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hcodec_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2024,7 +2281,9 @@ static struct clk_regmap meson8b_vdec_hcodec_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_hcodec_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hcodec_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hcodec_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2038,7 +2297,9 @@ static struct clk_regmap meson8b_vdec_hcodec = { .hw.init = &(struct clk_init_data) { .name = "vdec_hcodec", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hcodec_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hcodec_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2054,8 +2315,8 @@ static struct clk_regmap meson8b_vdec_2_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_2_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2070,7 +2331,9 @@ static struct clk_regmap meson8b_vdec_2_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_2_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_2_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_2_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2084,7 +2347,9 @@ static struct clk_regmap meson8b_vdec_2 = { .hw.init = &(struct clk_init_data) { .name = "vdec_2", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_2_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_2_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2100,8 +2365,8 @@ static struct clk_regmap meson8b_vdec_hevc_sel = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_vdec_parent_names, - .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), + .parent_hws = meson8b_vdec_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws), .flags = CLK_SET_RATE_PARENT, }, }; @@ -2116,7 +2381,9 @@ static struct clk_regmap meson8b_vdec_hevc_div = { .hw.init = &(struct clk_init_data){ .name = "vdec_hevc_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "vdec_hevc_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hevc_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2130,7 +2397,9 @@ static struct clk_regmap meson8b_vdec_hevc_en = { .hw.init = &(struct clk_init_data) { .name = "vdec_hevc_en", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "vdec_hevc_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hevc_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2147,15 +2416,19 @@ static struct clk_regmap meson8b_vdec_hevc = { .name = "vdec_hevc", .ops = &clk_regmap_mux_ops, /* TODO: The second parent is currently unknown */ - .parent_names = (const char *[]){ "vdec_hevc_en" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_vdec_hevc_en.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ -static const char * const meson8b_cts_amclk_parent_names[] = { - "mpll0", "mpll1", "mpll2" +static const struct clk_hw *meson8b_cts_amclk_parent_hws[] = { + &meson8b_mpll0.hw, + &meson8b_mpll1.hw, + &meson8b_mpll2.hw }; static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 }; @@ -2171,8 +2444,8 @@ static struct clk_regmap meson8b_cts_amclk_sel = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_cts_amclk_parent_names, - .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_names), + .parent_hws = meson8b_cts_amclk_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_hws), }, }; @@ -2186,7 +2459,9 @@ static struct clk_regmap meson8b_cts_amclk_div = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_amclk_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_amclk_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2200,15 +2475,19 @@ static struct clk_regmap meson8b_cts_amclk = { .hw.init = &(struct clk_init_data){ .name = "cts_amclk", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_amclk_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_amclk_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */ -static const char * const meson8b_cts_mclk_i958_parent_names[] = { - "mpll0", "mpll1", "mpll2" +static const struct clk_hw *meson8b_cts_mclk_i958_parent_hws[] = { + &meson8b_mpll0.hw, + &meson8b_mpll1.hw, + &meson8b_mpll2.hw }; static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 }; @@ -2224,8 +2503,8 @@ static struct clk_regmap meson8b_cts_mclk_i958_sel = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_sel", .ops = &clk_regmap_mux_ops, - .parent_names = meson8b_cts_mclk_i958_parent_names, - .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_names), + .parent_hws = meson8b_cts_mclk_i958_parent_hws, + .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_hws), }, }; @@ -2239,7 +2518,9 @@ static struct clk_regmap meson8b_cts_mclk_i958_div = { .hw.init = &(struct clk_init_data) { .name = "cts_mclk_i958_div", .ops = &clk_regmap_divider_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_mclk_i958_sel.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2253,7 +2534,9 @@ static struct clk_regmap meson8b_cts_mclk_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_mclk_i958", .ops = &clk_regmap_gate_ops, - .parent_names = (const char *[]){ "cts_mclk_i958_div" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_mclk_i958_div.hw + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -2268,8 +2551,10 @@ static struct clk_regmap meson8b_cts_i958 = { .hw.init = &(struct clk_init_data){ .name = "cts_i958", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "cts_amclk", - "cts_mclk_i958" }, + .parent_hws = (const struct clk_hw *[]) { + &meson8b_cts_amclk.hw, + &meson8b_cts_mclk_i958.hw + }, .num_parents = 2, /* * The parent is specific to origin of the audio data. Let the From 3a36044e7f3909c7ddb7ddfc727ab8104a563439 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:36 +0200 Subject: [PATCH 11/62] clk: meson: clk-regmap: migrate to new parent description method This clock controller use the string comparison method to describe parent relation between the clocks, which is not optimized. Migrate to the new way by using .parent_hws where possible (ie. when all clocks are local to the controller) and use .parent_data otherwise. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 3 +++ drivers/clk/meson/clk-regmap.h | 12 ++++++------ drivers/clk/meson/g12a.c | 6 ++++++ drivers/clk/meson/gxbb.c | 3 +++ drivers/clk/meson/meson8b.c | 3 +++ 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 7a3d795cc614..13fc0006f63d 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -1096,6 +1096,9 @@ static struct clk_regmap axg_gen_clk = { }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h index 1dd0abe3ba91..c4a39604cffd 100644 --- a/drivers/clk/meson/clk-regmap.h +++ b/drivers/clk/meson/clk-regmap.h @@ -111,7 +111,7 @@ clk_get_regmap_mux_data(struct clk_regmap *clk) extern const struct clk_ops clk_regmap_mux_ops; extern const struct clk_ops clk_regmap_mux_ro_ops; -#define __MESON_GATE(_name, _reg, _bit, _ops) \ +#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \ struct clk_regmap _name = { \ .data = &(struct clk_regmap_gate_data){ \ .offset = (_reg), \ @@ -120,15 +120,15 @@ struct clk_regmap _name = { \ .hw.init = &(struct clk_init_data) { \ .name = #_name, \ .ops = _ops, \ - .parent_names = (const char *[]){ "clk81" }, \ + .parent_hws = (const struct clk_hw *[]) { _pname }, \ .num_parents = 1, \ .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ }, \ } -#define MESON_GATE(_name, _reg, _bit) \ - __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ops) +#define MESON_PCLK(_name, _reg, _bit, _pname) \ + __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname) -#define MESON_GATE_RO(_name, _reg, _bit) \ - __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ro_ops) +#define MESON_PCLK_RO(_name, _reg, _bit, _pname) \ + __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname) #endif /* __CLK_REGMAP_H */ diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 8cc7f5acf7ab..a8f706de811b 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -3325,6 +3325,12 @@ static struct clk_regmap g12a_ts = { }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw) + +#define MESON_GATE_RO(_name, _reg, _bit) \ + MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 67e466356d4b..7cfb998eeb3e 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -2587,6 +2587,9 @@ static struct clk_regmap gxbb_gen_clk = { }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &gxbb_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index b30279a5bfcc..67e6691e080c 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -2564,6 +2564,9 @@ static struct clk_regmap meson8b_cts_i958 = { }, }; +#define MESON_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw) + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); From b11cfaba5b4d6e287540a3d64c403e5b26dd2728 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:37 +0200 Subject: [PATCH 12/62] clk: meson: remove ee input bypass clocks During probe, bypass clocks (i.e. ee-in-xtal) are made from device-tree inputs to provide input clocks which can be access through global name. The cons of this method are the duplicated clocks, means more string comparison. Specify parent directly with device-tree clock name. Remove the bypass clock registration from the ee probe function. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 1 - drivers/clk/meson/meson-eeclk.c | 10 ---------- drivers/clk/meson/meson-eeclk.h | 2 -- 3 files changed, 13 deletions(-) diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 178ee72ba4bc..72a37572501f 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -38,7 +38,6 @@ config COMMON_CLK_MESON_AO_CLKC config COMMON_CLK_MESON_EE_CLKC tristate select COMMON_CLK_MESON_REGMAP - select COMMON_CLK_MESON_INPUT config COMMON_CLK_MESON8B bool diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c index 6ba2094be257..a7cb1e7aedc4 100644 --- a/drivers/clk/meson/meson-eeclk.c +++ b/drivers/clk/meson/meson-eeclk.c @@ -10,7 +10,6 @@ #include #include -#include "clk-input.h" #include "clk-regmap.h" #include "meson-eeclk.h" @@ -18,7 +17,6 @@ int meson_eeclkc_probe(struct platform_device *pdev) { const struct meson_eeclkc_data *data; struct device *dev = &pdev->dev; - struct clk_hw *input; struct regmap *map; int ret, i; @@ -37,14 +35,6 @@ int meson_eeclkc_probe(struct platform_device *pdev) if (data->init_count) regmap_multi_reg_write(map, data->init_regs, data->init_count); - input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0); - if (IS_ERR(input)) { - ret = PTR_ERR(input); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get input clock"); - return ret; - } - /* Populate regmap for the regmap backed clocks */ for (i = 0; i < data->regmap_clk_num; i++) data->regmap_clks[i]->map = map; diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h index 9ab5d6fa7ccb..77316207bde1 100644 --- a/drivers/clk/meson/meson-eeclk.h +++ b/drivers/clk/meson/meson-eeclk.h @@ -10,8 +10,6 @@ #include #include "clk-regmap.h" -#define IN_PREFIX "ee-in-" - struct platform_device; struct meson_eeclkc_data { From e96c7612315a1183e12d5b6ebd523a3a93617510 Mon Sep 17 00:00:00 2001 From: Alexandre Mergnat Date: Thu, 25 Jul 2019 18:42:38 +0200 Subject: [PATCH 13/62] clk: meson: remove clk input helper The clk input function which allows clock controllers to register a bypass clock from a clock producer is no longer needed anymore since meson clock controllers have migrated to a new parent allocation method. Signed-off-by: Alexandre Mergnat Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 3 --- drivers/clk/meson/Makefile | 1 - drivers/clk/meson/clk-input.c | 49 ----------------------------------- drivers/clk/meson/clk-input.h | 19 -------------- 4 files changed, 72 deletions(-) delete mode 100644 drivers/clk/meson/clk-input.c delete mode 100644 drivers/clk/meson/clk-input.h diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 72a37572501f..500be0b0d473 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -1,7 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -config COMMON_CLK_MESON_INPUT - tristate - config COMMON_CLK_MESON_REGMAP tristate select REGMAP diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index bc35a4efd6b7..f09d83dc3d60 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o -obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o diff --git a/drivers/clk/meson/clk-input.c b/drivers/clk/meson/clk-input.c deleted file mode 100644 index 086226e9dba6..000000000000 --- a/drivers/clk/meson/clk-input.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Copyright (c) 2018 BayLibre, SAS. - * Author: Jerome Brunet - */ - -#include -#include -#include -#include -#include "clk-input.h" - -static const struct clk_ops meson_clk_no_ops = {}; - -struct clk_hw *meson_clk_hw_register_input(struct device *dev, - const char *of_name, - const char *clk_name, - unsigned long flags) -{ - struct clk *parent_clk = devm_clk_get(dev, of_name); - struct clk_init_data init; - const char *parent_name; - struct clk_hw *hw; - int ret; - - if (IS_ERR(parent_clk)) - return (struct clk_hw *)parent_clk; - - hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); - if (!hw) - return ERR_PTR(-ENOMEM); - - parent_name = __clk_get_name(parent_clk); - init.name = clk_name; - init.ops = &meson_clk_no_ops; - init.flags = flags; - init.parent_names = &parent_name; - init.num_parents = 1; - hw->init = &init; - - ret = devm_clk_hw_register(dev, hw); - - return ret ? ERR_PTR(ret) : hw; -} -EXPORT_SYMBOL_GPL(meson_clk_hw_register_input); - -MODULE_DESCRIPTION("Amlogic clock input helper"); -MODULE_AUTHOR("Jerome Brunet "); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h deleted file mode 100644 index 4a541b9685a6..000000000000 --- a/drivers/clk/meson/clk-input.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2019 BayLibre, SAS. - * Author: Jerome Brunet - */ - -#ifndef __MESON_CLK_INPUT_H -#define __MESON_CLK_INPUT_H - -#include - -struct device; - -struct clk_hw *meson_clk_hw_register_input(struct device *dev, - const char *of_name, - const char *clk_name, - unsigned long flags); - -#endif /* __MESON_CLK_INPUT_H */ From 568b9de48d80bcf1a92e2c4fa67651abbb8ebfe2 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Mon, 1 Jul 2019 13:36:06 +0200 Subject: [PATCH 14/62] clk: ingenic/jz4740: Fix "pll half" divider not read/written properly The code was setting the bit 21 of the CPCCR register to use a divider of 2 for the "pll half" clock, and clearing the bit to use a divider of 1. This is the opposite of how this register field works: a cleared bit means that the /2 divider is used, and a set bit means that the divider is 1. Restore the correct behaviour using the newly introduced .div_table field. Signed-off-by: Paul Cercueil Link: https://lkml.kernel.org/r/20190701113606.4130-1-paul@crapouillou.net Signed-off-by: Stephen Boyd --- drivers/clk/ingenic/jz4740-cgu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 4c0a20949c2c..9b27d75d9485 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -53,6 +53,10 @@ static const u8 jz4740_cgu_cpccr_div_table[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, }; +static const u8 jz4740_cgu_pll_half_div_table[] = { + 2, 1, +}; + static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { /* External clocks */ @@ -86,7 +90,10 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { [JZ4740_CLK_PLL_HALF] = { "pll half", CGU_CLK_DIV, .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, - .div = { CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1 }, + .div = { + CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, + jz4740_cgu_pll_half_div_table, + }, }, [JZ4740_CLK_CCLK] = { From 46e625b3e320e56da830a847f718635c26af9e04 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Jul 2019 13:13:44 +0530 Subject: [PATCH 15/62] clk: qcom: clk-alpha-pll: Remove unnecessary cast Commit 8f9fab480c7a ("linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL") fixed the overflow for DIV_ROUND_UP_ULL, so we no longer need the cast for DIV_ROUND_UP_ULL, so remove the unnecessary u64 casts. Signed-off-by: Vinod Koul Link: https://lkml.kernel.org/r/20190722074348.29582-2-vkoul@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-alpha-pll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 0ced4a5a9a17..b48707693ffd 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -832,7 +832,7 @@ static int clk_alpha_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, int div; /* 16 -> 0xf, 8 -> 0x7, 4 -> 0x3, 2 -> 0x1, 1 -> 0x0 */ - div = DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; + div = DIV_ROUND_UP_ULL(parent_rate, rate) - 1; return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT, @@ -1094,7 +1094,7 @@ static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw, return -EINVAL; } - div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); + div = DIV_ROUND_UP_ULL(parent_rate, rate); for (i = 0; i < pll->num_post_div; i++) { if (pll->post_div_table[i].div == div) { val = pll->post_div_table[i].val; From 4c45653b0b47a40c013362e17afd884301ad14c1 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Jul 2019 13:13:45 +0530 Subject: [PATCH 16/62] clk: qcom: clk-alpha-pll: Remove post_div_table checks We want users to code properly and fix the post_div_table missing and not rely on core to check. So remove the post_div_table check. Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lkml.kernel.org/r/20190722074348.29582-3-vkoul@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-alpha-pll.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index b48707693ffd..2c6773188761 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1036,11 +1036,6 @@ static unsigned long clk_alpha_pll_postdiv_fabia_recalc_rate(struct clk_hw *hw, u32 i, div = 1, val; int ret; - if (!pll->post_div_table) { - pr_err("Missing the post_div_table for the PLL\n"); - return -EINVAL; - } - ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val); if (ret) return ret; @@ -1063,11 +1058,6 @@ static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw, { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - if (!pll->post_div_table) { - pr_err("Missing the post_div_table for the PLL\n"); - return -EINVAL; - } - return divider_round_rate(hw, rate, prate, pll->post_div_table, pll->width, CLK_DIVIDER_ROUND_CLOSEST); } @@ -1089,11 +1079,6 @@ static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw, if (val & PLL_VOTE_FSM_ENA) return 0; - if (!pll->post_div_table) { - pr_err("Missing the post_div_table for the PLL\n"); - return -EINVAL; - } - div = DIV_ROUND_UP_ULL(parent_rate, rate); for (i = 0; i < pll->num_post_div; i++) { if (pll->post_div_table[i].div == div) { From 548a909597d5c176f66e5ffddb25bdf8c151170e Mon Sep 17 00:00:00 2001 From: Deepak Katragadda Date: Mon, 22 Jul 2019 13:13:46 +0530 Subject: [PATCH 17/62] clk: qcom: clk-alpha-pll: Add support for Trion PLLs Add programming sequence support for managing the Trion PLLs. Signed-off-by: Deepak Katragadda Signed-off-by: Taniya Das [vkoul: port to upstream and tidy-up use upstream way of specifying PLLs] Signed-off-by: Vinod Koul Link: https://lkml.kernel.org/r/20190722074348.29582-4-vkoul@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-alpha-pll.c | 217 +++++++++++++++++++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 7 + 2 files changed, 224 insertions(+) diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 2c6773188761..055318f97991 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -32,6 +32,7 @@ # define PLL_LOCK_DET BIT(31) #define PLL_L_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_L_VAL]) +#define PLL_CAL_L_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_L_VAL]) #define PLL_ALPHA_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL]) #define PLL_ALPHA_VAL_U(p) ((p)->offset + (p)->regs[PLL_OFF_ALPHA_VAL_U]) @@ -44,14 +45,17 @@ # define PLL_VCO_MASK 0x3 #define PLL_USER_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U]) +#define PLL_USER_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL_U1]) #define PLL_CONFIG_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL]) #define PLL_CONFIG_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U]) +#define PLL_CONFIG_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1]) #define PLL_TEST_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL]) #define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U]) #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS]) #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE]) #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC]) +#define PLL_CAL_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_VAL]) const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [CLK_ALPHA_PLL_TYPE_DEFAULT] = { @@ -96,6 +100,22 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_OPMODE] = 0x2c, [PLL_OFF_FRAC] = 0x38, }, + [CLK_ALPHA_PLL_TYPE_TRION] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_CAL_L_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_USER_CTL_U] = 0x10, + [PLL_OFF_USER_CTL_U1] = 0x14, + [PLL_OFF_CONFIG_CTL] = 0x18, + [PLL_OFF_CONFIG_CTL_U] = 0x1c, + [PLL_OFF_CONFIG_CTL_U1] = 0x20, + [PLL_OFF_TEST_CTL] = 0x24, + [PLL_OFF_TEST_CTL_U] = 0x28, + [PLL_OFF_STATUS] = 0x30, + [PLL_OFF_OPMODE] = 0x38, + [PLL_OFF_ALPHA_VAL] = 0x40, + [PLL_OFF_CAL_VAL] = 0x44, + }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -120,6 +140,10 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); #define FABIA_PLL_OUT_MASK 0x7 #define FABIA_PLL_RATE_MARGIN 500 +#define TRION_PLL_STANDBY 0x0 +#define TRION_PLL_RUN 0x1 +#define TRION_PLL_OUT_MASK 0x7 + #define pll_alpha_width(p) \ ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \ ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH) @@ -730,6 +754,130 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate, return alpha_huayra_pll_round_rate(rate, *prate, &l, &a); } +static int trion_pll_is_enabled(struct clk_alpha_pll *pll, + struct regmap *regmap) +{ + u32 mode_regval, opmode_regval; + int ret; + + ret = regmap_read(regmap, PLL_MODE(pll), &mode_regval); + ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_regval); + if (ret) + return 0; + + return ((opmode_regval & TRION_PLL_RUN) && (mode_regval & PLL_OUTCTRL)); +} + +static int clk_trion_pll_is_enabled(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + + return trion_pll_is_enabled(pll, pll->clkr.regmap); +} + +static int clk_trion_pll_enable(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 val; + int ret; + + ret = regmap_read(regmap, PLL_MODE(pll), &val); + if (ret) + return ret; + + /* If in FSM mode, just vote for it */ + if (val & PLL_VOTE_FSM_ENA) { + ret = clk_enable_regmap(hw); + if (ret) + return ret; + return wait_for_pll_enable_active(pll); + } + + /* Set operation mode to RUN */ + regmap_write(regmap, PLL_OPMODE(pll), TRION_PLL_RUN); + + ret = wait_for_pll_enable_lock(pll); + if (ret) + return ret; + + /* Enable the PLL outputs */ + ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), + TRION_PLL_OUT_MASK, TRION_PLL_OUT_MASK); + if (ret) + return ret; + + /* Enable the global PLL outputs */ + return regmap_update_bits(regmap, PLL_MODE(pll), + PLL_OUTCTRL, PLL_OUTCTRL); +} + +static void clk_trion_pll_disable(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 val; + int ret; + + ret = regmap_read(regmap, PLL_MODE(pll), &val); + if (ret) + return; + + /* If in FSM mode, just unvote it */ + if (val & PLL_VOTE_FSM_ENA) { + clk_disable_regmap(hw); + return; + } + + /* Disable the global PLL output */ + ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); + if (ret) + return; + + /* Disable the PLL outputs */ + ret = regmap_update_bits(regmap, PLL_USER_CTL(pll), + TRION_PLL_OUT_MASK, 0); + if (ret) + return; + + /* Place the PLL mode in STANDBY */ + regmap_write(regmap, PLL_OPMODE(pll), TRION_PLL_STANDBY); + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); +} + +static unsigned long +clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 l, frac; + u64 prate = parent_rate; + + regmap_read(regmap, PLL_L_VAL(pll), &l); + regmap_read(regmap, PLL_ALPHA_VAL(pll), &frac); + + return alpha_pll_calc_rate(prate, l, frac, ALPHA_REG_16BIT_WIDTH); +} + +static long clk_trion_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + unsigned long min_freq, max_freq; + u32 l; + u64 a; + + rate = alpha_pll_round_rate(rate, *prate, + &l, &a, ALPHA_REG_16BIT_WIDTH); + if (!pll->vco_table || alpha_pll_find_vco(pll, rate)) + return rate; + + min_freq = pll->vco_table[0].min_freq; + max_freq = pll->vco_table[pll->num_vco - 1].max_freq; + + return clamp(rate, min_freq, max_freq); +} + const struct clk_ops clk_alpha_pll_ops = { .enable = clk_alpha_pll_enable, .disable = clk_alpha_pll_disable, @@ -760,6 +908,15 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = { }; EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops); +const struct clk_ops clk_trion_fixed_pll_ops = { + .enable = clk_trion_pll_enable, + .disable = clk_trion_pll_disable, + .is_enabled = clk_trion_pll_is_enabled, + .recalc_rate = clk_trion_pll_recalc_rate, + .round_rate = clk_trion_pll_round_rate, +}; +EXPORT_SYMBOL_GPL(clk_trion_fixed_pll_ops); + static unsigned long clk_alpha_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -1053,6 +1210,66 @@ static unsigned long clk_alpha_pll_postdiv_fabia_recalc_rate(struct clk_hw *hw, return (parent_rate / div); } +static unsigned long +clk_trion_pll_postdiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 i, div = 1, val; + + regmap_read(regmap, PLL_USER_CTL(pll), &val); + + val >>= pll->post_div_shift; + val &= PLL_POST_DIV_MASK(pll); + + for (i = 0; i < pll->num_post_div; i++) { + if (pll->post_div_table[i].val == val) { + div = pll->post_div_table[i].div; + break; + } + } + + return (parent_rate / div); +} + +static long +clk_trion_pll_postdiv_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + + return divider_round_rate(hw, rate, prate, pll->post_div_table, + pll->width, CLK_DIVIDER_ROUND_CLOSEST); +}; + +static int +clk_trion_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); + struct regmap *regmap = pll->clkr.regmap; + int i, val = 0, div; + + div = DIV_ROUND_UP_ULL(parent_rate, rate); + for (i = 0; i < pll->num_post_div; i++) { + if (pll->post_div_table[i].div == div) { + val = pll->post_div_table[i].val; + break; + } + } + + return regmap_update_bits(regmap, PLL_USER_CTL(pll), + PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT, + val << PLL_POST_DIV_SHIFT); +} + +const struct clk_ops clk_trion_pll_postdiv_ops = { + .recalc_rate = clk_trion_pll_postdiv_recalc_rate, + .round_rate = clk_trion_pll_postdiv_round_rate, + .set_rate = clk_trion_pll_postdiv_set_rate, +}; +EXPORT_SYMBOL_GPL(clk_trion_pll_postdiv_ops); + static long clk_alpha_pll_postdiv_fabia_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 66755f0f84fc..15f27f4b06df 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -13,22 +13,27 @@ enum { CLK_ALPHA_PLL_TYPE_HUAYRA, CLK_ALPHA_PLL_TYPE_BRAMMO, CLK_ALPHA_PLL_TYPE_FABIA, + CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_MAX, }; enum { PLL_OFF_L_VAL, + PLL_OFF_CAL_L_VAL, PLL_OFF_ALPHA_VAL, PLL_OFF_ALPHA_VAL_U, PLL_OFF_USER_CTL, PLL_OFF_USER_CTL_U, + PLL_OFF_USER_CTL_U1, PLL_OFF_CONFIG_CTL, PLL_OFF_CONFIG_CTL_U, + PLL_OFF_CONFIG_CTL_U1, PLL_OFF_TEST_CTL, PLL_OFF_TEST_CTL_U, PLL_OFF_STATUS, PLL_OFF_OPMODE, PLL_OFF_FRAC, + PLL_OFF_CAL_VAL, PLL_OFF_MAX_REGS }; @@ -117,5 +122,7 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); +extern const struct clk_ops clk_trion_fixed_pll_ops; +extern const struct clk_ops clk_trion_pll_postdiv_ops; #endif From e5ee331ebcf33827d1bd64e984c565b23cf53227 Mon Sep 17 00:00:00 2001 From: Deepak Katragadda Date: Mon, 22 Jul 2019 13:13:47 +0530 Subject: [PATCH 18/62] dt-bindings: clock: Document gcc bindings for SM8150 Document the global clock controller found on SM8150. Signed-off-by: Deepak Katragadda Signed-off-by: Taniya Das [vkoul: port to upstream and add external clocks split binding to this patch]] Signed-off-by: Vinod Koul Link: https://lkml.kernel.org/r/20190722074348.29582-5-vkoul@kernel.org Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gcc.txt | 21 ++ include/dt-bindings/clock/qcom,gcc-sm8150.h | 243 ++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 include/dt-bindings/clock/qcom,gcc-sm8150.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 8661c3cd3ccf..d14362ad4132 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -23,6 +23,7 @@ Required properties : "qcom,gcc-sdm630" "qcom,gcc-sdm660" "qcom,gcc-sdm845" + "qcom,gcc-sm8150" - reg : shall contain base register location and length - #clock-cells : shall contain 1 @@ -38,6 +39,13 @@ Documentation/devicetree/bindings/thermal/qcom-tsens.txt - protected-clocks : Protected clock specifier list as per common clock binding. +For SM8150 only: + - clocks: a list of phandles and clock-specifier pairs, + one for each entry in clock-names. + - clock-names: "bi_tcxo" (required) + "sleep_clk" (optional) + "aud_ref_clock" (optional) + Example: clock-controller@900000 { compatible = "qcom,gcc-msm8960"; @@ -71,3 +79,16 @@ Example of GCC with protected-clocks properties: , ; }; + +Example of GCC with clocks + gcc: clock-controller@100000 { + compatible = "qcom,gcc-sm8150"; + reg = <0x00100000 0x1f0000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + clock-names = "bi_tcxo", + "sleep_clk"; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>; + }; diff --git a/include/dt-bindings/clock/qcom,gcc-sm8150.h b/include/dt-bindings/clock/qcom,gcc-sm8150.h new file mode 100644 index 000000000000..90d60ef94c64 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sm8150.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM8150_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SM8150_H + +/* GCC clocks */ +#define GCC_AGGRE_NOC_PCIE_TBU_CLK 0 +#define GCC_AGGRE_UFS_CARD_AXI_CLK 1 +#define GCC_AGGRE_UFS_CARD_AXI_HW_CTL_CLK 2 +#define GCC_AGGRE_UFS_PHY_AXI_CLK 3 +#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK 4 +#define GCC_AGGRE_USB3_PRIM_AXI_CLK 5 +#define GCC_AGGRE_USB3_SEC_AXI_CLK 6 +#define GCC_BOOT_ROM_AHB_CLK 7 +#define GCC_CAMERA_AHB_CLK 8 +#define GCC_CAMERA_HF_AXI_CLK 9 +#define GCC_CAMERA_SF_AXI_CLK 10 +#define GCC_CAMERA_XO_CLK 11 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 12 +#define GCC_CFG_NOC_USB3_SEC_AXI_CLK 13 +#define GCC_CPUSS_AHB_CLK 14 +#define GCC_CPUSS_AHB_CLK_SRC 15 +#define GCC_CPUSS_DVM_BUS_CLK 16 +#define GCC_CPUSS_GNOC_CLK 17 +#define GCC_CPUSS_RBCPR_CLK 18 +#define GCC_DDRSS_GPU_AXI_CLK 19 +#define GCC_DISP_AHB_CLK 20 +#define GCC_DISP_HF_AXI_CLK 21 +#define GCC_DISP_SF_AXI_CLK 22 +#define GCC_DISP_XO_CLK 23 +#define GCC_EMAC_AXI_CLK 24 +#define GCC_EMAC_PTP_CLK 25 +#define GCC_EMAC_PTP_CLK_SRC 26 +#define GCC_EMAC_RGMII_CLK 27 +#define GCC_EMAC_RGMII_CLK_SRC 28 +#define GCC_EMAC_SLV_AHB_CLK 29 +#define GCC_GP1_CLK 30 +#define GCC_GP1_CLK_SRC 31 +#define GCC_GP2_CLK 32 +#define GCC_GP2_CLK_SRC 33 +#define GCC_GP3_CLK 34 +#define GCC_GP3_CLK_SRC 35 +#define GCC_GPU_CFG_AHB_CLK 36 +#define GCC_GPU_GPLL0_CLK_SRC 37 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 38 +#define GCC_GPU_IREF_CLK 39 +#define GCC_GPU_MEMNOC_GFX_CLK 40 +#define GCC_GPU_SNOC_DVM_GFX_CLK 41 +#define GCC_NPU_AT_CLK 42 +#define GCC_NPU_AXI_CLK 43 +#define GCC_NPU_CFG_AHB_CLK 44 +#define GCC_NPU_GPLL0_CLK_SRC 45 +#define GCC_NPU_GPLL0_DIV_CLK_SRC 46 +#define GCC_NPU_TRIG_CLK 47 +#define GCC_PCIE0_PHY_REFGEN_CLK 48 +#define GCC_PCIE1_PHY_REFGEN_CLK 49 +#define GCC_PCIE_0_AUX_CLK 50 +#define GCC_PCIE_0_AUX_CLK_SRC 51 +#define GCC_PCIE_0_CFG_AHB_CLK 52 +#define GCC_PCIE_0_CLKREF_CLK 53 +#define GCC_PCIE_0_MSTR_AXI_CLK 54 +#define GCC_PCIE_0_PIPE_CLK 55 +#define GCC_PCIE_0_SLV_AXI_CLK 56 +#define GCC_PCIE_0_SLV_Q2A_AXI_CLK 57 +#define GCC_PCIE_1_AUX_CLK 58 +#define GCC_PCIE_1_AUX_CLK_SRC 59 +#define GCC_PCIE_1_CFG_AHB_CLK 60 +#define GCC_PCIE_1_CLKREF_CLK 61 +#define GCC_PCIE_1_MSTR_AXI_CLK 62 +#define GCC_PCIE_1_PIPE_CLK 63 +#define GCC_PCIE_1_SLV_AXI_CLK 64 +#define GCC_PCIE_1_SLV_Q2A_AXI_CLK 65 +#define GCC_PCIE_PHY_AUX_CLK 66 +#define GCC_PCIE_PHY_REFGEN_CLK_SRC 67 +#define GCC_PDM2_CLK 68 +#define GCC_PDM2_CLK_SRC 69 +#define GCC_PDM_AHB_CLK 70 +#define GCC_PDM_XO4_CLK 71 +#define GCC_PRNG_AHB_CLK 72 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 73 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 74 +#define GCC_QMIP_DISP_AHB_CLK 75 +#define GCC_QMIP_VIDEO_CVP_AHB_CLK 76 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 77 +#define GCC_QSPI_CNOC_PERIPH_AHB_CLK 78 +#define GCC_QSPI_CORE_CLK 79 +#define GCC_QSPI_CORE_CLK_SRC 80 +#define GCC_QUPV3_WRAP0_S0_CLK 81 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 82 +#define GCC_QUPV3_WRAP0_S1_CLK 83 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 84 +#define GCC_QUPV3_WRAP0_S2_CLK 85 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 86 +#define GCC_QUPV3_WRAP0_S3_CLK 87 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 88 +#define GCC_QUPV3_WRAP0_S4_CLK 89 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 90 +#define GCC_QUPV3_WRAP0_S5_CLK 91 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 92 +#define GCC_QUPV3_WRAP0_S6_CLK 93 +#define GCC_QUPV3_WRAP0_S6_CLK_SRC 94 +#define GCC_QUPV3_WRAP0_S7_CLK 95 +#define GCC_QUPV3_WRAP0_S7_CLK_SRC 96 +#define GCC_QUPV3_WRAP1_S0_CLK 97 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 98 +#define GCC_QUPV3_WRAP1_S1_CLK 99 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 100 +#define GCC_QUPV3_WRAP1_S2_CLK 101 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 102 +#define GCC_QUPV3_WRAP1_S3_CLK 103 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 104 +#define GCC_QUPV3_WRAP1_S4_CLK 105 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 106 +#define GCC_QUPV3_WRAP1_S5_CLK 107 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 108 +#define GCC_QUPV3_WRAP2_S0_CLK 109 +#define GCC_QUPV3_WRAP2_S0_CLK_SRC 110 +#define GCC_QUPV3_WRAP2_S1_CLK 111 +#define GCC_QUPV3_WRAP2_S1_CLK_SRC 112 +#define GCC_QUPV3_WRAP2_S2_CLK 113 +#define GCC_QUPV3_WRAP2_S2_CLK_SRC 114 +#define GCC_QUPV3_WRAP2_S3_CLK 115 +#define GCC_QUPV3_WRAP2_S3_CLK_SRC 116 +#define GCC_QUPV3_WRAP2_S4_CLK 117 +#define GCC_QUPV3_WRAP2_S4_CLK_SRC 118 +#define GCC_QUPV3_WRAP2_S5_CLK 119 +#define GCC_QUPV3_WRAP2_S5_CLK_SRC 120 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 121 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 122 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 123 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 124 +#define GCC_QUPV3_WRAP_2_M_AHB_CLK 125 +#define GCC_QUPV3_WRAP_2_S_AHB_CLK 126 +#define GCC_SDCC2_AHB_CLK 127 +#define GCC_SDCC2_APPS_CLK 128 +#define GCC_SDCC2_APPS_CLK_SRC 129 +#define GCC_SDCC4_AHB_CLK 130 +#define GCC_SDCC4_APPS_CLK 131 +#define GCC_SDCC4_APPS_CLK_SRC 132 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 133 +#define GCC_TSIF_AHB_CLK 134 +#define GCC_TSIF_INACTIVITY_TIMERS_CLK 135 +#define GCC_TSIF_REF_CLK 136 +#define GCC_TSIF_REF_CLK_SRC 137 +#define GCC_UFS_CARD_AHB_CLK 138 +#define GCC_UFS_CARD_AXI_CLK 139 +#define GCC_UFS_CARD_AXI_CLK_SRC 140 +#define GCC_UFS_CARD_AXI_HW_CTL_CLK 141 +#define GCC_UFS_CARD_CLKREF_CLK 142 +#define GCC_UFS_CARD_ICE_CORE_CLK 143 +#define GCC_UFS_CARD_ICE_CORE_CLK_SRC 144 +#define GCC_UFS_CARD_ICE_CORE_HW_CTL_CLK 145 +#define GCC_UFS_CARD_PHY_AUX_CLK 146 +#define GCC_UFS_CARD_PHY_AUX_CLK_SRC 147 +#define GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK 148 +#define GCC_UFS_CARD_RX_SYMBOL_0_CLK 149 +#define GCC_UFS_CARD_RX_SYMBOL_1_CLK 150 +#define GCC_UFS_CARD_TX_SYMBOL_0_CLK 151 +#define GCC_UFS_CARD_UNIPRO_CORE_CLK 152 +#define GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC 153 +#define GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK 154 +#define GCC_UFS_MEM_CLKREF_CLK 155 +#define GCC_UFS_PHY_AHB_CLK 156 +#define GCC_UFS_PHY_AXI_CLK 157 +#define GCC_UFS_PHY_AXI_CLK_SRC 158 +#define GCC_UFS_PHY_AXI_HW_CTL_CLK 159 +#define GCC_UFS_PHY_ICE_CORE_CLK 160 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 161 +#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK 162 +#define GCC_UFS_PHY_PHY_AUX_CLK 163 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 164 +#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK 165 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 166 +#define GCC_UFS_PHY_RX_SYMBOL_1_CLK 167 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 168 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 169 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 170 +#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK 171 +#define GCC_USB30_PRIM_MASTER_CLK 172 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 173 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 174 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 175 +#define GCC_USB30_PRIM_SLEEP_CLK 176 +#define GCC_USB30_SEC_MASTER_CLK 177 +#define GCC_USB30_SEC_MASTER_CLK_SRC 178 +#define GCC_USB30_SEC_MOCK_UTMI_CLK 179 +#define GCC_USB30_SEC_MOCK_UTMI_CLK_SRC 180 +#define GCC_USB30_SEC_SLEEP_CLK 181 +#define GCC_USB3_PRIM_CLKREF_CLK 182 +#define GCC_USB3_PRIM_PHY_AUX_CLK 183 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 184 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 185 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 186 +#define GCC_USB3_SEC_CLKREF_CLK 187 +#define GCC_USB3_SEC_PHY_AUX_CLK 188 +#define GCC_USB3_SEC_PHY_AUX_CLK_SRC 189 +#define GCC_USB3_SEC_PHY_COM_AUX_CLK 190 +#define GCC_USB3_SEC_PHY_PIPE_CLK 191 +#define GCC_VIDEO_AHB_CLK 192 +#define GCC_VIDEO_AXI0_CLK 193 +#define GCC_VIDEO_AXI1_CLK 194 +#define GCC_VIDEO_AXIC_CLK 195 +#define GCC_VIDEO_XO_CLK 196 +#define GPLL0 197 +#define GPLL0_OUT_EVEN 198 +#define GPLL7 199 +#define GPLL9 200 + +/* Reset clocks */ +#define GCC_EMAC_BCR 0 +#define GCC_GPU_BCR 1 +#define GCC_MMSS_BCR 2 +#define GCC_NPU_BCR 3 +#define GCC_PCIE_0_BCR 4 +#define GCC_PCIE_0_PHY_BCR 5 +#define GCC_PCIE_1_BCR 6 +#define GCC_PCIE_1_PHY_BCR 7 +#define GCC_PCIE_PHY_BCR 8 +#define GCC_PDM_BCR 9 +#define GCC_PRNG_BCR 10 +#define GCC_QSPI_BCR 11 +#define GCC_QUPV3_WRAPPER_0_BCR 12 +#define GCC_QUPV3_WRAPPER_1_BCR 13 +#define GCC_QUPV3_WRAPPER_2_BCR 14 +#define GCC_QUSB2PHY_PRIM_BCR 15 +#define GCC_QUSB2PHY_SEC_BCR 16 +#define GCC_USB3_PHY_PRIM_BCR 17 +#define GCC_USB3_DP_PHY_PRIM_BCR 18 +#define GCC_USB3_PHY_SEC_BCR 19 +#define GCC_USB3PHY_PHY_SEC_BCR 20 +#define GCC_SDCC2_BCR 21 +#define GCC_SDCC4_BCR 22 +#define GCC_TSIF_BCR 23 +#define GCC_UFS_CARD_BCR 24 +#define GCC_UFS_PHY_BCR 25 +#define GCC_USB30_PRIM_BCR 26 +#define GCC_USB30_SEC_BCR 27 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 28 + +#endif From 2a1d7eb854bb7737b4927f3266ba169dbb4aeae3 Mon Sep 17 00:00:00 2001 From: Deepak Katragadda Date: Mon, 22 Jul 2019 13:13:48 +0530 Subject: [PATCH 19/62] clk: qcom: gcc: Add global clock controller driver for SM8150 Add the clocks supported in global clock controller which clock the peripherals like BLSPs, SDCC, USB, MDSS etc. Register all the clocks to the clock framework for the clients to be able to request for them. Signed-off-by: Deepak Katragadda Signed-off-by: Taniya Das [vkoul: port to upstream and tidy-up port to new parent scheme Add comments for critical clocks]] Signed-off-by: Vinod Koul Link: https://lkml.kernel.org/r/20190722074348.29582-6-vkoul@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 7 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gcc-sm8150.c | 3588 +++++++++++++++++++++++++++++++++ 3 files changed, 3596 insertions(+) create mode 100644 drivers/clk/qcom/gcc-sm8150.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e1ff83cc361e..73cf0e916ea0 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -292,6 +292,13 @@ config SDM_LPASSCC_845 Say Y if you want to use the LPASS branch clocks of the LPASS clock controller to reset the LPASS subsystem. +config SM_GCC_8150 + tristate "SM8150 Global Clock Controller" + help + Support for the global clock controller on SM8150 devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on SPMI || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index f0768fb1f037..4a813b4055d0 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o +obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o obj-$(CONFIG_QCOM_HFPLL) += hfpll.o diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c new file mode 100644 index 000000000000..12ca2d14797f --- /dev/null +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -0,0 +1,3588 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_AUD_REF_CLK, + P_CORE_BI_PLL_TEST_SE, + P_GPLL0_OUT_EVEN, + P_GPLL0_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_GPLL9_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct pll_vco trion_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +static struct clk_alpha_pll gpll0 = { + .offset = 0x0, + .vco_table = trion_vco, + .num_vco = ARRAY_SIZE(trion_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_trion_fixed_pll_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_trion_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_trion_even, + .num_post_div = ARRAY_SIZE(post_div_table_trion_even), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], + .width = 4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll0_out_even", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_trion_pll_postdiv_ops, + }, +}; + +static struct clk_alpha_pll gpll7 = { + .offset = 0x1a000, + .vco_table = trion_vco, + .num_vco = ARRAY_SIZE(trion_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll7", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_trion_fixed_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll9 = { + .offset = 0x1c000, + .vco_table = trion_vco, + .num_vco = ARRAY_SIZE(trion_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gpll9", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + .name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_trion_fixed_pll_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_0[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_1[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "sleep_clk", .name = "sleep_clk" }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_2[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "sleep_clk", .name = "sleep_clk" }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_3[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "core_bi_pll_test_se"}, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_4[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_5[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll7.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL9_OUT_MAIN, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_6[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll9.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_AUD_REF_CLK, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const struct clk_parent_data gcc_parents_7[] = { + { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .fw_name = "aud_ref_clk", .name = "aud_ref_clk" }, + { .hw = &gpll0_out_even.clkr.hw }, + { .fw_name = "core_bi_pll_test_se" }, +}; + +static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { + .cmd_rcgr = 0x48014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac_ptp_clk_src = { + .cmd_rcgr = 0x6038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_emac_ptp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_emac_ptp_clk_src", + .parent_data = gcc_parents_5, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = { + F(2500000, P_BI_TCXO, 1, 25, 192), + F(5000000, P_BI_TCXO, 1, 25, 96), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0), + F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_emac_rgmii_clk_src = { + .cmd_rcgr = 0x601c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_emac_rgmii_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_emac_rgmii_clk_src", + .parent_data = gcc_parents_5, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parents_1, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parents_1, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parents_1, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0x6b02c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk_src", + .parent_data = gcc_parents_2, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_1_aux_clk_src = { + .cmd_rcgr = 0x8d02c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_aux_clk_src", + .parent_data = gcc_parents_2, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_phy_refgen_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { + .cmd_rcgr = 0x6f014, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_refgen_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qspi_core_clk_src = { + .cmd_rcgr = 0x4b008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qspi_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0), + F(128000000, P_GPLL0_OUT_MAIN, 1, 16, 75), + { } +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x17148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x17278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x173a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x174d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x17608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x17738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { + .cmd_rcgr = 0x17868, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { + .cmd_rcgr = 0x17998, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { + .cmd_rcgr = 0x183a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x184d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x18608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { + .cmd_rcgr = 0x1e148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s0_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { + .cmd_rcgr = 0x1e278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s1_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { + .cmd_rcgr = 0x1e3a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s2_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { + .cmd_rcgr = 0x1e4d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s3_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { + .cmd_rcgr = 0x1e608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s4_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { + .cmd_rcgr = 0x1e738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s5_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1400c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parents_6, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2), + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x1600c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parents_3, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_tsif_ref_clk_src[] = { + F(105495, P_BI_TCXO, 2, 1, 91), + { } +}; + +static struct clk_rcg2 gcc_tsif_ref_clk_src = { + .cmd_rcgr = 0x36010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_tsif_ref_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ref_clk_src", + .parent_data = gcc_parents_7, + .num_parents = 5, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_axi_clk_src = { + .cmd_rcgr = 0x75020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_axi_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_ice_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_ice_core_clk_src = { + .cmd_rcgr = 0x75060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ice_core_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_phy_aux_clk_src = { + .cmd_rcgr = 0x75094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_clk_src", + .parent_data = gcc_parents_4, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_card_unipro_core_clk_src = { + .cmd_rcgr = 0x75078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_unipro_core_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x77060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x77094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parents_4, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x77078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(33333333, P_GPLL0_OUT_EVEN, 9, 0, 0), + F(66666667, P_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0xf01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_EVEN, 15, 0, 0), + F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0xf034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_sec_master_clk_src = { + .cmd_rcgr = 0x1001c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_master_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = { + .cmd_rcgr = 0x10034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_mock_utmi_clk_src", + .parent_data = gcc_parents_0, + .num_parents = 4, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0xf060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parents_2, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { + .cmd_rcgr = 0x10060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_ufs_card_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_aux_clk_src", + .parent_data = gcc_parents_2, + .num_parents = 3, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_tbu_clk = { + .halt_reg = 0x90018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_noc_pcie_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_card_axi_clk = { + .halt_reg = 0x750c0, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x750c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x750c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_card_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_card_axi_hw_ctl_clk = { + .halt_reg = 0x750c0, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x750c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x750c0, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_card_axi_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_aggre_ufs_card_axi_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x770c0, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x770c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_hw_ctl_clk = { + .halt_reg = 0x770c0, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x770c0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770c0, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_ufs_phy_axi_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_aggre_ufs_phy_axi_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0xf07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_prim_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_sec_axi_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1007c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre_usb3_sec_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_sec_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* + * Clock ON depends on external parent 'config noc', so cant poll + * delay and also mark as crtitical for camss boot + */ +static struct clk_branch gcc_camera_ahb_clk = { + .halt_reg = 0xb008, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xb008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0xb030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_sf_axi_clk = { + .halt_reg = 0xb034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* XO critical input to camss, so no need to poll */ +static struct clk_branch gcc_camera_xo_clk = { + .halt_reg = 0xb044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_xo_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0xf078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_prim_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_sec_axi_clk = { + .halt_reg = 0x10078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_sec_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_sec_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_ahb_clk = { + .halt_reg = 0x48000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_cpuss_ahb_clk_src.clkr.hw }, + .num_parents = 1, + /* required for cpuss */ + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_dvm_bus_clk = { + .halt_reg = 0x48190, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48190, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_dvm_bus_clk", + /* required for cpuss */ + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_gnoc_clk = { + .halt_reg = 0x48004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x48004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_gnoc_clk", + /* required for cpuss */ + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_rbcpr_clk = { + .halt_reg = 0x48008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x48008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_rbcpr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_gpu_axi_clk = { + .halt_reg = 0x71154, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x71154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ddrss_gpu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* + * Clock ON depends on external parent 'config noc', so cant poll + * delay and also mark as crtitical for disp boot + */ +static struct clk_branch gcc_disp_ahb_clk = { + .halt_reg = 0xb00c, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xb00c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0xb038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_sf_axi_clk = { + .halt_reg = 0xb03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* XO critical input to disp, so no need to poll */ +static struct clk_branch gcc_disp_xo_clk = { + .halt_reg = 0xb048, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_xo_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_axi_clk = { + .halt_reg = 0x6010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_emac_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_ptp_clk = { + .halt_reg = 0x6034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_emac_ptp_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_emac_ptp_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_rgmii_clk = { + .halt_reg = 0x6018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_emac_rgmii_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_emac_rgmii_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_emac_slv_ahb_clk = { + .halt_reg = 0x6014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x6014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x6014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_emac_slv_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_gp1_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_gp2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_gp3_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_cfg_ahb_clk = { + .halt_reg = 0x71004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x71004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_cfg_ahb_clk", + /* required for gpu */ + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_iref_clk = { + .halt_reg = 0x8c010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_iref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x7100c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x7100c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x71018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x71018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_at_clk = { + .halt_reg = 0x4d010, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4d010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_at_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_axi_clk = { + .halt_reg = 0x4d008, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_cfg_ahb_clk = { + .halt_reg = 0x4d004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x4d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x4d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_cfg_ahb_clk", + /* required for npu */ + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_trig_clk = { + .halt_reg = 0x4d00c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4d00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_trig_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie0_phy_refgen_clk = { + .halt_reg = 0x6f02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie0_phy_refgen_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_pcie_phy_refgen_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie1_phy_refgen_clk = { + .halt_reg = 0x6f030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie1_phy_refgen_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_pcie_phy_refgen_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x6b020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_pcie_0_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x6b01c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_clkref_clk = { + .halt_reg = 0x8c00c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* Clock ON depends on external parent 'PIPE' clock, so dont poll */ +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b024, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { + .halt_reg = 0x6b010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_0_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_aux_clk = { + .halt_reg = 0x8d020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(29), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_pcie_1_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { + .halt_reg = 0x8d01c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8d01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(28), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_clkref_clk = { + .halt_reg = 0x8c02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_mstr_axi_clk = { + .halt_reg = 0x8d018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* Clock ON depends on external parent 'PIPE' clock, so dont poll */ +static struct clk_branch gcc_pcie_1_pipe_clk = { + .halt_reg = 0x8d024, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(30), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_axi_clk = { + .halt_reg = 0x8d014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8d014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_1_slv_q2a_axi_clk = { + .halt_reg = 0x8d010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_1_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_phy_aux_clk = { + .halt_reg = 0x6f004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6f004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_phy_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_pcie_0_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_pdm2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x34004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0xb018, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0xb01c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_ahb_clk = { + .halt_reg = 0xb020, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_disp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cvp_ahb_clk = { + .halt_reg = 0xb010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_video_cvp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0xb014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0xb014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = { + .halt_reg = 0x4b000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_cnoc_periph_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_core_clk = { + .halt_reg = 0x4b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qspi_core_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x17144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s0_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x17274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s1_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x173a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x174d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s3_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x17604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s4_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x17734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s5_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s6_clk = { + .halt_reg = 0x17864, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s6_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s6_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s7_clk = { + .halt_reg = 0x17994, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s7_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap0_s7_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x18144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap1_s0_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x18274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap1_s1_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x183a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap1_s2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x184d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap1_s3_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x18604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap1_s4_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x18734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap1_s5_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s0_clk = { + .halt_reg = 0x1e144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s0_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap2_s0_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s1_clk = { + .halt_reg = 0x1e274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s1_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap2_s1_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s2_clk = { + .halt_reg = 0x1e3a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s2_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap2_s2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s3_clk = { + .halt_reg = 0x1e4d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s3_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap2_s3_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s4_clk = { + .halt_reg = 0x1e604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s4_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap2_s4_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s5_clk = { + .halt_reg = 0x1e734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap2_s5_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_qupv3_wrap2_s5_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x18008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x18008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_2_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = { + .halt_reg = 0x1e008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1e008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52014, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_2_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_sdcc2_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x16008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc4_apps_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_sdcc4_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { + .halt_reg = 0x4819c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_cpuss_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_cpuss_ahb_clk_src.clkr.hw }, + .num_parents = 1, + /* required for cpuss */ + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ahb_clk = { + .halt_reg = 0x36004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_inactivity_timers_clk = { + .halt_reg = 0x3600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_inactivity_timers_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_tsif_ref_clk = { + .halt_reg = 0x36008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tsif_ref_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_tsif_ref_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_ahb_clk = { + .halt_reg = 0x75014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_axi_clk = { + .halt_reg = 0x75010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_axi_hw_ctl_clk = { + .halt_reg = 0x75010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75010, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_axi_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_axi_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_clkref_clk = { + .halt_reg = 0x8c004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_ice_core_clk = { + .halt_reg = 0x7505c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7505c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7505c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ice_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_ice_core_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_ice_core_hw_ctl_clk = { + .halt_reg = 0x7505c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7505c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7505c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_ice_core_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_ice_core_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_phy_aux_clk = { + .halt_reg = 0x75090, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_phy_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_phy_aux_hw_ctl_clk = { + .halt_reg = 0x75090, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75090, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_phy_aux_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_phy_aux_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_unipro_core_clk = { + .halt_reg = 0x75058, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75058, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_unipro_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_unipro_core_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_card_unipro_core_hw_ctl_clk = { + .halt_reg = 0x75058, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x75058, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x75058, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_unipro_core_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_card_unipro_core_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_mem_clkref_clk = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_mem_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_axi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_hw_ctl_clk = { + .halt_reg = 0x77010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77010, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_axi_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x7705c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7705c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7705c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_ice_core_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_hw_ctl_clk = { + .halt_reg = 0x7705c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x7705c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7705c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_ice_core_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x77090, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_phy_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = { + .halt_reg = 0x77090, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77090, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_phy_aux_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x77058, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77058, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_unipro_core_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_hw_ctl_clk = { + .halt_reg = 0x77058, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x77058, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77058, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_hw_ctl_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_ufs_phy_unipro_core_clk.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch_simple_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0xf010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_prim_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0xf018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0xf014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_master_clk = { + .halt_reg = 0x10010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_master_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_sec_master_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_mock_utmi_clk = { + .halt_reg = 0x10018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_mock_utmi_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb30_sec_mock_utmi_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_sec_sleep_clk = { + .halt_reg = 0x10014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_sec_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_clk = { + .halt_reg = 0x8c008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0xf050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0xf054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xf054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_clkref_clk = { + .halt_reg = 0x8c028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_aux_clk = { + .halt_reg = 0x10050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb3_sec_phy_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { + .halt_reg = 0x10054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sec_phy_com_aux_clk", + .parent_hws = (const struct clk_hw *[]){ + &gcc_usb3_sec_phy_aux_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +/* + * Clock ON depends on external parent 'config noc', so cant poll + * delay and also mark as crtitical for video boot + */ +static struct clk_branch gcc_video_ahb_clk = { + .halt_reg = 0xb004, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0xb004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0xb004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0xb024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi1_clk = { + .halt_reg = 0xb028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axic_clk = { + .halt_reg = 0xb02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axic_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* XO critical input to video, so no need to poll */ +static struct clk_branch gcc_video_xo_clk = { + .halt_reg = 0xb040, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_xo_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *gcc_sm8150_clocks[] = { + [GCC_AGGRE_NOC_PCIE_TBU_CLK] = &gcc_aggre_noc_pcie_tbu_clk.clkr, + [GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr, + [GCC_AGGRE_UFS_CARD_AXI_HW_CTL_CLK] = + &gcc_aggre_ufs_card_axi_hw_ctl_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK] = + &gcc_aggre_ufs_phy_axi_hw_ctl_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, + [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr, + [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr, + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, + [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, + [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, + [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, + [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, + [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_SF_AXI_CLK] = &gcc_disp_sf_axi_clk.clkr, + [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, + [GCC_EMAC_AXI_CLK] = &gcc_emac_axi_clk.clkr, + [GCC_EMAC_PTP_CLK] = &gcc_emac_ptp_clk.clkr, + [GCC_EMAC_PTP_CLK_SRC] = &gcc_emac_ptp_clk_src.clkr, + [GCC_EMAC_RGMII_CLK] = &gcc_emac_rgmii_clk.clkr, + [GCC_EMAC_RGMII_CLK_SRC] = &gcc_emac_rgmii_clk_src.clkr, + [GCC_EMAC_SLV_AHB_CLK] = &gcc_emac_slv_ahb_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, + [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_NPU_AT_CLK] = &gcc_npu_at_clk.clkr, + [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr, + [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr, + [GCC_NPU_TRIG_CLK] = &gcc_npu_trig_clk.clkr, + [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr, + [GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr, + [GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr, + [GCC_PCIE_1_AUX_CLK_SRC] = &gcc_pcie_1_aux_clk_src.clkr, + [GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr, + [GCC_PCIE_1_CLKREF_CLK] = &gcc_pcie_1_clkref_clk.clkr, + [GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr, + [GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr, + [GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr, + [GCC_PCIE_1_SLV_Q2A_AXI_CLK] = &gcc_pcie_1_slv_q2a_axi_clk.clkr, + [GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.clkr, + [GCC_PCIE_PHY_REFGEN_CLK_SRC] = &gcc_pcie_phy_refgen_clk_src.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, + [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, + [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr, + [GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr, + [GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr, + [GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr, + [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr, + [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr, + [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr, + [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr, + [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr, + [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr, + [GCC_QUPV3_WRAP2_S5_CLK] = &gcc_qupv3_wrap2_s5_clk.clkr, + [GCC_QUPV3_WRAP2_S5_CLK_SRC] = &gcc_qupv3_wrap2_s5_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, + [GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr, + [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr, + [GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr, + [GCC_TSIF_REF_CLK_SRC] = &gcc_tsif_ref_clk_src.clkr, + [GCC_UFS_CARD_AHB_CLK] = &gcc_ufs_card_ahb_clk.clkr, + [GCC_UFS_CARD_AXI_CLK] = &gcc_ufs_card_axi_clk.clkr, + [GCC_UFS_CARD_AXI_CLK_SRC] = &gcc_ufs_card_axi_clk_src.clkr, + [GCC_UFS_CARD_AXI_HW_CTL_CLK] = &gcc_ufs_card_axi_hw_ctl_clk.clkr, + [GCC_UFS_CARD_CLKREF_CLK] = &gcc_ufs_card_clkref_clk.clkr, + [GCC_UFS_CARD_ICE_CORE_CLK] = &gcc_ufs_card_ice_core_clk.clkr, + [GCC_UFS_CARD_ICE_CORE_CLK_SRC] = &gcc_ufs_card_ice_core_clk_src.clkr, + [GCC_UFS_CARD_ICE_CORE_HW_CTL_CLK] = + &gcc_ufs_card_ice_core_hw_ctl_clk.clkr, + [GCC_UFS_CARD_PHY_AUX_CLK] = &gcc_ufs_card_phy_aux_clk.clkr, + [GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr, + [GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK] = + &gcc_ufs_card_phy_aux_hw_ctl_clk.clkr, + [GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr, + [GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_card_unipro_core_clk_src.clkr, + [GCC_UFS_CARD_UNIPRO_CORE_HW_CTL_CLK] = + &gcc_ufs_card_unipro_core_hw_ctl_clk.clkr, + [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_AXI_HW_CTL_CLK] = &gcc_ufs_phy_axi_hw_ctl_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK] = + &gcc_ufs_phy_ice_core_hw_ctl_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK] = + &gcc_ufs_phy_unipro_core_hw_ctl_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB30_SEC_MASTER_CLK] = &gcc_usb30_sec_master_clk.clkr, + [GCC_USB30_SEC_MASTER_CLK_SRC] = &gcc_usb30_sec_master_clk_src.clkr, + [GCC_USB30_SEC_MOCK_UTMI_CLK] = &gcc_usb30_sec_mock_utmi_clk.clkr, + [GCC_USB30_SEC_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_sec_mock_utmi_clk_src.clkr, + [GCC_USB30_SEC_SLEEP_CLK] = &gcc_usb30_sec_sleep_clk.clkr, + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_SEC_CLKREF_CLK] = &gcc_usb3_sec_clkref_clk.clkr, + [GCC_USB3_SEC_PHY_AUX_CLK] = &gcc_usb3_sec_phy_aux_clk.clkr, + [GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &gcc_usb3_sec_phy_aux_clk_src.clkr, + [GCC_USB3_SEC_PHY_COM_AUX_CLK] = &gcc_usb3_sec_phy_com_aux_clk.clkr, + [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_VIDEO_AXIC_CLK] = &gcc_video_axic_clk.clkr, + [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, + [GPLL0] = &gpll0.clkr, + [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, + [GPLL7] = &gpll7.clkr, + [GPLL9] = &gpll9.clkr, +}; + +static const struct qcom_reset_map gcc_sm8150_resets[] = { + [GCC_EMAC_BCR] = { 0x6000 }, + [GCC_GPU_BCR] = { 0x71000 }, + [GCC_MMSS_BCR] = { 0xb000 }, + [GCC_NPU_BCR] = { 0x4d000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_1_BCR] = { 0x8d000 }, + [GCC_PCIE_1_PHY_BCR] = { 0x8e01c }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_PRNG_BCR] = { 0x34000 }, + [GCC_QSPI_BCR] = { 0x24008 }, + [GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_TSIF_BCR] = { 0x36000 }, + [GCC_UFS_CARD_BCR] = { 0x75000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB30_SEC_BCR] = { 0x10000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, +}; + +static const struct regmap_config gcc_sm8150_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x9c040, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sm8150_desc = { + .config = &gcc_sm8150_regmap_config, + .clks = gcc_sm8150_clocks, + .num_clks = ARRAY_SIZE(gcc_sm8150_clocks), + .resets = gcc_sm8150_resets, + .num_resets = ARRAY_SIZE(gcc_sm8150_resets), +}; + +static const struct of_device_id gcc_sm8150_match_table[] = { + { .compatible = "qcom,gcc-sm8150" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sm8150_match_table); + +static int gcc_sm8150_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_sm8150_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Disable the GPLL0 active input to NPU and GPU via MISC registers */ + regmap_update_bits(regmap, 0x4d110, 0x3, 0x3); + regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + + return qcom_cc_really_probe(pdev, &gcc_sm8150_desc, regmap); +} + +static struct platform_driver gcc_sm8150_driver = { + .probe = gcc_sm8150_probe, + .driver = { + .name = "gcc-sm8150", + .of_match_table = gcc_sm8150_match_table, + }, +}; + +static int __init gcc_sm8150_init(void) +{ + return platform_driver_register(&gcc_sm8150_driver); +} +subsys_initcall(gcc_sm8150_init); + +static void __exit gcc_sm8150_exit(void) +{ + platform_driver_unregister(&gcc_sm8150_driver); +} +module_exit(gcc_sm8150_exit); + +MODULE_DESCRIPTION("QTI GCC SM8150 Driver"); +MODULE_LICENSE("GPL v2"); From 56bf8740ff475c118fd6e9e623020cde0d2cc001 Mon Sep 17 00:00:00 2001 From: Marc Gonzalez Date: Thu, 13 Jun 2019 17:09:34 +0200 Subject: [PATCH 20/62] clk: qcom: msm8916: Don't build by default QCOM_A53PLL and QCOM_CLK_APCS_MSM8916 stand out as the only options built by default. Let's bring them back in line with the rest. Signed-off-by: Marc Gonzalez Link: https://lkml.kernel.org/r/d654907d-a3a2-a00f-d6f5-3a34ae25ebcf@free.fr Reviewed-by: Bjorn Andersson Acked-by: Georgi Djakov Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 73cf0e916ea0..32dbb4f09492 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -21,7 +21,6 @@ if COMMON_CLK_QCOM config QCOM_A53PLL tristate "MSM8916 A53 PLL" - default ARCH_QCOM help Support for the A53 PLL on MSM8916 devices. It provides the CPU with frequencies above 1GHz. @@ -31,7 +30,6 @@ config QCOM_A53PLL config QCOM_CLK_APCS_MSM8916 tristate "MSM8916 APCS Clock Controller" depends on QCOM_APCS_IPC || COMPILE_TEST - default ARCH_QCOM help Support for the APCS Clock Controller on msm8916 devices. The APCS is managing the mux and divider which feeds the CPUs. From 7d0c76bdf227774154e191636be739d7dc0247ba Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 26 Jul 2019 14:53:26 +0530 Subject: [PATCH 21/62] clk: qcom: Add WCSS gcc clock control for QCS404 Add support for the WCSS QDSP gcc clock control used on qcs404 based devices. This would allow wcss remoteproc driver to control the required gcc clocks to bring the subsystem out of reset. Signed-off-by: Govind Singh Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-qcs404.c | 30 +++++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-qcs404.h | 3 +++ 2 files changed, 33 insertions(+) diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index 29cf464dd2c8..e12c04c09a6a 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -2604,6 +2604,32 @@ static struct clk_branch gcc_usb_hs_system_clk = { }, }; +static struct clk_branch gcc_wdsp_q6ss_ahbs_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wdsp_q6ss_ahbs_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_wdsp_q6ss_axim_clk = { + .halt_reg = 0x1e008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wdsp_q6ss_axim_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_hw *gcc_qcs404_hws[] = { &cxo.hw, }; @@ -2749,6 +2775,9 @@ static struct clk_regmap *gcc_qcs404_clocks[] = { [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, [GCC_DCC_XO_CLK] = &gcc_dcc_xo_clk.clkr, + [GCC_WCSS_Q6_AHB_CLK] = &gcc_wdsp_q6ss_ahbs_clk.clkr, + [GCC_WCSS_Q6_AXIM_CLK] = &gcc_wdsp_q6ss_axim_clk.clkr, + }; static const struct qcom_reset_map gcc_qcs404_resets[] = { @@ -2774,6 +2803,7 @@ static const struct qcom_reset_map gcc_qcs404_resets[] = { [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, [GCC_EMAC_BCR] = { 0x4e000 }, + [GCC_WDSP_RESTART] = {0x19000}, }; static const struct regmap_config gcc_qcs404_regmap_config = { diff --git a/include/dt-bindings/clock/qcom,gcc-qcs404.h b/include/dt-bindings/clock/qcom,gcc-qcs404.h index 2cd62c98561f..bc3051543347 100644 --- a/include/dt-bindings/clock/qcom,gcc-qcs404.h +++ b/include/dt-bindings/clock/qcom,gcc-qcs404.h @@ -146,6 +146,8 @@ #define GCC_MDP_TBU_CLK 138 #define GCC_QDSS_DAP_CLK 139 #define GCC_DCC_XO_CLK 140 +#define GCC_WCSS_Q6_AHB_CLK 141 +#define GCC_WCSS_Q6_AXIM_CLK 142 #define GCC_CDSP_CFG_AHB_CLK 143 #define GCC_BIMC_CDSP_CLK 144 #define GCC_CDSP_TBU_CLK 145 @@ -173,5 +175,6 @@ #define GCC_PCIE_0_CORE_STICKY_ARES 19 #define GCC_PCIE_0_SLEEP_ARES 20 #define GCC_PCIE_0_PIPE_ARES 21 +#define GCC_WDSP_RESTART 22 #endif From 64ebb57a3df6c7126532f8acd22b0612867ad3e0 Mon Sep 17 00:00:00 2001 From: "yong.liang" Date: Fri, 26 Jul 2019 15:01:35 +0800 Subject: [PATCH 22/62] clk: reset: Modify reset-controller driver Set reset signal by a register and clear reset signal by another register for 8183. Signed-off-by: yong.liang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt8183.c | 16 +++- drivers/clk/mediatek/clk-mtk.h | 3 + drivers/clk/mediatek/reset.c | 56 ++++++++++++- .../reset-controller/mt8183-resets.h | 81 +++++++++++++++++++ 4 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 include/dt-bindings/reset-controller/mt8183-resets.h diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c index 1aa5f4059251..94bbadc0d259 100644 --- a/drivers/clk/mediatek/clk-mt8183.c +++ b/drivers/clk/mediatek/clk-mt8183.c @@ -17,6 +17,9 @@ #include +/* Infra global controller reset set register */ +#define INFRA_RST0_SET_OFFSET 0x120 + static DEFINE_SPINLOCK(mt8183_clk_lock); static const struct mtk_fixed_clk top_fixed_clks[] = { @@ -1185,13 +1188,24 @@ static int clk_mt8183_infra_probe(struct platform_device *pdev) { struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; + int r; clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data); - return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) { + dev_err(&pdev->dev, + "%s(): could not register clock provider: %d\n", + __func__, r); + return r; + } + + mtk_register_reset_controller_set_clr(node, 4, INFRA_RST0_SET_OFFSET); + + return r; } static int clk_mt8183_mcu_probe(struct platform_device *pdev) diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 733a11d1de94..2e9e26084798 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -240,4 +240,7 @@ struct clk *mtk_clk_register_ref2usb_tx(const char *name, void mtk_register_reset_controller(struct device_node *np, unsigned int num_regs, int regofs); +void mtk_register_reset_controller_set_clr(struct device_node *np, + unsigned int num_regs, int regofs); + #endif /* __DRV_CLK_MTK_H */ diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index d8376b92349e..cb939c071b0c 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -19,6 +19,24 @@ struct mtk_reset { struct reset_controller_dev rcdev; }; +static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); + unsigned int reg = data->regofs + ((id / 32) << 4); + + return regmap_write(data->regmap, reg, 1); +} + +static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); + unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4; + + return regmap_write(data->regmap, reg, 1); +} + static int mtk_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { @@ -49,14 +67,32 @@ static int mtk_reset(struct reset_controller_dev *rcdev, return mtk_reset_deassert(rcdev, id); } +static int mtk_reset_set_clr(struct reset_controller_dev *rcdev, + unsigned long id) +{ + int ret; + + ret = mtk_reset_assert_set_clr(rcdev, id); + if (ret) + return ret; + return mtk_reset_deassert_set_clr(rcdev, id); +} + static const struct reset_control_ops mtk_reset_ops = { .assert = mtk_reset_assert, .deassert = mtk_reset_deassert, .reset = mtk_reset, }; -void mtk_register_reset_controller(struct device_node *np, - unsigned int num_regs, int regofs) +static const struct reset_control_ops mtk_reset_ops_set_clr = { + .assert = mtk_reset_assert_set_clr, + .deassert = mtk_reset_deassert_set_clr, + .reset = mtk_reset_set_clr, +}; + +static void mtk_register_reset_controller_common(struct device_node *np, + unsigned int num_regs, int regofs, + const struct reset_control_ops *reset_ops) { struct mtk_reset *data; int ret; @@ -77,7 +113,7 @@ void mtk_register_reset_controller(struct device_node *np, data->regofs = regofs; data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = num_regs * 32; - data->rcdev.ops = &mtk_reset_ops; + data->rcdev.ops = reset_ops; data->rcdev.of_node = np; ret = reset_controller_register(&data->rcdev); @@ -87,3 +123,17 @@ void mtk_register_reset_controller(struct device_node *np, return; } } + +void mtk_register_reset_controller(struct device_node *np, + unsigned int num_regs, int regofs) +{ + mtk_register_reset_controller_common(np, num_regs, regofs, + &mtk_reset_ops); +} + +void mtk_register_reset_controller_set_clr(struct device_node *np, + unsigned int num_regs, int regofs) +{ + mtk_register_reset_controller_common(np, num_regs, regofs, + &mtk_reset_ops_set_clr); +} diff --git a/include/dt-bindings/reset-controller/mt8183-resets.h b/include/dt-bindings/reset-controller/mt8183-resets.h new file mode 100644 index 000000000000..8804e34ebdd4 --- /dev/null +++ b/include/dt-bindings/reset-controller/mt8183-resets.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Yong Liang + */ + +#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8183 +#define _DT_BINDINGS_RESET_CONTROLLER_MT8183 + +/* INFRACFG AO resets */ +#define MT8183_INFRACFG_AO_THERM_SW_RST 0 +#define MT8183_INFRACFG_AO_USB_TOP_SW_RST 1 +#define MT8183_INFRACFG_AO_MM_IOMMU_SW_RST 3 +#define MT8183_INFRACFG_AO_MSDC3_SW_RST 4 +#define MT8183_INFRACFG_AO_MSDC2_SW_RST 5 +#define MT8183_INFRACFG_AO_MSDC1_SW_RST 6 +#define MT8183_INFRACFG_AO_MSDC0_SW_RST 7 +#define MT8183_INFRACFG_AO_APDMA_SW_RST 9 +#define MT8183_INFRACFG_AO_MIMP_D_SW_RST 10 +#define MT8183_INFRACFG_AO_BTIF_SW_RST 12 +#define MT8183_INFRACFG_AO_DISP_PWM_SW_RST 14 +#define MT8183_INFRACFG_AO_AUXADC_SW_RST 15 + +#define MT8183_INFRACFG_AO_IRTX_SW_RST 32 +#define MT8183_INFRACFG_AO_SPI0_SW_RST 33 +#define MT8183_INFRACFG_AO_I2C0_SW_RST 34 +#define MT8183_INFRACFG_AO_I2C1_SW_RST 35 +#define MT8183_INFRACFG_AO_I2C2_SW_RST 36 +#define MT8183_INFRACFG_AO_I2C3_SW_RST 37 +#define MT8183_INFRACFG_AO_UART0_SW_RST 38 +#define MT8183_INFRACFG_AO_UART1_SW_RST 39 +#define MT8183_INFRACFG_AO_UART2_SW_RST 40 +#define MT8183_INFRACFG_AO_PWM_SW_RST 41 +#define MT8183_INFRACFG_AO_SPI1_SW_RST 42 +#define MT8183_INFRACFG_AO_I2C4_SW_RST 43 +#define MT8183_INFRACFG_AO_DVFSP_SW_RST 44 +#define MT8183_INFRACFG_AO_SPI2_SW_RST 45 +#define MT8183_INFRACFG_AO_SPI3_SW_RST 46 +#define MT8183_INFRACFG_AO_UFSHCI_SW_RST 47 + +#define MT8183_INFRACFG_AO_PMIC_WRAP_SW_RST 64 +#define MT8183_INFRACFG_AO_SPM_SW_RST 65 +#define MT8183_INFRACFG_AO_USBSIF_SW_RST 66 +#define MT8183_INFRACFG_AO_KP_SW_RST 68 +#define MT8183_INFRACFG_AO_APXGPT_SW_RST 69 +#define MT8183_INFRACFG_AO_CLDMA_AO_SW_RST 70 +#define MT8183_INFRACFG_AO_UNIPRO_UFS_SW_RST 71 +#define MT8183_INFRACFG_AO_DX_CC_SW_RST 72 +#define MT8183_INFRACFG_AO_UFSPHY_SW_RST 73 + +#define MT8183_INFRACFG_AO_DX_CC_SEC_SW_RST 96 +#define MT8183_INFRACFG_AO_GCE_SW_RST 97 +#define MT8183_INFRACFG_AO_CLDMA_SW_RST 98 +#define MT8183_INFRACFG_AO_TRNG_SW_RST 99 +#define MT8183_INFRACFG_AO_AP_MD_CCIF_1_SW_RST 103 +#define MT8183_INFRACFG_AO_AP_MD_CCIF_SW_RST 104 +#define MT8183_INFRACFG_AO_I2C1_IMM_SW_RST 105 +#define MT8183_INFRACFG_AO_I2C1_ARB_SW_RST 106 +#define MT8183_INFRACFG_AO_I2C2_IMM_SW_RST 107 +#define MT8183_INFRACFG_AO_I2C2_ARB_SW_RST 108 +#define MT8183_INFRACFG_AO_I2C5_SW_RST 109 +#define MT8183_INFRACFG_AO_I2C5_IMM_SW_RST 110 +#define MT8183_INFRACFG_AO_I2C5_ARB_SW_RST 111 +#define MT8183_INFRACFG_AO_SPI4_SW_RST 112 +#define MT8183_INFRACFG_AO_SPI5_SW_RST 113 +#define MT8183_INFRACFG_AO_INFRA2MFGAXI_CBIP_CLAS_SW_RST 114 +#define MT8183_INFRACFG_AO_MFGAXI2INFRA_M0_CBIP_GLAS_OUT_SW_RST 115 +#define MT8183_INFRACFG_AO_MFGAXI2INFRA_M1_CBIP_GLAS_OUT_SW_RST 116 +#define MT8183_INFRACFG_AO_UFS_AES_SW_RST 117 +#define MT8183_INFRACFG_AO_CCU_I2C_IRQ_SW_RST 118 +#define MT8183_INFRACFG_AO_CCU_I2C_DMA_SW_RST 119 +#define MT8183_INFRACFG_AO_I2C6_SW_RST 120 +#define MT8183_INFRACFG_AO_CCU_GALS_SW_RST 121 +#define MT8183_INFRACFG_AO_IPU_GALS_SW_RST 122 +#define MT8183_INFRACFG_AO_CONN2AP_GALS_SW_RST 123 +#define MT8183_INFRACFG_AO_AP_MD_CCIF2_SW_RST 124 +#define MT8183_INFRACFG_AO_AP_MD_CCIF3_SW_RST 125 +#define MT8183_INFRACFG_AO_I2C7_SW_RST 126 +#define MT8183_INFRACFG_AO_I2C8_SW_RST 127 + +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8183 */ From 75e0a1e301913b2b5627a69818f2521f48e6be07 Mon Sep 17 00:00:00 2001 From: Govind Singh Date: Fri, 26 Jul 2019 14:53:28 +0530 Subject: [PATCH 23/62] clk: qcom: define probe by index API as common API Extend the probe by index API in common code to be used by other qcom clock controller. Signed-off-by: Govind Singh Signed-off-by: Stephen Boyd --- drivers/clk/qcom/common.c | 20 ++++++++++++++++++++ drivers/clk/qcom/common.h | 2 ++ drivers/clk/qcom/lpasscc-sdm845.c | 23 ++--------------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index a6b2f86112d8..28ddc747d703 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -306,4 +306,24 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc) } EXPORT_SYMBOL_GPL(qcom_cc_probe); +int qcom_cc_probe_by_index(struct platform_device *pdev, int index, + const struct qcom_cc_desc *desc) +{ + struct regmap *regmap; + struct resource *res; + void __iomem *base; + + res = platform_get_resource(pdev, IORESOURCE_MEM, index); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return -ENOMEM; + + regmap = devm_regmap_init_mmio(&pdev->dev, base, desc->config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return qcom_cc_really_probe(pdev, desc, regmap); +} +EXPORT_SYMBOL_GPL(qcom_cc_probe_by_index); + MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 1e2a8bdac55a..bb39a7e106d8 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -61,5 +61,7 @@ extern int qcom_cc_really_probe(struct platform_device *pdev, struct regmap *regmap); extern int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc); +extern int qcom_cc_probe_by_index(struct platform_device *pdev, int index, + const struct qcom_cc_desc *desc); #endif diff --git a/drivers/clk/qcom/lpasscc-sdm845.c b/drivers/clk/qcom/lpasscc-sdm845.c index e246b99dfbc6..56d3e9928892 100644 --- a/drivers/clk/qcom/lpasscc-sdm845.c +++ b/drivers/clk/qcom/lpasscc-sdm845.c @@ -112,25 +112,6 @@ static const struct qcom_cc_desc lpass_qdsp6ss_sdm845_desc = { .num_clks = ARRAY_SIZE(lpass_qdsp6ss_sdm845_clocks), }; -static int lpass_clocks_sdm845_probe(struct platform_device *pdev, int index, - const struct qcom_cc_desc *desc) -{ - struct regmap *regmap; - struct resource *res; - void __iomem *base; - - res = platform_get_resource(pdev, IORESOURCE_MEM, index); - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); - - regmap = devm_regmap_init_mmio(&pdev->dev, base, desc->config); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - return qcom_cc_really_probe(pdev, desc, regmap); -} - static int lpass_cc_sdm845_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; @@ -139,14 +120,14 @@ static int lpass_cc_sdm845_probe(struct platform_device *pdev) lpass_regmap_config.name = "cc"; desc = &lpass_cc_sdm845_desc; - ret = lpass_clocks_sdm845_probe(pdev, 0, desc); + ret = qcom_cc_probe_by_index(pdev, 0, desc); if (ret) return ret; lpass_regmap_config.name = "qdsp6ss"; desc = &lpass_qdsp6ss_sdm845_desc; - return lpass_clocks_sdm845_probe(pdev, 1, desc); + return qcom_cc_probe_by_index(pdev, 1, desc); } static const struct of_device_id lpass_cc_sdm845_match_table[] = { From 096f4597406bc86cd93947eb0e96a8188f934ebf Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 10 Jul 2019 15:43:41 +0200 Subject: [PATCH 24/62] dt-bindings: ap806: add the cluster clock node in the syscon file Document the device tree binding for the cluster clock controllers found in the Armada 7K/8K SoCs. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/20190710134346.30239-2-gregory.clement@bootlin.com Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../arm/marvell/ap806-system-controller.txt | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt index 7b8b8eb0191f..4f21c1024073 100644 --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt @@ -21,8 +21,8 @@ Clocks: The Device Tree node representing the AP806 system controller provides a number of clocks: - - 0: clock of CPU cluster 0 - - 1: clock of CPU cluster 1 + - 0: reference clock of CPU cluster 0 + - 1: reference clock of CPU cluster 1 - 2: fixed PLL at 1200 Mhz - 3: MSS clock, derived from the fixed PLL @@ -143,3 +143,30 @@ ap_syscon1: system-controller@6f8000 { #thermal-sensor-cells = <1>; }; }; + +Cluster clocks: +--------------- + +Device Tree Clock bindings for cluster clock of AP806 Marvell. Each +cluster contain up to 2 CPUs running at the same frequency. + +Required properties: +- compatible: must be "marvell,ap806-cpu-clock"; +- #clock-cells : should be set to 1. + +- clocks : shall be the input parent clock(s) phandle for the clock + (one per cluster) + +- reg: register range associated with the cluster clocks + +ap_syscon1: system-controller@6f8000 { + compatible = "marvell,armada-ap806-syscon1", "syscon", "simple-mfd"; + reg = <0x6f8000 0x1000>; + + cpu_clk: clock-cpu@278 { + compatible = "marvell,ap806-cpu-clock"; + clocks = <&ap_clk 0>, <&ap_clk 1>; + #clock-cells = <1>; + reg = <0x278 0xa30>; + }; +}; From 33c0259092c805dc1cee9dd7bf66a955124702d9 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 10 Jul 2019 15:43:42 +0200 Subject: [PATCH 25/62] clk: mvebu: add helper file for Armada AP and CP clocks Clock drivers for Armada AP and Armada CP use the same function to generate unique clock name. A third drivers is coming with the same need, so it's time to move this function in a common file. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/20190710134346.30239-3-gregory.clement@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/Kconfig | 5 ++++ drivers/clk/mvebu/Makefile | 1 + drivers/clk/mvebu/ap806-system-controller.c | 24 ++++------------ drivers/clk/mvebu/armada_ap_cp_helper.c | 30 +++++++++++++++++++ drivers/clk/mvebu/armada_ap_cp_helper.h | 11 +++++++ drivers/clk/mvebu/cp110-system-controller.c | 32 ++++++--------------- 6 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 drivers/clk/mvebu/armada_ap_cp_helper.c create mode 100644 drivers/clk/mvebu/armada_ap_cp_helper.h diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index b09f6ded0a30..19f1b51ed15e 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -8,6 +8,9 @@ config MVEBU_CLK_CPU config MVEBU_CLK_COREDIV bool +config ARMADA_AP_CP_HELPER + bool + config ARMADA_370_CLK bool select MVEBU_CLK_COMMON @@ -35,9 +38,11 @@ config ARMADA_XP_CLK config ARMADA_AP806_SYSCON bool + select ARMADA_AP_CP_HELPER config ARMADA_CP110_SYSCON bool + select ARMADA_AP_CP_HELPER config DOVE_CLK bool diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 93ac3685271f..6638ad962ec1 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o +obj-$(CONFIG_ARMADA_AP_CP_HELPER) += armada_ap_cp_helper.o obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index ea54a874bbda..0a58824ff053 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -10,11 +10,11 @@ #define pr_fmt(fmt) "ap806-system-controller: " fmt +#include "armada_ap_cp_helper.h" #include #include #include #include -#include #include #include @@ -30,18 +30,6 @@ static struct clk_onecell_data ap806_clk_data = { .clk_num = AP806_CLK_NUM, }; -static char *ap806_unique_name(struct device *dev, struct device_node *np, - char *name) -{ - const __be32 *reg; - u64 addr; - - reg = of_get_property(np, "reg", NULL); - addr = of_translate_address(np, reg); - return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s", - (unsigned long long)addr, name); -} - static int ap806_syscon_common_probe(struct platform_device *pdev, struct device_node *syscon_node) { @@ -109,7 +97,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, cpuclk_freq *= 1000 * 1000; /* CPU clocks depend on the Sample At Reset configuration */ - name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0"); + name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-0"); ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL, 0, cpuclk_freq); if (IS_ERR(ap806_clks[0])) { @@ -117,7 +105,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, goto fail0; } - name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1"); + name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-1"); ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0, cpuclk_freq); if (IS_ERR(ap806_clks[1])) { @@ -126,7 +114,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, } /* Fixed clock is always 1200 Mhz */ - fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed"); + fixedclk_name = ap_cp_unique_name(dev, syscon_node, "fixed"); ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL, 0, 1200 * 1000 * 1000); if (IS_ERR(ap806_clks[2])) { @@ -135,7 +123,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, } /* MSS Clock is fixed clock divided by 6 */ - name = ap806_unique_name(dev, syscon_node, "mss"); + name = ap_cp_unique_name(dev, syscon_node, "mss"); ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name, 0, 1, 6); if (IS_ERR(ap806_clks[3])) { @@ -144,7 +132,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, } /* SDIO(/eMMC) Clock is fixed clock divided by 3 */ - name = ap806_unique_name(dev, syscon_node, "sdio"); + name = ap_cp_unique_name(dev, syscon_node, "sdio"); ap806_clks[4] = clk_register_fixed_factor(NULL, name, fixedclk_name, 0, 1, 3); diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.c b/drivers/clk/mvebu/armada_ap_cp_helper.c new file mode 100644 index 000000000000..6a930f697ee5 --- /dev/null +++ b/drivers/clk/mvebu/armada_ap_cp_helper.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Marvell Armada AP and CP110 helper + * + * Copyright (C) 2018 Marvell + * + * Gregory Clement + * + */ + +#include "armada_ap_cp_helper.h" +#include +#include +#include + +char *ap_cp_unique_name(struct device *dev, struct device_node *np, + const char *name) +{ + const __be32 *reg; + u64 addr; + + /* Do not create a name if there is no clock */ + if (!name) + return NULL; + + reg = of_get_property(np, "reg", NULL); + addr = of_translate_address(np, reg); + return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s", + (unsigned long long)addr, name); +} diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.h b/drivers/clk/mvebu/armada_ap_cp_helper.h new file mode 100644 index 000000000000..810af1e5dfa4 --- /dev/null +++ b/drivers/clk/mvebu/armada_ap_cp_helper.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __ARMADA_AP_CP_HELPER_H +#define __ARMADA_AP_CP_HELPER_H + +struct device; +struct device_node; + +char *ap_cp_unique_name(struct device *dev, struct device_node *np, + const char *name); +#endif diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index b6de283f45e3..808463276145 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -26,11 +26,11 @@ #define pr_fmt(fmt) "cp110-system-controller: " fmt +#include "armada_ap_cp_helper.h" #include #include #include #include -#include #include #include #include @@ -212,22 +212,6 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec, return ERR_PTR(-EINVAL); } -static char *cp110_unique_name(struct device *dev, struct device_node *np, - const char *name) -{ - const __be32 *reg; - u64 addr; - - /* Do not create a name if there is no clock */ - if (!name) - return NULL; - - reg = of_get_property(np, "reg", NULL); - addr = of_translate_address(np, reg); - return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s", - (unsigned long long)addr, name); -} - static int cp110_syscon_common_probe(struct platform_device *pdev, struct device_node *syscon_node) { @@ -261,7 +245,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, cp110_clk_data->num = CP110_CLK_NUM; /* Register the PLL0 which is the root of the hw tree */ - pll0_name = cp110_unique_name(dev, syscon_node, "pll0"); + pll0_name = ap_cp_unique_name(dev, syscon_node, "pll0"); hw = clk_hw_register_fixed_rate(NULL, pll0_name, NULL, 0, 1000 * 1000 * 1000); if (IS_ERR(hw)) { @@ -272,7 +256,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, cp110_clks[CP110_CORE_PLL0] = hw; /* PPv2 is PLL0/3 */ - ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core"); + ppv2_name = ap_cp_unique_name(dev, syscon_node, "ppv2-core"); hw = clk_hw_register_fixed_factor(NULL, ppv2_name, pll0_name, 0, 1, 3); if (IS_ERR(hw)) { ret = PTR_ERR(hw); @@ -282,7 +266,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, cp110_clks[CP110_CORE_PPV2] = hw; /* X2CORE clock is PLL0/2 */ - x2core_name = cp110_unique_name(dev, syscon_node, "x2core"); + x2core_name = ap_cp_unique_name(dev, syscon_node, "x2core"); hw = clk_hw_register_fixed_factor(NULL, x2core_name, pll0_name, 0, 1, 2); if (IS_ERR(hw)) { @@ -293,7 +277,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, cp110_clks[CP110_CORE_X2CORE] = hw; /* Core clock is X2CORE/2 */ - core_name = cp110_unique_name(dev, syscon_node, "core"); + core_name = ap_cp_unique_name(dev, syscon_node, "core"); hw = clk_hw_register_fixed_factor(NULL, core_name, x2core_name, 0, 1, 2); if (IS_ERR(hw)) { @@ -303,7 +287,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, cp110_clks[CP110_CORE_CORE] = hw; /* NAND can be either PLL0/2.5 or core clock */ - nand_name = cp110_unique_name(dev, syscon_node, "nand-core"); + nand_name = ap_cp_unique_name(dev, syscon_node, "nand-core"); if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK) hw = clk_hw_register_fixed_factor(NULL, nand_name, pll0_name, 0, 2, 5); @@ -318,7 +302,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, cp110_clks[CP110_CORE_NAND] = hw; /* SDIO clock is PLL0/2.5 */ - sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core"); + sdio_name = ap_cp_unique_name(dev, syscon_node, "sdio-core"); hw = clk_hw_register_fixed_factor(NULL, sdio_name, pll0_name, 0, 2, 5); if (IS_ERR(hw)) { @@ -330,7 +314,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev, /* create the unique name for all the gate clocks */ for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) - gate_name[i] = cp110_unique_name(dev, syscon_node, + gate_name[i] = ap_cp_unique_name(dev, syscon_node, gate_base_names[i]); for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) { From f756e362d938410a1143485cfcc44d7a8e6e3caf Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 10 Jul 2019 15:43:43 +0200 Subject: [PATCH 26/62] clk: mvebu: add CPU clock driver for Armada 7K/8K The CPU frequency is managed at the AP level for the Armada 7K/8K. The CPU frequency is modified by cluster: the CPUs of the same cluster have the same frequency. This patch adds the clock driver that will be used by CPUFreq, it is based on the work of Omri Itach . Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/20190710134346.30239-4-gregory.clement@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/Kconfig | 3 + drivers/clk/mvebu/Makefile | 1 + drivers/clk/mvebu/ap-cpu-clk.c | 259 +++++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 drivers/clk/mvebu/ap-cpu-clk.c diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 19f1b51ed15e..415e6906a113 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -40,6 +40,9 @@ config ARMADA_AP806_SYSCON bool select ARMADA_AP_CP_HELPER +config ARMADA_AP_CPU_CLK + bool + config ARMADA_CP110_SYSCON bool select ARMADA_AP_CP_HELPER diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 6638ad962ec1..04464cef0f06 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o mv98dx3236.o obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o +obj-$(CONFIG_ARMADA_AP_CPU_CLK) += ap-cpu-clk.o obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c new file mode 100644 index 000000000000..e4cecb456884 --- /dev/null +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -0,0 +1,259 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Marvell Armada AP CPU Clock Controller + * + * Copyright (C) 2018 Marvell + * + * Omri Itach + * Gregory Clement + */ + +#define pr_fmt(fmt) "ap-cpu-clk: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include "armada_ap_cp_helper.h" + +#define AP806_CPU_CLUSTER0 0 +#define AP806_CPU_CLUSTER1 1 +#define AP806_CPUS_PER_CLUSTER 2 +#define APN806_CPU1_MASK 0x1 + +#define APN806_CLUSTER_NUM_OFFSET 8 +#define APN806_CLUSTER_NUM_MASK BIT(APN806_CLUSTER_NUM_OFFSET) + +#define APN806_MAX_DIVIDER 32 + +/* AP806 CPU DFS register mapping*/ +#define AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET 0x278 +#define AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET 0x280 +#define AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET 0x284 +#define AP806_CA72MP2_0_PLL_SR_REG_OFFSET 0xC94 + +#define AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET 0x14 +#define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET 0 +#define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK \ + (0x3f << AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET) +#define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET 24 +#define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK \ + (0x1 << AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET) +#define AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET 16 +#define AP806_CA72MP2_0_PLL_RATIO_STATE 11 + +#define STATUS_POLL_PERIOD_US 1 +#define STATUS_POLL_TIMEOUT_US 1000000 + +#define to_ap_cpu_clk(_hw) container_of(_hw, struct ap_cpu_clk, hw) + +/* + * struct ap806_clk: CPU cluster clock controller instance + * @cluster: Cluster clock controller index + * @clk_name: Cluster clock controller name + * @dev : Cluster clock device + * @hw: HW specific structure of Cluster clock controller + * @pll_cr_base: CA72MP2 Register base (Device Sample at Reset register) + */ +struct ap_cpu_clk { + unsigned int cluster; + const char *clk_name; + struct device *dev; + struct clk_hw hw; + struct regmap *pll_cr_base; +}; + +static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ap_cpu_clk *clk = to_ap_cpu_clk(hw); + unsigned int cpu_clkdiv_reg; + int cpu_clkdiv_ratio; + + cpu_clkdiv_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET + + (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); + regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, &cpu_clkdiv_ratio); + cpu_clkdiv_ratio &= AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK; + cpu_clkdiv_ratio >>= AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET; + + return parent_rate / cpu_clkdiv_ratio; +} + +static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ap_cpu_clk *clk = to_ap_cpu_clk(hw); + int ret, reg, divider = parent_rate / rate; + unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit; + + cpu_clkdiv_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET + + (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); + cpu_force_reg = AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET + + (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); + cpu_ratio_reg = AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET + + (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); + + regmap_update_bits(clk->pll_cr_base, cpu_clkdiv_reg, + AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK, divider); + + regmap_update_bits(clk->pll_cr_base, cpu_force_reg, + AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK, + AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK); + + regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg, + BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET), + BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET)); + + stable_bit = BIT(clk->cluster * AP806_CA72MP2_0_PLL_RATIO_STATE), + + ret = regmap_read_poll_timeout(clk->pll_cr_base, + AP806_CA72MP2_0_PLL_SR_REG_OFFSET, reg, + reg & stable_bit, STATUS_POLL_PERIOD_US, + STATUS_POLL_TIMEOUT_US); + if (ret) + return ret; + + regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg, + BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET), 0); + + return 0; +} + +static long ap_cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + int divider = *parent_rate / rate; + + divider = min(divider, APN806_MAX_DIVIDER); + + return *parent_rate / divider; +} + +static const struct clk_ops ap_cpu_clk_ops = { + .recalc_rate = ap_cpu_clk_recalc_rate, + .round_rate = ap_cpu_clk_round_rate, + .set_rate = ap_cpu_clk_set_rate, +}; + +static int ap_cpu_clock_probe(struct platform_device *pdev) +{ + int ret, nclusters = 0, cluster_index = 0; + struct device *dev = &pdev->dev; + struct device_node *dn, *np = dev->of_node; + struct clk_hw_onecell_data *ap_cpu_data; + struct ap_cpu_clk *ap_cpu_clk; + struct regmap *regmap; + + regmap = syscon_node_to_regmap(np->parent); + if (IS_ERR(regmap)) { + pr_err("cannot get pll_cr_base regmap\n"); + return PTR_ERR(regmap); + } + + /* + * AP806 has 4 cpus and DFS for AP806 is controlled per + * cluster (2 CPUs per cluster), cpu0 and cpu1 are fixed to + * cluster0 while cpu2 and cpu3 are fixed to cluster1 whether + * they are enabled or not. Since cpu0 is the boot cpu, then + * cluster0 must exist. If cpu2 or cpu3 is enabled, cluster1 + * will exist and the cluster number is 2; otherwise the + * cluster number is 1. + */ + nclusters = 1; + for_each_of_cpu_node(dn) { + int cpu, err; + + err = of_property_read_u32(dn, "reg", &cpu); + if (WARN_ON(err)) + return err; + + /* If cpu2 or cpu3 is enabled */ + if (cpu & APN806_CLUSTER_NUM_MASK) { + nclusters = 2; + break; + } + } + /* + * DFS for AP806 is controlled per cluster (2 CPUs per cluster), + * so allocate structs per cluster + */ + ap_cpu_clk = devm_kcalloc(dev, nclusters, sizeof(*ap_cpu_clk), + GFP_KERNEL); + if (!ap_cpu_clk) + return -ENOMEM; + + ap_cpu_data = devm_kzalloc(dev, sizeof(*ap_cpu_data) + + sizeof(struct clk_hw *) * nclusters, + GFP_KERNEL); + if (!ap_cpu_data) + return -ENOMEM; + + for_each_of_cpu_node(dn) { + char *clk_name = "cpu-cluster-0"; + struct clk_init_data init; + const char *parent_name; + struct clk *parent; + int cpu, err; + + err = of_property_read_u32(dn, "reg", &cpu); + if (WARN_ON(err)) + return err; + + cluster_index = cpu & APN806_CLUSTER_NUM_MASK; + cluster_index >>= APN806_CLUSTER_NUM_OFFSET; + + /* Initialize once for one cluster */ + if (ap_cpu_data->hws[cluster_index]) + continue; + + parent = of_clk_get(np, cluster_index); + if (IS_ERR(parent)) { + dev_err(dev, "Could not get the clock parent\n"); + return -EINVAL; + } + parent_name = __clk_get_name(parent); + clk_name[12] += cluster_index; + ap_cpu_clk[cluster_index].clk_name = + ap_cp_unique_name(dev, np->parent, clk_name); + ap_cpu_clk[cluster_index].cluster = cluster_index; + ap_cpu_clk[cluster_index].pll_cr_base = regmap; + ap_cpu_clk[cluster_index].hw.init = &init; + ap_cpu_clk[cluster_index].dev = dev; + + init.name = ap_cpu_clk[cluster_index].clk_name; + init.ops = &ap_cpu_clk_ops; + init.num_parents = 1; + init.parent_names = &parent_name; + + ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw); + if (ret) + return ret; + ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw; + } + + ap_cpu_data->num = cluster_index + 1; + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ap_cpu_data); + if (ret) + dev_err(dev, "failed to register OF clock provider\n"); + + return ret; +} + +static const struct of_device_id ap_cpu_clock_of_match[] = { + { .compatible = "marvell,ap806-cpu-clock", }, + { } +}; + +static struct platform_driver ap_cpu_clock_driver = { + .probe = ap_cpu_clock_probe, + .driver = { + .name = "marvell-ap-cpu-clock", + .of_match_table = ap_cpu_clock_of_match, + .suppress_bind_attrs = true, + }, +}; +builtin_platform_driver(ap_cpu_clock_driver); From baf4c10f8878d44912070561d542a74c09f05adf Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 10 Jul 2019 15:43:44 +0200 Subject: [PATCH 27/62] clk: mvebu: ap806: Fix clock name for the cluster Actually, the clocks exposed for the cluster are not the CPU clocks, but the PLL clock used as entry clock for the CPU clocks. The CPU clock will be managed by a driver submitting in the following patches. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/20190710134346.30239-5-gregory.clement@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index 0a58824ff053..73ba8fd7860f 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -97,7 +97,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, cpuclk_freq *= 1000 * 1000; /* CPU clocks depend on the Sample At Reset configuration */ - name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-0"); + name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0"); ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL, 0, cpuclk_freq); if (IS_ERR(ap806_clks[0])) { @@ -105,7 +105,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, goto fail0; } - name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-1"); + name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-1"); ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0, cpuclk_freq); if (IS_ERR(ap806_clks[1])) { From 3567894b6914813299300019e028874927210880 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 31 Jul 2019 10:40:16 +0200 Subject: [PATCH 28/62] clk: core: introduce clk_hw_set_parent() Introduce the clk_hw_set_parent() provider call to change parent of a clock by using the clk_hw pointers. This eases the clock reparenting from clock rate notifiers and implementing DVFS with simpler code avoiding the boilerplates functions as __clk_lookup(clk_hw_get_name()) then clk_set_parent(). Signed-off-by: Neil Armstrong Acked-by: Martin Blumenstingl Acked-by: Stephen Boyd Signed-off-by: Jerome Brunet --- drivers/clk/clk.c | 6 ++++++ include/linux/clk-provider.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c0990703ce54..c11b1781d24a 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -2487,6 +2487,12 @@ runtime_put: return ret; } +int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent) +{ + return clk_core_set_parent_nolock(hw->core, parent->core); +} +EXPORT_SYMBOL_GPL(clk_hw_set_parent); + /** * clk_set_parent - switch the parent of a mux clk * @clk: the mux clk whose input we are switching diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2ae7604783dd..dce5521a9bf6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index); +int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent); unsigned int __clk_get_enable_count(struct clk *clk); unsigned long clk_hw_get_rate(const struct clk_hw *hw); unsigned long __clk_get_flags(struct clk *clk); From 26d34431add04a98a60b8935c25765914fa773f7 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 31 Jul 2019 10:40:17 +0200 Subject: [PATCH 29/62] clk: meson: add g12a cpu dynamic divider driver Add a clock driver for the cpu dynamic divider, this divider needs to have a flag set before setting the divider value then removed while writing the new value to the register. This drivers implements this behavior and will be used essentially on the Amlogic G12A and G12B SoCs for cpu clock trees. Signed-off-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/Kconfig | 5 ++ drivers/clk/meson/Makefile | 1 + drivers/clk/meson/clk-cpu-dyndiv.c | 73 ++++++++++++++++++++++++++++++ drivers/clk/meson/clk-cpu-dyndiv.h | 20 ++++++++ 4 files changed, 99 insertions(+) create mode 100644 drivers/clk/meson/clk-cpu-dyndiv.c create mode 100644 drivers/clk/meson/clk-cpu-dyndiv.h diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 500be0b0d473..dabeb435d067 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -36,6 +36,10 @@ config COMMON_CLK_MESON_EE_CLKC tristate select COMMON_CLK_MESON_REGMAP +config COMMON_CLK_MESON_CPU_DYNDIV + tristate + select COMMON_CLK_MESON_REGMAP + config COMMON_CLK_MESON8B bool depends on ARCH_MESON @@ -98,6 +102,7 @@ config COMMON_CLK_G12A select COMMON_CLK_MESON_PLL select COMMON_CLK_MESON_AO_CLKC select COMMON_CLK_MESON_EE_CLKC + select COMMON_CLK_MESON_CPU_DYNDIV select MFD_SYSCON help Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2 diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index f09d83dc3d60..3939f218587a 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -2,6 +2,7 @@ # Amlogic clock drivers obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o +obj-$(CONFIG_COMMON_CLK_MESON_CPU_DYNDIV) += clk-cpu-dyndiv.o obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c new file mode 100644 index 000000000000..36976927fe82 --- /dev/null +++ b/drivers/clk/meson/clk-cpu-dyndiv.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#include +#include + +#include "clk-regmap.h" +#include "clk-cpu-dyndiv.h" + +static inline struct meson_clk_cpu_dyndiv_data * +meson_clk_cpu_dyndiv_data(struct clk_regmap *clk) +{ + return (struct meson_clk_cpu_dyndiv_data *)clk->data; +} + +static unsigned long meson_clk_cpu_dyndiv_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk); + + return divider_recalc_rate(hw, prate, + meson_parm_read(clk->map, &data->div), + NULL, 0, data->div.width); +} + +static long meson_clk_cpu_dyndiv_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk); + + return divider_round_rate(hw, rate, prate, NULL, data->div.width, 0); +} + +static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk); + unsigned int val; + int ret; + + ret = divider_get_val(rate, parent_rate, NULL, data->div.width, 0); + if (ret < 0) + return ret; + + val = (unsigned int)ret << data->div.shift; + + /* Write the SYS_CPU_DYN_ENABLE bit before changing the divider */ + meson_parm_write(clk->map, &data->dyn, 1); + + /* Update the divider while removing the SYS_CPU_DYN_ENABLE bit */ + return regmap_update_bits(clk->map, data->div.reg_off, + SETPMASK(data->div.width, data->div.shift) | + SETPMASK(data->dyn.width, data->dyn.shift), + val); +}; + +const struct clk_ops meson_clk_cpu_dyndiv_ops = { + .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate, + .round_rate = meson_clk_cpu_dyndiv_round_rate, + .set_rate = meson_clk_cpu_dyndiv_set_rate, +}; +EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops); + +MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider"); +MODULE_AUTHOR("Neil Armstrong "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/meson/clk-cpu-dyndiv.h b/drivers/clk/meson/clk-cpu-dyndiv.h new file mode 100644 index 000000000000..f4908404792e --- /dev/null +++ b/drivers/clk/meson/clk-cpu-dyndiv.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#ifndef __MESON_CLK_CPU_DYNDIV_H +#define __MESON_CLK_CPU_DYNDIV_H + +#include +#include "parm.h" + +struct meson_clk_cpu_dyndiv_data { + struct parm div; + struct parm dyn; +}; + +extern const struct clk_ops meson_clk_cpu_dyndiv_ops; + +#endif /* __MESON_CLK_CPU_DYNDIV_H */ From ffae8475b90c045ca508675794c08a0c8c12d202 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 31 Jul 2019 10:40:18 +0200 Subject: [PATCH 30/62] clk: meson: g12a: add notifiers to handle cpu clock change In order to implement clock switching for the CLKID_CPU_CLK and CLKID_CPUB_CLK, notifiers are added on specific points of the clock tree : cpu_clk / cpub_clk | \- cpu_clk_dyn | | \- cpu_clk_premux0 | | |- cpu_clk_postmux0 | | | |- cpu_clk_dyn0_div | | | \- xtal/fclk_div2/fclk_div3 | | \- xtal/fclk_div2/fclk_div3 | \- cpu_clk_premux1 | |- cpu_clk_postmux1 | | |- cpu_clk_dyn1_div | | \- xtal/fclk_div2/fclk_div3 | \- xtal/fclk_div2/fclk_div3 \ sys_pll / sys1_pll This for each cluster, a single one for G12A, two for G12B. Each cpu_clk_premux1 tree is marked as read-only and CLK_SET_RATE_NO_REPARENT, to be used as "parking" clock in a safe clock frequency. A notifier is added on each cpu_clk_premux0 to detech when CCF want to change the frequency of the cpu_clk_dyn tree. In this notifier, the cpu_clk_premux1 tree is configured to use the xtal clock and then the cpu_clk_dyn is switch to cpu_clk_premux1 while CCF updates the cpu_clk_premux0 tree. A notifier is added on each sys_pll/sys1_pll to detect when CCF wants to change the PLL clock source of the cpu_clk. In this notifier, the cpu_clk is switched to cpu_clk_dyn while CCF updates the sys_pll/sys1_pll frequency. A third small notifier is added on each cpu_clk / cpub_clk and cpu_clk_dyn, add a small delay at PRE_RATE_CHANGE/POST_RATE_CHANGE to let the other notofiers change propagate before changing the cpu_clk_premux0 and sys_pll clock trees. This notifier set permits switching the cpu_clk / cpub_clk without any glitches and using a safe parking clock while switching between sub-GHz clocks using the cpu_clk_dyn tree. This setup has been tested and validated on the Amlogic G12A and G12B SoCs running the arm64 cpuburn at [1] and cycling between all the possible cpufreq translations of each cluster and checking the final frequency using the clock-measurer, script at [2]. [1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S [2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 531 +++++++++++++++++++++++++++++++++++---- 1 file changed, 479 insertions(+), 52 deletions(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index a8f706de811b..c3f0ffc3280d 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -14,10 +14,12 @@ #include #include #include +#include #include "clk-mpll.h" #include "clk-pll.h" #include "clk-regmap.h" +#include "clk-cpu-dyndiv.h" #include "vid-pll-div.h" #include "meson-eeclk.h" #include "g12a.h" @@ -88,16 +90,9 @@ static struct clk_regmap g12a_fixed_pll = { }, }; -/* - * Internal sys pll emulation configuration parameters - */ -static const struct reg_sequence g12a_sys_init_regs[] = { - { .reg = HHI_SYS_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_SYS_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_SYS_PLL_CNTL3, .def = 0x48681c00 }, - { .reg = HHI_SYS_PLL_CNTL4, .def = 0x88770290 }, - { .reg = HHI_SYS_PLL_CNTL5, .def = 0x39272000 }, - { .reg = HHI_SYS_PLL_CNTL6, .def = 0x56540000 }, +static const struct pll_mult_range g12a_sys_pll_mult_range = { + .min = 128, + .max = 250, }; static struct clk_regmap g12a_sys_pll_dco = { @@ -127,16 +122,17 @@ static struct clk_regmap g12a_sys_pll_dco = { .shift = 29, .width = 1, }, - .init_regs = g12a_sys_init_regs, - .init_count = ARRAY_SIZE(g12a_sys_init_regs), + .range = &g12a_sys_pll_mult_range, }, .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", - .ops = &meson_clk_pll_ro_ops, + .ops = &meson_clk_pll_ops, .parent_data = &(const struct clk_parent_data) { .fw_name = "xtal", }, .num_parents = 1, + /* This clock feeds the CPU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, }, }; @@ -149,11 +145,12 @@ static struct clk_regmap g12a_sys_pll = { }, .hw.init = &(struct clk_init_data){ .name = "sys_pll", - .ops = &clk_regmap_divider_ro_ops, + .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_sys_pll_dco.hw }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -184,14 +181,17 @@ static struct clk_regmap g12b_sys1_pll_dco = { .shift = 29, .width = 1, }, + .range = &g12a_sys_pll_mult_range, }, .hw.init = &(struct clk_init_data){ .name = "sys1_pll_dco", - .ops = &meson_clk_pll_ro_ops, + .ops = &meson_clk_pll_ops, .parent_data = &(const struct clk_parent_data) { .fw_name = "xtal", }, .num_parents = 1, + /* This clock feeds the CPU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, }, }; @@ -204,11 +204,12 @@ static struct clk_regmap g12b_sys1_pll = { }, .hw.init = &(struct clk_init_data){ .name = "sys1_pll", - .ops = &clk_regmap_divider_ro_ops, + .ops = &clk_regmap_divider_ops, .parent_hws = (const struct clk_hw *[]) { &g12b_sys1_pll_dco.hw }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -345,13 +346,15 @@ static struct clk_regmap g12a_cpu_clk_premux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0_sel", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div2.hw }, { .hw = &g12a_fclk_div3.hw }, }, .num_parents = 3, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -364,30 +367,40 @@ static struct clk_regmap g12a_cpu_clk_premux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1_sel", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div2.hw }, { .hw = &g12a_fclk_div3.hw }, }, .num_parents = 3, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT }, }; /* Datasheet names this field as "mux0_divn_tcnt" */ static struct clk_regmap g12a_cpu_clk_mux0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_SYS_CPU_CLK_CNTL0, - .shift = 4, - .width = 6, + .data = &(struct meson_clk_cpu_dyndiv_data){ + .div = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .shift = 4, + .width = 6, + }, + .dyn = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .shift = 26, + .width = 1, + }, }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0_div", - .ops = &clk_regmap_divider_ro_ops, + .ops = &meson_clk_cpu_dyndiv_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk_premux0.hw }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -400,12 +413,13 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn0", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk_premux0.hw, &g12a_cpu_clk_mux0_div.hw, }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -435,12 +449,14 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn1", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk_premux1.hw, &g12a_cpu_clk_mux1_div.hw, }, .num_parents = 2, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -453,12 +469,13 @@ static struct clk_regmap g12a_cpu_clk_dyn = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk_dyn", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk_postmux0.hw, &g12a_cpu_clk_postmux1.hw, }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -471,12 +488,13 @@ static struct clk_regmap g12a_cpu_clk = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk_dyn.hw, &g12a_sys_pll.hw, }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -489,12 +507,13 @@ static struct clk_regmap g12b_cpu_clk = { }, .hw.init = &(struct clk_init_data){ .name = "cpu_clk", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk_dyn.hw, &g12b_sys1_pll.hw }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -507,7 +526,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0_sel", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div2.hw }, @@ -519,18 +538,26 @@ static struct clk_regmap g12b_cpub_clk_premux0 = { /* Datasheet names this field as "mux0_divn_tcnt" */ static struct clk_regmap g12b_cpub_clk_mux0_div = { - .data = &(struct clk_regmap_div_data){ - .offset = HHI_SYS_CPUB_CLK_CNTL, - .shift = 4, - .width = 6, + .data = &(struct meson_clk_cpu_dyndiv_data){ + .div = { + .reg_off = HHI_SYS_CPUB_CLK_CNTL, + .shift = 4, + .width = 6, + }, + .dyn = { + .reg_off = HHI_SYS_CPUB_CLK_CNTL, + .shift = 26, + .width = 1, + }, }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0_div", - .ops = &clk_regmap_divider_ro_ops, + .ops = &meson_clk_cpu_dyndiv_ops, .parent_hws = (const struct clk_hw *[]) { &g12b_cpub_clk_premux0.hw }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -543,12 +570,13 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn0", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12b_cpub_clk_premux0.hw, &g12b_cpub_clk_mux0_div.hw }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -561,13 +589,15 @@ static struct clk_regmap g12b_cpub_clk_premux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1_sel", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_data = (const struct clk_parent_data []) { { .fw_name = "xtal", }, { .hw = &g12a_fclk_div2.hw }, { .hw = &g12a_fclk_div3.hw }, }, .num_parents = 3, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -597,12 +627,14 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn1", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12b_cpub_clk_premux1.hw, &g12b_cpub_clk_mux1_div.hw }, .num_parents = 2, + /* This sub-tree is used a parking clock */ + .flags = CLK_SET_RATE_NO_REPARENT, }, }; @@ -615,12 +647,13 @@ static struct clk_regmap g12b_cpub_clk_dyn = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk_dyn", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12b_cpub_clk_postmux0.hw, &g12b_cpub_clk_postmux1.hw }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -633,15 +666,227 @@ static struct clk_regmap g12b_cpub_clk = { }, .hw.init = &(struct clk_init_data){ .name = "cpub_clk", - .ops = &clk_regmap_mux_ro_ops, + .ops = &clk_regmap_mux_ops, .parent_hws = (const struct clk_hw *[]) { &g12b_cpub_clk_dyn.hw, &g12a_sys_pll.hw }, .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, }, }; +static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) { + /* Wait for clock propagation before/after changing the mux */ + udelay(100); + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static struct notifier_block g12a_cpu_clk_mux_nb = { + .notifier_call = g12a_cpu_clk_mux_notifier_cb, +}; + +struct g12a_cpu_clk_postmux_nb_data { + struct notifier_block nb; + struct clk_hw *xtal; + struct clk_hw *cpu_clk_dyn; + struct clk_hw *cpu_clk_postmux0; + struct clk_hw *cpu_clk_postmux1; + struct clk_hw *cpu_clk_premux1; +}; + +static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct g12a_cpu_clk_postmux_nb_data *nb_data = + container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * This notifier means cpu_clk_postmux0 clock will be changed + * to feed cpu_clk, this is the current path : + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_postmux0 + * \- cpu_clk_muxX_div + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + * OR + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + */ + + /* Setup cpu_clk_premux1 to xtal */ + clk_hw_set_parent(nb_data->cpu_clk_premux1, + nb_data->xtal); + + /* Setup cpu_clk_postmux1 to bypass divider */ + clk_hw_set_parent(nb_data->cpu_clk_postmux1, + nb_data->cpu_clk_premux1); + + /* Switch to parking clk on cpu_clk_postmux1 */ + clk_hw_set_parent(nb_data->cpu_clk_dyn, + nb_data->cpu_clk_postmux1); + + /* + * Now, cpu_clk is 24MHz in the current path : + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_postmux1 + * \- cpu_clk_premux1 + * \- xtal + */ + + udelay(100); + + return NOTIFY_OK; + + case POST_RATE_CHANGE: + /* + * The cpu_clk_postmux0 has ben updated, now switch back + * cpu_clk_dyn to cpu_clk_postmux0 and take the changes + * in account. + */ + + /* Configure cpu_clk_dyn back to cpu_clk_postmux0 */ + clk_hw_set_parent(nb_data->cpu_clk_dyn, + nb_data->cpu_clk_postmux0); + + /* + * new path : + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_postmux0 + * \- cpu_clk_muxX_div + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + * OR + * \- cpu_clk_premux0 + * \- fclk_div3 or fclk_div2 + */ + + udelay(100); + + return NOTIFY_OK; + + default: + return NOTIFY_DONE; + } +} + +static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = { + .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, + .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw, + .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw, + .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw, + .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb, +}; + +static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = { + .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw, + .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw, + .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw, + .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw, + .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb, +}; + +struct g12a_sys_pll_nb_data { + struct notifier_block nb; + struct clk_hw *sys_pll; + struct clk_hw *cpu_clk; + struct clk_hw *cpu_clk_dyn; +}; + +static int g12a_sys_pll_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct g12a_sys_pll_nb_data *nb_data = + container_of(nb, struct g12a_sys_pll_nb_data, nb); + + switch (event) { + case PRE_RATE_CHANGE: + /* + * This notifier means sys_pll clock will be changed + * to feed cpu_clk, this the current path : + * cpu_clk + * \- sys_pll + * \- sys_pll_dco + */ + + /* Configure cpu_clk to use cpu_clk_dyn */ + clk_hw_set_parent(nb_data->cpu_clk, + nb_data->cpu_clk_dyn); + + /* + * Now, cpu_clk uses the dyn path + * cpu_clk + * \- cpu_clk_dyn + * \- cpu_clk_dynX + * \- cpu_clk_dynX_sel + * \- cpu_clk_dynX_div + * \- xtal/fclk_div2/fclk_div3 + * \- xtal/fclk_div2/fclk_div3 + */ + + udelay(100); + + return NOTIFY_OK; + + case POST_RATE_CHANGE: + /* + * The sys_pll has ben updated, now switch back cpu_clk to + * sys_pll + */ + + /* Configure cpu_clk to use sys_pll */ + clk_hw_set_parent(nb_data->cpu_clk, + nb_data->sys_pll); + + udelay(100); + + /* new path : + * cpu_clk + * \- sys_pll + * \- sys_pll_dco + */ + + return NOTIFY_OK; + + default: + return NOTIFY_DONE; + } +} + +static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = { + .sys_pll = &g12a_sys_pll.hw, + .cpu_clk = &g12a_cpu_clk.hw, + .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, + .nb.notifier_call = g12a_sys_pll_notifier_cb, +}; + +/* G12B first CPU cluster uses sys1_pll */ +static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = { + .sys_pll = &g12b_sys1_pll.hw, + .cpu_clk = &g12b_cpu_clk.hw, + .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw, + .nb.notifier_call = g12a_sys_pll_notifier_cb, +}; + +/* G12B second CPU cluster uses sys_pll */ +static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = { + .sys_pll = &g12a_sys_pll.hw, + .cpu_clk = &g12b_cpub_clk.hw, + .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw, + .nb.notifier_call = g12a_sys_pll_notifier_cb, +}; + static struct clk_regmap g12a_cpu_clk_div16_en = { .data = &(struct clk_regmap_gate_data){ .offset = HHI_SYS_CPU_CLK_CNTL1, @@ -4097,28 +4342,210 @@ static const struct reg_sequence g12a_init_regs[] = { { .reg = HHI_MPLL_CNTL0, .def = 0x00000543 }, }; -static const struct meson_eeclkc_data g12a_clkc_data = { - .regmap_clks = g12a_clk_regmaps, - .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), - .hw_onecell_data = &g12a_hw_onecell_data, - .init_regs = g12a_init_regs, - .init_count = ARRAY_SIZE(g12a_init_regs), +static int meson_g12a_dvfs_setup_common(struct platform_device *pdev, + struct clk_hw **hws) +{ + const char *notifier_clk_name; + struct clk *notifier_clk; + struct clk_hw *xtal; + int ret; + + xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0); + + /* Setup clock notifier for cpu_clk_postmux0 */ + g12a_cpu_clk_postmux0_nb_data.xtal = xtal; + notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12a_cpu_clk_postmux0_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n"); + return ret; + } + + /* Setup clock notifier for cpu_clk_dyn mux */ + notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n"); + return ret; + } + + return 0; +} + +static int meson_g12b_dvfs_setup(struct platform_device *pdev) +{ + struct clk_hw **hws = g12b_hw_onecell_data.hws; + const char *notifier_clk_name; + struct clk *notifier_clk; + struct clk_hw *xtal; + int ret; + + ret = meson_g12a_dvfs_setup_common(pdev, hws); + if (ret) + return ret; + + xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0); + + /* Setup clock notifier for cpu_clk mux */ + notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n"); + return ret; + } + + /* Setup clock notifier for sys1_pll */ + notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12b_cpu_clk_sys1_pll_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n"); + return ret; + } + + /* Add notifiers for the second CPU cluster */ + + /* Setup clock notifier for cpub_clk_postmux0 */ + g12b_cpub_clk_postmux0_nb_data.xtal = xtal; + notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12b_cpub_clk_postmux0_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n"); + return ret; + } + + /* Setup clock notifier for cpub_clk_dyn mux */ + notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n"); + return ret; + } + + /* Setup clock notifier for cpub_clk mux */ + notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n"); + return ret; + } + + /* Setup clock notifier for sys_pll */ + notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, + &g12b_cpub_clk_sys_pll_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the sys_pll notifier\n"); + return ret; + } + + return 0; +} + +static int meson_g12a_dvfs_setup(struct platform_device *pdev) +{ + struct clk_hw **hws = g12a_hw_onecell_data.hws; + const char *notifier_clk_name; + struct clk *notifier_clk; + int ret; + + ret = meson_g12a_dvfs_setup_common(pdev, hws); + if (ret) + return ret; + + /* Setup clock notifier for cpu_clk mux */ + notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n"); + return ret; + } + + /* Setup clock notifier for sys_pll */ + notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw); + notifier_clk = __clk_lookup(notifier_clk_name); + ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb); + if (ret) { + dev_err(&pdev->dev, "failed to register the sys_pll notifier\n"); + return ret; + } + + return 0; +} + +struct meson_g12a_data { + const struct meson_eeclkc_data eeclkc_data; + int (*dvfs_setup)(struct platform_device *pdev); }; -static const struct meson_eeclkc_data g12b_clkc_data = { - .regmap_clks = g12a_clk_regmaps, - .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), - .hw_onecell_data = &g12b_hw_onecell_data +static int meson_g12a_probe(struct platform_device *pdev) +{ + const struct meson_eeclkc_data *eeclkc_data; + const struct meson_g12a_data *g12a_data; + int ret; + + eeclkc_data = of_device_get_match_data(&pdev->dev); + if (!eeclkc_data) + return -EINVAL; + + ret = meson_eeclkc_probe(pdev); + if (ret) + return ret; + + g12a_data = container_of(eeclkc_data, struct meson_g12a_data, + eeclkc_data); + + if (g12a_data->dvfs_setup) + return g12a_data->dvfs_setup(pdev); + + return 0; +} + +static const struct meson_g12a_data g12a_clkc_data = { + .eeclkc_data = { + .regmap_clks = g12a_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), + .hw_onecell_data = &g12a_hw_onecell_data, + .init_regs = g12a_init_regs, + .init_count = ARRAY_SIZE(g12a_init_regs), + }, + .dvfs_setup = meson_g12a_dvfs_setup, +}; + +static const struct meson_g12a_data g12b_clkc_data = { + .eeclkc_data = { + .regmap_clks = g12a_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), + .hw_onecell_data = &g12b_hw_onecell_data, + }, + .dvfs_setup = meson_g12b_dvfs_setup, }; static const struct of_device_id clkc_match_table[] = { - { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data }, - { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data }, + { + .compatible = "amlogic,g12a-clkc", + .data = &g12a_clkc_data.eeclkc_data + }, + { + .compatible = "amlogic,g12b-clkc", + .data = &g12b_clkc_data.eeclkc_data + }, {} }; static struct platform_driver g12a_driver = { - .probe = meson_eeclkc_probe, + .probe = meson_g12a_probe, .driver = { .name = "g12a-clkc", .of_match_table = clkc_match_table, From 85ab9d954698961960240622de4fad85c7d8a61e Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 31 Jul 2019 10:40:19 +0200 Subject: [PATCH 31/62] clk: meson: g12a: expose CPUB clock ID for G12B Expose the CPUB clock id to add DVFS to the second CPU cluster of the Amlogic G12B SoC. Reviewed-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.h | 1 - include/dt-bindings/clock/g12a-clkc.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index c8aed31fbe17..559a34cfdfeb 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -216,7 +216,6 @@ #define CLKID_CPUB_CLK_DYN1_DIV 221 #define CLKID_CPUB_CLK_DYN1 222 #define CLKID_CPUB_CLK_DYN 223 -#define CLKID_CPUB_CLK 224 #define CLKID_CPUB_CLK_DIV16_EN 225 #define CLKID_CPUB_CLK_DIV16 226 #define CLKID_CPUB_CLK_DIV2 227 diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h index b6b127e45634..8ccc29ac7a72 100644 --- a/include/dt-bindings/clock/g12a-clkc.h +++ b/include/dt-bindings/clock/g12a-clkc.h @@ -137,5 +137,6 @@ #define CLKID_VDEC_HEVC 207 #define CLKID_VDEC_HEVCF 210 #define CLKID_TS 212 +#define CLKID_CPUB_CLK 224 #endif /* __G12A_CLKC_H */ From 03d570e1a4dc669457af2888999ecc9548fc0d2a Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 10 Aug 2019 14:36:20 +0200 Subject: [PATCH 32/62] clk: ingenic: Use CLK_OF_DECLARE_DRIVER macro By using CLK_OF_DECLARE_DRIVER instead of the CLK_OF_DECLARE macro, we allow the driver to probe also as a platform driver. While this driver does not have code to probe as a platform driver, this is still useful for probing children devices in the case where the device node is compatible with "simple-mfd". Signed-off-by: Paul Cercueil Link: https://lkml.kernel.org/r/20190810123620.27238-1-paul@crapouillou.net Signed-off-by: Stephen Boyd --- drivers/clk/ingenic/jz4725b-cgu.c | 2 +- drivers/clk/ingenic/jz4740-cgu.c | 2 +- drivers/clk/ingenic/jz4770-cgu.c | 2 +- drivers/clk/ingenic/jz4780-cgu.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c index 2642d36d1e2c..a3b4635f6278 100644 --- a/drivers/clk/ingenic/jz4725b-cgu.c +++ b/drivers/clk/ingenic/jz4725b-cgu.c @@ -257,4 +257,4 @@ static void __init jz4725b_cgu_init(struct device_node *np) ingenic_cgu_register_syscore_ops(cgu); } -CLK_OF_DECLARE(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init); +CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init); diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 9b27d75d9485..978f32dd424a 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -248,4 +248,4 @@ static void __init jz4740_cgu_init(struct device_node *np) ingenic_cgu_register_syscore_ops(cgu); } -CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init); +CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init); diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index eebc1bea3841..956dd653a43d 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -443,4 +443,4 @@ static void __init jz4770_cgu_init(struct device_node *np) } /* We only probe via devicetree, no need for a platform driver */ -CLK_OF_DECLARE(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init); +CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init); diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index 8c67f89df25e..ea905ff72bf0 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -725,4 +725,4 @@ static void __init jz4780_cgu_init(struct device_node *np) ingenic_cgu_register_syscore_ops(cgu); } -CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); +CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); From 0688587a71200911721a0cb025fe805ddc0404b6 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 12 Aug 2019 14:32:52 +0200 Subject: [PATCH 33/62] dt-bindings: clock: meson: add resets to the audio clock controller Add the documentation and bindings for the resets provided by the g12a audio clock controller Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- .../bindings/clock/amlogic,axg-audio-clkc.txt | 1 + .../reset/amlogic,meson-g12a-audio-reset.h | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt index 0f777749f4f1..b3957d10d241 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt @@ -22,6 +22,7 @@ Required Properties: components. - resets : phandle of the internal reset line - #clock-cells : should be 1. +- #reset-cells : should be 1 on the g12a (and following) soc family Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. All available clocks are defined as diff --git a/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h new file mode 100644 index 000000000000..14b78dabed0e --- /dev/null +++ b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Jerome Brunet + * + */ + +#ifndef _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H +#define _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H + +#define AUD_RESET_PDM 0 +#define AUD_RESET_TDMIN_A 1 +#define AUD_RESET_TDMIN_B 2 +#define AUD_RESET_TDMIN_C 3 +#define AUD_RESET_TDMIN_LB 4 +#define AUD_RESET_LOOPBACK 5 +#define AUD_RESET_TODDR_A 6 +#define AUD_RESET_TODDR_B 7 +#define AUD_RESET_TODDR_C 8 +#define AUD_RESET_FRDDR_A 9 +#define AUD_RESET_FRDDR_B 10 +#define AUD_RESET_FRDDR_C 11 +#define AUD_RESET_TDMOUT_A 12 +#define AUD_RESET_TDMOUT_B 13 +#define AUD_RESET_TDMOUT_C 14 +#define AUD_RESET_SPDIFOUT 15 +#define AUD_RESET_SPDIFOUT_B 16 +#define AUD_RESET_SPDIFIN 17 +#define AUD_RESET_EQDRC 18 +#define AUD_RESET_RESAMPLE 19 +#define AUD_RESET_DDRARB 20 +#define AUD_RESET_POWDET 21 +#define AUD_RESET_TORAM 22 +#define AUD_RESET_TOACODEC 23 +#define AUD_RESET_TOHDMITX 24 +#define AUD_RESET_CLKTREE 25 + +#endif From 7cfefab6563f6e333477ec71613e1ec3bbdccc35 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 12 Aug 2019 14:32:53 +0200 Subject: [PATCH 34/62] clk: meson: axg-audio: add g12a reset support On the g12a, the register space dedicated to the audio clock also provides some resets. Let the clock controller register a reset provider as well for this SoC family. the axg SoC family does not appear to provide this feature. Reviewed-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 107 +++++++++++++++++++++++++++++++++- drivers/clk/meson/axg-audio.h | 1 + 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 741df7e955ca..6be9df1efce5 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "axg-audio.h" @@ -918,6 +919,84 @@ static int devm_clk_get_enable(struct device *dev, char *id) return 0; } +struct axg_audio_reset_data { + struct reset_controller_dev rstc; + struct regmap *map; + unsigned int offset; +}; + +static void axg_audio_reset_reg_and_bit(struct axg_audio_reset_data *rst, + unsigned long id, + unsigned int *reg, + unsigned int *bit) +{ + unsigned int stride = regmap_get_reg_stride(rst->map); + + *reg = (id / (stride * BITS_PER_BYTE)) * stride; + *reg += rst->offset; + *bit = id % (stride * BITS_PER_BYTE); +} + +static int axg_audio_reset_update(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct axg_audio_reset_data *rst = + container_of(rcdev, struct axg_audio_reset_data, rstc); + unsigned int offset, bit; + + axg_audio_reset_reg_and_bit(rst, id, &offset, &bit); + + regmap_update_bits(rst->map, offset, BIT(bit), + assert ? BIT(bit) : 0); + + return 0; +} + +static int axg_audio_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct axg_audio_reset_data *rst = + container_of(rcdev, struct axg_audio_reset_data, rstc); + unsigned int val, offset, bit; + + axg_audio_reset_reg_and_bit(rst, id, &offset, &bit); + + regmap_read(rst->map, offset, &val); + + return !!(val & BIT(bit)); +} + +static int axg_audio_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return axg_audio_reset_update(rcdev, id, true); +} + +static int axg_audio_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return axg_audio_reset_update(rcdev, id, false); +} + +static int axg_audio_reset_toggle(struct reset_controller_dev *rcdev, + unsigned long id) +{ + int ret; + + ret = axg_audio_reset_assert(rcdev, id); + if (ret) + return ret; + + return axg_audio_reset_deassert(rcdev, id); +} + +static const struct reset_control_ops axg_audio_rstc_ops = { + .assert = axg_audio_reset_assert, + .deassert = axg_audio_reset_deassert, + .reset = axg_audio_reset_toggle, + .status = axg_audio_reset_status, +}; + static const struct regmap_config axg_audio_regmap_cfg = { .reg_bits = 32, .val_bits = 32, @@ -927,12 +1006,15 @@ static const struct regmap_config axg_audio_regmap_cfg = { struct audioclk_data { struct clk_hw_onecell_data *hw_onecell_data; + unsigned int reset_offset; + unsigned int reset_num; }; static int axg_audio_clkc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct audioclk_data *data; + struct axg_audio_reset_data *rst; struct regmap *map; struct resource *res; void __iomem *regs; @@ -984,8 +1066,27 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) } } - return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, - data->hw_onecell_data); + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + data->hw_onecell_data); + if (ret) + return ret; + + /* Stop here if there is no reset */ + if (!data->reset_num) + return 0; + + rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL); + if (!rst) + return -ENOMEM; + + rst->map = map; + rst->offset = data->reset_offset; + rst->rstc.nr_resets = data->reset_num; + rst->rstc.ops = &axg_audio_rstc_ops; + rst->rstc.of_node = dev->of_node; + rst->rstc.owner = THIS_MODULE; + + return devm_reset_controller_register(dev, &rst->rstc); } static const struct audioclk_data axg_audioclk_data = { @@ -994,6 +1095,8 @@ static const struct audioclk_data axg_audioclk_data = { static const struct audioclk_data g12a_audioclk_data = { .hw_onecell_data = &g12a_audio_hw_onecell_data, + .reset_offset = AUDIO_SW_RESET, + .reset_num = 26, }; static const struct of_device_id clkc_match_table[] = { diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h index 5d972d55d6c7..c00e28b2e1a9 100644 --- a/drivers/clk/meson/axg-audio.h +++ b/drivers/clk/meson/axg-audio.h @@ -22,6 +22,7 @@ #define AUDIO_MCLK_F_CTRL 0x018 #define AUDIO_MST_PAD_CTRL0 0x01c #define AUDIO_MST_PAD_CTRL1 0x020 +#define AUDIO_SW_RESET 0x024 #define AUDIO_MST_A_SCLK_CTRL0 0x040 #define AUDIO_MST_A_SCLK_CTRL1 0x044 #define AUDIO_MST_B_SCLK_CTRL0 0x048 From cda4569137b90f200bee4922d894ca49d4188681 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 26 Aug 2019 09:25:35 +0200 Subject: [PATCH 35/62] dt-bindings: clk: meson: add sm1 periph clock controller bindings Update the documentation to support clock driver for the Amlogic SM1 SoC and expose the GP1, DSU and the CPU 1, 2 & 3 clocks. SM1 clock tree is very close, the main differences are : - each CPU core can achieve a different frequency, albeit a common PLL - a similar tree as the clock tree has been added for the DynamIQ Shared Unit - has a new GP1 PLL used for the DynamIQ Shared Unit - SM1 has additional clocks like for CSI, NanoQ an other components Signed-off-by: Neil Armstrong Reviewed-by: Kevin Hilman Signed-off-by: Jerome Brunet --- .../devicetree/bindings/clock/amlogic,gxbb-clkc.txt | 1 + include/dt-bindings/clock/g12a-clkc.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt index 6eaa52092313..7ccecd5c02c1 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt @@ -11,6 +11,7 @@ Required Properties: "amlogic,axg-clkc" for AXG SoC. "amlogic,g12a-clkc" for G12A SoC. "amlogic,g12b-clkc" for G12B SoC. + "amlogic,sm1-clkc" for SM1 SoC. - clocks : list of clock phandle, one for each entry clock-names. - clock-names : should contain the following: * "xtal": the platform xtal diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h index 8ccc29ac7a72..0837c1a7ae49 100644 --- a/include/dt-bindings/clock/g12a-clkc.h +++ b/include/dt-bindings/clock/g12a-clkc.h @@ -138,5 +138,10 @@ #define CLKID_VDEC_HEVCF 210 #define CLKID_TS 212 #define CLKID_CPUB_CLK 224 +#define CLKID_GP1_PLL 243 +#define CLKID_DSU_CLK 252 +#define CLKID_CPU1_CLK 253 +#define CLKID_CPU2_CLK 254 +#define CLKID_CPU3_CLK 255 #endif /* __G12A_CLKC_H */ From 3dd02b7334ecdea6cd5b0bd371a9c958f326c1ce Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 26 Aug 2019 09:25:36 +0200 Subject: [PATCH 36/62] clk: meson: g12a: add support for SM1 GP1 PLL Add the new GP1 PLL for the Amlogic SM1 SoC, used to feed the new DynamIQ Shared Unit of the ARM Cores Complex. This also adds a dedicated set of clock and compatible for SM1. Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 300 +++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/g12a.h | 11 +- 2 files changed, 310 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index c3f0ffc3280d..34dfac4b4dc6 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -1443,6 +1443,69 @@ static struct clk_regmap g12a_gp0_pll = { }, }; +static struct clk_regmap sm1_gp1_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_GP1_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + /* This clock feeds the DSU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, + }, +}; + +static struct clk_regmap sm1_gp1_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP1_PLL_CNTL0, + .shift = 16, + .width = 3, + .flags = (CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_ROUND_CLOSEST), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_gp1_pll_dco.hw + }, + .num_parents = 1, + }, +}; + /* * Internal hifi pll emulation configuration parameters */ @@ -4121,6 +4184,228 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = { .num = NR_CLKS, }; +static struct clk_hw_onecell_data sm1_hw_onecell_data = { + .hws = { + [CLKID_SYS_PLL] = &g12a_sys_pll.hw, + [CLKID_FIXED_PLL] = &g12a_fixed_pll.hw, + [CLKID_FCLK_DIV2] = &g12a_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &g12a_fclk_div3.hw, + [CLKID_FCLK_DIV4] = &g12a_fclk_div4.hw, + [CLKID_FCLK_DIV5] = &g12a_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &g12a_fclk_div7.hw, + [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5.hw, + [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, + [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel.hw, + [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div.hw, + [CLKID_CLK81] = &g12a_clk81.hw, + [CLKID_MPLL0] = &g12a_mpll0.hw, + [CLKID_MPLL1] = &g12a_mpll1.hw, + [CLKID_MPLL2] = &g12a_mpll2.hw, + [CLKID_MPLL3] = &g12a_mpll3.hw, + [CLKID_DDR] = &g12a_ddr.hw, + [CLKID_DOS] = &g12a_dos.hw, + [CLKID_AUDIO_LOCKER] = &g12a_audio_locker.hw, + [CLKID_MIPI_DSI_HOST] = &g12a_mipi_dsi_host.hw, + [CLKID_ETH_PHY] = &g12a_eth_phy.hw, + [CLKID_ISA] = &g12a_isa.hw, + [CLKID_PL301] = &g12a_pl301.hw, + [CLKID_PERIPHS] = &g12a_periphs.hw, + [CLKID_SPICC0] = &g12a_spicc_0.hw, + [CLKID_I2C] = &g12a_i2c.hw, + [CLKID_SANA] = &g12a_sana.hw, + [CLKID_SD] = &g12a_sd.hw, + [CLKID_RNG0] = &g12a_rng0.hw, + [CLKID_UART0] = &g12a_uart0.hw, + [CLKID_SPICC1] = &g12a_spicc_1.hw, + [CLKID_HIU_IFACE] = &g12a_hiu_reg.hw, + [CLKID_MIPI_DSI_PHY] = &g12a_mipi_dsi_phy.hw, + [CLKID_ASSIST_MISC] = &g12a_assist_misc.hw, + [CLKID_SD_EMMC_A] = &g12a_emmc_a.hw, + [CLKID_SD_EMMC_B] = &g12a_emmc_b.hw, + [CLKID_SD_EMMC_C] = &g12a_emmc_c.hw, + [CLKID_AUDIO_CODEC] = &g12a_audio_codec.hw, + [CLKID_AUDIO] = &g12a_audio.hw, + [CLKID_ETH] = &g12a_eth_core.hw, + [CLKID_DEMUX] = &g12a_demux.hw, + [CLKID_AUDIO_IFIFO] = &g12a_audio_ififo.hw, + [CLKID_ADC] = &g12a_adc.hw, + [CLKID_UART1] = &g12a_uart1.hw, + [CLKID_G2D] = &g12a_g2d.hw, + [CLKID_RESET] = &g12a_reset.hw, + [CLKID_PCIE_COMB] = &g12a_pcie_comb.hw, + [CLKID_PARSER] = &g12a_parser.hw, + [CLKID_USB] = &g12a_usb_general.hw, + [CLKID_PCIE_PHY] = &g12a_pcie_phy.hw, + [CLKID_AHB_ARB0] = &g12a_ahb_arb0.hw, + [CLKID_AHB_DATA_BUS] = &g12a_ahb_data_bus.hw, + [CLKID_AHB_CTRL_BUS] = &g12a_ahb_ctrl_bus.hw, + [CLKID_HTX_HDCP22] = &g12a_htx_hdcp22.hw, + [CLKID_HTX_PCLK] = &g12a_htx_pclk.hw, + [CLKID_BT656] = &g12a_bt656.hw, + [CLKID_USB1_DDR_BRIDGE] = &g12a_usb1_to_ddr.hw, + [CLKID_MMC_PCLK] = &g12a_mmc_pclk.hw, + [CLKID_UART2] = &g12a_uart2.hw, + [CLKID_VPU_INTR] = &g12a_vpu_intr.hw, + [CLKID_GIC] = &g12a_gic.hw, + [CLKID_SD_EMMC_A_CLK0_SEL] = &g12a_sd_emmc_a_clk0_sel.hw, + [CLKID_SD_EMMC_A_CLK0_DIV] = &g12a_sd_emmc_a_clk0_div.hw, + [CLKID_SD_EMMC_A_CLK0] = &g12a_sd_emmc_a_clk0.hw, + [CLKID_SD_EMMC_B_CLK0_SEL] = &g12a_sd_emmc_b_clk0_sel.hw, + [CLKID_SD_EMMC_B_CLK0_DIV] = &g12a_sd_emmc_b_clk0_div.hw, + [CLKID_SD_EMMC_B_CLK0] = &g12a_sd_emmc_b_clk0.hw, + [CLKID_SD_EMMC_C_CLK0_SEL] = &g12a_sd_emmc_c_clk0_sel.hw, + [CLKID_SD_EMMC_C_CLK0_DIV] = &g12a_sd_emmc_c_clk0_div.hw, + [CLKID_SD_EMMC_C_CLK0] = &g12a_sd_emmc_c_clk0.hw, + [CLKID_MPLL0_DIV] = &g12a_mpll0_div.hw, + [CLKID_MPLL1_DIV] = &g12a_mpll1_div.hw, + [CLKID_MPLL2_DIV] = &g12a_mpll2_div.hw, + [CLKID_MPLL3_DIV] = &g12a_mpll3_div.hw, + [CLKID_FCLK_DIV2_DIV] = &g12a_fclk_div2_div.hw, + [CLKID_FCLK_DIV3_DIV] = &g12a_fclk_div3_div.hw, + [CLKID_FCLK_DIV4_DIV] = &g12a_fclk_div4_div.hw, + [CLKID_FCLK_DIV5_DIV] = &g12a_fclk_div5_div.hw, + [CLKID_FCLK_DIV7_DIV] = &g12a_fclk_div7_div.hw, + [CLKID_FCLK_DIV2P5_DIV] = &g12a_fclk_div2p5_div.hw, + [CLKID_HIFI_PLL] = &g12a_hifi_pll.hw, + [CLKID_VCLK2_VENCI0] = &g12a_vclk2_venci0.hw, + [CLKID_VCLK2_VENCI1] = &g12a_vclk2_venci1.hw, + [CLKID_VCLK2_VENCP0] = &g12a_vclk2_vencp0.hw, + [CLKID_VCLK2_VENCP1] = &g12a_vclk2_vencp1.hw, + [CLKID_VCLK2_VENCT0] = &g12a_vclk2_venct0.hw, + [CLKID_VCLK2_VENCT1] = &g12a_vclk2_venct1.hw, + [CLKID_VCLK2_OTHER] = &g12a_vclk2_other.hw, + [CLKID_VCLK2_ENCI] = &g12a_vclk2_enci.hw, + [CLKID_VCLK2_ENCP] = &g12a_vclk2_encp.hw, + [CLKID_DAC_CLK] = &g12a_dac_clk.hw, + [CLKID_AOCLK] = &g12a_aoclk_gate.hw, + [CLKID_IEC958] = &g12a_iec958_gate.hw, + [CLKID_ENC480P] = &g12a_enc480p.hw, + [CLKID_RNG1] = &g12a_rng1.hw, + [CLKID_VCLK2_ENCT] = &g12a_vclk2_enct.hw, + [CLKID_VCLK2_ENCL] = &g12a_vclk2_encl.hw, + [CLKID_VCLK2_VENCLMMC] = &g12a_vclk2_venclmmc.hw, + [CLKID_VCLK2_VENCL] = &g12a_vclk2_vencl.hw, + [CLKID_VCLK2_OTHER1] = &g12a_vclk2_other1.hw, + [CLKID_FIXED_PLL_DCO] = &g12a_fixed_pll_dco.hw, + [CLKID_SYS_PLL_DCO] = &g12a_sys_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &g12a_gp0_pll_dco.hw, + [CLKID_HIFI_PLL_DCO] = &g12a_hifi_pll_dco.hw, + [CLKID_DMA] = &g12a_dma.hw, + [CLKID_EFUSE] = &g12a_efuse.hw, + [CLKID_ROM_BOOT] = &g12a_rom_boot.hw, + [CLKID_RESET_SEC] = &g12a_reset_sec.hw, + [CLKID_SEC_AHB_APB3] = &g12a_sec_ahb_apb3.hw, + [CLKID_MPLL_PREDIV] = &g12a_mpll_prediv.hw, + [CLKID_VPU_0_SEL] = &g12a_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &g12a_vpu_0_div.hw, + [CLKID_VPU_0] = &g12a_vpu_0.hw, + [CLKID_VPU_1_SEL] = &g12a_vpu_1_sel.hw, + [CLKID_VPU_1_DIV] = &g12a_vpu_1_div.hw, + [CLKID_VPU_1] = &g12a_vpu_1.hw, + [CLKID_VPU] = &g12a_vpu.hw, + [CLKID_VAPB_0_SEL] = &g12a_vapb_0_sel.hw, + [CLKID_VAPB_0_DIV] = &g12a_vapb_0_div.hw, + [CLKID_VAPB_0] = &g12a_vapb_0.hw, + [CLKID_VAPB_1_SEL] = &g12a_vapb_1_sel.hw, + [CLKID_VAPB_1_DIV] = &g12a_vapb_1_div.hw, + [CLKID_VAPB_1] = &g12a_vapb_1.hw, + [CLKID_VAPB_SEL] = &g12a_vapb_sel.hw, + [CLKID_VAPB] = &g12a_vapb.hw, + [CLKID_HDMI_PLL_DCO] = &g12a_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &g12a_hdmi_pll_od.hw, + [CLKID_HDMI_PLL_OD2] = &g12a_hdmi_pll_od2.hw, + [CLKID_HDMI_PLL] = &g12a_hdmi_pll.hw, + [CLKID_VID_PLL] = &g12a_vid_pll_div.hw, + [CLKID_VID_PLL_SEL] = &g12a_vid_pll_sel.hw, + [CLKID_VID_PLL_DIV] = &g12a_vid_pll.hw, + [CLKID_VCLK_SEL] = &g12a_vclk_sel.hw, + [CLKID_VCLK2_SEL] = &g12a_vclk2_sel.hw, + [CLKID_VCLK_INPUT] = &g12a_vclk_input.hw, + [CLKID_VCLK2_INPUT] = &g12a_vclk2_input.hw, + [CLKID_VCLK_DIV] = &g12a_vclk_div.hw, + [CLKID_VCLK2_DIV] = &g12a_vclk2_div.hw, + [CLKID_VCLK] = &g12a_vclk.hw, + [CLKID_VCLK2] = &g12a_vclk2.hw, + [CLKID_VCLK_DIV1] = &g12a_vclk_div1.hw, + [CLKID_VCLK_DIV2_EN] = &g12a_vclk_div2_en.hw, + [CLKID_VCLK_DIV4_EN] = &g12a_vclk_div4_en.hw, + [CLKID_VCLK_DIV6_EN] = &g12a_vclk_div6_en.hw, + [CLKID_VCLK_DIV12_EN] = &g12a_vclk_div12_en.hw, + [CLKID_VCLK2_DIV1] = &g12a_vclk2_div1.hw, + [CLKID_VCLK2_DIV2_EN] = &g12a_vclk2_div2_en.hw, + [CLKID_VCLK2_DIV4_EN] = &g12a_vclk2_div4_en.hw, + [CLKID_VCLK2_DIV6_EN] = &g12a_vclk2_div6_en.hw, + [CLKID_VCLK2_DIV12_EN] = &g12a_vclk2_div12_en.hw, + [CLKID_VCLK_DIV2] = &g12a_vclk_div2.hw, + [CLKID_VCLK_DIV4] = &g12a_vclk_div4.hw, + [CLKID_VCLK_DIV6] = &g12a_vclk_div6.hw, + [CLKID_VCLK_DIV12] = &g12a_vclk_div12.hw, + [CLKID_VCLK2_DIV2] = &g12a_vclk2_div2.hw, + [CLKID_VCLK2_DIV4] = &g12a_vclk2_div4.hw, + [CLKID_VCLK2_DIV6] = &g12a_vclk2_div6.hw, + [CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw, + [CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw, + [CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw, + [CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw, + [CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw, + [CLKID_CTS_ENCI] = &g12a_cts_enci.hw, + [CLKID_CTS_ENCP] = &g12a_cts_encp.hw, + [CLKID_CTS_VDAC] = &g12a_cts_vdac.hw, + [CLKID_HDMI_TX] = &g12a_hdmi_tx.hw, + [CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw, + [CLKID_HDMI_DIV] = &g12a_hdmi_div.hw, + [CLKID_HDMI] = &g12a_hdmi.hw, + [CLKID_MALI_0_SEL] = &g12a_mali_0_sel.hw, + [CLKID_MALI_0_DIV] = &g12a_mali_0_div.hw, + [CLKID_MALI_0] = &g12a_mali_0.hw, + [CLKID_MALI_1_SEL] = &g12a_mali_1_sel.hw, + [CLKID_MALI_1_DIV] = &g12a_mali_1_div.hw, + [CLKID_MALI_1] = &g12a_mali_1.hw, + [CLKID_MALI] = &g12a_mali.hw, + [CLKID_MPLL_50M_DIV] = &g12a_mpll_50m_div.hw, + [CLKID_MPLL_50M] = &g12a_mpll_50m.hw, + [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en.hw, + [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16.hw, + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0.hw, + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div.hw, + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0.hw, + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1.hw, + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div.hw, + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1.hw, + [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn.hw, + [CLKID_CPU_CLK] = &g12a_cpu_clk.hw, + [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en.hw, + [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16.hw, + [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div.hw, + [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb.hw, + [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div.hw, + [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb.hw, + [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div.hw, + [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi.hw, + [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div.hw, + [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace.hw, + [CLKID_PCIE_PLL_DCO] = &g12a_pcie_pll_dco.hw, + [CLKID_PCIE_PLL_DCO_DIV2] = &g12a_pcie_pll_dco_div2.hw, + [CLKID_PCIE_PLL_OD] = &g12a_pcie_pll_od.hw, + [CLKID_PCIE_PLL] = &g12a_pcie_pll.hw, + [CLKID_VDEC_1_SEL] = &g12a_vdec_1_sel.hw, + [CLKID_VDEC_1_DIV] = &g12a_vdec_1_div.hw, + [CLKID_VDEC_1] = &g12a_vdec_1.hw, + [CLKID_VDEC_HEVC_SEL] = &g12a_vdec_hevc_sel.hw, + [CLKID_VDEC_HEVC_DIV] = &g12a_vdec_hevc_div.hw, + [CLKID_VDEC_HEVC] = &g12a_vdec_hevc.hw, + [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel.hw, + [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div.hw, + [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, + [CLKID_TS_DIV] = &g12a_ts_div.hw, + [CLKID_TS] = &g12a_ts.hw, + [CLKID_GP1_PLL_DCO] = &sm1_gp1_pll_dco.hw, + [CLKID_GP1_PLL] = &sm1_gp1_pll.hw, + [NR_CLKS] = NULL, + }, + .num = NR_CLKS, +}; + /* Convenience table to populate regmap in .probe */ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12a_clk81, @@ -4336,6 +4621,8 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12b_cpub_clk_axi, &g12b_cpub_clk_trace_sel, &g12b_cpub_clk_trace, + &sm1_gp1_pll_dco, + &sm1_gp1_pll, }; static const struct reg_sequence g12a_init_regs[] = { @@ -4532,6 +4819,15 @@ static const struct meson_g12a_data g12b_clkc_data = { .dvfs_setup = meson_g12b_dvfs_setup, }; +static const struct meson_g12a_data sm1_clkc_data = { + .eeclkc_data = { + .regmap_clks = g12a_clk_regmaps, + .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps), + .hw_onecell_data = &sm1_hw_onecell_data, + }, + .dvfs_setup = meson_g12a_dvfs_setup, +}; + static const struct of_device_id clkc_match_table[] = { { .compatible = "amlogic,g12a-clkc", @@ -4541,6 +4837,10 @@ static const struct of_device_id clkc_match_table[] = { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data.eeclkc_data }, + { + .compatible = "amlogic,sm1-clkc", + .data = &sm1_clkc_data.eeclkc_data + }, {} }; diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index 559a34cfdfeb..e426b4121b7a 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -29,6 +29,14 @@ #define HHI_GP0_PLL_CNTL5 0x054 #define HHI_GP0_PLL_CNTL6 0x058 #define HHI_GP0_PLL_STS 0x05C +#define HHI_GP1_PLL_CNTL0 0x060 +#define HHI_GP1_PLL_CNTL1 0x064 +#define HHI_GP1_PLL_CNTL2 0x068 +#define HHI_GP1_PLL_CNTL3 0x06C +#define HHI_GP1_PLL_CNTL4 0x070 +#define HHI_GP1_PLL_CNTL5 0x074 +#define HHI_GP1_PLL_CNTL6 0x078 +#define HHI_GP1_PLL_STS 0x07C #define HHI_PCIE_PLL_CNTL0 0x098 #define HHI_PCIE_PLL_CNTL1 0x09C #define HHI_PCIE_PLL_CNTL2 0x0A0 @@ -233,8 +241,9 @@ #define CLKID_CPUB_CLK_AXI 239 #define CLKID_CPUB_CLK_TRACE_SEL 240 #define CLKID_CPUB_CLK_TRACE 241 +#define CLKID_GP1_PLL_DCO 242 -#define NR_CLKS 242 +#define NR_CLKS 244 /* include the CLKIDs that have been made part of the DT binding */ #include From 2edccd319fdef9bc35c06fe4150b21099ac99579 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 26 Aug 2019 09:25:37 +0200 Subject: [PATCH 37/62] clk: meson: g12a: add support for SM1 DynamIQ Shared Unit clock The Amlogic SM1 DynamIQ Shared Unit has a dedicated clock tree similar to the CPU clock tree with a supplementaty mux to select the CPU0 clock instead. Leave this as read-only since it's set up by the early boot stages. Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 184 +++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/g12a.h | 15 +++- 2 files changed, 198 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 34dfac4b4dc6..e00df17f800a 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -676,6 +676,172 @@ static struct clk_regmap g12b_cpub_clk = { }, }; +static struct clk_regmap sm1_gp1_pll; + +/* Datasheet names this field as "premux0" */ +static struct clk_regmap sm1_dsu_clk_premux0 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x3, + .shift = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn0_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &sm1_gp1_pll.hw }, + }, + .num_parents = 4, + }, +}; + +/* Datasheet names this field as "premux1" */ +static struct clk_regmap sm1_dsu_clk_premux1 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn1_sel", + .ops = &clk_regmap_mux_ro_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &g12a_fclk_div2.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &sm1_gp1_pll.hw }, + }, + .num_parents = 4, + }, +}; + +/* Datasheet names this field as "Mux0_divn_tcnt" */ +static struct clk_regmap sm1_dsu_clk_mux0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .shift = 4, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn0_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_dsu_clk_premux0.hw + }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "postmux0" */ +static struct clk_regmap sm1_dsu_clk_postmux0 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x1, + .shift = 2, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn0", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_dsu_clk_premux0.hw, + &sm1_dsu_clk_mux0_div.hw, + }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "Mux1_divn_tcnt" */ +static struct clk_regmap sm1_dsu_clk_mux1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .shift = 20, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn1_div", + .ops = &clk_regmap_divider_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_dsu_clk_premux1.hw + }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "postmux1" */ +static struct clk_regmap sm1_dsu_clk_postmux1 = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x1, + .shift = 18, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn1", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_dsu_clk_premux1.hw, + &sm1_dsu_clk_mux1_div.hw, + }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "Final_dyn_mux_sel" */ +static struct clk_regmap sm1_dsu_clk_dyn = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x1, + .shift = 10, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_dyn", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_dsu_clk_postmux0.hw, + &sm1_dsu_clk_postmux1.hw, + }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "Final_mux_sel" */ +static struct clk_regmap sm1_dsu_final_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL5, + .mask = 0x1, + .shift = 11, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk_final", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &sm1_dsu_clk_dyn.hw, + &g12a_sys_pll.hw, + }, + .num_parents = 2, + }, +}; + +/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 4 */ +static struct clk_regmap sm1_dsu_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL6, + .mask = 0x1, + .shift = 27, + }, + .hw.init = &(struct clk_init_data){ + .name = "dsu_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk.hw, + &sm1_dsu_final_clk.hw, + }, + .num_parents = 2, + }, +}; + static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb, unsigned long event, void *data) { @@ -4401,6 +4567,15 @@ static struct clk_hw_onecell_data sm1_hw_onecell_data = { [CLKID_TS] = &g12a_ts.hw, [CLKID_GP1_PLL_DCO] = &sm1_gp1_pll_dco.hw, [CLKID_GP1_PLL] = &sm1_gp1_pll.hw, + [CLKID_DSU_CLK_DYN0_SEL] = &sm1_dsu_clk_premux0.hw, + [CLKID_DSU_CLK_DYN0_DIV] = &sm1_dsu_clk_premux1.hw, + [CLKID_DSU_CLK_DYN0] = &sm1_dsu_clk_mux0_div.hw, + [CLKID_DSU_CLK_DYN1_SEL] = &sm1_dsu_clk_postmux0.hw, + [CLKID_DSU_CLK_DYN1_DIV] = &sm1_dsu_clk_mux1_div.hw, + [CLKID_DSU_CLK_DYN1] = &sm1_dsu_clk_postmux1.hw, + [CLKID_DSU_CLK_DYN] = &sm1_dsu_clk_dyn.hw, + [CLKID_DSU_CLK_FINAL] = &sm1_dsu_final_clk.hw, + [CLKID_DSU_CLK] = &sm1_dsu_clk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4623,6 +4798,15 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &g12b_cpub_clk_trace, &sm1_gp1_pll_dco, &sm1_gp1_pll, + &sm1_dsu_clk_premux0, + &sm1_dsu_clk_premux1, + &sm1_dsu_clk_mux0_div, + &sm1_dsu_clk_postmux0, + &sm1_dsu_clk_mux1_div, + &sm1_dsu_clk_postmux1, + &sm1_dsu_clk_dyn, + &sm1_dsu_final_clk, + &sm1_dsu_clk, }; static const struct reg_sequence g12a_init_regs[] = { diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index e426b4121b7a..6804fcced6b5 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -80,6 +80,11 @@ #define HHI_SYS_CPUB_CLK_CNTL1 0x200 #define HHI_SYS_CPUB_CLK_CNTL 0x208 #define HHI_VPU_CLKB_CNTL 0x20C +#define HHI_SYS_CPU_CLK_CNTL2 0x210 +#define HHI_SYS_CPU_CLK_CNTL3 0x214 +#define HHI_SYS_CPU_CLK_CNTL4 0x218 +#define HHI_SYS_CPU_CLK_CNTL5 0x21c +#define HHI_SYS_CPU_CLK_CNTL6 0x220 #define HHI_GEN_CLK_CNTL 0x228 #define HHI_VDIN_MEAS_CLK_CNTL 0x250 #define HHI_MIPIDSI_PHY_CLK_CNTL 0x254 @@ -242,8 +247,16 @@ #define CLKID_CPUB_CLK_TRACE_SEL 240 #define CLKID_CPUB_CLK_TRACE 241 #define CLKID_GP1_PLL_DCO 242 +#define CLKID_DSU_CLK_DYN0_SEL 244 +#define CLKID_DSU_CLK_DYN0_DIV 245 +#define CLKID_DSU_CLK_DYN0 246 +#define CLKID_DSU_CLK_DYN1_SEL 247 +#define CLKID_DSU_CLK_DYN1_DIV 248 +#define CLKID_DSU_CLK_DYN1 249 +#define CLKID_DSU_CLK_DYN 250 +#define CLKID_DSU_CLK_FINAL 251 -#define NR_CLKS 244 +#define NR_CLKS 253 /* include the CLKIDs that have been made part of the DT binding */ #include From da3ceae4ec9f581a50dc0763710078f22d3bc72a Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 26 Aug 2019 09:25:38 +0200 Subject: [PATCH 38/62] clk: meson: g12a: add support for SM1 CPU 1, 2 & 3 clocks The Amlogic SM1 can set a dedicated clock frequency for each CPU core by having a dedicate tree for each core similar to the CPU0 tree. Like the DSU tree, a supplementaty mux has been added to use the CPU0 frequency instead. But since the cluster only has a single power rail and shares a single PLL, it's not worth adding 3 unsused clock tree, so we add only the mux to select the CPU0 clock frequency for each CPU1, CPU2 and CPU3 cores. They are set read-only because the early boot stages sets them to select the CPU0 input clock. Signed-off-by: Neil Armstrong Signed-off-by: Jerome Brunet --- drivers/clk/meson/g12a.c | 60 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/meson/g12a.h | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index e00df17f800a..ea4c791f106d 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -824,6 +824,60 @@ static struct clk_regmap sm1_dsu_final_clk = { }, }; +/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 0 */ +static struct clk_regmap sm1_cpu1_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL6, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu1_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk.hw, + /* This CPU also have a dedicated clock tree */ + }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 1 */ +static struct clk_regmap sm1_cpu2_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL6, + .mask = 0x1, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu2_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk.hw, + /* This CPU also have a dedicated clock tree */ + }, + .num_parents = 1, + }, +}; + +/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 2 */ +static struct clk_regmap sm1_cpu3_clk = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SYS_CPU_CLK_CNTL6, + .mask = 0x1, + .shift = 26, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu3_clk", + .ops = &clk_regmap_mux_ro_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_cpu_clk.hw, + /* This CPU also have a dedicated clock tree */ + }, + .num_parents = 1, + }, +}; + /* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 4 */ static struct clk_regmap sm1_dsu_clk = { .data = &(struct clk_regmap_mux_data){ @@ -4576,6 +4630,9 @@ static struct clk_hw_onecell_data sm1_hw_onecell_data = { [CLKID_DSU_CLK_DYN] = &sm1_dsu_clk_dyn.hw, [CLKID_DSU_CLK_FINAL] = &sm1_dsu_final_clk.hw, [CLKID_DSU_CLK] = &sm1_dsu_clk.hw, + [CLKID_CPU1_CLK] = &sm1_cpu1_clk.hw, + [CLKID_CPU2_CLK] = &sm1_cpu2_clk.hw, + [CLKID_CPU3_CLK] = &sm1_cpu3_clk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4807,6 +4864,9 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &sm1_dsu_clk_dyn, &sm1_dsu_final_clk, &sm1_dsu_clk, + &sm1_cpu1_clk, + &sm1_cpu2_clk, + &sm1_cpu3_clk, }; static const struct reg_sequence g12a_init_regs[] = { diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index 6804fcced6b5..9df4068aced1 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -256,7 +256,7 @@ #define CLKID_DSU_CLK_DYN 250 #define CLKID_DSU_CLK_FINAL 251 -#define NR_CLKS 253 +#define NR_CLKS 256 /* include the CLKIDs that have been made part of the DT binding */ #include From 5e4b7e82d497580bc430576c4c9bce157dd72512 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Fri, 30 Aug 2019 12:51:42 -0700 Subject: [PATCH 39/62] clk: qcom: gcc-sdm845: Use floor ops for sdcc clks Some MMC cards fail to enumerate properly when inserted into an MMC slot on sdm845 devices. This is because the clk ops for qcom clks round the frequency up to the nearest rate instead of down to the nearest rate. For example, the MMC driver requests a frequency of 52MHz from clk_set_rate() but the qcom implementation for these clks rounds 52MHz up to the next supported frequency of 100MHz. The MMC driver could be modified to request clk rate ranges but for now we can fix this in the clk driver by changing the rounding policy for this clk to be round down instead of round up. Fixes: 06391eddb60a ("clk: qcom: Add Global Clock controller (GCC) driver for SDM845") Reported-by: Douglas Anderson Cc: Taniya Das Signed-off-by: Stephen Boyd Link: https://lkml.kernel.org/r/20190830195142.103564-1-swboyd@chromium.org Reviewed-by: Douglas Anderson Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-sdm845.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index 7131dcf9b060..95be125c3bdd 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -685,7 +685,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_names = gcc_parent_names_10, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -709,7 +709,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .name = "gcc_sdcc4_apps_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; From 593020811cb0903141649fb6c7c53c442baae90a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 6 Sep 2019 10:26:59 +0530 Subject: [PATCH 40/62] clk: qcom: gcc-qcs404: Use floor ops for sdcc clks Update the gcc qcs404 clock driver to use floor ops for sdcc clocks. As disuccsed in [1] it is good idea to use floor ops for sdcc clocks as we dont want the clock rates to do round up. [1]: https://lore.kernel.org/linux-arm-msm/20190830195142.103564-1-swboyd@chromium.org/ Signed-off-by: Vinod Koul Link: https://lkml.kernel.org/r/20190906045659.20621-1-vkoul@kernel.org Reviewed-by: Bjorn Andersson Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-qcs404.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/gcc-qcs404.c b/drivers/clk/qcom/gcc-qcs404.c index e12c04c09a6a..bd32212f37e6 100644 --- a/drivers/clk/qcom/gcc-qcs404.c +++ b/drivers/clk/qcom/gcc-qcs404.c @@ -1057,7 +1057,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { .name = "sdcc1_apps_clk_src", .parent_names = gcc_parent_names_13, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -1103,7 +1103,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .name = "sdcc2_apps_clk_src", .parent_names = gcc_parent_names_14, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; From 3f905469c8ce7c13ab500b17f5085b53d6cc3f40 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Mon, 9 Sep 2019 13:14:10 +0530 Subject: [PATCH 41/62] clk: qcom: gcc: Use floor ops for SDCC clocks Update global clock controller SDCC2/4 clocks to use the floor rcg ops, so as to use the rounded down clock rates for these clocks. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/20190909074410.18977-1-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-ipq8074.c | 2 +- drivers/clk/qcom/gcc-msm8998.c | 4 ++-- drivers/clk/qcom/gcc-sdm660.c | 2 +- drivers/clk/qcom/gcc-sm8150.c | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c index 39ade58b4ada..e01f5f591d1e 100644 --- a/drivers/clk/qcom/gcc-ipq8074.c +++ b/drivers/clk/qcom/gcc-ipq8074.c @@ -1108,7 +1108,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .name = "sdcc2_apps_clk_src", .parent_names = gcc_xo_gpll0_gpll2_gpll0_out_main_div2, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-msm8998.c b/drivers/clk/qcom/gcc-msm8998.c index 033688264c7b..091acd59c1d6 100644 --- a/drivers/clk/qcom/gcc-msm8998.c +++ b/drivers/clk/qcom/gcc-msm8998.c @@ -1042,7 +1042,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .name = "sdcc2_apps_clk_src", .parent_names = gcc_parent_names_4, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -1066,7 +1066,7 @@ static struct clk_rcg2 sdcc4_apps_clk_src = { .name = "sdcc4_apps_clk_src", .parent_names = gcc_parent_names_1, .num_parents = 3, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c index 8827db23066f..bf5730832ef3 100644 --- a/drivers/clk/qcom/gcc-sdm660.c +++ b/drivers/clk/qcom/gcc-sdm660.c @@ -787,7 +787,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .name = "sdcc2_apps_clk_src", .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm8150.c b/drivers/clk/qcom/gcc-sm8150.c index 12ca2d14797f..20877214acff 100644 --- a/drivers/clk/qcom/gcc-sm8150.c +++ b/drivers/clk/qcom/gcc-sm8150.c @@ -803,7 +803,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parents_6, .num_parents = 5, .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -828,7 +828,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parents_3, .num_parents = 3, .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; From 8c758d667584b5462cba6fd7b56b8798ea36f7b8 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 26 Aug 2019 23:01:17 +0530 Subject: [PATCH 42/62] dt-bindings: clock: Document the parent clocks With clock parent data scheme we must specify the parent clocks for the rpmhcc nodes. So describe the parent clock for rpmhcc in the bindings. Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lkml.kernel.org/r/20190826173120.2971-2-vkoul@kernel.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt index 3c007653da31..8b97968f9c88 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt @@ -9,6 +9,9 @@ Required properties : - compatible : shall contain "qcom,sdm845-rpmh-clk" - #clock-cells : must contain 1 +- clocks: a list of phandles and clock-specifier pairs, + one for each entry in clock-names. +- clock-names: Parent board clock: "xo". Example : From a64a9e5172f8551b48883eed2e2c5816180542b0 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 26 Aug 2019 23:01:18 +0530 Subject: [PATCH 43/62] clk: qcom: clk-rpmh: Convert to parent data scheme Convert the rpmh clock driver to use the new parent data scheme by specifying the parent data for board clock. Signed-off-by: Vinod Koul Link: https://lkml.kernel.org/r/20190826173120.2971-3-vkoul@kernel.org Reviewed-by: Bjorn Andersson Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rpmh.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index c3fd632af119..35d55aee6a01 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -95,7 +95,10 @@ static DEFINE_MUTEX(rpmh_clk_lock); .hw.init = &(struct clk_init_data){ \ .ops = &clk_rpmh_ops, \ .name = #_name, \ - .parent_names = (const char *[]){ "xo_board" }, \ + .parent_data = &(const struct clk_parent_data){ \ + .fw_name = "xo", \ + .name = "xo_board", \ + }, \ .num_parents = 1, \ }, \ }; \ @@ -110,7 +113,10 @@ static DEFINE_MUTEX(rpmh_clk_lock); .hw.init = &(struct clk_init_data){ \ .ops = &clk_rpmh_ops, \ .name = #_name_active, \ - .parent_names = (const char *[]){ "xo_board" }, \ + .parent_data = &(const struct clk_parent_data){ \ + .fw_name = "xo", \ + .name = "xo_board", \ + }, \ .num_parents = 1, \ }, \ } From 51ffc35d68d429ee0f4c700dbde60fb8c4278c99 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 26 Aug 2019 23:01:19 +0530 Subject: [PATCH 44/62] dt-bindings: clock: Document SM8150 rpmh-clock compatible Document the SM8150 rpmh-clock compatible for rpmh clock controller found on SM8150 platforms. Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lkml.kernel.org/r/20190826173120.2971-4-vkoul@kernel.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt index 8b97968f9c88..365bbde599b1 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmh-clk.txt @@ -6,7 +6,9 @@ some Qualcomm Technologies Inc. SoCs. It accepts clock requests from other hardware subsystems via RSC to control clocks. Required properties : -- compatible : shall contain "qcom,sdm845-rpmh-clk" +- compatible : must be one of: + "qcom,sdm845-rpmh-clk" + "qcom,sm8150-rpmh-clk" - #clock-cells : must contain 1 - clocks: a list of phandles and clock-specifier pairs, From 2243fd4186a94a7b47d0885d669afe0a3489a1cb Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 26 Aug 2019 23:01:20 +0530 Subject: [PATCH 45/62] clk: qcom: clk-rpmh: Add support for SM8150 Add support for rpmh clocks found in SM8150 Signed-off-by: Vinod Koul Reviewed-by: Bjorn Andersson Link: https://lkml.kernel.org/r/20190826173120.2971-5-vkoul@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rpmh.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 35d55aee6a01..49694082e9ec 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -374,6 +374,33 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = { .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks), }; +DEFINE_CLK_RPMH_ARC(sm8150, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); +DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); +DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); +DEFINE_CLK_RPMH_VRM(sm8150, rf_clk1, rf_clk1_ao, "rfclka1", 1); +DEFINE_CLK_RPMH_VRM(sm8150, rf_clk2, rf_clk2_ao, "rfclka2", 1); +DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1); + +static struct clk_hw *sm8150_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &sm8150_bi_tcxo.hw, + [RPMH_CXO_CLK_A] = &sm8150_bi_tcxo_ao.hw, + [RPMH_LN_BB_CLK2] = &sm8150_ln_bb_clk2.hw, + [RPMH_LN_BB_CLK2_A] = &sm8150_ln_bb_clk2_ao.hw, + [RPMH_LN_BB_CLK3] = &sm8150_ln_bb_clk3.hw, + [RPMH_LN_BB_CLK3_A] = &sm8150_ln_bb_clk3_ao.hw, + [RPMH_RF_CLK1] = &sm8150_rf_clk1.hw, + [RPMH_RF_CLK1_A] = &sm8150_rf_clk1_ao.hw, + [RPMH_RF_CLK2] = &sm8150_rf_clk2.hw, + [RPMH_RF_CLK2_A] = &sm8150_rf_clk2_ao.hw, + [RPMH_RF_CLK3] = &sm8150_rf_clk3.hw, + [RPMH_RF_CLK3_A] = &sm8150_rf_clk3_ao.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_sm8150 = { + .clks = sm8150_rpmh_clocks, + .num_clks = ARRAY_SIZE(sm8150_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -453,6 +480,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, + { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, { } }; MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); From 3bcff3e45bc0d0d18ac1df7145d37323b82caf88 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Mon, 9 Sep 2019 10:54:30 +0200 Subject: [PATCH 46/62] clk: qcom: fix QCS404 TuringCC regmap The max register is 0x23004 as per the manual (the current max_register that this commit is fixing is actually out of bounds). Fixes: 892df0191b29 ("clk: qcom: Add QCS404 TuringCC") Signed-off-by: Jorge Ramirez-Ortiz Link: https://lkml.kernel.org/r/20190909085430.8700-1-jorge.ramirez-ortiz@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/turingcc-qcs404.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/turingcc-qcs404.c b/drivers/clk/qcom/turingcc-qcs404.c index aa859e6ec9bd..4cfbbf5bf4d9 100644 --- a/drivers/clk/qcom/turingcc-qcs404.c +++ b/drivers/clk/qcom/turingcc-qcs404.c @@ -96,7 +96,7 @@ static const struct regmap_config turingcc_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x30000, + .max_register = 0x23004, .fast_io = true, }; From 171f68a3b27aa76d42c566bc869c829671497f5e Mon Sep 17 00:00:00 2001 From: mtk01761 Date: Mon, 19 Aug 2019 17:21:39 +0800 Subject: [PATCH 47/62] dt-bindings: mediatek: bindings for MT6779 clk This patch adds the binding documentation for apmixedsys, audiosys, camsys, imgsys, ipesys, infracfg, mfgcfg, mmsys, topckgen, vdecsys, and vencsys for Mediatek MT6779. Signed-off-by: mtk01761 Link: https://lkml.kernel.org/r/1566206502-4347-9-git-send-email-mars.cheng@mediatek.com Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../arm/mediatek/mediatek,apmixedsys.txt | 1 + .../bindings/arm/mediatek/mediatek,audsys.txt | 1 + .../bindings/arm/mediatek/mediatek,camsys.txt | 1 + .../bindings/arm/mediatek/mediatek,imgsys.txt | 1 + .../arm/mediatek/mediatek,infracfg.txt | 1 + .../bindings/arm/mediatek/mediatek,ipesys.txt | 22 +++++++++++++++++++ .../bindings/arm/mediatek/mediatek,mfgcfg.txt | 1 + .../bindings/arm/mediatek/mediatek,mmsys.txt | 1 + .../arm/mediatek/mediatek,topckgen.txt | 1 + .../arm/mediatek/mediatek,vdecsys.txt | 1 + .../arm/mediatek/mediatek,vencsys.txt | 1 + 11 files changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt index 161e63a6c254..ff000ccade78 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-apmixedsys" - "mediatek,mt2712-apmixedsys", "syscon" + - "mediatek,mt6779-apmixedsys", "syscon" - "mediatek,mt6797-apmixedsys" - "mediatek,mt7622-apmixedsys" - "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt index 07c9d813465c..e4ca7b703123 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-audsys", "syscon" + - "mediatek,mt6779-audio", "syscon" - "mediatek,mt7622-audsys", "syscon" - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon" - "mediatek,mt8183-audiosys", "syscon" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt index d8930f64aa98..1f4aaa15a37e 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,camsys.txt @@ -6,6 +6,7 @@ The MediaTek camsys controller provides various clocks to the system. Required Properties: - compatible: Should be one of: + - "mediatek,mt6779-camsys", "syscon" - "mediatek,mt8183-camsys", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt index e3bc4a1e7a6e..2b693e343c56 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-imgsys", "syscon" - "mediatek,mt2712-imgsys", "syscon" + - "mediatek,mt6779-imgsys", "syscon" - "mediatek,mt6797-imgsys", "syscon" - "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon" - "mediatek,mt8173-imgsys", "syscon" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt index a90913988d7e..db2f4fd754e7 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt @@ -9,6 +9,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-infracfg", "syscon" - "mediatek,mt2712-infracfg", "syscon" + - "mediatek,mt6779-infracfg_ao", "syscon" - "mediatek,mt6797-infracfg", "syscon" - "mediatek,mt7622-infracfg", "syscon" - "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt new file mode 100644 index 000000000000..2ce889b023d9 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ipesys.txt @@ -0,0 +1,22 @@ +Mediatek ipesys controller +============================ + +The Mediatek ipesys controller provides various clocks to the system. + +Required Properties: + +- compatible: Should be one of: + - "mediatek,mt6779-ipesys", "syscon" +- #clock-cells: Must be 1 + +The ipesys controller uses the common clk binding from +Documentation/devicetree/bindings/clock/clock-bindings.txt +The available clocks are defined in dt-bindings/clock/mt*-clk.h. + +Example: + +ipesys: clock-controller@1b000000 { + compatible = "mediatek,mt6779-ipesys", "syscon"; + reg = <0 0x1b000000 0 0x1000>; + #clock-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt index 72787e7dd227..ad5f9d2f6818 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mfgcfg.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2712-mfgcfg", "syscon" + - "mediatek,mt6779-mfgcfg", "syscon" - "mediatek,mt8183-mfgcfg", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt index 545eab717c96..301eefbe1618 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-mmsys", "syscon" - "mediatek,mt2712-mmsys", "syscon" + - "mediatek,mt6779-mmsys", "syscon" - "mediatek,mt6797-mmsys", "syscon" - "mediatek,mt7623-mmsys", "mediatek,mt2701-mmsys", "syscon" - "mediatek,mt8173-mmsys", "syscon" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt index a023b8338960..0293d693ce0c 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-topckgen" - "mediatek,mt2712-topckgen", "syscon" + - "mediatek,mt6779-topckgen", "syscon" - "mediatek,mt6797-topckgen" - "mediatek,mt7622-topckgen" - "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt index 57176bb8dbb5..7894558b7a1c 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2701-vdecsys", "syscon" - "mediatek,mt2712-vdecsys", "syscon" + - "mediatek,mt6779-vdecsys", "syscon" - "mediatek,mt6797-vdecsys", "syscon" - "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon" - "mediatek,mt8173-vdecsys", "syscon" diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt index c9faa6269087..6a6a14e15cd7 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: Should be one of: - "mediatek,mt2712-vencsys", "syscon" + - "mediatek,mt6779-vencsys", "syscon" - "mediatek,mt6797-vencsys", "syscon" - "mediatek,mt8173-vencsys", "syscon" - "mediatek,mt8183-vencsys", "syscon" From 85b18fe7049466cb15e7d33b51aa51854e0e05e7 Mon Sep 17 00:00:00 2001 From: mtk01761 Date: Mon, 19 Aug 2019 17:21:40 +0800 Subject: [PATCH 48/62] clk: mediatek: Add dt-bindings for MT6779 clocks Add MT6779 clock dt-bindings, include topckgen, apmixedsys, infracfg, and subsystem clocks. Signed-off-by: mtk01761 Link: https://lkml.kernel.org/r/1566206502-4347-10-git-send-email-mars.cheng@mediatek.com Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/mt6779-clk.h | 436 +++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 include/dt-bindings/clock/mt6779-clk.h diff --git a/include/dt-bindings/clock/mt6779-clk.h b/include/dt-bindings/clock/mt6779-clk.h new file mode 100644 index 000000000000..b083139afbd2 --- /dev/null +++ b/include/dt-bindings/clock/mt6779-clk.h @@ -0,0 +1,436 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#ifndef _DT_BINDINGS_CLK_MT6779_H +#define _DT_BINDINGS_CLK_MT6779_H + +/* TOPCKGEN */ +#define CLK_TOP_AXI 1 +#define CLK_TOP_MM 2 +#define CLK_TOP_CAM 3 +#define CLK_TOP_MFG 4 +#define CLK_TOP_CAMTG 5 +#define CLK_TOP_UART 6 +#define CLK_TOP_SPI 7 +#define CLK_TOP_MSDC50_0_HCLK 8 +#define CLK_TOP_MSDC50_0 9 +#define CLK_TOP_MSDC30_1 10 +#define CLK_TOP_MSDC30_2 11 +#define CLK_TOP_AUD 12 +#define CLK_TOP_AUD_INTBUS 13 +#define CLK_TOP_FPWRAP_ULPOSC 14 +#define CLK_TOP_SCP 15 +#define CLK_TOP_ATB 16 +#define CLK_TOP_SSPM 17 +#define CLK_TOP_DPI0 18 +#define CLK_TOP_SCAM 19 +#define CLK_TOP_AUD_1 20 +#define CLK_TOP_AUD_2 21 +#define CLK_TOP_DISP_PWM 22 +#define CLK_TOP_SSUSB_TOP_XHCI 23 +#define CLK_TOP_USB_TOP 24 +#define CLK_TOP_SPM 25 +#define CLK_TOP_I2C 26 +#define CLK_TOP_F52M_MFG 27 +#define CLK_TOP_SENINF 28 +#define CLK_TOP_DXCC 29 +#define CLK_TOP_CAMTG2 30 +#define CLK_TOP_AUD_ENG1 31 +#define CLK_TOP_AUD_ENG2 32 +#define CLK_TOP_FAES_UFSFDE 33 +#define CLK_TOP_FUFS 34 +#define CLK_TOP_IMG 35 +#define CLK_TOP_DSP 36 +#define CLK_TOP_DSP1 37 +#define CLK_TOP_DSP2 38 +#define CLK_TOP_IPU_IF 39 +#define CLK_TOP_CAMTG3 40 +#define CLK_TOP_CAMTG4 41 +#define CLK_TOP_PMICSPI 42 +#define CLK_TOP_MAINPLL_CK 43 +#define CLK_TOP_MAINPLL_D2 44 +#define CLK_TOP_MAINPLL_D3 45 +#define CLK_TOP_MAINPLL_D5 46 +#define CLK_TOP_MAINPLL_D7 47 +#define CLK_TOP_MAINPLL_D2_D2 48 +#define CLK_TOP_MAINPLL_D2_D4 49 +#define CLK_TOP_MAINPLL_D2_D8 50 +#define CLK_TOP_MAINPLL_D2_D16 51 +#define CLK_TOP_MAINPLL_D3_D2 52 +#define CLK_TOP_MAINPLL_D3_D4 53 +#define CLK_TOP_MAINPLL_D3_D8 54 +#define CLK_TOP_MAINPLL_D5_D2 55 +#define CLK_TOP_MAINPLL_D5_D4 56 +#define CLK_TOP_MAINPLL_D7_D2 57 +#define CLK_TOP_MAINPLL_D7_D4 58 +#define CLK_TOP_UNIVPLL_CK 59 +#define CLK_TOP_UNIVPLL_D2 60 +#define CLK_TOP_UNIVPLL_D3 61 +#define CLK_TOP_UNIVPLL_D5 62 +#define CLK_TOP_UNIVPLL_D7 63 +#define CLK_TOP_UNIVPLL_D2_D2 64 +#define CLK_TOP_UNIVPLL_D2_D4 65 +#define CLK_TOP_UNIVPLL_D2_D8 66 +#define CLK_TOP_UNIVPLL_D3_D2 67 +#define CLK_TOP_UNIVPLL_D3_D4 68 +#define CLK_TOP_UNIVPLL_D3_D8 69 +#define CLK_TOP_UNIVPLL_D5_D2 70 +#define CLK_TOP_UNIVPLL_D5_D4 71 +#define CLK_TOP_UNIVPLL_D5_D8 72 +#define CLK_TOP_APLL1_CK 73 +#define CLK_TOP_APLL1_D2 74 +#define CLK_TOP_APLL1_D4 75 +#define CLK_TOP_APLL1_D8 76 +#define CLK_TOP_APLL2_CK 77 +#define CLK_TOP_APLL2_D2 78 +#define CLK_TOP_APLL2_D4 79 +#define CLK_TOP_APLL2_D8 80 +#define CLK_TOP_TVDPLL_CK 81 +#define CLK_TOP_TVDPLL_D2 82 +#define CLK_TOP_TVDPLL_D4 83 +#define CLK_TOP_TVDPLL_D8 84 +#define CLK_TOP_TVDPLL_D16 85 +#define CLK_TOP_MSDCPLL_CK 86 +#define CLK_TOP_MSDCPLL_D2 87 +#define CLK_TOP_MSDCPLL_D4 88 +#define CLK_TOP_MSDCPLL_D8 89 +#define CLK_TOP_MSDCPLL_D16 90 +#define CLK_TOP_AD_OSC_CK 91 +#define CLK_TOP_OSC_D2 92 +#define CLK_TOP_OSC_D4 93 +#define CLK_TOP_OSC_D8 94 +#define CLK_TOP_OSC_D16 95 +#define CLK_TOP_F26M_CK_D2 96 +#define CLK_TOP_MFGPLL_CK 97 +#define CLK_TOP_UNIVP_192M_CK 98 +#define CLK_TOP_UNIVP_192M_D2 99 +#define CLK_TOP_UNIVP_192M_D4 100 +#define CLK_TOP_UNIVP_192M_D8 101 +#define CLK_TOP_UNIVP_192M_D16 102 +#define CLK_TOP_UNIVP_192M_D32 103 +#define CLK_TOP_MMPLL_CK 104 +#define CLK_TOP_MMPLL_D4 105 +#define CLK_TOP_MMPLL_D4_D2 106 +#define CLK_TOP_MMPLL_D4_D4 107 +#define CLK_TOP_MMPLL_D5 108 +#define CLK_TOP_MMPLL_D5_D2 109 +#define CLK_TOP_MMPLL_D5_D4 110 +#define CLK_TOP_MMPLL_D6 111 +#define CLK_TOP_MMPLL_D7 112 +#define CLK_TOP_CLK26M 113 +#define CLK_TOP_CLK13M 114 +#define CLK_TOP_ADSP 115 +#define CLK_TOP_DPMAIF 116 +#define CLK_TOP_VENC 117 +#define CLK_TOP_VDEC 118 +#define CLK_TOP_CAMTM 119 +#define CLK_TOP_PWM 120 +#define CLK_TOP_ADSPPLL_CK 121 +#define CLK_TOP_I2S0_M_SEL 122 +#define CLK_TOP_I2S1_M_SEL 123 +#define CLK_TOP_I2S2_M_SEL 124 +#define CLK_TOP_I2S3_M_SEL 125 +#define CLK_TOP_I2S4_M_SEL 126 +#define CLK_TOP_I2S5_M_SEL 127 +#define CLK_TOP_APLL12_DIV0 128 +#define CLK_TOP_APLL12_DIV1 129 +#define CLK_TOP_APLL12_DIV2 130 +#define CLK_TOP_APLL12_DIV3 131 +#define CLK_TOP_APLL12_DIV4 132 +#define CLK_TOP_APLL12_DIVB 133 +#define CLK_TOP_APLL12_DIV5 134 +#define CLK_TOP_IPE 135 +#define CLK_TOP_DPE 136 +#define CLK_TOP_CCU 137 +#define CLK_TOP_DSP3 138 +#define CLK_TOP_SENINF1 139 +#define CLK_TOP_SENINF2 140 +#define CLK_TOP_AUD_H 141 +#define CLK_TOP_CAMTG5 142 +#define CLK_TOP_TVDPLL_MAINPLL_D2_CK 143 +#define CLK_TOP_AD_OSC2_CK 144 +#define CLK_TOP_OSC2_D2 145 +#define CLK_TOP_OSC2_D3 146 +#define CLK_TOP_FMEM_466M_CK 147 +#define CLK_TOP_ADSPPLL_D4 148 +#define CLK_TOP_ADSPPLL_D5 149 +#define CLK_TOP_ADSPPLL_D6 150 +#define CLK_TOP_OSC_D10 151 +#define CLK_TOP_UNIVPLL_D3_D16 152 +#define CLK_TOP_NR_CLK 153 + +/* APMIXED */ +#define CLK_APMIXED_ARMPLL_LL 1 +#define CLK_APMIXED_ARMPLL_BL 2 +#define CLK_APMIXED_ARMPLL_BB 3 +#define CLK_APMIXED_CCIPLL 4 +#define CLK_APMIXED_MAINPLL 5 +#define CLK_APMIXED_UNIV2PLL 6 +#define CLK_APMIXED_MSDCPLL 7 +#define CLK_APMIXED_ADSPPLL 8 +#define CLK_APMIXED_MMPLL 9 +#define CLK_APMIXED_MFGPLL 10 +#define CLK_APMIXED_TVDPLL 11 +#define CLK_APMIXED_APLL1 12 +#define CLK_APMIXED_APLL2 13 +#define CLK_APMIXED_SSUSB26M 14 +#define CLK_APMIXED_APPLL26M 15 +#define CLK_APMIXED_MIPIC0_26M 16 +#define CLK_APMIXED_MDPLLGP26M 17 +#define CLK_APMIXED_MM_F26M 18 +#define CLK_APMIXED_UFS26M 19 +#define CLK_APMIXED_MIPIC1_26M 20 +#define CLK_APMIXED_MEMPLL26M 21 +#define CLK_APMIXED_CLKSQ_LVPLL_26M 22 +#define CLK_APMIXED_MIPID0_26M 23 +#define CLK_APMIXED_MIPID1_26M 24 +#define CLK_APMIXED_NR_CLK 25 + +/* CAMSYS */ +#define CLK_CAM_LARB10 1 +#define CLK_CAM_DFP_VAD 2 +#define CLK_CAM_LARB11 3 +#define CLK_CAM_LARB9 4 +#define CLK_CAM_CAM 5 +#define CLK_CAM_CAMTG 6 +#define CLK_CAM_SENINF 7 +#define CLK_CAM_CAMSV0 8 +#define CLK_CAM_CAMSV1 9 +#define CLK_CAM_CAMSV2 10 +#define CLK_CAM_CAMSV3 11 +#define CLK_CAM_CCU 12 +#define CLK_CAM_FAKE_ENG 13 +#define CLK_CAM_NR_CLK 14 + +/* INFRA */ +#define CLK_INFRA_PMIC_TMR 1 +#define CLK_INFRA_PMIC_AP 2 +#define CLK_INFRA_PMIC_MD 3 +#define CLK_INFRA_PMIC_CONN 4 +#define CLK_INFRA_SCPSYS 5 +#define CLK_INFRA_SEJ 6 +#define CLK_INFRA_APXGPT 7 +#define CLK_INFRA_ICUSB 8 +#define CLK_INFRA_GCE 9 +#define CLK_INFRA_THERM 10 +#define CLK_INFRA_I2C0 11 +#define CLK_INFRA_I2C1 12 +#define CLK_INFRA_I2C2 13 +#define CLK_INFRA_I2C3 14 +#define CLK_INFRA_PWM_HCLK 15 +#define CLK_INFRA_PWM1 16 +#define CLK_INFRA_PWM2 17 +#define CLK_INFRA_PWM3 18 +#define CLK_INFRA_PWM4 19 +#define CLK_INFRA_PWM 20 +#define CLK_INFRA_UART0 21 +#define CLK_INFRA_UART1 22 +#define CLK_INFRA_UART2 23 +#define CLK_INFRA_UART3 24 +#define CLK_INFRA_GCE_26M 25 +#define CLK_INFRA_CQ_DMA_FPC 26 +#define CLK_INFRA_BTIF 27 +#define CLK_INFRA_SPI0 28 +#define CLK_INFRA_MSDC0 29 +#define CLK_INFRA_MSDC1 30 +#define CLK_INFRA_MSDC2 31 +#define CLK_INFRA_MSDC0_SCK 32 +#define CLK_INFRA_DVFSRC 33 +#define CLK_INFRA_GCPU 34 +#define CLK_INFRA_TRNG 35 +#define CLK_INFRA_AUXADC 36 +#define CLK_INFRA_CPUM 37 +#define CLK_INFRA_CCIF1_AP 38 +#define CLK_INFRA_CCIF1_MD 39 +#define CLK_INFRA_AUXADC_MD 40 +#define CLK_INFRA_MSDC1_SCK 41 +#define CLK_INFRA_MSDC2_SCK 42 +#define CLK_INFRA_AP_DMA 43 +#define CLK_INFRA_XIU 44 +#define CLK_INFRA_DEVICE_APC 45 +#define CLK_INFRA_CCIF_AP 46 +#define CLK_INFRA_DEBUGSYS 47 +#define CLK_INFRA_AUD 48 +#define CLK_INFRA_CCIF_MD 49 +#define CLK_INFRA_DXCC_SEC_CORE 50 +#define CLK_INFRA_DXCC_AO 51 +#define CLK_INFRA_DRAMC_F26M 52 +#define CLK_INFRA_IRTX 53 +#define CLK_INFRA_DISP_PWM 54 +#define CLK_INFRA_DPMAIF_CK 55 +#define CLK_INFRA_AUD_26M_BCLK 56 +#define CLK_INFRA_SPI1 57 +#define CLK_INFRA_I2C4 58 +#define CLK_INFRA_MODEM_TEMP_SHARE 59 +#define CLK_INFRA_SPI2 60 +#define CLK_INFRA_SPI3 61 +#define CLK_INFRA_UNIPRO_SCK 62 +#define CLK_INFRA_UNIPRO_TICK 63 +#define CLK_INFRA_UFS_MP_SAP_BCLK 64 +#define CLK_INFRA_MD32_BCLK 65 +#define CLK_INFRA_SSPM 66 +#define CLK_INFRA_UNIPRO_MBIST 67 +#define CLK_INFRA_SSPM_BUS_HCLK 68 +#define CLK_INFRA_I2C5 69 +#define CLK_INFRA_I2C5_ARBITER 70 +#define CLK_INFRA_I2C5_IMM 71 +#define CLK_INFRA_I2C1_ARBITER 72 +#define CLK_INFRA_I2C1_IMM 73 +#define CLK_INFRA_I2C2_ARBITER 74 +#define CLK_INFRA_I2C2_IMM 75 +#define CLK_INFRA_SPI4 76 +#define CLK_INFRA_SPI5 77 +#define CLK_INFRA_CQ_DMA 78 +#define CLK_INFRA_UFS 79 +#define CLK_INFRA_AES_UFSFDE 80 +#define CLK_INFRA_UFS_TICK 81 +#define CLK_INFRA_MSDC0_SELF 82 +#define CLK_INFRA_MSDC1_SELF 83 +#define CLK_INFRA_MSDC2_SELF 84 +#define CLK_INFRA_SSPM_26M_SELF 85 +#define CLK_INFRA_SSPM_32K_SELF 86 +#define CLK_INFRA_UFS_AXI 87 +#define CLK_INFRA_I2C6 88 +#define CLK_INFRA_AP_MSDC0 89 +#define CLK_INFRA_MD_MSDC0 90 +#define CLK_INFRA_USB 91 +#define CLK_INFRA_DEVMPU_BCLK 92 +#define CLK_INFRA_CCIF2_AP 93 +#define CLK_INFRA_CCIF2_MD 94 +#define CLK_INFRA_CCIF3_AP 95 +#define CLK_INFRA_CCIF3_MD 96 +#define CLK_INFRA_SEJ_F13M 97 +#define CLK_INFRA_AES_BCLK 98 +#define CLK_INFRA_I2C7 99 +#define CLK_INFRA_I2C8 100 +#define CLK_INFRA_FBIST2FPC 101 +#define CLK_INFRA_CCIF4_AP 102 +#define CLK_INFRA_CCIF4_MD 103 +#define CLK_INFRA_FADSP 104 +#define CLK_INFRA_SSUSB_XHCI 105 +#define CLK_INFRA_SPI6 106 +#define CLK_INFRA_SPI7 107 +#define CLK_INFRA_NR_CLK 108 + +/* MFGCFG */ +#define CLK_MFGCFG_BG3D 1 +#define CLK_MFGCFG_NR_CLK 2 + +/* IMG */ +#define CLK_IMG_WPE_A 1 +#define CLK_IMG_MFB 2 +#define CLK_IMG_DIP 3 +#define CLK_IMG_LARB6 4 +#define CLK_IMG_LARB5 5 +#define CLK_IMG_NR_CLK 6 + +/* IPE */ +#define CLK_IPE_LARB7 1 +#define CLK_IPE_LARB8 2 +#define CLK_IPE_SMI_SUBCOM 3 +#define CLK_IPE_FD 4 +#define CLK_IPE_FE 5 +#define CLK_IPE_RSC 6 +#define CLK_IPE_DPE 7 +#define CLK_IPE_NR_CLK 8 + +/* MM_CONFIG */ +#define CLK_MM_SMI_COMMON 1 +#define CLK_MM_SMI_LARB0 2 +#define CLK_MM_SMI_LARB1 3 +#define CLK_MM_GALS_COMM0 4 +#define CLK_MM_GALS_COMM1 5 +#define CLK_MM_GALS_CCU2MM 6 +#define CLK_MM_GALS_IPU12MM 7 +#define CLK_MM_GALS_IMG2MM 8 +#define CLK_MM_GALS_CAM2MM 9 +#define CLK_MM_GALS_IPU2MM 10 +#define CLK_MM_MDP_DL_TXCK 11 +#define CLK_MM_IPU_DL_TXCK 12 +#define CLK_MM_MDP_RDMA0 13 +#define CLK_MM_MDP_RDMA1 14 +#define CLK_MM_MDP_RSZ0 15 +#define CLK_MM_MDP_RSZ1 16 +#define CLK_MM_MDP_TDSHP 17 +#define CLK_MM_MDP_WROT0 18 +#define CLK_MM_FAKE_ENG 19 +#define CLK_MM_DISP_OVL0 20 +#define CLK_MM_DISP_OVL0_2L 21 +#define CLK_MM_DISP_OVL1_2L 22 +#define CLK_MM_DISP_RDMA0 23 +#define CLK_MM_DISP_RDMA1 24 +#define CLK_MM_DISP_WDMA0 25 +#define CLK_MM_DISP_COLOR0 26 +#define CLK_MM_DISP_CCORR0 27 +#define CLK_MM_DISP_AAL0 28 +#define CLK_MM_DISP_GAMMA0 29 +#define CLK_MM_DISP_DITHER0 30 +#define CLK_MM_DISP_SPLIT 31 +#define CLK_MM_DSI0_MM_CK 32 +#define CLK_MM_DSI0_IF_CK 33 +#define CLK_MM_DPI_MM_CK 34 +#define CLK_MM_DPI_IF_CK 35 +#define CLK_MM_FAKE_ENG2 36 +#define CLK_MM_MDP_DL_RX_CK 37 +#define CLK_MM_IPU_DL_RX_CK 38 +#define CLK_MM_26M 39 +#define CLK_MM_MM_R2Y 40 +#define CLK_MM_DISP_RSZ 41 +#define CLK_MM_MDP_WDMA0 42 +#define CLK_MM_MDP_AAL 43 +#define CLK_MM_MDP_HDR 44 +#define CLK_MM_DBI_MM_CK 45 +#define CLK_MM_DBI_IF_CK 46 +#define CLK_MM_MDP_WROT1 47 +#define CLK_MM_DISP_POSTMASK0 48 +#define CLK_MM_DISP_HRT_BW 49 +#define CLK_MM_DISP_OVL_FBDC 50 +#define CLK_MM_NR_CLK 51 + +/* VDEC_GCON */ +#define CLK_VDEC_VDEC 1 +#define CLK_VDEC_LARB1 2 +#define CLK_VDEC_GCON_NR_CLK 3 + +/* VENC_GCON */ +#define CLK_VENC_GCON_LARB 1 +#define CLK_VENC_GCON_VENC 2 +#define CLK_VENC_GCON_JPGENC 3 +#define CLK_VENC_GCON_GALS 4 +#define CLK_VENC_GCON_NR_CLK 5 + +/* AUD */ +#define CLK_AUD_AFE 1 +#define CLK_AUD_22M 2 +#define CLK_AUD_24M 3 +#define CLK_AUD_APLL2_TUNER 4 +#define CLK_AUD_APLL_TUNER 5 +#define CLK_AUD_TDM 6 +#define CLK_AUD_ADC 7 +#define CLK_AUD_DAC 8 +#define CLK_AUD_DAC_PREDIS 9 +#define CLK_AUD_TML 10 +#define CLK_AUD_NLE 11 +#define CLK_AUD_I2S1_BCLK_SW 12 +#define CLK_AUD_I2S2_BCLK_SW 13 +#define CLK_AUD_I2S3_BCLK_SW 14 +#define CLK_AUD_I2S4_BCLK_SW 15 +#define CLK_AUD_I2S5_BCLK_SW 16 +#define CLK_AUD_CONN_I2S_ASRC 17 +#define CLK_AUD_GENERAL1_ASRC 18 +#define CLK_AUD_GENERAL2_ASRC 19 +#define CLK_AUD_DAC_HIRES 20 +#define CLK_AUD_PDN_ADDA6_ADC 21 +#define CLK_AUD_ADC_HIRES 22 +#define CLK_AUD_ADC_HIRES_TML 23 +#define CLK_AUD_ADDA6_ADC_HIRES 24 +#define CLK_AUD_3RD_DAC 25 +#define CLK_AUD_3RD_DAC_PREDIS 26 +#define CLK_AUD_3RD_DAC_TML 27 +#define CLK_AUD_3RD_DAC_HIRES 28 +#define CLK_AUD_NR_CLK 29 + +#endif /* _DT_BINDINGS_CLK_MT6779_H */ From 710774e048614c761a39a98e8d0fa75f688c83b6 Mon Sep 17 00:00:00 2001 From: mtk01761 Date: Mon, 19 Aug 2019 17:21:41 +0800 Subject: [PATCH 49/62] clk: mediatek: Add MT6779 clock support Add MT6779 clock support, include topckgen, apmixedsys, infracfg, and subsystem clocks. Signed-off-by: mtk01761 Link: https://lkml.kernel.org/r/1566206502-4347-11-git-send-email-mars.cheng@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 56 + drivers/clk/mediatek/Makefile | 9 + drivers/clk/mediatek/clk-mt6779-aud.c | 117 +++ drivers/clk/mediatek/clk-mt6779-cam.c | 66 ++ drivers/clk/mediatek/clk-mt6779-img.c | 58 ++ drivers/clk/mediatek/clk-mt6779-ipe.c | 60 ++ drivers/clk/mediatek/clk-mt6779-mfg.c | 55 + drivers/clk/mediatek/clk-mt6779-mm.c | 113 ++ drivers/clk/mediatek/clk-mt6779-vdec.c | 67 ++ drivers/clk/mediatek/clk-mt6779-venc.c | 58 ++ drivers/clk/mediatek/clk-mt6779.c | 1315 ++++++++++++++++++++++++ 11 files changed, 1974 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt6779-aud.c create mode 100644 drivers/clk/mediatek/clk-mt6779-cam.c create mode 100644 drivers/clk/mediatek/clk-mt6779-img.c create mode 100644 drivers/clk/mediatek/clk-mt6779-ipe.c create mode 100644 drivers/clk/mediatek/clk-mt6779-mfg.c create mode 100644 drivers/clk/mediatek/clk-mt6779-mm.c create mode 100644 drivers/clk/mediatek/clk-mt6779-vdec.c create mode 100644 drivers/clk/mediatek/clk-mt6779-venc.c create mode 100644 drivers/clk/mediatek/clk-mt6779.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index ce3d9b300bab..7efc3617bbd5 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -117,6 +117,62 @@ config COMMON_CLK_MT2712_VENCSYS ---help--- This driver supports MediaTek MT2712 vencsys clocks. +config COMMON_CLK_MT6779 + bool "Clock driver for MediaTek MT6779" + depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK && ARM64 + help + This driver supports MediaTek MT6779 basic clocks. + +config COMMON_CLK_MT6779_MMSYS + bool "Clock driver for MediaTek MT6779 mmsys" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 mmsys clocks. + +config COMMON_CLK_MT6779_IMGSYS + bool "Clock driver for MediaTek MT6779 imgsys" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 imgsys clocks. + +config COMMON_CLK_MT6779_IPESYS + bool "Clock driver for MediaTek MT6779 ipesys" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 ipesys clocks. + +config COMMON_CLK_MT6779_CAMSYS + bool "Clock driver for MediaTek MT6779 camsys" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 camsys clocks. + +config COMMON_CLK_MT6779_VDECSYS + bool "Clock driver for MediaTek MT6779 vdecsys" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 vdecsys clocks. + +config COMMON_CLK_MT6779_VENCSYS + bool "Clock driver for MediaTek MT6779 vencsys" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 vencsys clocks. + +config COMMON_CLK_MT6779_MFGCFG + bool "Clock driver for MediaTek MT6779 mfgcfg" + depends on COMMON_CLK_MT6779 + help + This driver supports MediaTek MT6779 mfgcfg clocks. + +config COMMON_CLK_MT6779_AUDSYS + bool "Clock driver for Mediatek MT6779 audsys" + depends on COMMON_CLK_MT6779 + help + This driver supports Mediatek MT6779 audsys clocks. + config COMMON_CLK_MT6797 bool "Clock driver for MediaTek MT6797" depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 672de0099eef..8cdb76a5cd71 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -1,6 +1,15 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o +obj-$(CONFIG_COMMON_CLK_MT6779) += clk-mt6779.o +obj-$(CONFIG_COMMON_CLK_MT6779_MMSYS) += clk-mt6779-mm.o +obj-$(CONFIG_COMMON_CLK_MT6779_IMGSYS) += clk-mt6779-img.o +obj-$(CONFIG_COMMON_CLK_MT6779_IPESYS) += clk-mt6779-ipe.o +obj-$(CONFIG_COMMON_CLK_MT6779_CAMSYS) += clk-mt6779-cam.o +obj-$(CONFIG_COMMON_CLK_MT6779_VDECSYS) += clk-mt6779-vdec.o +obj-$(CONFIG_COMMON_CLK_MT6779_VENCSYS) += clk-mt6779-venc.o +obj-$(CONFIG_COMMON_CLK_MT6779_MFGCFG) += clk-mt6779-mfg.o +obj-$(CONFIG_COMMON_CLK_MT6779_AUDSYS) += clk-mt6779-aud.o obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o diff --git a/drivers/clk/mediatek/clk-mt6779-aud.c b/drivers/clk/mediatek/clk-mt6779-aud.c new file mode 100644 index 000000000000..11b209f95e25 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-aud.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs audio0_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x0, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs audio1_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x4, + .sta_ofs = 0x4, +}; + +#define GATE_AUDIO0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &audio0_cg_regs, _shift, \ + &mtk_clk_gate_ops_no_setclr) +#define GATE_AUDIO1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &audio1_cg_regs, _shift, \ + &mtk_clk_gate_ops_no_setclr) + +static const struct mtk_gate audio_clks[] = { + /* AUDIO0 */ + GATE_AUDIO0(CLK_AUD_AFE, "aud_afe", "audio_sel", 2), + GATE_AUDIO0(CLK_AUD_22M, "aud_22m", "aud_eng1_sel", 8), + GATE_AUDIO0(CLK_AUD_24M, "aud_24m", "aud_eng2_sel", 9), + GATE_AUDIO0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", + "aud_eng2_sel", 18), + GATE_AUDIO0(CLK_AUD_APLL_TUNER, "aud_apll_tuner", + "aud_eng1_sel", 19), + GATE_AUDIO0(CLK_AUD_TDM, "aud_tdm", "aud_eng1_sel", 20), + GATE_AUDIO0(CLK_AUD_ADC, "aud_adc", "audio_sel", 24), + GATE_AUDIO0(CLK_AUD_DAC, "aud_dac", "audio_sel", 25), + GATE_AUDIO0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", + "audio_sel", 26), + GATE_AUDIO0(CLK_AUD_TML, "aud_tml", "audio_sel", 27), + GATE_AUDIO0(CLK_AUD_NLE, "aud_nle", "audio_sel", 28), + /* AUDIO1 */ + GATE_AUDIO1(CLK_AUD_I2S1_BCLK_SW, "aud_i2s1_bclk", + "audio_sel", 4), + GATE_AUDIO1(CLK_AUD_I2S2_BCLK_SW, "aud_i2s2_bclk", + "audio_sel", 5), + GATE_AUDIO1(CLK_AUD_I2S3_BCLK_SW, "aud_i2s3_bclk", + "audio_sel", 6), + GATE_AUDIO1(CLK_AUD_I2S4_BCLK_SW, "aud_i2s4_bclk", + "audio_sel", 7), + GATE_AUDIO1(CLK_AUD_I2S5_BCLK_SW, "aud_i2s5_bclk", + "audio_sel", 8), + GATE_AUDIO1(CLK_AUD_CONN_I2S_ASRC, "aud_conn_i2s", + "audio_sel", 12), + GATE_AUDIO1(CLK_AUD_GENERAL1_ASRC, "aud_general1", + "audio_sel", 13), + GATE_AUDIO1(CLK_AUD_GENERAL2_ASRC, "aud_general2", + "audio_sel", 14), + GATE_AUDIO1(CLK_AUD_DAC_HIRES, "aud_dac_hires", + "audio_h_sel", 15), + GATE_AUDIO1(CLK_AUD_ADC_HIRES, "aud_adc_hires", + "audio_h_sel", 16), + GATE_AUDIO1(CLK_AUD_ADC_HIRES_TML, "aud_adc_hires_tml", + "audio_h_sel", 17), + GATE_AUDIO1(CLK_AUD_PDN_ADDA6_ADC, "aud_pdn_adda6_adc", + "audio_sel", 20), + GATE_AUDIO1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", + "audio_h_sel", + 21), + GATE_AUDIO1(CLK_AUD_3RD_DAC, "aud_3rd_dac", "audio_sel", + 28), + GATE_AUDIO1(CLK_AUD_3RD_DAC_PREDIS, "aud_3rd_dac_predis", + "audio_sel", 29), + GATE_AUDIO1(CLK_AUD_3RD_DAC_TML, "aud_3rd_dac_tml", + "audio_sel", 30), + GATE_AUDIO1(CLK_AUD_3RD_DAC_HIRES, "aud_3rd_dac_hires", + "audio_h_sel", 31), +}; + +static const struct of_device_id of_match_clk_mt6779_aud[] = { + { .compatible = "mediatek,mt6779-audio", }, + {} +}; + +static int clk_mt6779_aud_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK); + + mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_aud_drv = { + .probe = clk_mt6779_aud_probe, + .driver = { + .name = "clk-mt6779-aud", + .of_match_table = of_match_clk_mt6779_aud, + }, +}; + +builtin_platform_driver(clk_mt6779_aud_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-cam.c b/drivers/clk/mediatek/clk-mt6779-cam.c new file mode 100644 index 000000000000..244d4208b7fb --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-cam.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +static const struct mtk_gate_regs cam_cg_regs = { + .set_ofs = 0x0004, + .clr_ofs = 0x0008, + .sta_ofs = 0x0000, +}; + +#define GATE_CAM(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate cam_clks[] = { + GATE_CAM(CLK_CAM_LARB10, "camsys_larb10", "cam_sel", 0), + GATE_CAM(CLK_CAM_DFP_VAD, "camsys_dfp_vad", "cam_sel", 1), + GATE_CAM(CLK_CAM_LARB11, "camsys_larb11", "cam_sel", 2), + GATE_CAM(CLK_CAM_LARB9, "camsys_larb9", "cam_sel", 3), + GATE_CAM(CLK_CAM_CAM, "camsys_cam", "cam_sel", 6), + GATE_CAM(CLK_CAM_CAMTG, "camsys_camtg", "cam_sel", 7), + GATE_CAM(CLK_CAM_SENINF, "camsys_seninf", "cam_sel", 8), + GATE_CAM(CLK_CAM_CAMSV0, "camsys_camsv0", "cam_sel", 9), + GATE_CAM(CLK_CAM_CAMSV1, "camsys_camsv1", "cam_sel", 10), + GATE_CAM(CLK_CAM_CAMSV2, "camsys_camsv2", "cam_sel", 11), + GATE_CAM(CLK_CAM_CAMSV3, "camsys_camsv3", "cam_sel", 12), + GATE_CAM(CLK_CAM_CCU, "camsys_ccu", "cam_sel", 13), + GATE_CAM(CLK_CAM_FAKE_ENG, "camsys_fake_eng", "cam_sel", 14), +}; + +static const struct of_device_id of_match_clk_mt6779_cam[] = { + { .compatible = "mediatek,mt6779-camsys", }, + {} +}; + +static int clk_mt6779_cam_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_CAM_NR_CLK); + + mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_cam_drv = { + .probe = clk_mt6779_cam_probe, + .driver = { + .name = "clk-mt6779-cam", + .of_match_table = of_match_clk_mt6779_cam, + }, +}; + +builtin_platform_driver(clk_mt6779_cam_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-img.c b/drivers/clk/mediatek/clk-mt6779-img.c new file mode 100644 index 000000000000..26292a45c613 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-img.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +static const struct mtk_gate_regs img_cg_regs = { + .set_ofs = 0x0004, + .clr_ofs = 0x0008, + .sta_ofs = 0x0000, +}; + +#define GATE_IMG(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate img_clks[] = { + GATE_IMG(CLK_IMG_LARB5, "imgsys_larb5", "img_sel", 0), + GATE_IMG(CLK_IMG_LARB6, "imgsys_larb6", "img_sel", 1), + GATE_IMG(CLK_IMG_DIP, "imgsys_dip", "img_sel", 2), + GATE_IMG(CLK_IMG_MFB, "imgsys_mfb", "img_sel", 6), + GATE_IMG(CLK_IMG_WPE_A, "imgsys_wpe_a", "img_sel", 7), +}; + +static const struct of_device_id of_match_clk_mt6779_img[] = { + { .compatible = "mediatek,mt6779-imgsys", }, + {} +}; + +static int clk_mt6779_img_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK); + + mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_img_drv = { + .probe = clk_mt6779_img_probe, + .driver = { + .name = "clk-mt6779-img", + .of_match_table = of_match_clk_mt6779_img, + }, +}; + +builtin_platform_driver(clk_mt6779_img_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-ipe.c b/drivers/clk/mediatek/clk-mt6779-ipe.c new file mode 100644 index 000000000000..bb519075639c --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-ipe.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +static const struct mtk_gate_regs ipe_cg_regs = { + .set_ofs = 0x0004, + .clr_ofs = 0x0008, + .sta_ofs = 0x0000, +}; + +#define GATE_IPE(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &ipe_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate ipe_clks[] = { + GATE_IPE(CLK_IPE_LARB7, "ipe_larb7", "ipe_sel", 0), + GATE_IPE(CLK_IPE_LARB8, "ipe_larb8", "ipe_sel", 1), + GATE_IPE(CLK_IPE_SMI_SUBCOM, "ipe_smi_subcom", "ipe_sel", 2), + GATE_IPE(CLK_IPE_FD, "ipe_fd", "ipe_sel", 3), + GATE_IPE(CLK_IPE_FE, "ipe_fe", "ipe_sel", 4), + GATE_IPE(CLK_IPE_RSC, "ipe_rsc", "ipe_sel", 5), + GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "ipe_sel", 6), +}; + +static const struct of_device_id of_match_clk_mt6779_ipe[] = { + { .compatible = "mediatek,mt6779-ipesys", }, + {} +}; + +static int clk_mt6779_ipe_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_IPE_NR_CLK); + + mtk_clk_register_gates(node, ipe_clks, ARRAY_SIZE(ipe_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_ipe_drv = { + .probe = clk_mt6779_ipe_probe, + .driver = { + .name = "clk-mt6779-ipe", + .of_match_table = of_match_clk_mt6779_ipe, + }, +}; + +builtin_platform_driver(clk_mt6779_ipe_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-mfg.c b/drivers/clk/mediatek/clk-mt6779-mfg.c new file mode 100644 index 000000000000..c6ee2a89c070 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-mfg.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs mfg_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_MFG(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate mfg_clks[] = { + GATE_MFG(CLK_MFGCFG_BG3D, "mfg_bg3d", "mfg_sel", 0), +}; + +static int clk_mt6779_mfg_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_MFGCFG_NR_CLK); + + mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static const struct of_device_id of_match_clk_mt6779_mfg[] = { + { .compatible = "mediatek,mt6779-mfgcfg", }, + {} +}; + +static struct platform_driver clk_mt6779_mfg_drv = { + .probe = clk_mt6779_mfg_probe, + .driver = { + .name = "clk-mt6779-mfg", + .of_match_table = of_match_clk_mt6779_mfg, + }, +}; + +builtin_platform_driver(clk_mt6779_mfg_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-mm.c b/drivers/clk/mediatek/clk-mt6779-mm.c new file mode 100644 index 000000000000..fb5fbb8e3e41 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-mm.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +static const struct mtk_gate_regs mm0_cg_regs = { + .set_ofs = 0x0104, + .clr_ofs = 0x0108, + .sta_ofs = 0x0100, +}; + +static const struct mtk_gate_regs mm1_cg_regs = { + .set_ofs = 0x0114, + .clr_ofs = 0x0118, + .sta_ofs = 0x0110, +}; + +#define GATE_MM0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) +#define GATE_MM1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate mm_clks[] = { + /* MM0 */ + GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0), + GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), + GATE_MM0(CLK_MM_SMI_LARB1, "mm_smi_larb1", "mm_sel", 2), + GATE_MM0(CLK_MM_GALS_COMM0, "mm_gals_comm0", "mm_sel", 3), + GATE_MM0(CLK_MM_GALS_COMM1, "mm_gals_comm1", "mm_sel", 4), + GATE_MM0(CLK_MM_GALS_CCU2MM, "mm_gals_ccu2mm", "mm_sel", 5), + GATE_MM0(CLK_MM_GALS_IPU12MM, "mm_gals_ipu12mm", "mm_sel", 6), + GATE_MM0(CLK_MM_GALS_IMG2MM, "mm_gals_img2mm", "mm_sel", 7), + GATE_MM0(CLK_MM_GALS_CAM2MM, "mm_gals_cam2mm", "mm_sel", 8), + GATE_MM0(CLK_MM_GALS_IPU2MM, "mm_gals_ipu2mm", "mm_sel", 9), + GATE_MM0(CLK_MM_MDP_DL_TXCK, "mm_mdp_dl_txck", "mm_sel", 10), + GATE_MM0(CLK_MM_IPU_DL_TXCK, "mm_ipu_dl_txck", "mm_sel", 11), + GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 12), + GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 13), + GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 14), + GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 15), + GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 16), + GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 17), + GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 18), + GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 19), + GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 20), + GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "mm_sel", 21), + GATE_MM0(CLK_MM_DISP_OVL1_2L, "mm_disp_ovl1_2l", "mm_sel", 22), + GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 23), + GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 24), + GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 25), + GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 26), + GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "mm_sel", 27), + GATE_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "mm_sel", 28), + GATE_MM0(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "mm_sel", 29), + GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "mm_sel", 30), + GATE_MM0(CLK_MM_DISP_SPLIT, "mm_disp_split", "mm_sel", 31), + /* MM1 */ + GATE_MM1(CLK_MM_DSI0_MM_CK, "mm_dsi0_mmck", "mm_sel", 0), + GATE_MM1(CLK_MM_DSI0_IF_CK, "mm_dsi0_ifck", "mm_sel", 1), + GATE_MM1(CLK_MM_DPI_MM_CK, "mm_dpi_mmck", "mm_sel", 2), + GATE_MM1(CLK_MM_DPI_IF_CK, "mm_dpi_ifck", "dpi0_sel", 3), + GATE_MM1(CLK_MM_FAKE_ENG2, "mm_fake_eng2", "mm_sel", 4), + GATE_MM1(CLK_MM_MDP_DL_RX_CK, "mm_mdp_dl_rxck", "mm_sel", 5), + GATE_MM1(CLK_MM_IPU_DL_RX_CK, "mm_ipu_dl_rxck", "mm_sel", 6), + GATE_MM1(CLK_MM_26M, "mm_26m", "f_f26m_ck", 7), + GATE_MM1(CLK_MM_MM_R2Y, "mm_mmsys_r2y", "mm_sel", 8), + GATE_MM1(CLK_MM_DISP_RSZ, "mm_disp_rsz", "mm_sel", 9), + GATE_MM1(CLK_MM_MDP_AAL, "mm_mdp_aal", "mm_sel", 10), + GATE_MM1(CLK_MM_MDP_HDR, "mm_mdp_hdr", "mm_sel", 11), + GATE_MM1(CLK_MM_DBI_MM_CK, "mm_dbi_mmck", "mm_sel", 12), + GATE_MM1(CLK_MM_DBI_IF_CK, "mm_dbi_ifck", "dpi0_sel", 13), + GATE_MM1(CLK_MM_DISP_POSTMASK0, "mm_disp_pm0", "mm_sel", 14), + GATE_MM1(CLK_MM_DISP_HRT_BW, "mm_disp_hrt_bw", "mm_sel", 15), + GATE_MM1(CLK_MM_DISP_OVL_FBDC, "mm_disp_ovl_fbdc", "mm_sel", 16), +}; + +static const struct of_device_id of_match_clk_mt6779_mm[] = { + { .compatible = "mediatek,mt6779-mmsys", }, + {} +}; + +static int clk_mt6779_mm_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK); + + mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_mm_drv = { + .probe = clk_mt6779_mm_probe, + .driver = { + .name = "clk-mt6779-mm", + .of_match_table = of_match_clk_mt6779_mm, + }, +}; + +builtin_platform_driver(clk_mt6779_mm_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-vdec.c b/drivers/clk/mediatek/clk-mt6779-vdec.c new file mode 100644 index 000000000000..1900da2586a1 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-vdec.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs vdec0_cg_regs = { + .set_ofs = 0x0000, + .clr_ofs = 0x0004, + .sta_ofs = 0x0000, +}; + +static const struct mtk_gate_regs vdec1_cg_regs = { + .set_ofs = 0x0008, + .clr_ofs = 0x000c, + .sta_ofs = 0x0008, +}; + +#define GATE_VDEC0_I(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr_inv) +#define GATE_VDEC1_I(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr_inv) + +static const struct mtk_gate vdec_clks[] = { + /* VDEC0 */ + GATE_VDEC0_I(CLK_VDEC_VDEC, "vdec_cken", "vdec_sel", 0), + /* VDEC1 */ + GATE_VDEC1_I(CLK_VDEC_LARB1, "vdec_larb1_cken", "vdec_sel", 0), +}; + +static const struct of_device_id of_match_clk_mt6779_vdec[] = { + { .compatible = "mediatek,mt6779-vdecsys", }, + {} +}; + +static int clk_mt6779_vdec_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_VDEC_GCON_NR_CLK); + + mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_vdec_drv = { + .probe = clk_mt6779_vdec_probe, + .driver = { + .name = "clk-mt6779-vdec", + .of_match_table = of_match_clk_mt6779_vdec, + }, +}; + +builtin_platform_driver(clk_mt6779_vdec_drv); diff --git a/drivers/clk/mediatek/clk-mt6779-venc.c b/drivers/clk/mediatek/clk-mt6779-venc.c new file mode 100644 index 000000000000..b41d1f859edc --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779-venc.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs venc_cg_regs = { + .set_ofs = 0x0004, + .clr_ofs = 0x0008, + .sta_ofs = 0x0000, +}; + +#define GATE_VENC_I(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr_inv) + +static const struct mtk_gate venc_clks[] = { + GATE_VENC_I(CLK_VENC_GCON_LARB, "venc_larb", "venc_sel", 0), + GATE_VENC_I(CLK_VENC_GCON_VENC, "venc_venc", "venc_sel", 4), + GATE_VENC_I(CLK_VENC_GCON_JPGENC, "venc_jpgenc", "venc_sel", 8), + GATE_VENC_I(CLK_VENC_GCON_GALS, "venc_gals", "venc_sel", 28), +}; + +static const struct of_device_id of_match_clk_mt6779_venc[] = { + { .compatible = "mediatek,mt6779-vencsys", }, + {} +}; + +static int clk_mt6779_venc_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_VENC_GCON_NR_CLK); + + mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt6779_venc_drv = { + .probe = clk_mt6779_venc_probe, + .driver = { + .name = "clk-mt6779-venc", + .of_match_table = of_match_clk_mt6779_venc, + }, +}; + +builtin_platform_driver(clk_mt6779_venc_drv); diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c new file mode 100644 index 000000000000..608a9a6621a3 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6779.c @@ -0,0 +1,1315 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Wendell Lin + */ + +#include +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-mux.h" +#include "clk-gate.h" + +#include + +static DEFINE_SPINLOCK(mt6779_clk_lock); + +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CLK_TOP_CLK26M, "f_f26m_ck", "clk26m", 26000000), +}; + +static const struct mtk_fixed_factor top_divs[] = { + FACTOR(CLK_TOP_CLK13M, "clk13m", "clk26m", 1, 2), + FACTOR(CLK_TOP_F26M_CK_D2, "csw_f26m_ck_d2", "clk26m", 1, 2), + FACTOR(CLK_TOP_MAINPLL_CK, "mainpll_ck", "mainpll", 1, 1), + FACTOR(CLK_TOP_MAINPLL_D2, "mainpll_d2", "mainpll_ck", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D2_D2, "mainpll_d2_d2", "mainpll_d2", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D2_D4, "mainpll_d2_d4", "mainpll_d2", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D2_D8, "mainpll_d2_d8", "mainpll_d2", 1, 8), + FACTOR(CLK_TOP_MAINPLL_D2_D16, "mainpll_d2_d16", "mainpll_d2", 1, 16), + FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3), + FACTOR(CLK_TOP_MAINPLL_D3_D2, "mainpll_d3_d2", "mainpll_d3", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D3_D4, "mainpll_d3_d4", "mainpll_d3", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D3_D8, "mainpll_d3_d8", "mainpll_d3", 1, 8), + FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5), + FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll_d5", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll_d5", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7), + FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll_d7", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll_d7", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_CK, "univpll", "univ2pll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D2_D2, "univpll_d2_d2", "univpll_d2", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D2_D4, "univpll_d2_d4", "univpll_d2", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D2_D8, "univpll_d2_d8", "univpll_d2", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), + FACTOR(CLK_TOP_UNIVPLL_D3_D2, "univpll_d3_d2", "univpll_d3", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D3_D4, "univpll_d3_d4", "univpll_d3", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D3_D8, "univpll_d3_d8", "univpll_d3", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D3_D16, "univpll_d3_d16", "univpll_d3", 1, 16), + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), + FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D5_D8, "univpll_d5_d8", "univpll_d5", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), + FACTOR(CLK_TOP_UNIVP_192M_CK, "univpll_192m_ck", "univ2pll", 1, 13), + FACTOR(CLK_TOP_UNIVP_192M_D2, "univpll_192m_d2", "univpll_192m_ck", + 1, 2), + FACTOR(CLK_TOP_UNIVP_192M_D4, "univpll_192m_d4", "univpll_192m_ck", + 1, 4), + FACTOR(CLK_TOP_UNIVP_192M_D8, "univpll_192m_d8", "univpll_192m_ck", + 1, 8), + FACTOR(CLK_TOP_UNIVP_192M_D16, "univpll_192m_d16", "univpll_192m_ck", + 1, 16), + FACTOR(CLK_TOP_UNIVP_192M_D32, "univpll_192m_d32", "univpll_192m_ck", + 1, 32), + FACTOR(CLK_TOP_APLL1_CK, "apll1_ck", "apll1", 1, 1), + FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1", 1, 2), + FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1, 4), + FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1", 1, 8), + FACTOR(CLK_TOP_APLL2_CK, "apll2_ck", "apll2", 1, 1), + FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2), + FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4), + FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2", 1, 8), + FACTOR(CLK_TOP_TVDPLL_CK, "tvdpll_ck", "tvdpll", 1, 1), + FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_ck", 1, 2), + FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), + FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll", 1, 8), + FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll", 1, 16), + FACTOR(CLK_TOP_MMPLL_CK, "mmpll_ck", "mmpll", 1, 1), + FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4), + FACTOR(CLK_TOP_MMPLL_D4_D2, "mmpll_d4_d2", "mmpll_d4", 1, 2), + FACTOR(CLK_TOP_MMPLL_D4_D4, "mmpll_d4_d4", "mmpll_d4", 1, 4), + FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5), + FACTOR(CLK_TOP_MMPLL_D5_D2, "mmpll_d5_d2", "mmpll_d5", 1, 2), + FACTOR(CLK_TOP_MMPLL_D5_D4, "mmpll_d5_d4", "mmpll_d5", 1, 4), + FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll", 1, 6), + FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7), + FACTOR(CLK_TOP_MFGPLL_CK, "mfgpll_ck", "mfgpll", 1, 1), + FACTOR(CLK_TOP_ADSPPLL_CK, "adsppll_ck", "adsppll", 1, 1), + FACTOR(CLK_TOP_ADSPPLL_D4, "adsppll_d4", "adsppll", 1, 4), + FACTOR(CLK_TOP_ADSPPLL_D5, "adsppll_d5", "adsppll", 1, 5), + FACTOR(CLK_TOP_ADSPPLL_D6, "adsppll_d6", "adsppll", 1, 6), + FACTOR(CLK_TOP_MSDCPLL_CK, "msdcpll_ck", "msdcpll", 1, 1), + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), + FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), + FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8), + FACTOR(CLK_TOP_MSDCPLL_D16, "msdcpll_d16", "msdcpll", 1, 16), + FACTOR(CLK_TOP_AD_OSC_CK, "ad_osc_ck", "osc", 1, 1), + FACTOR(CLK_TOP_OSC_D2, "osc_d2", "osc", 1, 2), + FACTOR(CLK_TOP_OSC_D4, "osc_d4", "osc", 1, 4), + FACTOR(CLK_TOP_OSC_D8, "osc_d8", "osc", 1, 8), + FACTOR(CLK_TOP_OSC_D10, "osc_d10", "osc", 1, 10), + FACTOR(CLK_TOP_OSC_D16, "osc_d16", "osc", 1, 16), + FACTOR(CLK_TOP_AD_OSC2_CK, "ad_osc2_ck", "osc2", 1, 1), + FACTOR(CLK_TOP_OSC2_D2, "osc2_d2", "osc2", 1, 2), + FACTOR(CLK_TOP_OSC2_D3, "osc2_d3", "osc2", 1, 3), + FACTOR(CLK_TOP_TVDPLL_MAINPLL_D2_CK, "tvdpll_mainpll_d2_ck", + "tvdpll", 1, 1), + FACTOR(CLK_TOP_FMEM_466M_CK, "fmem_466m_ck", "fmem", 1, 1), +}; + +static const char * const axi_parents[] = { + "clk26m", + "mainpll_d2_d4", + "mainpll_d7", + "osc_d4" +}; + +static const char * const mm_parents[] = { + "clk26m", + "tvdpll_mainpll_d2_ck", + "mmpll_d7", + "mmpll_d5_d2", + "mainpll_d2_d2", + "mainpll_d3_d2" +}; + +static const char * const scp_parents[] = { + "clk26m", + "univpll_d2_d8", + "mainpll_d2_d4", + "mainpll_d3", + "univpll_d3", + "ad_osc2_ck", + "osc2_d2", + "osc2_d3" +}; + +static const char * const img_parents[] = { + "clk26m", + "mainpll_d2", + "mainpll_d2", + "univpll_d3", + "mainpll_d3", + "mmpll_d5_d2", + "tvdpll_mainpll_d2_ck", + "mainpll_d5" +}; + +static const char * const ipe_parents[] = { + "clk26m", + "mainpll_d2", + "mmpll_d7", + "univpll_d3", + "mainpll_d3", + "mmpll_d5_d2", + "mainpll_d2_d2", + "mainpll_d5" +}; + +static const char * const dpe_parents[] = { + "clk26m", + "mainpll_d2", + "mmpll_d7", + "univpll_d3", + "mainpll_d3", + "mmpll_d5_d2", + "mainpll_d2_d2", + "mainpll_d5" +}; + +static const char * const cam_parents[] = { + "clk26m", + "mainpll_d2", + "mmpll_d6", + "mainpll_d3", + "mmpll_d7", + "univpll_d3", + "mmpll_d5_d2", + "adsppll_d5", + "tvdpll_mainpll_d2_ck", + "univpll_d3_d2" +}; + +static const char * const ccu_parents[] = { + "clk26m", + "mainpll_d2", + "mmpll_d6", + "mainpll_d3", + "mmpll_d7", + "univpll_d3", + "mmpll_d5_d2", + "mainpll_d2_d2", + "adsppll_d5", + "univpll_d3_d2" +}; + +static const char * const dsp_parents[] = { + "clk26m", + "univpll_d3_d8", + "univpll_d3_d4", + "mainpll_d2_d4", + "univpll_d3_d2", + "mainpll_d2_d2", + "univpll_d2_d2", + "mainpll_d3", + "univpll_d3", + "mmpll_d7", + "mmpll_d6", + "adsppll_d5", + "tvdpll_ck", + "tvdpll_mainpll_d2_ck", + "univpll_d2", + "adsppll_d4" +}; + +static const char * const dsp1_parents[] = { + "clk26m", + "univpll_d3_d8", + "univpll_d3_d4", + "mainpll_d2_d4", + "univpll_d3_d2", + "mainpll_d2_d2", + "univpll_d2_d2", + "mainpll_d3", + "univpll_d3", + "mmpll_d7", + "mmpll_d6", + "adsppll_d5", + "tvdpll_ck", + "tvdpll_mainpll_d2_ck", + "univpll_d2", + "adsppll_d4" +}; + +static const char * const dsp2_parents[] = { + "clk26m", + "univpll_d3_d8", + "univpll_d3_d4", + "mainpll_d2_d4", + "univpll_d3_d2", + "mainpll_d2_d2", + "univpll_d2_d2", + "mainpll_d3", + "univpll_d3", + "mmpll_d7", + "mmpll_d6", + "adsppll_d5", + "tvdpll_ck", + "tvdpll_mainpll_d2_ck", + "univpll_d2", + "adsppll_d4" +}; + +static const char * const dsp3_parents[] = { + "clk26m", + "univpll_d3_d8", + "mainpll_d2_d4", + "univpll_d3_d2", + "mainpll_d2_d2", + "univpll_d2_d2", + "mainpll_d3", + "univpll_d3", + "mmpll_d7", + "mmpll_d6", + "mainpll_d2", + "tvdpll_ck", + "tvdpll_mainpll_d2_ck", + "univpll_d2", + "adsppll_d4", + "mmpll_d4" +}; + +static const char * const ipu_if_parents[] = { + "clk26m", + "univpll_d3_d8", + "univpll_d3_d4", + "mainpll_d2_d4", + "univpll_d3_d2", + "mainpll_d2_d2", + "univpll_d2_d2", + "mainpll_d3", + "univpll_d3", + "mmpll_d7", + "mmpll_d6", + "adsppll_d5", + "tvdpll_ck", + "tvdpll_mainpll_d2_ck", + "univpll_d2", + "adsppll_d4" +}; + +static const char * const mfg_parents[] = { + "clk26m", + "mfgpll_ck", + "univpll_d3", + "mainpll_d5" +}; + +static const char * const f52m_mfg_parents[] = { + "clk26m", + "univpll_d3_d2", + "univpll_d3_d4", + "univpll_d3_d8" +}; + +static const char * const camtg_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d3_d8", + "univpll_192m_d4", + "univpll_d3_d16", + "csw_f26m_ck_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg2_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d3_d8", + "univpll_192m_d4", + "univpll_d3_d16", + "csw_f26m_ck_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg3_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d3_d8", + "univpll_192m_d4", + "univpll_d3_d16", + "csw_f26m_ck_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg4_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d3_d8", + "univpll_192m_d4", + "univpll_d3_d16", + "csw_f26m_ck_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const uart_parents[] = { + "clk26m", + "univpll_d3_d8" +}; + +static const char * const spi_parents[] = { + "clk26m", + "mainpll_d5_d2", + "mainpll_d3_d4", + "msdcpll_d4" +}; + +static const char * const msdc50_hclk_parents[] = { + "clk26m", + "mainpll_d2_d2", + "mainpll_d3_d2" +}; + +static const char * const msdc50_0_parents[] = { + "clk26m", + "msdcpll_ck", + "msdcpll_d2", + "univpll_d2_d4", + "mainpll_d3_d2", + "univpll_d2_d2" +}; + +static const char * const msdc30_1_parents[] = { + "clk26m", + "univpll_d3_d2", + "mainpll_d3_d2", + "mainpll_d7", + "msdcpll_d2" +}; + +static const char * const audio_parents[] = { + "clk26m", + "mainpll_d5_d4", + "mainpll_d7_d4", + "mainpll_d2_d16" +}; + +static const char * const aud_intbus_parents[] = { + "clk26m", + "mainpll_d2_d4", + "mainpll_d7_d2" +}; + +static const char * const fpwrap_ulposc_parents[] = { + "osc_d10", + "clk26m", + "osc_d4", + "osc_d8", + "osc_d16" +}; + +static const char * const atb_parents[] = { + "clk26m", + "mainpll_d2_d2", + "mainpll_d5" +}; + +static const char * const sspm_parents[] = { + "clk26m", + "univpll_d2_d4", + "mainpll_d2_d2", + "univpll_d2_d2", + "mainpll_d3" +}; + +static const char * const dpi0_parents[] = { + "clk26m", + "tvdpll_d2", + "tvdpll_d4", + "tvdpll_d8", + "tvdpll_d16" +}; + +static const char * const scam_parents[] = { + "clk26m", + "mainpll_d5_d2" +}; + +static const char * const disppwm_parents[] = { + "clk26m", + "univpll_d3_d4", + "osc_d2", + "osc_d4", + "osc_d16" +}; + +static const char * const usb_top_parents[] = { + "clk26m", + "univpll_d5_d4", + "univpll_d3_d4", + "univpll_d5_d2" +}; + +static const char * const ssusb_top_xhci_parents[] = { + "clk26m", + "univpll_d5_d4", + "univpll_d3_d4", + "univpll_d5_d2" +}; + +static const char * const spm_parents[] = { + "clk26m", + "osc_d8", + "mainpll_d2_d8" +}; + +static const char * const i2c_parents[] = { + "clk26m", + "mainpll_d2_d8", + "univpll_d5_d2" +}; + +static const char * const seninf_parents[] = { + "clk26m", + "univpll_d7", + "univpll_d3_d2", + "univpll_d2_d2", + "mainpll_d3", + "mmpll_d4_d2", + "mmpll_d7", + "mmpll_d6" +}; + +static const char * const seninf1_parents[] = { + "clk26m", + "univpll_d7", + "univpll_d3_d2", + "univpll_d2_d2", + "mainpll_d3", + "mmpll_d4_d2", + "mmpll_d7", + "mmpll_d6" +}; + +static const char * const seninf2_parents[] = { + "clk26m", + "univpll_d7", + "univpll_d3_d2", + "univpll_d2_d2", + "mainpll_d3", + "mmpll_d4_d2", + "mmpll_d7", + "mmpll_d6" +}; + +static const char * const dxcc_parents[] = { + "clk26m", + "mainpll_d2_d2", + "mainpll_d2_d4", + "mainpll_d2_d8" +}; + +static const char * const aud_engen1_parents[] = { + "clk26m", + "apll1_d2", + "apll1_d4", + "apll1_d8" +}; + +static const char * const aud_engen2_parents[] = { + "clk26m", + "apll2_d2", + "apll2_d4", + "apll2_d8" +}; + +static const char * const faes_ufsfde_parents[] = { + "clk26m", + "mainpll_d2", + "mainpll_d2_d2", + "mainpll_d3", + "mainpll_d2_d4", + "univpll_d3" +}; + +static const char * const fufs_parents[] = { + "clk26m", + "mainpll_d2_d4", + "mainpll_d2_d8", + "mainpll_d2_d16" +}; + +static const char * const aud_1_parents[] = { + "clk26m", + "apll1_ck" +}; + +static const char * const aud_2_parents[] = { + "clk26m", + "apll2_ck" +}; + +static const char * const adsp_parents[] = { + "clk26m", + "mainpll_d3", + "univpll_d2_d4", + "univpll_d2", + "mmpll_d4", + "adsppll_d4", + "adsppll_d6" +}; + +static const char * const dpmaif_parents[] = { + "clk26m", + "univpll_d2_d4", + "mainpll_d3", + "mainpll_d2_d2", + "univpll_d2_d2", + "univpll_d3" +}; + +static const char * const venc_parents[] = { + "clk26m", + "mmpll_d7", + "mainpll_d3", + "univpll_d2_d2", + "mainpll_d2_d2", + "univpll_d3", + "mmpll_d6", + "mainpll_d5", + "mainpll_d3_d2", + "mmpll_d4_d2", + "univpll_d2_d4", + "mmpll_d5", + "univpll_192m_d2" + +}; + +static const char * const vdec_parents[] = { + "clk26m", + "univpll_d2_d4", + "mainpll_d3", + "univpll_d2_d2", + "mainpll_d2_d2", + "univpll_d3", + "univpll_d5", + "univpll_d5_d2", + "mainpll_d2", + "univpll_d2", + "univpll_192m_d2" +}; + +static const char * const camtm_parents[] = { + "clk26m", + "univpll_d7", + "univpll_d3_d2", + "univpll_d2_d2" +}; + +static const char * const pwm_parents[] = { + "clk26m", + "univpll_d2_d8" +}; + +static const char * const audio_h_parents[] = { + "clk26m", + "univpll_d7", + "apll1_ck", + "apll2_ck" +}; + +static const char * const camtg5_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d3_d8", + "univpll_192m_d4", + "univpll_d3_d16", + "csw_f26m_ck_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +/* + * CRITICAL CLOCK: + * axi_sel is the main bus clock of whole SOC. + * spm_sel is the clock of the always-on co-processor. + * sspm_sel is the clock of the always-on co-processor. + */ +static const struct mtk_mux top_muxes[] = { + /* CLK_CFG_0 */ + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI, "axi_sel", axi_parents, + 0x20, 0x24, 0x28, 0, 2, 7, + 0x004, 0, CLK_IS_CRITICAL), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MM, "mm_sel", mm_parents, + 0x20, 0x24, 0x28, 8, 3, 15, 0x004, 1), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP, "scp_sel", scp_parents, + 0x20, 0x24, 0x28, 16, 3, 23, 0x004, 2), + /* CLK_CFG_1 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG, "img_sel", img_parents, + 0x30, 0x34, 0x38, 0, 3, 7, 0x004, 4), + MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE, "ipe_sel", ipe_parents, + 0x30, 0x34, 0x38, 8, 3, 15, 0x004, 5), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPE, "dpe_sel", dpe_parents, + 0x30, 0x34, 0x38, 16, 3, 23, 0x004, 6), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM, "cam_sel", cam_parents, + 0x30, 0x34, 0x38, 24, 4, 31, 0x004, 7), + /* CLK_CFG_2 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_CCU, "ccu_sel", ccu_parents, + 0x40, 0x44, 0x48, 0, 4, 7, 0x004, 8), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP, "dsp_sel", dsp_parents, + 0x40, 0x44, 0x48, 8, 4, 15, 0x004, 9), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP1, "dsp1_sel", dsp1_parents, + 0x40, 0x44, 0x48, 16, 4, 23, 0x004, 10), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP2, "dsp2_sel", dsp2_parents, + 0x40, 0x44, 0x48, 24, 4, 31, 0x004, 11), + /* CLK_CFG_3 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP3, "dsp3_sel", dsp3_parents, + 0x50, 0x54, 0x58, 0, 4, 7, 0x004, 12), + MUX_GATE_CLR_SET_UPD(CLK_TOP_IPU_IF, "ipu_if_sel", ipu_if_parents, + 0x50, 0x54, 0x58, 8, 4, 15, 0x004, 13), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG, "mfg_sel", mfg_parents, + 0x50, 0x54, 0x58, 16, 2, 23, 0x004, 14), + MUX_GATE_CLR_SET_UPD(CLK_TOP_F52M_MFG, "f52m_mfg_sel", + f52m_mfg_parents, 0x50, 0x54, 0x58, + 24, 2, 31, 0x004, 15), + /* CLK_CFG_4 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG, "camtg_sel", camtg_parents, + 0x60, 0x64, 0x68, 0, 3, 7, 0x004, 16), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2, "camtg2_sel", camtg2_parents, + 0x60, 0x64, 0x68, 8, 3, 15, 0x004, 17), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3, "camtg3_sel", camtg3_parents, + 0x60, 0x64, 0x68, 16, 3, 23, 0x004, 18), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4, "camtg4_sel", camtg4_parents, + 0x60, 0x64, 0x68, 24, 3, 31, 0x004, 19), + /* CLK_CFG_5 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_UART, "uart_sel", uart_parents, + 0x70, 0x74, 0x78, 0, 1, 7, 0x004, 20), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI, "spi_sel", spi_parents, + 0x70, 0x74, 0x78, 8, 2, 15, 0x004, 21), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK, "msdc50_hclk_sel", + msdc50_hclk_parents, 0x70, 0x74, 0x78, + 16, 2, 23, 0x004, 22), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0, "msdc50_0_sel", + msdc50_0_parents, 0x70, 0x74, 0x78, + 24, 3, 31, 0x004, 23), + /* CLK_CFG_6 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1, "msdc30_1_sel", + msdc30_1_parents, 0x80, 0x84, 0x88, + 0, 3, 7, 0x004, 24), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD, "audio_sel", audio_parents, + 0x80, 0x84, 0x88, 8, 2, 15, 0x004, 25), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS, "aud_intbus_sel", + aud_intbus_parents, 0x80, 0x84, 0x88, + 16, 2, 23, 0x004, 26), + MUX_GATE_CLR_SET_UPD(CLK_TOP_FPWRAP_ULPOSC, "fpwrap_ulposc_sel", + fpwrap_ulposc_parents, 0x80, 0x84, 0x88, + 24, 3, 31, 0x004, 27), + /* CLK_CFG_7 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB, "atb_sel", atb_parents, + 0x90, 0x94, 0x98, 0, 2, 7, 0x004, 28), + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SSPM, "sspm_sel", sspm_parents, + 0x90, 0x94, 0x98, 8, 3, 15, + 0x004, 29, CLK_IS_CRITICAL), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI0, "dpi0_sel", dpi0_parents, + 0x90, 0x94, 0x98, 16, 3, 23, 0x004, 30), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SCAM, "scam_sel", scam_parents, + 0x90, 0x94, 0x98, 24, 1, 31, 0x004, 0), + /* CLK_CFG_8 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM, "disppwm_sel", + disppwm_parents, 0xa0, 0xa4, 0xa8, + 0, 3, 7, 0x008, 1), + MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP, "usb_top_sel", + usb_top_parents, 0xa0, 0xa4, 0xa8, + 8, 2, 15, 0x008, 2), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_TOP_XHCI, "ssusb_top_xhci_sel", + ssusb_top_xhci_parents, 0xa0, 0xa4, 0xa8, + 16, 2, 23, 0x008, 3), + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM, "spm_sel", spm_parents, + 0xa0, 0xa4, 0xa8, 24, 2, 31, + 0x008, 4, CLK_IS_CRITICAL), + /* CLK_CFG_9 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C, "i2c_sel", i2c_parents, + 0xb0, 0xb4, 0xb8, 0, 2, 7, 0x008, 5), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF, "seninf_sel", seninf_parents, + 0xb0, 0xb4, 0xb8, 8, 2, 15, 0x008, 6), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1, "seninf1_sel", + seninf1_parents, 0xb0, 0xb4, 0xb8, + 16, 2, 23, 0x008, 7), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2, "seninf2_sel", + seninf2_parents, 0xb0, 0xb4, 0xb8, + 24, 2, 31, 0x008, 8), + /* CLK_CFG_10 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC, "dxcc_sel", dxcc_parents, + 0xc0, 0xc4, 0xc8, 0, 2, 7, 0x008, 9), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENG1, "aud_eng1_sel", + aud_engen1_parents, 0xc0, 0xc4, 0xc8, + 8, 2, 15, 0x008, 10), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENG2, "aud_eng2_sel", + aud_engen2_parents, 0xc0, 0xc4, 0xc8, + 16, 2, 23, 0x008, 11), + MUX_GATE_CLR_SET_UPD(CLK_TOP_FAES_UFSFDE, "faes_ufsfde_sel", + faes_ufsfde_parents, 0xc0, 0xc4, 0xc8, + 24, 3, 31, + 0x008, 12), + /* CLK_CFG_11 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_FUFS, "fufs_sel", fufs_parents, + 0xd0, 0xd4, 0xd8, 0, 2, 7, 0x008, 13), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1, "aud_1_sel", aud_1_parents, + 0xd0, 0xd4, 0xd8, 8, 1, 15, 0x008, 14), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2, "aud_2_sel", aud_2_parents, + 0xd0, 0xd4, 0xd8, 16, 1, 23, 0x008, 15), + MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP, "adsp_sel", adsp_parents, + 0xd0, 0xd4, 0xd8, 24, 3, 31, 0x008, 16), + /* CLK_CFG_12 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF, "dpmaif_sel", dpmaif_parents, + 0xe0, 0xe4, 0xe8, 0, 3, 7, 0x008, 17), + MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC, "venc_sel", venc_parents, + 0xe0, 0xe4, 0xe8, 8, 4, 15, 0x008, 18), + MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC, "vdec_sel", vdec_parents, + 0xe0, 0xe4, 0xe8, 16, 4, 23, 0x008, 19), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM, "camtm_sel", camtm_parents, + 0xe0, 0xe4, 0xe8, 24, 2, 31, 0x004, 20), + /* CLK_CFG_13 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM, "pwm_sel", pwm_parents, + 0xf0, 0xf4, 0xf8, 0, 1, 7, 0x008, 21), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_H, "audio_h_sel", + audio_h_parents, 0xf0, 0xf4, 0xf8, + 8, 2, 15, 0x008, 22), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5, "camtg5_sel", camtg5_parents, + 0xf0, 0xf4, 0xf8, 24, 3, 31, 0x008, 24), +}; + +static const char * const i2s0_m_ck_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const i2s1_m_ck_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const i2s2_m_ck_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const i2s3_m_ck_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const i2s4_m_ck_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const i2s5_m_ck_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const struct mtk_composite top_aud_muxes[] = { + MUX(CLK_TOP_I2S0_M_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents, + 0x320, 8, 1), + MUX(CLK_TOP_I2S1_M_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents, + 0x320, 9, 1), + MUX(CLK_TOP_I2S2_M_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents, + 0x320, 10, 1), + MUX(CLK_TOP_I2S3_M_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents, + 0x320, 11, 1), + MUX(CLK_TOP_I2S4_M_SEL, "i2s4_m_ck_sel", i2s4_m_ck_parents, + 0x320, 12, 1), + MUX(CLK_TOP_I2S5_M_SEL, "i2s5_m_ck_sel", i2s5_m_ck_parents, + 0x328, 20, 1), +}; + +static struct mtk_composite top_aud_divs[] = { + DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "i2s0_m_ck_sel", + 0x320, 2, 0x324, 8, 0), + DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "i2s1_m_ck_sel", + 0x320, 3, 0x324, 8, 8), + DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "i2s2_m_ck_sel", + 0x320, 4, 0x324, 8, 16), + DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "i2s3_m_ck_sel", + 0x320, 5, 0x324, 8, 24), + DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "i2s4_m_ck_sel", + 0x320, 6, 0x328, 8, 0), + DIV_GATE(CLK_TOP_APLL12_DIVB, "apll12_divb", "apll12_div4", + 0x320, 7, 0x328, 8, 8), + DIV_GATE(CLK_TOP_APLL12_DIV5, "apll12_div5", "i2s5_m_ck_sel", + 0x328, 16, 0x328, 4, 28), +}; + +static const struct mtk_gate_regs infra0_cg_regs = { + .set_ofs = 0x80, + .clr_ofs = 0x84, + .sta_ofs = 0x90, +}; + +static const struct mtk_gate_regs infra1_cg_regs = { + .set_ofs = 0x88, + .clr_ofs = 0x8c, + .sta_ofs = 0x94, +}; + +static const struct mtk_gate_regs infra2_cg_regs = { + .set_ofs = 0xa4, + .clr_ofs = 0xa8, + .sta_ofs = 0xac, +}; + +static const struct mtk_gate_regs infra3_cg_regs = { + .set_ofs = 0xc0, + .clr_ofs = 0xc4, + .sta_ofs = 0xc8, +}; + +#define GATE_INFRA0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) +#define GATE_INFRA1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra1_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) +#define GATE_INFRA2(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) +#define GATE_INFRA3(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra3_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate infra_clks[] = { + /* INFRA0 */ + GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", + "axi_sel", 0), + GATE_INFRA0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", + "axi_sel", 1), + GATE_INFRA0(CLK_INFRA_PMIC_MD, "infra_pmic_md", + "axi_sel", 2), + GATE_INFRA0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn", + "axi_sel", 3), + GATE_INFRA0(CLK_INFRA_SCPSYS, "infra_scp", + "axi_sel", 4), + GATE_INFRA0(CLK_INFRA_SEJ, "infra_sej", + "f_f26m_ck", 5), + GATE_INFRA0(CLK_INFRA_APXGPT, "infra_apxgpt", + "axi_sel", 6), + GATE_INFRA0(CLK_INFRA_ICUSB, "infra_icusb", + "axi_sel", 8), + GATE_INFRA0(CLK_INFRA_GCE, "infra_gce", + "axi_sel", 9), + GATE_INFRA0(CLK_INFRA_THERM, "infra_therm", + "axi_sel", 10), + GATE_INFRA0(CLK_INFRA_I2C0, "infra_i2c0", + "i2c_sel", 11), + GATE_INFRA0(CLK_INFRA_I2C1, "infra_i2c1", + "i2c_sel", 12), + GATE_INFRA0(CLK_INFRA_I2C2, "infra_i2c2", + "i2c_sel", 13), + GATE_INFRA0(CLK_INFRA_I2C3, "infra_i2c3", + "i2c_sel", 14), + GATE_INFRA0(CLK_INFRA_PWM_HCLK, "infra_pwm_hclk", + "pwm_sel", 15), + GATE_INFRA0(CLK_INFRA_PWM1, "infra_pwm1", + "pwm_sel", 16), + GATE_INFRA0(CLK_INFRA_PWM2, "infra_pwm2", + "pwm_sel", 17), + GATE_INFRA0(CLK_INFRA_PWM3, "infra_pwm3", + "pwm_sel", 18), + GATE_INFRA0(CLK_INFRA_PWM4, "infra_pwm4", + "pwm_sel", 19), + GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm", + "pwm_sel", 21), + GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1", + "uart_sel", 23), + GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2", + "uart_sel", 24), + GATE_INFRA0(CLK_INFRA_UART3, "infra_uart3", + "uart_sel", 25), + GATE_INFRA0(CLK_INFRA_GCE_26M, "infra_gce_26m", + "axi_sel", 27), + GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, "infra_cqdma_fpc", + "axi_sel", 28), + GATE_INFRA0(CLK_INFRA_BTIF, "infra_btif", + "axi_sel", 31), + /* INFRA1 */ + GATE_INFRA1(CLK_INFRA_SPI0, "infra_spi0", + "spi_sel", 1), + GATE_INFRA1(CLK_INFRA_MSDC0, "infra_msdc0", + "msdc50_hclk_sel", 2), + GATE_INFRA1(CLK_INFRA_MSDC1, "infra_msdc1", + "axi_sel", 4), + GATE_INFRA1(CLK_INFRA_MSDC2, "infra_msdc2", + "axi_sel", 5), + GATE_INFRA1(CLK_INFRA_MSDC0_SCK, "infra_msdc0_sck", + "msdc50_0_sel", 6), + GATE_INFRA1(CLK_INFRA_DVFSRC, "infra_dvfsrc", + "f_f26m_ck", 7), + GATE_INFRA1(CLK_INFRA_GCPU, "infra_gcpu", + "axi_sel", 8), + GATE_INFRA1(CLK_INFRA_TRNG, "infra_trng", + "axi_sel", 9), + GATE_INFRA1(CLK_INFRA_AUXADC, "infra_auxadc", + "f_f26m_ck", 10), + GATE_INFRA1(CLK_INFRA_CPUM, "infra_cpum", + "axi_sel", 11), + GATE_INFRA1(CLK_INFRA_CCIF1_AP, "infra_ccif1_ap", + "axi_sel", 12), + GATE_INFRA1(CLK_INFRA_CCIF1_MD, "infra_ccif1_md", + "axi_sel", 13), + GATE_INFRA1(CLK_INFRA_AUXADC_MD, "infra_auxadc_md", + "f_f26m_ck", 14), + GATE_INFRA1(CLK_INFRA_MSDC1_SCK, "infra_msdc1_sck", + "msdc30_1_sel", 16), + GATE_INFRA1(CLK_INFRA_MSDC2_SCK, "infra_msdc2_sck", + "msdc30_2_sel", 17), + GATE_INFRA1(CLK_INFRA_AP_DMA, "infra_apdma", + "axi_sel", 18), + GATE_INFRA1(CLK_INFRA_XIU, "infra_xiu", + "axi_sel", 19), + GATE_INFRA1(CLK_INFRA_DEVICE_APC, "infra_device_apc", + "axi_sel", 20), + GATE_INFRA1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", + "axi_sel", 23), + GATE_INFRA1(CLK_INFRA_DEBUGSYS, "infra_debugsys", + "axi_sel", 24), + GATE_INFRA1(CLK_INFRA_AUD, "infra_audio", + "axi_sel", 25), + GATE_INFRA1(CLK_INFRA_CCIF_MD, "infra_ccif_md", + "axi_sel", 26), + GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, "infra_dxcc_sec_core", + "dxcc_sel", 27), + GATE_INFRA1(CLK_INFRA_DXCC_AO, "infra_dxcc_ao", + "dxcc_sel", 28), + GATE_INFRA1(CLK_INFRA_DEVMPU_BCLK, "infra_devmpu_bclk", + "axi_sel", 30), + GATE_INFRA1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", + "f_f26m_ck", 31), + /* INFRA2 */ + GATE_INFRA2(CLK_INFRA_IRTX, "infra_irtx", + "f_f26m_ck", 0), + GATE_INFRA2(CLK_INFRA_USB, "infra_usb", + "usb_top_sel", 1), + GATE_INFRA2(CLK_INFRA_DISP_PWM, "infra_disppwm", + "axi_sel", 2), + GATE_INFRA2(CLK_INFRA_AUD_26M_BCLK, + "infracfg_ao_audio_26m_bclk", "f_f26m_ck", 4), + GATE_INFRA2(CLK_INFRA_SPI1, "infra_spi1", + "spi_sel", 6), + GATE_INFRA2(CLK_INFRA_I2C4, "infra_i2c4", + "i2c_sel", 7), + GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_md_tmp_share", + "f_f26m_ck", 8), + GATE_INFRA2(CLK_INFRA_SPI2, "infra_spi2", + "spi_sel", 9), + GATE_INFRA2(CLK_INFRA_SPI3, "infra_spi3", + "spi_sel", 10), + GATE_INFRA2(CLK_INFRA_UNIPRO_SCK, "infra_unipro_sck", + "fufs_sel", 11), + GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, "infra_unipro_tick", + "fufs_sel", 12), + GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_BCLK, "infra_ufs_mp_sap_bck", + "fufs_sel", 13), + GATE_INFRA2(CLK_INFRA_MD32_BCLK, "infra_md32_bclk", + "axi_sel", 14), + GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist", + "axi_sel", 16), + GATE_INFRA2(CLK_INFRA_SSPM_BUS_HCLK, "infra_sspm_bus_hclk", + "axi_sel", 17), + GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5", + "i2c_sel", 18), + GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter", + "i2c_sel", 19), + GATE_INFRA2(CLK_INFRA_I2C5_IMM, "infra_i2c5_imm", + "i2c_sel", 20), + GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, "infra_i2c1_arbiter", + "i2c_sel", 21), + GATE_INFRA2(CLK_INFRA_I2C1_IMM, "infra_i2c1_imm", + "i2c_sel", 22), + GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, "infra_i2c2_arbiter", + "i2c_sel", 23), + GATE_INFRA2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm", + "i2c_sel", 24), + GATE_INFRA2(CLK_INFRA_SPI4, "infra_spi4", + "spi_sel", 25), + GATE_INFRA2(CLK_INFRA_SPI5, "infra_spi5", + "spi_sel", 26), + GATE_INFRA2(CLK_INFRA_CQ_DMA, "infra_cqdma", + "axi_sel", 27), + GATE_INFRA2(CLK_INFRA_UFS, "infra_ufs", + "fufs_sel", 28), + GATE_INFRA2(CLK_INFRA_AES_UFSFDE, "infra_aes_ufsfde", + "faes_ufsfde_sel", 29), + GATE_INFRA2(CLK_INFRA_UFS_TICK, "infra_ufs_tick", + "fufs_sel", 30), + GATE_INFRA2(CLK_INFRA_SSUSB_XHCI, "infra_ssusb_xhci", + "ssusb_top_xhci_sel", 31), + /* INFRA3 */ + GATE_INFRA3(CLK_INFRA_MSDC0_SELF, "infra_msdc0_self", + "msdc50_0_sel", 0), + GATE_INFRA3(CLK_INFRA_MSDC1_SELF, "infra_msdc1_self", + "msdc50_0_sel", 1), + GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self", + "msdc50_0_sel", 2), + GATE_INFRA3(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self", + "f_f26m_ck", 3), + GATE_INFRA3(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", + "f_f26m_ck", 4), + GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", + "axi_sel", 5), + GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", + "i2c_sel", 6), + GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", + "msdc50_hclk_sel", 7), + GATE_INFRA3(CLK_INFRA_MD_MSDC0, "infra_md_msdc0", + "msdc50_hclk_sel", 8), + GATE_INFRA3(CLK_INFRA_CCIF2_AP, "infra_ccif2_ap", + "axi_sel", 16), + GATE_INFRA3(CLK_INFRA_CCIF2_MD, "infra_ccif2_md", + "axi_sel", 17), + GATE_INFRA3(CLK_INFRA_CCIF3_AP, "infra_ccif3_ap", + "axi_sel", 18), + GATE_INFRA3(CLK_INFRA_CCIF3_MD, "infra_ccif3_md", + "axi_sel", 19), + GATE_INFRA3(CLK_INFRA_SEJ_F13M, "infra_sej_f13m", + "f_f26m_ck", 20), + GATE_INFRA3(CLK_INFRA_AES_BCLK, "infra_aes_bclk", + "axi_sel", 21), + GATE_INFRA3(CLK_INFRA_I2C7, "infra_i2c7", + "i2c_sel", 22), + GATE_INFRA3(CLK_INFRA_I2C8, "infra_i2c8", + "i2c_sel", 23), + GATE_INFRA3(CLK_INFRA_FBIST2FPC, "infra_fbist2fpc", + "msdc50_0_sel", 24), + GATE_INFRA3(CLK_INFRA_DPMAIF_CK, "infra_dpmaif", + "dpmaif_sel", 26), + GATE_INFRA3(CLK_INFRA_FADSP, "infra_fadsp", + "adsp_sel", 27), + GATE_INFRA3(CLK_INFRA_CCIF4_AP, "infra_ccif4_ap", + "axi_sel", 28), + GATE_INFRA3(CLK_INFRA_CCIF4_MD, "infra_ccif4_md", + "axi_sel", 29), + GATE_INFRA3(CLK_INFRA_SPI6, "infra_spi6", + "spi_sel", 30), + GATE_INFRA3(CLK_INFRA_SPI7, "infra_spi7", + "spi_sel", 31), +}; + +static const struct mtk_gate_regs apmixed_cg_regs = { + .set_ofs = 0x20, + .clr_ofs = 0x20, + .sta_ofs = 0x20, +}; + +#define GATE_APMIXED_FLAGS(_id, _name, _parent, _shift, _flags) \ + GATE_MTK_FLAGS(_id, _name, _parent, &apmixed_cg_regs, \ + _shift, &mtk_clk_gate_ops_no_setclr_inv, _flags) + +#define GATE_APMIXED(_id, _name, _parent, _shift) \ + GATE_APMIXED_FLAGS(_id, _name, _parent, _shift, 0) + +/* + * CRITICAL CLOCK: + * apmixed_appll26m is the toppest clock gate of all PLLs. + */ +static const struct mtk_gate apmixed_clks[] = { + GATE_APMIXED(CLK_APMIXED_SSUSB26M, "apmixed_ssusb26m", + "f_f26m_ck", 4), + GATE_APMIXED_FLAGS(CLK_APMIXED_APPLL26M, "apmixed_appll26m", + "f_f26m_ck", 5, CLK_IS_CRITICAL), + GATE_APMIXED(CLK_APMIXED_MIPIC0_26M, "apmixed_mipic026m", + "f_f26m_ck", 6), + GATE_APMIXED(CLK_APMIXED_MDPLLGP26M, "apmixed_mdpll26m", + "f_f26m_ck", 7), + GATE_APMIXED(CLK_APMIXED_MM_F26M, "apmixed_mmsys26m", + "f_f26m_ck", 8), + GATE_APMIXED(CLK_APMIXED_UFS26M, "apmixed_ufs26m", + "f_f26m_ck", 9), + GATE_APMIXED(CLK_APMIXED_MIPIC1_26M, "apmixed_mipic126m", + "f_f26m_ck", 11), + GATE_APMIXED(CLK_APMIXED_MEMPLL26M, "apmixed_mempll26m", + "f_f26m_ck", 13), + GATE_APMIXED(CLK_APMIXED_CLKSQ_LVPLL_26M, "apmixed_lvpll26m", + "f_f26m_ck", 14), + GATE_APMIXED(CLK_APMIXED_MIPID0_26M, "apmixed_mipid026m", + "f_f26m_ck", 16), + GATE_APMIXED(CLK_APMIXED_MIPID1_26M, "apmixed_mipid126m", + "f_f26m_ck", 17), +}; + +#define MT6779_PLL_FMAX (3800UL * MHZ) +#define MT6779_PLL_FMIN (1500UL * MHZ) + +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ + _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg, \ + _pd_shift, _tuner_reg, _tuner_en_reg, \ + _tuner_en_bit, _pcw_reg, _pcw_shift, \ + _pcw_chg_reg, _div_table) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .pwr_reg = _pwr_reg, \ + .en_mask = _en_mask, \ + .flags = _flags, \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT6779_PLL_FMAX, \ + .fmin = MT6779_PLL_FMIN, \ + .pcwbits = _pcwbits, \ + .pcwibits = _pcwibits, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcw_chg_reg = _pcw_chg_reg, \ + .div_table = _div_table, \ + } + +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ + _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg, \ + _pd_shift, _tuner_reg, _tuner_en_reg, \ + _tuner_en_bit, _pcw_reg, _pcw_shift, \ + _pcw_chg_reg) \ + PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ + _rst_bar_mask, _pcwbits, _pcwibits, _pd_reg, \ + _pd_shift, _tuner_reg, _tuner_en_reg, \ + _tuner_en_bit, _pcw_reg, _pcw_shift, \ + _pcw_chg_reg, NULL) + +static const struct mtk_pll_data plls[] = { + PLL(CLK_APMIXED_ARMPLL_LL, "armpll_ll", 0x0200, 0x020C, BIT(0), + PLL_AO, 0, 22, 8, 0x0204, 24, 0, 0, 0, 0x0204, 0, 0), + PLL(CLK_APMIXED_ARMPLL_BL, "armpll_bl", 0x0210, 0x021C, BIT(0), + PLL_AO, 0, 22, 8, 0x0214, 24, 0, 0, 0, 0x0214, 0, 0), + PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x02A0, 0x02AC, BIT(0), + PLL_AO, 0, 22, 8, 0x02A4, 24, 0, 0, 0, 0x02A4, 0, 0), + PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, BIT(0), + (HAVE_RST_BAR), BIT(24), 22, 8, 0x0234, 24, 0, 0, 0, + 0x0234, 0, 0), + PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0240, 0x024C, BIT(0), + (HAVE_RST_BAR), BIT(24), 22, 8, 0x0244, 24, + 0, 0, 0, 0x0244, 0, 0), + PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0250, 0x025C, BIT(0), + 0, 0, 22, 8, 0x0254, 24, 0, 0, 0, 0x0254, 0, 0), + PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0260, 0x026C, BIT(0), + 0, 0, 22, 8, 0x0264, 24, 0, 0, 0, 0x0264, 0, 0), + PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0270, 0x027C, BIT(0), + 0, 0, 22, 8, 0x0274, 24, 0, 0, 0, 0x0274, 0, 0), + PLL(CLK_APMIXED_ADSPPLL, "adsppll", 0x02b0, 0x02bC, BIT(0), + (HAVE_RST_BAR), BIT(23), 22, 8, 0x02b4, 24, + 0, 0, 0, 0x02b4, 0, 0), + PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0280, 0x028C, BIT(0), + (HAVE_RST_BAR), BIT(23), 22, 8, 0x0284, 24, + 0, 0, 0, 0x0284, 0, 0), + PLL(CLK_APMIXED_APLL1, "apll1", 0x02C0, 0x02D0, BIT(0), + 0, 0, 32, 8, 0x02C0, 1, 0, 0x14, 0, 0x02C4, 0, 0x2C0), + PLL(CLK_APMIXED_APLL2, "apll2", 0x02D4, 0x02E4, BIT(0), + 0, 0, 32, 8, 0x02D4, 1, 0, 0x14, 1, 0x02D8, 0, 0x02D4), +}; + +static int clk_mt6779_apmixed_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); + + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + + mtk_clk_register_gates(node, apmixed_clks, + ARRAY_SIZE(apmixed_clks), clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static int clk_mt6779_top_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + void __iomem *base; + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), + clk_data); + + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); + + mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), + node, &mt6779_clk_lock, clk_data); + + mtk_clk_register_composites(top_aud_muxes, ARRAY_SIZE(top_aud_muxes), + base, &mt6779_clk_lock, clk_data); + + mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), + base, &mt6779_clk_lock, clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static int clk_mt6779_infra_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); + + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static const struct of_device_id of_match_clk_mt6779[] = { + { + .compatible = "mediatek,mt6779-apmixed", + .data = clk_mt6779_apmixed_probe, + }, { + .compatible = "mediatek,mt6779-topckgen", + .data = clk_mt6779_top_probe, + }, { + .compatible = "mediatek,mt6779-infracfg_ao", + .data = clk_mt6779_infra_probe, + }, { + /* sentinel */ + } +}; + +static int clk_mt6779_probe(struct platform_device *pdev) +{ + int (*clk_probe)(struct platform_device *pdev); + int r; + + clk_probe = of_device_get_match_data(&pdev->dev); + if (!clk_probe) + return -EINVAL; + + r = clk_probe(pdev); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + return r; +} + +static struct platform_driver clk_mt6779_drv = { + .probe = clk_mt6779_probe, + .driver = { + .name = "clk-mt6779", + .of_match_table = of_match_clk_mt6779, + }, +}; + +static int __init clk_mt6779_init(void) +{ + return platform_driver_register(&clk_mt6779_drv); +} + +arch_initcall(clk_mt6779_init); From 5aa00ad3fd3338eba1ed8bbb1a142eb40f43d728 Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Wed, 28 Aug 2019 16:22:12 +0800 Subject: [PATCH 50/62] dt-bindings: clock: mediatek: add pericfg for MT8183 This patch adds binding of pericfg for MT8183. Signed-off-by: Chunfeng Yun Link: https://lkml.kernel.org/r/1566980533-28282-1-git-send-email-chunfeng.yun@mediatek.com Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/arm/mediatek/mediatek,pericfg.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt index 4c7e478117a0..ecf027a9003a 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt @@ -14,6 +14,7 @@ Required Properties: - "mediatek,mt7629-pericfg", "syscon" - "mediatek,mt8135-pericfg", "syscon" - "mediatek,mt8173-pericfg", "syscon" + - "mediatek,mt8183-pericfg", "syscon" - #clock-cells: Must be 1 - #reset-cells: Must be 1 From f9e55ac22ce9246c085e1c97ddda93608ce17eaf Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Wed, 28 Aug 2019 16:22:13 +0800 Subject: [PATCH 51/62] clk: mediatek: add pericfg clocks for MT8183 Add pericfg clocks for MT8183, it's used when support USB remote wakeup Cc: Weiyi Lu Signed-off-by: Chunfeng Yun Link: https://lkml.kernel.org/r/1566980533-28282-2-git-send-email-chunfeng.yun@mediatek.com Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt8183.c | 30 ++++++++++++++++++++++++++ include/dt-bindings/clock/mt8183-clk.h | 4 ++++ 2 files changed, 34 insertions(+) diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c index 94bbadc0d259..7e7452e56694 100644 --- a/drivers/clk/mediatek/clk-mt8183.c +++ b/drivers/clk/mediatek/clk-mt8183.c @@ -1002,6 +1002,20 @@ static const struct mtk_gate infra_clks[] = { "msdc50_0_sel", 24), }; +static const struct mtk_gate_regs peri_cg_regs = { + .set_ofs = 0x20c, + .clr_ofs = 0x20c, + .sta_ofs = 0x20c, +}; + +#define GATE_PERI(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &peri_cg_regs, _shift, \ + &mtk_clk_gate_ops_no_setclr_inv) + +static const struct mtk_gate peri_clks[] = { + GATE_PERI(CLK_PERI_AXI, "peri_axi", "axi_sel", 31), +}; + static const struct mtk_gate_regs apmixed_cg_regs = { .set_ofs = 0x20, .clr_ofs = 0x20, @@ -1208,6 +1222,19 @@ static int clk_mt8183_infra_probe(struct platform_device *pdev) return r; } +static int clk_mt8183_peri_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + + clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); + + mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), + clk_data); + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + static int clk_mt8183_mcu_probe(struct platform_device *pdev) { struct clk_onecell_data *clk_data; @@ -1237,6 +1264,9 @@ static const struct of_device_id of_match_clk_mt8183[] = { }, { .compatible = "mediatek,mt8183-infracfg", .data = clk_mt8183_infra_probe, + }, { + .compatible = "mediatek,mt8183-pericfg", + .data = clk_mt8183_peri_probe, }, { .compatible = "mediatek,mt8183-mcucfg", .data = clk_mt8183_mcu_probe, diff --git a/include/dt-bindings/clock/mt8183-clk.h b/include/dt-bindings/clock/mt8183-clk.h index 0046506eb24c..a7b470b0ec8a 100644 --- a/include/dt-bindings/clock/mt8183-clk.h +++ b/include/dt-bindings/clock/mt8183-clk.h @@ -284,6 +284,10 @@ #define CLK_INFRA_FBIST2FPC 100 #define CLK_INFRA_NR_CLK 101 +/* PERICFG */ +#define CLK_PERI_AXI 0 +#define CLK_PERI_NR_CLK 1 + /* MFGCFG */ #define CLK_MFG_BG3D 0 #define CLK_MFG_NR_CLK 1 From e4c23e19aa2a611c2068f7c55487d2cbfea690ef Mon Sep 17 00:00:00 2001 From: Weiyi Lu Date: Mon, 2 Sep 2019 17:00:57 +0800 Subject: [PATCH 52/62] clk: mediatek: Register clock gate with device Allow those clocks under a power domain to do the runtime pm operation by forwarding the struct device pointer from clock provider. Signed-off-by: Weiyi Lu Link: https://lkml.kernel.org/r/1567414859-3244-2-git-send-email-weiyi.lu@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-gate.c | 5 +++-- drivers/clk/mediatek/clk-gate.h | 3 ++- drivers/clk/mediatek/clk-mtk.c | 16 +++++++++++++--- drivers/clk/mediatek/clk-mtk.h | 5 +++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 803bf0ae1fd6..a35cf0b22150 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -150,7 +150,8 @@ struct clk *mtk_clk_register_gate( int sta_ofs, u8 bit, const struct clk_ops *ops, - unsigned long flags) + unsigned long flags, + struct device *dev) { struct mtk_clk_gate *cg; struct clk *clk; @@ -174,7 +175,7 @@ struct clk *mtk_clk_register_gate( cg->hw.init = &init; - clk = clk_register(NULL, &cg->hw); + clk = clk_register(dev, &cg->hw); if (IS_ERR(clk)) kfree(cg); diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h index e05c73697485..3c3329ec54b7 100644 --- a/drivers/clk/mediatek/clk-gate.h +++ b/drivers/clk/mediatek/clk-gate.h @@ -40,7 +40,8 @@ struct clk *mtk_clk_register_gate( int sta_ofs, u8 bit, const struct clk_ops *ops, - unsigned long flags); + unsigned long flags, + struct device *dev); #define GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, \ _ops, _flags) { \ diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index d28790c74919..cec1c8a27211 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "clk-mtk.h" #include "clk-gate.h" @@ -93,9 +94,10 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, } } -int mtk_clk_register_gates(struct device_node *node, +int mtk_clk_register_gates_with_dev(struct device_node *node, const struct mtk_gate *clks, - int num, struct clk_onecell_data *clk_data) + int num, struct clk_onecell_data *clk_data, + struct device *dev) { int i; struct clk *clk; @@ -122,7 +124,7 @@ int mtk_clk_register_gates(struct device_node *node, gate->regs->set_ofs, gate->regs->clr_ofs, gate->regs->sta_ofs, - gate->shift, gate->ops, gate->flags); + gate->shift, gate->ops, gate->flags, dev); if (IS_ERR(clk)) { pr_err("Failed to register clk %s: %ld\n", @@ -136,6 +138,14 @@ int mtk_clk_register_gates(struct device_node *node, return 0; } +int mtk_clk_register_gates(struct device_node *node, + const struct mtk_gate *clks, + int num, struct clk_onecell_data *clk_data) +{ + return mtk_clk_register_gates_with_dev(node, + clks, num, clk_data, NULL); +} + struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, void __iomem *base, spinlock_t *lock) { diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 2e9e26084798..c3d6756b0c7e 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -169,6 +169,11 @@ int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, int num, struct clk_onecell_data *clk_data); +int mtk_clk_register_gates_with_dev(struct device_node *node, + const struct mtk_gate *clks, + int num, struct clk_onecell_data *clk_data, + struct device *dev); + struct mtk_clk_divider { int id; const char *name; From 327aa741563806f8b67fbf5e665be203acf5f4f5 Mon Sep 17 00:00:00 2001 From: Weiyi Lu Date: Mon, 2 Sep 2019 17:00:58 +0800 Subject: [PATCH 53/62] clk: mediatek: Runtime PM support for MT8183 mcucfg clock provider Enable the runtime PM support and forward the struct device pointer for registration of MT8183 mcucfg clocks. Signed-off-by: Weiyi Lu Link: https://lkml.kernel.org/r/1567414859-3244-3-git-send-email-weiyi.lu@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt8183-mfgcfg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c index 99a6b020833e..37b4162c5882 100644 --- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c +++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c @@ -5,6 +5,7 @@ #include #include +#include #include "clk-mtk.h" #include "clk-gate.h" @@ -30,10 +31,12 @@ static int clk_mt8183_mfg_probe(struct platform_device *pdev) struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; + pm_runtime_enable(&pdev->dev); + clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK); - mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks), - clk_data); + mtk_clk_register_gates_with_dev(node, mfg_clks, ARRAY_SIZE(mfg_clks), + clk_data, &pdev->dev); return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); } From 21ea4b62e1f3dc258001a68da98c9663a9dbd6c7 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Wed, 8 May 2019 23:54:53 +0530 Subject: [PATCH 54/62] clk: qcom: rcg: Return failure for RCG update In case of update config failure, return -EBUSY, so that consumers could handle the failure gracefully. Signed-off-by: Taniya Das Link: https://lkml.kernel.org/r/1557339895-21952-2-git-send-email-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rcg2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 8c02bffe50df..57dbac9a590e 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -119,7 +119,7 @@ static int update_config(struct clk_rcg2 *rcg) } WARN(1, "%s: rcg didn't update its configuration.", name); - return 0; + return -EBUSY; } static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) From d827af8f37e9c0183d383fe1955338373da5f394 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 5 Aug 2019 12:03:03 +0200 Subject: [PATCH 55/62] dt-bindings: ap80x: Document AP807 CPU clock compatible Add AP807 CPU clock compatible to the bindings. Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-2-miquel.raynal@bootlin.com Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/arm/marvell/ap806-system-controller.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt index 4f21c1024073..59b6b992fbc9 100644 --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt @@ -147,11 +147,14 @@ ap_syscon1: system-controller@6f8000 { Cluster clocks: --------------- -Device Tree Clock bindings for cluster clock of AP806 Marvell. Each -cluster contain up to 2 CPUs running at the same frequency. +Device Tree Clock bindings for cluster clock of Marvell +AP806/AP807. Each cluster contain up to 2 CPUs running at the same +frequency. Required properties: -- compatible: must be "marvell,ap806-cpu-clock"; + - compatible: must be one of: + * "marvell,ap806-cpu-clock" + * "marvell,ap807-cpu-clock" - #clock-cells : should be set to 1. - clocks : shall be the input parent clock(s) phandle for the clock From 64b379543e2aa64a1328ab3c7f4f34dd467b9474 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 5 Aug 2019 12:03:04 +0200 Subject: [PATCH 56/62] dt-bindings: ap806: Document AP807 clock compatible Add AP807 clock compatible to the bindings. Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-3-miquel.raynal@bootlin.com Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/arm/marvell/ap806-system-controller.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt index 59b6b992fbc9..26410fbb85be 100644 --- a/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt +++ b/Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt @@ -18,8 +18,8 @@ Clocks: ------- -The Device Tree node representing the AP806 system controller provides -a number of clocks: +The Device Tree node representing the AP806/AP807 system controller +provides a number of clocks: - 0: reference clock of CPU cluster 0 - 1: reference clock of CPU cluster 1 @@ -28,7 +28,9 @@ a number of clocks: Required properties: - - compatible: must be: "marvell,ap806-clock" + - compatible: must be one of: + * "marvell,ap806-clock" + * "marvell,ap807-clock" - #clock-cells: must be set to 1 Pinctrl: From a77f45eaa266e493e2bf190b5af6b88940dc0174 Mon Sep 17 00:00:00 2001 From: Christine Gharzuzi Date: Mon, 5 Aug 2019 12:03:05 +0200 Subject: [PATCH 57/62] clk: mvebu: ap806-cpu: prepare mapping of AP807 CPU clock This patch allows same flow to be executed on chips with different register mappings like AP806 and, in the future, AP807. Note: this patch has no functional effect, and only prepares the driver for additional chips to be supported by retrieving the right device data depenging on the compatible property. Signed-off-by: Christine Gharzuzi Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-4-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap-cpu-clk.c | 82 +++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index e4cecb456884..784104f6793b 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include "armada_ap_cp_helper.h" @@ -29,6 +30,26 @@ #define APN806_MAX_DIVIDER 32 +/** + * struct cpu_dfs_regs: CPU DFS register mapping + * @divider_reg: full integer ratio from PLL frequency to CPU clock frequency + * @force_reg: request to force new ratio regardless of relation to other clocks + * @ratio_reg: central request to switch ratios + */ +struct cpu_dfs_regs { + unsigned int divider_reg; + unsigned int force_reg; + unsigned int ratio_reg; + unsigned int ratio_state_reg; + unsigned int divider_mask; + unsigned int cluster_offset; + unsigned int force_mask; + int divider_offset; + int ratio_offset; + int ratio_state_offset; + int ratio_state_cluster_offset; +}; + /* AP806 CPU DFS register mapping*/ #define AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET 0x278 #define AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET 0x280 @@ -43,6 +64,7 @@ #define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK \ (0x1 << AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET) #define AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET 16 +#define AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET 0 #define AP806_CA72MP2_0_PLL_RATIO_STATE 11 #define STATUS_POLL_PERIOD_US 1 @@ -50,6 +72,20 @@ #define to_ap_cpu_clk(_hw) container_of(_hw, struct ap_cpu_clk, hw) +static const struct cpu_dfs_regs ap806_dfs_regs = { + .divider_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET, + .force_reg = AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET, + .ratio_reg = AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET, + .ratio_state_reg = AP806_CA72MP2_0_PLL_SR_REG_OFFSET, + .divider_mask = AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK, + .cluster_offset = AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET, + .force_mask = AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK, + .divider_offset = AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET, + .ratio_offset = AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET, + .ratio_state_offset = AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET, + .ratio_state_cluster_offset = AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET, +}; + /* * struct ap806_clk: CPU cluster clock controller instance * @cluster: Cluster clock controller index @@ -64,6 +100,7 @@ struct ap_cpu_clk { struct device *dev; struct clk_hw hw; struct regmap *pll_cr_base; + const struct cpu_dfs_regs *pll_regs; }; static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw, @@ -73,11 +110,11 @@ static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw, unsigned int cpu_clkdiv_reg; int cpu_clkdiv_ratio; - cpu_clkdiv_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET + - (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); + cpu_clkdiv_reg = clk->pll_regs->divider_reg + + (clk->cluster * clk->pll_regs->cluster_offset); regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, &cpu_clkdiv_ratio); - cpu_clkdiv_ratio &= AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK; - cpu_clkdiv_ratio >>= AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET; + cpu_clkdiv_ratio &= clk->pll_regs->divider_mask; + cpu_clkdiv_ratio >>= clk->pll_regs->divider_offset; return parent_rate / cpu_clkdiv_ratio; } @@ -89,35 +126,36 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate, int ret, reg, divider = parent_rate / rate; unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit; - cpu_clkdiv_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET + - (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); - cpu_force_reg = AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET + - (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); - cpu_ratio_reg = AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET + - (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET); + cpu_clkdiv_reg = clk->pll_regs->divider_reg + + (clk->cluster * clk->pll_regs->cluster_offset); + cpu_force_reg = clk->pll_regs->force_reg + + (clk->cluster * clk->pll_regs->cluster_offset); + cpu_ratio_reg = clk->pll_regs->ratio_reg + + (clk->cluster * clk->pll_regs->cluster_offset); regmap_update_bits(clk->pll_cr_base, cpu_clkdiv_reg, - AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK, divider); + clk->pll_regs->divider_mask, divider); regmap_update_bits(clk->pll_cr_base, cpu_force_reg, - AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK, - AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK); + clk->pll_regs->force_mask, + clk->pll_regs->force_mask); regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg, - BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET), - BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET)); - - stable_bit = BIT(clk->cluster * AP806_CA72MP2_0_PLL_RATIO_STATE), + BIT(clk->pll_regs->ratio_offset), + BIT(clk->pll_regs->ratio_offset)); + stable_bit = BIT(clk->pll_regs->ratio_state_offset + + clk->cluster * + clk->pll_regs->ratio_state_cluster_offset), ret = regmap_read_poll_timeout(clk->pll_cr_base, - AP806_CA72MP2_0_PLL_SR_REG_OFFSET, reg, + clk->pll_regs->ratio_state_reg, reg, reg & stable_bit, STATUS_POLL_PERIOD_US, STATUS_POLL_TIMEOUT_US); if (ret) return ret; regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg, - BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET), 0); + BIT(clk->pll_regs->ratio_offset), 0); return 0; } @@ -222,6 +260,7 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) ap_cpu_clk[cluster_index].pll_cr_base = regmap; ap_cpu_clk[cluster_index].hw.init = &init; ap_cpu_clk[cluster_index].dev = dev; + ap_cpu_clk[cluster_index].pll_regs = of_device_get_match_data(&pdev->dev); init.name = ap_cpu_clk[cluster_index].clk_name; init.ops = &ap_cpu_clk_ops; @@ -244,7 +283,10 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) } static const struct of_device_id ap_cpu_clock_of_match[] = { - { .compatible = "marvell,ap806-cpu-clock", }, + { + .compatible = "marvell,ap806-cpu-clock", + .data = &ap806_dfs_regs, + }, { } }; From 3b14e509ab997383e3ae243f1448886d748e3ac3 Mon Sep 17 00:00:00 2001 From: Ben Peled Date: Mon, 5 Aug 2019 12:03:06 +0200 Subject: [PATCH 58/62] clk: mvebu: ap80x-cpu: add AP807 CPU clock support Enhance the ap-cpu-clk driver to support both AP806 and AP807 CPU clocks. Signed-off-by: Ben Peled [: use device data instead of conditions on the compatible] Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-5-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap-cpu-clk.c | 59 ++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index 784104f6793b..af5e5acad370 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -45,6 +45,7 @@ struct cpu_dfs_regs { unsigned int cluster_offset; unsigned int force_mask; int divider_offset; + int divider_ratio; int ratio_offset; int ratio_state_offset; int ratio_state_cluster_offset; @@ -58,6 +59,7 @@ struct cpu_dfs_regs { #define AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET 0x14 #define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET 0 +#define AP806_PLL_CR_CPU_CLK_DIV_RATIO 0 #define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK \ (0x3f << AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET) #define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET 24 @@ -81,11 +83,47 @@ static const struct cpu_dfs_regs ap806_dfs_regs = { .cluster_offset = AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET, .force_mask = AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK, .divider_offset = AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET, + .divider_ratio = AP806_PLL_CR_CPU_CLK_DIV_RATIO, .ratio_offset = AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET, .ratio_state_offset = AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET, .ratio_state_cluster_offset = AP806_CA72MP2_0_PLL_RATIO_STABLE_OFFSET, }; +/* AP807 CPU DFS register mapping */ +#define AP807_DEVICE_GENERAL_CONTROL_10_REG_OFFSET 0x278 +#define AP807_DEVICE_GENERAL_CONTROL_11_REG_OFFSET 0x27c +#define AP807_DEVICE_GENERAL_STATUS_6_REG_OFFSET 0xc98 +#define AP807_CA72MP2_0_PLL_CR_CLUSTER_OFFSET 0x8 +#define AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET 18 +#define AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK \ + (0x3f << AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET) +#define AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET 12 +#define AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_MASK \ + (0x3f << AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET) +#define AP807_PLL_CR_CPU_CLK_DIV_RATIO 3 +#define AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET 0 +#define AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK \ + (0x3 << AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET) +#define AP807_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET 6 +#define AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_OFFSET 20 +#define AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_CLUSTER_OFFSET 3 + +static const struct cpu_dfs_regs ap807_dfs_regs = { + .divider_reg = AP807_DEVICE_GENERAL_CONTROL_10_REG_OFFSET, + .force_reg = AP807_DEVICE_GENERAL_CONTROL_11_REG_OFFSET, + .ratio_reg = AP807_DEVICE_GENERAL_CONTROL_11_REG_OFFSET, + .ratio_state_reg = AP807_DEVICE_GENERAL_STATUS_6_REG_OFFSET, + .divider_mask = AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK, + .cluster_offset = AP807_CA72MP2_0_PLL_CR_CLUSTER_OFFSET, + .force_mask = AP807_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK, + .divider_offset = AP807_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET, + .divider_ratio = AP807_PLL_CR_CPU_CLK_DIV_RATIO, + .ratio_offset = AP807_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET, + .ratio_state_offset = AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_OFFSET, + .ratio_state_cluster_offset = + AP807_CA72MP2_0_PLL_CLKDIV_RATIO_STABLE_CLUSTER_OFFSET +}; + /* * struct ap806_clk: CPU cluster clock controller instance * @cluster: Cluster clock controller index @@ -133,8 +171,21 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate, cpu_ratio_reg = clk->pll_regs->ratio_reg + (clk->cluster * clk->pll_regs->cluster_offset); - regmap_update_bits(clk->pll_cr_base, cpu_clkdiv_reg, - clk->pll_regs->divider_mask, divider); + regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, ®); + reg &= ~(clk->pll_regs->divider_mask); + reg |= (divider << clk->pll_regs->divider_offset); + + /* + * AP807 CPU divider has two channels with ratio 1:3 and divider_ratio + * is 1. Otherwise, in the case of the AP806, divider_ratio is 0. + */ + if (clk->pll_regs->divider_ratio) { + reg &= ~(AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_MASK); + reg |= ((divider * clk->pll_regs->divider_ratio) << + AP807_PLL_CR_1_CPU_CLK_DIV_RATIO_OFFSET); + } + regmap_write(clk->pll_cr_base, cpu_clkdiv_reg, reg); + regmap_update_bits(clk->pll_cr_base, cpu_force_reg, clk->pll_regs->force_mask, @@ -287,6 +338,10 @@ static const struct of_device_id ap_cpu_clock_of_match[] = { .compatible = "marvell,ap806-cpu-clock", .data = &ap806_dfs_regs, }, + { + .compatible = "marvell,ap807-cpu-clock", + .data = &ap807_dfs_regs, + }, { } }; From cd016cb01835e0b9f62fb675b336fbded912dcb6 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Mon, 5 Aug 2019 12:03:07 +0200 Subject: [PATCH 59/62] clk: mvebu: ap806: be more explicit on what SaR is "SaR" means Sample at Reset. DIP switches can be changed on the board, their states at reset time is available through a register read. Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-6-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index 73ba8fd7860f..2cf874f01394 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -89,7 +89,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, cpuclk_freq = 600; break; default: - dev_err(dev, "invalid SAR value\n"); + dev_err(dev, "invalid Sample at Reset value\n"); return -EINVAL; } From 0099dc446bb6a72ce24d4f86760d0f4fe4300138 Mon Sep 17 00:00:00 2001 From: Omri Itach Date: Mon, 5 Aug 2019 12:03:08 +0200 Subject: [PATCH 60/62] clk: mvebu: ap806: add AP-DCLK (hclk) to system controller driver Add dynamic AP-DCLK clock (hclk) to system controller driver. AP-DCLK is half the rate of DDR clock, so its derrived from Sample At Reset configuration. The clock frequency is required for AP806 AXI monitor profiling feature. Signed-off-by: Omri Itach Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-7-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 48 ++++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index 2cf874f01394..bc43adff02e0 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -21,7 +21,7 @@ #define AP806_SAR_REG 0x400 #define AP806_SAR_CLKFREQ_MODE_MASK 0x1f -#define AP806_CLK_NUM 5 +#define AP806_CLK_NUM 6 static struct clk *ap806_clks[AP806_CLK_NUM]; @@ -33,7 +33,7 @@ static struct clk_onecell_data ap806_clk_data = { static int ap806_syscon_common_probe(struct platform_device *pdev, struct device_node *syscon_node) { - unsigned int freq_mode, cpuclk_freq; + unsigned int freq_mode, cpuclk_freq, dclk_freq; const char *name, *fixedclk_name; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; @@ -93,8 +93,42 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, return -EINVAL; } + /* Get DCLK frequency (DCLK = DDR_CLK / 2) */ + switch (freq_mode) { + case 0x0: + case 0x6: + /* DDR_CLK = 1200Mhz */ + dclk_freq = 600; + break; + case 0x1: + case 0x7: + case 0xD: + /* DDR_CLK = 1050Mhz */ + dclk_freq = 525; + break; + case 0x13: + case 0x17: + /* DDR_CLK = 650Mhz */ + dclk_freq = 325; + break; + case 0x4: + case 0x14: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + /* DDR_CLK = 800Mhz */ + dclk_freq = 400; + break; + default: + dclk_freq = 0; + dev_err(dev, "invalid Sample at Reset value\n"); + } + /* Convert to hertz */ cpuclk_freq *= 1000 * 1000; + dclk_freq *= 1000 * 1000; /* CPU clocks depend on the Sample At Reset configuration */ name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0"); @@ -141,6 +175,14 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, goto fail4; } + /* AP-DCLK(HCLK) Clock is DDR clock divided by 2 */ + name = ap_cp_unique_name(dev, syscon_node, "ap-dclk"); + ap806_clks[5] = clk_register_fixed_rate(dev, name, NULL, 0, dclk_freq); + if (IS_ERR(ap806_clks[5])) { + ret = PTR_ERR(ap806_clks[5]); + goto fail5; + } + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); if (ret) goto fail_clk_add; @@ -148,6 +190,8 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, return 0; fail_clk_add: + clk_unregister_fixed_factor(ap806_clks[5]); +fail5: clk_unregister_fixed_factor(ap806_clks[4]); fail4: clk_unregister_fixed_factor(ap806_clks[3]); From be69e55df9afc2eb37a2a602ad607e28e1e553d7 Mon Sep 17 00:00:00 2001 From: Ben Peled Date: Mon, 5 Aug 2019 12:03:09 +0200 Subject: [PATCH 61/62] clk: mvebu: ap806: Prepare the introduction of AP807 clock support Factor out the code that is only useful to AP806 so it will be easier to support AP807. No functional changes. Signed-off-by: Ben Peled Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-8-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 146 +++++++++++--------- 1 file changed, 80 insertions(+), 66 deletions(-) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index bc43adff02e0..c64e2cc4a3ba 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -30,6 +30,78 @@ static struct clk_onecell_data ap806_clk_data = { .clk_num = AP806_CLK_NUM, }; +static int ap806_get_sar_clocks(unsigned int freq_mode, + unsigned int *cpuclk_freq, + unsigned int *dclk_freq) +{ + switch (freq_mode) { + case 0x0: + *cpuclk_freq = 2000; + *dclk_freq = 600; + break; + case 0x1: + *cpuclk_freq = 2000; + *dclk_freq = 525; + break; + case 0x6: + *cpuclk_freq = 1800; + *dclk_freq = 600; + break; + case 0x7: + *cpuclk_freq = 1800; + *dclk_freq = 525; + break; + case 0x4: + *cpuclk_freq = 1600; + *dclk_freq = 400; + break; + case 0xB: + *cpuclk_freq = 1600; + *dclk_freq = 450; + break; + case 0xD: + *cpuclk_freq = 1600; + *dclk_freq = 525; + break; + case 0x1a: + *cpuclk_freq = 1400; + *dclk_freq = 400; + break; + case 0x14: + *cpuclk_freq = 1300; + *dclk_freq = 400; + break; + case 0x17: + *cpuclk_freq = 1300; + *dclk_freq = 325; + break; + case 0x19: + *cpuclk_freq = 1200; + *dclk_freq = 400; + break; + case 0x13: + *cpuclk_freq = 1000; + *dclk_freq = 325; + break; + case 0x1d: + *cpuclk_freq = 1000; + *dclk_freq = 400; + break; + case 0x1c: + *cpuclk_freq = 800; + *dclk_freq = 400; + break; + case 0x1b: + *cpuclk_freq = 600; + *dclk_freq = 400; + break; + default: + return -EINVAL; + } + + return 0; +} + static int ap806_syscon_common_probe(struct platform_device *pdev, struct device_node *syscon_node) { @@ -54,76 +126,18 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, } freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK; - switch (freq_mode) { - case 0x0: - case 0x1: - cpuclk_freq = 2000; - break; - case 0x6: - case 0x7: - cpuclk_freq = 1800; - break; - case 0x4: - case 0xB: - case 0xD: - cpuclk_freq = 1600; - break; - case 0x1a: - cpuclk_freq = 1400; - break; - case 0x14: - case 0x17: - cpuclk_freq = 1300; - break; - case 0x19: - cpuclk_freq = 1200; - break; - case 0x13: - case 0x1d: - cpuclk_freq = 1000; - break; - case 0x1c: - cpuclk_freq = 800; - break; - case 0x1b: - cpuclk_freq = 600; - break; - default: - dev_err(dev, "invalid Sample at Reset value\n"); + + if (of_device_is_compatible(pdev->dev.of_node, + "marvell,ap806-clock")) { + ret = ap806_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq); + } else { + dev_err(dev, "compatible not supported\n"); return -EINVAL; } - /* Get DCLK frequency (DCLK = DDR_CLK / 2) */ - switch (freq_mode) { - case 0x0: - case 0x6: - /* DDR_CLK = 1200Mhz */ - dclk_freq = 600; - break; - case 0x1: - case 0x7: - case 0xD: - /* DDR_CLK = 1050Mhz */ - dclk_freq = 525; - break; - case 0x13: - case 0x17: - /* DDR_CLK = 650Mhz */ - dclk_freq = 325; - break; - case 0x4: - case 0x14: - case 0x19: - case 0x1A: - case 0x1B: - case 0x1C: - case 0x1D: - /* DDR_CLK = 800Mhz */ - dclk_freq = 400; - break; - default: - dclk_freq = 0; + if (ret) { dev_err(dev, "invalid Sample at Reset value\n"); + return ret; } /* Convert to hertz */ From c0448dce56a49812c889e5f670745c9f49176b00 Mon Sep 17 00:00:00 2001 From: Ben Peled Date: Mon, 5 Aug 2019 12:03:10 +0200 Subject: [PATCH 62/62] clk: mvebu: ap80x: add AP807 clock support Add driver support for AP807 clock. Signed-off-by: Ben Peled Signed-off-by: Miquel Raynal Link: https://lkml.kernel.org/r/20190805100310.29048-9-miquel.raynal@bootlin.com Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index c64e2cc4a3ba..948bd1e71aea 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -102,6 +102,30 @@ static int ap806_get_sar_clocks(unsigned int freq_mode, return 0; } +static int ap807_get_sar_clocks(unsigned int freq_mode, + unsigned int *cpuclk_freq, + unsigned int *dclk_freq) +{ + switch (freq_mode) { + case 0x0: + *cpuclk_freq = 2000; + *dclk_freq = 1200; + break; + case 0x6: + *cpuclk_freq = 2200; + *dclk_freq = 1200; + break; + case 0xD: + *cpuclk_freq = 1600; + *dclk_freq = 1200; + break; + default: + return -EINVAL; + } + + return 0; +} + static int ap806_syscon_common_probe(struct platform_device *pdev, struct device_node *syscon_node) { @@ -130,6 +154,9 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, if (of_device_is_compatible(pdev->dev.of_node, "marvell,ap806-clock")) { ret = ap806_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq); + } else if (of_device_is_compatible(pdev->dev.of_node, + "marvell,ap807-clock")) { + ret = ap807_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq); } else { dev_err(dev, "compatible not supported\n"); return -EINVAL; @@ -252,6 +279,7 @@ builtin_platform_driver(ap806_syscon_legacy_driver); static const struct of_device_id ap806_clock_of_match[] = { { .compatible = "marvell,ap806-clock", }, + { .compatible = "marvell,ap807-clock", }, { } };