#include "pmoc_comm.h" #define duty_formula(val) ((unsigned int)((1099 - (val)) * 460) >> 10) #define SVB_PWM_CTRL0 0x12028300 #define SVB_PWM_CTRL1 0x04 #define SVB_VER_REG 0x12020168 #define HPM_ADDR 0x1202015c static xmedia_void *g_svb_pwm = XMEDIA_NULL; static xmedia_void *g_svb_ver_addr = XMEDIA_NULL; static xmedia_void *g_chip_hpm = XMEDIA_NULL; static xmedia_s32 g_core_volt = 0; static xmedia_s32 g_temp_volt = 0; bool is_svb_enabled(void) { xmedia_u32 svb_disable = (osal_readl(g_svb_ver_addr) >> 4) & 0x1; if (svb_disable) { return false; } else { return true; } } xmedia_u32 get_core_volt(xmedia_void) { return (g_core_volt + g_temp_volt); } xmedia_u32 get_chip_hpm(xmedia_void) { return ((osal_readl(g_chip_hpm) >> 16) & 0x1FF); } static xmedia_s32 get_volt_to_svb(xmedia_void) { return (osal_readl(g_chip_hpm) & 0xffff); } static xmedia_void set_core_pwm(xmedia_s32 volt) { xmedia_u32 duty; /* svb_pwm volt code */ duty = duty_formula(volt); duty = ((duty << 16) & 0xFFFF0000) | 0x0c70; osal_writel(duty, g_svb_pwm); osal_writel(osal_readl(g_svb_pwm + SVB_PWM_CTRL1) | 0x1, g_svb_pwm + SVB_PWM_CTRL1); osal_writel(osal_readl(g_svb_pwm) | 0x1, g_svb_pwm); } xmedia_void set_core_comp(xmedia_s32 volt) { g_temp_volt = volt; } xmedia_void svb_control_apply(xmedia_void) { xmedia_s32 volt; volt = g_core_volt + g_temp_volt; PM_TRACE(MODULE_DBG_DEBUG, "volt = %d s_volt = %d temp_volt = %d\n", volt, g_core_volt, g_temp_volt); if (is_svb_enabled()) { set_core_pwm(volt); PM_TRACE(MODULE_DBG_DEBUG, "svb pwm ctrl0 = 0x%x, ctrl1 = 0x%x\n", osal_readl(g_svb_pwm), osal_readl(g_svb_pwm + SVB_PWM_CTRL1)); } } xmedia_s32 drv_svb_init(xmedia_void) { g_svb_pwm = (void *)osal_ioremap(SVB_PWM_CTRL0, 0x8); if (g_svb_pwm == XMEDIA_NULL) { PM_TRACE(MODULE_DBG_ERR, "remap pwm reg fail\n"); goto err1; } g_svb_ver_addr = (void *)osal_ioremap(SVB_VER_REG, 0x4); if (g_svb_ver_addr == XMEDIA_NULL) { PM_TRACE(MODULE_DBG_ERR, "remap svb ver fail\n"); goto err2; } g_chip_hpm = (void *)osal_ioremap(HPM_ADDR, 0x4); if (g_chip_hpm == XMEDIA_NULL) { PM_TRACE(MODULE_DBG_ERR, "remap hpm reg fail\n"); goto err3; } g_core_volt = get_volt_to_svb(); return XMEDIA_SUCCESS; err3: osal_iounmap(g_svb_ver_addr); g_svb_ver_addr = XMEDIA_NULL; err2: osal_iounmap(g_svb_pwm); g_svb_pwm = XMEDIA_NULL; err1: return XMEDIA_FAILURE; } xmedia_void drv_svb_deinit(xmedia_void) { osal_iounmap(g_chip_hpm); g_chip_hpm = XMEDIA_NULL; osal_iounmap(g_svb_ver_addr); g_svb_ver_addr = XMEDIA_NULL; osal_iounmap(g_svb_pwm); g_svb_pwm = XMEDIA_NULL; }