summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2014-03-19 03:38:25 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:08:53 -0400
commita9785995d5f22aaeb659285f8aeb64d8b56982e0 (patch)
treecc75f75bcf43db316a002a7a240b81f299bf6d7f /drivers/gpu/nvgpu/gk20a/ltc_gk20a.c
parent61efaf843c22b85424036ec98015121c08f5f16c (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.c203
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
28static 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
107static 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
166static 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
187void 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}