blob: 683c6082f2c3b9129019adf23b60686c35a8988a [file] [log] [blame]
Simon Glasse63ca972019-12-06 21:42:57 -07001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2017 Intel Corporation.
4 * Copyright 2019 Google LLC
5 *
6 * Modified from coreboot pmclib.c, pmc.c and pmutil.c
7 */
8
9#define LOG_CATEGORY UCLASS_ACPI_PMC
10
11#include <common.h>
12#include <acpi_s3.h>
13#include <dt-structs.h>
14#include <dm.h>
15#include <spl.h>
16#include <asm/io.h>
17#include <asm/pci.h>
18#include <power/acpi_pmc.h>
19
20#define GPIO_GPE_CFG 0x1050
21
22/* Memory mapped IO registers behind PMC_BASE_ADDRESS */
23#define PRSTS 0x1000
24#define GEN_PMCON1 0x1020
25#define COLD_BOOT_STS BIT(27)
26#define COLD_RESET_STS BIT(26)
27#define WARM_RESET_STS BIT(25)
28#define GLOBAL_RESET_STS BIT(24)
29#define SRS BIT(20)
30#define MS4V BIT(18)
31#define RPS BIT(2)
32#define GEN_PMCON1_CLR1_BITS (COLD_BOOT_STS | COLD_RESET_STS | \
33 WARM_RESET_STS | GLOBAL_RESET_STS | \
34 SRS | MS4V)
35#define GEN_PMCON2 0x1024
36#define GEN_PMCON3 0x1028
37
38/* Offset of TCO registers from ACPI base I/O address */
39#define TCO_REG_OFFSET 0x60
40#define TCO1_STS 0x64
41#define DMISCI_STS BIT(9)
42#define BOOT_STS BIT(18)
43#define TCO2_STS 0x66
44#define TCO1_CNT 0x68
45#define TCO_LOCK BIT(12)
46#define TCO2_CNT 0x6a
47
48enum {
49 ETR = 0x1048,
50 CF9_LOCK = 1UL << 31,
51 CF9_GLB_RST = 1 << 20,
52};
53
54struct apl_pmc_platdata {
55#if CONFIG_IS_ENABLED(OF_PLATDATA)
56 struct dtd_intel_apl_pmc dtplat;
57#endif
58 pci_dev_t bdf;
59};
60
61static int apl_pmc_fill_power_state(struct udevice *dev)
62{
63 struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
64
65 upriv->tco1_sts = inw(upriv->acpi_base + TCO1_STS);
66 upriv->tco2_sts = inw(upriv->acpi_base + TCO2_STS);
67
68 upriv->prsts = readl(upriv->pmc_bar0 + PRSTS);
69 upriv->gen_pmcon1 = readl(upriv->pmc_bar0 + GEN_PMCON1);
70 upriv->gen_pmcon2 = readl(upriv->pmc_bar0 + GEN_PMCON2);
71 upriv->gen_pmcon3 = readl(upriv->pmc_bar0 + GEN_PMCON3);
72
73 return 0;
74}
75
76static int apl_prev_sleep_state(struct udevice *dev, int prev_sleep_state)
77{
78 struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
79
80 /* WAK_STS bit will not be set when waking from G3 state */
81 if (!(upriv->pm1_sts & WAK_STS) &&
82 (upriv->gen_pmcon1 & COLD_BOOT_STS))
83 prev_sleep_state = ACPI_S5;
84
85 return prev_sleep_state;
86}
87
88static int apl_disable_tco(struct udevice *dev)
89{
90 struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
91
92 pmc_disable_tco_base(upriv->acpi_base + TCO_REG_OFFSET);
93
94 return 0;
95}
96
97static int apl_global_reset_set_enable(struct udevice *dev, bool enable)
98{
99 struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
100
101 if (enable)
102 setbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST);
103 else
104 clrbits_le32(upriv->pmc_bar0 + ETR, CF9_GLB_RST);
105
106 return 0;
107}
108
109int apl_pmc_ofdata_to_uc_platdata(struct udevice *dev)
110{
111 struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
112 struct apl_pmc_platdata *plat = dev_get_platdata(dev);
113
114#if !CONFIG_IS_ENABLED(OF_PLATDATA)
115 u32 base[6];
116 int size;
117 int ret;
118
119 ret = dev_read_u32_array(dev, "early-regs", base, ARRAY_SIZE(base));
120 if (ret)
121 return log_msg_ret("Missing/short early-regs", ret);
122 upriv->pmc_bar0 = (void *)base[0];
123 upriv->pmc_bar2 = (void *)base[2];
124 upriv->acpi_base = base[4];
125
126 /* Since PCI is not enabled, we must get the BDF manually */
127 plat->bdf = pci_get_devfn(dev);
128 if (plat->bdf < 0)
129 return log_msg_ret("Cannot get PMC PCI address", plat->bdf);
130
131 /* Get the dwX values for pmc gpe settings */
132 size = dev_read_size(dev, "gpe0-dw");
133 if (size < 0)
134 return log_msg_ret("Cannot read gpe0-dm", size);
135 upriv->gpe0_count = size / sizeof(u32);
136 ret = dev_read_u32_array(dev, "gpe0-dw", upriv->gpe0_dw,
137 upriv->gpe0_count);
138 if (ret)
139 return log_msg_ret("Bad gpe0-dw", ret);
140
141 return pmc_ofdata_to_uc_platdata(dev);
142#else
143 struct dtd_intel_apl_pmc *dtplat = &plat->dtplat;
144
145 plat->bdf = pci_ofplat_get_devfn(dtplat->reg[0]);
146 upriv->pmc_bar0 = (void *)dtplat->early_regs[0];
147 upriv->pmc_bar2 = (void *)dtplat->early_regs[2];
148 upriv->acpi_base = dtplat->early_regs[4];
149 upriv->gpe0_dwx_mask = dtplat->gpe0_dwx_mask;
150 upriv->gpe0_dwx_shift_base = dtplat->gpe0_dwx_shift_base;
151 upriv->gpe0_sts_reg = dtplat->gpe0_sts;
152 upriv->gpe0_sts_reg += upriv->acpi_base;
153 upriv->gpe0_en_reg = dtplat->gpe0_en;
154 upriv->gpe0_en_reg += upriv->acpi_base;
155 upriv->gpe0_count = min((int)ARRAY_SIZE(dtplat->gpe0_dw), GPE0_REG_MAX);
156 memcpy(upriv->gpe0_dw, dtplat->gpe0_dw, sizeof(dtplat->gpe0_dw));
157#endif
158 upriv->gpe_cfg = (u32 *)(upriv->pmc_bar0 + GPIO_GPE_CFG);
159
160 return 0;
161}
162
163static int enable_pmcbar(struct udevice *dev)
164{
165 struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(dev);
166 struct apl_pmc_platdata *priv = dev_get_platdata(dev);
167 pci_dev_t pmc = priv->bdf;
168
169 /*
170 * Set PMC base addresses and enable decoding. BARs 1 and 3 are 64-bit
171 * BARs.
172 */
173 pci_x86_write_config(pmc, PCI_BASE_ADDRESS_0, (ulong)upriv->pmc_bar0,
174 PCI_SIZE_32);
175 pci_x86_write_config(pmc, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
176 pci_x86_write_config(pmc, PCI_BASE_ADDRESS_2, (ulong)upriv->pmc_bar2,
177 PCI_SIZE_32);
178 pci_x86_write_config(pmc, PCI_BASE_ADDRESS_3, 0, PCI_SIZE_32);
179 pci_x86_write_config(pmc, PCI_BASE_ADDRESS_4, upriv->acpi_base,
180 PCI_SIZE_16);
181 pci_x86_write_config(pmc, PCI_COMMAND, PCI_COMMAND_IO |
182 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
183 PCI_SIZE_16);
184
185 return 0;
186}
187
188static int apl_pmc_probe(struct udevice *dev)
189{
190 if (spl_phase() == PHASE_TPL)
191 return enable_pmcbar(dev);
192
193 return 0;
194}
195
196static struct acpi_pmc_ops apl_pmc_ops = {
197 .init = apl_pmc_fill_power_state,
198 .prev_sleep_state = apl_prev_sleep_state,
199 .disable_tco = apl_disable_tco,
200 .global_reset_set_enable = apl_global_reset_set_enable,
201};
202
203static const struct udevice_id apl_pmc_ids[] = {
204 { .compatible = "intel,apl-pmc" },
205 { }
206};
207
208U_BOOT_DRIVER(apl_pmc) = {
209 .name = "intel_apl_pmc",
210 .id = UCLASS_ACPI_PMC,
211 .of_match = apl_pmc_ids,
212 .ofdata_to_platdata = apl_pmc_ofdata_to_uc_platdata,
213 .probe = apl_pmc_probe,
214 .ops = &apl_pmc_ops,
215 .platdata_auto_alloc_size = sizeof(struct apl_pmc_platdata),
216};