diff options
Diffstat (limited to 'drivers/media/pci/ivtv/ivtvfb.c')
| -rw-r--r-- | drivers/media/pci/ivtv/ivtvfb.c | 83 |
1 files changed, 44 insertions, 39 deletions
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 8ec2525d8ef5..90c584cf97c2 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* On Screen Display cx23415 Framebuffer driver @@ -23,19 +24,6 @@ Copyright (C) 2006 Ian Armstrong <ian@iarmst.demon.co.uk> - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ivtv-driver.h" @@ -48,28 +36,30 @@ #include <linux/fb.h> #include <linux/ivtvfb.h> -#ifdef CONFIG_X86_64 -#include <asm/pat.h> +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) +#include <asm/memtype.h> #endif /* card parameters */ static int ivtvfb_card_id = -1; -static int ivtvfb_debug = 0; +static int ivtvfb_debug; +static bool ivtvfb_force_pat = IS_ENABLED(CONFIG_VIDEO_FB_IVTV_FORCE_PAT); static bool osd_laced; static int osd_depth; static int osd_upper; static int osd_left; -static int osd_yres; -static int osd_xres; +static unsigned int osd_yres; +static unsigned int osd_xres; module_param(ivtvfb_card_id, int, 0444); module_param_named(debug,ivtvfb_debug, int, 0644); +module_param_named(force_pat, ivtvfb_force_pat, bool, 0644); module_param(osd_laced, bool, 0444); module_param(osd_depth, int, 0444); module_param(osd_upper, int, 0444); module_param(osd_left, int, 0444); -module_param(osd_yres, int, 0444); -module_param(osd_xres, int, 0444); +module_param(osd_yres, uint, 0444); +module_param(osd_xres, uint, 0444); MODULE_PARM_DESC(ivtvfb_card_id, "Only use framebuffer of the specified ivtv card (0-31)\n" @@ -79,6 +69,9 @@ MODULE_PARM_DESC(debug, "Debug level (bitmask). Default: errors only\n" "\t\t\t(debug = 3 gives full debugging)"); +MODULE_PARM_DESC(force_pat, + "Force initialization on x86 PAT-enabled systems (bool).\n"); + /* Why upper, left, xres, yres, depth, laced ? To match terminology used by fbset. Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */ @@ -111,6 +104,7 @@ MODULE_PARM_DESC(osd_xres, "\t\t\tdefault 640"); MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong"); +MODULE_DESCRIPTION("Conexant cx23415 framebuffer support"); MODULE_LICENSE("GPL"); /* --------------------------------------------------------------------- */ @@ -288,10 +282,10 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv, /* Map User DMA */ if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) { mutex_unlock(&itv->udma.lock); - IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with get_user_pages: %d bytes, %d pages returned\n", - size_in_bytes, itv->udma.page_count); + IVTVFB_WARN("%s, Error in ivtv_udma_setup: %d bytes, %d pages returned\n", + __func__, size_in_bytes, itv->udma.page_count); - /* get_user_pages must have failed completely */ + /* pin_user_pages or DMA must have failed completely */ return -EIO; } @@ -385,8 +379,8 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, unsigned long dma_size; u16 lead = 0, tail = 0; - if (info->state != FBINFO_STATE_RUNNING) - return -EPERM; + if (!info->screen_base) + return -ENODEV; total_size = info->screen_size; @@ -932,19 +926,19 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info) return 0; } -static struct fb_ops ivtvfb_ops = { +static const struct fb_ops ivtvfb_ops = { .owner = THIS_MODULE, + .fb_read = fb_io_read, .fb_write = ivtvfb_write, .fb_check_var = ivtvfb_check_var, .fb_set_par = ivtvfb_set_par, .fb_setcolreg = ivtvfb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_cursor = NULL, .fb_ioctl = ivtvfb_ioctl, .fb_pan_display = ivtvfb_pan_display, .fb_blank = ivtvfb_blank, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* Restore hardware after firmware restart */ @@ -1055,8 +1049,6 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) /* Generate valid fb_info */ oi->ivtvfb_info.node = -1; - oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT; - oi->ivtvfb_info.fbops = &ivtvfb_ops; oi->ivtvfb_info.par = itv; oi->ivtvfb_info.var = oi->ivtvfb_defined; oi->ivtvfb_info.fix = oi->ivtvfb_fix; @@ -1165,10 +1157,17 @@ static int ivtvfb_init_card(struct ivtv *itv) { int rc; -#ifdef CONFIG_X86_64 +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) if (pat_enabled()) { - pr_warn("ivtvfb needs PAT disabled, boot with nopat kernel parameter\n"); - return -ENODEV; + if (ivtvfb_force_pat) { + pr_info("PAT is enabled. Write-combined framebuffer caching will be disabled.\n"); + pr_info("To enable caching, boot with nopat kernel parameter\n"); + } else { + pr_warn("ivtvfb needs PAT disabled for write-combined framebuffer caching.\n"); + pr_warn("Boot with nopat kernel parameter to use caching, or use the\n"); + pr_warn("force_pat module parameter to run with caching disabled\n"); + return -ENODEV; + } } #endif @@ -1220,6 +1219,11 @@ static int ivtvfb_init_card(struct ivtv *itv) /* Allocate DMA */ ivtv_udma_alloc(itv); + itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps |= + V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps |= + V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + itv->v4l2_cap |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY; return 0; } @@ -1246,11 +1250,12 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) struct osd_info *oi = itv->osd_info; if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { - if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { - IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", - itv->instance); - return 0; - } + itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps &= + ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &= + ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + unregister_framebuffer(&itv->osd_info->ivtvfb_info); IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); itv->ivtvfb_restore = NULL; ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); |
