diff options
author | Tom Rini <trini@konsulko.com> | 2018-12-03 07:26:16 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-12-03 07:26:16 -0500 |
commit | e54457f7495e6fe527d1bad0d8cc7b717558a759 (patch) | |
tree | 5fe3560f24686a1152053805b3555c7423d52271 /arch/arc/lib/cpu.c | |
parent | 952061352acfd24034e6990b6b7d32cded020c0a (diff) | |
parent | 6ef705b1575045f7b63bf011a0774228159715b2 (diff) |
Merge tag 'arc-updates-for-2019.01-rc1' of git://git.denx.de/u-boot-arc
We introduce much better automatic identification of ARC cores.
1. Try to match found HW features to known ARC core templates
2. Print CPU frequency for all ARC boards
3. Add more board-specific info
Diffstat (limited to 'arch/arc/lib/cpu.c')
-rw-r--r-- | arch/arc/lib/cpu.c | 200 |
1 files changed, 180 insertions, 20 deletions
diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c index a969a167228..07daaa8d155 100644 --- a/arch/arc/lib/cpu.c +++ b/arch/arc/lib/cpu.c @@ -4,6 +4,7 @@ */ #include <common.h> +#include <malloc.h> #include <asm/arcregs.h> #include <asm/cache.h> @@ -35,34 +36,193 @@ int dram_init(void) } #ifdef CONFIG_DISPLAY_CPUINFO -const char *decode_identity(void) +const char *arc_700_version(int arcver, char *name, int name_len) { - int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff; + const char *arc_ver; + + switch (arcver) { + case 0x32: + arc_ver = "v4.4-4.5"; + break; + case 0x33: + arc_ver = "v4.6-v4.9"; + break; + case 0x34: + arc_ver = "v4.10"; + break; + case 0x35: + arc_ver = "v4.11"; + break; + default: + arc_ver = "unknown version"; + } + + snprintf(name, name_len, "ARC 700 %s", arc_ver); + + return name; +} + +struct em_template_t { + const bool cache; + const bool dsp; + const bool xymem; + const char name[8]; +}; + +static const struct em_template_t em_versions[] = { + {false, false, false, "EM4"}, + {true, false, false, "EM6"}, + {false, true, false, "EM5D"}, + {true, true, false, "EM7D"}, + {false, true, true, "EM9D"}, + {true, true, true, "EM11D"}, +}; + +const char *arc_em_version(int arcver, char *name, int name_len) +{ + const char *arc_name = "EM"; + const char *arc_ver; + bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD); + bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD); + bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD); + int i; + + for (i = 0; i++ < sizeof(em_versions) / sizeof(struct em_template_t);) { + if (em_versions[i].cache == cache && + em_versions[i].dsp == dsp && + em_versions[i].xymem == xymem) { + arc_name = em_versions[i].name; + break; + } + } + + switch (arcver) { + case 0x41: + arc_ver = "v1.1a"; + break; + case 0x42: + arc_ver = "v3.0"; + break; + case 0x43: + arc_ver = "v4.0"; + break; + case 0x44: + arc_ver = "v5.0"; + break; + default: + arc_ver = "unknown version"; + } + + snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver); + + return name; +} + +struct hs_template_t { + const bool cache; + const bool mmu; + const bool dual_issue; + const bool dsp; + const char name[8]; +}; + +static const struct hs_template_t hs_versions[] = { + {false, false, false, false, "HS34"}, + {true, false, false, false, "HS36"}, + {true, true, false, false, "HS38"}, + {false, false, true, false, "HS44"}, + {true, false, true, false, "HS46"}, + {true, true, true, false, "HS48"}, + {false, false, true, true, "HS45D"}, + {true, false, true, true, "HS47D"}, +}; + +const char *arc_hs_version(int arcver, char *name, int name_len) +{ + const char *arc_name = "HS"; + const char *arc_ver; + bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD); + bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD); + bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR); + bool dual_issue = arcver == 0x54 ? true : false; + int i; + + for (i = 0; i++ < sizeof(hs_versions) / sizeof(struct hs_template_t);) { + if (hs_versions[i].cache == cache && + hs_versions[i].mmu == mmu && + hs_versions[i].dual_issue == dual_issue && + hs_versions[i].dsp == dsp) { + arc_name = hs_versions[i].name; + break; + } + } switch (arcver) { - /* ARCompact cores */ - case 0x32: return "ARC 700 v4.4-4.5"; - case 0x33: return "ARC 700 v4.6-v4.9"; - case 0x34: return "ARC 700 v4.10"; - case 0x35: return "ARC 700 v4.11"; - - /* ARCv2 cores */ - case 0x41: return "ARC EM v1.1a"; - case 0x42: return "ARC EM v3.0"; - case 0x43: return "ARC EM v4.0"; - case 0x50: return "ARC HS v1.0"; - case 0x51: return "ARC EM v2.0"; - case 0x52: return "ARC EM v2.1"; - case 0x53: return "ARC HS v3.0"; - case 0x54: return "ARC HS v4.0"; - - default: return "Unknown ARC core"; + case 0x50: + arc_ver = "v1.0"; + break; + case 0x51: + arc_ver = "v2.0"; + break; + case 0x52: + arc_ver = "v2.1c"; + break; + case 0x53: + arc_ver = "v3.0"; + break; + case 0x54: + arc_ver = "v4.0"; + break; + default: + arc_ver = "unknown version"; } + + snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver); + + return name; +} + +const char *decode_identity(void) +{ +#define MAX_CPU_NAME_LEN 64 + + int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff; + char *name = malloc(MAX_CPU_NAME_LEN); + + if (arcver >= 0x50) + return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN); + else if (arcver >= 0x40) + return arc_em_version(arcver, name, MAX_CPU_NAME_LEN); + else if (arcver >= 0x30) + return arc_700_version(arcver, name, MAX_CPU_NAME_LEN); + else + return "Unknown ARC core"; +} + +const char *decode_subsystem(void) +{ + int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0); + + switch (subsys_type) { + case 0: return NULL; + case 2: return "ARC Sensor & Control IP Subsystem"; + case 3: return "ARC Data Fusion IP Subsystem"; + case 4: return "ARC Secure Subsystem"; + default: return "Unknown subsystem"; + }; } __weak int print_cpuinfo(void) { - printf("CPU: %s\n", decode_identity()); + const char *subsys_name = decode_subsystem(); + char mhz[8]; + + printf("CPU: %s at %s MHz\n", decode_identity(), + strmhz(mhz, gd->cpu_clk)); + + if (subsys_name) + printf("Subsys:%s\n", subsys_name); + return 0; } #endif /* CONFIG_DISPLAY_CPUINFO */ |