Loading drivers/gpu/msm/adreno_a6xx_snapshot.c +39 −13 Original line number Original line 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_capturescript; static struct kgsl_memdesc *a6xx_crashdump_registers; static struct kgsl_memdesc *a6xx_crashdump_registers; static bool crash_dump_valid; static bool crash_dump_valid; static u32 *a6xx_cd_reg_end; static struct reg_list { static struct reg_list { const unsigned int *regs; 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) static void _a6xx_do_crashdump(struct kgsl_device *device) { { u32 val = 0; u32 val = 0; int ret; ktime_t timeout; crash_dump_valid = false; crash_dump_valid = false; Loading @@ -1580,9 +1581,6 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) if (a6xx_is_smmu_stalled(device)) if (a6xx_is_smmu_stalled(device)) return; return; memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); /* Turn on APRIV for legacy targets so we can access the buffers */ /* Turn on APRIV for legacy targets so we can access the buffers */ if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1); 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)); upper_32_bits(a6xx_capturescript->gpuaddr)); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); /* wait 100 ms before starting the loop */ timeout = ktime_add_ms(ktime_get(), CP_CRASH_DUMPER_TIMEOUT); schedule_timeout_interruptible(HZ/10); 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); kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &val); if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0); 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); dev_err(device->dev, "Crash dump timed out: 0x%X\n", val); return; return; } } Loading Loading @@ -1901,6 +1908,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev, /* registers dumped through DBG AHB */ /* registers dumped through DBG AHB */ a6xx_snapshot_dbgahb_regs(device, snapshot); 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)) { if (adreno_is_a660(adreno_dev)) { Loading Loading @@ -2209,6 +2220,11 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) sizeof(unsigned int); 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 */ /* Now allocate the script and data buffers */ /* The script buffers needs 2 extra qwords on the end */ /* 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); 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; *ptr++ = 0; *ptr++ = 0; } } Loading
drivers/gpu/msm/adreno_a6xx_snapshot.c +39 −13 Original line number Original line 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_capturescript; static struct kgsl_memdesc *a6xx_crashdump_registers; static struct kgsl_memdesc *a6xx_crashdump_registers; static bool crash_dump_valid; static bool crash_dump_valid; static u32 *a6xx_cd_reg_end; static struct reg_list { static struct reg_list { const unsigned int *regs; 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) static void _a6xx_do_crashdump(struct kgsl_device *device) { { u32 val = 0; u32 val = 0; int ret; ktime_t timeout; crash_dump_valid = false; crash_dump_valid = false; Loading @@ -1580,9 +1581,6 @@ static void _a6xx_do_crashdump(struct kgsl_device *device) if (a6xx_is_smmu_stalled(device)) if (a6xx_is_smmu_stalled(device)) return; return; memset(a6xx_crashdump_registers->hostptr, 0xaa, a6xx_crashdump_registers->size); /* Turn on APRIV for legacy targets so we can access the buffers */ /* Turn on APRIV for legacy targets so we can access the buffers */ if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1); 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)); upper_32_bits(a6xx_capturescript->gpuaddr)); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1); /* wait 100 ms before starting the loop */ timeout = ktime_add_ms(ktime_get(), CP_CRASH_DUMPER_TIMEOUT); schedule_timeout_interruptible(HZ/10); 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); kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &val); if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) if (!ADRENO_FEATURE(ADRENO_DEVICE(device), ADRENO_APRIV)) kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0); 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); dev_err(device->dev, "Crash dump timed out: 0x%X\n", val); return; return; } } Loading Loading @@ -1901,6 +1908,10 @@ void a6xx_snapshot(struct adreno_device *adreno_dev, /* registers dumped through DBG AHB */ /* registers dumped through DBG AHB */ a6xx_snapshot_dbgahb_regs(device, snapshot); 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)) { if (adreno_is_a660(adreno_dev)) { Loading Loading @@ -2209,6 +2220,11 @@ void a6xx_crashdump_init(struct adreno_device *adreno_dev) sizeof(unsigned int); 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 */ /* Now allocate the script and data buffers */ /* The script buffers needs 2 extra qwords on the end */ /* 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); 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; *ptr++ = 0; *ptr++ = 0; } }