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