[U-Boot] [PATCH 1/8] imx: sip: add call_imx_sip_ret2

This function will be used by i.MX8 fuse driver.
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/include/asm/mach-imx/sys_proto.h | 3 +++ arch/arm/mach-imx/sip.c | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index d0f866b630..4925dd7894 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -134,4 +134,7 @@ int mxs_wait_mask_clr(struct mxs_register_32 *reg, u32 mask, u32 timeout);
unsigned long call_imx_sip(unsigned long id, unsigned long reg0, unsigned long reg1, unsigned long reg2); +unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0, + unsigned long *reg1, unsigned long reg2, + unsigned long reg3); #endif diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c index 813c2ae5e1..968e7cf309 100644 --- a/arch/arm/mach-imx/sip.c +++ b/arch/arm/mach-imx/sip.c @@ -20,3 +20,25 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0,
return regs.regs[0]; } + +/* + * Do an SMC call to return 2 registers by having reg1 passed in by reference + */ +unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0, + unsigned long *reg1, unsigned long reg2, + unsigned long reg3) +{ + struct pt_regs regs; + + regs.regs[0] = id; + regs.regs[1] = reg0; + regs.regs[2] = *reg1; + regs.regs[3] = reg2; + regs.regs[4] = reg3; + + smc_call(®s); + + *reg1 = regs.regs[1]; + + return regs.regs[0]; +}

Add fuse write for i.MX8
Signed-off-by: Peng Fan peng.fan@nxp.com --- drivers/misc/imx8/Makefile | 1 + drivers/misc/imx8/fuse.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 drivers/misc/imx8/fuse.c
diff --git a/drivers/misc/imx8/Makefile b/drivers/misc/imx8/Makefile index ee05893cbb..48fdb5b61c 100644 --- a/drivers/misc/imx8/Makefile +++ b/drivers/misc/imx8/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+
obj-y += scu_api.o scu.o +obj-$(CONFIG_CMD_FUSE) += fuse.o diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c new file mode 100644 index 0000000000..29d2256a22 --- /dev/null +++ b/drivers/misc/imx8/fuse.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP + */ + +#include <common.h> +#include <console.h> +#include <errno.h> +#include <fuse.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/sys_proto.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define FSL_ECC_WORD_START_1 0x10 +#define FSL_ECC_WORD_END_1 0x10F + +#ifdef CONFIG_IMX8QXP +#define FSL_ECC_WORD_START_2 0x220 +#define FSL_ECC_WORD_END_2 0x31F + +#define FSL_QXP_FUSE_GAP_START 0x110 +#define FSL_QXP_FUSE_GAP_END 0x21F +#endif + +#define FSL_SIP_OTP_READ 0xc200000A +#define FSL_SIP_OTP_WRITE 0xc200000B + +int fuse_read(u32 bank, u32 word, u32 *val) +{ + return fuse_sense(bank, word, val); +} + +int fuse_sense(u32 bank, u32 word, u32 *val) +{ + unsigned long ret = 0, value = 0; + + if (bank != 0) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + ret = call_imx_sip_ret2(FSL_SIP_OTP_READ, (unsigned long)word, &value, + 0, 0); + *val = (u32)value; + + return ret; +} + +int fuse_prog(u32 bank, u32 word, u32 val) +{ + if (bank != 0) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_IMX8QXP)) { + if (word >= FSL_QXP_FUSE_GAP_START && + word <= FSL_QXP_FUSE_GAP_END) { + printf("Invalid word argument for this SoC\n"); + return -EINVAL; + } + } + + if ((word >= FSL_ECC_WORD_START_1 && word <= FSL_ECC_WORD_END_1) || + (word >= FSL_ECC_WORD_START_2 && word <= FSL_ECC_WORD_END_2)) { + puts("Warning: Words in this index range have ECC protection\n" + "and can only be programmed once per word. Individual bit\n" + "operations will be rejected after the first one.\n" + "\n\n Really program this word? <y/N>\n"); + + if (!confirm_yesno()) { + puts("Word programming aborted\n"); + return -EPERM; + } + } + + return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word, + (unsigned long)val, 0); +} + +int fuse_override(u32 bank, u32 word, u32 val) +{ + printf("Override fuse to i.MX8 in u-boot is forbidden\n"); + return -EPERM; +}

Add fuse write for i.MX8 Signed-off-by: Peng Fan peng.fan@nxp.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Enable CMD_FUSE for i.MX8QXP MEK
Signed-off-by: Peng Fan peng.fan@nxp.com --- configs/imx8qxp_mek_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/imx8qxp_mek_defconfig b/configs/imx8qxp_mek_defconfig index a94998b8b5..14e9da386a 100644 --- a/configs/imx8qxp_mek_defconfig +++ b/configs/imx8qxp_mek_defconfig @@ -27,6 +27,7 @@ CONFIG_CMD_CPU=y # CONFIG_CMD_IMPORTENV is not set CONFIG_CMD_CLK=y CONFIG_CMD_DM=y +CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y

Enable CMD_FUSE for i.MX8QXP MEK Signed-off-by: Peng Fan peng.fan@nxp.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Add sc_misc_get_temp to support get temperature
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/include/asm/arch-imx8/sci/sci.h | 2 ++ arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h | 1 + drivers/misc/imx8/scu_api.c | 28 +++++++++++++++++++++++ 3 files changed, 31 insertions(+)
diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h index d1621669e2..ccf45d71f7 100644 --- a/arch/arm/include/asm/arch-imx8/sci/sci.h +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h @@ -76,6 +76,8 @@ void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev); void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status); void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit); int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val); +int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp, + s16 *celsius, s8 *tenths);
/* RM API */ sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr); diff --git a/arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h b/arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h index 5d17b553d7..3629eb68d7 100644 --- a/arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h +++ b/arch/arm/include/asm/arch-imx8/sci/svc/misc/api.h @@ -26,5 +26,6 @@ #define SC_MISC_REL_CONTAINER 2U /* Release container */
typedef u8 sc_misc_boot_status_t; +typedef u8 sc_misc_temp_t;
#endif /* SC_MISC_API_H */ diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index d9c4d5d784..031bc0048b 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -273,6 +273,34 @@ int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val) return 0; }
+int sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource, sc_misc_temp_t temp, + s16 *celsius, s8 *tenths) +{ + struct udevice *dev = gd->arch.scu_dev; + int size = sizeof(struct sc_rpc_msg_s); + struct sc_rpc_msg_s msg; + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC; + RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_TEMP; + RPC_U16(&msg, 0U) = (u16)resource; + RPC_U8(&msg, 2U) = (u8)temp; + RPC_SIZE(&msg) = 2U; + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret < 0) + return ret; + + if (celsius) + *celsius = RPC_I16(&msg, 0U); + + if (tenths) + *tenths = RPC_I8(&msg, 2U); + + return 0; +} + /* RM */ sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr) {

Add i.MX8 thermal driver to support get temperature from SCU.
Signed-off-by: Peng Fan peng.fan@nxp.com --- 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 <config.h> +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <thermal.h> +#include <dm/device-internal.h> +#include <dm/device.h> +#include <asm/arch/sci/sci.h> + +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, +};

Read the temperature when print cpu inforation.
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/mach-imx/imx8/cpu.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 4bbc956f9d..25b010489b 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -11,6 +11,7 @@ #include <dm/lists.h> #include <dm/uclass.h> #include <errno.h> +#include <thermal.h> #include <asm/arch/sci/sci.h> #include <asm/arch/sys_proto.h> #include <asm/arch-imx/cpu.h> @@ -571,15 +572,45 @@ const char *get_core_name(void) return "?"; }
+#if defined(CONFIG_IMX_SCU_THERMAL) +static int cpu_imx_get_temp(void) +{ + struct udevice *thermal_dev; + int cpu_tmp, ret; + + ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0", + &thermal_dev); + + if (!ret) { + ret = thermal_get_temp(thermal_dev, &cpu_tmp); + if (ret) + return 0xdeadbeef; + } else { + return 0xdeadbeef; + } + + return cpu_tmp; +} +#endif + int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_imx_platdata *plat = dev_get_platdata(dev); + int ret;
if (size < 100) return -ENOSPC;
- snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz\n", - plat->type, plat->rev, plat->name, plat->freq_mhz); + ret = snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz", + plat->type, plat->rev, plat->name, plat->freq_mhz); + + if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) { + buf = buf + ret; + size = size - ret; + ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp()); + } + + snprintf(buf + ret, size - ret, "\n");
return 0; }

Hi Peng,
On 12/04/19 09:55, Peng Fan wrote:
Read the temperature when print cpu inforation.
Signed-off-by: Peng Fan peng.fan@nxp.com
arch/arm/mach-imx/imx8/cpu.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 4bbc956f9d..25b010489b 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -11,6 +11,7 @@ #include <dm/lists.h> #include <dm/uclass.h> #include <errno.h> +#include <thermal.h> #include <asm/arch/sci/sci.h> #include <asm/arch/sys_proto.h> #include <asm/arch-imx/cpu.h> @@ -571,15 +572,45 @@ const char *get_core_name(void) return "?"; }
+#if defined(CONFIG_IMX_SCU_THERMAL) +static int cpu_imx_get_temp(void) +{
This generates a warning when CONFIG_IMX_SCU_THERMAL is not set, because it is called later:
- struct udevice *thermal_dev;
- int cpu_tmp, ret;
- ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0",
&thermal_dev);
- if (!ret) {
ret = thermal_get_temp(thermal_dev, &cpu_tmp);
if (ret)
return 0xdeadbeef;
- } else {
return 0xdeadbeef;
- }
- return cpu_tmp;
+} +#endif
int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_imx_platdata *plat = dev_get_platdata(dev);
int ret;
if (size < 100) return -ENOSPC;
- snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz\n",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- ret = snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
buf = buf + ret;
size = size - ret;
ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp());
^--- here it is referenced.
Regards, Stefano
}
snprintf(buf + ret, size - ret, "\n");
return 0;
}

Hi Stefano.
Subject: Re: [PATCH 6/8] imx8: cpu: get temperature when print cpu desc
Hi Peng,
On 12/04/19 09:55, Peng Fan wrote:
Read the temperature when print cpu inforation.
Signed-off-by: Peng Fan peng.fan@nxp.com
arch/arm/mach-imx/imx8/cpu.c | 35
+++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 4bbc956f9d..25b010489b 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -11,6 +11,7 @@ #include <dm/lists.h> #include <dm/uclass.h> #include <errno.h> +#include <thermal.h> #include <asm/arch/sci/sci.h> #include <asm/arch/sys_proto.h> #include <asm/arch-imx/cpu.h> @@ -571,15 +572,45 @@ const char *get_core_name(void) return "?"; }
+#if defined(CONFIG_IMX_SCU_THERMAL) +static int cpu_imx_get_temp(void) +{
This generates a warning when CONFIG_IMX_SCU_THERMAL is not set, because it is called later:
- struct udevice *thermal_dev;
- int cpu_tmp, ret;
- ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0",
&thermal_dev);
- if (!ret) {
ret = thermal_get_temp(thermal_dev, &cpu_tmp);
if (ret)
return 0xdeadbeef;
- } else {
return 0xdeadbeef;
- }
- return cpu_tmp;
+} +#endif
int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_imx_platdata *plat = dev_get_platdata(dev);
int ret;
if (size < 100) return -ENOSPC;
- snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz\n",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- ret = snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
buf = buf + ret;
size = size - ret;
ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp());
^---
I not able to connect my PC to verify. But just thinking, When CONFIG_IMX_SCU_THERMAL not enabled, the compiler should optimize the if block? Because it is just "if (0)"
Regards, Peng.
here it is referenced.
Regards, Stefano
}
snprintf(buf + ret, size - ret, "\n");
return 0;
}
--
======= DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de ============================================================== =======

On 25/04/19 15:46, Peng Fan wrote:
Hi Stefano.
Subject: Re: [PATCH 6/8] imx8: cpu: get temperature when print cpu desc
Hi Peng,
On 12/04/19 09:55, Peng Fan wrote:
Read the temperature when print cpu inforation.
Signed-off-by: Peng Fan peng.fan@nxp.com
arch/arm/mach-imx/imx8/cpu.c | 35
+++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 4bbc956f9d..25b010489b 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -11,6 +11,7 @@ #include <dm/lists.h> #include <dm/uclass.h> #include <errno.h> +#include <thermal.h> #include <asm/arch/sci/sci.h> #include <asm/arch/sys_proto.h> #include <asm/arch-imx/cpu.h> @@ -571,15 +572,45 @@ const char *get_core_name(void) return "?"; }
+#if defined(CONFIG_IMX_SCU_THERMAL) +static int cpu_imx_get_temp(void) +{
This generates a warning when CONFIG_IMX_SCU_THERMAL is not set, because it is called later:
- struct udevice *thermal_dev;
- int cpu_tmp, ret;
- ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0",
&thermal_dev);
- if (!ret) {
ret = thermal_get_temp(thermal_dev, &cpu_tmp);
if (ret)
return 0xdeadbeef;
- } else {
return 0xdeadbeef;
- }
- return cpu_tmp;
+} +#endif
int cpu_imx_get_desc(struct udevice *dev, char *buf, int size) { struct cpu_imx_platdata *plat = dev_get_platdata(dev);
int ret;
if (size < 100) return -ENOSPC;
- snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz\n",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- ret = snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz",
plat->type, plat->rev, plat->name, plat->freq_mhz);
- if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
buf = buf + ret;
size = size - ret;
ret = snprintf(buf, size, " at %dC", cpu_imx_get_temp());
^---
I not able to connect my PC to verify. But just thinking, When CONFIG_IMX_SCU_THERMAL not enabled, the compiler should optimize the if block? Because it is just "if (0)"
But if compiler optimizes the block, I should not see the warning...
Regards, Stefano

Add thermal dts node Enable thermal in defconfig
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/dts/fsl-imx8dx.dtsi | 56 +++++++++++++++++++++++++++++++++++++++++++ configs/imx8qxp_mek_defconfig | 2 ++ 2 files changed, 58 insertions(+)
diff --git a/arch/arm/dts/fsl-imx8dx.dtsi b/arch/arm/dts/fsl-imx8dx.dtsi index 3b1a2a20e3..1c163afdcd 100644 --- a/arch/arm/dts/fsl-imx8dx.dtsi +++ b/arch/arm/dts/fsl-imx8dx.dtsi @@ -11,6 +11,7 @@ #include <dt-bindings/input/input.h> #include <dt-bindings/pinctrl/pads-imx8qxp.h> #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/thermal/thermal.h>
/ { model = "Freescale i.MX8DX"; @@ -489,6 +490,61 @@ power-domains = <&pd_conn_enet1>; status = "disabled"; }; + + tsens: thermal-sensor { + compatible = "nxp,imx8qxp-sc-tsens"; + /* number of the temp sensor on the chip */ + tsens-num = <2>; + #thermal-sensor-cells = <1>; + }; + + thermal_zones: thermal-zones { + /* cpu thermal */ + cpu-thermal0 { + polling-delay-passive = <250>; + polling-delay = <2000>; + /*the slope and offset of the temp sensor */ + thermal-sensors = <&tsens 0>; + trips { + cpu_alert0: trip0 { + temperature = <107000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit0: trip1 { + temperature = <127000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + drc-thermal0 { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tsens 1>; + status = "disabled"; + trips { + drc_alert0: trip0 { + temperature = <107000>; + hysteresis = <2000>; + type = "passive"; + }; + drc_crit0: trip1 { + temperature = <127000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; };
&A35_0 { diff --git a/configs/imx8qxp_mek_defconfig b/configs/imx8qxp_mek_defconfig index 14e9da386a..f0da489645 100644 --- a/configs/imx8qxp_mek_defconfig +++ b/configs/imx8qxp_mek_defconfig @@ -73,5 +73,7 @@ CONFIG_DM_REGULATOR_GPIO=y CONFIG_SPL_DM_REGULATOR_GPIO=y CONFIG_DM_SERIAL=y CONFIG_FSL_LPUART=y +CONFIG_DM_THERMAL=y +CONFIG_IMX_SCU_THERMAL=y CONFIG_SPL_TINY_MEMSET=y # CONFIG_EFI_LOADER is not set

Move HUSH_PARSER to defconfig, otherwise meet " => run netboot Booting from net ... Unknown command 'if' - try 'help' Unknown command 'then' - try 'help' Unknown command 'else' - try 'help' Unknown command 'fi' - try 'help' Unknown command '0x80280000' - try 'help' Unknown command 'if' - try 'help' Unknown command 'then' - try 'help' Unknown command 'then' - try 'help' Unknown command 'else' - try 'help' Unknown command 'fi' - try 'help' Unknown command 'else' - try 'help' Unknown command 'fi' - try 'help' "
Signed-off-by: Peng Fan peng.fan@nxp.com --- configs/imx8qxp_mek_defconfig | 1 + include/configs/imx8qxp_mek.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/configs/imx8qxp_mek_defconfig b/configs/imx8qxp_mek_defconfig index f0da489645..38f0ff0bf3 100644 --- a/configs/imx8qxp_mek_defconfig +++ b/configs/imx8qxp_mek_defconfig @@ -23,6 +23,7 @@ CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_POWER_DOMAIN=y CONFIG_SPL_WATCHDOG_SUPPORT=y +CONFIG_HUSH_PARSER=y CONFIG_CMD_CPU=y # CONFIG_CMD_IMPORTENV is not set CONFIG_CMD_CLK=y diff --git a/include/configs/imx8qxp_mek.h b/include/configs/imx8qxp_mek.h index 312e30dc6c..1cff18e05e 100644 --- a/include/configs/imx8qxp_mek.h +++ b/include/configs/imx8qxp_mek.h @@ -159,7 +159,6 @@ #define CONFIG_BAUDRATE 115200
/* Monitor Command Prompt */ -#define CONFIG_HUSH_PARSER #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " #define CONFIG_SYS_CBSIZE 2048 #define CONFIG_SYS_MAXARGS 64

Move HUSH_PARSER to defconfig, otherwise meet " => run netboot Booting from net ... Unknown command 'if' - try 'help' Unknown command 'then' - try 'help' Unknown command 'else' - try 'help' Unknown command 'fi' - try 'help' Unknown command '0x80280000' - try 'help' Unknown command 'if' - try 'help' Unknown command 'then' - try 'help' Unknown command 'then' - try 'help' Unknown command 'else' - try 'help' Unknown command 'fi' - try 'help' Unknown command 'else' - try 'help' Unknown command 'fi' - try 'help' " Signed-off-by: Peng Fan peng.fan@nxp.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

This function will be used by i.MX8 fuse driver. Signed-off-by: Peng Fan peng.fan@nxp.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic
participants (3)
-
Peng Fan
-
sbabic@denx.de
-
Stefano Babic