• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Windfarm PowerMac thermal control.
4  * Control loops for PowerMac7,2 and 7,3
5  *
6  * Copyright (C) 2012 Benjamin Herrenschmidt, IBM Corp.
7  */
8 #include <linux/types.h>
9 #include <linux/errno.h>
10 #include <linux/kernel.h>
11 #include <linux/device.h>
12 #include <linux/platform_device.h>
13 #include <linux/reboot.h>
14 #include <asm/prom.h>
15 #include <asm/smu.h>
16 
17 #include "windfarm.h"
18 #include "windfarm_pid.h"
19 #include "windfarm_mpu.h"
20 
21 #define VERSION "1.0"
22 
23 #undef DEBUG
24 #undef LOTSA_DEBUG
25 
26 #ifdef DEBUG
27 #define DBG(args...)	printk(args)
28 #else
29 #define DBG(args...)	do { } while(0)
30 #endif
31 
32 #ifdef LOTSA_DEBUG
33 #define DBG_LOTS(args...)	printk(args)
34 #else
35 #define DBG_LOTS(args...)	do { } while(0)
36 #endif
37 
38 /* define this to force CPU overtemp to 60 degree, useful for testing
39  * the overtemp code
40  */
41 #undef HACKED_OVERTEMP
42 
43 /* We currently only handle 2 chips */
44 #define NR_CHIPS	2
45 #define NR_CPU_FANS	3 * NR_CHIPS
46 
47 /* Controls and sensors */
48 static struct wf_sensor *sens_cpu_temp[NR_CHIPS];
49 static struct wf_sensor *sens_cpu_volts[NR_CHIPS];
50 static struct wf_sensor *sens_cpu_amps[NR_CHIPS];
51 static struct wf_sensor *backside_temp;
52 static struct wf_sensor *drives_temp;
53 
54 static struct wf_control *cpu_front_fans[NR_CHIPS];
55 static struct wf_control *cpu_rear_fans[NR_CHIPS];
56 static struct wf_control *cpu_pumps[NR_CHIPS];
57 static struct wf_control *backside_fan;
58 static struct wf_control *drives_fan;
59 static struct wf_control *slots_fan;
60 static struct wf_control *cpufreq_clamp;
61 
62 /* We keep a temperature history for average calculation of 180s */
63 #define CPU_TEMP_HIST_SIZE	180
64 
65 /* Fixed speed for slot fan */
66 #define	SLOTS_FAN_DEFAULT_PWM	40
67 
68 /* Scale value for CPU intake fans */
69 #define CPU_INTAKE_SCALE	0x0000f852
70 
71 /* PID loop state */
72 static const struct mpu_data *cpu_mpu_data[NR_CHIPS];
73 static struct wf_cpu_pid_state cpu_pid[NR_CHIPS];
74 static bool cpu_pid_combined;
75 static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
76 static int cpu_thist_pt;
77 static s64 cpu_thist_total;
78 static s32 cpu_all_tmax = 100 << 16;
79 static struct wf_pid_state backside_pid;
80 static int backside_tick;
81 static struct wf_pid_state drives_pid;
82 static int drives_tick;
83 
84 static int nr_chips;
85 static bool have_all_controls;
86 static bool have_all_sensors;
87 static bool started;
88 
89 static int failure_state;
90 #define FAILURE_SENSOR		1
91 #define FAILURE_FAN		2
92 #define FAILURE_PERM		4
93 #define FAILURE_LOW_OVERTEMP	8
94 #define FAILURE_HIGH_OVERTEMP	16
95 
96 /* Overtemp values */
97 #define LOW_OVER_AVERAGE	0
98 #define LOW_OVER_IMMEDIATE	(10 << 16)
99 #define LOW_OVER_CLEAR		((-10) << 16)
100 #define HIGH_OVER_IMMEDIATE	(14 << 16)
101 #define HIGH_OVER_AVERAGE	(10 << 16)
102 #define HIGH_OVER_IMMEDIATE	(14 << 16)
103 
104 
cpu_max_all_fans(void)105 static void cpu_max_all_fans(void)
106 {
107 	int i;
108 
109 	/* We max all CPU fans in case of a sensor error. We also do the
110 	 * cpufreq clamping now, even if it's supposedly done later by the
111 	 * generic code anyway, we do it earlier here to react faster
112 	 */
113 	if (cpufreq_clamp)
114 		wf_control_set_max(cpufreq_clamp);
115 	for (i = 0; i < nr_chips; i++) {
116 		if (cpu_front_fans[i])
117 			wf_control_set_max(cpu_front_fans[i]);
118 		if (cpu_rear_fans[i])
119 			wf_control_set_max(cpu_rear_fans[i]);
120 		if (cpu_pumps[i])
121 			wf_control_set_max(cpu_pumps[i]);
122 	}
123 }
124 
cpu_check_overtemp(s32 temp)125 static int cpu_check_overtemp(s32 temp)
126 {
127 	int new_state = 0;
128 	s32 t_avg, t_old;
129 	static bool first = true;
130 
131 	/* First check for immediate overtemps */
132 	if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
133 		new_state |= FAILURE_LOW_OVERTEMP;
134 		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
135 			printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
136 			       " temperature !\n");
137 	}
138 	if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
139 		new_state |= FAILURE_HIGH_OVERTEMP;
140 		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
141 			printk(KERN_ERR "windfarm: Critical overtemp due to"
142 			       " immediate CPU temperature !\n");
143 	}
144 
145 	/*
146 	 * The first time around, initialize the array with the first
147 	 * temperature reading
148 	 */
149 	if (first) {
150 		int i;
151 
152 		cpu_thist_total = 0;
153 		for (i = 0; i < CPU_TEMP_HIST_SIZE; i++) {
154 			cpu_thist[i] = temp;
155 			cpu_thist_total += temp;
156 		}
157 		first = false;
158 	}
159 
160 	/*
161 	 * We calculate a history of max temperatures and use that for the
162 	 * overtemp management
163 	 */
164 	t_old = cpu_thist[cpu_thist_pt];
165 	cpu_thist[cpu_thist_pt] = temp;
166 	cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
167 	cpu_thist_total -= t_old;
168 	cpu_thist_total += temp;
169 	t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
170 
171 	DBG_LOTS("  t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
172 		 FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
173 
174 	/* Now check for average overtemps */
175 	if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
176 		new_state |= FAILURE_LOW_OVERTEMP;
177 		if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
178 			printk(KERN_ERR "windfarm: Overtemp due to average CPU"
179 			       " temperature !\n");
180 	}
181 	if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
182 		new_state |= FAILURE_HIGH_OVERTEMP;
183 		if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
184 			printk(KERN_ERR "windfarm: Critical overtemp due to"
185 			       " average CPU temperature !\n");
186 	}
187 
188 	/* Now handle overtemp conditions. We don't currently use the windfarm
189 	 * overtemp handling core as it's not fully suited to the needs of those
190 	 * new machine. This will be fixed later.
191 	 */
192 	if (new_state) {
193 		/* High overtemp -> immediate shutdown */
194 		if (new_state & FAILURE_HIGH_OVERTEMP)
195 			machine_power_off();
196 		if ((failure_state & new_state) != new_state)
197 			cpu_max_all_fans();
198 		failure_state |= new_state;
199 	} else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
200 		   (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
201 		printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
202 		failure_state &= ~FAILURE_LOW_OVERTEMP;
203 	}
204 
205 	return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
206 }
207 
read_one_cpu_vals(int cpu,s32 * temp,s32 * power)208 static int read_one_cpu_vals(int cpu, s32 *temp, s32 *power)
209 {
210 	s32 dtemp, volts, amps;
211 	int rc;
212 
213 	/* Get diode temperature */
214 	rc = wf_sensor_get(sens_cpu_temp[cpu], &dtemp);
215 	if (rc) {
216 		DBG("  CPU%d: temp reading error !\n", cpu);
217 		return -EIO;
218 	}
219 	DBG_LOTS("  CPU%d: temp   = %d.%03d\n", cpu, FIX32TOPRINT((dtemp)));
220 	*temp = dtemp;
221 
222 	/* Get voltage */
223 	rc = wf_sensor_get(sens_cpu_volts[cpu], &volts);
224 	if (rc) {
225 		DBG("  CPU%d, volts reading error !\n", cpu);
226 		return -EIO;
227 	}
228 	DBG_LOTS("  CPU%d: volts  = %d.%03d\n", cpu, FIX32TOPRINT((volts)));
229 
230 	/* Get current */
231 	rc = wf_sensor_get(sens_cpu_amps[cpu], &amps);
232 	if (rc) {
233 		DBG("  CPU%d, current reading error !\n", cpu);
234 		return -EIO;
235 	}
236 	DBG_LOTS("  CPU%d: amps   = %d.%03d\n", cpu, FIX32TOPRINT((amps)));
237 
238 	/* Calculate power */
239 
240 	/* Scale voltage and current raw sensor values according to fixed scales
241 	 * obtained in Darwin and calculate power from I and V
242 	 */
243 	*power = (((u64)volts) * ((u64)amps)) >> 16;
244 
245 	DBG_LOTS("  CPU%d: power  = %d.%03d\n", cpu, FIX32TOPRINT((*power)));
246 
247 	return 0;
248 
249 }
250 
cpu_fans_tick_split(void)251 static void cpu_fans_tick_split(void)
252 {
253 	int err, cpu;
254 	s32 intake, temp, power, t_max = 0;
255 
256 	DBG_LOTS("* cpu fans_tick_split()\n");
257 
258 	for (cpu = 0; cpu < nr_chips; ++cpu) {
259 		struct wf_cpu_pid_state *sp = &cpu_pid[cpu];
260 
261 		/* Read current speed */
262 		wf_control_get(cpu_rear_fans[cpu], &sp->target);
263 
264 		DBG_LOTS("  CPU%d: cur_target = %d RPM\n", cpu, sp->target);
265 
266 		err = read_one_cpu_vals(cpu, &temp, &power);
267 		if (err) {
268 			failure_state |= FAILURE_SENSOR;
269 			cpu_max_all_fans();
270 			return;
271 		}
272 
273 		/* Keep track of highest temp */
274 		t_max = max(t_max, temp);
275 
276 		/* Handle possible overtemps */
277 		if (cpu_check_overtemp(t_max))
278 			return;
279 
280 		/* Run PID */
281 		wf_cpu_pid_run(sp, power, temp);
282 
283 		DBG_LOTS("  CPU%d: target = %d RPM\n", cpu, sp->target);
284 
285 		/* Apply result directly to exhaust fan */
286 		err = wf_control_set(cpu_rear_fans[cpu], sp->target);
287 		if (err) {
288 			pr_warn("wf_pm72: Fan %s reports error %d\n",
289 				cpu_rear_fans[cpu]->name, err);
290 			failure_state |= FAILURE_FAN;
291 			break;
292 		}
293 
294 		/* Scale result for intake fan */
295 		intake = (sp->target * CPU_INTAKE_SCALE) >> 16;
296 		DBG_LOTS("  CPU%d: intake = %d RPM\n", cpu, intake);
297 		err = wf_control_set(cpu_front_fans[cpu], intake);
298 		if (err) {
299 			pr_warn("wf_pm72: Fan %s reports error %d\n",
300 				cpu_front_fans[cpu]->name, err);
301 			failure_state |= FAILURE_FAN;
302 			break;
303 		}
304 	}
305 }
306 
cpu_fans_tick_combined(void)307 static void cpu_fans_tick_combined(void)
308 {
309 	s32 temp0, power0, temp1, power1, t_max = 0;
310 	s32 temp, power, intake, pump;
311 	struct wf_control *pump0, *pump1;
312 	struct wf_cpu_pid_state *sp = &cpu_pid[0];
313 	int err, cpu;
314 
315 	DBG_LOTS("* cpu fans_tick_combined()\n");
316 
317 	/* Read current speed from cpu 0 */
318 	wf_control_get(cpu_rear_fans[0], &sp->target);
319 
320 	DBG_LOTS("  CPUs: cur_target = %d RPM\n", sp->target);
321 
322 	/* Read values for both CPUs */
323 	err = read_one_cpu_vals(0, &temp0, &power0);
324 	if (err) {
325 		failure_state |= FAILURE_SENSOR;
326 		cpu_max_all_fans();
327 		return;
328 	}
329 	err = read_one_cpu_vals(1, &temp1, &power1);
330 	if (err) {
331 		failure_state |= FAILURE_SENSOR;
332 		cpu_max_all_fans();
333 		return;
334 	}
335 
336 	/* Keep track of highest temp */
337 	t_max = max(t_max, max(temp0, temp1));
338 
339 	/* Handle possible overtemps */
340 	if (cpu_check_overtemp(t_max))
341 		return;
342 
343 	/* Use the max temp & power of both */
344 	temp = max(temp0, temp1);
345 	power = max(power0, power1);
346 
347 	/* Run PID */
348 	wf_cpu_pid_run(sp, power, temp);
349 
350 	/* Scale result for intake fan */
351 	intake = (sp->target * CPU_INTAKE_SCALE) >> 16;
352 
353 	/* Same deal with pump speed */
354 	pump0 = cpu_pumps[0];
355 	pump1 = cpu_pumps[1];
356 	if (!pump0) {
357 		pump0 = pump1;
358 		pump1 = NULL;
359 	}
360 	pump = (sp->target * wf_control_get_max(pump0)) /
361 		cpu_mpu_data[0]->rmaxn_exhaust_fan;
362 
363 	DBG_LOTS("  CPUs: target = %d RPM\n", sp->target);
364 	DBG_LOTS("  CPUs: intake = %d RPM\n", intake);
365 	DBG_LOTS("  CPUs: pump   = %d RPM\n", pump);
366 
367 	for (cpu = 0; cpu < nr_chips; cpu++) {
368 		err = wf_control_set(cpu_rear_fans[cpu], sp->target);
369 		if (err) {
370 			pr_warn("wf_pm72: Fan %s reports error %d\n",
371 				cpu_rear_fans[cpu]->name, err);
372 			failure_state |= FAILURE_FAN;
373 		}
374 		err = wf_control_set(cpu_front_fans[cpu], intake);
375 		if (err) {
376 			pr_warn("wf_pm72: Fan %s reports error %d\n",
377 				cpu_front_fans[cpu]->name, err);
378 			failure_state |= FAILURE_FAN;
379 		}
380 		err = 0;
381 		if (cpu_pumps[cpu])
382 			err = wf_control_set(cpu_pumps[cpu], pump);
383 		if (err) {
384 			pr_warn("wf_pm72: Pump %s reports error %d\n",
385 				cpu_pumps[cpu]->name, err);
386 			failure_state |= FAILURE_FAN;
387 		}
388 	}
389 }
390 
391 /* Implementation... */
cpu_setup_pid(int cpu)392 static int cpu_setup_pid(int cpu)
393 {
394 	struct wf_cpu_pid_param pid;
395 	const struct mpu_data *mpu = cpu_mpu_data[cpu];
396 	s32 tmax, ttarget, ptarget;
397 	int fmin, fmax, hsize;
398 
399 	/* Get PID params from the appropriate MPU EEPROM */
400 	tmax = mpu->tmax << 16;
401 	ttarget = mpu->ttarget << 16;
402 	ptarget = ((s32)(mpu->pmaxh - mpu->padjmax)) << 16;
403 
404 	DBG("wf_72: CPU%d ttarget = %d.%03d, tmax = %d.%03d\n",
405 	    cpu, FIX32TOPRINT(ttarget), FIX32TOPRINT(tmax));
406 
407 	/* We keep a global tmax for overtemp calculations */
408 	if (tmax < cpu_all_tmax)
409 		cpu_all_tmax = tmax;
410 
411 	/* Set PID min/max by using the rear fan min/max */
412 	fmin = wf_control_get_min(cpu_rear_fans[cpu]);
413 	fmax = wf_control_get_max(cpu_rear_fans[cpu]);
414 	DBG("wf_72: CPU%d max RPM range = [%d..%d]\n", cpu, fmin, fmax);
415 
416 	/* History size */
417 	hsize = min_t(int, mpu->tguardband, WF_PID_MAX_HISTORY);
418 	DBG("wf_72: CPU%d history size = %d\n", cpu, hsize);
419 
420 	/* Initialize PID loop */
421 	pid.interval	= 1;	/* seconds */
422 	pid.history_len = hsize;
423 	pid.gd		= mpu->pid_gd;
424 	pid.gp		= mpu->pid_gp;
425 	pid.gr		= mpu->pid_gr;
426 	pid.tmax	= tmax;
427 	pid.ttarget	= ttarget;
428 	pid.pmaxadj	= ptarget;
429 	pid.min		= fmin;
430 	pid.max		= fmax;
431 
432 	wf_cpu_pid_init(&cpu_pid[cpu], &pid);
433 	cpu_pid[cpu].target = 1000;
434 
435 	return 0;
436 }
437 
438 /* Backside/U3 fan */
439 static struct wf_pid_param backside_u3_param = {
440 	.interval	= 5,
441 	.history_len	= 2,
442 	.gd		= 40 << 20,
443 	.gp		= 5 << 20,
444 	.gr		= 0,
445 	.itarget	= 65 << 16,
446 	.additive	= 1,
447 	.min		= 20,
448 	.max		= 100,
449 };
450 
451 static struct wf_pid_param backside_u3h_param = {
452 	.interval	= 5,
453 	.history_len	= 2,
454 	.gd		= 20 << 20,
455 	.gp		= 5 << 20,
456 	.gr		= 0,
457 	.itarget	= 75 << 16,
458 	.additive	= 1,
459 	.min		= 20,
460 	.max		= 100,
461 };
462 
backside_fan_tick(void)463 static void backside_fan_tick(void)
464 {
465 	s32 temp;
466 	int speed;
467 	int err;
468 
469 	if (!backside_fan || !backside_temp || !backside_tick)
470 		return;
471 	if (--backside_tick > 0)
472 		return;
473 	backside_tick = backside_pid.param.interval;
474 
475 	DBG_LOTS("* backside fans tick\n");
476 
477 	/* Update fan speed from actual fans */
478 	err = wf_control_get(backside_fan, &speed);
479 	if (!err)
480 		backside_pid.target = speed;
481 
482 	err = wf_sensor_get(backside_temp, &temp);
483 	if (err) {
484 		printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
485 		       err);
486 		failure_state |= FAILURE_SENSOR;
487 		wf_control_set_max(backside_fan);
488 		return;
489 	}
490 	speed = wf_pid_run(&backside_pid, temp);
491 
492 	DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
493 		 FIX32TOPRINT(temp), speed);
494 
495 	err = wf_control_set(backside_fan, speed);
496 	if (err) {
497 		printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
498 		failure_state |= FAILURE_FAN;
499 	}
500 }
501 
backside_setup_pid(void)502 static void backside_setup_pid(void)
503 {
504 	/* first time initialize things */
505 	s32 fmin = wf_control_get_min(backside_fan);
506 	s32 fmax = wf_control_get_max(backside_fan);
507 	struct wf_pid_param param;
508 	struct device_node *u3;
509 	int u3h = 1; /* conservative by default */
510 
511 	u3 = of_find_node_by_path("/u3@0,f8000000");
512 	if (u3 != NULL) {
513 		const u32 *vers = of_get_property(u3, "device-rev", NULL);
514 		if (vers)
515 			if (((*vers) & 0x3f) < 0x34)
516 				u3h = 0;
517 		of_node_put(u3);
518 	}
519 
520 	param = u3h ? backside_u3h_param : backside_u3_param;
521 
522 	param.min = max(param.min, fmin);
523 	param.max = min(param.max, fmax);
524 	wf_pid_init(&backside_pid, &param);
525 	backside_tick = 1;
526 
527 	pr_info("wf_pm72: Backside control loop started.\n");
528 }
529 
530 /* Drive bay fan */
531 static const struct wf_pid_param drives_param = {
532 	.interval	= 5,
533 	.history_len	= 2,
534 	.gd		= 30 << 20,
535 	.gp		= 5 << 20,
536 	.gr		= 0,
537 	.itarget	= 40 << 16,
538 	.additive	= 1,
539 	.min		= 300,
540 	.max		= 4000,
541 };
542 
drives_fan_tick(void)543 static void drives_fan_tick(void)
544 {
545 	s32 temp;
546 	int speed;
547 	int err;
548 
549 	if (!drives_fan || !drives_temp || !drives_tick)
550 		return;
551 	if (--drives_tick > 0)
552 		return;
553 	drives_tick = drives_pid.param.interval;
554 
555 	DBG_LOTS("* drives fans tick\n");
556 
557 	/* Update fan speed from actual fans */
558 	err = wf_control_get(drives_fan, &speed);
559 	if (!err)
560 		drives_pid.target = speed;
561 
562 	err = wf_sensor_get(drives_temp, &temp);
563 	if (err) {
564 		pr_warn("wf_pm72: drive bay temp sensor error %d\n", err);
565 		failure_state |= FAILURE_SENSOR;
566 		wf_control_set_max(drives_fan);
567 		return;
568 	}
569 	speed = wf_pid_run(&drives_pid, temp);
570 
571 	DBG_LOTS("drives PID temp=%d.%.3d speed=%d\n",
572 		 FIX32TOPRINT(temp), speed);
573 
574 	err = wf_control_set(drives_fan, speed);
575 	if (err) {
576 		printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
577 		failure_state |= FAILURE_FAN;
578 	}
579 }
580 
drives_setup_pid(void)581 static void drives_setup_pid(void)
582 {
583 	/* first time initialize things */
584 	s32 fmin = wf_control_get_min(drives_fan);
585 	s32 fmax = wf_control_get_max(drives_fan);
586 	struct wf_pid_param param = drives_param;
587 
588 	param.min = max(param.min, fmin);
589 	param.max = min(param.max, fmax);
590 	wf_pid_init(&drives_pid, &param);
591 	drives_tick = 1;
592 
593 	pr_info("wf_pm72: Drive bay control loop started.\n");
594 }
595 
set_fail_state(void)596 static void set_fail_state(void)
597 {
598 	cpu_max_all_fans();
599 
600 	if (backside_fan)
601 		wf_control_set_max(backside_fan);
602 	if (slots_fan)
603 		wf_control_set_max(slots_fan);
604 	if (drives_fan)
605 		wf_control_set_max(drives_fan);
606 }
607 
pm72_tick(void)608 static void pm72_tick(void)
609 {
610 	int i, last_failure;
611 
612 	if (!started) {
613 		started = true;
614 		printk(KERN_INFO "windfarm: CPUs control loops started.\n");
615 		for (i = 0; i < nr_chips; ++i) {
616 			if (cpu_setup_pid(i) < 0) {
617 				failure_state = FAILURE_PERM;
618 				set_fail_state();
619 				break;
620 			}
621 		}
622 		DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
623 
624 		backside_setup_pid();
625 		drives_setup_pid();
626 
627 		/*
628 		 * We don't have the right stuff to drive the PCI fan
629 		 * so we fix it to a default value
630 		 */
631 		wf_control_set(slots_fan, SLOTS_FAN_DEFAULT_PWM);
632 
633 #ifdef HACKED_OVERTEMP
634 		cpu_all_tmax = 60 << 16;
635 #endif
636 	}
637 
638 	/* Permanent failure, bail out */
639 	if (failure_state & FAILURE_PERM)
640 		return;
641 
642 	/*
643 	 * Clear all failure bits except low overtemp which will be eventually
644 	 * cleared by the control loop itself
645 	 */
646 	last_failure = failure_state;
647 	failure_state &= FAILURE_LOW_OVERTEMP;
648 	if (cpu_pid_combined)
649 		cpu_fans_tick_combined();
650 	else
651 		cpu_fans_tick_split();
652 	backside_fan_tick();
653 	drives_fan_tick();
654 
655 	DBG_LOTS("  last_failure: 0x%x, failure_state: %x\n",
656 		 last_failure, failure_state);
657 
658 	/* Check for failures. Any failure causes cpufreq clamping */
659 	if (failure_state && last_failure == 0 && cpufreq_clamp)
660 		wf_control_set_max(cpufreq_clamp);
661 	if (failure_state == 0 && last_failure && cpufreq_clamp)
662 		wf_control_set_min(cpufreq_clamp);
663 
664 	/* That's it for now, we might want to deal with other failures
665 	 * differently in the future though
666 	 */
667 }
668 
pm72_new_control(struct wf_control * ct)669 static void pm72_new_control(struct wf_control *ct)
670 {
671 	bool all_controls;
672 	bool had_pump = cpu_pumps[0] || cpu_pumps[1];
673 
674 	if (!strcmp(ct->name, "cpu-front-fan-0"))
675 		cpu_front_fans[0] = ct;
676 	else if (!strcmp(ct->name, "cpu-front-fan-1"))
677 		cpu_front_fans[1] = ct;
678 	else if (!strcmp(ct->name, "cpu-rear-fan-0"))
679 		cpu_rear_fans[0] = ct;
680 	else if (!strcmp(ct->name, "cpu-rear-fan-1"))
681 		cpu_rear_fans[1] = ct;
682 	else if (!strcmp(ct->name, "cpu-pump-0"))
683 		cpu_pumps[0] = ct;
684 	else if (!strcmp(ct->name, "cpu-pump-1"))
685 		cpu_pumps[1] = ct;
686 	else if (!strcmp(ct->name, "backside-fan"))
687 		backside_fan = ct;
688 	else if (!strcmp(ct->name, "slots-fan"))
689 		slots_fan = ct;
690 	else if (!strcmp(ct->name, "drive-bay-fan"))
691 		drives_fan = ct;
692 	else if (!strcmp(ct->name, "cpufreq-clamp"))
693 		cpufreq_clamp = ct;
694 
695 	all_controls =
696 		cpu_front_fans[0] &&
697 		cpu_rear_fans[0] &&
698 		backside_fan &&
699 		slots_fan &&
700 		drives_fan;
701 	if (nr_chips > 1)
702 		all_controls &=
703 			cpu_front_fans[1] &&
704 			cpu_rear_fans[1];
705 	have_all_controls = all_controls;
706 
707 	if ((cpu_pumps[0] || cpu_pumps[1]) && !had_pump) {
708 		pr_info("wf_pm72: Liquid cooling pump(s) detected,"
709 			" using new algorithm !\n");
710 		cpu_pid_combined = true;
711 	}
712 }
713 
714 
pm72_new_sensor(struct wf_sensor * sr)715 static void pm72_new_sensor(struct wf_sensor *sr)
716 {
717 	bool all_sensors;
718 
719 	if (!strcmp(sr->name, "cpu-diode-temp-0"))
720 		sens_cpu_temp[0] = sr;
721 	else if (!strcmp(sr->name, "cpu-diode-temp-1"))
722 		sens_cpu_temp[1] = sr;
723 	else if (!strcmp(sr->name, "cpu-voltage-0"))
724 		sens_cpu_volts[0] = sr;
725 	else if (!strcmp(sr->name, "cpu-voltage-1"))
726 		sens_cpu_volts[1] = sr;
727 	else if (!strcmp(sr->name, "cpu-current-0"))
728 		sens_cpu_amps[0] = sr;
729 	else if (!strcmp(sr->name, "cpu-current-1"))
730 		sens_cpu_amps[1] = sr;
731 	else if (!strcmp(sr->name, "backside-temp"))
732 		backside_temp = sr;
733 	else if (!strcmp(sr->name, "hd-temp"))
734 		drives_temp = sr;
735 
736 	all_sensors =
737 		sens_cpu_temp[0] &&
738 		sens_cpu_volts[0] &&
739 		sens_cpu_amps[0] &&
740 		backside_temp &&
741 		drives_temp;
742 	if (nr_chips > 1)
743 		all_sensors &=
744 			sens_cpu_temp[1] &&
745 			sens_cpu_volts[1] &&
746 			sens_cpu_amps[1];
747 
748 	have_all_sensors = all_sensors;
749 }
750 
pm72_wf_notify(struct notifier_block * self,unsigned long event,void * data)751 static int pm72_wf_notify(struct notifier_block *self,
752 			  unsigned long event, void *data)
753 {
754 	switch (event) {
755 	case WF_EVENT_NEW_SENSOR:
756 		pm72_new_sensor(data);
757 		break;
758 	case WF_EVENT_NEW_CONTROL:
759 		pm72_new_control(data);
760 		break;
761 	case WF_EVENT_TICK:
762 		if (have_all_controls && have_all_sensors)
763 			pm72_tick();
764 	}
765 	return 0;
766 }
767 
768 static struct notifier_block pm72_events = {
769 	.notifier_call = pm72_wf_notify,
770 };
771 
wf_pm72_probe(struct platform_device * dev)772 static int wf_pm72_probe(struct platform_device *dev)
773 {
774 	wf_register_client(&pm72_events);
775 	return 0;
776 }
777 
wf_pm72_remove(struct platform_device * dev)778 static int wf_pm72_remove(struct platform_device *dev)
779 {
780 	wf_unregister_client(&pm72_events);
781 
782 	/* should release all sensors and controls */
783 	return 0;
784 }
785 
786 static struct platform_driver wf_pm72_driver = {
787 	.probe	= wf_pm72_probe,
788 	.remove	= wf_pm72_remove,
789 	.driver	= {
790 		.name = "windfarm",
791 	},
792 };
793 
wf_pm72_init(void)794 static int __init wf_pm72_init(void)
795 {
796 	struct device_node *cpu;
797 	int i;
798 
799 	if (!of_machine_is_compatible("PowerMac7,2") &&
800 	    !of_machine_is_compatible("PowerMac7,3"))
801 		return -ENODEV;
802 
803 	/* Count the number of CPU cores */
804 	nr_chips = 0;
805 	for_each_node_by_type(cpu, "cpu")
806 		++nr_chips;
807 	if (nr_chips > NR_CHIPS)
808 		nr_chips = NR_CHIPS;
809 
810 	pr_info("windfarm: Initializing for desktop G5 with %d chips\n",
811 		nr_chips);
812 
813 	/* Get MPU data for each CPU */
814 	for (i = 0; i < nr_chips; i++) {
815 		cpu_mpu_data[i] = wf_get_mpu(i);
816 		if (!cpu_mpu_data[i]) {
817 			pr_err("wf_pm72: Failed to find MPU data for CPU %d\n", i);
818 			return -ENXIO;
819 		}
820 	}
821 
822 #ifdef MODULE
823 	request_module("windfarm_fcu_controls");
824 	request_module("windfarm_lm75_sensor");
825 	request_module("windfarm_ad7417_sensor");
826 	request_module("windfarm_max6690_sensor");
827 	request_module("windfarm_cpufreq_clamp");
828 #endif /* MODULE */
829 
830 	platform_driver_register(&wf_pm72_driver);
831 	return 0;
832 }
833 
wf_pm72_exit(void)834 static void __exit wf_pm72_exit(void)
835 {
836 	platform_driver_unregister(&wf_pm72_driver);
837 }
838 
839 module_init(wf_pm72_init);
840 module_exit(wf_pm72_exit);
841 
842 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
843 MODULE_DESCRIPTION("Thermal control for AGP PowerMac G5s");
844 MODULE_LICENSE("GPL");
845 MODULE_ALIAS("platform:windfarm");
846