Loading drivers/gpu/msm/adreno_a6xx_snapshot.c +39 −13 Original line number Diff line number Diff line Loading @@ -574,6 +574,7 @@ static struct a6xx_shader_block a6xx_shader_blocks[] = { static struct kgsl_memdesc *a6xx_capturescript; static struct kgsl_memdesc *a6xx_crashdump_registers; static bool crash_dump_valid; static u32 *a6xx_cd_reg_end; static struct reg_list { const unsigned int *regs; Loading Loading @@ -1565,7 +1566,7 @@ static size_t a6xx_snapshot_sqe(struct kgsl_device *device, u8 *buf, static void _a6xx_do_crashdump(struct kgsl_device *device) { u32 val = 0; int ret; ktime_t timeout; crash_dump_valid = false; Loading @@ -1580,9 +1581,6 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) if (a6xx_is_smmu_stalled(device)) return; memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); /* Turn on APRIV for legacy targets so we can access the buffers */ if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1); Loading @@ -1593,20 +1591,29 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) upper_32_bits(a6xx_capturescript->gpuaddr)); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); /* wait 100 ms before starting the loop */ schedule_timeout_interruptible(HZ/10); timeout = ktime_add_ms(ktime_get(), CP_CRASH_DUMPER_TIMEOUT); might_sleep(); for (;;) { /* make sure we're reading the latest value */ rmb(); if ((*a6xx_cd_reg_end) != 0xaaaaaaaa) break; if (ktime_compare(ktime_get(), timeout) > 0) break; /* Wait 1msec to avoid unnecessary looping */ usleep_range(100, 1000); } /* Read every 10ms for 900ms */ ret = readl_poll_timeout(device->reg_virt + (A6XX_CP_CRASH_DUMP_STATUS << 2), val, val & 0x02, 10000, 900 * 1000); if (ret) kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &val); if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0); if (ret) { if (!(val & 0x2)) { dev_err(device->dev, "Crash dump timed out: 0x%X\n", val); return; } Loading Loading @@ -1901,6 +1908,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev, /* registers dumped through DBG AHB */ a6xx_snapshot_dbgahb_regs(device, snapshot); if (!a6xx_is_smmu_stalled(device)) memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); } if (adreno_is_a660(adreno_dev)) { Loading Loading @@ -2209,6 +2220,11 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) sizeof(unsigned int); } /* 16 bytes (2 qwords) for last entry in CD script */ script_size += 16; /* Increment data size to store last entry in CD */ data_size += sizeof(unsigned int); /* Now allocate the script and data buffers */ /* The script buffers needs 2 extra qwords on the end */ Loading Loading @@ -2271,6 +2287,16 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) ptr += _a6xx_crashdump_init_non_ctx_dbgahb(ptr, &offset); /* Save CD register end pointer to check CD status completion */ a6xx_cd_reg_end = a6xx_crashdump_registers->hostptr + offset; memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); /* Program the capturescript to read the last register entry */ *ptr++ = a6xx_crashdump_registers->gpuaddr + offset; *ptr++ = (((uint64_t) A6XX_CP_CRASH_DUMP_STATUS) << 44) | (uint64_t) 1; *ptr++ = 0; *ptr++ = 0; } Loading
drivers/gpu/msm/adreno_a6xx_snapshot.c +39 −13 Original line number Diff line number Diff line Loading @@ -574,6 +574,7 @@ static struct a6xx_shader_block a6xx_shader_blocks[] = { static struct kgsl_memdesc *a6xx_capturescript; static struct kgsl_memdesc *a6xx_crashdump_registers; static bool crash_dump_valid; static u32 *a6xx_cd_reg_end; static struct reg_list { const unsigned int *regs; Loading Loading @@ -1565,7 +1566,7 @@ static size_t a6xx_snapshot_sqe(struct kgsl_device *device, u8 *buf, static void _a6xx_do_crashdump(struct kgsl_device *device) { u32 val = 0; int ret; ktime_t timeout; crash_dump_valid = false; Loading @@ -1580,9 +1581,6 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) if (a6xx_is_smmu_stalled(device)) return; memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); /* Turn on APRIV for legacy targets so we can access the buffers */ if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1); Loading @@ -1593,20 +1591,29 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) upper_32_bits(a6xx_capturescript->gpuaddr)); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); /* wait 100 ms before starting the loop */ schedule_timeout_interruptible(HZ/10); timeout = ktime_add_ms(ktime_get(), CP_CRASH_DUMPER_TIMEOUT); might_sleep(); for (;;) { /* make sure we're reading the latest value */ rmb(); if ((*a6xx_cd_reg_end) != 0xaaaaaaaa) break; if (ktime_compare(ktime_get(), timeout) > 0) break; /* Wait 1msec to avoid unnecessary looping */ usleep_range(100, 1000); } /* Read every 10ms for 900ms */ ret = readl_poll_timeout(device->reg_virt + (A6XX_CP_CRASH_DUMP_STATUS << 2), val, val & 0x02, 10000, 900 * 1000); if (ret) kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &val); if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0); if (ret) { if (!(val & 0x2)) { dev_err(device->dev, "Crash dump timed out: 0x%X\n", val); return; } Loading Loading @@ -1901,6 +1908,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev, /* registers dumped through DBG AHB */ a6xx_snapshot_dbgahb_regs(device, snapshot); if (!a6xx_is_smmu_stalled(device)) memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); } if (adreno_is_a660(adreno_dev)) { Loading Loading @@ -2209,6 +2220,11 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) sizeof(unsigned int); } /* 16 bytes (2 qwords) for last entry in CD script */ script_size += 16; /* Increment data size to store last entry in CD */ data_size += sizeof(unsigned int); /* Now allocate the script and data buffers */ /* The script buffers needs 2 extra qwords on the end */ Loading Loading @@ -2271,6 +2287,16 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) ptr += _a6xx_crashdump_init_non_ctx_dbgahb(ptr, &offset); /* Save CD register end pointer to check CD status completion */ a6xx_cd_reg_end = a6xx_crashdump_registers->hostptr + offset; memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); /* Program the capturescript to read the last register entry */ *ptr++ = a6xx_crashdump_registers->gpuaddr + offset; *ptr++ = (((uint64_t) A6XX_CP_CRASH_DUMP_STATUS) << 44) | (uint64_t) 1; *ptr++ = 0; *ptr++ = 0; }