1a47a12beSStefan Roese /* 219a8dbdcSPrabhakar Kushwaha * Copyright 2009-2012 Freescale Semiconductor, Inc. 3a47a12beSStefan Roese * 4a47a12beSStefan Roese * This file is derived from arch/powerpc/cpu/mpc85xx/cpu.c and 5a47a12beSStefan Roese * arch/powerpc/cpu/mpc86xx/cpu.c. Basically this file contains 6a47a12beSStefan Roese * cpu specific common code for 85xx/86xx processors. 71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 8a47a12beSStefan Roese */ 9a47a12beSStefan Roese 10a47a12beSStefan Roese #include <config.h> 11a47a12beSStefan Roese #include <common.h> 12a47a12beSStefan Roese #include <command.h> 13a47a12beSStefan Roese #include <tsec.h> 14c916d7c9SKumar Gala #include <fm_eth.h> 15a47a12beSStefan Roese #include <netdev.h> 16a47a12beSStefan Roese #include <asm/cache.h> 17a47a12beSStefan Roese #include <asm/io.h> 18a47a12beSStefan Roese 19a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR; 20a47a12beSStefan Roese 212ed2e912SKim Phillips static struct cpu_type cpu_type_list[] = { 22a47a12beSStefan Roese #if defined(CONFIG_MPC85xx) 23a47a12beSStefan Roese CPU_TYPE_ENTRY(8533, 8533, 1), 24a47a12beSStefan Roese CPU_TYPE_ENTRY(8535, 8535, 1), 25a47a12beSStefan Roese CPU_TYPE_ENTRY(8536, 8536, 1), 26a47a12beSStefan Roese CPU_TYPE_ENTRY(8540, 8540, 1), 27a47a12beSStefan Roese CPU_TYPE_ENTRY(8541, 8541, 1), 28a47a12beSStefan Roese CPU_TYPE_ENTRY(8543, 8543, 1), 29a47a12beSStefan Roese CPU_TYPE_ENTRY(8544, 8544, 1), 30a47a12beSStefan Roese CPU_TYPE_ENTRY(8545, 8545, 1), 3148f6a5c3SYork Sun CPU_TYPE_ENTRY(8547, 8547, 1), 32a47a12beSStefan Roese CPU_TYPE_ENTRY(8548, 8548, 1), 33a47a12beSStefan Roese CPU_TYPE_ENTRY(8555, 8555, 1), 34a47a12beSStefan Roese CPU_TYPE_ENTRY(8560, 8560, 1), 35a47a12beSStefan Roese CPU_TYPE_ENTRY(8567, 8567, 1), 36a47a12beSStefan Roese CPU_TYPE_ENTRY(8568, 8568, 1), 37a47a12beSStefan Roese CPU_TYPE_ENTRY(8569, 8569, 1), 38a47a12beSStefan Roese CPU_TYPE_ENTRY(8572, 8572, 2), 39b8cdd014SPoonam Aggrwal CPU_TYPE_ENTRY(P1010, P1010, 1), 40a47a12beSStefan Roese CPU_TYPE_ENTRY(P1011, P1011, 1), 41a47a12beSStefan Roese CPU_TYPE_ENTRY(P1012, P1012, 1), 42a47a12beSStefan Roese CPU_TYPE_ENTRY(P1013, P1013, 1), 43b5debec5SPoonam Aggrwal CPU_TYPE_ENTRY(P1014, P1014, 1), 4467a719daSRoy Zang CPU_TYPE_ENTRY(P1017, P1017, 1), 45a47a12beSStefan Roese CPU_TYPE_ENTRY(P1020, P1020, 2), 46a47a12beSStefan Roese CPU_TYPE_ENTRY(P1021, P1021, 2), 47a47a12beSStefan Roese CPU_TYPE_ENTRY(P1022, P1022, 2), 4867a719daSRoy Zang CPU_TYPE_ENTRY(P1023, P1023, 2), 49093cffbeSKumar Gala CPU_TYPE_ENTRY(P1024, P1024, 2), 50093cffbeSKumar Gala CPU_TYPE_ENTRY(P1025, P1025, 2), 51a47a12beSStefan Roese CPU_TYPE_ENTRY(P2010, P2010, 1), 52a47a12beSStefan Roese CPU_TYPE_ENTRY(P2020, P2020, 2), 53f193e3daSKumar Gala CPU_TYPE_ENTRY(P2040, P2040, 4), 541f97987aSKumar Gala CPU_TYPE_ENTRY(P2041, P2041, 4), 55c26de2d8SKumar Gala CPU_TYPE_ENTRY(P3041, P3041, 4), 56a47a12beSStefan Roese CPU_TYPE_ENTRY(P4040, P4040, 4), 57a47a12beSStefan Roese CPU_TYPE_ENTRY(P4080, P4080, 8), 5819dbcc96SKumar Gala CPU_TYPE_ENTRY(P5010, P5010, 1), 5919dbcc96SKumar Gala CPU_TYPE_ENTRY(P5020, P5020, 2), 604905443fSTimur Tabi CPU_TYPE_ENTRY(P5021, P5021, 2), 614905443fSTimur Tabi CPU_TYPE_ENTRY(P5040, P5040, 4), 629e758758SYork Sun CPU_TYPE_ENTRY(T4240, T4240, 0), 639e758758SYork Sun CPU_TYPE_ENTRY(T4120, T4120, 0), 64b6240846SYork Sun CPU_TYPE_ENTRY(T4160, T4160, 0), 655122dfaeSShengzhou Liu CPU_TYPE_ENTRY(T4080, T4080, 4), 66d2404141SYork Sun CPU_TYPE_ENTRY(B4860, B4860, 0), 67d2404141SYork Sun CPU_TYPE_ENTRY(G4860, G4860, 0), 68d2404141SYork Sun CPU_TYPE_ENTRY(B4440, B4440, 0), 699c3fdd88SShaveta Leekha CPU_TYPE_ENTRY(B4460, B4460, 0), 70d2404141SYork Sun CPU_TYPE_ENTRY(G4440, G4440, 0), 71d2404141SYork Sun CPU_TYPE_ENTRY(B4420, B4420, 0), 72d2404141SYork Sun CPU_TYPE_ENTRY(B4220, B4220, 0), 735f208d11SYork Sun CPU_TYPE_ENTRY(T1040, T1040, 0), 745f208d11SYork Sun CPU_TYPE_ENTRY(T1041, T1041, 0), 755f208d11SYork Sun CPU_TYPE_ENTRY(T1042, T1042, 0), 765f208d11SYork Sun CPU_TYPE_ENTRY(T1020, T1020, 0), 775f208d11SYork Sun CPU_TYPE_ENTRY(T1021, T1021, 0), 785f208d11SYork Sun CPU_TYPE_ENTRY(T1022, T1022, 0), 79*f6050790SShengzhou Liu CPU_TYPE_ENTRY(T1024, T1024, 0), 80*f6050790SShengzhou Liu CPU_TYPE_ENTRY(T1023, T1023, 0), 81*f6050790SShengzhou Liu CPU_TYPE_ENTRY(T1014, T1014, 0), 82*f6050790SShengzhou Liu CPU_TYPE_ENTRY(T1013, T1013, 0), 83629d6b32SShengzhou Liu CPU_TYPE_ENTRY(T2080, T2080, 0), 84629d6b32SShengzhou Liu CPU_TYPE_ENTRY(T2081, T2081, 0), 8519a8dbdcSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9130, 9130, 1), 8619a8dbdcSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9131, 9131, 1), 8735fe948eSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9132, 9132, 2), 8835fe948eSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9232, 9232, 2), 893b75e982SMingkai Hu CPU_TYPE_ENTRY(C291, C291, 1), 903b75e982SMingkai Hu CPU_TYPE_ENTRY(C292, C292, 1), 913b75e982SMingkai Hu CPU_TYPE_ENTRY(C293, C293, 1), 92a47a12beSStefan Roese #elif defined(CONFIG_MPC86xx) 93a47a12beSStefan Roese CPU_TYPE_ENTRY(8610, 8610, 1), 94a47a12beSStefan Roese CPU_TYPE_ENTRY(8641, 8641, 2), 95a47a12beSStefan Roese CPU_TYPE_ENTRY(8641D, 8641D, 2), 96a47a12beSStefan Roese #endif 97a47a12beSStefan Roese }; 98a47a12beSStefan Roese 99123bd96dSYork Sun #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 100f6981439SYork Sun static inline u32 init_type(u32 cluster, int init_id) 101f6981439SYork Sun { 102f6981439SYork Sun ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 103f6981439SYork Sun u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK; 104f6981439SYork Sun u32 type = in_be32(&gur->tp_ityp[idx]); 105f6981439SYork Sun 106f6981439SYork Sun if (type & TP_ITYP_AV) 107f6981439SYork Sun return type; 108f6981439SYork Sun 109f6981439SYork Sun return 0; 110f6981439SYork Sun } 111f6981439SYork Sun 112123bd96dSYork Sun u32 compute_ppc_cpumask(void) 113123bd96dSYork Sun { 114f6981439SYork Sun ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 115123bd96dSYork Sun int i = 0, count = 0; 116f6981439SYork Sun u32 cluster, type, mask = 0; 117123bd96dSYork Sun 118123bd96dSYork Sun do { 119123bd96dSYork Sun int j; 120f6981439SYork Sun cluster = in_be32(&gur->tp_cluster[i].lower); 121f6981439SYork Sun for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { 122f6981439SYork Sun type = init_type(cluster, j); 123f6981439SYork Sun if (type) { 124123bd96dSYork Sun if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) 125123bd96dSYork Sun mask |= 1 << count; 126123bd96dSYork Sun count++; 127123bd96dSYork Sun } 128f6981439SYork Sun } 129f6981439SYork Sun i++; 130123bd96dSYork Sun } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); 131123bd96dSYork Sun 132123bd96dSYork Sun return mask; 133123bd96dSYork Sun } 134f6981439SYork Sun 135f6981439SYork Sun int fsl_qoriq_core_to_cluster(unsigned int core) 136f6981439SYork Sun { 137f6981439SYork Sun ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 138f6981439SYork Sun int i = 0, count = 0; 139f6981439SYork Sun u32 cluster; 140f6981439SYork Sun 141f6981439SYork Sun do { 142f6981439SYork Sun int j; 143f6981439SYork Sun cluster = in_be32(&gur->tp_cluster[i].lower); 144f6981439SYork Sun for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { 145f6981439SYork Sun if (init_type(cluster, j)) { 146f6981439SYork Sun if (count == core) 147f6981439SYork Sun return i; 148f6981439SYork Sun count++; 149f6981439SYork Sun } 150f6981439SYork Sun } 151f6981439SYork Sun i++; 152f6981439SYork Sun } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); 153f6981439SYork Sun 154f6981439SYork Sun return -1; /* cannot identify the cluster */ 155f6981439SYork Sun } 156f6981439SYork Sun 157123bd96dSYork Sun #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 158123bd96dSYork Sun /* 159123bd96dSYork Sun * Before chassis genenration 2, the cpumask should be hard-coded. 160123bd96dSYork Sun * In case of cpu type unknown or cpumask unset, use 1 as fail save. 161123bd96dSYork Sun */ 162123bd96dSYork Sun #define compute_ppc_cpumask() 1 163f6981439SYork Sun #define fsl_qoriq_core_to_cluster(x) x 164123bd96dSYork Sun #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 165123bd96dSYork Sun 1662ed2e912SKim Phillips static struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); 167a47a12beSStefan Roese 168a47a12beSStefan Roese struct cpu_type *identify_cpu(u32 ver) 169a47a12beSStefan Roese { 170a47a12beSStefan Roese int i; 171a47a12beSStefan Roese for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) { 172a47a12beSStefan Roese if (cpu_type_list[i].soc_ver == ver) 173a47a12beSStefan Roese return &cpu_type_list[i]; 174a47a12beSStefan Roese } 175a47a12beSStefan Roese return &cpu_type_unknown; 176a47a12beSStefan Roese } 177a47a12beSStefan Roese 178fbb9ecf7STimur Tabi #define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 179fbb9ecf7STimur Tabi #define MPC8xxx_PICFRR_NCPU_SHIFT 8 180fbb9ecf7STimur Tabi 181fbb9ecf7STimur Tabi /* 182fbb9ecf7STimur Tabi * Return a 32-bit mask indicating which cores are present on this SOC. 183fbb9ecf7STimur Tabi */ 184b539534dSAlexander Graf __weak u32 cpu_mask(void) 185fbb9ecf7STimur Tabi { 186fbb9ecf7STimur Tabi ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; 18767ac13b1SSimon Glass struct cpu_type *cpu = gd->arch.cpu; 188fbb9ecf7STimur Tabi 189fbb9ecf7STimur Tabi /* better to query feature reporting register than just assume 1 */ 190fbb9ecf7STimur Tabi if (cpu == &cpu_type_unknown) 191fbb9ecf7STimur Tabi return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> 192fbb9ecf7STimur Tabi MPC8xxx_PICFRR_NCPU_SHIFT) + 1; 193fbb9ecf7STimur Tabi 194123bd96dSYork Sun if (cpu->num_cores == 0) 195123bd96dSYork Sun return compute_ppc_cpumask(); 196123bd96dSYork Sun 197fbb9ecf7STimur Tabi return cpu->mask; 198fbb9ecf7STimur Tabi } 199fbb9ecf7STimur Tabi 200fbb9ecf7STimur Tabi /* 201fbb9ecf7STimur Tabi * Return the number of cores on this SOC. 202fbb9ecf7STimur Tabi */ 203b539534dSAlexander Graf __weak int cpu_numcores(void) 2042ed2e912SKim Phillips { 20567ac13b1SSimon Glass struct cpu_type *cpu = gd->arch.cpu; 206a37c36f4SKim Phillips 207123bd96dSYork Sun /* 208123bd96dSYork Sun * Report # of cores in terms of the cpu_mask if we haven't 209123bd96dSYork Sun * figured out how many there are yet 210123bd96dSYork Sun */ 211123bd96dSYork Sun if (cpu->num_cores == 0) 212123bd96dSYork Sun return hweight32(cpu_mask()); 213a37c36f4SKim Phillips 214a47a12beSStefan Roese return cpu->num_cores; 215a47a12beSStefan Roese } 216a47a12beSStefan Roese 217fbb9ecf7STimur Tabi /* 218fbb9ecf7STimur Tabi * Check if the given core ID is valid 219fbb9ecf7STimur Tabi * 220fbb9ecf7STimur Tabi * Returns zero if it isn't, 1 if it is. 221fbb9ecf7STimur Tabi */ 222fbb9ecf7STimur Tabi int is_core_valid(unsigned int core) 223fbb9ecf7STimur Tabi { 224123bd96dSYork Sun return !!((1 << core) & cpu_mask()); 225fbb9ecf7STimur Tabi } 226fbb9ecf7STimur Tabi 227a47a12beSStefan Roese int probecpu (void) 228a47a12beSStefan Roese { 229a47a12beSStefan Roese uint svr; 230a47a12beSStefan Roese uint ver; 231a47a12beSStefan Roese 232a47a12beSStefan Roese svr = get_svr(); 233a47a12beSStefan Roese ver = SVR_SOC_VER(svr); 234a47a12beSStefan Roese 23567ac13b1SSimon Glass gd->arch.cpu = identify_cpu(ver); 236a47a12beSStefan Roese 237a47a12beSStefan Roese return 0; 238a47a12beSStefan Roese } 239a47a12beSStefan Roese 240123bd96dSYork Sun /* Once in memory, compute mask & # cores once and save them off */ 241123bd96dSYork Sun int fixup_cpu(void) 242123bd96dSYork Sun { 24367ac13b1SSimon Glass struct cpu_type *cpu = gd->arch.cpu; 244123bd96dSYork Sun 245123bd96dSYork Sun if (cpu->num_cores == 0) { 246123bd96dSYork Sun cpu->mask = cpu_mask(); 247123bd96dSYork Sun cpu->num_cores = cpu_numcores(); 248123bd96dSYork Sun } 249123bd96dSYork Sun 250123bd96dSYork Sun return 0; 251123bd96dSYork Sun } 252123bd96dSYork Sun 253a47a12beSStefan Roese /* 254a47a12beSStefan Roese * Initializes on-chip ethernet controllers. 255a47a12beSStefan Roese * to override, implement board_eth_init() 256a47a12beSStefan Roese */ 257a47a12beSStefan Roese int cpu_eth_init(bd_t *bis) 258a47a12beSStefan Roese { 259a47a12beSStefan Roese #if defined(CONFIG_ETHER_ON_FCC) 260a47a12beSStefan Roese fec_initialize(bis); 261a47a12beSStefan Roese #endif 262a47a12beSStefan Roese 263a47a12beSStefan Roese #if defined(CONFIG_UEC_ETH) 264a47a12beSStefan Roese uec_standard_init(bis); 265a47a12beSStefan Roese #endif 266a47a12beSStefan Roese 267a47a12beSStefan Roese #if defined(CONFIG_TSEC_ENET) || defined(CONFIG_MPC85XX_FEC) 268a47a12beSStefan Roese tsec_standard_init(bis); 269a47a12beSStefan Roese #endif 270a47a12beSStefan Roese 271c916d7c9SKumar Gala #ifdef CONFIG_FMAN_ENET 272c916d7c9SKumar Gala fm_standard_init(bis); 273c916d7c9SKumar Gala #endif 274a47a12beSStefan Roese return 0; 275a47a12beSStefan Roese } 276