[coreboot-gerrit] New patch to review for coreboot: rockchip: rk3399: add tsadc driver

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Wed May 11 22:27:36 CEST 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14784

-gerrit

commit 88784805e5a785851f33f8f31ddc876bdf34ad5a
Author: Shunqian Zheng <zhengsq at rock-chips.com>
Date:   Fri May 6 16:50:48 2016 +0800

    rockchip: rk3399: add tsadc driver
    
    This patch configures clock for tsadc and then
    makes it in automatic mode to generate TSHUT when
    CPU temperature is higer than 120 degree Celsius.
    
    BRANCH=none
    BUG=chrome-os-partner:52382,chrome-os-partner:51537
    TEST=Set a lower tshut threshold(45C), run coreboot and check
         that coreboot reboot again and again.
    
    Change-Id: I30b530c6e34f1dce85f6bbc2d81c30532b1f6638
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 05107bd6a3430e31db216c247ff0213e12373390
    Original-Change-Id: Iffe54d3b09080d0f1ff31e8b3020d69510f07c95
    Original-Signed-off-by: Lin Huang <hl at rock-chips.com>
    Original-Signed-off-by: Shunqian Zheng <zhengsq at rock-chips.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/342797
    Original-Tested-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-by: Shelley Chen <shchen at chromium.org>
---
 src/soc/rockchip/rk3399/Makefile.inc        |   1 +
 src/soc/rockchip/rk3399/clock.c             |  22 +++++
 src/soc/rockchip/rk3399/include/soc/clock.h |   1 +
 src/soc/rockchip/rk3399/include/soc/tsadc.h |  26 ++++++
 src/soc/rockchip/rk3399/romstage.c          |   2 +
 src/soc/rockchip/rk3399/tsadc.c             | 139 ++++++++++++++++++++++++++++
 6 files changed, 191 insertions(+)

diff --git a/src/soc/rockchip/rk3399/Makefile.inc b/src/soc/rockchip/rk3399/Makefile.inc
index 4d5091d..9af451c 100644
--- a/src/soc/rockchip/rk3399/Makefile.inc
+++ b/src/soc/rockchip/rk3399/Makefile.inc
@@ -46,6 +46,7 @@ romstage-y += mmu_operations.c
 romstage-y += ../common/pwm.c
 romstage-y += timer.c
 romstage-y += romstage.c
+romstage-y += tsadc.c
 
 ################################################################################
 
diff --git a/src/soc/rockchip/rk3399/clock.c b/src/soc/rockchip/rk3399/clock.c
index 46c7a39..53c6e30 100644
--- a/src/soc/rockchip/rk3399/clock.c
+++ b/src/soc/rockchip/rk3399/clock.c
@@ -159,6 +159,13 @@ enum {
 	CLK_SARADC_DIV_CON_MASK		= 0xff,
 	CLK_SARADC_DIV_CON_SHIFT	= 8,
 
+	/* CLKSEL_CON27 */
+	CLK_TSADC_SEL_X24M		= 0x0,
+	CLK_TSADC_SEL_MASK		= 1,
+	CLK_TSADC_SEL_SHIFT		= 15,
+	CLK_TSADC_DIV_CON_MASK		= 0x3ff,
+	CLK_TSADC_DIV_CON_SHIFT		= 0,
+
 	/* CLKSEL_CON47 & CLKSEL_CON48 */
 	ACLK_VOP_PLL_SEL_MASK		= 0x3,
 	ACLK_VOP_PLL_SEL_SHIFT		= 6,
@@ -714,3 +721,18 @@ int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz)
 
 	return 0;
 }
+
+void rkclk_configure_tsadc(unsigned int hz)
+{
+	int src_clk_div;
+
+	/* use 24M as src clock */
+	src_clk_div = OSC_HZ / hz;
+	assert((src_clk_div - 1 < 1024) && (src_clk_div * hz == OSC_HZ));
+
+	write32(&cru_ptr->clksel_con[27], RK_CLRSETBITS(
+			CLK_TSADC_DIV_CON_MASK << CLK_TSADC_DIV_CON_SHIFT |
+			CLK_TSADC_SEL_MASK << CLK_TSADC_SEL_SHIFT,
+			src_clk_div << CLK_TSADC_DIV_CON_SHIFT |
+			CLK_TSADC_SEL_X24M << CLK_TSADC_SEL_SHIFT));
+}
diff --git a/src/soc/rockchip/rk3399/include/soc/clock.h b/src/soc/rockchip/rk3399/include/soc/clock.h
index 65e2e74..3b60d54 100644
--- a/src/soc/rockchip/rk3399/include/soc/clock.h
+++ b/src/soc/rockchip/rk3399/include/soc/clock.h
@@ -108,6 +108,7 @@ void rkclk_configure_cpu(enum apll_l_frequencies apll_l_freq);
 void rkclk_configure_ddr(unsigned int hz);
 void rkclk_configure_saradc(unsigned int hz);
 void rkclk_configure_spi(unsigned int bus, unsigned int hz);
+void rkclk_configure_tsadc(unsigned int hz);
 void rkclk_configure_vop_aclk(u32 vop_id, u32 aclk_hz);
 void rkclk_ddr_reset(u32 ch, u32 ctl, u32 phy);
 uint32_t rkclk_i2c_clock_for_bus(unsigned bus);
diff --git a/src/soc/rockchip/rk3399/include/soc/tsadc.h b/src/soc/rockchip/rk3399/include/soc/tsadc.h
new file mode 100644
index 0000000..b1f617d
--- /dev/null
+++ b/src/soc/rockchip/rk3399/include/soc/tsadc.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SOC_ROCKCHIP_RK3399_TSADC_H__
+#define __SOC_ROCKCHIP_RK3399_TSADC_H__
+
+enum {
+	TSHUT_POL_HIGH = 1 << 8,
+	TSHUT_POL_LOW = 0 << 8
+};
+
+void tsadc_init(uint32_t polarity);
+
+#endif
diff --git a/src/soc/rockchip/rk3399/romstage.c b/src/soc/rockchip/rk3399/romstage.c
index f22b8c9..ae0264e 100644
--- a/src/soc/rockchip/rk3399/romstage.c
+++ b/src/soc/rockchip/rk3399/romstage.c
@@ -28,6 +28,7 @@
 #include <soc/grf.h>
 #include <soc/mmu_operations.h>
 #include <soc/pwm.h>
+#include <soc/tsadc.h>
 #include <soc/sdram.h>
 #include <symbols.h>
 
@@ -74,6 +75,7 @@ static void init_dvs_outputs(void)
 void main(void)
 {
 	console_init();
+	tsadc_init(TSHUT_POL_HIGH);
 	exception_init();
 
 	/* Init DVS to conservative values. */
diff --git a/src/soc/rockchip/rk3399/tsadc.c b/src/soc/rockchip/rk3399/tsadc.c
new file mode 100644
index 0000000..234cd23
--- /dev/null
+++ b/src/soc/rockchip/rk3399/tsadc.c
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Rockchip Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <assert.h>
+#include <console/console.h>
+#include <delay.h>
+#include <soc/clock.h>
+#include <soc/grf.h>
+#include <soc/tsadc.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+struct rk3399_tsadc_regs {
+	u32	user_con;
+	u32	auto_con;
+	u32	int_en;
+	u32	int_pd;
+	u32	reserved0[(0x20 - 0x10) / 4];
+	u32	data0;
+	u32	data1;
+	u32	data2;
+	u32	data3;
+	u32	comp0_int;
+	u32	comp1_int;
+	u32	comp2_int;
+	u32	comp3_int;
+	u32	comp0_shut;
+	u32	comp1_shut;
+	u32	comp2_shut;
+	u32	comp3_shut;
+	u32	reserved1[(0x60 - 0x50) / 4];
+	u32	hight_int_debounce;
+	u32	hight_tshut_debounce;
+	u32	auto_period;
+	u32	auto_period_ht;
+};
+check_member(rk3399_tsadc_regs, auto_period_ht, 0x6c);
+
+/* user_con */
+#define ADC_POWER_CTRL	(1 << 3)
+#define START_MODE	(1 << 4)
+#define START_SHIFT	5
+#define START_MASK	1
+#define INTER_PD_SHIFT	6
+#define INTER_PD_MASK	0x3f
+
+/* auto_con */
+#define LAST_TSHUT	(1 << 24)
+#define SRC3_EN		(1 << 7)
+#define SRC2_EN		(1 << 6)
+#define SRC1_EN		(1 << 5)
+#define SRC0_EN		(1 << 4)
+#define Q_SEL		(1 << 1)
+#define AUTO_EN		(1 << 0)
+
+/* int_en */
+#define TSHUT_CRU_EN_SRC3	(1 << 11)
+#define TSHUT_CRU_EN_SRC2	(1 << 10)
+#define TSHUT_CRU_EN_SRC1	(1 << 9)
+#define TSHUT_CRU_EN_SRC0	(1 << 8)
+#define TSHUT_GPIO_EN_SRC3	(1 << 7)
+#define TSHUT_GPIO_EN_SRC2	(1 << 6)
+#define TSHUT_GPIO_EN_SRC1	(1 << 5)
+#define TSHUT_GPIO_EN_SRC0	(1 << 4)
+
+#define AUTO_PERIOD		187500 /* 250ms */
+#define AUTO_DEBOUNCE		4
+#define AUTO_PERIOD_HT		37500 /* 50ms */
+#define AUTO_DEBOUNCE_HT	4
+#define TSADC_CLOCK_HZ		(750 * KHz)
+
+/* AD value, correspond to 120 degrees Celsius,
+ * Please refer shut value table in:
+ * https://patchwork.kernel.org/patch/8908411/
+ * A quick ref:
+ * {573, 60000}, {599, 75000}, {616, 85000}, {633, 95000},
+ * {642, 100000}, {659, 110000}, {677, 120000}, {685, 125000}
+ */
+#define TSADC_SHUT_VALUE	677
+
+#define GRF_TSADC_TSEN_PD0_ON	RK_SETBITS(0)
+#define GRF_TSADC_TSEN_PD0_OFF	RK_CLRBITS(0)
+#define GRF_SARADC_TSEN_ON	RK_SETBITS(0)
+
+struct rk3399_tsadc_regs *rk3399_tsadc = (void *)TSADC_BASE;
+
+void tsadc_init(uint32_t polarity)
+{
+	rkclk_configure_tsadc(TSADC_CLOCK_HZ);
+
+	/* tsadc power sequence */
+	clrbits_le32(&rk3399_tsadc->user_con, ADC_POWER_CTRL);
+	write32(&rk3399_grf->tsadc_testbit_l, GRF_TSADC_TSEN_PD0_ON);
+	udelay(50);
+	write32(&rk3399_grf->tsadc_testbit_l, GRF_TSADC_TSEN_PD0_OFF);
+	udelay(20);
+	write32(&rk3399_grf->saradc_testbit, GRF_SARADC_TSEN_ON);
+	udelay(100);
+
+	/* set the tshut polarity */
+	write32(&rk3399_tsadc->auto_con, polarity);
+
+	/* setup the automatic mode:
+	 * AUTO_PERIOD: interleave between every two accessing of TSADC
+	 * AUTO_DEBOUNCE: only generate interrupt or TSHUT when temprature
+	 *                is higher than COMP_INT for "debounce" times
+	 * AUTO_PERIOD_HT: the interleave between every two accessing after the
+	 *                 temperature is higher than COMP_SHUT or COMP_INT
+	 * AUTO_DEBOUNCE_HT: only generate interrupt or TSHUT when temperature
+	 *                   is higher than COMP_SHUT for "debounce" times.
+	 */
+	write32(&rk3399_tsadc->auto_period, AUTO_PERIOD);
+	write32(&rk3399_tsadc->hight_int_debounce, AUTO_DEBOUNCE);
+	write32(&rk3399_tsadc->auto_period_ht, AUTO_PERIOD_HT);
+	write32(&rk3399_tsadc->hight_tshut_debounce, AUTO_DEBOUNCE_HT);
+	/* Enable the src0, negative temprature coefficient */
+	setbits_le32(&rk3399_tsadc->auto_con, Q_SEL | SRC0_EN);
+	udelay(100);
+	setbits_le32(&rk3399_tsadc->auto_con, AUTO_EN);
+
+	write32(&rk3399_tsadc->comp0_shut, TSADC_SHUT_VALUE);
+	write32(&rk3399_tsadc->int_en, TSHUT_CRU_EN_SRC0 | TSHUT_GPIO_EN_SRC0);
+
+	/* Set the tsadc_int pinmux */
+	write32(&rk3399_pmugrf->tsadc_int, IOMUX_TSADC_INT);
+}



More information about the coreboot-gerrit mailing list