blob: 1d8d08a847d9104356b3763248be95fd8beac2cf [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>
13#include <miiphy.h>
14#include <netdev.h>
15#include <asm/io.h>
16#include <asm/arch/cpu.h>
17#include <asm/arch/soc.h>
18#include <dm/uclass.h>
19#include <fdt_support.h>
20#include <time.h>
Marek Behún09e16b82017-06-09 19:28:45 +020021# include <atsha204a-i2c.h>
Marek Behún09e16b82017-06-09 19:28:45 +020022
Chris Packham1a07d212018-05-10 13:28:29 +120023#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
Marek Behún09e16b82017-06-09 19:28:45 +020024#include <../serdes/a38x/high_speed_env_spec.h>
25
26DECLARE_GLOBAL_DATA_PTR;
27
Marek Behúnba53b6b2019-05-02 16:53:30 +020028#define OMNIA_I2C_BUS_NAME "i2c@11000->i2cmux@70->i2c@0"
29
30#define OMNIA_I2C_MCU_CHIP_ADDR 0x2a
31#define OMNIA_I2C_MCU_CHIP_LEN 1
32
33#define OMNIA_I2C_EEPROM_CHIP_ADDR 0x54
34#define OMNIA_I2C_EEPROM_CHIP_LEN 2
Marek Behún09e16b82017-06-09 19:28:45 +020035#define OMNIA_I2C_EEPROM_MAGIC 0x0341a034
36
Marek Behúnba53b6b2019-05-02 16:53:30 +020037enum mcu_commands {
38 CMD_GET_STATUS_WORD = 0x01,
39 CMD_GET_RESET = 0x09,
40 CMD_WATCHDOG_STATE = 0x0b,
41};
42
43enum status_word_bits {
44 CARD_DET_STSBIT = 0x0010,
45 MSATA_IND_STSBIT = 0x0020,
46};
Marek Behún09e16b82017-06-09 19:28:45 +020047
48#define OMNIA_ATSHA204_OTP_VERSION 0
49#define OMNIA_ATSHA204_OTP_SERIAL 1
50#define OMNIA_ATSHA204_OTP_MAC0 3
51#define OMNIA_ATSHA204_OTP_MAC1 4
52
Marek Behún09e16b82017-06-09 19:28:45 +020053/*
54 * Those values and defines are taken from the Marvell U-Boot version
55 * "u-boot-2013.01-2014_T3.0"
56 */
57#define OMNIA_GPP_OUT_ENA_LOW \
58 (~(BIT(1) | BIT(4) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | \
59 BIT(10) | BIT(11) | BIT(19) | BIT(22) | BIT(23) | BIT(25) | \
60 BIT(26) | BIT(27) | BIT(29) | BIT(30) | BIT(31)))
61#define OMNIA_GPP_OUT_ENA_MID \
62 (~(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(15) | \
63 BIT(16) | BIT(17) | BIT(18)))
64
65#define OMNIA_GPP_OUT_VAL_LOW 0x0
66#define OMNIA_GPP_OUT_VAL_MID 0x0
67#define OMNIA_GPP_POL_LOW 0x0
68#define OMNIA_GPP_POL_MID 0x0
69
70static struct serdes_map board_serdes_map_pex[] = {
71 {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
72 {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
73 {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
74 {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
75 {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
76 {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
77};
78
79static struct serdes_map board_serdes_map_sata[] = {
80 {SATA0, SERDES_SPEED_6_GBPS, SERDES_DEFAULT_MODE, 0, 0},
81 {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
82 {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
83 {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
84 {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
85 {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}
86};
87
Marek Behúnba53b6b2019-05-02 16:53:30 +020088static struct udevice *omnia_get_i2c_chip(const char *name, uint addr,
89 uint offset_len)
Marek Behún09e16b82017-06-09 19:28:45 +020090{
91 struct udevice *bus, *dev;
Marek Behúnba53b6b2019-05-02 16:53:30 +020092 int ret;
Marek Behún09e16b82017-06-09 19:28:45 +020093
Marek Behúnba53b6b2019-05-02 16:53:30 +020094 ret = uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_BUS_NAME, &bus);
95 if (ret) {
96 printf("Cannot get I2C bus %s: uclass_get_device_by_name failed: %i\n",
97 OMNIA_I2C_BUS_NAME, ret);
98 return NULL;
Marek Behún09e16b82017-06-09 19:28:45 +020099 }
100
Marek Behúnba53b6b2019-05-02 16:53:30 +0200101 ret = i2c_get_chip(bus, addr, offset_len, &dev);
Marek Behún09e16b82017-06-09 19:28:45 +0200102 if (ret) {
Marek Behúnba53b6b2019-05-02 16:53:30 +0200103 printf("Cannot get %s I2C chip: i2c_get_chip failed: %i\n",
104 name, ret);
105 return NULL;
Marek Behún09e16b82017-06-09 19:28:45 +0200106 }
107
Marek Behúnba53b6b2019-05-02 16:53:30 +0200108 return dev;
109}
Marek Behúnd0b374d2017-08-04 15:28:25 +0200110
Marek Behúnba53b6b2019-05-02 16:53:30 +0200111static int omnia_mcu_read(u8 cmd, void *buf, int len)
112{
113 struct udevice *chip;
114
115 chip = omnia_get_i2c_chip("MCU", OMNIA_I2C_MCU_CHIP_ADDR,
116 OMNIA_I2C_MCU_CHIP_LEN);
117 if (!chip)
118 return -ENODEV;
119
120 return dm_i2c_read(chip, cmd, buf, len);
121}
122
123#ifndef CONFIG_SPL_BUILD
124static int omnia_mcu_write(u8 cmd, const void *buf, int len)
125{
126 struct udevice *chip;
127
128 chip = omnia_get_i2c_chip("MCU", OMNIA_I2C_MCU_CHIP_ADDR,
129 OMNIA_I2C_MCU_CHIP_LEN);
130 if (!chip)
131 return -ENODEV;
132
133 return dm_i2c_write(chip, cmd, buf, len);
134}
135
136static bool disable_mcu_watchdog(void)
137{
138 int ret;
139
140 puts("Disabling MCU watchdog... ");
141
142 ret = omnia_mcu_write(CMD_WATCHDOG_STATE, "\x00", 1);
143 if (ret) {
144 printf("omnia_mcu_write failed: %i\n", ret);
Marek Behún09e16b82017-06-09 19:28:45 +0200145 return false;
146 }
147
Marek Behúnba53b6b2019-05-02 16:53:30 +0200148 puts("disabled\n");
149
150 return true;
151}
152#endif
153
154static bool omnia_detect_sata(void)
155{
156 int ret;
157 u16 stsword;
158
159 puts("MiniPCIe/mSATA card detection... ");
160
161 ret = omnia_mcu_read(CMD_GET_STATUS_WORD, &stsword, sizeof(stsword));
162 if (ret) {
163 printf("omnia_mcu_read failed: %i, defaulting to MiniPCIe card\n",
164 ret);
Marek Behún09e16b82017-06-09 19:28:45 +0200165 return false;
166 }
167
Marek Behúnba53b6b2019-05-02 16:53:30 +0200168 if (!(stsword & CARD_DET_STSBIT)) {
169 puts("none\n");
Marek Behún09e16b82017-06-09 19:28:45 +0200170 return false;
171 }
Marek Behúnba53b6b2019-05-02 16:53:30 +0200172
173 if (stsword & MSATA_IND_STSBIT)
174 puts("mSATA\n");
175 else
176 puts("MiniPCIe\n");
177
178 return stsword & MSATA_IND_STSBIT ? true : false;
Marek Behún09e16b82017-06-09 19:28:45 +0200179}
180
181int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
182{
183 if (omnia_detect_sata()) {
184 *serdes_map_array = board_serdes_map_sata;
185 *count = ARRAY_SIZE(board_serdes_map_sata);
186 } else {
187 *serdes_map_array = board_serdes_map_pex;
188 *count = ARRAY_SIZE(board_serdes_map_pex);
189 }
190
191 return 0;
192}
193
194struct omnia_eeprom {
195 u32 magic;
196 u32 ramsize;
197 char region[4];
198 u32 crc;
199};
200
201static bool omnia_read_eeprom(struct omnia_eeprom *oep)
202{
Marek Behúnba53b6b2019-05-02 16:53:30 +0200203 struct udevice *chip;
204 u32 crc;
205 int ret;
Marek Behún09e16b82017-06-09 19:28:45 +0200206
Marek Behúnba53b6b2019-05-02 16:53:30 +0200207 chip = omnia_get_i2c_chip("EEPROM", OMNIA_I2C_EEPROM_CHIP_ADDR,
208 OMNIA_I2C_EEPROM_CHIP_LEN);
209
210 if (!chip)
Marek Behún09e16b82017-06-09 19:28:45 +0200211 return false;
Marek Behún09e16b82017-06-09 19:28:45 +0200212
Marek Behúnba53b6b2019-05-02 16:53:30 +0200213 ret = dm_i2c_read(chip, 0, (void *)oep, sizeof(*oep));
Marek Behún09e16b82017-06-09 19:28:45 +0200214 if (ret) {
Marek Behúnba53b6b2019-05-02 16:53:30 +0200215 printf("dm_i2c_read failed: %i, cannot read EEPROM\n", ret);
Marek Behún09e16b82017-06-09 19:28:45 +0200216 return false;
217 }
218
Marek Behúnba53b6b2019-05-02 16:53:30 +0200219 if (oep->magic != OMNIA_I2C_EEPROM_MAGIC) {
220 printf("bad EEPROM magic number (%08x, should be %08x)\n",
221 oep->magic, OMNIA_I2C_EEPROM_MAGIC);
222 return false;
Marek Behún09e16b82017-06-09 19:28:45 +0200223 }
224
Marek Behúnba53b6b2019-05-02 16:53:30 +0200225 crc = crc32(0, (void *)oep, sizeof(*oep) - 4);
226 if (crc != oep->crc) {
227 printf("bad EEPROM CRC (stored %08x, computed %08x)\n",
228 oep->crc, crc);
Marek Behún09e16b82017-06-09 19:28:45 +0200229 return false;
230 }
231
232 return true;
233}
234
Marek Behún77652c72019-05-02 16:53:33 +0200235static int omnia_get_ram_size_gb(void)
236{
237 static int ram_size;
238 struct omnia_eeprom oep;
239
240 if (!ram_size) {
241 /* Get the board config from EEPROM */
242 if (omnia_read_eeprom(&oep)) {
243 debug("Memory config in EEPROM: 0x%02x\n", oep.ramsize);
244
245 if (oep.ramsize == 0x2)
246 ram_size = 2;
247 else
248 ram_size = 1;
249 } else {
250 /* Hardcoded fallback */
251 puts("Memory config from EEPROM read failed!\n");
252 puts("Falling back to default 1 GiB!\n");
253 ram_size = 1;
254 }
255 }
256
257 return ram_size;
258}
259
Marek Behún09e16b82017-06-09 19:28:45 +0200260/*
261 * Define the DDR layout / topology here in the board file. This will
262 * be used by the DDR3 init code in the SPL U-Boot version to configure
263 * the DDR3 controller.
264 */
Chris Packham1a07d212018-05-10 13:28:29 +1200265static struct mv_ddr_topology_map board_topology_map_1g = {
266 DEBUG_LEVEL_ERROR,
Marek Behún09e16b82017-06-09 19:28:45 +0200267 0x1, /* active interfaces */
268 /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
269 { { { {0x1, 0, 0, 0},
270 {0x1, 0, 0, 0},
271 {0x1, 0, 0, 0},
272 {0x1, 0, 0, 0},
273 {0x1, 0, 0, 0} },
274 SPEED_BIN_DDR_1600K, /* speed_bin */
Chris Packham1a07d212018-05-10 13:28:29 +1200275 MV_DDR_DEV_WIDTH_16BIT, /* memory_width */
276 MV_DDR_DIE_CAP_4GBIT, /* mem_size */
Chris Packham4bf81db2018-12-03 14:26:49 +1300277 MV_DDR_FREQ_800, /* frequency */
Chris Packhamdd092bd2017-11-29 10:38:34 +1300278 0, 0, /* cas_wl cas_l */
Chris Packham3a09e132018-05-10 13:28:30 +1200279 MV_DDR_TEMP_NORMAL, /* temperature */
280 MV_DDR_TIM_2T} }, /* timing */
Chris Packham1a07d212018-05-10 13:28:29 +1200281 BUS_MASK_32BIT, /* Busses mask */
282 MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
283 { {0} }, /* raw spd data */
284 {0} /* timing parameters */
Marek Behún09e16b82017-06-09 19:28:45 +0200285};
286
Chris Packham1a07d212018-05-10 13:28:29 +1200287static struct mv_ddr_topology_map board_topology_map_2g = {
288 DEBUG_LEVEL_ERROR,
Marek Behún09e16b82017-06-09 19:28:45 +0200289 0x1, /* active interfaces */
290 /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
291 { { { {0x1, 0, 0, 0},
292 {0x1, 0, 0, 0},
293 {0x1, 0, 0, 0},
294 {0x1, 0, 0, 0},
295 {0x1, 0, 0, 0} },
296 SPEED_BIN_DDR_1600K, /* speed_bin */
Chris Packham1a07d212018-05-10 13:28:29 +1200297 MV_DDR_DEV_WIDTH_16BIT, /* memory_width */
298 MV_DDR_DIE_CAP_8GBIT, /* mem_size */
Chris Packham4bf81db2018-12-03 14:26:49 +1300299 MV_DDR_FREQ_800, /* frequency */
Chris Packhamdd092bd2017-11-29 10:38:34 +1300300 0, 0, /* cas_wl cas_l */
Chris Packham3a09e132018-05-10 13:28:30 +1200301 MV_DDR_TEMP_NORMAL, /* temperature */
302 MV_DDR_TIM_2T} }, /* timing */
Chris Packham1a07d212018-05-10 13:28:29 +1200303 BUS_MASK_32BIT, /* Busses mask */
304 MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
305 { {0} }, /* raw spd data */
306 {0} /* timing parameters */
Marek Behún09e16b82017-06-09 19:28:45 +0200307};
308
Chris Packham1a07d212018-05-10 13:28:29 +1200309struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
Marek Behún09e16b82017-06-09 19:28:45 +0200310{
Marek Behún77652c72019-05-02 16:53:33 +0200311 if (omnia_get_ram_size_gb() == 2)
Marek Behún09e16b82017-06-09 19:28:45 +0200312 return &board_topology_map_2g;
Marek Behún77652c72019-05-02 16:53:33 +0200313 else
314 return &board_topology_map_1g;
Marek Behún09e16b82017-06-09 19:28:45 +0200315}
316
317#ifndef CONFIG_SPL_BUILD
318static int set_regdomain(void)
319{
320 struct omnia_eeprom oep;
321 char rd[3] = {' ', ' ', 0};
322
323 if (omnia_read_eeprom(&oep))
324 memcpy(rd, &oep.region, 2);
325 else
326 puts("EEPROM regdomain read failed.\n");
327
328 printf("Regdomain set to %s\n", rd);
Simon Glass6a38e412017-08-03 12:22:09 -0600329 return env_set("regdomain", rd);
Marek Behún09e16b82017-06-09 19:28:45 +0200330}
Marek Behún0f2e66a2019-05-02 16:53:37 +0200331
332/*
333 * default factory reset bootcommand on Omnia first sets all the front LEDs
334 * to green and then tries to load the rescue image from SPI flash memory and
335 * boot it
336 */
337#define OMNIA_FACTORY_RESET_BOOTCMD \
338 "i2c dev 2; " \
339 "i2c mw 0x2a.1 0x3 0x1c 1; " \
340 "i2c mw 0x2a.1 0x4 0x1c 1; " \
341 "mw.l 0x01000000 0x00ff000c; " \
342 "i2c write 0x01000000 0x2a.1 0x5 4 -s; " \
Marek Behúnd9b86b02019-05-24 14:57:54 +0200343 "setenv bootargs \"earlyprintk console=ttyS0,115200" \
344 " omniarescue=$omnia_reset\"; " \
Marek Behún0f2e66a2019-05-02 16:53:37 +0200345 "sf probe; " \
346 "sf read 0x1000000 0x100000 0x700000; " \
347 "bootm 0x1000000; " \
348 "bootz 0x1000000"
349
350static void handle_reset_button(void)
351{
352 int ret;
353 u8 reset_status;
354
355 ret = omnia_mcu_read(CMD_GET_RESET, &reset_status, 1);
356 if (ret) {
357 printf("omnia_mcu_read failed: %i, reset status unknown!\n",
358 ret);
359 return;
360 }
361
362 env_set_ulong("omnia_reset", reset_status);
363
364 if (reset_status) {
365 printf("RESET button was pressed, overwriting bootcmd!\n");
366 env_set("bootcmd", OMNIA_FACTORY_RESET_BOOTCMD);
367 }
368}
Marek Behún09e16b82017-06-09 19:28:45 +0200369#endif
370
371int board_early_init_f(void)
372{
Marek Behún09e16b82017-06-09 19:28:45 +0200373 /* Configure MPP */
374 writel(0x11111111, MVEBU_MPP_BASE + 0x00);
375 writel(0x11111111, MVEBU_MPP_BASE + 0x04);
376 writel(0x11244011, MVEBU_MPP_BASE + 0x08);
377 writel(0x22222111, MVEBU_MPP_BASE + 0x0c);
378 writel(0x22200002, MVEBU_MPP_BASE + 0x10);
379 writel(0x30042022, MVEBU_MPP_BASE + 0x14);
380 writel(0x55550555, MVEBU_MPP_BASE + 0x18);
381 writel(0x00005550, MVEBU_MPP_BASE + 0x1c);
382
383 /* Set GPP Out value */
384 writel(OMNIA_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00);
385 writel(OMNIA_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00);
386
387 /* Set GPP Polarity */
388 writel(OMNIA_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c);
389 writel(OMNIA_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c);
390
391 /* Set GPP Out Enable */
392 writel(OMNIA_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04);
393 writel(OMNIA_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04);
394
Marek Behún09e16b82017-06-09 19:28:45 +0200395 return 0;
396}
397
Marek Behún09e16b82017-06-09 19:28:45 +0200398int board_init(void)
399{
Marek Behún4dfc57e2019-05-02 16:53:31 +0200400 /* address of boot parameters */
Marek Behún09e16b82017-06-09 19:28:45 +0200401 gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
402
403#ifndef CONFIG_SPL_BUILD
Marek Behúnba53b6b2019-05-02 16:53:30 +0200404 disable_mcu_watchdog();
Marek Behún09e16b82017-06-09 19:28:45 +0200405#endif
406
407 return 0;
408}
Marek Behún09e16b82017-06-09 19:28:45 +0200409
410int board_late_init(void)
411{
412#ifndef CONFIG_SPL_BUILD
413 set_regdomain();
Marek Behún0f2e66a2019-05-02 16:53:37 +0200414 handle_reset_button();
Marek Behún09e16b82017-06-09 19:28:45 +0200415#endif
Marek Behúndb1e5c62019-05-24 14:57:53 +0200416 pci_init();
Marek Behún09e16b82017-06-09 19:28:45 +0200417
418 return 0;
419}
420
Marek Behún09e16b82017-06-09 19:28:45 +0200421static struct udevice *get_atsha204a_dev(void)
422{
Marek Behún4dfc57e2019-05-02 16:53:31 +0200423 static struct udevice *dev;
Marek Behún09e16b82017-06-09 19:28:45 +0200424
Marek Behún4dfc57e2019-05-02 16:53:31 +0200425 if (dev)
Marek Behún09e16b82017-06-09 19:28:45 +0200426 return dev;
427
428 if (uclass_get_device_by_name(UCLASS_MISC, "atsha204a@64", &dev)) {
429 puts("Cannot find ATSHA204A on I2C bus!\n");
430 dev = NULL;
431 }
432
433 return dev;
434}
Marek Behún09e16b82017-06-09 19:28:45 +0200435
436int checkboard(void)
437{
438 u32 version_num, serial_num;
439 int err = 1;
440
Marek Behún09e16b82017-06-09 19:28:45 +0200441 struct udevice *dev = get_atsha204a_dev();
442
443 if (dev) {
444 err = atsha204a_wakeup(dev);
445 if (err)
446 goto out;
447
448 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
449 OMNIA_ATSHA204_OTP_VERSION,
Marek Behún4dfc57e2019-05-02 16:53:31 +0200450 (u8 *)&version_num);
Marek Behún09e16b82017-06-09 19:28:45 +0200451 if (err)
452 goto out;
453
454 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
455 OMNIA_ATSHA204_OTP_SERIAL,
Marek Behún4dfc57e2019-05-02 16:53:31 +0200456 (u8 *)&serial_num);
Marek Behún09e16b82017-06-09 19:28:45 +0200457 if (err)
458 goto out;
459
460 atsha204a_sleep(dev);
461 }
462
463out:
Marek Behúnc4ba72a2019-05-02 16:53:34 +0200464 printf("Turris Omnia:\n");
465 printf(" RAM size: %i MiB\n", omnia_get_ram_size_gb() * 1024);
Marek Behún09e16b82017-06-09 19:28:45 +0200466 if (err)
Marek Behúnc4ba72a2019-05-02 16:53:34 +0200467 printf(" Serial Number: unknown\n");
Marek Behún09e16b82017-06-09 19:28:45 +0200468 else
Marek Behúnc4ba72a2019-05-02 16:53:34 +0200469 printf(" Serial Number: %08X%08X\n", be32_to_cpu(version_num),
470 be32_to_cpu(serial_num));
Marek Behún09e16b82017-06-09 19:28:45 +0200471
472 return 0;
473}
474
475static void increment_mac(u8 *mac)
476{
477 int i;
478
479 for (i = 5; i >= 3; i--) {
480 mac[i] += 1;
481 if (mac[i])
482 break;
483 }
484}
485
486int misc_init_r(void)
487{
Marek Behún09e16b82017-06-09 19:28:45 +0200488 int err;
489 struct udevice *dev = get_atsha204a_dev();
490 u8 mac0[4], mac1[4], mac[6];
491
492 if (!dev)
493 goto out;
494
495 err = atsha204a_wakeup(dev);
496 if (err)
497 goto out;
498
499 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
500 OMNIA_ATSHA204_OTP_MAC0, mac0);
501 if (err)
502 goto out;
503
504 err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false,
505 OMNIA_ATSHA204_OTP_MAC1, mac1);
506 if (err)
507 goto out;
508
509 atsha204a_sleep(dev);
510
511 mac[0] = mac0[1];
512 mac[1] = mac0[2];
513 mac[2] = mac0[3];
514 mac[3] = mac1[1];
515 mac[4] = mac1[2];
516 mac[5] = mac1[3];
517
518 if (is_valid_ethaddr(mac))
Marek Behúncb50c712019-05-24 14:57:49 +0200519 eth_env_set_enetaddr("eth1addr", mac);
Marek Behún09e16b82017-06-09 19:28:45 +0200520
521 increment_mac(mac);
522
523 if (is_valid_ethaddr(mac))
Marek Behúncb50c712019-05-24 14:57:49 +0200524 eth_env_set_enetaddr("eth2addr", 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("ethaddr", mac);
Marek Behún09e16b82017-06-09 19:28:45 +0200530
531out:
Marek Behún09e16b82017-06-09 19:28:45 +0200532 return 0;
533}
534