Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/42136 )
Change subject: superio/nuvoton/nct6776: Add HWM API ......................................................................
superio/nuvoton/nct6776: Add HWM API
Tested with the usage examples on the Asrock B85M Pro4.
Change-Id: I3f2618eb112e2e3dc863c704817a2e87aa596a16 Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/mainboard/asrock/b85m_pro4/Kconfig M src/mainboard/asrock/b85m_pro4/bootblock.c M src/superio/nuvoton/nct6776/Kconfig M src/superio/nuvoton/nct6776/Makefile.inc A src/superio/nuvoton/nct6776/nct6776_hwm.c A src/superio/nuvoton/nct6776/nct6776_hwm.h 6 files changed, 291 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/36/42136/1
diff --git a/src/mainboard/asrock/b85m_pro4/Kconfig b/src/mainboard/asrock/b85m_pro4/Kconfig index ecb2ba9..1fd13e7 100644 --- a/src/mainboard/asrock/b85m_pro4/Kconfig +++ b/src/mainboard/asrock/b85m_pro4/Kconfig @@ -17,6 +17,7 @@ select SOUTHBRIDGE_INTEL_LYNXPOINT select SUPERIO_NUVOTON_NCT6776 select SUPERIO_NUVOTON_NCT6776_COM_A + select SUPERIO_NUVOTON_NCT6776_HWM
config MAINBOARD_DIR string diff --git a/src/mainboard/asrock/b85m_pro4/bootblock.c b/src/mainboard/asrock/b85m_pro4/bootblock.c index f95fb52..2aef95a 100644 --- a/src/mainboard/asrock/b85m_pro4/bootblock.c +++ b/src/mainboard/asrock/b85m_pro4/bootblock.c @@ -1,28 +1,65 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <device/pnp_ops.h> +#include <southbridge/intel/lynxpoint/pch.h> #include <superio/nuvoton/common/nuvoton.h> #include <superio/nuvoton/nct6776/nct6776.h> -#include <southbridge/intel/lynxpoint/pch.h> +#include <superio/nuvoton/nct6776/nct6776_hwm.h>
#define GLOBAL_DEV PNP_DEV(0x2e, 0) #define SERIAL_DEV PNP_DEV(0x2e, NCT6776_SP1) #define ACPI_DEV PNP_DEV(0x2e, NCT6776_ACPI) +#define HWM_DEV PNP_DEV(0x2e, NCT6776_HWM_FPLED) + +#define HWM_BASE 0x290
void mainboard_config_superio(void) { nuvoton_pnp_enter_conf_state(GLOBAL_DEV);
- /* Select HWM/LED functions instead of floppy functions */ - pnp_write_config(GLOBAL_DEV, 0x1c, 0x03); - pnp_write_config(GLOBAL_DEV, 0x24, 0x24); - - /* Power RAM in S3 and let the PCH handle power failure actions */ - pnp_set_logical_device(ACPI_DEV); - pnp_write_config(ACPI_DEV, 0xe4, 0x70); + /* Select SIO pin states */ + pnp_write_config(GLOBAL_DEV, 0x1b, 0x68); + pnp_write_config(GLOBAL_DEV, 0x1c, 0x80); + pnp_write_config(GLOBAL_DEV, 0x24, 0x1c); + pnp_write_config(GLOBAL_DEV, 0x27, 0xd0); + pnp_write_config(GLOBAL_DEV, 0x2a, 0x62); + pnp_write_config(GLOBAL_DEV, 0x2f, 0x03);
nuvoton_pnp_exit_conf_state(GLOBAL_DEV);
+ /* Set up the HWM */ + nct6776_hwm_init(HWM_DEV, HWM_BASE); + + nct6776_hwm_force_fan_full_on(HWM_BASE, SYS_FAN); + nct6776_hwm_force_fan_full_on(HWM_BASE, CPU_FAN); + nct6776_hwm_force_fan_full_on(HWM_BASE, AUX_FAN); + + nct6776_hwm_enable_peci(HWM_BASE); + + struct nct6776_hwm_thermal_cruise_params tcp = { + .target_temp = 55, + .tolerance = 0, + .start_up_val = 1, + .stop_val = 0, + .stopduty_en = false, + .stop_time = 1, + .step_up_time = 1, + .step_down_time = 1, + .critical_temp = 60, + .temp_src = PECI_0, + }; + + nct6776_hwm_program_thermal_cruise(HWM_BASE, CPU_FAN, &tcp); + + struct nct6776_hwm_speed_cruise_params scp = { + .target_speed = 4095, + .tolerance = 0, + .step_up_time = 1, + .step_down_time = 1, + }; + + nct6776_hwm_program_speed_cruise(HWM_BASE, CPU_FAN, &scp); + /* Enable UART */ nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); } diff --git a/src/superio/nuvoton/nct6776/Kconfig b/src/superio/nuvoton/nct6776/Kconfig index caa89b3..cf31635 100644 --- a/src/superio/nuvoton/nct6776/Kconfig +++ b/src/superio/nuvoton/nct6776/Kconfig @@ -8,3 +8,9 @@ bool depends on SUPERIO_NUVOTON_NCT6776 default n + +config SUPERIO_NUVOTON_NCT6776_HWM + bool + depends on SUPERIO_NUVOTON_NCT6776 + select SUPERIO_NUVOTON_COMMON_HWM + default n diff --git a/src/superio/nuvoton/nct6776/Makefile.inc b/src/superio/nuvoton/nct6776/Makefile.inc index a36361e..6cf2264 100644 --- a/src/superio/nuvoton/nct6776/Makefile.inc +++ b/src/superio/nuvoton/nct6776/Makefile.inc @@ -1,3 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later
ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6776) += superio.c + +all-$(CONFIG_SUPERIO_NUVOTON_NCT6776_HWM) += nct6776_hwm.c diff --git a/src/superio/nuvoton/nct6776/nct6776_hwm.c b/src/superio/nuvoton/nct6776/nct6776_hwm.c new file mode 100644 index 0000000..f89c3e1 --- /dev/null +++ b/src/superio/nuvoton/nct6776/nct6776_hwm.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <device/device.h> +#include <device/pnp.h> +#include <device/pnp_type.h> +#include <device/pnp_ops.h> +#include <superio/conf_mode.h> +#include <superio/hwm5_conf.h> +#include <superio/nuvoton/common/hwm.h> +#include <superio/nuvoton/common/nuvoton.h> + +#include "nct6776_hwm.h" +#include "nct6776.h" + +#if ENV_PNP_SIMPLE_DEVICE +void nct6776_hwm_init(pnp_devfn_t dev, const u16 base) +{ + nuvoton_pnp_enter_conf_state(dev); + + pnp_set_logical_device(dev); + pnp_set_enable(dev, 1); + pnp_set_iobase(dev, 0x60, base); + + nuvoton_pnp_exit_conf_state(dev); +} +#endif + +/* Higher order fan control functions */ +void nct6776_hwm_force_fan_full_on( + const u16 base, + const enum nct6776_hwm_fan fan) +{ + nct6776_hwm_set_fan_mode(base, fan, FAN_MODE_MANUAL); + nct6776_hwm_set_fan_duty(base, fan, 0xff); +} + +void nct6776_hwm_program_thermal_cruise( + const u16 base, + const enum nct6776_hwm_fan fan, + const struct nct6776_hwm_thermal_cruise_params *const tcp) +{ + /* For safety reasons, disengage fan control before reconfiguring this output */ + nct6776_hwm_force_fan_full_on(base, fan); + + /* Now, program Thermal Cruise mode using the desired settings */ + pnp_update_hwm5_index(base, 0x00, 0x70, ((!!tcp->stopduty_en) << 7) | tcp->temp_src); + pnp_update_hwm5_index(base, 0x02, 0xf8, tcp->tolerance); + + pnp_write_hwm5_index(base, 0x01, tcp->target_temp); + pnp_write_hwm5_index(base, 0x06, tcp->start_up_val); + pnp_write_hwm5_index(base, 0x05, tcp->stop_val); + pnp_write_hwm5_index(base, 0x07, tcp->stop_time); + pnp_write_hwm5_index(base, 0x03, tcp->step_up_time); + pnp_write_hwm5_index(base, 0x04, tcp->step_down_time); + pnp_write_hwm5_index(base, 0x35, tcp->critical_temp); + + /* Set fan speed to midpoint */ + nct6776_hwm_set_fan_duty(base, fan, 0x7f); + + /* And enable Thermal Cruise mode */ + nct6776_hwm_set_fan_mode(base, fan, FAN_MODE_THERMAL_CRUISE); +} + +void nct6776_hwm_program_speed_cruise( + const u16 base, + const enum nct6776_hwm_fan fan, + const struct nct6776_hwm_speed_cruise_params *const scp) +{ + /* For safety reasons, disengage fan control before reconfiguring this output */ + nct6776_hwm_force_fan_full_on(base, fan); + + /* High bits of target speed and tolerance go into the same register */ + const u8 reg_0c = ((scp->tolerance << 1) & 0x70) | ((scp->target_speed >> 8) & 0x0f); + + /* Now, program Speed Cruise mode using the desired settings */ + pnp_update_hwm5_index(base, 0x0c, 0x80, reg_0c); + pnp_update_hwm5_index(base, 0x02, 0xf8, scp->tolerance); + + pnp_write_hwm5_index(base, 0x01, (u8)scp->target_speed); + pnp_write_hwm5_index(base, 0x03, scp->step_up_time); + pnp_write_hwm5_index(base, 0x04, scp->step_down_time); + + /* Set fan speed to midpoint */ + nct6776_hwm_set_fan_duty(base, fan, 0x7f); + + /* And enable Thermal Cruise mode */ + nct6776_hwm_set_fan_mode(base, fan, FAN_MODE_SPEED_CRUISE); +} + +void nct6776_hwm_enable_peci(const u16 base) +{ + nuvoton_hwm_select_bank(base, 0); + pnp_update_hwm5_index(base, 0xae, 0xfc, 0x01); + + nuvoton_hwm_select_bank(base, 7); + + pnp_write_hwm5_index(base, 0x01, 0x95); + pnp_write_hwm5_index(base, 0x02, 0x02); + pnp_write_hwm5_index(base, 0x03, 0x30); + + pnp_write_hwm5_index(base, 0x09, 0x5c); +} diff --git a/src/superio/nuvoton/nct6776/nct6776_hwm.h b/src/superio/nuvoton/nct6776/nct6776_hwm.h new file mode 100644 index 0000000..3243b13 --- /dev/null +++ b/src/superio/nuvoton/nct6776/nct6776_hwm.h @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef SUPERIO_NUVOTON_NCT6776_HWM_H +#define SUPERIO_NUVOTON_NCT6776_HWM_H + + +#include <device/device.h> +#include <device/pnp.h> +#include <device/pnp_type.h> +#include <device/pnp_ops.h> +#include <stdint.h> +#include <superio/conf_mode.h> +#include <superio/hwm5_conf.h> +#include <superio/nuvoton/common/hwm.h> +#include <superio/nuvoton/common/nuvoton.h> + +/* The values correspond to the HWM Bank number for each fan */ +enum nct6776_hwm_fan { + SYS_FAN = 1, + CPU_FAN = 2, + AUX_FAN = 3, +}; + +/* The values can be directly applied to the HWM registers for fan mode control */ +enum nct6776_hwm_fan_mode { + FAN_MODE_MANUAL = 0x0 << 4, + FAN_MODE_THERMAL_CRUISE = 0x1 << 4, + FAN_MODE_SPEED_CRUISE = 0x2 << 4, + FAN_MODE_SMART_FAN_IV = 0x4 << 4, +}; + +enum nct6776_hwm_temp_src { + SYSTIN = 1, + CPUTIN = 2, + AUXTIN = 3, + SMBUSMASTER_0 = 4, + SMBUSMASTER_1 = 5, + SMBUSMASTER_2 = 6, + SMBUSMASTER_3 = 7, + SMBUSMASTER_4 = 8, + SMBUSMASTER_5 = 9, + SMBUSMASTER_6 = 10, + SMBUSMASTER_7 = 11, + PECI_0 = 12, + PECI_1 = 13, + PCH_CHIP_CPU_MAX_TEMP = 14, + PCH_CHIP_TEMP = 15, + PCH_CPU_TEMP = 16, + PCH_MCH_TEMP = 17, + PCH_DIM0_TEMP = 18, + PCH_DIM1_TEMP = 19, + PCH_DIM2_TEMP = 20, + PCH_DIM3_TEMP = 21, + BYTE_TEMP = 22 +}; + +struct nct6776_hwm_thermal_cruise_params { + u8 target_temp; + u8 tolerance; + u8 start_up_val; + u8 stop_val; + bool stopduty_en; + u8 stop_time; + u8 step_up_time; + u8 step_down_time; + u8 critical_temp; + enum nct6776_hwm_temp_src temp_src; +}; + +struct nct6776_hwm_speed_cruise_params { + u16 target_speed; + u8 tolerance; + u8 step_up_time; + u8 step_down_time; +}; + +#if ENV_PNP_SIMPLE_DEVICE +void nct6776_hwm_init(pnp_devfn_t dev, const u16 base); +#endif + +/* Low level fan control functions */ +static inline void nct6776_hwm_set_temperature_source( + const u16 base, + const enum nct6776_hwm_fan fan, + const enum nct6776_hwm_temp_src temp_src) +{ + nuvoton_hwm_select_bank(base, fan); + pnp_update_hwm5_index(base, 0x00, 0xf0, temp_src); +} + +static inline void nct6776_hwm_set_fan_mode( + const u16 base, + const enum nct6776_hwm_fan fan, + const enum nct6776_hwm_fan_mode fan_mode) +{ + nuvoton_hwm_select_bank(base, fan); + pnp_update_hwm5_index(base, 0x02, 0x0f, fan_mode); +} + +static inline void nct6776_hwm_set_temperature_tolerance( + const u16 base, + const enum nct6776_hwm_fan fan, + const u8 tolerance) +{ + nuvoton_hwm_select_bank(base, fan); + pnp_update_hwm5_index(base, 0x02, 0xf8, tolerance); +} + +static inline void nct6776_hwm_set_fan_duty( + const u16 base, + const enum nct6776_hwm_fan fan, + const u8 speed) +{ + nuvoton_hwm_select_bank(base, fan); + pnp_write_hwm5_index(base, 0x09, speed); +} + +/* Higher order fan control functions */ +void nct6776_hwm_force_fan_full_on( + const u16 base, + const enum nct6776_hwm_fan fan); + +void nct6776_hwm_program_thermal_cruise( + const u16 base, + const enum nct6776_hwm_fan fan, + const struct nct6776_hwm_thermal_cruise_params *const tcp); + +void nct6776_hwm_program_speed_cruise( + const u16 base, + const enum nct6776_hwm_fan fan, + const struct nct6776_hwm_speed_cruise_params *const scp); + +void nct6776_hwm_enable_peci(const u16 base); + +#endif /* SUPERIO_NUVOTON_NCT6776_HWM_H */
HAOUAS Elyes has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/42136 )
Change subject: superio/nuvoton/nct6776: Add HWM API ......................................................................
Patch Set 1: Code-Review+1
(1 comment)
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... File src/superio/nuvoton/nct6776/Makefile.inc:
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... PS1, Line 5: all- would you please explain why it is needed for "all"?
HAOUAS Elyes has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/42136 )
Change subject: superio/nuvoton/nct6776: Add HWM API ......................................................................
Patch Set 1:
(1 comment)
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... File src/superio/nuvoton/nct6776/nct6776_hwm.c:
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... PS1, Line 29: nct6776_hwm_force_fan_full_on isn't there a way to use only the older "fan values"? when you reboot or restart , the CPU temperature is lower than the old temperature.
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/42136 )
Change subject: superio/nuvoton/nct6776: Add HWM API ......................................................................
Patch Set 1:
(3 comments)
https://review.coreboot.org/c/coreboot/+/42136/1/src/mainboard/asrock/b85m_p... File src/mainboard/asrock/b85m_pro4/bootblock.c:
https://review.coreboot.org/c/coreboot/+/42136/1/src/mainboard/asrock/b85m_p... PS1, Line 61: nct6776_hwm_program_speed_cruise(HWM_BASE, CPU_FAN, &scp); Note to self: Since GPIOs aren't configured yet here, tach readings are zero, so the fan will ramp up until ramstage.
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... File src/superio/nuvoton/nct6776/Makefile.inc:
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... PS1, Line 5: all-
would you please explain why it is needed for "all"?
It's not strictly needed for all stages, but I'd rather give some flexibility in case someone wants to configure fan control inside superio.c in ramstage.
I currently do fan setup in bootblock, before raminit happens. Before I wrote the HWM API, I was forcing the fan speed to full on bootblock, half power on romstage and minimum power on ramstage, so I needed the code on three different stages.
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... File src/superio/nuvoton/nct6776/nct6776_hwm.c:
https://review.coreboot.org/c/coreboot/+/42136/1/src/superio/nuvoton/nct6776... PS1, Line 29: nct6776_hwm_force_fan_full_on
isn't there a way to use only the older "fan values"? […]
The point of this function is to "disengage" fan control. That is, make a fan spin up at constant full speed while reconfiguring automatic control. That way, if something bad happens when reconfiguring the SuperIO, there's no risk of overheating.
About using older fan values, if the fan speeds are automatically controlled, it doesn't matter 😉
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/42136 )
Change subject: superio/nuvoton/nct6776: Add HWM API ......................................................................
Patch Set 9:
This change is ready for review.