12c162f9bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2*e3e528d2SLi zeming #ifndef _WINDFARM_PID_H 3*e3e528d2SLi zeming #define _WINDFARM_PID_H 4*e3e528d2SLi zeming 575722d39SBenjamin Herrenschmidt /* 675722d39SBenjamin Herrenschmidt * Windfarm PowerMac thermal control. Generic PID helpers 775722d39SBenjamin Herrenschmidt * 875722d39SBenjamin Herrenschmidt * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp. 975722d39SBenjamin Herrenschmidt * <benh@kernel.crashing.org> 1075722d39SBenjamin Herrenschmidt * 1175722d39SBenjamin Herrenschmidt * This is a pair of generic PID helpers that can be used by 1275722d39SBenjamin Herrenschmidt * control loops. One is the basic PID implementation, the 1375722d39SBenjamin Herrenschmidt * other one is more specifically tailored to the loops used 1475722d39SBenjamin Herrenschmidt * for CPU control with 2 input sample types (temp and power) 1575722d39SBenjamin Herrenschmidt */ 1675722d39SBenjamin Herrenschmidt 1775722d39SBenjamin Herrenschmidt /* 1875722d39SBenjamin Herrenschmidt * *** Simple PID *** 1975722d39SBenjamin Herrenschmidt */ 2075722d39SBenjamin Herrenschmidt 2175722d39SBenjamin Herrenschmidt #define WF_PID_MAX_HISTORY 32 2275722d39SBenjamin Herrenschmidt 2375722d39SBenjamin Herrenschmidt /* This parameter array is passed to the PID algorithm. Currently, 2475722d39SBenjamin Herrenschmidt * we don't support changing parameters on the fly as it's not needed 2575722d39SBenjamin Herrenschmidt * but could be implemented (with necessary adjustment of the history 2675722d39SBenjamin Herrenschmidt * buffer 2775722d39SBenjamin Herrenschmidt */ 2875722d39SBenjamin Herrenschmidt struct wf_pid_param { 2975722d39SBenjamin Herrenschmidt int interval; /* Interval between samples in seconds */ 3075722d39SBenjamin Herrenschmidt int history_len; /* Size of history buffer */ 3175722d39SBenjamin Herrenschmidt int additive; /* 1: target relative to previous value */ 3275722d39SBenjamin Herrenschmidt s32 gd, gp, gr; /* PID gains */ 3375722d39SBenjamin Herrenschmidt s32 itarget; /* PID input target */ 3475722d39SBenjamin Herrenschmidt s32 min,max; /* min and max target values */ 3575722d39SBenjamin Herrenschmidt }; 3675722d39SBenjamin Herrenschmidt 3775722d39SBenjamin Herrenschmidt struct wf_pid_state { 3875722d39SBenjamin Herrenschmidt int first; /* first run of the loop */ 3975722d39SBenjamin Herrenschmidt int index; /* index of current sample */ 4075722d39SBenjamin Herrenschmidt s32 target; /* current target value */ 4175722d39SBenjamin Herrenschmidt s32 samples[WF_PID_MAX_HISTORY]; /* samples history buffer */ 4275722d39SBenjamin Herrenschmidt s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ 4375722d39SBenjamin Herrenschmidt 4475722d39SBenjamin Herrenschmidt struct wf_pid_param param; 4575722d39SBenjamin Herrenschmidt }; 4675722d39SBenjamin Herrenschmidt 4775722d39SBenjamin Herrenschmidt extern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param); 4875722d39SBenjamin Herrenschmidt extern s32 wf_pid_run(struct wf_pid_state *st, s32 sample); 4975722d39SBenjamin Herrenschmidt 5075722d39SBenjamin Herrenschmidt 5175722d39SBenjamin Herrenschmidt /* 5275722d39SBenjamin Herrenschmidt * *** CPU PID *** 5375722d39SBenjamin Herrenschmidt */ 5475722d39SBenjamin Herrenschmidt 5575722d39SBenjamin Herrenschmidt #define WF_CPU_PID_MAX_HISTORY 32 5675722d39SBenjamin Herrenschmidt 5775722d39SBenjamin Herrenschmidt /* This parameter array is passed to the CPU PID algorithm. Currently, 5875722d39SBenjamin Herrenschmidt * we don't support changing parameters on the fly as it's not needed 5975722d39SBenjamin Herrenschmidt * but could be implemented (with necessary adjustment of the history 6075722d39SBenjamin Herrenschmidt * buffer 6175722d39SBenjamin Herrenschmidt */ 6275722d39SBenjamin Herrenschmidt struct wf_cpu_pid_param { 6375722d39SBenjamin Herrenschmidt int interval; /* Interval between samples in seconds */ 6475722d39SBenjamin Herrenschmidt int history_len; /* Size of history buffer */ 6575722d39SBenjamin Herrenschmidt s32 gd, gp, gr; /* PID gains */ 6675722d39SBenjamin Herrenschmidt s32 pmaxadj; /* PID max power adjust */ 6775722d39SBenjamin Herrenschmidt s32 ttarget; /* PID input target */ 6875722d39SBenjamin Herrenschmidt s32 tmax; /* PID input max */ 6975722d39SBenjamin Herrenschmidt s32 min,max; /* min and max target values */ 7075722d39SBenjamin Herrenschmidt }; 7175722d39SBenjamin Herrenschmidt 7275722d39SBenjamin Herrenschmidt struct wf_cpu_pid_state { 7375722d39SBenjamin Herrenschmidt int first; /* first run of the loop */ 7475722d39SBenjamin Herrenschmidt int index; /* index of current power */ 7575722d39SBenjamin Herrenschmidt int tindex; /* index of current temp */ 7675722d39SBenjamin Herrenschmidt s32 target; /* current target value */ 77ac171c46SBenjamin Herrenschmidt s32 last_delta; /* last Tactual - Ttarget */ 7875722d39SBenjamin Herrenschmidt s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ 7975722d39SBenjamin Herrenschmidt s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ 8075722d39SBenjamin Herrenschmidt s32 temps[2]; /* temp. history buffer */ 8175722d39SBenjamin Herrenschmidt 8275722d39SBenjamin Herrenschmidt struct wf_cpu_pid_param param; 8375722d39SBenjamin Herrenschmidt }; 8475722d39SBenjamin Herrenschmidt 8575722d39SBenjamin Herrenschmidt extern void wf_cpu_pid_init(struct wf_cpu_pid_state *st, 8675722d39SBenjamin Herrenschmidt struct wf_cpu_pid_param *param); 8775722d39SBenjamin Herrenschmidt extern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp); 88*e3e528d2SLi zeming 89*e3e528d2SLi zeming #endif /* _WINDFARM_PID_H */ 90