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