Leroy P Leahy (leroy.p.leahy@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14497
-gerrit
commit 43d7a454df423b253021459913e2e3b30539e755 Author: Lee Leahy leroy.p.leahy@intel.com Date: Fri Apr 29 17:36:20 2016 -0700
soc/intel/quark: Add temperature sensor support
Migrate the temperature sensor support from QuarkFspPkg into coreboot.
TEST=Build and run on Galileo Gen2
Change-Id: I70896e6187b878ea572535432912f1d4db895a99 Signed-off-by: Lee Leahy leroy.p.leahy@intel.com --- src/soc/intel/quark/chip.c | 93 ++++++++++++++++++++++++++++ src/soc/intel/quark/include/soc/reg_access.h | 48 ++++++++++++++ src/soc/intel/quark/reg_access.c | 58 +++++++++++++++++ 3 files changed, 199 insertions(+)
diff --git a/src/soc/intel/quark/chip.c b/src/soc/intel/quark/chip.c index eb326d7..4219ccd 100644 --- a/src/soc/intel/quark/chip.c +++ b/src/soc/intel/quark/chip.c @@ -17,9 +17,102 @@ #include <console/console.h> #include <device/device.h> #include <soc/ramstage.h> +#include <soc/reg_access.h> + +/* Cat Trip Clear value must be less than Cat Trip Set value */ +#define PLATFORM_CATASTROPHIC_TRIP_CELSIUS 105 +#define PLATFORM_CATASTROPHIC_CLEAR_CELSIUS 65 + +static const struct reg_script init_script[] = { + + /* Setup RMU Thermal sensor registers for Ratiometric mode. */ + REG_SOC_UNIT_RMW(QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG, + ~(B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK + | B_TSCGF1_CONFIG_ISNSCHOPSEL_MASK + | B_TSCGF1_CONFIG_ISNSINTERNALVREFEN + | B_TSCGF1_CONFIG_IBGEN + | B_TSCGF1_CONFIG_IBGCHOPEN), + ((V_TSCGF1_CONFIG_ISNSCURRENTSEL_RATIO_MODE + << B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP) + | (V_TSCGF1_CONFIG_ISNSCHOPSEL_RATIO_MODE + << B_TSCGF1_CONFIG_ISNSCHOPSEL_BP) + | (V_TSCGF1_CONFIG_ISNSINTERNALVREFEN_RATIO_MODE + << B_TSCGF1_CONFIG_ISNSINTERNALVREFEN_BP) + | (V_TSCGF1_CONFIG_IBGEN_RATIO_MODE + << B_TSCGF1_CONFIG_IBGEN_BP) + | (V_TSCGF1_CONFIG_IBGCHOPEN_RATIO_MODE + << B_TSCGF1_CONFIG_IBGCHOPEN_BP))), + + REG_SOC_UNIT_RMW(QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2, + ~(B_TSCGF2_CONFIG2_ICALCONFIGSEL_MASK + | B_TSCGF2_CONFIG2_ISPARECTRL_MASK + | B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK), + ((V_TSCGF2_CONFIG2_ICALCONFIGSEL_RATIO_MODE + << B_TSCGF2_CONFIG2_ICALCONFIGSEL_BP) + | (V_TSCGF2_CONFIG2_ISPARECTRL_RATIO_MODE + << B_TSCGF2_CONFIG2_ISPARECTRL_BP) + | (V_TSCGF2_CONFIG2_ICALCOARSETUNE_RATIO_MODE + << B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP))), + + REG_SOC_UNIT_RMW(QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG, + ~(B_TSCGF2_CONFIG_IDSCONTROL_MASK + | B_TSCGF2_CONFIG_IDSTIMING_MASK), + ((V_TSCGF2_CONFIG_IDSCONTROL_RATIO_MODE + << B_TSCGF2_CONFIG_IDSCONTROL_BP) + | (V_TSCGF2_CONFIG_IDSTIMING_RATIO_MODE + << B_TSCGF2_CONFIG_IDSTIMING_BP))), + + REG_SOC_UNIT_RMW(QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG, + ~B_TSCGF3_CONFIG_ITSGAMMACOEFF_MASK, + V_TSCGF3_CONFIG_ITSGAMMACOEFF_RATIO_MODE + << B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP), + + /* Enable RMU Thermal sensor with a Catastrophic Trip point. */ + + /* Setup Catastrophic Trip point. + * + * Trip Register fields are 8-bit temperature values of granularity 1 + * degree C where 0x00 corresponds to -50 degrees C and 0xFF corresponds + * to 205 degrees C. + * + * Add 50 to values to Celsius values to get values for register fields. + */ + REG_RMU_TEMP_RMW(QUARK_NC_RMU_REG_TS_TRIP, + ~(TS_CAT_TRIP_SET_THOLD_MASK | TS_CAT_TRIP_CLEAR_THOLD_MASK), + (((PLATFORM_CATASTROPHIC_TRIP_CELSIUS + 50) + << TS_CAT_TRIP_SET_THOLD_BP) + | ((PLATFORM_CATASTROPHIC_CLEAR_CELSIUS + 50) + << TS_CAT_TRIP_CLEAR_THOLD_BP))), + + /* To enable the TS do the following: + * 1) Take the TS out of reset by setting itsrst to 0x0. + * 2) Enable the TS using RMU Thermal sensor mode register. + */ + REG_SOC_UNIT_AND(QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG, + ~B_TSCGF3_CONFIG_ITSRST), + REG_RMU_TEMP_OR(QUARK_NC_RMU_REG_TS_MODE, TS_ENABLE), + + /* Lock all RMU Thermal sensor control & trip point registers. */ + REG_RMU_TEMP_OR(QUARK_NC_RMU_REG_CONFIG, TS_LOCK_THRM_CTRL_REGS_ENABLE + | TS_LOCK_AUX_TRIP_PT_REGS_ENABLE), + REG_SCRIPT_END +};
static void chip_init(void *chip_info) { + /* Validate the temperature settings */ + ASSERT(PLATFORM_CATASTROPHIC_TRIP_CELSIUS <= 255); + ASSERT(PLATFORM_CATASTROPHIC_TRIP_CELSIUS + > PLATFORM_CATASTROPHIC_CLEAR_CELSIUS); + + /* Set the temperature settings */ + reg_script_run(init_script); + ASSERT((reg_rmu_temp_read(QUARK_NC_RMU_REG_CONFIG) + & (TS_LOCK_THRM_CTRL_REGS_ENABLE + | TS_LOCK_AUX_TRIP_PT_REGS_ENABLE)) + == (TS_LOCK_THRM_CTRL_REGS_ENABLE + | TS_LOCK_AUX_TRIP_PT_REGS_ENABLE)); + /* Perform silicon specific init. */ if (IS_ENABLED(CONFIG_RELOCATE_FSP_INTO_DRAM)) intel_silicon_init(); diff --git a/src/soc/intel/quark/include/soc/reg_access.h b/src/soc/intel/quark/include/soc/reg_access.h index a2e707d..90dea35 100644 --- a/src/soc/intel/quark/include/soc/reg_access.h +++ b/src/soc/intel/quark/include/soc/reg_access.h @@ -18,10 +18,13 @@
#include <fsp/util.h> #include <reg_script.h> +#include <soc/IntelQNCConfig.h> #include <soc/QuarkNcSocId.h>
enum { USB_PHY_REGS = 1, + SOC_UNIT_REGS, + RMU_TEMP_REGS, };
#if ENV_RAMSTAGE @@ -33,6 +36,50 @@ enum { #define SOC_ACCESS(cmd_, reg_, size_, mask_, value_, timeout_, reg_set_) \ _REG_SCRIPT_ENCODE_RAW(REG_SCRIPT_COMMAND_##cmd_, SOC_TYPE, \ size_, reg_, mask_, value_, timeout_, reg_set_) + +/* RMU temperature register access macros */ +#define REG_RMU_TEMP_ACCESS(cmd_, reg_, mask_, value_, timeout_) \ + SOC_ACCESS(cmd_, reg_, REG_SCRIPT_SIZE_32, mask_, value_, timeout_, \ + RMU_TEMP_REGS) +#define REG_RMU_TEMP_READ(reg_) \ + REG_RMU_TEMP_ACCESS(READ, reg_, 0, 0, 0) +#define REG_RMU_TEMP_WRITE(reg_, value_) \ + REG_RMU_TEMP_ACCESS(WRITE, reg_, 0, value_, 0) +#define REG_RMU_TEMP_AND(reg_, value_) \ + REG_RMU_TEMP_RMW(reg_, value_, 0) +#define REG_RMU_TEMP_RMW(reg_, mask_, value_) \ + REG_RMU_TEMP_ACCESS(RMW, reg_, mask_, value_, 0) +#define REG_RMU_TEMP_RXW(reg_, mask_, value_) \ + REG_RMU_TEMP_ACCESS(RXW, reg_, mask_, value_, 0) +#define REG_RMU_TEMP_OR(reg_, value_) \ + REG_RMU_TEMP_RMW(reg_, 0xffffffff, value_) +#define REG_RMU_TEMP_POLL(reg_, mask_, value_, timeout_) \ + REG_RMU_TEMP_ACCESS(POLL, reg_, mask_, value_, timeout_) +#define REG_RMU_TEMP_XOR(reg_, value_) \ + REG_RMU_TEMP_RXW(reg_, 0xffffffff, value_) + +/* Temperature sensor access macros */ +#define REG_SOC_UNIT_ACCESS(cmd_, reg_, mask_, value_, timeout_) \ + SOC_ACCESS(cmd_, reg_, REG_SCRIPT_SIZE_32, mask_, value_, timeout_, \ + SOC_UNIT_REGS) +#define REG_SOC_UNIT_READ(reg_) \ + REG_SOC_UNIT_ACCESS(READ, reg_, 0, 0, 0) +#define REG_SOC_UNIT_WRITE(reg_, value_) \ + REG_SOC_UNIT_ACCESS(WRITE, reg_, 0, value_, 0) +#define REG_SOC_UNIT_AND(reg_, value_) \ + REG_SOC_UNIT_RMW(reg_, value_, 0) +#define REG_SOC_UNIT_RMW(reg_, mask_, value_) \ + REG_SOC_UNIT_ACCESS(RMW, reg_, mask_, value_, 0) +#define REG_SOC_UNIT_RXW(reg_, mask_, value_) \ + REG_SOC_UNIT_ACCESS(RXW, reg_, mask_, value_, 0) +#define REG_SOC_UNIT_OR(reg_, value_) \ + REG_SOC_UNIT_RMW(reg_, 0xffffffff, value_) +#define REG_SOC_UNIT_POLL(reg_, mask_, value_, timeout_) \ + REG_SOC_UNIT_ACCESS(POLL, reg_, mask_, value_, timeout_) +#define REG_SOC_UNIT_XOR(reg_, value_) \ + REG_SOC_UNIT_RXW(reg_, 0xffffffff, value_) + +/* USB register access macros */ #define REG_USB_ACCESS(cmd_, reg_, mask_, value_, timeout_) \ SOC_ACCESS(cmd_, reg_, REG_SCRIPT_SIZE_32, mask_, value_, timeout_, \ USB_PHY_REGS) @@ -58,5 +105,6 @@ void mcr_write(uint8_t opcode, uint8_t port, uint32_t reg_address); uint32_t mdr_read(void); void mdr_write(uint32_t value); void mea_write(uint32_t reg_address); +uint32_t reg_rmu_temp_read(uint32_t reg_address);
#endif /* _QUARK_REG_ACCESS_H_ */ diff --git a/src/soc/intel/quark/reg_access.c b/src/soc/intel/quark/reg_access.c index b9ffb6c..e304a6d 100644 --- a/src/soc/intel/quark/reg_access.c +++ b/src/soc/intel/quark/reg_access.c @@ -46,6 +46,40 @@ void mea_write(uint32_t reg_address) }
#if ENV_RAMSTAGE +uint32_t reg_rmu_temp_read(uint32_t reg_address) +{ + /* Read the RMU temperature register */ + mea_write(reg_address); + mcr_write(QUARK_OPCODE_READ, QUARK_NC_RMU_SB_PORT_ID, reg_address); + return mdr_read(); +} + +static void reg_rmu_temp_write(uint32_t reg_address, uint32_t value) +{ + /* Write the RMU temperature register */ + mea_write(reg_address); + mdr_write(value); + mcr_write(QUARK_OPCODE_WRITE, QUARK_NC_RMU_SB_PORT_ID, reg_address); +} + +static uint32_t reg_soc_unit_read(uint32_t reg_address) +{ + /* Read the temperature sensor register */ + mea_write(reg_address); + mcr_write(QUARK_ALT_OPCODE_READ, QUARK_SCSS_SOC_UNIT_SB_PORT_ID, + reg_address); + return mdr_read(); +} + +static void reg_soc_unit_write(uint32_t reg_address, uint32_t value) +{ + /* Write the temperature sensor register */ + mea_write(reg_address); + mdr_write(value); + mcr_write(QUARK_ALT_OPCODE_WRITE, QUARK_SCSS_SOC_UNIT_SB_PORT_ID, + reg_address); +} + static uint32_t reg_usb_read(uint32_t reg_address) { /* Read the USB register */ @@ -77,6 +111,18 @@ static uint64_t reg_read(struct reg_script_context *ctx) reg_script_display = 0; return 0;
+ case RMU_TEMP_REGS: + if (reg_script_display) + printk(BIOS_INFO, "RMU TEMP: "); + value = reg_rmu_temp_read(step->reg); + break; + + case SOC_UNIT_REGS: + if (reg_script_display) + printk(BIOS_INFO, "SOC Unit: "); + value = reg_soc_unit_read(step->reg); + break; + case USB_PHY_REGS: if (reg_script_display) printk(BIOS_INFO, "USB PHY: "); @@ -98,6 +144,18 @@ static void reg_write(struct reg_script_context *ctx) reg_script_display = 0; return;
+ case RMU_TEMP_REGS: + if (reg_script_display) + printk(BIOS_INFO, "RMU TEMP: "); + reg_rmu_temp_write(step->reg, (uint32_t)step->value); + break; + + case SOC_UNIT_REGS: + if (reg_script_display) + printk(BIOS_INFO, "SOC Unit: "); + reg_soc_unit_write(step->reg, (uint32_t)step->value); + break; + case USB_PHY_REGS: if (reg_script_display) printk(BIOS_INFO, "USB PHY: ");