2 * Copyright 2013 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
28 #include <nvif/class.h>
30 /*******************************************************************************
31 * PGRAPH register lists
32 ******************************************************************************/
34 const struct gf100_gr_init
35 gk104_gr_init_main_0
[] = {
36 { 0x400080, 1, 0x04, 0x003083c2 },
37 { 0x400088, 1, 0x04, 0x0001ffe7 },
38 { 0x40008c, 1, 0x04, 0x00000000 },
39 { 0x400090, 1, 0x04, 0x00000030 },
40 { 0x40013c, 1, 0x04, 0x003901f7 },
41 { 0x400140, 1, 0x04, 0x00000100 },
42 { 0x400144, 1, 0x04, 0x00000000 },
43 { 0x400148, 1, 0x04, 0x00000110 },
44 { 0x400138, 1, 0x04, 0x00000000 },
45 { 0x400130, 2, 0x04, 0x00000000 },
46 { 0x400124, 1, 0x04, 0x00000002 },
50 static const struct gf100_gr_init
51 gk104_gr_init_ds_0
[] = {
52 { 0x405844, 1, 0x04, 0x00ffffff },
53 { 0x405850, 1, 0x04, 0x00000000 },
54 { 0x405900, 1, 0x04, 0x0000ff34 },
55 { 0x405908, 1, 0x04, 0x00000000 },
56 { 0x405928, 2, 0x04, 0x00000000 },
60 static const struct gf100_gr_init
61 gk104_gr_init_sked_0
[] = {
62 { 0x407010, 1, 0x04, 0x00000000 },
66 static const struct gf100_gr_init
67 gk104_gr_init_cwd_0
[] = {
68 { 0x405b50, 1, 0x04, 0x00000000 },
72 static const struct gf100_gr_init
73 gk104_gr_init_gpc_unk_1
[] = {
74 { 0x418d00, 1, 0x04, 0x00000000 },
75 { 0x418d28, 2, 0x04, 0x00000000 },
76 { 0x418f00, 1, 0x04, 0x00000000 },
77 { 0x418f08, 1, 0x04, 0x00000000 },
78 { 0x418f20, 2, 0x04, 0x00000000 },
79 { 0x418e00, 1, 0x04, 0x00000060 },
80 { 0x418e08, 1, 0x04, 0x00000000 },
81 { 0x418e1c, 2, 0x04, 0x00000000 },
85 const struct gf100_gr_init
86 gk104_gr_init_tpccs_0
[] = {
87 { 0x419d0c, 1, 0x04, 0x00000000 },
88 { 0x419d10, 1, 0x04, 0x00000014 },
92 const struct gf100_gr_init
93 gk104_gr_init_pe_0
[] = {
94 { 0x41980c, 1, 0x04, 0x00000010 },
95 { 0x419844, 1, 0x04, 0x00000000 },
96 { 0x419850, 1, 0x04, 0x00000004 },
97 { 0x419854, 2, 0x04, 0x00000000 },
101 static const struct gf100_gr_init
102 gk104_gr_init_l1c_0
[] = {
103 { 0x419c98, 1, 0x04, 0x00000000 },
104 { 0x419ca8, 1, 0x04, 0x00000000 },
105 { 0x419cb0, 1, 0x04, 0x01000000 },
106 { 0x419cb4, 1, 0x04, 0x00000000 },
107 { 0x419cb8, 1, 0x04, 0x00b08bea },
108 { 0x419c84, 1, 0x04, 0x00010384 },
109 { 0x419cbc, 1, 0x04, 0x28137646 },
110 { 0x419cc0, 2, 0x04, 0x00000000 },
111 { 0x419c80, 1, 0x04, 0x00020232 },
115 static const struct gf100_gr_init
116 gk104_gr_init_sm_0
[] = {
117 { 0x419e00, 1, 0x04, 0x00000000 },
118 { 0x419ea0, 1, 0x04, 0x00000000 },
119 { 0x419ee4, 1, 0x04, 0x00000000 },
120 { 0x419ea4, 1, 0x04, 0x00000100 },
121 { 0x419ea8, 1, 0x04, 0x00000000 },
122 { 0x419eb4, 4, 0x04, 0x00000000 },
123 { 0x419edc, 1, 0x04, 0x00000000 },
124 { 0x419f00, 1, 0x04, 0x00000000 },
125 { 0x419f74, 1, 0x04, 0x00000555 },
129 const struct gf100_gr_init
130 gk104_gr_init_be_0
[] = {
131 { 0x40880c, 1, 0x04, 0x00000000 },
132 { 0x408850, 1, 0x04, 0x00000004 },
133 { 0x408910, 9, 0x04, 0x00000000 },
134 { 0x408950, 1, 0x04, 0x00000000 },
135 { 0x408954, 1, 0x04, 0x0000ffff },
136 { 0x408958, 1, 0x04, 0x00000034 },
137 { 0x408984, 1, 0x04, 0x00000000 },
138 { 0x408988, 1, 0x04, 0x08040201 },
139 { 0x40898c, 1, 0x04, 0x80402010 },
143 const struct gf100_gr_pack
144 gk104_gr_pack_mmio
[] = {
145 { gk104_gr_init_main_0
},
146 { gf100_gr_init_fe_0
},
147 { gf100_gr_init_pri_0
},
148 { gf100_gr_init_rstr2d_0
},
149 { gf119_gr_init_pd_0
},
150 { gk104_gr_init_ds_0
},
151 { gf100_gr_init_scc_0
},
152 { gk104_gr_init_sked_0
},
153 { gk104_gr_init_cwd_0
},
154 { gf119_gr_init_prop_0
},
155 { gf108_gr_init_gpc_unk_0
},
156 { gf100_gr_init_setup_0
},
157 { gf100_gr_init_crstr_0
},
158 { gf108_gr_init_setup_1
},
159 { gf100_gr_init_zcull_0
},
160 { gf119_gr_init_gpm_0
},
161 { gk104_gr_init_gpc_unk_1
},
162 { gf100_gr_init_gcc_0
},
163 { gk104_gr_init_tpccs_0
},
164 { gf119_gr_init_tex_0
},
165 { gk104_gr_init_pe_0
},
166 { gk104_gr_init_l1c_0
},
167 { gf100_gr_init_mpc_0
},
168 { gk104_gr_init_sm_0
},
169 { gf117_gr_init_pes_0
},
170 { gf117_gr_init_wwdx_0
},
171 { gf117_gr_init_cbm_0
},
172 { gk104_gr_init_be_0
},
173 { gf100_gr_init_fe_1
},
177 const struct nvkm_therm_clkgate_init
178 gk104_clkgate_blcg_init_main_0
[] = {
179 { 0x4041f0, 1, 0x00004046 },
180 { 0x409890, 1, 0x00000045 },
181 { 0x4098b0, 1, 0x0000007f },
185 const struct nvkm_therm_clkgate_init
186 gk104_clkgate_blcg_init_rstr2d_0
[] = {
187 { 0x4078c0, 1, 0x00000042 },
191 const struct nvkm_therm_clkgate_init
192 gk104_clkgate_blcg_init_unk_0
[] = {
193 { 0x406000, 1, 0x00004044 },
194 { 0x405860, 1, 0x00004042 },
195 { 0x40590c, 1, 0x00004042 },
199 const struct nvkm_therm_clkgate_init
200 gk104_clkgate_blcg_init_gcc_0
[] = {
201 { 0x408040, 1, 0x00004044 },
205 const struct nvkm_therm_clkgate_init
206 gk104_clkgate_blcg_init_sked_0
[] = {
207 { 0x407000, 1, 0x00004044 },
211 const struct nvkm_therm_clkgate_init
212 gk104_clkgate_blcg_init_unk_1
[] = {
213 { 0x405bf0, 1, 0x00004044 },
217 const struct nvkm_therm_clkgate_init
218 gk104_clkgate_blcg_init_gpc_ctxctl_0
[] = {
219 { 0x41a890, 1, 0x00000042 },
220 { 0x41a8b0, 1, 0x0000007f },
224 const struct nvkm_therm_clkgate_init
225 gk104_clkgate_blcg_init_gpc_unk_0
[] = {
226 { 0x418500, 1, 0x00004042 },
227 { 0x418608, 1, 0x00004042 },
228 { 0x418688, 1, 0x00004042 },
229 { 0x418718, 1, 0x00000042 },
233 const struct nvkm_therm_clkgate_init
234 gk104_clkgate_blcg_init_gpc_esetup_0
[] = {
235 { 0x418828, 1, 0x00000044 },
239 const struct nvkm_therm_clkgate_init
240 gk104_clkgate_blcg_init_gpc_tpbus_0
[] = {
241 { 0x418bbc, 1, 0x00004042 },
245 const struct nvkm_therm_clkgate_init
246 gk104_clkgate_blcg_init_gpc_zcull_0
[] = {
247 { 0x418970, 1, 0x00004042 },
251 const struct nvkm_therm_clkgate_init
252 gk104_clkgate_blcg_init_gpc_tpconf_0
[] = {
253 { 0x418c70, 1, 0x00004042 },
257 const struct nvkm_therm_clkgate_init
258 gk104_clkgate_blcg_init_gpc_unk_1
[] = {
259 { 0x418cf0, 1, 0x00004042 },
260 { 0x418d70, 1, 0x00004042 },
261 { 0x418f0c, 1, 0x00004042 },
262 { 0x418e0c, 1, 0x00004042 },
266 const struct nvkm_therm_clkgate_init
267 gk104_clkgate_blcg_init_gpc_gcc_0
[] = {
268 { 0x419020, 1, 0x00004042 },
269 { 0x419038, 1, 0x00000042 },
273 const struct nvkm_therm_clkgate_init
274 gk104_clkgate_blcg_init_gpc_ffb_0
[] = {
275 { 0x418898, 1, 0x00000042 },
279 const struct nvkm_therm_clkgate_init
280 gk104_clkgate_blcg_init_gpc_tex_0
[] = {
281 { 0x419a40, 9, 0x00004042 },
282 { 0x419acc, 1, 0x00004047 },
286 const struct nvkm_therm_clkgate_init
287 gk104_clkgate_blcg_init_gpc_poly_0
[] = {
288 { 0x419868, 1, 0x00000042 },
292 const struct nvkm_therm_clkgate_init
293 gk104_clkgate_blcg_init_gpc_l1c_0
[] = {
294 { 0x419ccc, 3, 0x00000042 },
298 const struct nvkm_therm_clkgate_init
299 gk104_clkgate_blcg_init_gpc_unk_2
[] = {
300 { 0x419c70, 1, 0x00004045 },
304 const struct nvkm_therm_clkgate_init
305 gk104_clkgate_blcg_init_gpc_mp_0
[] = {
306 { 0x419fd0, 1, 0x00004043 },
307 { 0x419fd8, 1, 0x00004049 },
308 { 0x419fe0, 2, 0x00004042 },
309 { 0x419ff0, 1, 0x00004046 },
310 { 0x419ff8, 1, 0x00004042 },
314 const struct nvkm_therm_clkgate_init
315 gk104_clkgate_blcg_init_gpc_ppc_0
[] = {
316 { 0x41be28, 1, 0x00000042 },
317 { 0x41bfe8, 1, 0x00004042 },
318 { 0x41bed0, 1, 0x00004042 },
322 const struct nvkm_therm_clkgate_init
323 gk104_clkgate_blcg_init_rop_zrop_0
[] = {
324 { 0x408810, 2, 0x00004042 },
328 const struct nvkm_therm_clkgate_init
329 gk104_clkgate_blcg_init_rop_0
[] = {
330 { 0x408a80, 6, 0x00004042 },
334 const struct nvkm_therm_clkgate_init
335 gk104_clkgate_blcg_init_rop_crop_0
[] = {
336 { 0x4089a8, 1, 0x00004042 },
337 { 0x4089b0, 1, 0x00000042 },
338 { 0x4089b8, 1, 0x00004042 },
342 const struct nvkm_therm_clkgate_init
343 gk104_clkgate_blcg_init_pxbar_0
[] = {
344 { 0x13c820, 1, 0x0001007f },
345 { 0x13cbe0, 1, 0x00000042 },
349 static const struct nvkm_therm_clkgate_pack
350 gk104_clkgate_pack
[] = {
351 { gk104_clkgate_blcg_init_main_0
},
352 { gk104_clkgate_blcg_init_rstr2d_0
},
353 { gk104_clkgate_blcg_init_unk_0
},
354 { gk104_clkgate_blcg_init_gcc_0
},
355 { gk104_clkgate_blcg_init_sked_0
},
356 { gk104_clkgate_blcg_init_unk_1
},
357 { gk104_clkgate_blcg_init_gpc_ctxctl_0
},
358 { gk104_clkgate_blcg_init_gpc_unk_0
},
359 { gk104_clkgate_blcg_init_gpc_esetup_0
},
360 { gk104_clkgate_blcg_init_gpc_tpbus_0
},
361 { gk104_clkgate_blcg_init_gpc_zcull_0
},
362 { gk104_clkgate_blcg_init_gpc_tpconf_0
},
363 { gk104_clkgate_blcg_init_gpc_unk_1
},
364 { gk104_clkgate_blcg_init_gpc_gcc_0
},
365 { gk104_clkgate_blcg_init_gpc_ffb_0
},
366 { gk104_clkgate_blcg_init_gpc_tex_0
},
367 { gk104_clkgate_blcg_init_gpc_poly_0
},
368 { gk104_clkgate_blcg_init_gpc_l1c_0
},
369 { gk104_clkgate_blcg_init_gpc_unk_2
},
370 { gk104_clkgate_blcg_init_gpc_mp_0
},
371 { gk104_clkgate_blcg_init_gpc_ppc_0
},
372 { gk104_clkgate_blcg_init_rop_zrop_0
},
373 { gk104_clkgate_blcg_init_rop_0
},
374 { gk104_clkgate_blcg_init_rop_crop_0
},
375 { gk104_clkgate_blcg_init_pxbar_0
},
379 /*******************************************************************************
380 * PGRAPH engine/subdev functions
381 ******************************************************************************/
384 gk104_gr_init_rop_active_fbps(struct gf100_gr
*gr
)
386 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
387 const u32 fbp_count
= nvkm_rd32(device
, 0x120074);
388 nvkm_mask(device
, 0x408850, 0x0000000f, fbp_count
); /* zrop */
389 nvkm_mask(device
, 0x408958, 0x0000000f, fbp_count
); /* crop */
393 gk104_gr_init_ppc_exceptions(struct gf100_gr
*gr
)
395 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
398 for (gpc
= 0; gpc
< gr
->gpc_nr
; gpc
++) {
399 for (ppc
= 0; ppc
< gr
->ppc_nr
[gpc
]; ppc
++) {
400 if (!(gr
->ppc_mask
[gpc
] & (1 << ppc
)))
402 nvkm_wr32(device
, PPC_UNIT(gpc
, ppc
, 0x038), 0xc0000000);
408 gk104_gr_init(struct gf100_gr
*gr
)
410 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
411 const u32 magicgpc918
= DIV_ROUND_UP(0x00800000, gr
->tpc_total
);
412 u32 data
[TPC_MAX
/ 8] = {};
417 gr
->func
->init_gpc_mmu(gr
);
419 gf100_gr_mmio(gr
, gr
->func
->mmio
);
420 if (gr
->func
->clkgate_pack
)
421 nvkm_therm_clkgate_init(gr
->base
.engine
.subdev
.device
->therm
,
422 gr
->func
->clkgate_pack
);
424 nvkm_wr32(device
, GPC_UNIT(0, 0x3018), 0x00000001);
426 memset(data
, 0x00, sizeof(data
));
427 memcpy(tpcnr
, gr
->tpc_nr
, sizeof(gr
->tpc_nr
));
428 for (i
= 0, gpc
= -1; i
< gr
->tpc_total
; i
++) {
430 gpc
= (gpc
+ 1) % gr
->gpc_nr
;
431 } while (!tpcnr
[gpc
]);
432 tpc
= gr
->tpc_nr
[gpc
] - tpcnr
[gpc
]--;
434 data
[i
/ 8] |= tpc
<< ((i
% 8) * 4);
437 nvkm_wr32(device
, GPC_BCAST(0x0980), data
[0]);
438 nvkm_wr32(device
, GPC_BCAST(0x0984), data
[1]);
439 nvkm_wr32(device
, GPC_BCAST(0x0988), data
[2]);
440 nvkm_wr32(device
, GPC_BCAST(0x098c), data
[3]);
442 for (gpc
= 0; gpc
< gr
->gpc_nr
; gpc
++) {
443 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0914),
444 gr
->screen_tile_row_offset
<< 8 | gr
->tpc_nr
[gpc
]);
445 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0910), 0x00040000 |
447 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0918), magicgpc918
);
450 nvkm_wr32(device
, GPC_BCAST(0x3fd4), magicgpc918
);
451 nvkm_wr32(device
, GPC_BCAST(0x08ac), nvkm_rd32(device
, 0x100800));
453 gr
->func
->init_rop_active_fbps(gr
);
455 nvkm_wr32(device
, 0x400500, 0x00010001);
457 nvkm_wr32(device
, 0x400100, 0xffffffff);
458 nvkm_wr32(device
, 0x40013c, 0xffffffff);
460 nvkm_wr32(device
, 0x409ffc, 0x00000000);
461 nvkm_wr32(device
, 0x409c14, 0x00003e3e);
462 nvkm_wr32(device
, 0x409c24, 0x000f0001);
463 nvkm_wr32(device
, 0x404000, 0xc0000000);
464 nvkm_wr32(device
, 0x404600, 0xc0000000);
465 nvkm_wr32(device
, 0x408030, 0xc0000000);
466 nvkm_wr32(device
, 0x404490, 0xc0000000);
467 nvkm_wr32(device
, 0x406018, 0xc0000000);
468 nvkm_wr32(device
, 0x407020, 0x40000000);
469 nvkm_wr32(device
, 0x405840, 0xc0000000);
470 nvkm_wr32(device
, 0x405844, 0x00ffffff);
471 nvkm_mask(device
, 0x419cc0, 0x00000008, 0x00000008);
472 nvkm_mask(device
, 0x419eb4, 0x00001000, 0x00001000);
474 gr
->func
->init_ppc_exceptions(gr
);
476 for (gpc
= 0; gpc
< gr
->gpc_nr
; gpc
++) {
477 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0420), 0xc0000000);
478 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0900), 0xc0000000);
479 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x1028), 0xc0000000);
480 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0824), 0xc0000000);
481 for (tpc
= 0; tpc
< gr
->tpc_nr
[gpc
]; tpc
++) {
482 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x508), 0xffffffff);
483 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x50c), 0xffffffff);
484 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x224), 0xc0000000);
485 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x48c), 0xc0000000);
486 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x084), 0xc0000000);
487 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x644), 0x001ffffe);
488 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x64c), 0x0000000f);
490 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x2c90), 0xffffffff);
491 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x2c94), 0xffffffff);
494 for (rop
= 0; rop
< gr
->rop_nr
; rop
++) {
495 nvkm_wr32(device
, ROP_UNIT(rop
, 0x144), 0xc0000000);
496 nvkm_wr32(device
, ROP_UNIT(rop
, 0x070), 0xc0000000);
497 nvkm_wr32(device
, ROP_UNIT(rop
, 0x204), 0xffffffff);
498 nvkm_wr32(device
, ROP_UNIT(rop
, 0x208), 0xffffffff);
501 nvkm_wr32(device
, 0x400108, 0xffffffff);
502 nvkm_wr32(device
, 0x400138, 0xffffffff);
503 nvkm_wr32(device
, 0x400118, 0xffffffff);
504 nvkm_wr32(device
, 0x400130, 0xffffffff);
505 nvkm_wr32(device
, 0x40011c, 0xffffffff);
506 nvkm_wr32(device
, 0x400134, 0xffffffff);
508 nvkm_wr32(device
, 0x400054, 0x34ce3464);
510 gf100_gr_zbc_init(gr
);
512 return gf100_gr_init_ctxctl(gr
);
515 #include "fuc/hubgk104.fuc3.h"
517 static struct gf100_gr_ucode
518 gk104_gr_fecs_ucode
= {
519 .code
.data
= gk104_grhub_code
,
520 .code
.size
= sizeof(gk104_grhub_code
),
521 .data
.data
= gk104_grhub_data
,
522 .data
.size
= sizeof(gk104_grhub_data
),
525 #include "fuc/gpcgk104.fuc3.h"
527 static struct gf100_gr_ucode
528 gk104_gr_gpccs_ucode
= {
529 .code
.data
= gk104_grgpc_code
,
530 .code
.size
= sizeof(gk104_grgpc_code
),
531 .data
.data
= gk104_grgpc_data
,
532 .data
.size
= sizeof(gk104_grgpc_data
),
535 static const struct gf100_gr_func
537 .init
= gk104_gr_init
,
538 .init_gpc_mmu
= gf100_gr_init_gpc_mmu
,
539 .init_rop_active_fbps
= gk104_gr_init_rop_active_fbps
,
540 .init_ppc_exceptions
= gk104_gr_init_ppc_exceptions
,
541 .mmio
= gk104_gr_pack_mmio
,
542 .fecs
.ucode
= &gk104_gr_fecs_ucode
,
543 .gpccs
.ucode
= &gk104_gr_gpccs_ucode
,
544 .rops
= gf100_gr_rops
,
546 .grctx
= &gk104_grctx
,
547 .clkgate_pack
= gk104_clkgate_pack
,
549 { -1, -1, FERMI_TWOD_A
},
550 { -1, -1, KEPLER_INLINE_TO_MEMORY_A
},
551 { -1, -1, KEPLER_A
, &gf100_fermi
},
552 { -1, -1, KEPLER_COMPUTE_A
},
558 gk104_gr_new(struct nvkm_device
*device
, int index
, struct nvkm_gr
**pgr
)
560 return gf100_gr_new_(&gk104_gr
, device
, index
, pgr
);