diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2015-12-18 11:25:16 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-01-13 12:12:43 -0500 |
commit | 044c0629b55d73235161557a48870d663d0072f5 (patch) | |
tree | 18ddd5b338f2b866e80d2d5b8718b900cd5d1133 | |
parent | d83b1e8132f91ba9e038b5206dc81d32ecac1f75 (diff) |
drm/amdgpu/cz: add code to enable forcing VCE clocks
VCE DPM works similarly to SCLK DPM. Add a similar interface
for VCE for forcing the VCE clocks.
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cz_dpm.c | 98 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/cz_dpm.h | 1 |
2 files changed, 98 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c index 5ccea9f9c634..02cba49f13a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.c | |||
@@ -1770,7 +1770,6 @@ static int cz_dpm_unforce_dpm_levels(struct amdgpu_device *adev) | |||
1770 | return 0; | 1770 | return 0; |
1771 | } | 1771 | } |
1772 | 1772 | ||
1773 | |||
1774 | static int cz_dpm_uvd_force_highest(struct amdgpu_device *adev) | 1773 | static int cz_dpm_uvd_force_highest(struct amdgpu_device *adev) |
1775 | { | 1774 | { |
1776 | struct cz_power_info *pi = cz_get_pi(adev); | 1775 | struct cz_power_info *pi = cz_get_pi(adev); |
@@ -1868,6 +1867,103 @@ static int cz_dpm_unforce_uvd_dpm_levels(struct amdgpu_device *adev) | |||
1868 | return 0; | 1867 | return 0; |
1869 | } | 1868 | } |
1870 | 1869 | ||
1870 | static int cz_dpm_vce_force_highest(struct amdgpu_device *adev) | ||
1871 | { | ||
1872 | struct cz_power_info *pi = cz_get_pi(adev); | ||
1873 | int ret = 0; | ||
1874 | |||
1875 | if (pi->vce_dpm.soft_min_clk != pi->vce_dpm.soft_max_clk) { | ||
1876 | pi->vce_dpm.soft_min_clk = | ||
1877 | pi->vce_dpm.soft_max_clk; | ||
1878 | ret = cz_send_msg_to_smc_with_parameter(adev, | ||
1879 | PPSMC_MSG_SetEclkSoftMin, | ||
1880 | cz_get_eclk_level(adev, | ||
1881 | pi->vce_dpm.soft_min_clk, | ||
1882 | PPSMC_MSG_SetEclkSoftMin)); | ||
1883 | if (ret) | ||
1884 | return ret; | ||
1885 | } | ||
1886 | |||
1887 | return ret; | ||
1888 | } | ||
1889 | |||
1890 | static int cz_dpm_vce_force_lowest(struct amdgpu_device *adev) | ||
1891 | { | ||
1892 | struct cz_power_info *pi = cz_get_pi(adev); | ||
1893 | int ret = 0; | ||
1894 | |||
1895 | if (pi->vce_dpm.soft_max_clk != pi->vce_dpm.soft_min_clk) { | ||
1896 | pi->vce_dpm.soft_max_clk = pi->vce_dpm.soft_min_clk; | ||
1897 | ret = cz_send_msg_to_smc_with_parameter(adev, | ||
1898 | PPSMC_MSG_SetEclkSoftMax, | ||
1899 | cz_get_uvd_level(adev, | ||
1900 | pi->vce_dpm.soft_max_clk, | ||
1901 | PPSMC_MSG_SetEclkSoftMax)); | ||
1902 | if (ret) | ||
1903 | return ret; | ||
1904 | } | ||
1905 | |||
1906 | return ret; | ||
1907 | } | ||
1908 | |||
1909 | static uint32_t cz_dpm_get_max_vce_level(struct amdgpu_device *adev) | ||
1910 | { | ||
1911 | struct cz_power_info *pi = cz_get_pi(adev); | ||
1912 | |||
1913 | if (!pi->max_vce_level) { | ||
1914 | cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxEclkLevel); | ||
1915 | pi->max_vce_level = cz_get_argument(adev) + 1; | ||
1916 | } | ||
1917 | |||
1918 | if (pi->max_vce_level > CZ_MAX_HARDWARE_POWERLEVELS) { | ||
1919 | DRM_ERROR("Invalid max vce level!\n"); | ||
1920 | return -EINVAL; | ||
1921 | } | ||
1922 | |||
1923 | return pi->max_vce_level; | ||
1924 | } | ||
1925 | |||
1926 | static int cz_dpm_unforce_vce_dpm_levels(struct amdgpu_device *adev) | ||
1927 | { | ||
1928 | struct cz_power_info *pi = cz_get_pi(adev); | ||
1929 | struct amdgpu_vce_clock_voltage_dependency_table *dep_table = | ||
1930 | &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; | ||
1931 | uint32_t level = 0; | ||
1932 | int ret = 0; | ||
1933 | |||
1934 | pi->vce_dpm.soft_min_clk = dep_table->entries[0].ecclk; | ||
1935 | level = cz_dpm_get_max_vce_level(adev) - 1; | ||
1936 | if (level < dep_table->count) | ||
1937 | pi->vce_dpm.soft_max_clk = dep_table->entries[level].ecclk; | ||
1938 | else | ||
1939 | pi->vce_dpm.soft_max_clk = | ||
1940 | dep_table->entries[dep_table->count - 1].ecclk; | ||
1941 | |||
1942 | /* get min/max sclk soft value | ||
1943 | * notify SMU to execute */ | ||
1944 | ret = cz_send_msg_to_smc_with_parameter(adev, | ||
1945 | PPSMC_MSG_SetEclkSoftMin, | ||
1946 | cz_get_eclk_level(adev, | ||
1947 | pi->vce_dpm.soft_min_clk, | ||
1948 | PPSMC_MSG_SetEclkSoftMin)); | ||
1949 | if (ret) | ||
1950 | return ret; | ||
1951 | |||
1952 | ret = cz_send_msg_to_smc_with_parameter(adev, | ||
1953 | PPSMC_MSG_SetEclkSoftMax, | ||
1954 | cz_get_eclk_level(adev, | ||
1955 | pi->vce_dpm.soft_max_clk, | ||
1956 | PPSMC_MSG_SetEclkSoftMax)); | ||
1957 | if (ret) | ||
1958 | return ret; | ||
1959 | |||
1960 | DRM_DEBUG("DPM vce unforce state min=%d, max=%d.\n", | ||
1961 | pi->vce_dpm.soft_min_clk, | ||
1962 | pi->vce_dpm.soft_max_clk); | ||
1963 | |||
1964 | return 0; | ||
1965 | } | ||
1966 | |||
1871 | static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, | 1967 | static int cz_dpm_force_dpm_level(struct amdgpu_device *adev, |
1872 | enum amdgpu_dpm_forced_level level) | 1968 | enum amdgpu_dpm_forced_level level) |
1873 | { | 1969 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/cz_dpm.h b/drivers/gpu/drm/amd/amdgpu/cz_dpm.h index 6a6a6fe7967f..5df8c1faab51 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_dpm.h +++ b/drivers/gpu/drm/amd/amdgpu/cz_dpm.h | |||
@@ -184,6 +184,7 @@ struct cz_power_info { | |||
184 | uint32_t gfx_pg_threshold; | 184 | uint32_t gfx_pg_threshold; |
185 | uint32_t max_sclk_level; | 185 | uint32_t max_sclk_level; |
186 | uint32_t max_uvd_level; | 186 | uint32_t max_uvd_level; |
187 | uint32_t max_vce_level; | ||
187 | /* flags */ | 188 | /* flags */ |
188 | bool didt_enabled; | 189 | bool didt_enabled; |
189 | bool video_start; | 190 | bool video_start; |