diff options
author | Arto Merilainen <amerilainen@nvidia.com> | 2014-03-19 03:38:25 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:08:53 -0400 |
commit | a9785995d5f22aaeb659285f8aeb64d8b56982e0 (patch) | |
tree | cc75f75bcf43db316a002a7a240b81f299bf6d7f /drivers/gpu/nvgpu/gk20a/ltc_gk20a.c | |
parent | 61efaf843c22b85424036ec98015121c08f5f16c (diff) |
gpu: nvgpu: Add NVIDIA GPU Driver
This patch moves the NVIDIA GPU driver to a new location.
Bug 1482562
Change-Id: I24293810b9d0f1504fd9be00135e21dad656ccb6
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-on: http://git-master/r/383722
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/ltc_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ltc_gk20a.c | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c new file mode 100644 index 00000000..08aedecd --- /dev/null +++ b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * drivers/video/tegra/host/gk20a/ltc_gk20a.c | ||
3 | * | ||
4 | * GK20A Graphics | ||
5 | * | ||
6 | * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | |||
23 | #include "hw_ltc_gk20a.h" | ||
24 | #include "hw_proj_gk20a.h" | ||
25 | |||
26 | #include "ltc_common.c" | ||
27 | |||
28 | static int gk20a_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr) | ||
29 | { | ||
30 | struct device *d = dev_from_gk20a(g); | ||
31 | DEFINE_DMA_ATTRS(attrs); | ||
32 | dma_addr_t iova; | ||
33 | |||
34 | /* max memory size (MB) to cover */ | ||
35 | u32 max_size = gr->max_comptag_mem; | ||
36 | /* one tag line covers 128KB */ | ||
37 | u32 max_comptag_lines = max_size << 3; | ||
38 | |||
39 | u32 hw_max_comptag_lines = | ||
40 | ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_init_v(); | ||
41 | |||
42 | u32 cbc_param = | ||
43 | gk20a_readl(g, ltc_ltcs_ltss_cbc_param_r()); | ||
44 | u32 comptags_per_cacheline = | ||
45 | ltc_ltcs_ltss_cbc_param_comptags_per_cache_line_v(cbc_param); | ||
46 | u32 slices_per_fbp = | ||
47 | ltc_ltcs_ltss_cbc_param_slices_per_fbp_v(cbc_param); | ||
48 | u32 cacheline_size = | ||
49 | 512 << ltc_ltcs_ltss_cbc_param_cache_line_size_v(cbc_param); | ||
50 | |||
51 | u32 compbit_backing_size; | ||
52 | |||
53 | gk20a_dbg_fn(""); | ||
54 | |||
55 | if (max_comptag_lines == 0) { | ||
56 | gr->compbit_store.size = 0; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | if (max_comptag_lines > hw_max_comptag_lines) | ||
61 | max_comptag_lines = hw_max_comptag_lines; | ||
62 | |||
63 | /* no hybird fb */ | ||
64 | compbit_backing_size = | ||
65 | DIV_ROUND_UP(max_comptag_lines, comptags_per_cacheline) * | ||
66 | cacheline_size * slices_per_fbp * gr->num_fbps; | ||
67 | |||
68 | /* aligned to 2KB * num_fbps */ | ||
69 | compbit_backing_size += | ||
70 | gr->num_fbps << ltc_ltcs_ltss_cbc_base_alignment_shift_v(); | ||
71 | |||
72 | /* must be a multiple of 64KB */ | ||
73 | compbit_backing_size = roundup(compbit_backing_size, 64*1024); | ||
74 | |||
75 | max_comptag_lines = | ||
76 | (compbit_backing_size * comptags_per_cacheline) / | ||
77 | cacheline_size * slices_per_fbp * gr->num_fbps; | ||
78 | |||
79 | if (max_comptag_lines > hw_max_comptag_lines) | ||
80 | max_comptag_lines = hw_max_comptag_lines; | ||
81 | |||
82 | gk20a_dbg_info("compbit backing store size : %d", | ||
83 | compbit_backing_size); | ||
84 | gk20a_dbg_info("max comptag lines : %d", | ||
85 | max_comptag_lines); | ||
86 | |||
87 | dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); | ||
88 | gr->compbit_store.size = compbit_backing_size; | ||
89 | gr->compbit_store.pages = dma_alloc_attrs(d, gr->compbit_store.size, | ||
90 | &iova, GFP_KERNEL, &attrs); | ||
91 | if (!gr->compbit_store.pages) { | ||
92 | gk20a_err(dev_from_gk20a(g), "failed to allocate" | ||
93 | "backing store for compbit : size %d", | ||
94 | compbit_backing_size); | ||
95 | return -ENOMEM; | ||
96 | } | ||
97 | gr->compbit_store.base_iova = iova; | ||
98 | |||
99 | gk20a_allocator_init(&gr->comp_tags, "comptag", | ||
100 | 1, /* start */ | ||
101 | max_comptag_lines - 1, /* length*/ | ||
102 | 1); /* align */ | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | ||
108 | { | ||
109 | struct gr_gk20a *gr = &g->gr; | ||
110 | u32 fbp, slice, ctrl1, val; | ||
111 | unsigned long end_jiffies = jiffies + | ||
112 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | ||
113 | u32 delay = GR_IDLE_CHECK_DEFAULT; | ||
114 | u32 slices_per_fbp = | ||
115 | ltc_ltcs_ltss_cbc_param_slices_per_fbp_v( | ||
116 | gk20a_readl(g, ltc_ltcs_ltss_cbc_param_r())); | ||
117 | |||
118 | gk20a_dbg_fn(""); | ||
119 | |||
120 | if (gr->compbit_store.size == 0) | ||
121 | return 0; | ||
122 | |||
123 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(), | ||
124 | ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min)); | ||
125 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(), | ||
126 | ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max)); | ||
127 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(), | ||
128 | gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | | ||
129 | ltc_ltcs_ltss_cbc_ctrl1_clear_active_f()); | ||
130 | |||
131 | for (fbp = 0; fbp < gr->num_fbps; fbp++) { | ||
132 | for (slice = 0; slice < slices_per_fbp; slice++) { | ||
133 | |||
134 | delay = GR_IDLE_CHECK_DEFAULT; | ||
135 | |||
136 | ctrl1 = ltc_ltc0_lts0_cbc_ctrl1_r() + | ||
137 | fbp * proj_ltc_stride_v() + | ||
138 | slice * proj_lts_stride_v(); | ||
139 | |||
140 | do { | ||
141 | val = gk20a_readl(g, ctrl1); | ||
142 | if (ltc_ltcs_ltss_cbc_ctrl1_clear_v(val) != | ||
143 | ltc_ltcs_ltss_cbc_ctrl1_clear_active_v()) | ||
144 | break; | ||
145 | |||
146 | usleep_range(delay, delay * 2); | ||
147 | delay = min_t(u32, delay << 1, | ||
148 | GR_IDLE_CHECK_MAX); | ||
149 | |||
150 | } while (time_before(jiffies, end_jiffies) || | ||
151 | !tegra_platform_is_silicon()); | ||
152 | |||
153 | if (!time_before(jiffies, end_jiffies)) { | ||
154 | gk20a_err(dev_from_gk20a(g), | ||
155 | "comp tag clear timeout\n"); | ||
156 | return -EBUSY; | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | |||
165 | #ifdef CONFIG_DEBUG_FS | ||
166 | static void gk20a_ltc_sync_debugfs(struct gk20a *g) | ||
167 | { | ||
168 | u32 reg_f = ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f(); | ||
169 | |||
170 | spin_lock(&g->debugfs_lock); | ||
171 | if (g->mm.ltc_enabled != g->mm.ltc_enabled_debug) { | ||
172 | u32 reg = gk20a_readl(g, ltc_ltcs_ltss_tstg_set_mgmt_2_r()); | ||
173 | if (g->mm.ltc_enabled_debug) | ||
174 | /* bypass disabled (normal caching ops)*/ | ||
175 | reg &= ~reg_f; | ||
176 | else | ||
177 | /* bypass enabled (no caching) */ | ||
178 | reg |= reg_f; | ||
179 | |||
180 | gk20a_writel(g, ltc_ltcs_ltss_tstg_set_mgmt_2_r(), reg); | ||
181 | g->mm.ltc_enabled = g->mm.ltc_enabled_debug; | ||
182 | } | ||
183 | spin_unlock(&g->debugfs_lock); | ||
184 | } | ||
185 | #endif | ||
186 | |||
187 | void gk20a_init_ltc(struct gpu_ops *gops) | ||
188 | { | ||
189 | gops->ltc.determine_L2_size_bytes = gk20a_determine_L2_size_bytes; | ||
190 | gops->ltc.set_max_ways_evict_last = gk20a_ltc_set_max_ways_evict_last; | ||
191 | gops->ltc.init_comptags = gk20a_ltc_init_comptags; | ||
192 | gops->ltc.clear_comptags = gk20a_ltc_clear_comptags; | ||
193 | gops->ltc.set_zbc_color_entry = gk20a_ltc_set_zbc_color_entry; | ||
194 | gops->ltc.set_zbc_depth_entry = gk20a_ltc_set_zbc_depth_entry; | ||
195 | gops->ltc.clear_zbc_color_entry = gk20a_ltc_clear_zbc_color_entry; | ||
196 | gops->ltc.clear_zbc_depth_entry = gk20a_ltc_clear_zbc_depth_entry; | ||
197 | gops->ltc.init_zbc = gk20a_ltc_init_zbc; | ||
198 | gops->ltc.init_cbc = gk20a_ltc_init_cbc; | ||
199 | #ifdef CONFIG_DEBUG_FS | ||
200 | gops->ltc.sync_debugfs = gk20a_ltc_sync_debugfs; | ||
201 | #endif | ||
202 | gops->ltc.elpg_flush = gk20a_mm_g_elpg_flush_locked; | ||
203 | } | ||