diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2017-03-17 14:09:44 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-03-23 11:44:07 -0400 |
commit | 4492c62ffe9398bd4457f6f1c2773e40afe909fb (patch) | |
tree | 5d792f81d97844278f4eca665a8b4778fa93dc35 | |
parent | 33f637585ecd617a9f4423f56e2aa6df0691ac64 (diff) |
gpu: nvgpu: Add bus HAL
Add bus HAL and move all bus related hardware sequencing to that file:
BAR1 binding, timer access, and interrupt handling.
Change-Id: Ibc5f5797dc338de10749b446a7bdbcae600fecb4
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/1323353
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r-- | drivers/gpu/nvgpu/Makefile.nvgpu | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_arb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_mclk.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/bus_gk20a.c | 156 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/bus_gk20a.h | 29 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 104 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 12 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hal_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mc_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 25 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/bus_gm20b.c | 64 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/bus_gm20b.h | 23 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/hal_gm20b.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/mm_gm20b.c | 34 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp106/hal_gp106.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/hal_gp10b.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mc_gp10b.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/mm_gp10b.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/vgpu.c | 2 |
21 files changed, 306 insertions, 177 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu index 3852e728..9cf5195b 100644 --- a/drivers/gpu/nvgpu/Makefile.nvgpu +++ b/drivers/gpu/nvgpu/Makefile.nvgpu | |||
@@ -34,6 +34,7 @@ nvgpu-y := \ | |||
34 | common/semaphore.o \ | 34 | common/semaphore.o \ |
35 | common/vbios/bios.o \ | 35 | common/vbios/bios.o \ |
36 | gk20a/gk20a.o \ | 36 | gk20a/gk20a.o \ |
37 | gk20a/bus_gk20a.o \ | ||
37 | gk20a/sched_gk20a.o \ | 38 | gk20a/sched_gk20a.o \ |
38 | gk20a/as_gk20a.o \ | 39 | gk20a/as_gk20a.o \ |
39 | gk20a/ctrl_gk20a.o \ | 40 | gk20a/ctrl_gk20a.o \ |
@@ -67,6 +68,7 @@ nvgpu-y := \ | |||
67 | gk20a/mc_gk20a.o \ | 68 | gk20a/mc_gk20a.o \ |
68 | gk20a/sim_gk20a.o \ | 69 | gk20a/sim_gk20a.o \ |
69 | gm20b/hal_gm20b.o \ | 70 | gm20b/hal_gm20b.o \ |
71 | gm20b/bus_gm20b.o \ | ||
70 | gm20b/ltc_gm20b.o \ | 72 | gm20b/ltc_gm20b.o \ |
71 | gm20b/ce2_gm20b.o \ | 73 | gm20b/ce2_gm20b.o \ |
72 | gm20b/gr_gm20b.o \ | 74 | gm20b/gr_gm20b.o \ |
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c index 30447d3e..fc821235 100644 --- a/drivers/gpu/nvgpu/clk/clk_arb.c +++ b/drivers/gpu/nvgpu/clk/clk_arb.c | |||
@@ -1062,7 +1062,7 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work) | |||
1062 | goto exit_arb; | 1062 | goto exit_arb; |
1063 | 1063 | ||
1064 | #ifdef CONFIG_DEBUG_FS | 1064 | #ifdef CONFIG_DEBUG_FS |
1065 | g->ops.read_ptimer(g, &t0); | 1065 | g->ops.bus.read_ptimer(g, &t0); |
1066 | #endif | 1066 | #endif |
1067 | 1067 | ||
1068 | /* Only one arbiter should be running */ | 1068 | /* Only one arbiter should be running */ |
@@ -1248,7 +1248,7 @@ static void nvgpu_clk_arb_run_arbiter_cb(struct work_struct *work) | |||
1248 | wake_up_interruptible(&arb->request_wq); | 1248 | wake_up_interruptible(&arb->request_wq); |
1249 | 1249 | ||
1250 | #ifdef CONFIG_DEBUG_FS | 1250 | #ifdef CONFIG_DEBUG_FS |
1251 | g->ops.read_ptimer(g, &t1); | 1251 | g->ops.bus.read_ptimer(g, &t1); |
1252 | 1252 | ||
1253 | debug = arb->debug == &arb->debug_pool[0] ? | 1253 | debug = arb->debug == &arb->debug_pool[0] ? |
1254 | &arb->debug_pool[1] : &arb->debug_pool[0]; | 1254 | &arb->debug_pool[1] : &arb->debug_pool[0]; |
diff --git a/drivers/gpu/nvgpu/clk/clk_mclk.c b/drivers/gpu/nvgpu/clk/clk_mclk.c index c2e9b35c..e5452051 100644 --- a/drivers/gpu/nvgpu/clk/clk_mclk.c +++ b/drivers/gpu/nvgpu/clk/clk_mclk.c | |||
@@ -2311,7 +2311,7 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, u16 val) | |||
2311 | pseq_cmd->cmd_type = NV_PMU_SEQ_CMD_ID_RUN_SCRIPT; | 2311 | pseq_cmd->cmd_type = NV_PMU_SEQ_CMD_ID_RUN_SCRIPT; |
2312 | 2312 | ||
2313 | #ifdef CONFIG_DEBUG_FS | 2313 | #ifdef CONFIG_DEBUG_FS |
2314 | g->ops.read_ptimer(g, &t0); | 2314 | g->ops.bus.read_ptimer(g, &t0); |
2315 | #endif | 2315 | #endif |
2316 | 2316 | ||
2317 | if (speed == gk20a_mclk_high_speed) { | 2317 | if (speed == gk20a_mclk_high_speed) { |
@@ -2362,7 +2362,7 @@ int clk_mclkseq_change_mclk_gddr5(struct gk20a *g, u16 val) | |||
2362 | mclk->speed = speed; | 2362 | mclk->speed = speed; |
2363 | 2363 | ||
2364 | #ifdef CONFIG_DEBUG_FS | 2364 | #ifdef CONFIG_DEBUG_FS |
2365 | g->ops.read_ptimer(g, &t1); | 2365 | g->ops.bus.read_ptimer(g, &t1); |
2366 | 2366 | ||
2367 | nvgpu_mutex_acquire(&mclk->data_lock); | 2367 | nvgpu_mutex_acquire(&mclk->data_lock); |
2368 | mclk->switch_num++; | 2368 | mclk->switch_num++; |
diff --git a/drivers/gpu/nvgpu/gk20a/bus_gk20a.c b/drivers/gpu/nvgpu/gk20a/bus_gk20a.c new file mode 100644 index 00000000..fda1f80e --- /dev/null +++ b/drivers/gpu/nvgpu/gk20a/bus_gk20a.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <soc/tegra/chip-id.h> | ||
18 | |||
19 | #include <nvgpu/page_allocator.h> | ||
20 | |||
21 | #include "gk20a.h" | ||
22 | |||
23 | #include <nvgpu/hw/gk20a/hw_bus_gk20a.h> | ||
24 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> | ||
25 | #include <nvgpu/hw/gk20a/hw_gr_gk20a.h> | ||
26 | #include <nvgpu/hw/gk20a/hw_timer_gk20a.h> | ||
27 | |||
28 | void gk20a_bus_init_hw(struct gk20a *g) | ||
29 | { | ||
30 | struct gk20a_platform *platform = gk20a_get_platform(g->dev); | ||
31 | |||
32 | /* enable pri timeout only on silicon */ | ||
33 | if (tegra_platform_is_silicon()) { | ||
34 | gk20a_writel(g, | ||
35 | timer_pri_timeout_r(), | ||
36 | timer_pri_timeout_period_f( | ||
37 | platform->default_pri_timeout ? | ||
38 | platform->default_pri_timeout : | ||
39 | 0x186A0) | | ||
40 | timer_pri_timeout_en_en_enabled_f()); | ||
41 | } else { | ||
42 | gk20a_writel(g, | ||
43 | timer_pri_timeout_r(), | ||
44 | timer_pri_timeout_period_f(0x186A0) | | ||
45 | timer_pri_timeout_en_en_disabled_f()); | ||
46 | } | ||
47 | |||
48 | if (!tegra_platform_is_silicon()) | ||
49 | gk20a_writel(g, bus_intr_en_0_r(), 0x0); | ||
50 | else | ||
51 | gk20a_writel(g, bus_intr_en_0_r(), | ||
52 | bus_intr_en_0_pri_squash_m() | | ||
53 | bus_intr_en_0_pri_fecserr_m() | | ||
54 | bus_intr_en_0_pri_timeout_m()); | ||
55 | } | ||
56 | |||
57 | void gk20a_bus_isr(struct gk20a *g) | ||
58 | { | ||
59 | u32 val, err_code; | ||
60 | val = gk20a_readl(g, bus_intr_0_r()); | ||
61 | if (val & (bus_intr_0_pri_squash_m() | | ||
62 | bus_intr_0_pri_fecserr_m() | | ||
63 | bus_intr_0_pri_timeout_m())) { | ||
64 | gk20a_dbg(gpu_dbg_intr, "pmc_enable : 0x%x", | ||
65 | gk20a_readl(g, mc_enable_r())); | ||
66 | gk20a_dbg(gpu_dbg_intr, "NV_PBUS_INTR_0 : 0x%x", val); | ||
67 | gk20a_dbg(gpu_dbg_intr, | ||
68 | "NV_PTIMER_PRI_TIMEOUT_SAVE_0: 0x%x\n", | ||
69 | gk20a_readl(g, timer_pri_timeout_save_0_r())); | ||
70 | gk20a_dbg(gpu_dbg_intr, | ||
71 | "NV_PTIMER_PRI_TIMEOUT_SAVE_1: 0x%x\n", | ||
72 | gk20a_readl(g, timer_pri_timeout_save_1_r())); | ||
73 | err_code = gk20a_readl(g, timer_pri_timeout_fecs_errcode_r()); | ||
74 | gk20a_dbg(gpu_dbg_intr, | ||
75 | "NV_PTIMER_PRI_TIMEOUT_FECS_ERRCODE: 0x%x\n", | ||
76 | err_code); | ||
77 | if (err_code == 0xbadf13) | ||
78 | gk20a_dbg(gpu_dbg_intr, | ||
79 | "NV_PGRAPH_PRI_GPC0_GPCCS_FS_GPC: 0x%x\n", | ||
80 | gk20a_readl(g, gr_gpc0_fs_gpc_r())); | ||
81 | |||
82 | gk20a_writel(g, timer_pri_timeout_save_0_r(), 0); | ||
83 | gk20a_writel(g, timer_pri_timeout_save_1_r(), 0); | ||
84 | } | ||
85 | |||
86 | if (val) | ||
87 | gk20a_dbg(gpu_dbg_intr, | ||
88 | "Unhandled pending pbus interrupt\n"); | ||
89 | |||
90 | gk20a_writel(g, bus_intr_0_r(), val); | ||
91 | } | ||
92 | |||
93 | int gk20a_read_ptimer(struct gk20a *g, u64 *value) | ||
94 | { | ||
95 | const unsigned int max_iterations = 3; | ||
96 | unsigned int i = 0; | ||
97 | u32 gpu_timestamp_hi_prev = 0; | ||
98 | |||
99 | if (!value) | ||
100 | return -EINVAL; | ||
101 | |||
102 | /* Note. The GPU nanosecond timer consists of two 32-bit | ||
103 | * registers (high & low). To detect a possible low register | ||
104 | * wrap-around between the reads, we need to read the high | ||
105 | * register before and after low. The wraparound happens | ||
106 | * approximately once per 4 secs. */ | ||
107 | |||
108 | /* get initial gpu_timestamp_hi value */ | ||
109 | gpu_timestamp_hi_prev = gk20a_readl(g, timer_time_1_r()); | ||
110 | |||
111 | for (i = 0; i < max_iterations; ++i) { | ||
112 | u32 gpu_timestamp_hi = 0; | ||
113 | u32 gpu_timestamp_lo = 0; | ||
114 | |||
115 | gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r()); | ||
116 | gpu_timestamp_hi = gk20a_readl(g, timer_time_1_r()); | ||
117 | |||
118 | if (gpu_timestamp_hi == gpu_timestamp_hi_prev) { | ||
119 | *value = (((u64)gpu_timestamp_hi) << 32) | | ||
120 | gpu_timestamp_lo; | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* wrap-around detected, retry */ | ||
125 | gpu_timestamp_hi_prev = gpu_timestamp_hi; | ||
126 | } | ||
127 | |||
128 | /* too many iterations, bail out */ | ||
129 | gk20a_err(dev_from_gk20a(g), "failed to read ptimer"); | ||
130 | return -EBUSY; | ||
131 | } | ||
132 | |||
133 | static int gk20a_bus_bar1_bind(struct gk20a *g, struct mem_desc *bar1_inst) | ||
134 | { | ||
135 | u64 iova = gk20a_mm_inst_block_addr(g, bar1_inst); | ||
136 | u32 ptr_v = (u32)(iova >> bar1_instance_block_shift_gk20a()); | ||
137 | |||
138 | gk20a_dbg_info("bar1 inst block ptr: 0x%08x", ptr_v); | ||
139 | |||
140 | gk20a_writel(g, bus_bar1_block_r(), | ||
141 | gk20a_aperture_mask(g, bar1_inst, | ||
142 | bus_bar1_block_target_sys_mem_ncoh_f(), | ||
143 | bus_bar1_block_target_vid_mem_f()) | | ||
144 | bus_bar1_block_mode_virtual_f() | | ||
145 | bus_bar1_block_ptr_f(ptr_v)); | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | void gk20a_init_bus(struct gpu_ops *gops) | ||
151 | { | ||
152 | gops->bus.init_hw = gk20a_bus_init_hw; | ||
153 | gops->bus.isr = gk20a_bus_isr; | ||
154 | gops->bus.read_ptimer = gk20a_read_ptimer; | ||
155 | gops->bus.bar1_bind = gk20a_bus_bar1_bind; | ||
156 | } | ||
diff --git a/drivers/gpu/nvgpu/gk20a/bus_gk20a.h b/drivers/gpu/nvgpu/gk20a/bus_gk20a.h new file mode 100644 index 00000000..01526f06 --- /dev/null +++ b/drivers/gpu/nvgpu/gk20a/bus_gk20a.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #ifndef BUS_GK20A_H | ||
17 | #define BUS_GK20A_H | ||
18 | |||
19 | struct gk20a; | ||
20 | struct gpu_ops; | ||
21 | struct mem_desc; | ||
22 | |||
23 | void gk20a_init_bus(struct gpu_ops *gops); | ||
24 | |||
25 | void gk20a_bus_isr(struct gk20a *g); | ||
26 | int gk20a_read_ptimer(struct gk20a *g, u64 *value); | ||
27 | void gk20a_bus_init_hw(struct gk20a *g); | ||
28 | |||
29 | #endif /* GK20A_H */ | ||
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index e6626c4a..67971369 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | |||
@@ -725,7 +725,7 @@ static int nvgpu_gpu_get_gpu_time( | |||
725 | if (err) | 725 | if (err) |
726 | return err; | 726 | return err; |
727 | 727 | ||
728 | err = g->ops.read_ptimer(g, &time); | 728 | err = g->ops.bus.read_ptimer(g, &time); |
729 | if (!err) | 729 | if (!err) |
730 | args->gpu_timestamp = time; | 730 | args->gpu_timestamp = time; |
731 | 731 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c index 4ad2abd6..0736a03b 100644 --- a/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctxsw_trace_gk20a.c | |||
@@ -686,7 +686,7 @@ void gk20a_ctxsw_trace_channel_reset(struct gk20a *g, struct channel_gk20a *ch) | |||
686 | if (!g->ctxsw_trace) | 686 | if (!g->ctxsw_trace) |
687 | return; | 687 | return; |
688 | 688 | ||
689 | g->ops.read_ptimer(g, &entry.timestamp); | 689 | g->ops.bus.read_ptimer(g, &entry.timestamp); |
690 | gk20a_ctxsw_trace_write(g, &entry); | 690 | gk20a_ctxsw_trace_write(g, &entry); |
691 | gk20a_ctxsw_trace_wake_up(g, 0); | 691 | gk20a_ctxsw_trace_wake_up(g, 0); |
692 | #endif | 692 | #endif |
@@ -706,7 +706,7 @@ void gk20a_ctxsw_trace_tsg_reset(struct gk20a *g, struct tsg_gk20a *tsg) | |||
706 | if (!g->ctxsw_trace) | 706 | if (!g->ctxsw_trace) |
707 | return; | 707 | return; |
708 | 708 | ||
709 | g->ops.read_ptimer(g, &entry.timestamp); | 709 | g->ops.bus.read_ptimer(g, &entry.timestamp); |
710 | gk20a_ctxsw_trace_write(g, &entry); | 710 | gk20a_ctxsw_trace_write(g, &entry); |
711 | gk20a_ctxsw_trace_wake_up(g, 0); | 711 | gk20a_ctxsw_trace_wake_up(g, 0); |
712 | #endif | 712 | #endif |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 76484dd5..72528758 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include "hal.h" | 57 | #include "hal.h" |
58 | #include "vgpu/vgpu.h" | 58 | #include "vgpu/vgpu.h" |
59 | #include "pci.h" | 59 | #include "pci.h" |
60 | #include "bus_gk20a.h" | ||
60 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | 61 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC |
61 | #include "pstate/pstate.h" | 62 | #include "pstate/pstate.h" |
62 | #endif | 63 | #endif |
@@ -70,11 +71,8 @@ | |||
70 | #endif | 71 | #endif |
71 | 72 | ||
72 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> | 73 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> |
73 | #include <nvgpu/hw/gk20a/hw_timer_gk20a.h> | ||
74 | #include <nvgpu/hw/gk20a/hw_bus_gk20a.h> | ||
75 | #include <nvgpu/hw/gk20a/hw_top_gk20a.h> | 74 | #include <nvgpu/hw/gk20a/hw_top_gk20a.h> |
76 | #include <nvgpu/hw/gk20a/hw_ltc_gk20a.h> | 75 | #include <nvgpu/hw/gk20a/hw_ltc_gk20a.h> |
77 | #include <nvgpu/hw/gk20a/hw_gr_gk20a.h> | ||
78 | #include <nvgpu/hw/gk20a/hw_fb_gk20a.h> | 76 | #include <nvgpu/hw/gk20a/hw_fb_gk20a.h> |
79 | 77 | ||
80 | 78 | ||
@@ -330,42 +328,6 @@ static irqreturn_t gk20a_intr_isr_nonstall(int irq, void *dev_id) | |||
330 | return g->ops.mc.isr_nonstall(g); | 328 | return g->ops.mc.isr_nonstall(g); |
331 | } | 329 | } |
332 | 330 | ||
333 | void gk20a_pbus_isr(struct gk20a *g) | ||
334 | { | ||
335 | u32 val, err_code; | ||
336 | val = gk20a_readl(g, bus_intr_0_r()); | ||
337 | if (val & (bus_intr_0_pri_squash_m() | | ||
338 | bus_intr_0_pri_fecserr_m() | | ||
339 | bus_intr_0_pri_timeout_m())) { | ||
340 | gk20a_dbg(gpu_dbg_intr, "pmc_enable : 0x%x", | ||
341 | gk20a_readl(g, mc_enable_r())); | ||
342 | gk20a_dbg(gpu_dbg_intr, "NV_PBUS_INTR_0 : 0x%x", val); | ||
343 | gk20a_dbg(gpu_dbg_intr, | ||
344 | "NV_PTIMER_PRI_TIMEOUT_SAVE_0: 0x%x\n", | ||
345 | gk20a_readl(g, timer_pri_timeout_save_0_r())); | ||
346 | gk20a_dbg(gpu_dbg_intr, | ||
347 | "NV_PTIMER_PRI_TIMEOUT_SAVE_1: 0x%x\n", | ||
348 | gk20a_readl(g, timer_pri_timeout_save_1_r())); | ||
349 | err_code = gk20a_readl(g, timer_pri_timeout_fecs_errcode_r()); | ||
350 | gk20a_dbg(gpu_dbg_intr, | ||
351 | "NV_PTIMER_PRI_TIMEOUT_FECS_ERRCODE: 0x%x\n", | ||
352 | err_code); | ||
353 | if (err_code == 0xbadf13) | ||
354 | gk20a_dbg(gpu_dbg_intr, | ||
355 | "NV_PGRAPH_PRI_GPC0_GPCCS_FS_GPC: 0x%x\n", | ||
356 | gk20a_readl(g, gr_gpc0_fs_gpc_r())); | ||
357 | |||
358 | gk20a_writel(g, timer_pri_timeout_save_0_r(), 0); | ||
359 | gk20a_writel(g, timer_pri_timeout_save_1_r(), 0); | ||
360 | } | ||
361 | |||
362 | if (val) | ||
363 | gk20a_dbg(gpu_dbg_intr, | ||
364 | "Unhandled pending pbus interrupt\n"); | ||
365 | |||
366 | gk20a_writel(g, bus_intr_0_r(), val); | ||
367 | } | ||
368 | |||
369 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) | 331 | static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) |
370 | { | 332 | { |
371 | struct gk20a *g = dev_id; | 333 | struct gk20a *g = dev_id; |
@@ -596,13 +558,7 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
596 | if (err) | 558 | if (err) |
597 | goto done; | 559 | goto done; |
598 | 560 | ||
599 | if (!tegra_platform_is_silicon()) | 561 | g->ops.bus.init_hw(g); |
600 | gk20a_writel(g, bus_intr_en_0_r(), 0x0); | ||
601 | else | ||
602 | gk20a_writel(g, bus_intr_en_0_r(), | ||
603 | bus_intr_en_0_pri_squash_m() | | ||
604 | bus_intr_en_0_pri_fecserr_m() | | ||
605 | bus_intr_en_0_pri_timeout_m()); | ||
606 | 562 | ||
607 | if (g->ops.clk.disable_slowboot) | 563 | if (g->ops.clk.disable_slowboot) |
608 | g->ops.clk.disable_slowboot(g); | 564 | g->ops.clk.disable_slowboot(g); |
@@ -630,22 +586,6 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
630 | } | 586 | } |
631 | } | 587 | } |
632 | 588 | ||
633 | /* enable pri timeout only on silicon */ | ||
634 | if (tegra_platform_is_silicon()) { | ||
635 | gk20a_writel(g, | ||
636 | timer_pri_timeout_r(), | ||
637 | timer_pri_timeout_period_f( | ||
638 | platform->default_pri_timeout ? | ||
639 | platform->default_pri_timeout : | ||
640 | 0x186A0) | | ||
641 | timer_pri_timeout_en_en_enabled_f()); | ||
642 | } else { | ||
643 | gk20a_writel(g, | ||
644 | timer_pri_timeout_r(), | ||
645 | timer_pri_timeout_period_f(0x186A0) | | ||
646 | timer_pri_timeout_en_en_disabled_f()); | ||
647 | } | ||
648 | |||
649 | err = gk20a_init_fifo_reset_enable_hw(g); | 589 | err = gk20a_init_fifo_reset_enable_hw(g); |
650 | if (err) { | 590 | if (err) { |
651 | gk20a_err(dev, "failed to reset gk20a fifo"); | 591 | gk20a_err(dev, "failed to reset gk20a fifo"); |
@@ -1910,46 +1850,6 @@ int gk20a_init_gpu_characteristics(struct gk20a *g) | |||
1910 | return 0; | 1850 | return 0; |
1911 | } | 1851 | } |
1912 | 1852 | ||
1913 | int gk20a_read_ptimer(struct gk20a *g, u64 *value) | ||
1914 | { | ||
1915 | const unsigned int max_iterations = 3; | ||
1916 | unsigned int i = 0; | ||
1917 | u32 gpu_timestamp_hi_prev = 0; | ||
1918 | |||
1919 | if (!value) | ||
1920 | return -EINVAL; | ||
1921 | |||
1922 | /* Note. The GPU nanosecond timer consists of two 32-bit | ||
1923 | * registers (high & low). To detect a possible low register | ||
1924 | * wrap-around between the reads, we need to read the high | ||
1925 | * register before and after low. The wraparound happens | ||
1926 | * approximately once per 4 secs. */ | ||
1927 | |||
1928 | /* get initial gpu_timestamp_hi value */ | ||
1929 | gpu_timestamp_hi_prev = gk20a_readl(g, timer_time_1_r()); | ||
1930 | |||
1931 | for (i = 0; i < max_iterations; ++i) { | ||
1932 | u32 gpu_timestamp_hi = 0; | ||
1933 | u32 gpu_timestamp_lo = 0; | ||
1934 | |||
1935 | gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r()); | ||
1936 | gpu_timestamp_hi = gk20a_readl(g, timer_time_1_r()); | ||
1937 | |||
1938 | if (gpu_timestamp_hi == gpu_timestamp_hi_prev) { | ||
1939 | *value = (((u64)gpu_timestamp_hi) << 32) | | ||
1940 | gpu_timestamp_lo; | ||
1941 | return 0; | ||
1942 | } | ||
1943 | |||
1944 | /* wrap-around detected, retry */ | ||
1945 | gpu_timestamp_hi_prev = gpu_timestamp_hi; | ||
1946 | } | ||
1947 | |||
1948 | /* too many iterations, bail out */ | ||
1949 | gk20a_err(dev_from_gk20a(g), "failed to read ptimer"); | ||
1950 | return -EBUSY; | ||
1951 | } | ||
1952 | |||
1953 | /* | 1853 | /* |
1954 | * Free the gk20a struct. | 1854 | * Free the gk20a struct. |
1955 | */ | 1855 | */ |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 7c836b3c..8d03cc9a 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -629,7 +629,6 @@ struct gpu_ops { | |||
629 | struct vm_gk20a *vm); | 629 | struct vm_gk20a *vm); |
630 | u64 (*get_iova_addr)(struct gk20a *g, struct scatterlist *sgl, | 630 | u64 (*get_iova_addr)(struct gk20a *g, struct scatterlist *sgl, |
631 | u32 flags); | 631 | u32 flags); |
632 | int (*bar1_bind)(struct gk20a *g, struct mem_desc *bar1_inst); | ||
633 | size_t (*get_vidmem_size)(struct gk20a *g); | 632 | size_t (*get_vidmem_size)(struct gk20a *g); |
634 | void (*init_inst_block)(struct mem_desc *inst_block, | 633 | void (*init_inst_block)(struct mem_desc *inst_block, |
635 | struct vm_gk20a *vm, u32 big_page_size); | 634 | struct vm_gk20a *vm, u32 big_page_size); |
@@ -773,7 +772,13 @@ struct gpu_ops { | |||
773 | 772 | ||
774 | int (*get_litter_value)(struct gk20a *g, int value); | 773 | int (*get_litter_value)(struct gk20a *g, int value); |
775 | int (*chip_init_gpu_characteristics)(struct gk20a *g); | 774 | int (*chip_init_gpu_characteristics)(struct gk20a *g); |
776 | int (*read_ptimer)(struct gk20a *g, u64 *value); | 775 | |
776 | struct { | ||
777 | void (*init_hw)(struct gk20a *g); | ||
778 | void (*isr)(struct gk20a *g); | ||
779 | int (*read_ptimer)(struct gk20a *g, u64 *value); | ||
780 | int (*bar1_bind)(struct gk20a *g, struct mem_desc *bar1_inst); | ||
781 | } bus; | ||
777 | 782 | ||
778 | int (*bios_init)(struct gk20a *g); | 783 | int (*bios_init)(struct gk20a *g); |
779 | 784 | ||
@@ -1417,8 +1422,6 @@ int gk20a_wait_for_idle(struct device *dev); | |||
1417 | 1422 | ||
1418 | int gk20a_init_gpu_characteristics(struct gk20a *g); | 1423 | int gk20a_init_gpu_characteristics(struct gk20a *g); |
1419 | 1424 | ||
1420 | void gk20a_pbus_isr(struct gk20a *g); | ||
1421 | |||
1422 | int gk20a_user_init(struct device *dev, const char *interface_name, | 1425 | int gk20a_user_init(struct device *dev, const char *interface_name, |
1423 | struct class *class); | 1426 | struct class *class); |
1424 | void gk20a_user_deinit(struct device *dev, struct class *class); | 1427 | void gk20a_user_deinit(struct device *dev, struct class *class); |
@@ -1435,7 +1438,6 @@ static inline u32 scale_ptimer(u32 timeout , u32 scale10x) | |||
1435 | return (timeout * 10) / scale10x; | 1438 | return (timeout * 10) / scale10x; |
1436 | } | 1439 | } |
1437 | 1440 | ||
1438 | int gk20a_read_ptimer(struct gk20a *g, u64 *value); | ||
1439 | extern struct class nvgpu_class; | 1441 | extern struct class nvgpu_class; |
1440 | 1442 | ||
1441 | #define INTERFACE_NAME "nvhost%s-gpu" | 1443 | #define INTERFACE_NAME "nvhost%s-gpu" |
diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c index 23725b8b..1e4fffdc 100644 --- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "hal_gk20a.h" | 18 | #include "hal_gk20a.h" |
19 | #include "bus_gk20a.h" | ||
19 | #include "ltc_gk20a.h" | 20 | #include "ltc_gk20a.h" |
20 | #include "fb_gk20a.h" | 21 | #include "fb_gk20a.h" |
21 | #include "gk20a.h" | 22 | #include "gk20a.h" |
@@ -147,6 +148,7 @@ int gk20a_init_hal(struct gk20a *g) | |||
147 | gops->privsecurity = 0; | 148 | gops->privsecurity = 0; |
148 | gops->securegpccs = 0; | 149 | gops->securegpccs = 0; |
149 | gops->pmupstate = false; | 150 | gops->pmupstate = false; |
151 | gk20a_init_bus(gops); | ||
150 | gk20a_init_mc(gops); | 152 | gk20a_init_mc(gops); |
151 | gk20a_init_ltc(gops); | 153 | gk20a_init_ltc(gops); |
152 | gk20a_init_gr_ops(gops); | 154 | gk20a_init_gr_ops(gops); |
@@ -169,7 +171,6 @@ int gk20a_init_hal(struct gk20a *g) | |||
169 | gops->name = "gk20a"; | 171 | gops->name = "gk20a"; |
170 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; | 172 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; |
171 | gops->get_litter_value = gk20a_get_litter_value; | 173 | gops->get_litter_value = gk20a_get_litter_value; |
172 | gops->read_ptimer = gk20a_read_ptimer; | ||
173 | 174 | ||
174 | c->twod_class = FERMI_TWOD_A; | 175 | c->twod_class = FERMI_TWOD_A; |
175 | c->threed_class = KEPLER_C; | 176 | c->threed_class = KEPLER_C; |
diff --git a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c index a1861b0d..e51c4a29 100644 --- a/drivers/gpu/nvgpu/gk20a/mc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mc_gk20a.c | |||
@@ -150,7 +150,7 @@ irqreturn_t mc_gk20a_intr_thread_stall(struct gk20a *g) | |||
150 | if (mc_intr_0 & mc_intr_0_ltc_pending_f()) | 150 | if (mc_intr_0 & mc_intr_0_ltc_pending_f()) |
151 | g->ops.ltc.isr(g); | 151 | g->ops.ltc.isr(g); |
152 | if (mc_intr_0 & mc_intr_0_pbus_pending_f()) | 152 | if (mc_intr_0 & mc_intr_0_pbus_pending_f()) |
153 | gk20a_pbus_isr(g); | 153 | g->ops.bus.isr(g); |
154 | 154 | ||
155 | /* sync handled irq counter before re-enabling interrupts */ | 155 | /* sync handled irq counter before re-enabling interrupts */ |
156 | atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); | 156 | atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index eaf8f74a..b9217c2c 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -42,12 +42,13 @@ | |||
42 | #include "mm_gk20a.h" | 42 | #include "mm_gk20a.h" |
43 | #include "fence_gk20a.h" | 43 | #include "fence_gk20a.h" |
44 | #include "kind_gk20a.h" | 44 | #include "kind_gk20a.h" |
45 | #include "bus_gk20a.h" | ||
45 | 46 | ||
46 | #include <nvgpu/hw/gk20a/hw_gmmu_gk20a.h> | 47 | #include <nvgpu/hw/gk20a/hw_gmmu_gk20a.h> |
47 | #include <nvgpu/hw/gk20a/hw_bus_gk20a.h> | ||
48 | #include <nvgpu/hw/gk20a/hw_ram_gk20a.h> | 48 | #include <nvgpu/hw/gk20a/hw_ram_gk20a.h> |
49 | #include <nvgpu/hw/gk20a/hw_pram_gk20a.h> | 49 | #include <nvgpu/hw/gk20a/hw_pram_gk20a.h> |
50 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> | 50 | #include <nvgpu/hw/gk20a/hw_mc_gk20a.h> |
51 | #include <nvgpu/hw/gk20a/hw_bus_gk20a.h> | ||
51 | #include <nvgpu/hw/gk20a/hw_flush_gk20a.h> | 52 | #include <nvgpu/hw/gk20a/hw_flush_gk20a.h> |
52 | #include <nvgpu/hw/gk20a/hw_ltc_gk20a.h> | 53 | #include <nvgpu/hw/gk20a/hw_ltc_gk20a.h> |
53 | 54 | ||
@@ -1087,8 +1088,8 @@ int gk20a_init_mm_setup_hw(struct gk20a *g) | |||
1087 | 1088 | ||
1088 | g->ops.fb.init_hw(g); | 1089 | g->ops.fb.init_hw(g); |
1089 | 1090 | ||
1090 | if (g->ops.mm.bar1_bind) | 1091 | if (g->ops.bus.bar1_bind) |
1091 | g->ops.mm.bar1_bind(g, &mm->bar1.inst_block); | 1092 | g->ops.bus.bar1_bind(g, &mm->bar1.inst_block); |
1092 | 1093 | ||
1093 | if (g->ops.mm.init_bar2_mm_hw_setup) { | 1094 | if (g->ops.mm.init_bar2_mm_hw_setup) { |
1094 | err = g->ops.mm.init_bar2_mm_hw_setup(g); | 1095 | err = g->ops.mm.init_bar2_mm_hw_setup(g); |
@@ -1103,23 +1104,6 @@ int gk20a_init_mm_setup_hw(struct gk20a *g) | |||
1103 | return 0; | 1104 | return 0; |
1104 | } | 1105 | } |
1105 | 1106 | ||
1106 | static int gk20a_mm_bar1_bind(struct gk20a *g, struct mem_desc *bar1_inst) | ||
1107 | { | ||
1108 | u64 iova = gk20a_mm_inst_block_addr(g, bar1_inst); | ||
1109 | u32 ptr_v = (u32)(iova >> bar1_instance_block_shift_gk20a()); | ||
1110 | |||
1111 | gk20a_dbg_info("bar1 inst block ptr: 0x%08x", ptr_v); | ||
1112 | |||
1113 | gk20a_writel(g, bus_bar1_block_r(), | ||
1114 | gk20a_aperture_mask(g, bar1_inst, | ||
1115 | bus_bar1_block_target_sys_mem_ncoh_f(), | ||
1116 | bus_bar1_block_target_vid_mem_f()) | | ||
1117 | bus_bar1_block_mode_virtual_f() | | ||
1118 | bus_bar1_block_ptr_f(ptr_v)); | ||
1119 | |||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | int gk20a_init_mm_support(struct gk20a *g) | 1107 | int gk20a_init_mm_support(struct gk20a *g) |
1124 | { | 1108 | { |
1125 | u32 err; | 1109 | u32 err; |
@@ -5447,7 +5431,6 @@ void gk20a_init_mm(struct gpu_ops *gops) | |||
5447 | gops->mm.get_mmu_levels = gk20a_mm_get_mmu_levels; | 5431 | gops->mm.get_mmu_levels = gk20a_mm_get_mmu_levels; |
5448 | gops->mm.init_pdb = gk20a_mm_init_pdb; | 5432 | gops->mm.init_pdb = gk20a_mm_init_pdb; |
5449 | gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw; | 5433 | gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw; |
5450 | gops->mm.bar1_bind = gk20a_mm_bar1_bind; | ||
5451 | gops->mm.init_inst_block = gk20a_init_inst_block; | 5434 | gops->mm.init_inst_block = gk20a_init_inst_block; |
5452 | gops->mm.is_bar1_supported = gk20a_mm_is_bar1_supported; | 5435 | gops->mm.is_bar1_supported = gk20a_mm_is_bar1_supported; |
5453 | gops->mm.mmu_fault_pending = gk20a_fifo_mmu_fault_pending; | 5436 | gops->mm.mmu_fault_pending = gk20a_fifo_mmu_fault_pending; |
diff --git a/drivers/gpu/nvgpu/gm20b/bus_gm20b.c b/drivers/gpu/nvgpu/gm20b/bus_gm20b.c new file mode 100644 index 00000000..68a4b15f --- /dev/null +++ b/drivers/gpu/nvgpu/gm20b/bus_gm20b.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * GM20B MMU | ||
3 | * | ||
4 | * Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | |||
18 | #include <nvgpu/timers.h> | ||
19 | |||
20 | #include "bus_gm20b.h" | ||
21 | #include "gk20a/gk20a.h" | ||
22 | #include "gk20a/bus_gk20a.h" | ||
23 | |||
24 | #include <nvgpu/hw/gm20b/hw_bus_gm20b.h> | ||
25 | |||
26 | static int gm20b_bus_bar1_bind(struct gk20a *g, struct mem_desc *bar1_inst) | ||
27 | { | ||
28 | struct nvgpu_timeout timeout; | ||
29 | int err = 0; | ||
30 | u64 iova = gk20a_mm_inst_block_addr(g, bar1_inst); | ||
31 | u32 ptr_v = (u32)(iova >> bar1_instance_block_shift_gk20a()); | ||
32 | |||
33 | gk20a_dbg_info("bar1 inst block ptr: 0x%08x", ptr_v); | ||
34 | |||
35 | gk20a_writel(g, bus_bar1_block_r(), | ||
36 | gk20a_aperture_mask(g, bar1_inst, | ||
37 | bus_bar1_block_target_sys_mem_ncoh_f(), | ||
38 | bus_bar1_block_target_vid_mem_f()) | | ||
39 | bus_bar1_block_mode_virtual_f() | | ||
40 | bus_bar1_block_ptr_f(ptr_v)); | ||
41 | nvgpu_timeout_init(g, &timeout, 1000, NVGPU_TIMER_RETRY_TIMER); | ||
42 | do { | ||
43 | u32 val = gk20a_readl(g, bus_bind_status_r()); | ||
44 | u32 pending = bus_bind_status_bar1_pending_v(val); | ||
45 | u32 outstanding = bus_bind_status_bar1_outstanding_v(val); | ||
46 | if (!pending && !outstanding) | ||
47 | break; | ||
48 | |||
49 | udelay(5); | ||
50 | } while (!nvgpu_timeout_expired(&timeout)); | ||
51 | |||
52 | if (nvgpu_timeout_peek_expired(&timeout)) | ||
53 | err = -EINVAL; | ||
54 | |||
55 | return err; | ||
56 | } | ||
57 | |||
58 | void gm20b_init_bus(struct gpu_ops *gops) | ||
59 | { | ||
60 | gops->bus.init_hw = gk20a_bus_init_hw; | ||
61 | gops->bus.isr = gk20a_bus_isr; | ||
62 | gops->bus.read_ptimer = gk20a_read_ptimer; | ||
63 | gops->bus.bar1_bind = gm20b_bus_bar1_bind; | ||
64 | } | ||
diff --git a/drivers/gpu/nvgpu/gm20b/bus_gm20b.h b/drivers/gpu/nvgpu/gm20b/bus_gm20b.h new file mode 100644 index 00000000..853e50a6 --- /dev/null +++ b/drivers/gpu/nvgpu/gm20b/bus_gm20b.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * GM20B BUS | ||
3 | * | ||
4 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | */ | ||
15 | |||
16 | #ifndef _NVGPU_GM20B_BUS | ||
17 | #define _NVGPU_GM20B_BUS | ||
18 | |||
19 | struct gpu_ops; | ||
20 | |||
21 | void gm20b_init_bus(struct gpu_ops *gops); | ||
22 | |||
23 | #endif | ||
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c index ad041f67..684f5731 100644 --- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "gk20a/gk20a.h" | 18 | #include "gk20a/gk20a.h" |
19 | #include "gk20a/dbg_gpu_gk20a.h" | 19 | #include "gk20a/dbg_gpu_gk20a.h" |
20 | #include "gk20a/css_gr_gk20a.h" | 20 | #include "gk20a/css_gr_gk20a.h" |
21 | #include "gk20a/bus_gk20a.h" | ||
21 | 22 | ||
22 | #include "ltc_gm20b.h" | 23 | #include "ltc_gm20b.h" |
23 | #include "ce2_gm20b.h" | 24 | #include "ce2_gm20b.h" |
@@ -215,6 +216,7 @@ int gm20b_init_hal(struct gk20a *g) | |||
215 | } | 216 | } |
216 | } | 217 | } |
217 | #endif | 218 | #endif |
219 | gk20a_init_bus(gops); | ||
218 | gm20b_init_mc(gops); | 220 | gm20b_init_mc(gops); |
219 | gm20b_init_ltc(gops); | 221 | gm20b_init_ltc(gops); |
220 | gm20b_init_gr(gops); | 222 | gm20b_init_gr(gops); |
@@ -238,7 +240,6 @@ int gm20b_init_hal(struct gk20a *g) | |||
238 | gops->name = "gm20b"; | 240 | gops->name = "gm20b"; |
239 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; | 241 | gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; |
240 | gops->get_litter_value = gm20b_get_litter_value; | 242 | gops->get_litter_value = gm20b_get_litter_value; |
241 | gops->read_ptimer = gk20a_read_ptimer; | ||
242 | 243 | ||
243 | c->twod_class = FERMI_TWOD_A; | 244 | c->twod_class = FERMI_TWOD_A; |
244 | c->threed_class = MAXWELL_B; | 245 | c->threed_class = MAXWELL_B; |
diff --git a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c index 18f9eec1..949a5c5d 100644 --- a/drivers/gpu/nvgpu/gm20b/mm_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/mm_gm20b.c | |||
@@ -13,17 +13,12 @@ | |||
13 | * more details. | 13 | * more details. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/delay.h> | ||
17 | |||
18 | #include "gk20a/gk20a.h" | 16 | #include "gk20a/gk20a.h" |
19 | 17 | ||
20 | #include "mm_gm20b.h" | 18 | #include "mm_gm20b.h" |
21 | 19 | ||
22 | #include <nvgpu/timers.h> | ||
23 | |||
24 | #include <nvgpu/hw/gm20b/hw_gmmu_gm20b.h> | 20 | #include <nvgpu/hw/gm20b/hw_gmmu_gm20b.h> |
25 | #include <nvgpu/hw/gm20b/hw_ram_gm20b.h> | 21 | #include <nvgpu/hw/gm20b/hw_ram_gm20b.h> |
26 | #include <nvgpu/hw/gm20b/hw_bus_gm20b.h> | ||
27 | 22 | ||
28 | static void gm20b_mm_set_big_page_size(struct gk20a *g, | 23 | static void gm20b_mm_set_big_page_size(struct gk20a *g, |
29 | struct mem_desc *mem, int size) | 24 | struct mem_desc *mem, int size) |
@@ -55,34 +50,6 @@ static bool gm20b_mm_support_sparse(struct gk20a *g) | |||
55 | return true; | 50 | return true; |
56 | } | 51 | } |
57 | 52 | ||
58 | static int gm20b_mm_bar1_bind(struct gk20a *g, struct mem_desc *bar1_inst) | ||
59 | { | ||
60 | int retry = 1000; | ||
61 | u64 iova = gk20a_mm_inst_block_addr(g, bar1_inst); | ||
62 | u32 ptr_v = (u32)(iova >> bar1_instance_block_shift_gk20a()); | ||
63 | |||
64 | gk20a_dbg_info("bar1 inst block ptr: 0x%08x", ptr_v); | ||
65 | |||
66 | gk20a_writel(g, bus_bar1_block_r(), | ||
67 | gk20a_aperture_mask(g, bar1_inst, | ||
68 | bus_bar1_block_target_sys_mem_ncoh_f(), | ||
69 | bus_bar1_block_target_vid_mem_f()) | | ||
70 | bus_bar1_block_mode_virtual_f() | | ||
71 | bus_bar1_block_ptr_f(ptr_v)); | ||
72 | do { | ||
73 | u32 val = gk20a_readl(g, bus_bind_status_r()); | ||
74 | u32 pending = bus_bind_status_bar1_pending_v(val); | ||
75 | u32 outstanding = bus_bind_status_bar1_outstanding_v(val); | ||
76 | if (!pending && !outstanding) | ||
77 | break; | ||
78 | |||
79 | udelay(5); | ||
80 | retry--; | ||
81 | } while (retry >= 0 || !tegra_platform_is_silicon()); | ||
82 | |||
83 | return retry ? -EINVAL : 0; | ||
84 | } | ||
85 | |||
86 | static bool gm20b_mm_is_bar1_supported(struct gk20a *g) | 53 | static bool gm20b_mm_is_bar1_supported(struct gk20a *g) |
87 | { | 54 | { |
88 | return true; | 55 | return true; |
@@ -107,7 +74,6 @@ void gm20b_init_mm(struct gpu_ops *gops) | |||
107 | gops->mm.get_mmu_levels = gk20a_mm_get_mmu_levels; | 74 | gops->mm.get_mmu_levels = gk20a_mm_get_mmu_levels; |
108 | gops->mm.init_pdb = gk20a_mm_init_pdb; | 75 | gops->mm.init_pdb = gk20a_mm_init_pdb; |
109 | gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw; | 76 | gops->mm.init_mm_setup_hw = gk20a_init_mm_setup_hw; |
110 | gops->mm.bar1_bind = gm20b_mm_bar1_bind; | ||
111 | gops->mm.is_bar1_supported = gm20b_mm_is_bar1_supported; | 77 | gops->mm.is_bar1_supported = gm20b_mm_is_bar1_supported; |
112 | gops->mm.init_inst_block = gk20a_init_inst_block; | 78 | gops->mm.init_inst_block = gk20a_init_inst_block; |
113 | gops->mm.mmu_fault_pending = gk20a_fifo_mmu_fault_pending; | 79 | gops->mm.mmu_fault_pending = gk20a_fifo_mmu_fault_pending; |
diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index a05b71ab..36f72b12 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "gk20a/gk20a.h" | 21 | #include "gk20a/gk20a.h" |
22 | #include "gk20a/dbg_gpu_gk20a.h" | 22 | #include "gk20a/dbg_gpu_gk20a.h" |
23 | #include "gk20a/css_gr_gk20a.h" | 23 | #include "gk20a/css_gr_gk20a.h" |
24 | #include "gk20a/bus_gk20a.h" | ||
24 | 25 | ||
25 | #include "gp10b/gr_gp10b.h" | 26 | #include "gp10b/gr_gp10b.h" |
26 | #include "gp10b/fecs_trace_gp10b.h" | 27 | #include "gp10b/fecs_trace_gp10b.h" |
@@ -223,6 +224,7 @@ int gp106_init_hal(struct gk20a *g) | |||
223 | gops->privsecurity = 1; | 224 | gops->privsecurity = 1; |
224 | gops->securegpccs = 1; | 225 | gops->securegpccs = 1; |
225 | gops->pmupstate = true; | 226 | gops->pmupstate = true; |
227 | gk20a_init_bus(gops); | ||
226 | gp10b_init_mc(gops); | 228 | gp10b_init_mc(gops); |
227 | gp106_init_gr(gops); | 229 | gp106_init_gr(gops); |
228 | gp10b_init_fecs_trace_ops(gops); | 230 | gp10b_init_fecs_trace_ops(gops); |
@@ -251,7 +253,6 @@ int gp106_init_hal(struct gk20a *g) | |||
251 | gops->get_litter_value = gp106_get_litter_value; | 253 | gops->get_litter_value = gp106_get_litter_value; |
252 | gops->chip_init_gpu_characteristics = gp106_init_gpu_characteristics; | 254 | gops->chip_init_gpu_characteristics = gp106_init_gpu_characteristics; |
253 | gops->gr_ctx.use_dma_for_fw_bootstrap = true; | 255 | gops->gr_ctx.use_dma_for_fw_bootstrap = true; |
254 | gops->read_ptimer = gk20a_read_ptimer; | ||
255 | 256 | ||
256 | c->twod_class = FERMI_TWOD_A; | 257 | c->twod_class = FERMI_TWOD_A; |
257 | c->threed_class = PASCAL_B; | 258 | c->threed_class = PASCAL_B; |
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c index 62a19abd..245d2d26 100644 --- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "gk20a/gk20a.h" | 21 | #include "gk20a/gk20a.h" |
22 | #include "gk20a/dbg_gpu_gk20a.h" | 22 | #include "gk20a/dbg_gpu_gk20a.h" |
23 | #include "gk20a/css_gr_gk20a.h" | 23 | #include "gk20a/css_gr_gk20a.h" |
24 | #include "gk20a/bus_gk20a.h" | ||
24 | 25 | ||
25 | #include "gp10b/gr_gp10b.h" | 26 | #include "gp10b/gr_gp10b.h" |
26 | #include "gp10b/fecs_trace_gp10b.h" | 27 | #include "gp10b/fecs_trace_gp10b.h" |
@@ -232,6 +233,7 @@ int gp10b_init_hal(struct gk20a *g) | |||
232 | } | 233 | } |
233 | #endif | 234 | #endif |
234 | 235 | ||
236 | gk20a_init_bus(gops); | ||
235 | gp10b_init_mc(gops); | 237 | gp10b_init_mc(gops); |
236 | gp10b_init_gr(gops); | 238 | gp10b_init_gr(gops); |
237 | gp10b_init_fecs_trace_ops(gops); | 239 | gp10b_init_fecs_trace_ops(gops); |
@@ -254,7 +256,6 @@ int gp10b_init_hal(struct gk20a *g) | |||
254 | gops->name = "gp10b"; | 256 | gops->name = "gp10b"; |
255 | gops->chip_init_gpu_characteristics = gp10b_init_gpu_characteristics; | 257 | gops->chip_init_gpu_characteristics = gp10b_init_gpu_characteristics; |
256 | gops->get_litter_value = gp10b_get_litter_value; | 258 | gops->get_litter_value = gp10b_get_litter_value; |
257 | gops->read_ptimer = gk20a_read_ptimer; | ||
258 | 259 | ||
259 | c->twod_class = FERMI_TWOD_A; | 260 | c->twod_class = FERMI_TWOD_A; |
260 | c->threed_class = PASCAL_A; | 261 | c->threed_class = PASCAL_A; |
diff --git a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c index fc0e6553..547169ed 100644 --- a/drivers/gpu/nvgpu/gp10b/mc_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mc_gp10b.c | |||
@@ -162,7 +162,7 @@ irqreturn_t mc_gp10b_intr_thread_stall(struct gk20a *g) | |||
162 | if (mc_intr_0 & mc_intr_ltc_pending_f()) | 162 | if (mc_intr_0 & mc_intr_ltc_pending_f()) |
163 | g->ops.ltc.isr(g); | 163 | g->ops.ltc.isr(g); |
164 | if (mc_intr_0 & mc_intr_pbus_pending_f()) | 164 | if (mc_intr_0 & mc_intr_pbus_pending_f()) |
165 | gk20a_pbus_isr(g); | 165 | g->ops.bus.isr(g); |
166 | 166 | ||
167 | /* sync handled irq counter before re-enabling interrupts */ | 167 | /* sync handled irq counter before re-enabling interrupts */ |
168 | atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); | 168 | atomic_set(&g->sw_irq_stall_last_handled, hw_irq_count); |
diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c index 26facbe3..a5322bad 100644 --- a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c | |||
@@ -45,7 +45,7 @@ static int gp10b_init_mm_setup_hw(struct gk20a *g) | |||
45 | (g->ops.mm.get_iova_addr(g, g->mm.sysmem_flush.sgt->sgl, 0) | 45 | (g->ops.mm.get_iova_addr(g, g->mm.sysmem_flush.sgt->sgl, 0) |
46 | >> 8ULL)); | 46 | >> 8ULL)); |
47 | 47 | ||
48 | g->ops.mm.bar1_bind(g, inst_block); | 48 | g->ops.bus.bar1_bind(g, inst_block); |
49 | 49 | ||
50 | if (g->ops.mm.init_bar2_mm_hw_setup) { | 50 | if (g->ops.mm.init_bar2_mm_hw_setup) { |
51 | err = g->ops.mm.init_bar2_mm_hw_setup(g); | 51 | err = g->ops.mm.init_bar2_mm_hw_setup(g); |
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index 2d7417f0..72606952 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c | |||
@@ -362,7 +362,7 @@ void vgpu_init_hal_common(struct gk20a *g) | |||
362 | vgpu_init_css_ops(gops); | 362 | vgpu_init_css_ops(gops); |
363 | #endif | 363 | #endif |
364 | gops->chip_init_gpu_characteristics = vgpu_init_gpu_characteristics; | 364 | gops->chip_init_gpu_characteristics = vgpu_init_gpu_characteristics; |
365 | gops->read_ptimer = vgpu_read_ptimer; | 365 | gops->bus.read_ptimer = vgpu_read_ptimer; |
366 | } | 366 | } |
367 | 367 | ||
368 | static int vgpu_init_hal(struct gk20a *g) | 368 | static int vgpu_init_hal(struct gk20a *g) |