mb/google/brya/var/orisa: Update Type C DisplayPort HPD Configuration
[coreboot2.git] / src / mainboard / google / brya / variants / agah / variant.c
blob03720332bd0b3d606de1c79e1eb1b2fa1ee2d99f
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi.h>
4 #include <acpi/acpigen.h>
5 #include <baseboard/variants.h>
6 #include <boardid.h>
7 #include <delay.h>
8 #include <device/pci.h>
9 #include <gpio.h>
10 #include <static.h>
11 #include <timer.h>
12 #include <types.h>
14 #define GPU_1V8_PWR_EN GPP_F12
15 #define GPU_1V8_PG GPP_E20
16 #define NV33_PWR_EN GPP_A21
17 #define NV33_PG GPP_A22
18 #define NVVDD_PWR_EN GPP_E0
19 #define NVVDD_PG GPP_E3
20 #define PEXVDD_PWR_EN GPP_E10
21 #define PEXVDD_PG GPP_E17
22 #define FBVDD_PWR_EN GPP_A19
23 #define FBVDD_PG GPP_E4
24 #define GPU_PERST_L GPP_B3
25 #define GPU_ALLRAILS_PG GPP_E5
27 #define DEFAULT_PG_TIMEOUT_US 20000
29 #define VGAR_BYTE_OFFSET 5
31 /* Maximum size of PCI config space to save. */
32 #define GPU_CONFIG_SAVE_SPACE_BYTES 0x100
34 static bool gpu_powered_on;
36 struct power_rail_sequence {
37 const char *name;
39 /* This is the GPIO (output) connected to the VR's enable pin. */
40 gpio_t pwr_en_gpio;
41 bool pwr_en_active_low;
43 /* This is the GPIO (input) connected to the VR's power-good pin. */
44 gpio_t pg_gpio;
46 /* Delay after sequencing this rail. */
47 unsigned int delay_ms;
50 /* In GCOFF exit order (i.e., power-on order) */
51 static struct power_rail_sequence gpu_on_seq[] = {
52 { "GPU 1.8V", GPU_1V8_PWR_EN, false, GPU_1V8_PG, },
53 { "NV3_3", NV33_PWR_EN, false, NV33_PG, },
54 { "NVVDD+MSVDD", NVVDD_PWR_EN, false, NVVDD_PG, },
55 { "PEXVDD", PEXVDD_PWR_EN, false, PEXVDD_PG, },
56 { "FBVDD", FBVDD_PWR_EN, true, FBVDD_PG, },
59 /* In GCOFF entry order (i.e., power-off order) */
60 static struct power_rail_sequence gpu_off_seq[] = {
61 { "FBVDD", FBVDD_PWR_EN, true, FBVDD_PG, 0,},
62 { "PEXVDD", PEXVDD_PWR_EN, false, PEXVDD_PG, 10,},
63 { "NVVDD+MSVDD", NVVDD_PWR_EN, false, NVVDD_PG, 2,},
64 { "NV3_3", NV33_PWR_EN, false, NV33_PG, 4,},
65 { "GPU 1.8V", GPU_1V8_PWR_EN, false, GPU_1V8_PG, 0,},
68 enum rail_state {
69 RAIL_OFF = 0,
70 RAIL_ON = 1,
73 /* Assert the VR's enable pin, and wait until the VR's power-good is asserted. */
74 static bool sequence_rail(const struct power_rail_sequence *seq, enum rail_state state)
76 enum rail_state pwr_en_state = state;
77 bool result;
79 if (seq->pwr_en_active_low)
80 pwr_en_state = !pwr_en_state;
82 gpio_output(seq->pwr_en_gpio, pwr_en_state);
83 result = wait_us(DEFAULT_PG_TIMEOUT_US, gpio_get(seq->pg_gpio) == state) >= 0;
84 if (seq->delay_ms)
85 mdelay(seq->delay_ms);
87 return result;
90 static void dgpu_power_sequence_off(void)
92 /* Assert reset and clear power-good */
93 gpio_output(GPU_PERST_L, 0);
95 /* Inform the GPU that the power is no longer good. */
96 gpio_output(GPU_ALLRAILS_PG, 0);
98 for (size_t i = 0; i < ARRAY_SIZE(gpu_off_seq); i++) {
99 if (!sequence_rail(&gpu_off_seq[i], RAIL_OFF)) {
100 printk(BIOS_ERR, "Failed to disable %s rail, continuing!\n",
101 gpu_off_seq[i].name);
106 static void dgpu_power_sequence_on(void)
108 /* Assert PERST# */
109 gpio_output(GPU_PERST_L, 0);
111 for (size_t i = 0; i < ARRAY_SIZE(gpu_on_seq); i++) {
112 if (!sequence_rail(&gpu_on_seq[i], RAIL_ON)) {
113 printk(BIOS_ERR, "Failed to enable %s rail, sequencing back down!\n",
114 gpu_on_seq[i].name);
116 /* If an error occurred, then perform the power-off sequence and
117 return early to avoid setting GPU_ALLRAILS_PG and PERST_L. */
118 dgpu_power_sequence_off();
119 return;
123 /* Set power-good and release PERST# */
124 gpio_output(GPU_ALLRAILS_PG, 1);
125 mdelay(1);
126 gpio_output(GPU_PERST_L, 1);
128 printk(BIOS_INFO, "Sequenced GPU successfully\n");
129 mdelay(1);
131 gpu_powered_on = true;
134 void variant_init(void)
136 if (acpi_is_wakeup_s3())
137 return;
139 /* For board revs 3 and later, the power good pin for the
140 NVVDD VR moved from GPP_E16 to GPP_E3, and the GPU_1V8 enable
141 pin moved from GPP_E18 to GPP_F12, so patch up the table
142 for old board revs. */
143 if (board_id() < 3) {
144 const struct pad_config board_rev_2_gpios[] = {
145 PAD_NC(GPP_E3, NONE),
146 PAD_CFG_GPO(GPP_E18, 0, PLTRST),
147 PAD_CFG_GPI(GPP_E16, NONE, PLTRST),
148 PAD_NC(GPP_F12, NONE),
150 gpio_configure_pads(board_rev_2_gpios, ARRAY_SIZE(board_rev_2_gpios));
152 gpu_on_seq[2].pg_gpio = GPP_E16;
153 gpu_off_seq[2].pg_gpio = GPP_E16;
155 gpu_on_seq[0].pwr_en_gpio = GPP_E18;
156 gpu_off_seq[4].pwr_en_gpio = GPP_E18;
157 } else {
158 const struct pad_config board_rev_3_gpios[] = {
159 PAD_CFG_GPI(GPP_E3, NONE, PLTRST),
160 PAD_NC(GPP_E18, NONE),
161 PAD_NC(GPP_E16, NONE),
162 PAD_CFG_GPO(GPP_F12, 0, PLTRST),
164 gpio_configure_pads(board_rev_3_gpios, ARRAY_SIZE(board_rev_3_gpios));
167 dgpu_power_sequence_on();
171 * For board revs 3 and later, two pins moved:
172 * - The PG pin for the NVVDD VR moved from GPP_E16 to GPP_E3.
173 * - The enable pin for the GPU_1V8 VR moved from GPP_E18 to GPP_F12
175 * To accommodate this, the DSDT contains two Names that this code
176 * will write the correct GPIO # to depending on the board rev, and
177 * we'll use that instead.
179 void variant_fill_ssdt(const struct device *dev)
181 const int nvvdd_pg_gpio = board_id() < 3 ? GPP_E16 : GPP_E3;
182 const int gpu_1v8_en_gpio = board_id() < 3 ? GPP_E18 : GPP_F12;
183 acpigen_write_scope("\\_SB.PCI0.PEG0.PEGP");
184 acpigen_write_method("_INI", 0);
185 acpigen_write_store_int_to_namestr(nvvdd_pg_gpio, "NVPG");
186 acpigen_write_store_int_to_namestr(gpu_1v8_en_gpio, "GPEN");
187 acpigen_write_method_end();
188 acpigen_write_scope_end();
191 void variant_finalize(void)
194 * Currently the `pch_pirq_init()` function in lpc_lib.c will program
195 * PIRQ IRQs for all PCI devices discovered during enumeration. This may
196 * not be correct for all devices, and causes strange behavior with the
197 * Nvidia dGPU; it will start out with IRQ 11 and then after a
198 * suspend/resume cycle, it will get programmed back to 16, so the Linux
199 * kernel must be doing some IRQ sanitization at some point. To fix
200 * this anomaly, explicitly program the IRQ to 16 (which we know is what
201 * IRQ it will eventually take).
203 const struct device *dgpu = DEV_PTR(dgpu);
204 pci_write_config8(dgpu, PCI_INTERRUPT_LINE, 16);