1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
/*
*********************************************************************************************************
* 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;
}
|