summaryrefslogtreecommitdiff
path: root/include/power/acpi_pmc.h
blob: 64176d79bc6258b5dcfad8744c74948619ccdaf7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright 2019 Google LLC
 */

#ifndef __ACPI_PMC_H
#define __ACPI_PMC_H

#ifndef __ASSEMBLY__

enum {
	GPE0_REG_MAX	= 4,
};

enum {
	PM1_STS		= 0x00,
	PM1_EN		= 0x02,
	PM1_CNT		= 0x04,
	PM1_TMR		= 0x08,

	GPE0_STS	= 0x20,
	GPE0_EN		= 0x30,
};

/**
 * struct acpi_pmc_upriv - holds common data for the x86 PMC
 *
 * @pmc_bar0: Base address 0 of PMC
 * @pmc_bar1: Base address 2 of PMC
 * @acpi_base: Base address of ACPI block
 * @pm1_sts: PM1 status
 * @pm1_en: PM1 enable
 * @pm1_cnt: PM1 control
 * @gpe_cfg: Address of GPE_CFG register
 * @gpe0_dwx_mask: Mask to use for each GPE0 (typically 7 or 0xf)
 * @gpe0_dwx_shift_base: Base shift value to use for GPE0 (0 or 4)
 * @gpe0_sts_req: GPE0 status register offset
 * @gpe0_en_req: GPE0 enable register offset
 * @gpe0_sts: GPE0 status values
 * @gpe0_en: GPE0 enable values
 * @gpe0_dw: GPE0 DW values
 * @gpe0_count: Number of GPE0 registers
 * @tco1_sts: TCO1 status
 * @tco2_sts: TCO2 status
 * @prsts: Power and reset status
 * @gen_pmcon1: General power mgmt configuration 1
 * @gen_pmcon2: General power mgmt configuration 2
 * @gen_pmcon3: General power mgmt configuration 3
 */
struct acpi_pmc_upriv {
	void *pmc_bar0;
	void *pmc_bar2;
	u32 acpi_base;
	u16 pm1_sts;
	u16 pm1_en;
	u32 pm1_cnt;
	u32 *gpe_cfg;
	u32 gpe0_dwx_mask;
	u32 gpe0_dwx_shift_base;
	u32 gpe0_sts_reg;
	u32 gpe0_en_reg;
	u32 gpe0_sts[GPE0_REG_MAX];
	u32 gpe0_en[GPE0_REG_MAX];
	u32 gpe0_dw[GPE0_REG_MAX];
	int gpe0_count;
	u16 tco1_sts;
	u16 tco2_sts;
	u32 prsts;
	u32 gen_pmcon1;
	u32 gen_pmcon2;
	u32 gen_pmcon3;
};

struct acpi_pmc_ops {
	/**
	 * init() - Set up the PMC for use
	 *
	 * This reads the current state of the PMC. Most of the state is read
	 * automatically by the uclass since it is common.
	 *
	 * This is optional.
	 *
	 * @dev: PMC device to use
	 * @return 0 if OK, -ve on error
	 */
	int (*init)(struct udevice *dev);

	/**
	 * prev_sleep_state() - Get the previous sleep state (optional)
	 *
	 * This reads various state registers and returns the sleep state from
	 * which the system woke. If this method is not provided, the uclass
	 * will return a calculated value.
	 *
	 * This is optional.
	 *
	 * @dev: PMC device to use
	 * @prev_sleep_state: Previous sleep state as calculated by the uclass.
	 *	The method can use this as the return value or calculate its
	 *	own.
	 *
	 * @return enum acpi_sleep_state indicating the previous sleep state
	 *	(ACPI_S0, ACPI_S3 or ACPI_S5), or -ve on error
	 */
	int (*prev_sleep_state)(struct udevice *dev, int prev_sleep_state);

	/**
	 * disable_tco() - Disable the timer/counter
	 *
	 * Disables the timer/counter in the PMC
	 *
	 * This is optional.
	 *
	 * @dev: PMC device to use
	 * @return 0
	 */
	int (*disable_tco)(struct udevice *dev);

	/**
	 * global_reset_set_enable() - Enable/Disable global reset
	 *
	 * Enable or disable global reset. If global reset is enabled, both hard
	 * reset and soft reset will trigger global reset, where both host and
	 * TXE are reset. This is cleared on cold boot, hard reset, soft reset
	 * and Sx.
	 *
	 * This is optional.
	 *
	 * @dev: PMC device to use
	 * @enable: true to enable global reset, false to disable
	 * @return 0
	 */
	int (*global_reset_set_enable)(struct udevice *dev, bool enable);
};

#define acpi_pmc_get_ops(dev)	((struct acpi_pmc_ops *)(dev)->driver->ops)

/**
 * init() - Set up the PMC for use
 *
 * This reads the current state of the PMC. This reads in the common registers,
 * then calls the device's init() method to read the SoC-specific registers.
 *
 * @return 0 if OK, -ve on error
 */
int pmc_init(struct udevice *dev);

/**
 * pmc_prev_sleep_state() - Get the previous sleep state
 *
 * This reads various state registers and returns the sleep state from
 * which the system woke.
 *
 * @return enum acpi_sleep_state indicating the previous sleep state
 *	(ACPI_S0, ACPI_S3 or ACPI_S5), or -ve on error
 */
int pmc_prev_sleep_state(struct udevice *dev);

/**
 * pmc_disable_tco() - Disable the timer/counter
 *
 * Disables the timer/counter in the PMC
 *
 * @dev: PMC device to use
 * @return 0
 */
int pmc_disable_tco(struct udevice *dev);

/**
 * pmc_global_reset_set_enable() - Enable/Disable global reset
 *
 * Enable or disable global reset. If global reset is enabled, both hard
 * reset and soft reset will trigger global reset, where both host and
 * TXE are reset. This is cleared on cold boot, hard reset, soft reset
 * and Sx.
 *
 * @dev: PMC device to use
 * @enable: true to enable global reset, false to disable
 * @return 0
 */
int pmc_global_reset_set_enable(struct udevice *dev, bool enable);

int pmc_ofdata_to_uc_plat(struct udevice *dev);

int pmc_disable_tco_base(ulong tco_base);

void pmc_dump_info(struct udevice *dev);

/**
 * pmc_gpe_init() - Set up general-purpose events
 *
 * @dev: PMC device
 * @return 0 if OK, -ve on error
 */
int pmc_gpe_init(struct udevice *dev);

#endif /* !__ASSEMBLY__ */

#endif