driver: clock_control: npcx: add support for npcx4 series

This CL introduces new clock architectures in npcx4 series and wraps
clock configurations of different series by device tree files.

For example, the PWDWN_CTLx reg initialization relies on `pwdwn-ctl-val`
prop of pcc DT node now.

Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
diff --git a/drivers/clock_control/clock_control_npcx.c b/drivers/clock_control/clock_control_npcx.c
index 82199d6..dcc4a92 100644
--- a/drivers/clock_control/clock_control_npcx.c
+++ b/drivers/clock_control/clock_control_npcx.c
@@ -28,6 +28,8 @@
 #define HAL_PMC_INST(dev) \
 	((struct pmc_reg *)((const struct npcx_pcc_config *)(dev)->config)->base_pmc)
 
+static uint8_t pddwn_ctl_val[] = {NPCX_PWDWN_CTL_INIT};
+
 /* Clock controller local functions */
 static inline int npcx_clock_control_on(const struct device *dev,
 					 clock_control_subsys_t sub_system)
@@ -89,6 +91,11 @@
 	case NPCX_CLOCK_BUS_FIU:
 		*rate = CORE_CLK/(FIUDIV_VAL + 1);
 		break;
+#if defined(FIU1DIV_VAL)
+	case NPCX_CLOCK_BUS_FIU1:
+		*rate = CORE_CLK/(FIU1DIV_VAL + 1);
+		break;
+#endif
 	case NPCX_CLOCK_BUS_CORE:
 		*rate = CORE_CLK;
 		break;
@@ -144,30 +151,36 @@
 };
 
 /* valid clock frequency check */
-BUILD_ASSERT(CORE_CLK <= MHZ(100) && CORE_CLK >= MHZ(4) &&
+BUILD_ASSERT(OFMCLK <= MAX_OFMCLK, "Exceed maximum OFMCLK setting");
+BUILD_ASSERT(CORE_CLK <= MAX_OFMCLK && CORE_CLK >= MHZ(4) &&
 	     OFMCLK % CORE_CLK == 0 &&
 	     OFMCLK / CORE_CLK <= 10,
 	     "Invalid CORE_CLK setting");
-BUILD_ASSERT(CORE_CLK / (FIUDIV_VAL + 1) <= MHZ(50) &&
+BUILD_ASSERT(CORE_CLK / (FIUDIV_VAL + 1) <= (MAX_OFMCLK / 2) &&
 	     CORE_CLK / (FIUDIV_VAL + 1) >= MHZ(4),
 	     "Invalid FIUCLK setting");
-BUILD_ASSERT(CORE_CLK / (AHB6DIV_VAL + 1) <= MHZ(50) &&
+#if defined(FIU1DIV_VAL)
+BUILD_ASSERT(CORE_CLK / (FIU1DIV_VAL + 1) <= (MAX_OFMCLK / 2) &&
+	     CORE_CLK / (FIU1DIV_VAL + 1) >= MHZ(4),
+	     "Invalid FIU1CLK setting");
+#endif
+BUILD_ASSERT(CORE_CLK / (AHB6DIV_VAL + 1) <= (MAX_OFMCLK / 2) &&
 	     CORE_CLK / (AHB6DIV_VAL + 1) >= MHZ(4),
 	     "Invalid AHB6_CLK setting");
-BUILD_ASSERT(APBSRC_CLK / (APB1DIV_VAL + 1) <= MHZ(50) &&
+BUILD_ASSERT(APBSRC_CLK / (APB1DIV_VAL + 1) <= (MAX_OFMCLK / 2) &&
 	     APBSRC_CLK / (APB1DIV_VAL + 1) >= MHZ(4) &&
 	     (APB1DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
 	     "Invalid APB1_CLK setting");
-BUILD_ASSERT(APBSRC_CLK / (APB2DIV_VAL + 1) <= MHZ(50) &&
+BUILD_ASSERT(APBSRC_CLK / (APB2DIV_VAL + 1) <= (MAX_OFMCLK / 2) &&
 	     APBSRC_CLK / (APB2DIV_VAL + 1) >= MHZ(8) &&
 	     (APB2DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
 	     "Invalid APB2_CLK setting");
-BUILD_ASSERT(APBSRC_CLK / (APB3DIV_VAL + 1) <= MHZ(50) &&
+BUILD_ASSERT(APBSRC_CLK / (APB3DIV_VAL + 1) <= (MAX_OFMCLK / 2) &&
 	     APBSRC_CLK / (APB3DIV_VAL + 1) >= KHZ(12500) &&
 	     (APB3DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
 	     "Invalid APB3_CLK setting");
 #if defined(APB4DIV_VAL)
-BUILD_ASSERT(APBSRC_CLK / (APB4DIV_VAL + 1) <= MHZ(100) &&
+BUILD_ASSERT(APBSRC_CLK / (APB4DIV_VAL + 1) <= MAX_OFMCLK &&
 	     APBSRC_CLK / (APB4DIV_VAL + 1) >= MHZ(8) &&
 	     (APB4DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
 	     "Invalid APB4_CLK setting");
@@ -205,36 +218,23 @@
 	}
 
 	/* Set all clock prescalers of core and peripherals. */
-	inst_cdcg->HFCGP   = ((FPRED_VAL << 4) | AHB6DIV_VAL);
-	inst_cdcg->HFCBCD  = (FIUDIV_VAL << 4);
-	inst_cdcg->HFCBCD1 = (APB1DIV_VAL | (APB2DIV_VAL << 4));
-#if defined(APB4DIV_VAL)
-	inst_cdcg->HFCBCD2 = (APB3DIV_VAL | (APB4DIV_VAL << 4));
-#else
-	inst_cdcg->HFCBCD2 = APB3DIV_VAL;
-#endif
+	inst_cdcg->HFCGP   = VAL_HFCGP;
+	inst_cdcg->HFCBCD  = VAL_HFCBCD;
+	inst_cdcg->HFCBCD1 = VAL_HFCBCD1;
+	inst_cdcg->HFCBCD2 = VAL_HFCBCD2;
 
 	/*
 	 * Power-down (turn off clock) the modules initially for better
 	 * power consumption.
 	 */
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL1) = 0xFB; /* No SDP_PD/FIU_PD */
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL2) = 0xFF;
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL3) = 0x1F; /* No GDMA_PD */
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL4) = 0xFF;
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL5) = 0xFA;
-#if CONFIG_ESPI
-	/* Don't gate the clock of the eSPI module if eSPI interface is required */
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL6) = 0x7F;
-#else
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL6) = 0xFF;
-#endif
-#if defined(CONFIG_SOC_SERIES_NPCX7)
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL7) = 0xE7;
-#elif defined(CONFIG_SOC_SERIES_NPCX9)
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL7) = 0xFF;
-	NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL8) = 0x31;
-#endif
+	for (int i = 0; i < ARRAY_SIZE(pddwn_ctl_val); i++) {
+		NPCX_PWDWN_CTL(pmc_base, i) = pddwn_ctl_val[i];
+	}
+
+	/* Turn off the clock of the eSPI module only if eSPI isn't required */
+	if (!IS_ENABLED(CONFIG_ESPI)) {
+		NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL6) |= BIT(7);
+	}
 
 	return 0;
 }
diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi
index 9087681..cbad55d 100644
--- a/dts/arm/nuvoton/npcx/npcx4.dtsi
+++ b/dts/arm/nuvoton/npcx/npcx4.dtsi
@@ -115,6 +115,14 @@
 			apb3-prescaler = <8>; /* APB3_CLK runs at 15MHz */
 			apb4-prescaler = <8>; /* APB4_CLK runs at 15MHz */
 			ram-pd-depth = <8>; /* Valid bit-depth of RAM_PDn reg */
+			pwdwn-ctl-val = <0xfb
+					 0xff
+					 0x1f /* No GDMA1_PD/GDMA2_PD */
+					 0xff
+					 0xfa
+					 0x7f /* No ESPI_PD */
+					 0xff
+					 0xcf>; /* No FIU_PD */
 		};
 
 		/* Wake-up input source mapping for GPIOs in npcx4 series */
diff --git a/dts/arm/nuvoton/npcx/npcx7.dtsi b/dts/arm/nuvoton/npcx/npcx7.dtsi
index ee984d9..7181592 100644
--- a/dts/arm/nuvoton/npcx/npcx7.dtsi
+++ b/dts/arm/nuvoton/npcx/npcx7.dtsi
@@ -94,6 +94,13 @@
 			apb2-prescaler = <6>; /* APB2_CLK runs at 15MHz */
 			apb3-prescaler = <6>; /* APB3_CLK runs at 15MHz */
 			ram-pd-depth = <12>; /* Valid bit-depth of RAM_PDn reg */
+			pwdwn-ctl-val = <0xfb /* No FIU_PD */
+					 0xff
+					 0x1f /* No GDMA_PD */
+					 0xff
+					 0xfa
+					 0x7f /* No ESPI_PD */
+					 0xe7>;
 		};
 
 		/* Wake-up input source mapping for GPIOs in npcx7 series */
diff --git a/dts/arm/nuvoton/npcx/npcx9.dtsi b/dts/arm/nuvoton/npcx/npcx9.dtsi
index 7c2c47b..14b74e6 100644
--- a/dts/arm/nuvoton/npcx/npcx9.dtsi
+++ b/dts/arm/nuvoton/npcx/npcx9.dtsi
@@ -114,6 +114,14 @@
 			apb3-prescaler = <6>; /* APB3_CLK runs at 15MHz */
 			apb4-prescaler = <6>; /* APB4_CLK runs at 15MHz */
 			ram-pd-depth = <15>; /* Valid bit-depth of RAM_PDn reg */
+			pwdwn-ctl-val = <0xfb /* No FIU_PD */
+					 0xff
+					 0x1f /* No GDMA_PD */
+					 0xff
+					 0xfa
+					 0x7f /* No ESPI_PD */
+					 0xff
+					 0x31>;
 		};
 
 		/* Wake-up input source mapping for GPIOs in npcx9 series */
diff --git a/dts/bindings/clock/nuvoton,npcx-pcc.yaml b/dts/bindings/clock/nuvoton,npcx-pcc.yaml
index 258e5c6..00fbf0d 100644
--- a/dts/bindings/clock/nuvoton,npcx-pcc.yaml
+++ b/dts/bindings/clock/nuvoton,npcx-pcc.yaml
@@ -32,6 +32,7 @@
     description: |
       Default frequency in Hz for HFCG output clock (OFMCLK). Currently,
       only the following values are allowed:
+        120000000, 120 MHz
         100000000, 100 MHz
         96000000, 96 MHz
         90000000, 90 MHz
@@ -39,9 +40,8 @@
         66000000, 66 MHz
         50000000, 50 MHz
         48000000, 48 MHz
-        40000000, 40 MHz (default value after reset)
-        33000000, 33 MHz
     enum:
+      - 120000000
       - 100000000
       - 96000000
       - 90000000
@@ -49,8 +49,6 @@
       - 66000000
       - 50000000
       - 48000000
-      - 40000000
-      - 33000000
 
   core-prescaler:
     type: int
@@ -208,6 +206,7 @@
   ram-pd-depth:
     type: int
     enum:
+      - 8
       - 12
       - 15
     description: |
@@ -216,6 +215,13 @@
       itself to 1 for better power consumption and this valid bit-depth
       varies in different NPCX series.
 
+  pwdwn-ctl-val:
+    type: array
+    required: true
+    description: |
+      Power-down (turn off clock) the modules during system initialization for
+      better power consumption.
+
 clock-cells:
   - bus
   - ctl
diff --git a/include/zephyr/dt-bindings/clock/npcx_clock.h b/include/zephyr/dt-bindings/clock/npcx_clock.h
index adca438..713a05c 100644
--- a/include/zephyr/dt-bindings/clock/npcx_clock.h
+++ b/include/zephyr/dt-bindings/clock/npcx_clock.h
@@ -18,6 +18,8 @@
 #define NPCX_CLOCK_BUS_APB4        8
 #define NPCX_CLOCK_BUS_AHB6        9
 #define NPCX_CLOCK_BUS_FMCLK       10
+#define NPCX_CLOCK_BUS_FIU0        NPCX_CLOCK_BUS_FIU
+#define NPCX_CLOCK_BUS_FIU1        11
 
 /* clock enable/disable references */
 #define NPCX_PWDWN_CTL1            0
diff --git a/soc/arm/nuvoton_npcx/common/soc_clock.h b/soc/arm/nuvoton_npcx/common/soc_clock.h
index afefba8..cda024d 100644
--- a/soc/arm/nuvoton_npcx/common/soc_clock.h
+++ b/soc/arm/nuvoton_npcx/common/soc_clock.h
@@ -51,15 +51,28 @@
 #endif /* !CONFIG_SOC_SERIES_NPCX7 */
 #endif
 
+/* Construct a uint8_t array from 'pwdwn-ctl-val' prop for PWDWN_CTL initialization. */
+#define NPCX_PWDWN_CTL_ITEMS_INIT(node, prop, idx) DT_PROP_BY_IDX(node, prop, idx),
+#define NPCX_PWDWN_CTL_INIT DT_FOREACH_PROP_ELEM(DT_NODELABEL(pcc), \
+				pwdwn_ctl_val, NPCX_PWDWN_CTL_ITEMS_INIT)
+
 /*
  * NPCX7 and later series clock tree macros:
  * (Please refer Figure 58. for more information.)
  *
- * Suggestion:
- * - OFMCLK > 50MHz, XF_RANGE should be 1, else 0.
- * - CORE_CLK > 50MHz, AHB6DIV should be 1, else 0.
- * - CORE_CLK > 50MHz, FIUDIV should be 1, else 0.
+ * Maximum OFMCLK in npcx7/9 series is 100MHz,
+ * Maximum OFMCLK in npcx4 series is 120MHz,
+ *
+ * Suggestion for npcx series:
+ * - OFMCLK   > MAX_OFMCLK/2, XF_RANGE should be 1, else 0.
+ * - CORE_CLK > MAX_OFMCLK/2, AHB6DIV should be 1, else 0.
+ * - CORE_CLK > MAX_OFMCLK/2, FIUDIV should be 1, else 0.
  */
+#if defined(CONFIG_SOC_SERIES_NPCX4)
+#define MAX_OFMCLK 120000000
+#else
+#define MAX_OFMCLK 100000000
+#endif /* CONFIG_SOC_SERIES_NPCX4 */
 
 /* Core domain clock */
 #define CORE_CLK (OFMCLK / DT_PROP(DT_NODELABEL(pcc), core_prescaler))
@@ -67,8 +80,8 @@
 #define LFCLK 32768
 
 /* FMUL clock */
-#if (OFMCLK > 50000000)
-#define FMCLK (OFMCLK / 2) /* FMUL clock = OFMCLK/2 if OFMCLK > 50MHz */
+#if (OFMCLK > (MAX_OFMCLK / 2))
+#define FMCLK (OFMCLK / 2) /* FMUL clock = OFMCLK/2 */
 #else
 #define FMCLK OFMCLK /* FMUL clock = OFMCLK */
 #endif
@@ -77,18 +90,27 @@
 #define APBSRC_CLK OFMCLK
 
 /* AHB6 clock */
-#if (CORE_CLK > 50000000)
-#define AHB6DIV_VAL 1 /* AHB6_CLK = CORE_CLK/2 if CORE_CLK > 50MHz */
+#if (CORE_CLK > (MAX_OFMCLK / 2))
+#define AHB6DIV_VAL 1 /* AHB6_CLK = CORE_CLK/2 */
 #else
 #define AHB6DIV_VAL 0 /* AHB6_CLK = CORE_CLK */
 #endif
+
 /* FIU clock divider */
-#if (CORE_CLK > 50000000)
+#if (CORE_CLK > (MAX_OFMCLK / 2))
 #define FIUDIV_VAL 1 /* FIU_CLK = CORE_CLK/2 */
 #else
 #define FIUDIV_VAL 0 /* FIU_CLK = CORE_CLK */
 #endif
 
+#if defined(CONFIG_SOC_SERIES_NPCX4)
+#if (CORE_CLK > (MAX_OFMCLK / 2))
+#define FIU1DIV_VAL 1 /* FIU1_CLK = CORE_CLK/2 */
+#else
+#define FIU1DIV_VAL 0 /* FIU1_CLK = CORE_CLK */
+#endif
+#endif /* CONFIG_SOC_SERIES_NPCX4 */
+
 /* Get APB clock freq */
 #define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1))
 
@@ -96,8 +118,8 @@
  * Frequency multiplier M/N value definitions according to the requested
  * OFMCLK (Unit:Hz).
  */
-#if (OFMCLK > 50000000)
-#define HFCGN_VAL    0x82 /* Set XF_RANGE as 1 if OFMCLK > 50MHz */
+#if (OFMCLK > (MAX_OFMCLK / 2))
+#define HFCGN_VAL    0x82 /* Set XF_RANGE as 1 */
 #else
 #define HFCGN_VAL    0x02
 #endif
@@ -125,16 +147,24 @@
 #elif (OFMCLK == 48000000)
 #define HFCGMH_VAL   0x0B
 #define HFCGML_VAL   0x72
-#elif (OFMCLK == 40000000)
-#define HFCGMH_VAL   0x09
-#define HFCGML_VAL   0x89
-#elif (OFMCLK == 33000000)
-#define HFCGMH_VAL   0x07
-#define HFCGML_VAL   0xDE
 #else
 #error "Unsupported OFMCLK Frequency"
 #endif
 
+/* Clock prescaler configurations in different series */
+#define VAL_HFCGP   ((FPRED_VAL << 4) | AHB6DIV_VAL)
+#if defined(FIU1DIV_VAL)
+#define VAL_HFCBCD  ((FIU1DIV_VAL << 4) | (FIUDIV_VAL << 2))
+#else
+#define VAL_HFCBCD  (FIUDIV_VAL << 4)
+#endif /* FIU1DIV_VAL */
+#define VAL_HFCBCD1 (APB1DIV_VAL | (APB2DIV_VAL << 4))
+#if defined(APB4DIV_VAL)
+#define VAL_HFCBCD2 (APB3DIV_VAL | (APB4DIV_VAL << 4))
+#else
+#define VAL_HFCBCD2 APB3DIV_VAL
+#endif /* APB4DIV_VAL */
+
 /**
  * @brief Function to notify clock driver that backup the counter value of
  *        low-frequency timer before ec entered deep idle state.