forked from luck/tmp_suning_uos_patched
First round of amlogic clock updates for v5.10
* g12: update audio clock inverter and fdiv2 flag * config: allow to disable unnecessary amlogic clock controllers -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE9OFZrhjz9W1fG7cb5vwPHDfy2oUFAl9fpfEACgkQ5vwPHDfy 2oWZwRAAoi8q5jDtB4fcqubsy9CBu47VIcaunS/LdHE2D8f9HSqcnyvJbDtG6GqU soWodIxjy1jE9KKC09/SEko5j21pvoRxHna6AVevg0dceP1zlq+5b4FVt9j6U8Pp bXRd+RROE6mHSaX8GKD2WUTMHqSDisr8HY+Bq+1EfqjyvA1+Onz7St6529fSqXO+ VQ5cwC9WXYmP0SJjP/20QHhdfuPFdn0yIyDBvjSiI0m+Z5DXWUdebSclShRJneps T6dKoVFvSILzh5RNbsbF5vdlPsg0yf+V9VWMJBoyPQVC30gO8LMe1whM+GoHkEdr 0IebivuQEGjTiSw5wmsT0CdISgLnQH/vV/F6fH68YxFXhVvzAdnaXEKxE+w1DXwi CyBuNsih2d9Wu+YtW8B/1JkpmapfJgdw1fYRqoJTbOuWZWeOqiszREOcmmRmnU2S XgSM8VW+1RfbqiJC6LeiHkTGxEJoDhMAHIlS1AsuzBQRv0bumUtsCD8WT4/tjREg ZNtq9FiwMVSpSQzKfhsZElqd5AMghIyLik1JiUw1i6DZrMz2c9Y/Bm1QBVcSrhTV 7YSbfH0fy8f4pau/Bd9RIddYVRuuwJ9fli6kX7oXzBgXvdnN08FdN1Z8jU58vmB/ 3AERTLTbTkf57KanOTPKyxXUXTr7OmagdZyq8vPkaDz5WlRC9+g= =JLsW -----END PGP SIGNATURE----- Merge tag 'clk-meson-v5.10-1' of https://github.com/BayLibre/clk-meson into clk-amlogic Pull amlogic clk driver updates from Jerome Brunet: - g12: update audio clock inverter and fdiv2 flag - config: allow to disable unnecessary amlogic clock controllers * tag 'clk-meson-v5.10-1' of https://github.com/BayLibre/clk-meson: clk: meson: make shipped controller configurable clk: meson: g12a: mark fclk_div2 as critical clk: meson: axg-audio: fix g12a tdmout sclk inverter clk: meson: axg-audio: separate axg and g12a regmap tables clk: meson: add sclk-ws driver
This commit is contained in:
commit
871ca96f1c
|
@ -1,4 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menu "Clock support for Amlogic platforms"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
|
||||
config COMMON_CLK_MESON_REGMAP
|
||||
tristate
|
||||
select REGMAP
|
||||
|
@ -41,8 +44,9 @@ config COMMON_CLK_MESON_CPU_DYNDIV
|
|||
select COMMON_CLK_MESON_REGMAP
|
||||
|
||||
config COMMON_CLK_MESON8B
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "Meson8 SoC Clock controller support"
|
||||
depends on ARM
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
select COMMON_CLK_MESON_PLL
|
||||
|
@ -54,8 +58,9 @@ config COMMON_CLK_MESON8B
|
|||
want peripherals and CPU frequency scaling to work.
|
||||
|
||||
config COMMON_CLK_GXBB
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "GXBB and GXL SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_VID_PLL_DIV
|
||||
|
@ -69,8 +74,9 @@ config COMMON_CLK_GXBB
|
|||
Say Y if you want peripherals and CPU frequency scaling to work.
|
||||
|
||||
config COMMON_CLK_AXG
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "AXG SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
|
@ -84,7 +90,7 @@ config COMMON_CLK_AXG
|
|||
|
||||
config COMMON_CLK_AXG_AUDIO
|
||||
tristate "Meson AXG Audio Clock Controller Driver"
|
||||
depends on ARCH_MESON
|
||||
depends on ARM64
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_PHASE
|
||||
select COMMON_CLK_MESON_SCLK_DIV
|
||||
|
@ -94,8 +100,9 @@ config COMMON_CLK_AXG_AUDIO
|
|||
aka axg, Say Y if you want audio subsystem to work.
|
||||
|
||||
config COMMON_CLK_G12A
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "G12 and SM1 SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
|
@ -107,3 +114,4 @@ config COMMON_CLK_G12A
|
|||
help
|
||||
Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
|
||||
devices, aka g12a. Say Y if you want peripherals to work.
|
||||
endmenu
|
||||
|
|
|
@ -147,6 +147,29 @@
|
|||
}, \
|
||||
}
|
||||
|
||||
#define AUD_SCLK_WS(_name, _reg, _width, _shift_ph, _shift_ws, _pname, \
|
||||
_iflags) { \
|
||||
.data = &(struct meson_sclk_ws_inv_data) { \
|
||||
.ph = { \
|
||||
.reg_off = (_reg), \
|
||||
.shift = (_shift_ph), \
|
||||
.width = (_width), \
|
||||
}, \
|
||||
.ws = { \
|
||||
.reg_off = (_reg), \
|
||||
.shift = (_shift_ws), \
|
||||
.width = (_width), \
|
||||
}, \
|
||||
}, \
|
||||
.hw.init = &(struct clk_init_data) { \
|
||||
.name = "aud_"#_name, \
|
||||
.ops = &meson_clk_phase_ops, \
|
||||
.parent_names = (const char *[]){ #_pname }, \
|
||||
.num_parents = 1, \
|
||||
.flags = (_iflags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* Audio Master Clocks */
|
||||
static const struct clk_parent_data mst_mux_parent_data[] = {
|
||||
{ .fw_name = "mst_in0", },
|
||||
|
@ -254,6 +277,10 @@ static const struct clk_parent_data tdm_lrclk_parent_data[] = {
|
|||
AUD_PHASE(tdm##_name##_sclk, _reg, 1, 29, \
|
||||
aud_tdm##_name##_sclk_post_en, \
|
||||
CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
|
||||
#define AUD_TDM_SCLK_WS(_name, _reg) \
|
||||
AUD_SCLK_WS(tdm##_name##_sclk, _reg, 1, 29, 28, \
|
||||
aud_tdm##_name##_sclk_post_en, \
|
||||
CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
|
||||
|
||||
#define AUD_TDM_LRLCK(_name, _reg) \
|
||||
AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \
|
||||
|
@ -499,12 +526,6 @@ static struct clk_regmap tdmin_c_sclk =
|
|||
AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL);
|
||||
static struct clk_regmap tdmin_lb_sclk =
|
||||
AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
|
||||
static struct clk_regmap tdmout_a_sclk =
|
||||
AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
|
||||
static struct clk_regmap tdmout_b_sclk =
|
||||
AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
|
||||
static struct clk_regmap tdmout_c_sclk =
|
||||
AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
static struct clk_regmap tdmin_a_lrclk =
|
||||
AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL);
|
||||
|
@ -521,6 +542,14 @@ static struct clk_regmap tdmout_b_lrclk =
|
|||
static struct clk_regmap tdmout_c_lrclk =
|
||||
AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
/* AXG Clocks */
|
||||
static struct clk_regmap axg_tdmout_a_sclk =
|
||||
AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
|
||||
static struct clk_regmap axg_tdmout_b_sclk =
|
||||
AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
|
||||
static struct clk_regmap axg_tdmout_c_sclk =
|
||||
AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
/* AXG/G12A Clocks */
|
||||
static struct clk_hw axg_aud_top = {
|
||||
.init = &(struct clk_init_data) {
|
||||
|
@ -591,7 +620,13 @@ static struct clk_regmap g12a_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL(
|
|||
static struct clk_regmap g12a_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL(
|
||||
sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data);
|
||||
|
||||
/* G12a/SM1 clocks */
|
||||
static struct clk_regmap g12a_tdmout_a_sclk =
|
||||
AUD_TDM_SCLK_WS(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
|
||||
static struct clk_regmap g12a_tdmout_b_sclk =
|
||||
AUD_TDM_SCLK_WS(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
|
||||
static struct clk_regmap g12a_tdmout_c_sclk =
|
||||
AUD_TDM_SCLK_WS(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
static struct clk_regmap toram =
|
||||
AUD_PCLK_GATE(toram, AUDIO_CLK_GATE_EN, 20);
|
||||
static struct clk_regmap spdifout_b =
|
||||
|
@ -889,9 +924,9 @@ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = {
|
|||
[AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &axg_tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &axg_tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &axg_tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw,
|
||||
|
@ -1026,9 +1061,9 @@ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = {
|
|||
[AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &g12a_tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &g12a_tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &g12a_tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw,
|
||||
|
@ -1170,9 +1205,9 @@ static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = {
|
|||
[AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &g12a_tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &g12a_tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &g12a_tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw,
|
||||
|
@ -1209,13 +1244,132 @@ static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = {
|
|||
};
|
||||
|
||||
|
||||
/* Convenience table to populate regmap in .probe()
|
||||
* Note that this table is shared between both AXG and G12A,
|
||||
* with spdifout_b clocks being exclusive to G12A. Since those
|
||||
* clocks are not declared within the AXG onecell table, we do not
|
||||
* feel the need to have separate AXG/G12A regmap tables.
|
||||
*/
|
||||
/* Convenience table to populate regmap in .probe(). */
|
||||
static struct clk_regmap *const axg_clk_regmaps[] = {
|
||||
&ddr_arb,
|
||||
&pdm,
|
||||
&tdmin_a,
|
||||
&tdmin_b,
|
||||
&tdmin_c,
|
||||
&tdmin_lb,
|
||||
&tdmout_a,
|
||||
&tdmout_b,
|
||||
&tdmout_c,
|
||||
&frddr_a,
|
||||
&frddr_b,
|
||||
&frddr_c,
|
||||
&toddr_a,
|
||||
&toddr_b,
|
||||
&toddr_c,
|
||||
&loopback,
|
||||
&spdifin,
|
||||
&spdifout,
|
||||
&resample,
|
||||
&power_detect,
|
||||
&mst_a_mclk_sel,
|
||||
&mst_b_mclk_sel,
|
||||
&mst_c_mclk_sel,
|
||||
&mst_d_mclk_sel,
|
||||
&mst_e_mclk_sel,
|
||||
&mst_f_mclk_sel,
|
||||
&mst_a_mclk_div,
|
||||
&mst_b_mclk_div,
|
||||
&mst_c_mclk_div,
|
||||
&mst_d_mclk_div,
|
||||
&mst_e_mclk_div,
|
||||
&mst_f_mclk_div,
|
||||
&mst_a_mclk,
|
||||
&mst_b_mclk,
|
||||
&mst_c_mclk,
|
||||
&mst_d_mclk,
|
||||
&mst_e_mclk,
|
||||
&mst_f_mclk,
|
||||
&spdifout_clk_sel,
|
||||
&spdifout_clk_div,
|
||||
&spdifout_clk,
|
||||
&spdifin_clk_sel,
|
||||
&spdifin_clk_div,
|
||||
&spdifin_clk,
|
||||
&pdm_dclk_sel,
|
||||
&pdm_dclk_div,
|
||||
&pdm_dclk,
|
||||
&pdm_sysclk_sel,
|
||||
&pdm_sysclk_div,
|
||||
&pdm_sysclk,
|
||||
&mst_a_sclk_pre_en,
|
||||
&mst_b_sclk_pre_en,
|
||||
&mst_c_sclk_pre_en,
|
||||
&mst_d_sclk_pre_en,
|
||||
&mst_e_sclk_pre_en,
|
||||
&mst_f_sclk_pre_en,
|
||||
&mst_a_sclk_div,
|
||||
&mst_b_sclk_div,
|
||||
&mst_c_sclk_div,
|
||||
&mst_d_sclk_div,
|
||||
&mst_e_sclk_div,
|
||||
&mst_f_sclk_div,
|
||||
&mst_a_sclk_post_en,
|
||||
&mst_b_sclk_post_en,
|
||||
&mst_c_sclk_post_en,
|
||||
&mst_d_sclk_post_en,
|
||||
&mst_e_sclk_post_en,
|
||||
&mst_f_sclk_post_en,
|
||||
&mst_a_sclk,
|
||||
&mst_b_sclk,
|
||||
&mst_c_sclk,
|
||||
&mst_d_sclk,
|
||||
&mst_e_sclk,
|
||||
&mst_f_sclk,
|
||||
&mst_a_lrclk_div,
|
||||
&mst_b_lrclk_div,
|
||||
&mst_c_lrclk_div,
|
||||
&mst_d_lrclk_div,
|
||||
&mst_e_lrclk_div,
|
||||
&mst_f_lrclk_div,
|
||||
&mst_a_lrclk,
|
||||
&mst_b_lrclk,
|
||||
&mst_c_lrclk,
|
||||
&mst_d_lrclk,
|
||||
&mst_e_lrclk,
|
||||
&mst_f_lrclk,
|
||||
&tdmin_a_sclk_sel,
|
||||
&tdmin_b_sclk_sel,
|
||||
&tdmin_c_sclk_sel,
|
||||
&tdmin_lb_sclk_sel,
|
||||
&tdmout_a_sclk_sel,
|
||||
&tdmout_b_sclk_sel,
|
||||
&tdmout_c_sclk_sel,
|
||||
&tdmin_a_sclk_pre_en,
|
||||
&tdmin_b_sclk_pre_en,
|
||||
&tdmin_c_sclk_pre_en,
|
||||
&tdmin_lb_sclk_pre_en,
|
||||
&tdmout_a_sclk_pre_en,
|
||||
&tdmout_b_sclk_pre_en,
|
||||
&tdmout_c_sclk_pre_en,
|
||||
&tdmin_a_sclk_post_en,
|
||||
&tdmin_b_sclk_post_en,
|
||||
&tdmin_c_sclk_post_en,
|
||||
&tdmin_lb_sclk_post_en,
|
||||
&tdmout_a_sclk_post_en,
|
||||
&tdmout_b_sclk_post_en,
|
||||
&tdmout_c_sclk_post_en,
|
||||
&tdmin_a_sclk,
|
||||
&tdmin_b_sclk,
|
||||
&tdmin_c_sclk,
|
||||
&tdmin_lb_sclk,
|
||||
&axg_tdmout_a_sclk,
|
||||
&axg_tdmout_b_sclk,
|
||||
&axg_tdmout_c_sclk,
|
||||
&tdmin_a_lrclk,
|
||||
&tdmin_b_lrclk,
|
||||
&tdmin_c_lrclk,
|
||||
&tdmin_lb_lrclk,
|
||||
&tdmout_a_lrclk,
|
||||
&tdmout_b_lrclk,
|
||||
&tdmout_c_lrclk,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const g12a_clk_regmaps[] = {
|
||||
&ddr_arb,
|
||||
&pdm,
|
||||
&tdmin_a,
|
||||
|
@ -1328,9 +1482,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
|
|||
&tdmin_b_sclk,
|
||||
&tdmin_c_sclk,
|
||||
&tdmin_lb_sclk,
|
||||
&tdmout_a_sclk,
|
||||
&tdmout_b_sclk,
|
||||
&tdmout_c_sclk,
|
||||
&g12a_tdmout_a_sclk,
|
||||
&g12a_tdmout_b_sclk,
|
||||
&g12a_tdmout_c_sclk,
|
||||
&tdmin_a_lrclk,
|
||||
&tdmin_b_lrclk,
|
||||
&tdmin_c_lrclk,
|
||||
|
@ -1465,9 +1619,9 @@ static struct clk_regmap *const sm1_clk_regmaps[] = {
|
|||
&tdmin_b_sclk,
|
||||
&tdmin_c_sclk,
|
||||
&tdmin_lb_sclk,
|
||||
&tdmout_a_sclk,
|
||||
&tdmout_b_sclk,
|
||||
&tdmout_c_sclk,
|
||||
&g12a_tdmout_a_sclk,
|
||||
&g12a_tdmout_b_sclk,
|
||||
&g12a_tdmout_c_sclk,
|
||||
&tdmin_a_lrclk,
|
||||
&tdmin_b_lrclk,
|
||||
&tdmin_c_lrclk,
|
||||
|
@ -1713,8 +1867,8 @@ static const struct audioclk_data axg_audioclk_data = {
|
|||
};
|
||||
|
||||
static const struct audioclk_data g12a_audioclk_data = {
|
||||
.regmap_clks = axg_clk_regmaps,
|
||||
.regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
|
||||
.regmap_clks = g12a_clk_regmaps,
|
||||
.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
|
||||
.hw_onecell_data = &g12a_audio_hw_onecell_data,
|
||||
.reset_offset = AUDIO_SW_RESET,
|
||||
.reset_num = 26,
|
||||
|
|
|
@ -125,6 +125,62 @@ const struct clk_ops meson_clk_triphase_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
|
||||
|
||||
/*
|
||||
* This is a special clock for the audio controller.
|
||||
* This drive a bit clock inverter for which the
|
||||
* opposite value of the inverter bit needs to be manually
|
||||
* set into another bit
|
||||
*/
|
||||
static inline struct meson_sclk_ws_inv_data *
|
||||
meson_sclk_ws_inv_data(struct clk_regmap *clk)
|
||||
{
|
||||
return (struct meson_sclk_ws_inv_data *)clk->data;
|
||||
}
|
||||
|
||||
static int meson_sclk_ws_inv_sync(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
|
||||
unsigned int val;
|
||||
|
||||
/* Get phase and sync the inverted value to ws */
|
||||
val = meson_parm_read(clk->map, &tph->ph);
|
||||
meson_parm_write(clk->map, &tph->ws, val ? 0 : 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_sclk_ws_inv_get_phase(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
|
||||
unsigned int val;
|
||||
|
||||
val = meson_parm_read(clk->map, &tph->ph);
|
||||
|
||||
return meson_clk_degrees_from_val(val, tph->ph.width);
|
||||
}
|
||||
|
||||
static int meson_sclk_ws_inv_set_phase(struct clk_hw *hw, int degrees)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
|
||||
unsigned int val;
|
||||
|
||||
val = meson_clk_degrees_to_val(degrees, tph->ph.width);
|
||||
meson_parm_write(clk->map, &tph->ph, val);
|
||||
meson_parm_write(clk->map, &tph->ws, val ? 0 : 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_sclk_ws_inv_ops = {
|
||||
.init = meson_sclk_ws_inv_sync,
|
||||
.get_phase = meson_sclk_ws_inv_get_phase,
|
||||
.set_phase = meson_sclk_ws_inv_set_phase,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_sclk_ws_inv_ops);
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic phase driver");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -20,7 +20,13 @@ struct meson_clk_triphase_data {
|
|||
struct parm ph2;
|
||||
};
|
||||
|
||||
struct meson_sclk_ws_inv_data {
|
||||
struct parm ph;
|
||||
struct parm ws;
|
||||
};
|
||||
|
||||
extern const struct clk_ops meson_clk_phase_ops;
|
||||
extern const struct clk_ops meson_clk_triphase_ops;
|
||||
extern const struct clk_ops meson_sclk_ws_inv_ops;
|
||||
|
||||
#endif /* __MESON_CLK_PHASE_H */
|
||||
|
|
|
@ -298,6 +298,17 @@ static struct clk_regmap g12a_fclk_div2 = {
|
|||
&g12a_fclk_div2_div.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
/*
|
||||
* Similar to fclk_div3, it seems that 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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user