1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <clk.h>
9 #include <spi.h>
10 #include <linux/string.h>
11 
12 #ifdef CONFIG_WDT_ARMADA_3720
13 #include <wdt.h>
14 #endif
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 #ifdef CONFIG_WDT_ARMADA_3720
19 static struct udevice *watchdog_dev;
20 
21 void watchdog_reset(void)
22 {
23 	static ulong next_reset;
24 	ulong now;
25 
26 	if (!watchdog_dev)
27 		return;
28 
29 	now = timer_get_us();
30 
31 	/* Do not reset the watchdog too often */
32 	if (now > next_reset) {
33 		wdt_reset(watchdog_dev);
34 		next_reset = now + 100000;
35 	}
36 }
37 #endif
38 
39 int board_init(void)
40 {
41 	/* address of boot parameters */
42 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
43 
44 #ifdef CONFIG_WDT_ARMADA_3720
45 	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
46 		printf("Cannot find Armada 3720 watchdog!\n");
47 	} else {
48 		printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n");
49 		wdt_start(watchdog_dev, 180000, 0);
50 	}
51 #endif
52 
53 	return 0;
54 }
55 
56 int last_stage_init(void)
57 {
58 	struct spi_slave *slave;
59 	struct udevice *dev;
60 	u8 din[10], dout[10];
61 	int ret, i;
62 	size_t len = 0;
63 	char module_topology[128];
64 
65 	ret = spi_get_bus_and_cs(0, 1, 20000000, SPI_CPHA, "spi_generic_drv",
66 				 "mox-modules@1", &dev, &slave);
67 	if (ret)
68 		goto fail;
69 
70 	ret = spi_claim_bus(slave);
71 	if (ret)
72 		goto fail_free;
73 
74 	memset(din, 0, 10);
75 	memset(dout, 0, 10);
76 
77 	ret = spi_xfer(slave, 80, dout, din, SPI_XFER_ONCE);
78 	if (ret)
79 		goto fail_release;
80 
81 	if (din[0] != 0x00 && din[0] != 0xff)
82 		goto fail_release;
83 
84 	printf("Module Topology:\n");
85 	for (i = 1; i < 10 && din[i] != 0xff; ++i) {
86 		u8 mid = din[i] & 0xf;
87 		size_t mlen;
88 		const char *mname = "";
89 
90 		switch (mid) {
91 		case 0x1:
92 			mname = "sfp-";
93 			printf("% 4i: SFP Module\n", i);
94 			break;
95 		case 0x2:
96 			mname = "pci-";
97 			printf("% 4i: Mini-PCIe Module\n", i);
98 			break;
99 		case 0x3:
100 			mname = "topaz-";
101 			printf("% 4i: Topaz Switch Module\n", i);
102 			break;
103 		default:
104 			printf("% 4i: unknown (ID %i)\n", i, mid);
105 		}
106 
107 		mlen = strlen(mname);
108 		if (len + mlen < sizeof(module_topology)) {
109 			strcpy(module_topology + len, mname);
110 			len += mlen;
111 		}
112 	}
113 	printf("\n");
114 
115 	module_topology[len > 0 ? len - 1 : 0] = '\0';
116 
117 	env_set("module_topology", module_topology);
118 
119 fail_release:
120 	spi_release_bus(slave);
121 fail_free:
122 	spi_free_slave(slave);
123 fail:
124 	if (ret)
125 		printf("Cannot read module topology!\n");
126 	return ret;
127 }
128