]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/gpu/nvgpu/gk20a/ltc_common.c
6fbd0c2d5215c3333677433f460682e2e96e35d9
[sojka/nv-tegra/linux-3.10.git] / drivers / gpu / nvgpu / gk20a / ltc_common.c
1 /*
2  * drivers/video/tegra/host/gk20a/ltc_common.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/dma-mapping.h>
22 #include <linux/delay.h>
23
24 #include "gk20a.h"
25 #include "gr_gk20a.h"
26
27 /*
28  * Set the maximum number of ways that can have the "EVIST_LAST" class.
29  */
30 static void gk20a_ltc_set_max_ways_evict_last(struct gk20a *g, u32 max_ways)
31 {
32         u32 mgmt_reg;
33
34         mgmt_reg = gk20a_readl(g, ltc_ltcs_ltss_tstg_set_mgmt_r()) &
35                 ~ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(~0);
36         mgmt_reg |= ltc_ltcs_ltss_tstg_set_mgmt_max_ways_evict_last_f(max_ways);
37
38         gk20a_writel(g, ltc_ltcs_ltss_tstg_set_mgmt_r(), mgmt_reg);
39 }
40
41 /*
42  * Sets the ZBC color for the passed index.
43  */
44 static void gk20a_ltc_set_zbc_color_entry(struct gk20a *g,
45                                           struct zbc_entry *color_val,
46                                           u32 index)
47 {
48         u32 i;
49         u32 real_index = index + GK20A_STARTOF_ZBC_TABLE;
50
51         gk20a_writel(g, ltc_ltcs_ltss_dstg_zbc_index_r(),
52                      ltc_ltcs_ltss_dstg_zbc_index_address_f(real_index));
53
54         for (i = 0;
55              i < ltc_ltcs_ltss_dstg_zbc_color_clear_value__size_1_v(); i++)
56                 gk20a_writel(g, ltc_ltcs_ltss_dstg_zbc_color_clear_value_r(i),
57                              color_val->color_l2[i]);
58 }
59
60 /*
61  * Sets the ZBC depth for the passed index.
62  */
63 static void gk20a_ltc_set_zbc_depth_entry(struct gk20a *g,
64                                           struct zbc_entry *depth_val,
65                                           u32 index)
66 {
67         u32 real_index = index + GK20A_STARTOF_ZBC_TABLE;
68
69         gk20a_writel(g, ltc_ltcs_ltss_dstg_zbc_index_r(),
70                      ltc_ltcs_ltss_dstg_zbc_index_address_f(real_index));
71
72         gk20a_writel(g, ltc_ltcs_ltss_dstg_zbc_depth_clear_value_r(),
73                      depth_val->depth);
74 }
75
76 static int gk20a_ltc_alloc_phys_cbc(struct gk20a *g,
77                                     size_t compbit_backing_size)
78 {
79         struct gr_gk20a *gr = &g->gr;
80
81         return gk20a_gmmu_alloc_attr(g, DMA_ATTR_FORCE_CONTIGUOUS,
82                                     compbit_backing_size,
83                                     &gr->compbit_store.mem);
84 }
85
86 static int gk20a_ltc_alloc_virt_cbc(struct gk20a *g,
87                                     size_t compbit_backing_size)
88 {
89         struct gr_gk20a *gr = &g->gr;
90
91         return gk20a_gmmu_alloc_attr(g, DMA_ATTR_NO_KERNEL_MAPPING,
92                                     compbit_backing_size,
93                                     &gr->compbit_store.mem);
94 }
95
96 static void gk20a_ltc_init_cbc(struct gk20a *g, struct gr_gk20a *gr)
97 {
98         u32 max_size = gr->max_comptag_mem;
99         u32 max_comptag_lines = max_size << 3;
100
101         u32 compbit_base_post_divide;
102         u64 compbit_base_post_multiply64;
103         u64 compbit_store_iova;
104         u64 compbit_base_post_divide64;
105
106         if (tegra_platform_is_linsim())
107                 compbit_store_iova = gk20a_mem_phys(&gr->compbit_store.mem);
108         else
109                 compbit_store_iova = g->ops.mm.get_iova_addr(g,
110                                 gr->compbit_store.mem.sgt->sgl, 0);
111
112         compbit_base_post_divide64 = compbit_store_iova >>
113                 ltc_ltcs_ltss_cbc_base_alignment_shift_v();
114
115         do_div(compbit_base_post_divide64, g->ltc_count);
116         compbit_base_post_divide = u64_lo32(compbit_base_post_divide64);
117
118         compbit_base_post_multiply64 = ((u64)compbit_base_post_divide *
119                 g->ltc_count) << ltc_ltcs_ltss_cbc_base_alignment_shift_v();
120
121         if (compbit_base_post_multiply64 < compbit_store_iova)
122                 compbit_base_post_divide++;
123
124         /* Bug 1477079 indicates sw adjustment on the posted divided base. */
125         if (g->ops.ltc.cbc_fix_config)
126                 compbit_base_post_divide =
127                         g->ops.ltc.cbc_fix_config(g, compbit_base_post_divide);
128
129         gk20a_writel(g, ltc_ltcs_ltss_cbc_base_r(),
130                 compbit_base_post_divide);
131
132         gk20a_dbg(gpu_dbg_info | gpu_dbg_map | gpu_dbg_pte,
133                    "compbit base.pa: 0x%x,%08x cbc_base:0x%08x\n",
134                    (u32)(compbit_store_iova >> 32),
135                    (u32)(compbit_store_iova & 0xffffffff),
136                    compbit_base_post_divide);
137
138         gr->compbit_store.base_hw = compbit_base_post_divide;
139
140         g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_invalidate,
141                             0, max_comptag_lines - 1);
142
143 }
144
145 #ifdef CONFIG_DEBUG_FS
146 static void gk20a_ltc_sync_debugfs(struct gk20a *g)
147 {
148         u32 reg_f = ltc_ltcs_ltss_tstg_set_mgmt_2_l2_bypass_mode_enabled_f();
149
150         spin_lock(&g->debugfs_lock);
151         if (g->mm.ltc_enabled != g->mm.ltc_enabled_debug) {
152                 u32 reg = gk20a_readl(g, ltc_ltcs_ltss_tstg_set_mgmt_2_r());
153                 if (g->mm.ltc_enabled_debug)
154                         /* bypass disabled (normal caching ops)*/
155                         reg &= ~reg_f;
156                 else
157                         /* bypass enabled (no caching) */
158                         reg |= reg_f;
159
160                 gk20a_writel(g, ltc_ltcs_ltss_tstg_set_mgmt_2_r(), reg);
161                 g->mm.ltc_enabled = g->mm.ltc_enabled_debug;
162         }
163         spin_unlock(&g->debugfs_lock);
164 }
165 #endif