static int a3xx_snapshot_cp_roq(struct kgsl_device *device, void *snapshot, int remain, void *priv) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); struct kgsl_snapshot_debug *header = snapshot; unsigned int *data = snapshot + sizeof(*header); int i, size; size = adreno_is_a330(adreno_dev) ? A330_CP_ROQ_SIZE : A320_CP_ROQ_SIZE; if (remain < DEBUG_SECTION_SZ(size)) { SNAPSHOT_ERR_NOMEM(device, "CP ROQ DEBUG"); return 0; } header->type = SNAPSHOT_DEBUG_CP_ROQ; header->size = size; adreno_regwrite(device, A3XX_CP_ROQ_ADDR, 0x0); for (i = 0; i < size; i++) adreno_regread(device, A3XX_CP_ROQ_DATA, &data[i]); return DEBUG_SECTION_SZ(size); }
static void _snapshot_hlsq_regs(struct kgsl_snapshot_registers *regs, struct kgsl_snapshot_registers_list *list, struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; if (adreno_is_a330(adreno_dev)) { unsigned int stall_context_full = 0; _rbbm_debug_bus_read(device, RBBM_BLOCK_ID_HLSQ, 49, &stall_context_full); stall_context_full &= 0x08000000; if (stall_context_full) return; } else { unsigned int next_pif = 0; _rbbm_debug_bus_read(device, RBBM_BLOCK_ID_HLSQ, 4, &next_pif); next_pif &= 0x1f; if (next_pif != 0 && next_pif != 1 && next_pif != 28) return; _rbbm_debug_bus_read(device, RBBM_BLOCK_ID_HLSQ, 7, &next_pif); next_pif &= 0x3f; if (next_pif != 0 && next_pif != 1 && next_pif != 10) return; } regs[list->count].regs = (unsigned int *) a3xx_hlsq_registers; regs[list->count].count = a3xx_hlsq_registers_count; list->count++; }
static int a3xx_hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu); uint32_t *ptr, len; int i, ret; DBG("%s", gpu->name); if (adreno_is_a305(adreno_gpu)) { /* Set up 16 deep read/write request queues: */ gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010); /* Enable WR-REQ: */ gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff); /* Set up round robin arbitration between both AXI ports: */ gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030); /* Set up AOOO: */ gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c); gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c); } else if (adreno_is_a320(adreno_gpu)) { /* Set up 16 deep read/write request queues: */ gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010); gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010); /* Enable WR-REQ: */ gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff); /* Set up round robin arbitration between both AXI ports: */ gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030); /* Set up AOOO: */ gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c); gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c); /* Enable 1K sort: */ gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x000000ff); gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4); } else if (adreno_is_a330v2(adreno_gpu)) { /* * Most of the VBIF registers on 8974v2 have the correct * values at power on, so we won't modify those if we don't * need to */ /* Enable 1k sort: */ gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001003f); gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4); /* Enable WR-REQ: */ gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f); gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); /* Set up VBIF_ROUND_ROBIN_QOS_ARB: */ gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003); } else if (adreno_is_a330(adreno_gpu)) { /* Set up 16 deep read/write request queues: */ gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x18181818); gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x18181818); gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x18181818); gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x18181818); gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303); gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x18181818); gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x18181818); /* Enable WR-REQ: */ gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f); /* Set up round robin arbitration between both AXI ports: */ gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030); /* Set up VBIF_ROUND_ROBIN_QOS_ARB: */ gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0001); /* Set up AOOO: */ gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003f); gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003f003f); /* Enable 1K sort: */ gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001003f); gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4); /* Disable VBIF clock gating. This is to enable AXI running * higher frequency than GPU: */ gpu_write(gpu, REG_A3XX_VBIF_CLKON, 0x00000001); } else { BUG(); } /* Make all blocks contribute to the GPU BUSY perf counter: */ gpu_write(gpu, REG_A3XX_RBBM_GPU_BUSY_MASKED, 0xffffffff); /* Tune the hystersis counters for SP and CP idle detection: */ gpu_write(gpu, REG_A3XX_RBBM_SP_HYST_CNT, 0x10); gpu_write(gpu, REG_A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10); /* Enable the RBBM error reporting bits. This lets us get * useful information on failure: */ gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL0, 0x00000001); /* Enable AHB error reporting: */ gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL1, 0xa6ffffff); /* Turn on the power counters: */ gpu_write(gpu, REG_A3XX_RBBM_RBBM_CTL, 0x00030000); /* Turn on hang detection - this spews a lot of useful information * into the RBBM registers on a hang: */ gpu_write(gpu, REG_A3XX_RBBM_INTERFACE_HANG_INT_CTL, 0x00010fff); /* Enable 64-byte cacheline size. HW Default is 32-byte (0x000000E0): */ gpu_write(gpu, REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG, 0x00000001); /* Enable Clock gating: */ if (adreno_is_a320(adreno_gpu)) gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbfffffff); else if (adreno_is_a330v2(adreno_gpu)) gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xaaaaaaaa); else if (adreno_is_a330(adreno_gpu)) gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbffcffff); if (adreno_is_a330v2(adreno_gpu)) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x05515455); else if (adreno_is_a330(adreno_gpu)) gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x00000000); /* Set the OCMEM base address for A330, etc */ if (a3xx_gpu->ocmem_hdl) { gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR, (unsigned int)(a3xx_gpu->ocmem_base >> 14)); }
void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot, int *remain, int hang) { struct kgsl_device *device = &adreno_dev->dev; struct kgsl_snapshot_registers_list list; struct kgsl_snapshot_registers regs[5]; list.registers = regs; list.count = 0; adreno_regwrite(device, A3XX_RBBM_CLOCK_CTL, 0x00); _snapshot_a3xx_regs(regs, &list); _snapshot_hlsq_regs(regs, &list, adreno_dev); if (adreno_is_a330(adreno_dev)) _snapshot_a330_regs(regs, &list); snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, remain, kgsl_snapshot_dump_regs, &list); snapshot = kgsl_snapshot_indexed_registers(device, snapshot, remain, REG_CP_STATE_DEBUG_INDEX, REG_CP_STATE_DEBUG_DATA, 0x0, 0x14); snapshot = kgsl_snapshot_indexed_registers(device, snapshot, remain, REG_CP_ME_CNTL, REG_CP_ME_STATUS, 64, 44); snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_vpc_memory, NULL); snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_meq, NULL); snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_shader_memory, NULL); if (hang) { snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_pfp_ram, NULL); snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_pm4_ram, NULL); } snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_roq, NULL); if (adreno_is_a330(adreno_dev)) { snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a330_snapshot_cp_merciu, NULL); } snapshot = a3xx_snapshot_debugbus(device, snapshot, remain); adreno_regwrite(device, A3XX_RBBM_CLOCK_CTL, A3XX_RBBM_CLOCK_CTL_DEFAULT); return snapshot; }
void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot, int *remain, int hang) { struct kgsl_device *device = &adreno_dev->dev; struct kgsl_snapshot_registers_list list; struct kgsl_snapshot_registers regs[2]; regs[0].regs = (unsigned int *) a3xx_registers; regs[0].count = a3xx_registers_count; list.registers = regs; list.count = 1; /* For A330, append the additional list of new registers to grab */ if (adreno_is_a330(adreno_dev)) { regs[1].regs = (unsigned int *) a330_registers; regs[1].count = a330_registers_count; list.count++; } /* Master set of (non debug) registers */ snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, remain, kgsl_snapshot_dump_regs, &list); /* CP_STATE_DEBUG indexed registers */ snapshot = kgsl_snapshot_indexed_registers(device, snapshot, remain, REG_CP_STATE_DEBUG_INDEX, REG_CP_STATE_DEBUG_DATA, 0x0, 0x14); /* CP_ME indexed registers */ snapshot = kgsl_snapshot_indexed_registers(device, snapshot, remain, REG_CP_ME_CNTL, REG_CP_ME_STATUS, 64, 44); /* Disable Clock gating temporarily for the debug bus to work */ adreno_regwrite(device, A3XX_RBBM_CLOCK_CTL, 0x00); /* VPC memory */ snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_vpc_memory, NULL); /* CP MEQ */ snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_meq, NULL); /* Shader working/shadow memory */ snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_shader_memory, NULL); /* CP PFP and PM4 */ /* Reading these will hang the GPU if it isn't already hung */ if (hang) { snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_pfp_ram, NULL); snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_pm4_ram, NULL); } /* CP ROQ */ snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a3xx_snapshot_cp_roq, NULL); if (adreno_is_a330(adreno_dev)) { snapshot = kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain, a330_snapshot_cp_merciu, NULL); } snapshot = a3xx_snapshot_debugbus(device, snapshot, remain); /* Enable Clock gating */ adreno_regwrite(device, A3XX_RBBM_CLOCK_CTL, A3XX_RBBM_CLOCK_CTL_DEFAULT); return snapshot; }