Author: jmcneill
Date: Thu Sep  1 21:20:07 2016
New Revision: 305247
URL: https://svnweb.freebsd.org/changeset/base/305247

Log:
  Add support for changing A23 PLL1 frequency.

Modified:
  head/sys/arm/allwinner/clk/aw_pll.c

Modified: head/sys/arm/allwinner/clk/aw_pll.c
==============================================================================
--- head/sys/arm/allwinner/clk/aw_pll.c Thu Sep  1 21:19:11 2016        
(r305246)
+++ head/sys/arm/allwinner/clk/aw_pll.c Thu Sep  1 21:20:07 2016        
(r305247)
@@ -110,14 +110,14 @@ __FBSDID("$FreeBSD$");
 #define        A13_PLL2_PRE_DIV                (0x1f << 0)
 #define        A13_PLL2_PRE_DIV_SHIFT          0
 
+#define        A23_PLL1_FACTOR_P               (0x3 << 16)
+#define        A23_PLL1_FACTOR_P_SHIFT         16
 #define        A23_PLL1_FACTOR_N               (0x1f << 8)
 #define        A23_PLL1_FACTOR_N_SHIFT         8
 #define        A23_PLL1_FACTOR_K               (0x3 << 4)
 #define        A23_PLL1_FACTOR_K_SHIFT         4
 #define        A23_PLL1_FACTOR_M               (0x3 << 0)
 #define        A23_PLL1_FACTOR_M_SHIFT         0
-#define        A23_PLL1_FACTOR_P               (0x3 << 16)
-#define        A23_PLL1_FACTOR_P_SHIFT         16
 
 #define        A31_PLL1_LOCK                   (1 << 28)
 #define        A31_PLL1_CPU_SIGMA_DELTA_EN     (1 << 24)
@@ -171,6 +171,24 @@ __FBSDID("$FreeBSD$");
 #define        CLKID_A31_PLL6                  0
 #define        CLKID_A31_PLL6_X2               1
 
+struct aw_pll_factor {
+       unsigned int            n;
+       unsigned int            k;
+       unsigned int            m;
+       unsigned int            p;
+       uint64_t                freq;
+};
+#define        PLLFACTOR(_n, _k, _m, _p, _freq)        \
+       { .n = (_n), .k = (_k), .m = (_m), .p = (_p), .freq = (_freq) }
+
+static struct aw_pll_factor aw_a23_pll1_factors[] = {
+       PLLFACTOR(16, 0, 0, 0, 408000000),
+       PLLFACTOR(26, 0, 0, 0, 648000000),
+       PLLFACTOR(16, 1, 0, 0, 816000000),
+       PLLFACTOR(20, 1, 0, 0, 1008000000),
+       PLLFACTOR(24, 1, 0, 0, 1200000000),
+};
+
 enum aw_pll_type {
        AWPLL_A10_PLL1 = 1,
        AWPLL_A10_PLL2,
@@ -557,6 +575,39 @@ a13_pll2_set_freq(struct aw_pll_sc *sc, 
 }
 
 static int
+a23_pll1_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
+    int flags)
+{
+       struct aw_pll_factor *f;
+       uint32_t val;
+       int n;
+
+       f = NULL;
+       for (n = 0; n < nitems(aw_a23_pll1_factors); n++) {
+               if (aw_a23_pll1_factors[n].freq == *fout) {
+                       f = &aw_a23_pll1_factors[n];
+                       break;
+               }
+       }
+       if (f == NULL)
+               return (EINVAL);
+
+       DEVICE_LOCK(sc);
+       PLL_READ(sc, &val);
+       val &= ~(A23_PLL1_FACTOR_N|A23_PLL1_FACTOR_K|A23_PLL1_FACTOR_M|
+                A23_PLL1_FACTOR_P);
+       val |= (f->n << A23_PLL1_FACTOR_N_SHIFT);
+       val |= (f->k << A23_PLL1_FACTOR_K_SHIFT);
+       val |= (f->m << A23_PLL1_FACTOR_M_SHIFT);
+       val |= (f->p << A23_PLL1_FACTOR_P_SHIFT);
+       PLL_WRITE(sc, val);
+       DEVICE_UNLOCK(sc);
+
+       return (0);
+       
+}
+
+static int
 a23_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
 {
        uint32_t val, m, n, k, p;
@@ -719,7 +770,7 @@ static struct aw_pll_funcs aw_pll_func[]
        PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL),
        PLL(AWPLL_A10_PLL6, a10_pll6_recalc, a10_pll6_set_freq, a10_pll6_init),
        PLL(AWPLL_A13_PLL2, a13_pll2_recalc, a13_pll2_set_freq, NULL),
-       PLL(AWPLL_A23_PLL1, a23_pll1_recalc, NULL, NULL),
+       PLL(AWPLL_A23_PLL1, a23_pll1_recalc, a23_pll1_set_freq, NULL),
        PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
        PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
        PLL(AWPLL_A80_PLL4, a80_pll4_recalc, NULL, NULL),
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to