120 lines
2.5 KiB
C
120 lines
2.5 KiB
C
#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;
|
|
|
|
}
|
|
|