Module Name:    src
Committed By:   mrg
Date:           Wed May 15 01:24:43 UTC 2019

Modified Files:
        src/sys/arch/arm/rockchip: rk3328_cru.c rk_tsadc.c

Log Message:
support RK3328 tsadc:

- add clk_24m, clk_tsadc and pclk_tsadc rk3328 clocks
- rk3328 data<->temp conversion table is is wrong.  the actual values
  seen are 4096 - <expected>, and the linux driver has these values
  in the inverted value directly
- the above means the rk3328 is increasing data for increasing temp,
  and the min/max values are also inverted and swapped
- move auto-period into the rk_data
- rk3328 only has one sensor, deal with this
- rename rk_data_table as rk_data, and also s/rdt/rd/

thanks to jmcneill who helped clean up clocks confusion, and pointed
out the linux driver values matched my own inverted data experience.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/rockchip/rk3328_cru.c \
    src/sys/arch/arm/rockchip/rk_tsadc.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/rockchip/rk3328_cru.c
diff -u src/sys/arch/arm/rockchip/rk3328_cru.c:1.4 src/sys/arch/arm/rockchip/rk3328_cru.c:1.5
--- src/sys/arch/arm/rockchip/rk3328_cru.c:1.4	Sun Aug 12 16:48:04 2018
+++ src/sys/arch/arm/rockchip/rk3328_cru.c	Wed May 15 01:24:43 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3328_cru.c,v 1.4 2018/08/12 16:48:04 jmcneill Exp $ */
+/* $NetBSD: rk3328_cru.c,v 1.5 2019/05/15 01:24:43 mrg Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: rk3328_cru.c,v 1.4 2018/08/12 16:48:04 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3328_cru.c,v 1.5 2019/05/15 01:24:43 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -147,6 +147,7 @@ static const char * mux_uart1_parents[] 
 static const char * mux_uart2_parents[] = { "clk_uart2_div", "clk_uart2_frac", "xin24m" };
 static const char * mux_mac2io_src_parents[] = { "clk_mac2io_src", "gmac_clkin" };
 static const char * mux_mac2io_ext_parents[] = { "clk_mac2io", "gmac_clkin" };
+static const char * mux_clk_tsadc_parents[] = { "clk_24m" };
 static const char * mux_2plls_parents[] = { "cpll", "gpll" };
 static const char * mux_2plls_hdmiphy_parents[] = { "cpll", "gpll", "dummy_hdmiphy" };
 static const char * comp_uart_parents[] = { "cpll", "gpll", "usb480m" };
@@ -329,6 +330,15 @@ static struct rk_cru_clk rk3328_cru_clks
 		     CLKGATE_CON(2),	/* gate_reg */
 		     __BIT(12),		/* gate_mask */
 		     0),
+	RK_COMPOSITE(RK3328_SCLK_TSADC, "clk_tsadc", mux_clk_tsadc_parents,
+		     CLKSEL_CON(22),	/* muxdiv_reg */
+		     0,			/* mux_mask */
+		     __BITS(9,0),	/* div_mask */
+		     CLKGATE_CON(2),	/* gate_reg */
+		     __BIT(6),		/* gate_mask */
+		     0),
+
+	RK_DIV(0, "clk_24m", "xin24m", CLKSEL_CON(2), __BITS(12,8), 0),
 
 	RK_GATE(0, "apll_core", "apll", CLKGATE_CON(0), 0),
 	RK_GATE(0, "dpll_core", "dpll", CLKGATE_CON(0), 1),
@@ -351,6 +361,7 @@ static struct rk_cru_clk rk3328_cru_clks
 	RK_GATE(RK3328_PCLK_UART0, "pclk_uart0", "pclk_bus", CLKGATE_CON(16), 11),
 	RK_GATE(RK3328_PCLK_UART1, "pclk_uart1", "pclk_bus", CLKGATE_CON(16), 12),
 	RK_GATE(RK3328_PCLK_UART2, "pclk_uart2", "pclk_bus", CLKGATE_CON(16), 13),
+	RK_GATE(RK3328_PCLK_TSADC, "pclk_tsadc", "pclk_bus", CLKGATE_CON(16), 14),
 	RK_GATE(RK3328_SCLK_MAC2IO_REF, "clk_mac2io_ref", "clk_mac2io", CLKGATE_CON(9), 7),
 	RK_GATE(RK3328_SCLK_MAC2IO_RX, "clk_mac2io_rx", "clk_mac2io", CLKGATE_CON(9), 4),
 	RK_GATE(RK3328_SCLK_MAC2IO_TX, "clk_mac2io_tx", "clk_mac2io", CLKGATE_CON(9), 5),
Index: src/sys/arch/arm/rockchip/rk_tsadc.c
diff -u src/sys/arch/arm/rockchip/rk_tsadc.c:1.4 src/sys/arch/arm/rockchip/rk_tsadc.c:1.5
--- src/sys/arch/arm/rockchip/rk_tsadc.c:1.4	Tue May 14 07:45:03 2019
+++ src/sys/arch/arm/rockchip/rk_tsadc.c	Wed May 15 01:24:43 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: rk_tsadc.c,v 1.4 2019/05/14 07:45:03 mrg Exp $	*/
+/*	$NetBSD: rk_tsadc.c,v 1.5 2019/05/15 01:24:43 mrg Exp $	*/
 
 /*
  * Copyright (c) 2019 Matthew R. Green
@@ -30,7 +30,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.4 2019/05/14 07:45:03 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v 1.5 2019/05/15 01:24:43 mrg Exp $");
 
 /*
  * Driver for the TSADC temperature sensor monitor in RK3328 and RK3399.
@@ -40,8 +40,6 @@ __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v
  * - 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
- * - fix for RK3328, and port to other rockchips (will require moving some
- *   part into per-chipset sections, such as code<->temp tables)
  */
 
 #include <sys/param.h>
@@ -57,7 +55,6 @@ __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v
 
 #include <dev/sysmon/sysmonvar.h>
 
-//#define RKTSADC_DEBUG
 #ifdef RKTSADC_DEBUG
 #define DPRINTF(fmt, ...) \
 	printf("%s:%d: " fmt "\n", __func__, __LINE__, ## __VA_ARGS__)
@@ -159,7 +156,7 @@ __KERNEL_RCSID(0, "$NetBSD: rk_tsadc.c,v
 
 #define TSADC_DATA_MAX    0xfff
 
-#define NUM_SENSORS       2
+#define MAX_SENSORS       2
 
 typedef struct rk_data_array {
 	uint32_t data;  /* register value */
@@ -167,14 +164,15 @@ typedef struct rk_data_array {
 } rk_data_array;
 
 struct rk_tsadc_softc;
-typedef struct rk_data_table {
-	const rk_data_array	*rdt_array;
-	size_t			 rdt_size;
-	void			(*rdt_init)(struct rk_tsadc_softc *, int, int);
-	bool			 rdt_decr;  /* lower values -> higher temp */
-	unsigned		 rdt_min, rdt_max;
-	unsigned		 rdt_auto_period;
-} rk_data_table;
+typedef struct rk_data {
+	const rk_data_array	*rd_array;
+	size_t			 rd_size;
+	void			(*rd_init)(struct rk_tsadc_softc *, int, int);
+	bool			 rd_decr;  /* lower values -> higher temp */
+	unsigned		 rd_min, rd_max;
+	unsigned		 rd_auto_period;
+	unsigned		 rd_num_sensors;
+} rk_data;
 
 /* Per-sensor data */
 struct rk_tsadc_sensor {
@@ -201,14 +199,14 @@ struct rk_tsadc_softc {
 	void			*sc_ih;
 
 	struct sysmon_envsys	*sc_sme;
-	struct rk_tsadc_sensor	sc_sensors[NUM_SENSORS];
+	struct rk_tsadc_sensor	sc_sensors[MAX_SENSORS];
 
 	struct clk		*sc_clock;
 	struct clk		*sc_clockapb;
 	struct fdtbus_reset	*sc_reset;
 	struct syscon		*sc_syscon;
 
-	const rk_data_table	*sc_rdt;
+	const rk_data		*sc_rd;
 };
 
 static int rk_tsadc_match(device_t, cfdata_t, void *);
@@ -264,9 +262,15 @@ static const struct rk_tsadc_sensor rk_t
 	},
 };
 
-/* Table from RK3328 manual */
+/*
+ * Table from RK3328 manual.  Note that the manual lists valid numbers as
+ * 4096 - number.  This also means it is increasing not decreasing for
+ * higher temps, and the min and max are also offset from 4096.
+ */
+#define RK3328_DATA_OFFSET (4096)
 static const rk_data_array rk3328_data_array[] = {
-#define ENTRY(d,C)	{ .data = (d), .temp = (C) * 1000 * 1000, }
+#define ENTRY(d,C) \
+	{ .data = RK3328_DATA_OFFSET - (d), .temp = (C) * 1000 * 1000, }
 	ENTRY(TSADC_DATA_MAX,    -40),
 	ENTRY(3800, -40),
 	ENTRY(3792, -35),
@@ -348,34 +352,30 @@ static const rk_data_array rk3399_data_a
 #undef ENTRY
 };
 
-static const rk_data_table rk3328_data_table = {
-	.rdt_array = rk3328_data_array,
-	.rdt_size = __arraycount(rk3328_data_array),
-	.rdt_init = rk_tsadc_init_rk3328,
-	.rdt_decr = true,
-	.rdt_max = 3801,
-	.rdt_min = 3420,
-	.rdt_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME,
+static const rk_data rk3328_data_table = {
+	.rd_array = rk3328_data_array,
+	.rd_size = __arraycount(rk3328_data_array),
+	.rd_init = rk_tsadc_init_rk3328,
+	.rd_decr = false,
+	.rd_max = RK3328_DATA_OFFSET - 3420,
+	.rd_min = RK3328_DATA_OFFSET - 3801,
+	.rd_auto_period = RK3328_TSADC_AUTO_PERIOD_TIME,
+	.rd_num_sensors = 1,
 };
 
-static const rk_data_table rk3399_data_table = {
-	.rdt_array = rk3399_data_array,
-	.rdt_size = __arraycount(rk3399_data_array),
-	.rdt_init = rk_tsadc_init_rk3399,
-	.rdt_decr = false,
-	.rdt_max = 686,
-	.rdt_min = 401,
-	.rdt_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME,
+static const rk_data rk3399_data_table = {
+	.rd_array = rk3399_data_array,
+	.rd_size = __arraycount(rk3399_data_array),
+	.rd_init = rk_tsadc_init_rk3399,
+	.rd_decr = false,
+	.rd_max = 686,
+	.rd_min = 401,
+	.rd_auto_period = RK3399_TSADC_AUTO_PERIOD_TIME,
+	.rd_num_sensors = 2,
 };
 
 static const char * const compatible_rk3328[] = {
-#if 0
-	/*
-	 * does not yet report sane values.  should be between 3421 and 3800,
-	 * but CPU tends to report < 1000 and the GPU reports 600-1600.
-	 */
 	"rockchip,rk3328-tsadc",
-#endif
 	NULL
 };
 
@@ -430,6 +430,13 @@ rk_tsadc_attach(device_t parent, device_
 
 	pmf_device_register(self, NULL, NULL);
 
+	if (of_match_compatible(faa->faa_phandle, compatible_rk3328)) {
+		sc->sc_rd = &rk3328_data_table;
+	} else {
+		KASSERT(of_match_compatible(faa->faa_phandle, compatible_rk3399));
+		sc->sc_rd = &rk3399_data_table;
+	}
+
 	/* Default to tshut via gpio and tshut low is active */
 	if (of_getprop_uint32(phandle, "rockchip,hw-tshut-mode",
 			      &mode) != 0) {
@@ -455,7 +462,7 @@ rk_tsadc_attach(device_t parent, device_
 	tshut_temp *= 1000;	/* convert fdt ms -> us */
 
 	memcpy(sc->sc_sensors, rk_tsadc_sensors, sizeof(sc->sc_sensors));
-	for (unsigned n = 0; n < NUM_SENSORS; n++) {
+	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
 
 		rks->s_data.flags = ENVSYS_FMONLIMITS;
@@ -508,13 +515,6 @@ rk_tsadc_attach(device_t parent, device_
 		return;
 	}
 
-	if (of_match_compatible(faa->faa_phandle, compatible_rk3328)) {
-		sc->sc_rdt = &rk3328_data_table;
-	} else {
-		KASSERT(of_match_compatible(faa->faa_phandle, compatible_rk3399));
-		sc->sc_rdt = &rk3399_data_table;
-	}
-
 	/*
 	 * Manual says to setup auto period (both), high temp (interrupt),
 	 * high temp (shutdown), enable high temp resets (TSHUT to GPIO
@@ -536,7 +536,7 @@ rk_tsadc_detach(device_t self, int flags
 
 	pmf_device_deregister(self);
 
-	for (unsigned n = 0; n < NUM_SENSORS; n++) {
+	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
 
 		if (rks->s_attached) {
@@ -598,8 +598,8 @@ static void
 rk_tsadc_init_counts(struct rk_tsadc_softc *sc)
 {
 
-	TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rdt->rdt_auto_period);
-	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rdt->rdt_auto_period);
+	TSADC_WRITE(sc, TSADC_AUTO_PERIOD, sc->sc_rd->rd_auto_period);
+	TSADC_WRITE(sc, TSADC_AUTO_PERIOD_HT, sc->sc_rd->rd_auto_period);
 	TSADC_WRITE(sc, TSADC_HIGH_INT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
 	TSADC_WRITE(sc, TSADC_HIGH_TSHUT_DEBOUNCE, TSADC_HT_DEBOUNCE_COUNT);
 }
@@ -610,10 +610,15 @@ rk_tsadc_tshut_set(struct rk_tsadc_softc
 {
 	uint32_t val = TSADC_READ(sc, TSADC_AUTO_CON);
 
-	for (unsigned n = 0; n < NUM_SENSORS; n++) {
+	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
-		uint32_t data = rk_tsadc_temp_to_data(sc, rks->s_tshut);
-		uint32_t warndata = rk_tsadc_temp_to_data(sc, rks->s_warn);
+		uint32_t data, warndata;
+
+		if (!rks->s_attached)
+			continue;
+
+		data = rk_tsadc_temp_to_data(sc, rks->s_tshut);
+		warndata = rk_tsadc_temp_to_data(sc, rks->s_warn);
 
 		DPRINTF("(%s:%s): tshut/data %d/%u warn/data %d/%u",
 			sc->sc_sme->sme_name, rks->s_data.desc,
@@ -726,17 +731,18 @@ static void
 rk_tsadc_init(struct rk_tsadc_softc *sc, int mode, int polarity)
 {
 
-	(*sc->sc_rdt->rdt_init)(sc, mode, polarity);
+	(*sc->sc_rd->rd_init)(sc, mode, polarity);
 	rk_tsadc_init_enable(sc);
 }
 
 /* run time support */
 
+/* given edata, find the matching rk sensor structure */
 static struct rk_tsadc_sensor *
 rk_tsadc_edata_to_sensor(struct rk_tsadc_softc * const sc, envsys_data_t *edata)
 {
 
-	for (unsigned n = 0; n < NUM_SENSORS; n++) {
+	for (unsigned n = 0; n < sc->sc_rd->rd_num_sensors; n++) {
 		struct rk_tsadc_sensor *rks = &sc->sc_sensors[n];
 
 		if (&rks->s_data == edata)
@@ -821,23 +827,24 @@ static int
 rk_tsadc_data_to_temp(struct rk_tsadc_softc *sc, uint32_t data)
 {
 	unsigned i;
-	const rk_data_table *rdt = sc->sc_rdt;
+	const rk_data *rd = sc->sc_rd;
 
-	if (data > rdt->rdt_max || data < rdt->rdt_min) {
-		DPRINTF("data out of range (%u > %u || %u < %u)", data, rdt->rdt_max, data, rdt->rdt_min);
+	if (data > rd->rd_max || data < rd->rd_min) {
+		DPRINTF("data out of range (%u > %u || %u < %u)",
+			data, rd->rd_max, data, rd->rd_min);
 		return sc->sc_data_mask;
 	}
-	for (i = 1; i < rdt->rdt_size; i++) {
-		if (rdt->rdt_array[i].data >= data) {
+	for (i = 1; i < rd->rd_size; i++) {
+		if (rd->rd_array[i].data >= data) {
 			int temprange, offset;
 			uint32_t datarange, datadiff;
 			unsigned first, secnd;
 
-			if (rdt->rdt_array[i].data == data)
-				return rdt->rdt_array[i].temp;
+			if (rd->rd_array[i].data == data)
+				return rd->rd_array[i].temp;
 
 			/* must interpolate */
-			if (rdt->rdt_decr) {
+			if (rd->rd_decr) {
 				first = i;
 				secnd = i+1;
 			} else {
@@ -845,14 +852,14 @@ rk_tsadc_data_to_temp(struct rk_tsadc_so
 				secnd = i-1;
 			}
 
-			temprange = rdt->rdt_array[first].temp -
-				    rdt->rdt_array[secnd].temp;
-			datarange = rdt->rdt_array[first].data -
-				    rdt->rdt_array[secnd].data;
-			datadiff = data - rdt->rdt_array[secnd].data;
+			temprange = rd->rd_array[first].temp -
+				    rd->rd_array[secnd].temp;
+			datarange = rd->rd_array[first].data -
+				    rd->rd_array[secnd].data;
+			datadiff = data - rd->rd_array[secnd].data;
 
 			offset = (temprange * datadiff) / datarange;
-			return rdt->rdt_array[secnd].temp + offset;
+			return rd->rd_array[secnd].temp + offset;
 		}
 	}
 	panic("didn't find range");
@@ -862,19 +869,19 @@ static uint32_t
 rk_tsadc_temp_to_data(struct rk_tsadc_softc *sc, int temp)
 {
 	unsigned i;
-	const rk_data_table *rdt = sc->sc_rdt;
+	const rk_data *rd = sc->sc_rd;
 
-	for (i = 1; i < rdt->rdt_size; i++) {
-		if (rdt->rdt_array[i].temp >= temp) {
+	for (i = 1; i < rd->rd_size; i++) {
+		if (rd->rd_array[i].temp >= temp) {
 			int temprange, tempdiff;
 			uint32_t datarange, offset;
 			unsigned first, secnd;
 
-			if (rdt->rdt_array[i].temp == temp)
-				return rdt->rdt_array[i].data;
+			if (rd->rd_array[i].temp == temp)
+				return rd->rd_array[i].data;
 
 			/* must interpolate */
-			if (rdt->rdt_decr) {
+			if (rd->rd_decr) {
 				first = i;
 				secnd = i+1;
 			} else {
@@ -882,14 +889,14 @@ rk_tsadc_temp_to_data(struct rk_tsadc_so
 				secnd = i-1;
 			}
 
-			datarange = rdt->rdt_array[first].data -
-				    rdt->rdt_array[secnd].data;
-			temprange = rdt->rdt_array[first].temp -
-				    rdt->rdt_array[secnd].temp;
-			tempdiff = temp - rdt->rdt_array[secnd].temp;
+			datarange = rd->rd_array[first].data -
+				    rd->rd_array[secnd].data;
+			temprange = rd->rd_array[first].temp -
+				    rd->rd_array[secnd].temp;
+			tempdiff = temp - rd->rd_array[secnd].temp;
 
 			offset = (datarange * tempdiff) / temprange;
-			return rdt->rdt_array[secnd].data + offset;
+			return rd->rd_array[secnd].data + offset;
 		}
 	}
 

Reply via email to