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