1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef _SYS_PCICMU_H
27#define	_SYS_PCICMU_H
28
29#pragma ident	"%Z%%M%	%I%	%E% SMI"
30
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36#include <sys/pci.h>
37#include <sys/pci_intr_lib.h>
38#include <sys/pcicmu/pcmu_types.h>
39#include <sys/pcicmu/pcmu_ib.h>
40#include <sys/pcicmu/pcmu_cb.h>
41#include <sys/pcicmu/pcmu_ecc.h>
42#include <sys/pcicmu/pcmu_pbm.h>
43#include <sys/pcicmu/pcmu_counters.h>
44#include <sys/pcicmu/pcmu_util.h>
45#include <sys/pcicmu/pcmu_err.h>
46
47
48/*
49 * The following typedef is used to represent a
50 * 1275 "bus-range" property of a PCI Bus node.
51 */
52struct pcmu_bus_range {
53	uint32_t lo;
54	uint32_t hi;
55};
56
57/*
58 * Structure to represent an entry in the
59 * "ranges" property of a device node.
60 */
61struct pcmu_ranges {
62	uint32_t child_high;
63	uint32_t child_mid;
64	uint32_t child_low;
65	uint32_t parent_high;
66	uint32_t parent_low;
67	uint32_t size_high;
68	uint32_t size_low;
69};
70
71typedef enum {
72	PCMU_NEW,
73	PCMU_ATTACHED,
74	PCMU_DETACHED,
75	PCMU_SUSPENDED
76} pcmu_state_t;
77
78typedef enum {
79	PCMU_PBM_OBJ,
80	PCMU_ECC_OBJ,
81	PCMU_CB_OBJ
82} pcmu_obj_t;
83
84typedef enum {
85	PCMU_OBJ_INTR_ADD,
86	PCMU_OBJ_INTR_REMOVE
87} pcmu_obj_op_t;
88
89#define	PCI_OPLCMU	"pcicmu"
90
91/*
92 * pcicmu soft state structure.
93 */
94struct pcicmu {
95	/*
96	 * State flags and mutex:
97	 */
98	pcmu_state_t pcmu_state;
99	uint_t pcmu_soft_state;
100	uint_t pcmu_open_count;
101	kmutex_t pcmu_mutex;
102
103	/*
104	 * Links to other state structures:
105	 */
106	dev_info_t *pcmu_dip;			/* devinfo structure */
107	pcmu_ib_t *pcmu_ib_p;			/* interrupt block */
108	pcmu_cb_t *pcmu_cb_p;			/* control block */
109	pcmu_pbm_t *pcmu_pcbm_p;		/* PBM block */
110	pcmu_ecc_t *pcmu_pecc_p;		/* ECC error block */
111
112	/*
113	 * other state info:
114	 */
115	uint_t pcmu_id;			/* Jupiter device id */
116	uint32_t pcmu_rev;		/* Bus bridge chip identification */
117
118	/*
119	 * pci device node properties:
120	 */
121	pcmu_bus_range_t pcmu_bus_range;	/* "bus-range" */
122	pcmu_ranges_t *pcmu_ranges;	/* "ranges" data & length */
123	int pcmu_ranges_length;
124	uint32_t *pcmu_inos;		/* inos from "interrupts" prop */
125	int pcmu_inos_len;		/* "interrupts" length */
126	int pcmu_numproxy;		/* upa interrupt proxies */
127
128	/*
129	 * register mapping:
130	 */
131	caddr_t pcmu_address[4];
132	ddi_acc_handle_t pcmu_ac[4];
133
134	/*
135	 * Performance counters kstat.
136	 */
137	pcmu_cntr_pa_t	pcmu_uks_pa;
138	kstat_t	*pcmu_uksp;		/* ptr to upstream kstat */
139	kmutex_t pcmu_err_mutex;	/* per chip error handling mutex */
140
141	/* Fault Management support */
142	int pcmu_fm_cap;
143	ddi_iblock_cookie_t pcmu_fm_ibc;
144};
145
146/*
147 * pcmu_soft_state values.
148 */
149#define	PCMU_SOFT_STATE_OPEN		0x01
150#define	PCMU_SOFT_STATE_OPEN_EXCL	0x02
151#define	PCMU_SOFT_STATE_CLOSED		0x04
152
153/*
154 * CMU-CH and PBM soft state macros:
155 */
156#define	PCMU_AP_MINOR_NUM_TO_INSTANCE(x)	((x) >> 8)
157
158#define	get_pcmu_soft_state(i)	\
159	((pcmu_t *)ddi_get_soft_state(per_pcmu_state, (i)))
160
161#define	alloc_pcmu_soft_state(i)	\
162	ddi_soft_state_zalloc(per_pcmu_state, (i))
163
164#define	free_pcmu_soft_state(i)	\
165	ddi_soft_state_free(per_pcmu_state, (i))
166
167#define	DEV_TO_SOFTSTATE(dev)	((pcmu_t *)ddi_get_soft_state(per_pcmu_state, \
168	PCMU_AP_MINOR_NUM_TO_INSTANCE(getminor(dev))))
169
170#define	PCMU_ATTACH_RETCODE(obj, op, err) \
171	((err) ? (obj) << 8 | (op) << 4 | (err) & 0xf : DDI_SUCCESS)
172
173
174/*
175 * Performance counters information.
176 */
177#define	PCMU_SHIFT_PIC0	8
178#define	PCMU_SHIFT_PIC1	0
179
180/*
181 * CMU-CH-specific register offsets & bit field positions.
182 */
183
184/*
185 * Offsets of global registers:
186 */
187#define	PCMU_CB_DEVICE_ID_REG_OFFSET		0x00000000	/* RAGS */
188#define	PCMU_CB_CONTROL_STATUS_REG_OFFSET	0x00000010
189
190/*
191 * CMU-CH performance counters offsets.
192 */
193#define	PCMU_PERF_PCR_OFFSET			0x00000100
194#define	PCMU_PERF_PIC_OFFSET			0x00000108
195
196/*
197 * Offsets of registers in the interrupt block:
198 */
199#define	PCMU_IB_OBIO_INTR_MAP_REG_OFFSET	0x00001000
200#define	PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET	0x00001800
201
202/*
203 * Offsets of registers in the PBM block:
204 */
205#define	PCMU_PCI_PBM_REG_BASE			0x00002000 /* RAGS */
206#define	PCMU_PCI_CTRL_REG_OFFSET		0x00000000
207#define	PCMU_PCI_ASYNC_FLT_STATUS_REG_OFFSET	0x00000010
208#define	PCMU_PCI_ASYNC_FLT_ADDR_REG_OFFSET	0x00000018
209#define	PCMU_PCI_DIAG_REG_OFFSET		0x00000020
210
211/*
212 * CMU-CH control register bit definitions:
213 */
214#define	PCMU_CB_CONTROL_STATUS_MODE		0x0000000000000001ull
215#define	PCMU_CB_CONTROL_STATUS_IMPL		0xf000000000000000ull
216#define	PCMU_CB_CONTROL_STATUS_IMPL_SHIFT	60
217#define	PCMU_CB_CONTROL_STATUS_VER		0x0f00000000000000ull
218#define	PCMU_CB_CONTROL_STATUS_VER_SHIFT	56
219
220/*
221 * CMU-CH ECC UE AFSR bit definitions:
222 */
223#define	PCMU_ECC_UE_AFSR_BYTEMASK		0x0000ffff00000000ull
224#define	PCMU_ECC_UE_AFSR_BYTEMASK_SHIFT		32
225#define	PCMU_ECC_UE_AFSR_DW_OFFSET		0x00000000e0000000ull
226#define	PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT	29
227#define	PCMU_ECC_UE_AFSR_ID			0x000000001f000000ull
228#define	PCMU_ECC_UE_AFSR_ID_SHIFT		24
229#define	PCMU_ECC_UE_AFSR_BLK			0x0000000000800000ull
230
231/*
232 * CMU-CH pci control register bits:
233 */
234#define	PCMU_PCI_CTRL_ARB_PARK			0x0000000000200000ull
235#define	PCMU_PCI_CTRL_WAKEUP_EN			0x0000000000000200ull
236#define	PCMU_PCI_CTRL_ERR_INT_EN		0x0000000000000100ull
237#define	PCMU_PCI_CTRL_ARB_EN_MASK		0x000000000000000full
238
239/*
240 * CMU-CH PCI asynchronous fault status register bit definitions:
241 */
242#define	PCMU_PCI_AFSR_PE_SHIFT			60
243#define	PCMU_PCI_AFSR_SE_SHIFT			56
244#define	PCMU_PCI_AFSR_E_MA			0x0000000000000008ull
245#define	PCMU_PCI_AFSR_E_TA			0x0000000000000004ull
246#define	PCMU_PCI_AFSR_E_RTRY			0x0000000000000002ull
247#define	PCMU_PCI_AFSR_E_PERR			0x0000000000000001ull
248#define	PCMU_PCI_AFSR_E_MASK			0x000000000000000full
249#define	PCMU_PCI_AFSR_BYTEMASK			0x0000ffff00000000ull
250#define	PCMU_PCI_AFSR_BYTEMASK_SHIFT		32
251#define	PCMU_PCI_AFSR_BLK			0x0000000080000000ull
252#define	PCMU_PCI_AFSR_MID			0x000000003e000000ull
253#define	PCMU_PCI_AFSR_MID_SHIFT			25
254
255/*
256 * CMU-CH PCI diagnostic register bit definitions:
257 */
258#define	PCMU_PCI_DIAG_DIS_DWSYNC		0x0000000000000010ull
259
260#define	PBM_AFSR_TO_PRIERR(afsr)	\
261	(afsr >> PCMU_PCI_AFSR_PE_SHIFT & PCMU_PCI_AFSR_E_MASK)
262#define	PBM_AFSR_TO_SECERR(afsr)	\
263	(afsr >> PCMU_PCI_AFSR_SE_SHIFT & PCMU_PCI_AFSR_E_MASK)
264
265#define	PCMU_ID_TO_IGN(pcmu_id)		((pcmu_ign_t)UPAID_TO_IGN(pcmu_id))
266
267
268/*
269 * Number of dispatch target entries.
270 */
271#define	U2U_DATA_NUM  16
272
273/*
274 *  Offsets of registers in the Interrupt Dispatch Table:
275 */
276#define	U2U_MODE_STATUS_REGISTER_OFFSET		0x00000000
277#define	U2U_PID_REGISTER_OFFSET			0x00000008
278#define	U2U_DATA_REGISTER_OFFSET		0x00000010
279
280/*
281 * Mode Status register bit definitions:
282 */
283#define	U2U_MS_IEV    0x00000040	/* bit-6: Interrupt Extension enable */
284
285/*
286 * Index number of U2U registers in OBP's "regs-property" of CMU-CH
287 */
288#define	REGS_INDEX_OF_U2U	3
289
290/*
291 * The following two difinitions are used to control target id
292 * for Interrupt dispatch data by software.
293 */
294typedef struct u2u_ittrans_id {
295	uint_t u2u_tgt_cpu_id;			/* target CPU ID */
296	uint_t u2u_rsv1;			/* reserved */
297	volatile uint64_t *u2u_ino_map_reg;	/* u2u intr. map register */
298} u2u_ittrans_id_t;
299
300typedef struct u2u_ittrans_data {
301	kmutex_t u2u_ittrans_lock;
302	uintptr_t u2u_regs_base;	/* "reg" property */
303	ddi_acc_handle_t u2u_acc;	/* pointer to acc */
304	uint_t u2u_port_id;		/* "PID" register n U2U */
305	uint_t u2u_board;		/* "board#" property */
306	u2u_ittrans_id_t u2u_ittrans_id[U2U_DATA_NUM];
307} u2u_ittrans_data_t;
308
309/*
310 * Driver binding name for OPL DC system
311 */
312#define	PCICMU_OPL_DC_BINDING_NAME		"pci10cf,1390"
313
314/*
315 * Offsets of registers in the interrupt block:
316 */
317
318#define	PCMU_IB_UPA0_INTR_MAP_REG_OFFSET	0x6000
319#define	PCMU_IB_UPA1_INTR_MAP_REG_OFFSET	0x8000
320#define	PCMU_IB_SLOT_CLEAR_INTR_REG_OFFSET	0x1400
321#define	PCMU_IB_OBIO_INTR_STATE_DIAG_REG	0xA808
322#define	PCMU_IB_INTR_RETRY_TIMER_OFFSET		0x1A00
323
324/*
325 * Offsets of registers in the ECC block:
326 */
327#define	PCMU_ECC_CSR_OFFSET			0x20
328#define	PCMU_UE_AFSR_OFFSET			0x30
329#define	PCMU_UE_AFAR_OFFSET			0x38
330
331/*
332 * CMU-CH control register bit definitions:
333 */
334#define	PCMU_CB_CONTROL_STATUS_IGN		0x0007c00000000000ull
335#define	PCMU_CB_CONTROL_STATUS_IGN_SHIFT	46
336#define	PCMU_CB_CONTROL_STATUS_APCKEN		0x0000000000000008ull
337#define	PCMU_CB_CONTROL_STATUS_APERR		0x0000000000000004ull
338#define	PCMU_CB_CONTROL_STATUS_IAP		0x0000000000000002ull
339
340/*
341 * CMU-CH interrupt mapping register bit definitions:
342 */
343#define	PCMU_INTR_MAP_REG_VALID			0x0000000080000000ull
344#define	PCMU_INTR_MAP_REG_TID			0x000000007C000000ull
345#define	PCMU_INTR_MAP_REG_IGN			0x00000000000007C0ull
346#define	PCMU_INTR_MAP_REG_INO			0x000000000000003full
347#define	PCMU_INTR_MAP_REG_TID_SHIFT		26
348#define	PCMU_INTR_MAP_REG_IGN_SHIFT		6
349
350/*
351 * CMU-CH clear interrupt register bit definitions:
352 */
353#define	PCMU_CLEAR_INTR_REG_MASK		0x0000000000000003ull
354#define	PCMU_CLEAR_INTR_REG_IDLE		0x0000000000000000ull
355#define	PCMU_CLEAR_INTR_REG_RECEIVED		0x0000000000000001ull
356#define	PCMU_CLEAR_INTR_REG_RSVD		0x0000000000000002ull
357#define	PCMU_CLEAR_INTR_REG_PENDING		0x0000000000000003ull
358
359/*
360 * CMU-CH ECC control register bit definitions:
361 */
362#define	PCMU_ECC_CTRL_ECC_EN			0x8000000000000000ull
363#define	PCMU_ECC_CTRL_UE_INTEN			0x4000000000000000ull
364
365/*
366 * CMU-CH ECC UE AFSR bit definitions:
367 */
368#define	PCMU_ECC_UE_AFSR_PE_SHIFT		61
369#define	PCMU_ECC_UE_AFSR_SE_SHIFT		58
370#define	PCMU_ECC_UE_AFSR_E_MASK			0x0000000000000007ull
371#define	PCMU_ECC_UE_AFSR_E_PIO			0x0000000000000004ull
372
373/*
374 * CMU-CH PCI diagnostic register bit definitions:
375 */
376#define	PCMU_PCI_DIAG_DIS_RETRY			0x0000000000000040ull
377#define	PCMU_PCI_DIAG_DIS_INTSYNC		0x0000000000000020ull
378
379
380#define	NAMEINST(dip)	ddi_driver_name(dip), ddi_get_instance(dip)
381#define	NAMEADDR(dip)	ddi_node_name(dip), ddi_get_name_addr(dip)
382
383
384/*
385 * CMU-CH Tunables
386 */
387extern uint32_t pcmu_spurintr_duration;		/* spurious interupt duration */
388extern ushort_t pcmu_command_default;		/* default command */
389extern uint_t ecc_error_intr_enable;		/* ECC error intr */
390extern uint_t pcmu_ecc_afsr_retries;		/* num ECC afsr retries */
391extern uint_t pcmu_intr_retry_intv;		/* intr retry interval */
392extern uint_t pcmu_panic_on_fatal_errors;	/* PANIC on fatal errors */
393extern uint_t pcmu_unclaimed_intr_max;		/* Max unclaimed interrupts */
394extern hrtime_t pcmu_intrpend_timeout;		/* intr pending timeout */
395
396
397extern void *per_pcmu_state;		/* per-pbm soft state pointer */
398extern kmutex_t pcmu_global_mutex;	/* attach/detach common struct lock */
399extern uint64_t pcmu_errtrig_pa;
400
401
402/*
403 * Prototypes.
404 */
405extern void pcmu_post_uninit_child(pcmu_t *);
406extern void pcmu_kstat_init(void);
407extern void pcmu_kstat_fini(void);
408extern void pcmu_add_upstream_kstat(pcmu_t *);
409extern void pcmu_fix_ranges(pcmu_ranges_t *, int);
410extern uint_t pcmu_pbm_disable_errors(pcmu_pbm_t *);
411extern uint32_t ib_map_reg_get_cpu(volatile uint64_t);
412extern uint64_t *ib_intr_map_reg_addr(pcmu_ib_t *, pcmu_ib_ino_t);
413extern uint64_t *ib_clear_intr_reg_addr(pcmu_ib_t *, pcmu_ib_ino_t);
414extern void pcmu_cb_setup(pcmu_t *);
415extern void pcmu_cb_teardown(pcmu_t *);
416extern int cb_register_intr(pcmu_t *);
417extern void cb_enable_intr(pcmu_t *);
418extern uint64_t cb_ino_to_map_pa(pcmu_cb_t *, pcmu_ib_ino_t);
419extern uint64_t cb_ino_to_clr_pa(pcmu_cb_t *, pcmu_ib_ino_t);
420extern int cb_remove_xintr(pcmu_t *, dev_info_t *, dev_info_t *,
421    pcmu_ib_ino_t, pcmu_ib_mondo_t);
422extern uint32_t pcmu_intr_dist_cpuid(pcmu_ib_t *, pcmu_ib_ino_info_t *);
423extern void pcmu_ecc_setup(pcmu_ecc_t *);
424extern ushort_t pcmu_ecc_get_synd(uint64_t);
425extern void pcmu_pbm_setup(pcmu_pbm_t *);
426extern void pcmu_pbm_teardown(pcmu_pbm_t *);
427extern uintptr_t pcmu_ib_setup(pcmu_ib_t *);
428extern int pcmu_get_numproxy(dev_info_t *);
429extern int pcmu_ecc_add_intr(pcmu_t *, int, pcmu_ecc_intr_info_t *);
430extern void pcmu_ecc_rem_intr(pcmu_t *, int, pcmu_ecc_intr_info_t *);
431extern int pcmu_pbm_err_handler(dev_info_t *, ddi_fm_error_t *,
432    const void *, int);
433extern void pcmu_ecc_classify(uint64_t, pcmu_ecc_errstate_t *);
434extern int pcmu_pbm_classify(pcmu_pbm_errstate_t *);
435extern int pcmu_check_error(pcmu_t *);
436extern void set_intr_mapping_reg(int, uint64_t *, int);
437extern uint32_t pcmu_class_to_pil(dev_info_t *rdip);
438extern int pcmu_add_intr(dev_info_t *dip, dev_info_t *rdip,
439    ddi_intr_handle_impl_t *hdlp);
440extern int pcmu_remove_intr(dev_info_t *dip, dev_info_t *rdip,
441    ddi_intr_handle_impl_t *hdlp);
442extern void pcmu_intr_teardown(pcmu_t *pcmu_p);
443
444extern int u2u_translate_tgtid(pcmu_t *, uint_t, volatile uint64_t *);
445extern void u2u_ittrans_cleanup(u2u_ittrans_data_t *, volatile uint64_t *);
446void pcmu_err_create(pcmu_t *pcmu_p);
447void pcmu_err_destroy(pcmu_t *pcmu_p);
448void pcmu_pbm_ereport_post(dev_info_t *dip, uint64_t ena,
449    pcmu_pbm_errstate_t *pbm_err);
450#ifdef	__cplusplus
451}
452#endif
453
454#endif	/* _SYS_PCICMU_H */
455