diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 24ea683f7cf5..99bd8a9c56b3 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1538,7 +1538,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1538 | rdev->pm.power_state[state_index].pcie_lanes = | 1538 | rdev->pm.power_state[state_index].pcie_lanes = |
1539 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | 1539 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; |
1540 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | 1540 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); |
1541 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | 1541 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || |
1542 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1542 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1543 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1543 | VOLTAGE_GPIO; | 1544 | VOLTAGE_GPIO; |
1544 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | 1545 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = |
@@ -1605,7 +1606,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1605 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; | 1606 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; |
1606 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); | 1607 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); |
1607 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); | 1608 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); |
1608 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | 1609 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || |
1610 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1609 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1611 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1610 | VOLTAGE_GPIO; | 1612 | VOLTAGE_GPIO; |
1611 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | 1613 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = |
@@ -1679,7 +1681,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1679 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | 1681 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; |
1680 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | 1682 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); |
1681 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | 1683 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); |
1682 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { | 1684 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || |
1685 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1683 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1686 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1684 | VOLTAGE_GPIO; | 1687 | VOLTAGE_GPIO; |
1685 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | 1688 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = |
@@ -1755,9 +1758,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1755 | rdev->pm.power_state[state_index].misc2 = 0; | 1758 | rdev->pm.power_state[state_index].misc2 = 0; |
1756 | } | 1759 | } |
1757 | } else { | 1760 | } else { |
1761 | int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); | ||
1762 | uint8_t fw_frev, fw_crev; | ||
1763 | uint16_t fw_data_offset, vddc = 0; | ||
1764 | union firmware_info *firmware_info; | ||
1765 | ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; | ||
1766 | |||
1767 | if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, | ||
1768 | &fw_frev, &fw_crev, &fw_data_offset)) { | ||
1769 | firmware_info = | ||
1770 | (union firmware_info *)(mode_info->atom_context->bios + | ||
1771 | fw_data_offset); | ||
1772 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; | ||
1773 | } | ||
1774 | |||
1758 | /* add the i2c bus for thermal/fan chip */ | 1775 | /* add the i2c bus for thermal/fan chip */ |
1759 | /* no support for internal controller yet */ | 1776 | /* no support for internal controller yet */ |
1760 | ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; | ||
1761 | if (controller->ucType > 0) { | 1777 | if (controller->ucType > 0) { |
1762 | if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || | 1778 | if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || |
1763 | (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || | 1779 | (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || |
@@ -1817,10 +1833,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1817 | /* skip invalid modes */ | 1833 | /* skip invalid modes */ |
1818 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | 1834 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) |
1819 | continue; | 1835 | continue; |
1820 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 1836 | /* voltage works differently on IGPs */ |
1821 | VOLTAGE_SW; | ||
1822 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | ||
1823 | clock_info->usVDDC; | ||
1824 | mode_index++; | 1837 | mode_index++; |
1825 | } else if (ASIC_IS_DCE4(rdev)) { | 1838 | } else if (ASIC_IS_DCE4(rdev)) { |
1826 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = | 1839 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = |
@@ -1904,6 +1917,16 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1904 | rdev->pm.default_power_state_index = state_index; | 1917 | rdev->pm.default_power_state_index = state_index; |
1905 | rdev->pm.power_state[state_index].default_clock_mode = | 1918 | rdev->pm.power_state[state_index].default_clock_mode = |
1906 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | 1919 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; |
1920 | /* patch the table values with the default slck/mclk from firmware info */ | ||
1921 | for (j = 0; j < mode_index; j++) { | ||
1922 | rdev->pm.power_state[state_index].clock_info[j].mclk = | ||
1923 | rdev->clock.default_mclk; | ||
1924 | rdev->pm.power_state[state_index].clock_info[j].sclk = | ||
1925 | rdev->clock.default_sclk; | ||
1926 | if (vddc) | ||
1927 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = | ||
1928 | vddc; | ||
1929 | } | ||
1907 | } | 1930 | } |
1908 | state_index++; | 1931 | state_index++; |
1909 | } | 1932 | } |
@@ -1943,6 +1966,7 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) | |||
1943 | 1966 | ||
1944 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; | 1967 | rdev->pm.current_power_state_index = rdev->pm.default_power_state_index; |
1945 | rdev->pm.current_clock_mode_index = 0; | 1968 | rdev->pm.current_clock_mode_index = 0; |
1969 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; | ||
1946 | } | 1970 | } |
1947 | 1971 | ||
1948 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) | 1972 | void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable) |
@@ -1998,6 +2022,42 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, | |||
1998 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 2022 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1999 | } | 2023 | } |
2000 | 2024 | ||
2025 | union set_voltage { | ||
2026 | struct _SET_VOLTAGE_PS_ALLOCATION alloc; | ||
2027 | struct _SET_VOLTAGE_PARAMETERS v1; | ||
2028 | struct _SET_VOLTAGE_PARAMETERS_V2 v2; | ||
2029 | }; | ||
2030 | |||
2031 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) | ||
2032 | { | ||
2033 | union set_voltage args; | ||
2034 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); | ||
2035 | u8 frev, crev, volt_index = level; | ||
2036 | |||
2037 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | ||
2038 | return; | ||
2039 | |||
2040 | switch (crev) { | ||
2041 | case 1: | ||
2042 | args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; | ||
2043 | args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; | ||
2044 | args.v1.ucVoltageIndex = volt_index; | ||
2045 | break; | ||
2046 | case 2: | ||
2047 | args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; | ||
2048 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; | ||
2049 | args.v2.usVoltageLevel = cpu_to_le16(level); | ||
2050 | break; | ||
2051 | default: | ||
2052 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | ||
2053 | return; | ||
2054 | } | ||
2055 | |||
2056 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
2057 | } | ||
2058 | |||
2059 | |||
2060 | |||
2001 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) | 2061 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) |
2002 | { | 2062 | { |
2003 | struct radeon_device *rdev = dev->dev_private; | 2063 | struct radeon_device *rdev = dev->dev_private; |