All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] MIPS: Initial multi-cluster support
@ 2017-08-13  2:49 ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

This series cleans up some MIPS Coherent Processing System (CPS) code,
and then introduces the first portions of support for multi-cluster
systems, which are introduced with CM 3.5 & the MIPS I6500 core. My hope
is that this initial groundwork can go in first, then patches adding
support to the necessary drivers, power management & SMP code can follow
culminating in a later patchset to enable actually booting CPUs in
secondary clusters.

Applies to mips-for-linux-next as of aa9a357f236f.


Paul Burton (19):
  MIPS: CM: Rename mips_cm_base to mips_gcr_base
  MIPS: CM: Specify register size when generating accessors
  MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts
  MIPS: CPC: Use common CPS accessor generation macros
  MIPS: CPC: Use BIT/GENMASK for register fields, order & drop shifts
  MIPS: CPS: Introduce register modify (set/clear/change) accessors
  MIPS: CPS: Use change_*, set_* & clear_* where appropriate
  MIPS: CPS: Add CM/CPC 3.5 register definitions
  MIPS: Add accessor & bit definitions for GlobalNumber
  MIPS: CPS: Use GlobalNumber macros rather than magic numbers
  MIPS: Abstract CPU core & VP(E) ID access through accessor functions
  MIPS: Store core & VP IDs in GlobalNumber-style variable
  MIPS: Unify checks for sibling CPUs
  MIPS: Add CPU cluster number accessors
  MIPS: CM: Add cluster & block args to mips_cm_lock_other()
  MIPS: SMP: Allow boot_secondary SMP op to return errors
  MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers
  MIPS: CPS: Cluster support for topology functions
  MIPS: CPS: Detect CPUs in secondary clusters

 arch/mips/cavium-octeon/smp.c         |   8 +-
 arch/mips/include/asm/cpu-info.h      |  62 +++-
 arch/mips/include/asm/mips-cm.h       | 567 +++++++++++++++-------------------
 arch/mips/include/asm/mips-cpc.h      | 177 ++++++-----
 arch/mips/include/asm/mips-cps.h      | 239 ++++++++++++++
 arch/mips/include/asm/mipsregs.h      |  13 +
 arch/mips/include/asm/smp-ops.h       |   4 +-
 arch/mips/include/asm/topology.h      |   2 +-
 arch/mips/kernel/cps-vec.S            |   4 +-
 arch/mips/kernel/cpu-probe.c          |  39 ++-
 arch/mips/kernel/mips-cm.c            |  94 +++---
 arch/mips/kernel/mips-cpc.c           |  17 +-
 arch/mips/kernel/pm-cps.c             |  15 +-
 arch/mips/kernel/proc.c               |   6 +-
 arch/mips/kernel/smp-bmips.c          |   6 +-
 arch/mips/kernel/smp-cmp.c            |   3 +-
 arch/mips/kernel/smp-cps.c            | 145 +++++----
 arch/mips/kernel/smp-mt.c             |   6 +-
 arch/mips/kernel/smp-up.c             |   3 +-
 arch/mips/kernel/smp.c                |  20 +-
 arch/mips/kernel/traps.c              |  11 +-
 arch/mips/loongson64/loongson-3/smp.c |  14 +-
 arch/mips/mm/c-r4k.c                  |   2 +-
 arch/mips/mm/sc-mips.c                |  47 ++-
 arch/mips/mti-malta/malta-dtshim.c    |   4 +-
 arch/mips/mti-malta/malta-init.c      |   3 +-
 arch/mips/mti-malta/malta-int.c       |   1 -
 arch/mips/mti-malta/malta-setup.c     |   4 +-
 arch/mips/netlogic/common/smp.c       |   6 +-
 arch/mips/oprofile/op_model_mipsxx.c  |   4 +-
 arch/mips/paravirt/paravirt-smp.c     |   3 +-
 arch/mips/pci/pci-malta.c             |   6 +-
 arch/mips/pistachio/init.c            |   3 +-
 arch/mips/ralink/mt7621.c             |   5 +-
 arch/mips/sgi-ip27/ip27-smp.c         |   3 +-
 arch/mips/sibyte/bcm1480/smp.c        |   3 +-
 arch/mips/sibyte/sb1250/smp.c         |   3 +-
 arch/mips/vdso/gettimeofday.c         |   1 -
 drivers/cpuidle/cpuidle-cps.c         |   2 +-
 drivers/irqchip/irq-mips-cpu.c        |   2 +-
 drivers/irqchip/irq-mips-gic.c        |   6 +-
 41 files changed, 922 insertions(+), 641 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-cps.h

-- 
2.14.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 00/19] MIPS: Initial multi-cluster support
@ 2017-08-13  2:49 ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

This series cleans up some MIPS Coherent Processing System (CPS) code,
and then introduces the first portions of support for multi-cluster
systems, which are introduced with CM 3.5 & the MIPS I6500 core. My hope
is that this initial groundwork can go in first, then patches adding
support to the necessary drivers, power management & SMP code can follow
culminating in a later patchset to enable actually booting CPUs in
secondary clusters.

Applies to mips-for-linux-next as of aa9a357f236f.


Paul Burton (19):
  MIPS: CM: Rename mips_cm_base to mips_gcr_base
  MIPS: CM: Specify register size when generating accessors
  MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts
  MIPS: CPC: Use common CPS accessor generation macros
  MIPS: CPC: Use BIT/GENMASK for register fields, order & drop shifts
  MIPS: CPS: Introduce register modify (set/clear/change) accessors
  MIPS: CPS: Use change_*, set_* & clear_* where appropriate
  MIPS: CPS: Add CM/CPC 3.5 register definitions
  MIPS: Add accessor & bit definitions for GlobalNumber
  MIPS: CPS: Use GlobalNumber macros rather than magic numbers
  MIPS: Abstract CPU core & VP(E) ID access through accessor functions
  MIPS: Store core & VP IDs in GlobalNumber-style variable
  MIPS: Unify checks for sibling CPUs
  MIPS: Add CPU cluster number accessors
  MIPS: CM: Add cluster & block args to mips_cm_lock_other()
  MIPS: SMP: Allow boot_secondary SMP op to return errors
  MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers
  MIPS: CPS: Cluster support for topology functions
  MIPS: CPS: Detect CPUs in secondary clusters

 arch/mips/cavium-octeon/smp.c         |   8 +-
 arch/mips/include/asm/cpu-info.h      |  62 +++-
 arch/mips/include/asm/mips-cm.h       | 567 +++++++++++++++-------------------
 arch/mips/include/asm/mips-cpc.h      | 177 ++++++-----
 arch/mips/include/asm/mips-cps.h      | 239 ++++++++++++++
 arch/mips/include/asm/mipsregs.h      |  13 +
 arch/mips/include/asm/smp-ops.h       |   4 +-
 arch/mips/include/asm/topology.h      |   2 +-
 arch/mips/kernel/cps-vec.S            |   4 +-
 arch/mips/kernel/cpu-probe.c          |  39 ++-
 arch/mips/kernel/mips-cm.c            |  94 +++---
 arch/mips/kernel/mips-cpc.c           |  17 +-
 arch/mips/kernel/pm-cps.c             |  15 +-
 arch/mips/kernel/proc.c               |   6 +-
 arch/mips/kernel/smp-bmips.c          |   6 +-
 arch/mips/kernel/smp-cmp.c            |   3 +-
 arch/mips/kernel/smp-cps.c            | 145 +++++----
 arch/mips/kernel/smp-mt.c             |   6 +-
 arch/mips/kernel/smp-up.c             |   3 +-
 arch/mips/kernel/smp.c                |  20 +-
 arch/mips/kernel/traps.c              |  11 +-
 arch/mips/loongson64/loongson-3/smp.c |  14 +-
 arch/mips/mm/c-r4k.c                  |   2 +-
 arch/mips/mm/sc-mips.c                |  47 ++-
 arch/mips/mti-malta/malta-dtshim.c    |   4 +-
 arch/mips/mti-malta/malta-init.c      |   3 +-
 arch/mips/mti-malta/malta-int.c       |   1 -
 arch/mips/mti-malta/malta-setup.c     |   4 +-
 arch/mips/netlogic/common/smp.c       |   6 +-
 arch/mips/oprofile/op_model_mipsxx.c  |   4 +-
 arch/mips/paravirt/paravirt-smp.c     |   3 +-
 arch/mips/pci/pci-malta.c             |   6 +-
 arch/mips/pistachio/init.c            |   3 +-
 arch/mips/ralink/mt7621.c             |   5 +-
 arch/mips/sgi-ip27/ip27-smp.c         |   3 +-
 arch/mips/sibyte/bcm1480/smp.c        |   3 +-
 arch/mips/sibyte/sb1250/smp.c         |   3 +-
 arch/mips/vdso/gettimeofday.c         |   1 -
 drivers/cpuidle/cpuidle-cps.c         |   2 +-
 drivers/irqchip/irq-mips-cpu.c        |   2 +-
 drivers/irqchip/irq-mips-gic.c        |   6 +-
 41 files changed, 922 insertions(+), 641 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-cps.h

-- 
2.14.0

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 01/19] MIPS: CM: Rename mips_cm_base to mips_gcr_base
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

We currently have a mips_cm_base variable which holds the base address
of the Coherence Manager (CM) Global Configuration Registers (GCRs), and
accessor functions which use the GCR in their names. This works fine,
but gets in the way of sharing the code to generate the accessor
functions with other blocks (ie. CPC & GIC) because that code would then
need to separately handle the name of the base address variable & the
name used in the accessor functions.

In order to prepare for sharing the accessor generation code between CM,
CPC & GIC code this patch renames mips_cm_base to mips_gcr_base such
that the "gcr" portion is common to both the base address variable & the
accessor function names.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h |  6 +++---
 arch/mips/kernel/mips-cm.c      | 10 +++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index cfdbab015769..a13d721669e6 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 
 /* The base address of the CM GCR block */
-extern void __iomem *mips_cm_base;
+extern void __iomem *mips_gcr_base;
 
 /* The base address of the CM L2-only sync region */
 extern void __iomem *mips_cm_l2sync_base;
@@ -80,7 +80,7 @@ static inline int mips_cm_probe(void)
 static inline bool mips_cm_present(void)
 {
 #ifdef CONFIG_MIPS_CM
-	return mips_cm_base != NULL;
+	return mips_gcr_base != NULL;
 #else
 	return false;
 #endif
@@ -116,7 +116,7 @@ static inline bool mips_cm_has_l2sync(void)
 #define BUILD_CM_R_(name, off)					\
 static inline unsigned long __iomem *addr_gcr_##name(void)	\
 {								\
-	return (unsigned long __iomem *)(mips_cm_base + (off));	\
+	return (unsigned long __iomem *)(mips_gcr_base + (off));\
 }								\
 								\
 static inline u32 read32_gcr_##name(void)			\
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index cb0c57f860d4..caac4a523968 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -15,7 +15,7 @@
 #include <asm/mips-cm.h>
 #include <asm/mipsregs.h>
 
-void __iomem *mips_cm_base;
+void __iomem *mips_gcr_base;
 void __iomem *mips_cm_l2sync_base;
 int mips_cm_is64;
 
@@ -211,7 +211,7 @@ int mips_cm_probe(void)
 	 * No need to probe again if we have already been
 	 * here before.
 	 */
-	if (mips_cm_base)
+	if (mips_gcr_base)
 		return 0;
 
 	addr = mips_cm_phys_base();
@@ -219,8 +219,8 @@ int mips_cm_probe(void)
 	if (!addr)
 		return -ENODEV;
 
-	mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
-	if (!mips_cm_base)
+	mips_gcr_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
+	if (!mips_gcr_base)
 		return -ENXIO;
 
 	/* sanity check that we're looking at a CM */
@@ -228,7 +228,7 @@ int mips_cm_probe(void)
 	if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) {
 		pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
 		       (unsigned long)addr);
-		mips_cm_base = NULL;
+		mips_gcr_base = NULL;
 		return -ENODEV;
 	}
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 01/19] MIPS: CM: Rename mips_cm_base to mips_gcr_base
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

We currently have a mips_cm_base variable which holds the base address
of the Coherence Manager (CM) Global Configuration Registers (GCRs), and
accessor functions which use the GCR in their names. This works fine,
but gets in the way of sharing the code to generate the accessor
functions with other blocks (ie. CPC & GIC) because that code would then
need to separately handle the name of the base address variable & the
name used in the accessor functions.

In order to prepare for sharing the accessor generation code between CM,
CPC & GIC code this patch renames mips_cm_base to mips_gcr_base such
that the "gcr" portion is common to both the base address variable & the
accessor function names.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h |  6 +++---
 arch/mips/kernel/mips-cm.c      | 10 +++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index cfdbab015769..a13d721669e6 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 
 /* The base address of the CM GCR block */
-extern void __iomem *mips_cm_base;
+extern void __iomem *mips_gcr_base;
 
 /* The base address of the CM L2-only sync region */
 extern void __iomem *mips_cm_l2sync_base;
@@ -80,7 +80,7 @@ static inline int mips_cm_probe(void)
 static inline bool mips_cm_present(void)
 {
 #ifdef CONFIG_MIPS_CM
-	return mips_cm_base != NULL;
+	return mips_gcr_base != NULL;
 #else
 	return false;
 #endif
@@ -116,7 +116,7 @@ static inline bool mips_cm_has_l2sync(void)
 #define BUILD_CM_R_(name, off)					\
 static inline unsigned long __iomem *addr_gcr_##name(void)	\
 {								\
-	return (unsigned long __iomem *)(mips_cm_base + (off));	\
+	return (unsigned long __iomem *)(mips_gcr_base + (off));\
 }								\
 								\
 static inline u32 read32_gcr_##name(void)			\
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index cb0c57f860d4..caac4a523968 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -15,7 +15,7 @@
 #include <asm/mips-cm.h>
 #include <asm/mipsregs.h>
 
-void __iomem *mips_cm_base;
+void __iomem *mips_gcr_base;
 void __iomem *mips_cm_l2sync_base;
 int mips_cm_is64;
 
@@ -211,7 +211,7 @@ int mips_cm_probe(void)
 	 * No need to probe again if we have already been
 	 * here before.
 	 */
-	if (mips_cm_base)
+	if (mips_gcr_base)
 		return 0;
 
 	addr = mips_cm_phys_base();
@@ -219,8 +219,8 @@ int mips_cm_probe(void)
 	if (!addr)
 		return -ENODEV;
 
-	mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
-	if (!mips_cm_base)
+	mips_gcr_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE);
+	if (!mips_gcr_base)
 		return -ENXIO;
 
 	/* sanity check that we're looking at a CM */
@@ -228,7 +228,7 @@ int mips_cm_probe(void)
 	if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) {
 		pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
 		       (unsigned long)addr);
-		mips_cm_base = NULL;
+		mips_gcr_base = NULL;
 		return -ENODEV;
 	}
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 02/19] MIPS: CM: Specify register size when generating accessors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Some CM registers are always 32 bits, or at least only use bits in the
lower 32 bits of the register. For these registers it is wasteful for us
to generate accessors which bother to check mips_cm_is64 & perform 64
bit accesses.

This patch modifies the accessor generation to take into account the
size of the register, and for 32 bit registers we generate accessors
which only ever perform 32 bit accesses. For 64 bit registers we either
perform a 64 bit access or two 32 bit accesses, depending upon the value
of mips_cm_is64. Doing this saves us ~1.5KiB of code in a generic 64r6el
kernel, and perhaps more importantly simplifies various code paths.

This removes the read64_gcr_* accessors, so mips_cm_error_report() is
modified to stop using them & instead use the regular read_gcr_*
accessors which will return 64 bit values from the 64 bit registers.

The new accessor macros are placed in asm/mips-cps.h such that they can
be shared by CPC & GIC code in later patches.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h  | 154 ++++++++++++---------------------------
 arch/mips/include/asm/mips-cps.h |  87 ++++++++++++++++++++++
 arch/mips/kernel/mips-cm.c       |   9 +--
 3 files changed, 135 insertions(+), 115 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-cps.h

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index a13d721669e6..b01fcf4647d2 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/types.h>
+#include <asm/mips-cps.h>
 
 /* The base address of the CM GCR block */
 extern void __iomem *mips_gcr_base;
@@ -112,122 +113,57 @@ static inline bool mips_cm_has_l2sync(void)
 /* Size of the L2-only sync region */
 #define MIPS_CM_L2SYNC_SIZE	0x1000
 
-/* Macros to ease the creation of register access functions */
-#define BUILD_CM_R_(name, off)					\
-static inline unsigned long __iomem *addr_gcr_##name(void)	\
-{								\
-	return (unsigned long __iomem *)(mips_gcr_base + (off));\
-}								\
-								\
-static inline u32 read32_gcr_##name(void)			\
-{								\
-	return __raw_readl(addr_gcr_##name());			\
-}								\
-								\
-static inline u64 read64_gcr_##name(void)			\
-{								\
-	void __iomem *addr = addr_gcr_##name();			\
-	u64 ret;						\
-								\
-	if (mips_cm_is64) {					\
-		ret = __raw_readq(addr);			\
-	} else {						\
-		ret = __raw_readl(addr);			\
-		ret |= (u64)__raw_readl(addr + 0x4) << 32;	\
-	}							\
-								\
-	return ret;						\
-}								\
-								\
-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 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)					\
-	BUILD_CM_R_(name, off)					\
-	BUILD_CM__W(name, off)
+#define GCR_ACCESSOR_RO(sz, off, name)					\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name)
 
-#define BUILD_CM_Cx_R_(name, off)				\
-	BUILD_CM_R_(cl_##name, MIPS_CM_CLCB_OFS + (off))	\
-	BUILD_CM_R_(co_##name, MIPS_CM_COCB_OFS + (off))
+#define GCR_ACCESSOR_RW(sz, off, name)					\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name)
 
-#define BUILD_CM_Cx__W(name, off)				\
-	BUILD_CM__W(cl_##name, MIPS_CM_CLCB_OFS + (off))	\
-	BUILD_CM__W(co_##name, MIPS_CM_COCB_OFS + (off))
+#define GCR_CX_ACCESSOR_RO(sz, off, name)				\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
 
-#define BUILD_CM_Cx_RW(name, off)				\
-	BUILD_CM_Cx_R_(name, off)				\
-	BUILD_CM_Cx__W(name, off)
+#define GCR_CX_ACCESSOR_RW(sz, off, name)				\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
 
 /* GCB register accessor functions */
-BUILD_CM_R_(config,		MIPS_CM_GCB_OFS + 0x00)
-BUILD_CM_RW(base,		MIPS_CM_GCB_OFS + 0x08)
-BUILD_CM_RW(access,		MIPS_CM_GCB_OFS + 0x20)
-BUILD_CM_R_(rev,		MIPS_CM_GCB_OFS + 0x30)
-BUILD_CM_RW(err_control,	MIPS_CM_GCB_OFS + 0x38)
-BUILD_CM_RW(error_mask,		MIPS_CM_GCB_OFS + 0x40)
-BUILD_CM_RW(error_cause,	MIPS_CM_GCB_OFS + 0x48)
-BUILD_CM_RW(error_addr,		MIPS_CM_GCB_OFS + 0x50)
-BUILD_CM_RW(error_mult,		MIPS_CM_GCB_OFS + 0x58)
-BUILD_CM_RW(l2_only_sync_base,	MIPS_CM_GCB_OFS + 0x70)
-BUILD_CM_RW(gic_base,		MIPS_CM_GCB_OFS + 0x80)
-BUILD_CM_RW(cpc_base,		MIPS_CM_GCB_OFS + 0x88)
-BUILD_CM_RW(reg0_base,		MIPS_CM_GCB_OFS + 0x90)
-BUILD_CM_RW(reg0_mask,		MIPS_CM_GCB_OFS + 0x98)
-BUILD_CM_RW(reg1_base,		MIPS_CM_GCB_OFS + 0xa0)
-BUILD_CM_RW(reg1_mask,		MIPS_CM_GCB_OFS + 0xa8)
-BUILD_CM_RW(reg2_base,		MIPS_CM_GCB_OFS + 0xb0)
-BUILD_CM_RW(reg2_mask,		MIPS_CM_GCB_OFS + 0xb8)
-BUILD_CM_RW(reg3_base,		MIPS_CM_GCB_OFS + 0xc0)
-BUILD_CM_RW(reg3_mask,		MIPS_CM_GCB_OFS + 0xc8)
-BUILD_CM_R_(gic_status,		MIPS_CM_GCB_OFS + 0xd0)
-BUILD_CM_R_(cpc_status,		MIPS_CM_GCB_OFS + 0xf0)
-BUILD_CM_RW(l2_config,		MIPS_CM_GCB_OFS + 0x130)
-BUILD_CM_RW(sys_config2,	MIPS_CM_GCB_OFS + 0x150)
-BUILD_CM_RW(l2_pft_control,	MIPS_CM_GCB_OFS + 0x300)
-BUILD_CM_RW(l2_pft_control_b,	MIPS_CM_GCB_OFS + 0x308)
-BUILD_CM_RW(bev_base,		MIPS_CM_GCB_OFS + 0x680)
+GCR_ACCESSOR_RO(64, 0x000, config)
+GCR_ACCESSOR_RW(64, 0x008, base)
+GCR_ACCESSOR_RW(32, 0x020, access)
+GCR_ACCESSOR_RO(32, 0x030, rev)
+GCR_ACCESSOR_RW(32, 0x038, err_control)
+GCR_ACCESSOR_RW(64, 0x040, error_mask)
+GCR_ACCESSOR_RW(64, 0x048, error_cause)
+GCR_ACCESSOR_RW(64, 0x050, error_addr)
+GCR_ACCESSOR_RW(64, 0x058, error_mult)
+GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base)
+GCR_ACCESSOR_RW(64, 0x080, gic_base)
+GCR_ACCESSOR_RW(64, 0x088, cpc_base)
+GCR_ACCESSOR_RW(64, 0x090, reg0_base)
+GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
+GCR_ACCESSOR_RW(64, 0x0a0, reg1_base)
+GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
+GCR_ACCESSOR_RW(64, 0x0b0, reg2_base)
+GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
+GCR_ACCESSOR_RW(64, 0x0c0, reg3_base)
+GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask)
+GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
+GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
+GCR_ACCESSOR_RW(32, 0x130, l2_config)
+GCR_ACCESSOR_RO(32, 0x150, sys_config2)
+GCR_ACCESSOR_RW(32, 0x300, l2_pft_control)
+GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
+GCR_ACCESSOR_RW(64, 0x680, bev_base)
 
 /* Core Local & Core Other register accessor functions */
-BUILD_CM_Cx_RW(reset_release,	0x00)
-BUILD_CM_Cx_RW(coherence,	0x08)
-BUILD_CM_Cx_R_(config,		0x10)
-BUILD_CM_Cx_RW(other,		0x18)
-BUILD_CM_Cx_RW(reset_base,	0x20)
-BUILD_CM_Cx_R_(id,		0x28)
-BUILD_CM_Cx_RW(reset_ext_base,	0x30)
-BUILD_CM_Cx_R_(tcid_0_priority,	0x40)
-BUILD_CM_Cx_R_(tcid_1_priority,	0x48)
-BUILD_CM_Cx_R_(tcid_2_priority,	0x50)
-BUILD_CM_Cx_R_(tcid_3_priority,	0x58)
-BUILD_CM_Cx_R_(tcid_4_priority,	0x60)
-BUILD_CM_Cx_R_(tcid_5_priority,	0x68)
-BUILD_CM_Cx_R_(tcid_6_priority,	0x70)
-BUILD_CM_Cx_R_(tcid_7_priority,	0x78)
-BUILD_CM_Cx_R_(tcid_8_priority,	0x80)
+GCR_CX_ACCESSOR_RW(32, 0x000, reset_release)
+GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
+GCR_CX_ACCESSOR_RO(32, 0x010, config)
+GCR_CX_ACCESSOR_RW(32, 0x018, other)
+GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
+GCR_CX_ACCESSOR_RO(32, 0x028, id)
+GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
 
 /* GCR_CONFIG register fields */
 #define CM_GCR_CONFIG_NUMIOCU_SHF		8
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
new file mode 100644
index 000000000000..6ced7ba102b6
--- /dev/null
+++ b/arch/mips/include/asm/mips-cps.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+#define __MIPS_ASM_MIPS_CPS_H__
+
+#include <linux/io.h>
+#include <linux/types.h>
+
+extern unsigned long __cps_access_bad_size(void)
+	__compiletime_error("Bad size for CPS accessor");
+
+#define CPS_ACCESSOR_A(unit, off, name)					\
+static inline void *addr_##unit##_##name(void)				\
+{									\
+	return mips_##unit##_base + (off);				\
+}
+
+#define CPS_ACCESSOR_R(unit, sz, name)					\
+static inline uint##sz##_t read_##unit##_##name(void)			\
+{									\
+	uint64_t val64;							\
+									\
+	switch (sz) {							\
+	case 32:							\
+		return __raw_readl(addr_##unit##_##name());		\
+									\
+	case 64:							\
+		if (mips_cm_is64)					\
+			return __raw_readq(addr_##unit##_##name());	\
+									\
+		val64 = __raw_readl(addr_##unit##_##name() + 4);	\
+		val64 <<= 32;						\
+		val64 |= __raw_readl(addr_##unit##_##name());		\
+		return val64;						\
+									\
+	default:							\
+		return __cps_access_bad_size();				\
+	}								\
+}
+
+#define CPS_ACCESSOR_W(unit, sz, name)					\
+static inline void write_##unit##_##name(uint##sz##_t val)		\
+{									\
+	switch (sz) {							\
+	case 32:							\
+		__raw_writel(val, addr_##unit##_##name());		\
+		break;							\
+									\
+	case 64:							\
+		if (mips_cm_is64) {					\
+			__raw_writeq(val, addr_##unit##_##name());	\
+			break;						\
+		}							\
+									\
+		__raw_writel((uint64_t)val >> 32,			\
+			     addr_##unit##_##name() + 4);		\
+		__raw_writel(val, addr_##unit##_##name());		\
+		break;							\
+									\
+	default:							\
+		__cps_access_bad_size();				\
+		break;							\
+	}								\
+}
+
+#define CPS_ACCESSOR_RO(unit, sz, off, name)				\
+	CPS_ACCESSOR_A(unit, off, name)					\
+	CPS_ACCESSOR_R(unit, sz, name)
+
+#define CPS_ACCESSOR_WO(unit, sz, off, name)				\
+	CPS_ACCESSOR_A(unit, off, name)					\
+	CPS_ACCESSOR_W(unit, sz, name)
+
+#define CPS_ACCESSOR_RW(unit, sz, off, name)				\
+	CPS_ACCESSOR_A(unit, off, name)					\
+	CPS_ACCESSOR_R(unit, sz, name)					\
+	CPS_ACCESSOR_W(unit, sz, name)
+
+#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index caac4a523968..8b6b4976fb2f 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -332,11 +332,11 @@ void mips_cm_error_report(void)
 		return;
 
 	revision = mips_cm_revision();
+	cm_error = read_gcr_error_cause();
+	cm_addr = read_gcr_error_addr();
+	cm_other = read_gcr_error_mult();
 
 	if (revision < CM_REV_CM3) { /* CM2 */
-		cm_error = read_gcr_error_cause();
-		cm_addr = read_gcr_error_addr();
-		cm_other = read_gcr_error_mult();
 		cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
 		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
 
@@ -380,9 +380,6 @@ void mips_cm_error_report(void)
 		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
 		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
 
-		cm_error = read64_gcr_error_cause();
-		cm_addr = read64_gcr_error_addr();
-		cm_other = read64_gcr_error_mult();
 		cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
 		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 02/19] MIPS: CM: Specify register size when generating accessors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Some CM registers are always 32 bits, or at least only use bits in the
lower 32 bits of the register. For these registers it is wasteful for us
to generate accessors which bother to check mips_cm_is64 & perform 64
bit accesses.

This patch modifies the accessor generation to take into account the
size of the register, and for 32 bit registers we generate accessors
which only ever perform 32 bit accesses. For 64 bit registers we either
perform a 64 bit access or two 32 bit accesses, depending upon the value
of mips_cm_is64. Doing this saves us ~1.5KiB of code in a generic 64r6el
kernel, and perhaps more importantly simplifies various code paths.

This removes the read64_gcr_* accessors, so mips_cm_error_report() is
modified to stop using them & instead use the regular read_gcr_*
accessors which will return 64 bit values from the 64 bit registers.

The new accessor macros are placed in asm/mips-cps.h such that they can
be shared by CPC & GIC code in later patches.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h  | 154 ++++++++++++---------------------------
 arch/mips/include/asm/mips-cps.h |  87 ++++++++++++++++++++++
 arch/mips/kernel/mips-cm.c       |   9 +--
 3 files changed, 135 insertions(+), 115 deletions(-)
 create mode 100644 arch/mips/include/asm/mips-cps.h

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index a13d721669e6..b01fcf4647d2 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -15,6 +15,7 @@
 #include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/types.h>
+#include <asm/mips-cps.h>
 
 /* The base address of the CM GCR block */
 extern void __iomem *mips_gcr_base;
@@ -112,122 +113,57 @@ static inline bool mips_cm_has_l2sync(void)
 /* Size of the L2-only sync region */
 #define MIPS_CM_L2SYNC_SIZE	0x1000
 
-/* Macros to ease the creation of register access functions */
-#define BUILD_CM_R_(name, off)					\
-static inline unsigned long __iomem *addr_gcr_##name(void)	\
-{								\
-	return (unsigned long __iomem *)(mips_gcr_base + (off));\
-}								\
-								\
-static inline u32 read32_gcr_##name(void)			\
-{								\
-	return __raw_readl(addr_gcr_##name());			\
-}								\
-								\
-static inline u64 read64_gcr_##name(void)			\
-{								\
-	void __iomem *addr = addr_gcr_##name();			\
-	u64 ret;						\
-								\
-	if (mips_cm_is64) {					\
-		ret = __raw_readq(addr);			\
-	} else {						\
-		ret = __raw_readl(addr);			\
-		ret |= (u64)__raw_readl(addr + 0x4) << 32;	\
-	}							\
-								\
-	return ret;						\
-}								\
-								\
-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 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)					\
-	BUILD_CM_R_(name, off)					\
-	BUILD_CM__W(name, off)
+#define GCR_ACCESSOR_RO(sz, off, name)					\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name)
 
-#define BUILD_CM_Cx_R_(name, off)				\
-	BUILD_CM_R_(cl_##name, MIPS_CM_CLCB_OFS + (off))	\
-	BUILD_CM_R_(co_##name, MIPS_CM_COCB_OFS + (off))
+#define GCR_ACCESSOR_RW(sz, off, name)					\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name)
 
-#define BUILD_CM_Cx__W(name, off)				\
-	BUILD_CM__W(cl_##name, MIPS_CM_CLCB_OFS + (off))	\
-	BUILD_CM__W(co_##name, MIPS_CM_COCB_OFS + (off))
+#define GCR_CX_ACCESSOR_RO(sz, off, name)				\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
 
-#define BUILD_CM_Cx_RW(name, off)				\
-	BUILD_CM_Cx_R_(name, off)				\
-	BUILD_CM_Cx__W(name, off)
+#define GCR_CX_ACCESSOR_RW(sz, off, name)				\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
 
 /* GCB register accessor functions */
-BUILD_CM_R_(config,		MIPS_CM_GCB_OFS + 0x00)
-BUILD_CM_RW(base,		MIPS_CM_GCB_OFS + 0x08)
-BUILD_CM_RW(access,		MIPS_CM_GCB_OFS + 0x20)
-BUILD_CM_R_(rev,		MIPS_CM_GCB_OFS + 0x30)
-BUILD_CM_RW(err_control,	MIPS_CM_GCB_OFS + 0x38)
-BUILD_CM_RW(error_mask,		MIPS_CM_GCB_OFS + 0x40)
-BUILD_CM_RW(error_cause,	MIPS_CM_GCB_OFS + 0x48)
-BUILD_CM_RW(error_addr,		MIPS_CM_GCB_OFS + 0x50)
-BUILD_CM_RW(error_mult,		MIPS_CM_GCB_OFS + 0x58)
-BUILD_CM_RW(l2_only_sync_base,	MIPS_CM_GCB_OFS + 0x70)
-BUILD_CM_RW(gic_base,		MIPS_CM_GCB_OFS + 0x80)
-BUILD_CM_RW(cpc_base,		MIPS_CM_GCB_OFS + 0x88)
-BUILD_CM_RW(reg0_base,		MIPS_CM_GCB_OFS + 0x90)
-BUILD_CM_RW(reg0_mask,		MIPS_CM_GCB_OFS + 0x98)
-BUILD_CM_RW(reg1_base,		MIPS_CM_GCB_OFS + 0xa0)
-BUILD_CM_RW(reg1_mask,		MIPS_CM_GCB_OFS + 0xa8)
-BUILD_CM_RW(reg2_base,		MIPS_CM_GCB_OFS + 0xb0)
-BUILD_CM_RW(reg2_mask,		MIPS_CM_GCB_OFS + 0xb8)
-BUILD_CM_RW(reg3_base,		MIPS_CM_GCB_OFS + 0xc0)
-BUILD_CM_RW(reg3_mask,		MIPS_CM_GCB_OFS + 0xc8)
-BUILD_CM_R_(gic_status,		MIPS_CM_GCB_OFS + 0xd0)
-BUILD_CM_R_(cpc_status,		MIPS_CM_GCB_OFS + 0xf0)
-BUILD_CM_RW(l2_config,		MIPS_CM_GCB_OFS + 0x130)
-BUILD_CM_RW(sys_config2,	MIPS_CM_GCB_OFS + 0x150)
-BUILD_CM_RW(l2_pft_control,	MIPS_CM_GCB_OFS + 0x300)
-BUILD_CM_RW(l2_pft_control_b,	MIPS_CM_GCB_OFS + 0x308)
-BUILD_CM_RW(bev_base,		MIPS_CM_GCB_OFS + 0x680)
+GCR_ACCESSOR_RO(64, 0x000, config)
+GCR_ACCESSOR_RW(64, 0x008, base)
+GCR_ACCESSOR_RW(32, 0x020, access)
+GCR_ACCESSOR_RO(32, 0x030, rev)
+GCR_ACCESSOR_RW(32, 0x038, err_control)
+GCR_ACCESSOR_RW(64, 0x040, error_mask)
+GCR_ACCESSOR_RW(64, 0x048, error_cause)
+GCR_ACCESSOR_RW(64, 0x050, error_addr)
+GCR_ACCESSOR_RW(64, 0x058, error_mult)
+GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base)
+GCR_ACCESSOR_RW(64, 0x080, gic_base)
+GCR_ACCESSOR_RW(64, 0x088, cpc_base)
+GCR_ACCESSOR_RW(64, 0x090, reg0_base)
+GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
+GCR_ACCESSOR_RW(64, 0x0a0, reg1_base)
+GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
+GCR_ACCESSOR_RW(64, 0x0b0, reg2_base)
+GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
+GCR_ACCESSOR_RW(64, 0x0c0, reg3_base)
+GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask)
+GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
+GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
+GCR_ACCESSOR_RW(32, 0x130, l2_config)
+GCR_ACCESSOR_RO(32, 0x150, sys_config2)
+GCR_ACCESSOR_RW(32, 0x300, l2_pft_control)
+GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
+GCR_ACCESSOR_RW(64, 0x680, bev_base)
 
 /* Core Local & Core Other register accessor functions */
-BUILD_CM_Cx_RW(reset_release,	0x00)
-BUILD_CM_Cx_RW(coherence,	0x08)
-BUILD_CM_Cx_R_(config,		0x10)
-BUILD_CM_Cx_RW(other,		0x18)
-BUILD_CM_Cx_RW(reset_base,	0x20)
-BUILD_CM_Cx_R_(id,		0x28)
-BUILD_CM_Cx_RW(reset_ext_base,	0x30)
-BUILD_CM_Cx_R_(tcid_0_priority,	0x40)
-BUILD_CM_Cx_R_(tcid_1_priority,	0x48)
-BUILD_CM_Cx_R_(tcid_2_priority,	0x50)
-BUILD_CM_Cx_R_(tcid_3_priority,	0x58)
-BUILD_CM_Cx_R_(tcid_4_priority,	0x60)
-BUILD_CM_Cx_R_(tcid_5_priority,	0x68)
-BUILD_CM_Cx_R_(tcid_6_priority,	0x70)
-BUILD_CM_Cx_R_(tcid_7_priority,	0x78)
-BUILD_CM_Cx_R_(tcid_8_priority,	0x80)
+GCR_CX_ACCESSOR_RW(32, 0x000, reset_release)
+GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
+GCR_CX_ACCESSOR_RO(32, 0x010, config)
+GCR_CX_ACCESSOR_RW(32, 0x018, other)
+GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
+GCR_CX_ACCESSOR_RO(32, 0x028, id)
+GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
 
 /* GCR_CONFIG register fields */
 #define CM_GCR_CONFIG_NUMIOCU_SHF		8
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
new file mode 100644
index 000000000000..6ced7ba102b6
--- /dev/null
+++ b/arch/mips/include/asm/mips-cps.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+#define __MIPS_ASM_MIPS_CPS_H__
+
+#include <linux/io.h>
+#include <linux/types.h>
+
+extern unsigned long __cps_access_bad_size(void)
+	__compiletime_error("Bad size for CPS accessor");
+
+#define CPS_ACCESSOR_A(unit, off, name)					\
+static inline void *addr_##unit##_##name(void)				\
+{									\
+	return mips_##unit##_base + (off);				\
+}
+
+#define CPS_ACCESSOR_R(unit, sz, name)					\
+static inline uint##sz##_t read_##unit##_##name(void)			\
+{									\
+	uint64_t val64;							\
+									\
+	switch (sz) {							\
+	case 32:							\
+		return __raw_readl(addr_##unit##_##name());		\
+									\
+	case 64:							\
+		if (mips_cm_is64)					\
+			return __raw_readq(addr_##unit##_##name());	\
+									\
+		val64 = __raw_readl(addr_##unit##_##name() + 4);	\
+		val64 <<= 32;						\
+		val64 |= __raw_readl(addr_##unit##_##name());		\
+		return val64;						\
+									\
+	default:							\
+		return __cps_access_bad_size();				\
+	}								\
+}
+
+#define CPS_ACCESSOR_W(unit, sz, name)					\
+static inline void write_##unit##_##name(uint##sz##_t val)		\
+{									\
+	switch (sz) {							\
+	case 32:							\
+		__raw_writel(val, addr_##unit##_##name());		\
+		break;							\
+									\
+	case 64:							\
+		if (mips_cm_is64) {					\
+			__raw_writeq(val, addr_##unit##_##name());	\
+			break;						\
+		}							\
+									\
+		__raw_writel((uint64_t)val >> 32,			\
+			     addr_##unit##_##name() + 4);		\
+		__raw_writel(val, addr_##unit##_##name());		\
+		break;							\
+									\
+	default:							\
+		__cps_access_bad_size();				\
+		break;							\
+	}								\
+}
+
+#define CPS_ACCESSOR_RO(unit, sz, off, name)				\
+	CPS_ACCESSOR_A(unit, off, name)					\
+	CPS_ACCESSOR_R(unit, sz, name)
+
+#define CPS_ACCESSOR_WO(unit, sz, off, name)				\
+	CPS_ACCESSOR_A(unit, off, name)					\
+	CPS_ACCESSOR_W(unit, sz, name)
+
+#define CPS_ACCESSOR_RW(unit, sz, off, name)				\
+	CPS_ACCESSOR_A(unit, off, name)					\
+	CPS_ACCESSOR_R(unit, sz, name)					\
+	CPS_ACCESSOR_W(unit, sz, name)
+
+#endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index caac4a523968..8b6b4976fb2f 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -332,11 +332,11 @@ void mips_cm_error_report(void)
 		return;
 
 	revision = mips_cm_revision();
+	cm_error = read_gcr_error_cause();
+	cm_addr = read_gcr_error_addr();
+	cm_other = read_gcr_error_mult();
 
 	if (revision < CM_REV_CM3) { /* CM2 */
-		cm_error = read_gcr_error_cause();
-		cm_addr = read_gcr_error_addr();
-		cm_other = read_gcr_error_mult();
 		cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
 		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
 
@@ -380,9 +380,6 @@ void mips_cm_error_report(void)
 		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
 		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
 
-		cm_error = read64_gcr_error_cause();
-		cm_addr = read64_gcr_error_addr();
-		cm_other = read64_gcr_error_mult();
 		cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
 		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 03/19] MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

There's no reason for us not to use BIT() & GENMASK() in asm/mips-cm.h
when declaring macros corresponding to register fields. This patch
modifies our definitions to do so.

The *_SHF definitions are removed entirely - they duplicate information
found in the masks, are infrequently used & can be replaced with use of
__ffs() where needed.

The *_MSK definitions then lose their _MSK suffix which is now somewhat
redundant, and users are modified to match.

The field definitions are moved to follow the appropriate register's
accessor functions, which helps to keep the field definitions in order &
to find the appropriate fields for a given register. Whilst here a
comment is added describing each register & including its name, which is
helpful both for linking the register back to hardware documentation &
for grepping purposes.

This also cleans up a couple of issues that became obvious as a result
of making the changes described above:

  - We previously had definitions for GCR_Cx_RESET_EXT_BASE & a phony
    copy of that named GCR_RESET_EXT_BASE - a register which does not
    exist. The bad definitions were added by commit 497e803ebf98 ("MIPS:
    smp-cps: Ensure secondary cores start with EVA disabled") and made
    use of from boot_core(), which is now modified to use the
    GCR_Cx_RESET_EXT_BASE definitions.

  - We had a typo in CM_GCR_ERROR_CAUSE_ERRINGO_MSK - we now correctly
    define this as inFo rather than inGo.

Now that we don't duplicate field information between _SHF & _MSK
definitions, and keep the fields next to the register accessors, it will
be much easier to spot & prevent any similar oddities being introduced
in the future.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h    | 311 ++++++++++++++++---------------------
 arch/mips/kernel/mips-cm.c         |  48 +++---
 arch/mips/kernel/mips-cpc.c        |   8 +-
 arch/mips/kernel/pm-cps.c          |   4 +-
 arch/mips/kernel/smp-cps.c         |  10 +-
 arch/mips/kernel/traps.c           |   8 +-
 arch/mips/mm/sc-mips.c             |  36 ++---
 arch/mips/mti-malta/malta-dtshim.c |   2 +-
 drivers/irqchip/irq-mips-gic.c     |   4 +-
 9 files changed, 190 insertions(+), 241 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index b01fcf4647d2..4857d4ae97b7 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -127,212 +127,161 @@ static inline bool mips_cm_has_l2sync(void)
 	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
 	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
 
-/* GCB register accessor functions */
+/* GCR_CONFIG - Information about the system */
 GCR_ACCESSOR_RO(64, 0x000, config)
+#define CM_GCR_CONFIG_NUMIOCU			GENMASK(15, 8)
+#define CM_GCR_CONFIG_PCORES			GENMASK(7, 0)
+
+/* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */
 GCR_ACCESSOR_RW(64, 0x008, base)
+#define CM_GCR_BASE_GCRBASE			GENMASK_ULL(47, 15)
+#define CM_GCR_BASE_CMDEFTGT			GENMASK(1, 0)
+#define  CM_GCR_BASE_CMDEFTGT_DISABLED		0
+#define  CM_GCR_BASE_CMDEFTGT_MEM		1
+#define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
+#define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
+
+/* GCR_ACCESS - Controls core/IOCU access to GCRs */
 GCR_ACCESSOR_RW(32, 0x020, access)
+#define CM_GCR_ACCESS_ACCESSEN			GENMASK(7, 0)
+
+/* GCR_REV - Indicates the Coherence Manager revision */
 GCR_ACCESSOR_RO(32, 0x030, rev)
+#define CM_GCR_REV_MAJOR			GENMASK(15, 8)
+#define CM_GCR_REV_MINOR			GENMASK(7, 0)
+
+#define CM_ENCODE_REV(major, minor) \
+		(((major) << __ffs(CM_GCR_REV_MAJOR)) | \
+		 ((minor) << __ffs(CM_GCR_REV_MINOR)))
+
+#define CM_REV_CM2				CM_ENCODE_REV(6, 0)
+#define CM_REV_CM2_5				CM_ENCODE_REV(7, 0)
+#define CM_REV_CM3				CM_ENCODE_REV(8, 0)
+
+/* GCR_ERR_CONTROL - Control error checking logic */
 GCR_ACCESSOR_RW(32, 0x038, err_control)
+#define CM_GCR_ERR_CONTROL_L2_ECC_EN		BIT(1)
+#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT	BIT(0)
+
+/* GCR_ERR_MASK - Control which errors are reported as interrupts */
 GCR_ACCESSOR_RW(64, 0x040, error_mask)
+
+/* GCR_ERR_CAUSE - Indicates the type of error that occurred */
 GCR_ACCESSOR_RW(64, 0x048, error_cause)
+#define CM_GCR_ERROR_CAUSE_ERRTYPE		GENMASK(31, 27)
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE		GENMASK_ULL(63, 58)
+#define CM_GCR_ERROR_CAUSE_ERRINFO		GENMASK(26, 0)
+
+/* GCR_ERR_ADDR - Indicates the address associated with an error */
 GCR_ACCESSOR_RW(64, 0x050, error_addr)
+
+/* GCR_ERR_MULT - Indicates when multiple errors have occurred */
 GCR_ACCESSOR_RW(64, 0x058, error_mult)
+#define CM_GCR_ERROR_MULT_ERR2ND		GENMASK(4, 0)
+
+/* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */
 GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base)
+#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE	GENMASK(31, 12)
+#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN		BIT(0)
+
+/* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */
 GCR_ACCESSOR_RW(64, 0x080, gic_base)
+#define CM_GCR_GIC_BASE_GICBASE			GENMASK(31, 17)
+#define CM_GCR_GIC_BASE_GICEN			BIT(0)
+
+/* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */
 GCR_ACCESSOR_RW(64, 0x088, cpc_base)
+#define CM_GCR_CPC_BASE_CPCBASE			GENMASK(31, 15)
+#define CM_GCR_CPC_BASE_CPCEN			BIT(0)
+
+/* GCR_REGn_BASE - Base addresses of CM address regions */
 GCR_ACCESSOR_RW(64, 0x090, reg0_base)
-GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
 GCR_ACCESSOR_RW(64, 0x0a0, reg1_base)
-GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
 GCR_ACCESSOR_RW(64, 0x0b0, reg2_base)
-GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
 GCR_ACCESSOR_RW(64, 0x0c0, reg3_base)
+#define CM_GCR_REGn_BASE_BASEADDR		GENMASK(31, 16)
+
+/* GCR_REGn_MASK - Size & destination of CM address regions */
+GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
+GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
+GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
 GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask)
+#define CM_GCR_REGn_MASK_ADDRMASK		GENMASK(31, 16)
+#define CM_GCR_REGn_MASK_CCAOVR			GENMASK(7, 5)
+#define CM_GCR_REGn_MASK_CCAOVREN		BIT(4)
+#define CM_GCR_REGn_MASK_DROPL2			BIT(2)
+#define CM_GCR_REGn_MASK_CMTGT			GENMASK(1, 0)
+#define  CM_GCR_REGn_MASK_CMTGT_DISABLED	0x0
+#define  CM_GCR_REGn_MASK_CMTGT_MEM		0x1
+#define  CM_GCR_REGn_MASK_CMTGT_IOCU0		0x2
+#define  CM_GCR_REGn_MASK_CMTGT_IOCU1		0x3
+
+/* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */
 GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
+#define CM_GCR_GIC_STATUS_EX			BIT(0)
+
+/* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */
 GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
+#define CM_GCR_CPC_STATUS_EX			BIT(0)
+
+/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
 GCR_ACCESSOR_RW(32, 0x130, l2_config)
+#define CM_GCR_L2_CONFIG_BYPASS			BIT(20)
+#define CM_GCR_L2_CONFIG_SET_SIZE		GENMASK(15, 12)
+#define CM_GCR_L2_CONFIG_LINE_SIZE		GENMASK(11, 8)
+#define CM_GCR_L2_CONFIG_ASSOC			GENMASK(7, 0)
+
+/* GCR_SYS_CONFIG2 - Further information about the system */
 GCR_ACCESSOR_RO(32, 0x150, sys_config2)
+#define CM_GCR_SYS_CONFIG2_MAXVPW		GENMASK(3, 0)
+
+/* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */
 GCR_ACCESSOR_RW(32, 0x300, l2_pft_control)
+#define CM_GCR_L2_PFT_CONTROL_PAGEMASK		GENMASK(31, 12)
+#define CM_GCR_L2_PFT_CONTROL_PFTEN		BIT(8)
+#define CM_GCR_L2_PFT_CONTROL_NPFT		GENMASK(7, 0)
+
+/* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */
 GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
+#define CM_GCR_L2_PFT_CONTROL_B_CEN		BIT(8)
+#define CM_GCR_L2_PFT_CONTROL_B_PORTID		GENMASK(7, 0)
+
+/* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */
 GCR_ACCESSOR_RW(64, 0x680, bev_base)
 
-/* Core Local & Core Other register accessor functions */
+/* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */
 GCR_CX_ACCESSOR_RW(32, 0x000, reset_release)
-GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
-GCR_CX_ACCESSOR_RO(32, 0x010, config)
-GCR_CX_ACCESSOR_RW(32, 0x018, other)
-GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
-GCR_CX_ACCESSOR_RO(32, 0x028, id)
-GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
-
-/* GCR_CONFIG register fields */
-#define CM_GCR_CONFIG_NUMIOCU_SHF		8
-#define CM_GCR_CONFIG_NUMIOCU_MSK		(_ULCAST_(0xf) << 8)
-#define CM_GCR_CONFIG_PCORES_SHF		0
-#define CM_GCR_CONFIG_PCORES_MSK		(_ULCAST_(0xff) << 0)
-
-/* GCR_BASE register fields */
-#define CM_GCR_BASE_GCRBASE_SHF			15
-#define CM_GCR_BASE_GCRBASE_MSK			(_ULCAST_(0x1ffff) << 15)
-#define CM_GCR_BASE_CMDEFTGT_SHF		0
-#define CM_GCR_BASE_CMDEFTGT_MSK		(_ULCAST_(0x3) << 0)
-#define  CM_GCR_BASE_CMDEFTGT_DISABLED		0
-#define  CM_GCR_BASE_CMDEFTGT_MEM		1
-#define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
-#define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
 
-/* GCR_RESET_EXT_BASE register fields */
-#define CM_GCR_RESET_EXT_BASE_EVARESET		BIT(31)
-#define CM_GCR_RESET_EXT_BASE_UEB		BIT(30)
+/* GCR_Cx_COHERENCE - Controls core coherence */
+GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
+#define CM_GCR_Cx_COHERENCE_COHDOMAINEN		GENMASK(7, 0)
+#define CM3_GCR_Cx_COHERENCE_COHEN		BIT(0)
 
-/* GCR_ACCESS register fields */
-#define CM_GCR_ACCESS_ACCESSEN_SHF		0
-#define CM_GCR_ACCESS_ACCESSEN_MSK		(_ULCAST_(0xff) << 0)
+/* GCR_Cx_CONFIG - Information about a core's configuration */
+GCR_CX_ACCESSOR_RO(32, 0x010, config)
+#define CM_GCR_Cx_CONFIG_IOCUTYPE		GENMASK(11, 10)
+#define CM_GCR_Cx_CONFIG_PVPE			GENMASK(9, 0)
 
-/* GCR_REV register fields */
-#define CM_GCR_REV_MAJOR_SHF			8
-#define CM_GCR_REV_MAJOR_MSK			(_ULCAST_(0xff) << 8)
-#define CM_GCR_REV_MINOR_SHF			0
-#define CM_GCR_REV_MINOR_MSK			(_ULCAST_(0xff) << 0)
+/* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */
+GCR_CX_ACCESSOR_RW(32, 0x018, other)
+#define CM_GCR_Cx_OTHER_CORENUM			GENMASK(31, 16)
+#define CM3_GCR_Cx_OTHER_CORE			GENMASK(13, 8)
+#define CM3_GCR_Cx_OTHER_VP			GENMASK(2, 0)
 
-#define CM_ENCODE_REV(major, minor) \
-		(((major) << CM_GCR_REV_MAJOR_SHF) | \
-		 ((minor) << CM_GCR_REV_MINOR_SHF))
+/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
+GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
+#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE		GENMASK(31, 12)
 
-#define CM_REV_CM2				CM_ENCODE_REV(6, 0)
-#define CM_REV_CM2_5				CM_ENCODE_REV(7, 0)
-#define CM_REV_CM3				CM_ENCODE_REV(8, 0)
+/* GCR_Cx_ID - Identify the current core */
+GCR_CX_ACCESSOR_RO(32, 0x028, id)
 
-/* GCR_ERR_CONTROL register fields */
-#define CM_GCR_ERR_CONTROL_L2_ECC_EN_SHF	1
-#define CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK	(_ULCAST_(0x1) << 1)
-#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_SHF	0
-#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK	(_ULCAST_(0x1) << 0)
-
-/* GCR_ERROR_CAUSE register fields */
-#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF		27
-#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK		(_ULCAST_(0x1f) << 27)
-#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF		58
-#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK		GENMASK_ULL(63, 58)
-#define CM_GCR_ERROR_CAUSE_ERRINFO_SHF		0
-#define CM_GCR_ERROR_CAUSE_ERRINGO_MSK		(_ULCAST_(0x7ffffff) << 0)
-
-/* GCR_ERROR_MULT register fields */
-#define CM_GCR_ERROR_MULT_ERR2ND_SHF		0
-#define CM_GCR_ERROR_MULT_ERR2ND_MSK		(_ULCAST_(0x1f) << 0)
-
-/* GCR_L2_ONLY_SYNC_BASE register fields */
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_SHF	12
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK	(_ULCAST_(0xfffff) << 12)
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_SHF	0
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK	(_ULCAST_(0x1) << 0)
-
-/* GCR_GIC_BASE register fields */
-#define CM_GCR_GIC_BASE_GICBASE_SHF		17
-#define CM_GCR_GIC_BASE_GICBASE_MSK		(_ULCAST_(0x7fff) << 17)
-#define CM_GCR_GIC_BASE_GICEN_SHF		0
-#define CM_GCR_GIC_BASE_GICEN_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_CPC_BASE register fields */
-#define CM_GCR_CPC_BASE_CPCBASE_SHF		15
-#define CM_GCR_CPC_BASE_CPCBASE_MSK		(_ULCAST_(0x1ffff) << 15)
-#define CM_GCR_CPC_BASE_CPCEN_SHF		0
-#define CM_GCR_CPC_BASE_CPCEN_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_GIC_STATUS register fields */
-#define CM_GCR_GIC_STATUS_GICEX_SHF		0
-#define CM_GCR_GIC_STATUS_GICEX_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_REGn_BASE register fields */
-#define CM_GCR_REGn_BASE_BASEADDR_SHF		16
-#define CM_GCR_REGn_BASE_BASEADDR_MSK		(_ULCAST_(0xffff) << 16)
-
-/* GCR_REGn_MASK register fields */
-#define CM_GCR_REGn_MASK_ADDRMASK_SHF		16
-#define CM_GCR_REGn_MASK_ADDRMASK_MSK		(_ULCAST_(0xffff) << 16)
-#define CM_GCR_REGn_MASK_CCAOVR_SHF		5
-#define CM_GCR_REGn_MASK_CCAOVR_MSK		(_ULCAST_(0x3) << 5)
-#define CM_GCR_REGn_MASK_CCAOVREN_SHF		4
-#define CM_GCR_REGn_MASK_CCAOVREN_MSK		(_ULCAST_(0x1) << 4)
-#define CM_GCR_REGn_MASK_DROPL2_SHF		2
-#define CM_GCR_REGn_MASK_DROPL2_MSK		(_ULCAST_(0x1) << 2)
-#define CM_GCR_REGn_MASK_CMTGT_SHF		0
-#define CM_GCR_REGn_MASK_CMTGT_MSK		(_ULCAST_(0x3) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_DISABLED	(_ULCAST_(0x0) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_MEM		(_ULCAST_(0x1) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_IOCU0		(_ULCAST_(0x2) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_IOCU1		(_ULCAST_(0x3) << 0)
-
-/* GCR_GIC_STATUS register fields */
-#define CM_GCR_GIC_STATUS_EX_SHF		0
-#define CM_GCR_GIC_STATUS_EX_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_CPC_STATUS register fields */
-#define CM_GCR_CPC_STATUS_EX_SHF		0
-#define CM_GCR_CPC_STATUS_EX_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_L2_CONFIG register fields */
-#define CM_GCR_L2_CONFIG_BYPASS_SHF		20
-#define CM_GCR_L2_CONFIG_BYPASS_MSK		(_ULCAST_(0x1) << 20)
-#define CM_GCR_L2_CONFIG_SET_SIZE_SHF		12
-#define CM_GCR_L2_CONFIG_SET_SIZE_MSK		(_ULCAST_(0xf) << 12)
-#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF		8
-#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK		(_ULCAST_(0xf) << 8)
-#define CM_GCR_L2_CONFIG_ASSOC_SHF		0
-#define CM_GCR_L2_CONFIG_ASSOC_MSK		(_ULCAST_(0xff) << 0)
-
-/* GCR_SYS_CONFIG2 register fields */
-#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF		0
-#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK		(_ULCAST_(0xf) << 0)
-
-/* GCR_L2_PFT_CONTROL register fields */
-#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF	12
-#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK	(_ULCAST_(0xfffff) << 12)
-#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF		8
-#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK		(_ULCAST_(0x1) << 8)
-#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF		0
-#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK		(_ULCAST_(0xff) << 0)
-
-/* GCR_L2_PFT_CONTROL_B register fields */
-#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF		8
-#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK		(_ULCAST_(0x1) << 8)
-#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF	0
-#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK	(_ULCAST_(0xff) << 0)
-
-/* GCR_Cx_COHERENCE register fields */
-#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF	0
-#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK	(_ULCAST_(0xff) << 0)
-#define CM3_GCR_Cx_COHERENCE_COHEN_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_Cx_CONFIG register fields */
-#define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF		10
-#define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK		(_ULCAST_(0x3) << 10)
-#define CM_GCR_Cx_CONFIG_PVPE_SHF		0
-#define CM_GCR_Cx_CONFIG_PVPE_MSK		(_ULCAST_(0x3ff) << 0)
-
-/* GCR_Cx_OTHER register fields */
-#define CM_GCR_Cx_OTHER_CORENUM_SHF		16
-#define CM_GCR_Cx_OTHER_CORENUM_MSK		(_ULCAST_(0xffff) << 16)
-#define CM3_GCR_Cx_OTHER_CORE_SHF		8
-#define CM3_GCR_Cx_OTHER_CORE_MSK		(_ULCAST_(0x3f) << 8)
-#define CM3_GCR_Cx_OTHER_VP_SHF			0
-#define CM3_GCR_Cx_OTHER_VP_MSK			(_ULCAST_(0x7) << 0)
-
-/* GCR_Cx_RESET_BASE register fields */
-#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF	12
-#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_MSK	(_ULCAST_(0xfffff) << 12)
-
-/* GCR_Cx_RESET_EXT_BASE register fields */
-#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_SHF	31
-#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_MSK	(_ULCAST_(0x1) << 31)
-#define CM_GCR_Cx_RESET_EXT_BASE_UEB_SHF	30
-#define CM_GCR_Cx_RESET_EXT_BASE_UEB_MSK	(_ULCAST_(0x1) << 30)
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_SHF	20
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_MSK	(_ULCAST_(0xff) << 20)
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_SHF	1
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_MSK	(_ULCAST_(0x7f) << 1)
-#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_SHF	0
-#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_MSK	(_ULCAST_(0x1) << 0)
+/* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */
+GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
+#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET	BIT(31)
+#define CM_GCR_Cx_RESET_EXT_BASE_UEB		BIT(30)
+#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK	GENMASK(27, 20)
+#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA	GENMASK(7, 1)
+#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT	BIT(0)
 
 /**
  * mips_cm_numcores - return the number of cores present in the system
@@ -345,8 +294,8 @@ static inline unsigned mips_cm_numcores(void)
 	if (!mips_cm_present())
 		return 0;
 
-	return ((read_gcr_config() & CM_GCR_CONFIG_PCORES_MSK)
-		>> CM_GCR_CONFIG_PCORES_SHF) + 1;
+	return ((read_gcr_config() & CM_GCR_CONFIG_PCORES)
+		>> __ffs(CM_GCR_CONFIG_PCORES)) + 1;
 }
 
 /**
@@ -360,8 +309,8 @@ static inline unsigned mips_cm_numiocu(void)
 	if (!mips_cm_present())
 		return 0;
 
-	return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU_MSK)
-		>> CM_GCR_CONFIG_NUMIOCU_SHF;
+	return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU)
+		>> __ffs(CM_GCR_CONFIG_NUMIOCU);
 }
 
 /**
@@ -405,7 +354,7 @@ static inline unsigned int mips_cm_max_vp_width(void)
 	uint32_t cfg;
 
 	if (mips_cm_revision() >= CM_REV_CM3)
-		return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK;
+		return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW;
 
 	if (mips_cm_present()) {
 		/*
@@ -413,8 +362,8 @@ static inline unsigned int mips_cm_max_vp_width(void)
 		 * number of VP(E)s, and if that ever changes then this will
 		 * need revisiting.
 		 */
-		cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
-		return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
+		cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE;
+		return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1;
 	}
 
 	if (IS_ENABLED(CONFIG_SMP))
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 8b6b4976fb2f..7bbe0308617f 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -167,8 +167,8 @@ phys_addr_t __mips_cm_l2sync_phys_base(void)
 	 * current location.
 	 */
 	base_reg = read_gcr_l2_only_sync_base();
-	if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK)
-		return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK;
+	if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN)
+		return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE;
 
 	/* Default to following the CM */
 	return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
@@ -183,19 +183,19 @@ static void mips_cm_probe_l2sync(void)
 	phys_addr_t addr;
 
 	/* L2-only sync was introduced with CM major revision 6 */
-	major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >>
-		CM_GCR_REV_MAJOR_SHF;
+	major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >>
+		__ffs(CM_GCR_REV_MAJOR);
 	if (major_rev < 6)
 		return;
 
 	/* Find a location for the L2 sync region */
 	addr = mips_cm_l2sync_phys_base();
-	BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK) != addr);
+	BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE) != addr);
 	if (!addr)
 		return;
 
 	/* Set the region base address & enable it */
-	write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK);
+	write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN);
 
 	/* Map the region */
 	mips_cm_l2sync_base = ioremap_nocache(addr, MIPS_CM_L2SYNC_SIZE);
@@ -215,7 +215,7 @@ int mips_cm_probe(void)
 		return 0;
 
 	addr = mips_cm_phys_base();
-	BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);
+	BUG_ON((addr & CM_GCR_BASE_GCRBASE) != addr);
 	if (!addr)
 		return -ENODEV;
 
@@ -225,7 +225,7 @@ int mips_cm_probe(void)
 
 	/* sanity check that we're looking at a CM */
 	base_reg = read_gcr_base();
-	if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) {
+	if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) {
 		pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
 		       (unsigned long)addr);
 		mips_gcr_base = NULL;
@@ -233,19 +233,19 @@ int mips_cm_probe(void)
 	}
 
 	/* set default target to memory */
-	base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK;
+	base_reg &= ~CM_GCR_BASE_CMDEFTGT;
 	base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
 	write_gcr_base(base_reg);
 
 	/* disable CM regions */
-	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
-	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
-	write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
-	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
+	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
+	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
+	write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
+	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
 
 	/* probe for an L2-only sync region */
 	mips_cm_probe_l2sync();
@@ -267,8 +267,8 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 	preempt_disable();
 
 	if (mips_cm_revision() >= CM_REV_CM3) {
-		val = core << CM3_GCR_Cx_OTHER_CORE_SHF;
-		val |= vp << CM3_GCR_Cx_OTHER_VP_SHF;
+		val = core << __ffs(CM3_GCR_Cx_OTHER_CORE);
+		val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP);
 
 		/*
 		 * We need to disable interrupts in SMP systems in order to
@@ -293,7 +293,7 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 		spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
 				  per_cpu(cm_core_lock_flags, curr_core));
 
-		val = core << CM_GCR_Cx_OTHER_CORENUM_SHF;
+		val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM);
 	}
 
 	write_gcr_cl_other(val);
@@ -337,8 +337,8 @@ void mips_cm_error_report(void)
 	cm_other = read_gcr_error_mult();
 
 	if (revision < CM_REV_CM3) { /* CM2 */
-		cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
-		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+		cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE);
+		ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
 
 		if (!cause)
 			return;
@@ -380,8 +380,8 @@ void mips_cm_error_report(void)
 		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
 		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
 
-		cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
-		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+		cause = cm_error >> __ffs(CM3_GCR_ERROR_CAUSE_ERRTYPE);
+		ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
 
 		if (!cause)
 			return;
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index a4964c334cab..690eefd0fb54 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -40,13 +40,13 @@ static phys_addr_t mips_cpc_phys_base(void)
 	if (!mips_cm_present())
 		return 0;
 
-	if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX_MSK))
+	if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX))
 		return 0;
 
 	/* If the CPC is already enabled, leave it so */
 	cpc_base = read_gcr_cpc_base();
-	if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK)
-		return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK;
+	if (cpc_base & CM_GCR_CPC_BASE_CPCEN)
+		return cpc_base & CM_GCR_CPC_BASE_CPCBASE;
 
 	/* Otherwise, use the default address */
 	cpc_base = mips_cpc_default_phys_base();
@@ -54,7 +54,7 @@ static phys_addr_t mips_cpc_phys_base(void)
 		return cpc_base;
 
 	/* Enable the CPC, mapped at the default address */
-	write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK);
+	write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN);
 	return cpc_base;
 }
 
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index d99416094ba9..357b451c43a7 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -569,8 +569,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
 	 * rest will just be performing a rather unusual nop.
 	 */
 	uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3
-				? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK
-				: CM3_GCR_Cx_COHERENCE_COHEN_MSK);
+				? CM_GCR_Cx_COHERENCE_COHDOMAINEN
+				: CM3_GCR_Cx_COHERENCE_COHEN);
 
 	uasm_i_sw(&p, t0, 0, r_pcohctl);
 	uasm_i_lw(&p, t0, 0, r_pcohctl);
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index a6b8700563c7..b544d3df3b73 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -53,9 +53,9 @@ static unsigned core_vpe_count(unsigned core)
 		return 1;
 
 	mips_cm_lock_other(core, 0);
-	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
+	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE;
 	mips_cm_unlock_other();
-	return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
+	return cfg + 1;
 }
 
 static void __init cps_smp_setup(void)
@@ -225,11 +225,11 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 	write_gcr_co_coherence(0);
 
 	/* Start it with the legacy memory map and exception base */
-	write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB);
+	write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
 
 	/* Ensure the core can access the GCRs */
 	access = read_gcr_access();
-	access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
+	access |= 1 << core;
 	write_gcr_access(access);
 
 	if (mips_cpc_present()) {
@@ -599,7 +599,7 @@ int register_cps_smp_ops(void)
 	}
 
 	/* check we have a GIC - we need one for IPIs */
-	if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX_MSK)) {
+	if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) {
 		pr_warn("MIPS CPS SMP unable to proceed without a GIC\n");
 		return -ENODEV;
 	}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f3a69de9dc6b..4cba2e778284 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1672,7 +1672,7 @@ static inline void parity_protection_init(void)
 		/* Probe L2 ECC support */
 		gcr_ectl = read_gcr_err_control();
 
-		if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) ||
+		if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT) ||
 		    !(cp0_ectl & ERRCTL_PE)) {
 			/*
 			 * One of L1 or L2 ECC checking isn't supported,
@@ -1692,12 +1692,12 @@ static inline void parity_protection_init(void)
 
 		/* Configure L2 ECC checking */
 		if (l2parity)
-			gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
+			gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN;
 		else
-			gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
+			gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN;
 		write_gcr_err_control(gcr_ectl);
 		gcr_ectl = read_gcr_err_control();
-		gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
+		gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN;
 		WARN_ON(!!gcr_ectl != l2parity);
 
 		pr_info("Cache parity protection %sabled\n",
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index c909c3342729..7f30397cb10d 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -63,15 +63,15 @@ static void mips_sc_prefetch_enable(void)
 	 * prefetching for both code & data, for all ports.
 	 */
 	pftctl = read_gcr_l2_pft_control();
-	if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) {
-		pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
-		pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
-		pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+	if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT) {
+		pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK;
+		pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK;
+		pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN;
 		write_gcr_l2_pft_control(pftctl);
 
 		pftctl = read_gcr_l2_pft_control_b();
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+		pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID;
+		pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN;
 		write_gcr_l2_pft_control_b(pftctl);
 	}
 }
@@ -84,12 +84,12 @@ static void mips_sc_prefetch_disable(void)
 		return;
 
 	pftctl = read_gcr_l2_pft_control();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+	pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN;
 	write_gcr_l2_pft_control(pftctl);
 
 	pftctl = read_gcr_l2_pft_control_b();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID;
+	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN;
 	write_gcr_l2_pft_control_b(pftctl);
 }
 
@@ -101,9 +101,9 @@ static bool mips_sc_prefetch_is_enabled(void)
 		return false;
 
 	pftctl = read_gcr_l2_pft_control();
-	if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK))
+	if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT))
 		return false;
-	return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK);
+	return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN);
 }
 
 static struct bcache_ops mips_sc_ops = {
@@ -160,21 +160,21 @@ static int __init mips_sc_probe_cm3(void)
 	unsigned long cfg = read_gcr_l2_config();
 	unsigned long sets, line_sz, assoc;
 
-	if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK)
+	if (cfg & CM_GCR_L2_CONFIG_BYPASS)
 		return 0;
 
-	sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
-	sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
+	sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE;
+	sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE);
 	if (sets)
 		c->scache.sets = 64 << sets;
 
-	line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
-	line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
+	line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE;
+	line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE);
 	if (line_sz)
 		c->scache.linesz = 2 << line_sz;
 
-	assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
-	assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
+	assoc = cfg & CM_GCR_L2_CONFIG_ASSOC;
+	assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC);
 	c->scache.ways = assoc + 1;
 	c->scache.waysize = c->scache.sets * c->scache.linesz;
 	c->scache.waybit = __ffs(c->scache.waysize);
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index c398582c316f..67602d57710c 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt)
 
 	/* if we have a CM which reports a GIC is present, leave the DT alone */
 	err = mips_cm_probe();
-	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK))
+	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX))
 		return;
 
 	if (malta_scon() == MIPS_REVISION_SCON_ROCIT) {
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6ab1d3afec02..ae9f8e581d06 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -1009,7 +1009,7 @@ static int __init gic_of_init(struct device_node *node,
 		 */
 		if (mips_cm_present()) {
 			gic_base = read_gcr_gic_base() &
-				~CM_GCR_GIC_BASE_GICEN_MSK;
+				~CM_GCR_GIC_BASE_GICEN;
 			gic_len = 0x20000;
 		} else {
 			pr_err("Failed to get GIC memory range\n");
@@ -1021,7 +1021,7 @@ static int __init gic_of_init(struct device_node *node,
 	}
 
 	if (mips_cm_present())
-		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK);
+		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
 	gic_present = true;
 
 	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 03/19] MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

There's no reason for us not to use BIT() & GENMASK() in asm/mips-cm.h
when declaring macros corresponding to register fields. This patch
modifies our definitions to do so.

The *_SHF definitions are removed entirely - they duplicate information
found in the masks, are infrequently used & can be replaced with use of
__ffs() where needed.

The *_MSK definitions then lose their _MSK suffix which is now somewhat
redundant, and users are modified to match.

The field definitions are moved to follow the appropriate register's
accessor functions, which helps to keep the field definitions in order &
to find the appropriate fields for a given register. Whilst here a
comment is added describing each register & including its name, which is
helpful both for linking the register back to hardware documentation &
for grepping purposes.

This also cleans up a couple of issues that became obvious as a result
of making the changes described above:

  - We previously had definitions for GCR_Cx_RESET_EXT_BASE & a phony
    copy of that named GCR_RESET_EXT_BASE - a register which does not
    exist. The bad definitions were added by commit 497e803ebf98 ("MIPS:
    smp-cps: Ensure secondary cores start with EVA disabled") and made
    use of from boot_core(), which is now modified to use the
    GCR_Cx_RESET_EXT_BASE definitions.

  - We had a typo in CM_GCR_ERROR_CAUSE_ERRINGO_MSK - we now correctly
    define this as inFo rather than inGo.

Now that we don't duplicate field information between _SHF & _MSK
definitions, and keep the fields next to the register accessors, it will
be much easier to spot & prevent any similar oddities being introduced
in the future.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h    | 311 ++++++++++++++++---------------------
 arch/mips/kernel/mips-cm.c         |  48 +++---
 arch/mips/kernel/mips-cpc.c        |   8 +-
 arch/mips/kernel/pm-cps.c          |   4 +-
 arch/mips/kernel/smp-cps.c         |  10 +-
 arch/mips/kernel/traps.c           |   8 +-
 arch/mips/mm/sc-mips.c             |  36 ++---
 arch/mips/mti-malta/malta-dtshim.c |   2 +-
 drivers/irqchip/irq-mips-gic.c     |   4 +-
 9 files changed, 190 insertions(+), 241 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index b01fcf4647d2..4857d4ae97b7 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -127,212 +127,161 @@ static inline bool mips_cm_has_l2sync(void)
 	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
 	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name)
 
-/* GCB register accessor functions */
+/* GCR_CONFIG - Information about the system */
 GCR_ACCESSOR_RO(64, 0x000, config)
+#define CM_GCR_CONFIG_NUMIOCU			GENMASK(15, 8)
+#define CM_GCR_CONFIG_PCORES			GENMASK(7, 0)
+
+/* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */
 GCR_ACCESSOR_RW(64, 0x008, base)
+#define CM_GCR_BASE_GCRBASE			GENMASK_ULL(47, 15)
+#define CM_GCR_BASE_CMDEFTGT			GENMASK(1, 0)
+#define  CM_GCR_BASE_CMDEFTGT_DISABLED		0
+#define  CM_GCR_BASE_CMDEFTGT_MEM		1
+#define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
+#define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
+
+/* GCR_ACCESS - Controls core/IOCU access to GCRs */
 GCR_ACCESSOR_RW(32, 0x020, access)
+#define CM_GCR_ACCESS_ACCESSEN			GENMASK(7, 0)
+
+/* GCR_REV - Indicates the Coherence Manager revision */
 GCR_ACCESSOR_RO(32, 0x030, rev)
+#define CM_GCR_REV_MAJOR			GENMASK(15, 8)
+#define CM_GCR_REV_MINOR			GENMASK(7, 0)
+
+#define CM_ENCODE_REV(major, minor) \
+		(((major) << __ffs(CM_GCR_REV_MAJOR)) | \
+		 ((minor) << __ffs(CM_GCR_REV_MINOR)))
+
+#define CM_REV_CM2				CM_ENCODE_REV(6, 0)
+#define CM_REV_CM2_5				CM_ENCODE_REV(7, 0)
+#define CM_REV_CM3				CM_ENCODE_REV(8, 0)
+
+/* GCR_ERR_CONTROL - Control error checking logic */
 GCR_ACCESSOR_RW(32, 0x038, err_control)
+#define CM_GCR_ERR_CONTROL_L2_ECC_EN		BIT(1)
+#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT	BIT(0)
+
+/* GCR_ERR_MASK - Control which errors are reported as interrupts */
 GCR_ACCESSOR_RW(64, 0x040, error_mask)
+
+/* GCR_ERR_CAUSE - Indicates the type of error that occurred */
 GCR_ACCESSOR_RW(64, 0x048, error_cause)
+#define CM_GCR_ERROR_CAUSE_ERRTYPE		GENMASK(31, 27)
+#define CM3_GCR_ERROR_CAUSE_ERRTYPE		GENMASK_ULL(63, 58)
+#define CM_GCR_ERROR_CAUSE_ERRINFO		GENMASK(26, 0)
+
+/* GCR_ERR_ADDR - Indicates the address associated with an error */
 GCR_ACCESSOR_RW(64, 0x050, error_addr)
+
+/* GCR_ERR_MULT - Indicates when multiple errors have occurred */
 GCR_ACCESSOR_RW(64, 0x058, error_mult)
+#define CM_GCR_ERROR_MULT_ERR2ND		GENMASK(4, 0)
+
+/* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */
 GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base)
+#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE	GENMASK(31, 12)
+#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN		BIT(0)
+
+/* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */
 GCR_ACCESSOR_RW(64, 0x080, gic_base)
+#define CM_GCR_GIC_BASE_GICBASE			GENMASK(31, 17)
+#define CM_GCR_GIC_BASE_GICEN			BIT(0)
+
+/* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */
 GCR_ACCESSOR_RW(64, 0x088, cpc_base)
+#define CM_GCR_CPC_BASE_CPCBASE			GENMASK(31, 15)
+#define CM_GCR_CPC_BASE_CPCEN			BIT(0)
+
+/* GCR_REGn_BASE - Base addresses of CM address regions */
 GCR_ACCESSOR_RW(64, 0x090, reg0_base)
-GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
 GCR_ACCESSOR_RW(64, 0x0a0, reg1_base)
-GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
 GCR_ACCESSOR_RW(64, 0x0b0, reg2_base)
-GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
 GCR_ACCESSOR_RW(64, 0x0c0, reg3_base)
+#define CM_GCR_REGn_BASE_BASEADDR		GENMASK(31, 16)
+
+/* GCR_REGn_MASK - Size & destination of CM address regions */
+GCR_ACCESSOR_RW(64, 0x098, reg0_mask)
+GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask)
+GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask)
 GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask)
+#define CM_GCR_REGn_MASK_ADDRMASK		GENMASK(31, 16)
+#define CM_GCR_REGn_MASK_CCAOVR			GENMASK(7, 5)
+#define CM_GCR_REGn_MASK_CCAOVREN		BIT(4)
+#define CM_GCR_REGn_MASK_DROPL2			BIT(2)
+#define CM_GCR_REGn_MASK_CMTGT			GENMASK(1, 0)
+#define  CM_GCR_REGn_MASK_CMTGT_DISABLED	0x0
+#define  CM_GCR_REGn_MASK_CMTGT_MEM		0x1
+#define  CM_GCR_REGn_MASK_CMTGT_IOCU0		0x2
+#define  CM_GCR_REGn_MASK_CMTGT_IOCU1		0x3
+
+/* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */
 GCR_ACCESSOR_RO(32, 0x0d0, gic_status)
+#define CM_GCR_GIC_STATUS_EX			BIT(0)
+
+/* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */
 GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
+#define CM_GCR_CPC_STATUS_EX			BIT(0)
+
+/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
 GCR_ACCESSOR_RW(32, 0x130, l2_config)
+#define CM_GCR_L2_CONFIG_BYPASS			BIT(20)
+#define CM_GCR_L2_CONFIG_SET_SIZE		GENMASK(15, 12)
+#define CM_GCR_L2_CONFIG_LINE_SIZE		GENMASK(11, 8)
+#define CM_GCR_L2_CONFIG_ASSOC			GENMASK(7, 0)
+
+/* GCR_SYS_CONFIG2 - Further information about the system */
 GCR_ACCESSOR_RO(32, 0x150, sys_config2)
+#define CM_GCR_SYS_CONFIG2_MAXVPW		GENMASK(3, 0)
+
+/* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */
 GCR_ACCESSOR_RW(32, 0x300, l2_pft_control)
+#define CM_GCR_L2_PFT_CONTROL_PAGEMASK		GENMASK(31, 12)
+#define CM_GCR_L2_PFT_CONTROL_PFTEN		BIT(8)
+#define CM_GCR_L2_PFT_CONTROL_NPFT		GENMASK(7, 0)
+
+/* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */
 GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
+#define CM_GCR_L2_PFT_CONTROL_B_CEN		BIT(8)
+#define CM_GCR_L2_PFT_CONTROL_B_PORTID		GENMASK(7, 0)
+
+/* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */
 GCR_ACCESSOR_RW(64, 0x680, bev_base)
 
-/* Core Local & Core Other register accessor functions */
+/* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */
 GCR_CX_ACCESSOR_RW(32, 0x000, reset_release)
-GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
-GCR_CX_ACCESSOR_RO(32, 0x010, config)
-GCR_CX_ACCESSOR_RW(32, 0x018, other)
-GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
-GCR_CX_ACCESSOR_RO(32, 0x028, id)
-GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
-
-/* GCR_CONFIG register fields */
-#define CM_GCR_CONFIG_NUMIOCU_SHF		8
-#define CM_GCR_CONFIG_NUMIOCU_MSK		(_ULCAST_(0xf) << 8)
-#define CM_GCR_CONFIG_PCORES_SHF		0
-#define CM_GCR_CONFIG_PCORES_MSK		(_ULCAST_(0xff) << 0)
-
-/* GCR_BASE register fields */
-#define CM_GCR_BASE_GCRBASE_SHF			15
-#define CM_GCR_BASE_GCRBASE_MSK			(_ULCAST_(0x1ffff) << 15)
-#define CM_GCR_BASE_CMDEFTGT_SHF		0
-#define CM_GCR_BASE_CMDEFTGT_MSK		(_ULCAST_(0x3) << 0)
-#define  CM_GCR_BASE_CMDEFTGT_DISABLED		0
-#define  CM_GCR_BASE_CMDEFTGT_MEM		1
-#define  CM_GCR_BASE_CMDEFTGT_IOCU0		2
-#define  CM_GCR_BASE_CMDEFTGT_IOCU1		3
 
-/* GCR_RESET_EXT_BASE register fields */
-#define CM_GCR_RESET_EXT_BASE_EVARESET		BIT(31)
-#define CM_GCR_RESET_EXT_BASE_UEB		BIT(30)
+/* GCR_Cx_COHERENCE - Controls core coherence */
+GCR_CX_ACCESSOR_RW(32, 0x008, coherence)
+#define CM_GCR_Cx_COHERENCE_COHDOMAINEN		GENMASK(7, 0)
+#define CM3_GCR_Cx_COHERENCE_COHEN		BIT(0)
 
-/* GCR_ACCESS register fields */
-#define CM_GCR_ACCESS_ACCESSEN_SHF		0
-#define CM_GCR_ACCESS_ACCESSEN_MSK		(_ULCAST_(0xff) << 0)
+/* GCR_Cx_CONFIG - Information about a core's configuration */
+GCR_CX_ACCESSOR_RO(32, 0x010, config)
+#define CM_GCR_Cx_CONFIG_IOCUTYPE		GENMASK(11, 10)
+#define CM_GCR_Cx_CONFIG_PVPE			GENMASK(9, 0)
 
-/* GCR_REV register fields */
-#define CM_GCR_REV_MAJOR_SHF			8
-#define CM_GCR_REV_MAJOR_MSK			(_ULCAST_(0xff) << 8)
-#define CM_GCR_REV_MINOR_SHF			0
-#define CM_GCR_REV_MINOR_MSK			(_ULCAST_(0xff) << 0)
+/* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */
+GCR_CX_ACCESSOR_RW(32, 0x018, other)
+#define CM_GCR_Cx_OTHER_CORENUM			GENMASK(31, 16)
+#define CM3_GCR_Cx_OTHER_CORE			GENMASK(13, 8)
+#define CM3_GCR_Cx_OTHER_VP			GENMASK(2, 0)
 
-#define CM_ENCODE_REV(major, minor) \
-		(((major) << CM_GCR_REV_MAJOR_SHF) | \
-		 ((minor) << CM_GCR_REV_MINOR_SHF))
+/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
+GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
+#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE		GENMASK(31, 12)
 
-#define CM_REV_CM2				CM_ENCODE_REV(6, 0)
-#define CM_REV_CM2_5				CM_ENCODE_REV(7, 0)
-#define CM_REV_CM3				CM_ENCODE_REV(8, 0)
+/* GCR_Cx_ID - Identify the current core */
+GCR_CX_ACCESSOR_RO(32, 0x028, id)
 
-/* GCR_ERR_CONTROL register fields */
-#define CM_GCR_ERR_CONTROL_L2_ECC_EN_SHF	1
-#define CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK	(_ULCAST_(0x1) << 1)
-#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_SHF	0
-#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK	(_ULCAST_(0x1) << 0)
-
-/* GCR_ERROR_CAUSE register fields */
-#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF		27
-#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK		(_ULCAST_(0x1f) << 27)
-#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF		58
-#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK		GENMASK_ULL(63, 58)
-#define CM_GCR_ERROR_CAUSE_ERRINFO_SHF		0
-#define CM_GCR_ERROR_CAUSE_ERRINGO_MSK		(_ULCAST_(0x7ffffff) << 0)
-
-/* GCR_ERROR_MULT register fields */
-#define CM_GCR_ERROR_MULT_ERR2ND_SHF		0
-#define CM_GCR_ERROR_MULT_ERR2ND_MSK		(_ULCAST_(0x1f) << 0)
-
-/* GCR_L2_ONLY_SYNC_BASE register fields */
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_SHF	12
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK	(_ULCAST_(0xfffff) << 12)
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_SHF	0
-#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK	(_ULCAST_(0x1) << 0)
-
-/* GCR_GIC_BASE register fields */
-#define CM_GCR_GIC_BASE_GICBASE_SHF		17
-#define CM_GCR_GIC_BASE_GICBASE_MSK		(_ULCAST_(0x7fff) << 17)
-#define CM_GCR_GIC_BASE_GICEN_SHF		0
-#define CM_GCR_GIC_BASE_GICEN_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_CPC_BASE register fields */
-#define CM_GCR_CPC_BASE_CPCBASE_SHF		15
-#define CM_GCR_CPC_BASE_CPCBASE_MSK		(_ULCAST_(0x1ffff) << 15)
-#define CM_GCR_CPC_BASE_CPCEN_SHF		0
-#define CM_GCR_CPC_BASE_CPCEN_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_GIC_STATUS register fields */
-#define CM_GCR_GIC_STATUS_GICEX_SHF		0
-#define CM_GCR_GIC_STATUS_GICEX_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_REGn_BASE register fields */
-#define CM_GCR_REGn_BASE_BASEADDR_SHF		16
-#define CM_GCR_REGn_BASE_BASEADDR_MSK		(_ULCAST_(0xffff) << 16)
-
-/* GCR_REGn_MASK register fields */
-#define CM_GCR_REGn_MASK_ADDRMASK_SHF		16
-#define CM_GCR_REGn_MASK_ADDRMASK_MSK		(_ULCAST_(0xffff) << 16)
-#define CM_GCR_REGn_MASK_CCAOVR_SHF		5
-#define CM_GCR_REGn_MASK_CCAOVR_MSK		(_ULCAST_(0x3) << 5)
-#define CM_GCR_REGn_MASK_CCAOVREN_SHF		4
-#define CM_GCR_REGn_MASK_CCAOVREN_MSK		(_ULCAST_(0x1) << 4)
-#define CM_GCR_REGn_MASK_DROPL2_SHF		2
-#define CM_GCR_REGn_MASK_DROPL2_MSK		(_ULCAST_(0x1) << 2)
-#define CM_GCR_REGn_MASK_CMTGT_SHF		0
-#define CM_GCR_REGn_MASK_CMTGT_MSK		(_ULCAST_(0x3) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_DISABLED	(_ULCAST_(0x0) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_MEM		(_ULCAST_(0x1) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_IOCU0		(_ULCAST_(0x2) << 0)
-#define  CM_GCR_REGn_MASK_CMTGT_IOCU1		(_ULCAST_(0x3) << 0)
-
-/* GCR_GIC_STATUS register fields */
-#define CM_GCR_GIC_STATUS_EX_SHF		0
-#define CM_GCR_GIC_STATUS_EX_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_CPC_STATUS register fields */
-#define CM_GCR_CPC_STATUS_EX_SHF		0
-#define CM_GCR_CPC_STATUS_EX_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_L2_CONFIG register fields */
-#define CM_GCR_L2_CONFIG_BYPASS_SHF		20
-#define CM_GCR_L2_CONFIG_BYPASS_MSK		(_ULCAST_(0x1) << 20)
-#define CM_GCR_L2_CONFIG_SET_SIZE_SHF		12
-#define CM_GCR_L2_CONFIG_SET_SIZE_MSK		(_ULCAST_(0xf) << 12)
-#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF		8
-#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK		(_ULCAST_(0xf) << 8)
-#define CM_GCR_L2_CONFIG_ASSOC_SHF		0
-#define CM_GCR_L2_CONFIG_ASSOC_MSK		(_ULCAST_(0xff) << 0)
-
-/* GCR_SYS_CONFIG2 register fields */
-#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF		0
-#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK		(_ULCAST_(0xf) << 0)
-
-/* GCR_L2_PFT_CONTROL register fields */
-#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF	12
-#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK	(_ULCAST_(0xfffff) << 12)
-#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF		8
-#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK		(_ULCAST_(0x1) << 8)
-#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF		0
-#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK		(_ULCAST_(0xff) << 0)
-
-/* GCR_L2_PFT_CONTROL_B register fields */
-#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF		8
-#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK		(_ULCAST_(0x1) << 8)
-#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF	0
-#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK	(_ULCAST_(0xff) << 0)
-
-/* GCR_Cx_COHERENCE register fields */
-#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF	0
-#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK	(_ULCAST_(0xff) << 0)
-#define CM3_GCR_Cx_COHERENCE_COHEN_MSK		(_ULCAST_(0x1) << 0)
-
-/* GCR_Cx_CONFIG register fields */
-#define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF		10
-#define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK		(_ULCAST_(0x3) << 10)
-#define CM_GCR_Cx_CONFIG_PVPE_SHF		0
-#define CM_GCR_Cx_CONFIG_PVPE_MSK		(_ULCAST_(0x3ff) << 0)
-
-/* GCR_Cx_OTHER register fields */
-#define CM_GCR_Cx_OTHER_CORENUM_SHF		16
-#define CM_GCR_Cx_OTHER_CORENUM_MSK		(_ULCAST_(0xffff) << 16)
-#define CM3_GCR_Cx_OTHER_CORE_SHF		8
-#define CM3_GCR_Cx_OTHER_CORE_MSK		(_ULCAST_(0x3f) << 8)
-#define CM3_GCR_Cx_OTHER_VP_SHF			0
-#define CM3_GCR_Cx_OTHER_VP_MSK			(_ULCAST_(0x7) << 0)
-
-/* GCR_Cx_RESET_BASE register fields */
-#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF	12
-#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_MSK	(_ULCAST_(0xfffff) << 12)
-
-/* GCR_Cx_RESET_EXT_BASE register fields */
-#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_SHF	31
-#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_MSK	(_ULCAST_(0x1) << 31)
-#define CM_GCR_Cx_RESET_EXT_BASE_UEB_SHF	30
-#define CM_GCR_Cx_RESET_EXT_BASE_UEB_MSK	(_ULCAST_(0x1) << 30)
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_SHF	20
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_MSK	(_ULCAST_(0xff) << 20)
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_SHF	1
-#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_MSK	(_ULCAST_(0x7f) << 1)
-#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_SHF	0
-#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_MSK	(_ULCAST_(0x1) << 0)
+/* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */
+GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
+#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET	BIT(31)
+#define CM_GCR_Cx_RESET_EXT_BASE_UEB		BIT(30)
+#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK	GENMASK(27, 20)
+#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA	GENMASK(7, 1)
+#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT	BIT(0)
 
 /**
  * mips_cm_numcores - return the number of cores present in the system
@@ -345,8 +294,8 @@ static inline unsigned mips_cm_numcores(void)
 	if (!mips_cm_present())
 		return 0;
 
-	return ((read_gcr_config() & CM_GCR_CONFIG_PCORES_MSK)
-		>> CM_GCR_CONFIG_PCORES_SHF) + 1;
+	return ((read_gcr_config() & CM_GCR_CONFIG_PCORES)
+		>> __ffs(CM_GCR_CONFIG_PCORES)) + 1;
 }
 
 /**
@@ -360,8 +309,8 @@ static inline unsigned mips_cm_numiocu(void)
 	if (!mips_cm_present())
 		return 0;
 
-	return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU_MSK)
-		>> CM_GCR_CONFIG_NUMIOCU_SHF;
+	return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU)
+		>> __ffs(CM_GCR_CONFIG_NUMIOCU);
 }
 
 /**
@@ -405,7 +354,7 @@ static inline unsigned int mips_cm_max_vp_width(void)
 	uint32_t cfg;
 
 	if (mips_cm_revision() >= CM_REV_CM3)
-		return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK;
+		return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW;
 
 	if (mips_cm_present()) {
 		/*
@@ -413,8 +362,8 @@ static inline unsigned int mips_cm_max_vp_width(void)
 		 * number of VP(E)s, and if that ever changes then this will
 		 * need revisiting.
 		 */
-		cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
-		return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
+		cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE;
+		return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1;
 	}
 
 	if (IS_ENABLED(CONFIG_SMP))
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 8b6b4976fb2f..7bbe0308617f 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -167,8 +167,8 @@ phys_addr_t __mips_cm_l2sync_phys_base(void)
 	 * current location.
 	 */
 	base_reg = read_gcr_l2_only_sync_base();
-	if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK)
-		return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK;
+	if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN)
+		return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE;
 
 	/* Default to following the CM */
 	return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
@@ -183,19 +183,19 @@ static void mips_cm_probe_l2sync(void)
 	phys_addr_t addr;
 
 	/* L2-only sync was introduced with CM major revision 6 */
-	major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >>
-		CM_GCR_REV_MAJOR_SHF;
+	major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >>
+		__ffs(CM_GCR_REV_MAJOR);
 	if (major_rev < 6)
 		return;
 
 	/* Find a location for the L2 sync region */
 	addr = mips_cm_l2sync_phys_base();
-	BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK) != addr);
+	BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE) != addr);
 	if (!addr)
 		return;
 
 	/* Set the region base address & enable it */
-	write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK);
+	write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN);
 
 	/* Map the region */
 	mips_cm_l2sync_base = ioremap_nocache(addr, MIPS_CM_L2SYNC_SIZE);
@@ -215,7 +215,7 @@ int mips_cm_probe(void)
 		return 0;
 
 	addr = mips_cm_phys_base();
-	BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);
+	BUG_ON((addr & CM_GCR_BASE_GCRBASE) != addr);
 	if (!addr)
 		return -ENODEV;
 
@@ -225,7 +225,7 @@ int mips_cm_probe(void)
 
 	/* sanity check that we're looking at a CM */
 	base_reg = read_gcr_base();
-	if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) {
+	if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) {
 		pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
 		       (unsigned long)addr);
 		mips_gcr_base = NULL;
@@ -233,19 +233,19 @@ int mips_cm_probe(void)
 	}
 
 	/* set default target to memory */
-	base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK;
+	base_reg &= ~CM_GCR_BASE_CMDEFTGT;
 	base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
 	write_gcr_base(base_reg);
 
 	/* disable CM regions */
-	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
-	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
-	write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
-	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK);
-	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK);
+	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
+	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
+	write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
+	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
+	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
 
 	/* probe for an L2-only sync region */
 	mips_cm_probe_l2sync();
@@ -267,8 +267,8 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 	preempt_disable();
 
 	if (mips_cm_revision() >= CM_REV_CM3) {
-		val = core << CM3_GCR_Cx_OTHER_CORE_SHF;
-		val |= vp << CM3_GCR_Cx_OTHER_VP_SHF;
+		val = core << __ffs(CM3_GCR_Cx_OTHER_CORE);
+		val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP);
 
 		/*
 		 * We need to disable interrupts in SMP systems in order to
@@ -293,7 +293,7 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 		spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
 				  per_cpu(cm_core_lock_flags, curr_core));
 
-		val = core << CM_GCR_Cx_OTHER_CORENUM_SHF;
+		val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM);
 	}
 
 	write_gcr_cl_other(val);
@@ -337,8 +337,8 @@ void mips_cm_error_report(void)
 	cm_other = read_gcr_error_mult();
 
 	if (revision < CM_REV_CM3) { /* CM2 */
-		cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
-		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+		cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE);
+		ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
 
 		if (!cause)
 			return;
@@ -380,8 +380,8 @@ void mips_cm_error_report(void)
 		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
 		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
 
-		cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF;
-		ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
+		cause = cm_error >> __ffs(CM3_GCR_ERROR_CAUSE_ERRTYPE);
+		ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
 
 		if (!cause)
 			return;
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index a4964c334cab..690eefd0fb54 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -40,13 +40,13 @@ static phys_addr_t mips_cpc_phys_base(void)
 	if (!mips_cm_present())
 		return 0;
 
-	if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX_MSK))
+	if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX))
 		return 0;
 
 	/* If the CPC is already enabled, leave it so */
 	cpc_base = read_gcr_cpc_base();
-	if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK)
-		return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK;
+	if (cpc_base & CM_GCR_CPC_BASE_CPCEN)
+		return cpc_base & CM_GCR_CPC_BASE_CPCBASE;
 
 	/* Otherwise, use the default address */
 	cpc_base = mips_cpc_default_phys_base();
@@ -54,7 +54,7 @@ static phys_addr_t mips_cpc_phys_base(void)
 		return cpc_base;
 
 	/* Enable the CPC, mapped at the default address */
-	write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK);
+	write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN);
 	return cpc_base;
 }
 
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index d99416094ba9..357b451c43a7 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -569,8 +569,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
 	 * rest will just be performing a rather unusual nop.
 	 */
 	uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3
-				? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK
-				: CM3_GCR_Cx_COHERENCE_COHEN_MSK);
+				? CM_GCR_Cx_COHERENCE_COHDOMAINEN
+				: CM3_GCR_Cx_COHERENCE_COHEN);
 
 	uasm_i_sw(&p, t0, 0, r_pcohctl);
 	uasm_i_lw(&p, t0, 0, r_pcohctl);
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index a6b8700563c7..b544d3df3b73 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -53,9 +53,9 @@ static unsigned core_vpe_count(unsigned core)
 		return 1;
 
 	mips_cm_lock_other(core, 0);
-	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK;
+	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE;
 	mips_cm_unlock_other();
-	return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1;
+	return cfg + 1;
 }
 
 static void __init cps_smp_setup(void)
@@ -225,11 +225,11 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 	write_gcr_co_coherence(0);
 
 	/* Start it with the legacy memory map and exception base */
-	write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB);
+	write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
 
 	/* Ensure the core can access the GCRs */
 	access = read_gcr_access();
-	access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core);
+	access |= 1 << core;
 	write_gcr_access(access);
 
 	if (mips_cpc_present()) {
@@ -599,7 +599,7 @@ int register_cps_smp_ops(void)
 	}
 
 	/* check we have a GIC - we need one for IPIs */
-	if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX_MSK)) {
+	if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) {
 		pr_warn("MIPS CPS SMP unable to proceed without a GIC\n");
 		return -ENODEV;
 	}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f3a69de9dc6b..4cba2e778284 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1672,7 +1672,7 @@ static inline void parity_protection_init(void)
 		/* Probe L2 ECC support */
 		gcr_ectl = read_gcr_err_control();
 
-		if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) ||
+		if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT) ||
 		    !(cp0_ectl & ERRCTL_PE)) {
 			/*
 			 * One of L1 or L2 ECC checking isn't supported,
@@ -1692,12 +1692,12 @@ static inline void parity_protection_init(void)
 
 		/* Configure L2 ECC checking */
 		if (l2parity)
-			gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
+			gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN;
 		else
-			gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
+			gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN;
 		write_gcr_err_control(gcr_ectl);
 		gcr_ectl = read_gcr_err_control();
-		gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK;
+		gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN;
 		WARN_ON(!!gcr_ectl != l2parity);
 
 		pr_info("Cache parity protection %sabled\n",
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index c909c3342729..7f30397cb10d 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -63,15 +63,15 @@ static void mips_sc_prefetch_enable(void)
 	 * prefetching for both code & data, for all ports.
 	 */
 	pftctl = read_gcr_l2_pft_control();
-	if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) {
-		pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
-		pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
-		pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+	if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT) {
+		pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK;
+		pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK;
+		pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN;
 		write_gcr_l2_pft_control(pftctl);
 
 		pftctl = read_gcr_l2_pft_control_b();
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+		pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID;
+		pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN;
 		write_gcr_l2_pft_control_b(pftctl);
 	}
 }
@@ -84,12 +84,12 @@ static void mips_sc_prefetch_disable(void)
 		return;
 
 	pftctl = read_gcr_l2_pft_control();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
+	pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN;
 	write_gcr_l2_pft_control(pftctl);
 
 	pftctl = read_gcr_l2_pft_control_b();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
+	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID;
+	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN;
 	write_gcr_l2_pft_control_b(pftctl);
 }
 
@@ -101,9 +101,9 @@ static bool mips_sc_prefetch_is_enabled(void)
 		return false;
 
 	pftctl = read_gcr_l2_pft_control();
-	if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK))
+	if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT))
 		return false;
-	return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK);
+	return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN);
 }
 
 static struct bcache_ops mips_sc_ops = {
@@ -160,21 +160,21 @@ static int __init mips_sc_probe_cm3(void)
 	unsigned long cfg = read_gcr_l2_config();
 	unsigned long sets, line_sz, assoc;
 
-	if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK)
+	if (cfg & CM_GCR_L2_CONFIG_BYPASS)
 		return 0;
 
-	sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
-	sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
+	sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE;
+	sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE);
 	if (sets)
 		c->scache.sets = 64 << sets;
 
-	line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
-	line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
+	line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE;
+	line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE);
 	if (line_sz)
 		c->scache.linesz = 2 << line_sz;
 
-	assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
-	assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
+	assoc = cfg & CM_GCR_L2_CONFIG_ASSOC;
+	assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC);
 	c->scache.ways = assoc + 1;
 	c->scache.waysize = c->scache.sets * c->scache.linesz;
 	c->scache.waybit = __ffs(c->scache.waysize);
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index c398582c316f..67602d57710c 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt)
 
 	/* if we have a CM which reports a GIC is present, leave the DT alone */
 	err = mips_cm_probe();
-	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK))
+	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX))
 		return;
 
 	if (malta_scon() == MIPS_REVISION_SCON_ROCIT) {
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 6ab1d3afec02..ae9f8e581d06 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -1009,7 +1009,7 @@ static int __init gic_of_init(struct device_node *node,
 		 */
 		if (mips_cm_present()) {
 			gic_base = read_gcr_gic_base() &
-				~CM_GCR_GIC_BASE_GICEN_MSK;
+				~CM_GCR_GIC_BASE_GICEN;
 			gic_len = 0x20000;
 		} else {
 			pr_err("Failed to get GIC memory range\n");
@@ -1021,7 +1021,7 @@ static int __init gic_of_init(struct device_node *node,
 	}
 
 	if (mips_cm_present())
-		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK);
+		write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN);
 	gic_present = true;
 
 	__gic_init(gic_base, gic_len, cpu_vec, 0, node);
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 04/19] MIPS: CPC: Use common CPS accessor generation macros
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Switch the MIPS Cluster Power Controller (CPC) accessor functions to be
generated by the new common Coherent Processing System (CPS) macros
shared with the Coherence Manager (CM).

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cpc.h | 63 ++++++++++++++--------------------------
 1 file changed, 22 insertions(+), 41 deletions(-)

diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 8c519f9827a3..9de7addb59ba 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -13,6 +13,7 @@
 
 #include <linux/io.h>
 #include <linux/types.h>
+#include <asm/mips-cps.h>
 
 /* The base address of the CPC registers */
 extern void __iomem *mips_cpc_base;
@@ -61,54 +62,34 @@ static inline bool mips_cpc_present(void)
 #define MIPS_CPC_CLCB_OFS	0x2000
 #define MIPS_CPC_COCB_OFS	0x4000
 
-/* Macros to ease the creation of register access functions */
-#define BUILD_CPC_R_(name, off)					\
-static inline u32 *addr_cpc_##name(void)			\
-{								\
-	return (u32 *)(mips_cpc_base + (off));			\
-}								\
-								\
-static inline u32 read_cpc_##name(void)				\
-{								\
-	return __raw_readl(mips_cpc_base + (off));		\
-}
-
-#define BUILD_CPC__W(name, off) \
-static inline void write_cpc_##name(u32 value)			\
-{								\
-	__raw_writel(value, mips_cpc_base + (off));		\
-}
-
-#define BUILD_CPC_RW(name, off)					\
-	BUILD_CPC_R_(name, off)					\
-	BUILD_CPC__W(name, off)
+#define CPC_ACCESSOR_RO(sz, off, name)					\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
 
-#define BUILD_CPC_Cx_R_(name, off)				\
-	BUILD_CPC_R_(cl_##name, MIPS_CPC_CLCB_OFS + (off))	\
-	BUILD_CPC_R_(co_##name, MIPS_CPC_COCB_OFS + (off))
+#define CPC_ACCESSOR_RW(sz, off, name)					\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
 
-#define BUILD_CPC_Cx__W(name, off)				\
-	BUILD_CPC__W(cl_##name, MIPS_CPC_CLCB_OFS + (off))	\
-	BUILD_CPC__W(co_##name, MIPS_CPC_COCB_OFS + (off))
+#define CPC_CX_ACCESSOR_RO(sz, off, name)				\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
 
-#define BUILD_CPC_Cx_RW(name, off)				\
-	BUILD_CPC_Cx_R_(name, off)				\
-	BUILD_CPC_Cx__W(name, off)
+#define CPC_CX_ACCESSOR_RW(sz, off, name)				\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
 
 /* GCB register accessor functions */
-BUILD_CPC_RW(access,		MIPS_CPC_GCB_OFS + 0x00)
-BUILD_CPC_RW(seqdel,		MIPS_CPC_GCB_OFS + 0x08)
-BUILD_CPC_RW(rail,		MIPS_CPC_GCB_OFS + 0x10)
-BUILD_CPC_RW(resetlen,		MIPS_CPC_GCB_OFS + 0x18)
-BUILD_CPC_R_(revision,		MIPS_CPC_GCB_OFS + 0x20)
+CPC_ACCESSOR_RW(32, 0x000, access)
+CPC_ACCESSOR_RW(32, 0x008, seqdel)
+CPC_ACCESSOR_RW(32, 0x010, rail)
+CPC_ACCESSOR_RW(32, 0x018, resetlen)
+CPC_ACCESSOR_RO(32, 0x020, revision)
 
 /* Core Local & Core Other accessor functions */
-BUILD_CPC_Cx_RW(cmd,		0x00)
-BUILD_CPC_Cx_RW(stat_conf,	0x08)
-BUILD_CPC_Cx_RW(other,		0x10)
-BUILD_CPC_Cx_RW(vp_stop,	0x20)
-BUILD_CPC_Cx_RW(vp_run,		0x28)
-BUILD_CPC_Cx_RW(vp_running,	0x30)
+CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
+CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
+CPC_CX_ACCESSOR_RW(32, 0x010, other)
+CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
+CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
+CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
 /* CPC_Cx_CMD register fields */
 #define CPC_Cx_CMD_SHF				0
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 04/19] MIPS: CPC: Use common CPS accessor generation macros
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Switch the MIPS Cluster Power Controller (CPC) accessor functions to be
generated by the new common Coherent Processing System (CPS) macros
shared with the Coherence Manager (CM).

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cpc.h | 63 ++++++++++++++--------------------------
 1 file changed, 22 insertions(+), 41 deletions(-)

diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 8c519f9827a3..9de7addb59ba 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -13,6 +13,7 @@
 
 #include <linux/io.h>
 #include <linux/types.h>
+#include <asm/mips-cps.h>
 
 /* The base address of the CPC registers */
 extern void __iomem *mips_cpc_base;
@@ -61,54 +62,34 @@ static inline bool mips_cpc_present(void)
 #define MIPS_CPC_CLCB_OFS	0x2000
 #define MIPS_CPC_COCB_OFS	0x4000
 
-/* Macros to ease the creation of register access functions */
-#define BUILD_CPC_R_(name, off)					\
-static inline u32 *addr_cpc_##name(void)			\
-{								\
-	return (u32 *)(mips_cpc_base + (off));			\
-}								\
-								\
-static inline u32 read_cpc_##name(void)				\
-{								\
-	return __raw_readl(mips_cpc_base + (off));		\
-}
-
-#define BUILD_CPC__W(name, off) \
-static inline void write_cpc_##name(u32 value)			\
-{								\
-	__raw_writel(value, mips_cpc_base + (off));		\
-}
-
-#define BUILD_CPC_RW(name, off)					\
-	BUILD_CPC_R_(name, off)					\
-	BUILD_CPC__W(name, off)
+#define CPC_ACCESSOR_RO(sz, off, name)					\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
 
-#define BUILD_CPC_Cx_R_(name, off)				\
-	BUILD_CPC_R_(cl_##name, MIPS_CPC_CLCB_OFS + (off))	\
-	BUILD_CPC_R_(co_##name, MIPS_CPC_COCB_OFS + (off))
+#define CPC_ACCESSOR_RW(sz, off, name)					\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
 
-#define BUILD_CPC_Cx__W(name, off)				\
-	BUILD_CPC__W(cl_##name, MIPS_CPC_CLCB_OFS + (off))	\
-	BUILD_CPC__W(co_##name, MIPS_CPC_COCB_OFS + (off))
+#define CPC_CX_ACCESSOR_RO(sz, off, name)				\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
 
-#define BUILD_CPC_Cx_RW(name, off)				\
-	BUILD_CPC_Cx_R_(name, off)				\
-	BUILD_CPC_Cx__W(name, off)
+#define CPC_CX_ACCESSOR_RW(sz, off, name)				\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
 
 /* GCB register accessor functions */
-BUILD_CPC_RW(access,		MIPS_CPC_GCB_OFS + 0x00)
-BUILD_CPC_RW(seqdel,		MIPS_CPC_GCB_OFS + 0x08)
-BUILD_CPC_RW(rail,		MIPS_CPC_GCB_OFS + 0x10)
-BUILD_CPC_RW(resetlen,		MIPS_CPC_GCB_OFS + 0x18)
-BUILD_CPC_R_(revision,		MIPS_CPC_GCB_OFS + 0x20)
+CPC_ACCESSOR_RW(32, 0x000, access)
+CPC_ACCESSOR_RW(32, 0x008, seqdel)
+CPC_ACCESSOR_RW(32, 0x010, rail)
+CPC_ACCESSOR_RW(32, 0x018, resetlen)
+CPC_ACCESSOR_RO(32, 0x020, revision)
 
 /* Core Local & Core Other accessor functions */
-BUILD_CPC_Cx_RW(cmd,		0x00)
-BUILD_CPC_Cx_RW(stat_conf,	0x08)
-BUILD_CPC_Cx_RW(other,		0x10)
-BUILD_CPC_Cx_RW(vp_stop,	0x20)
-BUILD_CPC_Cx_RW(vp_run,		0x28)
-BUILD_CPC_Cx_RW(vp_running,	0x30)
+CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
+CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
+CPC_CX_ACCESSOR_RW(32, 0x010, other)
+CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
+CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
+CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
 /* CPC_Cx_CMD register fields */
 #define CPC_Cx_CMD_SHF				0
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 05/19] MIPS: CPC: Use BIT/GENMASK for register fields, order & drop shifts
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Tidy up asm/mips-cpc.h in a similar way to what "MIPS: CM: Use
BIT/GENMASK for register fields, order & drop shifts" did for
asm/mips-cm.h.

We use BIT() & GENMASK() to simplify the definition of register fields,
drop the _SHF definitions since that information can be found in the
_MSK ones, and then drop the _MSK suffix.

Fields definitions are moved to be next to the appropriate register
definition, making it easier to link the two & keep everything ordered
by register address. Comments are added including the name of each
register & a brief description of its purpose which helps to understand
what registers are for, link them back to hardware documentation or grep
for them.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cpc.h | 79 +++++++++++++++++++++-------------------
 arch/mips/kernel/mips-cpc.c      |  2 +-
 arch/mips/kernel/pm-cps.c        |  2 +-
 arch/mips/kernel/smp-cps.c       |  8 ++--
 4 files changed, 49 insertions(+), 42 deletions(-)

diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 9de7addb59ba..6cd2847fc95b 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -76,55 +76,60 @@ static inline bool mips_cpc_present(void)
 	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
 	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
 
-/* GCB register accessor functions */
+/* CPC_ACCESS - Control core/IOCU access to CPC registers prior to CM 3 */
 CPC_ACCESSOR_RW(32, 0x000, access)
+
+/* CPC_SEQDEL - Configure delays between command sequencer steps */
 CPC_ACCESSOR_RW(32, 0x008, seqdel)
+
+/* CPC_RAIL - Configure the delay from rail power-up to stability */
 CPC_ACCESSOR_RW(32, 0x010, rail)
+
+/* CPC_RESETLEN - Configure the length of reset sequences */
 CPC_ACCESSOR_RW(32, 0x018, resetlen)
+
+/* CPC_REVISION - Indicates the revisison of the CPC */
 CPC_ACCESSOR_RO(32, 0x020, revision)
 
-/* Core Local & Core Other accessor functions */
+/* CPC_Cx_CMD - Instruct the CPC to take action on a core */
 CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
+#define CPC_Cx_CMD				GENMASK(3, 0)
+#define  CPC_Cx_CMD_CLOCKOFF			0x1
+#define  CPC_Cx_CMD_PWRDOWN			0x2
+#define  CPC_Cx_CMD_PWRUP			0x3
+#define  CPC_Cx_CMD_RESET			0x4
+
+/* CPC_Cx_STAT_CONF - Indicates core configuration & state */
 CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
+#define CPC_Cx_STAT_CONF_PWRUPE			BIT(23)
+#define CPC_Cx_STAT_CONF_SEQSTATE		GENMASK(22, 19)
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D0		0x0
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U0		0x1
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U1		0x2
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U2		0x3
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U3		0x4
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U4		0x5
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U5		0x6
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U6		0x7
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D1		0x8
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D3		0x9
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D2		0xa
+#define CPC_Cx_STAT_CONF_CLKGAT_IMPL		BIT(17)
+#define CPC_Cx_STAT_CONF_PWRDN_IMPL		BIT(16)
+#define CPC_Cx_STAT_CONF_EJTAG_PROBE		BIT(15)
+
+/* CPC_Cx_OTHER - Configure the core-other register block prior to CM 3 */
 CPC_CX_ACCESSOR_RW(32, 0x010, other)
+#define CPC_Cx_OTHER_CORENUM			GENMASK(23, 16)
+
+/* CPC_Cx_VP_STOP - Stop Virtual Processors (VPs) within a core from running */
 CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
+
+/* CPC_Cx_VP_START - Start Virtual Processors (VPs) within a core running */
 CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
-CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
-/* CPC_Cx_CMD register fields */
-#define CPC_Cx_CMD_SHF				0
-#define CPC_Cx_CMD_MSK				(_ULCAST_(0xf) << 0)
-#define  CPC_Cx_CMD_CLOCKOFF			(_ULCAST_(0x1) << 0)
-#define  CPC_Cx_CMD_PWRDOWN			(_ULCAST_(0x2) << 0)
-#define  CPC_Cx_CMD_PWRUP			(_ULCAST_(0x3) << 0)
-#define  CPC_Cx_CMD_RESET			(_ULCAST_(0x4) << 0)
-
-/* CPC_Cx_STAT_CONF register fields */
-#define CPC_Cx_STAT_CONF_PWRUPE_SHF		23
-#define CPC_Cx_STAT_CONF_PWRUPE_MSK		(_ULCAST_(0x1) << 23)
-#define CPC_Cx_STAT_CONF_SEQSTATE_SHF		19
-#define CPC_Cx_STAT_CONF_SEQSTATE_MSK		(_ULCAST_(0xf) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D0		(_ULCAST_(0x0) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U0		(_ULCAST_(0x1) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U1		(_ULCAST_(0x2) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U2		(_ULCAST_(0x3) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U3		(_ULCAST_(0x4) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U4		(_ULCAST_(0x5) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U5		(_ULCAST_(0x6) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U6		(_ULCAST_(0x7) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D1		(_ULCAST_(0x8) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D3		(_ULCAST_(0x9) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D2		(_ULCAST_(0xa) << 19)
-#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_SHF	17
-#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK	(_ULCAST_(0x1) << 17)
-#define CPC_Cx_STAT_CONF_PWRDN_IMPL_SHF		16
-#define CPC_Cx_STAT_CONF_PWRDN_IMPL_MSK		(_ULCAST_(0x1) << 16)
-#define CPC_Cx_STAT_CONF_EJTAG_PROBE_SHF	15
-#define CPC_Cx_STAT_CONF_EJTAG_PROBE_MSK	(_ULCAST_(0x1) << 15)
-
-/* CPC_Cx_OTHER register fields */
-#define CPC_Cx_OTHER_CORENUM_SHF		16
-#define CPC_Cx_OTHER_CORENUM_MSK		(_ULCAST_(0xff) << 16)
+/* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */
+CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
 #ifdef CONFIG_MIPS_CPC
 
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 690eefd0fb54..0e3ac6d05e75 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -89,7 +89,7 @@ void mips_cpc_lock_other(unsigned int core)
 	curr_core = current_cpu_data.core;
 	spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
 			  per_cpu(cpc_core_lock_flags, curr_core));
-	write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF);
+	write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM));
 
 	/*
 	 * Ensure the core-other region reflects the appropriate core &
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index 357b451c43a7..df1a1a5b58b9 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -692,7 +692,7 @@ static int __init cps_pm_init(void)
 	/* Detect whether a CPC is present */
 	if (mips_cpc_present()) {
 		/* Detect whether clock gating is implemented */
-		if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK)
+		if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL)
 			set_bit(CPS_PM_CLOCK_GATED, state_support);
 		else
 			pr_warn("pm-cps: CPC does not support clock gating\n");
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index b544d3df3b73..777e0193e8ed 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -253,7 +253,8 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 		timeout = 100;
 		while (true) {
 			stat = read_cpc_co_stat_conf();
-			seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK;
+			seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE;
+			seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE);
 
 			/* U6 == coherent execution, ie. the core is up */
 			if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6)
@@ -522,7 +523,8 @@ static void cps_cpu_die(unsigned int cpu)
 			mips_cm_lock_other(core, 0);
 			mips_cpc_lock_other(core);
 			stat = read_cpc_co_stat_conf();
-			stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK;
+			stat &= CPC_Cx_STAT_CONF_SEQSTATE;
+			stat >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE);
 			mips_cpc_unlock_other();
 			mips_cm_unlock_other();
 
@@ -544,7 +546,7 @@ static void cps_cpu_die(unsigned int cpu)
 			 */
 			if (WARN(ktime_after(ktime_get(), fail_time),
 				 "CPU%u hasn't powered down, seq. state %u\n",
-				 cpu, stat >> CPC_Cx_STAT_CONF_SEQSTATE_SHF))
+				 cpu, stat))
 				break;
 		} while (1);
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 05/19] MIPS: CPC: Use BIT/GENMASK for register fields, order & drop shifts
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Tidy up asm/mips-cpc.h in a similar way to what "MIPS: CM: Use
BIT/GENMASK for register fields, order & drop shifts" did for
asm/mips-cm.h.

We use BIT() & GENMASK() to simplify the definition of register fields,
drop the _SHF definitions since that information can be found in the
_MSK ones, and then drop the _MSK suffix.

Fields definitions are moved to be next to the appropriate register
definition, making it easier to link the two & keep everything ordered
by register address. Comments are added including the name of each
register & a brief description of its purpose which helps to understand
what registers are for, link them back to hardware documentation or grep
for them.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cpc.h | 79 +++++++++++++++++++++-------------------
 arch/mips/kernel/mips-cpc.c      |  2 +-
 arch/mips/kernel/pm-cps.c        |  2 +-
 arch/mips/kernel/smp-cps.c       |  8 ++--
 4 files changed, 49 insertions(+), 42 deletions(-)

diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 9de7addb59ba..6cd2847fc95b 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -76,55 +76,60 @@ static inline bool mips_cpc_present(void)
 	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
 	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name)
 
-/* GCB register accessor functions */
+/* CPC_ACCESS - Control core/IOCU access to CPC registers prior to CM 3 */
 CPC_ACCESSOR_RW(32, 0x000, access)
+
+/* CPC_SEQDEL - Configure delays between command sequencer steps */
 CPC_ACCESSOR_RW(32, 0x008, seqdel)
+
+/* CPC_RAIL - Configure the delay from rail power-up to stability */
 CPC_ACCESSOR_RW(32, 0x010, rail)
+
+/* CPC_RESETLEN - Configure the length of reset sequences */
 CPC_ACCESSOR_RW(32, 0x018, resetlen)
+
+/* CPC_REVISION - Indicates the revisison of the CPC */
 CPC_ACCESSOR_RO(32, 0x020, revision)
 
-/* Core Local & Core Other accessor functions */
+/* CPC_Cx_CMD - Instruct the CPC to take action on a core */
 CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
+#define CPC_Cx_CMD				GENMASK(3, 0)
+#define  CPC_Cx_CMD_CLOCKOFF			0x1
+#define  CPC_Cx_CMD_PWRDOWN			0x2
+#define  CPC_Cx_CMD_PWRUP			0x3
+#define  CPC_Cx_CMD_RESET			0x4
+
+/* CPC_Cx_STAT_CONF - Indicates core configuration & state */
 CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf)
+#define CPC_Cx_STAT_CONF_PWRUPE			BIT(23)
+#define CPC_Cx_STAT_CONF_SEQSTATE		GENMASK(22, 19)
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D0		0x0
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U0		0x1
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U1		0x2
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U2		0x3
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U3		0x4
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U4		0x5
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U5		0x6
+#define  CPC_Cx_STAT_CONF_SEQSTATE_U6		0x7
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D1		0x8
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D3		0x9
+#define  CPC_Cx_STAT_CONF_SEQSTATE_D2		0xa
+#define CPC_Cx_STAT_CONF_CLKGAT_IMPL		BIT(17)
+#define CPC_Cx_STAT_CONF_PWRDN_IMPL		BIT(16)
+#define CPC_Cx_STAT_CONF_EJTAG_PROBE		BIT(15)
+
+/* CPC_Cx_OTHER - Configure the core-other register block prior to CM 3 */
 CPC_CX_ACCESSOR_RW(32, 0x010, other)
+#define CPC_Cx_OTHER_CORENUM			GENMASK(23, 16)
+
+/* CPC_Cx_VP_STOP - Stop Virtual Processors (VPs) within a core from running */
 CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop)
+
+/* CPC_Cx_VP_START - Start Virtual Processors (VPs) within a core running */
 CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
-CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
-/* CPC_Cx_CMD register fields */
-#define CPC_Cx_CMD_SHF				0
-#define CPC_Cx_CMD_MSK				(_ULCAST_(0xf) << 0)
-#define  CPC_Cx_CMD_CLOCKOFF			(_ULCAST_(0x1) << 0)
-#define  CPC_Cx_CMD_PWRDOWN			(_ULCAST_(0x2) << 0)
-#define  CPC_Cx_CMD_PWRUP			(_ULCAST_(0x3) << 0)
-#define  CPC_Cx_CMD_RESET			(_ULCAST_(0x4) << 0)
-
-/* CPC_Cx_STAT_CONF register fields */
-#define CPC_Cx_STAT_CONF_PWRUPE_SHF		23
-#define CPC_Cx_STAT_CONF_PWRUPE_MSK		(_ULCAST_(0x1) << 23)
-#define CPC_Cx_STAT_CONF_SEQSTATE_SHF		19
-#define CPC_Cx_STAT_CONF_SEQSTATE_MSK		(_ULCAST_(0xf) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D0		(_ULCAST_(0x0) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U0		(_ULCAST_(0x1) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U1		(_ULCAST_(0x2) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U2		(_ULCAST_(0x3) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U3		(_ULCAST_(0x4) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U4		(_ULCAST_(0x5) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U5		(_ULCAST_(0x6) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_U6		(_ULCAST_(0x7) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D1		(_ULCAST_(0x8) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D3		(_ULCAST_(0x9) << 19)
-#define  CPC_Cx_STAT_CONF_SEQSTATE_D2		(_ULCAST_(0xa) << 19)
-#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_SHF	17
-#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK	(_ULCAST_(0x1) << 17)
-#define CPC_Cx_STAT_CONF_PWRDN_IMPL_SHF		16
-#define CPC_Cx_STAT_CONF_PWRDN_IMPL_MSK		(_ULCAST_(0x1) << 16)
-#define CPC_Cx_STAT_CONF_EJTAG_PROBE_SHF	15
-#define CPC_Cx_STAT_CONF_EJTAG_PROBE_MSK	(_ULCAST_(0x1) << 15)
-
-/* CPC_Cx_OTHER register fields */
-#define CPC_Cx_OTHER_CORENUM_SHF		16
-#define CPC_Cx_OTHER_CORENUM_MSK		(_ULCAST_(0xff) << 16)
+/* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */
+CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
 #ifdef CONFIG_MIPS_CPC
 
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 690eefd0fb54..0e3ac6d05e75 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -89,7 +89,7 @@ void mips_cpc_lock_other(unsigned int core)
 	curr_core = current_cpu_data.core;
 	spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
 			  per_cpu(cpc_core_lock_flags, curr_core));
-	write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF);
+	write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM));
 
 	/*
 	 * Ensure the core-other region reflects the appropriate core &
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index 357b451c43a7..df1a1a5b58b9 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -692,7 +692,7 @@ static int __init cps_pm_init(void)
 	/* Detect whether a CPC is present */
 	if (mips_cpc_present()) {
 		/* Detect whether clock gating is implemented */
-		if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK)
+		if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL)
 			set_bit(CPS_PM_CLOCK_GATED, state_support);
 		else
 			pr_warn("pm-cps: CPC does not support clock gating\n");
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index b544d3df3b73..777e0193e8ed 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -253,7 +253,8 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 		timeout = 100;
 		while (true) {
 			stat = read_cpc_co_stat_conf();
-			seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK;
+			seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE;
+			seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE);
 
 			/* U6 == coherent execution, ie. the core is up */
 			if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6)
@@ -522,7 +523,8 @@ static void cps_cpu_die(unsigned int cpu)
 			mips_cm_lock_other(core, 0);
 			mips_cpc_lock_other(core);
 			stat = read_cpc_co_stat_conf();
-			stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK;
+			stat &= CPC_Cx_STAT_CONF_SEQSTATE;
+			stat >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE);
 			mips_cpc_unlock_other();
 			mips_cm_unlock_other();
 
@@ -544,7 +546,7 @@ static void cps_cpu_die(unsigned int cpu)
 			 */
 			if (WARN(ktime_after(ktime_get(), fail_time),
 				 "CPU%u hasn't powered down, seq. state %u\n",
-				 cpu, stat >> CPC_Cx_STAT_CONF_SEQSTATE_SHF))
+				 cpu, stat))
 				break;
 		} while (1);
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 06/19] MIPS: CPS: Introduce register modify (set/clear/change) accessors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

For read-write registers introduce accessor functions that simplify the
task of modifying a subset of bits within the register. set_* functions
set bits to 1, clear_* functions clear bits to 0 & change_* functions
set bits specified in a mask to an arbitrary value.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cps.h | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 6ced7ba102b6..7ae32ad15599 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -71,6 +71,26 @@ static inline void write_##unit##_##name(uint##sz##_t val)		\
 	}								\
 }
 
+#define CPS_ACCESSOR_M(unit, sz, name)					\
+static inline void change_##unit##_##name(uint##sz##_t mask,		\
+					  uint##sz##_t val)		\
+{									\
+	uint##sz##_t reg_val = read_##unit##_##name();			\
+	reg_val &= ~mask;						\
+	reg_val |= val;							\
+	write_##unit##_##name(reg_val);					\
+}									\
+									\
+static inline void set_##unit##_##name(uint##sz##_t val)		\
+{									\
+	change_##unit##_##name(val, val);				\
+}									\
+									\
+static inline void clear_##unit##_##name(uint##sz##_t val)		\
+{									\
+	change_##unit##_##name(val, 0);					\
+}
+
 #define CPS_ACCESSOR_RO(unit, sz, off, name)				\
 	CPS_ACCESSOR_A(unit, off, name)					\
 	CPS_ACCESSOR_R(unit, sz, name)
@@ -82,6 +102,7 @@ static inline void write_##unit##_##name(uint##sz##_t val)		\
 #define CPS_ACCESSOR_RW(unit, sz, off, name)				\
 	CPS_ACCESSOR_A(unit, off, name)					\
 	CPS_ACCESSOR_R(unit, sz, name)					\
-	CPS_ACCESSOR_W(unit, sz, name)
+	CPS_ACCESSOR_W(unit, sz, name)					\
+	CPS_ACCESSOR_M(unit, sz, name)
 
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 06/19] MIPS: CPS: Introduce register modify (set/clear/change) accessors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

For read-write registers introduce accessor functions that simplify the
task of modifying a subset of bits within the register. set_* functions
set bits to 1, clear_* functions clear bits to 0 & change_* functions
set bits specified in a mask to an arbitrary value.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cps.h | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 6ced7ba102b6..7ae32ad15599 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -71,6 +71,26 @@ static inline void write_##unit##_##name(uint##sz##_t val)		\
 	}								\
 }
 
+#define CPS_ACCESSOR_M(unit, sz, name)					\
+static inline void change_##unit##_##name(uint##sz##_t mask,		\
+					  uint##sz##_t val)		\
+{									\
+	uint##sz##_t reg_val = read_##unit##_##name();			\
+	reg_val &= ~mask;						\
+	reg_val |= val;							\
+	write_##unit##_##name(reg_val);					\
+}									\
+									\
+static inline void set_##unit##_##name(uint##sz##_t val)		\
+{									\
+	change_##unit##_##name(val, val);				\
+}									\
+									\
+static inline void clear_##unit##_##name(uint##sz##_t val)		\
+{									\
+	change_##unit##_##name(val, 0);					\
+}
+
 #define CPS_ACCESSOR_RO(unit, sz, off, name)				\
 	CPS_ACCESSOR_A(unit, off, name)					\
 	CPS_ACCESSOR_R(unit, sz, name)
@@ -82,6 +102,7 @@ static inline void write_##unit##_##name(uint##sz##_t val)		\
 #define CPS_ACCESSOR_RW(unit, sz, off, name)				\
 	CPS_ACCESSOR_A(unit, off, name)					\
 	CPS_ACCESSOR_R(unit, sz, name)					\
-	CPS_ACCESSOR_W(unit, sz, name)
+	CPS_ACCESSOR_W(unit, sz, name)					\
+	CPS_ACCESSOR_M(unit, sz, name)
 
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 07/19] MIPS: CPS: Use change_*, set_* & clear_* where appropriate
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Make use of the new change_*, set_* & clear_* accessor functions for CPS
(CM, CPC & GIC) registers where doing so makes the code easier to read
or shortens it without adversely affecting readability.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/mips-cm.c |  4 +---
 arch/mips/kernel/smp-cps.c |  6 ++----
 arch/mips/mm/sc-mips.c     | 19 +++++--------------
 3 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 7bbe0308617f..aa62a9e5254c 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -233,9 +233,7 @@ int mips_cm_probe(void)
 	}
 
 	/* set default target to memory */
-	base_reg &= ~CM_GCR_BASE_CMDEFTGT;
-	base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
-	write_gcr_base(base_reg);
+	change_gcr_base(CM_GCR_BASE_CMDEFTGT, CM_GCR_BASE_CMDEFTGT_MEM);
 
 	/* disable CM regions */
 	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 777e0193e8ed..5729d2c77461 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -212,7 +212,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 
 static void boot_core(unsigned int core, unsigned int vpe_id)
 {
-	u32 access, stat, seq_state;
+	u32 stat, seq_state;
 	unsigned timeout;
 
 	/* Select the appropriate core */
@@ -228,9 +228,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 	write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
 
 	/* Ensure the core can access the GCRs */
-	access = read_gcr_access();
-	access |= 1 << core;
-	write_gcr_access(access);
+	set_gcr_access(1 << core);
 
 	if (mips_cpc_present()) {
 		/* Reset the core */
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 7f30397cb10d..cda878c0010b 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -69,28 +69,19 @@ static void mips_sc_prefetch_enable(void)
 		pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN;
 		write_gcr_l2_pft_control(pftctl);
 
-		pftctl = read_gcr_l2_pft_control_b();
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID;
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN;
-		write_gcr_l2_pft_control_b(pftctl);
+		set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
+					 CM_GCR_L2_PFT_CONTROL_B_CEN);
 	}
 }
 
 static void mips_sc_prefetch_disable(void)
 {
-	unsigned long pftctl;
-
 	if (mips_cm_revision() < CM_REV_CM2_5)
 		return;
 
-	pftctl = read_gcr_l2_pft_control();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN;
-	write_gcr_l2_pft_control(pftctl);
-
-	pftctl = read_gcr_l2_pft_control_b();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID;
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN;
-	write_gcr_l2_pft_control_b(pftctl);
+	clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN);
+	clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
+				   CM_GCR_L2_PFT_CONTROL_B_CEN);
 }
 
 static bool mips_sc_prefetch_is_enabled(void)
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 07/19] MIPS: CPS: Use change_*, set_* & clear_* where appropriate
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Make use of the new change_*, set_* & clear_* accessor functions for CPS
(CM, CPC & GIC) registers where doing so makes the code easier to read
or shortens it without adversely affecting readability.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/mips-cm.c |  4 +---
 arch/mips/kernel/smp-cps.c |  6 ++----
 arch/mips/mm/sc-mips.c     | 19 +++++--------------
 3 files changed, 8 insertions(+), 21 deletions(-)

diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 7bbe0308617f..aa62a9e5254c 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -233,9 +233,7 @@ int mips_cm_probe(void)
 	}
 
 	/* set default target to memory */
-	base_reg &= ~CM_GCR_BASE_CMDEFTGT;
-	base_reg |= CM_GCR_BASE_CMDEFTGT_MEM;
-	write_gcr_base(base_reg);
+	change_gcr_base(CM_GCR_BASE_CMDEFTGT, CM_GCR_BASE_CMDEFTGT_MEM);
 
 	/* disable CM regions */
 	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 777e0193e8ed..5729d2c77461 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -212,7 +212,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 
 static void boot_core(unsigned int core, unsigned int vpe_id)
 {
-	u32 access, stat, seq_state;
+	u32 stat, seq_state;
 	unsigned timeout;
 
 	/* Select the appropriate core */
@@ -228,9 +228,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 	write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
 
 	/* Ensure the core can access the GCRs */
-	access = read_gcr_access();
-	access |= 1 << core;
-	write_gcr_access(access);
+	set_gcr_access(1 << core);
 
 	if (mips_cpc_present()) {
 		/* Reset the core */
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 7f30397cb10d..cda878c0010b 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -69,28 +69,19 @@ static void mips_sc_prefetch_enable(void)
 		pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN;
 		write_gcr_l2_pft_control(pftctl);
 
-		pftctl = read_gcr_l2_pft_control_b();
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID;
-		pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN;
-		write_gcr_l2_pft_control_b(pftctl);
+		set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
+					 CM_GCR_L2_PFT_CONTROL_B_CEN);
 	}
 }
 
 static void mips_sc_prefetch_disable(void)
 {
-	unsigned long pftctl;
-
 	if (mips_cm_revision() < CM_REV_CM2_5)
 		return;
 
-	pftctl = read_gcr_l2_pft_control();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN;
-	write_gcr_l2_pft_control(pftctl);
-
-	pftctl = read_gcr_l2_pft_control_b();
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID;
-	pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN;
-	write_gcr_l2_pft_control_b(pftctl);
+	clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN);
+	clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID |
+				   CM_GCR_L2_PFT_CONTROL_B_CEN);
 }
 
 static bool mips_sc_prefetch_is_enabled(void)
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 08/19] MIPS: CPS: Add CM/CPC 3.5 register definitions
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Introduce definitions & accessors for a selection of Coherence Manager
(CM) & Cluster Power Controller (CPC) registers that are new with CM
v3.5 & the MIPS I6500. These are primarily registers that will be used
in supporting multiple CPU clusters.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h  | 54 ++++++++++++++++++++++++++++++++++++----
 arch/mips/include/asm/mips-cpc.h | 22 ++++++++++++++--
 2 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 4857d4ae97b7..225586bdd81c 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -114,10 +114,12 @@ static inline bool mips_cm_has_l2sync(void)
 #define MIPS_CM_L2SYNC_SIZE	0x1000
 
 #define GCR_ACCESSOR_RO(sz, off, name)					\
-	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name)
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
 
 #define GCR_ACCESSOR_RW(sz, off, name)					\
-	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name)
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
 
 #define GCR_CX_ACCESSOR_RO(sz, off, name)				\
 	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
@@ -129,6 +131,9 @@ static inline bool mips_cm_has_l2sync(void)
 
 /* GCR_CONFIG - Information about the system */
 GCR_ACCESSOR_RO(64, 0x000, config)
+#define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE	BIT_ULL(43)
+#define CM_GCR_CONFIG_CLUSTER_ID		GENMASK_ULL(39, 32)
+#define CM_GCR_CONFIG_NUM_CLUSTERS		GENMASK(29, 23)
 #define CM_GCR_CONFIG_NUMIOCU			GENMASK(15, 8)
 #define CM_GCR_CONFIG_PCORES			GENMASK(7, 0)
 
@@ -157,6 +162,7 @@ GCR_ACCESSOR_RO(32, 0x030, rev)
 #define CM_REV_CM2				CM_ENCODE_REV(6, 0)
 #define CM_REV_CM2_5				CM_ENCODE_REV(7, 0)
 #define CM_REV_CM3				CM_ENCODE_REV(8, 0)
+#define CM_REV_CM3_5				CM_ENCODE_REV(9, 0)
 
 /* GCR_ERR_CONTROL - Control error checking logic */
 GCR_ACCESSOR_RW(32, 0x038, err_control)
@@ -246,6 +252,33 @@ GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
 #define CM_GCR_L2_PFT_CONTROL_B_CEN		BIT(8)
 #define CM_GCR_L2_PFT_CONTROL_B_PORTID		GENMASK(7, 0)
 
+/* GCR_L2SM_COP - L2 cache op state machine control */
+GCR_ACCESSOR_RW(32, 0x620, l2sm_cop)
+#define CM_GCR_L2SM_COP_PRESENT			BIT(31)
+#define CM_GCR_L2SM_COP_RESULT			GENMASK(8, 6)
+#define  CM_GCR_L2SM_COP_RESULT_DONTCARE	0
+#define  CM_GCR_L2SM_COP_RESULT_DONE_OK		1
+#define  CM_GCR_L2SM_COP_RESULT_DONE_ERROR	2
+#define  CM_GCR_L2SM_COP_RESULT_ABORT_OK	3
+#define  CM_GCR_L2SM_COP_RESULT_ABORT_ERROR	4
+#define CM_GCR_L2SM_COP_RUNNING			BIT(5)
+#define CM_GCR_L2SM_COP_TYPE			GENMASK(4, 2)
+#define  CM_GCR_L2SM_COP_TYPE_IDX_WBINV		0
+#define  CM_GCR_L2SM_COP_TYPE_IDX_STORETAG	1
+#define  CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA	2
+#define  CM_GCR_L2SM_COP_TYPE_HIT_INV		4
+#define  CM_GCR_L2SM_COP_TYPE_HIT_WBINV		5
+#define  CM_GCR_L2SM_COP_TYPE_HIT_WB		6
+#define  CM_GCR_L2SM_COP_TYPE_FETCHLOCK		7
+#define CM_GCR_L2SM_COP_CMD			GENMASK(1, 0)
+#define  CM_GCR_L2SM_COP_CMD_START		1	/* only when idle */
+#define  CM_GCR_L2SM_COP_CMD_ABORT		3	/* only when running */
+
+/* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */
+GCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop)
+#define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES	GENMASK_ULL(63, 48)
+#define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG	GENMASK_ULL(47, 6)
+
 /* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */
 GCR_ACCESSOR_RW(64, 0x680, bev_base)
 
@@ -264,9 +297,18 @@ GCR_CX_ACCESSOR_RO(32, 0x010, config)
 
 /* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */
 GCR_CX_ACCESSOR_RW(32, 0x018, other)
-#define CM_GCR_Cx_OTHER_CORENUM			GENMASK(31, 16)
-#define CM3_GCR_Cx_OTHER_CORE			GENMASK(13, 8)
-#define CM3_GCR_Cx_OTHER_VP			GENMASK(2, 0)
+#define CM_GCR_Cx_OTHER_CORENUM			GENMASK(31, 16)	/* CM < 3 */
+#define CM_GCR_Cx_OTHER_CLUSTER_EN		BIT(31)		/* CM >= 3.5 */
+#define CM_GCR_Cx_OTHER_GIC_EN			BIT(30)		/* CM >= 3.5 */
+#define CM_GCR_Cx_OTHER_BLOCK			GENMASK(25, 24)	/* CM >= 3.5 */
+#define  CM_GCR_Cx_OTHER_BLOCK_LOCAL		0
+#define  CM_GCR_Cx_OTHER_BLOCK_GLOBAL		1
+#define  CM_GCR_Cx_OTHER_BLOCK_USER		2
+#define  CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH	3
+#define CM_GCR_Cx_OTHER_CLUSTER			GENMASK(21, 16)	/* CM >= 3.5 */
+#define CM3_GCR_Cx_OTHER_CORE			GENMASK(13, 8)	/* CM >= 3 */
+#define  CM_GCR_Cx_OTHER_CORE_CM		32
+#define CM3_GCR_Cx_OTHER_VP			GENMASK(2, 0)	/* CM >= 3 */
 
 /* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
 GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
@@ -274,6 +316,8 @@ GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
 
 /* GCR_Cx_ID - Identify the current core */
 GCR_CX_ACCESSOR_RO(32, 0x028, id)
+#define CM_GCR_Cx_ID_CLUSTER			GENMASK(15, 8)
+#define CM_GCR_Cx_ID_CORE			GENMASK(7, 0)
 
 /* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */
 GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 6cd2847fc95b..1d024cc6ccd8 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -63,10 +63,12 @@ static inline bool mips_cpc_present(void)
 #define MIPS_CPC_COCB_OFS	0x4000
 
 #define CPC_ACCESSOR_RO(sz, off, name)					\
-	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
 
 #define CPC_ACCESSOR_RW(sz, off, name)					\
-	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
 
 #define CPC_CX_ACCESSOR_RO(sz, off, name)				\
 	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
@@ -91,6 +93,19 @@ CPC_ACCESSOR_RW(32, 0x018, resetlen)
 /* CPC_REVISION - Indicates the revisison of the CPC */
 CPC_ACCESSOR_RO(32, 0x020, revision)
 
+/* CPC_PWRUP_CTL - Control power to the Coherence Manager (CM) */
+CPC_ACCESSOR_RW(32, 0x030, pwrup_ctl)
+#define CPC_PWRUP_CTL_CM_PWRUP			BIT(0)
+
+/* CPC_CONFIG - Mirrors GCR_CONFIG */
+CPC_ACCESSOR_RW(64, 0x138, config)
+
+/* CPC_SYS_CONFIG - Control cluster endianness */
+CPC_ACCESSOR_RW(32, 0x140, sys_config)
+#define CPC_SYS_CONFIG_BE_IMMEDIATE		BIT(2)
+#define CPC_SYS_CONFIG_BE_STATUS		BIT(1)
+#define CPC_SYS_CONFIG_BE			BIT(0)
+
 /* CPC_Cx_CMD - Instruct the CPC to take action on a core */
 CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
 #define CPC_Cx_CMD				GENMASK(3, 0)
@@ -131,6 +146,9 @@ CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
 /* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */
 CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
+/* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */
+CPC_CX_ACCESSOR_RW(32, 0x090, config)
+
 #ifdef CONFIG_MIPS_CPC
 
 /**
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 08/19] MIPS: CPS: Add CM/CPC 3.5 register definitions
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Introduce definitions & accessors for a selection of Coherence Manager
(CM) & Cluster Power Controller (CPC) registers that are new with CM
v3.5 & the MIPS I6500. These are primarily registers that will be used
in supporting multiple CPU clusters.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h  | 54 ++++++++++++++++++++++++++++++++++++----
 arch/mips/include/asm/mips-cpc.h | 22 ++++++++++++++--
 2 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 4857d4ae97b7..225586bdd81c 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -114,10 +114,12 @@ static inline bool mips_cm_has_l2sync(void)
 #define MIPS_CM_L2SYNC_SIZE	0x1000
 
 #define GCR_ACCESSOR_RO(sz, off, name)					\
-	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name)
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
 
 #define GCR_ACCESSOR_RW(sz, off, name)					\
-	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name)
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name)
 
 #define GCR_CX_ACCESSOR_RO(sz, off, name)				\
 	CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name)	\
@@ -129,6 +131,9 @@ static inline bool mips_cm_has_l2sync(void)
 
 /* GCR_CONFIG - Information about the system */
 GCR_ACCESSOR_RO(64, 0x000, config)
+#define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE	BIT_ULL(43)
+#define CM_GCR_CONFIG_CLUSTER_ID		GENMASK_ULL(39, 32)
+#define CM_GCR_CONFIG_NUM_CLUSTERS		GENMASK(29, 23)
 #define CM_GCR_CONFIG_NUMIOCU			GENMASK(15, 8)
 #define CM_GCR_CONFIG_PCORES			GENMASK(7, 0)
 
@@ -157,6 +162,7 @@ GCR_ACCESSOR_RO(32, 0x030, rev)
 #define CM_REV_CM2				CM_ENCODE_REV(6, 0)
 #define CM_REV_CM2_5				CM_ENCODE_REV(7, 0)
 #define CM_REV_CM3				CM_ENCODE_REV(8, 0)
+#define CM_REV_CM3_5				CM_ENCODE_REV(9, 0)
 
 /* GCR_ERR_CONTROL - Control error checking logic */
 GCR_ACCESSOR_RW(32, 0x038, err_control)
@@ -246,6 +252,33 @@ GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b)
 #define CM_GCR_L2_PFT_CONTROL_B_CEN		BIT(8)
 #define CM_GCR_L2_PFT_CONTROL_B_PORTID		GENMASK(7, 0)
 
+/* GCR_L2SM_COP - L2 cache op state machine control */
+GCR_ACCESSOR_RW(32, 0x620, l2sm_cop)
+#define CM_GCR_L2SM_COP_PRESENT			BIT(31)
+#define CM_GCR_L2SM_COP_RESULT			GENMASK(8, 6)
+#define  CM_GCR_L2SM_COP_RESULT_DONTCARE	0
+#define  CM_GCR_L2SM_COP_RESULT_DONE_OK		1
+#define  CM_GCR_L2SM_COP_RESULT_DONE_ERROR	2
+#define  CM_GCR_L2SM_COP_RESULT_ABORT_OK	3
+#define  CM_GCR_L2SM_COP_RESULT_ABORT_ERROR	4
+#define CM_GCR_L2SM_COP_RUNNING			BIT(5)
+#define CM_GCR_L2SM_COP_TYPE			GENMASK(4, 2)
+#define  CM_GCR_L2SM_COP_TYPE_IDX_WBINV		0
+#define  CM_GCR_L2SM_COP_TYPE_IDX_STORETAG	1
+#define  CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA	2
+#define  CM_GCR_L2SM_COP_TYPE_HIT_INV		4
+#define  CM_GCR_L2SM_COP_TYPE_HIT_WBINV		5
+#define  CM_GCR_L2SM_COP_TYPE_HIT_WB		6
+#define  CM_GCR_L2SM_COP_TYPE_FETCHLOCK		7
+#define CM_GCR_L2SM_COP_CMD			GENMASK(1, 0)
+#define  CM_GCR_L2SM_COP_CMD_START		1	/* only when idle */
+#define  CM_GCR_L2SM_COP_CMD_ABORT		3	/* only when running */
+
+/* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */
+GCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop)
+#define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES	GENMASK_ULL(63, 48)
+#define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG	GENMASK_ULL(47, 6)
+
 /* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */
 GCR_ACCESSOR_RW(64, 0x680, bev_base)
 
@@ -264,9 +297,18 @@ GCR_CX_ACCESSOR_RO(32, 0x010, config)
 
 /* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */
 GCR_CX_ACCESSOR_RW(32, 0x018, other)
-#define CM_GCR_Cx_OTHER_CORENUM			GENMASK(31, 16)
-#define CM3_GCR_Cx_OTHER_CORE			GENMASK(13, 8)
-#define CM3_GCR_Cx_OTHER_VP			GENMASK(2, 0)
+#define CM_GCR_Cx_OTHER_CORENUM			GENMASK(31, 16)	/* CM < 3 */
+#define CM_GCR_Cx_OTHER_CLUSTER_EN		BIT(31)		/* CM >= 3.5 */
+#define CM_GCR_Cx_OTHER_GIC_EN			BIT(30)		/* CM >= 3.5 */
+#define CM_GCR_Cx_OTHER_BLOCK			GENMASK(25, 24)	/* CM >= 3.5 */
+#define  CM_GCR_Cx_OTHER_BLOCK_LOCAL		0
+#define  CM_GCR_Cx_OTHER_BLOCK_GLOBAL		1
+#define  CM_GCR_Cx_OTHER_BLOCK_USER		2
+#define  CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH	3
+#define CM_GCR_Cx_OTHER_CLUSTER			GENMASK(21, 16)	/* CM >= 3.5 */
+#define CM3_GCR_Cx_OTHER_CORE			GENMASK(13, 8)	/* CM >= 3 */
+#define  CM_GCR_Cx_OTHER_CORE_CM		32
+#define CM3_GCR_Cx_OTHER_VP			GENMASK(2, 0)	/* CM >= 3 */
 
 /* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
 GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
@@ -274,6 +316,8 @@ GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
 
 /* GCR_Cx_ID - Identify the current core */
 GCR_CX_ACCESSOR_RO(32, 0x028, id)
+#define CM_GCR_Cx_ID_CLUSTER			GENMASK(15, 8)
+#define CM_GCR_Cx_ID_CORE			GENMASK(7, 0)
 
 /* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */
 GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 6cd2847fc95b..1d024cc6ccd8 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -63,10 +63,12 @@ static inline bool mips_cpc_present(void)
 #define MIPS_CPC_COCB_OFS	0x4000
 
 #define CPC_ACCESSOR_RO(sz, off, name)					\
-	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
 
 #define CPC_ACCESSOR_RW(sz, off, name)					\
-	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name)		\
+	CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name)
 
 #define CPC_CX_ACCESSOR_RO(sz, off, name)				\
 	CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name)	\
@@ -91,6 +93,19 @@ CPC_ACCESSOR_RW(32, 0x018, resetlen)
 /* CPC_REVISION - Indicates the revisison of the CPC */
 CPC_ACCESSOR_RO(32, 0x020, revision)
 
+/* CPC_PWRUP_CTL - Control power to the Coherence Manager (CM) */
+CPC_ACCESSOR_RW(32, 0x030, pwrup_ctl)
+#define CPC_PWRUP_CTL_CM_PWRUP			BIT(0)
+
+/* CPC_CONFIG - Mirrors GCR_CONFIG */
+CPC_ACCESSOR_RW(64, 0x138, config)
+
+/* CPC_SYS_CONFIG - Control cluster endianness */
+CPC_ACCESSOR_RW(32, 0x140, sys_config)
+#define CPC_SYS_CONFIG_BE_IMMEDIATE		BIT(2)
+#define CPC_SYS_CONFIG_BE_STATUS		BIT(1)
+#define CPC_SYS_CONFIG_BE			BIT(0)
+
 /* CPC_Cx_CMD - Instruct the CPC to take action on a core */
 CPC_CX_ACCESSOR_RW(32, 0x000, cmd)
 #define CPC_Cx_CMD				GENMASK(3, 0)
@@ -131,6 +146,9 @@ CPC_CX_ACCESSOR_RW(32, 0x028, vp_run)
 /* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */
 CPC_CX_ACCESSOR_RW(32, 0x030, vp_running)
 
+/* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */
+CPC_CX_ACCESSOR_RW(32, 0x090, config)
+
 #ifdef CONFIG_MIPS_CPC
 
 /**
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 09/19] MIPS: Add accessor & bit definitions for GlobalNumber
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

MIPSr6 introduces a GlobalNumber register, which is required when VPs
are implemented (ie. when multi-threading is supported) but otherwise
optional. The register contains sufficient information to uniquely
identify a VP within a system using its cluster number, core number & VP
ID.

In preparation for using this register & its fields, introduce an
accessor macro for it & define its various bits with the typical style
preprocessor macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index dbb0eceda2c6..e4ed1bc9a734 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -48,6 +48,7 @@
 #define CP0_ENTRYLO0 $2
 #define CP0_ENTRYLO1 $3
 #define CP0_CONF $3
+#define CP0_GLOBALNUMBER $3, 1
 #define CP0_CONTEXT $4
 #define CP0_PAGEMASK $5
 #define CP0_SEGCTL0 $5, 2
@@ -147,6 +148,16 @@
 #define MIPS_ENTRYLO_XI		(_ULCAST_(1) << (BITS_PER_LONG - 2))
 #define MIPS_ENTRYLO_RI		(_ULCAST_(1) << (BITS_PER_LONG - 1))
 
+/*
+ * MIPSr6+ GlobalNumber register definitions
+ */
+#define MIPS_GLOBALNUMBER_VP_SHF	0
+#define MIPS_GLOBALNUMBER_VP		(_ULCAST_(0xff) << MIPS_GLOBALNUMBER_VP_SHF)
+#define MIPS_GLOBALNUMBER_CORE_SHF	8
+#define MIPS_GLOBALNUMBER_CORE		(_ULCAST_(0xff) << MIPS_GLOBALNUMBER_CORE_SHF)
+#define MIPS_GLOBALNUMBER_CLUSTER_SHF	16
+#define MIPS_GLOBALNUMBER_CLUSTER	(_ULCAST_(0xf) << MIPS_GLOBALNUMBER_CLUSTER_SHF)
+
 /*
  * Values for PageMask register
  */
@@ -1446,6 +1457,8 @@ do {									\
 #define read_c0_conf()		__read_32bit_c0_register($3, 0)
 #define write_c0_conf(val)	__write_32bit_c0_register($3, 0, val)
 
+#define read_c0_globalnumber()	__read_32bit_c0_register($3, 1)
+
 #define read_c0_context()	__read_ulong_c0_register($4, 0)
 #define write_c0_context(val)	__write_ulong_c0_register($4, 0, val)
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 09/19] MIPS: Add accessor & bit definitions for GlobalNumber
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

MIPSr6 introduces a GlobalNumber register, which is required when VPs
are implemented (ie. when multi-threading is supported) but otherwise
optional. The register contains sufficient information to uniquely
identify a VP within a system using its cluster number, core number & VP
ID.

In preparation for using this register & its fields, introduce an
accessor macro for it & define its various bits with the typical style
preprocessor macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mipsregs.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index dbb0eceda2c6..e4ed1bc9a734 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -48,6 +48,7 @@
 #define CP0_ENTRYLO0 $2
 #define CP0_ENTRYLO1 $3
 #define CP0_CONF $3
+#define CP0_GLOBALNUMBER $3, 1
 #define CP0_CONTEXT $4
 #define CP0_PAGEMASK $5
 #define CP0_SEGCTL0 $5, 2
@@ -147,6 +148,16 @@
 #define MIPS_ENTRYLO_XI		(_ULCAST_(1) << (BITS_PER_LONG - 2))
 #define MIPS_ENTRYLO_RI		(_ULCAST_(1) << (BITS_PER_LONG - 1))
 
+/*
+ * MIPSr6+ GlobalNumber register definitions
+ */
+#define MIPS_GLOBALNUMBER_VP_SHF	0
+#define MIPS_GLOBALNUMBER_VP		(_ULCAST_(0xff) << MIPS_GLOBALNUMBER_VP_SHF)
+#define MIPS_GLOBALNUMBER_CORE_SHF	8
+#define MIPS_GLOBALNUMBER_CORE		(_ULCAST_(0xff) << MIPS_GLOBALNUMBER_CORE_SHF)
+#define MIPS_GLOBALNUMBER_CLUSTER_SHF	16
+#define MIPS_GLOBALNUMBER_CLUSTER	(_ULCAST_(0xf) << MIPS_GLOBALNUMBER_CLUSTER_SHF)
+
 /*
  * Values for PageMask register
  */
@@ -1446,6 +1457,8 @@ do {									\
 #define read_c0_conf()		__read_32bit_c0_register($3, 0)
 #define write_c0_conf(val)	__write_32bit_c0_register($3, 0, val)
 
+#define read_c0_globalnumber()	__read_32bit_c0_register($3, 1)
+
 #define read_c0_context()	__read_ulong_c0_register($4, 0)
 #define write_c0_context(val)	__write_ulong_c0_register($4, 0, val)
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 10/19] MIPS: CPS: Use GlobalNumber macros rather than magic numbers
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

We now have definitions for the GlobalNumber register in asm/mipsregs.h,
so use them in place of magic numbers in cps-vec.S.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/cps-vec.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index b849fe6aad94..d173b49f212d 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -327,8 +327,8 @@ LEAF(mips_cps_get_bootcfg)
 	 * to handle contiguous VP numbering, but no such systems yet
 	 * exist.
 	 */
-	mfc0	t9, $3, 1
-	andi	t9, t9, 0xff
+	mfc0	t9, CP0_GLOBALNUMBER
+	andi	t9, t9, MIPS_GLOBALNUMBER_VP
 #elif defined(CONFIG_MIPS_MT_SMP)
 	has_mt	ta2, 1f
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 10/19] MIPS: CPS: Use GlobalNumber macros rather than magic numbers
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

We now have definitions for the GlobalNumber register in asm/mipsregs.h,
so use them in place of magic numbers in cps-vec.S.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/cps-vec.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index b849fe6aad94..d173b49f212d 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -327,8 +327,8 @@ LEAF(mips_cps_get_bootcfg)
 	 * to handle contiguous VP numbering, but no such systems yet
 	 * exist.
 	 */
-	mfc0	t9, $3, 1
-	andi	t9, t9, 0xff
+	mfc0	t9, CP0_GLOBALNUMBER
+	andi	t9, t9, MIPS_GLOBALNUMBER_VP
 #elif defined(CONFIG_MIPS_MT_SMP)
 	has_mt	ta2, 1f
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 11/19] MIPS: Abstract CPU core & VP(E) ID access through accessor functions
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

We currently have fields in struct cpuinfo_mips for the core & VP(E) ID
of a particular CPU, and various pieces of code directly access those
fields. This patch abstracts such access by introducing accessor
functions cpu_core(), cpu_set_core(), cpu_vpe_id() & cpu_set_vpe_id()
and having code that needs to access these values call those functions
rather than directly accessing the struct cpuinfo_mips fields. This
prepares us for changes to the way in which those values are stored in
later patches.

The cpu_vpe_id() function is introduced even though we already had a
cpu_vpe_id() macro for a couple of reasons:

  1) It's more consistent with the core, and future cluster, accessors.

  2) It ensures a sensible return type without explicit casts.

  3) It's generally preferable to use functions rather than macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h      | 27 ++++++++++++++++++++++++---
 arch/mips/include/asm/mips-cm.h       |  2 +-
 arch/mips/include/asm/topology.h      |  2 +-
 arch/mips/kernel/cpu-probe.c          |  7 +++++--
 arch/mips/kernel/mips-cm.c            |  4 ++--
 arch/mips/kernel/mips-cpc.c           |  4 ++--
 arch/mips/kernel/pm-cps.c             |  6 +++---
 arch/mips/kernel/proc.c               |  6 +++---
 arch/mips/kernel/smp-bmips.c          |  2 +-
 arch/mips/kernel/smp-cps.c            | 28 ++++++++++++++--------------
 arch/mips/kernel/smp-mt.c             |  2 +-
 arch/mips/kernel/smp.c                |  8 ++++----
 arch/mips/loongson64/loongson-3/smp.c | 11 ++++++-----
 arch/mips/netlogic/common/smp.c       |  2 +-
 arch/mips/oprofile/op_model_mipsxx.c  |  4 ++--
 drivers/cpuidle/cpuidle-cps.c         |  2 +-
 16 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index cd6efb07c980..2b2f97023705 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -144,11 +144,32 @@ struct proc_cpuinfo_notifier_args {
 	unsigned long n;
 };
 
+static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
+{
+	return cpuinfo->core;
+}
+
+static inline void cpu_set_core(struct cpuinfo_mips *cpuinfo,
+				unsigned int core)
+{
+	cpuinfo->core = core;
+}
+
+static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
+{
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-# define cpu_vpe_id(cpuinfo)	((cpuinfo)->vpe_id)
-#else
-# define cpu_vpe_id(cpuinfo)	({ (void)cpuinfo; 0; })
+	return cpuinfo->vpe_id;
 #endif
+	return 0;
+}
+
+static inline void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo,
+				  unsigned int vpe)
+{
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
+	cpuinfo->vpe_id = vpe;
+#endif
+}
 
 static inline unsigned long cpu_asid_inc(void)
 {
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 225586bdd81c..6cfc0cc265d7 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -428,7 +428,7 @@ static inline unsigned int mips_cm_max_vp_width(void)
  */
 static inline unsigned int mips_cm_vp_id(unsigned int cpu)
 {
-	unsigned int core = cpu_data[cpu].core;
+	unsigned int core = cpu_core(&cpu_data[cpu]);
 	unsigned int vp = cpu_vpe_id(&cpu_data[cpu]);
 
 	return (core * mips_cm_max_vp_width()) + vp;
diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h
index 7afda4150a59..0673d2d0f2e6 100644
--- a/arch/mips/include/asm/topology.h
+++ b/arch/mips/include/asm/topology.h
@@ -13,7 +13,7 @@
 
 #ifdef CONFIG_SMP
 #define topology_physical_package_id(cpu)	(cpu_data[cpu].package)
-#define topology_core_id(cpu)			(cpu_data[cpu].core)
+#define topology_core_id(cpu)			(cpu_core(&cpu_data[cpu]))
 #define topology_core_cpumask(cpu)		(&cpu_core_map[cpu])
 #define topology_sibling_cpumask(cpu)		(&cpu_sibling_map[cpu])
 #endif
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 19ae0e279c86..ed39b8e98bc1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -919,9 +919,12 @@ static void decode_configs(struct cpuinfo_mips *c)
 
 #ifndef CONFIG_MIPS_CPS
 	if (cpu_has_mips_r2_r6) {
-		c->core = get_ebase_cpunum();
+		unsigned int core;
+
+		core = get_ebase_cpunum();
 		if (cpu_has_mipsmt)
-			c->core >>= fls(core_nvpes()) - 1;
+			core >>= fls(core_nvpes()) - 1;
+		cpu_set_core(c, core);
 	}
 #endif
 }
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index aa62a9e5254c..64ad8d0a6986 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -287,7 +287,7 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 		 * CM 2.5 & older, so have to ensure other VP(E)s don't
 		 * race with us.
 		 */
-		curr_core = current_cpu_data.core;
+		curr_core = cpu_core(&current_cpu_data);
 		spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
 				  per_cpu(cm_core_lock_flags, curr_core));
 
@@ -308,7 +308,7 @@ void mips_cm_unlock_other(void)
 	unsigned int curr_core;
 
 	if (mips_cm_revision() < CM_REV_CM3) {
-		curr_core = current_cpu_data.core;
+		curr_core = cpu_core(&current_cpu_data);
 		spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core),
 				       per_cpu(cm_core_lock_flags, curr_core));
 	} else {
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 0e3ac6d05e75..06952bb34395 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -86,7 +86,7 @@ void mips_cpc_lock_other(unsigned int core)
 		return;
 
 	preempt_disable();
-	curr_core = current_cpu_data.core;
+	curr_core = cpu_core(&current_cpu_data);
 	spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
 			  per_cpu(cpc_core_lock_flags, curr_core));
 	write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM));
@@ -106,7 +106,7 @@ void mips_cpc_unlock_other(void)
 		/* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */
 		return;
 
-	curr_core = current_cpu_data.core;
+	curr_core = cpu_core(&current_cpu_data);
 	spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core),
 			       per_cpu(cpc_core_lock_flags, curr_core));
 	preempt_enable();
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index df1a1a5b58b9..daff76056609 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -114,7 +114,7 @@ static void coupled_barrier(atomic_t *a, unsigned online)
 int cps_pm_enter_state(enum cps_pm_state state)
 {
 	unsigned cpu = smp_processor_id();
-	unsigned core = current_cpu_data.core;
+	unsigned core = cpu_core(&current_cpu_data);
 	unsigned online, left;
 	cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled);
 	u32 *core_ready_count, *nc_core_ready_count;
@@ -486,7 +486,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
 		* defined by the interAptiv & proAptiv SUMs as ensuring that the
 		*  operation resulting from the preceding store is complete.
 		*/
-		uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core);
+		uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu]));
 		uasm_i_sw(&p, t0, 0, r_pcohctl);
 		uasm_i_lw(&p, t0, 0, r_pcohctl);
 
@@ -640,7 +640,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
 static int cps_pm_online_cpu(unsigned int cpu)
 {
 	enum cps_pm_state state;
-	unsigned core = cpu_data[cpu].core;
+	unsigned core = cpu_core(&cpu_data[cpu]);
 	void *entry_fn, *core_rc;
 
 	for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 70604c753aa4..bd9bf528f19b 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -134,13 +134,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	seq_printf(m, "kscratch registers\t: %d\n",
 		      hweight8(cpu_data[n].kscratch_mask));
 	seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
-	seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
+	seq_printf(m, "core\t\t\t: %d\n", cpu_core(&cpu_data[n]));
 
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
 	if (cpu_has_mipsmt)
-		seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
+		seq_printf(m, "VPE\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n]));
 	else if (cpu_has_vp)
-		seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id);
+		seq_printf(m, "VP\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n]));
 #endif
 
 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index f86d755e3d75..4ac576c68034 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -245,7 +245,7 @@ static void bmips_init_secondary(void)
 		break;
 	case CPU_BMIPS5000:
 		write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
-		current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3;
+		cpu_set_core(&current_cpu_data, (read_c0_brcm_config() >> 25) & 3);
 		break;
 	}
 }
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 5729d2c77461..699459ed293b 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -76,10 +76,8 @@ static void __init cps_smp_setup(void)
 			smp_num_siblings = core_vpes;
 
 		for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
-			cpu_data[nvpes + v].core = c;
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-			cpu_data[nvpes + v].vpe_id = v;
-#endif
+			cpu_set_core(&cpu_data[nvpes + v], c);
+			cpu_set_vpe_id(&cpu_data[nvpes + v], v);
 		}
 
 		nvpes += core_vpes;
@@ -149,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 			cpu_has_dc_aliases ? "dcache aliasing" : "");
 
 		for_each_present_cpu(c) {
-			if (cpu_data[c].core)
+			if (cpu_core(&cpu_data[c]))
 				set_cpu_present(c, false);
 		}
 	}
@@ -189,7 +187,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	}
 
 	/* Mark this CPU as booted */
-	atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask,
+	atomic_set(&mips_cps_core_bootcfg[cpu_core(&current_cpu_data)].vpe_mask,
 		   1 << cpu_vpe_id(&current_cpu_data));
 
 	return;
@@ -284,7 +282,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 
 static void remote_vpe_boot(void *dummy)
 {
-	unsigned core = current_cpu_data.core;
+	unsigned core = cpu_core(&current_cpu_data);
 	struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
 
 	mips_cps_boot_vpes(core_cfg, cpu_vpe_id(&current_cpu_data));
@@ -292,7 +290,7 @@ static void remote_vpe_boot(void *dummy)
 
 static void cps_boot_secondary(int cpu, struct task_struct *idle)
 {
-	unsigned core = cpu_data[cpu].core;
+	unsigned core = cpu_core(&cpu_data[cpu]);
 	unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
 	struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
 	struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id];
@@ -321,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 		mips_cm_unlock_other();
 	}
 
-	if (core != current_cpu_data.core) {
+	if (core != cpu_core(&current_cpu_data)) {
 		/* Boot a VPE on another powered up core */
 		for (remote = 0; remote < NR_CPUS; remote++) {
-			if (cpu_data[remote].core != core)
+			if (cpu_core(&cpu_data[remote]) != core)
 				continue;
 			if (cpu_online(remote))
 				break;
@@ -401,7 +399,7 @@ static int cps_cpu_disable(void)
 	if (!cps_pm_support_state(CPS_PM_POWER_GATED))
 		return -EINVAL;
 
-	core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core];
+	core_cfg = &mips_cps_core_bootcfg[cpu_core(&current_cpu_data)];
 	atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
 	smp_mb__after_atomic();
 	set_cpu_online(cpu, false);
@@ -423,15 +421,17 @@ void play_dead(void)
 	local_irq_disable();
 	idle_task_exit();
 	cpu = smp_processor_id();
-	core = cpu_data[cpu].core;
+	core = cpu_core(&cpu_data[cpu]);
 	cpu_death = CPU_DEATH_POWER;
 
 	pr_debug("CPU%d going offline\n", cpu);
 
 	if (cpu_has_mipsmt || cpu_has_vp) {
+		core = cpu_core(&cpu_data[cpu]);
+
 		/* Look for another online VPE within the core */
 		for_each_online_cpu(cpu_death_sibling) {
-			if (cpu_data[cpu_death_sibling].core != core)
+			if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
 				continue;
 
 			/*
@@ -487,7 +487,7 @@ static void wait_for_sibling_halt(void *ptr_cpu)
 
 static void cps_cpu_die(unsigned int cpu)
 {
-	unsigned core = cpu_data[cpu].core;
+	unsigned core = cpu_core(&cpu_data[cpu]);
 	unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]);
 	ktime_t fail_time;
 	unsigned stat;
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 004ff5e8a820..5a7b5857d083 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -83,7 +83,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
 	if (tc != 0)
 		smvp_copy_vpe_config();
 
-	cpu_data[ncpu].vpe_id = tc;
+	cpu_set_vpe_id(&cpu_data[ncpu], tc);
 
 	return ncpu;
 }
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 20c1f9ac946a..a54e5857c227 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -97,7 +97,7 @@ static inline void set_cpu_sibling_map(int cpu)
 	if (smp_num_siblings > 1) {
 		for_each_cpu(i, &cpu_sibling_setup_map) {
 			if (cpu_data[cpu].package == cpu_data[i].package &&
-				    cpu_data[cpu].core == cpu_data[i].core) {
+			    cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
 				cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
 				cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
 			}
@@ -135,7 +135,7 @@ void calculate_cpu_foreign_map(void)
 		core_present = 0;
 		for_each_cpu(k, &temp_foreign_map)
 			if (cpu_data[i].package == cpu_data[k].package &&
-			    cpu_data[i].core == cpu_data[k].core)
+			    cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
 				core_present = 1;
 		if (!core_present)
 			cpumask_set_cpu(i, &temp_foreign_map);
@@ -186,9 +186,9 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 
 	if (mips_cpc_present()) {
 		for_each_cpu(cpu, mask) {
-			core = cpu_data[cpu].core;
+			core = cpu_core(&cpu_data[cpu]);
 
-			if (core == current_cpu_data.core)
+			if (core == cpu_core(&current_cpu_data))
 				continue;
 
 			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index 5b5a44f50b0b..bde64b0f1e47 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -319,8 +319,8 @@ static void loongson3_init_secondary(void)
 		loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]);
 
 	per_cpu(cpu_state, cpu) = CPU_ONLINE;
-	cpu_data[cpu].core =
-		cpu_logical_map(cpu) % loongson_sysconf.cores_per_package;
+	cpu_set_core(&cpu_data[cpu],
+		     cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
 	cpu_data[cpu].package =
 		cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
 
@@ -386,7 +386,8 @@ static void __init loongson3_smp_setup(void)
 	ipi_status0_regs_init();
 	ipi_en0_regs_init();
 	ipi_mailbox_buf_init();
-	cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
+	cpu_set_core(&cpu_data[0],
+		     cpu_logical_map(0) % loongson_sysconf.cores_per_package);
 	cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
 }
 
@@ -697,7 +698,7 @@ void play_dead(void)
 
 static int loongson3_disable_clock(unsigned int cpu)
 {
-	uint64_t core_id = cpu_data[cpu].core;
+	uint64_t core_id = cpu_core(&cpu_data[cpu]);
 	uint64_t package_id = cpu_data[cpu].package;
 
 	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
@@ -711,7 +712,7 @@ static int loongson3_disable_clock(unsigned int cpu)
 
 static int loongson3_enable_clock(unsigned int cpu)
 {
-	uint64_t core_id = cpu_data[cpu].core;
+	uint64_t core_id = cpu_core(&cpu_data[cpu]);
 	uint64_t package_id = cpu_data[cpu].package;
 
 	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index eac3f2950b14..615027863f54 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -122,7 +122,7 @@ static void nlm_init_secondary(void)
 	int hwtid;
 
 	hwtid = hard_smp_processor_id();
-	current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;
+	cpu_set_core(&current_cpu_data, hwtid / NLM_THREADS_PER_CORE);
 	current_cpu_data.package = nlm_nodeid();
 	nlm_percpu_init(hwtid);
 	nlm_smp_irq_init(hwtid);
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index c57da6f13929..c3e4c18ef8d4 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -38,9 +38,9 @@ static int perfcount_irq;
 #ifdef CONFIG_MIPS_MT_SMP
 static int cpu_has_mipsmt_pertccounters;
 #define WHAT		(MIPS_PERFCTRL_MT_EN_VPE | \
-			 M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
+			 M_PERFCTL_VPEID(cpu_vpe_id(&current_cpu_data)))
 #define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
-			0 : cpu_data[smp_processor_id()].vpe_id)
+			0 : cpu_vpe_id(&current_cpu_data))
 
 /*
  * The number of bits to shift to convert between counters per core and
diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
index 12b9145913de..6041b6104f3d 100644
--- a/drivers/cpuidle/cpuidle-cps.c
+++ b/drivers/cpuidle/cpuidle-cps.c
@@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
 	 * TODO: don't treat core 0 specially, just prevent the final core
 	 * TODO: remap interrupt affinity temporarily
 	 */
-	if (!cpu_data[dev->cpu].core && (index > STATE_NC_WAIT))
+	if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
 		index = STATE_NC_WAIT;
 
 	/* Select the appropriate cps_pm_state */
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 11/19] MIPS: Abstract CPU core & VP(E) ID access through accessor functions
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

We currently have fields in struct cpuinfo_mips for the core & VP(E) ID
of a particular CPU, and various pieces of code directly access those
fields. This patch abstracts such access by introducing accessor
functions cpu_core(), cpu_set_core(), cpu_vpe_id() & cpu_set_vpe_id()
and having code that needs to access these values call those functions
rather than directly accessing the struct cpuinfo_mips fields. This
prepares us for changes to the way in which those values are stored in
later patches.

The cpu_vpe_id() function is introduced even though we already had a
cpu_vpe_id() macro for a couple of reasons:

  1) It's more consistent with the core, and future cluster, accessors.

  2) It ensures a sensible return type without explicit casts.

  3) It's generally preferable to use functions rather than macros.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h      | 27 ++++++++++++++++++++++++---
 arch/mips/include/asm/mips-cm.h       |  2 +-
 arch/mips/include/asm/topology.h      |  2 +-
 arch/mips/kernel/cpu-probe.c          |  7 +++++--
 arch/mips/kernel/mips-cm.c            |  4 ++--
 arch/mips/kernel/mips-cpc.c           |  4 ++--
 arch/mips/kernel/pm-cps.c             |  6 +++---
 arch/mips/kernel/proc.c               |  6 +++---
 arch/mips/kernel/smp-bmips.c          |  2 +-
 arch/mips/kernel/smp-cps.c            | 28 ++++++++++++++--------------
 arch/mips/kernel/smp-mt.c             |  2 +-
 arch/mips/kernel/smp.c                |  8 ++++----
 arch/mips/loongson64/loongson-3/smp.c | 11 ++++++-----
 arch/mips/netlogic/common/smp.c       |  2 +-
 arch/mips/oprofile/op_model_mipsxx.c  |  4 ++--
 drivers/cpuidle/cpuidle-cps.c         |  2 +-
 16 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index cd6efb07c980..2b2f97023705 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -144,11 +144,32 @@ struct proc_cpuinfo_notifier_args {
 	unsigned long n;
 };
 
+static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
+{
+	return cpuinfo->core;
+}
+
+static inline void cpu_set_core(struct cpuinfo_mips *cpuinfo,
+				unsigned int core)
+{
+	cpuinfo->core = core;
+}
+
+static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
+{
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-# define cpu_vpe_id(cpuinfo)	((cpuinfo)->vpe_id)
-#else
-# define cpu_vpe_id(cpuinfo)	({ (void)cpuinfo; 0; })
+	return cpuinfo->vpe_id;
 #endif
+	return 0;
+}
+
+static inline void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo,
+				  unsigned int vpe)
+{
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
+	cpuinfo->vpe_id = vpe;
+#endif
+}
 
 static inline unsigned long cpu_asid_inc(void)
 {
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 225586bdd81c..6cfc0cc265d7 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -428,7 +428,7 @@ static inline unsigned int mips_cm_max_vp_width(void)
  */
 static inline unsigned int mips_cm_vp_id(unsigned int cpu)
 {
-	unsigned int core = cpu_data[cpu].core;
+	unsigned int core = cpu_core(&cpu_data[cpu]);
 	unsigned int vp = cpu_vpe_id(&cpu_data[cpu]);
 
 	return (core * mips_cm_max_vp_width()) + vp;
diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h
index 7afda4150a59..0673d2d0f2e6 100644
--- a/arch/mips/include/asm/topology.h
+++ b/arch/mips/include/asm/topology.h
@@ -13,7 +13,7 @@
 
 #ifdef CONFIG_SMP
 #define topology_physical_package_id(cpu)	(cpu_data[cpu].package)
-#define topology_core_id(cpu)			(cpu_data[cpu].core)
+#define topology_core_id(cpu)			(cpu_core(&cpu_data[cpu]))
 #define topology_core_cpumask(cpu)		(&cpu_core_map[cpu])
 #define topology_sibling_cpumask(cpu)		(&cpu_sibling_map[cpu])
 #endif
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 19ae0e279c86..ed39b8e98bc1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -919,9 +919,12 @@ static void decode_configs(struct cpuinfo_mips *c)
 
 #ifndef CONFIG_MIPS_CPS
 	if (cpu_has_mips_r2_r6) {
-		c->core = get_ebase_cpunum();
+		unsigned int core;
+
+		core = get_ebase_cpunum();
 		if (cpu_has_mipsmt)
-			c->core >>= fls(core_nvpes()) - 1;
+			core >>= fls(core_nvpes()) - 1;
+		cpu_set_core(c, core);
 	}
 #endif
 }
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index aa62a9e5254c..64ad8d0a6986 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -287,7 +287,7 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 		 * CM 2.5 & older, so have to ensure other VP(E)s don't
 		 * race with us.
 		 */
-		curr_core = current_cpu_data.core;
+		curr_core = cpu_core(&current_cpu_data);
 		spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
 				  per_cpu(cm_core_lock_flags, curr_core));
 
@@ -308,7 +308,7 @@ void mips_cm_unlock_other(void)
 	unsigned int curr_core;
 
 	if (mips_cm_revision() < CM_REV_CM3) {
-		curr_core = current_cpu_data.core;
+		curr_core = cpu_core(&current_cpu_data);
 		spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core),
 				       per_cpu(cm_core_lock_flags, curr_core));
 	} else {
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 0e3ac6d05e75..06952bb34395 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -86,7 +86,7 @@ void mips_cpc_lock_other(unsigned int core)
 		return;
 
 	preempt_disable();
-	curr_core = current_cpu_data.core;
+	curr_core = cpu_core(&current_cpu_data);
 	spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core),
 			  per_cpu(cpc_core_lock_flags, curr_core));
 	write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM));
@@ -106,7 +106,7 @@ void mips_cpc_unlock_other(void)
 		/* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */
 		return;
 
-	curr_core = current_cpu_data.core;
+	curr_core = cpu_core(&current_cpu_data);
 	spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core),
 			       per_cpu(cpc_core_lock_flags, curr_core));
 	preempt_enable();
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index df1a1a5b58b9..daff76056609 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -114,7 +114,7 @@ static void coupled_barrier(atomic_t *a, unsigned online)
 int cps_pm_enter_state(enum cps_pm_state state)
 {
 	unsigned cpu = smp_processor_id();
-	unsigned core = current_cpu_data.core;
+	unsigned core = cpu_core(&current_cpu_data);
 	unsigned online, left;
 	cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled);
 	u32 *core_ready_count, *nc_core_ready_count;
@@ -486,7 +486,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
 		* defined by the interAptiv & proAptiv SUMs as ensuring that the
 		*  operation resulting from the preceding store is complete.
 		*/
-		uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core);
+		uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu]));
 		uasm_i_sw(&p, t0, 0, r_pcohctl);
 		uasm_i_lw(&p, t0, 0, r_pcohctl);
 
@@ -640,7 +640,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
 static int cps_pm_online_cpu(unsigned int cpu)
 {
 	enum cps_pm_state state;
-	unsigned core = cpu_data[cpu].core;
+	unsigned core = cpu_core(&cpu_data[cpu]);
 	void *entry_fn, *core_rc;
 
 	for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) {
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 70604c753aa4..bd9bf528f19b 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -134,13 +134,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	seq_printf(m, "kscratch registers\t: %d\n",
 		      hweight8(cpu_data[n].kscratch_mask));
 	seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
-	seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
+	seq_printf(m, "core\t\t\t: %d\n", cpu_core(&cpu_data[n]));
 
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
 	if (cpu_has_mipsmt)
-		seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
+		seq_printf(m, "VPE\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n]));
 	else if (cpu_has_vp)
-		seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id);
+		seq_printf(m, "VP\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n]));
 #endif
 
 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index f86d755e3d75..4ac576c68034 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -245,7 +245,7 @@ static void bmips_init_secondary(void)
 		break;
 	case CPU_BMIPS5000:
 		write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
-		current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3;
+		cpu_set_core(&current_cpu_data, (read_c0_brcm_config() >> 25) & 3);
 		break;
 	}
 }
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 5729d2c77461..699459ed293b 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -76,10 +76,8 @@ static void __init cps_smp_setup(void)
 			smp_num_siblings = core_vpes;
 
 		for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
-			cpu_data[nvpes + v].core = c;
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-			cpu_data[nvpes + v].vpe_id = v;
-#endif
+			cpu_set_core(&cpu_data[nvpes + v], c);
+			cpu_set_vpe_id(&cpu_data[nvpes + v], v);
 		}
 
 		nvpes += core_vpes;
@@ -149,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 			cpu_has_dc_aliases ? "dcache aliasing" : "");
 
 		for_each_present_cpu(c) {
-			if (cpu_data[c].core)
+			if (cpu_core(&cpu_data[c]))
 				set_cpu_present(c, false);
 		}
 	}
@@ -189,7 +187,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	}
 
 	/* Mark this CPU as booted */
-	atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask,
+	atomic_set(&mips_cps_core_bootcfg[cpu_core(&current_cpu_data)].vpe_mask,
 		   1 << cpu_vpe_id(&current_cpu_data));
 
 	return;
@@ -284,7 +282,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 
 static void remote_vpe_boot(void *dummy)
 {
-	unsigned core = current_cpu_data.core;
+	unsigned core = cpu_core(&current_cpu_data);
 	struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
 
 	mips_cps_boot_vpes(core_cfg, cpu_vpe_id(&current_cpu_data));
@@ -292,7 +290,7 @@ static void remote_vpe_boot(void *dummy)
 
 static void cps_boot_secondary(int cpu, struct task_struct *idle)
 {
-	unsigned core = cpu_data[cpu].core;
+	unsigned core = cpu_core(&cpu_data[cpu]);
 	unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
 	struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
 	struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id];
@@ -321,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 		mips_cm_unlock_other();
 	}
 
-	if (core != current_cpu_data.core) {
+	if (core != cpu_core(&current_cpu_data)) {
 		/* Boot a VPE on another powered up core */
 		for (remote = 0; remote < NR_CPUS; remote++) {
-			if (cpu_data[remote].core != core)
+			if (cpu_core(&cpu_data[remote]) != core)
 				continue;
 			if (cpu_online(remote))
 				break;
@@ -401,7 +399,7 @@ static int cps_cpu_disable(void)
 	if (!cps_pm_support_state(CPS_PM_POWER_GATED))
 		return -EINVAL;
 
-	core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core];
+	core_cfg = &mips_cps_core_bootcfg[cpu_core(&current_cpu_data)];
 	atomic_sub(1 << cpu_vpe_id(&current_cpu_data), &core_cfg->vpe_mask);
 	smp_mb__after_atomic();
 	set_cpu_online(cpu, false);
@@ -423,15 +421,17 @@ void play_dead(void)
 	local_irq_disable();
 	idle_task_exit();
 	cpu = smp_processor_id();
-	core = cpu_data[cpu].core;
+	core = cpu_core(&cpu_data[cpu]);
 	cpu_death = CPU_DEATH_POWER;
 
 	pr_debug("CPU%d going offline\n", cpu);
 
 	if (cpu_has_mipsmt || cpu_has_vp) {
+		core = cpu_core(&cpu_data[cpu]);
+
 		/* Look for another online VPE within the core */
 		for_each_online_cpu(cpu_death_sibling) {
-			if (cpu_data[cpu_death_sibling].core != core)
+			if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
 				continue;
 
 			/*
@@ -487,7 +487,7 @@ static void wait_for_sibling_halt(void *ptr_cpu)
 
 static void cps_cpu_die(unsigned int cpu)
 {
-	unsigned core = cpu_data[cpu].core;
+	unsigned core = cpu_core(&cpu_data[cpu]);
 	unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]);
 	ktime_t fail_time;
 	unsigned stat;
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 004ff5e8a820..5a7b5857d083 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -83,7 +83,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
 	if (tc != 0)
 		smvp_copy_vpe_config();
 
-	cpu_data[ncpu].vpe_id = tc;
+	cpu_set_vpe_id(&cpu_data[ncpu], tc);
 
 	return ncpu;
 }
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 20c1f9ac946a..a54e5857c227 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -97,7 +97,7 @@ static inline void set_cpu_sibling_map(int cpu)
 	if (smp_num_siblings > 1) {
 		for_each_cpu(i, &cpu_sibling_setup_map) {
 			if (cpu_data[cpu].package == cpu_data[i].package &&
-				    cpu_data[cpu].core == cpu_data[i].core) {
+			    cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
 				cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
 				cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
 			}
@@ -135,7 +135,7 @@ void calculate_cpu_foreign_map(void)
 		core_present = 0;
 		for_each_cpu(k, &temp_foreign_map)
 			if (cpu_data[i].package == cpu_data[k].package &&
-			    cpu_data[i].core == cpu_data[k].core)
+			    cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
 				core_present = 1;
 		if (!core_present)
 			cpumask_set_cpu(i, &temp_foreign_map);
@@ -186,9 +186,9 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 
 	if (mips_cpc_present()) {
 		for_each_cpu(cpu, mask) {
-			core = cpu_data[cpu].core;
+			core = cpu_core(&cpu_data[cpu]);
 
-			if (core == current_cpu_data.core)
+			if (core == cpu_core(&current_cpu_data))
 				continue;
 
 			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index 5b5a44f50b0b..bde64b0f1e47 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -319,8 +319,8 @@ static void loongson3_init_secondary(void)
 		loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]);
 
 	per_cpu(cpu_state, cpu) = CPU_ONLINE;
-	cpu_data[cpu].core =
-		cpu_logical_map(cpu) % loongson_sysconf.cores_per_package;
+	cpu_set_core(&cpu_data[cpu],
+		     cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
 	cpu_data[cpu].package =
 		cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
 
@@ -386,7 +386,8 @@ static void __init loongson3_smp_setup(void)
 	ipi_status0_regs_init();
 	ipi_en0_regs_init();
 	ipi_mailbox_buf_init();
-	cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
+	cpu_set_core(&cpu_data[0],
+		     cpu_logical_map(0) % loongson_sysconf.cores_per_package);
 	cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
 }
 
@@ -697,7 +698,7 @@ void play_dead(void)
 
 static int loongson3_disable_clock(unsigned int cpu)
 {
-	uint64_t core_id = cpu_data[cpu].core;
+	uint64_t core_id = cpu_core(&cpu_data[cpu]);
 	uint64_t package_id = cpu_data[cpu].package;
 
 	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
@@ -711,7 +712,7 @@ static int loongson3_disable_clock(unsigned int cpu)
 
 static int loongson3_enable_clock(unsigned int cpu)
 {
-	uint64_t core_id = cpu_data[cpu].core;
+	uint64_t core_id = cpu_core(&cpu_data[cpu]);
 	uint64_t package_id = cpu_data[cpu].package;
 
 	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index eac3f2950b14..615027863f54 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -122,7 +122,7 @@ static void nlm_init_secondary(void)
 	int hwtid;
 
 	hwtid = hard_smp_processor_id();
-	current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;
+	cpu_set_core(&current_cpu_data, hwtid / NLM_THREADS_PER_CORE);
 	current_cpu_data.package = nlm_nodeid();
 	nlm_percpu_init(hwtid);
 	nlm_smp_irq_init(hwtid);
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index c57da6f13929..c3e4c18ef8d4 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -38,9 +38,9 @@ static int perfcount_irq;
 #ifdef CONFIG_MIPS_MT_SMP
 static int cpu_has_mipsmt_pertccounters;
 #define WHAT		(MIPS_PERFCTRL_MT_EN_VPE | \
-			 M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
+			 M_PERFCTL_VPEID(cpu_vpe_id(&current_cpu_data)))
 #define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
-			0 : cpu_data[smp_processor_id()].vpe_id)
+			0 : cpu_vpe_id(&current_cpu_data))
 
 /*
  * The number of bits to shift to convert between counters per core and
diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
index 12b9145913de..6041b6104f3d 100644
--- a/drivers/cpuidle/cpuidle-cps.c
+++ b/drivers/cpuidle/cpuidle-cps.c
@@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
 	 * TODO: don't treat core 0 specially, just prevent the final core
 	 * TODO: remap interrupt affinity temporarily
 	 */
-	if (!cpu_data[dev->cpu].core && (index > STATE_NC_WAIT))
+	if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
 		index = STATE_NC_WAIT;
 
 	/* Select the appropriate cps_pm_state */
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 12/19] MIPS: Store core & VP IDs in GlobalNumber-style variable
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

This patch modifies the way we store core & VP IDs such that we store
them in a single 32 bit integer whose format matches that of the MIPSr6
GlobalNumber register. Whereas we have previously stored core & VP IDs
in separate fields, storing them in a single GlobalNumber-like field:

  1) Reduces the size of struct cpuinfo_mips by 4 bytes, and will allow
     it to not grow when cluster support is added.

  2) Gives us a natural place to store cluster number, which matches up
     with what the architecture provides.

  3) Will be useful in the future as a parameter to the MIPSr6 GINVI
     instruction to specify a target CPU whose icache that instruction
     should operate on.

The cpu_set*() accessor functions are moved out of the asm/cpu-info.h
header in order to allow them to use the WARN_ON macro, which is
unusable in asm/cpu-info.h due to include ordering.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h | 39 +++++++++++++--------------------------
 arch/mips/kernel/cpu-probe.c     | 22 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 2b2f97023705..9ae927282b12 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -15,6 +15,8 @@
 #include <linux/cache.h>
 #include <linux/types.h>
 
+#include <asm/mipsregs.h>
+
 /*
  * Descriptor for a cache
  */
@@ -77,16 +79,9 @@ struct cpuinfo_mips {
 	struct cache_desc	tcache; /* Tertiary/split secondary cache */
 	int			srsets; /* Shadow register sets */
 	int			package;/* physical package number */
-	int			core;	/* physical core number */
+	unsigned int		globalnumber;
 #ifdef CONFIG_64BIT
 	int			vmbits; /* Virtual memory size in bits */
-#endif
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-	/*
-	 * There is not necessarily a 1:1 mapping of VPE num to CPU number
-	 * in particular on multi-core systems.
-	 */
-	int			vpe_id;	 /* Virtual Processor number */
 #endif
 	void			*data;	/* Additional data */
 	unsigned int		watch_reg_count;   /* Number that exist */
@@ -146,31 +141,23 @@ struct proc_cpuinfo_notifier_args {
 
 static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
 {
-	return cpuinfo->core;
-}
-
-static inline void cpu_set_core(struct cpuinfo_mips *cpuinfo,
-				unsigned int core)
-{
-	cpuinfo->core = core;
+	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
+		MIPS_GLOBALNUMBER_CORE_SHF;
 }
 
 static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 {
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-	return cpuinfo->vpe_id;
-#endif
-	return 0;
-}
+	/* Optimisation for systems where VP(E)s aren't used */
+	if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
+		return 0;
 
-static inline void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo,
-				  unsigned int vpe)
-{
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-	cpuinfo->vpe_id = vpe;
-#endif
+	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >>
+		MIPS_GLOBALNUMBER_VP_SHF;
 }
 
+extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
+extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
+
 static inline unsigned long cpu_asid_inc(void)
 {
 	return 1 << CONFIG_MIPS_ASID_SHIFT;
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ed39b8e98bc1..d428e856085c 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2098,3 +2098,25 @@ void cpu_report(void)
 	if (cpu_has_msa)
 		pr_info("MSA revision is: %08x\n", c->msa_id);
 }
+
+void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core)
+{
+	/* Ensure the core number fits in the field */
+	WARN_ON(core > (MIPS_GLOBALNUMBER_CORE >> MIPS_GLOBALNUMBER_CORE_SHF));
+
+	cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CORE;
+	cpuinfo->globalnumber |= core << MIPS_GLOBALNUMBER_CORE_SHF;
+}
+
+void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe)
+{
+	/* Ensure the VP(E) ID fits in the field */
+	WARN_ON(vpe > (MIPS_GLOBALNUMBER_VP >> MIPS_GLOBALNUMBER_VP_SHF));
+
+	/* Ensure we're not using VP(E)s without support */
+	WARN_ON(vpe && !IS_ENABLED(CONFIG_MIPS_MT_SMP) &&
+		!IS_ENABLED(CONFIG_CPU_MIPSR6));
+
+	cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP;
+	cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF;
+}
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 12/19] MIPS: Store core & VP IDs in GlobalNumber-style variable
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

This patch modifies the way we store core & VP IDs such that we store
them in a single 32 bit integer whose format matches that of the MIPSr6
GlobalNumber register. Whereas we have previously stored core & VP IDs
in separate fields, storing them in a single GlobalNumber-like field:

  1) Reduces the size of struct cpuinfo_mips by 4 bytes, and will allow
     it to not grow when cluster support is added.

  2) Gives us a natural place to store cluster number, which matches up
     with what the architecture provides.

  3) Will be useful in the future as a parameter to the MIPSr6 GINVI
     instruction to specify a target CPU whose icache that instruction
     should operate on.

The cpu_set*() accessor functions are moved out of the asm/cpu-info.h
header in order to allow them to use the WARN_ON macro, which is
unusable in asm/cpu-info.h due to include ordering.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h | 39 +++++++++++++--------------------------
 arch/mips/kernel/cpu-probe.c     | 22 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 2b2f97023705..9ae927282b12 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -15,6 +15,8 @@
 #include <linux/cache.h>
 #include <linux/types.h>
 
+#include <asm/mipsregs.h>
+
 /*
  * Descriptor for a cache
  */
@@ -77,16 +79,9 @@ struct cpuinfo_mips {
 	struct cache_desc	tcache; /* Tertiary/split secondary cache */
 	int			srsets; /* Shadow register sets */
 	int			package;/* physical package number */
-	int			core;	/* physical core number */
+	unsigned int		globalnumber;
 #ifdef CONFIG_64BIT
 	int			vmbits; /* Virtual memory size in bits */
-#endif
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-	/*
-	 * There is not necessarily a 1:1 mapping of VPE num to CPU number
-	 * in particular on multi-core systems.
-	 */
-	int			vpe_id;	 /* Virtual Processor number */
 #endif
 	void			*data;	/* Additional data */
 	unsigned int		watch_reg_count;   /* Number that exist */
@@ -146,31 +141,23 @@ struct proc_cpuinfo_notifier_args {
 
 static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
 {
-	return cpuinfo->core;
-}
-
-static inline void cpu_set_core(struct cpuinfo_mips *cpuinfo,
-				unsigned int core)
-{
-	cpuinfo->core = core;
+	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
+		MIPS_GLOBALNUMBER_CORE_SHF;
 }
 
 static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 {
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-	return cpuinfo->vpe_id;
-#endif
-	return 0;
-}
+	/* Optimisation for systems where VP(E)s aren't used */
+	if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
+		return 0;
 
-static inline void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo,
-				  unsigned int vpe)
-{
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-	cpuinfo->vpe_id = vpe;
-#endif
+	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >>
+		MIPS_GLOBALNUMBER_VP_SHF;
 }
 
+extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
+extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
+
 static inline unsigned long cpu_asid_inc(void)
 {
 	return 1 << CONFIG_MIPS_ASID_SHIFT;
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ed39b8e98bc1..d428e856085c 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2098,3 +2098,25 @@ void cpu_report(void)
 	if (cpu_has_msa)
 		pr_info("MSA revision is: %08x\n", c->msa_id);
 }
+
+void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core)
+{
+	/* Ensure the core number fits in the field */
+	WARN_ON(core > (MIPS_GLOBALNUMBER_CORE >> MIPS_GLOBALNUMBER_CORE_SHF));
+
+	cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CORE;
+	cpuinfo->globalnumber |= core << MIPS_GLOBALNUMBER_CORE_SHF;
+}
+
+void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe)
+{
+	/* Ensure the VP(E) ID fits in the field */
+	WARN_ON(vpe > (MIPS_GLOBALNUMBER_VP >> MIPS_GLOBALNUMBER_VP_SHF));
+
+	/* Ensure we're not using VP(E)s without support */
+	WARN_ON(vpe && !IS_ENABLED(CONFIG_MIPS_MT_SMP) &&
+		!IS_ENABLED(CONFIG_CPU_MIPSR6));
+
+	cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP;
+	cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF;
+}
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 13/19] MIPS: Unify checks for sibling CPUs
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Up until now we have open-coded checks for whether CPUs are siblings,
with slight variations on whether we consider the package ID or not.

This will only get more complex when we introduce cluster support, so in
preparation for that this patch introduces a cpus_are_siblings()
function which can be used to check whether or not 2 CPUs are siblings
in a consistent manner.

By checking globalnumber with the VP ID masked out this also has the
neat side effect of being ready for multi-cluster systems already.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h | 17 +++++++++++++++++
 arch/mips/kernel/smp-cps.c       |  8 ++++----
 arch/mips/kernel/smp.c           | 12 +++++-------
 drivers/cpuidle/cpuidle-cps.c    |  2 +-
 drivers/irqchip/irq-mips-cpu.c   |  2 +-
 5 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 9ae927282b12..0c61bdc82a53 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -158,6 +158,23 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
 extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
 
+static inline bool cpus_are_siblings(int cpua, int cpub)
+{
+	struct cpuinfo_mips *infoa = &cpu_data[cpua];
+	struct cpuinfo_mips *infob = &cpu_data[cpub];
+	unsigned int gnuma, gnumb;
+
+	if (infoa->package != infob->package)
+		return false;
+
+	gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+	gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+	if (gnuma != gnumb)
+		return false;
+
+	return true;
+}
+
 static inline unsigned long cpu_asid_inc(void)
 {
 	return 1 << CONFIG_MIPS_ASID_SHIFT;
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 699459ed293b..8cc508809466 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -147,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 			cpu_has_dc_aliases ? "dcache aliasing" : "");
 
 		for_each_present_cpu(c) {
-			if (cpu_core(&cpu_data[c]))
+			if (!cpus_are_siblings(smp_processor_id(), c))
 				set_cpu_present(c, false);
 		}
 	}
@@ -319,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 		mips_cm_unlock_other();
 	}
 
-	if (core != cpu_core(&current_cpu_data)) {
+	if (!cpus_are_siblings(cpu, smp_processor_id())) {
 		/* Boot a VPE on another powered up core */
 		for (remote = 0; remote < NR_CPUS; remote++) {
-			if (cpu_core(&cpu_data[remote]) != core)
+			if (!cpus_are_siblings(cpu, remote))
 				continue;
 			if (cpu_online(remote))
 				break;
@@ -431,7 +431,7 @@ void play_dead(void)
 
 		/* Look for another online VPE within the core */
 		for_each_online_cpu(cpu_death_sibling) {
-			if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
+			if (!cpus_are_siblings(cpu, cpu_death_sibling))
 				continue;
 
 			/*
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index a54e5857c227..4cc43892b959 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu)
 
 	if (smp_num_siblings > 1) {
 		for_each_cpu(i, &cpu_sibling_setup_map) {
-			if (cpu_data[cpu].package == cpu_data[i].package &&
-			    cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
+			if (cpus_are_siblings(cpu, i)) {
 				cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
 				cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
 			}
@@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void)
 	for_each_online_cpu(i) {
 		core_present = 0;
 		for_each_cpu(k, &temp_foreign_map)
-			if (cpu_data[i].package == cpu_data[k].package &&
-			    cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
+			if (cpus_are_siblings(i, k))
 				core_present = 1;
 		if (!core_present)
 			cpumask_set_cpu(i, &temp_foreign_map);
@@ -186,11 +184,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 
 	if (mips_cpc_present()) {
 		for_each_cpu(cpu, mask) {
-			core = cpu_core(&cpu_data[cpu]);
-
-			if (core == cpu_core(&current_cpu_data))
+			if (cpus_are_siblings(cpu, smp_processor_id()))
 				continue;
 
+			core = cpu_core(&cpu_data[cpu]);
+
 			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
 				mips_cm_lock_other(core, 0);
 				mips_cpc_lock_other(core);
diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
index 6041b6104f3d..72b5e47286b4 100644
--- a/drivers/cpuidle/cpuidle-cps.c
+++ b/drivers/cpuidle/cpuidle-cps.c
@@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
 	 * TODO: don't treat core 0 specially, just prevent the final core
 	 * TODO: remap interrupt affinity temporarily
 	 */
-	if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
+	if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
 		index = STATE_NC_WAIT;
 
 	/* Select the appropriate cps_pm_state */
diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
index 14461cbfab2f..66f97fde13d8 100644
--- a/drivers/irqchip/irq-mips-cpu.c
+++ b/drivers/irqchip/irq-mips-cpu.c
@@ -101,7 +101,7 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
 	local_irq_save(flags);
 
 	/* We can only send IPIs to VPEs within the local core */
-	WARN_ON(cpu_data[cpu].core != current_cpu_data.core);
+	WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
 
 	vpflags = dvpe();
 	settc(cpu_vpe_id(&cpu_data[cpu]));
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 13/19] MIPS: Unify checks for sibling CPUs
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Up until now we have open-coded checks for whether CPUs are siblings,
with slight variations on whether we consider the package ID or not.

This will only get more complex when we introduce cluster support, so in
preparation for that this patch introduces a cpus_are_siblings()
function which can be used to check whether or not 2 CPUs are siblings
in a consistent manner.

By checking globalnumber with the VP ID masked out this also has the
neat side effect of being ready for multi-cluster systems already.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h | 17 +++++++++++++++++
 arch/mips/kernel/smp-cps.c       |  8 ++++----
 arch/mips/kernel/smp.c           | 12 +++++-------
 drivers/cpuidle/cpuidle-cps.c    |  2 +-
 drivers/irqchip/irq-mips-cpu.c   |  2 +-
 5 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 9ae927282b12..0c61bdc82a53 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -158,6 +158,23 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
 extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
 
+static inline bool cpus_are_siblings(int cpua, int cpub)
+{
+	struct cpuinfo_mips *infoa = &cpu_data[cpua];
+	struct cpuinfo_mips *infob = &cpu_data[cpub];
+	unsigned int gnuma, gnumb;
+
+	if (infoa->package != infob->package)
+		return false;
+
+	gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+	gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+	if (gnuma != gnumb)
+		return false;
+
+	return true;
+}
+
 static inline unsigned long cpu_asid_inc(void)
 {
 	return 1 << CONFIG_MIPS_ASID_SHIFT;
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 699459ed293b..8cc508809466 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -147,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 			cpu_has_dc_aliases ? "dcache aliasing" : "");
 
 		for_each_present_cpu(c) {
-			if (cpu_core(&cpu_data[c]))
+			if (!cpus_are_siblings(smp_processor_id(), c))
 				set_cpu_present(c, false);
 		}
 	}
@@ -319,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 		mips_cm_unlock_other();
 	}
 
-	if (core != cpu_core(&current_cpu_data)) {
+	if (!cpus_are_siblings(cpu, smp_processor_id())) {
 		/* Boot a VPE on another powered up core */
 		for (remote = 0; remote < NR_CPUS; remote++) {
-			if (cpu_core(&cpu_data[remote]) != core)
+			if (!cpus_are_siblings(cpu, remote))
 				continue;
 			if (cpu_online(remote))
 				break;
@@ -431,7 +431,7 @@ void play_dead(void)
 
 		/* Look for another online VPE within the core */
 		for_each_online_cpu(cpu_death_sibling) {
-			if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
+			if (!cpus_are_siblings(cpu, cpu_death_sibling))
 				continue;
 
 			/*
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index a54e5857c227..4cc43892b959 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu)
 
 	if (smp_num_siblings > 1) {
 		for_each_cpu(i, &cpu_sibling_setup_map) {
-			if (cpu_data[cpu].package == cpu_data[i].package &&
-			    cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
+			if (cpus_are_siblings(cpu, i)) {
 				cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
 				cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
 			}
@@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void)
 	for_each_online_cpu(i) {
 		core_present = 0;
 		for_each_cpu(k, &temp_foreign_map)
-			if (cpu_data[i].package == cpu_data[k].package &&
-			    cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
+			if (cpus_are_siblings(i, k))
 				core_present = 1;
 		if (!core_present)
 			cpumask_set_cpu(i, &temp_foreign_map);
@@ -186,11 +184,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 
 	if (mips_cpc_present()) {
 		for_each_cpu(cpu, mask) {
-			core = cpu_core(&cpu_data[cpu]);
-
-			if (core == cpu_core(&current_cpu_data))
+			if (cpus_are_siblings(cpu, smp_processor_id()))
 				continue;
 
+			core = cpu_core(&cpu_data[cpu]);
+
 			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
 				mips_cm_lock_other(core, 0);
 				mips_cpc_lock_other(core);
diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
index 6041b6104f3d..72b5e47286b4 100644
--- a/drivers/cpuidle/cpuidle-cps.c
+++ b/drivers/cpuidle/cpuidle-cps.c
@@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
 	 * TODO: don't treat core 0 specially, just prevent the final core
 	 * TODO: remap interrupt affinity temporarily
 	 */
-	if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
+	if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
 		index = STATE_NC_WAIT;
 
 	/* Select the appropriate cps_pm_state */
diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
index 14461cbfab2f..66f97fde13d8 100644
--- a/drivers/irqchip/irq-mips-cpu.c
+++ b/drivers/irqchip/irq-mips-cpu.c
@@ -101,7 +101,7 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
 	local_irq_save(flags);
 
 	/* We can only send IPIs to VPEs within the local core */
-	WARN_ON(cpu_data[cpu].core != current_cpu_data.core);
+	WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
 
 	vpflags = dvpe();
 	settc(cpu_vpe_id(&cpu_data[cpu]));
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 14/19] MIPS: Add CPU cluster number accessors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Introduce cpu_cluster() & cpu_set_cluster() accessor functions in the
same vein as cpu_core(), cpu_vpe_id() & their set variants. These will
be used in further patches to allow users to get or set a CPUs cluster
number.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h | 11 +++++++++++
 arch/mips/kernel/cpu-probe.c     | 10 ++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 0c61bdc82a53..a41059d47d31 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -139,6 +139,16 @@ struct proc_cpuinfo_notifier_args {
 	unsigned long n;
 };
 
+static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo)
+{
+	/* Optimisation for systems where multiple clusters aren't used */
+	if (!IS_ENABLED(CONFIG_CPU_MIPSR6))
+		return 0;
+
+	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >>
+		MIPS_GLOBALNUMBER_CLUSTER_SHF;
+}
+
 static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
 {
 	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
@@ -155,6 +165,7 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 		MIPS_GLOBALNUMBER_VP_SHF;
 }
 
+extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster);
 extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
 extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d428e856085c..a5fd5c2162e1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2099,6 +2099,16 @@ void cpu_report(void)
 		pr_info("MSA revision is: %08x\n", c->msa_id);
 }
 
+void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster)
+{
+	/* Ensure the core number fits in the field */
+	WARN_ON(cluster > (MIPS_GLOBALNUMBER_CLUSTER >>
+			   MIPS_GLOBALNUMBER_CLUSTER_SHF));
+
+	cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CLUSTER;
+	cpuinfo->globalnumber |= cluster << MIPS_GLOBALNUMBER_CLUSTER_SHF;
+}
+
 void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core)
 {
 	/* Ensure the core number fits in the field */
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 14/19] MIPS: Add CPU cluster number accessors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Introduce cpu_cluster() & cpu_set_cluster() accessor functions in the
same vein as cpu_core(), cpu_vpe_id() & their set variants. These will
be used in further patches to allow users to get or set a CPUs cluster
number.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/cpu-info.h | 11 +++++++++++
 arch/mips/kernel/cpu-probe.c     | 10 ++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index 0c61bdc82a53..a41059d47d31 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -139,6 +139,16 @@ struct proc_cpuinfo_notifier_args {
 	unsigned long n;
 };
 
+static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo)
+{
+	/* Optimisation for systems where multiple clusters aren't used */
+	if (!IS_ENABLED(CONFIG_CPU_MIPSR6))
+		return 0;
+
+	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >>
+		MIPS_GLOBALNUMBER_CLUSTER_SHF;
+}
+
 static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
 {
 	return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
@@ -155,6 +165,7 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 		MIPS_GLOBALNUMBER_VP_SHF;
 }
 
+extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster);
 extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
 extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d428e856085c..a5fd5c2162e1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2099,6 +2099,16 @@ void cpu_report(void)
 		pr_info("MSA revision is: %08x\n", c->msa_id);
 }
 
+void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster)
+{
+	/* Ensure the core number fits in the field */
+	WARN_ON(cluster > (MIPS_GLOBALNUMBER_CLUSTER >>
+			   MIPS_GLOBALNUMBER_CLUSTER_SHF));
+
+	cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CLUSTER;
+	cpuinfo->globalnumber |= cluster << MIPS_GLOBALNUMBER_CLUSTER_SHF;
+}
+
 void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core)
 {
 	/* Ensure the core number fits in the field */
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 15/19] MIPS: CM: Add cluster & block args to mips_cm_lock_other()
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

With CM >= 3.5 we have the notion of multiple clusters & can access
their CM, CPC & GIC registers via the apporpriate redirect/other
register blocks. In order to allow for this introduce cluster & block
arguments to mips_cm_lock_other() which configures the redirect/other
region to point at the appropriate cluster, core, VP & register block.

Since we now have 4 arguments to mips_cm_lock_other() & a common use is
likely to be to target the cluster, core & VP corresponding to a
particular Linux CPU number we also add a new mips_cm_lock_other_cpu()
helper function which handles that without the caller needing to
manually pull out the cluster, core & VP numbers.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h | 45 ++++++++++++++++++++++++++++++++---------
 arch/mips/kernel/mips-cm.c      | 19 ++++++++++++++---
 arch/mips/kernel/smp-cps.c      | 10 ++++-----
 arch/mips/kernel/smp.c          |  2 +-
 4 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 6cfc0cc265d7..d42cc8e76dc2 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -437,29 +437,56 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu)
 #ifdef CONFIG_MIPS_CM
 
 /**
- * mips_cm_lock_other - lock access to another core
+ * mips_cm_lock_other - lock access to redirect/other region
+ * @cluster: the other cluster to be accessed
  * @core: the other core to be accessed
  * @vp: the VP within the other core to be accessed
+ * @block: the register block to be accessed
  *
- * Call before operating upon a core via the 'other' register region in
- * order to prevent the region being moved during access. Must be followed
- * by a call to mips_cm_unlock_other.
+ * Configure the redirect/other region for the local core/VP (depending upon
+ * the CM revision) to target the specified @cluster, @core, @vp & register
+ * @block. Must be called before using the redirect/other region, and followed
+ * by a call to mips_cm_unlock_other() when access to the redirect/other region
+ * is complete.
+ *
+ * This function acquires a spinlock such that code between it &
+ * mips_cm_unlock_other() calls cannot be pre-empted by anything which may
+ * reconfigure the redirect/other region, and cannot be interfered with by
+ * another VP in the core. As such calls to this function should not be nested.
  */
-extern void mips_cm_lock_other(unsigned int core, unsigned int vp);
+extern void mips_cm_lock_other(unsigned int cluster, unsigned int core,
+			       unsigned int vp, unsigned int block);
 
 /**
- * mips_cm_unlock_other - unlock access to another core
+ * mips_cm_unlock_other - unlock access to redirect/other region
  *
- * Call after operating upon another core via the 'other' register region.
- * Must be called after mips_cm_lock_other.
+ * Must be called after mips_cm_lock_other() once all required access to the
+ * redirect/other region has been completed.
  */
 extern void mips_cm_unlock_other(void);
 
 #else /* !CONFIG_MIPS_CM */
 
-static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { }
+static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core,
+				      unsigned int vp, unsigned int block) { }
 static inline void mips_cm_unlock_other(void) { }
 
 #endif /* !CONFIG_MIPS_CM */
 
+/**
+ * mips_cm_lock_other_cpu - lock access to redirect/other region
+ * @cpu: the other CPU whose register we want to access
+ *
+ * Configure the redirect/other region for the local core/VP (depending upon
+ * the CM revision) to target the specified @cpu & register @block. This is
+ * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number
+ * for convenience.
+ */
+static inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block)
+{
+	struct cpuinfo_mips *d = &cpu_data[cpu];
+
+	mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block);
+}
+
 #endif /* __MIPS_ASM_MIPS_CM_H__ */
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 64ad8d0a6986..602c6ec9c01d 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -257,17 +257,28 @@ int mips_cm_probe(void)
 	return 0;
 }
 
-void mips_cm_lock_other(unsigned int core, unsigned int vp)
+void mips_cm_lock_other(unsigned int cluster, unsigned int core,
+			unsigned int vp, unsigned int block)
 {
-	unsigned curr_core;
+	unsigned int curr_core, cm_rev;
 	u32 val;
 
+	cm_rev = mips_cm_revision();
 	preempt_disable();
 
-	if (mips_cm_revision() >= CM_REV_CM3) {
+	if (cm_rev >= CM_REV_CM3) {
 		val = core << __ffs(CM3_GCR_Cx_OTHER_CORE);
 		val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP);
 
+		if (cm_rev >= CM_REV_CM3_5) {
+			val |= CM_GCR_Cx_OTHER_CLUSTER_EN;
+			val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER);
+			val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK);
+		} else {
+			WARN_ON(cluster != 0);
+			WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
+		}
+
 		/*
 		 * We need to disable interrupts in SMP systems in order to
 		 * ensure that we don't interrupt the caller with code which
@@ -280,7 +291,9 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 		spin_lock_irqsave(this_cpu_ptr(&cm_core_lock),
 				  *this_cpu_ptr(&cm_core_lock_flags));
 	} else {
+		WARN_ON(cluster != 0);
 		WARN_ON(vp != 0);
+		WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 
 		/*
 		 * We only have a GCR_CL_OTHER per core in systems with
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 8cc508809466..7aac84ffc2af 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -52,7 +52,7 @@ static unsigned core_vpe_count(unsigned core)
 		&& (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
 		return 1;
 
-	mips_cm_lock_other(core, 0);
+	mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE;
 	mips_cm_unlock_other();
 	return cfg + 1;
@@ -214,7 +214,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 	unsigned timeout;
 
 	/* Select the appropriate core */
-	mips_cm_lock_other(core, 0);
+	mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 
 	/* Set its reset vector */
 	write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
@@ -313,7 +313,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 	}
 
 	if (cpu_has_vp) {
-		mips_cm_lock_other(core, vpe_id);
+		mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 		core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry);
 		write_gcr_co_reset_base(core_entry);
 		mips_cm_unlock_other();
@@ -518,7 +518,7 @@ static void cps_cpu_die(unsigned int cpu)
 		 */
 		fail_time = ktime_add_ms(ktime_get(), 2000);
 		do {
-			mips_cm_lock_other(core, 0);
+			mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 			mips_cpc_lock_other(core);
 			stat = read_cpc_co_stat_conf();
 			stat &= CPC_Cx_STAT_CONF_SEQSTATE;
@@ -562,7 +562,7 @@ static void cps_cpu_die(unsigned int cpu)
 			panic("Failed to call remote sibling CPU\n");
 	} else if (cpu_has_vp) {
 		do {
-			mips_cm_lock_other(core, vpe_id);
+			mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 			stat = read_cpc_co_vp_running();
 			mips_cm_unlock_other();
 		} while (stat & (1 << vpe_id));
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 4cc43892b959..6248a5a3ec9e 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -190,7 +190,7 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 			core = cpu_core(&cpu_data[cpu]);
 
 			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
-				mips_cm_lock_other(core, 0);
+				mips_cm_lock_other_cpu(cpu, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 				mips_cpc_lock_other(core);
 				write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
 				mips_cpc_unlock_other();
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 15/19] MIPS: CM: Add cluster & block args to mips_cm_lock_other()
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

With CM >= 3.5 we have the notion of multiple clusters & can access
their CM, CPC & GIC registers via the apporpriate redirect/other
register blocks. In order to allow for this introduce cluster & block
arguments to mips_cm_lock_other() which configures the redirect/other
region to point at the appropriate cluster, core, VP & register block.

Since we now have 4 arguments to mips_cm_lock_other() & a common use is
likely to be to target the cluster, core & VP corresponding to a
particular Linux CPU number we also add a new mips_cm_lock_other_cpu()
helper function which handles that without the caller needing to
manually pull out the cluster, core & VP numbers.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h | 45 ++++++++++++++++++++++++++++++++---------
 arch/mips/kernel/mips-cm.c      | 19 ++++++++++++++---
 arch/mips/kernel/smp-cps.c      | 10 ++++-----
 arch/mips/kernel/smp.c          |  2 +-
 4 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 6cfc0cc265d7..d42cc8e76dc2 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -437,29 +437,56 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu)
 #ifdef CONFIG_MIPS_CM
 
 /**
- * mips_cm_lock_other - lock access to another core
+ * mips_cm_lock_other - lock access to redirect/other region
+ * @cluster: the other cluster to be accessed
  * @core: the other core to be accessed
  * @vp: the VP within the other core to be accessed
+ * @block: the register block to be accessed
  *
- * Call before operating upon a core via the 'other' register region in
- * order to prevent the region being moved during access. Must be followed
- * by a call to mips_cm_unlock_other.
+ * Configure the redirect/other region for the local core/VP (depending upon
+ * the CM revision) to target the specified @cluster, @core, @vp & register
+ * @block. Must be called before using the redirect/other region, and followed
+ * by a call to mips_cm_unlock_other() when access to the redirect/other region
+ * is complete.
+ *
+ * This function acquires a spinlock such that code between it &
+ * mips_cm_unlock_other() calls cannot be pre-empted by anything which may
+ * reconfigure the redirect/other region, and cannot be interfered with by
+ * another VP in the core. As such calls to this function should not be nested.
  */
-extern void mips_cm_lock_other(unsigned int core, unsigned int vp);
+extern void mips_cm_lock_other(unsigned int cluster, unsigned int core,
+			       unsigned int vp, unsigned int block);
 
 /**
- * mips_cm_unlock_other - unlock access to another core
+ * mips_cm_unlock_other - unlock access to redirect/other region
  *
- * Call after operating upon another core via the 'other' register region.
- * Must be called after mips_cm_lock_other.
+ * Must be called after mips_cm_lock_other() once all required access to the
+ * redirect/other region has been completed.
  */
 extern void mips_cm_unlock_other(void);
 
 #else /* !CONFIG_MIPS_CM */
 
-static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { }
+static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core,
+				      unsigned int vp, unsigned int block) { }
 static inline void mips_cm_unlock_other(void) { }
 
 #endif /* !CONFIG_MIPS_CM */
 
+/**
+ * mips_cm_lock_other_cpu - lock access to redirect/other region
+ * @cpu: the other CPU whose register we want to access
+ *
+ * Configure the redirect/other region for the local core/VP (depending upon
+ * the CM revision) to target the specified @cpu & register @block. This is
+ * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number
+ * for convenience.
+ */
+static inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block)
+{
+	struct cpuinfo_mips *d = &cpu_data[cpu];
+
+	mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block);
+}
+
 #endif /* __MIPS_ASM_MIPS_CM_H__ */
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 64ad8d0a6986..602c6ec9c01d 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -257,17 +257,28 @@ int mips_cm_probe(void)
 	return 0;
 }
 
-void mips_cm_lock_other(unsigned int core, unsigned int vp)
+void mips_cm_lock_other(unsigned int cluster, unsigned int core,
+			unsigned int vp, unsigned int block)
 {
-	unsigned curr_core;
+	unsigned int curr_core, cm_rev;
 	u32 val;
 
+	cm_rev = mips_cm_revision();
 	preempt_disable();
 
-	if (mips_cm_revision() >= CM_REV_CM3) {
+	if (cm_rev >= CM_REV_CM3) {
 		val = core << __ffs(CM3_GCR_Cx_OTHER_CORE);
 		val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP);
 
+		if (cm_rev >= CM_REV_CM3_5) {
+			val |= CM_GCR_Cx_OTHER_CLUSTER_EN;
+			val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER);
+			val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK);
+		} else {
+			WARN_ON(cluster != 0);
+			WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
+		}
+
 		/*
 		 * We need to disable interrupts in SMP systems in order to
 		 * ensure that we don't interrupt the caller with code which
@@ -280,7 +291,9 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp)
 		spin_lock_irqsave(this_cpu_ptr(&cm_core_lock),
 				  *this_cpu_ptr(&cm_core_lock_flags));
 	} else {
+		WARN_ON(cluster != 0);
 		WARN_ON(vp != 0);
+		WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 
 		/*
 		 * We only have a GCR_CL_OTHER per core in systems with
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 8cc508809466..7aac84ffc2af 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -52,7 +52,7 @@ static unsigned core_vpe_count(unsigned core)
 		&& (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
 		return 1;
 
-	mips_cm_lock_other(core, 0);
+	mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE;
 	mips_cm_unlock_other();
 	return cfg + 1;
@@ -214,7 +214,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
 	unsigned timeout;
 
 	/* Select the appropriate core */
-	mips_cm_lock_other(core, 0);
+	mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 
 	/* Set its reset vector */
 	write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
@@ -313,7 +313,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 	}
 
 	if (cpu_has_vp) {
-		mips_cm_lock_other(core, vpe_id);
+		mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 		core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry);
 		write_gcr_co_reset_base(core_entry);
 		mips_cm_unlock_other();
@@ -518,7 +518,7 @@ static void cps_cpu_die(unsigned int cpu)
 		 */
 		fail_time = ktime_add_ms(ktime_get(), 2000);
 		do {
-			mips_cm_lock_other(core, 0);
+			mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 			mips_cpc_lock_other(core);
 			stat = read_cpc_co_stat_conf();
 			stat &= CPC_Cx_STAT_CONF_SEQSTATE;
@@ -562,7 +562,7 @@ static void cps_cpu_die(unsigned int cpu)
 			panic("Failed to call remote sibling CPU\n");
 	} else if (cpu_has_vp) {
 		do {
-			mips_cm_lock_other(core, vpe_id);
+			mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 			stat = read_cpc_co_vp_running();
 			mips_cm_unlock_other();
 		} while (stat & (1 << vpe_id));
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 4cc43892b959..6248a5a3ec9e 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -190,7 +190,7 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 			core = cpu_core(&cpu_data[cpu]);
 
 			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
-				mips_cm_lock_other(core, 0);
+				mips_cm_lock_other_cpu(cpu, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
 				mips_cpc_lock_other(core);
 				write_cpc_co_cmd(CPC_Cx_CMD_PWRUP);
 				mips_cpc_unlock_other();
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 16/19] MIPS: SMP: Allow boot_secondary SMP op to return errors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Allow the boot_secondary SMP op to return an error to __cpu_up(), which
will in turn return it to its caller.

This will allow SMP implementations to return errors quickly in cases
they they know have failed, rather than relying upon __cpu_up()
eventually timing out waiting for the cpu_running completion.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/cavium-octeon/smp.c         | 8 ++++++--
 arch/mips/include/asm/smp-ops.h       | 2 +-
 arch/mips/kernel/smp-bmips.c          | 4 +++-
 arch/mips/kernel/smp-cmp.c            | 3 ++-
 arch/mips/kernel/smp-cps.c            | 3 ++-
 arch/mips/kernel/smp-mt.c             | 4 +++-
 arch/mips/kernel/smp-up.c             | 3 ++-
 arch/mips/kernel/smp.c                | 6 +++++-
 arch/mips/loongson64/loongson-3/smp.c | 3 ++-
 arch/mips/netlogic/common/smp.c       | 4 +++-
 arch/mips/paravirt/paravirt-smp.c     | 3 ++-
 arch/mips/sgi-ip27/ip27-smp.c         | 3 ++-
 arch/mips/sibyte/bcm1480/smp.c        | 3 ++-
 arch/mips/sibyte/sb1250/smp.c         | 3 ++-
 14 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 163663a5363d..75e7c8625659 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -205,7 +205,7 @@ int plat_post_relocation(long offset)
  * Firmware CPU startup hook
  *
  */
-static void octeon_boot_secondary(int cpu, struct task_struct *idle)
+static int octeon_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int count;
 
@@ -223,8 +223,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
 		udelay(1);
 		count--;
 	}
-	if (count == 0)
+	if (count == 0) {
 		pr_err("Secondary boot timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
 }
 
 /**
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index 38859e7b1f1f..e5f49dd453c7 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -26,7 +26,7 @@ struct plat_smp_ops {
 	void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
 	void (*init_secondary)(void);
 	void (*smp_finish)(void);
-	void (*boot_secondary)(int cpu, struct task_struct *idle);
+	int (*boot_secondary)(int cpu, struct task_struct *idle);
 	void (*smp_setup)(void);
 	void (*prepare_cpus)(unsigned int max_cpus);
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 4ac576c68034..406072e26752 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -179,7 +179,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus)
 /*
  * Tell the hardware to boot CPUx - runs on CPU0
  */
-static void bmips_boot_secondary(int cpu, struct task_struct *idle)
+static int bmips_boot_secondary(int cpu, struct task_struct *idle)
 {
 	bmips_smp_boot_sp = __KSTK_TOS(idle);
 	bmips_smp_boot_gp = (unsigned long)task_thread_info(idle);
@@ -231,6 +231,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
 		}
 		cpumask_set_cpu(cpu, &bmips_booted_mask);
 	}
+
+	return 0;
 }
 
 /*
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index 1acffdee88f4..04b21deea4f2 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -78,7 +78,7 @@ static void cmp_smp_finish(void)
  * __KSTK_TOS(idle) is apparently the stack pointer
  * (unsigned long)idle->thread_info the gp
  */
-static void cmp_boot_secondary(int cpu, struct task_struct *idle)
+static int cmp_boot_secondary(int cpu, struct task_struct *idle)
 {
 	struct thread_info *gp = task_thread_info(idle);
 	unsigned long sp = __KSTK_TOS(idle);
@@ -95,6 +95,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle)
 #endif
 
 	amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0);
+	return 0;
 }
 
 /*
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 7aac84ffc2af..4a4a25c722f1 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -288,7 +288,7 @@ static void remote_vpe_boot(void *dummy)
 	mips_cps_boot_vpes(core_cfg, cpu_vpe_id(&current_cpu_data));
 }
 
-static void cps_boot_secondary(int cpu, struct task_struct *idle)
+static int cps_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned core = cpu_core(&cpu_data[cpu]);
 	unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
@@ -346,6 +346,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 	mips_cps_boot_vpes(core_cfg, vpe_id);
 out:
 	preempt_enable();
+	return 0;
 }
 
 static void cps_init_secondary(void)
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 5a7b5857d083..30415a74f312 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -152,7 +152,7 @@ static void vsmp_smp_finish(void)
  * (unsigned long)idle->thread_info the gp
  * assumes a 1:1 mapping of TC => VPE
  */
-static void vsmp_boot_secondary(int cpu, struct task_struct *idle)
+static int vsmp_boot_secondary(int cpu, struct task_struct *idle)
 {
 	struct thread_info *gp = task_thread_info(idle);
 	dvpe();
@@ -184,6 +184,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle)
 	clear_c0_mvpcontrol(MVPCONTROL_VPC);
 
 	evpe(EVPE_ENABLE);
+
+	return 0;
 }
 
 /*
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
index 4cf015a624d1..525d3196f793 100644
--- a/arch/mips/kernel/smp-up.c
+++ b/arch/mips/kernel/smp-up.c
@@ -39,8 +39,9 @@ static void up_smp_finish(void)
 /*
  * Firmware CPU startup hook
  */
-static void up_boot_secondary(int cpu, struct task_struct *idle)
+static int up_boot_secondary(int cpu, struct task_struct *idle)
 {
+	return 0;
 }
 
 static void __init up_smp_setup(void)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 6248a5a3ec9e..a4a59ed0164c 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -439,7 +439,11 @@ void smp_prepare_boot_cpu(void)
 
 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	mp_ops->boot_secondary(cpu, tidle);
+	int err;
+
+	err = mp_ops->boot_secondary(cpu, tidle);
+	if (err)
+		return err;
 
 	/*
 	 * We must check for timeout here, as the CPU will not be marked
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index bde64b0f1e47..8501109bb0f0 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -400,7 +400,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus)
 /*
  * Setup the PC, SP, and GP of a secondary processor and start it runing!
  */
-static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
+static int loongson3_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned long startargs[4];
 
@@ -423,6 +423,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
 			(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
 	loongson3_ipi_write64(startargs[0],
 			(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
+	return 0;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index 615027863f54..39a300bd6cc2 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -147,7 +147,7 @@ unsigned long nlm_next_gp;
 unsigned long nlm_next_sp;
 static cpumask_t phys_cpu_present_mask;
 
-void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
+int nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 {
 	uint64_t picbase;
 	int hwtid;
@@ -161,6 +161,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 	/* barrier for sp/gp store above */
 	__sync();
 	nlm_pic_send_ipi(picbase, hwtid, 1, 1);  /* NMI */
+
+	return 0;
 }
 
 void __init nlm_smp_setup(void)
diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c
index b61b26ccf601..107d9f90d668 100644
--- a/arch/mips/paravirt/paravirt-smp.c
+++ b/arch/mips/paravirt/paravirt-smp.c
@@ -100,11 +100,12 @@ static void paravirt_smp_finish(void)
 	local_irq_enable();
 }
 
-static void paravirt_boot_secondary(int cpu, struct task_struct *idle)
+static int paravirt_boot_secondary(int cpu, struct task_struct *idle)
 {
 	paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle);
 	smp_wmb();
 	paravirt_smp_sp[cpu] = __KSTK_TOS(idle);
+	return 0;
 }
 
 static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id)
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 85ee974a1582..545446dfe7fa 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -195,7 +195,7 @@ static void ip27_smp_finish(void)
  * set sp to the kernel stack of the newly created idle process, gp to the proc
  * struct so that current_thread_info() will work.
  */
-static void ip27_boot_secondary(int cpu, struct task_struct *idle)
+static int ip27_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned long gp = (unsigned long)task_thread_info(idle);
 	unsigned long sp = __KSTK_TOS(idle);
@@ -203,6 +203,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle)
 	LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
 		(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
 		0, (void *) sp, (void *) gp);
+	return 0;
 }
 
 static void __init ip27_smp_setup(void)
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 20091d5fe5a1..90c9d1255ad7 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -117,7 +117,7 @@ static void bcm1480_smp_finish(void)
  * Setup the PC, SP, and GP of a secondary processor and start it
  * running!
  */
-static void bcm1480_boot_secondary(int cpu, struct task_struct *idle)
+static int bcm1480_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int retval;
 
@@ -126,6 +126,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle)
 			       (unsigned long)task_thread_info(idle), 0);
 	if (retval != 0)
 		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+	return retval;
 }
 
 /*
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index 46ce1298c27d..5baabca52f25 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -106,7 +106,7 @@ static void sb1250_smp_finish(void)
  * Setup the PC, SP, and GP of a secondary processor and start it
  * running!
  */
-static void sb1250_boot_secondary(int cpu, struct task_struct *idle)
+static int sb1250_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int retval;
 
@@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle)
 			       (unsigned long)task_thread_info(idle), 0);
 	if (retval != 0)
 		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+	return retval;
 }
 
 /*
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 16/19] MIPS: SMP: Allow boot_secondary SMP op to return errors
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Allow the boot_secondary SMP op to return an error to __cpu_up(), which
will in turn return it to its caller.

This will allow SMP implementations to return errors quickly in cases
they they know have failed, rather than relying upon __cpu_up()
eventually timing out waiting for the cpu_running completion.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/cavium-octeon/smp.c         | 8 ++++++--
 arch/mips/include/asm/smp-ops.h       | 2 +-
 arch/mips/kernel/smp-bmips.c          | 4 +++-
 arch/mips/kernel/smp-cmp.c            | 3 ++-
 arch/mips/kernel/smp-cps.c            | 3 ++-
 arch/mips/kernel/smp-mt.c             | 4 +++-
 arch/mips/kernel/smp-up.c             | 3 ++-
 arch/mips/kernel/smp.c                | 6 +++++-
 arch/mips/loongson64/loongson-3/smp.c | 3 ++-
 arch/mips/netlogic/common/smp.c       | 4 +++-
 arch/mips/paravirt/paravirt-smp.c     | 3 ++-
 arch/mips/sgi-ip27/ip27-smp.c         | 3 ++-
 arch/mips/sibyte/bcm1480/smp.c        | 3 ++-
 arch/mips/sibyte/sb1250/smp.c         | 3 ++-
 14 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 163663a5363d..75e7c8625659 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -205,7 +205,7 @@ int plat_post_relocation(long offset)
  * Firmware CPU startup hook
  *
  */
-static void octeon_boot_secondary(int cpu, struct task_struct *idle)
+static int octeon_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int count;
 
@@ -223,8 +223,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
 		udelay(1);
 		count--;
 	}
-	if (count == 0)
+	if (count == 0) {
 		pr_err("Secondary boot timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
 }
 
 /**
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index 38859e7b1f1f..e5f49dd453c7 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -26,7 +26,7 @@ struct plat_smp_ops {
 	void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
 	void (*init_secondary)(void);
 	void (*smp_finish)(void);
-	void (*boot_secondary)(int cpu, struct task_struct *idle);
+	int (*boot_secondary)(int cpu, struct task_struct *idle);
 	void (*smp_setup)(void);
 	void (*prepare_cpus)(unsigned int max_cpus);
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 4ac576c68034..406072e26752 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -179,7 +179,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus)
 /*
  * Tell the hardware to boot CPUx - runs on CPU0
  */
-static void bmips_boot_secondary(int cpu, struct task_struct *idle)
+static int bmips_boot_secondary(int cpu, struct task_struct *idle)
 {
 	bmips_smp_boot_sp = __KSTK_TOS(idle);
 	bmips_smp_boot_gp = (unsigned long)task_thread_info(idle);
@@ -231,6 +231,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
 		}
 		cpumask_set_cpu(cpu, &bmips_booted_mask);
 	}
+
+	return 0;
 }
 
 /*
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index 1acffdee88f4..04b21deea4f2 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -78,7 +78,7 @@ static void cmp_smp_finish(void)
  * __KSTK_TOS(idle) is apparently the stack pointer
  * (unsigned long)idle->thread_info the gp
  */
-static void cmp_boot_secondary(int cpu, struct task_struct *idle)
+static int cmp_boot_secondary(int cpu, struct task_struct *idle)
 {
 	struct thread_info *gp = task_thread_info(idle);
 	unsigned long sp = __KSTK_TOS(idle);
@@ -95,6 +95,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle)
 #endif
 
 	amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0);
+	return 0;
 }
 
 /*
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 7aac84ffc2af..4a4a25c722f1 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -288,7 +288,7 @@ static void remote_vpe_boot(void *dummy)
 	mips_cps_boot_vpes(core_cfg, cpu_vpe_id(&current_cpu_data));
 }
 
-static void cps_boot_secondary(int cpu, struct task_struct *idle)
+static int cps_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned core = cpu_core(&cpu_data[cpu]);
 	unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
@@ -346,6 +346,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
 	mips_cps_boot_vpes(core_cfg, vpe_id);
 out:
 	preempt_enable();
+	return 0;
 }
 
 static void cps_init_secondary(void)
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 5a7b5857d083..30415a74f312 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -152,7 +152,7 @@ static void vsmp_smp_finish(void)
  * (unsigned long)idle->thread_info the gp
  * assumes a 1:1 mapping of TC => VPE
  */
-static void vsmp_boot_secondary(int cpu, struct task_struct *idle)
+static int vsmp_boot_secondary(int cpu, struct task_struct *idle)
 {
 	struct thread_info *gp = task_thread_info(idle);
 	dvpe();
@@ -184,6 +184,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle)
 	clear_c0_mvpcontrol(MVPCONTROL_VPC);
 
 	evpe(EVPE_ENABLE);
+
+	return 0;
 }
 
 /*
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
index 4cf015a624d1..525d3196f793 100644
--- a/arch/mips/kernel/smp-up.c
+++ b/arch/mips/kernel/smp-up.c
@@ -39,8 +39,9 @@ static void up_smp_finish(void)
 /*
  * Firmware CPU startup hook
  */
-static void up_boot_secondary(int cpu, struct task_struct *idle)
+static int up_boot_secondary(int cpu, struct task_struct *idle)
 {
+	return 0;
 }
 
 static void __init up_smp_setup(void)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 6248a5a3ec9e..a4a59ed0164c 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -439,7 +439,11 @@ void smp_prepare_boot_cpu(void)
 
 int __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
-	mp_ops->boot_secondary(cpu, tidle);
+	int err;
+
+	err = mp_ops->boot_secondary(cpu, tidle);
+	if (err)
+		return err;
 
 	/*
 	 * We must check for timeout here, as the CPU will not be marked
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index bde64b0f1e47..8501109bb0f0 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -400,7 +400,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus)
 /*
  * Setup the PC, SP, and GP of a secondary processor and start it runing!
  */
-static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
+static int loongson3_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned long startargs[4];
 
@@ -423,6 +423,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
 			(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
 	loongson3_ipi_write64(startargs[0],
 			(void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
+	return 0;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c
index 615027863f54..39a300bd6cc2 100644
--- a/arch/mips/netlogic/common/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -147,7 +147,7 @@ unsigned long nlm_next_gp;
 unsigned long nlm_next_sp;
 static cpumask_t phys_cpu_present_mask;
 
-void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
+int nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 {
 	uint64_t picbase;
 	int hwtid;
@@ -161,6 +161,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 	/* barrier for sp/gp store above */
 	__sync();
 	nlm_pic_send_ipi(picbase, hwtid, 1, 1);  /* NMI */
+
+	return 0;
 }
 
 void __init nlm_smp_setup(void)
diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c
index b61b26ccf601..107d9f90d668 100644
--- a/arch/mips/paravirt/paravirt-smp.c
+++ b/arch/mips/paravirt/paravirt-smp.c
@@ -100,11 +100,12 @@ static void paravirt_smp_finish(void)
 	local_irq_enable();
 }
 
-static void paravirt_boot_secondary(int cpu, struct task_struct *idle)
+static int paravirt_boot_secondary(int cpu, struct task_struct *idle)
 {
 	paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle);
 	smp_wmb();
 	paravirt_smp_sp[cpu] = __KSTK_TOS(idle);
+	return 0;
 }
 
 static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id)
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 85ee974a1582..545446dfe7fa 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -195,7 +195,7 @@ static void ip27_smp_finish(void)
  * set sp to the kernel stack of the newly created idle process, gp to the proc
  * struct so that current_thread_info() will work.
  */
-static void ip27_boot_secondary(int cpu, struct task_struct *idle)
+static int ip27_boot_secondary(int cpu, struct task_struct *idle)
 {
 	unsigned long gp = (unsigned long)task_thread_info(idle);
 	unsigned long sp = __KSTK_TOS(idle);
@@ -203,6 +203,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle)
 	LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
 		(launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
 		0, (void *) sp, (void *) gp);
+	return 0;
 }
 
 static void __init ip27_smp_setup(void)
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 20091d5fe5a1..90c9d1255ad7 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -117,7 +117,7 @@ static void bcm1480_smp_finish(void)
  * Setup the PC, SP, and GP of a secondary processor and start it
  * running!
  */
-static void bcm1480_boot_secondary(int cpu, struct task_struct *idle)
+static int bcm1480_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int retval;
 
@@ -126,6 +126,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle)
 			       (unsigned long)task_thread_info(idle), 0);
 	if (retval != 0)
 		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+	return retval;
 }
 
 /*
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index 46ce1298c27d..5baabca52f25 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -106,7 +106,7 @@ static void sb1250_smp_finish(void)
  * Setup the PC, SP, and GP of a secondary processor and start it
  * running!
  */
-static void sb1250_boot_secondary(int cpu, struct task_struct *idle)
+static int sb1250_boot_secondary(int cpu, struct task_struct *idle)
 {
 	int retval;
 
@@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle)
 			       (unsigned long)task_thread_info(idle), 0);
 	if (retval != 0)
 		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+	return retval;
 }
 
 /*
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 17/19] MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

With Coherence Manager (CM) 3.5 information about the topology of the
system, which has previously only been available through & accessed from
the CM, is now also provided by the Cluster Power Controller (CPC). This
includes a new CPC_CONFIG register mirroring GCR_CONFIG, and similarly a
new CPC_Cx_CONFIG register mirroring GCR_Cx_CONFIG.

In preparation for adjusting functions such as mips_cm_numcores(), which
have previously only needed to access the CM, to also access the CPC
this patch modifies the way we use the various CPS headers. Rather than
having users include asm/mips-cm.h or asm/mips-cpc.h individually we
instead have users include asm/mips-cps.h which in turn includes
asm/mips-cm.h & asm/mips-cpc.h. This means that users will gain access
to both CM & CPC registers by including one header, and most importantly
it makes asm/mips-cps.h an ideal location for helper functions which
need to access the various components of the CPS.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h    | 7 ++++---
 arch/mips/include/asm/mips-cpc.h   | 9 ++++++---
 arch/mips/include/asm/mips-cps.h   | 3 +++
 arch/mips/include/asm/smp-ops.h    | 2 +-
 arch/mips/kernel/mips-cm.c         | 2 +-
 arch/mips/kernel/mips-cpc.c        | 3 +--
 arch/mips/kernel/pm-cps.c          | 3 +--
 arch/mips/kernel/smp-cps.c         | 3 +--
 arch/mips/kernel/traps.c           | 3 +--
 arch/mips/mm/c-r4k.c               | 2 +-
 arch/mips/mm/sc-mips.c             | 2 +-
 arch/mips/mti-malta/malta-dtshim.c | 2 +-
 arch/mips/mti-malta/malta-init.c   | 3 +--
 arch/mips/mti-malta/malta-int.c    | 1 -
 arch/mips/mti-malta/malta-setup.c  | 2 +-
 arch/mips/pci/pci-malta.c          | 2 +-
 arch/mips/pistachio/init.c         | 3 +--
 arch/mips/ralink/mt7621.c          | 3 +--
 arch/mips/vdso/gettimeofday.c      | 1 -
 drivers/irqchip/irq-mips-gic.c     | 2 +-
 20 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index d42cc8e76dc2..3b82ebb5b35c 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -8,14 +8,15 @@
  * option) any later version.
  */
 
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+# error Please include asm/mips-cps.h rather than asm/mips-cm.h
+#endif
+
 #ifndef __MIPS_ASM_MIPS_CM_H__
 #define __MIPS_ASM_MIPS_CM_H__
 
 #include <linux/bitops.h>
 #include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <asm/mips-cps.h>
 
 /* The base address of the CM GCR block */
 extern void __iomem *mips_gcr_base;
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 1d024cc6ccd8..f885051a8378 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -8,12 +8,15 @@
  * option) any later version.
  */
 
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+# error Please include asm/mips-cps.h rather than asm/mips-cpc.h
+#endif
+
 #ifndef __MIPS_ASM_MIPS_CPC_H__
 #define __MIPS_ASM_MIPS_CPC_H__
 
-#include <linux/io.h>
-#include <linux/types.h>
-#include <asm/mips-cps.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
 
 /* The base address of the CPC registers */
 extern void __iomem *mips_cpc_base;
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 7ae32ad15599..2ac88ed4b381 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -105,4 +105,7 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
 	CPS_ACCESSOR_W(unit, sz, name)					\
 	CPS_ACCESSOR_M(unit, sz, name)
 
+#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
+
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index e5f49dd453c7..53b2cb8e5966 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -13,7 +13,7 @@
 
 #include <linux/errno.h>
 
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 
 #ifdef CONFIG_SMP
 
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 602c6ec9c01d..b0d670af5cb1 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -12,7 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/spinlock.h>
 
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mipsregs.h>
 
 void __iomem *mips_gcr_base;
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 06952bb34395..f66b05ebf637 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -12,8 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/spinlock.h>
 
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 
 void __iomem *mips_cpc_base;
 
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index daff76056609..d5e452f9bddf 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -17,8 +17,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cacheops.h>
 #include <asm/idle.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mipsmtregs.h>
 #include <asm/pm.h>
 #include <asm/pm-cps.h>
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 4a4a25c722f1..57b331b85e54 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -19,8 +19,7 @@
 #include <linux/types.h>
 
 #include <asm/bcache.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mips_mt.h>
 #include <asm/mipsregs.h>
 #include <asm/pm-cps.h>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 4cba2e778284..5669d3b8bd38 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -50,9 +50,8 @@
 #include <asm/fpu.h>
 #include <asm/fpu_emulator.h>
 #include <asm/idle.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-r2-to-r6-emul.h>
-#include <asm/mips-cm.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/module.h>
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 81d6a15c93d0..6f534b209971 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -37,7 +37,7 @@
 #include <asm/cacheflush.h> /* for run_uncached() */
 #include <asm/traps.h>
 #include <asm/dma-coherence.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 
 /*
  * Bits describing what cache ops an SMP callback function may perform.
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index cda878c0010b..acfb89273dad 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -14,7 +14,7 @@
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/r4kcache.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 
 /*
  * MIPS32/MIPS64 L2 cache handling
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 67602d57710c..59a723d9a95a 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -18,7 +18,7 @@
 #include <asm/fw/fw.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
 #include <asm/page.h>
 
 #define ROCIT_REG_BASE			0x1f403000
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 0f3b881a3190..009f2918b320 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -21,8 +21,7 @@
 #include <asm/smp-ops.h>
 #include <asm/traps.h>
 #include <asm/fw/fw.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
 
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index b0f9b188e833..2e831f4abfb3 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -29,7 +29,6 @@
 #include <asm/i8259.h>
 #include <asm/irq_cpu.h>
 #include <asm/irq_regs.h>
-#include <asm/mips-cm.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
 #include <asm/gt64120.h>
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index a01d5debfcaf..7f1868888d18 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -28,7 +28,7 @@
 
 #include <asm/fw/fw.h>
 #include <asm/mach-malta/malta-dtshim.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c
index cfbbc3e3e914..de97b8f1c5a8 100644
--- a/arch/mips/pci/pci-malta.c
+++ b/arch/mips/pci/pci-malta.c
@@ -27,7 +27,7 @@
 #include <linux/init.h>
 
 #include <asm/gt64120.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/bonito64.h>
 #include <asm/mips-boards/msc01_pci.h>
diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c
index 1c91cad7988f..0b06c953d293 100644
--- a/arch/mips/pistachio/init.c
+++ b/arch/mips/pistachio/init.c
@@ -19,8 +19,7 @@
 #include <asm/dma-coherence.h>
 #include <asm/fw/fw.h>
 #include <asm/mips-boards/generic.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/prom.h>
 #include <asm/smp-ops.h>
 #include <asm/traps.h>
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 0695c2d64e49..9661c50305b5 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -12,8 +12,7 @@
 
 #include <asm/mipsregs.h>
 #include <asm/smp-ops.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mach-ralink/ralink_regs.h>
 #include <asm/mach-ralink/mt7621.h>
 
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
index e2690d7ca4dd..fec7835b9de7 100644
--- a/arch/mips/vdso/gettimeofday.c
+++ b/arch/mips/vdso/gettimeofday.c
@@ -16,7 +16,6 @@
 
 #include <asm/clocksource.h>
 #include <asm/io.h>
-#include <asm/mips-cm.h>
 #include <asm/unistd.h>
 #include <asm/vdso.h>
 
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index ae9f8e581d06..9e984cefdca0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -17,7 +17,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/setup.h>
 #include <asm/traps.h>
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 17/19] MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

With Coherence Manager (CM) 3.5 information about the topology of the
system, which has previously only been available through & accessed from
the CM, is now also provided by the Cluster Power Controller (CPC). This
includes a new CPC_CONFIG register mirroring GCR_CONFIG, and similarly a
new CPC_Cx_CONFIG register mirroring GCR_Cx_CONFIG.

In preparation for adjusting functions such as mips_cm_numcores(), which
have previously only needed to access the CM, to also access the CPC
this patch modifies the way we use the various CPS headers. Rather than
having users include asm/mips-cm.h or asm/mips-cpc.h individually we
instead have users include asm/mips-cps.h which in turn includes
asm/mips-cm.h & asm/mips-cpc.h. This means that users will gain access
to both CM & CPC registers by including one header, and most importantly
it makes asm/mips-cps.h an ideal location for helper functions which
need to access the various components of the CPS.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h    | 7 ++++---
 arch/mips/include/asm/mips-cpc.h   | 9 ++++++---
 arch/mips/include/asm/mips-cps.h   | 3 +++
 arch/mips/include/asm/smp-ops.h    | 2 +-
 arch/mips/kernel/mips-cm.c         | 2 +-
 arch/mips/kernel/mips-cpc.c        | 3 +--
 arch/mips/kernel/pm-cps.c          | 3 +--
 arch/mips/kernel/smp-cps.c         | 3 +--
 arch/mips/kernel/traps.c           | 3 +--
 arch/mips/mm/c-r4k.c               | 2 +-
 arch/mips/mm/sc-mips.c             | 2 +-
 arch/mips/mti-malta/malta-dtshim.c | 2 +-
 arch/mips/mti-malta/malta-init.c   | 3 +--
 arch/mips/mti-malta/malta-int.c    | 1 -
 arch/mips/mti-malta/malta-setup.c  | 2 +-
 arch/mips/pci/pci-malta.c          | 2 +-
 arch/mips/pistachio/init.c         | 3 +--
 arch/mips/ralink/mt7621.c          | 3 +--
 arch/mips/vdso/gettimeofday.c      | 1 -
 drivers/irqchip/irq-mips-gic.c     | 2 +-
 20 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index d42cc8e76dc2..3b82ebb5b35c 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -8,14 +8,15 @@
  * option) any later version.
  */
 
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+# error Please include asm/mips-cps.h rather than asm/mips-cm.h
+#endif
+
 #ifndef __MIPS_ASM_MIPS_CM_H__
 #define __MIPS_ASM_MIPS_CM_H__
 
 #include <linux/bitops.h>
 #include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <asm/mips-cps.h>
 
 /* The base address of the CM GCR block */
 extern void __iomem *mips_gcr_base;
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index 1d024cc6ccd8..f885051a8378 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -8,12 +8,15 @@
  * option) any later version.
  */
 
+#ifndef __MIPS_ASM_MIPS_CPS_H__
+# error Please include asm/mips-cps.h rather than asm/mips-cpc.h
+#endif
+
 #ifndef __MIPS_ASM_MIPS_CPC_H__
 #define __MIPS_ASM_MIPS_CPC_H__
 
-#include <linux/io.h>
-#include <linux/types.h>
-#include <asm/mips-cps.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
 
 /* The base address of the CPC registers */
 extern void __iomem *mips_cpc_base;
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 7ae32ad15599..2ac88ed4b381 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -105,4 +105,7 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
 	CPS_ACCESSOR_W(unit, sz, name)					\
 	CPS_ACCESSOR_M(unit, sz, name)
 
+#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
+
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index e5f49dd453c7..53b2cb8e5966 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -13,7 +13,7 @@
 
 #include <linux/errno.h>
 
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 
 #ifdef CONFIG_SMP
 
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 602c6ec9c01d..b0d670af5cb1 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -12,7 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/spinlock.h>
 
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mipsregs.h>
 
 void __iomem *mips_gcr_base;
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index 06952bb34395..f66b05ebf637 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -12,8 +12,7 @@
 #include <linux/percpu.h>
 #include <linux/spinlock.h>
 
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 
 void __iomem *mips_cpc_base;
 
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index daff76056609..d5e452f9bddf 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -17,8 +17,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cacheops.h>
 #include <asm/idle.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mipsmtregs.h>
 #include <asm/pm.h>
 #include <asm/pm-cps.h>
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 4a4a25c722f1..57b331b85e54 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -19,8 +19,7 @@
 #include <linux/types.h>
 
 #include <asm/bcache.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mips_mt.h>
 #include <asm/mipsregs.h>
 #include <asm/pm-cps.h>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 4cba2e778284..5669d3b8bd38 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -50,9 +50,8 @@
 #include <asm/fpu.h>
 #include <asm/fpu_emulator.h>
 #include <asm/idle.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-r2-to-r6-emul.h>
-#include <asm/mips-cm.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsmtregs.h>
 #include <asm/module.h>
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 81d6a15c93d0..6f534b209971 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -37,7 +37,7 @@
 #include <asm/cacheflush.h> /* for run_uncached() */
 #include <asm/traps.h>
 #include <asm/dma-coherence.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 
 /*
  * Bits describing what cache ops an SMP callback function may perform.
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index cda878c0010b..acfb89273dad 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -14,7 +14,7 @@
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/r4kcache.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 
 /*
  * MIPS32/MIPS64 L2 cache handling
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 67602d57710c..59a723d9a95a 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -18,7 +18,7 @@
 #include <asm/fw/fw.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
 #include <asm/page.h>
 
 #define ROCIT_REG_BASE			0x1f403000
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 0f3b881a3190..009f2918b320 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -21,8 +21,7 @@
 #include <asm/smp-ops.h>
 #include <asm/traps.h>
 #include <asm/fw/fw.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
 
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index b0f9b188e833..2e831f4abfb3 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -29,7 +29,6 @@
 #include <asm/i8259.h>
 #include <asm/irq_cpu.h>
 #include <asm/irq_regs.h>
-#include <asm/mips-cm.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
 #include <asm/gt64120.h>
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index a01d5debfcaf..7f1868888d18 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -28,7 +28,7 @@
 
 #include <asm/fw/fw.h>
 #include <asm/mach-malta/malta-dtshim.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c
index cfbbc3e3e914..de97b8f1c5a8 100644
--- a/arch/mips/pci/pci-malta.c
+++ b/arch/mips/pci/pci-malta.c
@@ -27,7 +27,7 @@
 #include <linux/init.h>
 
 #include <asm/gt64120.h>
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/bonito64.h>
 #include <asm/mips-boards/msc01_pci.h>
diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c
index 1c91cad7988f..0b06c953d293 100644
--- a/arch/mips/pistachio/init.c
+++ b/arch/mips/pistachio/init.c
@@ -19,8 +19,7 @@
 #include <asm/dma-coherence.h>
 #include <asm/fw/fw.h>
 #include <asm/mips-boards/generic.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/prom.h>
 #include <asm/smp-ops.h>
 #include <asm/traps.h>
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 0695c2d64e49..9661c50305b5 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -12,8 +12,7 @@
 
 #include <asm/mipsregs.h>
 #include <asm/smp-ops.h>
-#include <asm/mips-cm.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/mach-ralink/ralink_regs.h>
 #include <asm/mach-ralink/mt7621.h>
 
diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c
index e2690d7ca4dd..fec7835b9de7 100644
--- a/arch/mips/vdso/gettimeofday.c
+++ b/arch/mips/vdso/gettimeofday.c
@@ -16,7 +16,6 @@
 
 #include <asm/clocksource.h>
 #include <asm/io.h>
-#include <asm/mips-cm.h>
 #include <asm/unistd.h>
 #include <asm/vdso.h>
 
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index ae9f8e581d06..9e984cefdca0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -17,7 +17,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 
-#include <asm/mips-cm.h>
+#include <asm/mips-cps.h>
 #include <asm/setup.h>
 #include <asm/traps.h>
 
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 18/19] MIPS: CPS: Cluster support for topology functions
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Modify the functions we use to read information about the topology of
the system (the number of cores, VPs & IOCUs that it contains) in order
to take into account multiple clusters, and provide a new function to
determine the number of clusters in the system.

Users of these functions are modified only such that they continue to
build successfully - having them actually handle multiple clusters is
left to further patches.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h   |  30 ---------
 arch/mips/include/asm/mips-cps.h  | 128 ++++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/smp-cps.c        |  15 +----
 arch/mips/mti-malta/malta-setup.c |   2 +-
 arch/mips/pci/pci-malta.c         |   4 +-
 arch/mips/ralink/mt7621.c         |   2 +-
 6 files changed, 135 insertions(+), 46 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 3b82ebb5b35c..f6231b91b724 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -328,36 +328,6 @@ GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
 #define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA	GENMASK(7, 1)
 #define CM_GCR_Cx_RESET_EXT_BASE_PRESENT	BIT(0)
 
-/**
- * mips_cm_numcores - return the number of cores present in the system
- *
- * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or
- * zero if no Coherence Manager is present.
- */
-static inline unsigned mips_cm_numcores(void)
-{
-	if (!mips_cm_present())
-		return 0;
-
-	return ((read_gcr_config() & CM_GCR_CONFIG_PCORES)
-		>> __ffs(CM_GCR_CONFIG_PCORES)) + 1;
-}
-
-/**
- * mips_cm_numiocu - return the number of IOCUs present in the system
- *
- * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero
- * if no Coherence Manager is present.
- */
-static inline unsigned mips_cm_numiocu(void)
-{
-	if (!mips_cm_present())
-		return 0;
-
-	return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU)
-		>> __ffs(CM_GCR_CONFIG_NUMIOCU);
-}
-
 /**
  * mips_cm_l2sync - perform an L2-only sync operation
  *
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 2ac88ed4b381..2dd737d803e1 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -108,4 +108,132 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
 #include <asm/mips-cm.h>
 #include <asm/mips-cpc.h>
 
+/**
+ * mips_cps_numclusters - return the number of clusters present in the system
+ *
+ * Returns the number of clusters in the system.
+ */
+static inline unsigned int mips_cps_numclusters(void)
+{
+	unsigned int num_clusters;
+
+	if (mips_cm_revision() < CM_REV_CM3_5)
+		return 1;
+
+	num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS;
+	num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS);
+	return num_clusters;
+}
+
+/**
+ * mips_cps_cluster_config - return (GCR|CPC)_CONFIG from a cluster
+ * @cluster: the ID of the cluster whose config we want
+ *
+ * Read the value of GCR_CONFIG (or its CPC_CONFIG mirror) from a @cluster.
+ *
+ * Returns the value of GCR_CONFIG.
+ */
+static inline uint64_t mips_cps_cluster_config(unsigned int cluster)
+{
+	uint64_t config;
+
+	if (mips_cm_revision() < CM_REV_CM3_5) {
+		/*
+		 * Prior to CM 3.5 we don't have the notion of multiple
+		 * clusters so we can trivially read the GCR_CONFIG register
+		 * within this cluster.
+		 */
+		WARN_ON(cluster != 0);
+		config = read_gcr_config();
+	} else {
+		/*
+		 * From CM 3.5 onwards we read the CPC_CONFIG mirror of
+		 * GCR_CONFIG via the redirect region, since the CPC is always
+		 * powered up allowing us not to need to power up the CM.
+		 */
+		mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
+		config = read_cpc_redir_config();
+		mips_cm_unlock_other();
+	}
+
+	return config;
+}
+
+/**
+ * mips_cps_numcores - return the number of cores present in a cluster
+ * @cluster: the ID of the cluster whose core count we want
+ *
+ * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or
+ * zero if no Coherence Manager is present.
+ */
+static inline unsigned int mips_cps_numcores(unsigned int cluster)
+{
+	if (!mips_cm_present())
+		return 0;
+
+	/* Add one before masking to handle 0xff indicating no cores */
+	return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
+}
+
+/**
+ * mips_cps_numiocu - return the number of IOCUs present in a cluster
+ * @cluster: the ID of the cluster whose IOCU count we want
+ *
+ * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero
+ * if no Coherence Manager is present.
+ */
+static inline unsigned int mips_cps_numiocu(unsigned int cluster)
+{
+	unsigned int num_iocu;
+
+	if (!mips_cm_present())
+		return 0;
+
+	num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU;
+	num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU);
+	return num_iocu;
+}
+
+/**
+ * mips_cps_numvps - return the number of VPs (threads) supported by a core
+ * @cluster: the ID of the cluster containing the core we want to examine
+ * @core: the ID of the core whose VP count we want
+ *
+ * Returns the number of Virtual Processors (VPs, ie. hardware threads) that
+ * are supported by the given @core in the given @cluster. If the core or the
+ * kernel do not support hardware mutlti-threading this returns 1.
+ */
+static inline unsigned int mips_cps_numvps(unsigned int cluster, unsigned int core)
+{
+	unsigned int cfg;
+
+	if (!mips_cm_present())
+		return 1;
+
+	if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
+		&& (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
+		return 1;
+
+	mips_cm_lock_other(cluster, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
+
+	if (mips_cm_revision() < CM_REV_CM3_5) {
+		/*
+		 * Prior to CM 3.5 we can only have one cluster & don't have
+		 * CPC_Cx_CONFIG, so we read GCR_Cx_CONFIG.
+		 */
+		cfg = read_gcr_co_config();
+	} else {
+		/*
+		 * From CM 3.5 onwards we read CPC_Cx_CONFIG because the CPC is
+		 * always powered, which allows us to not worry about powering
+		 * up the cluster's CM here.
+		 */
+		cfg = read_cpc_co_config();
+	}
+
+	mips_cm_unlock_other();
+
+	return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE;
+}
+
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 57b331b85e54..4b9dcca12e5f 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -42,19 +42,10 @@ early_param("nothreads", setup_nothreads);
 
 static unsigned core_vpe_count(unsigned core)
 {
-	unsigned cfg;
-
 	if (threads_disabled)
 		return 1;
 
-	if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
-		&& (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
-		return 1;
-
-	mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
-	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE;
-	mips_cm_unlock_other();
-	return cfg + 1;
+	return mips_cps_numvps(0, core);
 }
 
 static void __init cps_smp_setup(void)
@@ -64,7 +55,7 @@ static void __init cps_smp_setup(void)
 	int c, v;
 
 	/* Detect & record VPE topology */
-	ncores = mips_cm_numcores();
+	ncores = mips_cps_numcores(0);
 	pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE");
 	for (c = nvpes = 0; c < ncores; c++) {
 		core_vpes = core_vpe_count(c);
@@ -138,7 +129,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	}
 
 	/* Warn the user if the CCA prevents multi-core */
-	ncores = mips_cm_numcores();
+	ncores = mips_cps_numcores(0);
 	if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) {
 		pr_warn("Using only one core due to %s%s%s\n",
 			cca_unsuitable ? "unsuitable CCA" : "",
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index 7f1868888d18..de34adb76157 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -128,7 +128,7 @@ static int __init plat_enable_iocoherency(void)
 				 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
 			pr_info("Enabled Bonito IOBC coherency\n");
 		}
-	} else if (mips_cm_numiocu() != 0) {
+	} else if (mips_cps_numiocu(0) != 0) {
 		/* Nothing special needs to be done to enable coherency */
 		pr_info("CMP IOCU detected\n");
 		cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0));
diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c
index de97b8f1c5a8..88e625fb3a47 100644
--- a/arch/mips/pci/pci-malta.c
+++ b/arch/mips/pci/pci-malta.c
@@ -201,7 +201,7 @@ void __init mips_pcibios_init(void)
 		msc_mem_resource.start = start & mask;
 		msc_mem_resource.end = (start & mask) | ~mask;
 		msc_controller.mem_offset = (start & mask) - (map & mask);
-		if (mips_cm_numiocu()) {
+		if (mips_cps_numiocu(0)) {
 			write_gcr_reg0_base(start);
 			write_gcr_reg0_mask(mask |
 					    CM_GCR_REGn_MASK_CMTGT_IOCU0);
@@ -213,7 +213,7 @@ void __init mips_pcibios_init(void)
 		msc_io_resource.end = (map & mask) | ~mask;
 		msc_controller.io_offset = 0;
 		ioport_resource.end = ~mask;
-		if (mips_cm_numiocu()) {
+		if (mips_cps_numiocu(0)) {
 			write_gcr_reg1_base(start);
 			write_gcr_reg1_mask(mask |
 					    CM_GCR_REGn_MASK_CMTGT_IOCU0);
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 9661c50305b5..1b274742077d 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -198,7 +198,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 	mips_cm_probe();
 	mips_cpc_probe();
 
-	if (mips_cm_numiocu()) {
+	if (mips_cps_numiocu(0)) {
 		/*
 		 * mips_cm_probe() wipes out bootloader
 		 * config for CM regions and we have to configure them
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 18/19] MIPS: CPS: Cluster support for topology functions
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Modify the functions we use to read information about the topology of
the system (the number of cores, VPs & IOCUs that it contains) in order
to take into account multiple clusters, and provide a new function to
determine the number of clusters in the system.

Users of these functions are modified only such that they continue to
build successfully - having them actually handle multiple clusters is
left to further patches.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/include/asm/mips-cm.h   |  30 ---------
 arch/mips/include/asm/mips-cps.h  | 128 ++++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/smp-cps.c        |  15 +----
 arch/mips/mti-malta/malta-setup.c |   2 +-
 arch/mips/pci/pci-malta.c         |   4 +-
 arch/mips/ralink/mt7621.c         |   2 +-
 6 files changed, 135 insertions(+), 46 deletions(-)

diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 3b82ebb5b35c..f6231b91b724 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -328,36 +328,6 @@ GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base)
 #define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA	GENMASK(7, 1)
 #define CM_GCR_Cx_RESET_EXT_BASE_PRESENT	BIT(0)
 
-/**
- * mips_cm_numcores - return the number of cores present in the system
- *
- * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or
- * zero if no Coherence Manager is present.
- */
-static inline unsigned mips_cm_numcores(void)
-{
-	if (!mips_cm_present())
-		return 0;
-
-	return ((read_gcr_config() & CM_GCR_CONFIG_PCORES)
-		>> __ffs(CM_GCR_CONFIG_PCORES)) + 1;
-}
-
-/**
- * mips_cm_numiocu - return the number of IOCUs present in the system
- *
- * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero
- * if no Coherence Manager is present.
- */
-static inline unsigned mips_cm_numiocu(void)
-{
-	if (!mips_cm_present())
-		return 0;
-
-	return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU)
-		>> __ffs(CM_GCR_CONFIG_NUMIOCU);
-}
-
 /**
  * mips_cm_l2sync - perform an L2-only sync operation
  *
diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h
index 2ac88ed4b381..2dd737d803e1 100644
--- a/arch/mips/include/asm/mips-cps.h
+++ b/arch/mips/include/asm/mips-cps.h
@@ -108,4 +108,132 @@ static inline void clear_##unit##_##name(uint##sz##_t val)		\
 #include <asm/mips-cm.h>
 #include <asm/mips-cpc.h>
 
+/**
+ * mips_cps_numclusters - return the number of clusters present in the system
+ *
+ * Returns the number of clusters in the system.
+ */
+static inline unsigned int mips_cps_numclusters(void)
+{
+	unsigned int num_clusters;
+
+	if (mips_cm_revision() < CM_REV_CM3_5)
+		return 1;
+
+	num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS;
+	num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS);
+	return num_clusters;
+}
+
+/**
+ * mips_cps_cluster_config - return (GCR|CPC)_CONFIG from a cluster
+ * @cluster: the ID of the cluster whose config we want
+ *
+ * Read the value of GCR_CONFIG (or its CPC_CONFIG mirror) from a @cluster.
+ *
+ * Returns the value of GCR_CONFIG.
+ */
+static inline uint64_t mips_cps_cluster_config(unsigned int cluster)
+{
+	uint64_t config;
+
+	if (mips_cm_revision() < CM_REV_CM3_5) {
+		/*
+		 * Prior to CM 3.5 we don't have the notion of multiple
+		 * clusters so we can trivially read the GCR_CONFIG register
+		 * within this cluster.
+		 */
+		WARN_ON(cluster != 0);
+		config = read_gcr_config();
+	} else {
+		/*
+		 * From CM 3.5 onwards we read the CPC_CONFIG mirror of
+		 * GCR_CONFIG via the redirect region, since the CPC is always
+		 * powered up allowing us not to need to power up the CM.
+		 */
+		mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL);
+		config = read_cpc_redir_config();
+		mips_cm_unlock_other();
+	}
+
+	return config;
+}
+
+/**
+ * mips_cps_numcores - return the number of cores present in a cluster
+ * @cluster: the ID of the cluster whose core count we want
+ *
+ * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or
+ * zero if no Coherence Manager is present.
+ */
+static inline unsigned int mips_cps_numcores(unsigned int cluster)
+{
+	if (!mips_cm_present())
+		return 0;
+
+	/* Add one before masking to handle 0xff indicating no cores */
+	return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
+}
+
+/**
+ * mips_cps_numiocu - return the number of IOCUs present in a cluster
+ * @cluster: the ID of the cluster whose IOCU count we want
+ *
+ * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero
+ * if no Coherence Manager is present.
+ */
+static inline unsigned int mips_cps_numiocu(unsigned int cluster)
+{
+	unsigned int num_iocu;
+
+	if (!mips_cm_present())
+		return 0;
+
+	num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU;
+	num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU);
+	return num_iocu;
+}
+
+/**
+ * mips_cps_numvps - return the number of VPs (threads) supported by a core
+ * @cluster: the ID of the cluster containing the core we want to examine
+ * @core: the ID of the core whose VP count we want
+ *
+ * Returns the number of Virtual Processors (VPs, ie. hardware threads) that
+ * are supported by the given @core in the given @cluster. If the core or the
+ * kernel do not support hardware mutlti-threading this returns 1.
+ */
+static inline unsigned int mips_cps_numvps(unsigned int cluster, unsigned int core)
+{
+	unsigned int cfg;
+
+	if (!mips_cm_present())
+		return 1;
+
+	if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
+		&& (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
+		return 1;
+
+	mips_cm_lock_other(cluster, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
+
+	if (mips_cm_revision() < CM_REV_CM3_5) {
+		/*
+		 * Prior to CM 3.5 we can only have one cluster & don't have
+		 * CPC_Cx_CONFIG, so we read GCR_Cx_CONFIG.
+		 */
+		cfg = read_gcr_co_config();
+	} else {
+		/*
+		 * From CM 3.5 onwards we read CPC_Cx_CONFIG because the CPC is
+		 * always powered, which allows us to not worry about powering
+		 * up the cluster's CM here.
+		 */
+		cfg = read_cpc_co_config();
+	}
+
+	mips_cm_unlock_other();
+
+	return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE;
+}
+
 #endif /* __MIPS_ASM_MIPS_CPS_H__ */
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 57b331b85e54..4b9dcca12e5f 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -42,19 +42,10 @@ early_param("nothreads", setup_nothreads);
 
 static unsigned core_vpe_count(unsigned core)
 {
-	unsigned cfg;
-
 	if (threads_disabled)
 		return 1;
 
-	if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt)
-		&& (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp))
-		return 1;
-
-	mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
-	cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE;
-	mips_cm_unlock_other();
-	return cfg + 1;
+	return mips_cps_numvps(0, core);
 }
 
 static void __init cps_smp_setup(void)
@@ -64,7 +55,7 @@ static void __init cps_smp_setup(void)
 	int c, v;
 
 	/* Detect & record VPE topology */
-	ncores = mips_cm_numcores();
+	ncores = mips_cps_numcores(0);
 	pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE");
 	for (c = nvpes = 0; c < ncores; c++) {
 		core_vpes = core_vpe_count(c);
@@ -138,7 +129,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	}
 
 	/* Warn the user if the CCA prevents multi-core */
-	ncores = mips_cm_numcores();
+	ncores = mips_cps_numcores(0);
 	if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) {
 		pr_warn("Using only one core due to %s%s%s\n",
 			cca_unsuitable ? "unsuitable CCA" : "",
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index 7f1868888d18..de34adb76157 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -128,7 +128,7 @@ static int __init plat_enable_iocoherency(void)
 				 BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
 			pr_info("Enabled Bonito IOBC coherency\n");
 		}
-	} else if (mips_cm_numiocu() != 0) {
+	} else if (mips_cps_numiocu(0) != 0) {
 		/* Nothing special needs to be done to enable coherency */
 		pr_info("CMP IOCU detected\n");
 		cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0));
diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c
index de97b8f1c5a8..88e625fb3a47 100644
--- a/arch/mips/pci/pci-malta.c
+++ b/arch/mips/pci/pci-malta.c
@@ -201,7 +201,7 @@ void __init mips_pcibios_init(void)
 		msc_mem_resource.start = start & mask;
 		msc_mem_resource.end = (start & mask) | ~mask;
 		msc_controller.mem_offset = (start & mask) - (map & mask);
-		if (mips_cm_numiocu()) {
+		if (mips_cps_numiocu(0)) {
 			write_gcr_reg0_base(start);
 			write_gcr_reg0_mask(mask |
 					    CM_GCR_REGn_MASK_CMTGT_IOCU0);
@@ -213,7 +213,7 @@ void __init mips_pcibios_init(void)
 		msc_io_resource.end = (map & mask) | ~mask;
 		msc_controller.io_offset = 0;
 		ioport_resource.end = ~mask;
-		if (mips_cm_numiocu()) {
+		if (mips_cps_numiocu(0)) {
 			write_gcr_reg1_base(start);
 			write_gcr_reg1_mask(mask |
 					    CM_GCR_REGn_MASK_CMTGT_IOCU0);
diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
index 9661c50305b5..1b274742077d 100644
--- a/arch/mips/ralink/mt7621.c
+++ b/arch/mips/ralink/mt7621.c
@@ -198,7 +198,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
 	mips_cm_probe();
 	mips_cpc_probe();
 
-	if (mips_cm_numiocu()) {
+	if (mips_cps_numiocu(0)) {
 		/*
 		 * mips_cm_probe() wipes out bootloader
 		 * config for CM regions and we have to configure them
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 19/19] MIPS: CPS: Detect CPUs in secondary clusters
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

As a first step towards supporting multi-cluster systems, detect cores &
VPs in secondary clusters & record their cluster information in the
cpu_data array. The "VP topology" line printed during boot is extended
to display multiple clusters. On a single cluster it shows output like
the following:

  VP topology: {4,4}

This would indicate a system with 2 cores which each contain 4 VPs. We
extend this to cover multiple clusters in a natural way:

  VP topology: {4,4},{2,2}

This would indicate a system with 2 clusters. The first cluster contains
2 cores which each contain 4 VPs. The second cluster contains 2 cores
which each contain 2 VPs.

Actually booting these cores & VPs is left to further patches once other
pieces are in place.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org

---

 arch/mips/kernel/smp-cps.c | 80 +++++++++++++++++++++++++++++-----------------
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 4b9dcca12e5f..0d9cda6a77de 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -40,44 +40,58 @@ static int __init setup_nothreads(char *s)
 }
 early_param("nothreads", setup_nothreads);
 
-static unsigned core_vpe_count(unsigned core)
+static unsigned core_vpe_count(unsigned int cluster, unsigned core)
 {
 	if (threads_disabled)
 		return 1;
 
-	return mips_cps_numvps(0, core);
+	return mips_cps_numvps(cluster, core);
 }
 
 static void __init cps_smp_setup(void)
 {
-	unsigned int ncores, nvpes, core_vpes;
+	unsigned int nclusters, ncores, nvpes, core_vpes;
 	unsigned long core_entry;
-	int c, v;
+	int cl, c, v;
 
 	/* Detect & record VPE topology */
-	ncores = mips_cps_numcores(0);
+	nvpes = 0;
+	nclusters = mips_cps_numclusters();
 	pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE");
-	for (c = nvpes = 0; c < ncores; c++) {
-		core_vpes = core_vpe_count(c);
-		pr_cont("%c%u", c ? ',' : '{', core_vpes);
-
-		/* Use the number of VPEs in core 0 for smp_num_siblings */
-		if (!c)
-			smp_num_siblings = core_vpes;
+	for (cl = 0; cl < nclusters; cl++) {
+		if (cl > 0)
+			pr_cont(",");
+		pr_cont("{");
+
+		ncores = mips_cps_numcores(cl);
+		for (c = 0; c < ncores; c++) {
+			core_vpes = core_vpe_count(cl, c);
+
+			if (c > 0)
+				pr_cont(",");
+			pr_cont("%u", core_vpes);
+
+			/* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */
+			if (!cl && !c)
+				smp_num_siblings = core_vpes;
+
+			for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
+				cpu_set_cluster(&cpu_data[nvpes + v], cl);
+				cpu_set_core(&cpu_data[nvpes + v], c);
+				cpu_set_vpe_id(&cpu_data[nvpes + v], v);
+			}
 
-		for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
-			cpu_set_core(&cpu_data[nvpes + v], c);
-			cpu_set_vpe_id(&cpu_data[nvpes + v], v);
+			nvpes += core_vpes;
 		}
 
-		nvpes += core_vpes;
+		pr_cont("}");
 	}
-	pr_cont("} total %u\n", nvpes);
+	pr_cont(" total %u\n", nvpes);
 
 	/* Indicate present CPUs (CPU being synonymous with VPE) */
 	for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) {
-		set_cpu_possible(v, true);
-		set_cpu_present(v, true);
+		set_cpu_possible(v, cpu_cluster(&cpu_data[v]) == 0);
+		set_cpu_present(v, cpu_cluster(&cpu_data[v]) == 0);
 		__cpu_number_map[v] = v;
 		__cpu_logical_map[v] = v;
 	}
@@ -109,7 +123,7 @@ static void __init cps_smp_setup(void)
 static void __init cps_prepare_cpus(unsigned int max_cpus)
 {
 	unsigned ncores, core_vpes, c, cca;
-	bool cca_unsuitable;
+	bool cca_unsuitable, cores_limited;
 	u32 *entry_code;
 
 	mips_mt_set_cpuoptions();
@@ -129,19 +143,22 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	}
 
 	/* Warn the user if the CCA prevents multi-core */
-	ncores = mips_cps_numcores(0);
-	if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) {
+	cores_limited = false;
+	if (cca_unsuitable || cpu_has_dc_aliases) {
+		for_each_present_cpu(c) {
+			if (cpus_are_siblings(smp_processor_id(), c))
+				continue;
+
+			set_cpu_present(c, false);
+			cores_limited = true;
+		}
+	}
+	if (cores_limited)
 		pr_warn("Using only one core due to %s%s%s\n",
 			cca_unsuitable ? "unsuitable CCA" : "",
 			(cca_unsuitable && cpu_has_dc_aliases) ? " & " : "",
 			cpu_has_dc_aliases ? "dcache aliasing" : "");
 
-		for_each_present_cpu(c) {
-			if (!cpus_are_siblings(smp_processor_id(), c))
-				set_cpu_present(c, false);
-		}
-	}
-
 	/*
 	 * Patch the start of mips_cps_core_entry to provide:
 	 *
@@ -156,6 +173,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	__sync();
 
 	/* Allocate core boot configuration structs */
+	ncores = mips_cps_numcores(0);
 	mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg),
 					GFP_KERNEL);
 	if (!mips_cps_core_bootcfg) {
@@ -165,7 +183,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 
 	/* Allocate VPE boot configuration structs */
 	for (c = 0; c < ncores; c++) {
-		core_vpes = core_vpe_count(c);
+		core_vpes = core_vpe_count(0, c);
 		mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes,
 				sizeof(*mips_cps_core_bootcfg[c].vpe_config),
 				GFP_KERNEL);
@@ -288,6 +306,10 @@ static int cps_boot_secondary(int cpu, struct task_struct *idle)
 	unsigned int remote;
 	int err;
 
+	/* We don't yet support booting CPUs in other clusters */
+	if (cpu_cluster(&cpu_data[cpu]) != cpu_cluster(&current_cpu_data))
+		return -ENOSYS;
+
 	vpe_cfg->pc = (unsigned long)&smp_bootstrap;
 	vpe_cfg->sp = __KSTK_TOS(idle);
 	vpe_cfg->gp = (unsigned long)task_thread_info(idle);
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH 19/19] MIPS: CPS: Detect CPUs in secondary clusters
@ 2017-08-13  2:49   ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-13  2:49 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

As a first step towards supporting multi-cluster systems, detect cores &
VPs in secondary clusters & record their cluster information in the
cpu_data array. The "VP topology" line printed during boot is extended
to display multiple clusters. On a single cluster it shows output like
the following:

  VP topology: {4,4}

This would indicate a system with 2 cores which each contain 4 VPs. We
extend this to cover multiple clusters in a natural way:

  VP topology: {4,4},{2,2}

This would indicate a system with 2 clusters. The first cluster contains
2 cores which each contain 4 VPs. The second cluster contains 2 cores
which each contain 2 VPs.

Actually booting these cores & VPs is left to further patches once other
pieces are in place.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org

---

 arch/mips/kernel/smp-cps.c | 80 +++++++++++++++++++++++++++++-----------------
 1 file changed, 51 insertions(+), 29 deletions(-)

diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 4b9dcca12e5f..0d9cda6a77de 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -40,44 +40,58 @@ static int __init setup_nothreads(char *s)
 }
 early_param("nothreads", setup_nothreads);
 
-static unsigned core_vpe_count(unsigned core)
+static unsigned core_vpe_count(unsigned int cluster, unsigned core)
 {
 	if (threads_disabled)
 		return 1;
 
-	return mips_cps_numvps(0, core);
+	return mips_cps_numvps(cluster, core);
 }
 
 static void __init cps_smp_setup(void)
 {
-	unsigned int ncores, nvpes, core_vpes;
+	unsigned int nclusters, ncores, nvpes, core_vpes;
 	unsigned long core_entry;
-	int c, v;
+	int cl, c, v;
 
 	/* Detect & record VPE topology */
-	ncores = mips_cps_numcores(0);
+	nvpes = 0;
+	nclusters = mips_cps_numclusters();
 	pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE");
-	for (c = nvpes = 0; c < ncores; c++) {
-		core_vpes = core_vpe_count(c);
-		pr_cont("%c%u", c ? ',' : '{', core_vpes);
-
-		/* Use the number of VPEs in core 0 for smp_num_siblings */
-		if (!c)
-			smp_num_siblings = core_vpes;
+	for (cl = 0; cl < nclusters; cl++) {
+		if (cl > 0)
+			pr_cont(",");
+		pr_cont("{");
+
+		ncores = mips_cps_numcores(cl);
+		for (c = 0; c < ncores; c++) {
+			core_vpes = core_vpe_count(cl, c);
+
+			if (c > 0)
+				pr_cont(",");
+			pr_cont("%u", core_vpes);
+
+			/* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */
+			if (!cl && !c)
+				smp_num_siblings = core_vpes;
+
+			for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
+				cpu_set_cluster(&cpu_data[nvpes + v], cl);
+				cpu_set_core(&cpu_data[nvpes + v], c);
+				cpu_set_vpe_id(&cpu_data[nvpes + v], v);
+			}
 
-		for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) {
-			cpu_set_core(&cpu_data[nvpes + v], c);
-			cpu_set_vpe_id(&cpu_data[nvpes + v], v);
+			nvpes += core_vpes;
 		}
 
-		nvpes += core_vpes;
+		pr_cont("}");
 	}
-	pr_cont("} total %u\n", nvpes);
+	pr_cont(" total %u\n", nvpes);
 
 	/* Indicate present CPUs (CPU being synonymous with VPE) */
 	for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) {
-		set_cpu_possible(v, true);
-		set_cpu_present(v, true);
+		set_cpu_possible(v, cpu_cluster(&cpu_data[v]) == 0);
+		set_cpu_present(v, cpu_cluster(&cpu_data[v]) == 0);
 		__cpu_number_map[v] = v;
 		__cpu_logical_map[v] = v;
 	}
@@ -109,7 +123,7 @@ static void __init cps_smp_setup(void)
 static void __init cps_prepare_cpus(unsigned int max_cpus)
 {
 	unsigned ncores, core_vpes, c, cca;
-	bool cca_unsuitable;
+	bool cca_unsuitable, cores_limited;
 	u32 *entry_code;
 
 	mips_mt_set_cpuoptions();
@@ -129,19 +143,22 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	}
 
 	/* Warn the user if the CCA prevents multi-core */
-	ncores = mips_cps_numcores(0);
-	if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) {
+	cores_limited = false;
+	if (cca_unsuitable || cpu_has_dc_aliases) {
+		for_each_present_cpu(c) {
+			if (cpus_are_siblings(smp_processor_id(), c))
+				continue;
+
+			set_cpu_present(c, false);
+			cores_limited = true;
+		}
+	}
+	if (cores_limited)
 		pr_warn("Using only one core due to %s%s%s\n",
 			cca_unsuitable ? "unsuitable CCA" : "",
 			(cca_unsuitable && cpu_has_dc_aliases) ? " & " : "",
 			cpu_has_dc_aliases ? "dcache aliasing" : "");
 
-		for_each_present_cpu(c) {
-			if (!cpus_are_siblings(smp_processor_id(), c))
-				set_cpu_present(c, false);
-		}
-	}
-
 	/*
 	 * Patch the start of mips_cps_core_entry to provide:
 	 *
@@ -156,6 +173,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 	__sync();
 
 	/* Allocate core boot configuration structs */
+	ncores = mips_cps_numcores(0);
 	mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg),
 					GFP_KERNEL);
 	if (!mips_cps_core_bootcfg) {
@@ -165,7 +183,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
 
 	/* Allocate VPE boot configuration structs */
 	for (c = 0; c < ncores; c++) {
-		core_vpes = core_vpe_count(c);
+		core_vpes = core_vpe_count(0, c);
 		mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes,
 				sizeof(*mips_cps_core_bootcfg[c].vpe_config),
 				GFP_KERNEL);
@@ -288,6 +306,10 @@ static int cps_boot_secondary(int cpu, struct task_struct *idle)
 	unsigned int remote;
 	int err;
 
+	/* We don't yet support booting CPUs in other clusters */
+	if (cpu_cluster(&cpu_data[cpu]) != cpu_cluster(&current_cpu_data))
+		return -ENOSYS;
+
 	vpe_cfg->pc = (unsigned long)&smp_bootstrap;
 	vpe_cfg->sp = __KSTK_TOS(idle);
 	vpe_cfg->gp = (unsigned long)task_thread_info(idle);
-- 
2.14.0

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH 13/19] MIPS: Unify checks for sibling CPUs
  2017-08-13  2:49   ` Paul Burton
  (?)
@ 2017-08-26 12:27   ` Ralf Baechle
  2017-08-26 12:49     ` Rafael J. Wysocki
  2017-08-29  7:42     ` Daniel Lezcano
  -1 siblings, 2 replies; 49+ messages in thread
From: Ralf Baechle @ 2017-08-26 12:27 UTC (permalink / raw)
  To: Paul Burton, Rafael J. Wysocki, Daniel Lezcano, linux-pm; +Cc: linux-mips

Hi,

Paul didn't cc the other maintainers.  Tglx gave me his Ack on IRC so I
now only still need one of a drivers/cpuidle/ maintainer.

Thanks,

  Ralf

On Sat, Aug 12, 2017 at 07:49:37PM -0700, Paul Burton wrote:
> Date:   Sat, 12 Aug 2017 19:49:37 -0700
> From: Paul Burton <paul.burton@imgtec.com>
> To: linux-mips@linux-mips.org
> CC: Ralf Baechle <ralf@linux-mips.org>, Paul Burton <paul.burton@imgtec.com>
> Subject: [PATCH 13/19] MIPS: Unify checks for sibling CPUs
> Content-Type: text/plain
> 
> Up until now we have open-coded checks for whether CPUs are siblings,
> with slight variations on whether we consider the package ID or not.
> 
> This will only get more complex when we introduce cluster support, so in
> preparation for that this patch introduces a cpus_are_siblings()
> function which can be used to check whether or not 2 CPUs are siblings
> in a consistent manner.
> 
> By checking globalnumber with the VP ID masked out this also has the
> neat side effect of being ready for multi-cluster systems already.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: linux-mips@linux-mips.org
> ---
> 
>  arch/mips/include/asm/cpu-info.h | 17 +++++++++++++++++
>  arch/mips/kernel/smp-cps.c       |  8 ++++----
>  arch/mips/kernel/smp.c           | 12 +++++-------
>  drivers/cpuidle/cpuidle-cps.c    |  2 +-
>  drivers/irqchip/irq-mips-cpu.c   |  2 +-
>  5 files changed, 28 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
> index 9ae927282b12..0c61bdc82a53 100644
> --- a/arch/mips/include/asm/cpu-info.h
> +++ b/arch/mips/include/asm/cpu-info.h
> @@ -158,6 +158,23 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
>  extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
>  extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
>  
> +static inline bool cpus_are_siblings(int cpua, int cpub)
> +{
> +	struct cpuinfo_mips *infoa = &cpu_data[cpua];
> +	struct cpuinfo_mips *infob = &cpu_data[cpub];
> +	unsigned int gnuma, gnumb;
> +
> +	if (infoa->package != infob->package)
> +		return false;
> +
> +	gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
> +	gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
> +	if (gnuma != gnumb)
> +		return false;
> +
> +	return true;
> +}
> +
>  static inline unsigned long cpu_asid_inc(void)
>  {
>  	return 1 << CONFIG_MIPS_ASID_SHIFT;
> diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
> index 699459ed293b..8cc508809466 100644
> --- a/arch/mips/kernel/smp-cps.c
> +++ b/arch/mips/kernel/smp-cps.c
> @@ -147,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
>  			cpu_has_dc_aliases ? "dcache aliasing" : "");
>  
>  		for_each_present_cpu(c) {
> -			if (cpu_core(&cpu_data[c]))
> +			if (!cpus_are_siblings(smp_processor_id(), c))
>  				set_cpu_present(c, false);
>  		}
>  	}
> @@ -319,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
>  		mips_cm_unlock_other();
>  	}
>  
> -	if (core != cpu_core(&current_cpu_data)) {
> +	if (!cpus_are_siblings(cpu, smp_processor_id())) {
>  		/* Boot a VPE on another powered up core */
>  		for (remote = 0; remote < NR_CPUS; remote++) {
> -			if (cpu_core(&cpu_data[remote]) != core)
> +			if (!cpus_are_siblings(cpu, remote))
>  				continue;
>  			if (cpu_online(remote))
>  				break;
> @@ -431,7 +431,7 @@ void play_dead(void)
>  
>  		/* Look for another online VPE within the core */
>  		for_each_online_cpu(cpu_death_sibling) {
> -			if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
> +			if (!cpus_are_siblings(cpu, cpu_death_sibling))
>  				continue;
>  
>  			/*
> diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
> index a54e5857c227..4cc43892b959 100644
> --- a/arch/mips/kernel/smp.c
> +++ b/arch/mips/kernel/smp.c
> @@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu)
>  
>  	if (smp_num_siblings > 1) {
>  		for_each_cpu(i, &cpu_sibling_setup_map) {
> -			if (cpu_data[cpu].package == cpu_data[i].package &&
> -			    cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
> +			if (cpus_are_siblings(cpu, i)) {
>  				cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
>  				cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
>  			}
> @@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void)
>  	for_each_online_cpu(i) {
>  		core_present = 0;
>  		for_each_cpu(k, &temp_foreign_map)
> -			if (cpu_data[i].package == cpu_data[k].package &&
> -			    cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
> +			if (cpus_are_siblings(i, k))
>  				core_present = 1;
>  		if (!core_present)
>  			cpumask_set_cpu(i, &temp_foreign_map);
> @@ -186,11 +184,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
>  
>  	if (mips_cpc_present()) {
>  		for_each_cpu(cpu, mask) {
> -			core = cpu_core(&cpu_data[cpu]);
> -
> -			if (core == cpu_core(&current_cpu_data))
> +			if (cpus_are_siblings(cpu, smp_processor_id()))
>  				continue;
>  
> +			core = cpu_core(&cpu_data[cpu]);
> +
>  			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
>  				mips_cm_lock_other(core, 0);
>  				mips_cpc_lock_other(core);
> diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
> index 6041b6104f3d..72b5e47286b4 100644
> --- a/drivers/cpuidle/cpuidle-cps.c
> +++ b/drivers/cpuidle/cpuidle-cps.c
> @@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
>  	 * TODO: don't treat core 0 specially, just prevent the final core
>  	 * TODO: remap interrupt affinity temporarily
>  	 */
> -	if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
> +	if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
>  		index = STATE_NC_WAIT;
>  
>  	/* Select the appropriate cps_pm_state */
> diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
> index 14461cbfab2f..66f97fde13d8 100644
> --- a/drivers/irqchip/irq-mips-cpu.c
> +++ b/drivers/irqchip/irq-mips-cpu.c
> @@ -101,7 +101,7 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
>  	local_irq_save(flags);
>  
>  	/* We can only send IPIs to VPEs within the local core */
> -	WARN_ON(cpu_data[cpu].core != current_cpu_data.core);
> +	WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
>  
>  	vpflags = dvpe();
>  	settc(cpu_vpe_id(&cpu_data[cpu]));
> -- 
> 2.14.0
> 

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 13/19] MIPS: Unify checks for sibling CPUs
  2017-08-26 12:27   ` Ralf Baechle
@ 2017-08-26 12:49     ` Rafael J. Wysocki
  2017-08-29  7:42     ` Daniel Lezcano
  1 sibling, 0 replies; 49+ messages in thread
From: Rafael J. Wysocki @ 2017-08-26 12:49 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Paul Burton, Daniel Lezcano, linux-pm, linux-mips

On Saturday, August 26, 2017 2:27:49 PM CEST Ralf Baechle wrote:
> Hi,
> 
> Paul didn't cc the other maintainers.  Tglx gave me his Ack on IRC so I
> now only still need one of a drivers/cpuidle/ maintainer.

ACK

> On Sat, Aug 12, 2017 at 07:49:37PM -0700, Paul Burton wrote:
> > Date:   Sat, 12 Aug 2017 19:49:37 -0700
> > From: Paul Burton <paul.burton@imgtec.com>
> > To: linux-mips@linux-mips.org
> > CC: Ralf Baechle <ralf@linux-mips.org>, Paul Burton <paul.burton@imgtec.com>
> > Subject: [PATCH 13/19] MIPS: Unify checks for sibling CPUs
> > Content-Type: text/plain
> > 
> > Up until now we have open-coded checks for whether CPUs are siblings,
> > with slight variations on whether we consider the package ID or not.
> > 
> > This will only get more complex when we introduce cluster support, so in
> > preparation for that this patch introduces a cpus_are_siblings()
> > function which can be used to check whether or not 2 CPUs are siblings
> > in a consistent manner.
> > 
> > By checking globalnumber with the VP ID masked out this also has the
> > neat side effect of being ready for multi-cluster systems already.
> > 
> > Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> > Cc: Ralf Baechle <ralf@linux-mips.org>
> > Cc: linux-mips@linux-mips.org
> > ---
> > 
> >  arch/mips/include/asm/cpu-info.h | 17 +++++++++++++++++
> >  arch/mips/kernel/smp-cps.c       |  8 ++++----
> >  arch/mips/kernel/smp.c           | 12 +++++-------
> >  drivers/cpuidle/cpuidle-cps.c    |  2 +-
> >  drivers/irqchip/irq-mips-cpu.c   |  2 +-
> >  5 files changed, 28 insertions(+), 13 deletions(-)
> > 
> > diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
> > index 9ae927282b12..0c61bdc82a53 100644
> > --- a/arch/mips/include/asm/cpu-info.h
> > +++ b/arch/mips/include/asm/cpu-info.h
> > @@ -158,6 +158,23 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
> >  extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
> >  extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
> >  
> > +static inline bool cpus_are_siblings(int cpua, int cpub)
> > +{
> > +	struct cpuinfo_mips *infoa = &cpu_data[cpua];
> > +	struct cpuinfo_mips *infob = &cpu_data[cpub];
> > +	unsigned int gnuma, gnumb;
> > +
> > +	if (infoa->package != infob->package)
> > +		return false;
> > +
> > +	gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
> > +	gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
> > +	if (gnuma != gnumb)
> > +		return false;
> > +
> > +	return true;
> > +}
> > +
> >  static inline unsigned long cpu_asid_inc(void)
> >  {
> >  	return 1 << CONFIG_MIPS_ASID_SHIFT;
> > diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
> > index 699459ed293b..8cc508809466 100644
> > --- a/arch/mips/kernel/smp-cps.c
> > +++ b/arch/mips/kernel/smp-cps.c
> > @@ -147,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
> >  			cpu_has_dc_aliases ? "dcache aliasing" : "");
> >  
> >  		for_each_present_cpu(c) {
> > -			if (cpu_core(&cpu_data[c]))
> > +			if (!cpus_are_siblings(smp_processor_id(), c))
> >  				set_cpu_present(c, false);
> >  		}
> >  	}
> > @@ -319,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
> >  		mips_cm_unlock_other();
> >  	}
> >  
> > -	if (core != cpu_core(&current_cpu_data)) {
> > +	if (!cpus_are_siblings(cpu, smp_processor_id())) {
> >  		/* Boot a VPE on another powered up core */
> >  		for (remote = 0; remote < NR_CPUS; remote++) {
> > -			if (cpu_core(&cpu_data[remote]) != core)
> > +			if (!cpus_are_siblings(cpu, remote))
> >  				continue;
> >  			if (cpu_online(remote))
> >  				break;
> > @@ -431,7 +431,7 @@ void play_dead(void)
> >  
> >  		/* Look for another online VPE within the core */
> >  		for_each_online_cpu(cpu_death_sibling) {
> > -			if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
> > +			if (!cpus_are_siblings(cpu, cpu_death_sibling))
> >  				continue;
> >  
> >  			/*
> > diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
> > index a54e5857c227..4cc43892b959 100644
> > --- a/arch/mips/kernel/smp.c
> > +++ b/arch/mips/kernel/smp.c
> > @@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu)
> >  
> >  	if (smp_num_siblings > 1) {
> >  		for_each_cpu(i, &cpu_sibling_setup_map) {
> > -			if (cpu_data[cpu].package == cpu_data[i].package &&
> > -			    cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
> > +			if (cpus_are_siblings(cpu, i)) {
> >  				cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
> >  				cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
> >  			}
> > @@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void)
> >  	for_each_online_cpu(i) {
> >  		core_present = 0;
> >  		for_each_cpu(k, &temp_foreign_map)
> > -			if (cpu_data[i].package == cpu_data[k].package &&
> > -			    cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
> > +			if (cpus_are_siblings(i, k))
> >  				core_present = 1;
> >  		if (!core_present)
> >  			cpumask_set_cpu(i, &temp_foreign_map);
> > @@ -186,11 +184,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
> >  
> >  	if (mips_cpc_present()) {
> >  		for_each_cpu(cpu, mask) {
> > -			core = cpu_core(&cpu_data[cpu]);
> > -
> > -			if (core == cpu_core(&current_cpu_data))
> > +			if (cpus_are_siblings(cpu, smp_processor_id()))
> >  				continue;
> >  
> > +			core = cpu_core(&cpu_data[cpu]);
> > +
> >  			while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
> >  				mips_cm_lock_other(core, 0);
> >  				mips_cpc_lock_other(core);
> > diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c
> > index 6041b6104f3d..72b5e47286b4 100644
> > --- a/drivers/cpuidle/cpuidle-cps.c
> > +++ b/drivers/cpuidle/cpuidle-cps.c
> > @@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
> >  	 * TODO: don't treat core 0 specially, just prevent the final core
> >  	 * TODO: remap interrupt affinity temporarily
> >  	 */
> > -	if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
> > +	if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
> >  		index = STATE_NC_WAIT;
> >  
> >  	/* Select the appropriate cps_pm_state */
> > diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
> > index 14461cbfab2f..66f97fde13d8 100644
> > --- a/drivers/irqchip/irq-mips-cpu.c
> > +++ b/drivers/irqchip/irq-mips-cpu.c
> > @@ -101,7 +101,7 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
> >  	local_irq_save(flags);
> >  
> >  	/* We can only send IPIs to VPEs within the local core */
> > -	WARN_ON(cpu_data[cpu].core != current_cpu_data.core);
> > +	WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
> >  
> >  	vpflags = dvpe();
> >  	settc(cpu_vpe_id(&cpu_data[cpu]));
> 

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 13/19] MIPS: Unify checks for sibling CPUs
  2017-08-26 12:27   ` Ralf Baechle
  2017-08-26 12:49     ` Rafael J. Wysocki
@ 2017-08-29  7:42     ` Daniel Lezcano
  1 sibling, 0 replies; 49+ messages in thread
From: Daniel Lezcano @ 2017-08-29  7:42 UTC (permalink / raw)
  To: Ralf Baechle, Paul Burton, Rafael J. Wysocki, linux-pm; +Cc: linux-mips

On 26/08/2017 14:27, Ralf Baechle wrote:
> Hi,
> 
> Paul didn't cc the other maintainers.  Tglx gave me his Ack on IRC so I
> now only still need one of a drivers/cpuidle/ maintainer.
> 
> Thanks,
> 
>   Ralf
> 
> On Sat, Aug 12, 2017 at 07:49:37PM -0700, Paul Burton wrote:
>> Date:   Sat, 12 Aug 2017 19:49:37 -0700
>> From: Paul Burton <paul.burton@imgtec.com>
>> To: linux-mips@linux-mips.org
>> CC: Ralf Baechle <ralf@linux-mips.org>, Paul Burton <paul.burton@imgtec.com>
>> Subject: [PATCH 13/19] MIPS: Unify checks for sibling CPUs
>> Content-Type: text/plain
>>
>> Up until now we have open-coded checks for whether CPUs are siblings,
>> with slight variations on whether we consider the package ID or not.
>>
>> This will only get more complex when we introduce cluster support, so in
>> preparation for that this patch introduces a cpus_are_siblings()
>> function which can be used to check whether or not 2 CPUs are siblings
>> in a consistent manner.
>>
>> By checking globalnumber with the VP ID masked out this also has the
>> neat side effect of being ready for multi-cluster systems already.
>>
>> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
>> Cc: Ralf Baechle <ralf@linux-mips.org>
>> Cc: linux-mips@linux-mips.org
>> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH] fixup: MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts
@ 2017-08-29 20:05     ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-29 20:05 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Ralf Baechle

This patch fixes an incorrectly fixed up use of __ffs() on a 64 bit
integer, and a missed usage of CM_GCR_GIC_STATUS_GICEX.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: 4f1f490f010b ("MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts")
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/mips-cm.c         | 2 +-
 arch/mips/mti-malta/malta-dtshim.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index b0d670af5cb1..e91c8c4e2eb5 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -391,7 +391,7 @@ void mips_cm_error_report(void)
 		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
 		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
 
-		cause = cm_error >> __ffs(CM3_GCR_ERROR_CAUSE_ERRTYPE);
+		cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE);
 		ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
 
 		if (!cause)
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 59a723d9a95a..361f7c146b75 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt)
 
 	/* if we have a CM which reports a GIC is present, leave the DT alone */
 	err = mips_cm_probe();
-	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX))
+	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX))
 		return;
 
 	if (malta_scon() == MIPS_REVISION_SCON_ROCIT) {
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH] fixup: MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts
@ 2017-08-29 20:05     ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-29 20:05 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Ralf Baechle

This patch fixes an incorrectly fixed up use of __ffs() on a 64 bit
integer, and a missed usage of CM_GCR_GIC_STATUS_GICEX.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: 4f1f490f010b ("MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts")
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/mips-cm.c         | 2 +-
 arch/mips/mti-malta/malta-dtshim.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index b0d670af5cb1..e91c8c4e2eb5 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -391,7 +391,7 @@ void mips_cm_error_report(void)
 		ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits;
 		ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
 
-		cause = cm_error >> __ffs(CM3_GCR_ERROR_CAUSE_ERRTYPE);
+		cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE);
 		ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND);
 
 		if (!cause)
diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 59a723d9a95a..361f7c146b75 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt)
 
 	/* if we have a CM which reports a GIC is present, leave the DT alone */
 	err = mips_cm_probe();
-	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX))
+	if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX))
 		return;
 
 	if (malta_scon() == MIPS_REVISION_SCON_ROCIT) {
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH] fixup: MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers
@ 2017-08-29 20:07     ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-29 20:07 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Ralf Baechle

Fix a missed inclusion of asm/mips-cpc.h to include asm/mips-cps.h
instead.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: bd819d76de64 ("MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers")
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/mti-malta/malta-dtshim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 361f7c146b75..a6699c15277d 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -18,7 +18,7 @@
 #include <asm/fw/fw.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/page.h>
 
 #define ROCIT_REG_BASE			0x1f403000
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH] fixup: MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers
@ 2017-08-29 20:07     ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-29 20:07 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Ralf Baechle

Fix a missed inclusion of asm/mips-cpc.h to include asm/mips-cps.h
instead.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: bd819d76de64 ("MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers")
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/mti-malta/malta-dtshim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c
index 361f7c146b75..a6699c15277d 100644
--- a/arch/mips/mti-malta/malta-dtshim.c
+++ b/arch/mips/mti-malta/malta-dtshim.c
@@ -18,7 +18,7 @@
 #include <asm/fw/fw.h>
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/malta.h>
-#include <asm/mips-cpc.h>
+#include <asm/mips-cps.h>
 #include <asm/page.h>
 
 #define ROCIT_REG_BASE			0x1f403000
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH] fixup: MIPS: CPS: Cluster support for topology functions
@ 2017-08-29 20:08     ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-29 20:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Ralf Baechle

From CM 3.5 onwards we might read information that has typically come
from the CM using registers which mirror that information in the CPC.
This requires that we include support for the CPC.

Ensure that CONFIG_MIPS_CPC is enabled along with CONFIG_MIPS_CM so that
we always include that support. Otherwise we fail to link due to the
missing mips_cpc_base symbol when the topology functions call CPC
register accessors.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: 20fb90f7620d ("MIPS: CPS: Cluster support for topology functions")
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/Kconfig | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2d1651797651..5284dfc38e78 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2385,7 +2385,6 @@ config MIPS_CPS
 	bool "MIPS Coherent Processing System support"
 	depends on SYS_SUPPORTS_MIPS_CPS
 	select MIPS_CM
-	select MIPS_CPC
 	select MIPS_CPS_PM if HOTPLUG_CPU
 	select SMP
 	select SYNC_R4K if (CEVT_R4K || CSRC_R4K)
@@ -2402,11 +2401,11 @@ config MIPS_CPS
 
 config MIPS_CPS_PM
 	depends on MIPS_CPS
-	select MIPS_CPC
 	bool
 
 config MIPS_CM
 	bool
+	select MIPS_CPC
 
 config MIPS_CPC
 	bool
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH] fixup: MIPS: CPS: Cluster support for topology functions
@ 2017-08-29 20:08     ` Paul Burton
  0 siblings, 0 replies; 49+ messages in thread
From: Paul Burton @ 2017-08-29 20:08 UTC (permalink / raw)
  To: linux-mips; +Cc: Paul Burton, Ralf Baechle



^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2017-08-29 20:08 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-13  2:49 [PATCH 00/19] MIPS: Initial multi-cluster support Paul Burton
2017-08-13  2:49 ` Paul Burton
2017-08-13  2:49 ` [PATCH 01/19] MIPS: CM: Rename mips_cm_base to mips_gcr_base Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 02/19] MIPS: CM: Specify register size when generating accessors Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 03/19] MIPS: CM: Use BIT/GENMASK for register fields, order & drop shifts Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-29 20:05   ` [PATCH] fixup: " Paul Burton
2017-08-29 20:05     ` Paul Burton
2017-08-13  2:49 ` [PATCH 04/19] MIPS: CPC: Use common CPS accessor generation macros Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 05/19] MIPS: CPC: Use BIT/GENMASK for register fields, order & drop shifts Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 06/19] MIPS: CPS: Introduce register modify (set/clear/change) accessors Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 07/19] MIPS: CPS: Use change_*, set_* & clear_* where appropriate Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 08/19] MIPS: CPS: Add CM/CPC 3.5 register definitions Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 09/19] MIPS: Add accessor & bit definitions for GlobalNumber Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 10/19] MIPS: CPS: Use GlobalNumber macros rather than magic numbers Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 11/19] MIPS: Abstract CPU core & VP(E) ID access through accessor functions Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 12/19] MIPS: Store core & VP IDs in GlobalNumber-style variable Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 13/19] MIPS: Unify checks for sibling CPUs Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-26 12:27   ` Ralf Baechle
2017-08-26 12:49     ` Rafael J. Wysocki
2017-08-29  7:42     ` Daniel Lezcano
2017-08-13  2:49 ` [PATCH 14/19] MIPS: Add CPU cluster number accessors Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 15/19] MIPS: CM: Add cluster & block args to mips_cm_lock_other() Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 16/19] MIPS: SMP: Allow boot_secondary SMP op to return errors Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-13  2:49 ` [PATCH 17/19] MIPS: CPS: Have asm/mips-cps.h include CM & CPC headers Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-29 20:07   ` [PATCH] fixup: " Paul Burton
2017-08-29 20:07     ` Paul Burton
2017-08-13  2:49 ` [PATCH 18/19] MIPS: CPS: Cluster support for topology functions Paul Burton
2017-08-13  2:49   ` Paul Burton
2017-08-29 20:08   ` [PATCH] fixup: " Paul Burton
2017-08-29 20:08     ` Paul Burton
2017-08-13  2:49 ` [PATCH 19/19] MIPS: CPS: Detect CPUs in secondary clusters Paul Burton
2017-08-13  2:49   ` Paul Burton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.