1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2021-2022 Stefan Roese <sr@denx.de>
4 */
5
6#include <cyclic.h>
7#include <dm.h>
8#include <event.h>
9#include <ram.h>
10#include <time.h>
11#include <asm/gpio.h>
12
13#include <mach/octeon_ddr.h>
14#include <mach/cvmx-qlm.h>
15#include <mach/octeon_qlm.h>
16#include <mach/octeon_fdt.h>
17#include <mach/cvmx-helper.h>
18#include <mach/cvmx-helper-cfg.h>
19#include <mach/cvmx-helper-util.h>
20#include <mach/cvmx-bgxx-defs.h>
21#include <mach/cvmx-dtx-defs.h>
22
23#include "board_ddr.h"
24
25/**
26 * cvmx_spem#_cfg_rd
27 *
28 * This register allows read access to the configuration in the PCIe core.
29 *
30 */
31union cvmx_spemx_cfg_rd {
32	u64 u64;
33	struct cvmx_spemx_cfg_rd_s {
34		u64 data                         : 32;
35		u64 addr                         : 32;
36	} s;
37	struct cvmx_spemx_cfg_rd_s            cn73xx;
38};
39
40/**
41 * cvmx_spem#_cfg_wr
42 *
43 * This register allows write access to the configuration in the PCIe core.
44 *
45 */
46union cvmx_spemx_cfg_wr {
47	u64 u64;
48	struct cvmx_spemx_cfg_wr_s {
49		u64 data                         : 32;
50		u64 addr                         : 32;
51	} s;
52	struct cvmx_spemx_cfg_wr_s            cn73xx;
53};
54
55/**
56 * cvmx_spem#_flr_pf_stopreq
57 *
58 * PF function level reset stop outbound requests register.
59 * Hardware automatically sets the STOPREQ bit for the PF when it enters a
60 * function level reset (FLR).  Software is responsible for clearing the STOPREQ
61 * bit but must not do so prior to hardware taking down the FLR, which could be
62 * as long as 100ms.  It may be appropriate for software to wait longer before clearing
63 * STOPREQ, software may need to drain deep DPI queues for example.
64 * Whenever SPEM receives a PF or child VF request mastered by CNXXXX over S2M (i.e. P or NP),
65 * when STOPREQ is set for the function, SPEM will discard the outgoing request
66 * before sending it to the PCIe core.  If a NP, SPEM will schedule an immediate
67 * SWI_RSP_ERROR completion for the request - no timeout is required.
68 * In both cases, SPEM()_DBG_PF()_INFO[P()_BMD_E] will be set and a error
69 * interrupt is generated.
70 *
71 * STOPREQ mimics the behavior of PCIEEP()_CFG001[ME] for outbound requests that will
72 * master the PCIe bus (P and NP).
73 *
74 * STOPREQ will have no effect on completions returned by CNXXXX over the S2M,
75 * nor on M2S traffic.
76 *
77 * When a PF()_STOPREQ is set, none of the associated
78 * PEM()_FLR_PF()_VF_STOPREQ[VF_STOPREQ] will be set.
79 *
80 * STOPREQ is reset when the MAC is reset, and is not reset after a chip soft reset.
81 */
82union cvmx_spemx_flr_pf_stopreq {
83	u64 u64;
84	struct cvmx_spemx_flr_pf_stopreq_s {
85		u64 reserved_3_63                : 61;
86		u64 pf2_stopreq                  : 1;
87		u64 pf1_stopreq                  : 1;
88		u64 pf0_stopreq                  : 1;
89	} s;
90	struct cvmx_spemx_flr_pf_stopreq_s    cn73xx;
91};
92
93#define CVMX_SPEMX_CFG_WR(offset)		0x00011800C0000028ull
94#define CVMX_SPEMX_CFG_RD(offset)		0x00011800C0000030ull
95#define CVMX_SPEMX_FLR_PF_STOPREQ(offset)	0x00011800C0000218ull
96
97#define DTX_SELECT_LTSSM		0x0
98#define DTX_SELECT_LTSSM_ENA		0x3ff
99#define LTSSM_L0			0x11
100
101#define NIC23_DEF_DRAM_FREQ		800
102
103static u32 pci_cfgspace_reg0[2] = { 0, 0 };
104
105static u8 octeon_nic23_cfg0_spd_values[512] = {
106	OCTEON_NIC23_CFG0_SPD_VALUES
107};
108
109static struct ddr_conf board_ddr_conf[] = {
110	 OCTEON_NIC23_DDR_CONFIGURATION
111};
112
113struct ddr_conf *octeon_ddr_conf_table_get(int *count, int *def_ddr_freq)
114{
115	*count = ARRAY_SIZE(board_ddr_conf);
116	*def_ddr_freq = NIC23_DEF_DRAM_FREQ;
117
118	return board_ddr_conf;
119}
120
121int board_fix_fdt(void *fdt)
122{
123	u32 range_data[5 * 8];
124	bool rev4;
125	int node;
126	int rc;
127
128	/*
129	 * ToDo:
130	 * Read rev4 info from EEPROM or where the original U-Boot does
131	 * and don't hard-code it here.
132	 */
133	rev4 = true;
134
135	debug("%s() rev4: %s\n", __func__, rev4 ? "true" : "false");
136	/* Patch the PHY configuration based on board revision */
137	rc = octeon_fdt_patch_rename(fdt,
138				     rev4 ? "4,nor-flash" : "4,no-nor-flash",
139				     "cavium,board-trim", false, NULL, NULL);
140	if (!rev4) {
141		/* Modify the ranges for CS 0 */
142		node = fdt_node_offset_by_compatible(fdt, -1,
143						     "cavium,octeon-3860-bootbus");
144		if (node < 0) {
145			printf("%s: Error: cannot find boot bus in device tree!\n",
146			       __func__);
147			return -1;
148		}
149
150		rc = fdtdec_get_int_array(fdt, node, "ranges",
151					  range_data, 5 * 8);
152		if (rc) {
153			printf("%s: Error reading ranges from boot bus FDT\n",
154			       __func__);
155			return -1;
156		}
157		range_data[2] = cpu_to_fdt32(0x10000);
158		range_data[3] = 0;
159		range_data[4] = 0;
160		rc = fdt_setprop(fdt, node, "ranges", range_data,
161				 sizeof(range_data));
162		if (rc) {
163			printf("%s: Error updating boot bus ranges in fdt\n",
164			       __func__);
165		}
166	}
167	return rc;
168}
169
170int board_early_init_f(void)
171{
172	struct gpio_desc gpio = {};
173	ofnode node;
174
175	/* Initial GPIO configuration */
176
177	/* GPIO 7: Vitesse reset */
178	node = ofnode_by_compatible(ofnode_null(), "vitesse,vsc7224");
179	if (ofnode_valid(node)) {
180		gpio_request_by_name_nodev(node, "los", 0, &gpio, GPIOD_IS_IN);
181		dm_gpio_free(gpio.dev, &gpio);
182		gpio_request_by_name_nodev(node, "reset", 0, &gpio,
183					   GPIOD_IS_OUT);
184		if (dm_gpio_is_valid(&gpio)) {
185			/* Vitesse reset */
186			debug("%s: Setting GPIO 7 to 1\n", __func__);
187			dm_gpio_set_value(&gpio, 1);
188		}
189		dm_gpio_free(gpio.dev, &gpio);
190	}
191
192	/* SFP+ transmitters */
193	ofnode_for_each_compatible_node(node, "ethernet,sfp-slot") {
194		gpio_request_by_name_nodev(node, "tx_disable", 0,
195					   &gpio, GPIOD_IS_OUT);
196		if (dm_gpio_is_valid(&gpio)) {
197			debug("%s: Setting GPIO %d to 1\n", __func__,
198			      gpio.offset);
199			dm_gpio_set_value(&gpio, 1);
200		}
201		dm_gpio_free(gpio.dev, &gpio);
202		gpio_request_by_name_nodev(node, "mod_abs", 0, &gpio,
203					   GPIOD_IS_IN);
204		dm_gpio_free(gpio.dev, &gpio);
205		gpio_request_by_name_nodev(node, "tx_error", 0, &gpio,
206					   GPIOD_IS_IN);
207		dm_gpio_free(gpio.dev, &gpio);
208		gpio_request_by_name_nodev(node, "rx_los", 0, &gpio,
209					   GPIOD_IS_IN);
210		dm_gpio_free(gpio.dev, &gpio);
211	}
212
213	return 0;
214}
215
216void board_configure_qlms(void)
217{
218	octeon_configure_qlm(4, 3000, CVMX_QLM_MODE_SATA_2X1, 0, 0, 0, 0);
219	octeon_configure_qlm(5, 103125, CVMX_QLM_MODE_XFI_1X2, 0, 0, 2, 0);
220	/* Apply amplitude tuning to 10G interface */
221	octeon_qlm_tune_v3(0, 4, 3000, -1, -1, 7, -1);
222	octeon_qlm_tune_v3(0, 5, 103125, 0x19, 0x0, -1, -1);
223	octeon_qlm_set_channel_v3(0, 5, 0);
224	octeon_qlm_dfe_disable(0, 5, -1, 103125, CVMX_QLM_MODE_XFI_1X2);
225	debug("QLM 4 reference clock: %d\n"
226	      "DLM 5 reference clock: %d\n",
227	      cvmx_qlm_measure_clock(4), cvmx_qlm_measure_clock(5));
228}
229
230/**
231 * If there is a PF FLR then the PCI EEPROM is not re-read.  In this case
232 * we need to re-program the vendor and device ID immediately after hardware
233 * completes FLR.
234 *
235 * PCI spec requires FLR to be completed within 100ms.  The user who triggered
236 * FLR expects hardware to finish FLR within 100ms, otherwise the user will
237 * end up reading DEVICE_ID incorrectly from the reset value.
238 * CN23XX exits FLR at any point between 66 and 99ms, so U-Boot has to wait
239 * 99ms to let hardware finish its part, then finish reprogramming the
240 * correct device ID before the end of 100ms.
241 *
242 * Note: this solution only works properly when there is no other activity
243 * within U-Boot for 100ms from the time FLR is triggered.
244 *
245 * This function gets called every 100usec.  If FLR happens during any
246 * other activity like bootloader/image update then it is possible that
247 * this function does not get called for more than the FLR period which will
248 * cause the PF device ID restore to happen after whoever initiated the FLR to
249 * read the incorrect device ID 0x9700 (reset value) instead of 0x9702
250 * (restored value).
251 */
252static void octeon_board_restore_pf(void *ctx)
253{
254	union cvmx_spemx_flr_pf_stopreq stopreq;
255	static bool start_initialized[2] = {false, false};
256	bool pf0_flag, pf1_flag;
257	u64 ltssm_bits;
258	const u64 pf_flr_wait_usecs = 99700;
259	u64 elapsed_usecs;
260	union cvmx_spemx_cfg_wr cfg_wr;
261	union cvmx_spemx_cfg_rd cfg_rd;
262	static u64 start_us[2];
263	int pf_num;
264
265	csr_wr(CVMX_DTX_SPEM_SELX(0), DTX_SELECT_LTSSM);
266	csr_rd(CVMX_DTX_SPEM_SELX(0));
267	csr_wr(CVMX_DTX_SPEM_ENAX(0), DTX_SELECT_LTSSM_ENA);
268	csr_rd(CVMX_DTX_SPEM_ENAX(0));
269	ltssm_bits = csr_rd(CVMX_DTX_SPEM_DATX(0));
270	if (((ltssm_bits >> 3) & 0x3f) != LTSSM_L0)
271		return;
272
273	stopreq.u64 = csr_rd(CVMX_SPEMX_FLR_PF_STOPREQ(0));
274	pf0_flag = stopreq.s.pf0_stopreq;
275	pf1_flag = stopreq.s.pf1_stopreq;
276	/* See if PF interrupt happened */
277	if (!(pf0_flag || pf1_flag))
278		return;
279
280	if (pf0_flag && !start_initialized[0]) {
281		start_initialized[0] = true;
282		start_us[0] = get_timer_us(0);
283	}
284
285	/* Store programmed PCIe DevID SPEM0 PF0 */
286	if (pf0_flag && !pci_cfgspace_reg0[0]) {
287		cfg_rd.s.addr = (0 << 24) | 0x0;
288		csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64);
289		cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0));
290		pci_cfgspace_reg0[0] = cfg_rd.s.data;
291	}
292
293	if (pf1_flag && !start_initialized[1]) {
294		start_initialized[1] = true;
295		start_us[1] = get_timer_us(0);
296	}
297
298	/* Store programmed PCIe DevID SPEM0 PF1 */
299	if (pf1_flag && !pci_cfgspace_reg0[1]) {
300		cfg_rd.s.addr = (1 << 24) | 0x0;
301		csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64);
302		cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0));
303		pci_cfgspace_reg0[1] = cfg_rd.s.data;
304	}
305
306	/* For PF, rewrite pci config space reg 0 */
307	for (pf_num = 0; pf_num < 2; pf_num++) {
308		if (!start_initialized[pf_num])
309			continue;
310
311		elapsed_usecs = get_timer_us(0) - start_us[pf_num];
312
313		if (elapsed_usecs > pf_flr_wait_usecs) {
314			/* Here, our measured FLR duration has passed;
315			 * check if device ID has been reset,
316			 * which indicates FLR completion (per MA team).
317			 */
318			cfg_rd.s.addr = (pf_num << 24) | 0x0;
319			csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64);
320			cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0));
321			/* if DevID has NOT been reset, FLR is not yet
322			 * complete
323			 */
324			if (cfg_rd.s.data != pci_cfgspace_reg0[pf_num]) {
325				stopreq.s.pf0_stopreq = (pf_num == 0) ? 1 : 0;
326				stopreq.s.pf1_stopreq = (pf_num == 1) ? 1 : 0;
327				csr_wr(CVMX_SPEMX_FLR_PF_STOPREQ(0), stopreq.u64);
328
329				cfg_wr.u64 = 0;
330				cfg_wr.s.addr = (pf_num << 24) | 0;
331				cfg_wr.s.data = pci_cfgspace_reg0[pf_num];
332				csr_wr(CVMX_SPEMX_CFG_WR(0), cfg_wr.u64);
333				start_initialized[pf_num] = false;
334			}
335		}
336	}
337}
338
339int board_late_init(void)
340{
341	struct cyclic_info *cyclic;
342	struct gpio_desc gpio = {};
343	ofnode node;
344
345	/* Turn on SFP+ transmitters */
346	ofnode_for_each_compatible_node(node, "ethernet,sfp-slot") {
347		gpio_request_by_name_nodev(node, "tx_disable", 0,
348					   &gpio, GPIOD_IS_OUT);
349		if (dm_gpio_is_valid(&gpio)) {
350			debug("%s: Setting GPIO %d to 0\n", __func__,
351			      gpio.offset);
352			dm_gpio_set_value(&gpio, 0);
353		}
354		dm_gpio_free(gpio.dev, &gpio);
355	}
356
357	board_configure_qlms();
358
359	/* Register cyclic function for PCIe FLR fixup */
360	cyclic = cyclic_register(octeon_board_restore_pf, 100,
361				 "pcie_flr_fix", NULL);
362	if (!cyclic)
363		printf("Registering of cyclic function failed\n");
364
365	return 0;
366}
367
368static int last_stage_init(void)
369{
370	struct gpio_desc gpio = {};
371	ofnode node;
372
373	node = ofnode_by_compatible(ofnode_null(), "vitesse,vsc7224");
374	if (!ofnode_valid(node)) {
375		printf("Vitesse SPF DT node not found!");
376		return 0;
377	}
378
379	gpio_request_by_name_nodev(node, "reset", 0, &gpio, GPIOD_IS_OUT);
380	if (dm_gpio_is_valid(&gpio)) {
381		/* Take Vitesse retimer out of reset */
382		debug("%s: Setting GPIO 7 to 0\n", __func__);
383		dm_gpio_set_value(&gpio, 0);
384		mdelay(50);
385	}
386	dm_gpio_free(gpio.dev, &gpio);
387
388	return 0;
389}
390EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init);
391