ar934x_chip.c revision 302408
1/*-
2 * Copyright (c) 2013 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: stable/11/sys/mips/atheros/ar934x_chip.c 298848 2016-04-30 14:41:18Z pfg $");
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/ar934xreg.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/ar934x_chip.h>
62
63static void
64ar934x_chip_detect_mem_size(void)
65{
66}
67
68static uint32_t
69ar934x_get_pll_freq(uint32_t ref, uint32_t ref_div, uint32_t nint,
70    uint32_t nfrac, uint32_t frac, uint32_t out_div)
71{
72	uint64_t t;
73	uint32_t ret;
74
75	t = u_ar71xx_refclk;
76	t *= nint;
77	t = t / ref_div;
78	ret = t;
79
80	t = u_ar71xx_refclk;
81	t *= nfrac;
82	t = t / (ref_div * frac);
83	ret += t;
84
85	ret /= (1 << out_div);
86	return (ret);
87}
88
89static void
90ar934x_chip_detect_sys_frequency(void)
91{
92	uint32_t pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
93	uint32_t cpu_pll, ddr_pll;
94	uint32_t bootstrap;
95	uint32_t reg;
96
97	bootstrap = ATH_READ_REG(AR934X_RESET_REG_BOOTSTRAP);
98	if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
99		u_ar71xx_refclk = 40 * 1000 * 1000;
100	else
101		u_ar71xx_refclk = 25 * 1000 * 1000;
102
103	pll = ATH_READ_REG(AR934X_SRIF_CPU_DPLL2_REG);
104	if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
105		out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
106		    AR934X_SRIF_DPLL2_OUTDIV_MASK;
107		pll = ATH_READ_REG(AR934X_SRIF_CPU_DPLL1_REG);
108		nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
109		    AR934X_SRIF_DPLL1_NINT_MASK;
110		nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
111		ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
112		    AR934X_SRIF_DPLL1_REFDIV_MASK;
113		frac = 1 << 18;
114	} else {
115		pll = ATH_READ_REG(AR934X_PLL_CPU_CONFIG_REG);
116		out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
117			AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
118		ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
119			  AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
120		nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
121		       AR934X_PLL_CPU_CONFIG_NINT_MASK;
122		nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
123			AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
124		frac = 1 << 6;
125	}
126
127	cpu_pll = ar934x_get_pll_freq(u_ar71xx_refclk, ref_div, nint,
128	    nfrac, frac, out_div);
129
130	pll = ATH_READ_REG(AR934X_SRIF_DDR_DPLL2_REG);
131	if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
132		out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
133		    AR934X_SRIF_DPLL2_OUTDIV_MASK;
134		pll = ATH_READ_REG(AR934X_SRIF_DDR_DPLL1_REG);
135		nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
136		    AR934X_SRIF_DPLL1_NINT_MASK;
137		nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
138		ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
139		    AR934X_SRIF_DPLL1_REFDIV_MASK;
140		frac = 1 << 18;
141	} else {
142		pll = ATH_READ_REG(AR934X_PLL_DDR_CONFIG_REG);
143		out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
144		    AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
145		ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
146		    AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
147		nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
148		    AR934X_PLL_DDR_CONFIG_NINT_MASK;
149		nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
150		    AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
151		frac = 1 << 10;
152	}
153
154	ddr_pll = ar934x_get_pll_freq(u_ar71xx_refclk, ref_div, nint,
155	    nfrac, frac, out_div);
156
157	clk_ctrl = ATH_READ_REG(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
158
159	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
160	    AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
161
162	if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
163	    u_ar71xx_cpu_freq = u_ar71xx_refclk;
164	else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
165		u_ar71xx_cpu_freq = cpu_pll / (postdiv + 1);
166	else
167		u_ar71xx_cpu_freq = ddr_pll / (postdiv + 1);
168
169	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
170	    AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
171
172	if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
173		u_ar71xx_ddr_freq = u_ar71xx_refclk;
174	else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
175		u_ar71xx_ddr_freq = ddr_pll / (postdiv + 1);
176	else
177		u_ar71xx_ddr_freq = cpu_pll / (postdiv + 1);
178
179	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
180		  AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
181
182	if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
183		u_ar71xx_ahb_freq = u_ar71xx_refclk;
184	else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL)
185		u_ar71xx_ahb_freq = ddr_pll / (postdiv + 1);
186	else
187		u_ar71xx_ahb_freq = cpu_pll / (postdiv + 1);
188
189	u_ar71xx_wdt_freq = u_ar71xx_refclk;
190	u_ar71xx_uart_freq = u_ar71xx_refclk;
191
192	/*
193	 * Next, fetch reference clock speed for MDIO bus.
194	 */
195	reg = ATH_READ_REG(AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
196	if (reg & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) {
197		printf("%s: mdio=100MHz\n", __func__);
198		u_ar71xx_mdio_freq = (100 * 1000 * 1000);
199	} else {
200		printf("%s: mdio=%d Hz\n", __func__, u_ar71xx_refclk);
201		u_ar71xx_mdio_freq = u_ar71xx_refclk;
202	}
203}
204
205static void
206ar934x_chip_device_stop(uint32_t mask)
207{
208	uint32_t reg;
209
210	reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE);
211	ATH_WRITE_REG(AR934X_RESET_REG_RESET_MODULE, reg | mask);
212}
213
214static void
215ar934x_chip_device_start(uint32_t mask)
216{
217	uint32_t reg;
218
219	reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE);
220	ATH_WRITE_REG(AR934X_RESET_REG_RESET_MODULE, reg & ~mask);
221}
222
223static int
224ar934x_chip_device_stopped(uint32_t mask)
225{
226	uint32_t reg;
227
228	reg = ATH_READ_REG(AR934X_RESET_REG_RESET_MODULE);
229	return ((reg & mask) == mask);
230}
231
232static void
233ar934x_chip_set_mii_speed(uint32_t unit, uint32_t speed)
234{
235
236	/* XXX TODO */
237	return;
238}
239
240/*
241 * XXX TODO !!
242 */
243static void
244ar934x_chip_set_pll_ge(int unit, int speed, uint32_t pll)
245{
246
247	switch (unit) {
248	case 0:
249		ATH_WRITE_REG(AR934X_PLL_ETH_XMII_CONTROL_REG, pll);
250		break;
251	case 1:
252		/* XXX nothing */
253		break;
254	default:
255		printf("%s: invalid PLL set for arge unit: %d\n",
256		    __func__, unit);
257		return;
258	}
259}
260
261static void
262ar934x_chip_ddr_flush(ar71xx_flush_ddr_id_t id)
263{
264
265	switch (id) {
266	case AR71XX_CPU_DDR_FLUSH_GE0:
267		ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_GE0);
268		break;
269	case AR71XX_CPU_DDR_FLUSH_GE1:
270		ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_GE1);
271		break;
272	case AR71XX_CPU_DDR_FLUSH_USB:
273		ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_USB);
274		break;
275	case AR71XX_CPU_DDR_FLUSH_PCIE:
276		ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_PCIE);
277		break;
278	case AR71XX_CPU_DDR_FLUSH_WMAC:
279		ar71xx_ddr_flush(AR934X_DDR_REG_FLUSH_WMAC);
280		break;
281	default:
282		printf("%s: invalid DDR flush id (%d)\n", __func__, id);
283		break;
284	}
285}
286
287
288static uint32_t
289ar934x_chip_get_eth_pll(unsigned int mac, int speed)
290{
291	uint32_t pll;
292
293	switch (speed) {
294	case 10:
295		pll = AR934X_PLL_VAL_10;
296		break;
297	case 100:
298		pll = AR934X_PLL_VAL_100;
299		break;
300	case 1000:
301		pll = AR934X_PLL_VAL_1000;
302		break;
303	default:
304		printf("%s%d: invalid speed %d\n", __func__, mac, speed);
305		pll = 0;
306	}
307	return (pll);
308}
309
310static void
311ar934x_chip_reset_ethernet_switch(void)
312{
313
314	ar71xx_device_stop(AR934X_RESET_ETH_SWITCH);
315	DELAY(100);
316	ar71xx_device_start(AR934X_RESET_ETH_SWITCH);
317	DELAY(100);
318}
319
320static void
321ar934x_configure_gmac(uint32_t gmac_cfg)
322{
323	uint32_t reg;
324
325	reg = ATH_READ_REG(AR934X_GMAC_REG_ETH_CFG);
326	printf("%s: ETH_CFG=0x%08x\n", __func__, reg);
327
328	reg &= ~(AR934X_ETH_CFG_RGMII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0 |
329	    AR934X_ETH_CFG_MII_GMAC0 | AR934X_ETH_CFG_SW_ONLY_MODE |
330	    AR934X_ETH_CFG_SW_PHY_SWAP);
331
332	reg |= gmac_cfg;
333
334	ATH_WRITE_REG(AR934X_GMAC_REG_ETH_CFG, reg);
335}
336
337static void
338ar934x_chip_init_usb_peripheral(void)
339{
340	uint32_t reg;
341
342	reg = ATH_READ_REG(AR934X_RESET_REG_BOOTSTRAP);
343	if (reg & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
344		return;
345
346	ar71xx_device_stop(AR934X_RESET_USBSUS_OVERRIDE);
347	DELAY(100);
348
349	ar71xx_device_start(AR934X_RESET_USB_PHY);
350	DELAY(100);
351
352	ar71xx_device_start(AR934X_RESET_USB_PHY_ANALOG);
353	DELAY(100);
354
355	ar71xx_device_start(AR934X_RESET_USB_HOST);
356	DELAY(100);
357}
358
359static void
360ar934x_chip_set_mii_if(uint32_t unit, uint32_t mii_mode)
361{
362
363	/*
364	 * XXX !
365	 *
366	 * Nothing to see here; although gmac0 can have its
367	 * MII configuration changed, the register values
368	 * are slightly different.
369	 */
370}
371
372/*
373 * XXX TODO: fetch default MII divider configuration
374 */
375
376static void
377ar934x_chip_reset_wmac(void)
378{
379
380	/* XXX TODO */
381}
382
383static void
384ar934x_chip_init_gmac(void)
385{
386	long gmac_cfg;
387
388	if (resource_long_value("ar934x_gmac", 0, "gmac_cfg",
389	    &gmac_cfg) == 0) {
390		printf("%s: gmac_cfg=0x%08lx\n",
391		    __func__,
392		    (long) gmac_cfg);
393		ar934x_configure_gmac((uint32_t) gmac_cfg);
394	}
395}
396
397/*
398 * Reset the NAND Flash Controller.
399 *
400 * + active=1 means "make it active".
401 * + active=0 means "make it inactive".
402 */
403static void
404ar934x_chip_reset_nfc(int active)
405{
406
407	if (active) {
408		ar71xx_device_start(AR934X_RESET_NANDF);
409		DELAY(100);
410
411		ar71xx_device_start(AR934X_RESET_ETH_SWITCH_ANALOG);
412		DELAY(250);
413	} else {
414		ar71xx_device_stop(AR934X_RESET_ETH_SWITCH_ANALOG);
415		DELAY(250);
416
417		ar71xx_device_stop(AR934X_RESET_NANDF);
418		DELAY(100);
419	}
420}
421
422/*
423 * Configure the GPIO output mux setup.
424 *
425 * The AR934x introduced an output mux which allowed
426 * certain functions to be configured on any pin.
427 * Specifically, the switch PHY link LEDs and
428 * WMAC external RX LNA switches are not limited to
429 * a specific GPIO pin.
430 */
431static void
432ar934x_chip_gpio_output_configure(int gpio, uint8_t func)
433{
434	uint32_t reg, s;
435	uint32_t t;
436
437	if (gpio > AR934X_GPIO_COUNT)
438		return;
439
440	reg = AR934X_GPIO_REG_OUT_FUNC0 + rounddown(gpio, 4);
441	s = 8 * (gpio % 4);
442
443	/* read-modify-write */
444	t = ATH_READ_REG(AR71XX_GPIO_BASE + reg);
445	t &= ~(0xff << s);
446	t |= func << s;
447	ATH_WRITE_REG(AR71XX_GPIO_BASE + reg, t);
448
449	/* flush write */
450	ATH_READ_REG(AR71XX_GPIO_BASE + reg);
451}
452
453struct ar71xx_cpu_def ar934x_chip_def = {
454	&ar934x_chip_detect_mem_size,
455	&ar934x_chip_detect_sys_frequency,
456	&ar934x_chip_device_stop,
457	&ar934x_chip_device_start,
458	&ar934x_chip_device_stopped,
459	&ar934x_chip_set_pll_ge,
460	&ar934x_chip_set_mii_speed,
461	&ar934x_chip_set_mii_if,
462	&ar934x_chip_get_eth_pll,
463	&ar934x_chip_ddr_flush,
464	&ar934x_chip_init_usb_peripheral,
465	&ar934x_chip_reset_ethernet_switch,
466	&ar934x_chip_reset_wmac,
467	&ar934x_chip_init_gmac,
468	&ar934x_chip_reset_nfc,
469	&ar934x_chip_gpio_output_configure,
470};
471