"Das U-Boot" Source Tree
at master 211 lines 5.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2021 Marek Vasut <marek.vasut+renesas@gmail.com> 4 */ 5 6#include <dm.h> 7#include <i2c_eeprom.h> 8#include <log.h> 9#include <sysinfo.h> 10 11#define BOARD_CODE_MASK 0xF8 12#define BOARD_REV_MASK 0x07 13#define BOARD_CODE_SHIFT 0x03 14 15#define BOARD_SALVATOR_X 0x0 16#define BOARD_KRIEK 0x1 17#define BOARD_STARTER_KIT 0x2 18#define BOARD_EAGLE 0x3 19#define BOARD_SALVATOR_XS 0x4 20#define BOARD_CONDOR 0x6 21#define BOARD_DRAAK 0x7 22#define BOARD_EBISU 0x8 23#define BOARD_STARTER_KIT_PRE 0xB 24#define BOARD_EBISU_4D 0xD 25#define BOARD_CONDOR_I 0x10 26 27/** 28 * struct sysinfo_rcar_priv - sysinfo private data 29 * @boardname: board model and revision 30 * @val: board ID value from eeprom 31 */ 32struct sysinfo_rcar_priv { 33 char boardmodel[64]; 34 u8 val; 35}; 36 37static int sysinfo_rcar_detect(struct udevice *dev) 38{ 39 struct sysinfo_rcar_priv *priv = dev_get_priv(dev); 40 41 return priv->val == 0xff; 42} 43 44static int sysinfo_rcar_get_str(struct udevice *dev, int id, size_t size, char *val) 45{ 46 struct sysinfo_rcar_priv *priv = dev_get_priv(dev); 47 48 switch (id) { 49 case SYSID_BOARD_MODEL: 50 strncpy(val, priv->boardmodel, size); 51 val[size - 1] = '\0'; 52 return 0; 53 default: 54 return -EINVAL; 55 }; 56} 57 58static const struct sysinfo_ops sysinfo_rcar_ops = { 59 .detect = sysinfo_rcar_detect, 60 .get_str = sysinfo_rcar_get_str, 61}; 62 63static void sysinfo_rcar_parse(struct sysinfo_rcar_priv *priv) 64{ 65 const u8 board_id = (priv->val & BOARD_CODE_MASK) >> BOARD_CODE_SHIFT; 66 const u8 board_rev = priv->val & BOARD_REV_MASK; 67 bool salvator_xs = false; 68 bool ebisu_4d = false; 69 bool condor_i = false; 70 char rev_major = '?'; 71 char rev_minor = '?'; 72 73 switch (board_id) { 74 case BOARD_SALVATOR_XS: 75 salvator_xs = true; 76 fallthrough; 77 case BOARD_SALVATOR_X: 78 if (!(board_rev & ~1)) { /* Only rev 0 and 1 is valid */ 79 rev_major = '1'; 80 rev_minor = '0' + (board_rev & BIT(0)); 81 } 82 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 83 "Renesas Salvator-X%s board rev %c.%c", 84 salvator_xs ? "S" : "", rev_major, rev_minor); 85 return; 86 case BOARD_STARTER_KIT: 87 if (!(board_rev & ~1)) { /* Only rev 0 and 1 is valid */ 88 rev_major = (board_rev & BIT(0)) ? '3' : '1'; 89 rev_minor = '0'; 90 } 91 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 92 "Renesas Starter Kit board rev %c.%c", 93 rev_major, rev_minor); 94 return; 95 case BOARD_STARTER_KIT_PRE: 96 if (!(board_rev & ~3)) { /* Only rev 0..3 is valid */ 97 rev_major = (board_rev & BIT(1)) ? '2' : '1'; 98 rev_minor = (board_rev == 3) ? '1' : '0'; 99 } 100 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 101 "Renesas Starter Kit Premier board rev %c.%c", 102 rev_major, rev_minor); 103 return; 104 case BOARD_EAGLE: 105 if (!board_rev) { /* Only rev 0 is valid */ 106 rev_major = '1'; 107 rev_minor = '0'; 108 } 109 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 110 "Renesas Eagle board rev %c.%c", 111 rev_major, rev_minor); 112 return; 113 case BOARD_EBISU_4D: 114 ebisu_4d = true; 115 fallthrough; 116 case BOARD_EBISU: 117 if (!board_rev) { /* Only rev 0 is valid */ 118 rev_major = '1'; 119 rev_minor = '0'; 120 } 121 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 122 "Renesas Ebisu%s board rev %c.%c", 123 ebisu_4d ? "-4D" : "", rev_major, rev_minor); 124 return; 125 case BOARD_DRAAK: 126 if (!board_rev) { /* Only rev 0 is valid */ 127 rev_major = '1'; 128 rev_minor = '0'; 129 } 130 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 131 "Renesas Draak board rev %c.%c", 132 rev_major, rev_minor); 133 return; 134 case BOARD_KRIEK: 135 if (!board_rev) { /* Only rev 0 is valid */ 136 rev_major = '1'; 137 rev_minor = '0'; 138 } 139 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 140 "Renesas Kriek board rev %c.%c", 141 rev_major, rev_minor); 142 return; 143 case BOARD_CONDOR_I: 144 condor_i = true; 145 fallthrough; 146 case BOARD_CONDOR: 147 if (!board_rev) { /* Only rev 0 is valid */ 148 rev_major = '1'; 149 rev_minor = '0'; 150 } 151 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 152 "Renesas Condor%s board rev %c.%c", 153 condor_i ? "-I" : "", rev_major, rev_minor); 154 return; 155 default: 156 snprintf(priv->boardmodel, sizeof(priv->boardmodel), 157 "Renesas -Unknown- board rev ?.?"); 158 priv->val = 0xff; 159 return; 160 } 161} 162 163static int sysinfo_rcar_probe(struct udevice *dev) 164{ 165 struct sysinfo_rcar_priv *priv = dev_get_priv(dev); 166 struct ofnode_phandle_args phandle_args; 167 struct udevice *i2c_eeprom; 168 u32 offset; 169 int ret; 170 171 offset = dev_read_u32_default(dev, "offset", 0x70); 172 173 ret = dev_read_phandle_with_args(dev, "i2c-eeprom", NULL, 174 0, 0, &phandle_args); 175 if (ret) { 176 debug("%s: i2c-eeprom backing device not specified\n", 177 dev->name); 178 return ret; 179 } 180 181 ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, phandle_args.node, 182 &i2c_eeprom); 183 if (ret) { 184 debug("%s: could not get backing device\n", dev->name); 185 return ret; 186 } 187 188 ret = i2c_eeprom_read(i2c_eeprom, offset, &priv->val, 1); 189 if (ret < 0) { 190 debug("%s: read failed\n", __func__); 191 return -EIO; 192 } 193 194 sysinfo_rcar_parse(priv); 195 196 return 0; 197} 198 199static const struct udevice_id sysinfo_rcar_ids[] = { 200 { .compatible = "renesas,rcar-sysinfo" }, 201 { /* sentinel */ } 202}; 203 204U_BOOT_DRIVER(sysinfo_rcar) = { 205 .name = "sysinfo_rcar", 206 .id = UCLASS_SYSINFO, 207 .of_match = sysinfo_rcar_ids, 208 .ops = &sysinfo_rcar_ops, 209 .priv_auto = sizeof(struct sysinfo_rcar_priv), 210 .probe = sysinfo_rcar_probe, 211};