xref: /openbmc/linux/arch/mips/bcm47xx/setup.c (revision 1690a7f9ab83f5c823f3044275a4a771a059d5bb)
11c0c13ebSAurelien Jarno /*
21c0c13ebSAurelien Jarno  *  Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
31c0c13ebSAurelien Jarno  *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
41c0c13ebSAurelien Jarno  *  Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
5121915c4SWaldemar Brodkorb  *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
61c0c13ebSAurelien Jarno  *
71c0c13ebSAurelien Jarno  *  This program is free software; you can redistribute  it and/or modify it
81c0c13ebSAurelien Jarno  *  under  the terms of  the GNU General  Public License as published by the
91c0c13ebSAurelien Jarno  *  Free Software Foundation;  either version 2 of the  License, or (at your
101c0c13ebSAurelien Jarno  *  option) any later version.
111c0c13ebSAurelien Jarno  *
121c0c13ebSAurelien Jarno  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
131c0c13ebSAurelien Jarno  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
141c0c13ebSAurelien Jarno  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
151c0c13ebSAurelien Jarno  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
161c0c13ebSAurelien Jarno  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
171c0c13ebSAurelien Jarno  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
181c0c13ebSAurelien Jarno  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
191c0c13ebSAurelien Jarno  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
201c0c13ebSAurelien Jarno  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
211c0c13ebSAurelien Jarno  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
221c0c13ebSAurelien Jarno  *
231c0c13ebSAurelien Jarno  *  You should have received a copy of the  GNU General Public License along
241c0c13ebSAurelien Jarno  *  with this program; if not, write  to the Free Software Foundation, Inc.,
251c0c13ebSAurelien Jarno  *  675 Mass Ave, Cambridge, MA 02139, USA.
261c0c13ebSAurelien Jarno  */
271c0c13ebSAurelien Jarno 
281c0c13ebSAurelien Jarno #include <linux/types.h>
291c0c13ebSAurelien Jarno #include <linux/ssb/ssb.h>
30b06f3e19SAurelien Jarno #include <linux/ssb/ssb_embedded.h>
3125e5fb97SAurelien Jarno #include <asm/bootinfo.h>
321c0c13ebSAurelien Jarno #include <asm/reboot.h>
331c0c13ebSAurelien Jarno #include <asm/time.h>
341c0c13ebSAurelien Jarno #include <bcm47xx.h>
35121915c4SWaldemar Brodkorb #include <asm/mach-bcm47xx/nvram.h>
361c0c13ebSAurelien Jarno 
371c0c13ebSAurelien Jarno struct ssb_bus ssb_bcm47xx;
381c0c13ebSAurelien Jarno EXPORT_SYMBOL(ssb_bcm47xx);
391c0c13ebSAurelien Jarno 
401c0c13ebSAurelien Jarno static void bcm47xx_machine_restart(char *command)
411c0c13ebSAurelien Jarno {
421c0c13ebSAurelien Jarno 	printk(KERN_ALERT "Please stand by while rebooting the system...\n");
431c0c13ebSAurelien Jarno 	local_irq_disable();
441c0c13ebSAurelien Jarno 	/* Set the watchdog timer to reset immediately */
45b06f3e19SAurelien Jarno 	ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
461c0c13ebSAurelien Jarno 	while (1)
471c0c13ebSAurelien Jarno 		cpu_relax();
481c0c13ebSAurelien Jarno }
491c0c13ebSAurelien Jarno 
501c0c13ebSAurelien Jarno static void bcm47xx_machine_halt(void)
511c0c13ebSAurelien Jarno {
521c0c13ebSAurelien Jarno 	/* Disable interrupts and watchdog and spin forever */
531c0c13ebSAurelien Jarno 	local_irq_disable();
54b06f3e19SAurelien Jarno 	ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
551c0c13ebSAurelien Jarno 	while (1)
561c0c13ebSAurelien Jarno 		cpu_relax();
571c0c13ebSAurelien Jarno }
581c0c13ebSAurelien Jarno 
592aa088d6SHauke Mehrtens #define READ_FROM_NVRAM(_outvar, name, buf) \
602aa088d6SHauke Mehrtens 	if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
612aa088d6SHauke Mehrtens 		sprom->_outvar = simple_strtoul(buf, NULL, 0);
622aa088d6SHauke Mehrtens 
632aa088d6SHauke Mehrtens static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
642aa088d6SHauke Mehrtens {
652aa088d6SHauke Mehrtens 	char buf[100];
662aa088d6SHauke Mehrtens 	u32 boardflags;
672aa088d6SHauke Mehrtens 
682aa088d6SHauke Mehrtens 	memset(sprom, 0, sizeof(struct ssb_sprom));
692aa088d6SHauke Mehrtens 
702aa088d6SHauke Mehrtens 	sprom->revision = 1; /* Fallback: Old hardware does not define this. */
712aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(revision, "sromrev", buf);
722aa088d6SHauke Mehrtens 	if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
7359833fcfSHauke Mehrtens 		nvram_parse_macaddr(buf, sprom->il0mac);
742aa088d6SHauke Mehrtens 	if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
7559833fcfSHauke Mehrtens 		nvram_parse_macaddr(buf, sprom->et0mac);
762aa088d6SHauke Mehrtens 	if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
7759833fcfSHauke Mehrtens 		nvram_parse_macaddr(buf, sprom->et1mac);
782aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
792aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
802aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
812aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
822aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(board_rev, "boardrev", buf);
832aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(country_code, "ccode", buf);
842aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
852aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
862aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
872aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
882aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
892aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
902aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
912aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
922aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
932aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
942aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
952aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
962aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
972aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
982aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
992aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
1002aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
1012aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
1022aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
1032aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
1042aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
1052aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
1062aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
1072aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
1082aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(tri2g, "tri2g", buf);
1092aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
1102aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(tri5g, "tri5g", buf);
1112aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
1122aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
1132aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
1142aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
1152aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
1162aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
1172aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
1182aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
1192aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
1202aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
1212aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
1222aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
1232aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
1242aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
1252aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
1262aa088d6SHauke Mehrtens 	READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
1272aa088d6SHauke Mehrtens 
1282aa088d6SHauke Mehrtens 	if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
1292aa088d6SHauke Mehrtens 		boardflags = simple_strtoul(buf, NULL, 0);
1302aa088d6SHauke Mehrtens 		if (boardflags) {
1312aa088d6SHauke Mehrtens 			sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
1322aa088d6SHauke Mehrtens 			sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
1332aa088d6SHauke Mehrtens 		}
1342aa088d6SHauke Mehrtens 	}
1352aa088d6SHauke Mehrtens 	if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
1362aa088d6SHauke Mehrtens 		boardflags = simple_strtoul(buf, NULL, 0);
1372aa088d6SHauke Mehrtens 		if (boardflags) {
1382aa088d6SHauke Mehrtens 			sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
1392aa088d6SHauke Mehrtens 			sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
1402aa088d6SHauke Mehrtens 		}
1412aa088d6SHauke Mehrtens 	}
1422aa088d6SHauke Mehrtens }
1432aa088d6SHauke Mehrtens 
1441c0c13ebSAurelien Jarno static int bcm47xx_get_invariants(struct ssb_bus *bus,
1451c0c13ebSAurelien Jarno 				   struct ssb_init_invariants *iv)
1461c0c13ebSAurelien Jarno {
1472aa088d6SHauke Mehrtens 	char buf[20];
14825e5fb97SAurelien Jarno 
14925e5fb97SAurelien Jarno 	/* Fill boardinfo structure */
15025e5fb97SAurelien Jarno 	memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
15125e5fb97SAurelien Jarno 
15282571084SHauke Mehrtens 	if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
1532aa088d6SHauke Mehrtens 		iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
1542aa088d6SHauke Mehrtens 	else
1552aa088d6SHauke Mehrtens 		iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
15682571084SHauke Mehrtens 	if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
15725e5fb97SAurelien Jarno 		iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
15882571084SHauke Mehrtens 	if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
15925e5fb97SAurelien Jarno 		iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
16025e5fb97SAurelien Jarno 
1612aa088d6SHauke Mehrtens 	bcm47xx_fill_sprom(&iv->sprom);
16225e5fb97SAurelien Jarno 
1632aa088d6SHauke Mehrtens 	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
1642aa088d6SHauke Mehrtens 		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
16525e5fb97SAurelien Jarno 
1661c0c13ebSAurelien Jarno 	return 0;
1671c0c13ebSAurelien Jarno }
1681c0c13ebSAurelien Jarno 
1691c0c13ebSAurelien Jarno void __init plat_mem_setup(void)
1701c0c13ebSAurelien Jarno {
1711c0c13ebSAurelien Jarno 	int err;
172*1690a7f9SHauke Mehrtens 	char buf[100];
173*1690a7f9SHauke Mehrtens 	struct ssb_mipscore *mcore;
1741c0c13ebSAurelien Jarno 
1751c0c13ebSAurelien Jarno 	err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
1761c0c13ebSAurelien Jarno 				      bcm47xx_get_invariants);
1771c0c13ebSAurelien Jarno 	if (err)
1781c0c13ebSAurelien Jarno 		panic("Failed to initialize SSB bus (err %d)\n", err);
1791c0c13ebSAurelien Jarno 
180*1690a7f9SHauke Mehrtens 	mcore = &ssb_bcm47xx.mipscore;
181*1690a7f9SHauke Mehrtens 	if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
182*1690a7f9SHauke Mehrtens 		if (strstr(buf, "console=ttyS1")) {
183*1690a7f9SHauke Mehrtens 			struct ssb_serial_port port;
184*1690a7f9SHauke Mehrtens 
185*1690a7f9SHauke Mehrtens 			printk(KERN_DEBUG "Swapping serial ports!\n");
186*1690a7f9SHauke Mehrtens 			/* swap serial ports */
187*1690a7f9SHauke Mehrtens 			memcpy(&port, &mcore->serial_ports[0], sizeof(port));
188*1690a7f9SHauke Mehrtens 			memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
189*1690a7f9SHauke Mehrtens 			       sizeof(port));
190*1690a7f9SHauke Mehrtens 			memcpy(&mcore->serial_ports[1], &port, sizeof(port));
191*1690a7f9SHauke Mehrtens 		}
192*1690a7f9SHauke Mehrtens 	}
193*1690a7f9SHauke Mehrtens 
1941c0c13ebSAurelien Jarno 	_machine_restart = bcm47xx_machine_restart;
1951c0c13ebSAurelien Jarno 	_machine_halt = bcm47xx_machine_halt;
1961c0c13ebSAurelien Jarno 	pm_power_off = bcm47xx_machine_halt;
1971c0c13ebSAurelien Jarno }
198