diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-11-22 17:56:34 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-11-22 18:23:31 -0500 |
commit | 560154e9a27f2f260fcb2dd18c488203246f257e (patch) | |
tree | 324d07a7bb44e513d34c59b5b11a87e29678d90d /drivers | |
parent | e719ebd916c2ecee072affc9e7f0b92aa33c2f94 (diff) |
drm/radeon/kms: refactor atombios power state fetching
The function was getting too large. Rework it to share
more state better handle new power table formats.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 941 |
1 files changed, 475 insertions, 466 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 4d37b2d1ba7..7056e20d329 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1763,495 +1763,504 @@ static const char *pp_lib_thermal_controller_names[] = { | |||
1763 | "RV6xx", | 1763 | "RV6xx", |
1764 | "RV770", | 1764 | "RV770", |
1765 | "adt7473", | 1765 | "adt7473", |
1766 | "NONE", | ||
1766 | "External GPIO", | 1767 | "External GPIO", |
1767 | "Evergreen", | 1768 | "Evergreen", |
1768 | "adt7473 with internal", | 1769 | "adt7473 with internal", |
1769 | |||
1770 | }; | 1770 | }; |
1771 | 1771 | ||
1772 | union power_info { | 1772 | union power_info { |
1773 | struct _ATOM_POWERPLAY_INFO info; | 1773 | struct _ATOM_POWERPLAY_INFO info; |
1774 | struct _ATOM_POWERPLAY_INFO_V2 info_2; | 1774 | struct _ATOM_POWERPLAY_INFO_V2 info_2; |
1775 | struct _ATOM_POWERPLAY_INFO_V3 info_3; | 1775 | struct _ATOM_POWERPLAY_INFO_V3 info_3; |
1776 | struct _ATOM_PPLIB_POWERPLAYTABLE info_4; | 1776 | struct _ATOM_PPLIB_POWERPLAYTABLE pplib; |
1777 | }; | 1777 | }; |
1778 | 1778 | ||
1779 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | 1779 | union pplib_clock_info { |
1780 | struct _ATOM_PPLIB_R600_CLOCK_INFO r600; | ||
1781 | struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; | ||
1782 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; | ||
1783 | }; | ||
1784 | |||
1785 | union pplib_power_state { | ||
1786 | struct _ATOM_PPLIB_STATE v1; | ||
1787 | struct _ATOM_PPLIB_STATE_V2 v2; | ||
1788 | }; | ||
1789 | |||
1790 | static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev, | ||
1791 | int state_index, | ||
1792 | u32 misc, u32 misc2) | ||
1793 | { | ||
1794 | rdev->pm.power_state[state_index].misc = misc; | ||
1795 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
1796 | /* order matters! */ | ||
1797 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1798 | rdev->pm.power_state[state_index].type = | ||
1799 | POWER_STATE_TYPE_POWERSAVE; | ||
1800 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1801 | rdev->pm.power_state[state_index].type = | ||
1802 | POWER_STATE_TYPE_BATTERY; | ||
1803 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1804 | rdev->pm.power_state[state_index].type = | ||
1805 | POWER_STATE_TYPE_BATTERY; | ||
1806 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1807 | rdev->pm.power_state[state_index].type = | ||
1808 | POWER_STATE_TYPE_BALANCED; | ||
1809 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1810 | rdev->pm.power_state[state_index].type = | ||
1811 | POWER_STATE_TYPE_PERFORMANCE; | ||
1812 | rdev->pm.power_state[state_index].flags &= | ||
1813 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1814 | } | ||
1815 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1816 | rdev->pm.power_state[state_index].type = | ||
1817 | POWER_STATE_TYPE_BALANCED; | ||
1818 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1819 | rdev->pm.power_state[state_index].type = | ||
1820 | POWER_STATE_TYPE_DEFAULT; | ||
1821 | rdev->pm.default_power_state_index = state_index; | ||
1822 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1823 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1824 | } else if (state_index == 0) { | ||
1825 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
1826 | RADEON_PM_MODE_NO_DISPLAY; | ||
1827 | } | ||
1828 | } | ||
1829 | |||
1830 | static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) | ||
1780 | { | 1831 | { |
1781 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1832 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1833 | u32 misc, misc2 = 0; | ||
1834 | int num_modes = 0, i; | ||
1835 | int state_index = 0; | ||
1836 | struct radeon_i2c_bus_rec i2c_bus; | ||
1837 | union power_info *power_info; | ||
1782 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | 1838 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
1783 | u16 data_offset; | 1839 | u16 data_offset; |
1784 | u8 frev, crev; | 1840 | u8 frev, crev; |
1785 | u32 misc, misc2 = 0, sclk, mclk; | ||
1786 | union power_info *power_info; | ||
1787 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; | ||
1788 | struct _ATOM_PPLIB_STATE *power_state; | ||
1789 | int num_modes = 0, i, j; | ||
1790 | int state_index = 0, mode_index = 0; | ||
1791 | struct radeon_i2c_bus_rec i2c_bus; | ||
1792 | |||
1793 | rdev->pm.default_power_state_index = -1; | ||
1794 | 1841 | ||
1795 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1842 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, |
1796 | &frev, &crev, &data_offset)) { | 1843 | &frev, &crev, &data_offset)) |
1797 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); | 1844 | return state_index; |
1798 | if (frev < 4) { | 1845 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
1799 | /* add the i2c bus for thermal/fan chip */ | 1846 | |
1800 | if (power_info->info.ucOverdriveThermalController > 0) { | 1847 | /* add the i2c bus for thermal/fan chip */ |
1801 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", | 1848 | if (power_info->info.ucOverdriveThermalController > 0) { |
1802 | thermal_controller_names[power_info->info.ucOverdriveThermalController], | 1849 | DRM_INFO("Possible %s thermal controller at 0x%02x\n", |
1803 | power_info->info.ucOverdriveControllerAddress >> 1); | 1850 | thermal_controller_names[power_info->info.ucOverdriveThermalController], |
1804 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); | 1851 | power_info->info.ucOverdriveControllerAddress >> 1); |
1805 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | 1852 | i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); |
1806 | if (rdev->pm.i2c_bus) { | 1853 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
1807 | struct i2c_board_info info = { }; | 1854 | if (rdev->pm.i2c_bus) { |
1808 | const char *name = thermal_controller_names[power_info->info. | 1855 | struct i2c_board_info info = { }; |
1809 | ucOverdriveThermalController]; | 1856 | const char *name = thermal_controller_names[power_info->info. |
1810 | info.addr = power_info->info.ucOverdriveControllerAddress >> 1; | 1857 | ucOverdriveThermalController]; |
1811 | strlcpy(info.type, name, sizeof(info.type)); | 1858 | info.addr = power_info->info.ucOverdriveControllerAddress >> 1; |
1812 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | 1859 | strlcpy(info.type, name, sizeof(info.type)); |
1813 | } | 1860 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); |
1861 | } | ||
1862 | } | ||
1863 | num_modes = power_info->info.ucNumOfPowerModeEntries; | ||
1864 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | ||
1865 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | ||
1866 | /* last mode is usually default, array is low to high */ | ||
1867 | for (i = 0; i < num_modes; i++) { | ||
1868 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | ||
1869 | switch (frev) { | ||
1870 | case 1: | ||
1871 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1872 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1873 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | ||
1874 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1875 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | ||
1876 | /* skip invalid modes */ | ||
1877 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1878 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1879 | continue; | ||
1880 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1881 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | ||
1882 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | ||
1883 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1884 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1885 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1886 | VOLTAGE_GPIO; | ||
1887 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1888 | radeon_lookup_gpio(rdev, | ||
1889 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1890 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1891 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1892 | true; | ||
1893 | else | ||
1894 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1895 | false; | ||
1896 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1897 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1898 | VOLTAGE_VDDC; | ||
1899 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1900 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1814 | } | 1901 | } |
1815 | num_modes = power_info->info.ucNumOfPowerModeEntries; | 1902 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
1816 | if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) | 1903 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0); |
1817 | num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; | 1904 | state_index++; |
1818 | /* last mode is usually default, array is low to high */ | 1905 | break; |
1819 | for (i = 0; i < num_modes; i++) { | 1906 | case 2: |
1820 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; | 1907 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
1821 | switch (frev) { | 1908 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
1822 | case 1: | 1909 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); |
1823 | rdev->pm.power_state[state_index].num_clock_modes = 1; | 1910 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
1824 | rdev->pm.power_state[state_index].clock_info[0].mclk = | 1911 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); |
1825 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); | 1912 | /* skip invalid modes */ |
1826 | rdev->pm.power_state[state_index].clock_info[0].sclk = | 1913 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || |
1827 | le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); | 1914 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) |
1828 | /* skip invalid modes */ | 1915 | continue; |
1829 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | 1916 | rdev->pm.power_state[state_index].pcie_lanes = |
1830 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | 1917 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; |
1831 | continue; | 1918 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); |
1832 | rdev->pm.power_state[state_index].pcie_lanes = | 1919 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); |
1833 | power_info->info.asPowerPlayInfo[i].ucNumPciELanes; | 1920 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || |
1834 | misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); | 1921 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { |
1835 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | 1922 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1836 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | 1923 | VOLTAGE_GPIO; |
1837 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1924 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = |
1838 | VOLTAGE_GPIO; | 1925 | radeon_lookup_gpio(rdev, |
1839 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | 1926 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); |
1840 | radeon_lookup_gpio(rdev, | 1927 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) |
1841 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); | 1928 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = |
1842 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | 1929 | true; |
1843 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | 1930 | else |
1844 | true; | 1931 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = |
1845 | else | 1932 | false; |
1846 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | 1933 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { |
1847 | false; | 1934 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = |
1848 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | 1935 | VOLTAGE_VDDC; |
1849 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | 1936 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = |
1850 | VOLTAGE_VDDC; | 1937 | power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; |
1851 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1852 | power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1853 | } | ||
1854 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1855 | rdev->pm.power_state[state_index].misc = misc; | ||
1856 | /* order matters! */ | ||
1857 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1858 | rdev->pm.power_state[state_index].type = | ||
1859 | POWER_STATE_TYPE_POWERSAVE; | ||
1860 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1861 | rdev->pm.power_state[state_index].type = | ||
1862 | POWER_STATE_TYPE_BATTERY; | ||
1863 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1864 | rdev->pm.power_state[state_index].type = | ||
1865 | POWER_STATE_TYPE_BATTERY; | ||
1866 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1867 | rdev->pm.power_state[state_index].type = | ||
1868 | POWER_STATE_TYPE_BALANCED; | ||
1869 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1870 | rdev->pm.power_state[state_index].type = | ||
1871 | POWER_STATE_TYPE_PERFORMANCE; | ||
1872 | rdev->pm.power_state[state_index].flags &= | ||
1873 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1874 | } | ||
1875 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1876 | rdev->pm.power_state[state_index].type = | ||
1877 | POWER_STATE_TYPE_DEFAULT; | ||
1878 | rdev->pm.default_power_state_index = state_index; | ||
1879 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1880 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1881 | rdev->pm.power_state[state_index].flags &= | ||
1882 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1883 | } else if (state_index == 0) { | ||
1884 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
1885 | RADEON_PM_MODE_NO_DISPLAY; | ||
1886 | } | ||
1887 | state_index++; | ||
1888 | break; | ||
1889 | case 2: | ||
1890 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1891 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1892 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); | ||
1893 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1894 | le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); | ||
1895 | /* skip invalid modes */ | ||
1896 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1897 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1898 | continue; | ||
1899 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1900 | power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; | ||
1901 | misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); | ||
1902 | misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); | ||
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_2.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_2.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1921 | } | ||
1922 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1923 | rdev->pm.power_state[state_index].misc = misc; | ||
1924 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
1925 | /* order matters! */ | ||
1926 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
1927 | rdev->pm.power_state[state_index].type = | ||
1928 | POWER_STATE_TYPE_POWERSAVE; | ||
1929 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
1930 | rdev->pm.power_state[state_index].type = | ||
1931 | POWER_STATE_TYPE_BATTERY; | ||
1932 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
1933 | rdev->pm.power_state[state_index].type = | ||
1934 | POWER_STATE_TYPE_BATTERY; | ||
1935 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
1936 | rdev->pm.power_state[state_index].type = | ||
1937 | POWER_STATE_TYPE_BALANCED; | ||
1938 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
1939 | rdev->pm.power_state[state_index].type = | ||
1940 | POWER_STATE_TYPE_PERFORMANCE; | ||
1941 | rdev->pm.power_state[state_index].flags &= | ||
1942 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1943 | } | ||
1944 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
1945 | rdev->pm.power_state[state_index].type = | ||
1946 | POWER_STATE_TYPE_BALANCED; | ||
1947 | if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT) | ||
1948 | rdev->pm.power_state[state_index].flags &= | ||
1949 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1950 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
1951 | rdev->pm.power_state[state_index].type = | ||
1952 | POWER_STATE_TYPE_DEFAULT; | ||
1953 | rdev->pm.default_power_state_index = state_index; | ||
1954 | rdev->pm.power_state[state_index].default_clock_mode = | ||
1955 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
1956 | rdev->pm.power_state[state_index].flags &= | ||
1957 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1958 | } else if (state_index == 0) { | ||
1959 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
1960 | RADEON_PM_MODE_NO_DISPLAY; | ||
1961 | } | ||
1962 | state_index++; | ||
1963 | break; | ||
1964 | case 3: | ||
1965 | rdev->pm.power_state[state_index].num_clock_modes = 1; | ||
1966 | rdev->pm.power_state[state_index].clock_info[0].mclk = | ||
1967 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); | ||
1968 | rdev->pm.power_state[state_index].clock_info[0].sclk = | ||
1969 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); | ||
1970 | /* skip invalid modes */ | ||
1971 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1972 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1973 | continue; | ||
1974 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1975 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
1976 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
1977 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
1978 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1979 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1980 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1981 | VOLTAGE_GPIO; | ||
1982 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1983 | radeon_lookup_gpio(rdev, | ||
1984 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1985 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1986 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1987 | true; | ||
1988 | else | ||
1989 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1990 | false; | ||
1991 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1992 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1993 | VOLTAGE_VDDC; | ||
1994 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1995 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1996 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
1997 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
1998 | true; | ||
1999 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
2000 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
2001 | } | ||
2002 | } | ||
2003 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
2004 | rdev->pm.power_state[state_index].misc = misc; | ||
2005 | rdev->pm.power_state[state_index].misc2 = misc2; | ||
2006 | /* order matters! */ | ||
2007 | if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) | ||
2008 | rdev->pm.power_state[state_index].type = | ||
2009 | POWER_STATE_TYPE_POWERSAVE; | ||
2010 | if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) | ||
2011 | rdev->pm.power_state[state_index].type = | ||
2012 | POWER_STATE_TYPE_BATTERY; | ||
2013 | if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) | ||
2014 | rdev->pm.power_state[state_index].type = | ||
2015 | POWER_STATE_TYPE_BATTERY; | ||
2016 | if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) | ||
2017 | rdev->pm.power_state[state_index].type = | ||
2018 | POWER_STATE_TYPE_BALANCED; | ||
2019 | if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { | ||
2020 | rdev->pm.power_state[state_index].type = | ||
2021 | POWER_STATE_TYPE_PERFORMANCE; | ||
2022 | rdev->pm.power_state[state_index].flags &= | ||
2023 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
2024 | } | ||
2025 | if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) | ||
2026 | rdev->pm.power_state[state_index].type = | ||
2027 | POWER_STATE_TYPE_BALANCED; | ||
2028 | if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { | ||
2029 | rdev->pm.power_state[state_index].type = | ||
2030 | POWER_STATE_TYPE_DEFAULT; | ||
2031 | rdev->pm.default_power_state_index = state_index; | ||
2032 | rdev->pm.power_state[state_index].default_clock_mode = | ||
2033 | &rdev->pm.power_state[state_index].clock_info[0]; | ||
2034 | } else if (state_index == 0) { | ||
2035 | rdev->pm.power_state[state_index].clock_info[0].flags |= | ||
2036 | RADEON_PM_MODE_NO_DISPLAY; | ||
2037 | } | ||
2038 | state_index++; | ||
2039 | break; | ||
2040 | } | ||
2041 | } | 1938 | } |
2042 | /* last mode is usually default */ | 1939 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
2043 | if (rdev->pm.default_power_state_index == -1) { | 1940 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); |
2044 | rdev->pm.power_state[state_index - 1].type = | 1941 | state_index++; |
2045 | POWER_STATE_TYPE_DEFAULT; | 1942 | break; |
2046 | rdev->pm.default_power_state_index = state_index - 1; | 1943 | case 3: |
2047 | rdev->pm.power_state[state_index - 1].default_clock_mode = | 1944 | rdev->pm.power_state[state_index].num_clock_modes = 1; |
2048 | &rdev->pm.power_state[state_index - 1].clock_info[0]; | 1945 | rdev->pm.power_state[state_index].clock_info[0].mclk = |
2049 | rdev->pm.power_state[state_index].flags &= | 1946 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); |
2050 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | 1947 | rdev->pm.power_state[state_index].clock_info[0].sclk = |
2051 | rdev->pm.power_state[state_index].misc = 0; | 1948 | le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); |
2052 | rdev->pm.power_state[state_index].misc2 = 0; | 1949 | /* skip invalid modes */ |
1950 | if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || | ||
1951 | (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) | ||
1952 | continue; | ||
1953 | rdev->pm.power_state[state_index].pcie_lanes = | ||
1954 | power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; | ||
1955 | misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); | ||
1956 | misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); | ||
1957 | if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || | ||
1958 | (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { | ||
1959 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1960 | VOLTAGE_GPIO; | ||
1961 | rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = | ||
1962 | radeon_lookup_gpio(rdev, | ||
1963 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); | ||
1964 | if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) | ||
1965 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1966 | true; | ||
1967 | else | ||
1968 | rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = | ||
1969 | false; | ||
1970 | } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { | ||
1971 | rdev->pm.power_state[state_index].clock_info[0].voltage.type = | ||
1972 | VOLTAGE_VDDC; | ||
1973 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = | ||
1974 | power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; | ||
1975 | if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { | ||
1976 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = | ||
1977 | true; | ||
1978 | rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = | ||
1979 | power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; | ||
1980 | } | ||
2053 | } | 1981 | } |
1982 | rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1983 | radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); | ||
1984 | state_index++; | ||
1985 | break; | ||
1986 | } | ||
1987 | } | ||
1988 | /* last mode is usually default */ | ||
1989 | if (rdev->pm.default_power_state_index == -1) { | ||
1990 | rdev->pm.power_state[state_index - 1].type = | ||
1991 | POWER_STATE_TYPE_DEFAULT; | ||
1992 | rdev->pm.default_power_state_index = state_index - 1; | ||
1993 | rdev->pm.power_state[state_index - 1].default_clock_mode = | ||
1994 | &rdev->pm.power_state[state_index - 1].clock_info[0]; | ||
1995 | rdev->pm.power_state[state_index].flags &= | ||
1996 | ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | ||
1997 | rdev->pm.power_state[state_index].misc = 0; | ||
1998 | rdev->pm.power_state[state_index].misc2 = 0; | ||
1999 | } | ||
2000 | return state_index; | ||
2001 | } | ||
2002 | |||
2003 | static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev, | ||
2004 | ATOM_PPLIB_THERMALCONTROLLER *controller) | ||
2005 | { | ||
2006 | struct radeon_i2c_bus_rec i2c_bus; | ||
2007 | |||
2008 | /* add the i2c bus for thermal/fan chip */ | ||
2009 | if (controller->ucType > 0) { | ||
2010 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { | ||
2011 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2012 | (controller->ucFanParameters & | ||
2013 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2014 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | ||
2015 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | ||
2016 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2017 | (controller->ucFanParameters & | ||
2018 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2019 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
2020 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
2021 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2022 | (controller->ucFanParameters & | ||
2023 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2024 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
2025 | } else if ((controller->ucType == | ||
2026 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | ||
2027 | (controller->ucType == | ||
2028 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { | ||
2029 | DRM_INFO("Special thermal controller config\n"); | ||
2054 | } else { | 2030 | } else { |
2055 | int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); | 2031 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", |
2056 | uint8_t fw_frev, fw_crev; | 2032 | pp_lib_thermal_controller_names[controller->ucType], |
2057 | uint16_t fw_data_offset, vddc = 0; | 2033 | controller->ucI2cAddress >> 1, |
2058 | union firmware_info *firmware_info; | 2034 | (controller->ucFanParameters & |
2059 | ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; | 2035 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); |
2060 | 2036 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | |
2061 | if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, | 2037 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); |
2062 | &fw_frev, &fw_crev, &fw_data_offset)) { | 2038 | if (rdev->pm.i2c_bus) { |
2063 | firmware_info = | 2039 | struct i2c_board_info info = { }; |
2064 | (union firmware_info *)(mode_info->atom_context->bios + | 2040 | const char *name = pp_lib_thermal_controller_names[controller->ucType]; |
2065 | fw_data_offset); | 2041 | info.addr = controller->ucI2cAddress >> 1; |
2066 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; | 2042 | strlcpy(info.type, name, sizeof(info.type)); |
2043 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
2067 | } | 2044 | } |
2045 | } | ||
2046 | } | ||
2047 | } | ||
2068 | 2048 | ||
2069 | /* add the i2c bus for thermal/fan chip */ | 2049 | static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) |
2070 | if (controller->ucType > 0) { | 2050 | { |
2071 | if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { | 2051 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2072 | DRM_INFO("Internal thermal controller %s fan control\n", | 2052 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
2073 | (controller->ucFanParameters & | 2053 | u8 frev, crev; |
2074 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | 2054 | u16 data_offset; |
2075 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; | 2055 | union firmware_info *firmware_info; |
2076 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { | 2056 | u16 vddc = 0; |
2077 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2078 | (controller->ucFanParameters & | ||
2079 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2080 | rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; | ||
2081 | } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { | ||
2082 | DRM_INFO("Internal thermal controller %s fan control\n", | ||
2083 | (controller->ucFanParameters & | ||
2084 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2085 | rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; | ||
2086 | } else if ((controller->ucType == | ||
2087 | ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || | ||
2088 | (controller->ucType == | ||
2089 | ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { | ||
2090 | DRM_INFO("Special thermal controller config\n"); | ||
2091 | } else { | ||
2092 | DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", | ||
2093 | pp_lib_thermal_controller_names[controller->ucType], | ||
2094 | controller->ucI2cAddress >> 1, | ||
2095 | (controller->ucFanParameters & | ||
2096 | ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); | ||
2097 | i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); | ||
2098 | rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); | ||
2099 | if (rdev->pm.i2c_bus) { | ||
2100 | struct i2c_board_info info = { }; | ||
2101 | const char *name = pp_lib_thermal_controller_names[controller->ucType]; | ||
2102 | info.addr = controller->ucI2cAddress >> 1; | ||
2103 | strlcpy(info.type, name, sizeof(info.type)); | ||
2104 | i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); | ||
2105 | } | ||
2106 | 2057 | ||
2107 | } | 2058 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
2108 | } | 2059 | &frev, &crev, &data_offset)) { |
2109 | /* first mode is usually default, followed by low to high */ | 2060 | firmware_info = |
2110 | for (i = 0; i < power_info->info_4.ucNumStates; i++) { | 2061 | (union firmware_info *)(mode_info->atom_context->bios + |
2111 | mode_index = 0; | 2062 | data_offset); |
2112 | power_state = (struct _ATOM_PPLIB_STATE *) | 2063 | vddc = firmware_info->info_14.usBootUpVDDCVoltage; |
2113 | (mode_info->atom_context->bios + | 2064 | } |
2114 | data_offset + | 2065 | |
2115 | le16_to_cpu(power_info->info_4.usStateArrayOffset) + | 2066 | return vddc; |
2116 | i * power_info->info_4.ucStateEntrySize); | 2067 | } |
2117 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | 2068 | |
2118 | (mode_info->atom_context->bios + | 2069 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
2119 | data_offset + | 2070 | int state_index, int mode_index, |
2120 | le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + | 2071 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) |
2121 | (power_state->ucNonClockStateIndex * | 2072 | { |
2122 | power_info->info_4.ucNonClockSize)); | 2073 | int j; |
2123 | for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { | 2074 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
2124 | if (rdev->flags & RADEON_IS_IGP) { | 2075 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
2125 | struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = | 2076 | u16 vddc = radeon_atombios_get_default_vddc(rdev); |
2126 | (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) | 2077 | |
2127 | (mode_info->atom_context->bios + | 2078 | rdev->pm.power_state[state_index].misc = misc; |
2128 | data_offset + | 2079 | rdev->pm.power_state[state_index].misc2 = misc2; |
2129 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2080 | rdev->pm.power_state[state_index].pcie_lanes = |
2130 | (power_state->ucClockStateIndices[j] * | 2081 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> |
2131 | power_info->info_4.ucClockInfoSize)); | 2082 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; |
2132 | sclk = le16_to_cpu(clock_info->usLowEngineClockLow); | 2083 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { |
2133 | sclk |= clock_info->ucLowEngineClockHigh << 16; | 2084 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: |
2134 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2085 | rdev->pm.power_state[state_index].type = |
2135 | /* skip invalid modes */ | 2086 | POWER_STATE_TYPE_BATTERY; |
2136 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) | 2087 | break; |
2137 | continue; | 2088 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: |
2138 | /* voltage works differently on IGPs */ | 2089 | rdev->pm.power_state[state_index].type = |
2139 | mode_index++; | 2090 | POWER_STATE_TYPE_BALANCED; |
2140 | } else if (ASIC_IS_DCE4(rdev)) { | 2091 | break; |
2141 | struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = | 2092 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: |
2142 | (struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *) | 2093 | rdev->pm.power_state[state_index].type = |
2143 | (mode_info->atom_context->bios + | 2094 | POWER_STATE_TYPE_PERFORMANCE; |
2144 | data_offset + | 2095 | break; |
2145 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2096 | case ATOM_PPLIB_CLASSIFICATION_UI_NONE: |
2146 | (power_state->ucClockStateIndices[j] * | 2097 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) |
2147 | power_info->info_4.ucClockInfoSize)); | 2098 | rdev->pm.power_state[state_index].type = |
2148 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | 2099 | POWER_STATE_TYPE_PERFORMANCE; |
2149 | sclk |= clock_info->ucEngineClockHigh << 16; | 2100 | break; |
2150 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | 2101 | } |
2151 | mclk |= clock_info->ucMemoryClockHigh << 16; | 2102 | rdev->pm.power_state[state_index].flags = 0; |
2152 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | 2103 | if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) |
2153 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2104 | rdev->pm.power_state[state_index].flags |= |
2154 | /* skip invalid modes */ | 2105 | RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; |
2155 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | 2106 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { |
2156 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | 2107 | rdev->pm.power_state[state_index].type = |
2157 | continue; | 2108 | POWER_STATE_TYPE_DEFAULT; |
2158 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2109 | rdev->pm.default_power_state_index = state_index; |
2159 | VOLTAGE_SW; | 2110 | rdev->pm.power_state[state_index].default_clock_mode = |
2160 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2111 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; |
2161 | clock_info->usVDDC; | 2112 | /* patch the table values with the default slck/mclk from firmware info */ |
2162 | /* XXX usVDDCI */ | 2113 | for (j = 0; j < mode_index; j++) { |
2163 | mode_index++; | 2114 | rdev->pm.power_state[state_index].clock_info[j].mclk = |
2164 | } else { | 2115 | rdev->clock.default_mclk; |
2165 | struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = | 2116 | rdev->pm.power_state[state_index].clock_info[j].sclk = |
2166 | (struct _ATOM_PPLIB_R600_CLOCK_INFO *) | 2117 | rdev->clock.default_sclk; |
2167 | (mode_info->atom_context->bios + | 2118 | if (vddc) |
2168 | data_offset + | 2119 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = |
2169 | le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + | 2120 | vddc; |
2170 | (power_state->ucClockStateIndices[j] * | 2121 | } |
2171 | power_info->info_4.ucClockInfoSize)); | 2122 | } |
2172 | sclk = le16_to_cpu(clock_info->usEngineClockLow); | 2123 | } |
2173 | sclk |= clock_info->ucEngineClockHigh << 16; | 2124 | |
2174 | mclk = le16_to_cpu(clock_info->usMemoryClockLow); | 2125 | static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, |
2175 | mclk |= clock_info->ucMemoryClockHigh << 16; | 2126 | int state_index, int mode_index, |
2176 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; | 2127 | union pplib_clock_info *clock_info) |
2177 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; | 2128 | { |
2178 | /* skip invalid modes */ | 2129 | u32 sclk, mclk; |
2179 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || | 2130 | |
2180 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) | 2131 | if (rdev->flags & RADEON_IS_IGP) { |
2181 | continue; | 2132 | sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); |
2182 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = | 2133 | sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; |
2183 | VOLTAGE_SW; | 2134 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2184 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2135 | } else if (ASIC_IS_DCE4(rdev)) { |
2185 | clock_info->usVDDC; | 2136 | sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); |
2186 | mode_index++; | 2137 | sclk |= clock_info->evergreen.ucEngineClockHigh << 16; |
2187 | } | 2138 | mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow); |
2188 | } | 2139 | mclk |= clock_info->evergreen.ucMemoryClockHigh << 16; |
2189 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | 2140 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; |
2190 | if (mode_index) { | 2141 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2191 | misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | 2142 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
2192 | misc2 = le16_to_cpu(non_clock_info->usClassification); | 2143 | VOLTAGE_SW; |
2193 | rdev->pm.power_state[state_index].misc = misc; | 2144 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
2194 | rdev->pm.power_state[state_index].misc2 = misc2; | 2145 | clock_info->evergreen.usVDDC; |
2195 | rdev->pm.power_state[state_index].pcie_lanes = | 2146 | } else { |
2196 | ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> | 2147 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); |
2197 | ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; | 2148 | sclk |= clock_info->r600.ucEngineClockHigh << 16; |
2198 | switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { | 2149 | mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); |
2199 | case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: | 2150 | mclk |= clock_info->r600.ucMemoryClockHigh << 16; |
2200 | rdev->pm.power_state[state_index].type = | 2151 | rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; |
2201 | POWER_STATE_TYPE_BATTERY; | 2152 | rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; |
2202 | break; | 2153 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = |
2203 | case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: | 2154 | VOLTAGE_SW; |
2204 | rdev->pm.power_state[state_index].type = | 2155 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
2205 | POWER_STATE_TYPE_BALANCED; | 2156 | clock_info->r600.usVDDC; |
2206 | break; | 2157 | } |
2207 | case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: | 2158 | |
2208 | rdev->pm.power_state[state_index].type = | 2159 | if (rdev->flags & RADEON_IS_IGP) { |
2209 | POWER_STATE_TYPE_PERFORMANCE; | 2160 | /* skip invalid modes */ |
2210 | break; | 2161 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) |
2211 | case ATOM_PPLIB_CLASSIFICATION_UI_NONE: | 2162 | return false; |
2212 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) | 2163 | } else { |
2213 | rdev->pm.power_state[state_index].type = | 2164 | /* skip invalid modes */ |
2214 | POWER_STATE_TYPE_PERFORMANCE; | 2165 | if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || |
2215 | break; | 2166 | (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) |
2216 | } | 2167 | return false; |
2217 | rdev->pm.power_state[state_index].flags = 0; | 2168 | } |
2218 | if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) | 2169 | return true; |
2219 | rdev->pm.power_state[state_index].flags |= | 2170 | } |
2220 | RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; | 2171 | |
2221 | if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { | 2172 | static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) |
2222 | rdev->pm.power_state[state_index].type = | 2173 | { |
2223 | POWER_STATE_TYPE_DEFAULT; | 2174 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2224 | rdev->pm.default_power_state_index = state_index; | 2175 | struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; |
2225 | rdev->pm.power_state[state_index].default_clock_mode = | 2176 | union pplib_power_state *power_state; |
2226 | &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; | 2177 | int i, j; |
2227 | /* patch the table values with the default slck/mclk from firmware info */ | 2178 | int state_index = 0, mode_index = 0; |
2228 | for (j = 0; j < mode_index; j++) { | 2179 | union pplib_clock_info *clock_info; |
2229 | rdev->pm.power_state[state_index].clock_info[j].mclk = | 2180 | bool valid; |
2230 | rdev->clock.default_mclk; | 2181 | union power_info *power_info; |
2231 | rdev->pm.power_state[state_index].clock_info[j].sclk = | 2182 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); |
2232 | rdev->clock.default_sclk; | 2183 | u16 data_offset; |
2233 | if (vddc) | 2184 | u8 frev, crev; |
2234 | rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = | 2185 | |
2235 | vddc; | 2186 | if (!atom_parse_data_header(mode_info->atom_context, index, NULL, |
2236 | } | 2187 | &frev, &crev, &data_offset)) |
2237 | } | 2188 | return state_index; |
2238 | state_index++; | 2189 | power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); |
2239 | } | 2190 | |
2240 | } | 2191 | radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); |
2241 | /* if multiple clock modes, mark the lowest as no display */ | 2192 | /* first mode is usually default, followed by low to high */ |
2242 | for (i = 0; i < state_index; i++) { | 2193 | for (i = 0; i < power_info->pplib.ucNumStates; i++) { |
2243 | if (rdev->pm.power_state[i].num_clock_modes > 1) | 2194 | mode_index = 0; |
2244 | rdev->pm.power_state[i].clock_info[0].flags |= | 2195 | power_state = (union pplib_power_state *) |
2245 | RADEON_PM_MODE_NO_DISPLAY; | 2196 | (mode_info->atom_context->bios + data_offset + |
2246 | } | 2197 | le16_to_cpu(power_info->pplib.usStateArrayOffset) + |
2247 | /* first mode is usually default */ | 2198 | i * power_info->pplib.ucStateEntrySize); |
2248 | if (rdev->pm.default_power_state_index == -1) { | 2199 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) |
2249 | rdev->pm.power_state[0].type = | 2200 | (mode_info->atom_context->bios + data_offset + |
2250 | POWER_STATE_TYPE_DEFAULT; | 2201 | le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + |
2251 | rdev->pm.default_power_state_index = 0; | 2202 | (power_state->v1.ucNonClockStateIndex * |
2252 | rdev->pm.power_state[0].default_clock_mode = | 2203 | power_info->pplib.ucNonClockSize)); |
2253 | &rdev->pm.power_state[0].clock_info[0]; | 2204 | for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { |
2254 | } | 2205 | clock_info = (union pplib_clock_info *) |
2206 | (mode_info->atom_context->bios + data_offset + | ||
2207 | le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + | ||
2208 | (power_state->v1.ucClockStateIndices[j] * | ||
2209 | power_info->pplib.ucClockInfoSize)); | ||
2210 | valid = radeon_atombios_parse_pplib_clock_info(rdev, | ||
2211 | state_index, mode_index, | ||
2212 | clock_info); | ||
2213 | if (valid) | ||
2214 | mode_index++; | ||
2215 | } | ||
2216 | rdev->pm.power_state[state_index].num_clock_modes = mode_index; | ||
2217 | if (mode_index) { | ||
2218 | radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, | ||
2219 | non_clock_info); | ||
2220 | state_index++; | ||
2221 | } | ||
2222 | } | ||
2223 | /* if multiple clock modes, mark the lowest as no display */ | ||
2224 | for (i = 0; i < state_index; i++) { | ||
2225 | if (rdev->pm.power_state[i].num_clock_modes > 1) | ||
2226 | rdev->pm.power_state[i].clock_info[0].flags |= | ||
2227 | RADEON_PM_MODE_NO_DISPLAY; | ||
2228 | } | ||
2229 | /* first mode is usually default */ | ||
2230 | if (rdev->pm.default_power_state_index == -1) { | ||
2231 | rdev->pm.power_state[0].type = | ||
2232 | POWER_STATE_TYPE_DEFAULT; | ||
2233 | rdev->pm.default_power_state_index = 0; | ||
2234 | rdev->pm.power_state[0].default_clock_mode = | ||
2235 | &rdev->pm.power_state[0].clock_info[0]; | ||
2236 | } | ||
2237 | return state_index; | ||
2238 | } | ||
2239 | |||
2240 | void radeon_atombios_get_power_modes(struct radeon_device *rdev) | ||
2241 | { | ||
2242 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
2243 | int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); | ||
2244 | u16 data_offset; | ||
2245 | u8 frev, crev; | ||
2246 | int state_index = 0; | ||
2247 | |||
2248 | rdev->pm.default_power_state_index = -1; | ||
2249 | |||
2250 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
2251 | &frev, &crev, &data_offset)) { | ||
2252 | switch (frev) { | ||
2253 | case 1: | ||
2254 | case 2: | ||
2255 | case 3: | ||
2256 | state_index = radeon_atombios_parse_power_table_1_3(rdev); | ||
2257 | break; | ||
2258 | case 4: | ||
2259 | case 5: | ||
2260 | state_index = radeon_atombios_parse_power_table_4_5(rdev); | ||
2261 | break; | ||
2262 | default: | ||
2263 | break; | ||
2255 | } | 2264 | } |
2256 | } else { | 2265 | } else { |
2257 | /* add the default mode */ | 2266 | /* add the default mode */ |