summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host/nvhost_channel.c
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@nvidia.com>2011-02-11 02:17:29 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:44:51 -0800
commit03e6e69aca66b068c5c9a5e0de1da3873e3146dc (patch)
tree637d12464fc3d154764116ffdde4e71eb609d15d /drivers/video/tegra/host/nvhost_channel.c
parent9e9b4e07a9408fb27e9d6aad37341dca8d231eaf (diff)
nvhost: Reimplement null kickoff functionality.
For each channel submit where null kickoff is requested, we don't place the user's commands in the pushbuffer. All necessary context switches, syncpoint increments and waitbase increments do happen though. Update: Add NULL_KICKOFF ioctl to use instead of FLIP, this prevents kernel ABI breakage. Bug 717235 Previous Id: I51c323729ea57993a5b52fb395ab90cb8608ee6b Previously Reviewed: http://git-master/r/5091 Original-Change-Id: I4f92db457aff6e1c3a8d454255c4b051c4663360 Reviewed-on: http://git-master/r/15882 Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com> Tested-by: Daniel Willemsen <dwillemsen@nvidia.com> Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: Rc79842436757d1cb1ae0622cf62e98763420ba6c
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 3a6998909ed5..c1f440577ab0 100644
--- a/drivers/video/tegra/host/nvhost_channel.c
+++ b/drivers/video/tegra/host/nvhost_channel.c
@@ -169,11 +169,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;
@@ -191,6 +192,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);
@@ -229,7 +255,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,