1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2018 4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc 5 */ 6 7 #include <common.h> 8 #include <bitfield.h> 9 #include <clk.h> 10 #include <cpu.h> 11 #include <dm.h> 12 13 #include "mpc83xx_cpu.h" 14 15 /** 16 * struct mpc83xx_cpu_priv - Private data for MPC83xx CPUs 17 * @e300_type: The e300 core type of the MPC83xx CPU 18 * @family: The MPC83xx family the CPU belongs to 19 * @type: The MPC83xx type of the CPU 20 * @is_e_processor: Flag indicating whether the CPU is a E processor or not 21 * @is_a_variant: Flag indicating whtther the CPU is a A variant or not 22 * @revid: The revision ID of the CPU 23 * @revid.major: The major part of the CPU's revision ID 24 * @revid.minor: The minor part of the CPU's revision ID 25 */ 26 struct mpc83xx_cpu_priv { 27 enum e300_type e300_type; 28 enum mpc83xx_cpu_family family; 29 enum mpc83xx_cpu_type type; 30 bool is_e_processor; 31 bool is_a_variant; 32 struct { 33 uint major; 34 uint minor; 35 } revid; 36 }; 37 38 int checkcpu(void) 39 { 40 /* Activate all CPUs from board_f.c */ 41 return cpu_probe_all(); 42 } 43 44 /** 45 * get_spridr() - Read SPRIDR (System Part and Revision ID Register) of CPU 46 * 47 * Return: The SPRIDR value 48 */ 49 static inline u32 get_spridr(void) 50 { 51 immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; 52 53 return in_be32(&immr->sysconf.spridr); 54 } 55 56 /** 57 * determine_type() - Determine CPU family of MPC83xx device 58 * @dev: CPU device from which to read CPU family from 59 */ 60 static inline void determine_family(struct udevice *dev) 61 { 62 struct mpc83xx_cpu_priv *priv = dev_get_priv(dev); 63 /* Upper 12 bits of PARTID field (bits 0-23 in SPRIDR) */ 64 const u32 PARTID_FAMILY_MASK = 0xFFF00000; 65 66 switch (bitfield_extract_by_mask(get_spridr(), PARTID_FAMILY_MASK)) { 67 case 0x810: 68 case 0x811: 69 priv->family = FAMILY_830X; 70 break; 71 case 0x80B: 72 priv->family = FAMILY_831X; 73 break; 74 case 0x806: 75 priv->family = FAMILY_832X; 76 break; 77 case 0x803: 78 priv->family = FAMILY_834X; 79 break; 80 case 0x804: 81 priv->family = FAMILY_836X; 82 break; 83 case 0x80C: 84 priv->family = FAMILY_837X; 85 break; 86 default: 87 priv->family = FAMILY_UNKNOWN; 88 } 89 } 90 91 /** 92 * determine_type() - Determine CPU type of MPC83xx device 93 * @dev: CPU device from which to read CPU type from 94 */ 95 static inline void determine_type(struct udevice *dev) 96 { 97 struct mpc83xx_cpu_priv *priv = dev_get_priv(dev); 98 /* Upper 16 bits of PVR (Processor Version Register) */ 99 const u32 PCR_UPPER_MASK = 0xFFFF0000; 100 u32 val; 101 102 val = bitfield_extract_by_mask(get_spridr(), PCR_UPPER_MASK); 103 104 /* Mask out E-variant bit */ 105 switch (val & 0xFFFE) { 106 case 0x8100: 107 priv->type = TYPE_8308; 108 break; 109 case 0x8110: 110 priv->type = TYPE_8309; 111 break; 112 case 0x80B2: 113 priv->type = TYPE_8311; 114 break; 115 case 0x80B0: 116 priv->type = TYPE_8313; 117 break; 118 case 0x80B6: 119 priv->type = TYPE_8314; 120 break; 121 case 0x80B4: 122 priv->type = TYPE_8315; 123 break; 124 case 0x8066: 125 priv->type = TYPE_8321; 126 break; 127 case 0x8062: 128 priv->type = TYPE_8323; 129 break; 130 case 0x8036: 131 priv->type = TYPE_8343; 132 break; 133 case 0x8032: 134 priv->type = TYPE_8347_TBGA; 135 break; 136 case 0x8034: 137 priv->type = TYPE_8347_PBGA; 138 break; 139 case 0x8030: 140 priv->type = TYPE_8349; 141 break; 142 case 0x804A: 143 priv->type = TYPE_8358_TBGA; 144 break; 145 case 0x804E: 146 priv->type = TYPE_8358_PBGA; 147 break; 148 case 0x8048: 149 priv->type = TYPE_8360; 150 break; 151 case 0x80C6: 152 priv->type = TYPE_8377; 153 break; 154 case 0x80C4: 155 priv->type = TYPE_8378; 156 break; 157 case 0x80C2: 158 priv->type = TYPE_8379; 159 break; 160 default: 161 priv->type = TYPE_UNKNOWN; 162 } 163 } 164 165 /** 166 * determine_e300_type() - Determine e300 core type of MPC83xx device 167 * @dev: CPU device from which to read e300 core type from 168 */ 169 static inline void determine_e300_type(struct udevice *dev) 170 { 171 struct mpc83xx_cpu_priv *priv = dev_get_priv(dev); 172 /* Upper 16 bits of PVR (Processor Version Register) */ 173 const u32 PCR_UPPER_MASK = 0xFFFF0000; 174 u32 pvr = get_pvr(); 175 176 switch ((pvr & PCR_UPPER_MASK) >> 16) { 177 case 0x8083: 178 priv->e300_type = E300C1; 179 break; 180 case 0x8084: 181 priv->e300_type = E300C2; 182 break; 183 case 0x8085: 184 priv->e300_type = E300C3; 185 break; 186 case 0x8086: 187 priv->e300_type = E300C4; 188 break; 189 default: 190 priv->e300_type = E300_UNKNOWN; 191 } 192 } 193 194 /** 195 * determine_revid() - Determine revision ID of CPU device 196 * @dev: CPU device from which to read revision ID 197 */ 198 static inline void determine_revid(struct udevice *dev) 199 { 200 struct mpc83xx_cpu_priv *priv = dev_get_priv(dev); 201 u32 REVID_MAJOR_MASK; 202 u32 REVID_MINOR_MASK; 203 u32 spridr = get_spridr(); 204 205 if (priv->family == FAMILY_834X) { 206 REVID_MAJOR_MASK = 0x0000FF00; 207 REVID_MINOR_MASK = 0x000000FF; 208 } else { 209 REVID_MAJOR_MASK = 0x000000F0; 210 REVID_MINOR_MASK = 0x0000000F; 211 } 212 213 priv->revid.major = bitfield_extract_by_mask(spridr, REVID_MAJOR_MASK); 214 priv->revid.minor = bitfield_extract_by_mask(spridr, REVID_MINOR_MASK); 215 } 216 217 /** 218 * determine_cpu_data() - Determine CPU information from hardware 219 * @dev: CPU device from which to read information 220 */ 221 static void determine_cpu_data(struct udevice *dev) 222 { 223 struct mpc83xx_cpu_priv *priv = dev_get_priv(dev); 224 const u32 E_FLAG_MASK = 0x00010000; 225 u32 spridr = get_spridr(); 226 227 determine_family(dev); 228 determine_type(dev); 229 determine_e300_type(dev); 230 determine_revid(dev); 231 232 if ((priv->family == FAMILY_834X || 233 priv->family == FAMILY_836X) && priv->revid.major >= 2) 234 priv->is_a_variant = true; 235 236 priv->is_e_processor = !bitfield_extract_by_mask(spridr, E_FLAG_MASK); 237 } 238 239 static int mpc83xx_cpu_get_desc(struct udevice *dev, char *buf, int size) 240 { 241 struct mpc83xx_cpu_priv *priv = dev_get_priv(dev); 242 struct clk core_clk; 243 struct clk csb_clk; 244 char core_freq[32]; 245 char csb_freq[32]; 246 int ret; 247 248 ret = clk_get_by_index(dev, 0, &core_clk); 249 if (ret) { 250 debug("%s: Failed to get core clock (err = %d)\n", 251 dev->name, ret); 252 return ret; 253 } 254 255 ret = clk_get_by_index(dev, 1, &csb_clk); 256 if (ret) { 257 debug("%s: Failed to get CSB clock (err = %d)\n", 258 dev->name, ret); 259 return ret; 260 } 261 262 determine_cpu_data(dev); 263 264 snprintf(buf, size, 265 "%s, MPC%s%s%s, Rev: %d.%d at %s MHz, CSB: %s MHz", 266 e300_names[priv->e300_type], 267 cpu_type_names[priv->type], 268 priv->is_e_processor ? "E" : "", 269 priv->is_a_variant ? "A" : "", 270 priv->revid.major, 271 priv->revid.minor, 272 strmhz(core_freq, clk_get_rate(&core_clk)), 273 strmhz(csb_freq, clk_get_rate(&csb_clk))); 274 275 return 0; 276 } 277 278 static int mpc83xx_cpu_get_info(struct udevice *dev, struct cpu_info *info) 279 { 280 struct clk clock; 281 int ret; 282 ulong freq; 283 284 ret = clk_get_by_index(dev, 0, &clock); 285 if (ret) { 286 debug("%s: Failed to get core clock (err = %d)\n", 287 dev->name, ret); 288 return ret; 289 } 290 291 freq = clk_get_rate(&clock); 292 if (!freq) { 293 debug("%s: Core clock speed is zero\n", dev->name); 294 return -EINVAL; 295 } 296 297 info->cpu_freq = freq; 298 info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU); 299 300 return 0; 301 } 302 303 static int mpc83xx_cpu_get_count(struct udevice *dev) 304 { 305 /* We have one e300cX core */ 306 return 1; 307 } 308 309 static int mpc83xx_cpu_get_vendor(struct udevice *dev, char *buf, int size) 310 { 311 snprintf(buf, size, "NXP"); 312 313 return 0; 314 } 315 316 static const struct cpu_ops mpc83xx_cpu_ops = { 317 .get_desc = mpc83xx_cpu_get_desc, 318 .get_info = mpc83xx_cpu_get_info, 319 .get_count = mpc83xx_cpu_get_count, 320 .get_vendor = mpc83xx_cpu_get_vendor, 321 }; 322 323 static int mpc83xx_cpu_probe(struct udevice *dev) 324 { 325 return 0; 326 } 327 328 static const struct udevice_id mpc83xx_cpu_ids[] = { 329 { .compatible = "fsl,mpc83xx", }, 330 { .compatible = "fsl,mpc8308", }, 331 { .compatible = "fsl,mpc8309", }, 332 { .compatible = "fsl,mpc8313", }, 333 { .compatible = "fsl,mpc8315", }, 334 { .compatible = "fsl,mpc832x", }, 335 { .compatible = "fsl,mpc8349", }, 336 { .compatible = "fsl,mpc8360", }, 337 { .compatible = "fsl,mpc8379", }, 338 { /* sentinel */ } 339 }; 340 341 U_BOOT_DRIVER(mpc83xx_cpu) = { 342 .name = "mpc83xx_cpu", 343 .id = UCLASS_CPU, 344 .of_match = mpc83xx_cpu_ids, 345 .probe = mpc83xx_cpu_probe, 346 .priv_auto_alloc_size = sizeof(struct mpc83xx_cpu_priv), 347 .ops = &mpc83xx_cpu_ops, 348 .flags = DM_FLAG_PRE_RELOC, 349 }; 350