diff options
author | Raphael Assenat <raph@8d.com> | 2007-10-16 04:28:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:14 -0400 |
commit | ba282daa919f89c871780f344a71e5403a70b634 (patch) | |
tree | bbe7422999670f7c9fcc07b924963f9cd450840e | |
parent | eb78f9b3fa8532057d2a45acbe415b27ece6341b (diff) |
mbxfb: Improvements and new features
This contains the following changes:
* Overlay surface alpha is configured separately from the overlay. This
prevents display glitches (configure and fill the overlay first, set
alpha to a visible value next)
* Added an ioctl for configuring transparency of the Overlay and graphics
planes. Blend mode, colorkey mode and global alpha mode are supported.
* Added an ioctl for setting the plane order. The overlay plance can be placed
over or
under the graphics plane.
* Added an ioctl for setting and reading chip registers, with mask.
* Updated copyright for 2007
[adaplas]
* Coding style changes
Signed-off-by: Raphael Assenat <raph@8d.com>
Signed-off-by: Antonino Daplas <adaplas@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/video/mbx/mbxfb.c | 344 | ||||
-rw-r--r-- | drivers/video/mbx/reg_bits.h | 87 | ||||
-rw-r--r-- | drivers/video/mbx/regs.h | 2 | ||||
-rw-r--r-- | include/video/mbxfb.h | 53 |
4 files changed, 402 insertions, 84 deletions
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 980d5f623902..80cd117ca65c 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/video/mbx/mbxfb.c | 2 | * linux/drivers/video/mbx/mbxfb.c |
3 | * | 3 | * |
4 | * Copyright (C) 2006 8D Technologies inc | 4 | * Copyright (C) 2006-2007 8D Technologies inc |
5 | * Raphael Assenat <raph@8d.com> | 5 | * Raphael Assenat <raph@8d.com> |
6 | * - Added video overlay support | 6 | * - Added video overlay support |
7 | * - Various improvements | 7 | * - Various improvements |
@@ -334,8 +334,8 @@ static int mbxfb_blank(int blank, struct fb_info *info) | |||
334 | 334 | ||
335 | static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | 335 | static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) |
336 | { | 336 | { |
337 | u32 vsctrl, vbbase, vscadr, vsadr; | 337 | u32 vsctrl, vscadr, vsadr; |
338 | u32 sssize, spoctrl, svctrl, shctrl; | 338 | u32 sssize, spoctrl, shctrl; |
339 | u32 vubase, vvbase; | 339 | u32 vubase, vvbase; |
340 | u32 vovrclk; | 340 | u32 vovrclk; |
341 | 341 | ||
@@ -349,13 +349,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
349 | vscadr = readl(VSCADR); | 349 | vscadr = readl(VSCADR); |
350 | vubase = readl(VUBASE); | 350 | vubase = readl(VUBASE); |
351 | vvbase = readl(VVBASE); | 351 | vvbase = readl(VVBASE); |
352 | shctrl = readl(SHCTRL); | ||
352 | 353 | ||
353 | spoctrl = readl(SPOCTRL); | 354 | spoctrl = readl(SPOCTRL); |
354 | sssize = readl(SSSIZE); | 355 | sssize = readl(SSSIZE); |
355 | 356 | ||
356 | |||
357 | vbbase = Vbbase_Glalpha(set->alpha); | ||
358 | |||
359 | vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) | | 357 | vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) | |
360 | FMsk(VSCTRL_VSHEIGHT) | | 358 | FMsk(VSCTRL_VSHEIGHT) | |
361 | FMsk(VSCTRL_VPIXFMT) | | 359 | FMsk(VSCTRL_VPIXFMT) | |
@@ -364,38 +362,41 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
364 | vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) | | 362 | vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) | |
365 | VSCTRL_CSC_EN; | 363 | VSCTRL_CSC_EN; |
366 | 364 | ||
367 | vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC | | 365 | vscadr &= ~(VSCADR_STR_EN | FMsk(VSCADR_VBASE_ADR) ); |
368 | FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) | | ||
369 | FMsk(VSCADR_VBASE_ADR) ); | ||
370 | vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR)); | 366 | vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR)); |
371 | vvbase &= ~(FMsk(VVBASE_VBASE_ADR)); | 367 | vvbase &= ~(FMsk(VVBASE_VBASE_ADR)); |
372 | 368 | ||
373 | switch (set->fmt) | 369 | switch (set->fmt) { |
374 | { | 370 | case MBXFB_FMT_YUV16: |
375 | case MBXFB_FMT_YUV12: | 371 | vsctrl |= VSCTRL_VPIXFMT_YUV12; |
376 | vsctrl |= VSCTRL_VPIXFMT_YUV12; | ||
377 | 372 | ||
378 | set->Y_stride = ((set->width) + 0xf ) & ~0xf; | 373 | set->Y_stride = ((set->width) + 0xf ) & ~0xf; |
374 | break; | ||
375 | case MBXFB_FMT_YUV12: | ||
376 | vsctrl |= VSCTRL_VPIXFMT_YUV12; | ||
379 | 377 | ||
378 | set->Y_stride = ((set->width) + 0xf ) & ~0xf; | ||
379 | vubase |= VUBASE_UVHALFSTR; | ||
380 | |||
381 | break; | ||
382 | case MBXFB_FMT_UY0VY1: | ||
383 | vsctrl |= VSCTRL_VPIXFMT_UY0VY1; | ||
384 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
385 | break; | ||
386 | case MBXFB_FMT_VY0UY1: | ||
387 | vsctrl |= VSCTRL_VPIXFMT_VY0UY1; | ||
388 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
389 | break; | ||
390 | case MBXFB_FMT_Y0UY1V: | ||
391 | vsctrl |= VSCTRL_VPIXFMT_Y0UY1V; | ||
392 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
393 | break; | ||
394 | case MBXFB_FMT_Y0VY1U: | ||
395 | vsctrl |= VSCTRL_VPIXFMT_Y0VY1U; | ||
396 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
380 | break; | 397 | break; |
381 | case MBXFB_FMT_UY0VY1: | 398 | default: |
382 | vsctrl |= VSCTRL_VPIXFMT_UY0VY1; | 399 | return -EINVAL; |
383 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
384 | break; | ||
385 | case MBXFB_FMT_VY0UY1: | ||
386 | vsctrl |= VSCTRL_VPIXFMT_VY0UY1; | ||
387 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
388 | break; | ||
389 | case MBXFB_FMT_Y0UY1V: | ||
390 | vsctrl |= VSCTRL_VPIXFMT_Y0UY1V; | ||
391 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
392 | break; | ||
393 | case MBXFB_FMT_Y0VY1U: | ||
394 | vsctrl |= VSCTRL_VPIXFMT_Y0VY1U; | ||
395 | set->Y_stride = (set->width*2 + 0xf ) & ~0xf; | ||
396 | break; | ||
397 | default: | ||
398 | return -EINVAL; | ||
399 | } | 400 | } |
400 | 401 | ||
401 | /* VSCTRL has the bits which sets the Video Pixel Format. | 402 | /* VSCTRL has the bits which sets the Video Pixel Format. |
@@ -417,8 +418,7 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
417 | (0x60000 + set->mem_offset + set->V_offset)>>3); | 418 | (0x60000 + set->mem_offset + set->V_offset)>>3); |
418 | 419 | ||
419 | 420 | ||
420 | vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB | | 421 | vscadr |= Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4); |
421 | Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4); | ||
422 | 422 | ||
423 | if (set->enable) | 423 | if (set->enable) |
424 | vscadr |= VSCADR_STR_EN; | 424 | vscadr |= VSCADR_STR_EN; |
@@ -433,9 +433,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
433 | 433 | ||
434 | spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | | 434 | spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | |
435 | SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C | | 435 | SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C | |
436 | FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH)); | 436 | FMsk(SPOCTRL_VPITCH)); |
437 | spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height) | 437 | spoctrl |= Spoctrl_Vpitch((set->height<<11)/set->scaled_height); |
438 | | SPOCTRL_VORDER_2TAP; | ||
439 | 438 | ||
440 | /* Bypass horiz/vert scaler when same size */ | 439 | /* Bypass horiz/vert scaler when same size */ |
441 | if (set->scaled_width == set->width) | 440 | if (set->scaled_width == set->width) |
@@ -443,14 +442,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
443 | if (set->scaled_height == set->height) | 442 | if (set->scaled_height == set->height) |
444 | spoctrl |= SPOCTRL_V_SC_BP; | 443 | spoctrl |= SPOCTRL_V_SC_BP; |
445 | 444 | ||
446 | svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10); | 445 | shctrl &= ~(FMsk(SHCTRL_HPITCH) | SHCTRL_HDECIM); |
447 | 446 | shctrl |= Shctrl_Hpitch((set->width<<11)/set->scaled_width); | |
448 | shctrl = Shctrl_Hinitial(4<<11) | ||
449 | | Shctrl_Hpitch((set->width<<11)/set->scaled_width); | ||
450 | 447 | ||
451 | /* Video plane registers */ | 448 | /* Video plane registers */ |
452 | write_reg(vsctrl, VSCTRL); | 449 | write_reg(vsctrl, VSCTRL); |
453 | write_reg(vbbase, VBBASE); | ||
454 | write_reg(vscadr, VSCADR); | 450 | write_reg(vscadr, VSCADR); |
455 | write_reg(vubase, VUBASE); | 451 | write_reg(vubase, VUBASE); |
456 | write_reg(vvbase, VVBASE); | 452 | write_reg(vvbase, VVBASE); |
@@ -459,28 +455,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
459 | /* Video scaler registers */ | 455 | /* Video scaler registers */ |
460 | write_reg(sssize, SSSIZE); | 456 | write_reg(sssize, SSSIZE); |
461 | write_reg(spoctrl, SPOCTRL); | 457 | write_reg(spoctrl, SPOCTRL); |
462 | write_reg(svctrl, SVCTRL); | ||
463 | write_reg(shctrl, SHCTRL); | 458 | write_reg(shctrl, SHCTRL); |
464 | 459 | ||
465 | /* RAPH: Using those coefficients, the scaled | ||
466 | * image is quite blurry. I dont know how | ||
467 | * to improve them ; The chip documentation | ||
468 | * was not helpful.. */ | ||
469 | write_reg(0x21212121, VSCOEFF0); | ||
470 | write_reg(0x21212121, VSCOEFF1); | ||
471 | write_reg(0x21212121, VSCOEFF2); | ||
472 | write_reg(0x21212121, VSCOEFF3); | ||
473 | write_reg(0x21212121, VSCOEFF4); | ||
474 | write_reg(0x00000000, HSCOEFF0); | ||
475 | write_reg(0x00000000, HSCOEFF1); | ||
476 | write_reg(0x00000000, HSCOEFF2); | ||
477 | write_reg(0x03020201, HSCOEFF3); | ||
478 | write_reg(0x09070604, HSCOEFF4); | ||
479 | write_reg(0x0f0e0c0a, HSCOEFF5); | ||
480 | write_reg(0x15141211, HSCOEFF6); | ||
481 | write_reg(0x19181716, HSCOEFF7); | ||
482 | write_reg(0x00000019, HSCOEFF8); | ||
483 | |||
484 | /* Clock */ | 460 | /* Clock */ |
485 | if (set->enable) | 461 | if (set->enable) |
486 | vovrclk |= 1; | 462 | vovrclk |= 1; |
@@ -492,27 +468,206 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) | |||
492 | return 0; | 468 | return 0; |
493 | } | 469 | } |
494 | 470 | ||
471 | static int mbxfb_ioctl_planeorder(struct mbxfb_planeorder *porder) | ||
472 | { | ||
473 | unsigned long gscadr, vscadr; | ||
474 | |||
475 | if (porder->bottom == porder->top) | ||
476 | return -EINVAL; | ||
477 | |||
478 | gscadr = readl(GSCADR); | ||
479 | vscadr = readl(VSCADR); | ||
480 | |||
481 | gscadr &= ~(FMsk(GSCADR_BLEND_POS)); | ||
482 | vscadr &= ~(FMsk(VSCADR_BLEND_POS)); | ||
483 | |||
484 | switch (porder->bottom) { | ||
485 | case MBXFB_PLANE_GRAPHICS: | ||
486 | gscadr |= GSCADR_BLEND_GFX; | ||
487 | break; | ||
488 | case MBXFB_PLANE_VIDEO: | ||
489 | vscadr |= VSCADR_BLEND_GFX; | ||
490 | break; | ||
491 | default: | ||
492 | return -EINVAL; | ||
493 | } | ||
494 | |||
495 | switch (porder->top) { | ||
496 | case MBXFB_PLANE_GRAPHICS: | ||
497 | gscadr |= GSCADR_BLEND_VID; | ||
498 | break; | ||
499 | case MBXFB_PLANE_VIDEO: | ||
500 | vscadr |= GSCADR_BLEND_VID; | ||
501 | break; | ||
502 | default: | ||
503 | return -EINVAL; | ||
504 | } | ||
505 | |||
506 | write_reg_dly(vscadr, VSCADR); | ||
507 | write_reg_dly(gscadr, GSCADR); | ||
508 | |||
509 | return 0; | ||
510 | |||
511 | } | ||
512 | |||
513 | static int mbxfb_ioctl_alphactl(struct mbxfb_alphaCtl *alpha) | ||
514 | { | ||
515 | unsigned long vscadr, vbbase, vcmsk; | ||
516 | unsigned long gscadr, gbbase, gdrctrl; | ||
517 | |||
518 | vbbase = Vbbase_Glalpha(alpha->overlay_global_alpha) | | ||
519 | Vbbase_Colkey(alpha->overlay_colorkey); | ||
520 | |||
521 | gbbase = Gbbase_Glalpha(alpha->graphics_global_alpha) | | ||
522 | Gbbase_Colkey(alpha->graphics_colorkey); | ||
523 | |||
524 | vcmsk = readl(VCMSK); | ||
525 | vcmsk &= ~(FMsk(VCMSK_COLKEY_M)); | ||
526 | vcmsk |= Vcmsk_colkey_m(alpha->overlay_colorkey_mask); | ||
527 | |||
528 | gdrctrl = readl(GDRCTRL); | ||
529 | gdrctrl &= ~(FMsk(GDRCTRL_COLKEYM)); | ||
530 | gdrctrl |= Gdrctrl_Colkeym(alpha->graphics_colorkey_mask); | ||
531 | |||
532 | vscadr = readl(VSCADR); | ||
533 | vscadr &= ~(FMsk(VSCADR_BLEND_M) | VSCADR_COLKEYSRC | VSCADR_COLKEY_EN); | ||
534 | |||
535 | gscadr = readl(GSCADR); | ||
536 | gscadr &= ~(FMsk(GSCADR_BLEND_M) | GSCADR_COLKEY_EN | GSCADR_COLKEYSRC); | ||
537 | |||
538 | switch (alpha->overlay_colorkey_mode) { | ||
539 | case MBXFB_COLORKEY_DISABLED: | ||
540 | break; | ||
541 | case MBXFB_COLORKEY_PREVIOUS: | ||
542 | vscadr |= VSCADR_COLKEY_EN; | ||
543 | break; | ||
544 | case MBXFB_COLORKEY_CURRENT: | ||
545 | vscadr |= VSCADR_COLKEY_EN | VSCADR_COLKEYSRC; | ||
546 | break; | ||
547 | default: | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | |||
551 | switch (alpha->overlay_blend_mode) { | ||
552 | case MBXFB_ALPHABLEND_NONE: | ||
553 | vscadr |= VSCADR_BLEND_NONE; | ||
554 | break; | ||
555 | case MBXFB_ALPHABLEND_GLOBAL: | ||
556 | vscadr |= VSCADR_BLEND_GLOB; | ||
557 | break; | ||
558 | case MBXFB_ALPHABLEND_PIXEL: | ||
559 | vscadr |= VSCADR_BLEND_PIX; | ||
560 | break; | ||
561 | default: | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | switch (alpha->graphics_colorkey_mode) { | ||
566 | case MBXFB_COLORKEY_DISABLED: | ||
567 | break; | ||
568 | case MBXFB_COLORKEY_PREVIOUS: | ||
569 | gscadr |= GSCADR_COLKEY_EN; | ||
570 | break; | ||
571 | case MBXFB_COLORKEY_CURRENT: | ||
572 | gscadr |= GSCADR_COLKEY_EN | GSCADR_COLKEYSRC; | ||
573 | break; | ||
574 | default: | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | |||
578 | switch (alpha->graphics_blend_mode) { | ||
579 | case MBXFB_ALPHABLEND_NONE: | ||
580 | gscadr |= GSCADR_BLEND_NONE; | ||
581 | break; | ||
582 | case MBXFB_ALPHABLEND_GLOBAL: | ||
583 | gscadr |= GSCADR_BLEND_GLOB; | ||
584 | break; | ||
585 | case MBXFB_ALPHABLEND_PIXEL: | ||
586 | gscadr |= GSCADR_BLEND_PIX; | ||
587 | break; | ||
588 | default: | ||
589 | return -EINVAL; | ||
590 | } | ||
591 | |||
592 | write_reg_dly(vbbase, VBBASE); | ||
593 | write_reg_dly(gbbase, GBBASE); | ||
594 | write_reg_dly(vcmsk, VCMSK); | ||
595 | write_reg_dly(gdrctrl, GDRCTRL); | ||
596 | write_reg_dly(gscadr, GSCADR); | ||
597 | write_reg_dly(vscadr, VSCADR); | ||
598 | |||
599 | return 0; | ||
600 | } | ||
601 | |||
495 | static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd, | 602 | static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd, |
496 | unsigned long arg) | 603 | unsigned long arg) |
497 | { | 604 | { |
498 | struct mbxfb_overlaySetup setup; | 605 | struct mbxfb_overlaySetup setup; |
606 | struct mbxfb_planeorder porder; | ||
607 | struct mbxfb_alphaCtl alpha; | ||
608 | struct mbxfb_reg reg; | ||
499 | int res; | 609 | int res; |
610 | __u32 tmp; | ||
500 | 611 | ||
501 | if (cmd == MBXFB_IOCX_OVERLAY) | 612 | switch (cmd) |
502 | { | 613 | { |
503 | if (copy_from_user(&setup, (void __user*)arg, | 614 | case MBXFB_IOCX_OVERLAY: |
504 | sizeof(struct mbxfb_overlaySetup))) | 615 | if (copy_from_user(&setup, (void __user*)arg, |
616 | sizeof(struct mbxfb_overlaySetup))) | ||
617 | return -EFAULT; | ||
618 | |||
619 | res = mbxfb_setupOverlay(&setup); | ||
620 | if (res) | ||
621 | return res; | ||
622 | |||
623 | if (copy_to_user((void __user*)arg, &setup, | ||
624 | sizeof(struct mbxfb_overlaySetup))) | ||
625 | return -EFAULT; | ||
626 | |||
627 | return 0; | ||
628 | |||
629 | case MBXFB_IOCS_PLANEORDER: | ||
630 | if (copy_from_user(&porder, (void __user*)arg, | ||
631 | sizeof(struct mbxfb_planeorder))) | ||
505 | return -EFAULT; | 632 | return -EFAULT; |
506 | 633 | ||
507 | res = mbxfb_setupOverlay(&setup); | 634 | return mbxfb_ioctl_planeorder(&porder); |
508 | if (res) | ||
509 | return res; | ||
510 | 635 | ||
511 | if (copy_to_user((void __user*)arg, &setup, | 636 | case MBXFB_IOCS_ALPHA: |
512 | sizeof(struct mbxfb_overlaySetup))) | 637 | if (copy_from_user(&alpha, (void __user*)arg, |
638 | sizeof(struct mbxfb_alphaCtl))) | ||
513 | return -EFAULT; | 639 | return -EFAULT; |
514 | 640 | ||
515 | return 0; | 641 | return mbxfb_ioctl_alphactl(&alpha); |
642 | |||
643 | case MBXFB_IOCS_REG: | ||
644 | if (copy_from_user(®, (void __user*)arg, | ||
645 | sizeof(struct mbxfb_reg))) | ||
646 | return -EFAULT; | ||
647 | |||
648 | if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */ | ||
649 | return -EINVAL; | ||
650 | |||
651 | tmp = readl(virt_base_2700 + reg.addr); | ||
652 | tmp &= ~reg.mask; | ||
653 | tmp |= reg.val & reg.mask; | ||
654 | writel(tmp, virt_base_2700 + reg.addr); | ||
655 | |||
656 | return 0; | ||
657 | case MBXFB_IOCX_REG: | ||
658 | if (copy_from_user(®, (void __user*)arg, | ||
659 | sizeof(struct mbxfb_reg))) | ||
660 | return -EFAULT; | ||
661 | |||
662 | if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */ | ||
663 | return -EINVAL; | ||
664 | reg.val = readl(virt_base_2700 + reg.addr); | ||
665 | |||
666 | if (copy_to_user((void __user*)arg, ®, | ||
667 | sizeof(struct mbxfb_reg))) | ||
668 | return -EFAULT; | ||
669 | |||
670 | return 0; | ||
516 | } | 671 | } |
517 | return -EINVAL; | 672 | return -EINVAL; |
518 | } | 673 | } |
@@ -558,7 +713,6 @@ static void __devinit setup_memc(struct fb_info *fbi) | |||
558 | LMTYPE); | 713 | LMTYPE); |
559 | /* enable memory controller */ | 714 | /* enable memory controller */ |
560 | write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); | 715 | write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); |
561 | |||
562 | /* perform dummy reads */ | 716 | /* perform dummy reads */ |
563 | for ( i = 0; i < 16; i++ ) { | 717 | for ( i = 0; i < 16; i++ ) { |
564 | tmp = readl(fbi->screen_base); | 718 | tmp = readl(fbi->screen_base); |
@@ -588,8 +742,8 @@ static void enable_clocks(struct fb_info *fbi) | |||
588 | write_reg_dly(0x00000000, VOVRCLK); | 742 | write_reg_dly(0x00000000, VOVRCLK); |
589 | write_reg_dly(PIXCLK_EN, PIXCLK); | 743 | write_reg_dly(PIXCLK_EN, PIXCLK); |
590 | write_reg_dly(MEMCLK_EN, MEMCLK); | 744 | write_reg_dly(MEMCLK_EN, MEMCLK); |
591 | write_reg_dly(0x00000006, M24CLK); | 745 | write_reg_dly(0x00000001, M24CLK); |
592 | write_reg_dly(0x00000006, MBXCLK); | 746 | write_reg_dly(0x00000001, MBXCLK); |
593 | write_reg_dly(SDCLK_EN, SDCLK); | 747 | write_reg_dly(SDCLK_EN, SDCLK); |
594 | write_reg_dly(0x00000001, PIXCLKDIV); | 748 | write_reg_dly(0x00000001, PIXCLKDIV); |
595 | } | 749 | } |
@@ -597,6 +751,7 @@ static void enable_clocks(struct fb_info *fbi) | |||
597 | static void __devinit setup_graphics(struct fb_info *fbi) | 751 | static void __devinit setup_graphics(struct fb_info *fbi) |
598 | { | 752 | { |
599 | unsigned long gsctrl; | 753 | unsigned long gsctrl; |
754 | unsigned long vscadr; | ||
600 | 755 | ||
601 | gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) | | 756 | gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) | |
602 | Gsctrl_Height(fbi->var.yres); | 757 | Gsctrl_Height(fbi->var.yres); |
@@ -620,6 +775,11 @@ static void __devinit setup_graphics(struct fb_info *fbi) | |||
620 | write_reg_dly(0x00ffffff, GDRCTRL); | 775 | write_reg_dly(0x00ffffff, GDRCTRL); |
621 | write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR); | 776 | write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR); |
622 | write_reg_dly(0x00000000, GPLUT); | 777 | write_reg_dly(0x00000000, GPLUT); |
778 | |||
779 | vscadr = readl(VSCADR); | ||
780 | vscadr &= ~(FMsk(VSCADR_BLEND_POS) | FMsk(VSCADR_BLEND_M)); | ||
781 | vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_NONE; | ||
782 | write_reg_dly(vscadr, VSCADR); | ||
623 | } | 783 | } |
624 | 784 | ||
625 | static void __devinit setup_display(struct fb_info *fbi) | 785 | static void __devinit setup_display(struct fb_info *fbi) |
@@ -638,13 +798,47 @@ static void __devinit setup_display(struct fb_info *fbi) | |||
638 | 798 | ||
639 | static void __devinit enable_controller(struct fb_info *fbi) | 799 | static void __devinit enable_controller(struct fb_info *fbi) |
640 | { | 800 | { |
801 | u32 svctrl, shctrl; | ||
802 | |||
641 | write_reg_dly(SYSRST_RST, SYSRST); | 803 | write_reg_dly(SYSRST_RST, SYSRST); |
642 | 804 | ||
805 | /* setup a timeout, raise drive strength */ | ||
806 | write_reg_dly(0xffffff0c, SYSCFG); | ||
643 | 807 | ||
644 | enable_clocks(fbi); | 808 | enable_clocks(fbi); |
645 | setup_memc(fbi); | 809 | setup_memc(fbi); |
646 | setup_graphics(fbi); | 810 | setup_graphics(fbi); |
647 | setup_display(fbi); | 811 | setup_display(fbi); |
812 | |||
813 | shctrl = readl(SHCTRL); | ||
814 | shctrl &= ~(FMsk(SHCTRL_HINITIAL)); | ||
815 | shctrl |= Shctrl_Hinitial(4<<11); | ||
816 | writel(shctrl, SHCTRL); | ||
817 | |||
818 | svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10); | ||
819 | writel(svctrl, SVCTRL); | ||
820 | |||
821 | writel(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | SPOCTRL_VORDER_4TAP | ||
822 | , SPOCTRL); | ||
823 | |||
824 | /* Those coefficients are good for scaling up. For scaling | ||
825 | * down, the application has to calculate them. */ | ||
826 | write_reg(0xff000100, VSCOEFF0); | ||
827 | write_reg(0xfdfcfdfe, VSCOEFF1); | ||
828 | write_reg(0x170d0500, VSCOEFF2); | ||
829 | write_reg(0x3d372d22, VSCOEFF3); | ||
830 | write_reg(0x00000040, VSCOEFF4); | ||
831 | |||
832 | write_reg(0xff010100, HSCOEFF0); | ||
833 | write_reg(0x00000000, HSCOEFF1); | ||
834 | write_reg(0x02010000, HSCOEFF2); | ||
835 | write_reg(0x01020302, HSCOEFF3); | ||
836 | write_reg(0xf9fbfe00, HSCOEFF4); | ||
837 | write_reg(0xfbf7f6f7, HSCOEFF5); | ||
838 | write_reg(0x1c110700, HSCOEFF6); | ||
839 | write_reg(0x3e393127, HSCOEFF7); | ||
840 | write_reg(0x00000040, HSCOEFF8); | ||
841 | |||
648 | } | 842 | } |
649 | 843 | ||
650 | #ifdef CONFIG_PM | 844 | #ifdef CONFIG_PM |
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h index 9a24fb0c7d48..5f14b4befd71 100644 --- a/drivers/video/mbx/reg_bits.h +++ b/drivers/video/mbx/reg_bits.h | |||
@@ -215,7 +215,7 @@ | |||
215 | /* GSCADR graphics stream control address register fields */ | 215 | /* GSCADR graphics stream control address register fields */ |
216 | #define GSCADR_STR_EN (1 << 31) | 216 | #define GSCADR_STR_EN (1 << 31) |
217 | #define GSCADR_COLKEY_EN (1 << 30) | 217 | #define GSCADR_COLKEY_EN (1 << 30) |
218 | #define GSCADR_COLKEYSCR (1 << 29) | 218 | #define GSCADR_COLKEYSRC (1 << 29) |
219 | #define GSCADR_BLEND_M Fld(2,27) | 219 | #define GSCADR_BLEND_M Fld(2,27) |
220 | #define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M)) | 220 | #define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M)) |
221 | #define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M)) | 221 | #define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M)) |
@@ -303,6 +303,67 @@ | |||
303 | #define VSADR_YSTART Fld(11,0) | 303 | #define VSADR_YSTART Fld(11,0) |
304 | #define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART)) | 304 | #define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART)) |
305 | 305 | ||
306 | /* VSCTRL - Video Surface Control Register */ | ||
307 | #define VSCTRL_VPIXFMT Fld(4,27) | ||
308 | #define VSCTRL_VPIXFMT_YUV12 ((0x9) << FShft(VSCTRL_VPIXFMT)) | ||
309 | #define VSCTRL_VPIXFMT_UY0VY1 ((0xc) << FShft(VSCTRL_VPIXFMT)) | ||
310 | #define VSCTRL_VPIXFMT_VY0UY1 ((0xd) << FShft(VSCTRL_VPIXFMT)) | ||
311 | #define VSCTRL_VPIXFMT_Y0UY1V ((0xe) << FShft(VSCTRL_VPIXFMT)) | ||
312 | #define VSCTRL_VPIXFMT_Y0VY1U ((0xf) << FShft(VSCTRL_VPIXFMT)) | ||
313 | #define VSCTRL_GAMMA_EN (1 << 26) | ||
314 | #define VSCTRL_CSC_EN (1 << 25) | ||
315 | #define VSCTRL_COSITED (1 << 22) | ||
316 | #define VSCTRL_VSWIDTH Fld(11,11) | ||
317 | #define Vsctrl_Width(Pixels) /* Video Width [1-2048] */ \ | ||
318 | (((Pixels) - 1) << FShft(VSCTRL_VSWIDTH)) | ||
319 | #define VSCTRL_VSHEIGHT Fld(11,0) | ||
320 | #define Vsctrl_Height(Pixels) /* Video Height [1-2048] */ \ | ||
321 | (((Pixels) - 1) << FShft(VSCTRL_VSHEIGHT)) | ||
322 | |||
323 | /* VBBASE - Video Blending Base Register */ | ||
324 | #define VBBASE_GLALPHA Fld(8,24) | ||
325 | #define Vbbase_Glalpha(x) ((x) << FShft(VBBASE_GLALPHA)) | ||
326 | |||
327 | #define VBBASE_COLKEY Fld(24,0) | ||
328 | #define Vbbase_Colkey(x) ((x) << FShft(VBBASE_COLKEY)) | ||
329 | |||
330 | /* VCMSK - Video Color Key Mask Register */ | ||
331 | #define VCMSK_COLKEY_M Fld(24,0) | ||
332 | #define Vcmsk_colkey_m(x) ((x) << FShft(VCMSK_COLKEY_M)) | ||
333 | |||
334 | /* VSCADR - Video Stream Control Rddress Register */ | ||
335 | #define VSCADR_STR_EN (1 << 31) | ||
336 | #define VSCADR_COLKEY_EN (1 << 30) | ||
337 | #define VSCADR_COLKEYSRC (1 << 29) | ||
338 | #define VSCADR_BLEND_M Fld(2,27) | ||
339 | #define VSCADR_BLEND_NONE ((0x0) << FShft(VSCADR_BLEND_M)) | ||
340 | #define VSCADR_BLEND_INV ((0x1) << FShft(VSCADR_BLEND_M)) | ||
341 | #define VSCADR_BLEND_GLOB ((0x2) << FShft(VSCADR_BLEND_M)) | ||
342 | #define VSCADR_BLEND_PIX ((0x3) << FShft(VSCADR_BLEND_M)) | ||
343 | #define VSCADR_BLEND_POS Fld(2,24) | ||
344 | #define VSCADR_BLEND_GFX ((0x0) << FShft(VSCADR_BLEND_POS)) | ||
345 | #define VSCADR_BLEND_VID ((0x1) << FShft(VSCADR_BLEND_POS)) | ||
346 | #define VSCADR_BLEND_CUR ((0x2) << FShft(VSCADR_BLEND_POS)) | ||
347 | #define VSCADR_VBASE_ADR Fld(23,0) | ||
348 | #define Vscadr_Vbase_Adr(x) ((x) << FShft(VSCADR_VBASE_ADR)) | ||
349 | |||
350 | /* VUBASE - Video U Base Register */ | ||
351 | #define VUBASE_UVHALFSTR (1 << 31) | ||
352 | #define VUBASE_UBASE_ADR Fld(24,0) | ||
353 | #define Vubase_Ubase_Adr(x) ((x) << FShft(VUBASE_UBASE_ADR)) | ||
354 | |||
355 | /* VVBASE - Video V Base Register */ | ||
356 | #define VVBASE_VBASE_ADR Fld(24,0) | ||
357 | #define Vvbase_Vbase_Adr(x) ((x) << FShft(VVBASE_VBASE_ADR)) | ||
358 | |||
359 | /* VSADR - Video Stride Address Register */ | ||
360 | #define VSADR_SRCSTRIDE Fld(10,22) | ||
361 | #define Vsadr_Srcstride(x) ((x) << FShft(VSADR_SRCSTRIDE)) | ||
362 | #define VSADR_XSTART Fld(11,11) | ||
363 | #define Vsadr_Xstart(x) ((x) << FShft(VSADR_XSTART)) | ||
364 | #define VSADR_YSTART Fld(11,0) | ||
365 | #define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART)) | ||
366 | |||
306 | /* HCCTRL - Hardware Cursor Register fields */ | 367 | /* HCCTRL - Hardware Cursor Register fields */ |
307 | #define HCCTRL_CUR_EN (1 << 31) | 368 | #define HCCTRL_CUR_EN (1 << 31) |
308 | #define HCCTRL_COLKEY_EN (1 << 29) | 369 | #define HCCTRL_COLKEY_EN (1 << 29) |
@@ -479,6 +540,30 @@ | |||
479 | #define DINTRE_HBLNK1_EN (1 << 1) | 540 | #define DINTRE_HBLNK1_EN (1 << 1) |
480 | #define DINTRE_HBLNK0_EN (1 << 0) | 541 | #define DINTRE_HBLNK0_EN (1 << 0) |
481 | 542 | ||
543 | /* DINTRS - Display Interrupt Status Register */ | ||
544 | #define DINTRS_CUR_OR_S (1 << 18) | ||
545 | #define DINTRS_STR2_OR_S (1 << 17) | ||
546 | #define DINTRS_STR1_OR_S (1 << 16) | ||
547 | #define DINTRS_CUR_UR_S (1 << 6) | ||
548 | #define DINTRS_STR2_UR_S (1 << 5) | ||
549 | #define DINTRS_STR1_UR_S (1 << 4) | ||
550 | #define DINTRS_VEVENT1_S (1 << 3) | ||
551 | #define DINTRS_VEVENT0_S (1 << 2) | ||
552 | #define DINTRS_HBLNK1_S (1 << 1) | ||
553 | #define DINTRS_HBLNK0_S (1 << 0) | ||
554 | |||
555 | /* DINTRE - Display Interrupt Enable Register */ | ||
556 | #define DINTRE_CUR_OR_EN (1 << 18) | ||
557 | #define DINTRE_STR2_OR_EN (1 << 17) | ||
558 | #define DINTRE_STR1_OR_EN (1 << 16) | ||
559 | #define DINTRE_CUR_UR_EN (1 << 6) | ||
560 | #define DINTRE_STR2_UR_EN (1 << 5) | ||
561 | #define DINTRE_STR1_UR_EN (1 << 4) | ||
562 | #define DINTRE_VEVENT1_EN (1 << 3) | ||
563 | #define DINTRE_VEVENT0_EN (1 << 2) | ||
564 | #define DINTRE_HBLNK1_EN (1 << 1) | ||
565 | #define DINTRE_HBLNK0_EN (1 << 0) | ||
566 | |||
482 | 567 | ||
483 | /* DLSTS - display load status register */ | 568 | /* DLSTS - display load status register */ |
484 | #define DLSTS_RLD_ADONE (1 << 23) | 569 | #define DLSTS_RLD_ADONE (1 << 23) |
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h index a7c63d865aad..063099d48839 100644 --- a/drivers/video/mbx/regs.h +++ b/drivers/video/mbx/regs.h | |||
@@ -30,7 +30,7 @@ | |||
30 | #define VOVRCLK __REG_2700G(0x00000044) | 30 | #define VOVRCLK __REG_2700G(0x00000044) |
31 | #define PIXCLK __REG_2700G(0x00000048) | 31 | #define PIXCLK __REG_2700G(0x00000048) |
32 | #define MEMCLK __REG_2700G(0x0000004c) | 32 | #define MEMCLK __REG_2700G(0x0000004c) |
33 | #define M24CLK __REG_2700G(0x00000054) | 33 | #define M24CLK __REG_2700G(0x00000050) |
34 | #define MBXCLK __REG_2700G(0x00000054) | 34 | #define MBXCLK __REG_2700G(0x00000054) |
35 | #define SDCLK __REG_2700G(0x00000058) | 35 | #define SDCLK __REG_2700G(0x00000058) |
36 | #define PIXCLKDIV __REG_2700G(0x0000005c) | 36 | #define PIXCLKDIV __REG_2700G(0x0000005c) |
diff --git a/include/video/mbxfb.h b/include/video/mbxfb.h index 20b9002712ef..ea18961fc5e7 100644 --- a/include/video/mbxfb.h +++ b/include/video/mbxfb.h | |||
@@ -29,18 +29,18 @@ struct mbxfb_platform_data { | |||
29 | }; | 29 | }; |
30 | 30 | ||
31 | /* planar */ | 31 | /* planar */ |
32 | #define MBXFB_FMT_YUV12 0 | 32 | #define MBXFB_FMT_YUV16 0 |
33 | #define MBXFB_FMT_YUV12 1 | ||
33 | 34 | ||
34 | /* packed */ | 35 | /* packed */ |
35 | #define MBXFB_FMT_UY0VY1 1 | 36 | #define MBXFB_FMT_UY0VY1 2 |
36 | #define MBXFB_FMT_VY0UY1 2 | 37 | #define MBXFB_FMT_VY0UY1 3 |
37 | #define MBXFB_FMT_Y0UY1V 3 | 38 | #define MBXFB_FMT_Y0UY1V 4 |
38 | #define MBXFB_FMT_Y0VY1U 4 | 39 | #define MBXFB_FMT_Y0VY1U 5 |
39 | struct mbxfb_overlaySetup { | 40 | struct mbxfb_overlaySetup { |
40 | __u32 enable; | 41 | __u32 enable; |
41 | __u32 x, y; | 42 | __u32 x, y; |
42 | __u32 width, height; | 43 | __u32 width, height; |
43 | __u32 alpha; | ||
44 | __u32 fmt; | 44 | __u32 fmt; |
45 | __u32 mem_offset; | 45 | __u32 mem_offset; |
46 | __u32 scaled_width; | 46 | __u32 scaled_width; |
@@ -54,6 +54,45 @@ struct mbxfb_overlaySetup { | |||
54 | __u16 UV_stride; | 54 | __u16 UV_stride; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | #define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup) | 57 | #define MBXFB_ALPHABLEND_NONE 0 |
58 | #define MBXFB_ALPHABLEND_GLOBAL 1 | ||
59 | #define MBXFB_ALPHABLEND_PIXEL 2 | ||
60 | |||
61 | #define MBXFB_COLORKEY_DISABLED 0 | ||
62 | #define MBXFB_COLORKEY_PREVIOUS 1 | ||
63 | #define MBXFB_COLORKEY_CURRENT 2 | ||
64 | struct mbxfb_alphaCtl { | ||
65 | __u8 overlay_blend_mode; | ||
66 | __u8 overlay_colorkey_mode; | ||
67 | __u8 overlay_global_alpha; | ||
68 | __u32 overlay_colorkey; | ||
69 | __u32 overlay_colorkey_mask; | ||
70 | |||
71 | __u8 graphics_blend_mode; | ||
72 | __u8 graphics_colorkey_mode; | ||
73 | __u8 graphics_global_alpha; | ||
74 | __u32 graphics_colorkey; | ||
75 | __u32 graphics_colorkey_mask; | ||
76 | }; | ||
77 | |||
78 | #define MBXFB_PLANE_GRAPHICS 0 | ||
79 | #define MBXFB_PLANE_VIDEO 1 | ||
80 | struct mbxfb_planeorder { | ||
81 | __u8 bottom; | ||
82 | __u8 top; | ||
83 | }; | ||
84 | |||
85 | struct mbxfb_reg { | ||
86 | __u32 addr; /* offset from 0x03fe 0000 */ | ||
87 | __u32 val; /* value */ | ||
88 | __u32 mask; /* which bits to touch (for write) */ | ||
89 | }; | ||
90 | |||
91 | #define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup) | ||
92 | #define MBXFB_IOCG_ALPHA _IOR(0xF4, 0x01,struct mbxfb_alphaCtl) | ||
93 | #define MBXFB_IOCS_ALPHA _IOW(0xF4, 0x02,struct mbxfb_alphaCtl) | ||
94 | #define MBXFB_IOCS_PLANEORDER _IOR(0xF4, 0x03,struct mbxfb_planeorder) | ||
95 | #define MBXFB_IOCS_REG _IOW(0xF4, 0x04,struct mbxfb_reg) | ||
96 | #define MBXFB_IOCX_REG _IOWR(0xF4, 0x05,struct mbxfb_reg) | ||
58 | 97 | ||
59 | #endif /* __MBX_FB_H */ | 98 | #endif /* __MBX_FB_H */ |