diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 529a3a70473..608b1c20a76 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -512,6 +512,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
512 | struct radeon_device *rdev = dev->dev_private; | 512 | struct radeon_device *rdev = dev->dev_private; |
513 | struct drm_encoder *encoder = NULL; | 513 | struct drm_encoder *encoder = NULL; |
514 | struct radeon_encoder *radeon_encoder = NULL; | 514 | struct radeon_encoder *radeon_encoder = NULL; |
515 | struct drm_connector *connector = NULL; | ||
515 | u32 adjusted_clock = mode->clock; | 516 | u32 adjusted_clock = mode->clock; |
516 | int encoder_mode = 0; | 517 | int encoder_mode = 0; |
517 | u32 dp_clock = mode->clock; | 518 | u32 dp_clock = mode->clock; |
@@ -546,9 +547,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
546 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 547 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
547 | if (encoder->crtc == crtc) { | 548 | if (encoder->crtc == crtc) { |
548 | radeon_encoder = to_radeon_encoder(encoder); | 549 | radeon_encoder = to_radeon_encoder(encoder); |
550 | connector = radeon_get_connector_for_encoder(encoder); | ||
551 | if (connector) | ||
552 | bpc = connector->display_info.bpc; | ||
549 | encoder_mode = atombios_get_encoder_mode(encoder); | 553 | encoder_mode = atombios_get_encoder_mode(encoder); |
550 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | 554 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { |
551 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
552 | if (connector) { | 555 | if (connector) { |
553 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 556 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
554 | struct radeon_connector_atom_dig *dig_connector = | 557 | struct radeon_connector_atom_dig *dig_connector = |
@@ -754,7 +757,8 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
754 | u32 ref_div, | 757 | u32 ref_div, |
755 | u32 fb_div, | 758 | u32 fb_div, |
756 | u32 frac_fb_div, | 759 | u32 frac_fb_div, |
757 | u32 post_div) | 760 | u32 post_div, |
761 | int bpc) | ||
758 | { | 762 | { |
759 | struct drm_device *dev = crtc->dev; | 763 | struct drm_device *dev = crtc->dev; |
760 | struct radeon_device *rdev = dev->dev_private; | 764 | struct radeon_device *rdev = dev->dev_private; |
@@ -812,6 +816,15 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
812 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | 816 | args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); |
813 | args.v5.ucPostDiv = post_div; | 817 | args.v5.ucPostDiv = post_div; |
814 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ | 818 | args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */ |
819 | switch (bpc) { | ||
820 | case 8: | ||
821 | default: | ||
822 | args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP; | ||
823 | break; | ||
824 | case 10: | ||
825 | args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; | ||
826 | break; | ||
827 | } | ||
815 | args.v5.ucTransmitterID = encoder_id; | 828 | args.v5.ucTransmitterID = encoder_id; |
816 | args.v5.ucEncoderMode = encoder_mode; | 829 | args.v5.ucEncoderMode = encoder_mode; |
817 | args.v5.ucPpll = pll_id; | 830 | args.v5.ucPpll = pll_id; |
@@ -824,6 +837,21 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc, | |||
824 | args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); | 837 | args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000); |
825 | args.v6.ucPostDiv = post_div; | 838 | args.v6.ucPostDiv = post_div; |
826 | args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */ | 839 | args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */ |
840 | switch (bpc) { | ||
841 | case 8: | ||
842 | default: | ||
843 | args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP; | ||
844 | break; | ||
845 | case 10: | ||
846 | args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP; | ||
847 | break; | ||
848 | case 12: | ||
849 | args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP; | ||
850 | break; | ||
851 | case 16: | ||
852 | args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; | ||
853 | break; | ||
854 | } | ||
827 | args.v6.ucTransmitterID = encoder_id; | 855 | args.v6.ucTransmitterID = encoder_id; |
828 | args.v6.ucEncoderMode = encoder_mode; | 856 | args.v6.ucEncoderMode = encoder_mode; |
829 | args.v6.ucPpll = pll_id; | 857 | args.v6.ucPpll = pll_id; |
@@ -855,6 +883,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
855 | int encoder_mode = 0; | 883 | int encoder_mode = 0; |
856 | struct radeon_atom_ss ss; | 884 | struct radeon_atom_ss ss; |
857 | bool ss_enabled = false; | 885 | bool ss_enabled = false; |
886 | int bpc = 8; | ||
858 | 887 | ||
859 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 888 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
860 | if (encoder->crtc == crtc) { | 889 | if (encoder->crtc == crtc) { |
@@ -891,6 +920,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
891 | struct radeon_connector_atom_dig *dig_connector = | 920 | struct radeon_connector_atom_dig *dig_connector = |
892 | radeon_connector->con_priv; | 921 | radeon_connector->con_priv; |
893 | int dp_clock; | 922 | int dp_clock; |
923 | bpc = connector->display_info.bpc; | ||
894 | 924 | ||
895 | switch (encoder_mode) { | 925 | switch (encoder_mode) { |
896 | case ATOM_ENCODER_MODE_DP: | 926 | case ATOM_ENCODER_MODE_DP: |
@@ -974,7 +1004,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
974 | 1004 | ||
975 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 1005 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
976 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | 1006 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
977 | ref_div, fb_div, frac_fb_div, post_div); | 1007 | ref_div, fb_div, frac_fb_div, post_div, bpc); |
978 | 1008 | ||
979 | if (ss_enabled) { | 1009 | if (ss_enabled) { |
980 | /* calculate ss amount and step size */ | 1010 | /* calculate ss amount and step size */ |
@@ -1522,7 +1552,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1522 | case ATOM_PPLL2: | 1552 | case ATOM_PPLL2: |
1523 | /* disable the ppll */ | 1553 | /* disable the ppll */ |
1524 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 1554 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1525 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0); | 1555 | 0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0); |
1526 | break; | 1556 | break; |
1527 | default: | 1557 | default: |
1528 | break; | 1558 | break; |