1224110Sjchandra/*- 2224110Sjchandra * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 3224110Sjchandra * reserved. 4224110Sjchandra * 5224110Sjchandra * Redistribution and use in source and binary forms, with or without 6224110Sjchandra * modification, are permitted provided that the following conditions are 7224110Sjchandra * met: 8224110Sjchandra * 9224110Sjchandra * 1. Redistributions of source code must retain the above copyright 10224110Sjchandra * notice, this list of conditions and the following disclaimer. 11224110Sjchandra * 2. Redistributions in binary form must reproduce the above copyright 12224110Sjchandra * notice, this list of conditions and the following disclaimer in 13224110Sjchandra * the documentation and/or other materials provided with the 14224110Sjchandra * distribution. 15224110Sjchandra * 16224110Sjchandra * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 17224110Sjchandra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18224110Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19224110Sjchandra * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 20224110Sjchandra * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21224110Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22224110Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23224110Sjchandra * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24224110Sjchandra * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25224110Sjchandra * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26224110Sjchandra * THE POSSIBILITY OF SUCH DAMAGE. 27224110Sjchandra * 28225394Sjchandra * NETLOGIC_BSD 29224110Sjchandra * $FreeBSD$ 30225394Sjchandra */ 31224110Sjchandra 32225394Sjchandra#ifndef _NLM_HAL_PIC_H 33227783Sjchandra#define _NLM_HAL_PIC_H 34224110Sjchandra 35224110Sjchandra/* PIC Specific registers */ 36227783Sjchandra#define PIC_CTRL 0x00 37224110Sjchandra 38225394Sjchandra/* PIC control register defines */ 39227783Sjchandra#define PIC_CTRL_ITV 32 /* interrupt timeout value */ 40227783Sjchandra#define PIC_CTRL_ICI 19 /* ICI interrupt timeout enable */ 41227783Sjchandra#define PIC_CTRL_ITE 18 /* interrupt timeout enable */ 42227783Sjchandra#define PIC_CTRL_STE 10 /* system timer interrupt enable */ 43227783Sjchandra#define PIC_CTRL_WWR1 8 /* watchdog 1 wraparound count for reset */ 44227783Sjchandra#define PIC_CTRL_WWR0 6 /* watchdog 0 wraparound count for reset */ 45227783Sjchandra#define PIC_CTRL_WWN1 4 /* watchdog 1 wraparound count for NMI */ 46227783Sjchandra#define PIC_CTRL_WWN0 2 /* watchdog 0 wraparound count for NMI */ 47227783Sjchandra#define PIC_CTRL_WTE 0 /* watchdog timer enable */ 48224110Sjchandra 49225394Sjchandra/* PIC Status register defines */ 50227783Sjchandra#define PIC_ICI_STATUS 33 /* ICI interrupt timeout status */ 51227783Sjchandra#define PIC_ITE_STATUS 32 /* interrupt timeout status */ 52227783Sjchandra#define PIC_STS_STATUS 4 /* System timer interrupt status */ 53227783Sjchandra#define PIC_WNS_STATUS 2 /* NMI status for watchdog timers */ 54227783Sjchandra#define PIC_WIS_STATUS 0 /* Interrupt status for watchdog timers */ 55224110Sjchandra 56225394Sjchandra/* PIC IPI control register offsets */ 57227783Sjchandra#define PIC_IPICTRL_NMI 32 58227783Sjchandra#define PIC_IPICTRL_RIV 20 /* received interrupt vector */ 59227783Sjchandra#define PIC_IPICTRL_IDB 16 /* interrupt destination base */ 60227783Sjchandra#define PIC_IPICTRL_DTE 0 /* interrupt destination thread enables */ 61224110Sjchandra 62225394Sjchandra/* PIC IRT register offsets */ 63227783Sjchandra#define PIC_IRT_ENABLE 31 64227783Sjchandra#define PIC_IRT_NMI 29 65227783Sjchandra#define PIC_IRT_SCH 28 /* Scheduling scheme */ 66227783Sjchandra#define PIC_IRT_RVEC 20 /* Interrupt receive vectors */ 67227783Sjchandra#define PIC_IRT_DT 19 /* Destination type */ 68227783Sjchandra#define PIC_IRT_DB 16 /* Destination base */ 69227783Sjchandra#define PIC_IRT_DTE 0 /* Destination thread enables */ 70224110Sjchandra 71227783Sjchandra#define PIC_BYTESWAP 0x02 72227783Sjchandra#define PIC_STATUS 0x04 73227783Sjchandra#define PIC_INTR_TIMEOUT 0x06 74227783Sjchandra#define PIC_ICI0_INTR_TIMEOUT 0x08 75227783Sjchandra#define PIC_ICI1_INTR_TIMEOUT 0x0a 76227783Sjchandra#define PIC_ICI2_INTR_TIMEOUT 0x0c 77227783Sjchandra#define PIC_IPI_CTL 0x0e 78227783Sjchandra#define PIC_INT_ACK 0x10 79227783Sjchandra#define PIC_INT_PENDING0 0x12 80227783Sjchandra#define PIC_INT_PENDING1 0x14 81227783Sjchandra#define PIC_INT_PENDING2 0x16 82224110Sjchandra 83227783Sjchandra#define PIC_WDOG0_MAXVAL 0x18 84227783Sjchandra#define PIC_WDOG0_COUNT 0x1a 85227783Sjchandra#define PIC_WDOG0_ENABLE0 0x1c 86227783Sjchandra#define PIC_WDOG0_ENABLE1 0x1e 87227783Sjchandra#define PIC_WDOG0_BEATCMD 0x20 88227783Sjchandra#define PIC_WDOG0_BEAT0 0x22 89227783Sjchandra#define PIC_WDOG0_BEAT1 0x24 90224110Sjchandra 91227783Sjchandra#define PIC_WDOG1_MAXVAL 0x26 92227783Sjchandra#define PIC_WDOG1_COUNT 0x28 93227783Sjchandra#define PIC_WDOG1_ENABLE0 0x2a 94227783Sjchandra#define PIC_WDOG1_ENABLE1 0x2c 95227783Sjchandra#define PIC_WDOG1_BEATCMD 0x2e 96227783Sjchandra#define PIC_WDOG1_BEAT0 0x30 97227783Sjchandra#define PIC_WDOG1_BEAT1 0x32 98224110Sjchandra 99227783Sjchandra#define PIC_WDOG_MAXVAL(i) (PIC_WDOG0_MAXVAL + ((i) ? 7 : 0)) 100227783Sjchandra#define PIC_WDOG_COUNT(i) (PIC_WDOG0_COUNT + ((i) ? 7 : 0)) 101227783Sjchandra#define PIC_WDOG_ENABLE0(i) (PIC_WDOG0_ENABLE0 + ((i) ? 7 : 0)) 102227783Sjchandra#define PIC_WDOG_ENABLE1(i) (PIC_WDOG0_ENABLE1 + ((i) ? 7 : 0)) 103227783Sjchandra#define PIC_WDOG_BEATCMD(i) (PIC_WDOG0_BEATCMD + ((i) ? 7 : 0)) 104227783Sjchandra#define PIC_WDOG_BEAT0(i) (PIC_WDOG0_BEAT0 + ((i) ? 7 : 0)) 105227783Sjchandra#define PIC_WDOG_BEAT1(i) (PIC_WDOG0_BEAT1 + ((i) ? 7 : 0)) 106224110Sjchandra 107227783Sjchandra#define PIC_TIMER0_MAXVAL 0x34 108227783Sjchandra#define PIC_TIMER1_MAXVAL 0x36 109227783Sjchandra#define PIC_TIMER2_MAXVAL 0x38 110227783Sjchandra#define PIC_TIMER3_MAXVAL 0x3a 111227783Sjchandra#define PIC_TIMER4_MAXVAL 0x3c 112227783Sjchandra#define PIC_TIMER5_MAXVAL 0x3e 113227783Sjchandra#define PIC_TIMER6_MAXVAL 0x40 114227783Sjchandra#define PIC_TIMER7_MAXVAL 0x42 115227783Sjchandra#define PIC_TIMER_MAXVAL(i) (PIC_TIMER0_MAXVAL + ((i) * 2)) 116224110Sjchandra 117227783Sjchandra#define PIC_TIMER0_COUNT 0x44 118227783Sjchandra#define PIC_TIMER1_COUNT 0x46 119227783Sjchandra#define PIC_TIMER2_COUNT 0x48 120227783Sjchandra#define PIC_TIMER3_COUNT 0x4a 121227783Sjchandra#define PIC_TIMER4_COUNT 0x4c 122227783Sjchandra#define PIC_TIMER5_COUNT 0x4e 123227783Sjchandra#define PIC_TIMER6_COUNT 0x50 124227783Sjchandra#define PIC_TIMER7_COUNT 0x52 125227783Sjchandra#define PIC_TIMER_COUNT(i) (PIC_TIMER0_COUNT + ((i) * 2)) 126224110Sjchandra 127227783Sjchandra#define PIC_ITE0_N0_N1 0x54 128227783Sjchandra#define PIC_ITE1_N0_N1 0x58 129227783Sjchandra#define PIC_ITE2_N0_N1 0x5c 130227783Sjchandra#define PIC_ITE3_N0_N1 0x60 131227783Sjchandra#define PIC_ITE4_N0_N1 0x64 132227783Sjchandra#define PIC_ITE5_N0_N1 0x68 133227783Sjchandra#define PIC_ITE6_N0_N1 0x6c 134227783Sjchandra#define PIC_ITE7_N0_N1 0x70 135227783Sjchandra#define PIC_ITE_N0_N1(i) (PIC_ITE0_N0_N1 + ((i) * 4)) 136225394Sjchandra 137227783Sjchandra#define PIC_ITE0_N2_N3 0x56 138227783Sjchandra#define PIC_ITE1_N2_N3 0x5a 139227783Sjchandra#define PIC_ITE2_N2_N3 0x5e 140227783Sjchandra#define PIC_ITE3_N2_N3 0x62 141227783Sjchandra#define PIC_ITE4_N2_N3 0x66 142227783Sjchandra#define PIC_ITE5_N2_N3 0x6a 143227783Sjchandra#define PIC_ITE6_N2_N3 0x6e 144227783Sjchandra#define PIC_ITE7_N2_N3 0x72 145227783Sjchandra#define PIC_ITE_N2_N3(i) (PIC_ITE0_N2_N3 + ((i) * 4)) 146225394Sjchandra 147227783Sjchandra#define PIC_IRT0 0x74 148227783Sjchandra#define PIC_IRT(i) (PIC_IRT0 + ((i) * 2)) 149225394Sjchandra 150227783Sjchandra#define TIMER_CYCLES_MAXVAL 0xffffffffffffffffULL 151225394Sjchandra 152225394Sjchandra/* 153225394Sjchandra * IRT Map 154225394Sjchandra */ 155227783Sjchandra#define PIC_IRT_WD_0_INDEX 0 156227783Sjchandra#define PIC_IRT_WD_1_INDEX 1 157227783Sjchandra#define PIC_IRT_WD_NMI_0_INDEX 2 158227783Sjchandra#define PIC_IRT_WD_NMI_1_INDEX 3 159227783Sjchandra#define PIC_IRT_TIMER_0_INDEX 4 160227783Sjchandra#define PIC_IRT_TIMER_1_INDEX 5 161227783Sjchandra#define PIC_IRT_TIMER_2_INDEX 6 162227783Sjchandra#define PIC_IRT_TIMER_3_INDEX 7 163227783Sjchandra#define PIC_IRT_TIMER_4_INDEX 8 164227783Sjchandra#define PIC_IRT_TIMER_5_INDEX 9 165227783Sjchandra#define PIC_IRT_TIMER_6_INDEX 10 166227783Sjchandra#define PIC_IRT_TIMER_7_INDEX 11 167227783Sjchandra#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX 168227783Sjchandra#define PIC_IRT_TIMER_INDEX(num) ((num) + PIC_IRT_TIMER_0_INDEX) 169225394Sjchandra 170227783Sjchandra#define PIC_CLOCK_TIMER 7 171227783Sjchandra#define PIC_IRQ_BASE 8 172225394Sjchandra 173225394Sjchandra#if !defined(LOCORE) && !defined(__ASSEMBLY__) 174224110Sjchandra 175227783Sjchandra#define PIC_IRT_FIRST_IRQ (PIC_IRQ_BASE) 176227783Sjchandra#define PIC_IRT_LAST_IRQ 63 177233563Sjchandra#define XLP_IRQ_IS_PICINTR(irq) ((irq) >= PIC_IRT_FIRST_IRQ) 178224110Sjchandra 179225394Sjchandra/* 180225394Sjchandra * Misc 181225394Sjchandra */ 182227783Sjchandra#define PIC_IRT_VALID 1 183227783Sjchandra#define PIC_LOCAL_SCHEDULING 1 184227783Sjchandra#define PIC_GLOBAL_SCHEDULING 0 185224110Sjchandra 186227783Sjchandra#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r) 187227783Sjchandra#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v) 188227783Sjchandra#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node)) 189227783Sjchandra#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ) 190224110Sjchandra 191224110Sjchandra/* IRT and h/w interrupt routines */ 192225394Sjchandrastatic inline int 193225394Sjchandranlm_pic_read_irt(uint64_t base, int irt_index) 194224110Sjchandra{ 195225394Sjchandra return nlm_read_pic_reg(base, PIC_IRT(irt_index)); 196224110Sjchandra} 197224110Sjchandra 198225394Sjchandrastatic inline void 199225394Sjchandranlm_pic_send_ipi(uint64_t base, int cpu, int vec, int nmi) 200224110Sjchandra{ 201225394Sjchandra uint64_t ipi; 202225394Sjchandra int node, ncpu; 203224110Sjchandra 204225394Sjchandra node = cpu / 32; 205225394Sjchandra ncpu = cpu & 0x1f; 206225394Sjchandra ipi = ((uint64_t)nmi << 31) | (vec << 20) | (node << 17) | 207225394Sjchandra (1 << (cpu & 0xf)); 208225394Sjchandra if (ncpu > 15) 209225394Sjchandra ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */ 210224110Sjchandra 211225394Sjchandra nlm_write_pic_reg(base, PIC_IPI_CTL, ipi); 212224110Sjchandra} 213224110Sjchandra 214225394Sjchandrastatic inline uint64_t 215225394Sjchandranlm_pic_read_control(uint64_t base) 216224110Sjchandra{ 217225394Sjchandra return nlm_read_pic_reg(base, PIC_CTRL); 218224110Sjchandra} 219224110Sjchandra 220225394Sjchandrastatic inline void 221225394Sjchandranlm_pic_write_control(uint64_t base, uint64_t control) 222224110Sjchandra{ 223225394Sjchandra nlm_write_pic_reg(base, PIC_CTRL, control); 224224110Sjchandra} 225224110Sjchandra 226225394Sjchandrastatic inline void 227225394Sjchandranlm_pic_update_control(uint64_t base, uint64_t control) 228224110Sjchandra{ 229225394Sjchandra uint64_t val; 230224110Sjchandra 231225394Sjchandra val = nlm_read_pic_reg(base, PIC_CTRL); 232225394Sjchandra nlm_write_pic_reg(base, PIC_CTRL, control | val); 233224110Sjchandra} 234224110Sjchandra 235225394Sjchandrastatic inline void 236225394Sjchandranlm_pic_ack(uint64_t base, int irt_num) 237224110Sjchandra{ 238225394Sjchandra nlm_write_pic_reg(base, PIC_INT_ACK, irt_num); 239224110Sjchandra 240225394Sjchandra /* Ack the Status register for Watchdog & System timers */ 241225394Sjchandra if (irt_num < 12) 242225394Sjchandra nlm_write_pic_reg(base, PIC_STATUS, (1 << irt_num)); 243224110Sjchandra} 244224110Sjchandra 245225394Sjchandrastatic inline void 246225394Sjchandranlm_set_irt_to_cpu(uint64_t base, int irt, int cpu) 247224110Sjchandra{ 248225394Sjchandra uint64_t val; 249224110Sjchandra 250225394Sjchandra val = nlm_read_pic_reg(base, PIC_IRT(irt)); 251225394Sjchandra val |= cpu & 0xf; 252225394Sjchandra if (cpu > 15) 253225394Sjchandra val |= 1 << 16; 254225394Sjchandra nlm_write_pic_reg(base, PIC_IRT(irt), val); 255224110Sjchandra} 256224110Sjchandra 257225394Sjchandrastatic inline void 258225394Sjchandranlm_pic_write_irt(uint64_t base, int irt_num, int en, int nmi, 259225394Sjchandra int sch, int vec, int dt, int db, int dte) 260224110Sjchandra{ 261225394Sjchandra uint64_t val; 262224110Sjchandra 263225394Sjchandra val = (((uint64_t)en & 0x1) << 31) | ((nmi & 0x1) << 29) | 264225394Sjchandra ((sch & 0x1) << 28) | ((vec & 0x3f) << 20) | 265225394Sjchandra ((dt & 0x1) << 19) | ((db & 0x7) << 16) | 266225394Sjchandra (dte & 0xffff); 267224110Sjchandra 268225394Sjchandra nlm_write_pic_reg(base, PIC_IRT(irt_num), val); 269224110Sjchandra} 270224110Sjchandra 271225394Sjchandrastatic inline void 272225394Sjchandranlm_pic_write_irt_direct(uint64_t base, int irt_num, int en, int nmi, 273225394Sjchandra int sch, int vec, int cpu) 274224110Sjchandra{ 275225394Sjchandra nlm_pic_write_irt(base, irt_num, en, nmi, sch, vec, 1, 276225394Sjchandra (cpu >> 4), /* thread group */ 277225394Sjchandra 1 << (cpu & 0xf)); /* thread mask */ 278224110Sjchandra} 279224110Sjchandra 280225394Sjchandrastatic inline uint64_t 281225394Sjchandranlm_pic_read_timer(uint64_t base, int timer) 282225394Sjchandra{ 283225394Sjchandra return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer)); 284225394Sjchandra} 285224110Sjchandra 286225394Sjchandrastatic inline void 287225394Sjchandranlm_pic_write_timer(uint64_t base, int timer, uint64_t value) 288224110Sjchandra{ 289225394Sjchandra nlm_write_pic_reg(base, PIC_TIMER_COUNT(timer), value); 290224110Sjchandra} 291224110Sjchandra 292225394Sjchandrastatic inline void 293225394Sjchandranlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu) 294224110Sjchandra{ 295227783Sjchandra uint64_t pic_ctrl; 296227783Sjchandra int en, nmi; 297224110Sjchandra 298227783Sjchandra en = nmi = 0; 299227783Sjchandra if (irq > 0) 300227783Sjchandra en = 1; 301227783Sjchandra else if (irq < 0) { 302227783Sjchandra en = nmi = 1; 303227783Sjchandra irq = -irq; 304227783Sjchandra } 305225394Sjchandra nlm_write_pic_reg(base, PIC_TIMER_MAXVAL(timer), value); 306225394Sjchandra nlm_pic_write_irt_direct(base, PIC_IRT_TIMER_INDEX(timer), 307227783Sjchandra en, nmi, 0, irq, cpu); 308225394Sjchandra 309225394Sjchandra /* enable the timer */ 310227783Sjchandra pic_ctrl = nlm_read_pic_reg(base, PIC_CTRL); 311225394Sjchandra pic_ctrl |= (1 << (PIC_CTRL_STE + timer)); 312225394Sjchandra nlm_write_pic_reg(base, PIC_CTRL, pic_ctrl); 313224110Sjchandra} 314224110Sjchandra 315225394Sjchandra#endif /* __ASSEMBLY__ */ 316225394Sjchandra#endif /* _NLM_HAL_PIC_H */ 317