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