mirror of https://gitee.com/openkylin/linux.git
Amlogic clock changes for v5.4
* Migrate to new clock description method * Add DVFS support to g12 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE9OFZrhjz9W1fG7cb5vwPHDfy2oUFAl1RLUQACgkQ5vwPHDfy 2oUeNA/9GSr1WUdlsGiWdjRmqiKTMSo8Evq0/LlSanDBR9lkCrgaWPG2vjxS5r8c 3Is/klVnPnVtG7wugrPXCrlE0VLsrbclN20dziUyLnK8eNsBG3UBtZLiGGV26nRA MInv/AfI4dad4nMYcNlIszHLewVeoTz+KyAaSEK/mhJca8kv4E4m0CXr0ZW6AAKF qpVKIMScmF+rDn4UtjE4XbTa3dm8vJva6GqUvy2IgUukg8UQ4zwOd2/m9870GvRA lKBtm4yiegkgmd8ykRcEg3QMs4CatAKIujeLftg4DQB7h3O8aDwobAeAgtVcJlKM Upy+9CMEPJQ6UC/bc4+RBlUpmOBWKEYANEObAZf83Mi5zzFYqsuAdnuzkWqxcKhF ptt/UxfgpoVG7QljjDbrQsQfhniZ7oSFog+FT52AzbbN0ch391MRW9ek5UwrT99A o36JXWl6YZivbSaF9KDzGVBZr7KUdLypXd9EkPdt+Xx6lIAsqBAlSC3KnYhndllz r4doYZs8PvK6K8nZFYXslwMc06+rMUGb7B6TixstozKyF+IUp8i3peXFxpKf3u/C 1ewriDsaakKMZvQ1dEQdw3Ls2qWl0Zf/BQYEQn7u9NzBpdmUA9JFkw4AcgxFxY9k JVle4Zb1iT5P2Lsuu+DcqKxPNbKcl1EQTuxttfhQh6UkcrKBs5A= =2py5 -----END PGP SIGNATURE----- Merge tag 'clk-meson-v5.4-1' of git://github.com/BayLibre/clk-meson into v5.4/dt64 Amlogic clock changes for v5.4 * Migrate to new clock description method * Add DVFS support to g12 # gpg: Signature made Mon 12 Aug 2019 02:11:32 AM PDT # gpg: using RSA key F4E159AE18F3F56D5F1BB71BE6FC0F1C37F2DA85 # gpg: Good signature from "Jerome Brunet <jbrunet@baylibre.com>" [full] # gpg: aka "Jerome Brunet <jerome@liltaz.com>" [full] # gpg: aka "Jerome Brunet <jerome.brunet@gmail.com>" [full] * tag 'clk-meson-v5.4-1' of git://github.com/BayLibre/clk-meson: clk: meson: g12a: expose CPUB clock ID for G12B clk: meson: g12a: add notifiers to handle cpu clock change clk: meson: add g12a cpu dynamic divider driver clk: core: introduce clk_hw_set_parent() clk: meson: remove clk input helper clk: meson: remove ee input bypass clocks clk: meson: clk-regmap: migrate to new parent description method clk: meson: meson8b: migrate to the new parent description method clk: meson: axg: migrate to the new parent description method clk: meson: gxbb: migrate to the new parent description method clk: meson: g12a: migrate to the new parent description method clk: meson: remove ao input bypass clocks clk: meson: axg-aoclk: migrate to the new parent description method clk: meson: gxbb-aoclk: migrate to the new parent description method clk: meson: g12a-aoclk: migrate to the new parent description method clk: meson: axg-audio: migrate to the new parent description method clk: meson: g12a: fix hifi typo in mali parent_names
This commit is contained in:
commit
b69337d38e
|
@ -2487,6 +2487,12 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
@ -33,13 +30,15 @@ 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
|
||||
tristate
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_INPUT
|
||||
|
||||
config COMMON_CLK_MESON_CPU_DYNDIV
|
||||
tristate
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
|
||||
config COMMON_CLK_MESON8B
|
||||
bool
|
||||
|
@ -86,7 +85,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
|
||||
|
@ -104,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
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
# 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_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
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <linux/slab.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#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,12 +1088,17 @@ 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,
|
||||
},
|
||||
};
|
||||
|
||||
#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);
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2019 BayLibre, SAS.
|
||||
* Author: Neil Armstrong <narmstrong@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#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 <narmstrong@baylibre.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,20 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2019 BayLibre, SAS.
|
||||
* Author: Neil Armstrong <narmstrong@baylibre.com>
|
||||
*/
|
||||
|
||||
#ifndef __MESON_CLK_CPU_DYNDIV_H
|
||||
#define __MESON_CLK_CPU_DYNDIV_H
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#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 */
|
|
@ -1,49 +0,0 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2018 BayLibre, SAS.
|
||||
* Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#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 <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -1,19 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2019 BayLibre, SAS.
|
||||
* Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
*/
|
||||
|
||||
#ifndef __MESON_CLK_INPUT_H
|
||||
#define __MESON_CLK_INPUT_H
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,8 +17,6 @@
|
|||
#include <linux/slab.h>
|
||||
#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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include "clk-regmap.h"
|
||||
|
||||
#define IN_PREFIX "ee-in-"
|
||||
|
||||
struct platform_device;
|
||||
|
||||
struct meson_eeclkc_data {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue