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":
52 case MBOX_CMD_DSP_DSPCFG:
54 u8 cfgc = cmd_l & 0x7f;
55 s = (cfgc == DSPCFG_REQ) ? "REQ":
56 (cfgc == DSPCFG_SYSADRH) ? "SYSADRH":
57 (cfgc == DSPCFG_SYSADRL) ? "SYSADRL":
58 (cfgc == DSPCFG_ABORT) ? "ABORT":
59 (cfgc == DSPCFG_PROTREV) ? "PROTREV":
63 case MBOX_CMD_DSP_REGRW:
64 s = (cmd_l == REGRW_MEMR) ? "MEMR":
65 (cmd_l == REGRW_MEMW) ? "MEMW":
66 (cmd_l == REGRW_IOR) ? "IOR":
67 (cmd_l == REGRW_IOW) ? "IOW":
68 (cmd_l == REGRW_DATA) ? "DATA":
71 case MBOX_CMD_DSP_GETVAR:
72 case MBOX_CMD_DSP_SETVAR:
73 s = (cmd_l == VARID_ICRMASK) ? "ICRMASK":
74 (cmd_l == VARID_LOADINFO) ? "LOADINFO":
77 case MBOX_CMD_DSP_ERR:
78 s = (cmd_l == EID_BADTID) ? "BADTID":
79 (cmd_l == EID_BADTCN) ? "BADTCN":
80 (cmd_l == EID_BADBID) ? "BADBID":
81 (cmd_l == EID_BADCNT) ? "BADCNT":
82 (cmd_l == EID_NOTLOCKED) ? "NOTLOCKED":
83 (cmd_l == EID_STVBUF) ? "STVBUF":
84 (cmd_l == EID_BADADR) ? "BADADR":
85 (cmd_l == EID_BADTCTL) ? "BADTCTL":
86 (cmd_l == EID_BADPARAM) ? "BADPARAM":
87 (cmd_l == EID_FATAL) ? "FATAL":
88 (cmd_l == EID_WDT) ? "WDT":
89 (cmd_l == EID_NOMEM) ? "NOMEM":
90 (cmd_l == EID_NORES) ? "NORES":
91 (cmd_l == EID_IPBFULL) ? "IPBFULL":
92 (cmd_l == EID_TASKNOTRDY) ? "TASKNOTRDY":
93 (cmd_l == EID_TASKBSY) ? "TASKBSY":
94 (cmd_l == EID_TASKERR) ? "TASKERR":
95 (cmd_l == EID_BADCFGTYP) ? "BADCFGTYP":
96 (cmd_l == EID_DEBUG) ? "DEBUG":
97 (cmd_l == EID_BADSEQ) ? "BADSEQ":
98 (cmd_l == EID_BADCMD) ? "BADCMD":
108 /* output of show() method should fit to PAGE_SIZE */
109 #define MBLOG_DEPTH 64
112 unsigned long jiffies;
120 unsigned long cnt, cnt_ad, cnt_da;
121 struct mblogent ent[MBLOG_DEPTH];
123 .lock = SPIN_LOCK_UNLOCKED,
126 #ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
127 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir)
129 const struct cmdinfo *ci = cmdinfo[mb->cmd_h];
133 dir_str = (dir == DIR_A2D) ? "sending " : "receiving";
134 switch (ci->cmd_l_type) {
135 case CMD_L_TYPE_SUBCMD:
136 subname = subcmd_name(mb);
137 if (unlikely(!subname))
140 "mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n",
141 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
142 ci->name, subname, mb->data);
146 "mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n",
147 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
148 ci->name, mb->cmd_l, mb->data);
150 case CMD_L_TYPE_NULL:
152 "mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n",
153 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
159 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) { }
162 void mblog_add(struct mbcmd *mb, arm_dsp_dir_t dir)
164 struct mblogent *ent;
166 spin_lock(&mblog.lock);
167 ent = &mblog.ent[mblog.wp];
168 ent->jiffies = jiffies;
169 ent->msg = *(mbox_msg_t *)mb;
171 if (mblog.cnt < 0xffffffff)
175 if (mblog.cnt_ad < 0xffffffff)
179 if (mblog.cnt_da < 0xffffffff)
183 if (++mblog.wp == MBLOG_DEPTH)
185 spin_unlock(&mblog.lock);
187 mblog_print_cmd(mb, dir);
193 static ssize_t mblog_show(struct device *dev, struct device_attribute *attr,
200 spin_lock(&mblog.lock);
203 len += sprintf(buf + len,
204 "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",
205 mblog.cnt, mblog.cnt_ad, mblog.cnt_da);
209 len += sprintf(buf + len, " ARM->DSP ARM<-DSP\n");
210 len += sprintf(buf + len, " jiffies cmd data cmd data\n");
211 i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;
213 struct mblogent *ent = &mblog.ent[i];
214 struct mbcmd *mb = (struct mbcmd *)&ent->msg;
216 struct cmdinfo ci_null = {
218 .cmd_l_type = CMD_L_TYPE_NULL,
220 const struct cmdinfo *ci;
222 len += sprintf(buf + len,
223 (ent->dir == DIR_A2D) ?
227 (ent->msg >> 16) & 0x7fff, ent->msg & 0xffff);
229 if ((ci = cmdinfo[mb->cmd_h]) == NULL)
232 switch (ci->cmd_l_type) {
233 case CMD_L_TYPE_SUBCMD:
234 if ((subname = subcmd_name(mb)) == NULL)
236 len += sprintf(buf + len, "%s:%s\n",
240 len += sprintf(buf + len, "%s:task %d\n",
241 ci->name, mb->cmd_l);
243 case CMD_L_TYPE_NULL:
244 len += sprintf(buf + len, "%s\n", ci->name);
248 if (++i == MBLOG_DEPTH)
253 spin_unlock(&mblog.lock);
258 static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog);
260 void __init mblog_init(void)
262 device_create_file(dsp_device, &dev_attr_mblog);
265 void mblog_exit(void)
267 device_remove_file(dsp_device, &dev_attr_mblog);