android_kernel_cmhtcleo/drivers/video/msm/gpu/kgsl/kgsl_log.c
2010-08-27 11:19:57 +02:00

293 lines
7.2 KiB
C

/*
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2008
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
*
* All source code in this file is licensed under the following license
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can find it at http://www.fsf.org
*/
#include <linux/debugfs.h>
#include "kgsl_log.h"
#include "kgsl_ringbuffer.h"
#include "kgsl_device.h"
#include "kgsl.h"
/*default log levels is error for everything*/
#define KGSL_LOG_LEVEL_DEFAULT 3
#define KGSL_LOG_LEVEL_MAX 7
unsigned int kgsl_drv_log = KGSL_LOG_LEVEL_DEFAULT;
unsigned int kgsl_cmd_log = KGSL_LOG_LEVEL_DEFAULT;
unsigned int kgsl_ctxt_log = KGSL_LOG_LEVEL_DEFAULT;
unsigned int kgsl_mem_log = KGSL_LOG_LEVEL_DEFAULT;
unsigned int kgsl_cache_enable;
#ifdef CONFIG_DEBUG_FS
static int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
{
*log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX);
return 0;
}
static int kgsl_drv_log_set(void *data, u64 val)
{
return kgsl_log_set(&kgsl_drv_log, data, val);
}
static int kgsl_drv_log_get(void *data, u64 *val)
{
*val = kgsl_drv_log;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(kgsl_drv_log_fops, kgsl_drv_log_get,
kgsl_drv_log_set, "%llu\n");
static int kgsl_cmd_log_set(void *data, u64 val)
{
return kgsl_log_set(&kgsl_cmd_log, data, val);
}
static int kgsl_cmd_log_get(void *data, u64 *val)
{
*val = kgsl_cmd_log;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(kgsl_cmd_log_fops, kgsl_cmd_log_get,
kgsl_cmd_log_set, "%llu\n");
static int kgsl_ctxt_log_set(void *data, u64 val)
{
return kgsl_log_set(&kgsl_ctxt_log, data, val);
}
static int kgsl_ctxt_log_get(void *data, u64 *val)
{
*val = kgsl_ctxt_log;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(kgsl_ctxt_log_fops, kgsl_ctxt_log_get,
kgsl_ctxt_log_set, "%llu\n");
static int kgsl_mem_log_set(void *data, u64 val)
{
return kgsl_log_set(&kgsl_mem_log, data, val);
}
static int kgsl_mem_log_get(void *data, u64 *val)
{
*val = kgsl_mem_log;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(kgsl_mem_log_fops, kgsl_mem_log_get,
kgsl_mem_log_set, "%llu\n");
#ifdef DEBUG
static ssize_t rb_regs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static ssize_t rb_regs_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
const int debug_bufmax = 4096;
static char buffer[4096];
int n = 0;
struct kgsl_device *device = NULL;
struct kgsl_ringbuffer *rb = NULL;
struct kgsl_rb_debug rb_debug;
device = &kgsl_driver.yamato_device;
rb = &device->ringbuffer;
kgsl_ringbuffer_debug(rb, &rb_debug);
n += scnprintf(buffer + n, debug_bufmax - n,
"rbbm_status %08x mem_rptr %08x mem_wptr_poll %08x\n",
rb_debug.rbbm_status,
rb_debug.mem_rptr,
rb_debug.mem_wptr_poll);
n += scnprintf(buffer + n, debug_bufmax - n,
"rb_base %08x rb_cntl %08x rb_rptr_addr %08x"
" rb_rptr %08x rb_rptr_wr %08x\n",
rb_debug.cp_rb_base,
rb_debug.cp_rb_cntl,
rb_debug.cp_rb_rptr_addr,
rb_debug.cp_rb_rptr,
rb_debug.cp_rb_rptr_wr);
n += scnprintf(buffer + n, debug_bufmax - n,
"rb_wptr %08x rb_wptr_delay %08x rb_wptr_base %08x"
" ib1_base %08x ib1_bufsz %08x\n",
rb_debug.cp_rb_wptr,
rb_debug.cp_rb_wptr_delay,
rb_debug.cp_rb_wptr_base,
rb_debug.cp_ib1_base,
rb_debug.cp_ib1_bufsz);
n += scnprintf(buffer + n, debug_bufmax - n,
"ib2_base %08x ib2_bufsz %08x st_base %08x"
" st_bufsz %08x cp_me_cntl %08x cp_me_status %08x\n",
rb_debug.cp_ib2_base,
rb_debug.cp_ib2_bufsz,
rb_debug.cp_st_base,
rb_debug.cp_st_bufsz,
rb_debug.cp_me_cntl,
rb_debug.cp_me_status);
n += scnprintf(buffer + n, debug_bufmax - n,
"csq_cp_rb %08x csq_cp_ib1 %08x csq_cp_ib2 %08x\n",
rb_debug.cp_csq_rb_stat,
rb_debug.cp_csq_ib1_stat,
rb_debug.cp_csq_ib2_stat);
n += scnprintf(buffer + n, debug_bufmax - n,
"cp_debug %08x cp_stat %08x cp_int_status %08x"
" cp_int_cntl %08x\n",
rb_debug.cp_debug,
rb_debug.cp_stat,
rb_debug.cp_int_status,
rb_debug.cp_int_cntl);
n += scnprintf(buffer + n, debug_bufmax - n,
"sop_timestamp: %0d eop_timestamp: %d\n",
rb_debug.sop_timestamp,
rb_debug.eop_timestamp);
n++;
buffer[n] = 0;
return simple_read_from_buffer(buf, count, ppos, buffer, n);
}
static struct file_operations kgsl_rb_regs_fops = {
.read = rb_regs_read,
.open = rb_regs_open,
};
#endif /*DEBUG*/
#ifdef DEBUG
static ssize_t mmu_regs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static ssize_t mmu_regs_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
const int debug_bufmax = 4096;
static char buffer[4096];
int n = 0;
struct kgsl_device *device = NULL;
struct kgsl_mmu *mmu = NULL;
struct kgsl_mmu_debug mmu_debug;
device = &kgsl_driver.yamato_device;
mmu = &device->mmu;
kgsl_mmu_debug(mmu, &mmu_debug);
n += scnprintf(buffer + n, debug_bufmax - n,
"config %08x mpu_base %08x mpu_end %08x\n",
mmu_debug.config,
mmu_debug.mpu_base,
mmu_debug.mpu_end);
n += scnprintf(buffer + n, debug_bufmax - n,
"va_range %08x pt_base %08x\n",
mmu_debug.va_range,
mmu_debug.pt_base);
n += scnprintf(buffer + n, debug_bufmax - n,
"page_fault %08x trans_error %08x axi_error %08x\n",
mmu_debug.page_fault,
mmu_debug.trans_error,
mmu_debug.axi_error);
n += scnprintf(buffer + n, debug_bufmax - n,
"interrupt_mask %08x interrupt_status %08x\n",
mmu_debug.interrupt_mask,
mmu_debug.interrupt_status);
n++;
buffer[n] = 0;
return simple_read_from_buffer(buf, count, ppos, buffer, n);
}
static struct file_operations kgsl_mmu_regs_fops = {
.read = mmu_regs_read,
.open = mmu_regs_open,
};
#endif /*DEBUG*/
#ifdef CONFIG_MSM_KGSL_MMU
static int kgsl_cache_enable_set(void *data, u64 val)
{
kgsl_cache_enable = (val != 0);
return 0;
}
static int kgsl_cache_enable_get(void *data, u64 *val)
{
*val = kgsl_cache_enable;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(kgsl_cache_enable_fops, kgsl_cache_enable_get,
kgsl_cache_enable_set, "%llu\n");
#endif
#endif /* CONFIG_DEBUG_FS */
int kgsl_debug_init(void)
{
#ifdef CONFIG_DEBUG_FS
struct dentry *dent;
dent = debugfs_create_dir("kgsl", 0);
if (IS_ERR(dent))
return 0;
debugfs_create_file("log_level_cmd", 0644, dent, 0,
&kgsl_cmd_log_fops);
debugfs_create_file("log_level_ctxt", 0644, dent, 0,
&kgsl_ctxt_log_fops);
debugfs_create_file("log_level_drv", 0644, dent, 0,
&kgsl_drv_log_fops);
debugfs_create_file("log_level_mem", 0644, dent, 0,
&kgsl_mem_log_fops);
#ifdef DEBUG
debugfs_create_file("rb_regs", 0444, dent, 0,
&kgsl_rb_regs_fops);
#endif
#ifdef DEBUG
debugfs_create_file("mmu_regs", 0444, dent, 0,
&kgsl_mmu_regs_fops);
#endif
#ifdef CONFIG_MSM_KGSL_MMU
debugfs_create_file("cache_enable", 0644, dent, 0,
&kgsl_cache_enable_fops);
#endif
#endif /* CONFIG_DEBUG_FS */
return 0;
}