1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved. 4 */ 5 6 #include <common.h> 7 #include <malloc.h> 8 #include <asm/arcregs.h> 9 #include <asm/cache.h> 10 11 DECLARE_GLOBAL_DATA_PTR; 12 13 int arch_cpu_init(void) 14 { 15 timer_init(); 16 17 gd->cpu_clk = CONFIG_SYS_CLK_FREQ; 18 gd->ram_size = CONFIG_SYS_SDRAM_SIZE; 19 20 cache_init(); 21 22 return 0; 23 } 24 25 int arch_early_init_r(void) 26 { 27 gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; 28 gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; 29 return 0; 30 } 31 32 /* This is a dummy function on arc */ 33 int dram_init(void) 34 { 35 return 0; 36 } 37 38 #ifdef CONFIG_DISPLAY_CPUINFO 39 const char *arc_700_version(int arcver, char *name, int name_len) 40 { 41 const char *arc_ver; 42 43 switch (arcver) { 44 case 0x32: 45 arc_ver = "v4.4-4.5"; 46 break; 47 case 0x33: 48 arc_ver = "v4.6-v4.9"; 49 break; 50 case 0x34: 51 arc_ver = "v4.10"; 52 break; 53 case 0x35: 54 arc_ver = "v4.11"; 55 break; 56 default: 57 arc_ver = "unknown version"; 58 } 59 60 snprintf(name, name_len, "ARC 700 %s", arc_ver); 61 62 return name; 63 } 64 65 struct em_template_t { 66 const bool cache; 67 const bool dsp; 68 const bool xymem; 69 const char name[8]; 70 }; 71 72 static const struct em_template_t em_versions[] = { 73 {false, false, false, "EM4"}, 74 {true, false, false, "EM6"}, 75 {false, true, false, "EM5D"}, 76 {true, true, false, "EM7D"}, 77 {false, true, true, "EM9D"}, 78 {true, true, true, "EM11D"}, 79 }; 80 81 const char *arc_em_version(int arcver, char *name, int name_len) 82 { 83 const char *arc_name = "EM"; 84 const char *arc_ver; 85 bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD); 86 bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD); 87 bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD); 88 int i; 89 90 for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) { 91 if (em_versions[i].cache == cache && 92 em_versions[i].dsp == dsp && 93 em_versions[i].xymem == xymem) { 94 arc_name = em_versions[i].name; 95 break; 96 } 97 } 98 99 switch (arcver) { 100 case 0x41: 101 arc_ver = "v1.1a"; 102 break; 103 case 0x42: 104 arc_ver = "v3.0"; 105 break; 106 case 0x43: 107 arc_ver = "v4.0"; 108 break; 109 case 0x44: 110 arc_ver = "v5.0"; 111 break; 112 default: 113 arc_ver = "unknown version"; 114 } 115 116 snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver); 117 118 return name; 119 } 120 121 struct hs_template_t { 122 const bool cache; 123 const bool mmu; 124 const bool dual_issue; 125 const bool dsp; 126 const char name[8]; 127 }; 128 129 static const struct hs_template_t hs_versions[] = { 130 {false, false, false, false, "HS34"}, 131 {true, false, false, false, "HS36"}, 132 {true, true, false, false, "HS38"}, 133 {false, false, true, false, "HS44"}, 134 {true, false, true, false, "HS46"}, 135 {true, true, true, false, "HS48"}, 136 {false, false, true, true, "HS45D"}, 137 {true, false, true, true, "HS47D"}, 138 }; 139 140 const char *arc_hs_version(int arcver, char *name, int name_len) 141 { 142 const char *arc_name = "HS"; 143 const char *arc_ver; 144 bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD); 145 bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD); 146 bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR); 147 bool dual_issue = arcver == 0x54 ? true : false; 148 int i; 149 150 for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) { 151 if (hs_versions[i].cache == cache && 152 hs_versions[i].mmu == mmu && 153 hs_versions[i].dual_issue == dual_issue && 154 hs_versions[i].dsp == dsp) { 155 arc_name = hs_versions[i].name; 156 break; 157 } 158 } 159 160 switch (arcver) { 161 case 0x50: 162 arc_ver = "v1.0"; 163 break; 164 case 0x51: 165 arc_ver = "v2.0"; 166 break; 167 case 0x52: 168 arc_ver = "v2.1c"; 169 break; 170 case 0x53: 171 arc_ver = "v3.0"; 172 break; 173 case 0x54: 174 arc_ver = "v4.0"; 175 break; 176 default: 177 arc_ver = "unknown version"; 178 } 179 180 snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver); 181 182 return name; 183 } 184 185 const char *decode_identity(void) 186 { 187 #define MAX_CPU_NAME_LEN 64 188 189 int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff; 190 char *name = malloc(MAX_CPU_NAME_LEN); 191 192 if (arcver >= 0x50) 193 return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN); 194 else if (arcver >= 0x40) 195 return arc_em_version(arcver, name, MAX_CPU_NAME_LEN); 196 else if (arcver >= 0x30) 197 return arc_700_version(arcver, name, MAX_CPU_NAME_LEN); 198 else 199 return "Unknown ARC core"; 200 } 201 202 const char *decode_subsystem(void) 203 { 204 int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0); 205 206 switch (subsys_type) { 207 case 0: return NULL; 208 case 2: return "ARC Sensor & Control IP Subsystem"; 209 case 3: return "ARC Data Fusion IP Subsystem"; 210 case 4: return "ARC Secure Subsystem"; 211 default: return "Unknown subsystem"; 212 }; 213 } 214 215 __weak int print_cpuinfo(void) 216 { 217 const char *subsys_name = decode_subsystem(); 218 char mhz[8]; 219 220 printf("CPU: %s at %s MHz\n", decode_identity(), 221 strmhz(mhz, gd->cpu_clk)); 222 223 if (subsys_name) 224 printf("Subsys:%s\n", subsys_name); 225 226 return 0; 227 } 228 #endif /* CONFIG_DISPLAY_CPUINFO */ 229