273 lines · plain
1/*2 * Copyright 2013 Red Hat Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: Ben Skeggs23 */24 25#define GT215 0xa326#define GF100 0xc027#define GF119 0xd928#define GK208 0x10829 30#include "os.h"31 32// IO addresses33#define NV_PPWR_INTR_TRIGGER 0x000034#define NV_PPWR_INTR_TRIGGER_USER1 0x0000008035#define NV_PPWR_INTR_TRIGGER_USER0 0x0000004036#define NV_PPWR_INTR_ACK 0x000437#define NV_PPWR_INTR_ACK_SUBINTR 0x0000080038#define NV_PPWR_INTR_ACK_WATCHDOG 0x0000000239#define NV_PPWR_INTR 0x000840#define NV_PPWR_INTR_SUBINTR 0x0000080041#define NV_PPWR_INTR_USER1 0x0000008042#define NV_PPWR_INTR_USER0 0x0000004043#define NV_PPWR_INTR_PAUSE 0x0000002044#define NV_PPWR_INTR_WATCHDOG 0x0000000245#define NV_PPWR_INTR_EN_SET 0x001046#define NV_PPWR_INTR_EN_SET_SUBINTR 0x0000080047#define NV_PPWR_INTR_EN_SET_WATCHDOG 0x0000000248#define NV_PPWR_INTR_EN_CLR 0x001449#define NV_PPWR_INTR_EN_CLR_MASK /* fuck i hate envyas */ -150#define NV_PPWR_INTR_ROUTE 0x001c51#define NV_PPWR_TIMER_LOW 0x002c52#define NV_PPWR_WATCHDOG_TIME 0x003453#define NV_PPWR_WATCHDOG_ENABLE 0x003854#define NV_PPWR_CAPS 0x010855#define NV_PPWR_UAS_CONFIG 0x016456#define NV_PPWR_UAS_CONFIG_ENABLE 0x0001000057#if NVKM_PPWR_CHIPSET >= GK20858#define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x0450)59#endif60#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 0x04c063#define NV_PPWR_FIFO_INTR_EN 0x04c464#define NV_PPWR_RFIFO_PUT 0x04c865#define NV_PPWR_RFIFO_GET 0x04cc66#define NV_PPWR_H2D 0x04d067#define NV_PPWR_D2H 0x04dc68#if NVKM_PPWR_CHIPSET < GK20869#define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x05d0)70#endif71#define NV_PPWR_SUBINTR 0x068872#define NV_PPWR_SUBINTR_FIFO 0x0000000273#define NV_PPWR_MMIO_ADDR 0x07a074#define NV_PPWR_MMIO_DATA 0x07a475#define NV_PPWR_MMIO_CTRL 0x07ac76#define NV_PPWR_MMIO_CTRL_TRIGGER 0x0001000077#define NV_PPWR_MMIO_CTRL_STATUS 0x0000700078#define NV_PPWR_MMIO_CTRL_STATUS_IDLE 0x0000000079#define NV_PPWR_MMIO_CTRL_MASK 0x000000f080#define NV_PPWR_MMIO_CTRL_MASK_B32_0 0x000000f081#define NV_PPWR_MMIO_CTRL_OP 0x0000000382#define NV_PPWR_MMIO_CTRL_OP_RD 0x0000000183#define NV_PPWR_MMIO_CTRL_OP_WR 0x0000000284#define NV_PPWR_OUTPUT 0x07c085#define NV_PPWR_OUTPUT_FB_PAUSE 0x0000000486#if NVKM_PPWR_CHIPSET < GF11987#define NV_PPWR_OUTPUT_I2C_3_SCL 0x0000010088#define NV_PPWR_OUTPUT_I2C_3_SDA 0x0000020089#define NV_PPWR_OUTPUT_I2C_0_SCL 0x0000100090#define NV_PPWR_OUTPUT_I2C_0_SDA 0x0000200091#define NV_PPWR_OUTPUT_I2C_1_SCL 0x0000400092#define NV_PPWR_OUTPUT_I2C_1_SDA 0x0000800093#define NV_PPWR_OUTPUT_I2C_2_SCL 0x0001000094#define NV_PPWR_OUTPUT_I2C_2_SDA 0x0002000095#define NV_PPWR_OUTPUT_I2C_4_SCL 0x0004000096#define NV_PPWR_OUTPUT_I2C_4_SDA 0x0008000097#define NV_PPWR_OUTPUT_I2C_5_SCL 0x0010000098#define NV_PPWR_OUTPUT_I2C_5_SDA 0x0020000099#define NV_PPWR_OUTPUT_I2C_6_SCL 0x00400000100#define NV_PPWR_OUTPUT_I2C_6_SDA 0x00800000101#define NV_PPWR_OUTPUT_I2C_7_SCL 0x01000000102#define NV_PPWR_OUTPUT_I2C_7_SDA 0x02000000103#define NV_PPWR_OUTPUT_I2C_8_SCL 0x04000000104#define NV_PPWR_OUTPUT_I2C_8_SDA 0x08000000105#define NV_PPWR_OUTPUT_I2C_9_SCL 0x10000000106#define NV_PPWR_OUTPUT_I2C_9_SDA 0x20000000107#else108#define NV_PPWR_OUTPUT_I2C_0_SCL 0x00000400109#define NV_PPWR_OUTPUT_I2C_1_SCL 0x00000800110#define NV_PPWR_OUTPUT_I2C_2_SCL 0x00001000111#define NV_PPWR_OUTPUT_I2C_3_SCL 0x00002000112#define NV_PPWR_OUTPUT_I2C_4_SCL 0x00004000113#define NV_PPWR_OUTPUT_I2C_5_SCL 0x00008000114#define NV_PPWR_OUTPUT_I2C_6_SCL 0x00010000115#define NV_PPWR_OUTPUT_I2C_7_SCL 0x00020000116#define NV_PPWR_OUTPUT_I2C_8_SCL 0x00040000117#define NV_PPWR_OUTPUT_I2C_9_SCL 0x00080000118#define NV_PPWR_OUTPUT_I2C_0_SDA 0x00100000119#define NV_PPWR_OUTPUT_I2C_1_SDA 0x00200000120#define NV_PPWR_OUTPUT_I2C_2_SDA 0x00400000121#define NV_PPWR_OUTPUT_I2C_3_SDA 0x00800000122#define NV_PPWR_OUTPUT_I2C_4_SDA 0x01000000123#define NV_PPWR_OUTPUT_I2C_5_SDA 0x02000000124#define NV_PPWR_OUTPUT_I2C_6_SDA 0x04000000125#define NV_PPWR_OUTPUT_I2C_7_SDA 0x08000000126#define NV_PPWR_OUTPUT_I2C_8_SDA 0x10000000127#define NV_PPWR_OUTPUT_I2C_9_SDA 0x20000000128#endif129#define NV_PPWR_INPUT 0x07c4130#define NV_PPWR_OUTPUT_SET 0x07e0131#define NV_PPWR_OUTPUT_SET_FB_PAUSE 0x00000004132#define NV_PPWR_OUTPUT_CLR 0x07e4133#define NV_PPWR_OUTPUT_CLR_FB_PAUSE 0x00000004134 135// Inter-process message format136.equ #msg_process 0x00 /* send() target, recv() sender */137.equ #msg_message 0x04138.equ #msg_data0 0x08139.equ #msg_data1 0x0c140 141// Kernel message IDs142#define KMSG_FIFO 0x00000000143#define KMSG_ALARM 0x00000001144 145// Process message queue description146.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 queue149.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 entry154.equ #proc_id 0x00155.equ #proc_init 0x04156.equ #proc_recv 0x08157.equ #proc_time 0x0c158.equ #proc_qput 0x10159.equ #proc_qget 0x14160.equ #proc_queue 0x18161.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 64171 172#if NVKM_PPWR_CHIPSET < GK208173#define imm32(reg,val) /*174*/ movw reg ((val) & 0x0000ffff) /*175*/ sethi reg ((val) & 0xffff0000)176#else177#define imm32(reg,val) /*178*/ mov reg (val)179#endif180 181#ifndef NVKM_FALCON_UNSHIFTED_IO182#define nv_iord(reg,ior) /*183*/ mov reg ior /*184*/ shl b32 reg 6 /*185*/ iord reg I[reg + 0x000]186#else187#define nv_iord(reg,ior) /*188*/ mov reg ior /*189*/ iord reg I[reg + 0x000]190#endif191 192#ifndef NVKM_FALCON_UNSHIFTED_IO193#define nv_iowr(ior,reg) /*194*/ mov $r0 ior /*195*/ shl b32 $r0 6 /*196*/ iowr I[$r0 + 0x000] reg /*197*/ clear b32 $r0198#else199#define nv_iowr(ior,reg) /*200*/ mov $r0 ior /*201*/ iowr I[$r0 + 0x000] reg /*202*/ clear b32 $r0203#endif204 205#ifndef NVKM_FALCON_UNSHIFTED_IO206#define nv_iowrs(ior,reg) /*207*/ mov $r0 ior /*208*/ shl b32 $r0 6 /*209*/ iowrs I[$r0 + 0x000] reg /*210*/ clear b32 $r0211#else212#define nv_iowrs(ior,reg) /*213*/ mov $r0 ior /*214*/ iowrs I[$r0 + 0x000] reg /*215*/ clear b32 $r0216#endif217 218#define hash #219#define fn(a) a220#ifndef NVKM_FALCON_PC24221#define call(a) call fn(hash)a222#else223#define call(a) lcall fn(hash)a224#endif225 226#ifndef NVKM_FALCON_MMIO_UAS227#define nv_rd32(reg,addr) /*228*/ mov b32 $r14 addr /*229*/ call(rd32) /*230*/ mov b32 reg $r13231#else232#define nv_rd32(reg,addr) /*233*/ sethi $r0 0x14000000 /*234*/ or $r0 addr /*235*/ ld b32 reg D[$r0] /*236*/ clear b32 $r0237#endif238 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#else247#define nv_wr32(addr,reg) /*248*/ sethi $r0 0x14000000 /*249*/ or $r0 addr /*250*/ st b32 D[$r0] reg /*251*/ clear b32 $r0252#endif253 254#define st(size, addr, reg) /*255*/ imm32($r0, addr) /*256*/ st size D[$r0] reg /*257*/ clear b32 $r0258 259#define ld(size, reg, addr) /*260*/ imm32($r0, addr) /*261*/ ld size reg D[$r0] /*262*/ clear b32 $r0263 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_hi268 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_hi273