xfs: remote attributes need to be considered data
[linux-drm-fsl-dcu.git] / drivers / media / pci / ivtv / ivtvfb.c
1 /*
2     On Screen Display cx23415 Framebuffer driver
3
4     This module presents the cx23415 OSD (onscreen display) framebuffer memory
5     as a standard Linux /dev/fb style framebuffer device. The framebuffer has
6     support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
7     mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
8     local alpha. The colorspace is selectable between rgb & yuv.
9     Depending on the TV standard configured in the ivtv module at load time,
10     the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
11     Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
12     or 59.94 (NTSC)
13
14     Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
15
16     Derived from drivers/video/vesafb.c
17     Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
18
19     2.6 kernel port:
20     Copyright (C) 2004 Matthias Badaire
21
22     Copyright (C) 2004  Chris Kennedy <c@groovy.org>
23
24     Copyright (C) 2006  Ian Armstrong <ian@iarmst.demon.co.uk>
25
26     This program is free software; you can redistribute it and/or modify
27     it under the terms of the GNU General Public License as published by
28     the Free Software Foundation; either version 2 of the License, or
29     (at your option) any later version.
30
31     This program is distributed in the hope that it will be useful,
32     but WITHOUT ANY WARRANTY; without even the implied warranty of
33     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34     GNU General Public License for more details.
35
36     You should have received a copy of the GNU General Public License
37     along with this program; if not, write to the Free Software
38     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
39  */
40
41 #include <linux/module.h>
42 #include <linux/kernel.h>
43 #include <linux/fb.h>
44 #include <linux/ivtvfb.h>
45 #include <linux/slab.h>
46
47 #ifdef CONFIG_X86_64
48 #include <asm/pat.h>
49 #endif
50
51 #include "ivtv-driver.h"
52 #include "ivtv-cards.h"
53 #include "ivtv-i2c.h"
54 #include "ivtv-udma.h"
55 #include "ivtv-mailbox.h"
56 #include "ivtv-firmware.h"
57
58 /* card parameters */
59 static int ivtvfb_card_id = -1;
60 static int ivtvfb_debug = 0;
61 static bool osd_laced;
62 static int osd_depth;
63 static int osd_upper;
64 static int osd_left;
65 static int osd_yres;
66 static int osd_xres;
67
68 module_param(ivtvfb_card_id, int, 0444);
69 module_param_named(debug,ivtvfb_debug, int, 0644);
70 module_param(osd_laced, bool, 0444);
71 module_param(osd_depth, int, 0444);
72 module_param(osd_upper, int, 0444);
73 module_param(osd_left, int, 0444);
74 module_param(osd_yres, int, 0444);
75 module_param(osd_xres, int, 0444);
76
77 MODULE_PARM_DESC(ivtvfb_card_id,
78                  "Only use framebuffer of the specified ivtv card (0-31)\n"
79                  "\t\t\tdefault -1: initialize all available framebuffers");
80
81 MODULE_PARM_DESC(debug,
82                  "Debug level (bitmask). Default: errors only\n"
83                  "\t\t\t(debug = 3 gives full debugging)");
84
85 /* Why upper, left, xres, yres, depth, laced ? To match terminology used
86    by fbset.
87    Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
88
89 MODULE_PARM_DESC(osd_laced,
90                  "Interlaced mode\n"
91                  "\t\t\t0=off\n"
92                  "\t\t\t1=on\n"
93                  "\t\t\tdefault off");
94
95 MODULE_PARM_DESC(osd_depth,
96                  "Bits per pixel - 8, 16, 32\n"
97                  "\t\t\tdefault 8");
98
99 MODULE_PARM_DESC(osd_upper,
100                  "Vertical start position\n"
101                  "\t\t\tdefault 0 (Centered)");
102
103 MODULE_PARM_DESC(osd_left,
104                  "Horizontal start position\n"
105                  "\t\t\tdefault 0 (Centered)");
106
107 MODULE_PARM_DESC(osd_yres,
108                  "Display height\n"
109                  "\t\t\tdefault 480 (PAL)\n"
110                  "\t\t\t        400 (NTSC)");
111
112 MODULE_PARM_DESC(osd_xres,
113                  "Display width\n"
114                  "\t\t\tdefault 640");
115
116 MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
117 MODULE_LICENSE("GPL");
118
119 /* --------------------------------------------------------------------- */
120
121 #define IVTVFB_DBGFLG_WARN  (1 << 0)
122 #define IVTVFB_DBGFLG_INFO  (1 << 1)
123
124 #define IVTVFB_DEBUG(x, type, fmt, args...) \
125         do { \
126                 if ((x) & ivtvfb_debug) \
127                         printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
128         } while (0)
129 #define IVTVFB_DEBUG_WARN(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
130 #define IVTVFB_DEBUG_INFO(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
131
132 /* Standard kernel messages */
133 #define IVTVFB_ERR(fmt, args...)   printk(KERN_ERR  "ivtvfb%d: " fmt, itv->instance , ## args)
134 #define IVTVFB_WARN(fmt, args...)  printk(KERN_WARNING  "ivtvfb%d: " fmt, itv->instance , ## args)
135 #define IVTVFB_INFO(fmt, args...)  printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
136
137 /* --------------------------------------------------------------------- */
138
139 #define IVTV_OSD_MAX_WIDTH  720
140 #define IVTV_OSD_MAX_HEIGHT 576
141
142 #define IVTV_OSD_BPP_8      0x00
143 #define IVTV_OSD_BPP_16_444 0x03
144 #define IVTV_OSD_BPP_16_555 0x02
145 #define IVTV_OSD_BPP_16_565 0x01
146 #define IVTV_OSD_BPP_32     0x04
147
148 struct osd_info {
149         /* Physical base address */
150         unsigned long video_pbase;
151         /* Relative base address (relative to start of decoder memory) */
152         u32 video_rbase;
153         /* Mapped base address */
154         volatile char __iomem *video_vbase;
155         /* Buffer size */
156         u32 video_buffer_size;
157
158         /* video_base rounded down as required by hardware MTRRs */
159         unsigned long fb_start_aligned_physaddr;
160         /* video_base rounded up as required by hardware MTRRs */
161         unsigned long fb_end_aligned_physaddr;
162         int wc_cookie;
163
164         /* Store the buffer offset */
165         int set_osd_coords_x;
166         int set_osd_coords_y;
167
168         /* Current dimensions (NOT VISIBLE SIZE!) */
169         int display_width;
170         int display_height;
171         int display_byte_stride;
172
173         /* Current bits per pixel */
174         int bits_per_pixel;
175         int bytes_per_pixel;
176
177         /* Frame buffer stuff */
178         struct fb_info ivtvfb_info;
179         struct fb_var_screeninfo ivtvfb_defined;
180         struct fb_fix_screeninfo ivtvfb_fix;
181
182         /* Used for a warm start */
183         struct fb_var_screeninfo fbvar_cur;
184         int blank_cur;
185         u32 palette_cur[256];
186         u32 pan_cur;
187 };
188
189 struct ivtv_osd_coords {
190         unsigned long offset;
191         unsigned long max_offset;
192         int pixel_stride;
193         int lines;
194         int x;
195         int y;
196 };
197
198 /* --------------------------------------------------------------------- */
199
200 /* ivtv API calls for framebuffer related support */
201
202 static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
203                                        u32 *fblength)
204 {
205         u32 data[CX2341X_MBOX_MAX_DATA];
206         int rc;
207
208         ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
209         rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
210         *fbbase = data[0];
211         *fblength = data[1];
212         return rc;
213 }
214
215 static int ivtvfb_get_osd_coords(struct ivtv *itv,
216                                       struct ivtv_osd_coords *osd)
217 {
218         struct osd_info *oi = itv->osd_info;
219         u32 data[CX2341X_MBOX_MAX_DATA];
220
221         ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
222
223         osd->offset = data[0] - oi->video_rbase;
224         osd->max_offset = oi->display_width * oi->display_height * 4;
225         osd->pixel_stride = data[1];
226         osd->lines = data[2];
227         osd->x = data[3];
228         osd->y = data[4];
229         return 0;
230 }
231
232 static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
233 {
234         struct osd_info *oi = itv->osd_info;
235
236         oi->display_width = osd->pixel_stride;
237         oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
238         oi->set_osd_coords_x += osd->x;
239         oi->set_osd_coords_y = osd->y;
240
241         return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
242                         osd->offset + oi->video_rbase,
243                         osd->pixel_stride,
244                         osd->lines, osd->x, osd->y);
245 }
246
247 static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
248 {
249         int osd_height_limit = itv->is_out_50hz ? 576 : 480;
250
251         /* Only fail if resolution too high, otherwise fudge the start coords. */
252         if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
253                 return -EINVAL;
254
255         /* Ensure we don't exceed display limits */
256         if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
257                 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
258                         ivtv_window->top, ivtv_window->height);
259                 ivtv_window->top = osd_height_limit - ivtv_window->height;
260         }
261
262         if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
263                 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
264                         ivtv_window->left, ivtv_window->width);
265                 ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
266         }
267
268         /* Set the OSD origin */
269         write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
270
271         /* How much to display */
272         write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
273
274         /* Pass this info back the yuv handler */
275         itv->yuv_info.osd_vis_w = ivtv_window->width;
276         itv->yuv_info.osd_vis_h = ivtv_window->height;
277         itv->yuv_info.osd_x_offset = ivtv_window->left;
278         itv->yuv_info.osd_y_offset = ivtv_window->top;
279
280         return 0;
281 }
282
283 static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
284                                   unsigned long ivtv_dest_addr, void __user *userbuf,
285                                   int size_in_bytes)
286 {
287         DEFINE_WAIT(wait);
288         int got_sig = 0;
289
290         mutex_lock(&itv->udma.lock);
291         /* Map User DMA */
292         if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
293                 mutex_unlock(&itv->udma.lock);
294                 IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, "
295                                "Error with get_user_pages: %d bytes, %d pages returned\n",
296                                size_in_bytes, itv->udma.page_count);
297
298                 /* get_user_pages must have failed completely */
299                 return -EIO;
300         }
301
302         IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n",
303                        size_in_bytes, itv->udma.page_count);
304
305         ivtv_udma_prepare(itv);
306         prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
307         /* if no UDMA is pending and no UDMA is in progress, then the DMA
308            is finished */
309         while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
310                test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
311                 /* don't interrupt if the DMA is in progress but break off
312                    a still pending DMA. */
313                 got_sig = signal_pending(current);
314                 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
315                         break;
316                 got_sig = 0;
317                 schedule();
318         }
319         finish_wait(&itv->dma_waitq, &wait);
320
321         /* Unmap Last DMA Xfer */
322         ivtv_udma_unmap(itv);
323         mutex_unlock(&itv->udma.lock);
324         if (got_sig) {
325                 IVTV_DEBUG_INFO("User stopped OSD\n");
326                 return -EINTR;
327         }
328
329         return 0;
330 }
331
332 static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
333                               unsigned long dest_offset, int count)
334 {
335         DEFINE_WAIT(wait);
336         struct osd_info *oi = itv->osd_info;
337
338         /* Nothing to do */
339         if (count == 0) {
340                 IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n");
341                 return -EINVAL;
342         }
343
344         /* Check Total FB Size */
345         if ((dest_offset + count) > oi->video_buffer_size) {
346                 IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
347                         dest_offset + count, oi->video_buffer_size);
348                 return -E2BIG;
349         }
350
351         /* Not fatal, but will have undesirable results */
352         if ((unsigned long)source & 3)
353                 IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",
354                         (unsigned long)source);
355
356         if (dest_offset & 3)
357                 IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
358
359         if (count & 3)
360                 IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
361
362         /* Check Source */
363         if (!access_ok(VERIFY_READ, source + dest_offset, count)) {
364                 IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
365                         (unsigned long)source);
366
367                 IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
368                         dest_offset, (unsigned long)source,
369                         count);
370                 return -EINVAL;
371         }
372
373         /* OSD Address to send DMA to */
374         dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
375
376         /* Fill Buffers */
377         return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
378 }
379
380 static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
381                                                 size_t count, loff_t *ppos)
382 {
383         unsigned long p = *ppos;
384         void *dst;
385         int err = 0;
386         int dma_err;
387         unsigned long total_size;
388         struct ivtv *itv = (struct ivtv *) info->par;
389         unsigned long dma_offset =
390                         IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
391         unsigned long dma_size;
392         u16 lead = 0, tail = 0;
393
394         if (info->state != FBINFO_STATE_RUNNING)
395                 return -EPERM;
396
397         total_size = info->screen_size;
398
399         if (total_size == 0)
400                 total_size = info->fix.smem_len;
401
402         if (p > total_size)
403                 return -EFBIG;
404
405         if (count > total_size) {
406                 err = -EFBIG;
407                 count = total_size;
408         }
409
410         if (count + p > total_size) {
411                 if (!err)
412                         err = -ENOSPC;
413                 count = total_size - p;
414         }
415
416         dst = (void __force *) (info->screen_base + p);
417
418         if (info->fbops->fb_sync)
419                 info->fbops->fb_sync(info);
420
421         /* If transfer size > threshold and both src/dst
422         addresses are aligned, use DMA */
423         if (count >= 4096 &&
424             ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
425                 /* Odd address = can't DMA. Align */
426                 if ((unsigned long)dst & 3) {
427                         lead = 4 - ((unsigned long)dst & 3);
428                         if (copy_from_user(dst, buf, lead))
429                                 return -EFAULT;
430                         buf += lead;
431                         dst += lead;
432                 }
433                 /* DMA resolution is 32 bits */
434                 if ((count - lead) & 3)
435                         tail = (count - lead) & 3;
436                 /* DMA the data */
437                 dma_size = count - lead - tail;
438                 dma_err = ivtvfb_prep_dec_dma_to_device(itv,
439                        p + lead + dma_offset, (void __user *)buf, dma_size);
440                 if (dma_err)
441                         return dma_err;
442                 dst += dma_size;
443                 buf += dma_size;
444                 /* Copy any leftover data */
445                 if (tail && copy_from_user(dst, buf, tail))
446                         return -EFAULT;
447         } else if (copy_from_user(dst, buf, count)) {
448                 return -EFAULT;
449         }
450
451         if  (!err)
452                 *ppos += count;
453
454         return (err) ? err : count;
455 }
456
457 static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
458 {
459         DEFINE_WAIT(wait);
460         struct ivtv *itv = (struct ivtv *)info->par;
461         int rc = 0;
462
463         switch (cmd) {
464                 case FBIOGET_VBLANK: {
465                         struct fb_vblank vblank;
466                         u32 trace;
467
468                         memset(&vblank, 0, sizeof(struct fb_vblank));
469
470                         vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
471                                         FB_VBLANK_HAVE_VSYNC;
472                         trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
473                         if (itv->is_out_50hz && trace > 312)
474                                 trace -= 312;
475                         else if (itv->is_out_60hz && trace > 262)
476                                 trace -= 262;
477                         if (trace == 1)
478                                 vblank.flags |= FB_VBLANK_VSYNCING;
479                         vblank.count = itv->last_vsync_field;
480                         vblank.vcount = trace;
481                         vblank.hcount = 0;
482                         if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
483                                 return -EFAULT;
484                         return 0;
485                 }
486
487                 case FBIO_WAITFORVSYNC:
488                         prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
489                         if (!schedule_timeout(msecs_to_jiffies(50)))
490                                 rc = -ETIMEDOUT;
491                         finish_wait(&itv->vsync_waitq, &wait);
492                         return rc;
493
494                 case IVTVFB_IOC_DMA_FRAME: {
495                         struct ivtvfb_dma_frame args;
496
497                         IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
498                         if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
499                                 return -EFAULT;
500
501                         return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
502                 }
503
504                 default:
505                         IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
506                         return -EINVAL;
507         }
508         return 0;
509 }
510
511 /* Framebuffer device handling */
512
513 static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
514 {
515         struct osd_info *oi = itv->osd_info;
516         struct ivtv_osd_coords ivtv_osd;
517         struct v4l2_rect ivtv_window;
518         int osd_mode = -1;
519
520         IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
521
522         /* Select color space */
523         if (var->nonstd) /* YUV */
524                 write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
525         else /* RGB  */
526                 write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
527
528         /* Set the color mode */
529         switch (var->bits_per_pixel) {
530                 case 8:
531                         osd_mode = IVTV_OSD_BPP_8;
532                         break;
533                 case 32:
534                         osd_mode = IVTV_OSD_BPP_32;
535                         break;
536                 case 16:
537                         switch (var->green.length) {
538                         case 4:
539                                 osd_mode = IVTV_OSD_BPP_16_444;
540                                 break;
541                         case 5:
542                                 osd_mode = IVTV_OSD_BPP_16_555;
543                                 break;
544                         case 6:
545                                 osd_mode = IVTV_OSD_BPP_16_565;
546                                 break;
547                         default:
548                                 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
549                         }
550                         break;
551                 default:
552                         IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
553         }
554
555         /* Set video mode. Although rare, the display can become scrambled even
556            if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
557         if (osd_mode != -1) {
558                 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
559                 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
560         }
561
562         oi->bits_per_pixel = var->bits_per_pixel;
563         oi->bytes_per_pixel = var->bits_per_pixel / 8;
564
565         /* Set the flicker filter */
566         switch (var->vmode & FB_VMODE_MASK) {
567                 case FB_VMODE_NONINTERLACED: /* Filter on */
568                         ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
569                         break;
570                 case FB_VMODE_INTERLACED: /* Filter off */
571                         ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
572                         break;
573                 default:
574                         IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
575         }
576
577         /* Read the current osd info */
578         ivtvfb_get_osd_coords(itv, &ivtv_osd);
579
580         /* Now set the OSD to the size we want */
581         ivtv_osd.pixel_stride = var->xres_virtual;
582         ivtv_osd.lines = var->yres_virtual;
583         ivtv_osd.x = 0;
584         ivtv_osd.y = 0;
585         ivtvfb_set_osd_coords(itv, &ivtv_osd);
586
587         /* Can't seem to find the right API combo for this.
588            Use another function which does what we need through direct register access. */
589         ivtv_window.width = var->xres;
590         ivtv_window.height = var->yres;
591
592         /* Minimum margin cannot be 0, as X won't allow such a mode */
593         if (!var->upper_margin)
594                 var->upper_margin++;
595         if (!var->left_margin)
596                 var->left_margin++;
597         ivtv_window.top = var->upper_margin - 1;
598         ivtv_window.left = var->left_margin - 1;
599
600         ivtvfb_set_display_window(itv, &ivtv_window);
601
602         /* Pass screen size back to yuv handler */
603         itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride;
604         itv->yuv_info.osd_full_h = ivtv_osd.lines;
605
606         /* Force update of yuv registers */
607         itv->yuv_info.yuv_forced_update = 1;
608
609         /* Keep a copy of these settings */
610         memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
611
612         IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
613                       var->xres, var->yres,
614                       var->xres_virtual, var->yres_virtual,
615                       var->bits_per_pixel);
616
617         IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
618                       var->left_margin, var->upper_margin);
619
620         IVTVFB_DEBUG_INFO("Display filter: %s\n",
621                         (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
622         IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
623
624         return 0;
625 }
626
627 static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
628 {
629         struct osd_info *oi = itv->osd_info;
630
631         IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
632         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
633         strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
634         fix->smem_start = oi->video_pbase;
635         fix->smem_len = oi->video_buffer_size;
636         fix->type = FB_TYPE_PACKED_PIXELS;
637         fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
638         fix->xpanstep = 1;
639         fix->ypanstep = 1;
640         fix->ywrapstep = 0;
641         fix->line_length = oi->display_byte_stride;
642         fix->accel = FB_ACCEL_NONE;
643         return 0;
644 }
645
646 /* Check the requested display mode, returning -EINVAL if we can't
647    handle it. */
648
649 static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
650 {
651         struct osd_info *oi = itv->osd_info;
652         int osd_height_limit;
653         u32 pixclock, hlimit, vlimit;
654
655         IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
656
657         /* Set base references for mode calcs. */
658         if (itv->is_out_50hz) {
659                 pixclock = 84316;
660                 hlimit = 776;
661                 vlimit = 591;
662                 osd_height_limit = 576;
663         }
664         else {
665                 pixclock = 83926;
666                 hlimit = 776;
667                 vlimit = 495;
668                 osd_height_limit = 480;
669         }
670
671         if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
672                 var->transp.offset = 24;
673                 var->transp.length = 8;
674                 var->red.offset = 16;
675                 var->red.length = 8;
676                 var->green.offset = 8;
677                 var->green.length = 8;
678                 var->blue.offset = 0;
679                 var->blue.length = 8;
680         }
681         else if (var->bits_per_pixel == 16) {
682                 /* To find out the true mode, check green length */
683                 switch (var->green.length) {
684                         case 4:
685                                 var->red.offset = 8;
686                                 var->red.length = 4;
687                                 var->green.offset = 4;
688                                 var->green.length = 4;
689                                 var->blue.offset = 0;
690                                 var->blue.length = 4;
691                                 var->transp.offset = 12;
692                                 var->transp.length = 1;
693                                 break;
694                         case 5:
695                                 var->red.offset = 10;
696                                 var->red.length = 5;
697                                 var->green.offset = 5;
698                                 var->green.length = 5;
699                                 var->blue.offset = 0;
700                                 var->blue.length = 5;
701                                 var->transp.offset = 15;
702                                 var->transp.length = 1;
703                                 break;
704                         default:
705                                 var->red.offset = 11;
706                                 var->red.length = 5;
707                                 var->green.offset = 5;
708                                 var->green.length = 6;
709                                 var->blue.offset = 0;
710                                 var->blue.length = 5;
711                                 var->transp.offset = 0;
712                                 var->transp.length = 0;
713                                 break;
714                 }
715         }
716         else {
717                 IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
718                 return -EINVAL;
719         }
720
721         /* Check the resolution */
722         if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
723                 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
724                                 var->xres, var->yres);
725                 return -EINVAL;
726         }
727
728         /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
729         if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
730             var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
731             var->xres_virtual < var->xres ||
732             var->yres_virtual < var->yres) {
733                 IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
734                         var->xres_virtual, var->yres_virtual);
735                 return -EINVAL;
736         }
737
738         /* Some extra checks if in 8 bit mode */
739         if (var->bits_per_pixel == 8) {
740                 /* Width must be a multiple of 4 */
741                 if (var->xres & 3) {
742                         IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
743                         return -EINVAL;
744                 }
745                 if (var->xres_virtual & 3) {
746                         IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
747                         return -EINVAL;
748                 }
749         }
750         else if (var->bits_per_pixel == 16) {
751                 /* Width must be a multiple of 2 */
752                 if (var->xres & 1) {
753                         IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
754                         return -EINVAL;
755                 }
756                 if (var->xres_virtual & 1) {
757                         IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
758                         return -EINVAL;
759                 }
760         }
761
762         /* Now check the offsets */
763         if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
764                 IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
765                         var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
766                 return -EINVAL;
767         }
768
769         /* Check pixel format */
770         if (var->nonstd > 1) {
771                 IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
772                 return -EINVAL;
773         }
774
775         /* Check video mode */
776         if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
777                 ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
778                 IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
779                 return -EINVAL;
780         }
781
782         /* Check the left & upper margins
783            If the margins are too large, just center the screen
784            (enforcing margins causes too many problems) */
785
786         if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
787                 var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
788
789         if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
790                 var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
791                         var->yres) / 2);
792
793         /* Maintain overall 'size' for a constant refresh rate */
794         var->right_margin = hlimit - var->left_margin - var->xres;
795         var->lower_margin = vlimit - var->upper_margin - var->yres;
796
797         /* Fixed sync times */
798         var->hsync_len = 24;
799         var->vsync_len = 2;
800
801         /* Non-interlaced / interlaced mode is used to switch the OSD filter
802            on or off. Adjust the clock timings to maintain a constant
803            vertical refresh rate. */
804         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
805                 var->pixclock = pixclock / 2;
806         else
807                 var->pixclock = pixclock;
808
809         itv->osd_rect.width = var->xres;
810         itv->osd_rect.height = var->yres;
811
812         IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
813                       var->xres, var->yres,
814                       var->xres_virtual, var->yres_virtual,
815                       var->bits_per_pixel);
816
817         IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
818                       var->left_margin, var->upper_margin);
819
820         IVTVFB_DEBUG_INFO("Display filter: %s\n",
821                         (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
822         IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
823         return 0;
824 }
825
826 static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
827 {
828         struct ivtv *itv = (struct ivtv *) info->par;
829         IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
830         return _ivtvfb_check_var(var, itv);
831 }
832
833 static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
834 {
835         u32 osd_pan_index;
836         struct ivtv *itv = (struct ivtv *) info->par;
837
838         if (var->yoffset + info->var.yres > info->var.yres_virtual ||
839             var->xoffset + info->var.xres > info->var.xres_virtual)
840                 return -EINVAL;
841
842         osd_pan_index = var->yoffset * info->fix.line_length
843                       + var->xoffset * info->var.bits_per_pixel / 8;
844         write_reg(osd_pan_index, 0x02A0C);
845
846         /* Pass this info back the yuv handler */
847         itv->yuv_info.osd_x_pan = var->xoffset;
848         itv->yuv_info.osd_y_pan = var->yoffset;
849         /* Force update of yuv registers */
850         itv->yuv_info.yuv_forced_update = 1;
851         /* Remember this value */
852         itv->osd_info->pan_cur = osd_pan_index;
853         return 0;
854 }
855
856 static int ivtvfb_set_par(struct fb_info *info)
857 {
858         int rc = 0;
859         struct ivtv *itv = (struct ivtv *) info->par;
860
861         IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
862
863         rc = ivtvfb_set_var(itv, &info->var);
864         ivtvfb_pan_display(&info->var, info);
865         ivtvfb_get_fix(itv, &info->fix);
866         ivtv_firmware_check(itv, "ivtvfb_set_par");
867         return rc;
868 }
869
870 static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
871                                 unsigned blue, unsigned transp,
872                                 struct fb_info *info)
873 {
874         u32 color, *palette;
875         struct ivtv *itv = (struct ivtv *)info->par;
876
877         if (regno >= info->cmap.len)
878                 return -EINVAL;
879
880         color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
881         if (info->var.bits_per_pixel <= 8) {
882                 write_reg(regno, 0x02a30);
883                 write_reg(color, 0x02a34);
884                 itv->osd_info->palette_cur[regno] = color;
885                 return 0;
886         }
887         if (regno >= 16)
888                 return -EINVAL;
889
890         palette = info->pseudo_palette;
891         if (info->var.bits_per_pixel == 16) {
892                 switch (info->var.green.length) {
893                         case 4:
894                                 color = ((red & 0xf000) >> 4) |
895                                         ((green & 0xf000) >> 8) |
896                                         ((blue & 0xf000) >> 12);
897                                 break;
898                         case 5:
899                                 color = ((red & 0xf800) >> 1) |
900                                         ((green & 0xf800) >> 6) |
901                                         ((blue & 0xf800) >> 11);
902                                 break;
903                         case 6:
904                                 color = (red & 0xf800 ) |
905                                         ((green & 0xfc00) >> 5) |
906                                         ((blue & 0xf800) >> 11);
907                                 break;
908                 }
909         }
910         palette[regno] = color;
911         return 0;
912 }
913
914 /* We don't really support blanking. All this does is enable or
915    disable the OSD. */
916 static int ivtvfb_blank(int blank_mode, struct fb_info *info)
917 {
918         struct ivtv *itv = (struct ivtv *)info->par;
919
920         IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
921         switch (blank_mode) {
922         case FB_BLANK_UNBLANK:
923                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
924                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
925                 break;
926         case FB_BLANK_NORMAL:
927         case FB_BLANK_HSYNC_SUSPEND:
928         case FB_BLANK_VSYNC_SUSPEND:
929                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
930                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
931                 break;
932         case FB_BLANK_POWERDOWN:
933                 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
934                 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
935                 break;
936         }
937         itv->osd_info->blank_cur = blank_mode;
938         return 0;
939 }
940
941 static struct fb_ops ivtvfb_ops = {
942         .owner = THIS_MODULE,
943         .fb_write       = ivtvfb_write,
944         .fb_check_var   = ivtvfb_check_var,
945         .fb_set_par     = ivtvfb_set_par,
946         .fb_setcolreg   = ivtvfb_setcolreg,
947         .fb_fillrect    = cfb_fillrect,
948         .fb_copyarea    = cfb_copyarea,
949         .fb_imageblit   = cfb_imageblit,
950         .fb_cursor      = NULL,
951         .fb_ioctl       = ivtvfb_ioctl,
952         .fb_pan_display = ivtvfb_pan_display,
953         .fb_blank       = ivtvfb_blank,
954 };
955
956 /* Restore hardware after firmware restart */
957 static void ivtvfb_restore(struct ivtv *itv)
958 {
959         struct osd_info *oi = itv->osd_info;
960         int i;
961
962         ivtvfb_set_var(itv, &oi->fbvar_cur);
963         ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
964         for (i = 0; i < 256; i++) {
965                 write_reg(i, 0x02a30);
966                 write_reg(oi->palette_cur[i], 0x02a34);
967         }
968         write_reg(oi->pan_cur, 0x02a0c);
969 }
970
971 /* Initialization */
972
973
974 /* Setup our initial video mode */
975 static int ivtvfb_init_vidmode(struct ivtv *itv)
976 {
977         struct osd_info *oi = itv->osd_info;
978         struct v4l2_rect start_window;
979         int max_height;
980
981         /* Color mode */
982
983         if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
984                 osd_depth = 8;
985         oi->bits_per_pixel = osd_depth;
986         oi->bytes_per_pixel = oi->bits_per_pixel / 8;
987
988         /* Horizontal size & position */
989
990         if (osd_xres > 720)
991                 osd_xres = 720;
992
993         /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
994         if (osd_depth == 8)
995                 osd_xres &= ~3;
996         else if (osd_depth == 16)
997                 osd_xres &= ~1;
998
999         start_window.width = osd_xres ? osd_xres : 640;
1000
1001         /* Check horizontal start (osd_left). */
1002         if (osd_left && osd_left + start_window.width > 721) {
1003                 IVTVFB_ERR("Invalid osd_left - assuming default\n");
1004                 osd_left = 0;
1005         }
1006
1007         /* Hardware coords start at 0, user coords start at 1. */
1008         osd_left--;
1009
1010         start_window.left = osd_left >= 0 ?
1011                  osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
1012
1013         oi->display_byte_stride =
1014                         start_window.width * oi->bytes_per_pixel;
1015
1016         /* Vertical size & position */
1017
1018         max_height = itv->is_out_50hz ? 576 : 480;
1019
1020         if (osd_yres > max_height)
1021                 osd_yres = max_height;
1022
1023         start_window.height = osd_yres ?
1024                 osd_yres : itv->is_out_50hz ? 480 : 400;
1025
1026         /* Check vertical start (osd_upper). */
1027         if (osd_upper + start_window.height > max_height + 1) {
1028                 IVTVFB_ERR("Invalid osd_upper - assuming default\n");
1029                 osd_upper = 0;
1030         }
1031
1032         /* Hardware coords start at 0, user coords start at 1. */
1033         osd_upper--;
1034
1035         start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
1036
1037         oi->display_width = start_window.width;
1038         oi->display_height = start_window.height;
1039
1040         /* Generate a valid fb_var_screeninfo */
1041
1042         oi->ivtvfb_defined.xres = oi->display_width;
1043         oi->ivtvfb_defined.yres = oi->display_height;
1044         oi->ivtvfb_defined.xres_virtual = oi->display_width;
1045         oi->ivtvfb_defined.yres_virtual = oi->display_height;
1046         oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
1047         oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
1048         oi->ivtvfb_defined.left_margin = start_window.left + 1;
1049         oi->ivtvfb_defined.upper_margin = start_window.top + 1;
1050         oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
1051         oi->ivtvfb_defined.nonstd = 0;
1052
1053         /* We've filled in the most data, let the usual mode check
1054            routine fill in the rest. */
1055         _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
1056
1057         /* Generate valid fb_fix_screeninfo */
1058
1059         ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
1060
1061         /* Generate valid fb_info */
1062
1063         oi->ivtvfb_info.node = -1;
1064         oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
1065         oi->ivtvfb_info.fbops = &ivtvfb_ops;
1066         oi->ivtvfb_info.par = itv;
1067         oi->ivtvfb_info.var = oi->ivtvfb_defined;
1068         oi->ivtvfb_info.fix = oi->ivtvfb_fix;
1069         oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
1070         oi->ivtvfb_info.fbops = &ivtvfb_ops;
1071
1072         /* Supply some monitor specs. Bogus values will do for now */
1073         oi->ivtvfb_info.monspecs.hfmin = 8000;
1074         oi->ivtvfb_info.monspecs.hfmax = 70000;
1075         oi->ivtvfb_info.monspecs.vfmin = 10;
1076         oi->ivtvfb_info.monspecs.vfmax = 100;
1077
1078         /* Allocate color map */
1079         if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
1080                 IVTVFB_ERR("abort, unable to alloc cmap\n");
1081                 return -ENOMEM;
1082         }
1083
1084         /* Allocate the pseudo palette */
1085         oi->ivtvfb_info.pseudo_palette =
1086                 kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
1087
1088         if (!oi->ivtvfb_info.pseudo_palette) {
1089                 IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
1090                 return -ENOMEM;
1091         }
1092
1093         return 0;
1094 }
1095
1096 /* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
1097
1098 static int ivtvfb_init_io(struct ivtv *itv)
1099 {
1100         struct osd_info *oi = itv->osd_info;
1101         /* Find the largest power of two that maps the whole buffer */
1102         int size_shift = 31;
1103
1104         mutex_lock(&itv->serialize_lock);
1105         if (ivtv_init_on_first_open(itv)) {
1106                 mutex_unlock(&itv->serialize_lock);
1107                 IVTVFB_ERR("Failed to initialize ivtv\n");
1108                 return -ENXIO;
1109         }
1110         mutex_unlock(&itv->serialize_lock);
1111
1112         if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1113                                         &oi->video_buffer_size) < 0) {
1114                 IVTVFB_ERR("Firmware failed to respond\n");
1115                 return -EIO;
1116         }
1117
1118         /* The osd buffer size depends on the number of video buffers allocated
1119            on the PVR350 itself. For now we'll hardcode the smallest osd buffer
1120            size to prevent any overlap. */
1121         oi->video_buffer_size = 1704960;
1122
1123         oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
1124         oi->video_vbase = itv->dec_mem + oi->video_rbase;
1125
1126         if (!oi->video_vbase) {
1127                 IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1128                      oi->video_buffer_size, oi->video_pbase);
1129                 return -EIO;
1130         }
1131
1132         IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1133                         oi->video_pbase, oi->video_vbase,
1134                         oi->video_buffer_size / 1024);
1135
1136         while (!(oi->video_buffer_size & (1 << size_shift)))
1137                 size_shift--;
1138         size_shift++;
1139         oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1140         oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1141         oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1142         oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1143         oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr,
1144                                          oi->fb_end_aligned_physaddr -
1145                                          oi->fb_start_aligned_physaddr);
1146         /* Blank the entire osd. */
1147         memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1148
1149         return 0;
1150 }
1151
1152 /* Release any memory we've grabbed & remove mtrr entry */
1153 static void ivtvfb_release_buffers (struct ivtv *itv)
1154 {
1155         struct osd_info *oi = itv->osd_info;
1156
1157         /* Release cmap */
1158         if (oi->ivtvfb_info.cmap.len)
1159                 fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1160
1161         /* Release pseudo palette */
1162         kfree(oi->ivtvfb_info.pseudo_palette);
1163         arch_phys_wc_del(oi->wc_cookie);
1164         kfree(oi);
1165         itv->osd_info = NULL;
1166 }
1167
1168 /* Initialize the specified card */
1169
1170 static int ivtvfb_init_card(struct ivtv *itv)
1171 {
1172         int rc;
1173
1174         if (itv->osd_info) {
1175                 IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
1176                 return -EBUSY;
1177         }
1178
1179         itv->osd_info = kzalloc(sizeof(struct osd_info),
1180                                         GFP_ATOMIC|__GFP_NOWARN);
1181         if (itv->osd_info == NULL) {
1182                 IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1183                 return -ENOMEM;
1184         }
1185
1186         /* Find & setup the OSD buffer */
1187         rc = ivtvfb_init_io(itv);
1188         if (rc) {
1189                 ivtvfb_release_buffers(itv);
1190                 return rc;
1191         }
1192
1193         /* Set the startup video mode information */
1194         if ((rc = ivtvfb_init_vidmode(itv))) {
1195                 ivtvfb_release_buffers(itv);
1196                 return rc;
1197         }
1198
1199         /* Register the framebuffer */
1200         if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
1201                 ivtvfb_release_buffers(itv);
1202                 return -EINVAL;
1203         }
1204
1205         itv->osd_video_pbase = itv->osd_info->video_pbase;
1206
1207         /* Set the card to the requested mode */
1208         ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
1209
1210         /* Set color 0 to black */
1211         write_reg(0, 0x02a30);
1212         write_reg(0, 0x02a34);
1213
1214         /* Enable the osd */
1215         ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1216
1217         /* Enable restart */
1218         itv->ivtvfb_restore = ivtvfb_restore;
1219
1220         /* Allocate DMA */
1221         ivtv_udma_alloc(itv);
1222         return 0;
1223
1224 }
1225
1226 static int __init ivtvfb_callback_init(struct device *dev, void *p)
1227 {
1228         struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1229         struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1230
1231         if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1232                 if (ivtvfb_init_card(itv) == 0) {
1233                         IVTVFB_INFO("Framebuffer registered on %s\n",
1234                                         itv->v4l2_dev.name);
1235                         (*(int *)p)++;
1236                 }
1237         }
1238         return 0;
1239 }
1240
1241 static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1242 {
1243         struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1244         struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1245         struct osd_info *oi = itv->osd_info;
1246
1247         if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1248                 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1249                         IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1250                                        itv->instance);
1251                         return 0;
1252                 }
1253                 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1254                 itv->ivtvfb_restore = NULL;
1255                 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1256                 ivtvfb_release_buffers(itv);
1257                 itv->osd_video_pbase = 0;
1258         }
1259         return 0;
1260 }
1261
1262 static int __init ivtvfb_init(void)
1263 {
1264         struct device_driver *drv;
1265         int registered = 0;
1266         int err;
1267
1268 #ifdef CONFIG_X86_64
1269         if (WARN(pat_enabled(),
1270                  "ivtvfb needs PAT disabled, boot with nopat kernel parameter\n")) {
1271                 return -ENODEV;
1272         }
1273 #endif
1274
1275         if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1276                 printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1277                      IVTV_MAX_CARDS - 1);
1278                 return -EINVAL;
1279         }
1280
1281         drv = driver_find("ivtv", &pci_bus_type);
1282         err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1283         (void)err;      /* suppress compiler warning */
1284         if (!registered) {
1285                 printk(KERN_ERR "ivtvfb:  no cards found\n");
1286                 return -ENODEV;
1287         }
1288         return 0;
1289 }
1290
1291 static void ivtvfb_cleanup(void)
1292 {
1293         struct device_driver *drv;
1294         int err;
1295
1296         printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
1297
1298         drv = driver_find("ivtv", &pci_bus_type);
1299         err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1300         (void)err;      /* suppress compiler warning */
1301 }
1302
1303 module_init(ivtvfb_init);
1304 module_exit(ivtvfb_cleanup);