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 <linux/jiffies.h>
27 #include <asm/arch/mailbox.h>
28 #include "dsp_mbcmd.h"
31 char *subcmd_name(struct mbcmd *mb)
38 case MBOX_CMD_DSP_RUNLEVEL:
39 s = (cmd_l == RUNLEVEL_USER) ? "USER":
40 (cmd_l == RUNLEVEL_SUPER) ? "SUPER":
41 (cmd_l == RUNLEVEL_RECOVERY) ? "RECOVERY":
45 s = (cmd_l == PM_DISABLE) ? "DISABLE":
46 (cmd_l == PM_ENABLE) ? "ENABLE":
49 case MBOX_CMD_DSP_KFUNC:
50 s = (cmd_l == KFUNC_FBCTL) ? "FBCTL":
51 (cmd_l == KFUNC_POWER) ? "POWER":
54 case MBOX_CMD_DSP_DSPCFG:
56 u8 cfgc = cmd_l & 0x7f;
57 s = (cfgc == DSPCFG_REQ) ? "REQ":
58 (cfgc == DSPCFG_SYSADRH) ? "SYSADRH":
59 (cfgc == DSPCFG_SYSADRL) ? "SYSADRL":
60 (cfgc == DSPCFG_ABORT) ? "ABORT":
61 (cfgc == DSPCFG_PROTREV) ? "PROTREV":
65 case MBOX_CMD_DSP_REGRW:
66 s = (cmd_l == REGRW_MEMR) ? "MEMR":
67 (cmd_l == REGRW_MEMW) ? "MEMW":
68 (cmd_l == REGRW_IOR) ? "IOR":
69 (cmd_l == REGRW_IOW) ? "IOW":
70 (cmd_l == REGRW_DATA) ? "DATA":
73 case MBOX_CMD_DSP_GETVAR:
74 case MBOX_CMD_DSP_SETVAR:
75 s = (cmd_l == VARID_ICRMASK) ? "ICRMASK":
76 (cmd_l == VARID_LOADINFO) ? "LOADINFO":
79 case MBOX_CMD_DSP_ERR:
80 s = (cmd_l == EID_BADTID) ? "BADTID":
81 (cmd_l == EID_BADTCN) ? "BADTCN":
82 (cmd_l == EID_BADBID) ? "BADBID":
83 (cmd_l == EID_BADCNT) ? "BADCNT":
84 (cmd_l == EID_NOTLOCKED) ? "NOTLOCKED":
85 (cmd_l == EID_STVBUF) ? "STVBUF":
86 (cmd_l == EID_BADADR) ? "BADADR":
87 (cmd_l == EID_BADTCTL) ? "BADTCTL":
88 (cmd_l == EID_BADPARAM) ? "BADPARAM":
89 (cmd_l == EID_FATAL) ? "FATAL":
90 (cmd_l == EID_WDT) ? "WDT":
91 (cmd_l == EID_NOMEM) ? "NOMEM":
92 (cmd_l == EID_NORES) ? "NORES":
93 (cmd_l == EID_IPBFULL) ? "IPBFULL":
94 (cmd_l == EID_TASKNOTRDY) ? "TASKNOTRDY":
95 (cmd_l == EID_TASKBSY) ? "TASKBSY":
96 (cmd_l == EID_TASKERR) ? "TASKERR":
97 (cmd_l == EID_BADCFGTYP) ? "BADCFGTYP":
98 (cmd_l == EID_DEBUG) ? "DEBUG":
99 (cmd_l == EID_BADSEQ) ? "BADSEQ":
100 (cmd_l == EID_BADCMD) ? "BADCMD":
110 /* output of show() method should fit to PAGE_SIZE */
111 #define MBLOG_DEPTH 64
114 unsigned long jiffies;
122 unsigned long cnt, cnt_ad, cnt_da;
123 struct mblogent ent[MBLOG_DEPTH];
125 .lock = SPIN_LOCK_UNLOCKED,
128 #ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
129 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir)
131 const struct cmdinfo *ci = cmdinfo[mb->cmd_h];
135 dir_str = (dir == DIR_A2D) ? "sending " : "receiving";
136 switch (ci->cmd_l_type) {
137 case CMD_L_TYPE_SUBCMD:
138 subname = subcmd_name(mb);
139 if (unlikely(!subname))
142 "mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n",
143 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
144 ci->name, subname, mb->data);
148 "mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n",
149 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
150 ci->name, mb->cmd_l, mb->data);
152 case CMD_L_TYPE_NULL:
154 "mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n",
155 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
161 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) { }
164 void mblog_add(struct mbcmd *mb, arm_dsp_dir_t dir)
166 struct mblogent *ent;
168 spin_lock(&mblog.lock);
169 ent = &mblog.ent[mblog.wp];
170 ent->jiffies = jiffies;
171 ent->msg = *(mbox_msg_t *)mb;
173 if (mblog.cnt < 0xffffffff)
177 if (mblog.cnt_ad < 0xffffffff)
181 if (mblog.cnt_da < 0xffffffff)
185 if (++mblog.wp == MBLOG_DEPTH)
187 spin_unlock(&mblog.lock);
189 mblog_print_cmd(mb, dir);
195 static ssize_t mblog_show(struct device *dev, struct device_attribute *attr,
202 spin_lock(&mblog.lock);
205 len += sprintf(buf + len,
206 "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",
207 mblog.cnt, mblog.cnt_ad, mblog.cnt_da);
211 len += sprintf(buf + len, " ARM->DSP ARM<-DSP\n");
212 len += sprintf(buf + len, " jiffies cmd data cmd data\n");
213 i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;
215 struct mblogent *ent = &mblog.ent[i];
216 struct mbcmd *mb = (struct mbcmd *)&ent->msg;
218 struct cmdinfo ci_null = {
220 .cmd_l_type = CMD_L_TYPE_NULL,
222 const struct cmdinfo *ci;
224 len += sprintf(buf + len,
225 (ent->dir == DIR_A2D) ?
229 (ent->msg >> 16) & 0x7fff, ent->msg & 0xffff);
231 if ((ci = cmdinfo[mb->cmd_h]) == NULL)
234 switch (ci->cmd_l_type) {
235 case CMD_L_TYPE_SUBCMD:
236 if ((subname = subcmd_name(mb)) == NULL)
238 len += sprintf(buf + len, "%s:%s\n",
242 len += sprintf(buf + len, "%s:task %d\n",
243 ci->name, mb->cmd_l);
245 case CMD_L_TYPE_NULL:
246 len += sprintf(buf + len, "%s\n", ci->name);
250 if (++i == MBLOG_DEPTH)
255 spin_unlock(&mblog.lock);
260 static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog);
262 void __init mblog_init(void)
266 ret = device_create_file(omap_dsp->dev, &dev_attr_mblog);
268 printk(KERN_ERR "device_create_file failed: %d\n", ret);
271 void mblog_exit(void)
273 device_remove_file(omap_dsp->dev, &dev_attr_mblog);