Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
| 2 | /* |
| 3 | * Copyright 2019 Google LLC |
| 4 | * Written by Simon Glass <sjg@chromium.org> |
| 5 | */ |
| 6 | |
| 7 | #include <common.h> |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 8 | #include <binman.h> |
| 9 | #include <dm.h> |
| 10 | #include <irq.h> |
Simon Glass | 9bc1564 | 2020-02-03 07:36:16 -0700 | [diff] [blame] | 11 | #include <malloc.h> |
Simon Glass | 5046109 | 2020-04-08 16:57:35 -0600 | [diff] [blame] | 12 | #include <acpi/acpi_s3.h> |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 13 | #include <asm/intel_pinctrl.h> |
| 14 | #include <asm/io.h> |
| 15 | #include <asm/intel_regs.h> |
| 16 | #include <asm/msr.h> |
| 17 | #include <asm/msr-index.h> |
| 18 | #include <asm/pci.h> |
| 19 | #include <asm/arch/cpu.h> |
| 20 | #include <asm/arch/systemagent.h> |
| 21 | #include <asm/arch/fsp/fsp_configs.h> |
| 22 | #include <asm/arch/fsp/fsp_s_upd.h> |
| 23 | |
| 24 | #define PCH_P2SB_E0 0xe0 |
| 25 | #define HIDE_BIT BIT(0) |
| 26 | |
| 27 | #define INTEL_GSPI_MAX 3 |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 28 | #define MAX_USB2_PORTS 8 |
| 29 | |
| 30 | enum { |
| 31 | CHIPSET_LOCKDOWN_FSP = 0, /* FSP handles locking per UPDs */ |
| 32 | CHIPSET_LOCKDOWN_COREBOOT, /* coreboot handles locking */ |
| 33 | }; |
| 34 | |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 35 | /* Serial IRQ control. SERIRQ_QUIET is the default (0) */ |
| 36 | enum serirq_mode { |
| 37 | SERIRQ_QUIET, |
| 38 | SERIRQ_CONTINUOUS, |
| 39 | SERIRQ_OFF, |
| 40 | }; |
| 41 | |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 42 | struct gspi_cfg { |
| 43 | /* Bus speed in MHz */ |
| 44 | u32 speed_mhz; |
| 45 | /* Bus should be enabled prior to ramstage with temporary base */ |
| 46 | u8 early_init; |
| 47 | }; |
| 48 | |
| 49 | /* |
| 50 | * This structure will hold data required by common blocks. |
| 51 | * These are soc specific configurations which will be filled by soc. |
| 52 | * We'll fill this structure once during init and use the data in common block. |
| 53 | */ |
| 54 | struct soc_intel_common_config { |
| 55 | int chipset_lockdown; |
| 56 | struct gspi_cfg gspi[INTEL_GSPI_MAX]; |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 57 | }; |
| 58 | |
| 59 | enum pnp_settings { |
| 60 | PNP_PERF, |
| 61 | PNP_POWER, |
| 62 | PNP_PERF_POWER, |
| 63 | }; |
| 64 | |
| 65 | struct usb2_eye_per_port { |
| 66 | u8 per_port_tx_pe_half; |
| 67 | u8 per_port_pe_txi_set; |
| 68 | u8 per_port_txi_set; |
| 69 | u8 hs_skew_sel; |
| 70 | u8 usb_tx_emphasis_en; |
| 71 | u8 per_port_rxi_set; |
| 72 | u8 hs_npre_drv_sel; |
| 73 | u8 override_en; |
| 74 | }; |
| 75 | |
| 76 | struct apl_config { |
| 77 | /* Common structure containing soc config data required by common code*/ |
| 78 | struct soc_intel_common_config common_soc_config; |
| 79 | |
| 80 | /* |
| 81 | * Mapping from PCIe root port to CLKREQ input on the SOC. The SOC has |
| 82 | * four CLKREQ inputs, but six root ports. Root ports without an |
| 83 | * associated CLKREQ signal must be marked with "CLKREQ_DISABLED" |
| 84 | */ |
| 85 | u8 pcie_rp_clkreq_pin[MAX_PCIE_PORTS]; |
| 86 | |
| 87 | /* Enable/disable hot-plug for root ports (0 = disable, 1 = enable) */ |
| 88 | u8 pcie_rp_hotplug_enable[MAX_PCIE_PORTS]; |
| 89 | |
| 90 | /* De-emphasis enable configuration for each PCIe root port */ |
| 91 | u8 pcie_rp_deemphasis_enable[MAX_PCIE_PORTS]; |
| 92 | |
| 93 | /* |
| 94 | * [14:8] DDR mode Number of dealy elements.Each = 125pSec. |
| 95 | * [6:0] SDR mode Number of dealy elements.Each = 125pSec. |
| 96 | */ |
| 97 | u32 emmc_tx_cmd_cntl; |
| 98 | |
| 99 | /* |
| 100 | * [14:8] HS400 mode Number of dealy elements.Each = 125pSec. |
| 101 | * [6:0] SDR104/HS200 mode Number of dealy elements.Each = 125pSec. |
| 102 | */ |
| 103 | u32 emmc_tx_data_cntl1; |
| 104 | |
| 105 | /* |
| 106 | * [30:24] SDR50 mode Number of dealy elements.Each = 125pSec. |
| 107 | * [22:16] DDR50 mode Number of dealy elements.Each = 125pSec. |
| 108 | * [14:8] SDR25/HS50 mode Number of dealy elements.Each = 125pSec. |
| 109 | * [6:0] SDR12/Compatibility mode Number of dealy elements. |
| 110 | * Each = 125pSec. |
| 111 | */ |
| 112 | u32 emmc_tx_data_cntl2; |
| 113 | |
| 114 | /* |
| 115 | * [30:24] SDR50 mode Number of dealy elements.Each = 125pSec. |
| 116 | * [22:16] DDR50 mode Number of dealy elements.Each = 125pSec. |
| 117 | * [14:8] SDR25/HS50 mode Number of dealy elements.Each = 125pSec. |
| 118 | * [6:0] SDR12/Compatibility mode Number of dealy elements. |
| 119 | * Each = 125pSec. |
| 120 | */ |
| 121 | u32 emmc_rx_cmd_data_cntl1; |
| 122 | |
| 123 | /* |
| 124 | * [14:8] HS400 mode 1 Number of dealy elements.Each = 125pSec. |
| 125 | * [6:0] HS400 mode 2 Number of dealy elements.Each = 125pSec. |
| 126 | */ |
| 127 | u32 emmc_rx_strobe_cntl; |
| 128 | |
| 129 | /* |
| 130 | * [13:8] Auto Tuning mode Number of dealy elements.Each = 125pSec. |
| 131 | * [6:0] SDR104/HS200 Number of dealy elements.Each = 125pSec. |
| 132 | */ |
| 133 | u32 emmc_rx_cmd_data_cntl2; |
| 134 | |
| 135 | /* Select the eMMC max speed allowed */ |
| 136 | u32 emmc_host_max_speed; |
| 137 | |
| 138 | /* Specifies on which IRQ the SCI will internally appear */ |
| 139 | u32 sci_irq; |
| 140 | |
| 141 | /* Configure serial IRQ (SERIRQ) line */ |
| 142 | enum serirq_mode serirq_mode; |
| 143 | |
| 144 | /* Configure LPSS S0ix Enable */ |
| 145 | bool lpss_s0ix_enable; |
| 146 | |
| 147 | /* Enable DPTF support */ |
| 148 | bool dptf_enable; |
| 149 | |
| 150 | /* TCC activation offset value in degrees Celsius */ |
| 151 | int tcc_offset; |
| 152 | |
| 153 | /* |
| 154 | * Configure Audio clk gate and power gate |
| 155 | * IOSF-SB port ID 92 offset 0x530 [5] and [3] |
| 156 | */ |
| 157 | bool hdaudio_clk_gate_enable; |
| 158 | bool hdaudio_pwr_gate_enable; |
| 159 | bool hdaudio_bios_config_lockdown; |
| 160 | |
| 161 | /* SLP S3 minimum assertion width */ |
| 162 | int slp_s3_assertion_width_usecs; |
| 163 | |
| 164 | /* GPIO pin for PERST_0 */ |
| 165 | u32 prt0_gpio; |
| 166 | |
| 167 | /* USB2 eye diagram settings per port */ |
| 168 | struct usb2_eye_per_port usb2eye[MAX_USB2_PORTS]; |
| 169 | |
| 170 | /* GPIO SD card detect pin */ |
| 171 | unsigned int sdcard_cd_gpio; |
| 172 | |
| 173 | /* |
| 174 | * PRMRR size setting with three options |
| 175 | * 0x02000000 - 32MiB |
| 176 | * 0x04000000 - 64MiB |
| 177 | * 0x08000000 - 128MiB |
| 178 | */ |
| 179 | u32 PrmrrSize; |
| 180 | |
| 181 | /* |
| 182 | * Enable SGX feature. |
| 183 | * Enabling SGX feature is 2 step process, |
| 184 | * (1) set sgx_enable = 1 |
| 185 | * (2) set PrmrrSize to supported size |
| 186 | */ |
| 187 | bool sgx_enable; |
| 188 | |
| 189 | /* |
| 190 | * Select PNP Settings. |
| 191 | * (0) Performance, |
| 192 | * (1) Power |
| 193 | * (2) Power & Performance |
| 194 | */ |
| 195 | enum pnp_settings pnp_settings; |
| 196 | |
| 197 | /* |
| 198 | * PMIC PCH_PWROK delay configuration - IPC Configuration |
| 199 | * Upd for changing PCH_PWROK delay configuration : I2C_Slave_Address |
| 200 | * (31:24) + Register_Offset (23:16) + OR Value (15:8) + AND Value (7:0) |
| 201 | */ |
| 202 | u32 pmic_pmc_ipc_ctrl; |
| 203 | |
| 204 | /* |
| 205 | * Options to disable XHCI Link Compliance Mode. Default is FALSE to not |
| 206 | * disable Compliance Mode. Set TRUE to disable Compliance Mode. |
| 207 | * 0:FALSE(Default), 1:True. |
| 208 | */ |
| 209 | bool disable_compliance_mode; |
| 210 | |
| 211 | /* |
| 212 | * Options to change USB3 ModPhy setting for the Integrated Filter (IF) |
| 213 | * value. Default is 0 to not changing default IF value (0x12). Set |
| 214 | * value with the range from 0x01 to 0xff to change IF value. |
| 215 | */ |
| 216 | u32 mod_phy_if_value; |
| 217 | |
| 218 | /* |
| 219 | * Options to bump USB3 LDO voltage. Default is FALSE to not increasing |
| 220 | * LDO voltage. Set TRUE to increase LDO voltage with 40mV. |
| 221 | * 0:FALSE (default), 1:True. |
| 222 | */ |
| 223 | bool mod_phy_voltage_bump; |
| 224 | |
| 225 | /* |
| 226 | * Options to adjust PMIC Vdd2 voltage. Default is 0 to not adjusting |
| 227 | * the PMIC Vdd2 default voltage 1.20v. Upd for changing Vdd2 Voltage |
| 228 | * configuration: I2C_Slave_Address (31:23) + Register_Offset (23:16) |
| 229 | * + OR Value (15:8) + AND Value (7:0) through BUCK5_VID[3:2]: |
| 230 | * 00=1.10v, 01=1.15v, 10=1.24v, 11=1.20v (default). |
| 231 | */ |
| 232 | u32 pmic_vdd2_voltage; |
| 233 | |
| 234 | /* Option to enable VTD feature */ |
| 235 | bool enable_vtd; |
| 236 | }; |
| 237 | |
| 238 | static int get_config(struct udevice *dev, struct apl_config *apl) |
| 239 | { |
| 240 | const u8 *ptr; |
| 241 | ofnode node; |
| 242 | u32 emmc[4]; |
| 243 | int ret; |
| 244 | |
| 245 | memset(apl, '\0', sizeof(*apl)); |
| 246 | |
| 247 | node = dev_read_subnode(dev, "fsp-s"); |
| 248 | if (!ofnode_valid(node)) |
| 249 | return log_msg_ret("fsp-s settings", -ENOENT); |
| 250 | |
| 251 | ptr = ofnode_read_u8_array_ptr(node, "pcie-rp-clkreq-pin", |
| 252 | MAX_PCIE_PORTS); |
| 253 | if (!ptr) |
| 254 | return log_msg_ret("pcie-rp-clkreq-pin", -EINVAL); |
| 255 | memcpy(apl->pcie_rp_clkreq_pin, ptr, MAX_PCIE_PORTS); |
| 256 | |
| 257 | ret = ofnode_read_u32(node, "prt0-gpio", &apl->prt0_gpio); |
| 258 | if (ret) |
| 259 | return log_msg_ret("prt0-gpio", ret); |
| 260 | ret = ofnode_read_u32(node, "sdcard-cd-gpio", &apl->sdcard_cd_gpio); |
| 261 | if (ret) |
| 262 | return log_msg_ret("sdcard-cd-gpio", ret); |
| 263 | |
| 264 | ret = ofnode_read_u32_array(node, "emmc", emmc, ARRAY_SIZE(emmc)); |
| 265 | if (ret) |
| 266 | return log_msg_ret("emmc", ret); |
| 267 | apl->emmc_tx_data_cntl1 = emmc[0]; |
| 268 | apl->emmc_tx_data_cntl2 = emmc[1]; |
| 269 | apl->emmc_rx_cmd_data_cntl1 = emmc[2]; |
| 270 | apl->emmc_rx_cmd_data_cntl2 = emmc[3]; |
| 271 | |
| 272 | apl->dptf_enable = ofnode_read_bool(node, "dptf-enable"); |
| 273 | |
| 274 | apl->hdaudio_clk_gate_enable = ofnode_read_bool(node, |
| 275 | "hdaudio-clk-gate-enable"); |
| 276 | apl->hdaudio_pwr_gate_enable = ofnode_read_bool(node, |
| 277 | "hdaudio-pwr-gate-enable"); |
| 278 | apl->hdaudio_bios_config_lockdown = ofnode_read_bool(node, |
| 279 | "hdaudio-bios-config-lockdown"); |
| 280 | apl->lpss_s0ix_enable = ofnode_read_bool(node, "lpss-s0ix-enable"); |
| 281 | |
| 282 | /* Santa */ |
| 283 | apl->usb2eye[1].per_port_pe_txi_set = 7; |
| 284 | apl->usb2eye[1].per_port_txi_set = 2; |
| 285 | |
| 286 | return 0; |
| 287 | } |
| 288 | |
| 289 | static void apl_fsp_silicon_init_params_cb(struct apl_config *apl, |
| 290 | struct fsp_s_config *cfg) |
| 291 | { |
| 292 | u8 port; |
| 293 | |
| 294 | for (port = 0; port < MAX_USB2_PORTS; port++) { |
| 295 | if (apl->usb2eye[port].per_port_tx_pe_half) |
| 296 | cfg->port_usb20_per_port_tx_pe_half[port] = |
| 297 | apl->usb2eye[port].per_port_tx_pe_half; |
| 298 | |
| 299 | if (apl->usb2eye[port].per_port_pe_txi_set) |
| 300 | cfg->port_usb20_per_port_pe_txi_set[port] = |
| 301 | apl->usb2eye[port].per_port_pe_txi_set; |
| 302 | |
| 303 | if (apl->usb2eye[port].per_port_txi_set) |
| 304 | cfg->port_usb20_per_port_txi_set[port] = |
| 305 | apl->usb2eye[port].per_port_txi_set; |
| 306 | |
| 307 | if (apl->usb2eye[port].hs_skew_sel) |
| 308 | cfg->port_usb20_hs_skew_sel[port] = |
| 309 | apl->usb2eye[port].hs_skew_sel; |
| 310 | |
| 311 | if (apl->usb2eye[port].usb_tx_emphasis_en) |
| 312 | cfg->port_usb20_i_usb_tx_emphasis_en[port] = |
| 313 | apl->usb2eye[port].usb_tx_emphasis_en; |
| 314 | |
| 315 | if (apl->usb2eye[port].per_port_rxi_set) |
| 316 | cfg->port_usb20_per_port_rxi_set[port] = |
| 317 | apl->usb2eye[port].per_port_rxi_set; |
| 318 | |
| 319 | if (apl->usb2eye[port].hs_npre_drv_sel) |
| 320 | cfg->port_usb20_hs_npre_drv_sel[port] = |
| 321 | apl->usb2eye[port].hs_npre_drv_sel; |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | int fsps_update_config(struct udevice *dev, ulong rom_offset, |
| 326 | struct fsps_upd *upd) |
| 327 | { |
| 328 | struct fsp_s_config *cfg = &upd->config; |
| 329 | struct apl_config *apl; |
| 330 | struct binman_entry vbt; |
| 331 | void *buf; |
| 332 | int ret; |
| 333 | |
| 334 | ret = binman_entry_find("intel-vbt", &vbt); |
| 335 | if (ret) |
| 336 | return log_msg_ret("Cannot find VBT", ret); |
| 337 | vbt.image_pos += rom_offset; |
| 338 | buf = malloc(vbt.size); |
| 339 | if (!buf) |
| 340 | return log_msg_ret("Alloc VBT", -ENOMEM); |
| 341 | |
| 342 | /* |
| 343 | * Load VBT before devicetree-specific config. This only supports |
| 344 | * memory-mapped SPI at present. |
| 345 | */ |
| 346 | bootstage_start(BOOTSTAGE_ID_ACCUM_MMAP_SPI, "mmap_spi"); |
| 347 | memcpy(buf, (void *)vbt.image_pos, vbt.size); |
| 348 | bootstage_accum(BOOTSTAGE_ID_ACCUM_MMAP_SPI); |
| 349 | if (*(u32 *)buf != VBT_SIGNATURE) |
| 350 | return log_msg_ret("VBT signature", -EINVAL); |
| 351 | cfg->graphics_config_ptr = (ulong)buf; |
| 352 | |
| 353 | apl = malloc(sizeof(*apl)); |
| 354 | if (!apl) |
| 355 | return log_msg_ret("config", -ENOMEM); |
| 356 | get_config(dev, apl); |
| 357 | |
| 358 | cfg->ish_enable = 0; |
| 359 | cfg->enable_sata = 0; |
| 360 | cfg->pcie_root_port_en[2] = 0; |
| 361 | cfg->pcie_rp_hot_plug[2] = 0; |
| 362 | cfg->pcie_root_port_en[3] = 0; |
| 363 | cfg->pcie_rp_hot_plug[3] = 0; |
| 364 | cfg->pcie_root_port_en[4] = 0; |
| 365 | cfg->pcie_rp_hot_plug[4] = 0; |
| 366 | cfg->pcie_root_port_en[5] = 0; |
| 367 | cfg->pcie_rp_hot_plug[5] = 0; |
| 368 | cfg->pcie_root_port_en[1] = 0; |
| 369 | cfg->pcie_rp_hot_plug[1] = 0; |
| 370 | cfg->usb_otg = 0; |
| 371 | cfg->i2c6_enable = 0; |
| 372 | cfg->i2c7_enable = 0; |
| 373 | cfg->hsuart3_enable = 0; |
| 374 | cfg->spi1_enable = 0; |
| 375 | cfg->spi2_enable = 0; |
| 376 | cfg->sdio_enabled = 0; |
| 377 | |
| 378 | memcpy(cfg->pcie_rp_clk_req_number, apl->pcie_rp_clkreq_pin, |
| 379 | sizeof(cfg->pcie_rp_clk_req_number)); |
| 380 | |
| 381 | memcpy(cfg->pcie_rp_hot_plug, apl->pcie_rp_hotplug_enable, |
| 382 | sizeof(cfg->pcie_rp_hot_plug)); |
| 383 | |
| 384 | switch (apl->serirq_mode) { |
| 385 | case SERIRQ_QUIET: |
| 386 | cfg->sirq_enable = 1; |
| 387 | cfg->sirq_mode = 0; |
| 388 | break; |
| 389 | case SERIRQ_CONTINUOUS: |
| 390 | cfg->sirq_enable = 1; |
| 391 | cfg->sirq_mode = 1; |
| 392 | break; |
| 393 | case SERIRQ_OFF: |
| 394 | default: |
| 395 | cfg->sirq_enable = 0; |
| 396 | break; |
| 397 | } |
| 398 | |
| 399 | if (apl->emmc_tx_cmd_cntl) |
| 400 | cfg->emmc_tx_cmd_cntl = apl->emmc_tx_cmd_cntl; |
| 401 | if (apl->emmc_tx_data_cntl1) |
| 402 | cfg->emmc_tx_data_cntl1 = apl->emmc_tx_data_cntl1; |
| 403 | if (apl->emmc_tx_data_cntl2) |
| 404 | cfg->emmc_tx_data_cntl2 = apl->emmc_tx_data_cntl2; |
| 405 | if (apl->emmc_rx_cmd_data_cntl1) |
| 406 | cfg->emmc_rx_cmd_data_cntl1 = apl->emmc_rx_cmd_data_cntl1; |
| 407 | if (apl->emmc_rx_strobe_cntl) |
| 408 | cfg->emmc_rx_strobe_cntl = apl->emmc_rx_strobe_cntl; |
| 409 | if (apl->emmc_rx_cmd_data_cntl2) |
| 410 | cfg->emmc_rx_cmd_data_cntl2 = apl->emmc_rx_cmd_data_cntl2; |
| 411 | if (apl->emmc_host_max_speed) |
| 412 | cfg->e_mmc_host_max_speed = apl->emmc_host_max_speed; |
| 413 | |
| 414 | cfg->lpss_s0ix_enable = apl->lpss_s0ix_enable; |
| 415 | |
| 416 | cfg->skip_mp_init = true; |
| 417 | |
| 418 | /* Disable setting of EISS bit in FSP */ |
| 419 | cfg->spi_eiss = 0; |
| 420 | |
| 421 | /* Disable FSP from locking access to the RTC NVRAM */ |
| 422 | cfg->rtc_lock = 0; |
| 423 | |
| 424 | /* Enable Audio clk gate and power gate */ |
| 425 | cfg->hd_audio_clk_gate = apl->hdaudio_clk_gate_enable; |
| 426 | cfg->hd_audio_pwr_gate = apl->hdaudio_pwr_gate_enable; |
| 427 | /* Bios config lockdown Audio clk and power gate */ |
| 428 | cfg->bios_cfg_lock_down = apl->hdaudio_bios_config_lockdown; |
| 429 | apl_fsp_silicon_init_params_cb(apl, cfg); |
| 430 | |
| 431 | cfg->usb_otg = true; |
| 432 | cfg->vtd_enable = apl->enable_vtd; |
| 433 | |
| 434 | return 0; |
| 435 | } |
| 436 | |
| 437 | static void p2sb_set_hide_bit(pci_dev_t dev, int hide) |
| 438 | { |
| 439 | pci_x86_clrset_config(dev, PCH_P2SB_E0 + 1, HIDE_BIT, |
| 440 | hide ? HIDE_BIT : 0, PCI_SIZE_8); |
| 441 | } |
| 442 | |
| 443 | /* Configure package power limits */ |
| 444 | static int set_power_limits(struct udevice *dev) |
| 445 | { |
| 446 | msr_t rapl_msr_reg, limit; |
| 447 | u32 power_unit; |
| 448 | u32 tdp, min_power, max_power; |
| 449 | u32 pl2_val; |
| 450 | u32 override_tdp[2]; |
| 451 | int ret; |
| 452 | |
| 453 | /* Get units */ |
| 454 | rapl_msr_reg = msr_read(MSR_PKG_POWER_SKU_UNIT); |
| 455 | power_unit = 1 << (rapl_msr_reg.lo & 0xf); |
| 456 | |
| 457 | /* Get power defaults for this SKU */ |
| 458 | rapl_msr_reg = msr_read(MSR_PKG_POWER_SKU); |
| 459 | tdp = rapl_msr_reg.lo & PKG_POWER_LIMIT_MASK; |
| 460 | pl2_val = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK; |
| 461 | min_power = (rapl_msr_reg.lo >> 16) & PKG_POWER_LIMIT_MASK; |
| 462 | max_power = rapl_msr_reg.hi & PKG_POWER_LIMIT_MASK; |
| 463 | |
| 464 | if (min_power > 0 && tdp < min_power) |
| 465 | tdp = min_power; |
| 466 | |
| 467 | if (max_power > 0 && tdp > max_power) |
| 468 | tdp = max_power; |
| 469 | |
| 470 | ret = dev_read_u32_array(dev, "tdp-pl-override-mw", override_tdp, |
| 471 | ARRAY_SIZE(override_tdp)); |
| 472 | if (ret) |
| 473 | return log_msg_ret("tdp-pl-override-mw", ret); |
| 474 | |
| 475 | /* Set PL1 override value */ |
| 476 | if (override_tdp[0]) |
| 477 | tdp = override_tdp[0] * power_unit / 1000; |
| 478 | |
| 479 | /* Set PL2 override value */ |
| 480 | if (override_tdp[1]) |
| 481 | pl2_val = override_tdp[1] * power_unit / 1000; |
| 482 | |
| 483 | /* Set long term power limit to TDP */ |
| 484 | limit.lo = tdp & PKG_POWER_LIMIT_MASK; |
| 485 | /* Set PL1 Pkg Power clamp bit */ |
| 486 | limit.lo |= PKG_POWER_LIMIT_CLAMP; |
| 487 | |
| 488 | limit.lo |= PKG_POWER_LIMIT_EN; |
| 489 | limit.lo |= (MB_POWER_LIMIT1_TIME_DEFAULT & |
| 490 | PKG_POWER_LIMIT_TIME_MASK) << PKG_POWER_LIMIT_TIME_SHIFT; |
| 491 | |
| 492 | /* Set short term power limit PL2 */ |
| 493 | limit.hi = pl2_val & PKG_POWER_LIMIT_MASK; |
| 494 | limit.hi |= PKG_POWER_LIMIT_EN; |
| 495 | |
| 496 | /* Program package power limits in RAPL MSR */ |
| 497 | msr_write(MSR_PKG_POWER_LIMIT, limit); |
| 498 | log_info("RAPL PL1 %d.%dW\n", tdp / power_unit, |
| 499 | 100 * (tdp % power_unit) / power_unit); |
| 500 | log_info("RAPL PL2 %d.%dW\n", pl2_val / power_unit, |
| 501 | 100 * (pl2_val % power_unit) / power_unit); |
| 502 | |
| 503 | /* |
| 504 | * Sett RAPL MMIO register for Power limits. RAPL driver is using MSR |
| 505 | * instead of MMIO, so disable LIMIT_EN bit for MMIO |
| 506 | */ |
| 507 | writel(limit.lo & ~PKG_POWER_LIMIT_EN, MCHBAR_REG(MCHBAR_RAPL_PPL)); |
| 508 | writel(limit.hi & ~PKG_POWER_LIMIT_EN, MCHBAR_REG(MCHBAR_RAPL_PPL + 4)); |
| 509 | |
| 510 | return 0; |
| 511 | } |
| 512 | |
| 513 | int p2sb_unhide(void) |
| 514 | { |
| 515 | pci_dev_t dev = PCI_BDF(0, 0xd, 0); |
| 516 | ulong val; |
| 517 | |
| 518 | p2sb_set_hide_bit(dev, 0); |
| 519 | |
| 520 | pci_x86_read_config(dev, PCI_VENDOR_ID, &val, PCI_SIZE_16); |
| 521 | |
| 522 | if (val != PCI_VENDOR_ID_INTEL) |
| 523 | return log_msg_ret("p2sb unhide", -EIO); |
| 524 | |
| 525 | return 0; |
| 526 | } |
| 527 | |
| 528 | /* Overwrites the SCI IRQ if another IRQ number is given by device tree */ |
| 529 | static void set_sci_irq(void) |
| 530 | { |
| 531 | /* Skip this for now */ |
| 532 | } |
| 533 | |
| 534 | int arch_fsps_preinit(void) |
| 535 | { |
| 536 | struct udevice *itss; |
| 537 | int ret; |
| 538 | |
Simon Glass | 21bb12a | 2020-02-06 09:54:58 -0700 | [diff] [blame] | 539 | ret = irq_first_device_type(X86_IRQT_ITSS, &itss); |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 540 | if (ret) |
| 541 | return log_msg_ret("no itss", ret); |
| 542 | /* |
| 543 | * Snapshot the current GPIO IRQ polarities. FSP is setting a default |
| 544 | * policy that doesn't honour boards' requirements |
| 545 | */ |
| 546 | irq_snapshot_polarities(itss); |
| 547 | |
| 548 | /* |
| 549 | * Clear the GPI interrupt status and enable registers. These |
| 550 | * registers do not get reset to default state when booting from S5. |
| 551 | */ |
| 552 | ret = pinctrl_gpi_clear_int_cfg(); |
| 553 | if (ret) |
| 554 | return log_msg_ret("gpi_clear", ret); |
| 555 | |
| 556 | return 0; |
| 557 | } |
| 558 | |
| 559 | int arch_fsp_init_r(void) |
| 560 | { |
| 561 | #ifdef CONFIG_HAVE_ACPI_RESUME |
| 562 | bool s3wake = gd->arch.prev_sleep_state == ACPI_S3; |
| 563 | #else |
| 564 | bool s3wake = false; |
| 565 | #endif |
| 566 | struct udevice *dev, *itss; |
| 567 | int ret; |
| 568 | |
Simon Glass | 8eac3f3 | 2020-04-26 09:12:54 -0600 | [diff] [blame^] | 569 | if (!ll_boot_init()) |
| 570 | return 0; |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 571 | /* |
| 572 | * This must be called before any devices are probed. Put any probing |
| 573 | * into arch_fsps_preinit() above. |
| 574 | * |
| 575 | * We don't use CONFIG_APL_BOOT_FROM_FAST_SPI_FLASH here since it will |
| 576 | * force PCI to be probed. |
| 577 | */ |
| 578 | ret = fsp_silicon_init(s3wake, false); |
| 579 | if (ret) |
| 580 | return ret; |
| 581 | |
Simon Glass | 21bb12a | 2020-02-06 09:54:58 -0700 | [diff] [blame] | 582 | ret = irq_first_device_type(X86_IRQT_ITSS, &itss); |
Simon Glass | 42bf7db | 2019-12-08 17:40:19 -0700 | [diff] [blame] | 583 | if (ret) |
| 584 | return log_msg_ret("no itss", ret); |
| 585 | /* Restore GPIO IRQ polarities back to previous settings */ |
| 586 | irq_restore_polarities(itss); |
| 587 | |
| 588 | /* soc_init() */ |
| 589 | ret = p2sb_unhide(); |
| 590 | if (ret) |
| 591 | return log_msg_ret("unhide p2sb", ret); |
| 592 | |
| 593 | /* Set RAPL MSR for Package power limits*/ |
| 594 | ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev); |
| 595 | if (ret) |
| 596 | return log_msg_ret("Cannot get northbridge", ret); |
| 597 | set_power_limits(dev); |
| 598 | |
| 599 | /* |
| 600 | * FSP-S routes SCI to IRQ 9. With the help of this function you can |
| 601 | * select another IRQ for SCI. |
| 602 | */ |
| 603 | set_sci_irq(); |
| 604 | |
| 605 | return 0; |
| 606 | } |