Rocky Phagura | cced346 | 2020-06-11 11:18:02 -0700 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
| 3 | #include "chip.h" |
| 4 | #include <console/console.h> |
| 5 | #include <device/device.h> |
| 6 | #include <device/pci_ops.h> |
| 7 | #include <intelblocks/pmc.h> |
| 8 | #include <intelblocks/pmclib.h> |
| 9 | #include <intelblocks/rtc.h> |
| 10 | #include <reg_script.h> |
| 11 | #include <soc/pci_devs.h> |
| 12 | #include <soc/pm.h> |
| 13 | |
| 14 | /* |
| 15 | * Set which power state system will be after reapplying |
| 16 | * the power (from G3 State) |
| 17 | */ |
| 18 | void pmc_soc_set_afterg3_en(const bool on) |
| 19 | { |
| 20 | uint8_t reg8; |
| 21 | reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B); |
| 22 | if (on) |
| 23 | reg8 &= ~SLEEP_AFTER_POWER_FAIL; |
| 24 | else |
| 25 | reg8 |= SLEEP_AFTER_POWER_FAIL; |
| 26 | pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8); |
| 27 | } |
| 28 | |
| 29 | #if ENV_RAMSTAGE |
| 30 | /* Fill up PMC resource structure */ |
| 31 | int pmc_soc_get_resources(struct pmc_resource_config *cfg) |
| 32 | { |
| 33 | cfg->pwrmbase_offset = PWRMBASE; |
| 34 | cfg->pwrmbase_addr = PCH_PWRM_BASE_ADDRESS; |
| 35 | cfg->pwrmbase_size = PCH_PWRM_BASE_SIZE; |
| 36 | cfg->abase_offset = ABASE; |
| 37 | cfg->abase_addr = ACPI_BASE_ADDRESS; |
| 38 | cfg->abase_size = ACPI_BASE_SIZE; |
| 39 | |
| 40 | return 0; |
| 41 | } |
| 42 | |
| 43 | static const struct reg_script pch_pmc_misc_init_script[] = { |
| 44 | /* Enable SCI and clear SLP requests. */ |
| 45 | REG_IO_RMW32(ACPI_BASE_ADDRESS + PM1_CNT, ~SLP_TYP, SCI_EN), |
| 46 | REG_SCRIPT_END |
| 47 | }; |
| 48 | |
| 49 | static const struct reg_script pmc_write1_to_clear_script[] = { |
| 50 | REG_PCI_OR32(GEN_PMCON_A, 0), |
| 51 | REG_PCI_OR32(GEN_PMCON_B, 0), |
| 52 | REG_PCI_OR32(GEN_PMCON_B, 0), |
| 53 | REG_RES_OR32(PWRMBASE, GBLRST_CAUSE0, 0), |
| 54 | REG_RES_OR32(PWRMBASE, GBLRST_CAUSE1, 0), |
| 55 | REG_SCRIPT_END |
| 56 | }; |
| 57 | |
| 58 | void pmc_soc_init(struct device *dev) |
| 59 | { |
| 60 | pmc_set_power_failure_state(true); |
| 61 | pmc_gpe_init(); |
| 62 | |
| 63 | /* Note that certain bits may be cleared from running script as |
| 64 | * certain bit fields are write 1 to clear. */ |
| 65 | reg_script_run_on_dev(dev, pch_pmc_misc_init_script); |
| 66 | pmc_set_acpi_mode(); |
| 67 | |
| 68 | /* Clear registers that contain write-1-to-clear bits. */ |
| 69 | reg_script_run_on_dev(dev, pmc_write1_to_clear_script); |
| 70 | } |
| 71 | #endif |
| 72 | |
| 73 | /* |
| 74 | * GPE0 |
| 75 | */ |
| 76 | |
| 77 | const char *const *soc_std_gpe_sts_array(size_t *gpe_arr) |
| 78 | { |
| 79 | static const char *const gpe_sts_bits[] = { |
| 80 | }; |
| 81 | |
| 82 | *gpe_arr = ARRAY_SIZE(gpe_sts_bits); |
| 83 | return gpe_sts_bits; |
| 84 | } |
| 85 | |
| 86 | uint8_t *pmc_mmio_regs(void) |
| 87 | { |
| 88 | return (void *)(uintptr_t) pci_read_config32(PCH_DEV_PMC, PWRMBASE); |
| 89 | } |
| 90 | |
| 91 | uintptr_t soc_read_pmc_base(void) |
| 92 | { |
| 93 | return (uintptr_t) (pmc_mmio_regs()); |
| 94 | } |
| 95 | |
| 96 | uint32_t *soc_pmc_etr_addr(void) |
| 97 | { |
| 98 | /* |
| 99 | * The pointer returned must not be cached, because the address depends on the |
| 100 | * MMCONF base address and the assigned PCI bus number, which both may change |
| 101 | * during the boot process! |
| 102 | */ |
| 103 | return pci_mmio_config32_addr(PCH_DEVFN_PMC << 12, ETR); |
| 104 | } |
| 105 | |
| 106 | void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) |
| 107 | { |
| 108 | /* No functionality for this yet */ |
| 109 | } |
| 110 | |
| 111 | int rtc_failure(void) |
| 112 | { |
| 113 | u8 reg8; |
| 114 | int rtc_failed; |
| 115 | /* PMC Controller Device 0x1F, Func 02 */ |
| 116 | reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B); |
| 117 | rtc_failed = reg8 & RTC_BATTERY_DEAD; |
| 118 | if (rtc_failed) { |
| 119 | reg8 &= ~RTC_BATTERY_DEAD; |
| 120 | pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8); |
| 121 | printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed); |
| 122 | } |
| 123 | |
| 124 | return !!rtc_failed; |
| 125 | } |
| 126 | |
| 127 | /* Return 0, 3, or 5 to indicate the previous sleep state. */ |
| 128 | int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) |
| 129 | { |
| 130 | /* |
| 131 | * Check for any power failure to determine if this a wake from |
| 132 | * S5 because the PCH does not set the WAK_STS bit when waking |
| 133 | * from a true G3 state. |
| 134 | */ |
| 135 | if (!(ps->pm1_sts & WAK_STS) && |
| 136 | (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR))) |
| 137 | prev_sleep_state = ACPI_S5; |
| 138 | |
| 139 | return prev_sleep_state; |
| 140 | } |
| 141 | |
| 142 | void soc_fill_power_state(struct chipset_power_state *ps) |
| 143 | { |
| 144 | uint8_t *pmc; |
| 145 | |
| 146 | ps->gen_pmcon_a = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_A); |
| 147 | ps->gen_pmcon_b = pci_read_config32(PCH_DEV_PMC, GEN_PMCON_B); |
| 148 | |
| 149 | pmc = pmc_mmio_regs(); |
| 150 | ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); |
| 151 | ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); |
| 152 | |
| 153 | printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", |
| 154 | ps->gen_pmcon_a, ps->gen_pmcon_b); |
| 155 | |
| 156 | printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", |
| 157 | ps->gblrst_cause[0], ps->gblrst_cause[1]); |
| 158 | } |
| 159 | |
| 160 | /* STM Support */ |
| 161 | uint16_t get_pmbase(void) |
| 162 | { |
| 163 | return ACPI_BASE_ADDRESS; |
| 164 | } |
| 165 | |
| 166 | const char *const *soc_smi_sts_array(size_t *smi_arr) |
| 167 | { |
| 168 | static const char *const smi_sts_bits[] = { |
| 169 | [2] = "BIOS", |
| 170 | [3] = "LEGACY_USB", |
| 171 | [4] = "SLP_SMI", |
| 172 | [5] = "APM", |
| 173 | [6] = "SWSMI_TMR", |
| 174 | [7] = "BIOS_RLS", |
| 175 | [8] = "PM1", |
| 176 | [9] = "GPE0", |
| 177 | [10] = "GPI", |
| 178 | [11] = "MCSMI", |
| 179 | [12] = "DEVMON", |
| 180 | [13] = "TCO", |
| 181 | [14] = "PERIODIC", |
| 182 | [20] = "PCI_EXP_SMI", |
| 183 | [23] = "IE_SMI", |
| 184 | [25] = "SCC_SMI", |
| 185 | [26] = "SPI", |
| 186 | [27] = "GPIO_UNLOCK", |
| 187 | [28] = "ESPI_SMI", |
| 188 | [29] = "SERIAL_I/O", |
| 189 | [30] = "ME_SMI", |
| 190 | [31] = "XHCI", |
| 191 | }; |
| 192 | |
| 193 | *smi_arr = ARRAY_SIZE(smi_sts_bits); |
| 194 | return smi_sts_bits; |
| 195 | } |