static int xgpu_ai_mailbox_rcv_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { enum idh_event event = xgpu_ai_mailbox_peek_msg(adev); switch (event) { case IDH_FLR_NOTIFICATION: if (amdgpu_sriov_runtime(adev)) schedule_work(&adev->virt.flr_work); break; case IDH_QUERY_ALIVE: xgpu_ai_mailbox_send_ack(adev); break; /* READY_TO_ACCESS_GPU is fetched by kernel polling, IRQ can ignore * it byfar since that polling thread will handle it, * other msg like flr complete is not handled here. */ case IDH_CLR_MSG_BUF: case IDH_FLR_NOTIFICATION_CMPL: case IDH_READY_TO_ACCESS_GPU: default: break; } return 0; }
static int xgpu_ai_mailbox_rcv_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { int r; /* trigger gpu-reset by hypervisor only if TDR disbaled */ if (!amdgpu_gpu_recovery) { /* see what event we get */ r = xgpu_ai_mailbox_rcv_msg(adev, IDH_FLR_NOTIFICATION); /* sometimes the interrupt is delayed to inject to VM, so under such case * the IDH_FLR_NOTIFICATION is overwritten by VF FLR from GIM side, thus * above recieve message could be failed, we should schedule the flr_work * anyway */ if (r) { DRM_ERROR("FLR_NOTIFICATION is missed\n"); xgpu_ai_mailbox_send_ack(adev); } schedule_work(&adev->virt.flr_work); } return 0; }
static int xgpu_ai_mailbox_rcv_msg(struct amdgpu_device *adev, enum idh_event event) { u32 reg; reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW0)); if (reg != event) return -ENOENT; xgpu_ai_mailbox_send_ack(adev); return 0; }
static int xgpu_ai_mailbox_rcv_msg(struct amdgpu_device *adev, enum idh_event event) { u32 reg; u32 mask = REG_FIELD_MASK(BIF_BX_PF0_MAILBOX_CONTROL, RCV_MSG_VALID); if (event != IDH_FLR_NOTIFICATION_CMPL) { reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_CONTROL)); if (!(reg & mask)) return -ENOENT; } reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW0)); if (reg != event) return -ENOENT; xgpu_ai_mailbox_send_ack(adev); return 0; }