ar5312.c revision 1.1 1 /* $NetBSD: ar5312.c,v 1.1 2006/08/28 07:21:15 gdamore Exp $ */
2
3 /*
4 * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
5 * Copyright (c) 2006 Garrett D'Amore.
6 * All rights reserved.
7 *
8 * Portions of this code were written by Garrett D'Amore for the
9 * Champaign-Urbana Community Wireless Network Project.
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgements:
22 * This product includes software developed by the Urbana-Champaign
23 * Independent Media Center.
24 * This product includes software developed by Garrett D'Amore.
25 * 4. Urbana-Champaign Independent Media Center's name and Garrett
26 * D'Amore's name may not be used to endorse or promote products
27 * derived from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
30 * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
31 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
34 * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * This file includes a bunch of implementation specific bits for
46 * AR5312, which differents these from other members of the AR5315
47 * family.
48 */
49 #include "opt_ddb.h"
50 #include "opt_kgdb.h"
51
52 #include "opt_memsize.h"
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/buf.h>
57
58 #include <mips/cache.h>
59 #include <mips/locore.h>
60 #include <mips/cpuregs.h>
61
62 #include <mips/atheros/include/ar5312reg.h>
63 #include <mips/atheros/include/ar531xvar.h>
64 #include <mips/atheros/include/arbusvar.h>
65 #include "com.h"
66
67 uint32_t
68 ar531x_memsize(void)
69 {
70 uint32_t memsize;
71 uint32_t memcfg, bank0, bank1;
72
73 /*
74 * Determine the memory size. Use the `memsize' PMON
75 * variable. If that's not available, panic.
76 *
77 * NB: we allow compile time override
78 */
79 #if defined(MEMSIZE)
80 memsize = MEMSIZE;
81 #else
82 memcfg = GETSDRAMREG(AR5312_SDRAMCTL_MEM_CFG1);
83 bank0 = (memcfg & AR5312_MEM_CFG1_BANK0_MASK) >>
84 AR5312_MEM_CFG1_BANK0_SHIFT;
85 bank1 = (memcfg & AR5312_MEM_CFG1_BANK1_MASK) >>
86 AR5312_MEM_CFG1_BANK1_SHIFT;
87
88 memsize = (bank0 ? (1 << (bank0 + 1)) : 0) +
89 (bank1 ? (1 << (bank1 + 1)) : 0);
90 memsize <<= 20;
91 #endif
92
93 return (memsize);
94 }
95
96 void
97 ar531x_wdog(uint32_t period)
98 {
99
100 if (period == 0) {
101 PUTSYSREG(AR5312_SYSREG_WDOG_CTL, AR5312_WDOG_CTL_IGNORE);
102 PUTSYSREG(AR5312_SYSREG_WDOG_TIMER, 0);
103 } else {
104 PUTSYSREG(AR5312_SYSREG_WDOG_TIMER, period);
105 PUTSYSREG(AR5312_SYSREG_WDOG_CTL, AR5312_WDOG_CTL_RESET);
106 }
107 }
108
109 const char *
110 ar531x_cpuname(void)
111 {
112 uint32_t revision;
113
114 revision = GETSYSREG(AR5312_SYSREG_REVISION);
115 switch (AR5312_REVISION_MAJOR(revision)) {
116 case AR5312_REVISION_MAJ_AR5311:
117 return ("Atheros AR5311");
118 case AR5312_REVISION_MAJ_AR5312:
119 return ("Atheros AR5312");
120 case AR5312_REVISION_MAJ_AR2313:
121 return ("Atheros AR2313");
122 case AR5312_REVISION_MAJ_AR5315:
123 return ("Atheros AR5315");
124 default:
125 return ("Atheros AR531X");
126 }
127 }
128
129 void
130 ar531x_consinit(void)
131 {
132 /*
133 * Everything related to console initialization is done
134 * in mach_init().
135 */
136 #if NCOM > 0
137 /* Setup polled serial for early console I/O */
138 /* XXX: pass in CONSPEED? */
139 com_arbus_cnattach(AR5312_UART0_BASE);
140 #else
141 panic("Not configured to use serial console!\n");
142 /* not going to see that message now, are we? */
143 #endif
144 }
145
146 void
147 ar531x_businit(void)
148
149 {
150 /*
151 * Clear previous AHB errors
152 */
153 GETSYSREG(AR5312_SYSREG_AHBPERR);
154 GETSYSREG(AR5312_SYSREG_AHBDMAE);
155 }
156
157 uint32_t
158 ar531x_cpu_freq(void)
159 {
160 static uint32_t cpufreq;
161 uint32_t wisoc = GETSYSREG(AR5312_SYSREG_REVISION);
162
163 uint32_t predivmask;
164 uint32_t predivshift;
165 uint32_t multmask;
166 uint32_t multshift;
167 uint32_t doublermask;
168 uint32_t divisor;
169 uint32_t multiplier;
170 uint32_t clockctl;
171
172 const int predivide_table[4] = { 1, 2, 4, 5 };
173
174 /* XXX: in theory we might be able to get clock from bootrom */
175
176 /*
177 * This logic looks at the clock control register and
178 * determines the actual CPU frequency. These parts lack any
179 * kind of real-time clock on them, but the cpu clocks should
180 * be very accurate -- WiFi requires usec resolution timers.
181 */
182
183 if (cpufreq) {
184 return cpufreq;
185 }
186
187 if (AR5312_REVISION_MAJOR(wisoc) == AR5312_REVISION_MAJ_AR2313) {
188 predivmask = AR2313_CLOCKCTL_PREDIVIDE_MASK;
189 predivshift = AR2313_CLOCKCTL_PREDIVIDE_SHIFT;
190 multmask = AR2313_CLOCKCTL_MULTIPLIER_MASK;
191 multshift = AR2313_CLOCKCTL_MULTIPLIER_SHIFT;
192 doublermask = AR2313_CLOCKCTL_DOUBLER_MASK;
193 } else {
194 predivmask = AR5312_CLOCKCTL_PREDIVIDE_MASK;
195 predivshift = AR5312_CLOCKCTL_PREDIVIDE_SHIFT;
196 multmask = AR5312_CLOCKCTL_MULTIPLIER_MASK;
197 multshift = AR5312_CLOCKCTL_MULTIPLIER_SHIFT;
198 doublermask = AR5312_CLOCKCTL_DOUBLER_MASK;
199 }
200
201 /*
202 * Note that the source clock involved here is a 40MHz.
203 */
204
205 clockctl = GETSYSREG(AR5312_SYSREG_CLOCKCTL);
206 divisor = predivide_table[(clockctl & predivmask) >> predivshift];
207 multiplier = (clockctl & multmask) >> multshift;
208
209 if (clockctl & doublermask)
210 multiplier <<= 1;
211
212 cpufreq = (40000000 / divisor) * multiplier;
213
214 return (cpufreq);
215 }
216
217 uint32_t
218 ar531x_sys_freq(void)
219 {
220 return (ar531x_cpu_freq() / 4);
221 }
222