uboot/arch/arm/mach-meson/board-info.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2019 Julien Masson <jmasson@baylibre.com>
   4 * (C) Copyright 2019 Neil Armstrong <narmstrong@baylibre.com>
   5 */
   6
   7#include <common.h>
   8#include <init.h>
   9#include <asm/global_data.h>
  10#include <asm/io.h>
  11#include <dm.h>
  12#include <linux/bitfield.h>
  13#include <regmap.h>
  14#include <syscon.h>
  15#include <linux/bitops.h>
  16#include <linux/err.h>
  17
  18#define AO_SEC_SD_CFG8          0xe0
  19#define AO_SEC_SOCINFO_OFFSET   AO_SEC_SD_CFG8
  20
  21#define SOCINFO_MAJOR   GENMASK(31, 24)
  22#define SOCINFO_PACK    GENMASK(23, 16)
  23#define SOCINFO_MINOR   GENMASK(15, 8)
  24#define SOCINFO_MISC    GENMASK(7, 0)
  25
  26static const struct meson_gx_soc_id {
  27        const char *name;
  28        unsigned int id;
  29} soc_ids[] = {
  30        { "GXBB",   0x1f },
  31        { "GXTVBB", 0x20 },
  32        { "GXL",    0x21 },
  33        { "GXM",    0x22 },
  34        { "TXL",    0x23 },
  35        { "TXLX",   0x24 },
  36        { "AXG",    0x25 },
  37        { "GXLX",   0x26 },
  38        { "TXHD",   0x27 },
  39        { "G12A",   0x28 },
  40        { "G12B",   0x29 },
  41        { "SM1",    0x2b },
  42        { "A1",     0x2c },
  43};
  44
  45static const struct meson_gx_package_id {
  46        const char *name;
  47        unsigned int major_id;
  48        unsigned int pack_id;
  49        unsigned int pack_mask;
  50} soc_packages[] = {
  51        { "S905",   0x1f, 0,    0x20 }, /* pack_id != 0x20 */
  52        { "S905H",  0x1f, 0x3,  0xf },  /* pack_id & 0xf == 0x3 */
  53        { "S905M",  0x1f, 0x20, 0xf0 }, /* pack_id == 0x20 */
  54        { "S905D",  0x21, 0,    0xf0 },
  55        { "S905X",  0x21, 0x80, 0xf0 },
  56        { "S905W",  0x21, 0xa0, 0xf0 },
  57        { "S905L",  0x21, 0xc0, 0xf0 },
  58        { "S905M2", 0x21, 0xe0, 0xf0 },
  59        { "S805X",  0x21, 0x30, 0xf0 },
  60        { "S805Y",  0x21, 0xb0, 0xf0 },
  61        { "S912",   0x22, 0,    0x0 },  /* Only S912 is known for GXM */
  62        { "962X",   0x24, 0x10, 0xf0 },
  63        { "962E",   0x24, 0x20, 0xf0 },
  64        { "A113X",  0x25, 0x37, 0xff },
  65        { "A113D",  0x25, 0x22, 0xff },
  66        { "S905D2", 0x28, 0x10, 0xf0 },
  67        { "S905Y2", 0x28, 0x30, 0xf0 },
  68        { "S905X2", 0x28, 0x40, 0xf0 },
  69        { "A311D",  0x29, 0x10, 0xf0 },
  70        { "S922X",  0x29, 0x40, 0xf0 },
  71        { "S905D3", 0x2b, 0x4, 0xf5 },
  72        { "S905X3", 0x2b, 0x5, 0xf5 },
  73        { "S905X3", 0x2b, 0x10, 0x3f },
  74        { "S905D3", 0x2b, 0x30, 0x3f },
  75        { "A113L", 0x2c, 0x0, 0xf8 },
  76};
  77
  78DECLARE_GLOBAL_DATA_PTR;
  79
  80static inline unsigned int socinfo_to_major(u32 socinfo)
  81{
  82        return FIELD_GET(SOCINFO_MAJOR, socinfo);
  83}
  84
  85static inline unsigned int socinfo_to_minor(u32 socinfo)
  86{
  87        return FIELD_GET(SOCINFO_MINOR, socinfo);
  88}
  89
  90static inline unsigned int socinfo_to_pack(u32 socinfo)
  91{
  92        return FIELD_GET(SOCINFO_PACK, socinfo);
  93}
  94
  95static inline unsigned int socinfo_to_misc(u32 socinfo)
  96{
  97        return FIELD_GET(SOCINFO_MISC, socinfo);
  98}
  99
 100static const char *socinfo_to_package_id(u32 socinfo)
 101{
 102        unsigned int pack = socinfo_to_pack(socinfo);
 103        unsigned int major = socinfo_to_major(socinfo);
 104        int i;
 105
 106        for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
 107                if (soc_packages[i].major_id == major &&
 108                    soc_packages[i].pack_id ==
 109                    (pack & soc_packages[i].pack_mask))
 110                        return soc_packages[i].name;
 111        }
 112
 113        return "Unknown";
 114}
 115
 116static const char *socinfo_to_soc_id(u32 socinfo)
 117{
 118        unsigned int id = socinfo_to_major(socinfo);
 119        int i;
 120
 121        for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
 122                if (soc_ids[i].id == id)
 123                        return soc_ids[i].name;
 124        }
 125
 126        return "Unknown";
 127}
 128
 129static void print_board_model(void)
 130{
 131        const char *model;
 132        model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
 133        printf("Model: %s\n", model ? model : "Unknown");
 134}
 135
 136static unsigned int get_socinfo(void)
 137{
 138        struct regmap *regmap;
 139        int nodeoffset, ret;
 140        ofnode node;
 141        unsigned int socinfo;
 142
 143        /* find the offset of compatible node */
 144        nodeoffset = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
 145                                                   "amlogic,meson-gx-ao-secure");
 146        if (nodeoffset < 0)
 147                return 0;
 148
 149        /* check if chip-id is available */
 150        if (!fdt_getprop(gd->fdt_blob, nodeoffset, "amlogic,has-chip-id", NULL))
 151                return 0;
 152
 153        /* get regmap from the syscon node */
 154        node = offset_to_ofnode(nodeoffset);
 155        regmap = syscon_node_to_regmap(node);
 156        if (IS_ERR(regmap)) {
 157                printf("%s: failed to get regmap\n", __func__);
 158                return 0;
 159        }
 160
 161        /* read soc info */
 162        ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
 163        if (ret && !socinfo) {
 164                printf("%s: invalid chipid value\n", __func__);
 165                return 0;
 166        }
 167
 168        return socinfo;
 169}
 170
 171int show_board_info(void)
 172{
 173        unsigned int socinfo;
 174
 175        /* print board information */
 176        print_board_model();
 177
 178        socinfo = get_socinfo();
 179        if (!socinfo)
 180                return 0;
 181
 182        printf("SoC:   Amlogic Meson %s (%s) Revision %x:%x (%x:%x)\n",
 183               socinfo_to_soc_id(socinfo),
 184               socinfo_to_package_id(socinfo),
 185               socinfo_to_major(socinfo),
 186               socinfo_to_minor(socinfo),
 187               socinfo_to_pack(socinfo),
 188               socinfo_to_misc(socinfo));
 189
 190        return 0;
 191}
 192
 193int meson_get_soc_rev(char *buff, size_t buff_len)
 194{
 195        unsigned int socinfo;
 196
 197        socinfo = get_socinfo();
 198        if (!socinfo)
 199                return -1;
 200
 201        /* Write SoC info */
 202        return snprintf(buff, buff_len, "%x", socinfo_to_minor(socinfo));
 203}
 204