Blame view

drivers/thermal/mtk_thermal.c 29.8 KB
1802d0bee   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
a92db1c80   Sascha Hauer   thermal: Add Medi...
2
3
4
5
  /*
   * Copyright (c) 2015 MediaTek Inc.
   * Author: Hanyi Wu <hanyi.wu@mediatek.com>
   *         Sascha Hauer <s.hauer@pengutronix.de>
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
6
   *         Dawei Chien <dawei.chien@mediatek.com>
6cf7f002e   Louis Yu   thermal: mediatek...
7
   *         Louis Yu <louis.yu@mediatek.com>
a92db1c80   Sascha Hauer   thermal: Add Medi...
8
9
10
11
12
13
14
15
16
17
   */
  
  #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>
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
18
  #include <linux/of_device.h>
a92db1c80   Sascha Hauer   thermal: Add Medi...
19
20
21
22
23
24
  #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>
a92db1c80   Sascha Hauer   thermal: Add Medi...
25
26
  
  /* AUXADC Registers */
a92db1c80   Sascha Hauer   thermal: Add Medi...
27
28
29
30
  #define AUXADC_CON1_SET_V	0x008
  #define AUXADC_CON1_CLR_V	0x00c
  #define AUXADC_CON2_V		0x010
  #define AUXADC_DATA(channel)	(0x14 + (channel) * 4)
a92db1c80   Sascha Hauer   thermal: Add Medi...
31
32
33
34
35
36
37
38
39
40
  
  #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
89945047b   Henry Yen   thermal: mediatek...
41
  #define TEMP_MSRCTL1		0x03c
a92db1c80   Sascha Hauer   thermal: Add Medi...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  #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
a4ffe6b52   Michael Kao   thermal: mediatek...
66
67
68
69
70
71
72
73
  #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
a92db1c80   Sascha Hauer   thermal: Add Medi...
74
75
76
  #define PTPCORESEL		0x400
  
  #define TEMP_MONCTL1_PERIOD_UNIT(x)	((x) & 0x3ff)
eb4fc33eb   Eduardo Valentin   thermal: small st...
77
  #define TEMP_MONCTL2_FILTER_INTERVAL(x)	(((x) & 0x3ff) << 16)
a92db1c80   Sascha Hauer   thermal: Add Medi...
78
79
80
81
82
83
84
85
86
  #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)
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
87
  /* MT8173 thermal sensors */
a92db1c80   Sascha Hauer   thermal: Add Medi...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  #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
bd9403943   Michael Kao   thermal: mediatek...
105
106
  /* The number of controller in the MT8173 */
  #define MT8173_NUM_CONTROLLER		1
f84514766   Michael Kao   thermal: mediatek...
107
108
  /* The calibration coefficient of sensor  */
  #define MT8173_CALIBRATION	165
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
109
110
  /*
   * Layout of the fuses providing the calibration data
a4ffe6b52   Michael Kao   thermal: mediatek...
111
112
   * These macros could be used for MT8183, MT8173, MT2701, and MT2712.
   * MT8183 has 6 sensors and needs 6 VTS calibration data.
0a0689933   Louis Yu   thermal: mediatek...
113
114
115
   * 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.
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
116
   */
54bf1e5a6   Henry Yen   thermal: mediatek...
117
118
119
120
121
122
123
124
125
126
127
128
  #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)
1d0819455   Michael Kao   thermal: mediatek...
129

89945047b   Henry Yen   thermal: mediatek...
130
131
132
133
134
135
136
137
138
139
140
141
142
  /*
   * 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)
1d0819455   Michael Kao   thermal: mediatek...
143
144
145
146
147
148
  
  enum {
  	VTS1,
  	VTS2,
  	VTS3,
  	VTS4,
a4ffe6b52   Michael Kao   thermal: mediatek...
149
  	VTS5,
1d0819455   Michael Kao   thermal: mediatek...
150
151
152
  	VTSABB,
  	MAX_NUM_VTS,
  };
a92db1c80   Sascha Hauer   thermal: Add Medi...
153

89945047b   Henry Yen   thermal: mediatek...
154
155
156
157
  enum mtk_thermal_version {
  	MTK_THERMAL_V1 = 1,
  	MTK_THERMAL_V2,
  };
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
158
159
160
161
162
163
164
165
166
167
  /* 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
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
168
169
  /* The number of sensing points per bank */
  #define MT2701_NUM_SENSORS_PER_ZONE	3
bd9403943   Michael Kao   thermal: mediatek...
170
171
  /* The number of controller in the MT2701 */
  #define MT2701_NUM_CONTROLLER		1
f84514766   Michael Kao   thermal: mediatek...
172
173
  /* The calibration coefficient of sensor  */
  #define MT2701_CALIBRATION	165
6cf7f002e   Louis Yu   thermal: mediatek...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  /* 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
bd9403943   Michael Kao   thermal: mediatek...
188
189
  /* The number of controller in the MT2712 */
  #define MT2712_NUM_CONTROLLER		1
f84514766   Michael Kao   thermal: mediatek...
190
191
  /* The calibration coefficient of sensor  */
  #define MT2712_CALIBRATION	165
3966be3c0   Sean Wang   thermal: mediatek...
192
193
194
195
196
  #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
bd9403943   Michael Kao   thermal: mediatek...
197
  #define MT7622_NUM_CONTROLLER		1
3966be3c0   Sean Wang   thermal: mediatek...
198

fb4d83f29   Pi-Hsun Shih   thermal: mtk: All...
199
200
  /* The maximum number of banks */
  #define MAX_NUM_ZONES		8
f84514766   Michael Kao   thermal: mediatek...
201
202
  /* The calibration coefficient of sensor  */
  #define MT7622_CALIBRATION	165
a4ffe6b52   Michael Kao   thermal: mediatek...
203
204
205
206
207
208
209
210
211
212
213
214
215
  /* 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
14533a5a6   Michael Kao   thermal/drivers/m...
216
217
  /* The number of banks in the MT8183 */
  #define MT8183_NUM_ZONES               1
a4ffe6b52   Michael Kao   thermal: mediatek...
218
219
220
221
222
223
224
225
  /* 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
a92db1c80   Sascha Hauer   thermal: Add Medi...
226
  struct mtk_thermal;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
227
228
229
230
  struct thermal_bank_cfg {
  	unsigned int num_sensors;
  	const int *sensors;
  };
a92db1c80   Sascha Hauer   thermal: Add Medi...
231
232
233
234
  struct mtk_thermal_bank {
  	struct mtk_thermal *mt;
  	int id;
  };
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
235
236
237
238
  struct mtk_thermal_data {
  	s32 num_banks;
  	s32 num_sensors;
  	s32 auxadc_channel;
1d0819455   Michael Kao   thermal: mediatek...
239
  	const int *vts_index;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
240
241
242
  	const int *sensor_mux_values;
  	const int *msr;
  	const int *adcpnp;
f84514766   Michael Kao   thermal: mediatek...
243
  	const int cali_val;
bd9403943   Michael Kao   thermal: mediatek...
244
245
  	const int num_controller;
  	const int *controller_offset;
cb82aaade   Michael Kao   thermal: mediatek...
246
  	bool need_switch_bank;
fb4d83f29   Pi-Hsun Shih   thermal: mtk: All...
247
  	struct thermal_bank_cfg bank_data[MAX_NUM_ZONES];
89945047b   Henry Yen   thermal: mediatek...
248
  	enum mtk_thermal_version version;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
249
  };
a92db1c80   Sascha Hauer   thermal: Add Medi...
250
251
252
253
254
255
  struct mtk_thermal {
  	struct device *dev;
  	void __iomem *thermal_base;
  
  	struct clk *clk_peri_therm;
  	struct clk *clk_auxadc;
eb4fc33eb   Eduardo Valentin   thermal: small st...
256
  	/* lock: for getting and putting banks */
a92db1c80   Sascha Hauer   thermal: Add Medi...
257
258
259
260
  	struct mutex lock;
  
  	/* Calibration values */
  	s32 adc_ge;
89945047b   Henry Yen   thermal: mediatek...
261
  	s32 adc_oe;
a92db1c80   Sascha Hauer   thermal: Add Medi...
262
263
  	s32 degc_cali;
  	s32 o_slope;
89945047b   Henry Yen   thermal: mediatek...
264
  	s32 o_slope_sign;
1d0819455   Michael Kao   thermal: mediatek...
265
  	s32 vts[MAX_NUM_VTS];
a92db1c80   Sascha Hauer   thermal: Add Medi...
266

b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
267
  	const struct mtk_thermal_data *conf;
fb4d83f29   Pi-Hsun Shih   thermal: mtk: All...
268
  	struct mtk_thermal_bank banks[MAX_NUM_ZONES];
a92db1c80   Sascha Hauer   thermal: Add Medi...
269
  };
a4ffe6b52   Michael Kao   thermal: mediatek...
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  /* 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
  };
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
290
  /* MT8173 thermal sensor data */
992edf395   Vivek Gautam   thermal: mtk_ther...
291
  static const int mt8173_bank_data[MT8173_NUM_ZONES][3] = {
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
292
293
294
295
  	{ MT8173_TS2, MT8173_TS3 },
  	{ MT8173_TS2, MT8173_TS4 },
  	{ MT8173_TS1, MT8173_TS2, MT8173_TSABB },
  	{ MT8173_TS2 },
a92db1c80   Sascha Hauer   thermal: Add Medi...
296
  };
992edf395   Vivek Gautam   thermal: mtk_ther...
297
  static const int mt8173_msr[MT8173_NUM_SENSORS_PER_ZONE] = {
05d7839aa   Dawei Chien   thermal: mt8173: ...
298
  	TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
299
  };
a92db1c80   Sascha Hauer   thermal: Add Medi...
300

992edf395   Vivek Gautam   thermal: mtk_ther...
301
  static const int mt8173_adcpnp[MT8173_NUM_SENSORS_PER_ZONE] = {
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
302
303
  	TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3
  };
992edf395   Vivek Gautam   thermal: mtk_ther...
304
  static const int mt8173_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
bd9403943   Michael Kao   thermal: mediatek...
305
  static const int mt8173_tc_offset[MT8173_NUM_CONTROLLER] = { 0x0, };
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
306

1d0819455   Michael Kao   thermal: mediatek...
307
308
309
  static const int mt8173_vts_index[MT8173_NUM_SENSORS] = {
  	VTS1, VTS2, VTS3, VTS4, VTSABB
  };
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
310
  /* MT2701 thermal sensor data */
992edf395   Vivek Gautam   thermal: mtk_ther...
311
  static const int mt2701_bank_data[MT2701_NUM_SENSORS] = {
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
312
313
  	MT2701_TS1, MT2701_TS2, MT2701_TSABB
  };
992edf395   Vivek Gautam   thermal: mtk_ther...
314
  static const int mt2701_msr[MT2701_NUM_SENSORS_PER_ZONE] = {
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
315
316
  	TEMP_MSR0, TEMP_MSR1, TEMP_MSR2
  };
992edf395   Vivek Gautam   thermal: mtk_ther...
317
  static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = {
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
318
319
  	TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2
  };
992edf395   Vivek Gautam   thermal: mtk_ther...
320
  static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 };
bd9403943   Michael Kao   thermal: mediatek...
321
  static const int mt2701_tc_offset[MT2701_NUM_CONTROLLER] = { 0x0, };
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
322

1d0819455   Michael Kao   thermal: mediatek...
323
324
325
  static const int mt2701_vts_index[MT2701_NUM_SENSORS] = {
  	VTS1, VTS2, VTS3
  };
6cf7f002e   Louis Yu   thermal: mediatek...
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  /* 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 };
bd9403943   Michael Kao   thermal: mediatek...
340
  static const int mt2712_tc_offset[MT2712_NUM_CONTROLLER] = { 0x0, };
6cf7f002e   Louis Yu   thermal: mediatek...
341

1d0819455   Michael Kao   thermal: mediatek...
342
343
344
  static const int mt2712_vts_index[MT2712_NUM_SENSORS] = {
  	VTS1, VTS2, VTS3, VTS4
  };
3966be3c0   Sean Wang   thermal: mediatek...
345
346
347
348
349
  /* 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, };
1d0819455   Michael Kao   thermal: mediatek...
350
  static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
bd9403943   Michael Kao   thermal: mediatek...
351
  static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
3966be3c0   Sean Wang   thermal: mediatek...
352

3772bb422   Amit Kucheria   thermal: mediatek...
353
  /*
a92db1c80   Sascha Hauer   thermal: Add Medi...
354
355
356
357
358
359
360
361
362
363
364
365
   * 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.
   */
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
366
367
368
369
  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,
1d0819455   Michael Kao   thermal: mediatek...
370
  	.vts_index = mt8173_vts_index,
f84514766   Michael Kao   thermal: mediatek...
371
  	.cali_val = MT8173_CALIBRATION,
bd9403943   Michael Kao   thermal: mediatek...
372
373
  	.num_controller = MT8173_NUM_CONTROLLER,
  	.controller_offset = mt8173_tc_offset,
cb82aaade   Michael Kao   thermal: mediatek...
374
  	.need_switch_bank = true,
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  	.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],
  		},
a92db1c80   Sascha Hauer   thermal: Add Medi...
389
  	},
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
390
391
392
  	.msr = mt8173_msr,
  	.adcpnp = mt8173_adcpnp,
  	.sensor_mux_values = mt8173_mux_values,
89945047b   Henry Yen   thermal: mediatek...
393
  	.version = MTK_THERMAL_V1,
a92db1c80   Sascha Hauer   thermal: Add Medi...
394
  };
3772bb422   Amit Kucheria   thermal: mediatek...
395
  /*
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
396
397
398
399
400
401
402
403
404
405
406
407
408
   * 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,
1d0819455   Michael Kao   thermal: mediatek...
409
  	.vts_index = mt2701_vts_index,
f84514766   Michael Kao   thermal: mediatek...
410
  	.cali_val = MT2701_CALIBRATION,
bd9403943   Michael Kao   thermal: mediatek...
411
412
  	.num_controller = MT2701_NUM_CONTROLLER,
  	.controller_offset = mt2701_tc_offset,
cb82aaade   Michael Kao   thermal: mediatek...
413
  	.need_switch_bank = true,
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
414
415
416
417
418
  	.bank_data = {
  		{
  			.num_sensors = 3,
  			.sensors = mt2701_bank_data,
  		},
a92db1c80   Sascha Hauer   thermal: Add Medi...
419
  	},
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
420
421
422
  	.msr = mt2701_msr,
  	.adcpnp = mt2701_adcpnp,
  	.sensor_mux_values = mt2701_mux_values,
89945047b   Henry Yen   thermal: mediatek...
423
  	.version = MTK_THERMAL_V1,
a92db1c80   Sascha Hauer   thermal: Add Medi...
424
  };
3772bb422   Amit Kucheria   thermal: mediatek...
425
  /*
6cf7f002e   Louis Yu   thermal: mediatek...
426
427
428
429
430
431
432
433
434
435
436
437
438
   * 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,
1d0819455   Michael Kao   thermal: mediatek...
439
  	.vts_index = mt2712_vts_index,
f84514766   Michael Kao   thermal: mediatek...
440
  	.cali_val = MT2712_CALIBRATION,
bd9403943   Michael Kao   thermal: mediatek...
441
442
  	.num_controller = MT2712_NUM_CONTROLLER,
  	.controller_offset = mt2712_tc_offset,
cb82aaade   Michael Kao   thermal: mediatek...
443
  	.need_switch_bank = true,
6cf7f002e   Louis Yu   thermal: mediatek...
444
445
446
447
448
449
450
451
452
  	.bank_data = {
  		{
  			.num_sensors = 4,
  			.sensors = mt2712_bank_data,
  		},
  	},
  	.msr = mt2712_msr,
  	.adcpnp = mt2712_adcpnp,
  	.sensor_mux_values = mt2712_mux_values,
89945047b   Henry Yen   thermal: mediatek...
453
  	.version = MTK_THERMAL_V1,
6cf7f002e   Louis Yu   thermal: mediatek...
454
  };
3966be3c0   Sean Wang   thermal: mediatek...
455
456
457
458
459
460
461
462
  /*
   * 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,
1d0819455   Michael Kao   thermal: mediatek...
463
  	.vts_index = mt7622_vts_index,
f84514766   Michael Kao   thermal: mediatek...
464
  	.cali_val = MT7622_CALIBRATION,
bd9403943   Michael Kao   thermal: mediatek...
465
466
  	.num_controller = MT7622_NUM_CONTROLLER,
  	.controller_offset = mt7622_tc_offset,
cb82aaade   Michael Kao   thermal: mediatek...
467
  	.need_switch_bank = true,
3966be3c0   Sean Wang   thermal: mediatek...
468
469
470
471
472
473
474
475
476
  	.bank_data = {
  		{
  			.num_sensors = 1,
  			.sensors = mt7622_bank_data,
  		},
  	},
  	.msr = mt7622_msr,
  	.adcpnp = mt7622_adcpnp,
  	.sensor_mux_values = mt7622_mux_values,
89945047b   Henry Yen   thermal: mediatek...
477
  	.version = MTK_THERMAL_V2,
3966be3c0   Sean Wang   thermal: mediatek...
478
  };
3772bb422   Amit Kucheria   thermal: mediatek...
479
  /*
a4ffe6b52   Michael Kao   thermal: mediatek...
480
481
482
483
484
485
486
487
488
489
   * 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.
   */
a4ffe6b52   Michael Kao   thermal: mediatek...
490
491
  static const struct mtk_thermal_data mt8183_thermal_data = {
  	.auxadc_channel = MT8183_TEMP_AUXADC_CHANNEL,
14533a5a6   Michael Kao   thermal/drivers/m...
492
  	.num_banks = MT8183_NUM_ZONES,
a4ffe6b52   Michael Kao   thermal: mediatek...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
  	.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,
89945047b   Henry Yen   thermal: mediatek...
509
  	.version = MTK_THERMAL_V1,
a4ffe6b52   Michael Kao   thermal: mediatek...
510
511
512
  };
  
  /**
a92db1c80   Sascha Hauer   thermal: Add Medi...
513
   * raw_to_mcelsius - convert a raw ADC value to mcelsius
3772bb422   Amit Kucheria   thermal: mediatek...
514
515
   * @mt:	The thermal controller
   * @sensno:	sensor number
a92db1c80   Sascha Hauer   thermal: Add Medi...
516
517
518
519
520
   * @raw:	raw ADC value
   *
   * This converts the raw ADC value to mcelsius using the SoC specific
   * calibration constants
   */
54bf1e5a6   Henry Yen   thermal: mediatek...
521
  static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
a92db1c80   Sascha Hauer   thermal: Add Medi...
522
523
524
525
526
527
  {
  	s32 tmp;
  
  	raw &= 0xfff;
  
  	tmp = 203450520 << 3;
f84514766   Michael Kao   thermal: mediatek...
528
  	tmp /= mt->conf->cali_val + mt->o_slope;
a92db1c80   Sascha Hauer   thermal: Add Medi...
529
530
531
532
533
534
  	tmp /= 10000 + mt->adc_ge;
  	tmp *= raw - mt->vts[sensno] - 3350;
  	tmp >>= 3;
  
  	return mt->degc_cali * 500 - tmp;
  }
89945047b   Henry Yen   thermal: mediatek...
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  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;
  }
a92db1c80   Sascha Hauer   thermal: Add Medi...
564
565
566
567
568
569
570
571
572
573
574
  /**
   * 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;
cb82aaade   Michael Kao   thermal: mediatek...
575
576
  	if (mt->conf->need_switch_bank) {
  		mutex_lock(&mt->lock);
a92db1c80   Sascha Hauer   thermal: Add Medi...
577

cb82aaade   Michael Kao   thermal: mediatek...
578
579
580
581
582
  		val = readl(mt->thermal_base + PTPCORESEL);
  		val &= ~0xf;
  		val |= bank->id;
  		writel(val, mt->thermal_base + PTPCORESEL);
  	}
a92db1c80   Sascha Hauer   thermal: Add Medi...
583
584
585
586
587
588
589
590
591
592
593
  }
  
  /**
   * 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;
cb82aaade   Michael Kao   thermal: mediatek...
594
595
  	if (mt->conf->need_switch_bank)
  		mutex_unlock(&mt->lock);
a92db1c80   Sascha Hauer   thermal: Add Medi...
596
597
598
599
600
601
602
603
604
605
606
607
  }
  
  /**
   * 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;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
608
  	const struct mtk_thermal_data *conf = mt->conf;
eb4fc33eb   Eduardo Valentin   thermal: small st...
609
  	int i, temp = INT_MIN, max = INT_MIN;
a92db1c80   Sascha Hauer   thermal: Add Medi...
610
  	u32 raw;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
611
  	for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
a8f62f183   Enric Balletbo i Serra   Revert "thermal: ...
612
  		raw = readl(mt->thermal_base + conf->msr[i]);
a92db1c80   Sascha Hauer   thermal: Add Medi...
613

89945047b   Henry Yen   thermal: mediatek...
614
615
616
617
618
619
620
  		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);
  		}
a92db1c80   Sascha Hauer   thermal: Add Medi...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  
  		/*
  		 * 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;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
642
  	for (i = 0; i < mt->conf->num_banks; i++) {
a92db1c80   Sascha Hauer   thermal: Add Medi...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  		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,
bd9403943   Michael Kao   thermal: mediatek...
662
663
  				  u32 apmixed_phys_base, u32 auxadc_phys_base,
  				  int ctrl_id)
a92db1c80   Sascha Hauer   thermal: Add Medi...
664
665
  {
  	struct mtk_thermal_bank *bank = &mt->banks[num];
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
666
  	const struct mtk_thermal_data *conf = mt->conf;
a92db1c80   Sascha Hauer   thermal: Add Medi...
667
  	int i;
bd9403943   Michael Kao   thermal: mediatek...
668
669
  	int offset = mt->conf->controller_offset[ctrl_id];
  	void __iomem *controller_base = mt->thermal_base + offset;
a92db1c80   Sascha Hauer   thermal: Add Medi...
670
671
672
673
674
675
  	bank->id = num;
  	bank->mt = mt;
  
  	mtk_thermal_get_bank(bank);
  
  	/* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
bd9403943   Michael Kao   thermal: mediatek...
676
  	writel(TEMP_MONCTL1_PERIOD_UNIT(12), controller_base + TEMP_MONCTL1);
a92db1c80   Sascha Hauer   thermal: Add Medi...
677
678
679
680
681
682
683
  
  	/*
  	 * filt interval is 1 * 46.540us = 46.54us,
  	 * sen interval is 429 * 46.540us = 19.96ms
  	 */
  	writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
  			TEMP_MONCTL2_SENSOR_INTERVAL(429),
bd9403943   Michael Kao   thermal: mediatek...
684
  			controller_base + TEMP_MONCTL2);
a92db1c80   Sascha Hauer   thermal: Add Medi...
685
686
687
  
  	/* poll is set to 10u */
  	writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
bd9403943   Michael Kao   thermal: mediatek...
688
  	       controller_base + TEMP_AHBPOLL);
a92db1c80   Sascha Hauer   thermal: Add Medi...
689
690
  
  	/* temperature sampling control, 1 sample */
bd9403943   Michael Kao   thermal: mediatek...
691
  	writel(0x0, controller_base + TEMP_MSRCTL0);
a92db1c80   Sascha Hauer   thermal: Add Medi...
692
693
  
  	/* exceed this polling time, IRQ would be inserted */
bd9403943   Michael Kao   thermal: mediatek...
694
  	writel(0xffffffff, controller_base + TEMP_AHBTO);
a92db1c80   Sascha Hauer   thermal: Add Medi...
695
696
  
  	/* number of interrupts per event, 1 is enough */
bd9403943   Michael Kao   thermal: mediatek...
697
698
  	writel(0x0, controller_base + TEMP_MONIDET0);
  	writel(0x0, controller_base + TEMP_MONIDET1);
a92db1c80   Sascha Hauer   thermal: Add Medi...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
  
  	/*
  	 * 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
  	 */
bd9403943   Michael Kao   thermal: mediatek...
713
  	writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCMUX);
a92db1c80   Sascha Hauer   thermal: Add Medi...
714
715
716
  
  	/* AHB address for auxadc mux selection */
  	writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
bd9403943   Michael Kao   thermal: mediatek...
717
  	       controller_base + TEMP_ADCMUXADDR);
a92db1c80   Sascha Hauer   thermal: Add Medi...
718

89945047b   Henry Yen   thermal: mediatek...
719
720
721
722
723
  	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);
  	}
a92db1c80   Sascha Hauer   thermal: Add Medi...
724
725
  
  	/* AHB value for auxadc enable */
bd9403943   Michael Kao   thermal: mediatek...
726
  	writel(BIT(conf->auxadc_channel), controller_base + TEMP_ADCEN);
a92db1c80   Sascha Hauer   thermal: Add Medi...
727
728
729
  
  	/* AHB address for auxadc enable (channel 0 immediate mode selected) */
  	writel(auxadc_phys_base + AUXADC_CON1_SET_V,
bd9403943   Michael Kao   thermal: mediatek...
730
  	       controller_base + TEMP_ADCENADDR);
a92db1c80   Sascha Hauer   thermal: Add Medi...
731
732
  
  	/* AHB address for auxadc valid bit */
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
733
  	writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
bd9403943   Michael Kao   thermal: mediatek...
734
  	       controller_base + TEMP_ADCVALIDADDR);
a92db1c80   Sascha Hauer   thermal: Add Medi...
735
736
  
  	/* AHB address for auxadc voltage output */
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
737
  	writel(auxadc_phys_base + AUXADC_DATA(conf->auxadc_channel),
bd9403943   Michael Kao   thermal: mediatek...
738
  	       controller_base + TEMP_ADCVOLTADDR);
a92db1c80   Sascha Hauer   thermal: Add Medi...
739
740
  
  	/* read valid & voltage are at the same register */
bd9403943   Michael Kao   thermal: mediatek...
741
  	writel(0x0, controller_base + TEMP_RDCTRL);
a92db1c80   Sascha Hauer   thermal: Add Medi...
742
743
744
  
  	/* indicate where the valid bit is */
  	writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
bd9403943   Michael Kao   thermal: mediatek...
745
  	       controller_base + TEMP_ADCVALIDMASK);
a92db1c80   Sascha Hauer   thermal: Add Medi...
746
747
  
  	/* no shift */
bd9403943   Michael Kao   thermal: mediatek...
748
  	writel(0x0, controller_base + TEMP_ADCVOLTAGESHIFT);
a92db1c80   Sascha Hauer   thermal: Add Medi...
749
750
751
  
  	/* enable auxadc mux write transaction */
  	writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
bd9403943   Michael Kao   thermal: mediatek...
752
  		controller_base + TEMP_ADCWRITECTRL);
a92db1c80   Sascha Hauer   thermal: Add Medi...
753

b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
754
755
  	for (i = 0; i < conf->bank_data[num].num_sensors; i++)
  		writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
a8f62f183   Enric Balletbo i Serra   Revert "thermal: ...
756
  		       mt->thermal_base + conf->adcpnp[i]);
a92db1c80   Sascha Hauer   thermal: Add Medi...
757

b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
758
  	writel((1 << conf->bank_data[num].num_sensors) - 1,
bd9403943   Michael Kao   thermal: mediatek...
759
  	       controller_base + TEMP_MONCTL0);
a92db1c80   Sascha Hauer   thermal: Add Medi...
760

eb4fc33eb   Eduardo Valentin   thermal: small st...
761
762
  	writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE |
  	       TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
bd9403943   Michael Kao   thermal: mediatek...
763
  	       controller_base + TEMP_ADCWRITECTRL);
a92db1c80   Sascha Hauer   thermal: Add Medi...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
  
  	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);
  }
54bf1e5a6   Henry Yen   thermal: mediatek...
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
  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;
  }
89945047b   Henry Yen   thermal: mediatek...
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
  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;
  }
eb4fc33eb   Eduardo Valentin   thermal: small st...
839
840
  static int mtk_thermal_get_calibration_data(struct device *dev,
  					    struct mtk_thermal *mt)
a92db1c80   Sascha Hauer   thermal: Add Medi...
841
842
843
844
845
846
847
848
  {
  	struct nvmem_cell *cell;
  	u32 *buf;
  	size_t len;
  	int i, ret = 0;
  
  	/* Start with default values */
  	mt->adc_ge = 512;
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
849
  	for (i = 0; i < mt->conf->num_sensors; i++)
a92db1c80   Sascha Hauer   thermal: Add Medi...
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
  		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
  ");
  		ret = -EINVAL;
  		goto out;
  	}
89945047b   Henry Yen   thermal: mediatek...
874
875
876
877
  	if (mt->conf->version == MTK_THERMAL_V1)
  		ret = mtk_thermal_extract_efuse_v1(mt, buf);
  	else
  		ret = mtk_thermal_extract_efuse_v2(mt, buf);
1d0819455   Michael Kao   thermal: mediatek...
878

89945047b   Henry Yen   thermal: mediatek...
879
  	if (ret) {
a92db1c80   Sascha Hauer   thermal: Add Medi...
880
881
  		dev_info(dev, "Device not calibrated, using default calibration values
  ");
89945047b   Henry Yen   thermal: mediatek...
882
  		ret = 0;
a92db1c80   Sascha Hauer   thermal: Add Medi...
883
884
885
886
887
888
889
  	}
  
  out:
  	kfree(buf);
  
  	return ret;
  }
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
890
891
892
893
894
895
896
897
  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,
6cf7f002e   Louis Yu   thermal: mediatek...
898
899
900
901
  	},
  	{
  		.compatible = "mediatek,mt2712-thermal",
  		.data = (void *)&mt2712_thermal_data,
3966be3c0   Sean Wang   thermal: mediatek...
902
903
904
905
  	},
  	{
  		.compatible = "mediatek,mt7622-thermal",
  		.data = (void *)&mt7622_thermal_data,
a4ffe6b52   Michael Kao   thermal: mediatek...
906
907
908
909
  	},
  	{
  		.compatible = "mediatek,mt8183-thermal",
  		.data = (void *)&mt8183_thermal_data,
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
910
911
912
913
  	}, {
  	},
  };
  MODULE_DEVICE_TABLE(of, mtk_thermal_of_match);
89945047b   Henry Yen   thermal: mediatek...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  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);
  }
a92db1c80   Sascha Hauer   thermal: Add Medi...
935
936
  static int mtk_thermal_probe(struct platform_device *pdev)
  {
bd9403943   Michael Kao   thermal: mediatek...
937
  	int ret, i, ctrl_id;
a92db1c80   Sascha Hauer   thermal: Add Medi...
938
939
940
941
  	struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
  	struct mtk_thermal *mt;
  	struct resource *res;
  	u64 auxadc_phys_base, apmixed_phys_base;
1f6b0889d   Axel Lin   thermal: mtk_ther...
942
  	struct thermal_zone_device *tzdev;
89945047b   Henry Yen   thermal: mediatek...
943
  	void __iomem *apmixed_base, *auxadc_base;
a92db1c80   Sascha Hauer   thermal: Add Medi...
944
945
946
947
  
  	mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
  	if (!mt)
  		return -ENOMEM;
9efc58dfa   Ryder Lee   thermal: mediatek...
948
  	mt->conf = of_device_get_match_data(&pdev->dev);
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
949

a92db1c80   Sascha Hauer   thermal: Add Medi...
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
  	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
  ");
  		return -ENODEV;
  	}
89945047b   Henry Yen   thermal: mediatek...
977
  	auxadc_base = of_iomap(auxadc, 0);
a92db1c80   Sascha Hauer   thermal: Add Medi...
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
  	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
  ");
  		return -EINVAL;
  	}
  
  	apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
  	if (!apmixedsys) {
  		dev_err(&pdev->dev, "missing apmixedsys node
  ");
  		return -ENODEV;
  	}
89945047b   Henry Yen   thermal: mediatek...
994
  	apmixed_base = of_iomap(apmixedsys, 0);
a92db1c80   Sascha Hauer   thermal: Add Medi...
995
996
997
998
999
1000
1001
1002
1003
  	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
  ");
  		return -EINVAL;
  	}
6760f3f74   Louis Yu   thermal: mediatek...
1004
1005
1006
  	ret = device_reset(&pdev->dev);
  	if (ret)
  		return ret;
a92db1c80   Sascha Hauer   thermal: Add Medi...
1007
1008
1009
1010
1011
1012
  	ret = clk_prepare_enable(mt->clk_auxadc);
  	if (ret) {
  		dev_err(&pdev->dev, "Can't enable auxadc clk: %d
  ", ret);
  		return ret;
  	}
a92db1c80   Sascha Hauer   thermal: Add Medi...
1013
1014
1015
1016
1017
1018
  	ret = clk_prepare_enable(mt->clk_peri_therm);
  	if (ret) {
  		dev_err(&pdev->dev, "Can't enable peri clk: %d
  ", ret);
  		goto err_disable_clk_auxadc;
  	}
89945047b   Henry Yen   thermal: mediatek...
1019
1020
1021
1022
  	if (mt->conf->version == MTK_THERMAL_V2) {
  		mtk_thermal_turn_on_buffer(apmixed_base);
  		mtk_thermal_release_periodic_ts(mt, auxadc_base);
  	}
bd9403943   Michael Kao   thermal: mediatek...
1023
1024
1025
1026
  	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);
a92db1c80   Sascha Hauer   thermal: Add Medi...
1027
1028
  
  	platform_set_drvdata(pdev, mt);
1f6b0889d   Axel Lin   thermal: mtk_ther...
1029
1030
1031
1032
1033
1034
  	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;
  	}
a92db1c80   Sascha Hauer   thermal: Add Medi...
1035
1036
  
  	return 0;
1f6b0889d   Axel Lin   thermal: mtk_ther...
1037
1038
  err_disable_clk_peri_therm:
  	clk_disable_unprepare(mt->clk_peri_therm);
a92db1c80   Sascha Hauer   thermal: Add Medi...
1039
1040
1041
1042
1043
1044
1045
1046
1047
  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);
a92db1c80   Sascha Hauer   thermal: Add Medi...
1048
1049
1050
1051
1052
  	clk_disable_unprepare(mt->clk_peri_therm);
  	clk_disable_unprepare(mt->clk_auxadc);
  
  	return 0;
  }
a92db1c80   Sascha Hauer   thermal: Add Medi...
1053
1054
1055
1056
  static struct platform_driver mtk_thermal_driver = {
  	.probe = mtk_thermal_probe,
  	.remove = mtk_thermal_remove,
  	.driver = {
f45ce7ee0   Matthias Brugger   thermal: mtk: Cle...
1057
  		.name = "mtk-thermal",
a92db1c80   Sascha Hauer   thermal: Add Medi...
1058
1059
1060
1061
1062
  		.of_match_table = mtk_thermal_of_match,
  	},
  };
  
  module_platform_driver(mtk_thermal_driver);
a4ffe6b52   Michael Kao   thermal: mediatek...
1063
  MODULE_AUTHOR("Michael Kao <michael.kao@mediatek.com>");
6cf7f002e   Louis Yu   thermal: mediatek...
1064
  MODULE_AUTHOR("Louis Yu <louis.yu@mediatek.com>");
b7cf00537   dawei.chien@mediatek.com   thermal: Add Medi...
1065
  MODULE_AUTHOR("Dawei Chien <dawei.chien@mediatek.com>");
9ebfb4e09   Randy Dunlap   thermal: minor mt...
1066
  MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
a92db1c80   Sascha Hauer   thermal: Add Medi...
1067
1068
1069
  MODULE_AUTHOR("Hanyi Wu <hanyi.wu@mediatek.com>");
  MODULE_DESCRIPTION("Mediatek thermal driver");
  MODULE_LICENSE("GPL v2");