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 /drivers/gpu/nvgpu/gk20a | |
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>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-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 |
9 files changed, 204 insertions, 133 deletions
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; |