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