int kgsl_g12_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv, int drawctxt_index, uint32_t ibaddr, int sizedwords, uint32_t *timestamp, unsigned int ctrl) { unsigned int result = 0; unsigned int ofs = PACKETSIZE_STATESTREAM * sizeof(unsigned int); unsigned int cnt = 5; unsigned int nextaddr = 0; unsigned int index = 0; unsigned int nextindex; unsigned int nextcnt = KGSL_G12_STREAM_END_CMD | 5; struct kgsl_memdesc tmp = {0}; unsigned int cmd; struct kgsl_device *device = dev_priv->device; struct kgsl_pagetable *pagetable = dev_priv->process_priv->pagetable; struct kgsl_g12_device *g12_device = (struct kgsl_g12_device *) device; cmd = ibaddr; tmp.hostptr = (void *)*timestamp; KGSL_CMD_INFO("ctxt %d ibaddr 0x%08x sizedwords %d", drawctxt_index, ibaddr, sizedwords); /* context switch */ if (drawctxt_index != (int)g12_device->ringbuffer.prevctx) { KGSL_CMD_INFO("context switch %d -> %d", drawctxt_index, g12_device->ringbuffer.prevctx); kgsl_mmu_setstate(device, pagetable); cnt = PACKETSIZE_STATESTREAM; ofs = 0; } kgsl_g12_setstate(device, kgsl_pt_get_flags(device->mmu.hwpagetable, device->id)); result = wait_event_interruptible_timeout(g12_device->wait_timestamp_wq, room_in_rb(g12_device), msecs_to_jiffies(KGSL_TIMEOUT_DEFAULT)); if (result < 0) { KGSL_CMD_ERR("failed waiting for ringbuffer. result %d", result); goto error; } result = 0; index = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT; g12_device->current_timestamp++; nextindex = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT; *timestamp = g12_device->current_timestamp; g12_device->ringbuffer.prevctx = drawctxt_index; addcmd(&g12_device->ringbuffer, index, cmd + ofs, cnt); /* Make sure the next ringbuffer entry has a marker */ addmarker(&g12_device->ringbuffer, nextindex); nextaddr = g12_device->ringbuffer.cmdbufdesc.gpuaddr + rb_offset(nextindex); tmp.hostptr = (void *)(tmp.hostptr + (sizedwords * sizeof(unsigned int))); tmp.size = 12; kgsl_sharedmem_writel(&tmp, 4, nextaddr); kgsl_sharedmem_writel(&tmp, 8, nextcnt); cmd = (int)(((2) & VGV3_CONTROL_MARKADD_FMASK) << VGV3_CONTROL_MARKADD_FSHIFT); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, cmd); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0); error: return result; }
int kgsl_g12_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv, int drawctxt_index, uint32_t ibaddr, int sizedwords, uint32_t *timestamp, unsigned int ctrl) { unsigned int result = 0; unsigned int ofs = PACKETSIZE_STATESTREAM * sizeof(unsigned int); unsigned int cnt = 5; unsigned int nextaddr = 0; unsigned int index = 0; unsigned int nextcnt = 0x9000 | 5; struct kgsl_memdesc tmp = {0}; unsigned int cmd; struct kgsl_device *device = dev_priv->device; struct kgsl_pagetable *pagetable = dev_priv->process_priv->pagetable; struct kgsl_g12_device *g12_device = (struct kgsl_g12_device *) device; cmd = ibaddr; tmp.hostptr = (void *)*timestamp; KGSL_CMD_INFO("ctxt %d ibaddr 0x%08x sizedwords %d", drawctxt_index, ibaddr, sizedwords); if (drawctxt_index != (int)g_z1xx.prevctx) { kgsl_mmu_setstate(device, pagetable); cnt = PACKETSIZE_STATESTREAM; ofs = 0; } else { kgsl_g12_setstate(device, device->mmu.tlb_flags); } result = wait_event_interruptible_timeout(g12_device->wait_timestamp_wq, room_in_rb(g12_device), msecs_to_jiffies(KGSL_TIMEOUT_DEFAULT)); if (result < 0) { KGSL_CMD_ERR("failed waiting for ringbuffer. result %d", result); goto error; } result = 0; index = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT; g12_device->current_timestamp++; *timestamp = g12_device->current_timestamp; g_z1xx.prevctx = drawctxt_index; addcmd(&g_z1xx, index, cmd + ofs, cnt); nextaddr = g_z1xx.cmdbufdesc.physaddr + rb_offset((index + 1) % KGSL_G12_PACKET_COUNT); tmp.hostptr = (void *)(tmp.hostptr + (sizedwords * sizeof(unsigned int))); tmp.size = 12; kgsl_sharedmem_writel(&tmp, 4, nextaddr); kgsl_sharedmem_writel(&tmp, 8, nextcnt); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 1); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0); error: return result; }
int kgsl_g12_cmdstream_issueibcmds(struct kgsl_device_private *dev_priv, struct kgsl_context *context, struct kgsl_ibdesc *ibdesc, unsigned int numibs, uint32_t *timestamp, unsigned int ctrl) { int result = 0; unsigned int ofs = PACKETSIZE_STATESTREAM * sizeof(unsigned int); unsigned int cnt = 5; unsigned int nextaddr = 0; unsigned int index = 0; unsigned int nextindex; unsigned int nextcnt = KGSL_G12_STREAM_END_CMD | 5; struct kgsl_memdesc tmp = {0}; unsigned int cmd; struct kgsl_device *device = dev_priv->device; struct kgsl_pagetable *pagetable = dev_priv->process_priv->pagetable; struct kgsl_g12_device *g12_device = KGSL_G12_DEVICE(device); unsigned int sizedwords; if (device->state & KGSL_STATE_HUNG) { return -EINVAL; goto error; } if (numibs != 1) { KGSL_DRV_ERR(device, "Invalid number of ibs: %d\n", numibs); result = -EINVAL; goto error; } cmd = ibdesc[0].gpuaddr; sizedwords = ibdesc[0].sizedwords; tmp.hostptr = (void *)*timestamp; KGSL_CMD_INFO(device, "ctxt %d ibaddr 0x%08x sizedwords %d\n", context->id, cmd, sizedwords); /* context switch */ if ((context->id != (int)g12_device->ringbuffer.prevctx) || (ctrl & KGSL_CONTEXT_CTX_SWITCH)) { KGSL_CMD_INFO(device, "context switch %d -> %d\n", context->id, g12_device->ringbuffer.prevctx); kgsl_mmu_setstate(device, pagetable); cnt = PACKETSIZE_STATESTREAM; ofs = 0; } kgsl_g12_setstate(device, kgsl_pt_get_flags(device->mmu.hwpagetable, device->id)); result = wait_event_interruptible_timeout(device->wait_queue, room_in_rb(g12_device), msecs_to_jiffies(KGSL_TIMEOUT_DEFAULT)); if (result <= 0) { KGSL_CMD_ERR(device, "wait_event_interruptible_timeout " "failed: %d\n", result); goto error; } result = 0; index = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT; g12_device->current_timestamp++; nextindex = g12_device->current_timestamp % KGSL_G12_PACKET_COUNT; *timestamp = g12_device->current_timestamp; g12_device->ringbuffer.prevctx = context->id; addcmd(&g12_device->ringbuffer, index, cmd + ofs, cnt); /* Make sure the next ringbuffer entry has a marker */ addmarker(&g12_device->ringbuffer, nextindex); nextaddr = g12_device->ringbuffer.cmdbufdesc.gpuaddr + rb_offset(nextindex); tmp.hostptr = (void *)(tmp.hostptr + (sizedwords * sizeof(unsigned int))); tmp.size = 12; kgsl_sharedmem_writel(&tmp, 4, nextaddr); kgsl_sharedmem_writel(&tmp, 8, nextcnt); /* sync memory before activating the hardware for the new command*/ mb(); cmd = (int)(((2) & VGV3_CONTROL_MARKADD_FMASK) << VGV3_CONTROL_MARKADD_FSHIFT); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, cmd); kgsl_g12_cmdwindow_write(device, KGSL_CMDWINDOW_2D, ADDR_VGV3_CONTROL, 0); error: return result; }