driver: clock: npcx: add apb4 clock support for npcx9 series.

Add apb4 clock support for npcx9 and later series.

Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
Mulin Chao 2021-04-27 20:50:52 -07:00 committed by Carles Cufí
commit a31378dec1
3 changed files with 50 additions and 12 deletions

View file

@ -68,3 +68,23 @@ config CLOCK_NPCX_APB3_PRESCALER
12.5MHz <= APB3_CLK <= 50MHz.
- The frequency of APB3_CLK must be an integer division (including 1)
of the frequency of the Core clock.
APB3 prescaler, allowed values: From 1 to 10.
config CLOCK_NPCX_APB4_PRESCALER
int "APB4 prescaler"
default 4
range 1 10
depends on SOC_SERIES_NPCX9
help
This sets the APB4 prescaler which changes the frequency of APB4_CLK.
APB4_CLK frequency = OSC_CLK / APB4_PRE. The APB4 prescaler allowed
value is from 1 to 10. Please notice only npcx9 and later series
support this feature.
The generated frequency of APB4_CLK should comply with the following
requirements:
- The frequency of APB4_CLK must be set to:
8MHz <= APB4_CLK <= 100MHz.
- The frequency of APB4_CLK must be an integer division (including 1)
of the frequency of the Core clock.
APB4 prescaler, allowed values: From 1 to 10.

View file

@ -79,6 +79,11 @@ static int npcx_clock_control_get_subsys_rate(const struct device *dev,
case NPCX_CLOCK_BUS_APB3:
*rate = NPCX_APB_CLOCK(3);
break;
#ifdef CONFIG_CLOCK_NPCX_APB4_PRESCALER
case NPCX_CLOCK_BUS_APB4:
*rate = NPCX_APB_CLOCK(4);
break;
#endif
case NPCX_CLOCK_BUS_AHB6:
*rate = CORE_CLK/(AHB6DIV_VAL + 1);
break;
@ -139,29 +144,34 @@ static struct clock_control_driver_api npcx_clock_control_api = {
};
/* valid clock frequency check */
BUILD_ASSERT(CORE_CLK <= 100000000 &&
CORE_CLK >= 4000000 &&
BUILD_ASSERT(CORE_CLK <= MHZ(100) && CORE_CLK >= MHZ(4) &&
OSC_CLK % CORE_CLK == 0 &&
OSC_CLK / CORE_CLK <= 10,
"Invalid CORE_CLK setting");
BUILD_ASSERT(CORE_CLK / (FIUDIV_VAL + 1) <= 50000000 &&
CORE_CLK / (FIUDIV_VAL + 1) >= 4000000,
BUILD_ASSERT(CORE_CLK / (FIUDIV_VAL + 1) <= MHZ(50) &&
CORE_CLK / (FIUDIV_VAL + 1) >= MHZ(4),
"Invalid FIUCLK setting");
BUILD_ASSERT(CORE_CLK / (AHB6DIV_VAL + 1) <= 50000000 &&
CORE_CLK / (AHB6DIV_VAL + 1) >= 4000000,
BUILD_ASSERT(CORE_CLK / (AHB6DIV_VAL + 1) <= MHZ(50) &&
CORE_CLK / (AHB6DIV_VAL + 1) >= MHZ(4),
"Invalid AHB6_CLK setting");
BUILD_ASSERT(APBSRC_CLK / (APB1DIV_VAL + 1) <= 50000000 &&
APBSRC_CLK / (APB1DIV_VAL + 1) >= 4000000 &&
BUILD_ASSERT(APBSRC_CLK / (APB1DIV_VAL + 1) <= MHZ(50) &&
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) <= 50000000 &&
APBSRC_CLK / (APB2DIV_VAL + 1) >= 8000000 &&
BUILD_ASSERT(APBSRC_CLK / (APB2DIV_VAL + 1) <= MHZ(50) &&
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) <= 50000000 &&
APBSRC_CLK / (APB3DIV_VAL + 1) >= 12500000 &&
BUILD_ASSERT(APBSRC_CLK / (APB3DIV_VAL + 1) <= MHZ(50) &&
APBSRC_CLK / (APB3DIV_VAL + 1) >= KHZ(12500) &&
(APB3DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
"Invalid APB3_CLK setting");
#ifdef CONFIG_CLOCK_NPCX_APB4_PRESCALER
BUILD_ASSERT(APBSRC_CLK / (APB4DIV_VAL + 1) <= MHZ(100) &&
APBSRC_CLK / (APB4DIV_VAL + 1) >= MHZ(8) &&
(APB4DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
"Invalid APB4_CLK setting");
#endif
static int npcx_clock_control_init(const struct device *dev)
{
@ -194,7 +204,11 @@ static int npcx_clock_control_init(const struct device *dev)
inst_cdcg->HFCGP = ((FPRED_VAL << 4) | AHB6DIV_VAL);
inst_cdcg->HFCBCD = (FIUDIV_VAL << 4);
inst_cdcg->HFCBCD1 = (APB1DIV_VAL | (APB2DIV_VAL << 4));
#ifdef CONFIG_CLOCK_NPCX_APB4_PRESCALER
inst_cdcg->HFCBCD2 = (APB3DIV_VAL | (APB4DIV_VAL << 4));
#else
inst_cdcg->HFCBCD2 = APB3DIV_VAL;
#endif
/*
* Power-down (turn off clock) the modules initially for better

View file

@ -60,6 +60,10 @@ struct npcx_clk_cfg {
#define APB2DIV_VAL (CONFIG_CLOCK_NPCX_APB2_PRESCALER - 1)
/* APB3 clock divider, default value (APB3 clock = OSC_CLK/2) */
#define APB3DIV_VAL (CONFIG_CLOCK_NPCX_APB3_PRESCALER - 1)
/* APB4 clock divider, default value (APB4 clock = OSC_CLK/6) */
#ifdef CONFIG_CLOCK_NPCX_APB4_PRESCALER
#define APB4DIV_VAL (CONFIG_CLOCK_NPCX_APB4_PRESCALER - 1)
#endif
/* AHB6 clock */
#if (CORE_CLK > 50000000)