1198160Srrs/*- 2198160Srrs * Copyright (c) 2003-2009 RMI Corporation 3198160Srrs * All rights reserved. 4198160Srrs * 5198160Srrs * Redistribution and use in source and binary forms, with or without 6198160Srrs * modification, are permitted provided that the following conditions 7198160Srrs * are met: 8198160Srrs * 1. Redistributions of source code must retain the above copyright 9198160Srrs * notice, this list of conditions and the following disclaimer. 10198160Srrs * 2. Redistributions in binary form must reproduce the above copyright 11198160Srrs * notice, this list of conditions and the following disclaimer in the 12198160Srrs * documentation and/or other materials provided with the distribution. 13198160Srrs * 3. Neither the name of RMI Corporation, nor the names of its contributors, 14198160Srrs * may be used to endorse or promote products derived from this software 15198160Srrs * without specific prior written permission. 16198160Srrs * 17198160Srrs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18198160Srrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19198160Srrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20198160Srrs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21198160Srrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22198160Srrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23198160Srrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24198160Srrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25198160Srrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26198160Srrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27198160Srrs * SUCH DAMAGE. 28198160Srrs * 29211994Sjchandra * RMI_BSD 30211994Sjchandra * $FreeBSD$ 31211994Sjchandra */ 32198160Srrs#ifndef _RMI_PIC_H_ 33211893Sjchandra#define _RMI_PIC_H_ 34211893Sjchandra 35203009Srrs#include <sys/cdefs.h> 36198160Srrs#include <sys/lock.h> 37198160Srrs#include <sys/mutex.h> 38198607Srrs#include <mips/rmi/iomap.h> 39198160Srrs 40211811Sjchandra#define PIC_IRT_WD_INDEX 0 41211811Sjchandra#define PIC_IRT_TIMER_INDEX(i) (1 + (i)) 42211811Sjchandra#define PIC_IRT_UART_0_INDEX 9 43211811Sjchandra#define PIC_IRT_UART_1_INDEX 10 44211811Sjchandra#define PIC_IRT_I2C_0_INDEX 11 45211811Sjchandra#define PIC_IRT_I2C_1_INDEX 12 46211811Sjchandra#define PIC_IRT_PCMCIA_INDEX 13 47211811Sjchandra#define PIC_IRT_GPIO_INDEX 14 48211811Sjchandra#define PIC_IRT_HYPER_INDEX 15 49211811Sjchandra#define PIC_IRT_PCIX_INDEX 16 50211811Sjchandra#define PIC_IRT_GMAC0_INDEX 17 51211811Sjchandra#define PIC_IRT_GMAC1_INDEX 18 52211811Sjchandra#define PIC_IRT_GMAC2_INDEX 19 53211811Sjchandra#define PIC_IRT_GMAC3_INDEX 20 54211811Sjchandra#define PIC_IRT_XGS0_INDEX 21 55211811Sjchandra#define PIC_IRT_XGS1_INDEX 22 56211811Sjchandra#define PIC_IRT_HYPER_FATAL_INDEX 23 57211811Sjchandra#define PIC_IRT_PCIX_FATAL_INDEX 24 58211811Sjchandra#define PIC_IRT_BRIDGE_AERR_INDEX 25 59211811Sjchandra#define PIC_IRT_BRIDGE_BERR_INDEX 26 60211811Sjchandra#define PIC_IRT_BRIDGE_TB_INDEX 27 61211811Sjchandra#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28 62198160Srrs 63198160Srrs/* numbering for XLS */ 64211811Sjchandra#define PIC_IRT_BRIDGE_ERR_INDEX 25 65211811Sjchandra#define PIC_IRT_PCIE_LINK0_INDEX 26 66211811Sjchandra#define PIC_IRT_PCIE_LINK1_INDEX 27 67211811Sjchandra#define PIC_IRT_PCIE_LINK2_INDEX 23 68211811Sjchandra#define PIC_IRT_PCIE_LINK3_INDEX 24 69213199Sjchandra#define PIC_IRT_PCIE_B0_LINK2_INDEX 28 70213199Sjchandra#define PIC_IRT_PCIE_B0_LINK3_INDEX 29 71211811Sjchandra#define PIC_IRT_PCIE_INT_INDEX 28 72211811Sjchandra#define PIC_IRT_PCIE_FATAL_INDEX 29 73211811Sjchandra#define PIC_IRT_GPIO_B_INDEX 30 74211811Sjchandra#define PIC_IRT_USB_INDEX 31 75211811Sjchandra#define PIC_NUM_IRTS 32 76198160Srrs 77211811Sjchandra#define PIC_CLOCK_TIMER 7 78198160Srrs 79211811Sjchandra#define PIC_CTRL 0x00 80211811Sjchandra#define PIC_IPI 0x04 81211811Sjchandra#define PIC_INT_ACK 0x06 82198160Srrs 83211811Sjchandra#define WD_MAX_VAL_0 0x08 84211811Sjchandra#define WD_MAX_VAL_1 0x09 85211811Sjchandra#define WD_MASK_0 0x0a 86211811Sjchandra#define WD_MASK_1 0x0b 87211811Sjchandra#define WD_HEARBEAT_0 0x0c 88211811Sjchandra#define WD_HEARBEAT_1 0x0d 89198160Srrs 90211811Sjchandra#define PIC_IRT_0_BASE 0x40 91211811Sjchandra#define PIC_IRT_1_BASE 0x80 92211811Sjchandra#define PIC_TIMER_MAXVAL_0_BASE 0x100 93211811Sjchandra#define PIC_TIMER_MAXVAL_1_BASE 0x110 94211811Sjchandra#define PIC_TIMER_COUNT_0_BASE 0x120 95211811Sjchandra#define PIC_TIMER_COUNT_1_BASE 0x130 96198160Srrs 97211811Sjchandra#define PIC_IRT_0(picintr) (PIC_IRT_0_BASE + (picintr)) 98211811Sjchandra#define PIC_IRT_1(picintr) (PIC_IRT_1_BASE + (picintr)) 99198160Srrs 100211811Sjchandra#define PIC_TIMER_MAXVAL_0(i) (PIC_TIMER_MAXVAL_0_BASE + (i)) 101211811Sjchandra#define PIC_TIMER_MAXVAL_1(i) (PIC_TIMER_MAXVAL_1_BASE + (i)) 102211811Sjchandra#define PIC_TIMER_COUNT_0(i) (PIC_TIMER_COUNT_0_BASE + (i)) 103211811Sjchandra#define PIC_TIMER_COUNT_1(i) (PIC_TIMER_COUNT_0_BASE + (i)) 104211814Sjchandra#define PIC_TIMER_HZ 66000000U 105198160Srrs 106211812Sjchandra/* 107211812Sjchandra * We use a simple mapping form PIC interrupts to CPU IRQs. 108211812Sjchandra * The PIC interrupts 0-31 are mapped to CPU irq's 8-39. 109211812Sjchandra * this leaves the lower 0-7 for the cpu interrupts (like 110211812Sjchandra * count/compare, msgrng) and 40-63 for IPIs 111211812Sjchandra */ 112211811Sjchandra#define PIC_IRQ_BASE 8 113211812Sjchandra#define PIC_INTR_TO_IRQ(i) (PIC_IRQ_BASE + (i)) 114211893Sjchandra#define PIC_IRQ_TO_INTR(i) ((i) - PIC_IRQ_BASE) 115198160Srrs 116211811Sjchandra#define PIC_WD_IRQ (PIC_IRQ_BASE + PIC_IRT_WD_INDEX) 117211811Sjchandra#define PIC_TIMER_IRQ(i) (PIC_IRQ_BASE + PIC_IRT_TIMER_INDEX(i)) 118211811Sjchandra#define PIC_CLOCK_IRQ PIC_TIMER_IRQ(PIC_CLOCK_TIMER) 119198160Srrs 120211811Sjchandra#define PIC_UART_0_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_0_INDEX) 121211811Sjchandra#define PIC_UART_1_IRQ (PIC_IRQ_BASE + PIC_IRT_UART_1_INDEX) 122211811Sjchandra#define PIC_I2C_0_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_0_INDEX) 123211811Sjchandra#define PIC_I2C_1_IRQ (PIC_IRQ_BASE + PIC_IRT_I2C_1_INDEX) 124211811Sjchandra#define PIC_PCMCIA_IRQ (PIC_IRQ_BASE + PIC_IRT_PCMCIA_INDEX) 125211811Sjchandra#define PIC_GPIO_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_INDEX) 126211811Sjchandra#define PIC_HYPER_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_INDEX) 127211811Sjchandra#define PIC_PCIX_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_INDEX) 128211811Sjchandra#define PIC_GMAC_0_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC0_INDEX) 129211811Sjchandra#define PIC_GMAC_1_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC1_INDEX) 130211811Sjchandra#define PIC_GMAC_2_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC2_INDEX) 131211811Sjchandra#define PIC_GMAC_3_IRQ (PIC_IRQ_BASE + PIC_IRT_GMAC3_INDEX) 132211811Sjchandra#define PIC_XGS_0_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS0_INDEX) 133211811Sjchandra#define PIC_XGS_1_IRQ (PIC_IRQ_BASE + PIC_IRT_XGS1_INDEX) 134211811Sjchandra#define PIC_HYPER_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_HYPER_FATAL_INDEX) 135211811Sjchandra#define PIC_PCIX_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIX_FATAL_INDEX) 136211811Sjchandra#define PIC_BRIDGE_AERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_INDEX) 137211811Sjchandra#define PIC_BRIDGE_BERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_BERR_INDEX) 138211811Sjchandra#define PIC_BRIDGE_TB_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_TB_INDEX) 139211811Sjchandra#define PIC_BRIDGE_AERR_NMI_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_AERR_NMI_INDEX) 140211811Sjchandra#define PIC_BRIDGE_ERR_IRQ (PIC_IRQ_BASE + PIC_IRT_BRIDGE_ERR_INDEX) 141211811Sjchandra#define PIC_PCIE_LINK0_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK0_INDEX) 142211811Sjchandra#define PIC_PCIE_LINK1_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK1_INDEX) 143211811Sjchandra#define PIC_PCIE_LINK2_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK2_INDEX) 144211811Sjchandra#define PIC_PCIE_LINK3_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_LINK3_INDEX) 145213199Sjchandra#define PIC_PCIE_B0_LINK2_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_B0_LINK2_INDEX) 146213199Sjchandra#define PIC_PCIE_B0_LINK3_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_B0_LINK3_INDEX) 147213199Sjchandra#define PIC_PCIE_INT_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_INT_INDEX) 148211811Sjchandra#define PIC_PCIE_FATAL_IRQ (PIC_IRQ_BASE + PIC_IRT_PCIE_FATAL_INDEX) 149211811Sjchandra#define PIC_GPIO_B_IRQ (PIC_IRQ_BASE + PIC_IRT_GPIO_B_INDEX) 150211811Sjchandra#define PIC_USB_IRQ (PIC_IRQ_BASE + PIC_IRT_USB_INDEX) 151198160Srrs 152211893Sjchandra#define PIC_IRQ_IS_PICINTR(irq) ((irq) >= PIC_IRQ_BASE && \ 153211893Sjchandra (irq) < PIC_IRQ_BASE + PIC_NUM_IRTS) 154211893Sjchandra#define PIC_IS_EDGE_TRIGGERED(i) ((i) >= PIC_IRT_TIMER_INDEX(0) && \ 155211893Sjchandra (i) <= PIC_IRT_TIMER_INDEX(7)) 156198160Srrs 157198160Srrsextern struct mtx xlr_pic_lock; 158198160Srrs 159211811Sjchandrastatic __inline uint32_t 160211811Sjchandrapic_read_control(void) 161198160Srrs{ 162198625Srrs xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 163211811Sjchandra uint32_t reg; 164198625Srrs 165211811Sjchandra mtx_lock_spin(&xlr_pic_lock); 166217625Sjchandra reg = xlr_read_reg(mmio, PIC_CTRL); 167211811Sjchandra mtx_unlock_spin(&xlr_pic_lock); 168211811Sjchandra return (reg); 169198160Srrs} 170198160Srrs 171211811Sjchandrastatic __inline void 172211811Sjchandrapic_write_control(uint32_t control) 173198160Srrs{ 174198625Srrs xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 175198625Srrs 176211811Sjchandra mtx_lock_spin(&xlr_pic_lock); 177198625Srrs xlr_write_reg(mmio, PIC_CTRL, control); 178211811Sjchandra mtx_unlock_spin(&xlr_pic_lock); 179198160Srrs} 180211811Sjchandra 181211811Sjchandrastatic __inline void 182217625Sjchandrapic_update_control(uint32_t control) 183198160Srrs{ 184198625Srrs xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 185198625Srrs 186211811Sjchandra mtx_lock_spin(&xlr_pic_lock); 187198625Srrs xlr_write_reg(mmio, PIC_CTRL, (control | xlr_read_reg(mmio, PIC_CTRL))); 188211811Sjchandra mtx_unlock_spin(&xlr_pic_lock); 189198160Srrs} 190198160Srrs 191211811Sjchandrastatic __inline void 192211893Sjchandrapic_ack(int picintr) 193198160Srrs{ 194198625Srrs xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 195198160Srrs 196212102Sjchandra xlr_write_reg(mmio, PIC_INT_ACK, 1U << picintr); 197198160Srrs} 198198160Srrs 199211811Sjchandrastatic __inline 200211811Sjchandravoid pic_send_ipi(int cpu, int ipi) 201208165Srrs{ 202211811Sjchandra xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 203211811Sjchandra int tid, pid; 204211811Sjchandra 205211811Sjchandra tid = cpu & 0x3; 206211811Sjchandra pid = (cpu >> 2) & 0x7; 207211811Sjchandra xlr_write_reg(mmio, PIC_IPI, (pid << 20) | (tid << 16) | ipi); 208211811Sjchandra} 209211811Sjchandra 210211811Sjchandrastatic __inline 211211893Sjchandravoid pic_setup_intr(int picintr, int irq, uint32_t cpumask, int level) 212211811Sjchandra{ 213208165Srrs xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 214208165Srrs 215211811Sjchandra mtx_lock_spin(&xlr_pic_lock); 216211811Sjchandra xlr_write_reg(mmio, PIC_IRT_0(picintr), cpumask); 217261455Seadler xlr_write_reg(mmio, PIC_IRT_1(picintr), ((1U << 31) | (level << 30) | 218211811Sjchandra (1 << 6) | irq)); 219211811Sjchandra mtx_unlock_spin(&xlr_pic_lock); 220208165Srrs} 221208165Srrs 222211814Sjchandrastatic __inline void 223211814Sjchandrapic_init_timer(int timer) 224211814Sjchandra{ 225211814Sjchandra xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 226211814Sjchandra uint32_t val; 227211814Sjchandra 228211814Sjchandra mtx_lock_spin(&xlr_pic_lock); 229211814Sjchandra val = xlr_read_reg(mmio, PIC_CTRL); 230211814Sjchandra val |= (1 << (8 + timer)); 231211814Sjchandra xlr_write_reg(mmio, PIC_CTRL, val); 232211814Sjchandra mtx_unlock_spin(&xlr_pic_lock); 233211814Sjchandra} 234211814Sjchandra 235211814Sjchandrastatic __inline void 236211814Sjchandrapic_set_timer(int timer, uint64_t maxval) 237211814Sjchandra{ 238211814Sjchandra xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 239211814Sjchandra 240211814Sjchandra xlr_write_reg(mmio, PIC_TIMER_MAXVAL_0(timer), 241211814Sjchandra (maxval & 0xffffffff)); 242211814Sjchandra xlr_write_reg(mmio, PIC_TIMER_MAXVAL_1(timer), 243211814Sjchandra (maxval >> 32) & 0xffffffff); 244211814Sjchandra} 245211814Sjchandra 246211814Sjchandrastatic __inline uint32_t 247211814Sjchandrapic_timer_count32(int timer) 248211814Sjchandra { 249211814Sjchandra xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 250211814Sjchandra 251211814Sjchandra return (xlr_read_reg(mmio, PIC_TIMER_COUNT_0(timer))); 252211814Sjchandra} 253211814Sjchandra 254211814Sjchandra/* 255211814Sjchandra * The timer can wrap 32 bits between the two reads, so we 256211814Sjchandra * need additional logic to detect that. 257211814Sjchandra */ 258211814Sjchandrastatic __inline uint64_t 259211814Sjchandrapic_timer_count(int timer) 260211814Sjchandra{ 261211814Sjchandra xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); 262211814Sjchandra uint32_t tu1, tu2, tl; 263211814Sjchandra 264211814Sjchandra tu1 = xlr_read_reg(mmio, PIC_TIMER_COUNT_1(timer)); 265211814Sjchandra tl = xlr_read_reg(mmio, PIC_TIMER_COUNT_0(timer)); 266211814Sjchandra tu2 = xlr_read_reg(mmio, PIC_TIMER_COUNT_1(timer)); 267211814Sjchandra if (tu2 != tu1) 268211814Sjchandra tl = xlr_read_reg(mmio, PIC_TIMER_COUNT_0(timer)); 269211814Sjchandra return (((uint64_t)tu2 << 32) | tl); 270211814Sjchandra} 271211814Sjchandra 272211811Sjchandra#endif /* _RMI_PIC_H_ */ 273