]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/dsp/mblog.c
287c378bf76acbbcdb1a44d119a1f3965f45d038
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / mblog.c
1 /*
2  * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
3  *
4  * Copyright (C) 2003-2006 Nokia Corporation. All rights reserved.
5  *
6  * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
7  *
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.
11  *
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.
16  *
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
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/platform_device.h>
25 #include <linux/init.h>
26 #include <asm/arch/mailbox.h>
27 #include "dsp_mbcmd.h"
28 #include "dsp.h"
29
30 char *subcmd_name(struct mbcmd *mb)
31 {
32         u8 cmd_h = mb->cmd_h;
33         u8 cmd_l = mb->cmd_l;
34         char *s;
35
36         switch (cmd_h) {
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":
41                     NULL;
42                 break;
43         case MBOX_CMD_DSP_PM:
44                 s = (cmd_l == PM_DISABLE) ? "DISABLE":
45                     (cmd_l == PM_ENABLE)  ? "ENABLE":
46                     NULL;
47                 break;
48         case MBOX_CMD_DSP_KFUNC:
49                 s = (cmd_l == KFUNC_FBCTL) ? "FBCTL":
50                     NULL;
51                 break;
52         case MBOX_CMD_DSP_DSPCFG:
53                 {
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":
60                             NULL;
61                         break;
62                 }
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":
69                     NULL;
70                 break;
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":
75                     NULL;
76                 break;
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":
99                     NULL;
100                 break;
101         default:
102                 s = NULL;
103         }
104
105         return s;
106 }
107
108 /* output of show() method should fit to PAGE_SIZE */
109 #define MBLOG_DEPTH     64
110
111 struct mblogent {
112         unsigned long jiffies;
113         mbox_msg_t msg;
114         enum arm_dsp_dir_e dir;
115 };
116
117 static struct {
118         spinlock_t lock;
119         int wp;
120         unsigned long cnt, cnt_ad, cnt_da;
121         struct mblogent ent[MBLOG_DEPTH];
122 } mblog = {
123         .lock = SPIN_LOCK_UNLOCKED,
124 };
125
126 void mblog_add(struct mbcmd *mb, enum arm_dsp_dir_e dir)
127 {
128         struct mblogent *ent;
129
130         spin_lock(&mblog.lock);
131         ent = &mblog.ent[mblog.wp];
132         ent->jiffies = jiffies;
133         ent->msg = *(mbox_msg_t *)mb;
134         ent->dir = dir;
135         if (mblog.cnt < 0xffffffff)
136                 mblog.cnt++;
137         switch (dir) {
138         case DIR_A2D:
139                 if (mblog.cnt_ad < 0xffffffff)
140                         mblog.cnt_ad++;
141                 break;
142         case DIR_D2A:
143                 if (mblog.cnt_da < 0xffffffff)
144                         mblog.cnt_da++;
145                 break;
146         }
147         if (++mblog.wp == MBLOG_DEPTH)
148                 mblog.wp = 0;
149         spin_unlock(&mblog.lock);
150 }
151
152 /*
153  * sysfs file
154  */
155 static ssize_t mblog_show(struct device *dev, struct device_attribute *attr,
156                           char *buf)
157 {
158         int len = 0;
159         int wp;
160         int i;
161
162         spin_lock(&mblog.lock);
163
164         wp = mblog.wp;
165         len += sprintf(buf + len,
166                        "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",
167                        mblog.cnt, mblog.cnt_ad, mblog.cnt_da);
168         if (mblog.cnt == 0)
169                 goto done;
170
171         len += sprintf(buf + len, "           ARM->DSP   ARM<-DSP\n");
172         len += sprintf(buf + len, " jiffies  cmd  data  cmd  data\n");
173         i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;
174         do {
175                 struct mblogent *ent = &mblog.ent[i];
176                 struct mbcmd *mb = (struct mbcmd *)&ent->msg;
177                 char *subname;
178                 struct cmdinfo ci_null = {
179                         .name = "Unknown",
180                         .cmd_l_type = CMD_L_TYPE_NULL,
181                 };
182                 const struct cmdinfo *ci;
183
184                 len += sprintf(buf + len,
185                                (ent->dir == DIR_A2D) ?
186                                 "%08lx  %04x %04x            ":
187                                 "%08lx             %04x %04x ",
188                                ent->jiffies,
189                                (ent->msg >> 16) & 0x7fff, ent->msg & 0xffff);
190
191                 if ((ci = cmdinfo[mb->cmd_h]) == NULL)
192                         ci = &ci_null;
193
194                 switch (ci->cmd_l_type) {
195                 case CMD_L_TYPE_SUBCMD:
196                         if ((subname = subcmd_name(mb)) == NULL)
197                                 subname = "Unknown";
198                         len += sprintf(buf + len, "%s:%s\n",
199                                        ci->name, subname);
200                         break;
201                 case CMD_L_TYPE_TID:
202                         len += sprintf(buf + len, "%s:task %d\n",
203                                        ci->name, mb->cmd_l);
204                         break;
205                 case CMD_L_TYPE_NULL:
206                         len += sprintf(buf + len, "%s\n", ci->name);
207                         break;
208                 }
209
210                 if (++i == MBLOG_DEPTH)
211                         i = 0;
212         } while (i != wp);
213
214 done:
215         spin_unlock(&mblog.lock);
216
217         return len;
218 }
219
220 static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog);
221
222 #ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
223 void mblog_printcmd(struct mbcmd *mb, enum arm_dsp_dir_e dir)
224 {
225         struct cmdinfo ci_null = {
226                 .name = "Unknown",
227                 .cmd_l_type = CMD_L_TYPE_NULL,
228         };
229         const struct cmdinfo *ci;
230         char *dir_str;
231         char *subname;
232
233         dir_str = (dir == DIR_A2D) ? "sending" : "receiving";
234
235         if ((ci = cmdinfo[mb->cmd_h]) == NULL)
236                 ci = &ci_null;
237
238         switch (ci->cmd_l_type) {
239         case CMD_L_TYPE_SUBCMD:
240                 if ((subname = subcmd_name(mb)) == NULL)
241                         subname = "Unknown";
242                 printk(KERN_DEBUG
243                        "mbox: %s cmd=%02x:%02x(%s:%s), data=%04x\n",
244                        dir_str, mb->cmd_h, mb->cmd_l,
245                        ci->name, subname, mb->data);
246                 break;
247         case CMD_L_TYPE_TID:
248                 printk(KERN_DEBUG
249                        "mbox: %s cmd=%02x:%02x(%s:task %d), data=%04x\n",
250                        dir_str, mb->cmd_h, mb->cmd_l,
251                        ci->name, mb->cmd_l, mb->data);
252                 break;
253         case CMD_L_TYPE_NULL:
254                 printk(KERN_DEBUG
255                        "mbox: %s cmd=%02x:%02x(%s), data=%04x\n",
256                        dir_str, mb->cmd_h, mb->cmd_l, ci->name, mb->data);
257                 break;
258         }
259 }
260 #endif /* CONFIG_OMAP_DSP_MBCMD_VERBOSE */
261
262 void __init mblog_init(void)
263 {
264         device_create_file(&dsp_device.dev, &dev_attr_mblog);
265 }
266
267 void mblog_exit(void)
268 {
269         device_remove_file(&dsp_device.dev, &dev_attr_mblog);
270 }