0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/pci.h>
0025
0026 #include "amdgpu.h"
0027 #include "amdgpu_ih.h"
0028 #include "soc15.h"
0029
0030 #include "oss/osssys_4_2_0_offset.h"
0031 #include "oss/osssys_4_2_0_sh_mask.h"
0032
0033 #include "soc15_common.h"
0034 #include "vega20_ih.h"
0035
0036 #define MAX_REARM_RETRY 10
0037
0038 #define mmIH_CHICKEN_ALDEBARAN 0x18d
0039 #define mmIH_CHICKEN_ALDEBARAN_BASE_IDX 0
0040
0041 static void vega20_ih_set_interrupt_funcs(struct amdgpu_device *adev);
0042
0043
0044
0045
0046
0047
0048
0049
0050 static void vega20_ih_init_register_offset(struct amdgpu_device *adev)
0051 {
0052 struct amdgpu_ih_regs *ih_regs;
0053
0054 if (adev->irq.ih.ring_size) {
0055 ih_regs = &adev->irq.ih.ih_regs;
0056 ih_regs->ih_rb_base = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE);
0057 ih_regs->ih_rb_base_hi = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI);
0058 ih_regs->ih_rb_cntl = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL);
0059 ih_regs->ih_rb_wptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR);
0060 ih_regs->ih_rb_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR);
0061 ih_regs->ih_doorbell_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_DOORBELL_RPTR);
0062 ih_regs->ih_rb_wptr_addr_lo = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO);
0063 ih_regs->ih_rb_wptr_addr_hi = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI);
0064 ih_regs->psp_reg_id = PSP_REG_IH_RB_CNTL;
0065 }
0066
0067 if (adev->irq.ih1.ring_size) {
0068 ih_regs = &adev->irq.ih1.ih_regs;
0069 ih_regs->ih_rb_base = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_RING1);
0070 ih_regs->ih_rb_base_hi = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI_RING1);
0071 ih_regs->ih_rb_cntl = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING1);
0072 ih_regs->ih_rb_wptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING1);
0073 ih_regs->ih_rb_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING1);
0074 ih_regs->ih_doorbell_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING1);
0075 ih_regs->psp_reg_id = PSP_REG_IH_RB_CNTL_RING1;
0076 }
0077
0078 if (adev->irq.ih2.ring_size) {
0079 ih_regs = &adev->irq.ih2.ih_regs;
0080 ih_regs->ih_rb_base = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_RING2);
0081 ih_regs->ih_rb_base_hi = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_BASE_HI_RING2);
0082 ih_regs->ih_rb_cntl = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL_RING2);
0083 ih_regs->ih_rb_wptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_WPTR_RING2);
0084 ih_regs->ih_rb_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_RPTR_RING2);
0085 ih_regs->ih_doorbell_rptr = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_DOORBELL_RPTR_RING2);
0086 ih_regs->psp_reg_id = PSP_REG_IH_RB_CNTL_RING2;
0087 }
0088 }
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099 static int vega20_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
0100 struct amdgpu_ih_ring *ih,
0101 bool enable)
0102 {
0103 struct amdgpu_ih_regs *ih_regs;
0104 uint32_t tmp;
0105
0106 ih_regs = &ih->ih_regs;
0107
0108 tmp = RREG32(ih_regs->ih_rb_cntl);
0109 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
0110 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
0111
0112
0113 if (ih == &adev->irq.ih)
0114 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
0115 if (amdgpu_sriov_vf(adev)) {
0116 if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
0117 dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
0118 return -ETIMEDOUT;
0119 }
0120 } else {
0121 WREG32(ih_regs->ih_rb_cntl, tmp);
0122 }
0123
0124 if (enable) {
0125 ih->enabled = true;
0126 } else {
0127
0128 WREG32(ih_regs->ih_rb_rptr, 0);
0129 WREG32(ih_regs->ih_rb_wptr, 0);
0130 ih->enabled = false;
0131 ih->rptr = 0;
0132 }
0133
0134 return 0;
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 static int vega20_ih_toggle_interrupts(struct amdgpu_device *adev, bool enable)
0146 {
0147 struct amdgpu_ih_ring *ih[] = {&adev->irq.ih, &adev->irq.ih1, &adev->irq.ih2};
0148 int i;
0149 int r;
0150
0151 for (i = 0; i < ARRAY_SIZE(ih); i++) {
0152 if (ih[i]->ring_size) {
0153 r = vega20_ih_toggle_ring_interrupts(adev, ih[i], enable);
0154 if (r)
0155 return r;
0156 }
0157 }
0158
0159 return 0;
0160 }
0161
0162 static uint32_t vega20_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl)
0163 {
0164 int rb_bufsz = order_base_2(ih->ring_size / 4);
0165
0166 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
0167 MC_SPACE, ih->use_bus_addr ? 1 : 4);
0168 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
0169 WPTR_OVERFLOW_CLEAR, 1);
0170 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
0171 WPTR_OVERFLOW_ENABLE, 1);
0172 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz);
0173
0174
0175
0176 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL,
0177 WPTR_WRITEBACK_ENABLE, 1);
0178 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1);
0179 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0);
0180 ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0);
0181
0182 return ih_rb_cntl;
0183 }
0184
0185 static uint32_t vega20_ih_doorbell_rptr(struct amdgpu_ih_ring *ih)
0186 {
0187 u32 ih_doorbell_rtpr = 0;
0188
0189 if (ih->use_doorbell) {
0190 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
0191 IH_DOORBELL_RPTR, OFFSET,
0192 ih->doorbell_index);
0193 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
0194 IH_DOORBELL_RPTR,
0195 ENABLE, 1);
0196 } else {
0197 ih_doorbell_rtpr = REG_SET_FIELD(ih_doorbell_rtpr,
0198 IH_DOORBELL_RPTR,
0199 ENABLE, 0);
0200 }
0201 return ih_doorbell_rtpr;
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 static int vega20_ih_enable_ring(struct amdgpu_device *adev,
0213 struct amdgpu_ih_ring *ih)
0214 {
0215 struct amdgpu_ih_regs *ih_regs;
0216 uint32_t tmp;
0217
0218 ih_regs = &ih->ih_regs;
0219
0220
0221 WREG32(ih_regs->ih_rb_base, ih->gpu_addr >> 8);
0222 WREG32(ih_regs->ih_rb_base_hi, (ih->gpu_addr >> 40) & 0xff);
0223
0224 tmp = RREG32(ih_regs->ih_rb_cntl);
0225 tmp = vega20_ih_rb_cntl(ih, tmp);
0226 if (ih == &adev->irq.ih)
0227 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RPTR_REARM, !!adev->irq.msi_enabled);
0228 if (ih == &adev->irq.ih1)
0229 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_FULL_DRAIN_ENABLE, 1);
0230 if (amdgpu_sriov_vf(adev)) {
0231 if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
0232 dev_err(adev->dev, "PSP program IH_RB_CNTL failed!\n");
0233 return -ETIMEDOUT;
0234 }
0235 } else {
0236 WREG32(ih_regs->ih_rb_cntl, tmp);
0237 }
0238
0239 if (ih == &adev->irq.ih) {
0240
0241 WREG32(ih_regs->ih_rb_wptr_addr_lo, lower_32_bits(ih->wptr_addr));
0242 WREG32(ih_regs->ih_rb_wptr_addr_hi, upper_32_bits(ih->wptr_addr) & 0xFFFF);
0243 }
0244
0245
0246 WREG32(ih_regs->ih_rb_wptr, 0);
0247 WREG32(ih_regs->ih_rb_rptr, 0);
0248
0249 WREG32(ih_regs->ih_doorbell_rptr, vega20_ih_doorbell_rptr(ih));
0250
0251 return 0;
0252 }
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 static void vega20_ih_reroute_ih(struct amdgpu_device *adev)
0264 {
0265 uint32_t tmp;
0266
0267
0268
0269
0270 if (adev->asic_type >= CHIP_ARCTURUS) {
0271
0272 WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x12);
0273 tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
0274 tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, CLIENT_TYPE, 1);
0275 tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
0276 WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
0277
0278
0279 WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_INDEX, 0x1B);
0280 tmp = RREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA);
0281 tmp = REG_SET_FIELD(tmp, IH_CLIENT_CFG_DATA, RING_ID, 1);
0282 WREG32_SOC15(OSSSYS, 0, mmIH_CLIENT_CFG_DATA, tmp);
0283 }
0284 }
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 static int vega20_ih_irq_init(struct amdgpu_device *adev)
0298 {
0299 struct amdgpu_ih_ring *ih[] = {&adev->irq.ih, &adev->irq.ih1, &adev->irq.ih2};
0300 u32 ih_chicken;
0301 int ret;
0302 int i;
0303
0304
0305 ret = vega20_ih_toggle_interrupts(adev, false);
0306 if (ret)
0307 return ret;
0308
0309 adev->nbio.funcs->ih_control(adev);
0310
0311 if (adev->asic_type == CHIP_ARCTURUS &&
0312 adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
0313 ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN);
0314 if (adev->irq.ih.use_bus_addr) {
0315 ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
0316 MC_SPACE_GPA_ENABLE, 1);
0317 }
0318 WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN, ih_chicken);
0319 }
0320
0321
0322
0323
0324 if (adev->asic_type == CHIP_ALDEBARAN) {
0325 ih_chicken = RREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_ALDEBARAN);
0326 if (adev->irq.ih.use_bus_addr) {
0327 ih_chicken = REG_SET_FIELD(ih_chicken, IH_CHICKEN,
0328 MC_SPACE_GPA_ENABLE, 1);
0329 }
0330 WREG32_SOC15(OSSSYS, 0, mmIH_CHICKEN_ALDEBARAN, ih_chicken);
0331 }
0332
0333 for (i = 0; i < ARRAY_SIZE(ih); i++) {
0334 if (ih[i]->ring_size) {
0335 if (i == 1)
0336 vega20_ih_reroute_ih(adev);
0337 ret = vega20_ih_enable_ring(adev, ih[i]);
0338 if (ret)
0339 return ret;
0340 }
0341 }
0342
0343 if (!amdgpu_sriov_vf(adev))
0344 adev->nbio.funcs->ih_doorbell_range(adev, adev->irq.ih.use_doorbell,
0345 adev->irq.ih.doorbell_index);
0346
0347 pci_set_master(adev->pdev);
0348
0349
0350 ret = vega20_ih_toggle_interrupts(adev, true);
0351 if (ret)
0352 return ret;
0353
0354 if (adev->irq.ih_soft.ring_size)
0355 adev->irq.ih_soft.enabled = true;
0356
0357 return 0;
0358 }
0359
0360
0361
0362
0363
0364
0365
0366
0367 static void vega20_ih_irq_disable(struct amdgpu_device *adev)
0368 {
0369 vega20_ih_toggle_interrupts(adev, false);
0370
0371
0372 mdelay(1);
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 static u32 vega20_ih_get_wptr(struct amdgpu_device *adev,
0387 struct amdgpu_ih_ring *ih)
0388 {
0389 u32 wptr, tmp;
0390 struct amdgpu_ih_regs *ih_regs;
0391
0392 if (ih == &adev->irq.ih || ih == &adev->irq.ih_soft) {
0393
0394
0395
0396
0397
0398 wptr = le32_to_cpu(*ih->wptr_cpu);
0399
0400 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
0401 goto out;
0402 }
0403
0404 ih_regs = &ih->ih_regs;
0405
0406
0407 wptr = RREG32_NO_KIQ(ih_regs->ih_rb_wptr);
0408 if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW))
0409 goto out;
0410
0411 wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
0412
0413
0414
0415
0416
0417 tmp = (wptr + 32) & ih->ptr_mask;
0418 dev_warn(adev->dev, "IH ring buffer overflow "
0419 "(0x%08X, 0x%08X, 0x%08X)\n",
0420 wptr, ih->rptr, tmp);
0421 ih->rptr = tmp;
0422
0423 tmp = RREG32_NO_KIQ(ih_regs->ih_rb_cntl);
0424 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
0425 WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
0426
0427 out:
0428 return (wptr & ih->ptr_mask);
0429 }
0430
0431
0432
0433
0434
0435
0436
0437
0438 static void vega20_ih_irq_rearm(struct amdgpu_device *adev,
0439 struct amdgpu_ih_ring *ih)
0440 {
0441 uint32_t v = 0;
0442 uint32_t i = 0;
0443 struct amdgpu_ih_regs *ih_regs;
0444
0445 ih_regs = &ih->ih_regs;
0446
0447
0448 for (i = 0; i < MAX_REARM_RETRY; i++) {
0449 v = RREG32_NO_KIQ(ih_regs->ih_rb_rptr);
0450 if ((v < ih->ring_size) && (v != ih->rptr))
0451 WDOORBELL32(ih->doorbell_index, ih->rptr);
0452 else
0453 break;
0454 }
0455 }
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465 static void vega20_ih_set_rptr(struct amdgpu_device *adev,
0466 struct amdgpu_ih_ring *ih)
0467 {
0468 struct amdgpu_ih_regs *ih_regs;
0469
0470 if (ih == &adev->irq.ih_soft)
0471 return;
0472
0473 if (ih->use_doorbell) {
0474
0475 *ih->rptr_cpu = ih->rptr;
0476 WDOORBELL32(ih->doorbell_index, ih->rptr);
0477
0478 if (amdgpu_sriov_vf(adev))
0479 vega20_ih_irq_rearm(adev, ih);
0480 } else {
0481 ih_regs = &ih->ih_regs;
0482 WREG32(ih_regs->ih_rb_rptr, ih->rptr);
0483 }
0484 }
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 static int vega20_ih_self_irq(struct amdgpu_device *adev,
0496 struct amdgpu_irq_src *source,
0497 struct amdgpu_iv_entry *entry)
0498 {
0499 switch (entry->ring_id) {
0500 case 1:
0501 schedule_work(&adev->irq.ih1_work);
0502 break;
0503 case 2:
0504 schedule_work(&adev->irq.ih2_work);
0505 break;
0506 default: break;
0507 }
0508 return 0;
0509 }
0510
0511 static const struct amdgpu_irq_src_funcs vega20_ih_self_irq_funcs = {
0512 .process = vega20_ih_self_irq,
0513 };
0514
0515 static void vega20_ih_set_self_irq_funcs(struct amdgpu_device *adev)
0516 {
0517 adev->irq.self_irq.num_types = 0;
0518 adev->irq.self_irq.funcs = &vega20_ih_self_irq_funcs;
0519 }
0520
0521 static int vega20_ih_early_init(void *handle)
0522 {
0523 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0524
0525 vega20_ih_set_interrupt_funcs(adev);
0526 vega20_ih_set_self_irq_funcs(adev);
0527 return 0;
0528 }
0529
0530 static int vega20_ih_sw_init(void *handle)
0531 {
0532 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0533 int r;
0534
0535 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0,
0536 &adev->irq.self_irq);
0537 if (r)
0538 return r;
0539
0540 r = amdgpu_ih_ring_init(adev, &adev->irq.ih, 256 * 1024, true);
0541 if (r)
0542 return r;
0543
0544 adev->irq.ih.use_doorbell = true;
0545 adev->irq.ih.doorbell_index = adev->doorbell_index.ih << 1;
0546
0547 r = amdgpu_ih_ring_init(adev, &adev->irq.ih1, PAGE_SIZE, true);
0548 if (r)
0549 return r;
0550
0551 adev->irq.ih1.use_doorbell = true;
0552 adev->irq.ih1.doorbell_index = (adev->doorbell_index.ih + 1) << 1;
0553
0554 r = amdgpu_ih_ring_init(adev, &adev->irq.ih2, PAGE_SIZE, true);
0555 if (r)
0556 return r;
0557
0558 adev->irq.ih2.use_doorbell = true;
0559 adev->irq.ih2.doorbell_index = (adev->doorbell_index.ih + 2) << 1;
0560
0561
0562 vega20_ih_init_register_offset(adev);
0563
0564 r = amdgpu_ih_ring_init(adev, &adev->irq.ih_soft, PAGE_SIZE, true);
0565 if (r)
0566 return r;
0567
0568 r = amdgpu_irq_init(adev);
0569
0570 return r;
0571 }
0572
0573 static int vega20_ih_sw_fini(void *handle)
0574 {
0575 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0576
0577 amdgpu_irq_fini_sw(adev);
0578
0579 return 0;
0580 }
0581
0582 static int vega20_ih_hw_init(void *handle)
0583 {
0584 int r;
0585 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0586
0587 r = vega20_ih_irq_init(adev);
0588 if (r)
0589 return r;
0590
0591 return 0;
0592 }
0593
0594 static int vega20_ih_hw_fini(void *handle)
0595 {
0596 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0597
0598 vega20_ih_irq_disable(adev);
0599
0600 return 0;
0601 }
0602
0603 static int vega20_ih_suspend(void *handle)
0604 {
0605 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0606
0607 return vega20_ih_hw_fini(adev);
0608 }
0609
0610 static int vega20_ih_resume(void *handle)
0611 {
0612 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0613
0614 return vega20_ih_hw_init(adev);
0615 }
0616
0617 static bool vega20_ih_is_idle(void *handle)
0618 {
0619
0620 return true;
0621 }
0622
0623 static int vega20_ih_wait_for_idle(void *handle)
0624 {
0625
0626 return -ETIMEDOUT;
0627 }
0628
0629 static int vega20_ih_soft_reset(void *handle)
0630 {
0631
0632
0633 return 0;
0634 }
0635
0636 static void vega20_ih_update_clockgating_state(struct amdgpu_device *adev,
0637 bool enable)
0638 {
0639 uint32_t data, def, field_val;
0640
0641 if (adev->cg_flags & AMD_CG_SUPPORT_IH_CG) {
0642 def = data = RREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL);
0643 field_val = enable ? 0 : 1;
0644 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0645 IH_RETRY_INT_CAM_MEM_CLK_SOFT_OVERRIDE, field_val);
0646 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0647 IH_BUFFER_MEM_CLK_SOFT_OVERRIDE, field_val);
0648 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0649 DBUS_MUX_CLK_SOFT_OVERRIDE, field_val);
0650 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0651 OSSSYS_SHARE_CLK_SOFT_OVERRIDE, field_val);
0652 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0653 LIMIT_SMN_CLK_SOFT_OVERRIDE, field_val);
0654 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0655 DYN_CLK_SOFT_OVERRIDE, field_val);
0656 data = REG_SET_FIELD(data, IH_CLK_CTRL,
0657 REG_CLK_SOFT_OVERRIDE, field_val);
0658 if (def != data)
0659 WREG32_SOC15(OSSSYS, 0, mmIH_CLK_CTRL, data);
0660 }
0661 }
0662
0663 static int vega20_ih_set_clockgating_state(void *handle,
0664 enum amd_clockgating_state state)
0665 {
0666 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0667
0668 vega20_ih_update_clockgating_state(adev,
0669 state == AMD_CG_STATE_GATE);
0670 return 0;
0671
0672 }
0673
0674 static int vega20_ih_set_powergating_state(void *handle,
0675 enum amd_powergating_state state)
0676 {
0677 return 0;
0678 }
0679
0680 const struct amd_ip_funcs vega20_ih_ip_funcs = {
0681 .name = "vega20_ih",
0682 .early_init = vega20_ih_early_init,
0683 .late_init = NULL,
0684 .sw_init = vega20_ih_sw_init,
0685 .sw_fini = vega20_ih_sw_fini,
0686 .hw_init = vega20_ih_hw_init,
0687 .hw_fini = vega20_ih_hw_fini,
0688 .suspend = vega20_ih_suspend,
0689 .resume = vega20_ih_resume,
0690 .is_idle = vega20_ih_is_idle,
0691 .wait_for_idle = vega20_ih_wait_for_idle,
0692 .soft_reset = vega20_ih_soft_reset,
0693 .set_clockgating_state = vega20_ih_set_clockgating_state,
0694 .set_powergating_state = vega20_ih_set_powergating_state,
0695 };
0696
0697 static const struct amdgpu_ih_funcs vega20_ih_funcs = {
0698 .get_wptr = vega20_ih_get_wptr,
0699 .decode_iv = amdgpu_ih_decode_iv_helper,
0700 .decode_iv_ts = amdgpu_ih_decode_iv_ts_helper,
0701 .set_rptr = vega20_ih_set_rptr
0702 };
0703
0704 static void vega20_ih_set_interrupt_funcs(struct amdgpu_device *adev)
0705 {
0706 adev->irq.ih_funcs = &vega20_ih_funcs;
0707 }
0708
0709 const struct amdgpu_ip_block_version vega20_ih_ip_block =
0710 {
0711 .type = AMD_IP_BLOCK_TYPE_IH,
0712 .major = 4,
0713 .minor = 2,
0714 .rev = 0,
0715 .funcs = &vega20_ih_ip_funcs,
0716 };