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 "vega10/soc15ip.h" 26 #include "vega10/NBIO/nbio_6_1_offset.h" 27 #include "vega10/NBIO/nbio_6_1_sh_mask.h" 28 #include "vega10/GC/gc_9_0_offset.h" 29 #include "vega10/GC/gc_9_0_sh_mask.h" 30 #include "soc15.h" 31 #include "soc15_common.h" 32 #include "mxgpu_ai.h" 33 34 static void xgpu_ai_mailbox_send_ack(struct amdgpu_device *adev) 35 { 36 u32 reg; 37 int timeout = AI_MAILBOX_TIMEDOUT; 38 u32 mask = REG_FIELD_MASK(BIF_BX_PF0_MAILBOX_CONTROL, RCV_MSG_VALID); 39 40 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 41 mmBIF_BX_PF0_MAILBOX_CONTROL)); 42 reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_CONTROL, RCV_MSG_ACK, 1); 43 WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 44 mmBIF_BX_PF0_MAILBOX_CONTROL), reg); 45 46 /*Wait for RCV_MSG_VALID to be 0*/ 47 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 48 mmBIF_BX_PF0_MAILBOX_CONTROL)); 49 while (reg & mask) { 50 if (timeout <= 0) { 51 pr_err("RCV_MSG_VALID is not cleared\n"); 52 break; 53 } 54 mdelay(1); 55 timeout -=1; 56 57 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 58 mmBIF_BX_PF0_MAILBOX_CONTROL)); 59 } 60 } 61 62 static void xgpu_ai_mailbox_set_valid(struct amdgpu_device *adev, bool val) 63 { 64 u32 reg; 65 66 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 67 mmBIF_BX_PF0_MAILBOX_CONTROL)); 68 reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_CONTROL, 69 TRN_MSG_VALID, val ? 1 : 0); 70 WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_CONTROL), 71 reg); 72 } 73 74 static void xgpu_ai_mailbox_trans_msg(struct amdgpu_device *adev, 75 enum idh_request req) 76 { 77 u32 reg; 78 79 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 80 mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0)); 81 reg = REG_SET_FIELD(reg, BIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0, 82 MSGBUF_DATA, req); 83 WREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, mmBIF_BX_PF0_MAILBOX_MSGBUF_TRN_DW0), 84 reg); 85 86 xgpu_ai_mailbox_set_valid(adev, true); 87 } 88 89 static int xgpu_ai_mailbox_rcv_msg(struct amdgpu_device *adev, 90 enum idh_event event) 91 { 92 u32 reg; 93 u32 mask = REG_FIELD_MASK(BIF_BX_PF0_MAILBOX_CONTROL, RCV_MSG_VALID); 94 95 if (event != IDH_FLR_NOTIFICATION_CMPL) { 96 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 97 mmBIF_BX_PF0_MAILBOX_CONTROL)); 98 if (!(reg & mask)) 99 return -ENOENT; 100 } 101 102 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 103 mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW0)); 104 if (reg != event) 105 return -ENOENT; 106 107 xgpu_ai_mailbox_send_ack(adev); 108 109 return 0; 110 } 111 112 static int xgpu_ai_poll_ack(struct amdgpu_device *adev) 113 { 114 int r = 0, timeout = AI_MAILBOX_TIMEDOUT; 115 u32 mask = REG_FIELD_MASK(BIF_BX_PF0_MAILBOX_CONTROL, TRN_MSG_ACK); 116 u32 reg; 117 118 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 119 mmBIF_BX_PF0_MAILBOX_CONTROL)); 120 while (!(reg & mask)) { 121 if (timeout <= 0) { 122 pr_err("Doesn't get ack from pf.\n"); 123 r = -ETIME; 124 break; 125 } 126 msleep(1); 127 timeout -= 1; 128 129 reg = RREG32_NO_KIQ(SOC15_REG_OFFSET(NBIO, 0, 130 mmBIF_BX_PF0_MAILBOX_CONTROL)); 131 } 132 133 return r; 134 } 135 136 static int xgpu_vi_poll_msg(struct amdgpu_device *adev, enum idh_event event) 137 { 138 int r = 0, timeout = AI_MAILBOX_TIMEDOUT; 139 140 r = xgpu_ai_mailbox_rcv_msg(adev, event); 141 while (r) { 142 if (timeout <= 0) { 143 pr_err("Doesn't get ack from pf.\n"); 144 r = -ETIME; 145 break; 146 } 147 msleep(1); 148 timeout -= 1; 149 150 r = xgpu_ai_mailbox_rcv_msg(adev, event); 151 } 152 153 return r; 154 } 155 156 157 static int xgpu_ai_send_access_requests(struct amdgpu_device *adev, 158 enum idh_request req) 159 { 160 int r; 161 162 xgpu_ai_mailbox_trans_msg(adev, req); 163 164 /* start to poll ack */ 165 r = xgpu_ai_poll_ack(adev); 166 if (r) 167 return r; 168 169 xgpu_ai_mailbox_set_valid(adev, false); 170 171 /* start to check msg if request is idh_req_gpu_init_access */ 172 if (req == IDH_REQ_GPU_INIT_ACCESS || 173 req == IDH_REQ_GPU_FINI_ACCESS || 174 req == IDH_REQ_GPU_RESET_ACCESS) { 175 r = xgpu_vi_poll_msg(adev, IDH_READY_TO_ACCESS_GPU); 176 if (r) 177 return r; 178 } 179 180 return 0; 181 } 182 183 static int xgpu_ai_request_full_gpu_access(struct amdgpu_device *adev, 184 bool init) 185 { 186 enum idh_request req; 187 188 req = init ? IDH_REQ_GPU_INIT_ACCESS : IDH_REQ_GPU_FINI_ACCESS; 189 return xgpu_ai_send_access_requests(adev, req); 190 } 191 192 static int xgpu_ai_release_full_gpu_access(struct amdgpu_device *adev, 193 bool init) 194 { 195 enum idh_request req; 196 int r = 0; 197 198 req = init ? IDH_REL_GPU_INIT_ACCESS : IDH_REL_GPU_FINI_ACCESS; 199 r = xgpu_ai_send_access_requests(adev, req); 200 201 return r; 202 } 203 204 const struct amdgpu_virt_ops xgpu_ai_virt_ops = { 205 .req_full_gpu = xgpu_ai_request_full_gpu_access, 206 .rel_full_gpu = xgpu_ai_release_full_gpu_access, 207 }; 208