Lines Matching +full:udma +full:- +full:p

1 // SPDX-License-Identifier: GPL-2.0-or-later
18 Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
29 #include "ivtv-driver.h"
30 #include "ivtv-cards.h"
31 #include "ivtv-i2c.h"
32 #include "ivtv-udma.h"
33 #include "ivtv-mailbox.h"
34 #include "ivtv-firmware.h"
44 static int ivtvfb_card_id = -1;
65 "Only use framebuffer of the specified ivtv card (0-31)\n"
66 "\t\t\tdefault -1: initialize all available framebuffers");
73 "Force initialization on x86 PAT-enabled systems (bool).\n");
86 "Bits per pixel - 8, 16, 32\n"
110 /* --------------------------------------------------------------------- */
118 printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
124 #define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args)
125 #define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args)
126 #define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
128 /* --------------------------------------------------------------------- */
189 /* --------------------------------------------------------------------- */
209 struct osd_info *oi = itv->osd_info; in ivtvfb_get_osd_coords()
214 osd->offset = data[0] - oi->video_rbase; in ivtvfb_get_osd_coords()
215 osd->max_offset = oi->display_width * oi->display_height * 4; in ivtvfb_get_osd_coords()
216 osd->pixel_stride = data[1]; in ivtvfb_get_osd_coords()
217 osd->lines = data[2]; in ivtvfb_get_osd_coords()
218 osd->x = data[3]; in ivtvfb_get_osd_coords()
219 osd->y = data[4]; in ivtvfb_get_osd_coords()
225 struct osd_info *oi = itv->osd_info; in ivtvfb_set_osd_coords()
227 oi->display_width = osd->pixel_stride; in ivtvfb_set_osd_coords()
228 oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel; in ivtvfb_set_osd_coords()
229 oi->set_osd_coords_x += osd->x; in ivtvfb_set_osd_coords()
230 oi->set_osd_coords_y = osd->y; in ivtvfb_set_osd_coords()
233 osd->offset + oi->video_rbase, in ivtvfb_set_osd_coords()
234 osd->pixel_stride, in ivtvfb_set_osd_coords()
235 osd->lines, osd->x, osd->y); in ivtvfb_set_osd_coords()
240 int osd_height_limit = itv->is_out_50hz ? 576 : 480; in ivtvfb_set_display_window()
243 if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH)) in ivtvfb_set_display_window()
244 return -EINVAL; in ivtvfb_set_display_window()
247 if (ivtv_window->top + ivtv_window->height > osd_height_limit) { in ivtvfb_set_display_window()
248 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n", in ivtvfb_set_display_window()
249 ivtv_window->top, ivtv_window->height); in ivtvfb_set_display_window()
250 ivtv_window->top = osd_height_limit - ivtv_window->height; in ivtvfb_set_display_window()
253 if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) { in ivtvfb_set_display_window()
254 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n", in ivtvfb_set_display_window()
255 ivtv_window->left, ivtv_window->width); in ivtvfb_set_display_window()
256 ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width; in ivtvfb_set_display_window()
260 write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04); in ivtvfb_set_display_window()
263 …write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width),… in ivtvfb_set_display_window()
266 itv->yuv_info.osd_vis_w = ivtv_window->width; in ivtvfb_set_display_window()
267 itv->yuv_info.osd_vis_h = ivtv_window->height; in ivtvfb_set_display_window()
268 itv->yuv_info.osd_x_offset = ivtv_window->left; in ivtvfb_set_display_window()
269 itv->yuv_info.osd_y_offset = ivtv_window->top; in ivtvfb_set_display_window()
281 mutex_lock(&itv->udma.lock); in ivtvfb_prep_dec_dma_to_device()
284 mutex_unlock(&itv->udma.lock); in ivtvfb_prep_dec_dma_to_device()
286 __func__, size_in_bytes, itv->udma.page_count); in ivtvfb_prep_dec_dma_to_device()
289 return -EIO; in ivtvfb_prep_dec_dma_to_device()
293 size_in_bytes, itv->udma.page_count); in ivtvfb_prep_dec_dma_to_device()
296 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); in ivtvfb_prep_dec_dma_to_device()
297 /* if no UDMA is pending and no UDMA is in progress, then the DMA in ivtvfb_prep_dec_dma_to_device()
299 while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) || in ivtvfb_prep_dec_dma_to_device()
300 test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { in ivtvfb_prep_dec_dma_to_device()
304 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) in ivtvfb_prep_dec_dma_to_device()
309 finish_wait(&itv->dma_waitq, &wait); in ivtvfb_prep_dec_dma_to_device()
313 mutex_unlock(&itv->udma.lock); in ivtvfb_prep_dec_dma_to_device()
316 return -EINTR; in ivtvfb_prep_dec_dma_to_device()
326 struct osd_info *oi = itv->osd_info; in ivtvfb_prep_frame()
331 return -EINVAL; in ivtvfb_prep_frame()
335 if ((dest_offset + count) > oi->video_buffer_size) { in ivtvfb_prep_frame()
337 dest_offset + count, oi->video_buffer_size); in ivtvfb_prep_frame()
338 return -E2BIG; in ivtvfb_prep_frame()
343 IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (%p)\n", in ivtvfb_prep_frame()
354 IVTVFB_WARN("Invalid userspace pointer %p\n", source); in ivtvfb_prep_frame()
356 IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source %p count %d\n", in ivtvfb_prep_frame()
358 return -EINVAL; in ivtvfb_prep_frame()
362 dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase; in ivtvfb_prep_frame()
371 unsigned long p = *ppos; in ivtvfb_write() local
376 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_write()
378 IVTV_DECODER_OFFSET + itv->osd_info->video_rbase; in ivtvfb_write()
382 if (!info->screen_base) in ivtvfb_write()
383 return -ENODEV; in ivtvfb_write()
385 total_size = info->screen_size; in ivtvfb_write()
388 total_size = info->fix.smem_len; in ivtvfb_write()
390 if (p > total_size) in ivtvfb_write()
391 return -EFBIG; in ivtvfb_write()
394 err = -EFBIG; in ivtvfb_write()
398 if (count + p > total_size) { in ivtvfb_write()
400 err = -ENOSPC; in ivtvfb_write()
401 count = total_size - p; in ivtvfb_write()
404 dst = (void __force *) (info->screen_base + p); in ivtvfb_write()
406 if (info->fbops->fb_sync) in ivtvfb_write()
407 info->fbops->fb_sync(info); in ivtvfb_write()
415 lead = 4 - ((unsigned long)dst & 3); in ivtvfb_write()
417 return -EFAULT; in ivtvfb_write()
422 if ((count - lead) & 3) in ivtvfb_write()
423 tail = (count - lead) & 3; in ivtvfb_write()
425 dma_size = count - lead - tail; in ivtvfb_write()
427 p + lead + dma_offset, (void __user *)buf, dma_size); in ivtvfb_write()
434 return -EFAULT; in ivtvfb_write()
436 return -EFAULT; in ivtvfb_write()
448 struct ivtv *itv = (struct ivtv *)info->par; in ivtvfb_ioctl()
461 if (itv->is_out_50hz && trace > 312) in ivtvfb_ioctl()
462 trace -= 312; in ivtvfb_ioctl()
463 else if (itv->is_out_60hz && trace > 262) in ivtvfb_ioctl()
464 trace -= 262; in ivtvfb_ioctl()
467 vblank.count = itv->last_vsync_field; in ivtvfb_ioctl()
471 return -EFAULT; in ivtvfb_ioctl()
476 prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); in ivtvfb_ioctl()
478 rc = -ETIMEDOUT; in ivtvfb_ioctl()
479 finish_wait(&itv->vsync_waitq, &wait); in ivtvfb_ioctl()
487 return -EFAULT; in ivtvfb_ioctl()
494 return -EINVAL; in ivtvfb_ioctl()
503 struct osd_info *oi = itv->osd_info; in ivtvfb_set_var()
506 int osd_mode = -1; in ivtvfb_set_var()
511 if (var->nonstd) /* YUV */ in ivtvfb_set_var()
517 switch (var->bits_per_pixel) { in ivtvfb_set_var()
525 switch (var->green.length) { in ivtvfb_set_var()
536 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); in ivtvfb_set_var()
540 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); in ivtvfb_set_var()
545 if (osd_mode != -1) { in ivtvfb_set_var()
550 oi->bits_per_pixel = var->bits_per_pixel; in ivtvfb_set_var()
551 oi->bytes_per_pixel = var->bits_per_pixel / 8; in ivtvfb_set_var()
554 switch (var->vmode & FB_VMODE_MASK) { in ivtvfb_set_var()
562 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n"); in ivtvfb_set_var()
569 ivtv_osd.pixel_stride = var->xres_virtual; in ivtvfb_set_var()
570 ivtv_osd.lines = var->yres_virtual; in ivtvfb_set_var()
577 ivtv_window.width = var->xres; in ivtvfb_set_var()
578 ivtv_window.height = var->yres; in ivtvfb_set_var()
581 if (!var->upper_margin) in ivtvfb_set_var()
582 var->upper_margin++; in ivtvfb_set_var()
583 if (!var->left_margin) in ivtvfb_set_var()
584 var->left_margin++; in ivtvfb_set_var()
585 ivtv_window.top = var->upper_margin - 1; in ivtvfb_set_var()
586 ivtv_window.left = var->left_margin - 1; in ivtvfb_set_var()
591 itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride; in ivtvfb_set_var()
592 itv->yuv_info.osd_full_h = ivtv_osd.lines; in ivtvfb_set_var()
595 itv->yuv_info.yuv_forced_update = 1; in ivtvfb_set_var()
598 memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur)); in ivtvfb_set_var()
601 var->xres, var->yres, in ivtvfb_set_var()
602 var->xres_virtual, var->yres_virtual, in ivtvfb_set_var()
603 var->bits_per_pixel); in ivtvfb_set_var()
606 var->left_margin, var->upper_margin); in ivtvfb_set_var()
609 (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off"); in ivtvfb_set_var()
610 IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB"); in ivtvfb_set_var()
617 struct osd_info *oi = itv->osd_info; in ivtvfb_get_fix()
621 strscpy(fix->id, "cx23415 TV out", sizeof(fix->id)); in ivtvfb_get_fix()
622 fix->smem_start = oi->video_pbase; in ivtvfb_get_fix()
623 fix->smem_len = oi->video_buffer_size; in ivtvfb_get_fix()
624 fix->type = FB_TYPE_PACKED_PIXELS; in ivtvfb_get_fix()
625 fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; in ivtvfb_get_fix()
626 fix->xpanstep = 1; in ivtvfb_get_fix()
627 fix->ypanstep = 1; in ivtvfb_get_fix()
628 fix->ywrapstep = 0; in ivtvfb_get_fix()
629 fix->line_length = oi->display_byte_stride; in ivtvfb_get_fix()
630 fix->accel = FB_ACCEL_NONE; in ivtvfb_get_fix()
634 /* Check the requested display mode, returning -EINVAL if we can't
639 struct osd_info *oi = itv->osd_info; in _ivtvfb_check_var()
646 if (itv->is_out_50hz) { in _ivtvfb_check_var()
659 if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { in _ivtvfb_check_var()
660 var->transp.offset = 24; in _ivtvfb_check_var()
661 var->transp.length = 8; in _ivtvfb_check_var()
662 var->red.offset = 16; in _ivtvfb_check_var()
663 var->red.length = 8; in _ivtvfb_check_var()
664 var->green.offset = 8; in _ivtvfb_check_var()
665 var->green.length = 8; in _ivtvfb_check_var()
666 var->blue.offset = 0; in _ivtvfb_check_var()
667 var->blue.length = 8; in _ivtvfb_check_var()
669 else if (var->bits_per_pixel == 16) { in _ivtvfb_check_var()
671 switch (var->green.length) { in _ivtvfb_check_var()
673 var->red.offset = 8; in _ivtvfb_check_var()
674 var->red.length = 4; in _ivtvfb_check_var()
675 var->green.offset = 4; in _ivtvfb_check_var()
676 var->green.length = 4; in _ivtvfb_check_var()
677 var->blue.offset = 0; in _ivtvfb_check_var()
678 var->blue.length = 4; in _ivtvfb_check_var()
679 var->transp.offset = 12; in _ivtvfb_check_var()
680 var->transp.length = 1; in _ivtvfb_check_var()
683 var->red.offset = 10; in _ivtvfb_check_var()
684 var->red.length = 5; in _ivtvfb_check_var()
685 var->green.offset = 5; in _ivtvfb_check_var()
686 var->green.length = 5; in _ivtvfb_check_var()
687 var->blue.offset = 0; in _ivtvfb_check_var()
688 var->blue.length = 5; in _ivtvfb_check_var()
689 var->transp.offset = 15; in _ivtvfb_check_var()
690 var->transp.length = 1; in _ivtvfb_check_var()
693 var->red.offset = 11; in _ivtvfb_check_var()
694 var->red.length = 5; in _ivtvfb_check_var()
695 var->green.offset = 5; in _ivtvfb_check_var()
696 var->green.length = 6; in _ivtvfb_check_var()
697 var->blue.offset = 0; in _ivtvfb_check_var()
698 var->blue.length = 5; in _ivtvfb_check_var()
699 var->transp.offset = 0; in _ivtvfb_check_var()
700 var->transp.length = 0; in _ivtvfb_check_var()
705 IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel); in _ivtvfb_check_var()
706 return -EINVAL; in _ivtvfb_check_var()
710 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { in _ivtvfb_check_var()
712 var->xres, var->yres); in _ivtvfb_check_var()
713 return -EINVAL; in _ivtvfb_check_var()
717 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || in _ivtvfb_check_var()
718 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || in _ivtvfb_check_var()
719 var->xres_virtual < var->xres || in _ivtvfb_check_var()
720 var->yres_virtual < var->yres) { in _ivtvfb_check_var()
722 var->xres_virtual, var->yres_virtual); in _ivtvfb_check_var()
723 return -EINVAL; in _ivtvfb_check_var()
727 if (var->bits_per_pixel == 8) { in _ivtvfb_check_var()
729 if (var->xres & 3) { in _ivtvfb_check_var()
730 IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres); in _ivtvfb_check_var()
731 return -EINVAL; in _ivtvfb_check_var()
733 if (var->xres_virtual & 3) { in _ivtvfb_check_var()
734 IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual); in _ivtvfb_check_var()
735 return -EINVAL; in _ivtvfb_check_var()
738 else if (var->bits_per_pixel == 16) { in _ivtvfb_check_var()
740 if (var->xres & 1) { in _ivtvfb_check_var()
741 IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres); in _ivtvfb_check_var()
742 return -EINVAL; in _ivtvfb_check_var()
744 if (var->xres_virtual & 1) { in _ivtvfb_check_var()
745 IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual); in _ivtvfb_check_var()
746 return -EINVAL; in _ivtvfb_check_var()
751 if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) { in _ivtvfb_check_var()
753 var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual); in _ivtvfb_check_var()
754 return -EINVAL; in _ivtvfb_check_var()
758 if (var->nonstd > 1) { in _ivtvfb_check_var()
759 IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd); in _ivtvfb_check_var()
760 return -EINVAL; in _ivtvfb_check_var()
764 if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) && in _ivtvfb_check_var()
765 ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) { in _ivtvfb_check_var()
766 IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK); in _ivtvfb_check_var()
767 return -EINVAL; in _ivtvfb_check_var()
774 if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) in _ivtvfb_check_var()
775 var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2); in _ivtvfb_check_var()
777 if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481)) in _ivtvfb_check_var()
778 var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) - in _ivtvfb_check_var()
779 var->yres) / 2); in _ivtvfb_check_var()
782 var->right_margin = hlimit - var->left_margin - var->xres; in _ivtvfb_check_var()
783 var->lower_margin = vlimit - var->upper_margin - var->yres; in _ivtvfb_check_var()
786 var->hsync_len = 24; in _ivtvfb_check_var()
787 var->vsync_len = 2; in _ivtvfb_check_var()
789 /* Non-interlaced / interlaced mode is used to switch the OSD filter in _ivtvfb_check_var()
792 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) in _ivtvfb_check_var()
793 var->pixclock = pixclock / 2; in _ivtvfb_check_var()
795 var->pixclock = pixclock; in _ivtvfb_check_var()
797 itv->osd_rect.width = var->xres; in _ivtvfb_check_var()
798 itv->osd_rect.height = var->yres; in _ivtvfb_check_var()
801 var->xres, var->yres, in _ivtvfb_check_var()
802 var->xres_virtual, var->yres_virtual, in _ivtvfb_check_var()
803 var->bits_per_pixel); in _ivtvfb_check_var()
806 var->left_margin, var->upper_margin); in _ivtvfb_check_var()
809 (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off"); in _ivtvfb_check_var()
810 IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB"); in _ivtvfb_check_var()
816 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_check_var()
824 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_pan_display()
826 if (var->yoffset + info->var.yres > info->var.yres_virtual || in ivtvfb_pan_display()
827 var->xoffset + info->var.xres > info->var.xres_virtual) in ivtvfb_pan_display()
828 return -EINVAL; in ivtvfb_pan_display()
830 osd_pan_index = var->yoffset * info->fix.line_length in ivtvfb_pan_display()
831 + var->xoffset * info->var.bits_per_pixel / 8; in ivtvfb_pan_display()
835 itv->yuv_info.osd_x_pan = var->xoffset; in ivtvfb_pan_display()
836 itv->yuv_info.osd_y_pan = var->yoffset; in ivtvfb_pan_display()
838 itv->yuv_info.yuv_forced_update = 1; in ivtvfb_pan_display()
840 itv->osd_info->pan_cur = osd_pan_index; in ivtvfb_pan_display()
847 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_set_par()
851 rc = ivtvfb_set_var(itv, &info->var); in ivtvfb_set_par()
852 ivtvfb_pan_display(&info->var, info); in ivtvfb_set_par()
853 ivtvfb_get_fix(itv, &info->fix); in ivtvfb_set_par()
863 struct ivtv *itv = (struct ivtv *)info->par; in ivtvfb_setcolreg()
865 if (regno >= info->cmap.len) in ivtvfb_setcolreg()
866 return -EINVAL; in ivtvfb_setcolreg()
869 if (info->var.bits_per_pixel <= 8) { in ivtvfb_setcolreg()
872 itv->osd_info->palette_cur[regno] = color; in ivtvfb_setcolreg()
876 return -EINVAL; in ivtvfb_setcolreg()
878 palette = info->pseudo_palette; in ivtvfb_setcolreg()
879 if (info->var.bits_per_pixel == 16) { in ivtvfb_setcolreg()
880 switch (info->var.green.length) { in ivtvfb_setcolreg()
906 struct ivtv *itv = (struct ivtv *)info->par; in ivtvfb_blank()
925 itv->osd_info->blank_cur = blank_mode; in ivtvfb_blank()
947 struct osd_info *oi = itv->osd_info; in ivtvfb_restore()
950 ivtvfb_set_var(itv, &oi->fbvar_cur); in ivtvfb_restore()
951 ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info); in ivtvfb_restore()
954 write_reg(oi->palette_cur[i], 0x02a34); in ivtvfb_restore()
956 write_reg(oi->pan_cur, 0x02a0c); in ivtvfb_restore()
965 struct osd_info *oi = itv->osd_info; in ivtvfb_init_vidmode()
973 oi->bits_per_pixel = osd_depth; in ivtvfb_init_vidmode()
974 oi->bytes_per_pixel = oi->bits_per_pixel / 8; in ivtvfb_init_vidmode()
991 IVTVFB_ERR("Invalid osd_left - assuming default\n"); in ivtvfb_init_vidmode()
996 osd_left--; in ivtvfb_init_vidmode()
999 osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2); in ivtvfb_init_vidmode()
1001 oi->display_byte_stride = in ivtvfb_init_vidmode()
1002 start_window.width * oi->bytes_per_pixel; in ivtvfb_init_vidmode()
1006 max_height = itv->is_out_50hz ? 576 : 480; in ivtvfb_init_vidmode()
1012 osd_yres : itv->is_out_50hz ? 480 : 400; in ivtvfb_init_vidmode()
1016 IVTVFB_ERR("Invalid osd_upper - assuming default\n"); in ivtvfb_init_vidmode()
1021 osd_upper--; in ivtvfb_init_vidmode()
1023 start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2); in ivtvfb_init_vidmode()
1025 oi->display_width = start_window.width; in ivtvfb_init_vidmode()
1026 oi->display_height = start_window.height; in ivtvfb_init_vidmode()
1030 oi->ivtvfb_defined.xres = oi->display_width; in ivtvfb_init_vidmode()
1031 oi->ivtvfb_defined.yres = oi->display_height; in ivtvfb_init_vidmode()
1032 oi->ivtvfb_defined.xres_virtual = oi->display_width; in ivtvfb_init_vidmode()
1033 oi->ivtvfb_defined.yres_virtual = oi->display_height; in ivtvfb_init_vidmode()
1034 oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel; in ivtvfb_init_vidmode()
1035 oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED); in ivtvfb_init_vidmode()
1036 oi->ivtvfb_defined.left_margin = start_window.left + 1; in ivtvfb_init_vidmode()
1037 oi->ivtvfb_defined.upper_margin = start_window.top + 1; in ivtvfb_init_vidmode()
1038 oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE; in ivtvfb_init_vidmode()
1039 oi->ivtvfb_defined.nonstd = 0; in ivtvfb_init_vidmode()
1043 _ivtvfb_check_var(&oi->ivtvfb_defined, itv); in ivtvfb_init_vidmode()
1047 ivtvfb_get_fix(itv, &oi->ivtvfb_fix); in ivtvfb_init_vidmode()
1051 oi->ivtvfb_info.node = -1; in ivtvfb_init_vidmode()
1052 oi->ivtvfb_info.par = itv; in ivtvfb_init_vidmode()
1053 oi->ivtvfb_info.var = oi->ivtvfb_defined; in ivtvfb_init_vidmode()
1054 oi->ivtvfb_info.fix = oi->ivtvfb_fix; in ivtvfb_init_vidmode()
1055 oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase; in ivtvfb_init_vidmode()
1056 oi->ivtvfb_info.fbops = &ivtvfb_ops; in ivtvfb_init_vidmode()
1059 oi->ivtvfb_info.monspecs.hfmin = 8000; in ivtvfb_init_vidmode()
1060 oi->ivtvfb_info.monspecs.hfmax = 70000; in ivtvfb_init_vidmode()
1061 oi->ivtvfb_info.monspecs.vfmin = 10; in ivtvfb_init_vidmode()
1062 oi->ivtvfb_info.monspecs.vfmax = 100; in ivtvfb_init_vidmode()
1065 if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) { in ivtvfb_init_vidmode()
1067 return -ENOMEM; in ivtvfb_init_vidmode()
1071 oi->ivtvfb_info.pseudo_palette = in ivtvfb_init_vidmode()
1074 if (!oi->ivtvfb_info.pseudo_palette) { in ivtvfb_init_vidmode()
1076 return -ENOMEM; in ivtvfb_init_vidmode()
1086 struct osd_info *oi = itv->osd_info; in ivtvfb_init_io()
1090 mutex_lock(&itv->serialize_lock); in ivtvfb_init_io()
1092 mutex_unlock(&itv->serialize_lock); in ivtvfb_init_io()
1094 return -ENXIO; in ivtvfb_init_io()
1096 mutex_unlock(&itv->serialize_lock); in ivtvfb_init_io()
1098 if (ivtvfb_get_framebuffer(itv, &oi->video_rbase, in ivtvfb_init_io()
1099 &oi->video_buffer_size) < 0) { in ivtvfb_init_io()
1101 return -EIO; in ivtvfb_init_io()
1107 oi->video_buffer_size = 1704960; in ivtvfb_init_io()
1109 oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase; in ivtvfb_init_io()
1110 oi->video_vbase = itv->dec_mem + oi->video_rbase; in ivtvfb_init_io()
1112 if (!oi->video_vbase) { in ivtvfb_init_io()
1114 oi->video_buffer_size, oi->video_pbase); in ivtvfb_init_io()
1115 return -EIO; in ivtvfb_init_io()
1118 IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", in ivtvfb_init_io()
1119 oi->video_pbase, oi->video_vbase, in ivtvfb_init_io()
1120 oi->video_buffer_size / 1024); in ivtvfb_init_io()
1122 while (!(oi->video_buffer_size & (1 << size_shift))) in ivtvfb_init_io()
1123 size_shift--; in ivtvfb_init_io()
1125 oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1); in ivtvfb_init_io()
1126 oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size; in ivtvfb_init_io()
1127 oi->fb_end_aligned_physaddr += (1 << size_shift) - 1; in ivtvfb_init_io()
1128 oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1); in ivtvfb_init_io()
1129 oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr, in ivtvfb_init_io()
1130 oi->fb_end_aligned_physaddr - in ivtvfb_init_io()
1131 oi->fb_start_aligned_physaddr); in ivtvfb_init_io()
1133 memset_io(oi->video_vbase, 0, oi->video_buffer_size); in ivtvfb_init_io()
1141 struct osd_info *oi = itv->osd_info; in ivtvfb_release_buffers()
1144 if (oi->ivtvfb_info.cmap.len) in ivtvfb_release_buffers()
1145 fb_dealloc_cmap(&oi->ivtvfb_info.cmap); in ivtvfb_release_buffers()
1148 kfree(oi->ivtvfb_info.pseudo_palette); in ivtvfb_release_buffers()
1149 arch_phys_wc_del(oi->wc_cookie); in ivtvfb_release_buffers()
1151 itv->osd_info = NULL; in ivtvfb_release_buffers()
1163 pr_info("PAT is enabled. Write-combined framebuffer caching will be disabled.\n"); in ivtvfb_init_card()
1166 pr_warn("ivtvfb needs PAT disabled for write-combined framebuffer caching.\n"); in ivtvfb_init_card()
1169 return -ENODEV; in ivtvfb_init_card()
1174 if (itv->osd_info) { in ivtvfb_init_card()
1176 return -EBUSY; in ivtvfb_init_card()
1179 itv->osd_info = kzalloc(sizeof(struct osd_info), in ivtvfb_init_card()
1181 if (itv->osd_info == NULL) { in ivtvfb_init_card()
1183 return -ENOMEM; in ivtvfb_init_card()
1200 if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) { in ivtvfb_init_card()
1202 return -EINVAL; in ivtvfb_init_card()
1205 itv->osd_video_pbase = itv->osd_info->video_pbase; in ivtvfb_init_card()
1208 ivtvfb_set_par(&itv->osd_info->ivtvfb_info); in ivtvfb_init_card()
1215 ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); in ivtvfb_init_card()
1218 itv->ivtvfb_restore = ivtvfb_restore; in ivtvfb_init_card()
1222 itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps |= in ivtvfb_init_card()
1224 itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps |= in ivtvfb_init_card()
1226 itv->v4l2_cap |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY; in ivtvfb_init_card()
1231 static int __init ivtvfb_callback_init(struct device *dev, void *p) in ivtvfb_callback_init() argument
1236 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { in ivtvfb_callback_init()
1239 itv->v4l2_dev.name); in ivtvfb_callback_init()
1240 (*(int *)p)++; in ivtvfb_callback_init()
1246 static int ivtvfb_callback_cleanup(struct device *dev, void *p) in ivtvfb_callback_cleanup() argument
1250 struct osd_info *oi = itv->osd_info; in ivtvfb_callback_cleanup()
1252 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { in ivtvfb_callback_cleanup()
1253 itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps &= in ivtvfb_callback_cleanup()
1255 itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &= in ivtvfb_callback_cleanup()
1257 itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; in ivtvfb_callback_cleanup()
1258 unregister_framebuffer(&itv->osd_info->ivtvfb_info); in ivtvfb_callback_cleanup()
1259 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); in ivtvfb_callback_cleanup()
1260 itv->ivtvfb_restore = NULL; in ivtvfb_callback_cleanup()
1261 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); in ivtvfb_callback_cleanup()
1263 itv->osd_video_pbase = 0; in ivtvfb_callback_cleanup()
1275 if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) { in ivtvfb_init()
1276 pr_err("ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n", in ivtvfb_init()
1277 IVTV_MAX_CARDS - 1); in ivtvfb_init()
1278 return -EINVAL; in ivtvfb_init()
1286 return -ENODEV; in ivtvfb_init()