Thread (23 messages) 23 messages, 2 authors, 2016-02-28
STALE3773d

[PATCH v5 10/20] clk: bcm2835: implement correct clamping for mash clocks

From: kernel at martin.sperl.org <hidden>
Date: 2016-02-28 15:37:01
Also in: linux-clk
Subsystem: common clk framework, the rest · Maintainers: Michael Turquette, Stephen Boyd, Linus Torvalds

From: Martin Sperl <redacted>

The bcm2835-soc has 2 kindes of clocks:
* normal clocks
* mash-enabled clocks that can spread frequency noise better
  into non-audiable frequency ranges

The mash clocks have distinct clock-divider requirements
and if the requested divider is not in range, then there will
no clock output.

This patch implements the clamping limits for first order
fractual mash dividers.

Only dividers that are impacted by this patch are: pcm and pwm

Signed-off-by: Martin Sperl <redacted>
---
 drivers/clk/bcm/clk-bcm2835.c |   24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 3df17a5..2fb9923 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -407,6 +407,7 @@ struct bcm2835_clock_data {
 	/* Number of fractional bits in the divider */
 	u32 frac_bits;
 
+	bool is_mash_clock;
 	bool is_vpu_clock;
 };
 
@@ -780,10 +781,19 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
 		div += unused_frac_mask + 1;
 	div &= ~unused_frac_mask;
 
-	/* Clamp to the limits. */
-	div = max(div, unused_frac_mask + 1);
-	div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
-				      CM_DIV_FRAC_BITS - data->frac_bits));
+	/* Clamp to the limits for the clock type */
+	if (data->is_mash_clock) {
+		/* clamp to min divider 2 */
+		div = max_t(u32, div, 2 << CM_DIV_FRAC_BITS);
+		/* clamp to max int divider */
+		div = min_t(u32, div,
+			    (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS);
+	} else {
+		div = max(div, unused_frac_mask + 1);
+		div = min_t(u32, div,
+			    GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+				    CM_DIV_FRAC_BITS - data->frac_bits));
+	}
 
 	return div;
 }
@@ -1512,13 +1522,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
 		.ctl_reg = CM_PCMCTL,
 		.div_reg = CM_PCMDIV,
 		.int_bits = 12,
-		.frac_bits = 12),
+		.frac_bits = 12,
+		.is_mash_clock = true),
 	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
 		.name = "pwm",
 		.ctl_reg = CM_PWMCTL,
 		.div_reg = CM_PWMDIV,
 		.int_bits = 12,
-		.frac_bits = 12),
+		.frac_bits = 12,
+		.is_mash_clock = true),
 	[BCM2835_CLOCK_UART]	= REGISTER_PER_CLK(
 		.name = "uart",
 		.ctl_reg = CM_UARTCTL,
-- 
1.7.10.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help