162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci#ifndef _WINDFARM_PID_H 362306a36Sopenharmony_ci#define _WINDFARM_PID_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Windfarm PowerMac thermal control. Generic PID helpers 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp. 962306a36Sopenharmony_ci * <benh@kernel.crashing.org> 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * This is a pair of generic PID helpers that can be used by 1262306a36Sopenharmony_ci * control loops. One is the basic PID implementation, the 1362306a36Sopenharmony_ci * other one is more specifically tailored to the loops used 1462306a36Sopenharmony_ci * for CPU control with 2 input sample types (temp and power) 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* 1862306a36Sopenharmony_ci * *** Simple PID *** 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define WF_PID_MAX_HISTORY 32 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* This parameter array is passed to the PID algorithm. Currently, 2462306a36Sopenharmony_ci * we don't support changing parameters on the fly as it's not needed 2562306a36Sopenharmony_ci * but could be implemented (with necessary adjustment of the history 2662306a36Sopenharmony_ci * buffer 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_cistruct wf_pid_param { 2962306a36Sopenharmony_ci int interval; /* Interval between samples in seconds */ 3062306a36Sopenharmony_ci int history_len; /* Size of history buffer */ 3162306a36Sopenharmony_ci int additive; /* 1: target relative to previous value */ 3262306a36Sopenharmony_ci s32 gd, gp, gr; /* PID gains */ 3362306a36Sopenharmony_ci s32 itarget; /* PID input target */ 3462306a36Sopenharmony_ci s32 min,max; /* min and max target values */ 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistruct wf_pid_state { 3862306a36Sopenharmony_ci int first; /* first run of the loop */ 3962306a36Sopenharmony_ci int index; /* index of current sample */ 4062306a36Sopenharmony_ci s32 target; /* current target value */ 4162306a36Sopenharmony_ci s32 samples[WF_PID_MAX_HISTORY]; /* samples history buffer */ 4262306a36Sopenharmony_ci s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci struct wf_pid_param param; 4562306a36Sopenharmony_ci}; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ciextern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param); 4862306a36Sopenharmony_ciextern s32 wf_pid_run(struct wf_pid_state *st, s32 sample); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* 5262306a36Sopenharmony_ci * *** CPU PID *** 5362306a36Sopenharmony_ci */ 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define WF_CPU_PID_MAX_HISTORY 32 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/* This parameter array is passed to the CPU PID algorithm. Currently, 5862306a36Sopenharmony_ci * we don't support changing parameters on the fly as it's not needed 5962306a36Sopenharmony_ci * but could be implemented (with necessary adjustment of the history 6062306a36Sopenharmony_ci * buffer 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_cistruct wf_cpu_pid_param { 6362306a36Sopenharmony_ci int interval; /* Interval between samples in seconds */ 6462306a36Sopenharmony_ci int history_len; /* Size of history buffer */ 6562306a36Sopenharmony_ci s32 gd, gp, gr; /* PID gains */ 6662306a36Sopenharmony_ci s32 pmaxadj; /* PID max power adjust */ 6762306a36Sopenharmony_ci s32 ttarget; /* PID input target */ 6862306a36Sopenharmony_ci s32 tmax; /* PID input max */ 6962306a36Sopenharmony_ci s32 min,max; /* min and max target values */ 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct wf_cpu_pid_state { 7362306a36Sopenharmony_ci int first; /* first run of the loop */ 7462306a36Sopenharmony_ci int index; /* index of current power */ 7562306a36Sopenharmony_ci int tindex; /* index of current temp */ 7662306a36Sopenharmony_ci s32 target; /* current target value */ 7762306a36Sopenharmony_ci s32 last_delta; /* last Tactual - Ttarget */ 7862306a36Sopenharmony_ci s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ 7962306a36Sopenharmony_ci s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ 8062306a36Sopenharmony_ci s32 temps[2]; /* temp. history buffer */ 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci struct wf_cpu_pid_param param; 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciextern void wf_cpu_pid_init(struct wf_cpu_pid_state *st, 8662306a36Sopenharmony_ci struct wf_cpu_pid_param *param); 8762306a36Sopenharmony_ciextern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#endif /* _WINDFARM_PID_H */ 90