diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gp10b')
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 | |||
31 | static 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 | |||
38 | static 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 | |||
45 | void 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 | |||
63 | int 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 | |||
30 | void gp10b_ce_isr(struct gk20a *g, u32 inst_id, u32 pri_base); | ||
31 | int 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 | |||
28 | struct gk20a_ecc_stat; | ||
29 | |||
30 | struct 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 | |||
28 | unsigned int gp10b_fb_compression_page_size(struct gk20a *g) | ||
29 | { | ||
30 | return SZ_64K; | ||
31 | } | ||
32 | |||
33 | unsigned 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 | ||
27 | struct gk20a; | ||
28 | |||
29 | unsigned int gp10b_fb_compression_page_size(struct gk20a *g); | ||
30 | unsigned 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 | ||
34 | int 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 | |||
28 | struct gk20a; | ||
29 | |||
30 | int 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 | |||
42 | static 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 | |||
66 | int 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 | |||
94 | int 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 | |||
161 | u32 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 | |||
167 | int 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 | |||
206 | int 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 | |||
222 | void 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 | |||
246 | void 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 | |||
291 | void 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 | |||
28 | struct gpu_ops; | ||
29 | struct channel_gk20a; | ||
30 | struct fifo_gk20a; | ||
31 | struct mmu_fault_info; | ||
32 | |||
33 | int channel_gp10b_setup_ramfc(struct channel_gk20a *c, | ||
34 | u64 gpfifo_base, u32 gpfifo_entries, | ||
35 | unsigned long acquire_timeout, u32 flags); | ||
36 | u32 gp10b_fifo_get_pbdma_signature(struct gk20a *g); | ||
37 | int gp10b_fifo_resetup_ramfc(struct channel_gk20a *c); | ||
38 | int gp10b_fifo_engine_enum_from_type(struct gk20a *g, u32 engine_type, | ||
39 | u32 *inst_id); | ||
40 | void gp10b_device_info_data_parse(struct gk20a *g, u32 table_entry, | ||
41 | u32 *inst_id, u32 *pri_base, u32 *fault_id); | ||
42 | void gp10b_fifo_init_pbdma_intr_descs(struct fifo_gk20a *f); | ||
43 | void gp10b_fifo_get_mmu_fault_info(struct gk20a *g, u32 mmu_fault_id, | ||
44 | struct mmu_fault_info *mmfault); | ||
45 | int 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 | |||
34 | static 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 | |||
114 | int 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 | |||
30 | int 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 | |||
31 | struct gating_desc { | ||
32 | u32 addr; | ||
33 | u32 prod; | ||
34 | u32 disable; | ||
35 | }; | ||
36 | /* slcg bus */ | ||
37 | static const struct gating_desc gp10b_slcg_bus[] = { | ||
38 | {.addr = 0x00001c04, .prod = 0x00000000, .disable = 0x000003fe}, | ||
39 | }; | ||
40 | |||
41 | /* slcg ce2 */ | ||
42 | static const struct gating_desc gp10b_slcg_ce2[] = { | ||
43 | {.addr = 0x00104204, .prod = 0x00000000, .disable = 0x000007fe}, | ||
44 | }; | ||
45 | |||
46 | /* slcg chiplet */ | ||
47 | static 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 */ | ||
55 | static 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 */ | ||
61 | static const struct gating_desc gp10b_slcg_fifo[] = { | ||
62 | {.addr = 0x000026ac, .prod = 0x00000f40, .disable = 0x0001fffe}, | ||
63 | }; | ||
64 | |||
65 | /* slcg gr */ | ||
66 | static 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 */ | ||
122 | static 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 */ | ||
128 | static 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 */ | ||
136 | static const struct gating_desc gp10b_slcg_priring[] = { | ||
137 | {.addr = 0x001200a8, .prod = 0x00000000, .disable = 0x00000001}, | ||
138 | }; | ||
139 | |||
140 | /* slcg pwr_csb */ | ||
141 | static 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 */ | ||
149 | static 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 */ | ||
156 | static const struct gating_desc gp10b_slcg_therm[] = { | ||
157 | {.addr = 0x000206b8, .prod = 0x00000000, .disable = 0x0000000f}, | ||
158 | }; | ||
159 | |||
160 | /* slcg Xbar */ | ||
161 | static 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 */ | ||
167 | static const struct gating_desc gp10b_blcg_bus[] = { | ||
168 | {.addr = 0x00001c00, .prod = 0x00000042, .disable = 0x00000000}, | ||
169 | }; | ||
170 | |||
171 | /* blcg ce */ | ||
172 | static const struct gating_desc gp10b_blcg_ce[] = { | ||
173 | {.addr = 0x00104200, .prod = 0x00008242, .disable = 0x00000000}, | ||
174 | }; | ||
175 | |||
176 | /* blcg ctxsw prog */ | ||
177 | static const struct gating_desc gp10b_blcg_ctxsw_prog[] = { | ||
178 | }; | ||
179 | |||
180 | /* blcg fb */ | ||
181 | static 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 */ | ||
190 | static const struct gating_desc gp10b_blcg_fifo[] = { | ||
191 | {.addr = 0x000026a4, .prod = 0x0000c242, .disable = 0x00000000}, | ||
192 | }; | ||
193 | |||
194 | /* blcg gr */ | ||
195 | static 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 */ | ||
252 | static 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 */ | ||
260 | static const struct gating_desc gp10b_blcg_pwr_csb[] = { | ||
261 | {.addr = 0x00000a70, .prod = 0x00000045, .disable = 0x00000000}, | ||
262 | }; | ||
263 | |||
264 | /* blcg pmu */ | ||
265 | static const struct gating_desc gp10b_blcg_pmu[] = { | ||
266 | {.addr = 0x0010aa70, .prod = 0x00000045, .disable = 0x00000000}, | ||
267 | }; | ||
268 | |||
269 | /* blcg Xbar */ | ||
270 | static 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 */ | ||
276 | static const struct gating_desc gp10b_pg_gr[] = { | ||
277 | }; | ||
278 | |||
279 | /* inline functions */ | ||
280 | void 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 | |||
299 | void 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 | |||
318 | void 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 | |||
337 | void gp10b_slcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, | ||
338 | bool prod) | ||
339 | { | ||
340 | } | ||
341 | |||
342 | void 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 | |||
361 | void 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 | |||
380 | void 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 | |||
399 | void 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 | |||
418 | void 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 | |||
437 | void 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 | |||
456 | void 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 | |||
475 | void 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 | |||
494 | void 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 | |||
513 | void 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 | |||
532 | void 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 | |||
551 | void 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 | |||
570 | void 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 | |||
589 | void 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 | |||
608 | void 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 | |||
627 | void 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 | |||
646 | void 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 | |||
665 | void 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 | |||
684 | void 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 | |||
703 | void 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 | |||
722 | void 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 | |||
25 | void gp10b_slcg_bus_load_gating_prod(struct gk20a *g, | ||
26 | bool prod); | ||
27 | |||
28 | void gp10b_slcg_ce2_load_gating_prod(struct gk20a *g, | ||
29 | bool prod); | ||
30 | |||
31 | void gp10b_slcg_chiplet_load_gating_prod(struct gk20a *g, | ||
32 | bool prod); | ||
33 | |||
34 | void gp10b_slcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, | ||
35 | bool prod); | ||
36 | |||
37 | void gp10b_slcg_fb_load_gating_prod(struct gk20a *g, | ||
38 | bool prod); | ||
39 | |||
40 | void gp10b_slcg_fifo_load_gating_prod(struct gk20a *g, | ||
41 | bool prod); | ||
42 | |||
43 | void gr_gp10b_slcg_gr_load_gating_prod(struct gk20a *g, | ||
44 | bool prod); | ||
45 | |||
46 | void ltc_gp10b_slcg_ltc_load_gating_prod(struct gk20a *g, | ||
47 | bool prod); | ||
48 | |||
49 | void gp10b_slcg_perf_load_gating_prod(struct gk20a *g, | ||
50 | bool prod); | ||
51 | |||
52 | void gp10b_slcg_priring_load_gating_prod(struct gk20a *g, | ||
53 | bool prod); | ||
54 | |||
55 | void gp10b_slcg_pwr_csb_load_gating_prod(struct gk20a *g, | ||
56 | bool prod); | ||
57 | |||
58 | void gp10b_slcg_pmu_load_gating_prod(struct gk20a *g, | ||
59 | bool prod); | ||
60 | |||
61 | void gp10b_slcg_therm_load_gating_prod(struct gk20a *g, | ||
62 | bool prod); | ||
63 | |||
64 | void gp10b_slcg_xbar_load_gating_prod(struct gk20a *g, | ||
65 | bool prod); | ||
66 | |||
67 | void gp10b_blcg_bus_load_gating_prod(struct gk20a *g, | ||
68 | bool prod); | ||
69 | |||
70 | void gp10b_blcg_ce_load_gating_prod(struct gk20a *g, | ||
71 | bool prod); | ||
72 | |||
73 | void gp10b_blcg_ctxsw_firmware_load_gating_prod(struct gk20a *g, | ||
74 | bool prod); | ||
75 | |||
76 | void gp10b_blcg_fb_load_gating_prod(struct gk20a *g, | ||
77 | bool prod); | ||
78 | |||
79 | void gp10b_blcg_fifo_load_gating_prod(struct gk20a *g, | ||
80 | bool prod); | ||
81 | |||
82 | void gp10b_blcg_gr_load_gating_prod(struct gk20a *g, | ||
83 | bool prod); | ||
84 | |||
85 | void gp10b_blcg_ltc_load_gating_prod(struct gk20a *g, | ||
86 | bool prod); | ||
87 | |||
88 | void gp10b_blcg_pwr_csb_load_gating_prod(struct gk20a *g, | ||
89 | bool prod); | ||
90 | |||
91 | void gp10b_blcg_pmu_load_gating_prod(struct gk20a *g, | ||
92 | bool prod); | ||
93 | |||
94 | void gp10b_blcg_xbar_load_gating_prod(struct gk20a *g, | ||
95 | bool prod); | ||
96 | |||
97 | void 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 | |||
30 | int 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 | |||
65 | bool 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 | |||
32 | int gr_gp10b_get_netlist_name(struct gk20a *g, int index, char *name); | ||
33 | bool 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 | |||
53 | bool 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 | |||
79 | bool 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 | |||
87 | bool 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 | |||
96 | static 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 | |||
131 | int 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 | |||
256 | int 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 | |||
392 | int 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 | |||
499 | void 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 | |||
517 | int 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 | |||
572 | int 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 | |||
610 | u32 gr_gp10b_pagepool_default_size(struct gk20a *g) | ||
611 | { | ||
612 | return gr_scc_pagepool_total_pages_hwmax_value_v(); | ||
613 | } | ||
614 | |||
615 | int 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 | |||
641 | static 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 | |||
646 | static 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 | |||
660 | void 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 | |||
685 | int 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 | |||
732 | fail: | ||
733 | return -EINVAL; | ||
734 | } | ||
735 | |||
736 | void 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 | |||
746 | void 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 | |||
800 | void 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 | |||
867 | int 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 | |||
903 | int 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 | |||
929 | fail_free: | ||
930 | nvgpu_dma_free(vm->mm->g, mem); | ||
931 | return err; | ||
932 | } | ||
933 | |||
934 | int 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 | |||
1048 | fail_free_betacb: | ||
1049 | nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.betacb_ctxsw_buffer); | ||
1050 | fail_free_spill: | ||
1051 | nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.spill_ctxsw_buffer); | ||
1052 | fail_free_preempt: | ||
1053 | nvgpu_dma_unmap_free(vm, &gr_ctx->t18x.preempt_ctxsw_buffer); | ||
1054 | fail: | ||
1055 | return err; | ||
1056 | } | ||
1057 | |||
1058 | int 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 | |||
1096 | fail_free_gk20a_ctx: | ||
1097 | gr_gk20a_free_gr_ctx(g, vm, *gr_ctx); | ||
1098 | *gr_ctx = NULL; | ||
1099 | |||
1100 | return err; | ||
1101 | } | ||
1102 | |||
1103 | static 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 | |||
1155 | void 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 | |||
1175 | void 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 | |||
1284 | out: | ||
1285 | gk20a_dbg_fn("done"); | ||
1286 | } | ||
1287 | |||
1288 | int 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 | |||
1421 | static 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 | |||
1434 | int 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 | |||
1485 | void 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 | |||
1513 | void 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 | |||
1548 | int 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 | |||
1593 | int 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 | |||
1618 | void 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 | |||
1631 | void 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 | |||
1672 | static 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 | |||
1710 | int 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 | |||
1792 | static 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 | */ | ||
1821 | int 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 | |||
1921 | static 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 | |||
1946 | int 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 | |||
2003 | clean_up: | ||
2004 | /* handle any remaining interrupts */ | ||
2005 | return gk20a_gr_handle_fecs_error(g, __ch, isr_data); | ||
2006 | } | ||
2007 | |||
2008 | u32 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 | |||
2023 | u32 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 | |||
2034 | static 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 | |||
2066 | int 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 | |||
2138 | clean_up: | ||
2139 | return err; | ||
2140 | } | ||
2141 | |||
2142 | int 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 | |||
2168 | enable_ch: | ||
2169 | gk20a_enable_channel_tsg(g, ch); | ||
2170 | unmap_ctx: | ||
2171 | nvgpu_mem_end(g, mem); | ||
2172 | |||
2173 | return err; | ||
2174 | } | ||
2175 | |||
2176 | void 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 | |||
2185 | int 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 | |||
2267 | enable_ch: | ||
2268 | gk20a_enable_channel_tsg(g, ch); | ||
2269 | unmap_ctx: | ||
2270 | nvgpu_mem_end(g, ctxheader); | ||
2271 | unamp_ctx_header: | ||
2272 | nvgpu_mem_end(g, mem); | ||
2273 | |||
2274 | return err; | ||
2275 | } | ||
2276 | |||
2277 | int 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 | |||
2296 | int 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 | |||
2313 | void 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 | |||
2323 | void gr_gp10b_init_czf_bypass(struct gk20a *g) | ||
2324 | { | ||
2325 | g->gr.czf_bypass = gr_gpc0_prop_debug1_czf_bypass_init_v(); | ||
2326 | } | ||
2327 | |||
2328 | int 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 | |||
2345 | void 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 | |||
30 | struct gk20a; | ||
31 | struct gr_gk20a_isr_data; | ||
32 | struct channel_ctx_gk20a; | ||
33 | struct zbc_entry; | ||
34 | struct gr_ctx_desc; | ||
35 | struct nvgpu_preemption_modes_rec; | ||
36 | struct gk20a_debug_output; | ||
37 | |||
38 | enum { | ||
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 | |||
56 | int gr_gp10b_init_fs_state(struct gk20a *g); | ||
57 | int gr_gp10b_alloc_buffer(struct vm_gk20a *vm, size_t size, | ||
58 | struct nvgpu_mem *mem); | ||
59 | void gr_gp10b_create_sysfs(struct gk20a *g); | ||
60 | int gr_gp10b_handle_fecs_error(struct gk20a *g, | ||
61 | struct channel_gk20a *__ch, | ||
62 | struct gr_gk20a_isr_data *isr_data); | ||
63 | int gr_gp10b_set_cilp_preempt_pending(struct gk20a *g, | ||
64 | struct channel_gk20a *fault_ch); | ||
65 | |||
66 | bool gr_gp10b_is_valid_class(struct gk20a *g, u32 class_num); | ||
67 | bool gr_gp10b_is_valid_gfx_class(struct gk20a *g, u32 class_num); | ||
68 | bool gr_gp10b_is_valid_compute_class(struct gk20a *g, u32 class_num); | ||
69 | int 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); | ||
73 | int gr_gp10b_handle_tex_exception(struct gk20a *g, u32 gpc, u32 tpc, | ||
74 | bool *post_event); | ||
75 | int gr_gp10b_commit_global_cb_manager(struct gk20a *g, | ||
76 | struct channel_gk20a *c, bool patch); | ||
77 | void gr_gp10b_commit_global_pagepool(struct gk20a *g, | ||
78 | struct channel_ctx_gk20a *ch_ctx, | ||
79 | u64 addr, u32 size, bool patch); | ||
80 | int gr_gp10b_add_zbc_color(struct gk20a *g, struct gr_gk20a *gr, | ||
81 | struct zbc_entry *color_val, u32 index); | ||
82 | int gr_gp10b_add_zbc_depth(struct gk20a *g, struct gr_gk20a *gr, | ||
83 | struct zbc_entry *depth_val, u32 index); | ||
84 | u32 gr_gp10b_pagepool_default_size(struct gk20a *g); | ||
85 | int gr_gp10b_calc_global_ctx_buffer_size(struct gk20a *g); | ||
86 | void gr_gp10b_set_bes_crop_debug3(struct gk20a *g, u32 data); | ||
87 | int gr_gp10b_handle_sw_method(struct gk20a *g, u32 addr, | ||
88 | u32 class_num, u32 offset, u32 data); | ||
89 | void gr_gp10b_cb_size_default(struct gk20a *g); | ||
90 | void gr_gp10b_set_alpha_circular_buffer_size(struct gk20a *g, u32 data); | ||
91 | void gr_gp10b_set_circular_buffer_size(struct gk20a *g, u32 data); | ||
92 | int gr_gp10b_init_ctx_state(struct gk20a *g); | ||
93 | int 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); | ||
98 | int 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); | ||
102 | void gr_gp10b_free_gr_ctx(struct gk20a *g, struct vm_gk20a *vm, | ||
103 | struct gr_ctx_desc *gr_ctx); | ||
104 | void gr_gp10b_update_ctxsw_preemption_mode(struct gk20a *g, | ||
105 | struct channel_ctx_gk20a *ch_ctx, | ||
106 | struct nvgpu_mem *mem); | ||
107 | int gr_gp10b_dump_gr_status_regs(struct gk20a *g, | ||
108 | struct gk20a_debug_output *o); | ||
109 | int gr_gp10b_wait_empty(struct gk20a *g, unsigned long duration_ms, | ||
110 | u32 expect_delay); | ||
111 | void gr_gp10b_commit_global_attrib_cb(struct gk20a *g, | ||
112 | struct channel_ctx_gk20a *ch_ctx, | ||
113 | u64 addr, bool patch); | ||
114 | void gr_gp10b_commit_global_bundle_cb(struct gk20a *g, | ||
115 | struct channel_ctx_gk20a *ch_ctx, | ||
116 | u64 addr, u64 size, bool patch); | ||
117 | int gr_gp10b_load_smid_config(struct gk20a *g); | ||
118 | void gr_gp10b_set_gpc_tpc_mask(struct gk20a *g, u32 gpc_index); | ||
119 | void gr_gp10b_get_access_map(struct gk20a *g, | ||
120 | u32 **whitelist, int *num_entries); | ||
121 | int 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); | ||
125 | u32 gp10b_gr_get_sm_hww_warp_esr(struct gk20a *g, | ||
126 | u32 gpc, u32 tpc, u32 sm); | ||
127 | u32 get_ecc_override_val(struct gk20a *g); | ||
128 | int gr_gp10b_suspend_contexts(struct gk20a *g, | ||
129 | struct dbg_session_gk20a *dbg_s, | ||
130 | int *ctx_resident_ch_fd); | ||
131 | int gr_gp10b_set_boosted_ctx(struct channel_gk20a *ch, | ||
132 | bool boost); | ||
133 | void gr_gp10b_update_boosted_ctx(struct gk20a *g, struct nvgpu_mem *mem, | ||
134 | struct gr_ctx_desc *gr_ctx); | ||
135 | int gr_gp10b_set_preemption_mode(struct channel_gk20a *ch, | ||
136 | u32 graphics_preempt_mode, | ||
137 | u32 compute_preempt_mode); | ||
138 | int gr_gp10b_get_preemption_mode_flags(struct gk20a *g, | ||
139 | struct nvgpu_preemption_modes_rec *preemption_modes_rec); | ||
140 | int gp10b_gr_fuse_override(struct gk20a *g); | ||
141 | int gr_gp10b_init_preemption_state(struct gk20a *g); | ||
142 | void gr_gp10b_set_preemption_buffer_va(struct gk20a *g, | ||
143 | struct nvgpu_mem *mem, u64 gpu_va); | ||
144 | int gr_gp10b_set_czf_bypass(struct gk20a *g, struct channel_gk20a *ch); | ||
145 | void gr_gp10b_init_czf_bypass(struct gk20a *g); | ||
146 | void gr_gp10b_init_ctxsw_hdr_data(struct gk20a *g, struct nvgpu_mem *mem); | ||
147 | |||
148 | struct 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 | |||
161 | struct 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 | |||
82 | int 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 | |||
193 | static 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 | |||
626 | int 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 | ||
27 | struct gk20a; | ||
28 | |||
29 | int gp10b_init_hal(struct gk20a *gops); | ||
30 | int 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 | |||
39 | int 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 | |||
59 | int 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 | |||
131 | void 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 | |||
196 | void 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 | |||
213 | void 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 | ||
25 | struct gpu_ops; | ||
26 | |||
27 | void gp10b_ltc_isr(struct gk20a *g); | ||
28 | |||
29 | int gp10b_determine_L2_size_bytes(struct gk20a *g); | ||
30 | int gp10b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr); | ||
31 | void gp10b_ltc_init_fs_state(struct gk20a *g); | ||
32 | void 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 | |||
35 | void 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 | |||
60 | void 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 | |||
80 | void 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 | |||
130 | u32 mc_gp10b_intr_stall(struct gk20a *g) | ||
131 | { | ||
132 | return gk20a_readl(g, mc_intr_r(NVGPU_MC_INTR_STALLING)); | ||
133 | } | ||
134 | |||
135 | void 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 | |||
140 | void 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 | |||
146 | u32 mc_gp10b_intr_nonstall(struct gk20a *g) | ||
147 | { | ||
148 | return gk20a_readl(g, mc_intr_r(NVGPU_MC_INTR_NONSTALLING)); | ||
149 | } | ||
150 | |||
151 | void 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 | |||
157 | void 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 | |||
163 | bool 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 | ||
25 | struct gk20a; | ||
26 | |||
27 | enum MC_INTERRUPT_REGLIST { | ||
28 | NVGPU_MC_INTR_STALLING = 0, | ||
29 | NVGPU_MC_INTR_NONSTALLING, | ||
30 | }; | ||
31 | |||
32 | void mc_gp10b_intr_enable(struct gk20a *g); | ||
33 | void mc_gp10b_intr_unit_config(struct gk20a *g, bool enable, | ||
34 | bool is_stalling, u32 mask); | ||
35 | void mc_gp10b_isr_stall(struct gk20a *g); | ||
36 | bool mc_gp10b_is_intr1_pending(struct gk20a *g, | ||
37 | enum nvgpu_unit unit, u32 mc_intr_1); | ||
38 | |||
39 | u32 mc_gp10b_intr_stall(struct gk20a *g); | ||
40 | void mc_gp10b_intr_stall_pause(struct gk20a *g); | ||
41 | void mc_gp10b_intr_stall_resume(struct gk20a *g); | ||
42 | u32 mc_gp10b_intr_nonstall(struct gk20a *g); | ||
43 | void mc_gp10b_intr_nonstall_pause(struct gk20a *g); | ||
44 | void 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 | |||
39 | u32 gp10b_mm_get_default_big_page_size(void) | ||
40 | { | ||
41 | return SZ_64K; | ||
42 | } | ||
43 | |||
44 | u32 gp10b_mm_get_iommu_bit(struct gk20a *g) | ||
45 | { | ||
46 | return 36; | ||
47 | } | ||
48 | |||
49 | int 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 | |||
80 | int 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 | |||
106 | clean_up_va: | ||
107 | nvgpu_vm_put(mm->bar2.vm); | ||
108 | return err; | ||
109 | } | ||
110 | |||
111 | int 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 | |||
135 | static 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 | |||
168 | static 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 | |||
226 | static 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 | |||
271 | static 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 | |||
277 | static 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 | */ | ||
329 | static 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 | |||
383 | static 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 | |||
412 | const 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 | |||
418 | void 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 | |||
439 | void 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 | |||
26 | struct gk20a; | ||
27 | struct gk20a_mmu_level; | ||
28 | struct nvgpu_mem; | ||
29 | struct vm_gk20a; | ||
30 | |||
31 | u32 gp10b_mm_get_default_big_page_size(void); | ||
32 | u32 gp10b_mm_get_iommu_bit(struct gk20a *g); | ||
33 | int gp10b_init_mm_setup_hw(struct gk20a *g); | ||
34 | int gb10b_init_bar2_vm(struct gk20a *g); | ||
35 | int gb10b_init_bar2_mm_hw_setup(struct gk20a *g); | ||
36 | const struct gk20a_mmu_level *gp10b_mm_get_mmu_levels(struct gk20a *g, | ||
37 | u32 big_page_size); | ||
38 | void gp10b_mm_init_pdb(struct gk20a *g, struct nvgpu_mem *inst_block, | ||
39 | struct vm_gk20a *vm); | ||
40 | void 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 | |||
28 | struct device; | ||
29 | |||
30 | int gp10b_tegra_get_clocks(struct device *dev); | ||
31 | int gp10b_tegra_reset_assert(struct device *dev); | ||
32 | int 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 | */ | ||
46 | struct pg_init_sequence_list { | ||
47 | u32 regaddr; | ||
48 | u32 writeval; | ||
49 | }; | ||
50 | |||
51 | /* PROD settings for ELPG sequencing registers*/ | ||
52 | static 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 | |||
151 | static 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 | |||
185 | int 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 | |||
217 | static 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 | |||
234 | int 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 | |||
262 | void 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 | |||
279 | int 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 | |||
301 | void 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 | |||
309 | int 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 | |||
347 | bool 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 | |||
365 | bool 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*/ | ||
384 | void 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 | |||
396 | bool 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 | |||
28 | struct gk20a; | ||
29 | |||
30 | |||
31 | bool gp10b_is_lazy_bootstrap(u32 falcon_id); | ||
32 | bool gp10b_is_priv_load(u32 falcon_id); | ||
33 | bool gp10b_is_pmu_supported(struct gk20a *g); | ||
34 | int gp10b_init_pmu_setup_hw1(struct gk20a *g); | ||
35 | void gp10b_pmu_elpg_statistics(struct gk20a *g, u32 pg_engine_id, | ||
36 | struct pmu_pg_stats_data *pg_stat_data); | ||
37 | int gp10b_pmu_setup_elpg(struct gk20a *g); | ||
38 | void pmu_dump_security_fuses_gp10b(struct gk20a *g); | ||
39 | int gp10b_load_falcon_ucode(struct gk20a *g, u32 falconidmask); | ||
40 | int gp10b_pg_gr_init(struct gk20a *g, u32 pg_engine_id); | ||
41 | void 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 | |||
36 | void 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 | |||
27 | struct gk20a; | ||
28 | |||
29 | void 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 | |||
34 | static 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 | |||
387 | static const u32 gp10b_global_whitelist_ranges_count = | ||
388 | ARRAY_SIZE(gp10b_global_whitelist_ranges); | ||
389 | |||
390 | /* context */ | ||
391 | |||
392 | /* runcontrol */ | ||
393 | static const u32 gp10b_runcontrol_whitelist[] = { | ||
394 | }; | ||
395 | static const u32 gp10b_runcontrol_whitelist_count = | ||
396 | ARRAY_SIZE(gp10b_runcontrol_whitelist); | ||
397 | |||
398 | static const struct regop_offset_range gp10b_runcontrol_whitelist_ranges[] = { | ||
399 | }; | ||
400 | static const u32 gp10b_runcontrol_whitelist_ranges_count = | ||
401 | ARRAY_SIZE(gp10b_runcontrol_whitelist_ranges); | ||
402 | |||
403 | |||
404 | /* quad ctl */ | ||
405 | static const u32 gp10b_qctl_whitelist[] = { | ||
406 | }; | ||
407 | static const u32 gp10b_qctl_whitelist_count = | ||
408 | ARRAY_SIZE(gp10b_qctl_whitelist); | ||
409 | |||
410 | static const struct regop_offset_range gp10b_qctl_whitelist_ranges[] = { | ||
411 | }; | ||
412 | static const u32 gp10b_qctl_whitelist_ranges_count = | ||
413 | ARRAY_SIZE(gp10b_qctl_whitelist_ranges); | ||
414 | |||
415 | const struct regop_offset_range *gp10b_get_global_whitelist_ranges(void) | ||
416 | { | ||
417 | return gp10b_global_whitelist_ranges; | ||
418 | } | ||
419 | |||
420 | int gp10b_get_global_whitelist_ranges_count(void) | ||
421 | { | ||
422 | return gp10b_global_whitelist_ranges_count; | ||
423 | } | ||
424 | |||
425 | const struct regop_offset_range *gp10b_get_context_whitelist_ranges(void) | ||
426 | { | ||
427 | return gp10b_global_whitelist_ranges; | ||
428 | } | ||
429 | |||
430 | int gp10b_get_context_whitelist_ranges_count(void) | ||
431 | { | ||
432 | return gp10b_global_whitelist_ranges_count; | ||
433 | } | ||
434 | |||
435 | const u32 *gp10b_get_runcontrol_whitelist(void) | ||
436 | { | ||
437 | return gp10b_runcontrol_whitelist; | ||
438 | } | ||
439 | |||
440 | int gp10b_get_runcontrol_whitelist_count(void) | ||
441 | { | ||
442 | return gp10b_runcontrol_whitelist_count; | ||
443 | } | ||
444 | |||
445 | const struct regop_offset_range *gp10b_get_runcontrol_whitelist_ranges(void) | ||
446 | { | ||
447 | return gp10b_runcontrol_whitelist_ranges; | ||
448 | } | ||
449 | |||
450 | int gp10b_get_runcontrol_whitelist_ranges_count(void) | ||
451 | { | ||
452 | return gp10b_runcontrol_whitelist_ranges_count; | ||
453 | } | ||
454 | |||
455 | const u32 *gp10b_get_qctl_whitelist(void) | ||
456 | { | ||
457 | return gp10b_qctl_whitelist; | ||
458 | } | ||
459 | |||
460 | int gp10b_get_qctl_whitelist_count(void) | ||
461 | { | ||
462 | return gp10b_qctl_whitelist_count; | ||
463 | } | ||
464 | |||
465 | const struct regop_offset_range *gp10b_get_qctl_whitelist_ranges(void) | ||
466 | { | ||
467 | return gp10b_qctl_whitelist_ranges; | ||
468 | } | ||
469 | |||
470 | int gp10b_get_qctl_whitelist_ranges_count(void) | ||
471 | { | ||
472 | return gp10b_qctl_whitelist_ranges_count; | ||
473 | } | ||
474 | |||
475 | int 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 | |||
28 | struct dbg_session_gk20a; | ||
29 | |||
30 | const struct regop_offset_range *gp10b_get_global_whitelist_ranges(void); | ||
31 | int gp10b_get_global_whitelist_ranges_count(void); | ||
32 | const struct regop_offset_range *gp10b_get_context_whitelist_ranges(void); | ||
33 | int gp10b_get_context_whitelist_ranges_count(void); | ||
34 | const u32 *gp10b_get_runcontrol_whitelist(void); | ||
35 | int gp10b_get_runcontrol_whitelist_count(void); | ||
36 | const struct regop_offset_range *gp10b_get_runcontrol_whitelist_ranges(void); | ||
37 | int gp10b_get_runcontrol_whitelist_ranges_count(void); | ||
38 | const u32 *gp10b_get_qctl_whitelist(void); | ||
39 | int gp10b_get_qctl_whitelist_count(void); | ||
40 | const struct regop_offset_range *gp10b_get_qctl_whitelist_ranges(void); | ||
41 | int gp10b_get_qctl_whitelist_ranges_count(void); | ||
42 | int 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 | |||
36 | int 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 | |||
67 | void 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 | |||
74 | u32 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 | |||
89 | u32 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 | |||
103 | bool 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 | |||
111 | bool 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 | |||
120 | bool 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 | |||
127 | void 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 | |||
136 | void 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 | ||
25 | struct gk20a; | ||
26 | |||
27 | #define NV_UVM_FAULT_BUF_SIZE 32 | ||
28 | |||
29 | int gp10b_replayable_pagefault_buffer_init(struct gk20a *g); | ||
30 | u32 gp10b_replayable_pagefault_buffer_get_index(struct gk20a *g); | ||
31 | u32 gp10b_replayable_pagefault_buffer_put_index(struct gk20a *g); | ||
32 | bool gp10b_replayable_pagefault_buffer_is_empty(struct gk20a *g); | ||
33 | bool gp10b_replayable_pagefault_buffer_is_full(struct gk20a *g); | ||
34 | bool gp10b_replayable_pagefault_buffer_is_overflow(struct gk20a *g); | ||
35 | void gp10b_replayable_pagefault_buffer_clear_overflow(struct gk20a *g); | ||
36 | void gp10b_replayable_pagefault_buffer_info(struct gk20a *g); | ||
37 | void 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 | |||
32 | int 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 | |||
92 | int 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 | |||
137 | void 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 | |||
25 | struct gk20a; | ||
26 | int gp10b_init_therm_setup_hw(struct gk20a *g); | ||
27 | int gp10b_elcg_init_idle_filters(struct gk20a *g); | ||
28 | |||
29 | #endif /* THERM_GP10B_H */ | ||