aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/host1x/syncpt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/host1x/syncpt.c')
-rw-r--r--drivers/gpu/host1x/syncpt.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index 6b7fdc1e2ed0..95589328ad52 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -73,7 +73,7 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
73 return NULL; 73 return NULL;
74 } 74 }
75 75
76 name = kasprintf(GFP_KERNEL, "%02d-%s", sp->id, 76 name = kasprintf(GFP_KERNEL, "%02u-%s", sp->id,
77 dev ? dev_name(dev) : NULL); 77 dev ? dev_name(dev) : NULL);
78 if (!name) 78 if (!name)
79 return NULL; 79 return NULL;
@@ -110,12 +110,14 @@ EXPORT_SYMBOL(host1x_syncpt_incr_max);
110void host1x_syncpt_restore(struct host1x *host) 110void host1x_syncpt_restore(struct host1x *host)
111{ 111{
112 struct host1x_syncpt *sp_base = host->syncpt; 112 struct host1x_syncpt *sp_base = host->syncpt;
113 u32 i; 113 unsigned int i;
114 114
115 for (i = 0; i < host1x_syncpt_nb_pts(host); i++) 115 for (i = 0; i < host1x_syncpt_nb_pts(host); i++)
116 host1x_hw_syncpt_restore(host, sp_base + i); 116 host1x_hw_syncpt_restore(host, sp_base + i);
117
117 for (i = 0; i < host1x_syncpt_nb_bases(host); i++) 118 for (i = 0; i < host1x_syncpt_nb_bases(host); i++)
118 host1x_hw_syncpt_restore_wait_base(host, sp_base + i); 119 host1x_hw_syncpt_restore_wait_base(host, sp_base + i);
120
119 wmb(); 121 wmb();
120} 122}
121 123
@@ -126,7 +128,7 @@ void host1x_syncpt_restore(struct host1x *host)
126void host1x_syncpt_save(struct host1x *host) 128void host1x_syncpt_save(struct host1x *host)
127{ 129{
128 struct host1x_syncpt *sp_base = host->syncpt; 130 struct host1x_syncpt *sp_base = host->syncpt;
129 u32 i; 131 unsigned int i;
130 132
131 for (i = 0; i < host1x_syncpt_nb_pts(host); i++) { 133 for (i = 0; i < host1x_syncpt_nb_pts(host); i++) {
132 if (host1x_syncpt_client_managed(sp_base + i)) 134 if (host1x_syncpt_client_managed(sp_base + i))
@@ -146,6 +148,7 @@ void host1x_syncpt_save(struct host1x *host)
146u32 host1x_syncpt_load(struct host1x_syncpt *sp) 148u32 host1x_syncpt_load(struct host1x_syncpt *sp)
147{ 149{
148 u32 val; 150 u32 val;
151
149 val = host1x_hw_syncpt_load(sp->host, sp); 152 val = host1x_hw_syncpt_load(sp->host, sp);
150 trace_host1x_syncpt_load_min(sp->id, val); 153 trace_host1x_syncpt_load_min(sp->id, val);
151 154
@@ -157,10 +160,9 @@ u32 host1x_syncpt_load(struct host1x_syncpt *sp)
157 */ 160 */
158u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp) 161u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp)
159{ 162{
160 u32 val;
161 host1x_hw_syncpt_load_wait_base(sp->host, sp); 163 host1x_hw_syncpt_load_wait_base(sp->host, sp);
162 val = sp->base_val; 164
163 return val; 165 return sp->base_val;
164} 166}
165 167
166/* 168/*
@@ -179,6 +181,7 @@ EXPORT_SYMBOL(host1x_syncpt_incr);
179static bool syncpt_load_min_is_expired(struct host1x_syncpt *sp, u32 thresh) 181static bool syncpt_load_min_is_expired(struct host1x_syncpt *sp, u32 thresh)
180{ 182{
181 host1x_hw_syncpt_load(sp->host, sp); 183 host1x_hw_syncpt_load(sp->host, sp);
184
182 return host1x_syncpt_is_expired(sp, thresh); 185 return host1x_syncpt_is_expired(sp, thresh);
183} 186}
184 187
@@ -186,7 +189,7 @@ static bool syncpt_load_min_is_expired(struct host1x_syncpt *sp, u32 thresh)
186 * Main entrypoint for syncpoint value waits. 189 * Main entrypoint for syncpoint value waits.
187 */ 190 */
188int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, 191int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
189 u32 *value) 192 u32 *value)
190{ 193{
191 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); 194 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
192 void *ref; 195 void *ref;
@@ -201,6 +204,7 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
201 if (host1x_syncpt_is_expired(sp, thresh)) { 204 if (host1x_syncpt_is_expired(sp, thresh)) {
202 if (value) 205 if (value)
203 *value = host1x_syncpt_load(sp); 206 *value = host1x_syncpt_load(sp);
207
204 return 0; 208 return 0;
205 } 209 }
206 210
@@ -209,6 +213,7 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
209 if (host1x_syncpt_is_expired(sp, thresh)) { 213 if (host1x_syncpt_is_expired(sp, thresh)) {
210 if (value) 214 if (value)
211 *value = val; 215 *value = val;
216
212 goto done; 217 goto done;
213 } 218 }
214 219
@@ -239,32 +244,42 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
239 /* wait for the syncpoint, or timeout, or signal */ 244 /* wait for the syncpoint, or timeout, or signal */
240 while (timeout) { 245 while (timeout) {
241 long check = min_t(long, SYNCPT_CHECK_PERIOD, timeout); 246 long check = min_t(long, SYNCPT_CHECK_PERIOD, timeout);
242 int remain = wait_event_interruptible_timeout(wq, 247 int remain;
248
249 remain = wait_event_interruptible_timeout(wq,
243 syncpt_load_min_is_expired(sp, thresh), 250 syncpt_load_min_is_expired(sp, thresh),
244 check); 251 check);
245 if (remain > 0 || host1x_syncpt_is_expired(sp, thresh)) { 252 if (remain > 0 || host1x_syncpt_is_expired(sp, thresh)) {
246 if (value) 253 if (value)
247 *value = host1x_syncpt_load(sp); 254 *value = host1x_syncpt_load(sp);
255
248 err = 0; 256 err = 0;
257
249 break; 258 break;
250 } 259 }
260
251 if (remain < 0) { 261 if (remain < 0) {
252 err = remain; 262 err = remain;
253 break; 263 break;
254 } 264 }
265
255 timeout -= check; 266 timeout -= check;
267
256 if (timeout && check_count <= MAX_STUCK_CHECK_COUNT) { 268 if (timeout && check_count <= MAX_STUCK_CHECK_COUNT) {
257 dev_warn(sp->host->dev, 269 dev_warn(sp->host->dev,
258 "%s: syncpoint id %d (%s) stuck waiting %d, timeout=%ld\n", 270 "%s: syncpoint id %u (%s) stuck waiting %d, timeout=%ld\n",
259 current->comm, sp->id, sp->name, 271 current->comm, sp->id, sp->name,
260 thresh, timeout); 272 thresh, timeout);
261 273
262 host1x_debug_dump_syncpts(sp->host); 274 host1x_debug_dump_syncpts(sp->host);
275
263 if (check_count == MAX_STUCK_CHECK_COUNT) 276 if (check_count == MAX_STUCK_CHECK_COUNT)
264 host1x_debug_dump(sp->host); 277 host1x_debug_dump(sp->host);
278
265 check_count++; 279 check_count++;
266 } 280 }
267 } 281 }
282
268 host1x_intr_put_ref(sp->host, sp->id, ref); 283 host1x_intr_put_ref(sp->host, sp->id, ref);
269 284
270done: 285done:
@@ -279,7 +294,9 @@ bool host1x_syncpt_is_expired(struct host1x_syncpt *sp, u32 thresh)
279{ 294{
280 u32 current_val; 295 u32 current_val;
281 u32 future_val; 296 u32 future_val;
297
282 smp_rmb(); 298 smp_rmb();
299
283 current_val = (u32)atomic_read(&sp->min_val); 300 current_val = (u32)atomic_read(&sp->min_val);
284 future_val = (u32)atomic_read(&sp->max_val); 301 future_val = (u32)atomic_read(&sp->max_val);
285 302
@@ -341,14 +358,14 @@ int host1x_syncpt_init(struct host1x *host)
341{ 358{
342 struct host1x_syncpt_base *bases; 359 struct host1x_syncpt_base *bases;
343 struct host1x_syncpt *syncpt; 360 struct host1x_syncpt *syncpt;
344 int i; 361 unsigned int i;
345 362
346 syncpt = devm_kzalloc(host->dev, sizeof(*syncpt) * host->info->nb_pts, 363 syncpt = devm_kcalloc(host->dev, host->info->nb_pts, sizeof(*syncpt),
347 GFP_KERNEL); 364 GFP_KERNEL);
348 if (!syncpt) 365 if (!syncpt)
349 return -ENOMEM; 366 return -ENOMEM;
350 367
351 bases = devm_kzalloc(host->dev, sizeof(*bases) * host->info->nb_bases, 368 bases = devm_kcalloc(host->dev, host->info->nb_bases, sizeof(*bases),
352 GFP_KERNEL); 369 GFP_KERNEL);
353 if (!bases) 370 if (!bases)
354 return -ENOMEM; 371 return -ENOMEM;
@@ -378,6 +395,7 @@ struct host1x_syncpt *host1x_syncpt_request(struct device *dev,
378 unsigned long flags) 395 unsigned long flags)
379{ 396{
380 struct host1x *host = dev_get_drvdata(dev->parent); 397 struct host1x *host = dev_get_drvdata(dev->parent);
398
381 return host1x_syncpt_alloc(host, dev, flags); 399 return host1x_syncpt_alloc(host, dev, flags);
382} 400}
383EXPORT_SYMBOL(host1x_syncpt_request); 401EXPORT_SYMBOL(host1x_syncpt_request);
@@ -398,8 +416,9 @@ EXPORT_SYMBOL(host1x_syncpt_free);
398 416
399void host1x_syncpt_deinit(struct host1x *host) 417void host1x_syncpt_deinit(struct host1x *host)
400{ 418{
401 int i;
402 struct host1x_syncpt *sp = host->syncpt; 419 struct host1x_syncpt *sp = host->syncpt;
420 unsigned int i;
421
403 for (i = 0; i < host->info->nb_pts; i++, sp++) 422 for (i = 0; i < host->info->nb_pts; i++, sp++)
404 kfree(sp->name); 423 kfree(sp->name);
405} 424}
@@ -407,10 +426,11 @@ void host1x_syncpt_deinit(struct host1x *host)
407/* 426/*
408 * Read max. It indicates how many operations there are in queue, either in 427 * Read max. It indicates how many operations there are in queue, either in
409 * channel or in a software thread. 428 * channel or in a software thread.
410 * */ 429 */
411u32 host1x_syncpt_read_max(struct host1x_syncpt *sp) 430u32 host1x_syncpt_read_max(struct host1x_syncpt *sp)
412{ 431{
413 smp_rmb(); 432 smp_rmb();
433
414 return (u32)atomic_read(&sp->max_val); 434 return (u32)atomic_read(&sp->max_val);
415} 435}
416EXPORT_SYMBOL(host1x_syncpt_read_max); 436EXPORT_SYMBOL(host1x_syncpt_read_max);
@@ -421,6 +441,7 @@ EXPORT_SYMBOL(host1x_syncpt_read_max);
421u32 host1x_syncpt_read_min(struct host1x_syncpt *sp) 441u32 host1x_syncpt_read_min(struct host1x_syncpt *sp)
422{ 442{
423 smp_rmb(); 443 smp_rmb();
444
424 return (u32)atomic_read(&sp->min_val); 445 return (u32)atomic_read(&sp->min_val);
425} 446}
426EXPORT_SYMBOL(host1x_syncpt_read_min); 447EXPORT_SYMBOL(host1x_syncpt_read_min);
@@ -431,25 +452,26 @@ u32 host1x_syncpt_read(struct host1x_syncpt *sp)
431} 452}
432EXPORT_SYMBOL(host1x_syncpt_read); 453EXPORT_SYMBOL(host1x_syncpt_read);
433 454
434int host1x_syncpt_nb_pts(struct host1x *host) 455unsigned int host1x_syncpt_nb_pts(struct host1x *host)
435{ 456{
436 return host->info->nb_pts; 457 return host->info->nb_pts;
437} 458}
438 459
439int host1x_syncpt_nb_bases(struct host1x *host) 460unsigned int host1x_syncpt_nb_bases(struct host1x *host)
440{ 461{
441 return host->info->nb_bases; 462 return host->info->nb_bases;
442} 463}
443 464
444int host1x_syncpt_nb_mlocks(struct host1x *host) 465unsigned int host1x_syncpt_nb_mlocks(struct host1x *host)
445{ 466{
446 return host->info->nb_mlocks; 467 return host->info->nb_mlocks;
447} 468}
448 469
449struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id) 470struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, unsigned int id)
450{ 471{
451 if (host->info->nb_pts < id) 472 if (host->info->nb_pts < id)
452 return NULL; 473 return NULL;
474
453 return host->syncpt + id; 475 return host->syncpt + id;
454} 476}
455EXPORT_SYMBOL(host1x_syncpt_get); 477EXPORT_SYMBOL(host1x_syncpt_get);