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

Commit 23ed8497 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: Enable TSENS driver debug check"

parents 7e38aa10 00c1e17f
Loading
Loading
Loading
Loading
+139 −9
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/thermal.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/io.h>
@@ -95,6 +96,9 @@
#define TSENS_TM_CODE_BIT_MASK			0xfff
#define TSENS_TM_CODE_BIT_MASK			0xfff
#define TSENS_TM_CODE_SIGN_BIT			0x800
#define TSENS_TM_CODE_SIGN_BIT			0x800


#define TSENS_CONTROLLER_ID(n)			((n) + 0x1000)
#define TSENS_DEBUG_CONTROL(n)			((n) + 0x1130)
#define TSENS_DEBUG_DATA(n)			((n) + 0x1134)
/* End TSENS_TM registers for 8996 */
/* End TSENS_TM registers for 8996 */


#define TSENS_CTRL_ADDR(n)		(n)
#define TSENS_CTRL_ADDR(n)		(n)
@@ -636,6 +640,22 @@
#define TSENS_NO_CALIB_POINT1_DATA 500
#define TSENS_NO_CALIB_POINT1_DATA 500
#define TSENS_NO_CALIB_POINT2_DATA 780
#define TSENS_NO_CALIB_POINT2_DATA 780


/* debug defines */
#define TSENS_DEBUG_BUS_ID_2		2
#define TSENS_DEBUG_BUS_ID_3		3
#define TSENS_DEBUG_BUS_ID_4		4
#define TSENS_DEBUG_LOOP_COUNT		5
#define TSENS_DEBUG_SROT_OFFSET_RANGE	0x140
#define TSENS_DEBUG_TM_OFFSET_RANGE	0x80
#define TSENS_DEBUG_OFFSET_WORD1	0x4
#define TSENS_DEBUG_OFFSET_WORD2	0x8
#define TSENS_DEBUG_OFFSET_WORD3	0xc
#define TSENS_DEBUG_OFFSET_ROW		0x10
#define TSENS_DEBUG_10_DECIDEGC		100

static uint32_t tsens_sec_to_msec_value = 3000;
static uint32_t tsens_completion_timeout_hz = HZ;

enum tsens_calib_fuse_map_type {
enum tsens_calib_fuse_map_type {
	TSENS_CALIB_FUSE_MAP_8974 = 0,
	TSENS_CALIB_FUSE_MAP_8974 = 0,
	TSENS_CALIB_FUSE_MAP_8X26,
	TSENS_CALIB_FUSE_MAP_8X26,
@@ -724,6 +744,8 @@ struct tsens_tm_device {
	int				tsens_upper_irq_cnt;
	int				tsens_upper_irq_cnt;
	int				tsens_lower_irq_cnt;
	int				tsens_lower_irq_cnt;
	int				tsens_critical_irq_cnt;
	int				tsens_critical_irq_cnt;
	struct delayed_work		tsens_critical_poll_test;
	struct completion		tsens_rslt_completion;
	struct tsens_tm_device_sensor	sensor[0];
	struct tsens_tm_device_sensor	sensor[0];
};
};


@@ -1583,6 +1605,105 @@ static int tsens_tz_set_trip_temp(struct thermal_zone_device *thermal,
	return 0;
	return 0;
}
}


static void tsens_poll(struct work_struct *work)
{
	struct tsens_tm_device *tmdev = container_of(work,
		       struct tsens_tm_device, tsens_critical_poll_test.work);
	unsigned int reg_cntl, mask, rc = 0, debug_dump, i = 0, loop = 0;
	uint32_t r1, r2, r3, r4, offset = 0;
	unsigned long temp;
	void __iomem *srot_addr;
	void __iomem *controller_id_addr;
	void __iomem *debug_id_addr;
	void __iomem *debug_data_addr;

	/* Set the Critical temperature threshold to a value of 10 that should
	 * guarantee a threshold to trigger. Check the interrupt count if
	 * it did. Schedule the next round of the above test again after
	 * 3 seconds.
	 */

	controller_id_addr = TSENS_CONTROLLER_ID(tmdev->tsens_addr);
	debug_id_addr = TSENS_DEBUG_CONTROL(tmdev->tsens_addr);
	debug_data_addr = TSENS_DEBUG_DATA(tmdev->tsens_addr);
	srot_addr = TSENS_CTRL_ADDR(tmdev->tsens_addr);

	temp = TSENS_DEBUG_10_DECIDEGC;
	/* Sensor 0 on either of the controllers */
	mask = 0;

	reinit_completion(&tmdev->tsens_rslt_completion);

	temp &= TSENS_TM_SN_CRITICAL_THRESHOLD_MASK;
	writel_relaxed(temp,
			(TSENS_TM_SN_CRITICAL_THRESHOLD(tmdev->tsens_addr) +
			(mask * TSENS_SN_ADDR_OFFSET)));

	reg_cntl = readl_relaxed(TSENS_TM_CRITICAL_INT_MASK(tmdev->tsens_addr));
	writel_relaxed(reg_cntl & ~(1 << mask),
				(TSENS_TM_CRITICAL_INT_MASK
				(tmdev->tsens_addr)));

	rc = wait_for_completion_timeout(
				&tmdev->tsens_rslt_completion,
				tsens_completion_timeout_hz);
	if (!rc) {
		pr_err("Did not receive the TSENS critical interrupt\n");
		debug_dump = readl_relaxed(controller_id_addr);
		pr_err("Controller_id: 0x%x\n", debug_dump);
		for (i = TSENS_DEBUG_BUS_ID_2; i < TSENS_DEBUG_BUS_ID_4; i++) {
			loop = 0;
			while (loop < TSENS_DEBUG_LOOP_COUNT) {
				writel_relaxed((i << 1) | 1,
					TSENS_DEBUG_CONTROL(tmdev->tsens_addr));
				debug_dump = readl_relaxed(debug_data_addr);
				pr_err("Data dump for debug bus-id:%d with data debug value: 0x%x\n",
					i, debug_dump);
				loop++;
			}
			loop = 0;
		}

		pr_err("Start of TSENS TM dump\n");
		for (i = 0; i < TSENS_DEBUG_SROT_OFFSET_RANGE;
						i += TSENS_DEBUG_OFFSET_WORD1) {
			r1 = readl_relaxed(controller_id_addr + offset);
			r2 = readl_relaxed(controller_id_addr + (offset +
						TSENS_DEBUG_OFFSET_WORD1));
			r3 = readl_relaxed(controller_id_addr +	(offset +
						TSENS_DEBUG_OFFSET_WORD2));
			r4 = readl_relaxed(controller_id_addr + (offset +
						TSENS_DEBUG_OFFSET_WORD3));

			pr_err("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
				offset, r1, r2, r3, r4);
			offset += TSENS_DEBUG_OFFSET_ROW;
		}

		offset = 0;
		pr_err("Start of TSENS SROT dump\n");
		for (i = 0; i < TSENS_DEBUG_TM_OFFSET_RANGE;
						i += TSENS_DEBUG_OFFSET_WORD1) {
			r1 = readl_relaxed(srot_addr + offset);
			r2 = readl_relaxed(srot_addr + (offset +
						TSENS_DEBUG_OFFSET_WORD1));
			r3 = readl_relaxed(srot_addr + (offset +
						TSENS_DEBUG_OFFSET_WORD2));
			r4 = readl_relaxed(srot_addr + (offset +
						TSENS_DEBUG_OFFSET_WORD3));

			pr_err("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
				offset, r1, r2, r3, r4);
			offset += TSENS_DEBUG_OFFSET_ROW;
		}

		BUG();
	}

	schedule_delayed_work(&tmdev->tsens_critical_poll_test,
			msecs_to_jiffies(tsens_sec_to_msec_value));
}

static struct thermal_zone_device_ops tsens_thermal_zone_ops = {
static struct thermal_zone_device_ops tsens_thermal_zone_ops = {
	.get_temp = tsens_tz_get_temp,
	.get_temp = tsens_tz_get_temp,
	.get_mode = tsens_tz_get_mode,
	.get_mode = tsens_tz_get_mode,
@@ -1632,35 +1753,39 @@ static irqreturn_t tsens_tm_critical_irq_thread(int irq, void *data)
			!(int_mask & (1 << tm->sensor[i].sensor_hw_num))) {
			!(int_mask & (1 << tm->sensor[i].sensor_hw_num))) {
			int_mask = readl_relaxed(sensor_int_mask_addr);
			int_mask = readl_relaxed(sensor_int_mask_addr);
			int_mask_val = (1 << tm->sensor[i].sensor_hw_num);
			int_mask_val = (1 << tm->sensor[i].sensor_hw_num);
			/* Mask the corresponding interrupt for the sensors */
			writel_relaxed(int_mask | int_mask_val,
			writel_relaxed(int_mask | int_mask_val,
				TSENS_TM_CRITICAL_INT_MASK(
				TSENS_TM_CRITICAL_INT_MASK(
					tm->tsens_addr));
					tm->tsens_addr));
			writel_relaxed(int_mask,
			/* Clear the corresponding sensors interrupt */
			writel_relaxed(int_mask_val,
				TSENS_TM_CRITICAL_INT_CLEAR(tm->tsens_addr));
				TSENS_TM_CRITICAL_INT_CLEAR(tm->tsens_addr));
			writel_relaxed(0,
				TSENS_TM_CRITICAL_INT_CLEAR(
					tm->tsens_addr));
			critical_thr = true;
			critical_thr = true;
		}
		}


		if (critical_thr) {
		if (critical_thr) {
			unsigned long temp;
			unsigned long temp;
			enum thermal_trip_type trip =
					THERMAL_TRIP_CRITICAL;
			tsens_tz_get_temp(tm->sensor[i].tz_dev, &temp);
			tsens_tz_get_temp(tm->sensor[i].tz_dev, &temp);
			thermal_sensor_trip(tm->sensor[i].tz_dev, trip, temp);

			rc = tsens_get_sw_id_mapping_for_controller(
			rc = tsens_get_sw_id_mapping_for_controller(
					tm->sensor[i].sensor_hw_num,
					tm->sensor[i].sensor_hw_num,
					&sensor_sw_id, tm);
					&sensor_sw_id, tm);
			if (rc < 0)
			if (rc < 0)
				pr_err("tsens mapping index not found\n");
				pr_err("tsens mapping index not found\n");
			pr_debug("sensor:%d trigger temp (%d degC)\n",
			pr_debug("sensor:%d trigger temp (%d degC) with count:%d\n",
				tm->sensor[i].sensor_hw_num,
				tm->sensor[i].sensor_hw_num,
				(status & TSENS_TM_SN_LAST_TEMP_MASK));
				(status & TSENS_TM_SN_LAST_TEMP_MASK),
				tm->tsens_critical_irq_cnt);

				tm->tsens_critical_irq_cnt++;
			threshold = readl_relaxed(sensor_critical_addr +
			threshold = readl_relaxed(sensor_critical_addr +
								addr_offset);
								addr_offset);
			tm->tsens_critical_irq_cnt++;
		}
		}
	}
	}


	complete(&tm->tsens_rslt_completion);
	/* Mask critical interrupt */
	/* Mask critical interrupt */
	mb();
	mb();


@@ -4524,6 +4649,12 @@ static int tsens_thermal_zone_register(struct tsens_tm_device *tmdev)
		} else {
		} else {
			enable_irq_wake(tmdev->tsens_critical_irq);
			enable_irq_wake(tmdev->tsens_critical_irq);
		}
		}

		INIT_DEFERRABLE_WORK(&tmdev->tsens_critical_poll_test,
								tsens_poll);
		schedule_delayed_work(&tmdev->tsens_critical_poll_test,
			msecs_to_jiffies(tsens_sec_to_msec_value));
		init_completion(&tmdev->tsens_rslt_completion);
	} else {
	} else {
		rc = request_threaded_irq(tmdev->tsens_irq, NULL,
		rc = request_threaded_irq(tmdev->tsens_irq, NULL,
			tsens_irq_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
			tsens_irq_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
@@ -4539,7 +4670,6 @@ static int tsens_thermal_zone_register(struct tsens_tm_device *tmdev)
		}
		}
	}
	}



	return 0;
	return 0;
fail:
fail:
	if (tmdev->tsens_calib_addr)
	if (tmdev->tsens_calib_addr)