diff options
Diffstat (limited to 'arch/mips/cavium-octeon')
-rw-r--r-- | arch/mips/cavium-octeon/executive/cvmx-l2c.c | 139 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/executive/octeon-model.c | 21 |
2 files changed, 66 insertions, 94 deletions
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index 89b5273299ab..f091c9b70603 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2017 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -239,6 +239,7 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) else { uint64_t counter = 0; int tad; + for (tad = 0; tad < CVMX_L2C_TADS; tad++) counter += cvmx_read_csr(CVMX_L2C_TADX_PFC0(tad)); return counter; @@ -249,6 +250,7 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) else { uint64_t counter = 0; int tad; + for (tad = 0; tad < CVMX_L2C_TADS; tad++) counter += cvmx_read_csr(CVMX_L2C_TADX_PFC1(tad)); return counter; @@ -259,6 +261,7 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) else { uint64_t counter = 0; int tad; + for (tad = 0; tad < CVMX_L2C_TADS; tad++) counter += cvmx_read_csr(CVMX_L2C_TADX_PFC2(tad)); return counter; @@ -270,6 +273,7 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) else { uint64_t counter = 0; int tad; + for (tad = 0; tad < CVMX_L2C_TADS; tad++) counter += cvmx_read_csr(CVMX_L2C_TADX_PFC3(tad)); return counter; @@ -301,7 +305,7 @@ static void fault_in(uint64_t addr, int len) */ CVMX_DCACHE_INVALIDATE; while (len > 0) { - ACCESS_ONCE(*ptr); + READ_ONCE(*ptr); len -= CVMX_CACHE_LINE_SIZE; ptr += CVMX_CACHE_LINE_SIZE; } @@ -375,7 +379,9 @@ int cvmx_l2c_lock_line(uint64_t addr) if (((union cvmx_l2c_cfg)(cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) { int alias_shift = CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1; uint64_t addr_tmp = addr ^ (addr & ((1 << alias_shift) - 1)) >> CVMX_L2_SET_BITS; + lckbase.s.lck_base = addr_tmp >> 7; + } else { lckbase.s.lck_base = addr >> 7; } @@ -435,6 +441,7 @@ void cvmx_l2c_flush(void) /* These may look like constants, but they aren't... */ int assoc_shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT; int set_shift = CVMX_L2C_IDX_ADDR_SHIFT; + for (set = 0; set < n_set; set++) { for (assoc = 0; assoc < n_assoc; assoc++) { address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, @@ -519,89 +526,49 @@ int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len) union __cvmx_l2c_tag { uint64_t u64; struct cvmx_l2c_tag_cn50xx { -#ifdef __BIG_ENDIAN_BITFIELD - uint64_t reserved:40; - uint64_t V:1; /* Line valid */ - uint64_t D:1; /* Line dirty */ - uint64_t L:1; /* Line locked */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t addr:20; /* Phys mem addr (33..14) */ -#else - uint64_t addr:20; /* Phys mem addr (33..14) */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t L:1; /* Line locked */ - uint64_t D:1; /* Line dirty */ - uint64_t V:1; /* Line valid */ - uint64_t reserved:40; -#endif + __BITFIELD_FIELD(uint64_t reserved:40, + __BITFIELD_FIELD(uint64_t V:1, /* Line valid */ + __BITFIELD_FIELD(uint64_t D:1, /* Line dirty */ + __BITFIELD_FIELD(uint64_t L:1, /* Line locked */ + __BITFIELD_FIELD(uint64_t U:1, /* Use, LRU eviction */ + __BITFIELD_FIELD(uint64_t addr:20, /* Phys addr (33..14) */ + ;)))))) } cn50xx; struct cvmx_l2c_tag_cn30xx { -#ifdef __BIG_ENDIAN_BITFIELD - uint64_t reserved:41; - uint64_t V:1; /* Line valid */ - uint64_t D:1; /* Line dirty */ - uint64_t L:1; /* Line locked */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t addr:19; /* Phys mem addr (33..15) */ -#else - uint64_t addr:19; /* Phys mem addr (33..15) */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t L:1; /* Line locked */ - uint64_t D:1; /* Line dirty */ - uint64_t V:1; /* Line valid */ - uint64_t reserved:41; -#endif + __BITFIELD_FIELD(uint64_t reserved:41, + __BITFIELD_FIELD(uint64_t V:1, /* Line valid */ + __BITFIELD_FIELD(uint64_t D:1, /* Line dirty */ + __BITFIELD_FIELD(uint64_t L:1, /* Line locked */ + __BITFIELD_FIELD(uint64_t U:1, /* Use, LRU eviction */ + __BITFIELD_FIELD(uint64_t addr:19, /* Phys addr (33..15) */ + ;)))))) } cn30xx; struct cvmx_l2c_tag_cn31xx { -#ifdef __BIG_ENDIAN_BITFIELD - uint64_t reserved:42; - uint64_t V:1; /* Line valid */ - uint64_t D:1; /* Line dirty */ - uint64_t L:1; /* Line locked */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t addr:18; /* Phys mem addr (33..16) */ -#else - uint64_t addr:18; /* Phys mem addr (33..16) */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t L:1; /* Line locked */ - uint64_t D:1; /* Line dirty */ - uint64_t V:1; /* Line valid */ - uint64_t reserved:42; -#endif + __BITFIELD_FIELD(uint64_t reserved:42, + __BITFIELD_FIELD(uint64_t V:1, /* Line valid */ + __BITFIELD_FIELD(uint64_t D:1, /* Line dirty */ + __BITFIELD_FIELD(uint64_t L:1, /* Line locked */ + __BITFIELD_FIELD(uint64_t U:1, /* Use, LRU eviction */ + __BITFIELD_FIELD(uint64_t addr:18, /* Phys addr (33..16) */ + ;)))))) } cn31xx; struct cvmx_l2c_tag_cn38xx { -#ifdef __BIG_ENDIAN_BITFIELD - uint64_t reserved:43; - uint64_t V:1; /* Line valid */ - uint64_t D:1; /* Line dirty */ - uint64_t L:1; /* Line locked */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t addr:17; /* Phys mem addr (33..17) */ -#else - uint64_t addr:17; /* Phys mem addr (33..17) */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t L:1; /* Line locked */ - uint64_t D:1; /* Line dirty */ - uint64_t V:1; /* Line valid */ - uint64_t reserved:43; -#endif + __BITFIELD_FIELD(uint64_t reserved:43, + __BITFIELD_FIELD(uint64_t V:1, /* Line valid */ + __BITFIELD_FIELD(uint64_t D:1, /* Line dirty */ + __BITFIELD_FIELD(uint64_t L:1, /* Line locked */ + __BITFIELD_FIELD(uint64_t U:1, /* Use, LRU eviction */ + __BITFIELD_FIELD(uint64_t addr:17, /* Phys addr (33..17) */ + ;)))))) } cn38xx; struct cvmx_l2c_tag_cn58xx { -#ifdef __BIG_ENDIAN_BITFIELD - uint64_t reserved:44; - uint64_t V:1; /* Line valid */ - uint64_t D:1; /* Line dirty */ - uint64_t L:1; /* Line locked */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t addr:16; /* Phys mem addr (33..18) */ -#else - uint64_t addr:16; /* Phys mem addr (33..18) */ - uint64_t U:1; /* Use, LRU eviction */ - uint64_t L:1; /* Line locked */ - uint64_t D:1; /* Line dirty */ - uint64_t V:1; /* Line valid */ - uint64_t reserved:44; -#endif + __BITFIELD_FIELD(uint64_t reserved:44, + __BITFIELD_FIELD(uint64_t V:1, /* Line valid */ + __BITFIELD_FIELD(uint64_t D:1, /* Line dirty */ + __BITFIELD_FIELD(uint64_t L:1, /* Line locked */ + __BITFIELD_FIELD(uint64_t U:1, /* Use, LRU eviction */ + __BITFIELD_FIELD(uint64_t addr:16, /* Phys addr (33..18) */ + ;)))))) } cn58xx; struct cvmx_l2c_tag_cn58xx cn56xx; /* 2048 sets */ struct cvmx_l2c_tag_cn31xx cn52xx; /* 512 sets */ @@ -629,8 +596,8 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index) union __cvmx_l2c_tag tag_val; uint64_t dbg_addr = CVMX_L2C_DBG; unsigned long flags; - union cvmx_l2c_dbg debug_val; + debug_val.u64 = 0; /* * For low core count parts, the core number is always small @@ -683,8 +650,8 @@ static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index) union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index) { union cvmx_l2c_tag tag; - tag.u64 = 0; + tag.u64 = 0; if ((int)association >= cvmx_l2c_get_num_assoc()) { cvmx_dprintf("ERROR: cvmx_l2c_get_tag association out of range\n"); return tag; @@ -767,10 +734,12 @@ uint32_t cvmx_l2c_address_to_index(uint64_t addr) if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { union cvmx_l2c_ctl l2c_ctl; + l2c_ctl.u64 = cvmx_read_csr(CVMX_L2C_CTL); indxalias = !l2c_ctl.s.disidxalias; } else { union cvmx_l2c_cfg l2c_cfg; + l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG); indxalias = l2c_cfg.s.idxalias; } @@ -778,6 +747,7 @@ uint32_t cvmx_l2c_address_to_index(uint64_t addr) if (indxalias) { if (OCTEON_IS_MODEL(OCTEON_CN63XX)) { uint32_t a_14_12 = (idx / (CVMX_L2C_MEMBANK_SELECT_SIZE/(1<<CVMX_L2C_IDX_ADDR_SHIFT))) & 0x7; + idx ^= idx / cvmx_l2c_get_num_sets(); idx ^= a_14_12; } else { @@ -801,6 +771,7 @@ int cvmx_l2c_get_cache_size_bytes(void) int cvmx_l2c_get_set_bits(void) { int l2_set_bits; + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) l2_set_bits = 11; /* 2048 sets */ else if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN63XX)) @@ -828,6 +799,7 @@ int cvmx_l2c_get_num_sets(void) int cvmx_l2c_get_num_assoc(void) { int l2_assoc; + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN58XX) || @@ -869,16 +841,17 @@ int cvmx_l2c_get_num_assoc(void) else if (mio_fus_dat3.s.l2c_crip == 1) l2_assoc = 12; } else { - union cvmx_l2d_fus3 val; - val.u64 = cvmx_read_csr(CVMX_L2D_FUS3); + uint64_t l2d_fus3; + + l2d_fus3 = cvmx_read_csr(CVMX_L2D_FUS3); /* * Using shifts here, as bit position names are * different for each model but they all mean the * same. */ - if ((val.u64 >> 35) & 0x1) + if ((l2d_fus3 >> 35) & 0x1) l2_assoc = l2_assoc >> 2; - else if ((val.u64 >> 34) & 0x1) + else if ((l2d_fus3 >> 34) & 0x1) l2_assoc = l2_assoc >> 1; } return l2_assoc; diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index d08a2bce653c..341052387b49 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c @@ -4,7 +4,7 @@ * Contact: support@caviumnetworks.com * This file is part of the OCTEON SDK * - * Copyright (c) 2003-2010 Cavium Networks + * Copyright (c) 2003-2017 Cavium, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, Version 2, as @@ -63,16 +63,15 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, char pass[4]; int clock_mhz; const char *suffix; - union cvmx_l2d_fus3 fus3; int num_cores; union cvmx_mio_fus_dat2 fus_dat2; union cvmx_mio_fus_dat3 fus_dat3; char fuse_model[10]; uint32_t fuse_data = 0; + uint64_t l2d_fus3 = 0; - fus3.u64 = 0; if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN5XXX)) - fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3); + l2d_fus3 = (cvmx_read_csr(CVMX_L2D_FUS3) >> 34) & 0x3; fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3); num_cores = cvmx_octeon_num_cores(); @@ -192,7 +191,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, /* Now figure out the family, the first two digits */ switch ((chip_id >> 8) & 0xff) { case 0: /* CN38XX, CN37XX or CN36XX */ - if (fus3.cn38xx.crip_512k) { + if (l2d_fus3) { /* * For some unknown reason, the 16 core one is * called 37 instead of 36. @@ -223,7 +222,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, } break; case 1: /* CN31XX or CN3020 */ - if ((chip_id & 0x10) || fus3.cn31xx.crip_128k) + if ((chip_id & 0x10) || l2d_fus3) family = "30"; else family = "31"; @@ -246,7 +245,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, case 2: /* CN3010 or CN3005 */ family = "30"; /* A chip with half cache is an 05 */ - if (fus3.cn30xx.crip_64k) + if (l2d_fus3) core_model = "05"; /* * This series of chips didn't follow the standard @@ -267,7 +266,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, case 3: /* CN58XX */ family = "58"; /* Special case. 4 core, half cache (CP with half cache) */ - if ((num_cores == 4) && fus3.cn58xx.crip_1024k && !strncmp(suffix, "CP", 2)) + if ((num_cores == 4) && l2d_fus3 && !strncmp(suffix, "CP", 2)) core_model = "29"; /* Pass 1 uses different encodings for pass numbers */ @@ -290,7 +289,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, break; case 4: /* CN57XX, CN56XX, CN55XX, CN54XX */ if (fus_dat2.cn56xx.raid_en) { - if (fus3.cn56xx.crip_1024k) + if (l2d_fus3) family = "55"; else family = "57"; @@ -309,7 +308,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, if (fus_dat3.cn56xx.bar2_en) suffix = "NSPB2"; } - if (fus3.cn56xx.crip_1024k) + if (l2d_fus3) family = "54"; else family = "56"; @@ -319,7 +318,7 @@ static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, family = "50"; break; case 7: /* CN52XX */ - if (fus3.cn52xx.crip_256k) + if (l2d_fus3) family = "51"; else family = "52"; |