summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/nvhost_channel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/tegra/host/nvhost_channel.c')
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c38
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,