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