summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gp10b
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b')
-rw-r--r--drivers/gpu/nvgpu/gp10b/ce_gp10b.c78
-rw-r--r--drivers/gpu/nvgpu/gp10b/ce_gp10b.h33
-rw-r--r--drivers/gpu/nvgpu/gp10b/ecc_gp10b.h50
-rw-r--r--drivers/gpu/nvgpu/gp10b/fb_gp10b.c36
-rw-r--r--drivers/gpu/nvgpu/gp10b/fb_gp10b.h32
-rw-r--r--drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.c55
-rw-r--r--drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.h32
-rw-r--r--drivers/gpu/nvgpu/gp10b/fifo_gp10b.c320
-rw-r--r--drivers/gpu/nvgpu/gp10b/fifo_gp10b.h47
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b.c120
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b.h32
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.c741
-rw-r--r--drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.h99
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.c72
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.h35
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.c2357
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.h171
-rw-r--r--drivers/gpu/nvgpu/gp10b/hal_gp10b.c748
-rw-r--r--drivers/gpu/nvgpu/gp10b/hal_gp10b.h31
-rw-r--r--drivers/gpu/nvgpu/gp10b/ltc_gp10b.c226
-rw-r--r--drivers/gpu/nvgpu/gp10b/ltc_gp10b.h33
-rw-r--r--drivers/gpu/nvgpu/gp10b/mc_gp10b.c185
-rw-r--r--drivers/gpu/nvgpu/gp10b/mc_gp10b.h46
-rw-r--r--drivers/gpu/nvgpu/gp10b/mm_gp10b.c446
-rw-r--r--drivers/gpu/nvgpu/gp10b/mm_gp10b.h42
-rw-r--r--drivers/gpu/nvgpu/gp10b/platform_gp10b.h34
-rw-r--r--drivers/gpu/nvgpu/gp10b/pmu_gp10b.c399
-rw-r--r--drivers/gpu/nvgpu/gp10b/pmu_gp10b.h43
-rw-r--r--drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c112
-rw-r--r--drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.h31
-rw-r--r--drivers/gpu/nvgpu/gp10b/regops_gp10b.c479
-rw-r--r--drivers/gpu/nvgpu/gp10b/regops_gp10b.h44
-rw-r--r--drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c160
-rw-r--r--drivers/gpu/nvgpu/gp10b/rpfb_gp10b.h39
-rw-r--r--drivers/gpu/nvgpu/gp10b/therm_gp10b.c141
-rw-r--r--drivers/gpu/nvgpu/gp10b/therm_gp10b.h29
36 files changed, 7578 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gp10b/ce_gp10b.c b/drivers/gpu/nvgpu/gp10b/ce_gp10b.c
new file mode 100644
index 00000000..86a2b751
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/ce_gp10b.c
@@ -0,0 +1,78 @@
1/*
2 * Pascal GPU series Copy Engine.
3 *
4 * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26
27#include "ce_gp10b.h"
28
29#include <nvgpu/hw/gp10b/hw_ce_gp10b.h>
30
31static u32 ce_blockpipe_isr(struct gk20a *g, u32 fifo_intr)
32{
33 gk20a_dbg(gpu_dbg_intr, "ce blocking pipe interrupt\n");
34
35 return ce_intr_status_blockpipe_pending_f();
36}
37
38static u32 ce_launcherr_isr(struct gk20a *g, u32 fifo_intr)
39{
40 gk20a_dbg(gpu_dbg_intr, "ce launch error interrupt\n");
41
42 return ce_intr_status_launcherr_pending_f();
43}
44
45void gp10b_ce_isr(struct gk20a *g, u32 inst_id, u32 pri_base)
46{
47 u32 ce_intr = gk20a_readl(g, ce_intr_status_r(inst_id));
48 u32 clear_intr = 0;
49
50 gk20a_dbg(gpu_dbg_intr, "ce isr %08x %08x\n", ce_intr, inst_id);
51
52 /* clear blocking interrupts: they exibit broken behavior */
53 if (ce_intr & ce_intr_status_blockpipe_pending_f())
54 clear_intr |= ce_blockpipe_isr(g, ce_intr);
55
56 if (ce_intr & ce_intr_status_launcherr_pending_f())
57 clear_intr |= ce_launcherr_isr(g, ce_intr);
58
59 gk20a_writel(g, ce_intr_status_r(inst_id), clear_intr);
60 return;
61}
62
63int gp10b_ce_nonstall_isr(struct gk20a *g, u32 inst_id, u32 pri_base)
64{
65 int ops = 0;
66 u32 ce_intr = gk20a_readl(g, ce_intr_status_r(inst_id));
67
68 gk20a_dbg(gpu_dbg_intr, "ce nonstall isr %08x %08x\n", ce_intr, inst_id);
69
70 if (ce_intr & ce_intr_status_nonblockpipe_pending_f()) {
71 gk20a_writel(g, ce_intr_status_r(inst_id),
72 ce_intr_status_nonblockpipe_pending_f());
73 ops |= (gk20a_nonstall_ops_wakeup_semaphore |
74 gk20a_nonstall_ops_post_events);
75 }
76
77 return ops;
78}
diff --git a/drivers/gpu/nvgpu/gp10b/ce_gp10b.h b/drivers/gpu/nvgpu/gp10b/ce_gp10b.h
new file mode 100644
index 00000000..7b747751
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/ce_gp10b.h
@@ -0,0 +1,33 @@
1/*
2 * Pascal GPU series Copy Engine.
3 *
4 * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#ifndef __CE_GP10B_H__
25#define __CE_GP10B_H__
26
27#include "gk20a/channel_gk20a.h"
28#include "gk20a/tsg_gk20a.h"
29
30void gp10b_ce_isr(struct gk20a *g, u32 inst_id, u32 pri_base);
31int gp10b_ce_nonstall_isr(struct gk20a *g, u32 inst_id, u32 pri_base);
32
33#endif /*__CE2_GP10B_H__*/
diff --git a/drivers/gpu/nvgpu/gp10b/ecc_gp10b.h b/drivers/gpu/nvgpu/gp10b/ecc_gp10b.h
new file mode 100644
index 00000000..a4a6e35b
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/ecc_gp10b.h
@@ -0,0 +1,50 @@
1/*
2 * GP10B ECC
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef _NVGPU_ECC_GP10B_H_
26#define _NVGPU_ECC_GP10B_H_
27
28struct gk20a_ecc_stat;
29
30struct ecc_gr_t18x {
31 struct gk20a_ecc_stat sm_lrf_single_err_count;
32 struct gk20a_ecc_stat sm_lrf_double_err_count;
33
34 struct gk20a_ecc_stat sm_shm_sec_count;
35 struct gk20a_ecc_stat sm_shm_sed_count;
36 struct gk20a_ecc_stat sm_shm_ded_count;
37
38 struct gk20a_ecc_stat tex_total_sec_pipe0_count;
39 struct gk20a_ecc_stat tex_total_ded_pipe0_count;
40 struct gk20a_ecc_stat tex_unique_sec_pipe0_count;
41 struct gk20a_ecc_stat tex_unique_ded_pipe0_count;
42 struct gk20a_ecc_stat tex_total_sec_pipe1_count;
43 struct gk20a_ecc_stat tex_total_ded_pipe1_count;
44 struct gk20a_ecc_stat tex_unique_sec_pipe1_count;
45 struct gk20a_ecc_stat tex_unique_ded_pipe1_count;
46
47 struct gk20a_ecc_stat l2_sec_count;
48 struct gk20a_ecc_stat l2_ded_count;
49};
50#endif
diff --git a/drivers/gpu/nvgpu/gp10b/fb_gp10b.c b/drivers/gpu/nvgpu/gp10b/fb_gp10b.c
new file mode 100644
index 00000000..9df4c851
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/fb_gp10b.c
@@ -0,0 +1,36 @@
1/*
2 * GP10B FB
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26#include "fb_gp10b.h"
27
28unsigned int gp10b_fb_compression_page_size(struct gk20a *g)
29{
30 return SZ_64K;
31}
32
33unsigned int gp10b_fb_compressible_page_size(struct gk20a *g)
34{
35 return SZ_4K;
36}
diff --git a/drivers/gpu/nvgpu/gp10b/fb_gp10b.h b/drivers/gpu/nvgpu/gp10b/fb_gp10b.h
new file mode 100644
index 00000000..52aa2a75
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/fb_gp10b.h
@@ -0,0 +1,32 @@
1/*
2 * GP10B FB
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef _NVGPU_GP10B_FB
26#define _NVGPU_GP10B_FB
27struct gk20a;
28
29unsigned int gp10b_fb_compression_page_size(struct gk20a *g);
30unsigned int gp10b_fb_compressible_page_size(struct gk20a *g);
31
32#endif
diff --git a/drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.c b/drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.c
new file mode 100644
index 00000000..511d565a
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.c
@@ -0,0 +1,55 @@
1/*
2 * GP10B GPU FECS traces
3 *
4 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26#include "gk20a/fecs_trace_gk20a.h"
27
28#include "fecs_trace_gp10b.h"
29
30#include <nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h>
31#include <nvgpu/hw/gp10b/hw_gr_gp10b.h>
32
33#ifdef CONFIG_GK20A_CTXSW_TRACE
34int gp10b_fecs_trace_flush(struct gk20a *g)
35{
36 struct fecs_method_op_gk20a op = {
37 .mailbox = { .id = 0, .data = 0,
38 .clr = ~0, .ok = 0, .fail = 0},
39 .method.addr = gr_fecs_method_push_adr_write_timestamp_record_v(),
40 .method.data = 0,
41 .cond.ok = GR_IS_UCODE_OP_NOT_EQUAL,
42 .cond.fail = GR_IS_UCODE_OP_SKIP,
43 };
44 int err;
45
46 gk20a_dbg(gpu_dbg_fn|gpu_dbg_ctxsw, "");
47
48 err = gr_gk20a_elpg_protected_call(g,
49 gr_gk20a_submit_fecs_method_op(g, op, false));
50 if (err)
51 nvgpu_err(g, "write timestamp record failed");
52
53 return err;
54}
55#endif /* CONFIG_GK20A_CTXSW_TRACE */
diff --git a/drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.h b/drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.h
new file mode 100644
index 00000000..f192617c
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/fecs_trace_gp10b.h
@@ -0,0 +1,32 @@
1/*
2 * GP10B GPU FECS traces
3 *
4 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef _NVGPU_FECS_TRACE_GP10B_H_
26#define _NVGPU_FECS_TRACE_GP10B_H_
27
28struct gk20a;
29
30int gp10b_fecs_trace_flush(struct gk20a *g);
31
32#endif
diff --git a/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c
new file mode 100644
index 00000000..1c9249d1
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c
@@ -0,0 +1,320 @@
1/*
2 * GP10B fifo
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <uapi/linux/nvgpu.h>
26
27#include <nvgpu/dma.h>
28#include <nvgpu/bug.h>
29#include <nvgpu/log2.h>
30
31#include "fifo_gp10b.h"
32
33#include "gk20a/gk20a.h"
34#include "gm20b/fifo_gm20b.h"
35
36#include <nvgpu/hw/gp10b/hw_pbdma_gp10b.h>
37#include <nvgpu/hw/gp10b/hw_ccsr_gp10b.h>
38#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h>
39#include <nvgpu/hw/gp10b/hw_ram_gp10b.h>
40#include <nvgpu/hw/gp10b/hw_top_gp10b.h>
41
42static void gp10b_set_pdb_fault_replay_flags(struct gk20a *g,
43 struct nvgpu_mem *mem)
44{
45 u32 val;
46
47 gk20a_dbg_fn("");
48
49 val = nvgpu_mem_rd32(g, mem,
50 ram_in_page_dir_base_fault_replay_tex_w());
51 val &= ~ram_in_page_dir_base_fault_replay_tex_m();
52 val |= ram_in_page_dir_base_fault_replay_tex_true_f();
53 nvgpu_mem_wr32(g, mem,
54 ram_in_page_dir_base_fault_replay_tex_w(), val);
55
56 val = nvgpu_mem_rd32(g, mem,
57 ram_in_page_dir_base_fault_replay_gcc_w());
58 val &= ~ram_in_page_dir_base_fault_replay_gcc_m();
59 val |= ram_in_page_dir_base_fault_replay_gcc_true_f();
60 nvgpu_mem_wr32(g, mem,
61 ram_in_page_dir_base_fault_replay_gcc_w(), val);
62
63 gk20a_dbg_fn("done");
64}
65
66int channel_gp10b_commit_userd(struct channel_gk20a *c)
67{
68 u32 addr_lo;
69 u32 addr_hi;
70 struct gk20a *g = c->g;
71
72 gk20a_dbg_fn("");
73
74 addr_lo = u64_lo32(c->userd_iova >> ram_userd_base_shift_v());
75 addr_hi = u64_hi32(c->userd_iova);
76
77 gk20a_dbg_info("channel %d : set ramfc userd 0x%16llx",
78 c->chid, (u64)c->userd_iova);
79
80 nvgpu_mem_wr32(g, &c->inst_block,
81 ram_in_ramfc_w() + ram_fc_userd_w(),
82 nvgpu_aperture_mask(g, &g->fifo.userd,
83 pbdma_userd_target_sys_mem_ncoh_f(),
84 pbdma_userd_target_vid_mem_f()) |
85 pbdma_userd_addr_f(addr_lo));
86
87 nvgpu_mem_wr32(g, &c->inst_block,
88 ram_in_ramfc_w() + ram_fc_userd_hi_w(),
89 pbdma_userd_hi_addr_f(addr_hi));
90
91 return 0;
92}
93
94int channel_gp10b_setup_ramfc(struct channel_gk20a *c,
95 u64 gpfifo_base, u32 gpfifo_entries,
96 unsigned long acquire_timeout, u32 flags)
97{
98 struct gk20a *g = c->g;
99 struct nvgpu_mem *mem = &c->inst_block;
100
101 gk20a_dbg_fn("");
102
103 nvgpu_memset(g, mem, 0, 0, ram_fc_size_val_v());
104
105 nvgpu_mem_wr32(g, mem, ram_fc_gp_base_w(),
106 pbdma_gp_base_offset_f(
107 u64_lo32(gpfifo_base >> pbdma_gp_base_rsvd_s())));
108
109 nvgpu_mem_wr32(g, mem, ram_fc_gp_base_hi_w(),
110 pbdma_gp_base_hi_offset_f(u64_hi32(gpfifo_base)) |
111 pbdma_gp_base_hi_limit2_f(ilog2(gpfifo_entries)));
112
113 nvgpu_mem_wr32(g, mem, ram_fc_signature_w(),
114 c->g->ops.fifo.get_pbdma_signature(c->g));
115
116 nvgpu_mem_wr32(g, mem, ram_fc_formats_w(),
117 pbdma_formats_gp_fermi0_f() |
118 pbdma_formats_pb_fermi1_f() |
119 pbdma_formats_mp_fermi0_f());
120
121 nvgpu_mem_wr32(g, mem, ram_fc_pb_header_w(),
122 pbdma_pb_header_priv_user_f() |
123 pbdma_pb_header_method_zero_f() |
124 pbdma_pb_header_subchannel_zero_f() |
125 pbdma_pb_header_level_main_f() |
126 pbdma_pb_header_first_true_f() |
127 pbdma_pb_header_type_inc_f());
128
129 nvgpu_mem_wr32(g, mem, ram_fc_subdevice_w(),
130 pbdma_subdevice_id_f(1) |
131 pbdma_subdevice_status_active_f() |
132 pbdma_subdevice_channel_dma_enable_f());
133
134 nvgpu_mem_wr32(g, mem, ram_fc_target_w(), pbdma_target_engine_sw_f());
135
136 nvgpu_mem_wr32(g, mem, ram_fc_acquire_w(),
137 g->ops.fifo.pbdma_acquire_val(acquire_timeout));
138
139 nvgpu_mem_wr32(g, mem, ram_fc_runlist_timeslice_w(),
140 pbdma_runlist_timeslice_timeout_128_f() |
141 pbdma_runlist_timeslice_timescale_3_f() |
142 pbdma_runlist_timeslice_enable_true_f());
143
144 if ( flags & NVGPU_ALLOC_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE)
145 gp10b_set_pdb_fault_replay_flags(c->g, mem);
146
147
148 nvgpu_mem_wr32(g, mem, ram_fc_chid_w(), ram_fc_chid_id_f(c->chid));
149
150 if (c->is_privileged_channel) {
151 /* Set privilege level for channel */
152 nvgpu_mem_wr32(g, mem, ram_fc_config_w(),
153 pbdma_config_auth_level_privileged_f());
154
155 gk20a_fifo_setup_ramfc_for_privileged_channel(c);
156 }
157
158 return channel_gp10b_commit_userd(c);
159}
160
161u32 gp10b_fifo_get_pbdma_signature(struct gk20a *g)
162{
163 return g->ops.get_litter_value(g, GPU_LIT_GPFIFO_CLASS)
164 | pbdma_signature_sw_zero_f();
165}
166
167int gp10b_fifo_resetup_ramfc(struct channel_gk20a *c)
168{
169 u32 new_syncpt = 0, old_syncpt;
170 u32 v;
171
172 gk20a_dbg_fn("");
173
174 v = nvgpu_mem_rd32(c->g, &c->inst_block,
175 ram_fc_allowed_syncpoints_w());
176 old_syncpt = pbdma_allowed_syncpoints_0_index_v(v);
177 if (c->sync)
178 new_syncpt = c->sync->syncpt_id(c->sync);
179
180 if (new_syncpt && new_syncpt != old_syncpt) {
181 /* disable channel */
182 gk20a_disable_channel_tsg(c->g, c);
183
184 /* preempt the channel */
185 WARN_ON(gk20a_fifo_preempt(c->g, c));
186
187 v = pbdma_allowed_syncpoints_0_valid_f(1);
188
189 gk20a_dbg_info("Channel %d, syncpt id %d\n",
190 c->chid, new_syncpt);
191
192 v |= pbdma_allowed_syncpoints_0_index_f(new_syncpt);
193
194 nvgpu_mem_wr32(c->g, &c->inst_block,
195 ram_fc_allowed_syncpoints_w(), v);
196 }
197
198 /* enable channel */
199 gk20a_enable_channel_tsg(c->g, c);
200
201 gk20a_dbg_fn("done");
202
203 return 0;
204}
205
206int gp10b_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type,
207 u32 *inst_id)
208{
209 int ret = ENGINE_INVAL_GK20A;
210
211 gk20a_dbg_info("engine type %d", engine_type);
212 if (engine_type == top_device_info_type_enum_graphics_v())
213 ret = ENGINE_GR_GK20A;
214 else if (engine_type == top_device_info_type_enum_lce_v()) {
215 /* Default assumptions - all the CE engine have separate runlist */
216 ret = ENGINE_ASYNC_CE_GK20A;
217 }
218
219 return ret;
220}
221
222void gp10b_device_info_data_parse(struct gk20a *g, u32 table_entry,
223 u32 *inst_id, u32 *pri_base, u32 *fault_id)
224{
225 if (top_device_info_data_type_v(table_entry) ==
226 top_device_info_data_type_enum2_v()) {
227 if (inst_id)
228 *inst_id = top_device_info_data_inst_id_v(table_entry);
229 if (pri_base) {
230 *pri_base =
231 (top_device_info_data_pri_base_v(table_entry)
232 << top_device_info_data_pri_base_align_v());
233 gk20a_dbg_info("device info: pri_base: %d", *pri_base);
234 }
235 if (fault_id && (top_device_info_data_fault_id_v(table_entry) ==
236 top_device_info_data_fault_id_valid_v())) {
237 *fault_id =
238 g->ops.fifo.device_info_fault_id(table_entry);
239 gk20a_dbg_info("device info: fault_id: %d", *fault_id);
240 }
241 } else
242 nvgpu_err(g, "unknown device_info_data %d",
243 top_device_info_data_type_v(table_entry));
244}
245
246void gp10b_fifo_init_pbdma_intr_descs(struct fifo_gk20a *f)
247{
248 /*
249 * These are all errors which indicate something really wrong
250 * going on in the device
251 */
252 f->intr.pbdma.device_fatal_0 =
253 pbdma_intr_0_memreq_pending_f() |
254 pbdma_intr_0_memack_timeout_pending_f() |
255 pbdma_intr_0_memack_extra_pending_f() |
256 pbdma_intr_0_memdat_timeout_pending_f() |
257 pbdma_intr_0_memdat_extra_pending_f() |
258 pbdma_intr_0_memflush_pending_f() |
259 pbdma_intr_0_memop_pending_f() |
260 pbdma_intr_0_lbconnect_pending_f() |
261 pbdma_intr_0_lback_timeout_pending_f() |
262 pbdma_intr_0_lback_extra_pending_f() |
263 pbdma_intr_0_lbdat_timeout_pending_f() |
264 pbdma_intr_0_lbdat_extra_pending_f() |
265 pbdma_intr_0_pri_pending_f();
266
267 /*
268 * These are data parsing, framing errors or others which can be
269 * recovered from with intervention... or just resetting the
270 * channel
271 */
272 f->intr.pbdma.channel_fatal_0 =
273 pbdma_intr_0_gpfifo_pending_f() |
274 pbdma_intr_0_gpptr_pending_f() |
275 pbdma_intr_0_gpentry_pending_f() |
276 pbdma_intr_0_gpcrc_pending_f() |
277 pbdma_intr_0_pbptr_pending_f() |
278 pbdma_intr_0_pbentry_pending_f() |
279 pbdma_intr_0_pbcrc_pending_f() |
280 pbdma_intr_0_method_pending_f() |
281 pbdma_intr_0_methodcrc_pending_f() |
282 pbdma_intr_0_pbseg_pending_f() |
283 pbdma_intr_0_syncpoint_illegal_pending_f() |
284 pbdma_intr_0_signature_pending_f();
285
286 /* Can be used for sw-methods, or represents a recoverable timeout. */
287 f->intr.pbdma.restartable_0 =
288 pbdma_intr_0_device_pending_f();
289}
290
291void gp10b_fifo_get_mmu_fault_info(struct gk20a *g, u32 mmu_fault_id,
292 struct mmu_fault_info *mmfault)
293{
294 u32 fault_info;
295 u32 addr_lo, addr_hi;
296
297 gk20a_dbg_fn("mmu_fault_id %d", mmu_fault_id);
298
299 memset(mmfault, 0, sizeof(*mmfault));
300
301 fault_info = gk20a_readl(g,
302 fifo_intr_mmu_fault_info_r(mmu_fault_id));
303 mmfault->fault_type =
304 fifo_intr_mmu_fault_info_type_v(fault_info);
305 mmfault->access_type =
306 fifo_intr_mmu_fault_info_access_type_v(fault_info);
307 mmfault->client_type =
308 fifo_intr_mmu_fault_info_client_type_v(fault_info);
309 mmfault->client_id =
310 fifo_intr_mmu_fault_info_client_v(fault_info);
311
312 addr_lo = gk20a_readl(g, fifo_intr_mmu_fault_lo_r(mmu_fault_id));
313 addr_hi = gk20a_readl(g, fifo_intr_mmu_fault_hi_r(mmu_fault_id));
314 mmfault->fault_addr = hi32_lo32_to_u64(addr_hi, addr_lo);
315 /* note:ignoring aperture */
316 mmfault->inst_ptr = fifo_intr_mmu_fault_inst_ptr_v(
317 gk20a_readl(g, fifo_intr_mmu_fault_inst_r(mmu_fault_id)));
318 /* note: inst_ptr is a 40b phys addr. */
319 mmfault->inst_ptr <<= fifo_intr_mmu_fault_inst_ptr_align_shift_v();
320}
diff --git a/drivers/gpu/nvgpu/gp10b/fifo_gp10b.h b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.h
new file mode 100644
index 00000000..20918483
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.h
@@ -0,0 +1,47 @@
1/*
2 * GP10B Fifo
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef FIFO_GP10B_H
26#define FIFO_GP10B_H
27
28struct gpu_ops;
29struct channel_gk20a;
30struct fifo_gk20a;
31struct mmu_fault_info;
32
33int channel_gp10b_setup_ramfc(struct channel_gk20a *c,
34 u64 gpfifo_base, u32 gpfifo_entries,
35 unsigned long acquire_timeout, u32 flags);
36u32 gp10b_fifo_get_pbdma_signature(struct gk20a *g);
37int gp10b_fifo_resetup_ramfc(struct channel_gk20a *c);
38int gp10b_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type,
39 u32 *inst_id);
40void gp10b_device_info_data_parse(struct gk20a *g, u32 table_entry,
41 u32 *inst_id, u32 *pri_base, u32 *fault_id);
42void gp10b_fifo_init_pbdma_intr_descs(struct fifo_gk20a *f);
43void gp10b_fifo_get_mmu_fault_info(struct gk20a *g, u32 mmu_fault_id,
44 struct mmu_fault_info *mmfault);
45int channel_gp10b_commit_userd(struct channel_gk20a *c);
46
47#endif
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b.c b/drivers/gpu/nvgpu/gp10b/gp10b.c
new file mode 100644
index 00000000..51dc4301
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gp10b.c
@@ -0,0 +1,120 @@
1/*
2 * GP10B Graphics
3 *
4 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26
27#include <nvgpu/enabled.h>
28
29#include "gp10b.h"
30
31#include <nvgpu/hw/gp10b/hw_fuse_gp10b.h>
32#include <nvgpu/hw/gp10b/hw_gr_gp10b.h>
33
34static void gp10b_detect_ecc_enabled_units(struct gk20a *g)
35{
36 u32 opt_ecc_en = gk20a_readl(g, fuse_opt_ecc_en_r());
37 u32 opt_feature_fuses_override_disable =
38 gk20a_readl(g,
39 fuse_opt_feature_fuses_override_disable_r());
40 u32 fecs_feature_override_ecc =
41 gk20a_readl(g,
42 gr_fecs_feature_override_ecc_r());
43
44 if (opt_feature_fuses_override_disable) {
45 if (opt_ecc_en) {
46 __nvgpu_set_enabled(g, NVGPU_ECC_ENABLED_SM_LRF, true);
47 __nvgpu_set_enabled(g, NVGPU_ECC_ENABLED_SM_SHM, true);
48 __nvgpu_set_enabled(g, NVGPU_ECC_ENABLED_TEX, true);
49 __nvgpu_set_enabled(g, NVGPU_ECC_ENABLED_LTC, true);
50 }
51 } else {
52 /* SM LRF */
53 if (gr_fecs_feature_override_ecc_sm_lrf_override_v(
54 fecs_feature_override_ecc)) {
55 if (gr_fecs_feature_override_ecc_sm_lrf_v(
56 fecs_feature_override_ecc)) {
57 __nvgpu_set_enabled(g,
58 NVGPU_ECC_ENABLED_SM_LRF, true);
59 }
60 } else {
61 if (opt_ecc_en) {
62 __nvgpu_set_enabled(g,
63 NVGPU_ECC_ENABLED_SM_LRF, true);
64 }
65 }
66
67 /* SM SHM */
68 if (gr_fecs_feature_override_ecc_sm_shm_override_v(
69 fecs_feature_override_ecc)) {
70 if (gr_fecs_feature_override_ecc_sm_shm_v(
71 fecs_feature_override_ecc)) {
72 __nvgpu_set_enabled(g,
73 NVGPU_ECC_ENABLED_SM_SHM, true);
74 }
75 } else {
76 if (opt_ecc_en) {
77 __nvgpu_set_enabled(g,
78 NVGPU_ECC_ENABLED_SM_SHM, true);
79 }
80 }
81
82 /* TEX */
83 if (gr_fecs_feature_override_ecc_tex_override_v(
84 fecs_feature_override_ecc)) {
85 if (gr_fecs_feature_override_ecc_tex_v(
86 fecs_feature_override_ecc)) {
87 __nvgpu_set_enabled(g,
88 NVGPU_ECC_ENABLED_TEX, true);
89 }
90 } else {
91 if (opt_ecc_en) {
92 __nvgpu_set_enabled(g,
93 NVGPU_ECC_ENABLED_TEX, true);
94 }
95 }
96
97 /* LTC */
98 if (gr_fecs_feature_override_ecc_ltc_override_v(
99 fecs_feature_override_ecc)) {
100 if (gr_fecs_feature_override_ecc_ltc_v(
101 fecs_feature_override_ecc)) {
102 __nvgpu_set_enabled(g,
103 NVGPU_ECC_ENABLED_LTC, true);
104 }
105 } else {
106 if (opt_ecc_en) {
107 __nvgpu_set_enabled(g,
108 NVGPU_ECC_ENABLED_LTC, true);
109 }
110 }
111 }
112}
113
114int gp10b_init_gpu_characteristics(struct gk20a *g)
115{
116 gk20a_init_gpu_characteristics(g);
117 gp10b_detect_ecc_enabled_units(g);
118 __nvgpu_set_enabled(g, NVGPU_SUPPORT_RESCHEDULE_RUNLIST, true);
119 return 0;
120}
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b.h b/drivers/gpu/nvgpu/gp10b/gp10b.h
new file mode 100644
index 00000000..cd850a07
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gp10b.h
@@ -0,0 +1,32 @@
1/*
2 * GP10B Graphics
3 *
4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef GP10B_H
26#define GP10B_H
27
28#include "gk20a/gk20a.h"
29
30int gp10b_init_gpu_characteristics(struct gk20a *g);
31
32#endif /* GP10B_H */
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.c b/drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.c
new file mode 100644
index 00000000..456f3fa0
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.c
@@ -0,0 +1,741 @@
1/*
2 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *
22 * This file is autogenerated. Do not edit.
23 */
24
25#ifndef __gp10b_gating_reglist_h__
26#define __gp10b_gating_reglist_h__
27
28#include "gp10b_gating_reglist.h"
29#include <nvgpu/enabled.h>
30
31struct gating_desc {
32 u32 addr;
33 u32 prod;
34 u32 disable;
35};
36/* slcg bus */
37static const struct gating_desc gp10b_slcg_bus[] = {
38 {.addr = 0x00001c04, .prod = 0x00000000, .disable = 0x000003fe},
39};
40
41/* slcg ce2 */
42static const struct gating_desc gp10b_slcg_ce2[] = {
43 {.addr = 0x00104204, .prod = 0x00000000, .disable = 0x000007fe},
44};
45
46/* slcg chiplet */
47static const struct gating_desc gp10b_slcg_chiplet[] = {
48 {.addr = 0x0010c07c, .prod = 0x00000000, .disable = 0x00000007},
49 {.addr = 0x0010e07c, .prod = 0x00000000, .disable = 0x00000007},
50 {.addr = 0x0010d07c, .prod = 0x00000000, .disable = 0x00000007},
51 {.addr = 0x0010e17c, .prod = 0x00000000, .disable = 0x00000007},
52};
53
54/* slcg fb */
55static const struct gating_desc gp10b_slcg_fb[] = {
56 {.addr = 0x00100d14, .prod = 0x00000000, .disable = 0xfffffffe},
57 {.addr = 0x00100c9c, .prod = 0x00000000, .disable = 0x000001fe},
58};
59
60/* slcg fifo */
61static const struct gating_desc gp10b_slcg_fifo[] = {
62 {.addr = 0x000026ac, .prod = 0x00000f40, .disable = 0x0001fffe},
63};
64
65/* slcg gr */
66static const struct gating_desc gp10b_slcg_gr[] = {
67 {.addr = 0x004041f4, .prod = 0x00000002, .disable = 0x03fffffe},
68 {.addr = 0x0040917c, .prod = 0x00020008, .disable = 0x0003fffe},
69 {.addr = 0x00409894, .prod = 0x00000040, .disable = 0x03fffffe},
70 {.addr = 0x004078c4, .prod = 0x00000000, .disable = 0x000001fe},
71 {.addr = 0x00406004, .prod = 0x00000200, .disable = 0x0001fffe},
72 {.addr = 0x00405864, .prod = 0x00000000, .disable = 0x000001fe},
73 {.addr = 0x00405910, .prod = 0xfffffff0, .disable = 0xfffffffe},
74 {.addr = 0x00408044, .prod = 0x00000000, .disable = 0x000007fe},
75 {.addr = 0x00407004, .prod = 0x00000000, .disable = 0x000001fe},
76 {.addr = 0x0041a17c, .prod = 0x00020008, .disable = 0x0003fffe},
77 {.addr = 0x0041a894, .prod = 0x00000040, .disable = 0x03fffffe},
78 {.addr = 0x00418504, .prod = 0x00000000, .disable = 0x0007fffe},
79 {.addr = 0x0041860c, .prod = 0x00000000, .disable = 0x000001fe},
80 {.addr = 0x0041868c, .prod = 0x00000000, .disable = 0x0000001e},
81 {.addr = 0x0041871c, .prod = 0x00000000, .disable = 0x0000003e},
82 {.addr = 0x00418388, .prod = 0x00000000, .disable = 0x00000001},
83 {.addr = 0x0041882c, .prod = 0x00000000, .disable = 0x0001fffe},
84 {.addr = 0x00418bc0, .prod = 0x00000000, .disable = 0x000001fe},
85 {.addr = 0x00418974, .prod = 0x00000000, .disable = 0x0001fffe},
86 {.addr = 0x00418c74, .prod = 0xffffffc0, .disable = 0xfffffffe},
87 {.addr = 0x00418cf4, .prod = 0xfffffffc, .disable = 0xfffffffe},
88 {.addr = 0x00418d74, .prod = 0xffffffe0, .disable = 0xfffffffe},
89 {.addr = 0x00418f10, .prod = 0xffffffe0, .disable = 0xfffffffe},
90 {.addr = 0x00418e10, .prod = 0xfffffffe, .disable = 0xfffffffe},
91 {.addr = 0x00419024, .prod = 0x000001fe, .disable = 0x000001fe},
92 {.addr = 0x0041889c, .prod = 0x00000000, .disable = 0x000001fe},
93 {.addr = 0x00419d24, .prod = 0x00000000, .disable = 0x0000ffff},
94 {.addr = 0x00419a44, .prod = 0x00000000, .disable = 0x0000000e},
95 {.addr = 0x00419a4c, .prod = 0x00000000, .disable = 0x000001fe},
96 {.addr = 0x00419a54, .prod = 0x00000000, .disable = 0x0000003e},
97 {.addr = 0x00419a5c, .prod = 0x00000000, .disable = 0x0000000e},
98 {.addr = 0x00419a64, .prod = 0x00000000, .disable = 0x000001fe},
99 {.addr = 0x00419a6c, .prod = 0x00000000, .disable = 0x0000000e},
100 {.addr = 0x00419a74, .prod = 0x00000000, .disable = 0x0000000e},
101 {.addr = 0x00419a7c, .prod = 0x00000000, .disable = 0x0000003e},
102 {.addr = 0x00419a84, .prod = 0x00000000, .disable = 0x0000000e},
103 {.addr = 0x0041986c, .prod = 0x00000104, .disable = 0x00fffffe},
104 {.addr = 0x00419cd8, .prod = 0x00000000, .disable = 0x001ffffe},
105 {.addr = 0x00419ce0, .prod = 0x00000000, .disable = 0x001ffffe},
106 {.addr = 0x00419c74, .prod = 0x0000001e, .disable = 0x0000001e},
107 {.addr = 0x00419fd4, .prod = 0x00000000, .disable = 0x0003fffe},
108 {.addr = 0x00419fdc, .prod = 0xffedff00, .disable = 0xfffffffe},
109 {.addr = 0x00419fe4, .prod = 0x00001b00, .disable = 0x00001ffe},
110 {.addr = 0x00419ff4, .prod = 0x00000000, .disable = 0x00003ffe},
111 {.addr = 0x00419ffc, .prod = 0x00000000, .disable = 0x0001fffe},
112 {.addr = 0x0041be2c, .prod = 0x04115fc0, .disable = 0xfffffffe},
113 {.addr = 0x0041bfec, .prod = 0xfffffff0, .disable = 0xfffffffe},
114 {.addr = 0x0041bed4, .prod = 0xfffffff8, .disable = 0xfffffffe},
115 {.addr = 0x00408814, .prod = 0x00000000, .disable = 0x0001fffe},
116 {.addr = 0x00408a84, .prod = 0x00000000, .disable = 0x0001fffe},
117 {.addr = 0x004089ac, .prod = 0x00000000, .disable = 0x0001fffe},
118 {.addr = 0x00408a24, .prod = 0x00000000, .disable = 0x0000ffff},
119};
120
121/* slcg ltc */
122static const struct gating_desc gp10b_slcg_ltc[] = {
123 {.addr = 0x0017e050, .prod = 0x00000000, .disable = 0xfffffffe},
124 {.addr = 0x0017e35c, .prod = 0x00000000, .disable = 0xfffffffe},
125};
126
127/* slcg perf */
128static const struct gating_desc gp10b_slcg_perf[] = {
129 {.addr = 0x001be018, .prod = 0x000001ff, .disable = 0x00000000},
130 {.addr = 0x001bc018, .prod = 0x000001ff, .disable = 0x00000000},
131 {.addr = 0x001b8018, .prod = 0x000001ff, .disable = 0x00000000},
132 {.addr = 0x001b4124, .prod = 0x00000001, .disable = 0x00000000},
133};
134
135/* slcg PriRing */
136static const struct gating_desc gp10b_slcg_priring[] = {
137 {.addr = 0x001200a8, .prod = 0x00000000, .disable = 0x00000001},
138};
139
140/* slcg pwr_csb */
141static const struct gating_desc gp10b_slcg_pwr_csb[] = {
142 {.addr = 0x00000134, .prod = 0x00020008, .disable = 0x0003fffe},
143 {.addr = 0x00000e74, .prod = 0x00000000, .disable = 0x0000000f},
144 {.addr = 0x00000a74, .prod = 0x00004000, .disable = 0x00007ffe},
145 {.addr = 0x000016b8, .prod = 0x00000000, .disable = 0x0000000f},
146};
147
148/* slcg pmu */
149static const struct gating_desc gp10b_slcg_pmu[] = {
150 {.addr = 0x0010a134, .prod = 0x00020008, .disable = 0x0003fffe},
151 {.addr = 0x0010aa74, .prod = 0x00004000, .disable = 0x00007ffe},
152 {.addr = 0x0010ae74, .prod = 0x00000000, .disable = 0x0000000f},
153};
154
155/* therm gr */
156static const struct gating_desc gp10b_slcg_therm[] = {
157 {.addr = 0x000206b8, .prod = 0x00000000, .disable = 0x0000000f},
158};
159
160/* slcg Xbar */
161static const struct gating_desc gp10b_slcg_xbar[] = {
162 {.addr = 0x0013cbe4, .prod = 0x00000000, .disable = 0x1ffffffe},
163 {.addr = 0x0013cc04, .prod = 0x00000000, .disable = 0x1ffffffe},
164};
165
166/* blcg bus */
167static const struct gating_desc gp10b_blcg_bus[] = {
168 {.addr = 0x00001c00, .prod = 0x00000042, .disable = 0x00000000},
169};
170
171/* blcg ce */
172static const struct gating_desc gp10b_blcg_ce[] = {
173 {.addr = 0x00104200, .prod = 0x00008242, .disable = 0x00000000},
174};
175
176/* blcg ctxsw prog */
177static const struct gating_desc gp10b_blcg_ctxsw_prog[] = {
178};
179
180/* blcg fb */
181static const struct gating_desc gp10b_blcg_fb[] = {
182 {.addr = 0x00100d10, .prod = 0x0000c242, .disable = 0x00000000},
183 {.addr = 0x00100d30, .prod = 0x0000c242, .disable = 0x00000000},
184 {.addr = 0x00100d3c, .prod = 0x00000242, .disable = 0x00000000},
185 {.addr = 0x00100d48, .prod = 0x0000c242, .disable = 0x00000000},
186 {.addr = 0x00100c98, .prod = 0x00004242, .disable = 0x00000000},
187};
188
189/* blcg fifo */
190static const struct gating_desc gp10b_blcg_fifo[] = {
191 {.addr = 0x000026a4, .prod = 0x0000c242, .disable = 0x00000000},
192};
193
194/* blcg gr */
195static const struct gating_desc gp10b_blcg_gr[] = {
196 {.addr = 0x004041f0, .prod = 0x0000c646, .disable = 0x00000000},
197 {.addr = 0x00409890, .prod = 0x0000007f, .disable = 0x00000000},
198 {.addr = 0x004098b0, .prod = 0x0000007f, .disable = 0x00000000},
199 {.addr = 0x004078c0, .prod = 0x00004242, .disable = 0x00000000},
200 {.addr = 0x00406000, .prod = 0x0000c444, .disable = 0x00000000},
201 {.addr = 0x00405860, .prod = 0x0000c242, .disable = 0x00000000},
202 {.addr = 0x0040590c, .prod = 0x0000c444, .disable = 0x00000000},
203 {.addr = 0x00408040, .prod = 0x0000c444, .disable = 0x00000000},
204 {.addr = 0x00407000, .prod = 0x4000c242, .disable = 0x00000000},
205 {.addr = 0x00405bf0, .prod = 0x0000c444, .disable = 0x00000000},
206 {.addr = 0x0041a890, .prod = 0x0000427f, .disable = 0x00000000},
207 {.addr = 0x0041a8b0, .prod = 0x0000007f, .disable = 0x00000000},
208 {.addr = 0x00418500, .prod = 0x0000c244, .disable = 0x00000000},
209 {.addr = 0x00418608, .prod = 0x0000c242, .disable = 0x00000000},
210 {.addr = 0x00418688, .prod = 0x0000c242, .disable = 0x00000000},
211 {.addr = 0x00418718, .prod = 0x00000042, .disable = 0x00000000},
212 {.addr = 0x00418828, .prod = 0x00008444, .disable = 0x00000000},
213 {.addr = 0x00418bbc, .prod = 0x0000c242, .disable = 0x00000000},
214 {.addr = 0x00418970, .prod = 0x0000c242, .disable = 0x00000000},
215 {.addr = 0x00418c70, .prod = 0x0000c444, .disable = 0x00000000},
216 {.addr = 0x00418cf0, .prod = 0x0000c444, .disable = 0x00000000},
217 {.addr = 0x00418d70, .prod = 0x0000c444, .disable = 0x00000000},
218 {.addr = 0x00418f0c, .prod = 0x0000c444, .disable = 0x00000000},
219 {.addr = 0x00418e0c, .prod = 0x00008444, .disable = 0x00000000},
220 {.addr = 0x00419020, .prod = 0x0000c242, .disable = 0x00000000},
221 {.addr = 0x00419038, .prod = 0x00000042, .disable = 0x00000000},
222 {.addr = 0x00418898, .prod = 0x00004242, .disable = 0x00000000},
223 {.addr = 0x00419a40, .prod = 0x0000c242, .disable = 0x00000000},
224 {.addr = 0x00419a48, .prod = 0x0000c242, .disable = 0x00000000},
225 {.addr = 0x00419a50, .prod = 0x0000c242, .disable = 0x00000000},
226 {.addr = 0x00419a58, .prod = 0x0000c242, .disable = 0x00000000},
227 {.addr = 0x00419a60, .prod = 0x0000c242, .disable = 0x00000000},
228 {.addr = 0x00419a68, .prod = 0x0000c242, .disable = 0x00000000},
229 {.addr = 0x00419a70, .prod = 0x0000c242, .disable = 0x00000000},
230 {.addr = 0x00419a78, .prod = 0x0000c242, .disable = 0x00000000},
231 {.addr = 0x00419a80, .prod = 0x0000c242, .disable = 0x00000000},
232 {.addr = 0x00419868, .prod = 0x00008242, .disable = 0x00000000},
233 {.addr = 0x00419cd4, .prod = 0x00000002, .disable = 0x00000000},
234 {.addr = 0x00419cdc, .prod = 0x00000002, .disable = 0x00000000},
235 {.addr = 0x00419c70, .prod = 0x0000c444, .disable = 0x00000000},
236 {.addr = 0x00419fd0, .prod = 0x0000c044, .disable = 0x00000000},
237 {.addr = 0x00419fd8, .prod = 0x0000c046, .disable = 0x00000000},
238 {.addr = 0x00419fe0, .prod = 0x0000c044, .disable = 0x00000000},
239 {.addr = 0x00419fe8, .prod = 0x0000c042, .disable = 0x00000000},
240 {.addr = 0x00419ff0, .prod = 0x0000c045, .disable = 0x00000000},
241 {.addr = 0x00419ff8, .prod = 0x00000002, .disable = 0x00000000},
242 {.addr = 0x00419f90, .prod = 0x00000002, .disable = 0x00000000},
243 {.addr = 0x0041be28, .prod = 0x00008242, .disable = 0x00000000},
244 {.addr = 0x0041bfe8, .prod = 0x0000c444, .disable = 0x00000000},
245 {.addr = 0x0041bed0, .prod = 0x0000c444, .disable = 0x00000000},
246 {.addr = 0x00408810, .prod = 0x0000c242, .disable = 0x00000000},
247 {.addr = 0x00408a80, .prod = 0x0000c242, .disable = 0x00000000},
248 {.addr = 0x004089a8, .prod = 0x0000c242, .disable = 0x00000000},
249};
250
251/* blcg ltc */
252static const struct gating_desc gp10b_blcg_ltc[] = {
253 {.addr = 0x0017e030, .prod = 0x00000044, .disable = 0x00000000},
254 {.addr = 0x0017e040, .prod = 0x00000044, .disable = 0x00000000},
255 {.addr = 0x0017e3e0, .prod = 0x00000044, .disable = 0x00000000},
256 {.addr = 0x0017e3c8, .prod = 0x00000044, .disable = 0x00000000},
257};
258
259/* blcg pwr_csb */
260static const struct gating_desc gp10b_blcg_pwr_csb[] = {
261 {.addr = 0x00000a70, .prod = 0x00000045, .disable = 0x00000000},
262};
263
264/* blcg pmu */
265static const struct gating_desc gp10b_blcg_pmu[] = {
266 {.addr = 0x0010aa70, .prod = 0x00000045, .disable = 0x00000000},
267};
268
269/* blcg Xbar */
270static const struct gating_desc gp10b_blcg_xbar[] = {
271 {.addr = 0x0013cbe0, .prod = 0x00000042, .disable = 0x00000000},
272 {.addr = 0x0013cc00, .prod = 0x00000042, .disable = 0x00000000},
273};
274
275/* pg gr */
276static const struct gating_desc gp10b_pg_gr[] = {
277};
278
279/* inline functions */
280void gp10b_slcg_bus_load_gating_prod(struct gk20a *g,
281 bool prod)
282{
283 u32 i;
284 u32 size = sizeof(gp10b_slcg_bus) / sizeof(struct gating_desc);
285
286 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
287 return;
288
289 for (i = 0; i < size; i++) {
290 if (prod)
291 gk20a_writel(g, gp10b_slcg_bus[i].addr,
292 gp10b_slcg_bus[i].prod);
293 else
294 gk20a_writel(g, gp10b_slcg_bus[i].addr,
295 gp10b_slcg_bus[i].disable);
296 }
297}
298
299void gp10b_slcg_ce2_load_gating_prod(struct gk20a *g,
300 bool prod)
301{
302 u32 i;
303 u32 size = sizeof(gp10b_slcg_ce2) / sizeof(struct gating_desc);
304
305 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
306 return;
307
308 for (i = 0; i < size; i++) {
309 if (prod)
310 gk20a_writel(g, gp10b_slcg_ce2[i].addr,
311 gp10b_slcg_ce2[i].prod);
312 else
313 gk20a_writel(g, gp10b_slcg_ce2[i].addr,
314 gp10b_slcg_ce2[i].disable);
315 }
316}
317
318void gp10b_slcg_chiplet_load_gating_prod(struct gk20a *g,
319 bool prod)
320{
321 u32 i;
322 u32 size = sizeof(gp10b_slcg_chiplet) / sizeof(struct gating_desc);
323
324 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
325 return;
326
327 for (i = 0; i < size; i++) {
328 if (prod)
329 gk20a_writel(g, gp10b_slcg_chiplet[i].addr,
330 gp10b_slcg_chiplet[i].prod);
331 else
332 gk20a_writel(g, gp10b_slcg_chiplet[i].addr,
333 gp10b_slcg_chiplet[i].disable);
334 }
335}
336
337void gp10b_slcg_ctxsw_firmware_load_gating_prod(struct gk20a *g,
338 bool prod)
339{
340}
341
342void gp10b_slcg_fb_load_gating_prod(struct gk20a *g,
343 bool prod)
344{
345 u32 i;
346 u32 size = sizeof(gp10b_slcg_fb) / sizeof(struct gating_desc);
347
348 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
349 return;
350
351 for (i = 0; i < size; i++) {
352 if (prod)
353 gk20a_writel(g, gp10b_slcg_fb[i].addr,
354 gp10b_slcg_fb[i].prod);
355 else
356 gk20a_writel(g, gp10b_slcg_fb[i].addr,
357 gp10b_slcg_fb[i].disable);
358 }
359}
360
361void gp10b_slcg_fifo_load_gating_prod(struct gk20a *g,
362 bool prod)
363{
364 u32 i;
365 u32 size = sizeof(gp10b_slcg_fifo) / sizeof(struct gating_desc);
366
367 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
368 return;
369
370 for (i = 0; i < size; i++) {
371 if (prod)
372 gk20a_writel(g, gp10b_slcg_fifo[i].addr,
373 gp10b_slcg_fifo[i].prod);
374 else
375 gk20a_writel(g, gp10b_slcg_fifo[i].addr,
376 gp10b_slcg_fifo[i].disable);
377 }
378}
379
380void gr_gp10b_slcg_gr_load_gating_prod(struct gk20a *g,
381 bool prod)
382{
383 u32 i;
384 u32 size = sizeof(gp10b_slcg_gr) / sizeof(struct gating_desc);
385
386 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
387 return;
388
389 for (i = 0; i < size; i++) {
390 if (prod)
391 gk20a_writel(g, gp10b_slcg_gr[i].addr,
392 gp10b_slcg_gr[i].prod);
393 else
394 gk20a_writel(g, gp10b_slcg_gr[i].addr,
395 gp10b_slcg_gr[i].disable);
396 }
397}
398
399void ltc_gp10b_slcg_ltc_load_gating_prod(struct gk20a *g,
400 bool prod)
401{
402 u32 i;
403 u32 size = sizeof(gp10b_slcg_ltc) / sizeof(struct gating_desc);
404
405 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
406 return;
407
408 for (i = 0; i < size; i++) {
409 if (prod)
410 gk20a_writel(g, gp10b_slcg_ltc[i].addr,
411 gp10b_slcg_ltc[i].prod);
412 else
413 gk20a_writel(g, gp10b_slcg_ltc[i].addr,
414 gp10b_slcg_ltc[i].disable);
415 }
416}
417
418void gp10b_slcg_perf_load_gating_prod(struct gk20a *g,
419 bool prod)
420{
421 u32 i;
422 u32 size = sizeof(gp10b_slcg_perf) / sizeof(struct gating_desc);
423
424 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
425 return;
426
427 for (i = 0; i < size; i++) {
428 if (prod)
429 gk20a_writel(g, gp10b_slcg_perf[i].addr,
430 gp10b_slcg_perf[i].prod);
431 else
432 gk20a_writel(g, gp10b_slcg_perf[i].addr,
433 gp10b_slcg_perf[i].disable);
434 }
435}
436
437void gp10b_slcg_priring_load_gating_prod(struct gk20a *g,
438 bool prod)
439{
440 u32 i;
441 u32 size = sizeof(gp10b_slcg_priring) / sizeof(struct gating_desc);
442
443 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
444 return;
445
446 for (i = 0; i < size; i++) {
447 if (prod)
448 gk20a_writel(g, gp10b_slcg_priring[i].addr,
449 gp10b_slcg_priring[i].prod);
450 else
451 gk20a_writel(g, gp10b_slcg_priring[i].addr,
452 gp10b_slcg_priring[i].disable);
453 }
454}
455
456void gp10b_slcg_pwr_csb_load_gating_prod(struct gk20a *g,
457 bool prod)
458{
459 u32 i;
460 u32 size = sizeof(gp10b_slcg_pwr_csb) / sizeof(struct gating_desc);
461
462 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
463 return;
464
465 for (i = 0; i < size; i++) {
466 if (prod)
467 gk20a_writel(g, gp10b_slcg_pwr_csb[i].addr,
468 gp10b_slcg_pwr_csb[i].prod);
469 else
470 gk20a_writel(g, gp10b_slcg_pwr_csb[i].addr,
471 gp10b_slcg_pwr_csb[i].disable);
472 }
473}
474
475void gp10b_slcg_pmu_load_gating_prod(struct gk20a *g,
476 bool prod)
477{
478 u32 i;
479 u32 size = sizeof(gp10b_slcg_pmu) / sizeof(struct gating_desc);
480
481 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
482 return;
483
484 for (i = 0; i < size; i++) {
485 if (prod)
486 gk20a_writel(g, gp10b_slcg_pmu[i].addr,
487 gp10b_slcg_pmu[i].prod);
488 else
489 gk20a_writel(g, gp10b_slcg_pmu[i].addr,
490 gp10b_slcg_pmu[i].disable);
491 }
492}
493
494void gp10b_slcg_therm_load_gating_prod(struct gk20a *g,
495 bool prod)
496{
497 u32 i;
498 u32 size = sizeof(gp10b_slcg_therm) / sizeof(struct gating_desc);
499
500 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
501 return;
502
503 for (i = 0; i < size; i++) {
504 if (prod)
505 gk20a_writel(g, gp10b_slcg_therm[i].addr,
506 gp10b_slcg_therm[i].prod);
507 else
508 gk20a_writel(g, gp10b_slcg_therm[i].addr,
509 gp10b_slcg_therm[i].disable);
510 }
511}
512
513void gp10b_slcg_xbar_load_gating_prod(struct gk20a *g,
514 bool prod)
515{
516 u32 i;
517 u32 size = sizeof(gp10b_slcg_xbar) / sizeof(struct gating_desc);
518
519 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_SLCG))
520 return;
521
522 for (i = 0; i < size; i++) {
523 if (prod)
524 gk20a_writel(g, gp10b_slcg_xbar[i].addr,
525 gp10b_slcg_xbar[i].prod);
526 else
527 gk20a_writel(g, gp10b_slcg_xbar[i].addr,
528 gp10b_slcg_xbar[i].disable);
529 }
530}
531
532void gp10b_blcg_bus_load_gating_prod(struct gk20a *g,
533 bool prod)
534{
535 u32 i;
536 u32 size = sizeof(gp10b_blcg_bus) / sizeof(struct gating_desc);
537
538 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
539 return;
540
541 for (i = 0; i < size; i++) {
542 if (prod)
543 gk20a_writel(g, gp10b_blcg_bus[i].addr,
544 gp10b_blcg_bus[i].prod);
545 else
546 gk20a_writel(g, gp10b_blcg_bus[i].addr,
547 gp10b_blcg_bus[i].disable);
548 }
549}
550
551void gp10b_blcg_ce_load_gating_prod(struct gk20a *g,
552 bool prod)
553{
554 u32 i;
555 u32 size = sizeof(gp10b_blcg_ce) / sizeof(struct gating_desc);
556
557 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
558 return;
559
560 for (i = 0; i < size; i++) {
561 if (prod)
562 gk20a_writel(g, gp10b_blcg_ce[i].addr,
563 gp10b_blcg_ce[i].prod);
564 else
565 gk20a_writel(g, gp10b_blcg_ce[i].addr,
566 gp10b_blcg_ce[i].disable);
567 }
568}
569
570void gp10b_blcg_ctxsw_firmware_load_gating_prod(struct gk20a *g,
571 bool prod)
572{
573 u32 i;
574 u32 size = sizeof(gp10b_blcg_ctxsw_prog) / sizeof(struct gating_desc);
575
576 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
577 return;
578
579 for (i = 0; i < size; i++) {
580 if (prod)
581 gk20a_writel(g, gp10b_blcg_ctxsw_prog[i].addr,
582 gp10b_blcg_ctxsw_prog[i].prod);
583 else
584 gk20a_writel(g, gp10b_blcg_ctxsw_prog[i].addr,
585 gp10b_blcg_ctxsw_prog[i].disable);
586 }
587}
588
589void gp10b_blcg_fb_load_gating_prod(struct gk20a *g,
590 bool prod)
591{
592 u32 i;
593 u32 size = sizeof(gp10b_blcg_fb) / sizeof(struct gating_desc);
594
595 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
596 return;
597
598 for (i = 0; i < size; i++) {
599 if (prod)
600 gk20a_writel(g, gp10b_blcg_fb[i].addr,
601 gp10b_blcg_fb[i].prod);
602 else
603 gk20a_writel(g, gp10b_blcg_fb[i].addr,
604 gp10b_blcg_fb[i].disable);
605 }
606}
607
608void gp10b_blcg_fifo_load_gating_prod(struct gk20a *g,
609 bool prod)
610{
611 u32 i;
612 u32 size = sizeof(gp10b_blcg_fifo) / sizeof(struct gating_desc);
613
614 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
615 return;
616
617 for (i = 0; i < size; i++) {
618 if (prod)
619 gk20a_writel(g, gp10b_blcg_fifo[i].addr,
620 gp10b_blcg_fifo[i].prod);
621 else
622 gk20a_writel(g, gp10b_blcg_fifo[i].addr,
623 gp10b_blcg_fifo[i].disable);
624 }
625}
626
627void gp10b_blcg_gr_load_gating_prod(struct gk20a *g,
628 bool prod)
629{
630 u32 i;
631 u32 size = sizeof(gp10b_blcg_gr) / sizeof(struct gating_desc);
632
633 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
634 return;
635
636 for (i = 0; i < size; i++) {
637 if (prod)
638 gk20a_writel(g, gp10b_blcg_gr[i].addr,
639 gp10b_blcg_gr[i].prod);
640 else
641 gk20a_writel(g, gp10b_blcg_gr[i].addr,
642 gp10b_blcg_gr[i].disable);
643 }
644}
645
646void gp10b_blcg_ltc_load_gating_prod(struct gk20a *g,
647 bool prod)
648{
649 u32 i;
650 u32 size = sizeof(gp10b_blcg_ltc) / sizeof(struct gating_desc);
651
652 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
653 return;
654
655 for (i = 0; i < size; i++) {
656 if (prod)
657 gk20a_writel(g, gp10b_blcg_ltc[i].addr,
658 gp10b_blcg_ltc[i].prod);
659 else
660 gk20a_writel(g, gp10b_blcg_ltc[i].addr,
661 gp10b_blcg_ltc[i].disable);
662 }
663}
664
665void gp10b_blcg_pwr_csb_load_gating_prod(struct gk20a *g,
666 bool prod)
667{
668 u32 i;
669 u32 size = sizeof(gp10b_blcg_pwr_csb) / sizeof(struct gating_desc);
670
671 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
672 return;
673
674 for (i = 0; i < size; i++) {
675 if (prod)
676 gk20a_writel(g, gp10b_blcg_pwr_csb[i].addr,
677 gp10b_blcg_pwr_csb[i].prod);
678 else
679 gk20a_writel(g, gp10b_blcg_pwr_csb[i].addr,
680 gp10b_blcg_pwr_csb[i].disable);
681 }
682}
683
684void gp10b_blcg_pmu_load_gating_prod(struct gk20a *g,
685 bool prod)
686{
687 u32 i;
688 u32 size = sizeof(gp10b_blcg_pmu) / sizeof(struct gating_desc);
689
690 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
691 return;
692
693 for (i = 0; i < size; i++) {
694 if (prod)
695 gk20a_writel(g, gp10b_blcg_pmu[i].addr,
696 gp10b_blcg_pmu[i].prod);
697 else
698 gk20a_writel(g, gp10b_blcg_pmu[i].addr,
699 gp10b_blcg_pmu[i].disable);
700 }
701}
702
703void gp10b_blcg_xbar_load_gating_prod(struct gk20a *g,
704 bool prod)
705{
706 u32 i;
707 u32 size = sizeof(gp10b_blcg_xbar) / sizeof(struct gating_desc);
708
709 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
710 return;
711
712 for (i = 0; i < size; i++) {
713 if (prod)
714 gk20a_writel(g, gp10b_blcg_xbar[i].addr,
715 gp10b_blcg_xbar[i].prod);
716 else
717 gk20a_writel(g, gp10b_blcg_xbar[i].addr,
718 gp10b_blcg_xbar[i].disable);
719 }
720}
721
722void gr_gp10b_pg_gr_load_gating_prod(struct gk20a *g,
723 bool prod)
724{
725 u32 i;
726 u32 size = sizeof(gp10b_pg_gr) / sizeof(struct gating_desc);
727
728 if (!nvgpu_is_enabled(g, NVGPU_GPU_CAN_BLCG))
729 return;
730
731 for (i = 0; i < size; i++) {
732 if (prod)
733 gk20a_writel(g, gp10b_pg_gr[i].addr,
734 gp10b_pg_gr[i].prod);
735 else
736 gk20a_writel(g, gp10b_pg_gr[i].addr,
737 gp10b_pg_gr[i].disable);
738 }
739}
740
741#endif /* __gp10b_gating_reglist_h__ */
diff --git a/drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.h b/drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.h
new file mode 100644
index 00000000..7dbc6cac
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gp10b_gating_reglist.h
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2015-2016, NVIDIA Corporation. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include "gk20a/gk20a.h"
24
25void gp10b_slcg_bus_load_gating_prod(struct gk20a *g,
26 bool prod);
27
28void gp10b_slcg_ce2_load_gating_prod(struct gk20a *g,
29 bool prod);
30
31void gp10b_slcg_chiplet_load_gating_prod(struct gk20a *g,
32 bool prod);
33
34void gp10b_slcg_ctxsw_firmware_load_gating_prod(struct gk20a *g,
35 bool prod);
36
37void gp10b_slcg_fb_load_gating_prod(struct gk20a *g,
38 bool prod);
39
40void gp10b_slcg_fifo_load_gating_prod(struct gk20a *g,
41 bool prod);
42
43void gr_gp10b_slcg_gr_load_gating_prod(struct gk20a *g,
44 bool prod);
45
46void ltc_gp10b_slcg_ltc_load_gating_prod(struct gk20a *g,
47 bool prod);
48
49void gp10b_slcg_perf_load_gating_prod(struct gk20a *g,
50 bool prod);
51
52void gp10b_slcg_priring_load_gating_prod(struct gk20a *g,
53 bool prod);
54
55void gp10b_slcg_pwr_csb_load_gating_prod(struct gk20a *g,
56 bool prod);
57
58void gp10b_slcg_pmu_load_gating_prod(struct gk20a *g,
59 bool prod);
60
61void gp10b_slcg_therm_load_gating_prod(struct gk20a *g,
62 bool prod);
63
64void gp10b_slcg_xbar_load_gating_prod(struct gk20a *g,
65 bool prod);
66
67void gp10b_blcg_bus_load_gating_prod(struct gk20a *g,
68 bool prod);
69
70void gp10b_blcg_ce_load_gating_prod(struct gk20a *g,
71 bool prod);
72
73void gp10b_blcg_ctxsw_firmware_load_gating_prod(struct gk20a *g,
74 bool prod);
75
76void gp10b_blcg_fb_load_gating_prod(struct gk20a *g,
77 bool prod);
78
79void gp10b_blcg_fifo_load_gating_prod(struct gk20a *g,
80 bool prod);
81
82void gp10b_blcg_gr_load_gating_prod(struct gk20a *g,
83 bool prod);
84
85void gp10b_blcg_ltc_load_gating_prod(struct gk20a *g,
86 bool prod);
87
88void gp10b_blcg_pwr_csb_load_gating_prod(struct gk20a *g,
89 bool prod);
90
91void gp10b_blcg_pmu_load_gating_prod(struct gk20a *g,
92 bool prod);
93
94void gp10b_blcg_xbar_load_gating_prod(struct gk20a *g,
95 bool prod);
96
97void gr_gp10b_pg_gr_load_gating_prod(struct gk20a *g,
98 bool prod);
99
diff --git a/drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.c
new file mode 100644
index 00000000..cf51e8b4
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.c
@@ -0,0 +1,72 @@
1/*
2 * drivers/video/tegra/host/gp10b/gr_ctx_gp10b.c
3 *
4 * GM20B Graphics Context
5 *
6 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 */
26
27#include "gk20a/gk20a.h"
28#include "gr_ctx_gp10b.h"
29
30int gr_gp10b_get_netlist_name(struct gk20a *g, int index, char *name)
31{
32 switch (index) {
33#ifdef GP10B_NETLIST_IMAGE_FW_NAME
34 case NETLIST_FINAL:
35 sprintf(name, GP10B_NETLIST_IMAGE_FW_NAME);
36 return 0;
37#endif
38#ifdef GK20A_NETLIST_IMAGE_A
39 case NETLIST_SLOT_A:
40 sprintf(name, GK20A_NETLIST_IMAGE_A);
41 return 0;
42#endif
43#ifdef GK20A_NETLIST_IMAGE_B
44 case NETLIST_SLOT_B:
45 sprintf(name, GK20A_NETLIST_IMAGE_B);
46 return 0;
47#endif
48#ifdef GK20A_NETLIST_IMAGE_C
49 case NETLIST_SLOT_C:
50 sprintf(name, GK20A_NETLIST_IMAGE_C);
51 return 0;
52#endif
53#ifdef GK20A_NETLIST_IMAGE_D
54 case NETLIST_SLOT_D:
55 sprintf(name, GK20A_NETLIST_IMAGE_D);
56 return 0;
57#endif
58 default:
59 return -1;
60 }
61
62 return -1;
63}
64
65bool gr_gp10b_is_firmware_defined(void)
66{
67#ifdef GP10B_NETLIST_IMAGE_FW_NAME
68 return true;
69#else
70 return false;
71#endif
72}
diff --git a/drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.h b/drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.h
new file mode 100644
index 00000000..b409b442
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gr_ctx_gp10b.h
@@ -0,0 +1,35 @@
1/*
2 * GP10B Graphics Context
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#ifndef __GR_CTX_GM10B_H__
25#define __GR_CTX_GM10B_H__
26
27#include "gk20a/gr_ctx_gk20a.h"
28
29/* production netlist, one and only one from below */
30#define GP10B_NETLIST_IMAGE_FW_NAME GK20A_NETLIST_IMAGE_A
31
32int gr_gp10b_get_netlist_name(struct gk20a *g, int index, char *name);
33bool gr_gp10b_is_firmware_defined(void);
34
35#endif /*__GR_CTX_GP10B_H__*/
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
new file mode 100644
index 00000000..08988ac8
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
@@ -0,0 +1,2357 @@
1/*
2 * GP10B GPU GR
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <dt-bindings/soc/gm20b-fuse.h>
26#include <dt-bindings/soc/gp10b-fuse.h>
27#include <uapi/linux/nvgpu.h>
28
29#include <nvgpu/timers.h>
30#include <nvgpu/kmem.h>
31#include <nvgpu/gmmu.h>
32#include <nvgpu/dma.h>
33#include <nvgpu/bug.h>
34#include <nvgpu/debug.h>
35#include <nvgpu/fuse.h>
36#include <nvgpu/enabled.h>
37
38#include "gk20a/gk20a.h"
39#include "gk20a/gr_gk20a.h"
40#include "gk20a/dbg_gpu_gk20a.h"
41#include "gk20a/regops_gk20a.h"
42#include "common/linux/os_linux.h"
43
44#include "gm20b/gr_gm20b.h"
45#include "gp10b/gr_gp10b.h"
46
47#include <nvgpu/hw/gp10b/hw_gr_gp10b.h>
48#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h>
49#include <nvgpu/hw/gp10b/hw_ctxsw_prog_gp10b.h>
50#include <nvgpu/hw/gp10b/hw_mc_gp10b.h>
51#include <nvgpu/hw/gp10b/hw_fuse_gp10b.h>
52
53bool gr_gp10b_is_valid_class(struct gk20a *g, u32 class_num)
54{
55 bool valid = false;
56
57 switch (class_num) {
58 case PASCAL_COMPUTE_A:
59 case PASCAL_A:
60 case PASCAL_DMA_COPY_A:
61 valid = true;
62 break;
63
64 case MAXWELL_COMPUTE_B:
65 case MAXWELL_B:
66 case FERMI_TWOD_A:
67 case KEPLER_DMA_COPY_A:
68 case MAXWELL_DMA_COPY_A:
69 valid = true;
70 break;
71
72 default:
73 break;
74 }
75 gk20a_dbg_info("class=0x%x valid=%d", class_num, valid);
76 return valid;
77}
78
79bool gr_gp10b_is_valid_gfx_class(struct gk20a *g, u32 class_num)
80{
81 if (class_num == PASCAL_A || class_num == MAXWELL_B)
82 return true;
83 else
84 return false;
85}
86
87bool gr_gp10b_is_valid_compute_class(struct gk20a *g, u32 class_num)
88{
89 if (class_num == PASCAL_COMPUTE_A || class_num == MAXWELL_COMPUTE_B)
90 return true;
91 else
92 return false;
93}
94
95
96static void gr_gp10b_sm_lrf_ecc_overcount_war(int single_err,
97 u32 sed_status,
98 u32 ded_status,
99 u32 *count_to_adjust,
100 u32 opposite_count)
101{
102 u32 over_count = 0;
103
104 sed_status >>= gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp0_b();
105 ded_status >>= gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp0_b();
106
107 /* One overcount for each partition on which a SBE occurred but not a
108 DBE (or vice-versa) */
109 if (single_err) {
110 over_count =
111 hweight32(sed_status & ~ded_status);
112 } else {
113 over_count =
114 hweight32(ded_status & ~sed_status);
115 }
116
117 /* If both a SBE and a DBE occur on the same partition, then we have an
118 overcount for the subpartition if the opposite error counts are
119 zero. */
120 if ((sed_status & ded_status) && (opposite_count == 0)) {
121 over_count +=
122 hweight32(sed_status & ded_status);
123 }
124
125 if (*count_to_adjust > over_count)
126 *count_to_adjust -= over_count;
127 else
128 *count_to_adjust = 0;
129}
130
131int gr_gp10b_handle_sm_exception(struct gk20a *g,
132 u32 gpc, u32 tpc, u32 sm,
133 bool *post_event, struct channel_gk20a *fault_ch,
134 u32 *hww_global_esr)
135{
136 int ret = 0;
137 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
138 u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE);
139 u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc;
140 u32 lrf_ecc_status, lrf_ecc_sed_status, lrf_ecc_ded_status;
141 u32 lrf_single_count_delta, lrf_double_count_delta;
142 u32 shm_ecc_status;
143
144 ret = gr_gk20a_handle_sm_exception(g,
145 gpc, tpc, sm, post_event, fault_ch, hww_global_esr);
146
147 /* Check for LRF ECC errors. */
148 lrf_ecc_status = gk20a_readl(g,
149 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r() + offset);
150 lrf_ecc_sed_status = lrf_ecc_status &
151 (gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp0_pending_f() |
152 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp1_pending_f() |
153 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp2_pending_f() |
154 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_single_err_detected_qrfdp3_pending_f());
155 lrf_ecc_ded_status = lrf_ecc_status &
156 (gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp0_pending_f() |
157 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp1_pending_f() |
158 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp2_pending_f() |
159 gr_pri_gpc0_tpc0_sm_lrf_ecc_status_double_err_detected_qrfdp3_pending_f());
160 lrf_single_count_delta =
161 gk20a_readl(g,
162 gr_pri_gpc0_tpc0_sm_lrf_ecc_single_err_count_r() +
163 offset);
164 lrf_double_count_delta =
165 gk20a_readl(g,
166 gr_pri_gpc0_tpc0_sm_lrf_ecc_double_err_count_r() +
167 offset);
168 gk20a_writel(g,
169 gr_pri_gpc0_tpc0_sm_lrf_ecc_single_err_count_r() + offset,
170 0);
171 gk20a_writel(g,
172 gr_pri_gpc0_tpc0_sm_lrf_ecc_double_err_count_r() + offset,
173 0);
174 if (lrf_ecc_sed_status) {
175 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
176 "Single bit error detected in SM LRF!");
177
178 gr_gp10b_sm_lrf_ecc_overcount_war(1,
179 lrf_ecc_sed_status,
180 lrf_ecc_ded_status,
181 &lrf_single_count_delta,
182 lrf_double_count_delta);
183 g->ecc.gr.t18x.sm_lrf_single_err_count.counters[tpc] +=
184 lrf_single_count_delta;
185 }
186 if (lrf_ecc_ded_status) {
187 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
188 "Double bit error detected in SM LRF!");
189
190 gr_gp10b_sm_lrf_ecc_overcount_war(0,
191 lrf_ecc_sed_status,
192 lrf_ecc_ded_status,
193 &lrf_double_count_delta,
194 lrf_single_count_delta);
195 g->ecc.gr.t18x.sm_lrf_double_err_count.counters[tpc] +=
196 lrf_double_count_delta;
197 }
198 gk20a_writel(g, gr_pri_gpc0_tpc0_sm_lrf_ecc_status_r() + offset,
199 lrf_ecc_status);
200
201 /* Check for SHM ECC errors. */
202 shm_ecc_status = gk20a_readl(g,
203 gr_pri_gpc0_tpc0_sm_shm_ecc_status_r() + offset);
204 if ((shm_ecc_status &
205 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_corrected_shm0_pending_f()) ||
206 (shm_ecc_status &
207 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_corrected_shm1_pending_f()) ||
208 (shm_ecc_status &
209 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_detected_shm0_pending_f()) ||
210 (shm_ecc_status &
211 gr_pri_gpc0_tpc0_sm_shm_ecc_status_single_err_detected_shm1_pending_f()) ) {
212 u32 ecc_stats_reg_val;
213
214 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
215 "Single bit error detected in SM SHM!");
216
217 ecc_stats_reg_val =
218 gk20a_readl(g,
219 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset);
220 g->ecc.gr.t18x.sm_shm_sec_count.counters[tpc] +=
221 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_v(ecc_stats_reg_val);
222 g->ecc.gr.t18x.sm_shm_sed_count.counters[tpc] +=
223 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_v(ecc_stats_reg_val);
224 ecc_stats_reg_val &= ~(gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_corrected_m() |
225 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_single_detected_m());
226 gk20a_writel(g,
227 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset,
228 ecc_stats_reg_val);
229 }
230 if ( (shm_ecc_status &
231 gr_pri_gpc0_tpc0_sm_shm_ecc_status_double_err_detected_shm0_pending_f()) ||
232 (shm_ecc_status &
233 gr_pri_gpc0_tpc0_sm_shm_ecc_status_double_err_detected_shm1_pending_f()) ) {
234 u32 ecc_stats_reg_val;
235
236 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
237 "Double bit error detected in SM SHM!");
238
239 ecc_stats_reg_val =
240 gk20a_readl(g,
241 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset);
242 g->ecc.gr.t18x.sm_shm_ded_count.counters[tpc] +=
243 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_v(ecc_stats_reg_val);
244 ecc_stats_reg_val &= ~(gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_double_detected_m());
245 gk20a_writel(g,
246 gr_pri_gpc0_tpc0_sm_shm_ecc_err_count_r() + offset,
247 ecc_stats_reg_val);
248 }
249 gk20a_writel(g, gr_pri_gpc0_tpc0_sm_shm_ecc_status_r() + offset,
250 shm_ecc_status);
251
252
253 return ret;
254}
255
256int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
257 bool *post_event)
258{
259 int ret = 0;
260 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
261 u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE);
262 u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc;
263 u32 esr;
264 u32 ecc_stats_reg_val;
265
266 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, "");
267
268 esr = gk20a_readl(g,
269 gr_gpc0_tpc0_tex_m_hww_esr_r() + offset);
270 gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "0x%08x", esr);
271
272 if (esr & gr_gpc0_tpc0_tex_m_hww_esr_ecc_sec_pending_f()) {
273 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
274 "Single bit error detected in TEX!");
275
276 /* Pipe 0 counters */
277 gk20a_writel(g,
278 gr_pri_gpc0_tpc0_tex_m_routing_r() + offset,
279 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe0_f());
280
281 ecc_stats_reg_val = gk20a_readl(g,
282 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
283 g->ecc.gr.t18x.tex_total_sec_pipe0_count.counters[tpc] +=
284 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(ecc_stats_reg_val);
285 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m();
286 gk20a_writel(g,
287 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset,
288 ecc_stats_reg_val);
289
290 ecc_stats_reg_val = gk20a_readl(g,
291 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
292 g->ecc.gr.t18x.tex_unique_sec_pipe0_count.counters[tpc] +=
293 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(ecc_stats_reg_val);
294 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m();
295 gk20a_writel(g,
296 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset,
297 ecc_stats_reg_val);
298
299
300 /* Pipe 1 counters */
301 gk20a_writel(g,
302 gr_pri_gpc0_tpc0_tex_m_routing_r() + offset,
303 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe1_f());
304
305 ecc_stats_reg_val = gk20a_readl(g,
306 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
307 g->ecc.gr.t18x.tex_total_sec_pipe1_count.counters[tpc] +=
308 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_v(ecc_stats_reg_val);
309 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_sec_m();
310 gk20a_writel(g,
311 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset,
312 ecc_stats_reg_val);
313
314 ecc_stats_reg_val = gk20a_readl(g,
315 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
316 g->ecc.gr.t18x.tex_unique_sec_pipe1_count.counters[tpc] +=
317 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_v(ecc_stats_reg_val);
318 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_sec_m();
319 gk20a_writel(g,
320 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset,
321 ecc_stats_reg_val);
322
323
324 gk20a_writel(g,
325 gr_pri_gpc0_tpc0_tex_m_routing_r() + offset,
326 gr_pri_gpc0_tpc0_tex_m_routing_sel_default_f());
327 }
328 if (esr & gr_gpc0_tpc0_tex_m_hww_esr_ecc_ded_pending_f()) {
329 gk20a_dbg(gpu_dbg_fn | gpu_dbg_intr,
330 "Double bit error detected in TEX!");
331
332 /* Pipe 0 counters */
333 gk20a_writel(g,
334 gr_pri_gpc0_tpc0_tex_m_routing_r() + offset,
335 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe0_f());
336
337 ecc_stats_reg_val = gk20a_readl(g,
338 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
339 g->ecc.gr.t18x.tex_total_ded_pipe0_count.counters[tpc] +=
340 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(ecc_stats_reg_val);
341 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m();
342 gk20a_writel(g,
343 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset,
344 ecc_stats_reg_val);
345
346 ecc_stats_reg_val = gk20a_readl(g,
347 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
348 g->ecc.gr.t18x.tex_unique_ded_pipe0_count.counters[tpc] +=
349 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(ecc_stats_reg_val);
350 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m();
351 gk20a_writel(g,
352 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset,
353 ecc_stats_reg_val);
354
355
356 /* Pipe 1 counters */
357 gk20a_writel(g,
358 gr_pri_gpc0_tpc0_tex_m_routing_r() + offset,
359 gr_pri_gpc0_tpc0_tex_m_routing_sel_pipe1_f());
360
361 ecc_stats_reg_val = gk20a_readl(g,
362 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset);
363 g->ecc.gr.t18x.tex_total_ded_pipe1_count.counters[tpc] +=
364 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_v(ecc_stats_reg_val);
365 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_ded_m();
366 gk20a_writel(g,
367 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_total_r() + offset,
368 ecc_stats_reg_val);
369
370 ecc_stats_reg_val = gk20a_readl(g,
371 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset);
372 g->ecc.gr.t18x.tex_unique_ded_pipe1_count.counters[tpc] +=
373 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_v(ecc_stats_reg_val);
374 ecc_stats_reg_val &= ~gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_ded_m();
375 gk20a_writel(g,
376 gr_pri_gpc0_tpc0_tex_m_ecc_cnt_unique_r() + offset,
377 ecc_stats_reg_val);
378
379
380 gk20a_writel(g,
381 gr_pri_gpc0_tpc0_tex_m_routing_r() + offset,
382 gr_pri_gpc0_tpc0_tex_m_routing_sel_default_f());
383 }
384
385 gk20a_writel(g,
386 gr_gpc0_tpc0_tex_m_hww_esr_r() + offset,
387 esr | gr_gpc0_tpc0_tex_m_hww_esr_reset_active_f());
388
389 return ret;
390}
391
392int gr_gp10b_commit_global_cb_manager(struct gk20a *g,
393 struct channel_gk20a *c, bool patch)
394{
395 struct gr_gk20a *gr = &g->gr;
396 struct channel_ctx_gk20a *ch_ctx = &c->ch_ctx;
397 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
398 u32 attrib_offset_in_chunk = 0;
399 u32 alpha_offset_in_chunk = 0;
400 u32 pd_ab_max_output;
401 u32 gpc_index, ppc_index;
402 u32 temp, temp2;
403 u32 cbm_cfg_size_beta, cbm_cfg_size_alpha, cbm_cfg_size_steadystate;
404 u32 attrib_size_in_chunk, cb_attrib_cache_size_init;
405 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
406 u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_STRIDE);
407 u32 num_pes_per_gpc = nvgpu_get_litter_value(g, GPU_LIT_NUM_PES_PER_GPC);
408
409 gk20a_dbg_fn("");
410
411 if (gr_ctx->graphics_preempt_mode == NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP) {
412 attrib_size_in_chunk = gr->attrib_cb_default_size +
413 (gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v() -
414 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v());
415 cb_attrib_cache_size_init = gr->attrib_cb_default_size +
416 (gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v() -
417 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v());
418 } else {
419 attrib_size_in_chunk = gr->attrib_cb_size;
420 cb_attrib_cache_size_init = gr->attrib_cb_default_size;
421 }
422
423 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_ds_tga_constraintlogic_beta_r(),
424 gr->attrib_cb_default_size, patch);
425 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_ds_tga_constraintlogic_alpha_r(),
426 gr->alpha_cb_default_size, patch);
427
428 pd_ab_max_output = (gr->alpha_cb_default_size *
429 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v()) /
430 gr_pd_ab_dist_cfg1_max_output_granularity_v();
431
432 if (g->gr.pd_max_batches) {
433 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_pd_ab_dist_cfg1_r(),
434 gr_pd_ab_dist_cfg1_max_output_f(pd_ab_max_output) |
435 gr_pd_ab_dist_cfg1_max_batches_f(g->gr.pd_max_batches), patch);
436 } else {
437 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_pd_ab_dist_cfg1_r(),
438 gr_pd_ab_dist_cfg1_max_output_f(pd_ab_max_output) |
439 gr_pd_ab_dist_cfg1_max_batches_init_f(), patch);
440 }
441
442 attrib_offset_in_chunk = alpha_offset_in_chunk +
443 gr->tpc_count * gr->alpha_cb_size;
444
445 for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) {
446 temp = gpc_stride * gpc_index;
447 temp2 = num_pes_per_gpc * gpc_index;
448 for (ppc_index = 0; ppc_index < gr->gpc_ppc_count[gpc_index];
449 ppc_index++) {
450 cbm_cfg_size_beta = cb_attrib_cache_size_init *
451 gr->pes_tpc_count[ppc_index][gpc_index];
452 cbm_cfg_size_alpha = gr->alpha_cb_default_size *
453 gr->pes_tpc_count[ppc_index][gpc_index];
454 cbm_cfg_size_steadystate = gr->attrib_cb_default_size *
455 gr->pes_tpc_count[ppc_index][gpc_index];
456
457 gr_gk20a_ctx_patch_write(g, ch_ctx,
458 gr_gpc0_ppc0_cbm_beta_cb_size_r() + temp +
459 ppc_in_gpc_stride * ppc_index,
460 cbm_cfg_size_beta, patch);
461
462 gr_gk20a_ctx_patch_write(g, ch_ctx,
463 gr_gpc0_ppc0_cbm_beta_cb_offset_r() + temp +
464 ppc_in_gpc_stride * ppc_index,
465 attrib_offset_in_chunk, patch);
466
467 gr_gk20a_ctx_patch_write(g, ch_ctx,
468 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r() + temp +
469 ppc_in_gpc_stride * ppc_index,
470 cbm_cfg_size_steadystate,
471 patch);
472
473 attrib_offset_in_chunk += attrib_size_in_chunk *
474 gr->pes_tpc_count[ppc_index][gpc_index];
475
476 gr_gk20a_ctx_patch_write(g, ch_ctx,
477 gr_gpc0_ppc0_cbm_alpha_cb_size_r() + temp +
478 ppc_in_gpc_stride * ppc_index,
479 cbm_cfg_size_alpha, patch);
480
481 gr_gk20a_ctx_patch_write(g, ch_ctx,
482 gr_gpc0_ppc0_cbm_alpha_cb_offset_r() + temp +
483 ppc_in_gpc_stride * ppc_index,
484 alpha_offset_in_chunk, patch);
485
486 alpha_offset_in_chunk += gr->alpha_cb_size *
487 gr->pes_tpc_count[ppc_index][gpc_index];
488
489 gr_gk20a_ctx_patch_write(g, ch_ctx,
490 gr_gpcs_swdx_tc_beta_cb_size_r(ppc_index + temp2),
491 gr_gpcs_swdx_tc_beta_cb_size_v_f(cbm_cfg_size_steadystate),
492 patch);
493 }
494 }
495
496 return 0;
497}
498
499void gr_gp10b_commit_global_pagepool(struct gk20a *g,
500 struct channel_ctx_gk20a *ch_ctx,
501 u64 addr, u32 size, bool patch)
502{
503 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_scc_pagepool_base_r(),
504 gr_scc_pagepool_base_addr_39_8_f(addr), patch);
505
506 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_scc_pagepool_r(),
507 gr_scc_pagepool_total_pages_f(size) |
508 gr_scc_pagepool_valid_true_f(), patch);
509
510 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_gcc_pagepool_base_r(),
511 gr_gpcs_gcc_pagepool_base_addr_39_8_f(addr), patch);
512
513 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_gcc_pagepool_r(),
514 gr_gpcs_gcc_pagepool_total_pages_f(size), patch);
515}
516
517int gr_gp10b_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr,
518 struct zbc_entry *color_val, u32 index)
519{
520 u32 i;
521 u32 zbc_c;
522
523 /* update l2 table */
524 g->ops.ltc.set_zbc_color_entry(g, color_val, index);
525
526 /* update ds table */
527 gk20a_writel(g, gr_ds_zbc_color_r_r(),
528 gr_ds_zbc_color_r_val_f(color_val->color_ds[0]));
529 gk20a_writel(g, gr_ds_zbc_color_g_r(),
530 gr_ds_zbc_color_g_val_f(color_val->color_ds[1]));
531 gk20a_writel(g, gr_ds_zbc_color_b_r(),
532 gr_ds_zbc_color_b_val_f(color_val->color_ds[2]));
533 gk20a_writel(g, gr_ds_zbc_color_a_r(),
534 gr_ds_zbc_color_a_val_f(color_val->color_ds[3]));
535
536 gk20a_writel(g, gr_ds_zbc_color_fmt_r(),
537 gr_ds_zbc_color_fmt_val_f(color_val->format));
538
539 gk20a_writel(g, gr_ds_zbc_tbl_index_r(),
540 gr_ds_zbc_tbl_index_val_f(index + GK20A_STARTOF_ZBC_TABLE));
541
542 /* trigger the write */
543 gk20a_writel(g, gr_ds_zbc_tbl_ld_r(),
544 gr_ds_zbc_tbl_ld_select_c_f() |
545 gr_ds_zbc_tbl_ld_action_write_f() |
546 gr_ds_zbc_tbl_ld_trigger_active_f());
547
548 /* update local copy */
549 for (i = 0; i < GK20A_ZBC_COLOR_VALUE_SIZE; i++) {
550 gr->zbc_col_tbl[index].color_l2[i] = color_val->color_l2[i];
551 gr->zbc_col_tbl[index].color_ds[i] = color_val->color_ds[i];
552 }
553 gr->zbc_col_tbl[index].format = color_val->format;
554 gr->zbc_col_tbl[index].ref_cnt++;
555
556 gk20a_writel_check(g, gr_gpcs_swdx_dss_zbc_color_r_r(index),
557 color_val->color_ds[0]);
558 gk20a_writel_check(g, gr_gpcs_swdx_dss_zbc_color_g_r(index),
559 color_val->color_ds[1]);
560 gk20a_writel_check(g, gr_gpcs_swdx_dss_zbc_color_b_r(index),
561 color_val->color_ds[2]);
562 gk20a_writel_check(g, gr_gpcs_swdx_dss_zbc_color_a_r(index),
563 color_val->color_ds[3]);
564 zbc_c = gk20a_readl(g, gr_gpcs_swdx_dss_zbc_c_01_to_04_format_r() + (index & ~3));
565 zbc_c &= ~(0x7f << ((index % 4) * 7));
566 zbc_c |= color_val->format << ((index % 4) * 7);
567 gk20a_writel_check(g, gr_gpcs_swdx_dss_zbc_c_01_to_04_format_r() + (index & ~3), zbc_c);
568
569 return 0;
570}
571
572int gr_gp10b_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr,
573 struct zbc_entry *depth_val, u32 index)
574{
575 u32 zbc_z;
576
577 /* update l2 table */
578 g->ops.ltc.set_zbc_depth_entry(g, depth_val, index);
579
580 /* update ds table */
581 gk20a_writel(g, gr_ds_zbc_z_r(),
582 gr_ds_zbc_z_val_f(depth_val->depth));
583
584 gk20a_writel(g, gr_ds_zbc_z_fmt_r(),
585 gr_ds_zbc_z_fmt_val_f(depth_val->format));
586
587 gk20a_writel(g, gr_ds_zbc_tbl_index_r(),
588 gr_ds_zbc_tbl_index_val_f(index + GK20A_STARTOF_ZBC_TABLE));
589
590 /* trigger the write */
591 gk20a_writel(g, gr_ds_zbc_tbl_ld_r(),
592 gr_ds_zbc_tbl_ld_select_z_f() |
593 gr_ds_zbc_tbl_ld_action_write_f() |
594 gr_ds_zbc_tbl_ld_trigger_active_f());
595
596 /* update local copy */
597 gr->zbc_dep_tbl[index].depth = depth_val->depth;
598 gr->zbc_dep_tbl[index].format = depth_val->format;
599 gr->zbc_dep_tbl[index].ref_cnt++;
600
601 gk20a_writel(g, gr_gpcs_swdx_dss_zbc_z_r(index), depth_val->depth);
602 zbc_z = gk20a_readl(g, gr_gpcs_swdx_dss_zbc_z_01_to_04_format_r() + (index & ~3));
603 zbc_z &= ~(0x7f << (index % 4) * 7);
604 zbc_z |= depth_val->format << (index % 4) * 7;
605 gk20a_writel(g, gr_gpcs_swdx_dss_zbc_z_01_to_04_format_r() + (index & ~3), zbc_z);
606
607 return 0;
608}
609
610u32 gr_gp10b_pagepool_default_size(struct gk20a *g)
611{
612 return gr_scc_pagepool_total_pages_hwmax_value_v();
613}
614
615int gr_gp10b_calc_global_ctx_buffer_size(struct gk20a *g)
616{
617 struct gr_gk20a *gr = &g->gr;
618 int size;
619
620 gr->attrib_cb_size = gr->attrib_cb_default_size;
621 gr->alpha_cb_size = gr->alpha_cb_default_size;
622
623 gr->attrib_cb_size = min(gr->attrib_cb_size,
624 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(~0) / g->gr.tpc_count);
625 gr->alpha_cb_size = min(gr->alpha_cb_size,
626 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(~0) / g->gr.tpc_count);
627
628 size = gr->attrib_cb_size *
629 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v() *
630 gr->max_tpc_count;
631
632 size += gr->alpha_cb_size *
633 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v() *
634 gr->max_tpc_count;
635
636 size = ALIGN(size, 128);
637
638 return size;
639}
640
641static void gr_gp10b_set_go_idle_timeout(struct gk20a *g, u32 data)
642{
643 gk20a_writel(g, gr_fe_go_idle_timeout_r(), data);
644}
645
646static void gr_gp10b_set_coalesce_buffer_size(struct gk20a *g, u32 data)
647{
648 u32 val;
649
650 gk20a_dbg_fn("");
651
652 val = gk20a_readl(g, gr_gpcs_tc_debug0_r());
653 val = set_field(val, gr_gpcs_tc_debug0_limit_coalesce_buffer_size_m(),
654 gr_gpcs_tc_debug0_limit_coalesce_buffer_size_f(data));
655 gk20a_writel(g, gr_gpcs_tc_debug0_r(), val);
656
657 gk20a_dbg_fn("done");
658}
659
660void gr_gp10b_set_bes_crop_debug3(struct gk20a *g, u32 data)
661{
662 u32 val;
663
664 gk20a_dbg_fn("");
665
666 val = gk20a_readl(g, gr_bes_crop_debug3_r());
667 if ((data & 1)) {
668 val = set_field(val,
669 gr_bes_crop_debug3_blendopt_read_suppress_m(),
670 gr_bes_crop_debug3_blendopt_read_suppress_enabled_f());
671 val = set_field(val,
672 gr_bes_crop_debug3_blendopt_fill_override_m(),
673 gr_bes_crop_debug3_blendopt_fill_override_enabled_f());
674 } else {
675 val = set_field(val,
676 gr_bes_crop_debug3_blendopt_read_suppress_m(),
677 gr_bes_crop_debug3_blendopt_read_suppress_disabled_f());
678 val = set_field(val,
679 gr_bes_crop_debug3_blendopt_fill_override_m(),
680 gr_bes_crop_debug3_blendopt_fill_override_disabled_f());
681 }
682 gk20a_writel(g, gr_bes_crop_debug3_r(), val);
683}
684
685int gr_gp10b_handle_sw_method(struct gk20a *g, u32 addr,
686 u32 class_num, u32 offset, u32 data)
687{
688 gk20a_dbg_fn("");
689
690 if (class_num == PASCAL_COMPUTE_A) {
691 switch (offset << 2) {
692 case NVC0C0_SET_SHADER_EXCEPTIONS:
693 gk20a_gr_set_shader_exceptions(g, data);
694 break;
695 case NVC0C0_SET_RD_COALESCE:
696 gr_gm20b_set_rd_coalesce(g, data);
697 break;
698 default:
699 goto fail;
700 }
701 }
702
703 if (class_num == PASCAL_A) {
704 switch (offset << 2) {
705 case NVC097_SET_SHADER_EXCEPTIONS:
706 gk20a_gr_set_shader_exceptions(g, data);
707 break;
708 case NVC097_SET_CIRCULAR_BUFFER_SIZE:
709 g->ops.gr.set_circular_buffer_size(g, data);
710 break;
711 case NVC097_SET_ALPHA_CIRCULAR_BUFFER_SIZE:
712 g->ops.gr.set_alpha_circular_buffer_size(g, data);
713 break;
714 case NVC097_SET_GO_IDLE_TIMEOUT:
715 gr_gp10b_set_go_idle_timeout(g, data);
716 break;
717 case NVC097_SET_COALESCE_BUFFER_SIZE:
718 gr_gp10b_set_coalesce_buffer_size(g, data);
719 break;
720 case NVC097_SET_RD_COALESCE:
721 gr_gm20b_set_rd_coalesce(g, data);
722 break;
723 case NVC097_SET_BES_CROP_DEBUG3:
724 g->ops.gr.set_bes_crop_debug3(g, data);
725 break;
726 default:
727 goto fail;
728 }
729 }
730 return 0;
731
732fail:
733 return -EINVAL;
734}
735
736void gr_gp10b_cb_size_default(struct gk20a *g)
737{
738 struct gr_gk20a *gr = &g->gr;
739
740 if (!gr->attrib_cb_default_size)
741 gr->attrib_cb_default_size = 0x800;
742 gr->alpha_cb_default_size =
743 gr_gpc0_ppc0_cbm_alpha_cb_size_v_default_v();
744}
745
746void gr_gp10b_set_alpha_circular_buffer_size(struct gk20a *g, u32 data)
747{
748 struct gr_gk20a *gr = &g->gr;
749 u32 gpc_index, ppc_index, stride, val;
750 u32 pd_ab_max_output;
751 u32 alpha_cb_size = data * 4;
752 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
753 u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_STRIDE);
754
755 gk20a_dbg_fn("");
756
757 if (alpha_cb_size > gr->alpha_cb_size)
758 alpha_cb_size = gr->alpha_cb_size;
759
760 gk20a_writel(g, gr_ds_tga_constraintlogic_alpha_r(),
761 (gk20a_readl(g, gr_ds_tga_constraintlogic_alpha_r()) &
762 ~gr_ds_tga_constraintlogic_alpha_cbsize_f(~0)) |
763 gr_ds_tga_constraintlogic_alpha_cbsize_f(alpha_cb_size));
764
765 pd_ab_max_output = alpha_cb_size *
766 gr_gpc0_ppc0_cbm_alpha_cb_size_v_granularity_v() /
767 gr_pd_ab_dist_cfg1_max_output_granularity_v();
768
769 if (g->gr.pd_max_batches) {
770 gk20a_writel(g, gr_pd_ab_dist_cfg1_r(),
771 gr_pd_ab_dist_cfg1_max_output_f(pd_ab_max_output) |
772 gr_pd_ab_dist_cfg1_max_batches_f(g->gr.pd_max_batches));
773 } else {
774 gk20a_writel(g, gr_pd_ab_dist_cfg1_r(),
775 gr_pd_ab_dist_cfg1_max_output_f(pd_ab_max_output) |
776 gr_pd_ab_dist_cfg1_max_batches_init_f());
777 }
778
779 for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) {
780 stride = gpc_stride * gpc_index;
781
782 for (ppc_index = 0; ppc_index < gr->gpc_ppc_count[gpc_index];
783 ppc_index++) {
784
785 val = gk20a_readl(g, gr_gpc0_ppc0_cbm_alpha_cb_size_r() +
786 stride +
787 ppc_in_gpc_stride * ppc_index);
788
789 val = set_field(val, gr_gpc0_ppc0_cbm_alpha_cb_size_v_m(),
790 gr_gpc0_ppc0_cbm_alpha_cb_size_v_f(alpha_cb_size *
791 gr->pes_tpc_count[ppc_index][gpc_index]));
792
793 gk20a_writel(g, gr_gpc0_ppc0_cbm_alpha_cb_size_r() +
794 stride +
795 ppc_in_gpc_stride * ppc_index, val);
796 }
797 }
798}
799
800void gr_gp10b_set_circular_buffer_size(struct gk20a *g, u32 data)
801{
802 struct gr_gk20a *gr = &g->gr;
803 u32 gpc_index, ppc_index, stride, val;
804 u32 cb_size_steady = data * 4, cb_size;
805 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
806 u32 ppc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_PPC_IN_GPC_STRIDE);
807
808 gk20a_dbg_fn("");
809
810 if (cb_size_steady > gr->attrib_cb_size)
811 cb_size_steady = gr->attrib_cb_size;
812 if (gk20a_readl(g, gr_gpc0_ppc0_cbm_beta_cb_size_r()) !=
813 gk20a_readl(g,
814 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r())) {
815 cb_size = cb_size_steady +
816 (gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v() -
817 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v());
818 } else {
819 cb_size = cb_size_steady;
820 }
821
822 gk20a_writel(g, gr_ds_tga_constraintlogic_beta_r(),
823 (gk20a_readl(g, gr_ds_tga_constraintlogic_beta_r()) &
824 ~gr_ds_tga_constraintlogic_beta_cbsize_f(~0)) |
825 gr_ds_tga_constraintlogic_beta_cbsize_f(cb_size_steady));
826
827 for (gpc_index = 0; gpc_index < gr->gpc_count; gpc_index++) {
828 stride = gpc_stride * gpc_index;
829
830 for (ppc_index = 0; ppc_index < gr->gpc_ppc_count[gpc_index];
831 ppc_index++) {
832
833 val = gk20a_readl(g, gr_gpc0_ppc0_cbm_beta_cb_size_r() +
834 stride +
835 ppc_in_gpc_stride * ppc_index);
836
837 val = set_field(val,
838 gr_gpc0_ppc0_cbm_beta_cb_size_v_m(),
839 gr_gpc0_ppc0_cbm_beta_cb_size_v_f(cb_size *
840 gr->pes_tpc_count[ppc_index][gpc_index]));
841
842 gk20a_writel(g, gr_gpc0_ppc0_cbm_beta_cb_size_r() +
843 stride +
844 ppc_in_gpc_stride * ppc_index, val);
845
846 gk20a_writel(g, ppc_in_gpc_stride * ppc_index +
847 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_r() +
848 stride,
849 gr_gpc0_ppc0_cbm_beta_steady_state_cb_size_v_f(
850 cb_size_steady));
851
852 val = gk20a_readl(g, gr_gpcs_swdx_tc_beta_cb_size_r(
853 ppc_index + gpc_index));
854
855 val = set_field(val,
856 gr_gpcs_swdx_tc_beta_cb_size_v_m(),
857 gr_gpcs_swdx_tc_beta_cb_size_v_f(
858 cb_size_steady *
859 gr->gpc_ppc_count[gpc_index]));
860
861 gk20a_writel(g, gr_gpcs_swdx_tc_beta_cb_size_r(
862 ppc_index + gpc_index), val);
863 }
864 }
865}
866
867int gr_gp10b_init_ctx_state(struct gk20a *g)
868{
869 struct fecs_method_op_gk20a op = {
870 .mailbox = { .id = 0, .data = 0,
871 .clr = ~0, .ok = 0, .fail = 0},
872 .method.data = 0,
873 .cond.ok = GR_IS_UCODE_OP_NOT_EQUAL,
874 .cond.fail = GR_IS_UCODE_OP_SKIP,
875 };
876 int err;
877
878 gk20a_dbg_fn("");
879
880 err = gr_gk20a_init_ctx_state(g);
881 if (err)
882 return err;
883
884 if (!g->gr.t18x.ctx_vars.preempt_image_size) {
885 op.method.addr =
886 gr_fecs_method_push_adr_discover_preemption_image_size_v();
887 op.mailbox.ret = &g->gr.t18x.ctx_vars.preempt_image_size;
888 err = gr_gk20a_submit_fecs_method_op(g, op, false);
889 if (err) {
890 nvgpu_err(g, "query preempt image size failed");
891 return err;
892 }
893 }
894
895 gk20a_dbg_info("preempt image size: %u",
896 g->gr.t18x.ctx_vars.preempt_image_size);
897
898 gk20a_dbg_fn("done");
899
900 return 0;
901}
902
903int gr_gp10b_alloc_buffer(struct vm_gk20a *vm, size_t size,
904 struct nvgpu_mem *mem)
905{
906 int err;
907
908 gk20a_dbg_fn("");
909
910 err = nvgpu_dma_alloc_sys(vm->mm->g, size, mem);
911 if (err)
912 return err;
913
914 mem->gpu_va = nvgpu_gmmu_map(vm,
915 mem,
916 mem->aligned_size,
917 NVGPU_AS_MAP_BUFFER_FLAGS_CACHEABLE,
918 gk20a_mem_flag_none,
919 false,
920 mem->aperture);
921
922 if (!mem->gpu_va) {
923 err = -ENOMEM;
924 goto fail_free;
925 }
926
927 return 0;
928
929fail_free:
930 nvgpu_dma_free(vm->mm->g, mem);
931 return err;
932}
933
934int gr_gp10b_set_ctxsw_preemption_mode(struct gk20a *g,
935 struct gr_ctx_desc *gr_ctx,
936 struct vm_gk20a *vm, u32 class,
937 u32 graphics_preempt_mode,
938 u32 compute_preempt_mode)
939{
940 int err = 0;
941
942 if (g->ops.gr.is_valid_gfx_class(g, class) &&
943 g->gr.t18x.ctx_vars.force_preemption_gfxp)
944 graphics_preempt_mode = NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP;
945
946 if (g->ops.gr.is_valid_compute_class(g, class) &&
947 g->gr.t18x.ctx_vars.force_preemption_cilp)
948 compute_preempt_mode = NVGPU_PREEMPTION_MODE_COMPUTE_CILP;
949
950 /* check for invalid combinations */
951 if ((graphics_preempt_mode == 0) && (compute_preempt_mode == 0))
952 return -EINVAL;
953
954 if ((graphics_preempt_mode == NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP) &&
955 (compute_preempt_mode == NVGPU_PREEMPTION_MODE_COMPUTE_CILP))
956 return -EINVAL;
957
958 /* Do not allow lower preemption modes than current ones */
959 if (graphics_preempt_mode &&
960 (graphics_preempt_mode < gr_ctx->graphics_preempt_mode))
961 return -EINVAL;
962
963 if (compute_preempt_mode &&
964 (compute_preempt_mode < gr_ctx->compute_preempt_mode))
965 return -EINVAL;
966
967 /* set preemption modes */
968 switch (graphics_preempt_mode) {
969 case NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP:
970 {
971 u32 spill_size =
972 gr_gpc0_swdx_rm_spill_buffer_size_256b_default_v() *
973 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v();
974 u32 pagepool_size = g->ops.gr.pagepool_default_size(g) *
975 gr_scc_pagepool_total_pages_byte_granularity_v();
976 u32 betacb_size = g->gr.attrib_cb_default_size +
977 (gr_gpc0_ppc0_cbm_beta_cb_size_v_gfxp_v() -
978 gr_gpc0_ppc0_cbm_beta_cb_size_v_default_v());
979 u32 attrib_cb_size = (betacb_size + g->gr.alpha_cb_size) *
980 gr_gpc0_ppc0_cbm_beta_cb_size_v_granularity_v() *
981 g->gr.max_tpc_count;
982 attrib_cb_size = ALIGN(attrib_cb_size, 128);
983
984 gk20a_dbg_info("gfxp context spill_size=%d", spill_size);
985 gk20a_dbg_info("gfxp context pagepool_size=%d", pagepool_size);
986 gk20a_dbg_info("gfxp context attrib_cb_size=%d",
987 attrib_cb_size);
988
989 err = gr_gp10b_alloc_buffer(vm,
990 g->gr.t18x.ctx_vars.preempt_image_size,
991 &gr_ctx->t18x.preempt_ctxsw_buffer);
992 if (err) {
993 nvgpu_err(g, "cannot allocate preempt buffer");
994 goto fail;
995 }
996
997 err = gr_gp10b_alloc_buffer(vm,
998 spill_size,
999 &gr_ctx->t18x.spill_ctxsw_buffer);
1000 if (err) {
1001 nvgpu_err(g, "cannot allocate spill buffer");
1002 goto fail_free_preempt;
1003 }
1004
1005 err = gr_gp10b_alloc_buffer(vm,
1006 attrib_cb_size,
1007 &gr_ctx->t18x.betacb_ctxsw_buffer);
1008 if (err) {
1009 nvgpu_err(g, "cannot allocate beta buffer");
1010 goto fail_free_spill;
1011 }
1012
1013 err = gr_gp10b_alloc_buffer(vm,
1014 pagepool_size,
1015 &gr_ctx->t18x.pagepool_ctxsw_buffer);
1016 if (err) {
1017 nvgpu_err(g, "cannot allocate page pool");
1018 goto fail_free_betacb;
1019 }
1020
1021 gr_ctx->graphics_preempt_mode = graphics_preempt_mode;
1022 break;
1023 }
1024
1025 case NVGPU_PREEMPTION_MODE_GRAPHICS_WFI:
1026 gr_ctx->graphics_preempt_mode = graphics_preempt_mode;
1027 break;
1028
1029 default:
1030 break;
1031 }
1032
1033 if (g->ops.gr.is_valid_compute_class(g, class) ||
1034 g->ops.gr.is_valid_gfx_class(g, class)) {
1035 switch (compute_preempt_mode) {
1036 case NVGPU_PREEMPTION_MODE_COMPUTE_WFI:
1037 case NVGPU_PREEMPTION_MODE_COMPUTE_CTA:
1038 case NVGPU_PREEMPTION_MODE_COMPUTE_CILP:
1039 gr_ctx->compute_preempt_mode = compute_preempt_mode;
1040 break;
1041 default:
1042 break;
1043 }
1044 }
1045
1046 return 0;
1047
1048fail_free_betacb:
1049 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.betacb_ctxsw_buffer);
1050fail_free_spill:
1051 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.spill_ctxsw_buffer);
1052fail_free_preempt:
1053 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.preempt_ctxsw_buffer);
1054fail:
1055 return err;
1056}
1057
1058int gr_gp10b_alloc_gr_ctx(struct gk20a *g,
1059 struct gr_ctx_desc **gr_ctx, struct vm_gk20a *vm,
1060 u32 class,
1061 u32 flags)
1062{
1063 int err;
1064 u32 graphics_preempt_mode = 0;
1065 u32 compute_preempt_mode = 0;
1066
1067 gk20a_dbg_fn("");
1068
1069 err = gr_gk20a_alloc_gr_ctx(g, gr_ctx, vm, class, flags);
1070 if (err)
1071 return err;
1072
1073 (*gr_ctx)->t18x.ctx_id_valid = false;
1074
1075 if (flags & NVGPU_OBJ_CTX_FLAGS_SUPPORT_GFXP)
1076 graphics_preempt_mode = NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP;
1077 if (flags & NVGPU_OBJ_CTX_FLAGS_SUPPORT_CILP)
1078 compute_preempt_mode = NVGPU_PREEMPTION_MODE_COMPUTE_CILP;
1079
1080 if (graphics_preempt_mode || compute_preempt_mode) {
1081 if (g->ops.gr.set_ctxsw_preemption_mode) {
1082 err = g->ops.gr.set_ctxsw_preemption_mode(g, *gr_ctx, vm,
1083 class, graphics_preempt_mode, compute_preempt_mode);
1084 if (err) {
1085 nvgpu_err(g, "set_ctxsw_preemption_mode failed");
1086 goto fail_free_gk20a_ctx;
1087 }
1088 } else
1089 goto fail_free_gk20a_ctx;
1090 }
1091
1092 gk20a_dbg_fn("done");
1093
1094 return 0;
1095
1096fail_free_gk20a_ctx:
1097 gr_gk20a_free_gr_ctx(g, vm, *gr_ctx);
1098 *gr_ctx = NULL;
1099
1100 return err;
1101}
1102
1103static void dump_ctx_switch_stats(struct gk20a *g, struct vm_gk20a *vm,
1104 struct gr_ctx_desc *gr_ctx)
1105{
1106 struct nvgpu_mem *mem = &gr_ctx->mem;
1107
1108 if (nvgpu_mem_begin(g, mem)) {
1109 WARN_ON("Cannot map context");
1110 return;
1111 }
1112 nvgpu_err(g, "ctxsw_prog_main_image_magic_value_o : %x (expect %x)",
1113 nvgpu_mem_rd(g, mem,
1114 ctxsw_prog_main_image_magic_value_o()),
1115 ctxsw_prog_main_image_magic_value_v_value_v());
1116
1117 nvgpu_err(g, "ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi : %x",
1118 nvgpu_mem_rd(g, mem,
1119 ctxsw_prog_main_image_context_timestamp_buffer_ptr_hi_o()));
1120
1121 nvgpu_err(g, "ctxsw_prog_main_image_context_timestamp_buffer_ptr : %x",
1122 nvgpu_mem_rd(g, mem,
1123 ctxsw_prog_main_image_context_timestamp_buffer_ptr_o()));
1124
1125 nvgpu_err(g, "ctxsw_prog_main_image_context_timestamp_buffer_control : %x",
1126 nvgpu_mem_rd(g, mem,
1127 ctxsw_prog_main_image_context_timestamp_buffer_control_o()));
1128
1129 nvgpu_err(g, "NUM_SAVE_OPERATIONS : %d",
1130 nvgpu_mem_rd(g, mem,
1131 ctxsw_prog_main_image_num_save_ops_o()));
1132 nvgpu_err(g, "WFI_SAVE_OPERATIONS : %d",
1133 nvgpu_mem_rd(g, mem,
1134 ctxsw_prog_main_image_num_wfi_save_ops_o()));
1135 nvgpu_err(g, "CTA_SAVE_OPERATIONS : %d",
1136 nvgpu_mem_rd(g, mem,
1137 ctxsw_prog_main_image_num_cta_save_ops_o()));
1138 nvgpu_err(g, "GFXP_SAVE_OPERATIONS : %d",
1139 nvgpu_mem_rd(g, mem,
1140 ctxsw_prog_main_image_num_gfxp_save_ops_o()));
1141 nvgpu_err(g, "CILP_SAVE_OPERATIONS : %d",
1142 nvgpu_mem_rd(g, mem,
1143 ctxsw_prog_main_image_num_cilp_save_ops_o()));
1144 nvgpu_err(g,
1145 "image gfx preemption option (GFXP is 1) %x",
1146 nvgpu_mem_rd(g, mem,
1147 ctxsw_prog_main_image_graphics_preemption_options_o()));
1148 nvgpu_err(g,
1149 "image compute preemption option (CTA is 1) %x",
1150 nvgpu_mem_rd(g, mem,
1151 ctxsw_prog_main_image_compute_preemption_options_o()));
1152 nvgpu_mem_end(g, mem);
1153}
1154
1155void gr_gp10b_free_gr_ctx(struct gk20a *g, struct vm_gk20a *vm,
1156 struct gr_ctx_desc *gr_ctx)
1157{
1158 gk20a_dbg_fn("");
1159
1160 if (!gr_ctx)
1161 return;
1162
1163 if (g->gr.t18x.ctx_vars.dump_ctxsw_stats_on_channel_close)
1164 dump_ctx_switch_stats(g, vm, gr_ctx);
1165
1166 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.pagepool_ctxsw_buffer);
1167 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.betacb_ctxsw_buffer);
1168 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.spill_ctxsw_buffer);
1169 nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.preempt_ctxsw_buffer);
1170 gr_gk20a_free_gr_ctx(g, vm, gr_ctx);
1171 gk20a_dbg_fn("done");
1172}
1173
1174
1175void gr_gp10b_update_ctxsw_preemption_mode(struct gk20a *g,
1176 struct channel_ctx_gk20a *ch_ctx,
1177 struct nvgpu_mem *mem)
1178{
1179 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
1180 struct ctx_header_desc *ctx = &ch_ctx->ctx_header;
1181 struct nvgpu_mem *ctxheader = &ctx->mem;
1182
1183 u32 gfxp_preempt_option =
1184 ctxsw_prog_main_image_graphics_preemption_options_control_gfxp_f();
1185 u32 cilp_preempt_option =
1186 ctxsw_prog_main_image_compute_preemption_options_control_cilp_f();
1187 u32 cta_preempt_option =
1188 ctxsw_prog_main_image_compute_preemption_options_control_cta_f();
1189 int err;
1190
1191 gk20a_dbg_fn("");
1192
1193 if (gr_ctx->graphics_preempt_mode == NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP) {
1194 gk20a_dbg_info("GfxP: %x", gfxp_preempt_option);
1195 nvgpu_mem_wr(g, mem,
1196 ctxsw_prog_main_image_graphics_preemption_options_o(),
1197 gfxp_preempt_option);
1198 }
1199
1200 if (gr_ctx->compute_preempt_mode == NVGPU_PREEMPTION_MODE_COMPUTE_CILP) {
1201 gk20a_dbg_info("CILP: %x", cilp_preempt_option);
1202 nvgpu_mem_wr(g, mem,
1203 ctxsw_prog_main_image_compute_preemption_options_o(),
1204 cilp_preempt_option);
1205 }
1206
1207 if (gr_ctx->compute_preempt_mode == NVGPU_PREEMPTION_MODE_COMPUTE_CTA) {
1208 gk20a_dbg_info("CTA: %x", cta_preempt_option);
1209 nvgpu_mem_wr(g, mem,
1210 ctxsw_prog_main_image_compute_preemption_options_o(),
1211 cta_preempt_option);
1212 }
1213
1214 if (gr_ctx->t18x.preempt_ctxsw_buffer.gpu_va) {
1215 u32 addr;
1216 u32 size;
1217 u32 cbes_reserve;
1218
1219 if (g->ops.gr.set_preemption_buffer_va) {
1220 if (ctxheader->gpu_va)
1221 g->ops.gr.set_preemption_buffer_va(g, ctxheader,
1222 gr_ctx->t18x.preempt_ctxsw_buffer.gpu_va);
1223 else
1224 g->ops.gr.set_preemption_buffer_va(g, mem,
1225 gr_ctx->t18x.preempt_ctxsw_buffer.gpu_va);
1226 }
1227
1228 err = gr_gk20a_ctx_patch_write_begin(g, ch_ctx, true);
1229 if (err) {
1230 nvgpu_err(g, "can't map patch context");
1231 goto out;
1232 }
1233
1234 addr = (u64_lo32(gr_ctx->t18x.betacb_ctxsw_buffer.gpu_va) >>
1235 gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v()) |
1236 (u64_hi32(gr_ctx->t18x.betacb_ctxsw_buffer.gpu_va) <<
1237 (32 - gr_gpcs_setup_attrib_cb_base_addr_39_12_align_bits_v()));
1238
1239 gk20a_dbg_info("attrib cb addr : 0x%016x", addr);
1240 g->ops.gr.commit_global_attrib_cb(g, ch_ctx, addr, true);
1241
1242 addr = (u64_lo32(gr_ctx->t18x.pagepool_ctxsw_buffer.gpu_va) >>
1243 gr_scc_pagepool_base_addr_39_8_align_bits_v()) |
1244 (u64_hi32(gr_ctx->t18x.pagepool_ctxsw_buffer.gpu_va) <<
1245 (32 - gr_scc_pagepool_base_addr_39_8_align_bits_v()));
1246 size = gr_ctx->t18x.pagepool_ctxsw_buffer.size;
1247
1248 if (size == g->ops.gr.pagepool_default_size(g))
1249 size = gr_scc_pagepool_total_pages_hwmax_v();
1250
1251 g->ops.gr.commit_global_pagepool(g, ch_ctx, addr, size, true);
1252
1253 addr = (u64_lo32(gr_ctx->t18x.spill_ctxsw_buffer.gpu_va) >>
1254 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_align_bits_v()) |
1255 (u64_hi32(gr_ctx->t18x.spill_ctxsw_buffer.gpu_va) <<
1256 (32 - gr_gpc0_swdx_rm_spill_buffer_addr_39_8_align_bits_v()));
1257 size = gr_ctx->t18x.spill_ctxsw_buffer.size /
1258 gr_gpc0_swdx_rm_spill_buffer_size_256b_byte_granularity_v();
1259
1260 gr_gk20a_ctx_patch_write(g, ch_ctx,
1261 gr_gpc0_swdx_rm_spill_buffer_addr_r(),
1262 gr_gpc0_swdx_rm_spill_buffer_addr_39_8_f(addr),
1263 true);
1264 gr_gk20a_ctx_patch_write(g, ch_ctx,
1265 gr_gpc0_swdx_rm_spill_buffer_size_r(),
1266 gr_gpc0_swdx_rm_spill_buffer_size_256b_f(size),
1267 true);
1268
1269 cbes_reserve = gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_gfxp_v();
1270 gr_gk20a_ctx_patch_write(g, ch_ctx,
1271 gr_gpcs_swdx_beta_cb_ctrl_r(),
1272 gr_gpcs_swdx_beta_cb_ctrl_cbes_reserve_f(
1273 cbes_reserve),
1274 true);
1275 gr_gk20a_ctx_patch_write(g, ch_ctx,
1276 gr_gpcs_ppcs_cbm_beta_cb_ctrl_r(),
1277 gr_gpcs_ppcs_cbm_beta_cb_ctrl_cbes_reserve_f(
1278 cbes_reserve),
1279 true);
1280
1281 gr_gk20a_ctx_patch_write_end(g, ch_ctx, true);
1282 }
1283
1284out:
1285 gk20a_dbg_fn("done");
1286}
1287
1288int gr_gp10b_dump_gr_status_regs(struct gk20a *g,
1289 struct gk20a_debug_output *o)
1290{
1291 struct gr_gk20a *gr = &g->gr;
1292 u32 gr_engine_id;
1293
1294 gr_engine_id = gk20a_fifo_get_gr_engine_id(g);
1295
1296 gk20a_debug_output(o, "NV_PGRAPH_STATUS: 0x%x\n",
1297 gk20a_readl(g, gr_status_r()));
1298 gk20a_debug_output(o, "NV_PGRAPH_STATUS1: 0x%x\n",
1299 gk20a_readl(g, gr_status_1_r()));
1300 gk20a_debug_output(o, "NV_PGRAPH_STATUS2: 0x%x\n",
1301 gk20a_readl(g, gr_status_2_r()));
1302 gk20a_debug_output(o, "NV_PGRAPH_ENGINE_STATUS: 0x%x\n",
1303 gk20a_readl(g, gr_engine_status_r()));
1304 gk20a_debug_output(o, "NV_PGRAPH_GRFIFO_STATUS : 0x%x\n",
1305 gk20a_readl(g, gr_gpfifo_status_r()));
1306 gk20a_debug_output(o, "NV_PGRAPH_GRFIFO_CONTROL : 0x%x\n",
1307 gk20a_readl(g, gr_gpfifo_ctl_r()));
1308 gk20a_debug_output(o, "NV_PGRAPH_PRI_FECS_HOST_INT_STATUS : 0x%x\n",
1309 gk20a_readl(g, gr_fecs_host_int_status_r()));
1310 gk20a_debug_output(o, "NV_PGRAPH_EXCEPTION : 0x%x\n",
1311 gk20a_readl(g, gr_exception_r()));
1312 gk20a_debug_output(o, "NV_PGRAPH_FECS_INTR : 0x%x\n",
1313 gk20a_readl(g, gr_fecs_intr_r()));
1314 gk20a_debug_output(o, "NV_PFIFO_ENGINE_STATUS(GR) : 0x%x\n",
1315 gk20a_readl(g, fifo_engine_status_r(gr_engine_id)));
1316 gk20a_debug_output(o, "NV_PGRAPH_ACTIVITY0: 0x%x\n",
1317 gk20a_readl(g, gr_activity_0_r()));
1318 gk20a_debug_output(o, "NV_PGRAPH_ACTIVITY1: 0x%x\n",
1319 gk20a_readl(g, gr_activity_1_r()));
1320 gk20a_debug_output(o, "NV_PGRAPH_ACTIVITY2: 0x%x\n",
1321 gk20a_readl(g, gr_activity_2_r()));
1322 gk20a_debug_output(o, "NV_PGRAPH_ACTIVITY4: 0x%x\n",
1323 gk20a_readl(g, gr_activity_4_r()));
1324 gk20a_debug_output(o, "NV_PGRAPH_PRI_SKED_ACTIVITY: 0x%x\n",
1325 gk20a_readl(g, gr_pri_sked_activity_r()));
1326 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_GPC_ACTIVITY0: 0x%x\n",
1327 gk20a_readl(g, gr_pri_gpc0_gpccs_gpc_activity0_r()));
1328 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_GPC_ACTIVITY1: 0x%x\n",
1329 gk20a_readl(g, gr_pri_gpc0_gpccs_gpc_activity1_r()));
1330 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_GPC_ACTIVITY2: 0x%x\n",
1331 gk20a_readl(g, gr_pri_gpc0_gpccs_gpc_activity2_r()));
1332 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_GPC_ACTIVITY3: 0x%x\n",
1333 gk20a_readl(g, gr_pri_gpc0_gpccs_gpc_activity3_r()));
1334 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_TPC0_TPCCS_TPC_ACTIVITY0: 0x%x\n",
1335 gk20a_readl(g, gr_pri_gpc0_tpc0_tpccs_tpc_activity_0_r()));
1336 if (gr->gpc_tpc_count && gr->gpc_tpc_count[0] == 2)
1337 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_TPC1_TPCCS_TPC_ACTIVITY0: 0x%x\n",
1338 gk20a_readl(g, gr_pri_gpc0_tpc1_tpccs_tpc_activity_0_r()));
1339 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_TPCS_TPCCS_TPC_ACTIVITY0: 0x%x\n",
1340 gk20a_readl(g, gr_pri_gpc0_tpcs_tpccs_tpc_activity_0_r()));
1341 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_GPCCS_GPC_ACTIVITY0: 0x%x\n",
1342 gk20a_readl(g, gr_pri_gpcs_gpccs_gpc_activity_0_r()));
1343 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_GPCCS_GPC_ACTIVITY1: 0x%x\n",
1344 gk20a_readl(g, gr_pri_gpcs_gpccs_gpc_activity_1_r()));
1345 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_GPCCS_GPC_ACTIVITY2: 0x%x\n",
1346 gk20a_readl(g, gr_pri_gpcs_gpccs_gpc_activity_2_r()));
1347 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_GPCCS_GPC_ACTIVITY3: 0x%x\n",
1348 gk20a_readl(g, gr_pri_gpcs_gpccs_gpc_activity_3_r()));
1349 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_TPC0_TPCCS_TPC_ACTIVITY0: 0x%x\n",
1350 gk20a_readl(g, gr_pri_gpcs_tpc0_tpccs_tpc_activity_0_r()));
1351 if (gr->gpc_tpc_count && gr->gpc_tpc_count[0] == 2)
1352 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_TPC1_TPCCS_TPC_ACTIVITY0: 0x%x\n",
1353 gk20a_readl(g, gr_pri_gpcs_tpc1_tpccs_tpc_activity_0_r()));
1354 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPCS_TPCS_TPCCS_TPC_ACTIVITY0: 0x%x\n",
1355 gk20a_readl(g, gr_pri_gpcs_tpcs_tpccs_tpc_activity_0_r()));
1356 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE0_BECS_BE_ACTIVITY0: 0x%x\n",
1357 gk20a_readl(g, gr_pri_be0_becs_be_activity0_r()));
1358 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE1_BECS_BE_ACTIVITY0: 0x%x\n",
1359 gk20a_readl(g, gr_pri_be1_becs_be_activity0_r()));
1360 gk20a_debug_output(o, "NV_PGRAPH_PRI_BES_BECS_BE_ACTIVITY0: 0x%x\n",
1361 gk20a_readl(g, gr_pri_bes_becs_be_activity0_r()));
1362 gk20a_debug_output(o, "NV_PGRAPH_PRI_DS_MPIPE_STATUS: 0x%x\n",
1363 gk20a_readl(g, gr_pri_ds_mpipe_status_r()));
1364 gk20a_debug_output(o, "NV_PGRAPH_PRI_FE_GO_IDLE_TIMEOUT : 0x%x\n",
1365 gk20a_readl(g, gr_fe_go_idle_timeout_r()));
1366 gk20a_debug_output(o, "NV_PGRAPH_PRI_FE_GO_IDLE_INFO : 0x%x\n",
1367 gk20a_readl(g, gr_pri_fe_go_idle_info_r()));
1368 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_TPC0_TEX_M_TEX_SUBUNITS_STATUS: 0x%x\n",
1369 gk20a_readl(g, gr_pri_gpc0_tpc0_tex_m_tex_subunits_status_r()));
1370 gk20a_debug_output(o, "NV_PGRAPH_PRI_CWD_FS: 0x%x\n",
1371 gk20a_readl(g, gr_cwd_fs_r()));
1372 gk20a_debug_output(o, "NV_PGRAPH_PRI_FE_TPC_FS: 0x%x\n",
1373 gk20a_readl(g, gr_fe_tpc_fs_r()));
1374 gk20a_debug_output(o, "NV_PGRAPH_PRI_CWD_GPC_TPC_ID(0): 0x%x\n",
1375 gk20a_readl(g, gr_cwd_gpc_tpc_id_r(0)));
1376 gk20a_debug_output(o, "NV_PGRAPH_PRI_CWD_SM_ID(0): 0x%x\n",
1377 gk20a_readl(g, gr_cwd_sm_id_r(0)));
1378 gk20a_debug_output(o, "NV_PGRAPH_PRI_FECS_CTXSW_STATUS_FE_0: 0x%x\n",
1379 gk20a_readl(g, gr_fecs_ctxsw_status_fe_0_r()));
1380 gk20a_debug_output(o, "NV_PGRAPH_PRI_FECS_CTXSW_STATUS_1: 0x%x\n",
1381 gk20a_readl(g, gr_fecs_ctxsw_status_1_r()));
1382 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_CTXSW_STATUS_GPC_0: 0x%x\n",
1383 gk20a_readl(g, gr_gpc0_gpccs_ctxsw_status_gpc_0_r()));
1384 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_CTXSW_STATUS_1: 0x%x\n",
1385 gk20a_readl(g, gr_gpc0_gpccs_ctxsw_status_1_r()));
1386 gk20a_debug_output(o, "NV_PGRAPH_PRI_FECS_CTXSW_IDLESTATE : 0x%x\n",
1387 gk20a_readl(g, gr_fecs_ctxsw_idlestate_r()));
1388 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_CTXSW_IDLESTATE : 0x%x\n",
1389 gk20a_readl(g, gr_gpc0_gpccs_ctxsw_idlestate_r()));
1390 gk20a_debug_output(o, "NV_PGRAPH_PRI_FECS_CURRENT_CTX : 0x%x\n",
1391 gk20a_readl(g, gr_fecs_current_ctx_r()));
1392 gk20a_debug_output(o, "NV_PGRAPH_PRI_FECS_NEW_CTX : 0x%x\n",
1393 gk20a_readl(g, gr_fecs_new_ctx_r()));
1394 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE0_CROP_STATUS1 : 0x%x\n",
1395 gk20a_readl(g, gr_pri_be0_crop_status1_r()));
1396 gk20a_debug_output(o, "NV_PGRAPH_PRI_BES_CROP_STATUS1 : 0x%x\n",
1397 gk20a_readl(g, gr_pri_bes_crop_status1_r()));
1398 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE0_ZROP_STATUS : 0x%x\n",
1399 gk20a_readl(g, gr_pri_be0_zrop_status_r()));
1400 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE0_ZROP_STATUS2 : 0x%x\n",
1401 gk20a_readl(g, gr_pri_be0_zrop_status2_r()));
1402 gk20a_debug_output(o, "NV_PGRAPH_PRI_BES_ZROP_STATUS : 0x%x\n",
1403 gk20a_readl(g, gr_pri_bes_zrop_status_r()));
1404 gk20a_debug_output(o, "NV_PGRAPH_PRI_BES_ZROP_STATUS2 : 0x%x\n",
1405 gk20a_readl(g, gr_pri_bes_zrop_status2_r()));
1406 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE0_BECS_BE_EXCEPTION: 0x%x\n",
1407 gk20a_readl(g, gr_pri_be0_becs_be_exception_r()));
1408 gk20a_debug_output(o, "NV_PGRAPH_PRI_BE0_BECS_BE_EXCEPTION_EN: 0x%x\n",
1409 gk20a_readl(g, gr_pri_be0_becs_be_exception_en_r()));
1410 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_GPC_EXCEPTION: 0x%x\n",
1411 gk20a_readl(g, gr_pri_gpc0_gpccs_gpc_exception_r()));
1412 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_GPCCS_GPC_EXCEPTION_EN: 0x%x\n",
1413 gk20a_readl(g, gr_pri_gpc0_gpccs_gpc_exception_en_r()));
1414 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_TPC0_TPCCS_TPC_EXCEPTION: 0x%x\n",
1415 gk20a_readl(g, gr_pri_gpc0_tpc0_tpccs_tpc_exception_r()));
1416 gk20a_debug_output(o, "NV_PGRAPH_PRI_GPC0_TPC0_TPCCS_TPC_EXCEPTION_EN: 0x%x\n",
1417 gk20a_readl(g, gr_pri_gpc0_tpc0_tpccs_tpc_exception_en_r()));
1418 return 0;
1419}
1420
1421static bool gr_activity_empty_or_preempted(u32 val)
1422{
1423 while(val) {
1424 u32 v = val & 7;
1425 if (v != gr_activity_4_gpc0_empty_v() &&
1426 v != gr_activity_4_gpc0_preempted_v())
1427 return false;
1428 val >>= 3;
1429 }
1430
1431 return true;
1432}
1433
1434int gr_gp10b_wait_empty(struct gk20a *g, unsigned long duration_ms,
1435 u32 expect_delay)
1436{
1437 u32 delay = expect_delay;
1438 bool gr_enabled;
1439 bool ctxsw_active;
1440 bool gr_busy;
1441 u32 gr_status;
1442 u32 activity0, activity1, activity2, activity4;
1443 struct nvgpu_timeout timeout;
1444
1445 gk20a_dbg_fn("");
1446
1447 nvgpu_timeout_init(g, &timeout, duration_ms, NVGPU_TIMER_CPU_TIMER);
1448
1449 do {
1450 /* fmodel: host gets fifo_engine_status(gr) from gr
1451 only when gr_status is read */
1452 gr_status = gk20a_readl(g, gr_status_r());
1453
1454 gr_enabled = gk20a_readl(g, mc_enable_r()) &
1455 mc_enable_pgraph_enabled_f();
1456
1457 ctxsw_active = gr_status & 1<<7;
1458
1459 activity0 = gk20a_readl(g, gr_activity_0_r());
1460 activity1 = gk20a_readl(g, gr_activity_1_r());
1461 activity2 = gk20a_readl(g, gr_activity_2_r());
1462 activity4 = gk20a_readl(g, gr_activity_4_r());
1463
1464 gr_busy = !(gr_activity_empty_or_preempted(activity0) &&
1465 gr_activity_empty_or_preempted(activity1) &&
1466 activity2 == 0 &&
1467 gr_activity_empty_or_preempted(activity4));
1468
1469 if (!gr_enabled || (!gr_busy && !ctxsw_active)) {
1470 gk20a_dbg_fn("done");
1471 return 0;
1472 }
1473
1474 nvgpu_usleep_range(delay, delay * 2);
1475 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
1476 } while (!nvgpu_timeout_expired(&timeout));
1477
1478 nvgpu_err(g,
1479 "timeout, ctxsw busy : %d, gr busy : %d, %08x, %08x, %08x, %08x",
1480 ctxsw_active, gr_busy, activity0, activity1, activity2, activity4);
1481
1482 return -EAGAIN;
1483}
1484
1485void gr_gp10b_commit_global_attrib_cb(struct gk20a *g,
1486 struct channel_ctx_gk20a *ch_ctx,
1487 u64 addr, bool patch)
1488{
1489 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
1490 int attrBufferSize;
1491
1492 if (gr_ctx->t18x.preempt_ctxsw_buffer.gpu_va)
1493 attrBufferSize = gr_ctx->t18x.betacb_ctxsw_buffer.size;
1494 else
1495 attrBufferSize = g->ops.gr.calc_global_ctx_buffer_size(g);
1496
1497 attrBufferSize /= gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_granularity_f();
1498
1499 gr_gm20b_commit_global_attrib_cb(g, ch_ctx, addr, patch);
1500
1501 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_r(),
1502 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_v_f(addr) |
1503 gr_gpcs_tpcs_mpc_vtg_cb_global_base_addr_valid_true_f(), patch);
1504
1505 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_tpcs_tex_rm_cb_0_r(),
1506 gr_gpcs_tpcs_tex_rm_cb_0_base_addr_43_12_f(addr), patch);
1507
1508 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_tpcs_tex_rm_cb_1_r(),
1509 gr_gpcs_tpcs_tex_rm_cb_1_size_div_128b_f(attrBufferSize) |
1510 gr_gpcs_tpcs_tex_rm_cb_1_valid_true_f(), patch);
1511}
1512
1513void gr_gp10b_commit_global_bundle_cb(struct gk20a *g,
1514 struct channel_ctx_gk20a *ch_ctx,
1515 u64 addr, u64 size, bool patch)
1516{
1517 u32 data;
1518
1519 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_scc_bundle_cb_base_r(),
1520 gr_scc_bundle_cb_base_addr_39_8_f(addr), patch);
1521
1522 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_scc_bundle_cb_size_r(),
1523 gr_scc_bundle_cb_size_div_256b_f(size) |
1524 gr_scc_bundle_cb_size_valid_true_f(), patch);
1525
1526 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_swdx_bundle_cb_base_r(),
1527 gr_gpcs_swdx_bundle_cb_base_addr_39_8_f(addr), patch);
1528
1529 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_gpcs_swdx_bundle_cb_size_r(),
1530 gr_gpcs_swdx_bundle_cb_size_div_256b_f(size) |
1531 gr_gpcs_swdx_bundle_cb_size_valid_true_f(), patch);
1532
1533 /* data for state_limit */
1534 data = (g->gr.bundle_cb_default_size *
1535 gr_scc_bundle_cb_size_div_256b_byte_granularity_v()) /
1536 gr_pd_ab_dist_cfg2_state_limit_scc_bundle_granularity_v();
1537
1538 data = min_t(u32, data, g->gr.min_gpm_fifo_depth);
1539
1540 gk20a_dbg_info("bundle cb token limit : %d, state limit : %d",
1541 g->gr.bundle_cb_token_limit, data);
1542
1543 gr_gk20a_ctx_patch_write(g, ch_ctx, gr_pd_ab_dist_cfg2_r(),
1544 gr_pd_ab_dist_cfg2_token_limit_f(g->gr.bundle_cb_token_limit) |
1545 gr_pd_ab_dist_cfg2_state_limit_f(data), patch);
1546}
1547
1548int gr_gp10b_load_smid_config(struct gk20a *g)
1549{
1550 u32 *tpc_sm_id;
1551 u32 i, j;
1552 u32 tpc_index, gpc_index;
1553 u32 max_gpcs = nvgpu_get_litter_value(g, GPU_LIT_NUM_GPCS);
1554
1555 tpc_sm_id = nvgpu_kcalloc(g, gr_cwd_sm_id__size_1_v(), sizeof(u32));
1556 if (!tpc_sm_id)
1557 return -ENOMEM;
1558
1559 /* Each NV_PGRAPH_PRI_CWD_GPC_TPC_ID can store 4 TPCs.*/
1560 for (i = 0; i <= ((g->gr.tpc_count-1) / 4); i++) {
1561 u32 reg = 0;
1562 u32 bit_stride = gr_cwd_gpc_tpc_id_gpc0_s() +
1563 gr_cwd_gpc_tpc_id_tpc0_s();
1564
1565 for (j = 0; j < 4; j++) {
1566 u32 sm_id = (i * 4) + j;
1567 u32 bits;
1568
1569 if (sm_id >= g->gr.tpc_count)
1570 break;
1571
1572 gpc_index = g->gr.sm_to_cluster[sm_id].gpc_index;
1573 tpc_index = g->gr.sm_to_cluster[sm_id].tpc_index;
1574
1575 bits = gr_cwd_gpc_tpc_id_gpc0_f(gpc_index) |
1576 gr_cwd_gpc_tpc_id_tpc0_f(tpc_index);
1577 reg |= bits << (j * bit_stride);
1578
1579 tpc_sm_id[gpc_index + max_gpcs * ((tpc_index & 4) >> 2)]
1580 |= sm_id << (bit_stride * (tpc_index & 3));
1581 }
1582 gk20a_writel(g, gr_cwd_gpc_tpc_id_r(i), reg);
1583 }
1584
1585 for (i = 0; i < gr_cwd_sm_id__size_1_v(); i++)
1586 gk20a_writel(g, gr_cwd_sm_id_r(i), tpc_sm_id[i]);
1587
1588 nvgpu_kfree(g, tpc_sm_id);
1589
1590 return 0;
1591}
1592
1593int gr_gp10b_init_fs_state(struct gk20a *g)
1594{
1595 u32 data;
1596
1597 gk20a_dbg_fn("");
1598
1599 data = gk20a_readl(g, gr_gpcs_tpcs_sm_texio_control_r());
1600 data = set_field(data, gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_m(),
1601 gr_gpcs_tpcs_sm_texio_control_oor_addr_check_mode_arm_63_48_match_f());
1602 gk20a_writel(g, gr_gpcs_tpcs_sm_texio_control_r(), data);
1603
1604 data = gk20a_readl(g, gr_gpcs_tpcs_sm_disp_ctrl_r());
1605 data = set_field(data, gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_m(),
1606 gr_gpcs_tpcs_sm_disp_ctrl_re_suppress_disable_f());
1607 gk20a_writel(g, gr_gpcs_tpcs_sm_disp_ctrl_r(), data);
1608
1609 if (g->gr.t18x.fecs_feature_override_ecc_val != 0) {
1610 gk20a_writel(g,
1611 gr_fecs_feature_override_ecc_r(),
1612 g->gr.t18x.fecs_feature_override_ecc_val);
1613 }
1614
1615 return gr_gm20b_init_fs_state(g);
1616}
1617
1618void gr_gp10b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index)
1619{
1620 nvgpu_tegra_fuse_write_bypass(g, 0x1);
1621 nvgpu_tegra_fuse_write_access_sw(g, 0x0);
1622
1623 if (g->gr.gpc_tpc_mask[gpc_index] == 0x1)
1624 nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(g, 0x2);
1625 else if (g->gr.gpc_tpc_mask[gpc_index] == 0x2)
1626 nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(g, 0x1);
1627 else
1628 nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(g, 0x0);
1629}
1630
1631void gr_gp10b_get_access_map(struct gk20a *g,
1632 u32 **whitelist, int *num_entries)
1633{
1634 static u32 wl_addr_gp10b[] = {
1635 /* this list must be sorted (low to high) */
1636 0x404468, /* gr_pri_mme_max_instructions */
1637 0x418300, /* gr_pri_gpcs_rasterarb_line_class */
1638 0x418800, /* gr_pri_gpcs_setup_debug */
1639 0x418e00, /* gr_pri_gpcs_swdx_config */
1640 0x418e40, /* gr_pri_gpcs_swdx_tc_bundle_ctrl */
1641 0x418e44, /* gr_pri_gpcs_swdx_tc_bundle_ctrl */
1642 0x418e48, /* gr_pri_gpcs_swdx_tc_bundle_ctrl */
1643 0x418e4c, /* gr_pri_gpcs_swdx_tc_bundle_ctrl */
1644 0x418e50, /* gr_pri_gpcs_swdx_tc_bundle_ctrl */
1645 0x418e58, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1646 0x418e5c, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1647 0x418e60, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1648 0x418e64, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1649 0x418e68, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1650 0x418e6c, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1651 0x418e70, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1652 0x418e74, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1653 0x418e78, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1654 0x418e7c, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1655 0x418e80, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1656 0x418e84, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1657 0x418e88, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1658 0x418e8c, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1659 0x418e90, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1660 0x418e94, /* gr_pri_gpcs_swdx_tc_bundle_addr */
1661 0x419864, /* gr_pri_gpcs_tpcs_pe_l2_evict_policy */
1662 0x419a04, /* gr_pri_gpcs_tpcs_tex_lod_dbg */
1663 0x419a08, /* gr_pri_gpcs_tpcs_tex_samp_dbg */
1664 0x419e10, /* gr_pri_gpcs_tpcs_sm_dbgr_control0 */
1665 0x419f78, /* gr_pri_gpcs_tpcs_sm_disp_ctrl */
1666 };
1667
1668 *whitelist = wl_addr_gp10b;
1669 *num_entries = ARRAY_SIZE(wl_addr_gp10b);
1670}
1671
1672static int gr_gp10b_disable_channel_or_tsg(struct gk20a *g, struct channel_gk20a *fault_ch)
1673{
1674 int ret = 0;
1675
1676 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, "");
1677
1678 ret = gk20a_disable_channel_tsg(g, fault_ch);
1679 if (ret) {
1680 nvgpu_err(g,
1681 "CILP: failed to disable channel/TSG!");
1682 return ret;
1683 }
1684
1685 ret = g->ops.fifo.update_runlist(g, fault_ch->runlist_id, ~0, true, false);
1686 if (ret) {
1687 nvgpu_err(g,
1688 "CILP: failed to restart runlist 0!");
1689 return ret;
1690 }
1691
1692 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, "CILP: restarted runlist");
1693
1694 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1695 "CILP: tsgid: 0x%x", fault_ch->tsgid);
1696
1697 if (gk20a_is_channel_marked_as_tsg(fault_ch)) {
1698 gk20a_fifo_issue_preempt(g, fault_ch->tsgid, true);
1699 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1700 "CILP: preempted tsg");
1701 } else {
1702 gk20a_fifo_issue_preempt(g, fault_ch->chid, false);
1703 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1704 "CILP: preempted channel");
1705 }
1706
1707 return ret;
1708}
1709
1710int gr_gp10b_set_cilp_preempt_pending(struct gk20a *g,
1711 struct channel_gk20a *fault_ch)
1712{
1713 int ret;
1714 struct gr_ctx_desc *gr_ctx = fault_ch->ch_ctx.gr_ctx;
1715
1716 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, "");
1717
1718 if (!gr_ctx)
1719 return -EINVAL;
1720
1721 if (gr_ctx->t18x.cilp_preempt_pending) {
1722 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1723 "CILP is already pending for chid %d",
1724 fault_ch->chid);
1725 return 0;
1726 }
1727
1728 /* get ctx_id from the ucode image */
1729 if (!gr_ctx->t18x.ctx_id_valid) {
1730 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1731 "CILP: looking up ctx id");
1732 ret = gr_gk20a_get_ctx_id(g, fault_ch, &gr_ctx->t18x.ctx_id);
1733 if (ret) {
1734 nvgpu_err(g, "CILP: error looking up ctx id!");
1735 return ret;
1736 }
1737 gr_ctx->t18x.ctx_id_valid = true;
1738 }
1739
1740 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1741 "CILP: ctx id is 0x%x", gr_ctx->t18x.ctx_id);
1742
1743 /* send ucode method to set ctxsw interrupt */
1744 ret = gr_gk20a_submit_fecs_sideband_method_op(g,
1745 (struct fecs_method_op_gk20a) {
1746 .method.data = gr_ctx->t18x.ctx_id,
1747 .method.addr =
1748 gr_fecs_method_push_adr_configure_interrupt_completion_option_v(),
1749 .mailbox = {
1750 .id = 1 /* sideband */, .data = 0,
1751 .clr = ~0, .ret = NULL,
1752 .ok = gr_fecs_ctxsw_mailbox_value_pass_v(),
1753 .fail = 0},
1754 .cond.ok = GR_IS_UCODE_OP_EQUAL,
1755 .cond.fail = GR_IS_UCODE_OP_SKIP});
1756
1757 if (ret) {
1758 nvgpu_err(g, "CILP: failed to enable ctxsw interrupt!");
1759 return ret;
1760 }
1761
1762 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1763 "CILP: enabled ctxsw completion interrupt");
1764
1765 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1766 "CILP: disabling channel %d",
1767 fault_ch->chid);
1768
1769 ret = gr_gp10b_disable_channel_or_tsg(g, fault_ch);
1770 if (ret) {
1771 nvgpu_err(g, "CILP: failed to disable channel!!");
1772 return ret;
1773 }
1774
1775 /* set cilp_preempt_pending = true and record the channel */
1776 gr_ctx->t18x.cilp_preempt_pending = true;
1777 g->gr.t18x.cilp_preempt_pending_chid = fault_ch->chid;
1778
1779 if (gk20a_is_channel_marked_as_tsg(fault_ch)) {
1780 struct tsg_gk20a *tsg = &g->fifo.tsg[fault_ch->tsgid];
1781
1782 gk20a_tsg_event_id_post_event(tsg,
1783 NVGPU_EVENT_ID_CILP_PREEMPTION_STARTED);
1784 } else {
1785 gk20a_channel_event_id_post_event(fault_ch,
1786 NVGPU_EVENT_ID_CILP_PREEMPTION_STARTED);
1787 }
1788
1789 return 0;
1790}
1791
1792static int gr_gp10b_clear_cilp_preempt_pending(struct gk20a *g,
1793 struct channel_gk20a *fault_ch)
1794{
1795 struct gr_ctx_desc *gr_ctx = fault_ch->ch_ctx.gr_ctx;
1796
1797 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, "");
1798
1799 if (!gr_ctx)
1800 return -EINVAL;
1801
1802 /* The ucode is self-clearing, so all we need to do here is
1803 to clear cilp_preempt_pending. */
1804 if (!gr_ctx->t18x.cilp_preempt_pending) {
1805 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1806 "CILP is already cleared for chid %d\n",
1807 fault_ch->chid);
1808 return 0;
1809 }
1810
1811 gr_ctx->t18x.cilp_preempt_pending = false;
1812 g->gr.t18x.cilp_preempt_pending_chid = -1;
1813
1814 return 0;
1815}
1816
1817/* @brief pre-process work on the SM exceptions to determine if we clear them or not.
1818 *
1819 * On Pascal, if we are in CILP preemtion mode, preempt the channel and handle errors with special processing
1820 */
1821int gr_gp10b_pre_process_sm_exception(struct gk20a *g,
1822 u32 gpc, u32 tpc, u32 sm, u32 global_esr, u32 warp_esr,
1823 bool sm_debugger_attached, struct channel_gk20a *fault_ch,
1824 bool *early_exit, bool *ignore_debugger)
1825{
1826 int ret;
1827 bool cilp_enabled = false;
1828 u32 global_mask = 0, dbgr_control0, global_esr_copy;
1829 u32 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
1830 u32 tpc_in_gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_TPC_IN_GPC_STRIDE);
1831 u32 offset = gpc_stride * gpc + tpc_in_gpc_stride * tpc;
1832
1833 *early_exit = false;
1834 *ignore_debugger = false;
1835
1836 if (fault_ch)
1837 cilp_enabled = (fault_ch->ch_ctx.gr_ctx->compute_preempt_mode ==
1838 NVGPU_PREEMPTION_MODE_COMPUTE_CILP);
1839
1840 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, "SM Exception received on gpc %d tpc %d = %u\n",
1841 gpc, tpc, global_esr);
1842
1843 if (cilp_enabled && sm_debugger_attached) {
1844 if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f())
1845 gk20a_writel(g, gr_gpc0_tpc0_sm_hww_global_esr_r() + offset,
1846 gr_gpc0_tpc0_sm_hww_global_esr_bpt_int_pending_f());
1847
1848 if (global_esr & gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f())
1849 gk20a_writel(g, gr_gpc0_tpc0_sm_hww_global_esr_r() + offset,
1850 gr_gpc0_tpc0_sm_hww_global_esr_single_step_complete_pending_f());
1851
1852 global_mask = gr_gpc0_tpc0_sm_hww_global_esr_sm_to_sm_fault_pending_f() |
1853 gr_gpcs_tpcs_sm_hww_global_esr_l1_error_pending_f() |
1854 gr_gpcs_tpcs_sm_hww_global_esr_multiple_warp_errors_pending_f() |
1855 gr_gpcs_tpcs_sm_hww_global_esr_physical_stack_overflow_error_pending_f() |
1856 gr_gpcs_tpcs_sm_hww_global_esr_timeout_error_pending_f() |
1857 gr_gpcs_tpcs_sm_hww_global_esr_bpt_pause_pending_f();
1858
1859 if (warp_esr != 0 || (global_esr & global_mask) != 0) {
1860 *ignore_debugger = true;
1861
1862 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg,
1863 "CILP: starting wait for LOCKED_DOWN on gpc %d tpc %d\n",
1864 gpc, tpc);
1865
1866 if (gk20a_dbg_gpu_broadcast_stop_trigger(fault_ch)) {
1867 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg,
1868 "CILP: Broadcasting STOP_TRIGGER from gpc %d tpc %d\n",
1869 gpc, tpc);
1870 g->ops.gr.suspend_all_sms(g, global_mask, false);
1871
1872 gk20a_dbg_gpu_clear_broadcast_stop_trigger(fault_ch);
1873 } else {
1874 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg,
1875 "CILP: STOP_TRIGGER from gpc %d tpc %d\n",
1876 gpc, tpc);
1877 g->ops.gr.suspend_single_sm(g, gpc, tpc, sm, global_mask, true);
1878 }
1879
1880 /* reset the HWW errors after locking down */
1881 global_esr_copy = g->ops.gr.get_sm_hww_global_esr(g,
1882 gpc, tpc, sm);
1883 g->ops.gr.clear_sm_hww(g,
1884 gpc, tpc, sm, global_esr_copy);
1885 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg,
1886 "CILP: HWWs cleared for gpc %d tpc %d\n",
1887 gpc, tpc);
1888
1889 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, "CILP: Setting CILP preempt pending\n");
1890 ret = gr_gp10b_set_cilp_preempt_pending(g, fault_ch);
1891 if (ret) {
1892 nvgpu_err(g, "CILP: error while setting CILP preempt pending!");
1893 return ret;
1894 }
1895
1896 dbgr_control0 = gk20a_readl(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset);
1897 if (dbgr_control0 & gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_enable_f()) {
1898 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg,
1899 "CILP: clearing SINGLE_STEP_MODE before resume for gpc %d tpc %d\n",
1900 gpc, tpc);
1901 dbgr_control0 = set_field(dbgr_control0,
1902 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_m(),
1903 gr_gpcs_tpcs_sm_dbgr_control0_single_step_mode_disable_f());
1904 gk20a_writel(g, gr_gpc0_tpc0_sm_dbgr_control0_r() + offset, dbgr_control0);
1905 }
1906
1907 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg,
1908 "CILP: resume for gpc %d tpc %d\n",
1909 gpc, tpc);
1910 g->ops.gr.resume_single_sm(g, gpc, tpc, sm);
1911
1912 *ignore_debugger = true;
1913 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg, "CILP: All done on gpc %d, tpc %d\n", gpc, tpc);
1914 }
1915
1916 *early_exit = true;
1917 }
1918 return 0;
1919}
1920
1921static int gr_gp10b_get_cilp_preempt_pending_chid(struct gk20a *g, int *__chid)
1922{
1923 struct gr_ctx_desc *gr_ctx;
1924 struct channel_gk20a *ch;
1925 int chid;
1926 int ret = -EINVAL;
1927
1928 chid = g->gr.t18x.cilp_preempt_pending_chid;
1929
1930 ch = gk20a_channel_get(gk20a_fifo_channel_from_chid(g, chid));
1931 if (!ch)
1932 return ret;
1933
1934 gr_ctx = ch->ch_ctx.gr_ctx;
1935
1936 if (gr_ctx->t18x.cilp_preempt_pending) {
1937 *__chid = chid;
1938 ret = 0;
1939 }
1940
1941 gk20a_channel_put(ch);
1942
1943 return ret;
1944}
1945
1946int gr_gp10b_handle_fecs_error(struct gk20a *g,
1947 struct channel_gk20a *__ch,
1948 struct gr_gk20a_isr_data *isr_data)
1949{
1950 u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r());
1951 struct channel_gk20a *ch;
1952 int chid = -1;
1953 int ret = 0;
1954
1955 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr, "");
1956
1957 /*
1958 * INTR1 (bit 1 of the HOST_INT_STATUS_CTXSW_INTR)
1959 * indicates that a CILP ctxsw save has finished
1960 */
1961 if (gr_fecs_intr & gr_fecs_host_int_status_ctxsw_intr_f(2)) {
1962 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
1963 "CILP: ctxsw save completed!\n");
1964
1965 /* now clear the interrupt */
1966 gk20a_writel(g, gr_fecs_host_int_clear_r(),
1967 gr_fecs_host_int_clear_ctxsw_intr1_clear_f());
1968
1969 ret = gr_gp10b_get_cilp_preempt_pending_chid(g, &chid);
1970 if (ret)
1971 goto clean_up;
1972
1973 ch = gk20a_channel_get(
1974 gk20a_fifo_channel_from_chid(g, chid));
1975 if (!ch)
1976 goto clean_up;
1977
1978
1979 /* set preempt_pending to false */
1980 ret = gr_gp10b_clear_cilp_preempt_pending(g, ch);
1981 if (ret) {
1982 nvgpu_err(g, "CILP: error while unsetting CILP preempt pending!");
1983 gk20a_channel_put(ch);
1984 goto clean_up;
1985 }
1986
1987 /* Post events to UMD */
1988 gk20a_dbg_gpu_post_events(ch);
1989
1990 if (gk20a_is_channel_marked_as_tsg(ch)) {
1991 struct tsg_gk20a *tsg = &g->fifo.tsg[ch->tsgid];
1992
1993 gk20a_tsg_event_id_post_event(tsg,
1994 NVGPU_EVENT_ID_CILP_PREEMPTION_COMPLETE);
1995 } else {
1996 gk20a_channel_event_id_post_event(ch,
1997 NVGPU_EVENT_ID_CILP_PREEMPTION_COMPLETE);
1998 }
1999
2000 gk20a_channel_put(ch);
2001 }
2002
2003clean_up:
2004 /* handle any remaining interrupts */
2005 return gk20a_gr_handle_fecs_error(g, __ch, isr_data);
2006}
2007
2008u32 gp10b_gr_get_sm_hww_warp_esr(struct gk20a *g,
2009 u32 gpc, u32 tpc, u32 sm)
2010{
2011 u32 offset = gk20a_gr_gpc_offset(g, gpc) + gk20a_gr_tpc_offset(g, tpc);
2012 u32 hww_warp_esr = gk20a_readl(g,
2013 gr_gpc0_tpc0_sm_hww_warp_esr_r() + offset);
2014
2015 if (!(hww_warp_esr & gr_gpc0_tpc0_sm_hww_warp_esr_addr_valid_m()))
2016 hww_warp_esr = set_field(hww_warp_esr,
2017 gr_gpc0_tpc0_sm_hww_warp_esr_addr_error_type_m(),
2018 gr_gpc0_tpc0_sm_hww_warp_esr_addr_error_type_none_f());
2019
2020 return hww_warp_esr;
2021}
2022
2023u32 get_ecc_override_val(struct gk20a *g)
2024{
2025 u32 val;
2026
2027 val = gk20a_readl(g, fuse_opt_ecc_en_r());
2028 if (val)
2029 return gk20a_readl(g, gr_fecs_feature_override_ecc_r());
2030
2031 return 0;
2032}
2033
2034static bool gr_gp10b_suspend_context(struct channel_gk20a *ch,
2035 bool *cilp_preempt_pending)
2036{
2037 struct gk20a *g = ch->g;
2038 struct channel_ctx_gk20a *ch_ctx = &ch->ch_ctx;
2039 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
2040 bool ctx_resident = false;
2041 int err = 0;
2042
2043 *cilp_preempt_pending = false;
2044
2045 if (gk20a_is_channel_ctx_resident(ch)) {
2046 g->ops.gr.suspend_all_sms(g, 0, false);
2047
2048 if (gr_ctx->compute_preempt_mode == NVGPU_PREEMPTION_MODE_COMPUTE_CILP) {
2049 err = gr_gp10b_set_cilp_preempt_pending(g, ch);
2050 if (err)
2051 nvgpu_err(g, "unable to set CILP preempt pending");
2052 else
2053 *cilp_preempt_pending = true;
2054
2055 g->ops.gr.resume_all_sms(g);
2056 }
2057
2058 ctx_resident = true;
2059 } else {
2060 gk20a_disable_channel_tsg(g, ch);
2061 }
2062
2063 return ctx_resident;
2064}
2065
2066int gr_gp10b_suspend_contexts(struct gk20a *g,
2067 struct dbg_session_gk20a *dbg_s,
2068 int *ctx_resident_ch_fd)
2069{
2070 u32 delay = GR_IDLE_CHECK_DEFAULT;
2071 bool cilp_preempt_pending = false;
2072 struct channel_gk20a *cilp_preempt_pending_ch = NULL;
2073 struct channel_gk20a *ch;
2074 struct dbg_session_channel_data *ch_data;
2075 int err = 0;
2076 int local_ctx_resident_ch_fd = -1;
2077 bool ctx_resident;
2078
2079 nvgpu_mutex_acquire(&g->dbg_sessions_lock);
2080
2081 err = gr_gk20a_disable_ctxsw(g);
2082 if (err) {
2083 nvgpu_err(g, "unable to stop gr ctxsw");
2084 nvgpu_mutex_release(&g->dbg_sessions_lock);
2085 goto clean_up;
2086 }
2087
2088 nvgpu_mutex_acquire(&dbg_s->ch_list_lock);
2089
2090 list_for_each_entry(ch_data, &dbg_s->ch_list, ch_entry) {
2091 ch = g->fifo.channel + ch_data->chid;
2092
2093 ctx_resident = gr_gp10b_suspend_context(ch,
2094 &cilp_preempt_pending);
2095 if (ctx_resident)
2096 local_ctx_resident_ch_fd = ch_data->channel_fd;
2097 if (cilp_preempt_pending)
2098 cilp_preempt_pending_ch = ch;
2099 }
2100
2101 nvgpu_mutex_release(&dbg_s->ch_list_lock);
2102
2103 err = gr_gk20a_enable_ctxsw(g);
2104 if (err) {
2105 nvgpu_mutex_release(&g->dbg_sessions_lock);
2106 goto clean_up;
2107 }
2108
2109 nvgpu_mutex_release(&g->dbg_sessions_lock);
2110
2111 if (cilp_preempt_pending_ch) {
2112 struct channel_ctx_gk20a *ch_ctx =
2113 &cilp_preempt_pending_ch->ch_ctx;
2114 struct gr_ctx_desc *gr_ctx = ch_ctx->gr_ctx;
2115 struct nvgpu_timeout timeout;
2116
2117 gk20a_dbg(gpu_dbg_fn | gpu_dbg_gpu_dbg | gpu_dbg_intr,
2118 "CILP preempt pending, waiting %lu msecs for preemption",
2119 gk20a_get_gr_idle_timeout(g));
2120
2121 nvgpu_timeout_init(g, &timeout, gk20a_get_gr_idle_timeout(g),
2122 NVGPU_TIMER_CPU_TIMER);
2123 do {
2124 if (!gr_ctx->t18x.cilp_preempt_pending)
2125 break;
2126
2127 nvgpu_usleep_range(delay, delay * 2);
2128 delay = min_t(u32, delay << 1, GR_IDLE_CHECK_MAX);
2129 } while (!nvgpu_timeout_expired(&timeout));
2130
2131 /* If cilp is still pending at this point, timeout */
2132 if (gr_ctx->t18x.cilp_preempt_pending)
2133 err = -ETIMEDOUT;
2134 }
2135
2136 *ctx_resident_ch_fd = local_ctx_resident_ch_fd;
2137
2138clean_up:
2139 return err;
2140}
2141
2142int gr_gp10b_set_boosted_ctx(struct channel_gk20a *ch,
2143 bool boost)
2144{
2145 struct gr_ctx_desc *gr_ctx = ch->ch_ctx.gr_ctx;
2146 struct gk20a *g = ch->g;
2147 struct nvgpu_mem *mem = &gr_ctx->mem;
2148 int err = 0;
2149
2150 gr_ctx->boosted_ctx = boost;
2151
2152 if (nvgpu_mem_begin(g, mem))
2153 return -ENOMEM;
2154
2155 err = gk20a_disable_channel_tsg(g, ch);
2156 if (err)
2157 goto unmap_ctx;
2158
2159 err = gk20a_fifo_preempt(g, ch);
2160 if (err)
2161 goto enable_ch;
2162
2163 if (g->ops.gr.update_boosted_ctx)
2164 g->ops.gr.update_boosted_ctx(g, mem, gr_ctx);
2165 else
2166 err = -ENOSYS;
2167
2168enable_ch:
2169 gk20a_enable_channel_tsg(g, ch);
2170unmap_ctx:
2171 nvgpu_mem_end(g, mem);
2172
2173 return err;
2174}
2175
2176void gr_gp10b_update_boosted_ctx(struct gk20a *g, struct nvgpu_mem *mem,
2177 struct gr_ctx_desc *gr_ctx) {
2178 u32 v;
2179
2180 v = ctxsw_prog_main_image_pmu_options_boost_clock_frequencies_f(
2181 gr_ctx->boosted_ctx);
2182 nvgpu_mem_wr(g, mem, ctxsw_prog_main_image_pmu_options_o(), v);
2183}
2184
2185int gr_gp10b_set_preemption_mode(struct channel_gk20a *ch,
2186 u32 graphics_preempt_mode,
2187 u32 compute_preempt_mode)
2188{
2189 struct gr_ctx_desc *gr_ctx = ch->ch_ctx.gr_ctx;
2190 struct channel_ctx_gk20a *ch_ctx = &ch->ch_ctx;
2191 struct gk20a *g = ch->g;
2192 struct tsg_gk20a *tsg;
2193 struct vm_gk20a *vm;
2194 struct nvgpu_mem *mem = &gr_ctx->mem;
2195 struct ctx_header_desc *ctx = &ch->ch_ctx.ctx_header;
2196 struct nvgpu_mem *ctxheader = &ctx->mem;
2197 u32 class;
2198 int err = 0;
2199
2200 class = ch->obj_class;
2201 if (!class)
2202 return -EINVAL;
2203
2204 if (gk20a_is_channel_marked_as_tsg(ch)) {
2205 tsg = &g->fifo.tsg[ch->tsgid];
2206 vm = tsg->vm;
2207 } else {
2208 vm = ch->vm;
2209 }
2210
2211 /* skip setting anything if both modes are already set */
2212 if (graphics_preempt_mode &&
2213 (graphics_preempt_mode == gr_ctx->graphics_preempt_mode))
2214 graphics_preempt_mode = 0;
2215
2216 if (compute_preempt_mode &&
2217 (compute_preempt_mode == gr_ctx->compute_preempt_mode))
2218 compute_preempt_mode = 0;
2219
2220 if (graphics_preempt_mode == 0 && compute_preempt_mode == 0)
2221 return 0;
2222
2223 if (g->ops.gr.set_ctxsw_preemption_mode) {
2224
2225 gk20a_dbg(gpu_dbg_sched, "chid=%d tsgid=%d pid=%d "
2226 "graphics_preempt=%d compute_preempt=%d",
2227 ch->chid,
2228 ch->tsgid,
2229 ch->tgid,
2230 graphics_preempt_mode,
2231 compute_preempt_mode);
2232 err = g->ops.gr.set_ctxsw_preemption_mode(g, gr_ctx, vm, class,
2233 graphics_preempt_mode, compute_preempt_mode);
2234 if (err) {
2235 nvgpu_err(g, "set_ctxsw_preemption_mode failed");
2236 return err;
2237 }
2238 }
2239
2240 if (nvgpu_mem_begin(g, mem))
2241 return -ENOMEM;
2242
2243 if (nvgpu_mem_begin(g, ctxheader))
2244 goto unamp_ctx_header;
2245
2246 err = gk20a_disable_channel_tsg(g, ch);
2247 if (err)
2248 goto unmap_ctx;
2249
2250 err = gk20a_fifo_preempt(g, ch);
2251 if (err)
2252 goto enable_ch;
2253
2254 if (g->ops.gr.update_ctxsw_preemption_mode) {
2255 g->ops.gr.update_ctxsw_preemption_mode(ch->g,
2256 ch_ctx, mem);
2257
2258 err = gr_gk20a_ctx_patch_write_begin(g, ch_ctx, true);
2259 if (err) {
2260 nvgpu_err(g, "can't map patch context");
2261 goto enable_ch;
2262 }
2263 g->ops.gr.commit_global_cb_manager(g, ch, true);
2264 gr_gk20a_ctx_patch_write_end(g, ch_ctx, true);
2265 }
2266
2267enable_ch:
2268 gk20a_enable_channel_tsg(g, ch);
2269unmap_ctx:
2270 nvgpu_mem_end(g, ctxheader);
2271unamp_ctx_header:
2272 nvgpu_mem_end(g, mem);
2273
2274 return err;
2275}
2276
2277int gr_gp10b_get_preemption_mode_flags(struct gk20a *g,
2278 struct nvgpu_preemption_modes_rec *preemption_modes_rec)
2279{
2280 preemption_modes_rec->graphics_preemption_mode_flags = (
2281 NVGPU_PREEMPTION_MODE_GRAPHICS_WFI |
2282 NVGPU_PREEMPTION_MODE_GRAPHICS_GFXP);
2283 preemption_modes_rec->compute_preemption_mode_flags = (
2284 NVGPU_PREEMPTION_MODE_COMPUTE_WFI |
2285 NVGPU_PREEMPTION_MODE_COMPUTE_CTA |
2286 NVGPU_PREEMPTION_MODE_COMPUTE_CILP);
2287
2288 preemption_modes_rec->default_graphics_preempt_mode =
2289 NVGPU_PREEMPTION_MODE_GRAPHICS_WFI;
2290 preemption_modes_rec->default_compute_preempt_mode =
2291 NVGPU_PREEMPTION_MODE_COMPUTE_WFI;
2292
2293 return 0;
2294}
2295
2296int gr_gp10b_init_preemption_state(struct gk20a *g)
2297{
2298 u32 debug_2;
2299 struct gr_gk20a *gr = &g->gr;
2300 u32 sysclk_cycles = gr->gfxp_wfi_timeout_count;
2301 gk20a_writel(g, gr_fe_gfxp_wfi_timeout_r(),
2302 gr_fe_gfxp_wfi_timeout_count_f(sysclk_cycles));
2303
2304 debug_2 = gk20a_readl(g, gr_debug_2_r());
2305 debug_2 = set_field(debug_2,
2306 gr_debug_2_gfxp_wfi_always_injects_wfi_m(),
2307 gr_debug_2_gfxp_wfi_always_injects_wfi_enabled_f());
2308 gk20a_writel(g, gr_debug_2_r(), debug_2);
2309
2310 return 0;
2311}
2312
2313void gr_gp10b_set_preemption_buffer_va(struct gk20a *g,
2314 struct nvgpu_mem *mem, u64 gpu_va)
2315{
2316 u32 va = u64_lo32(gpu_va >> 8);
2317
2318 nvgpu_mem_wr(g, mem,
2319 ctxsw_prog_main_image_full_preemption_ptr_o(), va);
2320
2321}
2322
2323void gr_gp10b_init_czf_bypass(struct gk20a *g)
2324{
2325 g->gr.czf_bypass = gr_gpc0_prop_debug1_czf_bypass_init_v();
2326}
2327
2328int gr_gp10b_set_czf_bypass(struct gk20a *g, struct channel_gk20a *ch)
2329{
2330 struct nvgpu_dbg_gpu_reg_op ops;
2331
2332 ops.op = REGOP(WRITE_32);
2333 ops.type = REGOP(TYPE_GR_CTX);
2334 ops.status = REGOP(STATUS_SUCCESS);
2335 ops.value_hi = 0;
2336 ops.and_n_mask_lo = gr_gpc0_prop_debug1_czf_bypass_m();
2337 ops.and_n_mask_hi = 0;
2338 ops.offset = gr_gpc0_prop_debug1_r();
2339 ops.value_lo = gr_gpc0_prop_debug1_czf_bypass_f(
2340 g->gr.czf_bypass);
2341
2342 return __gr_gk20a_exec_ctx_ops(ch, &ops, 1, 1, 0, false);
2343}
2344
2345void gr_gp10b_init_ctxsw_hdr_data(struct gk20a *g, struct nvgpu_mem *mem)
2346{
2347 gk20a_gr_init_ctxsw_hdr_data(g, mem);
2348
2349 nvgpu_mem_wr(g, mem,
2350 ctxsw_prog_main_image_num_wfi_save_ops_o(), 0);
2351 nvgpu_mem_wr(g, mem,
2352 ctxsw_prog_main_image_num_cta_save_ops_o(), 0);
2353 nvgpu_mem_wr(g, mem,
2354 ctxsw_prog_main_image_num_gfxp_save_ops_o(), 0);
2355 nvgpu_mem_wr(g, mem,
2356 ctxsw_prog_main_image_num_cilp_save_ops_o(), 0);
2357}
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.h b/drivers/gpu/nvgpu/gp10b/gr_gp10b.h
new file mode 100644
index 00000000..45ac5305
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.h
@@ -0,0 +1,171 @@
1/*
2 * GP10B GPU GR
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef _NVGPU_GR_GP10B_H_
26#define _NVGPU_GR_GP10B_H_
27
28#include "gk20a/mm_gk20a.h"
29
30struct gk20a;
31struct gr_gk20a_isr_data;
32struct channel_ctx_gk20a;
33struct zbc_entry;
34struct gr_ctx_desc;
35struct nvgpu_preemption_modes_rec;
36struct gk20a_debug_output;
37
38enum {
39 PASCAL_CHANNEL_GPFIFO_A = 0xC06F,
40 PASCAL_A = 0xC097,
41 PASCAL_COMPUTE_A = 0xC0C0,
42 PASCAL_DMA_COPY_A = 0xC0B5,
43 PASCAL_DMA_COPY_B = 0xC1B5,
44};
45
46#define NVC097_SET_GO_IDLE_TIMEOUT 0x022c
47#define NVC097_SET_ALPHA_CIRCULAR_BUFFER_SIZE 0x02dc
48#define NVC097_SET_COALESCE_BUFFER_SIZE 0x1028
49#define NVC097_SET_RD_COALESCE 0x102c
50#define NVC097_SET_CIRCULAR_BUFFER_SIZE 0x1280
51#define NVC097_SET_SHADER_EXCEPTIONS 0x1528
52#define NVC097_SET_BES_CROP_DEBUG3 0x10c4
53#define NVC0C0_SET_SHADER_EXCEPTIONS 0x1528
54#define NVC0C0_SET_RD_COALESCE 0x0228
55
56int gr_gp10b_init_fs_state(struct gk20a *g);
57int gr_gp10b_alloc_buffer(struct vm_gk20a *vm, size_t size,
58 struct nvgpu_mem *mem);
59void gr_gp10b_create_sysfs(struct gk20a *g);
60int gr_gp10b_handle_fecs_error(struct gk20a *g,
61 struct channel_gk20a *__ch,
62 struct gr_gk20a_isr_data *isr_data);
63int gr_gp10b_set_cilp_preempt_pending(struct gk20a *g,
64 struct channel_gk20a *fault_ch);
65
66bool gr_gp10b_is_valid_class(struct gk20a *g, u32 class_num);
67bool gr_gp10b_is_valid_gfx_class(struct gk20a *g, u32 class_num);
68bool gr_gp10b_is_valid_compute_class(struct gk20a *g, u32 class_num);
69int gr_gp10b_handle_sm_exception(struct gk20a *g,
70 u32 gpc, u32 tpc, u32 sm,
71 bool *post_event, struct channel_gk20a *fault_ch,
72 u32 *hww_global_esr);
73int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc,
74 bool *post_event);
75int gr_gp10b_commit_global_cb_manager(struct gk20a *g,
76 struct channel_gk20a *c, bool patch);
77void gr_gp10b_commit_global_pagepool(struct gk20a *g,
78 struct channel_ctx_gk20a *ch_ctx,
79 u64 addr, u32 size, bool patch);
80int gr_gp10b_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr,
81 struct zbc_entry *color_val, u32 index);
82int gr_gp10b_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr,
83 struct zbc_entry *depth_val, u32 index);
84u32 gr_gp10b_pagepool_default_size(struct gk20a *g);
85int gr_gp10b_calc_global_ctx_buffer_size(struct gk20a *g);
86void gr_gp10b_set_bes_crop_debug3(struct gk20a *g, u32 data);
87int gr_gp10b_handle_sw_method(struct gk20a *g, u32 addr,
88 u32 class_num, u32 offset, u32 data);
89void gr_gp10b_cb_size_default(struct gk20a *g);
90void gr_gp10b_set_alpha_circular_buffer_size(struct gk20a *g, u32 data);
91void gr_gp10b_set_circular_buffer_size(struct gk20a *g, u32 data);
92int gr_gp10b_init_ctx_state(struct gk20a *g);
93int gr_gp10b_set_ctxsw_preemption_mode(struct gk20a *g,
94 struct gr_ctx_desc *gr_ctx,
95 struct vm_gk20a *vm, u32 class,
96 u32 graphics_preempt_mode,
97 u32 compute_preempt_mode);
98int gr_gp10b_alloc_gr_ctx(struct gk20a *g,
99 struct gr_ctx_desc **gr_ctx, struct vm_gk20a *vm,
100 u32 class,
101 u32 flags);
102void gr_gp10b_free_gr_ctx(struct gk20a *g, struct vm_gk20a *vm,
103 struct gr_ctx_desc *gr_ctx);
104void gr_gp10b_update_ctxsw_preemption_mode(struct gk20a *g,
105 struct channel_ctx_gk20a *ch_ctx,
106 struct nvgpu_mem *mem);
107int gr_gp10b_dump_gr_status_regs(struct gk20a *g,
108 struct gk20a_debug_output *o);
109int gr_gp10b_wait_empty(struct gk20a *g, unsigned long duration_ms,
110 u32 expect_delay);
111void gr_gp10b_commit_global_attrib_cb(struct gk20a *g,
112 struct channel_ctx_gk20a *ch_ctx,
113 u64 addr, bool patch);
114void gr_gp10b_commit_global_bundle_cb(struct gk20a *g,
115 struct channel_ctx_gk20a *ch_ctx,
116 u64 addr, u64 size, bool patch);
117int gr_gp10b_load_smid_config(struct gk20a *g);
118void gr_gp10b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index);
119void gr_gp10b_get_access_map(struct gk20a *g,
120 u32 **whitelist, int *num_entries);
121int gr_gp10b_pre_process_sm_exception(struct gk20a *g,
122 u32 gpc, u32 tpc, u32 sm, u32 global_esr, u32 warp_esr,
123 bool sm_debugger_attached, struct channel_gk20a *fault_ch,
124 bool *early_exit, bool *ignore_debugger);
125u32 gp10b_gr_get_sm_hww_warp_esr(struct gk20a *g,
126 u32 gpc, u32 tpc, u32 sm);
127u32 get_ecc_override_val(struct gk20a *g);
128int gr_gp10b_suspend_contexts(struct gk20a *g,
129 struct dbg_session_gk20a *dbg_s,
130 int *ctx_resident_ch_fd);
131int gr_gp10b_set_boosted_ctx(struct channel_gk20a *ch,
132 bool boost);
133void gr_gp10b_update_boosted_ctx(struct gk20a *g, struct nvgpu_mem *mem,
134 struct gr_ctx_desc *gr_ctx);
135int gr_gp10b_set_preemption_mode(struct channel_gk20a *ch,
136 u32 graphics_preempt_mode,
137 u32 compute_preempt_mode);
138int gr_gp10b_get_preemption_mode_flags(struct gk20a *g,
139 struct nvgpu_preemption_modes_rec *preemption_modes_rec);
140int gp10b_gr_fuse_override(struct gk20a *g);
141int gr_gp10b_init_preemption_state(struct gk20a *g);
142void gr_gp10b_set_preemption_buffer_va(struct gk20a *g,
143 struct nvgpu_mem *mem, u64 gpu_va);
144int gr_gp10b_set_czf_bypass(struct gk20a *g, struct channel_gk20a *ch);
145void gr_gp10b_init_czf_bypass(struct gk20a *g);
146void gr_gp10b_init_ctxsw_hdr_data(struct gk20a *g, struct nvgpu_mem *mem);
147
148struct gr_t18x {
149 struct {
150 u32 preempt_image_size;
151 bool force_preemption_gfxp;
152 bool force_preemption_cilp;
153 bool dump_ctxsw_stats_on_channel_close;
154 } ctx_vars;
155
156 u32 fecs_feature_override_ecc_val;
157
158 int cilp_preempt_pending_chid;
159};
160
161struct gr_ctx_desc_t18x {
162 struct nvgpu_mem preempt_ctxsw_buffer;
163 struct nvgpu_mem spill_ctxsw_buffer;
164 struct nvgpu_mem betacb_ctxsw_buffer;
165 struct nvgpu_mem pagepool_ctxsw_buffer;
166 u32 ctx_id;
167 bool ctx_id_valid;
168 bool cilp_preempt_pending;
169};
170
171#endif
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
new file mode 100644
index 00000000..9b3d1a2c
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
@@ -0,0 +1,748 @@
1/*
2 * GP10B Tegra HAL interface
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26#include "gk20a/fifo_gk20a.h"
27#include "gk20a/fecs_trace_gk20a.h"
28#include "gk20a/mm_gk20a.h"
29#include "gk20a/dbg_gpu_gk20a.h"
30#include "gk20a/css_gr_gk20a.h"
31#include "gk20a/bus_gk20a.h"
32#include "gk20a/pramin_gk20a.h"
33#include "gk20a/flcn_gk20a.h"
34#include "gk20a/regops_gk20a.h"
35#include "gk20a/mc_gk20a.h"
36#include "gk20a/fb_gk20a.h"
37#include "gk20a/pmu_gk20a.h"
38#include "gk20a/gr_gk20a.h"
39#include "gk20a/tsg_gk20a.h"
40
41#include "gp10b/gr_gp10b.h"
42#include "gp10b/fecs_trace_gp10b.h"
43#include "gp10b/mc_gp10b.h"
44#include "gp10b/ltc_gp10b.h"
45#include "gp10b/mm_gp10b.h"
46#include "gp10b/ce_gp10b.h"
47#include "gp10b/fb_gp10b.h"
48#include "gp10b/pmu_gp10b.h"
49#include "gp10b/gr_ctx_gp10b.h"
50#include "gp10b/fifo_gp10b.h"
51#include "gp10b/gp10b_gating_reglist.h"
52#include "gp10b/regops_gp10b.h"
53#include "gp10b/therm_gp10b.h"
54#include "gp10b/priv_ring_gp10b.h"
55
56#include "gm20b/ltc_gm20b.h"
57#include "gm20b/gr_gm20b.h"
58#include "gm20b/fifo_gm20b.h"
59#include "gm20b/acr_gm20b.h"
60#include "gm20b/pmu_gm20b.h"
61#include "gm20b/clk_gm20b.h"
62#include "gm20b/fb_gm20b.h"
63#include "gm20b/mm_gm20b.h"
64
65#include "gp10b.h"
66#include "hal_gp10b.h"
67
68#include <nvgpu/debug.h>
69#include <nvgpu/bug.h>
70#include <nvgpu/enabled.h>
71#include <nvgpu/bus.h>
72#include <nvgpu/ctxsw_trace.h>
73
74#include <nvgpu/hw/gp10b/hw_proj_gp10b.h>
75#include <nvgpu/hw/gp10b/hw_fuse_gp10b.h>
76#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h>
77#include <nvgpu/hw/gp10b/hw_ram_gp10b.h>
78#include <nvgpu/hw/gp10b/hw_top_gp10b.h>
79#include <nvgpu/hw/gp10b/hw_pram_gp10b.h>
80#include <nvgpu/hw/gp10b/hw_pwr_gp10b.h>
81
82int gp10b_get_litter_value(struct gk20a *g, int value)
83{
84 int ret = EINVAL;
85 switch (value) {
86 case GPU_LIT_NUM_GPCS:
87 ret = proj_scal_litter_num_gpcs_v();
88 break;
89 case GPU_LIT_NUM_PES_PER_GPC:
90 ret = proj_scal_litter_num_pes_per_gpc_v();
91 break;
92 case GPU_LIT_NUM_ZCULL_BANKS:
93 ret = proj_scal_litter_num_zcull_banks_v();
94 break;
95 case GPU_LIT_NUM_TPC_PER_GPC:
96 ret = proj_scal_litter_num_tpc_per_gpc_v();
97 break;
98 case GPU_LIT_NUM_SM_PER_TPC:
99 ret = proj_scal_litter_num_sm_per_tpc_v();
100 break;
101 case GPU_LIT_NUM_FBPS:
102 ret = proj_scal_litter_num_fbps_v();
103 break;
104 case GPU_LIT_GPC_BASE:
105 ret = proj_gpc_base_v();
106 break;
107 case GPU_LIT_GPC_STRIDE:
108 ret = proj_gpc_stride_v();
109 break;
110 case GPU_LIT_GPC_SHARED_BASE:
111 ret = proj_gpc_shared_base_v();
112 break;
113 case GPU_LIT_TPC_IN_GPC_BASE:
114 ret = proj_tpc_in_gpc_base_v();
115 break;
116 case GPU_LIT_TPC_IN_GPC_STRIDE:
117 ret = proj_tpc_in_gpc_stride_v();
118 break;
119 case GPU_LIT_TPC_IN_GPC_SHARED_BASE:
120 ret = proj_tpc_in_gpc_shared_base_v();
121 break;
122 case GPU_LIT_PPC_IN_GPC_BASE:
123 ret = proj_ppc_in_gpc_base_v();
124 break;
125 case GPU_LIT_PPC_IN_GPC_STRIDE:
126 ret = proj_ppc_in_gpc_stride_v();
127 break;
128 case GPU_LIT_PPC_IN_GPC_SHARED_BASE:
129 ret = proj_ppc_in_gpc_shared_base_v();
130 break;
131 case GPU_LIT_ROP_BASE:
132 ret = proj_rop_base_v();
133 break;
134 case GPU_LIT_ROP_STRIDE:
135 ret = proj_rop_stride_v();
136 break;
137 case GPU_LIT_ROP_SHARED_BASE:
138 ret = proj_rop_shared_base_v();
139 break;
140 case GPU_LIT_HOST_NUM_ENGINES:
141 ret = proj_host_num_engines_v();
142 break;
143 case GPU_LIT_HOST_NUM_PBDMA:
144 ret = proj_host_num_pbdma_v();
145 break;
146 case GPU_LIT_LTC_STRIDE:
147 ret = proj_ltc_stride_v();
148 break;
149 case GPU_LIT_LTS_STRIDE:
150 ret = proj_lts_stride_v();
151 break;
152 /* Even though GP10B doesn't have an FBPA unit, the HW reports one,
153 * and the microcode as a result leaves space in the context buffer
154 * for one, so make sure SW accounts for this also.
155 */
156 case GPU_LIT_NUM_FBPAS:
157 ret = proj_scal_litter_num_fbpas_v();
158 break;
159 /* Hardcode FBPA values other than NUM_FBPAS to 0. */
160 case GPU_LIT_FBPA_STRIDE:
161 case GPU_LIT_FBPA_BASE:
162 case GPU_LIT_FBPA_SHARED_BASE:
163 ret = 0;
164 break;
165 case GPU_LIT_TWOD_CLASS:
166 ret = FERMI_TWOD_A;
167 break;
168 case GPU_LIT_THREED_CLASS:
169 ret = PASCAL_A;
170 break;
171 case GPU_LIT_COMPUTE_CLASS:
172 ret = PASCAL_COMPUTE_A;
173 break;
174 case GPU_LIT_GPFIFO_CLASS:
175 ret = PASCAL_CHANNEL_GPFIFO_A;
176 break;
177 case GPU_LIT_I2M_CLASS:
178 ret = KEPLER_INLINE_TO_MEMORY_B;
179 break;
180 case GPU_LIT_DMA_COPY_CLASS:
181 ret = PASCAL_DMA_COPY_A;
182 break;
183
184 default:
185 nvgpu_err(g, "Missing definition %d", value);
186 BUG();
187 break;
188 }
189
190 return ret;
191}
192
193static const struct gpu_ops gp10b_ops = {
194 .ltc = {
195 .determine_L2_size_bytes = gp10b_determine_L2_size_bytes,
196 .set_zbc_color_entry = gm20b_ltc_set_zbc_color_entry,
197 .set_zbc_depth_entry = gm20b_ltc_set_zbc_depth_entry,
198 .init_cbc = gm20b_ltc_init_cbc,
199 .init_fs_state = gp10b_ltc_init_fs_state,
200 .init_comptags = gp10b_ltc_init_comptags,
201 .cbc_ctrl = gm20b_ltc_cbc_ctrl,
202 .isr = gp10b_ltc_isr,
203 .cbc_fix_config = gm20b_ltc_cbc_fix_config,
204 .flush = gm20b_flush_ltc,
205 .set_enabled = gp10b_ltc_set_enabled,
206 },
207 .ce2 = {
208 .isr_stall = gp10b_ce_isr,
209 .isr_nonstall = gp10b_ce_nonstall_isr,
210 },
211 .gr = {
212 .get_patch_slots = gr_gk20a_get_patch_slots,
213 .init_gpc_mmu = gr_gm20b_init_gpc_mmu,
214 .bundle_cb_defaults = gr_gm20b_bundle_cb_defaults,
215 .cb_size_default = gr_gp10b_cb_size_default,
216 .calc_global_ctx_buffer_size =
217 gr_gp10b_calc_global_ctx_buffer_size,
218 .commit_global_attrib_cb = gr_gp10b_commit_global_attrib_cb,
219 .commit_global_bundle_cb = gr_gp10b_commit_global_bundle_cb,
220 .commit_global_cb_manager = gr_gp10b_commit_global_cb_manager,
221 .commit_global_pagepool = gr_gp10b_commit_global_pagepool,
222 .handle_sw_method = gr_gp10b_handle_sw_method,
223 .set_alpha_circular_buffer_size =
224 gr_gp10b_set_alpha_circular_buffer_size,
225 .set_circular_buffer_size = gr_gp10b_set_circular_buffer_size,
226 .enable_hww_exceptions = gr_gk20a_enable_hww_exceptions,
227 .is_valid_class = gr_gp10b_is_valid_class,
228 .is_valid_gfx_class = gr_gp10b_is_valid_gfx_class,
229 .is_valid_compute_class = gr_gp10b_is_valid_compute_class,
230 .get_sm_dsm_perf_regs = gr_gm20b_get_sm_dsm_perf_regs,
231 .get_sm_dsm_perf_ctrl_regs = gr_gm20b_get_sm_dsm_perf_ctrl_regs,
232 .init_fs_state = gr_gp10b_init_fs_state,
233 .set_hww_esr_report_mask = gr_gm20b_set_hww_esr_report_mask,
234 .falcon_load_ucode = gr_gm20b_load_ctxsw_ucode_segments,
235 .load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode,
236 .set_gpc_tpc_mask = gr_gp10b_set_gpc_tpc_mask,
237 .get_gpc_tpc_mask = gr_gm20b_get_gpc_tpc_mask,
238 .free_channel_ctx = gk20a_free_channel_ctx,
239 .alloc_obj_ctx = gk20a_alloc_obj_ctx,
240 .bind_ctxsw_zcull = gr_gk20a_bind_ctxsw_zcull,
241 .get_zcull_info = gr_gk20a_get_zcull_info,
242 .is_tpc_addr = gr_gm20b_is_tpc_addr,
243 .get_tpc_num = gr_gm20b_get_tpc_num,
244 .detect_sm_arch = gr_gm20b_detect_sm_arch,
245 .add_zbc_color = gr_gp10b_add_zbc_color,
246 .add_zbc_depth = gr_gp10b_add_zbc_depth,
247 .zbc_set_table = gk20a_gr_zbc_set_table,
248 .zbc_query_table = gr_gk20a_query_zbc,
249 .pmu_save_zbc = gk20a_pmu_save_zbc,
250 .add_zbc = gr_gk20a_add_zbc,
251 .pagepool_default_size = gr_gp10b_pagepool_default_size,
252 .init_ctx_state = gr_gp10b_init_ctx_state,
253 .alloc_gr_ctx = gr_gp10b_alloc_gr_ctx,
254 .free_gr_ctx = gr_gp10b_free_gr_ctx,
255 .update_ctxsw_preemption_mode =
256 gr_gp10b_update_ctxsw_preemption_mode,
257 .dump_gr_regs = gr_gp10b_dump_gr_status_regs,
258 .update_pc_sampling = gr_gm20b_update_pc_sampling,
259 .get_fbp_en_mask = gr_gm20b_get_fbp_en_mask,
260 .get_max_ltc_per_fbp = gr_gm20b_get_max_ltc_per_fbp,
261 .get_max_lts_per_ltc = gr_gm20b_get_max_lts_per_ltc,
262 .get_rop_l2_en_mask = gr_gm20b_rop_l2_en_mask,
263 .get_max_fbps_count = gr_gm20b_get_max_fbps_count,
264 .init_sm_dsm_reg_info = gr_gm20b_init_sm_dsm_reg_info,
265 .wait_empty = gr_gp10b_wait_empty,
266 .init_cyclestats = gr_gm20b_init_cyclestats,
267 .set_sm_debug_mode = gr_gk20a_set_sm_debug_mode,
268 .enable_cde_in_fecs = gr_gm20b_enable_cde_in_fecs,
269 .bpt_reg_info = gr_gm20b_bpt_reg_info,
270 .get_access_map = gr_gp10b_get_access_map,
271 .handle_fecs_error = gr_gp10b_handle_fecs_error,
272 .handle_sm_exception = gr_gp10b_handle_sm_exception,
273 .handle_tex_exception = gr_gp10b_handle_tex_exception,
274 .enable_gpc_exceptions = gk20a_gr_enable_gpc_exceptions,
275 .enable_exceptions = gk20a_gr_enable_exceptions,
276 .get_lrf_tex_ltc_dram_override = get_ecc_override_val,
277 .update_smpc_ctxsw_mode = gr_gk20a_update_smpc_ctxsw_mode,
278 .update_hwpm_ctxsw_mode = gr_gk20a_update_hwpm_ctxsw_mode,
279 .record_sm_error_state = gm20b_gr_record_sm_error_state,
280 .update_sm_error_state = gm20b_gr_update_sm_error_state,
281 .clear_sm_error_state = gm20b_gr_clear_sm_error_state,
282 .suspend_contexts = gr_gp10b_suspend_contexts,
283 .resume_contexts = gr_gk20a_resume_contexts,
284 .get_preemption_mode_flags = gr_gp10b_get_preemption_mode_flags,
285 .init_sm_id_table = gr_gk20a_init_sm_id_table,
286 .load_smid_config = gr_gp10b_load_smid_config,
287 .program_sm_id_numbering = gr_gm20b_program_sm_id_numbering,
288 .is_ltcs_ltss_addr = gr_gm20b_is_ltcs_ltss_addr,
289 .is_ltcn_ltss_addr = gr_gm20b_is_ltcn_ltss_addr,
290 .split_lts_broadcast_addr = gr_gm20b_split_lts_broadcast_addr,
291 .split_ltc_broadcast_addr = gr_gm20b_split_ltc_broadcast_addr,
292 .setup_rop_mapping = gr_gk20a_setup_rop_mapping,
293 .program_zcull_mapping = gr_gk20a_program_zcull_mapping,
294 .commit_global_timeslice = gr_gk20a_commit_global_timeslice,
295 .commit_inst = gr_gk20a_commit_inst,
296 .write_zcull_ptr = gr_gk20a_write_zcull_ptr,
297 .write_pm_ptr = gr_gk20a_write_pm_ptr,
298 .init_elcg_mode = gr_gk20a_init_elcg_mode,
299 .load_tpc_mask = gr_gm20b_load_tpc_mask,
300 .inval_icache = gr_gk20a_inval_icache,
301 .trigger_suspend = gr_gk20a_trigger_suspend,
302 .wait_for_pause = gr_gk20a_wait_for_pause,
303 .resume_from_pause = gr_gk20a_resume_from_pause,
304 .clear_sm_errors = gr_gk20a_clear_sm_errors,
305 .tpc_enabled_exceptions = gr_gk20a_tpc_enabled_exceptions,
306 .get_esr_sm_sel = gk20a_gr_get_esr_sm_sel,
307 .sm_debugger_attached = gk20a_gr_sm_debugger_attached,
308 .suspend_single_sm = gk20a_gr_suspend_single_sm,
309 .suspend_all_sms = gk20a_gr_suspend_all_sms,
310 .resume_single_sm = gk20a_gr_resume_single_sm,
311 .resume_all_sms = gk20a_gr_resume_all_sms,
312 .get_sm_hww_warp_esr = gp10b_gr_get_sm_hww_warp_esr,
313 .get_sm_hww_global_esr = gk20a_gr_get_sm_hww_global_esr,
314 .get_sm_no_lock_down_hww_global_esr_mask =
315 gk20a_gr_get_sm_no_lock_down_hww_global_esr_mask,
316 .lock_down_sm = gk20a_gr_lock_down_sm,
317 .wait_for_sm_lock_down = gk20a_gr_wait_for_sm_lock_down,
318 .clear_sm_hww = gm20b_gr_clear_sm_hww,
319 .init_ovr_sm_dsm_perf = gk20a_gr_init_ovr_sm_dsm_perf,
320 .get_ovr_perf_regs = gk20a_gr_get_ovr_perf_regs,
321 .disable_rd_coalesce = gm20a_gr_disable_rd_coalesce,
322 .set_boosted_ctx = gr_gp10b_set_boosted_ctx,
323 .set_preemption_mode = gr_gp10b_set_preemption_mode,
324 .set_czf_bypass = gr_gp10b_set_czf_bypass,
325 .init_czf_bypass = gr_gp10b_init_czf_bypass,
326 .pre_process_sm_exception = gr_gp10b_pre_process_sm_exception,
327 .set_preemption_buffer_va = gr_gp10b_set_preemption_buffer_va,
328 .init_preemption_state = gr_gp10b_init_preemption_state,
329 .update_boosted_ctx = gr_gp10b_update_boosted_ctx,
330 .set_bes_crop_debug3 = gr_gp10b_set_bes_crop_debug3,
331 .create_gr_sysfs = gr_gp10b_create_sysfs,
332 .set_ctxsw_preemption_mode = gr_gp10b_set_ctxsw_preemption_mode,
333 .init_ctxsw_hdr_data = gr_gp10b_init_ctxsw_hdr_data,
334 },
335 .fb = {
336 .reset = fb_gk20a_reset,
337 .init_hw = gk20a_fb_init_hw,
338 .init_fs_state = fb_gm20b_init_fs_state,
339 .set_mmu_page_size = gm20b_fb_set_mmu_page_size,
340 .set_use_full_comp_tag_line =
341 gm20b_fb_set_use_full_comp_tag_line,
342 .compression_page_size = gp10b_fb_compression_page_size,
343 .compressible_page_size = gp10b_fb_compressible_page_size,
344 .vpr_info_fetch = gm20b_fb_vpr_info_fetch,
345 .dump_vpr_wpr_info = gm20b_fb_dump_vpr_wpr_info,
346 .read_wpr_info = gm20b_fb_read_wpr_info,
347 .is_debug_mode_enabled = gm20b_fb_debug_mode_enabled,
348 .set_debug_mode = gm20b_fb_set_debug_mode,
349 .tlb_invalidate = gk20a_fb_tlb_invalidate,
350 .mem_unlock = NULL,
351 },
352 .clock_gating = {
353 .slcg_bus_load_gating_prod =
354 gp10b_slcg_bus_load_gating_prod,
355 .slcg_ce2_load_gating_prod =
356 gp10b_slcg_ce2_load_gating_prod,
357 .slcg_chiplet_load_gating_prod =
358 gp10b_slcg_chiplet_load_gating_prod,
359 .slcg_ctxsw_firmware_load_gating_prod =
360 gp10b_slcg_ctxsw_firmware_load_gating_prod,
361 .slcg_fb_load_gating_prod =
362 gp10b_slcg_fb_load_gating_prod,
363 .slcg_fifo_load_gating_prod =
364 gp10b_slcg_fifo_load_gating_prod,
365 .slcg_gr_load_gating_prod =
366 gr_gp10b_slcg_gr_load_gating_prod,
367 .slcg_ltc_load_gating_prod =
368 ltc_gp10b_slcg_ltc_load_gating_prod,
369 .slcg_perf_load_gating_prod =
370 gp10b_slcg_perf_load_gating_prod,
371 .slcg_priring_load_gating_prod =
372 gp10b_slcg_priring_load_gating_prod,
373 .slcg_pmu_load_gating_prod =
374 gp10b_slcg_pmu_load_gating_prod,
375 .slcg_therm_load_gating_prod =
376 gp10b_slcg_therm_load_gating_prod,
377 .slcg_xbar_load_gating_prod =
378 gp10b_slcg_xbar_load_gating_prod,
379 .blcg_bus_load_gating_prod =
380 gp10b_blcg_bus_load_gating_prod,
381 .blcg_ce_load_gating_prod =
382 gp10b_blcg_ce_load_gating_prod,
383 .blcg_ctxsw_firmware_load_gating_prod =
384 gp10b_blcg_ctxsw_firmware_load_gating_prod,
385 .blcg_fb_load_gating_prod =
386 gp10b_blcg_fb_load_gating_prod,
387 .blcg_fifo_load_gating_prod =
388 gp10b_blcg_fifo_load_gating_prod,
389 .blcg_gr_load_gating_prod =
390 gp10b_blcg_gr_load_gating_prod,
391 .blcg_ltc_load_gating_prod =
392 gp10b_blcg_ltc_load_gating_prod,
393 .blcg_pwr_csb_load_gating_prod =
394 gp10b_blcg_pwr_csb_load_gating_prod,
395 .blcg_pmu_load_gating_prod =
396 gp10b_blcg_pmu_load_gating_prod,
397 .blcg_xbar_load_gating_prod =
398 gp10b_blcg_xbar_load_gating_prod,
399 .pg_gr_load_gating_prod =
400 gr_gp10b_pg_gr_load_gating_prod,
401 },
402 .fifo = {
403 .init_fifo_setup_hw = gk20a_init_fifo_setup_hw,
404 .bind_channel = channel_gm20b_bind,
405 .unbind_channel = gk20a_fifo_channel_unbind,
406 .disable_channel = gk20a_fifo_disable_channel,
407 .enable_channel = gk20a_fifo_enable_channel,
408 .alloc_inst = gk20a_fifo_alloc_inst,
409 .free_inst = gk20a_fifo_free_inst,
410 .setup_ramfc = channel_gp10b_setup_ramfc,
411 .channel_set_timeslice = gk20a_fifo_set_timeslice,
412 .default_timeslice_us = gk20a_fifo_default_timeslice_us,
413 .setup_userd = gk20a_fifo_setup_userd,
414 .userd_gp_get = gk20a_fifo_userd_gp_get,
415 .userd_gp_put = gk20a_fifo_userd_gp_put,
416 .userd_pb_get = gk20a_fifo_userd_pb_get,
417 .pbdma_acquire_val = gk20a_fifo_pbdma_acquire_val,
418 .preempt_channel = gk20a_fifo_preempt_channel,
419 .preempt_tsg = gk20a_fifo_preempt_tsg,
420 .enable_tsg = gk20a_enable_tsg,
421 .disable_tsg = gk20a_disable_tsg,
422 .tsg_verify_channel_status = gk20a_fifo_tsg_unbind_channel_verify_status,
423 .tsg_verify_status_ctx_reload = gm20b_fifo_tsg_verify_status_ctx_reload,
424 .reschedule_runlist = gk20a_fifo_reschedule_runlist,
425 .update_runlist = gk20a_fifo_update_runlist,
426 .trigger_mmu_fault = gm20b_fifo_trigger_mmu_fault,
427 .get_mmu_fault_info = gp10b_fifo_get_mmu_fault_info,
428 .wait_engine_idle = gk20a_fifo_wait_engine_idle,
429 .get_num_fifos = gm20b_fifo_get_num_fifos,
430 .get_pbdma_signature = gp10b_fifo_get_pbdma_signature,
431 .set_runlist_interleave = gk20a_fifo_set_runlist_interleave,
432 .tsg_set_timeslice = gk20a_fifo_tsg_set_timeslice,
433 .force_reset_ch = gk20a_fifo_force_reset_ch,
434 .engine_enum_from_type = gp10b_fifo_engine_enum_from_type,
435 .device_info_data_parse = gp10b_device_info_data_parse,
436 .eng_runlist_base_size = fifo_eng_runlist_base__size_1_v,
437 .init_engine_info = gk20a_fifo_init_engine_info,
438 .runlist_entry_size = ram_rl_entry_size_v,
439 .get_tsg_runlist_entry = gk20a_get_tsg_runlist_entry,
440 .get_ch_runlist_entry = gk20a_get_ch_runlist_entry,
441 .is_fault_engine_subid_gpc = gk20a_is_fault_engine_subid_gpc,
442 .dump_pbdma_status = gk20a_dump_pbdma_status,
443 .dump_eng_status = gk20a_dump_eng_status,
444 .dump_channel_status_ramfc = gk20a_dump_channel_status_ramfc,
445 .intr_0_error_mask = gk20a_fifo_intr_0_error_mask,
446 .is_preempt_pending = gk20a_fifo_is_preempt_pending,
447 .init_pbdma_intr_descs = gp10b_fifo_init_pbdma_intr_descs,
448 .reset_enable_hw = gk20a_init_fifo_reset_enable_hw,
449 .teardown_ch_tsg = gk20a_fifo_teardown_ch_tsg,
450 .handle_sched_error = gk20a_fifo_handle_sched_error,
451 .handle_pbdma_intr_0 = gk20a_fifo_handle_pbdma_intr_0,
452 .handle_pbdma_intr_1 = gk20a_fifo_handle_pbdma_intr_1,
453 .tsg_bind_channel = gk20a_tsg_bind_channel,
454 .tsg_unbind_channel = gk20a_tsg_unbind_channel,
455#ifdef CONFIG_TEGRA_GK20A_NVHOST
456 .alloc_syncpt_buf = gk20a_fifo_alloc_syncpt_buf,
457 .free_syncpt_buf = gk20a_fifo_free_syncpt_buf,
458 .add_syncpt_wait_cmd = gk20a_fifo_add_syncpt_wait_cmd,
459 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size,
460 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd,
461 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size,
462#endif
463 .resetup_ramfc = gp10b_fifo_resetup_ramfc,
464 .device_info_fault_id = top_device_info_data_fault_id_enum_v,
465 },
466 .gr_ctx = {
467 .get_netlist_name = gr_gp10b_get_netlist_name,
468 .is_fw_defined = gr_gp10b_is_firmware_defined,
469 },
470#ifdef CONFIG_GK20A_CTXSW_TRACE
471 .fecs_trace = {
472 .alloc_user_buffer = gk20a_ctxsw_dev_ring_alloc,
473 .free_user_buffer = gk20a_ctxsw_dev_ring_free,
474 .mmap_user_buffer = gk20a_ctxsw_dev_mmap_buffer,
475 .init = gk20a_fecs_trace_init,
476 .deinit = gk20a_fecs_trace_deinit,
477 .enable = gk20a_fecs_trace_enable,
478 .disable = gk20a_fecs_trace_disable,
479 .is_enabled = gk20a_fecs_trace_is_enabled,
480 .reset = gk20a_fecs_trace_reset,
481 .flush = gp10b_fecs_trace_flush,
482 .poll = gk20a_fecs_trace_poll,
483 .bind_channel = gk20a_fecs_trace_bind_channel,
484 .unbind_channel = gk20a_fecs_trace_unbind_channel,
485 .max_entries = gk20a_gr_max_entries,
486 },
487#endif /* CONFIG_GK20A_CTXSW_TRACE */
488 .mm = {
489 .support_sparse = gm20b_mm_support_sparse,
490 .gmmu_map = gk20a_locked_gmmu_map,
491 .gmmu_unmap = gk20a_locked_gmmu_unmap,
492 .vm_bind_channel = gk20a_vm_bind_channel,
493 .fb_flush = gk20a_mm_fb_flush,
494 .l2_invalidate = gk20a_mm_l2_invalidate,
495 .l2_flush = gk20a_mm_l2_flush,
496 .cbc_clean = gk20a_mm_cbc_clean,
497 .set_big_page_size = gm20b_mm_set_big_page_size,
498 .get_big_page_sizes = gm20b_mm_get_big_page_sizes,
499 .get_default_big_page_size = gp10b_mm_get_default_big_page_size,
500 .gpu_phys_addr = gm20b_gpu_phys_addr,
501 .get_iommu_bit = gp10b_mm_get_iommu_bit,
502 .get_mmu_levels = gp10b_mm_get_mmu_levels,
503 .init_pdb = gp10b_mm_init_pdb,
504 .init_mm_setup_hw = gp10b_init_mm_setup_hw,
505 .is_bar1_supported = gm20b_mm_is_bar1_supported,
506 .alloc_inst_block = gk20a_alloc_inst_block,
507 .init_inst_block = gk20a_init_inst_block,
508 .mmu_fault_pending = gk20a_fifo_mmu_fault_pending,
509 .init_bar2_vm = gb10b_init_bar2_vm,
510 .init_bar2_mm_hw_setup = gb10b_init_bar2_mm_hw_setup,
511 .remove_bar2_vm = gp10b_remove_bar2_vm,
512 .get_kind_invalid = gm20b_get_kind_invalid,
513 .get_kind_pitch = gm20b_get_kind_pitch,
514 },
515 .pramin = {
516 .enter = gk20a_pramin_enter,
517 .exit = gk20a_pramin_exit,
518 .data032_r = pram_data032_r,
519 },
520 .therm = {
521 .init_therm_setup_hw = gp10b_init_therm_setup_hw,
522 .elcg_init_idle_filters = gp10b_elcg_init_idle_filters,
523 },
524 .pmu = {
525 .pmu_setup_elpg = gp10b_pmu_setup_elpg,
526 .pmu_get_queue_head = pwr_pmu_queue_head_r,
527 .pmu_get_queue_head_size = pwr_pmu_queue_head__size_1_v,
528 .pmu_get_queue_tail = pwr_pmu_queue_tail_r,
529 .pmu_get_queue_tail_size = pwr_pmu_queue_tail__size_1_v,
530 .pmu_queue_head = gk20a_pmu_queue_head,
531 .pmu_queue_tail = gk20a_pmu_queue_tail,
532 .pmu_msgq_tail = gk20a_pmu_msgq_tail,
533 .pmu_mutex_size = pwr_pmu_mutex__size_1_v,
534 .pmu_mutex_acquire = gk20a_pmu_mutex_acquire,
535 .pmu_mutex_release = gk20a_pmu_mutex_release,
536 .write_dmatrfbase = gp10b_write_dmatrfbase,
537 .pmu_elpg_statistics = gp10b_pmu_elpg_statistics,
538 .pmu_pg_init_param = gp10b_pg_gr_init,
539 .pmu_pg_supported_engines_list = gk20a_pmu_pg_engines_list,
540 .pmu_pg_engines_feature_list = gk20a_pmu_pg_feature_list,
541 .dump_secure_fuses = pmu_dump_security_fuses_gp10b,
542 .reset_engine = gk20a_pmu_engine_reset,
543 .is_engine_in_reset = gk20a_pmu_is_engine_in_reset,
544 },
545 .regops = {
546 .get_global_whitelist_ranges =
547 gp10b_get_global_whitelist_ranges,
548 .get_global_whitelist_ranges_count =
549 gp10b_get_global_whitelist_ranges_count,
550 .get_context_whitelist_ranges =
551 gp10b_get_context_whitelist_ranges,
552 .get_context_whitelist_ranges_count =
553 gp10b_get_context_whitelist_ranges_count,
554 .get_runcontrol_whitelist = gp10b_get_runcontrol_whitelist,
555 .get_runcontrol_whitelist_count =
556 gp10b_get_runcontrol_whitelist_count,
557 .get_runcontrol_whitelist_ranges =
558 gp10b_get_runcontrol_whitelist_ranges,
559 .get_runcontrol_whitelist_ranges_count =
560 gp10b_get_runcontrol_whitelist_ranges_count,
561 .get_qctl_whitelist = gp10b_get_qctl_whitelist,
562 .get_qctl_whitelist_count = gp10b_get_qctl_whitelist_count,
563 .get_qctl_whitelist_ranges = gp10b_get_qctl_whitelist_ranges,
564 .get_qctl_whitelist_ranges_count =
565 gp10b_get_qctl_whitelist_ranges_count,
566 .apply_smpc_war = gp10b_apply_smpc_war,
567 },
568 .mc = {
569 .intr_enable = mc_gp10b_intr_enable,
570 .intr_unit_config = mc_gp10b_intr_unit_config,
571 .isr_stall = mc_gp10b_isr_stall,
572 .intr_stall = mc_gp10b_intr_stall,
573 .intr_stall_pause = mc_gp10b_intr_stall_pause,
574 .intr_stall_resume = mc_gp10b_intr_stall_resume,
575 .intr_nonstall = mc_gp10b_intr_nonstall,
576 .intr_nonstall_pause = mc_gp10b_intr_nonstall_pause,
577 .intr_nonstall_resume = mc_gp10b_intr_nonstall_resume,
578 .enable = gk20a_mc_enable,
579 .disable = gk20a_mc_disable,
580 .reset = gk20a_mc_reset,
581 .boot_0 = gk20a_mc_boot_0,
582 .is_intr1_pending = mc_gp10b_is_intr1_pending,
583 },
584 .debug = {
585 .show_dump = gk20a_debug_show_dump,
586 },
587 .dbg_session_ops = {
588 .exec_reg_ops = exec_regops_gk20a,
589 .dbg_set_powergate = dbg_set_powergate,
590 .check_and_set_global_reservation =
591 nvgpu_check_and_set_global_reservation,
592 .check_and_set_context_reservation =
593 nvgpu_check_and_set_context_reservation,
594 .release_profiler_reservation =
595 nvgpu_release_profiler_reservation,
596 .perfbuffer_enable = gk20a_perfbuf_enable_locked,
597 .perfbuffer_disable = gk20a_perfbuf_disable_locked,
598 },
599 .bus = {
600 .init_hw = gk20a_bus_init_hw,
601 .isr = gk20a_bus_isr,
602 .read_ptimer = gk20a_read_ptimer,
603 .get_timestamps_zipper = nvgpu_get_timestamps_zipper,
604 .bar1_bind = gk20a_bus_bar1_bind,
605 },
606#if defined(CONFIG_GK20A_CYCLE_STATS)
607 .css = {
608 .enable_snapshot = css_hw_enable_snapshot,
609 .disable_snapshot = css_hw_disable_snapshot,
610 .check_data_available = css_hw_check_data_available,
611 .set_handled_snapshots = css_hw_set_handled_snapshots,
612 .allocate_perfmon_ids = css_gr_allocate_perfmon_ids,
613 .release_perfmon_ids = css_gr_release_perfmon_ids,
614 },
615#endif
616 .falcon = {
617 .falcon_hal_sw_init = gk20a_falcon_hal_sw_init,
618 },
619 .priv_ring = {
620 .isr = gp10b_priv_ring_isr,
621 },
622 .chip_init_gpu_characteristics = gp10b_init_gpu_characteristics,
623 .get_litter_value = gp10b_get_litter_value,
624};
625
626int gp10b_init_hal(struct gk20a *g)
627{
628 struct gpu_ops *gops = &g->ops;
629 u32 val;
630
631 gops->ltc = gp10b_ops.ltc;
632 gops->ce2 = gp10b_ops.ce2;
633 gops->gr = gp10b_ops.gr;
634 gops->fb = gp10b_ops.fb;
635 gops->clock_gating = gp10b_ops.clock_gating;
636 gops->fifo = gp10b_ops.fifo;
637 gops->gr_ctx = gp10b_ops.gr_ctx;
638#ifdef CONFIG_GK20A_CTXSW_TRACE
639 gops->fecs_trace = gp10b_ops.fecs_trace;
640#endif
641 gops->mm = gp10b_ops.mm;
642 gops->pramin = gp10b_ops.pramin;
643 gops->therm = gp10b_ops.therm;
644 gops->pmu = gp10b_ops.pmu;
645 gops->regops = gp10b_ops.regops;
646 gops->mc = gp10b_ops.mc;
647 gops->debug = gp10b_ops.debug;
648 gops->dbg_session_ops = gp10b_ops.dbg_session_ops;
649 gops->bus = gp10b_ops.bus;
650#if defined(CONFIG_GK20A_CYCLE_STATS)
651 gops->css = gp10b_ops.css;
652#endif
653 gops->falcon = gp10b_ops.falcon;
654
655 gops->priv_ring = gp10b_ops.priv_ring;
656
657 /* Lone Functions */
658 gops->chip_init_gpu_characteristics =
659 gp10b_ops.chip_init_gpu_characteristics;
660 gops->get_litter_value = gp10b_ops.get_litter_value;
661
662 __nvgpu_set_enabled(g, NVGPU_GR_USE_DMA_FOR_FW_BOOTSTRAP, true);
663 __nvgpu_set_enabled(g, NVGPU_PMU_PSTATE, false);
664
665#ifdef CONFIG_TEGRA_ACR
666 if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
667 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false);
668 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false);
669 } else if (g->is_virtual) {
670 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true);
671 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true);
672 } else {
673 val = gk20a_readl(g, fuse_opt_priv_sec_en_r());
674 if (val) {
675 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true);
676 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true);
677 } else {
678 gk20a_dbg_info("priv security is disabled in HW");
679 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false);
680 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false);
681 }
682 }
683#else
684 if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
685 gk20a_dbg_info("running simulator with PRIV security disabled");
686 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false);
687 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false);
688 } else {
689 val = gk20a_readl(g, fuse_opt_priv_sec_en_r());
690 if (val) {
691 gk20a_dbg_info("priv security is not supported but enabled");
692 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, true);
693 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, true);
694 return -EPERM;
695 } else {
696 __nvgpu_set_enabled(g, NVGPU_SEC_PRIVSECURITY, false);
697 __nvgpu_set_enabled(g, NVGPU_SEC_SECUREGPCCS, false);
698 }
699 }
700#endif
701
702 /* priv security dependent ops */
703 if (nvgpu_is_enabled(g, NVGPU_SEC_PRIVSECURITY)) {
704 /* Add in ops from gm20b acr */
705 gops->pmu.is_pmu_supported = gm20b_is_pmu_supported,
706 gops->pmu.prepare_ucode = prepare_ucode_blob,
707 gops->pmu.pmu_setup_hw_and_bootstrap = gm20b_bootstrap_hs_flcn,
708 gops->pmu.is_lazy_bootstrap = gm20b_is_lazy_bootstrap,
709 gops->pmu.is_priv_load = gm20b_is_priv_load,
710 gops->pmu.get_wpr = gm20b_wpr_info,
711 gops->pmu.alloc_blob_space = gm20b_alloc_blob_space,
712 gops->pmu.pmu_populate_loader_cfg =
713 gm20b_pmu_populate_loader_cfg,
714 gops->pmu.flcn_populate_bl_dmem_desc =
715 gm20b_flcn_populate_bl_dmem_desc,
716 gops->pmu.falcon_wait_for_halt = pmu_wait_for_halt,
717 gops->pmu.falcon_clear_halt_interrupt_status =
718 clear_halt_interrupt_status,
719 gops->pmu.init_falcon_setup_hw = gm20b_init_pmu_setup_hw1,
720
721 gops->pmu.init_wpr_region = gm20b_pmu_init_acr;
722 gops->pmu.load_lsfalcon_ucode = gp10b_load_falcon_ucode;
723 gops->pmu.is_lazy_bootstrap = gp10b_is_lazy_bootstrap;
724 gops->pmu.is_priv_load = gp10b_is_priv_load;
725
726 gops->gr.load_ctxsw_ucode = gr_gm20b_load_ctxsw_ucode;
727 } else {
728 /* Inherit from gk20a */
729 gops->pmu.is_pmu_supported = gk20a_is_pmu_supported,
730 gops->pmu.prepare_ucode = nvgpu_pmu_prepare_ns_ucode_blob,
731 gops->pmu.pmu_setup_hw_and_bootstrap = gk20a_init_pmu_setup_hw1,
732 gops->pmu.pmu_nsbootstrap = pmu_bootstrap,
733
734 gops->pmu.load_lsfalcon_ucode = NULL;
735 gops->pmu.init_wpr_region = NULL;
736 gops->pmu.pmu_setup_hw_and_bootstrap = gp10b_init_pmu_setup_hw1;
737
738 gops->gr.load_ctxsw_ucode = gr_gk20a_load_ctxsw_ucode;
739 }
740
741 __nvgpu_set_enabled(g, NVGPU_PMU_FECS_BOOTSTRAP_DONE, false);
742 g->pmu_lsf_pmu_wpr_init_done = 0;
743 g->bootstrap_owner = LSF_BOOTSTRAP_OWNER_DEFAULT;
744
745 g->name = "gp10b";
746
747 return 0;
748}
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.h b/drivers/gpu/nvgpu/gp10b/hal_gp10b.h
new file mode 100644
index 00000000..cf3c295d
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.h
@@ -0,0 +1,31 @@
1/*
2 * GP10B Tegra HAL interface
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef _NVGPU_HAL_GP10B_H
26#define _NVGPU_HAL_GP10B_H
27struct gk20a;
28
29int gp10b_init_hal(struct gk20a *gops);
30int gp10b_get_litter_value(struct gk20a *g, int value);
31#endif
diff --git a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
new file mode 100644
index 00000000..92a899b8
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.c
@@ -0,0 +1,226 @@
1/*
2 * GP10B L2
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <dt-bindings/memory/tegra-swgroup.h>
26
27#include <nvgpu/ltc.h>
28#include <nvgpu/log.h>
29#include <nvgpu/enabled.h>
30
31#include <nvgpu/hw/gp10b/hw_mc_gp10b.h>
32#include <nvgpu/hw/gp10b/hw_ltc_gp10b.h>
33
34#include "gk20a/gk20a.h"
35#include "gm20b/ltc_gm20b.h"
36
37#include "ltc_gp10b.h"
38
39int gp10b_determine_L2_size_bytes(struct gk20a *g)
40{
41 u32 tmp;
42 int ret;
43
44 gk20a_dbg_fn("");
45
46 tmp = gk20a_readl(g, ltc_ltc0_lts0_tstg_info_1_r());
47
48 ret = g->ltc_count *
49 ltc_ltc0_lts0_tstg_info_1_slice_size_in_kb_v(tmp)*1024 *
50 ltc_ltc0_lts0_tstg_info_1_slices_per_l2_v(tmp);
51
52 gk20a_dbg(gpu_dbg_info, "L2 size: %d\n", ret);
53
54 gk20a_dbg_fn("done");
55
56 return ret;
57}
58
59int gp10b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr)
60{
61 /* max memory size (MB) to cover */
62 u32 max_size = gr->max_comptag_mem;
63 /* one tag line covers 64KB */
64 u32 max_comptag_lines = max_size << 4;
65
66 u32 hw_max_comptag_lines =
67 ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v();
68
69 u32 cbc_param =
70 gk20a_readl(g, ltc_ltcs_ltss_cbc_param_r());
71 u32 comptags_per_cacheline =
72 ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(cbc_param);
73 u32 cacheline_size =
74 512 << ltc_ltcs_ltss_cbc_param_cache_line_size_v(cbc_param);
75 u32 slices_per_ltc =
76 ltc_ltcs_ltss_cbc_param_slices_per_ltc_v(cbc_param);
77 u32 cbc_param2 =
78 gk20a_readl(g, ltc_ltcs_ltss_cbc_param2_r());
79 u32 gobs_per_comptagline_per_slice =
80 ltc_ltcs_ltss_cbc_param2_gobs_per_comptagline_per_slice_v(cbc_param2);
81
82 u32 compbit_backing_size;
83
84 int err;
85
86 gk20a_dbg_fn("");
87
88 if (max_comptag_lines == 0)
89 return 0;
90
91 if (max_comptag_lines > hw_max_comptag_lines)
92 max_comptag_lines = hw_max_comptag_lines;
93
94 compbit_backing_size =
95 roundup(max_comptag_lines * gobs_per_comptagline_per_slice,
96 cacheline_size);
97 compbit_backing_size =
98 roundup(compbit_backing_size * slices_per_ltc * g->ltc_count,
99 g->ops.fb.compressible_page_size(g));
100
101 /* aligned to 2KB * ltc_count */
102 compbit_backing_size +=
103 g->ltc_count << ltc_ltcs_ltss_cbc_base_alignment_shift_v();
104
105 /* must be a multiple of 64KB */
106 compbit_backing_size = roundup(compbit_backing_size, 64*1024);
107
108 gk20a_dbg_info("compbit backing store size : %d",
109 compbit_backing_size);
110 gk20a_dbg_info("max comptag lines : %d",
111 max_comptag_lines);
112 gk20a_dbg_info("gobs_per_comptagline_per_slice: %d",
113 gobs_per_comptagline_per_slice);
114
115 err = nvgpu_ltc_alloc_cbc(g, compbit_backing_size);
116 if (err)
117 return err;
118
119 err = gk20a_comptag_allocator_init(g, &gr->comp_tags, max_comptag_lines);
120 if (err)
121 return err;
122
123 gr->comptags_per_cacheline = comptags_per_cacheline;
124 gr->slices_per_ltc = slices_per_ltc;
125 gr->cacheline_size = cacheline_size;
126 gr->gobs_per_comptagline_per_slice = gobs_per_comptagline_per_slice;
127
128 return 0;
129}
130
131void gp10b_ltc_isr(struct gk20a *g)
132{
133 u32 mc_intr, ltc_intr;
134 unsigned int ltc, slice;
135 u32 ltc_stride = nvgpu_get_litter_value(g, GPU_LIT_LTC_STRIDE);
136 u32 lts_stride = nvgpu_get_litter_value(g, GPU_LIT_LTS_STRIDE);
137
138 mc_intr = gk20a_readl(g, mc_intr_ltc_r());
139 nvgpu_err(g, "mc_ltc_intr: %08x", mc_intr);
140 for (ltc = 0; ltc < g->ltc_count; ltc++) {
141 if ((mc_intr & 1 << ltc) == 0)
142 continue;
143 for (slice = 0; slice < g->gr.slices_per_ltc; slice++) {
144 u32 offset = ltc_stride * ltc + lts_stride * slice;
145 ltc_intr = gk20a_readl(g, ltc_ltc0_lts0_intr_r() + offset);
146
147 /* Detect and handle ECC errors */
148 if (ltc_intr &
149 ltc_ltcs_ltss_intr_ecc_sec_error_pending_f()) {
150 u32 ecc_stats_reg_val;
151
152 nvgpu_err(g,
153 "Single bit error detected in GPU L2!");
154
155 ecc_stats_reg_val =
156 gk20a_readl(g,
157 ltc_ltc0_lts0_dstg_ecc_report_r() + offset);
158 g->ecc.gr.t18x.l2_sec_count.counters[ltc] +=
159 ltc_ltc0_lts0_dstg_ecc_report_sec_count_v(ecc_stats_reg_val);
160 ecc_stats_reg_val &=
161 ~(ltc_ltc0_lts0_dstg_ecc_report_sec_count_m());
162 gk20a_writel(g,
163 ltc_ltc0_lts0_dstg_ecc_report_r() + offset,
164 ecc_stats_reg_val);
165
166 g->ops.mm.l2_flush(g, true);
167 }
168 if (ltc_intr &
169 ltc_ltcs_ltss_intr_ecc_ded_error_pending_f()) {
170 u32 ecc_stats_reg_val;
171
172 nvgpu_err(g,
173 "Double bit error detected in GPU L2!");
174
175 ecc_stats_reg_val =
176 gk20a_readl(g,
177 ltc_ltc0_lts0_dstg_ecc_report_r() + offset);
178 g->ecc.gr.t18x.l2_ded_count.counters[ltc] +=
179 ltc_ltc0_lts0_dstg_ecc_report_ded_count_v(ecc_stats_reg_val);
180 ecc_stats_reg_val &=
181 ~(ltc_ltc0_lts0_dstg_ecc_report_ded_count_m());
182 gk20a_writel(g,
183 ltc_ltc0_lts0_dstg_ecc_report_r() + offset,
184 ecc_stats_reg_val);
185 }
186
187 nvgpu_err(g, "ltc%d, slice %d: %08x",
188 ltc, slice, ltc_intr);
189 gk20a_writel(g, ltc_ltc0_lts0_intr_r() +
190 ltc_stride * ltc + lts_stride * slice,
191 ltc_intr);
192 }
193 }
194}
195
196void gp10b_ltc_init_fs_state(struct gk20a *g)
197{
198 u32 ltc_intr;
199
200 gm20b_ltc_init_fs_state(g);
201
202 gk20a_writel(g, ltc_ltca_g_axi_pctrl_r(),
203 ltc_ltca_g_axi_pctrl_user_sid_f(TEGRA_SID_GPUB));
204
205 /* Enable ECC interrupts */
206 ltc_intr = gk20a_readl(g, ltc_ltcs_ltss_intr_r());
207 ltc_intr |= ltc_ltcs_ltss_intr_en_ecc_sec_error_enabled_f() |
208 ltc_ltcs_ltss_intr_en_ecc_ded_error_enabled_f();
209 gk20a_writel(g, ltc_ltcs_ltss_intr_r(),
210 ltc_intr);
211}
212
213void gp10b_ltc_set_enabled(struct gk20a *g, bool enabled)
214{
215 u32 reg_f = ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f();
216 u32 reg = gk20a_readl(g, ltc_ltcs_ltss_tstg_set_mgmt_2_r());
217
218 if (enabled)
219 /* bypass disabled (normal caching ops)*/
220 reg &= ~reg_f;
221 else
222 /* bypass enabled (no caching) */
223 reg |= reg_f;
224
225 gk20a_writel(g, ltc_ltcs_ltss_tstg_set_mgmt_2_r(), reg);
226}
diff --git a/drivers/gpu/nvgpu/gp10b/ltc_gp10b.h b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.h
new file mode 100644
index 00000000..825204cb
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/ltc_gp10b.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef LTC_GP10B_H
24#define LTC_GP10B_H
25struct gpu_ops;
26
27void gp10b_ltc_isr(struct gk20a *g);
28
29int gp10b_determine_L2_size_bytes(struct gk20a *g);
30int gp10b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr);
31void gp10b_ltc_init_fs_state(struct gk20a *g);
32void gp10b_ltc_set_enabled(struct gk20a *g, bool enabled);
33#endif
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c
new file mode 100644
index 00000000..9aea76f9
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c
@@ -0,0 +1,185 @@
1/*
2 * GP10B master
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26#include "gk20a/mc_gk20a.h"
27
28#include "mc_gp10b.h"
29
30#include <nvgpu/atomic.h>
31#include <nvgpu/unit.h>
32
33#include <nvgpu/hw/gp10b/hw_mc_gp10b.h>
34
35void mc_gp10b_intr_enable(struct gk20a *g)
36{
37 u32 eng_intr_mask = gk20a_fifo_engine_interrupt_mask(g);
38
39 gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_STALLING),
40 0xffffffff);
41 g->mc_intr_mask_restore[NVGPU_MC_INTR_STALLING] =
42 mc_intr_pfifo_pending_f() |
43 mc_intr_priv_ring_pending_f() |
44 mc_intr_pbus_pending_f() |
45 mc_intr_ltc_pending_f() |
46 mc_intr_replayable_fault_pending_f() |
47 eng_intr_mask;
48 gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_STALLING),
49 g->mc_intr_mask_restore[NVGPU_MC_INTR_STALLING]);
50
51 gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_NONSTALLING),
52 0xffffffff);
53 g->mc_intr_mask_restore[NVGPU_MC_INTR_NONSTALLING] =
54 mc_intr_pfifo_pending_f() |
55 eng_intr_mask;
56 gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING),
57 g->mc_intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]);
58}
59
60void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable,
61 bool is_stalling, u32 mask)
62{
63 u32 intr_index = 0;
64 u32 reg = 0;
65
66 intr_index = (is_stalling ? NVGPU_MC_INTR_STALLING :
67 NVGPU_MC_INTR_NONSTALLING);
68 if (enable) {
69 reg = mc_intr_en_set_r(intr_index);
70 g->mc_intr_mask_restore[intr_index] |= mask;
71
72 } else {
73 reg = mc_intr_en_clear_r(intr_index);
74 g->mc_intr_mask_restore[intr_index] &= ~mask;
75 }
76
77 gk20a_writel(g, reg, mask);
78}
79
80void mc_gp10b_isr_stall(struct gk20a *g)
81{
82 u32 mc_intr_0;
83
84 u32 engine_id_idx;
85 u32 active_engine_id = 0;
86 u32 engine_enum = ENGINE_INVAL_GK20A;
87
88 mc_intr_0 = gk20a_readl(g, mc_intr_r(0));
89
90 gk20a_dbg(gpu_dbg_intr, "stall intr 0x%08x\n", mc_intr_0);
91
92 for (engine_id_idx = 0; engine_id_idx < g->fifo.num_engines; engine_id_idx++) {
93 active_engine_id = g->fifo.active_engines_list[engine_id_idx];
94
95 if (mc_intr_0 & g->fifo.engine_info[active_engine_id].intr_mask) {
96 engine_enum = g->fifo.engine_info[active_engine_id].engine_enum;
97 /* GR Engine */
98 if (engine_enum == ENGINE_GR_GK20A) {
99 gr_gk20a_elpg_protected_call(g, gk20a_gr_isr(g));
100 }
101
102 /* CE Engine */
103 if (((engine_enum == ENGINE_GRCE_GK20A) ||
104 (engine_enum == ENGINE_ASYNC_CE_GK20A)) &&
105 g->ops.ce2.isr_stall){
106 g->ops.ce2.isr_stall(g,
107 g->fifo.engine_info[active_engine_id].inst_id,
108 g->fifo.engine_info[active_engine_id].pri_base);
109 }
110 }
111 }
112 if (g->ops.mc.is_intr_hub_pending &&
113 g->ops.mc.is_intr_hub_pending(g, mc_intr_0))
114 g->ops.fb.hub_isr(g);
115 if (mc_intr_0 & mc_intr_pfifo_pending_f())
116 gk20a_fifo_isr(g);
117 if (mc_intr_0 & mc_intr_pmu_pending_f())
118 gk20a_pmu_isr(g);
119 if (mc_intr_0 & mc_intr_priv_ring_pending_f())
120 g->ops.priv_ring.isr(g);
121 if (mc_intr_0 & mc_intr_ltc_pending_f())
122 g->ops.ltc.isr(g);
123 if (mc_intr_0 & mc_intr_pbus_pending_f())
124 g->ops.bus.isr(g);
125
126 gk20a_dbg(gpu_dbg_intr, "stall intr done 0x%08x\n", mc_intr_0);
127
128}
129
130u32 mc_gp10b_intr_stall(struct gk20a *g)
131{
132 return gk20a_readl(g, mc_intr_r(NVGPU_MC_INTR_STALLING));
133}
134
135void mc_gp10b_intr_stall_pause(struct gk20a *g)
136{
137 gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_STALLING), 0xffffffff);
138}
139
140void mc_gp10b_intr_stall_resume(struct gk20a *g)
141{
142 gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_STALLING),
143 g->mc_intr_mask_restore[NVGPU_MC_INTR_STALLING]);
144}
145
146u32 mc_gp10b_intr_nonstall(struct gk20a *g)
147{
148 return gk20a_readl(g, mc_intr_r(NVGPU_MC_INTR_NONSTALLING));
149}
150
151void mc_gp10b_intr_nonstall_pause(struct gk20a *g)
152{
153 gk20a_writel(g, mc_intr_en_clear_r(NVGPU_MC_INTR_NONSTALLING),
154 0xffffffff);
155}
156
157void mc_gp10b_intr_nonstall_resume(struct gk20a *g)
158{
159 gk20a_writel(g, mc_intr_en_set_r(NVGPU_MC_INTR_NONSTALLING),
160 g->mc_intr_mask_restore[NVGPU_MC_INTR_NONSTALLING]);
161}
162
163bool mc_gp10b_is_intr1_pending(struct gk20a *g,
164 enum nvgpu_unit unit, u32 mc_intr_1)
165{
166 u32 mask = 0;
167 bool is_pending;
168
169 switch (unit) {
170 case NVGPU_UNIT_FIFO:
171 mask = mc_intr_pfifo_pending_f();
172 break;
173 default:
174 break;
175 }
176
177 if (mask == 0) {
178 nvgpu_err(g, "unknown unit %d", unit);
179 is_pending = false;
180 } else {
181 is_pending = (mc_intr_1 & mask) ? true : false;
182 }
183
184 return is_pending;
185}
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.h b/drivers/gpu/nvgpu/gp10b/mc_gp10b.h
new file mode 100644
index 00000000..0eb4dd16
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef MC_GP20B_H
24#define MC_GP20B_H
25struct gk20a;
26
27enum MC_INTERRUPT_REGLIST {
28 NVGPU_MC_INTR_STALLING = 0,
29 NVGPU_MC_INTR_NONSTALLING,
30};
31
32void mc_gp10b_intr_enable(struct gk20a *g);
33void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable,
34 bool is_stalling, u32 mask);
35void mc_gp10b_isr_stall(struct gk20a *g);
36bool mc_gp10b_is_intr1_pending(struct gk20a *g,
37 enum nvgpu_unit unit, u32 mc_intr_1);
38
39u32 mc_gp10b_intr_stall(struct gk20a *g);
40void mc_gp10b_intr_stall_pause(struct gk20a *g);
41void mc_gp10b_intr_stall_resume(struct gk20a *g);
42u32 mc_gp10b_intr_nonstall(struct gk20a *g);
43void mc_gp10b_intr_nonstall_pause(struct gk20a *g);
44void mc_gp10b_intr_nonstall_resume(struct gk20a *g);
45
46#endif
diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
new file mode 100644
index 00000000..4b985af4
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
@@ -0,0 +1,446 @@
1/*
2 * GP10B MMU
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <nvgpu/mm.h>
26#include <nvgpu/dma.h>
27#include <nvgpu/gmmu.h>
28
29#include "gk20a/gk20a.h"
30#include "gm20b/mm_gm20b.h"
31#include "mm_gp10b.h"
32#include "rpfb_gp10b.h"
33
34#include <nvgpu/hw/gp10b/hw_fb_gp10b.h>
35#include <nvgpu/hw/gp10b/hw_ram_gp10b.h>
36#include <nvgpu/hw/gp10b/hw_bus_gp10b.h>
37#include <nvgpu/hw/gp10b/hw_gmmu_gp10b.h>
38
39u32 gp10b_mm_get_default_big_page_size(void)
40{
41 return SZ_64K;
42}
43
44u32 gp10b_mm_get_iommu_bit(struct gk20a *g)
45{
46 return 36;
47}
48
49int gp10b_init_mm_setup_hw(struct gk20a *g)
50{
51 struct mm_gk20a *mm = &g->mm;
52 struct nvgpu_mem *inst_block = &mm->bar1.inst_block;
53 int err = 0;
54
55 gk20a_dbg_fn("");
56
57 g->ops.fb.set_mmu_page_size(g);
58
59 gk20a_writel(g, fb_niso_flush_sysmem_addr_r(),
60 nvgpu_mem_get_addr(g, &g->mm.sysmem_flush) >> 8ULL);
61
62 g->ops.bus.bar1_bind(g, inst_block);
63
64 if (g->ops.mm.init_bar2_mm_hw_setup) {
65 err = g->ops.mm.init_bar2_mm_hw_setup(g);
66 if (err)
67 return err;
68 }
69
70 if (gk20a_mm_fb_flush(g) || gk20a_mm_fb_flush(g))
71 return -EBUSY;
72
73 err = gp10b_replayable_pagefault_buffer_init(g);
74
75 gk20a_dbg_fn("done");
76 return err;
77
78}
79
80int gb10b_init_bar2_vm(struct gk20a *g)
81{
82 int err;
83 struct mm_gk20a *mm = &g->mm;
84 struct nvgpu_mem *inst_block = &mm->bar2.inst_block;
85 u32 big_page_size = g->ops.mm.get_default_big_page_size();
86
87 /* BAR2 aperture size is 32MB */
88 mm->bar2.aperture_size = 32 << 20;
89 gk20a_dbg_info("bar2 vm size = 0x%x", mm->bar2.aperture_size);
90
91 mm->bar2.vm = nvgpu_vm_init(g, big_page_size, SZ_4K,
92 mm->bar2.aperture_size - SZ_4K,
93 mm->bar2.aperture_size, false, false, "bar2");
94 if (!mm->bar2.vm)
95 return -ENOMEM;
96
97 /* allocate instance mem for bar2 */
98 err = g->ops.mm.alloc_inst_block(g, inst_block);
99 if (err)
100 goto clean_up_va;
101
102 g->ops.mm.init_inst_block(inst_block, mm->bar2.vm, big_page_size);
103
104 return 0;
105
106clean_up_va:
107 nvgpu_vm_put(mm->bar2.vm);
108 return err;
109}
110
111int gb10b_init_bar2_mm_hw_setup(struct gk20a *g)
112{
113 struct mm_gk20a *mm = &g->mm;
114 struct nvgpu_mem *inst_block = &mm->bar2.inst_block;
115 u64 inst_pa = nvgpu_inst_block_addr(g, inst_block);
116
117 gk20a_dbg_fn("");
118
119 g->ops.fb.set_mmu_page_size(g);
120
121 inst_pa = (u32)(inst_pa >> bus_bar2_block_ptr_shift_v());
122 gk20a_dbg_info("bar2 inst block ptr: 0x%08x", (u32)inst_pa);
123
124 gk20a_writel(g, bus_bar2_block_r(),
125 nvgpu_aperture_mask(g, inst_block,
126 bus_bar2_block_target_sys_mem_ncoh_f(),
127 bus_bar2_block_target_vid_mem_f()) |
128 bus_bar2_block_mode_virtual_f() |
129 bus_bar2_block_ptr_f(inst_pa));
130
131 gk20a_dbg_fn("done");
132 return 0;
133}
134
135static void update_gmmu_pde3_locked(struct vm_gk20a *vm,
136 const struct gk20a_mmu_level *l,
137 struct nvgpu_gmmu_pd *pd,
138 u32 pd_idx,
139 u64 virt_addr,
140 u64 phys_addr,
141 struct nvgpu_gmmu_attrs *attrs)
142{
143 struct gk20a *g = gk20a_from_vm(vm);
144 u32 pd_offset = pd_offset_from_index(l, pd_idx);
145 u32 pde_v[2] = {0, 0};
146
147 phys_addr >>= gmmu_new_pde_address_shift_v();
148
149 pde_v[0] |= nvgpu_aperture_mask(g, pd->mem,
150 gmmu_new_pde_aperture_sys_mem_ncoh_f(),
151 gmmu_new_pde_aperture_video_memory_f());
152 pde_v[0] |= gmmu_new_pde_address_sys_f(u64_lo32(phys_addr));
153 pde_v[0] |= gmmu_new_pde_vol_true_f();
154 pde_v[1] |= phys_addr >> 24;
155
156 pd_write(g, pd, pd_offset + 0, pde_v[0]);
157 pd_write(g, pd, pd_offset + 1, pde_v[1]);
158
159 pte_dbg(g, attrs,
160 "PDE: i=%-4u size=%-2u offs=%-4u pgsz: -- | "
161 "GPU %#-12llx phys %#-12llx "
162 "[0x%08x, 0x%08x]",
163 pd_idx, l->entry_size, pd_offset,
164 virt_addr, phys_addr,
165 pde_v[1], pde_v[0]);
166}
167
168static void update_gmmu_pde0_locked(struct vm_gk20a *vm,
169 const struct gk20a_mmu_level *l,
170 struct nvgpu_gmmu_pd *pd,
171 u32 pd_idx,
172 u64 virt_addr,
173 u64 phys_addr,
174 struct nvgpu_gmmu_attrs *attrs)
175{
176 struct gk20a *g = gk20a_from_vm(vm);
177 bool small_valid, big_valid;
178 u32 small_addr = 0, big_addr = 0;
179 u32 pd_offset = pd_offset_from_index(l, pd_idx);
180 u32 pde_v[4] = {0, 0, 0, 0};
181
182 small_valid = attrs->pgsz == gmmu_page_size_small;
183 big_valid = attrs->pgsz == gmmu_page_size_big;
184
185 if (small_valid)
186 small_addr = phys_addr >> gmmu_new_dual_pde_address_shift_v();
187
188 if (big_valid)
189 big_addr = phys_addr >> gmmu_new_dual_pde_address_big_shift_v();
190
191 if (small_valid) {
192 pde_v[2] |=
193 gmmu_new_dual_pde_address_small_sys_f(small_addr);
194 pde_v[2] |= nvgpu_aperture_mask(g, pd->mem,
195 gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f(),
196 gmmu_new_dual_pde_aperture_small_video_memory_f());
197 pde_v[2] |= gmmu_new_dual_pde_vol_small_true_f();
198 pde_v[3] |= small_addr >> 24;
199 }
200
201 if (big_valid) {
202 pde_v[0] |= gmmu_new_dual_pde_address_big_sys_f(big_addr);
203 pde_v[0] |= gmmu_new_dual_pde_vol_big_true_f();
204 pde_v[0] |= nvgpu_aperture_mask(g, pd->mem,
205 gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f(),
206 gmmu_new_dual_pde_aperture_big_video_memory_f());
207 pde_v[1] |= big_addr >> 28;
208 }
209
210 pd_write(g, pd, pd_offset + 0, pde_v[0]);
211 pd_write(g, pd, pd_offset + 1, pde_v[1]);
212 pd_write(g, pd, pd_offset + 2, pde_v[2]);
213 pd_write(g, pd, pd_offset + 3, pde_v[3]);
214
215 pte_dbg(g, attrs,
216 "PDE: i=%-4u size=%-2u offs=%-4u pgsz: %c%c | "
217 "GPU %#-12llx phys %#-12llx "
218 "[0x%08x, 0x%08x, 0x%08x, 0x%08x]",
219 pd_idx, l->entry_size, pd_offset,
220 small_valid ? 'S' : '-',
221 big_valid ? 'B' : '-',
222 virt_addr, phys_addr,
223 pde_v[3], pde_v[2], pde_v[1], pde_v[0]);
224}
225
226static void __update_pte(struct vm_gk20a *vm,
227 u32 *pte_w,
228 u64 phys_addr,
229 struct nvgpu_gmmu_attrs *attrs)
230{
231 struct gk20a *g = gk20a_from_vm(vm);
232 u64 ctag_granularity = g->ops.fb.compression_page_size(g);
233 u32 page_size = vm->gmmu_page_sizes[attrs->pgsz];
234 u32 pte_valid = attrs->valid ?
235 gmmu_new_pte_valid_true_f() :
236 gmmu_new_pte_valid_false_f();
237 u32 phys_shifted = phys_addr >> gmmu_new_pte_address_shift_v();
238 u32 pte_addr = attrs->aperture == APERTURE_SYSMEM ?
239 gmmu_new_pte_address_sys_f(phys_shifted) :
240 gmmu_new_pte_address_vid_f(phys_shifted);
241 u32 pte_tgt = __nvgpu_aperture_mask(g,
242 attrs->aperture,
243 attrs->coherent ?
244 gmmu_new_pte_aperture_sys_mem_coh_f() :
245 gmmu_new_pte_aperture_sys_mem_ncoh_f(),
246 gmmu_new_pte_aperture_video_memory_f());
247
248 pte_w[0] = pte_valid | pte_addr | pte_tgt;
249
250 if (attrs->priv)
251 pte_w[0] |= gmmu_new_pte_privilege_true_f();
252
253 pte_w[1] = phys_addr >> (24 + gmmu_new_pte_address_shift_v()) |
254 gmmu_new_pte_kind_f(attrs->kind_v) |
255 gmmu_new_pte_comptagline_f((u32)(attrs->ctag /
256 ctag_granularity));
257
258 if (attrs->rw_flag == gk20a_mem_flag_read_only)
259 pte_w[0] |= gmmu_new_pte_read_only_true_f();
260
261 if (!attrs->valid && !attrs->cacheable)
262 pte_w[0] |= gmmu_new_pte_read_only_true_f();
263 else if (!attrs->cacheable)
264 pte_w[0] |= gmmu_new_pte_vol_true_f();
265
266 if (attrs->ctag)
267 attrs->ctag += page_size;
268
269}
270
271static void __update_pte_sparse(u32 *pte_w)
272{
273 pte_w[0] = gmmu_new_pte_valid_false_f();
274 pte_w[0] |= gmmu_new_pte_vol_true_f();
275}
276
277static void update_gmmu_pte_locked(struct vm_gk20a *vm,
278 const struct gk20a_mmu_level *l,
279 struct nvgpu_gmmu_pd *pd,
280 u32 pd_idx,
281 u64 virt_addr,
282 u64 phys_addr,
283 struct nvgpu_gmmu_attrs *attrs)
284{
285 struct gk20a *g = vm->mm->g;
286 u32 page_size = vm->gmmu_page_sizes[attrs->pgsz];
287 u32 pd_offset = pd_offset_from_index(l, pd_idx);
288 u32 pte_w[2] = {0, 0};
289
290 if (phys_addr)
291 __update_pte(vm, pte_w, phys_addr, attrs);
292 else if (attrs->sparse)
293 __update_pte_sparse(pte_w);
294
295 pte_dbg(g, attrs,
296 "vm=%s "
297 "PTE: i=%-4u size=%-2u | "
298 "GPU %#-12llx phys %#-12llx "
299 "pgsz: %3dkb perm=%-2s kind=%#02x APT=%-6s %c%c%c%c%c "
300 "ctag=0x%08x "
301 "[0x%08x, 0x%08x]",
302 vm->name,
303 pd_idx, l->entry_size,
304 virt_addr, phys_addr,
305 page_size >> 10,
306 nvgpu_gmmu_perm_str(attrs->rw_flag),
307 attrs->kind_v,
308 nvgpu_aperture_str(attrs->aperture),
309 attrs->cacheable ? 'C' : 'v',
310 attrs->sparse ? 'S' : '-',
311 attrs->priv ? 'P' : '-',
312 attrs->coherent ? 'c' : '-',
313 attrs->valid ? 'V' : '-',
314 (u32)attrs->ctag / g->ops.fb.compression_page_size(g),
315 pte_w[1], pte_w[0]);
316
317 pd_write(g, pd, pd_offset + 0, pte_w[0]);
318 pd_write(g, pd, pd_offset + 1, pte_w[1]);
319}
320
321#define GP10B_PDE0_ENTRY_SIZE 16
322
323/*
324 * Calculate the pgsz of the pde level
325 * Pascal+ implements a 5 level page table structure with only the last
326 * level having a different number of entries depending on whether it holds
327 * big pages or small pages.
328 */
329static enum gmmu_pgsz_gk20a gp10b_get_pde0_pgsz(struct gk20a *g,
330 struct nvgpu_gmmu_pd *pd, u32 pd_idx)
331{
332 u32 pde_base = pd->mem_offs / sizeof(u32);
333 u32 pde_v[GP10B_PDE0_ENTRY_SIZE >> 2];
334 u32 i;
335 enum gmmu_pgsz_gk20a pgsz = gmmu_nr_page_sizes;
336
337 if (!pd->mem)
338 return pgsz;
339
340 nvgpu_mem_begin(g, pd->mem);
341 for (i = 0; i < GP10B_PDE0_ENTRY_SIZE >> 2; i++)
342 pde_v[i] = nvgpu_mem_rd32(g, pd->mem, pde_base + i);
343 nvgpu_mem_end(g, pd->mem);
344
345 /*
346 * Check if the aperture AND address are set
347 */
348 if (pde_v[2] & (gmmu_new_dual_pde_aperture_small_sys_mem_ncoh_f() ||
349 gmmu_new_dual_pde_aperture_small_video_memory_f())) {
350 u64 addr = ((u64) (pde_v[2] &
351 gmmu_new_dual_pde_address_small_sys_f(~0)) <<
352 gmmu_new_dual_pde_address_shift_v()) |
353 ((u64) pde_v[3] << 32);
354
355 if (addr)
356 pgsz = gmmu_page_size_small;
357 }
358
359 if (pde_v[0] & (gmmu_new_dual_pde_aperture_big_sys_mem_ncoh_f() |
360 gmmu_new_dual_pde_aperture_big_video_memory_f())) {
361 u64 addr = ((u64) (pde_v[0] &
362 gmmu_new_dual_pde_address_big_sys_f(~0)) <<
363 gmmu_new_dual_pde_address_big_shift_v()) |
364 ((u64) pde_v[1] << 32);
365 if (addr) {
366 /*
367 * If small is set that means that somehow MM allowed
368 * both small and big to be set, the PDE is not valid
369 * and may be corrupted
370 */
371 if (pgsz == gmmu_page_size_small) {
372 nvgpu_err(g,
373 "both small and big apertures enabled");
374 return gmmu_nr_page_sizes;
375 }
376 }
377 pgsz = gmmu_page_size_big;
378 }
379
380 return pgsz;
381}
382
383static const struct gk20a_mmu_level gp10b_mm_levels[] = {
384 {.hi_bit = {48, 48},
385 .lo_bit = {47, 47},
386 .update_entry = update_gmmu_pde3_locked,
387 .entry_size = 8,
388 .get_pgsz = gk20a_get_pde_pgsz},
389 {.hi_bit = {46, 46},
390 .lo_bit = {38, 38},
391 .update_entry = update_gmmu_pde3_locked,
392 .entry_size = 8,
393 .get_pgsz = gk20a_get_pde_pgsz},
394 {.hi_bit = {37, 37},
395 .lo_bit = {29, 29},
396 .update_entry = update_gmmu_pde3_locked,
397 .entry_size = 8,
398 .get_pgsz = gk20a_get_pde_pgsz},
399 {.hi_bit = {28, 28},
400 .lo_bit = {21, 21},
401 .update_entry = update_gmmu_pde0_locked,
402 .entry_size = GP10B_PDE0_ENTRY_SIZE,
403 .get_pgsz = gp10b_get_pde0_pgsz},
404 {.hi_bit = {20, 20},
405 .lo_bit = {12, 16},
406 .update_entry = update_gmmu_pte_locked,
407 .entry_size = 8,
408 .get_pgsz = gk20a_get_pte_pgsz},
409 {.update_entry = NULL}
410};
411
412const struct gk20a_mmu_level *gp10b_mm_get_mmu_levels(struct gk20a *g,
413 u32 big_page_size)
414{
415 return gp10b_mm_levels;
416}
417
418void gp10b_mm_init_pdb(struct gk20a *g, struct nvgpu_mem *inst_block,
419 struct vm_gk20a *vm)
420{
421 u64 pdb_addr = nvgpu_mem_get_addr(g, vm->pdb.mem);
422 u32 pdb_addr_lo = u64_lo32(pdb_addr >> ram_in_base_shift_v());
423 u32 pdb_addr_hi = u64_hi32(pdb_addr);
424
425 gk20a_dbg_info("pde pa=0x%llx", pdb_addr);
426
427 nvgpu_mem_wr32(g, inst_block, ram_in_page_dir_base_lo_w(),
428 nvgpu_aperture_mask(g, vm->pdb.mem,
429 ram_in_page_dir_base_target_sys_mem_ncoh_f(),
430 ram_in_page_dir_base_target_vid_mem_f()) |
431 ram_in_page_dir_base_vol_true_f() |
432 ram_in_page_dir_base_lo_f(pdb_addr_lo) |
433 1 << 10);
434
435 nvgpu_mem_wr32(g, inst_block, ram_in_page_dir_base_hi_w(),
436 ram_in_page_dir_base_hi_f(pdb_addr_hi));
437}
438
439void gp10b_remove_bar2_vm(struct gk20a *g)
440{
441 struct mm_gk20a *mm = &g->mm;
442
443 gp10b_replayable_pagefault_buffer_deinit(g);
444 nvgpu_free_inst_block(g, &mm->bar2.inst_block);
445 nvgpu_vm_put(mm->bar2.vm);
446}
diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.h b/drivers/gpu/nvgpu/gp10b/mm_gp10b.h
new file mode 100644
index 00000000..b6bcb04a
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef MM_GP10B_H
24#define MM_GP10B_H
25
26struct gk20a;
27struct gk20a_mmu_level;
28struct nvgpu_mem;
29struct vm_gk20a;
30
31u32 gp10b_mm_get_default_big_page_size(void);
32u32 gp10b_mm_get_iommu_bit(struct gk20a *g);
33int gp10b_init_mm_setup_hw(struct gk20a *g);
34int gb10b_init_bar2_vm(struct gk20a *g);
35int gb10b_init_bar2_mm_hw_setup(struct gk20a *g);
36const struct gk20a_mmu_level *gp10b_mm_get_mmu_levels(struct gk20a *g,
37 u32 big_page_size);
38void gp10b_mm_init_pdb(struct gk20a *g, struct nvgpu_mem *inst_block,
39 struct vm_gk20a *vm);
40void gp10b_remove_bar2_vm(struct gk20a *g);
41
42#endif
diff --git a/drivers/gpu/nvgpu/gp10b/platform_gp10b.h b/drivers/gpu/nvgpu/gp10b/platform_gp10b.h
new file mode 100644
index 00000000..0791c2fe
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/platform_gp10b.h
@@ -0,0 +1,34 @@
1/*
2 * GP10B Platform (SoC) Interface
3 *
4 * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef _GP10B_PLATFORM_H_
26#define _GP10B_PLATFORM_H_
27
28struct device;
29
30int gp10b_tegra_get_clocks(struct device *dev);
31int gp10b_tegra_reset_assert(struct device *dev);
32int gp10b_tegra_reset_deassert(struct device *dev);
33
34#endif
diff --git a/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
new file mode 100644
index 00000000..147cd020
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.c
@@ -0,0 +1,399 @@
1/*
2 * GP10B PMU
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <nvgpu/pmu.h>
26#include <nvgpu/log.h>
27#include <nvgpu/fuse.h>
28#include <nvgpu/enabled.h>
29
30#include "gk20a/gk20a.h"
31#include "gk20a/pmu_gk20a.h"
32#include "gm20b/acr_gm20b.h"
33#include "gm20b/pmu_gm20b.h"
34
35#include "pmu_gp10b.h"
36
37#include <nvgpu/hw/gp10b/hw_pwr_gp10b.h>
38#include <nvgpu/hw/gp10b/hw_fuse_gp10b.h>
39
40#define gp10b_dbg_pmu(fmt, arg...) \
41 gk20a_dbg(gpu_dbg_pmu, fmt, ##arg)
42/*!
43 * Structure/object which single register write need to be done during PG init
44 * sequence to set PROD values.
45 */
46struct pg_init_sequence_list {
47 u32 regaddr;
48 u32 writeval;
49};
50
51/* PROD settings for ELPG sequencing registers*/
52static struct pg_init_sequence_list _pginitseq_gp10b[] = {
53 {0x0010ab10, 0x0000868B} ,
54 {0x0010e118, 0x8590848F} ,
55 {0x0010e000, 0} ,
56 {0x0010e06c, 0x000000A3} ,
57 {0x0010e06c, 0x000000A0} ,
58 {0x0010e06c, 0x00000095} ,
59 {0x0010e06c, 0x000000A6} ,
60 {0x0010e06c, 0x0000008C} ,
61 {0x0010e06c, 0x00000080} ,
62 {0x0010e06c, 0x00000081} ,
63 {0x0010e06c, 0x00000087} ,
64 {0x0010e06c, 0x00000088} ,
65 {0x0010e06c, 0x0000008D} ,
66 {0x0010e06c, 0x00000082} ,
67 {0x0010e06c, 0x00000083} ,
68 {0x0010e06c, 0x00000089} ,
69 {0x0010e06c, 0x0000008A} ,
70 {0x0010e06c, 0x000000A2} ,
71 {0x0010e06c, 0x00000097} ,
72 {0x0010e06c, 0x00000092} ,
73 {0x0010e06c, 0x00000099} ,
74 {0x0010e06c, 0x0000009B} ,
75 {0x0010e06c, 0x0000009D} ,
76 {0x0010e06c, 0x0000009F} ,
77 {0x0010e06c, 0x000000A1} ,
78 {0x0010e06c, 0x00000096} ,
79 {0x0010e06c, 0x00000091} ,
80 {0x0010e06c, 0x00000098} ,
81 {0x0010e06c, 0x0000009A} ,
82 {0x0010e06c, 0x0000009C} ,
83 {0x0010e06c, 0x0000009E} ,
84 {0x0010ab14, 0x00000000} ,
85 {0x0010e024, 0x00000000} ,
86 {0x0010e028, 0x00000000} ,
87 {0x0010e11c, 0x00000000} ,
88 {0x0010ab1c, 0x140B0BFF} ,
89 {0x0010e020, 0x0E2626FF} ,
90 {0x0010e124, 0x251010FF} ,
91 {0x0010ab20, 0x89abcdef} ,
92 {0x0010ab24, 0x00000000} ,
93 {0x0010e02c, 0x89abcdef} ,
94 {0x0010e030, 0x00000000} ,
95 {0x0010e128, 0x89abcdef} ,
96 {0x0010e12c, 0x00000000} ,
97 {0x0010ab28, 0x7FFFFFFF} ,
98 {0x0010ab2c, 0x70000000} ,
99 {0x0010e034, 0x7FFFFFFF} ,
100 {0x0010e038, 0x70000000} ,
101 {0x0010e130, 0x7FFFFFFF} ,
102 {0x0010e134, 0x70000000} ,
103 {0x0010ab30, 0x00000000} ,
104 {0x0010ab34, 0x00000001} ,
105 {0x00020004, 0x00000000} ,
106 {0x0010e138, 0x00000000} ,
107 {0x0010e040, 0x00000000} ,
108 {0x0010e168, 0x00000000} ,
109 {0x0010e114, 0x0000A5A4} ,
110 {0x0010e110, 0x00000000} ,
111 {0x0010e10c, 0x8590848F} ,
112 {0x0010e05c, 0x00000000} ,
113 {0x0010e044, 0x00000000} ,
114 {0x0010a644, 0x0000868B} ,
115 {0x0010a648, 0x00000000} ,
116 {0x0010a64c, 0x00829493} ,
117 {0x0010a650, 0x00000000} ,
118 {0x0010e000, 0} ,
119 {0x0010e068, 0x000000A3} ,
120 {0x0010e068, 0x000000A0} ,
121 {0x0010e068, 0x00000095} ,
122 {0x0010e068, 0x000000A6} ,
123 {0x0010e068, 0x0000008C} ,
124 {0x0010e068, 0x00000080} ,
125 {0x0010e068, 0x00000081} ,
126 {0x0010e068, 0x00000087} ,
127 {0x0010e068, 0x00000088} ,
128 {0x0010e068, 0x0000008D} ,
129 {0x0010e068, 0x00000082} ,
130 {0x0010e068, 0x00000083} ,
131 {0x0010e068, 0x00000089} ,
132 {0x0010e068, 0x0000008A} ,
133 {0x0010e068, 0x000000A2} ,
134 {0x0010e068, 0x00000097} ,
135 {0x0010e068, 0x00000092} ,
136 {0x0010e068, 0x00000099} ,
137 {0x0010e068, 0x0000009B} ,
138 {0x0010e068, 0x0000009D} ,
139 {0x0010e068, 0x0000009F} ,
140 {0x0010e068, 0x000000A1} ,
141 {0x0010e068, 0x00000096} ,
142 {0x0010e068, 0x00000091} ,
143 {0x0010e068, 0x00000098} ,
144 {0x0010e068, 0x0000009A} ,
145 {0x0010e068, 0x0000009C} ,
146 {0x0010e068, 0x0000009E} ,
147 {0x0010e000, 0} ,
148 {0x0010e004, 0x0000008E},
149};
150
151static void gp10b_pmu_load_multiple_falcons(struct gk20a *g, u32 falconidmask,
152 u32 flags)
153{
154 struct nvgpu_pmu *pmu = &g->pmu;
155 struct pmu_cmd cmd;
156 u32 seq;
157
158 gk20a_dbg_fn("");
159
160 gp10b_dbg_pmu("wprinit status = %x\n", g->pmu_lsf_pmu_wpr_init_done);
161 if (g->pmu_lsf_pmu_wpr_init_done) {
162 /* send message to load FECS falcon */
163 memset(&cmd, 0, sizeof(struct pmu_cmd));
164 cmd.hdr.unit_id = PMU_UNIT_ACR;
165 cmd.hdr.size = PMU_CMD_HDR_SIZE +
166 sizeof(struct pmu_acr_cmd_bootstrap_multiple_falcons);
167 cmd.cmd.acr.boot_falcons.cmd_type =
168 PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS;
169 cmd.cmd.acr.boot_falcons.flags = flags;
170 cmd.cmd.acr.boot_falcons.falconidmask =
171 falconidmask;
172 cmd.cmd.acr.boot_falcons.usevamask = 0;
173 cmd.cmd.acr.boot_falcons.wprvirtualbase.lo = 0x0;
174 cmd.cmd.acr.boot_falcons.wprvirtualbase.hi = 0x0;
175 gp10b_dbg_pmu("PMU_ACR_CMD_ID_BOOTSTRAP_MULTIPLE_FALCONS:%x\n",
176 falconidmask);
177 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
178 pmu_handle_fecs_boot_acr_msg, pmu, &seq, ~0);
179 }
180
181 gk20a_dbg_fn("done");
182 return;
183}
184
185int gp10b_load_falcon_ucode(struct gk20a *g, u32 falconidmask)
186{
187 u32 flags = PMU_ACR_CMD_BOOTSTRAP_FALCON_FLAGS_RESET_YES;
188
189 /* GM20B PMU supports loading FECS and GPCCS only */
190 if (falconidmask == 0)
191 return -EINVAL;
192 if (falconidmask & ~((1 << LSF_FALCON_ID_FECS) |
193 (1 << LSF_FALCON_ID_GPCCS)))
194 return -EINVAL;
195 g->pmu_lsf_loaded_falcon_id = 0;
196 /* check whether pmu is ready to bootstrap lsf if not wait for it */
197 if (!g->pmu_lsf_pmu_wpr_init_done) {
198 pmu_wait_message_cond(&g->pmu,
199 gk20a_get_gr_idle_timeout(g),
200 &g->pmu_lsf_pmu_wpr_init_done, 1);
201 /* check again if it still not ready indicate an error */
202 if (!g->pmu_lsf_pmu_wpr_init_done) {
203 nvgpu_err(g, "PMU not ready to load LSF");
204 return -ETIMEDOUT;
205 }
206 }
207 /* load falcon(s) */
208 gp10b_pmu_load_multiple_falcons(g, falconidmask, flags);
209 pmu_wait_message_cond(&g->pmu,
210 gk20a_get_gr_idle_timeout(g),
211 &g->pmu_lsf_loaded_falcon_id, falconidmask);
212 if (g->pmu_lsf_loaded_falcon_id != falconidmask)
213 return -ETIMEDOUT;
214 return 0;
215}
216
217static void pmu_handle_gr_param_msg(struct gk20a *g, struct pmu_msg *msg,
218 void *param, u32 handle, u32 status)
219{
220 gk20a_dbg_fn("");
221
222 if (status != 0) {
223 nvgpu_err(g, "GR PARAM cmd aborted");
224 /* TBD: disable ELPG */
225 return;
226 }
227
228 gp10b_dbg_pmu("GR PARAM is acknowledged from PMU %x \n",
229 msg->msg.pg.msg_type);
230
231 return;
232}
233
234int gp10b_pg_gr_init(struct gk20a *g, u32 pg_engine_id)
235{
236 struct nvgpu_pmu *pmu = &g->pmu;
237 struct pmu_cmd cmd;
238 u32 seq;
239
240 if (pg_engine_id == PMU_PG_ELPG_ENGINE_ID_GRAPHICS) {
241 memset(&cmd, 0, sizeof(struct pmu_cmd));
242 cmd.hdr.unit_id = PMU_UNIT_PG;
243 cmd.hdr.size = PMU_CMD_HDR_SIZE +
244 sizeof(struct pmu_pg_cmd_gr_init_param);
245 cmd.cmd.pg.gr_init_param.cmd_type =
246 PMU_PG_CMD_ID_PG_PARAM;
247 cmd.cmd.pg.gr_init_param.sub_cmd_id =
248 PMU_PG_PARAM_CMD_GR_INIT_PARAM;
249 cmd.cmd.pg.gr_init_param.featuremask =
250 PMU_PG_FEATURE_GR_POWER_GATING_ENABLED;
251
252 gp10b_dbg_pmu("cmd post PMU_PG_CMD_ID_PG_PARAM ");
253 nvgpu_pmu_cmd_post(g, &cmd, NULL, NULL, PMU_COMMAND_QUEUE_HPQ,
254 pmu_handle_gr_param_msg, pmu, &seq, ~0);
255
256 } else
257 return -EINVAL;
258
259 return 0;
260}
261
262void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
263 struct pmu_pg_stats_data *pg_stat_data)
264{
265 struct nvgpu_pmu *pmu = &g->pmu;
266 struct pmu_pg_stats_v1 stats;
267
268 nvgpu_flcn_copy_from_dmem(pmu->flcn,
269 pmu->stat_dmem_offset[pg_engine_id],
270 (u8 *)&stats, sizeof(struct pmu_pg_stats_v1), 0);
271
272 pg_stat_data->ingating_time = stats.total_sleep_timeus;
273 pg_stat_data->ungating_time = stats.total_nonsleep_timeus;
274 pg_stat_data->gating_cnt = stats.entry_count;
275 pg_stat_data->avg_entry_latency_us = stats.entrylatency_avgus;
276 pg_stat_data->avg_exit_latency_us = stats.exitlatency_avgus;
277}
278
279int gp10b_pmu_setup_elpg(struct gk20a *g)
280{
281 int ret = 0;
282 u32 reg_writes;
283 u32 index;
284
285 gk20a_dbg_fn("");
286
287 if (g->elpg_enabled) {
288 reg_writes = ((sizeof(_pginitseq_gp10b) /
289 sizeof((_pginitseq_gp10b)[0])));
290 /* Initialize registers with production values*/
291 for (index = 0; index < reg_writes; index++) {
292 gk20a_writel(g, _pginitseq_gp10b[index].regaddr,
293 _pginitseq_gp10b[index].writeval);
294 }
295 }
296
297 gk20a_dbg_fn("done");
298 return ret;
299}
300
301void gp10b_write_dmatrfbase(struct gk20a *g, u32 addr)
302{
303 gk20a_writel(g, pwr_falcon_dmatrfbase_r(),
304 addr);
305 gk20a_writel(g, pwr_falcon_dmatrfbase1_r(),
306 0x0);
307}
308
309int gp10b_init_pmu_setup_hw1(struct gk20a *g)
310{
311 struct nvgpu_pmu *pmu = &g->pmu;
312 int err;
313
314 gk20a_dbg_fn("");
315
316 nvgpu_mutex_acquire(&pmu->isr_mutex);
317 nvgpu_flcn_reset(pmu->flcn);
318 pmu->isr_enabled = true;
319 nvgpu_mutex_release(&pmu->isr_mutex);
320
321 /* setup apertures - virtual */
322 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_UCODE),
323 pwr_fbif_transcfg_mem_type_virtual_f());
324 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_VIRT),
325 pwr_fbif_transcfg_mem_type_virtual_f());
326
327 /* setup apertures - physical */
328 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_PHYS_VID),
329 pwr_fbif_transcfg_mem_type_physical_f() |
330 pwr_fbif_transcfg_target_local_fb_f());
331 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_PHYS_SYS_COH),
332 pwr_fbif_transcfg_mem_type_physical_f() |
333 pwr_fbif_transcfg_target_coherent_sysmem_f());
334 gk20a_writel(g, pwr_fbif_transcfg_r(GK20A_PMU_DMAIDX_PHYS_SYS_NCOH),
335 pwr_fbif_transcfg_mem_type_physical_f() |
336 pwr_fbif_transcfg_target_noncoherent_sysmem_f());
337
338 err = g->ops.pmu.pmu_nsbootstrap(pmu);
339 if (err)
340 return err;
341
342 gk20a_dbg_fn("done");
343 return 0;
344
345}
346
347bool gp10b_is_lazy_bootstrap(u32 falcon_id)
348{
349 bool enable_status = false;
350
351 switch (falcon_id) {
352 case LSF_FALCON_ID_FECS:
353 enable_status = false;
354 break;
355 case LSF_FALCON_ID_GPCCS:
356 enable_status = true;
357 break;
358 default:
359 break;
360 }
361
362 return enable_status;
363}
364
365bool gp10b_is_priv_load(u32 falcon_id)
366{
367 bool enable_status = false;
368
369 switch (falcon_id) {
370 case LSF_FALCON_ID_FECS:
371 enable_status = false;
372 break;
373 case LSF_FALCON_ID_GPCCS:
374 enable_status = true;
375 break;
376 default:
377 break;
378 }
379
380 return enable_status;
381}
382
383/*Dump Security related fuses*/
384void pmu_dump_security_fuses_gp10b(struct gk20a *g)
385{
386 u32 val;
387
388 nvgpu_err(g, "FUSE_OPT_SEC_DEBUG_EN_0: 0x%x",
389 gk20a_readl(g, fuse_opt_sec_debug_en_r()));
390 nvgpu_err(g, "FUSE_OPT_PRIV_SEC_EN_0: 0x%x",
391 gk20a_readl(g, fuse_opt_priv_sec_en_r()));
392 nvgpu_tegra_fuse_read_gcplex_config_fuse(g, &val);
393 nvgpu_err(g, "FUSE_GCPLEX_CONFIG_FUSE_0: 0x%x", val);
394}
395
396bool gp10b_is_pmu_supported(struct gk20a *g)
397{
398 return true;
399}
diff --git a/drivers/gpu/nvgpu/gp10b/pmu_gp10b.h b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.h
new file mode 100644
index 00000000..44e0ec98
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/pmu_gp10b.h
@@ -0,0 +1,43 @@
1/*
2 * GP10B PMU
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef __PMU_GP10B_H_
26#define __PMU_GP10B_H_
27
28struct gk20a;
29
30
31bool gp10b_is_lazy_bootstrap(u32 falcon_id);
32bool gp10b_is_priv_load(u32 falcon_id);
33bool gp10b_is_pmu_supported(struct gk20a *g);
34int gp10b_init_pmu_setup_hw1(struct gk20a *g);
35void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id,
36 struct pmu_pg_stats_data *pg_stat_data);
37int gp10b_pmu_setup_elpg(struct gk20a *g);
38void pmu_dump_security_fuses_gp10b(struct gk20a *g);
39int gp10b_load_falcon_ucode(struct gk20a *g, u32 falconidmask);
40int gp10b_pg_gr_init(struct gk20a *g, u32 pg_engine_id);
41void gp10b_write_dmatrfbase(struct gk20a *g, u32 addr);
42
43#endif /*__PMU_GP10B_H_*/
diff --git a/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
new file mode 100644
index 00000000..b780457f
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.c
@@ -0,0 +1,112 @@
1/*
2 * GP10B priv ring
3 *
4 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26
27#include <nvgpu/log.h>
28#include <nvgpu/timers.h>
29#include <nvgpu/enabled.h>
30
31#include <nvgpu/hw/gp10b/hw_mc_gp10b.h>
32#include <nvgpu/hw/gp10b/hw_pri_ringmaster_gp10b.h>
33#include <nvgpu/hw/gp10b/hw_pri_ringstation_sys_gp10b.h>
34#include <nvgpu/hw/gp10b/hw_pri_ringstation_gpc_gp10b.h>
35
36void gp10b_priv_ring_isr(struct gk20a *g)
37{
38 u32 status0, status1;
39 u32 cmd;
40 s32 retry = 100;
41 u32 gpc;
42 u32 gpc_stride, offset;
43
44 if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL)) {
45 nvgpu_info(g, "unhandled priv ring intr");
46 return;
47 }
48
49 status0 = gk20a_readl(g, pri_ringmaster_intr_status0_r());
50 status1 = gk20a_readl(g, pri_ringmaster_intr_status1_r());
51
52 nvgpu_err(g, "ringmaster intr status0: 0x%08x,"
53 "status1: 0x%08x", status0, status1);
54
55 if (pri_ringmaster_intr_status0_ring_start_conn_fault_v(status0) != 0)
56 nvgpu_err(g,
57 "BUG: connectivity problem on the startup sequence");
58
59 if (pri_ringmaster_intr_status0_disconnect_fault_v(status0) != 0)
60 nvgpu_err(g, "ring disconnected");
61
62 if (pri_ringmaster_intr_status0_overflow_fault_v(status0) != 0)
63 nvgpu_err(g, "ring overflowed");
64
65 if (pri_ringmaster_intr_status0_gbl_write_error_sys_v(status0) != 0) {
66 nvgpu_err(g, "SYS write error. ADR %08x WRDAT %08x INFO %08x, CODE %08x",
67 gk20a_readl(g, pri_ringstation_sys_priv_error_adr_r()),
68 gk20a_readl(g, pri_ringstation_sys_priv_error_wrdat_r()),
69 gk20a_readl(g, pri_ringstation_sys_priv_error_info_r()),
70 gk20a_readl(g, pri_ringstation_sys_priv_error_code_r()));
71 }
72
73 if (status1) {
74 gpc_stride = nvgpu_get_litter_value(g, GPU_LIT_GPC_STRIDE);
75 for (gpc = 0; gpc < g->gr.gpc_count; gpc++) {
76 offset = gpc * gpc_stride;
77 if (status1 & BIT(gpc)) {
78 nvgpu_err(g, "GPC%u write error. ADR %08x "
79 "WRDAT %08x INFO %08x, CODE %08x", gpc,
80 gk20a_readl(g,
81 pri_ringstation_gpc_gpc0_priv_error_adr_r() + offset),
82 gk20a_readl(g,
83 pri_ringstation_gpc_gpc0_priv_error_wrdat_r() + offset),
84 gk20a_readl(g,
85 pri_ringstation_gpc_gpc0_priv_error_info_r() + offset),
86 gk20a_readl(g,
87 pri_ringstation_gpc_gpc0_priv_error_code_r() + offset));
88 status1 = status1 & (~(BIT(gpc)));
89 if (!status1)
90 break;
91 }
92 }
93 }
94 /* clear interrupt */
95 cmd = gk20a_readl(g, pri_ringmaster_command_r());
96 cmd = set_field(cmd, pri_ringmaster_command_cmd_m(),
97 pri_ringmaster_command_cmd_ack_interrupt_f());
98 gk20a_writel(g, pri_ringmaster_command_r(), cmd);
99
100 /* poll for clear interrupt done */
101 cmd = pri_ringmaster_command_cmd_v(
102 gk20a_readl(g, pri_ringmaster_command_r()));
103 while (cmd != pri_ringmaster_command_cmd_no_cmd_v() && retry) {
104 nvgpu_udelay(20);
105 cmd = pri_ringmaster_command_cmd_v(
106 gk20a_readl(g, pri_ringmaster_command_r()));
107 retry--;
108 }
109
110 if (retry == 0)
111 nvgpu_err(g, "priv ringmaster intr ack failed");
112}
diff --git a/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.h b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.h
new file mode 100644
index 00000000..5b004a58
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/priv_ring_gp10b.h
@@ -0,0 +1,31 @@
1/*
2 * GP10B PRIV ringmaster
3 *
4 * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#ifndef __PRIV_RING_GP10B_H__
25#define __PRIV_RING_GP10B_H__
26
27struct gk20a;
28
29void gp10b_priv_ring_isr(struct gk20a *g);
30
31#endif /*__PRIV_RING_GP10B_H__*/
diff --git a/drivers/gpu/nvgpu/gp10b/regops_gp10b.c b/drivers/gpu/nvgpu/gp10b/regops_gp10b.c
new file mode 100644
index 00000000..bf360d6f
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/regops_gp10b.c
@@ -0,0 +1,479 @@
1/*
2 * Tegra GK20A GPU Debugger Driver Register Ops
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <uapi/linux/nvgpu.h>
26
27#include "gk20a/gk20a.h"
28#include "gk20a/dbg_gpu_gk20a.h"
29#include "gk20a/regops_gk20a.h"
30#include "regops_gp10b.h"
31
32#include <nvgpu/bsearch.h>
33
34static const struct regop_offset_range gp10b_global_whitelist_ranges[] = {
35 { 0x000004f0, 1},
36 { 0x00001a00, 3},
37 { 0x00002800, 128},
38 { 0x00009400, 1},
39 { 0x00009410, 1},
40 { 0x00009480, 1},
41 { 0x00020200, 24},
42 { 0x00021c00, 4},
43 { 0x00021c14, 3},
44 { 0x00021c24, 1},
45 { 0x00021c2c, 69},
46 { 0x00021d44, 1},
47 { 0x00021d4c, 1},
48 { 0x00021d54, 1},
49 { 0x00021d5c, 1},
50 { 0x00021d64, 2},
51 { 0x00021d70, 16},
52 { 0x00022430, 7},
53 { 0x00022450, 1},
54 { 0x0002245c, 1},
55 { 0x00070000, 5},
56 { 0x000884e0, 1},
57 { 0x0008e00c, 1},
58 { 0x00100c18, 3},
59 { 0x00100c84, 1},
60 { 0x00104038, 1},
61 { 0x0010a0a8, 1},
62 { 0x0010a4f0, 1},
63 { 0x0010e490, 1},
64 { 0x0013cc14, 1},
65 { 0x00140028, 1},
66 { 0x00140280, 1},
67 { 0x001402a0, 1},
68 { 0x00140350, 1},
69 { 0x00140480, 1},
70 { 0x001404a0, 1},
71 { 0x00140550, 1},
72 { 0x00142028, 1},
73 { 0x00142280, 1},
74 { 0x001422a0, 1},
75 { 0x00142350, 1},
76 { 0x00142480, 1},
77 { 0x001424a0, 1},
78 { 0x00142550, 1},
79 { 0x0017e028, 1},
80 { 0x0017e280, 1},
81 { 0x0017e294, 1},
82 { 0x0017e29c, 2},
83 { 0x0017e2ac, 1},
84 { 0x0017e350, 1},
85 { 0x0017e39c, 1},
86 { 0x0017e480, 1},
87 { 0x0017e4a0, 1},
88 { 0x0017e550, 1},
89 { 0x00180040, 41},
90 { 0x001800ec, 10},
91 { 0x00180240, 41},
92 { 0x001802ec, 10},
93 { 0x00180440, 41},
94 { 0x001804ec, 10},
95 { 0x00180640, 41},
96 { 0x001806ec, 10},
97 { 0x00180840, 41},
98 { 0x001808ec, 10},
99 { 0x00180a40, 41},
100 { 0x00180aec, 10},
101 { 0x00180c40, 41},
102 { 0x00180cec, 10},
103 { 0x00180e40, 41},
104 { 0x00180eec, 10},
105 { 0x001a0040, 41},
106 { 0x001a00ec, 10},
107 { 0x001a0240, 41},
108 { 0x001a02ec, 10},
109 { 0x001a0440, 41},
110 { 0x001a04ec, 10},
111 { 0x001a0640, 41},
112 { 0x001a06ec, 10},
113 { 0x001a0840, 41},
114 { 0x001a08ec, 10},
115 { 0x001a0a40, 41},
116 { 0x001a0aec, 10},
117 { 0x001a0c40, 41},
118 { 0x001a0cec, 10},
119 { 0x001a0e40, 41},
120 { 0x001a0eec, 10},
121 { 0x001b0040, 41},
122 { 0x001b00ec, 10},
123 { 0x001b0240, 41},
124 { 0x001b02ec, 10},
125 { 0x001b0440, 41},
126 { 0x001b04ec, 10},
127 { 0x001b0640, 41},
128 { 0x001b06ec, 10},
129 { 0x001b0840, 41},
130 { 0x001b08ec, 10},
131 { 0x001b0a40, 41},
132 { 0x001b0aec, 10},
133 { 0x001b0c40, 41},
134 { 0x001b0cec, 10},
135 { 0x001b0e40, 41},
136 { 0x001b0eec, 10},
137 { 0x001b4000, 1},
138 { 0x001b4008, 1},
139 { 0x001b4010, 3},
140 { 0x001b4020, 3},
141 { 0x001b4030, 3},
142 { 0x001b4040, 3},
143 { 0x001b4050, 3},
144 { 0x001b4060, 4},
145 { 0x001b4074, 7},
146 { 0x001b4094, 3},
147 { 0x001b40a4, 1},
148 { 0x001b4100, 6},
149 { 0x001b4124, 2},
150 { 0x001b8000, 1},
151 { 0x001b8008, 1},
152 { 0x001b8010, 3},
153 { 0x001bc000, 1},
154 { 0x001bc008, 1},
155 { 0x001bc010, 3},
156 { 0x001be000, 1},
157 { 0x001be008, 1},
158 { 0x001be010, 3},
159 { 0x00400500, 1},
160 { 0x0040415c, 1},
161 { 0x00404468, 1},
162 { 0x00404498, 1},
163 { 0x00405800, 1},
164 { 0x00405840, 2},
165 { 0x00405850, 1},
166 { 0x00405908, 1},
167 { 0x00405b40, 1},
168 { 0x00405b50, 1},
169 { 0x00406024, 5},
170 { 0x00407010, 1},
171 { 0x00407808, 1},
172 { 0x0040803c, 1},
173 { 0x00408804, 1},
174 { 0x0040880c, 1},
175 { 0x00408900, 2},
176 { 0x00408910, 1},
177 { 0x00408944, 1},
178 { 0x00408984, 1},
179 { 0x004090a8, 1},
180 { 0x004098a0, 1},
181 { 0x00409b00, 1},
182 { 0x0041000c, 1},
183 { 0x00410110, 1},
184 { 0x00410184, 1},
185 { 0x0041040c, 1},
186 { 0x00410510, 1},
187 { 0x00410584, 1},
188 { 0x00418000, 1},
189 { 0x00418008, 1},
190 { 0x00418380, 2},
191 { 0x00418400, 2},
192 { 0x004184a0, 1},
193 { 0x00418604, 1},
194 { 0x00418680, 1},
195 { 0x00418704, 1},
196 { 0x00418714, 1},
197 { 0x00418800, 1},
198 { 0x0041881c, 1},
199 { 0x00418830, 1},
200 { 0x00418884, 1},
201 { 0x004188b0, 1},
202 { 0x004188c8, 3},
203 { 0x004188fc, 1},
204 { 0x00418b04, 1},
205 { 0x00418c04, 1},
206 { 0x00418c10, 8},
207 { 0x00418c88, 1},
208 { 0x00418d00, 1},
209 { 0x00418e00, 1},
210 { 0x00418e08, 1},
211 { 0x00418e34, 1},
212 { 0x00418e40, 4},
213 { 0x00418e58, 16},
214 { 0x00418f08, 1},
215 { 0x00419000, 1},
216 { 0x0041900c, 1},
217 { 0x00419018, 1},
218 { 0x00419854, 1},
219 { 0x00419864, 1},
220 { 0x00419a04, 2},
221 { 0x00419a14, 1},
222 { 0x00419ab0, 1},
223 { 0x00419ab8, 3},
224 { 0x00419c0c, 1},
225 { 0x00419c8c, 2},
226 { 0x00419d00, 1},
227 { 0x00419d08, 2},
228 { 0x00419e00, 11},
229 { 0x00419e34, 2},
230 { 0x00419e44, 11},
231 { 0x00419e74, 10},
232 { 0x00419ea4, 1},
233 { 0x00419eac, 2},
234 { 0x00419ee8, 1},
235 { 0x00419ef0, 28},
236 { 0x00419f70, 1},
237 { 0x00419f78, 2},
238 { 0x00419f98, 2},
239 { 0x00419fdc, 1},
240 { 0x0041a02c, 2},
241 { 0x0041a0a0, 1},
242 { 0x0041a0a8, 1},
243 { 0x0041a890, 2},
244 { 0x0041a8a0, 3},
245 { 0x0041a8b0, 2},
246 { 0x0041b014, 1},
247 { 0x0041b0a0, 1},
248 { 0x0041b0cc, 1},
249 { 0x0041b1dc, 1},
250 { 0x0041be0c, 3},
251 { 0x0041bea0, 1},
252 { 0x0041becc, 1},
253 { 0x0041bfdc, 1},
254 { 0x0041c054, 1},
255 { 0x0041c2b0, 1},
256 { 0x0041c2b8, 3},
257 { 0x0041c40c, 1},
258 { 0x0041c48c, 2},
259 { 0x0041c500, 1},
260 { 0x0041c508, 2},
261 { 0x0041c600, 11},
262 { 0x0041c634, 2},
263 { 0x0041c644, 11},
264 { 0x0041c674, 10},
265 { 0x0041c6a4, 1},
266 { 0x0041c6ac, 2},
267 { 0x0041c6e8, 1},
268 { 0x0041c6f0, 28},
269 { 0x0041c770, 1},
270 { 0x0041c778, 2},
271 { 0x0041c798, 2},
272 { 0x0041c7dc, 1},
273 { 0x0041c854, 1},
274 { 0x0041cab0, 1},
275 { 0x0041cab8, 3},
276 { 0x0041cc0c, 1},
277 { 0x0041cc8c, 2},
278 { 0x0041cd00, 1},
279 { 0x0041cd08, 2},
280 { 0x0041ce00, 11},
281 { 0x0041ce34, 2},
282 { 0x0041ce44, 11},
283 { 0x0041ce74, 10},
284 { 0x0041cea4, 1},
285 { 0x0041ceac, 2},
286 { 0x0041cee8, 1},
287 { 0x0041cef0, 28},
288 { 0x0041cf70, 1},
289 { 0x0041cf78, 2},
290 { 0x0041cf98, 2},
291 { 0x0041cfdc, 1},
292 { 0x00500384, 1},
293 { 0x005004a0, 1},
294 { 0x00500604, 1},
295 { 0x00500680, 1},
296 { 0x00500714, 1},
297 { 0x0050081c, 1},
298 { 0x00500884, 1},
299 { 0x005008b0, 1},
300 { 0x005008c8, 3},
301 { 0x005008fc, 1},
302 { 0x00500b04, 1},
303 { 0x00500c04, 1},
304 { 0x00500c10, 8},
305 { 0x00500c88, 1},
306 { 0x00500d00, 1},
307 { 0x00500e08, 1},
308 { 0x00500f08, 1},
309 { 0x00501000, 1},
310 { 0x0050100c, 1},
311 { 0x00501018, 1},
312 { 0x00501854, 1},
313 { 0x00501ab0, 1},
314 { 0x00501ab8, 3},
315 { 0x00501c0c, 1},
316 { 0x00501c8c, 2},
317 { 0x00501d00, 1},
318 { 0x00501d08, 2},
319 { 0x00501e00, 11},
320 { 0x00501e34, 2},
321 { 0x00501e44, 11},
322 { 0x00501e74, 10},
323 { 0x00501ea4, 1},
324 { 0x00501eac, 2},
325 { 0x00501ee8, 1},
326 { 0x00501ef0, 28},
327 { 0x00501f70, 1},
328 { 0x00501f78, 2},
329 { 0x00501f98, 2},
330 { 0x00501fdc, 1},
331 { 0x0050202c, 2},
332 { 0x005020a0, 1},
333 { 0x005020a8, 1},
334 { 0x00502890, 2},
335 { 0x005028a0, 3},
336 { 0x005028b0, 2},
337 { 0x00503014, 1},
338 { 0x005030a0, 1},
339 { 0x005030cc, 1},
340 { 0x005031dc, 1},
341 { 0x00503e14, 1},
342 { 0x00503ea0, 1},
343 { 0x00503ecc, 1},
344 { 0x00503fdc, 1},
345 { 0x00504054, 1},
346 { 0x005042b0, 1},
347 { 0x005042b8, 3},
348 { 0x0050440c, 1},
349 { 0x0050448c, 2},
350 { 0x00504500, 1},
351 { 0x00504508, 2},
352 { 0x00504600, 11},
353 { 0x00504634, 2},
354 { 0x00504644, 11},
355 { 0x00504674, 10},
356 { 0x005046a4, 1},
357 { 0x005046ac, 2},
358 { 0x005046e8, 1},
359 { 0x005046f0, 28},
360 { 0x00504770, 1},
361 { 0x00504778, 2},
362 { 0x00504798, 2},
363 { 0x005047dc, 1},
364 { 0x00504854, 1},
365 { 0x00504ab0, 1},
366 { 0x00504ab8, 3},
367 { 0x00504c0c, 1},
368 { 0x00504c8c, 2},
369 { 0x00504d00, 1},
370 { 0x00504d08, 2},
371 { 0x00504e00, 11},
372 { 0x00504e34, 2},
373 { 0x00504e44, 11},
374 { 0x00504e74, 10},
375 { 0x00504ea4, 1},
376 { 0x00504eac, 2},
377 { 0x00504ee8, 1},
378 { 0x00504ef0, 28},
379 { 0x00504f70, 1},
380 { 0x00504f78, 2},
381 { 0x00504f98, 2},
382 { 0x00504fdc, 1},
383 { 0x00900100, 1},
384 { 0x009a0100, 1},
385};
386
387static const u32 gp10b_global_whitelist_ranges_count =
388 ARRAY_SIZE(gp10b_global_whitelist_ranges);
389
390/* context */
391
392/* runcontrol */
393static const u32 gp10b_runcontrol_whitelist[] = {
394};
395static const u32 gp10b_runcontrol_whitelist_count =
396 ARRAY_SIZE(gp10b_runcontrol_whitelist);
397
398static const struct regop_offset_range gp10b_runcontrol_whitelist_ranges[] = {
399};
400static const u32 gp10b_runcontrol_whitelist_ranges_count =
401 ARRAY_SIZE(gp10b_runcontrol_whitelist_ranges);
402
403
404/* quad ctl */
405static const u32 gp10b_qctl_whitelist[] = {
406};
407static const u32 gp10b_qctl_whitelist_count =
408 ARRAY_SIZE(gp10b_qctl_whitelist);
409
410static const struct regop_offset_range gp10b_qctl_whitelist_ranges[] = {
411};
412static const u32 gp10b_qctl_whitelist_ranges_count =
413 ARRAY_SIZE(gp10b_qctl_whitelist_ranges);
414
415const struct regop_offset_range *gp10b_get_global_whitelist_ranges(void)
416{
417 return gp10b_global_whitelist_ranges;
418}
419
420int gp10b_get_global_whitelist_ranges_count(void)
421{
422 return gp10b_global_whitelist_ranges_count;
423}
424
425const struct regop_offset_range *gp10b_get_context_whitelist_ranges(void)
426{
427 return gp10b_global_whitelist_ranges;
428}
429
430int gp10b_get_context_whitelist_ranges_count(void)
431{
432 return gp10b_global_whitelist_ranges_count;
433}
434
435const u32 *gp10b_get_runcontrol_whitelist(void)
436{
437 return gp10b_runcontrol_whitelist;
438}
439
440int gp10b_get_runcontrol_whitelist_count(void)
441{
442 return gp10b_runcontrol_whitelist_count;
443}
444
445const struct regop_offset_range *gp10b_get_runcontrol_whitelist_ranges(void)
446{
447 return gp10b_runcontrol_whitelist_ranges;
448}
449
450int gp10b_get_runcontrol_whitelist_ranges_count(void)
451{
452 return gp10b_runcontrol_whitelist_ranges_count;
453}
454
455const u32 *gp10b_get_qctl_whitelist(void)
456{
457 return gp10b_qctl_whitelist;
458}
459
460int gp10b_get_qctl_whitelist_count(void)
461{
462 return gp10b_qctl_whitelist_count;
463}
464
465const struct regop_offset_range *gp10b_get_qctl_whitelist_ranges(void)
466{
467 return gp10b_qctl_whitelist_ranges;
468}
469
470int gp10b_get_qctl_whitelist_ranges_count(void)
471{
472 return gp10b_qctl_whitelist_ranges_count;
473}
474
475int gp10b_apply_smpc_war(struct dbg_session_gk20a *dbg_s)
476{
477 /* Not needed on gp10b */
478 return 0;
479}
diff --git a/drivers/gpu/nvgpu/gp10b/regops_gp10b.h b/drivers/gpu/nvgpu/gp10b/regops_gp10b.h
new file mode 100644
index 00000000..7bc08189
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/regops_gp10b.h
@@ -0,0 +1,44 @@
1/*
2 *
3 * Tegra GP10B GPU Debugger Driver Register Ops
4 *
5 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#ifndef __REGOPS_GP10B_H_
26#define __REGOPS_GP10B_H_
27
28struct dbg_session_gk20a;
29
30const struct regop_offset_range *gp10b_get_global_whitelist_ranges(void);
31int gp10b_get_global_whitelist_ranges_count(void);
32const struct regop_offset_range *gp10b_get_context_whitelist_ranges(void);
33int gp10b_get_context_whitelist_ranges_count(void);
34const u32 *gp10b_get_runcontrol_whitelist(void);
35int gp10b_get_runcontrol_whitelist_count(void);
36const struct regop_offset_range *gp10b_get_runcontrol_whitelist_ranges(void);
37int gp10b_get_runcontrol_whitelist_ranges_count(void);
38const u32 *gp10b_get_qctl_whitelist(void);
39int gp10b_get_qctl_whitelist_count(void);
40const struct regop_offset_range *gp10b_get_qctl_whitelist_ranges(void);
41int gp10b_get_qctl_whitelist_ranges_count(void);
42int gp10b_apply_smpc_war(struct dbg_session_gk20a *dbg_s);
43
44#endif /* __REGOPS_GP10B_H_ */
diff --git a/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
new file mode 100644
index 00000000..3bbfde0a
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
@@ -0,0 +1,160 @@
1/*
2 * GP10B RPFB
3 *
4 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <nvgpu/dma.h>
26
27#include "gk20a/gk20a.h"
28
29#include "rpfb_gp10b.h"
30
31#include <nvgpu/hw/gp10b/hw_fifo_gp10b.h>
32#include <nvgpu/hw/gp10b/hw_fb_gp10b.h>
33#include <nvgpu/hw/gp10b/hw_bus_gp10b.h>
34#include <nvgpu/hw/gp10b/hw_gmmu_gp10b.h>
35
36int gp10b_replayable_pagefault_buffer_init(struct gk20a *g)
37{
38 u32 addr_lo;
39 u32 addr_hi;
40 struct vm_gk20a *vm = g->mm.bar2.vm;
41 int err;
42 size_t rbfb_size = NV_UVM_FAULT_BUF_SIZE *
43 fifo_replay_fault_buffer_size_hw_entries_v();
44
45 gk20a_dbg_fn("");
46
47 if (!g->mm.bar2_desc.gpu_va) {
48 err = nvgpu_dma_alloc_map_sys(vm, rbfb_size,
49 &g->mm.bar2_desc);
50 if (err) {
51 nvgpu_err(g, "Error in replayable fault buffer");
52 return err;
53 }
54 }
55 addr_lo = u64_lo32(g->mm.bar2_desc.gpu_va >> 12);
56 addr_hi = u64_hi32(g->mm.bar2_desc.gpu_va);
57 gk20a_writel(g, fifo_replay_fault_buffer_hi_r(),
58 fifo_replay_fault_buffer_hi_base_f(addr_hi));
59
60 gk20a_writel(g, fifo_replay_fault_buffer_lo_r(),
61 fifo_replay_fault_buffer_lo_base_f(addr_lo) |
62 fifo_replay_fault_buffer_lo_enable_true_v());
63 gk20a_dbg_fn("done");
64 return 0;
65}
66
67void gp10b_replayable_pagefault_buffer_deinit(struct gk20a *g)
68{
69 struct vm_gk20a *vm = g->mm.bar2.vm;
70
71 nvgpu_dma_unmap_free(vm, &g->mm.bar2_desc);
72}
73
74u32 gp10b_replayable_pagefault_buffer_get_index(struct gk20a *g)
75{
76 u32 get_idx = 0;
77
78 gk20a_dbg_fn("");
79
80 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
81
82 if (get_idx >= fifo_replay_fault_buffer_size_hw_entries_v())
83 nvgpu_err(g, "Error in replayable fault buffer");
84
85 gk20a_dbg_fn("done");
86 return get_idx;
87}
88
89u32 gp10b_replayable_pagefault_buffer_put_index(struct gk20a *g)
90{
91 u32 put_idx = 0;
92
93 gk20a_dbg_fn("");
94 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
95
96 if (put_idx >= fifo_replay_fault_buffer_size_hw_entries_v())
97 nvgpu_err(g, "Error in UVM");
98
99 gk20a_dbg_fn("done");
100 return put_idx;
101}
102
103bool gp10b_replayable_pagefault_buffer_is_empty(struct gk20a *g)
104{
105 u32 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
106 u32 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
107
108 return (get_idx == put_idx ? true : false);
109}
110
111bool gp10b_replayable_pagefault_buffer_is_full(struct gk20a *g)
112{
113 u32 get_idx = gk20a_readl(g, fifo_replay_fault_buffer_get_r());
114 u32 put_idx = gk20a_readl(g, fifo_replay_fault_buffer_put_r());
115 u32 hw_entries = gk20a_readl(g, fifo_replay_fault_buffer_size_r());
116
117 return (get_idx == ((put_idx + 1) % hw_entries) ? true : false);
118}
119
120bool gp10b_replayable_pagefault_buffer_is_overflow(struct gk20a *g)
121{
122 u32 info = gk20a_readl(g, fifo_replay_fault_buffer_info_r());
123
124 return fifo_replay_fault_buffer_info_overflow_f(info);
125}
126
127void gp10b_replayable_pagefault_buffer_clear_overflow(struct gk20a *g)
128{
129 u32 info = gk20a_readl(g, fifo_replay_fault_buffer_info_r());
130
131 info |= fifo_replay_fault_buffer_info_overflow_clear_v();
132 gk20a_writel(g, fifo_replay_fault_buffer_info_r(), info);
133
134}
135
136void gp10b_replayable_pagefault_buffer_info(struct gk20a *g)
137{
138
139 gk20a_dbg_fn("");
140 pr_info("rpfb low: 0x%x\n",
141 (gk20a_readl(g, fifo_replay_fault_buffer_lo_r()) >> 12));
142 pr_info("rpfb hi: 0x%x\n",
143 gk20a_readl(g, fifo_replay_fault_buffer_hi_r()));
144 pr_info("rpfb enabled: 0x%x\n",
145 (gk20a_readl(g, fifo_replay_fault_buffer_lo_r()) & 0x1));
146 pr_info("rpfb size: %d\n",
147 gk20a_readl(g, fifo_replay_fault_buffer_size_r()));
148 pr_info("rpfb get index: %d\n",
149 gp10b_replayable_pagefault_buffer_get_index(g));
150 pr_info("rpfb put index: %d\n",
151 gp10b_replayable_pagefault_buffer_put_index(g));
152 pr_info("rpfb empty: %d\n",
153 gp10b_replayable_pagefault_buffer_is_empty(g));
154 pr_info("rpfb full %d\n",
155 gp10b_replayable_pagefault_buffer_is_full(g));
156 pr_info("rpfb overflow %d\n",
157 gp10b_replayable_pagefault_buffer_is_overflow(g));
158
159 gk20a_dbg_fn("done");
160}
diff --git a/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.h b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.h
new file mode 100644
index 00000000..ee210a5f
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef RPFB_GP20B_H
24#define RPFB_GP20B_H
25struct gk20a;
26
27#define NV_UVM_FAULT_BUF_SIZE 32
28
29int gp10b_replayable_pagefault_buffer_init(struct gk20a *g);
30u32 gp10b_replayable_pagefault_buffer_get_index(struct gk20a *g);
31u32 gp10b_replayable_pagefault_buffer_put_index(struct gk20a *g);
32bool gp10b_replayable_pagefault_buffer_is_empty(struct gk20a *g);
33bool gp10b_replayable_pagefault_buffer_is_full(struct gk20a *g);
34bool gp10b_replayable_pagefault_buffer_is_overflow(struct gk20a *g);
35void gp10b_replayable_pagefault_buffer_clear_overflow(struct gk20a *g);
36void gp10b_replayable_pagefault_buffer_info(struct gk20a *g);
37void gp10b_replayable_pagefault_buffer_deinit(struct gk20a *g);
38
39#endif
diff --git a/drivers/gpu/nvgpu/gp10b/therm_gp10b.c b/drivers/gpu/nvgpu/gp10b/therm_gp10b.c
new file mode 100644
index 00000000..e02259d8
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/therm_gp10b.c
@@ -0,0 +1,141 @@
1/*
2 * GP10B Therm
3 *
4 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "gk20a/gk20a.h"
26#include "therm_gp10b.h"
27
28#include <nvgpu/soc.h>
29
30#include <nvgpu/hw/gp10b/hw_therm_gp10b.h>
31
32int gp10b_init_therm_setup_hw(struct gk20a *g)
33{
34 u32 v;
35
36 gk20a_dbg_fn("");
37
38 /* program NV_THERM registers */
39 gk20a_writel(g, therm_use_a_r(), therm_use_a_ext_therm_0_enable_f() |
40 therm_use_a_ext_therm_1_enable_f() |
41 therm_use_a_ext_therm_2_enable_f());
42 gk20a_writel(g, therm_evt_ext_therm_0_r(),
43 therm_evt_ext_therm_0_slow_factor_f(0x2));
44 gk20a_writel(g, therm_evt_ext_therm_1_r(),
45 therm_evt_ext_therm_1_slow_factor_f(0x6));
46 gk20a_writel(g, therm_evt_ext_therm_2_r(),
47 therm_evt_ext_therm_2_slow_factor_f(0xe));
48
49 gk20a_writel(g, therm_grad_stepping_table_r(0),
50 therm_grad_stepping_table_slowdown_factor0_f(
51 therm_grad_stepping_table_slowdown_factor0_fpdiv_by1p5_f()) |
52 therm_grad_stepping_table_slowdown_factor1_f(
53 therm_grad_stepping_table_slowdown_factor0_fpdiv_by2_f()) |
54 therm_grad_stepping_table_slowdown_factor2_f(
55 therm_grad_stepping_table_slowdown_factor0_fpdiv_by4_f()) |
56 therm_grad_stepping_table_slowdown_factor3_f(
57 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
58 therm_grad_stepping_table_slowdown_factor4_f(
59 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()));
60
61 gk20a_writel(g, therm_grad_stepping_table_r(1),
62 therm_grad_stepping_table_slowdown_factor0_f(
63 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
64 therm_grad_stepping_table_slowdown_factor1_f(
65 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
66 therm_grad_stepping_table_slowdown_factor2_f(
67 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
68 therm_grad_stepping_table_slowdown_factor3_f(
69 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()) |
70 therm_grad_stepping_table_slowdown_factor4_f(
71 therm_grad_stepping_table_slowdown_factor0_fpdiv_by8_f()));
72
73 v = gk20a_readl(g, therm_clk_timing_r(0));
74 v |= therm_clk_timing_grad_slowdown_enabled_f();
75 gk20a_writel(g, therm_clk_timing_r(0), v);
76
77 v = gk20a_readl(g, therm_config2_r());
78 v |= therm_config2_grad_enable_f(1);
79 v |= therm_config2_slowdown_factor_extended_f(1);
80 gk20a_writel(g, therm_config2_r(), v);
81
82 gk20a_writel(g, therm_grad_stepping1_r(),
83 therm_grad_stepping1_pdiv_duration_f(32));
84
85 v = gk20a_readl(g, therm_grad_stepping0_r());
86 v |= therm_grad_stepping0_feature_enable_f();
87 gk20a_writel(g, therm_grad_stepping0_r(), v);
88
89 return 0;
90}
91
92int gp10b_elcg_init_idle_filters(struct gk20a *g)
93{
94 u32 gate_ctrl, idle_filter;
95 u32 engine_id;
96 u32 active_engine_id = 0;
97 struct fifo_gk20a *f = &g->fifo;
98
99 gk20a_dbg_fn("");
100
101 for (engine_id = 0; engine_id < f->num_engines; engine_id++) {
102 active_engine_id = f->active_engines_list[engine_id];
103 gate_ctrl = gk20a_readl(g, therm_gate_ctrl_r(active_engine_id));
104
105 if (nvgpu_platform_is_simulation(g)) {
106 gate_ctrl = set_field(gate_ctrl,
107 therm_gate_ctrl_eng_delay_after_m(),
108 therm_gate_ctrl_eng_delay_after_f(4));
109 }
110
111 /* 2 * (1 << 9) = 1024 clks */
112 gate_ctrl = set_field(gate_ctrl,
113 therm_gate_ctrl_eng_idle_filt_exp_m(),
114 therm_gate_ctrl_eng_idle_filt_exp_f(9));
115 gate_ctrl = set_field(gate_ctrl,
116 therm_gate_ctrl_eng_idle_filt_mant_m(),
117 therm_gate_ctrl_eng_idle_filt_mant_f(2));
118 gate_ctrl = set_field(gate_ctrl,
119 therm_gate_ctrl_eng_delay_before_m(),
120 therm_gate_ctrl_eng_delay_before_f(4));
121 gk20a_writel(g, therm_gate_ctrl_r(active_engine_id), gate_ctrl);
122 }
123
124 /* default fecs_idle_filter to 0 */
125 idle_filter = gk20a_readl(g, therm_fecs_idle_filter_r());
126 idle_filter &= ~therm_fecs_idle_filter_value_m();
127 gk20a_writel(g, therm_fecs_idle_filter_r(), idle_filter);
128 /* default hubmmu_idle_filter to 0 */
129 idle_filter = gk20a_readl(g, therm_hubmmu_idle_filter_r());
130 idle_filter &= ~therm_hubmmu_idle_filter_value_m();
131 gk20a_writel(g, therm_hubmmu_idle_filter_r(), idle_filter);
132
133 gk20a_dbg_fn("done");
134 return 0;
135}
136
137void gp10b_init_therm_ops(struct gpu_ops *gops)
138{
139 gops->therm.init_therm_setup_hw = gp10b_init_therm_setup_hw;
140 gops->therm.elcg_init_idle_filters = gp10b_elcg_init_idle_filters;
141}
diff --git a/drivers/gpu/nvgpu/gp10b/therm_gp10b.h b/drivers/gpu/nvgpu/gp10b/therm_gp10b.h
new file mode 100644
index 00000000..2a40b73c
--- /dev/null
+++ b/drivers/gpu/nvgpu/gp10b/therm_gp10b.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22#ifndef THERM_GP10B_H
23#define THERM_GP10B_H
24
25struct gk20a;
26int gp10b_init_therm_setup_hw(struct gk20a *g);
27int gp10b_elcg_init_idle_filters(struct gk20a *g);
28
29#endif /* THERM_GP10B_H */