cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ivtvfb.c (37027B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3    On Screen Display cx23415 Framebuffer driver
      4
      5    This module presents the cx23415 OSD (onscreen display) framebuffer memory
      6    as a standard Linux /dev/fb style framebuffer device. The framebuffer has
      7    support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
      8    mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
      9    local alpha. The colorspace is selectable between rgb & yuv.
     10    Depending on the TV standard configured in the ivtv module at load time,
     11    the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
     12    Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
     13    or 59.94 (NTSC)
     14
     15    Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
     16
     17    Derived from drivers/video/vesafb.c
     18    Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
     19
     20    2.6 kernel port:
     21    Copyright (C) 2004 Matthias Badaire
     22
     23    Copyright (C) 2004  Chris Kennedy <c@groovy.org>
     24
     25    Copyright (C) 2006  Ian Armstrong <ian@iarmst.demon.co.uk>
     26
     27 */
     28
     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"
     35
     36#include <linux/fb.h>
     37#include <linux/ivtvfb.h>
     38
     39#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
     40#include <asm/memtype.h>
     41#endif
     42
     43/* card parameters */
     44static int ivtvfb_card_id = -1;
     45static int ivtvfb_debug;
     46static bool ivtvfb_force_pat = IS_ENABLED(CONFIG_VIDEO_FB_IVTV_FORCE_PAT);
     47static bool osd_laced;
     48static int osd_depth;
     49static int osd_upper;
     50static int osd_left;
     51static unsigned int osd_yres;
     52static unsigned int osd_xres;
     53
     54module_param(ivtvfb_card_id, int, 0444);
     55module_param_named(debug,ivtvfb_debug, int, 0644);
     56module_param_named(force_pat, ivtvfb_force_pat, bool, 0644);
     57module_param(osd_laced, bool, 0444);
     58module_param(osd_depth, int, 0444);
     59module_param(osd_upper, int, 0444);
     60module_param(osd_left, int, 0444);
     61module_param(osd_yres, uint, 0444);
     62module_param(osd_xres, uint, 0444);
     63
     64MODULE_PARM_DESC(ivtvfb_card_id,
     65		 "Only use framebuffer of the specified ivtv card (0-31)\n"
     66		 "\t\t\tdefault -1: initialize all available framebuffers");
     67
     68MODULE_PARM_DESC(debug,
     69		 "Debug level (bitmask). Default: errors only\n"
     70		 "\t\t\t(debug = 3 gives full debugging)");
     71
     72MODULE_PARM_DESC(force_pat,
     73		 "Force initialization on x86 PAT-enabled systems (bool).\n");
     74
     75/* Why upper, left, xres, yres, depth, laced ? To match terminology used
     76   by fbset.
     77   Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
     78
     79MODULE_PARM_DESC(osd_laced,
     80		 "Interlaced mode\n"
     81		 "\t\t\t0=off\n"
     82		 "\t\t\t1=on\n"
     83		 "\t\t\tdefault off");
     84
     85MODULE_PARM_DESC(osd_depth,
     86		 "Bits per pixel - 8, 16, 32\n"
     87		 "\t\t\tdefault 8");
     88
     89MODULE_PARM_DESC(osd_upper,
     90		 "Vertical start position\n"
     91		 "\t\t\tdefault 0 (Centered)");
     92
     93MODULE_PARM_DESC(osd_left,
     94		 "Horizontal start position\n"
     95		 "\t\t\tdefault 0 (Centered)");
     96
     97MODULE_PARM_DESC(osd_yres,
     98		 "Display height\n"
     99		 "\t\t\tdefault 480 (PAL)\n"
    100		 "\t\t\t        400 (NTSC)");
    101
    102MODULE_PARM_DESC(osd_xres,
    103		 "Display width\n"
    104		 "\t\t\tdefault 640");
    105
    106MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
    107MODULE_LICENSE("GPL");
    108
    109/* --------------------------------------------------------------------- */
    110
    111#define IVTVFB_DBGFLG_WARN  (1 << 0)
    112#define IVTVFB_DBGFLG_INFO  (1 << 1)
    113
    114#define IVTVFB_DEBUG(x, type, fmt, args...) \
    115	do { \
    116		if ((x) & ivtvfb_debug) \
    117			printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
    118	} while (0)
    119#define IVTVFB_DEBUG_WARN(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
    120#define IVTVFB_DEBUG_INFO(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
    121
    122/* Standard kernel messages */
    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)
    126
    127/* --------------------------------------------------------------------- */
    128
    129#define IVTV_OSD_MAX_WIDTH  720
    130#define IVTV_OSD_MAX_HEIGHT 576
    131
    132#define IVTV_OSD_BPP_8      0x00
    133#define IVTV_OSD_BPP_16_444 0x03
    134#define IVTV_OSD_BPP_16_555 0x02
    135#define IVTV_OSD_BPP_16_565 0x01
    136#define IVTV_OSD_BPP_32     0x04
    137
    138struct osd_info {
    139	/* Physical base address */
    140	unsigned long video_pbase;
    141	/* Relative base address (relative to start of decoder memory) */
    142	u32 video_rbase;
    143	/* Mapped base address */
    144	volatile char __iomem *video_vbase;
    145	/* Buffer size */
    146	u32 video_buffer_size;
    147
    148	/* video_base rounded down as required by hardware MTRRs */
    149	unsigned long fb_start_aligned_physaddr;
    150	/* video_base rounded up as required by hardware MTRRs */
    151	unsigned long fb_end_aligned_physaddr;
    152	int wc_cookie;
    153
    154	/* Store the buffer offset */
    155	int set_osd_coords_x;
    156	int set_osd_coords_y;
    157
    158	/* Current dimensions (NOT VISIBLE SIZE!) */
    159	int display_width;
    160	int display_height;
    161	int display_byte_stride;
    162
    163	/* Current bits per pixel */
    164	int bits_per_pixel;
    165	int bytes_per_pixel;
    166
    167	/* Frame buffer stuff */
    168	struct fb_info ivtvfb_info;
    169	struct fb_var_screeninfo ivtvfb_defined;
    170	struct fb_fix_screeninfo ivtvfb_fix;
    171
    172	/* Used for a warm start */
    173	struct fb_var_screeninfo fbvar_cur;
    174	int blank_cur;
    175	u32 palette_cur[256];
    176	u32 pan_cur;
    177};
    178
    179struct ivtv_osd_coords {
    180	unsigned long offset;
    181	unsigned long max_offset;
    182	int pixel_stride;
    183	int lines;
    184	int x;
    185	int y;
    186};
    187
    188/* --------------------------------------------------------------------- */
    189
    190/* ivtv API calls for framebuffer related support */
    191
    192static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
    193				       u32 *fblength)
    194{
    195	u32 data[CX2341X_MBOX_MAX_DATA];
    196	int rc;
    197
    198	ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
    199	rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
    200	*fbbase = data[0];
    201	*fblength = data[1];
    202	return rc;
    203}
    204
    205static int ivtvfb_get_osd_coords(struct ivtv *itv,
    206				      struct ivtv_osd_coords *osd)
    207{
    208	struct osd_info *oi = itv->osd_info;
    209	u32 data[CX2341X_MBOX_MAX_DATA];
    210
    211	ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
    212
    213	osd->offset = data[0] - oi->video_rbase;
    214	osd->max_offset = oi->display_width * oi->display_height * 4;
    215	osd->pixel_stride = data[1];
    216	osd->lines = data[2];
    217	osd->x = data[3];
    218	osd->y = data[4];
    219	return 0;
    220}
    221
    222static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
    223{
    224	struct osd_info *oi = itv->osd_info;
    225
    226	oi->display_width = osd->pixel_stride;
    227	oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
    228	oi->set_osd_coords_x += osd->x;
    229	oi->set_osd_coords_y = osd->y;
    230
    231	return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
    232			osd->offset + oi->video_rbase,
    233			osd->pixel_stride,
    234			osd->lines, osd->x, osd->y);
    235}
    236
    237static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
    238{
    239	int osd_height_limit = itv->is_out_50hz ? 576 : 480;
    240
    241	/* Only fail if resolution too high, otherwise fudge the start coords. */
    242	if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
    243		return -EINVAL;
    244
    245	/* Ensure we don't exceed display limits */
    246	if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
    247		IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
    248			ivtv_window->top, ivtv_window->height);
    249		ivtv_window->top = osd_height_limit - ivtv_window->height;
    250	}
    251
    252	if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
    253		IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
    254			ivtv_window->left, ivtv_window->width);
    255		ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
    256	}
    257
    258	/* Set the OSD origin */
    259	write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
    260
    261	/* How much to display */
    262	write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
    263
    264	/* Pass this info back the yuv handler */
    265	itv->yuv_info.osd_vis_w = ivtv_window->width;
    266	itv->yuv_info.osd_vis_h = ivtv_window->height;
    267	itv->yuv_info.osd_x_offset = ivtv_window->left;
    268	itv->yuv_info.osd_y_offset = ivtv_window->top;
    269
    270	return 0;
    271}
    272
    273static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
    274				  unsigned long ivtv_dest_addr, void __user *userbuf,
    275				  int size_in_bytes)
    276{
    277	DEFINE_WAIT(wait);
    278	int got_sig = 0;
    279
    280	mutex_lock(&itv->udma.lock);
    281	/* Map User DMA */
    282	if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
    283		mutex_unlock(&itv->udma.lock);
    284		IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with pin_user_pages: %d bytes, %d pages returned\n",
    285			       size_in_bytes, itv->udma.page_count);
    286
    287		/* pin_user_pages must have failed completely */
    288		return -EIO;
    289	}
    290
    291	IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n",
    292		       size_in_bytes, itv->udma.page_count);
    293
    294	ivtv_udma_prepare(itv);
    295	prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
    296	/* if no UDMA is pending and no UDMA is in progress, then the DMA
    297	   is finished */
    298	while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
    299	       test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
    300		/* don't interrupt if the DMA is in progress but break off
    301		   a still pending DMA. */
    302		got_sig = signal_pending(current);
    303		if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
    304			break;
    305		got_sig = 0;
    306		schedule();
    307	}
    308	finish_wait(&itv->dma_waitq, &wait);
    309
    310	/* Unmap Last DMA Xfer */
    311	ivtv_udma_unmap(itv);
    312	mutex_unlock(&itv->udma.lock);
    313	if (got_sig) {
    314		IVTV_DEBUG_INFO("User stopped OSD\n");
    315		return -EINTR;
    316	}
    317
    318	return 0;
    319}
    320
    321static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
    322			      unsigned long dest_offset, int count)
    323{
    324	DEFINE_WAIT(wait);
    325	struct osd_info *oi = itv->osd_info;
    326
    327	/* Nothing to do */
    328	if (count == 0) {
    329		IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n");
    330		return -EINVAL;
    331	}
    332
    333	/* Check Total FB Size */
    334	if ((dest_offset + count) > oi->video_buffer_size) {
    335		IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
    336			dest_offset + count, oi->video_buffer_size);
    337		return -E2BIG;
    338	}
    339
    340	/* Not fatal, but will have undesirable results */
    341	if ((unsigned long)source & 3)
    342		IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (%p)\n",
    343			    source);
    344
    345	if (dest_offset & 3)
    346		IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
    347
    348	if (count & 3)
    349		IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
    350
    351	/* Check Source */
    352	if (!access_ok(source + dest_offset, count)) {
    353		IVTVFB_WARN("Invalid userspace pointer %p\n", source);
    354
    355		IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source %p count %d\n",
    356				  dest_offset, source, count);
    357		return -EINVAL;
    358	}
    359
    360	/* OSD Address to send DMA to */
    361	dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
    362
    363	/* Fill Buffers */
    364	return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
    365}
    366
    367static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
    368						size_t count, loff_t *ppos)
    369{
    370	unsigned long p = *ppos;
    371	void *dst;
    372	int err = 0;
    373	int dma_err;
    374	unsigned long total_size;
    375	struct ivtv *itv = (struct ivtv *) info->par;
    376	unsigned long dma_offset =
    377			IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
    378	unsigned long dma_size;
    379	u16 lead = 0, tail = 0;
    380
    381	if (info->state != FBINFO_STATE_RUNNING)
    382		return -EPERM;
    383
    384	total_size = info->screen_size;
    385
    386	if (total_size == 0)
    387		total_size = info->fix.smem_len;
    388
    389	if (p > total_size)
    390		return -EFBIG;
    391
    392	if (count > total_size) {
    393		err = -EFBIG;
    394		count = total_size;
    395	}
    396
    397	if (count + p > total_size) {
    398		if (!err)
    399			err = -ENOSPC;
    400		count = total_size - p;
    401	}
    402
    403	dst = (void __force *) (info->screen_base + p);
    404
    405	if (info->fbops->fb_sync)
    406		info->fbops->fb_sync(info);
    407
    408	/* If transfer size > threshold and both src/dst
    409	addresses are aligned, use DMA */
    410	if (count >= 4096 &&
    411	    ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
    412		/* Odd address = can't DMA. Align */
    413		if ((unsigned long)dst & 3) {
    414			lead = 4 - ((unsigned long)dst & 3);
    415			if (copy_from_user(dst, buf, lead))
    416				return -EFAULT;
    417			buf += lead;
    418			dst += lead;
    419		}
    420		/* DMA resolution is 32 bits */
    421		if ((count - lead) & 3)
    422			tail = (count - lead) & 3;
    423		/* DMA the data */
    424		dma_size = count - lead - tail;
    425		dma_err = ivtvfb_prep_dec_dma_to_device(itv,
    426		       p + lead + dma_offset, (void __user *)buf, dma_size);
    427		if (dma_err)
    428			return dma_err;
    429		dst += dma_size;
    430		buf += dma_size;
    431		/* Copy any leftover data */
    432		if (tail && copy_from_user(dst, buf, tail))
    433			return -EFAULT;
    434	} else if (copy_from_user(dst, buf, count)) {
    435		return -EFAULT;
    436	}
    437
    438	if  (!err)
    439		*ppos += count;
    440
    441	return (err) ? err : count;
    442}
    443
    444static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
    445{
    446	DEFINE_WAIT(wait);
    447	struct ivtv *itv = (struct ivtv *)info->par;
    448	int rc = 0;
    449
    450	switch (cmd) {
    451		case FBIOGET_VBLANK: {
    452			struct fb_vblank vblank;
    453			u32 trace;
    454
    455			memset(&vblank, 0, sizeof(struct fb_vblank));
    456
    457			vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
    458					FB_VBLANK_HAVE_VSYNC;
    459			trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
    460			if (itv->is_out_50hz && trace > 312)
    461				trace -= 312;
    462			else if (itv->is_out_60hz && trace > 262)
    463				trace -= 262;
    464			if (trace == 1)
    465				vblank.flags |= FB_VBLANK_VSYNCING;
    466			vblank.count = itv->last_vsync_field;
    467			vblank.vcount = trace;
    468			vblank.hcount = 0;
    469			if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
    470				return -EFAULT;
    471			return 0;
    472		}
    473
    474		case FBIO_WAITFORVSYNC:
    475			prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
    476			if (!schedule_timeout(msecs_to_jiffies(50)))
    477				rc = -ETIMEDOUT;
    478			finish_wait(&itv->vsync_waitq, &wait);
    479			return rc;
    480
    481		case IVTVFB_IOC_DMA_FRAME: {
    482			struct ivtvfb_dma_frame args;
    483
    484			IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
    485			if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
    486				return -EFAULT;
    487
    488			return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
    489		}
    490
    491		default:
    492			IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
    493			return -EINVAL;
    494	}
    495	return 0;
    496}
    497
    498/* Framebuffer device handling */
    499
    500static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
    501{
    502	struct osd_info *oi = itv->osd_info;
    503	struct ivtv_osd_coords ivtv_osd;
    504	struct v4l2_rect ivtv_window;
    505	int osd_mode = -1;
    506
    507	IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
    508
    509	/* Select color space */
    510	if (var->nonstd) /* YUV */
    511		write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
    512	else /* RGB  */
    513		write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
    514
    515	/* Set the color mode */
    516	switch (var->bits_per_pixel) {
    517		case 8:
    518			osd_mode = IVTV_OSD_BPP_8;
    519			break;
    520		case 32:
    521			osd_mode = IVTV_OSD_BPP_32;
    522			break;
    523		case 16:
    524			switch (var->green.length) {
    525			case 4:
    526				osd_mode = IVTV_OSD_BPP_16_444;
    527				break;
    528			case 5:
    529				osd_mode = IVTV_OSD_BPP_16_555;
    530				break;
    531			case 6:
    532				osd_mode = IVTV_OSD_BPP_16_565;
    533				break;
    534			default:
    535				IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
    536			}
    537			break;
    538		default:
    539			IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
    540	}
    541
    542	/* Set video mode. Although rare, the display can become scrambled even
    543	   if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
    544	if (osd_mode != -1) {
    545		ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
    546		ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
    547	}
    548
    549	oi->bits_per_pixel = var->bits_per_pixel;
    550	oi->bytes_per_pixel = var->bits_per_pixel / 8;
    551
    552	/* Set the flicker filter */
    553	switch (var->vmode & FB_VMODE_MASK) {
    554		case FB_VMODE_NONINTERLACED: /* Filter on */
    555			ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
    556			break;
    557		case FB_VMODE_INTERLACED: /* Filter off */
    558			ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
    559			break;
    560		default:
    561			IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
    562	}
    563
    564	/* Read the current osd info */
    565	ivtvfb_get_osd_coords(itv, &ivtv_osd);
    566
    567	/* Now set the OSD to the size we want */
    568	ivtv_osd.pixel_stride = var->xres_virtual;
    569	ivtv_osd.lines = var->yres_virtual;
    570	ivtv_osd.x = 0;
    571	ivtv_osd.y = 0;
    572	ivtvfb_set_osd_coords(itv, &ivtv_osd);
    573
    574	/* Can't seem to find the right API combo for this.
    575	   Use another function which does what we need through direct register access. */
    576	ivtv_window.width = var->xres;
    577	ivtv_window.height = var->yres;
    578
    579	/* Minimum margin cannot be 0, as X won't allow such a mode */
    580	if (!var->upper_margin)
    581		var->upper_margin++;
    582	if (!var->left_margin)
    583		var->left_margin++;
    584	ivtv_window.top = var->upper_margin - 1;
    585	ivtv_window.left = var->left_margin - 1;
    586
    587	ivtvfb_set_display_window(itv, &ivtv_window);
    588
    589	/* Pass screen size back to yuv handler */
    590	itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride;
    591	itv->yuv_info.osd_full_h = ivtv_osd.lines;
    592
    593	/* Force update of yuv registers */
    594	itv->yuv_info.yuv_forced_update = 1;
    595
    596	/* Keep a copy of these settings */
    597	memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
    598
    599	IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
    600		      var->xres, var->yres,
    601		      var->xres_virtual, var->yres_virtual,
    602		      var->bits_per_pixel);
    603
    604	IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
    605		      var->left_margin, var->upper_margin);
    606
    607	IVTVFB_DEBUG_INFO("Display filter: %s\n",
    608			(var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
    609	IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
    610
    611	return 0;
    612}
    613
    614static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
    615{
    616	struct osd_info *oi = itv->osd_info;
    617
    618	IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
    619	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
    620	strscpy(fix->id, "cx23415 TV out", sizeof(fix->id));
    621	fix->smem_start = oi->video_pbase;
    622	fix->smem_len = oi->video_buffer_size;
    623	fix->type = FB_TYPE_PACKED_PIXELS;
    624	fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
    625	fix->xpanstep = 1;
    626	fix->ypanstep = 1;
    627	fix->ywrapstep = 0;
    628	fix->line_length = oi->display_byte_stride;
    629	fix->accel = FB_ACCEL_NONE;
    630	return 0;
    631}
    632
    633/* Check the requested display mode, returning -EINVAL if we can't
    634   handle it. */
    635
    636static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
    637{
    638	struct osd_info *oi = itv->osd_info;
    639	int osd_height_limit;
    640	u32 pixclock, hlimit, vlimit;
    641
    642	IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
    643
    644	/* Set base references for mode calcs. */
    645	if (itv->is_out_50hz) {
    646		pixclock = 84316;
    647		hlimit = 776;
    648		vlimit = 591;
    649		osd_height_limit = 576;
    650	}
    651	else {
    652		pixclock = 83926;
    653		hlimit = 776;
    654		vlimit = 495;
    655		osd_height_limit = 480;
    656	}
    657
    658	if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
    659		var->transp.offset = 24;
    660		var->transp.length = 8;
    661		var->red.offset = 16;
    662		var->red.length = 8;
    663		var->green.offset = 8;
    664		var->green.length = 8;
    665		var->blue.offset = 0;
    666		var->blue.length = 8;
    667	}
    668	else if (var->bits_per_pixel == 16) {
    669		/* To find out the true mode, check green length */
    670		switch (var->green.length) {
    671			case 4:
    672				var->red.offset = 8;
    673				var->red.length = 4;
    674				var->green.offset = 4;
    675				var->green.length = 4;
    676				var->blue.offset = 0;
    677				var->blue.length = 4;
    678				var->transp.offset = 12;
    679				var->transp.length = 1;
    680				break;
    681			case 5:
    682				var->red.offset = 10;
    683				var->red.length = 5;
    684				var->green.offset = 5;
    685				var->green.length = 5;
    686				var->blue.offset = 0;
    687				var->blue.length = 5;
    688				var->transp.offset = 15;
    689				var->transp.length = 1;
    690				break;
    691			default:
    692				var->red.offset = 11;
    693				var->red.length = 5;
    694				var->green.offset = 5;
    695				var->green.length = 6;
    696				var->blue.offset = 0;
    697				var->blue.length = 5;
    698				var->transp.offset = 0;
    699				var->transp.length = 0;
    700				break;
    701		}
    702	}
    703	else {
    704		IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
    705		return -EINVAL;
    706	}
    707
    708	/* Check the resolution */
    709	if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
    710		IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
    711				var->xres, var->yres);
    712		return -EINVAL;
    713	}
    714
    715	/* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
    716	if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
    717	    var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
    718	    var->xres_virtual < var->xres ||
    719	    var->yres_virtual < var->yres) {
    720		IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
    721			var->xres_virtual, var->yres_virtual);
    722		return -EINVAL;
    723	}
    724
    725	/* Some extra checks if in 8 bit mode */
    726	if (var->bits_per_pixel == 8) {
    727		/* Width must be a multiple of 4 */
    728		if (var->xres & 3) {
    729			IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
    730			return -EINVAL;
    731		}
    732		if (var->xres_virtual & 3) {
    733			IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
    734			return -EINVAL;
    735		}
    736	}
    737	else if (var->bits_per_pixel == 16) {
    738		/* Width must be a multiple of 2 */
    739		if (var->xres & 1) {
    740			IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
    741			return -EINVAL;
    742		}
    743		if (var->xres_virtual & 1) {
    744			IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
    745			return -EINVAL;
    746		}
    747	}
    748
    749	/* Now check the offsets */
    750	if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
    751		IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
    752			var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
    753		return -EINVAL;
    754	}
    755
    756	/* Check pixel format */
    757	if (var->nonstd > 1) {
    758		IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
    759		return -EINVAL;
    760	}
    761
    762	/* Check video mode */
    763	if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
    764		((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
    765		IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
    766		return -EINVAL;
    767	}
    768
    769	/* Check the left & upper margins
    770	   If the margins are too large, just center the screen
    771	   (enforcing margins causes too many problems) */
    772
    773	if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
    774		var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
    775
    776	if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
    777		var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
    778			var->yres) / 2);
    779
    780	/* Maintain overall 'size' for a constant refresh rate */
    781	var->right_margin = hlimit - var->left_margin - var->xres;
    782	var->lower_margin = vlimit - var->upper_margin - var->yres;
    783
    784	/* Fixed sync times */
    785	var->hsync_len = 24;
    786	var->vsync_len = 2;
    787
    788	/* Non-interlaced / interlaced mode is used to switch the OSD filter
    789	   on or off. Adjust the clock timings to maintain a constant
    790	   vertical refresh rate. */
    791	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
    792		var->pixclock = pixclock / 2;
    793	else
    794		var->pixclock = pixclock;
    795
    796	itv->osd_rect.width = var->xres;
    797	itv->osd_rect.height = var->yres;
    798
    799	IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
    800		      var->xres, var->yres,
    801		      var->xres_virtual, var->yres_virtual,
    802		      var->bits_per_pixel);
    803
    804	IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
    805		      var->left_margin, var->upper_margin);
    806
    807	IVTVFB_DEBUG_INFO("Display filter: %s\n",
    808			(var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
    809	IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
    810	return 0;
    811}
    812
    813static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
    814{
    815	struct ivtv *itv = (struct ivtv *) info->par;
    816	IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
    817	return _ivtvfb_check_var(var, itv);
    818}
    819
    820static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
    821{
    822	u32 osd_pan_index;
    823	struct ivtv *itv = (struct ivtv *) info->par;
    824
    825	if (var->yoffset + info->var.yres > info->var.yres_virtual ||
    826	    var->xoffset + info->var.xres > info->var.xres_virtual)
    827		return -EINVAL;
    828
    829	osd_pan_index = var->yoffset * info->fix.line_length
    830		      + var->xoffset * info->var.bits_per_pixel / 8;
    831	write_reg(osd_pan_index, 0x02A0C);
    832
    833	/* Pass this info back the yuv handler */
    834	itv->yuv_info.osd_x_pan = var->xoffset;
    835	itv->yuv_info.osd_y_pan = var->yoffset;
    836	/* Force update of yuv registers */
    837	itv->yuv_info.yuv_forced_update = 1;
    838	/* Remember this value */
    839	itv->osd_info->pan_cur = osd_pan_index;
    840	return 0;
    841}
    842
    843static int ivtvfb_set_par(struct fb_info *info)
    844{
    845	int rc = 0;
    846	struct ivtv *itv = (struct ivtv *) info->par;
    847
    848	IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
    849
    850	rc = ivtvfb_set_var(itv, &info->var);
    851	ivtvfb_pan_display(&info->var, info);
    852	ivtvfb_get_fix(itv, &info->fix);
    853	ivtv_firmware_check(itv, "ivtvfb_set_par");
    854	return rc;
    855}
    856
    857static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
    858				unsigned blue, unsigned transp,
    859				struct fb_info *info)
    860{
    861	u32 color, *palette;
    862	struct ivtv *itv = (struct ivtv *)info->par;
    863
    864	if (regno >= info->cmap.len)
    865		return -EINVAL;
    866
    867	color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
    868	if (info->var.bits_per_pixel <= 8) {
    869		write_reg(regno, 0x02a30);
    870		write_reg(color, 0x02a34);
    871		itv->osd_info->palette_cur[regno] = color;
    872		return 0;
    873	}
    874	if (regno >= 16)
    875		return -EINVAL;
    876
    877	palette = info->pseudo_palette;
    878	if (info->var.bits_per_pixel == 16) {
    879		switch (info->var.green.length) {
    880			case 4:
    881				color = ((red & 0xf000) >> 4) |
    882					((green & 0xf000) >> 8) |
    883					((blue & 0xf000) >> 12);
    884				break;
    885			case 5:
    886				color = ((red & 0xf800) >> 1) |
    887					((green & 0xf800) >> 6) |
    888					((blue & 0xf800) >> 11);
    889				break;
    890			case 6:
    891				color = (red & 0xf800 ) |
    892					((green & 0xfc00) >> 5) |
    893					((blue & 0xf800) >> 11);
    894				break;
    895		}
    896	}
    897	palette[regno] = color;
    898	return 0;
    899}
    900
    901/* We don't really support blanking. All this does is enable or
    902   disable the OSD. */
    903static int ivtvfb_blank(int blank_mode, struct fb_info *info)
    904{
    905	struct ivtv *itv = (struct ivtv *)info->par;
    906
    907	IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
    908	switch (blank_mode) {
    909	case FB_BLANK_UNBLANK:
    910		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
    911		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
    912		break;
    913	case FB_BLANK_NORMAL:
    914	case FB_BLANK_HSYNC_SUSPEND:
    915	case FB_BLANK_VSYNC_SUSPEND:
    916		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
    917		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
    918		break;
    919	case FB_BLANK_POWERDOWN:
    920		ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
    921		ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
    922		break;
    923	}
    924	itv->osd_info->blank_cur = blank_mode;
    925	return 0;
    926}
    927
    928static const struct fb_ops ivtvfb_ops = {
    929	.owner = THIS_MODULE,
    930	.fb_write       = ivtvfb_write,
    931	.fb_check_var   = ivtvfb_check_var,
    932	.fb_set_par     = ivtvfb_set_par,
    933	.fb_setcolreg   = ivtvfb_setcolreg,
    934	.fb_fillrect    = cfb_fillrect,
    935	.fb_copyarea    = cfb_copyarea,
    936	.fb_imageblit   = cfb_imageblit,
    937	.fb_cursor      = NULL,
    938	.fb_ioctl       = ivtvfb_ioctl,
    939	.fb_pan_display = ivtvfb_pan_display,
    940	.fb_blank       = ivtvfb_blank,
    941};
    942
    943/* Restore hardware after firmware restart */
    944static void ivtvfb_restore(struct ivtv *itv)
    945{
    946	struct osd_info *oi = itv->osd_info;
    947	int i;
    948
    949	ivtvfb_set_var(itv, &oi->fbvar_cur);
    950	ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
    951	for (i = 0; i < 256; i++) {
    952		write_reg(i, 0x02a30);
    953		write_reg(oi->palette_cur[i], 0x02a34);
    954	}
    955	write_reg(oi->pan_cur, 0x02a0c);
    956}
    957
    958/* Initialization */
    959
    960
    961/* Setup our initial video mode */
    962static int ivtvfb_init_vidmode(struct ivtv *itv)
    963{
    964	struct osd_info *oi = itv->osd_info;
    965	struct v4l2_rect start_window;
    966	int max_height;
    967
    968	/* Color mode */
    969
    970	if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
    971		osd_depth = 8;
    972	oi->bits_per_pixel = osd_depth;
    973	oi->bytes_per_pixel = oi->bits_per_pixel / 8;
    974
    975	/* Horizontal size & position */
    976
    977	if (osd_xres > 720)
    978		osd_xres = 720;
    979
    980	/* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
    981	if (osd_depth == 8)
    982		osd_xres &= ~3;
    983	else if (osd_depth == 16)
    984		osd_xres &= ~1;
    985
    986	start_window.width = osd_xres ? osd_xres : 640;
    987
    988	/* Check horizontal start (osd_left). */
    989	if (osd_left && osd_left + start_window.width > 721) {
    990		IVTVFB_ERR("Invalid osd_left - assuming default\n");
    991		osd_left = 0;
    992	}
    993
    994	/* Hardware coords start at 0, user coords start at 1. */
    995	osd_left--;
    996
    997	start_window.left = osd_left >= 0 ?
    998		 osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
    999
   1000	oi->display_byte_stride =
   1001			start_window.width * oi->bytes_per_pixel;
   1002
   1003	/* Vertical size & position */
   1004
   1005	max_height = itv->is_out_50hz ? 576 : 480;
   1006
   1007	if (osd_yres > max_height)
   1008		osd_yres = max_height;
   1009
   1010	start_window.height = osd_yres ?
   1011		osd_yres : itv->is_out_50hz ? 480 : 400;
   1012
   1013	/* Check vertical start (osd_upper). */
   1014	if (osd_upper + start_window.height > max_height + 1) {
   1015		IVTVFB_ERR("Invalid osd_upper - assuming default\n");
   1016		osd_upper = 0;
   1017	}
   1018
   1019	/* Hardware coords start at 0, user coords start at 1. */
   1020	osd_upper--;
   1021
   1022	start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
   1023
   1024	oi->display_width = start_window.width;
   1025	oi->display_height = start_window.height;
   1026
   1027	/* Generate a valid fb_var_screeninfo */
   1028
   1029	oi->ivtvfb_defined.xres = oi->display_width;
   1030	oi->ivtvfb_defined.yres = oi->display_height;
   1031	oi->ivtvfb_defined.xres_virtual = oi->display_width;
   1032	oi->ivtvfb_defined.yres_virtual = oi->display_height;
   1033	oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
   1034	oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
   1035	oi->ivtvfb_defined.left_margin = start_window.left + 1;
   1036	oi->ivtvfb_defined.upper_margin = start_window.top + 1;
   1037	oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
   1038	oi->ivtvfb_defined.nonstd = 0;
   1039
   1040	/* We've filled in the most data, let the usual mode check
   1041	   routine fill in the rest. */
   1042	_ivtvfb_check_var(&oi->ivtvfb_defined, itv);
   1043
   1044	/* Generate valid fb_fix_screeninfo */
   1045
   1046	ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
   1047
   1048	/* Generate valid fb_info */
   1049
   1050	oi->ivtvfb_info.node = -1;
   1051	oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
   1052	oi->ivtvfb_info.par = itv;
   1053	oi->ivtvfb_info.var = oi->ivtvfb_defined;
   1054	oi->ivtvfb_info.fix = oi->ivtvfb_fix;
   1055	oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
   1056	oi->ivtvfb_info.fbops = &ivtvfb_ops;
   1057
   1058	/* Supply some monitor specs. Bogus values will do for now */
   1059	oi->ivtvfb_info.monspecs.hfmin = 8000;
   1060	oi->ivtvfb_info.monspecs.hfmax = 70000;
   1061	oi->ivtvfb_info.monspecs.vfmin = 10;
   1062	oi->ivtvfb_info.monspecs.vfmax = 100;
   1063
   1064	/* Allocate color map */
   1065	if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
   1066		IVTVFB_ERR("abort, unable to alloc cmap\n");
   1067		return -ENOMEM;
   1068	}
   1069
   1070	/* Allocate the pseudo palette */
   1071	oi->ivtvfb_info.pseudo_palette =
   1072		kmalloc_array(16, sizeof(u32), GFP_KERNEL|__GFP_NOWARN);
   1073
   1074	if (!oi->ivtvfb_info.pseudo_palette) {
   1075		IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
   1076		return -ENOMEM;
   1077	}
   1078
   1079	return 0;
   1080}
   1081
   1082/* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
   1083
   1084static int ivtvfb_init_io(struct ivtv *itv)
   1085{
   1086	struct osd_info *oi = itv->osd_info;
   1087	/* Find the largest power of two that maps the whole buffer */
   1088	int size_shift = 31;
   1089
   1090	mutex_lock(&itv->serialize_lock);
   1091	if (ivtv_init_on_first_open(itv)) {
   1092		mutex_unlock(&itv->serialize_lock);
   1093		IVTVFB_ERR("Failed to initialize ivtv\n");
   1094		return -ENXIO;
   1095	}
   1096	mutex_unlock(&itv->serialize_lock);
   1097
   1098	if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
   1099					&oi->video_buffer_size) < 0) {
   1100		IVTVFB_ERR("Firmware failed to respond\n");
   1101		return -EIO;
   1102	}
   1103
   1104	/* The osd buffer size depends on the number of video buffers allocated
   1105	   on the PVR350 itself. For now we'll hardcode the smallest osd buffer
   1106	   size to prevent any overlap. */
   1107	oi->video_buffer_size = 1704960;
   1108
   1109	oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
   1110	oi->video_vbase = itv->dec_mem + oi->video_rbase;
   1111
   1112	if (!oi->video_vbase) {
   1113		IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
   1114		     oi->video_buffer_size, oi->video_pbase);
   1115		return -EIO;
   1116	}
   1117
   1118	IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
   1119			oi->video_pbase, oi->video_vbase,
   1120			oi->video_buffer_size / 1024);
   1121
   1122	while (!(oi->video_buffer_size & (1 << size_shift)))
   1123		size_shift--;
   1124	size_shift++;
   1125	oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
   1126	oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
   1127	oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
   1128	oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
   1129	oi->wc_cookie = arch_phys_wc_add(oi->fb_start_aligned_physaddr,
   1130					 oi->fb_end_aligned_physaddr -
   1131					 oi->fb_start_aligned_physaddr);
   1132	/* Blank the entire osd. */
   1133	memset_io(oi->video_vbase, 0, oi->video_buffer_size);
   1134
   1135	return 0;
   1136}
   1137
   1138/* Release any memory we've grabbed & remove mtrr entry */
   1139static void ivtvfb_release_buffers (struct ivtv *itv)
   1140{
   1141	struct osd_info *oi = itv->osd_info;
   1142
   1143	/* Release cmap */
   1144	if (oi->ivtvfb_info.cmap.len)
   1145		fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
   1146
   1147	/* Release pseudo palette */
   1148	kfree(oi->ivtvfb_info.pseudo_palette);
   1149	arch_phys_wc_del(oi->wc_cookie);
   1150	kfree(oi);
   1151	itv->osd_info = NULL;
   1152}
   1153
   1154/* Initialize the specified card */
   1155
   1156static int ivtvfb_init_card(struct ivtv *itv)
   1157{
   1158	int rc;
   1159
   1160#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
   1161	if (pat_enabled()) {
   1162		if (ivtvfb_force_pat) {
   1163			pr_info("PAT is enabled. Write-combined framebuffer caching will be disabled.\n");
   1164			pr_info("To enable caching, boot with nopat kernel parameter\n");
   1165		} else {
   1166			pr_warn("ivtvfb needs PAT disabled for write-combined framebuffer caching.\n");
   1167			pr_warn("Boot with nopat kernel parameter to use caching, or use the\n");
   1168			pr_warn("force_pat module parameter to run with caching disabled\n");
   1169			return -ENODEV;
   1170		}
   1171	}
   1172#endif
   1173
   1174	if (itv->osd_info) {
   1175		IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
   1176		return -EBUSY;
   1177	}
   1178
   1179	itv->osd_info = kzalloc(sizeof(struct osd_info),
   1180					GFP_KERNEL|__GFP_NOWARN);
   1181	if (itv->osd_info == NULL) {
   1182		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
   1183		return -ENOMEM;
   1184	}
   1185
   1186	/* Find & setup the OSD buffer */
   1187	rc = ivtvfb_init_io(itv);
   1188	if (rc) {
   1189		ivtvfb_release_buffers(itv);
   1190		return rc;
   1191	}
   1192
   1193	/* Set the startup video mode information */
   1194	if ((rc = ivtvfb_init_vidmode(itv))) {
   1195		ivtvfb_release_buffers(itv);
   1196		return rc;
   1197	}
   1198
   1199	/* Register the framebuffer */
   1200	if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
   1201		ivtvfb_release_buffers(itv);
   1202		return -EINVAL;
   1203	}
   1204
   1205	itv->osd_video_pbase = itv->osd_info->video_pbase;
   1206
   1207	/* Set the card to the requested mode */
   1208	ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
   1209
   1210	/* Set color 0 to black */
   1211	write_reg(0, 0x02a30);
   1212	write_reg(0, 0x02a34);
   1213
   1214	/* Enable the osd */
   1215	ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
   1216
   1217	/* Enable restart */
   1218	itv->ivtvfb_restore = ivtvfb_restore;
   1219
   1220	/* Allocate DMA */
   1221	ivtv_udma_alloc(itv);
   1222	itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps |=
   1223		V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
   1224	itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps |=
   1225		V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
   1226	itv->v4l2_cap |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
   1227	return 0;
   1228
   1229}
   1230
   1231static int __init ivtvfb_callback_init(struct device *dev, void *p)
   1232{
   1233	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
   1234	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
   1235
   1236	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
   1237		if (ivtvfb_init_card(itv) == 0) {
   1238			IVTVFB_INFO("Framebuffer registered on %s\n",
   1239					itv->v4l2_dev.name);
   1240			(*(int *)p)++;
   1241		}
   1242	}
   1243	return 0;
   1244}
   1245
   1246static int ivtvfb_callback_cleanup(struct device *dev, void *p)
   1247{
   1248	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
   1249	struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
   1250	struct osd_info *oi = itv->osd_info;
   1251
   1252	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
   1253		itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps &=
   1254			~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
   1255		itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &=
   1256			~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
   1257		itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
   1258		unregister_framebuffer(&itv->osd_info->ivtvfb_info);
   1259		IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
   1260		itv->ivtvfb_restore = NULL;
   1261		ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
   1262		ivtvfb_release_buffers(itv);
   1263		itv->osd_video_pbase = 0;
   1264	}
   1265	return 0;
   1266}
   1267
   1268static int __init ivtvfb_init(void)
   1269{
   1270	struct device_driver *drv;
   1271	int registered = 0;
   1272	int err;
   1273
   1274
   1275	if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
   1276		pr_err("ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
   1277		     IVTV_MAX_CARDS - 1);
   1278		return -EINVAL;
   1279	}
   1280
   1281	drv = driver_find("ivtv", &pci_bus_type);
   1282	err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
   1283	(void)err;	/* suppress compiler warning */
   1284	if (!registered) {
   1285		pr_err("no cards found\n");
   1286		return -ENODEV;
   1287	}
   1288	return 0;
   1289}
   1290
   1291static void ivtvfb_cleanup(void)
   1292{
   1293	struct device_driver *drv;
   1294	int err;
   1295
   1296	pr_info("Unloading framebuffer module\n");
   1297
   1298	drv = driver_find("ivtv", &pci_bus_type);
   1299	err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
   1300	(void)err;	/* suppress compiler warning */
   1301}
   1302
   1303module_init(ivtvfb_init);
   1304module_exit(ivtvfb_cleanup);