]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
Merge branch 'for-linus' into for-next
[linux.git] / drivers / gpu / drm / amd / amdgpu / mxgpu_nv.c
1 /*
2  * Copyright 2014 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #include "amdgpu.h"
25 #include "nbio/nbio_2_3_offset.h"
26 #include "nbio/nbio_2_3_sh_mask.h"
27 #include "gc/gc_10_1_0_offset.h"
28 #include "gc/gc_10_1_0_sh_mask.h"
29 #include "soc15.h"
30 #include "navi10_ih.h"
31 #include "soc15_common.h"
32 #include "mxgpu_nv.h"
33 #include "mxgpu_ai.h"
34
35 static void xgpu_nv_mailbox_send_ack(struct amdgpu_device *adev)
36 {
37         WREG8(NV_MAIBOX_CONTROL_RCV_OFFSET_BYTE, 2);
38 }
39
40 static void xgpu_nv_mailbox_set_valid(struct amdgpu_device *adev, bool val)
41 {
42         WREG8(NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE, val ? 1 : 0);
43 }
44
45 /*
46  * this peek_msg could *only* be called in IRQ routine becuase in IRQ routine
47  * RCV_MSG_VALID filed of BIF_BX_PF_MAILBOX_CONTROL must already be set to 1
48  * by host.
49  *
50  * if called no in IRQ routine, this peek_msg cannot guaranteed to return the
51  * correct value since it doesn't return the RCV_DW0 under the case that
52  * RCV_MSG_VALID is set by host.
53  */
54 static enum idh_event xgpu_nv_mailbox_peek_msg(struct amdgpu_device *adev)
55 {
56         return RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
57                                 mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW0));
58 }
59
60
61 static int xgpu_nv_mailbox_rcv_msg(struct amdgpu_device *adev,
62                                    enum idh_event event)
63 {
64         u32 reg;
65
66         reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
67                                              mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW0));
68         if (reg != event)
69                 return -ENOENT;
70
71         xgpu_nv_mailbox_send_ack(adev);
72
73         return 0;
74 }
75
76 static uint8_t xgpu_nv_peek_ack(struct amdgpu_device *adev)
77 {
78         return RREG8(NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE) & 2;
79 }
80
81 static int xgpu_nv_poll_ack(struct amdgpu_device *adev)
82 {
83         int timeout  = NV_MAILBOX_POLL_ACK_TIMEDOUT;
84         u8 reg;
85
86         do {
87                 reg = RREG8(NV_MAIBOX_CONTROL_TRN_OFFSET_BYTE);
88                 if (reg & 2)
89                         return 0;
90
91                 mdelay(5);
92                 timeout -= 5;
93         } while (timeout > 1);
94
95         pr_err("Doesn't get TRN_MSG_ACK from pf in %d msec\n", NV_MAILBOX_POLL_ACK_TIMEDOUT);
96
97         return -ETIME;
98 }
99
100 static int xgpu_nv_poll_msg(struct amdgpu_device *adev, enum idh_event event)
101 {
102         int r, timeout = NV_MAILBOX_POLL_MSG_TIMEDOUT;
103
104         do {
105                 r = xgpu_nv_mailbox_rcv_msg(adev, event);
106                 if (!r)
107                         return 0;
108
109                 msleep(10);
110                 timeout -= 10;
111         } while (timeout > 1);
112
113         pr_err("Doesn't get msg:%d from pf, error=%d\n", event, r);
114
115         return -ETIME;
116 }
117
118 static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
119               enum idh_request req, u32 data1, u32 data2, u32 data3)
120 {
121         u32 reg;
122         int r;
123         uint8_t trn;
124
125         /* IMPORTANT:
126          * clear TRN_MSG_VALID valid to clear host's RCV_MSG_ACK
127          * and with host's RCV_MSG_ACK cleared hw automatically clear host's RCV_MSG_ACK
128          * which lead to VF's TRN_MSG_ACK cleared, otherwise below xgpu_nv_poll_ack()
129          * will return immediatly
130          */
131         do {
132                 xgpu_nv_mailbox_set_valid(adev, false);
133                 trn = xgpu_nv_peek_ack(adev);
134                 if (trn) {
135                         pr_err("trn=%x ACK should not assert! wait again !\n", trn);
136                         msleep(1);
137                 }
138         } while (trn);
139
140         reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
141                                              mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0));
142         reg = REG_SET_FIELD(reg, BIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0,
143                             MSGBUF_DATA, req);
144         WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW0),
145                       reg);
146         WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW1),
147                                 data1);
148         WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW2),
149                                 data2);
150         WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_MSGBUF_TRN_DW3),
151                                 data3);
152
153         xgpu_nv_mailbox_set_valid(adev, true);
154
155         /* start to poll ack */
156         r = xgpu_nv_poll_ack(adev);
157         if (r)
158                 pr_err("Doesn't get ack from pf, continue\n");
159
160         xgpu_nv_mailbox_set_valid(adev, false);
161 }
162
163 static int xgpu_nv_send_access_requests(struct amdgpu_device *adev,
164                                         enum idh_request req)
165 {
166         int r;
167
168         xgpu_nv_mailbox_trans_msg(adev, req, 0, 0, 0);
169
170         /* start to check msg if request is idh_req_gpu_init_access */
171         if (req == IDH_REQ_GPU_INIT_ACCESS ||
172                 req == IDH_REQ_GPU_FINI_ACCESS ||
173                 req == IDH_REQ_GPU_RESET_ACCESS) {
174                 r = xgpu_nv_poll_msg(adev, IDH_READY_TO_ACCESS_GPU);
175                 if (r) {
176                         pr_err("Doesn't get READY_TO_ACCESS_GPU from pf, give up\n");
177                         return r;
178                 }
179                 /* Retrieve checksum from mailbox2 */
180                 if (req == IDH_REQ_GPU_INIT_ACCESS || req == IDH_REQ_GPU_RESET_ACCESS) {
181                         adev->virt.fw_reserve.checksum_key =
182                                 RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0,
183                                         mmBIF_BX_PF_MAILBOX_MSGBUF_RCV_DW2));
184                 }
185         }
186
187         return 0;
188 }
189
190 static int xgpu_nv_request_reset(struct amdgpu_device *adev)
191 {
192         return xgpu_nv_send_access_requests(adev, IDH_REQ_GPU_RESET_ACCESS);
193 }
194
195 static int xgpu_nv_request_full_gpu_access(struct amdgpu_device *adev,
196                                            bool init)
197 {
198         enum idh_request req;
199
200         req = init ? IDH_REQ_GPU_INIT_ACCESS : IDH_REQ_GPU_FINI_ACCESS;
201         return xgpu_nv_send_access_requests(adev, req);
202 }
203
204 static int xgpu_nv_release_full_gpu_access(struct amdgpu_device *adev,
205                                            bool init)
206 {
207         enum idh_request req;
208         int r = 0;
209
210         req = init ? IDH_REL_GPU_INIT_ACCESS : IDH_REL_GPU_FINI_ACCESS;
211         r = xgpu_nv_send_access_requests(adev, req);
212
213         return r;
214 }
215
216 static int xgpu_nv_mailbox_ack_irq(struct amdgpu_device *adev,
217                                         struct amdgpu_irq_src *source,
218                                         struct amdgpu_iv_entry *entry)
219 {
220         DRM_DEBUG("get ack intr and do nothing.\n");
221         return 0;
222 }
223
224 static int xgpu_nv_set_mailbox_ack_irq(struct amdgpu_device *adev,
225                                         struct amdgpu_irq_src *source,
226                                         unsigned type,
227                                         enum amdgpu_interrupt_state state)
228 {
229         u32 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL));
230
231         tmp = REG_SET_FIELD(tmp, BIF_BX_PF_MAILBOX_INT_CNTL, ACK_INT_EN,
232                                 (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0);
233         WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL), tmp);
234
235         return 0;
236 }
237
238 static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
239 {
240         struct amdgpu_virt *virt = container_of(work, struct amdgpu_virt, flr_work);
241         struct amdgpu_device *adev = container_of(virt, struct amdgpu_device, virt);
242         int timeout = NV_MAILBOX_POLL_FLR_TIMEDOUT;
243         int locked;
244
245         /* block amdgpu_gpu_recover till msg FLR COMPLETE received,
246          * otherwise the mailbox msg will be ruined/reseted by
247          * the VF FLR.
248          *
249          * we can unlock the lock_reset to allow "amdgpu_job_timedout"
250          * to run gpu_recover() after FLR_NOTIFICATION_CMPL received
251          * which means host side had finished this VF's FLR.
252          */
253         locked = mutex_trylock(&adev->lock_reset);
254         if (locked)
255                 adev->in_gpu_reset = 1;
256
257         do {
258                 if (xgpu_nv_mailbox_peek_msg(adev) == IDH_FLR_NOTIFICATION_CMPL)
259                         goto flr_done;
260
261                 msleep(10);
262                 timeout -= 10;
263         } while (timeout > 1);
264
265 flr_done:
266         if (locked) {
267                 adev->in_gpu_reset = 0;
268                 mutex_unlock(&adev->lock_reset);
269         }
270
271         /* Trigger recovery for world switch failure if no TDR */
272         if (amdgpu_device_should_recover_gpu(adev))
273                 amdgpu_device_gpu_recover(adev, NULL);
274 }
275
276 static int xgpu_nv_set_mailbox_rcv_irq(struct amdgpu_device *adev,
277                                        struct amdgpu_irq_src *src,
278                                        unsigned type,
279                                        enum amdgpu_interrupt_state state)
280 {
281         u32 tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL));
282
283         tmp = REG_SET_FIELD(tmp, BIF_BX_PF_MAILBOX_INT_CNTL, VALID_INT_EN,
284                             (state == AMDGPU_IRQ_STATE_ENABLE) ? 1 : 0);
285         WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF_MAILBOX_INT_CNTL), tmp);
286
287         return 0;
288 }
289
290 static int xgpu_nv_mailbox_rcv_irq(struct amdgpu_device *adev,
291                                    struct amdgpu_irq_src *source,
292                                    struct amdgpu_iv_entry *entry)
293 {
294         enum idh_event event = xgpu_nv_mailbox_peek_msg(adev);
295
296         switch (event) {
297         case IDH_FLR_NOTIFICATION:
298                 if (amdgpu_sriov_runtime(adev))
299                         schedule_work(&adev->virt.flr_work);
300                 break;
301                 /* READY_TO_ACCESS_GPU is fetched by kernel polling, IRQ can ignore
302                  * it byfar since that polling thread will handle it,
303                  * other msg like flr complete is not handled here.
304                  */
305         case IDH_CLR_MSG_BUF:
306         case IDH_FLR_NOTIFICATION_CMPL:
307         case IDH_READY_TO_ACCESS_GPU:
308         default:
309                 break;
310         }
311
312         return 0;
313 }
314
315 static const struct amdgpu_irq_src_funcs xgpu_nv_mailbox_ack_irq_funcs = {
316         .set = xgpu_nv_set_mailbox_ack_irq,
317         .process = xgpu_nv_mailbox_ack_irq,
318 };
319
320 static const struct amdgpu_irq_src_funcs xgpu_nv_mailbox_rcv_irq_funcs = {
321         .set = xgpu_nv_set_mailbox_rcv_irq,
322         .process = xgpu_nv_mailbox_rcv_irq,
323 };
324
325 void xgpu_nv_mailbox_set_irq_funcs(struct amdgpu_device *adev)
326 {
327         adev->virt.ack_irq.num_types = 1;
328         adev->virt.ack_irq.funcs = &xgpu_nv_mailbox_ack_irq_funcs;
329         adev->virt.rcv_irq.num_types = 1;
330         adev->virt.rcv_irq.funcs = &xgpu_nv_mailbox_rcv_irq_funcs;
331 }
332
333 int xgpu_nv_mailbox_add_irq_id(struct amdgpu_device *adev)
334 {
335         int r;
336
337         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_BIF, 135, &adev->virt.rcv_irq);
338         if (r)
339                 return r;
340
341         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_BIF, 138, &adev->virt.ack_irq);
342         if (r) {
343                 amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0);
344                 return r;
345         }
346
347         return 0;
348 }
349
350 int xgpu_nv_mailbox_get_irq(struct amdgpu_device *adev)
351 {
352         int r;
353
354         r = amdgpu_irq_get(adev, &adev->virt.rcv_irq, 0);
355         if (r)
356                 return r;
357         r = amdgpu_irq_get(adev, &adev->virt.ack_irq, 0);
358         if (r) {
359                 amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0);
360                 return r;
361         }
362
363         INIT_WORK(&adev->virt.flr_work, xgpu_nv_mailbox_flr_work);
364
365         return 0;
366 }
367
368 void xgpu_nv_mailbox_put_irq(struct amdgpu_device *adev)
369 {
370         amdgpu_irq_put(adev, &adev->virt.ack_irq, 0);
371         amdgpu_irq_put(adev, &adev->virt.rcv_irq, 0);
372 }
373
374 const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
375         .req_full_gpu   = xgpu_nv_request_full_gpu_access,
376         .rel_full_gpu   = xgpu_nv_release_full_gpu_access,
377         .reset_gpu = xgpu_nv_request_reset,
378         .wait_reset = NULL,
379         .trans_msg = xgpu_nv_mailbox_trans_msg,
380 };