Lines Matching +full:bitstream +full:- +full:flash
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018-2019, Intel Corporation
6 #include <linux/arm-smccc.h>
14 #include <linux/firmware/intel/stratix10-svc-client.h>
44 * struct stratix10_rsu_priv - rsu data structure
49 * @status.current_image: address of image currently running in flash
50 * @status.fail_image: address of failed image in flash
107 * rsu_status_callback() - Status callback from Intel Service Layer
118 struct stratix10_rsu_priv *priv = client->priv; in rsu_status_callback()
119 struct arm_smccc_res *res = (struct arm_smccc_res *)data->kaddr1; in rsu_status_callback()
121 if (data->status == BIT(SVC_STATUS_OK)) { in rsu_status_callback()
122 priv->status.version = FIELD_GET(RSU_VERSION_MASK, in rsu_status_callback()
123 res->a2); in rsu_status_callback()
124 priv->status.state = FIELD_GET(RSU_STATE_MASK, res->a2); in rsu_status_callback()
125 priv->status.fail_image = res->a1; in rsu_status_callback()
126 priv->status.current_image = res->a0; in rsu_status_callback()
127 priv->status.error_location = in rsu_status_callback()
128 FIELD_GET(RSU_ERROR_LOCATION_MASK, res->a3); in rsu_status_callback()
129 priv->status.error_details = in rsu_status_callback()
130 FIELD_GET(RSU_ERROR_DETAIL_MASK, res->a3); in rsu_status_callback()
132 dev_err(client->dev, "COMMAND_RSU_STATUS returned 0x%lX\n", in rsu_status_callback()
133 res->a0); in rsu_status_callback()
134 priv->status.version = 0; in rsu_status_callback()
135 priv->status.state = 0; in rsu_status_callback()
136 priv->status.fail_image = 0; in rsu_status_callback()
137 priv->status.current_image = 0; in rsu_status_callback()
138 priv->status.error_location = 0; in rsu_status_callback()
139 priv->status.error_details = 0; in rsu_status_callback()
142 complete(&priv->completion); in rsu_status_callback()
146 * rsu_command_callback() - Update callback from Intel Service Layer
155 struct stratix10_rsu_priv *priv = client->priv; in rsu_command_callback()
157 if (data->status == BIT(SVC_STATUS_NO_SUPPORT)) in rsu_command_callback()
158 dev_warn(client->dev, "Secure FW doesn't support notify\n"); in rsu_command_callback()
159 else if (data->status == BIT(SVC_STATUS_ERROR)) in rsu_command_callback()
160 dev_err(client->dev, "Failure, returned status is %lu\n", in rsu_command_callback()
161 BIT(data->status)); in rsu_command_callback()
163 complete(&priv->completion); in rsu_command_callback()
167 * rsu_retry_callback() - Callback from Intel service layer for getting
174 * itself before giving up and starting RSU fail-over flow.
179 struct stratix10_rsu_priv *priv = client->priv; in rsu_retry_callback()
180 unsigned int *counter = (unsigned int *)data->kaddr1; in rsu_retry_callback()
182 if (data->status == BIT(SVC_STATUS_OK)) in rsu_retry_callback()
183 priv->retry_counter = *counter; in rsu_retry_callback()
184 else if (data->status == BIT(SVC_STATUS_NO_SUPPORT)) in rsu_retry_callback()
185 dev_warn(client->dev, "Secure FW doesn't support retry\n"); in rsu_retry_callback()
187 dev_err(client->dev, "Failed to get retry counter %lu\n", in rsu_retry_callback()
188 BIT(data->status)); in rsu_retry_callback()
190 complete(&priv->completion); in rsu_retry_callback()
194 * rsu_max_retry_callback() - Callback from Intel service layer for getting
204 struct stratix10_rsu_priv *priv = client->priv; in rsu_max_retry_callback()
205 unsigned int *max_retry = (unsigned int *)data->kaddr1; in rsu_max_retry_callback()
207 if (data->status == BIT(SVC_STATUS_OK)) in rsu_max_retry_callback()
208 priv->max_retry = *max_retry; in rsu_max_retry_callback()
209 else if (data->status == BIT(SVC_STATUS_NO_SUPPORT)) in rsu_max_retry_callback()
210 dev_warn(client->dev, "Secure FW doesn't support max retry\n"); in rsu_max_retry_callback()
212 dev_err(client->dev, "Failed to get max retry %lu\n", in rsu_max_retry_callback()
213 BIT(data->status)); in rsu_max_retry_callback()
215 complete(&priv->completion); in rsu_max_retry_callback()
219 * rsu_dcmf_version_callback() - Callback from Intel service layer for getting
229 struct stratix10_rsu_priv *priv = client->priv; in rsu_dcmf_version_callback()
230 unsigned long long *value1 = (unsigned long long *)data->kaddr1; in rsu_dcmf_version_callback()
231 unsigned long long *value2 = (unsigned long long *)data->kaddr2; in rsu_dcmf_version_callback()
233 if (data->status == BIT(SVC_STATUS_OK)) { in rsu_dcmf_version_callback()
234 priv->dcmf_version.dcmf0 = FIELD_GET(RSU_DCMF0_MASK, *value1); in rsu_dcmf_version_callback()
235 priv->dcmf_version.dcmf1 = FIELD_GET(RSU_DCMF1_MASK, *value1); in rsu_dcmf_version_callback()
236 priv->dcmf_version.dcmf2 = FIELD_GET(RSU_DCMF2_MASK, *value2); in rsu_dcmf_version_callback()
237 priv->dcmf_version.dcmf3 = FIELD_GET(RSU_DCMF3_MASK, *value2); in rsu_dcmf_version_callback()
239 dev_err(client->dev, "failed to get DCMF version\n"); in rsu_dcmf_version_callback()
241 complete(&priv->completion); in rsu_dcmf_version_callback()
245 * rsu_dcmf_status_callback() - Callback from Intel service layer for getting
255 struct stratix10_rsu_priv *priv = client->priv; in rsu_dcmf_status_callback()
256 unsigned long long *value = (unsigned long long *)data->kaddr1; in rsu_dcmf_status_callback()
258 if (data->status == BIT(SVC_STATUS_OK)) { in rsu_dcmf_status_callback()
259 priv->dcmf_status.dcmf0 = FIELD_GET(RSU_DCMF0_STATUS_MASK, in rsu_dcmf_status_callback()
261 priv->dcmf_status.dcmf1 = FIELD_GET(RSU_DCMF1_STATUS_MASK, in rsu_dcmf_status_callback()
263 priv->dcmf_status.dcmf2 = FIELD_GET(RSU_DCMF2_STATUS_MASK, in rsu_dcmf_status_callback()
265 priv->dcmf_status.dcmf3 = FIELD_GET(RSU_DCMF3_STATUS_MASK, in rsu_dcmf_status_callback()
268 dev_err(client->dev, "failed to get DCMF status\n"); in rsu_dcmf_status_callback()
270 complete(&priv->completion); in rsu_dcmf_status_callback()
276 struct stratix10_rsu_priv *priv = client->priv; in rsu_get_spt_callback()
277 unsigned long *mbox_err = (unsigned long *)data->kaddr1; in rsu_get_spt_callback()
278 unsigned long *resp_len = (unsigned long *)data->kaddr2; in rsu_get_spt_callback()
280 if (data->status != BIT(SVC_STATUS_OK) || (*mbox_err) || in rsu_get_spt_callback()
284 priv->spt0_address = priv->get_spt_response_buf[0]; in rsu_get_spt_callback()
285 priv->spt0_address <<= 32; in rsu_get_spt_callback()
286 priv->spt0_address |= priv->get_spt_response_buf[1]; in rsu_get_spt_callback()
288 priv->spt1_address = priv->get_spt_response_buf[2]; in rsu_get_spt_callback()
289 priv->spt1_address <<= 32; in rsu_get_spt_callback()
290 priv->spt1_address |= priv->get_spt_response_buf[3]; in rsu_get_spt_callback()
295 dev_err(client->dev, "failed to get SPTs\n"); in rsu_get_spt_callback()
298 stratix10_svc_free_memory(priv->chan, priv->get_spt_response_buf); in rsu_get_spt_callback()
299 priv->get_spt_response_buf = NULL; in rsu_get_spt_callback()
300 complete(&priv->completion); in rsu_get_spt_callback()
304 * rsu_send_msg() - send a message to Intel service layer
307 * @arg: the request argument, the bitstream address or notify status
311 * is necessary to get RSU boot log or set the address of bitstream to
314 * Returns 0 on success or -ETIMEDOUT on error.
324 mutex_lock(&priv->lock); in rsu_send_msg()
325 reinit_completion(&priv->completion); in rsu_send_msg()
326 priv->client.receive_cb = callback; in rsu_send_msg()
336 msg.payload_output = priv->get_spt_response_buf; in rsu_send_msg()
340 ret = stratix10_svc_send(priv->chan, &msg); in rsu_send_msg()
344 ret = wait_for_completion_interruptible_timeout(&priv->completion, in rsu_send_msg()
347 dev_err(priv->client.dev, in rsu_send_msg()
349 ret = -ETIMEDOUT; in rsu_send_msg()
352 dev_err(priv->client.dev, in rsu_send_msg()
360 stratix10_svc_done(priv->chan); in rsu_send_msg()
361 mutex_unlock(&priv->lock); in rsu_send_msg()
378 return -ENODEV; in current_image_show()
380 return sprintf(buf, "0x%08lx\n", priv->status.current_image); in current_image_show()
389 return -ENODEV; in fail_image_show()
391 return sprintf(buf, "0x%08lx\n", priv->status.fail_image); in fail_image_show()
400 return -ENODEV; in version_show()
402 return sprintf(buf, "0x%08x\n", priv->status.version); in version_show()
411 return -ENODEV; in state_show()
413 return sprintf(buf, "0x%08x\n", priv->status.state); in state_show()
422 return -ENODEV; in error_location_show()
424 return sprintf(buf, "0x%08x\n", priv->status.error_location); in error_location_show()
433 return -ENODEV; in error_details_show()
435 return sprintf(buf, "0x%08x\n", priv->status.error_details); in error_details_show()
444 return -ENODEV; in retry_counter_show()
446 return sprintf(buf, "0x%08x\n", priv->retry_counter); in retry_counter_show()
455 return -ENODEV; in max_retry_show()
457 return scnprintf(buf, sizeof(priv->max_retry), in max_retry_show()
458 "0x%08x\n", priv->max_retry); in max_retry_show()
467 return -ENODEV; in dcmf0_show()
469 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf0); in dcmf0_show()
478 return -ENODEV; in dcmf1_show()
480 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf1); in dcmf1_show()
489 return -ENODEV; in dcmf2_show()
491 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf2); in dcmf2_show()
500 return -ENODEV; in dcmf3_show()
502 return sprintf(buf, "0x%08x\n", priv->dcmf_version.dcmf3); in dcmf3_show()
511 return -ENODEV; in dcmf0_status_show()
513 if (priv->dcmf_status.dcmf0 == INVALID_DCMF_STATUS) in dcmf0_status_show()
514 return -EIO; in dcmf0_status_show()
516 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf0); in dcmf0_status_show()
525 return -ENODEV; in dcmf1_status_show()
527 if (priv->dcmf_status.dcmf1 == INVALID_DCMF_STATUS) in dcmf1_status_show()
528 return -EIO; in dcmf1_status_show()
530 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf1); in dcmf1_status_show()
539 return -ENODEV; in dcmf2_status_show()
541 if (priv->dcmf_status.dcmf2 == INVALID_DCMF_STATUS) in dcmf2_status_show()
542 return -EIO; in dcmf2_status_show()
544 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf2); in dcmf2_status_show()
553 return -ENODEV; in dcmf3_status_show()
555 if (priv->dcmf_status.dcmf3 == INVALID_DCMF_STATUS) in dcmf3_status_show()
556 return -EIO; in dcmf3_status_show()
558 return sprintf(buf, "0x%08x\n", priv->dcmf_status.dcmf3); in dcmf3_status_show()
569 return -ENODEV; in reboot_image_store()
594 return -ENODEV; in notify_store()
630 return -ENODEV; in spt0_address_show()
632 if (priv->spt0_address == INVALID_SPT_ADDRESS) in spt0_address_show()
633 return -EIO; in spt0_address_show()
635 return scnprintf(buf, PAGE_SIZE, "0x%08lx\n", priv->spt0_address); in spt0_address_show()
644 return -ENODEV; in spt1_address_show()
646 if (priv->spt1_address == INVALID_SPT_ADDRESS) in spt1_address_show()
647 return -EIO; in spt1_address_show()
649 return scnprintf(buf, PAGE_SIZE, "0x%08lx\n", priv->spt1_address); in spt1_address_show()
701 struct device *dev = &pdev->dev; in stratix10_rsu_probe()
707 return -ENOMEM; in stratix10_rsu_probe()
709 priv->client.dev = dev; in stratix10_rsu_probe()
710 priv->client.receive_cb = NULL; in stratix10_rsu_probe()
711 priv->client.priv = priv; in stratix10_rsu_probe()
712 priv->status.current_image = 0; in stratix10_rsu_probe()
713 priv->status.fail_image = 0; in stratix10_rsu_probe()
714 priv->status.error_location = 0; in stratix10_rsu_probe()
715 priv->status.error_details = 0; in stratix10_rsu_probe()
716 priv->status.version = 0; in stratix10_rsu_probe()
717 priv->status.state = 0; in stratix10_rsu_probe()
718 priv->retry_counter = INVALID_RETRY_COUNTER; in stratix10_rsu_probe()
719 priv->dcmf_version.dcmf0 = INVALID_DCMF_VERSION; in stratix10_rsu_probe()
720 priv->dcmf_version.dcmf1 = INVALID_DCMF_VERSION; in stratix10_rsu_probe()
721 priv->dcmf_version.dcmf2 = INVALID_DCMF_VERSION; in stratix10_rsu_probe()
722 priv->dcmf_version.dcmf3 = INVALID_DCMF_VERSION; in stratix10_rsu_probe()
723 priv->dcmf_status.dcmf0 = INVALID_DCMF_STATUS; in stratix10_rsu_probe()
724 priv->dcmf_status.dcmf1 = INVALID_DCMF_STATUS; in stratix10_rsu_probe()
725 priv->dcmf_status.dcmf2 = INVALID_DCMF_STATUS; in stratix10_rsu_probe()
726 priv->dcmf_status.dcmf3 = INVALID_DCMF_STATUS; in stratix10_rsu_probe()
727 priv->max_retry = INVALID_RETRY_COUNTER; in stratix10_rsu_probe()
728 priv->spt0_address = INVALID_SPT_ADDRESS; in stratix10_rsu_probe()
729 priv->spt1_address = INVALID_SPT_ADDRESS; in stratix10_rsu_probe()
731 mutex_init(&priv->lock); in stratix10_rsu_probe()
732 priv->chan = stratix10_svc_request_channel_byname(&priv->client, in stratix10_rsu_probe()
734 if (IS_ERR(priv->chan)) { in stratix10_rsu_probe()
737 return PTR_ERR(priv->chan); in stratix10_rsu_probe()
740 init_completion(&priv->completion); in stratix10_rsu_probe()
748 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_probe()
756 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_probe()
763 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_probe()
769 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_probe()
776 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_probe()
779 priv->get_spt_response_buf = in stratix10_rsu_probe()
780 stratix10_svc_allocate_memory(priv->chan, RSU_GET_SPT_RESP_LEN); in stratix10_rsu_probe()
782 if (IS_ERR(priv->get_spt_response_buf)) { in stratix10_rsu_probe()
789 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_probe()
800 stratix10_svc_free_channel(priv->chan); in stratix10_rsu_remove()
807 .name = "stratix10-rsu",