struct nvhost_hwctx_handler *nvhost_gr3d_t114_ctxhandler_init( u32 syncpt, u32 waitbase, struct nvhost_channel *ch) { struct mem_mgr *memmgr; u32 *save_ptr; struct host1x_hwctx_handler *p; p = kmalloc(sizeof(*p), GFP_KERNEL); if (!p) return NULL; memmgr = nvhost_get_host(ch->dev)->memmgr; p->h.syncpt = syncpt; p->h.waitbase = waitbase; setup_save(p, NULL); p->save_buf = nvhost_memmgr_alloc(memmgr, p->save_size * 4, 32, mem_mgr_flag_write_combine); if (IS_ERR(p->save_buf)) goto fail_alloc; save_ptr = nvhost_memmgr_mmap(p->save_buf); if (!save_ptr) goto fail_mmap; p->save_sgt = nvhost_memmgr_pin(memmgr, p->save_buf, &ch->dev->dev); if (IS_ERR(p->save_sgt)) goto fail_pin; p->save_phys = sg_dma_address(p->save_sgt->sgl); setup_save(p, save_ptr); nvhost_memmgr_munmap(p->save_buf, save_ptr); p->save_slots = 5; p->h.alloc = ctx3d_alloc_v1; p->h.save_push = save_push_v1; p->h.restore_push = nvhost_3dctx_restore_push; p->h.save_service = NULL; p->h.get = nvhost_3dctx_get; p->h.put = nvhost_3dctx_put; return &p->h; fail_pin: nvhost_memmgr_munmap(p->save_buf, save_ptr); fail_mmap: nvhost_memmgr_put(memmgr, p->save_buf); fail_alloc: kfree(p); return NULL; }
int user_hwctx_set_save(struct user_hwctx *ctx, ulong mem, u32 offset, u32 words, struct nvhost_reloc *reloc) { struct mem_handle *buf; struct sg_table *sgt; void *page_addr; /* First the restore buffer is set, then the save buffer */ if (!ctx->restore || !ctx->restore_sgt) return -EINVAL; buf = nvhost_memmgr_get(ctx->hwctx.memmgr, mem, ctx->hwctx.channel->dev); if (IS_ERR(buf)) return PTR_ERR(buf); sgt = nvhost_memmgr_pin(ctx->hwctx.memmgr, buf, &ctx->hwctx.channel->dev->dev, mem_flag_none); if (IS_ERR(sgt)) return PTR_ERR(sgt); ctx->save_offset = offset; ctx->save_size = words; ctx->save_buf = buf; ctx->save_sgt = sgt; /* Patch restore buffer address into save buffer */ page_addr = nvhost_memmgr_kmap(ctx->save_buf, reloc->cmdbuf_offset >> PAGE_SHIFT); if (!page_addr) return -ENOMEM; __raw_writel(nvhost_memmgr_dma_addr(ctx->restore_sgt) + offset, page_addr + (reloc->cmdbuf_offset & ~PAGE_MASK)); nvhost_memmgr_kunmap(ctx->save_buf, reloc->cmdbuf_offset >> PAGE_SHIFT, page_addr); return 0; }
int user_hwctx_set_restore(struct user_hwctx *ctx, ulong mem, u32 offset, u32 words) { struct mem_handle *buf; struct sg_table *sgt; buf = nvhost_memmgr_get(ctx->hwctx.memmgr, mem, ctx->hwctx.channel->dev); if (IS_ERR(buf)) return PTR_ERR(buf); sgt = nvhost_memmgr_pin(ctx->hwctx.memmgr, buf, &ctx->hwctx.channel->dev->dev, mem_flag_none); if (IS_ERR(sgt)) return PTR_ERR(sgt); ctx->restore_offset = offset; ctx->restore_size = words; ctx->restore = buf; ctx->restore_sgt = sgt; return 0; }
int user_hwctx_set_restore(struct user_hwctx *ctx, u32 mem, u32 offset, u32 words) { struct mem_handle *buf; struct sg_table *sgt; buf = nvhost_memmgr_get(ctx->hwctx.memmgr, mem, ctx->hwctx.channel->dev); if (IS_ERR_OR_NULL(buf)) return -ENOMEM; sgt = nvhost_memmgr_pin(ctx->hwctx.memmgr, buf, &ctx->hwctx.channel->dev->dev); if (IS_ERR_OR_NULL(sgt)) return -ENOMEM; ctx->restore_offset = offset; ctx->restore_size = words; ctx->restore = buf; ctx->restore_sgt = sgt; return 0; }
int nvhost_gr3d_t30_read_reg( struct platform_device *dev, struct nvhost_channel *channel, struct nvhost_hwctx *hwctx, u32 offset, u32 *value) { struct host1x_hwctx_handler *h = to_host1x_hwctx_handler(hwctx->h); u32 syncpt_incrs = 1; DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); void *ref; void *read_waiter = NULL; struct nvhost_job *job; int err; struct mem_handle *mem = NULL; u32 *mem_ptr = NULL; u32 *cmdbuf_ptr = NULL; struct sg_table *mem_sgt = NULL; struct mem_mgr *memmgr = hwctx->memmgr; u32 opcodes[] = { /* Switch to 3D - set up output to memory */ nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0, 0), nvhost_opcode_imm(AR3D_GLOBAL_MEMORY_OUTPUT_READS, 1), nvhost_opcode_nonincr(AR3D_DW_MEMORY_OUTPUT_ADDRESS, 1), 0xdeadbeef, /* Get host1x to request a register read */ nvhost_opcode_setclass(NV_HOST1X_CLASS_ID, host1x_uclass_indoff_r(), 1), nvhost_class_host_indoff_reg_read( host1x_uclass_indoff_indmodid_gr3d_v(), offset, false), nvhost_opcode_imm(host1x_uclass_inddata_r(), 0), /* send reg reads back to host */ nvhost_opcode_setclass(NV_GRAPHICS_3D_CLASS_ID, 0, 0), nvhost_opcode_imm(AR3D_GLOBAL_MEMORY_OUTPUT_READS, 0), /* Finalize with syncpt increment */ nvhost_opcode_setclass(NV_HOST1X_CLASS_ID, host1x_uclass_incr_syncpt_base_r(), 1), nvhost_class_host_incr_syncpt_base(h->h.waitbase, 1), nvhost_opcode_imm_incr_syncpt( host1x_uclass_incr_syncpt_cond_immediate_v(), h->h.syncpt), }; /* 12 slots for gather, and one slot for storing the result value */ mem = nvhost_memmgr_alloc(memmgr, sizeof(opcodes)+4, 32, mem_mgr_flag_uncacheable); if (IS_ERR(mem)) return PTR_ERR(mem); mem_ptr = nvhost_memmgr_mmap(mem); if (!mem_ptr) { err = -ENOMEM; goto done; } cmdbuf_ptr = mem_ptr + 1; mem_sgt = nvhost_memmgr_pin(memmgr, mem, &channel->dev->dev); if (IS_ERR(mem_sgt)) { err = -ENOMEM; mem_sgt = NULL; goto done; } /* Set address of target memory slot to the stream */ opcodes[3] = sg_dma_address(mem_sgt->sgl); read_waiter = nvhost_intr_alloc_waiter(); if (!read_waiter) { err = -ENOMEM; goto done; } job = nvhost_job_alloc(channel, hwctx, 1, 0, 0, 1, memmgr); if (!job) { err = -ENOMEM; goto done; } job->hwctx_syncpt_idx = 0; job->sp->id = h->h.syncpt; job->sp->waitbase = h->h.waitbase; job->sp->incrs = syncpt_incrs; job->num_syncpts = 1; job->serialize = 1; memcpy(cmdbuf_ptr, opcodes, sizeof(opcodes)); /* Submit job */ nvhost_job_add_gather(job, nvhost_memmgr_handle_to_id(mem), ARRAY_SIZE(opcodes), 4); err = nvhost_job_pin(job, &nvhost_get_host(dev)->syncpt); if (err) goto done; err = nvhost_channel_submit(job); if (err) goto done; /* Wait for read to be ready */ err = nvhost_intr_add_action(&nvhost_get_host(dev)->intr, h->h.syncpt, job->sp->fence, NVHOST_INTR_ACTION_WAKEUP, &wq, read_waiter, &ref); read_waiter = NULL; WARN(err, "Failed to set wakeup interrupt"); wait_event(wq, nvhost_syncpt_is_expired(&nvhost_get_host(dev)->syncpt, h->h.syncpt, job->sp->fence)); nvhost_job_put(job); job = NULL; nvhost_intr_put_ref(&nvhost_get_host(dev)->intr, h->h.syncpt, ref); *value = *mem_ptr; done: kfree(read_waiter); if (mem_ptr) nvhost_memmgr_munmap(mem, mem_ptr); if (mem_sgt) nvhost_memmgr_unpin(memmgr, mem, &channel->dev->dev, mem_sgt); if (mem) nvhost_memmgr_put(memmgr, mem); return err; }