| /* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| */ |
| |
| #include <linux/export.h> |
| #include <linux/delay.h> |
| #include <linux/debugfs.h> |
| #include <linux/uaccess.h> |
| #include <linux/io.h> |
| |
| #include "kgsl.h" |
| #include "adreno_postmortem.h" |
| #include "adreno.h" |
| |
| #include "a2xx_reg.h" |
| |
| unsigned int kgsl_cff_dump_enable; |
| int adreno_pm_regs_enabled; |
| int adreno_pm_ib_enabled; |
| |
| static struct dentry *pm_d_debugfs; |
| |
| static int pm_dump_set(void *data, u64 val) |
| { |
| struct kgsl_device *device = data; |
| |
| if (val) { |
| mutex_lock(&device->mutex); |
| adreno_postmortem_dump(device, 1); |
| mutex_unlock(&device->mutex); |
| } |
| |
| return 0; |
| } |
| |
| DEFINE_SIMPLE_ATTRIBUTE(pm_dump_fops, |
| NULL, |
| pm_dump_set, "%llu\n"); |
| |
| static int pm_regs_enabled_set(void *data, u64 val) |
| { |
| adreno_pm_regs_enabled = val ? 1 : 0; |
| return 0; |
| } |
| |
| static int pm_regs_enabled_get(void *data, u64 *val) |
| { |
| *val = adreno_pm_regs_enabled; |
| return 0; |
| } |
| |
| static int pm_ib_enabled_set(void *data, u64 val) |
| { |
| adreno_pm_ib_enabled = val ? 1 : 0; |
| return 0; |
| } |
| |
| static int pm_ib_enabled_get(void *data, u64 *val) |
| { |
| *val = adreno_pm_ib_enabled; |
| return 0; |
| } |
| |
| |
| DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops, |
| pm_regs_enabled_get, |
| pm_regs_enabled_set, "%llu\n"); |
| |
| DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops, |
| pm_ib_enabled_get, |
| pm_ib_enabled_set, "%llu\n"); |
| |
| |
| static int kgsl_cff_dump_enable_set(void *data, u64 val) |
| { |
| #ifdef CONFIG_MSM_KGSL_CFF_DUMP |
| kgsl_cff_dump_enable = (val != 0); |
| return 0; |
| #else |
| return -EINVAL; |
| #endif |
| } |
| |
| static int kgsl_cff_dump_enable_get(void *data, u64 *val) |
| { |
| *val = kgsl_cff_dump_enable; |
| return 0; |
| } |
| |
| DEFINE_SIMPLE_ATTRIBUTE(kgsl_cff_dump_enable_fops, kgsl_cff_dump_enable_get, |
| kgsl_cff_dump_enable_set, "%llu\n"); |
| |
| typedef void (*reg_read_init_t)(struct kgsl_device *device); |
| typedef void (*reg_read_fill_t)(struct kgsl_device *device, int i, |
| unsigned int *vals, int linec); |
| |
| void adreno_debugfs_init(struct kgsl_device *device) |
| { |
| struct adreno_device *adreno_dev = ADRENO_DEVICE(device); |
| |
| if (!device->d_debugfs || IS_ERR(device->d_debugfs)) |
| return; |
| |
| debugfs_create_file("cff_dump", 0644, device->d_debugfs, device, |
| &kgsl_cff_dump_enable_fops); |
| debugfs_create_u32("wait_timeout", 0644, device->d_debugfs, |
| &adreno_dev->wait_timeout); |
| debugfs_create_u32("ib_check", 0644, device->d_debugfs, |
| &adreno_dev->ib_check_level); |
| |
| /* By Default enable fast hang detection */ |
| adreno_dev->fast_hang_detect = 1; |
| debugfs_create_u32("fast_hang_detect", 0644, device->d_debugfs, |
| &adreno_dev->fast_hang_detect); |
| |
| /* Create post mortem control files */ |
| |
| pm_d_debugfs = debugfs_create_dir("postmortem", device->d_debugfs); |
| |
| if (IS_ERR(pm_d_debugfs)) |
| return; |
| |
| debugfs_create_file("dump", 0600, pm_d_debugfs, device, |
| &pm_dump_fops); |
| debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device, |
| &pm_regs_enabled_fops); |
| debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device, |
| &pm_ib_enabled_fops); |
| } |