diff mbox

memory: tegra: mc: add support for a variable-size client ID bitfield

Message ID alpine.DEB.2.02.1506041924320.12316@utopia.booyaka.com
State Deferred
Headers show

Commit Message

Paul Walmsley June 4, 2015, 7:33 p.m. UTC
Recent versions of the Tegra MC hardware extend the size of the client
ID bitfield in the MC_ERR_STATUS register by one bit.  While one could
simply extend the bitfield for older hardware, that would allow data
from reserved bits into the driver code, which is generally a bad idea
on principle.  So this patch instead passes in the
MC_ERR_STATUS_CLIENT_MASK from the per-SoC MC data.

There's no MC support for T210 (yet), but when that support winds up
in the kernel, the appropriate soc->client_id_mask value for
that chip will be 0xff.

Based on an original patch by David Ung <davidu@nvidia.com>.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Paul Walmsley <pwalmsley@nvidia.com>
Cc: Thierry Reding <treding@nvidia.com>
Cc: David Ung <davidu@nvidia.com>
---
Based on next-20150602.  Basic build and boot test results are here:

http://nvt.pwsan.com/pub/pwalmsley-tester/testlogs/test_20150604122454_0ba689090bdac347f87b8f5892552d4f8b1b6a78/20150604122454/

(The multi_v7_defconfig build failure is due to unrelated problems with 
the sunxi clk drivers)

Intended for v4.3.

 drivers/memory/tegra/mc.c       | 5 +++--
 drivers/memory/tegra/tegra114.c | 1 +
 drivers/memory/tegra/tegra124.c | 2 ++
 drivers/memory/tegra/tegra30.c  | 1 +
 include/soc/tegra/mc.h          | 6 ++++++
 5 files changed, 13 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index c71ede67e6c8..d5d99c1c689c 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -42,7 +42,6 @@ 
 #define  MC_ERR_STATUS_ADR_HI_MASK 0x3
 #define  MC_ERR_STATUS_SECURITY (1 << 17)
 #define  MC_ERR_STATUS_RW (1 << 16)
-#define  MC_ERR_STATUS_CLIENT_MASK 0x7f
 
 #define MC_ERR_ADR 0x0c
 
@@ -283,7 +282,7 @@  static irqreturn_t tegra_mc_irq(int irq, void *data)
 		else
 			secure = "";
 
-		id = value & MC_ERR_STATUS_CLIENT_MASK;
+		id = value & mc->soc->client_id_mask;
 
 		for (i = 0; i < mc->soc->num_clients; i++) {
 			if (mc->soc->clients[i].id == id) {
@@ -410,6 +409,8 @@  static int tegra_mc_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	WARN(!mc->soc->client_id_mask, "Missing client_id_mask for this SoC\n");
+
 	value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
 		MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
 		MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM;
diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index 9f579589e800..a0b138310cd6 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -944,5 +944,6 @@  const struct tegra_mc_soc tegra114_mc_soc = {
 	.num_clients = ARRAY_SIZE(tegra114_mc_clients),
 	.num_address_bits = 32,
 	.atom_size = 32,
+	.client_id_mask = T30_MC_ERR_STATUS_CLIENT_MASK,
 	.smmu = &tegra114_smmu_soc,
 };
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 966e1557e6f4..7aa0b79fac73 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1032,6 +1032,7 @@  const struct tegra_mc_soc tegra124_mc_soc = {
 	.num_clients = ARRAY_SIZE(tegra124_mc_clients),
 	.num_address_bits = 34,
 	.atom_size = 32,
+	.client_id_mask = T30_MC_ERR_STATUS_CLIENT_MASK,
 	.smmu = &tegra124_smmu_soc,
 	.emem_regs = tegra124_mc_emem_regs,
 	.num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs),
@@ -1067,6 +1068,7 @@  const struct tegra_mc_soc tegra132_mc_soc = {
 	.num_clients = ARRAY_SIZE(tegra124_mc_clients),
 	.num_address_bits = 34,
 	.atom_size = 32,
+	.client_id_mask = T30_MC_ERR_STATUS_CLIENT_MASK,
 	.smmu = &tegra132_smmu_soc,
 };
 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index 1abcd8f6f3ba..dc46bf7ec40e 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -966,5 +966,6 @@  const struct tegra_mc_soc tegra30_mc_soc = {
 	.num_clients = ARRAY_SIZE(tegra30_mc_clients),
 	.num_address_bits = 32,
 	.atom_size = 16,
+	.client_id_mask = T30_MC_ERR_STATUS_CLIENT_MASK,
 	.smmu = &tegra30_smmu_soc,
 };
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1ab2813273cd..9fa2451dd1ae 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -92,6 +92,10 @@  static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
 }
 #endif
 
+/* Some SoC-specific MC_ERR_STATUS register bitfields */
+#define T30_MC_ERR_STATUS_CLIENT_MASK	0x7f
+#define T210_MC_ERR_STATUS_CLIENT_MASK	0xff
+
 struct tegra_mc_soc {
 	const struct tegra_mc_client *clients;
 	unsigned int num_clients;
@@ -102,6 +106,8 @@  struct tegra_mc_soc {
 	unsigned int num_address_bits;
 	unsigned int atom_size;
 
+	u8 client_id_mask;
+
 	const struct tegra_smmu_soc *smmu;
 };