soc/meidatek/mt8196: Extract common thermal code for reuse
To promote code reuse and maintainability, move partial thermal driver to common. BUG=b:379008996 BRANCH=none TEST=build passed. Signed-off-by: Kai-chun Huang <kai-chun.huang@mediatek.corp-partner.google.com> Change-Id: I6a52d1cb02d04308f1e833df0f318f93a8231fe1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/88440 Reviewed-by: Yu-Ping Wu <yupingso@google.com> Reviewed-by: Yidi Lin <yidilin@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
f62734976c
commit
e583b2ffb7
8 changed files with 464 additions and 397 deletions
59
src/soc/mediatek/common/include/soc/thermal_common.h
Normal file
59
src/soc/mediatek/common/include/soc/thermal_common.h
Normal file
|
|
@ -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 <soc/thermal_internal.h>
|
||||
|
||||
#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__ */
|
||||
332
src/soc/mediatek/common/thermal.c
Normal file
332
src/soc/mediatek/common/thermal.c
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <assert.h>
|
||||
#include <delay.h>
|
||||
#include <device/mmio.h>
|
||||
#include <soc/thermal.h>
|
||||
#include <timer.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
36
src/soc/mediatek/common/thermal_sram.c
Normal file
36
src/soc/mediatek/common/thermal_sram.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/cache.h>
|
||||
#include <soc/thermal.h>
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <soc/thermal_common.h>
|
||||
|
||||
#endif /* SOC_MEDIATEK_MT8196_THERMAL_H */
|
||||
|
|
|
|||
|
|
@ -3,16 +3,20 @@
|
|||
#ifndef SOC_MEDIATEK_MT8196_THERMAL_INTERNAL_H
|
||||
#define SOC_MEDIATEK_MT8196_THERMAL_INTERNAL_H
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/mmio.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/symbols.h>
|
||||
#include <soc/thermal.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <device/mmio.h>
|
||||
#include <soc/thermal.h>
|
||||
#include <soc/thermal_internal.h>
|
||||
|
||||
#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);
|
||||
|
|
|
|||
|
|
@ -2,44 +2,14 @@
|
|||
|
||||
#include <arch/cache.h>
|
||||
#include <assert.h>
|
||||
#include <soc/thermal_internal.h>
|
||||
#include <string.h>
|
||||
#include <device/mmio.h>
|
||||
#include <soc/thermal.h>
|
||||
|
||||
/* 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue