linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support
@ 2019-04-02 12:50 Alexandre Belloni
  2019-04-02 12:50 ` [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout Alexandre Belloni
                   ` (6 more replies)
  0 siblings, 7 replies; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

This series add support for the sam9x60 clocks handled by the PMC.

The first four patches are preparatory patches to handle register layout
and offset differences. Then, a driver for the new interface for PLLs is
added and the final patch is the driver for the sam9x60 PMC.

This supersedes
https://patchwork.kernel.org/project/linux-clk/list/?series=82811 and
https://patchwork.kernel.org/project/linux-clk/list/?series=100115

changes in v2:
 - rebased on v5.1-rc1
 - changed the PLL_ACR handling to conform to the datasheet errata

changes in v3:
 - remove unrelated patches

Alexandre Belloni (7):
  clk: at91: allow configuring peripheral PCR layout
  clk: at91: allow configuring generated PCR layout
  clk: at91: usb: Add sam9x60 support
  clk: at91: master: Add sam9x60 support
  clk: at91: add sam9x60 PLL driver
  dt-bindings: clk: at91: add bindings for SAM9X60 pmc
  clk: at91: add sam9x60 pmc driver

 .../devicetree/bindings/clock/at91-clock.txt  |   3 +-
 drivers/clk/at91/Makefile                     |   2 +
 drivers/clk/at91/at91sam9x5.c                 |   9 +
 drivers/clk/at91/clk-generated.c              |  48 +--
 drivers/clk/at91/clk-master.c                 |   8 +-
 drivers/clk/at91/clk-peripheral.c             |  46 +--
 drivers/clk/at91/clk-sam9x60-pll.c            | 330 ++++++++++++++++++
 drivers/clk/at91/clk-usb.c                    |  33 +-
 drivers/clk/at91/dt-compat.c                  |  12 +-
 drivers/clk/at91/pmc.h                        |  23 ++
 drivers/clk/at91/sam9x60.c                    | 307 ++++++++++++++++
 drivers/clk/at91/sama5d2.c                    |  10 +
 drivers/clk/at91/sama5d4.c                    |   8 +
 include/linux/clk/at91_pmc.h                  |  12 +-
 14 files changed, 786 insertions(+), 65 deletions(-)
 create mode 100644 drivers/clk/at91/clk-sam9x60-pll.c
 create mode 100644 drivers/clk/at91/sam9x60.c

-- 
2.20.1


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

* [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:36   ` Stephen Boyd
  2019-04-02 12:50 ` [PATCH v3 2/7] clk: at91: allow configuring generated " Alexandre Belloni
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

The PCR register actually changed layout for each SoC. By chance, this
didn't have impact on sama5d[2-4] support but since sama5d3, PID is seven
bits wide and sama5d4 and sama5d2 don't have DIV.

For the DT backward compatibility, keep the layout as is.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clk/at91/at91sam9x5.c     |  9 ++++++
 drivers/clk/at91/clk-peripheral.c | 46 ++++++++++++++++---------------
 drivers/clk/at91/dt-compat.c      |  9 ++++++
 drivers/clk/at91/pmc.h            | 12 ++++++++
 drivers/clk/at91/sama5d2.c        |  9 ++++++
 drivers/clk/at91/sama5d4.c        |  8 ++++++
 include/linux/clk/at91_pmc.h      |  3 --
 7 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
index 3487e03d4bc6..f5cfcbd85f10 100644
--- a/drivers/clk/at91/at91sam9x5.c
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -49,6 +49,13 @@ static const struct {
 	{ .n = "pck1",  .p = "prog1",    .id = 9 },
 };
 
+static const struct clk_pcr_layout at91sam9x5_pcr_layout = {
+	.offset = 0x10c,
+	.cmd = BIT(12),
+	.pid_mask = GENMASK(5, 0),
+	.div_mask = GENMASK(17, 16),
+};
+
 struct pck {
 	char *n;
 	u8 id;
@@ -242,6 +249,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
 
 	for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) {
 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &at91sam9x5_pcr_layout,
 							 at91sam9x5_periphck[i].n,
 							 "masterck",
 							 at91sam9x5_periphck[i].id,
@@ -254,6 +262,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
 
 	for (i = 0; extra_pcks[i].id; i++) {
 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &at91sam9x5_pcr_layout,
 							 extra_pcks[i].n,
 							 "masterck",
 							 extra_pcks[i].id,
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index 65c1defa78e4..6b7748b9588a 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -8,6 +8,7 @@
  *
  */
 
+#include <linux/bitops.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/at91_pmc.h>
@@ -23,9 +24,6 @@ DEFINE_SPINLOCK(pmc_pcr_lock);
 #define PERIPHERAL_ID_MAX	31
 #define PERIPHERAL_MASK(id)	(1 << ((id) & PERIPHERAL_ID_MAX))
 
-#define PERIPHERAL_RSHIFT_MASK	0x3
-#define PERIPHERAL_RSHIFT(val)	(((val) >> 16) & PERIPHERAL_RSHIFT_MASK)
-
 #define PERIPHERAL_MAX_SHIFT	3
 
 struct clk_peripheral {
@@ -43,6 +41,7 @@ struct clk_sam9x5_peripheral {
 	spinlock_t *lock;
 	u32 id;
 	u32 div;
+	const struct clk_pcr_layout *layout;
 	bool auto_div;
 };
 
@@ -169,13 +168,13 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
 		return 0;
 
 	spin_lock_irqsave(periph->lock, flags);
-	regmap_write(periph->regmap, AT91_PMC_PCR,
-		     (periph->id & AT91_PMC_PCR_PID_MASK));
-	regmap_update_bits(periph->regmap, AT91_PMC_PCR,
-			   AT91_PMC_PCR_DIV_MASK | AT91_PMC_PCR_CMD |
+	regmap_write(periph->regmap, periph->layout->offset,
+		     (periph->id & periph->layout->pid_mask));
+	regmap_update_bits(periph->regmap, periph->layout->offset,
+			   periph->layout->div_mask | periph->layout->cmd |
 			   AT91_PMC_PCR_EN,
-			   AT91_PMC_PCR_DIV(periph->div) |
-			   AT91_PMC_PCR_CMD |
+			   field_prep(periph->layout->div_mask, periph->div) |
+			   periph->layout->cmd |
 			   AT91_PMC_PCR_EN);
 	spin_unlock_irqrestore(periph->lock, flags);
 
@@ -191,11 +190,11 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
 		return;
 
 	spin_lock_irqsave(periph->lock, flags);
-	regmap_write(periph->regmap, AT91_PMC_PCR,
-		     (periph->id & AT91_PMC_PCR_PID_MASK));
-	regmap_update_bits(periph->regmap, AT91_PMC_PCR,
-			   AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD,
-			   AT91_PMC_PCR_CMD);
+	regmap_write(periph->regmap, periph->layout->offset,
+		     (periph->id & periph->layout->pid_mask));
+	regmap_update_bits(periph->regmap, periph->layout->offset,
+			   AT91_PMC_PCR_EN | periph->layout->cmd,
+			   periph->layout->cmd);
 	spin_unlock_irqrestore(periph->lock, flags);
 }
 
@@ -209,9 +208,9 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
 		return 1;
 
 	spin_lock_irqsave(periph->lock, flags);
-	regmap_write(periph->regmap, AT91_PMC_PCR,
-		     (periph->id & AT91_PMC_PCR_PID_MASK));
-	regmap_read(periph->regmap, AT91_PMC_PCR, &status);
+	regmap_write(periph->regmap, periph->layout->offset,
+		     (periph->id & periph->layout->pid_mask));
+	regmap_read(periph->regmap, periph->layout->offset, &status);
 	spin_unlock_irqrestore(periph->lock, flags);
 
 	return status & AT91_PMC_PCR_EN ? 1 : 0;
@@ -229,13 +228,13 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
 		return parent_rate;
 
 	spin_lock_irqsave(periph->lock, flags);
-	regmap_write(periph->regmap, AT91_PMC_PCR,
-		     (periph->id & AT91_PMC_PCR_PID_MASK));
-	regmap_read(periph->regmap, AT91_PMC_PCR, &status);
+	regmap_write(periph->regmap, periph->layout->offset,
+		     (periph->id & periph->layout->pid_mask));
+	regmap_read(periph->regmap, periph->layout->offset, &status);
 	spin_unlock_irqrestore(periph->lock, flags);
 
 	if (status & AT91_PMC_PCR_EN) {
-		periph->div = PERIPHERAL_RSHIFT(status);
+		periph->div = field_get(periph->layout->div_mask, status);
 		periph->auto_div = false;
 	} else {
 		clk_sam9x5_peripheral_autodiv(periph);
@@ -328,6 +327,7 @@ static const struct clk_ops sam9x5_peripheral_ops = {
 
 struct clk_hw * __init
 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
+				    const struct clk_pcr_layout *layout,
 				    const char *name, const char *parent_name,
 				    u32 id, const struct clk_range *range)
 {
@@ -354,7 +354,9 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
 	periph->div = 0;
 	periph->regmap = regmap;
 	periph->lock = lock;
-	periph->auto_div = true;
+	if (layout->div_mask)
+		periph->auto_div = true;
+	periph->layout = layout;
 	periph->range = *range;
 
 	hw = &periph->hw;
diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c
index b95bb4e2a927..aa09072f36db 100644
--- a/drivers/clk/at91/dt-compat.c
+++ b/drivers/clk/at91/dt-compat.c
@@ -93,6 +93,14 @@ CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
 	       of_sama5d2_clk_audio_pll_pmc_setup);
 #endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
 
+static const struct clk_pcr_layout dt_pcr_layout = {
+	.offset = 0x10c,
+	.cmd = BIT(12),
+	.pid_mask = GENMASK(5, 0),
+	.div_mask = GENMASK(17, 16),
+	.gckcss_mask = GENMASK(10, 8),
+};
+
 #ifdef CONFIG_HAVE_AT91_GENERATED_CLK
 #define GENERATED_SOURCE_MAX	6
 
@@ -448,6 +456,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
 
 			hw = at91_clk_register_sam9x5_peripheral(regmap,
 								 &pmc_pcr_lock,
+								 &dt_pcr_layout,
 								 name,
 								 parent_name,
 								 id, &range);
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 672a79bda88c..616c04588093 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -80,6 +80,17 @@ extern const struct clk_programmable_layout at91rm9200_programmable_layout;
 extern const struct clk_programmable_layout at91sam9g45_programmable_layout;
 extern const struct clk_programmable_layout at91sam9x5_programmable_layout;
 
+struct clk_pcr_layout {
+	u32 offset;
+	u32 cmd;
+	u32 div_mask;
+	u32 gckcss_mask;
+	u32 pid_mask;
+};
+
+#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
+#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask))
+
 #define ndck(a, s) (a[s - 1].id + 1)
 #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
 struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
@@ -143,6 +154,7 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
 			     const char *parent_name, u32 id);
 struct clk_hw * __init
 at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
+				    const struct clk_pcr_layout *layout,
 				    const char *name, const char *parent_name,
 				    u32 id, const struct clk_range *range);
 
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index 1f70cb164b06..9d128bd60fee 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -28,6 +28,13 @@ static const struct clk_pll_characteristics plla_characteristics = {
 	.out = plla_out,
 };
 
+static const struct clk_pcr_layout sama5d2_pcr_layout = {
+	.offset = 0x10c,
+	.cmd = BIT(12),
+	.gckcss_mask = GENMASK(10, 8),
+	.pid_mask = GENMASK(6, 0),
+};
+
 static const struct {
 	char *n;
 	char *p;
@@ -266,6 +273,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 
 	for (i = 0; i < ARRAY_SIZE(sama5d2_periphck); i++) {
 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sama5d2_pcr_layout,
 							 sama5d2_periphck[i].n,
 							 "masterck",
 							 sama5d2_periphck[i].id,
@@ -278,6 +286,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 
 	for (i = 0; i < ARRAY_SIZE(sama5d2_periph32ck); i++) {
 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sama5d2_pcr_layout,
 							 sama5d2_periph32ck[i].n,
 							 "h32mxck",
 							 sama5d2_periph32ck[i].id,
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
index b645a9d59cdb..840edca77821 100644
--- a/drivers/clk/at91/sama5d4.c
+++ b/drivers/clk/at91/sama5d4.c
@@ -28,6 +28,12 @@ static const struct clk_pll_characteristics plla_characteristics = {
 	.out = plla_out,
 };
 
+static const struct clk_pcr_layout sama5d4_pcr_layout = {
+	.offset = 0x10c,
+	.cmd = BIT(12),
+	.pid_mask = GENMASK(6, 0),
+};
+
 static const struct {
 	char *n;
 	char *p;
@@ -232,6 +238,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
 
 	for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) {
 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sama5d4_pcr_layout,
 							 sama5d4_periphck[i].n,
 							 "masterck",
 							 sama5d4_periphck[i].id,
@@ -244,6 +251,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
 
 	for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) {
 		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sama5d4_pcr_layout,
 							 sama5d4_periph32ck[i].n,
 							 "h32mxck",
 							 sama5d4_periph32ck[i].id,
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 931ab05f771d..b97b8dcbffe6 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -191,9 +191,6 @@
 #define		AT91_PMC_PCR_GCKCSS_MASK	(0x7  << AT91_PMC_PCR_GCKCSS_OFFSET)
 #define		AT91_PMC_PCR_GCKCSS(n)		((n)  << AT91_PMC_PCR_GCKCSS_OFFSET)	/* GCK Clock Source Selection */
 #define		AT91_PMC_PCR_CMD		(0x1  <<  12)				/* Command (read=0, write=1) */
-#define		AT91_PMC_PCR_DIV_OFFSET		16
-#define		AT91_PMC_PCR_DIV_MASK		(0x3  << AT91_PMC_PCR_DIV_OFFSET)
-#define		AT91_PMC_PCR_DIV(n)		((n)  << AT91_PMC_PCR_DIV_OFFSET)	/* Divisor Value */
 #define		AT91_PMC_PCR_GCKDIV_OFFSET	20
 #define		AT91_PMC_PCR_GCKDIV_MASK	(0xff  << AT91_PMC_PCR_GCKDIV_OFFSET)
 #define		AT91_PMC_PCR_GCKDIV(n)		((n)  << AT91_PMC_PCR_GCKDIV_OFFSET)	/* Generated Clock Divisor Value */
-- 
2.20.1


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

* [PATCH v3 2/7] clk: at91: allow configuring generated PCR layout
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
  2019-04-02 12:50 ` [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:37   ` Stephen Boyd
  2019-04-02 12:50 ` [PATCH v3 3/7] clk: at91: usb: Add sam9x60 support Alexandre Belloni
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

The PCR register layout for GCLKCSS is changing for the future SoCs, allow
configuring it.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clk/at91/clk-generated.c | 48 +++++++++++++++++---------------
 drivers/clk/at91/dt-compat.c     |  3 +-
 drivers/clk/at91/pmc.h           |  1 +
 drivers/clk/at91/sama5d2.c       |  1 +
 include/linux/clk/at91_pmc.h     |  7 +----
 5 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 66e7f7baf958..5f18847965c1 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/at91_pmc.h>
@@ -31,6 +32,7 @@ struct clk_generated {
 	spinlock_t *lock;
 	u32 id;
 	u32 gckdiv;
+	const struct clk_pcr_layout *layout;
 	u8 parent_id;
 	bool audio_pll_allowed;
 };
@@ -47,14 +49,14 @@ static int clk_generated_enable(struct clk_hw *hw)
 		 __func__, gck->gckdiv, gck->parent_id);
 
 	spin_lock_irqsave(gck->lock, flags);
-	regmap_write(gck->regmap, AT91_PMC_PCR,
-		     (gck->id & AT91_PMC_PCR_PID_MASK));
-	regmap_update_bits(gck->regmap, AT91_PMC_PCR,
-			   AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK |
-			   AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN,
-			   AT91_PMC_PCR_GCKCSS(gck->parent_id) |
-			   AT91_PMC_PCR_CMD |
-			   AT91_PMC_PCR_GCKDIV(gck->gckdiv) |
+	regmap_write(gck->regmap, gck->layout->offset,
+		     (gck->id & gck->layout->pid_mask));
+	regmap_update_bits(gck->regmap, gck->layout->offset,
+			   AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask |
+			   gck->layout->cmd | AT91_PMC_PCR_GCKEN,
+			   field_prep(gck->layout->gckcss_mask, gck->parent_id) |
+			   gck->layout->cmd |
+			   FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) |
 			   AT91_PMC_PCR_GCKEN);
 	spin_unlock_irqrestore(gck->lock, flags);
 	return 0;
@@ -66,11 +68,11 @@ static void clk_generated_disable(struct clk_hw *hw)
 	unsigned long flags;
 
 	spin_lock_irqsave(gck->lock, flags);
-	regmap_write(gck->regmap, AT91_PMC_PCR,
-		     (gck->id & AT91_PMC_PCR_PID_MASK));
-	regmap_update_bits(gck->regmap, AT91_PMC_PCR,
-			   AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN,
-			   AT91_PMC_PCR_CMD);
+	regmap_write(gck->regmap, gck->layout->offset,
+		     (gck->id & gck->layout->pid_mask));
+	regmap_update_bits(gck->regmap, gck->layout->offset,
+			   gck->layout->cmd | AT91_PMC_PCR_GCKEN,
+			   gck->layout->cmd);
 	spin_unlock_irqrestore(gck->lock, flags);
 }
 
@@ -81,9 +83,9 @@ static int clk_generated_is_enabled(struct clk_hw *hw)
 	unsigned int status;
 
 	spin_lock_irqsave(gck->lock, flags);
-	regmap_write(gck->regmap, AT91_PMC_PCR,
-		     (gck->id & AT91_PMC_PCR_PID_MASK));
-	regmap_read(gck->regmap, AT91_PMC_PCR, &status);
+	regmap_write(gck->regmap, gck->layout->offset,
+		     (gck->id & gck->layout->pid_mask));
+	regmap_read(gck->regmap, gck->layout->offset, &status);
 	spin_unlock_irqrestore(gck->lock, flags);
 
 	return status & AT91_PMC_PCR_GCKEN ? 1 : 0;
@@ -259,19 +261,18 @@ static void clk_generated_startup(struct clk_generated *gck)
 	unsigned long flags;
 
 	spin_lock_irqsave(gck->lock, flags);
-	regmap_write(gck->regmap, AT91_PMC_PCR,
-		     (gck->id & AT91_PMC_PCR_PID_MASK));
-	regmap_read(gck->regmap, AT91_PMC_PCR, &tmp);
+	regmap_write(gck->regmap, gck->layout->offset,
+		     (gck->id & gck->layout->pid_mask));
+	regmap_read(gck->regmap, gck->layout->offset, &tmp);
 	spin_unlock_irqrestore(gck->lock, flags);
 
-	gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
-					>> AT91_PMC_PCR_GCKCSS_OFFSET;
-	gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK)
-					>> AT91_PMC_PCR_GCKDIV_OFFSET;
+	gck->parent_id = field_get(gck->layout->gckcss_mask, tmp);
+	gck->gckdiv = FIELD_GET(AT91_PMC_PCR_GCKDIV_MASK, tmp);
 }
 
 struct clk_hw * __init
 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
+			    const struct clk_pcr_layout *layout,
 			    const char *name, const char **parent_names,
 			    u8 num_parents, u8 id, bool pll_audio,
 			    const struct clk_range *range)
@@ -298,6 +299,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
 	gck->lock = lock;
 	gck->range = *range;
 	gck->audio_pll_allowed = pll_audio;
+	gck->layout = layout;
 
 	clk_generated_startup(gck);
 	hw = &gck->hw;
diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c
index aa09072f36db..aa1754eac59f 100644
--- a/drivers/clk/at91/dt-compat.c
+++ b/drivers/clk/at91/dt-compat.c
@@ -154,7 +154,8 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
 		     id == GCK_ID_CLASSD))
 			pll_audio = true;
 
-		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
+		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+						 &dt_pcr_layout, name,
 						 parent_names, num_parents,
 						 id, pll_audio, &range);
 		if (IS_ERR(hw))
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 616c04588093..4027306b904c 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -116,6 +116,7 @@ at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
 
 struct clk_hw * __init
 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
+			    const struct clk_pcr_layout *layout,
 			    const char *name, const char **parent_names,
 			    u8 num_parents, u8 id, bool pll_audio,
 			    const struct clk_range *range);
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index 9d128bd60fee..096156850e08 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -305,6 +305,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	parent_names[5] = "audiopll_pmcck";
 	for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) {
 		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+						 &sama5d2_pcr_layout,
 						 sama5d2_gck[i].n,
 						 parent_names, 6,
 						 sama5d2_gck[i].id,
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index b97b8dcbffe6..31f00ebf1315 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -187,13 +187,8 @@
 
 #define AT91_PMC_PCR		0x10c			/* Peripheral Control Register [some SAM9 and SAMA5] */
 #define		AT91_PMC_PCR_PID_MASK		0x3f
-#define		AT91_PMC_PCR_GCKCSS_OFFSET	8
-#define		AT91_PMC_PCR_GCKCSS_MASK	(0x7  << AT91_PMC_PCR_GCKCSS_OFFSET)
-#define		AT91_PMC_PCR_GCKCSS(n)		((n)  << AT91_PMC_PCR_GCKCSS_OFFSET)	/* GCK Clock Source Selection */
 #define		AT91_PMC_PCR_CMD		(0x1  <<  12)				/* Command (read=0, write=1) */
-#define		AT91_PMC_PCR_GCKDIV_OFFSET	20
-#define		AT91_PMC_PCR_GCKDIV_MASK	(0xff  << AT91_PMC_PCR_GCKDIV_OFFSET)
-#define		AT91_PMC_PCR_GCKDIV(n)		((n)  << AT91_PMC_PCR_GCKDIV_OFFSET)	/* Generated Clock Divisor Value */
+#define		AT91_PMC_PCR_GCKDIV_MASK	GENMASK(27, 20)
 #define		AT91_PMC_PCR_EN			(0x1  <<  28)				/* Enable */
 #define		AT91_PMC_PCR_GCKEN		(0x1  <<  29)				/* GCK Enable */
 
-- 
2.20.1


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

* [PATCH v3 3/7] clk: at91: usb: Add sam9x60 support
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
  2019-04-02 12:50 ` [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout Alexandre Belloni
  2019-04-02 12:50 ` [PATCH v3 2/7] clk: at91: allow configuring generated " Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:37   ` Stephen Boyd
  2019-04-02 12:50 ` [PATCH v3 4/7] clk: at91: master: " Alexandre Belloni
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

The sam9x60 USB clock supports four different parents, ensure they can be
selected.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clk/at91/clk-usb.c | 33 +++++++++++++++++++++++++++------
 drivers/clk/at91/pmc.h     |  3 +++
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index 79ee1c760f2a..ebc37ee33518 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -23,9 +23,13 @@
 #define RM9200_USB_DIV_SHIFT	28
 #define RM9200_USB_DIV_TAB_SIZE	4
 
+#define SAM9X5_USBS_MASK	GENMASK(0, 0)
+#define SAM9X60_USBS_MASK	GENMASK(1, 0)
+
 struct at91sam9x5_clk_usb {
 	struct clk_hw hw;
 	struct regmap *regmap;
+	u32 usbs_mask;
 };
 
 #define to_at91sam9x5_clk_usb(hw) \
@@ -111,8 +115,7 @@ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
 	if (index > 1)
 		return -EINVAL;
 
-	regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS,
-			   index ? AT91_PMC_USBS : 0);
+	regmap_update_bits(usb->regmap, AT91_PMC_USB, usb->usbs_mask, index);
 
 	return 0;
 }
@@ -124,7 +127,7 @@ static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
 
 	regmap_read(usb->regmap, AT91_PMC_USB, &usbr);
 
-	return usbr & AT91_PMC_USBS;
+	return usbr & usb->usbs_mask;
 }
 
 static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -190,9 +193,10 @@ static const struct clk_ops at91sam9n12_usb_ops = {
 	.set_rate = at91sam9x5_clk_usb_set_rate,
 };
 
-struct clk_hw * __init
-at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
-			    const char **parent_names, u8 num_parents)
+static struct clk_hw * __init
+_at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
+			     const char **parent_names, u8 num_parents,
+			     u32 usbs_mask)
 {
 	struct at91sam9x5_clk_usb *usb;
 	struct clk_hw *hw;
@@ -212,6 +216,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
 
 	usb->hw.init = &init;
 	usb->regmap = regmap;
+	usb->usbs_mask = SAM9X5_USBS_MASK;
 
 	hw = &usb->hw;
 	ret = clk_hw_register(NULL, &usb->hw);
@@ -223,6 +228,22 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
 	return hw;
 }
 
+struct clk_hw * __init
+at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
+			    const char **parent_names, u8 num_parents)
+{
+	return _at91sam9x5_clk_register_usb(regmap, name, parent_names,
+					    num_parents, SAM9X5_USBS_MASK);
+}
+
+struct clk_hw * __init
+sam9x60_clk_register_usb(struct regmap *regmap, const char *name,
+			 const char **parent_names, u8 num_parents)
+{
+	return _at91sam9x5_clk_register_usb(regmap, name, parent_names,
+					    num_parents, SAM9X60_USBS_MASK);
+}
+
 struct clk_hw * __init
 at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
 			     const char *parent_name)
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 4027306b904c..44345e4ab1c9 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -194,6 +194,9 @@ struct clk_hw * __init
 at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
 			     const char *parent_name);
 struct clk_hw * __init
+sam9x60_clk_register_usb(struct regmap *regmap, const char *name,
+			 const char **parent_names, u8 num_parents);
+struct clk_hw * __init
 at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
 			    const char *parent_name, const u32 *divisors);
 
-- 
2.20.1


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

* [PATCH v3 4/7] clk: at91: master: Add sam9x60 support
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
                   ` (2 preceding siblings ...)
  2019-04-02 12:50 ` [PATCH v3 3/7] clk: at91: usb: Add sam9x60 support Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:37   ` Stephen Boyd
  2019-04-02 12:50 ` [PATCH v3 5/7] clk: at91: add sam9x60 PLL driver Alexandre Belloni
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

The sam9x60 cpu clock is located at a different offset but is otherwise
similar to the master clock.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clk/at91/clk-master.c | 8 +++++---
 drivers/clk/at91/pmc.h        | 1 +
 include/linux/clk/at91_pmc.h  | 2 ++
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index eb53b4a8fab6..12b5bf4cc7bb 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -29,6 +29,7 @@ struct clk_master {
 	struct regmap *regmap;
 	const struct clk_master_layout *layout;
 	const struct clk_master_characteristics *characteristics;
+	u32 mckr;
 };
 
 static inline bool clk_master_ready(struct regmap *regmap)
@@ -69,7 +70,7 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
 						master->characteristics;
 	unsigned int mckr;
 
-	regmap_read(master->regmap, AT91_PMC_MCKR, &mckr);
+	regmap_read(master->regmap, master->layout->offset, &mckr);
 	mckr &= layout->mask;
 
 	pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK;
@@ -95,7 +96,7 @@ static u8 clk_master_get_parent(struct clk_hw *hw)
 	struct clk_master *master = to_clk_master(hw);
 	unsigned int mckr;
 
-	regmap_read(master->regmap, AT91_PMC_MCKR, &mckr);
+	regmap_read(master->regmap, master->layout->offset, &mckr);
 
 	return mckr & AT91_PMC_CSS;
 }
@@ -147,13 +148,14 @@ at91_clk_register_master(struct regmap *regmap,
 	return hw;
 }
 
-
 const struct clk_master_layout at91rm9200_master_layout = {
 	.mask = 0x31F,
 	.pres_shift = 2,
+	.offset = AT91_PMC_MCKR,
 };
 
 const struct clk_master_layout at91sam9x5_master_layout = {
 	.mask = 0x373,
 	.pres_shift = 4,
+	.offset = AT91_PMC_MCKR,
 };
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 44345e4ab1c9..4a30c20f17f1 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -38,6 +38,7 @@ struct clk_range {
 #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
 
 struct clk_master_layout {
+	u32 offset;
 	u32 mask;
 	u8 pres_shift;
 };
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index 31f00ebf1315..0c53f26ae3d3 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -74,6 +74,8 @@
 #define			AT91_PMC_USBDIV_4		(2 << 28)
 #define		AT91_PMC_USB96M		(1     << 28)		/* Divider by 2 Enable (PLLB only) */
 
+#define AT91_PMC_CPU_CKR	0x28			/* CPU Clock Register */
+
 #define	AT91_PMC_MCKR		0x30			/* Master Clock Register */
 #define		AT91_PMC_CSS		(3 <<  0)		/* Master Clock Selection */
 #define			AT91_PMC_CSS_SLOW		(0 << 0)
-- 
2.20.1


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

* [PATCH v3 5/7] clk: at91: add sam9x60 PLL driver
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
                   ` (3 preceding siblings ...)
  2019-04-02 12:50 ` [PATCH v3 4/7] clk: at91: master: " Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:37   ` Stephen Boyd
  2019-04-02 12:50 ` [PATCH v3 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc Alexandre Belloni
  2019-04-02 12:50 ` [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver Alexandre Belloni
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

The PLLs on the sam9x60 (PLLA and USB PLL) use a different register set and
programming model than the previous SoCs.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clk/at91/Makefile          |   1 +
 drivers/clk/at91/clk-sam9x60-pll.c | 330 +++++++++++++++++++++++++++++
 drivers/clk/at91/pmc.h             |   6 +
 3 files changed, 337 insertions(+)
 create mode 100644 drivers/clk/at91/clk-sam9x60-pll.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index c75df1cad60e..0a30fc8dfcb0 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_HAVE_AT91_SMD)		+= clk-smd.o
 obj-$(CONFIG_HAVE_AT91_H32MX)		+= clk-h32mx.o
 obj-$(CONFIG_HAVE_AT91_GENERATED_CLK)	+= clk-generated.o
 obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK)	+= clk-i2s-mux.o
+obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL)	+= clk-sam9x60-pll.o
 obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
 obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
 obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
new file mode 100644
index 000000000000..34b817825b22
--- /dev/null
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright (C) 2019 Microchip Technology Inc.
+ *
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include "pmc.h"
+
+#define PMC_PLL_CTRL0	0xc
+#define		PMC_PLL_CTRL0_DIV_MSK		GENMASK(7, 0)
+#define		PMC_PLL_CTRL0_ENPLL		BIT(28)
+#define		PMC_PLL_CTRL0_ENPLLCK		BIT(29)
+#define		PMC_PLL_CTRL0_ENLOCK		BIT(31)
+
+#define PMC_PLL_CTRL1	0x10
+#define		PMC_PLL_CTRL1_FRACR_MSK		GENMASK(21, 0)
+#define		PMC_PLL_CTRL1_MUL_MSK		GENMASK(30, 24)
+
+#define PMC_PLL_ACR	0x18
+#define		PMC_PLL_ACR_DEFAULT		0x1b040010UL
+#define		PMC_PLL_ACR_UTMIVR		BIT(12)
+#define		PMC_PLL_ACR_UTMIBG		BIT(13)
+#define		PMC_PLL_ACR_LOOP_FILTER_MSK	GENMASK(31, 24)
+
+#define PMC_PLL_UPDT	0x1c
+#define		PMC_PLL_UPDT_UPDATE		BIT(8)
+
+#define PMC_PLL_ISR0	0xec
+
+#define PLL_DIV_MAX		(FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
+#define UPLL_DIV		2
+#define PLL_MUL_MAX		(FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
+
+#define PLL_MAX_ID		1
+
+struct sam9x60_pll {
+	struct clk_hw hw;
+	struct regmap *regmap;
+	spinlock_t *lock;
+	const struct clk_pll_characteristics *characteristics;
+	u32 frac;
+	u8 id;
+	u8 div;
+	u16 mul;
+};
+
+#define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw)
+
+static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
+{
+	unsigned int status;
+
+	regmap_read(regmap, PMC_PLL_ISR0, &status);
+
+	return !!(status & BIT(id));
+}
+
+static int sam9x60_pll_prepare(struct clk_hw *hw)
+{
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
+	struct regmap *regmap = pll->regmap;
+	unsigned long flags;
+	u8 div;
+	u16 mul;
+	u32 val;
+
+	spin_lock_irqsave(pll->lock, flags);
+	regmap_write(regmap, PMC_PLL_UPDT, pll->id);
+
+	regmap_read(regmap, PMC_PLL_CTRL0, &val);
+	div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
+
+	regmap_read(regmap, PMC_PLL_CTRL1, &val);
+	mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
+
+	if (sam9x60_pll_ready(regmap, pll->id) &&
+	    (div == pll->div && mul == pll->mul)) {
+		spin_unlock_irqrestore(pll->lock, flags);
+		return 0;
+	}
+
+	/* Recommended value for PMC_PLL_ACR */
+	val = PMC_PLL_ACR_DEFAULT;
+	regmap_write(regmap, PMC_PLL_ACR, val);
+
+	regmap_write(regmap, PMC_PLL_CTRL1,
+		     FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul));
+
+	if (pll->characteristics->upll) {
+		/* Enable the UTMI internal bandgap */
+		val |= PMC_PLL_ACR_UTMIBG;
+		regmap_write(regmap, PMC_PLL_ACR, val);
+
+		udelay(10);
+
+		/* Enable the UTMI internal regulator */
+		val |= PMC_PLL_ACR_UTMIVR;
+		regmap_write(regmap, PMC_PLL_ACR, val);
+
+		udelay(10);
+	}
+
+	regmap_update_bits(regmap, PMC_PLL_UPDT,
+			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
+
+	regmap_write(regmap, PMC_PLL_CTRL0,
+		     PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL |
+		     PMC_PLL_CTRL0_ENPLLCK | pll->div);
+
+	regmap_update_bits(regmap, PMC_PLL_UPDT,
+			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
+
+	while (!sam9x60_pll_ready(regmap, pll->id))
+		cpu_relax();
+
+	spin_unlock_irqrestore(pll->lock, flags);
+
+	return 0;
+}
+
+static int sam9x60_pll_is_prepared(struct clk_hw *hw)
+{
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
+
+	return sam9x60_pll_ready(pll->regmap, pll->id);
+}
+
+static void sam9x60_pll_unprepare(struct clk_hw *hw)
+{
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
+	unsigned long flags;
+
+	spin_lock_irqsave(pll->lock, flags);
+
+	regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id);
+
+	regmap_update_bits(pll->regmap, PMC_PLL_CTRL0,
+			   PMC_PLL_CTRL0_ENPLLCK, 0);
+
+	regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
+			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
+
+	regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0);
+
+	if (pll->characteristics->upll)
+		regmap_update_bits(pll->regmap, PMC_PLL_ACR,
+				   PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0);
+
+	regmap_update_bits(pll->regmap, PMC_PLL_UPDT,
+			   PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE);
+
+	spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
+
+	return (parent_rate * (pll->mul + 1)) / (pll->div + 1);
+}
+
+static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
+					 unsigned long rate,
+					 unsigned long parent_rate,
+					 bool update)
+{
+	const struct clk_pll_characteristics *characteristics =
+							pll->characteristics;
+	unsigned long bestremainder = ULONG_MAX;
+	unsigned long maxdiv, mindiv, tmpdiv;
+	long bestrate = -ERANGE;
+	unsigned long bestdiv = 0;
+	unsigned long bestmul = 0;
+	unsigned long bestfrac = 0;
+
+	if (rate < characteristics->output[0].min ||
+	    rate > characteristics->output[0].max)
+		return -ERANGE;
+
+	if (!pll->characteristics->upll) {
+		mindiv = parent_rate / rate;
+		if (mindiv < 2)
+			mindiv = 2;
+
+		maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate);
+		if (maxdiv > PLL_DIV_MAX)
+			maxdiv = PLL_DIV_MAX;
+	} else {
+		mindiv = maxdiv = UPLL_DIV;
+	}
+
+	for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) {
+		unsigned long remainder;
+		unsigned long tmprate;
+		unsigned long tmpmul;
+		unsigned long tmpfrac = 0;
+
+		/*
+		 * Calculate the multiplier associated with the current
+		 * divider that provide the closest rate to the requested one.
+		 */
+		tmpmul = mult_frac(rate, tmpdiv, parent_rate);
+		tmprate = mult_frac(parent_rate, tmpmul, tmpdiv);
+		remainder = rate - tmprate;
+
+		if (remainder) {
+			tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22),
+							parent_rate);
+
+			tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate,
+							 tmpdiv * (1 << 22));
+
+			if (tmprate > rate)
+				remainder = tmprate - rate;
+			else
+				remainder = rate - tmprate;
+		}
+
+		/*
+		 * Compare the remainder with the best remainder found until
+		 * now and elect a new best multiplier/divider pair if the
+		 * current remainder is smaller than the best one.
+		 */
+		if (remainder < bestremainder) {
+			bestremainder = remainder;
+			bestdiv = tmpdiv;
+			bestmul = tmpmul;
+			bestrate = tmprate;
+			bestfrac = tmpfrac;
+		}
+
+		/* We've found a perfect match!  */
+		if (!remainder)
+			break;
+	}
+
+	/* Check if bestrate is a valid output rate  */
+	if (bestrate < characteristics->output[0].min &&
+	    bestrate > characteristics->output[0].max)
+		return -ERANGE;
+
+	if (update) {
+		pll->div = bestdiv - 1;
+		pll->mul = bestmul - 1;
+		pll->frac = bestfrac;
+	}
+
+	return bestrate;
+}
+
+static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
+{
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
+
+	return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false);
+}
+
+static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct sam9x60_pll *pll = to_sam9x60_pll(hw);
+
+	return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true);
+}
+
+static const struct clk_ops pll_ops = {
+	.prepare = sam9x60_pll_prepare,
+	.unprepare = sam9x60_pll_unprepare,
+	.is_prepared = sam9x60_pll_is_prepared,
+	.recalc_rate = sam9x60_pll_recalc_rate,
+	.round_rate = sam9x60_pll_round_rate,
+	.set_rate = sam9x60_pll_set_rate,
+};
+
+struct clk_hw * __init
+sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
+			 const char *name, const char *parent_name, u8 id,
+			 const struct clk_pll_characteristics *characteristics)
+{
+	struct sam9x60_pll *pll;
+	struct clk_hw *hw;
+	struct clk_init_data init;
+	unsigned int pllr;
+	int ret;
+
+	if (id > PLL_MAX_ID)
+		return ERR_PTR(-EINVAL);
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &pll_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = CLK_SET_RATE_GATE;
+
+	pll->id = id;
+	pll->hw.init = &init;
+	pll->characteristics = characteristics;
+	pll->regmap = regmap;
+	pll->lock = lock;
+
+	regmap_write(regmap, PMC_PLL_UPDT, id);
+	regmap_read(regmap, PMC_PLL_CTRL0, &pllr);
+	pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr);
+	regmap_read(regmap, PMC_PLL_CTRL1, &pllr);
+	pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr);
+
+	hw = &pll->hw;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(pll);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
+
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 4a30c20f17f1..fb9e9c4cdc8d 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -69,6 +69,7 @@ struct clk_pll_characteristics {
 	struct clk_range *output;
 	u16 *icpll;
 	u8 *out;
+	u8 upll : 1;
 };
 
 struct clk_programmable_layout {
@@ -169,6 +170,11 @@ struct clk_hw * __init
 at91_clk_register_plldiv(struct regmap *regmap, const char *name,
 			 const char *parent_name);
 
+struct clk_hw * __init
+sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock,
+			 const char *name, const char *parent_name, u8 id,
+			 const struct clk_pll_characteristics *characteristics);
+
 struct clk_hw * __init
 at91_clk_register_programmable(struct regmap *regmap, const char *name,
 			       const char **parent_names, u8 num_parents, u8 id,
-- 
2.20.1


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

* [PATCH v3 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
                   ` (4 preceding siblings ...)
  2019-04-02 12:50 ` [PATCH v3 5/7] clk: at91: add sam9x60 PLL driver Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:37   ` Stephen Boyd
  2019-04-02 12:50 ` [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver Alexandre Belloni
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Add SAM9X60 PMC compatible string.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 Documentation/devicetree/bindings/clock/at91-clock.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt
index ce1d21102428..e0e4fa67716f 100644
--- a/Documentation/devicetree/bindings/clock/at91-clock.txt
+++ b/Documentation/devicetree/bindings/clock/at91-clock.txt
@@ -37,7 +37,8 @@ For example:
 Power Management Controller (PMC):
 
 Required properties:
-- compatible : shall be "atmel,<chip>-pmc", "syscon":
+- compatible : shall be "atmel,<chip>-pmc", "syscon" or
+	"microchip,sam9x60-pmc"
 	<chip> can be: at91rm9200, at91sam9260, at91sam9261,
 	at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15,
 	at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5,
-- 
2.20.1


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

* [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
                   ` (5 preceding siblings ...)
  2019-04-02 12:50 ` [PATCH v3 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc Alexandre Belloni
@ 2019-04-02 12:50 ` Alexandre Belloni
  2019-04-25 19:38   ` Stephen Boyd
  6 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-02 12:50 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Add a driver for the PMC clocks of the sam9c60.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/clk/at91/Makefile  |   1 +
 drivers/clk/at91/sam9x60.c | 307 +++++++++++++++++++++++++++++++++++++
 2 files changed, 308 insertions(+)
 create mode 100644 drivers/clk/at91/sam9x60.c

diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 0a30fc8dfcb0..3732241352ce 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_HAVE_AT91_GENERATED_CLK)	+= clk-generated.o
 obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK)	+= clk-i2s-mux.o
 obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL)	+= clk-sam9x60-pll.o
 obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
+obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
 obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
 obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
new file mode 100644
index 000000000000..22bf51c55bdc
--- /dev/null
+++ b/drivers/clk/at91/sam9x60.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+DEFINE_SPINLOCK(pmc_pll_lock);
+
+static const struct clk_master_characteristics mck_characteristics = {
+	.output = { .min = 140000000, .max = 200000000 },
+	.divisors = { 1, 2, 4, 3 },
+	.have_div3_pres = 1,
+};
+
+static const struct clk_master_layout sam9x60_master_layout = {
+	.mask = 0x373,
+	.pres_shift = 4,
+	.offset = 0x28,
+};
+
+static struct clk_range plla_outputs[] = {
+	{ .min = 300000000, .max = 600000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+	.input = { .min = 12000000, .max = 48000000 },
+	.num_output = ARRAY_SIZE(plla_outputs),
+	.output = plla_outputs,
+};
+
+static struct clk_range upll_outputs[] = {
+	{ .min = 300000000, .max = 500000000 },
+};
+
+static const struct clk_pll_characteristics upll_characteristics = {
+	.input = { .min = 12000000, .max = 48000000 },
+	.num_output = ARRAY_SIZE(upll_outputs),
+	.output = upll_outputs,
+	.upll = true,
+};
+
+static const struct clk_programmable_layout sam9x60_programmable_layout = {
+	.pres_shift = 8,
+	.css_mask = 0x1f,
+	.have_slck_mck = 0,
+};
+
+static const struct clk_pcr_layout sam9x60_pcr_layout = {
+	.offset = 0x88,
+	.cmd = BIT(31),
+	.gckcss_mask = GENMASK(12, 8),
+	.pid_mask = GENMASK(6, 0),
+};
+
+static const struct {
+	char *n;
+	char *p;
+	u8 id;
+} sam9x60_systemck[] = {
+	{ .n = "ddrck",  .p = "masterck", .id = 2 },
+	{ .n = "uhpck",  .p = "usbck",    .id = 6 },
+	{ .n = "pck0",   .p = "prog0",    .id = 8 },
+	{ .n = "pck1",   .p = "prog1",    .id = 9 },
+	{ .n = "qspick", .p = "masterck", .id = 19 },
+};
+
+static const struct {
+	char *n;
+	u8 id;
+} sam9x60_periphck[] = {
+	{ .n = "pioA_clk",   .id = 2, },
+	{ .n = "pioB_clk",   .id = 3, },
+	{ .n = "pioC_clk",   .id = 4, },
+	{ .n = "flex0_clk",  .id = 5, },
+	{ .n = "flex1_clk",  .id = 6, },
+	{ .n = "flex2_clk",  .id = 7, },
+	{ .n = "flex3_clk",  .id = 8, },
+	{ .n = "flex6_clk",  .id = 9, },
+	{ .n = "flex7_clk",  .id = 10, },
+	{ .n = "flex8_clk",  .id = 11, },
+	{ .n = "sdmmc0_clk", .id = 12, },
+	{ .n = "flex4_clk",  .id = 13, },
+	{ .n = "flex5_clk",  .id = 14, },
+	{ .n = "flex9_clk",  .id = 15, },
+	{ .n = "flex10_clk", .id = 16, },
+	{ .n = "tcb0_clk",   .id = 17, },
+	{ .n = "pwm_clk",    .id = 18, },
+	{ .n = "adc_clk",    .id = 19, },
+	{ .n = "dma0_clk",   .id = 20, },
+	{ .n = "matrix_clk", .id = 21, },
+	{ .n = "uhphs_clk",  .id = 22, },
+	{ .n = "udphs_clk",  .id = 23, },
+	{ .n = "macb0_clk",  .id = 24, },
+	{ .n = "lcd_clk",    .id = 25, },
+	{ .n = "sdmmc1_clk", .id = 26, },
+	{ .n = "macb1_clk",  .id = 27, },
+	{ .n = "ssc_clk",    .id = 28, },
+	{ .n = "can0_clk",   .id = 29, },
+	{ .n = "can1_clk",   .id = 30, },
+	{ .n = "flex11_clk", .id = 32, },
+	{ .n = "flex12_clk", .id = 33, },
+	{ .n = "i2s_clk",    .id = 34, },
+	{ .n = "qspi_clk",   .id = 35, },
+	{ .n = "gfx2d_clk",  .id = 36, },
+	{ .n = "pit64b_clk", .id = 37, },
+	{ .n = "trng_clk",   .id = 38, },
+	{ .n = "aes_clk",    .id = 39, },
+	{ .n = "tdes_clk",   .id = 40, },
+	{ .n = "sha_clk",    .id = 41, },
+	{ .n = "classd_clk", .id = 42, },
+	{ .n = "isi_clk",    .id = 43, },
+	{ .n = "pioD_clk",   .id = 44, },
+	{ .n = "tcb1_clk",   .id = 45, },
+	{ .n = "dbgu_clk",   .id = 47, },
+	{ .n = "mpddr_clk",  .id = 49, },
+};
+
+static const struct {
+	char *n;
+	u8 id;
+	struct clk_range r;
+	bool pll;
+} sam9x60_gck[] = {
+	{ .n = "flex0_gclk",  .id = 5, },
+	{ .n = "flex1_gclk",  .id = 6, },
+	{ .n = "flex2_gclk",  .id = 7, },
+	{ .n = "flex3_gclk",  .id = 8, },
+	{ .n = "flex6_gclk",  .id = 9, },
+	{ .n = "flex7_gclk",  .id = 10, },
+	{ .n = "flex8_gclk",  .id = 11, },
+	{ .n = "sdmmc0_gclk", .id = 12, .r = { .min = 0, .max = 105000000 }, },
+	{ .n = "flex4_gclk",  .id = 13, },
+	{ .n = "flex5_gclk",  .id = 14, },
+	{ .n = "flex9_gclk",  .id = 15, },
+	{ .n = "flex10_gclk", .id = 16, },
+	{ .n = "tcb0_gclk",   .id = 17, },
+	{ .n = "adc_gclk",    .id = 19, },
+	{ .n = "lcd_gclk",    .id = 25, .r = { .min = 0, .max = 140000000 }, },
+	{ .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, },
+	{ .n = "flex11_gclk", .id = 32, },
+	{ .n = "flex12_gclk", .id = 33, },
+	{ .n = "i2s_gclk",    .id = 34, .r = { .min = 0, .max = 105000000 },
+		.pll = true, },
+	{ .n = "pit64b_gclk", .id = 37, },
+	{ .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 },
+		.pll = true, },
+	{ .n = "tcb1_gclk",   .id = 45, },
+	{ .n = "dbgu_gclk",   .id = 47, },
+};
+
+static void __init sam9x60_pmc_setup(struct device_node *np)
+{
+	struct clk_range range = CLK_RANGE(0, 0);
+	const char *td_slck_name, *md_slck_name, *mainxtal_name;
+	struct pmc_data *sam9x60_pmc;
+	const char *parent_names[6];
+	struct regmap *regmap;
+	struct clk_hw *hw;
+	int i;
+	bool bypass;
+
+	i = of_property_match_string(np, "clock-names", "td_slck");
+	if (i < 0)
+		return;
+
+	td_slck_name = of_clk_get_parent_name(np, i);
+
+	i = of_property_match_string(np, "clock-names", "md_slck");
+	if (i < 0)
+		return;
+
+	md_slck_name = of_clk_get_parent_name(np, i);
+
+	i = of_property_match_string(np, "clock-names", "main_xtal");
+	if (i < 0)
+		return;
+	mainxtal_name = of_clk_get_parent_name(np, i);
+
+	regmap = syscon_node_to_regmap(np);
+	if (IS_ERR(regmap))
+		return;
+
+	sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1,
+					nck(sam9x60_systemck),
+					nck(sam9x60_periphck),
+					nck(sam9x60_gck));
+	if (!sam9x60_pmc)
+		return;
+
+	hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 24000000,
+					   50000000);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+	hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
+					bypass);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	parent_names[0] = "main_rc_osc";
+	parent_names[1] = "main_osc";
+	hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sam9x60_pmc->chws[PMC_MAIN] = hw;
+
+	hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "pllack",
+				      "mainck", 0, &plla_characteristics);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck",
+				      "main_osc", 1, &upll_characteristics);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sam9x60_pmc->chws[PMC_UTMI] = hw;
+
+	parent_names[0] = md_slck_name;
+	parent_names[1] = "mainck";
+	parent_names[2] = "pllack";
+	hw = at91_clk_register_master(regmap, "masterck", 3, parent_names,
+				      &sam9x60_master_layout,
+				      &mck_characteristics);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	sam9x60_pmc->chws[PMC_MCK] = hw;
+
+	parent_names[0] = "pllack";
+	parent_names[1] = "upllck";
+	parent_names[2] = "mainck";
+	parent_names[3] = "mainck";
+	hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 4);
+	if (IS_ERR(hw))
+		goto err_free;
+
+	parent_names[0] = md_slck_name;
+	parent_names[1] = td_slck_name;
+	parent_names[2] = "mainck";
+	parent_names[3] = "masterck";
+	parent_names[4] = "pllack";
+	parent_names[5] = "upllck";
+	for (i = 0; i < 8; i++) {
+		char name[6];
+
+		snprintf(name, sizeof(name), "prog%d", i);
+
+		hw = at91_clk_register_programmable(regmap, name,
+						    parent_names, 6, i,
+						    &sam9x60_programmable_layout);
+		if (IS_ERR(hw))
+			goto err_free;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
+		hw = at91_clk_register_system(regmap, sam9x60_systemck[i].n,
+					      sam9x60_systemck[i].p,
+					      sam9x60_systemck[i].id);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x60_pmc->shws[sam9x60_systemck[i].id] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) {
+		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+							 &sam9x60_pcr_layout,
+							 sam9x60_periphck[i].n,
+							 "masterck",
+							 sam9x60_periphck[i].id,
+							 &range);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x60_pmc->phws[sam9x60_periphck[i].id] = hw;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) {
+		hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+						 &sam9x60_pcr_layout,
+						 sam9x60_gck[i].n,
+						 parent_names, 6,
+						 sam9x60_gck[i].id,
+						 sam9x60_gck[i].pll,
+						 &sam9x60_gck[i].r);
+		if (IS_ERR(hw))
+			goto err_free;
+
+		sam9x60_pmc->ghws[sam9x60_gck[i].id] = hw;
+	}
+
+	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x60_pmc);
+
+	return;
+
+err_free:
+	pmc_data_free(sam9x60_pmc);
+}
+
+CLK_OF_DECLARE_DRIVER(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
-- 
2.20.1


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

* Re: [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout
  2019-04-02 12:50 ` [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout Alexandre Belloni
@ 2019-04-25 19:36   ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:36 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:50)
> The PCR register actually changed layout for each SoC. By chance, this
> didn't have impact on sama5d[2-4] support but since sama5d3, PID is seven
> bits wide and sama5d4 and sama5d2 don't have DIV.
> 
> For the DT backward compatibility, keep the layout as is.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---

Applied to clk-next


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

* Re: [PATCH v3 2/7] clk: at91: allow configuring generated PCR layout
  2019-04-02 12:50 ` [PATCH v3 2/7] clk: at91: allow configuring generated " Alexandre Belloni
@ 2019-04-25 19:37   ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:37 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:51)
> The PCR register layout for GCLKCSS is changing for the future SoCs, allow
> configuring it.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---

Applied to clk-next


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

* Re: [PATCH v3 3/7] clk: at91: usb: Add sam9x60 support
  2019-04-02 12:50 ` [PATCH v3 3/7] clk: at91: usb: Add sam9x60 support Alexandre Belloni
@ 2019-04-25 19:37   ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:37 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:52)
> The sam9x60 USB clock supports four different parents, ensure they can be
> selected.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---

Applied to clk-next


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

* Re: [PATCH v3 4/7] clk: at91: master: Add sam9x60 support
  2019-04-02 12:50 ` [PATCH v3 4/7] clk: at91: master: " Alexandre Belloni
@ 2019-04-25 19:37   ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:37 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:53)
> The sam9x60 cpu clock is located at a different offset but is otherwise
> similar to the master clock.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---

Applied to clk-next


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

* Re: [PATCH v3 5/7] clk: at91: add sam9x60 PLL driver
  2019-04-02 12:50 ` [PATCH v3 5/7] clk: at91: add sam9x60 PLL driver Alexandre Belloni
@ 2019-04-25 19:37   ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:37 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:54)
> The PLLs on the sam9x60 (PLLA and USB PLL) use a different register set and
> programming model than the previous SoCs.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---

Applied to clk-next


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

* Re: [PATCH v3 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc
  2019-04-02 12:50 ` [PATCH v3 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc Alexandre Belloni
@ 2019-04-25 19:37   ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:37 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:55)
> Add SAM9X60 PMC compatible string.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---

Applied to clk-next


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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-02 12:50 ` [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver Alexandre Belloni
@ 2019-04-25 19:38   ` Stephen Boyd
  2019-04-25 20:31     ` Alexandre Belloni
  0 siblings, 1 reply; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 19:38 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel, Alexandre Belloni

Quoting Alexandre Belloni (2019-04-02 05:50:56)
> diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
> new file mode 100644
> index 000000000000..22bf51c55bdc
> --- /dev/null
> +++ b/drivers/clk/at91/sam9x60.c
> @@ -0,0 +1,307 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/clk-provider.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/slab.h>
> +
> +#include <dt-bindings/clock/at91.h>
> +
> +#include "pmc.h"
> +
> +DEFINE_SPINLOCK(pmc_pll_lock);
> +
> +static const struct clk_master_characteristics mck_characteristics = {
> +       .output = { .min = 140000000, .max = 200000000 },
> +       .divisors = { 1, 2, 4, 3 },
> +       .have_div3_pres = 1,
> +};
> +
> +static const struct clk_master_layout sam9x60_master_layout = {
> +       .mask = 0x373,
> +       .pres_shift = 4,
> +       .offset = 0x28,
> +};
> +
> +static struct clk_range plla_outputs[] = {

const?

> +       { .min = 300000000, .max = 600000000 },
> +};
[...]
> +
> +}
> +
> +CLK_OF_DECLARE_DRIVER(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
> -- 

Can't be platform device?


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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 19:38   ` Stephen Boyd
@ 2019-04-25 20:31     ` Alexandre Belloni
  2019-04-25 20:58       ` Stephen Boyd
  0 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-25 20:31 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel

On 25/04/2019 12:38:55-0700, Stephen Boyd wrote:
> Quoting Alexandre Belloni (2019-04-02 05:50:56)
> > diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
> > new file mode 100644
> > index 000000000000..22bf51c55bdc
> > --- /dev/null
> > +++ b/drivers/clk/at91/sam9x60.c
> > @@ -0,0 +1,307 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +#include <linux/clk-provider.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/slab.h>
> > +
> > +#include <dt-bindings/clock/at91.h>
> > +
> > +#include "pmc.h"
> > +
> > +DEFINE_SPINLOCK(pmc_pll_lock);
> > +
> > +static const struct clk_master_characteristics mck_characteristics = {
> > +       .output = { .min = 140000000, .max = 200000000 },
> > +       .divisors = { 1, 2, 4, 3 },
> > +       .have_div3_pres = 1,
> > +};
> > +
> > +static const struct clk_master_layout sam9x60_master_layout = {
> > +       .mask = 0x373,
> > +       .pres_shift = 4,
> > +       .offset = 0x28,
> > +};
> > +
> > +static struct clk_range plla_outputs[] = {
> 
> const?
> 

Right, can you fix that up or should I send a new version?

> > +       { .min = 300000000, .max = 600000000 },
> > +};
> [...]
> > +
> > +}
> > +
> > +CLK_OF_DECLARE_DRIVER(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
> > -- 
> 
> Can't be platform device?
> 

IIRC two clocks are used by the clocksource and having it as a platform
device make the clocksource driver fail with -EPROBE_DEFER.


-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 20:31     ` Alexandre Belloni
@ 2019-04-25 20:58       ` Stephen Boyd
  2019-04-25 21:10         ` Alexandre Belloni
  2019-04-25 21:14         ` Stephen Boyd
  0 siblings, 2 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 20:58 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel

Quoting Alexandre Belloni (2019-04-25 13:31:39)
> On 25/04/2019 12:38:55-0700, Stephen Boyd wrote:
> > Quoting Alexandre Belloni (2019-04-02 05:50:56)
> > > diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
> > > new file mode 100644
> > > index 000000000000..22bf51c55bdc
> > > --- /dev/null
> > > +++ b/drivers/clk/at91/sam9x60.c
> > > @@ -0,0 +1,307 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +#include <linux/clk-provider.h>
> > > +#include <linux/mfd/syscon.h>
> > > +#include <linux/slab.h>
> > > +
> > > +#include <dt-bindings/clock/at91.h>
> > > +
> > > +#include "pmc.h"
> > > +
> > > +DEFINE_SPINLOCK(pmc_pll_lock);
> > > +
> > > +static const struct clk_master_characteristics mck_characteristics = {
> > > +       .output = { .min = 140000000, .max = 200000000 },
> > > +       .divisors = { 1, 2, 4, 3 },
> > > +       .have_div3_pres = 1,
> > > +};
> > > +
> > > +static const struct clk_master_layout sam9x60_master_layout = {
> > > +       .mask = 0x373,
> > > +       .pres_shift = 4,
> > > +       .offset = 0x28,
> > > +};
> > > +
> > > +static struct clk_range plla_outputs[] = {
> > 
> > const?
> > 
> 
> Right, can you fix that up or should I send a new version?
> 

I can fix it.

> > > +       { .min = 300000000, .max = 600000000 },
> > > +};
> > [...]
> > > +
> > > +}
> > > +
> > > +CLK_OF_DECLARE_DRIVER(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);
> > > -- 
> > 
> > Can't be platform device?
> > 
> 
> IIRC two clocks are used by the clocksource and having it as a platform
> device make the clocksource driver fail with -EPROBE_DEFER.
> 

Ok. I'll add a comment in the driver. It needs to be
CLK_OF_DECLARE_DRIVER() because it's used somewhere else too? Or it can
be CLK_OF_DECLARE() instead?

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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 20:58       ` Stephen Boyd
@ 2019-04-25 21:10         ` Alexandre Belloni
  2019-04-25 21:20           ` Stephen Boyd
  2019-04-25 21:14         ` Stephen Boyd
  1 sibling, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-25 21:10 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel

On 25/04/2019 13:58:10-0700, Stephen Boyd wrote:
> > IIRC two clocks are used by the clocksource and having it as a platform
> > device make the clocksource driver fail with -EPROBE_DEFER.
> > 
> 
> Ok. I'll add a comment in the driver. It needs to be
> CLK_OF_DECLARE_DRIVER() because it's used somewhere else too? Or it can
> be CLK_OF_DECLARE() instead?

It is coming from that comment:
https://lore.kernel.org/lkml/153573753043.93865.2420370848457480370@swboyd.mtv.corp.google.com/

Maybe I misinterpreted it.

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 20:58       ` Stephen Boyd
  2019-04-25 21:10         ` Alexandre Belloni
@ 2019-04-25 21:14         ` Stephen Boyd
  2019-04-26 20:52           ` Alexandre Belloni
  1 sibling, 1 reply; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 21:14 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Michael Turquette, linux-kernel, Claudiu Beznea, linux-clk,
	linux-arm-kernel

Quoting Stephen Boyd (2019-04-25 13:58:10)
> Quoting Alexandre Belloni (2019-04-25 13:31:39)
> > On 25/04/2019 12:38:55-0700, Stephen Boyd wrote:
> > > 
> > > const?
> > > 
> > 
> > Right, can you fix that up or should I send a new version?
> > 
> 
> I can fix it.

It's more complicated. I'll pile this patch on top. Maybe other
static data in drivers/clk/at91 can be const, but this at least covers
the struct clk_range ones.

diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
index b1af5a395423..0aabe49aed09 100644
--- a/drivers/clk/at91/at91sam9260.c
+++ b/drivers/clk/at91/at91sam9260.c
@@ -41,7 +41,7 @@ static u8 sam9260_plla_out[] = { 0, 2 };
 
 static u16 sam9260_plla_icpll[] = { 1, 1 };
 
-static struct clk_range sam9260_plla_outputs[] = {
+static const struct clk_range sam9260_plla_outputs[] = {
 	{ .min = 80000000, .max = 160000000 },
 	{ .min = 150000000, .max = 240000000 },
 };
@@ -58,7 +58,7 @@ static u8 sam9260_pllb_out[] = { 1 };
 
 static u16 sam9260_pllb_icpll[] = { 1 };
 
-static struct clk_range sam9260_pllb_outputs[] = {
+static const struct clk_range sam9260_pllb_outputs[] = {
 	{ .min = 70000000, .max = 130000000 },
 };
 
@@ -128,7 +128,7 @@ static u8 sam9g20_plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
 
 static u16 sam9g20_plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
 
-static struct clk_range sam9g20_plla_outputs[] = {
+static const struct clk_range sam9g20_plla_outputs[] = {
 	{ .min = 745000000, .max = 800000000 },
 	{ .min = 695000000, .max = 750000000 },
 	{ .min = 645000000, .max = 700000000 },
@@ -151,7 +151,7 @@ static u8 sam9g20_pllb_out[] = { 0 };
 
 static u16 sam9g20_pllb_icpll[] = { 0 };
 
-static struct clk_range sam9g20_pllb_outputs[] = {
+static const struct clk_range sam9g20_pllb_outputs[] = {
 	{ .min = 30000000, .max = 100000000 },
 };
 
@@ -182,7 +182,7 @@ static const struct clk_master_characteristics sam9261_mck_characteristics = {
 	.divisors = { 1, 2, 4, 0 },
 };
 
-static struct clk_range sam9261_plla_outputs[] = {
+static const struct clk_range sam9261_plla_outputs[] = {
 	{ .min = 80000000, .max = 200000000 },
 	{ .min = 190000000, .max = 240000000 },
 };
@@ -199,7 +199,7 @@ static u8 sam9261_pllb_out[] = { 1 };
 
 static u16 sam9261_pllb_icpll[] = { 1 };
 
-static struct clk_range sam9261_pllb_outputs[] = {
+static const struct clk_range sam9261_pllb_outputs[] = {
 	{ .min = 70000000, .max = 130000000 },
 };
 
@@ -262,7 +262,7 @@ static const struct clk_master_characteristics sam9263_mck_characteristics = {
 	.divisors = { 1, 2, 4, 0 },
 };
 
-static struct clk_range sam9263_pll_outputs[] = {
+static const struct clk_range sam9263_pll_outputs[] = {
 	{ .min = 80000000, .max = 200000000 },
 	{ .min = 190000000, .max = 240000000 },
 };
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
index 5aeef68b4bdd..0ac34cdaa106 100644
--- a/drivers/clk/at91/at91sam9rl.c
+++ b/drivers/clk/at91/at91sam9rl.c
@@ -14,7 +14,7 @@ static const struct clk_master_characteristics sam9rl_mck_characteristics = {
 
 static u8 sam9rl_plla_out[] = { 0, 2 };
 
-static struct clk_range sam9rl_plla_outputs[] = {
+static const struct clk_range sam9rl_plla_outputs[] = {
 	{ .min = 80000000, .max = 200000000 },
 	{ .min = 190000000, .max = 240000000 },
 };
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
index f5cfcbd85f10..0855f3a80cc7 100644
--- a/drivers/clk/at91/at91sam9x5.c
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -17,7 +17,7 @@ static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
 
 static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
 
-static struct clk_range plla_outputs[] = {
+static const struct clk_range plla_outputs[] = {
 	{ .min = 745000000, .max = 800000000 },
 	{ .min = 695000000, .max = 750000000 },
 	{ .min = 645000000, .max = 700000000 },
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index fb9e9c4cdc8d..775b77a433f5 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -66,7 +66,7 @@ extern const struct clk_pll_layout sama5d3_pll_layout;
 struct clk_pll_characteristics {
 	struct clk_range input;
 	int num_output;
-	struct clk_range *output;
+	const struct clk_range *output;
 	u16 *icpll;
 	u8 *out;
 	u8 upll : 1;
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index 864ac060aed6..6340b1fc1828 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -21,7 +21,7 @@ static const struct clk_master_layout sam9x60_master_layout = {
 	.offset = 0x28,
 };
 
-static struct clk_range plla_outputs[] = {
+static const struct clk_range plla_outputs[] = {
 	{ .min = 300000000, .max = 600000000 },
 };
 
@@ -31,7 +31,7 @@ static const struct clk_pll_characteristics plla_characteristics = {
 	.output = plla_outputs,
 };
 
-static struct clk_range upll_outputs[] = {
+static const struct clk_range upll_outputs[] = {
 	{ .min = 300000000, .max = 500000000 },
 };
 
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index 096156850e08..f3d3f6c8e261 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -16,7 +16,7 @@ static u8 plla_out[] = { 0 };
 
 static u16 plla_icpll[] = { 0 };
 
-static struct clk_range plla_outputs[] = {
+static const struct clk_range plla_outputs[] = {
 	{ .min = 600000000, .max = 1200000000 },
 };
 
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
index 840edca77821..25b156d4e645 100644
--- a/drivers/clk/at91/sama5d4.c
+++ b/drivers/clk/at91/sama5d4.c
@@ -16,7 +16,7 @@ static u8 plla_out[] = { 0 };
 
 static u16 plla_icpll[] = { 0 };
 
-static struct clk_range plla_outputs[] = {
+static const struct clk_range plla_outputs[] = {
 	{ .min = 600000000, .max = 1200000000 },
 };
 

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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 21:10         ` Alexandre Belloni
@ 2019-04-25 21:20           ` Stephen Boyd
  2019-04-26 21:06             ` Alexandre Belloni
  0 siblings, 1 reply; 23+ messages in thread
From: Stephen Boyd @ 2019-04-25 21:20 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel

Quoting Alexandre Belloni (2019-04-25 14:10:09)
> On 25/04/2019 13:58:10-0700, Stephen Boyd wrote:
> > > IIRC two clocks are used by the clocksource and having it as a platform
> > > device make the clocksource driver fail with -EPROBE_DEFER.
> > > 
> > 
> > Ok. I'll add a comment in the driver. It needs to be
> > CLK_OF_DECLARE_DRIVER() because it's used somewhere else too? Or it can
> > be CLK_OF_DECLARE() instead?
> 
> It is coming from that comment:
> https://lore.kernel.org/lkml/153573753043.93865.2420370848457480370@swboyd.mtv.corp.google.com/
> 
> Maybe I misinterpreted it.
> 

Hmm I was just confused it seems. If you don't have two devices probing
the same DT node with this compatible string then I think it can just be
CLK_OF_DECLARE(). I was thinking that you were running into some sort of
issue where the other driver using this same compatible couldn't probe.


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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 21:14         ` Stephen Boyd
@ 2019-04-26 20:52           ` Alexandre Belloni
  0 siblings, 0 replies; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-26 20:52 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Michael Turquette, linux-kernel, Claudiu Beznea, linux-clk,
	linux-arm-kernel

On 25/04/2019 14:14:54-0700, Stephen Boyd wrote:
> Quoting Stephen Boyd (2019-04-25 13:58:10)
> > Quoting Alexandre Belloni (2019-04-25 13:31:39)
> > > On 25/04/2019 12:38:55-0700, Stephen Boyd wrote:
> > > > 
> > > > const?
> > > > 
> > > 
> > > Right, can you fix that up or should I send a new version?
> > > 
> > 
> > I can fix it.
> 
> It's more complicated. I'll pile this patch on top. Maybe other
> static data in drivers/clk/at91 can be const, but this at least covers
> the struct clk_range ones.
> 

Seems good to me.

> diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
> index b1af5a395423..0aabe49aed09 100644
> --- a/drivers/clk/at91/at91sam9260.c
> +++ b/drivers/clk/at91/at91sam9260.c
> @@ -41,7 +41,7 @@ static u8 sam9260_plla_out[] = { 0, 2 };
>  
>  static u16 sam9260_plla_icpll[] = { 1, 1 };
>  
> -static struct clk_range sam9260_plla_outputs[] = {
> +static const struct clk_range sam9260_plla_outputs[] = {
>  	{ .min = 80000000, .max = 160000000 },
>  	{ .min = 150000000, .max = 240000000 },
>  };
> @@ -58,7 +58,7 @@ static u8 sam9260_pllb_out[] = { 1 };
>  
>  static u16 sam9260_pllb_icpll[] = { 1 };
>  
> -static struct clk_range sam9260_pllb_outputs[] = {
> +static const struct clk_range sam9260_pllb_outputs[] = {
>  	{ .min = 70000000, .max = 130000000 },
>  };
>  
> @@ -128,7 +128,7 @@ static u8 sam9g20_plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
>  
>  static u16 sam9g20_plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
>  
> -static struct clk_range sam9g20_plla_outputs[] = {
> +static const struct clk_range sam9g20_plla_outputs[] = {
>  	{ .min = 745000000, .max = 800000000 },
>  	{ .min = 695000000, .max = 750000000 },
>  	{ .min = 645000000, .max = 700000000 },
> @@ -151,7 +151,7 @@ static u8 sam9g20_pllb_out[] = { 0 };
>  
>  static u16 sam9g20_pllb_icpll[] = { 0 };
>  
> -static struct clk_range sam9g20_pllb_outputs[] = {
> +static const struct clk_range sam9g20_pllb_outputs[] = {
>  	{ .min = 30000000, .max = 100000000 },
>  };
>  
> @@ -182,7 +182,7 @@ static const struct clk_master_characteristics sam9261_mck_characteristics = {
>  	.divisors = { 1, 2, 4, 0 },
>  };
>  
> -static struct clk_range sam9261_plla_outputs[] = {
> +static const struct clk_range sam9261_plla_outputs[] = {
>  	{ .min = 80000000, .max = 200000000 },
>  	{ .min = 190000000, .max = 240000000 },
>  };
> @@ -199,7 +199,7 @@ static u8 sam9261_pllb_out[] = { 1 };
>  
>  static u16 sam9261_pllb_icpll[] = { 1 };
>  
> -static struct clk_range sam9261_pllb_outputs[] = {
> +static const struct clk_range sam9261_pllb_outputs[] = {
>  	{ .min = 70000000, .max = 130000000 },
>  };
>  
> @@ -262,7 +262,7 @@ static const struct clk_master_characteristics sam9263_mck_characteristics = {
>  	.divisors = { 1, 2, 4, 0 },
>  };
>  
> -static struct clk_range sam9263_pll_outputs[] = {
> +static const struct clk_range sam9263_pll_outputs[] = {
>  	{ .min = 80000000, .max = 200000000 },
>  	{ .min = 190000000, .max = 240000000 },
>  };
> diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
> index 5aeef68b4bdd..0ac34cdaa106 100644
> --- a/drivers/clk/at91/at91sam9rl.c
> +++ b/drivers/clk/at91/at91sam9rl.c
> @@ -14,7 +14,7 @@ static const struct clk_master_characteristics sam9rl_mck_characteristics = {
>  
>  static u8 sam9rl_plla_out[] = { 0, 2 };
>  
> -static struct clk_range sam9rl_plla_outputs[] = {
> +static const struct clk_range sam9rl_plla_outputs[] = {
>  	{ .min = 80000000, .max = 200000000 },
>  	{ .min = 190000000, .max = 240000000 },
>  };
> diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
> index f5cfcbd85f10..0855f3a80cc7 100644
> --- a/drivers/clk/at91/at91sam9x5.c
> +++ b/drivers/clk/at91/at91sam9x5.c
> @@ -17,7 +17,7 @@ static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
>  
>  static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
>  
> -static struct clk_range plla_outputs[] = {
> +static const struct clk_range plla_outputs[] = {
>  	{ .min = 745000000, .max = 800000000 },
>  	{ .min = 695000000, .max = 750000000 },
>  	{ .min = 645000000, .max = 700000000 },
> diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
> index fb9e9c4cdc8d..775b77a433f5 100644
> --- a/drivers/clk/at91/pmc.h
> +++ b/drivers/clk/at91/pmc.h
> @@ -66,7 +66,7 @@ extern const struct clk_pll_layout sama5d3_pll_layout;
>  struct clk_pll_characteristics {
>  	struct clk_range input;
>  	int num_output;
> -	struct clk_range *output;
> +	const struct clk_range *output;
>  	u16 *icpll;
>  	u8 *out;
>  	u8 upll : 1;
> diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
> index 864ac060aed6..6340b1fc1828 100644
> --- a/drivers/clk/at91/sam9x60.c
> +++ b/drivers/clk/at91/sam9x60.c
> @@ -21,7 +21,7 @@ static const struct clk_master_layout sam9x60_master_layout = {
>  	.offset = 0x28,
>  };
>  
> -static struct clk_range plla_outputs[] = {
> +static const struct clk_range plla_outputs[] = {
>  	{ .min = 300000000, .max = 600000000 },
>  };
>  
> @@ -31,7 +31,7 @@ static const struct clk_pll_characteristics plla_characteristics = {
>  	.output = plla_outputs,
>  };
>  
> -static struct clk_range upll_outputs[] = {
> +static const struct clk_range upll_outputs[] = {
>  	{ .min = 300000000, .max = 500000000 },
>  };
>  
> diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
> index 096156850e08..f3d3f6c8e261 100644
> --- a/drivers/clk/at91/sama5d2.c
> +++ b/drivers/clk/at91/sama5d2.c
> @@ -16,7 +16,7 @@ static u8 plla_out[] = { 0 };
>  
>  static u16 plla_icpll[] = { 0 };
>  
> -static struct clk_range plla_outputs[] = {
> +static const struct clk_range plla_outputs[] = {
>  	{ .min = 600000000, .max = 1200000000 },
>  };
>  
> diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
> index 840edca77821..25b156d4e645 100644
> --- a/drivers/clk/at91/sama5d4.c
> +++ b/drivers/clk/at91/sama5d4.c
> @@ -16,7 +16,7 @@ static u8 plla_out[] = { 0 };
>  
>  static u16 plla_icpll[] = { 0 };
>  
> -static struct clk_range plla_outputs[] = {
> +static const struct clk_range plla_outputs[] = {
>  	{ .min = 600000000, .max = 1200000000 },
>  };
>  

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-25 21:20           ` Stephen Boyd
@ 2019-04-26 21:06             ` Alexandre Belloni
  2019-04-26 22:02               ` Stephen Boyd
  0 siblings, 1 reply; 23+ messages in thread
From: Alexandre Belloni @ 2019-04-26 21:06 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel

On 25/04/2019 14:20:41-0700, Stephen Boyd wrote:
> Quoting Alexandre Belloni (2019-04-25 14:10:09)
> > On 25/04/2019 13:58:10-0700, Stephen Boyd wrote:
> > > > IIRC two clocks are used by the clocksource and having it as a platform
> > > > device make the clocksource driver fail with -EPROBE_DEFER.
> > > > 
> > > 
> > > Ok. I'll add a comment in the driver. It needs to be
> > > CLK_OF_DECLARE_DRIVER() because it's used somewhere else too? Or it can
> > > be CLK_OF_DECLARE() instead?
> > 
> > It is coming from that comment:
> > https://lore.kernel.org/lkml/153573753043.93865.2420370848457480370@swboyd.mtv.corp.google.com/
> > 
> > Maybe I misinterpreted it.
> > 
> 
> Hmm I was just confused it seems. If you don't have two devices probing
> the same DT node with this compatible string then I think it can just be
> CLK_OF_DECLARE(). I was thinking that you were running into some sort of
> issue where the other driver using this same compatible couldn't probe.
> 

I tried separating it into two initializations and do as much as
possible in the platform driver but because the TCB clocks are
peripheral clocks that depend on most of the other ones, I didn't find
it convenient. This can safely be changed to CLK_OF_DECLARE. I can send
v4 if you want. This should probably be changed for the other drivers
too.


-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver
  2019-04-26 21:06             ` Alexandre Belloni
@ 2019-04-26 22:02               ` Stephen Boyd
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Boyd @ 2019-04-26 22:02 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Claudiu Beznea, Michael Turquette, linux-clk,
	linux-arm-kernel, linux-kernel

Quoting Alexandre Belloni (2019-04-26 14:06:51)
> On 25/04/2019 14:20:41-0700, Stephen Boyd wrote:
> > 
> > Hmm I was just confused it seems. If you don't have two devices probing
> > the same DT node with this compatible string then I think it can just be
> > CLK_OF_DECLARE(). I was thinking that you were running into some sort of
> > issue where the other driver using this same compatible couldn't probe.
> > 
> 
> I tried separating it into two initializations and do as much as
> possible in the platform driver but because the TCB clocks are
> peripheral clocks that depend on most of the other ones, I didn't find
> it convenient. This can safely be changed to CLK_OF_DECLARE. I can send
> v4 if you want. This should probably be changed for the other drivers
> too.

I've fixed it locally, just haven't pushed it out. If you have other
drivers that should be using CLK_OF_DECLARE then feel free to send a
patch for it.


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

end of thread, other threads:[~2019-04-26 22:03 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-02 12:50 [PATCH v3 0/7] clk: at91: add sam9x60 pmc clock support Alexandre Belloni
2019-04-02 12:50 ` [PATCH v3 1/7] clk: at91: allow configuring peripheral PCR layout Alexandre Belloni
2019-04-25 19:36   ` Stephen Boyd
2019-04-02 12:50 ` [PATCH v3 2/7] clk: at91: allow configuring generated " Alexandre Belloni
2019-04-25 19:37   ` Stephen Boyd
2019-04-02 12:50 ` [PATCH v3 3/7] clk: at91: usb: Add sam9x60 support Alexandre Belloni
2019-04-25 19:37   ` Stephen Boyd
2019-04-02 12:50 ` [PATCH v3 4/7] clk: at91: master: " Alexandre Belloni
2019-04-25 19:37   ` Stephen Boyd
2019-04-02 12:50 ` [PATCH v3 5/7] clk: at91: add sam9x60 PLL driver Alexandre Belloni
2019-04-25 19:37   ` Stephen Boyd
2019-04-02 12:50 ` [PATCH v3 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc Alexandre Belloni
2019-04-25 19:37   ` Stephen Boyd
2019-04-02 12:50 ` [PATCH v3 7/7] clk: at91: add sam9x60 pmc driver Alexandre Belloni
2019-04-25 19:38   ` Stephen Boyd
2019-04-25 20:31     ` Alexandre Belloni
2019-04-25 20:58       ` Stephen Boyd
2019-04-25 21:10         ` Alexandre Belloni
2019-04-25 21:20           ` Stephen Boyd
2019-04-26 21:06             ` Alexandre Belloni
2019-04-26 22:02               ` Stephen Boyd
2019-04-25 21:14         ` Stephen Boyd
2019-04-26 20:52           ` Alexandre Belloni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).