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>
8 #include <linux/dma-mapping.h>
9 #include "adf_accel_devices.h"
10 #include "adf_common_drv.h"
11 #include "icp_qat_fw_init_admin.h"
13 /* Admin Messages Registers */
14 #define ADF_DH895XCC_ADMINMSGUR_OFFSET (0x3A000 + 0x574)
15 #define ADF_DH895XCC_ADMINMSGLR_OFFSET (0x3A000 + 0x578)
16 #define ADF_DH895XCC_MAILBOX_BASE_OFFSET 0x20970
17 #define ADF_DH895XCC_MAILBOX_STRIDE 0x1000
18 #define ADF_ADMINMSG_LEN 32
19 #define ADF_CONST_TABLE_SIZE 1024
20 #define ADF_ADMIN_POLL_DELAY_US 20
21 #define ADF_ADMIN_POLL_TIMEOUT_US (5 * USEC_PER_SEC)
23 static const u8 const_tab[1024] __aligned(1024) = {
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
37 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 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, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76,
49 0x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab,
51 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0,
52 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e,
55 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39,
56 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe,
57 0xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
59 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f,
60 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
63 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
64 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff,
65 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c,
66 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f,
67 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb,
69 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
70 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52,
71 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
72 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13,
73 0x7e, 0x21, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
104 struct adf_admin_comms {
106 dma_addr_t const_tbl_addr;
109 void __iomem *mailbox_addr;
110 struct mutex lock; /* protects adf_admin_comms struct */
113 static int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev, u32 ae,
118 struct adf_admin_comms *admin = accel_dev->admin;
119 int offset = ae * ADF_ADMINMSG_LEN * 2;
120 void __iomem *mailbox = admin->mailbox_addr;
121 int mb_offset = ae * ADF_DH895XCC_MAILBOX_STRIDE;
122 struct icp_qat_fw_init_admin_req *request = in;
124 mutex_lock(&admin->lock);
126 if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
127 mutex_unlock(&admin->lock);
131 memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
132 ADF_CSR_WR(mailbox, mb_offset, 1);
134 ret = read_poll_timeout(ADF_CSR_RD, status, status == 0,
135 ADF_ADMIN_POLL_DELAY_US,
136 ADF_ADMIN_POLL_TIMEOUT_US, true,
139 /* Response timeout */
140 dev_err(&GET_DEV(accel_dev),
141 "Failed to send admin msg %d to accelerator %d\n",
142 request->cmd_id, ae);
144 /* Response received from admin message, we can now
145 * make response data available in "out" parameter.
147 memcpy(out, admin->virt_addr + offset +
148 ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
151 mutex_unlock(&admin->lock);
155 static int adf_send_admin(struct adf_accel_dev *accel_dev,
156 struct icp_qat_fw_init_admin_req *req,
157 struct icp_qat_fw_init_admin_resp *resp,
158 const unsigned long ae_mask)
162 for_each_set_bit(ae, &ae_mask, ICP_QAT_HW_AE_DELIMITER)
163 if (adf_put_admin_msg_sync(accel_dev, ae, req, resp) ||
170 static int adf_init_me(struct adf_accel_dev *accel_dev)
172 struct icp_qat_fw_init_admin_req req;
173 struct icp_qat_fw_init_admin_resp resp;
174 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
175 u32 ae_mask = hw_device->ae_mask;
177 memset(&req, 0, sizeof(req));
178 memset(&resp, 0, sizeof(resp));
179 req.cmd_id = ICP_QAT_FW_INIT_ME;
181 return adf_send_admin(accel_dev, &req, &resp, ae_mask);
184 static int adf_set_fw_constants(struct adf_accel_dev *accel_dev)
186 struct icp_qat_fw_init_admin_req req;
187 struct icp_qat_fw_init_admin_resp resp;
188 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
189 u32 ae_mask = hw_device->ae_mask;
191 memset(&req, 0, sizeof(req));
192 memset(&resp, 0, sizeof(resp));
193 req.cmd_id = ICP_QAT_FW_CONSTANTS_CFG;
195 req.init_cfg_sz = ADF_CONST_TABLE_SIZE;
196 req.init_cfg_ptr = accel_dev->admin->const_tbl_addr;
198 return adf_send_admin(accel_dev, &req, &resp, ae_mask);
202 * adf_send_admin_init() - Function sends init message to FW
203 * @accel_dev: Pointer to acceleration device.
205 * Function sends admin init message to the FW
207 * Return: 0 on success, error code otherwise.
209 int adf_send_admin_init(struct adf_accel_dev *accel_dev)
213 ret = adf_init_me(accel_dev);
217 return adf_set_fw_constants(accel_dev);
219 EXPORT_SYMBOL_GPL(adf_send_admin_init);
221 int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
223 struct adf_admin_comms *admin;
224 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
225 struct adf_bar *pmisc =
226 &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
227 void __iomem *csr = pmisc->virt_addr;
228 void __iomem *mailbox = (void __iomem *)((uintptr_t)csr +
229 ADF_DH895XCC_MAILBOX_BASE_OFFSET);
232 admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL,
233 dev_to_node(&GET_DEV(accel_dev)));
236 admin->virt_addr = dma_alloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
237 &admin->phy_addr, GFP_KERNEL);
238 if (!admin->virt_addr) {
239 dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n");
244 admin->virt_tbl_addr = dma_alloc_coherent(&GET_DEV(accel_dev),
246 &admin->const_tbl_addr,
248 if (!admin->virt_tbl_addr) {
249 dev_err(&GET_DEV(accel_dev), "Failed to allocate const_tbl\n");
250 dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
251 admin->virt_addr, admin->phy_addr);
256 memcpy(admin->virt_tbl_addr, const_tab, sizeof(const_tab));
257 reg_val = (u64)admin->phy_addr;
258 ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGUR_OFFSET, reg_val >> 32);
259 ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGLR_OFFSET, reg_val);
260 mutex_init(&admin->lock);
261 admin->mailbox_addr = mailbox;
262 accel_dev->admin = admin;
265 EXPORT_SYMBOL_GPL(adf_init_admin_comms);
267 void adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
269 struct adf_admin_comms *admin = accel_dev->admin;
274 if (admin->virt_addr)
275 dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
276 admin->virt_addr, admin->phy_addr);
277 if (admin->virt_tbl_addr)
278 dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
279 admin->virt_tbl_addr, admin->const_tbl_addr);
281 mutex_destroy(&admin->lock);
283 accel_dev->admin = NULL;
285 EXPORT_SYMBOL_GPL(adf_exit_admin_comms);