1b6ee860bSMarek Behún /* 2b6ee860bSMarek Behún * Copyright (C) 2017 Marek Behun <marek.behun@nic.cz> 3b6ee860bSMarek Behún * Copyright (C) 2016 Tomas Hlavacek <tomas.hlavacek@nic.cz> 4b6ee860bSMarek Behún * 5b6ee860bSMarek Behún * Derived from the code for 6b6ee860bSMarek Behún * Marvell/db-88f6820-gp by Stefan Roese <sr@denx.de> 7b6ee860bSMarek Behún * 8b6ee860bSMarek Behún * SPDX-License-Identifier: GPL-2.0+ 9b6ee860bSMarek Behún */ 10b6ee860bSMarek Behún 11b6ee860bSMarek Behún #include <common.h> 12b6ee860bSMarek Behún #include <i2c.h> 13b6ee860bSMarek Behún #include <miiphy.h> 14b6ee860bSMarek Behún #include <netdev.h> 15b6ee860bSMarek Behún #include <asm/io.h> 16b6ee860bSMarek Behún #include <asm/arch/cpu.h> 17b6ee860bSMarek Behún #include <asm/arch/soc.h> 18b6ee860bSMarek Behún #include <dm/uclass.h> 19b6ee860bSMarek Behún #include <fdt_support.h> 20b6ee860bSMarek Behún #include <time.h> 21b6ee860bSMarek Behún 22b6ee860bSMarek Behún #ifdef CONFIG_ATSHA204A 23b6ee860bSMarek Behún # include <atsha204a-i2c.h> 24b6ee860bSMarek Behún #endif 25b6ee860bSMarek Behún 26b6ee860bSMarek Behún #ifdef CONFIG_WDT_ORION 27b6ee860bSMarek Behún # include <wdt.h> 28b6ee860bSMarek Behún #endif 29b6ee860bSMarek Behún 30b6ee860bSMarek Behún #include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h" 31b6ee860bSMarek Behún #include <../serdes/a38x/high_speed_env_spec.h> 32b6ee860bSMarek Behún 33b6ee860bSMarek Behún DECLARE_GLOBAL_DATA_PTR; 34b6ee860bSMarek Behún 35b6ee860bSMarek Behún #define OMNIA_I2C_EEPROM_DM_NAME "i2c@0" 36b6ee860bSMarek Behún #define OMNIA_I2C_EEPROM 0x54 37b6ee860bSMarek Behún #define OMNIA_I2C_EEPROM_CONFIG_ADDR 0x0 38b6ee860bSMarek Behún #define OMNIA_I2C_EEPROM_ADDRLEN 2 39b6ee860bSMarek Behún #define OMNIA_I2C_EEPROM_MAGIC 0x0341a034 40b6ee860bSMarek Behún 41b6ee860bSMarek Behún #define OMNIA_I2C_MCU_DM_NAME "i2c@0" 42b6ee860bSMarek Behún #define OMNIA_I2C_MCU_ADDR_STATUS 0x1 43b6ee860bSMarek Behún #define OMNIA_I2C_MCU_SATA 0x20 44b6ee860bSMarek Behún #define OMNIA_I2C_MCU_CARDDET 0x10 45b6ee860bSMarek Behún #define OMNIA_I2C_MCU 0x2a 46b6ee860bSMarek Behún #define OMNIA_I2C_MCU_WDT_ADDR 0x0b 47b6ee860bSMarek Behún 48b6ee860bSMarek Behún #define OMNIA_ATSHA204_OTP_VERSION 0 49b6ee860bSMarek Behún #define OMNIA_ATSHA204_OTP_SERIAL 1 50b6ee860bSMarek Behún #define OMNIA_ATSHA204_OTP_MAC0 3 51b6ee860bSMarek Behún #define OMNIA_ATSHA204_OTP_MAC1 4 52b6ee860bSMarek Behún 53b6ee860bSMarek Behún #define MVTWSI_ARMADA_DEBUG_REG 0x8c 54b6ee860bSMarek Behún 55b6ee860bSMarek Behún /* 56b6ee860bSMarek Behún * Those values and defines are taken from the Marvell U-Boot version 57b6ee860bSMarek Behún * "u-boot-2013.01-2014_T3.0" 58b6ee860bSMarek Behún */ 59b6ee860bSMarek Behún #define OMNIA_GPP_OUT_ENA_LOW \ 60b6ee860bSMarek Behún (~(BIT(1) | BIT(4) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | \ 61b6ee860bSMarek Behún BIT(10) | BIT(11) | BIT(19) | BIT(22) | BIT(23) | BIT(25) | \ 62b6ee860bSMarek Behún BIT(26) | BIT(27) | BIT(29) | BIT(30) | BIT(31))) 63b6ee860bSMarek Behún #define OMNIA_GPP_OUT_ENA_MID \ 64b6ee860bSMarek Behún (~(BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(15) | \ 65b6ee860bSMarek Behún BIT(16) | BIT(17) | BIT(18))) 66b6ee860bSMarek Behún 67b6ee860bSMarek Behún #define OMNIA_GPP_OUT_VAL_LOW 0x0 68b6ee860bSMarek Behún #define OMNIA_GPP_OUT_VAL_MID 0x0 69b6ee860bSMarek Behún #define OMNIA_GPP_POL_LOW 0x0 70b6ee860bSMarek Behún #define OMNIA_GPP_POL_MID 0x0 71b6ee860bSMarek Behún 72b6ee860bSMarek Behún static struct serdes_map board_serdes_map_pex[] = { 73b6ee860bSMarek Behún {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, 74b6ee860bSMarek Behún {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, 75b6ee860bSMarek Behún {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, 76b6ee860bSMarek Behún {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, 77b6ee860bSMarek Behún {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, 78b6ee860bSMarek Behún {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0} 79b6ee860bSMarek Behún }; 80b6ee860bSMarek Behún 81b6ee860bSMarek Behún static struct serdes_map board_serdes_map_sata[] = { 82b6ee860bSMarek Behún {SATA0, SERDES_SPEED_6_GBPS, SERDES_DEFAULT_MODE, 0, 0}, 83b6ee860bSMarek Behún {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, 84b6ee860bSMarek Behún {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, 85b6ee860bSMarek Behún {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, 86b6ee860bSMarek Behún {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, 87b6ee860bSMarek Behún {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0} 88b6ee860bSMarek Behún }; 89b6ee860bSMarek Behún 90b6ee860bSMarek Behún static bool omnia_detect_sata(void) 91b6ee860bSMarek Behún { 92b6ee860bSMarek Behún struct udevice *bus, *dev; 93*8daa3468SMarek Behún int ret, retry = 3; 94b6ee860bSMarek Behún u16 mode; 95b6ee860bSMarek Behún 96b6ee860bSMarek Behún puts("SERDES0 card detect: "); 97b6ee860bSMarek Behún 98b6ee860bSMarek Behún if (uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_MCU_DM_NAME, &bus)) { 99b6ee860bSMarek Behún puts("Cannot find MCU bus!\n"); 100b6ee860bSMarek Behún return false; 101b6ee860bSMarek Behún } 102b6ee860bSMarek Behún 103b6ee860bSMarek Behún ret = i2c_get_chip(bus, OMNIA_I2C_MCU, 1, &dev); 104b6ee860bSMarek Behún if (ret) { 105b6ee860bSMarek Behún puts("Cannot get MCU chip!\n"); 106b6ee860bSMarek Behún return false; 107b6ee860bSMarek Behún } 108b6ee860bSMarek Behún 109*8daa3468SMarek Behún for (; retry > 0; --retry) { 110b6ee860bSMarek Behún ret = dm_i2c_read(dev, OMNIA_I2C_MCU_ADDR_STATUS, (uchar *) &mode, 2); 111*8daa3468SMarek Behún if (!ret) 112*8daa3468SMarek Behún break; 113*8daa3468SMarek Behún } 114*8daa3468SMarek Behún 115*8daa3468SMarek Behún if (!retry) { 116b6ee860bSMarek Behún puts("I2C read failed! Default PEX\n"); 117b6ee860bSMarek Behún return false; 118b6ee860bSMarek Behún } 119b6ee860bSMarek Behún 120b6ee860bSMarek Behún if (!(mode & OMNIA_I2C_MCU_CARDDET)) { 121b6ee860bSMarek Behún puts("NONE\n"); 122b6ee860bSMarek Behún return false; 123b6ee860bSMarek Behún } 124b6ee860bSMarek Behún 125b6ee860bSMarek Behún if (mode & OMNIA_I2C_MCU_SATA) { 126b6ee860bSMarek Behún puts("SATA\n"); 127b6ee860bSMarek Behún return true; 128b6ee860bSMarek Behún } else { 129b6ee860bSMarek Behún puts("PEX\n"); 130b6ee860bSMarek Behún return false; 131b6ee860bSMarek Behún } 132b6ee860bSMarek Behún } 133b6ee860bSMarek Behún 134b6ee860bSMarek Behún int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) 135b6ee860bSMarek Behún { 136b6ee860bSMarek Behún if (omnia_detect_sata()) { 137b6ee860bSMarek Behún *serdes_map_array = board_serdes_map_sata; 138b6ee860bSMarek Behún *count = ARRAY_SIZE(board_serdes_map_sata); 139b6ee860bSMarek Behún } else { 140b6ee860bSMarek Behún *serdes_map_array = board_serdes_map_pex; 141b6ee860bSMarek Behún *count = ARRAY_SIZE(board_serdes_map_pex); 142b6ee860bSMarek Behún } 143b6ee860bSMarek Behún 144b6ee860bSMarek Behún return 0; 145b6ee860bSMarek Behún } 146b6ee860bSMarek Behún 147b6ee860bSMarek Behún struct omnia_eeprom { 148b6ee860bSMarek Behún u32 magic; 149b6ee860bSMarek Behún u32 ramsize; 150b6ee860bSMarek Behún char region[4]; 151b6ee860bSMarek Behún u32 crc; 152b6ee860bSMarek Behún }; 153b6ee860bSMarek Behún 154b6ee860bSMarek Behún static bool omnia_read_eeprom(struct omnia_eeprom *oep) 155b6ee860bSMarek Behún { 156b6ee860bSMarek Behún struct udevice *bus, *dev; 157b6ee860bSMarek Behún int ret, crc, retry = 3; 158b6ee860bSMarek Behún 159b6ee860bSMarek Behún if (uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_EEPROM_DM_NAME, &bus)) { 160b6ee860bSMarek Behún puts("Cannot find EEPROM bus\n"); 161b6ee860bSMarek Behún return false; 162b6ee860bSMarek Behún } 163b6ee860bSMarek Behún 164b6ee860bSMarek Behún ret = i2c_get_chip(bus, OMNIA_I2C_EEPROM, OMNIA_I2C_EEPROM_ADDRLEN, &dev); 165b6ee860bSMarek Behún if (ret) { 166b6ee860bSMarek Behún puts("Cannot get EEPROM chip\n"); 167b6ee860bSMarek Behún return false; 168b6ee860bSMarek Behún } 169b6ee860bSMarek Behún 170b6ee860bSMarek Behún for (; retry > 0; --retry) { 171b6ee860bSMarek Behún ret = dm_i2c_read(dev, OMNIA_I2C_EEPROM_CONFIG_ADDR, (uchar *) oep, sizeof(struct omnia_eeprom)); 172b6ee860bSMarek Behún if (ret) 173b6ee860bSMarek Behún continue; 174b6ee860bSMarek Behún 175b6ee860bSMarek Behún if (oep->magic != OMNIA_I2C_EEPROM_MAGIC) { 176b6ee860bSMarek Behún puts("I2C EEPROM missing magic number!\n"); 177b6ee860bSMarek Behún continue; 178b6ee860bSMarek Behún } 179b6ee860bSMarek Behún 180b6ee860bSMarek Behún crc = crc32(0, (unsigned char *) oep, 181b6ee860bSMarek Behún sizeof(struct omnia_eeprom) - 4); 182b6ee860bSMarek Behún if (crc == oep->crc) { 183b6ee860bSMarek Behún break; 184b6ee860bSMarek Behún } else { 185b6ee860bSMarek Behún printf("CRC of EEPROM memory config failed! " 186b6ee860bSMarek Behún "calc=0x%04x saved=0x%04x\n", crc, oep->crc); 187b6ee860bSMarek Behún } 188b6ee860bSMarek Behún } 189b6ee860bSMarek Behún 190b6ee860bSMarek Behún if (!retry) { 191b6ee860bSMarek Behún puts("I2C EEPROM read failed!\n"); 192b6ee860bSMarek Behún return false; 193b6ee860bSMarek Behún } 194b6ee860bSMarek Behún 195b6ee860bSMarek Behún return true; 196b6ee860bSMarek Behún } 197b6ee860bSMarek Behún 198b6ee860bSMarek Behún /* 199b6ee860bSMarek Behún * Define the DDR layout / topology here in the board file. This will 200b6ee860bSMarek Behún * be used by the DDR3 init code in the SPL U-Boot version to configure 201b6ee860bSMarek Behún * the DDR3 controller. 202b6ee860bSMarek Behún */ 203b6ee860bSMarek Behún static struct hws_topology_map board_topology_map_1g = { 204b6ee860bSMarek Behún 0x1, /* active interfaces */ 205b6ee860bSMarek Behún /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ 206b6ee860bSMarek Behún { { { {0x1, 0, 0, 0}, 207b6ee860bSMarek Behún {0x1, 0, 0, 0}, 208b6ee860bSMarek Behún {0x1, 0, 0, 0}, 209b6ee860bSMarek Behún {0x1, 0, 0, 0}, 210b6ee860bSMarek Behún {0x1, 0, 0, 0} }, 211b6ee860bSMarek Behún SPEED_BIN_DDR_1600K, /* speed_bin */ 212b6ee860bSMarek Behún BUS_WIDTH_16, /* memory_width */ 213b6ee860bSMarek Behún MEM_4G, /* mem_size */ 214b6ee860bSMarek Behún DDR_FREQ_800, /* frequency */ 215b6ee860bSMarek Behún 0, 0, /* cas_l cas_wl */ 216b6ee860bSMarek Behún HWS_TEMP_NORMAL, /* temperature */ 217b6ee860bSMarek Behún HWS_TIM_2T} }, /* timing (force 2t) */ 218b6ee860bSMarek Behún 5, /* Num Of Bus Per Interface*/ 219b6ee860bSMarek Behún BUS_MASK_32BIT /* Busses mask */ 220b6ee860bSMarek Behún }; 221b6ee860bSMarek Behún 222b6ee860bSMarek Behún static struct hws_topology_map board_topology_map_2g = { 223b6ee860bSMarek Behún 0x1, /* active interfaces */ 224b6ee860bSMarek Behún /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ 225b6ee860bSMarek Behún { { { {0x1, 0, 0, 0}, 226b6ee860bSMarek Behún {0x1, 0, 0, 0}, 227b6ee860bSMarek Behún {0x1, 0, 0, 0}, 228b6ee860bSMarek Behún {0x1, 0, 0, 0}, 229b6ee860bSMarek Behún {0x1, 0, 0, 0} }, 230b6ee860bSMarek Behún SPEED_BIN_DDR_1600K, /* speed_bin */ 231b6ee860bSMarek Behún BUS_WIDTH_16, /* memory_width */ 232b6ee860bSMarek Behún MEM_8G, /* mem_size */ 233b6ee860bSMarek Behún DDR_FREQ_800, /* frequency */ 234b6ee860bSMarek Behún 0, 0, /* cas_l cas_wl */ 235b6ee860bSMarek Behún HWS_TEMP_NORMAL, /* temperature */ 236b6ee860bSMarek Behún HWS_TIM_2T} }, /* timing (force 2t) */ 237b6ee860bSMarek Behún 5, /* Num Of Bus Per Interface*/ 238b6ee860bSMarek Behún BUS_MASK_32BIT /* Busses mask */ 239b6ee860bSMarek Behún }; 240b6ee860bSMarek Behún 241b6ee860bSMarek Behún struct hws_topology_map *ddr3_get_topology_map(void) 242b6ee860bSMarek Behún { 243b6ee860bSMarek Behún static int mem = 0; 244b6ee860bSMarek Behún struct omnia_eeprom oep; 245b6ee860bSMarek Behún 246b6ee860bSMarek Behún /* Get the board config from EEPROM */ 247b6ee860bSMarek Behún if (mem == 0) { 248b6ee860bSMarek Behún if(!omnia_read_eeprom(&oep)) 249b6ee860bSMarek Behún goto out; 250b6ee860bSMarek Behún 251b6ee860bSMarek Behún printf("Memory config in EEPROM: 0x%02x\n", oep.ramsize); 252b6ee860bSMarek Behún 253b6ee860bSMarek Behún if (oep.ramsize == 0x2) 254b6ee860bSMarek Behún mem = 2; 255b6ee860bSMarek Behún else 256b6ee860bSMarek Behún mem = 1; 257b6ee860bSMarek Behún } 258b6ee860bSMarek Behún 259b6ee860bSMarek Behún out: 260b6ee860bSMarek Behún /* Hardcoded fallback */ 261b6ee860bSMarek Behún if (mem == 0) { 262b6ee860bSMarek Behún puts("WARNING: Memory config from EEPROM read failed.\n"); 263b6ee860bSMarek Behún puts("Falling back to default 1GiB map.\n"); 264b6ee860bSMarek Behún mem = 1; 265b6ee860bSMarek Behún } 266b6ee860bSMarek Behún 267b6ee860bSMarek Behún /* Return the board topology as defined in the board code */ 268b6ee860bSMarek Behún if (mem == 1) 269b6ee860bSMarek Behún return &board_topology_map_1g; 270b6ee860bSMarek Behún if (mem == 2) 271b6ee860bSMarek Behún return &board_topology_map_2g; 272b6ee860bSMarek Behún 273b6ee860bSMarek Behún return &board_topology_map_1g; 274b6ee860bSMarek Behún } 275b6ee860bSMarek Behún 276b6ee860bSMarek Behún #ifndef CONFIG_SPL_BUILD 277b6ee860bSMarek Behún static int set_regdomain(void) 278b6ee860bSMarek Behún { 279b6ee860bSMarek Behún struct omnia_eeprom oep; 280b6ee860bSMarek Behún char rd[3] = {' ', ' ', 0}; 281b6ee860bSMarek Behún 282b6ee860bSMarek Behún if (omnia_read_eeprom(&oep)) 283b6ee860bSMarek Behún memcpy(rd, &oep.region, 2); 284b6ee860bSMarek Behún else 285b6ee860bSMarek Behún puts("EEPROM regdomain read failed.\n"); 286b6ee860bSMarek Behún 287b6ee860bSMarek Behún printf("Regdomain set to %s\n", rd); 288b6ee860bSMarek Behún return setenv("regdomain", rd); 289b6ee860bSMarek Behún } 290b6ee860bSMarek Behún #endif 291b6ee860bSMarek Behún 292b6ee860bSMarek Behún int board_early_init_f(void) 293b6ee860bSMarek Behún { 294b6ee860bSMarek Behún u32 i2c_debug_reg; 295b6ee860bSMarek Behún 296b6ee860bSMarek Behún /* Configure MPP */ 297b6ee860bSMarek Behún writel(0x11111111, MVEBU_MPP_BASE + 0x00); 298b6ee860bSMarek Behún writel(0x11111111, MVEBU_MPP_BASE + 0x04); 299b6ee860bSMarek Behún writel(0x11244011, MVEBU_MPP_BASE + 0x08); 300b6ee860bSMarek Behún writel(0x22222111, MVEBU_MPP_BASE + 0x0c); 301b6ee860bSMarek Behún writel(0x22200002, MVEBU_MPP_BASE + 0x10); 302b6ee860bSMarek Behún writel(0x30042022, MVEBU_MPP_BASE + 0x14); 303b6ee860bSMarek Behún writel(0x55550555, MVEBU_MPP_BASE + 0x18); 304b6ee860bSMarek Behún writel(0x00005550, MVEBU_MPP_BASE + 0x1c); 305b6ee860bSMarek Behún 306b6ee860bSMarek Behún /* Set GPP Out value */ 307b6ee860bSMarek Behún writel(OMNIA_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00); 308b6ee860bSMarek Behún writel(OMNIA_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00); 309b6ee860bSMarek Behún 310b6ee860bSMarek Behún /* Set GPP Polarity */ 311b6ee860bSMarek Behún writel(OMNIA_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c); 312b6ee860bSMarek Behún writel(OMNIA_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c); 313b6ee860bSMarek Behún 314b6ee860bSMarek Behún /* Set GPP Out Enable */ 315b6ee860bSMarek Behún writel(OMNIA_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04); 316b6ee860bSMarek Behún writel(OMNIA_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04); 317b6ee860bSMarek Behún 318b6ee860bSMarek Behún /* Disable I2C debug mode blocking 0x64 I2C address */ 319b6ee860bSMarek Behún i2c_debug_reg = readl(MVEBU_TWSI_BASE + MVTWSI_ARMADA_DEBUG_REG); 320b6ee860bSMarek Behún i2c_debug_reg &= ~(1<<18); 321b6ee860bSMarek Behún writel(i2c_debug_reg, MVEBU_TWSI_BASE + MVTWSI_ARMADA_DEBUG_REG); 322b6ee860bSMarek Behún 323b6ee860bSMarek Behún return 0; 324b6ee860bSMarek Behún } 325b6ee860bSMarek Behún 326b6ee860bSMarek Behún #ifndef CONFIG_SPL_BUILD 327b6ee860bSMarek Behún static bool disable_mcu_watchdog(void) 328b6ee860bSMarek Behún { 329b6ee860bSMarek Behún struct udevice *bus, *dev; 330b6ee860bSMarek Behún int ret, retry = 3; 331b6ee860bSMarek Behún uchar buf[1] = {0x0}; 332b6ee860bSMarek Behún 333b6ee860bSMarek Behún if (uclass_get_device_by_name(UCLASS_I2C, OMNIA_I2C_MCU_DM_NAME, &bus)) { 334b6ee860bSMarek Behún puts("Cannot find MCU bus! Can not disable MCU WDT.\n"); 335b6ee860bSMarek Behún return false; 336b6ee860bSMarek Behún } 337b6ee860bSMarek Behún 338b6ee860bSMarek Behún ret = i2c_get_chip(bus, OMNIA_I2C_MCU, 1, &dev); 339b6ee860bSMarek Behún if (ret) { 340b6ee860bSMarek Behún puts("Cannot get MCU chip! Can not disable MCU WDT.\n"); 341b6ee860bSMarek Behún return false; 342b6ee860bSMarek Behún } 343b6ee860bSMarek Behún 344b6ee860bSMarek Behún for (; retry > 0; --retry) 345b6ee860bSMarek Behún if (!dm_i2c_write(dev, OMNIA_I2C_MCU_WDT_ADDR, (uchar *) buf, 1)) 346b6ee860bSMarek Behún break; 347b6ee860bSMarek Behún 348b6ee860bSMarek Behún if (retry <= 0) { 349b6ee860bSMarek Behún puts("I2C MCU watchdog failed to disable!\n"); 350b6ee860bSMarek Behún return false; 351b6ee860bSMarek Behún } 352b6ee860bSMarek Behún 353b6ee860bSMarek Behún return true; 354b6ee860bSMarek Behún } 355b6ee860bSMarek Behún #endif 356b6ee860bSMarek Behún 357b6ee860bSMarek Behún #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) 358b6ee860bSMarek Behún static struct udevice *watchdog_dev = NULL; 359b6ee860bSMarek Behún #endif 360b6ee860bSMarek Behún 361b6ee860bSMarek Behún int board_init(void) 362b6ee860bSMarek Behún { 363b6ee860bSMarek Behún /* adress of boot parameters */ 364b6ee860bSMarek Behún gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; 365b6ee860bSMarek Behún 366b6ee860bSMarek Behún #ifndef CONFIG_SPL_BUILD 367b6ee860bSMarek Behún # ifdef CONFIG_WDT_ORION 368b6ee860bSMarek Behún if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { 369b6ee860bSMarek Behún puts("Cannot find Armada 385 watchdog!\n"); 370b6ee860bSMarek Behún } else { 371b6ee860bSMarek Behún puts("Enabling Armada 385 watchdog.\n"); 372b6ee860bSMarek Behún wdt_start(watchdog_dev, (u32) 25000000 * 120, 0); 373b6ee860bSMarek Behún } 374b6ee860bSMarek Behún # endif 375b6ee860bSMarek Behún 376b6ee860bSMarek Behún if (disable_mcu_watchdog()) 377b6ee860bSMarek Behún puts("Disabled MCU startup watchdog.\n"); 378b6ee860bSMarek Behún 379b6ee860bSMarek Behún set_regdomain(); 380b6ee860bSMarek Behún #endif 381b6ee860bSMarek Behún 382b6ee860bSMarek Behún return 0; 383b6ee860bSMarek Behún } 384b6ee860bSMarek Behún 385b6ee860bSMarek Behún #ifdef CONFIG_WATCHDOG 386b6ee860bSMarek Behún /* Called by macro WATCHDOG_RESET */ 387b6ee860bSMarek Behún void watchdog_reset(void) 388b6ee860bSMarek Behún { 389b6ee860bSMarek Behún # if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT_ORION) 390b6ee860bSMarek Behún static ulong next_reset = 0; 391b6ee860bSMarek Behún ulong now; 392b6ee860bSMarek Behún 393b6ee860bSMarek Behún if (!watchdog_dev) 394b6ee860bSMarek Behún return; 395b6ee860bSMarek Behún 396b6ee860bSMarek Behún now = timer_get_us(); 397b6ee860bSMarek Behún 398b6ee860bSMarek Behún /* Do not reset the watchdog too often */ 399b6ee860bSMarek Behún if (now > next_reset) { 400b6ee860bSMarek Behún wdt_reset(watchdog_dev); 401b6ee860bSMarek Behún next_reset = now + 1000; 402b6ee860bSMarek Behún } 403b6ee860bSMarek Behún # endif 404b6ee860bSMarek Behún } 405b6ee860bSMarek Behún #endif 406b6ee860bSMarek Behún 407b6ee860bSMarek Behún int board_late_init(void) 408b6ee860bSMarek Behún { 409b6ee860bSMarek Behún #ifndef CONFIG_SPL_BUILD 410b6ee860bSMarek Behún set_regdomain(); 411b6ee860bSMarek Behún #endif 412b6ee860bSMarek Behún 413b6ee860bSMarek Behún return 0; 414b6ee860bSMarek Behún } 415b6ee860bSMarek Behún 416b6ee860bSMarek Behún #ifdef CONFIG_ATSHA204A 417b6ee860bSMarek Behún static struct udevice *get_atsha204a_dev(void) 418b6ee860bSMarek Behún { 419b6ee860bSMarek Behún static struct udevice *dev = NULL; 420b6ee860bSMarek Behún 421b6ee860bSMarek Behún if (dev != NULL) 422b6ee860bSMarek Behún return dev; 423b6ee860bSMarek Behún 424b6ee860bSMarek Behún if (uclass_get_device_by_name(UCLASS_MISC, "atsha204a@64", &dev)) { 425b6ee860bSMarek Behún puts("Cannot find ATSHA204A on I2C bus!\n"); 426b6ee860bSMarek Behún dev = NULL; 427b6ee860bSMarek Behún } 428b6ee860bSMarek Behún 429b6ee860bSMarek Behún return dev; 430b6ee860bSMarek Behún } 431b6ee860bSMarek Behún #endif 432b6ee860bSMarek Behún 433b6ee860bSMarek Behún int checkboard(void) 434b6ee860bSMarek Behún { 435b6ee860bSMarek Behún u32 version_num, serial_num; 436b6ee860bSMarek Behún int err = 1; 437b6ee860bSMarek Behún 438b6ee860bSMarek Behún #ifdef CONFIG_ATSHA204A 439b6ee860bSMarek Behún struct udevice *dev = get_atsha204a_dev(); 440b6ee860bSMarek Behún 441b6ee860bSMarek Behún if (dev) { 442b6ee860bSMarek Behún err = atsha204a_wakeup(dev); 443b6ee860bSMarek Behún if (err) 444b6ee860bSMarek Behún goto out; 445b6ee860bSMarek Behún 446b6ee860bSMarek Behún err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false, 447b6ee860bSMarek Behún OMNIA_ATSHA204_OTP_VERSION, 448b6ee860bSMarek Behún (u8 *) &version_num); 449b6ee860bSMarek Behún if (err) 450b6ee860bSMarek Behún goto out; 451b6ee860bSMarek Behún 452b6ee860bSMarek Behún err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false, 453b6ee860bSMarek Behún OMNIA_ATSHA204_OTP_SERIAL, 454b6ee860bSMarek Behún (u8 *) &serial_num); 455b6ee860bSMarek Behún if (err) 456b6ee860bSMarek Behún goto out; 457b6ee860bSMarek Behún 458b6ee860bSMarek Behún atsha204a_sleep(dev); 459b6ee860bSMarek Behún } 460b6ee860bSMarek Behún 461b6ee860bSMarek Behún out: 462b6ee860bSMarek Behún #endif 463b6ee860bSMarek Behún 464b6ee860bSMarek Behún if (err) 465b6ee860bSMarek Behún printf("Board: Turris Omnia (ver N/A). SN: N/A\n"); 466b6ee860bSMarek Behún else 467b6ee860bSMarek Behún printf("Board: Turris Omnia SNL %08X%08X\n", 468b6ee860bSMarek Behún be32_to_cpu(version_num), be32_to_cpu(serial_num)); 469b6ee860bSMarek Behún 470b6ee860bSMarek Behún return 0; 471b6ee860bSMarek Behún } 472b6ee860bSMarek Behún 473b6ee860bSMarek Behún static void increment_mac(u8 *mac) 474b6ee860bSMarek Behún { 475b6ee860bSMarek Behún int i; 476b6ee860bSMarek Behún 477b6ee860bSMarek Behún for (i = 5; i >= 3; i--) { 478b6ee860bSMarek Behún mac[i] += 1; 479b6ee860bSMarek Behún if (mac[i]) 480b6ee860bSMarek Behún break; 481b6ee860bSMarek Behún } 482b6ee860bSMarek Behún } 483b6ee860bSMarek Behún 484b6ee860bSMarek Behún int misc_init_r(void) 485b6ee860bSMarek Behún { 486b6ee860bSMarek Behún #ifdef CONFIG_ATSHA204A 487b6ee860bSMarek Behún int err; 488b6ee860bSMarek Behún struct udevice *dev = get_atsha204a_dev(); 489b6ee860bSMarek Behún u8 mac0[4], mac1[4], mac[6]; 490b6ee860bSMarek Behún 491b6ee860bSMarek Behún if (!dev) 492b6ee860bSMarek Behún goto out; 493b6ee860bSMarek Behún 494b6ee860bSMarek Behún err = atsha204a_wakeup(dev); 495b6ee860bSMarek Behún if (err) 496b6ee860bSMarek Behún goto out; 497b6ee860bSMarek Behún 498b6ee860bSMarek Behún err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false, 499b6ee860bSMarek Behún OMNIA_ATSHA204_OTP_MAC0, mac0); 500b6ee860bSMarek Behún if (err) 501b6ee860bSMarek Behún goto out; 502b6ee860bSMarek Behún 503b6ee860bSMarek Behún err = atsha204a_read(dev, ATSHA204A_ZONE_OTP, false, 504b6ee860bSMarek Behún OMNIA_ATSHA204_OTP_MAC1, mac1); 505b6ee860bSMarek Behún if (err) 506b6ee860bSMarek Behún goto out; 507b6ee860bSMarek Behún 508b6ee860bSMarek Behún atsha204a_sleep(dev); 509b6ee860bSMarek Behún 510b6ee860bSMarek Behún mac[0] = mac0[1]; 511b6ee860bSMarek Behún mac[1] = mac0[2]; 512b6ee860bSMarek Behún mac[2] = mac0[3]; 513b6ee860bSMarek Behún mac[3] = mac1[1]; 514b6ee860bSMarek Behún mac[4] = mac1[2]; 515b6ee860bSMarek Behún mac[5] = mac1[3]; 516b6ee860bSMarek Behún 517b6ee860bSMarek Behún if (is_valid_ethaddr(mac)) 518b6ee860bSMarek Behún eth_setenv_enetaddr("ethaddr", mac); 519b6ee860bSMarek Behún 520b6ee860bSMarek Behún increment_mac(mac); 521b6ee860bSMarek Behún 522b6ee860bSMarek Behún if (is_valid_ethaddr(mac)) 523b6ee860bSMarek Behún eth_setenv_enetaddr("eth1addr", mac); 524b6ee860bSMarek Behún 525b6ee860bSMarek Behún increment_mac(mac); 526b6ee860bSMarek Behún 527b6ee860bSMarek Behún if (is_valid_ethaddr(mac)) 528b6ee860bSMarek Behún eth_setenv_enetaddr("eth2addr", mac); 529b6ee860bSMarek Behún 530b6ee860bSMarek Behún out: 531b6ee860bSMarek Behún #endif 532b6ee860bSMarek Behún 533b6ee860bSMarek Behún return 0; 534b6ee860bSMarek Behún } 535b6ee860bSMarek Behún 536