/** * @file sdrv_ckgen.h * @brief SemiDrive clock generator driver header file. * * @copyright Copyright (c) 2020 Semidrive Semiconductor. * All rights reserved. */ #ifndef SDRV_CLK_H_ #define SDRV_CLK_H_ #include #include #include #include #include #define CLK_NODE(node) (sdrv_ckgen_node_t *)&(node.clk_node) #define CLK_MHZ(x) ((x) * 1000 * 1000) #define CONFIG_CKGEN_PARENTS_NUM 5 /** * @brief CKGEN status error code. */ enum sdrv_ckgen_error { SDRV_CKGEN_POINTER_IS_NULL = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 1), SDRV_CKGEN_XTAL24M_NOT_READY = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 2), SDRV_CKGEN_FS24M_WAIT_ACTIVE_TIMEOUT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 3), SDRV_CKGEN_XTAL32K_NOT_READY = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 4), SDRV_CKGEN_FS32K_WAIT_ACTIVE_TIMEOUT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 5), SDRV_CKGEN_PLL_NOT_LOCK = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 6), SDRV_CKGEN_PLL_RATE_WRONG = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 7), SDRV_CKGEN_PLL_LVDS_DIV2_CHG_BUSY = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 8), SDRV_CKGEN_PLL_LVDS_DIV7_CHG_BUSY = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 9), SDRV_CKGEN_PLL_LVDS_CKGEN_CHG_BUSY = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 10), SDRV_CKGEN_PLL_NOT_DSM_MODE = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 11), SDRV_CKGEN_SLICE_TYPE_ERROR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 12), SDRV_CKGEN_SLICE_NO_SUITABLE_PARENT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 13), SDRV_CKGEN_SLICE_MAIN_STATUS_ERROR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 14), SDRV_CKGEN_SLICE_PRE_STATUS_ERROR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 15), SDRV_CKGEN_SLICE_D0_ACTIVE_ERROR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 16), SDRV_CKGEN_SLICE_POST_D0_ACTIVE_ERROR = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 17), SDRV_CKGEN_SLICE_DIV_CHG_BUSY = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 18), SDRV_CKGEN_BEYOND_MAX_DIVIDER = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 19), SDRV_CKGEN_FREQUENCY_INCORRECT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 20), SDRV_CKGEN_CONSTRUCT_CLKTREE_FAILED = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 21), SDRV_CKGEN_PARENT_NODE_NULL = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 22), SDRV_CKGEN_BEYOND_MAX_AXI_RATE = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 23), SDRV_CKGEN_CLOCK_SET_TIMEOUT = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_CLK, 24), }; /** * @brief Function Safe clock source. */ typedef enum sdrv_fs_src_type { FS_SRC_RC = 0, /**< RC oscillator */ FS_SRC_XTAL = 1 /**< XTAL oscillator */ } sdrv_fs_src_type_e; /** * @brief Clock node type. */ typedef enum sdrv_ckgen_type { CKGEN_IP_SLICE_TYPE = 0, /**< ip slice type */ CKGEN_SF_BUS_SLICE_TYPE = 1, /**< sf/sp bus slice type */ CKGEN_BUS_SLICE_TYPE = 2, /**< except sf/sp bus slice type */ CKGEN_CORE_SLICE_TYPE = 3, /**< core slice type */ CKGEN_PCG_TYPE = 4, /**< PCG type */ CKGEN_BCG_TYPE = 5, /**< BCG type */ CKGEN_CCG_TYPE = 6, /**< CCG type */ CKGEN_PLL_CG_TYPE = 7, /**< PLL CG type */ CKGEN_XTAL_CG_TYPE = 8, /**< XTAL CG type */ CKGEN_PLL_CTRL_TYPE = 9, /**< PLL CTRL type */ CKGEN_PLL_LVDS_TYPE = 10, /**< PLL LVDS type */ CKGEN_RC24M_TYPE = 11, /**< RC24M type */ CKGEN_FS24M_TYPE = 12, /**< FS24M type */ CKGEN_RC32K_TYPE = 13, /**< RC32K type */ CKGEN_FS32K_TYPE = 14 /**< FS32K type */ } sdrv_ckgen_type_e; /** * @brief Low power mode for clock config. */ typedef enum sdrv_ckgen_lp_mode { CKGEN_RUN_MODE = 0, /**< CKGEN RUN MODE */ CKGEN_HIB_MODE = 1, /**< CKGEN HIBERNATE MODE */ CKGEN_SLP_MODE = 2 /**< CKGEN SLEEP MODE */ } sdrv_ckgen_lp_mode_e; /** * @brief Config bus slice node output type. * For SF/SP BUS, clk_out_m for core, clk_out_n for AXI, clk_out_p for APB * For AP domain bus, clk_out_m not used, clk_out_n for AXI, clk_out_p for APB */ typedef enum sdrv_ckgen_bus_out_type { CKGEN_BUS_CLK_OUT = 0, /**< use clk_in4, no divide as output clock */ CKGEN_BUS_CLK_OUT_M = 1, /**< output clock divided by div_m_num */ CKGEN_BUS_CLK_OUT_N = 2, /**< output clock divided by div_n_num */ CKGEN_BUS_CLK_OUT_P = 3, /**< output clock divided by div_p_num */ CKGEN_BUS_CLK_OUT_Q = 4 /**< output clock divided by div_q_num */ } sdrv_ckgen_bus_out_type_e; /** * @brief Bus slice post divide ratio. */ typedef enum sdrv_ckgen_bus_post_div { CKGEN_BUS_DIV_4_2_1 = 0, /**< divm/divn/divp = 4/2/1 */ CKGEN_BUS_DIV_2_2_1 = 1 /**< divm/divn/divp = 2/2/1 */ } sdrv_ckgen_bus_post_div_e; /** * @brief PLL Spread amplitude. * */ typedef enum sdrv_ckgen_ssc_amplitude { CKGEN_SSC_0P0_PERCENT = 0, /**< SSC_DEP 0.0% */ CKGEN_SSC_0P1_PERCENT, /**< SSC_DEP 0.1% */ CKGEN_SSC_0P2_PERCENT, /**< SSC_DEP 0.2% */ CKGEN_SSC_0P3_PERCENT, /**< SSC_DEP 0.3% */ CKGEN_SSC_0P4_PERCENT, /**< SSC_DEP 0.4% */ CKGEN_SSC_0P5_PERCENT, /**< SSC_DEP 0.5% */ CKGEN_SSC_0P6_PERCENT, /**< SSC_DEP 0.6% */ CKGEN_SSC_0P7_PERCENT, /**< SSC_DEP 0.7% */ CKGEN_SSC_0P8_PERCENT, /**< SSC_DEP 0.8% */ CKGEN_SSC_0P9_PERCENT, /**< SSC_DEP 0.9% */ CKGEN_SSC_1P0_PERCENT, /**< SSC_DEP 1.0% */ CKGEN_SSC_1P1_PERCENT, /**< SSC_DEP 1.1% */ CKGEN_SSC_1P2_PERCENT, /**< SSC_DEP 1.2% */ CKGEN_SSC_1P3_PERCENT, /**< SSC_DEP 1.3% */ CKGEN_SSC_1P4_PERCENT, /**< SSC_DEP 1.4% */ CKGEN_SSC_1P5_PERCENT, /**< SSC_DEP 1.5% */ CKGEN_SSC_1P6_PERCENT, /**< SSC_DEP 1.6% */ CKGEN_SSC_1P7_PERCENT, /**< SSC_DEP 1.7% */ CKGEN_SSC_1P8_PERCENT, /**< SSC_DEP 1.8% */ CKGEN_SSC_1P9_PERCENT, /**< SSC_DEP 1.9% */ CKGEN_SSC_2P0_PERCENT, /**< SSC_DEP 2.0% */ CKGEN_SSC_2P1_PERCENT, /**< SSC_DEP 2.1% */ CKGEN_SSC_2P2_PERCENT, /**< SSC_DEP 2.2% */ CKGEN_SSC_2P3_PERCENT, /**< SSC_DEP 2.3% */ CKGEN_SSC_2P4_PERCENT, /**< SSC_DEP 2.4% */ CKGEN_SSC_2P5_PERCENT, /**< SSC_DEP 2.5% */ CKGEN_SSC_2P6_PERCENT, /**< SSC_DEP 2.6% */ CKGEN_SSC_2P7_PERCENT, /**< SSC_DEP 2.7% */ CKGEN_SSC_2P8_PERCENT, /**< SSC_DEP 2.8% */ CKGEN_SSC_2P9_PERCENT, /**< SSC_DEP 2.9% */ CKGEN_SSC_3P0_PERCENT, /**< SSC_DEP 3.0% */ CKGEN_SSC_3P1_PERCENT, /**< SSC_DEP 3.1% */ } sdrv_ckgen_ssc_amplitude_e; /** * @brief PLL Spread mode. * */ typedef enum sdrv_ckgen_ssc_mode { CKGEN_NO_SSC = 0, /**< PLL no spread */ CKGEN_DOWN_SPREADING, /**< PLL down spread */ CKGEN_CENTER_SPREADING, /**< PLL center spread */ } sdrv_ckgen_ssc_mode_e; /** * @brief PLL Spread Modulation frequency. * */ typedef enum sdrv_ckgen_ssc_freq { CKGEN_FREF_DIV_507 = 0, /**< For 16MHz ref. It's 31.5KHz */ CKGEN_FREF_DIV_761, /**< For 24MHz ref. It's 31.5KHz */ CKGEN_FREF_DIV_793, /**< For 25MHz ref. It's 31.5KHz */ CKGEN_FREF_DIV_857, /**< For 27MHz ref. It's 31.5KHz */ } sdrv_ckgen_ssc_freq_e; /** * @brief PLL spread spectrum config parameters. */ typedef struct sdrv_ckgen_pll_ssc_config { sdrv_ckgen_ssc_amplitude_e ampl; sdrv_ckgen_ssc_mode_e mode; sdrv_ckgen_ssc_freq_e freq; } sdrv_ckgen_pll_ssc_config_t; /** * @brief Abstract clock common node for driver operate. */ typedef struct sdrv_ckgen_node { uint32_t base; /**< CKGEN register base */ uint16_t type; /**< Clock node type */ uint16_t id; /**< Clock node index */ } sdrv_ckgen_node_t; /** * @brief Abstract clock slice node for driver operate. */ typedef struct sdrv_ckgen_slice_node { sdrv_ckgen_node_t clk_node; /**< Abstract clock common node */ uint8_t parents_num; /**< Slice node parent number */ const sdrv_ckgen_node_t * parents[CONFIG_CKGEN_PARENTS_NUM]; /**< Parent abstract clock common node sets */ } sdrv_ckgen_slice_node_t; /** * @brief Abstract xcg node for driver operate. */ typedef struct sdrv_ckgen_cg_node { sdrv_ckgen_node_t clk_node; /**< Abstract clock common node */ const sdrv_ckgen_node_t *parent; /**< Parent abstract clock common node */ } sdrv_ckgen_cg_node_t; /** * @brief Abstract pll node for driver operate. */ typedef struct sdrv_pll_node { sdrv_ckgen_node_t clk_node; /**< Abstract clock common node */ const sdrv_ckgen_node_t *parent; /**< Parent abstract clock common node */ } sdrv_pll_node_t; /** * @brief Clock rate config for IP/Core/PLL node. */ typedef struct sdrv_ckgen_rate_config_node { sdrv_ckgen_node_t *clk_node; /**< Abstract clock common node */ uint32_t rate; /**< Clock rate for node */ union { /**< For PLL node, pll spread spectrum parameters. IP/Core slice reserved. */ sdrv_ckgen_pll_ssc_config_t *pll; } node_cfg; } sdrv_ckgen_rate_config_node_t; /** * @brief Clock rate config lists for IP/Core/PLL node. */ typedef struct sdrv_ckgen_rate_config { uint32_t config_num; /**< Config node numbers */ sdrv_ckgen_rate_config_node_t config_nodes[]; /**< Clock node list */ } sdrv_ckgen_rate_config_t; /** * @brief Clock rate config for Bus node. */ typedef struct sdrv_ckgen_bus_config_node { sdrv_ckgen_node_t *clk_node; /**< Abstract clock common node */ uint32_t rate; /**< Clock rate for node */ sdrv_ckgen_bus_post_div_e post_div; /**< Post divide for bus slice */ } sdrv_ckgen_bus_config_node_t; /** * @brief Clock rate config lists for Bus node. */ typedef struct sdrv_ckgen_bus_config { uint32_t config_num; /**< Config node numbers */ sdrv_ckgen_bus_config_node_t config_nodes[]; /**< Clock node list */ } sdrv_ckgen_bus_config_t; /** * @brief Gate config for xcg node. */ typedef struct sdrv_ckgen_gating_config_node { sdrv_ckgen_node_t *clk_node; /**< Abstract clock common node */ sdrv_ckgen_lp_mode_e mode; /**< Mode for config */ bool gating; /**< Config gate or not */ } sdrv_ckgen_gating_config_node_t; /** * @brief Gate config list for XCG node. */ typedef struct sdrv_ckgen_gating_config { uint32_t config_num; /**< Config xcg node number */ sdrv_ckgen_gating_config_node_t config_nodes[]; /**< XCG node list */ } sdrv_ckgen_gating_config_t; /** * @brief IP clock enable/disable config node. */ typedef struct sdrv_ckgen_ip_clock_config_node { const sdrv_ckgen_node_t **ip_nodes; /**< IP XCG list */ sdrv_ckgen_lp_mode_e mode; /**< Mode for config */ bool enable; /**< Enable or disable */ } sdrv_ckgen_ip_clock_config_node_t; /** * @brief IP clock enable or disable config. */ typedef struct sdrv_ckgen_ip_clock_config { uint32_t config_num; /**< Config xcg node number */ sdrv_ckgen_ip_clock_config_node_t config_nodes[]; /**< IP node list */ } sdrv_ckgen_ip_clock_config_t; /** * @brief Initialize clock config for system setup. */ typedef struct sdrv_ckgen_config { sdrv_ckgen_bus_config_t const *pre_bus_config; /**< Before config pll, optional change Core/Bus to FS24M */ sdrv_ckgen_rate_config_t const *pll_config; /**< PLL rate config */ sdrv_ckgen_bus_config_t const *bus_config; /**< System bus rate config, this include SF/SP core rate */ sdrv_ckgen_rate_config_t const *core_config; /**< Core rate config, now only config SX rate */ sdrv_ckgen_rate_config_t const *ip_config; /**< IP rate config */ sdrv_ckgen_ip_clock_config_t const *enable_config; /**< IP clock enable or disable config */ sdrv_ckgen_gating_config_t const *gating_config; /**< Clock gate config for each xcg under Run/Sleep/Hibernate mode */ } sdrv_ckgen_config_t; #if CONFIG_CLK_DUMP /** * @brief Definition for clock tree node. */ typedef struct sdrv_clk { const char *name; const sdrv_ckgen_node_t *ckgen_ref; struct list_node node; struct list_node child; } sdrv_clk_t; /** * @brief System default total clock node list. */ typedef struct sdrv_clk_config { uint32_t config_num; sdrv_clk_t config_nodes[]; } sdrv_clk_config_t; /** * @brief Dump system clock tree. * * @param [in] clk_config system total clock node list. * @param [in] clk_node the root clock node begin to dump, if set NULL means dump all clock. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_clktree_dump(sdrv_clk_config_t *clk_config, sdrv_clk_t *clk_node); #endif /* CONFIG_CLK_DUMP */ /** * @brief CKGEN XCG List */ typedef struct sdrv_ckgen_xcg_set { uint32_t base; /**< Ckgen controller base */ sdrv_ckgen_type_e cg_type; /**< CG Type */ uint32_t num; /**< CG Total Number */ } sdrv_ckgen_xcg_set_t; #if CONFIG_RTC_SS_DYNAMIC_PCLK #include #include #if CONFIG_RTC_SS_DYNAMIC_PCLK_IRQ_DISABLE #define RTC_SS_ACCESS_START() \ irq_state_t _state = arch_irq_save(); \ sdrv_ckgen_clock_config(CLK_NODE(g_ckgen_gating_rtc_pclk), true); \ SDRV_RTC_REG_PARITY_ERR_ENABLE(); #define RTC_SS_ACCESS_END() \ SDRV_RTC_REG_PARITY_ERR_DISABLE(); \ sdrv_ckgen_clock_config(CLK_NODE(g_ckgen_gating_rtc_pclk), false); \ arch_irq_restore(_state); #else /* CONFIG_RTC_SS_DYNAMIC_PCLK_IRQ_DISABLE */ int sdrv_rtc_ss_pclk_enable(void); int sdrv_rtc_ss_pclk_disable(void); #define RTC_SS_ACCESS_START() sdrv_rtc_ss_pclk_enable(); #define RTC_SS_ACCESS_END() sdrv_rtc_ss_pclk_disable(); #endif /* CONFIG_RTC_SS_DYNAMIC_PCLK_IRQ_DISABLE */ #else #define RTC_SS_ACCESS_START() #define RTC_SS_ACCESS_END() #endif /* CONFIG_RTC_SS_DYNAMIC_PCLK */ /** * @brief Config XTAL24M oscillator. * * This function enable or disable xtal24m oscillator. * * @param [in] ckgen ckgen node type must be CKGEN_FS24M_TYPE. * @param [in] enable true represents enable oscillator, false represents disable oscillator. * @return true represents success, false represents fail. */ int sdrv_xtal24m_enable(sdrv_ckgen_node_t *ckgen, bool enable); /** * @brief Config XTAL24M oscillator. * * This function config 24M clock from external active crystal. * * @param [in] ckgen ckgen node type must be CKGEN_FS24M_TYPE. * @return true represents success, false represents fail. */ int sdrv_xtal24m_from_active_crystal(sdrv_ckgen_node_t *ckgen); /** * @brief Config FS24M clock source. * * This function select FS24M clock source, RC oscillator or XTAL oscillator. * * @param [in] ckgen ckgen node type must be CKGEN_FS24M_TYPE. * @param [in] src RC oscillator or XTAL oscillator * @return true represents success, false represents fail. */ int sdrv_fs24m_change_src(sdrv_ckgen_node_t *ckgen, sdrv_fs_src_type_e src); /** * @brief Get FS32K real output clock frequency. * * This function use FS24M to check FS32K clock frequency. So you must make sure * FS24M is accurate. If you want check RC32K frequency, first change FS32K source * to RC, then call this function. If you want check XTAL32K frequency, first change * FS32K source to XTAL, then call this function. * * @param [in] ckgen ckgen node type must be CKGEN_FS24M_TYPE. * @return Real FS32K output frequency. */ uint32_t sdrv_ckgen_get_fs32k_real_frequency(sdrv_ckgen_node_t *ckgen); /** * @brief Config XTAL32K oscillator. * * This function enable or disable xtal32k oscillator. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @param [in] enable true represents enable oscillator, false represents disable oscillator. * @return true represents success, false represents fail. */ int sdrv_xtal32k_enable(sdrv_ckgen_node_t *ckgen, bool enable); /** * @brief Config XTAL32K oscillator. * * This function enable or disable xtal32k oscillator without wait ready status. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @param [in] enable true represents enable oscillator, false represents disable oscillator. * @return true represents success, false represents fail. */ int sdrv_xtal32k_enable_nowait(sdrv_ckgen_node_t *ckgen, bool enable); /** * @brief Get xtal32k ready status. * * This function get xtal32k ready status. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @return true represents xtal32k ready, false represents xtal32 not ready. */ bool sdrv_xtal32k_get_ready_status(sdrv_ckgen_node_t *ckgen); /** * @brief Config XTAL32K oscillator. * * This function config 32k clock from external active crystal. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @return true represents success, false represents fail. */ int sdrv_xtal32k_from_active_crystal(sdrv_ckgen_node_t *ckgen); /** * @brief Config FS32K clock source. * * This function select FS32K clock source, RC oscillator or XTAL oscillator. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @param [in] src RC oscillator or XTAL oscillator * @return true represents success, false represents fail. */ int sdrv_fs32k_change_src(sdrv_ckgen_node_t *ckgen, sdrv_fs_src_type_e src); /** * @brief Config FS32K clock source without wait active status. * * This function select FS32K clock source, RC oscillator or XTAL oscillator. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @param [in] src RC oscillator or XTAL oscillator * @return true represents success, false represents fail. */ int sdrv_fs32k_change_src_nowait(sdrv_ckgen_node_t *ckgen, sdrv_fs_src_type_e src); /** * @brief Get FS32K clock source active status. * * This function get FS32K clock source, RC oscillator or XTAL oscillator, active status. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @param [in] src RC oscillator or XTAL oscillator * @return true represents clock source as FS32K */ bool sdrv_fs32k_get_src_active_status(sdrv_ckgen_node_t *ckgen, sdrv_fs_src_type_e src); /** * @brief Control low power voltage detector power on or down. * * @param [in] ckgen ckgen node type must be CKGEN_FS32K_TYPE. * @param [in] power_on True or False. * @return true represents success, false represents fail. */ int sdrv_fs32k_lpvd_power_ctrl(sdrv_ckgen_node_t *ckgen, bool power_on); /** * @brief Config PLL rate. * * This function config clock rate for specific PLL. * * @param [in] ckgen ckgen node type can be CKGEN_PLL_CTRL_TYPE or CKGEN_PLL_LVDS_TYPE. * @param [in] rate clock rate to be set. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_pll_set_rate(sdrv_ckgen_node_t *ckgen, uint32_t rate); /** * @brief Config PLL rate with delta-sigma modulator enable config. * * This function config clock rate for specific PLL, and when rate configed work as integer pll, * it's up to user whether enable fractional. * * @param [in] ckgen ckgen node type can be CKGEN_PLL_CTRL_TYPE or CKGEN_PLL_LVDS_TYPE. * @param [in] rate clock rate to be set. * @param [in] ssc_cfg pll spread spectrum config. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_pll_set_rate_with_dsm(sdrv_ckgen_node_t *ckgen, uint32_t rate, sdrv_ckgen_pll_ssc_config_t *ssc_cfg); /** * @brief Get PLL rate. * * This function get clock rate for specific PLL. * * @param [in] ckgen ckgen node type can be CKGEN_PLL_CTRL_TYPE or CKGEN_PLL_LVDS_TYPE. * @return pll clock rate. */ uint32_t sdrv_pll_get_rate(sdrv_ckgen_node_t *ckgen); /** * @brief Get PLL lock detector status. * * This function check whether pll is locked. * * @param [in] ckgen ckgen node type can be CKGEN_PLL_CTRL_TYPE. * @return true represets locked, false represents unlocked, negative is error code. */ status_t sdrv_pll_is_locked(sdrv_ckgen_node_t *ckgen); /** * @brief Config clock rate for Core/IP slice node. * * This function configures expected clock rate for specific ckgen node, it will * search all his parent nodes, and select a closest clock rate at last. * * @param [in] ckgen ckgen node type can be CKGEN_IP_SLICE_TYPE or CKGEN_CORE_SLICE_TYPE. * @param [in] rate expected clock rate. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_set_rate(sdrv_ckgen_node_t *ckgen, uint32_t rate); /** * @brief Get clock rate for Core/IP slice node. * * This function get clock rate for CORE or IP slice node. * * @param [in] ckgen ckgen node type can be CKGEN_IP_SLICE_TYPE or CKGEN_CORE_SLICE_TYPE. * @return CORE/IP clock rate. */ uint32_t sdrv_ckgen_get_rate(sdrv_ckgen_node_t *ckgen); /** * @brief Config clock rate for Bus slice node. * * This function configure expected clock rate for specific ckgen BUS slice node, * since bus slice can output clock direct, or clock divide by m/n/p/q, and their ratio only * has two option, one is 4:2:1, other is 2:2:1. Clk_out_m is for core clock rate, Clk_out_n * is for AXI bus clock rate, Clk_out_p is for APB bus clock rate. * * @param [in] ckgen ckgen node type can be CKGEN_SF_BUS_SLICE_TYPE or CKGEN_BUS_SLICE_TYPE. * @param [in] rate clock rate to be set for Clk_out_m. * @param [in] div m/n/p,q ratio select. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_bus_set_rate(sdrv_ckgen_node_t *ckgen, uint32_t rate, sdrv_ckgen_bus_post_div_e div); /** * @brief Get clock rate for Bus slice node. * * This function can get Bus slice clock rate, it can get clk_in4 clock directly without divide, or * Clk_out_m/Clk_out_n/Clk_out_p/Clk_out_q divided by m/n/p/q. * * @param [in] ckgen ckgen node type can be CKGEN_SF_BUS_SLICE_TYPE or CKGEN_BUS_SLICE_TYPE. * @param [in] clk_out Clk_out/Clk_out_m/Clk_out_n/Clk_out_p/Clk_out_q. * @return clock rate. */ uint32_t sdrv_ckgen_bus_get_rate(sdrv_ckgen_node_t *ckgen, sdrv_ckgen_bus_out_type_e clk_out); /** * @brief Set CG NODE whether participate in low power handshake. * * This function config CG Node lowpower mask bit. If set to mask, cg status is ignored under low power * handshake. Otherwize, cg status is considerd into low power handshake. * * @param [in] ckgen ckgen node type can be CG NODE. * @param [in] mask true or false. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_cg_mask(sdrv_ckgen_node_t *ckgen, bool mask); /** * @brief Config xcg status under run/sleep/hibernate mode. * * This function configure clock gating status in run/sleep/hibernate mode, * when system enter run/sleep/hibernate mode, hardware auto enable or disable * clock as configured. * * @param [in] ckgen ckgen node type can be CG NODE. * @param [in] lp_mode Run/Sleep/Hibernate. * @param [in] gating gating enable or disable. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_set_gate(sdrv_ckgen_node_t *ckgen, sdrv_ckgen_lp_mode_e lp_mode, bool gating); /** * @brief Config clock enable or disable in run mode. * * This function configure clock gating status in run mode. * * @param [in] ckgen ckgen node type can be CG NODE. * @param [in] enable clock enable or disable. * @return 0 represents success, otherwise failed. */ status_t sdrv_ckgen_clock_config(sdrv_ckgen_node_t *ckgen, bool enable); /** * @brief Config IP clock enable/disable in run/sleep/hibernate mode. * * This function config all xcg belongs to this IP in run/sleep/hibernate mode. * * @param [in] ckgen_ip CG Node list belongs to this IP. * @param [in] mode Run/Sleep/Hibernate. * @param [in] enable clock enable or disable. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_ip_clock_enable(const sdrv_ckgen_node_t *ckgen_ip[], sdrv_ckgen_lp_mode_e mode, bool enable); /** * @brief Config PLL power down under run/sleep/hibernate mode. * * This function config enable or disable PLL power under run/sleep/hibernate mode. * * @param [in] ckgen ckgen node type can be CKGEN_PLL_CG_TYPE. * @param [in] lp_mode Run/Sleep/Hibernate. * @param [in] power_down power down enable or disable. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_set_pll_power(sdrv_ckgen_node_t *ckgen, sdrv_ckgen_lp_mode_e lp_mode, bool power_down); /** * @brief Get ckgen xcg node gating status. * * This function check whether xcg node is gated. * * @param [in] ckgen ckgen node type can be CG NODE. * @return true represents clock is gated, false represents clock is active, negative is error code. */ status_t sdrv_ckgen_is_gated(sdrv_ckgen_node_t *ckgen); /** * @brief Get slice node gating status. * * This function check whether slice node is gated. * * @param [in] ckgen ckgen node type can be IP/Core/Bus slice. * @return true represents clock is gated, false represents clock is active, negative is error code. */ status_t sdrv_ckgen_slice_gated(sdrv_ckgen_node_t *ckgen); /** * @brief Config All xcg gate or active. * * This function config PCG/BCG/CCG all gate or active. * * @param [in] xcg xcg info. * @param [in] mode run mode. * @param [in] gate true or false. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_xcg_type_set(sdrv_ckgen_xcg_set_t *xcg, sdrv_ckgen_lp_mode_e mode, bool gate); /** * @brief System clock initialize. * * This function initialize all system clock as pre-defined. It will change core clock to * 24M, then config PLL, after PLL is locked, config BUS and CORE to expect rate. After that * config IP clock if defined, and enable or disable clock gate. * * @param [in] config pre-defined clock config list. * @return SDRV_STATUS_OK or error code. */ status_t sdrv_ckgen_init(sdrv_ckgen_config_t *config); #endif /* SDRV_CLK_H_ */