turris_mox.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
  4. */
  5. #include <common.h>
  6. #include <asm/arch/cpu.h>
  7. #include <asm/arch/soc.h>
  8. #include <net.h>
  9. #include <asm/io.h>
  10. #include <asm/gpio.h>
  11. #include <clk.h>
  12. #include <dm.h>
  13. #include <env.h>
  14. #include <fdt_support.h>
  15. #include <init.h>
  16. #include <linux/delay.h>
  17. #include <linux/libfdt.h>
  18. #include <linux/string.h>
  19. #include <miiphy.h>
  20. #include <mvebu/comphy.h>
  21. #include <spi.h>
  22. #include "mox_sp.h"
  23. #define MAX_MOX_MODULES 10
  24. #define MOX_MODULE_SFP 0x1
  25. #define MOX_MODULE_PCI 0x2
  26. #define MOX_MODULE_TOPAZ 0x3
  27. #define MOX_MODULE_PERIDOT 0x4
  28. #define MOX_MODULE_USB3 0x5
  29. #define MOX_MODULE_PASSPCI 0x6
  30. #define ARMADA_37XX_NB_GPIO_SEL (MVEBU_REGISTER(0x13830))
  31. #define ARMADA_37XX_SPI_CTRL (MVEBU_REGISTER(0x10600))
  32. #define ARMADA_37XX_SPI_CFG (MVEBU_REGISTER(0x10604))
  33. #define ARMADA_37XX_SPI_DOUT (MVEBU_REGISTER(0x10608))
  34. #define ARMADA_37XX_SPI_DIN (MVEBU_REGISTER(0x1060c))
  35. #define ETH1_PATH "/soc/internal-regs@d0000000/ethernet@40000"
  36. #define MDIO_PATH "/soc/internal-regs@d0000000/mdio@32004"
  37. #define SFP_GPIO_PATH "/soc/internal-regs@d0000000/spi@10600/moxtet@1/gpio@0"
  38. #define PCIE_PATH "/soc/pcie@d0070000"
  39. #define SFP_PATH "/sfp"
  40. DECLARE_GLOBAL_DATA_PTR;
  41. #if defined(CONFIG_OF_BOARD_FIXUP)
  42. int board_fix_fdt(void *blob)
  43. {
  44. u8 topology[MAX_MOX_MODULES];
  45. int i, size, node;
  46. bool enable;
  47. /*
  48. * SPI driver is not loaded in driver model yet, but we have to find out
  49. * if pcie should be enabled in U-Boot's device tree. Therefore we have
  50. * to read SPI by reading/writing SPI registers directly
  51. */
  52. writel(0x10df, ARMADA_37XX_SPI_CFG);
  53. /* put pin from GPIO to SPI mode */
  54. clrbits_le32(ARMADA_37XX_NB_GPIO_SEL, BIT(12));
  55. /* enable SPI CS1 */
  56. setbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17));
  57. while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
  58. udelay(1);
  59. for (i = 0; i < MAX_MOX_MODULES; ++i) {
  60. writel(0x0, ARMADA_37XX_SPI_DOUT);
  61. while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
  62. udelay(1);
  63. topology[i] = readl(ARMADA_37XX_SPI_DIN) & 0xff;
  64. if (topology[i] == 0xff)
  65. break;
  66. topology[i] &= 0xf;
  67. }
  68. size = i;
  69. /* disable SPI CS1 */
  70. clrbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17));
  71. if (size > 1 && (topology[1] == MOX_MODULE_PCI ||
  72. topology[1] == MOX_MODULE_USB3 ||
  73. topology[1] == MOX_MODULE_PASSPCI))
  74. enable = true;
  75. else
  76. enable = false;
  77. node = fdt_path_offset(blob, PCIE_PATH);
  78. if (node < 0) {
  79. printf("Cannot find PCIe node in U-Boot's device tree!\n");
  80. return 0;
  81. }
  82. if (fdt_setprop_string(blob, node, "status",
  83. enable ? "okay" : "disabled") < 0) {
  84. printf("Cannot %s PCIe in U-Boot's device tree!\n",
  85. enable ? "enable" : "disable");
  86. return 0;
  87. }
  88. if (a3700_fdt_fix_pcie_regions(blob) < 0) {
  89. printf("Cannot fix PCIe regions in U-Boot's device tree!\n");
  90. return 0;
  91. }
  92. return 0;
  93. }
  94. #endif
  95. int board_init(void)
  96. {
  97. /* address of boot parameters */
  98. gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
  99. return 0;
  100. }
  101. static int mox_do_spi(u8 *in, u8 *out, size_t size)
  102. {
  103. struct spi_slave *slave;
  104. struct udevice *dev;
  105. int ret;
  106. ret = spi_get_bus_and_cs(0, 1, 1000000, SPI_CPHA | SPI_CPOL,
  107. "spi_generic_drv", "moxtet@1", &dev,
  108. &slave);
  109. if (ret)
  110. goto fail;
  111. ret = spi_claim_bus(slave);
  112. if (ret)
  113. goto fail_free;
  114. ret = spi_xfer(slave, size * 8, out, in, SPI_XFER_ONCE);
  115. spi_release_bus(slave);
  116. fail_free:
  117. spi_free_slave(slave);
  118. fail:
  119. return ret;
  120. }
  121. static int mox_get_topology(const u8 **ptopology, int *psize, int *pis_sd)
  122. {
  123. static int is_sd;
  124. static u8 topology[MAX_MOX_MODULES - 1];
  125. static int size;
  126. u8 din[MAX_MOX_MODULES], dout[MAX_MOX_MODULES];
  127. int ret, i;
  128. if (size) {
  129. if (ptopology)
  130. *ptopology = topology;
  131. if (psize)
  132. *psize = size;
  133. if (pis_sd)
  134. *pis_sd = is_sd;
  135. return 0;
  136. }
  137. memset(din, 0, MAX_MOX_MODULES);
  138. memset(dout, 0, MAX_MOX_MODULES);
  139. ret = mox_do_spi(din, dout, MAX_MOX_MODULES);
  140. if (ret)
  141. return ret;
  142. if (din[0] == 0x10)
  143. is_sd = 1;
  144. else if (din[0] == 0x00)
  145. is_sd = 0;
  146. else
  147. return -ENODEV;
  148. for (i = 1; i < MAX_MOX_MODULES && din[i] != 0xff; ++i)
  149. topology[i - 1] = din[i] & 0xf;
  150. size = i - 1;
  151. if (ptopology)
  152. *ptopology = topology;
  153. if (psize)
  154. *psize = size;
  155. if (pis_sd)
  156. *pis_sd = is_sd;
  157. return 0;
  158. }
  159. int comphy_update_map(struct comphy_map *serdes_map, int count)
  160. {
  161. int ret, i, size, sfpindex = -1, swindex = -1;
  162. const u8 *topology;
  163. ret = mox_get_topology(&topology, &size, NULL);
  164. if (ret)
  165. return ret;
  166. for (i = 0; i < size; ++i) {
  167. if (topology[i] == MOX_MODULE_SFP && sfpindex == -1)
  168. sfpindex = i;
  169. else if ((topology[i] == MOX_MODULE_TOPAZ ||
  170. topology[i] == MOX_MODULE_PERIDOT) &&
  171. swindex == -1)
  172. swindex = i;
  173. }
  174. if (sfpindex >= 0 && swindex >= 0) {
  175. if (sfpindex < swindex)
  176. serdes_map[0].speed = PHY_SPEED_1_25G;
  177. else
  178. serdes_map[0].speed = PHY_SPEED_3_125G;
  179. } else if (sfpindex >= 0) {
  180. serdes_map[0].speed = PHY_SPEED_1_25G;
  181. } else if (swindex >= 0) {
  182. serdes_map[0].speed = PHY_SPEED_3_125G;
  183. }
  184. return 0;
  185. }
  186. #define SW_SMI_CMD_R(d, r) (0x9800 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
  187. #define SW_SMI_CMD_W(d, r) (0x9400 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
  188. static int sw_multi_read(struct mii_dev *bus, int sw, int dev, int reg)
  189. {
  190. bus->write(bus, sw, 0, 0, SW_SMI_CMD_R(dev, reg));
  191. mdelay(5);
  192. return bus->read(bus, sw, 0, 1);
  193. }
  194. static void sw_multi_write(struct mii_dev *bus, int sw, int dev, int reg,
  195. u16 val)
  196. {
  197. bus->write(bus, sw, 0, 1, val);
  198. bus->write(bus, sw, 0, 0, SW_SMI_CMD_W(dev, reg));
  199. mdelay(5);
  200. }
  201. static int sw_scratch_read(struct mii_dev *bus, int sw, int reg)
  202. {
  203. sw_multi_write(bus, sw, 0x1c, 0x1a, (reg & 0x7f) << 8);
  204. return sw_multi_read(bus, sw, 0x1c, 0x1a) & 0xff;
  205. }
  206. static void sw_led_write(struct mii_dev *bus, int sw, int port, int reg,
  207. u16 val)
  208. {
  209. sw_multi_write(bus, sw, port, 0x16, 0x8000 | ((reg & 7) << 12)
  210. | (val & 0x7ff));
  211. }
  212. static void sw_blink_leds(struct mii_dev *bus, int peridot, int topaz)
  213. {
  214. int i, p;
  215. struct {
  216. int port;
  217. u16 val;
  218. int wait;
  219. } regs[] = {
  220. { 2, 0xef, 1 }, { 2, 0xfe, 1 }, { 2, 0x33, 0 },
  221. { 4, 0xef, 1 }, { 4, 0xfe, 1 }, { 4, 0x33, 0 },
  222. { 3, 0xfe, 1 }, { 3, 0xef, 1 }, { 3, 0x33, 0 },
  223. { 1, 0xfe, 1 }, { 1, 0xef, 1 }, { 1, 0x33, 0 }
  224. };
  225. for (i = 0; i < 12; ++i) {
  226. for (p = 0; p < peridot; ++p) {
  227. sw_led_write(bus, 0x10 + p, regs[i].port, 0,
  228. regs[i].val);
  229. sw_led_write(bus, 0x10 + p, regs[i].port + 4, 0,
  230. regs[i].val);
  231. }
  232. if (topaz) {
  233. sw_led_write(bus, 0x2, 0x10 + regs[i].port, 0,
  234. regs[i].val);
  235. }
  236. if (regs[i].wait)
  237. mdelay(75);
  238. }
  239. }
  240. static void check_switch_address(struct mii_dev *bus, int addr)
  241. {
  242. if (sw_scratch_read(bus, addr, 0x70) >> 3 != addr)
  243. printf("Check of switch MDIO address failed for 0x%02x\n",
  244. addr);
  245. }
  246. static int sfp, pci, topaz, peridot, usb, passpci;
  247. static int sfp_pos, peridot_pos[3];
  248. static int module_count;
  249. static int configure_peridots(struct gpio_desc *reset_gpio)
  250. {
  251. int i, ret;
  252. u8 dout[MAX_MOX_MODULES];
  253. memset(dout, 0, MAX_MOX_MODULES);
  254. /* set addresses of Peridot modules */
  255. for (i = 0; i < peridot; ++i)
  256. dout[module_count - peridot_pos[i]] = (~i) & 3;
  257. /*
  258. * if there is a SFP module connected to the last Peridot module, set
  259. * the P10_SMODE to 1 for the Peridot module
  260. */
  261. if (sfp)
  262. dout[module_count - peridot_pos[i - 1]] |= 1 << 3;
  263. dm_gpio_set_value(reset_gpio, 1);
  264. mdelay(10);
  265. ret = mox_do_spi(NULL, dout, module_count + 1);
  266. mdelay(10);
  267. dm_gpio_set_value(reset_gpio, 0);
  268. mdelay(50);
  269. return ret;
  270. }
  271. static int get_reset_gpio(struct gpio_desc *reset_gpio)
  272. {
  273. int node;
  274. node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "cznic,moxtet");
  275. if (node < 0) {
  276. printf("Cannot find Moxtet bus device node!\n");
  277. return -1;
  278. }
  279. gpio_request_by_name_nodev(offset_to_ofnode(node), "reset-gpios", 0,
  280. reset_gpio, GPIOD_IS_OUT);
  281. if (!dm_gpio_is_valid(reset_gpio)) {
  282. printf("Cannot find reset GPIO for Moxtet bus!\n");
  283. return -1;
  284. }
  285. return 0;
  286. }
  287. int misc_init_r(void)
  288. {
  289. int ret;
  290. u8 mac1[6], mac2[6];
  291. ret = mbox_sp_get_board_info(NULL, mac1, mac2, NULL, NULL);
  292. if (ret < 0) {
  293. printf("Cannot read data from OTP!\n");
  294. return 0;
  295. }
  296. if (is_valid_ethaddr(mac1) && !env_get("ethaddr"))
  297. eth_env_set_enetaddr("ethaddr", mac1);
  298. if (is_valid_ethaddr(mac2) && !env_get("eth1addr"))
  299. eth_env_set_enetaddr("eth1addr", mac2);
  300. return 0;
  301. }
  302. static void mox_print_info(void)
  303. {
  304. int ret, board_version, ram_size;
  305. u64 serial_number;
  306. const char *pub_key;
  307. ret = mbox_sp_get_board_info(&serial_number, NULL, NULL, &board_version,
  308. &ram_size);
  309. if (ret < 0)
  310. return;
  311. printf("Turris Mox:\n");
  312. printf(" Board version: %i\n", board_version);
  313. printf(" RAM size: %i MiB\n", ram_size);
  314. printf(" Serial Number: %016llX\n", serial_number);
  315. pub_key = mox_sp_get_ecdsa_public_key();
  316. if (pub_key)
  317. printf(" ECDSA Public Key: %s\n", pub_key);
  318. else
  319. printf("Cannot read ECDSA Public Key\n");
  320. }
  321. int last_stage_init(void)
  322. {
  323. int ret, i;
  324. const u8 *topology;
  325. int is_sd;
  326. struct mii_dev *bus;
  327. struct gpio_desc reset_gpio = {};
  328. mox_print_info();
  329. ret = mox_get_topology(&topology, &module_count, &is_sd);
  330. if (ret) {
  331. printf("Cannot read module topology!\n");
  332. return 0;
  333. }
  334. printf(" SD/eMMC version: %s\n", is_sd ? "SD" : "eMMC");
  335. if (module_count)
  336. printf("Module Topology:\n");
  337. for (i = 0; i < module_count; ++i) {
  338. switch (topology[i]) {
  339. case MOX_MODULE_SFP:
  340. printf("% 4i: SFP Module\n", i + 1);
  341. break;
  342. case MOX_MODULE_PCI:
  343. printf("% 4i: Mini-PCIe Module\n", i + 1);
  344. break;
  345. case MOX_MODULE_TOPAZ:
  346. printf("% 4i: Topaz Switch Module (4-port)\n", i + 1);
  347. break;
  348. case MOX_MODULE_PERIDOT:
  349. printf("% 4i: Peridot Switch Module (8-port)\n", i + 1);
  350. break;
  351. case MOX_MODULE_USB3:
  352. printf("% 4i: USB 3.0 Module (4 ports)\n", i + 1);
  353. break;
  354. case MOX_MODULE_PASSPCI:
  355. printf("% 4i: Passthrough Mini-PCIe Module\n", i + 1);
  356. break;
  357. default:
  358. printf("% 4i: unknown (ID %i)\n", i + 1, topology[i]);
  359. }
  360. }
  361. /* now check if modules are connected in supported mode */
  362. for (i = 0; i < module_count; ++i) {
  363. switch (topology[i]) {
  364. case MOX_MODULE_SFP:
  365. if (sfp) {
  366. printf("Error: Only one SFP module is supported!\n");
  367. } else if (topaz) {
  368. printf("Error: SFP module cannot be connected after Topaz Switch module!\n");
  369. } else {
  370. sfp_pos = i;
  371. ++sfp;
  372. }
  373. break;
  374. case MOX_MODULE_PCI:
  375. if (pci)
  376. printf("Error: Only one Mini-PCIe module is supported!\n");
  377. else if (usb)
  378. printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n");
  379. else if (i && (i != 1 || !passpci))
  380. printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
  381. else
  382. ++pci;
  383. break;
  384. case MOX_MODULE_TOPAZ:
  385. if (topaz)
  386. printf("Error: Only one Topaz module is supported!\n");
  387. else if (peridot >= 3)
  388. printf("Error: At most two Peridot modules can come before Topaz module!\n");
  389. else
  390. ++topaz;
  391. break;
  392. case MOX_MODULE_PERIDOT:
  393. if (sfp || topaz) {
  394. printf("Error: Peridot module must come before SFP or Topaz module!\n");
  395. } else if (peridot >= 3) {
  396. printf("Error: At most three Peridot modules are supported!\n");
  397. } else {
  398. peridot_pos[peridot] = i;
  399. ++peridot;
  400. }
  401. break;
  402. case MOX_MODULE_USB3:
  403. if (pci)
  404. printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n");
  405. else if (usb)
  406. printf("Error: Only one USB 3.0 module is supported!\n");
  407. else if (i && (i != 1 || !passpci))
  408. printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
  409. else
  410. ++usb;
  411. break;
  412. case MOX_MODULE_PASSPCI:
  413. if (passpci)
  414. printf("Error: Only one Passthrough Mini-PCIe module is supported!\n");
  415. else if (i != 0)
  416. printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n");
  417. else
  418. ++passpci;
  419. }
  420. }
  421. /* now configure modules */
  422. if (get_reset_gpio(&reset_gpio) < 0)
  423. return 0;
  424. if (peridot > 0) {
  425. if (configure_peridots(&reset_gpio) < 0) {
  426. printf("Cannot configure Peridot modules!\n");
  427. peridot = 0;
  428. }
  429. } else {
  430. dm_gpio_set_value(&reset_gpio, 1);
  431. mdelay(50);
  432. dm_gpio_set_value(&reset_gpio, 0);
  433. mdelay(50);
  434. }
  435. if (peridot || topaz) {
  436. /*
  437. * now check if the addresses are set by reading Scratch & Misc
  438. * register 0x70 of Peridot (and potentially Topaz) modules
  439. */
  440. bus = miiphy_get_dev_by_name("neta@30000");
  441. if (!bus) {
  442. printf("Cannot get MDIO bus device!\n");
  443. } else {
  444. for (i = 0; i < peridot; ++i)
  445. check_switch_address(bus, 0x10 + i);
  446. if (topaz)
  447. check_switch_address(bus, 0x2);
  448. sw_blink_leds(bus, peridot, topaz);
  449. }
  450. }
  451. printf("\n");
  452. return 0;
  453. }
  454. #if defined(CONFIG_OF_BOARD_SETUP)
  455. static int vnode_by_path(void *blob, const char *fmt, va_list ap)
  456. {
  457. char path[128];
  458. vsnprintf(path, 128, fmt, ap);
  459. return fdt_path_offset(blob, path);
  460. }
  461. static int node_by_path(void *blob, const char *fmt, ...)
  462. {
  463. va_list ap;
  464. int res;
  465. va_start(ap, fmt);
  466. res = vnode_by_path(blob, fmt, ap);
  467. va_end(ap);
  468. return res;
  469. }
  470. static int phandle_by_path(void *blob, const char *fmt, ...)
  471. {
  472. va_list ap;
  473. int node, phandle, res;
  474. va_start(ap, fmt);
  475. node = vnode_by_path(blob, fmt, ap);
  476. va_end(ap);
  477. if (node < 0)
  478. return node;
  479. phandle = fdt_get_phandle(blob, node);
  480. if (phandle > 0)
  481. return phandle;
  482. phandle = fdt_get_max_phandle(blob);
  483. if (phandle < 0)
  484. return phandle;
  485. phandle += 1;
  486. res = fdt_setprop_u32(blob, node, "linux,phandle", phandle);
  487. if (res < 0)
  488. return res;
  489. res = fdt_setprop_u32(blob, node, "phandle", phandle);
  490. if (res < 0)
  491. return res;
  492. return phandle;
  493. }
  494. static int enable_by_path(void *blob, const char *fmt, ...)
  495. {
  496. va_list ap;
  497. int node;
  498. va_start(ap, fmt);
  499. node = vnode_by_path(blob, fmt, ap);
  500. va_end(ap);
  501. if (node < 0)
  502. return node;
  503. return fdt_setprop_string(blob, node, "status", "okay");
  504. }
  505. static bool is_topaz(int id)
  506. {
  507. return topaz && id == peridot + topaz - 1;
  508. }
  509. static int switch_addr(int id)
  510. {
  511. return is_topaz(id) ? 0x2 : 0x10 + id;
  512. }
  513. static int setup_switch(void *blob, int id)
  514. {
  515. int res, addr, i, node, phandle;
  516. addr = switch_addr(id);
  517. /* first enable the switch by setting status = "okay" */
  518. res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr);
  519. if (res < 0)
  520. return res;
  521. /*
  522. * now if there are more switches or a SFP module coming after,
  523. * enable corresponding ports
  524. */
  525. if (id < peridot + topaz - 1) {
  526. res = enable_by_path(blob,
  527. MDIO_PATH "/switch%i@%x/ports/port@a",
  528. id, addr);
  529. } else if (id == peridot - 1 && !topaz && sfp) {
  530. res = enable_by_path(blob,
  531. MDIO_PATH "/switch%i@%x/ports/port-sfp@a",
  532. id, addr);
  533. } else {
  534. res = 0;
  535. }
  536. if (res < 0)
  537. return res;
  538. if (id >= peridot + topaz - 1)
  539. return 0;
  540. /* finally change link property if needed */
  541. node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port@a", id,
  542. addr);
  543. if (node < 0)
  544. return node;
  545. for (i = id + 1; i < peridot + topaz; ++i) {
  546. phandle = phandle_by_path(blob,
  547. MDIO_PATH "/switch%i@%x/ports/port@%x",
  548. i, switch_addr(i),
  549. is_topaz(i) ? 5 : 9);
  550. if (phandle < 0)
  551. return phandle;
  552. if (i == id + 1)
  553. res = fdt_setprop_u32(blob, node, "link", phandle);
  554. else
  555. res = fdt_appendprop_u32(blob, node, "link", phandle);
  556. if (res < 0)
  557. return res;
  558. }
  559. return 0;
  560. }
  561. static int remove_disabled_nodes(void *blob)
  562. {
  563. while (1) {
  564. int res, offset;
  565. offset = fdt_node_offset_by_prop_value(blob, -1, "status",
  566. "disabled", 9);
  567. if (offset < 0)
  568. break;
  569. res = fdt_del_node(blob, offset);
  570. if (res < 0)
  571. return res;
  572. }
  573. return 0;
  574. }
  575. int ft_board_setup(void *blob, struct bd_info *bd)
  576. {
  577. int node, phandle, res;
  578. /*
  579. * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are
  580. * connected, enable the PCIe node.
  581. */
  582. if (pci || usb || passpci) {
  583. node = fdt_path_offset(blob, PCIE_PATH);
  584. if (node < 0)
  585. return node;
  586. res = fdt_setprop_string(blob, node, "status", "okay");
  587. if (res < 0)
  588. return res;
  589. /* Fix PCIe regions for devices with 4 GB RAM */
  590. res = a3700_fdt_fix_pcie_regions(blob);
  591. if (res < 0)
  592. return res;
  593. }
  594. /*
  595. * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected,
  596. * enable the eth1 node and setup the switches.
  597. */
  598. if (peridot || topaz) {
  599. int i;
  600. res = enable_by_path(blob, ETH1_PATH);
  601. if (res < 0)
  602. return res;
  603. for (i = 0; i < peridot + topaz; ++i) {
  604. res = setup_switch(blob, i);
  605. if (res < 0)
  606. return res;
  607. }
  608. }
  609. /*
  610. * If MOX D (SFP cage module) is connected, enable the SFP node and eth1
  611. * node. If there is no Peridot switch between MOX A and MOX D, add link
  612. * to the SFP node to eth1 node.
  613. * Also enable and configure SFP GPIO controller node.
  614. */
  615. if (sfp) {
  616. res = enable_by_path(blob, SFP_PATH);
  617. if (res < 0)
  618. return res;
  619. res = enable_by_path(blob, ETH1_PATH);
  620. if (res < 0)
  621. return res;
  622. if (!peridot) {
  623. phandle = phandle_by_path(blob, SFP_PATH);
  624. if (phandle < 0)
  625. return res;
  626. node = node_by_path(blob, ETH1_PATH);
  627. if (node < 0)
  628. return node;
  629. res = fdt_setprop_u32(blob, node, "sfp", phandle);
  630. if (res < 0)
  631. return res;
  632. res = fdt_setprop_string(blob, node, "phy-mode",
  633. "sgmii");
  634. if (res < 0)
  635. return res;
  636. }
  637. res = enable_by_path(blob, SFP_GPIO_PATH);
  638. if (res < 0)
  639. return res;
  640. if (sfp_pos) {
  641. char newname[16];
  642. /* moxtet-sfp is on non-zero position, change default */
  643. node = node_by_path(blob, SFP_GPIO_PATH);
  644. if (node < 0)
  645. return node;
  646. res = fdt_setprop_u32(blob, node, "reg", sfp_pos);
  647. if (res < 0)
  648. return res;
  649. sprintf(newname, "gpio@%x", sfp_pos);
  650. res = fdt_set_name(blob, node, newname);
  651. if (res < 0)
  652. return res;
  653. }
  654. }
  655. fdt_fixup_ethernet(blob);
  656. /* Finally remove disabled nodes, as per Rob Herring's request. */
  657. remove_disabled_nodes(blob);
  658. return 0;
  659. }
  660. #endif