xref: /netbsd-src/sys/arch/mips/atheros/ar5312_board.c (revision 97627a755de6688e3779397891de0a51dd226e2f)
1*97627a75Smatt /* $NetBSD: ar5312_board.c,v 1.5 2015/06/09 22:50:50 matt Exp $ */
2e653071cSgdamore /*
3e653071cSgdamore  * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
4e653071cSgdamore  * Copyright (c) 2006 Garrett D'Amore.
5e653071cSgdamore  * All rights reserved.
6e653071cSgdamore  *
7e653071cSgdamore  * This code was written by Garrett D'Amore for the Champaign-Urbana
8e653071cSgdamore  * Community Wireless Network Project.
9e653071cSgdamore  *
10e653071cSgdamore  * Redistribution and use in source and binary forms, with or
11e653071cSgdamore  * without modification, are permitted provided that the following
12e653071cSgdamore  * conditions are met:
13e653071cSgdamore  * 1. Redistributions of source code must retain the above copyright
14e653071cSgdamore  *    notice, this list of conditions and the following disclaimer.
15e653071cSgdamore  * 2. Redistributions in binary form must reproduce the above
16e653071cSgdamore  *    copyright notice, this list of conditions and the following
17e653071cSgdamore  *    disclaimer in the documentation and/or other materials provided
18e653071cSgdamore  *    with the distribution.
19e653071cSgdamore  * 3. All advertising materials mentioning features or use of this
20e653071cSgdamore  *    software must display the following acknowledgements:
21e653071cSgdamore  *      This product includes software developed by the Urbana-Champaign
22e653071cSgdamore  *      Independent Media Center.
23e653071cSgdamore  *	This product includes software developed by Garrett D'Amore.
24e653071cSgdamore  * 4. Urbana-Champaign Independent Media Center's name and Garrett
25e653071cSgdamore  *    D'Amore's name may not be used to endorse or promote products
26e653071cSgdamore  *    derived from this software without specific prior written permission.
27e653071cSgdamore  *
28e653071cSgdamore  * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
29e653071cSgdamore  * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
30e653071cSgdamore  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31e653071cSgdamore  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32e653071cSgdamore  * ARE DISCLAIMED.  IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
33e653071cSgdamore  * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
34e653071cSgdamore  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
35e653071cSgdamore  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36e653071cSgdamore  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
37e653071cSgdamore  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38e653071cSgdamore  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39e653071cSgdamore  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
40e653071cSgdamore  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41e653071cSgdamore  */
42e653071cSgdamore #include <sys/cdefs.h>
43*97627a75Smatt __KERNEL_RCSID(0, "$NetBSD: ar5312_board.c,v 1.5 2015/06/09 22:50:50 matt Exp $");
44e653071cSgdamore 
45e653071cSgdamore #include <sys/param.h>
46e265f67bSdyoung #include <sys/bus.h>
47*97627a75Smatt #include <sys/device.h>
48*97627a75Smatt #include <sys/systm.h>
49*97627a75Smatt 
50*97627a75Smatt #include <mips/cpuregs.h>
51*97627a75Smatt 
52e653071cSgdamore #include <mips/atheros/include/ar5312reg.h>
5381d18a2fSmatt #include <mips/atheros/include/platform.h>
54e653071cSgdamore 
556ce0e276Salc #include <ah_soc.h>
56e653071cSgdamore 
57e653071cSgdamore extern const char *ether_sprintf(const uint8_t *);
58e653071cSgdamore 
59e653071cSgdamore /*
60e653071cSgdamore  * Locate the Board Configuration data using heuristics.
61e653071cSgdamore  * Search backward from the (aliased) end of flash looking
62e653071cSgdamore  * for the signature string that marks the start of the data.
63e653071cSgdamore  * We search at most 500KB.
64e653071cSgdamore  */
6581d18a2fSmatt static const struct ar531x_boarddata *
ar5312_get_board_info(void)6681d18a2fSmatt ar5312_get_board_info(void)
67e653071cSgdamore {
68e653071cSgdamore 	static const struct ar531x_boarddata *board = NULL;
69e653071cSgdamore 	const uint8_t *ptr, *end;
70e653071cSgdamore 	uint32_t fctl;
71e653071cSgdamore 
72e653071cSgdamore 	if (board == NULL) {
73e653071cSgdamore 		/* configure flash bank 0 */
74e653071cSgdamore 		fctl = REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_0) &
7581d18a2fSmatt 		    AR5312_FLASHCTL_MW;
76e653071cSgdamore 
77e653071cSgdamore 		fctl |=
78e653071cSgdamore 		    AR5312_FLASHCTL_E |
79e653071cSgdamore 		    AR5312_FLASHCTL_RBLE |
80e653071cSgdamore 		    AR5312_FLASHCTL_AC_8M |
8181d18a2fSmatt 		    __SHIFTIN(1, AR5312_FLASHCTL_IDCY) |
8281d18a2fSmatt 		    __SHIFTIN(7, AR5312_FLASHCTL_WST1) |
8381d18a2fSmatt 		    __SHIFTIN(7, AR5312_FLASHCTL_WST2);
84e653071cSgdamore 
85e653071cSgdamore 		REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_0) = fctl;
86e653071cSgdamore 
87e653071cSgdamore 		REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_1) &=
8881d18a2fSmatt 		    ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
89e653071cSgdamore 
90e653071cSgdamore 		REGVAL(AR5312_FLASHCTL_BASE + AR5312_FLASHCTL_2) &=
9181d18a2fSmatt 		    ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
92e653071cSgdamore 
93e653071cSgdamore 		/* search backward in the flash looking for the signature */
94e653071cSgdamore 		ptr = (const uint8_t *) MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END - 0x1000);
95e653071cSgdamore 		end = ptr - (500 * 1024);	/* NB: max 500KB window */
96e653071cSgdamore 		/* XXX validate end */
97e653071cSgdamore 		for (; ptr > end; ptr -= 0x1000)
98e653071cSgdamore 			if (*(const uint32_t *)ptr == AR531X_BD_MAGIC) {
99e653071cSgdamore 				board = (const struct ar531x_boarddata *) ptr;
100e653071cSgdamore 				break;
101e653071cSgdamore 			}
102e653071cSgdamore 	}
103e653071cSgdamore 	return board;
104e653071cSgdamore }
105e653071cSgdamore 
106e653071cSgdamore /*
107e653071cSgdamore  * Locate the radio configuration data; it is located relative
108e653071cSgdamore  * to the board configuration data.
109e653071cSgdamore  */
11081d18a2fSmatt static const void *
ar5312_get_radio_info(void)11181d18a2fSmatt ar5312_get_radio_info(void)
112e653071cSgdamore {
113e653071cSgdamore 	static const void *radio = NULL;
114e653071cSgdamore 	const struct ar531x_boarddata *board;
115e653071cSgdamore 	const uint8_t *baddr, *ptr, *end;
116e653071cSgdamore 
117e653071cSgdamore 	if (radio == NULL) {
11881d18a2fSmatt 		board = ar5312_get_board_info();
119e653071cSgdamore 		if (board == NULL)
120e653071cSgdamore 			return NULL;
121e653071cSgdamore 		baddr = (const uint8_t *) board;
122e653071cSgdamore 		ptr = baddr + 0x1000;
123e653071cSgdamore 		end = (const uint8_t *)
124e653071cSgdamore 		    MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END-0x1000);
125e653071cSgdamore 	again:
126e653071cSgdamore 		for (; ptr < end; ptr += 0x1000)
127e653071cSgdamore 			if (*(const uint32_t *)ptr != 0xffffffff) {
128e653071cSgdamore 				radio = ptr;
129e653071cSgdamore 				goto done;
130e653071cSgdamore 			}
131e653071cSgdamore 		/* sort of an Algol-style for loop ... */
132e653071cSgdamore 		if (end == (uint8_t *) MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END)) {
133e653071cSgdamore 			/* NB: AR2316 has radio data in a different location */
134e653071cSgdamore 			ptr = baddr + 0xf8;
135e653071cSgdamore 			end = (const uint8_t *)
136e653071cSgdamore 			    MIPS_PHYS_TO_KSEG1(AR5312_FLASH_END-0x1000 + 0xf8);
137e653071cSgdamore 			goto again;
138e653071cSgdamore 		}
139e653071cSgdamore 	}
140e653071cSgdamore done:
141e653071cSgdamore 	return radio;
142e653071cSgdamore }
143e653071cSgdamore 
14481d18a2fSmatt const struct atheros_boardsw ar5312_boardsw = {
14581d18a2fSmatt 	.absw_get_board_info = ar5312_get_board_info,
14681d18a2fSmatt 	.absw_get_radio_info = ar5312_get_radio_info,
14781d18a2fSmatt };
148