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