pic.h revision 224110
185722Sjulian/*-
285722Sjulian * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
385722Sjulian * reserved.
485722Sjulian *
585722Sjulian * Redistribution and use in source and binary forms, with or without
685722Sjulian * modification, are permitted provided that the following conditions are
785722Sjulian * met:
885722Sjulian *
985722Sjulian * 1. Redistributions of source code must retain the above copyright
1085722Sjulian *    notice, this list of conditions and the following disclaimer.
1185722Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1285722Sjulian *    notice, this list of conditions and the following disclaimer in
1385722Sjulian *    the documentation and/or other materials provided with the
1485722Sjulian *    distribution.
1585722Sjulian *
1685722Sjulian * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
1785722Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1885722Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1985722Sjulian * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
2085722Sjulian * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2185722Sjulian * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2285722Sjulian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2385722Sjulian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2485722Sjulian * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2585722Sjulian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2685722Sjulian * THE POSSIBILITY OF SUCH DAMAGE.
2786742Sru *
2885722Sjulian * $FreeBSD: head/sys/mips/nlm/hal/pic.h 224110 2011-07-16 19:35:44Z jchandra $
29242997Sjoel * NETLOGIC_BSD */
3085722Sjulian
3186742Sru#ifndef __XLP_PIC_H__
3285722Sjulian#define __XLP_PIC_H__
3385722Sjulian
3485722Sjulian/* PIC Specific registers */
3585722Sjulian#define XLP_PIC_CTRL_REG		0x40
36141350Sru#define XLP_PIC_BYTESWAP_REG		0x42
3786742Sru#define XLP_PIC_STATUS_REG		0x44
3885722Sjulian#define XLP_PIC_INTR_TIMEOUT		0x46
3985722Sjulian#define XLP_PIC_ICI0_INTR_TIMEOUT	0x48
4085722Sjulian#define XLP_PIC_ICI1_INTR_TIMEOUT	0x4a
4185722Sjulian#define XLP_PIC_ICI2_INTR_TIMEOUT	0x4c
42139097Sbrueffer#define XLP_PIC_IPI_CTRL_REG		0x4e
4386742Sru#define XLP_PIC_INT_ACK_REG		0x50
4486742Sru#define XLP_PIC_INT_PENDING0_REG	0x52
4585722Sjulian#define XLP_PIC_INT_PENDING1_REG	0x54
4685722Sjulian#define XLP_PIC_INT_PENDING2_REG	0x56
4785722Sjulian
4886742Sru#define XLP_PIC_WDOG0_MAXVAL_REG	0x58
4986742Sru#define XLP_PIC_WDOG0_COUNT_REG		0x5a
5086742Sru#define XLP_PIC_WDOG0_ENABLE0_REG	0x5c
5185722Sjulian#define XLP_PIC_WDOG0_ENABLE1_REG	0x5e
5286742Sru#define XLP_PIC_WDOG0_BEATCMD_REG	0x60
5386742Sru#define XLP_PIC_WDOG0_BEAT0_REG		0x62
5485722Sjulian#define XLP_PIC_WDOG0_BEAT1_REG		0x64
5585722Sjulian
5685722Sjulian#define XLP_PIC_WDOG1_MAXVAL_REG	0x66
5786742Sru#define XLP_PIC_WDOG1_COUNT_REG		0x68
5885722Sjulian#define XLP_PIC_WDOG1_ENABLE0_REG	0x6a
5985722Sjulian#define XLP_PIC_WDOG1_ENABLE1_REG	0x6c
6086742Sru#define XLP_PIC_WDOG1_BEATCMD_REG	0x6e
6185722Sjulian#define XLP_PIC_WDOG1_BEAT0_REG		0x70
6286742Sru#define XLP_PIC_WDOG1_BEAT1_REG		0x72
6386742Sru
6486742Sru#define XLP_PIC_WDOG_MAXVAL_REG(i)	(XLP_PIC_WDOG0_MAXVAL_REG + ((i) ? 7 : 0))
6585722Sjulian#define XLP_PIC_WDOG_COUNT_REG(i)	(XLP_PIC_WDOG0_COUNT_REG + ((i) ? 7 : 0))
6685722Sjulian#define XLP_PIC_WDOG_ENABLE0_REG(i)	(XLP_PIC_WDOG0_ENABLE0_REG + ((i) ? 7 : 0))
6785722Sjulian#define XLP_PIC_WDOG_ENABLE1_REG(i)	(XLP_PIC_WDOG0_ENABLE1_REG + ((i) ? 7 : 0))
6885722Sjulian#define XLP_PIC_WDOG_BEATCMD_REG(i)	(XLP_PIC_WDOG0_BEATCMD_REG + ((i) ? 7 : 0))
69242997Sjoel#define XLP_PIC_WDOG_BEAT0_REG(i)	(XLP_PIC_WDOG0_BEAT0_REG + ((i) ? 7 : 0))
7085722Sjulian#define XLP_PIC_WDOG_BEAT1_REG(i)	(XLP_PIC_WDOG0_BEAT1_REG + ((i) ? 7 : 0))
7185722Sjulian
7285722Sjulian#define XLP_PIC_SYSTIMER0_MAXVAL_REG	0x74
7386742Sru#define XLP_PIC_SYSTIMER1_MAXVAL_REG	0x76
7485722Sjulian#define XLP_PIC_SYSTIMER2_MAXVAL_REG	0x78
7585722Sjulian#define XLP_PIC_SYSTIMER3_MAXVAL_REG	0x7a
7685722Sjulian#define XLP_PIC_SYSTIMER4_MAXVAL_REG	0x7c
7785722Sjulian#define XLP_PIC_SYSTIMER5_MAXVAL_REG	0x7e
7885722Sjulian#define XLP_PIC_SYSTIMER6_MAXVAL_REG	0x80
7986742Sru#define XLP_PIC_SYSTIMER7_MAXVAL_REG	0x82
8085722Sjulian#define XLP_PIC_SYSTIMER_MAXVAL_REG(i)	(XLP_PIC_SYSTIMER0_MAXVAL_REG + ((i)*2))
8185722Sjulian
8286742Sru#define XLP_PIC_SYSTIMER0_COUNT_REG	0x84
8385722Sjulian#define XLP_PIC_SYSTIMER1_COUNT_REG	0x86
8486742Sru#define XLP_PIC_SYSTIMER2_COUNT_REG	0x88
8586742Sru#define XLP_PIC_SYSTIMER3_COUNT_REG	0x8a
8685722Sjulian#define XLP_PIC_SYSTIMER4_COUNT_REG	0x8c
8785722Sjulian#define XLP_PIC_SYSTIMER5_COUNT_REG	0x8e
8885722Sjulian#define XLP_PIC_SYSTIMER6_COUNT_REG	0x90
8985722Sjulian#define XLP_PIC_SYSTIMER7_COUNT_REG	0x92
9085722Sjulian#define XLP_PIC_SYSTIMER_COUNT_REG(i)	(XLP_PIC_SYSTIMER0_COUNT_REG + ((i)*2))
9186742Sru
92242997Sjoel#define XLP_PIC_ITE0_N0_N1_REG		0x94
9385722Sjulian#define XLP_PIC_ITE1_N0_N1_REG		0x98
9486742Sru#define XLP_PIC_ITE2_N0_N1_REG		0x9c
9585722Sjulian#define XLP_PIC_ITE3_N0_N1_REG		0xa0
96242997Sjoel#define XLP_PIC_ITE4_N0_N1_REG		0xa4
9785722Sjulian#define XLP_PIC_ITE5_N0_N1_REG		0xa8
9886742Sru#define XLP_PIC_ITE6_N0_N1_REG		0xac
9986742Sru#define XLP_PIC_ITE7_N0_N1_REG		0xb0
10086742Sru#define XLP_PIC_ITE_N0_N1_REG(i)	(XLP_PIC_ITE0_N0_N1_REG + ((i)*4))
10186742Sru
10285722Sjulian#define XLP_PIC_ITE0_N2_N3_REG		0x96
10385722Sjulian#define XLP_PIC_ITE1_N2_N3_REG		0x9a
104242997Sjoel#define XLP_PIC_ITE2_N2_N3_REG		0x9e
105242997Sjoel#define XLP_PIC_ITE3_N2_N3_REG		0xa2
10685722Sjulian#define XLP_PIC_ITE4_N2_N3_REG		0xa6
10785722Sjulian#define XLP_PIC_ITE5_N2_N3_REG		0xaa
10885722Sjulian#define XLP_PIC_ITE6_N2_N3_REG		0xae
10985722Sjulian#define XLP_PIC_ITE7_N2_N3_REG		0xb2
11086742Sru#define XLP_PIC_ITE_N2_N3_REG(i)	(XLP_PIC_ITE0_N2_N3_REG + ((i)*4))
11186742Sru
11286742Sru#define XLP_PIC_IRT0_REG		0xb4
11385722Sjulian#define XLP_PIC_IRT_REG(i)		(XLP_PIC_IRT0_REG + ((i)*2))
11485722Sjulian
11585722Sjulian/* PIC IRT indices */
116158617Smarius
11785722Sjulian#define XLP_PIC_IRT_WD0_INDEX		0
11885722Sjulian#define XLP_PIC_IRT_WD1_INDEX		1
11985722Sjulian#define XLP_PIC_IRT_WD_NMI0_INDEX	2
120139097Sbrueffer#define XLP_PIC_IRT_WD_NMI1_INDEX	3
12185722Sjulian#define XLP_PIC_IRT_TIMER0_INDEX	4
12286742Sru#define XLP_PIC_IRT_TIMER1_INDEX	5
12385722Sjulian#define XLP_PIC_IRT_TIMER2_INDEX	6
12485722Sjulian#define XLP_PIC_IRT_TIMER3_INDEX	7
12585722Sjulian#define XLP_PIC_IRT_TIMER4_INDEX	8
12685722Sjulian#define XLP_PIC_IRT_TIMER5_INDEX	9
12785722Sjulian#define XLP_PIC_IRT_TIMER6_INDEX	10
12885722Sjulian#define XLP_PIC_IRT_TIMER7_INDEX	11
12985722Sjulian#define XLP_PIC_IRT_TIMER_INDEX(i)	(XLP_PIC_IRT_TIMER0_INDEX + (i))
13085722Sjulian
13185722Sjulian#define XLP_PIC_IRT_MSGQ0_INDEX		12
13294317Sjulian#define XLP_PIC_IRT_MSGQ_INDEX(i)	(XLP_PIC_IRT_MSGQ0_INDEX + (i))
13385722Sjulian/* 12 to 43 */
13485722Sjulian#define XLP_PIC_IRT_MSG0_INDEX		44
13585722Sjulian#define XLP_PIC_IRT_MSG1_INDEX		45
13685722Sjulian
13785722Sjulian#define XLP_PIC_IRT_PCIE_MSIX0_INDEX	46
13885722Sjulian#define XLP_PIC_IRT_PCIE_MSIX_INDEX(i)	(XLP_PIC_IRT_PCIE_MSIX0_INDEX + (i))
13985722Sjulian/* 46 to 77 */
14085722Sjulian#define XLP_PIC_IRT_PCIE_LINK0_INDEX	78
14186742Sru#define XLP_PIC_IRT_PCIE_LINK1_INDEX	79
14285722Sjulian#define XLP_PIC_IRT_PCIE_LINK2_INDEX	80
14385722Sjulian#define XLP_PIC_IRT_PCIE_LINK3_INDEX	81
14485722Sjulian#define XLP_PIC_IRT_PCIE_LINK_INDEX(i)	(XLP_PIC_IRT_PCIE_LINK0_INDEX + (i))
14585722Sjulian/* 78 to 81 */
14686742Sru#define XLP_PIC_IRT_NA0_INDEX		82
14785722Sjulian#define XLP_PIC_IRT_NA_INDEX(i)		(XLP_PIC_IRT_NA0_INDEX + (i))
14885722Sjulian/* 82 to 113 */
14985722Sjulian#define XLP_PIC_IRT_POE_INDEX		114
15085722Sjulian#define XLP_PIC_IRT_USB0_INDEX		115
15185722Sjulian#define XLP_PIC_IRT_EHCI0_INDEX		115
15285722Sjulian#define XLP_PIC_IRT_EHCI1_INDEX		118
15385722Sjulian#define XLP_PIC_IRT_USB_INDEX(i)	(XLP_PIC_IRT_USB0_INDEX + (i))
15485722Sjulian/* 115 to 120 */
155#define XLP_PIC_IRT_GDX_INDEX		121
156#define XLP_PIC_IRT_SEC_INDEX		122
157#define XLP_PIC_IRT_RSA_INDEX		123
158#define XLP_PIC_IRT_COMP0_INDEX		124
159#define XLP_PIC_IRT_COMP_INDEX(i)	(XLP_PIC_IRT_COMP0_INDEX + (i))
160/* 124 to 127 */
161#define XLP_PIC_IRT_GBU_INDEX		128
162/* coherent inter chip */
163#define XLP_PIC_IRT_CIC0_INDEX		129
164#define XLP_PIC_IRT_CIC1_INDEX		130
165#define XLP_PIC_IRT_CIC2_INDEX		131
166#define XLP_PIC_IRT_CAM_INDEX		132
167#define XLP_PIC_IRT_UART0_INDEX		133
168#define XLP_PIC_IRT_UART1_INDEX		134
169#define XLP_PIC_IRT_I2C0_INDEX		135
170#define XLP_PIC_IRT_I2C1_INDEX		136
171#define XLP_PIC_IRT_SYS0_INDEX		137
172#define XLP_PIC_IRT_SYS1_INDEX		138
173#define XLP_PIC_IRT_JTAG_INDEX		139
174#define XLP_PIC_IRT_PIC_INDEX		140
175#define XLP_PIC_IRT_NBU_INDEX		141
176#define XLP_PIC_IRT_TCU_INDEX		142
177/* global coherency */
178#define XLP_PIC_IRT_GCU_INDEX		143
179#define XLP_PIC_IRT_DMC0_INDEX		144
180#define XLP_PIC_IRT_DMC1_INDEX		145
181#define XLP_PIC_IRT_GPIO0_INDEX		146
182#define XLP_PIC_IRT_GPIO_INDEX(i)	(XLP_PIC_IRT_GPIO0_INDEX + (i))
183/* 146 to 149 */
184#define XLP_PIC_IRT_NOR_INDEX		150
185#define XLP_PIC_IRT_NAND_INDEX		151
186#define XLP_PIC_IRT_SPI_INDEX		152
187#define XLP_PIC_IRT_MMC_INDEX		153
188
189/* PIC control register defines */
190#define XLP_PIC_ITV_OFFSET		32 /* interrupt timeout value */
191#define XLP_PIC_ICI_OFFSET		19 /* ICI interrupt timeout enable */
192#define XLP_PIC_ITE_OFFSET		18 /* interrupt timeout enable */
193#define XLP_PIC_STE_OFFSET		10 /* system timer interrupt enable */
194#define XLP_PIC_WWR1_OFFSET		8  /* watchdog timer 1 wraparound count for reset */
195#define XLP_PIC_WWR0_OFFSET		6  /* watchdog timer 0 wraparound count for reset */
196#define XLP_PIC_WWN1_OFFSET		4  /* watchdog timer 1 wraparound count for NMI */
197#define XLP_PIC_WWN0_OFFSET		2  /* watchdog timer 0 wraparound count for NMI */
198#define XLP_PIC_WTE_OFFSET		0  /* watchdog timer enable */
199
200/* PIC Status register defines */
201#define XLP_PIC_ICI_STATUS_OFFSET	33 /* ICI interrupt timeout interrupt status */
202#define XLP_PIC_ITE_STATUS_OFFSET	32 /* interrupt timeout interrupt status */
203#define XLP_PIC_STS_STATUS_OFFSET	4  /* System timer interrupt status */
204#define XLP_PIC_WNS_STATUS_OFFSET	2  /* NMI interrupt status for watchdog timers */
205#define XLP_PIC_WIS_STATUS_OFFSET	0  /* Interrupt status for watchdog timers */
206
207/* PIC IPI control register offsets */
208#define XLP_PIC_IPICTRL_NMI_OFFSET	32
209#define XLP_PIC_IPICTRL_RIV_OFFSET	20 /* received interrupt vector */
210#define XLP_PIC_IPICTRL_IDB_OFFSET	16 /* interrupt destination base */
211#define XLP_PIC_IPICTRL_DTE_OFFSET	16 /* interrupt destination thread enables */
212
213/* PIC IRT register offsets */
214#define XLP_PIC_IRT_ENABLE_OFFSET	31
215#define XLP_PIC_IRT_NMI_OFFSET		29
216#define XLP_PIC_IRT_SCH_OFFSET		28 /* Scheduling scheme */
217#define XLP_PIC_IRT_RVEC_OFFSET		20 /* Interrupt receive vectors */
218#define XLP_PIC_IRT_DT_OFFSET		19 /* Destination type */
219#define XLP_PIC_IRT_DB_OFFSET		16 /* Destination base */
220#define XLP_PIC_IRT_DTE_OFFSET		0  /* Destination thread enables */
221
222#define XLP_PIC_MAX_IRQ			64
223#define XLP_PIC_MAX_IRT			160
224#define XLP_PIC_TIMER_FREQ		133000000
225
226#if !defined(LOCORE) && !defined(__ASSEMBLY__)
227
228#define	nlm_rdreg_pic(b, r)		nlm_read_reg64_kseg(b,r)
229#define	nlm_wreg_pic(b, r, v)		nlm_write_reg64_kseg(b,r,v)
230#define nlm_pcibase_pic(node)		nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
231#define nlm_regbase_pic(node)		nlm_pcibase_pic(node)
232
233/* IRT and h/w interrupt routines */
234static __inline__ int
235nlm_pic_get_numirts(uint64_t pcibase)
236{
237	return (nlm_pci_rdreg(pcibase, XLP_PCI_IRTINFO_REG) >> 16);
238}
239
240static __inline__ int
241nlm_pic_get_startirt(uint64_t base)
242{
243	return (nlm_pci_rdreg(base, XLP_PCI_IRTINFO_REG) & 0xff);
244}
245
246
247static __inline__ int
248nlm_pic_read_irt(uint64_t base, int irt_index)
249{
250	return nlm_rdreg_pic(base, XLP_PIC_IRT_REG(irt_index));
251}
252
253/* IRT's can be written into in two modes
254 * ITE mode - Here the destination of the interrupt is one of the
255 *   eight interrupt-thread-enable groups, allowing the interrupt
256 *   to be distributed to any thread on any node
257 * ID mode - In ID mode, the IRT has the DB and DTE fields.
258 *   DB[18:17] hold the node select and DB[16], if set to 0 selects
259 *   cpu-cores 0-3, and if set to 1 selects cpu-cores 4-7.
260 *   The DTE[15:0] field is a thread mask, allowing the PIC to broadcast
261 *   the interrupt to 1-16 threads selectable from that mask
262 */
263
264static __inline__ void
265nlm_pic_write_irt_raw(uint64_t base, int irt_index, int en, int nmi, int sch,
266		int vec, int dt, int db, int dte)
267{
268	uint64_t val =
269		(((en & 0x1) << XLP_PIC_IRT_ENABLE_OFFSET) |
270		 ((nmi & 0x1) << XLP_PIC_IRT_NMI_OFFSET) |
271		 ((sch & 0x1) << XLP_PIC_IRT_SCH_OFFSET) |
272		 ((vec & 0x3f) << XLP_PIC_IRT_RVEC_OFFSET) |
273		 ((dt & 0x1 ) << XLP_PIC_IRT_DT_OFFSET) |
274		 ((db & 0x7) << XLP_PIC_IRT_DB_OFFSET) |
275		 (dte & 0xffff));
276	nlm_wreg_pic(base, XLP_PIC_IRT_REG(irt_index), val);
277}
278
279/* write IRT in ID mode */
280static __inline__ void
281nlm_pic_write_irt_id(uint64_t base, int irt_index, int en, int nmi, int vec,
282		int node, int cpugroup, uint32_t cpu_mask)
283{
284	nlm_pic_write_irt_raw(base, irt_index, en, nmi, 1, vec, 1,
285			(node << 1) | cpugroup , cpu_mask);
286}
287
288/* write IRT in ITE mode */
289static __inline__ void
290nlm_pic_write_ite(uint64_t base, int ite, uint32_t node0_thrmask,
291	uint32_t node1_thrmask, uint32_t node2_thrmask, uint32_t node3_thrmask)
292{
293	uint64_t tm10 = ((uint64_t)node1_thrmask << 32) | node0_thrmask;
294	uint64_t tm32 = ((uint64_t)node1_thrmask << 32) | node0_thrmask;
295
296	/* Enable the ITE register for all nodes */
297	nlm_wreg_pic(base, XLP_PIC_ITE_N0_N1_REG(ite), tm10);
298	nlm_wreg_pic(base, XLP_PIC_ITE_N2_N3_REG(ite), tm32);
299}
300
301static __inline__ void
302nlm_pic_write_irt_ite(uint64_t base, int irt_index, int ite, int en, int nmi,
303		int sch, int vec)
304{
305	nlm_pic_write_irt_raw(base, irt_index, en, nmi, sch, vec, 0, ite, 0);
306}
307
308/* Goto PIC on that node, and ack the interrupt */
309static __inline__ void nlm_pic_ack(uint64_t src_base, int irt)
310{
311	nlm_wreg_pic(src_base, XLP_PIC_INT_ACK_REG, irt);
312	/* ack in the status registers for watchdog and system timers */
313	if (irt < 12)
314		nlm_wreg_pic(src_base, XLP_PIC_STATUS_REG, (1 << irt));
315}
316
317/* IPI routines */
318
319static __inline__ void
320nlm_pic_send_ipi(uint64_t local_base, int target_node, int vcpu, int vec, int nmi)
321{
322	uint64_t ipi =
323		(((uint64_t)nmi << XLP_PIC_IPICTRL_NMI_OFFSET) |
324		(vec << XLP_PIC_IPICTRL_RIV_OFFSET) |
325		(target_node << 17) |
326		(1 << (vcpu & 0xf)));
327	if (vcpu > 15)
328		ipi |= 0x10000; /* set bit 16 to select cpus 16-31 */
329
330	nlm_wreg_pic(local_base, XLP_PIC_IPI_CTRL_REG, ipi);
331}
332
333/* System Timer routines -- broadcasts systemtimer to 16 vcpus defined in cpu_mask */
334
335static __inline__ void
336nlm_pic_set_systimer(uint64_t base, int timer, uint64_t value, int irq, int node,
337		int cpugroup, uint32_t cpumask)
338{
339	uint64_t pic_ctrl = nlm_rdreg_pic(base, XLP_PIC_CTRL_REG);
340	int en;
341
342	en = (cpumask != 0);
343	nlm_wreg_pic(base, XLP_PIC_SYSTIMER_MAXVAL_REG(timer), value);
344	nlm_pic_write_irt_id(base, XLP_PIC_IRT_TIMER_INDEX(timer),
345		en, 0, irq, node, cpugroup, cpumask);
346
347	/* enable the timer */
348	pic_ctrl |= (1 << (XLP_PIC_STE_OFFSET+timer));
349	nlm_wreg_pic(base, XLP_PIC_CTRL_REG, pic_ctrl);
350}
351
352static __inline__ uint64_t
353nlm_pic_read_systimer(uint64_t base, int timer)
354{
355	return nlm_rdreg_pic(base, XLP_PIC_SYSTIMER_COUNT_REG(timer));
356}
357
358/* Watchdog timer routines */
359
360/* node - XLP node
361 * timer - watchdog timer. valid values are 0 and 1
362 * wrap_around_count - defines the number of times the watchdog timer can wrap-around
363 *     after which the reset / NMI gets generated to the threads defined in thread-enable-masks.
364 * value - the vatchdog timer max value, upto which the timer will count down
365 */
366
367static __inline__ void
368nlm_pic_set_wdogtimer(uint64_t base, int timer, int wrap_around_count, int nmi,
369		uint32_t node0_thrmask, uint32_t node1_thrmask,
370		uint32_t node2_thrmask, uint32_t node3_thrmask, uint64_t value)
371{
372	uint64_t pic_ctrl = nlm_rdreg_pic(base, XLP_PIC_CTRL_REG);
373	uint64_t mask0, mask1;
374
375	if (timer > 1 || wrap_around_count > 3)
376		return;
377
378	/* enable watchdog timer interrupt */
379	pic_ctrl |= (((1 << timer) & 0xf));
380
381	if (timer) {
382		if (nmi)
383			pic_ctrl |= (wrap_around_count << XLP_PIC_WWN1_OFFSET);
384		else
385			pic_ctrl |= (wrap_around_count << XLP_PIC_WWN0_OFFSET);
386	} else {
387		if (nmi)
388			pic_ctrl |= (wrap_around_count << XLP_PIC_WWR1_OFFSET);
389		else
390			pic_ctrl |= (wrap_around_count << XLP_PIC_WWR0_OFFSET);
391	}
392
393	mask0 = ((unsigned long long)node1_thrmask << 32) | node0_thrmask;
394	mask1 = ((unsigned long long)node3_thrmask << 32) | node2_thrmask;
395
396	nlm_wreg_pic(base, XLP_PIC_WDOG_MAXVAL_REG(timer), value);
397
398	nlm_wreg_pic(base, XLP_PIC_WDOG_ENABLE0_REG(timer), mask0);
399	nlm_wreg_pic(base, XLP_PIC_WDOG_ENABLE1_REG(timer), mask1);
400
401	nlm_wreg_pic(base, XLP_PIC_CTRL_REG, pic_ctrl);
402}
403
404/* watchdog's need to be "stroked" by heartbeats from vcpus.
405 * On XLP, the heartbeat bit for a specific cpu thread on a specific
406 * node is set according to the following formula:
407 * 32N + 4C + T
408 * where N = node, C=cpu-core number, T=thread number
409 *
410 * src_node = source node of watchdog timer interrupts. These interrupts
411 * get generated from the PIC on src_node.
412 * timer = watchdog timer 0 or 1
413 * node = node for which the hearbeat is being done
414 * cpu = cpu-core for which the hearbeat is being done
415 * thread = h/w thread for which the hearbeat is being done
416 */
417static __inline__ void
418nlm_pic_set_wdog_heartbeat(uint64_t base, int timer, int node, int cpu,
419		int thread)
420{
421	int val = 32 * node + 4 * cpu + thread;
422
423	nlm_wreg_pic(base, XLP_PIC_WDOG_BEATCMD_REG(timer), val);
424}
425
426#endif /* !LOCORE && !__ASSEMBLY__ */
427#endif
428