From fe3b082a6eb8b1526ed7397c849d6b2a6baeb6a1 Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Tue, 7 Nov 2023 16:57:12 +0530 Subject: [PATCH 1/3] memory: tegra: Add SID override programming for MC clients For some devices the bootloader/firmware may set up the device in bypass. Memory clients like display needs kernel to program SID after resume because bootloader/firmware programs the SID of display device to bypass. In order to make sure that kernel IOMMU mappings for these devices work after resume, add SID override programming support for all memory clients on memory controller resume. This partially reverts 'commit ef86b2c2807f ("memory: tegra: Remove clients SID override programming")' Signed-off-by: Ashish Mhetre Link: https://lore.kernel.org/r/20231107112713.21399-1-amhetre@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186.c | 14 ++++++++++++++ include/soc/tegra/mc.h | 1 + 2 files changed, 15 insertions(+) diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c index 533f85a4b2bd..8203f0db1350 100644 --- a/drivers/memory/tegra/tegra186.c +++ b/drivers/memory/tegra/tegra186.c @@ -136,9 +136,23 @@ static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev) return 0; } +static int tegra186_mc_resume(struct tegra_mc *mc) +{ + unsigned int i; + + for (i = 0; i < mc->soc->num_clients; i++) { + const struct tegra_mc_client *client = &mc->soc->clients[i]; + + tegra186_mc_client_sid_override(mc, client, client->sid); + } + + return 0; +} + const struct tegra_mc_ops tegra186_mc_ops = { .probe = tegra186_mc_probe, .remove = tegra186_mc_remove, + .resume = tegra186_mc_resume, .probe_device = tegra186_mc_probe_device, .handle_irq = tegra30_mc_handle_irq, }; diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index 71ae37d3bedd..af1d73a7f0cd 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -162,6 +162,7 @@ struct tegra_mc_ops { */ int (*probe)(struct tegra_mc *mc); void (*remove)(struct tegra_mc *mc); + int (*resume)(struct tegra_mc *mc); irqreturn_t (*handle_irq)(int irq, void *data); int (*probe_device)(struct tegra_mc *mc, struct device *dev); }; From 0d6c918011ce4764ed277de4726a468b7ffe5fed Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Tue, 7 Nov 2023 16:57:13 +0530 Subject: [PATCH 2/3] memory: tegra: Skip SID programming if SID registers aren't set There are few MC clients where SID security and override register offsets are not specified like "sw_cluster0" in tegra234. Don't program SID override for such clients because it leads to access to invalid addresses. Signed-off-by: Ashish Mhetre Link: https://lore.kernel.org/r/20231107112713.21399-2-amhetre@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c index 8203f0db1350..d1f1dfb42716 100644 --- a/drivers/memory/tegra/tegra186.c +++ b/drivers/memory/tegra/tegra186.c @@ -75,6 +75,9 @@ static void tegra186_mc_client_sid_override(struct tegra_mc *mc, { u32 value, old; + if (client->regs.sid.security == 0 && client->regs.sid.override == 0) + return; + value = readl(mc->regs + client->regs.sid.security); if ((value & MC_SID_STREAMID_SECURITY_OVERRIDE) == 0) { /* From 4a23d0f9814c38308dc82b6dbc466666a400b27d Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Tue, 5 Dec 2023 11:30:45 +0530 Subject: [PATCH 3/3] memory: tegra: Protect SID override call under CONFIG_IOMMU_API tegra186_mc_client_sid_override() is protected under CONFIG_IOMMU_API. Call to this function is being made from tegra186_mc_resume() without any protection which is leading to build failure when CONFIG_IOMMU_API is not set. Fix this by protecting SID override function call from tegra186_mc_resume() under CONFIG_IOMMU_API. Fixes: fe3b082a6eb8 ("memory: tegra: Add SID override programming for MC clients") Signed-off-by: Ashish Mhetre Reported-by: Randy Dunlap Acked-by: Randy Dunlap Tested-by: Randy Dunlap # build-tested Link: https://lore.kernel.org/r/20231205060045.7985-1-amhetre@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c index d1f1dfb42716..0ff014a9d3cd 100644 --- a/drivers/memory/tegra/tegra186.c +++ b/drivers/memory/tegra/tegra186.c @@ -141,6 +141,7 @@ static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev) static int tegra186_mc_resume(struct tegra_mc *mc) { +#if IS_ENABLED(CONFIG_IOMMU_API) unsigned int i; for (i = 0; i < mc->soc->num_clients; i++) { @@ -148,6 +149,7 @@ static int tegra186_mc_resume(struct tegra_mc *mc) tegra186_mc_client_sid_override(mc, client, client->sid); } +#endif return 0; }