xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/hwacpi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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