diff options
author | Markos Chandras <markos.chandras@imgtec.com> | 2015-07-14 11:14:12 +0300 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-08-26 16:23:12 +0300 |
commit | c0b584a2691ccbc3c0d4e6cb1874bcf00a921371 (patch) | |
tree | bf9c066b0cf5102ee911d38209b105f8f6aaf7e2 /arch/mips/include/asm/mips-cm.h | |
parent | c014d164f21dbdbe721a4ec7e5147591c4eed545 (diff) | |
download | linux-c0b584a2691ccbc3c0d4e6cb1874bcf00a921371.tar.xz |
MIPS: mips-cm: Extend CM accessors for 64-bit CPUs
Previously, the CM accessors were only accessing CM registers as u32
types instead of using the native CM register with. However, newer CMs
may actually be 64-bit on MIPS64 cores. Fortunately, current 64-bit CMs
(CM3) hold all the useful configuration bits in the lower half of the
64-bit registers (at least most of them) so they can still be accessed
using the current 32-bit accessors.
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Bresticker <abrestic@chromium.org>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/10707/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm/mips-cm.h')
-rw-r--r-- | arch/mips/include/asm/mips-cm.h | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index ca3f2c963fbd..46cc0c69b77c 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -33,6 +33,20 @@ extern void __iomem *mips_cm_l2sync_base; */ extern phys_addr_t __mips_cm_phys_base(void); +/* + * mips_cm_is64 - determine CM register width + * + * The CM register width is processor and CM specific. A 64-bit processor + * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit + * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs + * can be done either using regular 64-bit load/store instructions, or 32-bit + * load/store instruction on 32-bit register pairs. We opt for using 64-bit + * accesses on 64-bit CMs and kernels and 32-bit in any other case. + * + * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses. + */ +extern int mips_cm_is64; + /** * mips_cm_probe - probe for a Coherence Manager * @@ -90,20 +104,46 @@ static inline bool mips_cm_has_l2sync(void) /* Macros to ease the creation of register access functions */ #define BUILD_CM_R_(name, off) \ -static inline u32 __iomem *addr_gcr_##name(void) \ +static inline unsigned long __iomem *addr_gcr_##name(void) \ { \ - return (u32 __iomem *)(mips_cm_base + (off)); \ + return (unsigned long __iomem *)(mips_cm_base + (off)); \ } \ \ -static inline u32 read_gcr_##name(void) \ +static inline u32 read32_gcr_##name(void) \ { \ return __raw_readl(addr_gcr_##name()); \ +} \ + \ +static inline u64 read64_gcr_##name(void) \ +{ \ + return __raw_readq(addr_gcr_##name()); \ +} \ + \ +static inline unsigned long read_gcr_##name(void) \ +{ \ + if (mips_cm_is64) \ + return read64_gcr_##name(); \ + else \ + return read32_gcr_##name(); \ } #define BUILD_CM__W(name, off) \ -static inline void write_gcr_##name(u32 value) \ +static inline void write32_gcr_##name(u32 value) \ { \ __raw_writel(value, addr_gcr_##name()); \ +} \ + \ +static inline void write64_gcr_##name(u64 value) \ +{ \ + __raw_writeq(value, addr_gcr_##name()); \ +} \ + \ +static inline void write_gcr_##name(unsigned long value) \ +{ \ + if (mips_cm_is64) \ + write64_gcr_##name(value); \ + else \ + write32_gcr_##name(value); \ } #define BUILD_CM_RW(name, off) \ |