#include "scale3d.h"
#include "bus_client.h"
#include "nvhost_channel.h"
-#include "nvhost_memmgr.h"
#include "chip_support.h"
#include "pod_scaling.h"
#include "class_ids.h"
#include "nvhost_job.h"
-int nvhost_gr3d_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;
- ulong user_id;
- 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, 0);
- 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,
- mem_flag_none);
- if (IS_ERR(mem_sgt)) {
- err = -ENOMEM;
- mem_sgt = NULL;
- goto done;
- }
- /* Set address of target memory slot to the stream */
- opcodes[3] = nvhost_memmgr_dma_addr(mem_sgt);
-
- 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));
-
-#ifdef CONFIG_NVMAP_USE_FD_FOR_HANDLE
- get_dma_buf((struct dma_buf *)mem);
- user_id = dma_buf_fd((struct dma_buf *)mem, O_CLOEXEC);
-#else
- user_id = nvhost_memmgr_handle_to_id(mem);
-#endif
-
- /* Submit job */
- nvhost_job_add_gather(job, user_id,
- ARRAY_SIZE(opcodes), 4, 0);
-
- err = nvhost_job_pin(job, &nvhost_get_host(dev)->syncpt);
- if (err)
- goto done;
-
-#ifdef CONFIG_NVMAP_USE_FD_FOR_HANDLE
- sys_close(user_id);
-#endif
- 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;
-}
void nvhost_3dctx_restore_begin(struct host1x_hwctx_handler *p, u32 *ptr)
{
/* set class to host */