Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* |
| 3 | * Copyright 2019 Google LLC |
| 4 | */ |
| 5 | |
| 6 | #ifndef __ACPI_PMC_H |
| 7 | #define __ACPI_PMC_H |
| 8 | |
Simon Glass | 1055237 | 2020-09-22 12:45:06 -0600 | [diff] [blame] | 9 | #ifndef __ASSEMBLY__ |
Simon Glass | 11e27ae | 2020-07-07 21:32:33 -0600 | [diff] [blame] | 10 | |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 11 | enum { |
| 12 | GPE0_REG_MAX = 4, |
| 13 | }; |
| 14 | |
Simon Glass | 11e27ae | 2020-07-07 21:32:33 -0600 | [diff] [blame] | 15 | enum { |
| 16 | PM1_STS = 0x00, |
| 17 | PM1_EN = 0x02, |
| 18 | PM1_CNT = 0x04, |
| 19 | PM1_TMR = 0x08, |
| 20 | |
| 21 | GPE0_STS = 0x20, |
| 22 | GPE0_EN = 0x30, |
| 23 | }; |
| 24 | |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 25 | /** |
| 26 | * struct acpi_pmc_upriv - holds common data for the x86 PMC |
| 27 | * |
| 28 | * @pmc_bar0: Base address 0 of PMC |
| 29 | * @pmc_bar1: Base address 2 of PMC |
| 30 | * @acpi_base: Base address of ACPI block |
| 31 | * @pm1_sts: PM1 status |
| 32 | * @pm1_en: PM1 enable |
| 33 | * @pm1_cnt: PM1 control |
| 34 | * @gpe_cfg: Address of GPE_CFG register |
| 35 | * @gpe0_dwx_mask: Mask to use for each GPE0 (typically 7 or 0xf) |
| 36 | * @gpe0_dwx_shift_base: Base shift value to use for GPE0 (0 or 4) |
| 37 | * @gpe0_sts_req: GPE0 status register offset |
| 38 | * @gpe0_en_req: GPE0 enable register offset |
| 39 | * @gpe0_sts: GPE0 status values |
| 40 | * @gpe0_en: GPE0 enable values |
| 41 | * @gpe0_dw: GPE0 DW values |
| 42 | * @gpe0_count: Number of GPE0 registers |
| 43 | * @tco1_sts: TCO1 status |
| 44 | * @tco2_sts: TCO2 status |
| 45 | * @prsts: Power and reset status |
| 46 | * @gen_pmcon1: General power mgmt configuration 1 |
| 47 | * @gen_pmcon2: General power mgmt configuration 2 |
| 48 | * @gen_pmcon3: General power mgmt configuration 3 |
| 49 | */ |
| 50 | struct acpi_pmc_upriv { |
| 51 | void *pmc_bar0; |
| 52 | void *pmc_bar2; |
| 53 | u32 acpi_base; |
| 54 | u16 pm1_sts; |
| 55 | u16 pm1_en; |
| 56 | u32 pm1_cnt; |
| 57 | u32 *gpe_cfg; |
| 58 | u32 gpe0_dwx_mask; |
| 59 | u32 gpe0_dwx_shift_base; |
| 60 | u32 gpe0_sts_reg; |
| 61 | u32 gpe0_en_reg; |
| 62 | u32 gpe0_sts[GPE0_REG_MAX]; |
| 63 | u32 gpe0_en[GPE0_REG_MAX]; |
| 64 | u32 gpe0_dw[GPE0_REG_MAX]; |
| 65 | int gpe0_count; |
| 66 | u16 tco1_sts; |
| 67 | u16 tco2_sts; |
| 68 | u32 prsts; |
| 69 | u32 gen_pmcon1; |
| 70 | u32 gen_pmcon2; |
| 71 | u32 gen_pmcon3; |
| 72 | }; |
| 73 | |
| 74 | struct acpi_pmc_ops { |
| 75 | /** |
| 76 | * init() - Set up the PMC for use |
| 77 | * |
| 78 | * This reads the current state of the PMC. Most of the state is read |
| 79 | * automatically by the uclass since it is common. |
| 80 | * |
| 81 | * This is optional. |
| 82 | * |
| 83 | * @dev: PMC device to use |
| 84 | * @return 0 if OK, -ve on error |
| 85 | */ |
| 86 | int (*init)(struct udevice *dev); |
| 87 | |
| 88 | /** |
| 89 | * prev_sleep_state() - Get the previous sleep state (optional) |
| 90 | * |
| 91 | * This reads various state registers and returns the sleep state from |
| 92 | * which the system woke. If this method is not provided, the uclass |
| 93 | * will return a calculated value. |
| 94 | * |
| 95 | * This is optional. |
| 96 | * |
| 97 | * @dev: PMC device to use |
| 98 | * @prev_sleep_state: Previous sleep state as calculated by the uclass. |
| 99 | * The method can use this as the return value or calculate its |
| 100 | * own. |
| 101 | * |
| 102 | * @return enum acpi_sleep_state indicating the previous sleep state |
| 103 | * (ACPI_S0, ACPI_S3 or ACPI_S5), or -ve on error |
| 104 | */ |
| 105 | int (*prev_sleep_state)(struct udevice *dev, int prev_sleep_state); |
| 106 | |
| 107 | /** |
| 108 | * disable_tco() - Disable the timer/counter |
| 109 | * |
| 110 | * Disables the timer/counter in the PMC |
| 111 | * |
| 112 | * This is optional. |
| 113 | * |
| 114 | * @dev: PMC device to use |
| 115 | * @return 0 |
| 116 | */ |
| 117 | int (*disable_tco)(struct udevice *dev); |
| 118 | |
| 119 | /** |
| 120 | * global_reset_set_enable() - Enable/Disable global reset |
| 121 | * |
| 122 | * Enable or disable global reset. If global reset is enabled, both hard |
| 123 | * reset and soft reset will trigger global reset, where both host and |
| 124 | * TXE are reset. This is cleared on cold boot, hard reset, soft reset |
| 125 | * and Sx. |
| 126 | * |
| 127 | * This is optional. |
| 128 | * |
| 129 | * @dev: PMC device to use |
| 130 | * @enable: true to enable global reset, false to disable |
| 131 | * @return 0 |
| 132 | */ |
| 133 | int (*global_reset_set_enable)(struct udevice *dev, bool enable); |
| 134 | }; |
| 135 | |
| 136 | #define acpi_pmc_get_ops(dev) ((struct acpi_pmc_ops *)(dev)->driver->ops) |
| 137 | |
| 138 | /** |
| 139 | * init() - Set up the PMC for use |
| 140 | * |
| 141 | * This reads the current state of the PMC. This reads in the common registers, |
| 142 | * then calls the device's init() method to read the SoC-specific registers. |
| 143 | * |
Heinrich Schuchardt | 185f812 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 144 | * Return: 0 if OK, -ve on error |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 145 | */ |
| 146 | int pmc_init(struct udevice *dev); |
| 147 | |
| 148 | /** |
| 149 | * pmc_prev_sleep_state() - Get the previous sleep state |
| 150 | * |
| 151 | * This reads various state registers and returns the sleep state from |
| 152 | * which the system woke. |
| 153 | * |
Heinrich Schuchardt | 185f812 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 154 | * Return: enum acpi_sleep_state indicating the previous sleep state |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 155 | * (ACPI_S0, ACPI_S3 or ACPI_S5), or -ve on error |
| 156 | */ |
| 157 | int pmc_prev_sleep_state(struct udevice *dev); |
| 158 | |
| 159 | /** |
| 160 | * pmc_disable_tco() - Disable the timer/counter |
| 161 | * |
| 162 | * Disables the timer/counter in the PMC |
| 163 | * |
| 164 | * @dev: PMC device to use |
Heinrich Schuchardt | 185f812 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 165 | * Return: 0 |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 166 | */ |
| 167 | int pmc_disable_tco(struct udevice *dev); |
| 168 | |
| 169 | /** |
| 170 | * pmc_global_reset_set_enable() - Enable/Disable global reset |
| 171 | * |
| 172 | * Enable or disable global reset. If global reset is enabled, both hard |
| 173 | * reset and soft reset will trigger global reset, where both host and |
| 174 | * TXE are reset. This is cleared on cold boot, hard reset, soft reset |
| 175 | * and Sx. |
| 176 | * |
| 177 | * @dev: PMC device to use |
| 178 | * @enable: true to enable global reset, false to disable |
Heinrich Schuchardt | 185f812 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 179 | * Return: 0 |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 180 | */ |
| 181 | int pmc_global_reset_set_enable(struct udevice *dev, bool enable); |
| 182 | |
Simon Glass | 8a8d24b | 2020-12-03 16:55:23 -0700 | [diff] [blame] | 183 | int pmc_ofdata_to_uc_plat(struct udevice *dev); |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 184 | |
| 185 | int pmc_disable_tco_base(ulong tco_base); |
| 186 | |
| 187 | void pmc_dump_info(struct udevice *dev); |
| 188 | |
| 189 | /** |
| 190 | * pmc_gpe_init() - Set up general-purpose events |
| 191 | * |
| 192 | * @dev: PMC device |
Heinrich Schuchardt | 185f812 | 2022-01-19 18:05:50 +0100 | [diff] [blame] | 193 | * Return: 0 if OK, -ve on error |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 194 | */ |
| 195 | int pmc_gpe_init(struct udevice *dev); |
| 196 | |
Simon Glass | 1055237 | 2020-09-22 12:45:06 -0600 | [diff] [blame] | 197 | #endif /* !__ASSEMBLY__ */ |
Simon Glass | 11e27ae | 2020-07-07 21:32:33 -0600 | [diff] [blame] | 198 | |
Simon Glass | 6c6d88e | 2019-12-06 21:41:53 -0700 | [diff] [blame] | 199 | #endif |