1/* 2 * Copyright 2015 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 <bskeggs@redhat.com> 23 */ 24#include "gf100.h" 25#include "ctxgf100.h" 26 27#include <nvif/class.h> 28 29/******************************************************************************* 30 * Graphics object classes 31 ******************************************************************************/ 32 33struct nvkm_oclass 34gm204_gr_sclass[] = { 35 { FERMI_TWOD_A, &nvkm_object_ofuncs }, 36 { KEPLER_INLINE_TO_MEMORY_B, &nvkm_object_ofuncs }, 37 { MAXWELL_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds }, 38 { MAXWELL_COMPUTE_B, &nvkm_object_ofuncs, gf100_gr_90c0_omthds }, 39 {} 40}; 41 42/******************************************************************************* 43 * PGRAPH register lists 44 ******************************************************************************/ 45 46static const struct gf100_gr_init 47gm204_gr_init_main_0[] = { 48 { 0x400080, 1, 0x04, 0x003003e2 }, 49 { 0x400088, 1, 0x04, 0xe007bfe7 }, 50 { 0x40008c, 1, 0x04, 0x00060000 }, 51 { 0x400090, 1, 0x04, 0x00000030 }, 52 { 0x40013c, 1, 0x04, 0x003901f3 }, 53 { 0x400140, 1, 0x04, 0x00000100 }, 54 { 0x400144, 1, 0x04, 0x00000000 }, 55 { 0x400148, 1, 0x04, 0x00000110 }, 56 { 0x400138, 1, 0x04, 0x00000000 }, 57 { 0x400130, 2, 0x04, 0x00000000 }, 58 { 0x400124, 1, 0x04, 0x00000002 }, 59 {} 60}; 61 62static const struct gf100_gr_init 63gm204_gr_init_fe_0[] = { 64 { 0x40415c, 1, 0x04, 0x00000000 }, 65 { 0x404170, 1, 0x04, 0x00000000 }, 66 { 0x4041b4, 1, 0x04, 0x00000000 }, 67 { 0x4041b8, 1, 0x04, 0x00000010 }, 68 {} 69}; 70 71static const struct gf100_gr_init 72gm204_gr_init_ds_0[] = { 73 { 0x40583c, 1, 0x04, 0x00000000 }, 74 { 0x405844, 1, 0x04, 0x00ffffff }, 75 { 0x40584c, 1, 0x04, 0x00000001 }, 76 { 0x405850, 1, 0x04, 0x00000000 }, 77 { 0x405900, 1, 0x04, 0x00000000 }, 78 { 0x405908, 1, 0x04, 0x00000000 }, 79 {} 80}; 81 82static const struct gf100_gr_init 83gm204_gr_init_sked_0[] = { 84 { 0x407010, 1, 0x04, 0x00000000 }, 85 { 0x407040, 1, 0x04, 0x80440434 }, 86 { 0x407048, 1, 0x04, 0x00000008 }, 87 {} 88}; 89 90static const struct gf100_gr_init 91gm204_gr_init_tpccs_0[] = { 92 { 0x419d60, 1, 0x04, 0x0000003f }, 93 { 0x419d88, 3, 0x04, 0x00000000 }, 94 { 0x419dc4, 1, 0x04, 0x00000000 }, 95 { 0x419dc8, 1, 0x04, 0x00000501 }, 96 { 0x419dd0, 1, 0x04, 0x00000000 }, 97 { 0x419dd4, 1, 0x04, 0x00000100 }, 98 { 0x419dd8, 1, 0x04, 0x00000001 }, 99 { 0x419ddc, 1, 0x04, 0x00000002 }, 100 { 0x419de0, 1, 0x04, 0x00000001 }, 101 { 0x419de8, 1, 0x04, 0x000000cc }, 102 { 0x419dec, 1, 0x04, 0x00000000 }, 103 { 0x419df0, 1, 0x04, 0x000000cc }, 104 { 0x419df4, 1, 0x04, 0x00000000 }, 105 { 0x419d0c, 1, 0x04, 0x00000000 }, 106 { 0x419d10, 1, 0x04, 0x00000014 }, 107 {} 108}; 109 110static const struct gf100_gr_init 111gm204_gr_init_pe_0[] = { 112 { 0x419900, 1, 0x04, 0x000000ff }, 113 { 0x419810, 1, 0x04, 0x00000000 }, 114 { 0x41980c, 1, 0x04, 0x00000010 }, 115 { 0x419844, 1, 0x04, 0x00000000 }, 116 { 0x419838, 1, 0x04, 0x000000ff }, 117 { 0x419850, 1, 0x04, 0x00000004 }, 118 { 0x419854, 2, 0x04, 0x00000000 }, 119 { 0x419894, 3, 0x04, 0x00100401 }, 120 {} 121}; 122 123static const struct gf100_gr_init 124gm204_gr_init_sm_0[] = { 125 { 0x419e30, 1, 0x04, 0x000000ff }, 126 { 0x419e00, 1, 0x04, 0x00000000 }, 127 { 0x419ea0, 1, 0x04, 0x00000000 }, 128 { 0x419ee4, 1, 0x04, 0x00000000 }, 129 { 0x419ea4, 1, 0x04, 0x00000100 }, 130 { 0x419ea8, 1, 0x04, 0x00000000 }, 131 { 0x419ee8, 1, 0x04, 0x00000091 }, 132 { 0x419eb4, 1, 0x04, 0x00000000 }, 133 { 0x419ebc, 2, 0x04, 0x00000000 }, 134 { 0x419edc, 1, 0x04, 0x000c1810 }, 135 { 0x419ed8, 1, 0x04, 0x00000000 }, 136 { 0x419ee0, 1, 0x04, 0x00000000 }, 137 {} 138}; 139 140static const struct gf100_gr_init 141gm204_gr_init_l1c_1[] = { 142 { 0x419cf8, 2, 0x04, 0x00000000 }, 143 {} 144}; 145 146static const struct gf100_gr_init 147gm204_gr_init_sm_1[] = { 148 { 0x419f74, 1, 0x04, 0x00055155 }, 149 { 0x419f80, 4, 0x04, 0x00000000 }, 150 {} 151}; 152 153static const struct gf100_gr_init 154gm204_gr_init_l1c_2[] = { 155 { 0x419ccc, 2, 0x04, 0x00000000 }, 156 { 0x419c80, 1, 0x04, 0x3f006022 }, 157 { 0x419c88, 1, 0x04, 0x00210000 }, 158 {} 159}; 160 161static const struct gf100_gr_init 162gm204_gr_init_pes_0[] = { 163 { 0x41be50, 1, 0x04, 0x000000ff }, 164 { 0x41be04, 1, 0x04, 0x00000000 }, 165 { 0x41be08, 1, 0x04, 0x00000004 }, 166 { 0x41be0c, 1, 0x04, 0x00000008 }, 167 { 0x41be10, 1, 0x04, 0x2e3b8bc7 }, 168 { 0x41be14, 2, 0x04, 0x00000000 }, 169 { 0x41be3c, 5, 0x04, 0x00100401 }, 170 {} 171}; 172 173static const struct gf100_gr_init 174gm204_gr_init_be_0[] = { 175 { 0x408890, 1, 0x04, 0x000000ff }, 176 { 0x40880c, 1, 0x04, 0x00000000 }, 177 { 0x408850, 1, 0x04, 0x00000004 }, 178 { 0x408878, 1, 0x04, 0x01b4201c }, 179 { 0x40887c, 1, 0x04, 0x80004c55 }, 180 { 0x408880, 1, 0x04, 0x0018c258 }, 181 { 0x408884, 1, 0x04, 0x0000160f }, 182 { 0x408974, 1, 0x04, 0x000000ff }, 183 { 0x408910, 9, 0x04, 0x00000000 }, 184 { 0x408950, 1, 0x04, 0x00000000 }, 185 { 0x408954, 1, 0x04, 0x0000ffff }, 186 { 0x408958, 1, 0x04, 0x00000034 }, 187 { 0x40895c, 1, 0x04, 0x84b17403 }, 188 { 0x408960, 1, 0x04, 0x04c1884f }, 189 { 0x408964, 1, 0x04, 0x04714445 }, 190 { 0x408968, 1, 0x04, 0x0280802f }, 191 { 0x40896c, 1, 0x04, 0x04304856 }, 192 { 0x408970, 1, 0x04, 0x00012800 }, 193 { 0x408984, 1, 0x04, 0x00000000 }, 194 { 0x408988, 1, 0x04, 0x08040201 }, 195 { 0x40898c, 1, 0x04, 0x80402010 }, 196 {} 197}; 198 199const struct gf100_gr_pack 200gm204_gr_pack_mmio[] = { 201 { gm204_gr_init_main_0 }, 202 { gm204_gr_init_fe_0 }, 203 { gf100_gr_init_pri_0 }, 204 { gf100_gr_init_rstr2d_0 }, 205 { gf100_gr_init_pd_0 }, 206 { gm204_gr_init_ds_0 }, 207 { gm107_gr_init_scc_0 }, 208 { gm204_gr_init_sked_0 }, 209 { gk110_gr_init_cwd_0 }, 210 { gm107_gr_init_prop_0 }, 211 { gk208_gr_init_gpc_unk_0 }, 212 { gf100_gr_init_setup_0 }, 213 { gf100_gr_init_crstr_0 }, 214 { gm107_gr_init_setup_1 }, 215 { gm107_gr_init_zcull_0 }, 216 { gf100_gr_init_gpm_0 }, 217 { gm107_gr_init_gpc_unk_1 }, 218 { gf100_gr_init_gcc_0 }, 219 { gm204_gr_init_tpccs_0 }, 220 { gm107_gr_init_tex_0 }, 221 { gm204_gr_init_pe_0 }, 222 { gm107_gr_init_l1c_0 }, 223 { gf100_gr_init_mpc_0 }, 224 { gm204_gr_init_sm_0 }, 225 { gm204_gr_init_l1c_1 }, 226 { gm204_gr_init_sm_1 }, 227 { gm204_gr_init_l1c_2 }, 228 { gm204_gr_init_pes_0 }, 229 { gm107_gr_init_wwdx_0 }, 230 { gm107_gr_init_cbm_0 }, 231 { gm204_gr_init_be_0 }, 232 {} 233}; 234 235const struct gf100_gr_pack * 236gm204_gr_data[] = { 237 gm204_gr_pack_mmio, 238 NULL 239}; 240 241/******************************************************************************* 242 * PGRAPH engine/subdev functions 243 ******************************************************************************/ 244 245static int 246gm204_gr_init_ctxctl(struct gf100_gr_priv *priv) 247{ 248 return 0; 249} 250 251int 252gm204_gr_init(struct nvkm_object *object) 253{ 254 struct gf100_gr_oclass *oclass = (void *)object->oclass; 255 struct gf100_gr_priv *priv = (void *)object; 256 const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total); 257 u32 data[TPC_MAX / 8] = {}; 258 u8 tpcnr[GPC_MAX]; 259 int gpc, tpc, ppc, rop; 260 int ret, i; 261 u32 tmp; 262 263 ret = nvkm_gr_init(&priv->base); 264 if (ret) 265 return ret; 266 267 tmp = nv_rd32(priv, 0x100c80); /*XXX: mask? */ 268 nv_wr32(priv, 0x418880, 0x00001000 | (tmp & 0x00000fff)); 269 nv_wr32(priv, 0x418890, 0x00000000); 270 nv_wr32(priv, 0x418894, 0x00000000); 271 nv_wr32(priv, 0x4188b4, priv->unk4188b4->addr >> 8); 272 nv_wr32(priv, 0x4188b8, priv->unk4188b8->addr >> 8); 273 nv_mask(priv, 0x4188b0, 0x00040000, 0x00040000); 274 275 /*XXX: belongs in fb */ 276 nv_wr32(priv, 0x100cc8, priv->unk4188b4->addr >> 8); 277 nv_wr32(priv, 0x100ccc, priv->unk4188b8->addr >> 8); 278 nv_mask(priv, 0x100cc4, 0x00040000, 0x00040000); 279 280 gf100_gr_mmio(priv, oclass->mmio); 281 282 gm107_gr_init_bios(priv); 283 284 nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001); 285 286 memset(data, 0x00, sizeof(data)); 287 memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); 288 for (i = 0, gpc = -1; i < priv->tpc_total; i++) { 289 do { 290 gpc = (gpc + 1) % priv->gpc_nr; 291 } while (!tpcnr[gpc]); 292 tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; 293 294 data[i / 8] |= tpc << ((i % 8) * 4); 295 } 296 297 nv_wr32(priv, GPC_BCAST(0x0980), data[0]); 298 nv_wr32(priv, GPC_BCAST(0x0984), data[1]); 299 nv_wr32(priv, GPC_BCAST(0x0988), data[2]); 300 nv_wr32(priv, GPC_BCAST(0x098c), data[3]); 301 302 for (gpc = 0; gpc < priv->gpc_nr; gpc++) { 303 nv_wr32(priv, GPC_UNIT(gpc, 0x0914), 304 priv->magic_not_rop_nr << 8 | priv->tpc_nr[gpc]); 305 nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | 306 priv->tpc_total); 307 nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); 308 } 309 310 nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918); 311 nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); 312 nv_wr32(priv, GPC_BCAST(0x033c), nv_rd32(priv, 0x100804)); 313 314 nv_wr32(priv, 0x400500, 0x00010001); 315 nv_wr32(priv, 0x400100, 0xffffffff); 316 nv_wr32(priv, 0x40013c, 0xffffffff); 317 nv_wr32(priv, 0x400124, 0x00000002); 318 nv_wr32(priv, 0x409c24, 0x000e0000); 319 nv_wr32(priv, 0x405848, 0xc0000000); 320 nv_wr32(priv, 0x40584c, 0x00000001); 321 nv_wr32(priv, 0x404000, 0xc0000000); 322 nv_wr32(priv, 0x404600, 0xc0000000); 323 nv_wr32(priv, 0x408030, 0xc0000000); 324 nv_wr32(priv, 0x404490, 0xc0000000); 325 nv_wr32(priv, 0x406018, 0xc0000000); 326 nv_wr32(priv, 0x407020, 0x40000000); 327 nv_wr32(priv, 0x405840, 0xc0000000); 328 nv_wr32(priv, 0x405844, 0x00ffffff); 329 nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008); 330 331 for (gpc = 0; gpc < priv->gpc_nr; gpc++) { 332 for (ppc = 0; ppc < priv->ppc_nr[gpc]; ppc++) 333 nv_wr32(priv, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000); 334 nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); 335 nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); 336 nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); 337 nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); 338 for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { 339 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); 340 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); 341 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); 342 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); 343 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); 344 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); 345 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); 346 nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); 347 } 348 nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff); 349 nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff); 350 } 351 352 for (rop = 0; rop < priv->rop_nr; rop++) { 353 nv_wr32(priv, ROP_UNIT(rop, 0x144), 0x40000000); 354 nv_wr32(priv, ROP_UNIT(rop, 0x070), 0x40000000); 355 nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff); 356 nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff); 357 } 358 359 nv_wr32(priv, 0x400108, 0xffffffff); 360 nv_wr32(priv, 0x400138, 0xffffffff); 361 nv_wr32(priv, 0x400118, 0xffffffff); 362 nv_wr32(priv, 0x400130, 0xffffffff); 363 nv_wr32(priv, 0x40011c, 0xffffffff); 364 nv_wr32(priv, 0x400134, 0xffffffff); 365 366 nv_wr32(priv, 0x400054, 0x2c350f63); 367 368 gf100_gr_zbc_init(priv); 369 370 return gm204_gr_init_ctxctl(priv); 371} 372 373struct nvkm_oclass * 374gm204_gr_oclass = &(struct gf100_gr_oclass) { 375 .base.handle = NV_ENGINE(GR, 0x24), 376 .base.ofuncs = &(struct nvkm_ofuncs) { 377 .ctor = gf100_gr_ctor, 378 .dtor = gf100_gr_dtor, 379 .init = gm204_gr_init, 380 .fini = _nvkm_gr_fini, 381 }, 382 .cclass = &gm204_grctx_oclass, 383 .sclass = gm204_gr_sclass, 384 .mmio = gm204_gr_pack_mmio, 385 .ppc_nr = 2, 386}.base; 387