@@ -24,7 +24,8 @@ struct tegra_bpmp_ops {
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
- IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
+ IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
+ IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
extern const struct tegra_bpmp_ops tegra186_bpmp_ops;
#endif
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
@@ -6,6 +6,7 @@
#include <linux/genalloc.h>
#include <linux/io.h>
#include <linux/mailbox_client.h>
+#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
#include <soc/tegra/bpmp.h>
@@ -288,9 +289,11 @@ static int tegra186_bpmp_init(struct tegra_bpmp *bpmp)
bpmp->priv = priv;
priv->parent = bpmp;
- err = tegra186_bpmp_sram_init(bpmp);
- if (err < 0)
- return err;
+ if (of_reserved_mem_device_init(priv->parent->dev) < 0) {
+ err = tegra186_bpmp_sram_init(bpmp);
+ if (err < 0)
+ return err;
+ }
err = tegra186_bpmp_channel_setup(bpmp);
if (err < 0)
@@ -352,3 +355,51 @@ const struct tegra_bpmp_ops tegra186_bpmp_ops = {
.ring_doorbell = tegra186_bpmp_ring_doorbell,
.resume = tegra186_bpmp_resume,
};
+
+static int tegra_bpmp_rmem_device_init(struct reserved_mem *rmem,
+ struct device *dev)
+{
+ struct tegra_bpmp *bpmp = dev_get_drvdata(dev);
+ struct tegra186_bpmp *priv = bpmp->priv;
+
+ if (rmem->size < 0x2000)
+ return -ENOMEM;
+
+ priv->tx.phys = rmem->base;
+ priv->rx.phys = rmem->base + 0x1000;
+
+ priv->tx.virt = memremap(priv->tx.phys, rmem->size, MEMREMAP_WC);
+ if (priv->tx.virt == NULL)
+ return -ENOMEM;
+ priv->rx.virt = priv->tx.virt + 0x1000;
+
+ priv->type = TEGRA_RMEM;
+
+ return 0;
+}
+
+static void tegra_bpmp_rmem_device_release(struct reserved_mem *rmem,
+ struct device *dev)
+{
+ struct tegra_bpmp *bpmp = dev_get_drvdata(dev);
+ struct tegra186_bpmp *priv = bpmp->priv;
+
+ memunmap(priv->tx.virt);
+}
+
+
+static const struct reserved_mem_ops tegra_bpmp_rmem_ops = {
+ .device_init = tegra_bpmp_rmem_device_init,
+ .device_release = tegra_bpmp_rmem_device_release,
+};
+
+static int tegra_bpmp_rmem_init(struct reserved_mem *rmem)
+{
+ pr_debug("Tegra BPMP message buffer at %pa, size %lu bytes\n", &rmem->base, (unsigned long)rmem->size);
+
+ rmem->ops = &tegra_bpmp_rmem_ops;
+
+ return 0;
+}
+
+RESERVEDMEM_OF_DECLARE(tegra_bpmp, "nvidia,tegra234-bpmp-shmem", tegra_bpmp_rmem_init);
@@ -739,6 +739,8 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
if (!bpmp->threaded_channels)
return -ENOMEM;
+ platform_set_drvdata(pdev, bpmp);
+
err = bpmp->soc->ops->init(bpmp);
if (err < 0)
return err;
@@ -762,8 +764,6 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "firmware: %.*s\n", (int)sizeof(tag), tag);
- platform_set_drvdata(pdev, bpmp);
-
err = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev);
if (err < 0)
goto free_mrq;
@@ -814,7 +814,8 @@ static int __maybe_unused tegra_bpmp_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(tegra_bpmp_pm_ops, NULL, tegra_bpmp_resume);
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
- IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
+ IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
+ IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
static const struct tegra_bpmp_soc tegra186_soc = {
.channels = {
.cpu_tx = {
@@ -861,7 +862,8 @@ static const struct tegra_bpmp_soc tegra210_soc = {
static const struct of_device_id tegra_bpmp_match[] = {
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \
- IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC)
+ IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \
+ IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
{ .compatible = "nvidia,tegra186-bpmp", .data = &tegra186_soc },
#endif
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com> --- drivers/firmware/tegra/bpmp-private.h | 3 +- drivers/firmware/tegra/bpmp-tegra186.c | 57 ++++++++++++++++++++++++-- drivers/firmware/tegra/bpmp.c | 10 +++-- 3 files changed, 62 insertions(+), 8 deletions(-)