rmixlvar.h revision 1.1.2.25 1 /* $NetBSD: rmixlvar.h,v 1.1.2.25 2012/01/04 16:17:54 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 return cpu_rmixl(ct) && cpu_rmixl_chip_type(ct) == CIDFL_RMI_TYPE_XLR;
71 #else
72 return false;
73 #endif
74 }
75
76 static inline bool
77 cpu_rmixls(const struct pridtab *ct)
78 {
79 #ifdef MIPS64_XLS
80 return cpu_rmixl(ct) && cpu_rmixl_chip_type(ct) == CIDFL_RMI_TYPE_XLS;
81 #else
82 return false;
83 #endif
84 }
85
86 static inline bool
87 cpu_rmixlp(const struct pridtab *ct)
88 {
89 #ifdef MIPS64_XLP
90 return cpu_rmixl(ct) && cpu_rmixl_chip_type(ct) == CIDFL_RMI_TYPE_XLP;
91 #else
92 return false;
93 #endif
94 }
95
96 typedef enum {
97 PSB_TYPE_UNKNOWN=0,
98 PSB_TYPE_RMI,
99 PSB_TYPE_DELL,
100 } rmixlfw_psb_type_t;
101
102 static inline const char *
103 rmixlfw_psb_type_name(rmixlfw_psb_type_t type)
104 {
105 switch(type) {
106 case PSB_TYPE_UNKNOWN:
107 return "unknown";
108 case PSB_TYPE_RMI:
109 return "RMI";
110 case PSB_TYPE_DELL:
111 return "DELL";
112 default:
113 return "undefined";
114 }
115 }
116
117 typedef enum {
118 RMIXLP_8XX,
119 RMIXLP_4XX,
120 /* These next 4 need to be in this order */
121 RMIXLP_3XX,
122 RMIXLP_3XXL,
123 RMIXLP_3XXH,
124 RMIXLP_3XXQ,
125 RMIXLP_ANY, /* must be last */
126 } rmixlp_variant_t;
127
128 #define RMIXLP_8XX_P (RMIXLP_8XX <= rmixl_configuration.rc_xlp_variant \
129 && rmixl_configuration.rc_xlp_variant <= RMIXLP_4XX)
130 #define RMIXLP_3XX_P (RMIXLP_3XX <= rmixl_configuration.rc_xlp_variant \
131 && rmixl_configuration.rc_xlp_variant <= RMIXLP_3XXQ)
132
133 struct rmixl_region {
134 bus_addr_t r_pbase;
135 bus_size_t r_size;
136 };
137
138 struct rmixl_config {
139 struct rmixl_region rc_io;
140 struct rmixl_region rc_flash[RMIXLP_SBC_NFLASH]; /* FLASH_BAR */
141 struct rmixl_region rc_pci_cfg;
142 struct rmixl_region rc_pci_ecfg;
143 struct rmixl_region rc_pci_mem;
144 struct rmixl_region rc_pci_io;
145 struct rmixl_region rc_pci_link_mem[RMIXLP_SBC_NPCIE_MEM];
146 struct rmixl_region rc_pci_link_io[RMIXLP_SBC_NPCIE_IO];
147 struct rmixl_region rc_srio_mem;
148 struct rmixl_region rc_norflash[RMIXLP_NOR_NCS]; /* XLP */
149 struct mips_bus_space rc_obio_eb_memt; /* DEVIO -eb */
150 struct mips_bus_space rc_obio_el_memt; /* DEVIO -el */
151 struct mips_bus_space rc_iobus_memt; /* Peripherals IO Bus */
152 struct mips_bus_space rc_pci_cfg_memt; /* PCI CFG */
153 struct mips_bus_space rc_pci_ecfg_eb_memt; /* PCI ECFG */
154 struct mips_bus_space rc_pci_ecfg_el_memt; /* PCI ECFG */
155 struct mips_bus_space rc_pci_memt; /* PCI MEM */
156 struct mips_bus_space rc_pci_iot; /* PCI IO */
157 struct mips_bus_space rc_srio_memt; /* SRIO MEM */
158 struct mips_bus_dma_tag rc_dma_tag;
159 struct mips_pci_chipset rc_pci_chipset; /* pci_chipset_t */
160 bus_space_handle_t rc_pci_cfg_memh;
161 bus_space_handle_t rc_pci_ecfg_eb_memh;
162 bus_space_handle_t rc_pci_ecfg_el_memh;
163 bus_dma_tag_t rc_dmat64;
164 bus_dma_tag_t rc_dmat32;
165 bus_dma_tag_t rc_dmat29;
166 struct extent * rc_phys_ex; /* Note: MB units */
167 struct extent * rc_obio_eb_ex;
168 struct extent * rc_obio_el_ex;
169 struct extent * rc_iobus_ex;
170 struct extent * rc_pci_mem_ex;
171 struct extent * rc_pci_io_ex;
172 struct extent * rc_srio_mem_ex;
173 uint64_t rc_gpio_available;
174 rmixlfw_info_t rc_psb_info;
175 rmixlfw_psb_type_t rc_psb_type;
176 volatile struct rmixlfw_cpu_wakeup_info *
177 rc_cpu_wakeup_info;
178 const void * rc_cpu_wakeup_end;
179 const char * rc_cpuname;
180 int rc_mallocsafe;
181 rmixlp_variant_t rc_xlp_variant;
182 uint8_t rc_ncores;
183 };
184
185 extern struct rmixl_config rmixl_configuration;
186
187 void rmixl_flash_eb_bus_mem_init(bus_space_tag_t, void *);
188 void rmixl_flash_el_bus_mem_init(bus_space_tag_t, void *);
189 void rmixl_iobus_bus_mem_init(bus_space_tag_t, void *);
190 void rmixl_obio_eb_bus_mem_init(bus_space_tag_t, void *);
191 void rmixl_obio_el_bus_mem_init(bus_space_tag_t, void *);
192 void rmixl_pci_cfg_el_bus_mem_init(bus_space_tag_t, void *);
193 void rmixl_pci_cfg_eb_bus_mem_init(bus_space_tag_t, void *);
194 void rmixl_pci_ecfg_el_bus_mem_init(bus_space_tag_t, void *);
195 void rmixl_pci_ecfg_eb_bus_mem_init(bus_space_tag_t, void *);
196 void rmixl_pci_eb_bus_mem_init(bus_space_tag_t, void *);
197 void rmixl_pci_el_bus_mem_init(bus_space_tag_t, void *);
198 void rmixl_pci_bus_io_init(bus_space_tag_t, void *);
199
200 void rmixlp_pcie_pc_init(void);
201
202 void rmixl_addr_error_init(void);
203 int rmixl_addr_error_check(void);
204
205 uint64_t rmixl_mfcr(u_int);
206 void rmixl_mtcr(uint64_t, u_int);
207
208 void rmixl_eirr_ack(uint64_t, uint64_t, uint64_t);
209
210 void rmixl_fmn_init(void);
211
212 void rmixl_init_early_cons(struct rmixl_config *, bool);
213 void rmixl_mach_xlp_init(struct rmixl_config *);
214 void rmixl_mach_xlsxlr_init(struct rmixl_config *);
215 void rmixl_mach_freq_init(struct rmixl_config *, bool, bool);
216 void rmixl_mach_init_parse_args(int, char **);
217 void rmixl_mach_init_common(struct rmixl_config *, vaddr_t, uint64_t,
218 bool, bool);
219 uint64_t rmixl_physaddr_init(void);
220 uint64_t rmixlfw_init(int64_t);
221
222 /*
223 * rmixl_cache_err_dis:
224 * - disable Cache, Data ECC, Snoop Tag Parity, Tag Parity errors
225 * - clear the cache error log
226 * - return previous value from RMIXL_PCR_L1D_CONFIG0
227 */
228 static inline uint64_t
229 rmixl_cache_err_dis(void)
230 {
231 uint64_t r;
232
233 r = rmixl_mfcr(RMIXL_PCR_L1D_CONFIG0);
234 rmixl_mtcr(RMIXL_PCR_L1D_CONFIG0, r & ~0x2e);
235 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG, 0);
236 return r;
237 }
238
239 /*
240 * rmixl_cache_err_restore:
241 * - clear the cache error log, cache error overflow log,
242 * and cache interrupt registers
243 * - restore previous value to RMIXL_PCR_L1D_CONFIG0
244 */
245 static inline void
246 rmixl_cache_err_restore(uint64_t r)
247 {
248 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG, 0);
249 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_ERROR_OVF_LO, 0);
250 rmixl_mtcr(RMIXL_PCR_L1D_CACHE_INTERRUPT, 0);
251 rmixl_mtcr(RMIXL_PCR_L1D_CONFIG0, r);
252 }
253
254 static inline uint64_t
255 rmixl_cache_err_check(void)
256 {
257 return rmixl_mfcr(RMIXL_PCR_L1D_CACHE_ERROR_LOG);
258 }
259
260 static inline int
261 rmixl_probe_4(volatile uint32_t *va)
262 {
263 uint32_t tmp;
264 uint32_t r;
265 int err;
266 int s;
267
268 s = splhigh();
269 r = rmixl_cache_err_dis();
270 tmp = *va; /* probe */
271 err = rmixl_cache_err_check();
272 rmixl_cache_err_restore(r);
273 splx(s);
274
275 return (err == 0);
276 }
277
278 static inline uint32_t
279 rmixlp_read_4(uint32_t tag, bus_size_t offset)
280 {
281 #if 0
282 const struct rmixl_config * const rcp = &rmixl_configuration;
283
284 return bus_space_read_4(rcp->rc_pci_ecfg_memt, rcp->rc_pci_ecfg_memh,
285 offset);
286 #else
287 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
288 + tag + offset;
289
290 return be32toh(*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr));
291 #endif
292 }
293
294 static inline uint64_t
295 rmixlp_read_8(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_8(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 be64toh(*(volatile uint64_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr));
307 #endif
308 }
309
310 static inline void
311 rmixlp_write_4(uint32_t tag, bus_size_t offset, uint32_t v)
312 {
313 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
314 + tag + offset;
315
316 *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr) = htobe32(v);
317 __asm __volatile("sync");
318 }
319
320 static inline void
321 rmixlp_write_8(uint32_t tag, bus_size_t offset, uint64_t v)
322 {
323 const paddr_t ecfg_addr = rmixl_configuration.rc_pci_ecfg.r_pbase
324 + tag + offset;
325
326 *(volatile uint64_t *)MIPS_PHYS_TO_KSEG1(ecfg_addr) = htobe64(v);
327 __asm __volatile("sync");
328 }
329
330 static inline void
331 rmixl_physaddr_add(struct extent *ext, const char *name,
332 struct rmixl_region *rp, bus_addr_t xpbase, bus_size_t xsize)
333 {
334 rp->r_pbase = xpbase;
335 rp->r_size = xsize;
336 u_long base = xpbase >> 20;
337 u_long size = xsize >> 20;
338 if (extent_alloc_region(ext, base, size, EX_NOWAIT) != 0) {
339 panic("%s: %s: extent_alloc_region(%p, %#lx, %#lx, %#x) "
340 "failed", __func__, name, ext, base, size, EX_NOWAIT);
341 }
342 }
343
344 #endif /* _MIPS_RMI_RMIXLVAR_H_ */
345