From f126f9b0e537c0b1a393a6dd174310c9553f0746 Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 12 Jun 2024 09:06:15 +0000 Subject: [PATCH] Add RK3588 support. ok mlarkin@, kurt@ --- sys/dev/fdt/rktemp.c | 224 +++++++++++++++++++++++++++++-------------- 1 file changed, 150 insertions(+), 74 deletions(-) diff --git a/sys/dev/fdt/rktemp.c b/sys/dev/fdt/rktemp.c index 155431d9e2f..78465d370c6 100644 --- a/sys/dev/fdt/rktemp.c +++ b/sys/dev/fdt/rktemp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rktemp.c,v 1.12 2023/03/05 09:57:32 kettenis Exp $ */ +/* $OpenBSD: rktemp.c,v 1.13 2024/06/12 09:06:15 kettenis Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -36,43 +36,38 @@ #define TSADC_USER_CON_INTER_PD_SOC_SHIFT 6 #define TSADC_AUTO_CON 0x0004 #define TSADC_AUTO_CON_TSHUT_POLARITY (1 << 8) -#define TSADC_AUTO_CON_SRC3_EN (1 << 7) -#define TSADC_AUTO_CON_SRC2_EN (1 << 6) -#define TSADC_AUTO_CON_SRC1_EN (1 << 5) -#define TSADC_AUTO_CON_SRC0_EN (1 << 4) +#define TSADC_AUTO_CON_SRC_EN(ch) (1 << ((ch) + 4)) #define TSADC_AUTO_CON_TSADC_Q_SEL (1 << 1) #define TSADC_AUTO_CON_AUTO_EN (1 << 0) #define TSADC_INT_EN 0x0008 -#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC3 (1 << 11) -#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC2 (1 << 10) -#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC1 (1 << 9) -#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 (1 << 8) -#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC3 (1 << 7) -#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC2 (1 << 6) -#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC1 (1 << 5) -#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 (1 << 4) +#define TSADC_INT_EN_TSHUT_2CRU_EN_SRC(ch) (1 << ((ch) + 8)) +#define TSADC_INT_EN_TSHUT_2GPIO_EN_SRC(ch) (1 << ((ch) + 4)) #define TSADC_INT_PD 0x000c -#define TSADC_INT_PD_TSHUT_O_SRC0 (1 << 4) -#define TSADC_INT_PD_TSHUT_O_SRC1 (1 << 5) -#define TSADC_INT_PD_TSHUT_O_SRC2 (1 << 6) -#define TSADC_INT_PD_TSHUT_O_SRC3 (1 << 7) -#define TSADC_DATA0 0x0020 -#define TSADC_DATA1 0x0024 -#define TSADC_DATA2 0x0028 -#define TSADC_DATA3 0x002c -#define TSADC_COMP0_INT 0x0030 -#define TSADC_COMP1_INT 0x0034 -#define TSADC_COMP2_INT 0x0038 -#define TSADC_COMP3_INT 0x003c -#define TSADC_COMP0_SHUT 0x0040 -#define TSADC_COMP1_SHUT 0x0044 -#define TSADC_COMP2_SHUT 0x0048 -#define TSADC_COMP3_SHUT 0x004c +#define TSADC_INT_PD_TSHUT_O_SRC(ch) (1 << ((ch) + 4)) +#define TSADC_DATA(ch) (0x0020 + (ch) * 4) +#define TSADC_COMP_INT(ch) (0x0030 + (ch) * 4) +#define TSADC_COMP_SHUT(ch) (0x0040 + (ch) * 4) #define TSADC_HIGHT_INT_DEBOUNCE 0x0060 #define TSADC_HIGHT_TSHUT_DEBOUNCE 0x0064 #define TSADC_AUTO_PERIOD 0x0068 #define TSADC_AUTO_PERIOD_HT 0x006c +/* RK3588 */ +#define TSADC_V3_AUTO_SRC 0x000c +#define TSADC_V3_AUTO_SRC_CH(ch) (1 << (ch)) +#define TSADC_V3_GPIO_EN 0x0018 +#define TSADC_V3_GPIO_EN_CH(ch) (1 << (ch)) +#define TSADC_V3_CRU_EN 0x001c +#define TSADC_V3_CRU_EN_CH(ch) (1 << (ch)) +#define TSADC_V3_HLT_INT_PD 0x0024 +#define TSADC_V3_HT_INT_STATUS(ch) (1 << (ch)) +#define TSADC_V3_DATA(ch) (0x002c + (ch) * 4) +#define TSADC_V3_COMP_SHUT(ch) (0x010c + (ch) * 4) +#define TSADC_V3_HIGHT_INT_DEBOUNCE 0x014c +#define TSADC_V3_HIGHT_TSHUT_DEBOUNCE 0x0150 +#define TSADC_V3_AUTO_PERIOD 0x0154 +#define TSADC_V3_AUTO_PERIOD_HT 0x0158 + /* RK3568 */ #define RK3568_GRF_TSADC_CON 0x0600 #define RK3568_GRF_TSADC_EN (1 << 8) @@ -248,16 +243,36 @@ const struct rktemp_entry rk3568_temps[] = { const char *const rk3568_names[] = { "CPU", "GPU" }; +/* RK3588 conversion table. */ +const struct rktemp_entry rk3588_temps[] = { + { -40000, 215 }, + { 25000, 285 }, + { 85000, 350 }, + { 125000, 395 }, +}; + +const char *const rk3588_names[] = { + "Top", + "CPU (big0)", + "CPU (big1)", + "CPU (little)", + "Center", + "GPU", + "NPU" +}; + struct rktemp_softc { struct device sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; int sc_node; + bus_size_t sc_data0; + const struct rktemp_entry *sc_temps; int sc_ntemps; - struct ksensor sc_sensors[3]; + struct ksensor sc_sensors[7]; int sc_nsensors; struct ksensordev sc_sensordev; @@ -291,7 +306,8 @@ rktemp_match(struct device *parent, void *match, void *aux) OF_is_compatible(faa->fa_node, "rockchip,rk3308-tsadc") || OF_is_compatible(faa->fa_node, "rockchip,rk3328-tsadc") || OF_is_compatible(faa->fa_node, "rockchip,rk3399-tsadc") || - OF_is_compatible(faa->fa_node, "rockchip,rk3568-tsadc")); + OF_is_compatible(faa->fa_node, "rockchip,rk3568-tsadc") || + OF_is_compatible(faa->fa_node, "rockchip,rk3588-tsadc")); } void @@ -301,8 +317,7 @@ rktemp_attach(struct device *parent, struct device *self, void *aux) struct fdt_attach_args *faa = aux; const char *const *names; uint32_t mode, polarity, temp; - uint32_t auto_con, int_en; - uint32_t inter_pd_soc; + uint32_t auto_con, inter_pd_soc; int auto_period, auto_period_ht; int i; @@ -354,7 +369,7 @@ rktemp_attach(struct device *parent, struct device *self, void *aux) inter_pd_soc = 13; auto_period = 1875; /* 2.5 ms */ auto_period_ht = 1875; /* 2.5 ms */ - } else { + } else if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc")) { sc->sc_temps = rk3568_temps; sc->sc_ntemps = nitems(rk3568_temps); sc->sc_nsensors = 2; @@ -362,6 +377,14 @@ rktemp_attach(struct device *parent, struct device *self, void *aux) inter_pd_soc = 63; /* 97 us */ auto_period = 1622; /* 2.5 ms */ auto_period_ht = 1622; /* 2.5 ms */ + } else { + sc->sc_temps = rk3588_temps; + sc->sc_ntemps = nitems(rk3588_temps); + sc->sc_nsensors = 7; + names = rk3588_names; + inter_pd_soc = 0; + auto_period = 5000; /* 2.5 ms */ + auto_period_ht = 5000; /* 2.5 ms */ } pinctrl_byname(sc->sc_node, "init"); @@ -371,57 +394,110 @@ rktemp_attach(struct device *parent, struct device *self, void *aux) clock_enable(sc->sc_node, "apb_pclk"); /* Reset the TS-ADC controller block. */ - reset_assert(sc->sc_node, "tsadc-apb"); + reset_assert_all(sc->sc_node); delay(10); - reset_deassert(sc->sc_node, "tsadc-apb"); + reset_deassert_all(sc->sc_node); mode = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-mode", 1); polarity = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-polarity", 0); temp = OF_getpropint(sc->sc_node, "rockchip,hw-tshut-temp", 95000); - HWRITE4(sc, TSADC_USER_CON, - inter_pd_soc << TSADC_USER_CON_INTER_PD_SOC_SHIFT); - HWRITE4(sc, TSADC_AUTO_PERIOD, auto_period); - HWRITE4(sc, TSADC_AUTO_PERIOD_HT, auto_period_ht); - HWRITE4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4); - HWRITE4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4); - - if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc")) - rktemp_rk3568_init(sc); - - auto_con = HREAD4(sc, TSADC_AUTO_CON); - auto_con |= TSADC_AUTO_CON_TSADC_Q_SEL; - if (polarity) - auto_con |= TSADC_AUTO_CON_TSHUT_POLARITY; - HWRITE4(sc, TSADC_AUTO_CON, auto_con); - - /* Set shutdown limit. */ - for (i = 0; i < sc->sc_nsensors; i++) { - HWRITE4(sc, TSADC_COMP0_SHUT + i * 4, - rktemp_calc_code(sc, temp)); - auto_con |= (TSADC_AUTO_CON_SRC0_EN << i); - } - HWRITE4(sc, TSADC_AUTO_CON, auto_con); + if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) { + uint32_t gpio_en, cru_en; + + sc->sc_data0 = TSADC_V3_DATA(0); + + HWRITE4(sc, TSADC_V3_AUTO_PERIOD, auto_period); + HWRITE4(sc, TSADC_V3_AUTO_PERIOD_HT, auto_period_ht); + HWRITE4(sc, TSADC_V3_HIGHT_INT_DEBOUNCE, 4); + HWRITE4(sc, TSADC_V3_HIGHT_TSHUT_DEBOUNCE, 4); + + auto_con = TSADC_AUTO_CON_TSHUT_POLARITY << 16; + if (polarity) + auto_con = TSADC_AUTO_CON_TSHUT_POLARITY; + HWRITE4(sc, TSADC_AUTO_CON, auto_con); + + /* Set shutdown limit. */ + for (i = 0; i < sc->sc_nsensors; i++) { + HWRITE4(sc, TSADC_V3_COMP_SHUT(i), + rktemp_calc_code(sc, temp)); + HWRITE4(sc, TSADC_V3_AUTO_SRC, + TSADC_V3_AUTO_SRC_CH(i) << 16 | + TSADC_V3_AUTO_SRC_CH(i)); + } - /* Clear shutdown output status. */ - for (i = 0; i < sc->sc_nsensors; i++) - HWRITE4(sc, TSADC_INT_PD, (TSADC_INT_PD_TSHUT_O_SRC0 << i)); + /* Clear shutdown output status. */ + for (i = 0; i < sc->sc_nsensors; i++) { + HWRITE4(sc, TSADC_V3_HLT_INT_PD, + TSADC_V3_HT_INT_STATUS(i)); + } - /* Configure mode. */ - int_en = HREAD4(sc, TSADC_INT_EN); - for (i = 0; i < sc->sc_nsensors; i++) { - if (mode) - int_en |= (TSADC_INT_EN_TSHUT_2GPIO_EN_SRC0 << i); - else - int_en |= (TSADC_INT_EN_TSHUT_2CRU_EN_SRC0 << i); + /* Configure mode. */ + gpio_en = cru_en = 0; + for (i = 0; i < sc->sc_nsensors; i++) { + gpio_en |= TSADC_V3_GPIO_EN_CH(i) << 16; + cru_en |= TSADC_V3_CRU_EN_CH(i) << 16; + if (mode) + gpio_en |= TSADC_V3_GPIO_EN_CH(i); + else + cru_en |= TSADC_V3_CRU_EN_CH(i); + } + HWRITE4(sc, TSADC_V3_GPIO_EN, gpio_en); + HWRITE4(sc, TSADC_V3_CRU_EN, cru_en); + } else { + uint32_t int_en; + + sc->sc_data0 = TSADC_DATA(0); + + HWRITE4(sc, TSADC_USER_CON, + inter_pd_soc << TSADC_USER_CON_INTER_PD_SOC_SHIFT); + HWRITE4(sc, TSADC_AUTO_PERIOD, auto_period); + HWRITE4(sc, TSADC_AUTO_PERIOD_HT, auto_period_ht); + HWRITE4(sc, TSADC_HIGHT_INT_DEBOUNCE, 4); + HWRITE4(sc, TSADC_HIGHT_TSHUT_DEBOUNCE, 4); + + if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-tsadc")) + rktemp_rk3568_init(sc); + + auto_con = HREAD4(sc, TSADC_AUTO_CON); + auto_con |= TSADC_AUTO_CON_TSADC_Q_SEL; + if (polarity) + auto_con |= TSADC_AUTO_CON_TSHUT_POLARITY; + HWRITE4(sc, TSADC_AUTO_CON, auto_con); + + /* Set shutdown limit. */ + for (i = 0; i < sc->sc_nsensors; i++) { + HWRITE4(sc, TSADC_COMP_SHUT(i), + rktemp_calc_code(sc, temp)); + auto_con |= (TSADC_AUTO_CON_SRC_EN(i)); + } + HWRITE4(sc, TSADC_AUTO_CON, auto_con); + + /* Clear shutdown output status. */ + for (i = 0; i < sc->sc_nsensors; i++) + HWRITE4(sc, TSADC_INT_PD, TSADC_INT_PD_TSHUT_O_SRC(i)); + + /* Configure mode. */ + int_en = HREAD4(sc, TSADC_INT_EN); + for (i = 0; i < sc->sc_nsensors; i++) { + if (mode) + int_en |= TSADC_INT_EN_TSHUT_2GPIO_EN_SRC(i); + else + int_en |= TSADC_INT_EN_TSHUT_2CRU_EN_SRC(i); + } + HWRITE4(sc, TSADC_INT_EN, int_en); } - HWRITE4(sc, TSADC_INT_EN, int_en); pinctrl_byname(sc->sc_node, "default"); /* Finally turn on the ADC. */ - auto_con |= TSADC_AUTO_CON_AUTO_EN; - HWRITE4(sc, TSADC_AUTO_CON, auto_con); + if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-tsadc")) { + HWRITE4(sc, TSADC_AUTO_CON, + TSADC_AUTO_CON_AUTO_EN << 16 | TSADC_AUTO_CON_AUTO_EN); + } else { + auto_con |= TSADC_AUTO_CON_AUTO_EN; + HWRITE4(sc, TSADC_AUTO_CON, auto_con); + } /* Register sensors. */ strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname, @@ -557,7 +633,7 @@ rktemp_refresh_sensors(void *arg) int i; for (i = 0; i < sc->sc_nsensors; i++) { - code = HREAD4(sc, TSADC_DATA0 + i * 4); + code = HREAD4(sc, sc->sc_data0 + (i * 4)); temp = rktemp_calc_temp(sc, code); sc->sc_sensors[i].value = 273150000 + 1000 * temp; if (rktemp_valid(sc, code)) @@ -577,7 +653,7 @@ rktemp_get_temperature(void *cookie, uint32_t *cells) if (idx >= sc->sc_nsensors) return THERMAL_SENSOR_MAX; - code = HREAD4(sc, TSADC_DATA0 + idx * 4); + code = HREAD4(sc, sc->sc_data0 + (idx * 4)); if (rktemp_valid(sc, code)) return rktemp_calc_temp(sc, code); else -- 2.20.1