static uint32_t kgsl_ringbuffer_addcmds(struct kgsl_ringbuffer *rb, unsigned int flags, unsigned int *cmds, int sizedwords) { unsigned int *ringcmds; unsigned int timestamp; unsigned int total_sizedwords = sizedwords + 6; total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0; total_sizedwords += !(flags & KGSL_CMD_FLAGS_NO_TS_CMP) ? 9 : 0; ringcmds = kgsl_ringbuffer_allocspace(rb, total_sizedwords); if (flags & KGSL_CMD_FLAGS_PMODE) { *ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1); *ringcmds++ = 0; } memcpy(ringcmds, cmds, (sizedwords << 2)); ringcmds += sizedwords; if (flags & KGSL_CMD_FLAGS_PMODE) { *ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1); *ringcmds++ = 1; } rb->timestamp++; timestamp = rb->timestamp; *ringcmds++ = pm4_type0_packet(REG_CP_TIMESTAMP, 1); *ringcmds++ = rb->timestamp; *ringcmds++ = pm4_type3_packet(PM4_EVENT_WRITE, 3); *ringcmds++ = CACHE_FLUSH_TS; *ringcmds++ = (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)); *ringcmds++ = rb->timestamp; if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) { *ringcmds++ = pm4_type3_packet(PM4_COND_EXEC, 4); *ringcmds++ = (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable)) >> 2; *ringcmds++ = (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts)) >> 2; *ringcmds++ = rb->timestamp; *ringcmds++ = 4; *ringcmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); *ringcmds++ = 0x00000000; *ringcmds++ = pm4_type3_packet(PM4_INTERRUPT, 1); *ringcmds++ = CP_INT_CNTL__RB_INT_MASK; }
static uint32_t kgsl_ringbuffer_addcmds(struct kgsl_ringbuffer *rb, unsigned int flags, unsigned int *cmds, int sizedwords) { unsigned int *ringcmds; unsigned int timestamp; unsigned int total_sizedwords = sizedwords + 6; unsigned int i; unsigned int rcmd_gpu; /* reserve space to temporarily turn off protected mode * error checking if needed */ total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0; total_sizedwords += !(flags & KGSL_CMD_FLAGS_NO_TS_CMP) ? 7 : 0; total_sizedwords += !(flags & KGSL_CMD_FLAGS_NOT_KERNEL_CMD) ? 2 : 0; ringcmds = kgsl_ringbuffer_allocspace(rb, total_sizedwords); rcmd_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-total_sizedwords); if (!(flags & KGSL_CMD_FLAGS_NOT_KERNEL_CMD)) { GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_nop_packet(1)); GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER); } if (flags & KGSL_CMD_FLAGS_PMODE) { /* disable protected mode error checking */ GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1)); GSL_RB_WRITE(ringcmds, rcmd_gpu, 0); } for (i = 0; i < sizedwords; i++) { GSL_RB_WRITE(ringcmds, rcmd_gpu, *cmds); cmds++; } if (flags & KGSL_CMD_FLAGS_PMODE) { /* re-enable protected mode error checking */ GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1)); GSL_RB_WRITE(ringcmds, rcmd_gpu, 1); } rb->timestamp++; timestamp = rb->timestamp; /* start-of-pipeline and end-of-pipeline timestamps */ GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_type0_packet(REG_CP_TIMESTAMP, 1)); GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp); GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_type3_packet(PM4_EVENT_WRITE, 3)); GSL_RB_WRITE(ringcmds, rcmd_gpu, CACHE_FLUSH_TS); GSL_RB_WRITE(ringcmds, rcmd_gpu, (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp))); GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp); if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) { /* Conditional execution based on memory values */ GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_type3_packet(PM4_COND_EXEC, 4)); GSL_RB_WRITE(ringcmds, rcmd_gpu, (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable)) >> 2); GSL_RB_WRITE(ringcmds, rcmd_gpu, (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts)) >> 2); GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp); /* # of conditional command DWORDs */ GSL_RB_WRITE(ringcmds, rcmd_gpu, 2); GSL_RB_WRITE(ringcmds, rcmd_gpu, pm4_type3_packet(PM4_INTERRUPT, 1)); GSL_RB_WRITE(ringcmds, rcmd_gpu, CP_INT_CNTL__RB_INT_MASK); }
int kgsl_ringbuffer_start(struct kgsl_ringbuffer *rb, unsigned int init_ram) { int status; /*cp_rb_cntl_u cp_rb_cntl; */ union reg_cp_rb_cntl cp_rb_cntl; unsigned int *cmds, rb_cntl; struct kgsl_device *device = rb->device; uint cmds_gpu; if (rb->flags & KGSL_FLAGS_STARTED) return 0; if (init_ram) { rb->timestamp = 0; GSL_RB_INIT_TIMESTAMP(rb); } kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0, sizeof(struct kgsl_rbmemptrs)); kgsl_sharedmem_set(&rb->buffer_desc, 0, 0xAA, (rb->sizedwords << 2)); kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_BASE, (rb->memptrs_desc.gpuaddr + GSL_RB_MEMPTRS_WPTRPOLL_OFFSET)); /* setup WPTR delay */ kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_DELAY, 0 /*0x70000010 */); /*setup REG_CP_RB_CNTL */ kgsl_yamato_regread(device, REG_CP_RB_CNTL, &rb_cntl); cp_rb_cntl.val = rb_cntl; /* size of ringbuffer */ cp_rb_cntl.f.rb_bufsz = kgsl_ringbuffer_sizelog2quadwords(rb->sizedwords); /* quadwords to read before updating mem RPTR */ cp_rb_cntl.f.rb_blksz = rb->blksizequadwords; cp_rb_cntl.f.rb_poll_en = GSL_RB_CNTL_POLL_EN; /* WPTR polling */ /* mem RPTR writebacks */ cp_rb_cntl.f.rb_no_update = GSL_RB_CNTL_NO_UPDATE; kgsl_yamato_regwrite(device, REG_CP_RB_CNTL, cp_rb_cntl.val); kgsl_yamato_regwrite(device, REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); kgsl_yamato_regwrite(device, REG_CP_RB_RPTR_ADDR, rb->memptrs_desc.gpuaddr + GSL_RB_MEMPTRS_RPTR_OFFSET); /* explicitly clear all cp interrupts */ kgsl_yamato_regwrite(device, REG_CP_INT_ACK, 0xFFFFFFFF); /* setup scratch/timestamp */ kgsl_yamato_regwrite(device, REG_SCRATCH_ADDR, device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp)); kgsl_yamato_regwrite(device, REG_SCRATCH_UMSK, GSL_RB_MEMPTRS_SCRATCH_MASK); /* load the CP ucode */ status = kgsl_ringbuffer_load_pm4_ucode(device); if (status != 0) return status; /* load the prefetch parser ucode */ status = kgsl_ringbuffer_load_pfp_ucode(device); if (status != 0) return status; kgsl_yamato_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x000C0804); rb->rptr = 0; rb->wptr = 0; /* clear ME_HALT to start micro engine */ kgsl_yamato_regwrite(device, REG_CP_ME_CNTL, 0); /* ME_INIT */ cmds = kgsl_ringbuffer_allocspace(rb, 19); cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-19); GSL_RB_WRITE(cmds, cmds_gpu, PM4_HDR_ME_INIT); /* All fields present (bits 9:0) */ GSL_RB_WRITE(cmds, cmds_gpu, 0x000003ff); /* Disable/Enable Real-Time Stream processing (present but ignored) */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000); /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL)); GSL_RB_WRITE(cmds, cmds_gpu, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE)); /* Vertex and Pixel Shader Start Addresses in instructions * (3 DWORDS per instruction) */ GSL_RB_WRITE(cmds, cmds_gpu, 0x80000180); /* Maximum Contexts */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001); /* Write Confirm Interval and The CP will wait the * wait_interval * 16 clocks between polling */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000); /* NQ and External Memory Swap */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000); /* Protected mode error checking */ GSL_RB_WRITE(cmds, cmds_gpu, GSL_RB_PROTECTED_MODE_CONTROL); /* Disable header dumping and Header dump address */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000); /* Header dump size */ GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000); kgsl_ringbuffer_submit(rb); /* idle device to validate ME INIT */ status = kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, GSL_CP_INT_MASK); if (status == 0) rb->flags |= KGSL_FLAGS_STARTED; return status; }
static int kgsl_ringbuffer_start(struct kgsl_ringbuffer *rb) { int status; union reg_cp_rb_cntl cp_rb_cntl; unsigned int *cmds, rb_cntl; struct kgsl_device *device = rb->device; KGSL_CMD_VDBG("enter (rb=%p)\n", rb); if (rb->flags & KGSL_FLAGS_STARTED) { KGSL_CMD_VDBG("return %d\n", 0); return 0; } kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0, sizeof(struct kgsl_rbmemptrs)); kgsl_sharedmem_set(&rb->buffer_desc, 0, 0xAA, (rb->sizedwords << 2)); kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_BASE, (rb->memptrs_desc.gpuaddr + GSL_RB_MEMPTRS_WPTRPOLL_OFFSET)); kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_DELAY, 0 ); kgsl_yamato_regread(device, REG_CP_RB_CNTL, &rb_cntl); cp_rb_cntl.val = rb_cntl; cp_rb_cntl.f.rb_bufsz = kgsl_ringbuffer_sizelog2quadwords(rb->sizedwords); cp_rb_cntl.f.rb_blksz = rb->blksizequadwords; cp_rb_cntl.f.rb_poll_en = GSL_RB_CNTL_POLL_EN; cp_rb_cntl.f.rb_no_update = GSL_RB_CNTL_NO_UPDATE; kgsl_yamato_regwrite(device, REG_CP_RB_CNTL, cp_rb_cntl.val); kgsl_yamato_regwrite(device, REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); kgsl_yamato_regwrite(device, REG_CP_RB_RPTR_ADDR, rb->memptrs_desc.gpuaddr + GSL_RB_MEMPTRS_RPTR_OFFSET); kgsl_yamato_regwrite(device, REG_CP_INT_ACK, 0xFFFFFFFF); kgsl_yamato_regwrite(device, REG_SCRATCH_ADDR, device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp)); kgsl_yamato_regwrite(device, REG_SCRATCH_UMSK, GSL_RB_MEMPTRS_SCRATCH_MASK); status = kgsl_ringbuffer_load_pm4_ucode(device); if (status != 0) { KGSL_DRV_ERR("kgsl_ringbuffer_load_pm4_ucode failed %d\n", status); return status; } status = kgsl_ringbuffer_load_pfp_ucode(device); if (status != 0) { KGSL_DRV_ERR("kgsl_ringbuffer_load_pm4_ucode failed %d\n", status); return status; } kgsl_yamato_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x000C0804); rb->rptr = 0; rb->wptr = 0; rb->timestamp = 0; GSL_RB_INIT_TIMESTAMP(rb); INIT_LIST_HEAD(&rb->memqueue); kgsl_yamato_regwrite(device, REG_CP_ME_CNTL, 0); cmds = kgsl_ringbuffer_allocspace(rb, 19); GSL_RB_WRITE(cmds, PM4_HDR_ME_INIT); GSL_RB_WRITE(cmds, 0x000003ff); GSL_RB_WRITE(cmds, 0x00000000); GSL_RB_WRITE(cmds, 0x00000000); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL)); GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE)); GSL_RB_WRITE(cmds, 0x80000180); GSL_RB_WRITE(cmds, 0x00000001); GSL_RB_WRITE(cmds, 0x00000000); GSL_RB_WRITE(cmds, 0x00000000); GSL_RB_WRITE(cmds, GSL_RB_PROTECTED_MODE_CONTROL); GSL_RB_WRITE(cmds, 0x00000000); GSL_RB_WRITE(cmds, 0x00000000); kgsl_ringbuffer_submit(rb); status = kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); KGSL_CMD_DBG("enabling CP interrupts: mask %08lx\n", GSL_CP_INT_MASK); kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, GSL_CP_INT_MASK); if (status == 0) rb->flags |= KGSL_FLAGS_STARTED; KGSL_CMD_VDBG("return %d\n", status); return status; }
static uint32_t kgsl_ringbuffer_addcmds(struct kgsl_ringbuffer *rb, unsigned int flags, unsigned int *cmds, int sizedwords) { unsigned int *ringcmds; unsigned int timestamp; unsigned int total_sizedwords = sizedwords + 6; /* reserve space to temporarily turn off protected mode * error checking if needed */ total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0; total_sizedwords += !(flags & KGSL_CMD_FLAGS_NO_TS_CMP) ? 9 : 0; ringcmds = kgsl_ringbuffer_allocspace(rb, total_sizedwords); if (flags & KGSL_CMD_FLAGS_PMODE) { /* disable protected mode error checking */ *ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1); *ringcmds++ = 0; } memcpy(ringcmds, cmds, (sizedwords << 2)); ringcmds += sizedwords; if (flags & KGSL_CMD_FLAGS_PMODE) { /* re-enable protected mode error checking */ *ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1); *ringcmds++ = 1; } rb->timestamp++; timestamp = rb->timestamp; /* start-of-pipeline and end-of-pipeline timestamps */ *ringcmds++ = pm4_type0_packet(REG_CP_TIMESTAMP, 1); *ringcmds++ = rb->timestamp; *ringcmds++ = pm4_type3_packet(PM4_EVENT_WRITE, 3); *ringcmds++ = CACHE_FLUSH_TS; *ringcmds++ = (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)); *ringcmds++ = rb->timestamp; if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) { /* Conditional execution based on memory values */ *ringcmds++ = pm4_type3_packet(PM4_COND_EXEC, 4); *ringcmds++ = (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable)) >> 2; *ringcmds++ = (rb->device->memstore.gpuaddr + KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts)) >> 2; *ringcmds++ = rb->timestamp; /* # of conditional command DWORDs */ *ringcmds++ = 4; *ringcmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); *ringcmds++ = 0x00000000; *ringcmds++ = pm4_type3_packet(PM4_INTERRUPT, 1); *ringcmds++ = CP_INT_CNTL__RB_INT_MASK; }