meta-romulus: Add AVSBus and VRM workarounds

Add AVSBus and VRM control scripts.
Add systemd services to do AVSBus workaround, disable AVSBus, do VRM workaround and enable
AVSBus.
Add BitBake recipe to install script and services.

Change-Id: I72ec0138d23eba57ee56d5a6b01e3cd638c819bc
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control.bb b/meta-romulus/recipes-phosphor/chassis/avsbus-control.bb
new file mode 100644
index 0000000..f13bf11
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control.bb
@@ -0,0 +1,40 @@
+SUMMARY = "Romulus AVSBus control"
+PR = "r1"
+
+inherit obmc-phosphor-systemd
+inherit obmc-phosphor-license
+
+RDEPENDS_${PN} += "i2c-tools bash"
+
+S = "${WORKDIR}"
+SRC_URI += "file://avsbus-workaround.sh \
+            file://avsbus-enable.sh \
+            file://avsbus-disable.sh"
+
+do_install() {
+        install -d ${D}${bindir}
+        install -m 0755 ${WORKDIR}/avsbus-workaround.sh \
+            ${D}${bindir}/avsbus-workaround.sh
+        install -m 0755 ${WORKDIR}/avsbus-disable.sh \
+            ${D}${bindir}/avsbus-disable.sh
+        install -m 0755 ${WORKDIR}/avsbus-enable.sh \
+            ${D}${bindir}/avsbus-enable.sh
+}
+
+TMPL_EN= "avsbus-enable@.service"
+TMPL_DIS= "avsbus-disable@.service"
+TMPL_WA= "avsbus-workaround@.service"
+INSTFMT_EN= "avsbus-enable@{0}.service"
+INSTFMT_DIS= "avsbus-disable@{0}.service"
+INSTFMT_WA= "avsbus-workaround@{0}.service"
+TGTFMT = "obmc-chassis-start@{0}.target"
+FMT_EN = "../${TMPL_EN}:${TGTFMT}.wants/${INSTFMT_EN}"
+FMT_DIS = "../${TMPL_DIS}:${TGTFMT}.wants/${INSTFMT_DIS}"
+FMT_WA = "../${TMPL_WA}:${TGTFMT}.wants/${INSTFMT_WA}"
+
+SYSTEMD_SERVICE_${PN} += "${TMPL_EN}"
+SYSTEMD_LINK_${PN} += "${@compose_list(d, 'FMT_EN', 'OBMC_CHASSIS_INSTANCES')}"
+SYSTEMD_SERVICE_${PN} += "${TMPL_DIS}"
+SYSTEMD_LINK_${PN} += "${@compose_list(d, 'FMT_DIS', 'OBMC_CHASSIS_INSTANCES')}"
+SYSTEMD_SERVICE_${PN} += "${TMPL_WA}"
+SYSTEMD_LINK_${PN} += "${@compose_list(d, 'FMT_WA', 'OBMC_CHASSIS_INSTANCES')}"
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-disable.sh b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-disable.sh
new file mode 100644
index 0000000..c46c936
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-disable.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+i2cset -y 4 0x70 0x01 0x80 b    # VDD 0
+i2cset -y 4 0x70 0x00 0x01 b    # VCS 0  - PAGE set
+i2cset -y 4 0x70 0x01 0x80 b    # VCS 0
+i2cset -y 4 0x70 0x00 0x00 b    # VCS 0  - PAGE reset
+i2cset -y 4 0x73 0x01 0x80 b    # VDN 0
+i2cset -y 5 0x70 0x01 0x80 b    # VDD 1
+i2cset -y 5 0x70 0x00 0x01 b    # VCS 1  - PAGE set
+i2cset -y 5 0x70 0x01 0x80 b    # VCS 1
+i2cset -y 5 0x70 0x00 0x00 b    # VCS 1  - PAGE reset
+i2cset -y 5 0x73 0x01 0x80 b    # VDN 1
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-disable@.service b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-disable@.service
new file mode 100644
index 0000000..1970f00
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-disable@.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Disable the AVS bus on the VRMs
+Wants=avsbus-workaround@%i.service
+After=avsbus-workaround@%i.service
+Before=vrm-control@%i.service
+Conflicts=obmc-chassis-stop@%i.target
+
+[Service]
+ExecStart={bindir}/avsbus-disable.sh
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy=obmc-chassis-start@%i.target
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-enable.sh b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-enable.sh
new file mode 100644
index 0000000..d47d638
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-enable.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+i2cset -y 4 0x70 0x01 0xB0 b    # VDD 0
+i2cset -y 4 0x70 0x00 0x01 b    # VCS 0  - PAGE set
+i2cset -y 4 0x70 0x01 0xB0 b    # VCS 0
+i2cset -y 4 0x70 0x00 0x00 b    # VCS 0  - PAGE reset
+i2cset -y 4 0x73 0x01 0xB0 b    # VDN 0
+i2cset -y 5 0x70 0x01 0xB0 b    # VDD 1
+i2cset -y 5 0x70 0x00 0x01 b    # VCS 1  - PAGE set
+i2cset -y 5 0x70 0x01 0xB0 b    # VCS 1
+i2cset -y 5 0x70 0x00 0x00 b    # VCS 1  - PAGE reset
+i2cset -y 5 0x73 0x01 0xB0 b    # VDN 1
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-enable@.service b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-enable@.service
new file mode 100644
index 0000000..464287b
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-enable@.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Enable the AVS bus on VRMs
+Wants=vrm-control@%i.service
+After=vrm-control@%i.service
+Wants=obmc-power-start-pre@%i.target
+Before=obmc-power-start-pre@%i.target
+Conflicts=obmc-chassis-stop@%i.target
+
+[Service]
+ExecStart={bindir}/avsbus-enable.sh
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy=obmc-chassis-start@%i.target
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-workaround.sh b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-workaround.sh
new file mode 100644
index 0000000..75ec8ca
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-workaround.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+i2cset -y 4 0x28 0x2E 0x23 b # VDD/VCS 0
+i2cset -y 4 0x2B 0x2E 0x23 b # VDN 0
+i2cset -y 5 0x28 0x2E 0x23 b # VDD/VCS 1
+i2cset -y 5 0x2B 0x2E 0x23 b # VDN 1
+
diff --git a/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-workaround@.service b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-workaround@.service
new file mode 100644
index 0000000..92d1c9f
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/avsbus-control/avsbus-workaround@.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Perform AVS bus workaround on VRMs
+Wants=obmc-power-start-pre@%i.target
+Before=obmc-power-start-pre@%i.target
+Before=avsbus-disable@%i.service
+Conflicts=obmc-chassis-stop@%i.target
+
+[Service]
+ExecStart={bindir}/avsbus-workaround.sh
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy=obmc-chassis-start@%i.target
diff --git a/meta-romulus/recipes-phosphor/chassis/vrm-control.bb b/meta-romulus/recipes-phosphor/chassis/vrm-control.bb
new file mode 100644
index 0000000..b924aae
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/vrm-control.bb
@@ -0,0 +1,24 @@
+SUMMARY = "Romulus VRM Overrides"
+DESCRIPTION = "Sets Rolumus VRMs to custom voltages"
+PR = "r1"
+
+inherit obmc-phosphor-systemd
+inherit obmc-phosphor-license
+
+RDEPENDS_${PN} += "i2c-tools bash"
+
+S = "${WORKDIR}"
+SRC_URI += "file://vrm-control.sh"
+
+do_install() {
+        install -d ${D}${bindir}
+        install -m 0755 ${WORKDIR}/vrm-control.sh ${D}${bindir}/vrm-control.sh
+}
+
+TMPL = "vrm-control@.service"
+INSTFMT = "vrm-control@{0}.service"
+TGTFMT = "obmc-chassis-start@{0}.target"
+FMT = "../${TMPL}:${TGTFMT}.wants/${INSTFMT}"
+
+SYSTEMD_SERVICE_${PN} += "${TMPL}"
+SYSTEMD_LINK_${PN} += "${@compose_list(d, 'FMT', 'OBMC_CHASSIS_INSTANCES')}"
diff --git a/meta-romulus/recipes-phosphor/chassis/vrm-control/vrm-control.sh b/meta-romulus/recipes-phosphor/chassis/vrm-control/vrm-control.sh
new file mode 100644
index 0000000..9e6507e
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/vrm-control/vrm-control.sh
@@ -0,0 +1,144 @@
+#!/bin/bash
+# #########################################################
+# Script to run on BMC to read/set vrm voltages
+
+
+# #########################################################
+d2v () {
+# usage:   d2v <decimal volts>
+
+echo $1 | awk '{print $1 * 256 + .5}' | cut -d '.' -f 1
+}
+
+
+# #########################################################
+v2d () {
+# usage:   v2d <hex val>
+
+printf "	%0.3fV" `echo $1 | awk '{print $1 / 256}'`
+}
+
+
+# #########################################################
+i2d () {
+# usage:  i2d <hex val> <current divisor>
+
+# parse current mantisa and exponent
+# format: SEEE ESMM MMMM MMMM
+let e=$1/0x800
+let esign=e/0x10
+let m=$1\&0x07FF
+let msign=m/0x0400
+
+if [ $msign -eq 1 ]
+then
+  # calc ones compliment
+  let m=($m^0x07FF)+1
+  m="-$m"
+fi
+if [ $esign -eq 1 ]
+then
+  # calc ones compliment
+  let e=(e^0x1F)+1
+  e="-$e"
+fi
+printf "	%0.3fA\n" `echo $m $e $2 | awk '{print ($1 * 2^$2) / $3}'`
+}
+
+
+# #########################################################
+rw_vc () {
+# usage:   rw_vc <bus> <addr> <current divisor> <channel> <value>
+
+# select channel
+if [ $4 != "x" ]
+then
+  i2cset -y $1 $2 0 $4 b
+fi
+
+# write new voltage set point
+if [ ! -e $5 ]
+then
+  i2cset -y $1 $2 0x21 `d2v $5` w
+fi
+
+# print voltage set point
+v2d `i2cget -y $1 $2 0x21 w`
+
+# print voltage
+v2d `i2cget -y $1 $2 0x8B w`
+
+# print current
+i2d `i2cget -y $1 $2 0x8C w` $3
+
+# default back to channel 0
+if [ $4 != "x" ]
+then
+  i2cset -y $1 $2 0 0 b
+fi
+}
+
+
+# #########################################################
+# Main
+
+if [ -e $1 ]
+then
+  $0 vdda vcsa vdna vioa vddra vddb vcsb vdnb viob vddrb
+  exit
+fi
+
+if [ $1 == "-h" ]
+then
+  echo "  Usage: vrm [<rail>=[value] [<rail>=[value]] ...]"
+  echo "    rail: vdda vcsa vdna vioa vddra vddb vcsb vdnb viob vddrb"
+  echo "    value: volts"
+  echo
+  echo "    e.g., vrm vioa=1.0 viob=1.0"
+  echo
+  exit
+fi
+
+echo "rail	set	read	current"
+echo "-------	------- ------- -------"
+for param in ${@:1}
+do
+  rail=`echo $param | cut -d'=' -f 1`
+  val=`echo ${param}= | cut -d'=' -f 2`
+  echo -n "$rail"
+  case "$rail" in
+  # FIXME: What's the addresses for Romulus?
+    vdda)
+      rw_vc 4 0x70 2 0 $val
+      ;;
+    vddb)
+      rw_vc 5 0x70 2 0 $val
+      ;;
+    vcsa)
+      rw_vc 4 0x70 4 1 $val
+      ;;
+    vcsb)
+      rw_vc 5 0x70 4 1 $val
+      ;;
+    vdna)
+      rw_vc 4 0x73 2 0 $val
+      ;;
+    vdnb)
+      rw_vc 5 0x73 2 0 $val
+      ;;
+    vioa)
+      rw_vc 4 0x73 2 1 $val
+      ;;
+    viob)
+      rw_vc 5 0x73 2 1 $val
+      ;;
+    vddra)
+      rw_vc 4 0x72 2 1 $val  # This is wrong
+      ;;
+    vddrb)
+      rw_vc 5 0x72 2 1 $val  # This is wrong
+      ;;
+    *)
+      echo "	non-existant"
+  esac
+done
diff --git a/meta-romulus/recipes-phosphor/chassis/vrm-control/vrm-control@.service b/meta-romulus/recipes-phosphor/chassis/vrm-control/vrm-control@.service
new file mode 100644
index 0000000..716c526
--- /dev/null
+++ b/meta-romulus/recipes-phosphor/chassis/vrm-control/vrm-control@.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Apply voltage overrides to VRMs
+Wants=avsbus-disable@%i.service
+After=avsbus-disable@%i.service
+Before=avsbus-enable@%i.service
+Conflicts=obmc-chassis-stop@%i.target
+
+[Service]
+ExecStart={bindir}/vrm-control.sh vdna=0.9 vddra=1.35 vdnb=0.9 vddrb=1.35
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy=obmc-chassis-start@%i.target