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. 7a47a12beSStefan Roese * See file CREDITS for list of people who contributed to this 8a47a12beSStefan Roese * project. 9a47a12beSStefan Roese * 10a47a12beSStefan Roese * This program is free software; you can redistribute it and/or 11a47a12beSStefan Roese * modify it under the terms of the GNU General Public License as 12a47a12beSStefan Roese * published by the Free Software Foundation; either version 2 of 13a47a12beSStefan Roese * the License, or (at your option) any later version. 14a47a12beSStefan Roese * 15a47a12beSStefan Roese * This program is distributed in the hope that it will be useful, 16a47a12beSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 17a47a12beSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18a47a12beSStefan Roese * GNU General Public License for more details. 19a47a12beSStefan Roese * 20a47a12beSStefan Roese * You should have received a copy of the GNU General Public License 21a47a12beSStefan Roese * along with this program; if not, write to the Free Software 22a47a12beSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23a47a12beSStefan Roese * MA 02111-1307 USA 24a47a12beSStefan Roese */ 25a47a12beSStefan Roese 26a47a12beSStefan Roese #include <config.h> 27a47a12beSStefan Roese #include <common.h> 28a47a12beSStefan Roese #include <command.h> 29a47a12beSStefan Roese #include <tsec.h> 30c916d7c9SKumar Gala #include <fm_eth.h> 31a47a12beSStefan Roese #include <netdev.h> 32a47a12beSStefan Roese #include <asm/cache.h> 33a47a12beSStefan Roese #include <asm/io.h> 34a47a12beSStefan Roese 35a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR; 36a47a12beSStefan Roese 372ed2e912SKim Phillips static struct cpu_type cpu_type_list[] = { 38a47a12beSStefan Roese #if defined(CONFIG_MPC85xx) 39a47a12beSStefan Roese CPU_TYPE_ENTRY(8533, 8533, 1), 40a47a12beSStefan Roese CPU_TYPE_ENTRY(8535, 8535, 1), 41a47a12beSStefan Roese CPU_TYPE_ENTRY(8536, 8536, 1), 42a47a12beSStefan Roese CPU_TYPE_ENTRY(8540, 8540, 1), 43a47a12beSStefan Roese CPU_TYPE_ENTRY(8541, 8541, 1), 44a47a12beSStefan Roese CPU_TYPE_ENTRY(8543, 8543, 1), 45a47a12beSStefan Roese CPU_TYPE_ENTRY(8544, 8544, 1), 46a47a12beSStefan Roese CPU_TYPE_ENTRY(8545, 8545, 1), 4748f6a5c3SYork Sun CPU_TYPE_ENTRY(8547, 8547, 1), 48a47a12beSStefan Roese CPU_TYPE_ENTRY(8548, 8548, 1), 49a47a12beSStefan Roese CPU_TYPE_ENTRY(8555, 8555, 1), 50a47a12beSStefan Roese CPU_TYPE_ENTRY(8560, 8560, 1), 51a47a12beSStefan Roese CPU_TYPE_ENTRY(8567, 8567, 1), 52a47a12beSStefan Roese CPU_TYPE_ENTRY(8568, 8568, 1), 53a47a12beSStefan Roese CPU_TYPE_ENTRY(8569, 8569, 1), 54a47a12beSStefan Roese CPU_TYPE_ENTRY(8572, 8572, 2), 55b8cdd014SPoonam Aggrwal CPU_TYPE_ENTRY(P1010, P1010, 1), 56a47a12beSStefan Roese CPU_TYPE_ENTRY(P1011, P1011, 1), 57a47a12beSStefan Roese CPU_TYPE_ENTRY(P1012, P1012, 1), 58a47a12beSStefan Roese CPU_TYPE_ENTRY(P1013, P1013, 1), 59b5debec5SPoonam Aggrwal CPU_TYPE_ENTRY(P1014, P1014, 1), 6067a719daSRoy Zang CPU_TYPE_ENTRY(P1017, P1017, 1), 61a47a12beSStefan Roese CPU_TYPE_ENTRY(P1020, P1020, 2), 62a47a12beSStefan Roese CPU_TYPE_ENTRY(P1021, P1021, 2), 63a47a12beSStefan Roese CPU_TYPE_ENTRY(P1022, P1022, 2), 6467a719daSRoy Zang CPU_TYPE_ENTRY(P1023, P1023, 2), 65093cffbeSKumar Gala CPU_TYPE_ENTRY(P1024, P1024, 2), 66093cffbeSKumar Gala CPU_TYPE_ENTRY(P1025, P1025, 2), 67a47a12beSStefan Roese CPU_TYPE_ENTRY(P2010, P2010, 1), 68a47a12beSStefan Roese CPU_TYPE_ENTRY(P2020, P2020, 2), 69f193e3daSKumar Gala CPU_TYPE_ENTRY(P2040, P2040, 4), 701f97987aSKumar Gala CPU_TYPE_ENTRY(P2041, P2041, 4), 71c26de2d8SKumar Gala CPU_TYPE_ENTRY(P3041, P3041, 4), 72a47a12beSStefan Roese CPU_TYPE_ENTRY(P4040, P4040, 4), 73a47a12beSStefan Roese CPU_TYPE_ENTRY(P4080, P4080, 8), 7419dbcc96SKumar Gala CPU_TYPE_ENTRY(P5010, P5010, 1), 7519dbcc96SKumar Gala CPU_TYPE_ENTRY(P5020, P5020, 2), 764905443fSTimur Tabi CPU_TYPE_ENTRY(P5021, P5021, 2), 774905443fSTimur Tabi CPU_TYPE_ENTRY(P5040, P5040, 4), 789e758758SYork Sun CPU_TYPE_ENTRY(T4240, T4240, 0), 799e758758SYork Sun CPU_TYPE_ENTRY(T4120, T4120, 0), 80*b6240846SYork Sun CPU_TYPE_ENTRY(T4160, T4160, 0), 81d2404141SYork Sun CPU_TYPE_ENTRY(B4860, B4860, 0), 82d2404141SYork Sun CPU_TYPE_ENTRY(G4860, G4860, 0), 83d2404141SYork Sun CPU_TYPE_ENTRY(G4060, G4060, 0), 84d2404141SYork Sun CPU_TYPE_ENTRY(B4440, B4440, 0), 85d2404141SYork Sun CPU_TYPE_ENTRY(G4440, G4440, 0), 86d2404141SYork Sun CPU_TYPE_ENTRY(B4420, B4420, 0), 87d2404141SYork Sun CPU_TYPE_ENTRY(B4220, B4220, 0), 8819a8dbdcSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9130, 9130, 1), 8919a8dbdcSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9131, 9131, 1), 9035fe948eSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9132, 9132, 2), 9135fe948eSPrabhakar Kushwaha CPU_TYPE_ENTRY(BSC9232, 9232, 2), 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 100123bd96dSYork Sun u32 compute_ppc_cpumask(void) 101123bd96dSYork Sun { 102123bd96dSYork Sun ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 103123bd96dSYork Sun int i = 0, count = 0; 104123bd96dSYork Sun u32 cluster, mask = 0; 105123bd96dSYork Sun 106123bd96dSYork Sun do { 107123bd96dSYork Sun int j; 108123bd96dSYork Sun cluster = in_be32(&gur->tp_cluster[i++].lower); 109123bd96dSYork Sun for (j = 0; j < 4; j++) { 110123bd96dSYork Sun u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK; 111123bd96dSYork Sun u32 type = in_be32(&gur->tp_ityp[idx]); 112123bd96dSYork Sun 113123bd96dSYork Sun if (type & TP_ITYP_AV) { 114123bd96dSYork Sun if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) 115123bd96dSYork Sun mask |= 1 << count; 116123bd96dSYork Sun } 117123bd96dSYork Sun count++; 118123bd96dSYork Sun } 119123bd96dSYork Sun } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); 120123bd96dSYork Sun 121123bd96dSYork Sun return mask; 122123bd96dSYork Sun } 123123bd96dSYork Sun #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 124123bd96dSYork Sun /* 125123bd96dSYork Sun * Before chassis genenration 2, the cpumask should be hard-coded. 126123bd96dSYork Sun * In case of cpu type unknown or cpumask unset, use 1 as fail save. 127123bd96dSYork Sun */ 128123bd96dSYork Sun #define compute_ppc_cpumask() 1 129123bd96dSYork Sun #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ 130123bd96dSYork Sun 1312ed2e912SKim Phillips static struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); 132a47a12beSStefan Roese 133a47a12beSStefan Roese struct cpu_type *identify_cpu(u32 ver) 134a47a12beSStefan Roese { 135a47a12beSStefan Roese int i; 136a47a12beSStefan Roese for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) { 137a47a12beSStefan Roese if (cpu_type_list[i].soc_ver == ver) 138a47a12beSStefan Roese return &cpu_type_list[i]; 139a47a12beSStefan Roese } 140a47a12beSStefan Roese return &cpu_type_unknown; 141a47a12beSStefan Roese } 142a47a12beSStefan Roese 143fbb9ecf7STimur Tabi #define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 144fbb9ecf7STimur Tabi #define MPC8xxx_PICFRR_NCPU_SHIFT 8 145fbb9ecf7STimur Tabi 146fbb9ecf7STimur Tabi /* 147fbb9ecf7STimur Tabi * Return a 32-bit mask indicating which cores are present on this SOC. 148fbb9ecf7STimur Tabi */ 1492ed2e912SKim Phillips u32 cpu_mask(void) 150fbb9ecf7STimur Tabi { 151fbb9ecf7STimur Tabi ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; 15267ac13b1SSimon Glass struct cpu_type *cpu = gd->arch.cpu; 153fbb9ecf7STimur Tabi 154fbb9ecf7STimur Tabi /* better to query feature reporting register than just assume 1 */ 155fbb9ecf7STimur Tabi if (cpu == &cpu_type_unknown) 156fbb9ecf7STimur Tabi return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> 157fbb9ecf7STimur Tabi MPC8xxx_PICFRR_NCPU_SHIFT) + 1; 158fbb9ecf7STimur Tabi 159123bd96dSYork Sun if (cpu->num_cores == 0) 160123bd96dSYork Sun return compute_ppc_cpumask(); 161123bd96dSYork Sun 162fbb9ecf7STimur Tabi return cpu->mask; 163fbb9ecf7STimur Tabi } 164fbb9ecf7STimur Tabi 165fbb9ecf7STimur Tabi /* 166fbb9ecf7STimur Tabi * Return the number of cores on this SOC. 167fbb9ecf7STimur Tabi */ 1682ed2e912SKim Phillips int cpu_numcores(void) 1692ed2e912SKim Phillips { 17067ac13b1SSimon Glass struct cpu_type *cpu = gd->arch.cpu; 171a37c36f4SKim Phillips 172123bd96dSYork Sun /* 173123bd96dSYork Sun * Report # of cores in terms of the cpu_mask if we haven't 174123bd96dSYork Sun * figured out how many there are yet 175123bd96dSYork Sun */ 176123bd96dSYork Sun if (cpu->num_cores == 0) 177123bd96dSYork Sun return hweight32(cpu_mask()); 178a37c36f4SKim Phillips 179a47a12beSStefan Roese return cpu->num_cores; 180a47a12beSStefan Roese } 181a47a12beSStefan Roese 182fbb9ecf7STimur Tabi /* 183fbb9ecf7STimur Tabi * Check if the given core ID is valid 184fbb9ecf7STimur Tabi * 185fbb9ecf7STimur Tabi * Returns zero if it isn't, 1 if it is. 186fbb9ecf7STimur Tabi */ 187fbb9ecf7STimur Tabi int is_core_valid(unsigned int core) 188fbb9ecf7STimur Tabi { 189123bd96dSYork Sun return !!((1 << core) & cpu_mask()); 190fbb9ecf7STimur Tabi } 191fbb9ecf7STimur Tabi 192a47a12beSStefan Roese int probecpu (void) 193a47a12beSStefan Roese { 194a47a12beSStefan Roese uint svr; 195a47a12beSStefan Roese uint ver; 196a47a12beSStefan Roese 197a47a12beSStefan Roese svr = get_svr(); 198a47a12beSStefan Roese ver = SVR_SOC_VER(svr); 199a47a12beSStefan Roese 20067ac13b1SSimon Glass gd->arch.cpu = identify_cpu(ver); 201a47a12beSStefan Roese 202a47a12beSStefan Roese return 0; 203a47a12beSStefan Roese } 204a47a12beSStefan Roese 205123bd96dSYork Sun /* Once in memory, compute mask & # cores once and save them off */ 206123bd96dSYork Sun int fixup_cpu(void) 207123bd96dSYork Sun { 20867ac13b1SSimon Glass struct cpu_type *cpu = gd->arch.cpu; 209123bd96dSYork Sun 210123bd96dSYork Sun if (cpu->num_cores == 0) { 211123bd96dSYork Sun cpu->mask = cpu_mask(); 212123bd96dSYork Sun cpu->num_cores = cpu_numcores(); 213123bd96dSYork Sun } 214123bd96dSYork Sun 215123bd96dSYork Sun return 0; 216123bd96dSYork Sun } 217123bd96dSYork Sun 218a47a12beSStefan Roese /* 219a47a12beSStefan Roese * Initializes on-chip ethernet controllers. 220a47a12beSStefan Roese * to override, implement board_eth_init() 221a47a12beSStefan Roese */ 222a47a12beSStefan Roese int cpu_eth_init(bd_t *bis) 223a47a12beSStefan Roese { 224a47a12beSStefan Roese #if defined(CONFIG_ETHER_ON_FCC) 225a47a12beSStefan Roese fec_initialize(bis); 226a47a12beSStefan Roese #endif 227a47a12beSStefan Roese 228a47a12beSStefan Roese #if defined(CONFIG_UEC_ETH) 229a47a12beSStefan Roese uec_standard_init(bis); 230a47a12beSStefan Roese #endif 231a47a12beSStefan Roese 232a47a12beSStefan Roese #if defined(CONFIG_TSEC_ENET) || defined(CONFIG_MPC85XX_FEC) 233a47a12beSStefan Roese tsec_standard_init(bis); 234a47a12beSStefan Roese #endif 235a47a12beSStefan Roese 236c916d7c9SKumar Gala #ifdef CONFIG_FMAN_ENET 237c916d7c9SKumar Gala fm_standard_init(bis); 238c916d7c9SKumar Gala #endif 239a47a12beSStefan Roese return 0; 240a47a12beSStefan Roese } 241