blob: abfec24a7fa233871a67400e5e77cd6fa7485bef [file] [log] [blame]
Marc Olberding801bc902025-08-27 12:55:42 -07001// SPDX-License-Identifier: Apache-2.0
Patrick Williams4a943522025-10-09 20:34:38 -04002// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Marc Olberding801bc902025-08-27 12:55:42 -07003
4#include "gpio.hpp"
5#include "i2c.hpp"
6#include "utilities.hpp"
7
8#include <systemd/sd-daemon.h>
9
10#include <chrono>
11#include <filesystem>
12#include <iostream>
13
14using namespace std::chrono_literals;
15
16namespace nvidia
17{
18
19void init_p2020_gpu_card()
20{
21 std::cerr << "Initializing GPU card...\n";
22
23 // Init the P2020 gpio expander
24 i2c::new_device(14, 0x20, "pca6408");
25
26 // Wait for device to be created
27 const auto* device_path = "/sys/bus/i2c/devices/14-0020";
28 wait_for_path_to_exist(device_path, 1000ms);
29
30 // Find the GPIO chip number
31 int gpiochipint = gpio::find_chip_idx_from_dir(device_path);
32 if (gpiochipint < 0)
33 {
34 return;
35 }
36 // Set MCU in recovery
37 gpio::set_raw(gpiochipint, 3, 1);
38
39 // Reset MCU
40 gpio::set_raw(gpiochipint, 4, 0);
41 gpio::set_raw(gpiochipint, 4, 1);
42
43 // Switch MUX to MCU
44 gpio::set_raw(gpiochipint, 5, 1);
45}
46
47bool hmc_is_present()
48{
49 std::error_code ec;
50 bool exists = std::filesystem::exists("/sys/bus/i2c/devices/9-0074", ec);
51 if (ec)
52 {
53 exists = false;
54 }
55 if (exists)
56 {
57 std::cerr << "HMC present in platform";
58 }
59 else
60 {
61 std::cerr << "HMC not present in platform";
62 }
63 return exists;
64}
65
66int init_nvidia_gb200(bool has_p2020)
67{
68 // Reset USB hubs
69 gpio::set("USB_HUB_RESET_L-O", 0, 10000ms);
70 bool hmc_present = hmc_is_present();
71 if (!hmc_present)
72 {
73 gpio::set("SEC_USB2_HUB_RST_L-O", 0, 10000ms);
74 }
75
76 sleep_milliseconds(100ms);
77 if (!hmc_present)
78 {
79 gpio::set("SEC_USB2_HUB_RST_L-O", 1);
80 }
81 // Write SGPIO_BMC_EN-O=1 to correctly set mux to send SGPIO signals to
82 // FPGA
83 gpio::set("SGPIO_BMC_EN-O", 1);
84
85 // Write the bit for BMC without HMC
86 gpio::set("HMC_BMC_DETECT-O", static_cast<int>(!hmc_present), 30000ms);
87
88 // Set BMC_EROT_FPGA_SPI_MUX_SEL-O = 1 to enable FPGA to access its EROT
89 gpio::set("BMC_EROT_FPGA_SPI_MUX_SEL-O", 1);
90
91 // Enable 12V
92 gpio::set("BMC_12V_CTRL-O", 1, 10000ms);
93
94 gpio::set("PWR_BRAKE_L-O", 1);
95 gpio::set("SHDN_REQ_L-O", 1);
96 gpio::set("SHDN_FORCE_L-O", 1);
97 // Hold in reset (asserted) after standby power enabled
98 gpio::set("SYS_RST_IN_L-O", 0);
99
100 gpio::Event fpga_ready_wait = gpio::Event("FPGA_READY_BMC-I", 1);
101 gpio::Event sec_erot_fpga_rst = gpio::Event("SEC_FPGA_READY_BMC-I", 1);
102
103 // Release FPGA EROT from reset
104 gpio::set("EROT_FPGA_RST_L-O", 1);
105 gpio::set("SEC_EROT_FPGA_RST_L-O", 1);
106
107 sleep_milliseconds(100ms);
108
109 gpio::set("FPGA_RST_L-O", 1);
110
111 if (fpga_ready_wait.wait() != gpio::EventResult::Asserted)
112 {
113 std::cerr << "FPGA_READY_BMC-I failed to assert\n";
114 // return EXIT_FAILURE;
115 }
116
117 if (sec_erot_fpga_rst.wait() != gpio::EventResult::Asserted)
118 {
119 std::cerr << "SEC_FPGA_READY_BMC-I failed to assert\n";
120 // return EXIT_FAILURE;
121 }
122
123 // ReInitialize the FPGA connected I2C buses to unstick them and let
124 // FruDevice know it can scan for FRUs I2c bus 1
125 i2c::rebind_controller("1e78a100");
126 // I2c bus 2
127 i2c::rebind_controller("1e78a180");
128
129 // Set sgpio signals
130 gpio::set("RUN_POWER_EN-O", 1);
131 gpio::set("SYS_RST_IN_L-O", 1);
132 gpio::set("GLOBAL_WP_BMC-O", 0);
133
134 gpio::set("BMC_READY-O", 1);
135
136 if (has_p2020)
137 {
138 init_p2020_gpu_card();
139 }
140
141 gpio::set("USB_HUB_RESET_L-O", 1);
142 if (!hmc_present)
143 {
144 gpio::set("SEC_USB2_HUB_RST_L-O", 1);
145 }
146
147 sd_notify(0, "READY=1");
148 std::cerr << "Platform init complete\n";
149 pause();
150 std::cerr << "Releasing platform\n";
151
152 return EXIT_SUCCESS;
153}
154
155int init_gb200_base()
156{
157 return init_nvidia_gb200(false);
158}
159
160int init_gb200_with_p2020()
161{
162 return init_nvidia_gb200(true);
163}
164} // namespace nvidia