Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch implement TSADC driver for rockchip RK3328 and RK33...



details:   https://anonhg.NetBSD.org/src/rev/a893d11cfe70
branches:  trunk
changeset: 456171:a893d11cfe70
user:      mrg <mrg%NetBSD.org@localhost>
date:      Fri Apr 26 08:28:11 2019 +0000

description:
implement TSADC driver for rockchip RK3328 and RK3399.  so far, only
tested on RK3399 but the RK3328 looks mostly the same and has a good
chance of working too.

add clock entries for "clk_tsadc" and "pclk_tsadc" to cru.

exports "CPU" and "GPU" temp sensors.  these currently limited to 5
degC resolution but can be reduced to sub 1 degC resolution with some
interpolation.

todo list:

- handle setting various temp values
- add interpolation between the 5degC intervals in sample data
- handle DT trips/temp value defaults
- interrupts aren't triggered (test by lowering warn/crit values),
  and once they work, make the interrupt do something
- test on RK3328, and port to other rockchips (will require moving
  some part into per-chipset sections, such as code<->temp tables)


thanks to jmcneill for help.

diffstat:

 sys/arch/arm/rockchip/files.rockchip |    7 +-
 sys/arch/arm/rockchip/rk3399_cru.c   |   15 +-
 sys/arch/arm/rockchip/rk_tsadc.c     |  736 +++++++++++++++++++++++++++++++++++
 sys/arch/evbarm/conf/GENERIC64       |    3 +-
 4 files changed, 757 insertions(+), 4 deletions(-)

diffs (truncated from 822 to 300 lines):

diff -r 4ca7bf3597c2 -r a893d11cfe70 sys/arch/arm/rockchip/files.rockchip
--- a/sys/arch/arm/rockchip/files.rockchip      Fri Apr 26 07:35:21 2019 +0000
+++ b/sys/arch/arm/rockchip/files.rockchip      Fri Apr 26 08:28:11 2019 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.rockchip,v 1.17 2019/03/10 11:10:21 jmcneill Exp $
+#      $NetBSD: files.rockchip,v 1.18 2019/04/26 08:28:11 mrg Exp $
 #
 # Configuration info for Rockchip family SoCs
 #
@@ -68,6 +68,11 @@
 attach rkemmcphy at fdt
 file   arch/arm/rockchip/rk_emmcphy.c          rkemmcphy
 
+# TSADC temperature sensors
+device rktsadc: sysmon_envsys
+attach rktsadc at fdt with rk_tsadc
+file   arch/arm/rockchip/rk_tsadc.c            rk_tsadc
+
 # SOC parameters
 defflag        opt_soc.h                       SOC_ROCKCHIP
 defflag        opt_soc.h                       SOC_RK3328: SOC_ROCKCHIP
diff -r 4ca7bf3597c2 -r a893d11cfe70 sys/arch/arm/rockchip/rk3399_cru.c
--- a/sys/arch/arm/rockchip/rk3399_cru.c        Fri Apr 26 07:35:21 2019 +0000
+++ b/sys/arch/arm/rockchip/rk3399_cru.c        Fri Apr 26 08:28:11 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3399_cru.c,v 1.6 2019/03/13 10:29:56 jmcneill Exp $ */
+/* $NetBSD: rk3399_cru.c,v 1.7 2019/04/26 08:28:11 mrg Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.6 2019/03/13 10:29:56 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.7 2019/04/26 08:28:11 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -345,6 +345,7 @@
 static const char * pll_parents[] = { "xin24m", "xin32k" };
 static const char * armclkl_parents[] = { "clk_core_l_lpll_src", "clk_core_l_bpll_src", "clk_core_l_dpll_src", "clk_core_l_gpll_src" };
 static const char * armclkb_parents[] = { "clk_core_b_lpll_src", "clk_core_b_bpll_src", "clk_core_b_dpll_src", "clk_core_b_gpll_src" };
+static const char * mux_clk_tsadc_parents[] = { "xin24m", "xin32k" };
 static const char * mux_pll_src_cpll_gpll_parents[] = { "cpll", "gpll" };
 static const char * mux_pll_src_cpll_gpll_npll_parents[] = { "cpll", "gpll", "npll" };
 static const char * mux_pll_src_cpll_gpll_upll_parents[] = { "cpll", "gpll", "upll" };
@@ -785,6 +786,16 @@
                     __BIT(3),          /* gate_mask */
                     0),
        RK_MUX(RK3399_SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_parents, CLKSEL_CON(18), __BIT(7)),
+
+       /* TSADC */
+       RK_COMPOSITE(RK3399_SCLK_TSADC, "clk_tsadc", mux_clk_tsadc_parents,
+                    CLKSEL_CON(27),    /* muxdiv_reg */
+                    __BIT(15),         /* mux_mask */
+                    __BITS(9,0),       /* div_mask */
+                    CLKGATE_CON(9),    /* gate_reg */
+                    __BIT(1),          /* gate_mask */
+                    RK_COMPOSITE_ROUND_DOWN),
+       RK_GATE(RK3399_PCLK_TSADC, "pclk_tsadc", "pclk_perilp1", CLKGATE_CON(22), 13),
 };
 
 static int
diff -r 4ca7bf3597c2 -r a893d11cfe70 sys/arch/arm/rockchip/rk_tsadc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/rockchip/rk_tsadc.c  Fri Apr 26 08:28:11 2019 +0000
@@ -0,0 +1,736 @@
+/*     $NetBSD: rk_tsadc.c,v 1.1 2019/04/26 08:28:11 mrg Exp $ */
+
+/*
+ * Copyright (c) 2019 Matthew R. Green
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.1 2019/04/26 08:28:11 mrg Exp $");
+
+/*
+ * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399.
+ *
+ * TODO:
+ * - handle setting various temp values
+ * - add interpolation between the 5degC intervals in sample data
+ * - handle DT trips/temp value defaults
+ * - interrupts aren't triggered (test by lowering warn/crit values), and
+ *   once they work, make the interrupt do something
+ * - test on RK3328, and port to other rockchips (will require moving some
+ *   part into per-chipset sections, such as code<->temp tables)
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kmem.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
+
+#include <dev/sysmon/sysmonvar.h>
+
+//#define RKTSADC_DEBUG
+#ifdef RKTSADC_DEBUG
+#define DPRINTF(fmt, ...) \
+       printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+/* Register definitions */
+#define TSADC_USER_CON                          0x00
+#define  TSADC_USER_CON_ADC_STATUS              __BIT(12)
+#define  TSADC_USER_CON_INTER_PD_SOC            __BITS(11,6)
+#define  TSADC_USER_CON_START                   __BIT(5)
+#define  TSADC_USER_CON_START_MODE              __BIT(4)
+#define  TSADC_USER_CON_ADC_POWER_CTRL          __BIT(3)
+#define  TSADC_USER_CON_ADC_INPUT_SRC_SEL       __BITS(2,0)
+#define TSADC_AUTO_CON                          0x04
+#define  TSADC_AUTO_CON_LAST_TSHUT_2CRU         __BIT(25)
+#define  TSADC_AUTO_CON_LAST_TSHUT_2GPIO        __BIT(24)
+#define  TSADC_AUTO_CON_SAMPLE_DLY_SEL          __BIT(17)
+#define  TSADC_AUTO_CON_AUTO_STATUS             __BIT(16)
+#define  TSADC_AUTO_CON_SRC1_LT_EN              __BIT(13)
+#define  TSADC_AUTO_CON_SRC0_LT_EN              __BIT(12)
+#define  TSADC_AUTO_CON_TSHUT_POLARITY          __BIT(8)
+#define  TSADC_AUTO_CON_SRC1_EN                 __BIT(5)
+#define  TSADC_AUTO_CON_SRC0_EN                 __BIT(4)
+#define  TSADC_AUTO_CON_Q_SEL                   __BIT(1)
+#define  TSADC_AUTO_CON_AUTO_EN                 __BIT(0)
+#define TSADC_INT_EN                            0x08
+#define  TSADC_INT_EN_EOC_INT_EN                __BIT(16)
+#define  TSADC_INT_EN_LT_INTEN_SRC1             __BIT(13)
+#define  TSADC_INT_EN_LT_INTEN_SRC0             __BIT(12)
+#define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC1        __BIT(9)
+#define  TSADC_INT_EN_TSHUT_2CRU_EN_SRC0        __BIT(8)
+#define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1       __BIT(5)
+#define  TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0       __BIT(4)
+#define  TSADC_INT_EN_HT_INTEN_SRC1             __BIT(1)
+#define  TSADC_INT_EN_HT_INTEN_SRC0             __BIT(0)
+#define TSADC_INT_PD                            0x0c
+#define  TSADC_INT_PD_EOC_INT_PD                __BIT(16)
+#define  TSADC_INT_PD_LT_IRQ_SRC1               __BIT(13)
+#define  TSADC_INT_PD_LT_IRQ_SRC0               __BIT(12)
+#define  TSADC_INT_PD_TSHUT_O_SRC1              __BIT(5)
+#define  TSADC_INT_PD_TSHUT_O_SRC0              __BIT(4)
+#define  TSADC_INT_PD_HT_IRQ_SRC1               __BIT(1)
+#define  TSADC_INT_PD_HT_IRQ_SRC0               __BIT(0)
+#define TSADC_DATA0                             0x20
+#define  TSADC_DATA0_ADC_DATA                   __BITS(11,0)
+#define TSADC_DATA1                             0x24
+#define  TSADC_DATA1_ADC_DATA                   __BITS(11,0)
+#define TSADC_COMP0_INT                         0x30
+#define  TSADC_COMP0_INT_COMP_SRC0              __BITS(11,0)
+#define TSADC_COMP1_INT                         0x34
+#define  TSADC_COMP1_INT_COMP_SRC1              __BITS(11,0)
+#define TSADC_COMP0_SHUT                        0x40
+#define  TSADC_COMP0_SHUT_COMP_SRC0             __BITS(11,0)
+#define TSADC_COMP1_SHUT                        0x44
+#define  TSADC_COMP1_SHUT_COMP_SRC1             __BITS(11,0)
+#define TSADC_HIGH_INT_DEBOUNCE                 0x60
+#define  TSADC_HIGH_INT_DEBOUNCE_TEMP           __BITS(7,0)
+#define TSADC_HIGH_TSHUT_DEBOUNCE               0x64
+#define  TSADC_HIGH_TSHUT_DEBOUNCE_TEMP         __BITS(7,0)
+#define TSADC_AUTO_PERIOD                       0x68
+#define  TSADC_AUTO_PERIOD_TEMP                 __BITS(31,0)
+#define TSADC_AUTO_PERIOD_HT                    0x6c
+#define  TSADC_AUTO_PERIOD_HT_TEMP              __BITS(31,0)
+#define TSADC_COMP0_LOW_INT                     0x80
+#define  TSADC_COMP0_LOW_INT_COMP_SRC0          __BITS(11,0)
+#define TSADC_COMP1_LOW_INT                     0x84
+#define  TSADC_COMP1_LOW_INT_COMP_SRC1          __BITS(11,0)
+
+#define TSADC_AUTO_PERIOD_TIME                  1875 /* 2.5ms */
+#define TSADC_HT_DEBOUNCE_COUNT                 4
+
+/*
+ * All this magic is taking from the Linux rockchip_thermal driver.
+ *
+ * VCM means "voltage common mode", but the documentation for RK3399
+ * does not mention this and I don't know what any of this really
+ * is for.
+ */
+#define RK3399_GRF_SARADC_TESTBIT               0xe644
+#define  RK3399_GRF_SARADC_TESTBIT_ON           (0x10001 << 2)
+#define RK3399_GRF_TSADC_TESTBIT_L              0xe648
+#define  RK3399_GRF_TSADC_TESTBIT_VCM_EN_L      (0x10001 << 7)
+#define RK3399_GRF_TSADC_TESTBIT_H              0xe64c
+#define  RK3399_GRF_TSADC_TESTBIT_VCM_EN_H      (0x10001 << 7)
+#define  RK3399_GRF_TSADC_TESTBIT_H_ON          (0x10001 << 2)
+
+#define TEMP_uC_TO_uK             273150000
+
+#define TSHUT_MODE_CPU    0
+#define TSHUT_MODE_GPIO   1
+
+#define TSHUT_LOW_ACTIVE  0
+#define TSHUT_HIGH_ACTIVE 1
+
+#define TSHUT_DEF_TEMP    95000
+
+#define TSADC_DATA_MAX    0xfff
+
+#define NUM_SENSORS       2
+
+/* Table from RK3399 manual */
+static const struct {
+       uint32_t data;  /* register value */
+       int temp;       /* micro-degC */
+} rk3399_data_table[] = {
+#define ENTRY(d,C)     { .data = (d), .temp = (C) * 1000 * 1000, }
+       ENTRY(0,   -40),
+       ENTRY(402, -40),
+       ENTRY(410, -35),
+       ENTRY(419, -30),
+       ENTRY(427, -25),
+       ENTRY(436, -20),
+       ENTRY(444, -15),
+       ENTRY(453, -10),
+       ENTRY(461,  -5),
+       ENTRY(470,   0),
+       ENTRY(478,   5),
+       ENTRY(487,  10),
+       ENTRY(496,  15),
+       ENTRY(504,  20),
+       ENTRY(513,  25),
+       ENTRY(521,  30),
+       ENTRY(530,  35),
+       ENTRY(538,  40),
+       ENTRY(547,  45),
+       ENTRY(555,  50),
+       ENTRY(564,  55),
+       ENTRY(573,  60),
+       ENTRY(581,  65),
+       ENTRY(590,  70),
+       ENTRY(599,  75),
+       ENTRY(607,  80),
+       ENTRY(616,  85),
+       ENTRY(624,  90),
+       ENTRY(633,  95),
+       ENTRY(642, 100),
+       ENTRY(650, 105),
+       ENTRY(659, 110),
+       ENTRY(668, 115),
+       ENTRY(677, 120),
+       ENTRY(685, 125),
+#undef ENTRY
+};
+
+/* Per-sensor data */
+struct rk_tsadc_sensor {
+       envsys_data_t   s_data;
+       bool            s_attached;
+       /* TSADC register offsets for this sensor */
+       unsigned        s_data_reg;
+       unsigned        s_comp_tshut;
+       unsigned        s_comp_int;
+       unsigned        s_comp_int_en;
+       /* warn/crit values in micro Kelvin */
+       int             s_warn;
+       int             s_tshut;
+};
+
+struct rk_tsadc_softc {
+       device_t                sc_dev;
+       int                     sc_phandle;
+       bus_space_tag_t         sc_bst;
+       bus_space_handle_t      sc_bsh;
+       size_t                  sc_size;
+       uint32_t                sc_data_mask;
+       void                    *sc_ih;
+
+       struct sysmon_envsys    *sc_sme;
+       struct rk_tsadc_sensor  sc_sensors[NUM_SENSORS];



Home | Main Index | Thread Index | Old Index