aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtvfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtvfb.c')
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c92
1 files changed, 25 insertions, 67 deletions
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 9684048fe56c..52ffd154a3d8 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -55,7 +55,6 @@
55static int ivtvfb_card_id = -1; 55static int ivtvfb_card_id = -1;
56static int ivtvfb_debug = 0; 56static int ivtvfb_debug = 0;
57static int osd_laced; 57static int osd_laced;
58static int osd_compat;
59static int osd_depth; 58static int osd_depth;
60static int osd_upper; 59static int osd_upper;
61static int osd_left; 60static int osd_left;
@@ -65,7 +64,6 @@ static int osd_xres;
65module_param(ivtvfb_card_id, int, 0444); 64module_param(ivtvfb_card_id, int, 0444);
66module_param_named(debug,ivtvfb_debug, int, 0644); 65module_param_named(debug,ivtvfb_debug, int, 0644);
67module_param(osd_laced, bool, 0444); 66module_param(osd_laced, bool, 0444);
68module_param(osd_compat, bool, 0444);
69module_param(osd_depth, int, 0444); 67module_param(osd_depth, int, 0444);
70module_param(osd_upper, int, 0444); 68module_param(osd_upper, int, 0444);
71module_param(osd_left, int, 0444); 69module_param(osd_left, int, 0444);
@@ -80,12 +78,6 @@ MODULE_PARM_DESC(debug,
80 "Debug level (bitmask). Default: errors only\n" 78 "Debug level (bitmask). Default: errors only\n"
81 "\t\t\t(debug = 3 gives full debugging)"); 79 "\t\t\t(debug = 3 gives full debugging)");
82 80
83MODULE_PARM_DESC(osd_compat,
84 "Compatibility mode - Display size is locked (use for old X drivers)\n"
85 "\t\t\t0=off\n"
86 "\t\t\t1=on\n"
87 "\t\t\tdefault off");
88
89/* Why upper, left, xres, yres, depth, laced ? To match terminology used 81/* Why upper, left, xres, yres, depth, laced ? To match terminology used
90 by fbset. 82 by fbset.
91 Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ 83 Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
@@ -166,9 +158,6 @@ struct osd_info {
166 unsigned long fb_end_aligned_physaddr; 158 unsigned long fb_end_aligned_physaddr;
167#endif 159#endif
168 160
169 /* Current osd mode */
170 int osd_mode;
171
172 /* Store the buffer offset */ 161 /* Store the buffer offset */
173 int set_osd_coords_x; 162 int set_osd_coords_x;
174 int set_osd_coords_y; 163 int set_osd_coords_y;
@@ -470,13 +459,11 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
470 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); 459 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
471 } 460 }
472 461
473 /* Change osd mode if needed. 462 /* Set video mode. Although rare, the display can become scrambled even
474 Although rare, things can go wrong. The extra mode 463 if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
475 change seems to help... */ 464 if (osd_mode != -1) {
476 if (osd_mode != -1 && osd_mode != oi->osd_mode) {
477 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); 465 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
478 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode); 466 ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
479 oi->osd_mode = osd_mode;
480 } 467 }
481 468
482 oi->bits_per_pixel = var->bits_per_pixel; 469 oi->bits_per_pixel = var->bits_per_pixel;
@@ -579,14 +566,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
579 osd_height_limit = 480; 566 osd_height_limit = 480;
580 } 567 }
581 568
582 /* Check the bits per pixel */
583 if (osd_compat) {
584 if (var->bits_per_pixel != 32) {
585 IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
586 return -EINVAL;
587 }
588 }
589
590 if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { 569 if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
591 var->transp.offset = 24; 570 var->transp.offset = 24;
592 var->transp.length = 8; 571 var->transp.length = 8;
@@ -638,32 +617,20 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
638 } 617 }
639 618
640 /* Check the resolution */ 619 /* Check the resolution */
641 if (osd_compat) { 620 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
642 if (var->xres != oi->ivtvfb_defined.xres || 621 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
643 var->yres != oi->ivtvfb_defined.yres || 622 var->xres, var->yres);
644 var->xres_virtual != oi->ivtvfb_defined.xres_virtual || 623 return -EINVAL;
645 var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
646 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
647 var->xres, var->yres, var->xres_virtual, var->yres_virtual);
648 return -EINVAL;
649 }
650 } 624 }
651 else {
652 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
653 IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
654 var->xres, var->yres);
655 return -EINVAL;
656 }
657 625
658 /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */ 626 /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
659 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || 627 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
660 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || 628 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
661 var->xres_virtual < var->xres || 629 var->xres_virtual < var->xres ||
662 var->yres_virtual < var->yres) { 630 var->yres_virtual < var->yres) {
663 IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n", 631 IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
664 var->xres_virtual, var->yres_virtual); 632 var->xres_virtual, var->yres_virtual);
665 return -EINVAL; 633 return -EINVAL;
666 }
667 } 634 }
668 635
669 /* Some extra checks if in 8 bit mode */ 636 /* Some extra checks if in 8 bit mode */
@@ -877,17 +844,15 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
877 844
878 /* Color mode */ 845 /* Color mode */
879 846
880 if (osd_compat) osd_depth = 32; 847 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
881 if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8; 848 osd_depth = 8;
882 oi->bits_per_pixel = osd_depth; 849 oi->bits_per_pixel = osd_depth;
883 oi->bytes_per_pixel = oi->bits_per_pixel / 8; 850 oi->bytes_per_pixel = oi->bits_per_pixel / 8;
884 851
885 /* Invalidate current osd mode to force a mode switch later */
886 oi->osd_mode = -1;
887
888 /* Horizontal size & position */ 852 /* Horizontal size & position */
889 853
890 if (osd_xres > 720) osd_xres = 720; 854 if (osd_xres > 720)
855 osd_xres = 720;
891 856
892 /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */ 857 /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
893 if (osd_depth == 8) 858 if (osd_depth == 8)
@@ -895,10 +860,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
895 else if (osd_depth == 16) 860 else if (osd_depth == 16)
896 osd_xres &= ~1; 861 osd_xres &= ~1;
897 862
898 if (osd_xres) 863 start_window.width = osd_xres ? osd_xres : 640;
899 start_window.width = osd_xres;
900 else
901 start_window.width = osd_compat ? 720: 640;
902 864
903 /* Check horizontal start (osd_left). */ 865 /* Check horizontal start (osd_left). */
904 if (osd_left && osd_left + start_window.width > 721) { 866 if (osd_left && osd_left + start_window.width > 721) {
@@ -921,10 +883,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
921 if (osd_yres > max_height) 883 if (osd_yres > max_height)
922 osd_yres = max_height; 884 osd_yres = max_height;
923 885
924 if (osd_yres) 886 start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
925 start_window.height = osd_yres;
926 else
927 start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
928 887
929 /* Check vertical start (osd_upper). */ 888 /* Check vertical start (osd_upper). */
930 if (osd_upper + start_window.height > max_height + 1) { 889 if (osd_upper + start_window.height > max_height + 1) {
@@ -1127,10 +1086,6 @@ static int ivtvfb_init_card(struct ivtv *itv)
1127 /* Enable the osd */ 1086 /* Enable the osd */
1128 ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); 1087 ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
1129 1088
1130 /* Note if we're running in compatibility mode */
1131 if (osd_compat)
1132 IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n");
1133
1134 /* Allocate DMA */ 1089 /* Allocate DMA */
1135 ivtv_udma_alloc(itv); 1090 ivtv_udma_alloc(itv);
1136 return 0; 1091 return 0;
@@ -1177,9 +1132,12 @@ static void ivtvfb_cleanup(void)
1177 for (i = 0; i < ivtv_cards_active; i++) { 1132 for (i = 0; i < ivtv_cards_active; i++) {
1178 itv = ivtv_cards[i]; 1133 itv = ivtv_cards[i];
1179 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { 1134 if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) {
1135 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
1136 IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i);
1137 return;
1138 }
1180 IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); 1139 IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
1181 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); 1140 ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
1182 unregister_framebuffer(&itv->osd_info->ivtvfb_info);
1183 ivtvfb_release_buffers(itv); 1141 ivtvfb_release_buffers(itv);
1184 itv->osd_video_pbase = 0; 1142 itv->osd_video_pbase = 0;
1185 } 1143 }