]> www.infradead.org Git - users/hch/misc.git/commitdiff
clk: at91: clk-sam9x60-pll: force write to PLL_UPDT register
authorNicolas Ferre <nicolas.ferre@microchip.com>
Wed, 27 Aug 2025 15:08:10 +0000 (17:08 +0200)
committerNicolas Ferre <nicolas.ferre@microchip.com>
Wed, 17 Sep 2025 17:15:32 +0000 (19:15 +0200)
This register is important for sequencing the commands to PLLs, so
actually write the update bits with regmap_write_bits() instead of
relying on a read/modify/write regmap command that could skip the actual
hardware write if the value is identical to the one read.

It's changed when modification is needed to the PLL, when
read-only operation is done, we could keep the call to
regmap_update_bits().

Add a comment to the sam9x60_div_pll_set_div() function that uses this
PLL_UPDT register so that it's used consistently, according to the
product's datasheet.

Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Tested-by: Ryan Wanner <ryan.wanner@microchip.com> # on sama7d65 and sam9x75
Link: https://lore.kernel.org/r/20250827150811.82496-1-nicolas.ferre@microchip.com
[claudiu.beznea: fix "Alignment should match open parenthesis"
 checkpatch.pl check]
Signed-off-by: Claudiu Beznea <claudiu.beznea@tuxon.dev>
drivers/clk/at91/clk-sam9x60-pll.c

index cefd9948e10393e4762f8a1f5f2ca0a7e1180a87..a035dc15454b00a812a29b95b995b8e5a0f2b5f4 100644 (file)
@@ -93,8 +93,8 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
 
        spin_lock_irqsave(core->lock, flags);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_ID_MSK, core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_ID_MSK, core->id);
        regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
        cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
        cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
@@ -128,17 +128,17 @@ static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
                udelay(10);
        }
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
                           AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
                           AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        while (!sam9x60_pll_ready(regmap, core->id))
                cpu_relax();
@@ -164,8 +164,8 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)
 
        spin_lock_irqsave(core->lock, flags);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_ID_MSK, core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_ID_MSK, core->id);
 
        regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENPLL, 0);
 
@@ -173,9 +173,9 @@ static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)
                regmap_update_bits(regmap, AT91_PMC_PLL_ACR,
                                   AT91_PMC_PLL_ACR_UTMIBG | AT91_PMC_PLL_ACR_UTMIVR, 0);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        spin_unlock_irqrestore(core->lock, flags);
 }
@@ -262,8 +262,8 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
 
        spin_lock_irqsave(core->lock, irqflags);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
-                          core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
+                         core->id);
        regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
        cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
        cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
@@ -275,18 +275,18 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
                     (frac->mul << core->layout->mul_shift) |
                     (frac->frac << core->layout->frac_shift));
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
                           AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
                           AT91_PMC_PLL_CTRL0_ENLOCK |
                           AT91_PMC_PLL_CTRL0_ENPLL);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        while (!sam9x60_pll_ready(regmap, core->id))
                cpu_relax();
@@ -338,7 +338,10 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = {
        .restore_context = sam9x60_frac_pll_restore_context,
 };
 
-/* This function should be called with spinlock acquired. */
+/* This function should be called with spinlock acquired.
+ * Warning: this function must be called only if the same PLL ID was set in
+ *          PLL_UPDT register previously.
+ */
 static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div,
                                    bool enable)
 {
@@ -350,9 +353,9 @@ static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div,
                           core->layout->div_mask | ena_msk,
                           (div << core->layout->div_shift) | ena_val);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        while (!sam9x60_pll_ready(regmap, core->id))
                cpu_relax();
@@ -366,8 +369,8 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core)
        unsigned int val, cdiv;
 
        spin_lock_irqsave(core->lock, flags);
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_ID_MSK, core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_ID_MSK, core->id);
        regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
        cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
 
@@ -398,15 +401,15 @@ static void sam9x60_div_pll_unprepare(struct clk_hw *hw)
 
        spin_lock_irqsave(core->lock, flags);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_ID_MSK, core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_ID_MSK, core->id);
 
        regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
                           core->layout->endiv_mask, 0);
 
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
-                          AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
-                          AT91_PMC_PLL_UPDT_UPDATE | core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT,
+                         AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
+                         AT91_PMC_PLL_UPDT_UPDATE | core->id);
 
        spin_unlock_irqrestore(core->lock, flags);
 }
@@ -518,8 +521,8 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
        div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;
 
        spin_lock_irqsave(core->lock, irqflags);
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
-                          core->id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
+                         core->id);
        regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
        cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
 
@@ -574,8 +577,8 @@ static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier,
        div->div = div->safe_div;
 
        spin_lock_irqsave(core.lock, irqflags);
-       regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
-                          core.id);
+       regmap_write_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
+                         core.id);
        regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
        cdiv = (val & core.layout->div_mask) >> core.layout->div_shift;