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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.8 200 lines 4.9 kB view raw
1/* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 24#include <linux/firmware.h> 25#include "drmP.h" 26#include "amdgpu.h" 27#include "iceland_smum.h" 28 29MODULE_FIRMWARE("amdgpu/topaz_smc.bin"); 30 31static void iceland_dpm_set_funcs(struct amdgpu_device *adev); 32 33static int iceland_dpm_early_init(void *handle) 34{ 35 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 36 37 iceland_dpm_set_funcs(adev); 38 39 return 0; 40} 41 42static int iceland_dpm_init_microcode(struct amdgpu_device *adev) 43{ 44 char fw_name[30] = "amdgpu/topaz_smc.bin"; 45 int err; 46 47 err = request_firmware(&adev->pm.fw, fw_name, adev->dev); 48 if (err) 49 goto out; 50 err = amdgpu_ucode_validate(adev->pm.fw); 51 52out: 53 if (err) { 54 DRM_ERROR("Failed to load firmware \"%s\"", fw_name); 55 release_firmware(adev->pm.fw); 56 adev->pm.fw = NULL; 57 } 58 return err; 59} 60 61static int iceland_dpm_sw_init(void *handle) 62{ 63 int ret; 64 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 65 66 ret = iceland_dpm_init_microcode(adev); 67 if (ret) 68 return ret; 69 70 return 0; 71} 72 73static int iceland_dpm_sw_fini(void *handle) 74{ 75 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 76 77 release_firmware(adev->pm.fw); 78 adev->pm.fw = NULL; 79 80 return 0; 81} 82 83static int iceland_dpm_hw_init(void *handle) 84{ 85 int ret; 86 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 87 88 mutex_lock(&adev->pm.mutex); 89 90 /* smu init only needs to be called at startup, not resume. 91 * It should be in sw_init, but requires the fw info gathered 92 * in sw_init from other IP modules. 93 */ 94 ret = iceland_smu_init(adev); 95 if (ret) { 96 DRM_ERROR("SMU initialization failed\n"); 97 goto fail; 98 } 99 100 ret = iceland_smu_start(adev); 101 if (ret) { 102 DRM_ERROR("SMU start failed\n"); 103 goto fail; 104 } 105 106 mutex_unlock(&adev->pm.mutex); 107 return 0; 108 109fail: 110 adev->firmware.smu_load = false; 111 mutex_unlock(&adev->pm.mutex); 112 return -EINVAL; 113} 114 115static int iceland_dpm_hw_fini(void *handle) 116{ 117 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 118 119 mutex_lock(&adev->pm.mutex); 120 /* smu fini only needs to be called at teardown, not suspend. 121 * It should be in sw_fini, but we put it here for symmetry 122 * with smu init. 123 */ 124 iceland_smu_fini(adev); 125 mutex_unlock(&adev->pm.mutex); 126 return 0; 127} 128 129static int iceland_dpm_suspend(void *handle) 130{ 131 return 0; 132} 133 134static int iceland_dpm_resume(void *handle) 135{ 136 int ret; 137 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 138 139 mutex_lock(&adev->pm.mutex); 140 141 ret = iceland_smu_start(adev); 142 if (ret) { 143 DRM_ERROR("SMU start failed\n"); 144 goto fail; 145 } 146 147fail: 148 mutex_unlock(&adev->pm.mutex); 149 return ret; 150} 151 152static int iceland_dpm_set_clockgating_state(void *handle, 153 enum amd_clockgating_state state) 154{ 155 return 0; 156} 157 158static int iceland_dpm_set_powergating_state(void *handle, 159 enum amd_powergating_state state) 160{ 161 return 0; 162} 163 164const struct amd_ip_funcs iceland_dpm_ip_funcs = { 165 .name = "iceland_dpm", 166 .early_init = iceland_dpm_early_init, 167 .late_init = NULL, 168 .sw_init = iceland_dpm_sw_init, 169 .sw_fini = iceland_dpm_sw_fini, 170 .hw_init = iceland_dpm_hw_init, 171 .hw_fini = iceland_dpm_hw_fini, 172 .suspend = iceland_dpm_suspend, 173 .resume = iceland_dpm_resume, 174 .is_idle = NULL, 175 .wait_for_idle = NULL, 176 .soft_reset = NULL, 177 .set_clockgating_state = iceland_dpm_set_clockgating_state, 178 .set_powergating_state = iceland_dpm_set_powergating_state, 179}; 180 181static const struct amdgpu_dpm_funcs iceland_dpm_funcs = { 182 .get_temperature = NULL, 183 .pre_set_power_state = NULL, 184 .set_power_state = NULL, 185 .post_set_power_state = NULL, 186 .display_configuration_changed = NULL, 187 .get_sclk = NULL, 188 .get_mclk = NULL, 189 .print_power_state = NULL, 190 .debugfs_print_current_performance_level = NULL, 191 .force_performance_level = NULL, 192 .vblank_too_short = NULL, 193 .powergate_uvd = NULL, 194}; 195 196static void iceland_dpm_set_funcs(struct amdgpu_device *adev) 197{ 198 if (NULL == adev->pm.funcs) 199 adev->pm.funcs = &iceland_dpm_funcs; 200}