mainboard/starlabs: rework power profile limits

Recompute PL1/PL2 from the per-SKU TDP values instead of deriving PL1
from PL2.

- Performance: PL1 = TDP, PL2 = round_up(TDP * 2, 5)
- Balanced/Power saver: scale TDP first, then derive PL2
- Performance TCC offset: 10C with fan, 20C without
- Lower profiles: add +10C offset per step down

PL4 continues to be sourced from CONFIG_PL4_WATTS.

Change-Id: Idc5d008c8db0391fcc600e7485010e15c8fc01d8
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91055
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Sean Rhodes 2026-02-02 20:21:09 +00:00
commit 6b7084a053
2 changed files with 18 additions and 16 deletions

View file

@ -5,8 +5,6 @@
#include <soc/soc_chip.h>
#define TCC(temp) (CONFIG_TJ_MAX - temp)
enum cmos_power_profile {
PP_POWER_SAVER = 0,
PP_BALANCED = 1,

View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <commonlib/helpers.h>
#include <option.h>
#include <types.h>
#include <common/powercap.h>
@ -10,47 +11,50 @@ static enum cmos_power_profile get_power_profile(enum cmos_power_profile fallbac
return power_profile < NUM_POWER_PROFILES ? power_profile : fallback;
}
static uint16_t round_up_to_5(uint16_t value)
{
return DIV_ROUND_UP(value, 5) * 5;
}
void update_power_limits(config_t *cfg)
{
uint8_t performance_scale = 100;
uint32_t performance_tcc_offset = CONFIG(EC_STARLABS_FAN) ? 10 : 20;
/* Scale PL1 & PL2 based on CMOS settings */
switch (get_power_profile(PP_POWER_SAVER)) {
case PP_POWER_SAVER:
performance_scale -= 50;
cfg->tcc_offset = TCC(80);
cfg->tcc_offset = performance_tcc_offset + 20;
break;
case PP_BALANCED:
performance_scale -= 25;
cfg->tcc_offset = TCC(90);
cfg->tcc_offset = performance_tcc_offset + 10;
break;
case PP_PERFORMANCE:
/* Use the Intel defaults */
cfg->tcc_offset = TCC(100);
cfg->tcc_offset = performance_tcc_offset;
break;
}
struct soc_power_limits_config *limits =
(struct soc_power_limits_config *)&cfg->power_limits_config;
size_t limit_count = sizeof(cfg->power_limits_config) /
sizeof(struct soc_power_limits_config);
size_t limit_count =
sizeof(cfg->power_limits_config) / sizeof(struct soc_power_limits_config);
for (size_t i = 0; i < limit_count; i++) {
struct soc_power_limits_config *entry = &limits[i];
uint16_t tdp, pl1, pl2;
entry->tdp_pl4 = (uint16_t)CONFIG_PL4_WATTS;
if (!entry->tdp_pl2_override)
tdp = entry->tdp_pl1_override;
if (!tdp)
continue;
/* Set PL1 to 50% of PL2 */
entry->tdp_pl1_override = (entry->tdp_pl2_override / 2) & ~1;
pl1 = (tdp * performance_scale) / 100;
pl2 = round_up_to_5(pl1 * 2);
if (performance_scale == 100)
continue;
entry->tdp_pl1_override = ((entry->tdp_pl1_override * performance_scale) / 100);
entry->tdp_pl2_override = ((entry->tdp_pl2_override * performance_scale) / 100);
entry->tdp_pl1_override = pl1;
entry->tdp_pl2_override = pl2;
}
}