diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2017-06-14 19:18:39 -0400 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2017-06-15 08:24:41 -0400 |
commit | a47ac10e6e628740dd122d650afd193941f4770b (patch) | |
tree | a090e4af268d86cc974d02380af455bde7c916c4 | |
parent | a2b78b0d53f0808ebc2a0368b589a5cb6b672294 (diff) |
gpu: host1x: Check waits in the firewall
Check waits in the firewall in a way it is done for relocations.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
Reviewed-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r-- | drivers/gpu/host1x/job.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index ef746f7afb88..f32ae69a68c7 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include "job.h" | 31 | #include "job.h" |
32 | #include "syncpt.h" | 32 | #include "syncpt.h" |
33 | 33 | ||
34 | #define HOST1X_WAIT_SYNCPT_OFFSET 0x8 | ||
35 | |||
34 | struct host1x_job *host1x_job_alloc(struct host1x_channel *ch, | 36 | struct host1x_job *host1x_job_alloc(struct host1x_channel *ch, |
35 | u32 num_cmdbufs, u32 num_relocs, | 37 | u32 num_cmdbufs, u32 num_relocs, |
36 | u32 num_waitchks) | 38 | u32 num_waitchks) |
@@ -337,6 +339,17 @@ static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf, | |||
337 | return true; | 339 | return true; |
338 | } | 340 | } |
339 | 341 | ||
342 | static bool check_wait(struct host1x_waitchk *wait, struct host1x_bo *cmdbuf, | ||
343 | unsigned int offset) | ||
344 | { | ||
345 | offset *= sizeof(u32); | ||
346 | |||
347 | if (wait->bo != cmdbuf || wait->offset != offset) | ||
348 | return false; | ||
349 | |||
350 | return true; | ||
351 | } | ||
352 | |||
340 | struct host1x_firewall { | 353 | struct host1x_firewall { |
341 | struct host1x_job *job; | 354 | struct host1x_job *job; |
342 | struct device *dev; | 355 | struct device *dev; |
@@ -344,6 +357,9 @@ struct host1x_firewall { | |||
344 | unsigned int num_relocs; | 357 | unsigned int num_relocs; |
345 | struct host1x_reloc *reloc; | 358 | struct host1x_reloc *reloc; |
346 | 359 | ||
360 | unsigned int num_waitchks; | ||
361 | struct host1x_waitchk *waitchk; | ||
362 | |||
347 | struct host1x_bo *cmdbuf; | 363 | struct host1x_bo *cmdbuf; |
348 | unsigned int offset; | 364 | unsigned int offset; |
349 | 365 | ||
@@ -370,6 +386,20 @@ static int check_register(struct host1x_firewall *fw, unsigned long offset) | |||
370 | fw->reloc++; | 386 | fw->reloc++; |
371 | } | 387 | } |
372 | 388 | ||
389 | if (offset == HOST1X_WAIT_SYNCPT_OFFSET) { | ||
390 | if (fw->class != HOST1X_CLASS_HOST1X) | ||
391 | return -EINVAL; | ||
392 | |||
393 | if (!fw->num_waitchks) | ||
394 | return -EINVAL; | ||
395 | |||
396 | if (!check_wait(fw->waitchk, fw->cmdbuf, fw->offset)) | ||
397 | return -EINVAL; | ||
398 | |||
399 | fw->num_waitchks--; | ||
400 | fw->waitchk++; | ||
401 | } | ||
402 | |||
373 | return 0; | 403 | return 0; |
374 | } | 404 | } |
375 | 405 | ||
@@ -534,6 +564,8 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev) | |||
534 | fw.dev = dev; | 564 | fw.dev = dev; |
535 | fw.reloc = job->relocarray; | 565 | fw.reloc = job->relocarray; |
536 | fw.num_relocs = job->num_relocs; | 566 | fw.num_relocs = job->num_relocs; |
567 | fw.waitchk = job->waitchk; | ||
568 | fw.num_waitchks = job->num_waitchk; | ||
537 | fw.class = job->class; | 569 | fw.class = job->class; |
538 | 570 | ||
539 | for (i = 0; i < job->num_gathers; i++) { | 571 | for (i = 0; i < job->num_gathers; i++) { |
@@ -572,8 +604,8 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev) | |||
572 | offset += g->words * sizeof(u32); | 604 | offset += g->words * sizeof(u32); |
573 | } | 605 | } |
574 | 606 | ||
575 | /* No relocs should remain at this point */ | 607 | /* No relocs and waitchks should remain at this point */ |
576 | if (fw.num_relocs) | 608 | if (fw.num_relocs || fw.num_waitchks) |
577 | return -EINVAL; | 609 | return -EINVAL; |
578 | 610 | ||
579 | return 0; | 611 | return 0; |