From patchwork Sun May 5 13:23:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 1095429 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nxp.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=nxp.com header.i=@nxp.com header.b="ue6RBU3r"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44xmmt2SX6z9s3l for ; Sun, 5 May 2019 23:24:30 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id D2EA3C21CB1; Sun, 5 May 2019 13:24:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=SPF_HELO_PASS, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 42498C21E29; Sun, 5 May 2019 13:24:06 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6043DC21C38; Sun, 5 May 2019 13:23:59 +0000 (UTC) Received: from EUR02-VE1-obe.outbound.protection.outlook.com (mail-eopbgr20051.outbound.protection.outlook.com [40.107.2.51]) by lists.denx.de (Postfix) with ESMTPS id 487EFC21CB1 for ; Sun, 5 May 2019 13:23:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=S3Hiy7nZJPhlOh+ToxM+Um1EElQRi2Ct0/ICUayVBgY=; b=ue6RBU3rS+vN0ouvt5a28PuYagQbl4UOYskVMiK233ih/DeZxAFy7oNWmidgc7/Dg7tCE0STk9EGwox7rRV2hyxZuORs0nLdxoSidjO0L6EPvoMmgP2GdOh39iODo5sH9UFvN7KqFZDTxYj5ohGrtozOj0UWKEfOZR7PhTld/5s= Received: from AM0PR04MB4481.eurprd04.prod.outlook.com (52.135.147.15) by AM0PR04MB3970.eurprd04.prod.outlook.com (52.134.92.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1856.10; Sun, 5 May 2019 13:23:55 +0000 Received: from AM0PR04MB4481.eurprd04.prod.outlook.com ([fe80::3173:24:d401:2378]) by AM0PR04MB4481.eurprd04.prod.outlook.com ([fe80::3173:24:d401:2378%6]) with mapi id 15.20.1856.012; Sun, 5 May 2019 13:23:55 +0000 From: Peng Fan To: "sbabic@denx.de" , "festevam@gmail.com" Thread-Topic: [PATCH V2 2/4] thermal: add i.MX8 thermal driver Thread-Index: AQHVA0XJJIgzg5u7ZU+sd30mqk7+ww== Date: Sun, 5 May 2019 13:23:54 +0000 Message-ID: <20190505133713.27561-2-peng.fan@nxp.com> References: <20190505133713.27561-1-peng.fan@nxp.com> In-Reply-To: <20190505133713.27561-1-peng.fan@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 2.16.4 x-clientproxiedby: HK2PR04CA0073.apcprd04.prod.outlook.com (2603:1096:202:15::17) To AM0PR04MB4481.eurprd04.prod.outlook.com (2603:10a6:208:70::15) authentication-results: spf=none (sender IP is ) smtp.mailfrom=peng.fan@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [119.31.174.71] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1d8f0483-c049-4ec4-ccaa-08d6d15cec11 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600141)(711020)(4605104)(4618075)(2017052603328)(7193020); SRVR:AM0PR04MB3970; x-ms-traffictypediagnostic: AM0PR04MB3970: x-ld-processed: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635,ExtAddr x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:386; x-forefront-prvs: 00286C0CA6 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(136003)(396003)(376002)(189003)(199004)(66556008)(66476007)(66946007)(73956011)(25786009)(64756008)(66446008)(6512007)(6506007)(5660300002)(81166006)(81156014)(14454004)(386003)(66066001)(102836004)(6486002)(44832011)(2501003)(8936002)(316002)(71190400001)(86362001)(71200400001)(36756003)(486006)(6436002)(476003)(53936002)(2906002)(3846002)(14444005)(256004)(6116002)(446003)(11346002)(1076003)(52116002)(2616005)(305945005)(26005)(4326008)(186003)(478600001)(76176011)(8676002)(50226002)(99286004)(54906003)(110136005)(68736007)(7736002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR04MB3970; H:AM0PR04MB4481.eurprd04.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: YxNQIr6Mz3zsRB50yK8rqGKdzaxX5r82IpiKwVymcSNV7g3PYASItFdwP+jKZGpHnPeYItTYC8L+v/7T93xes/EexzmGv+hMGrXzlOe0S5M0xBKifNKN3D1PyLFIXnlQKjCcw4HXWDplvXCyexy8BpQcMuNESeKvYmWePktjxbbqXLfM0xNnDfcgr4fec6ztEe0ytfg+SLHHNPCwwfm3AcuemO+TGBC77eND46P5FcPoVye3nVYjRswcipoPFA/DCEgk3Vhi76I5JpKN/xRI3uuTl8fGWPQjRcOG3bsKaq4mS9uFPUfzH66T290sxgsBe5ErroY0sE5/oX2EdelN1RQkrocrP/zY1+Js5M2afoYc4kOXXpIEv46pgiRya3PFiveOft+/w0mYaP+TbJqbALrf4ZUDS0fjad9neAs/5Hg= MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1d8f0483-c049-4ec4-ccaa-08d6d15cec11 X-MS-Exchange-CrossTenant-originalarrivaltime: 05 May 2019 13:23:55.0617 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR04MB3970 Cc: "igor.opaniuk@toradex.com" , Marcel Ziswiler , "u-boot@lists.denx.de" , dl-uboot-imx Subject: [U-Boot] [PATCH V2 2/4] thermal: add i.MX8 thermal driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add i.MX8 thermal driver to support get temperature from SCU. Signed-off-by: Peng Fan --- V2: None drivers/thermal/Kconfig | 9 ++ drivers/thermal/Makefile | 1 + drivers/thermal/imx_scu_thermal.c | 203 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 drivers/thermal/imx_scu_thermal.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index a71b9be5fb..bdf8dc6fef 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -17,6 +17,15 @@ config IMX_THERMAL cpufreq is used as the cooling device to throttle CPUs when the passive trip is crossed. +config IMX_SCU_THERMAL + bool "Temperature sensor driver for NXP i.MX8" + depends on ARCH_IMX8 + help + Support for Temperature sensors on NXP i.MX8. + It supports one critical trip point and one passive trip point. The + boot is hold to the cool device to throttle CPUs when the passive + trip is crossed + config TI_DRA7_THERMAL bool "Temperature sensor driver for TI dra7xx SOCs" help diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index cc75e387e4..ef2929d180 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_DM_THERMAL) += thermal-uclass.o obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o +obj-$(CONFIG_IMX_SCU_THERMAL) += imx_scu_thermal.o obj-$(CONFIG_TI_DRA7_THERMAL) += ti-bandgap.o diff --git a/drivers/thermal/imx_scu_thermal.c b/drivers/thermal/imx_scu_thermal.c new file mode 100644 index 0000000000..7e17377b69 --- /dev/null +++ b/drivers/thermal/imx_scu_thermal.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct imx_sc_thermal_plat { + int critical; + int alert; + int polling_delay; + int id; + bool zone_node; +}; + +static int read_temperature(struct udevice *dev, int *temp) +{ + s16 celsius; + s8 tenths; + int ret; + + sc_rsrc_t *sensor_rsrc = (sc_rsrc_t *)dev_get_driver_data(dev); + + struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev); + + if (!temp) + return -EINVAL; + + ret = sc_misc_get_temp(-1, sensor_rsrc[pdata->id], SC_C_TEMP, + &celsius, &tenths); + if (ret) { + printf("Error: get temperature failed! (error = %d)\n", ret); + return ret; + } + + *temp = celsius * 1000 + tenths * 100; + + return 0; +} + +int imx_sc_thermal_get_temp(struct udevice *dev, int *temp) +{ + struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev); + int cpu_temp = 0; + int ret; + + ret = read_temperature(dev, &cpu_temp); + if (ret) + return ret; + + while (cpu_temp >= pdata->alert) { + printf("CPU Temperature (%dC) has beyond alert (%dC), close to critical (%dC)", + cpu_temp, pdata->alert, pdata->critical); + puts(" waiting...\n"); + mdelay(pdata->polling_delay); + ret = read_temperature(dev, &cpu_temp); + if (ret) + return ret; + } + + *temp = cpu_temp / 1000; + + return 0; +} + +static const struct dm_thermal_ops imx_sc_thermal_ops = { + .get_temp = imx_sc_thermal_get_temp, +}; + +static int imx_sc_thermal_probe(struct udevice *dev) +{ + debug("%s dev name %s\n", __func__, dev->name); + return 0; +} + +static int imx_sc_thermal_bind(struct udevice *dev) +{ + struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev); + int reg, ret; + int offset; + const char *name; + const void *prop; + + debug("%s dev name %s\n", __func__, dev->name); + + prop = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "compatible", + NULL); + if (!prop) + return 0; + + pdata->zone_node = 1; + + reg = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "tsens-num", 0); + if (reg == 0) { + printf("%s: no temp sensor number provided!\n", __func__); + return -EINVAL; + } + + offset = fdt_subnode_offset(gd->fdt_blob, 0, "thermal-zones"); + fdt_for_each_subnode(offset, gd->fdt_blob, offset) { + /* Bind the subnode to this driver */ + name = fdt_get_name(gd->fdt_blob, offset, NULL); + + ret = device_bind_with_driver_data(dev, dev->driver, name, + dev->driver_data, + offset_to_ofnode(offset), + NULL); + if (ret) + printf("Error binding driver '%s': %d\n", + dev->driver->name, ret); + } + return 0; +} + +static int imx_sc_thermal_ofdata_to_platdata(struct udevice *dev) +{ + struct imx_sc_thermal_plat *pdata = dev_get_platdata(dev); + struct fdtdec_phandle_args args; + const char *type; + int ret; + int trips_np; + + debug("%s dev name %s\n", __func__, dev->name); + + if (pdata->zone_node) + return 0; + + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), + "thermal-sensors", + "#thermal-sensor-cells", + 0, 0, &args); + if (ret) + return ret; + + if (args.node != dev_of_offset(dev->parent)) + return -EFAULT; + + if (args.args_count >= 1) + pdata->id = args.args[0]; + else + pdata->id = 0; + + debug("args.args_count %d, id %d\n", args.args_count, pdata->id); + + pdata->polling_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "polling-delay", 1000); + + trips_np = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(dev), + "trips"); + fdt_for_each_subnode(trips_np, gd->fdt_blob, trips_np) { + type = fdt_getprop(gd->fdt_blob, trips_np, "type", NULL); + if (type) { + if (strcmp(type, "critical") == 0) { + pdata->critical = fdtdec_get_int(gd->fdt_blob, + trips_np, + "temperature", + 85); + } else if (strcmp(type, "passive") == 0) { + pdata->alert = fdtdec_get_int(gd->fdt_blob, + trips_np, + "temperature", + 80); + } + } + } + + debug("id %d polling_delay %d, critical %d, alert %d\n", pdata->id, + pdata->polling_delay, pdata->critical, pdata->alert); + + return 0; +} + +static const sc_rsrc_t imx8qxp_sensor_rsrc[] = { + SC_R_SYSTEM, SC_R_DRC_0, SC_R_PMIC_0, + SC_R_PMIC_1, SC_R_PMIC_2, +}; + +static const struct udevice_id imx_sc_thermal_ids[] = { + { .compatible = "nxp,imx8qxp-sc-tsens", .data = + (ulong)&imx8qxp_sensor_rsrc, }, + { } +}; + +U_BOOT_DRIVER(imx_sc_thermal) = { + .name = "imx_sc_thermal", + .id = UCLASS_THERMAL, + .ops = &imx_sc_thermal_ops, + .of_match = imx_sc_thermal_ids, + .bind = imx_sc_thermal_bind, + .probe = imx_sc_thermal_probe, + .ofdata_to_platdata = imx_sc_thermal_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct imx_sc_thermal_plat), + .flags = DM_FLAG_PRE_RELOC, +};