MIPS: OCTEON: Add model checking support for cn73xx, cnf75xx and cn78xx
authorDavid Daney <david.daney@cavium.com>
Tue, 9 Feb 2016 19:00:09 +0000 (11:00 -0800)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 13 May 2016 12:01:40 +0000 (14:01 +0200)
Follow on patchs need to be able to distinguish the new models.

Signed-off-by: David Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/12498/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/cavium-octeon/executive/octeon-model.c
arch/mips/include/asm/octeon/cvmx.h
arch/mips/include/asm/octeon/octeon-feature.h
arch/mips/include/asm/octeon/octeon-model.h

index b2104bd..d08a2bc 100644 (file)
@@ -71,11 +71,11 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
        uint32_t fuse_data = 0;
 
        fus3.u64 = 0;
-       if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
+       if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX))
                fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
        fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
        fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
-       num_cores = cvmx_pop(cvmx_read_csr(CVMX_CIU_FUSE));
+       num_cores = cvmx_octeon_num_cores();
 
        /* Make sure the non existent devices look disabled */
        switch ((chip_id >> 8) & 0xff) {
@@ -121,6 +121,15 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
         * later.
         */
        switch (num_cores) {
+       case 48:
+               core_model = "90";
+               break;
+       case 44:
+               core_model = "88";
+               break;
+       case 40:
+               core_model = "85";
+               break;
        case 32:
                core_model = "80";
                break;
@@ -297,7 +306,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
                                if (fus_dat3.s.nozip)
                                        suffix = "SCP";
 
-                               if (fus_dat3.s.bar2_en)
+                               if (fus_dat3.cn56xx.bar2_en)
                                        suffix = "NSPB2";
                        }
                        if (fus3.cn56xx.crip_1024k)
@@ -369,6 +378,73 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
                else
                        suffix = "AAP";
                break;
+       case 0x94:              /* CNF71XX */
+               family = "F71";
+               if (fus_dat3.cnf71xx.nozip)
+                       suffix = "SCP";
+               else
+                       suffix = "AAP";
+               break;
+       case 0x95:              /* CN78XX */
+               if (num_cores == 6)     /* Other core counts match generic */
+                       core_model = "35";
+               if (OCTEON_IS_MODEL(OCTEON_CN76XX))
+                       family = "76";
+               else
+                       family = "78";
+               if (fus_dat3.cn78xx.l2c_crip == 2)
+                       family = "77";
+               if (fus_dat3.cn78xx.nozip
+                   && fus_dat3.cn78xx.nodfa_dte
+                   && fus_dat3.cn78xx.nohna_dte) {
+                       if (fus_dat3.cn78xx.nozip &&
+                               !fus_dat2.cn78xx.raid_en &&
+                               fus_dat3.cn78xx.nohna_dte) {
+                               suffix = "CP";
+                       } else {
+                               suffix = "SCP";
+                       }
+               } else if (fus_dat2.cn78xx.raid_en == 0)
+                       suffix = "HCP";
+               else
+                       suffix = "AAP";
+               break;
+       case 0x96:              /* CN70XX */
+               family = "70";
+               if (cvmx_read_csr(CVMX_MIO_FUS_PDF) & (0x1ULL << 32))
+                       family = "71";
+               if (fus_dat2.cn70xx.nocrypto)
+                       suffix = "CP";
+               else if (fus_dat3.cn70xx.nodfa_dte)
+                       suffix = "SCP";
+               else
+                       suffix = "AAP";
+               break;
+       case 0x97:              /* CN73XX */
+               if (num_cores == 6)     /* Other core counts match generic */
+                       core_model = "35";
+               family = "73";
+               if (fus_dat3.cn73xx.l2c_crip == 2)
+                       family = "72";
+               if (fus_dat3.cn73xx.nozip
+                               && fus_dat3.cn73xx.nodfa_dte
+                               && fus_dat3.cn73xx.nohna_dte) {
+                       if (!fus_dat2.cn73xx.raid_en)
+                               suffix = "CP";
+                       else
+                               suffix = "SCP";
+               } else
+                       suffix = "AAP";
+               break;
+       case 0x98:              /* CN75XX */
+               family = "F75";
+               if (fus_dat3.cn78xx.nozip
+                   && fus_dat3.cn78xx.nodfa_dte
+                   && fus_dat3.cn78xx.nohna_dte)
+                       suffix = "SCP";
+               else
+                       suffix = "AAP";
+               break;
        default:
                family = "XX";
                core_model = "XX";
index 3e982e0..2530e87 100644 (file)
@@ -57,6 +57,7 @@ enum cvmx_mips_space {
 #include <asm/octeon/cvmx-sysinfo.h>
 
 #include <asm/octeon/cvmx-ciu-defs.h>
+#include <asm/octeon/cvmx-ciu3-defs.h>
 #include <asm/octeon/cvmx-gpio-defs.h>
 #include <asm/octeon/cvmx-iob-defs.h>
 #include <asm/octeon/cvmx-ipd-defs.h>
@@ -341,6 +342,21 @@ static inline unsigned int cvmx_get_core_num(void)
        return core_num;
 }
 
+/* Maximum # of bits to define core in node */
+#define CVMX_NODE_NO_SHIFT     7
+#define CVMX_NODE_MASK         0x3
+static inline unsigned int cvmx_get_node_num(void)
+{
+       unsigned int core_num = cvmx_get_core_num();
+
+       return (core_num >> CVMX_NODE_NO_SHIFT) & CVMX_NODE_MASK;
+}
+
+static inline unsigned int cvmx_get_local_core_num(void)
+{
+       return cvmx_get_core_num() & ((1 << CVMX_NODE_NO_SHIFT) - 1);
+}
+
 /**
  * Returns the number of bits set in the provided value.
  * Simple wrapper for POP instruction.
@@ -448,8 +464,15 @@ static inline uint64_t cvmx_get_cycle_global(void)
 /* Return the number of cores available in the chip */
 static inline uint32_t cvmx_octeon_num_cores(void)
 {
-       uint32_t ciu_fuse = (uint32_t) cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
-       return cvmx_pop(ciu_fuse);
+       u64 ciu_fuse_reg;
+       u64 ciu_fuse;
+
+       if (OCTEON_IS_OCTEON3() && !OCTEON_IS_MODEL(OCTEON_CN70XX))
+               ciu_fuse_reg = CVMX_CIU3_FUSE;
+       else
+               ciu_fuse_reg = CVMX_CIU_FUSE;
+       ciu_fuse = cvmx_read_csr(ciu_fuse_reg);
+       return cvmx_dpop(ciu_fuse);
 }
 
 #endif /*  __CVMX_H__  */
index 3ed10a8..a19ca3b 100644 (file)
@@ -81,6 +81,10 @@ enum octeon_feature {
        OCTEON_FEATURE_HFA,
        OCTEON_FEATURE_DFM,
        OCTEON_FEATURE_CIU2,
+       OCTEON_FEATURE_CIU3,
+       /* Octeon has FPA first seen on 78XX */
+       OCTEON_FEATURE_FPA3,
+       OCTEON_FEATURE_FAU,
        OCTEON_MAX_FEATURE
 };
 
@@ -110,7 +114,7 @@ static inline int octeon_has_crypto(void)
  * Returns Non zero if the feature exists. Zero if the feature does not
  *        exist.
  */
-static inline int octeon_has_feature(enum octeon_feature feature)
+static inline bool octeon_has_feature(enum octeon_feature feature)
 {
        switch (feature) {
        case OCTEON_FEATURE_SAAD:
@@ -122,7 +126,7 @@ static inline int octeon_has_feature(enum octeon_feature feature)
                        fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
                        return !fus_2.s.nocrypto && !fus_2.s.nomul && fus_2.s.dorm_crypto;
                } else {
-                       return 0;
+                       return false;
                }
 
        case OCTEON_FEATURE_PCIE:
@@ -190,11 +194,20 @@ static inline int octeon_has_feature(enum octeon_feature feature)
 
        case OCTEON_FEATURE_CIU2:
                return OCTEON_IS_MODEL(OCTEON_CN68XX);
+       case OCTEON_FEATURE_CIU3:
+       case OCTEON_FEATURE_FPA3:
+               return OCTEON_IS_MODEL(OCTEON_CN78XX)
+                       || OCTEON_IS_MODEL(OCTEON_CNF75XX)
+                       || OCTEON_IS_MODEL(OCTEON_CN73XX);
+       case OCTEON_FEATURE_FAU:
+               return !(OCTEON_IS_MODEL(OCTEON_CN78XX)
+                        || OCTEON_IS_MODEL(OCTEON_CNF75XX)
+                        || OCTEON_IS_MODEL(OCTEON_CN73XX));
 
        default:
                break;
        }
-       return 0;
+       return false;
 }
 
 #endif /* __OCTEON_FEATURE_H__ */
index 92b377e..6c68517 100644 (file)
  * CN7XXX models with new revision encoding
  */
 
+#define OCTEON_CNF75XX_PASS1_0 0x000d9800
+#define OCTEON_CNF75XX         (OCTEON_CNF75XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CNF75XX_PASS1_X (OCTEON_CNF75XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+
 #define OCTEON_CN73XX_PASS1_0  0x000d9700
+#define OCTEON_CN73XX_PASS1_1  0x000d9701
 #define OCTEON_CN73XX          (OCTEON_CN73XX_PASS1_0 | OM_IGNORE_REVISION)
 #define OCTEON_CN73XX_PASS1_X  (OCTEON_CN73XX_PASS1_0 | \
                                 OM_IGNORE_MINOR_REVISION)