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 /drivers/video/mbx/mbxfb.c | |
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>
Diffstat (limited to 'drivers/video/mbx/mbxfb.c')
-rw-r--r-- | drivers/video/mbx/mbxfb.c | 344 |
1 files changed, 269 insertions, 75 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 |