1 /* 2 * Copyright (c) 2020 Nuvoton Technology Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef _NUVOTON_NPCX_SOC_CLOCK_H_ 8 #define _NUVOTON_NPCX_SOC_CLOCK_H_ 9 10 #include <stdbool.h> 11 #include <stdint.h> 12 13 #include <zephyr/devicetree.h> 14 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /* Common clock control device node for all NPCX series */ 20 #define NPCX_CLK_CTRL_NODE DT_NODELABEL(pcc) 21 22 /** 23 * @brief NPCX clock configuration structure 24 * 25 * Used to indicate the device's clock bus type and corresponding PWDWN_CTL 26 * register/bit to turn on/off its source clock. 27 */ 28 struct npcx_clk_cfg { 29 uint16_t bus:8; 30 uint16_t ctrl:5; 31 uint16_t bit:3; 32 }; 33 34 /* Clock settings from pcc node */ 35 /* Target OFMCLK freq */ 36 #define OFMCLK DT_PROP(DT_NODELABEL(pcc), clock_frequency) 37 /* Core clock prescaler */ 38 #define FPRED_VAL (DT_PROP(DT_NODELABEL(pcc), core_prescaler) - 1) 39 /* APB1 clock divider */ 40 #define APB1DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb1_prescaler) - 1) 41 /* APB2 clock divider */ 42 #define APB2DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb2_prescaler) - 1) 43 /* APB3 clock divider */ 44 #define APB3DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb3_prescaler) - 1) 45 /* APB4 clock divider if supported */ 46 #if DT_NODE_HAS_PROP(DT_NODELABEL(pcc), apb4_prescaler) 47 #if defined(CONFIG_SOC_SERIES_NPCX9) 48 #define APB4DIV_VAL (DT_PROP(DT_NODELABEL(pcc), apb4_prescaler) - 1) 49 #else 50 #error "APB4 clock divider is not supported but defined in pcc node!" 51 #endif 52 #endif 53 54 /* 55 * NPCX7 and later series clock tree macros: 56 * (Please refer Figure 58. for more information.) 57 * 58 * Suggestion: 59 * - OFMCLK > 50MHz, XF_RANGE should be 1, else 0. 60 * - CORE_CLK > 50MHz, AHB6DIV should be 1, else 0. 61 * - CORE_CLK > 50MHz, FIUDIV should be 1, else 0. 62 */ 63 64 /* Core domain clock */ 65 #define CORE_CLK (OFMCLK / DT_PROP(DT_NODELABEL(pcc), core_prescaler)) 66 /* Low Frequency clock */ 67 #define LFCLK 32768 68 69 /* FMUL clock */ 70 #if (OFMCLK > 50000000) 71 #define FMCLK (OFMCLK / 2) /* FMUL clock = OFMCLK/2 if OFMCLK > 50MHz */ 72 #else 73 #define FMCLK OFMCLK /* FMUL clock = OFMCLK */ 74 #endif 75 76 /* APBs source clock */ 77 #define APBSRC_CLK OFMCLK 78 79 /* AHB6 clock */ 80 #if (CORE_CLK > 50000000) 81 #define AHB6DIV_VAL 1 /* AHB6_CLK = CORE_CLK/2 if CORE_CLK > 50MHz */ 82 #else 83 #define AHB6DIV_VAL 0 /* AHB6_CLK = CORE_CLK */ 84 #endif 85 /* FIU clock divider */ 86 #if (CORE_CLK > 50000000) 87 #define FIUDIV_VAL 1 /* FIU_CLK = CORE_CLK/2 */ 88 #else 89 #define FIUDIV_VAL 0 /* FIU_CLK = CORE_CLK */ 90 #endif 91 92 /* Get APB clock freq */ 93 #define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1)) 94 95 /* 96 * Frequency multiplier M/N value definitions according to the requested 97 * OFMCLK (Unit:Hz). 98 */ 99 #if (OFMCLK > 50000000) 100 #define HFCGN_VAL 0x82 /* Set XF_RANGE as 1 if OFMCLK > 50MHz */ 101 #else 102 #define HFCGN_VAL 0x02 103 #endif 104 #if (OFMCLK == 100000000) 105 #define HFCGMH_VAL 0x0B 106 #define HFCGML_VAL 0xEC 107 #elif (OFMCLK == 96000000) 108 #define HFCGMH_VAL 0x0B 109 #define HFCGML_VAL 0x72 110 #elif (OFMCLK == 90000000) 111 #define HFCGMH_VAL 0x0A 112 #define HFCGML_VAL 0xBA 113 #elif (OFMCLK == 80000000) 114 #define HFCGMH_VAL 0x09 115 #define HFCGML_VAL 0x89 116 #elif (OFMCLK == 66000000) 117 #define HFCGMH_VAL 0x07 118 #define HFCGML_VAL 0xDE 119 #elif (OFMCLK == 50000000) 120 #define HFCGMH_VAL 0x0B 121 #define HFCGML_VAL 0xEC 122 #elif (OFMCLK == 48000000) 123 #define HFCGMH_VAL 0x0B 124 #define HFCGML_VAL 0x72 125 #elif (OFMCLK == 40000000) 126 #define HFCGMH_VAL 0x09 127 #define HFCGML_VAL 0x89 128 #elif (OFMCLK == 33000000) 129 #define HFCGMH_VAL 0x07 130 #define HFCGML_VAL 0xDE 131 #else 132 #error "Unsupported OFMCLK Frequency" 133 #endif 134 135 /** 136 * @brief Function to notify clock driver that backup the counter value of 137 * low-frequency timer before ec entered deep idle state. 138 */ 139 void npcx_clock_capture_low_freq_timer(void); 140 141 /** 142 * @brief Function to notify clock driver that compensate the counter value of 143 * system timer by low-frequency timer after ec left deep idle state. 144 * 145 */ 146 void npcx_clock_compensate_system_timer(void); 147 148 /** 149 * @brief Function to get time ticks in system sleep/deep sleep state. The unit 150 * is ticks. 151 * 152 */ 153 uint64_t npcx_clock_get_sleep_ticks(void); 154 155 /** 156 * @brief Function to configure system sleep settings. After ec received "wfi" 157 * instruction, ec will enter sleep/deep sleep state for better power 158 * consumption. 159 * 160 * @param is_deep A boolean indicating ec enters deep sleep or sleep state 161 * @param is_instant A boolean indicating 'Instant Wake-up' from deep idle is 162 * enabled 163 */ 164 void npcx_clock_control_turn_on_system_sleep(bool is_deep, bool is_instant); 165 166 /** 167 * @brief Function to turn off system sleep mode. 168 */ 169 void npcx_clock_control_turn_off_system_sleep(void); 170 171 #ifdef __cplusplus 172 } 173 #endif 174 175 #endif /* _NUVOTON_NPCX_SOC_CLOCK_H_ */ 176