diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 959025434f3a..7b8823763cfa 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -260,6 +260,10 @@ struct rockchip_thermal_data { #define TSADCV3_DATA_MASK 0x3ff #define TSADCV4_DATA_MASK 0x1ff #define TSADCV5_DATA_MASK 0x7ff +#define TSADCV6_DATA_MASK 0x1ffff + +#define TSADC_DATA_SIGN_BIT BIT(16) +#define TSADC_DATA_NEGATIVE 0xfffe0000 #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 @@ -277,6 +281,8 @@ struct rockchip_thermal_data { #define TSADCV12_AUTO_PERIOD_HT_TIME 3000 /* 2.5ms */ #define TSADCV13_AUTO_PERIOD_TIME 2500 /* 2.5ms */ #define TSADCV13_AUTO_PERIOD_HT_TIME 2500 /* 2.5ms */ +#define TSADCV14_AUTO_PERIOD_TIME 60000 /* 2.5ms */ +#define TSADCV14_AUTO_PERIOD_HT_TIME 60000 /* 2.5ms */ #define TSADCV3_Q_MAX_VAL 0x7ff /* 11bit 2047 */ #define TSADCV12_Q_MAX_VAL 0xfff /* 12bit 4095 */ #define TSADCV13_Q_MAX_VAL 0x3ff /* 10bit 1023 */ @@ -319,6 +325,15 @@ struct rockchip_thermal_data { #define RV1126_GRF0_TSADC_SHUT_2CRU (0x30003 << 10) #define RV1126_GRF0_TSADC_SHUT_2GPIO (0x70007 << 12) +#define RV1126B_GRF_TSADC_CON1 0x54 +#define RV1126B_GRF_TSADC_CON6 0x68 +#define RV1126B_CH_EN 0x300 +#define RV1126B_CH_EN_MASK (0x300 << 16) +#define RV1126B_UNLOCK_VALUE 0xa5 +#define RV1126B_UNLOCK_VALUE_MASK (0xff << 16) +#define RV1126B_UNLOCK_TRIGGER BIT(8) +#define RV1126B_UNLOCK_TRIGGER_MASK (BIT(8) << 16) + #define GRF_SARADC_TESTBIT_ON (0x10001 << 2) #define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) #define GRF_TSADC_BANDGAP_CHOPPER_EN (0x10001 << 2) @@ -1257,6 +1272,32 @@ static void rk_tsadcv13_initialize(struct regmap *grf, void __iomem *regs, regs + TSADCV2_AUTO_CON); } +static void rk_tsadcv14_initialize(struct regmap *grf, void __iomem *regs, + enum tshut_polarity tshut_polarity) +{ + writel_relaxed(TSADCV14_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD); + writel_relaxed(TSADCV14_AUTO_PERIOD_TIME, + regs + TSADCV3_AUTO_PERIOD_HT); + writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, + regs + TSADCV3_HIGHT_INT_DEBOUNCE); + writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, + regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE); + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH | + TSADCV2_AUTO_TSHUT_POLARITY_MASK, + regs + TSADCV2_AUTO_CON); + else + writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK, + regs + TSADCV2_AUTO_CON); + + regmap_write(grf, RV1126B_GRF_TSADC_CON6, + RV1126B_CH_EN | RV1126B_CH_EN_MASK); + regmap_write(grf, RV1126B_GRF_TSADC_CON1, + RV1126B_UNLOCK_VALUE | RV1126B_UNLOCK_VALUE_MASK); + regmap_write(grf, RV1126B_GRF_TSADC_CON1, + RV1126B_UNLOCK_TRIGGER | RV1126B_UNLOCK_TRIGGER_MASK); +} + static void rk3506_tsadc_suspend(struct regmap *grf, void __iomem *regs) { regmap_write(grf, RK3506_GRF_TSADC_CON, RV1106_VOGRF_TSADC_TSEN & 0xffff0000); @@ -1356,6 +1397,30 @@ static int rk_tsadcv4_get_temp(const struct chip_tsadc_table *table, return rk_tsadcv2_code_to_temp(table, val, temp); } +static int rk_tsadcv5_get_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int *temp) +{ + u32 val; + + if (chn == 0) + val = readl_relaxed(regs + TSADCV3_DATA(1)); + else if (chn == 1) + val = readl_relaxed(regs + TSADCV3_DATA(0)); + else + return -EINVAL; + + *temp = val & TSADCV6_DATA_MASK; + if (val & TSADC_DATA_SIGN_BIT) + *temp |= TSADC_DATA_NEGATIVE; + *temp *= 10; + if (*temp < MIN_TEMP) + *temp = MIN_TEMP; + else if (*temp > MAX_TEMP) + *temp = MAX_TEMP; + + return 0; +} + static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table, int chn, void __iomem *regs, int temp) { @@ -1417,6 +1482,34 @@ static int rk_tsadcv3_alarm_temp(const struct chip_tsadc_table *table, return 0; } +static int rk_tsadcv4_alarm_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int temp) +{ + u32 alarm_value; + + /* + * In some cases, some sensors didn't need the trip points, the + * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm + * in the end, ignore this case and disable the high temperature + * interrupt. + */ + if (temp == INT_MAX) { + writel_relaxed(TSADCV2_INT_SRC_EN_MASK(chn), + regs + TSADCV3_HT_INT_EN); + + return 0; + } + /* Make sure the value is valid */ + if (temp < MIN_TEMP || temp > MAX_TEMP) + return -ERANGE; + alarm_value = (temp / 10) & TSADCV6_DATA_MASK; + writel_relaxed(alarm_value, regs + TSADCV3_COMP_INT(chn)); + writel_relaxed(TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn), + regs + TSADCV3_HT_INT_EN); + + return 0; +} + static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table, int chn, void __iomem *regs, int temp) { @@ -1455,6 +1548,26 @@ static int rk_tsadcv3_tshut_temp(const struct chip_tsadc_table *table, return 0; } +static int rk_tsadcv4_tshut_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int temp) +{ + u32 tshut_value; + + /* Make sure the value is valid */ + if (temp < MIN_TEMP || temp > MAX_TEMP) + return -ERANGE; + + tshut_value = (temp / 10) & TSADCV6_DATA_MASK; + + writel_relaxed(tshut_value, regs + TSADCV3_COMP_SHUT(chn)); + + /* TSHUT will be valid */ + writel_relaxed(TSADCV3_AUTO_SRC_EN(chn) | TSADCV3_AUTO_SRC_EN_MASK(chn), + regs + TSADCV3_AUTO_SRC_CON); + + return 0; +} + static void rk_tsadcv2_tshut_mode(struct regmap *grf, int chn, void __iomem *regs, enum tshut_mode mode) @@ -1683,6 +1796,21 @@ static const struct rockchip_tsadc_chip rv1126_tsadc_data = { }, }; +static const struct rockchip_tsadc_chip rv1126b_tsadc_data = { + .chn_id = {0, 1}, /* cpu, npu */ + .chn_num = 2, /* two channels for tsadc */ + .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + .initialize = rk_tsadcv14_initialize, + .irq_ack = rk_tsadcv4_irq_ack, + .control = rk_tsadcv4_control, + .get_temp = rk_tsadcv5_get_temp, + .set_alarm_temp = rk_tsadcv4_alarm_temp, + .set_tshut_temp = rk_tsadcv4_tshut_temp, + .set_tshut_mode = rk_tsadcv4_tshut_mode, +}; + static const struct rockchip_tsadc_chip rk1808_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_num = 1, /* one channel for tsadc */ @@ -2080,6 +2208,12 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .data = (void *)&rv1126_tsadc_data, }, #endif +#ifdef CONFIG_CPU_RV1126B + { + .compatible = "rockchip,rv1126b-tsadc", + .data = (void *)&rv1126b_tsadc_data, + }, +#endif #ifdef CONFIG_CPU_RK1808 { .compatible = "rockchip,rk1808-tsadc",