| xj | b04a402 | 2021-11-25 15:01:52 +0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Windfarm PowerMac thermal control. Generic PID helpers | 
|  | 3 | * | 
|  | 4 | * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp. | 
|  | 5 | *                    <benh@kernel.crashing.org> | 
|  | 6 | * | 
|  | 7 | * Released under the term of the GNU GPL v2. | 
|  | 8 | * | 
|  | 9 | * This is a pair of generic PID helpers that can be used by | 
|  | 10 | * control loops. One is the basic PID implementation, the | 
|  | 11 | * other one is more specifically tailored to the loops used | 
|  | 12 | * for CPU control with 2 input sample types (temp and power) | 
|  | 13 | */ | 
|  | 14 |  | 
|  | 15 | /* | 
|  | 16 | * *** Simple PID *** | 
|  | 17 | */ | 
|  | 18 |  | 
|  | 19 | #define WF_PID_MAX_HISTORY	32 | 
|  | 20 |  | 
|  | 21 | /* This parameter array is passed to the PID algorithm. Currently, | 
|  | 22 | * we don't support changing parameters on the fly as it's not needed | 
|  | 23 | * but could be implemented (with necessary adjustment of the history | 
|  | 24 | * buffer | 
|  | 25 | */ | 
|  | 26 | struct wf_pid_param { | 
|  | 27 | int	interval;	/* Interval between samples in seconds */ | 
|  | 28 | int	history_len;	/* Size of history buffer */ | 
|  | 29 | int	additive;	/* 1: target relative to previous value */ | 
|  | 30 | s32	gd, gp, gr;	/* PID gains */ | 
|  | 31 | s32	itarget;	/* PID input target */ | 
|  | 32 | s32	min,max;	/* min and max target values */ | 
|  | 33 | }; | 
|  | 34 |  | 
|  | 35 | struct wf_pid_state { | 
|  | 36 | int	first;				/* first run of the loop */ | 
|  | 37 | int	index; 				/* index of current sample */ | 
|  | 38 | s32	target;				/* current target value */ | 
|  | 39 | s32	samples[WF_PID_MAX_HISTORY];	/* samples history buffer */ | 
|  | 40 | s32	errors[WF_PID_MAX_HISTORY];	/* error history buffer */ | 
|  | 41 |  | 
|  | 42 | struct wf_pid_param param; | 
|  | 43 | }; | 
|  | 44 |  | 
|  | 45 | extern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param); | 
|  | 46 | extern s32 wf_pid_run(struct wf_pid_state *st, s32 sample); | 
|  | 47 |  | 
|  | 48 |  | 
|  | 49 | /* | 
|  | 50 | * *** CPU PID *** | 
|  | 51 | */ | 
|  | 52 |  | 
|  | 53 | #define WF_CPU_PID_MAX_HISTORY	32 | 
|  | 54 |  | 
|  | 55 | /* This parameter array is passed to the CPU PID algorithm. Currently, | 
|  | 56 | * we don't support changing parameters on the fly as it's not needed | 
|  | 57 | * but could be implemented (with necessary adjustment of the history | 
|  | 58 | * buffer | 
|  | 59 | */ | 
|  | 60 | struct wf_cpu_pid_param { | 
|  | 61 | int	interval;	/* Interval between samples in seconds */ | 
|  | 62 | int	history_len;	/* Size of history buffer */ | 
|  | 63 | s32	gd, gp, gr;	/* PID gains */ | 
|  | 64 | s32	pmaxadj;	/* PID max power adjust */ | 
|  | 65 | s32	ttarget;	/* PID input target */ | 
|  | 66 | s32	tmax;		/* PID input max */ | 
|  | 67 | s32	min,max;	/* min and max target values */ | 
|  | 68 | }; | 
|  | 69 |  | 
|  | 70 | struct wf_cpu_pid_state { | 
|  | 71 | int	first;				/* first run of the loop */ | 
|  | 72 | int	index; 				/* index of current power */ | 
|  | 73 | int	tindex; 			/* index of current temp */ | 
|  | 74 | s32	target;				/* current target value */ | 
|  | 75 | s32	last_delta;			/* last Tactual - Ttarget */ | 
|  | 76 | s32	powers[WF_PID_MAX_HISTORY];	/* power history buffer */ | 
|  | 77 | s32	errors[WF_PID_MAX_HISTORY];	/* error history buffer */ | 
|  | 78 | s32	temps[2];			/* temp. history buffer */ | 
|  | 79 |  | 
|  | 80 | struct wf_cpu_pid_param param; | 
|  | 81 | }; | 
|  | 82 |  | 
|  | 83 | extern void wf_cpu_pid_init(struct wf_cpu_pid_state *st, | 
|  | 84 | struct wf_cpu_pid_param *param); | 
|  | 85 | extern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp); |