1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <acpi/acpigen.h>
5 #include <baseboard/variants.h>
8 #include <device/pci.h>
13 #define GPU_1V8_PWR_EN GPP_F12
14 #define GPU_1V8_PG GPP_E20
15 #define NV33_PWR_EN GPP_A21
16 #define NV33_PG GPP_A22
17 #define NVVDD_PWR_EN GPP_E0
18 #define NVVDD_PG GPP_E3
19 #define PEXVDD_PWR_EN GPP_E10
20 #define PEXVDD_PG GPP_E17
21 #define FBVDD_PWR_EN GPP_A19
22 #define FBVDD_PG GPP_E4
23 #define GPU_PERST_L GPP_B3
24 #define GPU_ALLRAILS_PG GPP_E5
26 #define DEFAULT_PG_TIMEOUT_US 20000
28 #define VGAR_BYTE_OFFSET 5
30 /* Maximum size of PCI config space to save. */
31 #define GPU_CONFIG_SAVE_SPACE_BYTES 0x100
33 static bool gpu_powered_on
;
35 struct power_rail_sequence
{
38 /* This is the GPIO (output) connected to the VR's enable pin. */
40 bool pwr_en_active_low
;
42 /* This is the GPIO (input) connected to the VR's power-good pin. */
45 /* Delay after sequencing this rail. */
46 unsigned int delay_ms
;
49 /* In GCOFF exit order (i.e., power-on order) */
50 static struct power_rail_sequence gpu_on_seq
[] = {
51 { "GPU 1.8V", GPU_1V8_PWR_EN
, false, GPU_1V8_PG
, },
52 { "NV3_3", NV33_PWR_EN
, false, NV33_PG
, },
53 { "NVVDD+MSVDD", NVVDD_PWR_EN
, false, NVVDD_PG
, },
54 { "PEXVDD", PEXVDD_PWR_EN
, false, PEXVDD_PG
, },
55 { "FBVDD", FBVDD_PWR_EN
, true, FBVDD_PG
, },
58 /* In GCOFF entry order (i.e., power-off order) */
59 static struct power_rail_sequence gpu_off_seq
[] = {
60 { "FBVDD", FBVDD_PWR_EN
, true, FBVDD_PG
, 0,},
61 { "PEXVDD", PEXVDD_PWR_EN
, false, PEXVDD_PG
, 10,},
62 { "NVVDD+MSVDD", NVVDD_PWR_EN
, false, NVVDD_PG
, 2,},
63 { "NV3_3", NV33_PWR_EN
, false, NV33_PG
, 4,},
64 { "GPU 1.8V", GPU_1V8_PWR_EN
, false, GPU_1V8_PG
, 0,},
72 /* Assert the VR's enable pin, and wait until the VR's power-good is asserted. */
73 static bool sequence_rail(const struct power_rail_sequence
*seq
, enum rail_state state
)
75 enum rail_state pwr_en_state
= state
;
78 if (seq
->pwr_en_active_low
)
79 pwr_en_state
= !pwr_en_state
;
81 gpio_output(seq
->pwr_en_gpio
, pwr_en_state
);
82 result
= wait_us(DEFAULT_PG_TIMEOUT_US
, gpio_get(seq
->pg_gpio
) == state
) >= 0;
84 mdelay(seq
->delay_ms
);
89 static void dgpu_power_sequence_off(void)
91 /* Assert reset and clear power-good */
92 gpio_output(GPU_PERST_L
, 0);
94 /* Inform the GPU that the power is no longer good. */
95 gpio_output(GPU_ALLRAILS_PG
, 0);
97 for (size_t i
= 0; i
< ARRAY_SIZE(gpu_off_seq
); i
++) {
98 if (!sequence_rail(&gpu_off_seq
[i
], RAIL_OFF
)) {
99 printk(BIOS_ERR
, "Failed to disable %s rail, continuing!\n",
100 gpu_off_seq
[i
].name
);
105 static void dgpu_power_sequence_on(void)
108 gpio_output(GPU_PERST_L
, 0);
110 for (size_t i
= 0; i
< ARRAY_SIZE(gpu_on_seq
); i
++) {
111 if (!sequence_rail(&gpu_on_seq
[i
], RAIL_ON
)) {
112 printk(BIOS_ERR
, "Failed to enable %s rail, sequencing back down!\n",
115 /* If an error occurred, then perform the power-off sequence and
116 return early to avoid setting GPU_ALLRAILS_PG and PERST_L. */
117 dgpu_power_sequence_off();
122 /* Set power-good and release PERST# */
123 gpio_output(GPU_ALLRAILS_PG
, 1);
125 gpio_output(GPU_PERST_L
, 1);
127 printk(BIOS_INFO
, "Sequenced GPU successfully\n");
130 gpu_powered_on
= true;
133 void variant_init(void)
135 if (acpi_is_wakeup_s3())
138 /* For board revs 3 and later, the power good pin for the
139 NVVDD VR moved from GPP_E16 to GPP_E3, and the GPU_1V8 enable
140 pin moved from GPP_E18 to GPP_F12, so patch up the table
141 for old board revs. */
142 if (board_id() < 3) {
143 const struct pad_config board_rev_2_gpios
[] = {
144 PAD_NC(GPP_E3
, NONE
),
145 PAD_CFG_GPO(GPP_E18
, 0, PLTRST
),
146 PAD_CFG_GPI(GPP_E16
, NONE
, PLTRST
),
147 PAD_NC(GPP_F12
, NONE
),
149 gpio_configure_pads(board_rev_2_gpios
, ARRAY_SIZE(board_rev_2_gpios
));
151 gpu_on_seq
[2].pg_gpio
= GPP_E16
;
152 gpu_off_seq
[2].pg_gpio
= GPP_E16
;
154 gpu_on_seq
[0].pwr_en_gpio
= GPP_E18
;
155 gpu_off_seq
[4].pwr_en_gpio
= GPP_E18
;
157 const struct pad_config board_rev_3_gpios
[] = {
158 PAD_CFG_GPI(GPP_E3
, NONE
, PLTRST
),
159 PAD_NC(GPP_E18
, NONE
),
160 PAD_NC(GPP_E16
, NONE
),
161 PAD_CFG_GPO(GPP_F12
, 0, PLTRST
),
163 gpio_configure_pads(board_rev_3_gpios
, ARRAY_SIZE(board_rev_3_gpios
));
166 dgpu_power_sequence_on();
170 * For board revs 3 and later, two pins moved:
171 * - The PG pin for the NVVDD VR moved from GPP_E16 to GPP_E3.
172 * - The enable pin for the GPU_1V8 VR moved from GPP_E18 to GPP_F12
174 * To accommodate this, the DSDT contains two Names that this code
175 * will write the correct GPIO # to depending on the board rev, and
176 * we'll use that instead.
178 void variant_fill_ssdt(const struct device
*dev
)
180 const int nvvdd_pg_gpio
= board_id() < 3 ? GPP_E16
: GPP_E3
;
181 const int gpu_1v8_en_gpio
= board_id() < 3 ? GPP_E18
: GPP_F12
;
182 acpigen_write_scope("\\_SB.PCI0.PEG0.PEGP");
183 acpigen_write_method("_INI", 0);
184 acpigen_write_store_int_to_namestr(nvvdd_pg_gpio
, "NVPG");
185 acpigen_write_store_int_to_namestr(gpu_1v8_en_gpio
, "GPEN");
186 acpigen_write_method_end();
187 acpigen_write_scope_end();
190 void variant_finalize(void)
193 * Currently the `pch_pirq_init()` function in lpc_lib.c will program
194 * PIRQ IRQs for all PCI devices discovered during enumeration. This may
195 * not be correct for all devices, and causes strange behavior with the
196 * Nvidia dGPU; it will start out with IRQ 11 and then after a
197 * suspend/resume cycle, it will get programmed back to 16, so the Linux
198 * kernel must be doing some IRQ sanitization at some point. To fix
199 * this anomaly, explicitly program the IRQ to 16 (which we know is what
200 * IRQ it will eventually take).
202 const struct device
*dgpu
= DEV_PTR(dgpu
);
203 pci_write_config8(dgpu
, PCI_INTERRUPT_LINE
, 16);