2 * Copyright 2012 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.
28 #include <core/client.h>
29 #include <core/option.h>
30 #include <core/firmware.h>
31 #include <subdev/secboot.h>
32 #include <subdev/fb.h>
33 #include <subdev/mc.h>
34 #include <subdev/pmu.h>
35 #include <subdev/timer.h>
36 #include <engine/fifo.h>
38 #include <nvif/class.h>
39 #include <nvif/cl9097.h>
40 #include <nvif/unpack.h>
42 /*******************************************************************************
43 * Zero Bandwidth Clear
44 ******************************************************************************/
47 gf100_gr_zbc_clear_color(struct gf100_gr
*gr
, int zbc
)
49 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
50 if (gr
->zbc_color
[zbc
].format
) {
51 nvkm_wr32(device
, 0x405804, gr
->zbc_color
[zbc
].ds
[0]);
52 nvkm_wr32(device
, 0x405808, gr
->zbc_color
[zbc
].ds
[1]);
53 nvkm_wr32(device
, 0x40580c, gr
->zbc_color
[zbc
].ds
[2]);
54 nvkm_wr32(device
, 0x405810, gr
->zbc_color
[zbc
].ds
[3]);
56 nvkm_wr32(device
, 0x405814, gr
->zbc_color
[zbc
].format
);
57 nvkm_wr32(device
, 0x405820, zbc
);
58 nvkm_wr32(device
, 0x405824, 0x00000004); /* TRIGGER | WRITE | COLOR */
62 gf100_gr_zbc_color_get(struct gf100_gr
*gr
, int format
,
63 const u32 ds
[4], const u32 l2
[4])
65 struct nvkm_ltc
*ltc
= gr
->base
.engine
.subdev
.device
->ltc
;
68 for (i
= ltc
->zbc_min
; i
<= ltc
->zbc_max
; i
++) {
69 if (gr
->zbc_color
[i
].format
) {
70 if (gr
->zbc_color
[i
].format
!= format
)
72 if (memcmp(gr
->zbc_color
[i
].ds
, ds
, sizeof(
73 gr
->zbc_color
[i
].ds
)))
75 if (memcmp(gr
->zbc_color
[i
].l2
, l2
, sizeof(
76 gr
->zbc_color
[i
].l2
))) {
82 zbc
= (zbc
< 0) ? i
: zbc
;
89 memcpy(gr
->zbc_color
[zbc
].ds
, ds
, sizeof(gr
->zbc_color
[zbc
].ds
));
90 memcpy(gr
->zbc_color
[zbc
].l2
, l2
, sizeof(gr
->zbc_color
[zbc
].l2
));
91 gr
->zbc_color
[zbc
].format
= format
;
92 nvkm_ltc_zbc_color_get(ltc
, zbc
, l2
);
93 gf100_gr_zbc_clear_color(gr
, zbc
);
98 gf100_gr_zbc_clear_depth(struct gf100_gr
*gr
, int zbc
)
100 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
101 if (gr
->zbc_depth
[zbc
].format
)
102 nvkm_wr32(device
, 0x405818, gr
->zbc_depth
[zbc
].ds
);
103 nvkm_wr32(device
, 0x40581c, gr
->zbc_depth
[zbc
].format
);
104 nvkm_wr32(device
, 0x405820, zbc
);
105 nvkm_wr32(device
, 0x405824, 0x00000005); /* TRIGGER | WRITE | DEPTH */
109 gf100_gr_zbc_depth_get(struct gf100_gr
*gr
, int format
,
110 const u32 ds
, const u32 l2
)
112 struct nvkm_ltc
*ltc
= gr
->base
.engine
.subdev
.device
->ltc
;
113 int zbc
= -ENOSPC
, i
;
115 for (i
= ltc
->zbc_min
; i
<= ltc
->zbc_max
; i
++) {
116 if (gr
->zbc_depth
[i
].format
) {
117 if (gr
->zbc_depth
[i
].format
!= format
)
119 if (gr
->zbc_depth
[i
].ds
!= ds
)
121 if (gr
->zbc_depth
[i
].l2
!= l2
) {
127 zbc
= (zbc
< 0) ? i
: zbc
;
134 gr
->zbc_depth
[zbc
].format
= format
;
135 gr
->zbc_depth
[zbc
].ds
= ds
;
136 gr
->zbc_depth
[zbc
].l2
= l2
;
137 nvkm_ltc_zbc_depth_get(ltc
, zbc
, l2
);
138 gf100_gr_zbc_clear_depth(gr
, zbc
);
142 /*******************************************************************************
143 * Graphics object classes
144 ******************************************************************************/
145 #define gf100_gr_object(p) container_of((p), struct gf100_gr_object, object)
147 struct gf100_gr_object
{
148 struct nvkm_object object
;
149 struct gf100_gr_chan
*chan
;
153 gf100_fermi_mthd_zbc_color(struct nvkm_object
*object
, void *data
, u32 size
)
155 struct gf100_gr
*gr
= gf100_gr(nvkm_gr(object
->engine
));
157 struct fermi_a_zbc_color_v0 v0
;
161 if (!(ret
= nvif_unpack(ret
, &data
, &size
, args
->v0
, 0, 0, false))) {
162 switch (args
->v0
.format
) {
163 case FERMI_A_ZBC_COLOR_V0_FMT_ZERO
:
164 case FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE
:
165 case FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32
:
166 case FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16
:
167 case FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16
:
168 case FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16
:
169 case FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16
:
170 case FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16
:
171 case FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8
:
172 case FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8
:
173 case FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10
:
174 case FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10
:
175 case FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8
:
176 case FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8
:
177 case FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8
:
178 case FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8
:
179 case FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8
:
180 case FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10
:
181 case FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11
:
182 ret
= gf100_gr_zbc_color_get(gr
, args
->v0
.format
,
186 args
->v0
.index
= ret
;
199 gf100_fermi_mthd_zbc_depth(struct nvkm_object
*object
, void *data
, u32 size
)
201 struct gf100_gr
*gr
= gf100_gr(nvkm_gr(object
->engine
));
203 struct fermi_a_zbc_depth_v0 v0
;
207 if (!(ret
= nvif_unpack(ret
, &data
, &size
, args
->v0
, 0, 0, false))) {
208 switch (args
->v0
.format
) {
209 case FERMI_A_ZBC_DEPTH_V0_FMT_FP32
:
210 ret
= gf100_gr_zbc_depth_get(gr
, args
->v0
.format
,
213 return (ret
>= 0) ? 0 : -ENOSPC
;
223 gf100_fermi_mthd(struct nvkm_object
*object
, u32 mthd
, void *data
, u32 size
)
225 nvif_ioctl(object
, "fermi mthd %08x\n", mthd
);
227 case FERMI_A_ZBC_COLOR
:
228 return gf100_fermi_mthd_zbc_color(object
, data
, size
);
229 case FERMI_A_ZBC_DEPTH
:
230 return gf100_fermi_mthd_zbc_depth(object
, data
, size
);
237 const struct nvkm_object_func
239 .mthd
= gf100_fermi_mthd
,
243 gf100_gr_mthd_set_shader_exceptions(struct nvkm_device
*device
, u32 data
)
245 nvkm_wr32(device
, 0x419e44, data
? 0xffffffff : 0x00000000);
246 nvkm_wr32(device
, 0x419e4c, data
? 0xffffffff : 0x00000000);
250 gf100_gr_mthd_sw(struct nvkm_device
*device
, u16
class, u32 mthd
, u32 data
)
252 switch (class & 0x00ff) {
257 gf100_gr_mthd_set_shader_exceptions(device
, data
);
269 static const struct nvkm_object_func
270 gf100_gr_object_func
= {
274 gf100_gr_object_new(const struct nvkm_oclass
*oclass
, void *data
, u32 size
,
275 struct nvkm_object
**pobject
)
277 struct gf100_gr_chan
*chan
= gf100_gr_chan(oclass
->parent
);
278 struct gf100_gr_object
*object
;
280 if (!(object
= kzalloc(sizeof(*object
), GFP_KERNEL
)))
282 *pobject
= &object
->object
;
284 nvkm_object_ctor(oclass
->base
.func
? oclass
->base
.func
:
285 &gf100_gr_object_func
, oclass
, &object
->object
);
291 gf100_gr_object_get(struct nvkm_gr
*base
, int index
, struct nvkm_sclass
*sclass
)
293 struct gf100_gr
*gr
= gf100_gr(base
);
296 while (gr
->func
->sclass
[c
].oclass
) {
298 *sclass
= gr
->func
->sclass
[index
];
299 sclass
->ctor
= gf100_gr_object_new
;
307 /*******************************************************************************
309 ******************************************************************************/
312 gf100_gr_chan_bind(struct nvkm_object
*object
, struct nvkm_gpuobj
*parent
,
313 int align
, struct nvkm_gpuobj
**pgpuobj
)
315 struct gf100_gr_chan
*chan
= gf100_gr_chan(object
);
316 struct gf100_gr
*gr
= chan
->gr
;
319 ret
= nvkm_gpuobj_new(gr
->base
.engine
.subdev
.device
, gr
->size
,
320 align
, false, parent
, pgpuobj
);
325 for (i
= 0; i
< gr
->size
; i
+= 4)
326 nvkm_wo32(*pgpuobj
, i
, gr
->data
[i
/ 4]);
329 nvkm_wo32(*pgpuobj
, 0x00, chan
->mmio_nr
/ 2);
330 nvkm_wo32(*pgpuobj
, 0x04, chan
->mmio_vma
.offset
>> 8);
332 nvkm_wo32(*pgpuobj
, 0xf4, 0);
333 nvkm_wo32(*pgpuobj
, 0xf8, 0);
334 nvkm_wo32(*pgpuobj
, 0x10, chan
->mmio_nr
/ 2);
335 nvkm_wo32(*pgpuobj
, 0x14, lower_32_bits(chan
->mmio_vma
.offset
));
336 nvkm_wo32(*pgpuobj
, 0x18, upper_32_bits(chan
->mmio_vma
.offset
));
337 nvkm_wo32(*pgpuobj
, 0x1c, 1);
338 nvkm_wo32(*pgpuobj
, 0x20, 0);
339 nvkm_wo32(*pgpuobj
, 0x28, 0);
340 nvkm_wo32(*pgpuobj
, 0x2c, 0);
347 gf100_gr_chan_dtor(struct nvkm_object
*object
)
349 struct gf100_gr_chan
*chan
= gf100_gr_chan(object
);
352 for (i
= 0; i
< ARRAY_SIZE(chan
->data
); i
++) {
353 if (chan
->data
[i
].vma
.node
) {
354 nvkm_vm_unmap(&chan
->data
[i
].vma
);
355 nvkm_vm_put(&chan
->data
[i
].vma
);
357 nvkm_memory_del(&chan
->data
[i
].mem
);
360 if (chan
->mmio_vma
.node
) {
361 nvkm_vm_unmap(&chan
->mmio_vma
);
362 nvkm_vm_put(&chan
->mmio_vma
);
364 nvkm_memory_del(&chan
->mmio
);
368 static const struct nvkm_object_func
370 .dtor
= gf100_gr_chan_dtor
,
371 .bind
= gf100_gr_chan_bind
,
375 gf100_gr_chan_new(struct nvkm_gr
*base
, struct nvkm_fifo_chan
*fifoch
,
376 const struct nvkm_oclass
*oclass
,
377 struct nvkm_object
**pobject
)
379 struct gf100_gr
*gr
= gf100_gr(base
);
380 struct gf100_gr_data
*data
= gr
->mmio_data
;
381 struct gf100_gr_mmio
*mmio
= gr
->mmio_list
;
382 struct gf100_gr_chan
*chan
;
383 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
386 if (!(chan
= kzalloc(sizeof(*chan
), GFP_KERNEL
)))
388 nvkm_object_ctor(&gf100_gr_chan
, oclass
, &chan
->object
);
390 *pobject
= &chan
->object
;
392 /* allocate memory for a "mmio list" buffer that's used by the HUB
393 * fuc to modify some per-context register settings on first load
396 ret
= nvkm_memory_new(device
, NVKM_MEM_TARGET_INST
, 0x1000, 0x100,
401 ret
= nvkm_vm_get(fifoch
->vm
, 0x1000, 12, NV_MEM_ACCESS_RW
|
402 NV_MEM_ACCESS_SYS
, &chan
->mmio_vma
);
406 nvkm_memory_map(chan
->mmio
, &chan
->mmio_vma
, 0);
408 /* allocate buffers referenced by mmio list */
409 for (i
= 0; data
->size
&& i
< ARRAY_SIZE(gr
->mmio_data
); i
++) {
410 ret
= nvkm_memory_new(device
, NVKM_MEM_TARGET_INST
,
411 data
->size
, data
->align
, false,
416 ret
= nvkm_vm_get(fifoch
->vm
,
417 nvkm_memory_size(chan
->data
[i
].mem
), 12,
418 data
->access
, &chan
->data
[i
].vma
);
422 nvkm_memory_map(chan
->data
[i
].mem
, &chan
->data
[i
].vma
, 0);
426 /* finally, fill in the mmio list and point the context at it */
427 nvkm_kmap(chan
->mmio
);
428 for (i
= 0; mmio
->addr
&& i
< ARRAY_SIZE(gr
->mmio_list
); i
++) {
429 u32 addr
= mmio
->addr
;
430 u32 data
= mmio
->data
;
432 if (mmio
->buffer
>= 0) {
433 u64 info
= chan
->data
[mmio
->buffer
].vma
.offset
;
434 data
|= info
>> mmio
->shift
;
437 nvkm_wo32(chan
->mmio
, chan
->mmio_nr
++ * 4, addr
);
438 nvkm_wo32(chan
->mmio
, chan
->mmio_nr
++ * 4, data
);
441 nvkm_done(chan
->mmio
);
445 /*******************************************************************************
446 * PGRAPH register lists
447 ******************************************************************************/
449 const struct gf100_gr_init
450 gf100_gr_init_main_0
[] = {
451 { 0x400080, 1, 0x04, 0x003083c2 },
452 { 0x400088, 1, 0x04, 0x00006fe7 },
453 { 0x40008c, 1, 0x04, 0x00000000 },
454 { 0x400090, 1, 0x04, 0x00000030 },
455 { 0x40013c, 1, 0x04, 0x013901f7 },
456 { 0x400140, 1, 0x04, 0x00000100 },
457 { 0x400144, 1, 0x04, 0x00000000 },
458 { 0x400148, 1, 0x04, 0x00000110 },
459 { 0x400138, 1, 0x04, 0x00000000 },
460 { 0x400130, 2, 0x04, 0x00000000 },
461 { 0x400124, 1, 0x04, 0x00000002 },
465 const struct gf100_gr_init
466 gf100_gr_init_fe_0
[] = {
467 { 0x40415c, 1, 0x04, 0x00000000 },
468 { 0x404170, 1, 0x04, 0x00000000 },
472 const struct gf100_gr_init
473 gf100_gr_init_pri_0
[] = {
474 { 0x404488, 2, 0x04, 0x00000000 },
478 const struct gf100_gr_init
479 gf100_gr_init_rstr2d_0
[] = {
480 { 0x407808, 1, 0x04, 0x00000000 },
484 const struct gf100_gr_init
485 gf100_gr_init_pd_0
[] = {
486 { 0x406024, 1, 0x04, 0x00000000 },
490 const struct gf100_gr_init
491 gf100_gr_init_ds_0
[] = {
492 { 0x405844, 1, 0x04, 0x00ffffff },
493 { 0x405850, 1, 0x04, 0x00000000 },
494 { 0x405908, 1, 0x04, 0x00000000 },
498 const struct gf100_gr_init
499 gf100_gr_init_scc_0
[] = {
500 { 0x40803c, 1, 0x04, 0x00000000 },
504 const struct gf100_gr_init
505 gf100_gr_init_prop_0
[] = {
506 { 0x4184a0, 1, 0x04, 0x00000000 },
510 const struct gf100_gr_init
511 gf100_gr_init_gpc_unk_0
[] = {
512 { 0x418604, 1, 0x04, 0x00000000 },
513 { 0x418680, 1, 0x04, 0x00000000 },
514 { 0x418714, 1, 0x04, 0x80000000 },
515 { 0x418384, 1, 0x04, 0x00000000 },
519 const struct gf100_gr_init
520 gf100_gr_init_setup_0
[] = {
521 { 0x418814, 3, 0x04, 0x00000000 },
525 const struct gf100_gr_init
526 gf100_gr_init_crstr_0
[] = {
527 { 0x418b04, 1, 0x04, 0x00000000 },
531 const struct gf100_gr_init
532 gf100_gr_init_setup_1
[] = {
533 { 0x4188c8, 1, 0x04, 0x80000000 },
534 { 0x4188cc, 1, 0x04, 0x00000000 },
535 { 0x4188d0, 1, 0x04, 0x00010000 },
536 { 0x4188d4, 1, 0x04, 0x00000001 },
540 const struct gf100_gr_init
541 gf100_gr_init_zcull_0
[] = {
542 { 0x418910, 1, 0x04, 0x00010001 },
543 { 0x418914, 1, 0x04, 0x00000301 },
544 { 0x418918, 1, 0x04, 0x00800000 },
545 { 0x418980, 1, 0x04, 0x77777770 },
546 { 0x418984, 3, 0x04, 0x77777777 },
550 const struct gf100_gr_init
551 gf100_gr_init_gpm_0
[] = {
552 { 0x418c04, 1, 0x04, 0x00000000 },
553 { 0x418c88, 1, 0x04, 0x00000000 },
557 const struct gf100_gr_init
558 gf100_gr_init_gpc_unk_1
[] = {
559 { 0x418d00, 1, 0x04, 0x00000000 },
560 { 0x418f08, 1, 0x04, 0x00000000 },
561 { 0x418e00, 1, 0x04, 0x00000050 },
562 { 0x418e08, 1, 0x04, 0x00000000 },
566 const struct gf100_gr_init
567 gf100_gr_init_gcc_0
[] = {
568 { 0x41900c, 1, 0x04, 0x00000000 },
569 { 0x419018, 1, 0x04, 0x00000000 },
573 const struct gf100_gr_init
574 gf100_gr_init_tpccs_0
[] = {
575 { 0x419d08, 2, 0x04, 0x00000000 },
576 { 0x419d10, 1, 0x04, 0x00000014 },
580 const struct gf100_gr_init
581 gf100_gr_init_tex_0
[] = {
582 { 0x419ab0, 1, 0x04, 0x00000000 },
583 { 0x419ab8, 1, 0x04, 0x000000e7 },
584 { 0x419abc, 2, 0x04, 0x00000000 },
588 const struct gf100_gr_init
589 gf100_gr_init_pe_0
[] = {
590 { 0x41980c, 3, 0x04, 0x00000000 },
591 { 0x419844, 1, 0x04, 0x00000000 },
592 { 0x41984c, 1, 0x04, 0x00005bc5 },
593 { 0x419850, 4, 0x04, 0x00000000 },
597 const struct gf100_gr_init
598 gf100_gr_init_l1c_0
[] = {
599 { 0x419c98, 1, 0x04, 0x00000000 },
600 { 0x419ca8, 1, 0x04, 0x80000000 },
601 { 0x419cb4, 1, 0x04, 0x00000000 },
602 { 0x419cb8, 1, 0x04, 0x00008bf4 },
603 { 0x419cbc, 1, 0x04, 0x28137606 },
604 { 0x419cc0, 2, 0x04, 0x00000000 },
608 const struct gf100_gr_init
609 gf100_gr_init_wwdx_0
[] = {
610 { 0x419bd4, 1, 0x04, 0x00800000 },
611 { 0x419bdc, 1, 0x04, 0x00000000 },
615 const struct gf100_gr_init
616 gf100_gr_init_tpccs_1
[] = {
617 { 0x419d2c, 1, 0x04, 0x00000000 },
621 const struct gf100_gr_init
622 gf100_gr_init_mpc_0
[] = {
623 { 0x419c0c, 1, 0x04, 0x00000000 },
627 static const struct gf100_gr_init
628 gf100_gr_init_sm_0
[] = {
629 { 0x419e00, 1, 0x04, 0x00000000 },
630 { 0x419ea0, 1, 0x04, 0x00000000 },
631 { 0x419ea4, 1, 0x04, 0x00000100 },
632 { 0x419ea8, 1, 0x04, 0x00001100 },
633 { 0x419eac, 1, 0x04, 0x11100702 },
634 { 0x419eb0, 1, 0x04, 0x00000003 },
635 { 0x419eb4, 4, 0x04, 0x00000000 },
636 { 0x419ec8, 1, 0x04, 0x06060618 },
637 { 0x419ed0, 1, 0x04, 0x0eff0e38 },
638 { 0x419ed4, 1, 0x04, 0x011104f1 },
639 { 0x419edc, 1, 0x04, 0x00000000 },
640 { 0x419f00, 1, 0x04, 0x00000000 },
641 { 0x419f2c, 1, 0x04, 0x00000000 },
645 const struct gf100_gr_init
646 gf100_gr_init_be_0
[] = {
647 { 0x40880c, 1, 0x04, 0x00000000 },
648 { 0x408910, 9, 0x04, 0x00000000 },
649 { 0x408950, 1, 0x04, 0x00000000 },
650 { 0x408954, 1, 0x04, 0x0000ffff },
651 { 0x408984, 1, 0x04, 0x00000000 },
652 { 0x408988, 1, 0x04, 0x08040201 },
653 { 0x40898c, 1, 0x04, 0x80402010 },
657 const struct gf100_gr_init
658 gf100_gr_init_fe_1
[] = {
659 { 0x4040f0, 1, 0x04, 0x00000000 },
663 const struct gf100_gr_init
664 gf100_gr_init_pe_1
[] = {
665 { 0x419880, 1, 0x04, 0x00000002 },
669 static const struct gf100_gr_pack
670 gf100_gr_pack_mmio
[] = {
671 { gf100_gr_init_main_0
},
672 { gf100_gr_init_fe_0
},
673 { gf100_gr_init_pri_0
},
674 { gf100_gr_init_rstr2d_0
},
675 { gf100_gr_init_pd_0
},
676 { gf100_gr_init_ds_0
},
677 { gf100_gr_init_scc_0
},
678 { gf100_gr_init_prop_0
},
679 { gf100_gr_init_gpc_unk_0
},
680 { gf100_gr_init_setup_0
},
681 { gf100_gr_init_crstr_0
},
682 { gf100_gr_init_setup_1
},
683 { gf100_gr_init_zcull_0
},
684 { gf100_gr_init_gpm_0
},
685 { gf100_gr_init_gpc_unk_1
},
686 { gf100_gr_init_gcc_0
},
687 { gf100_gr_init_tpccs_0
},
688 { gf100_gr_init_tex_0
},
689 { gf100_gr_init_pe_0
},
690 { gf100_gr_init_l1c_0
},
691 { gf100_gr_init_wwdx_0
},
692 { gf100_gr_init_tpccs_1
},
693 { gf100_gr_init_mpc_0
},
694 { gf100_gr_init_sm_0
},
695 { gf100_gr_init_be_0
},
696 { gf100_gr_init_fe_1
},
697 { gf100_gr_init_pe_1
},
701 /*******************************************************************************
702 * PGRAPH engine/subdev functions
703 ******************************************************************************/
706 gf100_gr_rops(struct gf100_gr
*gr
)
708 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
709 return (nvkm_rd32(device
, 0x409604) & 0x001f0000) >> 16;
713 gf100_gr_zbc_init(struct gf100_gr
*gr
)
715 const u32 zero
[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000,
716 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
717 const u32 one
[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
718 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
719 const u32 f32_0
[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000,
720 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
721 const u32 f32_1
[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
722 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 };
723 struct nvkm_ltc
*ltc
= gr
->base
.engine
.subdev
.device
->ltc
;
726 if (!gr
->zbc_color
[0].format
) {
727 gf100_gr_zbc_color_get(gr
, 1, & zero
[0], &zero
[4]);
728 gf100_gr_zbc_color_get(gr
, 2, & one
[0], &one
[4]);
729 gf100_gr_zbc_color_get(gr
, 4, &f32_0
[0], &f32_0
[4]);
730 gf100_gr_zbc_color_get(gr
, 4, &f32_1
[0], &f32_1
[4]);
731 gf100_gr_zbc_depth_get(gr
, 1, 0x00000000, 0x00000000);
732 gf100_gr_zbc_depth_get(gr
, 1, 0x3f800000, 0x3f800000);
735 for (index
= ltc
->zbc_min
; index
<= ltc
->zbc_max
; index
++)
736 gf100_gr_zbc_clear_color(gr
, index
);
737 for (index
= ltc
->zbc_min
; index
<= ltc
->zbc_max
; index
++)
738 gf100_gr_zbc_clear_depth(gr
, index
);
742 * Wait until GR goes idle. GR is considered idle if it is disabled by the
743 * MC (0x200) register, or GR is not busy and a context switch is not in
747 gf100_gr_wait_idle(struct gf100_gr
*gr
)
749 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
750 struct nvkm_device
*device
= subdev
->device
;
751 unsigned long end_jiffies
= jiffies
+ msecs_to_jiffies(2000);
752 bool gr_enabled
, ctxsw_active
, gr_busy
;
756 * required to make sure FIFO_ENGINE_STATUS (0x2640) is
759 nvkm_rd32(device
, 0x400700);
761 gr_enabled
= nvkm_rd32(device
, 0x200) & 0x1000;
762 ctxsw_active
= nvkm_rd32(device
, 0x2640) & 0x8000;
763 gr_busy
= nvkm_rd32(device
, 0x40060c) & 0x1;
765 if (!gr_enabled
|| (!gr_busy
&& !ctxsw_active
))
767 } while (time_before(jiffies
, end_jiffies
));
770 "wait for idle timeout (en: %d, ctxsw: %d, busy: %d)\n",
771 gr_enabled
, ctxsw_active
, gr_busy
);
776 gf100_gr_mmio(struct gf100_gr
*gr
, const struct gf100_gr_pack
*p
)
778 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
779 const struct gf100_gr_pack
*pack
;
780 const struct gf100_gr_init
*init
;
782 pack_for_each_init(init
, pack
, p
) {
783 u32 next
= init
->addr
+ init
->count
* init
->pitch
;
784 u32 addr
= init
->addr
;
785 while (addr
< next
) {
786 nvkm_wr32(device
, addr
, init
->data
);
793 gf100_gr_icmd(struct gf100_gr
*gr
, const struct gf100_gr_pack
*p
)
795 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
796 const struct gf100_gr_pack
*pack
;
797 const struct gf100_gr_init
*init
;
800 nvkm_wr32(device
, 0x400208, 0x80000000);
802 pack_for_each_init(init
, pack
, p
) {
803 u32 next
= init
->addr
+ init
->count
* init
->pitch
;
804 u32 addr
= init
->addr
;
806 if ((pack
== p
&& init
== p
->init
) || data
!= init
->data
) {
807 nvkm_wr32(device
, 0x400204, init
->data
);
811 while (addr
< next
) {
812 nvkm_wr32(device
, 0x400200, addr
);
814 * Wait for GR to go idle after submitting a
817 if ((addr
& 0xffff) == 0xe100)
818 gf100_gr_wait_idle(gr
);
819 nvkm_msec(device
, 2000,
820 if (!(nvkm_rd32(device
, 0x400700) & 0x00000004))
827 nvkm_wr32(device
, 0x400208, 0x00000000);
831 gf100_gr_mthd(struct gf100_gr
*gr
, const struct gf100_gr_pack
*p
)
833 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
834 const struct gf100_gr_pack
*pack
;
835 const struct gf100_gr_init
*init
;
838 pack_for_each_init(init
, pack
, p
) {
839 u32 ctrl
= 0x80000000 | pack
->type
;
840 u32 next
= init
->addr
+ init
->count
* init
->pitch
;
841 u32 addr
= init
->addr
;
843 if ((pack
== p
&& init
== p
->init
) || data
!= init
->data
) {
844 nvkm_wr32(device
, 0x40448c, init
->data
);
848 while (addr
< next
) {
849 nvkm_wr32(device
, 0x404488, ctrl
| (addr
<< 14));
856 gf100_gr_units(struct nvkm_gr
*base
)
858 struct gf100_gr
*gr
= gf100_gr(base
);
861 cfg
= (u32
)gr
->gpc_nr
;
862 cfg
|= (u32
)gr
->tpc_total
<< 8;
863 cfg
|= (u64
)gr
->rop_nr
<< 32;
868 static const struct nvkm_bitfield gf100_dispatch_error
[] = {
869 { 0x00000001, "INJECTED_BUNDLE_ERROR" },
870 { 0x00000002, "CLASS_SUBCH_MISMATCH" },
871 { 0x00000004, "SUBCHSW_DURING_NOTIFY" },
875 static const struct nvkm_bitfield gf100_m2mf_error
[] = {
876 { 0x00000001, "PUSH_TOO_MUCH_DATA" },
877 { 0x00000002, "PUSH_NOT_ENOUGH_DATA" },
881 static const struct nvkm_bitfield gf100_unk6_error
[] = {
882 { 0x00000001, "TEMP_TOO_SMALL" },
886 static const struct nvkm_bitfield gf100_ccache_error
[] = {
887 { 0x00000001, "INTR" },
888 { 0x00000002, "LDCONST_OOB" },
892 static const struct nvkm_bitfield gf100_macro_error
[] = {
893 { 0x00000001, "TOO_FEW_PARAMS" },
894 { 0x00000002, "TOO_MANY_PARAMS" },
895 { 0x00000004, "ILLEGAL_OPCODE" },
896 { 0x00000008, "DOUBLE_BRANCH" },
897 { 0x00000010, "WATCHDOG" },
901 static const struct nvkm_bitfield gk104_sked_error
[] = {
902 { 0x00000040, "CTA_RESUME" },
903 { 0x00000080, "CONSTANT_BUFFER_SIZE" },
904 { 0x00000200, "LOCAL_MEMORY_SIZE_POS" },
905 { 0x00000400, "LOCAL_MEMORY_SIZE_NEG" },
906 { 0x00000800, "WARP_CSTACK_SIZE" },
907 { 0x00001000, "TOTAL_TEMP_SIZE" },
908 { 0x00002000, "REGISTER_COUNT" },
909 { 0x00040000, "TOTAL_THREADS" },
910 { 0x00100000, "PROGRAM_OFFSET" },
911 { 0x00200000, "SHARED_MEMORY_SIZE" },
912 { 0x00800000, "CTA_THREAD_DIMENSION_ZERO" },
913 { 0x01000000, "MEMORY_WINDOW_OVERLAP" },
914 { 0x02000000, "SHARED_CONFIG_TOO_SMALL" },
915 { 0x04000000, "TOTAL_REGISTER_COUNT" },
919 static const struct nvkm_bitfield gf100_gpc_rop_error
[] = {
920 { 0x00000002, "RT_PITCH_OVERRUN" },
921 { 0x00000010, "RT_WIDTH_OVERRUN" },
922 { 0x00000020, "RT_HEIGHT_OVERRUN" },
923 { 0x00000080, "ZETA_STORAGE_TYPE_MISMATCH" },
924 { 0x00000100, "RT_STORAGE_TYPE_MISMATCH" },
925 { 0x00000400, "RT_LINEAR_MISMATCH" },
930 gf100_gr_trap_gpc_rop(struct gf100_gr
*gr
, int gpc
)
932 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
933 struct nvkm_device
*device
= subdev
->device
;
937 trap
[0] = nvkm_rd32(device
, GPC_UNIT(gpc
, 0x0420)) & 0x3fffffff;
938 trap
[1] = nvkm_rd32(device
, GPC_UNIT(gpc
, 0x0434));
939 trap
[2] = nvkm_rd32(device
, GPC_UNIT(gpc
, 0x0438));
940 trap
[3] = nvkm_rd32(device
, GPC_UNIT(gpc
, 0x043c));
942 nvkm_snprintbf(error
, sizeof(error
), gf100_gpc_rop_error
, trap
[0]);
944 nvkm_error(subdev
, "GPC%d/PROP trap: %08x [%s] x = %u, y = %u, "
945 "format = %x, storage type = %x\n",
946 gpc
, trap
[0], error
, trap
[1] & 0xffff, trap
[1] >> 16,
947 (trap
[2] >> 8) & 0x3f, trap
[3] & 0xff);
948 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0420), 0xc0000000);
951 static const struct nvkm_enum gf100_mp_warp_error
[] = {
952 { 0x01, "STACK_ERROR" },
953 { 0x02, "API_STACK_ERROR" },
954 { 0x03, "RET_EMPTY_STACK_ERROR" },
956 { 0x05, "MISALIGNED_PC" },
957 { 0x06, "PC_OVERFLOW" },
958 { 0x07, "MISALIGNED_IMMC_ADDR" },
959 { 0x08, "MISALIGNED_REG" },
960 { 0x09, "ILLEGAL_INSTR_ENCODING" },
961 { 0x0a, "ILLEGAL_SPH_INSTR_COMBO" },
962 { 0x0b, "ILLEGAL_INSTR_PARAM" },
963 { 0x0c, "INVALID_CONST_ADDR" },
965 { 0x0e, "OOR_ADDR" },
966 { 0x0f, "MISALIGNED_ADDR" },
967 { 0x10, "INVALID_ADDR_SPACE" },
968 { 0x11, "ILLEGAL_INSTR_PARAM2" },
969 { 0x12, "INVALID_CONST_ADDR_LDC" },
970 { 0x13, "GEOMETRY_SM_ERROR" },
971 { 0x14, "DIVERGENT" },
972 { 0x15, "WARP_EXIT" },
976 static const struct nvkm_bitfield gf100_mp_global_error
[] = {
977 { 0x00000001, "SM_TO_SM_FAULT" },
978 { 0x00000002, "L1_ERROR" },
979 { 0x00000004, "MULTIPLE_WARP_ERRORS" },
980 { 0x00000008, "PHYSICAL_STACK_OVERFLOW" },
981 { 0x00000010, "BPT_INT" },
982 { 0x00000020, "BPT_PAUSE" },
983 { 0x00000040, "SINGLE_STEP_COMPLETE" },
984 { 0x20000000, "ECC_SEC_ERROR" },
985 { 0x40000000, "ECC_DED_ERROR" },
986 { 0x80000000, "TIMEOUT" },
991 gf100_gr_trap_mp(struct gf100_gr
*gr
, int gpc
, int tpc
)
993 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
994 struct nvkm_device
*device
= subdev
->device
;
995 u32 werr
= nvkm_rd32(device
, TPC_UNIT(gpc
, tpc
, 0x648));
996 u32 gerr
= nvkm_rd32(device
, TPC_UNIT(gpc
, tpc
, 0x650));
997 const struct nvkm_enum
*warp
;
1000 nvkm_snprintbf(glob
, sizeof(glob
), gf100_mp_global_error
, gerr
);
1001 warp
= nvkm_enum_find(gf100_mp_warp_error
, werr
& 0xffff);
1003 nvkm_error(subdev
, "GPC%i/TPC%i/MP trap: "
1004 "global %08x [%s] warp %04x [%s]\n",
1005 gpc
, tpc
, gerr
, glob
, werr
, warp
? warp
->name
: "");
1007 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x648), 0x00000000);
1008 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x650), gerr
);
1012 gf100_gr_trap_tpc(struct gf100_gr
*gr
, int gpc
, int tpc
)
1014 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1015 struct nvkm_device
*device
= subdev
->device
;
1016 u32 stat
= nvkm_rd32(device
, TPC_UNIT(gpc
, tpc
, 0x0508));
1018 if (stat
& 0x00000001) {
1019 u32 trap
= nvkm_rd32(device
, TPC_UNIT(gpc
, tpc
, 0x0224));
1020 nvkm_error(subdev
, "GPC%d/TPC%d/TEX: %08x\n", gpc
, tpc
, trap
);
1021 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x0224), 0xc0000000);
1022 stat
&= ~0x00000001;
1025 if (stat
& 0x00000002) {
1026 gf100_gr_trap_mp(gr
, gpc
, tpc
);
1027 stat
&= ~0x00000002;
1030 if (stat
& 0x00000004) {
1031 u32 trap
= nvkm_rd32(device
, TPC_UNIT(gpc
, tpc
, 0x0084));
1032 nvkm_error(subdev
, "GPC%d/TPC%d/POLY: %08x\n", gpc
, tpc
, trap
);
1033 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x0084), 0xc0000000);
1034 stat
&= ~0x00000004;
1037 if (stat
& 0x00000008) {
1038 u32 trap
= nvkm_rd32(device
, TPC_UNIT(gpc
, tpc
, 0x048c));
1039 nvkm_error(subdev
, "GPC%d/TPC%d/L1C: %08x\n", gpc
, tpc
, trap
);
1040 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x048c), 0xc0000000);
1041 stat
&= ~0x00000008;
1045 nvkm_error(subdev
, "GPC%d/TPC%d/%08x: unknown\n", gpc
, tpc
, stat
);
1050 gf100_gr_trap_gpc(struct gf100_gr
*gr
, int gpc
)
1052 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1053 struct nvkm_device
*device
= subdev
->device
;
1054 u32 stat
= nvkm_rd32(device
, GPC_UNIT(gpc
, 0x2c90));
1057 if (stat
& 0x00000001) {
1058 gf100_gr_trap_gpc_rop(gr
, gpc
);
1059 stat
&= ~0x00000001;
1062 if (stat
& 0x00000002) {
1063 u32 trap
= nvkm_rd32(device
, GPC_UNIT(gpc
, 0x0900));
1064 nvkm_error(subdev
, "GPC%d/ZCULL: %08x\n", gpc
, trap
);
1065 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0900), 0xc0000000);
1066 stat
&= ~0x00000002;
1069 if (stat
& 0x00000004) {
1070 u32 trap
= nvkm_rd32(device
, GPC_UNIT(gpc
, 0x1028));
1071 nvkm_error(subdev
, "GPC%d/CCACHE: %08x\n", gpc
, trap
);
1072 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x1028), 0xc0000000);
1073 stat
&= ~0x00000004;
1076 if (stat
& 0x00000008) {
1077 u32 trap
= nvkm_rd32(device
, GPC_UNIT(gpc
, 0x0824));
1078 nvkm_error(subdev
, "GPC%d/ESETUP: %08x\n", gpc
, trap
);
1079 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0824), 0xc0000000);
1080 stat
&= ~0x00000009;
1083 for (tpc
= 0; tpc
< gr
->tpc_nr
[gpc
]; tpc
++) {
1084 u32 mask
= 0x00010000 << tpc
;
1086 gf100_gr_trap_tpc(gr
, gpc
, tpc
);
1087 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x2c90), mask
);
1093 nvkm_error(subdev
, "GPC%d/%08x: unknown\n", gpc
, stat
);
1098 gf100_gr_trap_intr(struct gf100_gr
*gr
)
1100 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1101 struct nvkm_device
*device
= subdev
->device
;
1103 u32 trap
= nvkm_rd32(device
, 0x400108);
1106 if (trap
& 0x00000001) {
1107 u32 stat
= nvkm_rd32(device
, 0x404000);
1109 nvkm_snprintbf(error
, sizeof(error
), gf100_dispatch_error
,
1111 nvkm_error(subdev
, "DISPATCH %08x [%s]\n", stat
, error
);
1112 nvkm_wr32(device
, 0x404000, 0xc0000000);
1113 nvkm_wr32(device
, 0x400108, 0x00000001);
1114 trap
&= ~0x00000001;
1117 if (trap
& 0x00000002) {
1118 u32 stat
= nvkm_rd32(device
, 0x404600);
1120 nvkm_snprintbf(error
, sizeof(error
), gf100_m2mf_error
,
1122 nvkm_error(subdev
, "M2MF %08x [%s]\n", stat
, error
);
1124 nvkm_wr32(device
, 0x404600, 0xc0000000);
1125 nvkm_wr32(device
, 0x400108, 0x00000002);
1126 trap
&= ~0x00000002;
1129 if (trap
& 0x00000008) {
1130 u32 stat
= nvkm_rd32(device
, 0x408030);
1132 nvkm_snprintbf(error
, sizeof(error
), gf100_m2mf_error
,
1134 nvkm_error(subdev
, "CCACHE %08x [%s]\n", stat
, error
);
1135 nvkm_wr32(device
, 0x408030, 0xc0000000);
1136 nvkm_wr32(device
, 0x400108, 0x00000008);
1137 trap
&= ~0x00000008;
1140 if (trap
& 0x00000010) {
1141 u32 stat
= nvkm_rd32(device
, 0x405840);
1142 nvkm_error(subdev
, "SHADER %08x, sph: 0x%06x, stage: 0x%02x\n",
1143 stat
, stat
& 0xffffff, (stat
>> 24) & 0x3f);
1144 nvkm_wr32(device
, 0x405840, 0xc0000000);
1145 nvkm_wr32(device
, 0x400108, 0x00000010);
1146 trap
&= ~0x00000010;
1149 if (trap
& 0x00000040) {
1150 u32 stat
= nvkm_rd32(device
, 0x40601c);
1152 nvkm_snprintbf(error
, sizeof(error
), gf100_unk6_error
,
1154 nvkm_error(subdev
, "UNK6 %08x [%s]\n", stat
, error
);
1156 nvkm_wr32(device
, 0x40601c, 0xc0000000);
1157 nvkm_wr32(device
, 0x400108, 0x00000040);
1158 trap
&= ~0x00000040;
1161 if (trap
& 0x00000080) {
1162 u32 stat
= nvkm_rd32(device
, 0x404490);
1163 u32 pc
= nvkm_rd32(device
, 0x404494);
1164 u32 op
= nvkm_rd32(device
, 0x40449c);
1166 nvkm_snprintbf(error
, sizeof(error
), gf100_macro_error
,
1168 nvkm_error(subdev
, "MACRO %08x [%s], pc: 0x%03x%s, op: 0x%08x\n",
1169 stat
, error
, pc
& 0x7ff,
1170 (pc
& 0x10000000) ? "" : " (invalid)",
1173 nvkm_wr32(device
, 0x404490, 0xc0000000);
1174 nvkm_wr32(device
, 0x400108, 0x00000080);
1175 trap
&= ~0x00000080;
1178 if (trap
& 0x00000100) {
1179 u32 stat
= nvkm_rd32(device
, 0x407020) & 0x3fffffff;
1181 nvkm_snprintbf(error
, sizeof(error
), gk104_sked_error
, stat
);
1182 nvkm_error(subdev
, "SKED: %08x [%s]\n", stat
, error
);
1185 nvkm_wr32(device
, 0x407020, 0x40000000);
1186 nvkm_wr32(device
, 0x400108, 0x00000100);
1187 trap
&= ~0x00000100;
1190 if (trap
& 0x01000000) {
1191 u32 stat
= nvkm_rd32(device
, 0x400118);
1192 for (gpc
= 0; stat
&& gpc
< gr
->gpc_nr
; gpc
++) {
1193 u32 mask
= 0x00000001 << gpc
;
1195 gf100_gr_trap_gpc(gr
, gpc
);
1196 nvkm_wr32(device
, 0x400118, mask
);
1200 nvkm_wr32(device
, 0x400108, 0x01000000);
1201 trap
&= ~0x01000000;
1204 if (trap
& 0x02000000) {
1205 for (rop
= 0; rop
< gr
->rop_nr
; rop
++) {
1206 u32 statz
= nvkm_rd32(device
, ROP_UNIT(rop
, 0x070));
1207 u32 statc
= nvkm_rd32(device
, ROP_UNIT(rop
, 0x144));
1208 nvkm_error(subdev
, "ROP%d %08x %08x\n",
1210 nvkm_wr32(device
, ROP_UNIT(rop
, 0x070), 0xc0000000);
1211 nvkm_wr32(device
, ROP_UNIT(rop
, 0x144), 0xc0000000);
1213 nvkm_wr32(device
, 0x400108, 0x02000000);
1214 trap
&= ~0x02000000;
1218 nvkm_error(subdev
, "TRAP UNHANDLED %08x\n", trap
);
1219 nvkm_wr32(device
, 0x400108, trap
);
1224 gf100_gr_ctxctl_debug_unit(struct gf100_gr
*gr
, u32 base
)
1226 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1227 struct nvkm_device
*device
= subdev
->device
;
1228 nvkm_error(subdev
, "%06x - done %08x\n", base
,
1229 nvkm_rd32(device
, base
+ 0x400));
1230 nvkm_error(subdev
, "%06x - stat %08x %08x %08x %08x\n", base
,
1231 nvkm_rd32(device
, base
+ 0x800),
1232 nvkm_rd32(device
, base
+ 0x804),
1233 nvkm_rd32(device
, base
+ 0x808),
1234 nvkm_rd32(device
, base
+ 0x80c));
1235 nvkm_error(subdev
, "%06x - stat %08x %08x %08x %08x\n", base
,
1236 nvkm_rd32(device
, base
+ 0x810),
1237 nvkm_rd32(device
, base
+ 0x814),
1238 nvkm_rd32(device
, base
+ 0x818),
1239 nvkm_rd32(device
, base
+ 0x81c));
1243 gf100_gr_ctxctl_debug(struct gf100_gr
*gr
)
1245 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
1246 u32 gpcnr
= nvkm_rd32(device
, 0x409604) & 0xffff;
1249 gf100_gr_ctxctl_debug_unit(gr
, 0x409000);
1250 for (gpc
= 0; gpc
< gpcnr
; gpc
++)
1251 gf100_gr_ctxctl_debug_unit(gr
, 0x502000 + (gpc
* 0x8000));
1255 gf100_gr_ctxctl_isr(struct gf100_gr
*gr
)
1257 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1258 struct nvkm_device
*device
= subdev
->device
;
1259 u32 stat
= nvkm_rd32(device
, 0x409c18);
1261 if (stat
& 0x00000001) {
1262 u32 code
= nvkm_rd32(device
, 0x409814);
1263 if (code
== E_BAD_FWMTHD
) {
1264 u32
class = nvkm_rd32(device
, 0x409808);
1265 u32 addr
= nvkm_rd32(device
, 0x40980c);
1266 u32 subc
= (addr
& 0x00070000) >> 16;
1267 u32 mthd
= (addr
& 0x00003ffc);
1268 u32 data
= nvkm_rd32(device
, 0x409810);
1270 nvkm_error(subdev
, "FECS MTHD subc %d class %04x "
1271 "mthd %04x data %08x\n",
1272 subc
, class, mthd
, data
);
1274 nvkm_wr32(device
, 0x409c20, 0x00000001);
1275 stat
&= ~0x00000001;
1277 nvkm_error(subdev
, "FECS ucode error %d\n", code
);
1281 if (stat
& 0x00080000) {
1282 nvkm_error(subdev
, "FECS watchdog timeout\n");
1283 gf100_gr_ctxctl_debug(gr
);
1284 nvkm_wr32(device
, 0x409c20, 0x00080000);
1285 stat
&= ~0x00080000;
1289 nvkm_error(subdev
, "FECS %08x\n", stat
);
1290 gf100_gr_ctxctl_debug(gr
);
1291 nvkm_wr32(device
, 0x409c20, stat
);
1296 gf100_gr_intr(struct nvkm_gr
*base
)
1298 struct gf100_gr
*gr
= gf100_gr(base
);
1299 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1300 struct nvkm_device
*device
= subdev
->device
;
1301 struct nvkm_fifo_chan
*chan
;
1302 unsigned long flags
;
1303 u64 inst
= nvkm_rd32(device
, 0x409b00) & 0x0fffffff;
1304 u32 stat
= nvkm_rd32(device
, 0x400100);
1305 u32 addr
= nvkm_rd32(device
, 0x400704);
1306 u32 mthd
= (addr
& 0x00003ffc);
1307 u32 subc
= (addr
& 0x00070000) >> 16;
1308 u32 data
= nvkm_rd32(device
, 0x400708);
1309 u32 code
= nvkm_rd32(device
, 0x400110);
1311 const char *name
= "unknown";
1314 chan
= nvkm_fifo_chan_inst(device
->fifo
, (u64
)inst
<< 12, &flags
);
1316 name
= chan
->object
.client
->name
;
1320 if (device
->card_type
< NV_E0
|| subc
< 4)
1321 class = nvkm_rd32(device
, 0x404200 + (subc
* 4));
1325 if (stat
& 0x00000001) {
1327 * notifier interrupt, only needed for cyclestats
1328 * can be safely ignored
1330 nvkm_wr32(device
, 0x400100, 0x00000001);
1331 stat
&= ~0x00000001;
1334 if (stat
& 0x00000010) {
1335 if (!gf100_gr_mthd_sw(device
, class, mthd
, data
)) {
1336 nvkm_error(subdev
, "ILLEGAL_MTHD ch %d [%010llx %s] "
1337 "subc %d class %04x mthd %04x data %08x\n",
1338 chid
, inst
<< 12, name
, subc
,
1341 nvkm_wr32(device
, 0x400100, 0x00000010);
1342 stat
&= ~0x00000010;
1345 if (stat
& 0x00000020) {
1346 nvkm_error(subdev
, "ILLEGAL_CLASS ch %d [%010llx %s] "
1347 "subc %d class %04x mthd %04x data %08x\n",
1348 chid
, inst
<< 12, name
, subc
, class, mthd
, data
);
1349 nvkm_wr32(device
, 0x400100, 0x00000020);
1350 stat
&= ~0x00000020;
1353 if (stat
& 0x00100000) {
1354 const struct nvkm_enum
*en
=
1355 nvkm_enum_find(nv50_data_error_names
, code
);
1356 nvkm_error(subdev
, "DATA_ERROR %08x [%s] ch %d [%010llx %s] "
1357 "subc %d class %04x mthd %04x data %08x\n",
1358 code
, en
? en
->name
: "", chid
, inst
<< 12,
1359 name
, subc
, class, mthd
, data
);
1360 nvkm_wr32(device
, 0x400100, 0x00100000);
1361 stat
&= ~0x00100000;
1364 if (stat
& 0x00200000) {
1365 nvkm_error(subdev
, "TRAP ch %d [%010llx %s]\n",
1366 chid
, inst
<< 12, name
);
1367 gf100_gr_trap_intr(gr
);
1368 nvkm_wr32(device
, 0x400100, 0x00200000);
1369 stat
&= ~0x00200000;
1372 if (stat
& 0x00080000) {
1373 gf100_gr_ctxctl_isr(gr
);
1374 nvkm_wr32(device
, 0x400100, 0x00080000);
1375 stat
&= ~0x00080000;
1379 nvkm_error(subdev
, "intr %08x\n", stat
);
1380 nvkm_wr32(device
, 0x400100, stat
);
1383 nvkm_wr32(device
, 0x400500, 0x00010001);
1384 nvkm_fifo_chan_put(device
->fifo
, flags
, &chan
);
1388 gf100_gr_init_fw(struct gf100_gr
*gr
, u32 fuc_base
,
1389 struct gf100_gr_fuc
*code
, struct gf100_gr_fuc
*data
)
1391 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
1394 nvkm_wr32(device
, fuc_base
+ 0x01c0, 0x01000000);
1395 for (i
= 0; i
< data
->size
/ 4; i
++)
1396 nvkm_wr32(device
, fuc_base
+ 0x01c4, data
->data
[i
]);
1398 nvkm_wr32(device
, fuc_base
+ 0x0180, 0x01000000);
1399 for (i
= 0; i
< code
->size
/ 4; i
++) {
1400 if ((i
& 0x3f) == 0)
1401 nvkm_wr32(device
, fuc_base
+ 0x0188, i
>> 6);
1402 nvkm_wr32(device
, fuc_base
+ 0x0184, code
->data
[i
]);
1405 /* code must be padded to 0x40 words */
1406 for (; i
& 0x3f; i
++)
1407 nvkm_wr32(device
, fuc_base
+ 0x0184, 0);
1411 gf100_gr_init_csdata(struct gf100_gr
*gr
,
1412 const struct gf100_gr_pack
*pack
,
1413 u32 falcon
, u32 starstar
, u32 base
)
1415 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
1416 const struct gf100_gr_pack
*iter
;
1417 const struct gf100_gr_init
*init
;
1418 u32 addr
= ~0, prev
= ~0, xfer
= 0;
1421 nvkm_wr32(device
, falcon
+ 0x01c0, 0x02000000 + starstar
);
1422 star
= nvkm_rd32(device
, falcon
+ 0x01c4);
1423 temp
= nvkm_rd32(device
, falcon
+ 0x01c4);
1426 nvkm_wr32(device
, falcon
+ 0x01c0, 0x01000000 + star
);
1428 pack_for_each_init(init
, iter
, pack
) {
1429 u32 head
= init
->addr
- base
;
1430 u32 tail
= head
+ init
->count
* init
->pitch
;
1431 while (head
< tail
) {
1432 if (head
!= prev
+ 4 || xfer
>= 32) {
1434 u32 data
= ((--xfer
<< 26) | addr
);
1435 nvkm_wr32(device
, falcon
+ 0x01c4, data
);
1443 head
= head
+ init
->pitch
;
1447 nvkm_wr32(device
, falcon
+ 0x01c4, (--xfer
<< 26) | addr
);
1448 nvkm_wr32(device
, falcon
+ 0x01c0, 0x01000004 + starstar
);
1449 nvkm_wr32(device
, falcon
+ 0x01c4, star
+ 4);
1453 gf100_gr_init_ctxctl(struct gf100_gr
*gr
)
1455 const struct gf100_grctx_func
*grctx
= gr
->func
->grctx
;
1456 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1457 struct nvkm_device
*device
= subdev
->device
;
1458 struct nvkm_secboot
*sb
= device
->secboot
;
1463 /* load fuc microcode */
1464 nvkm_mc_unk260(device
, 0);
1466 /* securely-managed falcons must be reset using secure boot */
1467 if (nvkm_secboot_is_managed(sb
, NVKM_SECBOOT_FALCON_FECS
))
1468 ret
= nvkm_secboot_reset(sb
, NVKM_SECBOOT_FALCON_FECS
);
1470 gf100_gr_init_fw(gr
, 0x409000, &gr
->fuc409c
,
1475 if (nvkm_secboot_is_managed(sb
, NVKM_SECBOOT_FALCON_GPCCS
))
1476 ret
= nvkm_secboot_reset(sb
, NVKM_SECBOOT_FALCON_GPCCS
);
1478 gf100_gr_init_fw(gr
, 0x41a000, &gr
->fuc41ac
,
1483 nvkm_mc_unk260(device
, 1);
1485 /* start both of them running */
1486 nvkm_wr32(device
, 0x409840, 0xffffffff);
1487 nvkm_wr32(device
, 0x41a10c, 0x00000000);
1488 nvkm_wr32(device
, 0x40910c, 0x00000000);
1490 if (nvkm_secboot_is_managed(sb
, NVKM_SECBOOT_FALCON_GPCCS
))
1491 nvkm_secboot_start(sb
, NVKM_SECBOOT_FALCON_GPCCS
);
1493 nvkm_wr32(device
, 0x41a100, 0x00000002);
1494 if (nvkm_secboot_is_managed(sb
, NVKM_SECBOOT_FALCON_FECS
))
1495 nvkm_secboot_start(sb
, NVKM_SECBOOT_FALCON_FECS
);
1497 nvkm_wr32(device
, 0x409100, 0x00000002);
1498 if (nvkm_msec(device
, 2000,
1499 if (nvkm_rd32(device
, 0x409800) & 0x00000001)
1504 nvkm_wr32(device
, 0x409840, 0xffffffff);
1505 nvkm_wr32(device
, 0x409500, 0x7fffffff);
1506 nvkm_wr32(device
, 0x409504, 0x00000021);
1508 nvkm_wr32(device
, 0x409840, 0xffffffff);
1509 nvkm_wr32(device
, 0x409500, 0x00000000);
1510 nvkm_wr32(device
, 0x409504, 0x00000010);
1511 if (nvkm_msec(device
, 2000,
1512 if ((gr
->size
= nvkm_rd32(device
, 0x409800)))
1517 nvkm_wr32(device
, 0x409840, 0xffffffff);
1518 nvkm_wr32(device
, 0x409500, 0x00000000);
1519 nvkm_wr32(device
, 0x409504, 0x00000016);
1520 if (nvkm_msec(device
, 2000,
1521 if (nvkm_rd32(device
, 0x409800))
1526 nvkm_wr32(device
, 0x409840, 0xffffffff);
1527 nvkm_wr32(device
, 0x409500, 0x00000000);
1528 nvkm_wr32(device
, 0x409504, 0x00000025);
1529 if (nvkm_msec(device
, 2000,
1530 if (nvkm_rd32(device
, 0x409800))
1535 if (device
->chipset
>= 0xe0) {
1536 nvkm_wr32(device
, 0x409800, 0x00000000);
1537 nvkm_wr32(device
, 0x409500, 0x00000001);
1538 nvkm_wr32(device
, 0x409504, 0x00000030);
1539 if (nvkm_msec(device
, 2000,
1540 if (nvkm_rd32(device
, 0x409800))
1545 nvkm_wr32(device
, 0x409810, 0xb00095c8);
1546 nvkm_wr32(device
, 0x409800, 0x00000000);
1547 nvkm_wr32(device
, 0x409500, 0x00000001);
1548 nvkm_wr32(device
, 0x409504, 0x00000031);
1549 if (nvkm_msec(device
, 2000,
1550 if (nvkm_rd32(device
, 0x409800))
1555 nvkm_wr32(device
, 0x409810, 0x00080420);
1556 nvkm_wr32(device
, 0x409800, 0x00000000);
1557 nvkm_wr32(device
, 0x409500, 0x00000001);
1558 nvkm_wr32(device
, 0x409504, 0x00000032);
1559 if (nvkm_msec(device
, 2000,
1560 if (nvkm_rd32(device
, 0x409800))
1565 nvkm_wr32(device
, 0x409614, 0x00000070);
1566 nvkm_wr32(device
, 0x409614, 0x00000770);
1567 nvkm_wr32(device
, 0x40802c, 0x00000001);
1570 if (gr
->data
== NULL
) {
1571 int ret
= gf100_grctx_generate(gr
);
1573 nvkm_error(subdev
, "failed to construct context\n");
1580 if (!gr
->func
->fecs
.ucode
) {
1584 /* load HUB microcode */
1585 nvkm_mc_unk260(device
, 0);
1586 nvkm_wr32(device
, 0x4091c0, 0x01000000);
1587 for (i
= 0; i
< gr
->func
->fecs
.ucode
->data
.size
/ 4; i
++)
1588 nvkm_wr32(device
, 0x4091c4, gr
->func
->fecs
.ucode
->data
.data
[i
]);
1590 nvkm_wr32(device
, 0x409180, 0x01000000);
1591 for (i
= 0; i
< gr
->func
->fecs
.ucode
->code
.size
/ 4; i
++) {
1592 if ((i
& 0x3f) == 0)
1593 nvkm_wr32(device
, 0x409188, i
>> 6);
1594 nvkm_wr32(device
, 0x409184, gr
->func
->fecs
.ucode
->code
.data
[i
]);
1597 /* load GPC microcode */
1598 nvkm_wr32(device
, 0x41a1c0, 0x01000000);
1599 for (i
= 0; i
< gr
->func
->gpccs
.ucode
->data
.size
/ 4; i
++)
1600 nvkm_wr32(device
, 0x41a1c4, gr
->func
->gpccs
.ucode
->data
.data
[i
]);
1602 nvkm_wr32(device
, 0x41a180, 0x01000000);
1603 for (i
= 0; i
< gr
->func
->gpccs
.ucode
->code
.size
/ 4; i
++) {
1604 if ((i
& 0x3f) == 0)
1605 nvkm_wr32(device
, 0x41a188, i
>> 6);
1606 nvkm_wr32(device
, 0x41a184, gr
->func
->gpccs
.ucode
->code
.data
[i
]);
1608 nvkm_mc_unk260(device
, 1);
1610 /* load register lists */
1611 gf100_gr_init_csdata(gr
, grctx
->hub
, 0x409000, 0x000, 0x000000);
1612 gf100_gr_init_csdata(gr
, grctx
->gpc
, 0x41a000, 0x000, 0x418000);
1613 gf100_gr_init_csdata(gr
, grctx
->tpc
, 0x41a000, 0x004, 0x419800);
1614 gf100_gr_init_csdata(gr
, grctx
->ppc
, 0x41a000, 0x008, 0x41be00);
1616 /* start HUB ucode running, it'll init the GPCs */
1617 nvkm_wr32(device
, 0x40910c, 0x00000000);
1618 nvkm_wr32(device
, 0x409100, 0x00000002);
1619 if (nvkm_msec(device
, 2000,
1620 if (nvkm_rd32(device
, 0x409800) & 0x80000000)
1623 gf100_gr_ctxctl_debug(gr
);
1627 gr
->size
= nvkm_rd32(device
, 0x409804);
1628 if (gr
->data
== NULL
) {
1629 int ret
= gf100_grctx_generate(gr
);
1631 nvkm_error(subdev
, "failed to construct context\n");
1640 gf100_gr_oneinit(struct nvkm_gr
*base
)
1642 struct gf100_gr
*gr
= gf100_gr(base
);
1643 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
1646 nvkm_pmu_pgob(device
->pmu
, false);
1648 gr
->rop_nr
= gr
->func
->rops(gr
);
1649 gr
->gpc_nr
= nvkm_rd32(device
, 0x409604) & 0x0000001f;
1650 for (i
= 0; i
< gr
->gpc_nr
; i
++) {
1651 gr
->tpc_nr
[i
] = nvkm_rd32(device
, GPC_UNIT(i
, 0x2608));
1652 gr
->tpc_total
+= gr
->tpc_nr
[i
];
1653 gr
->ppc_nr
[i
] = gr
->func
->ppc_nr
;
1654 for (j
= 0; j
< gr
->ppc_nr
[i
]; j
++) {
1655 u8 mask
= nvkm_rd32(device
, GPC_UNIT(i
, 0x0c30 + (j
* 4)));
1657 gr
->ppc_mask
[i
] |= (1 << j
);
1658 gr
->ppc_tpc_nr
[i
][j
] = hweight8(mask
);
1662 /*XXX: these need figuring out... though it might not even matter */
1663 switch (device
->chipset
) {
1665 if (gr
->tpc_total
== 11) { /* 465, 3/4/4/0, 4 */
1666 gr
->screen_tile_row_offset
= 0x07;
1668 if (gr
->tpc_total
== 14) { /* 470, 3/3/4/4, 5 */
1669 gr
->screen_tile_row_offset
= 0x05;
1671 if (gr
->tpc_total
== 15) { /* 480, 3/4/4/4, 6 */
1672 gr
->screen_tile_row_offset
= 0x06;
1675 case 0xc3: /* 450, 4/0/0/0, 2 */
1676 gr
->screen_tile_row_offset
= 0x03;
1678 case 0xc4: /* 460, 3/4/0/0, 4 */
1679 gr
->screen_tile_row_offset
= 0x01;
1681 case 0xc1: /* 2/0/0/0, 1 */
1682 gr
->screen_tile_row_offset
= 0x01;
1684 case 0xc8: /* 4/4/3/4, 5 */
1685 gr
->screen_tile_row_offset
= 0x06;
1687 case 0xce: /* 4/4/0/0, 4 */
1688 gr
->screen_tile_row_offset
= 0x03;
1690 case 0xcf: /* 4/0/0/0, 3 */
1691 gr
->screen_tile_row_offset
= 0x03;
1694 case 0xd9: /* 1/0/0/0, 1 */
1695 case 0xea: /* gk20a */
1696 case 0x12b: /* gm20b */
1697 gr
->screen_tile_row_offset
= 0x01;
1705 gf100_gr_init_(struct nvkm_gr
*base
)
1707 struct gf100_gr
*gr
= gf100_gr(base
);
1708 nvkm_pmu_pgob(gr
->base
.engine
.subdev
.device
->pmu
, false);
1709 return gr
->func
->init(gr
);
1713 gf100_gr_dtor_fw(struct gf100_gr_fuc
*fuc
)
1720 gf100_gr_dtor_init(struct gf100_gr_pack
*pack
)
1726 gf100_gr_dtor(struct nvkm_gr
*base
)
1728 struct gf100_gr
*gr
= gf100_gr(base
);
1734 gf100_gr_dtor_fw(&gr
->fuc409c
);
1735 gf100_gr_dtor_fw(&gr
->fuc409d
);
1736 gf100_gr_dtor_fw(&gr
->fuc41ac
);
1737 gf100_gr_dtor_fw(&gr
->fuc41ad
);
1739 gf100_gr_dtor_init(gr
->fuc_bundle
);
1740 gf100_gr_dtor_init(gr
->fuc_method
);
1741 gf100_gr_dtor_init(gr
->fuc_sw_ctx
);
1742 gf100_gr_dtor_init(gr
->fuc_sw_nonctx
);
1747 static const struct nvkm_gr_func
1749 .dtor
= gf100_gr_dtor
,
1750 .oneinit
= gf100_gr_oneinit
,
1751 .init
= gf100_gr_init_
,
1752 .intr
= gf100_gr_intr
,
1753 .units
= gf100_gr_units
,
1754 .chan_new
= gf100_gr_chan_new
,
1755 .object_get
= gf100_gr_object_get
,
1759 gf100_gr_ctor_fw(struct gf100_gr
*gr
, const char *fwname
,
1760 struct gf100_gr_fuc
*fuc
)
1762 struct nvkm_subdev
*subdev
= &gr
->base
.engine
.subdev
;
1763 struct nvkm_device
*device
= subdev
->device
;
1764 const struct firmware
*fw
;
1767 ret
= nvkm_firmware_get(device
, fwname
, &fw
);
1769 nvkm_error(subdev
, "failed to load %s\n", fwname
);
1773 fuc
->size
= fw
->size
;
1774 fuc
->data
= kmemdup(fw
->data
, fuc
->size
, GFP_KERNEL
);
1775 nvkm_firmware_put(fw
);
1776 return (fuc
->data
!= NULL
) ? 0 : -ENOMEM
;
1780 gf100_gr_ctor(const struct gf100_gr_func
*func
, struct nvkm_device
*device
,
1781 int index
, struct gf100_gr
*gr
)
1786 gr
->firmware
= nvkm_boolopt(device
->cfgopt
, "NvGrUseFW",
1787 func
->fecs
.ucode
== NULL
);
1789 ret
= nvkm_gr_ctor(&gf100_gr_
, device
, index
,
1790 gr
->firmware
|| func
->fecs
.ucode
!= NULL
,
1799 gf100_gr_new_(const struct gf100_gr_func
*func
, struct nvkm_device
*device
,
1800 int index
, struct nvkm_gr
**pgr
)
1802 struct gf100_gr
*gr
;
1805 if (!(gr
= kzalloc(sizeof(*gr
), GFP_KERNEL
)))
1809 ret
= gf100_gr_ctor(func
, device
, index
, gr
);
1814 if (gf100_gr_ctor_fw(gr
, "fecs_inst", &gr
->fuc409c
) ||
1815 gf100_gr_ctor_fw(gr
, "fecs_data", &gr
->fuc409d
) ||
1816 gf100_gr_ctor_fw(gr
, "gpccs_inst", &gr
->fuc41ac
) ||
1817 gf100_gr_ctor_fw(gr
, "gpccs_data", &gr
->fuc41ad
))
1825 gf100_gr_init(struct gf100_gr
*gr
)
1827 struct nvkm_device
*device
= gr
->base
.engine
.subdev
.device
;
1828 struct nvkm_fb
*fb
= device
->fb
;
1829 const u32 magicgpc918
= DIV_ROUND_UP(0x00800000, gr
->tpc_total
);
1830 u32 data
[TPC_MAX
/ 8] = {};
1835 nvkm_wr32(device
, GPC_BCAST(0x0880), 0x00000000);
1836 nvkm_wr32(device
, GPC_BCAST(0x08a4), 0x00000000);
1837 nvkm_wr32(device
, GPC_BCAST(0x0888), 0x00000000);
1838 nvkm_wr32(device
, GPC_BCAST(0x088c), 0x00000000);
1839 nvkm_wr32(device
, GPC_BCAST(0x0890), 0x00000000);
1840 nvkm_wr32(device
, GPC_BCAST(0x0894), 0x00000000);
1841 nvkm_wr32(device
, GPC_BCAST(0x08b4), nvkm_memory_addr(fb
->mmu_wr
) >> 8);
1842 nvkm_wr32(device
, GPC_BCAST(0x08b8), nvkm_memory_addr(fb
->mmu_rd
) >> 8);
1844 gf100_gr_mmio(gr
, gr
->func
->mmio
);
1846 nvkm_mask(device
, TPC_UNIT(0, 0, 0x05c), 0x00000001, 0x00000001);
1848 memcpy(tpcnr
, gr
->tpc_nr
, sizeof(gr
->tpc_nr
));
1849 for (i
= 0, gpc
= -1; i
< gr
->tpc_total
; i
++) {
1851 gpc
= (gpc
+ 1) % gr
->gpc_nr
;
1852 } while (!tpcnr
[gpc
]);
1853 tpc
= gr
->tpc_nr
[gpc
] - tpcnr
[gpc
]--;
1855 data
[i
/ 8] |= tpc
<< ((i
% 8) * 4);
1858 nvkm_wr32(device
, GPC_BCAST(0x0980), data
[0]);
1859 nvkm_wr32(device
, GPC_BCAST(0x0984), data
[1]);
1860 nvkm_wr32(device
, GPC_BCAST(0x0988), data
[2]);
1861 nvkm_wr32(device
, GPC_BCAST(0x098c), data
[3]);
1863 for (gpc
= 0; gpc
< gr
->gpc_nr
; gpc
++) {
1864 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0914),
1865 gr
->screen_tile_row_offset
<< 8 | gr
->tpc_nr
[gpc
]);
1866 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0910), 0x00040000 |
1868 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0918), magicgpc918
);
1871 if (device
->chipset
!= 0xd7)
1872 nvkm_wr32(device
, GPC_BCAST(0x1bd4), magicgpc918
);
1874 nvkm_wr32(device
, GPC_BCAST(0x3fd4), magicgpc918
);
1876 nvkm_wr32(device
, GPC_BCAST(0x08ac), nvkm_rd32(device
, 0x100800));
1878 nvkm_wr32(device
, 0x400500, 0x00010001);
1880 nvkm_wr32(device
, 0x400100, 0xffffffff);
1881 nvkm_wr32(device
, 0x40013c, 0xffffffff);
1883 nvkm_wr32(device
, 0x409c24, 0x000f0000);
1884 nvkm_wr32(device
, 0x404000, 0xc0000000);
1885 nvkm_wr32(device
, 0x404600, 0xc0000000);
1886 nvkm_wr32(device
, 0x408030, 0xc0000000);
1887 nvkm_wr32(device
, 0x40601c, 0xc0000000);
1888 nvkm_wr32(device
, 0x404490, 0xc0000000);
1889 nvkm_wr32(device
, 0x406018, 0xc0000000);
1890 nvkm_wr32(device
, 0x405840, 0xc0000000);
1891 nvkm_wr32(device
, 0x405844, 0x00ffffff);
1892 nvkm_mask(device
, 0x419cc0, 0x00000008, 0x00000008);
1893 nvkm_mask(device
, 0x419eb4, 0x00001000, 0x00001000);
1895 for (gpc
= 0; gpc
< gr
->gpc_nr
; gpc
++) {
1896 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0420), 0xc0000000);
1897 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0900), 0xc0000000);
1898 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x1028), 0xc0000000);
1899 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x0824), 0xc0000000);
1900 for (tpc
= 0; tpc
< gr
->tpc_nr
[gpc
]; tpc
++) {
1901 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x508), 0xffffffff);
1902 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x50c), 0xffffffff);
1903 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x224), 0xc0000000);
1904 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x48c), 0xc0000000);
1905 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x084), 0xc0000000);
1906 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x644), 0x001ffffe);
1907 nvkm_wr32(device
, TPC_UNIT(gpc
, tpc
, 0x64c), 0x0000000f);
1909 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x2c90), 0xffffffff);
1910 nvkm_wr32(device
, GPC_UNIT(gpc
, 0x2c94), 0xffffffff);
1913 for (rop
= 0; rop
< gr
->rop_nr
; rop
++) {
1914 nvkm_wr32(device
, ROP_UNIT(rop
, 0x144), 0xc0000000);
1915 nvkm_wr32(device
, ROP_UNIT(rop
, 0x070), 0xc0000000);
1916 nvkm_wr32(device
, ROP_UNIT(rop
, 0x204), 0xffffffff);
1917 nvkm_wr32(device
, ROP_UNIT(rop
, 0x208), 0xffffffff);
1920 nvkm_wr32(device
, 0x400108, 0xffffffff);
1921 nvkm_wr32(device
, 0x400138, 0xffffffff);
1922 nvkm_wr32(device
, 0x400118, 0xffffffff);
1923 nvkm_wr32(device
, 0x400130, 0xffffffff);
1924 nvkm_wr32(device
, 0x40011c, 0xffffffff);
1925 nvkm_wr32(device
, 0x400134, 0xffffffff);
1927 nvkm_wr32(device
, 0x400054, 0x34ce3464);
1929 gf100_gr_zbc_init(gr
);
1931 return gf100_gr_init_ctxctl(gr
);
1934 #include "fuc/hubgf100.fuc3.h"
1936 struct gf100_gr_ucode
1937 gf100_gr_fecs_ucode
= {
1938 .code
.data
= gf100_grhub_code
,
1939 .code
.size
= sizeof(gf100_grhub_code
),
1940 .data
.data
= gf100_grhub_data
,
1941 .data
.size
= sizeof(gf100_grhub_data
),
1944 #include "fuc/gpcgf100.fuc3.h"
1946 struct gf100_gr_ucode
1947 gf100_gr_gpccs_ucode
= {
1948 .code
.data
= gf100_grgpc_code
,
1949 .code
.size
= sizeof(gf100_grgpc_code
),
1950 .data
.data
= gf100_grgpc_data
,
1951 .data
.size
= sizeof(gf100_grgpc_data
),
1954 static const struct gf100_gr_func
1956 .init
= gf100_gr_init
,
1957 .mmio
= gf100_gr_pack_mmio
,
1958 .fecs
.ucode
= &gf100_gr_fecs_ucode
,
1959 .gpccs
.ucode
= &gf100_gr_gpccs_ucode
,
1960 .rops
= gf100_gr_rops
,
1961 .grctx
= &gf100_grctx
,
1963 { -1, -1, FERMI_TWOD_A
},
1964 { -1, -1, FERMI_MEMORY_TO_MEMORY_FORMAT_A
},
1965 { -1, -1, FERMI_A
, &gf100_fermi
},
1966 { -1, -1, FERMI_COMPUTE_A
},
1972 gf100_gr_new(struct nvkm_device
*device
, int index
, struct nvkm_gr
**pgr
)
1974 return gf100_gr_new_(&gf100_gr
, device
, index
, pgr
);