memory: tegra: Add support for a variable-size client ID bitfield
authorPaul Walmsley <paul@pwsan.com>
Thu, 4 Jun 2015 19:33:48 +0000 (19:33 +0000)
committerThierry Reding <treding@nvidia.com>
Thu, 13 Aug 2015 14:07:52 +0000 (16:07 +0200)
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 client ID mask from
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>
Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/memory/tegra/mc.c
drivers/memory/tegra/tegra114.c
drivers/memory/tegra/tegra124.c
drivers/memory/tegra/tegra30.c
include/soc/tegra/mc.h

index c71ede67e6c88399d5b6dec2be5cbf166985930d..5d10c9285f34736956e45984bd3dedab097c1c9e 100644 (file)
@@ -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;
index 9f579589e8000aaac06333c8d7162bdd5b6041ae..c8765db07a62517c2f4cf221d7cf488af95cf273 100644 (file)
@@ -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 = 0x7f,
        .smmu = &tegra114_smmu_soc,
 };
index 966e1557e6f414598868a8392b5487cb05e09f61..060fb3d7a23fb2b4ba486f6e069e55f190563898 100644 (file)
@@ -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 = 0x7f,
        .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 = 0x7f,
        .smmu = &tegra132_smmu_soc,
 };
 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
index 1abcd8f6f3ba60ed6cdabcc28478123061af0b63..52e16c7b34f81f94a851dfc1b839676f8d879a9f 100644 (file)
@@ -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 = 0x7f,
        .smmu = &tegra30_smmu_soc,
 };
index 1ab2813273cd1cf7d0116ca3d64b08de18013304..370f2909ec19d3a884aaf384549499bac4a6e085 100644 (file)
@@ -102,6 +102,8 @@ struct tegra_mc_soc {
        unsigned int num_address_bits;
        unsigned int atom_size;
 
+       u8 client_id_mask;
+
        const struct tegra_smmu_soc *smmu;
 };