Skip to content

Commit

Permalink
MIPS: CPS: Cluster support for topology functions
Browse files Browse the repository at this point in the history
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 <[email protected]>
Cc: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/17016/
Patchwork: https://patchwork.linux-mips.org/patch/17218/
Signed-off-by: Ralf Baechle <[email protected]>
  • Loading branch information
paulburton authored and ralfbaechle committed Aug 29, 2017
1 parent e83f7e0 commit 3c9b416
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 48 deletions.
3 changes: 1 addition & 2 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2365,7 +2365,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)
Expand All @@ -2382,11 +2381,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
Expand Down
30 changes: 0 additions & 30 deletions arch/mips/include/asm/mips-cm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
128 changes: 128 additions & 0 deletions arch/mips/include/asm/mips-cps.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
15 changes: 3 additions & 12 deletions arch/mips/kernel/smp-cps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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" : "",
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/mti-malta/malta-setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
4 changes: 2 additions & 2 deletions arch/mips/pci/pci-malta.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/ralink/mt7621.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3c9b416

Please sign in to comment.