195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
1295b482a8SLen Brown
1395b482a8SLen Brown #define _COMPONENT ACPI_HARDWARE
1495b482a8SLen Brown ACPI_MODULE_NAME("hwacpi")
1595b482a8SLen Brown
1633620c54SBob Moore #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
1795b482a8SLen Brown /******************************************************************************
1895b482a8SLen Brown *
1995b482a8SLen Brown * FUNCTION: acpi_hw_set_mode
2095b482a8SLen Brown *
21ba494beeSBob Moore * PARAMETERS: mode - SYS_MODE_ACPI or SYS_MODE_LEGACY
2295b482a8SLen Brown *
2395b482a8SLen Brown * RETURN: Status
2495b482a8SLen Brown *
2595b482a8SLen Brown * DESCRIPTION: Transitions the system into the requested mode.
2695b482a8SLen Brown *
2795b482a8SLen Brown ******************************************************************************/
acpi_hw_set_mode(u32 mode)2895b482a8SLen Brown acpi_status acpi_hw_set_mode(u32 mode)
2995b482a8SLen Brown {
3095b482a8SLen Brown
3195b482a8SLen Brown acpi_status status;
3295b482a8SLen Brown
3395b482a8SLen Brown ACPI_FUNCTION_TRACE(hw_set_mode);
3495b482a8SLen Brown
35c39660b2SBob Moore /* If the Hardware Reduced flag is set, machine is always in acpi mode */
36c39660b2SBob Moore
37c39660b2SBob Moore if (acpi_gbl_reduced_hardware) {
38c39660b2SBob Moore return_ACPI_STATUS(AE_OK);
39c39660b2SBob Moore }
40c39660b2SBob Moore
4195b482a8SLen Brown /*
4295b482a8SLen Brown * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
4395b482a8SLen Brown * system does not support mode transition.
4495b482a8SLen Brown */
4595b482a8SLen Brown if (!acpi_gbl_FADT.smi_command) {
4695b482a8SLen Brown ACPI_ERROR((AE_INFO,
4795b482a8SLen Brown "No SMI_CMD in FADT, mode transition failed"));
4895b482a8SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
4995b482a8SLen Brown }
5095b482a8SLen Brown
5195b482a8SLen Brown /*
5295b482a8SLen Brown * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
5395b482a8SLen Brown * in FADT: If it is zero, enabling or disabling is not supported.
5495b482a8SLen Brown * As old systems may have used zero for mode transition,
5595b482a8SLen Brown * we make sure both the numbers are zero to determine these
5695b482a8SLen Brown * transitions are not supported.
5795b482a8SLen Brown */
5895b482a8SLen Brown if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
5995b482a8SLen Brown ACPI_ERROR((AE_INFO,
60d4913dc6SBob Moore "No ACPI mode transition supported in this system "
61d4913dc6SBob Moore "(enable/disable both zero)"));
6295b482a8SLen Brown return_ACPI_STATUS(AE_OK);
6395b482a8SLen Brown }
6495b482a8SLen Brown
6595b482a8SLen Brown switch (mode) {
6695b482a8SLen Brown case ACPI_SYS_MODE_ACPI:
6795b482a8SLen Brown
6895b482a8SLen Brown /* BIOS should have disabled ALL fixed and GP events */
6995b482a8SLen Brown
707f071903SBob Moore status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
7195b482a8SLen Brown (u32) acpi_gbl_FADT.acpi_enable, 8);
7295b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO,
7395b482a8SLen Brown "Attempting to enable ACPI mode\n"));
7495b482a8SLen Brown break;
7595b482a8SLen Brown
7695b482a8SLen Brown case ACPI_SYS_MODE_LEGACY:
7795b482a8SLen Brown /*
7895b482a8SLen Brown * BIOS should clear all fixed status bits and restore fixed event
7995b482a8SLen Brown * enable bits to default
8095b482a8SLen Brown */
817f071903SBob Moore status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
823e8214e5SLv Zheng (u32)acpi_gbl_FADT.acpi_disable, 8);
8395b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO,
8495b482a8SLen Brown "Attempting to enable Legacy (non-ACPI) mode\n"));
8595b482a8SLen Brown break;
8695b482a8SLen Brown
8795b482a8SLen Brown default:
881d1ea1b7SChao Guan
8995b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER);
9095b482a8SLen Brown }
9195b482a8SLen Brown
9295b482a8SLen Brown if (ACPI_FAILURE(status)) {
9395b482a8SLen Brown ACPI_EXCEPTION((AE_INFO, status,
9495b482a8SLen Brown "Could not write ACPI mode change"));
9595b482a8SLen Brown return_ACPI_STATUS(status);
9695b482a8SLen Brown }
9795b482a8SLen Brown
9895b482a8SLen Brown return_ACPI_STATUS(AE_OK);
9995b482a8SLen Brown }
10095b482a8SLen Brown
10195b482a8SLen Brown /*******************************************************************************
10295b482a8SLen Brown *
10395b482a8SLen Brown * FUNCTION: acpi_hw_get_mode
10495b482a8SLen Brown *
10595b482a8SLen Brown * PARAMETERS: none
10695b482a8SLen Brown *
10795b482a8SLen Brown * RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY
10895b482a8SLen Brown *
10995b482a8SLen Brown * DESCRIPTION: Return current operating state of system. Determined by
11095b482a8SLen Brown * querying the SCI_EN bit.
11195b482a8SLen Brown *
11295b482a8SLen Brown ******************************************************************************/
11395b482a8SLen Brown
acpi_hw_get_mode(void)11495b482a8SLen Brown u32 acpi_hw_get_mode(void)
11595b482a8SLen Brown {
11695b482a8SLen Brown acpi_status status;
11795b482a8SLen Brown u32 value;
11895b482a8SLen Brown
11995b482a8SLen Brown ACPI_FUNCTION_TRACE(hw_get_mode);
12095b482a8SLen Brown
121c39660b2SBob Moore /* If the Hardware Reduced flag is set, machine is always in acpi mode */
122c39660b2SBob Moore
123c39660b2SBob Moore if (acpi_gbl_reduced_hardware) {
124fd1af712SBob Moore return_UINT32(ACPI_SYS_MODE_ACPI);
125c39660b2SBob Moore }
126c39660b2SBob Moore
12795b482a8SLen Brown /*
12895b482a8SLen Brown * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
12995b482a8SLen Brown * system does not support mode transition.
13095b482a8SLen Brown */
13195b482a8SLen Brown if (!acpi_gbl_FADT.smi_command) {
132fd1af712SBob Moore return_UINT32(ACPI_SYS_MODE_ACPI);
13395b482a8SLen Brown }
13495b482a8SLen Brown
13550ffba1bSBob Moore status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
13695b482a8SLen Brown if (ACPI_FAILURE(status)) {
137fd1af712SBob Moore return_UINT32(ACPI_SYS_MODE_LEGACY);
13895b482a8SLen Brown }
13995b482a8SLen Brown
14095b482a8SLen Brown if (value) {
141fd1af712SBob Moore return_UINT32(ACPI_SYS_MODE_ACPI);
14295b482a8SLen Brown } else {
143fd1af712SBob Moore return_UINT32(ACPI_SYS_MODE_LEGACY);
14495b482a8SLen Brown }
14595b482a8SLen Brown }
14633620c54SBob Moore
14733620c54SBob Moore #endif /* !ACPI_REDUCED_HARDWARE */
148