1315806cbSRalf Baechle /*
249bffbdcSSteven J. Hill * This file is subject to the terms and conditions of the GNU General Public
349bffbdcSSteven J. Hill * License. See the file "COPYING" in the main directory of this archive
449bffbdcSSteven J. Hill * for more details.
549bffbdcSSteven J. Hill *
649bffbdcSSteven J. Hill * PROM library initialisation code.
749bffbdcSSteven J. Hill *
849bffbdcSSteven J. Hill * Copyright (C) 1999,2000,2004,2005,2012 MIPS Technologies, Inc.
9315806cbSRalf Baechle * All rights reserved.
10315806cbSRalf Baechle * Authors: Carsten Langgaard <carstenl@mips.com>
11315806cbSRalf Baechle * Maciej W. Rozycki <macro@mips.com>
1249bffbdcSSteven J. Hill * Steven J. Hill <sjhill@mips.com>
13315806cbSRalf Baechle */
14315806cbSRalf Baechle #include <linux/init.h>
15315806cbSRalf Baechle #include <linux/string.h>
16315806cbSRalf Baechle #include <linux/kernel.h>
17422dd256SPaul Burton #include <linux/pci_regs.h>
18df519e7bSPeter Hurley #include <linux/serial_core.h>
19315806cbSRalf Baechle
20315806cbSRalf Baechle #include <asm/cacheflush.h>
21852fe310SRalf Baechle #include <asm/smp-ops.h>
22315806cbSRalf Baechle #include <asm/traps.h>
23b431f09dSSteven J. Hill #include <asm/fw/fw.h>
24e83f7e02SPaul Burton #include <asm/mips-cps.h>
25315806cbSRalf Baechle #include <asm/mips-boards/generic.h>
26315806cbSRalf Baechle #include <asm/mips-boards/malta.h>
27315806cbSRalf Baechle
28d0cdfe24SDmitri Vorobiev static int mips_revision_corid;
29315806cbSRalf Baechle int mips_revision_sconid;
30315806cbSRalf Baechle
31315806cbSRalf Baechle /* Bonito64 system controller register base. */
32315806cbSRalf Baechle unsigned long _pcictrl_bonito;
33315806cbSRalf Baechle unsigned long _pcictrl_bonito_pcicfg;
34315806cbSRalf Baechle
35315806cbSRalf Baechle /* GT64120 system controller register base */
36315806cbSRalf Baechle unsigned long _pcictrl_gt64120;
37315806cbSRalf Baechle
38315806cbSRalf Baechle /* MIPS System controller register base */
39315806cbSRalf Baechle unsigned long _pcictrl_msc;
40315806cbSRalf Baechle
41315806cbSRalf Baechle #ifdef CONFIG_SERIAL_8250_CONSOLE
console_config(void)42315806cbSRalf Baechle static void __init console_config(void)
43315806cbSRalf Baechle {
44315806cbSRalf Baechle char console_string[40];
45315806cbSRalf Baechle int baud = 0;
46315806cbSRalf Baechle char parity = '\0', bits = '\0', flow = '\0';
47315806cbSRalf Baechle char *s;
48315806cbSRalf Baechle
49b431f09dSSteven J. Hill s = fw_getenv("modetty0");
50315806cbSRalf Baechle if (s) {
51315806cbSRalf Baechle while (*s >= '0' && *s <= '9')
52315806cbSRalf Baechle baud = baud*10 + *s++ - '0';
5349bffbdcSSteven J. Hill if (*s == ',')
5449bffbdcSSteven J. Hill s++;
5549bffbdcSSteven J. Hill if (*s)
5649bffbdcSSteven J. Hill parity = *s++;
5749bffbdcSSteven J. Hill if (*s == ',')
5849bffbdcSSteven J. Hill s++;
5949bffbdcSSteven J. Hill if (*s)
6049bffbdcSSteven J. Hill bits = *s++;
6149bffbdcSSteven J. Hill if (*s == ',')
6249bffbdcSSteven J. Hill s++;
6349bffbdcSSteven J. Hill if (*s == 'h')
6449bffbdcSSteven J. Hill flow = 'r';
65315806cbSRalf Baechle }
66315806cbSRalf Baechle if (baud == 0)
67315806cbSRalf Baechle baud = 38400;
68315806cbSRalf Baechle if (parity != 'n' && parity != 'o' && parity != 'e')
69315806cbSRalf Baechle parity = 'n';
70315806cbSRalf Baechle if (bits != '7' && bits != '8')
71315806cbSRalf Baechle bits = '8';
72315806cbSRalf Baechle if (flow == '\0')
73315806cbSRalf Baechle flow = 'r';
7423a91de4SPaul Burton
7523a91de4SPaul Burton if ((strstr(fw_getcmdline(), "earlycon=")) == NULL) {
7623a91de4SPaul Burton sprintf(console_string, "uart8250,io,0x3f8,%d%c%c", baud,
7723a91de4SPaul Burton parity, bits);
78df519e7bSPeter Hurley setup_earlycon(console_string);
7923a91de4SPaul Burton }
8023a91de4SPaul Burton
8123a91de4SPaul Burton if ((strstr(fw_getcmdline(), "console=")) == NULL) {
8249bffbdcSSteven J. Hill sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
8349bffbdcSSteven J. Hill parity, bits, flow);
84b431f09dSSteven J. Hill strcat(fw_getcmdline(), console_string);
85315806cbSRalf Baechle pr_info("Config serial console:%s\n", console_string);
86315806cbSRalf Baechle }
87315806cbSRalf Baechle }
88315806cbSRalf Baechle #endif
89315806cbSRalf Baechle
mips_nmi_setup(void)90315806cbSRalf Baechle static void __init mips_nmi_setup(void)
91315806cbSRalf Baechle {
92315806cbSRalf Baechle void *base;
93315806cbSRalf Baechle
94315806cbSRalf Baechle base = cpu_has_veic ?
95315806cbSRalf Baechle (void *)(CAC_BASE + 0xa80) :
96315806cbSRalf Baechle (void *)(CAC_BASE + 0x380);
97*f39293fdSBen Hutchings memcpy(base, except_vec_nmi, 0x80);
98315806cbSRalf Baechle flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
99315806cbSRalf Baechle }
100315806cbSRalf Baechle
mips_ejtag_setup(void)101315806cbSRalf Baechle static void __init mips_ejtag_setup(void)
102315806cbSRalf Baechle {
103315806cbSRalf Baechle void *base;
104*f39293fdSBen Hutchings extern char except_vec_ejtag_debug[];
105315806cbSRalf Baechle
106315806cbSRalf Baechle base = cpu_has_veic ?
107315806cbSRalf Baechle (void *)(CAC_BASE + 0xa00) :
108315806cbSRalf Baechle (void *)(CAC_BASE + 0x300);
109*f39293fdSBen Hutchings memcpy(base, except_vec_ejtag_debug, 0x80);
110315806cbSRalf Baechle flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
111315806cbSRalf Baechle }
112315806cbSRalf Baechle
mips_cpc_default_phys_base(void)11315d45cceSRalf Baechle phys_addr_t mips_cpc_default_phys_base(void)
1147dc2834fSPaul Burton {
1157dc2834fSPaul Burton return CPC_BASE_ADDR;
1167dc2834fSPaul Burton }
1177dc2834fSPaul Burton
prom_init(void)118315806cbSRalf Baechle void __init prom_init(void)
119315806cbSRalf Baechle {
120315806cbSRalf Baechle /*
121315806cbSRalf Baechle * early setup of _pcictrl_bonito so that we can determine
122315806cbSRalf Baechle * the system controller on a CORE_EMUL board
123315806cbSRalf Baechle */
124315806cbSRalf Baechle _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
125315806cbSRalf Baechle
126315806cbSRalf Baechle mips_revision_corid = MIPS_REVISION_CORID;
127315806cbSRalf Baechle
128315806cbSRalf Baechle if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
129315806cbSRalf Baechle if (BONITO_PCIDID == 0x0001df53 ||
130315806cbSRalf Baechle BONITO_PCIDID == 0x0003df53)
131315806cbSRalf Baechle mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
132315806cbSRalf Baechle else
133315806cbSRalf Baechle mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
134315806cbSRalf Baechle }
135315806cbSRalf Baechle
136315806cbSRalf Baechle mips_revision_sconid = MIPS_REVISION_SCONID;
137315806cbSRalf Baechle if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) {
138315806cbSRalf Baechle switch (mips_revision_corid) {
139315806cbSRalf Baechle case MIPS_REVISION_CORID_QED_RM5261:
140315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_LV:
141315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_FPGA:
142315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_FPGAR2:
143315806cbSRalf Baechle mips_revision_sconid = MIPS_REVISION_SCON_GT64120;
144315806cbSRalf Baechle break;
145315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_EMUL_BON:
146315806cbSRalf Baechle case MIPS_REVISION_CORID_BONITO64:
147315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_20K:
148315806cbSRalf Baechle mips_revision_sconid = MIPS_REVISION_SCON_BONITO;
149315806cbSRalf Baechle break;
150315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_MSC:
151315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_FPGA2:
152315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_24K:
153315806cbSRalf Baechle /*
154315806cbSRalf Baechle * SOCit/ROCit support is essentially identical
155315806cbSRalf Baechle * but make an attempt to distinguish them
156315806cbSRalf Baechle */
157315806cbSRalf Baechle mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
158315806cbSRalf Baechle break;
159315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_FPGA3:
160315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_FPGA4:
161315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_FPGA5:
162315806cbSRalf Baechle case MIPS_REVISION_CORID_CORE_EMUL_MSC:
163315806cbSRalf Baechle default:
164315806cbSRalf Baechle /* See above */
165315806cbSRalf Baechle mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
166315806cbSRalf Baechle break;
167315806cbSRalf Baechle }
168315806cbSRalf Baechle }
169315806cbSRalf Baechle
170315806cbSRalf Baechle switch (mips_revision_sconid) {
171315806cbSRalf Baechle u32 start, map, mask, data;
172315806cbSRalf Baechle
173315806cbSRalf Baechle case MIPS_REVISION_SCON_GT64120:
174315806cbSRalf Baechle /*
175315806cbSRalf Baechle * Setup the North bridge to do Master byte-lane swapping
176315806cbSRalf Baechle * when running in bigendian.
177315806cbSRalf Baechle */
178315806cbSRalf Baechle _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
179315806cbSRalf Baechle
180315806cbSRalf Baechle #ifdef CONFIG_CPU_LITTLE_ENDIAN
181315806cbSRalf Baechle GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
182315806cbSRalf Baechle GT_PCI0_CMD_SBYTESWAP_BIT);
183315806cbSRalf Baechle #else
184315806cbSRalf Baechle GT_WRITE(GT_PCI0_CMD_OFS, 0);
185315806cbSRalf Baechle #endif
186315806cbSRalf Baechle /* Fix up PCI I/O mapping if necessary (for Atlas). */
187315806cbSRalf Baechle start = GT_READ(GT_PCI0IOLD_OFS);
188315806cbSRalf Baechle map = GT_READ(GT_PCI0IOREMAP_OFS);
189315806cbSRalf Baechle if ((start & map) != 0) {
190315806cbSRalf Baechle map &= ~start;
191315806cbSRalf Baechle GT_WRITE(GT_PCI0IOREMAP_OFS, map);
192315806cbSRalf Baechle }
193315806cbSRalf Baechle
194315806cbSRalf Baechle set_io_port_base(MALTA_GT_PORT_BASE);
195315806cbSRalf Baechle break;
196315806cbSRalf Baechle
197315806cbSRalf Baechle case MIPS_REVISION_SCON_BONITO:
198315806cbSRalf Baechle _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
199315806cbSRalf Baechle
200315806cbSRalf Baechle /*
201315806cbSRalf Baechle * Disable Bonito IOBC.
202315806cbSRalf Baechle */
203315806cbSRalf Baechle BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
204315806cbSRalf Baechle ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
205315806cbSRalf Baechle BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
206315806cbSRalf Baechle
207315806cbSRalf Baechle /*
208315806cbSRalf Baechle * Setup the North bridge to do Master byte-lane swapping
209315806cbSRalf Baechle * when running in bigendian.
210315806cbSRalf Baechle */
211315806cbSRalf Baechle #ifdef CONFIG_CPU_LITTLE_ENDIAN
212315806cbSRalf Baechle BONITO_BONGENCFG = BONITO_BONGENCFG &
213315806cbSRalf Baechle ~(BONITO_BONGENCFG_MSTRBYTESWAP |
214315806cbSRalf Baechle BONITO_BONGENCFG_BYTESWAP);
215315806cbSRalf Baechle #else
216315806cbSRalf Baechle BONITO_BONGENCFG = BONITO_BONGENCFG |
217315806cbSRalf Baechle BONITO_BONGENCFG_MSTRBYTESWAP |
218315806cbSRalf Baechle BONITO_BONGENCFG_BYTESWAP;
219315806cbSRalf Baechle #endif
220315806cbSRalf Baechle
221315806cbSRalf Baechle set_io_port_base(MALTA_BONITO_PORT_BASE);
222315806cbSRalf Baechle break;
223315806cbSRalf Baechle
224315806cbSRalf Baechle case MIPS_REVISION_SCON_SOCIT:
225315806cbSRalf Baechle case MIPS_REVISION_SCON_ROCIT:
226315806cbSRalf Baechle _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
227315806cbSRalf Baechle mips_pci_controller:
228315806cbSRalf Baechle mb();
229315806cbSRalf Baechle MSC_READ(MSC01_PCI_CFG, data);
230315806cbSRalf Baechle MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
231315806cbSRalf Baechle wmb();
232315806cbSRalf Baechle
233315806cbSRalf Baechle /* Fix up lane swapping. */
234315806cbSRalf Baechle #ifdef CONFIG_CPU_LITTLE_ENDIAN
235315806cbSRalf Baechle MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
236315806cbSRalf Baechle #else
237315806cbSRalf Baechle MSC_WRITE(MSC01_PCI_SWAP,
238315806cbSRalf Baechle MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
239315806cbSRalf Baechle MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
240315806cbSRalf Baechle MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
241315806cbSRalf Baechle #endif
242422dd256SPaul Burton
2432f284eacSLeonid Yegoshin /*
2442f284eacSLeonid Yegoshin * Setup the Malta max (2GB) memory for PCI DMA in host bridge
245422dd256SPaul Burton * in transparent addressing mode.
2462f284eacSLeonid Yegoshin */
247422dd256SPaul Burton mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH;
2482f284eacSLeonid Yegoshin MSC_WRITE(MSC01_PCI_BAR0, mask);
2492f284eacSLeonid Yegoshin MSC_WRITE(MSC01_PCI_HEAD4, mask);
250422dd256SPaul Burton
251422dd256SPaul Burton mask &= MSC01_PCI_BAR0_SIZE_MSK;
2522f284eacSLeonid Yegoshin MSC_WRITE(MSC01_PCI_P2SCMSKL, mask);
2532f284eacSLeonid Yegoshin MSC_WRITE(MSC01_PCI_P2SCMAPL, mask);
254422dd256SPaul Burton
255315806cbSRalf Baechle /* Don't handle target retries indefinitely. */
256315806cbSRalf Baechle if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
257315806cbSRalf Baechle MSC01_PCI_CFG_MAXRTRY_MSK)
258315806cbSRalf Baechle data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
259315806cbSRalf Baechle MSC01_PCI_CFG_MAXRTRY_SHF)) |
260315806cbSRalf Baechle ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
261315806cbSRalf Baechle MSC01_PCI_CFG_MAXRTRY_SHF);
262315806cbSRalf Baechle
263315806cbSRalf Baechle wmb();
264315806cbSRalf Baechle MSC_WRITE(MSC01_PCI_CFG, data);
265315806cbSRalf Baechle mb();
266315806cbSRalf Baechle
267315806cbSRalf Baechle set_io_port_base(MALTA_MSC_PORT_BASE);
268315806cbSRalf Baechle break;
269315806cbSRalf Baechle
270315806cbSRalf Baechle case MIPS_REVISION_SCON_SOCITSC:
271315806cbSRalf Baechle case MIPS_REVISION_SCON_SOCITSCP:
272315806cbSRalf Baechle _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000);
273315806cbSRalf Baechle goto mips_pci_controller;
274315806cbSRalf Baechle
275315806cbSRalf Baechle default:
276315806cbSRalf Baechle /* Unknown system controller */
277315806cbSRalf Baechle while (1); /* We die here... */
278315806cbSRalf Baechle }
279315806cbSRalf Baechle board_nmi_handler_setup = mips_nmi_setup;
280315806cbSRalf Baechle board_ejtag_handler_setup = mips_ejtag_setup;
281315806cbSRalf Baechle
282b431f09dSSteven J. Hill fw_init_cmdline();
283b431f09dSSteven J. Hill fw_meminit();
284315806cbSRalf Baechle #ifdef CONFIG_SERIAL_8250_CONSOLE
285315806cbSRalf Baechle console_config();
286315806cbSRalf Baechle #endif
287af3a1f6fSRalf Baechle /* Early detection of CMP support */
2887dc2834fSPaul Burton mips_cpc_probe();
289237036deSPaul Burton
290e56b6aa6SPaul Burton if (!register_cps_smp_ops())
291e56b6aa6SPaul Burton return;
292852fe310SRalf Baechle if (!register_vsmp_smp_ops())
293852fe310SRalf Baechle return;
294ecafe3e9SPaul Burton register_up_smp_ops();
295315806cbSRalf Baechle }
296