diff options
author | Dmitry Rokosov <ddrokosov@sberdevices.ru> | 2023-05-23 16:53:47 +0300 |
---|---|---|
committer | Jerome Brunet <jbrunet@baylibre.com> | 2023-05-30 18:53:00 +0300 |
commit | b6ec400aa153b27e056b2dfc5e830b724c053a04 (patch) | |
tree | 33095e84e86e32156a561afad021bf673355e93a /drivers/clk/meson | |
parent | 02f1e17c4106a24fabb27e1419cbcb144b4faa1b (diff) | |
download | linux-b6ec400aa153b27e056b2dfc5e830b724c053a04.tar.xz |
clk: meson: introduce new pll power-on sequence for A1 SoC family
Modern meson PLL IPs are a little bit different from early known PLLs.
The main difference is located in the init/enable/disable sequences; the
rate logic is the same.
In A1 PLL, the PLL enable sequence is different, so add new optional pll
reg bits and use the new power-on sequence to enable the PLL:
1. enable the pll, delay for 10us
2. enable the pll self-adaption current module, delay for 40us
3. enable the lock detect module
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru>
Link: https://lore.kernel.org/r/20230523135351.19133-3-ddrokosov@sberdevices.ru
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Diffstat (limited to 'drivers/clk/meson')
-rw-r--r-- | drivers/clk/meson/clk-pll.c | 23 | ||||
-rw-r--r-- | drivers/clk/meson/clk-pll.h | 2 |
2 files changed, 25 insertions, 0 deletions
diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 314ca945a4d0..56ec2210f1ad 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -358,6 +358,25 @@ static int meson_clk_pll_enable(struct clk_hw *hw) if (MESON_PARM_APPLICABLE(&pll->rst)) meson_parm_write(clk->map, &pll->rst, 0); + /* + * Compared with the previous SoCs, self-adaption current module + * is newly added for A1, keep the new power-on sequence to enable the + * PLL. The sequence is: + * 1. enable the pll, delay for 10us + * 2. enable the pll self-adaption current module, delay for 40us + * 3. enable the lock detect module + */ + if (MESON_PARM_APPLICABLE(&pll->current_en)) { + usleep_range(10, 20); + meson_parm_write(clk->map, &pll->current_en, 1); + usleep_range(40, 50); + }; + + if (MESON_PARM_APPLICABLE(&pll->l_detect)) { + meson_parm_write(clk->map, &pll->l_detect, 1); + meson_parm_write(clk->map, &pll->l_detect, 0); + } + if (meson_clk_pll_wait_lock(hw)) return -EIO; @@ -375,6 +394,10 @@ static void meson_clk_pll_disable(struct clk_hw *hw) /* Disable the pll */ meson_parm_write(clk->map, &pll->en, 0); + + /* Disable PLL internal self-adaption current module */ + if (MESON_PARM_APPLICABLE(&pll->current_en)) + meson_parm_write(clk->map, &pll->current_en, 0); } static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h index 367efd0f6410..a2228c0fdce5 100644 --- a/drivers/clk/meson/clk-pll.h +++ b/drivers/clk/meson/clk-pll.h @@ -36,6 +36,8 @@ struct meson_clk_pll_data { struct parm frac; struct parm l; struct parm rst; + struct parm current_en; + struct parm l_detect; const struct reg_sequence *init_regs; unsigned int init_count; const struct pll_params_table *table; |