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
// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> */ #include <cpu.h> #include <dm.h> #include <log.h> #include <mapmem.h> #include <acpi/acpi_s3.h> #include <acpi/acpi_table.h> #include <asm/io.h> #include <asm/tables.h> #include <asm/arch/global_nvs.h> #include <asm/arch/iomap.h> #include <dm/uclass-internal.h> void acpi_fill_fadt(struct acpi_fadt *fadt) { struct acpi_table_header *header; header = &fadt->header; u16 pmbase = ACPI_BASE_ADDRESS; header->revision = 4; fadt->preferred_pm_profile = ACPI_PM_MOBILE; fadt->sci_int = 9; fadt->smi_cmd = 0; fadt->acpi_enable = 0; fadt->acpi_disable = 0; fadt->s4bios_req = 0; fadt->pstate_cnt = 0; fadt->pm1a_evt_blk = pmbase; fadt->pm1b_evt_blk = 0x0; fadt->pm1a_cnt_blk = pmbase + 0x4; fadt->pm1b_cnt_blk = 0x0; fadt->pm2_cnt_blk = pmbase + 0x50; fadt->pm_tmr_blk = pmbase + 0x8; fadt->gpe0_blk = pmbase + 0x20; fadt->gpe1_blk = 0; fadt->pm1_evt_len = 4; fadt->pm1_cnt_len = 2; fadt->pm2_cnt_len = 1; fadt->pm_tmr_len = 4; fadt->gpe0_blk_len = 8; fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; fadt->cst_cnt = 0; fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; fadt->flush_size = 0; fadt->flush_stride = 0; fadt->duty_offset = 1; fadt->duty_width = 0; fadt->day_alrm = 0x0d; fadt->mon_alrm = 0x00; fadt->century = 0x00; fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042; fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_RESET_REGISTER | ACPI_FADT_PLATFORM_CLOCK; fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO; fadt->reset_reg.bit_width = 8; fadt->reset_reg.bit_offset = 0; fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->reset_reg.addrl = IO_PORT_RESET; fadt->reset_reg.addrh = 0; fadt->reset_value = SYS_RST | RST_CPU | FULL_RST; fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8; fadt->x_pm1a_evt_blk.bit_offset = 0; fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk; fadt->x_pm1a_evt_blk.addrh = 0x0; fadt->x_pm1b_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1b_evt_blk.bit_width = 0; fadt->x_pm1b_evt_blk.bit_offset = 0; fadt->x_pm1b_evt_blk.access_size = 0; fadt->x_pm1b_evt_blk.addrl = 0x0; fadt->x_pm1b_evt_blk.addrh = 0x0; fadt->x_pm1a_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm1b_cnt_blk.bit_width = 0; fadt->x_pm1b_cnt_blk.bit_offset = 0; fadt->x_pm1b_cnt_blk.access_size = 0; fadt->x_pm1b_cnt_blk.addrl = 0x0; fadt->x_pm1b_cnt_blk.addrh = 0x0; fadt->x_pm2_cnt_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8; fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; fadt->x_gpe0_blk.addrl = fadt->gpe0_blk; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = ACPI_ADDRESS_SPACE_IO; fadt->x_gpe1_blk.bit_width = 0; fadt->x_gpe1_blk.bit_offset = 0; fadt->x_gpe1_blk.access_size = 0; fadt->x_gpe1_blk.addrl = 0x0; fadt->x_gpe1_blk.addrh = 0x0; } int acpi_create_gnvs(struct acpi_global_nvs *gnvs) { struct udevice *dev; int ret; /* at least we have one processor */ gnvs->pcnt = 1; /* override the processor count with actual number */ ret = uclass_find_first_device(UCLASS_CPU, &dev); if (ret == 0 && dev != NULL) { ret = cpu_get_count(dev); if (ret > 0) gnvs->pcnt = ret; } /* determine whether internal uart is on */ if (IS_ENABLED(CONFIG_INTERNAL_UART)) gnvs->iuart_en = 1; else gnvs->iuart_en = 0; return 0; } /* * The following two routines are called at a very early stage, even before * FSP 2nd phase API fsp_init() is called. Registers off ACPI_BASE_ADDRESS * and PMC_BASE_ADDRESS are accessed, so we need make sure the base addresses * of these two blocks are programmed by either U-Boot or FSP. * * It has been verified that 1st phase API (see arch/x86/lib/fsp1/fsp_car.S) * on Intel BayTrail SoC already initializes these two base addresses so * we are safe to access these registers here. */ enum acpi_sleep_state chipset_prev_sleep_state(void) { u32 pm1_sts; u32 pm1_cnt; u32 gen_pmcon1; enum acpi_sleep_state prev_sleep_state = ACPI_S0; /* Read Power State */ pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); gen_pmcon1 = readl(PMC_BASE_ADDRESS + GEN_PMCON1); debug("PM1_STS = 0x%x PM1_CNT = 0x%x GEN_PMCON1 = 0x%x\n", pm1_sts, pm1_cnt, gen_pmcon1); if (pm1_sts & WAK_STS) prev_sleep_state = acpi_sleep_from_pm1(pm1_cnt); if (gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) prev_sleep_state = ACPI_S5; return prev_sleep_state; } void chipset_clear_sleep_state(void) { u32 pm1_cnt; pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); outl(pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT); }