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