Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+98 -1
+97 -1
drivers/gpu/drm/amd/amdgpu/cz_dpm.c
··· 1770 1770 return 0; 1771 1771 } 1772 1772 1773 - 1774 1773 static int cz_dpm_uvd_force_highest(struct amdgpu_device *adev) 1775 1774 { 1776 1775 struct cz_power_info *pi = cz_get_pi(adev); ··· 1863 1864 DRM_DEBUG("DPM uvd unforce state min=%d, max=%d.\n", 1864 1865 pi->uvd_dpm.soft_min_clk, 1865 1866 pi->uvd_dpm.soft_max_clk); 1867 + 1868 + return 0; 1869 + } 1870 + 1871 + static int cz_dpm_vce_force_highest(struct amdgpu_device *adev) 1872 + { 1873 + struct cz_power_info *pi = cz_get_pi(adev); 1874 + int ret = 0; 1875 + 1876 + if (pi->vce_dpm.soft_min_clk != pi->vce_dpm.soft_max_clk) { 1877 + pi->vce_dpm.soft_min_clk = 1878 + pi->vce_dpm.soft_max_clk; 1879 + ret = cz_send_msg_to_smc_with_parameter(adev, 1880 + PPSMC_MSG_SetEclkSoftMin, 1881 + cz_get_eclk_level(adev, 1882 + pi->vce_dpm.soft_min_clk, 1883 + PPSMC_MSG_SetEclkSoftMin)); 1884 + if (ret) 1885 + return ret; 1886 + } 1887 + 1888 + return ret; 1889 + } 1890 + 1891 + static int cz_dpm_vce_force_lowest(struct amdgpu_device *adev) 1892 + { 1893 + struct cz_power_info *pi = cz_get_pi(adev); 1894 + int ret = 0; 1895 + 1896 + if (pi->vce_dpm.soft_max_clk != pi->vce_dpm.soft_min_clk) { 1897 + pi->vce_dpm.soft_max_clk = pi->vce_dpm.soft_min_clk; 1898 + ret = cz_send_msg_to_smc_with_parameter(adev, 1899 + PPSMC_MSG_SetEclkSoftMax, 1900 + cz_get_uvd_level(adev, 1901 + pi->vce_dpm.soft_max_clk, 1902 + PPSMC_MSG_SetEclkSoftMax)); 1903 + if (ret) 1904 + return ret; 1905 + } 1906 + 1907 + return ret; 1908 + } 1909 + 1910 + static uint32_t cz_dpm_get_max_vce_level(struct amdgpu_device *adev) 1911 + { 1912 + struct cz_power_info *pi = cz_get_pi(adev); 1913 + 1914 + if (!pi->max_vce_level) { 1915 + cz_send_msg_to_smc(adev, PPSMC_MSG_GetMaxEclkLevel); 1916 + pi->max_vce_level = cz_get_argument(adev) + 1; 1917 + } 1918 + 1919 + if (pi->max_vce_level > CZ_MAX_HARDWARE_POWERLEVELS) { 1920 + DRM_ERROR("Invalid max vce level!\n"); 1921 + return -EINVAL; 1922 + } 1923 + 1924 + return pi->max_vce_level; 1925 + } 1926 + 1927 + static int cz_dpm_unforce_vce_dpm_levels(struct amdgpu_device *adev) 1928 + { 1929 + struct cz_power_info *pi = cz_get_pi(adev); 1930 + struct amdgpu_vce_clock_voltage_dependency_table *dep_table = 1931 + &adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; 1932 + uint32_t level = 0; 1933 + int ret = 0; 1934 + 1935 + pi->vce_dpm.soft_min_clk = dep_table->entries[0].ecclk; 1936 + level = cz_dpm_get_max_vce_level(adev) - 1; 1937 + if (level < dep_table->count) 1938 + pi->vce_dpm.soft_max_clk = dep_table->entries[level].ecclk; 1939 + else 1940 + pi->vce_dpm.soft_max_clk = 1941 + dep_table->entries[dep_table->count - 1].ecclk; 1942 + 1943 + /* get min/max sclk soft value 1944 + * notify SMU to execute */ 1945 + ret = cz_send_msg_to_smc_with_parameter(adev, 1946 + PPSMC_MSG_SetEclkSoftMin, 1947 + cz_get_eclk_level(adev, 1948 + pi->vce_dpm.soft_min_clk, 1949 + PPSMC_MSG_SetEclkSoftMin)); 1950 + if (ret) 1951 + return ret; 1952 + 1953 + ret = cz_send_msg_to_smc_with_parameter(adev, 1954 + PPSMC_MSG_SetEclkSoftMax, 1955 + cz_get_eclk_level(adev, 1956 + pi->vce_dpm.soft_max_clk, 1957 + PPSMC_MSG_SetEclkSoftMax)); 1958 + if (ret) 1959 + return ret; 1960 + 1961 + DRM_DEBUG("DPM vce unforce state min=%d, max=%d.\n", 1962 + pi->vce_dpm.soft_min_clk, 1963 + pi->vce_dpm.soft_max_clk); 1866 1964 1867 1965 return 0; 1868 1966 }
+1
drivers/gpu/drm/amd/amdgpu/cz_dpm.h
··· 184 184 uint32_t gfx_pg_threshold; 185 185 uint32_t max_sclk_level; 186 186 uint32_t max_uvd_level; 187 + uint32_t max_vce_level; 187 188 /* flags */ 188 189 bool didt_enabled; 189 190 bool video_start;