soc/mediatek/mt8189: Add thermal driver
Add MT8189 thermal driver for LVTS (low voltage thermal sensor) initialization. BUG=b:379008996 BRANCH=none TEST=temperature log should between 30~50 degrees: [INFO ] thermal_init: thermal initialized [INFO ] [LVTS_MSR] ts0 msr_all=13c50, valid=1, msr_temp=15440, temp=44430 [INFO ] [LVTS_MSR] ts1 msr_all=13c41, valid=1, msr_temp=15425, temp=44660 [INFO ] [LVTS_MSR] ts2 msr_all=13c3f, valid=1, msr_temp=15423, temp=44690 [INFO ] [LVTS_MSR] ts3 msr_all=13c4e, valid=1, msr_temp=15438, temp=44461 [INFO ] [LVTS_MSR] ts4 msr_all=13bc6, valid=1, msr_temp=15302, temp=46540 [INFO ] [LVTS_MSR] ts5 msr_all=13bd2, valid=1, msr_temp=15314, temp=46356 [INFO ] [LVTS_MSR] ts6 msr_all=13bd1, valid=1, msr_temp=15313, temp=46372 [INFO ] [LVTS_MSR] ts7 msr_all=13bc9, valid=1, msr_temp=15305, temp=46494 [INFO ] [LVTS_MSR] ts8 msr_all=13bed, valid=1, msr_temp=15341, temp=45944 [INFO ] [LVTS_MSR] ts9 msr_all=13be3, valid=1, msr_temp=15331, temp=46097 [INFO ] [LVTS_MSR] ts10 msr_all=13c01, valid=1, msr_temp=15361, temp=45638 [INFO ] [LVTS_MSR] ts11 msr_all=13bc6, valid=1, msr_temp=15302, temp=46540 [INFO ] [LVTS_MSR] ts12 msr_all=13c06, valid=1, msr_temp=15366, temp=45562 [INFO ] [LVTS_MSR] ts13 msr_all=13c03, valid=1, msr_temp=15363, temp=45607 [INFO ] [LVTS_MSR] ts14 msr_all=13bf3, valid=1, msr_temp=15347, temp=45852 [INFO ] [LVTS_MSR] ts15 msr_all=13c1a, valid=1, msr_temp=15386, temp=45256 [INFO ] [LVTS_MSR] ts16 msr_all=13c8b, valid=1, msr_temp=15499, temp=43528 [INFO ] [LVTS_MSR] ts17 msr_all=13c8b, valid=1, msr_temp=15499, temp=43528 Signed-off-by: Raymond Sun <raymond.sun@mediatek.corp-partner.google.com> Signed-off-by: Kai-chun Huang <kai-chun.huang@mediatek.corp-partner.google..com> Change-Id: I37dd9da6592146ade556660fa07d2fa374646da5 Reviewed-on: https://review.coreboot.org/c/coreboot/+/88441 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
5cc4b9e6ce
commit
6aec09875b
11 changed files with 662 additions and 3 deletions
|
|
@ -9,8 +9,10 @@ DECLARE_REGION(dram_dma)
|
|||
DECLARE_REGION(resv_mem_optee)
|
||||
DECLARE_REGION(resv_mem_gpu)
|
||||
DECLARE_REGION(resv_mem_gpueb)
|
||||
DECLARE_REGION(cpucooler_reserved)
|
||||
DECLARE_REGION(dvfs2_reserved)
|
||||
DECLARE_REGION(ptp1_reserved)
|
||||
DECLARE_REGION(thermal_reserved)
|
||||
DECLARE_OPTIONAL_REGION(mcufw_reserved)
|
||||
|
||||
#endif /* _SOC_MEDIATEK_COMMON_SYMBOLS_H_ */
|
||||
|
|
|
|||
|
|
@ -38,8 +38,10 @@ struct lvts_thermal_controller {
|
|||
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);
|
||||
void lvts_set_device_single_mode(int tc_num);
|
||||
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_clock_gate_disable(void);
|
||||
void lvts_tscpu_reset_thermal(void);
|
||||
void lvts_thermal_cal_prepare(void);
|
||||
void lvts_device_identification(void);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@
|
|||
#define LVTS_SENSOR_POINT_SELECTION_SETTING 0x13121110
|
||||
#define LVTS_CALCULATION_SCALING_RULE 0x300
|
||||
|
||||
__weak void lvts_set_device_single_mode(int tc_num)
|
||||
{
|
||||
}
|
||||
|
||||
__weak void lvts_clock_gate_disable(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int lvts_raw_to_temp(uint16_t msr_raw, enum lvts_sensor ts_name, uint32_t golden_temp)
|
||||
{
|
||||
int temp_mc;
|
||||
|
|
@ -66,6 +74,8 @@ static void lvts_tscpu_thermal_initial_all_tc(void)
|
|||
write32(&tc->regs->lvtstssel_0, LVTS_SENSOR_POINT_SELECTION_SETTING);
|
||||
/* Set calculation scale rules */
|
||||
write32(&tc->regs->lvtscalscale_0, LVTS_CALCULATION_SCALING_RULE);
|
||||
/* Set Device Single mode */
|
||||
lvts_set_device_single_mode(i);
|
||||
|
||||
lvts_configure_polling_speed_and_filter(tc);
|
||||
}
|
||||
|
|
@ -311,6 +321,8 @@ void lvts_thermal_init(void)
|
|||
if (lvts_lk_init_check())
|
||||
return;
|
||||
|
||||
lvts_clock_gate_disable();
|
||||
|
||||
lvts_tscpu_reset_thermal();
|
||||
|
||||
lvts_thermal_cal_prepare();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ romstage-y += dvfs.c
|
|||
romstage-y += ../common/emi.c
|
||||
romstage-y += ../common/memory.c ../common/memory_test.c ../common/memory_type.c
|
||||
romstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c
|
||||
romstage-y += ../common/thermal.c thermal.c
|
||||
romstage-y += ../common/thermal_sram.c thermal_sram.c
|
||||
romstage-y += ../common/mt6315.c mt6315.c
|
||||
romstage-y += ../common/mt6359p.c mt6359p.c
|
||||
romstage-y += ../common/pmif.c ../common/pmif_clk.c ../common/pmif_init.c pmif_clk.c
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ enum {
|
|||
INFRA_AO_BCRM_BASE = IO_PHYS + 0x00022000,
|
||||
DEVAPC_INFRA_AO_BASE = IO_PHYS + 0x00030000,
|
||||
DEVAPC_INFRA_AO1_BASE = IO_PHYS + 0x00034000,
|
||||
INFRACFG_BASE = IO_PHYS + 0x0020E000,
|
||||
EMI0_BASE = IO_PHYS + 0x00219000,
|
||||
EMI0_MPU_BASE = IO_PHYS + 0x00226000,
|
||||
DRAMC_CHA_AO_BASE = IO_PHYS + 0x00230000,
|
||||
|
|
|
|||
|
|
@ -4,19 +4,23 @@
|
|||
#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_EFUSE_H__
|
||||
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/thermal_internal.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct efuse_regs {
|
||||
u32 reserved1[96];
|
||||
u32 adc_cali_reg;
|
||||
u32 reserved2[391];
|
||||
u32 reserved2[8];
|
||||
u32 lvts_reg[LVTS_ADDRESS_INDEX_NUM];
|
||||
u32 reserved3[360];
|
||||
u32 cpu_id_reg;
|
||||
u32 reserved3[15];
|
||||
u32 reserved4[15];
|
||||
u32 cpu_seg_id_reg;
|
||||
u32 reserved4[14908];
|
||||
u32 reserved5[14908];
|
||||
u32 ecc_status_reg;
|
||||
};
|
||||
check_member(efuse_regs, adc_cali_reg, 0x180);
|
||||
check_member(efuse_regs, lvts_reg, 0x1A4);
|
||||
check_member(efuse_regs, cpu_id_reg, 0x7A0);
|
||||
check_member(efuse_regs, cpu_seg_id_reg, 0x7E0);
|
||||
check_member(efuse_regs, ecc_status_reg, 0xF0D4);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct mtk_infracfg_ao_regs {
|
|||
};
|
||||
check_member(mtk_infracfg_ao_regs, infra_bus_dcm_ctrl, 0x0070);
|
||||
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_0_set, 0x0080);
|
||||
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_0_clr, 0x0084);
|
||||
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_1, 0x0094);
|
||||
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_2_set, 0x00A4);
|
||||
check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_3_set, 0x00C0);
|
||||
|
|
|
|||
8
src/soc/mediatek/mt8189/include/soc/thermal.h
Normal file
8
src/soc/mediatek/mt8189/include/soc/thermal.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_THERMAL_H__
|
||||
#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_THERMAL_H__
|
||||
|
||||
#include <soc/thermal_common.h>
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_THERMAL_H__ */
|
||||
170
src/soc/mediatek/mt8189/include/soc/thermal_internal.h
Normal file
170
src/soc/mediatek/mt8189/include/soc/thermal_internal.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_THERMAL_INTERNAL_H__
|
||||
#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_THERMAL_INTERNAL_H__
|
||||
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/spm_mtcmos.h>
|
||||
#include <soc/symbols.h>
|
||||
|
||||
#define LVTS_MAGIC 0x0000555
|
||||
#define MAX_TS_NUMBER 4
|
||||
|
||||
#define LVTS_COF_T_SLP_GLD 219960
|
||||
#define LVTS_COF_COUNT_R_GLD 14437
|
||||
#define LVTS_COF_T_CONST_OFS 280000
|
||||
#define LVTS_ADDRESS_INDEX_NUM (L_TS_LVTS_NUM + LVTS_CONTROLLER_NUM)
|
||||
#define LVTS_GROUP_INTERVAL_DELAY_MASK GENMASK(29, 20)
|
||||
#define LVTS_COEFF_A (-250460)
|
||||
|
||||
#define DEFAULT_EFUSE_GOLDEN_TEMP 50
|
||||
#define DEFAULT_EFUSE_GOLDEN_TEMP_HT 170
|
||||
#define DEFAULT_EFUSE_COUNT 35000
|
||||
#define DEFAULT_EFUSE_COUNT_RC 2750
|
||||
|
||||
/* INFRACFG_AO_BASE + 0x0084 */
|
||||
#define THERM_CG BIT(10)
|
||||
|
||||
/* THERM_CTRL_BASE + lvts_tc_offset_enum + 0x0050 */
|
||||
#define DEVICE_SENSING_STATUS BIT(25)
|
||||
#define DEVICE_ACCESS_START_BIT BIT(24)
|
||||
#define WRITE_ACCESS BIT(16)
|
||||
|
||||
/* THERM_CTRL_BASE + lvts_tc_offset_enum + 0x000C */
|
||||
#define STAGE3_INT_EN BIT(31)
|
||||
|
||||
/* SRAM for Thermal */
|
||||
#define THERMAL_ATC_SRAM_OFFSET 0x280
|
||||
#define THERMAL_SRAM_BASE (_thermal_reserved + THERMAL_ATC_SRAM_OFFSET)
|
||||
#define THERMAL_SRAM_LEN (24 * 4)
|
||||
#define THERMAL_STAT_SRAM_BASE _cpucooler_reserved
|
||||
#define THERMAL_STAT_SRAM_LEN REGION_SIZE(cpucooler_reserved)
|
||||
|
||||
/*
|
||||
* module LVTS Plan
|
||||
*=====================================================
|
||||
* MCU_BIG core0/1 LVTS1-0, LVTS1-1, LVTS1-2, LVTS1-3
|
||||
* MCU_BIG core2/3 LVTS2-0, LVTS2-1, LVTS2-2, LVTS2-3
|
||||
* MCU_LITTLE LVTS3-0, LVTS3-1, LVTS3-2, LVTS3-3
|
||||
* SOC-TOP,APU LVTS4-0, LVTS4-1, LVTS4-2, LVTS4-3
|
||||
* GPU LVTS5-0, LVTS5-1
|
||||
* ptp_therm_ctrl_AP Base address: (+0x1031_5000), 0x1031_5100, 0x1031_5200
|
||||
* ptp_therm_ctrl_MCU Base address: (+0x1031_6000), 0x1031_6100, 0x1031_6200, 0x1031_6300
|
||||
*/
|
||||
|
||||
/* private thermal sensor */
|
||||
enum lvts_sensor {
|
||||
L_TS_LVTS1_0 = 0, /* LVTS1-0 Big-core0 */
|
||||
L_TS_LVTS1_1, /* LVTS1-1 Big-core0 */
|
||||
L_TS_LVTS1_2, /* LVTS1-2 Big-core1 */
|
||||
L_TS_LVTS1_3, /* LVTS1-3 Big-core1 */
|
||||
L_TS_LVTS2_0, /* LVTS2-0 Big-core2 */
|
||||
L_TS_LVTS2_1, /* LVTS2-1 Big-core2 */
|
||||
L_TS_LVTS2_2, /* LVTS2-2 Big-core3 */
|
||||
L_TS_LVTS2_3, /* LVTS2-3 Big-core3 */
|
||||
L_TS_LVTS3_0, /* LVTS3-0 Little-core0 */
|
||||
L_TS_LVTS3_1, /* LVTS3-1 Little-core1 */
|
||||
L_TS_LVTS3_2, /* LVTS3-2 Little-core2 */
|
||||
L_TS_LVTS3_3, /* LVTS3-3 Little-core3 */
|
||||
L_TS_LVTS4_0, /* LVTS4-0 SCO-TOP */
|
||||
L_TS_LVTS4_1, /* LVTS4-1 SCO-TOP */
|
||||
L_TS_LVTS4_2, /* LVTS4-0 SCO-TOP */
|
||||
L_TS_LVTS4_3, /* LVTS4-1 APU */
|
||||
L_TS_LVTS5_0, /* LVTS5-0 GPU */
|
||||
L_TS_LVTS5_1, /* LVTS5-1 GPU */
|
||||
L_TS_LVTS_NUM,
|
||||
};
|
||||
|
||||
enum lvts_tc_enum {
|
||||
LVTS_MCU_CONTROLLER0 = 0,
|
||||
LVTS_MCU_CONTROLLER1,
|
||||
LVTS_MCU_CONTROLLER2,
|
||||
LVTS_AP_CONTROLLER0,
|
||||
LVTS_MFG_CONTROLLER0,
|
||||
LVTS_CONTROLLER_NUM,
|
||||
};
|
||||
|
||||
enum lvts_tc_offset_enum {
|
||||
TC_OFFSET_AP_CONTROLLER0 = 0,
|
||||
TC_OFFSET_MFG_CONTROLLER0 = 0x100,
|
||||
TC_OFFSET_MCU_CONTROLLER0 = 0x1000,
|
||||
TC_OFFSET_MCU_CONTROLLER1 = 0x1100,
|
||||
TC_OFFSET_MCU_CONTROLLER2 = 0x1200,
|
||||
};
|
||||
|
||||
struct mtk_thermal_controller_regs {
|
||||
u32 lvtsmonctl0_0;
|
||||
u32 lvtsmonctl1_0;
|
||||
u32 lvtsmonctl2_0;
|
||||
u32 lvtsmonint_0;
|
||||
u32 reserved1[5];
|
||||
u32 lvtsh2nthre_0;
|
||||
u32 lvtshthre_0;
|
||||
u32 lvtscthre_0;
|
||||
u32 lvtsoffseth_0;
|
||||
u32 lvtsoffsetl_0;
|
||||
u32 lvtsmsrctl0_0;
|
||||
u32 lvtsmsrctl1_0;
|
||||
u32 lvtstssel_0;
|
||||
u32 reserved2[1];
|
||||
u32 lvtscalscale_0;
|
||||
u32 lvts_id_0;
|
||||
u32 lvts_config_0;
|
||||
u32 lvtsedata[4];
|
||||
u32 reserved3[11];
|
||||
u32 lvtsmsr[4];
|
||||
u32 reserved4[4];
|
||||
u32 lvtsrdata0_0;
|
||||
u32 reserved5[3];
|
||||
u32 lvtsprotctl_0;
|
||||
u32 reserved6[2];
|
||||
u32 lvtsprottc_0;
|
||||
u32 reserved7[5];
|
||||
u32 lvtsclken_0;
|
||||
u32 reserved8[2];
|
||||
u32 lvtsspare[2];
|
||||
u32 reserved9[2];
|
||||
};
|
||||
check_member(mtk_thermal_controller_regs, lvtsmonint_0, 0x000C);
|
||||
check_member(mtk_thermal_controller_regs, lvtsh2nthre_0, 0x0024);
|
||||
check_member(mtk_thermal_controller_regs, lvtstssel_0, 0x0040);
|
||||
check_member(mtk_thermal_controller_regs, lvtscalscale_0, 0x0048);
|
||||
check_member(mtk_thermal_controller_regs, lvtsedata[3], 0x0060);
|
||||
check_member(mtk_thermal_controller_regs, lvtsmsr[0], 0x0090);
|
||||
check_member(mtk_thermal_controller_regs, lvtsmsr[3], 0x009C);
|
||||
check_member(mtk_thermal_controller_regs, lvtsrdata0_0, 0x00B0);
|
||||
check_member(mtk_thermal_controller_regs, lvtsprotctl_0, 0x00C0);
|
||||
check_member(mtk_thermal_controller_regs, lvtsprottc_0, 0x00CC);
|
||||
check_member(mtk_thermal_controller_regs, lvtsclken_0, 0x00E4);
|
||||
check_member(mtk_thermal_controller_regs, lvtsspare[0], 0x00F0);
|
||||
check_member(mtk_thermal_controller_regs, lvtsspare[1], 0x00F4);
|
||||
|
||||
struct mtk_infracfg_regs {
|
||||
u32 reserved1[968];
|
||||
u32 mcu_rst_set;
|
||||
u32 mcu_rst_clr;
|
||||
u32 reserved2[10];
|
||||
u32 ap_rst_set;
|
||||
u32 ap_rst_clr;
|
||||
};
|
||||
check_member(mtk_infracfg_regs, mcu_rst_set, 0x0F20);
|
||||
check_member(mtk_infracfg_regs, mcu_rst_clr, 0x0F24);
|
||||
check_member(mtk_infracfg_regs, ap_rst_set, 0x0F50);
|
||||
check_member(mtk_infracfg_regs, ap_rst_clr, 0x0F54);
|
||||
|
||||
/* LVTS Thermal Controller Register Definition */
|
||||
|
||||
static struct mtk_thermal_controller_regs *const
|
||||
mtk_lvts_mcu_controller0 = (void *)(THERM_CTRL_BASE + TC_OFFSET_MCU_CONTROLLER0);
|
||||
static struct mtk_thermal_controller_regs *const
|
||||
mtk_lvts_mcu_controller1 = (void *)(THERM_CTRL_BASE + TC_OFFSET_MCU_CONTROLLER1);
|
||||
static struct mtk_thermal_controller_regs *const
|
||||
mtk_lvts_mcu_controller2 = (void *)(THERM_CTRL_BASE + TC_OFFSET_MCU_CONTROLLER2);
|
||||
static struct mtk_thermal_controller_regs *const
|
||||
mtk_lvts_ap_controller0 = (void *)(THERM_CTRL_BASE + TC_OFFSET_AP_CONTROLLER0);
|
||||
static struct mtk_thermal_controller_regs *const
|
||||
mtk_lvts_mfg_controller0 = (void *)(THERM_CTRL_BASE + TC_OFFSET_MFG_CONTROLLER0);
|
||||
|
||||
static struct mtk_infracfg_regs *const mtk_infracfg = (void *)INFRACFG_BASE;
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_THERMAL_INTERNAL_H__ */
|
||||
448
src/soc/mediatek/mt8189/thermal.c
Normal file
448
src/soc/mediatek/mt8189/thermal.c
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
/*
|
||||
* This file is created based on MT8189 Functional Specification
|
||||
* Chapter number: 9.13
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <delay.h>
|
||||
#include <soc/efuse.h>
|
||||
#include <soc/thermal.h>
|
||||
|
||||
#define LVTS_DEVICE_WRITE_CONFIG 0xC103
|
||||
|
||||
static uint32_t golden_temp;
|
||||
|
||||
static u32 ts_edata[L_TS_LVTS_NUM];
|
||||
static u32 op_cali[LVTS_CONTROLLER_NUM];
|
||||
static u32 count_rc_now[L_TS_LVTS_NUM];
|
||||
|
||||
/*
|
||||
* module LVTS Plan
|
||||
*=====================================================
|
||||
* MCU_BIG core0/1 LVTS1-0, LVTS1-1, LVTS1-2, LVTS1-3
|
||||
* MCU_BIG core2/3 LVTS2-0, LVTS2-1, LVTS2-2, LVTS2-3
|
||||
* MCU_LITTLE LVTS3-0, LVTS3-1, LVTS3-2, LVTS3-3
|
||||
* SOC-TOP,APU LVTS4-0, LVTS4-1, LVTS4-2, LVTS4-3
|
||||
* GPU LVTS5-0, LVTS5-1
|
||||
*
|
||||
* ptp_therm_ctrl_AP Base address: (+0x1031_5000), 0x1031_5100, 0x1031_5200
|
||||
* ptp_therm_ctrl_MCU Base address: (+0x1031_6000), 0x1031_6100, 0x1031_6200, 0x1031_6300
|
||||
*/
|
||||
static const struct lvts_thermal_controller lvts_tscpu_g_tc[LVTS_CONTROLLER_NUM] = {
|
||||
[LVTS_MCU_CONTROLLER0] = { /* MCU_BIG core0/1 */
|
||||
.ts = {L_TS_LVTS1_0, L_TS_LVTS1_1, L_TS_LVTS1_2, L_TS_LVTS1_3},
|
||||
.sensor_on_off = {SEN_ON, SEN_ON, SEN_ON, SEN_ON},
|
||||
.ts_number = 4,
|
||||
.reboot_temperature = 119000,
|
||||
.dominator_ts_idx = 0,
|
||||
.reboot_msr_sram_idx = 0,
|
||||
.has_reboot_msr_sram = false,
|
||||
.has_reboot_temp_sram = false,
|
||||
.speed = {
|
||||
.group_interval_delay = 0x0F6,
|
||||
.period_unit = 0x001,
|
||||
.filter_interval_delay = 0x001,
|
||||
.sensor_interval_delay = 0x001
|
||||
},
|
||||
.regs = mtk_lvts_mcu_controller0,
|
||||
},
|
||||
[LVTS_MCU_CONTROLLER1] = { /* MCU_BIG core2/3 */
|
||||
.ts = {L_TS_LVTS2_0, L_TS_LVTS2_1, L_TS_LVTS2_2, L_TS_LVTS2_3},
|
||||
.sensor_on_off = {SEN_ON, SEN_ON, SEN_ON, SEN_ON},
|
||||
.ts_number = 4,
|
||||
.reboot_temperature = 119000,
|
||||
.dominator_ts_idx = 0,
|
||||
.reboot_msr_sram_idx = 0,
|
||||
.has_reboot_msr_sram = false,
|
||||
.has_reboot_temp_sram = false,
|
||||
.speed = {
|
||||
.group_interval_delay = 0x0F6,
|
||||
.period_unit = 0x001,
|
||||
.filter_interval_delay = 0x001,
|
||||
.sensor_interval_delay = 0x001
|
||||
},
|
||||
.regs = mtk_lvts_mcu_controller1,
|
||||
},
|
||||
[LVTS_MCU_CONTROLLER2] = { /* MCU_LITTLE */
|
||||
.ts = {L_TS_LVTS3_0, L_TS_LVTS3_1, L_TS_LVTS3_2, L_TS_LVTS3_3},
|
||||
.sensor_on_off = {SEN_ON, SEN_ON, SEN_ON, SEN_ON},
|
||||
.ts_number = 4,
|
||||
.reboot_temperature = 119000,
|
||||
.dominator_ts_idx = 0,
|
||||
.reboot_msr_sram_idx = 0,
|
||||
.has_reboot_msr_sram = false,
|
||||
.has_reboot_temp_sram = false,
|
||||
.speed = {
|
||||
.group_interval_delay = 0x1C1,
|
||||
.period_unit = 0x001,
|
||||
.filter_interval_delay = 0x001,
|
||||
.sensor_interval_delay = 0x001
|
||||
},
|
||||
.regs = mtk_lvts_mcu_controller2,
|
||||
},
|
||||
[LVTS_AP_CONTROLLER0] = { /* SOC-TOP, APU */
|
||||
.ts = {L_TS_LVTS4_0, L_TS_LVTS4_1, L_TS_LVTS4_2, L_TS_LVTS4_3},
|
||||
.sensor_on_off = {SEN_ON, SEN_ON, SEN_ON, SEN_ON},
|
||||
.ts_number = 4,
|
||||
.reboot_temperature = 119000,
|
||||
.dominator_ts_idx = 0,
|
||||
.reboot_msr_sram_idx = 0,
|
||||
.has_reboot_msr_sram = false,
|
||||
.has_reboot_temp_sram = false,
|
||||
.speed = {
|
||||
.group_interval_delay = 0x0D2,
|
||||
.period_unit = 0x001,
|
||||
.filter_interval_delay = 0x001,
|
||||
.sensor_interval_delay = 0x001
|
||||
},
|
||||
.regs = mtk_lvts_ap_controller0,
|
||||
},
|
||||
[LVTS_MFG_CONTROLLER0] = { /* MFG */
|
||||
.ts = {L_TS_LVTS5_0, L_TS_LVTS5_1},
|
||||
.sensor_on_off = {SEN_ON, SEN_ON},
|
||||
.ts_number = 2,
|
||||
.reboot_temperature = 119000,
|
||||
.dominator_ts_idx = 0,
|
||||
.reboot_msr_sram_idx = 0,
|
||||
.has_reboot_msr_sram = false,
|
||||
.has_reboot_temp_sram = false,
|
||||
.speed = {
|
||||
.group_interval_delay = 0x08A,
|
||||
.period_unit = 0x001,
|
||||
.filter_interval_delay = 0x001,
|
||||
.sensor_interval_delay = 0x001
|
||||
},
|
||||
.regs = mtk_lvts_mfg_controller0,
|
||||
},
|
||||
};
|
||||
|
||||
const struct lvts_thermal_controller *lvts_get_controller(int tc_num)
|
||||
{
|
||||
assert(tc_num < LVTS_CONTROLLER_NUM);
|
||||
|
||||
return &lvts_tscpu_g_tc[tc_num];
|
||||
}
|
||||
|
||||
void lvts_clock_gate_disable(void)
|
||||
{
|
||||
write32(&mtk_infracfg_ao->infracfg_ao_module_cg_0_clr, THERM_CG);
|
||||
}
|
||||
|
||||
void lvts_tscpu_reset_thermal(void)
|
||||
{
|
||||
/* Reset AP thermal control */
|
||||
write32(&mtk_infracfg->ap_rst_set, BIT(23));
|
||||
write32(&mtk_infracfg->ap_rst_clr, BIT(23));
|
||||
|
||||
/* Reset MCU thermal control */
|
||||
write32(&mtk_infracfg->mcu_rst_set, BIT(12));
|
||||
write32(&mtk_infracfg->mcu_rst_clr, BIT(12));
|
||||
}
|
||||
|
||||
void lvts_thermal_cal_prepare(void)
|
||||
{
|
||||
u32 temp[LVTS_ADDRESS_INDEX_NUM];
|
||||
int i;
|
||||
bool efuse_calibrated = false;
|
||||
enum lvts_sensor sensor_groups[] = {L_TS_LVTS1_0, L_TS_LVTS2_0,
|
||||
L_TS_LVTS3_0, L_TS_LVTS4_0,
|
||||
L_TS_LVTS5_0};
|
||||
const size_t sensor_group_size = 4;
|
||||
int idx;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(temp); i++) {
|
||||
temp[i] = read32(&mtk_efuse->lvts_reg[i]);
|
||||
printk(BIOS_INFO, "[lvts_cali] %d: 0x%x\n", i, temp[i]);
|
||||
|
||||
if (temp[i] != 0)
|
||||
efuse_calibrated = true;
|
||||
}
|
||||
|
||||
/* 0x11F1_01A4,LVTS1 */
|
||||
golden_temp = (temp[0] & GENMASK(7, 0));
|
||||
idx = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sensor_groups); i++) {
|
||||
idx++;
|
||||
for (int j = 0; j < sensor_group_size; j++) {
|
||||
enum lvts_sensor sensor = sensor_groups[i] + j;
|
||||
if (sensor >= L_TS_LVTS_NUM)
|
||||
break;
|
||||
ts_edata[sensor] = temp[idx++] & GENMASK(23, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 0x11F1_01A4,LVTS1 */
|
||||
op_cali[LVTS_MCU_CONTROLLER0] = ((temp[0] & GENMASK(31, 8)) >> 8);
|
||||
/* 0x11F1_01B8,LVTS2 */
|
||||
op_cali[LVTS_MCU_CONTROLLER1] = (temp[5] & GENMASK(23, 0));
|
||||
/* 0x11F1_01CC,LVTS3 */
|
||||
op_cali[LVTS_MCU_CONTROLLER2] = (temp[10] & GENMASK(23, 0));
|
||||
|
||||
/* 0x11F1_01E0,LVTS4 */
|
||||
op_cali[LVTS_AP_CONTROLLER0] = (temp[15] & GENMASK(23, 0));
|
||||
|
||||
/* 0x11F1_01F4,LVTS5 */
|
||||
op_cali[LVTS_MFG_CONTROLLER0] = (temp[20] & GENMASK(23, 0));
|
||||
|
||||
if (!efuse_calibrated) {
|
||||
/* It means all efuse data are equal to 0 */
|
||||
printk(BIOS_ERR,
|
||||
"[lvts_cal] The efuses of this sample are all zero, "
|
||||
"meaning it is not calibrated, fake!!!\n");
|
||||
golden_temp = DEFAULT_EFUSE_GOLDEN_TEMP;
|
||||
for (i = 0; i < L_TS_LVTS_NUM; i++)
|
||||
ts_edata[i] = DEFAULT_EFUSE_COUNT;
|
||||
|
||||
for (i = 0; i < LVTS_CONTROLLER_NUM; i++)
|
||||
op_cali[i] = DEFAULT_EFUSE_COUNT_RC;
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "[lvts_cal] golden_temp = %d mdegC\n", golden_temp);
|
||||
|
||||
printk(BIOS_INFO, "[lvts_cal] num:ts_edata:op_cali ");
|
||||
for (i = 0; i < ARRAY_SIZE(ts_edata); i++) {
|
||||
if (i < ARRAY_SIZE(op_cali))
|
||||
printk(BIOS_INFO, "%d:%d:%d ", i, ts_edata[i], op_cali[i]);
|
||||
else
|
||||
printk(BIOS_INFO, "%d:%d ", i, ts_edata[i]);
|
||||
}
|
||||
printk(BIOS_INFO, "\n");
|
||||
|
||||
write32(&lvts_tscpu_g_tc[0].regs->lvtsspare[1], golden_temp);
|
||||
}
|
||||
|
||||
void lvts_device_identification(void)
|
||||
{
|
||||
u32 dev_id, data;
|
||||
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);
|
||||
/* Enable LVTS_CTRL Clock */
|
||||
write32(&tc->regs->lvtsclken_0, 0x00000001);
|
||||
|
||||
/* Reset All Devices */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0xFF, 0xFF, i);
|
||||
|
||||
/* Read back Dev_ID with Update */
|
||||
lvts_write_device(0xC502, 0xFC, 0x55, i);
|
||||
|
||||
dev_id = 0x81 + i;
|
||||
|
||||
if (!retry(LVTS_READ_ID_RETRY_CNT,
|
||||
(data = read32(&tc->regs->lvts_id_0) & GENMASK(7, 0)) == dev_id,
|
||||
udelay(LVTS_READ_ID_DELAY_US)))
|
||||
printk(BIOS_ERR,
|
||||
"LVTS_TC_%d read timeout, addr:0x%lx, Device ID should be 0x%x,"
|
||||
" but 0x%x\n",
|
||||
i, (uintptr_t)(&tc->regs->lvts_id_0), dev_id, data);
|
||||
}
|
||||
}
|
||||
|
||||
void lvts_device_enable_init_all_devices(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printk(BIOS_INFO, "===== %s begin ======\n", __func__);
|
||||
|
||||
for (i = 0; i < LVTS_CONTROLLER_NUM; i++) {
|
||||
/* Stop Counting (RG_TSFM_ST=0) */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x03, 0x00, i);
|
||||
/* RG_TSFM_LPDLY[1:0]=2' 10 */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x07, 0xA6, i);
|
||||
/* Set LVTS device counting window 20us */
|
||||
/* Counting Window */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x05, 0x00, i);
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x04, 0x20, i);
|
||||
/* TSV2F_CHOP_CKSEL & TSV2F_EN */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x0A, 0x8C, i);
|
||||
/* TSBG_DEM_CKSEL * TSBG_CHOP_EN */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x0C, 0xFC, i);
|
||||
/* Set TS_RSV */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x09, 0x8D, i);
|
||||
/* Set TS_CHOP control */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x08, 0xF1, i);
|
||||
}
|
||||
}
|
||||
|
||||
static u32 lvts_read_device(u32 config, u32 dev_reg_idx, int tc_num)
|
||||
{
|
||||
u32 data;
|
||||
u32 *lvts_config_reg = &lvts_tscpu_g_tc[tc_num].regs->lvts_config_0;
|
||||
|
||||
config |= (dev_reg_idx & 0xFF) << 8;
|
||||
|
||||
write32(lvts_config_reg, config);
|
||||
|
||||
/* Wait 2us + 3us buffer */
|
||||
udelay(5);
|
||||
|
||||
if (!retry(CHECK_DEVICE_ACCESS_RETRY_CNT,
|
||||
!(read32(lvts_config_reg) & DEVICE_ACCESS_START_BIT),
|
||||
udelay(2)))
|
||||
printk(BIOS_ERR,
|
||||
"read err: DEVICE_ACCESS_START_BIT is not ready, "
|
||||
"ASIF transaction not finished, reg0x%x\n",
|
||||
dev_reg_idx);
|
||||
|
||||
data = read32(&lvts_tscpu_g_tc[tc_num].regs->lvtsrdata0_0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void lvts_device_check_counting_status(const struct lvts_thermal_controller *tc)
|
||||
{
|
||||
/*
|
||||
* Check this when LVTS device is counting for a temperature or
|
||||
* a RC (Resistor-Capacitor Calibration) now
|
||||
*/
|
||||
|
||||
if (!retry(CHECK_DEVICE_ACCESS_RETRY_CNT,
|
||||
!(read32(&tc->regs->lvts_config_0) & DEVICE_SENSING_STATUS),
|
||||
udelay(2)))
|
||||
printk(BIOS_ERR, "Error: DEVICE_SENSING_STATUS is not ready\n");
|
||||
}
|
||||
|
||||
static void lvts_device_read_count_rc_n(void)
|
||||
{
|
||||
/* Perform RC (Resistor-Capacitor Calibration) and read current count (count_rc_n) */
|
||||
int i, j, s_index;
|
||||
u32 data;
|
||||
|
||||
/* Set LVTS MANUAL-RCK operation */
|
||||
for (i = 0; i < LVTS_CONTROLLER_NUM; i++)
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x0E, 0x00, i);
|
||||
|
||||
for (i = 0; i < LVTS_CONTROLLER_NUM; i++) {
|
||||
const struct lvts_thermal_controller *tc = lvts_get_controller(i);
|
||||
|
||||
/* Set LVTS Manual-RCK operation */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x0E, 0x00, i);
|
||||
|
||||
for (j = 0; j < tc->ts_number; j++) {
|
||||
if (tc->sensor_on_off[j] == SEN_OFF)
|
||||
continue;
|
||||
|
||||
s_index = tc->ts[j];
|
||||
|
||||
/* Select sensor-N with RCK */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x0D, j, i);
|
||||
/* Set Device Low-Power Single mode */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x06, 0x78, i);
|
||||
/* Set TS_EN and DEV_EN */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x08, 0xF5, i);
|
||||
/* Toggle VCO_RST */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x08, 0xFD, i);
|
||||
/* Set TS_EN and DEV_EN */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x08, 0xF5, i);
|
||||
/* wait 10us */
|
||||
udelay(10);
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x03, 0x02, i);
|
||||
/* polling counting status */
|
||||
lvts_device_check_counting_status(tc);
|
||||
/* disable TS_EN */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x08, 0xF1, i);
|
||||
/* wait 40us at sensor0 */
|
||||
/* 2us is margin for different IC */
|
||||
if (j == 0)
|
||||
udelay(42);
|
||||
|
||||
/* Get RCK count data (sensor-N) */
|
||||
data = lvts_read_device(0xC1020000, 0x00, i);
|
||||
/* wait 2us + 3us buffer */
|
||||
udelay(5);
|
||||
|
||||
/* Get RCK value from LSB[23:0] */
|
||||
count_rc_now[s_index] = data & GENMASK(23, 0);
|
||||
|
||||
/*
|
||||
* Recover Setting for Normal Access on
|
||||
* temperature fetch
|
||||
*/
|
||||
/* Select Sensor-N without RCK */
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x0D, (0x10 | j), i);
|
||||
}
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "[COUNT_RC_NOW] ");
|
||||
for (i = 0; i < L_TS_LVTS_NUM; i++)
|
||||
printk(BIOS_INFO, "%d:%d ", i, count_rc_now[i]);
|
||||
|
||||
printk(BIOS_INFO, "\n");
|
||||
}
|
||||
|
||||
void lvts_efuse_setting(void)
|
||||
{
|
||||
int i, j, s_index;
|
||||
uint32_t efuse_data;
|
||||
|
||||
printk(BIOS_INFO, "===== %s begin ======\n", __func__);
|
||||
|
||||
lvts_device_read_count_rc_n();
|
||||
|
||||
for (i = 0; i < LVTS_CONTROLLER_NUM; i++) {
|
||||
const struct lvts_thermal_controller *tc = lvts_get_controller(i);
|
||||
|
||||
assert(tc->ts_number <= ARRAY_SIZE(tc->regs->lvtsedata));
|
||||
for (j = 0; j < tc->ts_number; j++) {
|
||||
if (tc->sensor_on_off[j] == SEN_OFF)
|
||||
continue;
|
||||
|
||||
s_index = tc->ts[j];
|
||||
|
||||
efuse_data = ((u64)count_rc_now[s_index] * ts_edata[s_index]) >> 14;
|
||||
|
||||
write32(&tc->regs->lvtsedata[j], efuse_data);
|
||||
printk(BIOS_INFO,
|
||||
"efuse LVTSEDATA[%d]_%d %#x\n", j, i,
|
||||
read32(&tc->regs->lvtsedata[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lvts_tscpu_thermal_read_tc_temp(const struct lvts_thermal_controller *tc, int order)
|
||||
{
|
||||
enum lvts_sensor ts_name = tc->ts[order];
|
||||
int temperature;
|
||||
assert(order < ARRAY_SIZE(tc->regs->lvtsmsr));
|
||||
temperature = lvts_read_tc_raw_and_temp(&tc->regs->lvtsmsr[order],
|
||||
ts_name,
|
||||
golden_temp);
|
||||
|
||||
printk(BIOS_INFO,
|
||||
"%s order %d ts_name %d temp %d mdegC\n",
|
||||
__func__, order, ts_name, temperature);
|
||||
}
|
||||
|
||||
void lvts_set_device_single_mode(int tc_num)
|
||||
{
|
||||
lvts_write_device(LVTS_DEVICE_WRITE_CONFIG, 0x06, 0xF8, tc_num);
|
||||
}
|
||||
|
||||
uint16_t lvts_temp_to_raw(int temp_mc, enum lvts_sensor ts_name)
|
||||
{
|
||||
/*
|
||||
* MSR_RAW = ((temp_mc - GOLDEN_TEMP/2 - b) * 16384) / a
|
||||
* a = -250.46
|
||||
* b = 250.46
|
||||
*/
|
||||
uint32_t msr_raw;
|
||||
int64_t temp1;
|
||||
|
||||
temp1 = (int64_t)golden_temp * 500 - LVTS_COEFF_A - temp_mc;
|
||||
assert(temp1 >= 0);
|
||||
msr_raw = ((temp1 << 14) / (-1 * LVTS_COEFF_A)) & 0xFFFF;
|
||||
|
||||
printk(BIOS_INFO, "%s msr_raw = %u, temp_mc = %d\n", __func__, msr_raw, temp_mc);
|
||||
return msr_raw;
|
||||
}
|
||||
|
||||
void thermal_init(void)
|
||||
{
|
||||
lvts_thermal_init();
|
||||
thermal_sram_init();
|
||||
}
|
||||
9
src/soc/mediatek/mt8189/thermal_sram.c
Normal file
9
src/soc/mediatek/mt8189/thermal_sram.c
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
#include <soc/thermal.h>
|
||||
|
||||
void thermal_sram_init(void)
|
||||
{
|
||||
thermal_cls_sram();
|
||||
thermal_stat_cls_sram();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue