]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/dsp/dspgateway/mblog.c
REMOVE OMAP LEGACY CODE: Reset mach-omap1/board-*.c files to mainline
[linux-2.6-omap-h63xx.git] / drivers / dsp / dspgateway / 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 <linux/jiffies.h>
27 #include <mach/mailbox.h>
28 #include "dsp_mbcmd.h"
29 #include "dsp.h"
30
31 char *subcmd_name(struct mbcmd *mb)
32 {
33         u8 cmd_h = mb->cmd_h;
34         u8 cmd_l = mb->cmd_l;
35         char *s;
36
37         switch (cmd_h) {
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":
42                     NULL;
43                 break;
44         case MBOX_CMD_DSP_PM:
45                 s = (cmd_l == PM_DISABLE) ? "DISABLE":
46                     (cmd_l == PM_ENABLE)  ? "ENABLE":
47                     NULL;
48                 break;
49         case MBOX_CMD_DSP_KFUNC:
50                 s = (cmd_l == KFUNC_FBCTL) ? "FBCTL":
51                         (cmd_l == KFUNC_POWER) ?
52                         ((mb->data == AUDIO_PWR_UP)     ? "PWR AUD /UP":
53                          (mb->data == AUDIO_PWR_DOWN)   ? "PWR AUD /DOWN":
54                          (mb->data == AUDIO_PWR_DOWN2)  ? "PWR AUD /DOWN(2)":
55                          (mb->data == DSP_PWR_UP)       ? "PWR DSP /UP":
56                          (mb->data == DSP_PWR_DOWN)     ? "PWR DSP /DOWN":
57                          (mb->data == DVFS_START)       ? "PWR DVFS/START":
58                          (mb->data == DVFS_STOP)        ? "PWR DVFS/STOP":
59                          NULL):
60
61                     NULL;
62                 break;
63         case MBOX_CMD_DSP_DSPCFG:
64                 {
65                         u8 cfgc = cmd_l & 0x7f;
66                         s = (cfgc == DSPCFG_REQ)     ? "REQ":
67                             (cfgc == DSPCFG_SYSADRH) ? "SYSADRH":
68                             (cfgc == DSPCFG_SYSADRL) ? "SYSADRL":
69                             (cfgc == DSPCFG_ABORT)   ? "ABORT":
70                             (cfgc == DSPCFG_PROTREV) ? "PROTREV":
71                             NULL;
72                         break;
73                 }
74         case MBOX_CMD_DSP_REGRW:
75                 s = (cmd_l == REGRW_MEMR) ? "MEMR":
76                     (cmd_l == REGRW_MEMW) ? "MEMW":
77                     (cmd_l == REGRW_IOR)  ? "IOR":
78                     (cmd_l == REGRW_IOW)  ? "IOW":
79                     (cmd_l == REGRW_DATA) ? "DATA":
80                     NULL;
81                 break;
82         case MBOX_CMD_DSP_GETVAR:
83         case MBOX_CMD_DSP_SETVAR:
84                 s = (cmd_l == VARID_ICRMASK)  ? "ICRMASK":
85                     (cmd_l == VARID_LOADINFO) ? "LOADINFO":
86                     NULL;
87                 break;
88         case MBOX_CMD_DSP_ERR:
89                 s = (cmd_l == EID_BADTID)     ? "BADTID":
90                     (cmd_l == EID_BADTCN)     ? "BADTCN":
91                     (cmd_l == EID_BADBID)     ? "BADBID":
92                     (cmd_l == EID_BADCNT)     ? "BADCNT":
93                     (cmd_l == EID_NOTLOCKED)  ? "NOTLOCKED":
94                     (cmd_l == EID_STVBUF)     ? "STVBUF":
95                     (cmd_l == EID_BADADR)     ? "BADADR":
96                     (cmd_l == EID_BADTCTL)    ? "BADTCTL":
97                     (cmd_l == EID_BADPARAM)   ? "BADPARAM":
98                     (cmd_l == EID_FATAL)      ? "FATAL":
99                     (cmd_l == EID_WDT)        ? "WDT":
100                     (cmd_l == EID_NOMEM)      ? "NOMEM":
101                     (cmd_l == EID_NORES)      ? "NORES":
102                     (cmd_l == EID_IPBFULL)    ? "IPBFULL":
103                     (cmd_l == EID_TASKNOTRDY) ? "TASKNOTRDY":
104                     (cmd_l == EID_TASKBSY)    ? "TASKBSY":
105                     (cmd_l == EID_TASKERR)    ? "TASKERR":
106                     (cmd_l == EID_BADCFGTYP)  ? "BADCFGTYP":
107                     (cmd_l == EID_DEBUG)      ? "DEBUG":
108                     (cmd_l == EID_BADSEQ)     ? "BADSEQ":
109                     (cmd_l == EID_BADCMD)     ? "BADCMD":
110                     NULL;
111                 break;
112         default:
113                 s = NULL;
114         }
115
116         return s;
117 }
118
119 /* output of show() method should fit to PAGE_SIZE */
120 #define MBLOG_DEPTH     64
121
122 struct mblogent {
123         unsigned long jiffies;
124         mbox_msg_t msg;
125         arm_dsp_dir_t dir;
126 };
127
128 static struct {
129         spinlock_t lock;
130         int wp;
131         unsigned long cnt, cnt_ad, cnt_da;
132         struct mblogent ent[MBLOG_DEPTH];
133 } mblog = {
134         .lock = SPIN_LOCK_UNLOCKED,
135 };
136
137 #ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
138 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir)
139 {
140         const struct cmdinfo *ci = cmdinfo[mb->cmd_h];
141         char *dir_str;
142         char *subname;
143
144         dir_str = (dir == DIR_A2D) ? "sending  " : "receiving";
145         switch (ci->cmd_l_type) {
146         case CMD_L_TYPE_SUBCMD:
147                 subname = subcmd_name(mb);
148                 if (unlikely(!subname))
149                         subname = "Unknown";
150                 pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s:%s), data=%04x\n",
151                          dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
152                          ci->name, subname, mb->data);
153                 break;
154         case CMD_L_TYPE_TID:
155                 pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s:task %d), data=%04x\n",
156                          dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
157                          ci->name, mb->cmd_l, mb->data);
158                 break;
159         case CMD_L_TYPE_NULL:
160                 pr_debug("mbox: %s seq=%d, cmd=%02x:%02x(%s), data=%04x\n",
161                          dir_str, mb->seq, mb->cmd_h, mb->cmd_l,
162                          ci->name, mb->data);
163                 break;
164         }
165 }
166 #else
167 static inline void mblog_print_cmd(struct mbcmd *mb, arm_dsp_dir_t dir) { }
168 #endif
169
170 void mblog_add(struct mbcmd *mb, arm_dsp_dir_t dir)
171 {
172         struct mblogent *ent;
173
174         spin_lock(&mblog.lock);
175         ent = &mblog.ent[mblog.wp];
176         ent->jiffies = jiffies;
177         ent->msg = *(mbox_msg_t *)mb;
178         ent->dir = dir;
179         if (mblog.cnt < 0xffffffff)
180                 mblog.cnt++;
181         switch (dir) {
182         case DIR_A2D:
183                 if (mblog.cnt_ad < 0xffffffff)
184                         mblog.cnt_ad++;
185                 break;
186         case DIR_D2A:
187                 if (mblog.cnt_da < 0xffffffff)
188                         mblog.cnt_da++;
189                 break;
190         }
191         if (++mblog.wp == MBLOG_DEPTH)
192                 mblog.wp = 0;
193         spin_unlock(&mblog.lock);
194
195         mblog_print_cmd(mb, dir);
196 }
197
198 /*
199  * sysfs file
200  */
201 static ssize_t mblog_show(struct device *dev, struct device_attribute *attr,
202                           char *buf)
203 {
204         int len = 0;
205         int wp;
206         int i;
207
208         spin_lock(&mblog.lock);
209
210         wp = mblog.wp;
211         len += sprintf(buf + len,
212                        "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",
213                        mblog.cnt, mblog.cnt_ad, mblog.cnt_da);
214         if (mblog.cnt == 0)
215                 goto done;
216
217         len += sprintf(buf + len, "           ARM->DSP   ARM<-DSP\n");
218         len += sprintf(buf + len, " jiffies  cmd  data  cmd  data\n");
219         i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;
220         do {
221                 struct mblogent *ent = &mblog.ent[i];
222                 struct mbcmd *mb = (struct mbcmd *)&ent->msg;
223                 char *subname;
224                 struct cmdinfo ci_null = {
225                         .name = "Unknown",
226                         .cmd_l_type = CMD_L_TYPE_NULL,
227                 };
228                 const struct cmdinfo *ci;
229
230                 len += sprintf(buf + len,
231                                (ent->dir == DIR_A2D) ?
232                                 "%08lx  %04x %04x            ":
233                                 "%08lx             %04x %04x ",
234                                ent->jiffies,
235                                (ent->msg >> 16) & 0x7fff, ent->msg & 0xffff);
236
237                 if ((ci = cmdinfo[mb->cmd_h]) == NULL)
238                         ci = &ci_null;
239
240                 switch (ci->cmd_l_type) {
241                 case CMD_L_TYPE_SUBCMD:
242                         if ((subname = subcmd_name(mb)) == NULL)
243                                 subname = "Unknown";
244                         len += sprintf(buf + len, "%s:%s\n",
245                                        ci->name, subname);
246                         break;
247                 case CMD_L_TYPE_TID:
248                         len += sprintf(buf + len, "%s:task %d\n",
249                                        ci->name, mb->cmd_l);
250                         break;
251                 case CMD_L_TYPE_NULL:
252                         len += sprintf(buf + len, "%s\n", ci->name);
253                         break;
254                 }
255
256                 if (++i == MBLOG_DEPTH)
257                         i = 0;
258         } while (i != wp);
259
260 done:
261         spin_unlock(&mblog.lock);
262
263         return len;
264 }
265
266 static struct device_attribute dev_attr_mblog = __ATTR_RO(mblog);
267
268 void __init mblog_init(void)
269 {
270         int ret;
271
272         ret = device_create_file(omap_dsp->dev, &dev_attr_mblog);
273         if (ret)
274                 printk(KERN_ERR "device_create_file failed: %d\n", ret);
275 }
276
277 void mblog_exit(void)
278 {
279         device_remove_file(omap_dsp->dev, &dev_attr_mblog);
280 }