1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) 2 /* Copyright(c) 2014 - 2020 Intel Corporation */ 3 #include <linux/delay.h> 4 #include <linux/firmware.h> 5 #include <linux/pci.h> 6 #include "adf_cfg.h" 7 #include "adf_accel_devices.h" 8 #include "adf_common_drv.h" 9 #include "icp_qat_uclo.h" 10 11 static int adf_ae_fw_load_images(struct adf_accel_dev *accel_dev, void *fw_addr, 12 u32 fw_size) 13 { 14 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 15 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 16 struct icp_qat_fw_loader_handle *loader; 17 const char *obj_name; 18 u32 num_objs; 19 u32 ae_mask; 20 int i; 21 22 loader = loader_data->fw_loader; 23 num_objs = hw_device->uof_get_num_objs(accel_dev); 24 25 for (i = 0; i < num_objs; i++) { 26 obj_name = hw_device->uof_get_name(accel_dev, i); 27 ae_mask = hw_device->uof_get_ae_mask(accel_dev, i); 28 if (!obj_name || !ae_mask) { 29 dev_err(&GET_DEV(accel_dev), "Invalid UOF image\n"); 30 goto out_err; 31 } 32 33 if (qat_uclo_set_cfg_ae_mask(loader, ae_mask)) { 34 dev_err(&GET_DEV(accel_dev), 35 "Invalid mask for UOF image\n"); 36 goto out_err; 37 } 38 if (qat_uclo_map_obj(loader, fw_addr, fw_size, obj_name)) { 39 dev_err(&GET_DEV(accel_dev), 40 "Failed to map UOF firmware\n"); 41 goto out_err; 42 } 43 if (qat_uclo_wr_all_uimage(loader)) { 44 dev_err(&GET_DEV(accel_dev), 45 "Failed to load UOF firmware\n"); 46 goto out_err; 47 } 48 qat_uclo_del_obj(loader); 49 } 50 51 return 0; 52 53 out_err: 54 adf_ae_fw_release(accel_dev); 55 return -EFAULT; 56 } 57 58 int adf_ae_fw_load(struct adf_accel_dev *accel_dev) 59 { 60 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 61 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 62 void *fw_addr, *mmp_addr; 63 u32 fw_size, mmp_size; 64 65 if (!hw_device->fw_name) 66 return 0; 67 68 if (request_firmware(&loader_data->mmp_fw, hw_device->fw_mmp_name, 69 &accel_dev->accel_pci_dev.pci_dev->dev)) { 70 dev_err(&GET_DEV(accel_dev), "Failed to load MMP firmware %s\n", 71 hw_device->fw_mmp_name); 72 return -EFAULT; 73 } 74 if (request_firmware(&loader_data->uof_fw, hw_device->fw_name, 75 &accel_dev->accel_pci_dev.pci_dev->dev)) { 76 dev_err(&GET_DEV(accel_dev), "Failed to load UOF firmware %s\n", 77 hw_device->fw_name); 78 goto out_err; 79 } 80 81 fw_size = loader_data->uof_fw->size; 82 fw_addr = (void *)loader_data->uof_fw->data; 83 mmp_size = loader_data->mmp_fw->size; 84 mmp_addr = (void *)loader_data->mmp_fw->data; 85 86 if (qat_uclo_wr_mimage(loader_data->fw_loader, mmp_addr, mmp_size)) { 87 dev_err(&GET_DEV(accel_dev), "Failed to load MMP\n"); 88 goto out_err; 89 } 90 91 if (hw_device->uof_get_num_objs) 92 return adf_ae_fw_load_images(accel_dev, fw_addr, fw_size); 93 94 if (qat_uclo_map_obj(loader_data->fw_loader, fw_addr, fw_size, NULL)) { 95 dev_err(&GET_DEV(accel_dev), "Failed to map FW\n"); 96 goto out_err; 97 } 98 if (qat_uclo_wr_all_uimage(loader_data->fw_loader)) { 99 dev_err(&GET_DEV(accel_dev), "Failed to load UOF\n"); 100 goto out_err; 101 } 102 return 0; 103 104 out_err: 105 adf_ae_fw_release(accel_dev); 106 return -EFAULT; 107 } 108 109 void adf_ae_fw_release(struct adf_accel_dev *accel_dev) 110 { 111 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 112 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 113 114 if (!hw_device->fw_name) 115 return; 116 117 qat_uclo_del_obj(loader_data->fw_loader); 118 qat_hal_deinit(loader_data->fw_loader); 119 release_firmware(loader_data->uof_fw); 120 release_firmware(loader_data->mmp_fw); 121 loader_data->uof_fw = NULL; 122 loader_data->mmp_fw = NULL; 123 loader_data->fw_loader = NULL; 124 } 125 126 int adf_ae_start(struct adf_accel_dev *accel_dev) 127 { 128 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 129 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 130 u32 ae_ctr; 131 132 if (!hw_data->fw_name) 133 return 0; 134 135 ae_ctr = qat_hal_start(loader_data->fw_loader); 136 dev_info(&GET_DEV(accel_dev), 137 "qat_dev%d started %d acceleration engines\n", 138 accel_dev->accel_id, ae_ctr); 139 return 0; 140 } 141 142 int adf_ae_stop(struct adf_accel_dev *accel_dev) 143 { 144 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 145 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 146 u32 ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev); 147 148 if (!hw_data->fw_name) 149 return 0; 150 151 for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) { 152 if (hw_data->ae_mask & (1 << ae)) { 153 qat_hal_stop(loader_data->fw_loader, ae, 0xFF); 154 ae_ctr++; 155 } 156 } 157 dev_info(&GET_DEV(accel_dev), 158 "qat_dev%d stopped %d acceleration engines\n", 159 accel_dev->accel_id, ae_ctr); 160 return 0; 161 } 162 163 static int adf_ae_reset(struct adf_accel_dev *accel_dev, int ae) 164 { 165 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 166 unsigned long reset_delay; 167 168 qat_hal_reset(loader_data->fw_loader); 169 170 reset_delay = loader_data->fw_loader->chip_info->reset_delay_us; 171 if (reset_delay) 172 fsleep(reset_delay); 173 174 if (qat_hal_clr_reset(loader_data->fw_loader)) 175 return -EFAULT; 176 177 return 0; 178 } 179 180 int adf_ae_init(struct adf_accel_dev *accel_dev) 181 { 182 struct adf_fw_loader_data *loader_data; 183 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 184 185 if (!hw_device->fw_name) 186 return 0; 187 188 loader_data = kzalloc_obj(*loader_data); 189 if (!loader_data) 190 return -ENOMEM; 191 192 accel_dev->fw_loader = loader_data; 193 if (qat_hal_init(accel_dev)) { 194 dev_err(&GET_DEV(accel_dev), "Failed to init the AEs\n"); 195 kfree(loader_data); 196 return -EFAULT; 197 } 198 if (adf_ae_reset(accel_dev, 0)) { 199 dev_err(&GET_DEV(accel_dev), "Failed to reset the AEs\n"); 200 qat_hal_deinit(loader_data->fw_loader); 201 kfree(loader_data); 202 return -EFAULT; 203 } 204 return 0; 205 } 206 207 int adf_ae_shutdown(struct adf_accel_dev *accel_dev) 208 { 209 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 210 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 211 212 if (!hw_device->fw_name) 213 return 0; 214 215 qat_hal_deinit(loader_data->fw_loader); 216 kfree(accel_dev->fw_loader); 217 accel_dev->fw_loader = NULL; 218 return 0; 219 } 220