Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Feb 2019 13:15:31 +0000 (UTC)
From:      Emmanuel Vadot <manu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r344577 - head/sys/arm64/rockchip/clk
Message-ID:  <201902261315.x1QDFV8H017703@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: manu
Date: Tue Feb 26 13:15:31 2019
New Revision: 344577
URL: https://svnweb.freebsd.org/changeset/base/344577

Log:
  arm64: rockchip: clk: ARM CLK improvement
  
  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 set the parent after changing its freqeuncy, this reduce the time
  between changing the parent and changing the divider for the arm clock.
  
  MFC after:	1 week

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

Modified: head/sys/arm64/rockchip/clk/rk_clk_armclk.c
==============================================================================
--- head/sys/arm64/rockchip/clk/rk_clk_armclk.c	Tue Feb 26 13:14:49 2019	(r344576)
+++ head/sys/arm64/rockchip/clk/rk_clk_armclk.c	Tue Feb 26 13:15:31 2019	(r344577)
@@ -72,8 +72,11 @@ struct rk_clk_armclk_sc {
 #define	DEVICE_UNLOCK(_clk)						\
 	CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
 
-#define	RK_ARMCLK_WRITE_MASK	0xFFFF0000
+#define	RK_ARMCLK_WRITE_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_armclk_init(struct clknode *clk, device_t dev)
 {
@@ -98,14 +101,15 @@ static int
 rk_clk_armclk_set_mux(struct clknode *clk, int index)
 {
 	struct rk_clk_armclk_sc *sc;
-	uint32_t val;
+	uint32_t val = 0;
 
 	sc = clknode_get_softc(clk);
 
+	dprintf("Set mux to %d\n", index);
 	DEVICE_LOCK(clk);
-	READ4(clk, sc->muxdiv_offset, &val);
-	val &= ~(sc->mux_mask >> sc->mux_shift);
-	val |= index << sc->mux_shift | RK_ARMCLK_WRITE_MASK;
+	val |= index << sc->mux_shift;
+	val |= sc->mux_mask << RK_ARMCLK_WRITE_MASK_SHIFT;
+	dprintf("Write: muxdiv_offset=%x, val=%x\n", sc->muxdiv_offset, val);
 	WRITE4(clk, sc->muxdiv_offset, val);
 	DEVICE_UNLOCK(clk);
 
@@ -123,10 +127,12 @@ rk_clk_armclk_recalc(struct clknode *clk, uint64_t *fr
 	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;
 
@@ -141,14 +147,14 @@ rk_clk_armclk_set_freq(struct clknode *clk, uint64_t f
 	struct clknode *p_main;
 	const char **p_names;
 	uint64_t best = 0, best_p = 0;
-	uint32_t div = 0, val;
+	uint32_t div = 0, val = 0;
 	int err, i, rate = 0;
 
 	sc = clknode_get_softc(clk);
 
+	dprintf("Finding best parent/div for target freq of %lu\n", *fout);
 	p_names = clknode_get_parent_names(clk);
 	p_main = clknode_find_by_name(p_names[sc->main_parent]);
-	clknode_set_parent_by_idx(clk, sc->main_parent);
 
 	for (i = 0; i < sc->nrates; i++) {
 		if (sc->rates[i].freq == *fout) {
@@ -156,6 +162,10 @@ rk_clk_armclk_set_freq(struct clknode *clk, uint64_t f
 			div = sc->rates[i].div;
 			best_p = best * div;
 			rate = i;
+			dprintf("Best parent %s (%d) with best freq at %lu\n",
+			    clknode_get_name(p_main),
+			    sc->main_parent,
+			    best);
 			break;
 		}
 	}
@@ -169,17 +179,22 @@ rk_clk_armclk_set_freq(struct clknode *clk, uint64_t f
 		return (0);
 	}
 
+	dprintf("Changing parent (%s) freq to %lu\n", clknode_get_name(p_main), best_p);
 	err = clknode_set_freq(p_main, best_p, 0, 1);
 	if (err != 0)
 		printf("Cannot set %s to %lu\n",
 		    clknode_get_name(p_main),
 		    best_p);
 
+	clknode_set_parent_by_idx(clk, sc->main_parent);
+
+	clknode_get_freq(p_main, &best_p);
+	dprintf("main parent freq at %lu\n", best_p);
 	DEVICE_LOCK(clk);
-	READ4(clk, sc->muxdiv_offset, &val);
-	val &= ~sc->div_mask;
 	val |= (div - 1) << sc->div_shift;
-	WRITE4(clk, sc->muxdiv_offset, val | RK_CLK_ARMCLK_MASK);
+	val |= sc->div_mask << RK_ARMCLK_WRITE_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_armclk.h
==============================================================================
--- head/sys/arm64/rockchip/clk/rk_clk_armclk.h	Tue Feb 26 13:14:49 2019	(r344576)
+++ head/sys/arm64/rockchip/clk/rk_clk_armclk.h	Tue Feb 26 13:15:31 2019	(r344577)
@@ -58,8 +58,6 @@ struct rk_clk_armclk_def {
 	int				nrates;
 };
 
-#define	RK_CLK_ARMCLK_MASK	0xFFFF0000
-
 int rk_clk_armclk_register(struct clkdom *clkdom,
     struct rk_clk_armclk_def *clkdef);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902261315.x1QDFV8H017703>