blob: 2da878d3648b6cc89016d067a846f2cad4b9b71d [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Marek Behún09e16b82017-06-09 19:28:45 +02002/*
3 * Copyright (C) 2017 Marek Behun <marek.behun@nic.cz>
4 * Copyright (C) 2016 Tomas Hlavacek <tomas.hlavacek@nic.cz>
5 *
6 * Derived from the code for
7 * Marvell/db-88f6820-gp by Stefan Roese <sr@denx.de>
Marek Behún09e16b82017-06-09 19:28:45 +02008 */
9
10#include <common.h>
Simon Glass07dc93c2019-08-01 09:46:47 -060011#include <env.h>
Marek Behún09e16b82017-06-09 19:28:45 +020012#include <i2c.h>
Simon Glassa7b51302019-11-14 12:57:46 -070013#include <init.h>
Simon Glass0f2af882020-05-10 11:40:05 -060014#include <log.h>
Marek Behún09e16b82017-06-09 19:28:45 +020015#include <miiphy.h>
Simon Glass274e0b02020-05-10 11:39:56 -060016#include <net.h>
Marek Behún09e16b82017-06-09 19:28:45 +020017#include <netdev.h>
18#include <asm/io.h>
19#include <asm/arch/cpu.h>
20#include <asm/arch/soc.h>
21#include <dm/uclass.h>
22#include <fdt_support.h>
23#include <time.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060024#include <linux/bitops.h>
Simon Glass48b6c6b2019-11-14 12:57:16 -070025#include <u-boot/crc.h>
Marek Behún09e16b82017-06-09 19:28:45 +020026# include <atsha204a-i2c.h>
Marek Behún09e16b82017-06-09 19:28:45 +020027
Chris Packham1a07d212018-05-10 13:28:29 +120028#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
Marek Behún09e16b82017-06-09 19:28:45 +020029#include <../serdes/a38x/high_speed_env_spec.h>
30
31DECLARE_GLOBAL_DATA_PTR;
32
Marek Behúnba53b6b2019-05-02 16:53:30 +020033#define OMNIA_I2C_BUS_NAME "i2c@11000->i2cmux@70->i2c@0"
34
35#define OMNIA_I2C_MCU_CHIP_ADDR 0x2a
36#define OMNIA_I2C_MCU_CHIP_LEN 1
37
38#define OMNIA_I2C_EEPROM_CHIP_ADDR 0x54
39#define OMNIA_I2C_EEPROM_CHIP_LEN 2
Marek Behún09e16b82017-06-09 19:28:45 +020040#define OMNIA_I2C_EEPROM_MAGIC 0x0341a034
41
Marek Behúnba53b6b2019-05-02 16:53:30 +020042enum mcu_commands {
43 CMD_GET_STATUS_WORD = 0x01,
44 CMD_GET_RESET = 0x09,
45 CMD_WATCHDOG_STATE = 0x0b,
46};
47
48enum status_word_bits {
49 CARD_DET_STSBIT = 0x0010,
50 MSATA_IND_STSBIT = 0x0020,
51};
Marek Behún09e16b82017-06-09 19:28:45 +020052
53#define OMNIA_ATSHA204_OTP_VERSION 0
54#define OMNIA_ATSHA204_OTP_SERIAL 1
55#define OMNIA_ATSHA204_OTP_MAC0 3
56#define OMNIA_ATSHA204_OTP_MAC1 4
57
Marek Behún09e16b82017-06-09 19:28:45 +020058/*
59 * Those values and defines are taken from the Marvell U-Boot version
60 * "u-boot-2013.01-2014_T3.0"
61 */
62#define OMNIA_GPP_OUT_ENA_LOW \
63 (~(BIT(1) | BIT(4) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | \
64 BIT(10) | BIT(11) | BIT(19) | BIT(22) | BIT(23) | BIT(25) | \
65 BIT(26) | BIT(27) | BIT(29) | BIT(30) | BIT(31)))
66#define OMNIA_GPP_OUT_ENA_MID \
67 (~(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(15) | \
68 BIT(16) | BIT(17) | BIT(18)))
69
70#define OMNIA_GPP_OUT_VAL_LOW 0x0
71#define OMNIA_GPP_OUT_VAL_MID 0x0
72#define OMNIA_GPP_POL_LOW 0x0
73#define OMNIA_GPP_POL_MID 0x0
74
75static struct serdes_map board_serdes_map_pex[] = {
76 {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
77 {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
78 {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
79 {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
80 {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
81 {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
82};
83
84static struct serdes_map board_serdes_map_sata[] = {
85 {SATA0, SERDES_SPEED_6_GBPS, SERDES_DEFAULT_MODE, 0, 0},
86 {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
87 {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
88 {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
89 {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
90 {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
91};
92
Marek Behúnba53b6b2019-05-02 16:53:30 +020093static struct udevice *omnia_get_i2c_chip(const char *name, uint addr,
94 uint offset_len)
Marek Behún09e16b82017-06-09 19:28:45 +020095{
96 struct udevice *bus, *dev;
Marek Behúnba53b6b2019-05-02 16:53:30 +020097 int ret;
Marek Behún09e16b82017-06-09 19:28:45 +020098
Marek Behúnba53b6b2019-05-02 16:53:30 +020099 ret = uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_BUS_NAME, &bus);
100 if (ret) {
101 printf("Cannot get I2C bus %s: uclass_get_device_by_name failed: %i\n",
102 OMNIA_I2C_BUS_NAME, ret);
103 return NULL;
Marek Behún09e16b82017-06-09 19:28:45 +0200104 }
105
Marek Behúnba53b6b2019-05-02 16:53:30 +0200106 ret = i2c_get_chip(bus, addr, offset_len, &dev);
Marek Behún09e16b82017-06-09 19:28:45 +0200107 if (ret) {
Marek Behúnba53b6b2019-05-02 16:53:30 +0200108 printf("Cannot get %s I2C chip: i2c_get_chip failed: %i\n",
109 name, ret);
110 return NULL;
Marek Behún09e16b82017-06-09 19:28:45 +0200111 }
112
Marek Behúnba53b6b2019-05-02 16:53:30 +0200113 return dev;
114}
Marek Behúnd0b374d2017-08-04 15:28:25 +0200115
Marek Behúnba53b6b2019-05-02 16:53:30 +0200116static int omnia_mcu_read(u8 cmd, void *buf, int len)
117{
118 struct udevice *chip;
119
120 chip = omnia_get_i2c_chip("MCU", OMNIA_I2C_MCU_CHIP_ADDR,
121 OMNIA_I2C_MCU_CHIP_LEN);
122 if (!chip)
123 return -ENODEV;
124
125 return dm_i2c_read(chip, cmd, buf, len);
126}
127
128#ifndef CONFIG_SPL_BUILD
129static int omnia_mcu_write(u8 cmd, const void *buf, int len)
130{
131 struct udevice *chip;
132
133 chip = omnia_get_i2c_chip("MCU", OMNIA_I2C_MCU_CHIP_ADDR,
134 OMNIA_I2C_MCU_CHIP_LEN);
135 if (!chip)
136 return -ENODEV;
137
138 return dm_i2c_write(chip, cmd, buf, len);
139}
140
141static bool disable_mcu_watchdog(void)
142{
143 int ret;
144
145 puts("Disabling MCU watchdog... ");
146
147 ret = omnia_mcu_write(CMD_WATCHDOG_STATE, "\x00", 1);
148 if (ret) {
149 printf("omnia_mcu_write failed: %i\n", ret);
Marek Behún09e16b82017-06-09 19:28:45 +0200150 return false;
151 }
152
Marek Behúnba53b6b2019-05-02 16:53:30 +0200153 puts("disabled\n");
154
155 return true;
156}
157#endif
158
159static bool omnia_detect_sata(void)
160{
161 int ret;
162 u16 stsword;
163
164 puts("MiniPCIe/mSATA card detection... ");
165
166 ret = omnia_mcu_read(CMD_GET_STATUS_WORD, &stsword, sizeof(stsword));
167 if (ret) {
168 printf("omnia_mcu_read failed: %i, defaulting to MiniPCIe card\n",
169 ret);
Marek Behún09e16b82017-06-09 19:28:45 +0200170 return false;
171 }
172
Marek Behúnba53b6b2019-05-02 16:53:30 +0200173 if (!(stsword & CARD_DET_STSBIT)) {
174 puts("none\n");
Marek Behún09e16b82017-06-09 19:28:45 +0200175 return false;
176 }
Marek Behúnba53b6b2019-05-02 16:53:30 +0200177
178 if (stsword & MSATA_IND_STSBIT)
179 puts("mSATA\n");
180 else
181 puts("MiniPCIe\n");
182
183 return stsword & MSATA_IND_STSBIT ? true : false;
Marek Behún09e16b82017-06-09 19:28:45 +0200184}
185
186int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
187{
188 if (omnia_detect_sata()) {
189 *serdes_map_array = board_serdes_map_sata;
190 *count = ARRAY_SIZE(board_serdes_map_sata);
191 } else {
192 *serdes_map_array = board_serdes_map_pex;
193 *count = ARRAY_SIZE(board_serdes_map_pex);
194 }
195
196 return 0;
197}
198
199struct omnia_eeprom {
200 u32 magic;
201 u32 ramsize;
202 char region[4];
203 u32 crc;
204};
205
206static bool omnia_read_eeprom(struct omnia_eeprom *oep)
207{
Marek Behúnba53b6b2019-05-02 16:53:30 +0200208 struct udevice *chip;
209 u32 crc;
210 int ret;
Marek Behún09e16b82017-06-09 19:28:45 +0200211
Marek Behúnba53b6b2019-05-02 16:53:30 +0200212 chip = omnia_get_i2c_chip("EEPROM", OMNIA_I2C_EEPROM_CHIP_ADDR,
213 OMNIA_I2C_EEPROM_CHIP_LEN);
214
215 if (!chip)
Marek Behún09e16b82017-06-09 19:28:45 +0200216 return false;
Marek Behún09e16b82017-06-09 19:28:45 +0200217
Marek Behúnba53b6b2019-05-02 16:53:30 +0200218 ret = dm_i2c_read(chip, 0, (void *)oep, sizeof(*oep));
Marek Behún09e16b82017-06-09 19:28:45 +0200219 if (ret) {
Marek Behúnba53b6b2019-05-02 16:53:30 +0200220 printf("dm_i2c_read failed: %i, cannot read EEPROM\n", ret);
Marek Behún09e16b82017-06-09 19:28:45 +0200221 return false;
222 }
223
Marek Behúnba53b6b2019-05-02 16:53:30 +0200224 if (oep->magic != OMNIA_I2C_EEPROM_MAGIC) {
225 printf("bad EEPROM magic number (%08x, should be %08x)\n",
226 oep->magic, OMNIA_I2C_EEPROM_MAGIC);
227 return false;
Marek Behún09e16b82017-06-09 19:28:45 +0200228 }
229
Marek Behúnba53b6b2019-05-02 16:53:30 +0200230 crc = crc32(0, (void *)oep, sizeof(*oep) - 4);
231 if (crc != oep->crc) {
232 printf("bad EEPROM CRC (stored %08x, computed %08x)\n",
233 oep->crc, crc);
Marek Behún09e16b82017-06-09 19:28:45 +0200234 return false;
235 }
236
237 return true;
238}
239
Marek Behún77652c72019-05-02 16:53:33 +0200240static int omnia_get_ram_size_gb(void)
241{
242 static int ram_size;
243 struct omnia_eeprom oep;
244
245 if (!ram_size) {
246 /* Get the board config from EEPROM */
247 if (omnia_read_eeprom(&oep)) {
248 debug("Memory config in EEPROM: 0x%02x\n", oep.ramsize);
249
250 if (oep.ramsize == 0x2)
251 ram_size = 2;
252 else
253 ram_size = 1;
254 } else {
255 /* Hardcoded fallback */
256 puts("Memory config from EEPROM read failed!\n");
257 puts("Falling back to default 1 GiB!\n");
258 ram_size = 1;
259 }
260 }
261
262 return ram_size;
263}
264
Marek Behún09e16b82017-06-09 19:28:45 +0200265/*
266 * Define the DDR layout / topology here in the board file. This will
267 * be used by the DDR3 init code in the SPL U-Boot version to configure
268 * the DDR3 controller.
269 */
Chris Packham1a07d212018-05-10 13:28:29 +1200270static struct mv_ddr_topology_map board_topology_map_1g = {
271 DEBUG_LEVEL_ERROR,
Marek Behún09e16b82017-06-09 19:28:45 +0200272 0x1, /* active interfaces */
273 /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
274 { { { {0x1, 0, 0, 0},
275 {0x1, 0, 0, 0},
276 {0x1, 0, 0, 0},
277 {0x1, 0, 0, 0},
278 {0x1, 0, 0, 0} },
279 SPEED_BIN_DDR_1600K, /* speed_bin */
Chris Packham1a07d212018-05-10 13:28:29 +1200280 MV_DDR_DEV_WIDTH_16BIT, /* memory_width */
281 MV_DDR_DIE_CAP_4GBIT, /* mem_size */
Chris Packham4bf81db2018-12-03 14:26:49 +1300282 MV_DDR_FREQ_800, /* frequency */
Chris Packhamdd092bd2017-11-29 10:38:34 +1300283 0, 0, /* cas_wl cas_l */
Chris Packham3a09e132018-05-10 13:28:30 +1200284 MV_DDR_TEMP_NORMAL, /* temperature */
285 MV_DDR_TIM_2T} }, /* timing */
Chris Packham1a07d212018-05-10 13:28:29 +1200286 BUS_MASK_32BIT, /* Busses mask */
287 MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
288 { {0} }, /* raw spd data */
289 {0} /* timing parameters */
Marek Behún09e16b82017-06-09 19:28:45 +0200290};
291
Chris Packham1a07d212018-05-10 13:28:29 +1200292static struct mv_ddr_topology_map board_topology_map_2g = {
293 DEBUG_LEVEL_ERROR,
Marek Behún09e16b82017-06-09 19:28:45 +0200294 0x1, /* active interfaces */
295 /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
296 { { { {0x1, 0, 0, 0},
297 {0x1, 0, 0, 0},
298 {0x1, 0, 0, 0},
299 {0x1, 0, 0, 0},
300 {0x1, 0, 0, 0} },
301 SPEED_BIN_DDR_1600K, /* speed_bin */
Chris Packham1a07d212018-05-10 13:28:29 +1200302 MV_DDR_DEV_WIDTH_16BIT, /* memory_width */
303 MV_DDR_DIE_CAP_8GBIT, /* mem_size */
Chris Packham4bf81db2018-12-03 14:26:49 +1300304 MV_DDR_FREQ_800, /* frequency */
Chris Packhamdd092bd2017-11-29 10:38:34 +1300305 0, 0, /* cas_wl cas_l */
Chris Packham3a09e132018-05-10 13:28:30 +1200306 MV_DDR_TEMP_NORMAL, /* temperature */
307 MV_DDR_TIM_2T} }, /* timing */
Chris Packham1a07d212018-05-10 13:28:29 +1200308 BUS_MASK_32BIT, /* Busses mask */
309 MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
310 { {0} }, /* raw spd data */
311 {0} /* timing parameters */
Marek Behún09e16b82017-06-09 19:28:45 +0200312};
313
Chris Packham1a07d212018-05-10 13:28:29 +1200314struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
Marek Behún09e16b82017-06-09 19:28:45 +0200315{
Marek Behún77652c72019-05-02 16:53:33 +0200316 if (omnia_get_ram_size_gb() == 2)
Marek Behún09e16b82017-06-09 19:28:45 +0200317 return &board_topology_map_2g;
Marek Behún77652c72019-05-02 16:53:33 +0200318 else
319 return &board_topology_map_1g;
Marek Behún09e16b82017-06-09 19:28:45 +0200320}
321
322#ifndef CONFIG_SPL_BUILD
323static int set_regdomain(void)
324{
325 struct omnia_eeprom oep;
326 char rd[3] = {' ', ' ', 0};
327
328 if (omnia_read_eeprom(&oep))
329 memcpy(rd, &oep.region, 2);
330 else
331 puts("EEPROM regdomain read failed.\n");
332
333 printf("Regdomain set to %s\n", rd);
Simon Glass6a38e412017-08-03 12:22:09 -0600334 return env_set("regdomain", rd);
Marek Behún09e16b82017-06-09 19:28:45 +0200335}
Marek Behún0f2e66a2019-05-02 16:53:37 +0200336
337/*
338 * default factory reset bootcommand on Omnia first sets all the front LEDs
339 * to green and then tries to load the rescue image from SPI flash memory and
340 * boot it
341 */
342#define OMNIA_FACTORY_RESET_BOOTCMD \
343 "i2c dev 2; " \
344 "i2c mw 0x2a.1 0x3 0x1c 1; " \
345 "i2c mw 0x2a.1 0x4 0x1c 1; " \
346 "mw.l 0x01000000 0x00ff000c; " \
347 "i2c write 0x01000000 0x2a.1 0x5 4 -s; " \
Marek Behúnd9b86b02019-05-24 14:57:54 +0200348 "setenv bootargs \"earlyprintk console=ttyS0,115200" \
349 " omniarescue=$omnia_reset\"; " \
Marek Behún0f2e66a2019-05-02 16:53:37 +0200350 "sf probe; " \
351 "sf read 0x1000000 0x100000 0x700000; " \
352 "bootm 0x1000000; " \
353 "bootz 0x1000000"
354
355static void handle_reset_button(void)
356{
357 int ret;
358 u8 reset_status;
359
360 ret = omnia_mcu_read(CMD_GET_RESET, &reset_status, 1);
361 if (ret) {
362 printf("omnia_mcu_read failed: %i, reset status unknown!\n",
363 ret);
364 return;
365 }
366
367 env_set_ulong("omnia_reset", reset_status);
368
369 if (reset_status) {
370 printf("RESET button was pressed, overwriting bootcmd!\n");
371 env_set("bootcmd", OMNIA_FACTORY_RESET_BOOTCMD);
372 }
373}
Marek Behún09e16b82017-06-09 19:28:45 +0200374#endif
375
376int board_early_init_f(void)
377{
Marek Behún09e16b82017-06-09 19:28:45 +0200378 /* Configure MPP */
379 writel(0x11111111, MVEBU_MPP_BASE + 0x00);
380 writel(0x11111111, MVEBU_MPP_BASE + 0x04);
381 writel(0x11244011, MVEBU_MPP_BASE + 0x08);
382 writel(0x22222111, MVEBU_MPP_BASE + 0x0c);
383 writel(0x22200002, MVEBU_MPP_BASE + 0x10);
384 writel(0x30042022, MVEBU_MPP_BASE + 0x14);
385 writel(0x55550555, MVEBU_MPP_BASE + 0x18);
386 writel(0x00005550, MVEBU_MPP_BASE + 0x1c);
387
388 /* Set GPP Out value */
389 writel(OMNIA_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
390 writel(OMNIA_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
391
392 /* Set GPP Polarity */
393 writel(OMNIA_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
394 writel(OMNIA_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
395
396 /* Set GPP Out Enable */
397 writel(OMNIA_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
398 writel(OMNIA_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
399
Marek Behún09e16b82017-06-09 19:28:45 +0200400 return 0;
401}
402
Marek Behún09e16b82017-06-09 19:28:45 +0200403int board_init(void)
404{
Marek Behún4dfc57e2019-05-02 16:53:31 +0200405 /* address of boot parameters */
Marek Behún09e16b82017-06-09 19:28:45 +0200406 gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
407
408#ifndef CONFIG_SPL_BUILD
Marek Behúnba53b6b2019-05-02 16:53:30 +0200409 disable_mcu_watchdog();
Marek Behún09e16b82017-06-09 19:28:45 +0200410#endif
411
412 return 0;
413}
Marek Behún09e16b82017-06-09 19:28:45 +0200414
415int board_late_init(void)
416{
417#ifndef CONFIG_SPL_BUILD
418 set_regdomain();
Marek Behún0f2e66a2019-05-02 16:53:37 +0200419 handle_reset_button();
Marek Behún09e16b82017-06-09 19:28:45 +0200420#endif
Marek Behúndb1e5c62019-05-24 14:57:53 +0200421 pci_init();
Marek Behún09e16b82017-06-09 19:28:45 +0200422
423 return 0;
424}
425
Marek Behún09e16b82017-06-09 19:28:45 +0200426static struct udevice *get_atsha204a_dev(void)
427{
Marek Behún4dfc57e2019-05-02 16:53:31 +0200428 static struct udevice *dev;
Marek Behún09e16b82017-06-09 19:28:45 +0200429
Marek Behún4dfc57e2019-05-02 16:53:31 +0200430 if (dev)
Marek Behún09e16b82017-06-09 19:28:45 +0200431 return dev;
432
433 if (uclass_get_device_by_name(UCLASS_MISC, "atsha204a@64", &dev)) {
434 puts("Cannot find ATSHA204A on I2C bus!\n");
435 dev = NULL;
436 }
437
438 return dev;
439}
Marek Behún09e16b82017-06-09 19:28:45 +0200440
441int checkboard(void)
442{
443 u32 version_num, serial_num;
444 int err = 1;
445
Marek Behún09e16b82017-06-09 19:28:45 +0200446 struct udevice *dev = get_atsha204a_dev();
447
448 if (dev) {
449 err = atsha204a_wakeup(dev);
450 if (err)
451 goto out;
452
453 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
454 OMNIA_ATSHA204_OTP_VERSION,
Marek Behún4dfc57e2019-05-02 16:53:31 +0200455 (u8 *)&version_num);
Marek Behún09e16b82017-06-09 19:28:45 +0200456 if (err)
457 goto out;
458
459 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
460 OMNIA_ATSHA204_OTP_SERIAL,
Marek Behún4dfc57e2019-05-02 16:53:31 +0200461 (u8 *)&serial_num);
Marek Behún09e16b82017-06-09 19:28:45 +0200462 if (err)
463 goto out;
464
465 atsha204a_sleep(dev);
466 }
467
468out:
Marek Behúnc4ba72a2019-05-02 16:53:34 +0200469 printf("Turris Omnia:\n");
470 printf(" RAM size: %i MiB\n", omnia_get_ram_size_gb() * 1024);
Marek Behún09e16b82017-06-09 19:28:45 +0200471 if (err)
Marek Behúnc4ba72a2019-05-02 16:53:34 +0200472 printf(" Serial Number: unknown\n");
Marek Behún09e16b82017-06-09 19:28:45 +0200473 else
Marek Behúnc4ba72a2019-05-02 16:53:34 +0200474 printf(" Serial Number: %08X%08X\n", be32_to_cpu(version_num),
475 be32_to_cpu(serial_num));
Marek Behún09e16b82017-06-09 19:28:45 +0200476
477 return 0;
478}
479
480static void increment_mac(u8 *mac)
481{
482 int i;
483
484 for (i = 5; i >= 3; i--) {
485 mac[i] += 1;
486 if (mac[i])
487 break;
488 }
489}
490
491int misc_init_r(void)
492{
Marek Behún09e16b82017-06-09 19:28:45 +0200493 int err;
494 struct udevice *dev = get_atsha204a_dev();
495 u8 mac0[4], mac1[4], mac[6];
496
497 if (!dev)
498 goto out;
499
500 err = atsha204a_wakeup(dev);
501 if (err)
502 goto out;
503
504 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
505 OMNIA_ATSHA204_OTP_MAC0, mac0);
506 if (err)
507 goto out;
508
509 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
510 OMNIA_ATSHA204_OTP_MAC1, mac1);
511 if (err)
512 goto out;
513
514 atsha204a_sleep(dev);
515
516 mac[0] = mac0[1];
517 mac[1] = mac0[2];
518 mac[2] = mac0[3];
519 mac[3] = mac1[1];
520 mac[4] = mac1[2];
521 mac[5] = mac1[3];
522
523 if (is_valid_ethaddr(mac))
Marek Behúncb50c712019-05-24 14:57:49 +0200524 eth_env_set_enetaddr("eth1addr", mac);
Marek Behún09e16b82017-06-09 19:28:45 +0200525
526 increment_mac(mac);
527
528 if (is_valid_ethaddr(mac))
Marek Behúncb50c712019-05-24 14:57:49 +0200529 eth_env_set_enetaddr("eth2addr", mac);
Marek Behún09e16b82017-06-09 19:28:45 +0200530
531 increment_mac(mac);
532
533 if (is_valid_ethaddr(mac))
Marek Behúncb50c712019-05-24 14:57:49 +0200534 eth_env_set_enetaddr("ethaddr", mac);
Marek Behún09e16b82017-06-09 19:28:45 +0200535
536out:
Marek Behún09e16b82017-06-09 19:28:45 +0200537 return 0;
538}
539