xref: /linux/drivers/media/pci/ivtv/ivtvfb.c (revision 005438a8eef063495ac059d128eea71b58de50e5)
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);
1305