xref: /openbmc/linux/drivers/media/pci/ivtv/ivtvfb.c (revision ae213c44)
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 "ivtv-driver.h"
42 #include "ivtv-cards.h"
43 #include "ivtv-i2c.h"
44 #include "ivtv-udma.h"
45 #include "ivtv-mailbox.h"
46 #include "ivtv-firmware.h"
47 
48 #include <linux/fb.h>
49 #include <linux/ivtvfb.h>
50 
51 #ifdef CONFIG_X86_64
52 #include <asm/pat.h>
53 #endif
54 
55 /* card parameters */
56 static int ivtvfb_card_id = -1;
57 static int ivtvfb_debug = 0;
58 static bool ivtvfb_force_pat = IS_ENABLED(CONFIG_VIDEO_FB_IVTV_FORCE_PAT);
59 static bool osd_laced;
60 static int osd_depth;
61 static int osd_upper;
62 static int osd_left;
63 static int osd_yres;
64 static int osd_xres;
65 
66 module_param(ivtvfb_card_id, int, 0444);
67 module_param_named(debug,ivtvfb_debug, int, 0644);
68 module_param_named(force_pat, ivtvfb_force_pat, bool, 0644);
69 module_param(osd_laced, bool, 0444);
70 module_param(osd_depth, int, 0444);
71 module_param(osd_upper, int, 0444);
72 module_param(osd_left, int, 0444);
73 module_param(osd_yres, int, 0444);
74 module_param(osd_xres, int, 0444);
75 
76 MODULE_PARM_DESC(ivtvfb_card_id,
77 		 "Only use framebuffer of the specified ivtv card (0-31)\n"
78 		 "\t\t\tdefault -1: initialize all available framebuffers");
79 
80 MODULE_PARM_DESC(debug,
81 		 "Debug level (bitmask). Default: errors only\n"
82 		 "\t\t\t(debug = 3 gives full debugging)");
83 
84 MODULE_PARM_DESC(force_pat,
85 		 "Force initialization on x86 PAT-enabled systems (bool).\n");
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 (%p)\n",
355 			    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(source + dest_offset, count)) {
365 		IVTVFB_WARN("Invalid userspace pointer %p\n", source);
366 
367 		IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source %p count %d\n",
368 				  dest_offset, source, count);
369 		return -EINVAL;
370 	}
371 
372 	/* OSD Address to send DMA to */
373 	dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
374 
375 	/* Fill Buffers */
376 	return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
377 }
378 
379 static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
380 						size_t count, loff_t *ppos)
381 {
382 	unsigned long p = *ppos;
383 	void *dst;
384 	int err = 0;
385 	int dma_err;
386 	unsigned long total_size;
387 	struct ivtv *itv = (struct ivtv *) info->par;
388 	unsigned long dma_offset =
389 			IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
390 	unsigned long dma_size;
391 	u16 lead = 0, tail = 0;
392 
393 	if (info->state != FBINFO_STATE_RUNNING)
394 		return -EPERM;
395 
396 	total_size = info->screen_size;
397 
398 	if (total_size == 0)
399 		total_size = info->fix.smem_len;
400 
401 	if (p > total_size)
402 		return -EFBIG;
403 
404 	if (count > total_size) {
405 		err = -EFBIG;
406 		count = total_size;
407 	}
408 
409 	if (count + p > total_size) {
410 		if (!err)
411 			err = -ENOSPC;
412 		count = total_size - p;
413 	}
414 
415 	dst = (void __force *) (info->screen_base + p);
416 
417 	if (info->fbops->fb_sync)
418 		info->fbops->fb_sync(info);
419 
420 	/* If transfer size > threshold and both src/dst
421 	addresses are aligned, use DMA */
422 	if (count >= 4096 &&
423 	    ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
424 		/* Odd address = can't DMA. Align */
425 		if ((unsigned long)dst & 3) {
426 			lead = 4 - ((unsigned long)dst & 3);
427 			if (copy_from_user(dst, buf, lead))
428 				return -EFAULT;
429 			buf += lead;
430 			dst += lead;
431 		}
432 		/* DMA resolution is 32 bits */
433 		if ((count - lead) & 3)
434 			tail = (count - lead) & 3;
435 		/* DMA the data */
436 		dma_size = count - lead - tail;
437 		dma_err = ivtvfb_prep_dec_dma_to_device(itv,
438 		       p + lead + dma_offset, (void __user *)buf, dma_size);
439 		if (dma_err)
440 			return dma_err;
441 		dst += dma_size;
442 		buf += dma_size;
443 		/* Copy any leftover data */
444 		if (tail && copy_from_user(dst, buf, tail))
445 			return -EFAULT;
446 	} else if (copy_from_user(dst, buf, count)) {
447 		return -EFAULT;
448 	}
449 
450 	if  (!err)
451 		*ppos += count;
452 
453 	return (err) ? err : count;
454 }
455 
456 static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
457 {
458 	DEFINE_WAIT(wait);
459 	struct ivtv *itv = (struct ivtv *)info->par;
460 	int rc = 0;
461 
462 	switch (cmd) {
463 		case FBIOGET_VBLANK: {
464 			struct fb_vblank vblank;
465 			u32 trace;
466 
467 			memset(&vblank, 0, sizeof(struct fb_vblank));
468 
469 			vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
470 					FB_VBLANK_HAVE_VSYNC;
471 			trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
472 			if (itv->is_out_50hz && trace > 312)
473 				trace -= 312;
474 			else if (itv->is_out_60hz && trace > 262)
475 				trace -= 262;
476 			if (trace == 1)
477 				vblank.flags |= FB_VBLANK_VSYNCING;
478 			vblank.count = itv->last_vsync_field;
479 			vblank.vcount = trace;
480 			vblank.hcount = 0;
481 			if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
482 				return -EFAULT;
483 			return 0;
484 		}
485 
486 		case FBIO_WAITFORVSYNC:
487 			prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
488 			if (!schedule_timeout(msecs_to_jiffies(50)))
489 				rc = -ETIMEDOUT;
490 			finish_wait(&itv->vsync_waitq, &wait);
491 			return rc;
492 
493 		case IVTVFB_IOC_DMA_FRAME: {
494 			struct ivtvfb_dma_frame args;
495 
496 			IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
497 			if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
498 				return -EFAULT;
499 
500 			return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
501 		}
502 
503 		default:
504 			IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
505 			return -EINVAL;
506 	}
507 	return 0;
508 }
509 
510 /* Framebuffer device handling */
511 
512 static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
513 {
514 	struct osd_info *oi = itv->osd_info;
515 	struct ivtv_osd_coords ivtv_osd;
516 	struct v4l2_rect ivtv_window;
517 	int osd_mode = -1;
518 
519 	IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
520 
521 	/* Select color space */
522 	if (var->nonstd) /* YUV */
523 		write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
524 	else /* RGB  */
525 		write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
526 
527 	/* Set the color mode */
528 	switch (var->bits_per_pixel) {
529 		case 8:
530 			osd_mode = IVTV_OSD_BPP_8;
531 			break;
532 		case 32:
533 			osd_mode = IVTV_OSD_BPP_32;
534 			break;
535 		case 16:
536 			switch (var->green.length) {
537 			case 4:
538 				osd_mode = IVTV_OSD_BPP_16_444;
539 				break;
540 			case 5:
541 				osd_mode = IVTV_OSD_BPP_16_555;
542 				break;
543 			case 6:
544 				osd_mode = IVTV_OSD_BPP_16_565;
545 				break;
546 			default:
547 				IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
548 			}
549 			break;
550 		default:
551 			IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
552 	}
553 
554 	/* Set video mode. Although rare, the display can become scrambled even
555 	   if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
556 	if (osd_mode != -1) {
557 		ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
558 		ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
559 	}
560 
561 	oi->bits_per_pixel = var->bits_per_pixel;
562 	oi->bytes_per_pixel = var->bits_per_pixel / 8;
563 
564 	/* Set the flicker filter */
565 	switch (var->vmode & FB_VMODE_MASK) {
566 		case FB_VMODE_NONINTERLACED: /* Filter on */
567 			ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
568 			break;
569 		case FB_VMODE_INTERLACED: /* Filter off */
570 			ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
571 			break;
572 		default:
573 			IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
574 	}
575 
576 	/* Read the current osd info */
577 	ivtvfb_get_osd_coords(itv, &ivtv_osd);
578 
579 	/* Now set the OSD to the size we want */
580 	ivtv_osd.pixel_stride = var->xres_virtual;
581 	ivtv_osd.lines = var->yres_virtual;
582 	ivtv_osd.x = 0;
583 	ivtv_osd.y = 0;
584 	ivtvfb_set_osd_coords(itv, &ivtv_osd);
585 
586 	/* Can't seem to find the right API combo for this.
587 	   Use another function which does what we need through direct register access. */
588 	ivtv_window.width = var->xres;
589 	ivtv_window.height = var->yres;
590 
591 	/* Minimum margin cannot be 0, as X won't allow such a mode */
592 	if (!var->upper_margin)
593 		var->upper_margin++;
594 	if (!var->left_margin)
595 		var->left_margin++;
596 	ivtv_window.top = var->upper_margin - 1;
597 	ivtv_window.left = var->left_margin - 1;
598 
599 	ivtvfb_set_display_window(itv, &ivtv_window);
600 
601 	/* Pass screen size back to yuv handler */
602 	itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride;
603 	itv->yuv_info.osd_full_h = ivtv_osd.lines;
604 
605 	/* Force update of yuv registers */
606 	itv->yuv_info.yuv_forced_update = 1;
607 
608 	/* Keep a copy of these settings */
609 	memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
610 
611 	IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
612 		      var->xres, var->yres,
613 		      var->xres_virtual, var->yres_virtual,
614 		      var->bits_per_pixel);
615 
616 	IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
617 		      var->left_margin, var->upper_margin);
618 
619 	IVTVFB_DEBUG_INFO("Display filter: %s\n",
620 			(var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
621 	IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
622 
623 	return 0;
624 }
625 
626 static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
627 {
628 	struct osd_info *oi = itv->osd_info;
629 
630 	IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
631 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
632 	strscpy(fix->id, "cx23415 TV out", sizeof(fix->id));
633 	fix->smem_start = oi->video_pbase;
634 	fix->smem_len = oi->video_buffer_size;
635 	fix->type = FB_TYPE_PACKED_PIXELS;
636 	fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
637 	fix->xpanstep = 1;
638 	fix->ypanstep = 1;
639 	fix->ywrapstep = 0;
640 	fix->line_length = oi->display_byte_stride;
641 	fix->accel = FB_ACCEL_NONE;
642 	return 0;
643 }
644 
645 /* Check the requested display mode, returning -EINVAL if we can't
646    handle it. */
647 
648 static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
649 {
650 	struct osd_info *oi = itv->osd_info;
651 	int osd_height_limit;
652 	u32 pixclock, hlimit, vlimit;
653 
654 	IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
655 
656 	/* Set base references for mode calcs. */
657 	if (itv->is_out_50hz) {
658 		pixclock = 84316;
659 		hlimit = 776;
660 		vlimit = 591;
661 		osd_height_limit = 576;
662 	}
663 	else {
664 		pixclock = 83926;
665 		hlimit = 776;
666 		vlimit = 495;
667 		osd_height_limit = 480;
668 	}
669 
670 	if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
671 		var->transp.offset = 24;
672 		var->transp.length = 8;
673 		var->red.offset = 16;
674 		var->red.length = 8;
675 		var->green.offset = 8;
676 		var->green.length = 8;
677 		var->blue.offset = 0;
678 		var->blue.length = 8;
679 	}
680 	else if (var->bits_per_pixel == 16) {
681 		/* To find out the true mode, check green length */
682 		switch (var->green.length) {
683 			case 4:
684 				var->red.offset = 8;
685 				var->red.length = 4;
686 				var->green.offset = 4;
687 				var->green.length = 4;
688 				var->blue.offset = 0;
689 				var->blue.length = 4;
690 				var->transp.offset = 12;
691 				var->transp.length = 1;
692 				break;
693 			case 5:
694 				var->red.offset = 10;
695 				var->red.length = 5;
696 				var->green.offset = 5;
697 				var->green.length = 5;
698 				var->blue.offset = 0;
699 				var->blue.length = 5;
700 				var->transp.offset = 15;
701 				var->transp.length = 1;
702 				break;
703 			default:
704 				var->red.offset = 11;
705 				var->red.length = 5;
706 				var->green.offset = 5;
707 				var->green.length = 6;
708 				var->blue.offset = 0;
709 				var->blue.length = 5;
710 				var->transp.offset = 0;
711 				var->transp.length = 0;
712 				break;
713 		}
714 	}
715 	else {
716 		IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
717 		return -EINVAL;
718 	}
719 
720 	/* Check the resolution */
721 	if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
722 		IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
723 				var->xres, var->yres);
724 		return -EINVAL;
725 	}
726 
727 	/* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
728 	if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
729 	    var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
730 	    var->xres_virtual < var->xres ||
731 	    var->yres_virtual < var->yres) {
732 		IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
733 			var->xres_virtual, var->yres_virtual);
734 		return -EINVAL;
735 	}
736 
737 	/* Some extra checks if in 8 bit mode */
738 	if (var->bits_per_pixel == 8) {
739 		/* Width must be a multiple of 4 */
740 		if (var->xres & 3) {
741 			IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
742 			return -EINVAL;
743 		}
744 		if (var->xres_virtual & 3) {
745 			IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
746 			return -EINVAL;
747 		}
748 	}
749 	else if (var->bits_per_pixel == 16) {
750 		/* Width must be a multiple of 2 */
751 		if (var->xres & 1) {
752 			IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
753 			return -EINVAL;
754 		}
755 		if (var->xres_virtual & 1) {
756 			IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
757 			return -EINVAL;
758 		}
759 	}
760 
761 	/* Now check the offsets */
762 	if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
763 		IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
764 			var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
765 		return -EINVAL;
766 	}
767 
768 	/* Check pixel format */
769 	if (var->nonstd > 1) {
770 		IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
771 		return -EINVAL;
772 	}
773 
774 	/* Check video mode */
775 	if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
776 		((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
777 		IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
778 		return -EINVAL;
779 	}
780 
781 	/* Check the left & upper margins
782 	   If the margins are too large, just center the screen
783 	   (enforcing margins causes too many problems) */
784 
785 	if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
786 		var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
787 
788 	if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
789 		var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
790 			var->yres) / 2);
791 
792 	/* Maintain overall 'size' for a constant refresh rate */
793 	var->right_margin = hlimit - var->left_margin - var->xres;
794 	var->lower_margin = vlimit - var->upper_margin - var->yres;
795 
796 	/* Fixed sync times */
797 	var->hsync_len = 24;
798 	var->vsync_len = 2;
799 
800 	/* Non-interlaced / interlaced mode is used to switch the OSD filter
801 	   on or off. Adjust the clock timings to maintain a constant
802 	   vertical refresh rate. */
803 	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
804 		var->pixclock = pixclock / 2;
805 	else
806 		var->pixclock = pixclock;
807 
808 	itv->osd_rect.width = var->xres;
809 	itv->osd_rect.height = var->yres;
810 
811 	IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
812 		      var->xres, var->yres,
813 		      var->xres_virtual, var->yres_virtual,
814 		      var->bits_per_pixel);
815 
816 	IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
817 		      var->left_margin, var->upper_margin);
818 
819 	IVTVFB_DEBUG_INFO("Display filter: %s\n",
820 			(var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
821 	IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
822 	return 0;
823 }
824 
825 static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
826 {
827 	struct ivtv *itv = (struct ivtv *) info->par;
828 	IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
829 	return _ivtvfb_check_var(var, itv);
830 }
831 
832 static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
833 {
834 	u32 osd_pan_index;
835 	struct ivtv *itv = (struct ivtv *) info->par;
836 
837 	if (var->yoffset + info->var.yres > info->var.yres_virtual ||
838 	    var->xoffset + info->var.xres > info->var.xres_virtual)
839 		return -EINVAL;
840 
841 	osd_pan_index = var->yoffset * info->fix.line_length
842 		      + var->xoffset * info->var.bits_per_pixel / 8;
843 	write_reg(osd_pan_index, 0x02A0C);
844 
845 	/* Pass this info back the yuv handler */
846 	itv->yuv_info.osd_x_pan = var->xoffset;
847 	itv->yuv_info.osd_y_pan = var->yoffset;
848 	/* Force update of yuv registers */
849 	itv->yuv_info.yuv_forced_update = 1;
850 	/* Remember this value */
851 	itv->osd_info->pan_cur = osd_pan_index;
852 	return 0;
853 }
854 
855 static int ivtvfb_set_par(struct fb_info *info)
856 {
857 	int rc = 0;
858 	struct ivtv *itv = (struct ivtv *) info->par;
859 
860 	IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
861 
862 	rc = ivtvfb_set_var(itv, &info->var);
863 	ivtvfb_pan_display(&info->var, info);
864 	ivtvfb_get_fix(itv, &info->fix);
865 	ivtv_firmware_check(itv, "ivtvfb_set_par");
866 	return rc;
867 }
868 
869 static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
870 				unsigned blue, unsigned transp,
871 				struct fb_info *info)
872 {
873 	u32 color, *palette;
874 	struct ivtv *itv = (struct ivtv *)info->par;
875 
876 	if (regno >= info->cmap.len)
877 		return -EINVAL;
878 
879 	color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
880 	if (info->var.bits_per_pixel <= 8) {
881 		write_reg(regno, 0x02a30);
882 		write_reg(color, 0x02a34);
883 		itv->osd_info->palette_cur[regno] = color;
884 		return 0;
885 	}
886 	if (regno >= 16)
887 		return -EINVAL;
888 
889 	palette = info->pseudo_palette;
890 	if (info->var.bits_per_pixel == 16) {
891 		switch (info->var.green.length) {
892 			case 4:
893 				color = ((red & 0xf000) >> 4) |
894 					((green & 0xf000) >> 8) |
895 					((blue & 0xf000) >> 12);
896 				break;
897 			case 5:
898 				color = ((red & 0xf800) >> 1) |
899 					((green & 0xf800) >> 6) |
900 					((blue & 0xf800) >> 11);
901 				break;
902 			case 6:
903 				color = (red & 0xf800 ) |
904 					((green & 0xfc00) >> 5) |
905 					((blue & 0xf800) >> 11);
906 				break;
907 		}
908 	}
909 	palette[regno] = color;
910 	return 0;
911 }
912 
913 /* We don't really support blanking. All this does is enable or
914    disable the OSD. */
915 static int ivtvfb_blank(int blank_mode, struct fb_info *info)
916 {
917 	struct ivtv *itv = (struct ivtv *)info->par;
918 
919 	IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
920 	switch (blank_mode) {
921 	case FB_BLANK_UNBLANK:
922 		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
923 		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
924 		break;
925 	case FB_BLANK_NORMAL:
926 	case FB_BLANK_HSYNC_SUSPEND:
927 	case FB_BLANK_VSYNC_SUSPEND:
928 		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
929 		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
930 		break;
931 	case FB_BLANK_POWERDOWN:
932 		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
933 		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
934 		break;
935 	}
936 	itv->osd_info->blank_cur = blank_mode;
937 	return 0;
938 }
939 
940 static struct fb_ops ivtvfb_ops = {
941 	.owner = THIS_MODULE,
942 	.fb_write       = ivtvfb_write,
943 	.fb_check_var   = ivtvfb_check_var,
944 	.fb_set_par     = ivtvfb_set_par,
945 	.fb_setcolreg   = ivtvfb_setcolreg,
946 	.fb_fillrect    = cfb_fillrect,
947 	.fb_copyarea    = cfb_copyarea,
948 	.fb_imageblit   = cfb_imageblit,
949 	.fb_cursor      = NULL,
950 	.fb_ioctl       = ivtvfb_ioctl,
951 	.fb_pan_display = ivtvfb_pan_display,
952 	.fb_blank       = ivtvfb_blank,
953 };
954 
955 /* Restore hardware after firmware restart */
956 static void ivtvfb_restore(struct ivtv *itv)
957 {
958 	struct osd_info *oi = itv->osd_info;
959 	int i;
960 
961 	ivtvfb_set_var(itv, &oi->fbvar_cur);
962 	ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
963 	for (i = 0; i < 256; i++) {
964 		write_reg(i, 0x02a30);
965 		write_reg(oi->palette_cur[i], 0x02a34);
966 	}
967 	write_reg(oi->pan_cur, 0x02a0c);
968 }
969 
970 /* Initialization */
971 
972 
973 /* Setup our initial video mode */
974 static int ivtvfb_init_vidmode(struct ivtv *itv)
975 {
976 	struct osd_info *oi = itv->osd_info;
977 	struct v4l2_rect start_window;
978 	int max_height;
979 
980 	/* Color mode */
981 
982 	if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
983 		osd_depth = 8;
984 	oi->bits_per_pixel = osd_depth;
985 	oi->bytes_per_pixel = oi->bits_per_pixel / 8;
986 
987 	/* Horizontal size & position */
988 
989 	if (osd_xres > 720)
990 		osd_xres = 720;
991 
992 	/* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
993 	if (osd_depth == 8)
994 		osd_xres &= ~3;
995 	else if (osd_depth == 16)
996 		osd_xres &= ~1;
997 
998 	start_window.width = osd_xres ? osd_xres : 640;
999 
1000 	/* Check horizontal start (osd_left). */
1001 	if (osd_left && osd_left + start_window.width > 721) {
1002 		IVTVFB_ERR("Invalid osd_left - assuming default\n");
1003 		osd_left = 0;
1004 	}
1005 
1006 	/* Hardware coords start at 0, user coords start at 1. */
1007 	osd_left--;
1008 
1009 	start_window.left = osd_left >= 0 ?
1010 		 osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
1011 
1012 	oi->display_byte_stride =
1013 			start_window.width * oi->bytes_per_pixel;
1014 
1015 	/* Vertical size & position */
1016 
1017 	max_height = itv->is_out_50hz ? 576 : 480;
1018 
1019 	if (osd_yres > max_height)
1020 		osd_yres = max_height;
1021 
1022 	start_window.height = osd_yres ?
1023 		osd_yres : itv->is_out_50hz ? 480 : 400;
1024 
1025 	/* Check vertical start (osd_upper). */
1026 	if (osd_upper + start_window.height > max_height + 1) {
1027 		IVTVFB_ERR("Invalid osd_upper - assuming default\n");
1028 		osd_upper = 0;
1029 	}
1030 
1031 	/* Hardware coords start at 0, user coords start at 1. */
1032 	osd_upper--;
1033 
1034 	start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
1035 
1036 	oi->display_width = start_window.width;
1037 	oi->display_height = start_window.height;
1038 
1039 	/* Generate a valid fb_var_screeninfo */
1040 
1041 	oi->ivtvfb_defined.xres = oi->display_width;
1042 	oi->ivtvfb_defined.yres = oi->display_height;
1043 	oi->ivtvfb_defined.xres_virtual = oi->display_width;
1044 	oi->ivtvfb_defined.yres_virtual = oi->display_height;
1045 	oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
1046 	oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
1047 	oi->ivtvfb_defined.left_margin = start_window.left + 1;
1048 	oi->ivtvfb_defined.upper_margin = start_window.top + 1;
1049 	oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
1050 	oi->ivtvfb_defined.nonstd = 0;
1051 
1052 	/* We've filled in the most data, let the usual mode check
1053 	   routine fill in the rest. */
1054 	_ivtvfb_check_var(&oi->ivtvfb_defined, itv);
1055 
1056 	/* Generate valid fb_fix_screeninfo */
1057 
1058 	ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
1059 
1060 	/* Generate valid fb_info */
1061 
1062 	oi->ivtvfb_info.node = -1;
1063 	oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
1064 	oi->ivtvfb_info.fbops = &ivtvfb_ops;
1065 	oi->ivtvfb_info.par = itv;
1066 	oi->ivtvfb_info.var = oi->ivtvfb_defined;
1067 	oi->ivtvfb_info.fix = oi->ivtvfb_fix;
1068 	oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
1069 	oi->ivtvfb_info.fbops = &ivtvfb_ops;
1070 
1071 	/* Supply some monitor specs. Bogus values will do for now */
1072 	oi->ivtvfb_info.monspecs.hfmin = 8000;
1073 	oi->ivtvfb_info.monspecs.hfmax = 70000;
1074 	oi->ivtvfb_info.monspecs.vfmin = 10;
1075 	oi->ivtvfb_info.monspecs.vfmax = 100;
1076 
1077 	/* Allocate color map */
1078 	if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
1079 		IVTVFB_ERR("abort, unable to alloc cmap\n");
1080 		return -ENOMEM;
1081 	}
1082 
1083 	/* Allocate the pseudo palette */
1084 	oi->ivtvfb_info.pseudo_palette =
1085 		kmalloc_array(16, sizeof(u32), GFP_KERNEL|__GFP_NOWARN);
1086 
1087 	if (!oi->ivtvfb_info.pseudo_palette) {
1088 		IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
1089 		return -ENOMEM;
1090 	}
1091 
1092 	return 0;
1093 }
1094 
1095 /* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
1096 
1097 static int ivtvfb_init_io(struct ivtv *itv)
1098 {
1099 	struct osd_info *oi = itv->osd_info;
1100 	/* Find the largest power of two that maps the whole buffer */
1101 	int size_shift = 31;
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 	while (!(oi->video_buffer_size & (1 << size_shift)))
1136 		size_shift--;
1137 	size_shift++;
1138 	oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1139 	oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1140 	oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1141 	oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1142 	oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr,
1143 					 oi->fb_end_aligned_physaddr -
1144 					 oi->fb_start_aligned_physaddr);
1145 	/* Blank the entire osd. */
1146 	memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1147 
1148 	return 0;
1149 }
1150 
1151 /* Release any memory we've grabbed & remove mtrr entry */
1152 static void ivtvfb_release_buffers (struct ivtv *itv)
1153 {
1154 	struct osd_info *oi = itv->osd_info;
1155 
1156 	/* Release cmap */
1157 	if (oi->ivtvfb_info.cmap.len)
1158 		fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1159 
1160 	/* Release pseudo palette */
1161 	kfree(oi->ivtvfb_info.pseudo_palette);
1162 	arch_phys_wc_del(oi->wc_cookie);
1163 	kfree(oi);
1164 	itv->osd_info = NULL;
1165 }
1166 
1167 /* Initialize the specified card */
1168 
1169 static int ivtvfb_init_card(struct ivtv *itv)
1170 {
1171 	int rc;
1172 
1173 #ifdef CONFIG_X86_64
1174 	if (pat_enabled()) {
1175 		if (ivtvfb_force_pat) {
1176 			pr_info("PAT is enabled. Write-combined framebuffer caching will be disabled.\n");
1177 			pr_info("To enable caching, boot with nopat kernel parameter\n");
1178 		} else {
1179 			pr_warn("ivtvfb needs PAT disabled for write-combined framebuffer caching.\n");
1180 			pr_warn("Boot with nopat kernel parameter to use caching, or use the\n");
1181 			pr_warn("force_pat module parameter to run with caching disabled\n");
1182 			return -ENODEV;
1183 		}
1184 	}
1185 #endif
1186 
1187 	if (itv->osd_info) {
1188 		IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
1189 		return -EBUSY;
1190 	}
1191 
1192 	itv->osd_info = kzalloc(sizeof(struct osd_info),
1193 					GFP_KERNEL|__GFP_NOWARN);
1194 	if (itv->osd_info == NULL) {
1195 		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
1196 		return -ENOMEM;
1197 	}
1198 
1199 	/* Find & setup the OSD buffer */
1200 	rc = ivtvfb_init_io(itv);
1201 	if (rc) {
1202 		ivtvfb_release_buffers(itv);
1203 		return rc;
1204 	}
1205 
1206 	/* Set the startup video mode information */
1207 	if ((rc = ivtvfb_init_vidmode(itv))) {
1208 		ivtvfb_release_buffers(itv);
1209 		return rc;
1210 	}
1211 
1212 	/* Register the framebuffer */
1213 	if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
1214 		ivtvfb_release_buffers(itv);
1215 		return -EINVAL;
1216 	}
1217 
1218 	itv->osd_video_pbase = itv->osd_info->video_pbase;
1219 
1220 	/* Set the card to the requested mode */
1221 	ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
1222 
1223 	/* Set color 0 to black */
1224 	write_reg(0, 0x02a30);
1225 	write_reg(0, 0x02a34);
1226 
1227 	/* Enable the osd */
1228 	ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1229 
1230 	/* Enable restart */
1231 	itv->ivtvfb_restore = ivtvfb_restore;
1232 
1233 	/* Allocate DMA */
1234 	ivtv_udma_alloc(itv);
1235 	return 0;
1236 
1237 }
1238 
1239 static int __init ivtvfb_callback_init(struct device *dev, void *p)
1240 {
1241 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1242 	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1243 
1244 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1245 		if (ivtvfb_init_card(itv) == 0) {
1246 			IVTVFB_INFO("Framebuffer registered on %s\n",
1247 					itv->v4l2_dev.name);
1248 			(*(int *)p)++;
1249 		}
1250 	}
1251 	return 0;
1252 }
1253 
1254 static int ivtvfb_callback_cleanup(struct device *dev, void *p)
1255 {
1256 	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
1257 	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
1258 	struct osd_info *oi = itv->osd_info;
1259 
1260 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1261 		if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1262 			IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1263 				       itv->instance);
1264 			return 0;
1265 		}
1266 		IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1267 		itv->ivtvfb_restore = NULL;
1268 		ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
1269 		ivtvfb_release_buffers(itv);
1270 		itv->osd_video_pbase = 0;
1271 	}
1272 	return 0;
1273 }
1274 
1275 static int __init ivtvfb_init(void)
1276 {
1277 	struct device_driver *drv;
1278 	int registered = 0;
1279 	int err;
1280 
1281 
1282 	if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
1283 		pr_err("ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
1284 		     IVTV_MAX_CARDS - 1);
1285 		return -EINVAL;
1286 	}
1287 
1288 	drv = driver_find("ivtv", &pci_bus_type);
1289 	err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
1290 	(void)err;	/* suppress compiler warning */
1291 	if (!registered) {
1292 		pr_err("no cards found\n");
1293 		return -ENODEV;
1294 	}
1295 	return 0;
1296 }
1297 
1298 static void ivtvfb_cleanup(void)
1299 {
1300 	struct device_driver *drv;
1301 	int err;
1302 
1303 	pr_info("Unloading framebuffer module\n");
1304 
1305 	drv = driver_find("ivtv", &pci_bus_type);
1306 	err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
1307 	(void)err;	/* suppress compiler warning */
1308 }
1309 
1310 module_init(ivtvfb_init);
1311 module_exit(ivtvfb_cleanup);
1312