diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-07-20 09:16:03 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:03:03 -0400 |
commit | be383bd312c4defab8bd4bde8c06fea5bfe0996b (patch) | |
tree | 359ef4f3b45464b31ad1c849e60efbc478d06e93 /drivers | |
parent | 32db775452818656d5fd8fd8b0f54425f5cfc177 (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.c | 439 |
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 | ||
113 | MODULE_PARM_DESC(osd_depth, | 113 | MODULE_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 | ||
117 | MODULE_PARM_DESC(osd_upper, | 117 | MODULE_PARM_DESC(osd_upper, |
@@ -232,12 +232,13 @@ static int ivtv_fb_get_framebuffer(struct ivtv *itv, u32 *fbbase, | |||
232 | static int ivtv_fb_get_osd_coords(struct ivtv *itv, | 232 | static 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 | ||
248 | static int ivtv_fb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd) | 249 | static 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 | ||
261 | static int ivtv_fb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window) | 264 | static 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 | ||
347 | static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, unsigned long dest_offset, int count) | 349 | static 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 | ||
448 | static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | 446 | static 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 | ||
567 | static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix) | 550 | static 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 | ||
587 | static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) | 572 | static 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 | ||
779 | static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 747 | static 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 | ||
786 | static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 754 | static 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 */ |
899 | static int ivtvfb_init_vidmode(struct ivtv *itv) | 865 | static 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 | ||
1039 | static int ivtvfb_init_io(struct ivtv *itv) | 1002 | static 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 */ |
1091 | static void ivtvfb_release_buffers (struct ivtv *itv) | 1056 | static 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 | ||
1112 | static int ivtvfb_init_card (struct ivtv *itv) | 1081 | static 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 | } |