186 lines
5.2 KiB
C
186 lines
5.2 KiB
C
|
/*
|
||
|
*********************************************************************************************************
|
||
|
* AR100 SYSTEM
|
||
|
* AR100 Software System Develop Kits
|
||
|
* clock control unit module
|
||
|
*
|
||
|
* (c) Copyright 2012-2016, Sunny China
|
||
|
* All Rights Reserved
|
||
|
*
|
||
|
* File : power.c
|
||
|
* By : Sunny
|
||
|
* Version : v1.0
|
||
|
* Date : 2012-11-22
|
||
|
* Descript: module power manager.
|
||
|
* Update : date auther ver notes
|
||
|
* 2012-11-22 16:44:06 Sunny 1.0 Create this file.
|
||
|
*********************************************************************************************************
|
||
|
*/
|
||
|
|
||
|
#include "ccu_i.h"
|
||
|
#include "cpucfg_regs.h"
|
||
|
#include "hal_prcm.h"
|
||
|
#include "aw_io.h"
|
||
|
#include "aw_io.h"
|
||
|
#include "aw_common.h"
|
||
|
#include "errno.h"
|
||
|
#include "notifier.h"
|
||
|
#include "delay.h"
|
||
|
#include "platform.h"
|
||
|
|
||
|
static u32 hosc_lock;
|
||
|
static u32 pll_ldo_suspend;
|
||
|
/*
|
||
|
*********************************************************************************************************
|
||
|
* SET POWER OFF STATUS OF HWMODULE
|
||
|
*
|
||
|
* Description: set the power off gating status of a specific module.
|
||
|
*
|
||
|
* Arguments : module : the module ID which we want to set power off gating status.
|
||
|
* state : the power off status which we want to set, the detail please
|
||
|
* refer to the status of power-off gating.
|
||
|
*
|
||
|
* Returns : OK if set module power off gating status succeeded, others if failed.
|
||
|
*********************************************************************************************************
|
||
|
*/
|
||
|
s32 ccu_set_poweroff_gating_state(s32 module, s32 state)
|
||
|
{
|
||
|
volatile u32 value;
|
||
|
|
||
|
switch (module) {
|
||
|
case PWRCTL_C0CPU0:
|
||
|
{
|
||
|
value = readl(C0_CPUX_POWEROFF_GATING_REG);
|
||
|
value &= (~(0x1 << 0));
|
||
|
value |= (state & 0x1) << 0;
|
||
|
writel(value, C0_CPUX_POWEROFF_GATING_REG);
|
||
|
return OK;
|
||
|
}
|
||
|
case PWRCTL_C0CPU1:
|
||
|
{
|
||
|
value = readl(C0_CPUX_POWEROFF_GATING_REG);
|
||
|
value &= (~(0x1 << 1));
|
||
|
value |= (state & 0x1) << 1;
|
||
|
writel(value, C0_CPUX_POWEROFF_GATING_REG);
|
||
|
return OK;
|
||
|
}
|
||
|
case PWRCTL_C0CPUX:
|
||
|
{
|
||
|
value = readl(C0_CPUX_POWEROFF_GATING_REG);
|
||
|
value &= (~(0x1 << 4));
|
||
|
value |= (state & 0x1) << 4;
|
||
|
writel(value, C0_CPUX_POWEROFF_GATING_REG);
|
||
|
return OK;
|
||
|
}
|
||
|
case PWRCTL_VDD_CPUS:
|
||
|
{
|
||
|
ccu_reg_addr->sys_pwroff_gate.vdd_cpus_gate = state;
|
||
|
return OK;
|
||
|
}
|
||
|
case PWRCTL_VDD_AVCC_A:
|
||
|
{
|
||
|
ccu_reg_addr->ana_pwroff_gate.avcc_a_gate = state;
|
||
|
return OK;
|
||
|
}
|
||
|
default:
|
||
|
{
|
||
|
pr_warning(
|
||
|
"invaid power control module (%d) when set power-off gating\n",
|
||
|
module);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
}
|
||
|
/* un-reached */
|
||
|
}
|
||
|
|
||
|
struct notifier *hosc_notifier_list = NULL;
|
||
|
|
||
|
s32 ccu_24mhosc_reg_cb(__pNotifier_t pcb)
|
||
|
{
|
||
|
/* insert call-back to hosc_notifier_list. */
|
||
|
return notifier_insert(&hosc_notifier_list, pcb);
|
||
|
}
|
||
|
|
||
|
#define XO_CTRL_REG (SUNXI_R_RTC_PBASE+0x160)
|
||
|
#define DCXO_EN_SHFIT (1)
|
||
|
s32 ccu_24mhosc_disable(void)
|
||
|
{
|
||
|
u32 value = 0;
|
||
|
|
||
|
hosc_lock = 1;
|
||
|
|
||
|
/* notify 24mhosc will power-off */
|
||
|
pr_info("broadcast 24mhosc will power-off\n");
|
||
|
notifier_notify(&hosc_notifier_list, CCU_HOSC_WILL_OFF_NOTIFY, 0);
|
||
|
|
||
|
/* FIXME: in real board */
|
||
|
/* disable 24mhosc */
|
||
|
value = readl(XO_CTRL_REG);
|
||
|
value &= ~(0x1 << DCXO_EN_SHFIT);
|
||
|
writel(value, XO_CTRL_REG);
|
||
|
|
||
|
/* wait 20 cycles */
|
||
|
udelay(20);
|
||
|
|
||
|
/* save pll voltage */
|
||
|
pll_ldo_suspend = (readl(CCU_PLL_CTRL1) >> 16) & 0x7;
|
||
|
|
||
|
/* power-off pll ldo */
|
||
|
value = (readl(CCU_PLL_CTRL1) | (0xa7 << 24));
|
||
|
writel(value, CCU_PLL_CTRL1);
|
||
|
value = (readl(CCU_PLL_CTRL1) | (0xa7 << 24));
|
||
|
value &= (~(0x1 << 0));
|
||
|
writel(value, CCU_PLL_CTRL1);
|
||
|
|
||
|
return OK;
|
||
|
}
|
||
|
|
||
|
s32 ccu_24mhosc_enable(void)
|
||
|
{
|
||
|
u32 value = 0;
|
||
|
volatile int i = 0;
|
||
|
|
||
|
/* power-on pll ldo */
|
||
|
value = (readl(CCU_PLL_CTRL1) | (0xa7 << 24));
|
||
|
writel(value, CCU_PLL_CTRL1);
|
||
|
value = (readl(CCU_PLL_CTRL1) | (0xa7 << 24));
|
||
|
value |= (0x1 << 0);
|
||
|
writel(value, CCU_PLL_CTRL1);
|
||
|
|
||
|
/* wait 2ms for power-on ready */
|
||
|
for (i = 64; i; i--) ;
|
||
|
|
||
|
/* adjust pll voltage */
|
||
|
value = (readl(CCU_PLL_CTRL1) | (0xa7 << 24));
|
||
|
writel(value, CCU_PLL_CTRL1);
|
||
|
value = (readl(CCU_PLL_CTRL1) | (0xa7 << 24));
|
||
|
value &= (~(0x7 << 16));
|
||
|
value |= (pll_ldo_suspend << 16);
|
||
|
writel(value, CCU_PLL_CTRL1);
|
||
|
|
||
|
/* wait 2ms for voltage ready */
|
||
|
for (i = 64; i; i--) ;
|
||
|
|
||
|
/* FIXME: in real board */
|
||
|
/* enable 24mhosc */
|
||
|
value = readl(XO_CTRL_REG);
|
||
|
value |= (0x1 << DCXO_EN_SHFIT);
|
||
|
writel(value, XO_CTRL_REG);
|
||
|
|
||
|
/* wait 2ms for 24m hosc ready */
|
||
|
for (i = 64; i; i--) ;
|
||
|
|
||
|
/* notify 24mhosc power-on ready */
|
||
|
pr_info("broadcast 24mhosc power-on ready\n");
|
||
|
notifier_notify(&hosc_notifier_list, CCU_HOSC_ON_READY_NOTIFY, 0);
|
||
|
|
||
|
hosc_lock = 0;
|
||
|
|
||
|
return OK;
|
||
|
}
|
||
|
|
||
|
s32 is_hosc_lock(void)
|
||
|
{
|
||
|
return hosc_lock;
|
||
|
}
|