// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2023 MediaTek Inc.
* Author: Balsam CHIHI <bchihi@baylibre.com>
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/debugfs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/thermal.h>
#include <dt-bindings/thermal/mediatek,lvts-thermal.h>
#define LVTS_MONCTL0(__base) (__base + 0x0000)
#define LVTS_MONCTL1(__base) (__base + 0x0004)
#define LVTS_MONCTL2(__base) (__base + 0x0008)
#define LVTS_MONINT(__base) (__base + 0x000C)
#define LVTS_MONINTSTS(__base) (__base + 0x0010)
#define LVTS_MONIDET0(__base) (__base + 0x0014)
#define LVTS_MONIDET1(__base) (__base + 0x0018)
#define LVTS_MONIDET2(__base) (__base + 0x001C)
#define LVTS_MONIDET3(__base) (__base + 0x0020)
#define LVTS_H2NTHRE(__base) (__base + 0x0024)
#define LVTS_HTHRE(__base) (__base + 0x0028)
#define LVTS_OFFSETH(__base) (__base + 0x0030)
#define LVTS_OFFSETL(__base) (__base + 0x0034)
#define LVTS_MSRCTL0(__base) (__base + 0x0038)
#define LVTS_MSRCTL1(__base) (__base + 0x003C)
#define LVTS_TSSEL(__base) (__base + 0x0040)
#define LVTS_CALSCALE(__base) (__base + 0x0048)
#define LVTS_ID(__base) (__base + 0x004C)
#define LVTS_CONFIG(__base) (__base + 0x0050)
#define LVTS_EDATA00(__base) (__base + 0x0054)
#define LVTS_EDATA01(__base) (__base + 0x0058)
#define LVTS_EDATA02(__base) (__base + 0x005C)
#define LVTS_EDATA03(__base) (__base + 0x0060)
#define LVTS_MSR0(__base) (__base + 0x0090)
#define LVTS_MSR1(__base) (__base + 0x0094)
#define LVTS_MSR2(__base) (__base + 0x0098)
#define LVTS_MSR3(__base) (__base + 0x009C)
#define LVTS_IMMD0(__base) (__base + 0x00A0)
#define LVTS_IMMD1(__base) (__base + 0x00A4)
#define LVTS_IMMD2(__base) (__base + 0x00A8)
#define LVTS_IMMD3(__base) (__base + 0x00AC)
#define LVTS_PROTCTL(__base) (__base + 0x00C0)
#define LVTS_PROTTA(__base) (__base + 0x00C4)
#define LVTS_PROTTB(__base) (__base + 0x00C8)
#define LVTS_PROTTC(__base) (__base + 0x00CC)
#define LVTS_CLKEN(__base) (__base + 0x00E4)
#define LVTS_PERIOD_UNIT ((118 * 1000) / (256 * 38))
#define LVTS_GROUP_INTERVAL 1
#define LVTS_FILTER_INTERVAL 1
#define LVTS_SENSOR_INTERVAL 1
#define LVTS_HW_FILTER 0x2
#define LVTS_TSSEL_CONF 0x13121110
#define LVTS_CALSCALE_CONF 0x300
#define LVTS_MONINT_CONF 0x9FBF7BDE
#define LVTS_INT_SENSOR0 0x0009001F
#define LVTS_INT_SENSOR1 0x001203E0
#define LVTS_INT_SENSOR2 0x00247C00
#define LVTS_INT_SENSOR3 0x1FC00000
#define LVTS_SENSOR_MAX 4
#define LVTS_GOLDEN_TEMP_MAX 62
#define LVTS_GOLDEN_TEMP_DEFAULT 50
#define LVTS_COEFF_A -250460
#define LVTS_COEFF_B 250460
#define LVTS_MSR_IMMEDIATE_MODE 0
#define LVTS_MSR_FILTERED_MODE 1
#define LVTS_HW_SHUTDOWN_MT8195 105000
static int golden_temp = LVTS_GOLDEN_TEMP_DEFAULT;
static int coeff_b = LVTS_COEFF_B;
struct lvts_sensor_data {
int dt_id;
};
struct lvts_ctrl_data {
struct lvts_sensor_data lvts_sensor[LVTS_SENSOR_MAX];
int cal_offset[LVTS_SENSOR_MAX];
int hw_tshut_temp;
int num_lvts_sensor;
int offset;
int mode;
};
struct lvts_data {
const struct lvts_ctrl_data *lvts_ctrl;
int num_lvts_ctrl;
};
struct lvts_sensor {
struct thermal_zone_device *tz;
void __iomem *msr;
void __iomem *base;
int id;
int dt_id;
};
struct lvts_ctrl {
struct lvts_sensor sensors[LVTS_SENSOR_MAX];
u32 calibration[LVTS_SENSOR_MAX];
u32 hw_tshut_raw_temp;
int num_lvts_sensor;
int mode;
void __iomem *base;
};
struct lvts_domain {
struct lvts_ctrl *lvts_ctrl;
struct reset_control *reset;
struct clk *clk;
int num_lvts_ctrl;
void __iomem *base;
size_t calib_len;
u8 *calib;
#ifdef CONFIG_DEBUG_FS
struct dentry *dom_dentry;
#endif
};
#ifdef CONFIG_MTK_LVTS_THERMAL_DEBUGFS
#define LVTS_DEBUG_FS_REGS(__reg) \
{ \
.name = __stringify(__reg), \
.offset = __reg(0), \
}
static const struct debugfs_reg32 lvts_regs[] = {
LVTS_DEBUG_FS_REGS(LVTS_MONCTL0),
LVTS_DEBUG_FS_REGS(LVTS_MONCTL1),
LVTS_DEBUG_FS_REGS(LVTS_MONCTL2),
LVTS_DEBUG_FS_REGS(LVTS_MONINT),
LVTS_DEBUG_FS_REGS(LVTS_MONINTSTS),
LVTS_DEBUG_FS_REGS(LVTS_MONIDET0),
LVTS_DEBUG_FS_REGS(LVTS_MONIDET1),
LVTS_DEBUG_FS_REGS(LVTS_MONIDET2),
LVTS_DEBUG_FS_REGS(LVTS_MONIDET3),
LVTS_DEBUG_FS_REGS(LVTS_H2NTHRE),
LVTS_DEBUG_FS_REGS(LVTS_HTHRE),
LVTS_DEBUG_FS_REGS(LVTS_OFFSETH),
LVTS_DEBUG_FS_REGS(LVTS_OFFSETL),
LVTS_DEBUG_FS_REGS(LVTS_MSRCTL0),
LVTS_DEBUG_