Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0b584a2 authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

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: default avatarMarkos 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent c014d164
Loading
Loading
Loading
Loading
+44 −4
Original line number Original line Diff line number Diff line
@@ -33,6 +33,20 @@ extern void __iomem *mips_cm_l2sync_base;
 */
 */
extern phys_addr_t __mips_cm_phys_base(void);
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
 * 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 */
/* Macros to ease the creation of register access functions */
#define BUILD_CM_R_(name, off)					\
#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());			\
	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)					\
#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());			\
	__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)					\
#define BUILD_CM_RW(name, off)					\
+4 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@


void __iomem *mips_cm_base;
void __iomem *mips_cm_base;
void __iomem *mips_cm_l2sync_base;
void __iomem *mips_cm_l2sync_base;
int mips_cm_is64;


phys_addr_t __mips_cm_phys_base(void)
phys_addr_t __mips_cm_phys_base(void)
{
{
@@ -124,5 +125,8 @@ int mips_cm_probe(void)
	/* probe for an L2-only sync region */
	/* probe for an L2-only sync region */
	mips_cm_probe_l2sync();
	mips_cm_probe_l2sync();


	/* determine register width for this CM */
	mips_cm_is64 = config_enabled(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);

	return 0;
	return 0;
}
}