diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ltc_gk20a.c | 40 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 2 |
4 files changed, 44 insertions, 15 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 3bc53992..7aca186e 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -56,12 +56,19 @@ struct cooling_device_gk20a { | |||
56 | struct gk20a *g; | 56 | struct gk20a *g; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | enum gk20a_cbc_op { | ||
60 | gk20a_cbc_op_clear, | ||
61 | gk20a_cbc_op_clean, | ||
62 | gk20a_cbc_op_invalidate, | ||
63 | }; | ||
64 | |||
59 | struct gpu_ops { | 65 | struct gpu_ops { |
60 | struct { | 66 | struct { |
61 | int (*determine_L2_size_bytes)(struct gk20a *gk20a); | 67 | int (*determine_L2_size_bytes)(struct gk20a *gk20a); |
62 | void (*set_max_ways_evict_last)(struct gk20a *g, u32 max_ways); | 68 | void (*set_max_ways_evict_last)(struct gk20a *g, u32 max_ways); |
63 | int (*init_comptags)(struct gk20a *g, struct gr_gk20a *gr); | 69 | int (*init_comptags)(struct gk20a *g, struct gr_gk20a *gr); |
64 | int (*clear_comptags)(struct gk20a *g, u32 min, u32 max); | 70 | int (*cbc_ctrl)(struct gk20a *g, enum gk20a_cbc_op op, |
71 | u32 min, u32 max); | ||
65 | void (*set_zbc_color_entry)(struct gk20a *g, | 72 | void (*set_zbc_color_entry)(struct gk20a *g, |
66 | struct zbc_entry *color_val, | 73 | struct zbc_entry *color_val, |
67 | u32 index); | 74 | u32 index); |
diff --git a/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h index 8ea4ef71..f60b34e2 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_ltc_gk20a.h | |||
@@ -82,6 +82,14 @@ static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) | |||
82 | { | 82 | { |
83 | return 0x0017e8c8; | 83 | return 0x0017e8c8; |
84 | } | 84 | } |
85 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) | ||
86 | { | ||
87 | return 0x1; | ||
88 | } | ||
89 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) | ||
90 | { | ||
91 | return 0x2; | ||
92 | } | ||
85 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) | 93 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) |
86 | { | 94 | { |
87 | return (r >> 2) & 0x1; | 95 | return (r >> 2) & 0x1; |
diff --git a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c index 8450f664..74475d7a 100644 --- a/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ltc_gk20a.c | |||
@@ -108,10 +108,12 @@ static int gk20a_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr) | |||
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | 111 | static int gk20a_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op, |
112 | u32 min, u32 max) | ||
112 | { | 113 | { |
114 | int err = 0; | ||
113 | struct gr_gk20a *gr = &g->gr; | 115 | struct gr_gk20a *gr = &g->gr; |
114 | u32 fbp, slice, ctrl1, val; | 116 | u32 fbp, slice, ctrl1, val, hw_op = 0; |
115 | unsigned long end_jiffies = jiffies + | 117 | unsigned long end_jiffies = jiffies + |
116 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | 118 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); |
117 | u32 delay = GR_IDLE_CHECK_DEFAULT; | 119 | u32 delay = GR_IDLE_CHECK_DEFAULT; |
@@ -124,13 +126,24 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | |||
124 | if (gr->compbit_store.size == 0) | 126 | if (gr->compbit_store.size == 0) |
125 | return 0; | 127 | return 0; |
126 | 128 | ||
127 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(), | 129 | mutex_lock(&g->mm.l2_op_lock); |
128 | ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min)); | 130 | |
129 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(), | 131 | if (op == gk20a_cbc_op_clear) { |
130 | ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max)); | 132 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(), |
133 | ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min)); | ||
134 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(), | ||
135 | ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max)); | ||
136 | hw_op = ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(); | ||
137 | } else if (op == gk20a_cbc_op_clean) { | ||
138 | hw_op = ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(); | ||
139 | } else if (op == gk20a_cbc_op_invalidate) { | ||
140 | hw_op = ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(); | ||
141 | } else { | ||
142 | BUG_ON(1); | ||
143 | } | ||
144 | |||
131 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(), | 145 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(), |
132 | gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | | 146 | gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | hw_op); |
133 | ltc_ltcs_ltss_cbc_ctrl1_clear_active_f()); | ||
134 | 147 | ||
135 | for (fbp = 0; fbp < gr->num_fbps; fbp++) { | 148 | for (fbp = 0; fbp < gr->num_fbps; fbp++) { |
136 | for (slice = 0; slice < slices_per_fbp; slice++) { | 149 | for (slice = 0; slice < slices_per_fbp; slice++) { |
@@ -143,8 +156,7 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | |||
143 | 156 | ||
144 | do { | 157 | do { |
145 | val = gk20a_readl(g, ctrl1); | 158 | val = gk20a_readl(g, ctrl1); |
146 | if (ltc_ltcs_ltss_cbc_ctrl1_clear_v(val) != | 159 | if (!(val & hw_op)) |
147 | ltc_ltcs_ltss_cbc_ctrl1_clear_active_v()) | ||
148 | break; | 160 | break; |
149 | 161 | ||
150 | usleep_range(delay, delay * 2); | 162 | usleep_range(delay, delay * 2); |
@@ -157,11 +169,13 @@ static int gk20a_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | |||
157 | if (!time_before(jiffies, end_jiffies)) { | 169 | if (!time_before(jiffies, end_jiffies)) { |
158 | gk20a_err(dev_from_gk20a(g), | 170 | gk20a_err(dev_from_gk20a(g), |
159 | "comp tag clear timeout\n"); | 171 | "comp tag clear timeout\n"); |
160 | return -EBUSY; | 172 | err = -EBUSY; |
173 | goto out; | ||
161 | } | 174 | } |
162 | } | 175 | } |
163 | } | 176 | } |
164 | 177 | out: | |
178 | mutex_unlock(&g->mm.l2_op_lock); | ||
165 | return 0; | 179 | return 0; |
166 | } | 180 | } |
167 | 181 | ||
@@ -200,7 +214,7 @@ void gk20a_init_ltc(struct gpu_ops *gops) | |||
200 | gops->ltc.determine_L2_size_bytes = gk20a_determine_L2_size_bytes; | 214 | gops->ltc.determine_L2_size_bytes = gk20a_determine_L2_size_bytes; |
201 | gops->ltc.set_max_ways_evict_last = gk20a_ltc_set_max_ways_evict_last; | 215 | gops->ltc.set_max_ways_evict_last = gk20a_ltc_set_max_ways_evict_last; |
202 | gops->ltc.init_comptags = gk20a_ltc_init_comptags; | 216 | gops->ltc.init_comptags = gk20a_ltc_init_comptags; |
203 | gops->ltc.clear_comptags = gk20a_ltc_clear_comptags; | 217 | gops->ltc.cbc_ctrl = gk20a_ltc_cbc_ctrl; |
204 | gops->ltc.set_zbc_color_entry = gk20a_ltc_set_zbc_color_entry; | 218 | gops->ltc.set_zbc_color_entry = gk20a_ltc_set_zbc_color_entry; |
205 | gops->ltc.set_zbc_depth_entry = gk20a_ltc_set_zbc_depth_entry; | 219 | gops->ltc.set_zbc_depth_entry = gk20a_ltc_set_zbc_depth_entry; |
206 | gops->ltc.clear_zbc_color_entry = gk20a_ltc_clear_zbc_color_entry; | 220 | gops->ltc.clear_zbc_color_entry = gk20a_ltc_clear_zbc_color_entry; |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index c6883b61..210fe1b3 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -1380,7 +1380,7 @@ u64 gk20a_vm_map(struct vm_gk20a *vm, | |||
1380 | gk20a_get_comptags(d, dmabuf, &comptags); | 1380 | gk20a_get_comptags(d, dmabuf, &comptags); |
1381 | 1381 | ||
1382 | /* init/clear the ctag buffer */ | 1382 | /* init/clear the ctag buffer */ |
1383 | g->ops.ltc.clear_comptags(g, | 1383 | g->ops.ltc.cbc_ctrl(g, gk20a_cbc_op_clear, |
1384 | comptags.offset, | 1384 | comptags.offset, |
1385 | comptags.offset + comptags.lines - 1); | 1385 | comptags.offset + comptags.lines - 1); |
1386 | } | 1386 | } |