aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-yuv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-yuv.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c160
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
853static void ivtv_yuv_init (struct ivtv *itv) 858static 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
949int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) 957int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)