1 /* 2 * Copyright 2013 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 */ 24 25 #define GT215 0xa3 26 #define GF100 0xc0 27 #define GF119 0xd9 28 #define GK208 0x108 29 30 #include "os.h" 31 32 // IO addresses 33 #define NV_PPWR_INTR_TRIGGER 0x0000 34 #define NV_PPWR_INTR_TRIGGER_USER1 0x00000080 35 #define NV_PPWR_INTR_TRIGGER_USER0 0x00000040 36 #define NV_PPWR_INTR_ACK 0x0004 37 #define NV_PPWR_INTR_ACK_SUBINTR 0x00000800 38 #define NV_PPWR_INTR_ACK_WATCHDOG 0x00000002 39 #define NV_PPWR_INTR 0x0008 40 #define NV_PPWR_INTR_SUBINTR 0x00000800 41 #define NV_PPWR_INTR_USER1 0x00000080 42 #define NV_PPWR_INTR_USER0 0x00000040 43 #define NV_PPWR_INTR_PAUSE 0x00000020 44 #define NV_PPWR_INTR_WATCHDOG 0x00000002 45 #define NV_PPWR_INTR_EN_SET 0x0010 46 #define NV_PPWR_INTR_EN_SET_SUBINTR 0x00000800 47 #define NV_PPWR_INTR_EN_SET_WATCHDOG 0x00000002 48 #define NV_PPWR_INTR_EN_CLR 0x0014 49 #define NV_PPWR_INTR_EN_CLR_MASK /* fuck i hate envyas */ -1 50 #define NV_PPWR_INTR_ROUTE 0x001c 51 #define NV_PPWR_TIMER_LOW 0x002c 52 #define NV_PPWR_WATCHDOG_TIME 0x0034 53 #define NV_PPWR_WATCHDOG_ENABLE 0x0038 54 #define NV_PPWR_CAPS 0x0108 55 #define NV_PPWR_UAS_CONFIG 0x0164 56 #define NV_PPWR_UAS_CONFIG_ENABLE 0x00010000 57 #if NVKM_PPWR_CHIPSET >= GK208 58 #define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x0450) 59 #endif 60 #define NV_PPWR_FIFO_PUT(i) (4 * (i) + 0x04a0) 61 #define NV_PPWR_FIFO_GET(i) (4 * (i) + 0x04b0) 62 #define NV_PPWR_FIFO_INTR 0x04c0 63 #define NV_PPWR_FIFO_INTR_EN 0x04c4 64 #define NV_PPWR_RFIFO_PUT 0x04c8 65 #define NV_PPWR_RFIFO_GET 0x04cc 66 #define NV_PPWR_H2D 0x04d0 67 #define NV_PPWR_D2H 0x04dc 68 #if NVKM_PPWR_CHIPSET < GK208 69 #define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x05d0) 70 #endif 71 #define NV_PPWR_SUBINTR 0x0688 72 #define NV_PPWR_SUBINTR_FIFO 0x00000002 73 #define NV_PPWR_MMIO_ADDR 0x07a0 74 #define NV_PPWR_MMIO_DATA 0x07a4 75 #define NV_PPWR_MMIO_CTRL 0x07ac 76 #define NV_PPWR_MMIO_CTRL_TRIGGER 0x00010000 77 #define NV_PPWR_MMIO_CTRL_STATUS 0x00007000 78 #define NV_PPWR_MMIO_CTRL_STATUS_IDLE 0x00000000 79 #define NV_PPWR_MMIO_CTRL_MASK 0x000000f0 80 #define NV_PPWR_MMIO_CTRL_MASK_B32_0 0x000000f0 81 #define NV_PPWR_MMIO_CTRL_OP 0x00000003 82 #define NV_PPWR_MMIO_CTRL_OP_RD 0x00000001 83 #define NV_PPWR_MMIO_CTRL_OP_WR 0x00000002 84 #define NV_PPWR_OUTPUT 0x07c0 85 #define NV_PPWR_OUTPUT_FB_PAUSE 0x00000004 86 #if NVKM_PPWR_CHIPSET < GF119 87 #define NV_PPWR_OUTPUT_I2C_3_SCL 0x00000100 88 #define NV_PPWR_OUTPUT_I2C_3_SDA 0x00000200 89 #define NV_PPWR_OUTPUT_I2C_0_SCL 0x00001000 90 #define NV_PPWR_OUTPUT_I2C_0_SDA 0x00002000 91 #define NV_PPWR_OUTPUT_I2C_1_SCL 0x00004000 92 #define NV_PPWR_OUTPUT_I2C_1_SDA 0x00008000 93 #define NV_PPWR_OUTPUT_I2C_2_SCL 0x00010000 94 #define NV_PPWR_OUTPUT_I2C_2_SDA 0x00020000 95 #define NV_PPWR_OUTPUT_I2C_4_SCL 0x00040000 96 #define NV_PPWR_OUTPUT_I2C_4_SDA 0x00080000 97 #define NV_PPWR_OUTPUT_I2C_5_SCL 0x00100000 98 #define NV_PPWR_OUTPUT_I2C_5_SDA 0x00200000 99 #define NV_PPWR_OUTPUT_I2C_6_SCL 0x00400000 100 #define NV_PPWR_OUTPUT_I2C_6_SDA 0x00800000 101 #define NV_PPWR_OUTPUT_I2C_7_SCL 0x01000000 102 #define NV_PPWR_OUTPUT_I2C_7_SDA 0x02000000 103 #define NV_PPWR_OUTPUT_I2C_8_SCL 0x04000000 104 #define NV_PPWR_OUTPUT_I2C_8_SDA 0x08000000 105 #define NV_PPWR_OUTPUT_I2C_9_SCL 0x10000000 106 #define NV_PPWR_OUTPUT_I2C_9_SDA 0x20000000 107 #else 108 #define NV_PPWR_OUTPUT_I2C_0_SCL 0x00000400 109 #define NV_PPWR_OUTPUT_I2C_1_SCL 0x00000800 110 #define NV_PPWR_OUTPUT_I2C_2_SCL 0x00001000 111 #define NV_PPWR_OUTPUT_I2C_3_SCL 0x00002000 112 #define NV_PPWR_OUTPUT_I2C_4_SCL 0x00004000 113 #define NV_PPWR_OUTPUT_I2C_5_SCL 0x00008000 114 #define NV_PPWR_OUTPUT_I2C_6_SCL 0x00010000 115 #define NV_PPWR_OUTPUT_I2C_7_SCL 0x00020000 116 #define NV_PPWR_OUTPUT_I2C_8_SCL 0x00040000 117 #define NV_PPWR_OUTPUT_I2C_9_SCL 0x00080000 118 #define NV_PPWR_OUTPUT_I2C_0_SDA 0x00100000 119 #define NV_PPWR_OUTPUT_I2C_1_SDA 0x00200000 120 #define NV_PPWR_OUTPUT_I2C_2_SDA 0x00400000 121 #define NV_PPWR_OUTPUT_I2C_3_SDA 0x00800000 122 #define NV_PPWR_OUTPUT_I2C_4_SDA 0x01000000 123 #define NV_PPWR_OUTPUT_I2C_5_SDA 0x02000000 124 #define NV_PPWR_OUTPUT_I2C_6_SDA 0x04000000 125 #define NV_PPWR_OUTPUT_I2C_7_SDA 0x08000000 126 #define NV_PPWR_OUTPUT_I2C_8_SDA 0x10000000 127 #define NV_PPWR_OUTPUT_I2C_9_SDA 0x20000000 128 #endif 129 #define NV_PPWR_INPUT 0x07c4 130 #define NV_PPWR_OUTPUT_SET 0x07e0 131 #define NV_PPWR_OUTPUT_SET_FB_PAUSE 0x00000004 132 #define NV_PPWR_OUTPUT_CLR 0x07e4 133 #define NV_PPWR_OUTPUT_CLR_FB_PAUSE 0x00000004 134 135 // Inter-process message format 136 .equ #msg_process 0x00 /* send() target, recv() sender */ 137 .equ #msg_message 0x04 138 .equ #msg_data0 0x08 139 .equ #msg_data1 0x0c 140 141 // Kernel message IDs 142 #define KMSG_FIFO 0x00000000 143 #define KMSG_ALARM 0x00000001 144 145 // Process message queue description 146 .equ #proc_qlen 4 // log2(size of queue entry in bytes) 147 .equ #proc_qnum 2 // log2(max number of entries in queue) 148 .equ #proc_qmaskb (1 << #proc_qnum) // max number of entries in queue 149 .equ #proc_qmaskp (#proc_qmaskb - 1) 150 .equ #proc_qmaskf ((#proc_qmaskb << 1) - 1) 151 .equ #proc_qsize (1 << (#proc_qlen + #proc_qnum)) 152 153 // Process table entry 154 .equ #proc_id 0x00 155 .equ #proc_init 0x04 156 .equ #proc_recv 0x08 157 .equ #proc_time 0x0c 158 .equ #proc_qput 0x10 159 .equ #proc_qget 0x14 160 .equ #proc_queue 0x18 161 .equ #proc_size (0x18 + #proc_qsize) 162 163 #define process(id,init,recv) /* 164 */ .b32 id /* 165 */ .b32 init /* 166 */ .b32 recv /* 167 */ .b32 0 /* 168 */ .b32 0 /* 169 */ .b32 0 /* 170 */ .skip 64 171 172 #if NVKM_PPWR_CHIPSET < GK208 173 #define imm32(reg,val) /* 174 */ movw reg ((val) & 0x0000ffff) /* 175 */ sethi reg ((val) & 0xffff0000) 176 #else 177 #define imm32(reg,val) /* 178 */ mov reg (val) 179 #endif 180 181 #ifndef NVKM_FALCON_UNSHIFTED_IO 182 #define nv_iord(reg,ior) /* 183 */ mov reg ior /* 184 */ shl b32 reg 6 /* 185 */ iord reg I[reg + 0x000] 186 #else 187 #define nv_iord(reg,ior) /* 188 */ mov reg ior /* 189 */ iord reg I[reg + 0x000] 190 #endif 191 192 #ifndef NVKM_FALCON_UNSHIFTED_IO 193 #define nv_iowr(ior,reg) /* 194 */ mov $r0 ior /* 195 */ shl b32 $r0 6 /* 196 */ iowr I[$r0 + 0x000] reg /* 197 */ clear b32 $r0 198 #else 199 #define nv_iowr(ior,reg) /* 200 */ mov $r0 ior /* 201 */ iowr I[$r0 + 0x000] reg /* 202 */ clear b32 $r0 203 #endif 204 205 #ifndef NVKM_FALCON_UNSHIFTED_IO 206 #define nv_iowrs(ior,reg) /* 207 */ mov $r0 ior /* 208 */ shl b32 $r0 6 /* 209 */ iowrs I[$r0 + 0x000] reg /* 210 */ clear b32 $r0 211 #else 212 #define nv_iowrs(ior,reg) /* 213 */ mov $r0 ior /* 214 */ iowrs I[$r0 + 0x000] reg /* 215 */ clear b32 $r0 216 #endif 217 218 #define hash # 219 #define fn(a) a 220 #ifndef NVKM_FALCON_PC24 221 #define call(a) call fn(hash)a 222 #else 223 #define call(a) lcall fn(hash)a 224 #endif 225 226 #ifndef NVKM_FALCON_MMIO_UAS 227 #define nv_rd32(reg,addr) /* 228 */ mov b32 $r14 addr /* 229 */ call(rd32) /* 230 */ mov b32 reg $r13 231 #else 232 #define nv_rd32(reg,addr) /* 233 */ sethi $r0 0x14000000 /* 234 */ or $r0 addr /* 235 */ ld b32 reg D[$r0] /* 236 */ clear b32 $r0 237 #endif 238 239 #if !defined(NVKM_FALCON_MMIO_UAS) || defined(NVKM_FALCON_MMIO_TRAP) 240 #define nv_wr32(addr,reg) /* 241 */ push addr /* 242 */ push reg /* 243 */ pop $r13 /* 244 */ pop $r14 /* 245 */ call(wr32) 246 #else 247 #define nv_wr32(addr,reg) /* 248 */ sethi $r0 0x14000000 /* 249 */ or $r0 addr /* 250 */ st b32 D[$r0] reg /* 251 */ clear b32 $r0 252 #endif 253 254 #define st(size, addr, reg) /* 255 */ imm32($r0, addr) /* 256 */ st size D[$r0] reg /* 257 */ clear b32 $r0 258 259 #define ld(size, reg, addr) /* 260 */ imm32($r0, addr) /* 261 */ ld size reg D[$r0] /* 262 */ clear b32 $r0 263 264 // does a 64+64 -> 64 unsigned addition (C = A + B) 265 #define addu64(reg_a_c_hi, reg_a_c_lo, b_hi, b_lo) /* 266 */ add b32 reg_a_c_lo b_lo /* 267 */ adc b32 reg_a_c_hi b_hi 268 269 // does a 64+64 -> 64 substraction (C = A - B) 270 #define subu64(reg_a_c_hi, reg_a_c_lo, b_hi, b_lo) /* 271 */ sub b32 reg_a_c_lo b_lo /* 272 */ sbb b32 reg_a_c_hi b_hi 273