1 /* 2 * Copyright 2016 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/module.h> 25 26 #include <drm/drm_drv.h> 27 28 #include "amdgpu.h" 29 30 bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev) 31 { 32 /* By now all MMIO pages except mailbox are blocked */ 33 /* if blocking is enabled in hypervisor. Choose the */ 34 /* SCRATCH_REG0 to test. */ 35 return RREG32_NO_KIQ(0xc040) == 0xffffffff; 36 } 37 38 void amdgpu_virt_init_setting(struct amdgpu_device *adev) 39 { 40 /* enable virtual display */ 41 adev->mode_info.num_crtc = 1; 42 adev->enable_virtual_display = true; 43 adev->ddev->driver->driver_features &= ~DRIVER_ATOMIC; 44 adev->cg_flags = 0; 45 adev->pg_flags = 0; 46 } 47 48 void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev, 49 uint32_t reg0, uint32_t reg1, 50 uint32_t ref, uint32_t mask) 51 { 52 struct amdgpu_kiq *kiq = &adev->gfx.kiq; 53 struct amdgpu_ring *ring = &kiq->ring; 54 signed long r, cnt = 0; 55 unsigned long flags; 56 uint32_t seq; 57 58 spin_lock_irqsave(&kiq->ring_lock, flags); 59 amdgpu_ring_alloc(ring, 32); 60 amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1, 61 ref, mask); 62 amdgpu_fence_emit_polling(ring, &seq); 63 amdgpu_ring_commit(ring); 64 spin_unlock_irqrestore(&kiq->ring_lock, flags); 65 66 r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); 67 68 /* don't wait anymore for IRQ context */ 69 if (r < 1 && in_interrupt()) 70 goto failed_kiq; 71 72 might_sleep(); 73 while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) { 74 75 msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); 76 r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); 77 } 78 79 if (cnt > MAX_KIQ_REG_TRY) 80 goto failed_kiq; 81 82 return; 83 84 failed_kiq: 85 pr_err("failed to write reg %x wait reg %x\n", reg0, reg1); 86 } 87 88 /** 89 * amdgpu_virt_request_full_gpu() - request full gpu access 90 * @amdgpu: amdgpu device. 91 * @init: is driver init time. 92 * When start to init/fini driver, first need to request full gpu access. 93 * Return: Zero if request success, otherwise will return error. 94 */ 95 int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init) 96 { 97 struct amdgpu_virt *virt = &adev->virt; 98 int r; 99 100 if (virt->ops && virt->ops->req_full_gpu) { 101 r = virt->ops->req_full_gpu(adev, init); 102 if (r) 103 return r; 104 105 adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME; 106 } 107 108 return 0; 109 } 110 111 /** 112 * amdgpu_virt_release_full_gpu() - release full gpu access 113 * @amdgpu: amdgpu device. 114 * @init: is driver init time. 115 * When finishing driver init/fini, need to release full gpu access. 116 * Return: Zero if release success, otherwise will returen error. 117 */ 118 int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init) 119 { 120 struct amdgpu_virt *virt = &adev->virt; 121 int r; 122 123 if (virt->ops && virt->ops->rel_full_gpu) { 124 r = virt->ops->rel_full_gpu(adev, init); 125 if (r) 126 return r; 127 128 adev->virt.caps |= AMDGPU_SRIOV_CAPS_RUNTIME; 129 } 130 return 0; 131 } 132 133 /** 134 * amdgpu_virt_reset_gpu() - reset gpu 135 * @amdgpu: amdgpu device. 136 * Send reset command to GPU hypervisor to reset GPU that VM is using 137 * Return: Zero if reset success, otherwise will return error. 138 */ 139 int amdgpu_virt_reset_gpu(struct amdgpu_device *adev) 140 { 141 struct amdgpu_virt *virt = &adev->virt; 142 int r; 143 144 if (virt->ops && virt->ops->reset_gpu) { 145 r = virt->ops->reset_gpu(adev); 146 if (r) 147 return r; 148 149 adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME; 150 } 151 152 return 0; 153 } 154 155 /** 156 * amdgpu_virt_wait_reset() - wait for reset gpu completed 157 * @amdgpu: amdgpu device. 158 * Wait for GPU reset completed. 159 * Return: Zero if reset success, otherwise will return error. 160 */ 161 int amdgpu_virt_wait_reset(struct amdgpu_device *adev) 162 { 163 struct amdgpu_virt *virt = &adev->virt; 164 165 if (!virt->ops || !virt->ops->wait_reset) 166 return -EINVAL; 167 168 return virt->ops->wait_reset(adev); 169 } 170 171 /** 172 * amdgpu_virt_alloc_mm_table() - alloc memory for mm table 173 * @amdgpu: amdgpu device. 174 * MM table is used by UVD and VCE for its initialization 175 * Return: Zero if allocate success. 176 */ 177 int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev) 178 { 179 int r; 180 181 if (!amdgpu_sriov_vf(adev) || adev->virt.mm_table.gpu_addr) 182 return 0; 183 184 r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE, 185 AMDGPU_GEM_DOMAIN_VRAM, 186 &adev->virt.mm_table.bo, 187 &adev->virt.mm_table.gpu_addr, 188 (void *)&adev->virt.mm_table.cpu_addr); 189 if (r) { 190 DRM_ERROR("failed to alloc mm table and error = %d.\n", r); 191 return r; 192 } 193 194 memset((void *)adev->virt.mm_table.cpu_addr, 0, PAGE_SIZE); 195 DRM_INFO("MM table gpu addr = 0x%llx, cpu addr = %p.\n", 196 adev->virt.mm_table.gpu_addr, 197 adev->virt.mm_table.cpu_addr); 198 return 0; 199 } 200 201 /** 202 * amdgpu_virt_free_mm_table() - free mm table memory 203 * @amdgpu: amdgpu device. 204 * Free MM table memory 205 */ 206 void amdgpu_virt_free_mm_table(struct amdgpu_device *adev) 207 { 208 if (!amdgpu_sriov_vf(adev) || !adev->virt.mm_table.gpu_addr) 209 return; 210 211 amdgpu_bo_free_kernel(&adev->virt.mm_table.bo, 212 &adev->virt.mm_table.gpu_addr, 213 (void *)&adev->virt.mm_table.cpu_addr); 214 adev->virt.mm_table.gpu_addr = 0; 215 } 216 217 218 int amdgpu_virt_fw_reserve_get_checksum(void *obj, 219 unsigned long obj_size, 220 unsigned int key, 221 unsigned int chksum) 222 { 223 unsigned int ret = key; 224 unsigned long i = 0; 225 unsigned char *pos; 226 227 pos = (char *)obj; 228 /* calculate checksum */ 229 for (i = 0; i < obj_size; ++i) 230 ret += *(pos + i); 231 /* minus the chksum itself */ 232 pos = (char *)&chksum; 233 for (i = 0; i < sizeof(chksum); ++i) 234 ret -= *(pos + i); 235 return ret; 236 } 237 238 void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) 239 { 240 uint32_t pf2vf_size = 0; 241 uint32_t checksum = 0; 242 uint32_t checkval; 243 char *str; 244 245 adev->virt.fw_reserve.p_pf2vf = NULL; 246 adev->virt.fw_reserve.p_vf2pf = NULL; 247 248 if (adev->fw_vram_usage.va != NULL) { 249 adev->virt.fw_reserve.p_pf2vf = 250 (struct amd_sriov_msg_pf2vf_info_header *)( 251 adev->fw_vram_usage.va + AMDGIM_DATAEXCHANGE_OFFSET); 252 AMDGPU_FW_VRAM_PF2VF_READ(adev, header.size, &pf2vf_size); 253 AMDGPU_FW_VRAM_PF2VF_READ(adev, checksum, &checksum); 254 AMDGPU_FW_VRAM_PF2VF_READ(adev, feature_flags, &adev->virt.gim_feature); 255 256 /* pf2vf message must be in 4K */ 257 if (pf2vf_size > 0 && pf2vf_size < 4096) { 258 checkval = amdgpu_virt_fw_reserve_get_checksum( 259 adev->virt.fw_reserve.p_pf2vf, pf2vf_size, 260 adev->virt.fw_reserve.checksum_key, checksum); 261 if (checkval == checksum) { 262 adev->virt.fw_reserve.p_vf2pf = 263 ((void *)adev->virt.fw_reserve.p_pf2vf + 264 pf2vf_size); 265 memset((void *)adev->virt.fw_reserve.p_vf2pf, 0, 266 sizeof(amdgim_vf2pf_info)); 267 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.version, 268 AMDGPU_FW_VRAM_VF2PF_VER); 269 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, header.size, 270 sizeof(amdgim_vf2pf_info)); 271 AMDGPU_FW_VRAM_VF2PF_READ(adev, driver_version, 272 &str); 273 #ifdef MODULE 274 if (THIS_MODULE->version != NULL) 275 strcpy(str, THIS_MODULE->version); 276 else 277 #endif 278 strcpy(str, "N/A"); 279 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, driver_cert, 280 0); 281 AMDGPU_FW_VRAM_VF2PF_WRITE(adev, checksum, 282 amdgpu_virt_fw_reserve_get_checksum( 283 adev->virt.fw_reserve.p_vf2pf, 284 pf2vf_size, 285 adev->virt.fw_reserve.checksum_key, 0)); 286 } 287 } 288 } 289 } 290