svn commit: r344576 - head/sys/arm64/rockchip/clk

Emmanuel Vadot manu at FreeBSD.org
Tue Feb 26 13:14:50 UTC 2019


Author: manu
Date: Tue Feb 26 13:14:49 2019
New Revision: 344576
URL: https://svnweb.freebsd.org/changeset/base/344576

Log:
  arm64: rockchip: clk: rk_clk_composite: Properly use the mask bits
  
  RockChip clocks register have a write mask in the upper 16 bits, if a 1
  is present the corresponding bit in the lower 16 ones is set.
  Use this instead of always setting the mask to 0xFFFF0000.
  This avoids a read of the register.
  While here add some debug printf useful for debuging clock problems
  
  MFC after:	1 week

Modified:
  head/sys/arm64/rockchip/clk/rk_clk_composite.c
  head/sys/arm64/rockchip/clk/rk_clk_composite.h

Modified: head/sys/arm64/rockchip/clk/rk_clk_composite.c
==============================================================================
--- head/sys/arm64/rockchip/clk/rk_clk_composite.c	Tue Feb 26 12:26:25 2019	(r344575)
+++ head/sys/arm64/rockchip/clk/rk_clk_composite.c	Tue Feb 26 13:14:49 2019	(r344576)
@@ -66,8 +66,11 @@ struct rk_clk_composite_sc {
 #define	DEVICE_UNLOCK(_clk)						\
 	CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
 
-#define	RK_COMPOSITE_WRITE_MASK	0xFFFF0000
+#define	RK_CLK_COMPOSITE_MASK_SHIFT	16
 
+/* #define	dprintf(format, arg...)	printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg) */
+#define	dprintf(format, arg...)
+
 static int
 rk_clk_composite_init(struct clknode *clk, device_t dev)
 {
@@ -94,20 +97,21 @@ static int
 rk_clk_composite_set_gate(struct clknode *clk, bool enable)
 {
 	struct rk_clk_composite_sc *sc;
-	uint32_t val;
+	uint32_t val = 0;
 
 	sc = clknode_get_softc(clk);
 
 	if ((sc->flags & RK_CLK_COMPOSITE_HAVE_GATE) == 0)
 		return (0);
 
-	DEVICE_LOCK(clk);
-	READ4(clk, sc->gate_offset, &val);
-	if (enable)
-		val &= ~(1 << sc->gate_shift);
-	else
+	dprintf("%sabling gate\n", enable ? "En" : "Dis");
+	if (!enable)
 		val |= 1 << sc->gate_shift;
-	WRITE4(clk, sc->gate_offset, val | RK_CLK_COMPOSITE_MASK);
+	dprintf("sc->gate_shift: %x\n", sc->gate_shift);
+	val |= (1 << sc->gate_shift) << RK_CLK_COMPOSITE_MASK_SHIFT;
+	dprintf("Write: gate_offset=%x, val=%x\n", sc->gate_offset, val);
+	DEVICE_LOCK(clk);
+	WRITE4(clk, sc->gate_offset, val);
 	DEVICE_UNLOCK(clk);
 
 	return (0);
@@ -117,18 +121,19 @@ static int
 rk_clk_composite_set_mux(struct clknode *clk, int index)
 {
 	struct rk_clk_composite_sc *sc;
-	uint32_t val;
+	uint32_t val = 0;
 
 	sc = clknode_get_softc(clk);
 
 	if ((sc->flags & RK_CLK_COMPOSITE_HAVE_MUX) == 0)
 		return (0);
 
+	dprintf("Set mux to %d\n", index);
 	DEVICE_LOCK(clk);
-	READ4(clk, sc->muxdiv_offset, &val);
-	val &= ~sc->mux_mask;
-	val |= index << sc->mux_shift;
-	WRITE4(clk, sc->muxdiv_offset, val | RK_CLK_COMPOSITE_MASK);
+	val |= (index << sc->mux_shift);
+	val |= sc->mux_mask << RK_CLK_COMPOSITE_MASK_SHIFT;
+	dprintf("Write: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, val);
+	WRITE4(clk, sc->muxdiv_offset, val);
 	DEVICE_UNLOCK(clk);
 
 	return (0);
@@ -145,11 +150,12 @@ rk_clk_composite_recalc(struct clknode *clk, uint64_t 
 	DEVICE_LOCK(clk);
 
 	READ4(clk, sc->muxdiv_offset, &reg);
+	dprintf("Read: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, reg);
 
 	DEVICE_UNLOCK(clk);
 
 	div = ((reg & sc->div_mask) >> sc->div_shift) + 1;
-
+	dprintf("parent_freq=%lu, div=%u\n", *freq, div);
 	*freq = *freq / div;
 
 	return (0);
@@ -183,22 +189,25 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_
 	struct clknode *p_clk;
 	const char **p_names;
 	uint64_t best, cur;
-	uint32_t div, best_div, val;
+	uint32_t div, best_div, val = 0;
 	int p_idx, best_parent;
 
 	sc = clknode_get_softc(clk);
 
+	dprintf("Finding best parent/div for target freq of %lu\n", *fout);
 	p_names = clknode_get_parent_names(clk);
 	for (best_div = 0, best = 0, p_idx = 0;
 	     p_idx != clknode_get_parents_num(clk); p_idx++) {
 		p_clk = clknode_find_by_name(p_names[p_idx]);
 		clknode_get_freq(p_clk, &fparent);
+		dprintf("Testing with parent %s (%d) at freq %lu\n", clknode_get_name(p_clk), p_idx, fparent);
 		div = rk_clk_composite_find_best(sc, fparent, *fout);
 		cur = fparent / div;
 		if ((*fout - cur) < (*fout - best)) {
 			best = cur;
 			best_div = div;
 			best_parent = p_idx;
+			dprintf("Best parent so far %s (%d) with best freq at %lu\n", clknode_get_name(p_clk), p_idx, best);
 		}
 	}
 
@@ -223,14 +232,17 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_
 	}
 
 	p_idx = clknode_get_parent_idx(clk);
-	if (p_idx != best_parent)
+	if (p_idx != best_parent) {
+		dprintf("Switching parent index from %d to %d\n", p_idx, best_parent);
 		clknode_set_parent_by_idx(clk, best_parent);
+	}
 
+	dprintf("Setting divider to %d\n", best_div);
 	DEVICE_LOCK(clk);
-	READ4(clk, sc->muxdiv_offset, &val);
-	val &= ~sc->div_mask;
 	val |= (best_div - 1) << sc->div_shift;
-	WRITE4(clk, sc->muxdiv_offset, val | RK_CLK_COMPOSITE_MASK);
+	val |= (sc->div_mask << sc->div_shift) << RK_CLK_COMPOSITE_MASK_SHIFT;
+	dprintf("Write: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, val);
+	WRITE4(clk, sc->muxdiv_offset, val);
 	DEVICE_UNLOCK(clk);
 
 	*fout = best;

Modified: head/sys/arm64/rockchip/clk/rk_clk_composite.h
==============================================================================
--- head/sys/arm64/rockchip/clk/rk_clk_composite.h	Tue Feb 26 12:26:25 2019	(r344575)
+++ head/sys/arm64/rockchip/clk/rk_clk_composite.h	Tue Feb 26 13:14:49 2019	(r344576)
@@ -53,8 +53,6 @@ struct rk_clk_composite_def {
 #define	RK_CLK_COMPOSITE_HAVE_MUX	0x0001
 #define	RK_CLK_COMPOSITE_HAVE_GATE	0x0002
 
-#define	RK_CLK_COMPOSITE_MASK	0xFFFF0000
-
 int rk_clk_composite_register(struct clkdom *clkdom,
     struct rk_clk_composite_def *clkdef);
 


More information about the svn-src-head mailing list