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