svn commit: r314393 - head/sys/arm/allwinner/clkng

Emmanuel Vadot manu at FreeBSD.org
Tue Feb 28 15:11:35 UTC 2017


Author: manu
Date: Tue Feb 28 15:11:33 2017
New Revision: 314393
URL: https://svnweb.freebsd.org/changeset/base/314393

Log:
  allwinner: nkmp: Add MUX capability
  
  Some NKMP clocks have a mux options.
  Add the capability to aw_clk_nkmp.

Modified:
  head/sys/arm/allwinner/clkng/aw_clk.h
  head/sys/arm/allwinner/clkng/aw_clk_nkmp.c
  head/sys/arm/allwinner/clkng/aw_clk_nkmp.h

Modified: head/sys/arm/allwinner/clkng/aw_clk.h
==============================================================================
--- head/sys/arm/allwinner/clkng/aw_clk.h	Tue Feb 28 15:03:34 2017	(r314392)
+++ head/sys/arm/allwinner/clkng/aw_clk.h	Tue Feb 28 15:11:33 2017	(r314393)
@@ -219,6 +219,48 @@ aw_clk_factor_get_value(struct aw_clk_fa
 		.flags = _flags,			\
 	}
 
+#define NKMP_CLK_WITH_MUX(_clkname,			\
+  _id, _name, _pnames,					\
+  _offset,						\
+  _n_shift, _n_width, _n_value, _n_flags,		\
+  _k_shift, _k_width, _k_value, _k_flags,		\
+  _m_shift, _m_width, _m_value, _m_flags,		\
+  _p_shift, _p_width, _p_value, _p_flags,		\
+  _mux_shift, _mux_width, _gate,			\
+  _lock, _lock_retries,					\
+  _flags)						\
+	static struct aw_clk_nkmp_def _clkname = {	\
+		.clkdef = {				\
+			.id = _id,			\
+			.name = _name,			\
+			.parent_names = _pnames,	\
+			.parent_cnt = nitems(_pnames),	\
+		},					\
+		.offset = _offset,			\
+		.n.shift = _n_shift,			\
+		.n.width = _n_width,			\
+		.n.value = _n_value,			\
+		.n.flags = _n_flags,			\
+		.k.shift = _k_shift,			\
+		.k.width = _k_width,			\
+		.k.value = _k_value,			\
+		.k.flags = _k_flags,			\
+		.m.shift = _m_shift,			\
+		.m.width = _m_width,			\
+		.m.value = _m_value,			\
+		.m.flags = _m_flags,			\
+		.p.shift = _p_shift,			\
+		.p.width = _p_width,			\
+		.p.value = _p_value,			\
+		.p.flags = _p_flags,			\
+		.mux_shift = _mux_shift,		\
+		.mux_width = _mux_width,		\
+		.gate_shift = _gate,			\
+		.lock_shift = _lock,			\
+		.lock_retries = _lock_retries,		\
+		.flags = _flags,			\
+	}
+
 #define NKMP_CLK_WITH_UPDATE(_clkname,			\
   _id, _name, _pnames,					\
   _offset,						\

Modified: head/sys/arm/allwinner/clkng/aw_clk_nkmp.c
==============================================================================
--- head/sys/arm/allwinner/clkng/aw_clk_nkmp.c	Tue Feb 28 15:03:34 2017	(r314392)
+++ head/sys/arm/allwinner/clkng/aw_clk_nkmp.c	Tue Feb 28 15:11:33 2017	(r314393)
@@ -55,6 +55,8 @@ struct aw_clk_nkmp_sc {
 	struct aw_clk_factor	m;
 	struct aw_clk_factor	p;
 
+	uint32_t	mux_shift;
+	uint32_t	mux_mask;
 	uint32_t	gate_shift;
 	uint32_t	lock_shift;
 	uint32_t	lock_retries;
@@ -77,7 +79,21 @@ struct aw_clk_nkmp_sc {
 static int
 aw_clk_nkmp_init(struct clknode *clk, device_t dev)
 {
-	clknode_init_parent_idx(clk, 0);
+	struct aw_clk_nkmp_sc *sc;
+	uint32_t val, idx;
+
+	sc = clknode_get_softc(clk);
+
+	idx = 0;
+	if ((sc->flags & AW_CLK_HAS_MUX) != 0) {
+		DEVICE_LOCK(clk);
+		READ4(clk, sc->offset, &val);
+		DEVICE_UNLOCK(clk);
+
+		idx = (val & sc->mux_mask) >> sc->mux_shift;
+	}
+
+	clknode_init_parent_idx(clk, idx);
 	return (0);
 }
 
@@ -104,6 +120,27 @@ aw_clk_nkmp_set_gate(struct clknode *clk
 	return (0);
 }
 
+static int
+aw_clk_nkmp_set_mux(struct clknode *clk, int index)
+{
+	struct aw_clk_nkmp_sc *sc;
+	uint32_t val;
+
+	sc = clknode_get_softc(clk);
+
+	if ((sc->flags & AW_CLK_HAS_MUX) != 0)
+		return (0);
+
+	DEVICE_LOCK(clk);
+	READ4(clk, sc->offset, &val);
+	val &= ~(sc->mux_mask >> sc->mux_shift);
+	val |= index << sc->mux_shift;
+	WRITE4(clk, sc->offset, val);
+	DEVICE_UNLOCK(clk);
+
+	return (0);
+}
+
 static uint64_t
 aw_clk_nkmp_find_best(struct aw_clk_nkmp_sc *sc, uint64_t fparent, uint64_t *fout,
     uint32_t *factor_n, uint32_t *factor_k, uint32_t *factor_m, uint32_t *factor_p)
@@ -314,6 +351,7 @@ static clknode_method_t aw_nkmp_clknode_
 	/* Device interface */
 	CLKNODEMETHOD(clknode_init,		aw_clk_nkmp_init),
 	CLKNODEMETHOD(clknode_set_gate,		aw_clk_nkmp_set_gate),
+	CLKNODEMETHOD(clknode_set_mux,		aw_clk_nkmp_set_mux),
 	CLKNODEMETHOD(clknode_recalc_freq,	aw_clk_nkmp_recalc),
 	CLKNODEMETHOD(clknode_set_freq,		aw_clk_nkmp_set_freq),
 	CLKNODEMETHOD_END
@@ -360,6 +398,9 @@ aw_clk_nkmp_register(struct clkdom *clkd
 	sc->p.value = clkdef->p.value;
 	sc->p.flags = clkdef->p.flags;
 
+	sc->mux_shift = clkdef->mux_shift;
+	sc->mux_mask = ((1 << clkdef->mux_width) - 1) << sc->mux_shift;
+
 	sc->gate_shift = clkdef->gate_shift;
 	sc->lock_shift = clkdef->lock_shift;
 	sc->lock_retries = clkdef->lock_retries;

Modified: head/sys/arm/allwinner/clkng/aw_clk_nkmp.h
==============================================================================
--- head/sys/arm/allwinner/clkng/aw_clk_nkmp.h	Tue Feb 28 15:03:34 2017	(r314392)
+++ head/sys/arm/allwinner/clkng/aw_clk_nkmp.h	Tue Feb 28 15:11:33 2017	(r314393)
@@ -41,6 +41,8 @@ struct aw_clk_nkmp_def {
 	struct aw_clk_factor	n;
 	struct aw_clk_factor	p;
 
+	uint32_t		mux_shift;
+	uint32_t		mux_width;
 	uint32_t		gate_shift;
 	uint32_t		lock_shift;
 	uint32_t		lock_retries;


More information about the svn-src-all mailing list