Skip to content
Open

Oc #80

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions baseboard/fwk/fan.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
#define FAN_PID_I_INV 100
#define FAN_PID_I_MAX (10*FAN_PID_I_INV)

#define STABLE_RPM 2200
#define STABLE_RPM 4500

static int rpm_setting[FAN_CH_COUNT];
static int duty_setting[FAN_CH_COUNT];
Expand Down Expand Up @@ -96,17 +96,17 @@ int fan_rpm_to_percent(int fan, int rpm)
if (rpm <= STABLE_RPM) {
pct = rpm / 100;
return pct;
} else if (rpm <= 4000)
min = 1040 + (28 * ((rpm - STABLE_RPM) / 100));
else if (rpm <= 5200)
min = 1040 + (20 * ((rpm - STABLE_RPM) / 100));

}
min = 1718;
// min = STABLE_RPM*(10000-FAN_HARDARE_MAX)/(10000-STABLE_RPM)
/* make formula More in line with the actual-fan speed -
* Note that this will limit the fan % to about 94%
* if we want a performance mode we can tweak this
* to get a few more % of fan speed to unlock additional
* cooling TODO FRAMEWORK */
pct = (rpm - min) / ((FAN_HARDARE_MAX - min) / 100);
// original FAN_HARDARE_MAX = 7100
// Tested max : 7400 RPM on flat surface, 8500 RPM when intake blocked
pct = (rpm - min) / ((max - min) / 100);
/*CPRINTS(" Fan max min : %d , %d", max, min);*/
}
/*CPRINTS(" Fan PCT = %d ", pct);*/
Expand Down Expand Up @@ -185,7 +185,7 @@ void fan_set_rpm_target(int ch, int rpm)
rpm_setting[ch] = rpm;
if (chipset_in_state(CHIPSET_STATE_ON) && rpm == 0 &&
!timestamp_expired(fan_spindown_time, NULL)) {
rpm = 1200;
rpm = fans[0].rpm->rpm_min;
}

pct = fan_rpm_to_percent(ch, rpm);
Expand Down
14 changes: 10 additions & 4 deletions board/hx20/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,9 +973,9 @@ const struct fan_conf fan_conf_0 = {

/* Default */
const struct fan_rpm fan_rpm_0 = {
.rpm_min = 1800,
.rpm_start = 1800,
.rpm_max = 6800, /* Todo: Derate by -7% so all units have same performance */
.rpm_min = 1200,
.rpm_start = 1200,
.rpm_max = 7400,
};

const struct fan_t fans[FAN_CH_COUNT] = {
Expand Down Expand Up @@ -1023,7 +1023,7 @@ static const struct ec_thermal_config thermal_inductor_cpu = {
[EC_TEMP_THRESH_HALT] = 0,
},
.temp_fan_off = C_TO_K(40),
.temp_fan_max = C_TO_K(69),
.temp_fan_max = C_TO_K(75),
};
static const struct ec_thermal_config thermal_inductor_ddr = {
.temp_host = {
Expand Down Expand Up @@ -1073,6 +1073,10 @@ static const struct ec_thermal_config thermal_cpu = {

struct ec_thermal_config thermal_params[TEMP_SENSOR_COUNT];
BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT);

/* Forward declaration for fan mode initialization */
extern void update_thermal_params_for_mode(int mode);

static void setup_fans(void)
{
thermal_params[TEMP_SENSOR_LOCAL] = thermal_inductor_local;
Expand All @@ -1082,6 +1086,8 @@ static void setup_fans(void)
#ifdef CONFIG_PECI
thermal_params[TEMP_SENSOR_PECI] = thermal_cpu;
#endif
/* Initialize with normal fan mode */
update_thermal_params_for_mode(1);
}
DECLARE_HOOK(HOOK_INIT, setup_fans, HOOK_PRIO_DEFAULT);
#endif
Expand Down
2 changes: 1 addition & 1 deletion board/hx20/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@
#define CONFIG_FANS 1
#undef CONFIG_FAN_INIT_SPEED
#define CONFIG_FAN_INIT_SPEED 15
#define FAN_HARDARE_MAX 7100
#define FAN_HARDARE_MAX 7400
#define CONFIG_TEMP_SENSOR
#define CONFIG_DPTF
#define CONFIG_TEMP_SENSOR_F75303
Expand Down
186 changes: 136 additions & 50 deletions board/hx20/cpu_power.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,31 @@
#include "cypress5525.h"
#include "math_util.h"
#include "util.h"
#include "ec_commands.h"
#include "fan.h"
#include "temp_sensor.h"


#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)

#define POWER_LIMIT_1_W 28
// Loaded on EC reset
#define POWER_LIMIT_1_W_DEFAULT 40
#define POWER_LIMIT_2_W_DEFAULT 64
#define POWER_LIMIT_4_W_DEFAULT 121

static int pl1_watt;
static int pl2_watt;
static int pl4_watt;
// Loaded by ectool command "cpupower default"
#define POWER_LIMIT_1_W_USER_DEFAULT 28
#define POWER_LIMIT_2_W_USER_DEFAULT 64
#define POWER_LIMIT_4_W_USER_DEFAULT 121

static int POWER_LIMIT_1_W = POWER_LIMIT_1_W_DEFAULT;
static int POWER_LIMIT_2_W = POWER_LIMIT_2_W_DEFAULT;
static int POWER_LIMIT_4_W = POWER_LIMIT_4_W_DEFAULT;

static int pl1_watt = POWER_LIMIT_1_W_DEFAULT;
static int pl2_watt = POWER_LIMIT_2_W_DEFAULT;
static int pl4_watt = POWER_LIMIT_4_W_DEFAULT;
static int psys_watt;
bool manual_ctl;

Expand All @@ -45,6 +60,7 @@ void update_soc_power_limit(bool force_update, bool force_no_adapter)
int pps_power_budget;
int battery_percent;

static int old_pl1_watt = -1;
static int old_pl2_watt = -1;
static int old_pl4_watt = -1;
static int old_psys_watt = -1;
Expand All @@ -70,23 +86,23 @@ void update_soc_power_limit(bool force_update, bool force_no_adapter)
psys_watt = ((active_power * 95) / 100) - pps_power_budget;
} else {
/* ADP > 55W and Battery percentage >= 30% */
pl2_watt = 64;
pl4_watt = 121;
pl1_watt = POWER_LIMIT_1_W;
pl2_watt = POWER_LIMIT_2_W;
pl4_watt = POWER_LIMIT_4_W;
/* psys watt = adp watt * 0.95 + battery watt(55 W) * 0.7 - pps power budget */
psys_watt = ((active_power * 95) / 100) + 39 - pps_power_budget;
}
if (pl2_watt != old_pl2_watt || pl4_watt != old_pl4_watt ||
psys_watt != old_psys_watt || force_update) {
psys_watt != old_psys_watt || force_update ||
pl1_watt != old_pl1_watt) {
old_pl1_watt = pl1_watt;
old_psys_watt = psys_watt;
old_pl4_watt = pl4_watt;
old_pl2_watt = pl2_watt;

pl1_watt = POWER_LIMIT_1_W;
if (manual_ctl == false) {
CPRINTS("Updating SOC Power Limits: PL2 %d, PL4 %d, Psys %d, Adapter %d",
pl2_watt, pl4_watt, psys_watt, active_power);
set_pl_limits(pl1_watt, pl2_watt, pl4_watt, psys_watt);
}
CPRINTS("Updating SOC Power Limits: PL1 %d, PL2 %d, PL4 %d, Psys %d, Adapter %d",
pl1_watt, pl2_watt, pl4_watt, psys_watt, active_power);
set_pl_limits(pl1_watt, pl2_watt, pl4_watt, psys_watt);
}
}

Expand All @@ -100,49 +116,119 @@ DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, update_soc_power_limit_hook, HOOK_PRIO_DEF



static int cmd_cpupower(int argc, char **argv)
/* Fan mode enumeration */
enum fan_mode {
FAN_MODE_SILENT = 0,
FAN_MODE_NORMAL = 1,
FAN_MODE_EXTREME = 2,
};

static enum fan_mode current_fan_mode = FAN_MODE_NORMAL;

/* Update thermal params based on fan mode */
void update_thermal_params_for_mode(enum fan_mode mode)
{
uint32_t pl1, pl2, pl4, psys;
char *e;

CPRINTF("SOC Power Limit: PL1 %d, PL2 %d, PL4 %d, Psys %d\n",
pl1_watt, pl2_watt, pl4_watt, psys_watt);
if (argc >= 2) {
if (!strncmp(argv[1], "auto", 4)) {
manual_ctl = false;
CPRINTF("Auto Control");
update_soc_power_limit(false, false);
}
if (!strncmp(argv[1], "manual", 6)) {
manual_ctl = true;
CPRINTF("Manual Control");
set_pl_limits(pl1_watt, pl2_watt, pl4_watt, psys_watt);
extern struct ec_thermal_config thermal_params[TEMP_SENSOR_COUNT];

if (mode == FAN_MODE_SILENT) {
thermal_params[TEMP_SENSOR_CPU].temp_fan_off = C_TO_K(50);
thermal_params[TEMP_SENSOR_CPU].temp_fan_max = C_TO_K(85);
} else if (mode == FAN_MODE_EXTREME) {
thermal_params[TEMP_SENSOR_CPU].temp_fan_off = C_TO_K(20);
thermal_params[TEMP_SENSOR_CPU].temp_fan_max = C_TO_K(58);
} else {
/* NORMAL mode (default) */
thermal_params[TEMP_SENSOR_CPU].temp_fan_off = C_TO_K(40);
thermal_params[TEMP_SENSOR_CPU].temp_fan_max = C_TO_K(69);
}
current_fan_mode = mode;
fan_set_thermal_control_enabled(0, 1); /* Re-enable thermal control to apply new settings */
}

/* Fan mode host command handler */
static enum ec_status host_command_fan_mode(struct host_cmd_handler_args *args)
{
const struct ec_params_fan_mode *p = args->params;
struct ec_response_fan_mode *r = args->response;

/* If params provided, set the mode */
if (args->params_size > 0 && p) {
if (p->mode <= FAN_MODE_EXTREME) {
update_thermal_params_for_mode(p->mode);
CPRINTS("Fan mode set to %d", p->mode);
}
}

if (argc >= 5) {
pl1 = strtoi(argv[1], &e, 0);
if (*e)
return EC_ERROR_PARAM1;
pl2 = strtoi(argv[2], &e, 0);
if (*e)
return EC_ERROR_PARAM2;
pl4 = strtoi(argv[3], &e, 0);
if (*e)
return EC_ERROR_PARAM3;
psys = strtoi(argv[4], &e, 0);
if (*e)
return EC_ERROR_PARAM4;
pl1_watt = pl1;
pl2_watt = pl2;
pl4_watt = pl4;
psys_watt = psys;
set_pl_limits(pl1_watt, pl2_watt, pl4_watt, psys_watt);
/* Return current mode */
r->mode = current_fan_mode;
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
}

DECLARE_HOST_COMMAND(EC_CMD_FAN_MODE, host_command_fan_mode, EC_VER_MASK(0));

/* Console command for fan mode */
static int cmd_fan_mode(int argc, char **argv)
{
const char *mode_names[] = {"silent", "normal", "extreme"};
int mode;

if (argc > 1) {
if (!strcasecmp(argv[1], "silent"))
mode = FAN_MODE_SILENT;
else if (!strcasecmp(argv[1], "normal"))
mode = FAN_MODE_NORMAL;
else if (!strcasecmp(argv[1], "extreme"))
mode = FAN_MODE_EXTREME;
else {
CPRINTS("Invalid mode. Use: silent, normal, or extreme");
return EC_ERROR_PARAM1;
}
update_thermal_params_for_mode(mode);
}

CPRINTS("Current fan mode: %s", mode_names[current_fan_mode]);
return EC_SUCCESS;
}

DECLARE_CONSOLE_COMMAND(fanmode, cmd_fan_mode,
"[silent|normal|extreme]",
"Set/Get fan mode");

/* Host command handler for CPU power limits */
static enum ec_status host_command_cpu_power(struct host_cmd_handler_args *args)
{
const struct ec_params_cpu_power *p = args->params;
struct ec_response_cpu_power *r = args->response;

/* If parameters provided, set the values */
if (args->params_size > 0 && p) {
/*
* "default" from ectool is encoded as an all-zero payload.
*/
if (p->pl1_mW == 0 && p->pl2_mW == 0 && p->pl4_mW == 0) {
POWER_LIMIT_1_W = POWER_LIMIT_1_W_USER_DEFAULT;
POWER_LIMIT_2_W = POWER_LIMIT_2_W_USER_DEFAULT;
POWER_LIMIT_4_W = POWER_LIMIT_4_W_USER_DEFAULT;
} else {
if (p->pl1_mW != 0)
POWER_LIMIT_1_W = p->pl1_mW / 1000;
if (p->pl2_mW != 0)
POWER_LIMIT_2_W = p->pl2_mW / 1000;
if (p->pl4_mW != 0)
POWER_LIMIT_4_W = p->pl4_mW / 1000;
}
update_soc_power_limit(true, false);
}

/* Return current power limits in mW */
r->pl1_mW = pl1_watt * 1000;
r->pl2_mW = pl2_watt * 1000;
r->pl4_mW = pl4_watt * 1000;
r->psys_mW = psys_watt * 1000;

args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(cpupower, cmd_cpupower,
"cpupower pl1 pl2 pl4 psys ",
"Set/Get the cpupower limit");

DECLARE_HOST_COMMAND(EC_CMD_CPU_POWER, host_command_cpu_power, EC_VER_MASK(0));
4 changes: 2 additions & 2 deletions board/hx20/peci_customization.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#define PECI_INDEX_POWER_LIMITS_PL1 0x1A
#define PECI_PARAMS_POWER_LIMITS_PL1 0x0000
#define PECI_PL1_CONTROL_TIME_WINDOWS (0xDC << 16) /* 28 seconds */
#define PECI_PL1_CONTROL_TIME_WINDOWS (0xFF << 16) /* 28 seconds */
#define PECI_PL1_POWER_LIMIT_ENABLE (0x01 << 15)
#define PECI_PL1_POWER_LIMIT(x) (x << 3)

Expand All @@ -42,7 +42,7 @@

#define PECI_INDEX_POWER_LIMITS_PSYS_PL2 0x3B
#define PECI_PARAMS_POWER_LIMITS_PSYS_PL2 0x0000
#define PECI_PSYS_PL2_CONTROL_TIME_WINDOWS (0xDC << 16) /* 28 seconds */
#define PECI_PSYS_PL2_CONTROL_TIME_WINDOWS (0xFF << 16) /* 28 seconds */
#define PECI_PSYS_PL2_POWER_LIMIT_ENABLE (0x01 << 15)
#define PECI_PSYS_PL2_POWER_LIMIT(x) (x << 3)

Expand Down
5 changes: 5 additions & 0 deletions common/fan.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ test_export_static void set_thermal_control_enabled(int fan, int enable)
fan_set_rpm_mode(FAN_CH(fan), 1);
}

void fan_set_thermal_control_enabled(int fan, int enable)
{
set_thermal_control_enabled(fan, enable);
}

static void set_duty_cycle(int fan, int percent)
{
/* Move the fan to manual control */
Expand Down
Loading
Loading