ar933x_chip.c revision 248809
1248782Sadrian/*-
2248782Sadrian * Copyright (c) 2012 Adrian Chadd <adrian@FreeBSD.org>
3248782Sadrian * All rights reserved.
4248782Sadrian *
5248782Sadrian * Redistribution and use in source and binary forms, with or without
6248782Sadrian * modification, are permitted provided that the following conditions
7248782Sadrian * are met:
8248782Sadrian * 1. Redistributions of source code must retain the above copyright
9248782Sadrian *    notice, this list of conditions and the following disclaimer.
10248782Sadrian * 2. Redistributions in binary form must reproduce the above copyright
11248782Sadrian *    notice, this list of conditions and the following disclaimer in the
12248782Sadrian *    documentation and/or other materials provided with the distribution.
13248782Sadrian *
14248782Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15248782Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16248782Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17248782Sadrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18248782Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19248782Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20248782Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21248782Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22248782Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23248782Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24248782Sadrian * SUCH DAMAGE.
25248782Sadrian */
26248782Sadrian
27248782Sadrian#include <sys/cdefs.h>
28248782Sadrian__FBSDID("$FreeBSD: head/sys/mips/atheros/ar933x_chip.c 248809 2013-03-28 05:43:03Z adrian $");
29248782Sadrian
30248782Sadrian#include "opt_ddb.h"
31248782Sadrian
32248782Sadrian#include <sys/param.h>
33248782Sadrian#include <sys/conf.h>
34248782Sadrian#include <sys/kernel.h>
35248782Sadrian#include <sys/systm.h>
36248782Sadrian#include <sys/bus.h>
37248782Sadrian#include <sys/cons.h>
38248782Sadrian#include <sys/kdb.h>
39248782Sadrian#include <sys/reboot.h>
40248782Sadrian
41248782Sadrian#include <vm/vm.h>
42248782Sadrian#include <vm/vm_page.h>
43248782Sadrian
44248782Sadrian#include <net/ethernet.h>
45248782Sadrian
46248782Sadrian#include <machine/clock.h>
47248782Sadrian#include <machine/cpu.h>
48248782Sadrian#include <machine/cpuregs.h>
49248782Sadrian#include <machine/hwfunc.h>
50248782Sadrian#include <machine/md_var.h>
51248782Sadrian#include <machine/trap.h>
52248782Sadrian#include <machine/vmparam.h>
53248782Sadrian
54248782Sadrian#include <mips/atheros/ar71xxreg.h>
55248782Sadrian#include <mips/atheros/ar933xreg.h>
56248782Sadrian
57248782Sadrian#include <mips/atheros/ar71xx_cpudef.h>
58248782Sadrian#include <mips/atheros/ar71xx_setup.h>
59248782Sadrian
60248782Sadrian#include <mips/atheros/ar71xx_chip.h>
61248782Sadrian#include <mips/atheros/ar933x_chip.h>
62248782Sadrian
63248782Sadrianstatic void
64248782Sadrianar933x_chip_detect_mem_size(void)
65248782Sadrian{
66248782Sadrian}
67248782Sadrian
68248782Sadrianstatic void
69248782Sadrianar933x_chip_detect_sys_frequency(void)
70248782Sadrian{
71248782Sadrian	uint32_t clock_ctrl;
72248782Sadrian	uint32_t cpu_config;
73248782Sadrian	uint32_t freq;
74248782Sadrian	uint32_t t;
75248782Sadrian
76248782Sadrian	t = ATH_READ_REG(AR933X_RESET_REG_BOOTSTRAP);
77248782Sadrian	if (t & AR933X_BOOTSTRAP_REF_CLK_40)
78248782Sadrian		u_ar71xx_refclk = (40 * 1000 * 1000);
79248782Sadrian	else
80248782Sadrian		u_ar71xx_refclk = (25 * 1000 * 1000);
81248782Sadrian
82248782Sadrian	clock_ctrl = ATH_READ_REG(AR933X_PLL_CLOCK_CTRL_REG);
83248782Sadrian	if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
84248782Sadrian		u_ar71xx_cpu_freq = u_ar71xx_refclk;
85248782Sadrian		u_ar71xx_ahb_freq = u_ar71xx_refclk;
86248782Sadrian		u_ar71xx_ddr_freq = u_ar71xx_refclk;
87248782Sadrian	} else {
88248782Sadrian		cpu_config = ATH_READ_REG(AR933X_PLL_CPU_CONFIG_REG);
89248782Sadrian
90248782Sadrian		t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
91248782Sadrian		    AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
92248782Sadrian		freq = u_ar71xx_refclk / t;
93248782Sadrian
94248782Sadrian		t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
95248782Sadrian		    AR933X_PLL_CPU_CONFIG_NINT_MASK;
96248782Sadrian		freq *= t;
97248782Sadrian
98248782Sadrian		t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
99248782Sadrian		    AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
100248782Sadrian		if (t == 0)
101248782Sadrian			t = 1;
102248782Sadrian
103248782Sadrian		freq >>= t;
104248782Sadrian
105248782Sadrian		t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
106248782Sadrian		     AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
107248782Sadrian		u_ar71xx_cpu_freq = freq / t;
108248782Sadrian
109248782Sadrian		t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
110248782Sadrian		      AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
111248782Sadrian		u_ar71xx_ddr_freq = freq / t;
112248782Sadrian
113248782Sadrian		t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
114248782Sadrian		     AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
115248782Sadrian		u_ar71xx_ahb_freq = freq / t;
116248782Sadrian	}
117248782Sadrian}
118248782Sadrian
119248782Sadrianstatic void
120248782Sadrianar933x_chip_device_stop(uint32_t mask)
121248782Sadrian{
122248809Sadrian	uint32_t reg;
123248782Sadrian
124248782Sadrian	reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE);
125248809Sadrian	ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg | mask);
126248782Sadrian}
127248782Sadrian
128248782Sadrianstatic void
129248782Sadrianar933x_chip_device_start(uint32_t mask)
130248782Sadrian{
131248809Sadrian	uint32_t reg;
132248782Sadrian
133248782Sadrian	reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE);
134248809Sadrian	ATH_WRITE_REG(AR933X_RESET_REG_RESET_MODULE, reg & ~mask);
135248782Sadrian}
136248782Sadrian
137248782Sadrianstatic int
138248782Sadrianar933x_chip_device_stopped(uint32_t mask)
139248782Sadrian{
140248782Sadrian	uint32_t reg;
141248782Sadrian
142248782Sadrian	reg = ATH_READ_REG(AR933X_RESET_REG_RESET_MODULE);
143248782Sadrian	return ((reg & mask) == mask);
144248782Sadrian}
145248782Sadrian
146248782Sadrianstatic void
147248782Sadrianar933x_chip_set_mii_speed(uint32_t unit, uint32_t speed)
148248782Sadrian{
149248782Sadrian
150248782Sadrian	/* XXX TODO */
151248782Sadrian	return;
152248782Sadrian}
153248782Sadrian
154248782Sadrian/*
155248782Sadrian * XXX TODO !!
156248782Sadrian */
157248782Sadrianstatic void
158248782Sadrianar933x_chip_set_pll_ge(int unit, int speed, uint32_t pll)
159248782Sadrian{
160248782Sadrian
161248782Sadrian	switch (unit) {
162248782Sadrian	case 0:
163248782Sadrian		/* XXX TODO */
164248782Sadrian		break;
165248782Sadrian	case 1:
166248782Sadrian		/* XXX TODO */
167248782Sadrian		break;
168248782Sadrian	default:
169248782Sadrian		printf("%s: invalid PLL set for arge unit: %d\n",
170248782Sadrian		    __func__, unit);
171248782Sadrian		return;
172248782Sadrian	}
173248782Sadrian}
174248782Sadrian
175248782Sadrianstatic void
176248782Sadrianar933x_chip_ddr_flush_ge(int unit)
177248782Sadrian{
178248782Sadrian
179248782Sadrian	switch (unit) {
180248782Sadrian	case 0:
181248782Sadrian		ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE0);
182248782Sadrian		break;
183248782Sadrian	case 1:
184248782Sadrian		ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_GE1);
185248782Sadrian		break;
186248782Sadrian	default:
187248782Sadrian		printf("%s: invalid DDR flush for arge unit: %d\n",
188248782Sadrian		    __func__, unit);
189248782Sadrian		return;
190248782Sadrian	}
191248782Sadrian}
192248782Sadrian
193248782Sadrianstatic void
194248782Sadrianar933x_chip_ddr_flush_ip2(void)
195248782Sadrian{
196248782Sadrian
197248782Sadrian	ar71xx_ddr_flush(AR933X_DDR_REG_FLUSH_WMAC);
198248782Sadrian}
199248782Sadrian
200248782Sadrianstatic uint32_t
201248782Sadrianar933x_chip_get_eth_pll(unsigned int mac, int speed)
202248782Sadrian{
203248782Sadrian
204248782Sadrian	return (0);
205248782Sadrian}
206248782Sadrian
207248782Sadrianstatic void
208248782Sadrianar933x_chip_init_usb_peripheral(void)
209248782Sadrian{
210248782Sadrian#if 0
211248782Sadrian	switch (ar71xx_soc) {
212248782Sadrian	case AR71XX_SOC_AR7240:
213248782Sadrian		ar71xx_device_stop(AR724X_RESET_MODULE_USB_OHCI_DLL |
214248782Sadrian		    AR724X_RESET_USB_HOST);
215248782Sadrian		DELAY(1000);
216248782Sadrian
217248782Sadrian		ar71xx_device_start(AR724X_RESET_MODULE_USB_OHCI_DLL |
218248782Sadrian		    AR724X_RESET_USB_HOST);
219248782Sadrian		DELAY(1000);
220248782Sadrian
221248782Sadrian		/*
222248782Sadrian		 * WAR for HW bug. Here it adjusts the duration
223248782Sadrian		 * between two SOFS.
224248782Sadrian		 */
225248782Sadrian		ATH_WRITE_REG(AR71XX_USB_CTRL_FLADJ,
226248782Sadrian		    (3 << USB_CTRL_FLADJ_A0_SHIFT));
227248782Sadrian
228248782Sadrian		break;
229248782Sadrian
230248782Sadrian	case AR71XX_SOC_AR7241:
231248782Sadrian	case AR71XX_SOC_AR7242:
232248782Sadrian		ar71xx_device_start(AR724X_RESET_MODULE_USB_OHCI_DLL);
233248782Sadrian		DELAY(100);
234248782Sadrian
235248782Sadrian		ar71xx_device_start(AR724X_RESET_USB_HOST);
236248782Sadrian		DELAY(100);
237248782Sadrian
238248782Sadrian		ar71xx_device_start(AR724X_RESET_USB_PHY);
239248782Sadrian		DELAY(100);
240248782Sadrian
241248782Sadrian		break;
242248782Sadrian
243248782Sadrian	default:
244248782Sadrian		break;
245248782Sadrian	}
246248782Sadrian#endif
247248782Sadrian}
248248782Sadrian
249248782Sadrianstruct ar71xx_cpu_def ar933x_chip_def = {
250248782Sadrian	&ar933x_chip_detect_mem_size,
251248782Sadrian	&ar933x_chip_detect_sys_frequency,
252248782Sadrian	&ar933x_chip_device_stop,
253248782Sadrian	&ar933x_chip_device_start,
254248782Sadrian	&ar933x_chip_device_stopped,
255248782Sadrian	&ar933x_chip_set_pll_ge,
256248782Sadrian	&ar933x_chip_set_mii_speed,
257248782Sadrian	&ar71xx_chip_set_mii_if,
258248782Sadrian	&ar933x_chip_ddr_flush_ge,
259248782Sadrian	&ar933x_chip_get_eth_pll,
260248782Sadrian	&ar933x_chip_ddr_flush_ip2,
261248782Sadrian	&ar933x_chip_init_usb_peripheral
262248782Sadrian};
263