1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2 /* Copyright(c) 2014 - 2020 Intel Corporation */ 3 #include <linux/types.h> 4 #include <linux/mutex.h> 5 #include <linux/slab.h> 6 #include <linux/iopoll.h> 7 #include <linux/pci.h> 8 #include <linux/dma-mapping.h> 9 #include "adf_accel_devices.h" 10 #include "adf_common_drv.h" 11 #include "adf_cfg.h" 12 #include "adf_heartbeat.h" 13 #include "icp_qat_fw_init_admin.h" 14 15 #define ADF_ADMIN_MAILBOX_STRIDE 0x1000 16 #define ADF_ADMINMSG_LEN 32 17 #define ADF_CONST_TABLE_SIZE 1024 18 #define ADF_ADMIN_POLL_DELAY_US 20 19 #define ADF_ADMIN_POLL_TIMEOUT_US (5 * USEC_PER_SEC) 20 #define ADF_ONE_AE 1 21 22 static const u8 const_tab[1024] __aligned(1024) = { 23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 29 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 30 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 31 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 32 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 34 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 35 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 36 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 37 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 38 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 48 0x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 50 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 51 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e, 54 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39, 55 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe, 56 0xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 58 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 59 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05, 60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 0x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29, 62 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17, 63 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff, 64 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c, 65 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 66 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 68 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 69 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52, 70 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f, 71 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 72 0x7e, 0x21, 0x79, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x18, 76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 78 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0x00, 80 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02, 81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 82 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 83 0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 84 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 85 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 86 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 88 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01, 89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 91 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 102 103 struct adf_admin_comms { 104 dma_addr_t phy_addr; 105 dma_addr_t const_tbl_addr; 106 void *virt_addr; 107 void *virt_tbl_addr; 108 void __iomem *mailbox_addr; 109 struct mutex lock; /* protects adf_admin_comms struct */ 110 }; 111 112 static int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev, u32 ae, 113 void *in, void *out) 114 { 115 int ret; 116 u32 status; 117 struct adf_admin_comms *admin = accel_dev->admin; 118 int offset = ae * ADF_ADMINMSG_LEN * 2; 119 void __iomem *mailbox = admin->mailbox_addr; 120 int mb_offset = ae * ADF_ADMIN_MAILBOX_STRIDE; 121 struct icp_qat_fw_init_admin_req *request = in; 122 123 mutex_lock(&admin->lock); 124 125 if (ADF_CSR_RD(mailbox, mb_offset) == 1) { 126 mutex_unlock(&admin->lock); 127 return -EAGAIN; 128 } 129 130 memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN); 131 ADF_CSR_WR(mailbox, mb_offset, 1); 132 133 ret = read_poll_timeout(ADF_CSR_RD, status, status == 0, 134 ADF_ADMIN_POLL_DELAY_US, 135 ADF_ADMIN_POLL_TIMEOUT_US, true, 136 mailbox, mb_offset); 137 if (ret < 0) { 138 /* Response timeout */ 139 dev_err(&GET_DEV(accel_dev), 140 "Failed to send admin msg %d to accelerator %d\n", 141 request->cmd_id, ae); 142 } else { 143 /* Response received from admin message, we can now 144 * make response data available in "out" parameter. 145 */ 146 memcpy(out, admin->virt_addr + offset + 147 ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN); 148 } 149 150 mutex_unlock(&admin->lock); 151 return ret; 152 } 153 154 static int adf_send_admin(struct adf_accel_dev *accel_dev, 155 struct icp_qat_fw_init_admin_req *req, 156 struct icp_qat_fw_init_admin_resp *resp, 157 const unsigned long ae_mask) 158 { 159 u32 ae; 160 161 for_each_set_bit(ae, &ae_mask, ICP_QAT_HW_AE_DELIMITER) 162 if (adf_put_admin_msg_sync(accel_dev, ae, req, resp) || 163 resp->status) 164 return -EFAULT; 165 166 return 0; 167 } 168 169 static int adf_init_ae(struct adf_accel_dev *accel_dev) 170 { 171 struct icp_qat_fw_init_admin_req req; 172 struct icp_qat_fw_init_admin_resp resp; 173 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 174 u32 ae_mask = hw_device->ae_mask; 175 176 memset(&req, 0, sizeof(req)); 177 memset(&resp, 0, sizeof(resp)); 178 req.cmd_id = ICP_QAT_FW_INIT_AE; 179 180 return adf_send_admin(accel_dev, &req, &resp, ae_mask); 181 } 182 183 static int adf_set_fw_constants(struct adf_accel_dev *accel_dev) 184 { 185 struct icp_qat_fw_init_admin_req req; 186 struct icp_qat_fw_init_admin_resp resp; 187 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 188 u32 ae_mask = hw_device->admin_ae_mask ?: hw_device->ae_mask; 189 190 memset(&req, 0, sizeof(req)); 191 memset(&resp, 0, sizeof(resp)); 192 req.cmd_id = ICP_QAT_FW_CONSTANTS_CFG; 193 194 req.init_cfg_sz = ADF_CONST_TABLE_SIZE; 195 req.init_cfg_ptr = accel_dev->admin->const_tbl_addr; 196 197 return adf_send_admin(accel_dev, &req, &resp, ae_mask); 198 } 199 200 int adf_get_fw_timestamp(struct adf_accel_dev *accel_dev, u64 *timestamp) 201 { 202 struct icp_qat_fw_init_admin_req req = { }; 203 struct icp_qat_fw_init_admin_resp resp; 204 unsigned int ae_mask = ADF_ONE_AE; 205 int ret; 206 207 req.cmd_id = ICP_QAT_FW_TIMER_GET; 208 ret = adf_send_admin(accel_dev, &req, &resp, ae_mask); 209 if (ret) 210 return ret; 211 212 *timestamp = resp.timestamp; 213 return 0; 214 } 215 216 static int adf_set_chaining(struct adf_accel_dev *accel_dev) 217 { 218 u32 ae_mask = GET_HW_DATA(accel_dev)->ae_mask; 219 struct icp_qat_fw_init_admin_resp resp = { }; 220 struct icp_qat_fw_init_admin_req req = { }; 221 222 req.cmd_id = ICP_QAT_FW_DC_CHAIN_INIT; 223 224 return adf_send_admin(accel_dev, &req, &resp, ae_mask); 225 } 226 227 static int adf_get_dc_capabilities(struct adf_accel_dev *accel_dev, 228 u32 *capabilities) 229 { 230 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 231 struct icp_qat_fw_init_admin_resp resp; 232 struct icp_qat_fw_init_admin_req req; 233 unsigned long ae_mask; 234 unsigned long ae; 235 int ret; 236 237 /* Target only service accelerator engines */ 238 ae_mask = hw_device->ae_mask & ~hw_device->admin_ae_mask; 239 240 memset(&req, 0, sizeof(req)); 241 memset(&resp, 0, sizeof(resp)); 242 req.cmd_id = ICP_QAT_FW_COMP_CAPABILITY_GET; 243 244 *capabilities = 0; 245 for_each_set_bit(ae, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) { 246 ret = adf_send_admin(accel_dev, &req, &resp, 1ULL << ae); 247 if (ret) 248 return ret; 249 250 *capabilities |= resp.extended_features; 251 } 252 253 return 0; 254 } 255 256 int adf_get_ae_fw_counters(struct adf_accel_dev *accel_dev, u16 ae, u64 *reqs, u64 *resps) 257 { 258 struct icp_qat_fw_init_admin_resp resp = { }; 259 struct icp_qat_fw_init_admin_req req = { }; 260 int ret; 261 262 req.cmd_id = ICP_QAT_FW_COUNTERS_GET; 263 264 ret = adf_put_admin_msg_sync(accel_dev, ae, &req, &resp); 265 if (ret || resp.status) 266 return -EFAULT; 267 268 *reqs = resp.req_rec_count; 269 *resps = resp.resp_sent_count; 270 271 return 0; 272 } 273 274 int adf_send_admin_tim_sync(struct adf_accel_dev *accel_dev, u32 cnt) 275 { 276 u32 ae_mask = accel_dev->hw_device->ae_mask; 277 struct icp_qat_fw_init_admin_req req = { }; 278 struct icp_qat_fw_init_admin_resp resp = { }; 279 280 req.cmd_id = ICP_QAT_FW_SYNC; 281 req.int_timer_ticks = cnt; 282 283 return adf_send_admin(accel_dev, &req, &resp, ae_mask); 284 } 285 286 int adf_send_admin_hb_timer(struct adf_accel_dev *accel_dev, uint32_t ticks) 287 { 288 u32 ae_mask = accel_dev->hw_device->ae_mask; 289 struct icp_qat_fw_init_admin_req req = { }; 290 struct icp_qat_fw_init_admin_resp resp; 291 292 req.cmd_id = ICP_QAT_FW_HEARTBEAT_TIMER_SET; 293 req.init_cfg_ptr = accel_dev->heartbeat->dma.phy_addr; 294 req.heartbeat_ticks = ticks; 295 296 return adf_send_admin(accel_dev, &req, &resp, ae_mask); 297 } 298 299 static bool is_dcc_enabled(struct adf_accel_dev *accel_dev) 300 { 301 char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; 302 int ret; 303 304 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, 305 ADF_SERVICES_ENABLED, services); 306 if (ret) 307 return false; 308 309 return !strcmp(services, "dcc"); 310 } 311 312 /** 313 * adf_send_admin_init() - Function sends init message to FW 314 * @accel_dev: Pointer to acceleration device. 315 * 316 * Function sends admin init message to the FW 317 * 318 * Return: 0 on success, error code otherwise. 319 */ 320 int adf_send_admin_init(struct adf_accel_dev *accel_dev) 321 { 322 u32 dc_capabilities = 0; 323 int ret; 324 325 ret = adf_set_fw_constants(accel_dev); 326 if (ret) 327 return ret; 328 329 if (is_dcc_enabled(accel_dev)) { 330 ret = adf_set_chaining(accel_dev); 331 if (ret) 332 return ret; 333 } 334 335 ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities); 336 if (ret) { 337 dev_err(&GET_DEV(accel_dev), "Cannot get dc capabilities\n"); 338 return ret; 339 } 340 accel_dev->hw_device->extended_dc_capabilities = dc_capabilities; 341 342 return adf_init_ae(accel_dev); 343 } 344 EXPORT_SYMBOL_GPL(adf_send_admin_init); 345 346 /** 347 * adf_init_admin_pm() - Function sends PM init message to FW 348 * @accel_dev: Pointer to acceleration device. 349 * @idle_delay: QAT HW idle time before power gating is initiated. 350 * 000 - 64us 351 * 001 - 128us 352 * 010 - 256us 353 * 011 - 512us 354 * 100 - 1ms 355 * 101 - 2ms 356 * 110 - 4ms 357 * 111 - 8ms 358 * 359 * Function sends to the FW the admin init message for the PM state 360 * configuration. 361 * 362 * Return: 0 on success, error code otherwise. 363 */ 364 int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay) 365 { 366 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 367 struct icp_qat_fw_init_admin_resp resp = {0}; 368 struct icp_qat_fw_init_admin_req req = {0}; 369 u32 ae_mask = hw_data->admin_ae_mask; 370 371 if (!accel_dev->admin) { 372 dev_err(&GET_DEV(accel_dev), "adf_admin is not available\n"); 373 return -EFAULT; 374 } 375 376 req.cmd_id = ICP_QAT_FW_PM_STATE_CONFIG; 377 req.idle_filter = idle_delay; 378 379 return adf_send_admin(accel_dev, &req, &resp, ae_mask); 380 } 381 382 int adf_init_admin_comms(struct adf_accel_dev *accel_dev) 383 { 384 struct adf_admin_comms *admin; 385 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 386 void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); 387 struct admin_info admin_csrs_info; 388 u32 mailbox_offset, adminmsg_u, adminmsg_l; 389 void __iomem *mailbox; 390 u64 reg_val; 391 392 admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL, 393 dev_to_node(&GET_DEV(accel_dev))); 394 if (!admin) 395 return -ENOMEM; 396 admin->virt_addr = dma_alloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE, 397 &admin->phy_addr, GFP_KERNEL); 398 if (!admin->virt_addr) { 399 dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n"); 400 kfree(admin); 401 return -ENOMEM; 402 } 403 404 admin->virt_tbl_addr = dma_alloc_coherent(&GET_DEV(accel_dev), 405 PAGE_SIZE, 406 &admin->const_tbl_addr, 407 GFP_KERNEL); 408 if (!admin->virt_tbl_addr) { 409 dev_err(&GET_DEV(accel_dev), "Failed to allocate const_tbl\n"); 410 dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE, 411 admin->virt_addr, admin->phy_addr); 412 kfree(admin); 413 return -ENOMEM; 414 } 415 416 memcpy(admin->virt_tbl_addr, const_tab, sizeof(const_tab)); 417 hw_data->get_admin_info(&admin_csrs_info); 418 419 mailbox_offset = admin_csrs_info.mailbox_offset; 420 mailbox = pmisc_addr + mailbox_offset; 421 adminmsg_u = admin_csrs_info.admin_msg_ur; 422 adminmsg_l = admin_csrs_info.admin_msg_lr; 423 424 reg_val = (u64)admin->phy_addr; 425 ADF_CSR_WR(pmisc_addr, adminmsg_u, upper_32_bits(reg_val)); 426 ADF_CSR_WR(pmisc_addr, adminmsg_l, lower_32_bits(reg_val)); 427 428 mutex_init(&admin->lock); 429 admin->mailbox_addr = mailbox; 430 accel_dev->admin = admin; 431 return 0; 432 } 433 EXPORT_SYMBOL_GPL(adf_init_admin_comms); 434 435 void adf_exit_admin_comms(struct adf_accel_dev *accel_dev) 436 { 437 struct adf_admin_comms *admin = accel_dev->admin; 438 439 if (!admin) 440 return; 441 442 if (admin->virt_addr) 443 dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE, 444 admin->virt_addr, admin->phy_addr); 445 if (admin->virt_tbl_addr) 446 dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE, 447 admin->virt_tbl_addr, admin->const_tbl_addr); 448 449 mutex_destroy(&admin->lock); 450 kfree(admin); 451 accel_dev->admin = NULL; 452 } 453 EXPORT_SYMBOL_GPL(adf_exit_admin_comms); 454