1 // SPDX-License-Identifier: Apache-2.0
2 /* Copyright 2013-2019 IBM Corp. */
3 
4 #include <xscom.h>
5 #include <chip.h>
6 #include <sensor.h>
7 #include <dts.h>
8 #include <skiboot.h>
9 #include <opal-api.h>
10 #include <opal-msg.h>
11 #include <timer.h>
12 #include <timebase.h>
13 
14 struct dts {
15 	uint8_t		valid;
16 	uint8_t		trip;
17 	int16_t		temp;
18 };
19 
20 /*
21  * Attributes for the core temperature sensor
22  */
23 enum {
24 	SENSOR_DTS_ATTR_TEMP_MAX,
25 	SENSOR_DTS_ATTR_TEMP_TRIP
26 };
27 
28 
29 /* Therm mac result masking for DTS (result(0:15)
30  *  0:3   - 0x0
31  *  4:11  - Temperature in degrees C
32  *  12:13 - trip bits: 00 - no trip; 01 - warning; 10 - critical; 11 - fatal
33  *  14    - spare
34  *  15    - valid
35  */
dts_decode_one_dts(uint16_t raw,struct dts * dts)36 static void dts_decode_one_dts(uint16_t raw, struct dts *dts)
37 {
38 	/*
39 	 * The value is both signed and unsigned :-) 0xff could be
40 	 * either 255C or -1C, so for now we treat this as unsigned
41 	 * which is sufficient for our purpose. We could try to be
42 	 * a bit smarter and treat it as signed for values between
43 	 * -10 and 0 and unsigned to 239 or something like that...
44 	 */
45 	dts->valid = raw & 1;
46 	if (dts->valid) {
47 		dts->temp = (raw >> 4) & 0xff;
48 		dts->trip = (raw >> 2) & 0x3;
49 	} else {
50 		dts->temp = 0;
51 		dts->trip = 0;
52 	}
53 }
54 
dts_keep_max(struct dts * temps,int n,struct dts * dts)55 static void dts_keep_max(struct dts *temps, int n, struct dts *dts)
56 {
57 	int i;
58 
59 	for (i = 0; i < n; i++) {
60 		int16_t t = temps[i].temp;
61 
62 		if (!temps[i].valid)
63 			continue;
64 
65 		if (t > dts->temp)
66 			dts->temp = t;
67 
68 		dts->valid++;
69 		dts->trip |= temps[i].trip;
70 	}
71 }
72 
73 /* Per core Digital Thermal Sensors */
74 #define EX_THERM_DTS_RESULT0	0x10050000
75 #define EX_THERM_DTS_RESULT1	0x10050001
76 
77 /* Different sensor locations */
78 #define P8_CT_ZONE_LSU	0
79 #define P8_CT_ZONE_ISU	1
80 #define P8_CT_ZONE_FXU	2
81 #define P8_CT_ZONE_L3C	3
82 #define P8_CT_ZONES	4
83 
84 /*
85  * Returns the temperature as the max of all 4 zones and a global trip
86  * attribute.
87  */
dts_read_core_temp_p8(uint32_t pir,struct dts * dts)88 static int dts_read_core_temp_p8(uint32_t pir, struct dts *dts)
89 {
90 	int32_t chip_id = pir_to_chip_id(pir);
91 	int32_t core = pir_to_core_id(pir);
92 	uint64_t dts0, dts1;
93 	struct dts temps[P8_CT_ZONES];
94 	int rc;
95 
96 	rc = xscom_read(chip_id, XSCOM_ADDR_P8_EX(core, EX_THERM_DTS_RESULT0),
97 			&dts0);
98 	if (rc)
99 		return rc;
100 
101 	rc = xscom_read(chip_id, XSCOM_ADDR_P8_EX(core, EX_THERM_DTS_RESULT1),
102 			&dts1);
103 	if (rc)
104 		return rc;
105 
106 	dts_decode_one_dts(dts0 >> 48, &temps[P8_CT_ZONE_LSU]);
107 	dts_decode_one_dts(dts0 >> 32, &temps[P8_CT_ZONE_ISU]);
108 	dts_decode_one_dts(dts0 >> 16, &temps[P8_CT_ZONE_FXU]);
109 	dts_decode_one_dts(dts1 >> 48, &temps[P8_CT_ZONE_L3C]);
110 
111 	dts_keep_max(temps, P8_CT_ZONES, dts);
112 
113 	prlog(PR_TRACE, "DTS: Chip %x Core %x temp:%dC trip:%x\n",
114 	      chip_id, core, dts->temp, dts->trip);
115 
116 	/*
117 	 * FIXME: The trip bits are always set ?! Just discard
118 	 * them for the moment until we understand why.
119 	 */
120 	dts->trip = 0;
121 	return 0;
122 }
123 
124 /* Per core Digital Thermal Sensors */
125 #define EC_THERM_P9_DTS_RESULT0	0x050000
126 
127 /* Different sensor locations */
128 #define P9_CORE_DTS0	0
129 #define P9_CORE_DTS1	1
130 #define P9_CORE_ZONES	2
131 
132 /*
133  * Returns the temperature as the max of all zones and a global trip
134  * attribute.
135  */
dts_read_core_temp_p9(uint32_t pir,struct dts * dts)136 static int dts_read_core_temp_p9(uint32_t pir, struct dts *dts)
137 {
138 	int32_t chip_id = pir_to_chip_id(pir);
139 	int32_t core = pir_to_core_id(pir);
140 	uint64_t dts0;
141 	struct dts temps[P9_CORE_ZONES];
142 	int rc;
143 
144 	rc = xscom_read(chip_id, XSCOM_ADDR_P9_EC(core, EC_THERM_P9_DTS_RESULT0),
145 			&dts0);
146 	if (rc)
147 		return rc;
148 
149 	dts_decode_one_dts(dts0 >> 48, &temps[P9_CORE_DTS0]);
150 	dts_decode_one_dts(dts0 >> 32, &temps[P9_CORE_DTS1]);
151 
152 	dts_keep_max(temps, P9_CORE_ZONES, dts);
153 
154 	prlog(PR_TRACE, "DTS: Chip %x Core %x temp:%dC trip:%x\n",
155 	      chip_id, core, dts->temp, dts->trip);
156 
157 	/*
158 	 * FIXME: The trip bits are always set ?! Just discard
159 	 * them for the moment until we understand why.
160 	 */
161 	dts->trip = 0;
162 	return 0;
163 }
164 
dts_async_read_temp(struct timer * t __unused,void * data,u64 now __unused)165 static void dts_async_read_temp(struct timer *t __unused, void *data,
166 				u64 now __unused)
167 {
168 	struct dts dts = {0};
169 	int rc, swkup_rc;
170 	struct cpu_thread *cpu = data;
171 
172 	swkup_rc = dctl_set_special_wakeup(cpu);
173 
174 	if (proc_gen == proc_gen_p9)
175 		rc = dts_read_core_temp_p9(cpu->pir, &dts);
176 	else /* (proc_gen == proc_gen_p10) */
177 		rc = OPAL_UNSUPPORTED; /* XXX P10 */
178 
179 	if (!rc) {
180 		if (cpu->sensor_attr == SENSOR_DTS_ATTR_TEMP_MAX)
181 			*cpu->sensor_data = cpu_to_be64(dts.temp);
182 		else if (cpu->sensor_attr == SENSOR_DTS_ATTR_TEMP_TRIP)
183 			*cpu->sensor_data = cpu_to_be64(dts.trip);
184 	}
185 
186 	if (!swkup_rc)
187 		dctl_clear_special_wakeup(cpu);
188 
189 	check_sensor_read(cpu->token);
190 	rc = opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
191 			cpu_to_be64(cpu->token),
192 			cpu_to_be64(rc));
193 	if (rc)
194 		prerror("Failed to queue async message\n");
195 
196 	cpu->dts_read_in_progress = false;
197 }
198 
dts_read_core_temp(u32 pir,struct dts * dts,u8 attr,int token,__be64 * sensor_data)199 static int dts_read_core_temp(u32 pir, struct dts *dts, u8 attr,
200 			      int token, __be64 *sensor_data)
201 {
202 	struct cpu_thread *cpu;
203 	int rc;
204 
205 	switch (proc_gen) {
206 	case proc_gen_p8:
207 		rc = dts_read_core_temp_p8(pir, dts);
208 		break;
209 	case proc_gen_p9: /* Asynchronus read */
210 		cpu = find_cpu_by_pir(pir);
211 		if (!cpu)
212 			return OPAL_PARAMETER;
213 		lock(&cpu->dts_lock);
214 		if (cpu->dts_read_in_progress) {
215 			unlock(&cpu->dts_lock);
216 			return OPAL_BUSY;
217 		}
218 		cpu->dts_read_in_progress = true;
219 		cpu->sensor_attr = attr;
220 		cpu->sensor_data = sensor_data;
221 		cpu->token = token;
222 		schedule_timer(&cpu->dts_timer, 0);
223 		rc = OPAL_ASYNC_COMPLETION;
224 		unlock(&cpu->dts_lock);
225 		break;
226 	case proc_gen_p10: /* XXX P10 */
227 	default:
228 		rc = OPAL_UNSUPPORTED;
229 	}
230 	return rc;
231 }
232 
233 /* Per memory controller Digital Thermal Sensors */
234 #define THERM_MEM_DTS_RESULT0	0x2050000
235 
236 /* Different sensor locations */
237 #define P8_MEM_DTS0	0
238 #define P8_MEM_DTS1	1
239 #define P8_MEM_ZONES	2
240 
dts_read_mem_temp(uint32_t chip_id,struct dts * dts)241 static int dts_read_mem_temp(uint32_t chip_id, struct dts *dts)
242 {
243 	uint64_t dts0;
244 	struct dts temps[P8_MEM_ZONES];
245 	int i;
246 	int rc;
247 
248 	rc = xscom_read(chip_id, THERM_MEM_DTS_RESULT0, &dts0);
249 	if (rc)
250 		return rc;
251 
252 	dts_decode_one_dts(dts0 >> 48, &temps[P8_MEM_DTS0]);
253 	dts_decode_one_dts(dts0 >> 32, &temps[P8_MEM_DTS1]);
254 
255 	for (i = 0; i < P8_MEM_ZONES; i++) {
256 		int16_t t = temps[i].temp;
257 
258 		if (!temps[i].valid)
259 			continue;
260 
261 		/* keep the max temperature of all 4 sensors */
262 		if (t > dts->temp)
263 			dts->temp = t;
264 
265 		dts->valid++;
266 		dts->trip |= temps[i].trip;
267 	}
268 
269 	prlog(PR_TRACE, "DTS: Chip %x temp:%dC trip:%x\n",
270 	      chip_id, dts->temp, dts->trip);
271 
272 	/*
273 	 * FIXME: The trip bits are always set ?! Just discard
274 	 * them for the moment until we understand why.
275 	 */
276 	dts->trip = 0;
277 	return 0;
278 }
279 
280 /*
281  * DTS sensor class ids. Only one for the moment: the core
282  * temperature.
283  */
284 enum sensor_dts_class {
285 	SENSOR_DTS_CORE_TEMP,
286 	SENSOR_DTS_MEM_TEMP,
287 	/* To be continued */
288 };
289 
290 /*
291  * Extract the centaur chip id which was truncated to fit in the
292  * resource identifier field of the sensor handler
293  */
294 #define centaur_get_id(rid) (0x80000000 | ((rid) & 0x3ff))
295 
dts_sensor_read(u32 sensor_hndl,int token,__be64 * sensor_data)296 int64_t dts_sensor_read(u32 sensor_hndl, int token, __be64 *sensor_data)
297 {
298 	uint8_t	attr = sensor_get_attr(sensor_hndl);
299 	uint32_t rid = sensor_get_rid(sensor_hndl);
300 	struct dts dts = {0};
301 	int64_t rc;
302 
303 	if (attr > SENSOR_DTS_ATTR_TEMP_TRIP)
304 		return OPAL_PARAMETER;
305 
306 	memset(&dts, 0, sizeof(struct dts));
307 
308 	switch (sensor_get_frc(sensor_hndl)) {
309 	case SENSOR_DTS_CORE_TEMP:
310 		rc = dts_read_core_temp(rid, &dts, attr, token, sensor_data);
311 		break;
312 	case SENSOR_DTS_MEM_TEMP:
313 		rc = dts_read_mem_temp(centaur_get_id(rid), &dts);
314 		break;
315 	default:
316 		rc = OPAL_PARAMETER;
317 		break;
318 	}
319 	if (rc)
320 		return rc;
321 
322 	if (attr == SENSOR_DTS_ATTR_TEMP_MAX)
323 		*sensor_data = cpu_to_be64(dts.temp);
324 	else if (attr == SENSOR_DTS_ATTR_TEMP_TRIP)
325 		*sensor_data = cpu_to_be64(dts.trip);
326 
327 	return 0;
328 }
329 
330 /*
331  * We only have two bytes for the resource identifier in the sensor
332  * handler. Let's trunctate the centaur chip id to squeeze it in.
333  *
334  * Centaur chip IDs are using the XSCOM "partID" encoding described in
335  * xscom.h. recap:
336  *
337  *     0b1000.0000.0000.0000.0000.00NN.NCCC.MMMM
338  *     N=Node, C=Chip, M=Memory Channel
339  */
340 #define centaur_make_id(cen_id, dimm_id)	\
341 	(((chip_id) & 0x3ff) | ((dimm_id) << 10))
342 
343 #define core_handler(core_id, attr_id)					\
344 	sensor_make_handler(SENSOR_DTS, SENSOR_DTS_CORE_TEMP,		\
345 			    core_id, attr_id)
346 
347 #define cen_handler(cen_id, attr_id)					\
348 	sensor_make_handler(SENSOR_DTS, SENSOR_DTS_MEM_TEMP,		\
349 			    centaur_make_id(chip_id, 0), attr_id)
350 
dts_sensor_create_nodes(struct dt_node * sensors)351 bool dts_sensor_create_nodes(struct dt_node *sensors)
352 {
353 	struct proc_chip *chip;
354 	struct dt_node *cn;
355 	char name[64];
356 
357 	/* build the device tree nodes :
358 	 *
359 	 *     sensors/core-temp@pir
360 	 *
361 	 * The core is identified by its PIR, is stored in the resource
362 	 * number of the sensor handler.
363 	 */
364 	for_each_chip(chip) {
365 		struct cpu_thread *c;
366 
367 		for_each_available_core_in_chip(c, chip->id) {
368 			struct dt_node *node;
369 			uint32_t handler;
370 
371 			snprintf(name, sizeof(name), "core-temp@%x", c->pir);
372 
373 			handler = core_handler(c->pir, SENSOR_DTS_ATTR_TEMP_MAX);
374 			node = dt_new(sensors, name);
375 			dt_add_property_string(node, "compatible",
376 					       "ibm,opal-sensor");
377 			dt_add_property_cells(node, "sensor-data", handler);
378 			handler = core_handler(c->pir, SENSOR_DTS_ATTR_TEMP_TRIP);
379 			dt_add_property_cells(node, "sensor-status", handler);
380 			dt_add_property_string(node, "sensor-type", "temp");
381 			dt_add_property_cells(node, "ibm,pir", c->pir);
382 			dt_add_property_cells(node, "reg", handler);
383 			dt_add_property_string(node, "label", "Core");
384 			init_timer(&c->dts_timer, dts_async_read_temp, c);
385 			c->dts_read_in_progress = false;
386 		}
387 	}
388 
389 	/*
390 	 * sensors/mem-temp@chip for Centaurs
391 	 */
392 	dt_for_each_compatible(dt_root, cn, "ibm,centaur") {
393 		uint32_t chip_id;
394 		struct dt_node *node;
395 		uint32_t handler;
396 
397 		chip_id = dt_prop_get_u32(cn, "ibm,chip-id");
398 
399 		snprintf(name, sizeof(name), "mem-temp@%x", chip_id);
400 
401 		handler = cen_handler(chip_id, SENSOR_DTS_ATTR_TEMP_MAX);
402 		node = dt_new(sensors, name);
403 		dt_add_property_string(node, "compatible",
404 				       "ibm,opal-sensor");
405 		dt_add_property_cells(node, "sensor-data", handler);
406 
407 		handler = cen_handler(chip_id, SENSOR_DTS_ATTR_TEMP_TRIP);
408 		dt_add_property_cells(node, "sensor-status", handler);
409 		dt_add_property_string(node, "sensor-type", "temp");
410 		dt_add_property_cells(node, "ibm,chip-id", chip_id);
411 		dt_add_property_cells(node, "reg", handler);
412 		dt_add_property_string(node, "label", "Centaur");
413 	}
414 
415 	return true;
416 }
417