Merge tag 'drm-misc-next-fixes-2021-09-09' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / mxgpu_nv.c
index 48e588d..a35e6d8 100644 (file)
@@ -96,7 +96,11 @@ static int xgpu_nv_poll_ack(struct amdgpu_device *adev)
 
 static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
 {
-       int r, timeout = NV_MAILBOX_POLL_MSG_TIMEDOUT;
+       int r;
+       uint64_t timeout, now;
+
+       now = (uint64_t)ktime_to_ms(ktime_get());
+       timeout = now + NV_MAILBOX_POLL_MSG_TIMEDOUT;
 
        do {
                r = xgpu_nv_mailbox_rcv_msg(adev, event);
@@ -104,8 +108,8 @@ static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
                        return 0;
 
                msleep(10);
-               timeout -= 10;
-       } while (timeout > 1);
+               now = (uint64_t)ktime_to_ms(ktime_get());
+       } while (timeout > now);
 
 
        return -ETIME;
@@ -149,9 +153,10 @@ static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
 static int xgpu_nv_send_access_requests(struct amdgpu_device *adev,
                                        enum idh_request req)
 {
-       int r;
+       int r, retry = 1;
        enum idh_event event = -1;
 
+send_request:
        xgpu_nv_mailbox_trans_msg(adev, req, 0, 0, 0);
 
        switch (req) {
@@ -170,6 +175,9 @@ static int xgpu_nv_send_access_requests(struct amdgpu_device *adev,
        if (event != -1) {
                r = xgpu_nv_poll_msg(adev, event);
                if (r) {
+                       if (retry++ < 2)
+                               goto send_request;
+
                        if (req != IDH_REQ_GPU_INIT_DATA) {
                                pr_err("Doesn't get msg:%d from pf, error=%d\n", event, r);
                                return r;
@@ -273,12 +281,14 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
         * otherwise the mailbox msg will be ruined/reseted by
         * the VF FLR.
         */
-       if (!down_read_trylock(&adev->reset_sem))
+       if (!down_write_trylock(&adev->reset_sem))
                return;
 
        amdgpu_virt_fini_data_exchange(adev);
        atomic_set(&adev->in_gpu_reset, 1);
 
+       xgpu_nv_mailbox_trans_msg(adev, IDH_READY_TO_RESET, 0, 0, 0);
+
        do {
                if (xgpu_nv_mailbox_peek_msg(adev) == IDH_FLR_NOTIFICATION_CMPL)
                        goto flr_done;
@@ -289,7 +299,7 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
 
 flr_done:
        atomic_set(&adev->in_gpu_reset, 0);
-       up_read(&adev->reset_sem);
+       up_write(&adev->reset_sem);
 
        /* Trigger recovery for world switch failure if no TDR */
        if (amdgpu_device_should_recover_gpu(adev)