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