• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <boot/boot.h>
30 #include <msm7k/gpt.h>
31 
rd_cycle_count(void)32 static inline unsigned rd_cycle_count(void)
33 {
34     unsigned cc;
35     asm volatile (
36         "mrc p15, 0, %0, c15, c12, 1\n" :
37         "=r" (cc)
38         );
39     return cc;
40 }
41 
rd_dtcm(void)42 static inline unsigned rd_dtcm(void)
43 {
44     unsigned cc;
45     asm volatile (
46         "mrc p15, 0, %0, c9, c1, 0\n" :
47         "=r" (cc)
48         );
49     return cc;
50 }
51 
rd_itcm(void)52 static inline unsigned rd_itcm(void)
53 {
54     unsigned cc;
55     asm volatile (
56         "mrc p15, 0, %0, c9, c1, 1\n" :
57         "=r" (cc)
58         );
59     return cc;
60 }
61 
perf_enable(void)62 static inline void perf_enable(void)
63 {
64     asm volatile (
65         "mcr p15, 0, %0, c15, c12, 0\n" : : "r" (7)
66         );
67 }
68 
perf_disable(void)69 static inline void perf_disable(void)
70 {
71     asm volatile (
72         "mcr p15, 0, %0, c15, c12, 0\n" : : "r" (0)
73         );
74 }
75 
cycles_per_second(void)76 unsigned cycles_per_second(void)
77 {
78     unsigned T0, T1;
79 
80     perf_enable();
81 
82     writel(0, GPT_CLEAR);
83     writel(0, GPT_ENABLE);
84     while(readl(GPT_COUNT_VAL) != 0) ;
85 
86     writel(GPT_ENABLE_EN, GPT_ENABLE);
87     T0 = rd_cycle_count();
88     while(readl(GPT_COUNT_VAL) < 32766) ;
89     T1 = rd_cycle_count();
90 
91     writel(0, GPT_ENABLE);
92     writel(0, GPT_CLEAR);
93 
94     perf_disable();
95 
96     return T1-T0;
97 }
98 
mdelay(unsigned msecs)99 void mdelay(unsigned msecs)
100 {
101     msecs *= 33;
102 
103     writel(0, GPT_CLEAR);
104     writel(0, GPT_ENABLE);
105     while(readl(GPT_COUNT_VAL) != 0) ;
106 
107     writel(GPT_ENABLE_EN, GPT_ENABLE);
108     while(readl(GPT_COUNT_VAL) < msecs) ;
109 
110     writel(0, GPT_ENABLE);
111     writel(0, GPT_CLEAR);
112 }
113 
udelay(unsigned usecs)114 void udelay(unsigned usecs)
115 {
116     usecs = (usecs * 33 + 1000 - 33) / 1000;
117 
118     writel(0, GPT_CLEAR);
119     writel(0, GPT_ENABLE);
120     while(readl(GPT_COUNT_VAL) != 0) ;
121 
122     writel(GPT_ENABLE_EN, GPT_ENABLE);
123     while(readl(GPT_COUNT_VAL) < usecs) ;
124 
125     writel(0, GPT_ENABLE);
126     writel(0, GPT_CLEAR);
127 }
128 
print_cpu_speed(void)129 void print_cpu_speed(void)
130 {
131     unsigned cps = cycles_per_second();
132     dprintf("1 second = %d cycles\n%d MHz\n", cps, cps / 1000000);
133 }
134 
135 #define A11S_CLK_CNTL 0xC0100100
136 #define A11S_CLK_SEL  0xC0100104
137 
138 #define C A11S_CLK_CNTL
139 #define S A11S_CLK_SEL
140 
141 #if FROM_APPSBOOT_MBN
142 static unsigned tbl_old[] = {
143     C, 0x640000,
144     S, 2,
145     C, 0x640010,
146     C, 0x64001F,
147     S, 3,
148     C, 0x64101F,
149     C, 0x64171F,
150     S, 2,
151     C, 0x64171F,
152     C, 0x641715,
153     S, 3,
154     S, 5,
155     C, 0x641715,
156     C, 0x641315,
157     S, 4,
158     S, 6,
159     C, 0x641315,
160     C, 0x641312,
161     S, 7,
162     C, 0x641312,
163     C, 0x641112,
164     S, 6,
165     0
166 };
167 #endif
168 
169 static unsigned tbl[] = {
170 #if EXPLORE
171     C, 0x640000, S, 2,
172     C, 0x640001, S, 3,
173     C, 0x640201, S, 2,
174     C, 0x640203, S, 3,
175     C, 0x640403, S, 2,
176     C, 0x640405, S, 3,
177     C, 0x640605, S, 2,
178     C, 0x640607, S, 3,
179     C, 0x640807, S, 2,
180     C, 0x640809, S, 3,
181     C, 0x640A09, S, 2,
182     C, 0x640A0B, S, 3,
183     C, 0x640C0B, S, 2,
184     C, 0x640C0D, S, 3,
185     C, 0x640E0D, S, 2,
186     C, 0x640E0F, S, 3,
187 #endif
188     C, 0x640000, S, 2,
189     C, 0x64001F, S, 3,
190     C, 0x64171F, S, 2,
191     C, 0x641715, S, 5,
192     C, 0x641315, S, 6,
193     C, 0x641312, S, 7,
194     C, 0x641112, S, 6,
195     0
196 };
197 #undef C
198 #undef S
199 
200 #if TESTCASE
201 unsigned cc_div[16] = {
202 	1, 2, 3, 4,  5, 8, 6, 16,
203 	1, 1, 1, 1,  1, 1, 1, 32  /* guess */
204 };
205 
206 unsigned cc_base[4] = {
207 	19200000,
208     245760000,
209     800000000,
210     0
211 };
212 
213 unsigned cs_div[4] = {
214 	1, 2, 3, 4
215 };
216 
info(unsigned c,unsigned s)217 void info(unsigned c, unsigned s)
218 {
219     unsigned src_sel, src_div;
220 
221     if(s & 1) {
222             /* src1 selected */
223         src_sel = (c >> 4) & 0x7;
224         src_div = c & 0xF;
225     } else {
226             /* src0 selected */
227         src_sel = (c >> 12) & 0x7;
228         src_div = (c >> 8) & 0xF;
229     }
230 
231     unsigned src = s & 1;
232     unsigned pdiv = cs_div[(s >> 1) & 3];
233     unsigned div = cc_div[src_div];
234     unsigned clk = cc_base[src_sel] / div;
235     unsigned pclk = clk / pdiv;
236 
237     unsigned cps = cycles_per_second();
238 
239     dprintf("CC=0x%x CS=0x%x SRC=%d PDIV=%d SEL=%d DIV=%d CPS=%d ACLK=%d\n",
240             c, s, src, pdiv, src_sel, div, cps, clk);
241 }
242 
243 
arm11_clock_test(void)244 void arm11_clock_test(void)
245 {
246     unsigned c, s;
247     unsigned *x = tbl;
248 
249     while(*x) {
250         unsigned *ptr = (unsigned*) *x++;
251         unsigned val = *x++;
252         *ptr = val;
253 
254         if(ptr == ((unsigned*) A11S_CLK_CNTL)) {
255             c = val;
256         } else {
257             s = val;
258             info(c, s);
259         }
260     }
261 }
262 #endif
263 
arm11_clock_init(void)264 void arm11_clock_init(void)
265 {
266     unsigned *x = tbl;
267     while(*x) {
268         unsigned *ptr = (unsigned*) *x++;
269         unsigned val = *x++;
270         *ptr = val;
271     }
272 }
273 
274 
275