diff options
Diffstat (limited to 'drivers/gpu/host1x/syncpt.c')
-rw-r--r-- | drivers/gpu/host1x/syncpt.c | 58 |
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); | |||
110 | void host1x_syncpt_restore(struct host1x *host) | 110 | void 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) | |||
126 | void host1x_syncpt_save(struct host1x *host) | 128 | void 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) | |||
146 | u32 host1x_syncpt_load(struct host1x_syncpt *sp) | 148 | u32 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 | */ |
158 | u32 host1x_syncpt_load_wait_base(struct host1x_syncpt *sp) | 161 | u32 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); | |||
179 | static bool syncpt_load_min_is_expired(struct host1x_syncpt *sp, u32 thresh) | 181 | static 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 | */ |
188 | int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, | 191 | int 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 | ||
270 | done: | 285 | done: |
@@ -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 | } |
383 | EXPORT_SYMBOL(host1x_syncpt_request); | 401 | EXPORT_SYMBOL(host1x_syncpt_request); |
@@ -398,8 +416,9 @@ EXPORT_SYMBOL(host1x_syncpt_free); | |||
398 | 416 | ||
399 | void host1x_syncpt_deinit(struct host1x *host) | 417 | void 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 | */ |
411 | u32 host1x_syncpt_read_max(struct host1x_syncpt *sp) | 430 | u32 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 | } |
416 | EXPORT_SYMBOL(host1x_syncpt_read_max); | 436 | EXPORT_SYMBOL(host1x_syncpt_read_max); |
@@ -421,6 +441,7 @@ EXPORT_SYMBOL(host1x_syncpt_read_max); | |||
421 | u32 host1x_syncpt_read_min(struct host1x_syncpt *sp) | 441 | u32 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 | } |
426 | EXPORT_SYMBOL(host1x_syncpt_read_min); | 447 | EXPORT_SYMBOL(host1x_syncpt_read_min); |
@@ -431,25 +452,26 @@ u32 host1x_syncpt_read(struct host1x_syncpt *sp) | |||
431 | } | 452 | } |
432 | EXPORT_SYMBOL(host1x_syncpt_read); | 453 | EXPORT_SYMBOL(host1x_syncpt_read); |
433 | 454 | ||
434 | int host1x_syncpt_nb_pts(struct host1x *host) | 455 | unsigned 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 | ||
439 | int host1x_syncpt_nb_bases(struct host1x *host) | 460 | unsigned 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 | ||
444 | int host1x_syncpt_nb_mlocks(struct host1x *host) | 465 | unsigned 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 | ||
449 | struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id) | 470 | struct 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 | } |
455 | EXPORT_SYMBOL(host1x_syncpt_get); | 477 | EXPORT_SYMBOL(host1x_syncpt_get); |