diff --git a/src/soc/mediatek/common/include/soc/thermal_common.h b/src/soc/mediatek/common/include/soc/thermal_common.h new file mode 100644 index 0000000000..7875aec7ea --- /dev/null +++ b/src/soc/mediatek/common/include/soc/thermal_common.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_COMMON_INCLUDE_SOC_THERMAL_COMMON_H__ +#define __SOC_MEDIATEK_COMMON_INCLUDE_SOC_THERMAL_COMMON_H__ + +#include + +#define CHECK_DEVICE_ACCESS_RETRY_CNT 100 +#define LVTS_DEVICE_ACCESS_DELAY_US 3 +#define LVTS_READ_ID_RETRY_CNT 5 +#define LVTS_READ_ID_DELAY_US 3 + +enum sensor_switch_status { + SEN_OFF, + SEN_ON, +}; + +struct lvts_thermal_controller_speed { + u32 group_interval_delay; + u32 period_unit; + u32 filter_interval_delay; + u32 sensor_interval_delay; +}; + +struct lvts_thermal_controller { + enum lvts_sensor ts[MAX_TS_NUMBER]; /* sensor point */ + enum sensor_switch_status sensor_on_off[MAX_TS_NUMBER]; + size_t ts_number; + int reboot_temperature; + int dominator_ts_idx; + unsigned int reboot_msr_sram_idx; + bool has_reboot_temp_sram; + bool has_reboot_msr_sram; + struct lvts_thermal_controller_speed speed; + struct mtk_thermal_controller_regs *regs; +}; + +int lvts_write_device(uint16_t config, uint8_t dev_reg_idx, uint8_t data, int tc_num); +const struct lvts_thermal_controller *lvts_get_controller(int tc_num); +void lvts_configure_polling_speed_and_filter(const struct lvts_thermal_controller *tc); +int lvts_read_tc_raw_and_temp(void *msr_reg, enum lvts_sensor ts_name, uint32_t golden_temp); +void lvts_thermal_init(void); +void lvts_tscpu_reset_thermal(void); +void lvts_thermal_cal_prepare(void); +void lvts_device_identification(void); +void lvts_device_enable_init_all_devices(void); +void lvts_efuse_setting(void); +void lvts_config_all_tc_hw_protect(void); +uint16_t lvts_temp_to_raw(int temp_mc, enum lvts_sensor ts_name); +void lvts_tscpu_thermal_read_tc_temp(const struct lvts_thermal_controller *tc, int order); + +void thermal_cls_sram(void); +void thermal_stat_cls_sram(void); +void thermal_sram_init(void); +void thermal_init(void); +void thermal_write_reboot_temp_sram(uint32_t value); +void thermal_write_reboot_msr_sram(unsigned int idx, uint32_t value); + +#endif /* __SOC_MEDIATEK_COMMON_INCLUDE_SOC_THERMAL_COMMON_H__ */ diff --git a/src/soc/mediatek/common/thermal.c b/src/soc/mediatek/common/thermal.c new file mode 100644 index 0000000000..47babf5ee4 --- /dev/null +++ b/src/soc/mediatek/common/thermal.c @@ -0,0 +1,332 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#define LVTS_SINGLE_SENSE_MODE_EN BIT(9) +#define LVTS_SENSOR_POINT_SELECTION_SETTING 0x13121110 +#define LVTS_CALCULATION_SCALING_RULE 0x300 + +static int lvts_raw_to_temp(uint16_t msr_raw, enum lvts_sensor ts_name, uint32_t golden_temp) +{ + int temp_mc; + int64_t temp1, coeff_a; + + coeff_a = LVTS_COEFF_A; + + temp1 = (coeff_a * msr_raw) / (1 << 14); + temp_mc = temp1 + golden_temp * 500 - coeff_a; + + return temp_mc; +} + +int lvts_read_tc_raw_and_temp(void *msr_reg, enum lvts_sensor ts_name, uint32_t golden_temp) +{ + int temp; + uint32_t msr_data; + uint16_t msr_raw; + + msr_data = read32(msr_reg); + msr_raw = msr_data & 0xFFFF; + + if (msr_raw > 0) { + temp = lvts_raw_to_temp(msr_raw, ts_name, golden_temp); + } else { + /* + * 26111 is magic num. + * This is to keep system alive for a while to wait until + * HW init is done, because 0 msr raw will translate to 28x'C + * and then 28x'C will trigger a SW reset. + * + * If HW init finishes, this msr raw will not be 0, + * system can report normal temperature. + * If wait over 60 times zero, this means something wrong with HW. + */ + temp = 26111; + } + + printk(BIOS_INFO, "[LVTS_MSR] ts%d msr_all=%x, msr_temp=%d, temp=%d\n", ts_name, + msr_data, msr_raw, temp); + + return temp; +} + +static void lvts_tscpu_thermal_initial_all_tc(void) +{ + u32 i = 0; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + /* Set sensor index of LVTS */ + write32(&tc->regs->lvtstssel_0, LVTS_SENSOR_POINT_SELECTION_SETTING); + /* Set calculation scale rules */ + write32(&tc->regs->lvtscalscale_0, LVTS_CALCULATION_SCALING_RULE); + + lvts_configure_polling_speed_and_filter(tc); + } + +} + +void lvts_configure_polling_speed_and_filter(const struct lvts_thermal_controller *tc) +{ + u32 lvtsMonCtl1, lvtsMonCtl2; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + lvtsMonCtl1 = ((tc->speed.group_interval_delay << 20) & + LVTS_GROUP_INTERVAL_DELAY_MASK) | (tc->speed.period_unit & GENMASK(9, 0)); + + lvtsMonCtl2 = ((tc->speed.filter_interval_delay << 16) & GENMASK(25, 16)) | + (tc->speed.sensor_interval_delay & GENMASK(9, 0)); + + /* + * Calculating period unit in Module clock x 256, and the Module clock + * will be changed to 26M when Infrasys enters Sleep mode. + */ + + /* + * Bus clock 66M counting unit is + * 12 * 1/66M * 256 = 12 * 3.879us = 46.545 us + */ + write32(&tc->regs->lvtsmonctl1_0, lvtsMonCtl1); + /* + * Filt interval is 1 * 46.545us = 46.545us, + * sen interval is 429 * 46.545us = 19.968ms + */ + write32(&tc->regs->lvtsmonctl2_0, lvtsMonCtl2); + + /* Temperature sampling control, 1 sample */ + write32(&tc->regs->lvtsmsrctl0_0, 0); + + udelay(1); + printk(BIOS_INFO, + "%s,LVTSMONCTL1_0= %#x,LVTSMONCTL2_0= %#x,LVTSMSRCTL0_0= %#x\n", + __func__, + read32(&tc->regs->lvtsmonctl1_0), + read32(&tc->regs->lvtsmonctl2_0), + read32(&tc->regs->lvtsmsrctl0_0)); +} + +static int lvts_check_all_sensing_points_idle(void) +{ + uint32_t mask, temp; + int i; + + mask = BIT(10) | BIT(7) | BIT(0); + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + temp = read32(&tc->regs->lvtsmsrctl1_0); + if ((temp & mask) != 0) + return -1; + } + + return 0; +} + +static void lvts_wait_all_sensing_points_idle(void) +{ + if (!retry(CHECK_DEVICE_ACCESS_RETRY_CNT, + lvts_check_all_sensing_points_idle() == 0, + udelay(2))) + printk(BIOS_ERR, "%s timeout\n", __func__); +} + +static bool lvts_lk_init_check(void) +{ + int i; + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + /* Check LVTS device ID */ + if ((read32(&tc->regs->lvtsspare[0]) & GENMASK(11, 0)) != LVTS_MAGIC) + return false; + } + + return true; +} + +int lvts_write_device(uint16_t config, uint8_t dev_reg_idx, uint8_t data, int tc_num) +{ + const struct lvts_thermal_controller *tc = lvts_get_controller(tc_num); + uint32_t config_data = (config << 16) | (dev_reg_idx << 8) | data; + + write32(&tc->regs->lvts_config_0, config_data); + /* + * LVTS Device Register Setting takes 1us (by 26MHz clock source) + * interface latency to access. + * So we set 2~3 us delay could guarantee access complete. + */ + udelay(LVTS_DEVICE_ACCESS_DELAY_US); + + /* + * Check ASIF bus status for transaction finished + * Wait until DEVICE_ACCESS_START_BIT = 0 + */ + if (!retry(CHECK_DEVICE_ACCESS_RETRY_CNT, + !(read32(&tc->regs->lvts_config_0) & DEVICE_ACCESS_START_BIT), udelay(2))) { + printk(BIOS_ERR, "DEVICE_ACCESS_START_BIT didn't ready, reg0x%x\n", + dev_reg_idx); + } + return 1; +} + +static void lvts_enable_sensing_points(const struct lvts_thermal_controller *tc) +{ + int i; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + uint32_t value = LVTS_SINGLE_SENSE_MODE_EN; + + for (i = 0; i < tc->ts_number; i++) { + if (tc->sensor_on_off[i] == SEN_ON) + value |= BIT(i); + } + + write32(&tc->regs->lvtsmonctl0_0, value); + + printk(BIOS_INFO, "%s,value in LVTSMONCTL0_0 = %#x\n", __func__, value); +} + +/* + * disable ALL periodoc temperature sensing point + */ +static void lvts_disable_all_sensing_points(void) +{ + int i; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + write32(&tc->regs->lvtsmonctl0_0, LVTS_SINGLE_SENSE_MODE_EN); + } +} + +static void lvts_enable_all_sensing_points(void) +{ + int i = 0; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + lvts_enable_sensing_points(tc); + } +} + +static void lvts_set_init_flag(void) +{ + u32 i; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + /*write init done flag to inform kernel */ + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + printk(BIOS_INFO, "%s %d:%zu, tc_base_addr:%p\n", __func__, i, + tc->ts_number, tc->regs); + + write32(&tc->regs->lvtsspare[0], LVTS_MAGIC); + } +} + +static void lvts_set_tc_trigger_hw_protect(const struct lvts_thermal_controller *tc) +{ + int d_index, i; + uint32_t raw_high; + uint16_t raw; + enum lvts_sensor ts_name; + + if (tc->dominator_ts_idx < tc->ts_number) { + d_index = tc->dominator_ts_idx; + } else { + printk(BIOS_ERR, "LVTS, dominator_ts_idx %d >= ts_number %zu; use idx 0\n", + tc->dominator_ts_idx, tc->ts_number); + d_index = 0; + } + + ts_name = tc->ts[d_index]; + + printk(BIOS_INFO, "%s, the dominator ts_name is %d\n", __func__, ts_name); + + /* Maximum of 4 sensing points */ + raw_high = 0; + for (i = 0; i < tc->ts_number; i++) { + ts_name = tc->ts[i]; + raw = lvts_temp_to_raw(tc->reboot_temperature, ts_name); + raw_high = MAX(raw_high, raw); + } + if (tc->has_reboot_msr_sram) + thermal_write_reboot_msr_sram(tc->reboot_msr_sram_idx, raw_high); + if (tc->has_reboot_temp_sram) + thermal_write_reboot_temp_sram(tc->reboot_temperature); + + setbits32(&tc->regs->lvtsprotctl_0, 0x3FFF); + /* disable trigger SPM interrupt */ + write32(&tc->regs->lvtsmonint_0, 0); + + clrsetbits32(&tc->regs->lvtsprotctl_0, 0xF << 16, BIT(16)); + + write32(&tc->regs->lvtsprottc_0, raw_high); + + /* enable trigger Hot SPM interrupt */ + write32(&tc->regs->lvtsmonint_0, STAGE3_INT_EN); + + clrbits32(&tc->regs->lvtsprotctl_0, 0xFFFF); +} + +void lvts_config_all_tc_hw_protect(void) +{ + int i; + + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + lvts_set_tc_trigger_hw_protect(tc); + } +} + +static void read_all_tc_lvts_temperature(void) +{ + int i, j; + + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); + for (j = 0; j < tc->ts_number; j++) + lvts_tscpu_thermal_read_tc_temp(tc, j); + } +} + +void lvts_thermal_init(void) +{ + printk(BIOS_INFO, "===== %s begin ======\n", __func__); + + if (lvts_lk_init_check()) + return; + + lvts_tscpu_reset_thermal(); + + lvts_thermal_cal_prepare(); + lvts_device_identification(); + lvts_device_enable_init_all_devices(); + lvts_efuse_setting(); + + lvts_disable_all_sensing_points(); + lvts_wait_all_sensing_points_idle(); + lvts_tscpu_thermal_initial_all_tc(); + lvts_config_all_tc_hw_protect(); + lvts_enable_all_sensing_points(); + + lvts_set_init_flag(); + + printk(BIOS_INFO, "%s: thermal initialized\n", __func__); + + read_all_tc_lvts_temperature(); +} diff --git a/src/soc/mediatek/common/thermal_sram.c b/src/soc/mediatek/common/thermal_sram.c new file mode 100644 index 0000000000..3282c84599 --- /dev/null +++ b/src/soc/mediatek/common/thermal_sram.c @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void thermal_cls_sram(void) +{ + int i = 0; + const uint32_t pattern = 0x27BC86AA; + uint32_t *buff = (uint32_t *)THERMAL_SRAM_BASE; + for (i = 0; i < THERMAL_SRAM_LEN / sizeof(*buff); i++) { + *buff = pattern; + buff++; + } + dcache_clean_invalidate_by_mva((void *)THERMAL_SRAM_BASE, THERMAL_SRAM_LEN); +} + +void thermal_stat_cls_sram(void) +{ + int i = 0; + const uint32_t pattern = 0xFFFFFFFF; + uint32_t *buff = (uint32_t *)THERMAL_STAT_SRAM_BASE; + for (i = 0; i < THERMAL_STAT_SRAM_LEN / sizeof(*buff); i++) { + *buff = pattern; + buff++; + } + dcache_clean_invalidate_by_mva((void *)THERMAL_STAT_SRAM_BASE, THERMAL_STAT_SRAM_LEN); +} + +__weak void thermal_write_reboot_temp_sram(uint32_t value) +{ +} + +__weak void thermal_write_reboot_msr_sram(unsigned int idx, uint32_t value) +{ +} diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index 9426d157db..762dcb17cb 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -50,8 +50,8 @@ romstage-y += ../common/pmif.c pmif_init.c romstage-y += ../common/rtc.c ../common/rtc_osc_init.c romstage-y += ../common/pmif_spmi_v2.c pmif_spmi.c romstage-y += ../common/srclken_rc.c srclken_rc.c -romstage-y += thermal.c -romstage-y += thermal_sram.c +romstage-y += ../common/thermal.c thermal.c +romstage-y += ../common/thermal_sram.c thermal_sram.c ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += ../common/bl31.c ramstage-y += dcc.c diff --git a/src/soc/mediatek/mt8196/include/soc/thermal.h b/src/soc/mediatek/mt8196/include/soc/thermal.h index 2494853f99..b1bab82099 100644 --- a/src/soc/mediatek/mt8196/include/soc/thermal.h +++ b/src/soc/mediatek/mt8196/include/soc/thermal.h @@ -3,9 +3,6 @@ #ifndef SOC_MEDIATEK_MT8196_THERMAL_H #define SOC_MEDIATEK_MT8196_THERMAL_H -void thermal_sram_init(void); -void thermal_init(void); -void thermal_write_reboot_temp_sram(uint32_t value); -void thermal_write_reboot_msr_sram(unsigned int idx, uint32_t value); +#include #endif /* SOC_MEDIATEK_MT8196_THERMAL_H */ diff --git a/src/soc/mediatek/mt8196/include/soc/thermal_internal.h b/src/soc/mediatek/mt8196/include/soc/thermal_internal.h index 65c053d21e..180c349b9c 100644 --- a/src/soc/mediatek/mt8196/include/soc/thermal_internal.h +++ b/src/soc/mediatek/mt8196/include/soc/thermal_internal.h @@ -3,16 +3,20 @@ #ifndef SOC_MEDIATEK_MT8196_THERMAL_INTERNAL_H #define SOC_MEDIATEK_MT8196_THERMAL_INTERNAL_H -#include -#include #include #include -#include -#include #define LVTS_MAGIC 0x0000555 #define MAX_TS_NUMBER 4 +/* SRAM for Thermal */ +#define THERMAL_SRAM_BASE (_mcufw_reserved + 0x1000) +#define THERMAL_SRAM_LEN 0x400 + +/* SRAM for Thermal state */ +#define THERMAL_STAT_SRAM_BASE ((uintptr_t)_sram + 0x0001A800) +#define THERMAL_STAT_SRAM_LEN 0x400 + /* private thermal sensor enum */ enum lvts_sensor { L_TS_LVTS11_0 = 0, /* LVTS11-0 SOC-TOP */ @@ -37,30 +41,6 @@ enum lvts_tc_offset { TS_OFFSET_AP_CONTROLLER1 = 0x100, }; -enum sensor_switch_status { - SEN_OFF, - SEN_ON, -}; - -struct lvts_thermal_controller_speed { - uint32_t group_interval_delay; - uint32_t period_unit; - uint32_t filter_interval_delay; - uint32_t sensor_interval_delay; -}; - -struct lvts_thermal_controller { - enum lvts_sensor ts[MAX_TS_NUMBER]; - enum sensor_switch_status sensor_on_off[MAX_TS_NUMBER]; - size_t ts_number; - int reboot_temperature; - int dominator_ts_idx; - unsigned int reboot_msr_sram_idx; - bool has_reboot_temp_sram; - struct lvts_thermal_controller_speed speed; - struct mtk_thermal_controller_regs *regs; -}; - /* LVTS Thermal Controller Register Definition */ static struct mtk_thermal_controller_regs *const mtk_lvts_ap_controller0 = (void *)(THERM_CTRL_BASE + TS_OFFSET_AP_CONTROLLER0); @@ -154,8 +134,10 @@ check_member(mtk_thermal_controller_regs, lvtsspare, 0x0f0); #define AP_RST_CLR (INFRACFG_AO_SEC_BASE + 0xf34) #define LVTS_COF_T_SLP_GLD 391460 +#define LVTS_COEFF_A LVTS_COF_T_SLP_GLD #define LVTS_COF_COUNT_R_GLD 34412 #define LVTS_COF_T_CONST_OFS 0 +#define LVTS_GROUP_INTERVAL_DELAY_MASK GENMASK(31, 17) #define DEFAULT_EFUSE_GOLDEN_TEMP 60 #define DEFAULT_EFUSE_COUNT 34389 diff --git a/src/soc/mediatek/mt8196/thermal.c b/src/soc/mediatek/mt8196/thermal.c index 7ea2725283..ef4f73eaca 100644 --- a/src/soc/mediatek/mt8196/thermal.c +++ b/src/soc/mediatek/mt8196/thermal.c @@ -3,11 +3,10 @@ #include #include #include +#include #include -#include #define LVTS_DEVICE_ACCESS_DELAY_US 3 -#define CHECK_DEVICE_ACCESS_RETRY_CNT 100 #define THERMAL_LVTS_MSR_OFT 64552 #define LVTS_READ_ID_DELAY_US 3 #define LVTS_READ_ID_RETRY_CNT 5 @@ -44,6 +43,7 @@ static const struct lvts_thermal_controller lvts_tscpu_g_tc[LVTS_CONTROLLER_NUM] .reboot_temperature = 118800, .dominator_ts_idx = 0, .reboot_msr_sram_idx = 0, + .has_reboot_msr_sram = true, .has_reboot_temp_sram = true, .speed = { .group_interval_delay = 0x7fff, @@ -60,6 +60,7 @@ static const struct lvts_thermal_controller lvts_tscpu_g_tc[LVTS_CONTROLLER_NUM] .reboot_temperature = 118800, .dominator_ts_idx = 0, .reboot_msr_sram_idx = 1, + .has_reboot_msr_sram = true, .has_reboot_temp_sram = false, .speed = { .group_interval_delay = 0x7fff, @@ -75,58 +76,24 @@ static uint32_t golden_temp; static uint32_t ts_edata[L_TS_LVTS_NUM]; static uint8_t op_cali[LVTS_CONTROLLER_NUM]; -static int lvts_write_device(uint16_t config, uint8_t dev_reg_idx, uint8_t data, int tc_num) +const struct lvts_thermal_controller *lvts_get_controller(int tc_num) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[tc_num]; - uint32_t config_data = (config << 16) | (dev_reg_idx << 8) | data; + assert(tc_num < LVTS_CONTROLLER_NUM); - write32(&tc->regs->lvts_config_0, config_data); - - /* - * LVTS Device Register Setting takes 1us (by 26MHz clock source) - * interface latency to access. - * So we set 2~3 us delay could guarantee access complete. - */ - udelay(LVTS_DEVICE_ACCESS_DELAY_US); - - /* - * Check ASIF bus status for transaction finished - * Wait until DEVICE_ACCESS_START = 0 - */ - if (!retry(CHECK_DEVICE_ACCESS_RETRY_CNT, - !(read32(&tc->regs->lvts_config_0) & DEVICE_ACCESS_START_BIT), udelay(2))) { - printk(BIOS_ERR, "DEVICE_ACCESS_START didn't ready, reg0x%x\n", - dev_reg_idx); - } - - return 1; -} - -static int lvts_raw_to_temp(uint16_t msr_raw, enum lvts_sensor ts_name) -{ - /* In millidegree Celsius */ - int temp_mc; - int64_t temp1, coff_a; - - coff_a = LVTS_COF_T_SLP_GLD; - - temp1 = (coff_a * msr_raw) / (1 << 14); - temp_mc = temp1 + golden_temp * 500 - coff_a; - - return temp_mc; + return &lvts_tscpu_g_tc[tc_num]; } /* * The return value is NOT the same as the argument `msr_raw` of lvts_raw_to_temp. * Instead, it is equal to "(1 << 28) / msr_raw". */ -static uint16_t lvts_temp_to_raw(int temp_mc, enum lvts_sensor ts_name) +uint16_t lvts_temp_to_raw(int temp_mc, enum lvts_sensor ts_name) { uint32_t msr_raw = 0; int64_t coff_a = 0; int64_t temp1; - coff_a = LVTS_COF_T_SLP_GLD; + coff_a = LVTS_COEFF_A; temp1 = (int64_t)temp_mc - (golden_temp * 500) + coff_a; assert(temp1 > 0); @@ -137,7 +104,7 @@ static uint16_t lvts_temp_to_raw(int temp_mc, enum lvts_sensor ts_name) return msr_raw; } -static void lvts_efuse_setting(void) +void lvts_efuse_setting(void) { int i, j, s_index; uint32_t efuse_data; @@ -145,8 +112,8 @@ static void lvts_efuse_setting(void) printk(BIOS_INFO, "%s\n", __func__); - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); val_0 = 0; val_1 = 0; for (j = 0; j < tc->ts_number; j++) { @@ -196,14 +163,14 @@ static void lvts_efuse_setting(void) } } -static void lvts_device_identification(void) +void lvts_device_identification(void) { uint32_t dev_id, data; int i; printk(BIOS_INFO, "===== %s begin ======\n", __func__); - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { + const struct lvts_thermal_controller *tc = lvts_get_controller(i); /* Enable LVTS_CTRL Clock */ write32(&tc->regs->lvtsclken_0, 0x00000001); @@ -228,12 +195,12 @@ static void lvts_device_identification(void) } } -static void lvts_device_enable_init_all_devices(void) +void lvts_device_enable_init_all_devices(void) { int i; uint8_t cali_0, cali_1; - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { + for (i = 0; i < LVTS_CONTROLLER_NUM; i++) { /* Stop Counting (RG_TSFM_ST=0) */ lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x03, 0x00, i); @@ -252,7 +219,7 @@ static void lvts_device_enable_init_all_devices(void) } } -static void lvts_thermal_cal_prepare(void) +void lvts_thermal_cal_prepare(void) { uint32_t temp[7]; int i, j; @@ -316,38 +283,7 @@ static void lvts_thermal_cal_prepare(void) write32(&lvts_tscpu_g_tc[LVTS_AP_CONTROLLER0].regs->lvtsspare[1], golden_temp); } -static int lvts_read_tc_raw_and_temp(void *msr_reg, enum lvts_sensor ts_name) -{ - int temp; - uint32_t msr_data; - uint16_t msr_raw; - - msr_data = read32(msr_reg); - msr_raw = msr_data & 0xFFFF; - - if (msr_raw > 0) { - temp = lvts_raw_to_temp(msr_raw, ts_name); - } else { - /* - * 26111 is magic num. - * This is to keep system alive for a while to wait until - * HW init is done, because 0 msr raw will translate to 28x'C - * and then 28x'C will trigger a SW reset. - * - * If HW init finishes, this msr raw will not be 0, - * system can report normal temperature. - * If wait over 60 times zero, this means something wrong with HW. - */ - temp = 26111; - } - - printk(BIOS_INFO, "[LVTS_MSR] ts%d msr_all=%x, msr_temp=%d, temp=%d\n", ts_name, - msr_data, msr_raw, temp); - - return temp; -} - -static void lvts_tscpu_thermal_read_tc_temp(const struct lvts_thermal_controller *tc, int order) +void lvts_tscpu_thermal_read_tc_temp(const struct lvts_thermal_controller *tc, int order) { uint32_t rg_temp; enum lvts_sensor ts_name = tc->ts[order]; @@ -355,163 +291,16 @@ static void lvts_tscpu_thermal_read_tc_temp(const struct lvts_thermal_controller ASSERT(order < ARRAY_SIZE(tc->regs->lvtsatp)); - temperature = lvts_read_tc_raw_and_temp(&tc->regs->lvtsatp[order], ts_name); + temperature = lvts_read_tc_raw_and_temp(&tc->regs->lvtsatp[order], + ts_name, + golden_temp); rg_temp = read32(&tc->regs->lvtstemp[order]) & 0x7FFFFF; printk(BIOS_INFO, "%s order %d ts_name %d temp %d rg_temp %d(%d)\n", __func__, order, ts_name, temperature, (rg_temp * 1000 / 1024), rg_temp); } -static void read_all_tc_lvts_temperature(void) -{ - int i, j; - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - for (j = 0; j < tc->ts_number; j++) - lvts_tscpu_thermal_read_tc_temp(tc, j); - } -} - -static void lvts_enable_sensing_points(const struct lvts_thermal_controller *tc) -{ - int i; - - printk(BIOS_INFO, "===== %s begin ======\n", __func__); - uint32_t value = LVTS_SINGLE_SENSE_MODE_EN; - - for (i = 0; i < tc->ts_number; i++) { - if (tc->sensor_on_off[i] == SEN_ON) - value |= BIT(i); - } - - write32(&tc->regs->lvtsmonctl0_0, value); - - printk(BIOS_INFO, "%s, value in LVTSMONCTL0_0 = %#x\n", __func__, value); -} - -/* - * disable ALL periodoc temperature sensing point - */ -static void lvts_disable_all_sensing_points(void) -{ - int i = 0; - - printk(BIOS_INFO, "%s\n", __func__); - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - write32(&tc->regs->lvtsmonctl0_0, LVTS_SINGLE_SENSE_MODE_EN); - } -} - -static int lvts_check_all_sensing_points_idle(void) -{ - uint32_t mask, temp; - int i; - - mask = BIT(10) | BIT(7) | BIT(0); - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - temp = read32(&tc->regs->lvtsmsrctl1_0); - if ((temp & mask) != 0) - return -1; - } - - return 0; -} - -static void lvts_wait_all_sensing_points_idle(void) -{ - if (!retry(CHECK_SENSING_POINTS_IDLE_RETRY_CNT, - lvts_check_all_sensing_points_idle() == 0, - udelay(2))) - printk(BIOS_ERR, "%s timeout\n", __func__); -} - -static void lvts_enable_all_sensing_points(void) -{ - int i = 0; - - printk(BIOS_INFO, "%s\n", __func__); - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - lvts_enable_sensing_points(tc); - } -} - -static void lvts_set_init_flag(void) -{ - int i; - - printk(BIOS_INFO, "%s\n", __func__); - - /* write init done flag to inform kernel */ - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - printk(BIOS_INFO, "%s %d:%zu, tc_base_addr:%p\n", __func__, i, - tc->ts_number, tc->regs); - - write32(&tc->regs->lvtsspare[0], LVTS_MAGIC); - } -} - -static void lvts_configure_polling_speed_and_filter(const struct lvts_thermal_controller *tc) -{ - uint32_t lvts_mon_ctl1, lvts_mon_ctl2; - - lvts_mon_ctl1 = (((tc->speed.group_interval_delay << 17) & GENMASK(31, 17)) | - (tc->speed.period_unit & GENMASK(9, 0))); - - lvts_mon_ctl2 = (((tc->speed.filter_interval_delay << 16) & GENMASK(25, 16)) | - (tc->speed.sensor_interval_delay & GENMASK(9, 0))); - - /* - * Calculate period unit in Module clock x 256, and the Module clock - * will be changed to 26M when Infrasys enters Sleep mode. - */ - - /* - * bus clock 66M counting unit is - * 12 * 1/66M * 256 = 12 * 3.879us = 46.545 us - */ - write32(&tc->regs->lvtsmonctl1_0, lvts_mon_ctl1); - /* - * filt interval is 1 * 46.545us = 46.545us, - * sen interval is 429 * 46.545us = 19.968ms - */ - write32(&tc->regs->lvtsmonctl2_0, lvts_mon_ctl2); - - /* temperature sampling control, 1 sample */ - write32(&tc->regs->lvtsmsrctl0_0, 0); - - udelay(1); - printk(BIOS_INFO, "%s, LVTSMONCTL1_0= 0x%x,LVTSMONCTL2_0= 0x%x,LVTSMSRCTL0_0= 0x%x\n", - __func__, read32(&tc->regs->lvtsmonctl1_0), read32(&tc->regs->lvtsmonctl2_0), - read32(&tc->regs->lvtsmsrctl0_0)); -} - -static void lvts_tscpu_thermal_initial_all_tc(void) -{ - uint32_t i = 0; - - printk(BIOS_INFO, "%s\n", __func__); - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - /* set sensor index of LVTS */ - write32(&tc->regs->lvtstssel_0, LVTS_SENSOR_POINT_SELECTION_SETTING); - /* set calculation scale rules */ - write32(&tc->regs->lvtscalscale_0, LVTS_CALCULATION_SCALING_RULE); - - lvts_configure_polling_speed_and_filter(tc); - } - -} - -static void lvts_tscpu_reset_thermal(void) +void lvts_tscpu_reset_thermal(void) { /* Enable thermal control software reset */ write32p(AP_RST_SET, BIT(11)); @@ -520,104 +309,6 @@ static void lvts_tscpu_reset_thermal(void) write32p(AP_RST_CLR, BIT(11)); } -static void lvts_set_tc_trigger_hw_protect(const struct lvts_thermal_controller *tc) -{ - int d_index, i; - uint32_t raw_high; - uint16_t raw; - enum lvts_sensor ts_name; - - if (tc->dominator_ts_idx < tc->ts_number) { - d_index = tc->dominator_ts_idx; - } else { - printk(BIOS_ERR, "LVTS, dominator_ts_idx %d >= ts_number %zu; use idx 0\n", - tc->dominator_ts_idx, tc->ts_number); - d_index = 0; - } - - ts_name = tc->ts[d_index]; - - printk(BIOS_INFO, "%s, the dominator ts_name is %d\n", __func__, ts_name); - - /* Maximum of 4 sensing points */ - raw_high = 0; - for (i = 0; i < tc->ts_number; i++) { - ts_name = tc->ts[i]; - raw = lvts_temp_to_raw(tc->reboot_temperature, ts_name); - raw_high = MAX(raw_high, raw); - } - - thermal_write_reboot_msr_sram(tc->reboot_msr_sram_idx, raw_high); - if (tc->has_reboot_temp_sram) - thermal_write_reboot_temp_sram(tc->reboot_temperature); - - setbits32(&tc->regs->lvtsprotctl_0, 0x3FFF); - /* disable trigger SPM interrupt */ - write32(&tc->regs->lvtsmonint_0, 0); - - clrsetbits32(&tc->regs->lvtsprotctl_0, 0xF << 16, BIT(16)); - - write32(&tc->regs->lvtsprottc_0, raw_high); - - /* enable trigger Hot SPM interrupt */ - write32(&tc->regs->lvtsmonint_0, STAGE3_INT_EN); - - clrbits32(&tc->regs->lvtsprotctl_0, 0xFFFF); -} - -static void lvts_config_all_tc_hw_protect(void) -{ - int i = 0; - - printk(BIOS_INFO, "===== %s begin ======\n", __func__); - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - lvts_set_tc_trigger_hw_protect(tc); - } -} - -static bool lvts_lk_init_check(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(lvts_tscpu_g_tc); i++) { - const struct lvts_thermal_controller *tc = &lvts_tscpu_g_tc[i]; - /* Check LVTS device ID */ - if ((read32(&tc->regs->lvtsspare[0]) & GENMASK(11, 0)) != LVTS_MAGIC) - return false; - } - - return true; -} - -static void lvts_thermal_init(void) -{ - printk(BIOS_INFO, "===== %s begin ======\n", __func__); - - if (lvts_lk_init_check()) - return; - - lvts_tscpu_reset_thermal(); - - lvts_thermal_cal_prepare(); - lvts_device_identification(); - lvts_device_enable_init_all_devices(); - lvts_efuse_setting(); - - lvts_disable_all_sensing_points(); - lvts_wait_all_sensing_points_idle(); - lvts_tscpu_thermal_initial_all_tc(); - lvts_config_all_tc_hw_protect(); - lvts_enable_all_sensing_points(); - - lvts_set_init_flag(); - - printk(BIOS_INFO, "%s: thermal initialized\n", __func__); - - read_all_tc_lvts_temperature(); -} - static void reset_cpu_lvts(void) { write32p(CPU_LVTS_RESET_ADDR, 1); diff --git a/src/soc/mediatek/mt8196/thermal_sram.c b/src/soc/mediatek/mt8196/thermal_sram.c index eb36bf478e..789f240024 100644 --- a/src/soc/mediatek/mt8196/thermal_sram.c +++ b/src/soc/mediatek/mt8196/thermal_sram.c @@ -2,44 +2,14 @@ #include #include -#include -#include +#include +#include /* SRAM for Thermal */ -#define THERMAL_SRAM_BASE (_mcufw_reserved + 0x1000) -#define THERMAL_SRAM_LEN 0x400 #define THERMAL_REBOOT_TEMP_SRAM_OFFSET 0x39C #define THERMAL_REBOOT_MSR_SRAM_OFFSET 0x340 #define THERMAL_REBOOT_MSR_SRAM_LEN (6 * 4) -static void thermal_cls_sram(void) -{ - int i = 0; - const uint32_t pattern = 0x27BC86AA; - uint32_t *buff = (uint32_t *)THERMAL_SRAM_BASE; - for (i = 0; i < THERMAL_SRAM_LEN / sizeof(*buff); i++) { - *buff = pattern; - buff++; - } - dcache_clean_invalidate_by_mva((void *)THERMAL_SRAM_BASE, THERMAL_SRAM_LEN); -} - -/* SRAM for Thermal state */ -#define THERMAL_STAT_SRAM_BASE ((uintptr_t)_sram + 0x0001A800) -#define THERMAL_STAT_SRAM_LEN 0x400 - -static void thermal_stat_cls_sram(void) -{ - int i = 0; - const uint32_t pattern = 0xFFFFFFFF; - uint32_t *buff = (uint32_t *)THERMAL_STAT_SRAM_BASE; - for (i = 0; i < THERMAL_STAT_SRAM_LEN / sizeof(*buff); i++) { - *buff = pattern; - buff++; - } - dcache_clean_invalidate_by_mva((void *)THERMAL_STAT_SRAM_BASE, THERMAL_STAT_SRAM_LEN); -} - /* SRAM for GPU Thermal state */ #define GPU_THERMAL_STAT_SRAM_BASE ((uintptr_t)_sram + 0x00017C00) #define GPU_THERMAL_STAT_SRAM_LEN 0x400