Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ivtv-mailbox.c
Go to the documentation of this file.
1 /*
2  mailbox functions
3  Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4  Copyright (C) 2004 Chris Kennedy <[email protected]>
5  Copyright (C) 2005-2007 Hans Verkuil <[email protected]>
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #include <stdarg.h>
23 
24 #include "ivtv-driver.h"
25 #include "ivtv-mailbox.h"
26 
27 /* Firmware mailbox flags*/
28 #define IVTV_MBOX_FIRMWARE_DONE 0x00000004
29 #define IVTV_MBOX_DRIVER_DONE 0x00000002
30 #define IVTV_MBOX_DRIVER_BUSY 0x00000001
31 #define IVTV_MBOX_FREE 0x00000000
32 
33 /* Firmware mailbox standard timeout */
34 #define IVTV_API_STD_TIMEOUT 0x02000000
35 
36 #define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */
37 #define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */
38 #define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */
39 #define API_DMA (1 << 3) /* DMA mailbox, has special handling */
40 #define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */
41 #define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */
42 #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */
43 #define API_NO_POLL (1 << 6) /* Avoid pointless polling */
44 
45 struct ivtv_api_info {
46  int flags; /* Flags, see above */
47  const char *name; /* The name of the command */
48 };
49 
50 #define API_ENTRY(x, f) [x] = { (f), #x }
51 
52 static const struct ivtv_api_info api_info[256] = {
53  /* MPEG encoder API */
95  /* Obsolete PULLDOWN API command */
96  API_ENTRY(0xb1, API_CACHE),
97 
98  /* MPEG decoder API */
113  API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/),
120 
121  /* OSD API */
143 };
144 
145 static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
146 {
147  u32 flags = readl(&mbdata->mbox[mb].flags);
148  int is_free = flags == IVTV_MBOX_FREE || (flags & IVTV_MBOX_FIRMWARE_DONE);
149 
150  /* if the mailbox is free, then try to claim it */
151  if (is_free && !test_and_set_bit(mb, &mbdata->busy)) {
152  write_sync(IVTV_MBOX_DRIVER_BUSY, &mbdata->mbox[mb].flags);
153  return 1;
154  }
155  return 0;
156 }
157 
158 /* Try to find a free mailbox. Note mailbox 0 is reserved for DMA and so is not
159  attempted here. */
160 static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int flags)
161 {
162  unsigned long then = jiffies;
163  int i, mb;
164  int max_mbox = mbdata->max_mbox;
165  int retries = 100;
166 
167  /* All slow commands use the same mailbox, serializing them and also
168  leaving the other mailbox free for simple fast commands. */
169  if ((flags & API_FAST_RESULT) == API_RESULT)
170  max_mbox = 1;
171 
172  /* find free non-DMA mailbox */
173  for (i = 0; i < retries; i++) {
174  for (mb = 1; mb <= max_mbox; mb++)
175  if (try_mailbox(itv, mbdata, mb))
176  return mb;
177 
178  /* Sleep before a retry, if not atomic */
179  if (!(flags & API_NO_WAIT_MB)) {
180  if (time_after(jiffies,
181  then + msecs_to_jiffies(10*retries)))
182  break;
183  ivtv_msleep_timeout(10, 0);
184  }
185  }
186  return -ENODEV;
187 }
188 
189 static void write_mailbox(volatile struct ivtv_mailbox __iomem *mbox, int cmd, int args, u32 data[])
190 {
191  int i;
192 
193  write_sync(cmd, &mbox->cmd);
194  write_sync(IVTV_API_STD_TIMEOUT, &mbox->timeout);
195 
196  for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
197  write_sync(data[i], &mbox->data[i]);
198 
200 }
201 
202 static void clear_all_mailboxes(struct ivtv *itv, struct ivtv_mailbox_data *mbdata)
203 {
204  int i;
205 
206  for (i = 0; i <= mbdata->max_mbox; i++) {
207  IVTV_DEBUG_WARN("Clearing mailbox %d: cmd 0x%08x flags 0x%08x\n",
208  i, readl(&mbdata->mbox[i].cmd), readl(&mbdata->mbox[i].flags));
209  write_sync(0, &mbdata->mbox[i].flags);
210  clear_bit(i, &mbdata->busy);
211  }
212 }
213 
214 static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
215 {
216  struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox;
217  volatile struct ivtv_mailbox __iomem *mbox;
218  int api_timeout = msecs_to_jiffies(1000);
219  int flags, mb, i;
220  unsigned long then;
221 
222  /* sanity checks */
223  if (NULL == mbdata) {
224  IVTV_ERR("No mailbox allocated\n");
225  return -ENODEV;
226  }
227  if (args < 0 || args > CX2341X_MBOX_MAX_DATA ||
228  cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) {
229  IVTV_ERR("Invalid MB call: cmd = 0x%02x, args = %d\n", cmd, args);
230  return -EINVAL;
231  }
232 
233  if (api_info[cmd].flags & API_HIGH_VOL) {
234  IVTV_DEBUG_HI_MB("MB Call: %s\n", api_info[cmd].name);
235  }
236  else {
237  IVTV_DEBUG_MB("MB Call: %s\n", api_info[cmd].name);
238  }
239 
240  /* clear possibly uninitialized part of data array */
241  for (i = args; i < CX2341X_MBOX_MAX_DATA; i++)
242  data[i] = 0;
243 
244  /* If this command was issued within the last 30 minutes and with identical
245  data, then just return 0 as there is no need to issue this command again.
246  Just an optimization to prevent unnecessary use of mailboxes. */
247  if (itv->api_cache[cmd].last_jiffies &&
248  time_before(jiffies,
249  itv->api_cache[cmd].last_jiffies +
250  msecs_to_jiffies(1800000)) &&
251  !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) {
252  itv->api_cache[cmd].last_jiffies = jiffies;
253  return 0;
254  }
255 
256  flags = api_info[cmd].flags;
257 
258  if (flags & API_DMA) {
259  for (i = 0; i < 100; i++) {
260  mb = i % (mbdata->max_mbox + 1);
261  if (try_mailbox(itv, mbdata, mb)) {
262  write_mailbox(&mbdata->mbox[mb], cmd, args, data);
263  clear_bit(mb, &mbdata->busy);
264  return 0;
265  }
266  IVTV_DEBUG_WARN("%s: mailbox %d not free %08x\n",
267  api_info[cmd].name, mb, readl(&mbdata->mbox[mb].flags));
268  }
269  IVTV_WARN("Could not find free DMA mailbox for %s\n", api_info[cmd].name);
270  clear_all_mailboxes(itv, mbdata);
271  return -EBUSY;
272  }
273 
274  if ((flags & API_FAST_RESULT) == API_FAST_RESULT)
275  api_timeout = msecs_to_jiffies(100);
276 
277  mb = get_mailbox(itv, mbdata, flags);
278  if (mb < 0) {
279  IVTV_DEBUG_WARN("No free mailbox found (%s)\n", api_info[cmd].name);
280  clear_all_mailboxes(itv, mbdata);
281  return -EBUSY;
282  }
283  mbox = &mbdata->mbox[mb];
284  write_mailbox(mbox, cmd, args, data);
285  if (flags & API_CACHE) {
286  memcpy(itv->api_cache[cmd].data, data, sizeof(itv->api_cache[cmd].data));
287  itv->api_cache[cmd].last_jiffies = jiffies;
288  }
289  if ((flags & API_RESULT) == 0) {
290  clear_bit(mb, &mbdata->busy);
291  return 0;
292  }
293 
294  /* Get results */
295  then = jiffies;
296 
297  if (!(flags & API_NO_POLL)) {
298  /* First try to poll, then switch to delays */
299  for (i = 0; i < 100; i++) {
300  if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)
301  break;
302  }
303  }
304  while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) {
305  if (time_after(jiffies, then + api_timeout)) {
306  IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name);
307  /* reset the mailbox, but it is likely too late already */
308  write_sync(0, &mbox->flags);
309  clear_bit(mb, &mbdata->busy);
310  return -EIO;
311  }
312  if (flags & API_NO_WAIT_RES)
313  mdelay(1);
314  else
315  ivtv_msleep_timeout(1, 0);
316  }
317  if (time_after(jiffies, then + msecs_to_jiffies(100)))
318  IVTV_DEBUG_WARN("%s took %u jiffies\n",
319  api_info[cmd].name,
320  jiffies_to_msecs(jiffies - then));
321 
322  for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
323  data[i] = readl(&mbox->data[i]);
324  write_sync(0, &mbox->flags);
325  clear_bit(mb, &mbdata->busy);
326  return 0;
327 }
328 
329 int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[])
330 {
331  int res = ivtv_api_call(itv, cmd, args, data);
332 
333  /* Allow a single retry, probably already too late though.
334  If there is no free mailbox then that is usually an indication
335  of a more serious problem. */
336  return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res;
337 }
338 
339 int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
340 {
341  return ivtv_api(priv, cmd, in, data);
342 }
343 
344 int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...)
345 {
346  va_list ap;
347  int i;
348 
349  va_start(ap, args);
350  for (i = 0; i < args; i++) {
351  data[i] = va_arg(ap, u32);
352  }
353  va_end(ap);
354  return ivtv_api(itv, cmd, args, data);
355 }
356 
357 int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
358 {
360  va_list ap;
361  int i;
362 
363  va_start(ap, args);
364  for (i = 0; i < args; i++) {
365  data[i] = va_arg(ap, u32);
366  }
367  va_end(ap);
368  return ivtv_api(itv, cmd, args, data);
369 }
370 
371 /* This one is for stuff that can't sleep.. irq handlers, etc.. */
372 void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
373  int argc, u32 data[])
374 {
375  volatile u32 __iomem *p = mbdata->mbox[mb].data;
376  int i;
377  for (i = 0; i < argc; i++, p++)
378  data[i] = readl(p);
379 }
380 
381 /* Wipe api cache */
383 {
384  int i;
385  for (i = 0; i < 256; i++)
386  itv->api_cache[i].last_jiffies = 0;
387 }