1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/pci_ops.h>
5 #include <cpu/x86/smm.h>
6 #include <southbridge/intel/lynxpoint/pch.h>
9 void acpi_fill_fadt(acpi_fadt_t
*fadt
)
11 struct device
*dev
= pcidev_on_root(0x1f, 0);
12 struct southbridge_intel_lynxpoint_config
*cfg
= dev
->chip_info
;
13 u16 pmbase
= get_pmbase();
17 if (permanent_smi_handler()) {
18 fadt
->smi_cmd
= APM_CNT
;
19 fadt
->acpi_enable
= APM_CNT_ACPI_ENABLE
;
20 fadt
->acpi_disable
= APM_CNT_ACPI_DISABLE
;
23 fadt
->pm1a_evt_blk
= pmbase
+ PM1_STS
;
24 fadt
->pm1a_cnt_blk
= pmbase
+ PM1_CNT
;
25 fadt
->pm2_cnt_blk
= pmbase
+ PM2_CNT
;
26 fadt
->pm_tmr_blk
= pmbase
+ PM1_TMR
;
28 fadt
->gpe0_blk
= pmbase
+ LP_GPE0_STS_1
;
30 fadt
->gpe0_blk
= pmbase
+ GPE0_STS
;
33 * Some of the lengths here are doubled. This is because they describe
34 * blocks containing two registers, where the size of each register
35 * is found by halving the block length. See Table 5-34 and section
36 * 4.8.3 of the ACPI specification for details.
38 fadt
->pm1_evt_len
= 2 * 2;
39 fadt
->pm1_cnt_len
= 2;
40 fadt
->pm2_cnt_len
= 1;
43 fadt
->gpe0_blk_len
= 2 * 16;
45 fadt
->gpe0_blk_len
= 2 * 8;
48 fadt
->p_lvl2_lat
= 101;
49 fadt
->p_lvl3_lat
= 1001;
50 fadt
->duty_offset
= 0;
53 fadt
->mon_alrm
= 0x00;
54 fadt
->iapc_boot_arch
= ACPI_FADT_LEGACY_DEVICES
| ACPI_FADT_8042
;
56 fadt
->flags
|= ACPI_FADT_WBINVD
|
57 ACPI_FADT_C1_SUPPORTED
|
58 ACPI_FADT_SLEEP_BUTTON
|
59 ACPI_FADT_SEALED_CASE
|
60 ACPI_FADT_S4_RTC_WAKE
|
61 ACPI_FADT_PLATFORM_CLOCK
;
63 if (cfg
&& cfg
->docking_supported
)
64 fadt
->flags
|= ACPI_FADT_DOCKING_SUPPORTED
;
66 fadt
->x_pm1a_evt_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
67 fadt
->x_pm1a_evt_blk
.bit_width
= fadt
->pm1_evt_len
* 8;
68 fadt
->x_pm1a_evt_blk
.bit_offset
= 0;
69 fadt
->x_pm1a_evt_blk
.access_size
= ACPI_ACCESS_SIZE_WORD_ACCESS
;
70 fadt
->x_pm1a_evt_blk
.addrl
= fadt
->pm1a_evt_blk
;
71 fadt
->x_pm1a_evt_blk
.addrh
= 0x0;
73 fadt
->x_pm1a_cnt_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
74 fadt
->x_pm1a_cnt_blk
.bit_width
= fadt
->pm1_cnt_len
* 8;
75 fadt
->x_pm1a_cnt_blk
.bit_offset
= 0;
76 fadt
->x_pm1a_cnt_blk
.access_size
= ACPI_ACCESS_SIZE_WORD_ACCESS
;
77 fadt
->x_pm1a_cnt_blk
.addrl
= fadt
->pm1a_cnt_blk
;
78 fadt
->x_pm1a_cnt_blk
.addrh
= 0x0;
80 fadt
->x_pm2_cnt_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
81 fadt
->x_pm2_cnt_blk
.bit_width
= fadt
->pm2_cnt_len
* 8;
82 fadt
->x_pm2_cnt_blk
.bit_offset
= 0;
83 fadt
->x_pm2_cnt_blk
.access_size
= ACPI_ACCESS_SIZE_BYTE_ACCESS
;
84 fadt
->x_pm2_cnt_blk
.addrl
= fadt
->pm2_cnt_blk
;
85 fadt
->x_pm2_cnt_blk
.addrh
= 0x0;
87 fadt
->x_pm_tmr_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
88 fadt
->x_pm_tmr_blk
.bit_width
= fadt
->pm_tmr_len
* 8;
89 fadt
->x_pm_tmr_blk
.bit_offset
= 0;
90 fadt
->x_pm_tmr_blk
.access_size
= ACPI_ACCESS_SIZE_DWORD_ACCESS
;
91 fadt
->x_pm_tmr_blk
.addrl
= fadt
->pm_tmr_blk
;
92 fadt
->x_pm_tmr_blk
.addrh
= 0x0;
95 * Windows 10 requires x_gpe0_blk to be set starting with FADT revision 5.
96 * The bit_width field intentionally overflows here.
97 * The OSPM can instead use the values in `fadt->gpe0_blk{,_len}`, which
98 * seems to work fine on Linux 5.0 and Windows 10.
100 fadt
->x_gpe0_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
101 fadt
->x_gpe0_blk
.bit_width
= fadt
->gpe0_blk_len
* 8;
102 fadt
->x_gpe0_blk
.bit_offset
= 0;
103 fadt
->x_gpe0_blk
.access_size
= ACPI_ACCESS_SIZE_BYTE_ACCESS
;
104 fadt
->x_gpe0_blk
.addrl
= fadt
->gpe0_blk
;
105 fadt
->x_gpe0_blk
.addrh
= 0x0;