summaryrefslogtreecommitdiff
path: root/drivers/memory
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/brcmstb_memc.c56
-rw-r--r--drivers/memory/emif.c1
-rw-r--r--drivers/memory/mtk-smi.c33
-rw-r--r--drivers/memory/omap-gpmc.c4
-rw-r--r--drivers/memory/stm32_omm.c21
-rw-r--r--drivers/memory/tegra/Makefile2
-rw-r--r--drivers/memory/tegra/mc.c5
-rw-r--r--drivers/memory/tegra/mc.h9
-rw-r--r--drivers/memory/tegra/tegra186-emc.c5
-rw-r--r--drivers/memory/tegra/tegra186.c17
-rw-r--r--drivers/memory/tegra/tegra210-emc-core.c5
-rw-r--r--drivers/memory/tegra/tegra264-bwmgr.h50
-rw-r--r--drivers/memory/tegra/tegra264.c313
13 files changed, 442 insertions, 79 deletions
diff --git a/drivers/memory/brcmstb_memc.c b/drivers/memory/brcmstb_memc.c
index c87b37e2c1f0..ba73470b1b13 100644
--- a/drivers/memory/brcmstb_memc.c
+++ b/drivers/memory/brcmstb_memc.c
@@ -184,62 +184,10 @@ static const struct of_device_id brcmstb_memc_of_match[] = {
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.1",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.2",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.3",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.5",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.6",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.7",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.8",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.3.0",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-b.3.1",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.0",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.2",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.3",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- {
- .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.4",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
- },
- /* default to the original offset */
+ /* default to the V21 offset */
{
.compatible = "brcm,brcmstb-memc-ddr",
- .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V1X]
+ .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{}
};
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 2e1ecae9e959..2fadad0666b1 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -39,6 +39,7 @@
* are two devices attached to this EMIF, this
* value is the maximum of the two temperature
* levels.
+ * @lpmode: Chosen low power mode
* @node: node in the device list
* @base: base address of memory-mapped IO registers.
* @dev: device pointer.
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index c086c22511f7..733e22f695ab 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -320,6 +320,38 @@ static const u8 mtk_smi_larb_mt6893_ostd[][SMI_LARB_PORT_NR_MAX] = {
[20] = {0x9, 0x9, 0x5, 0x5, 0x1, 0x1},
};
+static const u8 mtk_smi_larb_mt8186_ostd[][SMI_LARB_PORT_NR_MAX] = {
+ [0] = {0x2, 0x1, 0x8, 0x1,},
+ [1] = {0x1, 0x3, 0x1, 0x1,},
+ [2] = {0x6, 0x1, 0x4, 0x1,},
+ [3] = {},
+ [4] = {0xf, 0x1, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x1, 0x1, 0x1,},
+ [5] = {},
+ [6] = {},
+ [7] = {0x1, 0x3, 0x1, 0x1, 0x1, 0x3, 0x2, 0xd, 0x7, 0x5, 0x3,
+ 0x1, 0x5,},
+ [8] = {0x1, 0x2, 0x2,},
+ [9] = {0x9, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0xb, 0x7, 0x4,
+ 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x1, 0x1, 0x1, 0x1, 0x1,},
+ [10] = {},
+ [11] = {0x9, 0x7, 0xf, 0x8, 0x1, 0x8, 0x9, 0x3, 0x3, 0xb, 0x7, 0x4,
+ 0x9, 0x1, 0x1, 0x1, 0x1, 0x1, 0x8, 0x7, 0x7, 0x1, 0x6, 0x2,
+ 0xf, 0x8, 0x1, 0x1, 0x1,},
+ [12] = {},
+ [13] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x6, 0x6, 0x1, 0x1, 0x1,},
+ [14] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1,},
+ [15] = {},
+ [16] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x1, 0x14, 0x1, 0x4, 0x4, 0x4,
+ 0x2, 0x4, 0x2, 0x8, 0x4, 0x4,},
+ [17] = {0x28, 0x14, 0x2, 0xc, 0x18, 0x1, 0x14, 0x1, 0x4, 0x4, 0x4,
+ 0x2, 0x4, 0x2, 0x8, 0x4, 0x4,},
+ [18] = {},
+ [19] = {0x1, 0x1, 0x1, 0x1,},
+ [20] = {0x2, 0x2, 0x2, 0x2, 0x1, 0x1,},
+};
+
static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = {
[0] = {0x02, 0x18, 0x22, 0x22, 0x01, 0x02, 0x0a,},
[1] = {0x12, 0x02, 0x14, 0x14, 0x01, 0x18, 0x0a,},
@@ -491,6 +523,7 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
.flags_general = MTK_SMI_FLAG_SLEEP_CTL,
+ .ostd = mtk_smi_larb_mt8186_ostd,
};
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = {
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 9c96eed00194..d9e13c1f9b13 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -1455,8 +1455,8 @@ static int gpmc_setup_irq(struct gpmc_device *gpmc)
gpmc->irq_chip.irq_unmask = gpmc_irq_unmask;
gpmc->irq_chip.irq_set_type = gpmc_irq_set_type;
- gpmc_irq_domain = irq_domain_create_linear(of_fwnode_handle(gpmc->dev->of_node),
- gpmc->nirqs, &gpmc_irq_domain_ops, gpmc);
+ gpmc_irq_domain = irq_domain_create_linear(dev_fwnode(gpmc->dev), gpmc->nirqs,
+ &gpmc_irq_domain_ops, gpmc);
if (!gpmc_irq_domain) {
dev_err(gpmc->dev, "IRQ domain add failed\n");
return -ENODEV;
diff --git a/drivers/memory/stm32_omm.c b/drivers/memory/stm32_omm.c
index 79ceb1635698..bee2ecc8c2b9 100644
--- a/drivers/memory/stm32_omm.c
+++ b/drivers/memory/stm32_omm.c
@@ -46,7 +46,7 @@ static int stm32_omm_set_amcr(struct device *dev, bool set)
struct regmap *syscfg_regmap;
struct device_node *node;
struct resource res, res1;
- u32 amcr_base, amcr_mask;
+ unsigned int syscon_args[2];
int ret, idx;
unsigned int i, amcr, read_amcr;
@@ -98,29 +98,20 @@ static int stm32_omm_set_amcr(struct device *dev, bool set)
of_node_put(node);
}
- syscfg_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "st,syscfg-amcr");
+ syscfg_regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, "st,syscfg-amcr",
+ 2, syscon_args);
if (IS_ERR(syscfg_regmap))
return dev_err_probe(dev, PTR_ERR(syscfg_regmap),
"Failed to get st,syscfg-amcr property\n");
- ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 1,
- &amcr_base);
- if (ret)
- return ret;
-
- ret = of_property_read_u32_index(dev->of_node, "st,syscfg-amcr", 2,
- &amcr_mask);
- if (ret)
- return ret;
-
amcr = mm_ospi2_size / SZ_64M;
if (set)
- regmap_update_bits(syscfg_regmap, amcr_base, amcr_mask, amcr);
+ regmap_update_bits(syscfg_regmap, syscon_args[0], syscon_args[1], amcr);
/* read AMCR and check coherency with memory-map areas defined in DT */
- regmap_read(syscfg_regmap, amcr_base, &read_amcr);
- read_amcr = read_amcr >> (ffs(amcr_mask) - 1);
+ regmap_read(syscfg_regmap, syscon_args[0], &read_amcr);
+ read_amcr = read_amcr >> (ffs(syscon_args[1]) - 1);
if (amcr != read_amcr) {
dev_err(dev, "AMCR value not coherent with DT memory-map areas\n");
diff --git a/drivers/memory/tegra/Makefile b/drivers/memory/tegra/Makefile
index 0750847dac3c..6334601e6120 100644
--- a/drivers/memory/tegra/Makefile
+++ b/drivers/memory/tegra/Makefile
@@ -10,6 +10,7 @@ tegra-mc-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
tegra-mc-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o
tegra-mc-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186.o tegra194.o
tegra-mc-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra186.o tegra234.o
+tegra-mc-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra186.o tegra264.o
obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
@@ -21,5 +22,6 @@ obj-$(CONFIG_TEGRA210_EMC) += tegra210-emc.o
obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-emc.o
obj-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186-emc.o
obj-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra186-emc.o
+obj-$(CONFIG_ARCH_TEGRA_264_SOC) += tegra186-emc.o
tegra210-emc-y := tegra210-emc-core.o tegra210-emc-cc-r21021.o
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index bd5b58f1fd42..6edb210287dc 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/clk.h>
@@ -49,6 +49,9 @@ static const struct of_device_id tegra_mc_of_match[] = {
#ifdef CONFIG_ARCH_TEGRA_234_SOC
{ .compatible = "nvidia,tegra234-mc", .data = &tegra234_mc_soc },
#endif
+#ifdef CONFIG_ARCH_TEGRA_264_SOC
+ { .compatible = "nvidia,tegra264-mc", .data = &tegra264_mc_soc },
+#endif
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index c3f6655bec60..1d97cf4d3a94 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef MEMORY_TEGRA_MC_H
@@ -182,6 +182,10 @@ extern const struct tegra_mc_soc tegra194_mc_soc;
extern const struct tegra_mc_soc tegra234_mc_soc;
#endif
+#ifdef CONFIG_ARCH_TEGRA_264_SOC
+extern const struct tegra_mc_soc tegra264_mc_soc;
+#endif
+
#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
defined(CONFIG_ARCH_TEGRA_114_SOC) || \
defined(CONFIG_ARCH_TEGRA_124_SOC) || \
@@ -193,7 +197,8 @@ extern const struct tegra_mc_ops tegra30_mc_ops;
#if defined(CONFIG_ARCH_TEGRA_186_SOC) || \
defined(CONFIG_ARCH_TEGRA_194_SOC) || \
- defined(CONFIG_ARCH_TEGRA_234_SOC)
+ defined(CONFIG_ARCH_TEGRA_234_SOC) || \
+ defined(CONFIG_ARCH_TEGRA_264_SOC)
extern const struct tegra_mc_ops tegra186_mc_ops;
#endif
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index bc807d7fcd4e..d6cd90c7ad53 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2019 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2019-2025 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/clk.h>
@@ -394,6 +394,9 @@ static const struct of_device_id tegra186_emc_of_match[] = {
#if defined(CONFIG_ARCH_TEGRA_234_SOC)
{ .compatible = "nvidia,tegra234-emc" },
#endif
+#if defined(CONFIG_ARCH_TEGRA_264_SOC)
+ { .compatible = "nvidia,tegra264-emc" },
+#endif
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, tegra186_emc_of_match);
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 1b3183951bfe..aee11457bf8e 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2017-2021 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2017-2025 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/io.h>
@@ -26,11 +26,24 @@
static int tegra186_mc_probe(struct tegra_mc *mc)
{
struct platform_device *pdev = to_platform_device(mc->dev);
+ struct resource *res;
unsigned int i;
char name[8];
int err;
- mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
+ /*
+ * From Tegra264, the SID region is not present in MC node and BROADCAST is first.
+ * The common function 'tegra_mc_probe()' already maps first region entry from DT.
+ * Check if the SID region is present in DT then map BROADCAST. Otherwise, consider
+ * the first entry mapped in mc probe as the BROADCAST region. This is done to avoid
+ * mapping the region twice when SID is not present and keep backward compatibility.
+ */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sid");
+ if (res)
+ mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
+ else
+ mc->bcast_ch_regs = mc->regs;
+
if (IS_ERR(mc->bcast_ch_regs)) {
if (PTR_ERR(mc->bcast_ch_regs) == -EINVAL) {
dev_warn(&pdev->dev,
diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
index e63f62690571..e96ca4157d48 100644
--- a/drivers/memory/tegra/tegra210-emc-core.c
+++ b/drivers/memory/tegra/tegra210-emc-core.c
@@ -558,7 +558,7 @@ tegra210_emc_table_register_offsets = {
static void tegra210_emc_train(struct timer_list *timer)
{
- struct tegra210_emc *emc = from_timer(emc, timer, training);
+ struct tegra210_emc *emc = timer_container_of(emc, timer, training);
unsigned long flags;
if (!emc->last)
@@ -614,7 +614,8 @@ static unsigned int tegra210_emc_get_temperature(struct tegra210_emc *emc)
static void tegra210_emc_poll_refresh(struct timer_list *timer)
{
- struct tegra210_emc *emc = from_timer(emc, timer, refresh_timer);
+ struct tegra210_emc *emc = timer_container_of(emc, timer,
+ refresh_timer);
unsigned int temperature;
if (!emc->debugfs.temperature)
diff --git a/drivers/memory/tegra/tegra264-bwmgr.h b/drivers/memory/tegra/tegra264-bwmgr.h
new file mode 100644
index 000000000000..93bfceaac9c8
--- /dev/null
+++ b/drivers/memory/tegra/tegra264-bwmgr.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2025 NVIDIA CORPORATION. All rights reserved. */
+
+#ifndef MEMORY_TEGRA_TEGRA264_BWMGR_H
+#define MEMORY_TEGRA_TEGRA264_BWMGR_H
+
+#define TEGRA264_BWMGR_ICC_PRIMARY 1
+#define TEGRA264_BWMGR_DEBUG 2
+#define TEGRA264_BWMGR_CPU_CLUSTER0 3
+#define TEGRA264_BWMGR_CPU_CLUSTER1 4
+#define TEGRA264_BWMGR_CPU_CLUSTER2 5
+#define TEGRA264_BWMGR_CPU_CLUSTER3 6
+#define TEGRA264_BWMGR_CPU_CLUSTER4 7
+#define TEGRA264_BWMGR_CPU_CLUSTER5 8
+#define TEGRA264_BWMGR_CPU_CLUSTER6 9
+#define TEGRA264_BWMGR_CACTMON 10
+#define TEGRA264_BWMGR_DISPLAY 11
+#define TEGRA264_BWMGR_VI 12
+#define TEGRA264_BWMGR_APE 13
+#define TEGRA264_BWMGR_VIFAL 14
+#define TEGRA264_BWMGR_GPU 15
+#define TEGRA264_BWMGR_EQOS 16
+#define TEGRA264_BWMGR_PCIE_0 17
+#define TEGRA264_BWMGR_PCIE_1 18
+#define TEGRA264_BWMGR_PCIE_2 19
+#define TEGRA264_BWMGR_PCIE_3 20
+#define TEGRA264_BWMGR_PCIE_4 21
+#define TEGRA264_BWMGR_PCIE_5 22
+#define TEGRA264_BWMGR_SDMMC_1 23
+#define TEGRA264_BWMGR_SDMMC_2 24
+#define TEGRA264_BWMGR_NVDEC 25
+#define TEGRA264_BWMGR_NVENC 26
+#define TEGRA264_BWMGR_NVJPG_0 27
+#define TEGRA264_BWMGR_NVJPG_1 28
+#define TEGRA264_BWMGR_OFAA 29
+#define TEGRA264_BWMGR_XUSB_HOST 30
+#define TEGRA264_BWMGR_XUSB_DEV 31
+#define TEGRA264_BWMGR_TSEC 32
+#define TEGRA264_BWMGR_VIC 33
+#define TEGRA264_BWMGR_APEDMA 34
+#define TEGRA264_BWMGR_SE 35
+#define TEGRA264_BWMGR_ISP 36
+#define TEGRA264_BWMGR_HDA 37
+#define TEGRA264_BWMGR_VI2FAL 38
+#define TEGRA264_BWMGR_VI2 39
+#define TEGRA264_BWMGR_RCE 40
+#define TEGRA264_BWMGR_PVA 41
+#define TEGRA264_BWMGR_NVPMODEL 42
+
+#endif
diff --git a/drivers/memory/tegra/tegra264.c b/drivers/memory/tegra/tegra264.c
new file mode 100644
index 000000000000..5203e6c11372
--- /dev/null
+++ b/drivers/memory/tegra/tegra264.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025, NVIDIA CORPORATION. All rights reserved.
+ */
+
+#include <dt-bindings/memory/nvidia,tegra264.h>
+
+#include <linux/interconnect.h>
+#include <linux/of_device.h>
+#include <linux/tegra-icc.h>
+
+#include <soc/tegra/bpmp.h>
+#include <soc/tegra/mc.h>
+
+#include "mc.h"
+#include "tegra264-bwmgr.h"
+
+/*
+ * MC Client entries are sorted in the increasing order of the
+ * override and security register offsets.
+ */
+static const struct tegra_mc_client tegra264_mc_clients[] = {
+ {
+ .id = TEGRA264_MEMORY_CLIENT_HDAR,
+ .name = "hdar",
+ .bpmp_id = TEGRA264_BWMGR_HDA,
+ .type = TEGRA_ICC_ISO_AUDIO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_HDAW,
+ .name = "hdaw",
+ .bpmp_id = TEGRA264_BWMGR_HDA,
+ .type = TEGRA_ICC_ISO_AUDIO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_MGBE0R,
+ .name = "mgbe0r",
+ .bpmp_id = TEGRA264_BWMGR_EQOS,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_MGBE0W,
+ .name = "mgbe0w",
+ .bpmp_id = TEGRA264_BWMGR_EQOS,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_MGBE1R,
+ .name = "mgbe1r",
+ .bpmp_id = TEGRA264_BWMGR_EQOS,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_MGBE1W,
+ .name = "mgbe1w",
+ .bpmp_id = TEGRA264_BWMGR_EQOS,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_SDMMC0R,
+ .name = "sdmmc0r",
+ .bpmp_id = TEGRA264_BWMGR_SDMMC_1,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_SDMMC0W,
+ .name = "sdmmc0w",
+ .bpmp_id = TEGRA264_BWMGR_SDMMC_1,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_VICR,
+ .name = "vicr",
+ .bpmp_id = TEGRA264_BWMGR_VIC,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_VICW,
+ .name = "vicw",
+ .bpmp_id = TEGRA264_BWMGR_VIC,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_APER,
+ .name = "aper",
+ .bpmp_id = TEGRA264_BWMGR_APE,
+ .type = TEGRA_ICC_ISO_AUDIO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_APEW,
+ .name = "apew",
+ .bpmp_id = TEGRA264_BWMGR_APE,
+ .type = TEGRA_ICC_ISO_AUDIO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_APEDMAR,
+ .name = "apedmar",
+ .bpmp_id = TEGRA264_BWMGR_APEDMA,
+ .type = TEGRA_ICC_ISO_AUDIO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_APEDMAW,
+ .name = "apedmaw",
+ .bpmp_id = TEGRA264_BWMGR_APEDMA,
+ .type = TEGRA_ICC_ISO_AUDIO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_VIFALCONR,
+ .name = "vifalconr",
+ .bpmp_id = TEGRA264_BWMGR_VIFAL,
+ .type = TEGRA_ICC_ISO_VIFAL,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_VIFALCONW,
+ .name = "vifalconw",
+ .bpmp_id = TEGRA264_BWMGR_VIFAL,
+ .type = TEGRA_ICC_ISO_VIFAL,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_RCER,
+ .name = "rcer",
+ .bpmp_id = TEGRA264_BWMGR_RCE,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_RCEW,
+ .name = "rcew",
+ .bpmp_id = TEGRA264_BWMGR_RCE,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE0W,
+ .name = "pcie0w",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_0,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE1R,
+ .name = "pcie1r",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_1,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE1W,
+ .name = "pcie1w",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_1,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE2AR,
+ .name = "pcie2ar",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_2,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE2AW,
+ .name = "pcie2aw",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_2,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE3R,
+ .name = "pcie3r",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_3,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE3W,
+ .name = "pcie3w",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_3,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE4R,
+ .name = "pcie4r",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_4,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE4W,
+ .name = "pcie4w",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_4,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE5R,
+ .name = "pcie5r",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_5,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_PCIE5W,
+ .name = "pcie5w",
+ .bpmp_id = TEGRA264_BWMGR_PCIE_5,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_GPUR02MC,
+ .name = "gpur02mc",
+ .bpmp_id = TEGRA264_BWMGR_GPU,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_GPUW02MC,
+ .name = "gpuw02mc",
+ .bpmp_id = TEGRA264_BWMGR_GPU,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_NVDECSRD2MC,
+ .name = "nvdecsrd2mc",
+ .bpmp_id = TEGRA264_BWMGR_NVDEC,
+ .type = TEGRA_ICC_NISO,
+ }, {
+ .id = TEGRA264_MEMORY_CLIENT_NVDECSWR2MC,
+ .name = "nvdecswr2mc",
+ .bpmp_id = TEGRA264_BWMGR_NVDEC,
+ .type = TEGRA_ICC_NISO,
+ },
+};
+
+/*
+ * tegra264_mc_icc_set() - Pass MC client info to the BPMP-FW
+ * @src: ICC node for Memory Controller's (MC) Client
+ * @dst: ICC node for Memory Controller (MC)
+ *
+ * Passing the current request info from the MC to the BPMP-FW where
+ * LA and PTSA registers are accessed and the final EMC freq is set
+ * based on client_id, type, latency and bandwidth.
+ * icc_set_bw() makes set_bw calls for both MC and EMC providers in
+ * sequence. Both the calls are protected by 'mutex_lock(&icc_lock)'.
+ * So, the data passed won't be updated by concurrent set calls from
+ * other clients.
+ */
+static int tegra264_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+ struct tegra_mc *mc = icc_provider_to_tegra_mc(dst->provider);
+ struct mrq_bwmgr_int_request bwmgr_req = { 0 };
+ struct mrq_bwmgr_int_response bwmgr_resp = { 0 };
+ const struct tegra_mc_client *pclient = src->data;
+ struct tegra_bpmp_message msg;
+ int ret;
+
+ /*
+ * Same Src and Dst node will happen during boot from icc_node_add().
+ * This can be used to pre-initialize and set bandwidth for all clients
+ * before their drivers are loaded. We are skipping this case as for us,
+ * the pre-initialization already happened in Bootloader(MB2) and BPMP-FW.
+ */
+ if (src->id == dst->id)
+ return 0;
+
+ if (!mc->bwmgr_mrq_supported)
+ return 0;
+
+ if (!mc->bpmp) {
+ dev_err(mc->dev, "BPMP reference NULL\n");
+ return -ENOENT;
+ }
+
+ if (pclient->type == TEGRA_ICC_NISO)
+ bwmgr_req.bwmgr_calc_set_req.niso_bw = src->avg_bw;
+ else
+ bwmgr_req.bwmgr_calc_set_req.iso_bw = src->avg_bw;
+
+ bwmgr_req.bwmgr_calc_set_req.client_id = pclient->bpmp_id;
+
+ bwmgr_req.cmd = CMD_BWMGR_INT_CALC_AND_SET;
+ bwmgr_req.bwmgr_calc_set_req.mc_floor = src->peak_bw;
+ bwmgr_req.bwmgr_calc_set_req.floor_unit = BWMGR_INT_UNIT_KBPS;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.mrq = MRQ_BWMGR_INT;
+ msg.tx.data = &bwmgr_req;
+ msg.tx.size = sizeof(bwmgr_req);
+ msg.rx.data = &bwmgr_resp;
+ msg.rx.size = sizeof(bwmgr_resp);
+
+ ret = tegra_bpmp_transfer(mc->bpmp, &msg);
+ if (ret < 0) {
+ dev_err(mc->dev, "BPMP transfer failed: %d\n", ret);
+ goto error;
+ }
+ if (msg.rx.ret < 0) {
+ pr_err("failed to set bandwidth for %u: %d\n",
+ bwmgr_req.bwmgr_calc_set_req.client_id, msg.rx.ret);
+ ret = -EINVAL;
+ }
+
+error:
+ return ret;
+}
+
+static int tegra264_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+ u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+ struct icc_provider *p = node->provider;
+ struct tegra_mc *mc = icc_provider_to_tegra_mc(p);
+
+ if (!mc->bwmgr_mrq_supported)
+ return 0;
+
+ *agg_avg += avg_bw;
+ *agg_peak = max(*agg_peak, peak_bw);
+
+ return 0;
+}
+
+static int tegra264_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+ *avg = 0;
+ *peak = 0;
+
+ return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra264_mc_icc_ops = {
+ .xlate = tegra_mc_icc_xlate,
+ .aggregate = tegra264_mc_icc_aggregate,
+ .get_bw = tegra264_mc_icc_get_init_bw,
+ .set = tegra264_mc_icc_set,
+};
+
+const struct tegra_mc_soc tegra264_mc_soc = {
+ .num_clients = ARRAY_SIZE(tegra264_mc_clients),
+ .clients = tegra264_mc_clients,
+ .num_address_bits = 40,
+ .num_channels = 16,
+ .client_id_mask = 0x1ff,
+ .intmask = MC_INT_DECERR_ROUTE_SANITY |
+ MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
+ MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .has_addr_hi_reg = true,
+ .ops = &tegra186_mc_ops,
+ .icc_ops = &tegra264_mc_icc_ops,
+ .ch_intmask = 0x0000ff00,
+ .global_intstatus_channel_shift = 8,
+ /*
+ * Additionally, there are lite carveouts but those are not currently
+ * supported.
+ */
+ .num_carveouts = 32,
+};