diff options
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/hw_ltc_gm20b.h | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/ltc_gm20b.c | 39 |
2 files changed, 34 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gm20b/hw_ltc_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_ltc_gm20b.h index 38a3121f..28c58f50 100644 --- a/drivers/gpu/nvgpu/gm20b/hw_ltc_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/hw_ltc_gm20b.h | |||
@@ -94,6 +94,14 @@ static inline u32 ltc_ltcs_ltss_cbc_ctrl1_r(void) | |||
94 | { | 94 | { |
95 | return 0x0017e26c; | 95 | return 0x0017e26c; |
96 | } | 96 | } |
97 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(void) | ||
98 | { | ||
99 | return 0x1; | ||
100 | } | ||
101 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(void) | ||
102 | { | ||
103 | return 0x2; | ||
104 | } | ||
97 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) | 105 | static inline u32 ltc_ltcs_ltss_cbc_ctrl1_clear_v(u32 r) |
98 | { | 106 | { |
99 | return (r >> 2) & 0x1; | 107 | return (r >> 2) & 0x1; |
diff --git a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c index 134ac491..305e28c2 100644 --- a/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/ltc_gm20b.c | |||
@@ -103,10 +103,12 @@ static int gm20b_ltc_init_comptags(struct gk20a *g, struct gr_gk20a *gr) | |||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | 105 | ||
106 | static int gm20b_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | 106 | static int gm20b_ltc_cbc_ctrl(struct gk20a *g, enum gk20a_cbc_op op, |
107 | u32 min, u32 max) | ||
107 | { | 108 | { |
109 | int err = 0; | ||
108 | struct gr_gk20a *gr = &g->gr; | 110 | struct gr_gk20a *gr = &g->gr; |
109 | u32 fbp, slice, ctrl1, val; | 111 | u32 fbp, slice, ctrl1, val, hw_op = 0; |
110 | unsigned long end_jiffies = jiffies + | 112 | unsigned long end_jiffies = jiffies + |
111 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); | 113 | msecs_to_jiffies(gk20a_get_gr_idle_timeout(g)); |
112 | u32 delay = GR_IDLE_CHECK_DEFAULT; | 114 | u32 delay = GR_IDLE_CHECK_DEFAULT; |
@@ -118,13 +120,23 @@ static int gm20b_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | |||
118 | if (gr->compbit_store.size == 0) | 120 | if (gr->compbit_store.size == 0) |
119 | return 0; | 121 | return 0; |
120 | 122 | ||
121 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(), | 123 | mutex_lock(&g->mm.l2_op_lock); |
122 | ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min)); | 124 | |
123 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(), | 125 | if (op == gk20a_cbc_op_clear) { |
124 | ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max)); | 126 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl2_r(), |
127 | ltc_ltcs_ltss_cbc_ctrl2_clear_lower_bound_f(min)); | ||
128 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl3_r(), | ||
129 | ltc_ltcs_ltss_cbc_ctrl3_clear_upper_bound_f(max)); | ||
130 | hw_op = ltc_ltcs_ltss_cbc_ctrl1_clear_active_f(); | ||
131 | } else if (op == gk20a_cbc_op_clean) { | ||
132 | hw_op = ltc_ltcs_ltss_cbc_ctrl1_clean_active_f(); | ||
133 | } else if (op == gk20a_cbc_op_invalidate) { | ||
134 | hw_op = ltc_ltcs_ltss_cbc_ctrl1_invalidate_active_f(); | ||
135 | } else { | ||
136 | BUG_ON(1); | ||
137 | } | ||
125 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(), | 138 | gk20a_writel(g, ltc_ltcs_ltss_cbc_ctrl1_r(), |
126 | gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) | | 139 | gk20a_readl(g, ltc_ltcs_ltss_cbc_ctrl1_r()) || hw_op); |
127 | ltc_ltcs_ltss_cbc_ctrl1_clear_active_f()); | ||
128 | 140 | ||
129 | for (fbp = 0; fbp < gr->num_fbps; fbp++) { | 141 | for (fbp = 0; fbp < gr->num_fbps; fbp++) { |
130 | for (slice = 0; slice < slices_per_ltc; slice++) { | 142 | for (slice = 0; slice < slices_per_ltc; slice++) { |
@@ -137,8 +149,7 @@ static int gm20b_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | |||
137 | 149 | ||
138 | do { | 150 | do { |
139 | val = gk20a_readl(g, ctrl1); | 151 | val = gk20a_readl(g, ctrl1); |
140 | if (ltc_ltcs_ltss_cbc_ctrl1_clear_v(val) != | 152 | if (!(val & hw_op)) |
141 | ltc_ltcs_ltss_cbc_ctrl1_clear_active_v()) | ||
142 | break; | 153 | break; |
143 | 154 | ||
144 | usleep_range(delay, delay * 2); | 155 | usleep_range(delay, delay * 2); |
@@ -151,11 +162,13 @@ static int gm20b_ltc_clear_comptags(struct gk20a *g, u32 min, u32 max) | |||
151 | if (!time_before(jiffies, end_jiffies)) { | 162 | if (!time_before(jiffies, end_jiffies)) { |
152 | gk20a_err(dev_from_gk20a(g), | 163 | gk20a_err(dev_from_gk20a(g), |
153 | "comp tag clear timeout\n"); | 164 | "comp tag clear timeout\n"); |
154 | return -EBUSY; | 165 | err = -EBUSY; |
166 | goto out; | ||
155 | } | 167 | } |
156 | } | 168 | } |
157 | } | 169 | } |
158 | 170 | out: | |
171 | mutex_unlock(&g->mm.l2_op_lock); | ||
159 | return 0; | 172 | return 0; |
160 | } | 173 | } |
161 | 174 | ||
@@ -192,6 +205,6 @@ void gm20b_init_ltc(struct gpu_ops *gops) | |||
192 | /* GM20b specific ops. */ | 205 | /* GM20b specific ops. */ |
193 | gops->ltc.init_fs_state = gm20b_ltc_init_fs_state; | 206 | gops->ltc.init_fs_state = gm20b_ltc_init_fs_state; |
194 | gops->ltc.init_comptags = gm20b_ltc_init_comptags; | 207 | gops->ltc.init_comptags = gm20b_ltc_init_comptags; |
195 | gops->ltc.clear_comptags = gm20b_ltc_clear_comptags; | 208 | gops->ltc.cbc_ctrl = gm20b_ltc_cbc_ctrl; |
196 | gops->ltc.elpg_flush = gk20a_mm_g_elpg_flush_locked; | 209 | gops->ltc.elpg_flush = gk20a_mm_g_elpg_flush_locked; |
197 | } | 210 | } |