diff options
Diffstat (limited to 'sys/dev/fdt/imxtmu.c')
-rw-r--r-- | sys/dev/fdt/imxtmu.c | 151 |
1 files changed, 93 insertions, 58 deletions
diff --git a/sys/dev/fdt/imxtmu.c b/sys/dev/fdt/imxtmu.c index af9e50bb226..b796b0fad86 100644 --- a/sys/dev/fdt/imxtmu.c +++ b/sys/dev/fdt/imxtmu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imxtmu.c,v 1.1 2019/08/27 12:51:57 patrick Exp $ */ +/* $OpenBSD: imxtmu.c,v 1.2 2020/03/20 09:13:03 patrick Exp $ */ /* * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se> * @@ -27,22 +27,29 @@ #include <dev/ofw/openfirm.h> #include <dev/ofw/fdt.h> - -/* registers */ -#define TMU_TMR 0x000 -#define TMU_TMR_ME (1U << 31) -#define TMU_TMR_ALPF (0x3 << 26) -#define TMU_TMR_SENSOR(x) (1 << (15 - (x))) -#define TMU_TMTMIR 0x008 -#define TMU_TMTMIR_DEFAULT 0xf -#define TMU_TIER 0x020 -#define TMU_TTCFGR 0x080 -#define TMU_TSCFGR 0x084 -#define TMU_TRITSR(x) (0x100 + ((x) * 0x10)) -#define TMU_TTR0CR 0xf10 -#define TMU_TTR1CR 0xf14 -#define TMU_TTR2CR 0xf18 -#define TMU_TTR3CR 0xf1c +#include <dev/ofw/ofw_clock.h> + +/* i.MX8MQ registers */ +#define TMU_MQ_TMR 0x000 +#define TMU_MQ_TMR_ME (1U << 31) +#define TMU_MQ_TMR_ALPF (0x3 << 26) +#define TMU_MQ_TMR_SENSOR(x) (1 << (15 - (x))) +#define TMU_MQ_TMTMIR 0x008 +#define TMU_MQ_TMTMIR_DEFAULT 0xf +#define TMU_MQ_TIER 0x020 +#define TMU_MQ_TTCFGR 0x080 +#define TMU_MQ_TSCFGR 0x084 +#define TMU_MQ_TRITSR(x) (0x100 + ((x) * 0x10)) +#define TMU_MQ_TTR0CR 0xf10 +#define TMU_MQ_TTR1CR 0xf14 +#define TMU_MQ_TTR2CR 0xf18 +#define TMU_MQ_TTR3CR 0xf1c + +/* i.MX8MM registers */ +#define TMU_MM_TER 0x000 +#define TMU_MM_TER_EN (1U << 31) +#define TMU_MM_TRITSR 0x020 +#define TMU_MM_TRITSR_LOW_LIMIT 10 #define HREAD4(sc, reg) \ (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) @@ -66,7 +73,9 @@ struct imxtmu_softc { int imxtmu_match(struct device *, void *, void *); void imxtmu_attach(struct device *, struct device *, void *); -void imxtmu_refresh_sensors(void *); + +void imxtmu_mm_refresh_sensors(void *); +void imxtmu_mq_refresh_sensors(void *); struct cfattach imxtmu_ca = { sizeof(struct imxtmu_softc), imxtmu_match, imxtmu_attach @@ -81,7 +90,8 @@ imxtmu_match(struct device *parent, void *match, void *aux) { struct fdt_attach_args *faa = aux; - return OF_is_compatible(faa->fa_node, "fsl,imx8mq-tmu"); + return OF_is_compatible(faa->fa_node, "fsl,imx8mm-tmu") || + OF_is_compatible(faa->fa_node, "fsl,imx8mq-tmu"); } void @@ -102,42 +112,7 @@ imxtmu_attach(struct device *parent, struct device *self, void *aux) printf("\n"); - /* - * XXX: This thermal unit can show temperatures per node, and - * XXX: the thermal-zones can reference this. But since we do - * XXX: not register ourselves with such a infrastructure we can - * XXX: live with just extracting sensor 0: the CPU. - */ - sc->sc_sensorid = 0; - - HWRITE4(sc, TMU_TIER, 0); - HWRITE4(sc, TMU_TMTMIR, TMU_TMTMIR_DEFAULT); - HWRITE4(sc, TMU_TMR, 0); - - if (OF_getpropintarray(faa->fa_node, "fsl,tmu-range", range, - sizeof(range)) != sizeof(range)) - return; - - HWRITE4(sc, TMU_TTR0CR, range[0]); - HWRITE4(sc, TMU_TTR1CR, range[1]); - HWRITE4(sc, TMU_TTR2CR, range[2]); - HWRITE4(sc, TMU_TTR3CR, range[3]); - - len = OF_getproplen(faa->fa_node, "fsl,tmu-calibration"); - if (len <= 0 || (len % 8) != 0) - return; - - calibration = malloc(len, M_TEMP, M_WAITOK); - OF_getpropintarray(faa->fa_node, "fsl,tmu-calibration", calibration, - len); - for (i = 0; i < (len / 4); i += 2) { - HWRITE4(sc, TMU_TTCFGR, calibration[i + 0]); - HWRITE4(sc, TMU_TSCFGR, calibration[i + 1]); - } - free(calibration, M_TEMP, len); - - HWRITE4(sc, TMU_TMR, TMU_TMR_SENSOR(sc->sc_sensorid) | - TMU_TMR_ME | TMU_TMR_ALPF); + clock_enable_all(faa->fa_node); strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, sizeof(sc->sc_sensordev.xname)); @@ -147,16 +122,76 @@ imxtmu_attach(struct device *parent, struct device *self, void *aux) sc->sc_sensor.flags = SENSOR_FINVALID; sensor_attach(&sc->sc_sensordev, &sc->sc_sensor); sensordev_install(&sc->sc_sensordev); - sensor_task_register(sc, imxtmu_refresh_sensors, 5); + + if (OF_is_compatible(faa->fa_node, "fsl,imx8mm-tmu")) { + HSET4(sc, TMU_MM_TER, TMU_MM_TER_EN); + sensor_task_register(sc, imxtmu_mm_refresh_sensors, 5); + } + + if (OF_is_compatible(faa->fa_node, "fsl,imx8mq-tmu")) { + /* + * XXX: This thermal unit can show temperatures per node, and + * XXX: the thermal-zones can reference this. But since we do + * XXX: not register ourselves with such a infrastructure we can + * XXX: live with just extracting sensor 0: the CPU. + */ + sc->sc_sensorid = 0; + + HWRITE4(sc, TMU_MQ_TIER, 0); + HWRITE4(sc, TMU_MQ_TMTMIR, TMU_MQ_TMTMIR_DEFAULT); + HWRITE4(sc, TMU_MQ_TMR, 0); + + if (OF_getpropintarray(faa->fa_node, "fsl,tmu-range", range, + sizeof(range)) != sizeof(range)) + return; + + HWRITE4(sc, TMU_MQ_TTR0CR, range[0]); + HWRITE4(sc, TMU_MQ_TTR1CR, range[1]); + HWRITE4(sc, TMU_MQ_TTR2CR, range[2]); + HWRITE4(sc, TMU_MQ_TTR3CR, range[3]); + + len = OF_getproplen(faa->fa_node, "fsl,tmu-calibration"); + if (len <= 0 || (len % 8) != 0) + return; + + calibration = malloc(len, M_TEMP, M_WAITOK); + OF_getpropintarray(faa->fa_node, "fsl,tmu-calibration", calibration, + len); + for (i = 0; i < (len / 4); i += 2) { + HWRITE4(sc, TMU_MQ_TTCFGR, calibration[i + 0]); + HWRITE4(sc, TMU_MQ_TSCFGR, calibration[i + 1]); + } + free(calibration, M_TEMP, len); + + HWRITE4(sc, TMU_MQ_TMR, TMU_MQ_TMR_SENSOR(sc->sc_sensorid) | + TMU_MQ_TMR_ME | TMU_MQ_TMR_ALPF); + + sensor_task_register(sc, imxtmu_mq_refresh_sensors, 5); + } +} + +void +imxtmu_mm_refresh_sensors(void *arg) +{ + struct imxtmu_softc *sc = (struct imxtmu_softc *)arg; + uint32_t value; + + value = HREAD4(sc, TMU_MM_TRITSR); + if (value < TMU_MM_TRITSR_LOW_LIMIT) + return; + value = (value & 0xff) * 1000000; + + sc->sc_sensor.value = value + 273150000; + sc->sc_sensor.flags &= ~SENSOR_FINVALID; } void -imxtmu_refresh_sensors(void *arg) +imxtmu_mq_refresh_sensors(void *arg) { struct imxtmu_softc *sc = (struct imxtmu_softc *)arg; uint32_t value; - value = HREAD4(sc, TMU_TRITSR(sc->sc_sensorid)); + value = HREAD4(sc, TMU_MQ_TRITSR(sc->sc_sensorid)); value = (value & 0xff) * 1000000; sc->sc_sensor.value = value + 273150000; |