xref: /freebsd-11-stable/sys/mips/atheros/ar933x_chip.c (revision 4ab2e064d7950be84256d671a7ae93f87cc6aa36)
1 /*-
2  * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org>
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  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include "opt_ddb.h"
31 
32 #include <sys/param.h>
33 #include <sys/conf.h>
34 #include <sys/kernel.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/cons.h>
38 #include <sys/kdb.h>
39 #include <sys/reboot.h>
40 
41 #include <vm/vm.h>
42 #include <vm/vm_page.h>
43 
44 #include <net/ethernet.h>
45 
46 #include <machine/clock.h>
47 #include <machine/cpu.h>
48 #include <machine/cpuregs.h>
49 #include <machine/hwfunc.h>
50 #include <machine/md_var.h>
51 #include <machine/trap.h>
52 #include <machine/vmparam.h>
53 
54 #include <mips/atheros/ar71xxreg.h>
55 #include <mips/atheros/ar933xreg.h>
56 
57 #include <mips/atheros/ar71xx_cpudef.h>
58 #include <mips/atheros/ar71xx_setup.h>
59 
60 #include <mips/atheros/ar71xx_chip.h>
61 #include <mips/atheros/ar933x_chip.h>
62 
63 static void
ar933x_chip_detect_mem_size(void)64 ar933x_chip_detect_mem_size(void)
65 {
66 }
67 
68 static void
ar933x_chip_detect_sys_frequency(void)69 ar933x_chip_detect_sys_frequency(void)
70 {
71 	uint32_t clock_ctrl;
72 	uint32_t cpu_config;
73 	uint32_t freq;
74 	uint32_t t;
75 
76 	t = ATH_READ_REG(AR933X_RESET_REG_BOOTSTRAP);
77 	if (t & AR933X_BOOTSTRAP_REF_CLK_40)
78 		u_ar71xx_refclk = (40 * 1000 * 1000);
79 	else
80 		u_ar71xx_refclk = (25 * 1000 * 1000);
81 
82 	clock_ctrl = ATH_READ_REG(AR933X_PLL_CLOCK_CTRL_REG);
83 	if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
84 		u_ar71xx_cpu_freq = u_ar71xx_refclk;
85 		u_ar71xx_ahb_freq = u_ar71xx_refclk;
86 		u_ar71xx_ddr_freq = u_ar71xx_refclk;
87 	} else {
88 		cpu_config = ATH_READ_REG(AR933X_PLL_CPU_CONFIG_REG);
89 
90 		t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
91 		    AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
92 		freq = u_ar71xx_refclk / t;
93 
94 		t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
95 		    AR933X_PLL_CPU_CONFIG_NINT_MASK;
96 		freq *= t;
97 
98 		t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
99 		    AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
100 		if (t == 0)
101 			t = 1;
102 
103 		freq >>= t;
104 
105 		t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
106 		     AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
107 		u_ar71xx_cpu_freq = freq / t;
108 
109 		t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
110 		      AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
111 		u_ar71xx_ddr_freq = freq / t;
112 
113 		t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
114 		     AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
115 		u_ar71xx_ahb_freq = freq / t;
116 	}
117 
118 	/*
119 	 * On the AR933x, the UART frequency is the reference clock,
120 	 * not the AHB bus clock.
121 	 */
122 	u_ar71xx_uart_freq = u_ar71xx_refclk;
123 
124 	/*
125 	 * XXX TODO: check whether the mdio frequency is always the
126 	 * refclock frequency, or whether it's variable like on the
127 	 * AR934x.
128 	 */
129 	u_ar71xx_mdio_freq = u_ar71xx_refclk;
130 
131 	/*
132 	 * XXX check what the watchdog frequency should be?
133 	 */
134 	u_ar71xx_wdt_freq = u_ar71xx_ahb_freq;
135 }
136 
137 static void
ar933x_chip_device_stop(uint32_t mask)138 ar933x_chip_device_stop(uint32_t mask)
139 {
140 	uint32_t reg;
141 
142 	reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE);
143 	ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg | mask);
144 }
145 
146 static void
ar933x_chip_device_start(uint32_t mask)147 ar933x_chip_device_start(uint32_t mask)
148 {
149 	uint32_t reg;
150 
151 	reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE);
152 	ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg & ~mask);
153 }
154 
155 static int
ar933x_chip_device_stopped(uint32_t mask)156 ar933x_chip_device_stopped(uint32_t mask)
157 {
158 	uint32_t reg;
159 
160 	reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE);
161 	return ((reg & mask) == mask);
162 }
163 
164 static void
ar933x_chip_set_mii_speed(uint32_t unit,uint32_t speed)165 ar933x_chip_set_mii_speed(uint32_t unit, uint32_t speed)
166 {
167 
168 	/* XXX TODO */
169 	return;
170 }
171 
172 /*
173  * XXX TODO !!
174  */
175 static void
ar933x_chip_set_pll_ge(int unit,int speed,uint32_t pll)176 ar933x_chip_set_pll_ge(int unit, int speed, uint32_t pll)
177 {
178 
179 	switch (unit) {
180 	case 0:
181 		/* XXX TODO */
182 		break;
183 	case 1:
184 		/* XXX TODO */
185 		break;
186 	default:
187 		printf("%s: invalid PLL set for arge unit: %d\n",
188 		    __func__, unit);
189 		return;
190 	}
191 }
192 
193 static void
ar933x_chip_ddr_flush(ar71xx_flush_ddr_id_t id)194 ar933x_chip_ddr_flush(ar71xx_flush_ddr_id_t id)
195 {
196 
197 	switch (id) {
198 	case AR71XX_CPU_DDR_FLUSH_GE0:
199 		ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0);
200 		break;
201 	case AR71XX_CPU_DDR_FLUSH_GE1:
202 		ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1);
203 		break;
204 	case AR71XX_CPU_DDR_FLUSH_USB:
205 		ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_USB);
206 		break;
207 	case AR71XX_CPU_DDR_FLUSH_WMAC:
208 		ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC);
209 		break;
210 	default:
211 		printf("%s: invalid DDR flush id (%d)\n", __func__, id);
212 		break;
213 	}
214 }
215 
216 
217 static uint32_t
ar933x_chip_get_eth_pll(unsigned int mac,int speed)218 ar933x_chip_get_eth_pll(unsigned int mac, int speed)
219 {
220 	uint32_t pll;
221 
222 	switch (speed) {
223 	case 10:
224 		pll = AR933X_PLL_VAL_10;
225 		break;
226 	case 100:
227 		pll = AR933X_PLL_VAL_100;
228 		break;
229 	case 1000:
230 		pll = AR933X_PLL_VAL_1000;
231 		break;
232 	default:
233 		printf("%s%d: invalid speed %d\n", __func__, mac, speed);
234 		pll = 0;
235 	}
236 	return (pll);
237 }
238 
239 static void
ar933x_chip_init_usb_peripheral(void)240 ar933x_chip_init_usb_peripheral(void)
241 {
242 	ar71xx_device_stop(AR933X_RESET_USBSUS_OVERRIDE);
243 	DELAY(100);
244 
245 	ar71xx_device_start(AR933X_RESET_USB_HOST);
246 	DELAY(100);
247 
248 	ar71xx_device_start(AR933X_RESET_USB_PHY);
249 	DELAY(100);
250 }
251 
252 static void
ar933x_configure_gmac(uint32_t gmac_cfg)253 ar933x_configure_gmac(uint32_t gmac_cfg)
254 {
255 	uint32_t reg;
256 
257 	reg = ATH_READ_REG(AR933X_GMAC_REG_ETH_CFG);
258 
259 	/*
260 	 * The relevant bits here include:
261 	 *
262 	 * + AR933X_ETH_CFG_SW_PHY_SWAP
263 	 * + AR933X_ETH_CFG_SW_PHY_ADDR_SWAP
264 	 *
265 	 * There are other things; look at what openwrt exposes so
266 	 * it can be correctly exposed.
267 	 *
268 	 * TODO: what about ethernet switch support? How's that work?
269 	 */
270 	if (bootverbose)
271 		printf("%s: GMAC config was 0x%08x\n", __func__, reg);
272         reg &= ~(AR933X_ETH_CFG_SW_PHY_SWAP | AR933X_ETH_CFG_SW_PHY_ADDR_SWAP);
273 	reg |= gmac_cfg;
274 	if (bootverbose)
275 		printf("%s: GMAC setting is 0x%08x; register is now 0x%08x\n",
276 		    __func__,
277 		    gmac_cfg,
278 		    reg);
279 	ATH_WRITE_REG(AR933X_GMAC_REG_ETH_CFG, reg);
280 }
281 
282 static void
ar933x_chip_init_gmac(void)283 ar933x_chip_init_gmac(void)
284 {
285 	int val;
286 	uint32_t gmac_cfg = 0;
287 
288 	/*
289 	 * These two bits need a bit better explanation.
290 	 *
291 	 * The default configuration in the hardware is to map both
292 	 * ports to the internal switch.
293 	 *
294 	 * Here, GE0 == arge0, GE1 == arge1.
295 	 *
296 	 * The internal switch has:
297 	 * + 5 MAC ports, MAC0->MAC4.
298 	 * + 5 PHY ports, PHY0->PHY4,
299 	 * + MAC0 connects to GE1;
300 	 * + GE0 connects to PHY4;
301 	 * + The other mappings are MAC1->PHY0, MAC2->PHY1 .. MAC4->PHY3.
302 	 *
303 	 * The GE1 port is linked in via 1000MBit/full, supplying what is
304 	 * normally the 'WAN' switch ports.
305 	 *
306 	 * The switch is connected the MDIO bus on GE1.  It looks like
307 	 * a normal AR7240 on-board switch.
308 	 *
309 	 * The GE0 port is connected via MII to PHY4, and can operate in
310 	 * 10/100mbit, full/half duplex.  Ie, you can speak to PHY4 on
311 	 * the MDIO bus and everything will simply 'work'.
312 	 *
313 	 * So far so good.  This looks just like an AR7240 SoC.
314 	 *
315 	 * However, some configurations will just expose one or two
316 	 * physical ports.  In this case, some configuration bits can
317 	 * be set to tweak this.
318 	 *
319 	 * + CFG_SW_PHY_ADDR_SWAP swaps PHY port 0 with PHY port 4.
320 	 *   Ie, GE0's PHY shows up as PHY 0.  So if there's only
321 	 *   one physical port, there's no need to involve the
322 	 *   switch framework - it can just show up as a default,
323 	 *   normal single PHY.
324 	 *
325 	 * + CFG_SW_PHY_SWAP swaps the internal switch connection
326 	 *   between PHY0 and PHY4.  Ie, PHY4 connects to MAc1,
327 	 *   PHY0 connects to GE0.
328 	 */
329 	if ((resource_int_value("ar933x_gmac", 0, "override_phy", &val) == 0)
330 	    && (val == 0))
331 		return;
332 	if ((resource_int_value("ar933x_gmac", 0, "swap_phy", &val) == 0)
333 	    && (val == 1))
334 		gmac_cfg |= AR933X_ETH_CFG_SW_PHY_SWAP;
335 	if ((resource_int_value("ar933x_gmac", 0, "swap_phy_addr", &val) == 0)
336 	    && (val == 1))
337 		gmac_cfg |= AR933X_ETH_CFG_SW_PHY_ADDR_SWAP;
338 	ar933x_configure_gmac(gmac_cfg);
339 }
340 
341 struct ar71xx_cpu_def ar933x_chip_def = {
342 	&ar933x_chip_detect_mem_size,
343 	&ar933x_chip_detect_sys_frequency,
344 	&ar933x_chip_device_stop,
345 	&ar933x_chip_device_start,
346 	&ar933x_chip_device_stopped,
347 	&ar933x_chip_set_pll_ge,
348 	&ar933x_chip_set_mii_speed,
349 	&ar71xx_chip_set_mii_if,
350 	&ar933x_chip_get_eth_pll,
351 	&ar933x_chip_ddr_flush,
352 	&ar933x_chip_init_usb_peripheral,
353 	NULL,
354 	NULL,
355 	&ar933x_chip_init_gmac,
356 };
357