Module Name:    src
Committed By:   jmcneill
Date:           Sun Jan 28 18:24:51 UTC 2018

Modified Files:
        src/sys/arch/arm/sunxi: sunxi_thermal.c

Log Message:
Add support for H5 CPU and GPU thermal sensors.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_thermal.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/sunxi/sunxi_thermal.c
diff -u src/sys/arch/arm/sunxi/sunxi_thermal.c:1.4 src/sys/arch/arm/sunxi/sunxi_thermal.c:1.5
--- src/sys/arch/arm/sunxi/sunxi_thermal.c:1.4	Wed Dec 13 21:37:10 2017
+++ src/sys/arch/arm/sunxi/sunxi_thermal.c	Sun Jan 28 18:24:50 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_thermal.c,v 1.4 2017/12/13 21:37:10 jmcneill Exp $ */
+/* $NetBSD: sunxi_thermal.c,v 1.5 2018/01/28 18:24:50 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2016-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_thermal.c,v 1.4 2017/12/13 21:37:10 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_thermal.c,v 1.5 2018/01/28 18:24:50 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -108,6 +108,20 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_therma
 #define	H3_INIT_ALARM		90	/* degC */
 #define	H3_INIT_SHUT		105	/* degC */
 
+#define	H5_ADC_ACQUIRE_TIME	0x1df
+#define	H5_FILTER		0x6
+#define	H5_INTC			0x3a070
+#define	H5_TEMP_DIV		20
+#define	H5_TEMP_BASE_L		233832448
+#define	H5_TEMP_MUL_L		124885
+#define	H5_TEMP_BASE_H_0	271581184
+#define	H5_TEMP_MUL_H_0		152253
+#define	H5_TEMP_BASE_H_1	289406976
+#define	H5_TEMP_MUL_H_1		166723
+#define	H5_CLK_RATE		24000000
+#define	H5_INIT_ALARM		105	/* degC */
+#define	H5_INIT_SHUT		120	/* degC */
+
 #define	TEMP_C_TO_K		273150000
 #define	SENSOR_ENABLE_ALL	(SENSOR0_EN|SENSOR1_EN|SENSOR2_EN)
 #define	SHUT_INT_ALL		(SHUT_INT0_STS|SHUT_INT1_STS|SHUT_INT2_STS)
@@ -137,17 +151,14 @@ struct sunxi_thermal_config {
 	int				adc_cali_en;
 	uint32_t			filter;
 	uint32_t			intc;
-	int				(*to_temp)(uint32_t);
-	uint32_t			(*to_reg)(int);
-	int				temp_base;
-	int				temp_mul;
-	int				temp_div;
+	int				(*to_temp)(u_int, uint32_t);
+	uint32_t			(*to_reg)(u_int, int);
 	int				calib0, calib1;
 	uint32_t			calib0_mask, calib1_mask;
 };
 
 static int
-a83t_to_temp(uint32_t val)
+a83t_to_temp(u_int sensor, uint32_t val)
 {
 	return ((A83T_TEMP_BASE - (val * A83T_TEMP_MUL)) / A83T_TEMP_DIV);
 }
@@ -179,7 +190,7 @@ static const struct sunxi_thermal_config
 };
 
 static int
-a64_to_temp(uint32_t val)
+a64_to_temp(u_int sensor, uint32_t val)
 {
 	return ((A64_TEMP_BASE - (val * A64_TEMP_MUL)) / A64_TEMP_DIV);
 }
@@ -208,13 +219,13 @@ static const struct sunxi_thermal_config
 };
 
 static int
-h3_to_temp(uint32_t val)
+h3_to_temp(u_int sensor, uint32_t val)
 {
 	return (H3_TEMP_BASE - ((val * H3_TEMP_MUL) / H3_TEMP_DIV));
 }
 
 static uint32_t
-h3_to_reg(int val)
+h3_to_reg(u_int sensor, int val)
 {
 	return ((H3_TEMP_MINUS - (val * H3_TEMP_DIV)) / H3_TEMP_MUL);
 }
@@ -238,10 +249,67 @@ static const struct sunxi_thermal_config
 	.calib0_mask = 0xfff,
 };
 
+static int
+h5_to_temp(u_int sensor, uint32_t val)
+{
+	int base, mul;
+
+	if (val >= 0x500) {
+		base = H5_TEMP_BASE_L;
+		mul = H5_TEMP_MUL_L;
+	} else {
+		base = sensor == 0 ? H5_TEMP_BASE_H_0 : H5_TEMP_BASE_H_1;
+		mul = sensor == 0 ? H5_TEMP_MUL_H_1 : H5_TEMP_MUL_H_1;
+	}
+
+	return (base - val * mul) >> H5_TEMP_DIV;
+}
+
+static uint32_t
+h5_to_reg(u_int sensor, int val)
+{
+	int base, mul;
+
+	if (val <= 70) {
+		base = H5_TEMP_BASE_L;
+		mul = H5_TEMP_MUL_L;
+	} else {
+		base = sensor == 0 ? H5_TEMP_BASE_H_0 : H5_TEMP_BASE_H_1;
+		mul = sensor == 0 ? H5_TEMP_MUL_H_1 : H5_TEMP_MUL_H_1;
+	}
+
+	return (base - (val << H5_TEMP_DIV)) / mul;
+}
+
+static const struct sunxi_thermal_config h5_config = {
+	.nsensors = 2,
+	.sensors = {
+		[0] = {
+			.name = "cpu",
+			.desc = "CPU temperature",
+			.init_alarm = H5_INIT_ALARM,
+			.init_shut = H5_INIT_SHUT,
+		},
+		[1] = {
+			.name = "gpu",
+			.desc = "GPU temperature",
+			.init_alarm = H5_INIT_ALARM,
+			.init_shut = H5_INIT_SHUT,
+		},
+	},
+	.clk_rate = H5_CLK_RATE,
+	.adc_acquire_time = H5_ADC_ACQUIRE_TIME,
+	.filter = H5_FILTER,
+	.intc = H5_INTC,
+	.to_temp = h5_to_temp,
+	.to_reg = h5_to_reg,
+};
+
 static struct of_compat_data compat_data[] = {
 	{ "allwinner,sun8i-a83t-ts",	(uintptr_t)&a83t_config },
 	{ "allwinner,sun8i-h3-ts",	(uintptr_t)&h3_config },
 	{ "allwinner,sun50i-a64-ts",	(uintptr_t)&a64_config },
+	{ "allwinner,sun50i-h5-ts",	(uintptr_t)&h5_config },
 	{ NULL,				(uintptr_t)NULL }
 };
 
@@ -311,7 +379,7 @@ sunxi_thermal_gettemp(struct sunxi_therm
 
 	val = RD4(sc, THS_DATA0 + (sensor * 4));
 
-	return sc->conf->to_temp(val);
+	return sc->conf->to_temp(sensor, val);
 }
 
 static int
@@ -322,7 +390,7 @@ sunxi_thermal_getshut(struct sunxi_therm
 	val = RD4(sc, THS_SHUTDOWN0_CTRL + (sensor * 4));
 	val = (val >> SHUT_T_HOT_SHIFT) & SHUT_T_HOT_MASK;
 
-	return sc->conf->to_temp(val);
+	return sc->conf->to_temp(sensor, val);
 }
 
 static void
@@ -332,7 +400,7 @@ sunxi_thermal_setshut(struct sunxi_therm
 
 	val = RD4(sc, THS_SHUTDOWN0_CTRL + (sensor * 4));
 	val &= ~(SHUT_T_HOT_MASK << SHUT_T_HOT_SHIFT);
-	val |= (sc->conf->to_reg(temp) << SHUT_T_HOT_SHIFT);
+	val |= (sc->conf->to_reg(sensor, temp) << SHUT_T_HOT_SHIFT);
 	WR4(sc, THS_SHUTDOWN0_CTRL + (sensor * 4), val);
 }
 
@@ -344,7 +412,7 @@ sunxi_thermal_gethyst(struct sunxi_therm
 	val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4));
 	val = (val >> ALARM_T_HYST_SHIFT) & ALARM_T_HYST_MASK;
 
-	return sc->conf->to_temp(val);
+	return sc->conf->to_temp(sensor, val);
 }
 
 static int
@@ -355,7 +423,7 @@ sunxi_thermal_getalarm(struct sunxi_ther
 	val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4));
 	val = (val >> ALARM_T_HOT_SHIFT) & ALARM_T_HOT_MASK;
 
-	return sc->conf->to_temp(val);
+	return sc->conf->to_temp(sensor, val);
 }
 
 static void
@@ -365,7 +433,7 @@ sunxi_thermal_setalarm(struct sunxi_ther
 
 	val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4));
 	val &= ~(ALARM_T_HOT_MASK << ALARM_T_HOT_SHIFT);
-	val |= (sc->conf->to_reg(temp) << ALARM_T_HOT_SHIFT);
+	val |= (sc->conf->to_reg(sensor, temp) << ALARM_T_HOT_SHIFT);
 	WR4(sc, THS_ALARM0_CTRL + (sensor * 4), val);
 }
 

Reply via email to