Message ID | 1584611693-3553-3-git-send-email-henry.yen@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Daniel Lezcano |
Headers | show |
Series | Add Mediatek thermal driver for MT7622 | expand |
On 19/03/2020 10:54, Henry Yen wrote: > This patch adds the support for version 2 thermal system(e.g., MT7622 SoC). > The changes include the way of reading calibration data, the way of > converting temperature and hardware initialization specific for version 2 > thermal system. > > Signed-off-by: Henry Yen <henry.yen@mediatek.com> > --- > drivers/thermal/mtk_thermal.c | 100 +++++++++++++++++++++++++++++++++- > 1 file changed, 98 insertions(+), 2 deletions(-) > > diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c > index 13e17c31ba3b..9e6807f6abd4 100644 > --- a/drivers/thermal/mtk_thermal.c > +++ b/drivers/thermal/mtk_thermal.c > @@ -38,6 +38,7 @@ > #define TEMP_MONIDET0 0x014 > #define TEMP_MONIDET1 0x018 > #define TEMP_MSRCTL0 0x038 > +#define TEMP_MSRCTL1 0x03c > #define TEMP_AHBPOLL 0x040 > #define TEMP_AHBTO 0x044 > #define TEMP_ADCPNP0 0x048 > @@ -133,6 +134,20 @@ > #define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1) > #define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1) > > +/* > + * Layout of the fuses providing the calibration data > + * These macros could be used for MT7622. > + */ > +#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff) > +#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff) > +#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f) > +#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f) > +#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff) > +#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff) > +#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff) > +#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1) > +#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1) > + > enum { > VTS1, > VTS2, > @@ -266,8 +281,10 @@ struct mtk_thermal { > > /* Calibration values */ > s32 adc_ge; > + s32 adc_oe; > s32 degc_cali; > s32 o_slope; > + s32 o_slope_sign; > s32 vts[MAX_NUM_VTS]; > > const struct mtk_thermal_data *conf; > @@ -367,7 +384,9 @@ static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 }; > static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, }; > > static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf); > +static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf); > static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw); > +static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw); > > /* > * The MT8173 thermal controller has four banks. Each bank can read up to > @@ -503,8 +522,8 @@ static const struct mtk_thermal_data mt7622_thermal_data = { > .adcpnp = mt7622_adcpnp, > .sensor_mux_values = mt7622_mux_values, > .version = MTK_THERMAL_V2, > - .extract = mtk_thermal_extract_efuse_v1, > - .convert = raw_to_mcelsius_v1, > + .extract = mtk_thermal_extract_efuse_v2, > + .convert = raw_to_mcelsius_v2, Hm, does this mean that patch 1/2 get's fixed here? Please reorganize your patches so that they are correct in the first place and do not needed to be fixed in the same series. Regards, Matthias > }; > > /* > @@ -566,6 +585,36 @@ static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw) > return mt->degc_cali * 500 - tmp; > } > > +static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw) > +{ > + s32 format_1 = 0; > + s32 format_2 = 0; > + s32 g_oe = 1; > + s32 g_gain = 1; > + s32 g_x_roomt = 0; > + s32 tmp = 0; > + > + if (raw == 0) > + return 0; > + > + raw &= 0xfff; > + g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12); > + g_oe = mt->adc_oe - 512; > + format_1 = mt->vts[VTS2] + 3105 - g_oe; > + format_2 = (mt->degc_cali * 10) >> 1; > + g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain; > + > + tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt; > + tmp = tmp * 10 * 100 / 11; > + > + if (mt->o_slope_sign == 0) > + tmp = tmp / (165 - mt->o_slope); > + else > + tmp = tmp / (165 + mt->o_slope); > + > + return (format_2 - tmp) * 100; > +} > + > /** > * mtk_thermal_get_bank - get bank > * @bank: The bank > @@ -831,6 +880,23 @@ static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf) > return 0; > } > > +static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf) > +{ > + if (!CALIB_BUF1_VALID_V2(buf[1])) > + return -EINVAL; > + > + mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]); > + mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]); > + mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]); > + mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]); > + mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]); > + mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]); > + mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]); > + mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]); > + > + return 0; > +} > + > static int mtk_thermal_get_calibration_data(struct device *dev, > struct mtk_thermal *mt) > { > @@ -900,6 +966,28 @@ static const struct of_device_id mtk_thermal_of_match[] = { > }; > MODULE_DEVICE_TABLE(of, mtk_thermal_of_match); > > +static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base) > +{ > + int tmp; > + > + tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1); > + tmp &= ~(0x37); > + tmp |= 0x1; > + writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1); > + udelay(200); > +} > + > +static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt, > + void __iomem *auxadc_base) > +{ > + int tmp; > + > + writel(0x800, auxadc_base + AUXADC_CON1_SET_V); > + writel(0x1, mt->thermal_base + TEMP_MONCTL0); > + tmp = readl(mt->thermal_base + TEMP_MSRCTL1); > + writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1); > +} > + > static int mtk_thermal_probe(struct platform_device *pdev) > { > int ret, i, ctrl_id; > @@ -908,6 +996,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) > struct resource *res; > u64 auxadc_phys_base, apmixed_phys_base; > struct thermal_zone_device *tzdev; > + void __iomem *apmixed_base, *auxadc_base; > > mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); > if (!mt) > @@ -942,6 +1031,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) > return -ENODEV; > } > > + auxadc_base = of_iomap(auxadc, 0); > auxadc_phys_base = of_get_phys_base(auxadc); > > of_node_put(auxadc); > @@ -957,6 +1047,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) > return -ENODEV; > } > > + apmixed_base = of_iomap(apmixedsys, 0); > apmixed_phys_base = of_get_phys_base(apmixedsys); > > of_node_put(apmixedsys); > @@ -982,6 +1073,11 @@ static int mtk_thermal_probe(struct platform_device *pdev) > goto err_disable_clk_auxadc; > } > > + if (mt->conf->version == MTK_THERMAL_V2) { > + mtk_thermal_turn_on_buffer(apmixed_base); > + mtk_thermal_release_periodic_ts(mt, auxadc_base); > + } > + > for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++) > for (i = 0; i < mt->conf->num_banks; i++) > mtk_thermal_init_bank(mt, i, apmixed_phys_base, >
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 13e17c31ba3b..9e6807f6abd4 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -38,6 +38,7 @@ #define TEMP_MONIDET0 0x014 #define TEMP_MONIDET1 0x018 #define TEMP_MSRCTL0 0x038 +#define TEMP_MSRCTL1 0x03c #define TEMP_AHBPOLL 0x040 #define TEMP_AHBTO 0x044 #define TEMP_ADCPNP0 0x048 @@ -133,6 +134,20 @@ #define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1) #define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1) +/* + * Layout of the fuses providing the calibration data + * These macros could be used for MT7622. + */ +#define CALIB_BUF0_ADC_OE_V2(x) (((x) >> 22) & 0x3ff) +#define CALIB_BUF0_ADC_GE_V2(x) (((x) >> 12) & 0x3ff) +#define CALIB_BUF0_DEGC_CALI_V2(x) (((x) >> 6) & 0x3f) +#define CALIB_BUF0_O_SLOPE_V2(x) (((x) >> 0) & 0x3f) +#define CALIB_BUF1_VTS_TS1_V2(x) (((x) >> 23) & 0x1ff) +#define CALIB_BUF1_VTS_TS2_V2(x) (((x) >> 14) & 0x1ff) +#define CALIB_BUF1_VTS_TSABB_V2(x) (((x) >> 5) & 0x1ff) +#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1) +#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1) + enum { VTS1, VTS2, @@ -266,8 +281,10 @@ struct mtk_thermal { /* Calibration values */ s32 adc_ge; + s32 adc_oe; s32 degc_cali; s32 o_slope; + s32 o_slope_sign; s32 vts[MAX_NUM_VTS]; const struct mtk_thermal_data *conf; @@ -367,7 +384,9 @@ static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 }; static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, }; static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf); +static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf); static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw); +static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw); /* * The MT8173 thermal controller has four banks. Each bank can read up to @@ -503,8 +522,8 @@ static const struct mtk_thermal_data mt7622_thermal_data = { .adcpnp = mt7622_adcpnp, .sensor_mux_values = mt7622_mux_values, .version = MTK_THERMAL_V2, - .extract = mtk_thermal_extract_efuse_v1, - .convert = raw_to_mcelsius_v1, + .extract = mtk_thermal_extract_efuse_v2, + .convert = raw_to_mcelsius_v2, }; /* @@ -566,6 +585,36 @@ static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw) return mt->degc_cali * 500 - tmp; } +static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw) +{ + s32 format_1 = 0; + s32 format_2 = 0; + s32 g_oe = 1; + s32 g_gain = 1; + s32 g_x_roomt = 0; + s32 tmp = 0; + + if (raw == 0) + return 0; + + raw &= 0xfff; + g_gain = 10000 + (((mt->adc_ge - 512) * 10000) >> 12); + g_oe = mt->adc_oe - 512; + format_1 = mt->vts[VTS2] + 3105 - g_oe; + format_2 = (mt->degc_cali * 10) >> 1; + g_x_roomt = (((format_1 * 10000) >> 12) * 10000) / g_gain; + + tmp = (((((raw - g_oe) * 10000) >> 12) * 10000) / g_gain) - g_x_roomt; + tmp = tmp * 10 * 100 / 11; + + if (mt->o_slope_sign == 0) + tmp = tmp / (165 - mt->o_slope); + else + tmp = tmp / (165 + mt->o_slope); + + return (format_2 - tmp) * 100; +} + /** * mtk_thermal_get_bank - get bank * @bank: The bank @@ -831,6 +880,23 @@ static int mtk_thermal_extract_efuse_v1(struct mtk_thermal *mt, u32 *buf) return 0; } +static int mtk_thermal_extract_efuse_v2(struct mtk_thermal *mt, u32 *buf) +{ + if (!CALIB_BUF1_VALID_V2(buf[1])) + return -EINVAL; + + mt->adc_oe = CALIB_BUF0_ADC_OE_V2(buf[0]); + mt->adc_ge = CALIB_BUF0_ADC_GE_V2(buf[0]); + mt->degc_cali = CALIB_BUF0_DEGC_CALI_V2(buf[0]); + mt->o_slope = CALIB_BUF0_O_SLOPE_V2(buf[0]); + mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V2(buf[1]); + mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V2(buf[1]); + mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V2(buf[1]); + mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V2(buf[1]); + + return 0; +} + static int mtk_thermal_get_calibration_data(struct device *dev, struct mtk_thermal *mt) { @@ -900,6 +966,28 @@ static const struct of_device_id mtk_thermal_of_match[] = { }; MODULE_DEVICE_TABLE(of, mtk_thermal_of_match); +static void mtk_thermal_turn_on_buffer(void __iomem *apmixed_base) +{ + int tmp; + + tmp = readl(apmixed_base + APMIXED_SYS_TS_CON1); + tmp &= ~(0x37); + tmp |= 0x1; + writel(tmp, apmixed_base + APMIXED_SYS_TS_CON1); + udelay(200); +} + +static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt, + void __iomem *auxadc_base) +{ + int tmp; + + writel(0x800, auxadc_base + AUXADC_CON1_SET_V); + writel(0x1, mt->thermal_base + TEMP_MONCTL0); + tmp = readl(mt->thermal_base + TEMP_MSRCTL1); + writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1); +} + static int mtk_thermal_probe(struct platform_device *pdev) { int ret, i, ctrl_id; @@ -908,6 +996,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) struct resource *res; u64 auxadc_phys_base, apmixed_phys_base; struct thermal_zone_device *tzdev; + void __iomem *apmixed_base, *auxadc_base; mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); if (!mt) @@ -942,6 +1031,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -ENODEV; } + auxadc_base = of_iomap(auxadc, 0); auxadc_phys_base = of_get_phys_base(auxadc); of_node_put(auxadc); @@ -957,6 +1047,7 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -ENODEV; } + apmixed_base = of_iomap(apmixedsys, 0); apmixed_phys_base = of_get_phys_base(apmixedsys); of_node_put(apmixedsys); @@ -982,6 +1073,11 @@ static int mtk_thermal_probe(struct platform_device *pdev) goto err_disable_clk_auxadc; } + if (mt->conf->version == MTK_THERMAL_V2) { + mtk_thermal_turn_on_buffer(apmixed_base); + mtk_thermal_release_periodic_ts(mt, auxadc_base); + } + for (ctrl_id = 0; ctrl_id < mt->conf->num_controller ; ctrl_id++) for (i = 0; i < mt->conf->num_banks; i++) mtk_thermal_init_bank(mt, i, apmixed_phys_base,
This patch adds the support for version 2 thermal system(e.g., MT7622 SoC). The changes include the way of reading calibration data, the way of converting temperature and hardware initialization specific for version 2 thermal system. Signed-off-by: Henry Yen <henry.yen@mediatek.com> --- drivers/thermal/mtk_thermal.c | 100 +++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-)