1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun *****************************************************************************/
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <acpi/acpi.h>
11*4882a593Smuzhiyun #include "accommon.h"
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define _COMPONENT ACPI_HARDWARE
14*4882a593Smuzhiyun ACPI_MODULE_NAME("hwacpi")
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
17*4882a593Smuzhiyun /******************************************************************************
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * FUNCTION: acpi_hw_set_mode
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * PARAMETERS: mode - SYS_MODE_ACPI or SYS_MODE_LEGACY
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * RETURN: Status
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * DESCRIPTION: Transitions the system into the requested mode.
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun ******************************************************************************/
acpi_hw_set_mode(u32 mode)28*4882a593Smuzhiyun acpi_status acpi_hw_set_mode(u32 mode)
29*4882a593Smuzhiyun {
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun acpi_status status;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(hw_set_mode);
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* If the Hardware Reduced flag is set, machine is always in acpi mode */
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun if (acpi_gbl_reduced_hardware) {
38*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
43*4882a593Smuzhiyun * system does not support mode transition.
44*4882a593Smuzhiyun */
45*4882a593Smuzhiyun if (!acpi_gbl_FADT.smi_command) {
46*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
47*4882a593Smuzhiyun "No SMI_CMD in FADT, mode transition failed"));
48*4882a593Smuzhiyun return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /*
52*4882a593Smuzhiyun * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
53*4882a593Smuzhiyun * in FADT: If it is zero, enabling or disabling is not supported.
54*4882a593Smuzhiyun * As old systems may have used zero for mode transition,
55*4882a593Smuzhiyun * we make sure both the numbers are zero to determine these
56*4882a593Smuzhiyun * transitions are not supported.
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
59*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
60*4882a593Smuzhiyun "No ACPI mode transition supported in this system "
61*4882a593Smuzhiyun "(enable/disable both zero)"));
62*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun switch (mode) {
66*4882a593Smuzhiyun case ACPI_SYS_MODE_ACPI:
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* BIOS should have disabled ALL fixed and GP events */
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
71*4882a593Smuzhiyun (u32) acpi_gbl_FADT.acpi_enable, 8);
72*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_INFO,
73*4882a593Smuzhiyun "Attempting to enable ACPI mode\n"));
74*4882a593Smuzhiyun break;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun case ACPI_SYS_MODE_LEGACY:
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun * BIOS should clear all fixed status bits and restore fixed event
79*4882a593Smuzhiyun * enable bits to default
80*4882a593Smuzhiyun */
81*4882a593Smuzhiyun status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
82*4882a593Smuzhiyun (u32)acpi_gbl_FADT.acpi_disable, 8);
83*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_INFO,
84*4882a593Smuzhiyun "Attempting to enable Legacy (non-ACPI) mode\n"));
85*4882a593Smuzhiyun break;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun default:
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
93*4882a593Smuzhiyun ACPI_EXCEPTION((AE_INFO, status,
94*4882a593Smuzhiyun "Could not write ACPI mode change"));
95*4882a593Smuzhiyun return_ACPI_STATUS(status);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun /*******************************************************************************
102*4882a593Smuzhiyun *
103*4882a593Smuzhiyun * FUNCTION: acpi_hw_get_mode
104*4882a593Smuzhiyun *
105*4882a593Smuzhiyun * PARAMETERS: none
106*4882a593Smuzhiyun *
107*4882a593Smuzhiyun * RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY
108*4882a593Smuzhiyun *
109*4882a593Smuzhiyun * DESCRIPTION: Return current operating state of system. Determined by
110*4882a593Smuzhiyun * querying the SCI_EN bit.
111*4882a593Smuzhiyun *
112*4882a593Smuzhiyun ******************************************************************************/
113*4882a593Smuzhiyun
acpi_hw_get_mode(void)114*4882a593Smuzhiyun u32 acpi_hw_get_mode(void)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun acpi_status status;
117*4882a593Smuzhiyun u32 value;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(hw_get_mode);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /* If the Hardware Reduced flag is set, machine is always in acpi mode */
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun if (acpi_gbl_reduced_hardware) {
124*4882a593Smuzhiyun return_UINT32(ACPI_SYS_MODE_ACPI);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
129*4882a593Smuzhiyun * system does not support mode transition.
130*4882a593Smuzhiyun */
131*4882a593Smuzhiyun if (!acpi_gbl_FADT.smi_command) {
132*4882a593Smuzhiyun return_UINT32(ACPI_SYS_MODE_ACPI);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
136*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
137*4882a593Smuzhiyun return_UINT32(ACPI_SYS_MODE_LEGACY);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun if (value) {
141*4882a593Smuzhiyun return_UINT32(ACPI_SYS_MODE_ACPI);
142*4882a593Smuzhiyun } else {
143*4882a593Smuzhiyun return_UINT32(ACPI_SYS_MODE_LEGACY);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #endif /* !ACPI_REDUCED_HARDWARE */
148