Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Windfarm PowerMac thermal control. Generic PID helpers
0004  *
0005  * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
0006  *                    <benh@kernel.crashing.org>
0007  *
0008  * This is a pair of generic PID helpers that can be used by
0009  * control loops. One is the basic PID implementation, the
0010  * other one is more specifically tailored to the loops used
0011  * for CPU control with 2 input sample types (temp and power)
0012  */
0013 
0014 /*
0015  * *** Simple PID ***
0016  */
0017 
0018 #define WF_PID_MAX_HISTORY  32
0019 
0020 /* This parameter array is passed to the PID algorithm. Currently,
0021  * we don't support changing parameters on the fly as it's not needed
0022  * but could be implemented (with necessary adjustment of the history
0023  * buffer
0024  */
0025 struct wf_pid_param {
0026     int interval;   /* Interval between samples in seconds */
0027     int history_len;    /* Size of history buffer */
0028     int additive;   /* 1: target relative to previous value */
0029     s32 gd, gp, gr; /* PID gains */
0030     s32 itarget;    /* PID input target */
0031     s32 min,max;    /* min and max target values */
0032 };
0033 
0034 struct wf_pid_state {
0035     int first;              /* first run of the loop */
0036     int index;              /* index of current sample */
0037     s32 target;             /* current target value */
0038     s32 samples[WF_PID_MAX_HISTORY];    /* samples history buffer */
0039     s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
0040 
0041     struct wf_pid_param param;
0042 };
0043 
0044 extern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param);
0045 extern s32 wf_pid_run(struct wf_pid_state *st, s32 sample);
0046 
0047 
0048 /*
0049  * *** CPU PID ***
0050  */
0051 
0052 #define WF_CPU_PID_MAX_HISTORY  32
0053 
0054 /* This parameter array is passed to the CPU PID algorithm. Currently,
0055  * we don't support changing parameters on the fly as it's not needed
0056  * but could be implemented (with necessary adjustment of the history
0057  * buffer
0058  */
0059 struct wf_cpu_pid_param {
0060     int interval;   /* Interval between samples in seconds */
0061     int history_len;    /* Size of history buffer */
0062     s32 gd, gp, gr; /* PID gains */
0063     s32 pmaxadj;    /* PID max power adjust */
0064     s32 ttarget;    /* PID input target */
0065     s32 tmax;       /* PID input max */
0066     s32 min,max;    /* min and max target values */
0067 };
0068 
0069 struct wf_cpu_pid_state {
0070     int first;              /* first run of the loop */
0071     int index;              /* index of current power */
0072     int tindex;             /* index of current temp */
0073     s32 target;             /* current target value */
0074     s32 last_delta;         /* last Tactual - Ttarget */
0075     s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */
0076     s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
0077     s32 temps[2];           /* temp. history buffer */
0078 
0079     struct wf_cpu_pid_param param;
0080 };
0081 
0082 extern void wf_cpu_pid_init(struct wf_cpu_pid_state *st,
0083                 struct wf_cpu_pid_param *param);
0084 extern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp);