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