Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: stratix10-rsu: query spt addresses

Extend Intel Remote System Update (RSU) driver to get SPT
(Sub-Partition Table) addresses. The query SPT address can be used
to determine if the RSU QSPI layout is 32kB or 64kB aligned.
The alignment can be determined by minus the upper with the lower of
the SPT addresses.

This patch depends on patch:
firmware: stratix10-svc: Generic Mailbox Command

Signed-off-by: Radu Bacrau <radu.bacrau@intel.com>
Signed-off-by: Kah Jing Lee <kah.jing.lee@intel.com>
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Link: https://lore.kernel.org/r/20230727192907.982070-2-dinguyen@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Radu Bacrau and committed by
Greg Kroah-Hartman
abe8ff43 34949a31

+99 -1
+99 -1
drivers/firmware/stratix10-rsu.c
··· 34 34 #define INVALID_RETRY_COUNTER 0xFF 35 35 #define INVALID_DCMF_VERSION 0xFF 36 36 #define INVALID_DCMF_STATUS 0xFFFFFFFF 37 + #define INVALID_SPT_ADDRESS 0x0 38 + 39 + #define RSU_GET_SPT_CMD 0x5A 40 + #define RSU_GET_SPT_RESP_LEN (4 * sizeof(unsigned int)) 37 41 38 42 typedef void (*rsu_callback)(struct stratix10_svc_client *client, 39 43 struct stratix10_svc_cb_data *data); ··· 63 59 * @dcmf_status.dcmf3: dcmf3 status 64 60 * @retry_counter: the current image's retry counter 65 61 * @max_retry: the preset max retry value 62 + * @spt0_address: address of spt0 63 + * @spt1_address: address of spt1 64 + * @get_spt_response_buf: response from sdm for get_spt command 66 65 */ 67 66 struct stratix10_rsu_priv { 68 67 struct stratix10_svc_chan *chan; ··· 97 90 98 91 unsigned int retry_counter; 99 92 unsigned int max_retry; 93 + 94 + unsigned long spt0_address; 95 + unsigned long spt1_address; 96 + 97 + unsigned int *get_spt_response_buf; 100 98 }; 101 99 102 100 /** ··· 271 259 complete(&priv->completion); 272 260 } 273 261 262 + static void rsu_get_spt_callback(struct stratix10_svc_client *client, 263 + struct stratix10_svc_cb_data *data) 264 + { 265 + struct stratix10_rsu_priv *priv = client->priv; 266 + unsigned long *mbox_err = (unsigned long *)data->kaddr1; 267 + unsigned long *resp_len = (unsigned long *)data->kaddr2; 268 + 269 + if (data->status != BIT(SVC_STATUS_OK) || (*mbox_err) || 270 + (*resp_len != RSU_GET_SPT_RESP_LEN)) 271 + goto error; 272 + 273 + priv->spt0_address = priv->get_spt_response_buf[0]; 274 + priv->spt0_address <<= 32; 275 + priv->spt0_address |= priv->get_spt_response_buf[1]; 276 + 277 + priv->spt1_address = priv->get_spt_response_buf[2]; 278 + priv->spt1_address <<= 32; 279 + priv->spt1_address |= priv->get_spt_response_buf[3]; 280 + 281 + goto complete; 282 + 283 + error: 284 + dev_err(client->dev, "failed to get SPTs\n"); 285 + 286 + complete: 287 + stratix10_svc_free_memory(priv->chan, priv->get_spt_response_buf); 288 + priv->get_spt_response_buf = NULL; 289 + complete(&priv->completion); 290 + } 291 + 274 292 /** 275 293 * rsu_send_msg() - send a message to Intel service layer 276 294 * @priv: pointer to rsu private data ··· 329 287 msg.command = command; 330 288 if (arg) 331 289 msg.arg[0] = arg; 290 + 291 + if (command == COMMAND_MBOX_SEND_CMD) { 292 + msg.arg[1] = 0; 293 + msg.payload = NULL; 294 + msg.payload_length = 0; 295 + msg.payload_output = priv->get_spt_response_buf; 296 + msg.payload_length_output = RSU_GET_SPT_RESP_LEN; 297 + } 332 298 333 299 ret = stratix10_svc_send(priv->chan, &msg); 334 300 if (ret < 0) ··· 622 572 return count; 623 573 } 624 574 575 + static ssize_t spt0_address_show(struct device *dev, 576 + struct device_attribute *attr, char *buf) 577 + { 578 + struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 579 + 580 + if (!priv) 581 + return -ENODEV; 582 + 583 + if (priv->spt0_address == INVALID_SPT_ADDRESS) 584 + return -EIO; 585 + 586 + return scnprintf(buf, PAGE_SIZE, "0x%08lx\n", priv->spt0_address); 587 + } 588 + 589 + static ssize_t spt1_address_show(struct device *dev, 590 + struct device_attribute *attr, char *buf) 591 + { 592 + struct stratix10_rsu_priv *priv = dev_get_drvdata(dev); 593 + 594 + if (!priv) 595 + return -ENODEV; 596 + 597 + if (priv->spt1_address == INVALID_SPT_ADDRESS) 598 + return -EIO; 599 + 600 + return scnprintf(buf, PAGE_SIZE, "0x%08lx\n", priv->spt1_address); 601 + } 602 + 625 603 static DEVICE_ATTR_RO(current_image); 626 604 static DEVICE_ATTR_RO(fail_image); 627 605 static DEVICE_ATTR_RO(state); ··· 668 590 static DEVICE_ATTR_RO(dcmf3_status); 669 591 static DEVICE_ATTR_WO(reboot_image); 670 592 static DEVICE_ATTR_WO(notify); 593 + static DEVICE_ATTR_RO(spt0_address); 594 + static DEVICE_ATTR_RO(spt1_address); 671 595 672 596 static struct attribute *rsu_attrs[] = { 673 597 &dev_attr_current_image.attr, ··· 690 610 &dev_attr_dcmf3_status.attr, 691 611 &dev_attr_reboot_image.attr, 692 612 &dev_attr_notify.attr, 613 + &dev_attr_spt0_address.attr, 614 + &dev_attr_spt1_address.attr, 693 615 NULL 694 616 }; 695 617 ··· 721 639 priv->dcmf_version.dcmf1 = INVALID_DCMF_VERSION; 722 640 priv->dcmf_version.dcmf2 = INVALID_DCMF_VERSION; 723 641 priv->dcmf_version.dcmf3 = INVALID_DCMF_VERSION; 724 - priv->max_retry = INVALID_RETRY_COUNTER; 725 642 priv->dcmf_status.dcmf0 = INVALID_DCMF_STATUS; 726 643 priv->dcmf_status.dcmf1 = INVALID_DCMF_STATUS; 727 644 priv->dcmf_status.dcmf2 = INVALID_DCMF_STATUS; 728 645 priv->dcmf_status.dcmf3 = INVALID_DCMF_STATUS; 646 + priv->max_retry = INVALID_RETRY_COUNTER; 647 + priv->spt0_address = INVALID_SPT_ADDRESS; 648 + priv->spt1_address = INVALID_SPT_ADDRESS; 729 649 730 650 mutex_init(&priv->lock); 731 651 priv->chan = stratix10_svc_request_channel_byname(&priv->client, ··· 775 691 if (ret) { 776 692 dev_err(dev, "Error, getting RSU max retry %i\n", ret); 777 693 stratix10_svc_free_channel(priv->chan); 694 + } 695 + 696 + priv->get_spt_response_buf = 697 + stratix10_svc_allocate_memory(priv->chan, RSU_GET_SPT_RESP_LEN); 698 + 699 + if (IS_ERR(priv->get_spt_response_buf)) { 700 + dev_err(dev, "failed to allocate get spt buffer\n"); 701 + } else { 702 + ret = rsu_send_msg(priv, COMMAND_MBOX_SEND_CMD, 703 + RSU_GET_SPT_CMD, rsu_get_spt_callback); 704 + if (ret) { 705 + dev_err(dev, "Error, getting SPT table %i\n", ret); 706 + stratix10_svc_free_channel(priv->chan); 707 + } 778 708 } 779 709 780 710 return ret;