meta-quanta: gbs: add pid controller with config

1. add pid control with fan table config
2. add reboot control service to set fan duty to expected default
   value before pid control up
3. initial read-margin-temp with json file and the script waits
   related hwmon sensor could monitor

Signed-off-by: George Hung <george.hung@quantatw.com>
Change-Id: I6433078915b7c4df498bcb0f7a271dccaf66fbfa
diff --git a/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/config.json b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/config.json
new file mode 100644
index 0000000..e28ac9c
--- /dev/null
+++ b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/config.json
@@ -0,0 +1,238 @@
+{
+    "version" : "R00",
+    "sensors" : [
+        {
+            "name": "fan0",
+            "type": "fan",
+            "readPath": "/xyz/openbmc_project/sensors/fan_tach/fan0",
+            "writePath": "/sys/devices/platform/ahb/ahb:apb/f0103000.pwm-fan-controller/hwmon/Fan_0_To_4_Hwmon/pwm1",
+            "min": 0,
+            "max": 255
+        },
+        {
+            "name": "fan1",
+            "type": "fan",
+            "readPath": "/xyz/openbmc_project/sensors/fan_tach/fan1",
+            "writePath": "/sys/devices/platform/ahb/ahb:apb/f0103000.pwm-fan-controller/hwmon/Fan_0_To_4_Hwmon/pwm2",
+            "min": 0,
+            "max": 255
+        },
+        {
+            "name": "fan2",
+            "type": "fan",
+            "readPath": "/xyz/openbmc_project/sensors/fan_tach/fan2",
+            "writePath": "/sys/devices/platform/ahb/ahb:apb/f0103000.pwm-fan-controller/hwmon/Fan_0_To_4_Hwmon/pwm3",
+            "min": 0,
+            "max": 255
+        },
+        {
+            "name": "fan3",
+            "type": "fan",
+            "readPath": "/xyz/openbmc_project/sensors/fan_tach/fan3",
+            "writePath": "/sys/devices/platform/ahb/ahb:apb/f0103000.pwm-fan-controller/hwmon/Fan_0_To_4_Hwmon/pwm4",
+            "min": 0,
+            "max": 255
+        },
+        {
+            "name": "fan4",
+            "type": "fan",
+            "readPath": "/xyz/openbmc_project/sensors/fan_tach/fan4",
+            "writePath": "/sys/devices/platform/ahb/ahb:apb/f0103000.pwm-fan-controller/hwmon/Fan_0_To_4_Hwmon/pwm5",
+            "min": 0,
+            "max": 255
+        },
+        {
+            "name": "fleeting0",
+            "type": "margin",
+            "readPath": "/xyz/openbmc_project/extsensors/margin/fleeting0",
+            "writePath": "",
+            "min": 0,
+            "max": 0,
+            "ignoreDbusMinMax": true,
+            "timeout": 0
+        },
+        {
+            "name": "fleeting1",
+            "type": "margin",
+            "readPath": "/xyz/openbmc_project/extsensors/margin/fleeting1",
+            "writePath": "",
+            "min": 0,
+            "max": 0,
+            "ignoreDbusMinMax": true,
+            "timeout": 0
+        },
+        {
+            "name": "real_fleeting0",
+            "type": "margin",
+            "readPath": "/xyz/openbmc_project/extsensors/margin/real_fleeting0",
+            "writePath": "",
+            "min": 0,
+            "max": 0,
+            "ignoreDbusMinMax": true,
+            "timeout": 0
+        },
+        {
+            "name": "real_fleeting1",
+            "type": "margin",
+            "readPath": "/xyz/openbmc_project/extsensors/margin/real_fleeting1",
+            "writePath": "",
+            "min": 0,
+            "max": 0,
+            "ignoreDbusMinMax": true,
+            "timeout": 0
+        }
+    ],
+    "zones" : [
+        {
+            "id": 0,
+            "minThermalOutput": 0.0,
+            "failsafePercent": 100.0,
+            "pids": [
+                {
+                    "name": "fan0",
+                    "type": "fan",
+                    "inputs": ["fan0"],
+                    "setpoint": 0.0,
+                    "pid": {
+                        "samplePeriod": 0.1,
+                        "proportionalCoeff": 0.0,
+                        "integralCoeff": 0.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0056,
+                        "integralLimit_min": 0.0,
+                        "integralLimit_max": 0.0,
+                        "outLim_min": 20.0,
+                        "outLim_max": 100.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0
+                    }
+                },
+                {
+                    "name": "fan1",
+                    "type": "fan",
+                    "inputs": ["fan1"],
+                    "setpoint": 0.0,
+                    "pid": {
+                        "samplePeriod": 0.1,
+                        "proportionalCoeff": 0.0,
+                        "integralCoeff": 0.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0056,
+                        "integralLimit_min": 0.0,
+                        "integralLimit_max": 0.0,
+                        "outLim_min": 20.0,
+                        "outLim_max": 100.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0
+                    }
+                },
+                {
+                    "name": "real_fleeting0",
+                    "type": "margin",
+                    "inputs": ["real_fleeting0"],
+                    "setpoint": 10.0,
+                    "pid": {
+                        "samplePeriod": 1.0,
+                        "proportionalCoeff": 225.0,
+                        "integralCoeff": 45.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0,
+                        "integralLimit_min": 2500.0,
+                        "integralLimit_max": 18000.0,
+                        "outLim_min": 2500.0,
+                        "outLim_max": 18000.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0,
+                        "positiveHysteresis": 0.0,
+                        "negativeHysteresis": 0.0
+                    }
+                }
+            ]
+        },
+        {
+            "id": 1,
+            "minThermalOutput": 0.0,
+            "failsafePercent": 100.0,
+            "pids": [
+                {
+                    "name": "fan2",
+                    "type": "fan",
+                    "inputs": ["fan2"],
+                    "setpoint": 0.0,
+                    "pid": {
+                        "samplePeriod": 0.1,
+                        "proportionalCoeff": 0.0,
+                        "integralCoeff": 0.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0056,
+                        "integralLimit_min": 0.0,
+                        "integralLimit_max": 0.0,
+                        "outLim_min": 20.0,
+                        "outLim_max": 100.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0
+                    }
+                },
+                {
+                    "name": "fan3",
+                    "type": "fan",
+                    "inputs": ["fan3"],
+                    "setpoint": 0.0,
+                    "pid": {
+                        "samplePeriod": 0.1,
+                        "proportionalCoeff": 0.0,
+                        "integralCoeff": 0.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0056,
+                        "integralLimit_min": 0.0,
+                        "integralLimit_max": 0.0,
+                        "outLim_min": 20.0,
+                        "outLim_max": 100.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0
+                    }
+                },
+                {
+                    "name": "fan4",
+                    "type": "fan",
+                    "inputs": ["fan4"],
+                    "setpoint": 0.0,
+                    "pid": {
+                        "samplePeriod": 0.1,
+                        "proportionalCoeff": 0.0,
+                        "integralCoeff": 0.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0056,
+                        "integralLimit_min": 0.0,
+                        "integralLimit_max": 0.0,
+                        "outLim_min": 20.0,
+                        "outLim_max": 100.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0
+                    }
+                },
+                {
+                    "name": "real_fleeting1",
+                    "type": "margin",
+                    "inputs": ["real_fleeting1"],
+                    "setpoint": 10.0,
+                    "pid": {
+                        "samplePeriod": 1.0,
+                        "proportionalCoeff": 225.0,
+                        "integralCoeff": 45.0,
+                        "feedFwdOffsetCoeff": 0.0,
+                        "feedFwdGainCoeff": 0.0,
+                        "integralLimit_min": 2500.0,
+                        "integralLimit_max": 18000.0,
+                        "outLim_min": 2500.0,
+                        "outLim_max": 18000.0,
+                        "slewNeg": 0.0,
+                        "slewPos": 0.0,
+                        "positiveHysteresis": 0.0,
+                        "negativeHysteresis": 0.0
+                    }
+                }
+            ]
+        }
+    ]
+}
diff --git a/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-default-speed.sh b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-default-speed.sh
new file mode 100644
index 0000000..22cfab5
--- /dev/null
+++ b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-default-speed.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for i in {1..5};
+do
+    echo 255 > /sys/class/hwmon/*/pwm${i}
+done
diff --git a/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-reboot-control.service b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-reboot-control.service
new file mode 100644
index 0000000..681bdbe
--- /dev/null
+++ b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-reboot-control.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Set Fan to Default Duty as Rebooting
+DefaultDependencies=no
+After=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=true
+ExecStart=/usr/bin/fan-default-speed.sh
+
+[Install]
+WantedBy=shutdown.target
diff --git a/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-table-init.sh b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-table-init.sh
new file mode 100644
index 0000000..06914af
--- /dev/null
+++ b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/fan-table-init.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# wait for fan dbus
+mapper wait /xyz/openbmc_project/sensors/fan_tach/fan0
+mapper wait /xyz/openbmc_project/sensors/fan_tach/fan1
+mapper wait /xyz/openbmc_project/sensors/fan_tach/fan2
+mapper wait /xyz/openbmc_project/sensors/fan_tach/fan3
+mapper wait /xyz/openbmc_project/sensors/fan_tach/fan4
+
+/usr/bin/fan-default-speed.sh
+
+# generate fan table writePath
+Fan_0_To_4_Hwmon="$(ls -la /sys/class/hwmon |grep pwm |  head -n 1| tail -n +1|cut -d '/' -f 9)"
+
+if [[ "$Fan_0_To_4_Hwmon" != "" ]]
+then
+     sed -i "s/Fan_0_To_4_Hwmon/$Fan_0_To_4_Hwmon/g" /usr/share/swampd/config.json
+fi
+
+# start read margin temp wait
+/usr/bin/read-margin-temp-wait.sh &
+
+exit 0
diff --git a/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service
new file mode 100644
index 0000000..33a4419
--- /dev/null
+++ b/meta-gbs/recipes-phosphor/fans/phosphor-pid-control/phosphor-pid-control.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Swampd Margin-based Fan Control Daemon
+After=xyz.openbmc_project.Hwmon@-ahb-apb-pwm\x2dfan\x2dcontroller\x40103000.service
+
+[Service]
+Type=simple
+ExecStartPre=/usr/bin/fan-table-init.sh
+ExecStart=/usr/bin/swampd
+Restart=always
+RestartSec=5
+StartLimitInterval=0
+ExecStopPost=/usr/bin/fan-default-speed.sh
+
+[Install]
+WantedBy=basic.target