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.9-rc7 318 lines 8.0 kB view raw
1/* 2 * Copyright 2015 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 * Authors: AMD 23 * 24 */ 25#include "atom.h" 26#include "amdgpu.h" 27#include "amd_shared.h" 28#include <linux/module.h> 29#include <linux/moduleparam.h> 30#include "amdgpu_pm.h" 31#include <drm/amdgpu_drm.h> 32#include "amdgpu_powerplay.h" 33#include "si_dpm.h" 34#include "cik_dpm.h" 35#include "vi_dpm.h" 36 37static int amdgpu_powerplay_init(struct amdgpu_device *adev) 38{ 39 int ret = 0; 40 struct amd_powerplay *amd_pp; 41 42 amd_pp = &(adev->powerplay); 43 44 if (adev->pp_enabled) { 45 struct amd_pp_init *pp_init; 46 47 pp_init = kzalloc(sizeof(struct amd_pp_init), GFP_KERNEL); 48 49 if (pp_init == NULL) 50 return -ENOMEM; 51 52 pp_init->chip_family = adev->family; 53 pp_init->chip_id = adev->asic_type; 54 pp_init->device = amdgpu_cgs_create_device(adev); 55 ret = amd_powerplay_init(pp_init, amd_pp); 56 kfree(pp_init); 57 } else { 58 amd_pp->pp_handle = (void *)adev; 59 60 switch (adev->asic_type) { 61#ifdef CONFIG_DRM_AMDGPU_SI 62 case CHIP_TAHITI: 63 case CHIP_PITCAIRN: 64 case CHIP_VERDE: 65 case CHIP_OLAND: 66 case CHIP_HAINAN: 67 amd_pp->ip_funcs = &si_dpm_ip_funcs; 68 break; 69#endif 70#ifdef CONFIG_DRM_AMDGPU_CIK 71 case CHIP_BONAIRE: 72 case CHIP_HAWAII: 73 amd_pp->ip_funcs = &ci_dpm_ip_funcs; 74 break; 75 case CHIP_KABINI: 76 case CHIP_MULLINS: 77 case CHIP_KAVERI: 78 amd_pp->ip_funcs = &kv_dpm_ip_funcs; 79 break; 80#endif 81 case CHIP_CARRIZO: 82 case CHIP_STONEY: 83 amd_pp->ip_funcs = &cz_dpm_ip_funcs; 84 break; 85 default: 86 ret = -EINVAL; 87 break; 88 } 89 } 90 return ret; 91} 92 93static int amdgpu_pp_early_init(void *handle) 94{ 95 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 96 int ret = 0; 97 98 switch (adev->asic_type) { 99 case CHIP_POLARIS11: 100 case CHIP_POLARIS10: 101 case CHIP_TONGA: 102 case CHIP_FIJI: 103 case CHIP_TOPAZ: 104 adev->pp_enabled = true; 105 break; 106 case CHIP_CARRIZO: 107 case CHIP_STONEY: 108 adev->pp_enabled = (amdgpu_powerplay == 0) ? false : true; 109 break; 110 /* These chips don't have powerplay implemenations */ 111 case CHIP_BONAIRE: 112 case CHIP_HAWAII: 113 case CHIP_KABINI: 114 case CHIP_MULLINS: 115 case CHIP_KAVERI: 116 default: 117 adev->pp_enabled = false; 118 break; 119 } 120 121 ret = amdgpu_powerplay_init(adev); 122 if (ret) 123 return ret; 124 125 if (adev->powerplay.ip_funcs->early_init) 126 ret = adev->powerplay.ip_funcs->early_init( 127 adev->powerplay.pp_handle); 128 return ret; 129} 130 131 132static int amdgpu_pp_late_init(void *handle) 133{ 134 int ret = 0; 135 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 136 137 if (adev->powerplay.ip_funcs->late_init) 138 ret = adev->powerplay.ip_funcs->late_init( 139 adev->powerplay.pp_handle); 140 141 if (adev->pp_enabled && adev->pm.dpm_enabled) { 142 amdgpu_pm_sysfs_init(adev); 143 amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL); 144 } 145 146 return ret; 147} 148 149static int amdgpu_pp_sw_init(void *handle) 150{ 151 int ret = 0; 152 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 153 154 if (adev->powerplay.ip_funcs->sw_init) 155 ret = adev->powerplay.ip_funcs->sw_init( 156 adev->powerplay.pp_handle); 157 158 if (adev->pp_enabled) 159 adev->pm.dpm_enabled = true; 160 161 return ret; 162} 163 164static int amdgpu_pp_sw_fini(void *handle) 165{ 166 int ret = 0; 167 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 168 169 if (adev->powerplay.ip_funcs->sw_fini) 170 ret = adev->powerplay.ip_funcs->sw_fini( 171 adev->powerplay.pp_handle); 172 if (ret) 173 return ret; 174 175 return ret; 176} 177 178static int amdgpu_pp_hw_init(void *handle) 179{ 180 int ret = 0; 181 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 182 183 if (adev->pp_enabled && adev->firmware.smu_load) 184 amdgpu_ucode_init_bo(adev); 185 186 if (adev->powerplay.ip_funcs->hw_init) 187 ret = adev->powerplay.ip_funcs->hw_init( 188 adev->powerplay.pp_handle); 189 190 return ret; 191} 192 193static int amdgpu_pp_hw_fini(void *handle) 194{ 195 int ret = 0; 196 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 197 198 if (adev->powerplay.ip_funcs->hw_fini) 199 ret = adev->powerplay.ip_funcs->hw_fini( 200 adev->powerplay.pp_handle); 201 202 if (adev->pp_enabled && adev->firmware.smu_load) 203 amdgpu_ucode_fini_bo(adev); 204 205 return ret; 206} 207 208static void amdgpu_pp_late_fini(void *handle) 209{ 210 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 211 212 if (adev->pp_enabled) { 213 amdgpu_pm_sysfs_fini(adev); 214 amd_powerplay_fini(adev->powerplay.pp_handle); 215 } 216 217 if (adev->powerplay.ip_funcs->late_fini) 218 adev->powerplay.ip_funcs->late_fini( 219 adev->powerplay.pp_handle); 220} 221 222static int amdgpu_pp_suspend(void *handle) 223{ 224 int ret = 0; 225 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 226 227 if (adev->powerplay.ip_funcs->suspend) 228 ret = adev->powerplay.ip_funcs->suspend( 229 adev->powerplay.pp_handle); 230 return ret; 231} 232 233static int amdgpu_pp_resume(void *handle) 234{ 235 int ret = 0; 236 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 237 238 if (adev->powerplay.ip_funcs->resume) 239 ret = adev->powerplay.ip_funcs->resume( 240 adev->powerplay.pp_handle); 241 return ret; 242} 243 244static int amdgpu_pp_set_clockgating_state(void *handle, 245 enum amd_clockgating_state state) 246{ 247 int ret = 0; 248 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 249 250 if (adev->powerplay.ip_funcs->set_clockgating_state) 251 ret = adev->powerplay.ip_funcs->set_clockgating_state( 252 adev->powerplay.pp_handle, state); 253 return ret; 254} 255 256static int amdgpu_pp_set_powergating_state(void *handle, 257 enum amd_powergating_state state) 258{ 259 int ret = 0; 260 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 261 262 if (adev->powerplay.ip_funcs->set_powergating_state) 263 ret = adev->powerplay.ip_funcs->set_powergating_state( 264 adev->powerplay.pp_handle, state); 265 return ret; 266} 267 268 269static bool amdgpu_pp_is_idle(void *handle) 270{ 271 bool ret = true; 272 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 273 274 if (adev->powerplay.ip_funcs->is_idle) 275 ret = adev->powerplay.ip_funcs->is_idle( 276 adev->powerplay.pp_handle); 277 return ret; 278} 279 280static int amdgpu_pp_wait_for_idle(void *handle) 281{ 282 int ret = 0; 283 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 284 285 if (adev->powerplay.ip_funcs->wait_for_idle) 286 ret = adev->powerplay.ip_funcs->wait_for_idle( 287 adev->powerplay.pp_handle); 288 return ret; 289} 290 291static int amdgpu_pp_soft_reset(void *handle) 292{ 293 int ret = 0; 294 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 295 296 if (adev->powerplay.ip_funcs->soft_reset) 297 ret = adev->powerplay.ip_funcs->soft_reset( 298 adev->powerplay.pp_handle); 299 return ret; 300} 301 302const struct amd_ip_funcs amdgpu_pp_ip_funcs = { 303 .name = "amdgpu_powerplay", 304 .early_init = amdgpu_pp_early_init, 305 .late_init = amdgpu_pp_late_init, 306 .sw_init = amdgpu_pp_sw_init, 307 .sw_fini = amdgpu_pp_sw_fini, 308 .hw_init = amdgpu_pp_hw_init, 309 .hw_fini = amdgpu_pp_hw_fini, 310 .late_fini = amdgpu_pp_late_fini, 311 .suspend = amdgpu_pp_suspend, 312 .resume = amdgpu_pp_resume, 313 .is_idle = amdgpu_pp_is_idle, 314 .wait_for_idle = amdgpu_pp_wait_for_idle, 315 .soft_reset = amdgpu_pp_soft_reset, 316 .set_clockgating_state = amdgpu_pp_set_clockgating_state, 317 .set_powergating_state = amdgpu_pp_set_powergating_state, 318};