diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 02d5c415f499..f5d12fb103fa 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -675,7 +675,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
675 | ATOM_ENCODER_CAP_RECORD *cap_record; | 675 | ATOM_ENCODER_CAP_RECORD *cap_record; |
676 | u16 caps = 0; | 676 | u16 caps = 0; |
677 | 677 | ||
678 | while (record->ucRecordType > 0 && | 678 | while (record->ucRecordSize > 0 && |
679 | record->ucRecordType > 0 && | ||
679 | record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { | 680 | record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { |
680 | switch (record->ucRecordType) { | 681 | switch (record->ucRecordType) { |
681 | case ATOM_ENCODER_CAP_RECORD_TYPE: | 682 | case ATOM_ENCODER_CAP_RECORD_TYPE: |
@@ -720,7 +721,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
720 | break; | 721 | break; |
721 | } | 722 | } |
722 | 723 | ||
723 | while (record->ucRecordType > 0 && | 724 | while (record->ucRecordSize > 0 && |
725 | record->ucRecordType > 0 && | ||
724 | record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { | 726 | record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { |
725 | switch (record->ucRecordType) { | 727 | switch (record->ucRecordType) { |
726 | case ATOM_I2C_RECORD_TYPE: | 728 | case ATOM_I2C_RECORD_TYPE: |
@@ -782,10 +784,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
782 | ATOM_HPD_INT_RECORD *hpd_record; | 784 | ATOM_HPD_INT_RECORD *hpd_record; |
783 | ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; | 785 | ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; |
784 | 786 | ||
785 | while (record->ucRecordType > 0 | 787 | while (record->ucRecordSize > 0 && |
786 | && record-> | 788 | record->ucRecordType > 0 && |
787 | ucRecordType <= | 789 | record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { |
788 | ATOM_MAX_OBJECT_RECORD_NUMBER) { | ||
789 | switch (record->ucRecordType) { | 790 | switch (record->ucRecordType) { |
790 | case ATOM_I2C_RECORD_TYPE: | 791 | case ATOM_I2C_RECORD_TYPE: |
791 | i2c_record = | 792 | i2c_record = |
@@ -2175,24 +2176,27 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r | |||
2175 | } | 2176 | } |
2176 | } | 2177 | } |
2177 | 2178 | ||
2178 | static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) | 2179 | static void radeon_atombios_get_default_voltages(struct radeon_device *rdev, |
2180 | u16 *vddc, u16 *vddci) | ||
2179 | { | 2181 | { |
2180 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 2182 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2181 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); | 2183 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
2182 | u8 frev, crev; | 2184 | u8 frev, crev; |
2183 | u16 data_offset; | 2185 | u16 data_offset; |
2184 | union firmware_info *firmware_info; | 2186 | union firmware_info *firmware_info; |
2185 | u16 vddc = 0; | 2187 | |
2188 | *vddc = 0; | ||
2189 | *vddci = 0; | ||
2186 | 2190 | ||
2187 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 2191 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
2188 | &frev, &crev, &data_offset)) { | 2192 | &frev, &crev, &data_offset)) { |
2189 | firmware_info = | 2193 | firmware_info = |
2190 | (union firmware_info *)(mode_info->atom_context->bios + | 2194 | (union firmware_info *)(mode_info->atom_context->bios + |
2191 | data_offset); | 2195 | data_offset); |
2192 | vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); | 2196 | *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); |
2197 | if ((frev == 2) && (crev >= 2)) | ||
2198 | *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage); | ||
2193 | } | 2199 | } |
2194 | |||
2195 | return vddc; | ||
2196 | } | 2200 | } |
2197 | 2201 | ||
2198 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, | 2202 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
@@ -2202,7 +2206,9 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde | |||
2202 | int j; | 2206 | int j; |
2203 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | 2207 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
2204 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); | 2208 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
2205 | u16 vddc = radeon_atombios_get_default_vddc(rdev); | 2209 | u16 vddc, vddci; |
2210 | |||
2211 | radeon_atombios_get_default_voltages(rdev, &vddc, &vddci); | ||
2206 | 2212 | ||
2207 | rdev->pm.power_state[state_index].misc = misc; | 2213 | rdev->pm.power_state[state_index].misc = misc; |
2208 | rdev->pm.power_state[state_index].misc2 = misc2; | 2214 | rdev->pm.power_state[state_index].misc2 = misc2; |
@@ -2243,6 +2249,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde | |||
2243 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; | 2249 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
2244 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; | 2250 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
2245 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; | 2251 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; |
2252 | rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci; | ||
2246 | } else { | 2253 | } else { |
2247 | /* patch the table values with the default slck/mclk from firmware info */ | 2254 | /* patch the table values with the default slck/mclk from firmware info */ |
2248 | for (j = 0; j < mode_index; j++) { | 2255 | for (j = 0; j < mode_index; j++) { |
@@ -2285,6 +2292,8 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2285 | VOLTAGE_SW; | 2292 | VOLTAGE_SW; |
2286 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2293 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
2287 | le16_to_cpu(clock_info->evergreen.usVDDC); | 2294 | le16_to_cpu(clock_info->evergreen.usVDDC); |
2295 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci = | ||
2296 | le16_to_cpu(clock_info->evergreen.usVDDCI); | ||
2288 | } else { | 2297 | } else { |
2289 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); | 2298 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); |
2290 | sclk |= clock_info->r600.ucEngineClockHigh << 16; | 2299 | sclk |= clock_info->r600.ucEngineClockHigh << 16; |
@@ -2576,25 +2585,25 @@ union set_voltage { | |||
2576 | struct _SET_VOLTAGE_PARAMETERS_V2 v2; | 2585 | struct _SET_VOLTAGE_PARAMETERS_V2 v2; |
2577 | }; | 2586 | }; |
2578 | 2587 | ||
2579 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) | 2588 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type) |
2580 | { | 2589 | { |
2581 | union set_voltage args; | 2590 | union set_voltage args; |
2582 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); | 2591 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); |
2583 | u8 frev, crev, volt_index = level; | 2592 | u8 frev, crev, volt_index = voltage_level; |
2584 | 2593 | ||
2585 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 2594 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
2586 | return; | 2595 | return; |
2587 | 2596 | ||
2588 | switch (crev) { | 2597 | switch (crev) { |
2589 | case 1: | 2598 | case 1: |
2590 | args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; | 2599 | args.v1.ucVoltageType = voltage_type; |
2591 | args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; | 2600 | args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; |
2592 | args.v1.ucVoltageIndex = volt_index; | 2601 | args.v1.ucVoltageIndex = volt_index; |
2593 | break; | 2602 | break; |
2594 | case 2: | 2603 | case 2: |
2595 | args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; | 2604 | args.v2.ucVoltageType = voltage_type; |
2596 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; | 2605 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; |
2597 | args.v2.usVoltageLevel = cpu_to_le16(level); | 2606 | args.v2.usVoltageLevel = cpu_to_le16(voltage_level); |
2598 | break; | 2607 | break; |
2599 | default: | 2608 | default: |
2600 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | 2609 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |