U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [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