* [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board
@ 2025-03-17 6:56 Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 1/8] dt-bindings: drop at91.h from clock includes Manikandan Muralidharan
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m
This patch series adds support for the new SoC family - sam9x7.
- sam9x7 SoC is added
- Clock driver for sam9x7 is added
- Target board SAM9X75 Curiosity is added with its differences in DT
and MMC config support
----
changes in v4:
- 1/8 - Drop the local include file clock/at91.h and the update
the MAINTAINERS respectively.
changes in v3:
- 1/8 - rename at91.h to at91-pmc-status.h, update the SoC DTs
and MAINTAINERS file respectively
- 4/8 - update header from clk/at91.h to clock/at91.h
changes in v2:
- 1/8 - add additional PMC clock definition to support the sam9x7 upstream DT
- 6/8 - Remove support for SoC DT and board DTS as they are already available
in dts/upstream
- add the differences in DT files between upstream Linux DT and U-Boot DT to
at91-sam9x75_curiosity-u-boot.dtsi
- 7/8 - Add OF_UPSTREAM support for sam9x75 curiosity board
- 8/8 - update the DEFAULT_DEVICE_TREE config to <vendor/name>
----
Manikandan Muralidharan (4):
dt-bindings: drop at91.h from clock includes
ARM: dts: at91: sam9x75_curiosity: add tweaks for sam9x75 curiosity
board
board: sam9x75_curiosity: Add support for sam9x75 curiosity
configs: sam9x75_curiosity: Add initial mmc default config
Varshini Rajendran (4):
clk: at91: sam9x60-pll: add support for core clock frequency inputs
clk: at91: sam9x60-pll: add support for HW PLL freq dividers
clk: at91: sam9x7: add pmc driver for sam9x7 SoC family
ARM: at91: Add sam9x7 soc
MAINTAINERS | 1 -
.../dts/at91-sam9x75_curiosity-u-boot.dtsi | 107 ++
arch/arm/mach-at91/Kconfig | 12 +
arch/arm/mach-at91/arm926ejs/Makefile | 1 +
arch/arm/mach-at91/arm926ejs/sam9x7_devices.c | 49 +
arch/arm/mach-at91/include/mach/hardware.h | 2 +
arch/arm/mach-at91/include/mach/sam9x7.h | 172 +++
board/atmel/sam9x75_curiosity/Kconfig | 15 +
board/atmel/sam9x75_curiosity/MAINTAINERS | 7 +
board/atmel/sam9x75_curiosity/Makefile | 7 +
.../sam9x75_curiosity/sam9x75_curiosity.c | 66 +
configs/sam9x75_curiosity_mmc_defconfig | 73 ++
drivers/clk/at91/Makefile | 1 +
drivers/clk/at91/clk-sam9x60-pll.c | 55 +-
drivers/clk/at91/pmc.h | 2 +
drivers/clk/at91/sam9x60.c | 7 +
drivers/clk/at91/sam9x7.c | 1094 +++++++++++++++++
drivers/clk/at91/sama7g5.c | 6 +
include/configs/sam9x75_curiosity.h | 23 +
include/dt-bindings/clock/at91.h | 23 -
20 files changed, 1689 insertions(+), 34 deletions(-)
create mode 100644 arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
create mode 100644 arch/arm/mach-at91/arm926ejs/sam9x7_devices.c
create mode 100644 arch/arm/mach-at91/include/mach/sam9x7.h
create mode 100644 board/atmel/sam9x75_curiosity/Kconfig
create mode 100644 board/atmel/sam9x75_curiosity/MAINTAINERS
create mode 100644 board/atmel/sam9x75_curiosity/Makefile
create mode 100644 board/atmel/sam9x75_curiosity/sam9x75_curiosity.c
create mode 100644 configs/sam9x75_curiosity_mmc_defconfig
create mode 100644 drivers/clk/at91/sam9x7.c
create mode 100644 include/configs/sam9x75_curiosity.h
delete mode 100644 include/dt-bindings/clock/at91.h
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/8] dt-bindings: drop at91.h from clock includes
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 2/8] clk: at91: sam9x60-pll: add support for core clock frequency inputs Manikandan Muralidharan
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m
Remove clock/at91.h file as it is subset of
dts/upstream/include/dt-bindings/clock/at91.h.
The constants defined in this header are being used only in dts
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
MAINTAINERS | 1 -
include/dt-bindings/clock/at91.h | 23 -----------------------
2 files changed, 24 deletions(-)
delete mode 100644 include/dt-bindings/clock/at91.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 10f7f1fd180..9322bc542e9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -464,7 +464,6 @@ F: drivers/memory/atmel-ebi.c
F: drivers/misc/microchip_flexcom.c
F: drivers/timer/atmel_tcb_timer.c
F: include/dt-bindings/clk/at91.h
-F: include/dt-bindings/clock/at91.h
F: include/dt-bindings/dma/at91.h
F: include/dt-bindings/mfd/at91-usart.h
F: include/dt-bindings/mfd/atmel-flexcom.h
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
deleted file mode 100644
index ab3ee241d10..00000000000
--- a/include/dt-bindings/clock/at91.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This header provides constants for AT91 pmc status.
- *
- * The constants defined in this header are being used in dts.
- *
- * Licensed under GPLv2 or later.
- */
-
-#ifndef _DT_BINDINGS_CLK_AT91_H
-#define _DT_BINDINGS_CLK_AT91_H
-
-#define AT91_PMC_MOSCS 0 /* MOSCS Flag */
-#define AT91_PMC_LOCKA 1 /* PLLA Lock */
-#define AT91_PMC_LOCKB 2 /* PLLB Lock */
-#define AT91_PMC_MCKRDY 3 /* Master Clock */
-#define AT91_PMC_LOCKU 6 /* UPLL Lock */
-#define AT91_PMC_PCKRDY(id) (8 + (id)) /* Programmable Clock */
-#define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */
-#define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */
-#define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */
-#define AT91_PMC_GCKRDY 24 /* Generated Clocks */
-
-#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/8] clk: at91: sam9x60-pll: add support for core clock frequency inputs
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 1/8] dt-bindings: drop at91.h from clock includes Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 3/8] clk: at91: sam9x60-pll: add support for HW PLL freq dividers Manikandan Muralidharan
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m, Varshini Rajendran
From: Varshini Rajendran <varshini.rajendran@microchip.com>
Add support for different core clock frequency input ranges
for different PLL IDs in the PLL driver and align sam9x60, sama7g5 SOC
platforms.
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
---
drivers/clk/at91/clk-sam9x60-pll.c | 17 ++++++++---------
drivers/clk/at91/pmc.h | 1 +
drivers/clk/at91/sam9x60.c | 7 +++++++
drivers/clk/at91/sama7g5.c | 6 ++++++
4 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index a30035eb8ce..676ad8294a6 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -31,9 +31,6 @@
#define UPLL_DIV 2
#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
-#define FCORE_MIN (600000000)
-#define FCORE_MAX (1200000000)
-
#define PLL_MAX_ID 7
struct sam9x60_pll {
@@ -55,14 +52,15 @@ static inline bool sam9x60_pll_ready(void __iomem *base, int id)
return !!(status & BIT(id));
}
-static long sam9x60_frac_pll_compute_mul_frac(u32 *mul, u32 *frac, ulong rate,
+static long sam9x60_frac_pll_compute_mul_frac(const struct clk_range *core_clk,
+ u32 *mul, u32 *frac, ulong rate,
ulong parent_rate)
{
unsigned long tmprate, remainder;
unsigned long nmul = 0;
unsigned long nfrac = 0;
- if (rate < FCORE_MIN || rate > FCORE_MAX)
+ if (rate < core_clk->min || rate > core_clk->max)
return -ERANGE;
/*
@@ -82,7 +80,7 @@ static long sam9x60_frac_pll_compute_mul_frac(u32 *mul, u32 *frac, ulong rate,
}
/* Check if resulted rate is valid. */
- if (tmprate < FCORE_MIN || tmprate > FCORE_MAX)
+ if (tmprate < core_clk[0].min || tmprate > core_clk[0].max)
return -ERANGE;
*mul = nmul - 1;
@@ -103,8 +101,8 @@ static ulong sam9x60_frac_pll_set_rate(struct clk *clk, ulong rate)
if (!parent_rate)
return 0;
- ret = sam9x60_frac_pll_compute_mul_frac(&nmul, &nfrac, rate,
- parent_rate);
+ ret = sam9x60_frac_pll_compute_mul_frac(pll->characteristics->core_output,
+ &nmul, &nfrac, rate, parent_rate);
if (ret < 0)
return 0;
@@ -163,7 +161,8 @@ static int sam9x60_frac_pll_enable(struct clk *clk)
ulong crate;
crate = sam9x60_frac_pll_get_rate(clk);
- if (crate < FCORE_MIN || crate > FCORE_MAX)
+ if (crate < pll->characteristics->core_output[0].min ||
+ crate > pll->characteristics->core_output[0].max)
return -ERANGE;
pmc_update_bits(base, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index ff464522aa0..49134531564 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -38,6 +38,7 @@ struct clk_pll_characteristics {
struct clk_range input;
int num_output;
const struct clk_range *output;
+ const struct clk_range *core_output;
u16 *icpll;
u8 *out;
u8 upll : 1;
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index b7d64bdbb3d..e04266a2be2 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -112,17 +112,24 @@ static const struct clk_range upll_outputs[] = {
{ .min = 300000000, .max = 500000000 },
};
+/* Fractional PLL core output range. */
+static const struct clk_range core_outputs[] = {
+ { .min = 600000000, .max = 1200000000 },
+};
+
/* PLL characteristics. */
static const struct clk_pll_characteristics apll_characteristics = {
.input = { .min = 12000000, .max = 48000000 },
.num_output = ARRAY_SIZE(plla_outputs),
.output = plla_outputs,
+ .core_output = core_outputs,
};
static const struct clk_pll_characteristics upll_characteristics = {
.input = { .min = 12000000, .max = 48000000 },
.num_output = ARRAY_SIZE(upll_outputs),
.output = upll_outputs,
+ .core_output = core_outputs,
.upll = true,
};
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index 63b2c647467..c0e27828b1a 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -158,11 +158,17 @@ static const struct clk_range pll_outputs[] = {
{ .min = 2343750, .max = 1200000000 },
};
+/* Fractional PLL core output range. */
+static const struct clk_range core_outputs[] = {
+ { .min = 600000000, .max = 1200000000 },
+};
+
/* PLL characteristics. */
static const struct clk_pll_characteristics pll_characteristics = {
.input = { .min = 12000000, .max = 50000000 },
.num_output = ARRAY_SIZE(pll_outputs),
.output = pll_outputs,
+ .core_output = core_outputs,
};
/* Layout for fractional PLLs. */
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/8] clk: at91: sam9x60-pll: add support for HW PLL freq dividers
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 1/8] dt-bindings: drop at91.h from clock includes Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 2/8] clk: at91: sam9x60-pll: add support for core clock frequency inputs Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 4/8] clk: at91: sam9x7: add pmc driver for sam9x7 SoC family Manikandan Muralidharan
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m, Varshini Rajendran
From: Varshini Rajendran <varshini.rajendran@microchip.com>
Add support for hardware dividers for PLL IDs.In sam9x7 SoC,
PLL_ID_PLLA and PLL_ID_PLLA_DIV2 has /2 hardware dividers
each.
fcorepllack -----> HW Div = 2 -+--> fpllack
|
+--> HW Div = 2 ---> fplladiv2ck
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
---
drivers/clk/at91/clk-sam9x60-pll.c | 38 +++++++++++++++++++++++++++++-
drivers/clk/at91/pmc.h | 1 +
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index 676ad8294a6..df8172bccac 100644
--- a/drivers/clk/at91/clk-sam9x60-pll.c
+++ b/drivers/clk/at91/clk-sam9x60-pll.c
@@ -22,6 +22,7 @@
#define UBOOT_DM_CLK_AT91_SAM9X60_DIV_PLL "at91-sam9x60-div-pll-clk"
#define UBOOT_DM_CLK_AT91_SAM9X60_FRAC_PLL "at91-sam9x60-frac-pll-clk"
+#define UBOOT_DM_CLK_AT91_SAM9X60_FIXED_DIV_PLL "at91-sam9x60-fixed-div-pll-clk"
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(31, 24)
@@ -140,6 +141,7 @@ static ulong sam9x60_frac_pll_get_rate(struct clk *clk)
void __iomem *base = pll->base;
ulong parent_rate = clk_get_parent_rate(clk);
u32 mul, frac, val;
+ ulong pll_rate;
if (!parent_rate)
return 0;
@@ -149,8 +151,12 @@ static ulong sam9x60_frac_pll_get_rate(struct clk *clk)
pmc_read(base, AT91_PMC_PLL_CTRL1, &val);
mul = (val & pll->layout->mul_mask) >> pll->layout->mul_shift;
frac = (val & pll->layout->frac_mask) >> pll->layout->frac_shift;
+ pll_rate = (parent_rate * (mul + 1) + ((u64)parent_rate * frac >> 22));
- return (parent_rate * (mul + 1) + ((u64)parent_rate * frac >> 22));
+ if (pll->layout->div2)
+ pll_rate >>= 1;
+
+ return pll_rate;
}
static int sam9x60_frac_pll_enable(struct clk *clk)
@@ -359,6 +365,16 @@ static ulong sam9x60_div_pll_get_rate(struct clk *clk)
return parent_rate / (div + 1);
}
+static ulong sam9x60_fixed_div_pll_get_rate(struct clk *clk)
+{
+ ulong parent_rate = clk_get_parent_rate(clk);
+
+ if (!parent_rate)
+ return 0;
+
+ return parent_rate >> 1;
+}
+
static const struct clk_ops sam9x60_div_pll_ops = {
.enable = sam9x60_div_pll_enable,
.disable = sam9x60_div_pll_disable,
@@ -366,6 +382,12 @@ static const struct clk_ops sam9x60_div_pll_ops = {
.get_rate = sam9x60_div_pll_get_rate,
};
+static const struct clk_ops sam9x60_fixed_div_pll_ops = {
+ .enable = sam9x60_div_pll_enable,
+ .disable = sam9x60_div_pll_disable,
+ .get_rate = sam9x60_fixed_div_pll_get_rate,
+};
+
static struct clk *
sam9x60_clk_register_pll(void __iomem *base, const char *type,
const char *name, const char *parent_name, u8 id,
@@ -406,6 +428,13 @@ sam9x60_clk_register_div_pll(void __iomem *base, const char *name,
const struct clk_pll_characteristics *characteristics,
const struct clk_pll_layout *layout, bool critical)
{
+ if (layout->div2) {
+ return sam9x60_clk_register_pll(base,
+ UBOOT_DM_CLK_AT91_SAM9X60_FIXED_DIV_PLL, name, parent_name,
+ id, characteristics, layout,
+ CLK_GET_RATE_NOCACHE | (critical ? CLK_IS_CRITICAL : 0));
+ }
+
return sam9x60_clk_register_pll(base,
UBOOT_DM_CLK_AT91_SAM9X60_DIV_PLL, name, parent_name, id,
characteristics, layout,
@@ -431,6 +460,13 @@ U_BOOT_DRIVER(at91_sam9x60_div_pll_clk) = {
.flags = DM_FLAG_PRE_RELOC,
};
+U_BOOT_DRIVER(at91_sam9x60_fixed_div_pll_clk) = {
+ .name = UBOOT_DM_CLK_AT91_SAM9X60_FIXED_DIV_PLL,
+ .id = UCLASS_CLK,
+ .ops = &sam9x60_fixed_div_pll_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
U_BOOT_DRIVER(at91_sam9x60_frac_pll_clk) = {
.name = UBOOT_DM_CLK_AT91_SAM9X60_FRAC_PLL,
.id = UCLASS_CLK,
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 49134531564..580c9964ff4 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -54,6 +54,7 @@ struct clk_pll_layout {
u8 frac_shift;
u8 div_shift;
u8 endiv_shift;
+ u8 div2;
};
struct clk_programmable_layout {
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 4/8] clk: at91: sam9x7: add pmc driver for sam9x7 SoC family
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
` (2 preceding siblings ...)
2025-03-17 6:56 ` [PATCH v4 3/8] clk: at91: sam9x60-pll: add support for HW PLL freq dividers Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-18 9:02 ` Eugen Hristev
2025-03-17 6:56 ` [PATCH v4 5/8] ARM: at91: Add sam9x7 soc Manikandan Muralidharan
` (3 subsequent siblings)
7 siblings, 1 reply; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m, Varshini Rajendran, Balamanikandan Gunasundar
From: Varshini Rajendran <varshini.rajendran@microchip.com>
Add PMC driver support for sam9x7 SoC family
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
[balamanikandan.gunasundar@microchip.com: Add peripheral clock id for pmecc]
Signed-off-by: Balamanikandan Gunasundar <balamanikandan.gunasundar@microchip.com>
---
drivers/clk/at91/Makefile | 1 +
drivers/clk/at91/sam9x7.c | 1094 +++++++++++++++++++++++++++++++++++++
2 files changed, 1095 insertions(+)
create mode 100644 drivers/clk/at91/sam9x7.c
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index e53dcb4ca7a..6cca861f81c 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
obj-$(CONFIG_AT91_SAM9X60_USB) += clk-sam9x60-usb.o
obj-$(CONFIG_SAMA7G5) += sama7g5.o
obj-$(CONFIG_SAM9X60) += sam9x60.o
+obj-$(CONFIG_SAM9X7) += sam9x7.o
else
obj-y += compat.o
endif
diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c
new file mode 100644
index 00000000000..b362d2f9858
--- /dev/null
+++ b/drivers/clk/at91/sam9x7.c
@@ -0,0 +1,1094 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Varshini Rajendran <varshini.rajendran@microchip.com>
+ *
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-bindings/clock/at91.h>
+#include <linux/clk-provider.h>
+
+#include "pmc.h"
+
+/**
+ * Clock identifiers to be used in conjunction with macros like
+ * AT91_TO_CLK_ID()
+ *
+ * @ID_MD_SLCK: TD slow clock identifier
+ * @ID_TD_SLCK: MD slow clock identifier
+ * @ID_MAIN_XTAL: Main Xtal clock identifier
+ * @ID_MAIN_RC: Main RC clock identifier
+ * @ID_MAIN_RC_OSC: Main RC Oscillator clock identifier
+ * @ID_MAIN_OSC: Main Oscillator clock identifier
+ * @ID_MAINCK: MAINCK clock identifier
+ * @ID_PLL_U_FRAC: UPLL fractional clock identifier
+ * @ID_PLL_U_DIV: UPLL divider clock identifier
+ * @ID_PLL_A_FRAC: APLL fractional clock identifier
+ * @ID_PLL_A_DIV: APLL divider clock identifier
+ * @ID_PLL_A_2_DIV: PLLA DIV2 divider clock identifier
+ * @ID_PLL_AUDIO_FRAC: Audio PLL fractional clock identifier
+ * @ID_PLL_AUDIO_DIVPMC: Audio PLL divider clock identifier
+ * @ID_PLL_AUDIO_DIVIO: Audio PLL IO divider clock identifier
+ * @ID_PLL_LVDS_FRAC: LVDS PLL fractional clock identifier
+ * @ID_PLL_LVDS_DIV: LVDS PLL divider clock identifier
+
+ * @ID_MCK_DIV: MCK DIV clock identifier
+
+ * @ID_UTMI: UTMI clock identifier
+
+ * @ID_PROG0: Programmable 0 clock identifier
+ * @ID_PROG1: Programmable 1 clock identifier
+
+ * @ID_PCK0: PCK0 system clock identifier
+ * @ID_PCK1: PCK1 system clock identifier
+ * @ID_DDR: DDR system clock identifier
+ * @ID_QSPI: QSPI system clock identifier
+ *
+ * @ID_MCK_PRES: MCK PRES clock identifier
+ *
+ * Note: if changing the values of this enums please sync them with
+ * device tree
+ */
+enum pmc_clk_ids {
+ ID_MD_SLCK = 0,
+ ID_TD_SLCK = 1,
+ ID_MAIN_XTAL = 2,
+ ID_MAIN_RC = 3,
+ ID_MAIN_RC_OSC = 4,
+ ID_MAIN_OSC = 5,
+ ID_MAINCK = 6,
+
+ ID_PLL_U_FRAC = 7,
+ ID_PLL_U_DIV = 8,
+ ID_PLL_A_FRAC = 9,
+ ID_PLL_A_DIV = 10,
+ ID_PLL_A_2_DIV = 11,
+ ID_PLL_AUDIO_FRAC = 12,
+ ID_PLL_AUDIO_DIVPMC = 13,
+ ID_PLL_AUDIO_DIVIO = 14,
+ ID_PLL_LVDS_FRAC = 15,
+ ID_PLL_LVDS_DIV = 16,
+
+ ID_MCK_DIV = 17,
+
+ ID_UTMI = 18,
+
+ ID_PROG0 = 19,
+ ID_PROG1 = 20,
+
+ ID_PCK0 = 21,
+ ID_PCK1 = 22,
+
+ ID_DDR = 23,
+ ID_QSPI = 24,
+
+ ID_MCK_PRES = 25,
+
+ ID_MAX,
+};
+
+/**
+ * PLL type identifiers
+ * @PLL_TYPE_FRAC: fractional PLL identifier
+ * @PLL_TYPE_DIV: divider PLL identifier
+ */
+enum pll_type {
+ PLL_TYPE_FRAC,
+ PLL_TYPE_DIV,
+};
+
+/* Clock names used as parents for multiple clocks. */
+static const char *clk_names[] = {
+ [ID_MAIN_RC_OSC] = "main_rc_osc",
+ [ID_MAIN_OSC] = "main_osc",
+ [ID_MAINCK] = "mainck",
+ [ID_PLL_U_DIV] = "upll_divpmcck",
+ [ID_PLL_A_DIV] = "plla_divpmcck",
+ [ID_PLL_A_2_DIV] = "plla_div2pmcck",
+ [ID_PLL_AUDIO_DIVPMC] = "pll_audio_divpmcck",
+ [ID_PLL_AUDIO_DIVIO] = "pll_audio_diviock",
+ [ID_PLL_LVDS_DIV] = "pll_lvds_divpmcck",
+ [ID_MCK_PRES] = "mck_pres",
+ [ID_MCK_DIV] = "mck_div",
+};
+
+/* Fractional PLL core output range. */
+static const struct clk_range plla_core_outputs[] = {
+ { .min = 800000000, .max = 1600000000 },
+};
+
+static const struct clk_range upll_core_outputs[] = {
+ { .min = 600000000, .max = 960000000 },
+};
+
+static const struct clk_range lvdspll_core_outputs[] = {
+ { .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range audiopll_core_outputs[] = {
+ { .min = 600000000, .max = 1200000000 },
+};
+
+static const struct clk_range plladiv2_core_outputs[] = {
+ { .min = 800000000, .max = 1600000000 },
+};
+
+/* Fractional PLL output range. */
+static const struct clk_range plla_outputs[] = {
+ { .min = 400000000, .max = 800000000 },
+};
+
+static const struct clk_range upll_outputs[] = {
+ { .min = 300000000, .max = 480000000 },
+};
+
+static const struct clk_range lvdspll_outputs[] = {
+ { .min = 175000000, .max = 550000000 },
+};
+
+static const struct clk_range audiopll_outputs[] = {
+ { .min = 0, .max = 300000000 },
+};
+
+static const struct clk_range plladiv2_outputs[] = {
+ { .min = 200000000, .max = 400000000 },
+};
+
+/* PLL characteristics. */
+static const struct clk_pll_characteristics plla_characteristics = {
+ .input = { .min = 20000000, .max = 50000000 },
+ .num_output = ARRAY_SIZE(plla_outputs),
+ .output = plla_outputs,
+ .core_output = plla_core_outputs,
+};
+
+static const struct clk_pll_characteristics upll_characteristics = {
+ .input = { .min = 20000000, .max = 50000000 },
+ .num_output = ARRAY_SIZE(upll_outputs),
+ .output = upll_outputs,
+ .core_output = upll_core_outputs,
+ .upll = true,
+};
+
+static const struct clk_pll_characteristics lvdspll_characteristics = {
+ .input = { .min = 20000000, .max = 50000000 },
+ .num_output = ARRAY_SIZE(lvdspll_outputs),
+ .output = lvdspll_outputs,
+ .core_output = lvdspll_core_outputs,
+};
+
+static const struct clk_pll_characteristics audiopll_characteristics = {
+ .input = { .min = 20000000, .max = 50000000 },
+ .num_output = ARRAY_SIZE(audiopll_outputs),
+ .output = audiopll_outputs,
+ .core_output = audiopll_core_outputs,
+};
+
+static const struct clk_pll_characteristics plladiv2_characteristics = {
+ .input = { .min = 20000000, .max = 50000000 },
+ .num_output = ARRAY_SIZE(plladiv2_outputs),
+ .output = plladiv2_outputs,
+ .core_output = plladiv2_core_outputs,
+};
+
+/* Layout for fractional PLLs. */
+static const struct clk_pll_layout pll_layout_frac = {
+ .mul_mask = GENMASK(31, 24),
+ .frac_mask = GENMASK(21, 0),
+ .mul_shift = 24,
+ .frac_shift = 0,
+};
+
+/* Layout for fractional PLL ID PLLA. */
+static const struct clk_pll_layout plla_layout_frac = {
+ .mul_mask = GENMASK(31, 24),
+ .frac_mask = GENMASK(21, 0),
+ .mul_shift = 24,
+ .frac_shift = 0,
+ .div2 = 1,
+};
+
+/* Layout for DIV PLLs. */
+static const struct clk_pll_layout pll_layout_divpmc = {
+ .div_mask = GENMASK(7, 0),
+ .endiv_mask = BIT(29),
+ .div_shift = 0,
+ .endiv_shift = 29,
+};
+
+/* Layout for DIV PLLs. */
+static const struct clk_pll_layout plladiv2_layout_divpmc = {
+ .div_mask = GENMASK(7, 0),
+ .endiv_mask = BIT(29),
+ .div_shift = 0,
+ .endiv_shift = 29,
+ .div2 = 1,
+};
+
+/* Layout for DIVIO dividers. */
+static const struct clk_pll_layout pll_layout_divio = {
+ .div_mask = GENMASK(19, 12),
+ .endiv_mask = BIT(30),
+ .div_shift = 12,
+ .endiv_shift = 30,
+};
+
+/* MCK characteristics. */
+static const struct clk_master_characteristics mck_characteristics = {
+ .output = { .min = 32000000, .max = 266666666 },
+ .divisors = { 1, 2, 4, 3, 5},
+ .have_div3_pres = 1,
+};
+
+/* MCK layout. */
+static const struct clk_master_layout mck_layout = {
+ .mask = 0x373,
+ .pres_shift = 4,
+ .offset = 0x28,
+};
+
+/* Programmable clock layout. */
+static const struct clk_programmable_layout programmable_layout = {
+ .pres_mask = 0xff,
+ .pres_shift = 8,
+ .css_mask = 0x1f,
+ .have_slck_mck = 0,
+ .is_pres_direct = 1,
+};
+
+/* Peripheral clock layout. */
+static const struct clk_pcr_layout sam9x7_pcr_layout = {
+ .offset = 0x88,
+ .cmd = BIT(31),
+ .gckcss_mask = GENMASK(12, 8),
+ .pid_mask = GENMASK(6, 0),
+};
+
+/**
+ * PLL clocks description
+ * @n: clock name
+ * @p: clock parent
+ * @l: clock layout
+ * @t: clock type
+ * @c: pll characteristics
+ * @f: true if clock is fixed and not changeable by driver
+ * @id: clock id corresponding to PLL driver
+ * @cid: clock id corresponding to clock subsystem
+ */
+static const struct {
+ const char *n;
+ const char *p;
+ const struct clk_pll_layout *l;
+ const struct clk_pll_characteristics *c;
+ u8 t;
+ u8 f;
+ u8 id;
+ u8 cid;
+} sam9x7_plls[] = {
+ {
+ .n = "plla_fracck",
+ .p = "mainck",
+ .l = &plla_layout_frac,
+ .c = &plla_characteristics,
+ .t = PLL_TYPE_FRAC,
+ .f = 1,
+ .id = 0,
+ .cid = ID_PLL_A_FRAC,
+ },
+
+ {
+ .n = "plla_divpmcck",
+ .p = "plla_fracck",
+ .l = &pll_layout_divpmc,
+ .c = &plla_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 0,
+ .cid = ID_PLL_A_DIV,
+ },
+
+ {
+ .n = "upll_fracck",
+ .p = "main_osc",
+ .l = &pll_layout_frac,
+ .c = &upll_characteristics,
+ .t = PLL_TYPE_FRAC,
+ .f = 1,
+ .id = 1,
+ .cid = ID_PLL_U_FRAC,
+ },
+
+ {
+ .n = "upll_divpmcck",
+ .p = "upll_fracck",
+ .l = &pll_layout_divpmc,
+ .c = &upll_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 1,
+ .cid = ID_PLL_U_DIV,
+ },
+
+ {
+ .n = "audiopll_fracck",
+ .p = "main_osc",
+ .l = &pll_layout_frac,
+ .c = &audiopll_characteristics,
+ .t = PLL_TYPE_FRAC,
+ .f = 1,
+ .id = 2,
+ .cid = ID_PLL_AUDIO_FRAC,
+ },
+
+ {
+ .n = "audiopll_divpmcck",
+ .p = "audiopll_fracck",
+ .l = &pll_layout_divpmc,
+ .c = &audiopll_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 2,
+ .cid = ID_PLL_AUDIO_DIVPMC,
+ },
+
+ {
+ .n = "audiopll_diviock",
+ .p = "audiopll_fracck",
+ .l = &pll_layout_divio,
+ .c = &audiopll_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 2,
+ .cid = ID_PLL_AUDIO_DIVIO,
+ },
+
+ {
+ .n = "lvdspll_fracck",
+ .p = "main_osc",
+ .l = &pll_layout_frac,
+ .c = &lvdspll_characteristics,
+ .t = PLL_TYPE_FRAC,
+ .f = 1,
+ .id = 3,
+ .cid = ID_PLL_LVDS_FRAC,
+ },
+
+ {
+ .n = "lvdspll_divpmcck",
+ .p = "lvdspll_fracck",
+ .l = &pll_layout_divpmc,
+ .c = &lvdspll_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 3,
+ .cid = ID_PLL_LVDS_DIV,
+ },
+
+ {
+ .n = "plla_div2pmcck",
+ .p = "plla_fracck",
+ .l = &plladiv2_layout_divpmc,
+ .c = &plladiv2_characteristics,
+ .t = PLL_TYPE_DIV,
+ .f = 1,
+ .id = 4,
+ .cid = ID_PLL_A_2_DIV,
+ },
+
+};
+
+/**
+ * Programmable clock description
+ * @n: clock name
+ * @cid: clock id corresponding to clock subsystem
+ */
+static const struct {
+ const char *n;
+ u8 cid;
+} sam9x7_prog[] = {
+ { .n = "prog0", .cid = ID_PROG0, },
+ { .n = "prog1", .cid = ID_PROG1, },
+};
+
+/* Mux table for programmable clocks. */
+static u32 sam9x7_prog_mux_table[] = { 0, 1, 2, 3, 4, 5, 6, };
+
+/**
+ * System clock description
+ * @n: clock name
+ * @p: parent clock name
+ * @id: clock id corresponding to system clock driver
+ * @cid: clock id corresponding to clock subsystem
+ */
+static const struct {
+ const char *n;
+ const char *p;
+ u8 id;
+ u8 cid;
+} sam9x7_systemck[] = {
+ { .n = "ddrck", .p = "mck_pres", .id = 2, .cid = ID_DDR, },
+ { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, },
+ { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, },
+};
+
+/**
+ * Peripheral clock description
+ * @n: clock name
+ * @id: clock id
+ */
+static const struct {
+ const char *n;
+ u8 id;
+} sam9x7_periphck[] = {
+ { .n = "pioA_clk", .id = 2, },
+ { .n = "pioB_clk", .id = 3, },
+ { .n = "pioC_clk", .id = 4, },
+ { .n = "flex0_clk", .id = 5, },
+ { .n = "flex1_clk", .id = 6, },
+ { .n = "flex2_clk", .id = 7, },
+ { .n = "flex3_clk", .id = 8, },
+ { .n = "flex6_clk", .id = 9, },
+ { .n = "flex7_clk", .id = 10, },
+ { .n = "flex8_clk", .id = 11, },
+ { .n = "sdmmc0_clk", .id = 12, },
+ { .n = "flex4_clk", .id = 13, },
+ { .n = "flex5_clk", .id = 14, },
+ { .n = "flex9_clk", .id = 15, },
+ { .n = "flex10_clk", .id = 16, },
+ { .n = "tcb0_clk", .id = 17, },
+ { .n = "pwm_clk", .id = 18, },
+ { .n = "adc_clk", .id = 19, },
+ { .n = "dma0_clk", .id = 20, },
+ { .n = "uhphs_clk", .id = 22, },
+ { .n = "udphs_clk", .id = 23, },
+ { .n = "gmac_clk", .id = 24, },
+ { .n = "lcd_clk", .id = 25, },
+ { .n = "sdmmc1_clk", .id = 26, },
+ { .n = "ssc_clk", .id = 28, },
+ { .n = "mcan0_clk", .id = 29, },
+ { .n = "mcan1_clk", .id = 30, },
+ { .n = "flex11_clk", .id = 32, },
+ { .n = "flex12_clk", .id = 33, },
+ { .n = "i2s_clk", .id = 34, },
+ { .n = "qspi_clk", .id = 35, },
+ { .n = "gfx2d_clk", .id = 36, },
+ { .n = "pit64b0_clk", .id = 37, },
+ { .n = "trng_clk", .id = 38, },
+ { .n = "aes_clk", .id = 39, },
+ { .n = "tdes_clk", .id = 40, },
+ { .n = "sha_clk", .id = 41, },
+ { .n = "classd_clk", .id = 42, },
+ { .n = "isi_clk", .id = 43, },
+ { .n = "pioD_clk", .id = 44, },
+ { .n = "tcb1_clk", .id = 45, },
+ { .n = "dbgu_clk", .id = 47, },
+ { .n = "pmecc_clk", .id = 48, },
+ { .n = "mpddr_clk", .id = 49, },
+ { .n = "csi2dc_clk", .id = 52, },
+ { .n = "csi4l_clk", .id = 53, },
+ { .n = "dsi4l_clk", .id = 54, },
+ { .n = "lvdsc_clk", .id = 56, },
+ { .n = "pit64b1_clk", .id = 58, },
+ { .n = "puf_clk", .id = 59, },
+ { .n = "gmactsu_clk", .id = 67, },
+};
+
+/**
+ * Generic clock description
+ * @n: clock name
+ * @ep: extra parents names
+ * @ep_mux_table: extra parents mux table
+ * @ep_clk_mux_table: extra parents clock mux table (for CCF)
+ * @r: clock output range
+ * @ep_count: extra parents count
+ * @id: clock id
+ */
+static const struct {
+ const char *n;
+ const char *ep[8];
+ const char ep_mux_table[8];
+ const char ep_clk_mux_table[8];
+ struct clk_range r;
+ u8 ep_count;
+ u8 id;
+} sam9x7_gck[] = {
+ {
+ .n = "flex0_gclk",
+ .id = 5,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex1_gclk",
+ .id = 6,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex2_gclk",
+ .id = 7,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex3_gclk",
+ .id = 8,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex6_gclk",
+ .id = 9,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex7_gclk",
+ .id = 10,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex8_gclk",
+ .id = 11,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "sdmmc0_gclk",
+ .id = 12,
+ .r = { .max = 105000000 },
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "flex4_gclk",
+ .id = 13,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex5_gclk",
+ .id = 14,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex9_gclk",
+ .id = 15,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex10_gclk",
+ .id = 16,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "tcb0_gclk",
+ .id = 17,
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "adc_gclk",
+ .id = 19,
+ .ep = { "upll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 5, 8, },
+ .ep_clk_mux_table = { ID_PLL_U_DIV, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "gmac_gclk",
+ .id = 24,
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "lcd_gclk",
+ .id = 25,
+ .r = { .max = 75000000 },
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "sdmmc1_gclk",
+ .id = 26,
+ .r = { .max = 105000000 },
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "mcan0_gclk",
+ .id = 29,
+ .r = { .max = 80000000 },
+ .ep = { "upll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 5, 8, },
+ .ep_clk_mux_table = { ID_PLL_U_DIV, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "mcan1_gclk",
+ .id = 30,
+ .r = { .max = 80000000 },
+ .ep = { "upll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 5, 8, },
+ .ep_clk_mux_table = { ID_PLL_U_DIV, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "flex11_gclk",
+ .id = 32,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "flex12_gclk",
+ .id = 33,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "i2s_gclk",
+ .id = 34,
+ .r = { .max = 100000000 },
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "qspi_gclk",
+ .id = 35,
+ .r = { .max = 200000000 },
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "pit64b0_gclk",
+ .id = 37,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "classd_gclk",
+ .id = 42,
+ .r = { .max = 100000000 },
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "tcb1_gclk",
+ .id = 45,
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+ {
+ .n = "dbgu_gclk",
+ .id = 47,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "mipiphy_gclk",
+ .id = 55,
+ .r = { .max = 27000000 },
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "pit64b1_gclk",
+ .id = 58,
+ .ep = { "plla_div2pmcck", },
+ .ep_mux_table = { 8, },
+ .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
+ .ep_count = 1,
+ },
+
+ {
+ .n = "gmac_tsu_gclk",
+ .id = 67,
+ .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
+ .ep_mux_table = { 6, 8, },
+ .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
+ .ep_count = 2,
+ },
+
+};
+
+#define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \
+ do { \
+ int _i; \
+ (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \
+ if (!(_dst)) { \
+ ret = -ENOMEM; \
+ goto _label; \
+ } \
+ (_allocs)[(_index)++] = (_dst); \
+ for (_i = 0; _i < (_num); _i++) \
+ (_dst)[_i] = (_src)[_i]; \
+ } while (0)
+
+static int sam9x7_clk_probe(struct udevice *dev)
+{
+ void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
+ unsigned int *clkmuxallocs[64], *muxallocs[64];
+ const char *p[10];
+ unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
+ struct clk clk, *c;
+ int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
+ static const struct clk_range r = { 0, 0 };
+
+ if (!base)
+ return -EINVAL;
+
+ memset(muxallocs, 0, ARRAY_SIZE(muxallocs));
+ memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_id(clk.id, &c);
+ if (ret)
+ return ret;
+
+ clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
+ strlen(clk_hw_get_name(c)) + 1,
+ GFP_KERNEL);
+ if (!clk_names[ID_TD_SLCK])
+ return -ENOMEM;
+
+ ret = clk_get_by_index(dev, 1, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_id(clk.id, &c);
+ if (ret)
+ return ret;
+
+ clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
+ strlen(clk_hw_get_name(c)) + 1,
+ GFP_KERNEL);
+ if (!clk_names[ID_MD_SLCK])
+ return -ENOMEM;
+
+ ret = clk_get_by_index(dev, 2, &clk);
+ if (ret)
+ return ret;
+
+ clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
+ strlen(clk_hw_get_name(&clk)) + 1,
+ GFP_KERNEL);
+ if (!clk_names[ID_MAIN_XTAL])
+ return -ENOMEM;
+
+ ret = clk_get_by_index(dev, 3, &clk);
+ if (ret)
+ goto fail;
+
+ clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
+ strlen(clk_hw_get_name(&clk)) + 1,
+ GFP_KERNEL);
+ if (ret)
+ goto fail;
+
+ /* Register main rc oscillator. */
+ c = at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
+ clk_names[ID_MAIN_RC]);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC), c);
+
+ /* Register main oscillator. */
+ c = at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
+ clk_names[ID_MAIN_XTAL], false);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC), c);
+
+ /* Register mainck. */
+ p[0] = clk_names[ID_MAIN_RC_OSC];
+ p[1] = clk_names[ID_MAIN_OSC];
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
+ fail);
+ c = at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
+ 2, tmpclkmux, PMC_TYPE_CORE);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK), c);
+
+ /* Register PLL fracs clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x7_plls); i++) {
+ if (sam9x7_plls[i].t != PLL_TYPE_FRAC)
+ continue;
+
+ c = sam9x60_clk_register_frac_pll(base, sam9x7_plls[i].n,
+ sam9x7_plls[i].p,
+ sam9x7_plls[i].id,
+ sam9x7_plls[i].c,
+ sam9x7_plls[i].l,
+ sam9x7_plls[i].f);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x7_plls[i].cid), c);
+ }
+
+ /* Register PLL div clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x7_plls); i++) {
+ if (sam9x7_plls[i].t != PLL_TYPE_DIV)
+ continue;
+
+ c = sam9x60_clk_register_div_pll(base, sam9x7_plls[i].n,
+ sam9x7_plls[i].p,
+ sam9x7_plls[i].id,
+ sam9x7_plls[i].c,
+ sam9x7_plls[i].l,
+ sam9x7_plls[i].f);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x7_plls[i].cid), c);
+ }
+
+ /* Register MCK pres clock. */
+ p[0] = clk_names[ID_MD_SLCK];
+ p[1] = clk_names[ID_MAINCK];
+ p[2] = clk_names[ID_PLL_A_DIV];
+ p[3] = clk_names[ID_PLL_U_DIV];
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
+ cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
+ cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4,
+ fail);
+ c = at91_clk_register_master_pres(base, clk_names[ID_MCK_PRES], p, 4,
+ &mck_layout, &mck_characteristics,
+ tmpclkmux);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_PRES), c);
+
+ /* Register MCK div clock. */
+ c = at91_clk_register_master_div(base, clk_names[ID_MCK_DIV],
+ clk_names[ID_MCK_PRES],
+ &mck_layout, &mck_characteristics);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV), c);
+
+ /* Register programmable clocks. */
+ p[0] = clk_names[ID_MD_SLCK];
+ p[1] = clk_names[ID_TD_SLCK];
+ p[2] = clk_names[ID_MAINCK];
+ p[3] = clk_names[ID_MCK_DIV];
+ p[4] = clk_names[ID_PLL_A_DIV];
+ p[5] = clk_names[ID_PLL_U_DIV];
+ p[6] = clk_names[ID_PLL_AUDIO_DIVPMC];
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
+ cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
+ cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV);
+ cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
+ cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
+ cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_AUDIO_DIVPMC);
+ for (i = 0; i < ARRAY_SIZE(sam9x7_prog); i++) {
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
+ 7, fail);
+
+ c = at91_clk_register_programmable(base, sam9x7_prog[i].n, p,
+ 7, i, &programmable_layout,
+ tmpclkmux,
+ sam9x7_prog_mux_table);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x7_prog[i].cid), c);
+ }
+
+ /* System clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
+ c = at91_clk_register_system(base, sam9x7_systemck[i].n,
+ sam9x7_systemck[i].p,
+ sam9x7_systemck[i].id);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sam9x7_systemck[i].cid),
+ c);
+ }
+
+ /* Peripheral clocks. */
+ for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {
+ c = at91_clk_register_sam9x5_peripheral(base, &sam9x7_pcr_layout,
+ sam9x7_periphck[i].n,
+ clk_names[ID_MCK_DIV],
+ sam9x7_periphck[i].id,
+ &r);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
+ sam9x7_periphck[i].id), c);
+ }
+
+ /* Generic clocks. */
+ p[0] = clk_names[ID_MD_SLCK];
+ p[1] = clk_names[ID_TD_SLCK];
+ p[2] = clk_names[ID_MAINCK];
+ p[3] = clk_names[ID_MCK_DIV];
+ m[0] = 0;
+ m[1] = 1;
+ m[2] = 2;
+ m[3] = 3;
+ cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
+ cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
+ cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
+ cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV);
+ for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
+ for (j = 0; j < sam9x7_gck[i].ep_count; j++) {
+ p[4 + j] = sam9x7_gck[i].ep[j];
+ m[4 + j] = sam9x7_gck[i].ep_mux_table[j];
+ cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
+ sam9x7_gck[i].ep_clk_mux_table[j]);
+ }
+ prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
+ 4 + sam9x7_gck[i].ep_count, fail);
+ prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
+ 4 + sam9x7_gck[i].ep_count, fail);
+
+ c = at91_clk_register_generic(base, &sam9x7_pcr_layout,
+ sam9x7_gck[i].n, p, tmpclkmux,
+ tmpmux, 4 + sam9x7_gck[i].ep_count,
+ sam9x7_gck[i].id,
+ &sam9x7_gck[i].r);
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sam9x7_gck[i].id), c);
+ }
+
+ return 0;
+
+fail:
+ for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
+ kfree(muxallocs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
+ kfree(clkmuxallocs[i]);
+
+ return ret;
+}
+
+static const struct udevice_id sam9x7_clk_ids[] = {
+ { .compatible = "microchip,sam9x7-pmc" },
+ { /* Sentinel. */ },
+};
+
+U_BOOT_DRIVER(at91_sam9x7_pmc) = {
+ .name = "at91-sam9x7-pmc",
+ .id = UCLASS_CLK,
+ .of_match = sam9x7_clk_ids,
+ .ops = &at91_clk_ops,
+ .probe = sam9x7_clk_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 5/8] ARM: at91: Add sam9x7 soc
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
` (3 preceding siblings ...)
2025-03-17 6:56 ` [PATCH v4 4/8] clk: at91: sam9x7: add pmc driver for sam9x7 SoC family Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 6/8] ARM: dts: at91: sam9x75_curiosity: add tweaks for sam9x75 curiosity board Manikandan Muralidharan
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m, Varshini Rajendran, Balamanikandan Gunasundar
From: Varshini Rajendran <varshini.rajendran@microchip.com>
Add new Microchip sam9x7 SoC based on an ARM926.
Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
Signed-off-by: Balamanikandan Gunasundar <balamanikandan.gunasundar@microchip.com>
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
arch/arm/mach-at91/Kconfig | 4 +
arch/arm/mach-at91/arm926ejs/Makefile | 1 +
arch/arm/mach-at91/arm926ejs/sam9x7_devices.c | 49 +++++
arch/arm/mach-at91/include/mach/hardware.h | 2 +
arch/arm/mach-at91/include/mach/sam9x7.h | 172 ++++++++++++++++++
5 files changed, 228 insertions(+)
create mode 100644 arch/arm/mach-at91/arm926ejs/sam9x7_devices.c
create mode 100644 arch/arm/mach-at91/include/mach/sam9x7.h
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 7c4ccc427c8..5429257875d 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -43,6 +43,10 @@ config SAM9X60
bool
select CPU_ARM926EJS
+config SAM9X7
+ bool
+ select CPU_ARM926EJS
+
config SAMA7G5
bool
select CPU_V7A
diff --git a/arch/arm/mach-at91/arm926ejs/Makefile b/arch/arm/mach-at91/arm926ejs/Makefile
index 8f0bc5d997e..977299a5911 100644
--- a/arch/arm/mach-at91/arm926ejs/Makefile
+++ b/arch/arm/mach-at91/arm926ejs/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91SAM9G45) += at91sam9m10g45_devices.o
obj-$(CONFIG_AT91SAM9N12) += at91sam9n12_devices.o
obj-$(CONFIG_AT91SAM9X5) += at91sam9x5_devices.o
obj-$(CONFIG_SAM9X60) += sam9x60_devices.o
+obj-$(CONFIG_SAM9X7) += sam9x7_devices.o
obj-y += clock.o
obj-y += cpu.o
ifndef CONFIG_$(PHASE_)SYSRESET
diff --git a/arch/arm/mach-at91/arm926ejs/sam9x7_devices.c b/arch/arm/mach-at91/arm926ejs/sam9x7_devices.c
new file mode 100644
index 00000000000..c65764a3de4
--- /dev/null
+++ b/arch/arm/mach-at91/arm926ejs/sam9x7_devices.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+ */
+
+#include <asm/arch/at91_common.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+
+unsigned int get_chip_id(void)
+{
+ /* The 0x40 is the offset of cidr in DBGU */
+ return readl(ATMEL_BASE_DBGU + 0x40);
+}
+
+unsigned int get_extension_chip_id(void)
+{
+ /* The 0x44 is the offset of exid in DBGU */
+ return readl(ATMEL_BASE_DBGU + 0x44);
+}
+
+char *get_cpu_name(void)
+{
+ unsigned int extension_id = get_extension_chip_id();
+
+ if (cpu_is_sam9x7()) {
+ switch (extension_id) {
+ case ARCH_EXID_SAM9X70:
+ return "SAM9X70";
+ case ARCH_EXID_SAM9X72:
+ return "SAM9X72";
+ case ARCH_EXID_SAM9X75:
+ return "SAM9X75";
+ case ARCH_EXID_SAM9X75_D1M:
+ return "SAM9X75 16MB DDR2 SiP";
+ case ARCH_EXID_SAM9X75_D5M:
+ return "SAM9X75 64MB DDR2 SiP";
+ case ARCH_EXID_SAM9X75_D1G:
+ return "SAM9X75 125MB DDR3L SiP";
+ case ARCH_EXID_SAM9X75_D2G:
+ return "SAM9X75 250MB DDR3L SiP";
+ default:
+ return "Unknown CPU type";
+ }
+ } else {
+ return "Unknown CPU type";
+ }
+}
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index 988ef492b62..de89714b097 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -23,6 +23,8 @@
# include <asm/arch/at91sam9x5.h>
#elif defined(CONFIG_SAM9X60)
# include <asm/arch/sam9x60.h>
+#elif defined(CONFIG_SAM9X7)
+# include <asm/arch/sam9x7.h>
#elif defined(CONFIG_SAMA7G5)
# include <asm/arch/sama7g5.h>
#elif defined(CONFIG_SAMA5D2)
diff --git a/arch/arm/mach-at91/include/mach/sam9x7.h b/arch/arm/mach-at91/include/mach/sam9x7.h
new file mode 100644
index 00000000000..998fa786f90
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/sam9x7.h
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Chip-specific header file for the SAM9X7 SoC.
+ *
+ * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+ */
+
+#ifndef __SAM9X7_H__
+#define __SAM9X7_H__
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define ATMEL_ID_FIQ 0 /* Advanced Interrupt Controller - FIQ */
+#define ATMEL_ID_SYS 1 /* System Controller Interrupt */
+#define ATMEL_ID_PIOA 2 /* Parallel I/O Controller A */
+#define ATMEL_ID_PIOB 3 /* Parallel I/O Controller B */
+#define ATMEL_ID_PIOC 4 /* Parallel I/O Controller C */
+#define ATMEL_ID_FLEXCOM0 5 /* FLEXCOM 0 */
+#define ATMEL_ID_FLEXCOM1 6 /* FLEXCOM 1 */
+#define ATMEL_ID_FLEXCOM2 7 /* FLEXCOM 2 */
+#define ATMEL_ID_FLEXCOM3 8 /* FLEXCOM 3 */
+#define ATMEL_ID_FLEXCOM6 9 /* FLEXCOM 6 */
+#define ATMEL_ID_FLEXCOM7 10 /* FLEXCOM 7 */
+#define ATMEL_ID_FLEXCOM8 11 /* FLEXCOM 8 */
+#define ATMEL_ID_SDMMC0 12 /* SDMMC 0 */
+#define ATMEL_ID_FLEXCOM4 13 /* FLEXCOM 4 */
+#define ATMEL_ID_FLEXCOM5 14 /* FLEXCOM 5 */
+#define ATMEL_ID_FLEXCOM9 15 /* FLEXCOM 9 */
+#define ATMEL_ID_FLEXCOM10 16 /* FLEXCOM 10 */
+#define ATMEL_ID_TC01 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */
+#define ATMEL_ID_PWM 18 /* Pulse Width Modulation Controller */
+#define ATMEL_ID_ADC 19 /* ADC Controller */
+#define ATMEL_ID_XDMAC0 20 /* XDMA Controller 0 */
+#define ATMEL_ID_MATRIX 21 /* BUS Matrix */
+#define ATMEL_ID_UHPHS 22 /* USB Host High Speed */
+#define ATMEL_ID_UDPHS 23 /* USB Device High Speed */
+#define ATMEL_ID_GMAC 24 /* GMAC */
+#define ATMEL_ID_LCDC 25 /* LCD Controller */
+#define ATMEL_ID_SDMMC1 26 /* SDMMC 1 */
+#define ATMEL_ID_SSC 28 /* Synchronous Serial Controller */
+#define ATMEL_ID_IRQ 31 /* Advanced Interrupt Controller - IRQ */
+#define ATMEL_ID_TRNG 38 /* True Random Number Generator */
+#define ATMEL_ID_PIOD 44 /* Parallel I/O Controller D */
+#define ATMEL_ID_DBGU 47 /* Debug unit */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define ATMEL_BASE_FLEXCOM4 0xf0000000
+#define ATMEL_BASE_FLEXCOM5 0xf0004000
+#define ATMEL_BASE_XDMA0 0xf0008000
+#define ATMEL_BASE_SSC 0xf0010000
+#define ATMEL_BASE_QSPI 0xf0014000
+#define ATMEL_BASE_CAN0 0xf8000000
+#define ATMEL_BASE_CAN1 0xf8004000
+#define ATMEL_BASE_TC0 0xf8008000
+#define ATMEL_BASE_TC1 0xf800c000
+#define ATMEL_BASE_FLEXCOM6 0xf8010000
+#define ATMEL_BASE_FLEXCOM7 0xf8014000
+#define ATMEL_BASE_FLEXCOM8 0xf8018000
+#define ATMEL_BASE_FLEXCOM0 0xf801c000
+#define ATMEL_BASE_FLEXCOM1 0xf8020000
+#define ATMEL_BASE_FLEXCOM2 0xf8024000
+#define ATMEL_BASE_FLEXCOM3 0xf8028000
+#define ATMEL_BASE_GMAC 0xf802c000
+#define ATMEL_BASE_PWM 0xf8034000
+#define ATMEL_BASE_LCDC 0xf8038000
+#define ATMEL_BASE_UDPHS 0xf803c000
+#define ATMEL_BASE_FLEXCOM9 0xf8040000
+#define ATMEL_BASE_FLEXCOM10 0xf8044000
+#define ATMEL_BASE_ISC 0xf8048000
+#define ATMEL_BASE_ADC 0xf804c000
+#define ATMEL_BASE_SFR 0xf8050000
+#define ATMEL_BASE_SYS 0xffffc000
+
+/*
+ * System Peripherals
+ */
+#define ATMEL_BASE_MATRIX 0xffffde00
+#define ATMEL_BASE_PMECC 0xffffe000
+#define ATMEL_BASE_PMERRLOC 0xffffe600
+#define ATMEL_BASE_MPDDRC 0xffffe800
+#define ATMEL_BASE_SMC 0xffffea00
+#define ATMEL_BASE_SDRAMC 0xffffec00
+#define ATMEL_BASE_AIC 0xfffff100
+#define ATMEL_BASE_DBGU 0xfffff200
+#define ATMEL_BASE_PIOA 0xfffff400
+#define ATMEL_BASE_PIOB 0xfffff600
+#define ATMEL_BASE_PIOC 0xfffff800
+#define ATMEL_BASE_PIOD 0xfffffa00
+#define ATMEL_BASE_PMC 0xfffffc00
+#define ATMEL_BASE_RSTC 0xfffffe00
+#define ATMEL_BASE_SHDWC 0xfffffe10
+#define ATMEL_BASE_PIT 0xfffffe40
+#define ATMEL_BASE_GPBR 0xfffffe60
+#define ATMEL_BASE_RTC 0xfffffea8
+#define ATMEL_BASE_WDT 0xffffff80
+
+/*
+ * Internal Memory.
+ */
+#define ATMEL_BASE_ROM 0x00100000 /* Internal ROM base address */
+#define ATMEL_BASE_SRAM 0x00300000 /* Internal SRAM base address */
+#define ATMEL_BASE_UDPHS_FIFO 0x00500000 /* USB Device HS controller */
+#define ATMEL_BASE_OHCI 0x00600000 /* USB Host controller (OHCI) */
+#define ATMEL_BASE_EHCI 0x00700000 /* USB Host controller (EHCI) */
+
+/*
+ * External memory
+ */
+#define ATMEL_BASE_CS0 0x10000000
+#define ATMEL_BASE_CS1 0x20000000
+#define ATMEL_BASE_CS2 0x30000000
+#define ATMEL_BASE_CS3 0x40000000
+#define ATMEL_BASE_CS4 0x50000000
+#define ATMEL_BASE_CS5 0x60000000
+#define ATMEL_BASE_SDMMC0 0x80000000
+#define ATMEL_BASE_SDMMC1 0x90000000
+
+/*
+ * SAM9x7 series chip id definitions
+ */
+#define ARCH_ID_SAM9X7 0x89750030
+#define ARCH_EXID_SAM9X70 0x00000005
+#define ARCH_EXID_SAM9X72 0x00000004
+#define ARCH_EXID_SAM9X75 0x00000000
+#define ARCH_EXID_SAM9X75_D1G 0x00000018
+#define ARCH_EXID_SAM9X75_D2G 0x00000020
+#define ARCH_EXID_SAM9X75_D1M 0x00000003
+#define ARCH_EXID_SAM9X75_D5M 0x00000010
+
+#define cpu_is_sam9x7() (get_chip_id() == ARCH_ID_SAM9X7)
+
+/*
+ * Cpu Name
+ */
+#define ATMEL_CPU_NAME get_cpu_name()
+
+/*
+ * Timer
+ */
+#define CFG_SYS_TIMER_COUNTER 0xf0028000
+
+/*
+ * Other misc defines
+ */
+#define ATMEL_PIO_PORTS 4
+#define CPU_HAS_PCR
+#define CPU_NO_PLLB
+#define PLL_ID_PLLA 0
+#define PLL_ID_UPLL 1
+#define PLL_ID_AUDIOPLL 2
+#define PLL_ID_LVDSPLL 3
+#define PLL_ID_PLLA_DIV_2 4
+
+/*
+ * PMECC table in ROM
+ */
+#define ATMEL_PMECC_INDEX_OFFSET_512 0x0000
+#define ATMEL_PMECC_INDEX_OFFSET_1024 0x8000
+
+/*
+ * SAM9X7 specific prototypes
+ */
+#ifndef __ASSEMBLY__
+unsigned int get_chip_id(void);
+unsigned int get_extension_chip_id(void);
+char *get_cpu_name(void);
+#endif
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 6/8] ARM: dts: at91: sam9x75_curiosity: add tweaks for sam9x75 curiosity board
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
` (4 preceding siblings ...)
2025-03-17 6:56 ` [PATCH v4 5/8] ARM: at91: Add sam9x7 soc Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 7/8] board: sam9x75_curiosity: Add support for sam9x75 curiosity Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 8/8] configs: sam9x75_curiosity: Add initial mmc default config Manikandan Muralidharan
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m
Since the SoC and board DT are already available in dts/upstream,
add the difference from upstream DTS to at91-sam9x75_curiosity-u-boot.dtsi
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
.../dts/at91-sam9x75_curiosity-u-boot.dtsi | 107 ++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
diff --git a/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi b/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
new file mode 100644
index 00000000000..dc4fef950ec
--- /dev/null
+++ b/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sam9x75_curiosity-u-boot.dtsi - Device Tree file for SAM9X75
+ * CURIOSITY board.
+ *
+ * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Manikandan Muralidharan <manikandan.m@microchip.com>
+ */
+
+/ {
+ cpus {
+ cpu@0 {
+ clocks = <&pmc PMC_TYPE_CORE 25>, <&pmc PMC_TYPE_CORE 17>, <&main_xtal>;
+ clock-names = "cpu", "master", "xtal";
+ };
+ };
+
+ clocks {
+ slow_rc_osc: slow_rc_osc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <18500>;
+ };
+
+ main_rc: main_rc {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ bootph-all;
+
+ apb {
+ bootph-all;
+
+ pinctrl {
+ bootph-all;
+ };
+ };
+ };
+
+ chosen {
+ bootph-all;
+ };
+};
+
+&clk32k {
+ bootph-all;
+ clocks = <&slow_rc_osc>, <&slow_xtal>;
+};
+
+&dbgu {
+ bootph-all;
+};
+
+&gmac {
+ compatible = "microchip,sam9x7-gem", "cdns,sama7g5-gem";
+};
+
+&main_rc {
+ bootph-all;
+};
+
+&main_xtal {
+ bootph-all;
+};
+
+&pinctrl_dbgu_default {
+ bootph-all;
+};
+
+&pinctrl_sdmmc0_default {
+ bootph-all;
+};
+
+&pioA {
+ bootph-all;
+};
+
+&pioB {
+ bootph-all;
+};
+
+&pit64b0 {
+ bootph-all;
+};
+
+&pmc {
+ bootph-all;
+ clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>, <&main_rc>;
+ clock-names = "td_slck", "md_slck", "main_xtal", "main_rc";
+};
+
+&sdmmc0 {
+ bootph-all;
+};
+
+&slow_xtal {
+ bootph-all;
+};
+
+&slow_rc_osc {
+ bootph-all;
+};
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 7/8] board: sam9x75_curiosity: Add support for sam9x75 curiosity
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
` (5 preceding siblings ...)
2025-03-17 6:56 ` [PATCH v4 6/8] ARM: dts: at91: sam9x75_curiosity: add tweaks for sam9x75 curiosity board Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 8/8] configs: sam9x75_curiosity: Add initial mmc default config Manikandan Muralidharan
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m
Add board specific functions for sam9x75 curiosity
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
arch/arm/mach-at91/Kconfig | 8 +++
board/atmel/sam9x75_curiosity/Kconfig | 15 +++++
board/atmel/sam9x75_curiosity/MAINTAINERS | 6 ++
board/atmel/sam9x75_curiosity/Makefile | 7 ++
.../sam9x75_curiosity/sam9x75_curiosity.c | 66 +++++++++++++++++++
include/configs/sam9x75_curiosity.h | 23 +++++++
6 files changed, 125 insertions(+)
create mode 100644 board/atmel/sam9x75_curiosity/Kconfig
create mode 100644 board/atmel/sam9x75_curiosity/MAINTAINERS
create mode 100644 board/atmel/sam9x75_curiosity/Makefile
create mode 100644 board/atmel/sam9x75_curiosity/sam9x75_curiosity.c
create mode 100644 include/configs/sam9x75_curiosity.h
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 5429257875d..d21534ce883 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -158,6 +158,13 @@ config TARGET_SAM9X60_CURIOSITY
select BOARD_EARLY_INIT_F
select BOARD_LATE_INIT
+config TARGET_SAM9X75_CURIOSITY
+ bool "SAM9X75 CURIOSITY board"
+ select SAM9X7
+ select BOARD_EARLY_INIT_F
+ select BOARD_LATE_INIT
+ imply OF_UPSTREAM
+
config TARGET_SAMA5D2_PTC_EK
bool "SAMA5D2 PTC EK board"
select BOARD_EARLY_INIT_F
@@ -355,6 +362,7 @@ source "board/atmel/at91sam9rlek/Kconfig"
source "board/atmel/at91sam9x5ek/Kconfig"
source "board/atmel/sam9x60ek/Kconfig"
source "board/atmel/sam9x60_curiosity/Kconfig"
+source "board/atmel/sam9x75_curiosity/Kconfig"
source "board/atmel/sama7g5ek/Kconfig"
source "board/atmel/sama7g54_curiosity/Kconfig"
source "board/atmel/sama5d2_ptc_ek/Kconfig"
diff --git a/board/atmel/sam9x75_curiosity/Kconfig b/board/atmel/sam9x75_curiosity/Kconfig
new file mode 100644
index 00000000000..8ea93a21aa3
--- /dev/null
+++ b/board/atmel/sam9x75_curiosity/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_SAM9X75_CURIOSITY
+
+config SYS_BOARD
+ default "sam9x75_curiosity"
+
+config SYS_VENDOR
+ default "atmel"
+
+config SYS_SOC
+ default "at91"
+
+config SYS_CONFIG_NAME
+ default "sam9x75_curiosity"
+
+endif
diff --git a/board/atmel/sam9x75_curiosity/MAINTAINERS b/board/atmel/sam9x75_curiosity/MAINTAINERS
new file mode 100644
index 00000000000..a175053418f
--- /dev/null
+++ b/board/atmel/sam9x75_curiosity/MAINTAINERS
@@ -0,0 +1,6 @@
+SAM9X75 CURIOSITY BOARD
+M: Manikandan Muralidharan <manikandan.m@microchip.com>
+S: Maintained
+F: board/atmel/sam9x75_curiosity/
+F: include/configs/sam9x75_curiosity.h
+F: arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
diff --git a/board/atmel/sam9x75_curiosity/Makefile b/board/atmel/sam9x75_curiosity/Makefile
new file mode 100644
index 00000000000..1f36d613229
--- /dev/null
+++ b/board/atmel/sam9x75_curiosity/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+#
+# Author: Manikandan Muralidharan <manikandan.m@microchip.com>
+
+obj-y += sam9x75_curiosity.o
diff --git a/board/atmel/sam9x75_curiosity/sam9x75_curiosity.c b/board/atmel/sam9x75_curiosity/sam9x75_curiosity.c
new file mode 100644
index 00000000000..4e7c5667e21
--- /dev/null
+++ b/board/atmel/sam9x75_curiosity/sam9x75_curiosity.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Manikandan Muralidharan <manikandan.m@microchip.com>
+ */
+
+#include <debug_uart.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/at91sam9_smc.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_sfr.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/gpio.h>
+#include <asm/mach-types.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void at91_prepare_cpu_var(void);
+
+int board_late_init(void)
+{
+ at91_prepare_cpu_var();
+
+ return 0;
+}
+
+#if (IS_ENABLED(CONFIG_DEBUG_UART_BOARD_INIT))
+static void board_dbgu0_hw_init(void)
+{
+ at91_pio3_set_a_periph(AT91_PIO_PORTA, 26, 1); /* DRXD */
+ at91_pio3_set_a_periph(AT91_PIO_PORTA, 27, 1); /* DTXD */
+
+ at91_periph_clk_enable(ATMEL_ID_DBGU);
+}
+
+void board_debug_uart_init(void)
+{
+ board_dbgu0_hw_init();
+}
+#endif
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100;
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
diff --git a/include/configs/sam9x75_curiosity.h b/include/configs/sam9x75_curiosity.h
new file mode 100644
index 00000000000..62a855d9f01
--- /dev/null
+++ b/include/configs/sam9x75_curiosity.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration settings for the SAM9X75 CURIOSITY board.
+ *
+ * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Manikandan Muralidharan <manikandan.m@microchip.com>
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define CFG_SYS_AT91_SLOW_CLOCK 32768
+#define CFG_SYS_AT91_MAIN_CLOCK 24000000 /* 24 MHz crystal */
+
+#define CFG_USART_BASE ATMEL_BASE_DBGU
+#define CFG_USART_ID 0 /* ignored in arm */
+
+/* SDRAM */
+#define CFG_SYS_SDRAM_BASE 0x20000000
+#define CFG_SYS_SDRAM_SIZE 0x10000000 /* 256 megs */
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 8/8] configs: sam9x75_curiosity: Add initial mmc default config
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
` (6 preceding siblings ...)
2025-03-17 6:56 ` [PATCH v4 7/8] board: sam9x75_curiosity: Add support for sam9x75 curiosity Manikandan Muralidharan
@ 2025-03-17 6:56 ` Manikandan Muralidharan
7 siblings, 0 replies; 10+ messages in thread
From: Manikandan Muralidharan @ 2025-03-17 6:56 UTC (permalink / raw)
To: Eugen Hristev, Lukasz Majewski, seanga2, sjg, mkorpershoek,
nathan.morrison, ilias.apalodimas, greg.malysa, caleb.connolly,
Oliver.Gaskell, robert.marko, jerome.forissier, semen.protsenko,
william.zhang, nicolas.ferre, u-boot
Cc: manikandan.m
Add default configuration for sd-card to boot the linux kernel.
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
board/atmel/sam9x75_curiosity/MAINTAINERS | 1 +
configs/sam9x75_curiosity_mmc_defconfig | 73 +++++++++++++++++++++++
2 files changed, 74 insertions(+)
create mode 100644 configs/sam9x75_curiosity_mmc_defconfig
diff --git a/board/atmel/sam9x75_curiosity/MAINTAINERS b/board/atmel/sam9x75_curiosity/MAINTAINERS
index a175053418f..f0dfdbe8d5c 100644
--- a/board/atmel/sam9x75_curiosity/MAINTAINERS
+++ b/board/atmel/sam9x75_curiosity/MAINTAINERS
@@ -4,3 +4,4 @@ S: Maintained
F: board/atmel/sam9x75_curiosity/
F: include/configs/sam9x75_curiosity.h
F: arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
+F: configs/sam9x75_curiosity_mmc_defconfig
diff --git a/configs/sam9x75_curiosity_mmc_defconfig b/configs/sam9x75_curiosity_mmc_defconfig
new file mode 100644
index 00000000000..76b85448285
--- /dev/null
+++ b/configs/sam9x75_curiosity_mmc_defconfig
@@ -0,0 +1,73 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_ARCH_AT91=y
+CONFIG_TEXT_BASE=0x23f00000
+CONFIG_SYS_MALLOC_LEN=0x81000
+CONFIG_SYS_MALLOC_F_LEN=0x12000
+CONFIG_TARGET_SAM9X75_CURIOSITY=y
+CONFIG_ATMEL_LEGACY=y
+CONFIG_NR_DRAM_BANKS=8
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20015f00
+CONFIG_ENV_SIZE=0x4000
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="microchip/at91-sam9x75_curiosity"
+CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_SYS_LOAD_ADDR=0x22000000
+CONFIG_DEBUG_UART_BASE=0xfffff200
+CONFIG_DEBUG_UART_CLOCK=266666666
+CONFIG_DEBUG_UART_BOARD_INIT=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_SD_BOOT=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="mem=256M console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait"
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="fatload mmc 0:1 0x21000000 at91-sam9x75_curiosity.dtb; fatload mmc 0:1 0x22000000 zImage; bootz 0x22000000 - 0x21000000"
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=281
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DM=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_BOOTP_BOOTFILESIZE=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_HASH=y
+CONFIG_HASH_VERIFY=y
+CONFIG_CMD_FAT=y
+CONFIG_OF_CONTROL=y
+CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_CLK=y
+CONFIG_CLK_CCF=y
+CONFIG_CLK_AT91=y
+CONFIG_AT91_GENERIC_CLK=y
+CONFIG_AT91_SAM9X60_PLL=y
+CONFIG_CPU=y
+CONFIG_AT91_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_AT91=y
+CONFIG_I2C_EEPROM=y
+CONFIG_MICROCHIP_FLEXCOM=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ATMEL=y
+CONFIG_MTD=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_AT91=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ATMEL_USART=y
+CONFIG_TIMER=y
+CONFIG_MCHP_PIT64B_TIMER=y
+CONFIG_PHANDLE_CHECK_SEQ=y
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 4/8] clk: at91: sam9x7: add pmc driver for sam9x7 SoC family
2025-03-17 6:56 ` [PATCH v4 4/8] clk: at91: sam9x7: add pmc driver for sam9x7 SoC family Manikandan Muralidharan
@ 2025-03-18 9:02 ` Eugen Hristev
0 siblings, 0 replies; 10+ messages in thread
From: Eugen Hristev @ 2025-03-18 9:02 UTC (permalink / raw)
To: Manikandan Muralidharan, Lukasz Majewski, seanga2, sjg,
mkorpershoek, nathan.morrison, ilias.apalodimas, greg.malysa,
caleb.connolly, Oliver.Gaskell, robert.marko, jerome.forissier,
semen.protsenko, william.zhang, nicolas.ferre, u-boot
Cc: Varshini Rajendran, Balamanikandan Gunasundar
On 3/17/25 08:56, Manikandan Muralidharan wrote:
> From: Varshini Rajendran <varshini.rajendran@microchip.com>
>
> Add PMC driver support for sam9x7 SoC family
>
> Signed-off-by: Varshini Rajendran <varshini.rajendran@microchip.com>
> [balamanikandan.gunasundar@microchip.com: Add peripheral clock id for pmecc]
> Signed-off-by: Balamanikandan Gunasundar <balamanikandan.gunasundar@microchip.com>
> ---
> drivers/clk/at91/Makefile | 1 +
> drivers/clk/at91/sam9x7.c | 1094 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 1095 insertions(+)
> create mode 100644 drivers/clk/at91/sam9x7.c
>
> diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
> index e53dcb4ca7a..6cca861f81c 100644
> --- a/drivers/clk/at91/Makefile
> +++ b/drivers/clk/at91/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
> obj-$(CONFIG_AT91_SAM9X60_USB) += clk-sam9x60-usb.o
> obj-$(CONFIG_SAMA7G5) += sama7g5.o
> obj-$(CONFIG_SAM9X60) += sam9x60.o
> +obj-$(CONFIG_SAM9X7) += sam9x7.o
> else
> obj-y += compat.o
> endif
> diff --git a/drivers/clk/at91/sam9x7.c b/drivers/clk/at91/sam9x7.c
> new file mode 100644
> index 00000000000..b362d2f9858
> --- /dev/null
> +++ b/drivers/clk/at91/sam9x7.c
> @@ -0,0 +1,1094 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
> + *
> + * Author: Varshini Rajendran <varshini.rajendran@microchip.com>
> + *
> + */
> +
> +#include <clk-uclass.h>
> +#include <dm.h>
> +#include <dt-bindings/clock/at91.h>
> +#include <linux/clk-provider.h>
> +
> +#include "pmc.h"
> +
> +/**
> + * Clock identifiers to be used in conjunction with macros like
> + * AT91_TO_CLK_ID()
> + *
> + * @ID_MD_SLCK: TD slow clock identifier
> + * @ID_TD_SLCK: MD slow clock identifier
> + * @ID_MAIN_XTAL: Main Xtal clock identifier
> + * @ID_MAIN_RC: Main RC clock identifier
> + * @ID_MAIN_RC_OSC: Main RC Oscillator clock identifier
> + * @ID_MAIN_OSC: Main Oscillator clock identifier
> + * @ID_MAINCK: MAINCK clock identifier
> + * @ID_PLL_U_FRAC: UPLL fractional clock identifier
> + * @ID_PLL_U_DIV: UPLL divider clock identifier
> + * @ID_PLL_A_FRAC: APLL fractional clock identifier
> + * @ID_PLL_A_DIV: APLL divider clock identifier
> + * @ID_PLL_A_2_DIV: PLLA DIV2 divider clock identifier
> + * @ID_PLL_AUDIO_FRAC: Audio PLL fractional clock identifier
> + * @ID_PLL_AUDIO_DIVPMC: Audio PLL divider clock identifier
> + * @ID_PLL_AUDIO_DIVIO: Audio PLL IO divider clock identifier
> + * @ID_PLL_LVDS_FRAC: LVDS PLL fractional clock identifier
> + * @ID_PLL_LVDS_DIV: LVDS PLL divider clock identifier
> +
> + * @ID_MCK_DIV: MCK DIV clock identifier
> +
> + * @ID_UTMI: UTMI clock identifier
> +
> + * @ID_PROG0: Programmable 0 clock identifier
> + * @ID_PROG1: Programmable 1 clock identifier
> +
> + * @ID_PCK0: PCK0 system clock identifier
> + * @ID_PCK1: PCK1 system clock identifier
> + * @ID_DDR: DDR system clock identifier
> + * @ID_QSPI: QSPI system clock identifier
> + *
> + * @ID_MCK_PRES: MCK PRES clock identifier
> + *
> + * Note: if changing the values of this enums please sync them with
> + * device tree
> + */
> +enum pmc_clk_ids {
> + ID_MD_SLCK = 0,
> + ID_TD_SLCK = 1,
> + ID_MAIN_XTAL = 2,
> + ID_MAIN_RC = 3,
> + ID_MAIN_RC_OSC = 4,
> + ID_MAIN_OSC = 5,
> + ID_MAINCK = 6,
> +
> + ID_PLL_U_FRAC = 7,
> + ID_PLL_U_DIV = 8,
> + ID_PLL_A_FRAC = 9,
> + ID_PLL_A_DIV = 10,
> + ID_PLL_A_2_DIV = 11,
> + ID_PLL_AUDIO_FRAC = 12,
> + ID_PLL_AUDIO_DIVPMC = 13,
> + ID_PLL_AUDIO_DIVIO = 14,
> + ID_PLL_LVDS_FRAC = 15,
> + ID_PLL_LVDS_DIV = 16,
> +
> + ID_MCK_DIV = 17,
> +
> + ID_UTMI = 18,
> +
> + ID_PROG0 = 19,
> + ID_PROG1 = 20,
> +
> + ID_PCK0 = 21,
> + ID_PCK1 = 22,
> +
> + ID_DDR = 23,
> + ID_QSPI = 24,
> +
> + ID_MCK_PRES = 25,
> +
> + ID_MAX,
> +};
> +
> +/**
> + * PLL type identifiers
> + * @PLL_TYPE_FRAC: fractional PLL identifier
> + * @PLL_TYPE_DIV: divider PLL identifier
> + */
> +enum pll_type {
> + PLL_TYPE_FRAC,
> + PLL_TYPE_DIV,
> +};
> +
> +/* Clock names used as parents for multiple clocks. */
> +static const char *clk_names[] = {
> + [ID_MAIN_RC_OSC] = "main_rc_osc",
> + [ID_MAIN_OSC] = "main_osc",
> + [ID_MAINCK] = "mainck",
> + [ID_PLL_U_DIV] = "upll_divpmcck",
> + [ID_PLL_A_DIV] = "plla_divpmcck",
> + [ID_PLL_A_2_DIV] = "plla_div2pmcck",
> + [ID_PLL_AUDIO_DIVPMC] = "pll_audio_divpmcck",
> + [ID_PLL_AUDIO_DIVIO] = "pll_audio_diviock",
> + [ID_PLL_LVDS_DIV] = "pll_lvds_divpmcck",
> + [ID_MCK_PRES] = "mck_pres",
> + [ID_MCK_DIV] = "mck_div",
> +};
> +
> +/* Fractional PLL core output range. */
> +static const struct clk_range plla_core_outputs[] = {
> + { .min = 800000000, .max = 1600000000 },
> +};
> +
> +static const struct clk_range upll_core_outputs[] = {
> + { .min = 600000000, .max = 960000000 },
> +};
> +
> +static const struct clk_range lvdspll_core_outputs[] = {
> + { .min = 600000000, .max = 1200000000 },
> +};
> +
> +static const struct clk_range audiopll_core_outputs[] = {
> + { .min = 600000000, .max = 1200000000 },
> +};
> +
> +static const struct clk_range plladiv2_core_outputs[] = {
> + { .min = 800000000, .max = 1600000000 },
> +};
> +
> +/* Fractional PLL output range. */
> +static const struct clk_range plla_outputs[] = {
> + { .min = 400000000, .max = 800000000 },
> +};
> +
> +static const struct clk_range upll_outputs[] = {
> + { .min = 300000000, .max = 480000000 },
> +};
> +
> +static const struct clk_range lvdspll_outputs[] = {
> + { .min = 175000000, .max = 550000000 },
> +};
> +
> +static const struct clk_range audiopll_outputs[] = {
> + { .min = 0, .max = 300000000 },
> +};
> +
> +static const struct clk_range plladiv2_outputs[] = {
> + { .min = 200000000, .max = 400000000 },
> +};
> +
> +/* PLL characteristics. */
> +static const struct clk_pll_characteristics plla_characteristics = {
> + .input = { .min = 20000000, .max = 50000000 },
> + .num_output = ARRAY_SIZE(plla_outputs),
> + .output = plla_outputs,
> + .core_output = plla_core_outputs,
> +};
> +
> +static const struct clk_pll_characteristics upll_characteristics = {
> + .input = { .min = 20000000, .max = 50000000 },
> + .num_output = ARRAY_SIZE(upll_outputs),
> + .output = upll_outputs,
> + .core_output = upll_core_outputs,
> + .upll = true,
> +};
> +
> +static const struct clk_pll_characteristics lvdspll_characteristics = {
> + .input = { .min = 20000000, .max = 50000000 },
> + .num_output = ARRAY_SIZE(lvdspll_outputs),
> + .output = lvdspll_outputs,
> + .core_output = lvdspll_core_outputs,
> +};
> +
> +static const struct clk_pll_characteristics audiopll_characteristics = {
> + .input = { .min = 20000000, .max = 50000000 },
> + .num_output = ARRAY_SIZE(audiopll_outputs),
> + .output = audiopll_outputs,
> + .core_output = audiopll_core_outputs,
> +};
> +
> +static const struct clk_pll_characteristics plladiv2_characteristics = {
> + .input = { .min = 20000000, .max = 50000000 },
> + .num_output = ARRAY_SIZE(plladiv2_outputs),
> + .output = plladiv2_outputs,
> + .core_output = plladiv2_core_outputs,
> +};
> +
> +/* Layout for fractional PLLs. */
> +static const struct clk_pll_layout pll_layout_frac = {
> + .mul_mask = GENMASK(31, 24),
> + .frac_mask = GENMASK(21, 0),
> + .mul_shift = 24,
> + .frac_shift = 0,
> +};
> +
> +/* Layout for fractional PLL ID PLLA. */
> +static const struct clk_pll_layout plla_layout_frac = {
> + .mul_mask = GENMASK(31, 24),
> + .frac_mask = GENMASK(21, 0),
> + .mul_shift = 24,
> + .frac_shift = 0,
> + .div2 = 1,
> +};
> +
> +/* Layout for DIV PLLs. */
> +static const struct clk_pll_layout pll_layout_divpmc = {
> + .div_mask = GENMASK(7, 0),
> + .endiv_mask = BIT(29),
> + .div_shift = 0,
> + .endiv_shift = 29,
> +};
> +
> +/* Layout for DIV PLLs. */
> +static const struct clk_pll_layout plladiv2_layout_divpmc = {
> + .div_mask = GENMASK(7, 0),
> + .endiv_mask = BIT(29),
> + .div_shift = 0,
> + .endiv_shift = 29,
> + .div2 = 1,
> +};
> +
> +/* Layout for DIVIO dividers. */
> +static const struct clk_pll_layout pll_layout_divio = {
> + .div_mask = GENMASK(19, 12),
> + .endiv_mask = BIT(30),
> + .div_shift = 12,
> + .endiv_shift = 30,
> +};
> +
> +/* MCK characteristics. */
> +static const struct clk_master_characteristics mck_characteristics = {
> + .output = { .min = 32000000, .max = 266666666 },
> + .divisors = { 1, 2, 4, 3, 5},
> + .have_div3_pres = 1,
> +};
> +
> +/* MCK layout. */
> +static const struct clk_master_layout mck_layout = {
> + .mask = 0x373,
> + .pres_shift = 4,
> + .offset = 0x28,
> +};
> +
> +/* Programmable clock layout. */
> +static const struct clk_programmable_layout programmable_layout = {
> + .pres_mask = 0xff,
> + .pres_shift = 8,
> + .css_mask = 0x1f,
> + .have_slck_mck = 0,
> + .is_pres_direct = 1,
> +};
> +
> +/* Peripheral clock layout. */
> +static const struct clk_pcr_layout sam9x7_pcr_layout = {
> + .offset = 0x88,
> + .cmd = BIT(31),
> + .gckcss_mask = GENMASK(12, 8),
> + .pid_mask = GENMASK(6, 0),
> +};
> +
> +/**
> + * PLL clocks description
> + * @n: clock name
> + * @p: clock parent
> + * @l: clock layout
> + * @t: clock type
> + * @c: pll characteristics
> + * @f: true if clock is fixed and not changeable by driver
> + * @id: clock id corresponding to PLL driver
> + * @cid: clock id corresponding to clock subsystem
> + */
> +static const struct {
> + const char *n;
> + const char *p;
> + const struct clk_pll_layout *l;
> + const struct clk_pll_characteristics *c;
> + u8 t;
> + u8 f;
> + u8 id;
> + u8 cid;
> +} sam9x7_plls[] = {
> + {
> + .n = "plla_fracck",
> + .p = "mainck",
> + .l = &plla_layout_frac,
> + .c = &plla_characteristics,
> + .t = PLL_TYPE_FRAC,
> + .f = 1,
> + .id = 0,
> + .cid = ID_PLL_A_FRAC,
> + },
> +
> + {
> + .n = "plla_divpmcck",
> + .p = "plla_fracck",
> + .l = &pll_layout_divpmc,
> + .c = &plla_characteristics,
> + .t = PLL_TYPE_DIV,
> + .f = 1,
> + .id = 0,
> + .cid = ID_PLL_A_DIV,
> + },
> +
> + {
> + .n = "upll_fracck",
> + .p = "main_osc",
> + .l = &pll_layout_frac,
> + .c = &upll_characteristics,
> + .t = PLL_TYPE_FRAC,
> + .f = 1,
> + .id = 1,
> + .cid = ID_PLL_U_FRAC,
> + },
> +
> + {
> + .n = "upll_divpmcck",
> + .p = "upll_fracck",
> + .l = &pll_layout_divpmc,
> + .c = &upll_characteristics,
> + .t = PLL_TYPE_DIV,
> + .f = 1,
> + .id = 1,
> + .cid = ID_PLL_U_DIV,
> + },
> +
> + {
> + .n = "audiopll_fracck",
> + .p = "main_osc",
> + .l = &pll_layout_frac,
> + .c = &audiopll_characteristics,
> + .t = PLL_TYPE_FRAC,
> + .f = 1,
> + .id = 2,
> + .cid = ID_PLL_AUDIO_FRAC,
> + },
> +
> + {
> + .n = "audiopll_divpmcck",
> + .p = "audiopll_fracck",
> + .l = &pll_layout_divpmc,
> + .c = &audiopll_characteristics,
> + .t = PLL_TYPE_DIV,
> + .f = 1,
> + .id = 2,
> + .cid = ID_PLL_AUDIO_DIVPMC,
> + },
> +
> + {
> + .n = "audiopll_diviock",
> + .p = "audiopll_fracck",
> + .l = &pll_layout_divio,
> + .c = &audiopll_characteristics,
> + .t = PLL_TYPE_DIV,
> + .f = 1,
> + .id = 2,
> + .cid = ID_PLL_AUDIO_DIVIO,
> + },
> +
> + {
> + .n = "lvdspll_fracck",
> + .p = "main_osc",
> + .l = &pll_layout_frac,
> + .c = &lvdspll_characteristics,
> + .t = PLL_TYPE_FRAC,
> + .f = 1,
> + .id = 3,
> + .cid = ID_PLL_LVDS_FRAC,
> + },
> +
> + {
> + .n = "lvdspll_divpmcck",
> + .p = "lvdspll_fracck",
> + .l = &pll_layout_divpmc,
> + .c = &lvdspll_characteristics,
> + .t = PLL_TYPE_DIV,
> + .f = 1,
> + .id = 3,
> + .cid = ID_PLL_LVDS_DIV,
> + },
> +
> + {
> + .n = "plla_div2pmcck",
> + .p = "plla_fracck",
> + .l = &plladiv2_layout_divpmc,
> + .c = &plladiv2_characteristics,
> + .t = PLL_TYPE_DIV,
> + .f = 1,
> + .id = 4,
> + .cid = ID_PLL_A_2_DIV,
> + },
> +
> +};
> +
> +/**
> + * Programmable clock description
> + * @n: clock name
> + * @cid: clock id corresponding to clock subsystem
> + */
> +static const struct {
> + const char *n;
> + u8 cid;
> +} sam9x7_prog[] = {
> + { .n = "prog0", .cid = ID_PROG0, },
> + { .n = "prog1", .cid = ID_PROG1, },
> +};
> +
> +/* Mux table for programmable clocks. */
> +static u32 sam9x7_prog_mux_table[] = { 0, 1, 2, 3, 4, 5, 6, };
> +
> +/**
> + * System clock description
> + * @n: clock name
> + * @p: parent clock name
> + * @id: clock id corresponding to system clock driver
> + * @cid: clock id corresponding to clock subsystem
> + */
> +static const struct {
> + const char *n;
> + const char *p;
> + u8 id;
> + u8 cid;
> +} sam9x7_systemck[] = {
> + { .n = "ddrck", .p = "mck_pres", .id = 2, .cid = ID_DDR, },
> + { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, },
> + { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, },
> +};
> +
> +/**
> + * Peripheral clock description
> + * @n: clock name
> + * @id: clock id
> + */
> +static const struct {
> + const char *n;
> + u8 id;
> +} sam9x7_periphck[] = {
> + { .n = "pioA_clk", .id = 2, },
> + { .n = "pioB_clk", .id = 3, },
> + { .n = "pioC_clk", .id = 4, },
> + { .n = "flex0_clk", .id = 5, },
> + { .n = "flex1_clk", .id = 6, },
> + { .n = "flex2_clk", .id = 7, },
> + { .n = "flex3_clk", .id = 8, },
> + { .n = "flex6_clk", .id = 9, },
> + { .n = "flex7_clk", .id = 10, },
> + { .n = "flex8_clk", .id = 11, },
> + { .n = "sdmmc0_clk", .id = 12, },
> + { .n = "flex4_clk", .id = 13, },
> + { .n = "flex5_clk", .id = 14, },
> + { .n = "flex9_clk", .id = 15, },
> + { .n = "flex10_clk", .id = 16, },
> + { .n = "tcb0_clk", .id = 17, },
> + { .n = "pwm_clk", .id = 18, },
> + { .n = "adc_clk", .id = 19, },
> + { .n = "dma0_clk", .id = 20, },
> + { .n = "uhphs_clk", .id = 22, },
> + { .n = "udphs_clk", .id = 23, },
> + { .n = "gmac_clk", .id = 24, },
> + { .n = "lcd_clk", .id = 25, },
> + { .n = "sdmmc1_clk", .id = 26, },
> + { .n = "ssc_clk", .id = 28, },
> + { .n = "mcan0_clk", .id = 29, },
> + { .n = "mcan1_clk", .id = 30, },
> + { .n = "flex11_clk", .id = 32, },
> + { .n = "flex12_clk", .id = 33, },
> + { .n = "i2s_clk", .id = 34, },
> + { .n = "qspi_clk", .id = 35, },
> + { .n = "gfx2d_clk", .id = 36, },
> + { .n = "pit64b0_clk", .id = 37, },
> + { .n = "trng_clk", .id = 38, },
> + { .n = "aes_clk", .id = 39, },
> + { .n = "tdes_clk", .id = 40, },
> + { .n = "sha_clk", .id = 41, },
> + { .n = "classd_clk", .id = 42, },
> + { .n = "isi_clk", .id = 43, },
> + { .n = "pioD_clk", .id = 44, },
> + { .n = "tcb1_clk", .id = 45, },
> + { .n = "dbgu_clk", .id = 47, },
> + { .n = "pmecc_clk", .id = 48, },
> + { .n = "mpddr_clk", .id = 49, },
> + { .n = "csi2dc_clk", .id = 52, },
> + { .n = "csi4l_clk", .id = 53, },
> + { .n = "dsi4l_clk", .id = 54, },
> + { .n = "lvdsc_clk", .id = 56, },
> + { .n = "pit64b1_clk", .id = 58, },
> + { .n = "puf_clk", .id = 59, },
> + { .n = "gmactsu_clk", .id = 67, },
> +};
> +
> +/**
> + * Generic clock description
> + * @n: clock name
> + * @ep: extra parents names
> + * @ep_mux_table: extra parents mux table
> + * @ep_clk_mux_table: extra parents clock mux table (for CCF)
> + * @r: clock output range
> + * @ep_count: extra parents count
> + * @id: clock id
> + */
> +static const struct {
> + const char *n;
> + const char *ep[8];
> + const char ep_mux_table[8];
> + const char ep_clk_mux_table[8];
> + struct clk_range r;
> + u8 ep_count;
> + u8 id;
> +} sam9x7_gck[] = {
> + {
> + .n = "flex0_gclk",
> + .id = 5,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex1_gclk",
> + .id = 6,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex2_gclk",
> + .id = 7,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex3_gclk",
> + .id = 8,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex6_gclk",
> + .id = 9,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex7_gclk",
> + .id = 10,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex8_gclk",
> + .id = 11,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "sdmmc0_gclk",
> + .id = 12,
> + .r = { .max = 105000000 },
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "flex4_gclk",
> + .id = 13,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex5_gclk",
> + .id = 14,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex9_gclk",
> + .id = 15,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex10_gclk",
> + .id = 16,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "tcb0_gclk",
> + .id = 17,
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "adc_gclk",
> + .id = 19,
> + .ep = { "upll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 5, 8, },
> + .ep_clk_mux_table = { ID_PLL_U_DIV, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "gmac_gclk",
> + .id = 24,
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "lcd_gclk",
> + .id = 25,
> + .r = { .max = 75000000 },
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "sdmmc1_gclk",
> + .id = 26,
> + .r = { .max = 105000000 },
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "mcan0_gclk",
> + .id = 29,
> + .r = { .max = 80000000 },
> + .ep = { "upll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 5, 8, },
> + .ep_clk_mux_table = { ID_PLL_U_DIV, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "mcan1_gclk",
> + .id = 30,
> + .r = { .max = 80000000 },
> + .ep = { "upll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 5, 8, },
> + .ep_clk_mux_table = { ID_PLL_U_DIV, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "flex11_gclk",
> + .id = 32,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "flex12_gclk",
> + .id = 33,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "i2s_gclk",
> + .id = 34,
> + .r = { .max = 100000000 },
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "qspi_gclk",
> + .id = 35,
> + .r = { .max = 200000000 },
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "pit64b0_gclk",
> + .id = 37,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "classd_gclk",
> + .id = 42,
> + .r = { .max = 100000000 },
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "tcb1_gclk",
> + .id = 45,
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> + {
> + .n = "dbgu_gclk",
> + .id = 47,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "mipiphy_gclk",
> + .id = 55,
> + .r = { .max = 27000000 },
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "pit64b1_gclk",
> + .id = 58,
> + .ep = { "plla_div2pmcck", },
> + .ep_mux_table = { 8, },
> + .ep_clk_mux_table = { ID_PLL_A_2_DIV, },
> + .ep_count = 1,
> + },
> +
> + {
> + .n = "gmac_tsu_gclk",
> + .id = 67,
> + .ep = { "audiopll_divpmcck", "plla_div2pmcck", },
> + .ep_mux_table = { 6, 8, },
> + .ep_clk_mux_table = { ID_PLL_AUDIO_DIVPMC, ID_PLL_A_2_DIV, },
> + .ep_count = 2,
> + },
> +
> +};
> +
> +#define prepare_mux_table(_allocs, _index, _dst, _src, _num, _label) \
> + do { \
> + int _i; \
> + (_dst) = kzalloc(sizeof(*(_dst)) * (_num), GFP_KERNEL); \
> + if (!(_dst)) { \
> + ret = -ENOMEM; \
> + goto _label; \
> + } \
> + (_allocs)[(_index)++] = (_dst); \
> + for (_i = 0; _i < (_num); _i++) \
> + (_dst)[_i] = (_src)[_i]; \
> + } while (0)
> +
> +static int sam9x7_clk_probe(struct udevice *dev)
> +{
> + void __iomem *base = (void *)devfdt_get_addr_ptr(dev);
> + unsigned int *clkmuxallocs[64], *muxallocs[64];
> + const char *p[10];
> + unsigned int cm[10], m[10], *tmpclkmux, *tmpmux;
> + struct clk clk, *c;
> + int ret, muxallocindex = 0, clkmuxallocindex = 0, i, j;
> + static const struct clk_range r = { 0, 0 };
> +
> + if (!base)
> + return -EINVAL;
> +
> + memset(muxallocs, 0, ARRAY_SIZE(muxallocs));
> + memset(clkmuxallocs, 0, ARRAY_SIZE(clkmuxallocs));
> +
> + ret = clk_get_by_index(dev, 0, &clk);
> + if (ret)
> + return ret;
> +
> + ret = clk_get_by_id(clk.id, &c);
> + if (ret)
> + return ret;
> +
> + clk_names[ID_TD_SLCK] = kmemdup(clk_hw_get_name(c),
> + strlen(clk_hw_get_name(c)) + 1,
> + GFP_KERNEL);
> + if (!clk_names[ID_TD_SLCK])
> + return -ENOMEM;
> +
> + ret = clk_get_by_index(dev, 1, &clk);
> + if (ret)
> + return ret;
> +
> + ret = clk_get_by_id(clk.id, &c);
> + if (ret)
> + return ret;
> +
> + clk_names[ID_MD_SLCK] = kmemdup(clk_hw_get_name(c),
> + strlen(clk_hw_get_name(c)) + 1,
> + GFP_KERNEL);
> + if (!clk_names[ID_MD_SLCK])
> + return -ENOMEM;
> +
> + ret = clk_get_by_index(dev, 2, &clk);
> + if (ret)
> + return ret;
> +
> + clk_names[ID_MAIN_XTAL] = kmemdup(clk_hw_get_name(&clk),
> + strlen(clk_hw_get_name(&clk)) + 1,
> + GFP_KERNEL);
> + if (!clk_names[ID_MAIN_XTAL])
> + return -ENOMEM;
> +
> + ret = clk_get_by_index(dev, 3, &clk);
Linux does not have this clock if I am not mistaking.
This is the "main_rc" , right ?
Legacy speaking, U-boot has had four clocks on the PMC.
But now you are writing this new pmc driver for sam9x7.
Can you remove this clock such that the binding would be aligned to linux ?
What is this clock required for ?
Eugen
> + if (ret)
> + goto fail;
> +
> + clk_names[ID_MAIN_RC] = kmemdup(clk_hw_get_name(&clk),
> + strlen(clk_hw_get_name(&clk)) + 1,
> + GFP_KERNEL);
> + if (ret)
> + goto fail;
> +
> + /* Register main rc oscillator. */
> + c = at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
> + clk_names[ID_MAIN_RC]);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC), c);
> +
> + /* Register main oscillator. */
> + c = at91_clk_main_osc(base, clk_names[ID_MAIN_OSC],
> + clk_names[ID_MAIN_XTAL], false);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC), c);
> +
> + /* Register mainck. */
> + p[0] = clk_names[ID_MAIN_RC_OSC];
> + p[1] = clk_names[ID_MAIN_OSC];
> + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_RC_OSC);
> + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAIN_OSC);
> + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 2,
> + fail);
> + c = at91_clk_sam9x5_main(base, clk_names[ID_MAINCK], p,
> + 2, tmpclkmux, PMC_TYPE_CORE);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK), c);
> +
> + /* Register PLL fracs clocks. */
> + for (i = 0; i < ARRAY_SIZE(sam9x7_plls); i++) {
> + if (sam9x7_plls[i].t != PLL_TYPE_FRAC)
> + continue;
> +
> + c = sam9x60_clk_register_frac_pll(base, sam9x7_plls[i].n,
> + sam9x7_plls[i].p,
> + sam9x7_plls[i].id,
> + sam9x7_plls[i].c,
> + sam9x7_plls[i].l,
> + sam9x7_plls[i].f);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x7_plls[i].cid), c);
> + }
> +
> + /* Register PLL div clocks. */
> + for (i = 0; i < ARRAY_SIZE(sam9x7_plls); i++) {
> + if (sam9x7_plls[i].t != PLL_TYPE_DIV)
> + continue;
> +
> + c = sam9x60_clk_register_div_pll(base, sam9x7_plls[i].n,
> + sam9x7_plls[i].p,
> + sam9x7_plls[i].id,
> + sam9x7_plls[i].c,
> + sam9x7_plls[i].l,
> + sam9x7_plls[i].f);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x7_plls[i].cid), c);
> + }
> +
> + /* Register MCK pres clock. */
> + p[0] = clk_names[ID_MD_SLCK];
> + p[1] = clk_names[ID_MAINCK];
> + p[2] = clk_names[ID_PLL_A_DIV];
> + p[3] = clk_names[ID_PLL_U_DIV];
> + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
> + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
> + cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
> + cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
> + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm, 4,
> + fail);
> + c = at91_clk_register_master_pres(base, clk_names[ID_MCK_PRES], p, 4,
> + &mck_layout, &mck_characteristics,
> + tmpclkmux);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_PRES), c);
> +
> + /* Register MCK div clock. */
> + c = at91_clk_register_master_div(base, clk_names[ID_MCK_DIV],
> + clk_names[ID_MCK_PRES],
> + &mck_layout, &mck_characteristics);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV), c);
> +
> + /* Register programmable clocks. */
> + p[0] = clk_names[ID_MD_SLCK];
> + p[1] = clk_names[ID_TD_SLCK];
> + p[2] = clk_names[ID_MAINCK];
> + p[3] = clk_names[ID_MCK_DIV];
> + p[4] = clk_names[ID_PLL_A_DIV];
> + p[5] = clk_names[ID_PLL_U_DIV];
> + p[6] = clk_names[ID_PLL_AUDIO_DIVPMC];
> + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
> + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
> + cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
> + cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV);
> + cm[4] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_A_DIV);
> + cm[5] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_U_DIV);
> + cm[6] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_PLL_AUDIO_DIVPMC);
> + for (i = 0; i < ARRAY_SIZE(sam9x7_prog); i++) {
> + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
> + 7, fail);
> +
> + c = at91_clk_register_programmable(base, sam9x7_prog[i].n, p,
> + 7, i, &programmable_layout,
> + tmpclkmux,
> + sam9x7_prog_mux_table);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_CORE, sam9x7_prog[i].cid), c);
> + }
> +
> + /* System clocks. */
> + for (i = 0; i < ARRAY_SIZE(sam9x7_systemck); i++) {
> + c = at91_clk_register_system(base, sam9x7_systemck[i].n,
> + sam9x7_systemck[i].p,
> + sam9x7_systemck[i].id);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_SYSTEM, sam9x7_systemck[i].cid),
> + c);
> + }
> +
> + /* Peripheral clocks. */
> + for (i = 0; i < ARRAY_SIZE(sam9x7_periphck); i++) {
> + c = at91_clk_register_sam9x5_peripheral(base, &sam9x7_pcr_layout,
> + sam9x7_periphck[i].n,
> + clk_names[ID_MCK_DIV],
> + sam9x7_periphck[i].id,
> + &r);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_PERIPHERAL,
> + sam9x7_periphck[i].id), c);
> + }
> +
> + /* Generic clocks. */
> + p[0] = clk_names[ID_MD_SLCK];
> + p[1] = clk_names[ID_TD_SLCK];
> + p[2] = clk_names[ID_MAINCK];
> + p[3] = clk_names[ID_MCK_DIV];
> + m[0] = 0;
> + m[1] = 1;
> + m[2] = 2;
> + m[3] = 3;
> + cm[0] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MD_SLCK);
> + cm[1] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_TD_SLCK);
> + cm[2] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MAINCK);
> + cm[3] = AT91_TO_CLK_ID(PMC_TYPE_CORE, ID_MCK_DIV);
> + for (i = 0; i < ARRAY_SIZE(sam9x7_gck); i++) {
> + for (j = 0; j < sam9x7_gck[i].ep_count; j++) {
> + p[4 + j] = sam9x7_gck[i].ep[j];
> + m[4 + j] = sam9x7_gck[i].ep_mux_table[j];
> + cm[4 + j] = AT91_TO_CLK_ID(PMC_TYPE_CORE,
> + sam9x7_gck[i].ep_clk_mux_table[j]);
> + }
> + prepare_mux_table(clkmuxallocs, clkmuxallocindex, tmpclkmux, cm,
> + 4 + sam9x7_gck[i].ep_count, fail);
> + prepare_mux_table(muxallocs, muxallocindex, tmpmux, m,
> + 4 + sam9x7_gck[i].ep_count, fail);
> +
> + c = at91_clk_register_generic(base, &sam9x7_pcr_layout,
> + sam9x7_gck[i].n, p, tmpclkmux,
> + tmpmux, 4 + sam9x7_gck[i].ep_count,
> + sam9x7_gck[i].id,
> + &sam9x7_gck[i].r);
> + if (IS_ERR(c)) {
> + ret = PTR_ERR(c);
> + goto fail;
> + }
> + clk_dm(AT91_TO_CLK_ID(PMC_TYPE_GCK, sam9x7_gck[i].id), c);
> + }
> +
> + return 0;
> +
> +fail:
> + for (i = 0; i < ARRAY_SIZE(muxallocs); i++)
> + kfree(muxallocs[i]);
> +
> + for (i = 0; i < ARRAY_SIZE(clkmuxallocs); i++)
> + kfree(clkmuxallocs[i]);
> +
> + return ret;
> +}
> +
> +static const struct udevice_id sam9x7_clk_ids[] = {
> + { .compatible = "microchip,sam9x7-pmc" },
> + { /* Sentinel. */ },
> +};
> +
> +U_BOOT_DRIVER(at91_sam9x7_pmc) = {
> + .name = "at91-sam9x7-pmc",
> + .id = UCLASS_CLK,
> + .of_match = sam9x7_clk_ids,
> + .ops = &at91_clk_ops,
> + .probe = sam9x7_clk_probe,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-03-18 9:03 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-17 6:56 [PATCH v4 0/8] Add support for sam9x7 SoC and SAM9X75 Curiosity board Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 1/8] dt-bindings: drop at91.h from clock includes Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 2/8] clk: at91: sam9x60-pll: add support for core clock frequency inputs Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 3/8] clk: at91: sam9x60-pll: add support for HW PLL freq dividers Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 4/8] clk: at91: sam9x7: add pmc driver for sam9x7 SoC family Manikandan Muralidharan
2025-03-18 9:02 ` Eugen Hristev
2025-03-17 6:56 ` [PATCH v4 5/8] ARM: at91: Add sam9x7 soc Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 6/8] ARM: dts: at91: sam9x75_curiosity: add tweaks for sam9x75 curiosity board Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 7/8] board: sam9x75_curiosity: Add support for sam9x75 curiosity Manikandan Muralidharan
2025-03-17 6:56 ` [PATCH v4 8/8] configs: sam9x75_curiosity: Add initial mmc default config Manikandan Muralidharan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox