aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2013-05-29 06:26:04 -0400
committerThierry Reding <thierry.reding@gmail.com>2013-06-22 06:43:53 -0400
commitafac0e43c6c98473cce18fdeb5f7dda86dcf244f (patch)
treec0521c4175d60aa4d3854764d5ddbb7ae69b4972 /drivers/gpu
parent5060d8ec7cfc29dd399b4fe952ba96e7a88aa778 (diff)
gpu: host1x: Don't reset firewall between gathers
The firewall was reinitialised for each gather. Because the filter was reinitialised, it did not track the class over gather boundaries. This allowed the user application to set host1x class to one class in one gather and use that class in another gather without firewall having knowledge about that. Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/host1x/job.c72
1 files changed, 34 insertions, 38 deletions
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index 83804fdf9c99..5b9548f610f1 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -376,69 +376,60 @@ static int check_nonincr(struct host1x_firewall *fw)
376 return 0; 376 return 0;
377} 377}
378 378
379static int validate(struct host1x_job *job, struct device *dev, 379static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g)
380 struct host1x_job_gather *g)
381{ 380{
382 u32 *cmdbuf_base; 381 u32 *cmdbuf_base;
383 int err = 0; 382 int err = 0;
384 struct host1x_firewall fw;
385 383
386 fw.job = job; 384 if (!fw->job->is_addr_reg)
387 fw.dev = dev;
388 fw.reloc = job->relocarray;
389 fw.num_relocs = job->num_relocs;
390 fw.cmdbuf_id = g->bo;
391
392 fw.offset = 0;
393 fw.class = 0;
394
395 if (!job->is_addr_reg)
396 return 0; 385 return 0;
397 386
398 cmdbuf_base = host1x_bo_mmap(g->bo); 387 cmdbuf_base = host1x_bo_mmap(g->bo);
399 if (!cmdbuf_base) 388 if (!cmdbuf_base)
400 return -ENOMEM; 389 return -ENOMEM;
390 fw->words = g->words;
391 fw->cmdbuf_id = g->bo;
392 fw->offset = 0;
401 393
402 fw.words = g->words; 394 while (fw->words && !err) {
403 while (fw.words && !err) { 395 u32 word = cmdbuf_base[fw->offset];
404 u32 word = cmdbuf_base[fw.offset];
405 u32 opcode = (word & 0xf0000000) >> 28; 396 u32 opcode = (word & 0xf0000000) >> 28;
406 397
407 fw.mask = 0; 398 fw->mask = 0;
408 fw.reg = 0; 399 fw->reg = 0;
409 fw.count = 0; 400 fw->count = 0;
410 fw.words--; 401 fw->words--;
411 fw.offset++; 402 fw->offset++;
412 403
413 switch (opcode) { 404 switch (opcode) {
414 case 0: 405 case 0:
415 fw.class = word >> 6 & 0x3ff; 406 fw->class = word >> 6 & 0x3ff;
416 fw.mask = word & 0x3f; 407 fw->mask = word & 0x3f;
417 fw.reg = word >> 16 & 0xfff; 408 fw->reg = word >> 16 & 0xfff;
418 err = check_mask(&fw); 409 err = check_mask(fw);
419 if (err) 410 if (err)
420 goto out; 411 goto out;
421 break; 412 break;
422 case 1: 413 case 1:
423 fw.reg = word >> 16 & 0xfff; 414 fw->reg = word >> 16 & 0xfff;
424 fw.count = word & 0xffff; 415 fw->count = word & 0xffff;
425 err = check_incr(&fw); 416 err = check_incr(fw);
426 if (err) 417 if (err)
427 goto out; 418 goto out;
428 break; 419 break;
429 420
430 case 2: 421 case 2:
431 fw.reg = word >> 16 & 0xfff; 422 fw->reg = word >> 16 & 0xfff;
432 fw.count = word & 0xffff; 423 fw->count = word & 0xffff;
433 err = check_nonincr(&fw); 424 err = check_nonincr(fw);
434 if (err) 425 if (err)
435 goto out; 426 goto out;
436 break; 427 break;
437 428
438 case 3: 429 case 3:
439 fw.mask = word & 0xffff; 430 fw->mask = word & 0xffff;
440 fw.reg = word >> 16 & 0xfff; 431 fw->reg = word >> 16 & 0xfff;
441 err = check_mask(&fw); 432 err = check_mask(fw);
442 if (err) 433 if (err)
443 goto out; 434 goto out;
444 break; 435 break;
@@ -453,12 +444,10 @@ static int validate(struct host1x_job *job, struct device *dev,
453 } 444 }
454 445
455 /* No relocs should remain at this point */ 446 /* No relocs should remain at this point */
456 if (fw.num_relocs) 447 if (fw->num_relocs)
457 err = -EINVAL; 448 err = -EINVAL;
458 449
459out: 450out:
460 host1x_bo_munmap(g->bo, cmdbuf_base);
461
462 return err; 451 return err;
463} 452}
464 453
@@ -508,8 +497,15 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
508 int err; 497 int err;
509 unsigned int i, j; 498 unsigned int i, j;
510 struct host1x *host = dev_get_drvdata(dev->parent); 499 struct host1x *host = dev_get_drvdata(dev->parent);
500 struct host1x_firewall fw;
511 DECLARE_BITMAP(waitchk_mask, host1x_syncpt_nb_pts(host)); 501 DECLARE_BITMAP(waitchk_mask, host1x_syncpt_nb_pts(host));
512 502
503 fw.job = job;
504 fw.dev = dev;
505 fw.reloc = job->relocarray;
506 fw.num_relocs = job->num_relocs;
507 fw.class = 0;
508
513 bitmap_zero(waitchk_mask, host1x_syncpt_nb_pts(host)); 509 bitmap_zero(waitchk_mask, host1x_syncpt_nb_pts(host));
514 for (i = 0; i < job->num_waitchk; i++) { 510 for (i = 0; i < job->num_waitchk; i++) {
515 u32 syncpt_id = job->waitchk[i].syncpt_id; 511 u32 syncpt_id = job->waitchk[i].syncpt_id;
@@ -543,7 +539,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
543 err = 0; 539 err = 0;
544 540
545 if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) 541 if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
546 err = validate(job, dev, g); 542 err = validate(&fw, g);
547 543
548 if (err) 544 if (err)
549 dev_err(dev, "Job invalid (err=%d)\n", err); 545 dev_err(dev, "Job invalid (err=%d)\n", err);