From patchwork Thu Feb 26 11:35:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chanwoo Choi X-Patchwork-Id: 5891191 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8F21FBF440 for ; Thu, 26 Feb 2015 11:39:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6AE4E20394 for ; Thu, 26 Feb 2015 11:39:26 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 33A8D20382 for ; Thu, 26 Feb 2015 11:39:25 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YQwkB-0006L9-SK; Thu, 26 Feb 2015 11:36:40 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YQwjK-0005ec-D0 for linux-arm-kernel@lists.infradead.org; Thu, 26 Feb 2015 11:35:48 +0000 Received: from epcpsbgr4.samsung.com (u144.gpu120.samsung.co.kr [203.254.230.144]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NKD00L3LMUZ6A50@mailout4.samsung.com> for linux-arm-kernel@lists.infradead.org; Thu, 26 Feb 2015 20:35:23 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.114]) by epcpsbgr4.samsung.com (EPCPMTA) with SMTP id AF.07.18167.AF40FE45; Thu, 26 Feb 2015 20:35:22 +0900 (KST) X-AuditID: cbfee690-f79ab6d0000046f7-27-54ef04facf05 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id CC.58.20081.AF40FE45; Thu, 26 Feb 2015 20:35:22 +0900 (KST) Received: from chan.10.32.193.11 ([10.252.81.195]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NKD0015EMUYLDA0@mmp1.samsung.com>; Thu, 26 Feb 2015 20:35:22 +0900 (KST) From: Chanwoo Choi To: rui.zhang@intel.com, edubezval@gmail.com, l.majewski@samsung.com Subject: [PATCH 1/3] thermal: exynos: Add the support for Exynos5433 TMU Date: Thu, 26 Feb 2015 20:35:19 +0900 Message-id: <1424950521-6236-2-git-send-email-cw00.choi@samsung.com> X-Mailer: git-send-email 1.8.5.5 In-reply-to: <1424950521-6236-1-git-send-email-cw00.choi@samsung.com> References: <1424950521-6236-1-git-send-email-cw00.choi@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpikeLIzCtJLcpLzFFi42JZI2JSpPuL5X2IwYlvVhaP1yxmsmi4GmKx ccZ6VovL+7Utrn95zmox/8o1VotJ9yewWPQ/fs1scbbpDbvFm4ebGS02PQZKXN41h83ic+8R RosZ5/cxWTx52MfmwO+xc9Zddo/Fe14yeWxa1cnmsXlJvUffllWMHp83yQWwRXHZpKTmZJal FunbJXBlHO39yVyw3adi8+8GtgbGp/ZdjBwcEgImEg/atbsYOYFMMYkL99azdTFycQgJLGWU mNQxkxkiYSKxs+sjK4gtJLCIUeLNezmIoiYmidXX/zCBJNgEtCT2v7jBBmKLCLhIdF2eBBZn FrjJJLF9jR+ILSzgIXF56mZ2kMUsAqoSB9bVgJi8QOXvX1hArFKQWLZ8JtgqTgFXiT0bX7JD rHWR6JtwixFkrYTAJXaJXYvOsoAkWAQEJL5NPsQC8YusxKYDUCdLShxccYNlAqPwAkaGVYyi qQXJBcVJ6UUmesWJucWleel6yfm5mxiBUXP637MJOxjvHbA+xCjAwajEw5uQ/S5EiDWxrLgy 9xCjKdCGicxSosn5wNjMK4k3NDYzsjA1MTU2Mrc0UxLnfS31M1hIID2xJDU7NbUgtSi+qDQn tfgQIxMHp1QD4xKneXeWtcll/Uj9v/vA4cw/G+4s0jMx5AtlXn/123fxO83cZ1Z7hH3ZYLvq 1Ycvmev+z6o/tl122fyFRjYf9A9OKyoIWH4pqWGTzKkbayZ7Sy0+7HZJ9F/c0rrNYdFHzpwq LhJ9ZyDrvrxj9vJNlyzrvnYy/fn97em81nRzfuOy3BLdeYp83QZKLMUZiYZazEXFiQCXj4+J lQIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrLIsWRmVeSWpSXmKPExsVy+t9jAd1fLO9DDP691LN4vGYxk0XD1RCL jTPWs1pc3q9tcf3Lc1aL+VeusVpMuj+BxaL/8Wtmi7NNb9gt3jzczGix6TFQ4vKuOWwWn3uP MFrMOL+PyeLJwz42B36PnbPusnss3vOSyWPTqk42j81L6j36tqxi9Pi8SS6ALaqB0SYjNTEl tUghNS85PyUzL91WyTs43jne1MzAUNfQ0sJcSSEvMTfVVsnFJ0DXLTMH6GIlhbLEnFKgUEBi cbGSvh2mCaEhbroWMI0Rur4hQXA9RgZoIGENY8bR3p/MBdt9Kjb/bmBrYHxq38XIySEhYCKx s+sjK4QtJnHh3no2EFtIYBGjxJv3cl2MXEB2E5PE6ut/mEASbAJaEvtf3AArEhFwkei6PAks zixwk0li+xo/EFtYwEPi8tTN7F2MHBwsAqoSB9bVgJi8QOXvX1hArFKQWLZ8JthaTgFXiT0b X7JDrHWR6Jtwi3ECI+8CRoZVjKKpBckFxUnpuYZ6xYm5xaV56XrJ+bmbGMFR+UxqB+PKBotD jAIcjEo8vAnZ70KEWBPLiitzDzFKcDArifA+eQ4U4k1JrKxKLcqPLyrNSS0+xGgKdNNEZinR 5HxgwsgriTc0NjEzsjQyN7QwMjZXEudVsm8LERJITyxJzU5NLUgtgulj4uCUamBUn/yETy15 +0e+eI/b6wQq+U9vleJaZZolpvlJ7WDWyun3b9pZ2nAxfE+ZPFdyutTVDqVLJSGh+ltOex1Y JeloqJhSHXHv7UyxDbfmXM/Z89U6pubi16Wx/msTOhImPJtb4+j/xn717NwrVpqpDDPZ7jMX 7IuwN53nz6j9ivt+u9zTq85XmiYpsRRnJBpqMRcVJwIAbnhjNeACAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150226_033546_836975_986822E3 X-CRM114-Status: GOOD ( 20.26 ) X-Spam-Score: -5.0 (-----) Cc: linux-samsung-soc@vger.kernel.org, b.zolnierkie@samsung.com, linux-pm@vger.kernel.org, kyungmin.park@samsung.com, linux-kernel@vger.kernel.org, inki.dae@samsung.com, Chanwoo Choi , amit.daniel@samsung.com, kgene@kernel.org, a.kesavan@samsung.com, chanho61.park@samsung.com, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds the support for Exynos5433's TMU (Thermal Management Unit). Exynos5433 has a little different register bit fields as following description: - Support the eight trip points for rising/falling interrupt by using two registers - Read the calibration type (1-point or 2-point) and sensor id from TRIMINFO register - Use a little different register address Cc: Zhang Rui Cc: Eduardo Valentin Signed-off-by: Chanwoo Choi --- drivers/thermal/samsung/exynos_tmu.c | 161 +++++++++++++++++++++++++++++++++-- drivers/thermal/samsung/exynos_tmu.h | 1 + 2 files changed, 157 insertions(+), 5 deletions(-) diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 1d30b09..1bb2fb7 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -97,6 +97,32 @@ #define EXYNOS4412_MUX_ADDR_VALUE 6 #define EXYNOS4412_MUX_ADDR_SHIFT 20 +/* Exynos5433 specific registers */ +#define EXYNOS5433_TMU_REG_CONTROL1 0x024 +#define EXYNOS5433_TMU_SAMPLING_INTERVAL 0x02c +#define EXYNOS5433_TMU_COUNTER_VALUE0 0x030 +#define EXYNOS5433_TMU_COUNTER_VALUE1 0x034 +#define EXYNOS5433_TMU_REG_CURRENT_TEMP1 0x044 +#define EXYNOS5433_THD_TEMP_RISE3_0 0x050 +#define EXYNOS5433_THD_TEMP_RISE7_4 0x054 +#define EXYNOS5433_THD_TEMP_FALL3_0 0x060 +#define EXYNOS5433_THD_TEMP_FALL7_4 0x064 +#define EXYNOS5433_TMU_REG_INTEN 0x0c0 +#define EXYNOS5433_TMU_REG_INTPEND 0x0c8 +#define EXYNOS5433_TMU_EMUL_CON 0x110 +#define EXYNOS5433_TMU_PD_DET_EN 0x130 + +#define EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT 16 +#define EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT 23 +#define EXYNOS5433_TRIMINFO_SENSOR_ID_MASK \ + (0xf << EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT) +#define EXYNOS5433_TRIMINFO_CALIB_SEL_MASK BIT(23) + +#define EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING 0 +#define EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING 1 + +#define EXYNOS5433_PD_DET_EN 1 + /*exynos5440 specific registers*/ #define EXYNOS5440_TMU_S0_7_TRIM 0x000 #define EXYNOS5440_TMU_S0_7_CTRL 0x020 @@ -484,6 +510,101 @@ out: return ret; } +static int exynos5433_tmu_initialize(struct platform_device *pdev) +{ + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + struct exynos_tmu_platform_data *pdata = data->pdata; + struct thermal_zone_device *tz = data->tzd; + unsigned int status, trim_info; + unsigned int rising_threshold = 0, falling_threshold = 0; + unsigned long temp, temp_hist; + int ret = 0, threshold_code, i, sensor_id, cal_type; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); + if (!status) { + ret = -EBUSY; + goto out; + } + + trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO); + sanitize_temp_error(data, trim_info); + + /* Read the temperature sensor id */ + sensor_id = (trim_info & EXYNOS5433_TRIMINFO_SENSOR_ID_MASK) + >> EXYNOS5433_TRIMINFO_SENSOR_ID_SHIFT; + dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); + + /* Read the calibration mode */ + writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); + cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) + >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; + + switch (cal_type) { + case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING: + pdata->cal_type = TYPE_ONE_POINT_TRIMMING; + break; + case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING: + pdata->cal_type = TYPE_TWO_POINT_TRIMMING; + break; + default: + pdata->cal_type = TYPE_ONE_POINT_TRIMMING; + break; + }; + + dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", + cal_type ? 2 : 1); + + /* Write temperature code for rising and falling threshold */ + for (i = 0; i < of_thermal_get_ntrips(tz); i++) { + int rising_reg_offset, falling_reg_offset; + int j = 0; + + switch (i) { + case 0: + case 1: + case 2: + case 3: + rising_reg_offset = EXYNOS5433_THD_TEMP_RISE3_0; + falling_reg_offset = EXYNOS5433_THD_TEMP_FALL3_0; + j = i; + break; + case 4: + case 5: + case 6: + case 7: + rising_reg_offset = EXYNOS5433_THD_TEMP_RISE7_4; + falling_reg_offset = EXYNOS5433_THD_TEMP_FALL7_4; + j = i - 4; + break; + default: + continue; + } + + /* Write temperature code for rising threshold */ + tz->ops->get_trip_temp(tz, i, &temp); + temp /= MCELSIUS; + threshold_code = temp_to_code(data, temp); + + rising_threshold = readl(data->base + rising_reg_offset); + rising_threshold |= (threshold_code << j * 8); + writel(rising_threshold, data->base + rising_reg_offset); + + /* Write temperature code for falling threshold */ + tz->ops->get_trip_hyst(tz, i, &temp_hist); + temp_hist = temp - (temp_hist / MCELSIUS); + threshold_code = temp_to_code(data, temp_hist); + + falling_threshold = readl(data->base + falling_reg_offset); + falling_threshold &= ~(0xff << j * 8); + falling_threshold |= (threshold_code << j * 8); + writel(falling_threshold, data->base + falling_reg_offset); + } + + data->tmu_clear_irqs(data); +out: + return ret; +} + static int exynos5440_tmu_initialize(struct platform_device *pdev) { struct exynos_tmu_data *data = platform_get_drvdata(pdev); @@ -682,7 +803,8 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) if (on) { con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT); - con |= (1 << EXYNOS7_PD_DET_EN_SHIFT); + if (data->soc == SOC_ARCH_EXYNOS7) + con |= (1 << EXYNOS7_PD_DET_EN_SHIFT); interrupt_en = (of_thermal_is_trip_valid(tz, 7) << EXYNOS7_TMU_INTEN_RISE7_SHIFT) | @@ -705,11 +827,20 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT; } else { con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT); - con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT); + if (data->soc == SOC_ARCH_EXYNOS7) + con &= ~(1 << EXYNOS7_PD_DET_EN_SHIFT); interrupt_en = 0; /* Disable all interrupts */ } - writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); + if (data->soc == SOC_ARCH_EXYNOS5433) { + int pd_det_en = on ? EXYNOS5433_PD_DET_EN : 0; + + writel(pd_det_en, data->base + EXYNOS5433_TMU_PD_DET_EN); + writel(interrupt_en, data->base + EXYNOS5433_TMU_REG_INTEN); + } else { + writel(interrupt_en, data->base + EXYNOS7_TMU_REG_INTEN); + } + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); } @@ -770,6 +901,8 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, if (data->soc == SOC_ARCH_EXYNOS5260) emul_con = EXYNOS5260_EMUL_CON; + if (data->soc == SOC_ARCH_EXYNOS5433) + emul_con = EXYNOS5433_TMU_EMUL_CON; else if (data->soc == SOC_ARCH_EXYNOS7) emul_con = EXYNOS7_TMU_REG_EMUL_CON; else @@ -882,6 +1015,9 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data) } else if (data->soc == SOC_ARCH_EXYNOS7) { tmu_intstat = EXYNOS7_TMU_REG_INTPEND; tmu_intclear = EXYNOS7_TMU_REG_INTPEND; + } else if (data->soc == SOC_ARCH_EXYNOS5433) { + tmu_intstat = EXYNOS5433_TMU_REG_INTPEND; + tmu_intclear = EXYNOS5433_TMU_REG_INTPEND; } else { tmu_intstat = EXYNOS_TMU_REG_INTSTAT; tmu_intclear = EXYNOS_TMU_REG_INTCLEAR; @@ -926,6 +1062,7 @@ static const struct of_device_id exynos_tmu_match[] = { { .compatible = "samsung,exynos5260-tmu", }, { .compatible = "samsung,exynos5420-tmu", }, { .compatible = "samsung,exynos5420-tmu-ext-triminfo", }, + { .compatible = "samsung,exynos5433-tmu", }, { .compatible = "samsung,exynos5440-tmu", }, { .compatible = "samsung,exynos7-tmu", }, { /* sentinel */ }, @@ -949,6 +1086,8 @@ static int exynos_of_get_soc_type(struct device_node *np) else if (of_device_is_compatible(np, "samsung,exynos5420-tmu-ext-triminfo")) return SOC_ARCH_EXYNOS5420_TRIMINFO; + else if (of_device_is_compatible(np, "samsung,exynos5433-tmu")) + return SOC_ARCH_EXYNOS5433; else if (of_device_is_compatible(np, "samsung,exynos5440-tmu")) return SOC_ARCH_EXYNOS5440; else if (of_device_is_compatible(np, "samsung,exynos7-tmu")) @@ -1069,6 +1208,13 @@ static int exynos_map_dt_data(struct platform_device *pdev) data->tmu_set_emulation = exynos4412_tmu_set_emulation; data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; break; + case SOC_ARCH_EXYNOS5433: + data->tmu_initialize = exynos5433_tmu_initialize; + data->tmu_control = exynos7_tmu_control; + data->tmu_read = exynos4412_tmu_read; + data->tmu_set_emulation = exynos4412_tmu_set_emulation; + data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; + break; case SOC_ARCH_EXYNOS5440: data->tmu_initialize = exynos5440_tmu_initialize; data->tmu_control = exynos5440_tmu_control; @@ -1172,7 +1318,9 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk_sec; } - if (data->soc == SOC_ARCH_EXYNOS7) { + switch (data->soc) { + case SOC_ARCH_EXYNOS5433: + case SOC_ARCH_EXYNOS7: data->sclk = devm_clk_get(&pdev->dev, "tmu_sclk"); if (IS_ERR(data->sclk)) { dev_err(&pdev->dev, "Failed to get sclk\n"); @@ -1184,7 +1332,10 @@ static int exynos_tmu_probe(struct platform_device *pdev) goto err_clk; } } - } + break; + default: + break; + }; ret = exynos_tmu_initialize(pdev); if (ret) { diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 4d71ec6..440c714 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -33,6 +33,7 @@ enum soc_type { SOC_ARCH_EXYNOS5260, SOC_ARCH_EXYNOS5420, SOC_ARCH_EXYNOS5420_TRIMINFO, + SOC_ARCH_EXYNOS5433, SOC_ARCH_EXYNOS5440, SOC_ARCH_EXYNOS7, };