svn commit: r305247 - head/sys/arm/allwinner/clk

Jared McNeill jmcneill at FreeBSD.org
Thu Sep 1 21:20:09 UTC 2016


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),


More information about the svn-src-head mailing list