diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 461 |
1 files changed, 250 insertions, 211 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 93783b15c81..1fff95505cf 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -75,46 +75,45 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev | |||
75 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); | 75 | memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); |
76 | i2c.valid = false; | 76 | i2c.valid = false; |
77 | 77 | ||
78 | atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); | 78 | if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { |
79 | 79 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | |
80 | i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); | 80 | |
81 | 81 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | |
82 | 82 | gpio = &i2c_info->asGPIO_Info[i]; | |
83 | for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { | 83 | |
84 | gpio = &i2c_info->asGPIO_Info[i]; | 84 | if (gpio->sucI2cId.ucAccess == id) { |
85 | 85 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | |
86 | if (gpio->sucI2cId.ucAccess == id) { | 86 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; |
87 | i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; | 87 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; |
88 | i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; | 88 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; |
89 | i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; | 89 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; |
90 | i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; | 90 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; |
91 | i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; | 91 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; |
92 | i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; | 92 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; |
93 | i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; | 93 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); |
94 | i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; | 94 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); |
95 | i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); | 95 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); |
96 | i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); | 96 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); |
97 | i2c.en_clk_mask = (1 << gpio->ucClkEnShift); | 97 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); |
98 | i2c.en_data_mask = (1 << gpio->ucDataEnShift); | 98 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); |
99 | i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); | 99 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); |
100 | i2c.y_data_mask = (1 << gpio->ucDataY_Shift); | 100 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); |
101 | i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); | 101 | |
102 | i2c.a_data_mask = (1 << gpio->ucDataA_Shift); | 102 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) |
103 | 103 | i2c.hw_capable = true; | |
104 | if (gpio->sucI2cId.sbfAccess.bfHW_Capable) | 104 | else |
105 | i2c.hw_capable = true; | 105 | i2c.hw_capable = false; |
106 | else | 106 | |
107 | i2c.hw_capable = false; | 107 | if (gpio->sucI2cId.ucAccess == 0xa0) |
108 | 108 | i2c.mm_i2c = true; | |
109 | if (gpio->sucI2cId.ucAccess == 0xa0) | 109 | else |
110 | i2c.mm_i2c = true; | 110 | i2c.mm_i2c = false; |
111 | else | 111 | |
112 | i2c.mm_i2c = false; | 112 | i2c.i2c_id = gpio->sucI2cId.ucAccess; |
113 | 113 | ||
114 | i2c.i2c_id = gpio->sucI2cId.ucAccess; | 114 | i2c.valid = true; |
115 | 115 | break; | |
116 | i2c.valid = true; | 116 | } |
117 | break; | ||
118 | } | 117 | } |
119 | } | 118 | } |
120 | 119 | ||
@@ -135,20 +134,21 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd | |||
135 | memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); | 134 | memset(&gpio, 0, sizeof(struct radeon_gpio_rec)); |
136 | gpio.valid = false; | 135 | gpio.valid = false; |
137 | 136 | ||
138 | atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset); | 137 | if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { |
138 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); | ||
139 | 139 | ||
140 | gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); | 140 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / |
141 | sizeof(ATOM_GPIO_PIN_ASSIGNMENT); | ||
141 | 142 | ||
142 | num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); | 143 | for (i = 0; i < num_indices; i++) { |
143 | 144 | pin = &gpio_info->asGPIO_Pin[i]; | |
144 | for (i = 0; i < num_indices; i++) { | 145 | if (id == pin->ucGPIO_ID) { |
145 | pin = &gpio_info->asGPIO_Pin[i]; | 146 | gpio.id = pin->ucGPIO_ID; |
146 | if (id == pin->ucGPIO_ID) { | 147 | gpio.reg = pin->usGpioPin_AIndex * 4; |
147 | gpio.id = pin->ucGPIO_ID; | 148 | gpio.mask = (1 << pin->ucGpioPinBitShift); |
148 | gpio.reg = pin->usGpioPin_AIndex * 4; | 149 | gpio.valid = true; |
149 | gpio.mask = (1 << pin->ucGpioPinBitShift); | 150 | break; |
150 | gpio.valid = true; | 151 | } |
151 | break; | ||
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
@@ -264,6 +264,8 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
264 | if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) || | 264 | if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) || |
265 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) | 265 | (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) |
266 | return false; | 266 | return false; |
267 | if (supported_device == ATOM_DEVICE_CRT2_SUPPORT) | ||
268 | *line_mux = 0x90; | ||
267 | } | 269 | } |
268 | 270 | ||
269 | /* ASUS HD 3600 XT board lists the DVI port as HDMI */ | 271 | /* ASUS HD 3600 XT board lists the DVI port as HDMI */ |
@@ -395,9 +397,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
395 | struct radeon_gpio_rec gpio; | 397 | struct radeon_gpio_rec gpio; |
396 | struct radeon_hpd hpd; | 398 | struct radeon_hpd hpd; |
397 | 399 | ||
398 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 400 | if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) |
399 | |||
400 | if (data_offset == 0) | ||
401 | return false; | 401 | return false; |
402 | 402 | ||
403 | if (crev < 2) | 403 | if (crev < 2) |
@@ -449,37 +449,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
449 | GetIndexIntoMasterTable(DATA, | 449 | GetIndexIntoMasterTable(DATA, |
450 | IntegratedSystemInfo); | 450 | IntegratedSystemInfo); |
451 | 451 | ||
452 | atom_parse_data_header(ctx, index, &size, &frev, | 452 | if (atom_parse_data_header(ctx, index, &size, &frev, |
453 | &crev, &igp_offset); | 453 | &crev, &igp_offset)) { |
454 | 454 | ||
455 | if (crev >= 2) { | 455 | if (crev >= 2) { |
456 | igp_obj = | 456 | igp_obj = |
457 | (ATOM_INTEGRATED_SYSTEM_INFO_V2 | 457 | (ATOM_INTEGRATED_SYSTEM_INFO_V2 |
458 | *) (ctx->bios + igp_offset); | 458 | *) (ctx->bios + igp_offset); |
459 | 459 | ||
460 | if (igp_obj) { | 460 | if (igp_obj) { |
461 | uint32_t slot_config, ct; | 461 | uint32_t slot_config, ct; |
462 | 462 | ||
463 | if (con_obj_num == 1) | 463 | if (con_obj_num == 1) |
464 | slot_config = | 464 | slot_config = |
465 | igp_obj-> | 465 | igp_obj-> |
466 | ulDDISlot1Config; | 466 | ulDDISlot1Config; |
467 | else | 467 | else |
468 | slot_config = | 468 | slot_config = |
469 | igp_obj-> | 469 | igp_obj-> |
470 | ulDDISlot2Config; | 470 | ulDDISlot2Config; |
471 | 471 | ||
472 | ct = (slot_config >> 16) & 0xff; | 472 | ct = (slot_config >> 16) & 0xff; |
473 | connector_type = | 473 | connector_type = |
474 | object_connector_convert | 474 | object_connector_convert |
475 | [ct]; | 475 | [ct]; |
476 | connector_object_id = ct; | 476 | connector_object_id = ct; |
477 | igp_lane_info = | 477 | igp_lane_info = |
478 | slot_config & 0xffff; | 478 | slot_config & 0xffff; |
479 | } else | ||
480 | continue; | ||
479 | } else | 481 | } else |
480 | continue; | 482 | continue; |
481 | } else | 483 | } else { |
482 | continue; | 484 | igp_lane_info = 0; |
485 | connector_type = | ||
486 | object_connector_convert[con_obj_id]; | ||
487 | connector_object_id = con_obj_id; | ||
488 | } | ||
483 | } else { | 489 | } else { |
484 | igp_lane_info = 0; | 490 | igp_lane_info = 0; |
485 | connector_type = | 491 | connector_type = |
@@ -627,20 +633,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev, | |||
627 | uint8_t frev, crev; | 633 | uint8_t frev, crev; |
628 | ATOM_XTMDS_INFO *xtmds; | 634 | ATOM_XTMDS_INFO *xtmds; |
629 | 635 | ||
630 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 636 | if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) { |
631 | xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); | 637 | xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); |
632 | 638 | ||
633 | if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { | 639 | if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { |
634 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | 640 | if (connector_type == DRM_MODE_CONNECTOR_DVII) |
635 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; | 641 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; |
636 | else | 642 | else |
637 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; | 643 | return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; |
638 | } else { | 644 | } else { |
639 | if (connector_type == DRM_MODE_CONNECTOR_DVII) | 645 | if (connector_type == DRM_MODE_CONNECTOR_DVII) |
640 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | 646 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
641 | else | 647 | else |
642 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; | 648 | return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; |
643 | } | 649 | } |
650 | } else | ||
651 | return supported_devices_connector_object_id_convert | ||
652 | [connector_type]; | ||
644 | } else { | 653 | } else { |
645 | return supported_devices_connector_object_id_convert | 654 | return supported_devices_connector_object_id_convert |
646 | [connector_type]; | 655 | [connector_type]; |
@@ -672,7 +681,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
672 | int i, j, max_device; | 681 | int i, j, max_device; |
673 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; | 682 | struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; |
674 | 683 | ||
675 | atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); | 684 | if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) |
685 | return false; | ||
676 | 686 | ||
677 | supported_devices = | 687 | supported_devices = |
678 | (union atom_supported_devices *)(ctx->bios + data_offset); | 688 | (union atom_supported_devices *)(ctx->bios + data_offset); |
@@ -865,14 +875,11 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
865 | struct radeon_pll *mpll = &rdev->clock.mpll; | 875 | struct radeon_pll *mpll = &rdev->clock.mpll; |
866 | uint16_t data_offset; | 876 | uint16_t data_offset; |
867 | 877 | ||
868 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 878 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
869 | &crev, &data_offset); | 879 | &frev, &crev, &data_offset)) { |
870 | 880 | firmware_info = | |
871 | firmware_info = | 881 | (union firmware_info *)(mode_info->atom_context->bios + |
872 | (union firmware_info *)(mode_info->atom_context->bios + | 882 | data_offset); |
873 | data_offset); | ||
874 | |||
875 | if (firmware_info) { | ||
876 | /* pixel clocks */ | 883 | /* pixel clocks */ |
877 | p1pll->reference_freq = | 884 | p1pll->reference_freq = |
878 | le16_to_cpu(firmware_info->info.usReferenceClock); | 885 | le16_to_cpu(firmware_info->info.usReferenceClock); |
@@ -887,6 +894,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
887 | p1pll->pll_out_max = | 894 | p1pll->pll_out_max = |
888 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); | 895 | le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); |
889 | 896 | ||
897 | if (crev >= 4) { | ||
898 | p1pll->lcd_pll_out_min = | ||
899 | le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100; | ||
900 | if (p1pll->lcd_pll_out_min == 0) | ||
901 | p1pll->lcd_pll_out_min = p1pll->pll_out_min; | ||
902 | p1pll->lcd_pll_out_max = | ||
903 | le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100; | ||
904 | if (p1pll->lcd_pll_out_max == 0) | ||
905 | p1pll->lcd_pll_out_max = p1pll->pll_out_max; | ||
906 | } else { | ||
907 | p1pll->lcd_pll_out_min = p1pll->pll_out_min; | ||
908 | p1pll->lcd_pll_out_max = p1pll->pll_out_max; | ||
909 | } | ||
910 | |||
890 | if (p1pll->pll_out_min == 0) { | 911 | if (p1pll->pll_out_min == 0) { |
891 | if (ASIC_IS_AVIVO(rdev)) | 912 | if (ASIC_IS_AVIVO(rdev)) |
892 | p1pll->pll_out_min = 64800; | 913 | p1pll->pll_out_min = 64800; |
@@ -992,13 +1013,10 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
992 | u8 frev, crev; | 1013 | u8 frev, crev; |
993 | u16 data_offset; | 1014 | u16 data_offset; |
994 | 1015 | ||
995 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1016 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
996 | &crev, &data_offset); | 1017 | &frev, &crev, &data_offset)) { |
997 | 1018 | igp_info = (union igp_info *)(mode_info->atom_context->bios + | |
998 | igp_info = (union igp_info *)(mode_info->atom_context->bios + | ||
999 | data_offset); | 1019 | data_offset); |
1000 | |||
1001 | if (igp_info) { | ||
1002 | switch (crev) { | 1020 | switch (crev) { |
1003 | case 1: | 1021 | case 1: |
1004 | if (igp_info->info.ucMemoryType & 0xf0) | 1022 | if (igp_info->info.ucMemoryType & 0xf0) |
@@ -1029,14 +1047,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder, | |||
1029 | uint16_t maxfreq; | 1047 | uint16_t maxfreq; |
1030 | int i; | 1048 | int i; |
1031 | 1049 | ||
1032 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1050 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1033 | &crev, &data_offset); | 1051 | &frev, &crev, &data_offset)) { |
1034 | 1052 | tmds_info = | |
1035 | tmds_info = | 1053 | (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + |
1036 | (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + | 1054 | data_offset); |
1037 | data_offset); | ||
1038 | 1055 | ||
1039 | if (tmds_info) { | ||
1040 | maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); | 1056 | maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); |
1041 | for (i = 0; i < 4; i++) { | 1057 | for (i = 0; i < 4; i++) { |
1042 | tmds->tmds_pll[i].freq = | 1058 | tmds->tmds_pll[i].freq = |
@@ -1085,13 +1101,11 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | |||
1085 | if (id > ATOM_MAX_SS_ENTRY) | 1101 | if (id > ATOM_MAX_SS_ENTRY) |
1086 | return NULL; | 1102 | return NULL; |
1087 | 1103 | ||
1088 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1104 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1089 | &crev, &data_offset); | 1105 | &frev, &crev, &data_offset)) { |
1106 | ss_info = | ||
1107 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); | ||
1090 | 1108 | ||
1091 | ss_info = | ||
1092 | (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); | ||
1093 | |||
1094 | if (ss_info) { | ||
1095 | ss = | 1109 | ss = |
1096 | kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); | 1110 | kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); |
1097 | 1111 | ||
@@ -1114,30 +1128,6 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct | |||
1114 | return ss; | 1128 | return ss; |
1115 | } | 1129 | } |
1116 | 1130 | ||
1117 | static void radeon_atom_apply_lvds_quirks(struct drm_device *dev, | ||
1118 | struct radeon_encoder_atom_dig *lvds) | ||
1119 | { | ||
1120 | |||
1121 | /* Toshiba A300-1BU laptop panel doesn't like new pll divider algo */ | ||
1122 | if ((dev->pdev->device == 0x95c4) && | ||
1123 | (dev->pdev->subsystem_vendor == 0x1179) && | ||
1124 | (dev->pdev->subsystem_device == 0xff50)) { | ||
1125 | if ((lvds->native_mode.hdisplay == 1280) && | ||
1126 | (lvds->native_mode.vdisplay == 800)) | ||
1127 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1128 | } | ||
1129 | |||
1130 | /* Dell Studio 15 laptop panel doesn't like new pll divider algo */ | ||
1131 | if ((dev->pdev->device == 0x95c4) && | ||
1132 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
1133 | (dev->pdev->subsystem_device == 0x029f)) { | ||
1134 | if ((lvds->native_mode.hdisplay == 1280) && | ||
1135 | (lvds->native_mode.vdisplay == 800)) | ||
1136 | lvds->pll_algo = PLL_ALGO_LEGACY; | ||
1137 | } | ||
1138 | |||
1139 | } | ||
1140 | |||
1141 | union lvds_info { | 1131 | union lvds_info { |
1142 | struct _ATOM_LVDS_INFO info; | 1132 | struct _ATOM_LVDS_INFO info; |
1143 | struct _ATOM_LVDS_INFO_V12 info_12; | 1133 | struct _ATOM_LVDS_INFO_V12 info_12; |
@@ -1156,13 +1146,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1156 | uint8_t frev, crev; | 1146 | uint8_t frev, crev; |
1157 | struct radeon_encoder_atom_dig *lvds = NULL; | 1147 | struct radeon_encoder_atom_dig *lvds = NULL; |
1158 | 1148 | ||
1159 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, | 1149 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1160 | &crev, &data_offset); | 1150 | &frev, &crev, &data_offset)) { |
1161 | 1151 | lvds_info = | |
1162 | lvds_info = | 1152 | (union lvds_info *)(mode_info->atom_context->bios + data_offset); |
1163 | (union lvds_info *)(mode_info->atom_context->bios + data_offset); | ||
1164 | |||
1165 | if (lvds_info) { | ||
1166 | lvds = | 1153 | lvds = |
1167 | kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | 1154 | kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); |
1168 | 1155 | ||
@@ -1220,9 +1207,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1220 | lvds->pll_algo = PLL_ALGO_LEGACY; | 1207 | lvds->pll_algo = PLL_ALGO_LEGACY; |
1221 | } | 1208 | } |
1222 | 1209 | ||
1223 | /* LVDS quirks */ | ||
1224 | radeon_atom_apply_lvds_quirks(dev, lvds); | ||
1225 | |||
1226 | encoder->native_mode = lvds->native_mode; | 1210 | encoder->native_mode = lvds->native_mode; |
1227 | } | 1211 | } |
1228 | return lvds; | 1212 | return lvds; |
@@ -1241,11 +1225,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
1241 | uint8_t bg, dac; | 1225 | uint8_t bg, dac; |
1242 | struct radeon_encoder_primary_dac *p_dac = NULL; | 1226 | struct radeon_encoder_primary_dac *p_dac = NULL; |
1243 | 1227 | ||
1244 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 1228 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1245 | 1229 | &frev, &crev, &data_offset)) { | |
1246 | dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); | 1230 | dac_info = (struct _COMPASSIONATE_DATA *) |
1231 | (mode_info->atom_context->bios + data_offset); | ||
1247 | 1232 | ||
1248 | if (dac_info) { | ||
1249 | p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); | 1233 | p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); |
1250 | 1234 | ||
1251 | if (!p_dac) | 1235 | if (!p_dac) |
@@ -1270,7 +1254,9 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | |||
1270 | u8 frev, crev; | 1254 | u8 frev, crev; |
1271 | u16 data_offset, misc; | 1255 | u16 data_offset, misc; |
1272 | 1256 | ||
1273 | atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); | 1257 | if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL, |
1258 | &frev, &crev, &data_offset)) | ||
1259 | return false; | ||
1274 | 1260 | ||
1275 | switch (crev) { | 1261 | switch (crev) { |
1276 | case 1: | 1262 | case 1: |
@@ -1362,47 +1348,50 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev) | |||
1362 | struct _ATOM_ANALOG_TV_INFO *tv_info; | 1348 | struct _ATOM_ANALOG_TV_INFO *tv_info; |
1363 | enum radeon_tv_std tv_std = TV_STD_NTSC; | 1349 | enum radeon_tv_std tv_std = TV_STD_NTSC; |
1364 | 1350 | ||
1365 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 1351 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1352 | &frev, &crev, &data_offset)) { | ||
1366 | 1353 | ||
1367 | tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); | 1354 | tv_info = (struct _ATOM_ANALOG_TV_INFO *) |
1355 | (mode_info->atom_context->bios + data_offset); | ||
1368 | 1356 | ||
1369 | switch (tv_info->ucTV_BootUpDefaultStandard) { | 1357 | switch (tv_info->ucTV_BootUpDefaultStandard) { |
1370 | case ATOM_TV_NTSC: | 1358 | case ATOM_TV_NTSC: |
1371 | tv_std = TV_STD_NTSC; | 1359 | tv_std = TV_STD_NTSC; |
1372 | DRM_INFO("Default TV standard: NTSC\n"); | 1360 | DRM_INFO("Default TV standard: NTSC\n"); |
1373 | break; | 1361 | break; |
1374 | case ATOM_TV_NTSCJ: | 1362 | case ATOM_TV_NTSCJ: |
1375 | tv_std = TV_STD_NTSC_J; | 1363 | tv_std = TV_STD_NTSC_J; |
1376 | DRM_INFO("Default TV standard: NTSC-J\n"); | 1364 | DRM_INFO("Default TV standard: NTSC-J\n"); |
1377 | break; | 1365 | break; |
1378 | case ATOM_TV_PAL: | 1366 | case ATOM_TV_PAL: |
1379 | tv_std = TV_STD_PAL; | 1367 | tv_std = TV_STD_PAL; |
1380 | DRM_INFO("Default TV standard: PAL\n"); | 1368 | DRM_INFO("Default TV standard: PAL\n"); |
1381 | break; | 1369 | break; |
1382 | case ATOM_TV_PALM: | 1370 | case ATOM_TV_PALM: |
1383 | tv_std = TV_STD_PAL_M; | 1371 | tv_std = TV_STD_PAL_M; |
1384 | DRM_INFO("Default TV standard: PAL-M\n"); | 1372 | DRM_INFO("Default TV standard: PAL-M\n"); |
1385 | break; | 1373 | break; |
1386 | case ATOM_TV_PALN: | 1374 | case ATOM_TV_PALN: |
1387 | tv_std = TV_STD_PAL_N; | 1375 | tv_std = TV_STD_PAL_N; |
1388 | DRM_INFO("Default TV standard: PAL-N\n"); | 1376 | DRM_INFO("Default TV standard: PAL-N\n"); |
1389 | break; | 1377 | break; |
1390 | case ATOM_TV_PALCN: | 1378 | case ATOM_TV_PALCN: |
1391 | tv_std = TV_STD_PAL_CN; | 1379 | tv_std = TV_STD_PAL_CN; |
1392 | DRM_INFO("Default TV standard: PAL-CN\n"); | 1380 | DRM_INFO("Default TV standard: PAL-CN\n"); |
1393 | break; | 1381 | break; |
1394 | case ATOM_TV_PAL60: | 1382 | case ATOM_TV_PAL60: |
1395 | tv_std = TV_STD_PAL_60; | 1383 | tv_std = TV_STD_PAL_60; |
1396 | DRM_INFO("Default TV standard: PAL-60\n"); | 1384 | DRM_INFO("Default TV standard: PAL-60\n"); |
1397 | break; | 1385 | break; |
1398 | case ATOM_TV_SECAM: | 1386 | case ATOM_TV_SECAM: |
1399 | tv_std = TV_STD_SECAM; | 1387 | tv_std = TV_STD_SECAM; |
1400 | DRM_INFO("Default TV standard: SECAM\n"); | 1388 | DRM_INFO("Default TV standard: SECAM\n"); |
1401 | break; | 1389 | break; |
1402 | default: | 1390 | default: |
1403 | tv_std = TV_STD_NTSC; | 1391 | tv_std = TV_STD_NTSC; |
1404 | DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); | 1392 | DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); |
1405 | break; | 1393 | break; |
1394 | } | ||
1406 | } | 1395 | } |
1407 | return tv_std; | 1396 | return tv_std; |
1408 | } | 1397 | } |
@@ -1420,11 +1409,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
1420 | uint8_t bg, dac; | 1409 | uint8_t bg, dac; |
1421 | struct radeon_encoder_tv_dac *tv_dac = NULL; | 1410 | struct radeon_encoder_tv_dac *tv_dac = NULL; |
1422 | 1411 | ||
1423 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 1412 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1413 | &frev, &crev, &data_offset)) { | ||
1424 | 1414 | ||
1425 | dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); | 1415 | dac_info = (struct _COMPASSIONATE_DATA *) |
1416 | (mode_info->atom_context->bios + data_offset); | ||
1426 | 1417 | ||
1427 | if (dac_info) { | ||
1428 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); | 1418 | tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); |
1429 | 1419 | ||
1430 | if (!tv_dac) | 1420 | if (!tv_dac) |
@@ -1447,6 +1437,30 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
1447 | return tv_dac; | 1437 | return tv_dac; |
1448 | } | 1438 | } |
1449 | 1439 | ||
1440 | static const char *thermal_controller_names[] = { | ||
1441 | "NONE", | ||
1442 | "LM63", | ||
1443 | "ADM1032", | ||
1444 | "ADM1030", | ||
1445 | "MUA6649", | ||
1446 | "LM64", | ||
1447 | "F75375", | ||
1448 | "ASC7512", | ||
1449 | }; | ||
1450 | |||
1451 | static const char *pp_lib_thermal_controller_names[] = { | ||
1452 | "NONE", | ||
1453 | "LM63", | ||
1454 | "ADM1032", | ||
1455 | "ADM1030", | ||
1456 | "MUA6649", | ||
1457 | "LM64", | ||
1458 | "F75375", | ||
1459 | "RV6xx", | ||
1460 | "RV770", | ||
1461 | "ADT7473", | ||
1462 | }; | ||
1463 | |||
1450 | union power_info { | 1464 | union power_info { |
1451 | struct _ATOM_POWERPLAY_INFO info; | 1465 | struct _ATOM_POWERPLAY_INFO info; |
1452 | struct _ATOM_POWERPLAY_INFO_V2 info_2; | 1466 | struct _ATOM_POWERPLAY_INFO_V2 info_2; |
@@ -1466,15 +1480,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1466 | struct _ATOM_PPLIB_STATE *power_state; | 1480 | struct _ATOM_PPLIB_STATE *power_state; |
1467 | int num_modes = 0, i, j; | 1481 | int num_modes = 0, i, j; |
1468 | int state_index = 0, mode_index = 0; | 1482 | int state_index = 0, mode_index = 0; |
1469 | 1483 | struct radeon_i2c_bus_rec i2c_bus; | |
1470 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | ||
1471 | |||
1472 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | ||
1473 | 1484 | ||
1474 | rdev->pm.default_power_state = NULL; | 1485 | rdev->pm.default_power_state = NULL; |
1475 | 1486 | ||
1476 | if (power_info) { | 1487 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1488 | &frev, &crev, &data_offset)) { | ||
1489 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | ||
1477 | if (frev < 4) { | 1490 | if (frev < 4) { |
1491 | /* add the i2c bus for thermal/fan chip */ | ||
1492 | if (power_info->info.ucOverdriveThermalController > 0) { | ||
1493 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | ||
1494 | thermal_controller_names[power_info->info.ucOverdriveThermalController], | ||
1495 | power_info->info.ucOverdriveControllerAddress >> 1); | ||
1496 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); | ||
1497 | rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); | ||
1498 | } | ||
1478 | num_modes = power_info->info.ucNumOfPowerModeEntries; | 1499 | num_modes = power_info->info.ucNumOfPowerModeEntries; |
1479 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | 1500 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) |
1480 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | 1501 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; |
@@ -1684,6 +1705,24 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1684 | } | 1705 | } |
1685 | } | 1706 | } |
1686 | } else if (frev == 4) { | 1707 | } else if (frev == 4) { |
1708 | /* add the i2c bus for thermal/fan chip */ | ||
1709 | /* no support for internal controller yet */ | ||
1710 | if (power_info->info_4.sThermalController.ucType > 0) { | ||
1711 | if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || | ||
1712 | (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770)) { | ||
1713 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
1714 | (power_info->info_4.sThermalController.ucFanParameters & | ||
1715 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
1716 | } else { | ||
1717 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | ||
1718 | pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType], | ||
1719 | power_info->info_4.sThermalController.ucI2cAddress >> 1, | ||
1720 | (power_info->info_4.sThermalController.ucFanParameters & | ||
1721 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
1722 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine); | ||
1723 | rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); | ||
1724 | } | ||
1725 | } | ||
1687 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { | 1726 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { |
1688 | mode_index = 0; | 1727 | mode_index = 0; |
1689 | power_state = (struct _ATOM_PPLIB_STATE *) | 1728 | power_state = (struct _ATOM_PPLIB_STATE *) |