1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. 4 */ 5 6 /* 7 * CPU specific code for the MPC83xx family. 8 * 9 * Derived from the MPC8260 and MPC85xx. 10 */ 11 12 #include <common.h> 13 #include <cpu_func.h> 14 #include <irq_func.h> 15 #include <net.h> 16 #include <time.h> 17 #include <vsprintf.h> 18 #include <watchdog.h> 19 #include <command.h> 20 #include <mpc83xx.h> 21 #include <asm/global_data.h> 22 #include <asm/processor.h> 23 #include <linux/delay.h> 24 #include <linux/libfdt.h> 25 #include <tsec.h> 26 #include <netdev.h> 27 #include <fsl_esdhc.h> 28 #if defined(CONFIG_BOOTCOUNT_LIMIT) && !defined(CONFIG_ARCH_MPC831X) 29 #include <linux/immap_qe.h> 30 #include <asm/io.h> 31 #endif 32 33 DECLARE_GLOBAL_DATA_PTR; 34 35 #ifndef CONFIG_CPU_MPC83XX 36 int checkcpu(void) 37 { 38 volatile immap_t *immr; 39 ulong clock = gd->cpu_clk; 40 u32 pvr = get_pvr(); 41 u32 spridr; 42 char buf[32]; 43 int ret; 44 int i; 45 46 const struct cpu_type { 47 char name[15]; 48 u32 partid; 49 } cpu_type_list [] = { 50 CPU_TYPE_ENTRY(8308), 51 CPU_TYPE_ENTRY(8309), 52 CPU_TYPE_ENTRY(8311), 53 CPU_TYPE_ENTRY(8313), 54 CPU_TYPE_ENTRY(8314), 55 CPU_TYPE_ENTRY(8315), 56 CPU_TYPE_ENTRY(8321), 57 CPU_TYPE_ENTRY(8323), 58 CPU_TYPE_ENTRY(8343), 59 CPU_TYPE_ENTRY(8347_TBGA_), 60 CPU_TYPE_ENTRY(8347_PBGA_), 61 CPU_TYPE_ENTRY(8349), 62 CPU_TYPE_ENTRY(8358_TBGA_), 63 CPU_TYPE_ENTRY(8358_PBGA_), 64 CPU_TYPE_ENTRY(8360), 65 CPU_TYPE_ENTRY(8377), 66 CPU_TYPE_ENTRY(8378), 67 CPU_TYPE_ENTRY(8379), 68 }; 69 70 immr = (immap_t *)CONFIG_SYS_IMMR; 71 72 ret = prt_83xx_rsr(); 73 if (ret) 74 return ret; 75 76 puts("CPU: "); 77 78 switch (pvr & 0xffff0000) { 79 case PVR_E300C1: 80 printf("e300c1, "); 81 break; 82 83 case PVR_E300C2: 84 printf("e300c2, "); 85 break; 86 87 case PVR_E300C3: 88 printf("e300c3, "); 89 break; 90 91 case PVR_E300C4: 92 printf("e300c4, "); 93 break; 94 95 default: 96 printf("Unknown core, "); 97 } 98 99 spridr = immr->sysconf.spridr; 100 101 for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) 102 if (cpu_type_list[i].partid == PARTID_NO_E(spridr)) { 103 puts("MPC"); 104 puts(cpu_type_list[i].name); 105 if (IS_E_PROCESSOR(spridr)) 106 puts("E"); 107 if ((SPR_FAMILY(spridr) == SPR_834X_FAMILY || 108 SPR_FAMILY(spridr) == SPR_836X_FAMILY) && 109 REVID_MAJOR(spridr) >= 2) 110 puts("A"); 111 printf(", Rev: %d.%d", REVID_MAJOR(spridr), 112 REVID_MINOR(spridr)); 113 break; 114 } 115 116 if (i == ARRAY_SIZE(cpu_type_list)) 117 printf("(SPRIDR %08x unknown), ", spridr); 118 119 printf(" at %s MHz, ", strmhz(buf, clock)); 120 121 printf("CSB: %s MHz\n", strmhz(buf, gd->arch.csb_clk)); 122 123 return 0; 124 } 125 #endif 126 127 #ifndef CONFIG_SYSRESET 128 int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) 129 { 130 ulong msr; 131 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 132 133 puts("Resetting the board.\n"); 134 135 /* Interrupts and MMU off */ 136 msr = mfmsr(); 137 msr &= ~(MSR_EE | MSR_IR | MSR_DR); 138 mtmsr(msr); 139 140 /* enable Reset Control Reg */ 141 immap->reset.rpr = 0x52535445; 142 sync(); 143 isync(); 144 145 /* confirm Reset Control Reg is enabled */ 146 while(!((immap->reset.rcer) & RCER_CRE)) 147 ; 148 149 udelay(200); 150 151 /* perform reset, only one bit */ 152 immap->reset.rcr = RCR_SWHR; 153 154 return 1; 155 } 156 #endif 157 158 /* 159 * Get timebase clock frequency (like cpu_clk in Hz) 160 */ 161 #ifndef CONFIG_TIMER 162 unsigned long get_tbclk(void) 163 { 164 return (gd->bus_clk + 3L) / 4L; 165 } 166 #endif 167 168 #if defined(CONFIG_WATCHDOG) 169 void watchdog_reset (void) 170 { 171 int re_enable = disable_interrupts(); 172 173 /* Reset the 83xx watchdog */ 174 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; 175 immr->wdt.swsrr = 0x556c; 176 immr->wdt.swsrr = 0xaa39; 177 178 if (re_enable) 179 enable_interrupts(); 180 } 181 #endif 182 183 #ifndef CONFIG_DM_ETH 184 /* 185 * Initializes on-chip ethernet controllers. 186 * to override, implement board_eth_init() 187 */ 188 int cpu_eth_init(struct bd_info *bis) 189 { 190 #if defined(CONFIG_UEC_ETH) 191 uec_standard_init(bis); 192 #endif 193 194 #if defined(CONFIG_TSEC_ENET) 195 tsec_standard_init(bis); 196 #endif 197 return 0; 198 } 199 #endif /* !CONFIG_DM_ETH */ 200 201 /* 202 * Initializes on-chip MMC controllers. 203 * to override, implement board_mmc_init() 204 */ 205 int cpu_mmc_init(struct bd_info *bis) 206 { 207 #ifdef CONFIG_FSL_ESDHC 208 return fsl_esdhc_mmc_init(bis); 209 #else 210 return 0; 211 #endif 212 } 213 214 void ppcDWstore(unsigned int *addr, unsigned int *value) 215 { 216 asm("lfd 1, 0(%1)\n\t" 217 "stfd 1, 0(%0)" 218 : 219 : "r" (addr), "r" (value) 220 : "memory"); 221 } 222 223 void ppcDWload(unsigned int *addr, unsigned int *ret) 224 { 225 asm("lfd 1, 0(%0)\n\t" 226 "stfd 1, 0(%1)" 227 : 228 : "r" (addr), "r" (ret) 229 : "memory"); 230 } 231