driver: clock: Add clock controller support in NPCX series.
Add clock controller support for Nuvoton NPCX series. This CL includes: 1. Add clock controller device tree declarations. 2. Introduce clock-cells in yaml file clock tree to get module's source clock and turn off/on the its clock 3. Clock controller driver implementation. Signed-off-by: Mulin Chao <MLChao@nuvoton.com>
This commit is contained in:
parent
ec50b1846f
commit
0245a27bc5
14 changed files with 555 additions and 0 deletions
|
@ -150,6 +150,7 @@
|
|||
/drivers/can/*mcp2515* @karstenkoenig
|
||||
/drivers/clock_control/*nrf* @nordic-krch
|
||||
/drivers/clock_control/*esp32* @extremegtx
|
||||
/drivers/clock_control/*npcx* @MulinChao
|
||||
/drivers/counter/ @nordic-krch
|
||||
/drivers/console/semihost_console.c @luozhongyao
|
||||
/drivers/counter/counter_cmos.c @andrewboie
|
||||
|
|
|
@ -7,6 +7,7 @@ zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_MCG clock_control_mcux
|
|||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_PCC clock_control_mcux_pcc.c)
|
||||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SCG clock_control_mcux_scg.c)
|
||||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_MCUX_SIM clock_control_mcux_sim.c)
|
||||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_NPCX clock_control_npcx.c)
|
||||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF nrf_power_clock.c)
|
||||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION nrf_clock_calibration.c)
|
||||
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_RV32M1_PCC clock_control_rv32m1_pcc.c)
|
||||
|
|
|
@ -38,6 +38,8 @@ source "drivers/clock_control/Kconfig.mcux_scg"
|
|||
|
||||
source "drivers/clock_control/Kconfig.mcux_sim"
|
||||
|
||||
source "drivers/clock_control/Kconfig.npcx"
|
||||
|
||||
source "drivers/clock_control/Kconfig.rv32m1"
|
||||
|
||||
source "drivers/clock_control/Kconfig.esp32"
|
||||
|
|
43
drivers/clock_control/Kconfig.npcx
Normal file
43
drivers/clock_control/Kconfig.npcx
Normal file
|
@ -0,0 +1,43 @@
|
|||
# NPCX Clock controller driver configuration options
|
||||
|
||||
# Copyright (c) 2020 Nuvoton Technology Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config CLOCK_CONTROL_NPCX
|
||||
bool "NPCX clock controller driver"
|
||||
depends on SOC_FAMILY_NPCX
|
||||
help
|
||||
Enable support for NPCX clock controller driver.
|
||||
|
||||
config CLOCK_NPCX_OSC_CYCLES_PER_SEC
|
||||
int "CDCG PLL frequency"
|
||||
default 48000000
|
||||
range 10000000 100000000
|
||||
depends on SOC_FAMILY_NPCX
|
||||
help
|
||||
Core Domain Clock Generator PLL frequency,
|
||||
allowed values: From 10Mhz to 100Mhz.
|
||||
|
||||
config CLOCK_NPCX_APB1_PRESCALER
|
||||
int "APB1 prescaler"
|
||||
default 4
|
||||
range 1 10
|
||||
depends on SOC_FAMILY_NPCX
|
||||
help
|
||||
APB1 prescaler, allowed values: From 1 to 10.
|
||||
|
||||
config CLOCK_NPCX_APB2_PRESCALER
|
||||
int "APB1 prescaler"
|
||||
default 8
|
||||
range 1 10
|
||||
depends on SOC_FAMILY_NPCX
|
||||
help
|
||||
APB2 prescaler, allowed values: From 1 to 10.
|
||||
|
||||
config CLOCK_NPCX_APB3_PRESCALER
|
||||
int "APB3 prescaler"
|
||||
default 2
|
||||
range 1 10
|
||||
depends on SOC_FAMILY_NPCX
|
||||
help
|
||||
APB3 prescaler, allowed values: From 1 to 10.
|
162
drivers/clock_control/clock_control_npcx.c
Normal file
162
drivers/clock_control/clock_control_npcx.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nuvoton Technology Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT nuvoton_npcx_pcc
|
||||
|
||||
#include <soc.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <dt-bindings/clock/npcx_clock.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(clock_control_npcx, LOG_LEVEL_ERR);
|
||||
|
||||
/* Driver config */
|
||||
struct npcx_pcc_config {
|
||||
/* cdcg device base address */
|
||||
uint32_t base_cdcg;
|
||||
/* pmc device base address */
|
||||
uint32_t base_pmc;
|
||||
};
|
||||
|
||||
/* Driver convenience defines */
|
||||
#define DRV_CONFIG(dev) \
|
||||
((const struct npcx_pcc_config *)(dev)->config)
|
||||
|
||||
#define HAL_CDCG_INST(dev) \
|
||||
(struct cdcg_reg_t *)(DRV_CONFIG(dev)->base_cdcg)
|
||||
|
||||
#define HAL_PMC_INST(dev) \
|
||||
(struct pmc_reg_t *)(DRV_CONFIG(dev)->base_pmc)
|
||||
|
||||
/* Clock controller local functions */
|
||||
static inline int npcx_clock_control_on(struct device *dev,
|
||||
clock_control_subsys_t sub_system)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
struct npcx_clk_cfg *clk_cfg = (struct npcx_clk_cfg *)(sub_system);
|
||||
uint32_t pmc_base = DRV_CONFIG(dev)->base_pmc;
|
||||
|
||||
/* Clear related PD (Power-Down) bit of module to turn on clock */
|
||||
NPCX_PWDWN_CTL(pmc_base, clk_cfg->ctrl) &= ~(BIT(clk_cfg->bit));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int npcx_clock_control_off(struct device *dev,
|
||||
clock_control_subsys_t sub_system)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
struct npcx_clk_cfg *clk_cfg = (struct npcx_clk_cfg *)(sub_system);
|
||||
uint32_t pmc_base = DRV_CONFIG(dev)->base_pmc;
|
||||
|
||||
/* Set related PD (Power-Down) bit of module to turn off clock */
|
||||
NPCX_PWDWN_CTL(pmc_base, clk_cfg->ctrl) |= BIT(clk_cfg->bit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int npcx_clock_control_get_subsys_rate(struct device *dev,
|
||||
clock_control_subsys_t sub_system,
|
||||
uint32_t *rate)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
struct npcx_clk_cfg *clk_cfg = (struct npcx_clk_cfg *)(sub_system);
|
||||
|
||||
switch (clk_cfg->bus) {
|
||||
case NPCX_CLOCK_BUS_APB1:
|
||||
*rate = NPCX_APB_CLOCK(1);
|
||||
break;
|
||||
case NPCX_CLOCK_BUS_APB2:
|
||||
*rate = NPCX_APB_CLOCK(2);
|
||||
break;
|
||||
case NPCX_CLOCK_BUS_APB3:
|
||||
*rate = NPCX_APB_CLOCK(3);
|
||||
break;
|
||||
case NPCX_CLOCK_BUS_AHB6:
|
||||
*rate = CORE_CLK/(AHB6DIV_VAL + 1);
|
||||
break;
|
||||
case NPCX_CLOCK_BUS_FIU:
|
||||
*rate = CORE_CLK/(FIUDIV_VAL + 1);
|
||||
break;
|
||||
case NPCX_CLOCK_BUS_CORE:
|
||||
*rate = CORE_CLK;
|
||||
break;
|
||||
case NPCX_CLOCK_BUS_LFCLK:
|
||||
*rate = LFCLK;
|
||||
break;
|
||||
default:
|
||||
*rate = 0U;
|
||||
/* Invalid parameters */
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clock controller driver registration */
|
||||
static struct clock_control_driver_api npcx_clock_control_api = {
|
||||
.on = npcx_clock_control_on,
|
||||
.off = npcx_clock_control_off,
|
||||
.get_rate = npcx_clock_control_get_subsys_rate,
|
||||
};
|
||||
|
||||
static int npcx_clock_control_init(struct device *dev)
|
||||
{
|
||||
struct cdcg_reg_t *inst_cdcg = HAL_CDCG_INST(dev);
|
||||
uint32_t pmc_base = DRV_CONFIG(dev)->base_pmc;
|
||||
|
||||
/*
|
||||
* Resetting the OSC_CLK (even to the same value) will make the clock
|
||||
* unstable for a little which can affect peripheral communication like
|
||||
* eSPI. Skip this if not needed.
|
||||
*/
|
||||
if (inst_cdcg->HFCGN != HFCGN_VAL || inst_cdcg->HFCGML != HFCGML_VAL
|
||||
|| inst_cdcg->HFCGMH != HFCGMH_VAL) {
|
||||
/*
|
||||
* Configure frequency multiplier M/N values according to
|
||||
* the requested OSC_CLK (Unit:Hz).
|
||||
*/
|
||||
inst_cdcg->HFCGN = HFCGN_VAL;
|
||||
inst_cdcg->HFCGML = HFCGML_VAL;
|
||||
inst_cdcg->HFCGMH = HFCGMH_VAL;
|
||||
|
||||
/* Load M and N values into the frequency multiplier */
|
||||
inst_cdcg->HFCGCTRL |= BIT(NPCX_HFCGCTRL_LOAD);
|
||||
/* Wait for stable */
|
||||
while (IS_BIT_SET(inst_cdcg->HFCGCTRL, NPCX_HFCGCTRL_CLK_CHNG))
|
||||
;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
inst_cdcg->HFCBCD2 = APB3DIV_VAL;
|
||||
|
||||
/*
|
||||
* Power-down (turn off clock) the modules initially for better
|
||||
* power consumption.
|
||||
*/
|
||||
NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL1) = 0xF9; /* 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;
|
||||
NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL6) = 0xFF;
|
||||
NPCX_PWDWN_CTL(pmc_base, NPCX_PWDWN_CTL7) = 0xE7;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct npcx_pcc_config pcc_config = {
|
||||
.base_cdcg = DT_INST_REG_ADDR_BY_NAME(0, cdcg),
|
||||
.base_pmc = DT_INST_REG_ADDR_BY_NAME(0, pmc),
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(npcx_cdcg, NPCX_CLOCK_CONTROL_NAME,
|
||||
&npcx_clock_control_init,
|
||||
NULL, &pcc_config,
|
||||
PRE_KERNEL_1,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_OBJECTS,
|
||||
&npcx_clock_control_api);
|
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
|
||||
#include <arm/armv7-m.dtsi>
|
||||
/* Macros for device tree declarations */
|
||||
#include <dt-bindings/clock/npcx_clock.h>
|
||||
|
||||
/ {
|
||||
cpus {
|
||||
|
@ -26,6 +28,20 @@
|
|||
compatible = "mmio-sram";
|
||||
reg = <0x200C0000 0x10000>;
|
||||
};
|
||||
|
||||
soc {
|
||||
pcc: clock-controller@4000d000 {
|
||||
compatible = "nuvoton,npcx-pcc";
|
||||
/* Cells for bus type, clock control reg and bit */
|
||||
#clock-cells = <3>;
|
||||
/* First reg region is Power Management Controller */
|
||||
/* Second reg region is Core Domain Clock Generator */
|
||||
reg = <0x4000d000 0x2000
|
||||
0x400b5000 0x2000>;
|
||||
reg-names = "pmc", "cdcg";
|
||||
label = "PMC_CDCG";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&nvic {
|
||||
|
|
17
dts/bindings/clock/nuvoton,npcx-pcc.yaml
Normal file
17
dts/bindings/clock/nuvoton,npcx-pcc.yaml
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2020 Nuvoton Technology Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Nuvoton, NPCX PCC (Power and Clock Controller) node
|
||||
|
||||
compatible: "nuvoton,npcx-pcc"
|
||||
|
||||
include: [clock-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
clock-cells:
|
||||
- bus
|
||||
- ctl
|
||||
- bit
|
32
include/dt-bindings/clock/npcx_clock.h
Normal file
32
include/dt-bindings/clock/npcx_clock.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nuvoton Technology Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NPCX_CLOCK_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NPCX_CLOCK_H_
|
||||
|
||||
/* clock bus references */
|
||||
#define NPCX_CLOCK_BUS_FREERUN 0
|
||||
#define NPCX_CLOCK_BUS_LFCLK 1
|
||||
#define NPCX_CLOCK_BUS_OSC 2
|
||||
#define NPCX_CLOCK_BUS_FIU 3
|
||||
#define NPCX_CLOCK_BUS_CORE 4
|
||||
#define NPCX_CLOCK_BUS_APB1 5
|
||||
#define NPCX_CLOCK_BUS_APB2 6
|
||||
#define NPCX_CLOCK_BUS_APB3 7
|
||||
#define NPCX_CLOCK_BUS_APB4 8
|
||||
#define NPCX_CLOCK_BUS_AHB6 9
|
||||
|
||||
/* clock enable/disable references */
|
||||
#define NPCX_PWDWN_CTL1 0
|
||||
#define NPCX_PWDWN_CTL2 1
|
||||
#define NPCX_PWDWN_CTL3 2
|
||||
#define NPCX_PWDWN_CTL4 3
|
||||
#define NPCX_PWDWN_CTL5 4
|
||||
#define NPCX_PWDWN_CTL6 5
|
||||
#define NPCX_PWDWN_CTL7 6
|
||||
#define NPCX_PWDWN_CTL8 7
|
||||
#define NPCX_PWDWN_CTL_NONE 8
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_NPCX_CLOCK_H_ */
|
|
@ -7,6 +7,117 @@
|
|||
#ifndef _NUVOTON_NPCX_REG_DEF_H
|
||||
#define _NUVOTON_NPCX_REG_DEF_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!")
|
||||
|
||||
/*
|
||||
* Core Domain Clock Generator (CDCG) device registers
|
||||
*/
|
||||
struct cdcg_reg_t {
|
||||
/* High Frequency Clock Generator (HFCG) registers */
|
||||
/* 0x000: HFCG Control */
|
||||
volatile uint8_t HFCGCTRL;
|
||||
volatile uint8_t reserved1;
|
||||
/* 0x002: HFCG M Low Byte Value */
|
||||
volatile uint8_t HFCGML;
|
||||
volatile uint8_t reserved2;
|
||||
/* 0x004: HFCG M High Byte Value */
|
||||
volatile uint8_t HFCGMH;
|
||||
volatile uint8_t reserved3;
|
||||
/* 0x006: HFCG N Value */
|
||||
volatile uint8_t HFCGN;
|
||||
volatile uint8_t reserved4;
|
||||
/* 0x008: HFCG Prescaler */
|
||||
volatile uint8_t HFCGP;
|
||||
volatile uint8_t reserved5[7];
|
||||
/* 0x010: HFCG Bus Clock Dividers */
|
||||
volatile uint8_t HFCBCD;
|
||||
volatile uint8_t reserved6;
|
||||
/* 0x012: HFCG Bus Clock Dividers */
|
||||
volatile uint8_t HFCBCD1;
|
||||
volatile uint8_t reserved7;
|
||||
/* 0x014: HFCG Bus Clock Dividers */
|
||||
volatile uint8_t HFCBCD2;
|
||||
volatile uint8_t reserved8[235];
|
||||
|
||||
/* Low Frequency Clock Generator (LFCG) registers */
|
||||
/* 0x100: LFCG Control */
|
||||
volatile uint8_t LFCGCTL;
|
||||
volatile uint8_t reserved9;
|
||||
/* 0x102: High-Frequency Reference Divisor I */
|
||||
volatile uint16_t HFRDI;
|
||||
/* 0x104: High-Frequency Reference Divisor F */
|
||||
volatile uint16_t HFRDF;
|
||||
/* 0x106: FRCLK Clock Divisor */
|
||||
volatile uint16_t FRCDIV;
|
||||
/* 0x108: Divisor Correction Value 1 */
|
||||
volatile uint16_t DIVCOR1;
|
||||
/* 0x10A: Divisor Correction Value 2 */
|
||||
volatile uint16_t DIVCOR2;
|
||||
volatile uint8_t reserved10[8];
|
||||
/* 0x114: LFCG Control 2 */
|
||||
volatile uint8_t LFCGCTL2;
|
||||
volatile uint8_t reserved11;
|
||||
};
|
||||
|
||||
/* CDCG register fields */
|
||||
#define NPCX_HFCGCTRL_LOAD 0
|
||||
#define NPCX_HFCGCTRL_LOCK 2
|
||||
#define NPCX_HFCGCTRL_CLK_CHNG 7
|
||||
|
||||
/*
|
||||
* Power Management Controller (PMC) device registers
|
||||
*/
|
||||
struct pmc_reg_t {
|
||||
/* 0x000: Power Management Controller */
|
||||
volatile uint8_t PMCSR;
|
||||
volatile uint8_t reserved1[2];
|
||||
/* 0x003: Enable in Sleep Control */
|
||||
volatile uint8_t ENIDL_CTL;
|
||||
/* 0x004: Disable in Idle Control */
|
||||
volatile uint8_t DISIDL_CTL;
|
||||
/* 0x005: Disable in Idle Control 1 */
|
||||
volatile uint8_t DISIDL_CTL1;
|
||||
volatile uint8_t reserved2[2];
|
||||
/* 0x008 - 0D: Power-Down Control 1 - 6 */
|
||||
volatile uint8_t PWDWN_CTL1[6];
|
||||
volatile uint8_t reserved3[18];
|
||||
/* 0x020 - 21: Power-Down Control 1 - 2 */
|
||||
volatile uint8_t RAM_PD[2];
|
||||
volatile uint8_t reserved4[2];
|
||||
/* 0x024: Power-Down Control 7 */
|
||||
volatile uint8_t PWDWN_CTL7[1];
|
||||
};
|
||||
|
||||
/* PMC multi-registers */
|
||||
#define NPCX_PWDWN_CTL_OFFSET(n) (((n) < 6) ? (0x008 + n) : (0x024 + (n - 6)))
|
||||
#define NPCX_PWDWN_CTL(base, n) (*(volatile uint8_t *)(base + \
|
||||
NPCX_PWDWN_CTL_OFFSET(n)))
|
||||
|
||||
/* PMC register fields */
|
||||
#define NPCX_PMCSR_DI_INSTW 0
|
||||
#define NPCX_PMCSR_DHF 1
|
||||
#define NPCX_PMCSR_IDLE 2
|
||||
#define NPCX_PMCSR_NWBI 3
|
||||
#define NPCX_PMCSR_OHFC 6
|
||||
#define NPCX_PMCSR_OLFC 7
|
||||
#define NPCX_DISIDL_CTL_RAM_DID 5
|
||||
#define NPCX_ENIDL_CTL_ADC_LFSL 7
|
||||
#define NPCX_ENIDL_CTL_LP_WK_CTL 6
|
||||
#define NPCX_ENIDL_CTL_PECI_ENI 2
|
||||
#define NPCX_ENIDL_CTL_ADC_ACC_DIS 1
|
||||
|
||||
#endif /* _NUVOTON_NPCX_REG_DEF_H */
|
||||
|
||||
|
||||
|
|
127
soc/arm/nuvoton_npcx/common/soc_clock.h
Normal file
127
soc/arm/nuvoton_npcx/common/soc_clock.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nuvoton Technology Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _NUVOTON_NPCX_SOC_CLOCK_H_
|
||||
#define _NUVOTON_NPCX_SOC_CLOCK_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Common clock control device name for all NPCX series */
|
||||
#define NPCX_CLOCK_CONTROL_NAME "npcx-cc"
|
||||
|
||||
/**
|
||||
* @brief NPCX clock configuration structure
|
||||
*
|
||||
* Used to indicate the device's clock bus type and corresponding PWDWN_CTL
|
||||
* 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;
|
||||
};
|
||||
|
||||
/*
|
||||
* NPCX7 and later series clock tree macros:
|
||||
* (Please refer Figure 58. for more information.)
|
||||
*
|
||||
* Suggestion:
|
||||
* - OSC_CLK >= 80MHz, XF_RANGE should be 1, else 0.
|
||||
* - CORE_CLK > 66MHz, AHB6DIV should be 1, else 0.
|
||||
* - CORE_CLK > 50MHz, FIUDIV should be 1, else 0.
|
||||
*/
|
||||
|
||||
/* Target OSC_CLK freq */
|
||||
#define OSC_CLK CONFIG_CLOCK_NPCX_OSC_CYCLES_PER_SEC
|
||||
/* Core domain clock */
|
||||
#define CORE_CLK CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
/* Low Frequency clock */
|
||||
#define LFCLK 32768
|
||||
/* Core clock prescaler */
|
||||
#define FPRED_VAL ((OSC_CLK / CORE_CLK) - 1)
|
||||
|
||||
/* FMUL clock */
|
||||
#if (OSC_CLK >= 80000000)
|
||||
#define FMCLK (OSC_CLK / 2) /* FMUL clock = OSC_CLK/2 if OSC_CLK >= 80MHz */
|
||||
#else
|
||||
#define FMCLK OSC_CLK /* FMUL clock = OSC_CLK */
|
||||
#endif
|
||||
|
||||
/* APBs source clock */
|
||||
#define APBSRC_CLK OSC_CLK
|
||||
/* APB1 clock divider, default value (APB1 clock = OSC_CLK/6) */
|
||||
#define APB1DIV_VAL (CONFIG_CLOCK_NPCX_APB1_PRESCALER - 1)
|
||||
/* APB2 clock divider, default value (APB2 clock = OSC_CLK/6) */
|
||||
#define APB2DIV_VAL (CONFIG_CLOCK_NPCX_APB2_PRESCALER - 1)
|
||||
/* APB3 clock divider, default value (APB3 clock = OSC_CLK/6) */
|
||||
#define APB3DIV_VAL (CONFIG_CLOCK_NPCX_APB3_PRESCALER - 1)
|
||||
|
||||
/* AHB6 clock */
|
||||
#if (CORE_CLK > 66000000)
|
||||
#define AHB6DIV_VAL 1 /* AHB6_CLK = CORE_CLK/2 if CORE_CLK > 66MHz */
|
||||
#else
|
||||
#define AHB6DIV_VAL 0 /* AHB6_CLK = CORE_CLK */
|
||||
#endif
|
||||
/* FIU clock divider */
|
||||
#if (CORE_CLK > 50000000)
|
||||
#define FIUDIV_VAL 1 /* FIU_CLK = CORE_CLK/2 */
|
||||
#else
|
||||
#define FIUDIV_VAL 0 /* FIU_CLK = CORE_CLK */
|
||||
#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
|
||||
* OSC_CLK (Unit:Hz).
|
||||
*/
|
||||
#if (OSC_CLK > 80000000)
|
||||
#define HFCGN_VAL 0x82 /* Set XF_RANGE as 1 if OSC_CLK >= 80MHz */
|
||||
#else
|
||||
#define HFCGN_VAL 0x02
|
||||
#endif
|
||||
#if (OSC_CLK == 100000000)
|
||||
#define HFCGMH_VAL 0x0B
|
||||
#define HFCGML_VAL 0xEC
|
||||
#elif (OSC_CLK == 90000000)
|
||||
#define HFCGMH_VAL 0x0A
|
||||
#define HFCGML_VAL 0xBA
|
||||
#elif (OSC_CLK == 80000000)
|
||||
#define HFCGMH_VAL 0x09
|
||||
#define HFCGML_VAL 0x89
|
||||
#elif (OSC_CLK == 66000000)
|
||||
#define HFCGMH_VAL 0x0F
|
||||
#define HFCGML_VAL 0xBC
|
||||
#elif (OSC_CLK == 50000000)
|
||||
#define HFCGMH_VAL 0x0B
|
||||
#define HFCGML_VAL 0xEC
|
||||
#elif (OSC_CLK == 48000000)
|
||||
#define HFCGMH_VAL 0x0B
|
||||
#define HFCGML_VAL 0x72
|
||||
#elif (OSC_CLK == 40000000)
|
||||
#define HFCGMH_VAL 0x09
|
||||
#define HFCGML_VAL 0x89
|
||||
#elif (OSC_CLK == 33000000)
|
||||
#define HFCGMH_VAL 0x07
|
||||
#define HFCGML_VAL 0xDE
|
||||
#elif (OSC_CLK == 30000000)
|
||||
#define HFCGMH_VAL 0x07
|
||||
#define HFCGML_VAL 0x27
|
||||
#elif (OSC_CLK == 26000000)
|
||||
#define HFCGMH_VAL 0x06
|
||||
#define HFCGML_VAL 0x33
|
||||
#else
|
||||
#error "Unsupported OSC_CLK Frequency"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NUVOTON_NPCX_SOC_CLOCK_H_ */
|
21
soc/arm/nuvoton_npcx/common/soc_dt.h
Normal file
21
soc/arm/nuvoton_npcx/common/soc_dt.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Nuvoton Technology Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _NUVOTON_NPCX_SOC_DT_H_
|
||||
#define _NUVOTON_NPCX_SOC_DT_H_
|
||||
|
||||
/*
|
||||
* Construct a npcx_clk_cfg item from clocks prop which type is 'phandle-array'
|
||||
* to handle "clock-cells" in current driver device
|
||||
*/
|
||||
#define DT_NPCX_CLK_CFG_ITEM(inst) \
|
||||
{ \
|
||||
.bus = DT_PHA(DT_DRV_INST(inst), clocks, bus), \
|
||||
.ctrl = DT_PHA(DT_DRV_INST(inst), clocks, ctl), \
|
||||
.bit = DT_PHA(DT_DRV_INST(inst), clocks, bit), \
|
||||
}
|
||||
|
||||
#endif /* _NUVOTON_NPCX_SOC_DT_H_ */
|
|
@ -10,6 +10,12 @@ config SOC_SERIES
|
|||
|
||||
config NUM_IRQS
|
||||
default 64
|
||||
|
||||
config CLOCK_CONTROL_NPCX
|
||||
default y
|
||||
depends on CLOCK_CONTROL
|
||||
help
|
||||
Enable support for NPCX clock controller driver.
|
||||
|
||||
source "soc/arm/nuvoton_npcx/npcx7/Kconfig.defconfig.npcx7*"
|
||||
|
||||
|
|
|
@ -17,3 +17,17 @@ static int soc_init(struct device *dev)
|
|||
}
|
||||
|
||||
SYS_INIT(soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||
|
||||
/* CDCG register structure check */
|
||||
NPCX_REG_SIZE_CHECK(cdcg_reg_t, 0x116);
|
||||
NPCX_REG_OFFSET_CHECK(cdcg_reg_t, HFCBCD, 0x010);
|
||||
NPCX_REG_OFFSET_CHECK(cdcg_reg_t, HFCBCD2, 0x014);
|
||||
NPCX_REG_OFFSET_CHECK(cdcg_reg_t, LFCGCTL, 0x100);
|
||||
NPCX_REG_OFFSET_CHECK(cdcg_reg_t, LFCGCTL2, 0x114);
|
||||
|
||||
/* PMC register structure check */
|
||||
NPCX_REG_SIZE_CHECK(pmc_reg_t, 0x025);
|
||||
NPCX_REG_OFFSET_CHECK(pmc_reg_t, ENIDL_CTL, 0x003);
|
||||
NPCX_REG_OFFSET_CHECK(pmc_reg_t, PWDWN_CTL1, 0x008);
|
||||
NPCX_REG_OFFSET_CHECK(pmc_reg_t, PWDWN_CTL7, 0x024);
|
||||
|
||||
|
|
|
@ -16,5 +16,7 @@
|
|||
|
||||
#include <reg/reg_access.h>
|
||||
#include <reg/reg_def.h>
|
||||
#include <soc_dt.h>
|
||||
#include <soc_clock.h>
|
||||
|
||||
#endif /* _NUVOTON_NPCX_SOC_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue