1 /* $NetBSD: nouveau_nvkm_subdev_bios_timing.c,v 1.3 2021/12/18 23:45:38 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_bios_timing.c,v 1.3 2021/12/18 23:45:38 riastradh Exp $"); 28 29 #include <subdev/bios.h> 30 #include <subdev/bios/bit.h> 31 #include <subdev/bios/timing.h> 32 33 u32 34 nvbios_timingTe(struct nvkm_bios *bios, 35 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz) 36 { 37 struct bit_entry bit_P; 38 u32 timing = 0; 39 40 if (!bit_entry(bios, 'P', &bit_P)) { 41 if (bit_P.version == 1) 42 timing = nvbios_rd32(bios, bit_P.offset + 4); 43 else 44 if (bit_P.version == 2) 45 timing = nvbios_rd32(bios, bit_P.offset + 8); 46 47 if (timing) { 48 *ver = nvbios_rd08(bios, timing + 0); 49 switch (*ver) { 50 case 0x10: 51 *hdr = nvbios_rd08(bios, timing + 1); 52 *cnt = nvbios_rd08(bios, timing + 2); 53 *len = nvbios_rd08(bios, timing + 3); 54 *snr = 0; 55 *ssz = 0; 56 return timing; 57 case 0x20: 58 *hdr = nvbios_rd08(bios, timing + 1); 59 *cnt = nvbios_rd08(bios, timing + 5); 60 *len = nvbios_rd08(bios, timing + 2); 61 *snr = nvbios_rd08(bios, timing + 4); 62 *ssz = nvbios_rd08(bios, timing + 3); 63 return timing; 64 default: 65 break; 66 } 67 } 68 } 69 70 return 0; 71 } 72 73 u32 74 nvbios_timingEe(struct nvkm_bios *bios, int idx, 75 u8 *ver, u8 *hdr, u8 *cnt, u8 *len) 76 { 77 u8 snr, ssz; 78 u32 timing = nvbios_timingTe(bios, ver, hdr, cnt, len, &snr, &ssz); 79 if (timing && idx < *cnt) { 80 timing += *hdr + idx * (*len + (snr * ssz)); 81 *hdr = *len; 82 *cnt = snr; 83 *len = ssz; 84 return timing; 85 } 86 return 0; 87 } 88 89 u32 90 nvbios_timingEp(struct nvkm_bios *bios, int idx, 91 u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ramcfg *p) 92 { 93 u32 data = nvbios_timingEe(bios, idx, ver, hdr, cnt, len), temp; 94 p->timing_ver = *ver; 95 p->timing_hdr = *hdr; 96 switch (!!data * *ver) { 97 case 0x10: 98 p->timing_10_WR = nvbios_rd08(bios, data + 0x00); 99 p->timing_10_WTR = nvbios_rd08(bios, data + 0x01); 100 p->timing_10_CL = nvbios_rd08(bios, data + 0x02); 101 p->timing_10_RC = nvbios_rd08(bios, data + 0x03); 102 p->timing_10_RFC = nvbios_rd08(bios, data + 0x05); 103 p->timing_10_RAS = nvbios_rd08(bios, data + 0x07); 104 p->timing_10_RP = nvbios_rd08(bios, data + 0x09); 105 p->timing_10_RCDRD = nvbios_rd08(bios, data + 0x0a); 106 p->timing_10_RCDWR = nvbios_rd08(bios, data + 0x0b); 107 p->timing_10_RRD = nvbios_rd08(bios, data + 0x0c); 108 p->timing_10_13 = nvbios_rd08(bios, data + 0x0d); 109 p->timing_10_ODT = nvbios_rd08(bios, data + 0x0e) & 0x07; 110 if (p->ramcfg_ver >= 0x10) 111 p->ramcfg_RON = nvbios_rd08(bios, data + 0x0e) & 0x07; 112 113 p->timing_10_24 = 0xff; 114 p->timing_10_21 = 0; 115 p->timing_10_20 = 0; 116 p->timing_10_CWL = 0; 117 p->timing_10_18 = 0; 118 p->timing_10_16 = 0; 119 120 switch (min_t(u8, *hdr, 25)) { 121 case 25: 122 p->timing_10_24 = nvbios_rd08(bios, data + 0x18); 123 /* fall through */ 124 case 24: 125 case 23: 126 case 22: 127 p->timing_10_21 = nvbios_rd08(bios, data + 0x15); 128 /* fall through */ 129 case 21: 130 p->timing_10_20 = nvbios_rd08(bios, data + 0x14); 131 /* fall through */ 132 case 20: 133 p->timing_10_CWL = nvbios_rd08(bios, data + 0x13); 134 /* fall through */ 135 case 19: 136 p->timing_10_18 = nvbios_rd08(bios, data + 0x12); 137 /* fall through */ 138 case 18: 139 case 17: 140 p->timing_10_16 = nvbios_rd08(bios, data + 0x10); 141 } 142 143 break; 144 case 0x20: 145 p->timing[0] = nvbios_rd32(bios, data + 0x00); 146 p->timing[1] = nvbios_rd32(bios, data + 0x04); 147 p->timing[2] = nvbios_rd32(bios, data + 0x08); 148 p->timing[3] = nvbios_rd32(bios, data + 0x0c); 149 p->timing[4] = nvbios_rd32(bios, data + 0x10); 150 p->timing[5] = nvbios_rd32(bios, data + 0x14); 151 p->timing[6] = nvbios_rd32(bios, data + 0x18); 152 p->timing[7] = nvbios_rd32(bios, data + 0x1c); 153 p->timing[8] = nvbios_rd32(bios, data + 0x20); 154 p->timing[9] = nvbios_rd32(bios, data + 0x24); 155 p->timing[10] = nvbios_rd32(bios, data + 0x28); 156 p->timing_20_2e_03 = (nvbios_rd08(bios, data + 0x2e) & 0x03) >> 0; 157 p->timing_20_2e_30 = (nvbios_rd08(bios, data + 0x2e) & 0x30) >> 4; 158 p->timing_20_2e_c0 = (nvbios_rd08(bios, data + 0x2e) & 0xc0) >> 6; 159 p->timing_20_2f_03 = (nvbios_rd08(bios, data + 0x2f) & 0x03) >> 0; 160 temp = nvbios_rd16(bios, data + 0x2c); 161 p->timing_20_2c_003f = (temp & 0x003f) >> 0; 162 p->timing_20_2c_1fc0 = (temp & 0x1fc0) >> 6; 163 p->timing_20_30_07 = (nvbios_rd08(bios, data + 0x30) & 0x07) >> 0; 164 p->timing_20_30_f8 = (nvbios_rd08(bios, data + 0x30) & 0xf8) >> 3; 165 temp = nvbios_rd16(bios, data + 0x31); 166 p->timing_20_31_0007 = (temp & 0x0007) >> 0; 167 p->timing_20_31_0078 = (temp & 0x0078) >> 3; 168 p->timing_20_31_0780 = (temp & 0x0780) >> 7; 169 p->timing_20_31_0800 = (temp & 0x0800) >> 11; 170 p->timing_20_31_7000 = (temp & 0x7000) >> 12; 171 p->timing_20_31_8000 = (temp & 0x8000) >> 15; 172 break; 173 default: 174 data = 0; 175 break; 176 } 177 return data; 178 } 179