blob: 5a339c91f79f28e33025b08c72c2f3f7f9897838 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Patrick Rudolph853bb4d2018-06-28 13:58:36 +02002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Patrick Rudolph853bb4d2018-06-28 13:58:36 +02004#include <arch/io.h>
Kyösti Mälkkie742b682023-04-10 17:03:32 +03005#include <arch/ioapic.h>
Elyes Haouas89d9bf92022-10-02 20:05:20 +02006#include <assert.h>
Bill XIE516c0a52020-02-24 23:08:35 +08007#include <bootmode.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02008#include <device/pci_ops.h>
Elyes Haouas89d9bf92022-10-02 20:05:20 +02009#include <device/pci_type.h>
Kyösti Mälkki83faa5d2023-01-05 15:39:16 +020010#include <halt.h>
Elyes Haouas89d9bf92022-10-02 20:05:20 +020011#include <stdint.h>
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020012
13#include "pmbase.h"
Joel Kitching1d93b882018-09-26 17:58:14 +080014#include "pmutil.h"
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020015
16/* LPC PM Base Address Register */
17#define PMBASE 0x40
18#define PMSIZE 0x80
19
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020020u16 lpc_get_pmbase(void)
21{
Kyösti Mälkki21d6a272019-11-05 18:50:38 +020022#ifdef __SIMPLE_DEVICE__
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020023 /* Don't assume PMBASE is still the same */
Angel Ponsac9af1a2021-04-17 12:32:38 +020024 return pci_read_config16(PCI_DEV(0, 0x1f, 0), PMBASE) & 0xfffc;
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020025#else
Arthur Heymansf751aee2018-12-29 13:35:26 +010026 static u16 pmbase;
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020027
28 if (pmbase)
29 return pmbase;
30
Angel Ponsac9af1a2021-04-17 12:32:38 +020031 pmbase = pci_read_config16(pcidev_on_root(0x1f, 0), PMBASE) & 0xfffc;
Patrick Rudolph853bb4d2018-06-28 13:58:36 +020032
33 return pmbase;
34#endif
35}
36
37void write_pmbase32(const u8 addr, const u32 val)
38{
39 ASSERT(addr <= (PMSIZE - sizeof(u32)));
40
41 outl(val, lpc_get_pmbase() + addr);
42}
43
44void write_pmbase16(const u8 addr, const u16 val)
45{
46 ASSERT(addr <= (PMSIZE - sizeof(u16)));
47
48 outw(val, lpc_get_pmbase() + addr);
49}
50
51void write_pmbase8(const u8 addr, const u8 val)
52{
53 ASSERT(addr <= (PMSIZE - sizeof(u8)));
54
55 outb(val, lpc_get_pmbase() + addr);
56}
57
58u32 read_pmbase32(const u8 addr)
59{
60 ASSERT(addr <= (PMSIZE - sizeof(u32)));
61
62 return inl(lpc_get_pmbase() + addr);
63}
64
65u16 read_pmbase16(const u8 addr)
66{
67 ASSERT(addr <= (PMSIZE - sizeof(u16)));
68
69 return inw(lpc_get_pmbase() + addr);
70}
71
72u8 read_pmbase8(const u8 addr)
73{
74 ASSERT(addr <= (PMSIZE - sizeof(u8)));
75
76 return inb(lpc_get_pmbase() + addr);
77}
Joel Kitching1d93b882018-09-26 17:58:14 +080078
Arthur Heymans89c55532021-05-05 10:39:00 +020079int acpi_get_sleep_type(void)
80{
81 return acpi_sleep_from_pm1(read_pmbase32(PM1_CNT));
82}
83
Arthur Heymansa2c51152021-05-05 10:42:24 +020084/*
85 * Note that southbridge_detect_s3_resume clears the sleep state,
86 * so this may not be used reliable throughout romstage.
87 */
Bill XIE516c0a52020-02-24 23:08:35 +080088int platform_is_resuming(void)
Joel Kitching1d93b882018-09-26 17:58:14 +080089{
90 u16 reg16 = read_pmbase16(PM1_STS);
91
92 if (!(reg16 & WAK_STS))
93 return 0;
94
Arthur Heymansa2c51152021-05-05 10:42:24 +020095 return acpi_get_sleep_type() == ACPI_S3;
Joel Kitching1d93b882018-09-26 17:58:14 +080096}
Kyösti Mälkkie742b682023-04-10 17:03:32 +030097
Kyösti Mälkki83faa5d2023-01-05 15:39:16 +020098void poweroff(void)
99{
100 uint32_t pm1_cnt;
101
102 /* Go to S5 */
103 pm1_cnt = read_pmbase32(PM1_CNT);
104 pm1_cnt |= (0xf << 10);
105 write_pmbase32(PM1_CNT, pm1_cnt);
106}
107
Kyösti Mälkkie742b682023-04-10 17:03:32 +0300108#define ACPI_SCI_IRQ 9
109
110void ioapic_get_sci_pin(u8 *gsi, u8 *irq, u8 *flags)
111{
112 *gsi = ACPI_SCI_IRQ;
113 *irq = ACPI_SCI_IRQ;
114 *flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH;
115}