diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-yuv.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.c | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c index bcea09542e5a..e2288f224ab6 100644 --- a/drivers/media/video/ivtv/ivtv-yuv.c +++ b/drivers/media/video/ivtv/ivtv-yuv.c | |||
@@ -19,11 +19,16 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "ivtv-driver.h" | 21 | #include "ivtv-driver.h" |
22 | #include "ivtv-queue.h" | ||
23 | #include "ivtv-udma.h" | 22 | #include "ivtv-udma.h" |
24 | #include "ivtv-irq.h" | ||
25 | #include "ivtv-yuv.h" | 23 | #include "ivtv-yuv.h" |
26 | 24 | ||
25 | const u32 yuv_offset[4] = { | ||
26 | IVTV_YUV_BUFFER_OFFSET, | ||
27 | IVTV_YUV_BUFFER_OFFSET_1, | ||
28 | IVTV_YUV_BUFFER_OFFSET_2, | ||
29 | IVTV_YUV_BUFFER_OFFSET_3 | ||
30 | }; | ||
31 | |||
27 | static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, | 32 | static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, |
28 | struct ivtv_dma_frame *args) | 33 | struct ivtv_dma_frame *args) |
29 | { | 34 | { |
@@ -37,7 +42,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, | |||
37 | int y_decode_height, uv_decode_height, y_size; | 42 | int y_decode_height, uv_decode_height, y_size; |
38 | int frame = atomic_read(&itv->yuv_info.next_fill_frame); | 43 | int frame = atomic_read(&itv->yuv_info.next_fill_frame); |
39 | 44 | ||
40 | y_buffer_offset = IVTV_DEC_MEM_START + yuv_offset[frame]; | 45 | y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame]; |
41 | uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET; | 46 | uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET; |
42 | 47 | ||
43 | y_decode_height = uv_decode_height = args->src.height + args->src.top; | 48 | y_decode_height = uv_decode_height = args->src.height + args->src.top; |
@@ -83,7 +88,14 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, | |||
83 | } | 88 | } |
84 | 89 | ||
85 | /* Fill & map SG List */ | 90 | /* Fill & map SG List */ |
86 | ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)); | 91 | if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) { |
92 | IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n"); | ||
93 | for (i = 0; i < dma->page_count; i++) { | ||
94 | put_page(dma->map[i]); | ||
95 | } | ||
96 | dma->page_count = 0; | ||
97 | return -ENOMEM; | ||
98 | } | ||
87 | dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); | 99 | dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); |
88 | 100 | ||
89 | /* Fill SG Array with new values */ | 101 | /* Fill SG Array with new values */ |
@@ -94,7 +106,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, | |||
94 | if (itv->yuv_info.blanking_dmaptr) { | 106 | if (itv->yuv_info.blanking_dmaptr) { |
95 | dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16); | 107 | dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16); |
96 | dma->SGarray[dma->SG_length].src = cpu_to_le32(itv->yuv_info.blanking_dmaptr); | 108 | dma->SGarray[dma->SG_length].src = cpu_to_le32(itv->yuv_info.blanking_dmaptr); |
97 | dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DEC_MEM_START + yuv_offset[frame]); | 109 | dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]); |
98 | dma->SG_length++; | 110 | dma->SG_length++; |
99 | } | 111 | } |
100 | } | 112 | } |
@@ -612,7 +624,6 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi | |||
612 | itv->yuv_info.v_filter_2 = v_filter_2; | 624 | itv->yuv_info.v_filter_2 = v_filter_2; |
613 | } | 625 | } |
614 | 626 | ||
615 | itv->yuv_info.frame_interlaced_last = itv->yuv_info.frame_interlaced; | ||
616 | } | 627 | } |
617 | 628 | ||
618 | /* Modify the supplied coordinate information to fit the visible osd area */ | 629 | /* Modify the supplied coordinate information to fit the visible osd area */ |
@@ -799,6 +810,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo | |||
799 | (itv->yuv_info.old_frame_info.src_y != window->src_y) || | 810 | (itv->yuv_info.old_frame_info.src_y != window->src_y) || |
800 | (itv->yuv_info.old_frame_info.pan_y != window->pan_y) || | 811 | (itv->yuv_info.old_frame_info.pan_y != window->pan_y) || |
801 | (itv->yuv_info.old_frame_info.vis_h != window->vis_h) || | 812 | (itv->yuv_info.old_frame_info.vis_h != window->vis_h) || |
813 | (itv->yuv_info.old_frame_info.lace_mode != window->lace_mode) || | ||
802 | (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) || | 814 | (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) || |
803 | (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) { | 815 | (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) { |
804 | yuv_update |= IVTV_YUV_UPDATE_VERTICAL; | 816 | yuv_update |= IVTV_YUV_UPDATE_VERTICAL; |
@@ -898,8 +910,21 @@ static void ivtv_yuv_init (struct ivtv *itv) | |||
898 | itv->yuv_info.decode_height = 480; | 910 | itv->yuv_info.decode_height = 480; |
899 | 911 | ||
900 | /* If no visible size set, assume full size */ | 912 | /* If no visible size set, assume full size */ |
901 | if (!itv->yuv_info.osd_vis_w) itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset; | 913 | if (!itv->yuv_info.osd_vis_w) |
902 | if (!itv->yuv_info.osd_vis_h) itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; | 914 | itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_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 { | ||
919 | /* If output video standard has changed, requested height may | ||
920 | not be legal */ | ||
921 | if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) { | ||
922 | IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", | ||
923 | itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset, | ||
924 | itv->yuv_info.decode_height); | ||
925 | itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset; | ||
926 | } | ||
927 | } | ||
903 | 928 | ||
904 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ | 929 | /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ |
905 | itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL); | 930 | itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL); |
@@ -927,6 +952,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | |||
927 | int rc = 0; | 952 | int rc = 0; |
928 | int got_sig = 0; | 953 | int got_sig = 0; |
929 | int frame, next_fill_frame, last_fill_frame; | 954 | int frame, next_fill_frame, last_fill_frame; |
955 | int register_update = 0; | ||
930 | 956 | ||
931 | IVTV_DEBUG_INFO("yuv_prep_frame\n"); | 957 | IVTV_DEBUG_INFO("yuv_prep_frame\n"); |
932 | 958 | ||
@@ -940,6 +966,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | |||
940 | /* Buffers are full - Overwrite the last frame */ | 966 | /* Buffers are full - Overwrite the last frame */ |
941 | next_fill_frame = frame; | 967 | next_fill_frame = frame; |
942 | frame = (frame - 1) & 3; | 968 | frame = (frame - 1) & 3; |
969 | register_update = itv->yuv_info.new_frame_info[frame].update; | ||
943 | } | 970 | } |
944 | 971 | ||
945 | /* Take a snapshot of the yuv coordinate information */ | 972 | /* Take a snapshot of the yuv coordinate information */ |
@@ -955,6 +982,9 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | |||
955 | itv->yuv_info.new_frame_info[frame].tru_w = args->src_width; | 982 | itv->yuv_info.new_frame_info[frame].tru_w = args->src_width; |
956 | itv->yuv_info.new_frame_info[frame].tru_h = args->src_height; | 983 | itv->yuv_info.new_frame_info[frame].tru_h = args->src_height; |
957 | 984 | ||
985 | /* Snapshot field order */ | ||
986 | itv->yuv_info.sync_field[frame] = itv->yuv_info.lace_sync_field; | ||
987 | |||
958 | /* Are we going to offset the Y plane */ | 988 | /* Are we going to offset the Y plane */ |
959 | if (args->src.height + args->src.top < 512-16) | 989 | if (args->src.height + args->src.top < 512-16) |
960 | itv->yuv_info.new_frame_info[frame].offset_y = 1; | 990 | itv->yuv_info.new_frame_info[frame].offset_y = 1; |
@@ -970,6 +1000,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | |||
970 | itv->yuv_info.new_frame_info[frame].update = 0; | 1000 | itv->yuv_info.new_frame_info[frame].update = 0; |
971 | itv->yuv_info.new_frame_info[frame].interlaced_y = 0; | 1001 | itv->yuv_info.new_frame_info[frame].interlaced_y = 0; |
972 | itv->yuv_info.new_frame_info[frame].interlaced_uv = 0; | 1002 | itv->yuv_info.new_frame_info[frame].interlaced_uv = 0; |
1003 | itv->yuv_info.new_frame_info[frame].lace_mode = itv->yuv_info.lace_mode; | ||
973 | 1004 | ||
974 | if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame], | 1005 | if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame], |
975 | sizeof (itv->yuv_info.new_frame_info[frame]))) { | 1006 | sizeof (itv->yuv_info.new_frame_info[frame]))) { |
@@ -978,6 +1009,14 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) | |||
978 | /* IVTV_DEBUG_YUV ("Requesting register update for frame %d\n",frame); */ | 1009 | /* IVTV_DEBUG_YUV ("Requesting register update for frame %d\n",frame); */ |
979 | } | 1010 | } |
980 | 1011 | ||
1012 | itv->yuv_info.new_frame_info[frame].update |= register_update; | ||
1013 | |||
1014 | /* Should this frame be delayed ? */ | ||
1015 | if (itv->yuv_info.sync_field[frame] != itv->yuv_info.sync_field[(frame - 1) & 3]) | ||
1016 | itv->yuv_info.field_delay[frame] = 1; | ||
1017 | else | ||
1018 | itv->yuv_info.field_delay[frame] = 0; | ||
1019 | |||
981 | /* DMA the frame */ | 1020 | /* DMA the frame */ |
982 | mutex_lock(&itv->udma.lock); | 1021 | mutex_lock(&itv->udma.lock); |
983 | 1022 | ||