1/*
2 * Setup pointers to hardware-dependent routines.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License.  See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
9 * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
10 */
11#include <linux/eisa.h>
12#include <linux/init.h>
13#include <linux/export.h>
14#include <linux/console.h>
15#include <linux/fb.h>
16#include <linux/screen_info.h>
17
18#ifdef CONFIG_FW_ARC
19#include <asm/fw/arc/types.h>
20#include <asm/sgialib.h>
21#endif
22
23#ifdef CONFIG_FW_SNIPROM
24#include <asm/mipsprom.h>
25#endif
26
27#include <asm/bootinfo.h>
28#include <asm/cpu.h>
29#include <asm/io.h>
30#include <asm/reboot.h>
31#include <asm/sni.h>
32
33unsigned int sni_brd_type;
34EXPORT_SYMBOL(sni_brd_type);
35
36extern void sni_machine_restart(char *command);
37extern void sni_machine_power_off(void);
38
39static void __init sni_display_setup(void)
40{
41#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_FW_ARC)
42	struct screen_info *si = &screen_info;
43	DISPLAY_STATUS *di;
44
45	di = ArcGetDisplayStatus(1);
46
47	if (di) {
48		si->orig_x		= di->CursorXPosition;
49		si->orig_y		= di->CursorYPosition;
50		si->orig_video_cols	= di->CursorMaxXPosition;
51		si->orig_video_lines	= di->CursorMaxYPosition;
52		si->orig_video_isVGA	= VIDEO_TYPE_VGAC;
53		si->orig_video_points	= 16;
54	}
55#endif
56}
57
58static void __init sni_console_setup(void)
59{
60#ifndef CONFIG_FW_ARC
61	char *ctype;
62	char *cdev;
63	char *baud;
64	int port;
65	static char options[8] __initdata;
66
67	cdev = prom_getenv("console_dev");
68	if (strncmp(cdev, "tty", 3) == 0) {
69		ctype = prom_getenv("console");
70		switch (*ctype) {
71		default:
72		case 'l':
73			port = 0;
74			baud = prom_getenv("lbaud");
75			break;
76		case 'r':
77			port = 1;
78			baud = prom_getenv("rbaud");
79			break;
80		}
81		if (baud)
82			strcpy(options, baud);
83		if (strncmp(cdev, "tty552", 6) == 0)
84			add_preferred_console("ttyS", port,
85					      baud ? options : NULL);
86		else
87			add_preferred_console("ttySC", port,
88					      baud ? options : NULL);
89	}
90#endif
91}
92
93#ifdef DEBUG
94static void __init sni_idprom_dump(void)
95{
96	int	i;
97
98	pr_debug("SNI IDProm dump:\n");
99	for (i = 0; i < 256; i++) {
100		if (i%16 == 0)
101			pr_debug("%04x ", i);
102
103		printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
104
105		if (i % 16 == 15)
106			printk("\n");
107	}
108}
109#endif
110
111void __init plat_mem_setup(void)
112{
113	int cputype;
114
115	set_io_port_base(SNI_PORT_BASE);
116//	ioport_resource.end = sni_io_resource.end;
117
118	/*
119	 * Setup (E)ISA I/O memory access stuff
120	 */
121#ifdef CONFIG_EISA
122	EISA_bus = 1;
123#endif
124
125	sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
126	cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
127	switch (sni_brd_type) {
128	case SNI_BRD_TOWER_OASIC:
129		switch (cputype) {
130		case SNI_CPU_M8030:
131			system_type = "RM400-330";
132			break;
133		case SNI_CPU_M8031:
134			system_type = "RM400-430";
135			break;
136		case SNI_CPU_M8037:
137			system_type = "RM400-530";
138			break;
139		case SNI_CPU_M8034:
140			system_type = "RM400-730";
141			break;
142		default:
143			system_type = "RM400-xxx";
144			break;
145		}
146		break;
147	case SNI_BRD_MINITOWER:
148		switch (cputype) {
149		case SNI_CPU_M8021:
150		case SNI_CPU_M8043:
151			system_type = "RM400-120";
152			break;
153		case SNI_CPU_M8040:
154			system_type = "RM400-220";
155			break;
156		case SNI_CPU_M8053:
157			system_type = "RM400-225";
158			break;
159		case SNI_CPU_M8050:
160			system_type = "RM400-420";
161			break;
162		default:
163			system_type = "RM400-xxx";
164			break;
165		}
166		break;
167	case SNI_BRD_PCI_TOWER:
168		system_type = "RM400-Cxx";
169		break;
170	case SNI_BRD_RM200:
171		system_type = "RM200-xxx";
172		break;
173	case SNI_BRD_PCI_MTOWER:
174		system_type = "RM300-Cxx";
175		break;
176	case SNI_BRD_PCI_DESKTOP:
177		switch (read_c0_prid() & PRID_IMP_MASK) {
178		case PRID_IMP_R4600:
179		case PRID_IMP_R4700:
180			system_type = "RM200-C20";
181			break;
182		case PRID_IMP_R5000:
183			system_type = "RM200-C40";
184			break;
185		default:
186			system_type = "RM200-Cxx";
187			break;
188		}
189		break;
190	case SNI_BRD_PCI_TOWER_CPLUS:
191		system_type = "RM400-Exx";
192		break;
193	case SNI_BRD_PCI_MTOWER_CPLUS:
194		system_type = "RM300-Exx";
195		break;
196	}
197	pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, system_type);
198
199#ifdef DEBUG
200	sni_idprom_dump();
201#endif
202
203	switch (sni_brd_type) {
204	case SNI_BRD_10:
205	case SNI_BRD_10NEW:
206	case SNI_BRD_TOWER_OASIC:
207	case SNI_BRD_MINITOWER:
208		sni_a20r_init();
209		break;
210
211	case SNI_BRD_PCI_TOWER:
212	case SNI_BRD_PCI_TOWER_CPLUS:
213		sni_pcit_init();
214		break;
215
216	case SNI_BRD_RM200:
217		sni_rm200_init();
218		break;
219
220	case SNI_BRD_PCI_MTOWER:
221	case SNI_BRD_PCI_DESKTOP:
222	case SNI_BRD_PCI_MTOWER_CPLUS:
223		sni_pcimt_init();
224		break;
225	}
226
227	_machine_restart = sni_machine_restart;
228	pm_power_off = sni_machine_power_off;
229
230	sni_display_setup();
231	sni_console_setup();
232}
233
234#ifdef CONFIG_PCI
235
236#include <linux/pci.h>
237#include <video/vga.h>
238#include <video/cirrus.h>
239
240static void quirk_cirrus_ram_size(struct pci_dev *dev)
241{
242	u16 cmd;
243
244	/*
245	 * firmware doesn't set the ram size correct, so we
246	 * need to do it here, otherwise we get screen corruption
247	 * on older Cirrus chips
248	 */
249	pci_read_config_word(dev, PCI_COMMAND, &cmd);
250	if ((cmd & (PCI_COMMAND_IO|PCI_COMMAND_MEMORY))
251		== (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) {
252		vga_wseq(NULL, CL_SEQR6, 0x12); /* unlock all extension registers */
253		vga_wseq(NULL, CL_SEQRF, 0x18);
254	}
255}
256
257DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_8,
258			quirk_cirrus_ram_size);
259DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5436,
260			quirk_cirrus_ram_size);
261DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446,
262			quirk_cirrus_ram_size);
263#endif
264