diff options
Diffstat (limited to 'drivers/ps3/ps3av.c')
-rw-r--r-- | drivers/ps3/ps3av.c | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 21f69a75be67..fbf8dcde9675 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c | |||
@@ -585,54 +585,73 @@ static void ps3avd(struct work_struct *work) | |||
585 | complete(&ps3av->done); | 585 | complete(&ps3av->done); |
586 | } | 586 | } |
587 | 587 | ||
588 | static int ps3av_resbit2id(u32 res_50, u32 res_60) | 588 | #define SHIFT_50 0 |
589 | #define SHIFT_60 4 | ||
590 | #define SHIFT_VESA 8 | ||
591 | |||
592 | static const struct { | ||
593 | unsigned mask : 19; | ||
594 | unsigned id : 4; | ||
595 | } ps3av_preferred_modes[] = { | ||
596 | { .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 }, | ||
597 | { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 }, | ||
598 | { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 }, | ||
599 | { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 }, | ||
600 | { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 }, | ||
601 | { .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 }, | ||
602 | { .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 }, | ||
603 | { .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 }, | ||
604 | { .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 }, | ||
605 | { .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 }, | ||
606 | { .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 }, | ||
607 | }; | ||
608 | |||
609 | static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa) | ||
589 | { | 610 | { |
590 | int id = 0; | 611 | unsigned int i; |
591 | 612 | u32 res_all; | |
592 | if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */ | 613 | |
593 | if (res_50 & PS3AV_RESBIT_1920x1080P) | 614 | /* |
594 | id = 10; | 615 | * We mask off the resolution bits we care about and combine the |
595 | else if (res_50 & PS3AV_RESBIT_1920x1080I) | 616 | * results in one bitfield, so make sure there's no overlap |
596 | id = 9; | 617 | */ |
597 | else if (res_50 & PS3AV_RESBIT_1280x720P) | 618 | BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 & |
598 | id = 8; | 619 | PS3AV_RES_MASK_60 << SHIFT_60); |
599 | else if (res_50 & PS3AV_RESBIT_720x576P) | 620 | BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 & |
600 | id = 7; | 621 | PS3AV_RES_MASK_VESA << SHIFT_VESA); |
601 | else | 622 | BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 & |
602 | id = 0; | 623 | PS3AV_RES_MASK_VESA << SHIFT_VESA); |
603 | } else { | 624 | res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 | |
604 | if (res_60 & PS3AV_RESBIT_1920x1080P) | 625 | (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 | |
605 | id = 5; | 626 | (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA; |
606 | else if (res_60 & PS3AV_RESBIT_1920x1080I) | 627 | |
607 | id = 4; | 628 | if (!res_all) |
608 | else if (res_60 & PS3AV_RESBIT_1280x720P) | 629 | return 0; |
609 | id = 3; | 630 | |
610 | else if (res_60 & PS3AV_RESBIT_720x480P) | 631 | for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++) |
611 | id = 2; | 632 | if (res_all & ps3av_preferred_modes[i].mask) |
612 | else | 633 | return ps3av_preferred_modes[i].id; |
613 | id = 0; | 634 | |
614 | } | 635 | return 0; |
615 | return id; | ||
616 | } | 636 | } |
617 | 637 | ||
618 | static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) | 638 | static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) |
619 | { | 639 | { |
620 | u32 res_50, res_60; | ||
621 | int id; | 640 | int id; |
622 | 641 | ||
623 | /* check native resolution */ | 642 | /* check native resolution */ |
624 | res_50 = info->res_50.native & PS3AV_RES_MASK_50; | 643 | id = ps3av_resbit2id(info->res_50.native, info->res_60.native, |
625 | res_60 = info->res_60.native & PS3AV_RES_MASK_60; | 644 | info->res_vesa.native); |
626 | if (res_50 || res_60) { | 645 | if (id) { |
627 | id = ps3av_resbit2id(res_50, res_60); | 646 | pr_debug("%s: Using native mode %d\n", __func__, id); |
628 | return id; | 647 | return id; |
629 | } | 648 | } |
630 | 649 | ||
631 | /* check resolution */ | 650 | /* check supported resolutions */ |
632 | res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50; | 651 | id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits, |
633 | res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60; | 652 | info->res_vesa.res_bits); |
634 | if (res_50 || res_60) { | 653 | if (id) { |
635 | id = ps3av_resbit2id(res_50, res_60); | 654 | pr_debug("%s: Using supported mode %d\n", __func__, id); |
636 | return id; | 655 | return id; |
637 | } | 656 | } |
638 | 657 | ||
@@ -640,6 +659,7 @@ static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) | |||
640 | id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; | 659 | id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; |
641 | else | 660 | else |
642 | id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50; | 661 | id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50; |
662 | pr_debug("%s: Using default mode %d\n", __func__, id); | ||
643 | return id; | 663 | return id; |
644 | } | 664 | } |
645 | 665 | ||
@@ -737,6 +757,7 @@ static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf, | |||
737 | id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50; | 757 | id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50; |
738 | if (ps3av->region & PS3AV_REGION_RGB) | 758 | if (ps3av->region & PS3AV_REGION_RGB) |
739 | rgb = PS3AV_MODE_RGB; | 759 | rgb = PS3AV_MODE_RGB; |
760 | pr_debug("%s: Using avmulti mode %d\n", __func__, id); | ||
740 | } else if (boot) { | 761 | } else if (boot) { |
741 | /* HDMI: using DEFAULT HDMI_MODE_ID while booting up */ | 762 | /* HDMI: using DEFAULT HDMI_MODE_ID while booting up */ |
742 | info = &monitor_info.info; | 763 | info = &monitor_info.info; |