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