/** * iceland_ih_irq_disable - disable interrupts * * @adev: amdgpu_device pointer * * Disable interrupts on the hw (VI). */ static void iceland_ih_irq_disable(struct amdgpu_device *adev) { iceland_ih_disable_interrupts(adev); /* Wait and acknowledge irq */ mdelay(1); }
/** * iceland_ih_irq_init - init and enable the interrupt ring * * @adev: amdgpu_device pointer * * Allocate a ring buffer for the interrupt controller, * enable the RLC, disable interrupts, enable the IH * ring buffer and enable it (VI). * Called at device load and reume. * Returns 0 for success, errors for failure. */ static int iceland_ih_irq_init(struct amdgpu_device *adev) { int ret = 0; int rb_bufsz; u32 interrupt_cntl, ih_cntl, ih_rb_cntl; u64 wptr_off; /* disable irqs */ iceland_ih_disable_interrupts(adev); /* setup interrupt control */ WREG32(mmINTERRUPT_CNTL2, adev->dummy_page.addr >> 8); interrupt_cntl = RREG32(mmINTERRUPT_CNTL); /* INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=0 - dummy read disabled with msi, enabled without msi * INTERRUPT_CNTL__IH_DUMMY_RD_OVERRIDE_MASK=1 - dummy read controlled by IH_DUMMY_RD_EN */ interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_DUMMY_RD_OVERRIDE, 0); /* INTERRUPT_CNTL__IH_REQ_NONSNOOP_EN_MASK=1 if ring is in non-cacheable memory, e.g., vram */ interrupt_cntl = REG_SET_FIELD(interrupt_cntl, INTERRUPT_CNTL, IH_REQ_NONSNOOP_EN, 0); WREG32(mmINTERRUPT_CNTL, interrupt_cntl); /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/ WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8); rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4); ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz); /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register value is written to memory */ ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1); /* set the writeback address whether it's enabled or not */ wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4); WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off)); WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF); WREG32(mmIH_RB_CNTL, ih_rb_cntl); /* set rptr, wptr to 0 */ WREG32(mmIH_RB_RPTR, 0); WREG32(mmIH_RB_WPTR, 0); /* Default settings for IH_CNTL (disabled at first) */ ih_cntl = RREG32(mmIH_CNTL); ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, MC_VMID, 0); if (adev->irq.msi_enabled) ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL, RPTR_REARM, 1); WREG32(mmIH_CNTL, ih_cntl); pci_set_master(adev->pdev); /* enable interrupts */ iceland_ih_enable_interrupts(adev); return ret; }