diff options
author | Ian Armstrong <ian@iarmst.co.uk> | 2007-07-21 15:43:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:03:08 -0400 |
commit | aaf9fa21b684509973dd593e30423fc0a6a5e7a3 (patch) | |
tree | 404e36cfcdd643dcfa261327da336c57db0b9c05 | |
parent | 84149a0f70a73385ee7fbb77024544cbed4fe16d (diff) |
V4L/DVB (5908): ivtv-fb: cleanups, prevent fw calls in some cases
Signed-off-by: Ian Armstrong <ian@iarmst.co.uk>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fb.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fb.c b/drivers/media/video/ivtv/ivtv-fb.c index 6f5da57299a1..56ce5c08bbb3 100644 --- a/drivers/media/video/ivtv/ivtv-fb.c +++ b/drivers/media/video/ivtv/ivtv-fb.c | |||
@@ -185,6 +185,9 @@ struct osd_info { | |||
185 | unsigned long fb_end_aligned_physaddr; | 185 | unsigned long fb_end_aligned_physaddr; |
186 | #endif | 186 | #endif |
187 | 187 | ||
188 | /* Current osd mode */ | ||
189 | int osd_mode; | ||
190 | |||
188 | /* Store the buffer offset */ | 191 | /* Store the buffer offset */ |
189 | int set_osd_coords_x; | 192 | int set_osd_coords_x; |
190 | int set_osd_coords_y; | 193 | int set_osd_coords_y; |
@@ -350,6 +353,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | |||
350 | unsigned long dest_offset, int count) | 353 | unsigned long dest_offset, int count) |
351 | { | 354 | { |
352 | DEFINE_WAIT(wait); | 355 | DEFINE_WAIT(wait); |
356 | struct osd_info *oi = itv->osd_info; | ||
353 | 357 | ||
354 | /* Nothing to do */ | 358 | /* Nothing to do */ |
355 | if (count == 0) { | 359 | if (count == 0) { |
@@ -358,9 +362,9 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | |||
358 | } | 362 | } |
359 | 363 | ||
360 | /* Check Total FB Size */ | 364 | /* Check Total FB Size */ |
361 | if ((dest_offset + count) > itv->osd_info->video_buffer_size) { | 365 | if ((dest_offset + count) > oi->video_buffer_size) { |
362 | IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n", | 366 | IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n", |
363 | dest_offset + count, itv->osd_info->video_buffer_size); | 367 | dest_offset + count, oi->video_buffer_size); |
364 | return -E2BIG; | 368 | return -E2BIG; |
365 | } | 369 | } |
366 | 370 | ||
@@ -387,7 +391,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, | |||
387 | } | 391 | } |
388 | 392 | ||
389 | /* OSD Address to send DMA to */ | 393 | /* OSD Address to send DMA to */ |
390 | dest_offset += IVTV_DEC_MEM_START + itv->osd_info->video_rbase; | 394 | dest_offset += IVTV_DEC_MEM_START + oi->video_rbase; |
391 | 395 | ||
392 | /* Fill Buffers */ | 396 | /* Fill Buffers */ |
393 | return ivtv_fb_prep_dec_dma_to_device(itv, dest_offset, source, count); | 397 | return ivtv_fb_prep_dec_dma_to_device(itv, dest_offset, source, count); |
@@ -445,8 +449,10 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar | |||
445 | 449 | ||
446 | static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | 450 | static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) |
447 | { | 451 | { |
452 | struct osd_info *oi = itv->osd_info; | ||
448 | struct ivtv_osd_coords ivtv_osd; | 453 | struct ivtv_osd_coords ivtv_osd; |
449 | struct v4l2_rect ivtv_window; | 454 | struct v4l2_rect ivtv_window; |
455 | int osd_mode = -1; | ||
450 | 456 | ||
451 | IVTV_FB_DEBUG_INFO("ivtvfb_set_var\n"); | 457 | IVTV_FB_DEBUG_INFO("ivtvfb_set_var\n"); |
452 | 458 | ||
@@ -456,32 +462,24 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | |||
456 | else /* RGB */ | 462 | else /* RGB */ |
457 | write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00); | 463 | write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00); |
458 | 464 | ||
459 | /* Set the color mode | 465 | /* Set the color mode */ |
460 | Although rare, occasionally things go wrong. The extra mode | ||
461 | change seems to help... */ | ||
462 | |||
463 | switch (var->bits_per_pixel) { | 466 | switch (var->bits_per_pixel) { |
464 | case 8: | 467 | case 8: |
465 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 468 | osd_mode = IVTV_OSD_BPP_8; |
466 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_8); | ||
467 | break; | 469 | break; |
468 | case 32: | 470 | case 32: |
469 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 471 | osd_mode = IVTV_OSD_BPP_32; |
470 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_32); | ||
471 | break; | 472 | break; |
472 | case 16: | 473 | case 16: |
473 | switch (var->green.length) { | 474 | switch (var->green.length) { |
474 | case 4: | 475 | case 4: |
475 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 476 | osd_mode = IVTV_OSD_BPP_16_444; |
476 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_444); | ||
477 | break; | 477 | break; |
478 | case 5: | 478 | case 5: |
479 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 479 | osd_mode = IVTV_OSD_BPP_16_555; |
480 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_555); | ||
481 | break; | 480 | break; |
482 | case 6: | 481 | case 6: |
483 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | 482 | osd_mode = IVTV_OSD_BPP_16_565; |
484 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_565); | ||
485 | break; | 483 | break; |
486 | default: | 484 | default: |
487 | IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); | 485 | IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); |
@@ -491,8 +489,17 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) | |||
491 | IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); | 489 | IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); |
492 | } | 490 | } |
493 | 491 | ||
494 | itv->osd_info->bits_per_pixel = var->bits_per_pixel; | 492 | /* Change osd mode if needed. |
495 | itv->osd_info->bytes_per_pixel = var->bits_per_pixel / 8; | 493 | Although rare, things can go wrong. The extra mode |
494 | change seems to help... */ | ||
495 | if (osd_mode != -1 && osd_mode != oi->osd_mode) { | ||
496 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); | ||
497 | ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); | ||
498 | oi->osd_mode = osd_mode; | ||
499 | } | ||
500 | |||
501 | oi->bits_per_pixel = var->bits_per_pixel; | ||
502 | oi->bytes_per_pixel = var->bits_per_pixel / 8; | ||
496 | 503 | ||
497 | /* Set the flicker filter */ | 504 | /* Set the flicker filter */ |
498 | switch (var->vmode & FB_VMODE_MASK) { | 505 | switch (var->vmode & FB_VMODE_MASK) { |
@@ -887,6 +894,9 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) | |||
887 | oi->bits_per_pixel = osd_depth; | 894 | oi->bits_per_pixel = osd_depth; |
888 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; | 895 | oi->bytes_per_pixel = oi->bits_per_pixel / 8; |
889 | 896 | ||
897 | /* Invalidate current osd mode to force a mode switch later */ | ||
898 | oi->osd_mode = -1; | ||
899 | |||
890 | /* Horizontal size & position */ | 900 | /* Horizontal size & position */ |
891 | 901 | ||
892 | if (osd_xres > 720) osd_xres = 720; | 902 | if (osd_xres > 720) osd_xres = 720; |