Merge tag 'u-boot-at91-2025.10-a' of https://source.denx.de/u-boot/custodians/u-boot-at91 into next

First set of u-boot-at91 features for the 2025.10 cycle:

This feature set includes the addition of new sam9x7 SoC and a new board
named sam9x7-curiosity. There is also new support for sam9x60 compatible
at91 watchdog.
diff --git a/MAINTAINERS b/MAINTAINERS
index 5fda9b5..9211966 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -468,7 +468,6 @@
 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/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi b/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi
index dd46233..9144387 100644
--- a/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi
+++ b/arch/arm/dts/at91-sam9x60_curiosity-u-boot.dtsi
@@ -95,3 +95,7 @@
 &slow_xtal {
 	bootph-all;
 };
+
+&watchdog {
+	timeout-sec = <16>;
+};
diff --git a/arch/arm/dts/at91-sam9x60_curiosity.dts b/arch/arm/dts/at91-sam9x60_curiosity.dts
index 1c7f0fa..f165fda 100644
--- a/arch/arm/dts/at91-sam9x60_curiosity.dts
+++ b/arch/arm/dts/at91-sam9x60_curiosity.dts
@@ -336,3 +336,7 @@
 &usb2 {
 	status = "okay";
 };
+
+&watchdog {
+	status = "okay";
+};
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 0000000..94585ee
--- /dev/null
+++ b/arch/arm/dts/at91-sam9x75_curiosity-u-boot.dtsi
@@ -0,0 +1,95 @@
+// 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>;
+		};
+	};
+
+	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_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;
+};
+
+&sdmmc0 {
+	bootph-all;
+};
+
+&slow_xtal {
+	bootph-all;
+};
+
+&slow_rc_osc {
+	bootph-all;
+};
diff --git a/arch/arm/dts/sam9x60.dtsi b/arch/arm/dts/sam9x60.dtsi
index 7631dfa..7944904 100644
--- a/arch/arm/dts/sam9x60.dtsi
+++ b/arch/arm/dts/sam9x60.dtsi
@@ -311,6 +311,14 @@
 				clocks = <&slow_rc_osc>, <&slow_xtal>;
 				#clock-cells = <1>;
 			};
+
+			watchdog: watchdog@ffffff80 {
+				compatible = "microchip,sam9x60-wdt";
+				reg = <0xffffff80 0x24>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+				clocks = <&clk32 0>;
+				status = "disabled";
+			};
 		};
 	};
 
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 7c4ccc4..d21534c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -43,6 +43,10 @@
 	bool
 	select CPU_ARM926EJS
 
+config SAM9X7
+	bool
+	select CPU_ARM926EJS
+
 config SAMA7G5
 	bool
 	select CPU_V7A
@@ -154,6 +158,13 @@
         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
@@ -351,6 +362,7 @@
 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/arch/arm/mach-at91/arm926ejs/Makefile b/arch/arm/mach-at91/arm926ejs/Makefile
index 62c44b9..8a9464c 100644
--- a/arch/arm/mach-at91/arm926ejs/Makefile
+++ b/arch/arm/mach-at91/arm926ejs/Makefile
@@ -14,6 +14,7 @@
 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 0000000..c65764a
--- /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/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h
index 25d95fa..3780f0b 100644
--- a/arch/arm/mach-at91/include/mach/at91_wdt.h
+++ b/arch/arm/mach-at91/include/mach/at91_wdt.h
@@ -19,15 +19,16 @@
 
 #else
 
-typedef struct at91_wdt {
-	u32	cr;
-	u32	mr;
-	u32	sr;
-} at91_wdt_t;
+enum {
+	AT91_WDT_MODE_SAM9260 = 0,
+	AT91_WDT_MODE_SAM9X60 = 1
+};
 
 struct at91_wdt_priv {
 	void __iomem *regs;
-	u32 regval;
+	u32 mr;
+	u32 wddis;
+	u8 mode;
 };
 
 #endif
@@ -39,14 +40,22 @@
 
 /* Watchdog Mode Register*/
 #define AT91_WDT_MR			0x04
-#define AT91_WDT_MR_WDV(x)		(x & 0xfff)
+#define AT91_WDT_MR_WDV(x)		((x) & 0xfff)
+#define AT91_SAM9X60_MR_PERIODRST	0x00000010
 #define AT91_WDT_MR_WDFIEN		0x00001000
+#define AT91_SAM9X60_MR_WDDIS		0x00001000
 #define AT91_WDT_MR_WDRSTEN		0x00002000
 #define AT91_WDT_MR_WDRPROC		0x00004000
 #define AT91_WDT_MR_WDDIS		0x00008000
-#define AT91_WDT_MR_WDD(x)		((x & 0xfff) << 16)
+#define AT91_WDT_MR_WDD(x)		(((x) & 0xfff) << 16)
 #define AT91_WDT_MR_WDDBGHLT		0x10000000
+#define AT91_SAM9X60_MR_WDIDLEHLT	0x10000000
 #define AT91_WDT_MR_WDIDLEHLT		0x20000000
+#define AT91_SAM9X60_MR_WDDBGHLT	0x20000000
+
+/* Watchdog Window Level Register */
+#define AT91_SAM9X60_WLR		0x0c
+#define AT91_SAM9X60_WLR_COUNTER(x)	((x) & 0xfff)
 
 /* Hardware timeout in seconds */
 #define WDT_MAX_TIMEOUT		16
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index 988ef49..de89714 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 0000000..998fa78
--- /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
diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c
index 5feb8f7..a814973 100644
--- a/arch/arm/mach-at91/spl.c
+++ b/arch/arm/mach-at91/spl.c
@@ -14,9 +14,7 @@
 #if !defined(CONFIG_WDT_AT91)
 void at91_disable_wdt(void)
 {
-	struct at91_wdt *wdt = (struct at91_wdt *)ATMEL_BASE_WDT;
-
-	writel(AT91_WDT_MR_WDDIS, &wdt->mr);
+	writel(AT91_WDT_MR_WDDIS, ATMEL_BASE_WDT + AT91_WDT_MR);
 }
 #endif
 
diff --git a/board/atmel/sam9x75_curiosity/Kconfig b/board/atmel/sam9x75_curiosity/Kconfig
new file mode 100644
index 0000000..8ea93a2
--- /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 0000000..f0dfdbe
--- /dev/null
+++ b/board/atmel/sam9x75_curiosity/MAINTAINERS
@@ -0,0 +1,7 @@
+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
+F:	configs/sam9x75_curiosity_mmc_defconfig
diff --git a/board/atmel/sam9x75_curiosity/Makefile b/board/atmel/sam9x75_curiosity/Makefile
new file mode 100644
index 0000000..1f36d61
--- /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 0000000..4e7c566
--- /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/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c b/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
index 04de125..897fab5 100644
--- a/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
+++ b/board/atmel/sama5d27_wlsom1_ek/sama5d27_wlsom1_ek.c
@@ -65,7 +65,7 @@
 int board_init(void)
 {
 	/* address of boot parameters */
-	gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
+	gd->bd->bi_boot_params = gd->bd->bi_dram[0].start + 0x100;
 
 	rgb_leds_init();
 
@@ -82,11 +82,14 @@
 }
 #endif
 
+int dram_init_banksize(void)
+{
+	return fdtdec_setup_memory_banksize();
+}
+
 int dram_init(void)
 {
-	gd->ram_size = get_ram_size((void *)CFG_SYS_SDRAM_BASE,
-				    CFG_SYS_SDRAM_SIZE);
-	return 0;
+	return fdtdec_setup_mem_size_base();
 }
 
 /* SPL */
diff --git a/configs/sam9x75_curiosity_mmc_defconfig b/configs/sam9x75_curiosity_mmc_defconfig
new file mode 100644
index 0000000..76b8544
--- /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
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile
index e53dcb4..6cca861 100644
--- a/drivers/clk/at91/Makefile
+++ b/drivers/clk/at91/Makefile
@@ -12,6 +12,7 @@
 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/clk-main.c b/drivers/clk/at91/clk-main.c
index 09daae9..a5186f8 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -110,7 +110,7 @@
 	struct clk *clk;
 	int ret;
 
-	if (!reg || !name || !parent_name)
+	if (!reg || !name)
 		return ERR_PTR(-EINVAL);
 
 	main_rc = kzalloc(sizeof(*main_rc), GFP_KERNEL);
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c
index a30035e..df8172b 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)
@@ -31,9 +32,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 +53,15 @@
 	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 +81,7 @@
 	}
 
 	/* 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 +102,8 @@
 	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;
 
@@ -142,6 +141,7 @@
 	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;
@@ -151,8 +151,12 @@
 	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)
@@ -163,7 +167,8 @@
 	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,
@@ -360,6 +365,16 @@
 	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,
@@ -367,6 +382,12 @@
 	.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,
@@ -407,6 +428,13 @@
 			     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,
@@ -432,6 +460,13 @@
 	.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 ff46452..580c996 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -38,6 +38,7 @@
 	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;
@@ -53,6 +54,7 @@
 	u8 frac_shift;
 	u8 div_shift;
 	u8 endiv_shift;
+	u8 div2;
 };
 
 struct clk_programmable_layout {
diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c
index b7d64bd..e04266a 100644
--- a/drivers/clk/at91/sam9x60.c
+++ b/drivers/clk/at91/sam9x60.c
@@ -112,17 +112,24 @@
 	{ .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/sam9x7.c b/drivers/clk/at91/sam9x7.c
new file mode 100644
index 0000000..ad9865f
--- /dev/null
+++ b/drivers/clk/at91/sam9x7.c
@@ -0,0 +1,1085 @@
+// 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]		= "main_rc",
+	[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;
+
+	/* Register main rc oscillator. */
+	c = at91_clk_main_rc(base, clk_names[ID_MAIN_RC_OSC],
+			     NULL);
+	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,
+};
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index 63b2c64..c0e2782 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -158,11 +158,17 @@
 	{ .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. */
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index c809a89..72e1378 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -38,7 +38,7 @@
  */
 static int at91_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 {
-	struct at91_wdt_priv *priv = dev_get_priv(dev);
+	struct at91_wdt_priv *wdt = dev_get_priv(dev);
 	u64 timeout;
 	u32 ticks;
 
@@ -49,7 +49,7 @@
 	ticks = WDT_SEC2TICKS(timeout);
 
 	/* Check if disabled */
-	if (readl(priv->regs + AT91_WDT_MR) & AT91_WDT_MR_WDDIS) {
+	if (readl(wdt->regs + AT91_WDT_MR) & wdt->wddis) {
 		printf("sorry, watchdog is disabled\n");
 		return -1;
 	}
@@ -60,31 +60,41 @@
 	 * Since WDV is a 12-bit counter, the maximum period is
 	 * 4096 / 256 = 16 seconds.
 	 */
-	priv->regval = AT91_WDT_MR_WDRSTEN	/* causes watchdog reset */
-		| AT91_WDT_MR_WDDBGHLT		/* disabled in debug mode */
-		| AT91_WDT_MR_WDD(0xfff)	/* restart at any time */
-		| AT91_WDT_MR_WDV(ticks);	/* timer value */
-	writel(priv->regval, priv->regs + AT91_WDT_MR);
+
+	if (wdt->mode == AT91_WDT_MODE_SAM9260) {
+		wdt->mr = AT91_WDT_MR_WDRSTEN	/* causes watchdog reset */
+		    | AT91_WDT_MR_WDDBGHLT	/* disabled in debug mode */
+		    | AT91_WDT_MR_WDD(0xfff)	/* restart at any time */
+		    | AT91_WDT_MR_WDV(ticks);	/* timer value */
+		writel(wdt->mr, wdt->regs + AT91_WDT_MR);
+	} else if (wdt->mode == AT91_WDT_MODE_SAM9X60) {
+		writel(AT91_SAM9X60_WLR_COUNTER(ticks),	/* timer value */
+		       wdt->regs + AT91_SAM9X60_WLR);
+
+		wdt->mr = AT91_SAM9X60_MR_PERIODRST /* causes watchdog reset */
+			| AT91_SAM9X60_MR_WDDBGHLT; /* disabled in debug mode */
+		writel(wdt->mr, wdt->regs + AT91_WDT_MR);
+	}
 
 	return 0;
 }
 
 static int at91_wdt_stop(struct udevice *dev)
 {
-	struct at91_wdt_priv *priv = dev_get_priv(dev);
+	struct at91_wdt_priv *wdt = dev_get_priv(dev);
 
 	/* Disable Watchdog Timer */
-	priv->regval |= AT91_WDT_MR_WDDIS;
-	writel(priv->regval, priv->regs + AT91_WDT_MR);
+	wdt->mr |= wdt->wddis;
+	writel(wdt->mr, wdt->regs + AT91_WDT_MR);
 
 	return 0;
 }
 
 static int at91_wdt_reset(struct udevice *dev)
 {
-	struct at91_wdt_priv *priv = dev_get_priv(dev);
+	struct at91_wdt_priv *wdt = dev_get_priv(dev);
 
-	writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, priv->regs + AT91_WDT_CR);
+	writel(AT91_WDT_CR_WDRSTT | AT91_WDT_CR_KEY, wdt->regs + AT91_WDT_CR);
 
 	return 0;
 }
@@ -96,18 +106,31 @@
 };
 
 static const struct udevice_id at91_wdt_ids[] = {
-	{ .compatible = "atmel,at91sam9260-wdt" },
+	{ .compatible = "atmel,at91sam9260-wdt",
+	  .data = AT91_WDT_MODE_SAM9260 },
+	{ .compatible = "atmel,sama5d4-wdt",
+	  .data = AT91_WDT_MODE_SAM9260 },
+	{ .compatible = "microchip,sam9x60-wdt",
+	  .data = AT91_WDT_MODE_SAM9X60 },
+	{ .compatible = "microchip,sama7g5-wdt",
+	  .data = AT91_WDT_MODE_SAM9X60 },
 	{}
 };
 
 static int at91_wdt_probe(struct udevice *dev)
 {
-	struct at91_wdt_priv *priv = dev_get_priv(dev);
+	struct at91_wdt_priv *wdt = dev_get_priv(dev);
 
-	priv->regs = dev_remap_addr(dev);
-	if (!priv->regs)
+	wdt->regs = dev_remap_addr(dev);
+	if (!wdt->regs)
 		return -EINVAL;
 
+	wdt->mode = dev_get_driver_data(dev);
+	if (wdt->mode == AT91_WDT_MODE_SAM9260)
+		wdt->wddis = AT91_WDT_MR_WDDIS;
+	else if (wdt->mode == AT91_WDT_MODE_SAM9X60)
+		wdt->wddis = AT91_SAM9X60_MR_WDDIS;
+
 	debug("%s: Probing wdt%u\n", __func__, dev_seq(dev));
 
 	return 0;
diff --git a/include/configs/sam9x75_curiosity.h b/include/configs/sam9x75_curiosity.h
new file mode 100644
index 0000000..62a855d
--- /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
diff --git a/include/configs/sama5d27_wlsom1_ek.h b/include/configs/sama5d27_wlsom1_ek.h
index 1979cb3..b54e3d5 100644
--- a/include/configs/sama5d27_wlsom1_ek.h
+++ b/include/configs/sama5d27_wlsom1_ek.h
@@ -15,10 +15,4 @@
 #undef CFG_SYS_AT91_MAIN_CLOCK
 #define CFG_SYS_AT91_MAIN_CLOCK      24000000 /* from 24 MHz crystal */
 
-/* SDRAM */
-#define CFG_SYS_SDRAM_BASE		0x20000000
-#define CFG_SYS_SDRAM_SIZE		0x10000000
-
-/* SPL */
-
 #endif