diff options
author | Hiro Sugawara <hsugawara@nvidia.com> | 2011-06-16 16:30:13 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:47:15 -0800 |
commit | bc5d6e60f4e81a36146692525902ff894a73e57c (patch) | |
tree | 9a3a7974f5690957b05c98b6a2fa86f57c04f9bc /arch/arm/mach-tegra/iovmm-smmu.c | |
parent | 5aa5d0a98a577476ae655fe3c3bdc87432befa9b (diff) |
arm: tegra: Add sysfs entries for SMMU debugging
CONFIG_TEGRA_SMMU_SYSFS enables /sys/devices/smmu/* entries to update
various SMMU register contents from user's land.
Default is "n" to allow only displaying the current values but not
updating except SMMU TLB/PTC statistics enabling and disabling bits.
Original-Change-Id: Icb4574c08d89006cb09da1d8d60c7ab40fefd1b1
Reviewed-on: http://git-master/r/37118
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Rebase-Id: R647d1f9a59edbbc8a60b7393cb0572a927bd6d32
Diffstat (limited to 'arch/arm/mach-tegra/iovmm-smmu.c')
-rw-r--r-- | arch/arm/mach-tegra/iovmm-smmu.c | 65 |
1 files changed, 43 insertions, 22 deletions
diff --git a/arch/arm/mach-tegra/iovmm-smmu.c b/arch/arm/mach-tegra/iovmm-smmu.c index 9eb1484be676..021906b99bfb 100644 --- a/arch/arm/mach-tegra/iovmm-smmu.c +++ b/arch/arm/mach-tegra/iovmm-smmu.c @@ -39,8 +39,6 @@ #include <mach/iomap.h> /* For debugging */ -/*#define HIT_MISS_STAT */ -/*#define SMMU_SYSFS */ /*#define SMMU_DEBUG*/ #ifdef SMMU_DEBUG @@ -58,12 +56,14 @@ #define MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE 1 #define MC_SMMU_TLB_CONFIG_0 0x14 +#define MC_SMMU_TLB_CONFIG_0_TLB_STATS__MASK (1<<31) #define MC_SMMU_TLB_CONFIG_0_TLB_STATS__ENABLE (1<<31) #define MC_SMMU_TLB_CONFIG_0_TLB_HIT_UNDER_MISS__ENABLE (1<<29) #define MC_SMMU_TLB_CONFIG_0_TLB_ACTIVE_LINES__VALUE 0x10 #define MC_SMMU_TLB_CONFIG_0_RESET_VAL 0x20000010 #define MC_SMMU_PTC_CONFIG_0 0x18 +#define MC_SMMU_PTC_CONFIG_0_PTC_STATS__MASK (1<<31) #define MC_SMMU_PTC_CONFIG_0_PTC_STATS__ENABLE (1<<31) #define MC_SMMU_PTC_CONFIG_0_PTC_CACHE__ENABLE (1<<29) #define MC_SMMU_PTC_CONFIG_0_PTC_INDEX_MAP__PATTERN 0x3f @@ -398,24 +398,10 @@ static void smmu_setup_regs(struct smmu_device *smmu) smmu->regs + MC_SMMU_TRANSLATION_ENABLE_2_0); writel(smmu->asid_security_0, smmu->regs + MC_SMMU_ASID_SECURITY_0); -#ifdef HIT_MISS_STAT - writel( - MC_SMMU_TLB_CONFIG_0_TLB_STATS__ENABLE | - MC_SMMU_TLB_CONFIG_0_TLB_HIT_UNDER_MISS__ENABLE | - MC_SMMU_TLB_CONFIG_0_TLB_ACTIVE_LINES__VALUE, - smmu->regs + MC_SMMU_TLB_CONFIG_0); - - writel( - MC_SMMU_PTC_CONFIG_0_PTC_STATS__ENABLE | - MC_SMMU_PTC_CONFIG_0_PTC_CACHE__ENABLE | - MC_SMMU_PTC_CONFIG_0_PTC_INDEX_MAP__PATTERN, - smmu->regs + MC_SMMU_PTC_CONFIG_0); -#else writel(MC_SMMU_TLB_CONFIG_0_RESET_VAL, smmu->regs + MC_SMMU_TLB_CONFIG_0); writel(MC_SMMU_PTC_CONFIG_0_RESET_VAL, smmu->regs + MC_SMMU_PTC_CONFIG_0); -#endif smmu_flush_regs(smmu, 1); writel( @@ -1074,7 +1060,6 @@ static void __exit smmu_exit(void) subsys_initcall(smmu_init); module_exit(smmu_exit); -#ifdef SMMU_SYSFS /* * SMMU-global sysfs interface for debugging */ @@ -1165,7 +1150,33 @@ static ssize_t _sysfs_store_reg(struct device *d, if (offset < 0) return offset; value = simple_strtoul(buf, NULL, 16); +#ifdef CONFIG_TEGRA_SMMU_SYSFS writel(value, smmu->regs + offset); +#else + /* Allow writing to reg only for TLB/PTC stats enabling/disabling */ + { + unsigned long mask = 0; + switch (offset) + { + case MC_SMMU_TLB_CONFIG_0: + mask = MC_SMMU_TLB_CONFIG_0_TLB_STATS__MASK; + break; + case MC_SMMU_PTC_CONFIG_0: + mask = MC_SMMU_PTC_CONFIG_0_PTC_STATS__MASK; + break; + default: + break; + } + + if (mask) { + unsigned long currval = readl(smmu->regs + offset); + currval &= ~mask; + value &= mask; + value |= currval; + writel(value, smmu->regs + offset); + } + } +#endif return count; } @@ -1200,6 +1211,10 @@ static ssize_t _sysfs_show_##name(struct device *d, \ return rv; \ } +#ifdef CONFIG_TEGRA_SMMU_SYSFS +static void (*_sysfs_null_callback)(struct smmu_device *, unsigned long *) = + NULL; + #define _SYSFS_SET_VALUE(name, field, base, ceil, callback) \ static ssize_t _sysfs_set_##name(struct device *d, \ struct device_attribute *da, const char *buf, size_t count) \ @@ -1214,9 +1229,15 @@ static ssize_t _sysfs_set_##name(struct device *d, \ } \ return count; \ } +#else +#define _SYSFS_SET_VALUE(name, field, base, ceil, callback) \ +static ssize_t _sysfs_set_##name(struct device *d, \ + struct device_attribute *da, const char *buf, size_t count) \ +{ \ + return count; \ +} +#endif -static void (*_sysfs_null_callback)(struct smmu_device *, unsigned long *) = - NULL; _SYSFS_SHOW_VALUE(lowest_asid, lowest_asid, "%lu") _SYSFS_SET_VALUE(lowest_asid, lowest_asid, 10, MC_SMMU_NUM_ASIDS, _sysfs_null_callback) @@ -1226,6 +1247,7 @@ _SYSFS_SET_VALUE(debug_asid, debug_asid, 10, _SYSFS_SHOW_VALUE(verbose, verbose, "%lu") _SYSFS_SET_VALUE(verbose, verbose, 10, 3, _sysfs_null_callback) +#ifdef CONFIG_TEGRA_SMMU_SYSFS static void _sysfs_mask_attr(struct smmu_device *smmu, unsigned long *field) { *field &= _MASK_ATTR; @@ -1250,6 +1272,8 @@ static void (*_sysfs_mask_attr_callback)(struct smmu_device *, unsigned long *field) = &_sysfs_mask_attr; static void (*_sysfs_mask_pdir_attr_callback)(struct smmu_device *, unsigned long *field) = &_sysfs_mask_pdir_attr; +#endif + _SYSFS_SHOW_VALUE(pdir_attr, as[smmu->debug_asid].pdir_attr, "%lx") _SYSFS_SET_VALUE(pdir_attr, as[smmu->debug_asid].pdir_attr, 16, _PDIR_ATTR+1, _sysfs_mask_pdir_attr_callback) @@ -1311,11 +1335,8 @@ static void _sysfs_smmu(struct smmu_device *smmu, struct device *parent) return; } } -#endif static void _sysfs_create(struct smmu_as *as, struct device *parent) { -#ifdef SMMU_SYSFS _sysfs_smmu(as->smmu, parent); -#endif } |