xref: /linux/drivers/media/pci/ivtv/ivtvfb.c (revision 32786fdc9506aeba98278c1844d4bfb766863832)
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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
42 
43 #include <linux/module.h>
44 #include <linux/kernel.h>
45 #include <linux/fb.h>
46 #include <linux/ivtvfb.h>
47 #include <linux/slab.h>
48 
49 #ifdef CONFIG_X86_64
50 #include <asm/pat.h>
51 #endif
52 
53 #include "ivtv-driver.h"
54 #include "ivtv-cards.h"
55 #include "ivtv-i2c.h"
56 #include "ivtv-udma.h"
57 #include "ivtv-mailbox.h"
58 #include "ivtv-firmware.h"
59 
60 /* card parameters */
61 static int ivtvfb_card_id = -1;
62 static int ivtvfb_debug = 0;
63 static bool osd_laced;
64 static int osd_depth;
65 static int osd_upper;
66 static int osd_left;
67 static int osd_yres;
68 static int osd_xres;
69 
70 module_param(ivtvfb_card_id, int, 0444);
71 module_param_named(debug,ivtvfb_debug, int, 0644);
72 module_param(osd_laced, bool, 0444);
73 module_param(osd_depth, int, 0444);
74 module_param(osd_upper, int, 0444);
75 module_param(osd_left, int, 0444);
76 module_param(osd_yres, int, 0444);
77 module_param(osd_xres, int, 0444);
78 
79 MODULE_PARM_DESC(ivtvfb_card_id,
80 		 "Only use framebuffer of the specified ivtv card (0-31)\n"
81 		 "\t\t\tdefault -1: initialize all available framebuffers");
82 
83 MODULE_PARM_DESC(debug,
84 		 "Debug level (bitmask). Default: errors only\n"
85 		 "\t\t\t(debug = 3 gives full debugging)");
86 
87 /* Why upper, left, xres, yres, depth, laced ? To match terminology used
88    by fbset.
89    Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
90 
91 MODULE_PARM_DESC(osd_laced,
92 		 "Interlaced mode\n"
93 		 "\t\t\t0=off\n"
94 		 "\t\t\t1=on\n"
95 		 "\t\t\tdefault off");
96 
97 MODULE_PARM_DESC(osd_depth,
98 		 "Bits per pixel - 8, 16, 32\n"
99 		 "\t\t\tdefault 8");
100 
101 MODULE_PARM_DESC(osd_upper,
102 		 "Vertical start position\n"
103 		 "\t\t\tdefault 0 (Centered)");
104 
105 MODULE_PARM_DESC(osd_left,
106 		 "Horizontal start position\n"
107 		 "\t\t\tdefault 0 (Centered)");
108 
109 MODULE_PARM_DESC(osd_yres,
110 		 "Display height\n"
111 		 "\t\t\tdefault 480 (PAL)\n"
112 		 "\t\t\t        400 (NTSC)");
113 
114 MODULE_PARM_DESC(osd_xres,
115 		 "Display width\n"
116 		 "\t\t\tdefault 640");
117 
118 MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
119 MODULE_LICENSE("GPL");
120 
121 /* --------------------------------------------------------------------- */
122 
123 #define IVTVFB_DBGFLG_WARN  (1 << 0)
124 #define IVTVFB_DBGFLG_INFO  (1 << 1)
125 
126 #define IVTVFB_DEBUG(x, type, fmt, args...) \
127 	do { \
128 		if ((x) & ivtvfb_debug) \
129 			printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
130 	} while (0)
131 #define IVTVFB_DEBUG_WARN(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
132 #define IVTVFB_DEBUG_INFO(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
133 
134 /* Standard kernel messages */
135 #define IVTVFB_ERR(fmt, args...)   printk(KERN_ERR  "ivtvfb%d: " fmt, itv->instance , ## args)
136 #define IVTVFB_WARN(fmt, args...)  printk(KERN_WARNING  "ivtvfb%d: " fmt, itv->instance , ## args)
137 #define IVTVFB_INFO(fmt, args...)  printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
138 
139 /* --------------------------------------------------------------------- */
140 
141 #define IVTV_OSD_MAX_WIDTH  720
142 #define IVTV_OSD_MAX_HEIGHT 576
143 
144 #define IVTV_OSD_BPP_8      0x00
145 #define IVTV_OSD_BPP_16_444 0x03
146 #define IVTV_OSD_BPP_16_555 0x02
147 #define IVTV_OSD_BPP_16_565 0x01
148 #define IVTV_OSD_BPP_32     0x04
149 
150 struct osd_info {
151 	/* Physical base address */
152 	unsigned long video_pbase;
153 	/* Relative base address (relative to start of decoder memory) */
154 	u32 video_rbase;
155 	/* Mapped base address */
156 	volatile char __iomem *video_vbase;
157 	/* Buffer size */
158 	u32 video_buffer_size;
159 
160 	/* video_base rounded down as required by hardware MTRRs */
161 	unsigned long fb_start_aligned_physaddr;
162 	/* video_base rounded up as required by hardware MTRRs */
163 	unsigned long fb_end_aligned_physaddr;
164 	int wc_cookie;
165 
166 	/* Store the buffer offset */
167 	int set_osd_coords_x;
168 	int set_osd_coords_y;
169 
170 	/* Current dimensions (NOT VISIBLE SIZE!) */
171 	int display_width;
172 	int display_height;
173 	int display_byte_stride;
174 
175 	/* Current bits per pixel */
176 	int bits_per_pixel;
177 	int bytes_per_pixel;
178 
179 	/* Frame buffer stuff */
180 	struct fb_info ivtvfb_info;
181 	struct fb_var_screeninfo ivtvfb_defined;
182 	struct fb_fix_screeninfo ivtvfb_fix;
183 
184 	/* Used for a warm start */
185 	struct fb_var_screeninfo fbvar_cur;
186 	int blank_cur;
187 	u32 palette_cur[256];
188 	u32 pan_cur;
189 };
190 
191 struct ivtv_osd_coords {
192 	unsigned long offset;
193 	unsigned long max_offset;
194 	int pixel_stride;
195 	int lines;
196 	int x;
197 	int y;
198 };
199 
200 /* --------------------------------------------------------------------- */
201 
202 /* ivtv API calls for framebuffer related support */
203 
204 static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
205 				       u32 *fblength)
206 {
207 	u32 data[CX2341X_MBOX_MAX_DATA];
208 	int rc;
209 
210 	ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
211 	rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
212 	*fbbase = data[0];
213 	*fblength = data[1];
214 	return rc;
215 }
216 
217 static int ivtvfb_get_osd_coords(struct ivtv *itv,
218 				      struct ivtv_osd_coords *osd)
219 {
220 	struct osd_info *oi = itv->osd_info;
221 	u32 data[CX2341X_MBOX_MAX_DATA];
222 
223 	ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
224 
225 	osd->offset = data[0] - oi->video_rbase;
226 	osd->max_offset = oi->display_width * oi->display_height * 4;
227 	osd->pixel_stride = data[1];
228 	osd->lines = data[2];
229 	osd->x = data[3];
230 	osd->y = data[4];
231 	return 0;
232 }
233 
234 static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
235 {
236 	struct osd_info *oi = itv->osd_info;
237 
238 	oi->display_width = osd->pixel_stride;
239 	oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
240 	oi->set_osd_coords_x += osd->x;
241 	oi->set_osd_coords_y = osd->y;
242 
243 	return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
244 			osd->offset + oi->video_rbase,
245 			osd->pixel_stride,
246 			osd->lines, osd->x, osd->y);
247 }
248 
249 static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
250 {
251 	int osd_height_limit = itv->is_out_50hz ? 576 : 480;
252 
253 	/* Only fail if resolution too high, otherwise fudge the start coords. */
254 	if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
255 		return -EINVAL;
256 
257 	/* Ensure we don't exceed display limits */
258 	if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
259 		IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
260 			ivtv_window->top, ivtv_window->height);
261 		ivtv_window->top = osd_height_limit - ivtv_window->height;
262 	}
263 
264 	if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
265 		IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
266 			ivtv_window->left, ivtv_window->width);
267 		ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
268 	}
269 
270 	/* Set the OSD origin */
271 	write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
272 
273 	/* How much to display */
274 	write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
275 
276 	/* Pass this info back the yuv handler */
277 	itv->yuv_info.osd_vis_w = ivtv_window->width;
278 	itv->yuv_info.osd_vis_h = ivtv_window->height;
279 	itv->yuv_info.osd_x_offset = ivtv_window->left;
280 	itv->yuv_info.osd_y_offset = ivtv_window->top;
281 
282 	return 0;
283 }
284 
285 static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
286 				  unsigned long ivtv_dest_addr, void __user *userbuf,
287 				  int size_in_bytes)
288 {
289 	DEFINE_WAIT(wait);
290 	int got_sig = 0;
291 
292 	mutex_lock(&itv->udma.lock);
293 	/* Map User DMA */
294 	if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
295 		mutex_unlock(&itv->udma.lock);
296 		IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, 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 	/* Find the largest power of two that maps the whole buffer */
1103 	int size_shift = 31;
1104 
1105 	mutex_lock(&itv->serialize_lock);
1106 	if (ivtv_init_on_first_open(itv)) {
1107 		mutex_unlock(&itv->serialize_lock);
1108 		IVTVFB_ERR("Failed to initialize ivtv\n");
1109 		return -ENXIO;
1110 	}
1111 	mutex_unlock(&itv->serialize_lock);
1112 
1113 	if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
1114 					&oi->video_buffer_size) < 0) {
1115 		IVTVFB_ERR("Firmware failed to respond\n");
1116 		return -EIO;
1117 	}
1118 
1119 	/* The osd buffer size depends on the number of video buffers allocated
1120 	   on the PVR350 itself. For now we'll hardcode the smallest osd buffer
1121 	   size to prevent any overlap. */
1122 	oi->video_buffer_size = 1704960;
1123 
1124 	oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
1125 	oi->video_vbase = itv->dec_mem + oi->video_rbase;
1126 
1127 	if (!oi->video_vbase) {
1128 		IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1129 		     oi->video_buffer_size, oi->video_pbase);
1130 		return -EIO;
1131 	}
1132 
1133 	IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1134 			oi->video_pbase, oi->video_vbase,
1135 			oi->video_buffer_size / 1024);
1136 
1137 	while (!(oi->video_buffer_size & (1 << size_shift)))
1138 		size_shift--;
1139 	size_shift++;
1140 	oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1141 	oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1142 	oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1143 	oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1144 	oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr,
1145 					 oi->fb_end_aligned_physaddr -
1146 					 oi->fb_start_aligned_physaddr);
1147 	/* Blank the entire osd. */
1148 	memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1149 
1150 	return 0;
1151 }
1152 
1153 /* Release any memory we've grabbed & remove mtrr entry */
1154 static void ivtvfb_release_buffers (struct ivtv *itv)
1155 {
1156 	struct osd_info *oi = itv->osd_info;
1157 
1158 	/* Release cmap */
1159 	if (oi->ivtvfb_info.cmap.len)
1160 		fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1161 
1162 	/* Release pseudo palette */
1163 	kfree(oi->ivtvfb_info.pseudo_palette);
1164 	arch_phys_wc_del(oi->wc_cookie);
1165 	kfree(oi);
1166 	itv->osd_info = NULL;
1167 }
1168 
1169 /* Initialize the specified card */
1170 
1171 static int ivtvfb_init_card(struct ivtv *itv)
1172 {
1173 	int rc;
1174 
1175 #ifdef CONFIG_X86_64
1176 	if (pat_enabled()) {
1177 		pr_warn("ivtvfb needs PAT disabled, boot with nopat kernel parameter\n");
1178 		return -ENODEV;
1179 	}
1180 #endif
1181 
1182 	if (itv->osd_info) {
1183 		IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
1184 		return -EBUSY;
1185 	}
1186 
1187 	itv->osd_info = kzalloc(sizeof(struct osd_info),
1188 					GFP_ATOMIC|__GFP_NOWARN);
1189 	if (itv->osd_info == NULL) {
1190 		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1191 		return -ENOMEM;
1192 	}
1193 
1194 	/* Find & setup the OSD buffer */
1195 	rc = ivtvfb_init_io(itv);
1196 	if (rc) {
1197 		ivtvfb_release_buffers(itv);
1198 		return rc;
1199 	}
1200 
1201 	/* Set the startup video mode information */
1202 	if ((rc = ivtvfb_init_vidmode(itv))) {
1203 		ivtvfb_release_buffers(itv);
1204 		return rc;
1205 	}
1206 
1207 	/* Register the framebuffer */
1208 	if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
1209 		ivtvfb_release_buffers(itv);
1210 		return -EINVAL;
1211 	}
1212 
1213 	itv->osd_video_pbase = itv->osd_info->video_pbase;
1214 
1215 	/* Set the card to the requested mode */
1216 	ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
1217 
1218 	/* Set color 0 to black */
1219 	write_reg(0, 0x02a30);
1220 	write_reg(0, 0x02a34);
1221 
1222 	/* Enable the osd */
1223 	ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1224 
1225 	/* Enable restart */
1226 	itv->ivtvfb_restore = ivtvfb_restore;
1227 
1228 	/* Allocate DMA */
1229 	ivtv_udma_alloc(itv);
1230 	return 0;
1231 
1232 }
1233 
1234 static int __init ivtvfb_callback_init(struct device *dev, void *p)
1235 {
1236 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1237 	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1238 
1239 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1240 		if (ivtvfb_init_card(itv) == 0) {
1241 			IVTVFB_INFO("Framebuffer registered on %s\n",
1242 					itv->v4l2_dev.name);
1243 			(*(int *)p)++;
1244 		}
1245 	}
1246 	return 0;
1247 }
1248 
1249 static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1250 {
1251 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1252 	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1253 	struct osd_info *oi = itv->osd_info;
1254 
1255 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1256 		if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1257 			IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1258 				       itv->instance);
1259 			return 0;
1260 		}
1261 		IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1262 		itv->ivtvfb_restore = NULL;
1263 		ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1264 		ivtvfb_release_buffers(itv);
1265 		itv->osd_video_pbase = 0;
1266 	}
1267 	return 0;
1268 }
1269 
1270 static int __init ivtvfb_init(void)
1271 {
1272 	struct device_driver *drv;
1273 	int registered = 0;
1274 	int err;
1275 
1276 
1277 	if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1278 		printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1279 		     IVTV_MAX_CARDS - 1);
1280 		return -EINVAL;
1281 	}
1282 
1283 	drv = driver_find("ivtv", &pci_bus_type);
1284 	err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1285 	(void)err;	/* suppress compiler warning */
1286 	if (!registered) {
1287 		printk(KERN_ERR "ivtvfb:  no cards found\n");
1288 		return -ENODEV;
1289 	}
1290 	return 0;
1291 }
1292 
1293 static void ivtvfb_cleanup(void)
1294 {
1295 	struct device_driver *drv;
1296 	int err;
1297 
1298 	printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
1299 
1300 	drv = driver_find("ivtv", &pci_bus_type);
1301 	err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1302 	(void)err;	/* suppress compiler warning */
1303 }
1304 
1305 module_init(ivtvfb_init);
1306 module_exit(ivtvfb_cleanup);
1307