-
Notifications
You must be signed in to change notification settings - Fork 10
/
pll.c
executable file
·211 lines (171 loc) · 5.78 KB
/
pll.c
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
* This file is for M8 Only . If you want to implement your pll initial function
* please copy this file into the $(uboot)/board/amlogic/$(board name)/firmware/ directory .
*/
#include <config.h>
#include <asm/arch/cpu.h>
#include <asm/arch/io.h>
#include <asm/arch/timing.h>
#include <asm/arch/romboot.h>
#include <asm/arch/uart.h>
unsigned long clk_util_clk_msr(unsigned long clk_mux)
{
unsigned long measured_val;
unsigned long uS_gate_time=64; //64us: 1024MHz, 32us:2048MHz
unsigned long dummy_rd;
//set resolution
writel((uS_gate_time-1),P_MSR_CLK_REG0);
//set mux and start measure
writel(readl(P_MSR_CLK_REG0)|(clk_mux<<20) |(1<<19)|(1<<16),
P_MSR_CLK_REG0);
//dummy read
{ dummy_rd = readl(P_MSR_CLK_REG0); }
//Wait for the measurement to be done
while( (readl(P_MSR_CLK_REG0) & (1 << 31)) ) {}
//Disable measuring
clrbits_le32(P_MSR_CLK_REG0, 1<<16 );
measured_val = readl(P_MSR_CLK_REG2)&0xFFFFF; //20bit length
//Return Mhz, 64us:>>6,32us:>>5
return (measured_val>>6);
}
static void wait_clock(unsigned clk,unsigned dest)
{
char * pszCLK[] = {
NULL,NULL,NULL,"A9_ring_osc",NULL,NULL,
"VID PLL","CLK81","cts_encp","cts_encl",NULL,"ETH RMII",NULL,
};
unsigned cur;
do{
cur=clk_util_clk_msr(clk);
serial_puts("\nSet [");
if(clk < (sizeof(pszCLK)/sizeof(pszCLK[0])) &&
pszCLK[clk])
serial_puts(pszCLK[clk]);
else
serial_puts("N/A");
serial_puts("] to ");
serial_put_dec(dest);
serial_puts("MHz now it is ");
//tolerance +/- 1
if((cur == dest-1) || (cur == dest+1))
serial_put_dec(dest);
else
serial_put_dec(cur);
serial_puts("MHz");
__udelay(100);
}while(cur<dest-1 || cur >dest+1);
serial_puts(" --> OK!\n");
}
SPL_STATIC_FUNC void pll_init(struct pll_clk_settings * plls)
{
Wr_cbus(AM_ANALOG_TOP_REG1, Rd_cbus(AM_ANALOG_TOP_REG1)|1);
//bandgap enable
//SYS,MPLL
Wr_cbus(HHI_MPLL_CNTL6, Rd_cbus(HHI_MPLL_CNTL6)|(1<<26));
//VID,HDMI
Wr_cbus(HHI_VID_PLL_CNTL5, Rd_cbus(HHI_VID_PLL_CNTL5)|(1<<16));
//DDR
writel(readl(0xc8000410)|(1<<12),0xc8000410);
//MUST
//switch a9 clock to oscillator in the first. This is sync mux.
Wr_cbus( HHI_A9_CLK_CNTL, Rd_cbus(HHI_A9_CLK_CNTL) & (~(1<<7)));
__udelay(10);
Wr_cbus( HHI_A9_CLK_CNTL, 0);
__udelay(10);
//???
Wr_cbus(HHI_MPEG_CLK_CNTL, Rd_cbus(HHI_MPEG_CLK_CNTL) & (~(1<<8)) );
__udelay(100);
serial_init(52|UART_CNTL_MASK_TX_EN|UART_CNTL_MASK_RX_EN); //clk81 switch to 24M before MPLL init
//PLL setup: bandgap enable -> 1ms delay -> PLL reset + PLL set ->
// PLL enable -> 1ms delay -> PLL release from reset
int n_pll_try_times = 0;
//SYS PLL init
do{
//BANDGAP reset for SYS_PLL,MPLL lock fail
Wr_reg_bits(HHI_MPLL_CNTL6,0,26,1);
__udelay(10);
Wr_reg_bits(HHI_MPLL_CNTL6,1,26,1);
__udelay(1000); //1ms for bandgap bootup
PLL_ENTER_RESET(HHI_SYS_PLL_CNTL);
Wr_cbus(HHI_SYS_PLL_CNTL2,CFG_SYS_PLL_CNTL_2);
Wr_cbus(HHI_SYS_PLL_CNTL3,CFG_SYS_PLL_CNTL_3);
Wr_cbus(HHI_SYS_PLL_CNTL4,CFG_SYS_PLL_CNTL_4);
Wr_cbus(HHI_SYS_PLL_CNTL5,CFG_SYS_PLL_CNTL_5);
PLL_SETUP(HHI_SYS_PLL_CNTL, plls->sys_pll_cntl);
PLL_RELEASE_RESET(HHI_SYS_PLL_CNTL);
PLL_LOCK_CHECK(n_pll_try_times,1);
}while((Rd_cbus(HHI_SYS_PLL_CNTL)&(1<<31))==0);
//A9 clock setting
Wr_cbus(HHI_A9_CLK_CNTL,(plls->sys_clk_cntl & (~(1<<7))));
__udelay(1);
//enable A9 clock
Wr_cbus(HHI_A9_CLK_CNTL,(plls->sys_clk_cntl | (1<<7)));
//MPLL init
//FIXED PLL/Multi-phase PLL, fixed to 2.55GHz
PLL_ENTER_RESET(HHI_MPLL_CNTL); //set reset bit to 1
Wr_cbus(HHI_DPLL_TOP_0, 0x100);
Wr_cbus(HHI_MPLL_CNTL2, CFG_MPLL_CNTL_2 );
Wr_cbus(HHI_MPLL_CNTL3, CFG_MPLL_CNTL_3 );
Wr_cbus(HHI_MPLL_CNTL4, CFG_MPLL_CNTL_4 );
Wr_cbus(HHI_MPLL_CNTL5, CFG_MPLL_CNTL_5 );
Wr_cbus(HHI_MPLL_CNTL6, CFG_MPLL_CNTL_6 );
Wr_cbus(HHI_MPLL_CNTL7, CFG_MPLL_CNTL_7 );
Wr_cbus(HHI_MPLL_CNTL8, CFG_MPLL_CNTL_8 );
Wr_cbus(HHI_MPLL_CNTL9, CFG_MPLL_CNTL_9 );
PLL_SETUP(HHI_MPLL_CNTL, plls->mpll_cntl); //2.55G, FIXED
PLL_RELEASE_RESET(HHI_MPLL_CNTL); //set reset bit to 0
//PLL_WAIT_FOR_LOCK(HHI_MPLL_CNTL); //need bandgap reset?
n_pll_try_times=0;
do{
PLL_LOCK_CHECK(n_pll_try_times,5);
if((Rd_cbus(HHI_MPLL_CNTL)&(1<<31))!=0)
break;
Wr_cbus(HHI_MPLL_CNTL,Rd_cbus(HHI_MPLL_CNTL) | (1<<29));
__udelay(1000);
PLL_RELEASE_RESET(HHI_MPLL_CNTL);
__udelay(1000);
}while((Rd_cbus(HHI_MPLL_CNTL)&(1<<31))==0);
//MPLL is fixed to 2.55GHz
//clk81=fclk_div4 /2=637.5/4=159.375M
Wr_cbus(HHI_MPEG_CLK_CNTL, plls->mpeg_clk_cntl );
//here need do UART init, print MPLL LOCK CHECK info
serial_init(__plls.uart);
n_pll_try_times=0;
//VID PLL init
do{
//BANDGAP reset for VID_PLL, VID2_PLL
Wr_reg_bits(HHI_VID_PLL_CNTL5,0,16,1);
__udelay(10);
Wr_reg_bits(HHI_VID_PLL_CNTL5,1,16,1);
__udelay(1000); //1ms for bandgap bootup
PLL_ENTER_RESET(HHI_VID_PLL_CNTL);
Wr_cbus(HHI_VID_PLL_CNTL2,CFG_VID_PLL_CNTL_2);
Wr_cbus(HHI_VID_PLL_CNTL3,CFG_VID_PLL_CNTL_3);
Wr_cbus(HHI_VID_PLL_CNTL4,CFG_VID_PLL_CNTL_4);
Wr_cbus(HHI_VID_PLL_CNTL5,CFG_VID_PLL_CNTL_5);
PLL_SETUP(HHI_VID_PLL_CNTL, plls->vid_pll_cntl);
PLL_RELEASE_RESET(HHI_VID_PLL_CNTL);
PLL_LOCK_CHECK(n_pll_try_times,2);
}while((Rd_cbus(HHI_VID_PLL_CNTL)&(1<<31))==0);
n_pll_try_times=0;
#ifdef CONFIG_VPU_PRESET
//GP PLL init
if(IS_MESON_M8M2_CPU){
do{
__udelay(10);
PLL_ENTER_RESET(HHI_GP_PLL_CNTL);
Wr_cbus(HHI_GP_PLL_CNTL2, CFG_GP_PLL_CNTL_2);
Wr_cbus(HHI_GP_PLL_CNTL3, CFG_GP_PLL_CNTL_3);
Wr_cbus(HHI_GP_PLL_CNTL4, CFG_GP_PLL_CNTL_4);
Wr_cbus(HHI_GP_PLL_CNTL5, CFG_GP_PLL_CNTL_5);
/*fixed 364MHz, OD=2, N=3, M=182. 24/N*M/2^OD=364*/
Wr_cbus(HHI_GP_PLL_CNTL, 0x400206B6);
PLL_RELEASE_RESET(HHI_VID_PLL_CNTL);
PLL_LOCK_CHECK(n_pll_try_times,6);
}while((Rd_cbus(HHI_GP_PLL_CNTL)&(1<<31)) == 0);
/*power down*/
PLL_DISABLE(HHI_GP_PLL_CNTL);
}
#endif
__udelay(100);
}