Karthik Ramasubramanian has submitted this change. ( https://review.coreboot.org/c/coreboot/+/83752?usp=email )
Change subject: mb/google/brox: Fix booting to kernel without battery ......................................................................
mb/google/brox: Fix booting to kernel without battery
When battery is disconnected and only adaptor is connected higher PL2 power draw causes cpu brown out and system does not boot to kernel. To avoid this set Boot frequency UPD to 1. Reduce PL4 value to overcome power spikes from SoC during boot. Remove Psys implementation as it impacts active state platform performance.
BUG=b:335046538,b:329722827 BRANCH=None TEST=Able to successfully boot on 3 different Brox proto2 SKU1 and SKU2 boards with 65W, 45W and 30W adaptors for 3 iterations of cold boot. Change-Id: I58e136c607ea9290ecac0cee453d6632760a6433 Signed-off-by: Sowmya Aralguppe sowmya.aralguppe@intel.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/83752 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Subrata Banik subratabanik@google.com Reviewed-by: Karthik Ramasubramanian kramasub@google.com --- M src/mainboard/google/brox/Kconfig M src/mainboard/google/brox/romstage.c M src/mainboard/google/brox/variants/baseboard/brox/ramstage.c M src/mainboard/google/brox/variants/brox/ramstage.c M src/soc/intel/alderlake/chip.h 5 files changed, 59 insertions(+), 23 deletions(-)
Approvals: Karthik Ramasubramanian: Looks good to me, approved Subrata Banik: Looks good to me, approved build bot (Jenkins): Verified
diff --git a/src/mainboard/google/brox/Kconfig b/src/mainboard/google/brox/Kconfig index a1d284b..8fd43f4 100644 --- a/src/mainboard/google/brox/Kconfig +++ b/src/mainboard/google/brox/Kconfig @@ -117,6 +117,19 @@ hex default 0x4 if BOARD_GOOGLE_BASEBOARD_BROX
+config PL4_LIMIT_FOR_CRITICAL_BAT_BOOT + int + default 9 + help + Select this if the variant has to boot even with low battery, critical battery + threshold, or when the battery is physically disconnected. PL4, which stands for + Processor Instantaneous Power or Absolute Peak Power, controls the highest power draw + from the processor at any given moment within the Pl1Tau duration. Therefore, PL4 + acts as a failsafe mechanism to set an upper threshold limit for the processor's + instantaneous power draw. For a 30W adapter, the maximum peak power is set at 9 + watts, which is 30W multiplied by 32% efficiency. This default pl4 value is set for + 30W or any higher adapter rating, such as 45W or 65W. + config DRIVER_TPM_I2C_ADDR hex default 0x50 diff --git a/src/mainboard/google/brox/romstage.c b/src/mainboard/google/brox/romstage.c index 4e88eca..ced9184 100644 --- a/src/mainboard/google/brox/romstage.c +++ b/src/mainboard/google/brox/romstage.c @@ -2,6 +2,7 @@
#include <baseboard/gpio.h> #include <baseboard/variants.h> +#include <ec/google/chromeec/ec.h> #include <fsp/api.h> #include <gpio.h> #include <soc/romstage.h> @@ -19,6 +20,14 @@ const struct pad_config *pads; size_t pads_num;
+ /* If battery is not present - Boot with maximum non-turbo frequency */ + if (CONFIG(EC_GOOGLE_CHROMEEC) && + !google_chromeec_is_battery_present_and_above_critical_threshold()) { + FSP_M_CONFIG *mem_cfg = &memupd->FspmConfig; + mem_cfg->BootFrequency = MAX_NONTURBO_PERFORMANCE; + printk(BIOS_DEBUG, "Boot Frequency is set to %u\n", mem_cfg->BootFrequency); + } + memcfg_init(memupd, mem_config, &spd_info, half_populated);
pads = variant_romstage_gpio_table(&pads_num); diff --git a/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c b/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c index 038255f..85c3c48 100644 --- a/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c +++ b/src/mainboard/google/brox/variants/baseboard/brox/ramstage.c @@ -42,13 +42,27 @@ }
if (i == num_entries) { - printk(BIOS_ERR, "Cannot find correct brox sku index (mchid = %u).\n", mchid); + printk(BIOS_ERR, "Cannot find brox sku index (mchid = %u)\n", mchid); return false; }
return true; }
+static void variant_pl4_override(struct soc_power_limits_config *config, + const struct cpu_power_limits *limits, size_t brox_idx) +{ + if (!config->tdp_pl4) + return; + + /* limiting PL4 value for battery disconnected or below critical threshold */ + if (CONFIG_PL4_LIMIT_FOR_CRITICAL_BAT_BOOT && + (!google_chromeec_is_battery_present_and_above_critical_threshold())) + config->tdp_pl4 = CONFIG_PL4_LIMIT_FOR_CRITICAL_BAT_BOOT; + else + config->tdp_pl4 = DIV_ROUND_UP(limits[brox_idx].pl4_power, MILLIWATTS_TO_WATTS); +} + void variant_update_power_limits(const struct cpu_power_limits *limits, size_t num_entries) { const struct device *policy_dev; @@ -61,30 +75,33 @@ if (!num_entries) return;
- policy_dev = DEV_PTR(dptf_policy); - if (!policy_dev) - return; - if (!get_sku_index(limits, num_entries, &intel_idx, &brox_idx)) return;
- config = policy_dev->chip_info; - settings = &config->controls.power_limits; conf = config_of_soc(); soc_config = &conf->power_limits_config[intel_idx]; + variant_pl4_override(soc_config, limits, brox_idx); + + policy_dev = DEV_PTR(dptf_policy); + if (!policy_dev) { + printk(BIOS_INFO, "DPTF policy not set\n"); + return; + } + config = policy_dev->chip_info; + settings = &config->controls.power_limits; settings->pl1.min_power = limits[brox_idx].pl1_min_power; settings->pl1.max_power = limits[brox_idx].pl1_max_power; settings->pl2.min_power = limits[brox_idx].pl2_min_power; settings->pl2.max_power = limits[brox_idx].pl2_max_power;
if (soc_config->tdp_pl2_override != 0) { - settings->pl2.max_power = soc_config->tdp_pl2_override * 1000; + settings->pl2.max_power = soc_config->tdp_pl2_override * MILLIWATTS_TO_WATTS; settings->pl2.min_power = settings->pl2.max_power; }
- if (soc_config->tdp_pl4 == 0) - soc_config->tdp_pl4 = DIV_ROUND_UP(limits[brox_idx].pl4_power, - MILLIWATTS_TO_WATTS); + printk(BIOS_INFO, "Overriding power limits PL1 (%u, %u) PL2 (%u, %u) PL4 (%u)\n", + settings->pl1.min_power, settings->pl1.max_power, settings->pl2.min_power, + settings->pl2.max_power, soc_config->tdp_pl4); }
/* @@ -138,7 +155,8 @@ watts = ((u32)current_ma * volts_mv) / 1000000; } /* If battery is present and has enough charge, add discharge rate */ - if (CONFIG(EC_GOOGLE_CHROMEEC) && google_chromeec_is_battery_present_and_above_critical_threshold()) { + if (CONFIG(EC_GOOGLE_CHROMEEC) && + google_chromeec_is_battery_present_and_above_critical_threshold()) { watts += 65; }
diff --git a/src/mainboard/google/brox/variants/brox/ramstage.c b/src/mainboard/google/brox/variants/brox/ramstage.c index 78e03ca..aef7a00 100644 --- a/src/mainboard/google/brox/variants/brox/ramstage.c +++ b/src/mainboard/google/brox/variants/brox/ramstage.c @@ -33,16 +33,6 @@ }, };
-const struct system_power_limits sys_limits[] = { - /* SKU_ID, TDP (Watts), psys_pl2 (Watts) */ - { PCI_DID_INTEL_RPL_P_ID_3, 15, 60 }, - { PCI_DID_INTEL_RPL_P_ID_4, 15, 60 }, -}; - -const struct psys_config psys_config = { - .efficiency = 86, -}; - void __weak variant_devtree_update(void) { uint32_t board_version = board_id(); @@ -52,7 +42,6 @@ size_t limits_size = ARRAY_SIZE(performance_efficient_limits);
variant_update_power_limits(limits, limits_size); - variant_update_psys_power_limits(limits, sys_limits, limits_size, &psys_config);
/* Disable I2C bus device for Touchscreen */ if (board_version >= 1) { diff --git a/src/soc/intel/alderlake/chip.h b/src/soc/intel/alderlake/chip.h index c3034ca..040b3d1 100644 --- a/src/soc/intel/alderlake/chip.h +++ b/src/soc/intel/alderlake/chip.h @@ -42,6 +42,13 @@ /* add ECC error injection if needed by a mainboard */ };
+/* FSPM UPD for setting the boot frequency */ +enum fspm_boot_freq { + MAX_BATTERY_PERFORMANCE, + MAX_NONTURBO_PERFORMANCE, + TURBO_PERFORMANCE +}; + /* Types of different SKUs */ enum soc_intel_alderlake_power_limits { ADL_P_142_242_282_15W_CORE,