2 * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
4 * Copyright (C) 2003-2006 Nokia Corporation. All rights reserved.
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 #include <linux/platform_device.h>
25 #include <linux/init.h>
26 #include <asm/arch/mailbox.h>
27 #include "dsp_mbcmd.h"
30 char *subcmd_name(struct mbcmd *mb)
37 case MBOX_CMD_DSP_RUNLEVEL:
38 s = (cmd_l == RUNLEVEL_USER) ? "USER":
39 (cmd_l == RUNLEVEL_SUPER) ? "SUPER":
40 (cmd_l == RUNLEVEL_RECOVERY) ? "RECOVERY":
44 s = (cmd_l == PM_DISABLE) ? "DISABLE":
45 (cmd_l == PM_ENABLE) ? "ENABLE":
48 case MBOX_CMD_DSP_KFUNC:
49 s = (cmd_l == KFUNC_FBCTL) ? "FBCTL":
50 (cmd_l == KFUNC_POWER) ? "POWER":
53 case MBOX_CMD_DSP_DSPCFG:
55 u8 cfgc = cmd_l & 0x7f;
56 s = (cfgc == DSPCFG_REQ) ? "REQ":
57 (cfgc == DSPCFG_SYSADRH) ? "SYSADRH":
58 (cfgc == DSPCFG_SYSADRL) ? "SYSADRL":
59 (cfgc == DSPCFG_ABORT) ? "ABORT":
60 (cfgc == DSPCFG_PROTREV) ? "PROTREV":
64 case MBOX_CMD_DSP_REGRW:
65 s = (cmd_l == REGRW_MEMR) ? "MEMR":
66 (cmd_l == REGRW_MEMW) ? "MEMW":
67 (cmd_l == REGRW_IOR) ? "IOR":
68 (cmd_l == REGRW_IOW) ? "IOW":
69 (cmd_l == REGRW_DATA) ? "DATA":
72 case MBOX_CMD_DSP_GETVAR:
73 case MBOX_CMD_DSP_SETVAR:
74 s = (cmd_l == VARID_ICRMASK) ? "ICRMASK":
75 (cmd_l == VARID_LOADINFO) ? "LOADINFO":
78 case MBOX_CMD_DSP_ERR:
79 s = (cmd_l == EID_BADTID) ? "BADTID":
80 (cmd_l == EID_BADTCN) ? "BADTCN":
81 (cmd_l == EID_BADBID) ? "BADBID":
82 (cmd_l == EID_BADCNT) ? "BADCNT":
83 (cmd_l == EID_NOTLOCKED) ? "NOTLOCKED":
84 (cmd_l == EID_STVBUF) ? "STVBUF":
85 (cmd_l == EID_BADADR) ? "BADADR":
86 (cmd_l == EID_BADTCTL) ? "BADTCTL":
87 (cmd_l == EID_BADPARAM) ? "BADPARAM":
88 (cmd_l == EID_FATAL) ? "FATAL":
89 (cmd_l == EID_WDT) ? "WDT":
90 (cmd_l == EID_NOMEM) ? "NOMEM":
91 (cmd_l == EID_NORES) ? "NORES":
92 (cmd_l == EID_IPBFULL) ? "IPBFULL":
93 (cmd_l == EID_TASKNOTRDY) ? "TASKNOTRDY":
94 (cmd_l == EID_TASKBSY) ? "TASKBSY":
95 (cmd_l == EID_TASKERR) ? "TASKERR":
96 (cmd_l == EID_BADCFGTYP) ? "BADCFGTYP":
97 (cmd_l == EID_DEBUG) ? "DEBUG":
98 (cmd_l == EID_BADSEQ) ? "BADSEQ":
99 (cmd_l == EID_BADCMD) ? "BADCMD":
109 /* output of show() method should fit to PAGE_SIZE */
110 #define MBLOG_DEPTH 64
113 unsigned long jiffies;
121 unsigned long cnt, cnt_ad, cnt_da;
122 struct mblogent ent[MBLOG_DEPTH];
124 .lock = SPIN_LOCK_UNLOCKED,
127 #ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
128 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir)
130 const struct cmdinfo *ci = cmdinfo[mb->cmd_h];
134 dir_str = (dir == DIR_A2D) ? "sending " : "receiving";
135 switch (ci->cmd_l_type) {
136 case CMD_L_TYPE_SUBCMD:
137 subname = subcmd_name(mb);
138 if (unlikely(!subname))
141 "mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n",
142 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
143 ci->name, subname, mb->data);
147 "mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n",
148 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
149 ci->name, mb->cmd_l, mb->data);
151 case CMD_L_TYPE_NULL:
153 "mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n",
154 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
160 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) { }
163 void mblog_add(struct mbcmd *mb, arm_dsp_dir_t dir)
165 struct mblogent *ent;
167 spin_lock(&mblog.lock);
168 ent = &mblog.ent[mblog.wp];
169 ent->jiffies = jiffies;
170 ent->msg = *(mbox_msg_t *)mb;
172 if (mblog.cnt < 0xffffffff)
176 if (mblog.cnt_ad < 0xffffffff)
180 if (mblog.cnt_da < 0xffffffff)
184 if (++mblog.wp == MBLOG_DEPTH)
186 spin_unlock(&mblog.lock);
188 mblog_print_cmd(mb, dir);
194 static ssize_t mblog_show(struct device *dev, struct device_attribute *attr,
201 spin_lock(&mblog.lock);
204 len += sprintf(buf + len,
205 "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",
206 mblog.cnt, mblog.cnt_ad, mblog.cnt_da);
210 len += sprintf(buf + len, " ARM->DSP ARM<-DSP\n");
211 len += sprintf(buf + len, " jiffies cmd data cmd data\n");
212 i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;
214 struct mblogent *ent = &mblog.ent[i];
215 struct mbcmd *mb = (struct mbcmd *)&ent->msg;
217 struct cmdinfo ci_null = {
219 .cmd_l_type = CMD_L_TYPE_NULL,
221 const struct cmdinfo *ci;
223 len += sprintf(buf + len,
224 (ent->dir == DIR_A2D) ?
228 (ent->msg >> 16) & 0x7fff, ent->msg & 0xffff);
230 if ((ci = cmdinfo[mb->cmd_h]) == NULL)
233 switch (ci->cmd_l_type) {
234 case CMD_L_TYPE_SUBCMD:
235 if ((subname = subcmd_name(mb)) == NULL)
237 len += sprintf(buf + len, "%s:%s\n",
241 len += sprintf(buf + len, "%s:task %d\n",
242 ci->name, mb->cmd_l);
244 case CMD_L_TYPE_NULL:
245 len += sprintf(buf + len, "%s\n", ci->name);
249 if (++i == MBLOG_DEPTH)
254 spin_unlock(&mblog.lock);
259 static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog);
261 void __init mblog_init(void)
263 device_create_file(omap_dsp->dev, &dev_attr_mblog);
266 void mblog_exit(void)
268 device_remove_file(omap_dsp->dev, &dev_attr_mblog);