aboutsummaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorSumeet Pawnikar <sumeet.r.pawnikar@intel.com>2022-06-08 17:43:36 +0530
committerFelix Held <felix-coreboot@felixheld.de>2023-04-12 14:11:45 +0000
commit2f7fa5543308e83787b7cef6e83e20e1e3f379d9 (patch)
tree94a4d6dbe8092e729392ae1459b150f060fc4109 /src/drivers
parent0c06dbb1a4aaf6506b769fb36e8a694e91ab411b (diff)
Reland "drivers/intel/dptf: Add multiple fan support under dptf"
This reverts commit 4dba71fd25c91a9e610287c61238a8fe24452e4e. Add multiple fan support for dptf policies. This also fixes the Google Meet resolution drop issue as per b:246535768 comment#12. When system starts Google Meet video call, it uses the hardware accelerated encoder as expected. But, as soon as another system connects to the call, an immediate fallback is observed from hardware to software encoder. Due to this, Google Meet resolution dropped from 720p to 180p. This issue is observed on Alder Lake-N SoC based fanless platforms. This same issue was not seen on fan based systems. With the fix in dptf driver where fan configures appropriate setting for only fan participant, not for other device participants, able to see consistent 720p resolution. BUG=b:246535768,b:235254828 BRANCH=None TEST=Built and tested on Alder Lake-P Redrix system for two fans support and on Alder Lake-N fanless systems. With this code change Google Meet resolution drop not observed. Signed-off-by: Sumeet Pawnikar <sumeet.r.pawnikar@intel.com> Change-Id: Id07d279ff962253c22be9d395ed7be0d732aeaa7 Reviewed-on: https://review.coreboot.org/c/coreboot/+/73249 Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Reviewed-by: Reka Norman <rekanorman@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/intel/dptf/chip.h12
-rw-r--r--src/drivers/intel/dptf/dptf.c83
2 files changed, 79 insertions, 16 deletions
diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h
index 060f19699d..9bbf11f2f7 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -25,6 +25,8 @@ struct drivers_intel_dptf_config {
struct {
struct dptf_charger_perf charger_perf[DPTF_MAX_CHARGER_PERF_STATES];
struct dptf_fan_perf fan_perf[DPTF_MAX_FAN_PERF_STATES];
+ struct dptf_multifan_perf
+ multifan_perf[DPTF_MAX_FAN_PARTICIPANTS][DPTF_MAX_FAN_PERF_STATES];
struct dptf_power_limits power_limits;
} controls;
@@ -44,6 +46,14 @@ struct drivers_intel_dptf_config {
*/
bool low_speed_notify;
} fan;
+
+ /* For multiple TFN fan options */
+ struct {
+ bool fine_grained_control;
+ uint8_t step_size;
+ bool low_speed_notify;
+ } multifan_options[DPTF_MAX_FAN_PARTICIPANTS];
+
struct {
/*
* The amount of hysteresis implemented in circuitry or in the platform
@@ -62,6 +72,8 @@ struct drivers_intel_dptf_config {
/* Rest of platform Power */
uint32_t prop;
+
+ bool dptf_multifan_support;
};
#endif /* _DRIVERS_INTEL_DPTF_CHIP_H_ */
diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c
index 886093e26d..fb7cb85e75 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -13,6 +13,7 @@
/* Generic DPTF participants have a PTYP field to distinguish them */
enum dptf_generic_participant_type {
DPTF_GENERIC_PARTICIPANT_TYPE_TSR = 0x3,
+ DPTF_GENERIC_PARTICIPANT_TYPE_FAN = 0x4,
DPTF_GENERIC_PARTICIPANT_TYPE_TPCH = 0x5,
DPTF_GENERIC_PARTICIPANT_TYPE_CHARGER = 0xB,
DPTF_GENERIC_PARTICIPANT_TYPE_BATTERY = 0xC,
@@ -23,6 +24,7 @@ enum dptf_generic_participant_type {
#define DEFAULT_TPCH_STR "Intel PCH FIVR Participant"
#define DEFAULT_POWER_STR "Power Participant"
#define DEFAULT_BATTERY_STR "Battery Participant"
+#define DEFAULT_FAN_STR "Fan Participant"
#define PMC_IPC_COMMAND_FIVR_SIZE 0x8
@@ -52,12 +54,26 @@ static bool is_participant_used(const struct drivers_intel_dptf_config *config,
return true;
/* Check fan as well (its use is implicit in the Active policy) */
- if (participant == DPTF_FAN && config->policies.active[0].target != DPTF_NONE)
+ if ((participant == DPTF_FAN || participant == DPTF_FAN_2) &&
+ config->policies.active[0].target != DPTF_NONE)
return true;
return false;
}
+/* Return the assigned namestring of the FAN participant */
+static const char *fan_namestring_of(enum dptf_participant participant)
+{
+ switch (participant) {
+ case DPTF_FAN:
+ return "TFN1";
+ case DPTF_FAN_2:
+ return "TFN2";
+ default:
+ return "";
+ }
+}
+
static const char *dptf_acpi_name(const struct device *dev)
{
return "DPTF";
@@ -116,15 +132,20 @@ static void write_tcpu(const struct device *pci_dev,
acpigen_pop_len(); /* TCPU Scope */
}
-/* \_SB.DPTF.TFN1 */
+/* \_SB.DPTF.TFNx */
static void write_fan(const struct drivers_intel_dptf_config *config,
- const struct dptf_platform_info *platform_info)
+ const struct dptf_platform_info *platform_info,
+ enum dptf_participant participant)
{
- acpigen_write_device("TFN1");
+ static int fan_uid = 0;
+
+ acpigen_write_device(fan_namestring_of(participant));
acpigen_write_name("_HID");
dptf_write_hid(platform_info->use_eisa_hids, platform_info->fan_hid);
- acpigen_write_name_integer("_UID", 0);
- acpigen_write_STA(get_STA_value(config, DPTF_FAN));
+ acpigen_write_name_integer("_UID", fan_uid++);
+ acpigen_write_name_string("_STR", DEFAULT_FAN_STR);
+ acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_FAN);
+ acpigen_write_STA(get_STA_value(config, participant));
acpigen_pop_len(); /* Device */
}
@@ -479,6 +500,7 @@ static void write_device_definitions(const struct device *dev)
const struct dptf_platform_info *platform_info = get_dptf_platform_info();
const struct drivers_intel_dptf_config *config;
struct device *parent;
+ enum dptf_participant p;
/* The CPU device gets an _ADR that matches the ACPI PCI address for 00:04.00 */
parent = dev && dev->bus ? dev->bus->dev : NULL;
@@ -491,7 +513,13 @@ static void write_device_definitions(const struct device *dev)
config = config_of(dev);
write_tcpu(parent, config);
write_open_dptf_device(dev, platform_info);
- write_fan(config, platform_info);
+
+ if (config->dptf_multifan_support) {
+ for (p = DPTF_FAN; p <= DPTF_FAN_2; ++p)
+ write_fan(config, platform_info, p);
+ } else
+ write_fan(config, platform_info, DPTF_FAN);
+
write_oem_variables(config);
write_imok();
write_generic_devices(config, platform_info);
@@ -517,7 +545,7 @@ static void write_policies(const struct drivers_intel_dptf_config *config)
config->policies.critical, DPTF_MAX_CRITICAL_POLICIES);
dptf_write_active_policies(config->policies.active,
- DPTF_MAX_ACTIVE_POLICIES);
+ DPTF_MAX_ACTIVE_POLICIES, config->dptf_multifan_support);
dptf_write_passive_policies(config->policies.passive,
DPTF_MAX_PASSIVE_POLICIES);
@@ -529,8 +557,20 @@ static void write_policies(const struct drivers_intel_dptf_config *config)
/* Writes other static tables that are used by DPTF */
static void write_controls(const struct drivers_intel_dptf_config *config)
{
+ enum dptf_participant p;
+ int fan_num;
+
dptf_write_charger_perf(config->controls.charger_perf, DPTF_MAX_CHARGER_PERF_STATES);
- dptf_write_fan_perf(config->controls.fan_perf, DPTF_MAX_FAN_PERF_STATES);
+
+ /* Write TFN perf states based on the number of fans on the platform */
+ if (config->dptf_multifan_support) {
+ for (p = DPTF_FAN, fan_num = 0; p <= DPTF_FAN_2; ++p, ++fan_num)
+ dptf_write_multifan_perf(config->controls.multifan_perf,
+ DPTF_MAX_FAN_PERF_STATES, p, fan_num);
+ } else
+ dptf_write_fan_perf(config->controls.fan_perf, DPTF_MAX_FAN_PERF_STATES,
+ DPTF_FAN);
+
dptf_write_power_limits(&config->controls.power_limits);
}
@@ -538,14 +578,25 @@ static void write_controls(const struct drivers_intel_dptf_config *config)
static void write_options(const struct drivers_intel_dptf_config *config)
{
enum dptf_participant p;
- int i;
+ int i, fan_num;
- /* Fan options */
- dptf_write_scope(DPTF_FAN);
- dptf_write_fan_options(config->options.fan.fine_grained_control,
- config->options.fan.step_size,
- config->options.fan.low_speed_notify);
- acpigen_pop_len(); /* Scope */
+ /* Configure Fan options based on the number of fans on the platform */
+ if (config->dptf_multifan_support) {
+ for (p = DPTF_FAN, fan_num = 0; p <= DPTF_FAN_2; ++p, ++fan_num) {
+ dptf_write_scope(p);
+ dptf_write_fan_options(
+ config->options.multifan_options[fan_num].fine_grained_control,
+ config->options.multifan_options[fan_num].step_size,
+ config->options.multifan_options[fan_num].low_speed_notify);
+ acpigen_pop_len(); /* Scope */
+ }
+ } else {
+ dptf_write_scope(DPTF_FAN);
+ dptf_write_fan_options(config->options.fan.fine_grained_control,
+ config->options.fan.step_size,
+ config->options.fan.low_speed_notify);
+ acpigen_pop_len(); /* Scope */
+ }
/* TSR options */
for (p = DPTF_TEMP_SENSOR_0, i = 0; p <= DPTF_TEMP_SENSOR_4; ++p, ++i) {