linux/drivers/media/pci/ivtv/ivtvfb.c
<<
>>
Prefs
   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 = 0;
  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);
1305