aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorAshish Mhetre <amhetre@nvidia.com>2022-05-06 15:23:11 +0200
committerKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>2022-05-09 10:46:11 +0200
commita7cffa11fa9232eabf0c4f441dc53002978ab526 (patch)
tree4ccdc2a99c2875162eb8ec1dfe14afca5273bc93 /drivers/memory
parentmemory: tegra: Add APE memory clients for Tegra234 (diff)
downloadlinux-dev-a7cffa11fa9232eabf0c4f441dc53002978ab526.tar.xz
linux-dev-a7cffa11fa9232eabf0c4f441dc53002978ab526.zip
memory: tegra: Add memory controller channels support
From Tegra186 onwards, the memory controller supports multiple channels. Add support for mapping the address spaces of these channels and specify the number of channels supported by Tegra186, Tegra194 and Tegra234. In case of old bindings, channels won't be present. If channels are not present then print a warning and continue so that backward compatibility will be preserved in driver. During error interrupts from memory controller, appropriate registers from these channels need to be accessed for logging error info. Signed-off-by: Ashish Mhetre <amhetre@nvidia.com> Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Link: https://lore.kernel.org/r/20220506132312.3910637-4-thierry.reding@gmail.com Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/tegra/tegra186.c30
-rw-r--r--drivers/memory/tegra/tegra194.c1
-rw-r--r--drivers/memory/tegra/tegra234.c1
3 files changed, 32 insertions, 0 deletions
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index 3d153881abc1..4a84752403d8 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -48,8 +48,37 @@ static void tegra186_mc_program_sid(struct tegra_mc *mc)
static int tegra186_mc_probe(struct tegra_mc *mc)
{
+ struct platform_device *pdev = to_platform_device(mc->dev);
+ unsigned int i;
+ char name[8];
int err;
+ mc->bcast_ch_regs = devm_platform_ioremap_resource_byname(pdev, "broadcast");
+ if (IS_ERR(mc->bcast_ch_regs)) {
+ if (PTR_ERR(mc->bcast_ch_regs) == -EINVAL) {
+ dev_warn(&pdev->dev,
+ "Broadcast channel is missing, please update your device-tree\n");
+ mc->bcast_ch_regs = NULL;
+ goto populate;
+ }
+
+ return PTR_ERR(mc->bcast_ch_regs);
+ }
+
+ mc->ch_regs = devm_kcalloc(mc->dev, mc->soc->num_channels, sizeof(*mc->ch_regs),
+ GFP_KERNEL);
+ if (!mc->ch_regs)
+ return -ENOMEM;
+
+ for (i = 0; i < mc->soc->num_channels; i++) {
+ snprintf(name, sizeof(name), "ch%u", i);
+
+ mc->ch_regs[i] = devm_platform_ioremap_resource_byname(pdev, name);
+ if (IS_ERR(mc->ch_regs[i]))
+ return PTR_ERR(mc->ch_regs[i]);
+ }
+
+populate:
err = of_platform_populate(mc->dev->of_node, NULL, NULL, mc->dev);
if (err < 0)
return err;
@@ -875,6 +904,7 @@ const struct tegra_mc_soc tegra186_mc_soc = {
.num_clients = ARRAY_SIZE(tegra186_mc_clients),
.clients = tegra186_mc_clients,
.num_address_bits = 40,
+ .num_channels = 4,
.ops = &tegra186_mc_ops,
};
#endif
diff --git a/drivers/memory/tegra/tegra194.c b/drivers/memory/tegra/tegra194.c
index cab998b8bd5c..94001174deaf 100644
--- a/drivers/memory/tegra/tegra194.c
+++ b/drivers/memory/tegra/tegra194.c
@@ -1347,5 +1347,6 @@ const struct tegra_mc_soc tegra194_mc_soc = {
.num_clients = ARRAY_SIZE(tegra194_mc_clients),
.clients = tegra194_mc_clients,
.num_address_bits = 40,
+ .num_channels = 16,
.ops = &tegra186_mc_ops,
};
diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c
index e22824a79f45..6335a132be2d 100644
--- a/drivers/memory/tegra/tegra234.c
+++ b/drivers/memory/tegra/tegra234.c
@@ -97,5 +97,6 @@ const struct tegra_mc_soc tegra234_mc_soc = {
.num_clients = ARRAY_SIZE(tegra234_mc_clients),
.clients = tegra234_mc_clients,
.num_address_bits = 40,
+ .num_channels = 16,
.ops = &tegra186_mc_ops,
};