turris_omnia.c 12 KB

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