xref: /netbsd-src/sys/arch/mvmeppc/mvmeppc/platform_160x.c (revision 43ebc391218a8a54db978a34f9dbfcdfe7a478cb)
1 /*	$NetBSD: platform_160x.c,v 1.9 2014/03/26 17:44:36 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Steve C. Woodford.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: platform_160x.c,v 1.9 2014/03/26 17:44:36 christos Exp $");
34 
35 #include <sys/param.h>
36 #include <sys/device.h>
37 #include <sys/kernel.h>
38 #include <sys/systm.h>
39 
40 #include <machine/cpu.h>
41 #include <machine/bootinfo.h>
42 #include <machine/pio.h>
43 #include <machine/platform.h>
44 #include <arch/powerpc/pic/picvar.h>
45 
46 static int	p160x_match(struct platform *);
47 static void	p160x_pci_intr_fixup(int, int, int *);
48 static void	p160x_cpu_setup(device_t);
49 static void	p160x_reset(void);
50 static void	p160x_pic_setup(void);
51 
52 struct platform	platform_160x = {
53 	NULL,
54 	p160x_pic_setup,
55 	p160x_match,
56 	p160x_pci_intr_fixup,
57 	p160x_cpu_setup,
58 	p160x_reset
59 };
60 
61 struct ppcbug_brdid {
62 	char	version[4];
63 	char	serial[12];
64 	char	id[16];
65 	char	pwa[16];
66 	char	reserved_0[4];
67 	char	ethernet_adr[6];
68 	char	reserved_1[2];
69 	char	lscsiid[2];
70 	char	speed_mpu[3];
71 	char	speed_bus[3];
72 	char	reserved[187];
73 	char	cksum[1];
74 };
75 #define	NVRAM_BRDID_OFF		0x1ef8
76 
77 static void	p160x_get_brdid(struct ppcbug_brdid *);
78 
79 static char	p160x_model[64];
80 
81 static u_int32_t p160x_dram_size[] = {
82 	0x08000000, 0x02000000, 0x00800000, 0x00000000,
83 	0x10000000, 0x04000000, 0x01000000, 0x00000000
84 };
85 
86 extern struct pic_ops *isa_pic;
87 
88 static int
p160x_match(struct platform * p)89 p160x_match(struct platform *p)
90 {
91 	struct ppcbug_brdid bid;
92 	char speed[4], *cp;
93 	u_int8_t dsr;
94 
95 	if (MVMEPPC_FAMILY(bootinfo.bi_modelnumber) != MVMEPPC_FAMILY_160x)
96 		return(0);
97 
98 	p160x_get_brdid(&bid);
99 
100 	for (cp = &bid.id[sizeof(bid.id) - 1]; *cp == ' '; cp--)
101 		*cp = '\0';
102 	for (cp = &bid.serial[sizeof(bid.serial) - 1]; *cp == ' '; cp--)
103 		*cp = '\0';
104 	for (cp = &bid.pwa[sizeof(bid.pwa) - 1]; *cp == ' '; cp--)
105 		*cp = '\0';
106 
107 	snprintf(p160x_model, sizeof(p160x_model),
108 	    "%s, Serial: %s, PWA: %s", bid.id, bid.serial, bid.pwa);
109 	p->model = p160x_model;
110 
111 	speed[3] = '\0';
112 	strncpy(speed, bid.speed_mpu, sizeof(bid.speed_mpu));
113 	bootinfo.bi_mpuspeed = strtoul(speed, NULL, 10) * 1000000;
114 	strncpy(speed, bid.speed_bus, sizeof(bid.speed_bus));
115 	bootinfo.bi_busspeed = strtoul(speed, NULL, 10) * 1000000;
116 	bootinfo.bi_clocktps = bootinfo.bi_busspeed / 4;
117 
118 	/* Fetch the DRAM size register */
119 	dsr = inb(0x80000804);
120 	bootinfo.bi_memsize = p160x_dram_size[dsr & 0x7];
121 	bootinfo.bi_memsize += p160x_dram_size[(dsr >> 4) & 0x7];
122 
123 	return(1);
124 }
125 
126 static void
p160x_pci_intr_fixup(int bus,int dev,int * line)127 p160x_pci_intr_fixup(int bus, int dev, int *line)
128 {
129 
130 	aprint_verbose("p160x_pci_intr_fixup: bus=%d, dev=%d, line=%d\n",
131 	    bus, dev, *line);
132 }
133 
134 static void
p160x_cpu_setup(device_t dev)135 p160x_cpu_setup(device_t dev)
136 {
137 }
138 
139 static void
p160x_pic_setup(void)140 p160x_pic_setup(void)
141 {
142 	pic_init();
143 	/* I really wonder if this shouldn't be prepivr instead */
144 	isa_pic = setup_i8259();
145 	oea_install_extint(pic_ext_intr);
146 }
147 
148 
149 static void
p160x_reset(void)150 p160x_reset(void)
151 {
152 	/*
153 	 * The mvme160x programmer's manual makes reference to an
154 	 * "IBC Port 92" register which can be used to reset the board.
155 	 * Unfortunately, I can't find any documentation for this
156 	 * register.
157 	 * Fortunately, it appears that simply setting bit-0 does
158 	 * the trick...
159 	 */
160 	outb(0x80000092, inb(0x80000092) | 1);
161 }
162 
163 static void
p160x_get_brdid(struct ppcbug_brdid * bid)164 p160x_get_brdid(struct ppcbug_brdid *bid)
165 {
166 	u_int8_t *pbid = (u_int8_t *)bid;
167 	int off;
168 	int i;
169 
170 	for (i = 0, off = NVRAM_BRDID_OFF; i < sizeof(*bid); i++, off++) {
171 		outb(0x80000074, off & 0xff);
172 		outb(0x80000075, (off >> 8) & 0xff);
173 		pbid[i] = inb(0x80000077);
174 	}
175 }
176