rmixlvar.h revision 1.1.2.27 1 /* rmixlvar.h,v 1.1.2.26 2012/01/19 08:03:22 matt Exp */
2
3 /*
4 * Copyright 2002 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Simon Burge for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #ifndef _MIPS_RMI_RMIXLVAR_H_
39 #define _MIPS_RMI_RMIXLVAR_H_
40
41 #include <sys/bus.h>
42 #include <sys/extent.h>
43
44 #include <dev/pci/pcivar.h>
45
46 #include <mips/cpu.h>
47 #include <mips/locore.h>
48
49 #include <mips/rmi/rmixl_firmware.h>
50 #include <mips/rmi/rmixlreg.h>
51
52 void rmixl_pcr_init_core(bool);
53
54 static inline int
55 cpu_rmixl_chip_type(const struct pridtab *ct)
56 {
57 return ct->cpu_cidflags & MIPS_CIDFL_RMI_TYPE;
58 }
59
60 static inline bool
61 cpu_rmixl(const struct pridtab *ct)
62 {
63 return ct->cpu_cid == MIPS_PRID_CID_RMI;
64 }
65
66 static inline bool
67 cpu_rmixlr(const struct pridtab *ct)
68 {
69 #ifdef MIPS64_XLR
70 #if (MIPS64_XLS + MIPS64_XLP) == 0
71 return true;
72 #else
73 return cpu_rmixl(ct) && cpu_rmixl_chip_type(ct) == CIDFL_RMI_TYPE_XLR;
74 #endif
75 #else
76 return false;
77 #endif
78 }
79
80 static inline bool
81 cpu_rmixls(const struct pridtab *ct)
82 {
83 #ifdef MIPS64_XLS
84 #if (MIPS64_XLR + MIPS64_XLP) == 0
85 return true;
86 #else
87 return cpu_rmixl(ct) && cpu_rmixl_chip_type(ct) == CIDFL_RMI_TYPE_XLS;
88 #endif
89 #else
90 return false;
91 #endif
92 }
93
94 static inline bool
95 cpu_rmixlp(const struct pridtab *ct)
96 {
97 #ifdef MIPS64_XLP
98 #if (MIPS64_XLR + MIPS64_XLS) == 0
99 return true;
100 #else
101 return cpu_rmixl(ct) && cpu_rmixl_chip_type(ct) == CIDFL_RMI_TYPE_XLP;
102 #endif
103 #else
104 return false;
105 #endif
106 }
107
108 typedef enum {
109 PSB_TYPE_UNKNOWN=0,
110 PSB_TYPE_RMI,
111 PSB_TYPE_DELL,
112 } rmixlfw_psb_type_t;
113
114 static inline const char *
115 rmixlfw_psb_type_name(rmixlfw_psb_type_t type)
116 {
117 switch(type) {
118 case PSB_TYPE_UNKNOWN:
119 return "unknown";
120 case PSB_TYPE_RMI:
121 return "RMI";
122 case PSB_TYPE_DELL:
123 return "DELL";
124 default:
125 return "undefined";
126 }
127 }
128
129 typedef enum {
130 RMIXLP_8XX,
131 RMIXLP_4XX,
132 /* These next 4 need to be in this order */
133 RMIXLP_3XX,
134 RMIXLP_3XXL,
135 RMIXLP_3XXH,
136 RMIXLP_3XXQ,
137 RMIXLP_2XX,
138 RMIXLP_1XX,
139 RMIXLP_ANY, /* must be last */
140 } rmixlp_variant_t;
141
142 #define RMIXLP_8XX_P (RMIXLP_8XX <= rmixl_configuration.rc_xlp_variant \
143 && rmixl_configuration.rc_xlp_variant <= RMIXLP_4XX)
144 #define RMIXLP_3XX_P (RMIXLP_3XX <= rmixl_configuration.rc_xlp_variant \
145 && rmixl_configuration.rc_xlp_variant <= RMIXLP_3XXQ)
146 #define RMIXLP_2XX_P (RMIXLP_2XX <= rmixl_configuration.rc_xlp_variant \
147 && rmixl_configuration.rc_xlp_variant <= RMIXLP_1XX)
148
149 struct rmixl_region {
150 bus_addr_t r_pbase;
151 bus_size_t r_size;
152 };
153
154 struct rmixl_config {
155 struct rmixl_region rc_io;
156 struct rmixl_region rc_flash[RMIXLP_SBC_NFLASH]; /* FLASH_BAR */
157 struct rmixl_region rc_pci_cfg;
158 struct rmixl_region rc_pci_ecfg;
159 struct rmixl_region rc_pci_mem;
160 struct rmixl_region rc_pci_io;
161 struct rmixl_region rc_pci_link_mem[RMIXLP_SBC_NPCIE_MEM];
162 struct rmixl_region rc_pci_link_io[RMIXLP_SBC_NPCIE_IO];
163 struct rmixl_region rc_srio_mem;
164 struct rmixl_region rc_norflash[RMIXLP_NOR_NCS]; /* XLP */
165 struct mips_bus_space rc_obio_eb_memt; /* DEVIO -eb */
166 struct mips_bus_space rc_obio_el_memt; /* DEVIO -el */
167 struct mips_bus_space rc_iobus_memt; /* Peripherals IO Bus */
168 struct mips_bus_space rc_pci_cfg_memt; /* PCI CFG */
169 struct mips_bus_space rc_pci_ecfg_eb_memt; /* PCI ECFG */
170 struct mips_bus_space rc_pci_ecfg_el_memt; /* PCI ECFG */
171 struct mips_bus_space rc_pci_memt; /* PCI MEM */
172 struct mips_bus_space rc_pci_iot; /* PCI IO */
173 struct mips_bus_space rc_srio_memt; /* SRIO MEM */
174 struct mips_bus_dma_tag rc_dma_tag;
175 struct mips_pci_chipset rc_pci_chipset; /* pci_chipset_t */
176 bus_space_handle_t rc_pci_cfg_memh;
177 bus_space_handle_t rc_pci_ecfg_eb_memh;
178 bus_space_handle_t rc_pci_ecfg_el_memh;
179 bus_dma_tag_t rc_dmat64;
180 bus_dma_tag_t rc_dmat32;
181 bus_dma_tag_t rc_dmat29;
182 struct extent * rc_phys_ex; /* Note: MB units */
183 struct extent * rc_obio_eb_ex;
184 struct extent * rc_obio_el_ex;
185 struct extent * rc_iobus_ex;
186 struct extent * rc_pci_mem_ex;
187 struct extent * rc_pci_io_ex;
188 struct extent * rc_srio_mem_ex;
189 uint64_t rc_gpio_available;
190 rmixlfw_info_t rc_psb_info;
191 rmixlfw_psb_type_t rc_psb_type;
192 volatile struct rmixlfw_cpu_wakeup_info *
193 rc_cpu_wakeup_info;
194 const void * rc_cpu_wakeup_end;
195 const char * rc_cpuname;
196 int rc_mallocsafe;
197 rmixlp_variant_t rc_xlp_variant;
198 uint8_t rc_ncores;
199 };
200
201 extern struct rmixl_config rmixl_configuration;
202
203 void rmixl_flash_eb_bus_mem_init(bus_space_tag_t, void *);
204 void rmixl_flash_el_bus_mem_init(bus_space_tag_t, void *);
205 void rmixl_iobus_bus_mem_init(bus_space_tag_t, void *);
206 void rmixl_obio_eb_bus_mem_init(bus_space_tag_t, void *);
207 void rmixl_obio_el_bus_mem_init(bus_space_tag_t, void *);
208 void rmixl_pci_cfg_el_bus_mem_init(bus_space_tag_t, void *);
209 void rmixl_pci_cfg_eb_bus_mem_init(bus_space_tag_t, void *);
210 void rmixl_pci_ecfg_el_bus_mem_init(bus_space_tag_t, void *);
211 void rmixl_pci_ecfg_eb_bus_mem_init(bus_space_tag_t, void *);
212 void rmixl_pci_eb_bus_mem_init(bus_space_tag_t, void *);
213 void rmixl_pci_el_bus_mem_init(bus_space_tag_t, void *);
214 void rmixl_pci_bus_io_init(bus_space_tag_t, void *);
215
216 void rmixlp_pcie_pc_init(void);
217
218 void rmixl_addr_error_init(void);
219 int rmixl_addr_error_check(void);
220
221 uint64_t rmixl_mfcr(u_int);
222 void rmixl_mtcr(uint64_t, u_int);
223
224 void rmixl_eirr_ack(uint64_t, uint64_t, uint64_t);
225
226 void rmixl_fmn_init(void);
227
228 void rmixl_init_early_cons(struct rmixl_config *, bool);
229 void rmixl_mach_xlp_init(struct rmixl_config *);
230 void rmixl_mach_xlsxlr_init(struct rmixl_config *);
231 void rmixl_mach_freq_init(struct rmixl_config *, bool, bool);
232 void rmixl_mach_init_parse_args(int, char **);
233 void rmixl_mach_init_common(struct rmixl_config *, vaddr_t, uint64_t,
234 bool, bool);
235 uint64_t rmixl_physaddr_init(void);
236 uint64_t rmixlfw_init(int64_t);
237
238 /*
239 * rmixl_cache_err_dis:
240 * - disable Cache, Data ECC, Snoop Tag Parity, Tag Parity errors
241 * - clear the cache error log
242 * - return previous value from RMIXL_PCR_L1D_CONFIG0
243 */
244 static inline uint64_t
245 rmixl_cache_err_dis(void)
246 {
247 uint64_t r;
248
249 r = rmixl_mfcr(RMIXL_PCR_L1D_CONFIG0);
250 rmixl_mtcr(RMIXL_PCR_L1D_CONFIG0, r & ~0x2e);
251 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG, 0);
252 return r;
253 }
254
255 /*
256 * rmixl_cache_err_restore:
257 * - clear the cache error log, cache error overflow log,
258 * and cache interrupt registers
259 * - restore previous value to RMIXL_PCR_L1D_CONFIG0
260 */
261 static inline void
262 rmixl_cache_err_restore(uint64_t r)
263 {
264 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG, 0);
265 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_OVF_LO, 0);
266 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_INTERRUPT, 0);
267 rmixl_mtcr(RMIXL_PCR_L1D_CONFIG0, r);
268 }
269
270 static inline uint64_t
271 rmixl_cache_err_check(void)
272 {
273 return rmixl_mfcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG);
274 }
275
276 static inline int
277 rmixl_probe_4(volatile uint32_t *va)
278 {
279 uint32_t tmp;
280 uint32_t r;
281 int err;
282 int s;
283
284 s = splhigh();
285 r = rmixl_cache_err_dis();
286 tmp = *va; /* probe */
287 err = rmixl_cache_err_check();
288 rmixl_cache_err_restore(r);
289 splx(s);
290
291 return (err == 0);
292 }
293
294 static inline uint32_t
295 rmixlp_read_4(uint32_t tag, bus_size_t offset)
296 {
297 #if 0
298 const struct rmixl_config * const rcp = &rmixl_configuration;
299
300 return bus_space_read_4(rcp->rc_pci_ecfg_memt, rcp->rc_pci_ecfg_memh,
301 offset);
302 #else
303 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
304 + tag + offset;
305
306 return be32toh(*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr));
307 #endif
308 }
309
310 static inline uint64_t
311 rmixlp_read_8(uint32_t tag, bus_size_t offset)
312 {
313 #if 0
314 const struct rmixl_config * const rcp = &rmixl_configuration;
315
316 return bus_space_read_8(rcp->rc_pci_ecfg_memt, rcp->rc_pci_ecfg_memh,
317 offset);
318 #else
319 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
320 + tag + offset;
321
322 return be64toh(*(volatile uint64_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr));
323 #endif
324 }
325
326 static inline void
327 rmixlp_write_4(uint32_t tag, bus_size_t offset, uint32_t v)
328 {
329 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
330 + tag + offset;
331
332 *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr) = htobe32(v);
333 __asm __volatile("sync");
334 }
335
336 static inline void
337 rmixlp_write_8(uint32_t tag, bus_size_t offset, uint64_t v)
338 {
339 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
340 + tag + offset;
341
342 *(volatile uint64_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr) = htobe64(v);
343 __asm __volatile("sync");
344 }
345
346 static inline void
347 rmixl_physaddr_add(struct extent *ext, const char *name,
348 struct rmixl_region *rp, bus_addr_t xpbase, bus_size_t xsize)
349 {
350 rp->r_pbase = xpbase;
351 rp->r_size = xsize;
352 u_long base = xpbase >> 20;
353 u_long size = xsize >> 20;
354 if (extent_alloc_region(ext, base, size, EX_NOWAIT) != 0) {
355 panic("%s: %s: extent_alloc_region(%p, %#lx, %#lx, %#x) "
356 "failed", __func__, name, ext, base, size, EX_NOWAIT);
357 }
358 }
359
360 #endif /* _MIPS_RMI_RMIXLVAR_H_ */
361