xref: /openbmc/linux/arch/mips/bcm63xx/setup.c (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
1e7300d04SMaxime Bizon /*
2e7300d04SMaxime Bizon  * This file is subject to the terms and conditions of the GNU General Public
3e7300d04SMaxime Bizon  * License.  See the file "COPYING" in the main directory of this archive
4e7300d04SMaxime Bizon  * for more details.
5e7300d04SMaxime Bizon  *
6e7300d04SMaxime Bizon  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7e7300d04SMaxime Bizon  */
8e7300d04SMaxime Bizon 
9e7300d04SMaxime Bizon #include <linux/init.h>
10e7300d04SMaxime Bizon #include <linux/kernel.h>
11e7300d04SMaxime Bizon #include <linux/delay.h>
1257c8a661SMike Rapoport #include <linux/memblock.h>
13e7300d04SMaxime Bizon #include <linux/ioport.h>
14e7300d04SMaxime Bizon #include <linux/pm.h>
15e7300d04SMaxime Bizon #include <asm/bootinfo.h>
16e7300d04SMaxime Bizon #include <asm/time.h>
17e7300d04SMaxime Bizon #include <asm/reboot.h>
18e7300d04SMaxime Bizon #include <asm/cacheflush.h>
19e7300d04SMaxime Bizon #include <bcm63xx_board.h>
20e7300d04SMaxime Bizon #include <bcm63xx_cpu.h>
21e7300d04SMaxime Bizon #include <bcm63xx_regs.h>
22e7300d04SMaxime Bizon #include <bcm63xx_io.h>
232ec459f2SNicolas Schichan #include <bcm63xx_gpio.h>
24e7300d04SMaxime Bizon 
bcm63xx_machine_halt(void)25e7300d04SMaxime Bizon void bcm63xx_machine_halt(void)
26e7300d04SMaxime Bizon {
2763893ea5SGregory Fong 	pr_info("System halted\n");
28e7300d04SMaxime Bizon 	while (1)
29e7300d04SMaxime Bizon 		;
30e7300d04SMaxime Bizon }
31e7300d04SMaxime Bizon 
bcm6348_a1_reboot(void)32e7300d04SMaxime Bizon static void bcm6348_a1_reboot(void)
33e7300d04SMaxime Bizon {
34e7300d04SMaxime Bizon 	u32 reg;
35e7300d04SMaxime Bizon 
36e7300d04SMaxime Bizon 	/* soft reset all blocks */
3763893ea5SGregory Fong 	pr_info("soft-resetting all blocks ...\n");
38e7300d04SMaxime Bizon 	reg = bcm_perf_readl(PERF_SOFTRESET_REG);
39e7300d04SMaxime Bizon 	reg &= ~SOFTRESET_6348_ALL;
40e7300d04SMaxime Bizon 	bcm_perf_writel(reg, PERF_SOFTRESET_REG);
41e7300d04SMaxime Bizon 	mdelay(10);
42e7300d04SMaxime Bizon 
43e7300d04SMaxime Bizon 	reg = bcm_perf_readl(PERF_SOFTRESET_REG);
44e7300d04SMaxime Bizon 	reg |= SOFTRESET_6348_ALL;
45e7300d04SMaxime Bizon 	bcm_perf_writel(reg, PERF_SOFTRESET_REG);
46e7300d04SMaxime Bizon 	mdelay(10);
47e7300d04SMaxime Bizon 
48e7300d04SMaxime Bizon 	/* Jump to the power on address. */
4963893ea5SGregory Fong 	pr_info("jumping to reset vector.\n");
50e7300d04SMaxime Bizon 	/* set high vectors (base at 0xbfc00000 */
51e7300d04SMaxime Bizon 	set_c0_status(ST0_BEV | ST0_ERL);
52e7300d04SMaxime Bizon 	/* run uncached in kseg0 */
53e7300d04SMaxime Bizon 	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
54e7300d04SMaxime Bizon 	__flush_cache_all();
55e7300d04SMaxime Bizon 	/* remove all wired TLB entries */
56e7300d04SMaxime Bizon 	write_c0_wired(0);
57e7300d04SMaxime Bizon 	__asm__ __volatile__(
58e7300d04SMaxime Bizon 		"jr\t%0"
59e7300d04SMaxime Bizon 		:
60e7300d04SMaxime Bizon 		: "r" (0xbfc00000));
61e7300d04SMaxime Bizon 	while (1)
62e7300d04SMaxime Bizon 		;
63e7300d04SMaxime Bizon }
64e7300d04SMaxime Bizon 
bcm63xx_machine_reboot(void)65e7300d04SMaxime Bizon void bcm63xx_machine_reboot(void)
66e7300d04SMaxime Bizon {
676224892cSMaxime Bizon 	u32 reg, perf_regs[2] = { 0, 0 };
686224892cSMaxime Bizon 	unsigned int i;
69e7300d04SMaxime Bizon 
70e7300d04SMaxime Bizon 	/* mask and clear all external irq */
716224892cSMaxime Bizon 	switch (bcm63xx_get_cpu_id()) {
727b933421SFlorian Fainelli 	case BCM3368_CPU_ID:
737b933421SFlorian Fainelli 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_3368;
747b933421SFlorian Fainelli 		break;
75e5766aeaSJonas Gorski 	case BCM6328_CPU_ID:
76e5766aeaSJonas Gorski 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
77e5766aeaSJonas Gorski 		break;
786224892cSMaxime Bizon 	case BCM6338_CPU_ID:
796224892cSMaxime Bizon 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
806224892cSMaxime Bizon 		break;
8164eaea4aSMaxime Bizon 	case BCM6345_CPU_ID:
8264eaea4aSMaxime Bizon 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345;
8364eaea4aSMaxime Bizon 		break;
846224892cSMaxime Bizon 	case BCM6348_CPU_ID:
856224892cSMaxime Bizon 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
866224892cSMaxime Bizon 		break;
876224892cSMaxime Bizon 	case BCM6358_CPU_ID:
886224892cSMaxime Bizon 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6358;
896224892cSMaxime Bizon 		break;
902c8aaf71SJonas Gorski 	case BCM6362_CPU_ID:
912c8aaf71SJonas Gorski 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6362;
922c8aaf71SJonas Gorski 		break;
936224892cSMaxime Bizon 	}
946224892cSMaxime Bizon 
956224892cSMaxime Bizon 	for (i = 0; i < 2; i++) {
966d591805SMaxime Bizon 		if (!perf_regs[i])
976d591805SMaxime Bizon 			break;
986d591805SMaxime Bizon 
996224892cSMaxime Bizon 		reg = bcm_perf_readl(perf_regs[i]);
1006224892cSMaxime Bizon 		if (BCMCPU_IS_6348()) {
1016224892cSMaxime Bizon 			reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
1026224892cSMaxime Bizon 			reg |= EXTIRQ_CFG_CLEAR_ALL_6348;
1036224892cSMaxime Bizon 		} else {
104e7300d04SMaxime Bizon 			reg &= ~EXTIRQ_CFG_MASK_ALL;
105e7300d04SMaxime Bizon 			reg |= EXTIRQ_CFG_CLEAR_ALL;
1066224892cSMaxime Bizon 		}
1076224892cSMaxime Bizon 		bcm_perf_writel(reg, perf_regs[i]);
1086224892cSMaxime Bizon 	}
109e7300d04SMaxime Bizon 
110e7300d04SMaxime Bizon 	if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
111e7300d04SMaxime Bizon 		bcm6348_a1_reboot();
112e7300d04SMaxime Bizon 
11363893ea5SGregory Fong 	pr_info("triggering watchdog soft-reset...\n");
114e5766aeaSJonas Gorski 	if (BCMCPU_IS_6328()) {
115e5766aeaSJonas Gorski 		bcm_wdt_writel(1, WDT_SOFTRESET_REG);
116e5766aeaSJonas Gorski 	} else {
117e85d59dfSFlorian Fainelli 		reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
118e85d59dfSFlorian Fainelli 		reg |= SYS_PLL_SOFT_RESET;
119e85d59dfSFlorian Fainelli 		bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
120e5766aeaSJonas Gorski 	}
121e7300d04SMaxime Bizon 	while (1)
122e7300d04SMaxime Bizon 		;
123e7300d04SMaxime Bizon }
124e7300d04SMaxime Bizon 
__bcm63xx_machine_reboot(char * p)125e7300d04SMaxime Bizon static void __bcm63xx_machine_reboot(char *p)
126e7300d04SMaxime Bizon {
127e7300d04SMaxime Bizon 	bcm63xx_machine_reboot();
128e7300d04SMaxime Bizon }
129e7300d04SMaxime Bizon 
130e7300d04SMaxime Bizon /*
131e7300d04SMaxime Bizon  * return system type in /proc/cpuinfo
132e7300d04SMaxime Bizon  */
get_system_type(void)133e7300d04SMaxime Bizon const char *get_system_type(void)
134e7300d04SMaxime Bizon {
135e7300d04SMaxime Bizon 	static char buf[128];
1366605428cSJonas Gorski 	snprintf(buf, sizeof(buf), "bcm63xx/%s (0x%04x/0x%02X)",
137e7300d04SMaxime Bizon 		 board_get_name(),
138e7300d04SMaxime Bizon 		 bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
139e7300d04SMaxime Bizon 	return buf;
140e7300d04SMaxime Bizon }
141e7300d04SMaxime Bizon 
plat_time_init(void)142e7300d04SMaxime Bizon void __init plat_time_init(void)
143e7300d04SMaxime Bizon {
144e7300d04SMaxime Bizon 	mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2;
145e7300d04SMaxime Bizon }
146e7300d04SMaxime Bizon 
plat_mem_setup(void)147e7300d04SMaxime Bizon void __init plat_mem_setup(void)
148e7300d04SMaxime Bizon {
149*e7ae8d17SThomas Bogendoerfer 	memblock_add(0, bcm63xx_get_memory_size());
150e7300d04SMaxime Bizon 
151e7300d04SMaxime Bizon 	_machine_halt = bcm63xx_machine_halt;
152e7300d04SMaxime Bizon 	_machine_restart = __bcm63xx_machine_reboot;
153e7300d04SMaxime Bizon 	pm_power_off = bcm63xx_machine_halt;
154e7300d04SMaxime Bizon 
155e7300d04SMaxime Bizon 	set_io_port_base(0);
156e7300d04SMaxime Bizon 	ioport_resource.start = 0;
157e7300d04SMaxime Bizon 	ioport_resource.end = ~0;
158e7300d04SMaxime Bizon 
159e7300d04SMaxime Bizon 	board_setup();
160e7300d04SMaxime Bizon }
161e7300d04SMaxime Bizon 
bcm63xx_register_devices(void)162e7300d04SMaxime Bizon int __init bcm63xx_register_devices(void)
163e7300d04SMaxime Bizon {
1642ec459f2SNicolas Schichan 	/* register gpiochip */
1652ec459f2SNicolas Schichan 	bcm63xx_gpio_init();
1662ec459f2SNicolas Schichan 
167e7300d04SMaxime Bizon 	return board_register_devices();
168e7300d04SMaxime Bizon }
169e7300d04SMaxime Bizon 
1701762c5abSJonas Gorski arch_initcall(bcm63xx_register_devices);
171