aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ps3/ps3av.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ps3/ps3av.c')
-rw-r--r--drivers/ps3/ps3av.c95
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
588static 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
592static 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
609static 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
618static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) 638static 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;