diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-yuv.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.c | 160 |
1 files changed, 84 insertions, 76 deletions
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index e2288f224ab6..9091c4837bbc 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -710,7 +710,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo | |||
710 | 710 | ||
711 | /* If there's nothing to safe to display, we may as well stop now */ | 711 | /* If there's nothing to safe to display, we may as well stop now */ |
712 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { | 712 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { |
713 | return 0; | 713 | return IVTV_YUV_UPDATE_INVALID; |
714 | } | 714 | } |
715 | 715 | ||
716 | /* Ensure video remains inside OSD area */ | 716 | /* Ensure video remains inside OSD area */ |
@@ -791,7 +791,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo | |||
791 | 791 | ||
792 | /* Check again. If there's nothing to safe to display, stop now */ | 792 | /* Check again. If there's nothing to safe to display, stop now */ |
793 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { | 793 | if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) { |
794 | return 0; | 794 | return IVTV_YUV_UPDATE_INVALID; |
795 | } | 795 | } |
796 | 796 | ||
797 | /* Both x offset & width are linked, so they have to be done together */ | 797 | /* Both x offset & width are linked, so they have to be done together */ |
@@ -840,110 +840,118 @@ void ivtv_yuv_work_handler (struct ivtv *itv) | |||
840 | if (!(yuv_update = ivtv_yuv_window_setup (itv, &window))) | 840 | if (!(yuv_update = ivtv_yuv_window_setup (itv, &window))) |
841 | return; | 841 | return; |
842 | 842 | ||
843 | /* Update horizontal settings */ | 843 | if (yuv_update & IVTV_YUV_UPDATE_INVALID) { |
844 | if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL) | 844 | write_reg(0x01008080, 0x2898); |
845 | ivtv_yuv_handle_horizontal(itv, &window); | 845 | } else if (yuv_update) { |
846 | write_reg(0x00108080, 0x2898); | ||
846 | 847 | ||
847 | if (yuv_update & IVTV_YUV_UPDATE_VERTICAL) | 848 | if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL) |
848 | ivtv_yuv_handle_vertical(itv, &window); | 849 | ivtv_yuv_handle_horizontal(itv, &window); |
850 | |||
851 | if (yuv_update & IVTV_YUV_UPDATE_VERTICAL) | ||
852 | ivtv_yuv_handle_vertical(itv, &window); | ||
853 | } | ||
849 | 854 | ||
850 | memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info)); | 855 | memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info)); |
851 | } | 856 | } |
852 | 857 | ||
853 | static void ivtv_yuv_init (struct ivtv *itv) | 858 | static void ivtv_yuv_init (struct ivtv *itv) |
854 | { | 859 | { |
860 | struct yuv_playback_info *yi = &itv->yuv_info; | ||
861 | |||
855 | IVTV_DEBUG_YUV("ivtv_yuv_init\n"); | 862 | IVTV_DEBUG_YUV("ivtv_yuv_init\n"); |
856 | 863 | ||
857 | /* Take a snapshot of the current register settings */ | 864 | /* Take a snapshot of the current register settings */ |
858 | itv->yuv_info.reg_2834 = read_reg(0x02834); | 865 | yi->reg_2834 = read_reg(0x02834); |
859 | itv->yuv_info.reg_2838 = read_reg(0x02838); | 866 | yi->reg_2838 = read_reg(0x02838); |
860 | itv->yuv_info.reg_283c = read_reg(0x0283c); | 867 | yi->reg_283c = read_reg(0x0283c); |
861 | itv->yuv_info.reg_2840 = read_reg(0x02840); | 868 | yi->reg_2840 = read_reg(0x02840); |
862 | itv->yuv_info.reg_2844 = read_reg(0x02844); | 869 | yi->reg_2844 = read_reg(0x02844); |
863 | itv->yuv_info.reg_2848 = read_reg(0x02848); | 870 | yi->reg_2848 = read_reg(0x02848); |
864 | itv->yuv_info.reg_2854 = read_reg(0x02854); | 871 | yi->reg_2854 = read_reg(0x02854); |
865 | itv->yuv_info.reg_285c = read_reg(0x0285c); | 872 | yi->reg_285c = read_reg(0x0285c); |
866 | itv->yuv_info.reg_2864 = read_reg(0x02864); | 873 | yi->reg_2864 = read_reg(0x02864); |
867 | itv->yuv_info.reg_2870 = read_reg(0x02870); | 874 | yi->reg_2870 = read_reg(0x02870); |
868 | itv->yuv_info.reg_2874 = read_reg(0x02874); | 875 | yi->reg_2874 = read_reg(0x02874); |
869 | itv->yuv_info.reg_2898 = read_reg(0x02898); | 876 | yi->reg_2898 = read_reg(0x02898); |
870 | itv->yuv_info.reg_2890 = read_reg(0x02890); | 877 | yi->reg_2890 = read_reg(0x02890); |
871 | 878 | ||
872 | itv->yuv_info.reg_289c = read_reg(0x0289c); | 879 | yi->reg_289c = read_reg(0x0289c); |
873 | itv->yuv_info.reg_2918 = read_reg(0x02918); | 880 | yi->reg_2918 = read_reg(0x02918); |
874 | itv->yuv_info.reg_291c = read_reg(0x0291c); | 881 | yi->reg_291c = read_reg(0x0291c); |
875 | itv->yuv_info.reg_2920 = read_reg(0x02920); | 882 | yi->reg_2920 = read_reg(0x02920); |
876 | itv->yuv_info.reg_2924 = read_reg(0x02924); | 883 | yi->reg_2924 = read_reg(0x02924); |
877 | itv->yuv_info.reg_2928 = read_reg(0x02928); | 884 | yi->reg_2928 = read_reg(0x02928); |
878 | itv->yuv_info.reg_292c = read_reg(0x0292c); | 885 | yi->reg_292c = read_reg(0x0292c); |
879 | itv->yuv_info.reg_2930 = read_reg(0x02930); | 886 | yi->reg_2930 = read_reg(0x02930); |
880 | itv->yuv_info.reg_2934 = read_reg(0x02934); | 887 | yi->reg_2934 = read_reg(0x02934); |
881 | itv->yuv_info.reg_2938 = read_reg(0x02938); | 888 | yi->reg_2938 = read_reg(0x02938); |
882 | itv->yuv_info.reg_293c = read_reg(0x0293c); | 889 | yi->reg_293c = read_reg(0x0293c); |
883 | itv->yuv_info.reg_2940 = read_reg(0x02940); | 890 | yi->reg_2940 = read_reg(0x02940); |
884 | itv->yuv_info.reg_2944 = read_reg(0x02944); | 891 | yi->reg_2944 = read_reg(0x02944); |
885 | itv->yuv_info.reg_2948 = read_reg(0x02948); | 892 | yi->reg_2948 = read_reg(0x02948); |
886 | itv->yuv_info.reg_294c = read_reg(0x0294c); | 893 | yi->reg_294c = read_reg(0x0294c); |
887 | itv->yuv_info.reg_2950 = read_reg(0x02950); | 894 | yi->reg_2950 = read_reg(0x02950); |
888 | itv->yuv_info.reg_2954 = read_reg(0x02954); | 895 | yi->reg_2954 = read_reg(0x02954); |
889 | itv->yuv_info.reg_2958 = read_reg(0x02958); | 896 | yi->reg_2958 = read_reg(0x02958); |
890 | itv->yuv_info.reg_295c = read_reg(0x0295c); | 897 | yi->reg_295c = read_reg(0x0295c); |
891 | itv->yuv_info.reg_2960 = read_reg(0x02960); | 898 | yi->reg_2960 = read_reg(0x02960); |
892 | itv->yuv_info.reg_2964 = read_reg(0x02964); | 899 | yi->reg_2964 = read_reg(0x02964); |
893 | itv->yuv_info.reg_2968 = read_reg(0x02968); | 900 | yi->reg_2968 = read_reg(0x02968); |
894 | itv->yuv_info.reg_296c = read_reg(0x0296c); | 901 | yi->reg_296c = read_reg(0x0296c); |
895 | itv->yuv_info.reg_2970 = read_reg(0x02970); | 902 | yi->reg_2970 = read_reg(0x02970); |
896 | 903 | ||
897 | itv->yuv_info.v_filter_1 = -1; | 904 | yi->v_filter_1 = -1; |
898 | itv->yuv_info.v_filter_2 = -1; | 905 | yi->v_filter_2 = -1; |
899 | itv->yuv_info.h_filter = -1; | 906 | yi->h_filter = -1; |
900 | 907 | ||
901 | /* Set some valid size info */ | 908 | /* Set some valid size info */ |
902 | itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF; | 909 | yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF; |
903 | itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF; | 910 | yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF; |
904 | 911 | ||
905 | /* Bit 2 of reg 2878 indicates current decoder output format | 912 | /* Bit 2 of reg 2878 indicates current decoder output format |
906 | 0 : NTSC 1 : PAL */ | 913 | 0 : NTSC 1 : PAL */ |
907 | if (read_reg(0x2878) & 4) | 914 | if (read_reg(0x2878) & 4) |
908 | itv->yuv_info.decode_height = 576; | 915 | yi->decode_height = 576; |
909 | else | 916 | else |
910 | itv->yuv_info.decode_height = 480; | 917 | yi->decode_height = 480; |
911 | 918 | ||
912 | /* If no visible size set, assume full size */ | 919 | if (!itv->osd_info) { |
913 | if (!itv->yuv_info.osd_vis_w) | 920 | yi->osd_vis_w = 720 - yi->osd_x_offset; |
914 | itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset; | 921 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; |
915 | |||
916 | if (!itv->yuv_info.osd_vis_h) { | ||
917 | itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; | ||
918 | } else { | 922 | } else { |
919 | /* If output video standard has changed, requested height may | 923 | /* If no visible size set, assume full size */ |
920 | not be legal */ | 924 | if (!yi->osd_vis_w) |
921 | if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) { | 925 | yi->osd_vis_w = 720 - yi->osd_x_offset; |
922 | IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", | 926 | |
923 | itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset, | 927 | if (!yi->osd_vis_h) |
924 | itv->yuv_info.decode_height); | 928 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; |
925 | itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; | 929 | else { |
930 | /* If output video standard has changed, requested height may | ||
931 | not be legal */ | ||
932 | if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) { | ||
933 | IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", | ||
934 | yi->osd_vis_h + yi->osd_y_offset, | ||
935 | yi->decode_height); | ||
936 | yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; | ||
937 | } | ||
926 | } | 938 | } |
927 | } | 939 | } |
928 | 940 | ||
929 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ | 941 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ |
930 | itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL); | 942 | yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL); |
931 | if (itv->yuv_info.blanking_ptr) { | 943 | if (yi->blanking_ptr) |
932 | itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE); | 944 | yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); |
933 | } | ||
934 | else { | 945 | else { |
935 | itv->yuv_info.blanking_dmaptr = 0; | 946 | yi->blanking_dmaptr = 0; |
936 | IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n"); | 947 | IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); |
937 | } | 948 | } |
938 | 949 | ||
939 | IVTV_DEBUG_WARN("Enable video output\n"); | ||
940 | write_reg_sync(0x00108080, 0x2898); | ||
941 | |||
942 | /* Enable YUV decoder output */ | 950 | /* Enable YUV decoder output */ |
943 | write_reg_sync(0x01, IVTV_REG_VDM); | 951 | write_reg_sync(0x01, IVTV_REG_VDM); |
944 | 952 | ||
945 | set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); | 953 | set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); |
946 | atomic_set(&itv->yuv_info.next_dma_frame,0); | 954 | atomic_set(&yi->next_dma_frame, 0); |
947 | } | 955 | } |
948 | 956 | ||
949 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | 957 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) |