2 * linux/arch/arm/mach-omap/dsp/mblog.c
4 * OMAP DSP driver Mailbox log module
6 * Copyright (C) 2003-2005 Nokia Corporation
8 * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * 2005/05/18: DSP Gateway version 3.3
27 #include <linux/module.h>
28 #include <linux/sched.h>
29 #include <linux/platform_device.h>
30 #include <linux/init.h>
32 #include <asm/arch/dsp.h>
35 #define RLCMD(nm) OMAP_DSP_MBCMD_RUNLEVEL_##nm
36 #define KFUNCCMD(nm) OMAP_DSP_MBCMD_KFUNC_##nm
37 #define PMCMD(nm) OMAP_DSP_MBCMD_PM_##nm
38 #define CFGCMD(nm) OMAP_DSP_MBCMD_DSPCFG_##nm
39 #define REGCMD(nm) OMAP_DSP_MBCMD_REGRW_##nm
40 #define VICMD(nm) OMAP_DSP_MBCMD_VARID_##nm
41 #define EID(nm) OMAP_DSP_EID_##nm
43 char *subcmd_name(struct mbcmd *mb)
45 unsigned char cmd_h = mb->cmd_h;
46 unsigned char cmd_l = mb->cmd_l;
51 s = (cmd_l == RLCMD(USER)) ? "USER":
52 (cmd_l == RLCMD(SUPER)) ? "SUPER":
53 (cmd_l == RLCMD(RECOVERY)) ? "RECOVERY":
57 s = (cmd_l == PMCMD(DISABLE)) ? "DISABLE":
58 (cmd_l == PMCMD(ENABLE)) ? "ENABLE":
62 s = (cmd_l == KFUNCCMD(FBCTL)) ? "FBCTL":
63 (cmd_l == KFUNCCMD(AUDIO_PWR)) ? "AUDIO_PWR":
68 unsigned char cfgc = cmd_l & 0x7f;
69 s = (cfgc == CFGCMD(REQ)) ? "REQ":
70 (cfgc == CFGCMD(SYSADRH)) ? "SYSADRH":
71 (cfgc == CFGCMD(SYSADRL)) ? "SYSADRL":
72 (cfgc == CFGCMD(ABORT)) ? "ABORT":
73 (cfgc == CFGCMD(PROTREV)) ? "PROTREV":
78 s = (cmd_l == REGCMD(MEMR)) ? "MEMR":
79 (cmd_l == REGCMD(MEMW)) ? "MEMW":
80 (cmd_l == REGCMD(IOR)) ? "IOR":
81 (cmd_l == REGCMD(IOW)) ? "IOW":
82 (cmd_l == REGCMD(DATA)) ? "DATA":
87 s = (cmd_l == VICMD(ICRMASK)) ? "ICRMASK":
88 (cmd_l == VICMD(LOADINFO)) ? "LOADINFO":
92 s = (cmd_l == EID(BADTID)) ? "BADTID":
93 (cmd_l == EID(BADTCN)) ? "BADTCN":
94 (cmd_l == EID(BADBID)) ? "BADBID":
95 (cmd_l == EID(BADCNT)) ? "BADCNT":
96 (cmd_l == EID(NOTLOCKED)) ? "NOTLOCKED":
97 (cmd_l == EID(STVBUF)) ? "STVBUF":
98 (cmd_l == EID(BADADR)) ? "BADADR":
99 (cmd_l == EID(BADTCTL)) ? "BADTCTL":
100 (cmd_l == EID(BADPARAM)) ? "BADPARAM":
101 (cmd_l == EID(FATAL)) ? "FATAL":
102 (cmd_l == EID(WDT)) ? "WDT":
103 (cmd_l == EID(NOMEM)) ? "NOMEM":
104 (cmd_l == EID(NORES)) ? "NORES":
105 (cmd_l == EID(IPBFULL)) ? "IPBFULL":
106 (cmd_l == EID(TASKNOTRDY)) ? "TASKNOTRDY":
107 (cmd_l == EID(TASKBSY)) ? "TASKBSY":
108 (cmd_l == EID(TASKERR)) ? "TASKERR":
109 (cmd_l == EID(BADCFGTYP)) ? "BADCFGTYP":
110 (cmd_l == EID(DEBUG)) ? "DEBUG":
111 (cmd_l == EID(BADSEQ)) ? "BADSEQ":
112 (cmd_l == EID(BADCMD)) ? "BADCMD":
122 /* output of show() method should fit to PAGE_SIZE */
123 #define MBLOG_DEPTH 64
126 unsigned long jiffies;
129 enum arm_dsp_dir dir;
135 unsigned long cnt, cnt_ad, cnt_da;
136 struct mblogent ent[MBLOG_DEPTH];
139 void mblog_add(struct mbcmd *mb, enum arm_dsp_dir dir)
141 struct mbcmd_hw *mb_hw = (struct mbcmd_hw *)mb;
142 struct mblogent *ent;
144 spin_lock(&mblog.lock);
145 ent = &mblog.ent[mblog.wp];
146 ent->jiffies = jiffies;
147 ent->cmd = mb_hw->cmd;
148 ent->data = mb_hw->data;
150 if (mblog.cnt < 0xffffffff)
154 if (mblog.cnt_ad < 0xffffffff)
158 if (mblog.cnt_da < 0xffffffff)
162 if (++mblog.wp == MBLOG_DEPTH)
164 spin_unlock(&mblog.lock);
170 static ssize_t mblog_show(struct device *dev, struct device_attribute *attr,
177 spin_lock(&mblog.lock);
180 len += sprintf(buf + len,
181 "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",
182 mblog.cnt, mblog.cnt_ad, mblog.cnt_da);
186 len += sprintf(buf + len, " ARM -> DSP ARM <- DSP\n");
187 len += sprintf(buf + len, "jiffies q cmd data q cmd data\n");
188 i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;
190 struct mblogent *ent = &mblog.ent[i];
199 const struct cmdinfo *ci = cmdinfo[mb.sw.cmd_h];
201 len += sprintf(buf + len,
202 (ent->dir == DIR_A2D) ?
203 "%08lx %d %04x %04x ":
204 "%08lx %d %04x %04x ",
205 ent->jiffies, mb.sw.seq, ent->cmd, ent->data);
206 switch (ci->cmd_l_type) {
207 case CMD_L_TYPE_SUBCMD:
208 if ((subname = subcmd_name(&mb.sw)) == NULL)
210 len += sprintf(buf + len, "%s:%s\n",
214 len += sprintf(buf + len, "%s:task %d\n",
215 ci->name, mb.sw.cmd_l);
217 case CMD_L_TYPE_NULL:
218 len += sprintf(buf + len, "%s\n", ci->name);
222 if (++i == MBLOG_DEPTH)
227 spin_unlock(&mblog.lock);
232 static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog);
234 #ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
235 void mblog_printcmd(struct mbcmd *mb, enum arm_dsp_dir dir)
237 const struct cmdinfo *ci = cmdinfo[mb->cmd_h];
241 dir_str = (dir == DIR_A2D) ? "sending" : "receiving";
242 switch (ci->cmd_l_type) {
243 case CMD_L_TYPE_SUBCMD:
244 if ((subname = subcmd_name(mb)) == NULL)
247 "mbx: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n",
248 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
249 ci->name, subname, mb->data);
253 "mbx: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n",
254 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
255 ci->name, mb->cmd_l, mb->data);
257 case CMD_L_TYPE_NULL:
259 "mbx: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n",
260 dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
265 #endif /* CONFIG_OMAP_DSP_MBCMD_VERBOSE */
267 void __init mblog_init(void)
269 spin_lock_init(&mblog.lock);
270 device_create_file(&dsp_device.dev, &dev_attr_mblog);
273 void mblog_exit(void)
275 device_remove_file(&dsp_device.dev, &dev_attr_mblog);