Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/sunxi Add driver for thermal sensor controller ...
details: https://anonhg.NetBSD.org/src/rev/3c1f2df64738
branches: trunk
changeset: 356606:3c1f2df64738
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Thu Oct 05 01:30:26 2017 +0000
description:
Add driver for thermal sensor controller found in Allwinner H3, A64, and
A83T SoCs.
diffstat:
sys/arch/arm/sunxi/files.sunxi | 7 +-
sys/arch/arm/sunxi/sunxi_thermal.c | 572 +++++++++++++++++++++++++++++++++++++
2 files changed, 578 insertions(+), 1 deletions(-)
diffs (truncated from 597 to 300 lines):
diff -r ca01d094776b -r 3c1f2df64738 sys/arch/arm/sunxi/files.sunxi
--- a/sys/arch/arm/sunxi/files.sunxi Thu Oct 05 01:29:49 2017 +0000
+++ b/sys/arch/arm/sunxi/files.sunxi Thu Oct 05 01:30:26 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.sunxi,v 1.25 2017/10/03 23:42:17 jmcneill Exp $
+# $NetBSD: files.sunxi,v 1.26 2017/10/05 01:30:26 jmcneill Exp $
#
# Configuration info for Allwinner sunxi family SoCs
#
@@ -174,6 +174,11 @@
attach sunxisid at fdt with sunxi_sid
file arch/arm/sunxi/sunxi_sid.c sunxi_sid
+# Thermal sensor controller
+device sunxithermal: sysmon_envsys, sysmon_taskq
+attach sunxithermal at fdt with sunxi_thermal
+file arch/arm/sunxi/sunxi_thermal.c sunxi_thermal
+
# SOC parameters
defflag opt_soc.h SOC_SUNXI
defflag opt_soc.h SOC_SUN5I: SOC_SUNXI
diff -r ca01d094776b -r 3c1f2df64738 sys/arch/arm/sunxi/sunxi_thermal.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/sunxi/sunxi_thermal.c Thu Oct 05 01:30:26 2017 +0000
@@ -0,0 +1,572 @@
+/* $NetBSD: sunxi_thermal.c,v 1.1 2017/10/05 01:30:26 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2016-2017 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Allwinner thermal sensor controller
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: sunxi_thermal.c,v 1.1 2017/10/05 01:30:26 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/reboot.h>
+
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmon_taskq.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/sunxi/sunxi_sid.h>
+
+#define THS_CTRL0 0x00
+#define THS_CTRL1 0x04
+#define ADC_CALI_EN (1 << 17)
+#define THS_CTRL2 0x40
+#define SENSOR_ACQ1_SHIFT 16
+#define SENSOR2_EN (1 << 2)
+#define SENSOR1_EN (1 << 1)
+#define SENSOR0_EN (1 << 0)
+#define THS_INTC 0x44
+#define THS_INTS 0x48
+#define THS2_DATA_IRQ_STS (1 << 10)
+#define THS1_DATA_IRQ_STS (1 << 9)
+#define THS0_DATA_IRQ_STS (1 << 8)
+#define SHUT_INT2_STS (1 << 6)
+#define SHUT_INT1_STS (1 << 5)
+#define SHUT_INT0_STS (1 << 4)
+#define ALARM_INT2_STS (1 << 2)
+#define ALARM_INT1_STS (1 << 1)
+#define ALARM_INT0_STS (1 << 0)
+#define THS_ALARM0_CTRL 0x50
+#define ALARM_T_HOT_MASK 0xfff
+#define ALARM_T_HOT_SHIFT 16
+#define ALARM_T_HYST_MASK 0xfff
+#define ALARM_T_HYST_SHIFT 0
+#define THS_SHUTDOWN0_CTRL 0x60
+#define SHUT_T_HOT_MASK 0xfff
+#define SHUT_T_HOT_SHIFT 16
+#define THS_FILTER 0x70
+#define THS_CALIB0 0x74
+#define THS_CALIB1 0x78
+#define THS_DATA0 0x80
+#define THS_DATA1 0x84
+#define THS_DATA2 0x88
+#define DATA_MASK 0xfff
+
+#define A83T_ADC_ACQUIRE_TIME 0x17
+#define A83T_FILTER 0x4
+#define A83T_INTC 0x1000
+#define A83T_TEMP_BASE 2719000
+#define A83T_TEMP_MUL 1000
+#define A83T_TEMP_DIV 14186
+#define A83T_CLK_RATE 24000000
+
+#define A64_ADC_ACQUIRE_TIME 0x190
+#define A64_FILTER 0x6
+#define A64_INTC 0x18000
+#define A64_TEMP_BASE 2170000
+#define A64_TEMP_MUL 1000
+#define A64_TEMP_DIV 8560
+#define A64_CLK_RATE 4000000
+
+#define H3_ADC_ACQUIRE_TIME 0x3f
+#define H3_FILTER 0x6
+#define H3_INTC 0x191000
+#define H3_TEMP_BASE 217
+#define H3_TEMP_MUL 1000
+#define H3_TEMP_DIV 8253
+#define H3_TEMP_MINUS 1794000
+#define H3_CLK_RATE 4000000
+#define H3_INIT_ALARM 90 /* degC */
+#define H3_INIT_SHUT 105 /* 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)
+#define ALARM_INT_ALL (ALARM_INT0_STS)
+
+#define MAX_SENSORS 3
+
+#if notyet
+#define THROTTLE_ENABLE_DEFAULT 1
+
+/* Enable thermal throttling */
+static int sunxi_thermal_throttle_enable = THROTTLE_ENABLE_DEFAULT;
+#endif
+
+struct sunxi_thermal_sensor {
+ const char *name;
+ const char *desc;
+ int init_alarm;
+ int init_shut;
+};
+
+struct sunxi_thermal_config {
+ struct sunxi_thermal_sensor sensors[MAX_SENSORS];
+ int nsensors;
+ uint64_t clk_rate;
+ uint32_t adc_acquire_time;
+ 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 calib0, calib1;
+ uint32_t calib0_mask, calib1_mask;
+};
+
+static int
+a83t_to_temp(uint32_t val)
+{
+ return ((A83T_TEMP_BASE - (val * A83T_TEMP_MUL)) / A83T_TEMP_DIV);
+}
+
+static const struct sunxi_thermal_config a83t_config = {
+ .nsensors = 3,
+ .sensors = {
+ [0] = {
+ .name = "cluster0",
+ .desc = "CPU cluster 0 temperature",
+ },
+ [1] = {
+ .name = "cluster1",
+ .desc = "CPU cluster 1 temperature",
+ },
+ [2] = {
+ .name = "gpu",
+ .desc = "GPU temperature",
+ },
+ },
+ .clk_rate = A83T_CLK_RATE,
+ .adc_acquire_time = A83T_ADC_ACQUIRE_TIME,
+ .adc_cali_en = 1,
+ .filter = A83T_FILTER,
+ .intc = A83T_INTC,
+ .to_temp = a83t_to_temp,
+ .calib0_mask = 0xffffffff,
+ .calib1_mask = 0xffffffff,
+};
+
+static int
+a64_to_temp(uint32_t val)
+{
+ return ((A64_TEMP_BASE - (val * A64_TEMP_MUL)) / A64_TEMP_DIV);
+}
+
+static const struct sunxi_thermal_config a64_config = {
+ .nsensors = 3,
+ .sensors = {
+ [0] = {
+ .name = "cpu",
+ .desc = "CPU temperature",
+ },
+ [1] = {
+ .name = "gpu1",
+ .desc = "GPU temperature 1",
+ },
+ [2] = {
+ .name = "gpu2",
+ .desc = "GPU temperature 2",
+ },
+ },
+ .clk_rate = A64_CLK_RATE,
+ .adc_acquire_time = A64_ADC_ACQUIRE_TIME,
+ .filter = A64_FILTER,
+ .intc = A64_INTC,
+ .to_temp = a64_to_temp,
+};
+
+static int
+h3_to_temp(uint32_t val)
+{
+ return (H3_TEMP_BASE - ((val * H3_TEMP_MUL) / H3_TEMP_DIV));
+}
+
+static uint32_t
+h3_to_reg(int val)
+{
+ return ((H3_TEMP_MINUS - (val * H3_TEMP_DIV)) / H3_TEMP_MUL);
+}
+
+static const struct sunxi_thermal_config h3_config = {
+ .nsensors = 1,
+ .sensors = {
+ [0] = {
+ .name = "cpu",
+ .desc = "CPU temperature",
+ .init_alarm = H3_INIT_ALARM,
+ .init_shut = H3_INIT_SHUT,
+ },
+ },
+ .clk_rate = H3_CLK_RATE,
+ .adc_acquire_time = H3_ADC_ACQUIRE_TIME,
+ .filter = H3_FILTER,
+ .intc = H3_INTC,
+ .to_temp = h3_to_temp,
+ .to_reg = h3_to_reg,
+ .calib0_mask = 0xfff,
+};
+
+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 },
+ { NULL, (uintptr_t)NULL }
+};
+
+struct sunxi_thermal_softc {
+ device_t dev;
+ int phandle;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ struct sunxi_thermal_config *conf;
+
+ kmutex_t lock;
+ callout_t tick;
+
+ struct sysmon_envsys *sme;
+ envsys_data_t data[MAX_SENSORS];
+};
+
+#define RD4(sc, reg) \
+ bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
+#define WR4(sc, reg, val) \
+ bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
+
+static int
+sunxi_thermal_init(struct sunxi_thermal_softc *sc)
+{
+ uint32_t calib[2];
+ int error;
+
+ if (sc->conf->calib0_mask != 0 || sc->conf->calib1_mask != 0) {
+ /* Read calibration settings from SRAM */
+ error = sunxi_sid_read_tscalib(calib);
Home |
Main Index |
Thread Index |
Old Index