Commit 2d32d657 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'tegra-for-4.21-firmware' of...

Merge tag 'tegra-for-4.21-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers

firmware: tegra: Changes for v4.21-rc1

These changes update the BPMP ABI header and implement a new variant of
the BPMP firmware version tag query if supported.

* tag 'tegra-for-4.21-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  firmware: tegra: Use in-band messages for firmware version query
  soc/tegra: bpmp: Update ABI header
  firmware: tegra: Print version tag at full
  firmware: tegra: Switch to global mrq_is_supported()
  firmware: tegra: Add helper to check for supported MRQs
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 4a598c7b af51c25f
...@@ -379,33 +379,6 @@ static int create_debugfs_mirror(struct tegra_bpmp *bpmp, void *buf, ...@@ -379,33 +379,6 @@ static int create_debugfs_mirror(struct tegra_bpmp *bpmp, void *buf,
return err; return err;
} }
static int mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
{
struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
struct mrq_query_abi_response resp;
struct tegra_bpmp_message msg = {
.mrq = MRQ_QUERY_ABI,
.tx = {
.data = &req,
.size = sizeof(req),
},
.rx = {
.data = &resp,
.size = sizeof(resp),
},
};
int ret;
ret = tegra_bpmp_transfer(bpmp, &msg);
if (ret < 0) {
/* something went wrong; assume not supported */
dev_warn(bpmp->dev, "tegra_bpmp_transfer failed (%d)\n", ret);
return 0;
}
return resp.status ? 0 : 1;
}
int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
{ {
dma_addr_t phys; dma_addr_t phys;
...@@ -415,7 +388,7 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp) ...@@ -415,7 +388,7 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
int ret; int ret;
struct dentry *root; struct dentry *root;
if (!mrq_is_supported(bpmp, MRQ_DEBUGFS)) if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
return 0; return 0;
root = debugfs_create_dir("bpmp", NULL); root = debugfs_create_dir("bpmp", NULL);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define MSG_ACK BIT(0) #define MSG_ACK BIT(0)
#define MSG_RING BIT(1) #define MSG_RING BIT(1)
#define TAG_SZ 32
static inline struct tegra_bpmp * static inline struct tegra_bpmp *
mbox_client_to_bpmp(struct mbox_client *client) mbox_client_to_bpmp(struct mbox_client *client)
...@@ -470,6 +471,31 @@ void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, void *data) ...@@ -470,6 +471,31 @@ void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, void *data)
} }
EXPORT_SYMBOL_GPL(tegra_bpmp_free_mrq); EXPORT_SYMBOL_GPL(tegra_bpmp_free_mrq);
bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq)
{
struct mrq_query_abi_request req = { .mrq = cpu_to_le32(mrq) };
struct mrq_query_abi_response resp;
struct tegra_bpmp_message msg = {
.mrq = MRQ_QUERY_ABI,
.tx = {
.data = &req,
.size = sizeof(req),
},
.rx = {
.data = &resp,
.size = sizeof(resp),
},
};
int ret;
ret = tegra_bpmp_transfer(bpmp, &msg);
if (ret || msg.rx.ret)
return false;
return resp.status == 0;
}
EXPORT_SYMBOL_GPL(tegra_bpmp_mrq_is_supported);
static void tegra_bpmp_mrq_handle_ping(unsigned int mrq, static void tegra_bpmp_mrq_handle_ping(unsigned int mrq,
struct tegra_bpmp_channel *channel, struct tegra_bpmp_channel *channel,
void *data) void *data)
...@@ -521,7 +547,8 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp) ...@@ -521,7 +547,8 @@ static int tegra_bpmp_ping(struct tegra_bpmp *bpmp)
return err; return err;
} }
static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag, /* deprecated version of tag query */
static int tegra_bpmp_get_firmware_tag_old(struct tegra_bpmp *bpmp, char *tag,
size_t size) size_t size)
{ {
struct mrq_query_tag_request request; struct mrq_query_tag_request request;
...@@ -531,7 +558,10 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag, ...@@ -531,7 +558,10 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
void *virt; void *virt;
int err; int err;
virt = dma_alloc_coherent(bpmp->dev, MSG_DATA_MIN_SZ, &phys, if (size != TAG_SZ)
return -EINVAL;
virt = dma_alloc_coherent(bpmp->dev, TAG_SZ, &phys,
GFP_KERNEL | GFP_DMA32); GFP_KERNEL | GFP_DMA32);
if (!virt) if (!virt)
return -ENOMEM; return -ENOMEM;
...@@ -549,11 +579,42 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag, ...@@ -549,11 +579,42 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
local_irq_restore(flags); local_irq_restore(flags);
if (err == 0) if (err == 0)
strlcpy(tag, virt, size); memcpy(tag, virt, TAG_SZ);
dma_free_coherent(bpmp->dev, TAG_SZ, virt, phys);
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;
dma_free_coherent(bpmp->dev, MSG_DATA_MIN_SZ, virt, phys); if (size != sizeof(resp.tag))
return -EINVAL;
err = tegra_bpmp_transfer(bpmp, &msg);
if (err)
return 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) static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
...@@ -664,7 +725,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev) ...@@ -664,7 +725,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
{ {
struct tegra_bpmp *bpmp; struct tegra_bpmp *bpmp;
unsigned int i; unsigned int i;
char tag[32]; char tag[TAG_SZ];
size_t size; size_t size;
int err; int err;
...@@ -792,13 +853,13 @@ static int tegra_bpmp_probe(struct platform_device *pdev) ...@@ -792,13 +853,13 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
goto free_mrq; goto free_mrq;
} }
err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag) - 1); err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag));
if (err < 0) { if (err < 0) {
dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err); dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
goto free_mrq; goto free_mrq;
} }
dev_info(&pdev->dev, "firmware: %s\n", tag); dev_info(&pdev->dev, "firmware: %.*s\n", (int)sizeof(tag), tag);
platform_set_drvdata(pdev, bpmp); platform_set_drvdata(pdev, bpmp);
......
This diff is collapsed.
...@@ -129,6 +129,7 @@ int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, ...@@ -129,6 +129,7 @@ int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
tegra_bpmp_mrq_handler_t handler, void *data); tegra_bpmp_mrq_handler_t handler, void *data);
void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
void *data); void *data);
bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq);
#else #else
static inline struct tegra_bpmp *tegra_bpmp_get(struct device *dev) static inline struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
{ {
...@@ -164,6 +165,12 @@ static inline void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, ...@@ -164,6 +165,12 @@ static inline void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp,
unsigned int mrq, void *data) unsigned int mrq, void *data)
{ {
} }
static inline bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp,
unsigned int mrq)
{
return false;
}
#endif #endif
#if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP) #if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment