diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-05-20 04:34:15 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-05-20 06:02:20 -0400 |
commit | df271bec805b42527d864777ed035fcbb42e76c0 (patch) | |
tree | f0147418442af534bab26040b5aa45ec009cf666 /drivers | |
parent | 96b3bef8c1d20b3f0087a26313296bf476930380 (diff) |
drm/radeon/kms: properly handle bpc >8 in atom command tables
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 70 |
2 files changed, 101 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 529a3a704731..608b1c20a768 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; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index b2e0b586e784..6c6793e6e3a5 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -760,6 +760,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
760 | int dp_clock = 0; | 760 | int dp_clock = 0; |
761 | int dp_lane_count = 0; | 761 | int dp_lane_count = 0; |
762 | int hpd_id = RADEON_HPD_NONE; | 762 | int hpd_id = RADEON_HPD_NONE; |
763 | int bpc = 8; | ||
763 | 764 | ||
764 | if (connector) { | 765 | if (connector) { |
765 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 766 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -769,6 +770,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
769 | dp_clock = dig_connector->dp_clock; | 770 | dp_clock = dig_connector->dp_clock; |
770 | dp_lane_count = dig_connector->dp_lane_count; | 771 | dp_lane_count = dig_connector->dp_lane_count; |
771 | hpd_id = radeon_connector->hpd.hpd; | 772 | hpd_id = radeon_connector->hpd.hpd; |
773 | bpc = connector->display_info.bpc; | ||
772 | } | 774 | } |
773 | 775 | ||
774 | /* no dig encoder assigned */ | 776 | /* no dig encoder assigned */ |
@@ -810,7 +812,27 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
810 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | 812 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; |
811 | } | 813 | } |
812 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | 814 | args.v4.acConfig.ucDigSel = dig->dig_encoder; |
813 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 815 | switch (bpc) { |
816 | case 0: | ||
817 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
818 | break; | ||
819 | case 6: | ||
820 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
821 | break; | ||
822 | case 8: | ||
823 | default: | ||
824 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
825 | break; | ||
826 | case 10: | ||
827 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
828 | break; | ||
829 | case 12: | ||
830 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
831 | break; | ||
832 | case 16: | ||
833 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
834 | break; | ||
835 | } | ||
814 | if (hpd_id == RADEON_HPD_NONE) | 836 | if (hpd_id == RADEON_HPD_NONE) |
815 | args.v4.ucHPD_ID = 0; | 837 | args.v4.ucHPD_ID = 0; |
816 | else | 838 | else |
@@ -819,7 +841,27 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
819 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | 841 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) |
820 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | 842 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; |
821 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | 843 | args.v3.acConfig.ucDigSel = dig->dig_encoder; |
822 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 844 | switch (bpc) { |
845 | case 0: | ||
846 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
847 | break; | ||
848 | case 6: | ||
849 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
850 | break; | ||
851 | case 8: | ||
852 | default: | ||
853 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
854 | break; | ||
855 | case 10: | ||
856 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
857 | break; | ||
858 | case 12: | ||
859 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
860 | break; | ||
861 | case 16: | ||
862 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
863 | break; | ||
864 | } | ||
823 | } else { | 865 | } else { |
824 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | 866 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) |
825 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 867 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
@@ -1099,6 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1099 | int dp_lane_count = 0; | 1141 | int dp_lane_count = 0; |
1100 | int connector_object_id = 0; | 1142 | int connector_object_id = 0; |
1101 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | 1143 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; |
1144 | int bpc = 8; | ||
1102 | 1145 | ||
1103 | if (connector) { | 1146 | if (connector) { |
1104 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1147 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -1109,6 +1152,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1109 | dp_lane_count = dig_connector->dp_lane_count; | 1152 | dp_lane_count = dig_connector->dp_lane_count; |
1110 | connector_object_id = | 1153 | connector_object_id = |
1111 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | 1154 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; |
1155 | bpc = connector->display_info.bpc; | ||
1112 | } | 1156 | } |
1113 | 1157 | ||
1114 | memset(&args, 0, sizeof(args)); | 1158 | memset(&args, 0, sizeof(args)); |
@@ -1166,7 +1210,27 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1166 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | 1210 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; |
1167 | break; | 1211 | break; |
1168 | } | 1212 | } |
1169 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 1213 | switch (bpc) { |
1214 | case 0: | ||
1215 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
1216 | break; | ||
1217 | case 6: | ||
1218 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
1219 | break; | ||
1220 | case 8: | ||
1221 | default: | ||
1222 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
1223 | break; | ||
1224 | case 10: | ||
1225 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
1226 | break; | ||
1227 | case 12: | ||
1228 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
1229 | break; | ||
1230 | case 16: | ||
1231 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
1232 | break; | ||
1233 | } | ||
1170 | break; | 1234 | break; |
1171 | default: | 1235 | default: |
1172 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | 1236 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); |