public inbox for linux-pwm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pwm: atmel-hlcdc: add at91sam9x5 and sama5d3 errata handling
@ 2014-11-18 12:40 Boris Brezillon
  2014-11-18 14:35 ` Nicolas Ferre
  2014-11-18 15:00 ` Thierry Reding
  0 siblings, 2 replies; 4+ messages in thread
From: Boris Brezillon @ 2014-11-18 12:40 UTC (permalink / raw)
  To: Thierry Reding, linux-pwm
  Cc: Nicolas Ferre, Jean-Christophe Plagniol-Villard,
	Alexandre Belloni, Andrew Victor, Boris Brezillon

at91sam9x5 has an errata forbidding the use of slow clk as a clk source and
sama5d3 SoCs has another errata forbidding the use of div1 prescaler.

Take both of these erratas into account.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
 drivers/pwm/pwm-atmel-hlcdc.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
index eaf8b12..405f8a5 100644
--- a/drivers/pwm/pwm-atmel-hlcdc.c
+++ b/drivers/pwm/pwm-atmel-hlcdc.c
@@ -36,6 +36,8 @@ struct atmel_hlcdc_pwm {
 	struct pwm_chip chip;
 	struct atmel_hlcdc *hlcdc;
 	struct clk *cur_clk;
+	bool slow_clk_errata;
+	bool div1_clk_errata;
 };
 
 static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip)
@@ -56,20 +58,28 @@ static int atmel_hlcdc_pwm_config(struct pwm_chip *c,
 	u32 pwmcfg;
 	int pres;
 
-	clk_freq = clk_get_rate(new_clk);
-	clk_period_ns = (u64)NSEC_PER_SEC * 256;
-	do_div(clk_period_ns, clk_freq);
+	if (!chip->slow_clk_errata) {
+		clk_freq = clk_get_rate(new_clk);
+		clk_period_ns = (u64)NSEC_PER_SEC * 256;
+		do_div(clk_period_ns, clk_freq);
+	}
 
-	if (clk_period_ns > period_ns) {
+	/* Errata: cannot use slow clk on some IP revisions */
+	if (chip->slow_clk_errata || clk_period_ns > period_ns) {
 		new_clk = hlcdc->sys_clk;
 		clk_freq = clk_get_rate(new_clk);
 		clk_period_ns = (u64)NSEC_PER_SEC * 256;
 		do_div(clk_period_ns, clk_freq);
 	}
 
-	for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++)
+	for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) {
+		/* Errata: cannot divide by 1 on some IP revisions */
+		if (!pres && chip->div1_clk_errata)
+			continue;
+
 		if ((clk_period_ns << pres) >= period_ns)
 			break;
+	}
 
 	if (pres > ATMEL_HLCDC_PWMPS_MAX)
 		return -EINVAL;
@@ -204,6 +214,14 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	if (of_device_is_compatible(dev->parent->of_node,
+				    "atmel,sama5d3-hlcdc"))
+		chip->div1_clk_errata = true;
+
+	if (of_device_is_compatible(dev->parent->of_node,
+				    "atmel,at91sam9x5-hlcdc"))
+		chip->slow_clk_errata = true;
+
 	chip->hlcdc = hlcdc;
 	chip->chip.ops = &atmel_hlcdc_pwm_ops;
 	chip->chip.dev = dev;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-11-18 15:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-18 12:40 [PATCH] pwm: atmel-hlcdc: add at91sam9x5 and sama5d3 errata handling Boris Brezillon
2014-11-18 14:35 ` Nicolas Ferre
2014-11-18 15:00 ` Thierry Reding
2014-11-18 15:53   ` Boris Brezillon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox