From patchwork Fri Sep 22 09:42:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tao Wang X-Patchwork-Id: 9965715 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0BC7F6057C for ; Fri, 22 Sep 2017 09:52:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 09A4E2982C for ; Fri, 22 Sep 2017 09:52:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F2AB92983C; Fri, 22 Sep 2017 09:52:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3A05D2982C for ; Fri, 22 Sep 2017 09:52:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=FrsYz4YcQ8ROGL1sr9G8MbwiNfPTUe6G59jiGIQtYMM=; b=qS4HzpIbuz/KkwUyWmrR4TpLW O+v0GOZ5/tH4huBp53LYgrmgYqEVaUinU5Ng4nQr7cEcYTubUlOkoGaLk2cECQjM7n+YI33WwoejV KpLcXgi9mmIVpT/98d0Plb3ax0iH10tdCf80vz8cF4CG3bLqiJMlbs/nRPjsp8wfwnRu6E9HoLNTb F5HU2WIZkjrr8qVbpg1UxaaIKYZVucBJ+g4E+ovg1JaGinXNJlXMrwB7UDSG3jyUBi2fSC2m8REGW 70F/igkJpci2BBmiWsu85S4U2nz30RW6w+eXiPOK8KhdfubH+9Tu/xaHFgxXwe13+ffgLdw58RTkg ogvs3PHGg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dvKdG-0007Kf-Jf; Fri, 22 Sep 2017 09:52:26 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dvKat-0004Xe-M5 for linux-arm-kernel@lists.infradead.org; Fri, 22 Sep 2017 09:50:09 +0000 Received: from 172.30.72.58 (EHLO DGGEMS403-HUB.china.huawei.com) ([172.30.72.58]) by dggrg05-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DHV05247; Fri, 22 Sep 2017 17:49:26 +0800 (CST) Received: from HSH1000038028.huawei.com (10.177.161.152) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.301.0; Fri, 22 Sep 2017 17:49:19 +0800 From: Tao Wang To: , , , , , , Subject: [PATCH 8/9] thermal/drivers/hisi: add support for hi3660 SoC Date: Fri, 22 Sep 2017 17:42:11 +0800 Message-ID: <1506073332-92438-9-git-send-email-kevin.wangtao@hisilicon.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1506073332-92438-1-git-send-email-kevin.wangtao@hisilicon.com> References: <1506073332-92438-1-git-send-email-kevin.wangtao@hisilicon.com> MIME-Version: 1.0 X-Originating-IP: [10.177.161.152] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020204.59C4DCA6.0053, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 9995eded797108bb925d6158a11cf4f0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170922_025000_473972_E34F4B0F X-CRM114-Status: GOOD ( 14.97 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, vincent.guittot@linaro.org, gengyanping@hisilicon.com, linux-pm@vger.kernel.org, daniel.lezcano@linaro.org, lonela.Voinescu@arm.com, linux-kernel@vger.kernel.org, Kevin Wangtao , leo.yan@linaro.org, sunzhaosheng@hisilicon.com, Valentin.Schneider@arm.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kevin Wangtao This patch adds the support for thermal sensor of Hi3660 SoC. Hi3660 tsensor support alarm interrupt and have three configurable alarm thresholds, it also has a configurable hysteresis interval, interrupt will be triggered when temperature rise above the alarm threshold or fall below the hysteresis threshold. Signed-off-by: Kevin Wangtao --- drivers/thermal/hisi_thermal.c | 146 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 718376b..133238a 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -39,12 +39,24 @@ #define HI6220_TEMP0_RST_MSK (0x1C) #define HI6220_TEMP0_VALUE (0x28) +#define HI3660_OFFSET(chan) ((chan) * 0x40) +#define HI3660_TEMP(chan) (HI3660_OFFSET(chan) + 0x1C) +#define HI3660_TH(chan) (HI3660_OFFSET(chan) + 0x20) +#define HI3660_LAG(chan) (HI3660_OFFSET(chan) + 0x28) +#define HI3660_INT_EN(chan) (HI3660_OFFSET(chan) + 0x2C) +#define HI3660_INT_CLR(chan) (HI3660_OFFSET(chan) + 0x30) + #define HI6220_TEMP_BASE (-60000) #define HI6220_TEMP_RESET (100000) #define HI6220_TEMP_STEP (785) #define HI6220_TEMP_LAG (3500) +#define HI3660_TEMP_BASE (-63780) +#define HI3660_TEMP_STEP (205) +#define HI3660_TEMP_LAG (4000) + #define HI6220_DEFAULT_SENSOR 2 +#define HI3660_DEFAULT_SENSOR 1 #define MAX_THRES_NUM 2 @@ -96,6 +108,24 @@ static inline int hi6220_thermal_temp_to_step(int temp) } /* + * for Hi3660, + * Step: 189/922 (0.205) + * Temperature base: -63.780°C + * + * The register is programmed in temperature steps, every step is 205 + * millidegree and begins at -63 780 m°C + */ +static inline int hi3660_thermal_step_to_temp(int step) +{ + return HI3660_TEMP_BASE + step * HI3660_TEMP_STEP; +} + +static inline int hi3660_thermal_temp_to_step(int temp) +{ + return DIV_ROUND_UP(temp - HI3660_TEMP_BASE, HI3660_TEMP_STEP); +} + +/* * The lag register contains 5 bits encoding the temperature in steps. * * Each time the temperature crosses the threshold boundary, an @@ -169,6 +199,45 @@ static inline int hi6220_thermal_get_temperature(void __iomem *addr) } /* + * [0:6] lag register + * + * The temperature is coded in steps, cf. HI3660_TEMP_STEP. + * + * Min : 0x00 : 0.0 °C + * Max : 0x7F : 26.0 °C + * + */ +static inline void hi3660_thermal_set_lag(void __iomem *addr, + int id, int value) +{ + writel(DIV_ROUND_UP(value, HI3660_TEMP_STEP) & 0x7F, + addr + HI3660_LAG(id)); +} + +static inline void hi3660_thermal_alarm_clear(void __iomem *addr, + int id, int value) +{ + writel(value, addr + HI3660_INT_CLR(id)); +} + +static inline void hi3660_thermal_alarm_enable(void __iomem *addr, + int id, int value) +{ + writel(value, addr + HI3660_INT_EN(id)); +} + +static inline void hi3660_thermal_alarm_set(void __iomem *addr, + int id, int value) +{ + writel(value, addr + HI3660_TH(id)); +} + +static inline int hi3660_thermal_get_temperature(void __iomem *addr, int id) +{ + return hi3660_thermal_step_to_temp(readl(addr + HI3660_TEMP(id))); +} + +/* * Temperature configuration register - Sensor selection * * Bits [19:12] @@ -206,11 +275,22 @@ static int hi6220_thermal_irq_handler(struct hisi_thermal_data *data) return 0; } +static int hi3660_thermal_irq_handler(struct hisi_thermal_data *data) +{ + hi3660_thermal_alarm_clear(data->regs, data->sensor.id, 1); + return 0; +} + static int hi6220_thermal_get_temp(struct hisi_thermal_data *data) { return hi6220_thermal_get_temperature(data->regs); } +static int hi3660_thermal_get_temp(struct hisi_thermal_data *data) +{ + return hi3660_thermal_get_temperature(data->regs, data->sensor.id); +} + static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) { /* disable sensor module */ @@ -222,6 +302,13 @@ static int hi6220_thermal_disable_sensor(struct hisi_thermal_data *data) return 0; } +static int hi3660_thermal_disable_sensor(struct hisi_thermal_data *data) +{ + /* disable sensor module */ + hi3660_thermal_alarm_enable(data->regs, data->sensor.id, 0); + return 0; +} + static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) { struct hisi_thermal_sensor *sensor = &data->sensor; @@ -260,6 +347,29 @@ static int hi6220_thermal_enable_sensor(struct hisi_thermal_data *data) return 0; } +static int hi3660_thermal_enable_sensor(struct hisi_thermal_data *data) +{ + unsigned int value; + struct hisi_thermal_sensor *sensor = &data->sensor; + + /* disable interrupt */ + hi3660_thermal_alarm_enable(data->regs, sensor->id, 0); + + /* setting lag value between current temp and the threshold */ + hi3660_thermal_set_lag(data->regs, sensor->id, HI3660_TEMP_LAG); + + /* set interrupt threshold */ + value = hi3660_thermal_temp_to_step(sensor->thres_temp[0]); + value |= hi3660_thermal_temp_to_step(sensor->thres_temp[1]) << 10; + hi3660_thermal_alarm_set(data->regs, sensor->id, value); + + /* enable interrupt */ + hi3660_thermal_alarm_clear(data->regs, sensor->id, 1); + hi3660_thermal_alarm_enable(data->regs, sensor->id, 1); + + return 0; +} + static int hi6220_thermal_probe(struct hisi_thermal_data *data) { struct platform_device *pdev = data->pdev; @@ -296,6 +406,33 @@ static int hi6220_thermal_probe(struct hisi_thermal_data *data) return 0; } +static int hi3660_thermal_probe(struct hisi_thermal_data *data) +{ + struct platform_device *pdev = data->pdev; + struct device *dev = &pdev->dev; + struct resource *res; + + data->get_temp = hi3660_thermal_get_temp; + data->enable_sensor = hi3660_thermal_enable_sensor; + data->disable_sensor = hi3660_thermal_disable_sensor; + data->irq_handler = hi3660_thermal_irq_handler; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(data->regs)) { + dev_err(dev, "failed to get io address\n"); + return PTR_ERR(data->regs); + } + + data->irq = platform_get_irq(pdev, 0); + if (data->irq < 0) + return data->irq; + + data->sensor.id = HI3660_DEFAULT_SENSOR; + + return 0; +} + static int hisi_thermal_get_temp(void *__data, int *temp) { @@ -371,7 +508,14 @@ static int hisi_thermal_register_sensor(struct platform_device *pdev, } static const struct of_device_id of_hisi_thermal_match[] = { - { .compatible = "hisilicon,tsensor", .data = hi6220_thermal_probe }, + { + .compatible = "hisilicon,tsensor", + .data = hi6220_thermal_probe + }, + { + .compatible = "hisilicon,hi3660-tsensor", + .data = hi3660_thermal_probe + }, { /* end */ } }; MODULE_DEVICE_TABLE(of, of_hisi_thermal_match);