Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4313aedf authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "thermal: tsens: Update MTC support for msmtitanium"

parents 02de0c97 2a88e41e
Loading
Loading
Loading
Loading
+310 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/err.h>
#include <linux/of.h>
#include <linux/debugfs.h>
#include <linux/vmalloc.h>

#define CREATE_TRACE_POINTS
#include <trace/trace_thermal.h>
@@ -57,6 +58,29 @@
#define TSENS2_SN_STATUS_VALID_MASK	0x4000
#define TSENS2_TRDY_ADDR(n)		((n) + 0x84)

#define TSENS4_TRDY_ADDR(n)            ((n) + 0x1084)

#define TSENS_MTC_ZONE0_SW_MASK_ADDR(n)  ((n) + 0x10c0)
#define TSENS_TH1_MTC_IN_EFFECT               BIT(0)
#define TSENS_TH2_MTC_IN_EFFECT               BIT(1)
#define TSENS_MTC_IN_EFFECT			0x3
#define TSENS_MTC_DISABLE			0x0

#define TSENS_MTC_ZONE0_LOG(n)     ((n) + 0x10d0)
#define TSENS_LOGS_VALID_MASK      0x40000000
#define TSENS_LOGS_VALID_SHIFT     30
#define TSENS_LOGS_LATEST_MASK    0x0000001f
#define TSENS_LOGS_LOG1_MASK      0x000003e0
#define TSENS_LOGS_LOG2_MASK      0x00007c00
#define TSENS_LOGS_LOG3_MASK      0x000f8000
#define TSENS_LOGS_LOG4_MASK      0x01f00000
#define TSENS_LOGS_LOG5_MASK      0x3e000000
#define TSENS_LOGS_LOG1_SHIFT     5
#define TSENS_LOGS_LOG2_SHIFT     10
#define TSENS_LOGS_LOG3_SHIFT     15
#define TSENS_LOGS_LOG4_SHIFT     20
#define TSENS_LOGS_LOG5_SHIFT     25

/* TSENS_TM registers for 8996 */
#define TSENS_TM_INT_EN(n)			((n) + 0x1004)
#define TSENS_TM_CRITICAL_INT_EN		BIT(2)
@@ -99,6 +123,11 @@
#define TSENS_CONTROLLER_ID(n)			((n) + 0x1000)
#define TSENS_DEBUG_CONTROL(n)			((n) + 0x1130)
#define TSENS_DEBUG_DATA(n)			((n) + 0x1134)
#define TSENS_TM_MTC_ZONE0_SW_MASK_ADDR(n)	((n) + 0x1140)
#define TSENS_TM_MTC_ZONE0_LOG(n)		((n) + 0x1150)
#define TSENS_TM_MTC_ZONE0_HISTORY(n)		((n) + 0x1160)
#define TSENS_RESET_HISTORY_MASK	0x4
#define TSENS_RESET_HISTORY_SHIFT	2
/* End TSENS_TM registers for 8996 */

#define TSENS_CTRL_ADDR(n)		(n)
@@ -353,6 +382,7 @@
#define TSENS_TYPE0		0
#define TSENS_TYPE2		2
#define TSENS_TYPE3		3
#define TSENS_TYPE4		4

#define TSENS_8916_BASE0_MASK		0x0000007f
#define TSENS_8916_BASE1_MASK		0xfe000000
@@ -718,6 +748,13 @@ struct tsens_sensor_dbg_info {
	unsigned long long		time_stmp[10];
};

struct tsens_mtc_sysfs {
	uint32_t zone_log;
	int zone_mtc;
	int th1;
	int th2;
};

struct tsens_tm_device {
	struct platform_device		*pdev;
	struct workqueue_struct		*tsens_critical_wq;
@@ -746,6 +783,7 @@ struct tsens_tm_device {
	int				tsens_critical_irq_cnt;
	struct delayed_work		tsens_critical_poll_test;
	struct completion		tsens_rslt_completion;
	struct tsens_mtc_sysfs		mtcsys;
	struct tsens_tm_device_sensor	sensor[0];
};

@@ -990,6 +1028,130 @@ int tsens_get_hw_id_mapping(int sensor_sw_id, int *sensor_client_id)
}
EXPORT_SYMBOL(tsens_get_hw_id_mapping);

static ssize_t
zonemask_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct tsens_tm_device *tmdev = NULL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	return snprintf(buf, PAGE_SIZE,
		"Zone =%d th1=%d th2=%d\n" , tmdev->mtcsys.zone_mtc,
				tmdev->mtcsys.th1 , tmdev->mtcsys.th2);
}

static ssize_t
zonemask_store(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	int ret;
	struct tsens_tm_device *tmdev = NULL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	ret = sscanf(buf, "%d %d %d", &tmdev->mtcsys.zone_mtc ,
				&tmdev->mtcsys.th1 , &tmdev->mtcsys.th2);

	if (ret != TSENS_ZONEMASK_PARAMS) {
		pr_err("Invalid command line arguments\n");
		count = -EINVAL;
	} else {
		pr_debug("store zone_mtc=%d th1=%d th2=%d\n",
				tmdev->mtcsys.zone_mtc,
				tmdev->mtcsys.th1 , tmdev->mtcsys.th2);
		ret = tsens_set_mtc_zone_sw_mask(tmdev->mtcsys.zone_mtc ,
					tmdev->mtcsys.th1 , tmdev->mtcsys.th2);
		if (ret < 0) {
			pr_err("Invalid command line arguments\n");
			count = -EINVAL;
		}
	}

	return count;
}

static ssize_t
zonelog_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	int ret, zlog[TSENS_MTC_ZONE_LOG_SIZE];
	struct tsens_tm_device *tmdev = NULL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	ret = tsens_get_mtc_zone_log(tmdev->mtcsys.zone_log , zlog);
	if (ret < 0) {
		pr_err("Invalid command line arguments\n");
		return -EINVAL;
	}

	return snprintf(buf, PAGE_SIZE,
		"Log[0]=%d\nLog[1]=%d\nLog[2]=%d\nLog[3]=%d\nLog[4]=%d\nLog[5]=%d\n",
			zlog[0], zlog[1], zlog[2], zlog[3], zlog[4], zlog[5]);
}

static ssize_t
zonelog_store(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	int ret;
	struct tsens_tm_device *tmdev = NULL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	ret = kstrtou32(buf, 0, &tmdev->mtcsys.zone_log);
	if (ret < 0) {
		pr_err("Invalid command line arguments\n");
		return -EINVAL;
	}

	return count;
}

static struct device_attribute tsens_mtc_dev_attr[] = {
	__ATTR(zonemask, 0644, zonemask_show, zonemask_store),
	__ATTR(zonelog, 0644, zonelog_show, zonelog_store),
};

static int create_tsens_mtc_sysfs(struct platform_device *pdev)
{
	int result = 0, i;
	struct device_attribute *attr_ptr = NULL;

	attr_ptr = tsens_mtc_dev_attr;

	for (i = 0; i < ARRAY_SIZE(tsens_mtc_dev_attr); i++) {
		result = device_create_file(&pdev->dev, &attr_ptr[i]);
		if (result < 0)
			goto error;
	}

	pr_debug("create_tsens_mtc_sysfs success\n");

	return result;

error:
	for (i--; i >= 0; i--)
		device_remove_file(&pdev->dev, &attr_ptr[i]);

	return result;
}

static int tsens_tz_code_to_degc(int adc_code, int sensor_sw_id,
				struct tsens_tm_device *tmdev)
{
@@ -1061,6 +1223,9 @@ static int msm_tsens_get_temp(int sensor_client_id, unsigned long *temp)
	} else if (tmdev->tsens_type == TSENS_TYPE3) {
		trdy_addr = TSENS_TM_TRDY(tmdev->tsens_addr);
		sensor_addr = TSENS_TM_SN_STATUS(tmdev->tsens_addr);
	} else if (tmdev->tsens_type == TSENS_TYPE4) {
		trdy_addr = TSENS4_TRDY_ADDR(tmdev->tsens_addr);
		sensor_addr = TSENS2_SN_STATUS_ADDR(tmdev->tsens_addr);
	} else {
		trdy_addr = TSENS_TRDY_ADDR(tmdev->tsens_addr);
		sensor_addr = TSENS_S0_STATUS_ADDR(tmdev->tsens_addr);
@@ -1736,6 +1901,143 @@ re_schedule:
			msecs_to_jiffies(tsens_sec_to_msec_value));
}

int tsens_mtc_reset_history_counter(unsigned int zone)
{
	unsigned int reg_cntl, is_valid;
	void __iomem *sensor_addr;
	struct tsens_tm_device *tmdev = NULL;

	if (zone > TSENS_NUM_MTC_ZONES_SUPPORT)
			return -EINVAL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	sensor_addr = TSENS_TM_MTC_ZONE0_SW_MASK_ADDR(tmdev->tsens_addr);
	reg_cntl = readl_relaxed((sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
	is_valid = (reg_cntl & TSENS_RESET_HISTORY_MASK)
				>> TSENS_RESET_HISTORY_SHIFT;
	if (!is_valid) {
		/*Enable the bit to reset counter*/
		writel_relaxed(reg_cntl | (1 << TSENS_RESET_HISTORY_SHIFT),
				(sensor_addr + (zone * TSENS_SN_ADDR_OFFSET)));
		reg_cntl = readl_relaxed((sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
		pr_debug("tsens : zone =%d reg=%x\n", zone , reg_cntl);
	}

	/*Disble the bit to start counter*/
	writel_relaxed(reg_cntl & ~(1 << TSENS_RESET_HISTORY_SHIFT),
				(sensor_addr + (zone * TSENS_SN_ADDR_OFFSET)));
	reg_cntl = readl_relaxed((sensor_addr +
			(zone * TSENS_SN_ADDR_OFFSET)));
	pr_debug("tsens : zone =%d reg=%x\n", zone , reg_cntl);

	return 0;
}
EXPORT_SYMBOL(tsens_mtc_reset_history_counter);

int tsens_set_mtc_zone_sw_mask(unsigned int zone , unsigned int th1_enable,
				unsigned int th2_enable)
{
	unsigned int reg_cntl;
	void __iomem *sensor_addr;
	struct tsens_tm_device *tmdev = NULL;

	if (zone > TSENS_NUM_MTC_ZONES_SUPPORT)
			return -EINVAL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	if (tmdev->tsens_type == TSENS_TYPE3)
			sensor_addr = TSENS_TM_MTC_ZONE0_SW_MASK_ADDR
						(tmdev->tsens_addr);
		else
			sensor_addr = TSENS_MTC_ZONE0_SW_MASK_ADDR
						(tmdev->tsens_addr);

	if (th1_enable && th2_enable)
		writel_relaxed(TSENS_MTC_IN_EFFECT,
				(sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
	if (!th1_enable && !th2_enable)
		writel_relaxed(TSENS_MTC_DISABLE,
				(sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
	if (th1_enable && !th2_enable)
		writel_relaxed(TSENS_TH1_MTC_IN_EFFECT,
				(sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
	if (!th1_enable && th2_enable)
		writel_relaxed(TSENS_TH2_MTC_IN_EFFECT,
				(sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
	reg_cntl = readl_relaxed((sensor_addr +
				(zone *	TSENS_SN_ADDR_OFFSET)));
	pr_debug("tsens : zone =%d th1=%d th2=%d reg=%x\n",
		zone , th1_enable , th2_enable , reg_cntl);

	return 0;
}
EXPORT_SYMBOL(tsens_set_mtc_zone_sw_mask);

int tsens_get_mtc_zone_log(unsigned int zone , void *zone_log)
{
	unsigned int i , reg_cntl , is_valid , log[TSENS_MTC_ZONE_LOG_SIZE];
	int *zlog = (int *)zone_log;
	void __iomem *sensor_addr;
	struct tsens_tm_device *tmdev = NULL;

	if (zone > TSENS_NUM_MTC_ZONES_SUPPORT)
		return -EINVAL;

	tmdev = tsens_controller_is_present();
	if (!tmdev) {
		pr_err("No TSENS controller present\n");
		return -EPROBE_DEFER;
	}

	if (tmdev->tsens_type == TSENS_TYPE3)
		sensor_addr = TSENS_TM_MTC_ZONE0_LOG(tmdev->tsens_addr);
	else
		sensor_addr = TSENS_MTC_ZONE0_LOG(tmdev->tsens_addr);

	reg_cntl = readl_relaxed((sensor_addr +
				(zone * TSENS_SN_ADDR_OFFSET)));
	is_valid = (reg_cntl & TSENS_LOGS_VALID_MASK)
				>> TSENS_LOGS_VALID_SHIFT;
	if (is_valid) {
		log[0] = (reg_cntl & TSENS_LOGS_LATEST_MASK);
		log[1] = (reg_cntl & TSENS_LOGS_LOG1_MASK)
				  >> TSENS_LOGS_LOG1_SHIFT;
		log[2] = (reg_cntl & TSENS_LOGS_LOG2_MASK)
				  >> TSENS_LOGS_LOG2_SHIFT;
		log[3] = (reg_cntl & TSENS_LOGS_LOG3_MASK)
				  >> TSENS_LOGS_LOG3_SHIFT;
		log[4] = (reg_cntl & TSENS_LOGS_LOG4_MASK)
				  >> TSENS_LOGS_LOG4_SHIFT;
		log[5] = (reg_cntl & TSENS_LOGS_LOG5_MASK)
				  >> TSENS_LOGS_LOG5_SHIFT;
		for (i = 0; i < (TSENS_MTC_ZONE_LOG_SIZE); i++) {
			*(zlog+i) = log[i];
			pr_debug("Log[%d]=%d\n", i , log[i]);
		}
	} else {
		pr_debug("tsens: Valid bit disabled\n");
		return -EINVAL;
	}
	return 0;
}
EXPORT_SYMBOL(tsens_get_mtc_zone_log);

static struct thermal_zone_device_ops tsens_thermal_zone_ops = {
	.get_temp = tsens_tz_get_temp,
	.get_mode = tsens_tz_get_mode,
@@ -1939,7 +2241,8 @@ static irqreturn_t tsens_irq_thread(int irq, void *data)
	int sensor_sw_id = -EINVAL;
	uint32_t idx = 0;

	if (tm->tsens_type == TSENS_TYPE2)
	if ((tm->tsens_type == TSENS_TYPE2) |
			(tm->tsens_type == TSENS_TYPE4))
		sensor_status_addr = TSENS2_SN_STATUS_ADDR(tm->tsens_addr);
	else
		sensor_status_addr = TSENS_S0_STATUS_ADDR(tm->tsens_addr);
@@ -4399,6 +4702,8 @@ static int get_device_tree_data(struct platform_device *pdev,
		tmdev->tsens_type = TSENS_TYPE2;
	else if (!strcmp(id->compatible, "qcom,msm8996-tsens"))
		tmdev->tsens_type = TSENS_TYPE3;
	else if (!strcmp(id->compatible, "qcom,msm8952-tsens"))
		tmdev->tsens_type = TSENS_TYPE4;
	else
		tmdev->tsens_type = TSENS_TYPE0;

@@ -4548,6 +4853,10 @@ static int tsens_tm_probe(struct platform_device *pdev)
	list_add_tail(&tmdev->list, &tsens_device_list);
	platform_set_drvdata(pdev, tmdev);

	rc = create_tsens_mtc_sysfs(pdev);
	if (rc < 0)
		pr_debug("Cannot create create_tsens_mtc_sysfs %d\n", rc);

	return 0;
fail:
	if (tmdev->tsens_critical_wq)
+16 −0
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@ enum platform_type {
};

#define TSENS_MAX_SENSORS		11
#define TSENS_MTC_ZONE_LOG_SIZE	6
#define TSENS_NUM_MTC_ZONES_SUPPORT	3
#define TSENS_ZONEMASK_PARAMS		3
#define TSENS_ZONELOG_PARAMS		1

struct tsens_platform_data {
	int				slope[TSENS_MAX_SENSORS];
@@ -47,6 +51,10 @@ int tsens_is_ready(void);
int __init tsens_tm_init_driver(void);
int tsens_get_hw_id_mapping(int sensor_sw_id, int *sensor_hw_num);
int tsens_get_max_sensor_num(uint32_t *tsens_num_sensors);
int tsens_set_mtc_zone_sw_mask(unsigned int zone , unsigned int th1_enable,
				unsigned int th2_enable);
int tsens_get_mtc_zone_log(unsigned int zone , void *zone_log);
int tsens_mtc_reset_history_counter(unsigned int zone);
#else
static inline int tsens_is_ready(void)
{ return -ENXIO; }
@@ -57,6 +65,14 @@ static inline int tsens_get_hw_id_mapping(
{ return -ENXIO; }
static inline int tsens_get_max_sensor_num(uint32_t *tsens_num_sensors)
{ return -ENXIO; }
static inline int tsens_set_mtc_zone_sw_mask(unsigned int zone ,
				unsigned int th1_enable ,
				unsigned int th2_enable)
{ return -ENXIO; }
static inline int tsens_get_mtc_zone_log(unsigned int zone , void *zone_log)
{ return -ENXIO; }
static inline int tsens_mtc_reset_history_counter(unsigned int zone)
{ return -ENXIO; }
#endif

#endif /*MSM_TSENS_H */