diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c index 9be3f5be8f..59afa551a5 100644 --- a/src/acpi/acpigen_dptf.c +++ b/src/acpi/acpigen_dptf.c @@ -404,3 +404,31 @@ void dptf_write_power_limits(const struct dptf_power_limits *limits) acpigen_pop_len(); /* Method */ acpigen_pop_len(); /* Scope */ } + +void dptf_write_STR(const char *str) +{ + if (!str) + return; + + acpigen_write_name_string("_STR", str); +} + +void dptf_write_fan_options(bool fine_grained, int step_size, bool low_speed_notify) +{ + acpigen_write_name("_FIF"); + acpigen_write_package(4); + + acpigen_write_integer(0); /* Revision */ + acpigen_write_integer(fine_grained); + acpigen_write_integer(step_size); + acpigen_write_integer(low_speed_notify); + acpigen_pop_len(); /* Package */ +} + +void dptf_write_tsr_hysteresis(uint8_t hysteresis) +{ + if (!hysteresis) + return; + + acpigen_write_name_integer("GTSH", hysteresis); +} diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h index 0d2c25cf61..28403a83bd 100644 --- a/src/drivers/intel/dptf/chip.h +++ b/src/drivers/intel/dptf/chip.h @@ -17,6 +17,33 @@ struct drivers_intel_dptf_config { struct dptf_fan_perf fan_perf[DPTF_MAX_FAN_PERF_STATES]; struct dptf_power_limits power_limits; } controls; + + /* Note that all values in this struct are optional */ + struct { + struct { + /* True means _FSL is percentages, False means _FSL is Control values */ + bool fine_grained_control; + /* + * Recommended minimum step size in percentage points to adjust fan + * speed when utilizing fine-grained control (1-9) + */ + uint8_t step_size; + /* + * True means the platform will issue a Notify (0x80) to the fan device + * if a a low fan speed is detected + */ + bool low_speed_notify; + } fan; + struct { + /* + * The amount of hysteresis implemented in circuitry or in the platform + * EC's firmware implementation (using the GTSH object) + */ + uint8_t hysteresis; + /* Name applied to TSR (using the _STR object) */ + const char *desc; + } tsr[DPTF_MAX_TSR]; + } options; }; #endif /* _DRIVERS_INTEL_DPTF_CHIP_H_ */ diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c index 15a7d1297b..1fe9653eb7 100644 --- a/src/drivers/intel/dptf/dptf.c +++ b/src/drivers/intel/dptf/dptf.c @@ -62,6 +62,12 @@ static const char *dptf_acpi_name(const struct device *dev) static void dptf_fill_ssdt(const struct device *dev) { struct drivers_intel_dptf_config *config = config_of(dev); + enum dptf_participant p; + bool tsr_en[DPTF_MAX_TSR] = {false}; + int i; + + for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_3; ++p, ++i) + tsr_en[i] = is_participant_used(config, p); dptf_write_active_policies(config->policies.active, DPTF_MAX_ACTIVE_POLICIES); @@ -77,6 +83,19 @@ static void dptf_fill_ssdt(const struct device *dev) dptf_write_fan_perf(config->controls.fan_perf, DPTF_MAX_FAN_PERF_STATES); dptf_write_power_limits(&config->controls.power_limits); + /* Fan options */ + dptf_write_fan_options(config->options.fan.fine_grained_control, + config->options.fan.step_size, + config->options.fan.low_speed_notify); + + /* TSR options */ + for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_3; ++p, ++i) { + if (tsr_en[i]) { + dptf_write_tsr_hysteresis(config->options.tsr[i].hysteresis); + dptf_write_STR(config->options.tsr[i].desc); + } + } + printk(BIOS_INFO, "\\_SB.DPTF: %s at %s\n", dev->chip_ops->name, dev_path(dev)); } diff --git a/src/include/acpi/acpigen_dptf.h b/src/include/acpi/acpigen_dptf.h index 474f72cd71..496840b8b4 100644 --- a/src/include/acpi/acpigen_dptf.h +++ b/src/include/acpi/acpigen_dptf.h @@ -36,6 +36,9 @@ enum { /* From ACPI spec 6.3 */ DPTF_FIELD_UNUSED = 0xFFFFFFFFull, + + /* Max supported by DPTF */ + DPTF_MAX_TSR = 4, }; /* Active Policy */ @@ -169,6 +172,18 @@ void dptf_write_fan_perf(const struct dptf_fan_perf *perf, int max_count); */ void dptf_write_power_limits(const struct dptf_power_limits *limits); +/* Set the _STR Name */ +void dptf_write_STR(const char *str); + +/* Set options in the _FIF table */ +void dptf_write_fan_options(bool fine_grained, int step_size, bool low_speed_notify); + +/* + * Sets the amount of inherent hysteresis in temperature sensor readings (either from hardware + * circuitry or possibly from the EC's firmware implementation. + */ +void dptf_write_tsr_hysteresis(uint8_t hysteresis); + /* Helper method to open the scope for a given participant. */ void dptf_write_scope(enum dptf_participant participant);