From edccdc6e41a0a7cf8d6d6786bdf58c8ea17636e8 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Thu, 1 Dec 2016 21:49:33 +0530 Subject: [PATCH 1/2] msm: kgsl: Add support to disable CP Crash Dumper By default A5xx GPUs use CP crash dumper to get GPU snapshot in case of any fault. At times it is required to disable crash dumper in case of any abnormalities, add support to do so. Change-Id: Iea6497778bcd711e769f0e509103bd3bd0fd8574 Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/adreno_a5xx_snapshot.c | 3 ++- drivers/gpu/msm/kgsl_device.h | 4 +++ drivers/gpu/msm/kgsl_snapshot.c | 35 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/adreno_a5xx_snapshot.c b/drivers/gpu/msm/adreno_a5xx_snapshot.c index c09d2f8c1947..490b61738187 100644 --- a/drivers/gpu/msm/adreno_a5xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a5xx_snapshot.c @@ -834,7 +834,8 @@ void a5xx_snapshot(struct adreno_device *adreno_dev, a5xx_hwcg_set(adreno_dev, false); /* Try to run the crash dumper */ - _a5xx_do_crashdump(device); + if (device->snapshot_crashdumper) + _a5xx_do_crashdump(device); kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, a5xx_snapshot_registers, NULL); diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 04935e8d0019..7d68c23ad5b7 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -264,6 +264,10 @@ struct kgsl_device { u32 snapshot_faultcount; /* Total number of faults since boot */ bool force_panic; /* Force panic after snapshot dump */ + + /* Use CP Crash dumper to get GPU snapshot*/ + bool snapshot_crashdumper; + struct kobject snapshot_kobj; struct kobject ppd_kobj; diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index 13dc3017072d..1caa673db6ff 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -833,6 +833,32 @@ static ssize_t force_panic_store(struct kgsl_device *device, const char *buf, return (ssize_t) ret < 0 ? ret : count; } + +/* Show the snapshot_crashdumper request status */ +static ssize_t snapshot_crashdumper_show(struct kgsl_device *device, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", device->snapshot_crashdumper); +} + + +/* Store the value to snapshot_crashdumper*/ +static ssize_t snapshot_crashdumper_store(struct kgsl_device *device, + const char *buf, size_t count) +{ + unsigned int val = 0; + int ret; + + if (device && count > 0) + device->snapshot_crashdumper = 1; + + ret = kgsl_sysfs_store(buf, &val); + + if (!ret && device) + device->snapshot_crashdumper = (bool)val; + + return (ssize_t) ret < 0 ? ret : count; +} + /* Show the timestamp of the last collected snapshot */ static ssize_t timestamp_show(struct kgsl_device *device, char *buf) { @@ -859,6 +885,8 @@ struct kgsl_snapshot_attribute attr_##_name = { \ static SNAPSHOT_ATTR(timestamp, 0444, timestamp_show, NULL); static SNAPSHOT_ATTR(faultcount, 0644, faultcount_show, faultcount_store); static SNAPSHOT_ATTR(force_panic, 0644, force_panic_show, force_panic_store); +static SNAPSHOT_ATTR(snapshot_crashdumper, 0644, snapshot_crashdumper_show, + snapshot_crashdumper_store); static ssize_t snapshot_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -939,6 +967,7 @@ int kgsl_device_snapshot_init(struct kgsl_device *device) device->snapshot = NULL; device->snapshot_faultcount = 0; device->force_panic = 0; + device->snapshot_crashdumper = 1; ret = kobject_init_and_add(&device->snapshot_kobj, &ktype_snapshot, &device->dev->kobj, "snapshot"); @@ -959,6 +988,11 @@ int kgsl_device_snapshot_init(struct kgsl_device *device) ret = sysfs_create_file(&device->snapshot_kobj, &attr_force_panic.attr); + if (ret) + goto done; + + ret = sysfs_create_file(&device->snapshot_kobj, + &attr_snapshot_crashdumper.attr); done: return ret; } @@ -984,6 +1018,7 @@ void kgsl_device_snapshot_close(struct kgsl_device *device) device->snapshot_memory.size = 0; device->snapshot_faultcount = 0; device->force_panic = 0; + device->snapshot_crashdumper = 1; } EXPORT_SYMBOL(kgsl_device_snapshot_close); From 58b88b8933e5a565f660257b8a96303960281851 Mon Sep 17 00:00:00 2001 From: Rajesh Kemisetti Date: Thu, 1 Dec 2016 23:41:56 +0530 Subject: [PATCH 2/2] msm: kgsl: Dump VBIF and few GPU registers before crash dumper Triggering Crash Dumper might actually change the values of few GPU registers including VBIF. Hence dump those registers ahead and skip them from the list which goes to crash dumper. Change-Id: I37a53983a65bd8abfefa780053819de71df7f24f Signed-off-by: Rajesh Kemisetti --- drivers/gpu/msm/adreno_a5xx_snapshot.c | 44 ++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/msm/adreno_a5xx_snapshot.c b/drivers/gpu/msm/adreno_a5xx_snapshot.c index 490b61738187..bd93ded07131 100644 --- a/drivers/gpu/msm/adreno_a5xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a5xx_snapshot.c @@ -358,10 +358,12 @@ static const unsigned int a5xx_registers[] = { 0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B, 0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095, 0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3, - 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807, + 0x04E0, 0x04F4, 0X04F6, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, + 0xF800, 0xF807, /* CP */ 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0, - 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD, + 0x0B00, 0x0B12, 0x0B15, 0X0B1C, 0X0B1E, 0x0B28, 0x0B78, 0x0B7F, + 0x0BB0, 0x0BBD, /* VSC */ 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, /* GRAS */ @@ -412,6 +414,19 @@ static const unsigned int a5xx_registers[] = { 0xA800, 0xA8FF, 0xAC60, 0xAC60, }; +/* + * Set of registers to dump for A5XX before actually triggering crash dumper. + * Registers in pairs - first value is the start offset, second + * is the stop offset (inclusive) + */ +static const unsigned int a5xx_pre_crashdumper_registers[] = { + /* RBBM: RBBM_STATUS */ + 0x04F5, 0x04F5, + /* CP: CP_STATUS_1 */ + 0x0B1D, 0x0B1D, +}; + + struct a5xx_hlsq_sp_tp_regs { unsigned int statetype; unsigned int ahbaddr; @@ -634,6 +649,18 @@ static void a5xx_snapshot_shader(struct kgsl_device *device, } } +/* Dump registers which get affected by crash dumper trigger */ +static size_t a5xx_snapshot_pre_crashdump_regs(struct kgsl_device *device, + u8 *buf, size_t remain, void *priv) +{ + struct kgsl_snapshot_registers pre_cdregs = { + .regs = a5xx_pre_crashdumper_registers, + .count = ARRAY_SIZE(a5xx_pre_crashdumper_registers)/2, + }; + + return kgsl_snapshot_dump_registers(device, buf, remain, &pre_cdregs); +} + static size_t a5xx_legacy_snapshot_registers(struct kgsl_device *device, u8 *buf, size_t remain) { @@ -833,6 +860,15 @@ void a5xx_snapshot(struct adreno_device *adreno_dev, /* Disable Clock gating temporarily for the debug bus to work */ a5xx_hwcg_set(adreno_dev, false); + /* Dump the registers which get affected by crash dumper trigger */ + kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, + snapshot, a5xx_snapshot_pre_crashdump_regs, NULL); + + /* Dump vbif registers as well which get affected by crash dumper */ + adreno_snapshot_vbif_registers(device, snapshot, + a5xx_vbif_snapshot_registers, + ARRAY_SIZE(a5xx_vbif_snapshot_registers)); + /* Try to run the crash dumper */ if (device->snapshot_crashdumper) _a5xx_do_crashdump(device); @@ -840,10 +876,6 @@ void a5xx_snapshot(struct adreno_device *adreno_dev, kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, a5xx_snapshot_registers, NULL); - adreno_snapshot_vbif_registers(device, snapshot, - a5xx_vbif_snapshot_registers, - ARRAY_SIZE(a5xx_vbif_snapshot_registers)); - /* Dump SP TP HLSQ registers */ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, a5xx_snapshot_dump_hlsq_sp_tp_regs, NULL);