diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-12-16 16:02:15 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-12-16 16:02:15 -0500 |
commit | d8c58fabd75021cdd99abcd96513cb088d41092b (patch) | |
tree | f6554ecfb27c0d50f5ae6acae3a7077282813cab /drivers/gpu/drm/radeon/radeon_atombios.c | |
parent | 9c04f015ebc2cc2cca5a4a576deb82a311578edc (diff) | |
parent | b08ebe7e776e5be0271ed1e1bbb384e1f29dd117 (diff) |
Merge remote branch 'airlied/drm-core-next' into drm-intel-next
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 1078 |
1 files changed, 611 insertions, 467 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index bc5a2c3382d9..8e82f672263f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1337,6 +1337,43 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, | |||
1337 | return false; | 1337 | return false; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | ||
1341 | struct radeon_atom_ss *ss, | ||
1342 | int id) | ||
1343 | { | ||
1344 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
1345 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | ||
1346 | u16 data_offset, size; | ||
1347 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | ||
1348 | u8 frev, crev; | ||
1349 | u16 percentage = 0, rate = 0; | ||
1350 | |||
1351 | /* get any igp specific overrides */ | ||
1352 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | ||
1353 | &frev, &crev, &data_offset)) { | ||
1354 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | ||
1355 | (mode_info->atom_context->bios + data_offset); | ||
1356 | switch (id) { | ||
1357 | case ASIC_INTERNAL_SS_ON_TMDS: | ||
1358 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | ||
1359 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | ||
1360 | break; | ||
1361 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
1362 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | ||
1363 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | ||
1364 | break; | ||
1365 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
1366 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | ||
1367 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
1368 | break; | ||
1369 | } | ||
1370 | if (percentage) | ||
1371 | ss->percentage = percentage; | ||
1372 | if (rate) | ||
1373 | ss->rate = rate; | ||
1374 | } | ||
1375 | } | ||
1376 | |||
1340 | union asic_ss_info { | 1377 | union asic_ss_info { |
1341 | struct _ATOM_ASIC_INTERNAL_SS_INFO info; | 1378 | struct _ATOM_ASIC_INTERNAL_SS_INFO info; |
1342 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; | 1379 | struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; |
@@ -1401,6 +1438,8 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, | |||
1401 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); | 1438 | le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); |
1402 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; | 1439 | ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; |
1403 | ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); | 1440 | ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); |
1441 | if (rdev->flags & RADEON_IS_IGP) | ||
1442 | radeon_atombios_get_igp_ss_overrides(rdev, ss, id); | ||
1404 | return true; | 1443 | return true; |
1405 | } | 1444 | } |
1406 | } | 1445 | } |
@@ -1740,495 +1779,600 @@ static const char *pp_lib_thermal_controller_names[] = { | |||
1740 | "RV6xx", | 1779 | "RV6xx", |
1741 | "RV770", | 1780 | "RV770", |
1742 | "adt7473", | 1781 | "adt7473", |
1782 | "NONE", | ||
1743 | "External GPIO", | 1783 | "External GPIO", |
1744 | "Evergreen", | 1784 | "Evergreen", |
1745 | "adt7473 with internal", | 1785 | "emc2103", |
1746 | 1786 | "Sumo", | |
1747 | }; | 1787 | }; |
1748 | 1788 | ||
1749 | union power_info { | 1789 | union power_info { |
1750 | struct _ATOM_POWERPLAY_INFO info; | 1790 | struct _ATOM_POWERPLAY_INFO info; |
1751 | struct _ATOM_POWERPLAY_INFO_V2 info_2; | 1791 | struct _ATOM_POWERPLAY_INFO_V2 info_2; |
1752 | struct _ATOM_POWERPLAY_INFO_V3 info_3; | 1792 | struct _ATOM_POWERPLAY_INFO_V3 info_3; |
1753 | struct _ATOM_PPLIB_POWERPLAYTABLE info_4; | 1793 | struct _ATOM_PPLIB_POWERPLAYTABLE pplib; |
1794 | struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2; | ||
1795 | struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3; | ||
1754 | }; | 1796 | }; |
1755 | 1797 | ||
1756 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | 1798 | union pplib_clock_info { |
1799 | struct _ATOM_PPLIB_R600_CLOCK_INFO r600; | ||
1800 | struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; | ||
1801 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; | ||
1802 | struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; | ||
1803 | }; | ||
1804 | |||
1805 | union pplib_power_state { | ||
1806 | struct _ATOM_PPLIB_STATE v1; | ||
1807 | struct _ATOM_PPLIB_STATE_V2 v2; | ||
1808 | }; | ||
1809 | |||
1810 | static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev, | ||
1811 | int state_index, | ||
1812 | u32 misc, u32 misc2) | ||
1813 | { | ||
1814 | rdev->pm.power_state[state_index].misc = misc; | ||
1815 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
1816 | /* order matters! */ | ||
1817 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1818 | rdev->pm.power_state[state_index].type = | ||
1819 | POWER_STATE_TYPE_POWERSAVE; | ||
1820 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1821 | rdev->pm.power_state[state_index].type = | ||
1822 | POWER_STATE_TYPE_BATTERY; | ||
1823 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1824 | rdev->pm.power_state[state_index].type = | ||
1825 | POWER_STATE_TYPE_BATTERY; | ||
1826 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1827 | rdev->pm.power_state[state_index].type = | ||
1828 | POWER_STATE_TYPE_BALANCED; | ||
1829 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1830 | rdev->pm.power_state[state_index].type = | ||
1831 | POWER_STATE_TYPE_PERFORMANCE; | ||
1832 | rdev->pm.power_state[state_index].flags &= | ||
1833 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1834 | } | ||
1835 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1836 | rdev->pm.power_state[state_index].type = | ||
1837 | POWER_STATE_TYPE_BALANCED; | ||
1838 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1839 | rdev->pm.power_state[state_index].type = | ||
1840 | POWER_STATE_TYPE_DEFAULT; | ||
1841 | rdev->pm.default_power_state_index = state_index; | ||
1842 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1843 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1844 | } else if (state_index == 0) { | ||
1845 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
1846 | RADEON_PM_MODE_NO_DISPLAY; | ||
1847 | } | ||
1848 | } | ||
1849 | |||
1850 | static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | ||
1757 | { | 1851 | { |
1758 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1852 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1853 | u32 misc, misc2 = 0; | ||
1854 | int num_modes = 0, i; | ||
1855 | int state_index = 0; | ||
1856 | struct radeon_i2c_bus_rec i2c_bus; | ||
1857 | union power_info *power_info; | ||
1759 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | 1858 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
1760 | u16 data_offset; | 1859 | u16 data_offset; |
1761 | u8 frev, crev; | 1860 | u8 frev, crev; |
1762 | u32 misc, misc2 = 0, sclk, mclk; | ||
1763 | union power_info *power_info; | ||
1764 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
1765 | struct _ATOM_PPLIB_STATE *power_state; | ||
1766 | int num_modes = 0, i, j; | ||
1767 | int state_index = 0, mode_index = 0; | ||
1768 | struct radeon_i2c_bus_rec i2c_bus; | ||
1769 | |||
1770 | rdev->pm.default_power_state_index = -1; | ||
1771 | 1861 | ||
1772 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1862 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, |
1773 | &frev, &crev, &data_offset)) { | 1863 | &frev, &crev, &data_offset)) |
1774 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | 1864 | return state_index; |
1775 | if (frev < 4) { | 1865 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
1776 | /* add the i2c bus for thermal/fan chip */ | 1866 | |
1777 | if (power_info->info.ucOverdriveThermalController > 0) { | 1867 | /* add the i2c bus for thermal/fan chip */ |
1778 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | 1868 | if (power_info->info.ucOverdriveThermalController > 0) { |
1779 | thermal_controller_names[power_info->info.ucOverdriveThermalController], | 1869 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", |
1780 | power_info->info.ucOverdriveControllerAddress >> 1); | 1870 | thermal_controller_names[power_info->info.ucOverdriveThermalController], |
1781 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); | 1871 | power_info->info.ucOverdriveControllerAddress >> 1); |
1782 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | 1872 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); |
1783 | if (rdev->pm.i2c_bus) { | 1873 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
1784 | struct i2c_board_info info = { }; | 1874 | if (rdev->pm.i2c_bus) { |
1785 | const char *name = thermal_controller_names[power_info->info. | 1875 | struct i2c_board_info info = { }; |
1786 | ucOverdriveThermalController]; | 1876 | const char *name = thermal_controller_names[power_info->info. |
1787 | info.addr = power_info->info.ucOverdriveControllerAddress >> 1; | 1877 | ucOverdriveThermalController]; |
1788 | strlcpy(info.type, name, sizeof(info.type)); | 1878 | info.addr = power_info->info.ucOverdriveControllerAddress >> 1; |
1789 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | 1879 | strlcpy(info.type, name, sizeof(info.type)); |
1790 | } | 1880 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); |
1881 | } | ||
1882 | } | ||
1883 | num_modes = power_info->info.ucNumOfPowerModeEntries; | ||
1884 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | ||
1885 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | ||
1886 | /* last mode is usually default, array is low to high */ | ||
1887 | for (i = 0; i < num_modes; i++) { | ||
1888 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
1889 | switch (frev) { | ||
1890 | case 1: | ||
1891 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1892 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1893 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | ||
1894 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1895 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | ||
1896 | /* skip invalid modes */ | ||
1897 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1898 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1899 | continue; | ||
1900 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1901 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | ||
1902 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | ||
1903 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1904 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1905 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1906 | VOLTAGE_GPIO; | ||
1907 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1908 | radeon_lookup_gpio(rdev, | ||
1909 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1910 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1911 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1912 | true; | ||
1913 | else | ||
1914 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1915 | false; | ||
1916 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1917 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1918 | VOLTAGE_VDDC; | ||
1919 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1920 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1791 | } | 1921 | } |
1792 | num_modes = power_info->info.ucNumOfPowerModeEntries; | 1922 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
1793 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | 1923 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0); |
1794 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | 1924 | state_index++; |
1795 | /* last mode is usually default, array is low to high */ | 1925 | break; |
1796 | for (i = 0; i < num_modes; i++) { | 1926 | case 2: |
1797 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 1927 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
1798 | switch (frev) { | 1928 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
1799 | case 1: | 1929 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); |
1800 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 1930 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
1801 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 1931 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); |
1802 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | 1932 | /* skip invalid modes */ |
1803 | rdev->pm.power_state[state_index].clock_info[0].sclk = | 1933 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || |
1804 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | 1934 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) |
1805 | /* skip invalid modes */ | 1935 | continue; |
1806 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | 1936 | rdev->pm.power_state[state_index].pcie_lanes = |
1807 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | 1937 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; |
1808 | continue; | 1938 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); |
1809 | rdev->pm.power_state[state_index].pcie_lanes = | 1939 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); |
1810 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | 1940 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || |
1811 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | 1941 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { |
1812 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | 1942 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1813 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | 1943 | VOLTAGE_GPIO; |
1814 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1944 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = |
1815 | VOLTAGE_GPIO; | 1945 | radeon_lookup_gpio(rdev, |
1816 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | 1946 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); |
1817 | radeon_lookup_gpio(rdev, | 1947 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) |
1818 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | 1948 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = |
1819 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | 1949 | true; |
1820 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | 1950 | else |
1821 | true; | 1951 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = |
1822 | else | 1952 | false; |
1823 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | 1953 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { |
1824 | false; | 1954 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1825 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | 1955 | VOLTAGE_VDDC; |
1826 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1956 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = |
1827 | VOLTAGE_VDDC; | 1957 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; |
1828 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1829 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1830 | } | ||
1831 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1832 | rdev->pm.power_state[state_index].misc = misc; | ||
1833 | /* order matters! */ | ||
1834 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1835 | rdev->pm.power_state[state_index].type = | ||
1836 | POWER_STATE_TYPE_POWERSAVE; | ||
1837 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1838 | rdev->pm.power_state[state_index].type = | ||
1839 | POWER_STATE_TYPE_BATTERY; | ||
1840 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1841 | rdev->pm.power_state[state_index].type = | ||
1842 | POWER_STATE_TYPE_BATTERY; | ||
1843 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1844 | rdev->pm.power_state[state_index].type = | ||
1845 | POWER_STATE_TYPE_BALANCED; | ||
1846 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1847 | rdev->pm.power_state[state_index].type = | ||
1848 | POWER_STATE_TYPE_PERFORMANCE; | ||
1849 | rdev->pm.power_state[state_index].flags &= | ||
1850 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1851 | } | ||
1852 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1853 | rdev->pm.power_state[state_index].type = | ||
1854 | POWER_STATE_TYPE_DEFAULT; | ||
1855 | rdev->pm.default_power_state_index = state_index; | ||
1856 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1857 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1858 | rdev->pm.power_state[state_index].flags &= | ||
1859 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1860 | } else if (state_index == 0) { | ||
1861 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
1862 | RADEON_PM_MODE_NO_DISPLAY; | ||
1863 | } | ||
1864 | state_index++; | ||
1865 | break; | ||
1866 | case 2: | ||
1867 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1868 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1869 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | ||
1870 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1871 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); | ||
1872 | /* skip invalid modes */ | ||
1873 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1874 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1875 | continue; | ||
1876 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1877 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; | ||
1878 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); | ||
1879 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); | ||
1880 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1881 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1882 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1883 | VOLTAGE_GPIO; | ||
1884 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1885 | radeon_lookup_gpio(rdev, | ||
1886 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1887 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1888 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1889 | true; | ||
1890 | else | ||
1891 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1892 | false; | ||
1893 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1894 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1895 | VOLTAGE_VDDC; | ||
1896 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1897 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1898 | } | ||
1899 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1900 | rdev->pm.power_state[state_index].misc = misc; | ||
1901 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
1902 | /* order matters! */ | ||
1903 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1904 | rdev->pm.power_state[state_index].type = | ||
1905 | POWER_STATE_TYPE_POWERSAVE; | ||
1906 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1907 | rdev->pm.power_state[state_index].type = | ||
1908 | POWER_STATE_TYPE_BATTERY; | ||
1909 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1910 | rdev->pm.power_state[state_index].type = | ||
1911 | POWER_STATE_TYPE_BATTERY; | ||
1912 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1913 | rdev->pm.power_state[state_index].type = | ||
1914 | POWER_STATE_TYPE_BALANCED; | ||
1915 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1916 | rdev->pm.power_state[state_index].type = | ||
1917 | POWER_STATE_TYPE_PERFORMANCE; | ||
1918 | rdev->pm.power_state[state_index].flags &= | ||
1919 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1920 | } | ||
1921 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1922 | rdev->pm.power_state[state_index].type = | ||
1923 | POWER_STATE_TYPE_BALANCED; | ||
1924 | if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT) | ||
1925 | rdev->pm.power_state[state_index].flags &= | ||
1926 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1927 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1928 | rdev->pm.power_state[state_index].type = | ||
1929 | POWER_STATE_TYPE_DEFAULT; | ||
1930 | rdev->pm.default_power_state_index = state_index; | ||
1931 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1932 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1933 | rdev->pm.power_state[state_index].flags &= | ||
1934 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1935 | } else if (state_index == 0) { | ||
1936 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
1937 | RADEON_PM_MODE_NO_DISPLAY; | ||
1938 | } | ||
1939 | state_index++; | ||
1940 | break; | ||
1941 | case 3: | ||
1942 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1943 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1944 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | ||
1945 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1946 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); | ||
1947 | /* skip invalid modes */ | ||
1948 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1949 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1950 | continue; | ||
1951 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1952 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
1953 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
1954 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
1955 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1956 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1957 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1958 | VOLTAGE_GPIO; | ||
1959 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1960 | radeon_lookup_gpio(rdev, | ||
1961 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1962 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1963 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1964 | true; | ||
1965 | else | ||
1966 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1967 | false; | ||
1968 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1969 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1970 | VOLTAGE_VDDC; | ||
1971 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1972 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1973 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
1974 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
1975 | true; | ||
1976 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
1977 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
1978 | } | ||
1979 | } | ||
1980 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1981 | rdev->pm.power_state[state_index].misc = misc; | ||
1982 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
1983 | /* order matters! */ | ||
1984 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1985 | rdev->pm.power_state[state_index].type = | ||
1986 | POWER_STATE_TYPE_POWERSAVE; | ||
1987 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1988 | rdev->pm.power_state[state_index].type = | ||
1989 | POWER_STATE_TYPE_BATTERY; | ||
1990 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1991 | rdev->pm.power_state[state_index].type = | ||
1992 | POWER_STATE_TYPE_BATTERY; | ||
1993 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1994 | rdev->pm.power_state[state_index].type = | ||
1995 | POWER_STATE_TYPE_BALANCED; | ||
1996 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1997 | rdev->pm.power_state[state_index].type = | ||
1998 | POWER_STATE_TYPE_PERFORMANCE; | ||
1999 | rdev->pm.power_state[state_index].flags &= | ||
2000 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
2001 | } | ||
2002 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
2003 | rdev->pm.power_state[state_index].type = | ||
2004 | POWER_STATE_TYPE_BALANCED; | ||
2005 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
2006 | rdev->pm.power_state[state_index].type = | ||
2007 | POWER_STATE_TYPE_DEFAULT; | ||
2008 | rdev->pm.default_power_state_index = state_index; | ||
2009 | rdev->pm.power_state[state_index].default_clock_mode = | ||
2010 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
2011 | } else if (state_index == 0) { | ||
2012 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
2013 | RADEON_PM_MODE_NO_DISPLAY; | ||
2014 | } | ||
2015 | state_index++; | ||
2016 | break; | ||
2017 | } | ||
2018 | } | 1958 | } |
2019 | /* last mode is usually default */ | 1959 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
2020 | if (rdev->pm.default_power_state_index == -1) { | 1960 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); |
2021 | rdev->pm.power_state[state_index - 1].type = | 1961 | state_index++; |
2022 | POWER_STATE_TYPE_DEFAULT; | 1962 | break; |
2023 | rdev->pm.default_power_state_index = state_index - 1; | 1963 | case 3: |
2024 | rdev->pm.power_state[state_index - 1].default_clock_mode = | 1964 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
2025 | &rdev->pm.power_state[state_index - 1].clock_info[0]; | 1965 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
2026 | rdev->pm.power_state[state_index].flags &= | 1966 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); |
2027 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | 1967 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
2028 | rdev->pm.power_state[state_index].misc = 0; | 1968 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); |
2029 | rdev->pm.power_state[state_index].misc2 = 0; | 1969 | /* skip invalid modes */ |
1970 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1971 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1972 | continue; | ||
1973 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1974 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
1975 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
1976 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
1977 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1978 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1979 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1980 | VOLTAGE_GPIO; | ||
1981 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1982 | radeon_lookup_gpio(rdev, | ||
1983 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1984 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1985 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1986 | true; | ||
1987 | else | ||
1988 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1989 | false; | ||
1990 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1991 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1992 | VOLTAGE_VDDC; | ||
1993 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1994 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1995 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
1996 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
1997 | true; | ||
1998 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
1999 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
2000 | } | ||
2030 | } | 2001 | } |
2002 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
2003 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); | ||
2004 | state_index++; | ||
2005 | break; | ||
2006 | } | ||
2007 | } | ||
2008 | /* last mode is usually default */ | ||
2009 | if (rdev->pm.default_power_state_index == -1) { | ||
2010 | rdev->pm.power_state[state_index - 1].type = | ||
2011 | POWER_STATE_TYPE_DEFAULT; | ||
2012 | rdev->pm.default_power_state_index = state_index - 1; | ||
2013 | rdev->pm.power_state[state_index - 1].default_clock_mode = | ||
2014 | &rdev->pm.power_state[state_index - 1].clock_info[0]; | ||
2015 | rdev->pm.power_state[state_index].flags &= | ||
2016 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
2017 | rdev->pm.power_state[state_index].misc = 0; | ||
2018 | rdev->pm.power_state[state_index].misc2 = 0; | ||
2019 | } | ||
2020 | return state_index; | ||
2021 | } | ||
2022 | |||
2023 | static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev, | ||
2024 | ATOM_PPLIB_THERMALCONTROLLER *controller) | ||
2025 | { | ||
2026 | struct radeon_i2c_bus_rec i2c_bus; | ||
2027 | |||
2028 | /* add the i2c bus for thermal/fan chip */ | ||
2029 | if (controller->ucType > 0) { | ||
2030 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { | ||
2031 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2032 | (controller->ucFanParameters & | ||
2033 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2034 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | ||
2035 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | ||
2036 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2037 | (controller->ucFanParameters & | ||
2038 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2039 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
2040 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
2041 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2042 | (controller->ucFanParameters & | ||
2043 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2044 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
2045 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) { | ||
2046 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2047 | (controller->ucFanParameters & | ||
2048 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2049 | rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO; | ||
2050 | } else if ((controller->ucType == | ||
2051 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | ||
2052 | (controller->ucType == | ||
2053 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || | ||
2054 | (controller->ucType == | ||
2055 | ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { | ||
2056 | DRM_INFO("Special thermal controller config\n"); | ||
2031 | } else { | 2057 | } else { |
2032 | int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); | 2058 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", |
2033 | uint8_t fw_frev, fw_crev; | 2059 | pp_lib_thermal_controller_names[controller->ucType], |
2034 | uint16_t fw_data_offset, vddc = 0; | 2060 | controller->ucI2cAddress >> 1, |
2035 | union firmware_info *firmware_info; | 2061 | (controller->ucFanParameters & |
2036 | ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; | 2062 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
2037 | 2063 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | |
2038 | if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, | 2064 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
2039 | &fw_frev, &fw_crev, &fw_data_offset)) { | 2065 | if (rdev->pm.i2c_bus) { |
2040 | firmware_info = | 2066 | struct i2c_board_info info = { }; |
2041 | (union firmware_info *)(mode_info->atom_context->bios + | 2067 | const char *name = pp_lib_thermal_controller_names[controller->ucType]; |
2042 | fw_data_offset); | 2068 | info.addr = controller->ucI2cAddress >> 1; |
2043 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; | 2069 | strlcpy(info.type, name, sizeof(info.type)); |
2070 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
2044 | } | 2071 | } |
2072 | } | ||
2073 | } | ||
2074 | } | ||
2045 | 2075 | ||
2046 | /* add the i2c bus for thermal/fan chip */ | 2076 | static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) |
2047 | if (controller->ucType > 0) { | 2077 | { |
2048 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { | 2078 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2049 | DRM_INFO("Internal thermal controller %s fan control\n", | 2079 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
2050 | (controller->ucFanParameters & | 2080 | u8 frev, crev; |
2051 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | 2081 | u16 data_offset; |
2052 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | 2082 | union firmware_info *firmware_info; |
2053 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | 2083 | u16 vddc = 0; |
2054 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2055 | (controller->ucFanParameters & | ||
2056 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2057 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
2058 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
2059 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2060 | (controller->ucFanParameters & | ||
2061 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2062 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
2063 | } else if ((controller->ucType == | ||
2064 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | ||
2065 | (controller->ucType == | ||
2066 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { | ||
2067 | DRM_INFO("Special thermal controller config\n"); | ||
2068 | } else { | ||
2069 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | ||
2070 | pp_lib_thermal_controller_names[controller->ucType], | ||
2071 | controller->ucI2cAddress >> 1, | ||
2072 | (controller->ucFanParameters & | ||
2073 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2074 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | ||
2075 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | ||
2076 | if (rdev->pm.i2c_bus) { | ||
2077 | struct i2c_board_info info = { }; | ||
2078 | const char *name = pp_lib_thermal_controller_names[controller->ucType]; | ||
2079 | info.addr = controller->ucI2cAddress >> 1; | ||
2080 | strlcpy(info.type, name, sizeof(info.type)); | ||
2081 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
2082 | } | ||
2083 | 2084 | ||
2084 | } | 2085 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
2085 | } | 2086 | &frev, &crev, &data_offset)) { |
2086 | /* first mode is usually default, followed by low to high */ | 2087 | firmware_info = |
2087 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { | 2088 | (union firmware_info *)(mode_info->atom_context->bios + |
2088 | mode_index = 0; | 2089 | data_offset); |
2089 | power_state = (struct _ATOM_PPLIB_STATE *) | 2090 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; |
2090 | (mode_info->atom_context->bios + | 2091 | } |
2091 | data_offset + | 2092 | |
2092 | le16_to_cpu(power_info->info_4.usStateArrayOffset) + | 2093 | return vddc; |
2093 | i * power_info->info_4.ucStateEntrySize); | 2094 | } |
2094 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | 2095 | |
2095 | (mode_info->atom_context->bios + | 2096 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
2096 | data_offset + | 2097 | int state_index, int mode_index, |
2097 | le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + | 2098 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) |
2098 | (power_state->ucNonClockStateIndex * | 2099 | { |
2099 | power_info->info_4.ucNonClockSize)); | 2100 | int j; |
2100 | for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { | 2101 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
2101 | if (rdev->flags & RADEON_IS_IGP) { | 2102 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
2102 | struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = | 2103 | u16 vddc = radeon_atombios_get_default_vddc(rdev); |
2103 | (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) | 2104 | |
2104 | (mode_info->atom_context->bios + | 2105 | rdev->pm.power_state[state_index].misc = misc; |
2105 | data_offset + | 2106 | rdev->pm.power_state[state_index].misc2 = misc2; |
2106 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2107 | rdev->pm.power_state[state_index].pcie_lanes = |
2107 | (power_state->ucClockStateIndices[j] * | 2108 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> |
2108 | power_info->info_4.ucClockInfoSize)); | 2109 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; |
2109 | sclk = le16_to_cpu(clock_info->usLowEngineClockLow); | 2110 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { |
2110 | sclk |= clock_info->ucLowEngineClockHigh << 16; | 2111 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: |
2111 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2112 | rdev->pm.power_state[state_index].type = |
2112 | /* skip invalid modes */ | 2113 | POWER_STATE_TYPE_BATTERY; |
2113 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | 2114 | break; |
2114 | continue; | 2115 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: |
2115 | /* voltage works differently on IGPs */ | 2116 | rdev->pm.power_state[state_index].type = |
2116 | mode_index++; | 2117 | POWER_STATE_TYPE_BALANCED; |
2117 | } else if (ASIC_IS_DCE4(rdev)) { | 2118 | break; |
2118 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = | 2119 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: |
2119 | (struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *) | 2120 | rdev->pm.power_state[state_index].type = |
2120 | (mode_info->atom_context->bios + | 2121 | POWER_STATE_TYPE_PERFORMANCE; |
2121 | data_offset + | 2122 | break; |
2122 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2123 | case ATOM_PPLIB_CLASSIFICATION_UI_NONE: |
2123 | (power_state->ucClockStateIndices[j] * | 2124 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) |
2124 | power_info->info_4.ucClockInfoSize)); | 2125 | rdev->pm.power_state[state_index].type = |
2125 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | 2126 | POWER_STATE_TYPE_PERFORMANCE; |
2126 | sclk |= clock_info->ucEngineClockHigh << 16; | 2127 | break; |
2127 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | 2128 | } |
2128 | mclk |= clock_info->ucMemoryClockHigh << 16; | 2129 | rdev->pm.power_state[state_index].flags = 0; |
2129 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | 2130 | if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) |
2130 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2131 | rdev->pm.power_state[state_index].flags |= |
2131 | /* skip invalid modes */ | 2132 | RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
2132 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | 2133 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { |
2133 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | 2134 | rdev->pm.power_state[state_index].type = |
2134 | continue; | 2135 | POWER_STATE_TYPE_DEFAULT; |
2135 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2136 | rdev->pm.default_power_state_index = state_index; |
2136 | VOLTAGE_SW; | 2137 | rdev->pm.power_state[state_index].default_clock_mode = |
2137 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2138 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; |
2138 | clock_info->usVDDC; | 2139 | /* patch the table values with the default slck/mclk from firmware info */ |
2139 | /* XXX usVDDCI */ | 2140 | for (j = 0; j < mode_index; j++) { |
2140 | mode_index++; | 2141 | rdev->pm.power_state[state_index].clock_info[j].mclk = |
2141 | } else { | 2142 | rdev->clock.default_mclk; |
2142 | struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = | 2143 | rdev->pm.power_state[state_index].clock_info[j].sclk = |
2143 | (struct _ATOM_PPLIB_R600_CLOCK_INFO *) | 2144 | rdev->clock.default_sclk; |
2144 | (mode_info->atom_context->bios + | 2145 | if (vddc) |
2145 | data_offset + | 2146 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = |
2146 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2147 | vddc; |
2147 | (power_state->ucClockStateIndices[j] * | 2148 | } |
2148 | power_info->info_4.ucClockInfoSize)); | 2149 | } |
2149 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | 2150 | } |
2150 | sclk |= clock_info->ucEngineClockHigh << 16; | 2151 | |
2151 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | 2152 | static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, |
2152 | mclk |= clock_info->ucMemoryClockHigh << 16; | 2153 | int state_index, int mode_index, |
2153 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | 2154 | union pplib_clock_info *clock_info) |
2154 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2155 | { |
2155 | /* skip invalid modes */ | 2156 | u32 sclk, mclk; |
2156 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | 2157 | |
2157 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | 2158 | if (rdev->flags & RADEON_IS_IGP) { |
2158 | continue; | 2159 | if (rdev->family >= CHIP_PALM) { |
2159 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2160 | sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); |
2160 | VOLTAGE_SW; | 2161 | sclk |= clock_info->sumo.ucEngineClockHigh << 16; |
2161 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2162 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2162 | clock_info->usVDDC; | 2163 | } else { |
2163 | mode_index++; | 2164 | sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); |
2164 | } | 2165 | sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; |
2165 | } | 2166 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2166 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | 2167 | } |
2167 | if (mode_index) { | 2168 | } else if (ASIC_IS_DCE4(rdev)) { |
2168 | misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | 2169 | sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); |
2169 | misc2 = le16_to_cpu(non_clock_info->usClassification); | 2170 | sclk |= clock_info->evergreen.ucEngineClockHigh << 16; |
2170 | rdev->pm.power_state[state_index].misc = misc; | 2171 | mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow); |
2171 | rdev->pm.power_state[state_index].misc2 = misc2; | 2172 | mclk |= clock_info->evergreen.ucMemoryClockHigh << 16; |
2172 | rdev->pm.power_state[state_index].pcie_lanes = | 2173 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; |
2173 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> | 2174 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2174 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; | 2175 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
2175 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { | 2176 | VOLTAGE_SW; |
2176 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: | 2177 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
2177 | rdev->pm.power_state[state_index].type = | 2178 | clock_info->evergreen.usVDDC; |
2178 | POWER_STATE_TYPE_BATTERY; | 2179 | } else { |
2179 | break; | 2180 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); |
2180 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: | 2181 | sclk |= clock_info->r600.ucEngineClockHigh << 16; |
2181 | rdev->pm.power_state[state_index].type = | 2182 | mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); |
2182 | POWER_STATE_TYPE_BALANCED; | 2183 | mclk |= clock_info->r600.ucMemoryClockHigh << 16; |
2183 | break; | 2184 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; |
2184 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: | 2185 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2185 | rdev->pm.power_state[state_index].type = | 2186 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
2186 | POWER_STATE_TYPE_PERFORMANCE; | 2187 | VOLTAGE_SW; |
2187 | break; | 2188 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
2188 | case ATOM_PPLIB_CLASSIFICATION_UI_NONE: | 2189 | clock_info->r600.usVDDC; |
2189 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) | 2190 | } |
2190 | rdev->pm.power_state[state_index].type = | 2191 | |
2191 | POWER_STATE_TYPE_PERFORMANCE; | 2192 | if (rdev->flags & RADEON_IS_IGP) { |
2192 | break; | 2193 | /* skip invalid modes */ |
2193 | } | 2194 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) |
2194 | rdev->pm.power_state[state_index].flags = 0; | 2195 | return false; |
2195 | if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) | 2196 | } else { |
2196 | rdev->pm.power_state[state_index].flags |= | 2197 | /* skip invalid modes */ |
2197 | RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | 2198 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || |
2198 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { | 2199 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) |
2199 | rdev->pm.power_state[state_index].type = | 2200 | return false; |
2200 | POWER_STATE_TYPE_DEFAULT; | 2201 | } |
2201 | rdev->pm.default_power_state_index = state_index; | 2202 | return true; |
2202 | rdev->pm.power_state[state_index].default_clock_mode = | 2203 | } |
2203 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | 2204 | |
2204 | /* patch the table values with the default slck/mclk from firmware info */ | 2205 | static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) |
2205 | for (j = 0; j < mode_index; j++) { | 2206 | { |
2206 | rdev->pm.power_state[state_index].clock_info[j].mclk = | 2207 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2207 | rdev->clock.default_mclk; | 2208 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; |
2208 | rdev->pm.power_state[state_index].clock_info[j].sclk = | 2209 | union pplib_power_state *power_state; |
2209 | rdev->clock.default_sclk; | 2210 | int i, j; |
2210 | if (vddc) | 2211 | int state_index = 0, mode_index = 0; |
2211 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = | 2212 | union pplib_clock_info *clock_info; |
2212 | vddc; | 2213 | bool valid; |
2213 | } | 2214 | union power_info *power_info; |
2214 | } | 2215 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
2215 | state_index++; | 2216 | u16 data_offset; |
2216 | } | 2217 | u8 frev, crev; |
2217 | } | 2218 | |
2218 | /* if multiple clock modes, mark the lowest as no display */ | 2219 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, |
2219 | for (i = 0; i < state_index; i++) { | 2220 | &frev, &crev, &data_offset)) |
2220 | if (rdev->pm.power_state[i].num_clock_modes > 1) | 2221 | return state_index; |
2221 | rdev->pm.power_state[i].clock_info[0].flags |= | 2222 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
2222 | RADEON_PM_MODE_NO_DISPLAY; | 2223 | |
2223 | } | 2224 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); |
2224 | /* first mode is usually default */ | 2225 | /* first mode is usually default, followed by low to high */ |
2225 | if (rdev->pm.default_power_state_index == -1) { | 2226 | for (i = 0; i < power_info->pplib.ucNumStates; i++) { |
2226 | rdev->pm.power_state[0].type = | 2227 | mode_index = 0; |
2227 | POWER_STATE_TYPE_DEFAULT; | 2228 | power_state = (union pplib_power_state *) |
2228 | rdev->pm.default_power_state_index = 0; | 2229 | (mode_info->atom_context->bios + data_offset + |
2229 | rdev->pm.power_state[0].default_clock_mode = | 2230 | le16_to_cpu(power_info->pplib.usStateArrayOffset) + |
2230 | &rdev->pm.power_state[0].clock_info[0]; | 2231 | i * power_info->pplib.ucStateEntrySize); |
2231 | } | 2232 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) |
2233 | (mode_info->atom_context->bios + data_offset + | ||
2234 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + | ||
2235 | (power_state->v1.ucNonClockStateIndex * | ||
2236 | power_info->pplib.ucNonClockSize)); | ||
2237 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { | ||
2238 | clock_info = (union pplib_clock_info *) | ||
2239 | (mode_info->atom_context->bios + data_offset + | ||
2240 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + | ||
2241 | (power_state->v1.ucClockStateIndices[j] * | ||
2242 | power_info->pplib.ucClockInfoSize)); | ||
2243 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
2244 | state_index, mode_index, | ||
2245 | clock_info); | ||
2246 | if (valid) | ||
2247 | mode_index++; | ||
2248 | } | ||
2249 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
2250 | if (mode_index) { | ||
2251 | radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, | ||
2252 | non_clock_info); | ||
2253 | state_index++; | ||
2254 | } | ||
2255 | } | ||
2256 | /* if multiple clock modes, mark the lowest as no display */ | ||
2257 | for (i = 0; i < state_index; i++) { | ||
2258 | if (rdev->pm.power_state[i].num_clock_modes > 1) | ||
2259 | rdev->pm.power_state[i].clock_info[0].flags |= | ||
2260 | RADEON_PM_MODE_NO_DISPLAY; | ||
2261 | } | ||
2262 | /* first mode is usually default */ | ||
2263 | if (rdev->pm.default_power_state_index == -1) { | ||
2264 | rdev->pm.power_state[0].type = | ||
2265 | POWER_STATE_TYPE_DEFAULT; | ||
2266 | rdev->pm.default_power_state_index = 0; | ||
2267 | rdev->pm.power_state[0].default_clock_mode = | ||
2268 | &rdev->pm.power_state[0].clock_info[0]; | ||
2269 | } | ||
2270 | return state_index; | ||
2271 | } | ||
2272 | |||
2273 | static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) | ||
2274 | { | ||
2275 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
2276 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
2277 | union pplib_power_state *power_state; | ||
2278 | int i, j, non_clock_array_index, clock_array_index; | ||
2279 | int state_index = 0, mode_index = 0; | ||
2280 | union pplib_clock_info *clock_info; | ||
2281 | struct StateArray *state_array; | ||
2282 | struct ClockInfoArray *clock_info_array; | ||
2283 | struct NonClockInfoArray *non_clock_info_array; | ||
2284 | bool valid; | ||
2285 | union power_info *power_info; | ||
2286 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | ||
2287 | u16 data_offset; | ||
2288 | u8 frev, crev; | ||
2289 | |||
2290 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
2291 | &frev, &crev, &data_offset)) | ||
2292 | return state_index; | ||
2293 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | ||
2294 | |||
2295 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); | ||
2296 | state_array = (struct StateArray *) | ||
2297 | (mode_info->atom_context->bios + data_offset + | ||
2298 | power_info->pplib.usStateArrayOffset); | ||
2299 | clock_info_array = (struct ClockInfoArray *) | ||
2300 | (mode_info->atom_context->bios + data_offset + | ||
2301 | power_info->pplib.usClockInfoArrayOffset); | ||
2302 | non_clock_info_array = (struct NonClockInfoArray *) | ||
2303 | (mode_info->atom_context->bios + data_offset + | ||
2304 | power_info->pplib.usNonClockInfoArrayOffset); | ||
2305 | for (i = 0; i < state_array->ucNumEntries; i++) { | ||
2306 | mode_index = 0; | ||
2307 | power_state = (union pplib_power_state *)&state_array->states[i]; | ||
2308 | /* XXX this might be an inagua bug... */ | ||
2309 | non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ | ||
2310 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | ||
2311 | &non_clock_info_array->nonClockInfo[non_clock_array_index]; | ||
2312 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { | ||
2313 | clock_array_index = power_state->v2.clockInfoIndex[j]; | ||
2314 | /* XXX this might be an inagua bug... */ | ||
2315 | if (clock_array_index >= clock_info_array->ucNumEntries) | ||
2316 | continue; | ||
2317 | clock_info = (union pplib_clock_info *) | ||
2318 | &clock_info_array->clockInfo[clock_array_index]; | ||
2319 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
2320 | state_index, mode_index, | ||
2321 | clock_info); | ||
2322 | if (valid) | ||
2323 | mode_index++; | ||
2324 | } | ||
2325 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
2326 | if (mode_index) { | ||
2327 | radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, | ||
2328 | non_clock_info); | ||
2329 | state_index++; | ||
2330 | } | ||
2331 | } | ||
2332 | /* if multiple clock modes, mark the lowest as no display */ | ||
2333 | for (i = 0; i < state_index; i++) { | ||
2334 | if (rdev->pm.power_state[i].num_clock_modes > 1) | ||
2335 | rdev->pm.power_state[i].clock_info[0].flags |= | ||
2336 | RADEON_PM_MODE_NO_DISPLAY; | ||
2337 | } | ||
2338 | /* first mode is usually default */ | ||
2339 | if (rdev->pm.default_power_state_index == -1) { | ||
2340 | rdev->pm.power_state[0].type = | ||
2341 | POWER_STATE_TYPE_DEFAULT; | ||
2342 | rdev->pm.default_power_state_index = 0; | ||
2343 | rdev->pm.power_state[0].default_clock_mode = | ||
2344 | &rdev->pm.power_state[0].clock_info[0]; | ||
2345 | } | ||
2346 | return state_index; | ||
2347 | } | ||
2348 | |||
2349 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | ||
2350 | { | ||
2351 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
2352 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | ||
2353 | u16 data_offset; | ||
2354 | u8 frev, crev; | ||
2355 | int state_index = 0; | ||
2356 | |||
2357 | rdev->pm.default_power_state_index = -1; | ||
2358 | |||
2359 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
2360 | &frev, &crev, &data_offset)) { | ||
2361 | switch (frev) { | ||
2362 | case 1: | ||
2363 | case 2: | ||
2364 | case 3: | ||
2365 | state_index = radeon_atombios_parse_power_table_1_3(rdev); | ||
2366 | break; | ||
2367 | case 4: | ||
2368 | case 5: | ||
2369 | state_index = radeon_atombios_parse_power_table_4_5(rdev); | ||
2370 | break; | ||
2371 | case 6: | ||
2372 | state_index = radeon_atombios_parse_power_table_6(rdev); | ||
2373 | break; | ||
2374 | default: | ||
2375 | break; | ||
2232 | } | 2376 | } |
2233 | } else { | 2377 | } else { |
2234 | /* add the default mode */ | 2378 | /* add the default mode */ |