clk: meson: introduce new pll power-on sequence for A1 SoC family
authorDmitry Rokosov <ddrokosov@sberdevices.ru>
Tue, 23 May 2023 13:53:47 +0000 (16:53 +0300)
committerJerome Brunet <jbrunet@baylibre.com>
Tue, 30 May 2023 15:53:00 +0000 (17:53 +0200)
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>
drivers/clk/meson/clk-pll.c
drivers/clk/meson/clk-pll.h

index 314ca94..56ec221 100644 (file)
@@ -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,
index 367efd0..a2228c0 100644 (file)
@@ -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;