diff options
| author | Dmitry Rokosov <ddrokosov@salutedevices.com> | 2024-03-26 18:49:00 +0300 |
|---|---|---|
| committer | Dmitry Rokosov <rockosov@rulkc.org> | 2026-08-13 14:41:32 +0300 |
| commit | a7b5c66bd2bfa0c6d334894b2b0c0026f9b9a2eb (patch) | |
| tree | b597b34e70546e1c9dc72dce51877fd84879a4e8 | |
| parent | 5f204a2fdebaace178e5e792d01622fca40797f3 (diff) | |
| download | linux-a7b5c66bd2bfa0c6d334894b2b0c0026f9b9a2eb.tar.gz linux-a7b5c66bd2bfa0c6d334894b2b0c0026f9b9a2eb.zip | |
clk: meson: a1: pll: support 'syspll' general-purpose PLL for CPU clock
The 'syspll' PLL, also known as the system PLL, is a general and
essential PLL responsible for generating the CPU clock frequency.
With its wide-ranging capabilities, it is designed to accommodate
frequencies within the range of 768MHz to 1536MHz.
Signed-off-by: Dmitry Rokosov <rockosov@rulkc.org>
| -rw-r--r-- | drivers/clk/meson/a1-pll.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/drivers/clk/meson/a1-pll.c b/drivers/clk/meson/a1-pll.c index 1f82e9c7c14e..ea6bddad2c97 100644 --- a/drivers/clk/meson/a1-pll.c +++ b/drivers/clk/meson/a1-pll.c @@ -17,6 +17,12 @@ #define ANACTRL_FIXPLL_CTRL0 0x0 #define ANACTRL_FIXPLL_CTRL1 0x4 #define ANACTRL_FIXPLL_STS 0x14 +#define ANACTRL_SYSPLL_CTRL0 0x80 +#define ANACTRL_SYSPLL_CTRL1 0x84 +#define ANACTRL_SYSPLL_CTRL2 0x88 +#define ANACTRL_SYSPLL_CTRL3 0x8c +#define ANACTRL_SYSPLL_CTRL4 0x90 +#define ANACTRL_SYSPLL_STS 0x94 #define ANACTRL_HIFIPLL_CTRL0 0xc0 #define ANACTRL_HIFIPLL_CTRL1 0xc4 #define ANACTRL_HIFIPLL_CTRL2 0xc8 @@ -148,6 +154,76 @@ static struct clk_regmap a1_hifi_pll = { }, }; +static const struct pll_mult_range a1_sys_pll_mult_range = { + .min = 32, + .max = 64, +}; + +static const struct reg_sequence a1_sys_pll_init_regs[] = { + { .reg = ANACTRL_SYSPLL_CTRL1, .def = 0x01800000 }, + { .reg = ANACTRL_SYSPLL_CTRL2, .def = 0x00001100 }, + { .reg = ANACTRL_SYSPLL_CTRL3, .def = 0x10022300 }, + { .reg = ANACTRL_SYSPLL_CTRL4, .def = 0x00300000 }, + { .reg = ANACTRL_SYSPLL_CTRL0, .def = 0x01f18432 }, +}; + +static struct clk_regmap a1_sys_pll = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = ANACTRL_SYSPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = ANACTRL_SYSPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = ANACTRL_SYSPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = ANACTRL_SYSPLL_CTRL1, + .shift = 0, + .width = 19, + }, + .l = { + .reg_off = ANACTRL_SYSPLL_STS, + .shift = 31, + .width = 1, + }, + .current_en = { + .reg_off = ANACTRL_SYSPLL_CTRL0, + .shift = 26, + .width = 1, + }, + .l_detect = { + .reg_off = ANACTRL_SYSPLL_CTRL2, + .shift = 6, + .width = 1, + }, + .range = &a1_sys_pll_mult_range, + .init_regs = a1_sys_pll_init_regs, + .init_count = ARRAY_SIZE(a1_sys_pll_init_regs), + /* + * The sys_pll clock is usually enabled and initialized in the + * bootloader stage. Additionally, the cpu_clk is connected to + * sys_pll. As a result, it is not allowed to initialize the + * cpu_clk again, as doing so would prevent the CPU from + * executing any instructions. + */ + .flags = CLK_MESON_PLL_NOINIT_ENABLED, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &meson_clk_pll_ops, + .parent_names = (const char *[]){ "syspll_in" }, + .num_parents = 1, + }, +}; + static struct clk_fixed_factor a1_fclk_div2_div = { .mult = 1, .div = 2, @@ -293,6 +369,7 @@ static struct clk_hw *a1_pll_hw_clks[] = { [CLKID_FCLK_DIV5] = &a1_fclk_div5.hw, [CLKID_FCLK_DIV7] = &a1_fclk_div7.hw, [CLKID_HIFI_PLL] = &a1_hifi_pll.hw, + [CLKID_SYS_PLL] = &a1_sys_pll.hw, }; static const struct meson_clkc_data a1_pll_clkc_data = { |
