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"
109 /* --------------------------------------------------------------------- */
117 printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
123 #define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args)
124 #define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args)
125 #define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
127 /* --------------------------------------------------------------------- */
188 /* --------------------------------------------------------------------- */
208 struct osd_info *oi = itv->osd_info; in ivtvfb_get_osd_coords()
213 osd->offset = data[0] - oi->video_rbase; in ivtvfb_get_osd_coords()
214 osd->max_offset = oi->display_width * oi->display_height * 4; in ivtvfb_get_osd_coords()
215 osd->pixel_stride = data[1]; in ivtvfb_get_osd_coords()
216 osd->lines = data[2]; in ivtvfb_get_osd_coords()
217 osd->x = data[3]; in ivtvfb_get_osd_coords()
218 osd->y = data[4]; in ivtvfb_get_osd_coords()
224 struct osd_info *oi = itv->osd_info; in ivtvfb_set_osd_coords()
226 oi->display_width = osd->pixel_stride; in ivtvfb_set_osd_coords()
227 oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel; in ivtvfb_set_osd_coords()
228 oi->set_osd_coords_x += osd->x; in ivtvfb_set_osd_coords()
229 oi->set_osd_coords_y = osd->y; in ivtvfb_set_osd_coords()
232 osd->offset + oi->video_rbase, in ivtvfb_set_osd_coords()
233 osd->pixel_stride, in ivtvfb_set_osd_coords()
234 osd->lines, osd->x, osd->y); in ivtvfb_set_osd_coords()
239 int osd_height_limit = itv->is_out_50hz ? 576 : 480; in ivtvfb_set_display_window()
242 if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH)) in ivtvfb_set_display_window()
243 return -EINVAL; in ivtvfb_set_display_window()
246 if (ivtv_window->top + ivtv_window->height > osd_height_limit) { in ivtvfb_set_display_window()
247 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n", in ivtvfb_set_display_window()
248 ivtv_window->top, ivtv_window->height); in ivtvfb_set_display_window()
249 ivtv_window->top = osd_height_limit - ivtv_window->height; in ivtvfb_set_display_window()
252 if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) { in ivtvfb_set_display_window()
253 IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n", in ivtvfb_set_display_window()
254 ivtv_window->left, ivtv_window->width); in ivtvfb_set_display_window()
255 ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width; in ivtvfb_set_display_window()
259 write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04); in ivtvfb_set_display_window()
262 …write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width),… in ivtvfb_set_display_window()
265 itv->yuv_info.osd_vis_w = ivtv_window->width; in ivtvfb_set_display_window()
266 itv->yuv_info.osd_vis_h = ivtv_window->height; in ivtvfb_set_display_window()
267 itv->yuv_info.osd_x_offset = ivtv_window->left; in ivtvfb_set_display_window()
268 itv->yuv_info.osd_y_offset = ivtv_window->top; in ivtvfb_set_display_window()
280 mutex_lock(&itv->udma.lock); in ivtvfb_prep_dec_dma_to_device()
283 mutex_unlock(&itv->udma.lock); in ivtvfb_prep_dec_dma_to_device()
285 __func__, size_in_bytes, itv->udma.page_count); in ivtvfb_prep_dec_dma_to_device()
288 return -EIO; in ivtvfb_prep_dec_dma_to_device()
292 size_in_bytes, itv->udma.page_count); in ivtvfb_prep_dec_dma_to_device()
295 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); in ivtvfb_prep_dec_dma_to_device()
296 /* if no UDMA is pending and no UDMA is in progress, then the DMA in ivtvfb_prep_dec_dma_to_device()
298 while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) || in ivtvfb_prep_dec_dma_to_device()
299 test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { in ivtvfb_prep_dec_dma_to_device()
303 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) in ivtvfb_prep_dec_dma_to_device()
308 finish_wait(&itv->dma_waitq, &wait); in ivtvfb_prep_dec_dma_to_device()
312 mutex_unlock(&itv->udma.lock); in ivtvfb_prep_dec_dma_to_device()
315 return -EINTR; in ivtvfb_prep_dec_dma_to_device()
325 struct osd_info *oi = itv->osd_info; in ivtvfb_prep_frame()
330 return -EINVAL; in ivtvfb_prep_frame()
334 if ((dest_offset + count) > oi->video_buffer_size) { in ivtvfb_prep_frame()
336 dest_offset + count, oi->video_buffer_size); in ivtvfb_prep_frame()
337 return -E2BIG; in ivtvfb_prep_frame()
342 IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (%p)\n", in ivtvfb_prep_frame()
353 IVTVFB_WARN("Invalid userspace pointer %p\n", source); in ivtvfb_prep_frame()
355 IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source %p count %d\n", in ivtvfb_prep_frame()
357 return -EINVAL; in ivtvfb_prep_frame()
361 dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase; in ivtvfb_prep_frame()
370 unsigned long p = *ppos; in ivtvfb_write() local
375 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_write()
377 IVTV_DECODER_OFFSET + itv->osd_info->video_rbase; in ivtvfb_write()
381 if (!info->screen_base) in ivtvfb_write()
382 return -ENODEV; in ivtvfb_write()
384 total_size = info->screen_size; in ivtvfb_write()
387 total_size = info->fix.smem_len; in ivtvfb_write()
389 if (p > total_size) in ivtvfb_write()
390 return -EFBIG; in ivtvfb_write()
393 err = -EFBIG; in ivtvfb_write()
397 if (count + p > total_size) { in ivtvfb_write()
399 err = -ENOSPC; in ivtvfb_write()
400 count = total_size - p; in ivtvfb_write()
403 dst = (void __force *) (info->screen_base + p); in ivtvfb_write()
405 if (info->fbops->fb_sync) in ivtvfb_write()
406 info->fbops->fb_sync(info); in ivtvfb_write()
414 lead = 4 - ((unsigned long)dst & 3); in ivtvfb_write()
416 return -EFAULT; in ivtvfb_write()
421 if ((count - lead) & 3) in ivtvfb_write()
422 tail = (count - lead) & 3; in ivtvfb_write()
424 dma_size = count - lead - tail; in ivtvfb_write()
426 p + lead + dma_offset, (void __user *)buf, dma_size); in ivtvfb_write()
433 return -EFAULT; in ivtvfb_write()
435 return -EFAULT; in ivtvfb_write()
447 struct ivtv *itv = (struct ivtv *)info->par; in ivtvfb_ioctl()
460 if (itv->is_out_50hz && trace > 312) in ivtvfb_ioctl()
461 trace -= 312; in ivtvfb_ioctl()
462 else if (itv->is_out_60hz && trace > 262) in ivtvfb_ioctl()
463 trace -= 262; in ivtvfb_ioctl()
466 vblank.count = itv->last_vsync_field; in ivtvfb_ioctl()
470 return -EFAULT; in ivtvfb_ioctl()
475 prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE); in ivtvfb_ioctl()
477 rc = -ETIMEDOUT; in ivtvfb_ioctl()
478 finish_wait(&itv->vsync_waitq, &wait); in ivtvfb_ioctl()
486 return -EFAULT; in ivtvfb_ioctl()
493 return -EINVAL; in ivtvfb_ioctl()
502 struct osd_info *oi = itv->osd_info; in ivtvfb_set_var()
505 int osd_mode = -1; in ivtvfb_set_var()
510 if (var->nonstd) /* YUV */ in ivtvfb_set_var()
516 switch (var->bits_per_pixel) { in ivtvfb_set_var()
524 switch (var->green.length) { in ivtvfb_set_var()
535 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); in ivtvfb_set_var()
539 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); in ivtvfb_set_var()
544 if (osd_mode != -1) { in ivtvfb_set_var()
549 oi->bits_per_pixel = var->bits_per_pixel; in ivtvfb_set_var()
550 oi->bytes_per_pixel = var->bits_per_pixel / 8; in ivtvfb_set_var()
553 switch (var->vmode & FB_VMODE_MASK) { in ivtvfb_set_var()
561 IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n"); in ivtvfb_set_var()
568 ivtv_osd.pixel_stride = var->xres_virtual; in ivtvfb_set_var()
569 ivtv_osd.lines = var->yres_virtual; in ivtvfb_set_var()
576 ivtv_window.width = var->xres; in ivtvfb_set_var()
577 ivtv_window.height = var->yres; in ivtvfb_set_var()
580 if (!var->upper_margin) in ivtvfb_set_var()
581 var->upper_margin++; in ivtvfb_set_var()
582 if (!var->left_margin) in ivtvfb_set_var()
583 var->left_margin++; in ivtvfb_set_var()
584 ivtv_window.top = var->upper_margin - 1; in ivtvfb_set_var()
585 ivtv_window.left = var->left_margin - 1; in ivtvfb_set_var()
590 itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride; in ivtvfb_set_var()
591 itv->yuv_info.osd_full_h = ivtv_osd.lines; in ivtvfb_set_var()
594 itv->yuv_info.yuv_forced_update = 1; in ivtvfb_set_var()
597 memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur)); in ivtvfb_set_var()
600 var->xres, var->yres, in ivtvfb_set_var()
601 var->xres_virtual, var->yres_virtual, in ivtvfb_set_var()
602 var->bits_per_pixel); in ivtvfb_set_var()
605 var->left_margin, var->upper_margin); in ivtvfb_set_var()
608 (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off"); in ivtvfb_set_var()
609 IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB"); in ivtvfb_set_var()
616 struct osd_info *oi = itv->osd_info; in ivtvfb_get_fix()
620 strscpy(fix->id, "cx23415 TV out", sizeof(fix->id)); in ivtvfb_get_fix()
621 fix->smem_start = oi->video_pbase; in ivtvfb_get_fix()
622 fix->smem_len = oi->video_buffer_size; in ivtvfb_get_fix()
623 fix->type = FB_TYPE_PACKED_PIXELS; in ivtvfb_get_fix()
624 fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; in ivtvfb_get_fix()
625 fix->xpanstep = 1; in ivtvfb_get_fix()
626 fix->ypanstep = 1; in ivtvfb_get_fix()
627 fix->ywrapstep = 0; in ivtvfb_get_fix()
628 fix->line_length = oi->display_byte_stride; in ivtvfb_get_fix()
629 fix->accel = FB_ACCEL_NONE; in ivtvfb_get_fix()
633 /* Check the requested display mode, returning -EINVAL if we can't
638 struct osd_info *oi = itv->osd_info; in _ivtvfb_check_var()
645 if (itv->is_out_50hz) { in _ivtvfb_check_var()
658 if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) { in _ivtvfb_check_var()
659 var->transp.offset = 24; in _ivtvfb_check_var()
660 var->transp.length = 8; in _ivtvfb_check_var()
661 var->red.offset = 16; in _ivtvfb_check_var()
662 var->red.length = 8; in _ivtvfb_check_var()
663 var->green.offset = 8; in _ivtvfb_check_var()
664 var->green.length = 8; in _ivtvfb_check_var()
665 var->blue.offset = 0; in _ivtvfb_check_var()
666 var->blue.length = 8; in _ivtvfb_check_var()
668 else if (var->bits_per_pixel == 16) { in _ivtvfb_check_var()
670 switch (var->green.length) { in _ivtvfb_check_var()
672 var->red.offset = 8; in _ivtvfb_check_var()
673 var->red.length = 4; in _ivtvfb_check_var()
674 var->green.offset = 4; in _ivtvfb_check_var()
675 var->green.length = 4; in _ivtvfb_check_var()
676 var->blue.offset = 0; in _ivtvfb_check_var()
677 var->blue.length = 4; in _ivtvfb_check_var()
678 var->transp.offset = 12; in _ivtvfb_check_var()
679 var->transp.length = 1; in _ivtvfb_check_var()
682 var->red.offset = 10; in _ivtvfb_check_var()
683 var->red.length = 5; in _ivtvfb_check_var()
684 var->green.offset = 5; in _ivtvfb_check_var()
685 var->green.length = 5; in _ivtvfb_check_var()
686 var->blue.offset = 0; in _ivtvfb_check_var()
687 var->blue.length = 5; in _ivtvfb_check_var()
688 var->transp.offset = 15; in _ivtvfb_check_var()
689 var->transp.length = 1; in _ivtvfb_check_var()
692 var->red.offset = 11; in _ivtvfb_check_var()
693 var->red.length = 5; in _ivtvfb_check_var()
694 var->green.offset = 5; in _ivtvfb_check_var()
695 var->green.length = 6; in _ivtvfb_check_var()
696 var->blue.offset = 0; in _ivtvfb_check_var()
697 var->blue.length = 5; in _ivtvfb_check_var()
698 var->transp.offset = 0; in _ivtvfb_check_var()
699 var->transp.length = 0; in _ivtvfb_check_var()
704 IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel); in _ivtvfb_check_var()
705 return -EINVAL; in _ivtvfb_check_var()
709 if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) { in _ivtvfb_check_var()
711 var->xres, var->yres); in _ivtvfb_check_var()
712 return -EINVAL; in _ivtvfb_check_var()
716 if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) || in _ivtvfb_check_var()
717 var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size || in _ivtvfb_check_var()
718 var->xres_virtual < var->xres || in _ivtvfb_check_var()
719 var->yres_virtual < var->yres) { in _ivtvfb_check_var()
721 var->xres_virtual, var->yres_virtual); in _ivtvfb_check_var()
722 return -EINVAL; in _ivtvfb_check_var()
726 if (var->bits_per_pixel == 8) { in _ivtvfb_check_var()
728 if (var->xres & 3) { in _ivtvfb_check_var()
729 IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres); in _ivtvfb_check_var()
730 return -EINVAL; in _ivtvfb_check_var()
732 if (var->xres_virtual & 3) { in _ivtvfb_check_var()
733 IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual); in _ivtvfb_check_var()
734 return -EINVAL; in _ivtvfb_check_var()
737 else if (var->bits_per_pixel == 16) { in _ivtvfb_check_var()
739 if (var->xres & 1) { in _ivtvfb_check_var()
740 IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres); in _ivtvfb_check_var()
741 return -EINVAL; in _ivtvfb_check_var()
743 if (var->xres_virtual & 1) { in _ivtvfb_check_var()
744 IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual); in _ivtvfb_check_var()
745 return -EINVAL; in _ivtvfb_check_var()
750 if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) { in _ivtvfb_check_var()
752 var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual); in _ivtvfb_check_var()
753 return -EINVAL; in _ivtvfb_check_var()
757 if (var->nonstd > 1) { in _ivtvfb_check_var()
758 IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd); in _ivtvfb_check_var()
759 return -EINVAL; in _ivtvfb_check_var()
763 if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) && in _ivtvfb_check_var()
764 ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) { in _ivtvfb_check_var()
765 IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK); in _ivtvfb_check_var()
766 return -EINVAL; in _ivtvfb_check_var()
773 if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) in _ivtvfb_check_var()
774 var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2); in _ivtvfb_check_var()
776 if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481)) in _ivtvfb_check_var()
777 var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) - in _ivtvfb_check_var()
778 var->yres) / 2); in _ivtvfb_check_var()
781 var->right_margin = hlimit - var->left_margin - var->xres; in _ivtvfb_check_var()
782 var->lower_margin = vlimit - var->upper_margin - var->yres; in _ivtvfb_check_var()
785 var->hsync_len = 24; in _ivtvfb_check_var()
786 var->vsync_len = 2; in _ivtvfb_check_var()
788 /* Non-interlaced / interlaced mode is used to switch the OSD filter in _ivtvfb_check_var()
791 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) in _ivtvfb_check_var()
792 var->pixclock = pixclock / 2; in _ivtvfb_check_var()
794 var->pixclock = pixclock; in _ivtvfb_check_var()
796 itv->osd_rect.width = var->xres; in _ivtvfb_check_var()
797 itv->osd_rect.height = var->yres; in _ivtvfb_check_var()
800 var->xres, var->yres, in _ivtvfb_check_var()
801 var->xres_virtual, var->yres_virtual, in _ivtvfb_check_var()
802 var->bits_per_pixel); in _ivtvfb_check_var()
805 var->left_margin, var->upper_margin); in _ivtvfb_check_var()
808 (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off"); in _ivtvfb_check_var()
809 IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB"); in _ivtvfb_check_var()
815 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_check_var()
823 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_pan_display()
825 if (var->yoffset + info->var.yres > info->var.yres_virtual || in ivtvfb_pan_display()
826 var->xoffset + info->var.xres > info->var.xres_virtual) in ivtvfb_pan_display()
827 return -EINVAL; in ivtvfb_pan_display()
829 osd_pan_index = var->yoffset * info->fix.line_length in ivtvfb_pan_display()
830 + var->xoffset * info->var.bits_per_pixel / 8; in ivtvfb_pan_display()
834 itv->yuv_info.osd_x_pan = var->xoffset; in ivtvfb_pan_display()
835 itv->yuv_info.osd_y_pan = var->yoffset; in ivtvfb_pan_display()
837 itv->yuv_info.yuv_forced_update = 1; in ivtvfb_pan_display()
839 itv->osd_info->pan_cur = osd_pan_index; in ivtvfb_pan_display()
846 struct ivtv *itv = (struct ivtv *) info->par; in ivtvfb_set_par()
850 rc = ivtvfb_set_var(itv, &info->var); in ivtvfb_set_par()
851 ivtvfb_pan_display(&info->var, info); in ivtvfb_set_par()
852 ivtvfb_get_fix(itv, &info->fix); in ivtvfb_set_par()
862 struct ivtv *itv = (struct ivtv *)info->par; in ivtvfb_setcolreg()
864 if (regno >= info->cmap.len) in ivtvfb_setcolreg()
865 return -EINVAL; in ivtvfb_setcolreg()
868 if (info->var.bits_per_pixel <= 8) { in ivtvfb_setcolreg()
871 itv->osd_info->palette_cur[regno] = color; in ivtvfb_setcolreg()
875 return -EINVAL; in ivtvfb_setcolreg()
877 palette = info->pseudo_palette; in ivtvfb_setcolreg()
878 if (info->var.bits_per_pixel == 16) { in ivtvfb_setcolreg()
879 switch (info->var.green.length) { in ivtvfb_setcolreg()
905 struct ivtv *itv = (struct ivtv *)info->par; in ivtvfb_blank()
924 itv->osd_info->blank_cur = blank_mode; in ivtvfb_blank()
946 struct osd_info *oi = itv->osd_info; in ivtvfb_restore()
949 ivtvfb_set_var(itv, &oi->fbvar_cur); in ivtvfb_restore()
950 ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info); in ivtvfb_restore()
953 write_reg(oi->palette_cur[i], 0x02a34); in ivtvfb_restore()
955 write_reg(oi->pan_cur, 0x02a0c); in ivtvfb_restore()
964 struct osd_info *oi = itv->osd_info; in ivtvfb_init_vidmode()
972 oi->bits_per_pixel = osd_depth; in ivtvfb_init_vidmode()
973 oi->bytes_per_pixel = oi->bits_per_pixel / 8; in ivtvfb_init_vidmode()
990 IVTVFB_ERR("Invalid osd_left - assuming default\n"); in ivtvfb_init_vidmode()
995 osd_left--; in ivtvfb_init_vidmode()
998 osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2); in ivtvfb_init_vidmode()
1000 oi->display_byte_stride = in ivtvfb_init_vidmode()
1001 start_window.width * oi->bytes_per_pixel; in ivtvfb_init_vidmode()
1005 max_height = itv->is_out_50hz ? 576 : 480; in ivtvfb_init_vidmode()
1011 osd_yres : itv->is_out_50hz ? 480 : 400; in ivtvfb_init_vidmode()
1015 IVTVFB_ERR("Invalid osd_upper - assuming default\n"); in ivtvfb_init_vidmode()
1020 osd_upper--; in ivtvfb_init_vidmode()
1022 start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2); in ivtvfb_init_vidmode()
1024 oi->display_width = start_window.width; in ivtvfb_init_vidmode()
1025 oi->display_height = start_window.height; in ivtvfb_init_vidmode()
1029 oi->ivtvfb_defined.xres = oi->display_width; in ivtvfb_init_vidmode()
1030 oi->ivtvfb_defined.yres = oi->display_height; in ivtvfb_init_vidmode()
1031 oi->ivtvfb_defined.xres_virtual = oi->display_width; in ivtvfb_init_vidmode()
1032 oi->ivtvfb_defined.yres_virtual = oi->display_height; in ivtvfb_init_vidmode()
1033 oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel; in ivtvfb_init_vidmode()
1034 oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED); in ivtvfb_init_vidmode()
1035 oi->ivtvfb_defined.left_margin = start_window.left + 1; in ivtvfb_init_vidmode()
1036 oi->ivtvfb_defined.upper_margin = start_window.top + 1; in ivtvfb_init_vidmode()
1037 oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE; in ivtvfb_init_vidmode()
1038 oi->ivtvfb_defined.nonstd = 0; in ivtvfb_init_vidmode()
1042 _ivtvfb_check_var(&oi->ivtvfb_defined, itv); in ivtvfb_init_vidmode()
1046 ivtvfb_get_fix(itv, &oi->ivtvfb_fix); in ivtvfb_init_vidmode()
1050 oi->ivtvfb_info.node = -1; in ivtvfb_init_vidmode()
1051 oi->ivtvfb_info.par = itv; in ivtvfb_init_vidmode()
1052 oi->ivtvfb_info.var = oi->ivtvfb_defined; in ivtvfb_init_vidmode()
1053 oi->ivtvfb_info.fix = oi->ivtvfb_fix; in ivtvfb_init_vidmode()
1054 oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase; in ivtvfb_init_vidmode()
1055 oi->ivtvfb_info.fbops = &ivtvfb_ops; in ivtvfb_init_vidmode()
1058 oi->ivtvfb_info.monspecs.hfmin = 8000; in ivtvfb_init_vidmode()
1059 oi->ivtvfb_info.monspecs.hfmax = 70000; in ivtvfb_init_vidmode()
1060 oi->ivtvfb_info.monspecs.vfmin = 10; in ivtvfb_init_vidmode()
1061 oi->ivtvfb_info.monspecs.vfmax = 100; in ivtvfb_init_vidmode()
1064 if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) { in ivtvfb_init_vidmode()
1066 return -ENOMEM; in ivtvfb_init_vidmode()
1070 oi->ivtvfb_info.pseudo_palette = in ivtvfb_init_vidmode()
1073 if (!oi->ivtvfb_info.pseudo_palette) { in ivtvfb_init_vidmode()
1075 return -ENOMEM; in ivtvfb_init_vidmode()
1085 struct osd_info *oi = itv->osd_info; in ivtvfb_init_io()
1089 mutex_lock(&itv->serialize_lock); in ivtvfb_init_io()
1091 mutex_unlock(&itv->serialize_lock); in ivtvfb_init_io()
1093 return -ENXIO; in ivtvfb_init_io()
1095 mutex_unlock(&itv->serialize_lock); in ivtvfb_init_io()
1097 if (ivtvfb_get_framebuffer(itv, &oi->video_rbase, in ivtvfb_init_io()
1098 &oi->video_buffer_size) < 0) { in ivtvfb_init_io()
1100 return -EIO; in ivtvfb_init_io()
1106 oi->video_buffer_size = 1704960; in ivtvfb_init_io()
1108 oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase; in ivtvfb_init_io()
1109 oi->video_vbase = itv->dec_mem + oi->video_rbase; in ivtvfb_init_io()
1111 if (!oi->video_vbase) { in ivtvfb_init_io()
1113 oi->video_buffer_size, oi->video_pbase); in ivtvfb_init_io()
1114 return -EIO; in ivtvfb_init_io()
1117 IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", in ivtvfb_init_io()
1118 oi->video_pbase, oi->video_vbase, in ivtvfb_init_io()
1119 oi->video_buffer_size / 1024); in ivtvfb_init_io()
1121 while (!(oi->video_buffer_size & (1 << size_shift))) in ivtvfb_init_io()
1122 size_shift--; in ivtvfb_init_io()
1124 oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1); in ivtvfb_init_io()
1125 oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size; in ivtvfb_init_io()
1126 oi->fb_end_aligned_physaddr += (1 << size_shift) - 1; in ivtvfb_init_io()
1127 oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1); in ivtvfb_init_io()
1128 oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr, in ivtvfb_init_io()
1129 oi->fb_end_aligned_physaddr - in ivtvfb_init_io()
1130 oi->fb_start_aligned_physaddr); in ivtvfb_init_io()
1132 memset_io(oi->video_vbase, 0, oi->video_buffer_size); in ivtvfb_init_io()
1140 struct osd_info *oi = itv->osd_info; in ivtvfb_release_buffers()
1143 if (oi->ivtvfb_info.cmap.len) in ivtvfb_release_buffers()
1144 fb_dealloc_cmap(&oi->ivtvfb_info.cmap); in ivtvfb_release_buffers()
1147 kfree(oi->ivtvfb_info.pseudo_palette); in ivtvfb_release_buffers()
1148 arch_phys_wc_del(oi->wc_cookie); in ivtvfb_release_buffers()
1150 itv->osd_info = NULL; in ivtvfb_release_buffers()
1162 pr_info("PAT is enabled. Write-combined framebuffer caching will be disabled.\n"); in ivtvfb_init_card()
1165 pr_warn("ivtvfb needs PAT disabled for write-combined framebuffer caching.\n"); in ivtvfb_init_card()
1168 return -ENODEV; in ivtvfb_init_card()
1173 if (itv->osd_info) { in ivtvfb_init_card()
1175 return -EBUSY; in ivtvfb_init_card()
1178 itv->osd_info = kzalloc(sizeof(struct osd_info), in ivtvfb_init_card()
1180 if (itv->osd_info == NULL) { in ivtvfb_init_card()
1182 return -ENOMEM; in ivtvfb_init_card()
1199 if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) { in ivtvfb_init_card()
1201 return -EINVAL; in ivtvfb_init_card()
1204 itv->osd_video_pbase = itv->osd_info->video_pbase; in ivtvfb_init_card()
1207 ivtvfb_set_par(&itv->osd_info->ivtvfb_info); in ivtvfb_init_card()
1214 ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info); in ivtvfb_init_card()
1217 itv->ivtvfb_restore = ivtvfb_restore; in ivtvfb_init_card()
1221 itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps |= in ivtvfb_init_card()
1223 itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps |= in ivtvfb_init_card()
1225 itv->v4l2_cap |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY; in ivtvfb_init_card()
1230 static int __init ivtvfb_callback_init(struct device *dev, void *p) in ivtvfb_callback_init() argument
1235 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { in ivtvfb_callback_init()
1238 itv->v4l2_dev.name); in ivtvfb_callback_init()
1239 (*(int *)p)++; in ivtvfb_callback_init()
1245 static int ivtvfb_callback_cleanup(struct device *dev, void *p) in ivtvfb_callback_cleanup() argument
1249 struct osd_info *oi = itv->osd_info; in ivtvfb_callback_cleanup()
1251 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { in ivtvfb_callback_cleanup()
1252 itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps &= in ivtvfb_callback_cleanup()
1254 itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &= in ivtvfb_callback_cleanup()
1256 itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; in ivtvfb_callback_cleanup()
1257 unregister_framebuffer(&itv->osd_info->ivtvfb_info); in ivtvfb_callback_cleanup()
1258 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); in ivtvfb_callback_cleanup()
1259 itv->ivtvfb_restore = NULL; in ivtvfb_callback_cleanup()
1260 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); in ivtvfb_callback_cleanup()
1262 itv->osd_video_pbase = 0; in ivtvfb_callback_cleanup()
1274 if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) { in ivtvfb_init()
1275 pr_err("ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n", in ivtvfb_init()
1276 IVTV_MAX_CARDS - 1); in ivtvfb_init()
1277 return -EINVAL; in ivtvfb_init()
1285 return -ENODEV; in ivtvfb_init()