2019-05-27 08:55:21 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2015-11-30 12:42:32 +01:00
/*
* Copyright ( c ) 2015 MediaTek Inc .
* Author : Hanyi Wu < hanyi . wu @ mediatek . com >
* Sascha Hauer < s . hauer @ pengutronix . de >
2016-08-18 11:50:52 +08:00
* Dawei Chien < dawei . chien @ mediatek . com >
2017-08-01 15:28:31 +08:00
* Louis Yu < louis . yu @ mediatek . com >
2015-11-30 12:42:32 +01:00
*/
# include <linux/clk.h>
# include <linux/delay.h>
# include <linux/interrupt.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/nvmem-consumer.h>
# include <linux/of.h>
# include <linux/of_address.h>
2016-08-18 11:50:52 +08:00
# include <linux/of_device.h>
2015-11-30 12:42:32 +01:00
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <linux/io.h>
# include <linux/thermal.h>
# include <linux/reset.h>
# include <linux/types.h>
/* AUXADC Registers */
# define AUXADC_CON1_SET_V 0x008
# define AUXADC_CON1_CLR_V 0x00c
# define AUXADC_CON2_V 0x010
# define AUXADC_DATA(channel) (0x14 + (channel) * 4)
# define APMIXED_SYS_TS_CON1 0x604
/* Thermal Controller Registers */
# define TEMP_MONCTL0 0x000
# define TEMP_MONCTL1 0x004
# define TEMP_MONCTL2 0x008
# define TEMP_MONIDET0 0x014
# define TEMP_MONIDET1 0x018
# define TEMP_MSRCTL0 0x038
2020-04-30 17:14:34 +08:00
# define TEMP_MSRCTL1 0x03c
2015-11-30 12:42:32 +01:00
# define TEMP_AHBPOLL 0x040
# define TEMP_AHBTO 0x044
# define TEMP_ADCPNP0 0x048
# define TEMP_ADCPNP1 0x04c
# define TEMP_ADCPNP2 0x050
# define TEMP_ADCPNP3 0x0b4
# define TEMP_ADCMUX 0x054
# define TEMP_ADCEN 0x060
# define TEMP_PNPMUXADDR 0x064
# define TEMP_ADCMUXADDR 0x068
# define TEMP_ADCENADDR 0x074
# define TEMP_ADCVALIDADDR 0x078
# define TEMP_ADCVOLTADDR 0x07c
# define TEMP_RDCTRL 0x080
# define TEMP_ADCVALIDMASK 0x084
# define TEMP_ADCVOLTAGESHIFT 0x088
# define TEMP_ADCWRITECTRL 0x08c
# define TEMP_MSR0 0x090
# define TEMP_MSR1 0x094
# define TEMP_MSR2 0x098
# define TEMP_MSR3 0x0B8
# define TEMP_SPARE0 0x0f0
2019-02-01 15:38:13 +08:00
# define TEMP_ADCPNP0_1 0x148
# define TEMP_ADCPNP1_1 0x14c
# define TEMP_ADCPNP2_1 0x150
# define TEMP_MSR0_1 0x190
# define TEMP_MSR1_1 0x194
# define TEMP_MSR2_1 0x198
# define TEMP_ADCPNP3_1 0x1b4
# define TEMP_MSR3_1 0x1B8
2015-11-30 12:42:32 +01:00
# define PTPCORESEL 0x400
# define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff)
2016-02-18 07:43:57 -08:00
# define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff) << 16)
2015-11-30 12:42:32 +01:00
# define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff)
# define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x) (x)
# define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0)
# define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1)
# define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5)
# define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit)
2016-08-18 11:50:52 +08:00
/* MT8173 thermal sensors */
2015-11-30 12:42:32 +01:00
# define MT8173_TS1 0
# define MT8173_TS2 1
# define MT8173_TS3 2
# define MT8173_TS4 3
# define MT8173_TSABB 4
/* AUXADC channel 11 is used for the temperature sensors */
# define MT8173_TEMP_AUXADC_CHANNEL 11
/* The total number of temperature sensors in the MT8173 */
# define MT8173_NUM_SENSORS 5
/* The number of banks in the MT8173 */
# define MT8173_NUM_ZONES 4
/* The number of sensing points per bank */
# define MT8173_NUM_SENSORS_PER_ZONE 4
2019-02-01 15:38:10 +08:00
/* The number of controller in the MT8173 */
# define MT8173_NUM_CONTROLLER 1
2019-02-01 15:38:09 +08:00
/* The calibration coefficient of sensor */
# define MT8173_CALIBRATION 165
2016-08-18 11:50:52 +08:00
/*
* Layout of the fuses providing the calibration data
2019-02-01 15:38:13 +08:00
* These macros could be used for MT8183 , MT8173 , MT2701 , and MT2712 .
* MT8183 has 6 sensors and needs 6 VTS calibration data .
2017-08-01 15:28:32 +08:00
* MT8173 has 5 sensors and needs 5 VTS calibration data .
* MT2701 has 3 sensors and needs 3 VTS calibration data .
* MT2712 has 4 sensors and needs 4 VTS calibration data .
2016-08-18 11:50:52 +08:00
*/
2020-04-30 17:14:33 +08:00
# define CALIB_BUF0_VALID_V1 BIT(0)
# define CALIB_BUF1_ADC_GE_V1(x) (((x) >> 22) & 0x3ff)
# define CALIB_BUF0_VTS_TS1_V1(x) (((x) >> 17) & 0x1ff)
# define CALIB_BUF0_VTS_TS2_V1(x) (((x) >> 8) & 0x1ff)
# define CALIB_BUF1_VTS_TS3_V1(x) (((x) >> 0) & 0x1ff)
# define CALIB_BUF2_VTS_TS4_V1(x) (((x) >> 23) & 0x1ff)
# define CALIB_BUF2_VTS_TS5_V1(x) (((x) >> 5) & 0x1ff)
# define CALIB_BUF2_VTS_TSABB_V1(x) (((x) >> 14) & 0x1ff)
# define CALIB_BUF0_DEGC_CALI_V1(x) (((x) >> 1) & 0x3f)
# define CALIB_BUF0_O_SLOPE_V1(x) (((x) >> 26) & 0x3f)
# define CALIB_BUF0_O_SLOPE_SIGN_V1(x) (((x) >> 7) & 0x1)
# define CALIB_BUF1_ID_V1(x) (((x) >> 9) & 0x1)
2019-02-01 15:38:08 +08:00
2020-04-30 17:14:34 +08:00
/*
* 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)
2019-02-01 15:38:08 +08:00
enum {
VTS1 ,
VTS2 ,
VTS3 ,
VTS4 ,
2019-02-01 15:38:13 +08:00
VTS5 ,
2019-02-01 15:38:08 +08:00
VTSABB ,
MAX_NUM_VTS ,
} ;
2015-11-30 12:42:32 +01:00
2020-04-30 17:14:34 +08:00
enum mtk_thermal_version {
MTK_THERMAL_V1 = 1 ,
MTK_THERMAL_V2 ,
} ;
2016-08-18 11:50:52 +08:00
/* MT2701 thermal sensors */
# define MT2701_TS1 0
# define MT2701_TS2 1
# define MT2701_TSABB 2
/* AUXADC channel 11 is used for the temperature sensors */
# define MT2701_TEMP_AUXADC_CHANNEL 11
/* The total number of temperature sensors in the MT2701 */
# define MT2701_NUM_SENSORS 3
/* The number of sensing points per bank */
# define MT2701_NUM_SENSORS_PER_ZONE 3
2019-02-01 15:38:10 +08:00
/* The number of controller in the MT2701 */
# define MT2701_NUM_CONTROLLER 1
2019-02-01 15:38:09 +08:00
/* The calibration coefficient of sensor */
# define MT2701_CALIBRATION 165
2017-08-01 15:28:31 +08:00
/* MT2712 thermal sensors */
# define MT2712_TS1 0
# define MT2712_TS2 1
# define MT2712_TS3 2
# define MT2712_TS4 3
/* AUXADC channel 11 is used for the temperature sensors */
# define MT2712_TEMP_AUXADC_CHANNEL 11
/* The total number of temperature sensors in the MT2712 */
# define MT2712_NUM_SENSORS 4
/* The number of sensing points per bank */
# define MT2712_NUM_SENSORS_PER_ZONE 4
2019-02-01 15:38:10 +08:00
/* The number of controller in the MT2712 */
# define MT2712_NUM_CONTROLLER 1
2019-02-01 15:38:09 +08:00
/* The calibration coefficient of sensor */
# define MT2712_CALIBRATION 165
2018-02-17 16:49:02 +08:00
# define MT7622_TEMP_AUXADC_CHANNEL 11
# define MT7622_NUM_SENSORS 1
# define MT7622_NUM_ZONES 1
# define MT7622_NUM_SENSORS_PER_ZONE 1
# define MT7622_TS1 0
2019-02-01 15:38:10 +08:00
# define MT7622_NUM_CONTROLLER 1
2018-02-17 16:49:02 +08:00
2019-01-09 13:57:24 +08:00
/* The maximum number of banks */
# define MAX_NUM_ZONES 8
2019-02-01 15:38:09 +08:00
/* The calibration coefficient of sensor */
# define MT7622_CALIBRATION 165
2019-02-01 15:38:13 +08:00
/* MT8183 thermal sensors */
# define MT8183_TS1 0
# define MT8183_TS2 1
# define MT8183_TS3 2
# define MT8183_TS4 3
# define MT8183_TS5 4
# define MT8183_TSABB 5
/* AUXADC channel is used for the temperature sensors */
# define MT8183_TEMP_AUXADC_CHANNEL 11
/* The total number of temperature sensors in the MT8183 */
# define MT8183_NUM_SENSORS 6
2020-03-23 20:15:35 +08:00
/* The number of banks in the MT8183 */
# define MT8183_NUM_ZONES 1
2019-02-01 15:38:13 +08:00
/* The number of sensing points per bank */
# define MT8183_NUM_SENSORS_PER_ZONE 6
/* The number of controller in the MT8183 */
# define MT8183_NUM_CONTROLLER 2
/* The calibration coefficient of sensor */
# define MT8183_CALIBRATION 153
2015-11-30 12:42:32 +01:00
struct mtk_thermal ;
2016-08-18 11:50:52 +08:00
struct thermal_bank_cfg {
unsigned int num_sensors ;
const int * sensors ;
} ;
2015-11-30 12:42:32 +01:00
struct mtk_thermal_bank {
struct mtk_thermal * mt ;
int id ;
} ;
2016-08-18 11:50:52 +08:00
struct mtk_thermal_data {
s32 num_banks ;
s32 num_sensors ;
s32 auxadc_channel ;
2019-02-01 15:38:08 +08:00
const int * vts_index ;
2016-08-18 11:50:52 +08:00
const int * sensor_mux_values ;
const int * msr ;
const int * adcpnp ;
2019-02-01 15:38:09 +08:00
const int cali_val ;
2019-02-01 15:38:10 +08:00
const int num_controller ;
const int * controller_offset ;
2019-02-01 15:38:11 +08:00
bool need_switch_bank ;
2019-01-09 13:57:24 +08:00
struct thermal_bank_cfg bank_data [ MAX_NUM_ZONES ] ;
2020-04-30 17:14:34 +08:00
enum mtk_thermal_version version ;
2016-08-18 11:50:52 +08:00
} ;
2015-11-30 12:42:32 +01:00
struct mtk_thermal {
struct device * dev ;
void __iomem * thermal_base ;
struct clk * clk_peri_therm ;
struct clk * clk_auxadc ;
2016-02-18 07:43:57 -08:00
/* lock: for getting and putting banks */
2015-11-30 12:42:32 +01:00
struct mutex lock ;
/* Calibration values */
s32 adc_ge ;
2020-04-30 17:14:34 +08:00
s32 adc_oe ;
2015-11-30 12:42:32 +01:00
s32 degc_cali ;
s32 o_slope ;
2020-04-30 17:14:34 +08:00
s32 o_slope_sign ;
2019-02-01 15:38:08 +08:00
s32 vts [ MAX_NUM_VTS ] ;
2015-11-30 12:42:32 +01:00
2016-08-18 11:50:52 +08:00
const struct mtk_thermal_data * conf ;
2019-01-09 13:57:24 +08:00
struct mtk_thermal_bank banks [ MAX_NUM_ZONES ] ;
2015-11-30 12:42:32 +01:00
} ;
2019-02-01 15:38:13 +08:00
/* MT8183 thermal sensor data */
static const int mt8183_bank_data [ MT8183_NUM_SENSORS ] = {
MT8183_TS1 , MT8183_TS2 , MT8183_TS3 , MT8183_TS4 , MT8183_TS5 , MT8183_TSABB
} ;
static const int mt8183_msr [ MT8183_NUM_SENSORS_PER_ZONE ] = {
TEMP_MSR0_1 , TEMP_MSR1_1 , TEMP_MSR2_1 , TEMP_MSR1 , TEMP_MSR0 , TEMP_MSR3_1
} ;
static const int mt8183_adcpnp [ MT8183_NUM_SENSORS_PER_ZONE ] = {
TEMP_ADCPNP0_1 , TEMP_ADCPNP1_1 , TEMP_ADCPNP2_1 ,
TEMP_ADCPNP1 , TEMP_ADCPNP0 , TEMP_ADCPNP3_1
} ;
static const int mt8183_mux_values [ MT8183_NUM_SENSORS ] = { 0 , 1 , 2 , 3 , 4 , 0 } ;
static const int mt8183_tc_offset [ MT8183_NUM_CONTROLLER ] = { 0x0 , 0x100 } ;
static const int mt8183_vts_index [ MT8183_NUM_SENSORS ] = {
VTS1 , VTS2 , VTS3 , VTS4 , VTS5 , VTSABB
} ;
2016-08-18 11:50:52 +08:00
/* MT8173 thermal sensor data */
2016-12-28 14:16:45 +05:30
static const int mt8173_bank_data [ MT8173_NUM_ZONES ] [ 3 ] = {
2016-08-18 11:50:52 +08:00
{ MT8173_TS2 , MT8173_TS3 } ,
{ MT8173_TS2 , MT8173_TS4 } ,
{ MT8173_TS1 , MT8173_TS2 , MT8173_TSABB } ,
{ MT8173_TS2 } ,
2015-11-30 12:42:32 +01:00
} ;
2016-12-28 14:16:45 +05:30
static const int mt8173_msr [ MT8173_NUM_SENSORS_PER_ZONE ] = {
2017-02-21 20:26:52 +08:00
TEMP_MSR0 , TEMP_MSR1 , TEMP_MSR2 , TEMP_MSR3
2016-08-18 11:50:52 +08:00
} ;
2015-11-30 12:42:32 +01:00
2016-12-28 14:16:45 +05:30
static const int mt8173_adcpnp [ MT8173_NUM_SENSORS_PER_ZONE ] = {
2016-08-18 11:50:52 +08:00
TEMP_ADCPNP0 , TEMP_ADCPNP1 , TEMP_ADCPNP2 , TEMP_ADCPNP3
} ;
2016-12-28 14:16:45 +05:30
static const int mt8173_mux_values [ MT8173_NUM_SENSORS ] = { 0 , 1 , 2 , 3 , 16 } ;
2019-02-01 15:38:10 +08:00
static const int mt8173_tc_offset [ MT8173_NUM_CONTROLLER ] = { 0x0 , } ;
2016-08-18 11:50:52 +08:00
2019-02-01 15:38:08 +08:00
static const int mt8173_vts_index [ MT8173_NUM_SENSORS ] = {
VTS1 , VTS2 , VTS3 , VTS4 , VTSABB
} ;
2016-08-18 11:50:52 +08:00
/* MT2701 thermal sensor data */
2016-12-28 14:16:45 +05:30
static const int mt2701_bank_data [ MT2701_NUM_SENSORS ] = {
2016-08-18 11:50:52 +08:00
MT2701_TS1 , MT2701_TS2 , MT2701_TSABB
} ;
2016-12-28 14:16:45 +05:30
static const int mt2701_msr [ MT2701_NUM_SENSORS_PER_ZONE ] = {
2016-08-18 11:50:52 +08:00
TEMP_MSR0 , TEMP_MSR1 , TEMP_MSR2
} ;
2016-12-28 14:16:45 +05:30
static const int mt2701_adcpnp [ MT2701_NUM_SENSORS_PER_ZONE ] = {
2016-08-18 11:50:52 +08:00
TEMP_ADCPNP0 , TEMP_ADCPNP1 , TEMP_ADCPNP2
} ;
2016-12-28 14:16:45 +05:30
static const int mt2701_mux_values [ MT2701_NUM_SENSORS ] = { 0 , 1 , 16 } ;
2019-02-01 15:38:10 +08:00
static const int mt2701_tc_offset [ MT2701_NUM_CONTROLLER ] = { 0x0 , } ;
2016-08-18 11:50:52 +08:00
2019-02-01 15:38:08 +08:00
static const int mt2701_vts_index [ MT2701_NUM_SENSORS ] = {
VTS1 , VTS2 , VTS3
} ;
2017-08-01 15:28:31 +08:00
/* MT2712 thermal sensor data */
static const int mt2712_bank_data [ MT2712_NUM_SENSORS ] = {
MT2712_TS1 , MT2712_TS2 , MT2712_TS3 , MT2712_TS4
} ;
static const int mt2712_msr [ MT2712_NUM_SENSORS_PER_ZONE ] = {
TEMP_MSR0 , TEMP_MSR1 , TEMP_MSR2 , TEMP_MSR3
} ;
static const int mt2712_adcpnp [ MT2712_NUM_SENSORS_PER_ZONE ] = {
TEMP_ADCPNP0 , TEMP_ADCPNP1 , TEMP_ADCPNP2 , TEMP_ADCPNP3
} ;
static const int mt2712_mux_values [ MT2712_NUM_SENSORS ] = { 0 , 1 , 2 , 3 } ;
2019-02-01 15:38:10 +08:00
static const int mt2712_tc_offset [ MT2712_NUM_CONTROLLER ] = { 0x0 , } ;
2017-08-01 15:28:31 +08:00
2019-02-01 15:38:08 +08:00
static const int mt2712_vts_index [ MT2712_NUM_SENSORS ] = {
VTS1 , VTS2 , VTS3 , VTS4
} ;
2018-02-17 16:49:02 +08:00
/* MT7622 thermal sensor data */
static const int mt7622_bank_data [ MT7622_NUM_SENSORS ] = { MT7622_TS1 , } ;
static const int mt7622_msr [ MT7622_NUM_SENSORS_PER_ZONE ] = { TEMP_MSR0 , } ;
static const int mt7622_adcpnp [ MT7622_NUM_SENSORS_PER_ZONE ] = { TEMP_ADCPNP0 , } ;
static const int mt7622_mux_values [ MT7622_NUM_SENSORS ] = { 0 , } ;
2019-02-01 15:38:08 +08:00
static const int mt7622_vts_index [ MT7622_NUM_SENSORS ] = { VTS1 } ;
2019-02-01 15:38:10 +08:00
static const int mt7622_tc_offset [ MT7622_NUM_CONTROLLER ] = { 0x0 , } ;
2018-02-17 16:49:02 +08:00
2019-11-20 21:15:15 +05:30
/*
2015-11-30 12:42:32 +01:00
* The MT8173 thermal controller has four banks . Each bank can read up to
* four temperature sensors simultaneously . The MT8173 has a total of 5
* temperature sensors . We use each bank to measure a certain area of the
* SoC . Since TS2 is located centrally in the SoC it is influenced by multiple
* areas , hence is used in different banks .
*
* The thermal core only gets the maximum temperature of all banks , so
* the bank concept wouldn ' t be necessary here . However , the SVS ( Smart
* Voltage Scaling ) unit makes its decisions based on the same bank
* data , and this indeed needs the temperatures of the individual banks
* for making better decisions .
*/
2016-08-18 11:50:52 +08:00
static const struct mtk_thermal_data mt8173_thermal_data = {
. auxadc_channel = MT8173_TEMP_AUXADC_CHANNEL ,
. num_banks = MT8173_NUM_ZONES ,
. num_sensors = MT8173_NUM_SENSORS ,
2019-02-01 15:38:08 +08:00
. vts_index = mt8173_vts_index ,
2019-02-01 15:38:09 +08:00
. cali_val = MT8173_CALIBRATION ,
2019-02-01 15:38:10 +08:00
. num_controller = MT8173_NUM_CONTROLLER ,
. controller_offset = mt8173_tc_offset ,
2019-02-01 15:38:11 +08:00
. need_switch_bank = true ,
2016-08-18 11:50:52 +08:00
. bank_data = {
{
. num_sensors = 2 ,
. sensors = mt8173_bank_data [ 0 ] ,
} , {
. num_sensors = 2 ,
. sensors = mt8173_bank_data [ 1 ] ,
} , {
. num_sensors = 3 ,
. sensors = mt8173_bank_data [ 2 ] ,
} , {
. num_sensors = 1 ,
. sensors = mt8173_bank_data [ 3 ] ,
} ,
2015-11-30 12:42:32 +01:00
} ,
2016-08-18 11:50:52 +08:00
. msr = mt8173_msr ,
. adcpnp = mt8173_adcpnp ,
. sensor_mux_values = mt8173_mux_values ,
2020-04-30 17:14:34 +08:00
. version = MTK_THERMAL_V1 ,
2015-11-30 12:42:32 +01:00
} ;
2019-11-20 21:15:15 +05:30
/*
2016-08-18 11:50:52 +08:00
* The MT2701 thermal controller has one bank , which can read up to
* three temperature sensors simultaneously . The MT2701 has a total of 3
* temperature sensors .
*
* The thermal core only gets the maximum temperature of this one bank ,
* so the bank concept wouldn ' t be necessary here . However , the SVS ( Smart
* Voltage Scaling ) unit makes its decisions based on the same bank
* data .
*/
static const struct mtk_thermal_data mt2701_thermal_data = {
. auxadc_channel = MT2701_TEMP_AUXADC_CHANNEL ,
. num_banks = 1 ,
. num_sensors = MT2701_NUM_SENSORS ,
2019-02-01 15:38:08 +08:00
. vts_index = mt2701_vts_index ,
2019-02-01 15:38:09 +08:00
. cali_val = MT2701_CALIBRATION ,
2019-02-01 15:38:10 +08:00
. num_controller = MT2701_NUM_CONTROLLER ,
. controller_offset = mt2701_tc_offset ,
2019-02-01 15:38:11 +08:00
. need_switch_bank = true ,
2016-08-18 11:50:52 +08:00
. bank_data = {
{
. num_sensors = 3 ,
. sensors = mt2701_bank_data ,
} ,
2015-11-30 12:42:32 +01:00
} ,
2016-08-18 11:50:52 +08:00
. msr = mt2701_msr ,
. adcpnp = mt2701_adcpnp ,
. sensor_mux_values = mt2701_mux_values ,
2020-04-30 17:14:34 +08:00
. version = MTK_THERMAL_V1 ,
2015-11-30 12:42:32 +01:00
} ;
2019-11-20 21:15:15 +05:30
/*
2017-08-01 15:28:31 +08:00
* The MT2712 thermal controller has one bank , which can read up to
* four temperature sensors simultaneously . The MT2712 has a total of 4
* temperature sensors .
*
* The thermal core only gets the maximum temperature of this one bank ,
* so the bank concept wouldn ' t be necessary here . However , the SVS ( Smart
* Voltage Scaling ) unit makes its decisions based on the same bank
* data .
*/
static const struct mtk_thermal_data mt2712_thermal_data = {
. auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL ,
. num_banks = 1 ,
. num_sensors = MT2712_NUM_SENSORS ,
2019-02-01 15:38:08 +08:00
. vts_index = mt2712_vts_index ,
2019-02-01 15:38:09 +08:00
. cali_val = MT2712_CALIBRATION ,
2019-02-01 15:38:10 +08:00
. num_controller = MT2712_NUM_CONTROLLER ,
. controller_offset = mt2712_tc_offset ,
2019-02-01 15:38:11 +08:00
. need_switch_bank = true ,
2017-08-01 15:28:31 +08:00
. bank_data = {
{
. num_sensors = 4 ,
. sensors = mt2712_bank_data ,
} ,
} ,
. msr = mt2712_msr ,
. adcpnp = mt2712_adcpnp ,
. sensor_mux_values = mt2712_mux_values ,
2020-04-30 17:14:34 +08:00
. version = MTK_THERMAL_V1 ,
2017-08-01 15:28:31 +08:00
} ;
2018-02-17 16:49:02 +08:00
/*
* MT7622 have only one sensing point which uses AUXADC Channel 11 for raw data
* access .
*/
static const struct mtk_thermal_data mt7622_thermal_data = {
. auxadc_channel = MT7622_TEMP_AUXADC_CHANNEL ,
. num_banks = MT7622_NUM_ZONES ,
. num_sensors = MT7622_NUM_SENSORS ,
2019-02-01 15:38:08 +08:00
. vts_index = mt7622_vts_index ,
2019-02-01 15:38:09 +08:00
. cali_val = MT7622_CALIBRATION ,
2019-02-01 15:38:10 +08:00
. num_controller = MT7622_NUM_CONTROLLER ,
. controller_offset = mt7622_tc_offset ,
2019-02-01 15:38:11 +08:00
. need_switch_bank = true ,
2018-02-17 16:49:02 +08:00
. bank_data = {
{
. num_sensors = 1 ,
. sensors = mt7622_bank_data ,
} ,
} ,
. msr = mt7622_msr ,
. adcpnp = mt7622_adcpnp ,
. sensor_mux_values = mt7622_mux_values ,
2020-04-30 17:14:34 +08:00
. version = MTK_THERMAL_V2 ,
2018-02-17 16:49:02 +08:00
} ;
2019-11-20 21:15:15 +05:30
/*
2019-02-01 15:38:13 +08:00
* The MT8183 thermal controller has one bank for the current SW framework .
* The MT8183 has a total of 6 temperature sensors .
* There are two thermal controller to control the six sensor .
* The first one bind 2 sensor , and the other bind 4 sensors .
* The thermal core only gets the maximum temperature of all sensor , so
* the bank concept wouldn ' t be necessary here . However , the SVS ( Smart
* Voltage Scaling ) unit makes its decisions based on the same bank
* data , and this indeed needs the temperatures of the individual banks
* for making better decisions .
*/
static const struct mtk_thermal_data mt8183_thermal_data = {
. auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL ,
2020-03-23 20:15:35 +08:00
. num_banks = MT8183_NUM_ZONES ,
2019-02-01 15:38:13 +08:00
. num_sensors = MT8183_NUM_SENSORS ,
. vts_index = mt8183_vts_index ,
. cali_val = MT8183_CALIBRATION ,
. num_controller = MT8183_NUM_CONTROLLER ,
. controller_offset = mt8183_tc_offset ,
. need_switch_bank = false ,
. bank_data = {
{
. num_sensors = 6 ,
. sensors = mt8183_bank_data ,
} ,
} ,
. msr = mt8183_msr ,
. adcpnp = mt8183_adcpnp ,
. sensor_mux_values = mt8183_mux_values ,
2020-04-30 17:14:34 +08:00
. version = MTK_THERMAL_V1 ,
2019-02-01 15:38:13 +08:00
} ;
2015-11-30 12:42:32 +01:00
/**
* raw_to_mcelsius - convert a raw ADC value to mcelsius
2019-11-20 21:15:15 +05:30
* @ mt : The thermal controller
* @ sensno : sensor number
2015-11-30 12:42:32 +01:00
* @ raw : raw ADC value
*
* This converts the raw ADC value to mcelsius using the SoC specific
* calibration constants
*/
2020-04-30 17:14:33 +08:00
static int raw_to_mcelsius_v1 ( struct mtk_thermal * mt , int sensno , s32 raw )
2015-11-30 12:42:32 +01:00
{
s32 tmp ;
raw & = 0xfff ;
tmp = 203450520 < < 3 ;
2019-02-01 15:38:09 +08:00
tmp / = mt - > conf - > cali_val + mt - > o_slope ;
2015-11-30 12:42:32 +01:00
tmp / = 10000 + mt - > adc_ge ;
tmp * = raw - mt - > vts [ sensno ] - 3350 ;
tmp > > = 3 ;
return mt - > degc_cali * 500 - tmp ;
}
2020-04-30 17:14:34 +08:00
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 ;
}
2015-11-30 12:42:32 +01:00
/**
* mtk_thermal_get_bank - get bank
* @ bank : The bank
*
* The bank registers are banked , we have to select a bank in the
* PTPCORESEL register to access it .
*/
static void mtk_thermal_get_bank ( struct mtk_thermal_bank * bank )
{
struct mtk_thermal * mt = bank - > mt ;
u32 val ;
2019-02-01 15:38:11 +08:00
if ( mt - > conf - > need_switch_bank ) {
mutex_lock ( & mt - > lock ) ;
2015-11-30 12:42:32 +01:00
2019-02-01 15:38:11 +08:00
val = readl ( mt - > thermal_base + PTPCORESEL ) ;
val & = ~ 0xf ;
val | = bank - > id ;
writel ( val , mt - > thermal_base + PTPCORESEL ) ;
}
2015-11-30 12:42:32 +01:00
}
/**
* mtk_thermal_put_bank - release bank
* @ bank : The bank
*
* release a bank previously taken with mtk_thermal_get_bank ,
*/
static void mtk_thermal_put_bank ( struct mtk_thermal_bank * bank )
{
struct mtk_thermal * mt = bank - > mt ;
2019-02-01 15:38:11 +08:00
if ( mt - > conf - > need_switch_bank )
mutex_unlock ( & mt - > lock ) ;
2015-11-30 12:42:32 +01:00
}
/**
* mtk_thermal_bank_temperature - get the temperature of a bank
* @ bank : The bank
*
* The temperature of a bank is considered the maximum temperature of
* the sensors associated to the bank .
*/
static int mtk_thermal_bank_temperature ( struct mtk_thermal_bank * bank )
{
struct mtk_thermal * mt = bank - > mt ;
2016-08-18 11:50:52 +08:00
const struct mtk_thermal_data * conf = mt - > conf ;
2016-02-18 07:43:57 -08:00
int i , temp = INT_MIN , max = INT_MIN ;
2015-11-30 12:42:32 +01:00
u32 raw ;
2016-08-18 11:50:52 +08:00
for ( i = 0 ; i < conf - > bank_data [ bank - > id ] . num_sensors ; i + + ) {
Revert "thermal: mediatek: fix register index error"
This reverts commit eb9aecd90d1a39601e91cd08b90d5fee51d321a6
The above patch is supposed to fix a register index error on mt2701. It
is not clear if the problem solved is a hang or just an invalid value
returned, my guess is the second. The patch introduces, though, a new
hang on MT8173 device making them unusable. So, seems reasonable, revert
the patch because introduces a worst issue.
The reason I send a revert instead of trying to fix the issue for MT8173
is because the information needed to fix the issue is in the datasheet
and is not public. So I am not really able to fix it.
Fixes the following bug when CONFIG_MTK_THERMAL is set on MT8173
devices.
[ 2.222488] Unable to handle kernel paging request at virtual address ffff8000125f5001
[ 2.230421] Mem abort info:
[ 2.233207] ESR = 0x96000021
[ 2.236261] EC = 0x25: DABT (current EL), IL = 32 bits
[ 2.241571] SET = 0, FnV = 0
[ 2.244623] EA = 0, S1PTW = 0
[ 2.247762] Data abort info:
[ 2.250640] ISV = 0, ISS = 0x00000021
[ 2.254473] CM = 0, WnR = 0
[ 2.257544] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041850000
[ 2.264251] [ffff8000125f5001] pgd=000000013ffff003, pud=000000013fffe003, pmd=000000013fff9003, pte=006800001100b707
[ 2.274867] Internal error: Oops: 96000021 [#1] PREEMPT SMP
[ 2.280432] Modules linked in:
[ 2.283483] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.7.0-rc6+ #162
[ 2.289914] Hardware name: Google Elm (DT)
[ 2.294003] pstate: 20000005 (nzCv daif -PAN -UAO)
[ 2.298792] pc : mtk_read_temp+0xb8/0x1c8
[ 2.302793] lr : mtk_read_temp+0x7c/0x1c8
[ 2.306794] sp : ffff80001003b930
[ 2.310100] x29: ffff80001003b930 x28: 0000000000000000
[ 2.315404] x27: 0000000000000002 x26: ffff0000f9550b10
[ 2.320709] x25: ffff0000f9550a80 x24: 0000000000000090
[ 2.326014] x23: ffff80001003ba24 x22: 00000000610344c0
[ 2.331318] x21: 0000000000002710 x20: 00000000000001f4
[ 2.336622] x19: 0000000000030d40 x18: ffff800011742ec0
[ 2.341926] x17: 0000000000000001 x16: 0000000000000001
[ 2.347230] x15: ffffffffffffffff x14: ffffff0000000000
[ 2.352535] x13: ffffffffffffffff x12: 0000000000000028
[ 2.357839] x11: 0000000000000003 x10: ffff800011295ec8
[ 2.363143] x9 : 000000000000291b x8 : 0000000000000002
[ 2.368447] x7 : 00000000000000a8 x6 : 0000000000000004
[ 2.373751] x5 : 0000000000000000 x4 : ffff800011295cb0
[ 2.379055] x3 : 0000000000000002 x2 : ffff8000125f5001
[ 2.384359] x1 : 0000000000000001 x0 : ffff0000f9550a80
[ 2.389665] Call trace:
[ 2.392105] mtk_read_temp+0xb8/0x1c8
[ 2.395760] of_thermal_get_temp+0x2c/0x40
[ 2.399849] thermal_zone_get_temp+0x78/0x160
[ 2.404198] thermal_zone_device_update.part.0+0x3c/0x1f8
[ 2.409589] thermal_zone_device_update+0x34/0x48
[ 2.414286] of_thermal_set_mode+0x58/0x88
[ 2.418375] thermal_zone_of_sensor_register+0x1a8/0x1d8
[ 2.423679] devm_thermal_zone_of_sensor_register+0x64/0xb0
[ 2.429242] mtk_thermal_probe+0x690/0x7d0
[ 2.433333] platform_drv_probe+0x5c/0xb0
[ 2.437335] really_probe+0xe4/0x448
[ 2.440901] driver_probe_device+0xe8/0x140
[ 2.445077] device_driver_attach+0x7c/0x88
[ 2.449252] __driver_attach+0xac/0x178
[ 2.453082] bus_for_each_dev+0x78/0xc8
[ 2.456909] driver_attach+0x2c/0x38
[ 2.460476] bus_add_driver+0x14c/0x230
[ 2.464304] driver_register+0x6c/0x128
[ 2.468131] __platform_driver_register+0x50/0x60
[ 2.472831] mtk_thermal_driver_init+0x24/0x30
[ 2.477268] do_one_initcall+0x50/0x298
[ 2.481098] kernel_init_freeable+0x1ec/0x264
[ 2.485450] kernel_init+0x1c/0x110
[ 2.488931] ret_from_fork+0x10/0x1c
[ 2.492502] Code: f9401081 f9400402 b8a67821 8b010042 (b9400042)
[ 2.498599] ---[ end trace e43e3105ed27dc99 ]---
[ 2.503367] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[ 2.511020] SMP: stopping secondary CPUs
[ 2.514941] Kernel Offset: disabled
[ 2.518421] CPU features: 0x090002,25006005
[ 2.522595] Memory Limit: none
[ 2.525644] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]--
Cc: Michael Kao <michael.kao@mediatek.com>
Fixes: eb9aecd90d1a ("thermal: mediatek: fix register index error")
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20200707103412.1010823-1-enric.balletbo@collabora.com
2020-07-07 12:34:12 +02:00
raw = readl ( mt - > thermal_base + conf - > msr [ i ] ) ;
2015-11-30 12:42:32 +01:00
2020-04-30 17:14:34 +08:00
if ( mt - > conf - > version = = MTK_THERMAL_V1 ) {
temp = raw_to_mcelsius_v1 (
mt , conf - > bank_data [ bank - > id ] . sensors [ i ] , raw ) ;
} else {
temp = raw_to_mcelsius_v2 (
mt , conf - > bank_data [ bank - > id ] . sensors [ i ] , raw ) ;
}
2015-11-30 12:42:32 +01:00
/*
* The first read of a sensor often contains very high bogus
* temperature value . Filter these out so that the system does
* not immediately shut down .
*/
if ( temp > 200000 )
temp = 0 ;
if ( temp > max )
max = temp ;
}
return max ;
}
static int mtk_read_temp ( void * data , int * temperature )
{
struct mtk_thermal * mt = data ;
int i ;
int tempmax = INT_MIN ;
2016-08-18 11:50:52 +08:00
for ( i = 0 ; i < mt - > conf - > num_banks ; i + + ) {
2015-11-30 12:42:32 +01:00
struct mtk_thermal_bank * bank = & mt - > banks [ i ] ;
mtk_thermal_get_bank ( bank ) ;
tempmax = max ( tempmax , mtk_thermal_bank_temperature ( bank ) ) ;
mtk_thermal_put_bank ( bank ) ;
}
* temperature = tempmax ;
return 0 ;
}
static const struct thermal_zone_of_device_ops mtk_thermal_ops = {
. get_temp = mtk_read_temp ,
} ;
static void mtk_thermal_init_bank ( struct mtk_thermal * mt , int num ,
2019-02-01 15:38:10 +08:00
u32 apmixed_phys_base , u32 auxadc_phys_base ,
int ctrl_id )
2015-11-30 12:42:32 +01:00
{
struct mtk_thermal_bank * bank = & mt - > banks [ num ] ;
2016-08-18 11:50:52 +08:00
const struct mtk_thermal_data * conf = mt - > conf ;
2015-11-30 12:42:32 +01:00
int i ;
2019-02-01 15:38:10 +08:00
int offset = mt - > conf - > controller_offset [ ctrl_id ] ;
void __iomem * controller_base = mt - > thermal_base + offset ;
2015-11-30 12:42:32 +01:00
bank - > id = num ;
bank - > mt = mt ;
mtk_thermal_get_bank ( bank ) ;
/* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
2019-02-01 15:38:10 +08:00
writel ( TEMP_MONCTL1_PERIOD_UNIT ( 12 ) , controller_base + TEMP_MONCTL1 ) ;
2015-11-30 12:42:32 +01:00
/*
* filt interval is 1 * 46.540 us = 46.54 us ,
* sen interval is 429 * 46.540 us = 19.96 ms
*/
writel ( TEMP_MONCTL2_FILTER_INTERVAL ( 1 ) |
TEMP_MONCTL2_SENSOR_INTERVAL ( 429 ) ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_MONCTL2 ) ;
2015-11-30 12:42:32 +01:00
/* poll is set to 10u */
writel ( TEMP_AHBPOLL_ADC_POLL_INTERVAL ( 768 ) ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_AHBPOLL ) ;
2015-11-30 12:42:32 +01:00
/* temperature sampling control, 1 sample */
2019-02-01 15:38:10 +08:00
writel ( 0x0 , controller_base + TEMP_MSRCTL0 ) ;
2015-11-30 12:42:32 +01:00
/* exceed this polling time, IRQ would be inserted */
2019-02-01 15:38:10 +08:00
writel ( 0xffffffff , controller_base + TEMP_AHBTO ) ;
2015-11-30 12:42:32 +01:00
/* number of interrupts per event, 1 is enough */
2019-02-01 15:38:10 +08:00
writel ( 0x0 , controller_base + TEMP_MONIDET0 ) ;
writel ( 0x0 , controller_base + TEMP_MONIDET1 ) ;
2015-11-30 12:42:32 +01:00
/*
* The MT8173 thermal controller does not have its own ADC . Instead it
* uses AHB bus accesses to control the AUXADC . To do this the thermal
* controller has to be programmed with the physical addresses of the
* AUXADC registers and with the various bit positions in the AUXADC .
* Also the thermal controller controls a mux in the APMIXEDSYS register
* space .
*/
/*
* this value will be stored to TEMP_PNPMUXADDR ( TEMP_SPARE0 )
* automatically by hw
*/
2019-02-01 15:38:10 +08:00
writel ( BIT ( conf - > auxadc_channel ) , controller_base + TEMP_ADCMUX ) ;
2015-11-30 12:42:32 +01:00
/* AHB address for auxadc mux selection */
writel ( auxadc_phys_base + AUXADC_CON1_CLR_V ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCMUXADDR ) ;
2015-11-30 12:42:32 +01:00
2020-04-30 17:14:34 +08:00
if ( mt - > conf - > version = = MTK_THERMAL_V1 ) {
/* AHB address for pnp sensor mux selection */
writel ( apmixed_phys_base + APMIXED_SYS_TS_CON1 ,
controller_base + TEMP_PNPMUXADDR ) ;
}
2015-11-30 12:42:32 +01:00
/* AHB value for auxadc enable */
2019-02-01 15:38:10 +08:00
writel ( BIT ( conf - > auxadc_channel ) , controller_base + TEMP_ADCEN ) ;
2015-11-30 12:42:32 +01:00
/* AHB address for auxadc enable (channel 0 immediate mode selected) */
writel ( auxadc_phys_base + AUXADC_CON1_SET_V ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCENADDR ) ;
2015-11-30 12:42:32 +01:00
/* AHB address for auxadc valid bit */
2016-08-18 11:50:52 +08:00
writel ( auxadc_phys_base + AUXADC_DATA ( conf - > auxadc_channel ) ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCVALIDADDR ) ;
2015-11-30 12:42:32 +01:00
/* AHB address for auxadc voltage output */
2016-08-18 11:50:52 +08:00
writel ( auxadc_phys_base + AUXADC_DATA ( conf - > auxadc_channel ) ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCVOLTADDR ) ;
2015-11-30 12:42:32 +01:00
/* read valid & voltage are at the same register */
2019-02-01 15:38:10 +08:00
writel ( 0x0 , controller_base + TEMP_RDCTRL ) ;
2015-11-30 12:42:32 +01:00
/* indicate where the valid bit is */
writel ( TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS ( 12 ) ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCVALIDMASK ) ;
2015-11-30 12:42:32 +01:00
/* no shift */
2019-02-01 15:38:10 +08:00
writel ( 0x0 , controller_base + TEMP_ADCVOLTAGESHIFT ) ;
2015-11-30 12:42:32 +01:00
/* enable auxadc mux write transaction */
writel ( TEMP_ADCWRITECTRL_ADC_MUX_WRITE ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCWRITECTRL ) ;
2015-11-30 12:42:32 +01:00
2016-08-18 11:50:52 +08:00
for ( i = 0 ; i < conf - > bank_data [ num ] . num_sensors ; i + + )
writel ( conf - > sensor_mux_values [ conf - > bank_data [ num ] . sensors [ i ] ] ,
Revert "thermal: mediatek: fix register index error"
This reverts commit eb9aecd90d1a39601e91cd08b90d5fee51d321a6
The above patch is supposed to fix a register index error on mt2701. It
is not clear if the problem solved is a hang or just an invalid value
returned, my guess is the second. The patch introduces, though, a new
hang on MT8173 device making them unusable. So, seems reasonable, revert
the patch because introduces a worst issue.
The reason I send a revert instead of trying to fix the issue for MT8173
is because the information needed to fix the issue is in the datasheet
and is not public. So I am not really able to fix it.
Fixes the following bug when CONFIG_MTK_THERMAL is set on MT8173
devices.
[ 2.222488] Unable to handle kernel paging request at virtual address ffff8000125f5001
[ 2.230421] Mem abort info:
[ 2.233207] ESR = 0x96000021
[ 2.236261] EC = 0x25: DABT (current EL), IL = 32 bits
[ 2.241571] SET = 0, FnV = 0
[ 2.244623] EA = 0, S1PTW = 0
[ 2.247762] Data abort info:
[ 2.250640] ISV = 0, ISS = 0x00000021
[ 2.254473] CM = 0, WnR = 0
[ 2.257544] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000041850000
[ 2.264251] [ffff8000125f5001] pgd=000000013ffff003, pud=000000013fffe003, pmd=000000013fff9003, pte=006800001100b707
[ 2.274867] Internal error: Oops: 96000021 [#1] PREEMPT SMP
[ 2.280432] Modules linked in:
[ 2.283483] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.7.0-rc6+ #162
[ 2.289914] Hardware name: Google Elm (DT)
[ 2.294003] pstate: 20000005 (nzCv daif -PAN -UAO)
[ 2.298792] pc : mtk_read_temp+0xb8/0x1c8
[ 2.302793] lr : mtk_read_temp+0x7c/0x1c8
[ 2.306794] sp : ffff80001003b930
[ 2.310100] x29: ffff80001003b930 x28: 0000000000000000
[ 2.315404] x27: 0000000000000002 x26: ffff0000f9550b10
[ 2.320709] x25: ffff0000f9550a80 x24: 0000000000000090
[ 2.326014] x23: ffff80001003ba24 x22: 00000000610344c0
[ 2.331318] x21: 0000000000002710 x20: 00000000000001f4
[ 2.336622] x19: 0000000000030d40 x18: ffff800011742ec0
[ 2.341926] x17: 0000000000000001 x16: 0000000000000001
[ 2.347230] x15: ffffffffffffffff x14: ffffff0000000000
[ 2.352535] x13: ffffffffffffffff x12: 0000000000000028
[ 2.357839] x11: 0000000000000003 x10: ffff800011295ec8
[ 2.363143] x9 : 000000000000291b x8 : 0000000000000002
[ 2.368447] x7 : 00000000000000a8 x6 : 0000000000000004
[ 2.373751] x5 : 0000000000000000 x4 : ffff800011295cb0
[ 2.379055] x3 : 0000000000000002 x2 : ffff8000125f5001
[ 2.384359] x1 : 0000000000000001 x0 : ffff0000f9550a80
[ 2.389665] Call trace:
[ 2.392105] mtk_read_temp+0xb8/0x1c8
[ 2.395760] of_thermal_get_temp+0x2c/0x40
[ 2.399849] thermal_zone_get_temp+0x78/0x160
[ 2.404198] thermal_zone_device_update.part.0+0x3c/0x1f8
[ 2.409589] thermal_zone_device_update+0x34/0x48
[ 2.414286] of_thermal_set_mode+0x58/0x88
[ 2.418375] thermal_zone_of_sensor_register+0x1a8/0x1d8
[ 2.423679] devm_thermal_zone_of_sensor_register+0x64/0xb0
[ 2.429242] mtk_thermal_probe+0x690/0x7d0
[ 2.433333] platform_drv_probe+0x5c/0xb0
[ 2.437335] really_probe+0xe4/0x448
[ 2.440901] driver_probe_device+0xe8/0x140
[ 2.445077] device_driver_attach+0x7c/0x88
[ 2.449252] __driver_attach+0xac/0x178
[ 2.453082] bus_for_each_dev+0x78/0xc8
[ 2.456909] driver_attach+0x2c/0x38
[ 2.460476] bus_add_driver+0x14c/0x230
[ 2.464304] driver_register+0x6c/0x128
[ 2.468131] __platform_driver_register+0x50/0x60
[ 2.472831] mtk_thermal_driver_init+0x24/0x30
[ 2.477268] do_one_initcall+0x50/0x298
[ 2.481098] kernel_init_freeable+0x1ec/0x264
[ 2.485450] kernel_init+0x1c/0x110
[ 2.488931] ret_from_fork+0x10/0x1c
[ 2.492502] Code: f9401081 f9400402 b8a67821 8b010042 (b9400042)
[ 2.498599] ---[ end trace e43e3105ed27dc99 ]---
[ 2.503367] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[ 2.511020] SMP: stopping secondary CPUs
[ 2.514941] Kernel Offset: disabled
[ 2.518421] CPU features: 0x090002,25006005
[ 2.522595] Memory Limit: none
[ 2.525644] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]--
Cc: Michael Kao <michael.kao@mediatek.com>
Fixes: eb9aecd90d1a ("thermal: mediatek: fix register index error")
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20200707103412.1010823-1-enric.balletbo@collabora.com
2020-07-07 12:34:12 +02:00
mt - > thermal_base + conf - > adcpnp [ i ] ) ;
2015-11-30 12:42:32 +01:00
2016-08-18 11:50:52 +08:00
writel ( ( 1 < < conf - > bank_data [ num ] . num_sensors ) - 1 ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_MONCTL0 ) ;
2015-11-30 12:42:32 +01:00
2016-02-18 07:43:57 -08:00
writel ( TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
TEMP_ADCWRITECTRL_ADC_MUX_WRITE ,
2019-02-01 15:38:10 +08:00
controller_base + TEMP_ADCWRITECTRL ) ;
2015-11-30 12:42:32 +01:00
mtk_thermal_put_bank ( bank ) ;
}
static u64 of_get_phys_base ( struct device_node * np )
{
u64 size64 ;
const __be32 * regaddr_p ;
regaddr_p = of_get_address ( np , 0 , & size64 , NULL ) ;
if ( ! regaddr_p )
return OF_BAD_ADDR ;
return of_translate_address ( np , regaddr_p ) ;
}
2020-04-30 17:14:33 +08:00
static int mtk_thermal_extract_efuse_v1 ( struct mtk_thermal * mt , u32 * buf )
{
int i ;
if ( ! ( buf [ 0 ] & CALIB_BUF0_VALID_V1 ) )
return - EINVAL ;
mt - > adc_ge = CALIB_BUF1_ADC_GE_V1 ( buf [ 1 ] ) ;
for ( i = 0 ; i < mt - > conf - > num_sensors ; i + + ) {
switch ( mt - > conf - > vts_index [ i ] ) {
case VTS1 :
mt - > vts [ VTS1 ] = CALIB_BUF0_VTS_TS1_V1 ( buf [ 0 ] ) ;
break ;
case VTS2 :
mt - > vts [ VTS2 ] = CALIB_BUF0_VTS_TS2_V1 ( buf [ 0 ] ) ;
break ;
case VTS3 :
mt - > vts [ VTS3 ] = CALIB_BUF1_VTS_TS3_V1 ( buf [ 1 ] ) ;
break ;
case VTS4 :
mt - > vts [ VTS4 ] = CALIB_BUF2_VTS_TS4_V1 ( buf [ 2 ] ) ;
break ;
case VTS5 :
mt - > vts [ VTS5 ] = CALIB_BUF2_VTS_TS5_V1 ( buf [ 2 ] ) ;
break ;
case VTSABB :
mt - > vts [ VTSABB ] =
CALIB_BUF2_VTS_TSABB_V1 ( buf [ 2 ] ) ;
break ;
default :
break ;
}
}
mt - > degc_cali = CALIB_BUF0_DEGC_CALI_V1 ( buf [ 0 ] ) ;
if ( CALIB_BUF1_ID_V1 ( buf [ 1 ] ) &
CALIB_BUF0_O_SLOPE_SIGN_V1 ( buf [ 0 ] ) )
mt - > o_slope = - CALIB_BUF0_O_SLOPE_V1 ( buf [ 0 ] ) ;
else
mt - > o_slope = CALIB_BUF0_O_SLOPE_V1 ( buf [ 0 ] ) ;
return 0 ;
}
2020-04-30 17:14:34 +08:00
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 ;
}
2016-02-18 07:43:57 -08:00
static int mtk_thermal_get_calibration_data ( struct device * dev ,
struct mtk_thermal * mt )
2015-11-30 12:42:32 +01:00
{
struct nvmem_cell * cell ;
u32 * buf ;
size_t len ;
int i , ret = 0 ;
/* Start with default values */
mt - > adc_ge = 512 ;
2016-08-18 11:50:52 +08:00
for ( i = 0 ; i < mt - > conf - > num_sensors ; i + + )
2015-11-30 12:42:32 +01:00
mt - > vts [ i ] = 260 ;
mt - > degc_cali = 40 ;
mt - > o_slope = 0 ;
cell = nvmem_cell_get ( dev , " calibration-data " ) ;
if ( IS_ERR ( cell ) ) {
if ( PTR_ERR ( cell ) = = - EPROBE_DEFER )
return PTR_ERR ( cell ) ;
return 0 ;
}
buf = ( u32 * ) nvmem_cell_read ( cell , & len ) ;
nvmem_cell_put ( cell ) ;
if ( IS_ERR ( buf ) )
return PTR_ERR ( buf ) ;
if ( len < 3 * sizeof ( u32 ) ) {
dev_warn ( dev , " invalid calibration data \n " ) ;
ret = - EINVAL ;
goto out ;
}
2020-04-30 17:14:34 +08:00
if ( mt - > conf - > version = = MTK_THERMAL_V1 )
ret = mtk_thermal_extract_efuse_v1 ( mt , buf ) ;
else
ret = mtk_thermal_extract_efuse_v2 ( mt , buf ) ;
2019-02-01 15:38:08 +08:00
2020-04-30 17:14:34 +08:00
if ( ret ) {
2015-11-30 12:42:32 +01:00
dev_info ( dev , " Device not calibrated, using default calibration values \n " ) ;
2020-04-30 17:14:34 +08:00
ret = 0 ;
2015-11-30 12:42:32 +01:00
}
out :
kfree ( buf ) ;
return ret ;
}
2016-08-18 11:50:52 +08:00
static const struct of_device_id mtk_thermal_of_match [ ] = {
{
. compatible = " mediatek,mt8173-thermal " ,
. data = ( void * ) & mt8173_thermal_data ,
} ,
{
. compatible = " mediatek,mt2701-thermal " ,
. data = ( void * ) & mt2701_thermal_data ,
2017-08-01 15:28:31 +08:00
} ,
{
. compatible = " mediatek,mt2712-thermal " ,
. data = ( void * ) & mt2712_thermal_data ,
2018-02-17 16:49:02 +08:00
} ,
{
. compatible = " mediatek,mt7622-thermal " ,
. data = ( void * ) & mt7622_thermal_data ,
2019-02-01 15:38:13 +08:00
} ,
{
. compatible = " mediatek,mt8183-thermal " ,
. data = ( void * ) & mt8183_thermal_data ,
2016-08-18 11:50:52 +08:00
} , {
} ,
} ;
MODULE_DEVICE_TABLE ( of , mtk_thermal_of_match ) ;
2020-04-30 17:14:34 +08:00
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 ) ;
}
2015-11-30 12:42:32 +01:00
static int mtk_thermal_probe ( struct platform_device * pdev )
{
2019-02-01 15:38:10 +08:00
int ret , i , ctrl_id ;
2015-11-30 12:42:32 +01:00
struct device_node * auxadc , * apmixedsys , * np = pdev - > dev . of_node ;
struct mtk_thermal * mt ;
struct resource * res ;
u64 auxadc_phys_base , apmixed_phys_base ;
2016-09-07 17:24:52 +08:00
struct thermal_zone_device * tzdev ;
2020-04-30 17:14:34 +08:00
void __iomem * apmixed_base , * auxadc_base ;
2015-11-30 12:42:32 +01:00
mt = devm_kzalloc ( & pdev - > dev , sizeof ( * mt ) , GFP_KERNEL ) ;
if ( ! mt )
return - ENOMEM ;
2018-04-16 10:34:16 +08:00
mt - > conf = of_device_get_match_data ( & pdev - > dev ) ;
2016-08-18 11:50:52 +08:00
2015-11-30 12:42:32 +01:00
mt - > clk_peri_therm = devm_clk_get ( & pdev - > dev , " therm " ) ;
if ( IS_ERR ( mt - > clk_peri_therm ) )
return PTR_ERR ( mt - > clk_peri_therm ) ;
mt - > clk_auxadc = devm_clk_get ( & pdev - > dev , " auxadc " ) ;
if ( IS_ERR ( mt - > clk_auxadc ) )
return PTR_ERR ( mt - > clk_auxadc ) ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
mt - > thermal_base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( mt - > thermal_base ) )
return PTR_ERR ( mt - > thermal_base ) ;
ret = mtk_thermal_get_calibration_data ( & pdev - > dev , mt ) ;
if ( ret )
return ret ;
mutex_init ( & mt - > lock ) ;
mt - > dev = & pdev - > dev ;
auxadc = of_parse_phandle ( np , " mediatek,auxadc " , 0 ) ;
if ( ! auxadc ) {
dev_err ( & pdev - > dev , " missing auxadc node \n " ) ;
return - ENODEV ;
}
2020-04-30 17:14:34 +08:00
auxadc_base = of_iomap ( auxadc , 0 ) ;
2015-11-30 12:42:32 +01:00
auxadc_phys_base = of_get_phys_base ( auxadc ) ;
of_node_put ( auxadc ) ;
if ( auxadc_phys_base = = OF_BAD_ADDR ) {
dev_err ( & pdev - > dev , " Can't get auxadc phys address \n " ) ;
return - EINVAL ;
}
apmixedsys = of_parse_phandle ( np , " mediatek,apmixedsys " , 0 ) ;
if ( ! apmixedsys ) {
dev_err ( & pdev - > dev , " missing apmixedsys node \n " ) ;
return - ENODEV ;
}
2020-04-30 17:14:34 +08:00
apmixed_base = of_iomap ( apmixedsys , 0 ) ;
2015-11-30 12:42:32 +01:00
apmixed_phys_base = of_get_phys_base ( apmixedsys ) ;
of_node_put ( apmixedsys ) ;
if ( apmixed_phys_base = = OF_BAD_ADDR ) {
dev_err ( & pdev - > dev , " Can't get auxadc phys address \n " ) ;
return - EINVAL ;
}
2017-08-01 15:28:33 +08:00
ret = device_reset ( & pdev - > dev ) ;
if ( ret )
return ret ;
2015-11-30 12:42:32 +01:00
ret = clk_prepare_enable ( mt - > clk_auxadc ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " Can't enable auxadc clk: %d \n " , ret ) ;
return ret ;
}
ret = clk_prepare_enable ( mt - > clk_peri_therm ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " Can't enable peri clk: %d \n " , ret ) ;
goto err_disable_clk_auxadc ;
}
2020-04-30 17:14:34 +08:00
if ( mt - > conf - > version = = MTK_THERMAL_V2 ) {
mtk_thermal_turn_on_buffer ( apmixed_base ) ;
mtk_thermal_release_periodic_ts ( mt , auxadc_base ) ;
}
2019-02-01 15:38:10 +08:00
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 ,
auxadc_phys_base , ctrl_id ) ;
2015-11-30 12:42:32 +01:00
platform_set_drvdata ( pdev , mt ) ;
2016-09-07 17:24:52 +08:00
tzdev = devm_thermal_zone_of_sensor_register ( & pdev - > dev , 0 , mt ,
& mtk_thermal_ops ) ;
if ( IS_ERR ( tzdev ) ) {
ret = PTR_ERR ( tzdev ) ;
goto err_disable_clk_peri_therm ;
}
2015-11-30 12:42:32 +01:00
return 0 ;
2016-09-07 17:24:52 +08:00
err_disable_clk_peri_therm :
clk_disable_unprepare ( mt - > clk_peri_therm ) ;
2015-11-30 12:42:32 +01:00
err_disable_clk_auxadc :
clk_disable_unprepare ( mt - > clk_auxadc ) ;
return ret ;
}
static int mtk_thermal_remove ( struct platform_device * pdev )
{
struct mtk_thermal * mt = platform_get_drvdata ( pdev ) ;
clk_disable_unprepare ( mt - > clk_peri_therm ) ;
clk_disable_unprepare ( mt - > clk_auxadc ) ;
return 0 ;
}
static struct platform_driver mtk_thermal_driver = {
. probe = mtk_thermal_probe ,
. remove = mtk_thermal_remove ,
. driver = {
2017-12-01 11:43:21 +01:00
. name = " mtk-thermal " ,
2015-11-30 12:42:32 +01:00
. of_match_table = mtk_thermal_of_match ,
} ,
} ;
module_platform_driver ( mtk_thermal_driver ) ;
2019-02-01 15:38:13 +08:00
MODULE_AUTHOR ( " Michael Kao <michael.kao@mediatek.com> " ) ;
2017-08-01 15:28:31 +08:00
MODULE_AUTHOR ( " Louis Yu <louis.yu@mediatek.com> " ) ;
2016-08-18 11:50:52 +08:00
MODULE_AUTHOR ( " Dawei Chien <dawei.chien@mediatek.com> " ) ;
2016-04-19 16:45:01 -07:00
MODULE_AUTHOR ( " Sascha Hauer <s.hauer@pengutronix.de> " ) ;
2015-11-30 12:42:32 +01:00
MODULE_AUTHOR ( " Hanyi Wu <hanyi.wu@mediatek.com> " ) ;
MODULE_DESCRIPTION ( " Mediatek thermal driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;