daca4a8
From patchwork Thu Jun  1 14:14:16 2017
daca4a8
Content-Type: text/plain; charset="utf-8"
daca4a8
MIME-Version: 1.0
daca4a8
Content-Transfer-Encoding: 7bit
daca4a8
Subject: [v4,1/2] clk: bcm2835: Limit PCM clock to OSC and PLLD_PER
daca4a8
From: Phil Elwell <phil@raspberrypi.org>
daca4a8
X-Patchwork-Id: 9759641
daca4a8
Message-Id: <8cc0ba82-d33e-127b-7b86-ac595ef416d1@raspberrypi.org>
daca4a8
To: Michael Turquette <mturquette@baylibre.com>,
daca4a8
 Stephen Boyd <sboyd@codeaurora.org>, Eric Anholt <eric@anholt.net>,
daca4a8
 Stefan Wahren <stefan.wahren@i2se.com>,
daca4a8
 Florian Fainelli <f.fainelli@gmail.com>,
daca4a8
 linux-clk@vger.kernel.org, linux-rpi-kernel@lists.infradead.org,
daca4a8
 linux-kernel@vger.kernel.org
daca4a8
Date: Thu, 1 Jun 2017 15:14:16 +0100
daca4a8
daca4a8
Restrict clock sources for the PCM peripheral to the oscillator and
daca4a8
PLLD_PER because other source may have varying rates or be switched off.
daca4a8
Prevent other sources from being selected by replacing their names in
daca4a8
the list of potential parents with dummy entries (entry index is
daca4a8
significant).
daca4a8
daca4a8
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
daca4a8
Reviewed-by: Eric Anholt <eric@anholt.net>
daca4a8
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
daca4a8
---
daca4a8
 drivers/clk/bcm/clk-bcm2835.c | 27 ++++++++++++++++++++++++++-
daca4a8
 1 file changed, 26 insertions(+), 1 deletion(-)
daca4a8
daca4a8
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
daca4a8
index 0258538..49867d2 100644
daca4a8
--- a/drivers/clk/bcm/clk-bcm2835.c
daca4a8
+++ b/drivers/clk/bcm/clk-bcm2835.c
daca4a8
@@ -1516,6 +1516,31 @@ struct bcm2835_clk_desc {
daca4a8
 	.parents = bcm2835_clock_per_parents,				\
daca4a8
 	__VA_ARGS__)
daca4a8
 
daca4a8
+/*
daca4a8
+ * Restrict clock sources for the PCM peripheral to the oscillator and
daca4a8
+ * PLLD_PER because other source may have varying rates or be switched
daca4a8
+ * off.
daca4a8
+ *
daca4a8
+ * Prevent other sources from being selected by replacing their names in
daca4a8
+ * the list of potential parents with dummy entries (entry index is
daca4a8
+ * significant).
daca4a8
+ */
daca4a8
+static const char *const bcm2835_pcm_per_parents[] = {
daca4a8
+	"-",
daca4a8
+	"xosc",
daca4a8
+	"-",
daca4a8
+	"-",
daca4a8
+	"-",
daca4a8
+	"-",
daca4a8
+	"plld_per",
daca4a8
+	"-",
daca4a8
+};
daca4a8
+
daca4a8
+#define REGISTER_PCM_CLK(...)	REGISTER_CLK(				\
daca4a8
+	.num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents),		\
daca4a8
+	.parents = bcm2835_pcm_per_parents,				\
daca4a8
+	__VA_ARGS__)
daca4a8
+
daca4a8
 /* main vpu parent mux */
daca4a8
 static const char *const bcm2835_clock_vpu_parents[] = {
daca4a8
 	"gnd",
daca4a8
@@ -1993,7 +2018,7 @@ struct bcm2835_clk_desc {
daca4a8
 		.int_bits = 4,
daca4a8
 		.frac_bits = 8,
daca4a8
 		.tcnt_mux = 22),
daca4a8
-	[BCM2835_CLOCK_PCM]	= REGISTER_PER_CLK(
daca4a8
+	[BCM2835_CLOCK_PCM]	= REGISTER_PCM_CLK(
daca4a8
 		.name = "pcm",
daca4a8
 		.ctl_reg = CM_PCMCTL,
daca4a8
 		.div_reg = CM_PCMDIV,
daca4a8
From patchwork Thu Jun  1 14:14:22 2017
daca4a8
Content-Type: text/plain; charset="utf-8"
daca4a8
MIME-Version: 1.0
daca4a8
Content-Transfer-Encoding: 7bit
daca4a8
Subject: [v4,2/2] clk: bcm2835: Minimise clock jitter for PCM clock
daca4a8
From: Phil Elwell <phil@raspberrypi.org>
daca4a8
X-Patchwork-Id: 9759643
daca4a8
Message-Id: <9989244b-ca4d-9081-95d9-b24f51099222@raspberrypi.org>
daca4a8
To: Michael Turquette <mturquette@baylibre.com>,
daca4a8
 Stephen Boyd <sboyd@codeaurora.org>, Eric Anholt <eric@anholt.net>,
daca4a8
 Stefan Wahren <stefan.wahren@i2se.com>,
daca4a8
 Florian Fainelli <f.fainelli@gmail.com>,
daca4a8
 linux-clk@vger.kernel.org, linux-rpi-kernel@lists.infradead.org,
daca4a8
 linux-kernel@vger.kernel.org
daca4a8
Date: Thu, 1 Jun 2017 15:14:22 +0100
daca4a8
daca4a8
Fractional clock dividers generate accurate average frequencies but
daca4a8
with jitter, particularly when the integer divisor is small.
daca4a8
daca4a8
Introduce a new metric of clock accuracy to penalise clocks with a good
daca4a8
average but worse jitter compared to clocks with an average which is no
daca4a8
better but with lower jitter. The metric is the ideal rate minus the
daca4a8
worse deviation from that ideal using the nearest integer divisors.
daca4a8
daca4a8
Use this metric for parent selection for clocks requiring low jitter
daca4a8
(currently just PCM).
daca4a8
daca4a8
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
daca4a8
Reviewed-by: Eric Anholt <eric@anholt.net>
daca4a8
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
daca4a8
---
daca4a8
 drivers/clk/bcm/clk-bcm2835.c | 34 +++++++++++++++++++++++++++++-----
daca4a8
 1 file changed, 29 insertions(+), 5 deletions(-)
daca4a8
daca4a8
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
daca4a8
index 49867d2..0bc56a0 100644
daca4a8
--- a/drivers/clk/bcm/clk-bcm2835.c
daca4a8
+++ b/drivers/clk/bcm/clk-bcm2835.c
daca4a8
@@ -530,6 +530,7 @@ struct bcm2835_clock_data {
daca4a8
 
daca4a8
 	bool is_vpu_clock;
daca4a8
 	bool is_mash_clock;
daca4a8
+	bool low_jitter;
daca4a8
 
daca4a8
 	u32 tcnt_mux;
daca4a8
 };
daca4a8
@@ -1124,7 +1125,8 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
daca4a8
 							int parent_idx,
daca4a8
 							unsigned long rate,
daca4a8
 							u32 *div,
daca4a8
-							unsigned long *prate)
daca4a8
+							unsigned long *prate,
daca4a8
+							unsigned long *avgrate)
daca4a8
 {
daca4a8
 	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
daca4a8
 	struct bcm2835_cprman *cprman = clock->cprman;
daca4a8
@@ -1139,8 +1141,25 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
daca4a8
 		*prate = clk_hw_get_rate(parent);
daca4a8
 		*div = bcm2835_clock_choose_div(hw, rate, *prate, true);
daca4a8
 
daca4a8
-		return bcm2835_clock_rate_from_divisor(clock, *prate,
daca4a8
-						       *div);
daca4a8
+		*avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div);
daca4a8
+
daca4a8
+		if (data->low_jitter && (*div & CM_DIV_FRAC_MASK)) {
daca4a8
+			unsigned long high, low;
daca4a8
+			u32 int_div = *div & ~CM_DIV_FRAC_MASK;
daca4a8
+
daca4a8
+			high = bcm2835_clock_rate_from_divisor(clock, *prate,
daca4a8
+							       int_div);
daca4a8
+			int_div += CM_DIV_FRAC_MASK + 1;
daca4a8
+			low = bcm2835_clock_rate_from_divisor(clock, *prate,
daca4a8
+							      int_div);
daca4a8
+
daca4a8
+			/*
daca4a8
+			 * Return a value which is the maximum deviation
daca4a8
+			 * below the ideal rate, for use as a metric.
daca4a8
+			 */
daca4a8
+			return *avgrate - max(*avgrate - low, high - *avgrate);
daca4a8
+		}
daca4a8
+		return *avgrate;
daca4a8
 	}
daca4a8
 
daca4a8
 	if (data->frac_bits)
daca4a8
@@ -1167,6 +1186,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
daca4a8
 
daca4a8
 	*div = curdiv << CM_DIV_FRAC_BITS;
daca4a8
 	*prate = curdiv * best_rate;
daca4a8
+	*avgrate = best_rate;
daca4a8
 
daca4a8
 	return best_rate;
daca4a8
 }
daca4a8
@@ -1178,6 +1198,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
daca4a8
 	bool current_parent_is_pllc;
daca4a8
 	unsigned long rate, best_rate = 0;
daca4a8
 	unsigned long prate, best_prate = 0;
daca4a8
+	unsigned long avgrate, best_avgrate = 0;
daca4a8
 	size_t i;
daca4a8
 	u32 div;
daca4a8
 
daca4a8
@@ -1202,11 +1223,13 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
daca4a8
 			continue;
daca4a8
 
daca4a8
 		rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate,
daca4a8
-							  &div, &prate);
daca4a8
+							  &div, &prate,
daca4a8
+							  &avgrate);
daca4a8
 		if (rate > best_rate && rate <= req->rate) {
daca4a8
 			best_parent = parent;
daca4a8
 			best_prate = prate;
daca4a8
 			best_rate = rate;
daca4a8
+			best_avgrate = avgrate;
daca4a8
 		}
daca4a8
 	}
daca4a8
 
daca4a8
@@ -1216,7 +1239,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
daca4a8
 	req->best_parent_hw = best_parent;
daca4a8
 	req->best_parent_rate = best_prate;
daca4a8
 
daca4a8
-	req->rate = best_rate;
daca4a8
+	req->rate = best_avgrate;
daca4a8
 
daca4a8
 	return 0;
daca4a8
 }
daca4a8
@@ -2025,6 +2048,7 @@ struct bcm2835_clk_desc {
daca4a8
 		.int_bits = 12,
daca4a8
 		.frac_bits = 12,
daca4a8
 		.is_mash_clock = true,
daca4a8
+		.low_jitter = true,
daca4a8
 		.tcnt_mux = 23),
daca4a8
 	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
daca4a8
 		.name = "pwm",