diff options
Diffstat (limited to 'drivers/video/tegra/host/nvhost_channel.c')
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c index 949e67ffb653..70fb173d7f41 100644 --- a/drivers/video/tegra/host/nvhost_channel.c +++ b/drivers/video/tegra/host/nvhost_channel.c @@ -168,11 +168,12 @@ void nvhost_channel_suspend(struct nvhost_channel *ch) } void nvhost_channel_submit(struct nvhost_channel *ch, - struct nvmap_client *user_nvmap, - struct nvhost_op_pair *ops, int num_pairs, - struct nvhost_cpuinterrupt *intrs, int num_intrs, - struct nvmap_handle **unpins, int num_unpins, - u32 syncpt_id, u32 syncpt_val) + struct nvmap_client *user_nvmap, + struct nvhost_op_pair *ops, int num_pairs, + struct nvhost_cpuinterrupt *intrs, int num_intrs, + struct nvmap_handle **unpins, int num_unpins, + u32 syncpt_id, u32 syncpt_val, + int num_nulled_incrs) { int i; struct nvhost_op_pair* p; @@ -190,6 +191,31 @@ void nvhost_channel_submit(struct nvhost_channel *ch, for (i = 0, p = ops; i < num_pairs; i++, p++) nvhost_cdma_push(&ch->cdma, p->op1, p->op2); + /* extra work to do for null kickoff */ + if (num_nulled_incrs) { + u32 incr; + u32 op_incr; + + /* TODO ideally we'd also perform host waits here */ + + /* push increments that correspond to nulled out commands */ + op_incr = nvhost_opcode_imm(0, 0x100 | syncpt_id); + for (incr = 0; incr < (num_nulled_incrs >> 1); incr++) + nvhost_cdma_push(&ch->cdma, op_incr, op_incr); + if (num_nulled_incrs & 1) + nvhost_cdma_push(&ch->cdma, op_incr, NVHOST_OPCODE_NOOP); + + /* for 3d, waitbase needs to be incremented after each submit */ + if (ch->desc->class == NV_GRAPHICS_3D_CLASS_ID) { + u32 op1 = nvhost_opcode_setclass(NV_HOST1X_CLASS_ID, + NV_CLASS_HOST_INCR_SYNCPT_BASE, 1); + u32 op2 = nvhost_class_host_incr_syncpt_base(NVWAITBASE_3D, + num_nulled_incrs); + + nvhost_cdma_push(&ch->cdma, op1, op2); + } + } + /* end CDMA submit & stash pinned hMems into sync queue for later cleanup */ nvhost_cdma_end(user_nvmap, &ch->cdma, syncpt_id, syncpt_val, unpins, num_unpins); @@ -228,7 +254,7 @@ static void power_3d(struct nvhost_module *mod, enum nvhost_power_action action) nvhost_channel_submit(ch, ch->dev->nvmap, &save, 1, &ctxsw, 1, NULL, 0, - NVSYNCPT_3D, syncval); + NVSYNCPT_3D, syncval, 0); nvhost_intr_add_action(&ch->dev->intr, NVSYNCPT_3D, syncval, |