1// SPDX-License-Identifier:    GPL-2.0
2/*
3 * Copyright (C) 2018 Marvell International Ltd.
4 *
5 * https://spdx.org/licenses
6 */
7
8#include <dm.h>
9#include <malloc.h>
10#include <errno.h>
11#include <env.h>
12#include <init.h>
13#include <log.h>
14#include <netdev.h>
15#include <pci_ids.h>
16#include <asm/global_data.h>
17#include <asm/io.h>
18#include <linux/compiler.h>
19#include <linux/libfdt.h>
20#include <fdt_support.h>
21#include <asm/arch/smc.h>
22#include <asm/arch/soc.h>
23#include <asm/arch/board.h>
24#include <dm/util.h>
25
26DECLARE_GLOBAL_DATA_PTR;
27
28void octeontx_cleanup_ethaddr(void)
29{
30	char ename[32];
31
32	for (int i = 0; i < 20; i++) {
33		sprintf(ename, i ? "eth%daddr" : "ethaddr", i);
34		if (env_get(ename))
35			env_set(ename, NULL);
36	}
37}
38
39int octeontx_board_has_pmp(void)
40{
41	return (otx_is_board("sff8104") || otx_is_board("nas8104"));
42}
43
44int board_early_init_r(void)
45{
46	pci_init();
47	return 0;
48}
49
50int board_init(void)
51{
52	if (IS_ENABLED(CONFIG_NET_OCTEONTX))
53		fdt_parse_phy_info();
54
55	return 0;
56}
57
58int timer_init(void)
59{
60	return 0;
61}
62
63int dram_init(void)
64{
65	gd->ram_size = smc_dram_size(0);
66	gd->ram_size -= CFG_SYS_SDRAM_BASE;
67	mem_map_fill();
68
69	return 0;
70}
71
72void board_late_probe_devices(void)
73{
74	struct udevice *dev;
75	int err, bgx_cnt, i;
76
77	/* Probe MAC(BGX) and NIC PF devices before Network stack init */
78	bgx_cnt = otx_is_soc(CN81XX) ? 2 : 4;
79	for (i = 0; i < bgx_cnt; i++) {
80		err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
81					 PCI_DEVICE_ID_CAVIUM_BGX, i, &dev);
82		if (err)
83			debug("%s BGX%d device not found\n", __func__, i);
84	}
85	if (otx_is_soc(CN81XX)) {
86		err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
87					 PCI_DEVICE_ID_CAVIUM_RGX, 0, &dev);
88		if (err)
89			debug("%s RGX device not found\n", __func__);
90	}
91	err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
92				 PCI_DEVICE_ID_CAVIUM_NIC, 0, &dev);
93	if (err)
94		debug("NIC PF device not found\n");
95}
96
97/**
98 * Board late initialization routine.
99 */
100int board_late_init(void)
101{
102	char boardname[32];
103	char boardserial[150], boardrev[150];
104	bool save_env = false;
105	const char *str;
106
107	/*
108	 * Try to cleanup ethaddr env variables, this is needed
109	 * as with each boot, configuration of network interfaces can change.
110	 */
111	octeontx_cleanup_ethaddr();
112
113	snprintf(boardname, sizeof(boardname), "%s> ", fdt_get_board_model());
114	env_set("prompt", boardname);
115
116	set_working_fdt_addr(env_get_hex("fdtcontroladdr", fdt_base_addr));
117
118	str = fdt_get_board_revision();
119	if (str) {
120		snprintf(boardrev, sizeof(boardrev), "%s", str);
121		if (env_get("boardrev") &&
122		    strcmp(boardrev, env_get("boardrev")))
123			save_env = true;
124		env_set("boardrev", boardrev);
125	}
126
127	str = fdt_get_board_serial();
128	if (str) {
129		snprintf(boardserial, sizeof(boardserial), "%s", str);
130		if (env_get("serial#") &&
131		    strcmp(boardserial, env_get("serial#")))
132			save_env = true;
133		env_set("serial#", boardserial);
134	}
135
136	if (IS_ENABLED(CONFIG_NET_OCTEONTX))
137		board_late_probe_devices();
138
139	if (save_env)
140		env_save();
141
142	return 0;
143}
144
145/*
146 * Invoked before relocation, so limit to stack variables.
147 */
148int checkboard(void)
149{
150	printf("Board: %s\n", fdt_get_board_model());
151
152	return 0;
153}
154