]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - arch/arm/mach-uniphier/clk/pll-base-ld20.c
ARM: uniphier: use FIELD_PREP for PLL settings
[people/ms/u-boot.git] / arch / arm / mach-uniphier / clk / pll-base-ld20.c
index caa631d9f766ebb243d249078c3ec642b916dbde..385f54dfc3b9941fcacabd62fc283f9c011d4e95 100644 (file)
@@ -5,8 +5,11 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#include <common.h>
+#include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
 
@@ -17,6 +20,7 @@
 #define SC_PLLCTRL_SSC_EN              BIT(31)
 #define SC_PLLCTRL2_NRSTDS             BIT(28)
 #define SC_PLLCTRL2_SSC_JK_MASK                GENMASK(26, 0)
+#define SC_PLLCTRL3_REGI_MASK          GENMASK(19, 16)
 
 /* PLL type: VPLL27 */
 #define SC_VPLL27CTRL_WP               BIT(0)
@@ -38,13 +42,17 @@ int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq,
        if (freq != UNIPHIER_PLL_FREQ_DEFAULT) {
                tmp = readl(base);      /* SSCPLLCTRL */
                tmp &= ~SC_PLLCTRL_SSC_DK_MASK;
-               tmp |= (487 * freq * ssc_rate / divn / 512) &
-                                                       SC_PLLCTRL_SSC_DK_MASK;
+               tmp |= FIELD_PREP(SC_PLLCTRL_SSC_DK_MASK,
+                                 DIV_ROUND_CLOSEST(487UL * freq * ssc_rate,
+                                                   divn * 512));
                writel(tmp, base);
 
                tmp = readl(base + 4);
                tmp &= ~SC_PLLCTRL2_SSC_JK_MASK;
-               tmp |= (41859 * freq / divn) & SC_PLLCTRL2_SSC_JK_MASK;
+               tmp |= FIELD_PREP(SC_PLLCTRL2_SSC_JK_MASK,
+                                 DIV_ROUND_CLOSEST(21431887UL * freq,
+                                                   divn * 512));
+               writel(tmp, base + 4);
 
                udelay(50);
        }
@@ -76,6 +84,25 @@ int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base)
        return 0;
 }
 
+int uniphier_ld20_sscpll_set_regi(unsigned long reg_base, unsigned regi)
+{
+       void __iomem *base;
+       u32 tmp;
+
+       base = ioremap(reg_base, SZ_16);
+       if (!base)
+               return -ENOMEM;
+
+       tmp = readl(base + 8);  /* SSCPLLCTRL3 */
+       tmp &= ~SC_PLLCTRL3_REGI_MASK;
+       tmp |= FIELD_PREP(SC_PLLCTRL3_REGI_MASK, regi);
+       writel(tmp, base + 8);
+
+       iounmap(base);
+
+       return 0;
+}
+
 int uniphier_ld20_vpll27_init(unsigned long reg_base)
 {
        void __iomem *base;
@@ -111,9 +138,9 @@ int uniphier_ld20_dspll_init(unsigned long reg_base)
        if (!base)
                return -ENOMEM;
 
-       tmp = readl(base + 8);          /* DSPLLCTRL2 */
+       tmp = readl(base + 4);          /* DSPLLCTRL2 */
        tmp |= SC_DSPLLCTRL2_K_LD;
-       writel(tmp, base + 8);
+       writel(tmp, base + 4);
 
        iounmap(base);