hwacpi.c revision 231844
171867Smsmith
267754Smsmith/******************************************************************************
367754Smsmith *
471867Smsmith * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
567754Smsmith *
667754Smsmith *****************************************************************************/
767754Smsmith
8217365Sjkim/*
9229989Sjkim * Copyright (C) 2000 - 2012, Intel Corp.
1070243Smsmith * All rights reserved.
1167754Smsmith *
12217365Sjkim * Redistribution and use in source and binary forms, with or without
13217365Sjkim * modification, are permitted provided that the following conditions
14217365Sjkim * are met:
15217365Sjkim * 1. Redistributions of source code must retain the above copyright
16217365Sjkim *    notice, this list of conditions, and the following disclaimer,
17217365Sjkim *    without modification.
18217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
20217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
21217365Sjkim *    including a substantially similar Disclaimer requirement for further
22217365Sjkim *    binary redistribution.
23217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
24217365Sjkim *    of any contributors may be used to endorse or promote products derived
25217365Sjkim *    from this software without specific prior written permission.
2667754Smsmith *
27217365Sjkim * Alternatively, this software may be distributed under the terms of the
28217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
29217365Sjkim * Software Foundation.
3067754Smsmith *
31217365Sjkim * NO WARRANTY
32217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
43217365Sjkim */
4467754Smsmith
4567754Smsmith#define __HWACPI_C__
4667754Smsmith
47193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
48193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
4967754Smsmith
5067754Smsmith
5177424Smsmith#define _COMPONENT          ACPI_HARDWARE
5291116Smsmith        ACPI_MODULE_NAME    ("hwacpi")
5367754Smsmith
5467754Smsmith
55231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
5667754Smsmith/******************************************************************************
5767754Smsmith *
5867754Smsmith * FUNCTION:    AcpiHwSetMode
5967754Smsmith *
6067754Smsmith * PARAMETERS:  Mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
6167754Smsmith *
6267754Smsmith * RETURN:      Status
6367754Smsmith *
6491116Smsmith * DESCRIPTION: Transitions the system into the requested mode.
6567754Smsmith *
6667754Smsmith ******************************************************************************/
6767754Smsmith
6867754SmsmithACPI_STATUS
6967754SmsmithAcpiHwSetMode (
7067754Smsmith    UINT32                  Mode)
7167754Smsmith{
7267754Smsmith
7399679Siwasaki    ACPI_STATUS             Status;
7499679Siwasaki    UINT32                  Retry;
7567754Smsmith
7683174Smsmith
77167802Sjkim    ACPI_FUNCTION_TRACE (HwSetMode);
7867754Smsmith
79102550Siwasaki    /*
80102550Siwasaki     * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
81102550Siwasaki     * system does not support mode transition.
82102550Siwasaki     */
83167802Sjkim    if (!AcpiGbl_FADT.SmiCommand)
84102550Siwasaki    {
85167802Sjkim        ACPI_ERROR ((AE_INFO, "No SMI_CMD in FADT, mode transition failed"));
86102550Siwasaki        return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
87102550Siwasaki    }
88102550Siwasaki
89102550Siwasaki    /*
90102550Siwasaki     * ACPI 2.0 clarified the meaning of ACPI_ENABLE and ACPI_DISABLE
91102550Siwasaki     * in FADT: If it is zero, enabling or disabling is not supported.
92102550Siwasaki     * As old systems may have used zero for mode transition,
93102550Siwasaki     * we make sure both the numbers are zero to determine these
94102550Siwasaki     * transitions are not supported.
95102550Siwasaki     */
96167802Sjkim    if (!AcpiGbl_FADT.AcpiEnable && !AcpiGbl_FADT.AcpiDisable)
97102550Siwasaki    {
98167802Sjkim        ACPI_ERROR ((AE_INFO,
99193267Sjkim            "No ACPI mode transition supported in this system "
100193267Sjkim            "(enable/disable both zero)"));
101102550Siwasaki        return_ACPI_STATUS (AE_OK);
102102550Siwasaki    }
103102550Siwasaki
10499679Siwasaki    switch (Mode)
10599679Siwasaki    {
10699679Siwasaki    case ACPI_SYS_MODE_ACPI:
10767754Smsmith
10867754Smsmith        /* BIOS should have disabled ALL fixed and GP events */
10967754Smsmith
110193267Sjkim        Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
111167802Sjkim                        (UINT32) AcpiGbl_FADT.AcpiEnable, 8);
11282367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n"));
11399679Siwasaki        break;
11499679Siwasaki
11599679Siwasaki    case ACPI_SYS_MODE_LEGACY:
11699679Siwasaki
11767754Smsmith        /*
11867754Smsmith         * BIOS should clear all fixed status bits and restore fixed event
11967754Smsmith         * enable bits to default
12067754Smsmith         */
121193267Sjkim        Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand,
122167802Sjkim                    (UINT32) AcpiGbl_FADT.AcpiDisable, 8);
12382367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
12482367Smsmith                    "Attempting to enable Legacy (non-ACPI) mode\n"));
12599679Siwasaki        break;
12699679Siwasaki
12799679Siwasaki    default:
12899679Siwasaki        return_ACPI_STATUS (AE_BAD_PARAMETER);
12967754Smsmith    }
13067754Smsmith
13199679Siwasaki    if (ACPI_FAILURE (Status))
13299679Siwasaki    {
133167802Sjkim        ACPI_EXCEPTION ((AE_INFO, Status,
134167802Sjkim            "Could not write ACPI mode change"));
13599679Siwasaki        return_ACPI_STATUS (Status);
13699679Siwasaki    }
13783174Smsmith
13899679Siwasaki    /*
13999679Siwasaki     * Some hardware takes a LONG time to switch modes. Give them 3 sec to
14099679Siwasaki     * do so, but allow faster systems to proceed more quickly.
14199679Siwasaki     */
14299679Siwasaki    Retry = 3000;
14399679Siwasaki    while (Retry)
14499679Siwasaki    {
145102550Siwasaki        if (AcpiHwGetMode() == Mode)
146102550Siwasaki        {
147151937Sjkim            ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n",
148151937Sjkim                Mode));
149123315Snjl            return_ACPI_STATUS (AE_OK);
15099679Siwasaki        }
151102550Siwasaki        AcpiOsStall(1000);
15299679Siwasaki        Retry--;
15367754Smsmith    }
15467754Smsmith
155167802Sjkim    ACPI_ERROR ((AE_INFO, "Hardware did not change modes"));
156123315Snjl    return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
15767754Smsmith}
15867754Smsmith
15967754Smsmith
160151937Sjkim/*******************************************************************************
16167754Smsmith *
16267754Smsmith * FUNCTION:    AcpiHwGetMode
16367754Smsmith *
16467754Smsmith * PARAMETERS:  none
16567754Smsmith *
16667754Smsmith * RETURN:      SYS_MODE_ACPI or SYS_MODE_LEGACY
16767754Smsmith *
16867754Smsmith * DESCRIPTION: Return current operating state of system.  Determined by
16967754Smsmith *              querying the SCI_EN bit.
17067754Smsmith *
17167754Smsmith ******************************************************************************/
17267754Smsmith
17367754SmsmithUINT32
174151937SjkimAcpiHwGetMode (
175151937Sjkim    void)
17667754Smsmith{
17799679Siwasaki    ACPI_STATUS             Status;
17899679Siwasaki    UINT32                  Value;
17967754Smsmith
18099679Siwasaki
181167802Sjkim    ACPI_FUNCTION_TRACE (HwGetMode);
18267754Smsmith
183123315Snjl
184123315Snjl    /*
185123315Snjl     * ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
186123315Snjl     * system does not support mode transition.
187123315Snjl     */
188167802Sjkim    if (!AcpiGbl_FADT.SmiCommand)
189123315Snjl    {
190151937Sjkim        return_UINT32 (ACPI_SYS_MODE_ACPI);
191123315Snjl    }
192123315Snjl
193193267Sjkim    Status = AcpiReadBitRegister (ACPI_BITREG_SCI_ENABLE, &Value);
19499679Siwasaki    if (ACPI_FAILURE (Status))
19599679Siwasaki    {
196151937Sjkim        return_UINT32 (ACPI_SYS_MODE_LEGACY);
19799679Siwasaki    }
19867754Smsmith
19999679Siwasaki    if (Value)
20067754Smsmith    {
201151937Sjkim        return_UINT32 (ACPI_SYS_MODE_ACPI);
20267754Smsmith    }
20367754Smsmith    else
20467754Smsmith    {
205151937Sjkim        return_UINT32 (ACPI_SYS_MODE_LEGACY);
20667754Smsmith    }
20767754Smsmith}
208231844Sjkim
209231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */
210