tsc.c revision 1.14 1 /* $NetBSD: tsc.c,v 1.14 2009/03/14 14:45:53 dsl Exp $ */
2
3 /*-
4 * Copyright (c) 1999 by Ross Harvey. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Ross Harvey.
17 * 4. The name of Ross Harvey may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY ROSS HARVEY ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP0SE
23 * ARE DISCLAIMED. IN NO EVENT SHALL ROSS HARVEY BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34 #include "opt_dec_6600.h"
35
36 #include <sys/cdefs.h>
37
38 __KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.14 2009/03/14 14:45:53 dsl Exp $");
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/malloc.h>
44
45 #include <machine/autoconf.h>
46 #include <machine/rpb.h>
47 #include <machine/sysarch.h>
48
49 #include <dev/isa/isareg.h>
50 #include <dev/isa/isavar.h>
51 #include <dev/pci/pcireg.h>
52 #include <dev/pci/pcivar.h>
53 #include <alpha/pci/tsreg.h>
54 #include <alpha/pci/tsvar.h>
55
56 #ifdef DEC_6600
57 #include <alpha/pci/pci_6600.h>
58 #endif
59
60 #define tsc() { Generate ctags(1) key. }
61
62 int tscmatch(struct device *, struct cfdata *, void *);
63 void tscattach(struct device *, struct device *, void *);
64
65 CFATTACH_DECL(tsc, sizeof(struct tsc_softc),
66 tscmatch, tscattach, NULL, NULL);
67
68 extern struct cfdriver tsc_cd;
69
70 struct tsp_config tsp_configuration[2];
71
72 static int tscprint(void *, const char *pnp);
73
74 int tspmatch(struct device *, struct cfdata *, void *);
75 void tspattach(struct device *, struct device *, void *);
76
77 CFATTACH_DECL(tsp, sizeof(struct tsp_softc),
78 tspmatch, tspattach, NULL, NULL);
79
80 extern struct cfdriver tsp_cd;
81
82 static int tsp_bus_get_window(int, int,
83 struct alpha_bus_space_translation *);
84
85 /* There can be only one */
86 static int tscfound;
87
88 /* Which hose is the display console connected to? */
89 int tsp_console_hose;
90
91 int
92 tscmatch(parent, match, aux)
93 struct device *parent;
94 struct cfdata *match;
95 void *aux;
96 {
97 struct mainbus_attach_args *ma = aux;
98
99 return cputype == ST_DEC_6600
100 && strcmp(ma->ma_name, tsc_cd.cd_name) == 0
101 && !tscfound;
102 }
103
104 void tscattach(parent, self, aux)
105 struct device *parent, *self;
106 void *aux;
107 {
108 int i;
109 int nbus;
110 u_int64_t csc, aar;
111 struct tsp_attach_args tsp;
112 struct mainbus_attach_args *ma = aux;
113
114 tscfound = 1;
115
116 csc = LDQP(TS_C_CSC);
117
118 nbus = 1 + (CSC_BC(csc) >= 2);
119 printf(": 21272 Core Logic Chipset, Cchip rev %d\n"
120 "%s%d: %c Dchips, %d memory bus%s of %d bytes\n",
121 (int)MISC_REV(LDQP(TS_C_MISC)),
122 ma->ma_name, ma->ma_slot, "2448"[CSC_BC(csc)],
123 nbus, nbus > 1 ? "es" : "", 16 + 16 * ((csc & CSC_AW) != 0));
124 printf("%s%d: arrays present: ", ma->ma_name, ma->ma_slot);
125 for(i = 0; i < 4; ++i) {
126 aar = LDQP(TS_C_AAR0 + i * TS_STEP);
127 printf("%s%dMB%s", i ? ", " : "", (8 << AAR_ASIZ(aar)) & ~0xf,
128 aar & AAR_SPLIT ? " (split)" : "");
129 }
130 printf(", Dchip 0 rev %d\n", (int)LDQP(TS_D_DREV) & 0xf);
131
132 memset(&tsp, 0, sizeof tsp);
133 tsp.tsp_name = "tsp";
134 config_found(self, &tsp, NULL);
135
136 if(LDQP(TS_C_CSC) & CSC_P1P) {
137 ++tsp.tsp_slot;
138 config_found(self, &tsp, tscprint);
139 }
140 }
141
142 static int
143 tscprint(aux, p)
144 void *aux;
145 const char *p;
146 {
147 register struct tsp_attach_args *tsp = aux;
148
149 if(p)
150 aprint_normal("%s%d at %s", tsp->tsp_name, tsp->tsp_slot, p);
151 return UNCONF;
152 }
153
154 #define tsp() { Generate ctags(1) key. }
155
156 int
157 tspmatch(parent, match, aux)
158 struct device *parent;
159 struct cfdata *match;
160 void *aux;
161 {
162 struct tsp_attach_args *t = aux;
163
164 return cputype == ST_DEC_6600
165 && strcmp(t->tsp_name, tsp_cd.cd_name) == 0;
166 }
167
168 void
169 tspattach(parent, self, aux)
170 struct device *parent, *self;
171 void *aux;
172 {
173 struct pcibus_attach_args pba;
174 struct tsp_attach_args *t = aux;
175 struct tsp_config *pcp;
176
177 printf("\n");
178 pcp = tsp_init(1, t->tsp_slot);
179
180 tsp_dma_init(pcp);
181
182 /*
183 * Do PCI memory initialization that needs to be deferred until
184 * malloc is safe. On the Tsunami, we need to do this after
185 * DMA is initialized, as well.
186 */
187 tsp_bus_mem_init2(&pcp->pc_memt, pcp);
188
189 pci_6600_pickintr(pcp);
190
191 pba.pba_iot = &pcp->pc_iot;
192 pba.pba_memt = &pcp->pc_memt;
193 pba.pba_dmat =
194 alphabus_dma_get_tag(&pcp->pc_dmat_direct, ALPHA_BUS_PCI);
195 pba.pba_dmat64 = NULL;
196 pba.pba_pc = &pcp->pc_pc;
197 pba.pba_bus = 0;
198 pba.pba_bridgetag = NULL;
199 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
200 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
201 config_found_ia(self, "pcibus", &pba, pcibusprint);
202 }
203
204 struct tsp_config *
205 tsp_init(mallocsafe, n)
206 int mallocsafe;
207 int n; /* Pchip number */
208 {
209 struct tsp_config *pcp;
210
211 KASSERT((n | 1) == 1);
212 pcp = &tsp_configuration[n];
213 pcp->pc_pslot = n;
214 pcp->pc_iobase = TS_Pn(n, 0);
215 pcp->pc_csr = S_PAGE(TS_Pn(n, P_CSRBASE));
216 if (!pcp->pc_initted) {
217 tsp_bus_io_init(&pcp->pc_iot, pcp);
218 tsp_bus_mem_init(&pcp->pc_memt, pcp);
219
220 alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_IO] = 1;
221 alpha_bus_window_count[ALPHA_BUS_TYPE_PCI_MEM] = 1;
222
223 alpha_bus_get_window = tsp_bus_get_window;
224 }
225 pcp->pc_mallocsafe = mallocsafe;
226 tsp_pci_init(&pcp->pc_pc, pcp);
227 pcp->pc_initted = 1;
228 return pcp;
229 }
230
231 static int
232 tsp_bus_get_window(type, window, abst)
233 int type, window;
234 struct alpha_bus_space_translation *abst;
235 {
236 struct tsp_config *tsp = &tsp_configuration[tsp_console_hose];
237 bus_space_tag_t st;
238 int error;
239
240 switch (type) {
241 case ALPHA_BUS_TYPE_PCI_IO:
242 st = &tsp->pc_iot;
243 break;
244
245 case ALPHA_BUS_TYPE_PCI_MEM:
246 st = &tsp->pc_memt;
247 break;
248
249 default:
250 panic("tsp_bus_get_window");
251 }
252
253 error = alpha_bus_space_get_window(st, window, abst);
254 if (error)
255 return (error);
256
257 abst->abst_sys_start = TS_PHYSADDR(abst->abst_sys_start);
258 abst->abst_sys_end = TS_PHYSADDR(abst->abst_sys_end);
259
260 return (0);
261 }
262