Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: piu.h | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
46 | * Use is subject to license terms. | |
47 | */ | |
48 | ||
49 | #ifndef _NIAGARA_PIU_H | |
50 | #define _NIAGARA_PIU_H | |
51 | ||
52 | #pragma ident "@(#)piu.h 1.6 07/08/16 SMI" | |
53 | ||
54 | ||
55 | #ifdef __cplusplus | |
56 | extern "C" { | |
57 | #endif | |
58 | ||
59 | #include <support.h> | |
60 | #include <vpiu_errs_defs.h> | |
61 | #include <piu/piu_regs.h> | |
62 | #include <piu/piu.h> | |
63 | #include <sun4v/vpci.h> | |
64 | ||
65 | #define NPIUS 1 | |
66 | ||
67 | #define AID2JBUS(aid) (0x080ull << 32) | |
68 | #define AID2HANDLE(aid) ((uint64_t)(PIU_AID) << DEVCFGPA_SHIFT) | |
69 | ||
70 | #define AID2PCI(aid) ((uint64_t)(0x0c0ull << 32)) | |
71 | ||
72 | #define AID2VINO(aid) (PIU_AID << PIU_DEVINO_SHIFT) | |
73 | #define AID2PCIE(aid) ((uint64_t)(AID2JBUS(aid)|0x600000LL|(0x8ull << 32))) | |
74 | ||
75 | #define AID2MMU(aid) ((uint64_t)(AID2PCIE(aid) | PIU_DLC_MMU_CTL)) | |
76 | #define AID2INTMAP(aid) (AID2PCIE(aid) | PIU_DLC_IMU_ISS_INTERRUPT_MAPPING(0)) | |
77 | #define AID2INTCLR(aid) (AID2PCIE(aid) | PIU_DLC_IMU_ISS_CLR_INT_REG(0)) | |
78 | #define AID2MMUFLUSH(aid) ((uint64_t)(AID2JBUS(aid) |\ | |
79 | NCU_MMU_TTE_CACHE_FLUSH_ADDR_OFFSET)) | |
80 | ||
81 | #define CFGIO(n) (0xc800 << 24) | |
82 | #define MEM32(n) (0xca00 << 24) | |
83 | #define MEM64(n) (0xcc00 << 24) | |
84 | ||
85 | #define AID2PCIECFG(aid) (AID2PCI(aid) | 1ull << 35) | |
86 | ||
87 | #define IO_SIZE (256 MB) | |
88 | #define CFG_SIZE IO_SIZE | |
89 | #define CFGIO_SIZE (CFG_SIZE + IO_SIZE) | |
90 | #define MEM32_SIZE (2 GB) | |
91 | #define MEM64_SIZE (16 GB) | |
92 | ||
93 | /* BEGIN CSTYLED */ | |
94 | /* | |
95 | * PIU LEAF 0 | |
96 | * c0.0000.0000 | |
97 | *#=========================# 0.0000.0000 | |
98 | *| | | |
99 | *| | 0.1000.0000 | |
100 | *| | | |
101 | *| | 0.2000.0000 | |
102 | *| | | |
103 | *| UNUSED 16 GB | 2.0000.0000 | |
104 | *| | | |
105 | *| | 2.8000.0000 | |
106 | *| | | |
107 | *| | 3.0000.0000 | |
108 | *| | | |
109 | *#-------------------------# 4.0000.0000 | |
110 | *| UNUSED 16 GB | | |
111 | *#-------------------------# 8.0000.0000 | |
112 | *| CFG 256 MB | | |
113 | *+-------------------------+ 8.1000.0000 | |
114 | *| IO 256 MB | | |
115 | *+-------------------------+ 8.2000.0000 | |
116 | *| | | |
117 | *| UNUSED 8 GB - 512 MB | 8.2800.0000 | |
118 | *| | | |
119 | *+-------------------------+ a.0000.0000 | |
120 | *| MEM32 2 GB | | |
121 | *+-------------------------+ a.8000.0000 | |
122 | *| DVMA 2 GB | | |
123 | *+-------------------------+ b.0000.0000 | |
124 | *| UNUSED 4 GB | | |
125 | *#-------------------------# c.0000.0000 | |
126 | *| | | |
127 | *| MEM64 16 GB | f.0000.0000 | |
128 | *| | | |
129 | *#=========================# f.ffff.ffff | |
130 | */ | |
131 | /* END CSTYLED */ | |
132 | ||
133 | #define PIU_IOBASE(n) (CFGIO(n) + CFG_SIZE) | |
134 | #define PIU_IOLIMIT(n) (MEM64(n) + MEM64_SIZE) | |
135 | ||
136 | #define PIU_BAR(n) ((n) & 0x8000000fff000000) | |
137 | #define PIU_BAR_V(n) (PIU_BAR(n) | (1LL << 63)) | |
138 | #define PIU_SIZE(n) (((1 << 40) - 1) ^ ((n) - 1)) | |
139 | ||
140 | #define AID2PCIEIO(aid) (AID2PCIECFG(aid) | CFG_SIZE) | |
141 | ||
142 | #define PIU_PERF_REGS(n) 0x0fff | |
143 | ||
144 | #define RUC_P (1 << 16) | |
145 | #define WUC_P (1 << 17) | |
146 | #define LUP_P (1 << 8) | |
147 | #define LDN_P (1 << 9) | |
148 | ||
149 | #define RWUC_P (RUC_P | WUC_P) | |
150 | #define RWUC_S (RWUC_P << 32) | |
151 | ||
152 | #define LUP_LDN_P (LUP_P | LDN_P) | |
153 | #define LUP_LDN_S (LUP_LDN_P << 32) | |
154 | ||
155 | /* | |
156 | * These IO config space offsets are expected to remain fixed and so | |
157 | * we just hard code them. These are used for PCI bus reset of a logical | |
158 | * domain which is being reset (and controls one or more of the IO leafs). | |
159 | */ | |
160 | #define UPST_CFG_BASE 0x200000 /* upstream port cfg base */ | |
161 | ||
162 | #define DNST_CFG_PORT_BASE(_x) (0x300000 + ((_x)<<15)) | |
163 | #define DNST_CFG_BASE 0x308000 /* downstream port 1 cfg base */ | |
164 | ||
165 | #define PE2X_CFG_BASE 0x400000 /* PCIE->PCIX bridge cfg base */ | |
166 | #define SOUTHBRIDGE_CFG_BASE 0x510000 | |
167 | #define CFG_SECONDARY_RESET 0x3c /* used for secondary reset */ | |
168 | #define CFG_CMD_REG 0x4 /* command register */ | |
169 | #define CFG_CLASS_CODE 0x8 /* class code */ | |
170 | #define CFG_BAR0 0x10 /* BAR0 */ | |
171 | #define CFG_BAR1 0x14 /* BAR1 */ | |
172 | #define CFG_PS_BUS 0x18 /* primary/secondary bus#s */ | |
173 | #define CFG_IOBASE_LIM 0x1c /* I/O base and Limit */ | |
174 | #define CFG_MEMBASE 0x20 /* memory base */ | |
175 | #define CFG_MEMLIM 0x22 /* memory limit */ | |
176 | #define CFG_PFBASE 0x24 /* prefetchable base */ | |
177 | #define CFG_PFLIM 0x26 /* prefetchable limit */ | |
178 | #define CFG_PF_UBASE 0x28 /* prefetchable upper base */ | |
179 | #define CFG_PF_ULIM 0x2c /* prefetchable upper limit */ | |
180 | #define CFG_IO_UBASE 0x30 /* IO upper base */ | |
181 | #define CFG_IO_ULIM 0x32 /* IO upper limit */ | |
182 | ||
183 | #define CFG_STAT_CTRL 0x70 /* device status and control */ | |
184 | #define CFG_LINK_TRAIN 0x78 /* link training status */ | |
185 | #define CFG_LINK_TRAIN_MASK (1LL<<27) /* link training status */ | |
186 | #define CFG_LINK_TRAIN_ERR_MASK (1LL<<26) /* link training status */ | |
187 | #define CFG_VC0_STATUS 0x160 /* Virtual channel 0 status */ | |
188 | #define CFG_VC0_STATUS_MASK (1LL<<17) /* link train up */ | |
189 | ||
190 | #define UPST_CFG_PS_BUS_VAL 0x60302 | |
191 | #define DNST_CFG_PS_BUS_VAL 0x60403 | |
192 | #define PE2X_CFG_PS_BUS_VAL 0x60504 | |
193 | #define SOUTHBRIDGE_RESET_VAL 0xfe | |
194 | #define SOUTHBRIDGE_CFG_RESET 0x44 /* Southbridge reset (cfg) */ | |
195 | #define SOUTHBRIDGE_IO_RESET 0x64 /* Southbridge reset (io) */ | |
196 | ||
197 | #define PLX_8532_DEV_VEND_ID 0x853210b5 | |
198 | #define INTEL_BRG_DEV_VEND_ID 0x3408086 | |
199 | #define ALI_SB_DEV_VEND_ID 0x153310b9 | |
200 | #define BRIDGE_CLASS_CODE 0x60400 | |
201 | ||
202 | /* | |
203 | * PIU Link Status Register values | |
204 | */ | |
205 | #define PIU_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_WIDTH_MASK 0x3f | |
206 | #define PIU_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_WIDTH_SHIFT 4 | |
207 | #define PIU_PLC_TLU_CTB_TLR_CSR_A_LNK_STS_WIDTH_x8 0x8 | |
208 | ||
209 | /* | |
210 | * Disable reporting of PIU R/W Unsuccessful Completion (UC) errors | |
211 | * during PCI config space accesses, PCI peek and PCI poke | |
212 | */ | |
213 | /* BEGIN CSTYLED */ | |
214 | #define DISABLE_PCIE_RWUC_ERRORS(piu, scr1, scr2, scr3) \ | |
215 | DISABLE_PCIE_OE_ERR_INTERRUPTS(piu, scr1, scr2, scr3, \ | |
216 | (RWUC_P | RWUC_S)) | |
217 | ||
218 | /* | |
219 | * After PCI config space acesses, PCI peek and PCI poke | |
220 | * are completed, clear any new R/W Unsuccessful Completion (UC) | |
221 | * errors and then reenable reporting of these errors. | |
222 | */ | |
223 | #define ENABLE_PCIE_RWUC_ERRORS(piu, scr1, scr2, scr3) \ | |
224 | ENABLE_PCIE_OE_ERR_INTERRUPTS(piu, scr1, scr2, scr3, \ | |
225 | (RWUC_P | RWUC_S)) | |
226 | ||
227 | /* | |
228 | * For link training or retraining, disable generation of | |
229 | * Link Up or Down events. | |
230 | */ | |
231 | #define DISABLE_PCIE_LUP_LDN_ERRORS(piu, scr1, scr2, scr3) \ | |
232 | DISABLE_PCIE_OE_ERR_INTERRUPTS(piu, scr1, scr2, scr3, \ | |
233 | (LUP_LDN_P | LUP_LDN_S)) | |
234 | ||
235 | #define ENABLE_PCIE_LUP_LDN_ERRORS(piu, scr1, scr2, scr3) \ | |
236 | ENABLE_PCIE_OE_ERR_INTERRUPTS(piu, scr1, scr2, scr3, \ | |
237 | (LUP_LDN_P | LUP_LDN_S)) | |
238 | ||
239 | ||
240 | #define DISABLE_PCIE_OE_ERR_INTERRUPTS(piu, scr1, scr2, scr3, \ | |
241 | registers_bits) \ | |
242 | .pushlocals ;\ | |
243 | add piu, PIU_COOKIE_ERR_LOCK, scr3 ;\ | |
244 | SPINLOCK_ENTER(scr3, scr1, scr2) ;\ | |
245 | ldx [piu + PIU_COOKIE_ERR_LOCK_COUNTER], scr1 ;\ | |
246 | add scr1, 1, scr2 ;\ | |
247 | stx scr2, [piu + PIU_COOKIE_ERR_LOCK_COUNTER] ;\ | |
248 | brgz,pn scr1, 0f ;\ | |
249 | ldx [piu + PIU_COOKIE_PCIE], scr1 ;\ | |
250 | set PIU_PLC_TLU_CTB_TLR_OE_EN_ERR, scr2 ;\ | |
251 | ldx [scr1 + scr2], scr2 ;\ | |
252 | stx scr2, [piu + PIU_COOKIE_OE_STATUS] ;\ | |
253 | setx registers_bits, scr2, scr3 ;\ | |
254 | set PIU_PLC_TLU_CTB_TLR_OE_INT_EN, scr2 ;\ | |
255 | ldx [scr1 + scr2], scr2 ;\ | |
256 | andn scr2, scr3, scr3 ;\ | |
257 | set PIU_PLC_TLU_CTB_TLR_OE_INT_EN, scr2 ;\ | |
258 | stx scr3, [scr1 + scr2] ;\ | |
259 | ldx [scr1 + scr2], %g0 ;\ | |
260 | 0: add piu, PIU_COOKIE_ERR_LOCK, scr3 ;\ | |
261 | SPINLOCK_EXIT(scr3) ;\ | |
262 | .poplocals | |
263 | ||
264 | #define ENABLE_PCIE_OE_ERR_INTERRUPTS(piu, scr1, scr2, scr3, \ | |
265 | registers_bits) \ | |
266 | .pushlocals ;\ | |
267 | add piu, PIU_COOKIE_ERR_LOCK, scr3 ;\ | |
268 | SPINLOCK_ENTER(scr3, scr1, scr2) ;\ | |
269 | ldx [piu + PIU_COOKIE_ERR_LOCK_COUNTER], scr1 ;\ | |
270 | dec scr1 ;\ | |
271 | stx scr1, [piu + PIU_COOKIE_ERR_LOCK_COUNTER] ;\ | |
272 | brgz,pn scr1, 0f ;\ | |
273 | ldx [piu + PIU_COOKIE_PCIE], scr1 ;\ | |
274 | setx registers_bits, scr2, scr3 ;\ | |
275 | ldx [piu + PIU_COOKIE_OE_STATUS], scr2 ;\ | |
276 | andn scr3, scr2, scr3 ;\ | |
277 | set PIU_PLC_TLU_CTB_TLR_OE_ERR_RW1C_ALIAS, scr2 ;\ | |
278 | stx scr3, [scr1 + scr2] ;\ | |
279 | setx (RWUC_P | RWUC_S), scr2, scr3 ;\ | |
280 | set PIU_PLC_TLU_CTB_TLR_OE_INT_EN, scr2 ;\ | |
281 | ldx [scr1 + scr2], scr2 ;\ | |
282 | or scr2, scr3, scr3 ;\ | |
283 | set PIU_PLC_TLU_CTB_TLR_OE_INT_EN, scr2 ;\ | |
284 | stx scr3, [scr1 + scr2] ;\ | |
285 | 0: add piu, PIU_COOKIE_ERR_LOCK, scr3 ;\ | |
286 | SPINLOCK_EXIT(scr3) ;\ | |
287 | .poplocals | |
288 | ||
289 | /* | |
290 | * This macro flushes all IOMMU entries from the PIU | |
291 | * | |
292 | * Inputs: | |
293 | * | |
294 | * piu - (preserved) pointer to PIU_COOKIE | |
295 | * | |
296 | */ | |
297 | #define PIU_IOMMU_FLUSH(piu, scr1, scr2, scr3, scr4) \ | |
298 | .pushlocals ;\ | |
299 | ldx [piu + PIU_COOKIE_IOTSB0], scr1 ;\ | |
300 | setx IOTSB0_INDEX_MASK, scr4, scr3 ;\ | |
301 | /* ;\ | |
302 | * piu - piu cookie pointer ;\ | |
303 | * scr1 = IOTSB offset ;\ | |
304 | * scr3 = #ttes to unmap ;\ | |
305 | */ ;\ | |
306 | ldx [piu + PIU_COOKIE_MMUFLUSH], scr4 ;\ | |
307 | 0: ;\ | |
308 | ldx [scr1], scr2 ;\ | |
309 | /* Clear V bit 0 */ ;\ | |
310 | srlx scr2, PIU_IOTTE_V_SHIFT, scr2 ;\ | |
311 | sllx scr2, PIU_IOTTE_V_SHIFT, scr2 ;\ | |
312 | /* Clear Attributes */ ;\ | |
313 | srlx scr2, IOMMU_PAGESHIFT_8K, scr2 ;\ | |
314 | sllx scr2, IOMMU_PAGESHIFT_8K, scr2 ;\ | |
315 | stx scr2, [scr1] ;\ | |
316 | /* IOMMU Flush */ ;\ | |
317 | stx scr1, [scr4] ;\ | |
318 | add scr1, IOTTE_SIZE, scr1 ;\ | |
319 | sub scr3, 1, scr3 ;\ | |
320 | brgz,pt scr3, 0b ;\ | |
321 | nop ;\ | |
322 | .poplocals | |
323 | ||
324 | ||
325 | /* | |
326 | * This macro brings a given piu leaf's link down | |
327 | * | |
328 | * Inputs: | |
329 | * | |
330 | * piu - (preserved) pointer to PIU_COOKIE | |
331 | * | |
332 | */ | |
333 | #define PIU_LINK_DOWN(piu, scr1, scr2, scr3, scr4) \ | |
334 | .pushlocals ;\ | |
335 | ldx [ piu + PIU_COOKIE_PCIE ], scr1 ;\ | |
336 | /* And now the actual reset code... */ ;\ | |
337 | /* Remain in detect quiesce */ ;\ | |
338 | /* PEU control register */ ;\ | |
339 | set PIU_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR, scr2 ;\ | |
340 | ldx [scr1 + scr2], scr3 ;\ | |
341 | or scr3, (1 << 8), scr3 ;\ | |
342 | stx scr3, [scr1 + scr2] ;\ | |
343 | ;\ | |
344 | /* Disable link - set bit 4 of PEU Link Control register */ ;\ | |
345 | set PIU_PLC_TLU_CTB_TLR_LNK_CTL, scr2 ;\ | |
346 | ldx [scr1 + scr2], scr3 ;\ | |
347 | bset (1 << 4), scr3 ;\ | |
348 | stx scr3, [scr1 + scr2] ;\ | |
349 | ;\ | |
350 | CPU_MSEC_DELAY(50, scr2, scr3, scr4) ;\ | |
351 | ;\ | |
352 | /* Clear Disable link - bit 4 of PEU Link Control register */ ;\ | |
353 | set PIU_PLC_TLU_CTB_TLR_LNK_CTL, scr2 ;\ | |
354 | ldx [scr1 + scr2], scr3 ;\ | |
355 | bclr (1 << 4), scr3 ;\ | |
356 | stx scr3, [scr1 + scr2] ;\ | |
357 | /* Wait for link to go down */ ;\ | |
358 | /* PEU CXPL Core Status ltssm_state.Detect.Quiet e2100 */ ;\ | |
359 | clr scr4 ;\ | |
360 | 1: ;\ | |
361 | cmp scr4, 100 /* 100 * 50 = 5 sec max delay */ ;\ | |
362 | bge,pn %xcc, 1f ;\ | |
363 | ldx [ piu + PIU_COOKIE_PCIE ], scr1 ;\ | |
364 | set PIU_PLC_TLU_CTB_TLR_CSR_A_CORE_STATUS_ADDR, scr2 ;\ | |
365 | ldx [scr1 + scr2 ], scr3 ;\ | |
366 | srlx scr3, 44, scr3 ;\ | |
367 | and scr3, 0x1f, scr3 /* ltssm_state[48:44] */ ;\ | |
368 | brz,pt scr3, 2f /* 0x0 = DETECT.QUIET */ ;\ | |
369 | nop ;\ | |
370 | CPU_MSEC_DELAY(50, scr1, scr2, scr3) ;\ | |
371 | ba 1b ;\ | |
372 | inc scr4 ;\ | |
373 | 1: ;\ | |
374 | /* Link did not go down, abort */ ;\ | |
375 | HVABORT(-1, "piu linkdown failed\r\n") ;\ | |
376 | 2: ;\ | |
377 | .poplocals | |
378 | ||
379 | ||
380 | /* | |
381 | * This macro brings a given piu leaf's link up | |
382 | * | |
383 | * Inputs: | |
384 | * | |
385 | * piu - (preserved) pointer to PIU_COOKIE | |
386 | * | |
387 | */ | |
388 | #define PIU_LINK_UP(piu, scr1, scr2, scr3) \ | |
389 | .pushlocals ;\ | |
390 | /* get the base addr of RC control regs */ ;\ | |
391 | ldx [ piu + PIU_COOKIE_PCIE ], scr1 ;\ | |
392 | /* Clear Other Event Status Register errors */ ;\ | |
393 | set PIU_PLC_TLU_CTB_TLR_OE_ERR_RW1C_ALIAS, scr2 ;\ | |
394 | mov -1, scr3 ;\ | |
395 | stx scr3, [scr1 + scr2] ;\ | |
396 | /* The drain bit is cleared via W1C */ ;\ | |
397 | set PIU_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_ADDR, scr2 ;\ | |
398 | ldx [scr1 + scr2], scr3 ;\ | |
399 | bset (1 << 8), scr3 /* drain bit */ ;\ | |
400 | stx scr3, [scr1 + scr2] ;\ | |
401 | /* bit 8 of the TLU Control Register is */ ;\ | |
402 | /* cleared to initiate link training */ ;\ | |
403 | set PIU_PLC_TLU_CTB_TLR_CSR_A_TLU_CTL_ADDR, scr2 ;\ | |
404 | ldx [scr1 + scr2], scr3 ;\ | |
405 | bclr 1<<8, scr3 ;\ | |
406 | stx scr3, [scr1 + scr2] ;\ | |
407 | .poplocals | |
408 | ||
409 | /* | |
410 | * This macro resets the PIU using the following sequence :- | |
411 | * | |
412 | * 1. Disable the PIU link. | |
413 | * 2. Drive all on-board devices into reset | |
414 | * 3. Short delay, (300ms). | |
415 | * 4. Drive all slots into reset | |
416 | * 5. Short delay, (300ms). | |
417 | * 6. Release all slots from reset | |
418 | * 7. Short delay, (300ms). | |
419 | * 8. Release all on-board devices from reset except PLX devices 0/1 | |
420 | * 9. Short delay, (300ms). | |
421 | * 10. Start PIU linkup with the PLX switch. | |
422 | * 11. Short delay, (300ms). | |
423 | * 12. Release on-board devices PLX devices 0/1 from reset | |
424 | * 13. Short delay, (300ms), as per PLX errata. | |
425 | * | |
426 | * Inputs: | |
427 | * | |
428 | * piu - (preserved) pointer to PIU_COOKIE | |
429 | * bus - (clobbered) 0 | |
430 | * | |
431 | */ | |
432 | #define RESET_PIU_LEAF(piu, bus, scr1, scr2, scr3, scr4) \ | |
433 | .pushlocals ;\ | |
434 | ;\ | |
435 | /* ******************************************** */ ;\ | |
436 | /* If the link is down, we don't do anything */ ;\ | |
437 | /* since it may mean there is no HW on the bus. */ ;\ | |
438 | /* ******************************************** */ ;\ | |
439 | ldx [piu + PIU_COOKIE_PCIE ], scr1 ;\ | |
440 | setx PIU_PLC_TLU_CTB_TLR_CSR_A_TLU_STS_ADDR, scr3, scr2 ;\ | |
441 | ldx [ scr1 + scr2 ], scr3 ;\ | |
442 | and scr3, 0x7, scr3 ;\ | |
443 | cmp scr3, 0x4 ;\ | |
444 | bne,pt %xcc, 0f ;\ | |
445 | nop ;\ | |
446 | ;\ | |
447 | PIU_LINK_DOWN(piu, scr1, scr2, scr3, scr4) ;\ | |
448 | ;\ | |
449 | setx FPGA_DEVICE_ID, scr2, scr1 ;\ | |
450 | lduh [scr1], scr1 ;\ | |
451 | srlx scr1, FPGA_ID_MAJOR_ID_SHIFT, scr1 ;\ | |
452 | and scr1, FPGA_ID_MAJOR_ID_MASK, scr1 ;\ | |
453 | cmp scr1, FPGA_MIN_MAJOR_ID_RESET_SUPPORT ;\ | |
454 | blu,pn %xcc, 4f ;\ | |
455 | .empty ;\ | |
456 | ;\ | |
457 | setx FPGA_PLATFORM_REGS, scr2, scr1 ;\ | |
458 | mov FPGA_LDOM_RESET_CONTROL_MASK, scr3 ;\ | |
459 | /* drive all devices into reset */ ;\ | |
460 | stb scr3, [scr1 + FPGA_LDOM_RESET_CONTROL_OFFSET] ;\ | |
461 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
462 | /* drive all slots into reset */ ;\ | |
463 | ldub [scr1 + FPGA_DEVICE_PRESENT_OFFSET], scr2 ;\ | |
464 | and scr2, FPGA_PCIE_SLOT_RESET_CTRL_MASK, scr2 ;\ | |
465 | stb scr2, [scr1 + FPGA_LDOM_SLOT_RESET_CONTROL_OFFSET] ;\ | |
466 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
467 | /* take all slots out of reset */ ;\ | |
468 | stb %g0, [scr1 + FPGA_LDOM_SLOT_RESET_CONTROL_OFFSET] ;\ | |
469 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
470 | /* take all devices except PLX's out of reset */ ;\ | |
471 | mov FPGA_LDOM_RESET_CONTROL_DEV_1 | FPGA_LDOM_RESET_CONTROL_DEV_0, scr2 ;\ | |
472 | stb scr2, [scr1 + FPGA_LDOM_RESET_CONTROL_OFFSET] ;\ | |
473 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
474 | ;\ | |
475 | /* train PIU link */ ;\ | |
476 | PIU_LINK_UP(piu, scr4, scr2, scr3) ;\ | |
477 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
478 | ;\ | |
479 | /* Bring PLX's out of reset */ ;\ | |
480 | stb %g0, [scr1 + FPGA_LDOM_RESET_CONTROL_OFFSET] ;\ | |
481 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
482 | ba,pt %xcc, 0f ;\ | |
483 | nop ;\ | |
484 | ;\ | |
485 | 4: ;\ | |
486 | PIU_LINK_UP(piu, scr1, scr2, scr3) ;\ | |
487 | CPU_MSEC_DELAY(300, scr2, scr3, scr4) ;\ | |
488 | 0: ;\ | |
489 | .poplocals | |
490 | ||
491 | /* | |
492 | * We check the link width to ensure that the link came up in x8 mode. | |
493 | * If not, we retry. If it fails PIU_RESET_MAX_ATTEMPTS times we blacklist | |
494 | * the device. | |
495 | */ | |
496 | #define PIU_RESET_MAX_ATTEMPTS 3 | |
497 | ||
498 | /* END CSTYLED */ | |
499 | ||
500 | #ifndef _ASM | |
501 | ||
502 | extern void piu_devino2vino(void); | |
503 | extern void piu_mondo_receive(void); | |
504 | extern void piu_intr_getvalid(void); | |
505 | extern void piu_intr_setvalid(void); | |
506 | extern void piu_intr_getstate(void); | |
507 | extern void piu_intr_setstate(void); | |
508 | extern void piu_intr_gettarget(void); | |
509 | extern void piu_intr_settarget(void); | |
510 | extern void piu_get_perf_reg(void); | |
511 | extern void piu_set_perf_reg(void); | |
512 | ||
513 | extern void piu_err_devino2vino(void); | |
514 | extern void piu_err_mondo_receive(void); | |
515 | extern void piu_err_intr_getvalid(void); | |
516 | extern void piu_err_intr_setvalid(void); | |
517 | extern void piu_err_intr_getstate(void); | |
518 | extern void piu_err_intr_setstate(void); | |
519 | extern void piu_err_intr_gettarget(void); | |
520 | extern void piu_err_intr_settarget(void); | |
521 | ||
522 | extern void piu_msi_devino2vino(void); | |
523 | extern void piu_msi_mondo_receive(void); | |
524 | extern void piu_msi_intr_getvalid(void); | |
525 | extern void piu_msi_intr_setvalid(void); | |
526 | extern void piu_msi_intr_getstate(void); | |
527 | extern void piu_msi_intr_setstate(void); | |
528 | extern void piu_msi_intr_gettarget(void); | |
529 | extern void piu_msi_intr_settarget(void); | |
530 | ||
531 | extern void piu_iommu_map(void); | |
532 | extern void piu_iommu_map_v2(void); | |
533 | extern void piu_iommu_getmap(void); | |
534 | extern void piu_iommu_getmap_v2(void); | |
535 | extern void piu_iommu_unmap(void); | |
536 | extern void piu_iommu_getbypass(void); | |
537 | extern void piu_config_get(void); | |
538 | extern void piu_config_put(void); | |
539 | extern void piu_dma_sync(void); | |
540 | extern void piu_io_peek(void); | |
541 | extern void piu_io_poke(void); | |
542 | ||
543 | extern void piu_msiq_conf(void); | |
544 | extern void piu_msiq_info(void); | |
545 | extern void piu_msiq_getvalid(void); | |
546 | extern void piu_msiq_setvalid(void); | |
547 | extern void piu_msiq_getstate(void); | |
548 | extern void piu_msiq_setstate(void); | |
549 | extern void piu_msiq_gethead(void); | |
550 | extern void piu_msiq_sethead(void); | |
551 | extern void piu_msiq_gettail(void); | |
552 | extern void piu_msi_msg_getmsiq(void); | |
553 | extern void piu_msi_msg_setmsiq(void); | |
554 | extern void piu_msi_msg_getvalid(void); | |
555 | extern void piu_msi_msg_setvalid(void); | |
556 | ||
557 | extern void piu_msi_getvalid(void); | |
558 | extern void piu_msi_setvalid(void); | |
559 | extern void piu_msi_getstate(void); | |
560 | extern void piu_msi_setstate(void); | |
561 | extern void piu_msi_getmsiq(void); | |
562 | extern void piu_msi_setmsiq(void); | |
563 | ||
564 | extern void init_pcie_buses(void); | |
565 | ||
566 | ||
567 | struct piu_msieq { | |
568 | uint64_t eqmask; | |
569 | uint64_t *base; | |
570 | uint64_t *guest; | |
571 | uint64_t word0; | |
572 | uint64_t word1; | |
573 | }; | |
574 | ||
575 | struct piu_msi_cookie { | |
576 | const struct piu_cookie *piu; | |
577 | #ifdef CONFIG_PIU | |
578 | struct piu_msieq eq[PIU_NEQS]; | |
579 | #else | |
580 | struct piu_msieq eq[1]; | |
581 | #endif | |
582 | }; | |
583 | ||
584 | struct piu_err_cookie { | |
585 | const struct piu_cookie *piu; | |
586 | uint64_t state[2]; /* XXX */ | |
587 | }; | |
588 | ||
589 | struct piu_cookie { | |
590 | uint64_t handle; | |
591 | uint64_t ncu; /* NCU Base PA */ | |
592 | uint64_t pcie; | |
593 | uint64_t cfg; /* PCI CFG PA */ | |
594 | ||
595 | bool_t needs_warm_reset; /* false if fresh from poweron */ | |
596 | uint64_t live_port; /* Bit mask for live PLX ports */ | |
597 | ||
598 | uint64_t perfregs; | |
599 | ||
600 | uint64_t eqctlset; | |
601 | uint64_t eqctlclr; | |
602 | uint64_t eqstate; | |
603 | uint64_t eqtail; | |
604 | uint64_t eqhead; | |
605 | uint64_t msimap; | |
606 | uint64_t msiclr; | |
607 | uint64_t msgmap; | |
608 | ||
609 | uint64_t mmu; | |
610 | uint64_t mmuflush; | |
611 | ||
612 | uint64_t intclr; | |
613 | uint64_t intmap; | |
614 | uint64_t *virtual_intmap; | |
615 | ||
616 | uint64_t err_lock; | |
617 | uint64_t err_lock_counter; | |
618 | uint64_t tlu_oe_status; | |
619 | ||
620 | uint16_t inomax; /* Max INO */ | |
621 | uint16_t vino; /* First Vino */ | |
622 | uint64_t *iotsb0; /* IOTSB 8k page Base PA */ | |
623 | uint64_t *iotsb1; /* IOTSB 4m page Base PA */ | |
624 | uint64_t *msieqbase; | |
625 | struct piu_msi_cookie *msicookie; | |
626 | struct piu_err_cookie *errcookie; | |
627 | ||
628 | struct pci_erpt dmu_erpt; /* PIU error buffer */ | |
629 | struct pci_erpt peu_erpt; /* PIU error buffer */ | |
630 | bool_t blacklist; | |
631 | }; | |
632 | ||
633 | ||
634 | typedef struct piu_cookie piu_dev_t; | |
635 | ||
636 | extern const piu_dev_t piu_dev[]; | |
637 | ||
638 | extern bool_t is_piu_port_link_up(piu_dev_t *); | |
639 | extern bool_t pci_config_get(piu_dev_t *, uint64_t offset, int size, | |
640 | uint64_t *valp); | |
641 | extern bool_t pci_config_put(piu_dev_t *, uint64_t offset, int size, | |
642 | uint64_t val); | |
643 | extern bool_t pci_io_peek(piu_dev_t *, uint64_t offset, int size, | |
644 | uint64_t *valp); | |
645 | extern bool_t pci_io_poke(piu_dev_t *, uint64_t offset, int size, | |
646 | uint64_t val, uint64_t cfg_offset); | |
647 | ||
648 | extern bool_t piu_link_up(piu_dev_t *); | |
649 | extern bool_t piu_link_down(piu_dev_t *); | |
650 | ||
651 | extern bool_t pcie_bus_reset(int busnum); | |
652 | ||
653 | extern void piu_reset_onboard_devices(void); | |
654 | ||
655 | #endif /* !_ASM */ | |
656 | ||
657 | #ifdef __cplusplus | |
658 | } | |
659 | #endif | |
660 | ||
661 | #endif /* _NIAGARA_PIU_H */ |