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/pci.h> 25 26 #include "amdgpu.h" 27 #include "amdgpu_ih.h" 28 #include "soc15.h" 29 30 #include "oss/osssys_4_0_offset.h" 31 #include "oss/osssys_4_0_sh_mask.h" 32 33 #include "soc15_common.h" 34 #include "vega10_ih.h" 35 36 #define MAX_REARM_RETRY 10 37 38 static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev); 39 40 /** 41 * vega10_ih_enable_interrupts - Enable the interrupt ring buffer 42 * 43 * @adev: amdgpu_device pointer 44 * 45 * Enable the interrupt ring buffer (VEGA10). 46 */ 47 static void vega10_ih_enable_interrupts(struct amdgpu_device *adev) 48 { 49 u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL); 50 51 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 1); 52 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1); 53 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 54 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) { 55 DRM_ERROR("PSP program IH_RB_CNTL failed!\n"); 56 return; 57 } 58 } else { 59 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl); 60 } 61 adev->irq.ih.enabled = true; 62 63 if (adev->irq.ih1.ring_size) { 64 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); 65 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, 66 RB_ENABLE, 1); 67 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 68 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1, 69 ih_rb_cntl)) { 70 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n"); 71 return; 72 } 73 } else { 74 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); 75 } 76 adev->irq.ih1.enabled = true; 77 } 78 79 if (adev->irq.ih2.ring_size) { 80 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); 81 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, 82 RB_ENABLE, 1); 83 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 84 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2, 85 ih_rb_cntl)) { 86 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n"); 87 return; 88 } 89 } else { 90 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); 91 } 92 adev->irq.ih2.enabled = true; 93 } 94 } 95 96 /** 97 * vega10_ih_disable_interrupts - Disable the interrupt ring buffer 98 * 99 * @adev: amdgpu_device pointer 100 * 101 * Disable the interrupt ring buffer (VEGA10). 102 */ 103 static void vega10_ih_disable_interrupts(struct amdgpu_device *adev) 104 { 105 u32 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL); 106 107 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_ENABLE, 0); 108 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 0); 109 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 110 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) { 111 DRM_ERROR("PSP program IH_RB_CNTL failed!\n"); 112 return; 113 } 114 } else { 115 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl); 116 } 117 118 /* set rptr, wptr to 0 */ 119 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0); 120 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0); 121 adev->irq.ih.enabled = false; 122 adev->irq.ih.rptr = 0; 123 124 if (adev->irq.ih1.ring_size) { 125 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); 126 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, 127 RB_ENABLE, 0); 128 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 129 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1, 130 ih_rb_cntl)) { 131 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n"); 132 return; 133 } 134 } else { 135 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); 136 } 137 /* set rptr, wptr to 0 */ 138 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0); 139 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0); 140 adev->irq.ih1.enabled = false; 141 adev->irq.ih1.rptr = 0; 142 } 143 144 if (adev->irq.ih2.ring_size) { 145 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); 146 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, 147 RB_ENABLE, 0); 148 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 149 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2, 150 ih_rb_cntl)) { 151 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n"); 152 return; 153 } 154 } else { 155 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); 156 } 157 158 /* set rptr, wptr to 0 */ 159 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0); 160 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0); 161 adev->irq.ih2.enabled = false; 162 adev->irq.ih2.rptr = 0; 163 } 164 } 165 166 static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl) 167 { 168 int rb_bufsz = order_base_2(ih->ring_size / 4); 169 170 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, 171 MC_SPACE, ih->use_bus_addr ? 1 : 4); 172 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, 173 WPTR_OVERFLOW_CLEAR, 1); 174 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, 175 WPTR_OVERFLOW_ENABLE, 1); 176 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz); 177 /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register 178 * value is written to memory 179 */ 180 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, 181 WPTR_WRITEBACK_ENABLE, 1); 182 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1); 183 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0); 184 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0); 185 186 return ih_rb_cntl; 187 } 188 189 static uint32_t vega10_ih_doorbell_rptr(struct amdgpu_ih_ring *ih) 190 { 191 u32 ih_doorbell_rtpr = 0; 192 193 if (ih->use_doorbell) { 194 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, 195 IH_DOORBELL_RPTR, OFFSET, 196 ih->doorbell_index); 197 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, 198 IH_DOORBELL_RPTR, 199 ENABLE, 1); 200 } else { 201 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr, 202 IH_DOORBELL_RPTR, 203 ENABLE, 0); 204 } 205 return ih_doorbell_rtpr; 206 } 207 208 /** 209 * vega10_ih_irq_init - init and enable the interrupt ring 210 * 211 * @adev: amdgpu_device pointer 212 * 213 * Allocate a ring buffer for the interrupt controller, 214 * enable the RLC, disable interrupts, enable the IH 215 * ring buffer and enable it (VI). 216 * Called at device load and reume. 217 * Returns 0 for success, errors for failure. 218 */ 219 static int vega10_ih_irq_init(struct amdgpu_device *adev) 220 { 221 struct amdgpu_ih_ring *ih; 222 u32 ih_rb_cntl, ih_chicken; 223 int ret = 0; 224 u32 tmp; 225 226 /* disable irqs */ 227 vega10_ih_disable_interrupts(adev); 228 229 adev->nbio_funcs->ih_control(adev); 230 231 ih = &adev->irq.ih; 232 /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/ 233 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, ih->gpu_addr >> 8); 234 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (ih->gpu_addr >> 40) & 0xff); 235 236 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL); 237 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl); 238 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RPTR_REARM, 239 !!adev->irq.msi_enabled); 240 241 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 242 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL, ih_rb_cntl)) { 243 DRM_ERROR("PSP program IH_RB_CNTL failed!\n"); 244 return -ETIMEDOUT; 245 } 246 } else { 247 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl); 248 } 249 250 if (adev->asic_type == CHIP_ARCTURUS && 251 adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { 252 if (adev->irq.ih.use_bus_addr) { 253 ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN); 254 ih_chicken |= 0x00000010; 255 WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken); 256 } 257 } 258 259 /* set the writeback address whether it's enabled or not */ 260 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, 261 lower_32_bits(ih->wptr_addr)); 262 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, 263 upper_32_bits(ih->wptr_addr) & 0xFFFF); 264 265 /* set rptr, wptr to 0 */ 266 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0); 267 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0); 268 269 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR, 270 vega10_ih_doorbell_rptr(ih)); 271 272 ih = &adev->irq.ih1; 273 if (ih->ring_size) { 274 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING1, ih->gpu_addr >> 8); 275 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING1, 276 (ih->gpu_addr >> 40) & 0xff); 277 278 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); 279 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl); 280 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, 281 WPTR_OVERFLOW_ENABLE, 0); 282 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, 283 RB_FULL_DRAIN_ENABLE, 1); 284 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 285 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING1, 286 ih_rb_cntl)) { 287 DRM_ERROR("program IH_RB_CNTL_RING1 failed!\n"); 288 return -ETIMEDOUT; 289 } 290 } else { 291 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); 292 } 293 294 /* set rptr, wptr to 0 */ 295 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0); 296 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0); 297 298 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING1, 299 vega10_ih_doorbell_rptr(ih)); 300 } 301 302 ih = &adev->irq.ih2; 303 if (ih->ring_size) { 304 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_RING2, ih->gpu_addr >> 8); 305 WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI_RING2, 306 (ih->gpu_addr >> 40) & 0xff); 307 308 ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); 309 ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl); 310 311 if (amdgpu_virt_support_psp_prg_ih_reg(adev)) { 312 if (psp_reg_program(&adev->psp, PSP_REG_IH_RB_CNTL_RING2, 313 ih_rb_cntl)) { 314 DRM_ERROR("program IH_RB_CNTL_RING2 failed!\n"); 315 return -ETIMEDOUT; 316 } 317 } else { 318 WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); 319 } 320 321 /* set rptr, wptr to 0 */ 322 WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0); 323 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0); 324 325 WREG32_SOC15(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING2, 326 vega10_ih_doorbell_rptr(ih)); 327 } 328 329 tmp = RREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL); 330 tmp = REG_SET_FIELD(tmp, IH_STORM_CLIENT_LIST_CNTL, 331 CLIENT18_IS_STORM_CLIENT, 1); 332 WREG32_SOC15(OSSSYS, 0, mmIH_STORM_CLIENT_LIST_CNTL, tmp); 333 334 tmp = RREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL); 335 tmp = REG_SET_FIELD(tmp, IH_INT_FLOOD_CNTL, FLOOD_CNTL_ENABLE, 1); 336 WREG32_SOC15(OSSSYS, 0, mmIH_INT_FLOOD_CNTL, tmp); 337 338 pci_set_master(adev->pdev); 339 340 /* enable interrupts */ 341 vega10_ih_enable_interrupts(adev); 342 343 return ret; 344 } 345 346 /** 347 * vega10_ih_irq_disable - disable interrupts 348 * 349 * @adev: amdgpu_device pointer 350 * 351 * Disable interrupts on the hw (VEGA10). 352 */ 353 static void vega10_ih_irq_disable(struct amdgpu_device *adev) 354 { 355 vega10_ih_disable_interrupts(adev); 356 357 /* Wait and acknowledge irq */ 358 mdelay(1); 359 } 360 361 /** 362 * vega10_ih_get_wptr - get the IH ring buffer wptr 363 * 364 * @adev: amdgpu_device pointer 365 * 366 * Get the IH ring buffer wptr from either the register 367 * or the writeback memory buffer (VEGA10). Also check for 368 * ring buffer overflow and deal with it. 369 * Returns the value of the wptr. 370 */ 371 static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, 372 struct amdgpu_ih_ring *ih) 373 { 374 u32 wptr, reg, tmp; 375 376 wptr = le32_to_cpu(*ih->wptr_cpu); 377 378 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) 379 goto out; 380 381 /* Double check that the overflow wasn't already cleared. */ 382 383 if (ih == &adev->irq.ih) 384 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR); 385 else if (ih == &adev->irq.ih1) 386 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1); 387 else if (ih == &adev->irq.ih2) 388 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2); 389 else 390 BUG(); 391 392 wptr = RREG32_NO_KIQ(reg); 393 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) 394 goto out; 395 396 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); 397 398 /* When a ring buffer overflow happen start parsing interrupt 399 * from the last not overwritten vector (wptr + 32). Hopefully 400 * this should allow us to catchup. 401 */ 402 tmp = (wptr + 32) & ih->ptr_mask; 403 dev_warn(adev->dev, "IH ring buffer overflow " 404 "(0x%08X, 0x%08X, 0x%08X)\n", 405 wptr, ih->rptr, tmp); 406 ih->rptr = tmp; 407 408 if (ih == &adev->irq.ih) 409 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); 410 else if (ih == &adev->irq.ih1) 411 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1); 412 else if (ih == &adev->irq.ih2) 413 reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2); 414 else 415 BUG(); 416 417 tmp = RREG32_NO_KIQ(reg); 418 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); 419 WREG32_NO_KIQ(reg, tmp); 420 421 out: 422 return (wptr & ih->ptr_mask); 423 } 424 425 /** 426 * vega10_ih_decode_iv - decode an interrupt vector 427 * 428 * @adev: amdgpu_device pointer 429 * 430 * Decodes the interrupt vector at the current rptr 431 * position and also advance the position. 432 */ 433 static void vega10_ih_decode_iv(struct amdgpu_device *adev, 434 struct amdgpu_ih_ring *ih, 435 struct amdgpu_iv_entry *entry) 436 { 437 /* wptr/rptr are in bytes! */ 438 u32 ring_index = ih->rptr >> 2; 439 uint32_t dw[8]; 440 441 dw[0] = le32_to_cpu(ih->ring[ring_index + 0]); 442 dw[1] = le32_to_cpu(ih->ring[ring_index + 1]); 443 dw[2] = le32_to_cpu(ih->ring[ring_index + 2]); 444 dw[3] = le32_to_cpu(ih->ring[ring_index + 3]); 445 dw[4] = le32_to_cpu(ih->ring[ring_index + 4]); 446 dw[5] = le32_to_cpu(ih->ring[ring_index + 5]); 447 dw[6] = le32_to_cpu(ih->ring[ring_index + 6]); 448 dw[7] = le32_to_cpu(ih->ring[ring_index + 7]); 449 450 entry->client_id = dw[0] & 0xff; 451 entry->src_id = (dw[0] >> 8) & 0xff; 452 entry->ring_id = (dw[0] >> 16) & 0xff; 453 entry->vmid = (dw[0] >> 24) & 0xf; 454 entry->vmid_src = (dw[0] >> 31); 455 entry->timestamp = dw[1] | ((u64)(dw[2] & 0xffff) << 32); 456 entry->timestamp_src = dw[2] >> 31; 457 entry->pasid = dw[3] & 0xffff; 458 entry->pasid_src = dw[3] >> 31; 459 entry->src_data[0] = dw[4]; 460 entry->src_data[1] = dw[5]; 461 entry->src_data[2] = dw[6]; 462 entry->src_data[3] = dw[7]; 463 464 /* wptr/rptr are in bytes! */ 465 ih->rptr += 32; 466 } 467 468 /** 469 * vega10_ih_irq_rearm - rearm IRQ if lost 470 * 471 * @adev: amdgpu_device pointer 472 * 473 */ 474 static void vega10_ih_irq_rearm(struct amdgpu_device *adev, 475 struct amdgpu_ih_ring *ih) 476 { 477 uint32_t reg_rptr = 0; 478 uint32_t v = 0; 479 uint32_t i = 0; 480 481 if (ih == &adev->irq.ih) 482 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR); 483 else if (ih == &adev->irq.ih1) 484 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING1); 485 else if (ih == &adev->irq.ih2) 486 reg_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING2); 487 else 488 return; 489 490 /* Rearm IRQ / re-wwrite doorbell if doorbell write is lost */ 491 for (i = 0; i < MAX_REARM_RETRY; i++) { 492 v = RREG32_NO_KIQ(reg_rptr); 493 if ((v < ih->ring_size) && (v != ih->rptr)) 494 WDOORBELL32(ih->doorbell_index, ih->rptr); 495 else 496 break; 497 } 498 } 499 500 /** 501 * vega10_ih_set_rptr - set the IH ring buffer rptr 502 * 503 * @adev: amdgpu_device pointer 504 * 505 * Set the IH ring buffer rptr. 506 */ 507 static void vega10_ih_set_rptr(struct amdgpu_device *adev, 508 struct amdgpu_ih_ring *ih) 509 { 510 if (ih->use_doorbell) { 511 /* XXX check if swapping is necessary on BE */ 512 *ih->rptr_cpu = ih->rptr; 513 WDOORBELL32(ih->doorbell_index, ih->rptr); 514 515 if (amdgpu_sriov_vf(adev)) 516 vega10_ih_irq_rearm(adev, ih); 517 } else if (ih == &adev->irq.ih) { 518 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); 519 } else if (ih == &adev->irq.ih1) { 520 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr); 521 } else if (ih == &adev->irq.ih2) { 522 WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr); 523 } 524 } 525 526 /** 527 * vega10_ih_self_irq - dispatch work for ring 1 and 2 528 * 529 * @adev: amdgpu_device pointer 530 * @source: irq source 531 * @entry: IV with WPTR update 532 * 533 * Update the WPTR from the IV and schedule work to handle the entries. 534 */ 535 static int vega10_ih_self_irq(struct amdgpu_device *adev, 536 struct amdgpu_irq_src *source, 537 struct amdgpu_iv_entry *entry) 538 { 539 uint32_t wptr = cpu_to_le32(entry->src_data[0]); 540 541 switch (entry->ring_id) { 542 case 1: 543 *adev->irq.ih1.wptr_cpu = wptr; 544 schedule_work(&adev->irq.ih1_work); 545 break; 546 case 2: 547 *adev->irq.ih2.wptr_cpu = wptr; 548 schedule_work(&adev->irq.ih2_work); 549 break; 550 default: break; 551 } 552 return 0; 553 } 554 555 static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = { 556 .process = vega10_ih_self_irq, 557 }; 558 559 static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev) 560 { 561 adev->irq.self_irq.num_types = 0; 562 adev->irq.self_irq.funcs = &vega10_ih_self_irq_funcs; 563 } 564 565 static int vega10_ih_early_init(void *handle) 566 { 567 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 568 569 vega10_ih_set_interrupt_funcs(adev); 570 vega10_ih_set_self_irq_funcs(adev); 571 return 0; 572 } 573 574 static int vega10_ih_sw_init(void *handle) 575 { 576 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 577 int r; 578 579 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0, 580 &adev->irq.self_irq); 581 if (r) 582 return r; 583 584 r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true); 585 if (r) 586 return r; 587 588 adev->irq.ih.use_doorbell = true; 589 adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1; 590 591 r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true); 592 if (r) 593 return r; 594 595 adev->irq.ih1.use_doorbell = true; 596 adev->irq.ih1.doorbell_index = (adev->doorbell_index.ih + 1) << 1; 597 598 r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true); 599 if (r) 600 return r; 601 602 adev->irq.ih2.use_doorbell = true; 603 adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1; 604 605 r = amdgpu_irq_init(adev); 606 607 return r; 608 } 609 610 static int vega10_ih_sw_fini(void *handle) 611 { 612 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 613 614 amdgpu_irq_fini(adev); 615 amdgpu_ih_ring_fini(adev, &adev->irq.ih2); 616 amdgpu_ih_ring_fini(adev, &adev->irq.ih1); 617 amdgpu_ih_ring_fini(adev, &adev->irq.ih); 618 619 return 0; 620 } 621 622 static int vega10_ih_hw_init(void *handle) 623 { 624 int r; 625 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 626 627 r = vega10_ih_irq_init(adev); 628 if (r) 629 return r; 630 631 return 0; 632 } 633 634 static int vega10_ih_hw_fini(void *handle) 635 { 636 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 637 638 vega10_ih_irq_disable(adev); 639 640 return 0; 641 } 642 643 static int vega10_ih_suspend(void *handle) 644 { 645 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 646 647 return vega10_ih_hw_fini(adev); 648 } 649 650 static int vega10_ih_resume(void *handle) 651 { 652 struct amdgpu_device *adev = (struct amdgpu_device *)handle; 653 654 return vega10_ih_hw_init(adev); 655 } 656 657 static bool vega10_ih_is_idle(void *handle) 658 { 659 /* todo */ 660 return true; 661 } 662 663 static int vega10_ih_wait_for_idle(void *handle) 664 { 665 /* todo */ 666 return -ETIMEDOUT; 667 } 668 669 static int vega10_ih_soft_reset(void *handle) 670 { 671 /* todo */ 672 673 return 0; 674 } 675 676 static int vega10_ih_set_clockgating_state(void *handle, 677 enum amd_clockgating_state state) 678 { 679 return 0; 680 } 681 682 static int vega10_ih_set_powergating_state(void *handle, 683 enum amd_powergating_state state) 684 { 685 return 0; 686 } 687 688 const struct amd_ip_funcs vega10_ih_ip_funcs = { 689 .name = "vega10_ih", 690 .early_init = vega10_ih_early_init, 691 .late_init = NULL, 692 .sw_init = vega10_ih_sw_init, 693 .sw_fini = vega10_ih_sw_fini, 694 .hw_init = vega10_ih_hw_init, 695 .hw_fini = vega10_ih_hw_fini, 696 .suspend = vega10_ih_suspend, 697 .resume = vega10_ih_resume, 698 .is_idle = vega10_ih_is_idle, 699 .wait_for_idle = vega10_ih_wait_for_idle, 700 .soft_reset = vega10_ih_soft_reset, 701 .set_clockgating_state = vega10_ih_set_clockgating_state, 702 .set_powergating_state = vega10_ih_set_powergating_state, 703 }; 704 705 static const struct amdgpu_ih_funcs vega10_ih_funcs = { 706 .get_wptr = vega10_ih_get_wptr, 707 .decode_iv = vega10_ih_decode_iv, 708 .set_rptr = vega10_ih_set_rptr 709 }; 710 711 static void vega10_ih_set_interrupt_funcs(struct amdgpu_device *adev) 712 { 713 adev->irq.ih_funcs = &vega10_ih_funcs; 714 } 715 716 const struct amdgpu_ip_block_version vega10_ih_ip_block = 717 { 718 .type = AMD_IP_BLOCK_TYPE_IH, 719 .major = 4, 720 .minor = 0, 721 .rev = 0, 722 .funcs = &vega10_ih_ip_funcs, 723 }; 724