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: Olof Johansson <olof@lixom.net>
This commit is contained in:
@@ -379,33 +379,6 @@ static int create_debugfs_mirror(struct tegra_bpmp *bpmp, void *buf,
|
||||
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)
|
||||
{
|
||||
dma_addr_t phys;
|
||||
@@ -415,7 +388,7 @@ int tegra_bpmp_init_debugfs(struct tegra_bpmp *bpmp)
|
||||
int ret;
|
||||
struct dentry *root;
|
||||
|
||||
if (!mrq_is_supported(bpmp, MRQ_DEBUGFS))
|
||||
if (!tegra_bpmp_mrq_is_supported(bpmp, MRQ_DEBUGFS))
|
||||
return 0;
|
||||
|
||||
root = debugfs_create_dir("bpmp", NULL);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#define MSG_ACK BIT(0)
|
||||
#define MSG_RING BIT(1)
|
||||
#define TAG_SZ 32
|
||||
|
||||
static inline struct tegra_bpmp *
|
||||
mbox_client_to_bpmp(struct mbox_client *client)
|
||||
@@ -470,6 +471,31 @@ unlock:
|
||||
}
|
||||
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,
|
||||
struct tegra_bpmp_channel *channel,
|
||||
void *data)
|
||||
@@ -521,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;
|
||||
@@ -531,7 +558,10 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
|
||||
void *virt;
|
||||
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);
|
||||
if (!virt)
|
||||
return -ENOMEM;
|
||||
@@ -549,13 +579,44 @@ static int tegra_bpmp_get_firmware_tag(struct tegra_bpmp *bpmp, char *tag,
|
||||
local_irq_restore(flags);
|
||||
|
||||
if (err == 0)
|
||||
strlcpy(tag, virt, size);
|
||||
memcpy(tag, virt, TAG_SZ);
|
||||
|
||||
dma_free_coherent(bpmp->dev, MSG_DATA_MIN_SZ, virt, phys);
|
||||
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;
|
||||
|
||||
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;
|
||||
@@ -664,7 +725,7 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_bpmp *bpmp;
|
||||
unsigned int i;
|
||||
char tag[32];
|
||||
char tag[TAG_SZ];
|
||||
size_t size;
|
||||
int err;
|
||||
|
||||
@@ -792,13 +853,13 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
|
||||
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) {
|
||||
dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
|
||||
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);
|
||||
|
||||
|
||||
+949
-243
File diff suppressed because it is too large
Load Diff
@@ -129,6 +129,7 @@ int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
|
||||
tegra_bpmp_mrq_handler_t handler, void *data);
|
||||
void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp, unsigned int mrq,
|
||||
void *data);
|
||||
bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq);
|
||||
#else
|
||||
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,
|
||||
unsigned int mrq, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp,
|
||||
unsigned int mrq)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CLK_TEGRA_BPMP)
|
||||
|
||||
Reference in New Issue
Block a user