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