Beispiel #1
0
/**
 * 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;
}