1/*	$NetBSD: nouveau_nvkm_engine_gr_gk104.c,v 1.3 2021/12/18 23:45:36 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 <bskeggs@redhat.com>
25 */
26#include <sys/cdefs.h>
27__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_gr_gk104.c,v 1.3 2021/12/18 23:45:36 riastradh Exp $");
28
29#include "gf100.h"
30#include "gk104.h"
31#include "ctxgf100.h"
32
33#include <nvif/class.h>
34
35/*******************************************************************************
36 * PGRAPH register lists
37 ******************************************************************************/
38
39const struct gf100_gr_init
40gk104_gr_init_main_0[] = {
41	{ 0x400080,   1, 0x04, 0x003083c2 },
42	{ 0x400088,   1, 0x04, 0x0001ffe7 },
43	{ 0x40008c,   1, 0x04, 0x00000000 },
44	{ 0x400090,   1, 0x04, 0x00000030 },
45	{ 0x40013c,   1, 0x04, 0x003901f7 },
46	{ 0x400140,   1, 0x04, 0x00000100 },
47	{ 0x400144,   1, 0x04, 0x00000000 },
48	{ 0x400148,   1, 0x04, 0x00000110 },
49	{ 0x400138,   1, 0x04, 0x00000000 },
50	{ 0x400130,   2, 0x04, 0x00000000 },
51	{ 0x400124,   1, 0x04, 0x00000002 },
52	{}
53};
54
55static const struct gf100_gr_init
56gk104_gr_init_ds_0[] = {
57	{ 0x405844,   1, 0x04, 0x00ffffff },
58	{ 0x405850,   1, 0x04, 0x00000000 },
59	{ 0x405900,   1, 0x04, 0x0000ff34 },
60	{ 0x405908,   1, 0x04, 0x00000000 },
61	{ 0x405928,   2, 0x04, 0x00000000 },
62	{}
63};
64
65static const struct gf100_gr_init
66gk104_gr_init_sked_0[] = {
67	{ 0x407010,   1, 0x04, 0x00000000 },
68	{}
69};
70
71static const struct gf100_gr_init
72gk104_gr_init_cwd_0[] = {
73	{ 0x405b50,   1, 0x04, 0x00000000 },
74	{}
75};
76
77static const struct gf100_gr_init
78gk104_gr_init_gpc_unk_1[] = {
79	{ 0x418d00,   1, 0x04, 0x00000000 },
80	{ 0x418d28,   2, 0x04, 0x00000000 },
81	{ 0x418f00,   1, 0x04, 0x00000000 },
82	{ 0x418f08,   1, 0x04, 0x00000000 },
83	{ 0x418f20,   2, 0x04, 0x00000000 },
84	{ 0x418e00,   1, 0x04, 0x00000060 },
85	{ 0x418e08,   1, 0x04, 0x00000000 },
86	{ 0x418e1c,   2, 0x04, 0x00000000 },
87	{}
88};
89
90const struct gf100_gr_init
91gk104_gr_init_gpc_unk_2[] = {
92	{ 0x418884,   1, 0x04, 0x00000000 },
93	{}
94};
95
96const struct gf100_gr_init
97gk104_gr_init_tpccs_0[] = {
98	{ 0x419d0c,   1, 0x04, 0x00000000 },
99	{ 0x419d10,   1, 0x04, 0x00000014 },
100	{}
101};
102
103const struct gf100_gr_init
104gk104_gr_init_pe_0[] = {
105	{ 0x41980c,   1, 0x04, 0x00000010 },
106	{ 0x419844,   1, 0x04, 0x00000000 },
107	{ 0x419850,   1, 0x04, 0x00000004 },
108	{ 0x419854,   2, 0x04, 0x00000000 },
109	{}
110};
111
112static const struct gf100_gr_init
113gk104_gr_init_l1c_0[] = {
114	{ 0x419c98,   1, 0x04, 0x00000000 },
115	{ 0x419ca8,   1, 0x04, 0x00000000 },
116	{ 0x419cb0,   1, 0x04, 0x01000000 },
117	{ 0x419cb4,   1, 0x04, 0x00000000 },
118	{ 0x419cb8,   1, 0x04, 0x00b08bea },
119	{ 0x419c84,   1, 0x04, 0x00010384 },
120	{ 0x419cbc,   1, 0x04, 0x28137646 },
121	{ 0x419cc0,   2, 0x04, 0x00000000 },
122	{ 0x419c80,   1, 0x04, 0x00020232 },
123	{}
124};
125
126static const struct gf100_gr_init
127gk104_gr_init_sm_0[] = {
128	{ 0x419e00,   1, 0x04, 0x00000000 },
129	{ 0x419ea0,   1, 0x04, 0x00000000 },
130	{ 0x419ee4,   1, 0x04, 0x00000000 },
131	{ 0x419ea4,   1, 0x04, 0x00000100 },
132	{ 0x419ea8,   1, 0x04, 0x00000000 },
133	{ 0x419eb4,   4, 0x04, 0x00000000 },
134	{ 0x419edc,   1, 0x04, 0x00000000 },
135	{ 0x419f00,   1, 0x04, 0x00000000 },
136	{ 0x419f74,   1, 0x04, 0x00000555 },
137	{}
138};
139
140const struct gf100_gr_init
141gk104_gr_init_be_0[] = {
142	{ 0x40880c,   1, 0x04, 0x00000000 },
143	{ 0x408850,   1, 0x04, 0x00000004 },
144	{ 0x408910,   9, 0x04, 0x00000000 },
145	{ 0x408950,   1, 0x04, 0x00000000 },
146	{ 0x408954,   1, 0x04, 0x0000ffff },
147	{ 0x408958,   1, 0x04, 0x00000034 },
148	{ 0x408984,   1, 0x04, 0x00000000 },
149	{ 0x408988,   1, 0x04, 0x08040201 },
150	{ 0x40898c,   1, 0x04, 0x80402010 },
151	{}
152};
153
154const struct gf100_gr_pack
155gk104_gr_pack_mmio[] = {
156	{ gk104_gr_init_main_0 },
157	{ gf100_gr_init_fe_0 },
158	{ gf100_gr_init_pri_0 },
159	{ gf100_gr_init_rstr2d_0 },
160	{ gf119_gr_init_pd_0 },
161	{ gk104_gr_init_ds_0 },
162	{ gf100_gr_init_scc_0 },
163	{ gk104_gr_init_sked_0 },
164	{ gk104_gr_init_cwd_0 },
165	{ gf119_gr_init_prop_0 },
166	{ gf108_gr_init_gpc_unk_0 },
167	{ gf100_gr_init_setup_0 },
168	{ gf100_gr_init_crstr_0 },
169	{ gf108_gr_init_setup_1 },
170	{ gf100_gr_init_zcull_0 },
171	{ gf119_gr_init_gpm_0 },
172	{ gk104_gr_init_gpc_unk_1 },
173	{ gf100_gr_init_gcc_0 },
174	{ gk104_gr_init_gpc_unk_2 },
175	{ gk104_gr_init_tpccs_0 },
176	{ gf119_gr_init_tex_0 },
177	{ gk104_gr_init_pe_0 },
178	{ gk104_gr_init_l1c_0 },
179	{ gf100_gr_init_mpc_0 },
180	{ gk104_gr_init_sm_0 },
181	{ gf117_gr_init_pes_0 },
182	{ gf117_gr_init_wwdx_0 },
183	{ gf117_gr_init_cbm_0 },
184	{ gk104_gr_init_be_0 },
185	{ gf100_gr_init_fe_1 },
186	{}
187};
188
189const struct nvkm_therm_clkgate_init
190gk104_clkgate_blcg_init_main_0[] = {
191	{ 0x4041f0, 1, 0x00004046 },
192	{ 0x409890, 1, 0x00000045 },
193	{ 0x4098b0, 1, 0x0000007f },
194	{}
195};
196
197const struct nvkm_therm_clkgate_init
198gk104_clkgate_blcg_init_rstr2d_0[] = {
199	{ 0x4078c0, 1, 0x00000042 },
200	{}
201};
202
203const struct nvkm_therm_clkgate_init
204gk104_clkgate_blcg_init_unk_0[] = {
205	{ 0x406000, 1, 0x00004044 },
206	{ 0x405860, 1, 0x00004042 },
207	{ 0x40590c, 1, 0x00004042 },
208	{}
209};
210
211const struct nvkm_therm_clkgate_init
212gk104_clkgate_blcg_init_gcc_0[] = {
213	{ 0x408040, 1, 0x00004044 },
214	{}
215};
216
217const struct nvkm_therm_clkgate_init
218gk104_clkgate_blcg_init_sked_0[] = {
219	{ 0x407000, 1, 0x00004044 },
220	{}
221};
222
223const struct nvkm_therm_clkgate_init
224gk104_clkgate_blcg_init_unk_1[] = {
225	{ 0x405bf0, 1, 0x00004044 },
226	{}
227};
228
229const struct nvkm_therm_clkgate_init
230gk104_clkgate_blcg_init_gpc_ctxctl_0[] = {
231	{ 0x41a890, 1, 0x00000042 },
232	{ 0x41a8b0, 1, 0x0000007f },
233	{}
234};
235
236const struct nvkm_therm_clkgate_init
237gk104_clkgate_blcg_init_gpc_unk_0[] = {
238	{ 0x418500, 1, 0x00004042 },
239	{ 0x418608, 1, 0x00004042 },
240	{ 0x418688, 1, 0x00004042 },
241	{ 0x418718, 1, 0x00000042 },
242	{}
243};
244
245const struct nvkm_therm_clkgate_init
246gk104_clkgate_blcg_init_gpc_esetup_0[] = {
247	{ 0x418828, 1, 0x00000044 },
248	{}
249};
250
251const struct nvkm_therm_clkgate_init
252gk104_clkgate_blcg_init_gpc_tpbus_0[] = {
253	{ 0x418bbc, 1, 0x00004042 },
254	{}
255};
256
257const struct nvkm_therm_clkgate_init
258gk104_clkgate_blcg_init_gpc_zcull_0[] = {
259	{ 0x418970, 1, 0x00004042 },
260	{}
261};
262
263const struct nvkm_therm_clkgate_init
264gk104_clkgate_blcg_init_gpc_tpconf_0[] = {
265	{ 0x418c70, 1, 0x00004042 },
266	{}
267};
268
269const struct nvkm_therm_clkgate_init
270gk104_clkgate_blcg_init_gpc_unk_1[] = {
271	{ 0x418cf0, 1, 0x00004042 },
272	{ 0x418d70, 1, 0x00004042 },
273	{ 0x418f0c, 1, 0x00004042 },
274	{ 0x418e0c, 1, 0x00004042 },
275	{}
276};
277
278const struct nvkm_therm_clkgate_init
279gk104_clkgate_blcg_init_gpc_gcc_0[] = {
280	{ 0x419020, 1, 0x00004042 },
281	{ 0x419038, 1, 0x00000042 },
282	{}
283};
284
285const struct nvkm_therm_clkgate_init
286gk104_clkgate_blcg_init_gpc_ffb_0[] = {
287	{ 0x418898, 1, 0x00000042 },
288	{}
289};
290
291const struct nvkm_therm_clkgate_init
292gk104_clkgate_blcg_init_gpc_tex_0[] = {
293	{ 0x419a40, 9, 0x00004042 },
294	{ 0x419acc, 1, 0x00004047 },
295	{}
296};
297
298const struct nvkm_therm_clkgate_init
299gk104_clkgate_blcg_init_gpc_poly_0[] = {
300	{ 0x419868, 1, 0x00000042 },
301	{}
302};
303
304const struct nvkm_therm_clkgate_init
305gk104_clkgate_blcg_init_gpc_l1c_0[] = {
306	{ 0x419ccc, 3, 0x00000042 },
307	{}
308};
309
310const struct nvkm_therm_clkgate_init
311gk104_clkgate_blcg_init_gpc_unk_2[] = {
312	{ 0x419c70, 1, 0x00004045 },
313	{}
314};
315
316const struct nvkm_therm_clkgate_init
317gk104_clkgate_blcg_init_gpc_mp_0[] = {
318	{ 0x419fd0, 1, 0x00004043 },
319	{ 0x419fd8, 1, 0x00004049 },
320	{ 0x419fe0, 2, 0x00004042 },
321	{ 0x419ff0, 1, 0x00004046 },
322	{ 0x419ff8, 1, 0x00004042 },
323	{}
324};
325
326const struct nvkm_therm_clkgate_init
327gk104_clkgate_blcg_init_gpc_ppc_0[] = {
328	{ 0x41be28, 1, 0x00000042 },
329	{ 0x41bfe8, 1, 0x00004042 },
330	{ 0x41bed0, 1, 0x00004042 },
331	{}
332};
333
334const struct nvkm_therm_clkgate_init
335gk104_clkgate_blcg_init_rop_zrop_0[] = {
336	{ 0x408810, 2, 0x00004042 },
337	{}
338};
339
340const struct nvkm_therm_clkgate_init
341gk104_clkgate_blcg_init_rop_0[] = {
342	{ 0x408a80, 6, 0x00004042 },
343	{}
344};
345
346const struct nvkm_therm_clkgate_init
347gk104_clkgate_blcg_init_rop_crop_0[] = {
348	{ 0x4089a8, 1, 0x00004042 },
349	{ 0x4089b0, 1, 0x00000042 },
350	{ 0x4089b8, 1, 0x00004042 },
351	{}
352};
353
354const struct nvkm_therm_clkgate_init
355gk104_clkgate_blcg_init_pxbar_0[] = {
356	{ 0x13c820, 1, 0x0001007f },
357	{ 0x13cbe0, 1, 0x00000042 },
358	{}
359};
360
361static const struct nvkm_therm_clkgate_pack
362gk104_clkgate_pack[] = {
363	{ gk104_clkgate_blcg_init_main_0 },
364	{ gk104_clkgate_blcg_init_rstr2d_0 },
365	{ gk104_clkgate_blcg_init_unk_0 },
366	{ gk104_clkgate_blcg_init_gcc_0 },
367	{ gk104_clkgate_blcg_init_sked_0 },
368	{ gk104_clkgate_blcg_init_unk_1 },
369	{ gk104_clkgate_blcg_init_gpc_ctxctl_0 },
370	{ gk104_clkgate_blcg_init_gpc_unk_0 },
371	{ gk104_clkgate_blcg_init_gpc_esetup_0 },
372	{ gk104_clkgate_blcg_init_gpc_tpbus_0 },
373	{ gk104_clkgate_blcg_init_gpc_zcull_0 },
374	{ gk104_clkgate_blcg_init_gpc_tpconf_0 },
375	{ gk104_clkgate_blcg_init_gpc_unk_1 },
376	{ gk104_clkgate_blcg_init_gpc_gcc_0 },
377	{ gk104_clkgate_blcg_init_gpc_ffb_0 },
378	{ gk104_clkgate_blcg_init_gpc_tex_0 },
379	{ gk104_clkgate_blcg_init_gpc_poly_0 },
380	{ gk104_clkgate_blcg_init_gpc_l1c_0 },
381	{ gk104_clkgate_blcg_init_gpc_unk_2 },
382	{ gk104_clkgate_blcg_init_gpc_mp_0 },
383	{ gk104_clkgate_blcg_init_gpc_ppc_0 },
384	{ gk104_clkgate_blcg_init_rop_zrop_0 },
385	{ gk104_clkgate_blcg_init_rop_0 },
386	{ gk104_clkgate_blcg_init_rop_crop_0 },
387	{ gk104_clkgate_blcg_init_pxbar_0 },
388	{}
389};
390
391/*******************************************************************************
392 * PGRAPH engine/subdev functions
393 ******************************************************************************/
394
395void
396gk104_gr_init_sked_hww_esr(struct gf100_gr *gr)
397{
398	nvkm_wr32(gr->base.engine.subdev.device, 0x407020, 0x40000000);
399}
400
401static void
402gk104_gr_init_fecs_exceptions(struct gf100_gr *gr)
403{
404	struct nvkm_device *device = gr->base.engine.subdev.device;
405	nvkm_wr32(device, 0x409ffc, 0x00000000);
406	nvkm_wr32(device, 0x409c14, 0x00003e3e);
407	nvkm_wr32(device, 0x409c24, 0x000f0001);
408}
409
410void
411gk104_gr_init_rop_active_fbps(struct gf100_gr *gr)
412{
413	struct nvkm_device *device = gr->base.engine.subdev.device;
414	const u32 fbp_count = nvkm_rd32(device, 0x120074);
415	nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */
416	nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */
417}
418
419void
420gk104_gr_init_ppc_exceptions(struct gf100_gr *gr)
421{
422	struct nvkm_device *device = gr->base.engine.subdev.device;
423	int gpc, ppc;
424
425	for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
426		for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) {
427			if (!(gr->ppc_mask[gpc] & (1 << ppc)))
428				continue;
429			nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000);
430		}
431	}
432}
433
434void
435gk104_gr_init_vsc_stream_master(struct gf100_gr *gr)
436{
437	struct nvkm_device *device = gr->base.engine.subdev.device;
438	nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001);
439}
440
441#include "fuc/hubgk104.fuc3.h"
442
443static struct gf100_gr_ucode
444gk104_gr_fecs_ucode = {
445	.code.data = gk104_grhub_code,
446	.code.size = sizeof(gk104_grhub_code),
447	.data.data = gk104_grhub_data,
448	.data.size = sizeof(gk104_grhub_data),
449};
450
451#include "fuc/gpcgk104.fuc3.h"
452
453static struct gf100_gr_ucode
454gk104_gr_gpccs_ucode = {
455	.code.data = gk104_grgpc_code,
456	.code.size = sizeof(gk104_grgpc_code),
457	.data.data = gk104_grgpc_data,
458	.data.size = sizeof(gk104_grgpc_data),
459};
460
461static const struct gf100_gr_func
462gk104_gr = {
463	.oneinit_tiles = gf100_gr_oneinit_tiles,
464	.oneinit_sm_id = gf100_gr_oneinit_sm_id,
465	.init = gf100_gr_init,
466	.init_gpc_mmu = gf100_gr_init_gpc_mmu,
467	.init_vsc_stream_master = gk104_gr_init_vsc_stream_master,
468	.init_zcull = gf117_gr_init_zcull,
469	.init_num_active_ltcs = gf100_gr_init_num_active_ltcs,
470	.init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
471	.init_fecs_exceptions = gk104_gr_init_fecs_exceptions,
472	.init_sked_hww_esr = gk104_gr_init_sked_hww_esr,
473	.init_419cc0 = gf100_gr_init_419cc0,
474	.init_419eb4 = gf100_gr_init_419eb4,
475	.init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
476	.init_tex_hww_esr = gf100_gr_init_tex_hww_esr,
477	.init_shader_exceptions = gf100_gr_init_shader_exceptions,
478	.init_400054 = gf100_gr_init_400054,
479	.trap_mp = gf100_gr_trap_mp,
480	.mmio = gk104_gr_pack_mmio,
481	.fecs.ucode = &gk104_gr_fecs_ucode,
482	.gpccs.ucode = &gk104_gr_gpccs_ucode,
483	.rops = gf100_gr_rops,
484	.ppc_nr = 1,
485	.grctx = &gk104_grctx,
486	.clkgate_pack = gk104_clkgate_pack,
487	.zbc = &gf100_gr_zbc,
488	.sclass = {
489		{ -1, -1, FERMI_TWOD_A },
490		{ -1, -1, KEPLER_INLINE_TO_MEMORY_A },
491		{ -1, -1, KEPLER_A, &gf100_fermi },
492		{ -1, -1, KEPLER_COMPUTE_A },
493		{}
494	}
495};
496
497static const struct gf100_gr_fwif
498gk104_gr_fwif[] = {
499	{ -1, gf100_gr_load, &gk104_gr },
500	{ -1, gf100_gr_nofw, &gk104_gr },
501	{}
502};
503
504int
505gk104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
506{
507	return gf100_gr_new_(gk104_gr_fwif, device, index, pgr);
508}
509