cregit-Linux how code gets into the kernel

Release 4.14 arch/mips/include/asm/mips-cps.h

/*
 * Copyright (C) 2017 Imagination Technologies
 * Author: Paul Burton <paul.burton@mips.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_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)


#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)                                  \
        CPS_ACCESSOR_M(unit, sz, name)

#include <asm/mips-cm.h>
#include <asm/mips-cpc.h>
#include <asm/mips-gic.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; }

Contributors

PersonTokensPropCommitsCommitProp
Paul Burton41100.00%1100.00%
Total41100.00%1100.00%

/** * 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; }

Contributors

PersonTokensPropCommitsCommitProp
Paul Burton62100.00%1100.00%
Total62100.00%1100.00%

/** * 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; }

Contributors

PersonTokensPropCommitsCommitProp
Paul Burton34100.00%1100.00%
Total34100.00%1100.00%

/** * 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; }

Contributors

PersonTokensPropCommitsCommitProp
Paul Burton44100.00%1100.00%
Total44100.00%1100.00%

/** * 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; }

Contributors

PersonTokensPropCommitsCommitProp
Paul Burton103100.00%1100.00%
Total103100.00%1100.00%

#endif /* __MIPS_ASM_MIPS_CPS_H__ */

Overall Contributors

PersonTokensPropCommitsCommitProp
Paul Burton416100.00%6100.00%
Total416100.00%6100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.