summaryrefslogtreecommitdiff
path: root/drivers/firmware/tegra
diff options
context:
space:
mode:
authorTimo Alho <talho@nvidia.com>2018-10-22 16:19:40 +0300
committerThierry Reding <treding@nvidia.com>2018-11-08 12:49:26 +0100
commitaf51c25fb59d4365c259ab93f388462e0998a2ed (patch)
tree19be7c5d5218e0da3b906c9d390fc5522479e01e /drivers/firmware/tegra
parent4bef358c9071748aa3e55f70f3ba5abc6363fcfe (diff)
downloadlinux-af51c25fb59d4365c259ab93f388462e0998a2ed.tar.gz
firmware: tegra: Use in-band messages for firmware version query
Add support for a new MRQ, that uses in-band messaging instead of IOVA buffer, to retrieve the firmware version 'tag' during boot. If an older firmware is used, that does not support the new MRQ, fall back to the earlier implementation. Signed-off-by: Timo Alho <talho@nvidia.com> Acked-by: Sivaram Nair <sivaramn@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/firmware/tegra')
-rw-r--r--drivers/firmware/tegra/bpmp.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index 191f8a91c466..689478b92bce 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -547,8 +547,9 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
return err;
}
-static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
- size_t size)
+/* deprecated version of tag query */
+static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
+ size_t size)
{
struct mrq_query_tag_request request;
struct tegra_bpmp_message msg;
@@ -585,6 +586,37 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
return err;
}
+static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
+ size_t size)
+{
+ if (tegra_bpmp_mrq_is_supported(bpmp, MRQ_QUERY_FW_TAG)) {
+ struct mrq_query_fw_tag_response resp;
+ struct tegra_bpmp_message msg = {
+ .mrq = MRQ_QUERY_FW_TAG,
+ .rx = {
+ .data = &resp,
+ .size = sizeof(resp),
+ },
+ };
+ int err;
+
+ if (size != sizeof(resp.tag))
+ return -EINVAL;
+
+ err = tegra_bpmp_transfer(bpmp, &msg);
+
+ if (err)
+ return err;
+ if (msg.rx.ret < 0)
+ return -EINVAL;
+
+ memcpy(tag, resp.tag, sizeof(resp.tag));
+ return 0;
+ }
+
+ return tegra_bpmp_get_firmware_tag_old(bpmp, tag, size);
+}
+
static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
{
unsigned long flags = channel->ob->flags;