diff mbox series

[v3,7/7] clk: at91: add sam9x60 pmc driver

Message ID 20190402125056.21509-8-alexandre.belloni@bootlin.com (mailing list archive)
State New, archived
Headers show
Series clk: at91: add sam9x60 pmc clock support | expand

Commit Message

Alexandre Belloni April 2, 2019, 12:50 p.m. UTC
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

Comments

Stephen Boyd April 25, 2019, 7:38 p.m. UTC | #1
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?
Alexandre Belloni April 25, 2019, 8:31 p.m. UTC | #2
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.
Stephen Boyd April 25, 2019, 8:58 p.m. UTC | #3
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?
Alexandre Belloni April 25, 2019, 9:10 p.m. UTC | #4
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.
Stephen Boyd April 25, 2019, 9:14 p.m. UTC | #5
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 },
 };
Stephen Boyd April 25, 2019, 9:20 p.m. UTC | #6
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.
Alexandre Belloni April 26, 2019, 8:52 p.m. UTC | #7
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 April 26, 2019, 9:06 p.m. UTC | #8
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.
Stephen Boyd April 26, 2019, 10:02 p.m. UTC | #9
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.
diff mbox series

Patch

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);