X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=drivers%2Fdsp%2Fdspgateway%2Fmblog.c;fp=drivers%2Fdsp%2Fdspgateway%2Fmblog.c;h=7e008afb6c90f1c32990457528538eafabe77699;hb=a78d411c6518eb7dd038eef6668f78a7e6c14ec4;hp=0000000000000000000000000000000000000000;hpb=4a6908a3a050aacc9c3a2f36b276b46c0629ad91;p=h-e-n diff --git a/drivers/dsp/dspgateway/mblog.c b/drivers/dsp/dspgateway/mblog.c new file mode 100644 index 0000000..7e008af --- /dev/null +++ b/drivers/dsp/dspgateway/mblog.c @@ -0,0 +1,280 @@ +/* + * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1) + * + * Copyright (C) 2003-2006 Nokia Corporation. All rights reserved. + * + * Contact: Toshihiro Kobayashi + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include "dsp_mbcmd.h" +#include "dsp.h" + +char *subcmd_name(struct mbcmd *mb) +{ + u8 cmd_h = mb->cmd_h; + u8 cmd_l = mb->cmd_l; + char *s; + + switch (cmd_h) { + case MBOX_CMD_DSP_RUNLEVEL: + s = (cmd_l == RUNLEVEL_USER) ? "USER": + (cmd_l == RUNLEVEL_SUPER) ? "SUPER": + (cmd_l == RUNLEVEL_RECOVERY) ? "RECOVERY": + NULL; + break; + case MBOX_CMD_DSP_PM: + s = (cmd_l == PM_DISABLE) ? "DISABLE": + (cmd_l == PM_ENABLE) ? "ENABLE": + NULL; + break; + case MBOX_CMD_DSP_KFUNC: + s = (cmd_l == KFUNC_FBCTL) ? "FBCTL": + (cmd_l == KFUNC_POWER) ? + ((mb->data == AUDIO_PWR_UP) ? "PWR AUD /UP": + (mb->data == AUDIO_PWR_DOWN) ? "PWR AUD /DOWN": + (mb->data == AUDIO_PWR_DOWN2) ? "PWR AUD /DOWN(2)": + (mb->data == DSP_PWR_UP) ? "PWR DSP /UP": + (mb->data == DSP_PWR_DOWN) ? "PWR DSP /DOWN": + (mb->data == DVFS_START) ? "PWR DVFS/START": + (mb->data == DVFS_STOP) ? "PWR DVFS/STOP": + NULL): + + NULL; + break; + case MBOX_CMD_DSP_DSPCFG: + { + u8 cfgc = cmd_l & 0x7f; + s = (cfgc == DSPCFG_REQ) ? "REQ": + (cfgc == DSPCFG_SYSADRH) ? "SYSADRH": + (cfgc == DSPCFG_SYSADRL) ? "SYSADRL": + (cfgc == DSPCFG_ABORT) ? "ABORT": + (cfgc == DSPCFG_PROTREV) ? "PROTREV": + NULL; + break; + } + case MBOX_CMD_DSP_REGRW: + s = (cmd_l == REGRW_MEMR) ? "MEMR": + (cmd_l == REGRW_MEMW) ? "MEMW": + (cmd_l == REGRW_IOR) ? "IOR": + (cmd_l == REGRW_IOW) ? "IOW": + (cmd_l == REGRW_DATA) ? "DATA": + NULL; + break; + case MBOX_CMD_DSP_GETVAR: + case MBOX_CMD_DSP_SETVAR: + s = (cmd_l == VARID_ICRMASK) ? "ICRMASK": + (cmd_l == VARID_LOADINFO) ? "LOADINFO": + NULL; + break; + case MBOX_CMD_DSP_ERR: + s = (cmd_l == EID_BADTID) ? "BADTID": + (cmd_l == EID_BADTCN) ? "BADTCN": + (cmd_l == EID_BADBID) ? "BADBID": + (cmd_l == EID_BADCNT) ? "BADCNT": + (cmd_l == EID_NOTLOCKED) ? "NOTLOCKED": + (cmd_l == EID_STVBUF) ? "STVBUF": + (cmd_l == EID_BADADR) ? "BADADR": + (cmd_l == EID_BADTCTL) ? "BADTCTL": + (cmd_l == EID_BADPARAM) ? "BADPARAM": + (cmd_l == EID_FATAL) ? "FATAL": + (cmd_l == EID_WDT) ? "WDT": + (cmd_l == EID_NOMEM) ? "NOMEM": + (cmd_l == EID_NORES) ? "NORES": + (cmd_l == EID_IPBFULL) ? "IPBFULL": + (cmd_l == EID_TASKNOTRDY) ? "TASKNOTRDY": + (cmd_l == EID_TASKBSY) ? "TASKBSY": + (cmd_l == EID_TASKERR) ? "TASKERR": + (cmd_l == EID_BADCFGTYP) ? "BADCFGTYP": + (cmd_l == EID_DEBUG) ? "DEBUG": + (cmd_l == EID_BADSEQ) ? "BADSEQ": + (cmd_l == EID_BADCMD) ? "BADCMD": + NULL; + break; + default: + s = NULL; + } + + return s; +} + +/* output of show() method should fit to PAGE_SIZE */ +#define MBLOG_DEPTH 64 + +struct mblogent { + unsigned long jiffies; + mbox_msg_t msg; + arm_dsp_dir_t dir; +}; + +static struct { + spinlock_t lock; + int wp; + unsigned long cnt, cnt_ad, cnt_da; + struct mblogent ent[MBLOG_DEPTH]; +} mblog = { + .lock = SPIN_LOCK_UNLOCKED, +}; + +#ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE +static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) +{ + const struct cmdinfo *ci = cmdinfo[mb->cmd_h]; + char *dir_str; + char *subname; + + dir_str = (dir == DIR_A2D) ? "sending " : "receiving"; + switch (ci->cmd_l_type) { + case CMD_L_TYPE_SUBCMD: + subname = subcmd_name(mb); + if (unlikely(!subname)) + subname = "Unknown"; + pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n", + dir_str, mb->seq, mb->cmd_h, mb->cmd_l, + ci->name, subname, mb->data); + break; + case CMD_L_TYPE_TID: + pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n", + dir_str, mb->seq, mb->cmd_h, mb->cmd_l, + ci->name, mb->cmd_l, mb->data); + break; + case CMD_L_TYPE_NULL: + pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n", + dir_str, mb->seq, mb->cmd_h, mb->cmd_l, + ci->name, mb->data); + break; + } +} +#else +static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) { } +#endif + +void mblog_add(struct mbcmd *mb, arm_dsp_dir_t dir) +{ + struct mblogent *ent; + + spin_lock(&mblog.lock); + ent = &mblog.ent[mblog.wp]; + ent->jiffies = jiffies; + ent->msg = *(mbox_msg_t *)mb; + ent->dir = dir; + if (mblog.cnt < 0xffffffff) + mblog.cnt++; + switch (dir) { + case DIR_A2D: + if (mblog.cnt_ad < 0xffffffff) + mblog.cnt_ad++; + break; + case DIR_D2A: + if (mblog.cnt_da < 0xffffffff) + mblog.cnt_da++; + break; + } + if (++mblog.wp == MBLOG_DEPTH) + mblog.wp = 0; + spin_unlock(&mblog.lock); + + mblog_print_cmd(mb, dir); +} + +/* + * sysfs file + */ +static ssize_t mblog_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int len = 0; + int wp; + int i; + + spin_lock(&mblog.lock); + + wp = mblog.wp; + len += sprintf(buf + len, + "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n", + mblog.cnt, mblog.cnt_ad, mblog.cnt_da); + if (mblog.cnt == 0) + goto done; + + len += sprintf(buf + len, " ARM->DSP ARM<-DSP\n"); + len += sprintf(buf + len, " jiffies cmd data cmd data\n"); + i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0; + do { + struct mblogent *ent = &mblog.ent[i]; + struct mbcmd *mb = (struct mbcmd *)&ent->msg; + char *subname; + struct cmdinfo ci_null = { + .name = "Unknown", + .cmd_l_type = CMD_L_TYPE_NULL, + }; + const struct cmdinfo *ci; + + len += sprintf(buf + len, + (ent->dir == DIR_A2D) ? + "%08lx %04x %04x ": + "%08lx %04x %04x ", + ent->jiffies, + (ent->msg >> 16) & 0x7fff, ent->msg & 0xffff); + + if ((ci = cmdinfo[mb->cmd_h]) == NULL) + ci = &ci_null; + + switch (ci->cmd_l_type) { + case CMD_L_TYPE_SUBCMD: + if ((subname = subcmd_name(mb)) == NULL) + subname = "Unknown"; + len += sprintf(buf + len, "%s:%s\n", + ci->name, subname); + break; + case CMD_L_TYPE_TID: + len += sprintf(buf + len, "%s:task %d\n", + ci->name, mb->cmd_l); + break; + case CMD_L_TYPE_NULL: + len += sprintf(buf + len, "%s\n", ci->name); + break; + } + + if (++i == MBLOG_DEPTH) + i = 0; + } while (i != wp); + +done: + spin_unlock(&mblog.lock); + + return len; +} + +static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog); + +void __init mblog_init(void) +{ + int ret; + + ret = device_create_file(omap_dsp->dev, &dev_attr_mblog); + if (ret) + printk(KERN_ERR "device_create_file failed: %d\n", ret); +} + +void mblog_exit(void) +{ + device_remove_file(omap_dsp->dev, &dev_attr_mblog); +}