1130e0371SOded Gabbay /* 2130e0371SOded Gabbay * Copyright 2014 Advanced Micro Devices, Inc. 3130e0371SOded Gabbay * 4130e0371SOded Gabbay * Permission is hereby granted, free of charge, to any person obtaining a 5130e0371SOded Gabbay * copy of this software and associated documentation files (the "Software"), 6130e0371SOded Gabbay * to deal in the Software without restriction, including without limitation 7130e0371SOded Gabbay * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8130e0371SOded Gabbay * and/or sell copies of the Software, and to permit persons to whom the 9130e0371SOded Gabbay * Software is furnished to do so, subject to the following conditions: 10130e0371SOded Gabbay * 11130e0371SOded Gabbay * The above copyright notice and this permission notice shall be included in 12130e0371SOded Gabbay * all copies or substantial portions of the Software. 13130e0371SOded Gabbay * 14130e0371SOded Gabbay * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15130e0371SOded Gabbay * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16130e0371SOded Gabbay * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17130e0371SOded Gabbay * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18130e0371SOded Gabbay * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19130e0371SOded Gabbay * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20130e0371SOded Gabbay * OTHER DEALINGS IN THE SOFTWARE. 21130e0371SOded Gabbay */ 22130e0371SOded Gabbay 23130e0371SOded Gabbay #include "amdgpu_amdkfd.h" 24*2f7d10b3SJammy Zhou #include "amd_shared.h" 25130e0371SOded Gabbay #include <drm/drmP.h> 26130e0371SOded Gabbay #include "amdgpu.h" 27130e0371SOded Gabbay #include <linux/module.h> 28130e0371SOded Gabbay 29130e0371SOded Gabbay const struct kfd2kgd_calls *kfd2kgd; 30130e0371SOded Gabbay const struct kgd2kfd_calls *kgd2kfd; 31130e0371SOded Gabbay bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); 32130e0371SOded Gabbay 33130e0371SOded Gabbay bool amdgpu_amdkfd_init(void) 34130e0371SOded Gabbay { 35130e0371SOded Gabbay #if defined(CONFIG_HSA_AMD_MODULE) 36130e0371SOded Gabbay bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); 37130e0371SOded Gabbay 38130e0371SOded Gabbay kgd2kfd_init_p = symbol_request(kgd2kfd_init); 39130e0371SOded Gabbay 40130e0371SOded Gabbay if (kgd2kfd_init_p == NULL) 41130e0371SOded Gabbay return false; 42130e0371SOded Gabbay #endif 43130e0371SOded Gabbay return true; 44130e0371SOded Gabbay } 45130e0371SOded Gabbay 46130e0371SOded Gabbay bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev) 47130e0371SOded Gabbay { 48130e0371SOded Gabbay #if defined(CONFIG_HSA_AMD_MODULE) 49130e0371SOded Gabbay bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); 50130e0371SOded Gabbay #endif 51130e0371SOded Gabbay 52130e0371SOded Gabbay switch (rdev->asic_type) { 53130e0371SOded Gabbay case CHIP_KAVERI: 5432c22e99SOded Gabbay kfd2kgd = amdgpu_amdkfd_gfx_7_get_functions(); 5532c22e99SOded Gabbay break; 56ff758a12SBen Goz case CHIP_CARRIZO: 57ff758a12SBen Goz kfd2kgd = amdgpu_amdkfd_gfx_8_0_get_functions(); 58ff758a12SBen Goz break; 59130e0371SOded Gabbay default: 60130e0371SOded Gabbay return false; 61130e0371SOded Gabbay } 62130e0371SOded Gabbay 63130e0371SOded Gabbay #if defined(CONFIG_HSA_AMD_MODULE) 64130e0371SOded Gabbay kgd2kfd_init_p = symbol_request(kgd2kfd_init); 65130e0371SOded Gabbay 66130e0371SOded Gabbay if (kgd2kfd_init_p == NULL) { 67130e0371SOded Gabbay kfd2kgd = NULL; 68130e0371SOded Gabbay return false; 69130e0371SOded Gabbay } 70130e0371SOded Gabbay 71130e0371SOded Gabbay if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd)) { 72130e0371SOded Gabbay symbol_put(kgd2kfd_init); 73130e0371SOded Gabbay kfd2kgd = NULL; 74130e0371SOded Gabbay kgd2kfd = NULL; 75130e0371SOded Gabbay 76130e0371SOded Gabbay return false; 77130e0371SOded Gabbay } 78130e0371SOded Gabbay 79130e0371SOded Gabbay return true; 80130e0371SOded Gabbay #elif defined(CONFIG_HSA_AMD) 81130e0371SOded Gabbay if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd)) { 82130e0371SOded Gabbay kfd2kgd = NULL; 83130e0371SOded Gabbay kgd2kfd = NULL; 84130e0371SOded Gabbay return false; 85130e0371SOded Gabbay } 86130e0371SOded Gabbay 87130e0371SOded Gabbay return true; 88130e0371SOded Gabbay #else 89130e0371SOded Gabbay kfd2kgd = NULL; 90130e0371SOded Gabbay return false; 91130e0371SOded Gabbay #endif 92130e0371SOded Gabbay } 93130e0371SOded Gabbay 94130e0371SOded Gabbay void amdgpu_amdkfd_fini(void) 95130e0371SOded Gabbay { 96130e0371SOded Gabbay if (kgd2kfd) { 97130e0371SOded Gabbay kgd2kfd->exit(); 98130e0371SOded Gabbay symbol_put(kgd2kfd_init); 99130e0371SOded Gabbay } 100130e0371SOded Gabbay } 101130e0371SOded Gabbay 102130e0371SOded Gabbay void amdgpu_amdkfd_device_probe(struct amdgpu_device *rdev) 103130e0371SOded Gabbay { 104130e0371SOded Gabbay if (kgd2kfd) 105130e0371SOded Gabbay rdev->kfd = kgd2kfd->probe((struct kgd_dev *)rdev, 106130e0371SOded Gabbay rdev->pdev, kfd2kgd); 107130e0371SOded Gabbay } 108130e0371SOded Gabbay 109130e0371SOded Gabbay void amdgpu_amdkfd_device_init(struct amdgpu_device *rdev) 110130e0371SOded Gabbay { 111130e0371SOded Gabbay if (rdev->kfd) { 112130e0371SOded Gabbay struct kgd2kfd_shared_resources gpu_resources = { 113130e0371SOded Gabbay .compute_vmid_bitmap = 0xFF00, 114130e0371SOded Gabbay 115130e0371SOded Gabbay .first_compute_pipe = 1, 116130e0371SOded Gabbay .compute_pipe_count = 4 - 1, 117130e0371SOded Gabbay }; 118130e0371SOded Gabbay 119130e0371SOded Gabbay amdgpu_doorbell_get_kfd_info(rdev, 120130e0371SOded Gabbay &gpu_resources.doorbell_physical_address, 121130e0371SOded Gabbay &gpu_resources.doorbell_aperture_size, 122130e0371SOded Gabbay &gpu_resources.doorbell_start_offset); 123130e0371SOded Gabbay 124130e0371SOded Gabbay kgd2kfd->device_init(rdev->kfd, &gpu_resources); 125130e0371SOded Gabbay } 126130e0371SOded Gabbay } 127130e0371SOded Gabbay 128130e0371SOded Gabbay void amdgpu_amdkfd_device_fini(struct amdgpu_device *rdev) 129130e0371SOded Gabbay { 130130e0371SOded Gabbay if (rdev->kfd) { 131130e0371SOded Gabbay kgd2kfd->device_exit(rdev->kfd); 132130e0371SOded Gabbay rdev->kfd = NULL; 133130e0371SOded Gabbay } 134130e0371SOded Gabbay } 135130e0371SOded Gabbay 136130e0371SOded Gabbay void amdgpu_amdkfd_interrupt(struct amdgpu_device *rdev, 137130e0371SOded Gabbay const void *ih_ring_entry) 138130e0371SOded Gabbay { 139130e0371SOded Gabbay if (rdev->kfd) 140130e0371SOded Gabbay kgd2kfd->interrupt(rdev->kfd, ih_ring_entry); 141130e0371SOded Gabbay } 142130e0371SOded Gabbay 143130e0371SOded Gabbay void amdgpu_amdkfd_suspend(struct amdgpu_device *rdev) 144130e0371SOded Gabbay { 145130e0371SOded Gabbay if (rdev->kfd) 146130e0371SOded Gabbay kgd2kfd->suspend(rdev->kfd); 147130e0371SOded Gabbay } 148130e0371SOded Gabbay 149130e0371SOded Gabbay int amdgpu_amdkfd_resume(struct amdgpu_device *rdev) 150130e0371SOded Gabbay { 151130e0371SOded Gabbay int r = 0; 152130e0371SOded Gabbay 153130e0371SOded Gabbay if (rdev->kfd) 154130e0371SOded Gabbay r = kgd2kfd->resume(rdev->kfd); 155130e0371SOded Gabbay 156130e0371SOded Gabbay return r; 157130e0371SOded Gabbay } 158130e0371SOded Gabbay 159130e0371SOded Gabbay u32 pool_to_domain(enum kgd_memory_pool p) 160130e0371SOded Gabbay { 161130e0371SOded Gabbay switch (p) { 162130e0371SOded Gabbay case KGD_POOL_FRAMEBUFFER: return AMDGPU_GEM_DOMAIN_VRAM; 163130e0371SOded Gabbay default: return AMDGPU_GEM_DOMAIN_GTT; 164130e0371SOded Gabbay } 165130e0371SOded Gabbay } 166130e0371SOded Gabbay 167130e0371SOded Gabbay int alloc_gtt_mem(struct kgd_dev *kgd, size_t size, 168130e0371SOded Gabbay void **mem_obj, uint64_t *gpu_addr, 169130e0371SOded Gabbay void **cpu_ptr) 170130e0371SOded Gabbay { 171130e0371SOded Gabbay struct amdgpu_device *rdev = (struct amdgpu_device *)kgd; 172130e0371SOded Gabbay struct kgd_mem **mem = (struct kgd_mem **) mem_obj; 173130e0371SOded Gabbay int r; 174130e0371SOded Gabbay 175130e0371SOded Gabbay BUG_ON(kgd == NULL); 176130e0371SOded Gabbay BUG_ON(gpu_addr == NULL); 177130e0371SOded Gabbay BUG_ON(cpu_ptr == NULL); 178130e0371SOded Gabbay 179130e0371SOded Gabbay *mem = kmalloc(sizeof(struct kgd_mem), GFP_KERNEL); 180130e0371SOded Gabbay if ((*mem) == NULL) 181130e0371SOded Gabbay return -ENOMEM; 182130e0371SOded Gabbay 183130e0371SOded Gabbay r = amdgpu_bo_create(rdev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_GTT, 184130e0371SOded Gabbay AMDGPU_GEM_CREATE_CPU_GTT_USWC, NULL, &(*mem)->bo); 185130e0371SOded Gabbay if (r) { 186130e0371SOded Gabbay dev_err(rdev->dev, 187130e0371SOded Gabbay "failed to allocate BO for amdkfd (%d)\n", r); 188130e0371SOded Gabbay return r; 189130e0371SOded Gabbay } 190130e0371SOded Gabbay 191130e0371SOded Gabbay /* map the buffer */ 192130e0371SOded Gabbay r = amdgpu_bo_reserve((*mem)->bo, true); 193130e0371SOded Gabbay if (r) { 194130e0371SOded Gabbay dev_err(rdev->dev, "(%d) failed to reserve bo for amdkfd\n", r); 195130e0371SOded Gabbay goto allocate_mem_reserve_bo_failed; 196130e0371SOded Gabbay } 197130e0371SOded Gabbay 198130e0371SOded Gabbay r = amdgpu_bo_pin((*mem)->bo, AMDGPU_GEM_DOMAIN_GTT, 199130e0371SOded Gabbay &(*mem)->gpu_addr); 200130e0371SOded Gabbay if (r) { 201130e0371SOded Gabbay dev_err(rdev->dev, "(%d) failed to pin bo for amdkfd\n", r); 202130e0371SOded Gabbay goto allocate_mem_pin_bo_failed; 203130e0371SOded Gabbay } 204130e0371SOded Gabbay *gpu_addr = (*mem)->gpu_addr; 205130e0371SOded Gabbay 206130e0371SOded Gabbay r = amdgpu_bo_kmap((*mem)->bo, &(*mem)->cpu_ptr); 207130e0371SOded Gabbay if (r) { 208130e0371SOded Gabbay dev_err(rdev->dev, 209130e0371SOded Gabbay "(%d) failed to map bo to kernel for amdkfd\n", r); 210130e0371SOded Gabbay goto allocate_mem_kmap_bo_failed; 211130e0371SOded Gabbay } 212130e0371SOded Gabbay *cpu_ptr = (*mem)->cpu_ptr; 213130e0371SOded Gabbay 214130e0371SOded Gabbay amdgpu_bo_unreserve((*mem)->bo); 215130e0371SOded Gabbay 216130e0371SOded Gabbay return 0; 217130e0371SOded Gabbay 218130e0371SOded Gabbay allocate_mem_kmap_bo_failed: 219130e0371SOded Gabbay amdgpu_bo_unpin((*mem)->bo); 220130e0371SOded Gabbay allocate_mem_pin_bo_failed: 221130e0371SOded Gabbay amdgpu_bo_unreserve((*mem)->bo); 222130e0371SOded Gabbay allocate_mem_reserve_bo_failed: 223130e0371SOded Gabbay amdgpu_bo_unref(&(*mem)->bo); 224130e0371SOded Gabbay 225130e0371SOded Gabbay return r; 226130e0371SOded Gabbay } 227130e0371SOded Gabbay 228130e0371SOded Gabbay void free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) 229130e0371SOded Gabbay { 230130e0371SOded Gabbay struct kgd_mem *mem = (struct kgd_mem *) mem_obj; 231130e0371SOded Gabbay 232130e0371SOded Gabbay BUG_ON(mem == NULL); 233130e0371SOded Gabbay 234130e0371SOded Gabbay amdgpu_bo_reserve(mem->bo, true); 235130e0371SOded Gabbay amdgpu_bo_kunmap(mem->bo); 236130e0371SOded Gabbay amdgpu_bo_unpin(mem->bo); 237130e0371SOded Gabbay amdgpu_bo_unreserve(mem->bo); 238130e0371SOded Gabbay amdgpu_bo_unref(&(mem->bo)); 239130e0371SOded Gabbay kfree(mem); 240130e0371SOded Gabbay } 241130e0371SOded Gabbay 242130e0371SOded Gabbay uint64_t get_vmem_size(struct kgd_dev *kgd) 243130e0371SOded Gabbay { 244130e0371SOded Gabbay struct amdgpu_device *rdev = 245130e0371SOded Gabbay (struct amdgpu_device *)kgd; 246130e0371SOded Gabbay 247130e0371SOded Gabbay BUG_ON(kgd == NULL); 248130e0371SOded Gabbay 249130e0371SOded Gabbay return rdev->mc.real_vram_size; 250130e0371SOded Gabbay } 251130e0371SOded Gabbay 252130e0371SOded Gabbay uint64_t get_gpu_clock_counter(struct kgd_dev *kgd) 253130e0371SOded Gabbay { 254130e0371SOded Gabbay struct amdgpu_device *rdev = (struct amdgpu_device *)kgd; 255130e0371SOded Gabbay 256130e0371SOded Gabbay if (rdev->asic_funcs->get_gpu_clock_counter) 257130e0371SOded Gabbay return rdev->asic_funcs->get_gpu_clock_counter(rdev); 258130e0371SOded Gabbay return 0; 259130e0371SOded Gabbay } 260130e0371SOded Gabbay 261130e0371SOded Gabbay uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd) 262130e0371SOded Gabbay { 263130e0371SOded Gabbay struct amdgpu_device *rdev = (struct amdgpu_device *)kgd; 264130e0371SOded Gabbay 265130e0371SOded Gabbay /* The sclk is in quantas of 10kHz */ 266130e0371SOded Gabbay return rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk / 100; 267130e0371SOded Gabbay } 268