1 /* $NetBSD: nouveau_nvkm_subdev_devinit_gt215.c,v 1.3 2021/12/18 23:45:39 riastradh Exp $ */ 2 3 /* 4 * Copyright 2013 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Ben Skeggs 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_devinit_gt215.c,v 1.3 2021/12/18 23:45:39 riastradh Exp $"); 28 29 #include "nv50.h" 30 31 #include <subdev/bios.h> 32 #include <subdev/bios/init.h> 33 #include <subdev/bios/pll.h> 34 #include <subdev/clk/pll.h> 35 36 int 37 gt215_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) 38 { 39 struct nvkm_subdev *subdev = &init->subdev; 40 struct nvkm_device *device = subdev->device; 41 struct nvbios_pll info; 42 int N, fN, M, P; 43 int ret; 44 45 ret = nvbios_pll_parse(device->bios, type, &info); 46 if (ret) 47 return ret; 48 49 ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P); 50 if (ret < 0) 51 return ret; 52 53 switch (info.type) { 54 case PLL_VPLL0: 55 case PLL_VPLL1: 56 nvkm_wr32(device, info.reg + 0, 0x50000610); 57 nvkm_mask(device, info.reg + 4, 0x003fffff, 58 (P << 16) | (M << 8) | N); 59 nvkm_wr32(device, info.reg + 8, fN); 60 break; 61 default: 62 nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq); 63 ret = -EINVAL; 64 break; 65 } 66 67 return ret; 68 } 69 70 static u64 71 gt215_devinit_disable(struct nvkm_devinit *init) 72 { 73 struct nvkm_device *device = init->subdev.device; 74 u32 r001540 = nvkm_rd32(device, 0x001540); 75 u32 r00154c = nvkm_rd32(device, 0x00154c); 76 u64 disable = 0ULL; 77 78 if (!(r001540 & 0x40000000)) { 79 disable |= (1ULL << NVKM_ENGINE_MSPDEC); 80 disable |= (1ULL << NVKM_ENGINE_MSPPP); 81 } 82 83 if (!(r00154c & 0x00000004)) 84 disable |= (1ULL << NVKM_ENGINE_DISP); 85 if (!(r00154c & 0x00000020)) 86 disable |= (1ULL << NVKM_ENGINE_MSVLD); 87 if (!(r00154c & 0x00000200)) 88 disable |= (1ULL << NVKM_ENGINE_CE0); 89 90 return disable; 91 } 92 93 static u32 94 gt215_devinit_mmio_part[] = { 95 0x100720, 0x1008bc, 4, 96 0x100a20, 0x100adc, 4, 97 0x100d80, 0x100ddc, 4, 98 0x110000, 0x110f9c, 4, 99 0x111000, 0x11103c, 8, 100 0x111080, 0x1110fc, 4, 101 0x111120, 0x1111fc, 4, 102 0x111300, 0x1114bc, 4, 103 0, 104 }; 105 106 static u32 107 gt215_devinit_mmio(struct nvkm_devinit *base, u32 addr) 108 { 109 struct nv50_devinit *init = nv50_devinit(base); 110 struct nvkm_device *device = init->base.subdev.device; 111 u32 *mmio = gt215_devinit_mmio_part; 112 113 /* the init tables on some boards have INIT_RAM_RESTRICT_ZM_REG_GROUP 114 * instructions which touch registers that may not even exist on 115 * some configurations (Quadro 400), which causes the register 116 * interface to screw up for some amount of time after attempting to 117 * write to one of these, and results in all sorts of things going 118 * horribly wrong. 119 * 120 * the binary driver avoids touching these registers at all, however, 121 * the video bios doesn't care and does what the scripts say. it's 122 * presumed that the io-port access to init registers isn't effected 123 * by the screw-up bug mentioned above. 124 * 125 * really, a new opcode should've been invented to handle these 126 * requirements, but whatever, it's too late for that now. 127 */ 128 while (mmio[0]) { 129 if (addr >= mmio[0] && addr <= mmio[1]) { 130 u32 part = (addr / mmio[2]) & 7; 131 if (!init->r001540) 132 init->r001540 = nvkm_rd32(device, 0x001540); 133 if (part >= hweight8((init->r001540 >> 16) & 0xff)) 134 return ~0; 135 return addr; 136 } 137 mmio += 3; 138 } 139 140 return addr; 141 } 142 143 static const struct nvkm_devinit_func 144 gt215_devinit = { 145 .preinit = nv50_devinit_preinit, 146 .init = nv50_devinit_init, 147 .post = nv04_devinit_post, 148 .mmio = gt215_devinit_mmio, 149 .pll_set = gt215_devinit_pll_set, 150 .disable = gt215_devinit_disable, 151 }; 152 153 int 154 gt215_devinit_new(struct nvkm_device *device, int index, 155 struct nvkm_devinit **pinit) 156 { 157 return nv50_devinit_new_(>215_devinit, device, index, pinit); 158 } 159