* [PATCH v3 0/9] at91: Support PMC clock bindings
@ 2019-02-18 19:47 Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 1/9] arm: at91: fix at91_configure_usart6 warning Sam Ravnborg
` (8 more replies)
0 siblings, 9 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
The following patchset add supports for the PMC clk
bindings for at91.
The patchset was tested on:
- at91sam9264ek - DT enabled
- sama5d4-xplained - non DT
The patchset includes sama5d2.c which is not used today.
I have a sama5d27-som1-ek board that I hope to find time to work
with and then this will be needed.
Patch was made on top of:
12cd92023788fdc67ad72c6e7d96251a6234ca3e ("Merge branch 'for-next/rpi' into next")
One stray patch sneaked in - to kill a warning.
The patchset triggers some checkpatch warnings:
- SPDX, the barebox variant of checkpatch is missing support for these (anyone?)
- Too long lines. As code is copied from the kernel I left them as-is
Comments/testing very welcome!
v3:
- Fixed build breakage in sama5d4 and clk-h32mx
- Added Tested-by: Ladislav Michl <ladis@linux-mips.org> to relevant patches
v2:
- Split up in smaller patches
- Fix builds in various configs
- Reworked Kconfig changes
- Fix checkpatch warnings (mostly whitespace)
v1:
- Posted to mailing list as a WIP patch
Sam
Sam Ravnborg (9):
arm: at91: fix at91_configure_usart6 warning
clocksource: Do not mix depends and select for ATMEL_PIT
arm: at91: add SOC_SAMA5{D3,D4}
clk: at91: add at91sam9260
clk: at91: add at91sam9rl
clk: at91: add at91sam9x5
clk: at91: add sama5d2
clk: at91: add sama5d4
clk: at91: update to PMC bindings
arch/arm/mach-at91/Kconfig | 31 +-
arch/arm/mach-at91/include/mach/board.h | 1 +
drivers/clk/at91/Makefile | 5 +
drivers/clk/at91/at91sam9260.c | 497 ++++++++++++++++++++++++++++++++
drivers/clk/at91/at91sam9rl.c | 177 ++++++++++++
drivers/clk/at91/at91sam9x5.c | 315 ++++++++++++++++++++
drivers/clk/at91/clk-generated.c | 185 ++----------
drivers/clk/at91/clk-h32mx.c | 55 ++--
drivers/clk/at91/clk-main.c | 112 +------
drivers/clk/at91/clk-master.c | 94 +-----
drivers/clk/at91/clk-peripheral.c | 82 +-----
drivers/clk/at91/clk-pll.c | 174 +----------
drivers/clk/at91/clk-plldiv.c | 27 +-
drivers/clk/at91/clk-programmable.c | 83 +-----
drivers/clk/at91/clk-slow.c | 33 +--
drivers/clk/at91/clk-smd.c | 33 +--
drivers/clk/at91/clk-system.c | 42 +--
drivers/clk/at91/clk-usb.c | 94 +-----
drivers/clk/at91/clk-utmi.c | 100 ++++---
drivers/clk/at91/pmc.c | 248 ++++++++++++++++
drivers/clk/at91/pmc.h | 169 +++++++++++
drivers/clk/at91/sama5d2.c | 342 ++++++++++++++++++++++
drivers/clk/at91/sama5d4.c | 270 +++++++++++++++++
drivers/clocksource/Kconfig | 1 -
include/linux/clk.h | 7 +
include/soc/at91/atmel-sfr.h | 34 +++
26 files changed, 2233 insertions(+), 978 deletions(-)
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 1/9] arm: at91: fix at91_configure_usart6 warning
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 2/9] clocksource: Do not mix depends and select for ATMEL_PIT Sam Ravnborg
` (7 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Add declaration to silence following warning:
arch/arm/mach-at91/sama5d4_devices.c:487:24:
warning: no previous prototype for ‘at91_configure_usart6’
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
arch/arm/mach-at91/include/mach/board.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 886f81e9a..4c4b51180 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -102,6 +102,7 @@ resource_size_t __init at91_configure_usart2(unsigned pins);
resource_size_t __init at91_configure_usart3(unsigned pins);
resource_size_t __init at91_configure_usart4(unsigned pins);
resource_size_t __init at91_configure_usart5(unsigned pins);
+resource_size_t __init at91_configure_usart6(unsigned pins);
#if defined(CONFIG_DRIVER_SERIAL_ATMEL)
static inline struct device_d * at91_register_uart(unsigned id, unsigned pins)
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 2/9] clocksource: Do not mix depends and select for ATMEL_PIT
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 1/9] arm: at91: fix at91_configure_usart6 warning Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 3/9] arm: at91: add SOC_SAMA5{D3,D4} Sam Ravnborg
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
CLOCKSOURCE_ATMEL_PIT was both set to yes using depends on
and using select.
Use only select to set this non-visible symbol to 'y'
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
drivers/clocksource/Kconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 7b04663d2..b0502c303 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -69,7 +69,6 @@ config CLOCKSOURCE_ROCKCHIP
config CLOCKSOURCE_ATMEL_PIT
bool
- depends on SOC_AT91SAM9 || SOC_SAMA5
config CLOCKSOURCE_ARMV8_TIMER
bool
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 3/9] arm: at91: add SOC_SAMA5{D3,D4}
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 1/9] arm: at91: fix at91_configure_usart6 warning Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 2/9] clocksource: Do not mix depends and select for ATMEL_PIT Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 4/9] clk: at91: add at91sam9260 Sam Ravnborg
` (5 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
This split allows us to distingush between the two SOC
types.
The SOC_SAMA5D3 and SOC_SAMA5D4 symbols will be used in
following patches.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/arm/mach-at91/Kconfig | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index b101e61d2..a2737a367 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -57,6 +57,16 @@ config SOC_AT91SAM9
config SOC_SAMA5
bool
select CPU_V7
+
+config SOC_SAMA5D3
+ bool
+ select SOC_SAMA5
+ select AT91SAM9_SMC
+ select CLOCKSOURCE_ATMEL_PIT
+
+config SOC_SAMA5D4
+ bool
+ select SOC_SAMA5
select AT91SAM9_SMC
select CLOCKSOURCE_ATMEL_PIT
@@ -188,14 +198,14 @@ config ARCH_AT91SAM9N12
config ARCH_SAMA5D3
bool "SAMA5D3x"
- select SOC_SAMA5
+ select SOC_SAMA5D3
select HAVE_AT91_DBGU1
select HAS_MACB
select HAVE_MACH_ARM_HEAD
config ARCH_SAMA5D4
bool "SAMA5D4"
- select SOC_SAMA5
+ select SOC_SAMA5D4
select HAVE_AT91_DBGU2
select HAS_MACB
select HAVE_MACH_ARM_HEAD
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 4/9] clk: at91: add at91sam9260
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
` (2 preceding siblings ...)
2019-02-18 19:47 ` [PATCH v3 3/9] arm: at91: add SOC_SAMA5{D3,D4} Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 5/9] clk: at91: add at91sam9rl Sam Ravnborg
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Add at91sam9260 as part of supporting the PMC bindings for ARM at91.
The file will be wired into the build in a follow-up patch.
The file is a copy from kernel 5.0-rc6 modified to build
with barebox.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
drivers/clk/at91/at91sam9260.c | 497 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 497 insertions(+)
create mode 100644 drivers/clk/at91/at91sam9260.c
diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c
new file mode 100644
index 000000000..ac67dcc8f
--- /dev/null
+++ b/drivers/clk/at91/at91sam9260.c
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <driver.h>
+#include <regmap.h>
+#include <stdio.h>
+#include <mfd/syscon.h>
+
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+struct sck {
+ char *n;
+ char *p;
+ u8 id;
+};
+
+struct pck {
+ char *n;
+ u8 id;
+};
+
+struct at91sam926x_data {
+ const struct clk_pll_layout *plla_layout;
+ const struct clk_pll_characteristics *plla_characteristics;
+ const struct clk_pll_layout *pllb_layout;
+ const struct clk_pll_characteristics *pllb_characteristics;
+ const struct clk_master_characteristics *mck_characteristics;
+ const struct sck *sck;
+ const struct pck *pck;
+ u8 num_sck;
+ u8 num_pck;
+ u8 num_progck;
+ bool has_slck;
+};
+
+static const struct clk_master_characteristics sam9260_mck_characteristics = {
+ .output = { .min = 0, .max = 105000000 },
+ .divisors = { 1, 2, 4, 0 },
+};
+
+static u8 sam9260_plla_out[] = { 0, 2 };
+
+static u16 sam9260_plla_icpll[] = { 1, 1 };
+
+static struct clk_range sam9260_plla_outputs[] = {
+ { .min = 80000000, .max = 160000000 },
+ { .min = 150000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9260_plla_characteristics = {
+ .input = { .min = 1000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(sam9260_plla_outputs),
+ .output = sam9260_plla_outputs,
+ .icpll = sam9260_plla_icpll,
+ .out = sam9260_plla_out,
+};
+
+static u8 sam9260_pllb_out[] = { 1 };
+
+static u16 sam9260_pllb_icpll[] = { 1 };
+
+static struct clk_range sam9260_pllb_outputs[] = {
+ { .min = 70000000, .max = 130000000 },
+};
+
+static const struct clk_pll_characteristics sam9260_pllb_characteristics = {
+ .input = { .min = 1000000, .max = 5000000 },
+ .num_output = ARRAY_SIZE(sam9260_pllb_outputs),
+ .output = sam9260_pllb_outputs,
+ .icpll = sam9260_pllb_icpll,
+ .out = sam9260_pllb_out,
+};
+
+static const struct sck at91sam9260_systemck[] = {
+ { .n = "uhpck", .p = "usbck", .id = 6 },
+ { .n = "udpck", .p = "usbck", .id = 7 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+};
+
+static const struct pck at91sam9260_periphck[] = {
+ { .n = "pioA_clk", .id = 2 },
+ { .n = "pioB_clk", .id = 3 },
+ { .n = "pioC_clk", .id = 4 },
+ { .n = "adc_clk", .id = 5 },
+ { .n = "usart0_clk", .id = 6 },
+ { .n = "usart1_clk", .id = 7 },
+ { .n = "usart2_clk", .id = 8 },
+ { .n = "mci0_clk", .id = 9 },
+ { .n = "udc_clk", .id = 10 },
+ { .n = "twi0_clk", .id = 11 },
+ { .n = "spi0_clk", .id = 12 },
+ { .n = "spi1_clk", .id = 13 },
+ { .n = "ssc0_clk", .id = 14 },
+ { .n = "tc0_clk", .id = 17 },
+ { .n = "tc1_clk", .id = 18 },
+ { .n = "tc2_clk", .id = 19 },
+ { .n = "ohci_clk", .id = 20 },
+ { .n = "macb0_clk", .id = 21 },
+ { .n = "isi_clk", .id = 22 },
+ { .n = "usart3_clk", .id = 23 },
+ { .n = "uart0_clk", .id = 24 },
+ { .n = "uart1_clk", .id = 25 },
+ { .n = "tc3_clk", .id = 26 },
+ { .n = "tc4_clk", .id = 27 },
+ { .n = "tc5_clk", .id = 28 },
+};
+
+static struct at91sam926x_data at91sam9260_data = {
+ .plla_layout = &at91rm9200_pll_layout,
+ .plla_characteristics = &sam9260_plla_characteristics,
+ .pllb_layout = &at91rm9200_pll_layout,
+ .pllb_characteristics = &sam9260_pllb_characteristics,
+ .mck_characteristics = &sam9260_mck_characteristics,
+ .sck = at91sam9260_systemck,
+ .num_sck = ARRAY_SIZE(at91sam9260_systemck),
+ .pck = at91sam9260_periphck,
+ .num_pck = ARRAY_SIZE(at91sam9260_periphck),
+ .num_progck = 2,
+ .has_slck = true,
+};
+
+static const struct clk_master_characteristics sam9g20_mck_characteristics = {
+ .output = { .min = 0, .max = 133000000 },
+ .divisors = { 1, 2, 4, 6 },
+};
+
+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[] = {
+ { .min = 745000000, .max = 800000000 },
+ { .min = 695000000, .max = 750000000 },
+ { .min = 645000000, .max = 700000000 },
+ { .min = 595000000, .max = 650000000 },
+ { .min = 545000000, .max = 600000000 },
+ { .min = 495000000, .max = 550000000 },
+ { .min = 445000000, .max = 500000000 },
+ { .min = 400000000, .max = 450000000 },
+};
+
+static const struct clk_pll_characteristics sam9g20_plla_characteristics = {
+ .input = { .min = 2000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(sam9g20_plla_outputs),
+ .output = sam9g20_plla_outputs,
+ .icpll = sam9g20_plla_icpll,
+ .out = sam9g20_plla_out,
+};
+
+static u8 sam9g20_pllb_out[] = { 0 };
+
+static u16 sam9g20_pllb_icpll[] = { 0 };
+
+static struct clk_range sam9g20_pllb_outputs[] = {
+ { .min = 30000000, .max = 100000000 },
+};
+
+static const struct clk_pll_characteristics sam9g20_pllb_characteristics = {
+ .input = { .min = 2000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(sam9g20_pllb_outputs),
+ .output = sam9g20_pllb_outputs,
+ .icpll = sam9g20_pllb_icpll,
+ .out = sam9g20_pllb_out,
+};
+
+static struct at91sam926x_data at91sam9g20_data = {
+ .plla_layout = &at91sam9g45_pll_layout,
+ .plla_characteristics = &sam9g20_plla_characteristics,
+ .pllb_layout = &at91sam9g20_pllb_layout,
+ .pllb_characteristics = &sam9g20_pllb_characteristics,
+ .mck_characteristics = &sam9g20_mck_characteristics,
+ .sck = at91sam9260_systemck,
+ .num_sck = ARRAY_SIZE(at91sam9260_systemck),
+ .pck = at91sam9260_periphck,
+ .num_pck = ARRAY_SIZE(at91sam9260_periphck),
+ .num_progck = 2,
+ .has_slck = true,
+};
+
+static const struct clk_master_characteristics sam9261_mck_characteristics = {
+ .output = { .min = 0, .max = 94000000 },
+ .divisors = { 1, 2, 4, 0 },
+};
+
+static struct clk_range sam9261_plla_outputs[] = {
+ { .min = 80000000, .max = 200000000 },
+ { .min = 190000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9261_plla_characteristics = {
+ .input = { .min = 1000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(sam9261_plla_outputs),
+ .output = sam9261_plla_outputs,
+ .icpll = sam9260_plla_icpll,
+ .out = sam9260_plla_out,
+};
+
+static u8 sam9261_pllb_out[] = { 1 };
+
+static u16 sam9261_pllb_icpll[] = { 1 };
+
+static struct clk_range sam9261_pllb_outputs[] = {
+ { .min = 70000000, .max = 130000000 },
+};
+
+static const struct clk_pll_characteristics sam9261_pllb_characteristics = {
+ .input = { .min = 1000000, .max = 5000000 },
+ .num_output = ARRAY_SIZE(sam9261_pllb_outputs),
+ .output = sam9261_pllb_outputs,
+ .icpll = sam9261_pllb_icpll,
+ .out = sam9261_pllb_out,
+};
+
+static const struct sck at91sam9261_systemck[] = {
+ { .n = "uhpck", .p = "usbck", .id = 6 },
+ { .n = "udpck", .p = "usbck", .id = 7 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+ { .n = "pck2", .p = "prog2", .id = 10 },
+ { .n = "pck3", .p = "prog3", .id = 11 },
+ { .n = "hclk0", .p = "masterck", .id = 16 },
+ { .n = "hclk1", .p = "masterck", .id = 17 },
+};
+
+static const struct pck at91sam9261_periphck[] = {
+ { .n = "pioA_clk", .id = 2, },
+ { .n = "pioB_clk", .id = 3, },
+ { .n = "pioC_clk", .id = 4, },
+ { .n = "usart0_clk", .id = 6, },
+ { .n = "usart1_clk", .id = 7, },
+ { .n = "usart2_clk", .id = 8, },
+ { .n = "mci0_clk", .id = 9, },
+ { .n = "udc_clk", .id = 10, },
+ { .n = "twi0_clk", .id = 11, },
+ { .n = "spi0_clk", .id = 12, },
+ { .n = "spi1_clk", .id = 13, },
+ { .n = "ssc0_clk", .id = 14, },
+ { .n = "ssc1_clk", .id = 15, },
+ { .n = "ssc2_clk", .id = 16, },
+ { .n = "tc0_clk", .id = 17, },
+ { .n = "tc1_clk", .id = 18, },
+ { .n = "tc2_clk", .id = 19, },
+ { .n = "ohci_clk", .id = 20, },
+ { .n = "lcd_clk", .id = 21, },
+};
+
+static struct at91sam926x_data at91sam9261_data = {
+ .plla_layout = &at91rm9200_pll_layout,
+ .plla_characteristics = &sam9261_plla_characteristics,
+ .pllb_layout = &at91rm9200_pll_layout,
+ .pllb_characteristics = &sam9261_pllb_characteristics,
+ .mck_characteristics = &sam9261_mck_characteristics,
+ .sck = at91sam9261_systemck,
+ .num_sck = ARRAY_SIZE(at91sam9261_systemck),
+ .pck = at91sam9261_periphck,
+ .num_pck = ARRAY_SIZE(at91sam9261_periphck),
+ .num_progck = 4,
+};
+
+static const struct clk_master_characteristics sam9263_mck_characteristics = {
+ .output = { .min = 0, .max = 120000000 },
+ .divisors = { 1, 2, 4, 0 },
+};
+
+static struct clk_range sam9263_pll_outputs[] = {
+ { .min = 80000000, .max = 200000000 },
+ { .min = 190000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9263_pll_characteristics = {
+ .input = { .min = 1000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(sam9263_pll_outputs),
+ .output = sam9263_pll_outputs,
+ .icpll = sam9260_plla_icpll,
+ .out = sam9260_plla_out,
+};
+
+static const struct sck at91sam9263_systemck[] = {
+ { .n = "uhpck", .p = "usbck", .id = 6 },
+ { .n = "udpck", .p = "usbck", .id = 7 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+ { .n = "pck2", .p = "prog2", .id = 10 },
+ { .n = "pck3", .p = "prog3", .id = 11 },
+};
+
+static const struct pck at91sam9263_periphck[] = {
+ { .n = "pioA_clk", .id = 2, },
+ { .n = "pioB_clk", .id = 3, },
+ { .n = "pioCDE_clk", .id = 4, },
+ { .n = "usart0_clk", .id = 7, },
+ { .n = "usart1_clk", .id = 8, },
+ { .n = "usart2_clk", .id = 9, },
+ { .n = "mci0_clk", .id = 10, },
+ { .n = "mci1_clk", .id = 11, },
+ { .n = "can_clk", .id = 12, },
+ { .n = "twi0_clk", .id = 13, },
+ { .n = "spi0_clk", .id = 14, },
+ { .n = "spi1_clk", .id = 15, },
+ { .n = "ssc0_clk", .id = 16, },
+ { .n = "ssc1_clk", .id = 17, },
+ { .n = "ac97_clk", .id = 18, },
+ { .n = "tcb_clk", .id = 19, },
+ { .n = "pwm_clk", .id = 20, },
+ { .n = "macb0_clk", .id = 21, },
+ { .n = "g2de_clk", .id = 23, },
+ { .n = "udc_clk", .id = 24, },
+ { .n = "isi_clk", .id = 25, },
+ { .n = "lcd_clk", .id = 26, },
+ { .n = "dma_clk", .id = 27, },
+ { .n = "ohci_clk", .id = 29, },
+};
+
+static struct at91sam926x_data at91sam9263_data = {
+ .plla_layout = &at91rm9200_pll_layout,
+ .plla_characteristics = &sam9263_pll_characteristics,
+ .pllb_layout = &at91rm9200_pll_layout,
+ .pllb_characteristics = &sam9263_pll_characteristics,
+ .mck_characteristics = &sam9263_mck_characteristics,
+ .sck = at91sam9263_systemck,
+ .num_sck = ARRAY_SIZE(at91sam9263_systemck),
+ .pck = at91sam9263_periphck,
+ .num_pck = ARRAY_SIZE(at91sam9263_periphck),
+ .num_progck = 4,
+};
+
+static void __init at91sam926x_pmc_setup(struct device_node *np,
+ struct at91sam926x_data *data)
+{
+ const char *slowxtal_name, *mainxtal_name;
+ struct pmc_data *at91sam9260_pmc;
+ u32 usb_div[] = { 1, 2, 4, 0 };
+ const char *parent_names[6];
+ const char *slck_name;
+ struct regmap *regmap;
+ struct clk *hw;
+ int i;
+ bool bypass;
+
+ i = of_property_match_string(np, "clock-names", "slow_xtal");
+ if (i < 0)
+ return;
+
+ slowxtal_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;
+
+ at91sam9260_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ ndck(data->sck, data->num_sck),
+ ndck(data->pck, data->num_pck), 0);
+ if (!at91sam9260_pmc)
+ return;
+
+ 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;
+
+ hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9260_pmc->chws[PMC_MAIN] = hw;
+
+ if (data->has_slck) {
+ hw = clk_fixed("slow_rc_osc", 32768);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = "slow_rc_osc";
+ parent_names[1] = "slow_xtal";
+ hw = at91_clk_register_sam9260_slow(regmap, "slck",
+ parent_names, 2);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9260_pmc->chws[PMC_SLOW] = hw;
+ slck_name = "slck";
+ } else {
+ slck_name = slowxtal_name;
+ }
+
+ hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+ data->plla_layout,
+ data->plla_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
+ data->pllb_layout,
+ data->pllb_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "pllack";
+ parent_names[3] = "pllbck";
+ hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+ &at91rm9200_master_layout,
+ data->mck_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9260_pmc->chws[PMC_MCK] = hw;
+
+ hw = at91rm9200_clk_register_usb(regmap, "usbck", "pllbck", usb_div);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "pllack";
+ parent_names[3] = "pllbck";
+ for (i = 0; i < data->num_progck; i++) {
+ char *name;
+
+ name = xasprintf("prog%d", i);
+
+ hw = at91_clk_register_programmable(regmap, name,
+ parent_names, 4, i,
+ &at91rm9200_programmable_layout);
+ if (IS_ERR(hw))
+ goto err_free;
+ }
+
+ for (i = 0; i < data->num_sck; i++) {
+ hw = at91_clk_register_system(regmap, data->sck[i].n,
+ data->sck[i].p,
+ data->sck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9260_pmc->shws[data->sck[i].id] = hw;
+ }
+
+ for (i = 0; i < data->num_pck; i++) {
+ hw = at91_clk_register_peripheral(regmap,
+ data->pck[i].n,
+ "masterck",
+ data->pck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9260_pmc->phws[data->pck[i].id] = hw;
+ }
+
+ of_clk_add_provider(np, of_clk_hw_pmc_get, at91sam9260_pmc);
+
+ return;
+
+err_free:
+ pmc_data_free(at91sam9260_pmc);
+}
+
+static void __init at91sam9260_pmc_setup(struct device_node *np)
+{
+ at91sam926x_pmc_setup(np, &at91sam9260_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9260_pmc, "atmel,at91sam9260-pmc",
+ at91sam9260_pmc_setup);
+
+static void __init at91sam9261_pmc_setup(struct device_node *np)
+{
+ at91sam926x_pmc_setup(np, &at91sam9261_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9261_pmc, "atmel,at91sam9261-pmc",
+ at91sam9261_pmc_setup);
+
+static void __init at91sam9263_pmc_setup(struct device_node *np)
+{
+ at91sam926x_pmc_setup(np, &at91sam9263_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9263_pmc, "atmel,at91sam9263-pmc",
+ at91sam9263_pmc_setup);
+
+static void __init at91sam9g20_pmc_setup(struct device_node *np)
+{
+ at91sam926x_pmc_setup(np, &at91sam9g20_data);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g20_pmc, "atmel,at91sam9g20-pmc",
+ at91sam9g20_pmc_setup);
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 5/9] clk: at91: add at91sam9rl
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
` (3 preceding siblings ...)
2019-02-18 19:47 ` [PATCH v3 4/9] clk: at91: add at91sam9260 Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 6/9] clk: at91: add at91sam9x5 Sam Ravnborg
` (3 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Add at91sam9rl as part of supporting the PMC bindings for ARM at91.
The file will be wired into the build in a follow-up patch.
The file is a copy from kernel 5.0-rc6 modified to build
with barebox.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/clk/at91/at91sam9rl.c | 177 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 177 insertions(+)
create mode 100644 drivers/clk/at91/at91sam9rl.c
diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c
new file mode 100644
index 000000000..82acb3825
--- /dev/null
+++ b/drivers/clk/at91/at91sam9rl.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <driver.h>
+#include <regmap.h>
+#include <stdio.h>
+#include <mfd/syscon.h>
+
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics sam9rl_mck_characteristics = {
+ .output = { .min = 0, .max = 94000000 },
+ .divisors = { 1, 2, 4, 0 },
+};
+
+static u8 sam9rl_plla_out[] = { 0, 2 };
+
+static struct clk_range sam9rl_plla_outputs[] = {
+ { .min = 80000000, .max = 200000000 },
+ { .min = 190000000, .max = 240000000 },
+};
+
+static const struct clk_pll_characteristics sam9rl_plla_characteristics = {
+ .input = { .min = 1000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(sam9rl_plla_outputs),
+ .output = sam9rl_plla_outputs,
+ .out = sam9rl_plla_out,
+};
+
+static const struct {
+ char *n;
+ char *p;
+ u8 id;
+} at91sam9rl_systemck[] = {
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+};
+
+static const struct {
+ char *n;
+ u8 id;
+} at91sam9rl_periphck[] = {
+ { .n = "pioA_clk", .id = 2, },
+ { .n = "pioB_clk", .id = 3, },
+ { .n = "pioC_clk", .id = 4, },
+ { .n = "pioD_clk", .id = 5, },
+ { .n = "usart0_clk", .id = 6, },
+ { .n = "usart1_clk", .id = 7, },
+ { .n = "usart2_clk", .id = 8, },
+ { .n = "usart3_clk", .id = 9, },
+ { .n = "mci0_clk", .id = 10, },
+ { .n = "twi0_clk", .id = 11, },
+ { .n = "twi1_clk", .id = 12, },
+ { .n = "spi0_clk", .id = 13, },
+ { .n = "ssc0_clk", .id = 14, },
+ { .n = "ssc1_clk", .id = 15, },
+ { .n = "tc0_clk", .id = 16, },
+ { .n = "tc1_clk", .id = 17, },
+ { .n = "tc2_clk", .id = 18, },
+ { .n = "pwm_clk", .id = 19, },
+ { .n = "adc_clk", .id = 20, },
+ { .n = "dma0_clk", .id = 21, },
+ { .n = "udphs_clk", .id = 22, },
+ { .n = "lcd_clk", .id = 23, },
+};
+
+static void __init at91sam9rl_pmc_setup(struct device_node *np)
+{
+ const char *slck_name, *mainxtal_name;
+ struct pmc_data *at91sam9rl_pmc;
+ const char *parent_names[6];
+ struct regmap *regmap;
+ struct clk *hw;
+ int i;
+
+ i = of_property_match_string(np, "clock-names", "slow_clk");
+ if (i < 0)
+ return;
+
+ 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;
+
+ at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ nck(at91sam9rl_systemck),
+ nck(at91sam9rl_periphck), 0);
+ if (!at91sam9rl_pmc)
+ return;
+
+ hw = at91_clk_register_rm9200_main(regmap, "mainck", mainxtal_name);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9rl_pmc->chws[PMC_MAIN] = hw;
+
+ hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+ &at91rm9200_pll_layout,
+ &sam9rl_plla_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9rl_pmc->chws[PMC_UTMI] = hw;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "pllack";
+ parent_names[3] = "utmick";
+ hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+ &at91rm9200_master_layout,
+ &sam9rl_mck_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9rl_pmc->chws[PMC_MCK] = hw;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "pllack";
+ parent_names[3] = "utmick";
+ parent_names[4] = "masterck";
+ for (i = 0; i < 2; i++) {
+ char *name;
+
+ name = xasprintf("prog%d", i);
+
+ hw = at91_clk_register_programmable(regmap, name,
+ parent_names, 5, i,
+ &at91rm9200_programmable_layout);
+ if (IS_ERR(hw))
+ goto err_free;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
+ hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n,
+ at91sam9rl_systemck[i].p,
+ at91sam9rl_systemck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9rl_pmc->shws[at91sam9rl_systemck[i].id] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) {
+ hw = at91_clk_register_peripheral(regmap,
+ at91sam9rl_periphck[i].n,
+ "masterck",
+ at91sam9rl_periphck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9rl_pmc->phws[at91sam9rl_periphck[i].id] = hw;
+ }
+
+ of_clk_add_provider(np, of_clk_hw_pmc_get, at91sam9rl_pmc);
+
+ return;
+
+err_free:
+ pmc_data_free(at91sam9rl_pmc);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 6/9] clk: at91: add at91sam9x5
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
` (4 preceding siblings ...)
2019-02-18 19:47 ` [PATCH v3 5/9] clk: at91: add at91sam9rl Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 7/9] clk: at91: add sama5d2 Sam Ravnborg
` (2 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Add at91sam9x5 as part of supporting the PMC bindings for ARM at91.
The file will be wired into the build in a follow-up patch.
The file is a copy from kernel 5.0-rc6 modified to build
with barebox.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/clk/at91/at91sam9x5.c | 315 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 315 insertions(+)
create mode 100644 drivers/clk/at91/at91sam9x5.c
diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c
new file mode 100644
index 000000000..5e0aacfbf
--- /dev/null
+++ b/drivers/clk/at91/at91sam9x5.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <driver.h>
+#include <regmap.h>
+#include <stdio.h>
+#include <mfd/syscon.h>
+
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics mck_characteristics = {
+ .output = { .min = 0, .max = 133333333 },
+ .divisors = { 1, 2, 4, 3 },
+ .have_div3_pres = 1,
+};
+
+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[] = {
+ { .min = 745000000, .max = 800000000 },
+ { .min = 695000000, .max = 750000000 },
+ { .min = 645000000, .max = 700000000 },
+ { .min = 595000000, .max = 650000000 },
+ { .min = 545000000, .max = 600000000 },
+ { .min = 495000000, .max = 555000000 },
+ { .min = 445000000, .max = 500000000 },
+ { .min = 400000000, .max = 450000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+ .input = { .min = 2000000, .max = 32000000 },
+ .num_output = ARRAY_SIZE(plla_outputs),
+ .output = plla_outputs,
+ .icpll = plla_icpll,
+ .out = plla_out,
+};
+
+static const struct {
+ char *n;
+ char *p;
+ u8 id;
+} at91sam9x5_systemck[] = {
+ { .n = "ddrck", .p = "masterck", .id = 2 },
+ { .n = "smdck", .p = "smdclk", .id = 4 },
+ { .n = "uhpck", .p = "usbck", .id = 6 },
+ { .n = "udpck", .p = "usbck", .id = 7 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+};
+
+struct pck {
+ char *n;
+ u8 id;
+};
+
+static const struct pck at91sam9x5_periphck[] = {
+ { .n = "pioAB_clk", .id = 2, },
+ { .n = "pioCD_clk", .id = 3, },
+ { .n = "smd_clk", .id = 4, },
+ { .n = "usart0_clk", .id = 5, },
+ { .n = "usart1_clk", .id = 6, },
+ { .n = "usart2_clk", .id = 7, },
+ { .n = "twi0_clk", .id = 9, },
+ { .n = "twi1_clk", .id = 10, },
+ { .n = "twi2_clk", .id = 11, },
+ { .n = "mci0_clk", .id = 12, },
+ { .n = "spi0_clk", .id = 13, },
+ { .n = "spi1_clk", .id = 14, },
+ { .n = "uart0_clk", .id = 15, },
+ { .n = "uart1_clk", .id = 16, },
+ { .n = "tcb0_clk", .id = 17, },
+ { .n = "pwm_clk", .id = 18, },
+ { .n = "adc_clk", .id = 19, },
+ { .n = "dma0_clk", .id = 20, },
+ { .n = "dma1_clk", .id = 21, },
+ { .n = "uhphs_clk", .id = 22, },
+ { .n = "udphs_clk", .id = 23, },
+ { .n = "mci1_clk", .id = 26, },
+ { .n = "ssc0_clk", .id = 28, },
+};
+
+static const struct pck at91sam9g15_periphck[] = {
+ { .n = "lcdc_clk", .id = 25, },
+ { /* sentinel */}
+};
+
+static const struct pck at91sam9g25_periphck[] = {
+ { .n = "usart3_clk", .id = 8, },
+ { .n = "macb0_clk", .id = 24, },
+ { .n = "isi_clk", .id = 25, },
+ { /* sentinel */}
+};
+
+static const struct pck at91sam9g35_periphck[] = {
+ { .n = "macb0_clk", .id = 24, },
+ { .n = "lcdc_clk", .id = 25, },
+ { /* sentinel */}
+};
+
+static const struct pck at91sam9x25_periphck[] = {
+ { .n = "usart3_clk", .id = 8, },
+ { .n = "macb0_clk", .id = 24, },
+ { .n = "macb1_clk", .id = 27, },
+ { .n = "can0_clk", .id = 29, },
+ { .n = "can1_clk", .id = 30, },
+ { /* sentinel */}
+};
+
+static const struct pck at91sam9x35_periphck[] = {
+ { .n = "macb0_clk", .id = 24, },
+ { .n = "lcdc_clk", .id = 25, },
+ { .n = "can0_clk", .id = 29, },
+ { .n = "can1_clk", .id = 30, },
+ { /* sentinel */}
+};
+
+static void __init at91sam9x5_pmc_setup(struct device_node *np,
+ const struct pck *extra_pcks,
+ bool has_lcdck)
+{
+ struct clk_range range = CLK_RANGE(0, 0);
+ const char *slck_name, *mainxtal_name;
+ struct pmc_data *at91sam9x5_pmc;
+ const char *parent_names[6];
+ struct regmap *regmap;
+ struct clk *hw;
+ int i;
+ bool bypass;
+
+ i = of_property_match_string(np, "clock-names", "slow_clk");
+ if (i < 0)
+ return;
+
+ 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;
+
+ at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
+ nck(at91sam9x5_systemck),
+ nck(at91sam9x35_periphck), 0);
+ if (!at91sam9x5_pmc)
+ return;
+
+ hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+ 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;
+
+ at91sam9x5_pmc->chws[PMC_MAIN] = hw;
+
+ hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+ &at91rm9200_pll_layout, &plla_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9x5_pmc->chws[PMC_UTMI] = hw;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+ &at91sam9x5_master_layout,
+ &mck_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9x5_pmc->chws[PMC_MCK] = hw;
+
+ parent_names[0] = "plladivck";
+ parent_names[1] = "utmick";
+ hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ parent_names[4] = "mck";
+ for (i = 0; i < 2; i++) {
+ char *name;
+
+ name = xasprintf("prog%d", i);
+
+ hw = at91_clk_register_programmable(regmap, name,
+ parent_names, 5, i,
+ &at91sam9x5_programmable_layout);
+ if (IS_ERR(hw))
+ goto err_free;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
+ hw = at91_clk_register_system(regmap, at91sam9x5_systemck[i].n,
+ at91sam9x5_systemck[i].p,
+ at91sam9x5_systemck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9x5_pmc->shws[at91sam9x5_systemck[i].id] = hw;
+ }
+
+ if (has_lcdck) {
+ hw = at91_clk_register_system(regmap, "lcdck", "masterck", 3);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9x5_pmc->shws[3] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) {
+ hw = at91_clk_register_sam9x5_peripheral(regmap,
+ at91sam9x5_periphck[i].n,
+ "masterck",
+ at91sam9x5_periphck[i].id,
+ &range);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9x5_pmc->phws[at91sam9x5_periphck[i].id] = hw;
+ }
+
+ for (i = 0; extra_pcks[i].id; i++) {
+ hw = at91_clk_register_sam9x5_peripheral(regmap,
+ extra_pcks[i].n,
+ "masterck",
+ extra_pcks[i].id,
+ &range);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ at91sam9x5_pmc->phws[extra_pcks[i].id] = hw;
+ }
+
+ of_clk_add_provider(np, of_clk_hw_pmc_get, at91sam9x5_pmc);
+
+ return;
+
+err_free:
+ pmc_data_free(at91sam9x5_pmc);
+}
+
+static void __init at91sam9g15_pmc_setup(struct device_node *np)
+{
+ at91sam9x5_pmc_setup(np, at91sam9g15_periphck, true);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g15_pmc, "atmel,at91sam9g15-pmc",
+ at91sam9g15_pmc_setup);
+
+static void __init at91sam9g25_pmc_setup(struct device_node *np)
+{
+ at91sam9x5_pmc_setup(np, at91sam9g25_periphck, false);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g25_pmc, "atmel,at91sam9g25-pmc",
+ at91sam9g25_pmc_setup);
+
+static void __init at91sam9g35_pmc_setup(struct device_node *np)
+{
+ at91sam9x5_pmc_setup(np, at91sam9g35_periphck, true);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9g35_pmc, "atmel,at91sam9g35-pmc",
+ at91sam9g35_pmc_setup);
+
+static void __init at91sam9x25_pmc_setup(struct device_node *np)
+{
+ at91sam9x5_pmc_setup(np, at91sam9x25_periphck, false);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9x25_pmc, "atmel,at91sam9x25-pmc",
+ at91sam9x25_pmc_setup);
+
+static void __init at91sam9x35_pmc_setup(struct device_node *np)
+{
+ at91sam9x5_pmc_setup(np, at91sam9x35_periphck, true);
+}
+CLK_OF_DECLARE_DRIVER(at91sam9x35_pmc, "atmel,at91sam9x35-pmc",
+ at91sam9x35_pmc_setup);
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 7/9] clk: at91: add sama5d2
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
` (5 preceding siblings ...)
2019-02-18 19:47 ` [PATCH v3 6/9] clk: at91: add at91sam9x5 Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 8/9] clk: at91: add sama5d4 Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 9/9] clk: at91: update to PMC bindings Sam Ravnborg
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Add sama5d2 as part of supporting the PMC bindings for ARM at91.
The file will be wired into the build in a follow-up patch.
The file is a copy from kernel 5.0-rc6 modified to build
with barebox.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/clk/at91/sama5d2.c | 342 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 342 insertions(+)
create mode 100644 drivers/clk/at91/sama5d2.c
diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
new file mode 100644
index 000000000..dc15f7d9c
--- /dev/null
+++ b/drivers/clk/at91/sama5d2.c
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <driver.h>
+#include <regmap.h>
+#include <stdio.h>
+#include <mfd/syscon.h>
+
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics mck_characteristics = {
+ .output = { .min = 124000000, .max = 166000000 },
+ .divisors = { 1, 2, 4, 3 },
+};
+
+static u8 plla_out[] = { 0 };
+
+static u16 plla_icpll[] = { 0 };
+
+static struct clk_range plla_outputs[] = {
+ { .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+ .input = { .min = 12000000, .max = 12000000 },
+ .num_output = ARRAY_SIZE(plla_outputs),
+ .output = plla_outputs,
+ .icpll = plla_icpll,
+ .out = plla_out,
+};
+
+static const struct {
+ char *n;
+ char *p;
+ u8 id;
+} sama5d2_systemck[] = {
+ { .n = "ddrck", .p = "masterck", .id = 2 },
+ { .n = "lcdck", .p = "masterck", .id = 3 },
+ { .n = "uhpck", .p = "usbck", .id = 6 },
+ { .n = "udpck", .p = "usbck", .id = 7 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+ { .n = "pck2", .p = "prog2", .id = 10 },
+ { .n = "iscck", .p = "masterck", .id = 18 },
+};
+
+static const struct {
+ char *n;
+ u8 id;
+ struct clk_range r;
+} sama5d2_periph32ck[] = {
+ { .n = "macb0_clk", .id = 5, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "tdes_clk", .id = 11, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "matrix1_clk", .id = 14, },
+ { .n = "hsmc_clk", .id = 17, },
+ { .n = "pioA_clk", .id = 18, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "flx0_clk", .id = 19, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "flx1_clk", .id = 20, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "flx2_clk", .id = 21, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "flx3_clk", .id = 22, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "flx4_clk", .id = 23, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "uart0_clk", .id = 24, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "uart1_clk", .id = 25, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "uart2_clk", .id = 26, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "uart3_clk", .id = 27, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "uart4_clk", .id = 28, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "twi0_clk", .id = 29, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "twi1_clk", .id = 30, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "spi0_clk", .id = 33, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "spi1_clk", .id = 34, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "tcb0_clk", .id = 35, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "tcb1_clk", .id = 36, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "pwm_clk", .id = 38, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "adc_clk", .id = 40, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "uhphs_clk", .id = 41, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "udphs_clk", .id = 42, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "ssc0_clk", .id = 43, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "ssc1_clk", .id = 44, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "trng_clk", .id = 47, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "pdmic_clk", .id = 48, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "securam_clk", .id = 51, },
+ { .n = "i2s0_clk", .id = 54, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "i2s1_clk", .id = 55, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "can0_clk", .id = 56, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "can1_clk", .id = 57, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "classd_clk", .id = 59, .r = { .min = 0, .max = 83000000 }, },
+};
+
+static const struct {
+ char *n;
+ u8 id;
+} sama5d2_periphck[] = {
+ { .n = "dma0_clk", .id = 6, },
+ { .n = "dma1_clk", .id = 7, },
+ { .n = "aes_clk", .id = 9, },
+ { .n = "aesb_clk", .id = 10, },
+ { .n = "sha_clk", .id = 12, },
+ { .n = "mpddr_clk", .id = 13, },
+ { .n = "matrix0_clk", .id = 15, },
+ { .n = "sdmmc0_hclk", .id = 31, },
+ { .n = "sdmmc1_hclk", .id = 32, },
+ { .n = "lcdc_clk", .id = 45, },
+ { .n = "isc_clk", .id = 46, },
+ { .n = "qspi0_clk", .id = 52, },
+ { .n = "qspi1_clk", .id = 53, },
+};
+
+static const struct {
+ char *n;
+ u8 id;
+ struct clk_range r;
+ bool pll;
+} sama5d2_gck[] = {
+ { .n = "sdmmc0_gclk", .id = 31, },
+ { .n = "sdmmc1_gclk", .id = 32, },
+ { .n = "tcb0_gclk", .id = 35, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "tcb1_gclk", .id = 36, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "pwm_gclk", .id = 38, .r = { .min = 0, .max = 83000000 }, },
+ { .n = "isc_gclk", .id = 46, },
+ { .n = "pdmic_gclk", .id = 48, },
+ { .n = "i2s0_gclk", .id = 54, .pll = true },
+ { .n = "i2s1_gclk", .id = 55, .pll = true },
+ { .n = "can0_gclk", .id = 56, .r = { .min = 0, .max = 80000000 }, },
+ { .n = "can1_gclk", .id = 57, .r = { .min = 0, .max = 80000000 }, },
+ { .n = "classd_gclk", .id = 59, .r = { .min = 0, .max = 100000000 },
+ .pll = true },
+};
+
+static void __init sama5d2_pmc_setup(struct device_node *np)
+{
+ struct clk_range range = CLK_RANGE(0, 0);
+ const char *slck_name, *mainxtal_name;
+ struct pmc_data *sama5d2_pmc;
+ const char *parent_names[6];
+ struct regmap *regmap, *regmap_sfr;
+ struct clk *hw;
+ int i;
+ bool bypass;
+
+ i = of_property_match_string(np, "clock-names", "slow_clk");
+ if (i < 0)
+ return;
+
+ 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;
+
+ sama5d2_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1,
+ nck(sama5d2_systemck),
+ nck(sama5d2_periph32ck),
+ nck(sama5d2_gck));
+ if (!sama5d2_pmc)
+ return;
+
+ hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+ 100000000);
+ 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;
+
+ sama5d2_pmc->chws[PMC_MAIN] = hw;
+
+ hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+ &sama5d3_pll_layout, &plla_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_audio_pll_frac(regmap, "audiopll_fracck",
+ "mainck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_audio_pll_pad(regmap, "audiopll_padck",
+ "audiopll_fracck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_audio_pll_pmc(regmap, "audiopll_pmcck",
+ "audiopll_fracck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+ if (IS_ERR(regmap_sfr))
+ regmap_sfr = NULL;
+
+ hw = at91_clk_register_utmi(regmap, regmap_sfr, "utmick", "mainck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->chws[PMC_UTMI] = hw;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+ &at91sam9x5_master_layout,
+ &mck_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->chws[PMC_MCK] = hw;
+
+ hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->chws[PMC_MCK2] = hw;
+
+ parent_names[0] = "plladivck";
+ parent_names[1] = "utmick";
+ hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ parent_names[4] = "mck";
+ for (i = 0; i < 3; i++) {
+ char *name;
+
+ name = xasprintf("prog%d", i);
+
+ hw = at91_clk_register_programmable(regmap, name,
+ parent_names, 5, i,
+ &at91sam9x5_programmable_layout);
+ if (IS_ERR(hw))
+ goto err_free;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
+ hw = at91_clk_register_system(regmap, sama5d2_systemck[i].n,
+ sama5d2_systemck[i].p,
+ sama5d2_systemck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->shws[sama5d2_systemck[i].id] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sama5d2_periphck); i++) {
+ hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+ sama5d2_periphck[i].n,
+ "masterck",
+ sama5d2_periphck[i].id,
+ &range);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->phws[sama5d2_periphck[i].id] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sama5d2_periph32ck); i++) {
+ hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
+ sama5d2_periph32ck[i].n,
+ "h32mxck",
+ sama5d2_periph32ck[i].id,
+ &sama5d2_periph32ck[i].r);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->phws[sama5d2_periph32ck[i].id] = hw;
+ }
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ parent_names[4] = "mck";
+ parent_names[5] = "audiopll_pmcck";
+ for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) {
+ hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+ sama5d2_gck[i].n,
+ parent_names, 6,
+ sama5d2_gck[i].id,
+ sama5d2_gck[i].pll,
+ &sama5d2_gck[i].r);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->ghws[sama5d2_gck[i].id] = hw;
+ }
+
+ if (regmap_sfr) {
+ parent_names[0] = "i2s0_clk";
+ parent_names[1] = "i2s0_gclk";
+ hw = at91_clk_i2s_mux_register(regmap_sfr, "i2s0_muxclk",
+ parent_names, 2, 0);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->chws[PMC_I2S0_MUX] = hw;
+
+ parent_names[0] = "i2s1_clk";
+ parent_names[1] = "i2s1_gclk";
+ hw = at91_clk_i2s_mux_register(regmap_sfr, "i2s1_muxclk",
+ parent_names, 2, 1);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d2_pmc->chws[PMC_I2S1_MUX] = hw;
+ }
+
+ of_clk_add_provider(np, of_clk_hw_pmc_get, sama5d2_pmc);
+
+ return;
+
+err_free:
+ pmc_data_free(sama5d2_pmc);
+}
+CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 8/9] clk: at91: add sama5d4
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
` (6 preceding siblings ...)
2019-02-18 19:47 ` [PATCH v3 7/9] clk: at91: add sama5d2 Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 9/9] clk: at91: update to PMC bindings Sam Ravnborg
8 siblings, 0 replies; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Add sama5d4 as part of supporting the PMC bindings for ARM at91.
The file will be wired into the build in a follow-up patch.
The file is a copy from kernel 5.0-rc6 modified to build
with barebox.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
---
drivers/clk/at91/sama5d4.c | 270 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 270 insertions(+)
create mode 100644 drivers/clk/at91/sama5d4.c
diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c
new file mode 100644
index 000000000..2fbfca6f8
--- /dev/null
+++ b/drivers/clk/at91/sama5d4.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <driver.h>
+#include <regmap.h>
+#include <stdio.h>
+#include <mfd/syscon.h>
+
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <dt-bindings/clock/at91.h>
+
+#include "pmc.h"
+
+static const struct clk_master_characteristics mck_characteristics = {
+ .output = { .min = 125000000, .max = 200000000 },
+ .divisors = { 1, 2, 4, 3 },
+};
+
+static u8 plla_out[] = { 0 };
+
+static u16 plla_icpll[] = { 0 };
+
+static struct clk_range plla_outputs[] = {
+ { .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_pll_characteristics plla_characteristics = {
+ .input = { .min = 12000000, .max = 12000000 },
+ .num_output = ARRAY_SIZE(plla_outputs),
+ .output = plla_outputs,
+ .icpll = plla_icpll,
+ .out = plla_out,
+};
+
+static const struct {
+ char *n;
+ char *p;
+ u8 id;
+} sama5d4_systemck[] = {
+ { .n = "ddrck", .p = "masterck", .id = 2 },
+ { .n = "lcdck", .p = "masterck", .id = 3 },
+ { .n = "smdck", .p = "smdclk", .id = 4 },
+ { .n = "uhpck", .p = "usbck", .id = 6 },
+ { .n = "udpck", .p = "usbck", .id = 7 },
+ { .n = "pck0", .p = "prog0", .id = 8 },
+ { .n = "pck1", .p = "prog1", .id = 9 },
+ { .n = "pck2", .p = "prog2", .id = 10 },
+};
+
+static const struct {
+ char *n;
+ u8 id;
+} sama5d4_periph32ck[] = {
+ { .n = "pioD_clk", .id = 5 },
+ { .n = "usart0_clk", .id = 6 },
+ { .n = "usart1_clk", .id = 7 },
+ { .n = "icm_clk", .id = 9 },
+ { .n = "aes_clk", .id = 12 },
+ { .n = "tdes_clk", .id = 14 },
+ { .n = "sha_clk", .id = 15 },
+ { .n = "matrix1_clk", .id = 17 },
+ { .n = "hsmc_clk", .id = 22 },
+ { .n = "pioA_clk", .id = 23 },
+ { .n = "pioB_clk", .id = 24 },
+ { .n = "pioC_clk", .id = 25 },
+ { .n = "pioE_clk", .id = 26 },
+ { .n = "uart0_clk", .id = 27 },
+ { .n = "uart1_clk", .id = 28 },
+ { .n = "usart2_clk", .id = 29 },
+ { .n = "usart3_clk", .id = 30 },
+ { .n = "usart4_clk", .id = 31 },
+ { .n = "twi0_clk", .id = 32 },
+ { .n = "twi1_clk", .id = 33 },
+ { .n = "twi2_clk", .id = 34 },
+ { .n = "mci0_clk", .id = 35 },
+ { .n = "mci1_clk", .id = 36 },
+ { .n = "spi0_clk", .id = 37 },
+ { .n = "spi1_clk", .id = 38 },
+ { .n = "spi2_clk", .id = 39 },
+ { .n = "tcb0_clk", .id = 40 },
+ { .n = "tcb1_clk", .id = 41 },
+ { .n = "tcb2_clk", .id = 42 },
+ { .n = "pwm_clk", .id = 43 },
+ { .n = "adc_clk", .id = 44 },
+ { .n = "dbgu_clk", .id = 45 },
+ { .n = "uhphs_clk", .id = 46 },
+ { .n = "udphs_clk", .id = 47 },
+ { .n = "ssc0_clk", .id = 48 },
+ { .n = "ssc1_clk", .id = 49 },
+ { .n = "trng_clk", .id = 53 },
+ { .n = "macb0_clk", .id = 54 },
+ { .n = "macb1_clk", .id = 55 },
+ { .n = "fuse_clk", .id = 57 },
+ { .n = "securam_clk", .id = 59 },
+ { .n = "smd_clk", .id = 61 },
+ { .n = "twi3_clk", .id = 62 },
+ { .n = "catb_clk", .id = 63 },
+};
+
+static const struct {
+ char *n;
+ u8 id;
+} sama5d4_periphck[] = {
+ { .n = "dma0_clk", .id = 8 },
+ { .n = "cpkcc_clk", .id = 10 },
+ { .n = "aesb_clk", .id = 13 },
+ { .n = "mpddr_clk", .id = 16 },
+ { .n = "matrix0_clk", .id = 18 },
+ { .n = "vdec_clk", .id = 19 },
+ { .n = "dma1_clk", .id = 50 },
+ { .n = "lcdc_clk", .id = 51 },
+ { .n = "isi_clk", .id = 52 },
+};
+
+static void __init sama5d4_pmc_setup(struct device_node *np)
+{
+ struct clk_range range = CLK_RANGE(0, 0);
+ const char *slck_name, *mainxtal_name;
+ struct pmc_data *sama5d4_pmc;
+ const char *parent_names[5];
+ struct regmap *regmap;
+ struct clk *hw;
+ int i;
+ bool bypass;
+
+ i = of_property_match_string(np, "clock-names", "slow_clk");
+ if (i < 0)
+ return;
+
+ 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;
+
+ sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
+ nck(sama5d4_systemck),
+ nck(sama5d4_periph32ck), 0);
+ if (!sama5d4_pmc)
+ return;
+
+ hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
+ 100000000);
+ 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;
+
+ hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
+ &sama5d3_pll_layout, &plla_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d4_pmc->chws[PMC_UTMI] = hw;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
+ &at91sam9x5_master_layout,
+ &mck_characteristics);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d4_pmc->chws[PMC_MCK] = hw;
+
+ hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck");
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d4_pmc->chws[PMC_MCK2] = hw;
+
+ parent_names[0] = "plladivck";
+ parent_names[1] = "utmick";
+ hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = "plladivck";
+ parent_names[1] = "utmick";
+ hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ parent_names[0] = slck_name;
+ parent_names[1] = "mainck";
+ parent_names[2] = "plladivck";
+ parent_names[3] = "utmick";
+ parent_names[4] = "mck";
+ for (i = 0; i < 3; i++) {
+ char *name;
+
+ name = xasprintf("prog%d", i);
+
+ hw = at91_clk_register_programmable(regmap, name,
+ parent_names, 5, i,
+ &at91sam9x5_programmable_layout);
+ if (IS_ERR(hw))
+ goto err_free;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
+ hw = at91_clk_register_system(regmap, sama5d4_systemck[i].n,
+ sama5d4_systemck[i].p,
+ sama5d4_systemck[i].id);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d4_pmc->shws[sama5d4_systemck[i].id] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) {
+ hw = at91_clk_register_sam9x5_peripheral(regmap,
+ sama5d4_periphck[i].n,
+ "masterck",
+ sama5d4_periphck[i].id,
+ &range);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d4_pmc->phws[sama5d4_periphck[i].id] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) {
+ hw = at91_clk_register_sam9x5_peripheral(regmap,
+ sama5d4_periph32ck[i].n,
+ "h32mxck",
+ sama5d4_periph32ck[i].id,
+ &range);
+ if (IS_ERR(hw))
+ goto err_free;
+
+ sama5d4_pmc->phws[sama5d4_periph32ck[i].id] = hw;
+ }
+
+ of_clk_add_provider(np, of_clk_hw_pmc_get, sama5d4_pmc);
+
+ return;
+
+err_free:
+ pmc_data_free(sama5d4_pmc);
+}
+CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 9/9] clk: at91: update to PMC bindings
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
` (7 preceding siblings ...)
2019-02-18 19:47 ` [PATCH v3 8/9] clk: at91: add sama5d4 Sam Ravnborg
@ 2019-02-18 19:47 ` Sam Ravnborg
2019-02-19 7:50 ` Ahmad Fatoum
8 siblings, 1 reply; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-18 19:47 UTC (permalink / raw)
To: Barebox List, Sascha Hauer, Ladislav Michl; +Cc: Sam Ravnborg
Based on kernel 5.0-rc6 update at91 clk support
to match the new PMC bindings.
Manually added all changes done in the kernel from 4.9-rc3
to 5.0-rc6.
New drivers required was added as seperate commits.
The kernel has a dt-compat file for all the backward
compatibility code.
As barebox has only a few DT enabled at91 targets this was not ported
over.
clk-programmable saw some extra changes - it had never been bulit.
It is used only by at91sama5d2 - and barebox has no baord support for
this cpu (yet).
For the SOC config symbols updated these to match the kernel,
to enable the same set of clk features in barebox as in the kernel.
In the kernel CLK_OF_DECLARE_DRIVER() can be used for a two step init.
In barebox this is a simple one step init.
It was added to have less differences between the kernel and the barebox
versions of the drivers.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
arch/arm/mach-at91/Kconfig | 17 ++-
drivers/clk/at91/Makefile | 5 +
drivers/clk/at91/clk-generated.c | 185 +++++----------------------
drivers/clk/at91/clk-h32mx.c | 55 ++++----
drivers/clk/at91/clk-main.c | 112 +---------------
drivers/clk/at91/clk-master.c | 94 +-------------
drivers/clk/at91/clk-peripheral.c | 82 +-----------
drivers/clk/at91/clk-pll.c | 174 +------------------------
drivers/clk/at91/clk-plldiv.c | 27 +---
drivers/clk/at91/clk-programmable.c | 83 +-----------
drivers/clk/at91/clk-slow.c | 33 +----
drivers/clk/at91/clk-smd.c | 33 +----
drivers/clk/at91/clk-system.c | 42 +-----
drivers/clk/at91/clk-usb.c | 94 +-------------
drivers/clk/at91/clk-utmi.c | 100 +++++++++------
drivers/clk/at91/pmc.c | 248 ++++++++++++++++++++++++++++++++++++
drivers/clk/at91/pmc.h | 169 ++++++++++++++++++++++++
include/linux/clk.h | 7 +
include/soc/at91/atmel-sfr.h | 34 +++++
19 files changed, 619 insertions(+), 975 deletions(-)
create mode 100644 include/soc/at91/atmel-sfr.h
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index a2737a367..344344429 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -53,6 +53,9 @@ config SOC_AT91SAM9
select AT91SAM9_SMC
select CLOCKSOURCE_ATMEL_PIT
select PINCTRL
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ select HAVE_AT91_UTMI
config SOC_SAMA5
bool
@@ -63,12 +66,19 @@ config SOC_SAMA5D3
select SOC_SAMA5
select AT91SAM9_SMC
select CLOCKSOURCE_ATMEL_PIT
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ select HAVE_AT91_UTMI
config SOC_SAMA5D4
bool
select SOC_SAMA5
select AT91SAM9_SMC
select CLOCKSOURCE_ATMEL_PIT
+ select HAVE_AT91_H32MX
+ select HAVE_AT91_SMD
+ select HAVE_AT91_USB_CLK
+ select HAVE_AT91_UTMI
config ARCH_TEXT_BASE
hex
@@ -92,8 +102,9 @@ comment "Atmel AT91 System-on-Chip"
config SOC_AT91RM9200
bool
select CPU_ARM920T
- select HAVE_AT91_DBGU0
select HAS_AT91_ETHER
+ select HAVE_AT91_DBGU0
+ select HAVE_AT91_USB_CLK
config SOC_AT91SAM9260
bool
@@ -132,9 +143,6 @@ config SOC_AT91SAM9X5
select SOC_AT91SAM9
select HAVE_AT91_DBGU0
select HAS_MACB
- select HAVE_AT91_SMD
- select HAVE_AT91_USB_CLK
- select HAVE_AT91_UTMI
select COMMON_CLK_OF_PROVIDER
help
Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
@@ -532,7 +540,6 @@ config MACH_AT91SAM9263EK
depends on ARCH_AT91SAM9263
select OFDEVICE
select COMMON_CLK_OF_PROVIDER
- select HAVE_AT91_USB_CLK
select HAVE_NAND_ATMEL_BUSWIDTH_16
select HAVE_AT91_BOOTSTRAP
select AT91SAM926X_BOARD_INIT
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index 13e67bd35..ec41c15fa 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -11,3 +11,8 @@ obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
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_SOC_AT91SAM9) += at91sam9260.o
+obj-$(CONFIG_SOC_AT91SAM9) += at91sam9rl.o
+obj-$(CONFIG_SOC_AT91SAM9) += at91sam9x5.o
+obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
+obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
index 4e1cd5aa6..60516ca10 100644
--- a/drivers/clk/at91/clk-generated.c
+++ b/drivers/clk/at91/clk-generated.c
@@ -11,26 +11,23 @@
*
*/
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
+#include <common.h>
+#include <clock.h>
+#include <io.h>
+#include <linux/list.h>
+#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
-#include <linux/of.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
+#include <mfd/syscon.h>
+#include <regmap.h>
#include "pmc.h"
-#define PERIPHERAL_MAX 64
-#define PERIPHERAL_ID_MIN 2
-
-#define GENERATED_SOURCE_MAX 6
#define GENERATED_MAX_DIV 255
struct clk_generated {
- struct clk_hw hw;
+ struct clk hw;
struct regmap *regmap;
struct clk_range range;
- spinlock_t *lock;
u32 id;
u32 gckdiv;
u8 parent_id;
@@ -39,15 +36,13 @@ struct clk_generated {
#define to_clk_generated(hw) \
container_of(hw, struct clk_generated, hw)
-static int clk_generated_enable(struct clk_hw *hw)
+static int clk_generated_enable(struct clk *hw)
{
struct clk_generated *gck = to_clk_generated(hw);
- unsigned long flags;
pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n",
__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,
@@ -57,41 +52,34 @@ static int clk_generated_enable(struct clk_hw *hw)
AT91_PMC_PCR_CMD |
AT91_PMC_PCR_GCKDIV(gck->gckdiv) |
AT91_PMC_PCR_GCKEN);
- spin_unlock_irqrestore(gck->lock, flags);
return 0;
}
-static void clk_generated_disable(struct clk_hw *hw)
+static void clk_generated_disable(struct clk *hw)
{
struct clk_generated *gck = to_clk_generated(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);
- spin_unlock_irqrestore(gck->lock, flags);
}
-static int clk_generated_is_enabled(struct clk_hw *hw)
+static int clk_generated_is_enabled(struct clk *hw)
{
struct clk_generated *gck = to_clk_generated(hw);
- unsigned long flags;
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);
- spin_unlock_irqrestore(gck->lock, flags);
return status & AT91_PMC_PCR_GCKEN ? 1 : 0;
}
static unsigned long
-clk_generated_recalc_rate(struct clk_hw *hw,
+clk_generated_recalc_rate(struct clk *hw,
unsigned long parent_rate)
{
struct clk_generated *gck = to_clk_generated(hw);
@@ -99,75 +87,19 @@ clk_generated_recalc_rate(struct clk_hw *hw,
return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
}
-static int clk_generated_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
-{
- struct clk_generated *gck = to_clk_generated(hw);
- struct clk_hw *parent = NULL;
- long best_rate = -EINVAL;
- unsigned long tmp_rate, min_rate;
- int best_diff = -1;
- int tmp_diff;
- int i;
-
- for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
- u32 div;
- unsigned long parent_rate;
-
- parent = clk_hw_get_parent_by_index(hw, i);
- if (!parent)
- continue;
-
- parent_rate = clk_hw_get_rate(parent);
- min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1);
- if (!parent_rate ||
- (gck->range.max && min_rate > gck->range.max))
- continue;
-
- for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
- tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
- tmp_diff = abs(req->rate - tmp_rate);
-
- if (best_diff < 0 || best_diff > tmp_diff) {
- best_rate = tmp_rate;
- best_diff = tmp_diff;
- req->best_parent_rate = parent_rate;
- req->best_parent_hw = parent;
- }
-
- if (!best_diff || tmp_rate < req->rate)
- break;
- }
-
- if (!best_diff)
- break;
- }
-
- pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
- __func__, best_rate,
- __clk_get_name((req->best_parent_hw)->clk),
- req->best_parent_rate);
-
- if (best_rate < 0)
- return best_rate;
-
- req->rate = best_rate;
- return 0;
-}
-
/* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */
-static int clk_generated_set_parent(struct clk_hw *hw, u8 index)
+static int clk_generated_set_parent(struct clk *hw, u8 index)
{
struct clk_generated *gck = to_clk_generated(hw);
- if (index >= clk_hw_get_num_parents(hw))
+ if (index >= clk_get_num_parents(hw))
return -EINVAL;
gck->parent_id = index;
return 0;
}
-static u8 clk_generated_get_parent(struct clk_hw *hw)
+static int clk_generated_get_parent(struct clk *hw)
{
struct clk_generated *gck = to_clk_generated(hw);
@@ -175,7 +107,7 @@ static u8 clk_generated_get_parent(struct clk_hw *hw)
}
/* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */
-static int clk_generated_set_rate(struct clk_hw *hw,
+static int clk_generated_set_rate(struct clk *hw,
unsigned long rate,
unsigned long parent_rate)
{
@@ -201,7 +133,6 @@ static const struct clk_ops generated_ops = {
.disable = clk_generated_disable,
.is_enabled = clk_generated_is_enabled,
.recalc_rate = clk_generated_recalc_rate,
- .determine_rate = clk_generated_determine_rate,
.get_parent = clk_generated_get_parent,
.set_parent = clk_generated_set_parent,
.set_rate = clk_generated_set_rate,
@@ -219,13 +150,10 @@ static const struct clk_ops generated_ops = {
static void clk_generated_startup(struct clk_generated *gck)
{
u32 tmp;
- 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);
- spin_unlock_irqrestore(gck->lock, flags);
gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
>> AT91_PMC_PCR_GCKCSS_OFFSET;
@@ -233,35 +161,37 @@ static void clk_generated_startup(struct clk_generated *gck)
>> AT91_PMC_PCR_GCKDIV_OFFSET;
}
-static struct clk_hw * __init
-at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
+struct clk * __init
+at91_clk_register_generated(struct regmap *regmap,
const char *name, const char **parent_names,
- u8 num_parents, u8 id,
+ u8 num_parents, u8 id, bool pll_audio,
const struct clk_range *range)
{
+ size_t parents_array_size;
struct clk_generated *gck;
- struct clk_init_data init;
- struct clk_hw *hw;
+ struct clk *hw;
int ret;
gck = kzalloc(sizeof(*gck), GFP_KERNEL);
if (!gck)
return ERR_PTR(-ENOMEM);
- init.name = name;
- init.ops = &generated_ops;
- init.parent_names = parent_names;
- init.num_parents = num_parents;
- init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
-
gck->id = id;
- gck->hw.init = &init;
+ gck->hw.name = name;
+ gck->hw.ops = &generated_ops;
+
+ parents_array_size = num_parents * sizeof(gck->hw.parent_names[0]);
+ gck->hw.parent_names = xzalloc(parents_array_size);
+ memcpy(gck->hw.parent_names, parent_names, parents_array_size);
+ gck->hw.num_parents = num_parents;
+
+ /* gck->hw.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; */
gck->regmap = regmap;
- gck->lock = lock;
gck->range = *range;
+ /* gck->audio_pll_allowed = pll_audio; */
hw = &gck->hw;
- ret = clk_hw_register(NULL, &gck->hw);
+ ret = clk_register(&gck->hw);
if (ret) {
kfree(gck);
hw = ERR_PTR(ret);
@@ -270,54 +200,3 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
return hw;
}
-
-static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
-{
- int num;
- u32 id;
- const char *name;
- struct clk_hw *hw;
- unsigned int num_parents;
- const char *parent_names[GENERATED_SOURCE_MAX];
- struct device_node *gcknp;
- struct clk_range range = CLK_RANGE(0, 0);
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
- return;
-
- of_clk_parent_fill(np, parent_names, num_parents);
-
- num = of_get_child_count(np);
- if (!num || num > PERIPHERAL_MAX)
- return;
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return;
-
- for_each_child_of_node(np, gcknp) {
- if (of_property_read_u32(gcknp, "reg", &id))
- continue;
-
- if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
- continue;
-
- if (of_property_read_string(np, "clock-output-names", &name))
- name = gcknp->name;
-
- of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
- &range);
-
- hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
- parent_names, num_parents,
- id, &range);
- if (IS_ERR(hw))
- continue;
-
- of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
- }
-}
-CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
- of_sama5d2_clk_generated_setup);
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index e0daa4a31..31906a9e2 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -12,25 +12,27 @@
*
*/
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
+#include <common.h>
+#include <clock.h>
+#include <linux/list.h>
+#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
-#include <linux/of.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
+#include <regmap.h>
+
#include "pmc.h"
#define H32MX_MAX_FREQ 90000000
struct clk_sama5d4_h32mx {
- struct clk_hw hw;
+ struct clk hw;
struct regmap *regmap;
+ const char *parent;
};
#define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw)
-static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
+static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk *hw,
unsigned long parent_rate)
{
struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
@@ -45,7 +47,7 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
return parent_rate;
}
-static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate,
+static long clk_sama5d4_h32mx_round_rate(struct clk *hw, unsigned long rate,
unsigned long *parent_rate)
{
unsigned long div;
@@ -62,7 +64,7 @@ static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate,
return *parent_rate;
}
-static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_sama5d4_h32mx_set_rate(struct clk *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
@@ -86,40 +88,31 @@ static const struct clk_ops h32mx_ops = {
.set_rate = clk_sama5d4_h32mx_set_rate,
};
-static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
+struct clk *
+at91_clk_register_h32mx(struct regmap *regmap, const char *name,
+ const char *parent_name)
{
struct clk_sama5d4_h32mx *h32mxclk;
- struct clk_init_data init;
- const char *parent_name;
- struct regmap *regmap;
int ret;
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return;
-
h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL);
if (!h32mxclk)
- return;
-
- parent_name = of_clk_get_parent_name(np, 0);
+ return ERR_PTR(-ENOMEM);
- init.name = np->name;
- init.ops = &h32mx_ops;
- init.parent_names = parent_name ? &parent_name : NULL;
- init.num_parents = parent_name ? 1 : 0;
- init.flags = CLK_SET_RATE_GATE;
+ h32mxclk->parent = parent_name;
+ h32mxclk->hw.name = name;
+ h32mxclk->hw.ops = &h32mx_ops;
+ h32mxclk->hw.parent_names = &h32mxclk->parent;
+ h32mxclk->hw.num_parents = 1;
+ /* h32mxclk.hw.flags = CLK_SET_RATE_GATE; */
- h32mxclk->hw.init = &init;
h32mxclk->regmap = regmap;
- ret = clk_hw_register(NULL, &h32mxclk->hw);
+ ret = clk_register(&h32mxclk->hw);
if (ret) {
kfree(h32mxclk);
- return;
+ return ERR_PTR(ret);
}
- of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
+ return &h32mxclk->hw;
}
-CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
- of_sama5d4_clk_h32mx_setup);
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index 77dfdef51..4d4127dd0 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -9,7 +9,6 @@
*/
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
@@ -129,7 +128,7 @@ static const struct clk_ops main_osc_ops = {
.is_enabled = clk_main_osc_is_enabled,
};
-static struct clk *
+struct clk *
at91_clk_register_main_osc(struct regmap *regmap,
const char *name,
const char *parent_name,
@@ -165,31 +164,6 @@ at91_clk_register_main_osc(struct regmap *regmap,
return &osc->clk;
}
-static int of_at91rm9200_clk_main_osc_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *name = np->name;
- const char *parent_name;
- struct regmap *regmap;
- bool bypass;
-
- of_property_read_string(np, "clock-output-names", &name);
- bypass = of_property_read_bool(np, "atmel,osc-bypass");
- parent_name = of_clk_get_parent_name(np, 0);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
- of_at91rm9200_clk_main_osc_setup);
-
static bool clk_main_rc_osc_ready(struct regmap *regmap)
{
unsigned int status;
@@ -260,10 +234,10 @@ static const struct clk_ops main_rc_osc_ops = {
.recalc_rate = clk_main_rc_osc_recalc_rate,
};
-static struct clk *
+struct clk *
at91_clk_register_main_rc_osc(struct regmap *regmap,
const char *name,
- u32 frequency)
+ u32 frequency, u32 accuracy)
{
int ret;
struct clk_main_rc_osc *osc;
@@ -290,30 +264,6 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
return &osc->clk;
}
-static int of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
-{
- struct clk *clk;
- u32 frequency = 0;
- const char *name = np->name;
- struct regmap *regmap;
-
- of_property_read_string(np, "clock-output-names", &name);
- of_property_read_u32(np, "clock-frequency", &frequency);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91_clk_register_main_rc_osc(regmap, name, frequency);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
- of_at91sam9x5_clk_main_rc_osc_setup);
-
-
static int clk_main_probe_frequency(struct regmap *regmap)
{
unsigned int mcfr;
@@ -375,7 +325,7 @@ static const struct clk_ops rm9200_main_ops = {
.recalc_rate = clk_rm9200_main_recalc_rate,
};
-static struct clk *
+struct clk *
at91_clk_register_rm9200_main(struct regmap *regmap,
const char *name,
const char *parent_name)
@@ -407,29 +357,6 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
return &clkmain->clk;
}
-static int of_at91rm9200_clk_main_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_name;
- const char *name = np->name;
- struct regmap *regmap;
-
- parent_name = of_clk_get_parent_name(np, 0);
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91_clk_register_rm9200_main(regmap, name, parent_name);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
- of_at91rm9200_clk_main_setup);
-
static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
{
unsigned int status;
@@ -506,7 +433,7 @@ static const struct clk_ops sam9x5_main_ops = {
.get_parent = clk_sam9x5_main_get_parent,
};
-static struct clk *
+struct clk *
at91_clk_register_sam9x5_main(struct regmap *regmap,
const char *name,
const char **parent_names,
@@ -546,32 +473,3 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
return &clkmain->clk;
}
-
-static int of_at91sam9x5_clk_main_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_names[2];
- unsigned int num_parents;
- const char *name = np->name;
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents == 0 || num_parents > 2)
- return -EINVAL;
-
- of_clk_parent_fill(np, parent_names, num_parents);
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- clk = at91_clk_register_sam9x5_main(regmap, name, parent_names,
- num_parents);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
- of_at91sam9x5_clk_main_setup);
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index b3a50ce54..f7a0fb1d1 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -9,7 +9,6 @@
*/
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
@@ -25,17 +24,6 @@
#define MASTER_DIV_SHIFT 8
#define MASTER_DIV_MASK 0x3
-struct clk_master_characteristics {
- struct clk_range output;
- u32 divisors[4];
- u8 have_div3_pres;
-};
-
-struct clk_master_layout {
- u32 mask;
- u8 pres_shift;
-};
-
#define to_clk_master(clk) container_of(clk, struct clk_master, clk)
struct clk_master {
@@ -122,7 +110,7 @@ static const struct clk_ops master_ops = {
.get_parent = clk_master_get_parent,
};
-static struct clk *
+struct clk *
at91_clk_register_master(struct regmap *regmap,
const char *name, int num_parents,
const char **parent_names,
@@ -158,88 +146,12 @@ at91_clk_register_master(struct regmap *regmap,
}
-static const struct clk_master_layout at91rm9200_master_layout = {
+const struct clk_master_layout at91rm9200_master_layout = {
.mask = 0x31F,
.pres_shift = 2,
};
-static const struct clk_master_layout at91sam9x5_master_layout = {
+const struct clk_master_layout at91sam9x5_master_layout = {
.mask = 0x373,
.pres_shift = 4,
};
-
-
-static struct clk_master_characteristics *
-of_at91_clk_master_get_characteristics(struct device_node *np)
-{
- struct clk_master_characteristics *characteristics;
-
- characteristics = xzalloc(sizeof(*characteristics));
-
- if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
- goto out_free_characteristics;
-
- of_property_read_u32_array(np, "atmel,clk-divisors",
- characteristics->divisors, 4);
-
- characteristics->have_div3_pres =
- of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
-
- return characteristics;
-
-out_free_characteristics:
- kfree(characteristics);
- return NULL;
-}
-
-static int
-of_at91_clk_master_setup(struct device_node *np,
- const struct clk_master_layout *layout)
-{
- struct clk *clk;
- unsigned int num_parents;
- const char *parent_names[MASTER_SOURCE_MAX];
- const char *name = np->name;
- struct clk_master_characteristics *characteristics;
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
- return -EINVAL;
-
- of_clk_parent_fill(np, parent_names, num_parents);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- characteristics = of_at91_clk_master_get_characteristics(np);
- if (!characteristics)
- return -EINVAL;
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91_clk_register_master(regmap, name, num_parents,
- parent_names, layout,
- characteristics);
- if (IS_ERR(clk)) {
- kfree(characteristics);
- return PTR_ERR(clk);
- }
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-
-static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
-{
- of_at91_clk_master_setup(np, &at91rm9200_master_layout);
-}
-CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
- of_at91rm9200_clk_master_setup);
-
-static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
-{
- of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
- of_at91sam9x5_clk_master_setup);
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
index bbe6ffac6..00852672d 100644
--- a/drivers/clk/at91/clk-peripheral.c
+++ b/drivers/clk/at91/clk-peripheral.c
@@ -10,7 +10,6 @@
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
@@ -19,11 +18,6 @@
#include "pmc.h"
-#define PERIPHERAL_MAX 64
-
-#define PERIPHERAL_AT91RM9200 0
-#define PERIPHERAL_AT91SAM9X5 1
-
#define PERIPHERAL_ID_MIN 2
#define PERIPHERAL_ID_MAX 31
#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
@@ -105,7 +99,7 @@ static const struct clk_ops peripheral_ops = {
.is_enabled = clk_peripheral_is_enabled,
};
-static struct clk *
+struct clk *
at91_clk_register_peripheral(struct regmap *regmap, const char *name,
const char *parent_name, u32 id)
{
@@ -317,7 +311,7 @@ static const struct clk_ops sam9x5_peripheral_ops = {
.set_rate = clk_sam9x5_peripheral_set_rate,
};
-static struct clk *
+struct clk *
at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
const char *name, const char *parent_name,
u32 id, const struct clk_range *range)
@@ -355,75 +349,3 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
return &periph->clk;
}
-
-static int
-of_at91_clk_periph_setup(struct device_node *np, u8 type)
-{
- int num;
- u32 id;
- struct clk *clk;
- const char *parent_name;
- const char *name;
- struct device_node *periphclknp;
- struct regmap *regmap;
-
- parent_name = of_clk_get_parent_name(np, 0);
- if (!parent_name)
- return -ENOENT;
-
- num = of_get_child_count(np);
- if (!num || num > PERIPHERAL_MAX)
- return -EINVAL;
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- for_each_child_of_node(np, periphclknp) {
- if (of_property_read_u32(periphclknp, "reg", &id))
- continue;
-
- if (id >= PERIPHERAL_MAX)
- continue;
-
- if (of_property_read_string(np, "clock-output-names", &name))
- name = periphclknp->name;
-
- if (type == PERIPHERAL_AT91RM9200) {
- clk = at91_clk_register_peripheral(regmap, name,
- parent_name, id);
- } else {
- struct clk_range range = CLK_RANGE(0, 0);
-
- of_at91_get_clk_range(periphclknp,
- "atmel,clk-output-range",
- &range);
-
- clk = at91_clk_register_sam9x5_peripheral(regmap,
- name,
- parent_name,
- id, &range);
- }
-
- if (IS_ERR(clk))
- continue;
-
- of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk);
- }
-
- return 0;
-}
-
-static int of_at91rm9200_clk_periph_setup(struct device_node *np)
-{
- return of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
-}
-CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
- of_at91rm9200_clk_periph_setup);
-
-static int of_at91sam9x5_clk_periph_setup(struct device_node *np)
-{
- return of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
- of_at91sam9x5_clk_periph_setup);
diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
index e0af4fe5a..bc504e8a9 100644
--- a/drivers/clk/at91/clk-pll.c
+++ b/drivers/clk/at91/clk-pll.c
@@ -36,20 +36,6 @@
#define PLL_OUT_SHIFT 14
#define PLL_MAX_ID 1
-struct clk_pll_characteristics {
- struct clk_range input;
- int num_output;
- struct clk_range *output;
- u16 *icpll;
- u8 *out;
-};
-
-struct clk_pll_layout {
- u32 pllr_mask;
- u16 mul_mask;
- u8 mul_shift;
-};
-
#define to_clk_pll(clk) container_of(clk, struct clk_pll, clk)
struct clk_pll {
@@ -299,7 +285,7 @@ static const struct clk_ops pll_ops = {
.set_rate = clk_pll_set_rate,
};
-static struct clk *
+struct clk *
at91_clk_register_pll(struct regmap *regmap, const char *name,
const char *parent_name, u8 id,
const struct clk_pll_layout *layout,
@@ -341,176 +327,26 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
}
-static const struct clk_pll_layout at91rm9200_pll_layout = {
+const struct clk_pll_layout at91rm9200_pll_layout = {
.pllr_mask = 0x7FFFFFF,
.mul_shift = 16,
.mul_mask = 0x7FF,
};
-static const struct clk_pll_layout at91sam9g45_pll_layout = {
+const struct clk_pll_layout at91sam9g45_pll_layout = {
.pllr_mask = 0xFFFFFF,
.mul_shift = 16,
.mul_mask = 0xFF,
};
-static const struct clk_pll_layout at91sam9g20_pllb_layout = {
+const struct clk_pll_layout at91sam9g20_pllb_layout = {
.pllr_mask = 0x3FFFFF,
.mul_shift = 16,
.mul_mask = 0x3F,
};
-static const struct clk_pll_layout sama5d3_pll_layout = {
+const struct clk_pll_layout sama5d3_pll_layout = {
.pllr_mask = 0x1FFFFFF,
.mul_shift = 18,
.mul_mask = 0x7F,
};
-
-
-static struct clk_pll_characteristics *
-of_at91_clk_pll_get_characteristics(struct device_node *np)
-{
- int i;
- int offset;
- u32 tmp;
- int num_output;
- u32 num_cells;
- struct clk_range input;
- struct clk_range *output;
- u8 *out = NULL;
- u16 *icpll = NULL;
- struct clk_pll_characteristics *characteristics;
-
- if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
- return NULL;
-
- if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
- &num_cells))
- return NULL;
-
- if (num_cells < 2 || num_cells > 4)
- return NULL;
-
- if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
- return NULL;
- num_output = tmp / (sizeof(u32) * num_cells);
-
- characteristics = xzalloc(sizeof(*characteristics));
- output = xzalloc(sizeof(*output) * num_output);
-
- if (num_cells > 2)
- out = xzalloc(sizeof(*out) * num_output);
-
- if (num_cells > 3)
- icpll = xzalloc(sizeof(*icpll) * num_output);
-
-
- for (i = 0; i < num_output; i++) {
- offset = i * num_cells;
- if (of_property_read_u32_index(np,
- "atmel,pll-clk-output-ranges",
- offset, &tmp))
- goto out_free_output;
- output[i].min = tmp;
- if (of_property_read_u32_index(np,
- "atmel,pll-clk-output-ranges",
- offset + 1, &tmp))
- goto out_free_output;
- output[i].max = tmp;
-
- if (num_cells == 2)
- continue;
-
- if (of_property_read_u32_index(np,
- "atmel,pll-clk-output-ranges",
- offset + 2, &tmp))
- goto out_free_output;
- out[i] = tmp;
-
- if (num_cells == 3)
- continue;
-
- if (of_property_read_u32_index(np,
- "atmel,pll-clk-output-ranges",
- offset + 3, &tmp))
- goto out_free_output;
- icpll[i] = tmp;
- }
-
- characteristics->input = input;
- characteristics->num_output = num_output;
- characteristics->output = output;
- characteristics->out = out;
- characteristics->icpll = icpll;
- return characteristics;
-
-out_free_output:
- kfree(icpll);
- kfree(out);
- kfree(output);
- kfree(characteristics);
- return NULL;
-}
-
-static int
-of_at91_clk_pll_setup(struct device_node *np,
- const struct clk_pll_layout *layout)
-{
- u32 id;
- struct clk *clk;
- struct regmap *regmap;
- const char *parent_name;
- const char *name = np->name;
- struct clk_pll_characteristics *characteristics;
-
- if (of_property_read_u32(np, "reg", &id))
- return -EINVAL;
-
- parent_name = of_clk_get_parent_name(np, 0);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- characteristics = of_at91_clk_pll_get_characteristics(np);
- if (!characteristics)
- return -EINVAL;
-
- clk = at91_clk_register_pll(regmap, name, parent_name, id, layout,
- characteristics);
- if (IS_ERR(clk)) {
- kfree(characteristics);
- return PTR_ERR(clk);
- }
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-
-static int of_at91rm9200_clk_pll_setup(struct device_node *np)
-{
- return of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
-}
-CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
- of_at91rm9200_clk_pll_setup);
-
-static int of_at91sam9g45_clk_pll_setup(struct device_node *np)
-{
- return of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
-}
-CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
- of_at91sam9g45_clk_pll_setup);
-
-static int of_at91sam9g20_clk_pllb_setup(struct device_node *np)
-{
- return of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
-}
-CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
- of_at91sam9g20_clk_pllb_setup);
-
-static int of_sama5d3_clk_pll_setup(struct device_node *np)
-{
- return of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
-}
-CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
- of_sama5d3_clk_pll_setup);
diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c
index 917108e84..98d79ef59 100644
--- a/drivers/clk/at91/clk-plldiv.c
+++ b/drivers/clk/at91/clk-plldiv.c
@@ -78,7 +78,7 @@ static const struct clk_ops plldiv_ops = {
.set_rate = clk_plldiv_set_rate,
};
-static struct clk *
+struct clk *
at91_clk_register_plldiv(struct regmap *regmap, const char *name,
const char *parent_name)
{
@@ -108,28 +108,3 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
return &plldiv->clk;
}
-
-static int
-of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_name;
- const char *name = np->name;
- struct regmap *regmap;
-
- parent_name = of_clk_get_parent_name(np, 0);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91_clk_register_plldiv(regmap, name, parent_name);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
- of_at91sam9x5_clk_plldiv_setup);
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index ddb18c0f7..857ede1ca 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -10,7 +10,6 @@
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <io.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -28,12 +27,6 @@
#define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK)
#define PROG_MAX_RM9200_CSS 3
-struct clk_programmable_layout {
- u8 pres_shift;
- u8 css_mask;
- u8 have_slck_mck;
-};
-
struct clk_programmable {
struct clk clk;
struct regmap *regmap;
@@ -130,7 +123,7 @@ static const struct clk_ops programmable_ops = {
.set_rate = clk_programmable_set_rate,
};
-static struct clk *
+struct clk *
at91_clk_register_programmable(struct regmap *regmap,
const char *name, const char **parent_names,
u8 num_parents, u8 id,
@@ -167,88 +160,20 @@ at91_clk_register_programmable(struct regmap *regmap,
return &prog->clk;
}
-static const struct clk_programmable_layout at91rm9200_programmable_layout = {
+const struct clk_programmable_layout at91rm9200_programmable_layout = {
.pres_shift = 2,
.css_mask = 0x3,
.have_slck_mck = 0,
};
-static const struct clk_programmable_layout at91sam9g45_programmable_layout = {
+const struct clk_programmable_layout at91sam9g45_programmable_layout = {
.pres_shift = 2,
.css_mask = 0x3,
.have_slck_mck = 1,
};
-static const struct clk_programmable_layout at91sam9x5_programmable_layout = {
+const struct clk_programmable_layout at91sam9x5_programmable_layout = {
.pres_shift = 4,
.css_mask = 0x7,
.have_slck_mck = 0,
};
-
-static int
-of_at91_clk_prog_setup(struct device_node *np,
- const struct clk_programmable_layout *layout)
-{
- int num;
- u32 id;
- struct clk *clk;
- unsigned int num_parents;
- const char *parent_names[PROG_SOURCE_MAX];
- const char *name;
- struct device_node *progclknp;
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
- return -EINVAL;
-
- of_clk_parent_fill(np, parent_names, num_parents);
-
- num = of_get_child_count(np);
- if (!num || num > (PROG_ID_MAX + 1))
- return -EINVAL;
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- for_each_child_of_node(np, progclknp) {
- if (of_property_read_u32(progclknp, "reg", &id))
- continue;
-
- if (of_property_read_string(np, "clock-output-names", &name))
- name = progclknp->name;
-
- clk = at91_clk_register_programmable(regmap, name,
- parent_names, num_parents,
- id, layout);
- if (IS_ERR(clk))
- continue;
-
- of_clk_add_provider(progclknp, of_clk_src_simple_get, clk);
- }
-
- return 0;
-}
-
-
-static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
-{
- of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
-}
-CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
- of_at91rm9200_clk_prog_setup);
-
-static int of_at91sam9g45_clk_prog_setup(struct device_node *np)
-{
- return of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
-}
-CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
- of_at91sam9g45_clk_prog_setup);
-
-static int of_at91sam9x5_clk_prog_setup(struct device_node *np)
-{
- return of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
- of_at91sam9x5_clk_prog_setup);
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index d4981e7b4..d19f7e15a 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -12,7 +12,6 @@
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <io.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -44,7 +43,7 @@ static const struct clk_ops sam9260_slow_ops = {
.get_parent = clk_sam9260_slow_get_parent,
};
-static struct clk * __init
+struct clk * __init
at91_clk_register_sam9260_slow(struct regmap *regmap,
const char *name,
const char **parent_names,
@@ -76,33 +75,3 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
return &slowck->clk;
}
-
-static int of_at91sam9260_clk_slow_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_names[2];
- unsigned int num_parents;
- const char *name = np->name;
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents != 2)
- return -EINVAL;
-
- of_clk_parent_fill(np, parent_names, num_parents);
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- clk = at91_clk_register_sam9260_slow(regmap, name, parent_names,
- num_parents);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-
-CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
- of_at91sam9260_clk_slow_setup);
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index 65c53efbb..e81f0d4d4 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -10,7 +10,6 @@
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <io.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -115,7 +114,7 @@ static const struct clk_ops at91sam9x5_smd_ops = {
.set_rate = at91sam9x5_clk_smd_set_rate,
};
-static struct clk *
+struct clk *
at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
@@ -140,33 +139,3 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
return &smd->clk;
}
-
-static int of_at91sam9x5_clk_smd_setup(struct device_node *np)
-{
- struct clk *clk;
- unsigned int num_parents;
- const char *parent_names[SMD_SOURCE_MAX];
- const char *name = np->name;
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
- return -EINVAL;
-
- of_clk_parent_fill(np, parent_names, num_parents);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91sam9x5_clk_register_smd(regmap, name, parent_names,
- num_parents);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
- of_at91sam9x5_clk_smd_setup);
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 021930e54..8be5c7f2b 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -9,7 +9,6 @@
*/
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <io.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -91,7 +90,7 @@ static const struct clk_ops system_ops = {
.is_enabled = clk_system_is_enabled,
};
-static struct clk *
+struct clk *
at91_clk_register_system(struct regmap *regmap, const char *name,
const char *parent_name, u8 id)
{
@@ -119,42 +118,3 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
return &sys->clk;
}
-
-static int of_at91rm9200_clk_sys_setup(struct device_node *np)
-{
- int num;
- u32 id;
- struct clk *clk;
- const char *name;
- struct device_node *sysclknp;
- const char *parent_name;
- struct regmap *regmap;
-
- num = of_get_child_count(np);
- if (num > (SYSTEM_MAX_ID + 1))
- return -EINVAL;
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- for_each_child_of_node(np, sysclknp) {
- if (of_property_read_u32(sysclknp, "reg", &id))
- continue;
-
- if (of_property_read_string(np, "clock-output-names", &name))
- name = sysclknp->name;
-
- parent_name = of_clk_get_parent_name(sysclknp, 0);
-
- clk = at91_clk_register_system(regmap, name, parent_name, id);
- if (IS_ERR(clk))
- continue;
-
- of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
- }
-
- return 0;
-}
-CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
- of_at91rm9200_clk_sys_setup);
diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
index 99ba671c9..0eb0b1f5b 100644
--- a/drivers/clk/at91/clk-usb.c
+++ b/drivers/clk/at91/clk-usb.c
@@ -10,7 +10,6 @@
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <io.h>
#include <linux/list.h>
#include <linux/clk.h>
@@ -144,7 +143,7 @@ static const struct clk_ops at91sam9n12_usb_ops = {
.set_rate = at91sam9x5_clk_usb_set_rate,
};
-static struct clk *
+struct clk *
at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
@@ -172,7 +171,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
return &usb->clk;
}
-static struct clk *
+struct clk *
at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name)
{
@@ -282,7 +281,7 @@ static const struct clk_ops at91rm9200_usb_ops = {
.set_rate = at91rm9200_clk_usb_set_rate,
};
-static struct clk *
+struct clk *
at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name, const u32 *divisors)
{
@@ -308,90 +307,3 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
return &usb->clk;
}
-
-static int of_at91sam9x5_clk_usb_setup(struct device_node *np)
-{
- struct clk *clk;
- unsigned int num_parents;
- const char *parent_names[USB_SOURCE_MAX];
- const char *name = np->name;
- struct regmap *regmap;
-
- num_parents = of_clk_get_parent_count(np);
- if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
- return -EINVAL;
-
- of_clk_parent_fill(np, parent_names, num_parents);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91sam9x5_clk_register_usb(regmap, name, parent_names,
- num_parents);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
- of_at91sam9x5_clk_usb_setup);
-
-static int of_at91sam9n12_clk_usb_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_name;
- const char *name = np->name;
- struct regmap *regmap;
-
- parent_name = of_clk_get_parent_name(np, 0);
- if (!parent_name)
- return -EINVAL;
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91sam9n12_clk_register_usb(regmap, name, parent_name);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
- of_at91sam9n12_clk_usb_setup);
-
-static int of_at91rm9200_clk_usb_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_name;
- const char *name = np->name;
- u32 divisors[4] = {0, 0, 0, 0};
- struct regmap *regmap;
-
- parent_name = of_clk_get_parent_name(np, 0);
- if (!parent_name)
- return -EINVAL;
-
- of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
- if (!divisors[0])
- return -EINVAL;
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return PTR_ERR(regmap);
-
- clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
- if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- return of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
- of_at91rm9200_clk_usb_setup);
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
index 6a1c5e6df..c40af34d0 100644
--- a/drivers/clk/at91/clk-utmi.c
+++ b/drivers/clk/at91/clk-utmi.c
@@ -10,21 +10,27 @@
#include <common.h>
#include <clock.h>
-#include <of.h>
#include <linux/list.h>
#include <linux/clk.h>
#include <linux/clk/at91_pmc.h>
#include <mfd/syscon.h>
#include <regmap.h>
+#include <soc/at91/atmel-sfr.h>
+
#include "pmc.h"
-#define UTMI_FIXED_MUL 40
+/*
+ * The purpose of this clock is to generate a 480 MHz signal. A different
+ * rate can't be configured.
+ */
+#define UTMI_RATE 480000000
struct clk_utmi {
struct clk clk;
- struct regmap *regmap;
const char *parent;
+ struct regmap *regmap_pmc;
+ struct regmap *regmap_sfr;
};
#define to_clk_utmi(clk) container_of(clk, struct clk_utmi, clk)
@@ -40,13 +46,55 @@ static inline bool clk_utmi_ready(struct regmap *regmap)
static int clk_utmi_enable(struct clk *clk)
{
+ struct clk *hw_parent;
struct clk_utmi *utmi = to_clk_utmi(clk);
unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
AT91_PMC_BIASEN;
+ unsigned int utmi_ref_clk_freq;
+ unsigned long parent_rate;
+
+ /*
+ * If mainck rate is different from 12 MHz, we have to configure the
+ * FREQ field of the SFR_UTMICKTRIM register to generate properly
+ * the utmi clock.
+ */
+ hw_parent = clk_get_parent(clk);
+ parent_rate = clk_get_rate(hw_parent);
+
+ switch (parent_rate) {
+ case 12000000:
+ utmi_ref_clk_freq = 0;
+ break;
+ case 16000000:
+ utmi_ref_clk_freq = 1;
+ break;
+ case 24000000:
+ utmi_ref_clk_freq = 2;
+ break;
+ /*
+ * Not supported on SAMA5D2 but it's not an issue since MAINCK
+ * maximum value is 24 MHz.
+ */
+ case 48000000:
+ utmi_ref_clk_freq = 3;
+ break;
+ default:
+ pr_err("UTMICK: unsupported mainck rate\n");
+ return -EINVAL;
+ }
+
+
+ if (utmi->regmap_sfr) {
+ regmap_write_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
+ AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
+ } else if (utmi_ref_clk_freq) {
+ pr_err("UTMICK: sfr node required\n");
+ return -EINVAL;
+ }
+ regmap_write_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr);
- regmap_write_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr);
- while (!clk_utmi_ready(utmi->regmap))
+ while (!clk_utmi_ready(utmi->regmap_pmc))
barrier();
return 0;
@@ -56,21 +104,22 @@ static int clk_utmi_is_enabled(struct clk *clk)
{
struct clk_utmi *utmi = to_clk_utmi(clk);
- return clk_utmi_ready(utmi->regmap);
+ return clk_utmi_ready(utmi->regmap_pmc);
}
static void clk_utmi_disable(struct clk *clk)
{
struct clk_utmi *utmi = to_clk_utmi(clk);
- regmap_write_bits(utmi->regmap, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0);
+ regmap_write_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
+ AT91_PMC_UPLLEN, 0);
}
static unsigned long clk_utmi_recalc_rate(struct clk *clk,
unsigned long parent_rate)
{
- /* UTMI clk is a fixed clk multiplier */
- return parent_rate * UTMI_FIXED_MUL;
+ /* UTMI clk rate is fixed */
+ return UTMI_RATE;
}
static const struct clk_ops utmi_ops = {
@@ -80,8 +129,8 @@ static const struct clk_ops utmi_ops = {
.recalc_rate = clk_utmi_recalc_rate,
};
-static struct clk * __init
-at91_clk_register_utmi(struct regmap *regmap,
+struct clk * __init
+at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
const char *name, const char *parent_name)
{
int ret;
@@ -100,7 +149,8 @@ at91_clk_register_utmi(struct regmap *regmap,
/* utmi->clk.flags = CLK_SET_RATE_GATE; */
- utmi->regmap = regmap;
+ utmi->regmap_pmc = regmap_pmc;
+ utmi->regmap_sfr = regmap_sfr;
ret = clk_register(&utmi->clk);
if (ret) {
@@ -110,29 +160,3 @@ at91_clk_register_utmi(struct regmap *regmap,
return &utmi->clk;
}
-#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER)
-static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
-{
- struct clk *clk;
- const char *parent_name;
- const char *name = np->name;
- struct regmap *regmap;
-
- parent_name = of_clk_get_parent_name(np, 0);
-
- of_property_read_string(np, "clock-output-names", &name);
-
- regmap = syscon_node_to_regmap(of_get_parent(np));
- if (IS_ERR(regmap))
- return;
-
- clk = at91_clk_register_utmi(regmap, name, parent_name);
- if (IS_ERR(clk))
- return;
-
- of_clk_add_provider(np, of_clk_src_simple_get, clk);
- return;
-}
-CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
- of_at91sam9x5_clk_utmi_setup);
-#endif
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index d156d50ca..aa73d61c5 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -15,8 +15,13 @@
#include <mfd/syscon.h>
#include <regmap.h>
+#include <dt-bindings/clock/at91.h>
+
#include "pmc.h"
+#define PMC_MAX_IDS 128
+#define PMC_MAX_PCKS 8
+
int of_at91_get_clk_range(struct device_node *np, const char *propname,
struct clk_range *range)
{
@@ -39,3 +44,246 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname,
return 0;
}
EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
+
+struct clk *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
+{
+ unsigned int type = clkspec->args[0];
+ unsigned int idx = clkspec->args[1];
+ struct pmc_data *pmc_data = data;
+
+ switch (type) {
+ case PMC_TYPE_CORE:
+ if (idx < pmc_data->ncore)
+ return pmc_data->chws[idx];
+ break;
+ case PMC_TYPE_SYSTEM:
+ if (idx < pmc_data->nsystem)
+ return pmc_data->shws[idx];
+ break;
+ case PMC_TYPE_PERIPHERAL:
+ if (idx < pmc_data->nperiph)
+ return pmc_data->phws[idx];
+ break;
+ case PMC_TYPE_GCK:
+ if (idx < pmc_data->ngck)
+ return pmc_data->ghws[idx];
+ break;
+ default:
+ break;
+ }
+
+ pr_err("%s: invalid type (%u) or index (%u)\n", __func__, type, idx);
+
+ return ERR_PTR(-EINVAL);
+}
+
+void pmc_data_free(struct pmc_data *pmc_data)
+{
+ kfree(pmc_data->chws);
+ kfree(pmc_data->shws);
+ kfree(pmc_data->phws);
+ kfree(pmc_data->ghws);
+}
+
+struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
+ unsigned int nperiph, unsigned int ngck)
+{
+ struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
+
+ if (!pmc_data)
+ return NULL;
+
+ pmc_data->ncore = ncore;
+ pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
+ if (!pmc_data->chws)
+ goto err;
+
+ pmc_data->nsystem = nsystem;
+ pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
+ if (!pmc_data->shws)
+ goto err;
+
+ pmc_data->nperiph = nperiph;
+ pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
+ if (!pmc_data->phws)
+ goto err;
+
+ pmc_data->ngck = ngck;
+ pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
+ if (!pmc_data->ghws)
+ goto err;
+
+ return pmc_data;
+
+err:
+ pmc_data_free(pmc_data);
+
+ return NULL;
+}
+
+#ifdef CONFIG_PM
+static struct regmap *pmcreg;
+
+static u8 registered_ids[PMC_MAX_IDS];
+static u8 registered_pcks[PMC_MAX_PCKS];
+
+static struct
+{
+ u32 scsr;
+ u32 pcsr0;
+ u32 uckr;
+ u32 mor;
+ u32 mcfr;
+ u32 pllar;
+ u32 mckr;
+ u32 usb;
+ u32 imr;
+ u32 pcsr1;
+ u32 pcr[PMC_MAX_IDS];
+ u32 audio_pll0;
+ u32 audio_pll1;
+ u32 pckr[PMC_MAX_PCKS];
+} pmc_cache;
+
+/*
+ * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored
+ * without alteration in the table, and 0 is for unused clocks.
+ */
+void pmc_register_id(u8 id)
+{
+ int i;
+
+ for (i = 0; i < PMC_MAX_IDS; i++) {
+ if (registered_ids[i] == 0) {
+ registered_ids[i] = id;
+ break;
+ }
+ if (registered_ids[i] == id)
+ break;
+ }
+}
+
+/*
+ * As Programmable Clock 0 is valid on AT91 chips, there is an offset
+ * of 1 between the stored value and the real clock ID.
+ */
+void pmc_register_pck(u8 pck)
+{
+ int i;
+
+ for (i = 0; i < PMC_MAX_PCKS; i++) {
+ if (registered_pcks[i] == 0) {
+ registered_pcks[i] = pck + 1;
+ break;
+ }
+ if (registered_pcks[i] == (pck + 1))
+ break;
+ }
+}
+
+static int pmc_suspend(void)
+{
+ int i;
+ u8 num;
+
+ regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr);
+ regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0);
+ regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr);
+ regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor);
+ regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr);
+ regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar);
+ regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr);
+ regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb);
+ regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr);
+ regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1);
+
+ for (i = 0; registered_ids[i]; i++) {
+ regmap_write(pmcreg, AT91_PMC_PCR,
+ (registered_ids[i] & AT91_PMC_PCR_PID_MASK));
+ regmap_read(pmcreg, AT91_PMC_PCR,
+ &pmc_cache.pcr[registered_ids[i]]);
+ }
+ for (i = 0; registered_pcks[i]; i++) {
+ num = registered_pcks[i] - 1;
+ regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]);
+ }
+
+ return 0;
+}
+
+static bool pmc_ready(unsigned int mask)
+{
+ unsigned int status;
+
+ regmap_read(pmcreg, AT91_PMC_SR, &status);
+
+ return ((status & mask) == mask) ? 1 : 0;
+}
+
+static void pmc_resume(void)
+{
+ int i;
+ u8 num;
+ u32 tmp;
+ u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA;
+
+ regmap_read(pmcreg, AT91_PMC_MCKR, &tmp);
+ if (pmc_cache.mckr != tmp)
+ pr_warn("MCKR was not configured properly by the firmware\n");
+ regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp);
+ if (pmc_cache.pllar != tmp)
+ pr_warn("PLLAR was not configured properly by the firmware\n");
+
+ regmap_write(pmcreg, AT91_PMC_SCER, pmc_cache.scsr);
+ regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0);
+ regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr);
+ regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor);
+ regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr);
+ regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb);
+ regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr);
+ regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1);
+
+ for (i = 0; registered_ids[i]; i++) {
+ regmap_write(pmcreg, AT91_PMC_PCR,
+ pmc_cache.pcr[registered_ids[i]] |
+ AT91_PMC_PCR_CMD);
+ }
+ for (i = 0; registered_pcks[i]; i++) {
+ num = registered_pcks[i] - 1;
+ regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]);
+ }
+
+ if (pmc_cache.uckr & AT91_PMC_UPLLEN)
+ mask |= AT91_PMC_LOCKU;
+
+ while (!pmc_ready(mask))
+ cpu_relax();
+}
+
+static struct syscore_ops pmc_syscore_ops = {
+ .suspend = pmc_suspend,
+ .resume = pmc_resume,
+};
+
+static const struct of_device_id sama5d2_pmc_dt_ids[] = {
+ { .compatible = "atmel,sama5d2-pmc" },
+ { /* sentinel */ }
+};
+
+static int __init pmc_register_ops(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
+
+ pmcreg = syscon_node_to_regmap(np);
+ if (IS_ERR(pmcreg))
+ return PTR_ERR(pmcreg);
+
+ register_syscore_ops(&pmc_syscore_ops);
+
+ return 0;
+}
+/* This has to happen before arch_initcall because of the tcb_clksrc driver */
+postcore_initcall(pmc_register_ops);
+#endif
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index c6c14a79a..529498308 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -13,6 +13,19 @@
#define __PMC_H_
#include <io.h>
+#include <linux/spinlock.h>
+#include <printk.h>
+
+struct pmc_data {
+ unsigned int ncore;
+ struct clk **chws;
+ unsigned int nsystem;
+ struct clk **shws;
+ unsigned int nperiph;
+ struct clk **phws;
+ unsigned int ngck;
+ struct clk **ghws;
+};
struct clk_range {
unsigned long min;
@@ -21,7 +34,163 @@ struct clk_range {
#define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
+struct clk_master_layout {
+ u32 mask;
+ u8 pres_shift;
+};
+
+extern const struct clk_master_layout at91rm9200_master_layout;
+extern const struct clk_master_layout at91sam9x5_master_layout;
+
+struct clk_master_characteristics {
+ struct clk_range output;
+ u32 divisors[4];
+ u8 have_div3_pres;
+};
+
+struct clk_pll_layout {
+ u32 pllr_mask;
+ u16 mul_mask;
+ u8 mul_shift;
+};
+
+extern const struct clk_pll_layout at91rm9200_pll_layout;
+extern const struct clk_pll_layout at91sam9g45_pll_layout;
+extern const struct clk_pll_layout at91sam9g20_pllb_layout;
+extern const struct clk_pll_layout sama5d3_pll_layout;
+
+struct clk_pll_characteristics {
+ struct clk_range input;
+ int num_output;
+ struct clk_range *output;
+ u16 *icpll;
+ u8 *out;
+};
+
+struct clk_programmable_layout {
+ u8 pres_shift;
+ u8 css_mask;
+ u8 have_slck_mck;
+};
+
+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;
+
+#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,
+ unsigned int nperiph, unsigned int ngck);
+void pmc_data_free(struct pmc_data *pmc_data);
+
int of_at91_get_clk_range(struct device_node *np, const char *propname,
struct clk_range *range);
+struct clk *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data);
+
+struct clk *
+at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
+ const char *parent_name);
+
+struct clk *
+at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
+ const char *parent_name);
+
+struct clk *
+at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
+ const char *parent_name);
+
+struct clk *
+at91_clk_register_generated(struct regmap *regmap,
+ const char *name, const char **parent_names,
+ u8 num_parents, u8 id, bool pll_audio,
+ const struct clk_range *range);
+
+struct clk *
+at91_clk_register_h32mx(struct regmap *regmap, const char *name,
+ const char *parent_name);
+
+struct clk *
+at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
+ const char * const *parent_names,
+ unsigned int num_parents, u8 bus_id);
+
+struct clk *
+at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name,
+ u32 frequency, u32 accuracy);
+struct clk *
+at91_clk_register_main_osc(struct regmap *regmap, const char *name,
+ const char *parent_name, bool bypass);
+struct clk *
+at91_clk_register_rm9200_main(struct regmap *regmap,
+ const char *name,
+ const char *parent_name);
+struct clk *
+at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name,
+ const char **parent_names, int num_parents);
+
+struct clk *
+at91_clk_register_master(struct regmap *regmap, const char *name,
+ int num_parents, const char **parent_names,
+ const struct clk_master_layout *layout,
+ const struct clk_master_characteristics *characteristics);
+
+struct clk *
+at91_clk_register_peripheral(struct regmap *regmap, const char *name,
+ const char *parent_name, u32 id);
+struct clk *
+at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
+ const char *name, const char *parent_name,
+ u32 id, const struct clk_range *range);
+
+struct clk *
+at91_clk_register_pll(struct regmap *regmap, const char *name,
+ const char *parent_name, u8 id,
+ const struct clk_pll_layout *layout,
+ const struct clk_pll_characteristics *characteristics);
+struct clk *
+at91_clk_register_plldiv(struct regmap *regmap, const char *name,
+ const char *parent_name);
+
+struct clk *
+at91_clk_register_programmable(struct regmap *regmap, const char *name,
+ const char **parent_names, u8 num_parents, u8 id,
+ const struct clk_programmable_layout *layout);
+
+struct clk *
+at91_clk_register_sam9260_slow(struct regmap *regmap,
+ const char *name,
+ const char **parent_names,
+ int num_parents);
+
+struct clk *
+at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
+ const char **parent_names, u8 num_parents);
+
+struct clk *
+at91_clk_register_system(struct regmap *regmap, const char *name,
+ const char *parent_name, u8 id);
+
+struct clk *
+at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
+ const char **parent_names, u8 num_parents);
+struct clk *
+at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
+ const char *parent_name);
+struct clk *
+at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
+ const char *parent_name, const u32 *divisors);
+
+struct clk *
+at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
+ const char *name, const char *parent_name);
+
+#ifdef CONFIG_PM
+void pmc_register_id(u8 id);
+void pmc_register_pck(u8 pck);
+#else
+static inline void pmc_register_id(u8 id) {}
+static inline void pmc_register_pck(u8 pck) {}
+#endif
+
#endif /* __PMC_H_ */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 978a0a8a9..20498574f 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -385,6 +385,11 @@ int of_clk_add_provider(struct device_node *np,
struct clk *(*clk_src_get)(struct of_phandle_args *args,
void *data),
void *data);
+
+static inline unsigned int clk_get_num_parents(const struct clk *hw)
+{
+ return hw->num_parents;
+}
#else
@@ -430,6 +435,8 @@ static inline int of_clk_add_provider(struct device_node *np,
}
#endif
+#define CLK_OF_DECLARE_DRIVER(name, compat, fn) CLK_OF_DECLARE(name, compat, fn)
+
struct string_list;
int clk_name_complete(struct string_list *sl, char *instr);
diff --git a/include/soc/at91/atmel-sfr.h b/include/soc/at91/atmel-sfr.h
new file mode 100644
index 000000000..482337af0
--- /dev/null
+++ b/include/soc/at91/atmel-sfr.h
@@ -0,0 +1,34 @@
+/*
+ * Atmel SFR (Special Function Registers) register offsets and bit definitions.
+ *
+ * Copyright (C) 2016 Atmel
+ *
+ * Author: Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _LINUX_MFD_SYSCON_ATMEL_SFR_H
+#define _LINUX_MFD_SYSCON_ATMEL_SFR_H
+
+#define AT91_SFR_DDRCFG 0x04 /* DDR Configuration Register */
+/* 0x08 ~ 0x0c: Reserved */
+#define AT91_SFR_OHCIICR 0x10 /* OHCI INT Configuration Register */
+#define AT91_SFR_OHCIISR 0x14 /* OHCI INT Status Register */
+#define AT91_SFR_UTMICKTRIM 0x30 /* UTMI Clock Trimming Register */
+#define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */
+
+/* Field definitions */
+#define AT91_OHCIICR_SUSPEND_A BIT(8)
+#define AT91_OHCIICR_SUSPEND_B BIT(9)
+#define AT91_OHCIICR_SUSPEND_C BIT(10)
+
+#define AT91_OHCIICR_USB_SUSPEND (AT91_OHCIICR_SUSPEND_A | \
+ AT91_OHCIICR_SUSPEND_B | \
+ AT91_OHCIICR_SUSPEND_C)
+
+#define AT91_UTMICKTRIM_FREQ GENMASK(1, 0)
+
+#endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */
--
2.12.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 9/9] clk: at91: update to PMC bindings
2019-02-18 19:47 ` [PATCH v3 9/9] clk: at91: update to PMC bindings Sam Ravnborg
@ 2019-02-19 7:50 ` Ahmad Fatoum
2019-02-19 7:52 ` [PATCH] fixup! " Ahmad Fatoum
0 siblings, 1 reply; 15+ messages in thread
From: Ahmad Fatoum @ 2019-02-19 7:50 UTC (permalink / raw)
To: barebox
Hello Sam,
On 18/2/19 20:47, Sam Ravnborg wrote:
> Based on kernel 5.0-rc6 update at91 clk support
> to match the new PMC bindings.
>
> Manually added all changes done in the kernel from 4.9-rc3
> to 5.0-rc6.
> New drivers required was added as seperate commits.
>
> The kernel has a dt-compat file for all the backward
> compatibility code.
> As barebox has only a few DT enabled at91 targets this was not ported
> over.
There's a DT enabled sama5d3 based second stage (microchip-ksz9477-evb),
which is now broken now by this change omitting the dt-compat code.
I'll reply to this mail with a fixup.
>
> clk-programmable saw some extra changes - it had never been bulit.
> It is used only by at91sama5d2 - and barebox has no baord support for
> this cpu (yet).
Great! I have a sama5d27-som1-ek board sitting (without fully functioning
barebox yet though) on my desk as well.
>
> For the SOC config symbols updated these to match the kernel,
> to enable the same set of clk features in barebox as in the kernel.
>
> In the kernel CLK_OF_DECLARE_DRIVER() can be used for a two step init.
> In barebox this is a simple one step init.
> It was added to have less differences between the kernel and the barebox
> versions of the drivers.
>
> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
> Tested-by: Ladislav Michl <ladis@linux-mips.org>
> ---
> arch/arm/mach-at91/Kconfig | 17 ++-
> drivers/clk/at91/Makefile | 5 +
> drivers/clk/at91/clk-generated.c | 185 +++++----------------------
> drivers/clk/at91/clk-h32mx.c | 55 ++++----
> drivers/clk/at91/clk-main.c | 112 +---------------
> drivers/clk/at91/clk-master.c | 94 +-------------
> drivers/clk/at91/clk-peripheral.c | 82 +-----------
> drivers/clk/at91/clk-pll.c | 174 +------------------------
> drivers/clk/at91/clk-plldiv.c | 27 +---
> drivers/clk/at91/clk-programmable.c | 83 +-----------
> drivers/clk/at91/clk-slow.c | 33 +----
> drivers/clk/at91/clk-smd.c | 33 +----
> drivers/clk/at91/clk-system.c | 42 +-----
> drivers/clk/at91/clk-usb.c | 94 +-------------
> drivers/clk/at91/clk-utmi.c | 100 +++++++++------
> drivers/clk/at91/pmc.c | 248 ++++++++++++++++++++++++++++++++++++
> drivers/clk/at91/pmc.h | 169 ++++++++++++++++++++++++
> include/linux/clk.h | 7 +
> include/soc/at91/atmel-sfr.h | 34 +++++
> 19 files changed, 619 insertions(+), 975 deletions(-)
> create mode 100644 include/soc/at91/atmel-sfr.h
>
> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
> index a2737a367..344344429 100644
> --- a/arch/arm/mach-at91/Kconfig
> +++ b/arch/arm/mach-at91/Kconfig
> @@ -53,6 +53,9 @@ config SOC_AT91SAM9
> select AT91SAM9_SMC
> select CLOCKSOURCE_ATMEL_PIT
> select PINCTRL
> + select HAVE_AT91_SMD
> + select HAVE_AT91_USB_CLK
> + select HAVE_AT91_UTMI
>
> config SOC_SAMA5
> bool
> @@ -63,12 +66,19 @@ config SOC_SAMA5D3
> select SOC_SAMA5
> select AT91SAM9_SMC
> select CLOCKSOURCE_ATMEL_PIT
> + select HAVE_AT91_SMD
> + select HAVE_AT91_USB_CLK
> + select HAVE_AT91_UTMI
>
> config SOC_SAMA5D4
> bool
> select SOC_SAMA5
> select AT91SAM9_SMC
> select CLOCKSOURCE_ATMEL_PIT
> + select HAVE_AT91_H32MX
> + select HAVE_AT91_SMD
> + select HAVE_AT91_USB_CLK
> + select HAVE_AT91_UTMI
>
> config ARCH_TEXT_BASE
> hex
> @@ -92,8 +102,9 @@ comment "Atmel AT91 System-on-Chip"
> config SOC_AT91RM9200
> bool
> select CPU_ARM920T
> - select HAVE_AT91_DBGU0
> select HAS_AT91_ETHER
> + select HAVE_AT91_DBGU0
> + select HAVE_AT91_USB_CLK
>
> config SOC_AT91SAM9260
> bool
> @@ -132,9 +143,6 @@ config SOC_AT91SAM9X5
> select SOC_AT91SAM9
> select HAVE_AT91_DBGU0
> select HAS_MACB
> - select HAVE_AT91_SMD
> - select HAVE_AT91_USB_CLK
> - select HAVE_AT91_UTMI
> select COMMON_CLK_OF_PROVIDER
> help
> Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
> @@ -532,7 +540,6 @@ config MACH_AT91SAM9263EK
> depends on ARCH_AT91SAM9263
> select OFDEVICE
> select COMMON_CLK_OF_PROVIDER
> - select HAVE_AT91_USB_CLK
> select HAVE_NAND_ATMEL_BUSWIDTH_16
> select HAVE_AT91_BOOTSTRAP
> select AT91SAM926X_BOARD_INIT
> diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
> index 13e67bd35..ec41c15fa 100644
> --- a/drivers/clk/at91/Makefile
> +++ b/drivers/clk/at91/Makefile
> @@ -11,3 +11,8 @@ obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o
> 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_SOC_AT91SAM9) += at91sam9260.o
> +obj-$(CONFIG_SOC_AT91SAM9) += at91sam9rl.o
> +obj-$(CONFIG_SOC_AT91SAM9) += at91sam9x5.o
> +obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
> +obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
> diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
> index 4e1cd5aa6..60516ca10 100644
> --- a/drivers/clk/at91/clk-generated.c
> +++ b/drivers/clk/at91/clk-generated.c
> @@ -11,26 +11,23 @@
> *
> */
>
> -#include <linux/clk-provider.h>
> -#include <linux/clkdev.h>
> +#include <common.h>
> +#include <clock.h>
> +#include <io.h>
> +#include <linux/list.h>
> +#include <linux/clk.h>
> #include <linux/clk/at91_pmc.h>
> -#include <linux/of.h>
> -#include <linux/mfd/syscon.h>
> -#include <linux/regmap.h>
> +#include <mfd/syscon.h>
> +#include <regmap.h>
>
> #include "pmc.h"
>
> -#define PERIPHERAL_MAX 64
> -#define PERIPHERAL_ID_MIN 2
> -
> -#define GENERATED_SOURCE_MAX 6
> #define GENERATED_MAX_DIV 255
>
> struct clk_generated {
> - struct clk_hw hw;
> + struct clk hw;
> struct regmap *regmap;
> struct clk_range range;
> - spinlock_t *lock;
> u32 id;
> u32 gckdiv;
> u8 parent_id;
> @@ -39,15 +36,13 @@ struct clk_generated {
> #define to_clk_generated(hw) \
> container_of(hw, struct clk_generated, hw)
>
> -static int clk_generated_enable(struct clk_hw *hw)
> +static int clk_generated_enable(struct clk *hw)
> {
> struct clk_generated *gck = to_clk_generated(hw);
> - unsigned long flags;
>
> pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n",
> __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,
> @@ -57,41 +52,34 @@ static int clk_generated_enable(struct clk_hw *hw)
> AT91_PMC_PCR_CMD |
> AT91_PMC_PCR_GCKDIV(gck->gckdiv) |
> AT91_PMC_PCR_GCKEN);
> - spin_unlock_irqrestore(gck->lock, flags);
> return 0;
> }
>
> -static void clk_generated_disable(struct clk_hw *hw)
> +static void clk_generated_disable(struct clk *hw)
> {
> struct clk_generated *gck = to_clk_generated(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);
> - spin_unlock_irqrestore(gck->lock, flags);
> }
>
> -static int clk_generated_is_enabled(struct clk_hw *hw)
> +static int clk_generated_is_enabled(struct clk *hw)
> {
> struct clk_generated *gck = to_clk_generated(hw);
> - unsigned long flags;
> 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);
> - spin_unlock_irqrestore(gck->lock, flags);
>
> return status & AT91_PMC_PCR_GCKEN ? 1 : 0;
> }
>
> static unsigned long
> -clk_generated_recalc_rate(struct clk_hw *hw,
> +clk_generated_recalc_rate(struct clk *hw,
> unsigned long parent_rate)
> {
> struct clk_generated *gck = to_clk_generated(hw);
> @@ -99,75 +87,19 @@ clk_generated_recalc_rate(struct clk_hw *hw,
> return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
> }
>
> -static int clk_generated_determine_rate(struct clk_hw *hw,
> - struct clk_rate_request *req)
> -{
> - struct clk_generated *gck = to_clk_generated(hw);
> - struct clk_hw *parent = NULL;
> - long best_rate = -EINVAL;
> - unsigned long tmp_rate, min_rate;
> - int best_diff = -1;
> - int tmp_diff;
> - int i;
> -
> - for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
> - u32 div;
> - unsigned long parent_rate;
> -
> - parent = clk_hw_get_parent_by_index(hw, i);
> - if (!parent)
> - continue;
> -
> - parent_rate = clk_hw_get_rate(parent);
> - min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1);
> - if (!parent_rate ||
> - (gck->range.max && min_rate > gck->range.max))
> - continue;
> -
> - for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
> - tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
> - tmp_diff = abs(req->rate - tmp_rate);
> -
> - if (best_diff < 0 || best_diff > tmp_diff) {
> - best_rate = tmp_rate;
> - best_diff = tmp_diff;
> - req->best_parent_rate = parent_rate;
> - req->best_parent_hw = parent;
> - }
> -
> - if (!best_diff || tmp_rate < req->rate)
> - break;
> - }
> -
> - if (!best_diff)
> - break;
> - }
> -
> - pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
> - __func__, best_rate,
> - __clk_get_name((req->best_parent_hw)->clk),
> - req->best_parent_rate);
> -
> - if (best_rate < 0)
> - return best_rate;
> -
> - req->rate = best_rate;
> - return 0;
> -}
> -
> /* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */
> -static int clk_generated_set_parent(struct clk_hw *hw, u8 index)
> +static int clk_generated_set_parent(struct clk *hw, u8 index)
> {
> struct clk_generated *gck = to_clk_generated(hw);
>
> - if (index >= clk_hw_get_num_parents(hw))
> + if (index >= clk_get_num_parents(hw))
> return -EINVAL;
>
> gck->parent_id = index;
> return 0;
> }
>
> -static u8 clk_generated_get_parent(struct clk_hw *hw)
> +static int clk_generated_get_parent(struct clk *hw)
> {
> struct clk_generated *gck = to_clk_generated(hw);
>
> @@ -175,7 +107,7 @@ static u8 clk_generated_get_parent(struct clk_hw *hw)
> }
>
> /* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */
> -static int clk_generated_set_rate(struct clk_hw *hw,
> +static int clk_generated_set_rate(struct clk *hw,
> unsigned long rate,
> unsigned long parent_rate)
> {
> @@ -201,7 +133,6 @@ static const struct clk_ops generated_ops = {
> .disable = clk_generated_disable,
> .is_enabled = clk_generated_is_enabled,
> .recalc_rate = clk_generated_recalc_rate,
> - .determine_rate = clk_generated_determine_rate,
> .get_parent = clk_generated_get_parent,
> .set_parent = clk_generated_set_parent,
> .set_rate = clk_generated_set_rate,
> @@ -219,13 +150,10 @@ static const struct clk_ops generated_ops = {
> static void clk_generated_startup(struct clk_generated *gck)
> {
> u32 tmp;
> - 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);
> - spin_unlock_irqrestore(gck->lock, flags);
>
> gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
> >> AT91_PMC_PCR_GCKCSS_OFFSET;
> @@ -233,35 +161,37 @@ static void clk_generated_startup(struct clk_generated *gck)
> >> AT91_PMC_PCR_GCKDIV_OFFSET;
> }
>
> -static struct clk_hw * __init
> -at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
> +struct clk * __init
> +at91_clk_register_generated(struct regmap *regmap,
> const char *name, const char **parent_names,
> - u8 num_parents, u8 id,
> + u8 num_parents, u8 id, bool pll_audio,
> const struct clk_range *range)
> {
> + size_t parents_array_size;
> struct clk_generated *gck;
> - struct clk_init_data init;
> - struct clk_hw *hw;
> + struct clk *hw;
> int ret;
>
> gck = kzalloc(sizeof(*gck), GFP_KERNEL);
> if (!gck)
> return ERR_PTR(-ENOMEM);
>
> - init.name = name;
> - init.ops = &generated_ops;
> - init.parent_names = parent_names;
> - init.num_parents = num_parents;
> - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
> -
> gck->id = id;
> - gck->hw.init = &init;
> + gck->hw.name = name;
> + gck->hw.ops = &generated_ops;
> +
> + parents_array_size = num_parents * sizeof(gck->hw.parent_names[0]);
> + gck->hw.parent_names = xzalloc(parents_array_size);
> + memcpy(gck->hw.parent_names, parent_names, parents_array_size);
> + gck->hw.num_parents = num_parents;
> +
> + /* gck->hw.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; */
> gck->regmap = regmap;
> - gck->lock = lock;
> gck->range = *range;
> + /* gck->audio_pll_allowed = pll_audio; */
>
> hw = &gck->hw;
> - ret = clk_hw_register(NULL, &gck->hw);
> + ret = clk_register(&gck->hw);
> if (ret) {
> kfree(gck);
> hw = ERR_PTR(ret);
> @@ -270,54 +200,3 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
>
> return hw;
> }
> -
> -static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
> -{
> - int num;
> - u32 id;
> - const char *name;
> - struct clk_hw *hw;
> - unsigned int num_parents;
> - const char *parent_names[GENERATED_SOURCE_MAX];
> - struct device_node *gcknp;
> - struct clk_range range = CLK_RANGE(0, 0);
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
> - return;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> -
> - num = of_get_child_count(np);
> - if (!num || num > PERIPHERAL_MAX)
> - return;
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return;
> -
> - for_each_child_of_node(np, gcknp) {
> - if (of_property_read_u32(gcknp, "reg", &id))
> - continue;
> -
> - if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
> - continue;
> -
> - if (of_property_read_string(np, "clock-output-names", &name))
> - name = gcknp->name;
> -
> - of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
> - &range);
> -
> - hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
> - parent_names, num_parents,
> - id, &range);
> - if (IS_ERR(hw))
> - continue;
> -
> - of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
> - }
> -}
> -CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
> - of_sama5d2_clk_generated_setup);
> diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
> index e0daa4a31..31906a9e2 100644
> --- a/drivers/clk/at91/clk-h32mx.c
> +++ b/drivers/clk/at91/clk-h32mx.c
> @@ -12,25 +12,27 @@
> *
> */
>
> -#include <linux/clk-provider.h>
> -#include <linux/clkdev.h>
> +#include <common.h>
> +#include <clock.h>
> +#include <linux/list.h>
> +#include <linux/clk.h>
> #include <linux/clk/at91_pmc.h>
> -#include <linux/of.h>
> -#include <linux/regmap.h>
> -#include <linux/mfd/syscon.h>
> +#include <regmap.h>
> +
>
> #include "pmc.h"
>
> #define H32MX_MAX_FREQ 90000000
>
> struct clk_sama5d4_h32mx {
> - struct clk_hw hw;
> + struct clk hw;
> struct regmap *regmap;
> + const char *parent;
> };
>
> #define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw)
>
> -static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
> +static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk *hw,
> unsigned long parent_rate)
> {
> struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
> @@ -45,7 +47,7 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
> return parent_rate;
> }
>
> -static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate,
> +static long clk_sama5d4_h32mx_round_rate(struct clk *hw, unsigned long rate,
> unsigned long *parent_rate)
> {
> unsigned long div;
> @@ -62,7 +64,7 @@ static long clk_sama5d4_h32mx_round_rate(struct clk_hw *hw, unsigned long rate,
> return *parent_rate;
> }
>
> -static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate,
> +static int clk_sama5d4_h32mx_set_rate(struct clk *hw, unsigned long rate,
> unsigned long parent_rate)
> {
> struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
> @@ -86,40 +88,31 @@ static const struct clk_ops h32mx_ops = {
> .set_rate = clk_sama5d4_h32mx_set_rate,
> };
>
> -static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
> +struct clk *
> +at91_clk_register_h32mx(struct regmap *regmap, const char *name,
> + const char *parent_name)
> {
> struct clk_sama5d4_h32mx *h32mxclk;
> - struct clk_init_data init;
> - const char *parent_name;
> - struct regmap *regmap;
> int ret;
>
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return;
> -
> h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL);
> if (!h32mxclk)
> - return;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> + return ERR_PTR(-ENOMEM);
>
> - init.name = np->name;
> - init.ops = &h32mx_ops;
> - init.parent_names = parent_name ? &parent_name : NULL;
> - init.num_parents = parent_name ? 1 : 0;
> - init.flags = CLK_SET_RATE_GATE;
> + h32mxclk->parent = parent_name;
> + h32mxclk->hw.name = name;
> + h32mxclk->hw.ops = &h32mx_ops;
> + h32mxclk->hw.parent_names = &h32mxclk->parent;
> + h32mxclk->hw.num_parents = 1;
> + /* h32mxclk.hw.flags = CLK_SET_RATE_GATE; */
>
> - h32mxclk->hw.init = &init;
> h32mxclk->regmap = regmap;
>
> - ret = clk_hw_register(NULL, &h32mxclk->hw);
> + ret = clk_register(&h32mxclk->hw);
> if (ret) {
> kfree(h32mxclk);
> - return;
> + return ERR_PTR(ret);
> }
>
> - of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
> + return &h32mxclk->hw;
> }
> -CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
> - of_sama5d4_clk_h32mx_setup);
> diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
> index 77dfdef51..4d4127dd0 100644
> --- a/drivers/clk/at91/clk-main.c
> +++ b/drivers/clk/at91/clk-main.c
> @@ -9,7 +9,6 @@
> */
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> #include <linux/clk/at91_pmc.h>
> @@ -129,7 +128,7 @@ static const struct clk_ops main_osc_ops = {
> .is_enabled = clk_main_osc_is_enabled,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_main_osc(struct regmap *regmap,
> const char *name,
> const char *parent_name,
> @@ -165,31 +164,6 @@ at91_clk_register_main_osc(struct regmap *regmap,
> return &osc->clk;
> }
>
> -static int of_at91rm9200_clk_main_osc_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *name = np->name;
> - const char *parent_name;
> - struct regmap *regmap;
> - bool bypass;
> -
> - of_property_read_string(np, "clock-output-names", &name);
> - bypass = of_property_read_bool(np, "atmel,osc-bypass");
> - parent_name = of_clk_get_parent_name(np, 0);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
> - of_at91rm9200_clk_main_osc_setup);
> -
> static bool clk_main_rc_osc_ready(struct regmap *regmap)
> {
> unsigned int status;
> @@ -260,10 +234,10 @@ static const struct clk_ops main_rc_osc_ops = {
> .recalc_rate = clk_main_rc_osc_recalc_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_main_rc_osc(struct regmap *regmap,
> const char *name,
> - u32 frequency)
> + u32 frequency, u32 accuracy)
> {
> int ret;
> struct clk_main_rc_osc *osc;
> @@ -290,30 +264,6 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
> return &osc->clk;
> }
>
> -static int of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - u32 frequency = 0;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - of_property_read_string(np, "clock-output-names", &name);
> - of_property_read_u32(np, "clock-frequency", &frequency);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91_clk_register_main_rc_osc(regmap, name, frequency);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
> - of_at91sam9x5_clk_main_rc_osc_setup);
> -
> -
> static int clk_main_probe_frequency(struct regmap *regmap)
> {
> unsigned int mcfr;
> @@ -375,7 +325,7 @@ static const struct clk_ops rm9200_main_ops = {
> .recalc_rate = clk_rm9200_main_recalc_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_rm9200_main(struct regmap *regmap,
> const char *name,
> const char *parent_name)
> @@ -407,29 +357,6 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
> return &clkmain->clk;
> }
>
> -static int of_at91rm9200_clk_main_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_name;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91_clk_register_rm9200_main(regmap, name, parent_name);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
> - of_at91rm9200_clk_main_setup);
> -
> static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
> {
> unsigned int status;
> @@ -506,7 +433,7 @@ static const struct clk_ops sam9x5_main_ops = {
> .get_parent = clk_sam9x5_main_get_parent,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_sam9x5_main(struct regmap *regmap,
> const char *name,
> const char **parent_names,
> @@ -546,32 +473,3 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
>
> return &clkmain->clk;
> }
> -
> -static int of_at91sam9x5_clk_main_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_names[2];
> - unsigned int num_parents;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents == 0 || num_parents > 2)
> - return -EINVAL;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - clk = at91_clk_register_sam9x5_main(regmap, name, parent_names,
> - num_parents);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
> - of_at91sam9x5_clk_main_setup);
> diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
> index b3a50ce54..f7a0fb1d1 100644
> --- a/drivers/clk/at91/clk-master.c
> +++ b/drivers/clk/at91/clk-master.c
> @@ -9,7 +9,6 @@
> */
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> #include <linux/clk/at91_pmc.h>
> @@ -25,17 +24,6 @@
> #define MASTER_DIV_SHIFT 8
> #define MASTER_DIV_MASK 0x3
>
> -struct clk_master_characteristics {
> - struct clk_range output;
> - u32 divisors[4];
> - u8 have_div3_pres;
> -};
> -
> -struct clk_master_layout {
> - u32 mask;
> - u8 pres_shift;
> -};
> -
> #define to_clk_master(clk) container_of(clk, struct clk_master, clk)
>
> struct clk_master {
> @@ -122,7 +110,7 @@ static const struct clk_ops master_ops = {
> .get_parent = clk_master_get_parent,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_master(struct regmap *regmap,
> const char *name, int num_parents,
> const char **parent_names,
> @@ -158,88 +146,12 @@ at91_clk_register_master(struct regmap *regmap,
> }
>
>
> -static const struct clk_master_layout at91rm9200_master_layout = {
> +const struct clk_master_layout at91rm9200_master_layout = {
> .mask = 0x31F,
> .pres_shift = 2,
> };
>
> -static const struct clk_master_layout at91sam9x5_master_layout = {
> +const struct clk_master_layout at91sam9x5_master_layout = {
> .mask = 0x373,
> .pres_shift = 4,
> };
> -
> -
> -static struct clk_master_characteristics *
> -of_at91_clk_master_get_characteristics(struct device_node *np)
> -{
> - struct clk_master_characteristics *characteristics;
> -
> - characteristics = xzalloc(sizeof(*characteristics));
> -
> - if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
> - goto out_free_characteristics;
> -
> - of_property_read_u32_array(np, "atmel,clk-divisors",
> - characteristics->divisors, 4);
> -
> - characteristics->have_div3_pres =
> - of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
> -
> - return characteristics;
> -
> -out_free_characteristics:
> - kfree(characteristics);
> - return NULL;
> -}
> -
> -static int
> -of_at91_clk_master_setup(struct device_node *np,
> - const struct clk_master_layout *layout)
> -{
> - struct clk *clk;
> - unsigned int num_parents;
> - const char *parent_names[MASTER_SOURCE_MAX];
> - const char *name = np->name;
> - struct clk_master_characteristics *characteristics;
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
> - return -EINVAL;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - characteristics = of_at91_clk_master_get_characteristics(np);
> - if (!characteristics)
> - return -EINVAL;
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91_clk_register_master(regmap, name, num_parents,
> - parent_names, layout,
> - characteristics);
> - if (IS_ERR(clk)) {
> - kfree(characteristics);
> - return PTR_ERR(clk);
> - }
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -
> -static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
> -{
> - of_at91_clk_master_setup(np, &at91rm9200_master_layout);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
> - of_at91rm9200_clk_master_setup);
> -
> -static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
> -{
> - of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
> - of_at91sam9x5_clk_master_setup);
> diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c
> index bbe6ffac6..00852672d 100644
> --- a/drivers/clk/at91/clk-peripheral.c
> +++ b/drivers/clk/at91/clk-peripheral.c
> @@ -10,7 +10,6 @@
>
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> #include <linux/clk/at91_pmc.h>
> @@ -19,11 +18,6 @@
>
> #include "pmc.h"
>
> -#define PERIPHERAL_MAX 64
> -
> -#define PERIPHERAL_AT91RM9200 0
> -#define PERIPHERAL_AT91SAM9X5 1
> -
> #define PERIPHERAL_ID_MIN 2
> #define PERIPHERAL_ID_MAX 31
> #define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
> @@ -105,7 +99,7 @@ static const struct clk_ops peripheral_ops = {
> .is_enabled = clk_peripheral_is_enabled,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_peripheral(struct regmap *regmap, const char *name,
> const char *parent_name, u32 id)
> {
> @@ -317,7 +311,7 @@ static const struct clk_ops sam9x5_peripheral_ops = {
> .set_rate = clk_sam9x5_peripheral_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
> const char *name, const char *parent_name,
> u32 id, const struct clk_range *range)
> @@ -355,75 +349,3 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
>
> return &periph->clk;
> }
> -
> -static int
> -of_at91_clk_periph_setup(struct device_node *np, u8 type)
> -{
> - int num;
> - u32 id;
> - struct clk *clk;
> - const char *parent_name;
> - const char *name;
> - struct device_node *periphclknp;
> - struct regmap *regmap;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> - if (!parent_name)
> - return -ENOENT;
> -
> - num = of_get_child_count(np);
> - if (!num || num > PERIPHERAL_MAX)
> - return -EINVAL;
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - for_each_child_of_node(np, periphclknp) {
> - if (of_property_read_u32(periphclknp, "reg", &id))
> - continue;
> -
> - if (id >= PERIPHERAL_MAX)
> - continue;
> -
> - if (of_property_read_string(np, "clock-output-names", &name))
> - name = periphclknp->name;
> -
> - if (type == PERIPHERAL_AT91RM9200) {
> - clk = at91_clk_register_peripheral(regmap, name,
> - parent_name, id);
> - } else {
> - struct clk_range range = CLK_RANGE(0, 0);
> -
> - of_at91_get_clk_range(periphclknp,
> - "atmel,clk-output-range",
> - &range);
> -
> - clk = at91_clk_register_sam9x5_peripheral(regmap,
> - name,
> - parent_name,
> - id, &range);
> - }
> -
> - if (IS_ERR(clk))
> - continue;
> -
> - of_clk_add_provider(periphclknp, of_clk_src_simple_get, clk);
> - }
> -
> - return 0;
> -}
> -
> -static int of_at91rm9200_clk_periph_setup(struct device_node *np)
> -{
> - return of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
> - of_at91rm9200_clk_periph_setup);
> -
> -static int of_at91sam9x5_clk_periph_setup(struct device_node *np)
> -{
> - return of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
> - of_at91sam9x5_clk_periph_setup);
> diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c
> index e0af4fe5a..bc504e8a9 100644
> --- a/drivers/clk/at91/clk-pll.c
> +++ b/drivers/clk/at91/clk-pll.c
> @@ -36,20 +36,6 @@
> #define PLL_OUT_SHIFT 14
> #define PLL_MAX_ID 1
>
> -struct clk_pll_characteristics {
> - struct clk_range input;
> - int num_output;
> - struct clk_range *output;
> - u16 *icpll;
> - u8 *out;
> -};
> -
> -struct clk_pll_layout {
> - u32 pllr_mask;
> - u16 mul_mask;
> - u8 mul_shift;
> -};
> -
> #define to_clk_pll(clk) container_of(clk, struct clk_pll, clk)
>
> struct clk_pll {
> @@ -299,7 +285,7 @@ static const struct clk_ops pll_ops = {
> .set_rate = clk_pll_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_pll(struct regmap *regmap, const char *name,
> const char *parent_name, u8 id,
> const struct clk_pll_layout *layout,
> @@ -341,176 +327,26 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
> }
>
>
> -static const struct clk_pll_layout at91rm9200_pll_layout = {
> +const struct clk_pll_layout at91rm9200_pll_layout = {
> .pllr_mask = 0x7FFFFFF,
> .mul_shift = 16,
> .mul_mask = 0x7FF,
> };
>
> -static const struct clk_pll_layout at91sam9g45_pll_layout = {
> +const struct clk_pll_layout at91sam9g45_pll_layout = {
> .pllr_mask = 0xFFFFFF,
> .mul_shift = 16,
> .mul_mask = 0xFF,
> };
>
> -static const struct clk_pll_layout at91sam9g20_pllb_layout = {
> +const struct clk_pll_layout at91sam9g20_pllb_layout = {
> .pllr_mask = 0x3FFFFF,
> .mul_shift = 16,
> .mul_mask = 0x3F,
> };
>
> -static const struct clk_pll_layout sama5d3_pll_layout = {
> +const struct clk_pll_layout sama5d3_pll_layout = {
> .pllr_mask = 0x1FFFFFF,
> .mul_shift = 18,
> .mul_mask = 0x7F,
> };
> -
> -
> -static struct clk_pll_characteristics *
> -of_at91_clk_pll_get_characteristics(struct device_node *np)
> -{
> - int i;
> - int offset;
> - u32 tmp;
> - int num_output;
> - u32 num_cells;
> - struct clk_range input;
> - struct clk_range *output;
> - u8 *out = NULL;
> - u16 *icpll = NULL;
> - struct clk_pll_characteristics *characteristics;
> -
> - if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
> - return NULL;
> -
> - if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
> - &num_cells))
> - return NULL;
> -
> - if (num_cells < 2 || num_cells > 4)
> - return NULL;
> -
> - if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
> - return NULL;
> - num_output = tmp / (sizeof(u32) * num_cells);
> -
> - characteristics = xzalloc(sizeof(*characteristics));
> - output = xzalloc(sizeof(*output) * num_output);
> -
> - if (num_cells > 2)
> - out = xzalloc(sizeof(*out) * num_output);
> -
> - if (num_cells > 3)
> - icpll = xzalloc(sizeof(*icpll) * num_output);
> -
> -
> - for (i = 0; i < num_output; i++) {
> - offset = i * num_cells;
> - if (of_property_read_u32_index(np,
> - "atmel,pll-clk-output-ranges",
> - offset, &tmp))
> - goto out_free_output;
> - output[i].min = tmp;
> - if (of_property_read_u32_index(np,
> - "atmel,pll-clk-output-ranges",
> - offset + 1, &tmp))
> - goto out_free_output;
> - output[i].max = tmp;
> -
> - if (num_cells == 2)
> - continue;
> -
> - if (of_property_read_u32_index(np,
> - "atmel,pll-clk-output-ranges",
> - offset + 2, &tmp))
> - goto out_free_output;
> - out[i] = tmp;
> -
> - if (num_cells == 3)
> - continue;
> -
> - if (of_property_read_u32_index(np,
> - "atmel,pll-clk-output-ranges",
> - offset + 3, &tmp))
> - goto out_free_output;
> - icpll[i] = tmp;
> - }
> -
> - characteristics->input = input;
> - characteristics->num_output = num_output;
> - characteristics->output = output;
> - characteristics->out = out;
> - characteristics->icpll = icpll;
> - return characteristics;
> -
> -out_free_output:
> - kfree(icpll);
> - kfree(out);
> - kfree(output);
> - kfree(characteristics);
> - return NULL;
> -}
> -
> -static int
> -of_at91_clk_pll_setup(struct device_node *np,
> - const struct clk_pll_layout *layout)
> -{
> - u32 id;
> - struct clk *clk;
> - struct regmap *regmap;
> - const char *parent_name;
> - const char *name = np->name;
> - struct clk_pll_characteristics *characteristics;
> -
> - if (of_property_read_u32(np, "reg", &id))
> - return -EINVAL;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - characteristics = of_at91_clk_pll_get_characteristics(np);
> - if (!characteristics)
> - return -EINVAL;
> -
> - clk = at91_clk_register_pll(regmap, name, parent_name, id, layout,
> - characteristics);
> - if (IS_ERR(clk)) {
> - kfree(characteristics);
> - return PTR_ERR(clk);
> - }
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -
> -static int of_at91rm9200_clk_pll_setup(struct device_node *np)
> -{
> - return of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
> - of_at91rm9200_clk_pll_setup);
> -
> -static int of_at91sam9g45_clk_pll_setup(struct device_node *np)
> -{
> - return of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
> -}
> -CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
> - of_at91sam9g45_clk_pll_setup);
> -
> -static int of_at91sam9g20_clk_pllb_setup(struct device_node *np)
> -{
> - return of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
> -}
> -CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
> - of_at91sam9g20_clk_pllb_setup);
> -
> -static int of_sama5d3_clk_pll_setup(struct device_node *np)
> -{
> - return of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
> -}
> -CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
> - of_sama5d3_clk_pll_setup);
> diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c
> index 917108e84..98d79ef59 100644
> --- a/drivers/clk/at91/clk-plldiv.c
> +++ b/drivers/clk/at91/clk-plldiv.c
> @@ -78,7 +78,7 @@ static const struct clk_ops plldiv_ops = {
> .set_rate = clk_plldiv_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_plldiv(struct regmap *regmap, const char *name,
> const char *parent_name)
> {
> @@ -108,28 +108,3 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
>
> return &plldiv->clk;
> }
> -
> -static int
> -of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_name;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91_clk_register_plldiv(regmap, name, parent_name);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
> - of_at91sam9x5_clk_plldiv_setup);
> diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
> index ddb18c0f7..857ede1ca 100644
> --- a/drivers/clk/at91/clk-programmable.c
> +++ b/drivers/clk/at91/clk-programmable.c
> @@ -10,7 +10,6 @@
>
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <io.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> @@ -28,12 +27,6 @@
> #define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK)
> #define PROG_MAX_RM9200_CSS 3
>
> -struct clk_programmable_layout {
> - u8 pres_shift;
> - u8 css_mask;
> - u8 have_slck_mck;
> -};
> -
> struct clk_programmable {
> struct clk clk;
> struct regmap *regmap;
> @@ -130,7 +123,7 @@ static const struct clk_ops programmable_ops = {
> .set_rate = clk_programmable_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_programmable(struct regmap *regmap,
> const char *name, const char **parent_names,
> u8 num_parents, u8 id,
> @@ -167,88 +160,20 @@ at91_clk_register_programmable(struct regmap *regmap,
> return &prog->clk;
> }
>
> -static const struct clk_programmable_layout at91rm9200_programmable_layout = {
> +const struct clk_programmable_layout at91rm9200_programmable_layout = {
> .pres_shift = 2,
> .css_mask = 0x3,
> .have_slck_mck = 0,
> };
>
> -static const struct clk_programmable_layout at91sam9g45_programmable_layout = {
> +const struct clk_programmable_layout at91sam9g45_programmable_layout = {
> .pres_shift = 2,
> .css_mask = 0x3,
> .have_slck_mck = 1,
> };
>
> -static const struct clk_programmable_layout at91sam9x5_programmable_layout = {
> +const struct clk_programmable_layout at91sam9x5_programmable_layout = {
> .pres_shift = 4,
> .css_mask = 0x7,
> .have_slck_mck = 0,
> };
> -
> -static int
> -of_at91_clk_prog_setup(struct device_node *np,
> - const struct clk_programmable_layout *layout)
> -{
> - int num;
> - u32 id;
> - struct clk *clk;
> - unsigned int num_parents;
> - const char *parent_names[PROG_SOURCE_MAX];
> - const char *name;
> - struct device_node *progclknp;
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
> - return -EINVAL;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> -
> - num = of_get_child_count(np);
> - if (!num || num > (PROG_ID_MAX + 1))
> - return -EINVAL;
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - for_each_child_of_node(np, progclknp) {
> - if (of_property_read_u32(progclknp, "reg", &id))
> - continue;
> -
> - if (of_property_read_string(np, "clock-output-names", &name))
> - name = progclknp->name;
> -
> - clk = at91_clk_register_programmable(regmap, name,
> - parent_names, num_parents,
> - id, layout);
> - if (IS_ERR(clk))
> - continue;
> -
> - of_clk_add_provider(progclknp, of_clk_src_simple_get, clk);
> - }
> -
> - return 0;
> -}
> -
> -
> -static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
> -{
> - of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
> - of_at91rm9200_clk_prog_setup);
> -
> -static int of_at91sam9g45_clk_prog_setup(struct device_node *np)
> -{
> - return of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
> -}
> -CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
> - of_at91sam9g45_clk_prog_setup);
> -
> -static int of_at91sam9x5_clk_prog_setup(struct device_node *np)
> -{
> - return of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
> - of_at91sam9x5_clk_prog_setup);
> diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
> index d4981e7b4..d19f7e15a 100644
> --- a/drivers/clk/at91/clk-slow.c
> +++ b/drivers/clk/at91/clk-slow.c
> @@ -12,7 +12,6 @@
>
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <io.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> @@ -44,7 +43,7 @@ static const struct clk_ops sam9260_slow_ops = {
> .get_parent = clk_sam9260_slow_get_parent,
> };
>
> -static struct clk * __init
> +struct clk * __init
> at91_clk_register_sam9260_slow(struct regmap *regmap,
> const char *name,
> const char **parent_names,
> @@ -76,33 +75,3 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
>
> return &slowck->clk;
> }
> -
> -static int of_at91sam9260_clk_slow_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_names[2];
> - unsigned int num_parents;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents != 2)
> - return -EINVAL;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - clk = at91_clk_register_sam9260_slow(regmap, name, parent_names,
> - num_parents);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -
> -CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
> - of_at91sam9260_clk_slow_setup);
> diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
> index 65c53efbb..e81f0d4d4 100644
> --- a/drivers/clk/at91/clk-smd.c
> +++ b/drivers/clk/at91/clk-smd.c
> @@ -10,7 +10,6 @@
>
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <io.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> @@ -115,7 +114,7 @@ static const struct clk_ops at91sam9x5_smd_ops = {
> .set_rate = at91sam9x5_clk_smd_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
> const char **parent_names, u8 num_parents)
> {
> @@ -140,33 +139,3 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
>
> return &smd->clk;
> }
> -
> -static int of_at91sam9x5_clk_smd_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - unsigned int num_parents;
> - const char *parent_names[SMD_SOURCE_MAX];
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
> - return -EINVAL;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91sam9x5_clk_register_smd(regmap, name, parent_names,
> - num_parents);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
> - of_at91sam9x5_clk_smd_setup);
> diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
> index 021930e54..8be5c7f2b 100644
> --- a/drivers/clk/at91/clk-system.c
> +++ b/drivers/clk/at91/clk-system.c
> @@ -9,7 +9,6 @@
> */
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <io.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> @@ -91,7 +90,7 @@ static const struct clk_ops system_ops = {
> .is_enabled = clk_system_is_enabled,
> };
>
> -static struct clk *
> +struct clk *
> at91_clk_register_system(struct regmap *regmap, const char *name,
> const char *parent_name, u8 id)
> {
> @@ -119,42 +118,3 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
>
> return &sys->clk;
> }
> -
> -static int of_at91rm9200_clk_sys_setup(struct device_node *np)
> -{
> - int num;
> - u32 id;
> - struct clk *clk;
> - const char *name;
> - struct device_node *sysclknp;
> - const char *parent_name;
> - struct regmap *regmap;
> -
> - num = of_get_child_count(np);
> - if (num > (SYSTEM_MAX_ID + 1))
> - return -EINVAL;
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - for_each_child_of_node(np, sysclknp) {
> - if (of_property_read_u32(sysclknp, "reg", &id))
> - continue;
> -
> - if (of_property_read_string(np, "clock-output-names", &name))
> - name = sysclknp->name;
> -
> - parent_name = of_clk_get_parent_name(sysclknp, 0);
> -
> - clk = at91_clk_register_system(regmap, name, parent_name, id);
> - if (IS_ERR(clk))
> - continue;
> -
> - of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
> - }
> -
> - return 0;
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
> - of_at91rm9200_clk_sys_setup);
> diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c
> index 99ba671c9..0eb0b1f5b 100644
> --- a/drivers/clk/at91/clk-usb.c
> +++ b/drivers/clk/at91/clk-usb.c
> @@ -10,7 +10,6 @@
>
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <io.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> @@ -144,7 +143,7 @@ static const struct clk_ops at91sam9n12_usb_ops = {
> .set_rate = at91sam9x5_clk_usb_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
> const char **parent_names, u8 num_parents)
> {
> @@ -172,7 +171,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
> return &usb->clk;
> }
>
> -static struct clk *
> +struct clk *
> at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
> const char *parent_name)
> {
> @@ -282,7 +281,7 @@ static const struct clk_ops at91rm9200_usb_ops = {
> .set_rate = at91rm9200_clk_usb_set_rate,
> };
>
> -static struct clk *
> +struct clk *
> at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
> const char *parent_name, const u32 *divisors)
> {
> @@ -308,90 +307,3 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
>
> return &usb->clk;
> }
> -
> -static int of_at91sam9x5_clk_usb_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - unsigned int num_parents;
> - const char *parent_names[USB_SOURCE_MAX];
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - num_parents = of_clk_get_parent_count(np);
> - if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
> - return -EINVAL;
> -
> - of_clk_parent_fill(np, parent_names, num_parents);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91sam9x5_clk_register_usb(regmap, name, parent_names,
> - num_parents);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
> - of_at91sam9x5_clk_usb_setup);
> -
> -static int of_at91sam9n12_clk_usb_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_name;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> - if (!parent_name)
> - return -EINVAL;
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91sam9n12_clk_register_usb(regmap, name, parent_name);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
> - of_at91sam9n12_clk_usb_setup);
> -
> -static int of_at91rm9200_clk_usb_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_name;
> - const char *name = np->name;
> - u32 divisors[4] = {0, 0, 0, 0};
> - struct regmap *regmap;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> - if (!parent_name)
> - return -EINVAL;
> -
> - of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
> - if (!divisors[0])
> - return -EINVAL;
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return PTR_ERR(regmap);
> -
> - clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> -
> - return of_clk_add_provider(np, of_clk_src_simple_get, clk);
> -}
> -CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
> - of_at91rm9200_clk_usb_setup);
> diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c
> index 6a1c5e6df..c40af34d0 100644
> --- a/drivers/clk/at91/clk-utmi.c
> +++ b/drivers/clk/at91/clk-utmi.c
> @@ -10,21 +10,27 @@
>
> #include <common.h>
> #include <clock.h>
> -#include <of.h>
> #include <linux/list.h>
> #include <linux/clk.h>
> #include <linux/clk/at91_pmc.h>
> #include <mfd/syscon.h>
> #include <regmap.h>
>
> +#include <soc/at91/atmel-sfr.h>
> +
> #include "pmc.h"
>
> -#define UTMI_FIXED_MUL 40
> +/*
> + * The purpose of this clock is to generate a 480 MHz signal. A different
> + * rate can't be configured.
> + */
> +#define UTMI_RATE 480000000
>
> struct clk_utmi {
> struct clk clk;
> - struct regmap *regmap;
> const char *parent;
> + struct regmap *regmap_pmc;
> + struct regmap *regmap_sfr;
> };
>
> #define to_clk_utmi(clk) container_of(clk, struct clk_utmi, clk)
> @@ -40,13 +46,55 @@ static inline bool clk_utmi_ready(struct regmap *regmap)
>
> static int clk_utmi_enable(struct clk *clk)
> {
> + struct clk *hw_parent;
> struct clk_utmi *utmi = to_clk_utmi(clk);
> unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
> AT91_PMC_BIASEN;
> + unsigned int utmi_ref_clk_freq;
> + unsigned long parent_rate;
> +
> + /*
> + * If mainck rate is different from 12 MHz, we have to configure the
> + * FREQ field of the SFR_UTMICKTRIM register to generate properly
> + * the utmi clock.
> + */
> + hw_parent = clk_get_parent(clk);
> + parent_rate = clk_get_rate(hw_parent);
> +
> + switch (parent_rate) {
> + case 12000000:
> + utmi_ref_clk_freq = 0;
> + break;
> + case 16000000:
> + utmi_ref_clk_freq = 1;
> + break;
> + case 24000000:
> + utmi_ref_clk_freq = 2;
> + break;
> + /*
> + * Not supported on SAMA5D2 but it's not an issue since MAINCK
> + * maximum value is 24 MHz.
> + */
> + case 48000000:
> + utmi_ref_clk_freq = 3;
> + break;
> + default:
> + pr_err("UTMICK: unsupported mainck rate\n");
> + return -EINVAL;
> + }
> +
> +
> + if (utmi->regmap_sfr) {
> + regmap_write_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
> + AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
> + } else if (utmi_ref_clk_freq) {
> + pr_err("UTMICK: sfr node required\n");
> + return -EINVAL;
> + }
> + regmap_write_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr);
>
> - regmap_write_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr);
>
> - while (!clk_utmi_ready(utmi->regmap))
> + while (!clk_utmi_ready(utmi->regmap_pmc))
> barrier();
>
> return 0;
> @@ -56,21 +104,22 @@ static int clk_utmi_is_enabled(struct clk *clk)
> {
> struct clk_utmi *utmi = to_clk_utmi(clk);
>
> - return clk_utmi_ready(utmi->regmap);
> + return clk_utmi_ready(utmi->regmap_pmc);
> }
>
> static void clk_utmi_disable(struct clk *clk)
> {
> struct clk_utmi *utmi = to_clk_utmi(clk);
>
> - regmap_write_bits(utmi->regmap, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0);
> + regmap_write_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
> + AT91_PMC_UPLLEN, 0);
> }
>
> static unsigned long clk_utmi_recalc_rate(struct clk *clk,
> unsigned long parent_rate)
> {
> - /* UTMI clk is a fixed clk multiplier */
> - return parent_rate * UTMI_FIXED_MUL;
> + /* UTMI clk rate is fixed */
> + return UTMI_RATE;
> }
>
> static const struct clk_ops utmi_ops = {
> @@ -80,8 +129,8 @@ static const struct clk_ops utmi_ops = {
> .recalc_rate = clk_utmi_recalc_rate,
> };
>
> -static struct clk * __init
> -at91_clk_register_utmi(struct regmap *regmap,
> +struct clk * __init
> +at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
> const char *name, const char *parent_name)
> {
> int ret;
> @@ -100,7 +149,8 @@ at91_clk_register_utmi(struct regmap *regmap,
>
> /* utmi->clk.flags = CLK_SET_RATE_GATE; */
>
> - utmi->regmap = regmap;
> + utmi->regmap_pmc = regmap_pmc;
> + utmi->regmap_sfr = regmap_sfr;
>
> ret = clk_register(&utmi->clk);
> if (ret) {
> @@ -110,29 +160,3 @@ at91_clk_register_utmi(struct regmap *regmap,
>
> return &utmi->clk;
> }
> -#if defined(CONFIG_OFTREE) && defined(CONFIG_COMMON_CLK_OF_PROVIDER)
> -static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
> -{
> - struct clk *clk;
> - const char *parent_name;
> - const char *name = np->name;
> - struct regmap *regmap;
> -
> - parent_name = of_clk_get_parent_name(np, 0);
> -
> - of_property_read_string(np, "clock-output-names", &name);
> -
> - regmap = syscon_node_to_regmap(of_get_parent(np));
> - if (IS_ERR(regmap))
> - return;
> -
> - clk = at91_clk_register_utmi(regmap, name, parent_name);
> - if (IS_ERR(clk))
> - return;
> -
> - of_clk_add_provider(np, of_clk_src_simple_get, clk);
> - return;
> -}
> -CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
> - of_at91sam9x5_clk_utmi_setup);
> -#endif
> diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
> index d156d50ca..aa73d61c5 100644
> --- a/drivers/clk/at91/pmc.c
> +++ b/drivers/clk/at91/pmc.c
> @@ -15,8 +15,13 @@
> #include <mfd/syscon.h>
> #include <regmap.h>
>
> +#include <dt-bindings/clock/at91.h>
> +
> #include "pmc.h"
>
> +#define PMC_MAX_IDS 128
> +#define PMC_MAX_PCKS 8
> +
> int of_at91_get_clk_range(struct device_node *np, const char *propname,
> struct clk_range *range)
> {
> @@ -39,3 +44,246 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname,
> return 0;
> }
> EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
> +
> +struct clk *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
> +{
> + unsigned int type = clkspec->args[0];
> + unsigned int idx = clkspec->args[1];
> + struct pmc_data *pmc_data = data;
> +
> + switch (type) {
> + case PMC_TYPE_CORE:
> + if (idx < pmc_data->ncore)
> + return pmc_data->chws[idx];
> + break;
> + case PMC_TYPE_SYSTEM:
> + if (idx < pmc_data->nsystem)
> + return pmc_data->shws[idx];
> + break;
> + case PMC_TYPE_PERIPHERAL:
> + if (idx < pmc_data->nperiph)
> + return pmc_data->phws[idx];
> + break;
> + case PMC_TYPE_GCK:
> + if (idx < pmc_data->ngck)
> + return pmc_data->ghws[idx];
> + break;
> + default:
> + break;
> + }
> +
> + pr_err("%s: invalid type (%u) or index (%u)\n", __func__, type, idx);
> +
> + return ERR_PTR(-EINVAL);
> +}
> +
> +void pmc_data_free(struct pmc_data *pmc_data)
> +{
> + kfree(pmc_data->chws);
> + kfree(pmc_data->shws);
> + kfree(pmc_data->phws);
> + kfree(pmc_data->ghws);
> +}
> +
> +struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
> + unsigned int nperiph, unsigned int ngck)
> +{
> + struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
> +
> + if (!pmc_data)
> + return NULL;
> +
> + pmc_data->ncore = ncore;
> + pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
> + if (!pmc_data->chws)
> + goto err;
> +
> + pmc_data->nsystem = nsystem;
> + pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
> + if (!pmc_data->shws)
> + goto err;
> +
> + pmc_data->nperiph = nperiph;
> + pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
> + if (!pmc_data->phws)
> + goto err;
> +
> + pmc_data->ngck = ngck;
> + pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
> + if (!pmc_data->ghws)
> + goto err;
> +
> + return pmc_data;
> +
> +err:
> + pmc_data_free(pmc_data);
> +
> + return NULL;
> +}
> +
> +#ifdef CONFIG_PM
> +static struct regmap *pmcreg;
> +
> +static u8 registered_ids[PMC_MAX_IDS];
> +static u8 registered_pcks[PMC_MAX_PCKS];
> +
> +static struct
> +{
> + u32 scsr;
> + u32 pcsr0;
> + u32 uckr;
> + u32 mor;
> + u32 mcfr;
> + u32 pllar;
> + u32 mckr;
> + u32 usb;
> + u32 imr;
> + u32 pcsr1;
> + u32 pcr[PMC_MAX_IDS];
> + u32 audio_pll0;
> + u32 audio_pll1;
> + u32 pckr[PMC_MAX_PCKS];
> +} pmc_cache;
> +
> +/*
> + * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored
> + * without alteration in the table, and 0 is for unused clocks.
> + */
> +void pmc_register_id(u8 id)
> +{
> + int i;
> +
> + for (i = 0; i < PMC_MAX_IDS; i++) {
> + if (registered_ids[i] == 0) {
> + registered_ids[i] = id;
> + break;
> + }
> + if (registered_ids[i] == id)
> + break;
> + }
> +}
> +
> +/*
> + * As Programmable Clock 0 is valid on AT91 chips, there is an offset
> + * of 1 between the stored value and the real clock ID.
> + */
> +void pmc_register_pck(u8 pck)
> +{
> + int i;
> +
> + for (i = 0; i < PMC_MAX_PCKS; i++) {
> + if (registered_pcks[i] == 0) {
> + registered_pcks[i] = pck + 1;
> + break;
> + }
> + if (registered_pcks[i] == (pck + 1))
> + break;
> + }
> +}
> +
> +static int pmc_suspend(void)
> +{
> + int i;
> + u8 num;
> +
> + regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr);
> + regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0);
> + regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr);
> + regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor);
> + regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr);
> + regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar);
> + regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr);
> + regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb);
> + regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr);
> + regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1);
> +
> + for (i = 0; registered_ids[i]; i++) {
> + regmap_write(pmcreg, AT91_PMC_PCR,
> + (registered_ids[i] & AT91_PMC_PCR_PID_MASK));
> + regmap_read(pmcreg, AT91_PMC_PCR,
> + &pmc_cache.pcr[registered_ids[i]]);
> + }
> + for (i = 0; registered_pcks[i]; i++) {
> + num = registered_pcks[i] - 1;
> + regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]);
> + }
> +
> + return 0;
> +}
> +
> +static bool pmc_ready(unsigned int mask)
> +{
> + unsigned int status;
> +
> + regmap_read(pmcreg, AT91_PMC_SR, &status);
> +
> + return ((status & mask) == mask) ? 1 : 0;
> +}
> +
> +static void pmc_resume(void)
> +{
> + int i;
> + u8 num;
> + u32 tmp;
> + u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA;
> +
> + regmap_read(pmcreg, AT91_PMC_MCKR, &tmp);
> + if (pmc_cache.mckr != tmp)
> + pr_warn("MCKR was not configured properly by the firmware\n");
> + regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp);
> + if (pmc_cache.pllar != tmp)
> + pr_warn("PLLAR was not configured properly by the firmware\n");
> +
> + regmap_write(pmcreg, AT91_PMC_SCER, pmc_cache.scsr);
> + regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0);
> + regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr);
> + regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor);
> + regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr);
> + regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb);
> + regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr);
> + regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1);
> +
> + for (i = 0; registered_ids[i]; i++) {
> + regmap_write(pmcreg, AT91_PMC_PCR,
> + pmc_cache.pcr[registered_ids[i]] |
> + AT91_PMC_PCR_CMD);
> + }
> + for (i = 0; registered_pcks[i]; i++) {
> + num = registered_pcks[i] - 1;
> + regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]);
> + }
> +
> + if (pmc_cache.uckr & AT91_PMC_UPLLEN)
> + mask |= AT91_PMC_LOCKU;
> +
> + while (!pmc_ready(mask))
> + cpu_relax();
> +}
> +
> +static struct syscore_ops pmc_syscore_ops = {
> + .suspend = pmc_suspend,
> + .resume = pmc_resume,
> +};
> +
> +static const struct of_device_id sama5d2_pmc_dt_ids[] = {
> + { .compatible = "atmel,sama5d2-pmc" },
> + { /* sentinel */ }
> +};
> +
> +static int __init pmc_register_ops(void)
> +{
> + struct device_node *np;
> +
> + np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
> +
> + pmcreg = syscon_node_to_regmap(np);
> + if (IS_ERR(pmcreg))
> + return PTR_ERR(pmcreg);
> +
> + register_syscore_ops(&pmc_syscore_ops);
> +
> + return 0;
> +}
> +/* This has to happen before arch_initcall because of the tcb_clksrc driver */
> +postcore_initcall(pmc_register_ops);
> +#endif
> diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
> index c6c14a79a..529498308 100644
> --- a/drivers/clk/at91/pmc.h
> +++ b/drivers/clk/at91/pmc.h
> @@ -13,6 +13,19 @@
> #define __PMC_H_
>
> #include <io.h>
> +#include <linux/spinlock.h>
> +#include <printk.h>
> +
> +struct pmc_data {
> + unsigned int ncore;
> + struct clk **chws;
> + unsigned int nsystem;
> + struct clk **shws;
> + unsigned int nperiph;
> + struct clk **phws;
> + unsigned int ngck;
> + struct clk **ghws;
> +};
>
> struct clk_range {
> unsigned long min;
> @@ -21,7 +34,163 @@ struct clk_range {
>
> #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
>
> +struct clk_master_layout {
> + u32 mask;
> + u8 pres_shift;
> +};
> +
> +extern const struct clk_master_layout at91rm9200_master_layout;
> +extern const struct clk_master_layout at91sam9x5_master_layout;
> +
> +struct clk_master_characteristics {
> + struct clk_range output;
> + u32 divisors[4];
> + u8 have_div3_pres;
> +};
> +
> +struct clk_pll_layout {
> + u32 pllr_mask;
> + u16 mul_mask;
> + u8 mul_shift;
> +};
> +
> +extern const struct clk_pll_layout at91rm9200_pll_layout;
> +extern const struct clk_pll_layout at91sam9g45_pll_layout;
> +extern const struct clk_pll_layout at91sam9g20_pllb_layout;
> +extern const struct clk_pll_layout sama5d3_pll_layout;
> +
> +struct clk_pll_characteristics {
> + struct clk_range input;
> + int num_output;
> + struct clk_range *output;
> + u16 *icpll;
> + u8 *out;
> +};
> +
> +struct clk_programmable_layout {
> + u8 pres_shift;
> + u8 css_mask;
> + u8 have_slck_mck;
> +};
> +
> +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;
> +
> +#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,
> + unsigned int nperiph, unsigned int ngck);
> +void pmc_data_free(struct pmc_data *pmc_data);
> +
> int of_at91_get_clk_range(struct device_node *np, const char *propname,
> struct clk_range *range);
>
> +struct clk *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data);
> +
> +struct clk *
> +at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
> + const char *parent_name);
> +
> +struct clk *
> +at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
> + const char *parent_name);
> +
> +struct clk *
> +at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
> + const char *parent_name);
> +
> +struct clk *
> +at91_clk_register_generated(struct regmap *regmap,
> + const char *name, const char **parent_names,
> + u8 num_parents, u8 id, bool pll_audio,
> + const struct clk_range *range);
> +
> +struct clk *
> +at91_clk_register_h32mx(struct regmap *regmap, const char *name,
> + const char *parent_name);
> +
> +struct clk *
> +at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
> + const char * const *parent_names,
> + unsigned int num_parents, u8 bus_id);
> +
> +struct clk *
> +at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name,
> + u32 frequency, u32 accuracy);
> +struct clk *
> +at91_clk_register_main_osc(struct regmap *regmap, const char *name,
> + const char *parent_name, bool bypass);
> +struct clk *
> +at91_clk_register_rm9200_main(struct regmap *regmap,
> + const char *name,
> + const char *parent_name);
> +struct clk *
> +at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name,
> + const char **parent_names, int num_parents);
> +
> +struct clk *
> +at91_clk_register_master(struct regmap *regmap, const char *name,
> + int num_parents, const char **parent_names,
> + const struct clk_master_layout *layout,
> + const struct clk_master_characteristics *characteristics);
> +
> +struct clk *
> +at91_clk_register_peripheral(struct regmap *regmap, const char *name,
> + const char *parent_name, u32 id);
> +struct clk *
> +at91_clk_register_sam9x5_peripheral(struct regmap *regmap,
> + const char *name, const char *parent_name,
> + u32 id, const struct clk_range *range);
> +
> +struct clk *
> +at91_clk_register_pll(struct regmap *regmap, const char *name,
> + const char *parent_name, u8 id,
> + const struct clk_pll_layout *layout,
> + const struct clk_pll_characteristics *characteristics);
> +struct clk *
> +at91_clk_register_plldiv(struct regmap *regmap, const char *name,
> + const char *parent_name);
> +
> +struct clk *
> +at91_clk_register_programmable(struct regmap *regmap, const char *name,
> + const char **parent_names, u8 num_parents, u8 id,
> + const struct clk_programmable_layout *layout);
> +
> +struct clk *
> +at91_clk_register_sam9260_slow(struct regmap *regmap,
> + const char *name,
> + const char **parent_names,
> + int num_parents);
> +
> +struct clk *
> +at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
> + const char **parent_names, u8 num_parents);
> +
> +struct clk *
> +at91_clk_register_system(struct regmap *regmap, const char *name,
> + const char *parent_name, u8 id);
> +
> +struct clk *
> +at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
> + const char **parent_names, u8 num_parents);
> +struct clk *
> +at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
> + const char *parent_name);
> +struct clk *
> +at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
> + const char *parent_name, const u32 *divisors);
> +
> +struct clk *
> +at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
> + const char *name, const char *parent_name);
> +
> +#ifdef CONFIG_PM
> +void pmc_register_id(u8 id);
> +void pmc_register_pck(u8 pck);
> +#else
> +static inline void pmc_register_id(u8 id) {}
> +static inline void pmc_register_pck(u8 pck) {}
> +#endif
> +
> #endif /* __PMC_H_ */
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 978a0a8a9..20498574f 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -385,6 +385,11 @@ int of_clk_add_provider(struct device_node *np,
> struct clk *(*clk_src_get)(struct of_phandle_args *args,
> void *data),
> void *data);
> +
> +static inline unsigned int clk_get_num_parents(const struct clk *hw)
> +{
> + return hw->num_parents;
> +}
> #else
>
>
> @@ -430,6 +435,8 @@ static inline int of_clk_add_provider(struct device_node *np,
> }
> #endif
>
> +#define CLK_OF_DECLARE_DRIVER(name, compat, fn) CLK_OF_DECLARE(name, compat, fn)
> +
> struct string_list;
>
> int clk_name_complete(struct string_list *sl, char *instr);
> diff --git a/include/soc/at91/atmel-sfr.h b/include/soc/at91/atmel-sfr.h
> new file mode 100644
> index 000000000..482337af0
> --- /dev/null
> +++ b/include/soc/at91/atmel-sfr.h
> @@ -0,0 +1,34 @@
> +/*
> + * Atmel SFR (Special Function Registers) register offsets and bit definitions.
> + *
> + * Copyright (C) 2016 Atmel
> + *
> + * Author: Ludovic Desroches <ludovic.desroches@atmel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef _LINUX_MFD_SYSCON_ATMEL_SFR_H
> +#define _LINUX_MFD_SYSCON_ATMEL_SFR_H
> +
> +#define AT91_SFR_DDRCFG 0x04 /* DDR Configuration Register */
> +/* 0x08 ~ 0x0c: Reserved */
> +#define AT91_SFR_OHCIICR 0x10 /* OHCI INT Configuration Register */
> +#define AT91_SFR_OHCIISR 0x14 /* OHCI INT Status Register */
> +#define AT91_SFR_UTMICKTRIM 0x30 /* UTMI Clock Trimming Register */
> +#define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */
> +
> +/* Field definitions */
> +#define AT91_OHCIICR_SUSPEND_A BIT(8)
> +#define AT91_OHCIICR_SUSPEND_B BIT(9)
> +#define AT91_OHCIICR_SUSPEND_C BIT(10)
> +
> +#define AT91_OHCIICR_USB_SUSPEND (AT91_OHCIICR_SUSPEND_A | \
> + AT91_OHCIICR_SUSPEND_B | \
> + AT91_OHCIICR_SUSPEND_C)
> +
> +#define AT91_UTMICKTRIM_FREQ GENMASK(1, 0)
> +
> +#endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH] fixup! clk: at91: update to PMC bindings
2019-02-19 7:50 ` Ahmad Fatoum
@ 2019-02-19 7:52 ` Ahmad Fatoum
2019-02-19 8:02 ` [PATCH] regmap: Implement syscon_regmap_lookup_by_compatible() Ahmad Fatoum
2019-02-19 10:04 ` [PATCH] fixup! clk: at91: update to PMC bindings Sam Ravnborg
0 siblings, 2 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-02-19 7:52 UTC (permalink / raw)
To: sam; +Cc: barebox
As the sama5d3 based microchip-ksz9477-evb board still uses the old
bindings, the dt-compat.c code is ported as well. This can be removed
when all in-kernel at91 boards have been ported to the new bindings.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/clk/at91/Makefile | 2 +-
drivers/clk/at91/dt-compat.c | 961 +++++++++++++++++++++++++++++++++++
2 files changed, 962 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/at91/dt-compat.c
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index ec41c15fa5f4..f8935129101c 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -2,7 +2,7 @@
# Makefile for at91 specific clk
#
-obj-y += pmc.o sckc.o
+obj-y += pmc.o sckc.o dt-compat.o
obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
obj-y += clk-system.o clk-peripheral.o clk-programmable.o
diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c
new file mode 100644
index 000000000000..bbd670641bba
--- /dev/null
+++ b/drivers/clk/at91/dt-compat.c
@@ -0,0 +1,961 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <of.h>
+#include <driver.h>
+#include <regmap.h>
+#include <mfd/syscon.h>
+
+
+#include "pmc.h"
+
+#define MASTER_SOURCE_MAX 4
+
+#define PERIPHERAL_AT91RM9200 0
+#define PERIPHERAL_AT91SAM9X5 1
+
+#define PERIPHERAL_MAX 64
+
+#define PERIPHERAL_ID_MIN 2
+
+#define PROG_SOURCE_MAX 5
+#define PROG_ID_MAX 7
+
+#define SYSTEM_MAX_ID 31
+
+#ifdef CONFIG_HAVE_AT91_AUDIO_PLL
+static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
+ "atmel,sama5d2-clk-audio-pll-frac",
+ of_sama5d2_clk_audio_pll_frac_setup);
+
+static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
+ "atmel,sama5d2-clk-audio-pll-pad",
+ of_sama5d2_clk_audio_pll_pad_setup);
+
+static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
+ "atmel,sama5d2-clk-audio-pll-pmc",
+ of_sama5d2_clk_audio_pll_pmc_setup);
+#endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
+
+#ifdef CONFIG_HAVE_AT91_GENERATED_CLK
+#define GENERATED_SOURCE_MAX 6
+
+#define GCK_ID_I2S0 54
+#define GCK_ID_I2S1 55
+#define GCK_ID_CLASSD 59
+
+static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
+{
+ int num;
+ u32 id;
+ const char *name;
+ struct clk *hw;
+ unsigned int num_parents;
+ const char *parent_names[GENERATED_SOURCE_MAX];
+ struct device_node *gcknp;
+ struct clk_range range = CLK_RANGE(0, 0);
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+
+ num = of_get_child_count(np);
+ if (!num || num > PERIPHERAL_MAX)
+ return;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ for_each_child_of_node(np, gcknp) {
+ bool pll_audio = false;
+
+ if (of_property_read_u32(gcknp, "reg", &id))
+ continue;
+
+ if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = gcknp->name;
+
+ of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
+ &range);
+
+ if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") &&
+ (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 ||
+ id == GCK_ID_CLASSD))
+ pll_audio = true;
+
+ hw = at91_clk_register_generated(regmap, name,
+ parent_names, num_parents,
+ id, pll_audio, &range);
+ if (IS_ERR(hw))
+ continue;
+
+ of_clk_add_provider(gcknp, of_clk_src_simple_get, hw);
+ }
+}
+CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
+ of_sama5d2_clk_generated_setup);
+#endif /* CONFIG_HAVE_AT91_GENERATED_CLK */
+
+#ifdef CONFIG_HAVE_AT91_H32MX
+static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ hw = at91_clk_register_h32mx(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
+ of_sama5d4_clk_h32mx_setup);
+#endif /* CONFIG_HAVE_AT91_H32MX */
+
+#ifdef CONFIG_HAVE_AT91_I2S_MUX_CLK
+#define I2S_BUS_NR 2
+
+static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
+{
+ struct regmap *regmap_sfr;
+ u8 bus_id;
+ const char *parent_names[2];
+ struct device_node *i2s_mux_np;
+ struct clk *hw;
+ int ret;
+
+ regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+ if (IS_ERR(regmap_sfr))
+ return;
+
+ for_each_child_of_node(np, i2s_mux_np) {
+ if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
+ continue;
+
+ if (bus_id > I2S_BUS_NR)
+ continue;
+
+ ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
+ if (ret != 2)
+ continue;
+
+ hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
+ parent_names, 2, bus_id);
+ if (IS_ERR(hw))
+ continue;
+
+ of_clk_add_provider(i2s_mux_np, of_clk_src_simple_get, hw);
+ }
+}
+CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
+ of_sama5d2_clk_i2s_mux_setup);
+#endif /* CONFIG_HAVE_AT91_I2S_MUX_CLK */
+
+static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *name = np->name;
+ const char *parent_name;
+ struct regmap *regmap;
+ bool bypass;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ bypass = of_property_read_bool(np, "atmel,osc-bypass");
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
+ of_at91rm9200_clk_main_osc_setup);
+
+static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
+{
+ struct clk *hw;
+ u32 frequency = 0;
+ u32 accuracy = 0;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ of_property_read_string(np, "clock-output-names", &name);
+ of_property_read_u32(np, "clock-frequency", &frequency);
+ of_property_read_u32(np, "clock-accuracy", &accuracy);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
+ of_at91sam9x5_clk_main_rc_osc_setup);
+
+static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_name;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
+ of_at91rm9200_clk_main_setup);
+
+static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_names[2];
+ unsigned int num_parents;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents == 0 || num_parents > 2)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
+ of_at91sam9x5_clk_main_setup);
+
+static struct clk_master_characteristics * __init
+of_at91_clk_master_get_characteristics(struct device_node *np)
+{
+ struct clk_master_characteristics *characteristics;
+
+ characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
+ if (!characteristics)
+ return NULL;
+
+ if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
+ goto out_free_characteristics;
+
+ of_property_read_u32_array(np, "atmel,clk-divisors",
+ characteristics->divisors, 4);
+
+ characteristics->have_div3_pres =
+ of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
+
+ return characteristics;
+
+out_free_characteristics:
+ kfree(characteristics);
+ return NULL;
+}
+
+static void __init
+of_at91_clk_master_setup(struct device_node *np,
+ const struct clk_master_layout *layout)
+{
+ struct clk *hw;
+ unsigned int num_parents;
+ const char *parent_names[MASTER_SOURCE_MAX];
+ const char *name = np->name;
+ struct clk_master_characteristics *characteristics;
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ characteristics = of_at91_clk_master_get_characteristics(np);
+ if (!characteristics)
+ return;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91_clk_register_master(regmap, name, num_parents,
+ parent_names, layout,
+ characteristics);
+ if (IS_ERR(hw))
+ goto out_free_characteristics;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+ return;
+
+out_free_characteristics:
+ kfree(characteristics);
+}
+
+static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
+{
+ of_at91_clk_master_setup(np, &at91rm9200_master_layout);
+}
+CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
+ of_at91rm9200_clk_master_setup);
+
+static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
+{
+ of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
+ of_at91sam9x5_clk_master_setup);
+
+static void __init
+of_at91_clk_periph_setup(struct device_node *np, u8 type)
+{
+ int num;
+ u32 id;
+ struct clk *hw;
+ const char *parent_name;
+ const char *name;
+ struct device_node *periphclknp;
+ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+ return;
+
+ num = of_get_child_count(np);
+ if (!num || num > PERIPHERAL_MAX)
+ return;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ for_each_child_of_node(np, periphclknp) {
+ if (of_property_read_u32(periphclknp, "reg", &id))
+ continue;
+
+ if (id >= PERIPHERAL_MAX)
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = periphclknp->name;
+
+ if (type == PERIPHERAL_AT91RM9200) {
+ hw = at91_clk_register_peripheral(regmap, name,
+ parent_name, id);
+ } else {
+ struct clk_range range = CLK_RANGE(0, 0);
+
+ of_at91_get_clk_range(periphclknp,
+ "atmel,clk-output-range",
+ &range);
+
+ hw = at91_clk_register_sam9x5_peripheral(regmap,
+ name,
+ parent_name,
+ id, &range);
+ }
+
+ if (IS_ERR(hw))
+ continue;
+
+ of_clk_add_provider(periphclknp, of_clk_src_simple_get, hw);
+ }
+}
+
+static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
+{
+ of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
+}
+CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
+ of_at91rm9200_clk_periph_setup);
+
+static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
+{
+ of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
+ of_at91sam9x5_clk_periph_setup);
+
+static struct clk_pll_characteristics * __init
+of_at91_clk_pll_get_characteristics(struct device_node *np)
+{
+ int i;
+ int offset;
+ u32 tmp;
+ int num_output;
+ u32 num_cells;
+ struct clk_range input;
+ struct clk_range *output;
+ u8 *out = NULL;
+ u16 *icpll = NULL;
+ struct clk_pll_characteristics *characteristics;
+
+ if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
+ return NULL;
+
+ if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
+ &num_cells))
+ return NULL;
+
+ if (num_cells < 2 || num_cells > 4)
+ return NULL;
+
+ if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
+ return NULL;
+ num_output = tmp / (sizeof(u32) * num_cells);
+
+ characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
+ if (!characteristics)
+ return NULL;
+
+ output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
+ if (!output)
+ goto out_free_characteristics;
+
+ if (num_cells > 2) {
+ out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
+ if (!out)
+ goto out_free_output;
+ }
+
+ if (num_cells > 3) {
+ icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
+ if (!icpll)
+ goto out_free_output;
+ }
+
+ for (i = 0; i < num_output; i++) {
+ offset = i * num_cells;
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset, &tmp))
+ goto out_free_output;
+ output[i].min = tmp;
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset + 1, &tmp))
+ goto out_free_output;
+ output[i].max = tmp;
+
+ if (num_cells == 2)
+ continue;
+
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset + 2, &tmp))
+ goto out_free_output;
+ out[i] = tmp;
+
+ if (num_cells == 3)
+ continue;
+
+ if (of_property_read_u32_index(np,
+ "atmel,pll-clk-output-ranges",
+ offset + 3, &tmp))
+ goto out_free_output;
+ icpll[i] = tmp;
+ }
+
+ characteristics->input = input;
+ characteristics->num_output = num_output;
+ characteristics->output = output;
+ characteristics->out = out;
+ characteristics->icpll = icpll;
+ return characteristics;
+
+out_free_output:
+ kfree(icpll);
+ kfree(out);
+ kfree(output);
+out_free_characteristics:
+ kfree(characteristics);
+ return NULL;
+}
+
+static void __init
+of_at91_clk_pll_setup(struct device_node *np,
+ const struct clk_pll_layout *layout)
+{
+ u32 id;
+ struct clk *hw;
+ struct regmap *regmap;
+ const char *parent_name;
+ const char *name = np->name;
+ struct clk_pll_characteristics *characteristics;
+
+ if (of_property_read_u32(np, "reg", &id))
+ return;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ characteristics = of_at91_clk_pll_get_characteristics(np);
+ if (!characteristics)
+ return;
+
+ hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
+ characteristics);
+ if (IS_ERR(hw))
+ goto out_free_characteristics;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+ return;
+
+out_free_characteristics:
+ kfree(characteristics);
+}
+
+static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
+{
+ of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
+}
+CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
+ of_at91rm9200_clk_pll_setup);
+
+static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
+{
+ of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
+}
+CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
+ of_at91sam9g45_clk_pll_setup);
+
+static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
+{
+ of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
+}
+CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
+ of_at91sam9g20_clk_pllb_setup);
+
+static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
+{
+ of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
+}
+CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
+ of_sama5d3_clk_pll_setup);
+
+static void __init
+of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_name;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91_clk_register_plldiv(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
+ of_at91sam9x5_clk_plldiv_setup);
+
+static void __init
+of_at91_clk_prog_setup(struct device_node *np,
+ const struct clk_programmable_layout *layout)
+{
+ int num;
+ u32 id;
+ struct clk *hw;
+ unsigned int num_parents;
+ const char *parent_names[PROG_SOURCE_MAX];
+ const char *name;
+ struct device_node *progclknp;
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+
+ num = of_get_child_count(np);
+ if (!num || num > (PROG_ID_MAX + 1))
+ return;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ for_each_child_of_node(np, progclknp) {
+ if (of_property_read_u32(progclknp, "reg", &id))
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = progclknp->name;
+
+ hw = at91_clk_register_programmable(regmap, name,
+ parent_names, num_parents,
+ id, layout);
+ if (IS_ERR(hw))
+ continue;
+
+ of_clk_add_provider(progclknp, of_clk_src_simple_get, hw);
+ }
+}
+
+static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
+{
+ of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
+}
+CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
+ of_at91rm9200_clk_prog_setup);
+
+static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
+{
+ of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
+}
+CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
+ of_at91sam9g45_clk_prog_setup);
+
+static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
+{
+ of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
+ of_at91sam9x5_clk_prog_setup);
+
+static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_names[2];
+ unsigned int num_parents;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents != 2)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
+ of_at91sam9260_clk_slow_setup);
+
+#ifdef CONFIG_HAVE_AT91_SMD
+#define SMD_SOURCE_MAX 2
+
+static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
+{
+ struct clk *hw;
+ unsigned int num_parents;
+ const char *parent_names[SMD_SOURCE_MAX];
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
+ of_at91sam9x5_clk_smd_setup);
+#endif /* CONFIG_HAVE_AT91_SMD */
+
+static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
+{
+ int num;
+ u32 id;
+ struct clk *hw;
+ const char *name;
+ struct device_node *sysclknp;
+ const char *parent_name;
+ struct regmap *regmap;
+
+ num = of_get_child_count(np);
+ if (num > (SYSTEM_MAX_ID + 1))
+ return;
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ for_each_child_of_node(np, sysclknp) {
+ if (of_property_read_u32(sysclknp, "reg", &id))
+ continue;
+
+ if (of_property_read_string(np, "clock-output-names", &name))
+ name = sysclknp->name;
+
+ parent_name = of_clk_get_parent_name(sysclknp, 0);
+
+ hw = at91_clk_register_system(regmap, name, parent_name, id);
+ if (IS_ERR(hw))
+ continue;
+
+ of_clk_add_provider(sysclknp, of_clk_src_simple_get, hw);
+ }
+}
+CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
+ of_at91rm9200_clk_sys_setup);
+
+#ifdef CONFIG_HAVE_AT91_USB_CLK
+#define USB_SOURCE_MAX 2
+
+static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
+{
+ struct clk *hw;
+ unsigned int num_parents;
+ const char *parent_names[USB_SOURCE_MAX];
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ num_parents = of_clk_get_parent_count(np);
+ if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
+ return;
+
+ of_clk_parent_fill(np, parent_names, num_parents);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
+ num_parents);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
+ of_at91sam9x5_clk_usb_setup);
+
+static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_name;
+ const char *name = np->name;
+ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
+ hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
+ of_at91sam9n12_clk_usb_setup);
+
+static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_name;
+ const char *name = np->name;
+ u32 divisors[4] = {0, 0, 0, 0};
+ struct regmap *regmap;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+ if (!parent_name)
+ return;
+
+ of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
+ if (!divisors[0])
+ return;
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+ hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
+ of_at91rm9200_clk_usb_setup);
+#endif /* CONFIG_HAVE_AT91_USB_CLK */
+
+#ifdef CONFIG_HAVE_AT91_UTMI
+static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
+{
+ struct clk *hw;
+ const char *parent_name;
+ const char *name = np->name;
+ struct regmap *regmap_pmc, *regmap_sfr;
+
+ parent_name = of_clk_get_parent_name(np, 0);
+
+ of_property_read_string(np, "clock-output-names", &name);
+
+ regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap_pmc))
+ return;
+
+ /*
+ * If the device supports different mainck rates, this value has to be
+ * set in the UTMI Clock Trimming register.
+ * - 9x5: mainck supports several rates but it is indicated that a
+ * 12 MHz is needed in case of USB.
+ * - sama5d3 and sama5d2: mainck supports several rates. Configuring
+ * the FREQ field of the UTMI Clock Trimming register is mandatory.
+ * - sama5d4: mainck is at 12 MHz.
+ *
+ * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
+ */
+ regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
+ if (IS_ERR(regmap_sfr)) {
+ regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
+ if (IS_ERR(regmap_sfr))
+ regmap_sfr = NULL;
+ }
+
+ hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
+ if (IS_ERR(hw))
+ return;
+
+ of_clk_add_provider(np, of_clk_src_simple_get, hw);
+}
+CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
+ of_at91sam9x5_clk_utmi_setup);
+#endif /* CONFIG_HAVE_AT91_UTMI */
--
2.20.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH] regmap: Implement syscon_regmap_lookup_by_compatible()
2019-02-19 7:52 ` [PATCH] fixup! " Ahmad Fatoum
@ 2019-02-19 8:02 ` Ahmad Fatoum
2019-02-19 10:04 ` [PATCH] fixup! clk: at91: update to PMC bindings Sam Ravnborg
1 sibling, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-02-19 8:02 UTC (permalink / raw)
To: sam; +Cc: barebox
Implement syscon_regmap_lookup_by_compatible() to simplify porting kernel code.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Forgot to send this one first. Should be applied prior to the fixed up commit.
drivers/mfd/syscon.c | 14 ++++++++++++++
include/mfd/syscon.h | 5 +++++
2 files changed, 19 insertions(+)
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index 30ed65f73700..b1ff1b1eac5e 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -160,6 +160,20 @@ struct regmap *syscon_node_to_regmap(struct device_node *np)
return syscon->regmap;
}
+struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
+{
+ struct device_node *syscon_np;
+ struct regmap *regmap;
+
+ syscon_np = of_find_compatible_node(NULL, NULL, s);
+ if (!syscon_np)
+ return ERR_PTR(-ENODEV);
+
+ regmap = syscon_node_to_regmap(syscon_np);
+
+ return regmap;
+}
+
static int syscon_probe(struct device_d *dev)
{
struct syscon *syscon;
diff --git a/include/mfd/syscon.h b/include/mfd/syscon.h
index 63b893e4aee7..902f9fa2f339 100644
--- a/include/mfd/syscon.h
+++ b/include/mfd/syscon.h
@@ -21,6 +21,7 @@ void __iomem *syscon_base_lookup_by_pdevname(const char *s);
void __iomem *syscon_base_lookup_by_phandle
(struct device_node *np, const char *property);
struct regmap *syscon_node_to_regmap(struct device_node *np);
+struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
#else
static inline void __iomem *syscon_base_lookup_by_pdevname(const char *s)
{
@@ -37,6 +38,10 @@ static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
{
return ERR_PTR(-ENOSYS);
}
+static inline struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
+{
+ return ERR_PTR(-ENOSYS);
+}
#endif
#endif
--
2.20.1
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] fixup! clk: at91: update to PMC bindings
2019-02-19 7:52 ` [PATCH] fixup! " Ahmad Fatoum
2019-02-19 8:02 ` [PATCH] regmap: Implement syscon_regmap_lookup_by_compatible() Ahmad Fatoum
@ 2019-02-19 10:04 ` Sam Ravnborg
2019-02-19 11:14 ` Ahmad Fatoum
1 sibling, 1 reply; 15+ messages in thread
From: Sam Ravnborg @ 2019-02-19 10:04 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
Hi Ahmad.
On Tue, Feb 19, 2019 at 08:52:39AM +0100, Ahmad Fatoum wrote:
> As the sama5d3 based microchip-ksz9477-evb board still uses the old
> bindings, the dt-compat.c code is ported as well. This can be removed
> when all in-kernel at91 boards have been ported to the new bindings.
Thanks.
I see we need this for now.
I hope someone we get around and add support for new clock bindings to sama5d3 soon.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> drivers/clk/at91/Makefile | 2 +-
> drivers/clk/at91/dt-compat.c | 961 +++++++++++++++++++++++++++++++++++
> 2 files changed, 962 insertions(+), 1 deletion(-)
> create mode 100644 drivers/clk/at91/dt-compat.c
>
> diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
> index ec41c15fa5f4..f8935129101c 100644
> --- a/drivers/clk/at91/Makefile
> +++ b/drivers/clk/at91/Makefile
> @@ -2,7 +2,7 @@
> # Makefile for at91 specific clk
> #
>
> -obj-y += pmc.o sckc.o
> +obj-y += pmc.o sckc.o dt-compat.o
To avoid increasing the image size further we could introduce a SOC_SAMA5D3
and let this .o file depends on this.
?
I can fix it while applying if you agree.
Sam
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] fixup! clk: at91: update to PMC bindings
2019-02-19 10:04 ` [PATCH] fixup! clk: at91: update to PMC bindings Sam Ravnborg
@ 2019-02-19 11:14 ` Ahmad Fatoum
0 siblings, 0 replies; 15+ messages in thread
From: Ahmad Fatoum @ 2019-02-19 11:14 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: barebox
On 19/2/19 11:04, Sam Ravnborg wrote:
> Hi Ahmad.
>
> On Tue, Feb 19, 2019 at 08:52:39AM +0100, Ahmad Fatoum wrote:
>> As the sama5d3 based microchip-ksz9477-evb board still uses the old
>> bindings, the dt-compat.c code is ported as well. This can be removed
>> when all in-kernel at91 boards have been ported to the new bindings.
>
> Thanks.
> I see we need this for now.
> I hope someone we get around and add support for new clock bindings to sama5d3 soon.
>
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> drivers/clk/at91/Makefile | 2 +-
>> drivers/clk/at91/dt-compat.c | 961 +++++++++++++++++++++++++++++++++++
>> 2 files changed, 962 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/clk/at91/dt-compat.c
>>
>> diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
>> index ec41c15fa5f4..f8935129101c 100644
>> --- a/drivers/clk/at91/Makefile
>> +++ b/drivers/clk/at91/Makefile
>> @@ -2,7 +2,7 @@
>> # Makefile for at91 specific clk
>> #
>>
>> -obj-y += pmc.o sckc.o
>> +obj-y += pmc.o sckc.o dt-compat.o
> To avoid increasing the image size further we could introduce a SOC_SAMA5D3
> and let this .o file depends on this.
> ?
>
> I can fix it while applying if you agree.
Agreed. That's a good idea.
>
> Sam
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2019-02-19 11:14 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-18 19:47 [PATCH v3 0/9] at91: Support PMC clock bindings Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 1/9] arm: at91: fix at91_configure_usart6 warning Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 2/9] clocksource: Do not mix depends and select for ATMEL_PIT Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 3/9] arm: at91: add SOC_SAMA5{D3,D4} Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 4/9] clk: at91: add at91sam9260 Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 5/9] clk: at91: add at91sam9rl Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 6/9] clk: at91: add at91sam9x5 Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 7/9] clk: at91: add sama5d2 Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 8/9] clk: at91: add sama5d4 Sam Ravnborg
2019-02-18 19:47 ` [PATCH v3 9/9] clk: at91: update to PMC bindings Sam Ravnborg
2019-02-19 7:50 ` Ahmad Fatoum
2019-02-19 7:52 ` [PATCH] fixup! " Ahmad Fatoum
2019-02-19 8:02 ` [PATCH] regmap: Implement syscon_regmap_lookup_by_compatible() Ahmad Fatoum
2019-02-19 10:04 ` [PATCH] fixup! clk: at91: update to PMC bindings Sam Ravnborg
2019-02-19 11:14 ` Ahmad Fatoum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox