soc: nuvoton: npcx: refactor npcx soc hierarchy for future chip support

This commit refactors the NPCX SoC hierarchy to improve maintainability and
enable future support for upcoming chips.

Key changes include:
1. Introduced a new `npcxn` subdirectory under `common/` to consolidate
shared components across the npcxn series.
2. Renamed and reorganized register access files for improved consistency.
3. Updated relevant Kconfig files, header files, and CMakeLists
for the new structure.

Signed-off-by: Alvis Sun <yfsun@nuvoton.com>
This commit is contained in:
Alvis Sun 2025-03-20 14:17:17 +08:00 committed by Benjamin Cabé
commit dd578065bc
15 changed files with 786 additions and 789 deletions

View file

@ -9,4 +9,17 @@ config SOC_FAMILY_NPCX
config SOC_FAMILY
default "nuvoton_npcx" if SOC_FAMILY_NPCX
config NPCX_SOC_VARIANT_NPCXN
bool
select SOC_FAMILY_NPCX
config NPCX_SOC_VARIANT_NPCKN
bool
select SOC_FAMILY_NPCX
config NPCX_SOC_VARIANT
string
default "npcxn" if NPCX_SOC_VARIANT_NPCXN
default "npckn" if NPCX_SOC_VARIANT_NPCKN
rsource "*/Kconfig.soc"

View file

@ -1,11 +1,13 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_include_directories(.)
zephyr_sources_ifdef(CONFIG_PM power.c)
zephyr_sources(
scfg.c
registers.c
${CONFIG_NPCX_SOC_VARIANT}/registers.c
)
zephyr_include_directories(${CONFIG_NPCX_SOC_VARIANT}/include)
# Check for disabling header CRC.
if (NOT DEFINED CONFIG_NPCX_HEADER_ENABLE_HEADER_CRC)

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2020 Nuvoton Technology Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NUVOTON_NPCX_CLOCK_DEF_H_
#define _NUVOTON_NPCX_CLOCK_DEF_H_
#include <stdbool.h>
#include <stdint.h>
#include <zephyr/devicetree.h>
#include <soc_clock.h>
/* FMUL clock */
#if (OFMCLK > (MAX_OFMCLK / 2))
#define FMCLK (OFMCLK / 2) /* FMUL clock = OFMCLK/2 */
#else
#define FMCLK OFMCLK /* FMUL clock = OFMCLK */
#endif
/* APBs source clock */
#define APBSRC_CLK OFMCLK
/* AHB6 clock */
#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 > (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_CLOCK_CONTROL_NPCX_SUPP_FIU1)
#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_CLOCK_CONTROL_NPCX_SUPP_FIU1 */
/* I3C clock divider */
#if (OFMCLK == MHZ(120)) /* MCLkD must between 40 mhz to 50 mhz*/
#define MCLKD_SL 2 /* I3C_CLK = (MCLK / 3) */
#elif (OFMCLK <= MHZ(100) && OFMCLK >= MHZ(80))
#define MCLKD_SL 1 /* I3C_CLK = (MCLK / 2) */
#else
#define MCLKD_SL 0 /* I3C_CLK = MCLK */
#endif
/* Get APB clock freq */
#define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1))
/*
* Frequency multiplier M/N value definitions according to the requested
* OFMCLK (Unit:Hz).
*/
#if (OFMCLK > (MAX_OFMCLK / 2))
#define HFCGN_VAL 0x82 /* Set XF_RANGE as 1 */
#else
#define HFCGN_VAL 0x02
#endif
#if (OFMCLK == 120000000)
#define HFCGMH_VAL 0x0E
#define HFCGML_VAL 0x4E
#elif (OFMCLK == 100000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0xEC
#elif (OFMCLK == 96000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0x72
#elif (OFMCLK == 90000000)
#define HFCGMH_VAL 0x0A
#define HFCGML_VAL 0xBA
#elif (OFMCLK == 80000000)
#define HFCGMH_VAL 0x09
#define HFCGML_VAL 0x89
#elif (OFMCLK == 66000000)
#define HFCGMH_VAL 0x07
#define HFCGML_VAL 0xDE
#elif (OFMCLK == 50000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0xEC
#elif (OFMCLK == 48000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0x72
#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 */
/* I3C1~I3C3 share the same configuration */
#define VAL_HFCBCD3 MCLKD_SL
#endif /* _NUVOTON_NPCX_CLOCK_DEF_H_ */

View file

@ -6,6 +6,7 @@
#include <zephyr/device.h>
#include <soc.h>
#include "reg_def.h"
/* CDCG register structure check */
NPCX_REG_SIZE_CHECK(cdcg_reg, 0x116);

View file

@ -1,37 +0,0 @@
/*
* Copyright (c) 2020 Nuvoton Technology Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NUVOTON_NPCX_REG_ACCESS_H
#define _NUVOTON_NPCX_REG_ACCESS_H
/*
* NPCX register bit/field access operations
*/
#define GET_POS_FIELD(pos, size) pos
#define GET_SIZE_FIELD(pos, size) size
#define FIELD_POS(field) GET_POS_##field
#define FIELD_SIZE(field) GET_SIZE_##field
#define GET_FIELD(reg, field) \
_GET_FIELD_(reg, FIELD_POS(field), FIELD_SIZE(field))
#define _GET_FIELD_(reg, f_pos, f_size) (((reg)>>(f_pos)) & ((1<<(f_size))-1))
#define SET_FIELD(reg, field, value) \
_SET_FIELD_(reg, FIELD_POS(field), FIELD_SIZE(field), value)
#define _SET_FIELD_(reg, f_pos, f_size, value) \
((reg) = ((reg) & (~(((1 << (f_size))-1) << (f_pos)))) \
| ((value) << (f_pos)))
#define GET_FIELD_POS(field) \
_GET_FIELD_POS_(FIELD_POS(field))
#define _GET_FIELD_POS_(f_ops) f_ops
#define GET_FIELD_SZ(field) \
_GET_FIELD_SZ_(FIELD_SIZE(field))
#define _GET_FIELD_SZ_(f_ops) f_ops
#endif /* _NUVOTON_NPCX_REG_ACCESS_H */

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2020 Nuvoton Technology Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NUVOTON_NPCX_REG_ACCESS_H
#define _NUVOTON_NPCX_REG_ACCESS_H
/*
* NPCX register structure size/offset checking macro function to mitigate
* the risk of unexpected compiling results. All addresses of NPCX registers
* must meet the alignment requirement of cortex-m4.
* DO NOT use 'packed' attribute if module contains different length ie.
* 8/16/32 bits registers.
*/
#define NPCX_REG_SIZE_CHECK(reg_def, size) \
BUILD_ASSERT(sizeof(struct reg_def) == size, "Failed in size check of register " \
"structure!")
#define NPCX_REG_OFFSET_CHECK(reg_def, member, offset) \
BUILD_ASSERT(offsetof(struct reg_def, member) == offset, \
"Failed in offset check of register structure member!")
/*
* NPCX register access checking via structure macro function to mitigate the
* risk of unexpected compiling results if module contains different length
* registers. For example, a word register access might break into two byte
* register accesses by adding 'packed' attribute.
*
* For example, add this macro for word register 'PRSC' of PWM module in its
* device init function for checking violation. Once it occurred, core will be
* stalled forever and easy to find out what happens.
*/
#define NPCX_REG_WORD_ACCESS_CHECK(reg, val) \
{ \
uint16_t placeholder = reg; \
reg = val; \
__ASSERT(reg == val, "16-bit reg access failed!"); \
reg = placeholder; \
}
#define NPCX_REG_DWORD_ACCESS_CHECK(reg, val) \
{ \
uint32_t placeholder = reg; \
reg = val; \
__ASSERT(reg == val, "32-bit reg access failed!"); \
reg = placeholder; \
}
/*
* NPCX register bit/field access operations
*/
#define GET_POS_FIELD(pos, size) pos
#define GET_SIZE_FIELD(pos, size) size
#define FIELD_POS(field) GET_POS_##field
#define FIELD_SIZE(field) GET_SIZE_##field
#define GET_FIELD(reg, field) _GET_FIELD_(reg, FIELD_POS(field), FIELD_SIZE(field))
#define _GET_FIELD_(reg, f_pos, f_size) (((reg) >> (f_pos)) & ((1 << (f_size)) - 1))
#define SET_FIELD(reg, field, value) _SET_FIELD_(reg, FIELD_POS(field), FIELD_SIZE(field), value)
#define _SET_FIELD_(reg, f_pos, f_size, value) \
((reg) = ((reg) & (~(((1 << (f_size)) - 1) << (f_pos)))) | ((value) << (f_pos)))
#define GET_FIELD_POS(field) _GET_FIELD_POS_(FIELD_POS(field))
#define _GET_FIELD_POS_(f_ops) f_ops
#define GET_FIELD_SZ(field) _GET_FIELD_SZ_(FIELD_SIZE(field))
#define _GET_FIELD_SZ_(f_ops) f_ops
#endif /* _NUVOTON_NPCX_REG_ACCESS_H */

View file

@ -26,16 +26,16 @@ extern "C" {
* register/bit to turn on/off its source clock.
*/
struct npcx_clk_cfg {
uint16_t bus:8;
uint16_t ctrl:5;
uint16_t bit:3;
uint16_t bus: 8;
uint16_t ctrl: 5;
uint16_t bit: 3;
};
/* Clock settings from pcc node */
/* Target OFMCLK freq */
#define OFMCLK DT_PROP(DT_NODELABEL(pcc), clock_frequency)
#define OFMCLK DT_PROP(DT_NODELABEL(pcc), clock_frequency)
/* Core clock prescaler */
#define FPRED_VAL (DT_PROP(DT_NODELABEL(pcc), core_prescaler) - 1)
#define FPRED_VAL (DT_PROP(DT_NODELABEL(pcc), core_prescaler) - 1)
/* APB1 clock divider */
#define APB1DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb1_prescaler) - 1)
/* APB2 clock divider */
@ -53,8 +53,8 @@ struct npcx_clk_cfg {
/* 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)
#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:
@ -71,105 +71,7 @@ struct npcx_clk_cfg {
/* Core domain clock */
#define CORE_CLK (OFMCLK / DT_PROP(DT_NODELABEL(pcc), core_prescaler))
/* Low Frequency clock */
#define LFCLK 32768
/* FMUL clock */
#if (OFMCLK > (MAX_OFMCLK / 2))
#define FMCLK (OFMCLK / 2) /* FMUL clock = OFMCLK/2 */
#else
#define FMCLK OFMCLK /* FMUL clock = OFMCLK */
#endif
/* APBs source clock */
#define APBSRC_CLK OFMCLK
/* AHB6 clock */
#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 > (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_CLOCK_CONTROL_NPCX_SUPP_FIU1)
#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_CLOCK_CONTROL_NPCX_SUPP_FIU1 */
/* I3C clock divider */
#if (OFMCLK == MHZ(120)) /* MCLkD must between 40 mhz to 50 mhz*/
#define MCLKD_SL 2 /* I3C_CLK = (MCLK / 3) */
#elif (OFMCLK <= MHZ(100) && OFMCLK >= MHZ(80))
#define MCLKD_SL 1 /* I3C_CLK = (MCLK / 2) */
#else
#define MCLKD_SL 0 /* I3C_CLK = MCLK */
#endif
/* Get APB clock freq */
#define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1))
/*
* Frequency multiplier M/N value definitions according to the requested
* OFMCLK (Unit:Hz).
*/
#if (OFMCLK > (MAX_OFMCLK / 2))
#define HFCGN_VAL 0x82 /* Set XF_RANGE as 1 */
#else
#define HFCGN_VAL 0x02
#endif
#if (OFMCLK == 120000000)
#define HFCGMH_VAL 0x0E
#define HFCGML_VAL 0x4E
#elif (OFMCLK == 100000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0xEC
#elif (OFMCLK == 96000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0x72
#elif (OFMCLK == 90000000)
#define HFCGMH_VAL 0x0A
#define HFCGML_VAL 0xBA
#elif (OFMCLK == 80000000)
#define HFCGMH_VAL 0x09
#define HFCGML_VAL 0x89
#elif (OFMCLK == 66000000)
#define HFCGMH_VAL 0x07
#define HFCGML_VAL 0xDE
#elif (OFMCLK == 50000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0xEC
#elif (OFMCLK == 48000000)
#define HFCGMH_VAL 0x0B
#define HFCGML_VAL 0x72
#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 */
/* I3C1~I3C3 share the same configuration */
#define VAL_HFCBCD3 MCLKD_SL
#define LFCLK 32768
/**
* @brief Function to notify clock driver that backup the counter value of

View file

@ -9,7 +9,7 @@
#include <stdint.h>
#include "reg/reg_def.h"
#include "reg_def.h"
#ifdef __cplusplus
extern "C" {

View file

@ -5,7 +5,7 @@
config SOC_SERIES_NPCX4
bool
select SOC_FAMILY_NPCX
select NPCX_SOC_VARIANT_NPCXN
help
Enable support for Nuvoton NPCX4 series

View file

@ -50,10 +50,9 @@
/* NPCX4 Clock Configuration */
#define MAX_OFMCLK 120000000
#include <reg/reg_access.h>
#include <reg/reg_def.h>
#include "reg_def.h"
#include "clock_def.h"
#include <soc_dt.h>
#include <soc_clock.h>
#include <soc_espi_taf.h>
#include <soc_pins.h>
#include <soc_power.h>

View file

@ -5,7 +5,7 @@
config SOC_SERIES_NPCX7
bool
select SOC_FAMILY_NPCX
select NPCX_SOC_VARIANT_NPCXN
help
Enable support for Nuvoton NPCX7 series

View file

@ -42,10 +42,9 @@
/* NPCX7 Clock configuration */
#define MAX_OFMCLK 100000000
#include <reg/reg_access.h>
#include <reg/reg_def.h>
#include "reg_def.h"
#include "clock_def.h"
#include <soc_dt.h>
#include <soc_clock.h>
#include <soc_pins.h>
#include <soc_power.h>

View file

@ -5,7 +5,7 @@
config SOC_SERIES_NPCX9
bool
select SOC_FAMILY_NPCX
select NPCX_SOC_VARIANT_NPCXN
help
Enable support for Nuvoton NPCX9 series

View file

@ -47,10 +47,9 @@
/* NPCX9 Clock configuration and limitation */
#define MAX_OFMCLK 100000000
#include <reg/reg_access.h>
#include <reg/reg_def.h>
#include "reg_def.h"
#include "clock_def.h"
#include <soc_dt.h>
#include <soc_clock.h>
#include <soc_pins.h>
#include <soc_power.h>