aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-07-20 09:16:03 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:03:03 -0400
commitbe383bd312c4defab8bd4bde8c06fea5bfe0996b (patch)
tree359ef4f3b45464b31ad1c849e60efbc478d06e93 /drivers
parent32db775452818656d5fd8fd8b0f54425f5cfc177 (diff)
V4L/DVB (5904): ivtv-fb: cleanups
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/ivtv/ivtv-fb.c439
1 files changed, 204 insertions, 235 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fb.c b/drivers/media/video/ivtv/ivtv-fb.c
index 8e9bd75fc2bf..01cd65328e8a 100644
--- a/drivers/media/video/ivtv/ivtv-fb.c
+++ b/drivers/media/video/ivtv/ivtv-fb.c
@@ -3,7 +3,7 @@
3 3
4 This module presents the cx23415 OSD (onscreen display) framebuffer memory 4 This module presents the cx23415 OSD (onscreen display) framebuffer memory
5 as a standard Linux /dev/fb style framebuffer device. The framebuffer has 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 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 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. 8 local alpha. The colorspace is selectable between rgb & yuv.
9 Depending on the TV standard configured in the ivtv module at load time, 9 Depending on the TV standard configured in the ivtv module at load time,
@@ -111,7 +111,7 @@ MODULE_PARM_DESC(osd_laced,
111 "\t\t\tdefault off"); 111 "\t\t\tdefault off");
112 112
113MODULE_PARM_DESC(osd_depth, 113MODULE_PARM_DESC(osd_depth,
114 "Bits per pixel - 8,16,32\n" 114 "Bits per pixel - 8, 16, 32\n"
115 "\t\t\tdefault 8"); 115 "\t\t\tdefault 8");
116 116
117MODULE_PARM_DESC(osd_upper, 117MODULE_PARM_DESC(osd_upper,
@@ -232,12 +232,13 @@ static int ivtv_fb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
232static int ivtv_fb_get_osd_coords(struct ivtv *itv, 232static int ivtv_fb_get_osd_coords(struct ivtv *itv,
233 struct ivtv_osd_coords *osd) 233 struct ivtv_osd_coords *osd)
234{ 234{
235 struct osd_info *oi = itv->osd_info;
235 u32 data[CX2341X_MBOX_MAX_DATA]; 236 u32 data[CX2341X_MBOX_MAX_DATA];
236 237
237 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0); 238 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
238 239
239 osd->offset = data[0] - itv->osd_info->video_rbase; 240 osd->offset = data[0] - oi->video_rbase;
240 osd->max_offset = itv->osd_info->display_width * itv->osd_info->display_height * 4; 241 osd->max_offset = oi->display_width * oi->display_height * 4;
241 osd->pixel_stride = data[1]; 242 osd->pixel_stride = data[1];
242 osd->lines = data[2]; 243 osd->lines = data[2];
243 osd->x = data[3]; 244 osd->x = data[3];
@@ -247,20 +248,21 @@ static int ivtv_fb_get_osd_coords(struct ivtv *itv,
247 248
248static int ivtv_fb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd) 249static int ivtv_fb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
249{ 250{
250 itv->osd_info->display_width = osd->pixel_stride; 251 struct osd_info *oi = itv->osd_info;
251 itv->osd_info->display_byte_stride = osd->pixel_stride * itv->osd_info->bytes_per_pixel; 252
252 itv->osd_info->set_osd_coords_x += osd->x; 253 oi->display_width = osd->pixel_stride;
253 itv->osd_info->set_osd_coords_y = osd->y; 254 oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
255 oi->set_osd_coords_x += osd->x;
256 oi->set_osd_coords_y = osd->y;
254 257
255 return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5, 258 return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
256 osd->offset + itv->osd_info->video_rbase, 259 osd->offset + oi->video_rbase,
257 osd->pixel_stride, 260 osd->pixel_stride,
258 osd->lines, osd->x, osd->y); 261 osd->lines, osd->x, osd->y);
259} 262}
260 263
261static int ivtv_fb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window) 264static int ivtv_fb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
262{ 265{
263
264 int osd_height_limit = itv->is_50hz ? 576 : 480; 266 int osd_height_limit = itv->is_50hz ? 576 : 480;
265 267
266 /* Only fail if resolution too high, otherwise fudge the start coords. */ 268 /* Only fail if resolution too high, otherwise fudge the start coords. */
@@ -269,13 +271,13 @@ static int ivtv_fb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_w
269 271
270 /* Ensure we don't exceed display limits */ 272 /* Ensure we don't exceed display limits */
271 if (ivtv_window->top + ivtv_window->height > osd_height_limit) { 273 if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
272 IVTV_FB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d,%d)\n", 274 IVTV_FB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
273 ivtv_window->top, ivtv_window->height); 275 ivtv_window->top, ivtv_window->height);
274 ivtv_window->top = osd_height_limit - ivtv_window->height; 276 ivtv_window->top = osd_height_limit - ivtv_window->height;
275 } 277 }
276 278
277 if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) { 279 if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
278 IVTV_FB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d,%d)\n", 280 IVTV_FB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
279 ivtv_window->left, ivtv_window->width); 281 ivtv_window->left, ivtv_window->width);
280 ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width; 282 ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
281 } 283 }
@@ -344,7 +346,8 @@ static int ivtv_fb_prep_dec_dma_to_device(struct ivtv *itv,
344 return ret; 346 return ret;
345} 347}
346 348
347static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, unsigned long dest_offset, int count) 349static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
350 unsigned long dest_offset, int count)
348{ 351{
349 DEFINE_WAIT(wait); 352 DEFINE_WAIT(wait);
350 353
@@ -356,31 +359,28 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, un
356 359
357 /* Check Total FB Size */ 360 /* Check Total FB Size */
358 if ((dest_offset + count) > itv->osd_info->video_buffer_size) { 361 if ((dest_offset + count) > itv->osd_info->video_buffer_size) {
359 IVTV_FB_WARN( 362 IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
360 "ivtv_fb_prep_frame: Overflowing the framebuffer %ld, " 363 dest_offset + count, itv->osd_info->video_buffer_size);
361 "only %d available\n",
362 (dest_offset + count), itv->osd_info->video_buffer_size);
363 return -E2BIG; 364 return -E2BIG;
364 } 365 }
365 366
366 /* Not fatal, but will have undesirable results */ 367 /* Not fatal, but will have undesirable results */
367 if ((unsigned long)source & 3) 368 if ((unsigned long)source & 3)
368 IVTV_FB_WARN ("ivtv_fb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",(unsigned long)source); 369 IVTV_FB_WARN("ivtv_fb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",
370 (unsigned long)source);
369 371
370 if (dest_offset & 3) 372 if (dest_offset & 3)
371 IVTV_FB_WARN ("ivtv_fb_prep_frame: Dest offset not 32 bit aligned (%ld)\n",dest_offset); 373 IVTV_FB_WARN("ivtv_fb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
372 374
373 if (count & 3) 375 if (count & 3)
374 IVTV_FB_WARN ("ivtv_fb_prep_frame: Count not a multiple of 4 (%d)\n",count); 376 IVTV_FB_WARN("ivtv_fb_prep_frame: Count not a multiple of 4 (%d)\n", count);
375 377
376 /* Check Source */ 378 /* Check Source */
377 if (!access_ok(VERIFY_READ, source + dest_offset, count)) { 379 if (!access_ok(VERIFY_READ, source + dest_offset, count)) {
378 IVTV_FB_WARN( 380 IVTV_FB_WARN("Invalid userspace pointer 0x%08lx\n",
379 "Invalid userspace pointer!!! 0x%08lx\n",
380 (unsigned long)source); 381 (unsigned long)source);
381 382
382 IVTV_FB_DEBUG_WARN( 383 IVTV_FB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
383 "access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
384 dest_offset, (unsigned long)source, 384 dest_offset, (unsigned long)source,
385 count); 385 count);
386 return -EINVAL; 386 return -EINVAL;
@@ -397,17 +397,16 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
397{ 397{
398 DEFINE_WAIT(wait); 398 DEFINE_WAIT(wait);
399 struct ivtv *itv = (struct ivtv *)info->par; 399 struct ivtv *itv = (struct ivtv *)info->par;
400 int rc=0; 400 int rc = 0;
401 401
402 switch (cmd) { 402 switch (cmd) {
403
404 case FBIOGET_VBLANK: { 403 case FBIOGET_VBLANK: {
405 struct fb_vblank vblank; 404 struct fb_vblank vblank;
406 u32 trace; 405 u32 trace;
407 406
408 vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | 407 vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
409 FB_VBLANK_HAVE_VSYNC; 408 FB_VBLANK_HAVE_VSYNC;
410 trace = read_reg (0x028c0) >> 16; 409 trace = read_reg(0x028c0) >> 16;
411 if (itv->is_50hz && trace > 312) trace -= 312; 410 if (itv->is_50hz && trace > 312) trace -= 312;
412 else if (itv->is_60hz && trace > 262) trace -= 262; 411 else if (itv->is_60hz && trace > 262) trace -= 262;
413 if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING; 412 if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING;
@@ -419,12 +418,11 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
419 return 0; 418 return 0;
420 } 419 }
421 420
422 case FBIO_WAITFORVSYNC: { 421 case FBIO_WAITFORVSYNC:
423 prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); 422 prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
424 if (!schedule_timeout(HZ/20)) rc = -ETIMEDOUT; 423 if (!schedule_timeout(HZ/20)) rc = -ETIMEDOUT;
425 finish_wait (&itv->vsync_waitq, &wait); 424 finish_wait(&itv->vsync_waitq, &wait);
426 return rc; 425 return rc;
427 }
428 426
429 case IVTVFB_IOCTL_PREP_FRAME: { 427 case IVTVFB_IOCTL_PREP_FRAME: {
430 struct ivtvfb_ioctl_dma_host_to_ivtv_args args; 428 struct ivtvfb_ioctl_dma_host_to_ivtv_args args;
@@ -437,7 +435,7 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
437 } 435 }
438 436
439 default: 437 default:
440 IVTV_FB_ERR("Unknown IOCTL %d\n",cmd); 438 IVTV_FB_ERR("Unknown IOCTL %d\n", cmd);
441 return -EINVAL; 439 return -EINVAL;
442 } 440 }
443 return 0; 441 return 0;
@@ -447,7 +445,6 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
447 445
448static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) 446static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
449{ 447{
450
451 struct ivtv_osd_coords ivtv_osd; 448 struct ivtv_osd_coords ivtv_osd;
452 struct v4l2_rect ivtv_window; 449 struct v4l2_rect ivtv_window;
453 450
@@ -455,9 +452,9 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
455 452
456 /* Select color space */ 453 /* Select color space */
457 if (var->nonstd) /* YUV */ 454 if (var->nonstd) /* YUV */
458 write_reg (read_reg(0x02a00) | 0x0002000,0x02a00); 455 write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
459 else /* RGB */ 456 else /* RGB */
460 write_reg (read_reg(0x02a00) & ~0x0002000,0x02a00); 457 write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
461 458
462 /* Set the color mode 459 /* Set the color mode
463 Although rare, occasionally things go wrong. The extra mode 460 Although rare, occasionally things go wrong. The extra mode
@@ -525,8 +522,8 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
525 ivtv_window.height = var->yres; 522 ivtv_window.height = var->yres;
526 523
527 /* Minimum margin cannot be 0, as X won't allow such a mode */ 524 /* Minimum margin cannot be 0, as X won't allow such a mode */
528 if (!var->upper_margin) var->upper_margin ++; 525 if (!var->upper_margin) var->upper_margin++;
529 if (!var->left_margin) var->left_margin ++; 526 if (!var->left_margin) var->left_margin++;
530 ivtv_window.top = var->upper_margin - 1; 527 ivtv_window.top = var->upper_margin - 1;
531 ivtv_window.left = var->left_margin - 1; 528 ivtv_window.left = var->left_margin - 1;
532 529
@@ -535,48 +532,36 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
535 /* Force update of yuv registers */ 532 /* Force update of yuv registers */
536 itv->yuv_info.yuv_forced_update = 1; 533 itv->yuv_info.yuv_forced_update = 1;
537 534
538 IVTV_FB_INFO("=== Display mode change ===\n"); 535 IVTV_FB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
539 IVTV_FB_INFO("Display size %dx%d (%dx%d Virtual) @ %dbpp\n", 536 var->xres, var->yres,
540 var->xres, 537 var->xres_virtual, var->yres_virtual,
541 var->yres, 538 var->bits_per_pixel);
542 var->xres_virtual,
543 var->yres_virtual,
544 var->bits_per_pixel);
545
546 IVTV_FB_INFO("Display position %d,%d\n",
547 var->left_margin,
548 var->upper_margin);
549 539
550 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { 540 IVTV_FB_DEBUG_INFO("Display position: %d, %d\n",
551 IVTV_FB_INFO("Display filter : on\n"); 541 var->left_margin, var->upper_margin);
552 }
553 else {
554 IVTV_FB_INFO("Display filter : off\n");
555 }
556 542
557 if (var->nonstd) { 543 IVTV_FB_DEBUG_INFO("Display filter: %s\n",
558 IVTV_FB_INFO("Color space : YUV\n"); 544 (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
559 } 545 IVTV_FB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
560 else {
561 IVTV_FB_INFO("Color space : RGB\n");
562 }
563 546
564 return 0; 547 return 0;
565} 548}
566 549
567static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix) 550static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
568{ 551{
569 IVTV_FB_DEBUG_INFO ("ivtvfb_get_fix\n"); 552 struct osd_info *oi = itv->osd_info;
553
554 IVTV_FB_DEBUG_INFO("ivtvfb_get_fix\n");
570 memset(fix, 0, sizeof(struct fb_fix_screeninfo)); 555 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
571 strcpy(fix->id, "cx23415 TV out"); 556 strcpy(fix->id, "cx23415 TV out");
572 fix->smem_start = itv->osd_info->video_pbase; 557 fix->smem_start = oi->video_pbase;
573 fix->smem_len = itv->osd_info->video_buffer_size; 558 fix->smem_len = oi->video_buffer_size;
574 fix->type = FB_TYPE_PACKED_PIXELS; 559 fix->type = FB_TYPE_PACKED_PIXELS;
575 fix->visual = (itv->osd_info->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 560 fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
576 fix->xpanstep = 1; 561 fix->xpanstep = 1;
577 fix->ypanstep = 1; 562 fix->ypanstep = 1;
578 fix->ywrapstep = 0; 563 fix->ywrapstep = 0;
579 fix->line_length = itv->osd_info->display_byte_stride; 564 fix->line_length = oi->display_byte_stride;
580 fix->accel = FB_ACCEL_NONE; 565 fix->accel = FB_ACCEL_NONE;
581 return 0; 566 return 0;
582} 567}
@@ -586,14 +571,15 @@ static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
586 571
587static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) 572static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
588{ 573{
574 struct osd_info *oi = itv->osd_info;
589 int osd_height_limit = itv->is_50hz ? 576 : 480; 575 int osd_height_limit = itv->is_50hz ? 576 : 480;
590 576
591 IVTV_FB_DEBUG_INFO ("ivtvfb_check_var\n"); 577 IVTV_FB_DEBUG_INFO("ivtvfb_check_var\n");
592 578
593 /* Check the bits per pixel */ 579 /* Check the bits per pixel */
594 if (osd_compat) { 580 if (osd_compat) {
595 if (var->bits_per_pixel != 32) { 581 if (var->bits_per_pixel != 32) {
596 IVTV_FB_DEBUG_WARN ("Invalid colour mode: %d\n",var->bits_per_pixel); 582 IVTV_FB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
597 return -EINVAL; 583 return -EINVAL;
598 } 584 }
599 } 585 }
@@ -609,11 +595,12 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
609 var->blue.length = 8; 595 var->blue.length = 8;
610 } 596 }
611 else if (var->bits_per_pixel == 16) { 597 else if (var->bits_per_pixel == 16) {
598 var->transp.offset = 0;
599 var->transp.length = 0;
600
612 /* To find out the true mode, check green length */ 601 /* To find out the true mode, check green length */
613 switch (var->green.length) { 602 switch (var->green.length) {
614 case 4: 603 case 4:
615 var->transp.offset = 0;
616 var->transp.length = 0;
617 var->red.offset = 8; 604 var->red.offset = 8;
618 var->red.length = 4; 605 var->red.length = 4;
619 var->green.offset = 4; 606 var->green.offset = 4;
@@ -622,8 +609,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
622 var->blue.length = 4; 609 var->blue.length = 4;
623 break; 610 break;
624 case 5: 611 case 5:
625 var->transp.offset = 0;
626 var->transp.length = 0;
627 var->red.offset = 10; 612 var->red.offset = 10;
628 var->red.length = 5; 613 var->red.length = 5;
629 var->green.offset = 5; 614 var->green.offset = 5;
@@ -632,8 +617,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
632 var->blue.length = 5; 617 var->blue.length = 5;
633 break; 618 break;
634 default: 619 default:
635 var->transp.offset = 0;
636 var->transp.length = 0;
637 var->red.offset = 11; 620 var->red.offset = 11;
638 var->red.length = 5; 621 var->red.length = 5;
639 var->green.offset = 5; 622 var->green.offset = 5;
@@ -644,33 +627,34 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
644 } 627 }
645 } 628 }
646 else { 629 else {
647 IVTV_FB_DEBUG_WARN ("Invalid colour mode: %d\n",var->bits_per_pixel); 630 IVTV_FB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
648 return -EINVAL; 631 return -EINVAL;
649 } 632 }
650 633
651 /* Check the resolution */ 634 /* Check the resolution */
652 if (osd_compat) { 635 if (osd_compat) {
653 if (var->xres != itv->osd_info->ivtvfb_defined.xres || var->yres != itv->osd_info->ivtvfb_defined.yres || 636 if (var->xres != oi->ivtvfb_defined.xres ||
654 var->xres_virtual != itv->osd_info->ivtvfb_defined.xres_virtual || var->yres_virtual != 637 var->yres != oi->ivtvfb_defined.yres ||
655 itv->osd_info->ivtvfb_defined.yres_virtual) { 638 var->xres_virtual != oi->ivtvfb_defined.xres_virtual ||
656 IVTV_FB_DEBUG_WARN ("Invalid resolution: %d x %d (%d x %d Virtual)\n", 639 var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
657 var->xres,var->yres, var->xres_virtual,var->yres_virtual); 640 IVTV_FB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
641 var->xres, var->yres, var->xres_virtual, var->yres_virtual);
658 return -EINVAL; 642 return -EINVAL;
659 } 643 }
660 } 644 }
661 else { 645 else {
662 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit ) { 646 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
663 IVTV_FB_DEBUG_WARN ("Invalid resolution: %d x %d\n", 647 IVTV_FB_DEBUG_WARN("Invalid resolution: %dx%d\n",
664 var->xres,var->yres); 648 var->xres, var->yres);
665 return -EINVAL; 649 return -EINVAL;
666 } 650 }
667 651
668 /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ 652 /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
669 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || 653 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
670 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel/8) > itv->osd_info->video_buffer_size || 654 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
671 var->xres_virtual < var->xres || 655 var->xres_virtual < var->xres ||
672 var->yres_virtual < var->yres) { 656 var->yres_virtual < var->yres) {
673 IVTV_FB_DEBUG_WARN ("Invalid virtual resolution: %d x %d\n", 657 IVTV_FB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
674 var->xres_virtual, var->yres_virtual); 658 var->xres_virtual, var->yres_virtual);
675 return -EINVAL; 659 return -EINVAL;
676 } 660 }
@@ -680,43 +664,43 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
680 if (var->bits_per_pixel == 8) { 664 if (var->bits_per_pixel == 8) {
681 /* Width must be a multiple of 4 */ 665 /* Width must be a multiple of 4 */
682 if (var->xres & 3) { 666 if (var->xres & 3) {
683 IVTV_FB_DEBUG_WARN ("Invalid resolution for 8bpp: %d\n", var->xres); 667 IVTV_FB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
684 return -EINVAL; 668 return -EINVAL;
685 } 669 }
686 if (var->xres_virtual & 3) { 670 if (var->xres_virtual & 3) {
687 IVTV_FB_DEBUG_WARN ("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual); 671 IVTV_FB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
688 return -EINVAL; 672 return -EINVAL;
689 } 673 }
690 } 674 }
691 else if (var->bits_per_pixel == 16) { 675 else if (var->bits_per_pixel == 16) {
692 /* Width must be a multiple of 2 */ 676 /* Width must be a multiple of 2 */
693 if (var->xres & 1) { 677 if (var->xres & 1) {
694 IVTV_FB_DEBUG_WARN ("Invalid resolution for 16bpp: %d\n", var->xres); 678 IVTV_FB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
695 return -EINVAL; 679 return -EINVAL;
696 } 680 }
697 if (var->xres_virtual & 1) { 681 if (var->xres_virtual & 1) {
698 IVTV_FB_DEBUG_WARN ("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual); 682 IVTV_FB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
699 return -EINVAL; 683 return -EINVAL;
700 } 684 }
701 } 685 }
702 686
703 /* Now check the offsets */ 687 /* Now check the offsets */
704 if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) { 688 if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
705 IVTV_FB_DEBUG_WARN ("Invalid offset: %d (%d) %d (%d)\n",var->xoffset,var->xres_virtual, 689 IVTV_FB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
706 var->yoffset,var->yres_virtual); 690 var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
707 return -EINVAL; 691 return -EINVAL;
708 } 692 }
709 693
710 /* Check pixel format */ 694 /* Check pixel format */
711 if (var->nonstd > 1) { 695 if (var->nonstd > 1) {
712 IVTV_FB_DEBUG_WARN ("Invalid nonstd % d\n",var->nonstd); 696 IVTV_FB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
713 return -EINVAL; 697 return -EINVAL;
714 } 698 }
715 699
716 /* Check video mode */ 700 /* Check video mode */
717 if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) && 701 if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
718 ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) { 702 ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
719 IVTV_FB_DEBUG_WARN ("Invalid video mode: %d\n",var->vmode & FB_VMODE_MASK); 703 IVTV_FB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
720 return -EINVAL; 704 return -EINVAL;
721 } 705 }
722 706
@@ -732,8 +716,8 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
732 } 716 }
733 717
734 /* Maintain overall 'size' for a constant refresh rate */ 718 /* Maintain overall 'size' for a constant refresh rate */
735 var->right_margin = itv->osd_info->hlimit - var->left_margin - var->xres; 719 var->right_margin = oi->hlimit - var->left_margin - var->xres;
736 var->lower_margin = itv->osd_info->vlimit - var->upper_margin - var->yres; 720 var->lower_margin = oi->vlimit - var->upper_margin - var->yres;
737 721
738 /* Fixed sync times */ 722 /* Fixed sync times */
739 var->hsync_len = 24; 723 var->hsync_len = 24;
@@ -742,45 +726,29 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
742 /* Non-interlaced / interlaced mode is used to switch the OSD filter 726 /* Non-interlaced / interlaced mode is used to switch the OSD filter
743 on or off. Adjust the clock timings to maintain a constant 727 on or off. Adjust the clock timings to maintain a constant
744 vertical refresh rate. */ 728 vertical refresh rate. */
745 var->pixclock = itv->osd_info->pixclock; 729 var->pixclock = oi->pixclock;
746 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) 730 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
747 var->pixclock /= 2; 731 var->pixclock /= 2;
748 732
749 IVTV_FB_DEBUG_INFO ("ivtvfb_check_var - Parameters validated\n"); 733 IVTV_FB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
750 734 var->xres, var->yres,
751 IVTV_FB_INFO("=== Validated display mode ===\n"); 735 var->xres_virtual, var->yres_virtual,
752 IVTV_FB_INFO("Display size %dx%d (%dx%d Virtual) @ %dbpp\n",
753 var->xres,
754 var->yres,
755 var->xres_virtual,
756 var->yres_virtual,
757 var->bits_per_pixel); 736 var->bits_per_pixel);
758 737
759 IVTV_FB_INFO("Display position %d,%d\n", 738 IVTV_FB_DEBUG_INFO("Display position: %d, %d\n",
760 var->left_margin, 739 var->left_margin, var->upper_margin);
761 var->upper_margin);
762 740
763 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) { 741 IVTV_FB_DEBUG_INFO("Display filter: %s\n",
764 IVTV_FB_INFO("Display filter : on\n"); 742 (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
765 } 743 IVTV_FB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
766 else {
767 IVTV_FB_INFO("Display filter : off\n");
768 }
769
770 if (var->nonstd) {
771 IVTV_FB_INFO("Color space : YUV\n");
772 }
773 else {
774 IVTV_FB_INFO("Color space : RGB\n");
775 }
776 return 0; 744 return 0;
777} 745}
778 746
779static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 747static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
780{ 748{
781 struct ivtv *itv = (struct ivtv *) info->par; 749 struct ivtv *itv = (struct ivtv *) info->par;
782 IVTV_FB_DEBUG_INFO ("ivtvfb_check_var\n"); 750 IVTV_FB_DEBUG_INFO("ivtvfb_check_var\n");
783 return _ivtvfb_check_var (var,itv); 751 return _ivtvfb_check_var(var, itv);
784} 752}
785 753
786static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 754static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -789,7 +757,7 @@ static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf
789 struct ivtv *itv = (struct ivtv *) info->par; 757 struct ivtv *itv = (struct ivtv *) info->par;
790 758
791 osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8; 759 osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8;
792 write_reg (osd_pan_index,0x02A0C); 760 write_reg(osd_pan_index, 0x02A0C);
793 761
794 /* Pass this info back the yuv handler */ 762 /* Pass this info back the yuv handler */
795 itv->yuv_info.osd_x_pan = var->xoffset; 763 itv->yuv_info.osd_x_pan = var->xoffset;
@@ -804,11 +772,11 @@ static int ivtvfb_set_par(struct fb_info *info)
804 int rc = 0; 772 int rc = 0;
805 struct ivtv *itv = (struct ivtv *) info->par; 773 struct ivtv *itv = (struct ivtv *) info->par;
806 774
807 IVTV_FB_DEBUG_INFO ("ivtvfb_set_par\n"); 775 IVTV_FB_DEBUG_INFO("ivtvfb_set_par\n");
808 776
809 rc = ivtvfb_set_var(itv, &info->var); 777 rc = ivtvfb_set_var(itv, &info->var);
810 ivtvfb_pan_display(&info->var, info); 778 ivtvfb_pan_display(&info->var, info);
811 ivtvfb_get_fix (itv, &info->fix); 779 ivtvfb_get_fix(itv, &info->fix);
812 return rc; 780 return rc;
813} 781}
814 782
@@ -817,7 +785,7 @@ static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
817 struct fb_info *info) 785 struct fb_info *info)
818{ 786{
819 u32 color, *palette; 787 u32 color, *palette;
820 struct ivtv *itv = (struct ivtv *) info->par; 788 struct ivtv *itv = (struct ivtv *)info->par;
821 789
822 if (regno >= info->cmap.len) 790 if (regno >= info->cmap.len)
823 return -EINVAL; 791 return -EINVAL;
@@ -826,34 +794,32 @@ static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
826 if (info->var.bits_per_pixel <= 8) { 794 if (info->var.bits_per_pixel <= 8) {
827 write_reg(regno, 0x02a30); 795 write_reg(regno, 0x02a30);
828 write_reg(color, 0x02a34); 796 write_reg(color, 0x02a34);
797 return 0;
829 } 798 }
830 else { 799 if (regno >= 16)
831 if (regno >= 16) 800 return -EINVAL;
832 return -EINVAL;
833 801
834 palette = info->pseudo_palette; 802 palette = info->pseudo_palette;
835 if (info->var.bits_per_pixel == 16) { 803 if (info->var.bits_per_pixel == 16) {
836 switch (info->var.green.length) { 804 switch (info->var.green.length) {
837 case 4: 805 case 4:
838 color = ((red & 0xf000) >> 4) | 806 color = ((red & 0xf000) >> 4) |
839 ((green & 0xf000) >> 8) | 807 ((green & 0xf000) >> 8) |
840 ((blue & 0xf000) >> 12); 808 ((blue & 0xf000) >> 12);
841 break; 809 break;
842 case 5: 810 case 5:
843 color = ((red & 0xf800) >> 1) | 811 color = ((red & 0xf800) >> 1) |
844 ((green & 0xf800) >> 6) | 812 ((green & 0xf800) >> 6) |
845 ((blue & 0xf800) >> 11); 813 ((blue & 0xf800) >> 11);
846 break; 814 break;
847 case 6: 815 case 6:
848 color = (red & 0xf800 ) | 816 color = (red & 0xf800 ) |
849 ((green & 0xfc00) >> 5) | 817 ((green & 0xfc00) >> 5) |
850 ((blue & 0xf800) >> 11); 818 ((blue & 0xf800) >> 11);
851 break; 819 break;
852 }
853 } 820 }
854 palette[regno] = color;
855 } 821 }
856 822 palette[regno] = color;
857 return 0; 823 return 0;
858} 824}
859 825
@@ -863,7 +829,7 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info)
863{ 829{
864 struct ivtv *itv = (struct ivtv *)info->par; 830 struct ivtv *itv = (struct ivtv *)info->par;
865 831
866 IVTV_FB_DEBUG_INFO ("Set blanking mode : %d\n",blank_mode); 832 IVTV_FB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
867 switch (blank_mode) { 833 switch (blank_mode) {
868 case FB_BLANK_UNBLANK: 834 case FB_BLANK_UNBLANK:
869 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1); 835 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
@@ -898,27 +864,28 @@ static struct fb_ops ivtvfb_ops = {
898/* Setup our initial video mode */ 864/* Setup our initial video mode */
899static int ivtvfb_init_vidmode(struct ivtv *itv) 865static int ivtvfb_init_vidmode(struct ivtv *itv)
900{ 866{
901 int max_height; 867 struct osd_info *oi = itv->osd_info;
902 struct v4l2_rect start_window; 868 struct v4l2_rect start_window;
869 int max_height;
903 870
904 /* Set base references for mode calcs. */ 871 /* Set base references for mode calcs. */
905 if (itv->is_50hz) { 872 if (itv->is_50hz) {
906 itv->osd_info->pixclock = 84316; 873 oi->pixclock = 84316;
907 itv->osd_info->hlimit = 776; 874 oi->hlimit = 776;
908 itv->osd_info->vlimit = 591; 875 oi->vlimit = 591;
909 } 876 }
910 else { 877 else {
911 itv->osd_info->pixclock = 83926; 878 oi->pixclock = 83926;
912 itv->osd_info->hlimit = 776; 879 oi->hlimit = 776;
913 itv->osd_info->vlimit = 495; 880 oi->vlimit = 495;
914 } 881 }
915 882
916 /* Color mode */ 883 /* Color mode */
917 884
918 if (osd_compat) osd_depth = 32; 885 if (osd_compat) osd_depth = 32;
919 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8; 886 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8;
920 itv->osd_info->bits_per_pixel = osd_depth; 887 oi->bits_per_pixel = osd_depth;
921 itv->osd_info->bytes_per_pixel = itv->osd_info->bits_per_pixel / 8; 888 oi->bytes_per_pixel = oi->bits_per_pixel / 8;
922 889
923 /* Horizontal size & position */ 890 /* Horizontal size & position */
924 891
@@ -937,97 +904,93 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
937 904
938 /* Check horizontal start (osd_left). */ 905 /* Check horizontal start (osd_left). */
939 if (osd_left && osd_left + start_window.width > 721) { 906 if (osd_left && osd_left + start_window.width > 721) {
940 IVTV_FB_ERR ("Invalid osd_left - assuming default\n"); 907 IVTV_FB_ERR("Invalid osd_left - assuming default\n");
941 osd_left = 0; 908 osd_left = 0;
942 } 909 }
943 910
944 /* Hardware coords start at 0, user coords start at 1. */ 911 /* Hardware coords start at 0, user coords start at 1. */
945 osd_left --; 912 osd_left--;
946 913
947 start_window.left = 914 start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
948 osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
949 915
950 itv->osd_info->display_byte_stride = 916 oi->display_byte_stride =
951 start_window.width * itv->osd_info->bytes_per_pixel; 917 start_window.width * oi->bytes_per_pixel;
952 918
953 /* Vertical size & position */ 919 /* Vertical size & position */
954 920
955 max_height = itv->is_50hz ? 576 : 480; 921 max_height = itv->is_50hz ? 576 : 480;
956 922
957 if ( osd_yres > max_height) osd_yres = max_height; 923 if (osd_yres > max_height)
924 osd_yres = max_height;
958 925
959 if (osd_yres) 926 if (osd_yres)
960 start_window.height = osd_yres; 927 start_window.height = osd_yres;
961 else { 928 else
962 if (itv->is_50hz) 929 start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
963 start_window.height = osd_compat ? max_height : 480;
964 else
965 start_window.height = osd_compat ? max_height : 400;
966 }
967 930
968 /* Check vertical start (osd_upper). */ 931 /* Check vertical start (osd_upper). */
969 if (osd_upper + start_window.height > max_height + 1) { 932 if (osd_upper + start_window.height > max_height + 1) {
970 IVTV_FB_ERR ("Invalid osd_upper - assuming default\n"); 933 IVTV_FB_ERR("Invalid osd_upper - assuming default\n");
971 osd_upper = 0; 934 osd_upper = 0;
972 } 935 }
973 936
974 /* Hardware coords start at 0, user coords start at 1. */ 937 /* Hardware coords start at 0, user coords start at 1. */
975 osd_upper --; 938 osd_upper--;
976 939
977 start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2); 940 start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
978 941
979 itv->osd_info->display_width = start_window.width; 942 oi->display_width = start_window.width;
980 itv->osd_info->display_height = start_window.height; 943 oi->display_height = start_window.height;
981 944
982 /* Generate a valid fb_var_screeninfo */ 945 /* Generate a valid fb_var_screeninfo */
983 946
984 itv->osd_info->ivtvfb_defined.xres = itv->osd_info->display_width; 947 oi->ivtvfb_defined.xres = oi->display_width;
985 itv->osd_info->ivtvfb_defined.yres = itv->osd_info->display_height; 948 oi->ivtvfb_defined.yres = oi->display_height;
986 itv->osd_info->ivtvfb_defined.xres_virtual = itv->osd_info->display_width; 949 oi->ivtvfb_defined.xres_virtual = oi->display_width;
987 itv->osd_info->ivtvfb_defined.yres_virtual = itv->osd_info->display_height; 950 oi->ivtvfb_defined.yres_virtual = oi->display_height;
988 itv->osd_info->ivtvfb_defined.bits_per_pixel = itv->osd_info->bits_per_pixel; 951 oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
989 itv->osd_info->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED); 952 oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
990 itv->osd_info->ivtvfb_defined.left_margin = start_window.left + 1; 953 oi->ivtvfb_defined.left_margin = start_window.left + 1;
991 itv->osd_info->ivtvfb_defined.upper_margin = start_window.top + 1; 954 oi->ivtvfb_defined.upper_margin = start_window.top + 1;
992 itv->osd_info->ivtvfb_defined.accel_flags = FB_ACCEL_NONE; 955 oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
993 itv->osd_info->ivtvfb_defined.nonstd = 0; 956 oi->ivtvfb_defined.nonstd = 0;
994 957
995 /* We've filled in the most data, let the usual mode check 958 /* We've filled in the most data, let the usual mode check
996 routine fill in the rest. */ 959 routine fill in the rest. */
997 _ivtvfb_check_var (&itv->osd_info->ivtvfb_defined,itv); 960 _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
998 961
999 /* Generate valid fb_fix_screeninfo */ 962 /* Generate valid fb_fix_screeninfo */
1000 963
1001 ivtvfb_get_fix(itv,&itv->osd_info->ivtvfb_fix); 964 ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
1002 965
1003 /* Generate valid fb_info */ 966 /* Generate valid fb_info */
1004 967
1005 itv->osd_info->ivtvfb_info.node = -1; 968 oi->ivtvfb_info.node = -1;
1006 itv->osd_info->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT; 969 oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
1007 itv->osd_info->ivtvfb_info.fbops = &ivtvfb_ops; 970 oi->ivtvfb_info.fbops = &ivtvfb_ops;
1008 itv->osd_info->ivtvfb_info.par = itv; 971 oi->ivtvfb_info.par = itv;
1009 itv->osd_info->ivtvfb_info.var = itv->osd_info->ivtvfb_defined; 972 oi->ivtvfb_info.var = oi->ivtvfb_defined;
1010 itv->osd_info->ivtvfb_info.fix = itv->osd_info->ivtvfb_fix; 973 oi->ivtvfb_info.fix = oi->ivtvfb_fix;
1011 itv->osd_info->ivtvfb_info.screen_base = (u8 __iomem *)itv->osd_info->video_vbase; 974 oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
1012 itv->osd_info->ivtvfb_info.fbops = &ivtvfb_ops; 975 oi->ivtvfb_info.fbops = &ivtvfb_ops;
1013 976
1014 /* Supply some monitor specs. Bogus values will do for now */ 977 /* Supply some monitor specs. Bogus values will do for now */
1015 itv->osd_info->ivtvfb_info.monspecs.hfmin = 8000; 978 oi->ivtvfb_info.monspecs.hfmin = 8000;
1016 itv->osd_info->ivtvfb_info.monspecs.hfmax = 70000; 979 oi->ivtvfb_info.monspecs.hfmax = 70000;
1017 itv->osd_info->ivtvfb_info.monspecs.vfmin = 10; 980 oi->ivtvfb_info.monspecs.vfmin = 10;
1018 itv->osd_info->ivtvfb_info.monspecs.vfmax = 100; 981 oi->ivtvfb_info.monspecs.vfmax = 100;
1019 982
1020 /* Allocate color map */ 983 /* Allocate color map */
1021 if (fb_alloc_cmap(&itv->osd_info->ivtvfb_info.cmap, 256, 1)) { 984 if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
1022 IVTV_FB_ERR ("abort, unable to alloc cmap\n"); 985 IVTV_FB_ERR("abort, unable to alloc cmap\n");
1023 return -ENOMEM; 986 return -ENOMEM;
1024 } 987 }
1025 988
1026 /* Allocate the pseudo palette */ 989 /* Allocate the pseudo palette */
1027 itv->osd_info->ivtvfb_info.pseudo_palette = kmalloc(sizeof (u32) * 16, GFP_KERNEL); 990 oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
1028 991
1029 if (!itv->osd_info->ivtvfb_info.pseudo_palette) { 992 if (!oi->ivtvfb_info.pseudo_palette) {
1030 IVTV_FB_ERR ("abort, unable to alloc pseudo pallete\n"); 993 IVTV_FB_ERR("abort, unable to alloc pseudo pallete\n");
1031 return -ENOMEM; 994 return -ENOMEM;
1032 } 995 }
1033 996
@@ -1038,51 +1001,53 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
1038 1001
1039static int ivtvfb_init_io(struct ivtv *itv) 1002static int ivtvfb_init_io(struct ivtv *itv)
1040{ 1003{
1041 ivtv_fb_get_framebuffer(itv, &itv->osd_info->video_rbase, &itv->osd_info->video_buffer_size); 1004 struct osd_info *oi = itv->osd_info;
1005
1006 ivtv_fb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size);
1042 1007
1043 /* The osd buffer size depends on the number of video buffers allocated 1008 /* The osd buffer size depends on the number of video buffers allocated
1044 on the PVR350 itself. For now we'll hardcode the smallest osd buffer 1009 on the PVR350 itself. For now we'll hardcode the smallest osd buffer
1045 size to prevent any overlap. */ 1010 size to prevent any overlap. */
1046 itv->osd_info->video_buffer_size = 1704960; 1011 oi->video_buffer_size = 1704960;
1047 1012
1048 itv->osd_info->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + itv->osd_info->video_rbase; 1013 oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
1049 itv->osd_info->video_vbase = itv->dec_mem + itv->osd_info->video_rbase; 1014 oi->video_vbase = itv->dec_mem + oi->video_rbase;
1050 1015
1051 if (!itv->osd_info->video_vbase) { 1016 if (!oi->video_vbase) {
1052 IVTV_FB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n", 1017 IVTV_FB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
1053 itv->osd_info->video_buffer_size, itv->osd_info->video_pbase); 1018 oi->video_buffer_size, oi->video_pbase);
1054 return -EIO; 1019 return -EIO;
1055 } 1020 }
1056 1021
1057 IVTV_FB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", 1022 IVTV_FB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
1058 itv->osd_info->video_pbase, itv->osd_info->video_vbase, 1023 oi->video_pbase, oi->video_vbase,
1059 itv->osd_info->video_buffer_size / 1024); 1024 oi->video_buffer_size / 1024);
1060 1025
1061#ifdef CONFIG_MTRR 1026#ifdef CONFIG_MTRR
1062 { 1027 {
1063 /* Find the largest power of two that maps the whole buffer */ 1028 /* Find the largest power of two that maps the whole buffer */
1064 int size_shift = 31; 1029 int size_shift = 31;
1065 1030
1066 while (!(itv->osd_info->video_buffer_size & (1 << size_shift))) { 1031 while (!(oi->video_buffer_size & (1 << size_shift))) {
1067 size_shift--; 1032 size_shift--;
1068 } 1033 }
1069 size_shift++; 1034 size_shift++;
1070 itv->osd_info->fb_start_aligned_physaddr = itv->osd_info->video_pbase & ~((1 << size_shift) - 1); 1035 oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
1071 itv->osd_info->fb_end_aligned_physaddr = itv->osd_info->video_pbase + itv->osd_info->video_buffer_size; 1036 oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
1072 itv->osd_info->fb_end_aligned_physaddr += (1 << size_shift) - 1; 1037 oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
1073 itv->osd_info->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1); 1038 oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
1074 if (mtrr_add(itv->osd_info->fb_start_aligned_physaddr, 1039 if (mtrr_add(oi->fb_start_aligned_physaddr,
1075 itv->osd_info->fb_end_aligned_physaddr - itv->osd_info->fb_start_aligned_physaddr, 1040 oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
1076 MTRR_TYPE_WRCOMB, 1) < 0) { 1041 MTRR_TYPE_WRCOMB, 1) < 0) {
1077 IVTV_FB_ERR("warning: mtrr_add() failed to add write combining region 0x%08x-0x%08x\n", 1042 IVTV_FB_WARN("cannot use mttr\n");
1078 (unsigned int)itv->osd_info->fb_start_aligned_physaddr, 1043 oi->fb_start_aligned_physaddr = 0;
1079 (unsigned int)itv->osd_info->fb_end_aligned_physaddr); 1044 oi->fb_end_aligned_physaddr = 0;
1080 } 1045 }
1081 } 1046 }
1082#endif /* CONFIG_MTRR */ 1047#endif
1083 1048
1084 /* Blank the entire osd. */ 1049 /* Blank the entire osd. */
1085 memset_io(itv->osd_info->video_vbase, 0, itv->osd_info->video_buffer_size); 1050 memset_io(oi->video_vbase, 0, oi->video_buffer_size);
1086 1051
1087 return 0; 1052 return 0;
1088} 1053}
@@ -1090,26 +1055,30 @@ static int ivtvfb_init_io(struct ivtv *itv)
1090/* Release any memory we've grabbed & remove mtrr entry */ 1055/* Release any memory we've grabbed & remove mtrr entry */
1091static void ivtvfb_release_buffers (struct ivtv *itv) 1056static void ivtvfb_release_buffers (struct ivtv *itv)
1092{ 1057{
1058 struct osd_info *oi = itv->osd_info;
1059
1093 /* Release cmap */ 1060 /* Release cmap */
1094 if (itv->osd_info->ivtvfb_info.cmap.len); 1061 if (oi->ivtvfb_info.cmap.len);
1095 fb_dealloc_cmap(&itv->osd_info->ivtvfb_info.cmap); 1062 fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
1096 1063
1097 /* Release pseudo palette */ 1064 /* Release pseudo palette */
1098 if (itv->osd_info->ivtvfb_info.pseudo_palette) 1065 if (oi->ivtvfb_info.pseudo_palette)
1099 kfree(itv->osd_info->ivtvfb_info.pseudo_palette); 1066 kfree(oi->ivtvfb_info.pseudo_palette);
1100 1067
1101#ifdef CONFIG_MTRR 1068#ifdef CONFIG_MTRR
1102 mtrr_del(-1, itv->osd_info->fb_start_aligned_physaddr, 1069 if (oi->fb_end_aligned_physaddr) {
1103 (itv->osd_info->fb_end_aligned_physaddr - itv->osd_info->fb_start_aligned_physaddr)); 1070 mtrr_del(-1, oi->fb_start_aligned_physaddr,
1104#endif /* CONFIG_MTRR */ 1071 oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
1072 }
1073#endif
1105 1074
1106 kfree(itv->osd_info); 1075 kfree(oi);
1107 itv->osd_info = NULL; 1076 itv->osd_info = NULL;
1108} 1077}
1109 1078
1110/* Initialize the specified card */ 1079/* Initialize the specified card */
1111 1080
1112static int ivtvfb_init_card (struct ivtv *itv) 1081static int ivtvfb_init_card(struct ivtv *itv)
1113{ 1082{
1114 int rc; 1083 int rc;
1115 1084
@@ -1125,11 +1094,11 @@ static int ivtvfb_init_card (struct ivtv *itv)
1125 } 1094 }
1126 1095
1127 /* Find & setup the OSD buffer */ 1096 /* Find & setup the OSD buffer */
1128 if ((rc = ivtvfb_init_io (itv))) 1097 if ((rc = ivtvfb_init_io(itv)))
1129 return rc; 1098 return rc;
1130 1099
1131 /* Set the startup video mode information */ 1100 /* Set the startup video mode information */
1132 if ((rc = ivtvfb_init_vidmode (itv))) { 1101 if ((rc = ivtvfb_init_vidmode(itv))) {
1133 ivtvfb_release_buffers(itv); 1102 ivtvfb_release_buffers(itv);
1134 return rc; 1103 return rc;
1135 } 1104 }