/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2019. All rights reserved. * Description: clk spread configuration */ #include "soc_log.h" #include "drv_sys_ext.h" #include "drv_spread_ext.h" #include "osal_ext.h" #include "drv_spread.h" #undef LOG_MODULE_ID #define LOG_MODULE_ID SOC_ID_SPREAD /* ---------------- clk spread ---------------- */ #ifndef ext_ss_reg_write_bits #define ext_ss_reg_write_bits(pu32_vir_reg_addr, value, mask) \ do { \ td_u32 reg_value_ = 0; \ reg_value_ = osal_readl(pu32_vir_reg_addr); \ reg_value_ &= ~(mask); \ reg_value_ |= (value) & (mask); \ osal_writel(reg_value_, pu32_vir_reg_addr); \ } while (0) #endif #ifndef ext_ss_reg_read_bits #define ext_ss_reg_read_bits(pu32_vir_reg_addr, off_set, mask, pu32_value) \ do { \ td_u32 reg_value_ = 0; \ reg_value_ = osal_readl(pu32_vir_reg_addr); \ *(pu32_value) = (reg_value_ >> (off_set)) & (mask); \ } while (0) #endif #define spread_func_call(ret, func) do { \ (ret) = (func); \ if ((ret) != TD_SUCCESS) { \ soc_log_err("failed!\n"); \ } \ } while (0) #define SS_FREQ_MASK 0x0F #define SS_FREQ_OFFSET 0x09 #define SS_RATIO_MASK 0x1F #define SS_RATIO_OFFSET 0x04 #define SS_DOWN_MASK 0x01 #define SS_DOWN_OFFSET 0x03 #define SS_ENABLE_MASK 0x01 #define SS_ENABLE_OFFSET 0x02 #define SS_RST_MASK 0x01 #define SS_RST_OFFSET 0x01 #define SS_CLK_MASK 0x01 #define SS_CLK_OFFSET 0x00 #define CI_CLK_MASK 0x01 #define CI_CLK_OFFSET 0x04 #define CI_RST_MASK 0x01 #define CI_RST_OFFSET 0x01 /* [0-31] 0:0;1:0.1%;2:0.2%3:0.3%;4:0.4%;5:0.5%;6:0.6%;7:0.7%...31:3.1% */ #define SS_SPREAD_RATIO_MAX 31 static td_u32 g_ddr_spread_ratio_max = 10; /* [2-5] 93KHZ,62KHZ,46KHZ,37KHZ,31KHZ */ #define SS_SPREAD_FREQ_MIN 2 #define SS_SPREAD_FREQ_MAX 5 /* wait at least 8*41.66*REFDIV(ns) */ #define SS_WAIT_US 5 #define GMAC_WAIT_TIME 5 #define DDR_SS_CTRL_OFFSET 0x280 /* DDR spread ctrl register */ #define EMMC_SS_CTRL_OFFSET 0x1B8 /* EMMC spread ctrl register */ #define GMAC_SS_CTRL_OFFSET 0x134 /* GMAC spread ctrl register */ /* #define GMAC_CLK_CTRL_OFFSET 0x0CC */ /* GMAC spread ctrl register */ #define CI_CRG_CLK_OFFSET 0x188 /* CI spread ctrl register */ #define I2C_CRG_CLK_OFFSET 0x06C td_s32 ext_drv_ss_set_ddr_max_ratio(td_u32 max_ratio) { if (max_ratio < 0 && max_ratio > SS_SPREAD_RATIO_MAX) { soc_log_err("max_ratio is invalid!\n"); return TD_FAILURE; } g_ddr_spread_ratio_max = max_ratio; soc_log_dbg("g_ddr_spread_ratio_max is %u!\n", g_ddr_spread_ratio_max); return TD_SUCCESS; } /* open/close clk */ td_s32 ext_drv_ss_set_clk_en(td_u32 *pu32_vir_reg_addr, td_bool b_enable) { if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } if (b_enable) { ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_TRUE << SS_CLK_OFFSET), (SS_CLK_MASK << SS_CLK_OFFSET)); osal_msleep(GMAC_WAIT_TIME); ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_FALSE << SS_RST_OFFSET), (SS_RST_MASK << SS_RST_OFFSET)); } else { ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_FALSE << SS_CLK_OFFSET), (SS_CLK_MASK << SS_CLK_OFFSET)); osal_msleep(GMAC_WAIT_TIME); ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_TRUE << SS_RST_OFFSET), (SS_RST_MASK << SS_RST_OFFSET)); } osal_msleep(GMAC_WAIT_TIME); return TD_SUCCESS; } td_s32 ext_drv_ss_set_spread_en(td_u32 *pu32_vir_reg_addr, td_bool b_enable) { td_s32 ret; td_u32 enable; if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_TRUE << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_FALSE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } osal_msleep(GMAC_WAIT_TIME); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_TRUE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } osal_msleep(GMAC_WAIT_TIME); enable = (~(td_u32)b_enable); ext_ss_reg_write_bits(pu32_vir_reg_addr, (enable << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); return TD_SUCCESS; } td_s32 ext_drv_ss_get_spread_en(td_u32 *pu32_vir_reg_addr, td_bool *b_enable) { td_u32 reg_value; if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } if (b_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } reg_value = osal_readl(pu32_vir_reg_addr); *b_enable = (reg_value & (SS_ENABLE_MASK << SS_ENABLE_OFFSET)) ? TD_TRUE : TD_FALSE; return TD_SUCCESS; } /* 0. read the status of spread enable */ /* 1. stop spread */ /* 2. close ssmod clk */ /* 3. config spread ratio */ /* 4. open ssmod clk */ /* 5. wait at least 8*41.66*REFDIV(ns) before opening spread */ td_s32 ext_drv_ss_set_spread_down(td_u32 *pu32_vir_reg_addr, td_bool b_enable) { td_s32 ret; td_u32 reg_value; td_bool b_spread_disable; if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } reg_value = osal_readl(pu32_vir_reg_addr); b_spread_disable = (reg_value & (SS_ENABLE_MASK << SS_ENABLE_OFFSET)) ? TD_TRUE : TD_FALSE; ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_TRUE << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_FALSE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } ext_ss_reg_write_bits(pu32_vir_reg_addr, ((td_u32)(b_enable) << SS_DOWN_OFFSET), (SS_DOWN_MASK << SS_DOWN_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_TRUE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } osal_udelay(SS_WAIT_US); ext_ss_reg_write_bits(pu32_vir_reg_addr, ((td_u32)(b_spread_disable) << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); return TD_SUCCESS; } /* 0. read the status of spread enable */ /* 1. stop spread */ /* 2. close ssmod clk */ /* 3. config spread ratio */ /* 4. open ssmod clk */ /* 5. wait at least 8*41.66*REFDIV(ns) before opening spread */ td_s32 ext_drv_ss_set_spread_ratio(td_u32 *pu32_vir_reg_addr, td_u32 spread_ratio) { td_s32 ret; td_u32 reg_value; td_bool b_spread_disable; if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } reg_value = osal_readl(pu32_vir_reg_addr); b_spread_disable = (reg_value & (SS_ENABLE_MASK << SS_ENABLE_OFFSET)) ? TD_TRUE : TD_FALSE; ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_TRUE << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_FALSE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } ext_ss_reg_write_bits(pu32_vir_reg_addr, (spread_ratio << SS_RATIO_OFFSET), (SS_RATIO_MASK << SS_RATIO_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_TRUE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } osal_udelay(SS_WAIT_US); ext_ss_reg_write_bits(pu32_vir_reg_addr, ((td_u32)(b_spread_disable) << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); return TD_SUCCESS; } td_s32 ext_drv_ss_get_spread_ratio(td_u32 *pu32_vir_reg_addr, td_u32 *spread_ratio) { if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } if (spread_ratio == TD_NULL) { soc_log_err("spread_ratio is null point!\n"); return TD_FAILURE; } ext_ss_reg_read_bits(pu32_vir_reg_addr, SS_RATIO_OFFSET, SS_RATIO_MASK, spread_ratio); return TD_SUCCESS; } /* 0. read the status of spread enable */ /* 1. stop spread */ /* 2. close ssmod clk */ /* 3. config spread freq */ /* 4. open ssmod clk */ /* 5. wait at least 8*41.66*REFDIV(ns) before opening spread */ td_s32 ext_drv_ss_set_spread_freq(td_u32 *pu32_vir_reg_addr, td_u32 spread_freq) { td_s32 ret; td_u32 reg_value; td_bool b_spread_disable; if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } reg_value = osal_readl(pu32_vir_reg_addr); b_spread_disable = (reg_value & (SS_ENABLE_MASK << SS_ENABLE_OFFSET)) ? TD_TRUE : TD_FALSE; ext_ss_reg_write_bits(pu32_vir_reg_addr, (TD_TRUE << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_FALSE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } ext_ss_reg_write_bits(pu32_vir_reg_addr, (spread_freq << SS_FREQ_OFFSET), (SS_FREQ_MASK << SS_FREQ_OFFSET)); ret = ext_drv_ss_set_clk_en(pu32_vir_reg_addr, TD_TRUE); if (ret == TD_FAILURE) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } osal_udelay(SS_WAIT_US); ext_ss_reg_write_bits(pu32_vir_reg_addr, ((td_u32)(b_spread_disable) << SS_ENABLE_OFFSET), (SS_ENABLE_MASK << SS_ENABLE_OFFSET)); return TD_SUCCESS; } td_s32 ext_drv_ss_get_spread_freq(td_u32 *pu32_vir_reg_addr, td_u32 *spread_freq) { if (pu32_vir_reg_addr == TD_NULL) { soc_log_err("pu32_vir_reg_addr is null point!\n"); return TD_FAILURE; } if (spread_freq == TD_NULL) { soc_log_err("spread_freq is null point!\n"); return TD_FAILURE; } ext_ss_reg_read_bits(pu32_vir_reg_addr, SS_FREQ_OFFSET, SS_FREQ_MASK, spread_freq); return TD_SUCCESS; } /* ---------------- DDR spread func ---------------- */ td_s32 ext_drv_ss_set_ddr_spread_en(td_bool *pb_enable) { td_s32 ret; td_bool b_enable; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } b_enable = *pb_enable; ret = ext_drv_ss_set_spread_en((td_void *)reg_crg + DDR_SS_CTRL_OFFSET, b_enable); return ret; } td_s32 ext_drv_ss_get_ddr_spread_en(td_bool *pb_enable) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_en((td_void *)reg_crg + DDR_SS_CTRL_OFFSET, pb_enable); return ret; } td_s32 ext_drv_ss_set_ddr_spread_ratio(td_u32 *pu32_spread_ratio) { td_s32 ret; td_u32 spread_ratio; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_ratio == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } spread_ratio = *pu32_spread_ratio; if (spread_ratio > g_ddr_spread_ratio_max) { soc_log_err("ddr_spread_ratio[%d] is an invalid value\n", spread_ratio); return TD_FAILURE; } ret = ext_drv_ss_set_spread_ratio((td_void *)reg_crg + DDR_SS_CTRL_OFFSET, spread_ratio); return ret; } td_s32 ext_drv_ss_get_ddr_spread_ratio(td_u32 *pu32_spread_ratio) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_ratio == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_ratio((td_void *)reg_crg + DDR_SS_CTRL_OFFSET, pu32_spread_ratio); return ret; } td_s32 ext_drv_ss_set_ddr_spread_freq(td_u32 *pu32_spread_freq) { td_s32 ret; td_u32 spread_freq; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_freq == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } spread_freq = *pu32_spread_freq; if ((spread_freq > SS_SPREAD_FREQ_MAX) || (spread_freq < SS_SPREAD_FREQ_MIN)) { soc_log_err("ddr_spread_freq is an invalid value\n"); return TD_FAILURE; } ret = ext_drv_ss_set_spread_freq((td_void *)reg_crg + DDR_SS_CTRL_OFFSET, spread_freq); return ret; } td_s32 ext_drv_ss_get_ddr_spread_freq(td_u32 *pu32_spread_freq) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_freq == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_freq((td_void *)reg_crg + DDR_SS_CTRL_OFFSET, pu32_spread_freq); return ret; } /* ---------------- GMAC spread func ---------------- */ td_s32 ext_drv_ss_set_gmac_clk_en(td_bool *pb_enable) { td_s32 ret; td_bool b_enable; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } b_enable = *pb_enable; ret = ext_drv_ss_set_clk_en((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, b_enable); return ret; } td_s32 ext_drv_ss_set_gmac_spread_en(td_bool *pb_enable) { td_s32 ret; td_bool b_enable; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } b_enable = *pb_enable; ret = ext_drv_ss_set_spread_en((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, b_enable); return ret; } td_s32 ext_drv_ss_get_gmac_spread_en(td_bool *pb_enable) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_en((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, pb_enable); return ret; } td_s32 ext_drv_ss_set_gmac_spread_ratio(td_u32 *pu32_spread_ratio) { td_s32 ret; td_u32 spread_ratio; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_ratio == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } spread_ratio = *pu32_spread_ratio; if (spread_ratio > SS_SPREAD_RATIO_MAX) { soc_log_err("gmac_spread_ratio is an invalid value\n"); return TD_FAILURE; } ret = ext_drv_ss_set_spread_ratio((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, spread_ratio); return ret; } td_s32 ext_drv_ss_get_gmac_spread_ratio(td_u32 *pu32_spread_ratio) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_ratio == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_ratio((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, pu32_spread_ratio); return ret; } td_s32 ext_drv_ss_set_gmac_spread_freq(td_u32 *pu32_spread_freq) { td_s32 ret; td_u32 spread_freq; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_freq == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } spread_freq = *pu32_spread_freq; if ((spread_freq > SS_SPREAD_FREQ_MAX) || (spread_freq < SS_SPREAD_FREQ_MIN)) { soc_log_err("gmac_spread_freq is an invalid value\n"); return TD_FAILURE; } ret = ext_drv_ss_set_spread_freq((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, spread_freq); return ret; } td_s32 ext_drv_ss_get_gmac_spread_freq(td_u32 *pu32_spread_freq) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_freq == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_freq((td_void *)reg_crg + GMAC_SS_CTRL_OFFSET, pu32_spread_freq); return ret; } /* ---------------- EMMC spread func ---------------- */ td_s32 ext_drv_ss_set_emmc_clk_en(td_bool *pb_enable) { td_s32 ret; td_bool b_enable; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } b_enable = *pb_enable; ret = ext_drv_ss_set_clk_en((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, b_enable); return ret; } td_s32 ext_drv_ss_set_emmc_spread_en(td_bool *pb_enable) { td_s32 ret; td_bool b_enable; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } b_enable = *pb_enable; ret = ext_drv_ss_set_spread_en((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, b_enable); return ret; } td_s32 ext_drv_ss_get_emmc_spread_en(td_bool *pb_enable) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_en((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, pb_enable); return ret; } td_s32 ext_drv_ss_set_emmc_spread_ratio(td_u32 *pu32_spread_ratio) { td_s32 ret; td_u32 spread_ratio; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_ratio == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } spread_ratio = *pu32_spread_ratio; if (spread_ratio > SS_SPREAD_RATIO_MAX) { soc_log_err("emmc_spread_ratio is an invalid value\n"); return TD_FAILURE; } ret = ext_drv_ss_set_spread_ratio((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, spread_ratio); return ret; } td_s32 ext_drv_ss_get_emmc_spread_ratio(td_u32 *pu32_spread_ratio) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_ratio == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_ratio((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, pu32_spread_ratio); return ret; } td_s32 ext_drv_ss_set_emmc_spread_freq(td_u32 *pu32_spread_freq) { td_s32 ret; td_u32 spread_freq; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_freq == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } spread_freq = *pu32_spread_freq; if ((spread_freq > SS_SPREAD_FREQ_MAX) || (spread_freq < SS_SPREAD_FREQ_MIN)) { soc_log_err("emmc_spread_freq is an invalid value\n"); return TD_FAILURE; } ret = ext_drv_ss_set_spread_freq((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, spread_freq); return ret; } td_s32 ext_drv_ss_get_emmc_spread_freq(td_u32 *pu32_spread_freq) { td_s32 ret; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pu32_spread_freq == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } ret = ext_drv_ss_get_spread_freq((td_void *)reg_crg + EMMC_SS_CTRL_OFFSET, pu32_spread_freq); return ret; } /* ---------------- CI spread func ---------------- */ td_s32 ext_drv_ss_set_ci_clk_en(td_bool *pb_enable) { td_bool b_enable; td_void *reg_crg = (td_void *)ext_drv_sys_get_crg_reg_ptr(); if (pb_enable == TD_NULL) { soc_log_err("null pointer error!\n"); return TD_FAILURE; } b_enable = *pb_enable; if (b_enable) { ext_ss_reg_write_bits((td_void *)reg_crg + CI_CRG_CLK_OFFSET, (TD_TRUE << CI_CLK_OFFSET), (CI_CLK_MASK << CI_CLK_OFFSET)); ext_ss_reg_write_bits((td_void *)reg_crg + CI_CRG_CLK_OFFSET, (TD_FALSE << CI_RST_OFFSET), (CI_RST_MASK << CI_RST_OFFSET)); } else { ext_ss_reg_write_bits((td_void *)reg_crg + CI_CRG_CLK_OFFSET, (TD_TRUE << CI_RST_OFFSET), (CI_RST_MASK << CI_RST_OFFSET)); ext_ss_reg_write_bits((td_void *)reg_crg + CI_CRG_CLK_OFFSET, (TD_FALSE << CI_CLK_OFFSET), (CI_CLK_MASK << CI_CLK_OFFSET)); } return TD_SUCCESS; } td_s32 ext_drv_ss_get_proc_info(spread_proc_info *spread_proc_info) { td_s32 ret = TD_SUCCESS; spread_proc_info->ddr_spread_ratio_max = g_ddr_spread_ratio_max; spread_proc_info->gmac_spread_ratio_max = SS_SPREAD_RATIO_MAX; spread_proc_info->emmc_spread_ratio_max = SS_SPREAD_RATIO_MAX; spread_func_call(ret, ext_drv_ss_get_ddr_spread_en(&(spread_proc_info->ddr_spread_status))); spread_func_call(ret, ext_drv_ss_get_ddr_spread_ratio(&(spread_proc_info->ddr_spread_ratio))); spread_func_call(ret, ext_drv_ss_get_ddr_spread_freq(&(spread_proc_info->ddr_spread_div_freq))); spread_func_call(ret, ext_drv_ss_get_gmac_spread_en(&(spread_proc_info->gmac_spread_status))); spread_func_call(ret, ext_drv_ss_get_gmac_spread_ratio(&(spread_proc_info->gmac_spread_ratio))); spread_func_call(ret, ext_drv_ss_get_gmac_spread_freq(&(spread_proc_info->gmac_spread_div_freq))); spread_func_call(ret, ext_drv_ss_get_emmc_spread_en(&(spread_proc_info->emmc_spread_status))); spread_func_call(ret, ext_drv_ss_get_emmc_spread_ratio(&(spread_proc_info->emmc_spread_ratio))); spread_func_call(ret, ext_drv_ss_get_emmc_spread_freq(&(spread_proc_info->emmc_spread_div_freq))); return ret; } EXPORT_SYMBOL(ext_drv_ss_get_proc_info); EXPORT_SYMBOL(ext_drv_ss_set_ddr_spread_en); EXPORT_SYMBOL(ext_drv_ss_set_ddr_spread_ratio); EXPORT_SYMBOL(ext_drv_ss_set_ddr_spread_freq); EXPORT_SYMBOL(ext_drv_ss_set_gmac_clk_en); EXPORT_SYMBOL(ext_drv_ss_set_gmac_spread_en); EXPORT_SYMBOL(ext_drv_ss_set_gmac_spread_ratio); EXPORT_SYMBOL(ext_drv_ss_set_gmac_spread_freq); EXPORT_SYMBOL(ext_drv_ss_set_emmc_clk_en); EXPORT_SYMBOL(ext_drv_ss_set_emmc_spread_en); EXPORT_SYMBOL(ext_drv_ss_set_emmc_spread_ratio); EXPORT_SYMBOL(ext_drv_ss_set_emmc_spread_freq); EXPORT_SYMBOL(ext_drv_ss_set_ci_clk_en);