1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * NETLOGIC_BSD 31 * $FreeBSD$ 32 */ 33 34#ifndef _NLM_HAL_PIC_H 35#define _NLM_HAL_PIC_H 36 37/* PIC Specific registers */ 38#define PIC_CTRL 0x00 39 40/* PIC control register defines */ 41#define PIC_CTRL_ITV 32 /* interrupt timeout value */ 42#define PIC_CTRL_ICI 19 /* ICI interrupt timeout enable */ 43#define PIC_CTRL_ITE 18 /* interrupt timeout enable */ 44#define PIC_CTRL_STE 10 /* system timer interrupt enable */ 45#define PIC_CTRL_WWR1 8 /* watchdog 1 wraparound count for reset */ 46#define PIC_CTRL_WWR0 6 /* watchdog 0 wraparound count for reset */ 47#define PIC_CTRL_WWN1 4 /* watchdog 1 wraparound count for NMI */ 48#define PIC_CTRL_WWN0 2 /* watchdog 0 wraparound count for NMI */ 49#define PIC_CTRL_WTE 0 /* watchdog timer enable */ 50 51/* PIC Status register defines */ 52#define PIC_ICI_STATUS 33 /* ICI interrupt timeout status */ 53#define PIC_ITE_STATUS 32 /* interrupt timeout status */ 54#define PIC_STS_STATUS 4 /* System timer interrupt status */ 55#define PIC_WNS_STATUS 2 /* NMI status for watchdog timers */ 56#define PIC_WIS_STATUS 0 /* Interrupt status for watchdog timers */ 57 58/* PIC IPI control register offsets */ 59#define PIC_IPICTRL_NMI 32 60#define PIC_IPICTRL_RIV 20 /* received interrupt vector */ 61#define PIC_IPICTRL_IDB 16 /* interrupt destination base */ 62#define PIC_IPICTRL_DTE 0 /* interrupt destination thread enables */ 63 64/* PIC IRT register offsets */ 65#define PIC_IRT_ENABLE 31 66#define PIC_IRT_NMI 29 67#define PIC_IRT_SCH 28 /* Scheduling scheme */ 68#define PIC_IRT_RVEC 20 /* Interrupt receive vectors */ 69#define PIC_IRT_DT 19 /* Destination type */ 70#define PIC_IRT_DB 16 /* Destination base */ 71#define PIC_IRT_DTE 0 /* Destination thread enables */ 72 73#define PIC_BYTESWAP 0x02 74#define PIC_STATUS 0x04 75#define PIC_INTR_TIMEOUT 0x06 76#define PIC_ICI0_INTR_TIMEOUT 0x08 77#define PIC_ICI1_INTR_TIMEOUT 0x0a 78#define PIC_ICI2_INTR_TIMEOUT 0x0c 79#define PIC_IPI_CTL 0x0e 80#define PIC_INT_ACK 0x10 81#define PIC_INT_PENDING0 0x12 82#define PIC_INT_PENDING1 0x14 83#define PIC_INT_PENDING2 0x16 84 85#define PIC_WDOG0_MAXVAL 0x18 86#define PIC_WDOG0_COUNT 0x1a 87#define PIC_WDOG0_ENABLE0 0x1c 88#define PIC_WDOG0_ENABLE1 0x1e 89#define PIC_WDOG0_BEATCMD 0x20 90#define PIC_WDOG0_BEAT0 0x22 91#define PIC_WDOG0_BEAT1 0x24 92 93#define PIC_WDOG1_MAXVAL 0x26 94#define PIC_WDOG1_COUNT 0x28 95#define PIC_WDOG1_ENABLE0 0x2a 96#define PIC_WDOG1_ENABLE1 0x2c 97#define PIC_WDOG1_BEATCMD 0x2e 98#define PIC_WDOG1_BEAT0 0x30 99#define PIC_WDOG1_BEAT1 0x32 100 101#define PIC_WDOG_MAXVAL(i) (PIC_WDOG0_MAXVAL + ((i) ? 7 : 0)) 102#define PIC_WDOG_COUNT(i) (PIC_WDOG0_COUNT + ((i) ? 7 : 0)) 103#define PIC_WDOG_ENABLE0(i) (PIC_WDOG0_ENABLE0 + ((i) ? 7 : 0)) 104#define PIC_WDOG_ENABLE1(i) (PIC_WDOG0_ENABLE1 + ((i) ? 7 : 0)) 105#define PIC_WDOG_BEATCMD(i) (PIC_WDOG0_BEATCMD + ((i) ? 7 : 0)) 106#define PIC_WDOG_BEAT0(i) (PIC_WDOG0_BEAT0 + ((i) ? 7 : 0)) 107#define PIC_WDOG_BEAT1(i) (PIC_WDOG0_BEAT1 + ((i) ? 7 : 0)) 108 109#define PIC_TIMER0_MAXVAL 0x34 110#define PIC_TIMER1_MAXVAL 0x36 111#define PIC_TIMER2_MAXVAL 0x38 112#define PIC_TIMER3_MAXVAL 0x3a 113#define PIC_TIMER4_MAXVAL 0x3c 114#define PIC_TIMER5_MAXVAL 0x3e 115#define PIC_TIMER6_MAXVAL 0x40 116#define PIC_TIMER7_MAXVAL 0x42 117#define PIC_TIMER_MAXVAL(i) (PIC_TIMER0_MAXVAL + ((i) * 2)) 118 119#define PIC_TIMER0_COUNT 0x44 120#define PIC_TIMER1_COUNT 0x46 121#define PIC_TIMER2_COUNT 0x48 122#define PIC_TIMER3_COUNT 0x4a 123#define PIC_TIMER4_COUNT 0x4c 124#define PIC_TIMER5_COUNT 0x4e 125#define PIC_TIMER6_COUNT 0x50 126#define PIC_TIMER7_COUNT 0x52 127#define PIC_TIMER_COUNT(i) (PIC_TIMER0_COUNT + ((i) * 2)) 128 129#define PIC_ITE0_N0_N1 0x54 130#define PIC_ITE1_N0_N1 0x58 131#define PIC_ITE2_N0_N1 0x5c 132#define PIC_ITE3_N0_N1 0x60 133#define PIC_ITE4_N0_N1 0x64 134#define PIC_ITE5_N0_N1 0x68 135#define PIC_ITE6_N0_N1 0x6c 136#define PIC_ITE7_N0_N1 0x70 137#define PIC_ITE_N0_N1(i) (PIC_ITE0_N0_N1 + ((i) * 4)) 138 139#define PIC_ITE0_N2_N3 0x56 140#define PIC_ITE1_N2_N3 0x5a 141#define PIC_ITE2_N2_N3 0x5e 142#define PIC_ITE3_N2_N3 0x62 143#define PIC_ITE4_N2_N3 0x66 144#define PIC_ITE5_N2_N3 0x6a 145#define PIC_ITE6_N2_N3 0x6e 146#define PIC_ITE7_N2_N3 0x72 147#define PIC_ITE_N2_N3(i) (PIC_ITE0_N2_N3 + ((i) * 4)) 148 149#define PIC_IRT0 0x74 150#define PIC_IRT(i) (PIC_IRT0 + ((i) * 2)) 151 152#define TIMER_CYCLES_MAXVAL 0xffffffffffffffffULL 153 154/* 155 * IRT Map 156 */ 157#define PIC_IRT_WD_0_INDEX 0 158#define PIC_IRT_WD_1_INDEX 1 159#define PIC_IRT_WD_NMI_0_INDEX 2 160#define PIC_IRT_WD_NMI_1_INDEX 3 161#define PIC_IRT_TIMER_0_INDEX 4 162#define PIC_IRT_TIMER_1_INDEX 5 163#define PIC_IRT_TIMER_2_INDEX 6 164#define PIC_IRT_TIMER_3_INDEX 7 165#define PIC_IRT_TIMER_4_INDEX 8 166#define PIC_IRT_TIMER_5_INDEX 9 167#define PIC_IRT_TIMER_6_INDEX 10 168#define PIC_IRT_TIMER_7_INDEX 11 169#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX 170#define PIC_IRT_TIMER_INDEX(num) ((num) + PIC_IRT_TIMER_0_INDEX) 171 172#define PIC_CLOCK_TIMER 7 173 174#if !defined(LOCORE) && !defined(__ASSEMBLY__) 175 176/* 177 * Misc 178 */ 179#define PIC_IRT_VALID 1 180#define PIC_LOCAL_SCHEDULING 1 181#define PIC_GLOBAL_SCHEDULING 0 182 183#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r) 184#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v) 185#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node)) 186#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ) 187 188/* IRT and h/w interrupt routines */ 189static inline int 190nlm_pic_read_irt(uint64_t base, int irt_index) 191{ 192 return nlm_read_pic_reg(base, PIC_IRT(irt_index)); 193} 194 195static inline void 196nlm_pic_send_ipi(uint64_t base, int cpu, int vec, int nmi) 197{ 198 uint64_t ipi; 199 int node, ncpu; 200 201 node = cpu / 32; 202 ncpu = cpu & 0x1f; 203 ipi = ((uint64_t)nmi << 31) | (vec << 20) | (node << 17) | 204 (1 << (cpu & 0xf)); 205 if (ncpu > 15) 206 ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */ 207 208 nlm_write_pic_reg(base, PIC_IPI_CTL, ipi); 209} 210 211static inline uint64_t 212nlm_pic_read_control(uint64_t base) 213{ 214 return nlm_read_pic_reg(base, PIC_CTRL); 215} 216 217static inline void 218nlm_pic_write_control(uint64_t base, uint64_t control) 219{ 220 nlm_write_pic_reg(base, PIC_CTRL, control); 221} 222 223static inline void 224nlm_pic_update_control(uint64_t base, uint64_t control) 225{ 226 uint64_t val; 227 228 val = nlm_read_pic_reg(base, PIC_CTRL); 229 nlm_write_pic_reg(base, PIC_CTRL, control | val); 230} 231 232static inline void 233nlm_pic_ack(uint64_t base, int irt_num) 234{ 235 nlm_write_pic_reg(base, PIC_INT_ACK, irt_num); 236 237 /* Ack the Status register for Watchdog & System timers */ 238 if (irt_num < 12) 239 nlm_write_pic_reg(base, PIC_STATUS, (1 << irt_num)); 240} 241 242static inline void 243nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu) 244{ 245 uint64_t val; 246 247 val = nlm_read_pic_reg(base, PIC_IRT(irt)); 248 val |= cpu & 0xf; 249 if (cpu > 15) 250 val |= 1 << 16; 251 nlm_write_pic_reg(base, PIC_IRT(irt), val); 252} 253 254static inline void 255nlm_pic_write_irt(uint64_t base, int irt_num, int en, int nmi, 256 int sch, int vec, int dt, int db, int dte) 257{ 258 uint64_t val; 259 260 val = (((uint64_t)en & 0x1) << 31) | ((nmi & 0x1) << 29) | 261 ((sch & 0x1) << 28) | ((vec & 0x3f) << 20) | 262 ((dt & 0x1) << 19) | ((db & 0x7) << 16) | 263 (dte & 0xffff); 264 265 nlm_write_pic_reg(base, PIC_IRT(irt_num), val); 266} 267 268static inline void 269nlm_pic_write_irt_direct(uint64_t base, int irt_num, int en, int nmi, 270 int sch, int vec, int cpu) 271{ 272 nlm_pic_write_irt(base, irt_num, en, nmi, sch, vec, 1, 273 (cpu >> 4), /* thread group */ 274 1 << (cpu & 0xf)); /* thread mask */ 275} 276 277static inline uint64_t 278nlm_pic_read_timer(uint64_t base, int timer) 279{ 280 return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer)); 281} 282 283static inline void 284nlm_pic_write_timer(uint64_t base, int timer, uint64_t value) 285{ 286 nlm_write_pic_reg(base, PIC_TIMER_COUNT(timer), value); 287} 288 289static inline void 290nlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu) 291{ 292 uint64_t pic_ctrl; 293 int en, nmi; 294 295 en = nmi = 0; 296 if (irq > 0) 297 en = 1; 298 else if (irq < 0) { 299 en = nmi = 1; 300 irq = -irq; 301 } 302 nlm_write_pic_reg(base, PIC_TIMER_MAXVAL(timer), value); 303 nlm_pic_write_irt_direct(base, PIC_IRT_TIMER_INDEX(timer), 304 en, nmi, 0, irq, cpu); 305 306 /* enable the timer */ 307 pic_ctrl = nlm_read_pic_reg(base, PIC_CTRL); 308 pic_ctrl |= (1 << (PIC_CTRL_STE + timer)); 309 nlm_write_pic_reg(base, PIC_CTRL, pic_ctrl); 310} 311 312#endif /* __ASSEMBLY__ */ 313#endif /* _NLM_HAL_PIC_H */ 314