Loading drivers/gpu/msm/adreno.c +8 −0 Original line number Diff line number Diff line Loading @@ -3761,6 +3761,13 @@ static void adreno_gpu_model(struct kgsl_device *device, char *str, ADRENO_CHIPID_PATCH(adreno_dev->chipid) + 1); } static bool adreno_is_hwcg_on(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag); } static const struct kgsl_functable adreno_functable = { /* Mandatory functions */ .regread = adreno_regread, Loading Loading @@ -3805,6 +3812,7 @@ static const struct kgsl_functable adreno_functable = { .dispatcher_halt = adreno_dispatcher_halt, .dispatcher_unhalt = adreno_dispatcher_unhalt, .query_property_list = adreno_query_property_list, .is_hwcg_on = adreno_is_hwcg_on, }; static struct platform_driver adreno_platform_driver = { Loading drivers/gpu/msm/kgsl_debugfs.c +48 −2 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ */ #include <linux/debugfs.h> #include <linux/io.h> #include "kgsl_debugfs.h" #include "kgsl_device.h" Loading @@ -29,11 +30,56 @@ static int _strict_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(_strict_fops, _strict_get, _strict_set, "%llu\n"); static void kgsl_qdss_gfx_register_probe(struct kgsl_device *device) { struct resource *res; res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM, "qdss_gfx"); if (res == NULL) return; device->qdss_gfx_virt = devm_ioremap(device->dev, res->start, resource_size(res)); if (device->qdss_gfx_virt == NULL) dev_warn(device->dev, "qdss_gfx ioremap failed\n"); } static int _isdb_set(void *data, u64 val) { struct kgsl_device *device = data; if (device->qdss_gfx_virt == NULL) kgsl_qdss_gfx_register_probe(device); device->set_isdb_breakpoint = val ? true : false; return 0; } static int _isdb_get(void *data, u64 *val) { struct kgsl_device *device = data; *val = device->set_isdb_breakpoint ? 1 : 0; return 0; } DEFINE_DEBUGFS_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n"); void kgsl_device_debugfs_init(struct kgsl_device *device) { if (!IS_ERR_OR_NULL(kgsl_debugfs_dir)) struct dentry *snapshot_dir; if (IS_ERR_OR_NULL(kgsl_debugfs_dir)) return; device->d_debugfs = debugfs_create_dir(device->name, kgsl_debugfs_dir); snapshot_dir = debugfs_create_dir("snapshot", kgsl_debugfs_dir); debugfs_create_file("break_isdb", 0644, snapshot_dir, device, &_isdb_fops); } void kgsl_device_debugfs_close(struct kgsl_device *device) Loading drivers/gpu/msm/kgsl_device.h +5 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,7 @@ struct kgsl_functable { */ int (*query_property_list)(struct kgsl_device *device, u32 *list, u32 count); bool (*is_hwcg_on)(struct kgsl_device *device); }; struct kgsl_ioctl { Loading Loading @@ -246,6 +247,9 @@ struct kgsl_device { /* Starting physical address for GPU shader memory */ unsigned long shader_mem_phys; /* Starting kernel virtual address for QDSS GFX DBG register block */ void __iomem *qdss_gfx_virt; /* GPU shader memory size */ unsigned int shader_mem_len; struct kgsl_memdesc memstore; Loading Loading @@ -291,6 +295,7 @@ struct kgsl_device { u32 snapshot_faultcount; /* Total number of faults since boot */ bool force_panic; /* Force panic after snapshot dump */ bool prioritize_unrecoverable; /* Overwrite with new GMU snapshots */ bool set_isdb_breakpoint; /* Set isdb registers before snapshot */ /* Use CP Crash dumper to get GPU snapshot*/ bool snapshot_crashdumper; Loading drivers/gpu/msm/kgsl_snapshot.c +43 −0 Original line number Diff line number Diff line Loading @@ -594,6 +594,47 @@ static void kgsl_free_snapshot(struct kgsl_snapshot *snapshot) dev_err(device->dev, "snapshot: objects released\n"); } #define SP0_ISDB_ISDB_BRKPT_CFG 0x40014 #define SP0_ISDB_ISDB_EN 0x40004 #define SP0_ISDB_ISDB_CMD 0x4000C static void isdb_write(void __iomem *base, u32 offset) { /* To set the SCHBREAKTYPE bit */ __raw_writel(0x800, base + SP0_ISDB_ISDB_BRKPT_CFG + offset); /* * ensure the configurations are set before * enabling ISDB */ wmb(); /* To set the ISDBCLKON and ISDB_EN bits*/ __raw_writel(0x03, base + SP0_ISDB_ISDB_EN + offset); /* * ensure previous write to enable isdb posts * before issuing the break command */ wmb(); /*To issue ISDB_0_ISDB_CMD_BREAK*/ __raw_writel(0x1, base + SP0_ISDB_ISDB_CMD + offset); } static void set_isdb_breakpoint_registers(struct kgsl_device *device) { if (!device->set_isdb_breakpoint || !device->ftbl->is_hwcg_on(device) || device->qdss_gfx_virt == NULL) return; /* Issue break command for all six SPs */ isdb_write(device->qdss_gfx_virt, 0x0000); isdb_write(device->qdss_gfx_virt, 0x1000); isdb_write(device->qdss_gfx_virt, 0x2000); isdb_write(device->qdss_gfx_virt, 0x3000); isdb_write(device->qdss_gfx_virt, 0x4000); isdb_write(device->qdss_gfx_virt, 0x5000); } /** * kgsl_snapshot() - construct a device snapshot * @device: device to snapshot Loading @@ -611,6 +652,8 @@ void kgsl_device_snapshot(struct kgsl_device *device, struct timespec boot; phys_addr_t pa; set_isdb_breakpoint_registers(device); if (device->snapshot_memory.ptr == NULL) { dev_err(device->dev, "snapshot: no snapshot memory available\n"); Loading Loading
drivers/gpu/msm/adreno.c +8 −0 Original line number Diff line number Diff line Loading @@ -3761,6 +3761,13 @@ static void adreno_gpu_model(struct kgsl_device *device, char *str, ADRENO_CHIPID_PATCH(adreno_dev->chipid) + 1); } static bool adreno_is_hwcg_on(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag); } static const struct kgsl_functable adreno_functable = { /* Mandatory functions */ .regread = adreno_regread, Loading Loading @@ -3805,6 +3812,7 @@ static const struct kgsl_functable adreno_functable = { .dispatcher_halt = adreno_dispatcher_halt, .dispatcher_unhalt = adreno_dispatcher_unhalt, .query_property_list = adreno_query_property_list, .is_hwcg_on = adreno_is_hwcg_on, }; static struct platform_driver adreno_platform_driver = { Loading
drivers/gpu/msm/kgsl_debugfs.c +48 −2 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ */ #include <linux/debugfs.h> #include <linux/io.h> #include "kgsl_debugfs.h" #include "kgsl_device.h" Loading @@ -29,11 +30,56 @@ static int _strict_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(_strict_fops, _strict_get, _strict_set, "%llu\n"); static void kgsl_qdss_gfx_register_probe(struct kgsl_device *device) { struct resource *res; res = platform_get_resource_byname(device->pdev, IORESOURCE_MEM, "qdss_gfx"); if (res == NULL) return; device->qdss_gfx_virt = devm_ioremap(device->dev, res->start, resource_size(res)); if (device->qdss_gfx_virt == NULL) dev_warn(device->dev, "qdss_gfx ioremap failed\n"); } static int _isdb_set(void *data, u64 val) { struct kgsl_device *device = data; if (device->qdss_gfx_virt == NULL) kgsl_qdss_gfx_register_probe(device); device->set_isdb_breakpoint = val ? true : false; return 0; } static int _isdb_get(void *data, u64 *val) { struct kgsl_device *device = data; *val = device->set_isdb_breakpoint ? 1 : 0; return 0; } DEFINE_DEBUGFS_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n"); void kgsl_device_debugfs_init(struct kgsl_device *device) { if (!IS_ERR_OR_NULL(kgsl_debugfs_dir)) struct dentry *snapshot_dir; if (IS_ERR_OR_NULL(kgsl_debugfs_dir)) return; device->d_debugfs = debugfs_create_dir(device->name, kgsl_debugfs_dir); snapshot_dir = debugfs_create_dir("snapshot", kgsl_debugfs_dir); debugfs_create_file("break_isdb", 0644, snapshot_dir, device, &_isdb_fops); } void kgsl_device_debugfs_close(struct kgsl_device *device) Loading
drivers/gpu/msm/kgsl_device.h +5 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,7 @@ struct kgsl_functable { */ int (*query_property_list)(struct kgsl_device *device, u32 *list, u32 count); bool (*is_hwcg_on)(struct kgsl_device *device); }; struct kgsl_ioctl { Loading Loading @@ -246,6 +247,9 @@ struct kgsl_device { /* Starting physical address for GPU shader memory */ unsigned long shader_mem_phys; /* Starting kernel virtual address for QDSS GFX DBG register block */ void __iomem *qdss_gfx_virt; /* GPU shader memory size */ unsigned int shader_mem_len; struct kgsl_memdesc memstore; Loading Loading @@ -291,6 +295,7 @@ struct kgsl_device { u32 snapshot_faultcount; /* Total number of faults since boot */ bool force_panic; /* Force panic after snapshot dump */ bool prioritize_unrecoverable; /* Overwrite with new GMU snapshots */ bool set_isdb_breakpoint; /* Set isdb registers before snapshot */ /* Use CP Crash dumper to get GPU snapshot*/ bool snapshot_crashdumper; Loading
drivers/gpu/msm/kgsl_snapshot.c +43 −0 Original line number Diff line number Diff line Loading @@ -594,6 +594,47 @@ static void kgsl_free_snapshot(struct kgsl_snapshot *snapshot) dev_err(device->dev, "snapshot: objects released\n"); } #define SP0_ISDB_ISDB_BRKPT_CFG 0x40014 #define SP0_ISDB_ISDB_EN 0x40004 #define SP0_ISDB_ISDB_CMD 0x4000C static void isdb_write(void __iomem *base, u32 offset) { /* To set the SCHBREAKTYPE bit */ __raw_writel(0x800, base + SP0_ISDB_ISDB_BRKPT_CFG + offset); /* * ensure the configurations are set before * enabling ISDB */ wmb(); /* To set the ISDBCLKON and ISDB_EN bits*/ __raw_writel(0x03, base + SP0_ISDB_ISDB_EN + offset); /* * ensure previous write to enable isdb posts * before issuing the break command */ wmb(); /*To issue ISDB_0_ISDB_CMD_BREAK*/ __raw_writel(0x1, base + SP0_ISDB_ISDB_CMD + offset); } static void set_isdb_breakpoint_registers(struct kgsl_device *device) { if (!device->set_isdb_breakpoint || !device->ftbl->is_hwcg_on(device) || device->qdss_gfx_virt == NULL) return; /* Issue break command for all six SPs */ isdb_write(device->qdss_gfx_virt, 0x0000); isdb_write(device->qdss_gfx_virt, 0x1000); isdb_write(device->qdss_gfx_virt, 0x2000); isdb_write(device->qdss_gfx_virt, 0x3000); isdb_write(device->qdss_gfx_virt, 0x4000); isdb_write(device->qdss_gfx_virt, 0x5000); } /** * kgsl_snapshot() - construct a device snapshot * @device: device to snapshot Loading @@ -611,6 +652,8 @@ void kgsl_device_snapshot(struct kgsl_device *device, struct timespec boot; phys_addr_t pa; set_isdb_breakpoint_registers(device); if (device->snapshot_memory.ptr == NULL) { dev_err(device->dev, "snapshot: no snapshot memory available\n"); Loading