meta-ampere: mtjade: Add more Host firmware support

Add support SCP firmware update with checking if the ampere_fru_upgrade
available to execute the update.
This commit also supports 2nd Host SPI-NOR update ability.

Tested:
1. Manually copy ampere_fru_upgrade to the /usr/sbin folder and run SCP
firmware update via Redfish.
2. Flash UEFI firmware update on the secondary Host SPI-NOR.

Signed-off-by: Thang Q. Nguyen <thang@os.amperecomputing.com>
Change-Id: Ic335ee2d21625239c3df1937ed5333708233845b
diff --git a/meta-ampere/meta-jade/conf/machine/mtjade.conf b/meta-ampere/meta-jade/conf/machine/mtjade.conf
index 633efa0..ede176a 100644
--- a/meta-ampere/meta-jade/conf/machine/mtjade.conf
+++ b/meta-ampere/meta-jade/conf/machine/mtjade.conf
@@ -32,7 +32,6 @@
                                    ampere-flash-utils \
                                    ampere-mac-update \
                                    mtjade-gpio-config \
-                                   mtd-utils \
                                    ampere-platform-init \
                                    ampere-ipmi-oem \
                                   "
diff --git a/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils.bb b/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils.bb
index 241070c..844709b 100644
--- a/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils.bb
+++ b/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils.bb
@@ -9,6 +9,7 @@
 DEPENDS = "zlib"
 
 SRC_URI += "\
+            file://ampere_firmware_upgrade.sh \
             file://ampere_flash_bios.sh \
            "
 
@@ -19,5 +20,6 @@
 
 do_install:append() {
     install -d ${D}/usr/sbin
+    install -m 0755 ${WORKDIR}/ampere_firmware_upgrade.sh ${D}/${sbindir}/ampere_firmware_upgrade.sh
     install -m 0755 ${S}/ampere_flash_bios.sh ${D}/${sbindir}/ampere_flash_bios.sh
 }
diff --git a/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_firmware_upgrade.sh b/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_firmware_upgrade.sh
new file mode 100755
index 0000000..130682d
--- /dev/null
+++ b/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_firmware_upgrade.sh
@@ -0,0 +1,144 @@
+#!/bin/bash
+
+do_fru_upgrade() {
+	FRU_DEVICE="/sys/bus/i2c/devices/3-0050/eeprom"
+
+	if ! command -v ampere_fru_upgrade;
+	then
+		echo "Bypass fru update as no ampere_fru_upgrade available"
+		exit
+	fi
+	ampere_fru_upgrade -d $FRU_DEVICE -f "$IMAGE"
+
+	systemctl restart xyz.openbmc_project.FruDevice.service
+	systemctl restart phosphor-ipmi-host.service
+}
+
+do_smpmpro_upgrade() {
+	I2C_BUS_DEV="1"
+	EEPROM_ADDR="0x50"
+
+	if ! command -v ampere_eeprom_prog;
+	then
+		echo "Bypass SCP firmware update as no ampere_eeprom_prog available"
+		exit
+	fi
+	echo "SECPRO mode: $SECPRO"
+	# Turn off the Host if it is currently ON
+	chassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}')
+	echo "Current Chassis State: $chassisstate"
+	if [ "$chassisstate" == 'On' ];
+	then
+		echo "Turning the Chassis off"
+		obmcutil chassisoff
+		sleep 15
+		# Check if HOST was OFF
+		chassisstate_off=$(obmcutil chassisstate | awk -F. '{print $NF}')
+		if [ "$chassisstate_off" == 'On' ];
+		then
+			echo "Error : Failed turning the Chassis off"
+			exit
+		fi
+	fi
+
+	if [[ $SECPRO == 1 ]]; then
+		# 3 is S0_SPECIAL_BOOT
+		gpioset 0 3=1
+		# 66 is S1_SPECIAL_BOOT
+		gpioset 0 66=1
+	fi
+
+	# Switch EEPROM control to BMC AST2500 I2C
+	# 226 is BMC_GPIOAC2_SPI0_PROGRAM_SEL
+	gpioset 0 226=0
+
+	# 08 is BMC_GPIOB0_I2C_BACKUP_SEL
+	if [[ $DEV_SEL == 1 ]]; then
+		echo "Run update primary Boot EEPROM"
+		gpioset 0 8=1       # Main EEPROM
+	elif [[ $DEV_SEL == 2 ]]; then
+		echo "Run update secondary Boot EEPROM"
+		gpioset 0 8=0       # Second EEPROM
+	else
+		echo "Please choose Main (1) or Second EEPROM (2)"
+		exit 0
+	fi
+
+	# Write Firmware to EEPROM and read back for validation
+	ampere_eeprom_prog -b $I2C_BUS_DEV -s $EEPROM_ADDR -p -f "$IMAGE"
+
+	# Switch EEPROM control to Host
+	# 08 is BMC_GPIOB0_I2C_BACKUP_SEL
+	gpioset 0 8=1
+	# 226 is BMC_GPIOAC2_SPI0_PROGRAM_SEL
+	gpioset 0 226=1
+
+	if [ "$chassisstate" == 'On' ];
+	then
+		sleep 5
+		echo "Turn on the Host"
+		obmcutil poweron
+	fi
+
+	# Deassert SECPRO GPIO PINs
+	if [[ $SECPRO == 1 ]]; then
+		chassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}')
+		if [ "$chassisstate_off" == 'Off' ]; then
+			obmcutil poweron
+		fi
+
+		sleep 30s
+		echo "De-asserting special GPIO PINs"
+		# 3 is S0_SPECIAL_BOOT
+		gpioset 0 3=0
+		# 66 is S1_SPECIAL_BOOT
+		gpioset 0 66=0
+	fi
+}
+
+
+if [ $# -eq 0 ]; then
+	echo "Usage:"
+	echo "      $(basename "$0") <Type> <Image file> <DEV_SEL> [SECPRO]"
+	echo "Where:"
+	echo "    <Type>: smpmpro or fru"
+	echo "            If Type is smpmpro, then DEV_SEL must is 1 (MAIN EEPROM), 2 (Failover)"
+	echo "    SECPRO: Optional, input '1' to enter & flash secpro mode. Default: 0"
+	exit 0
+fi
+
+TYPE=$1
+IMAGE=$2
+if [ -z "$3" ]
+then
+	DEV_SEL="1"    # by default, select Main image
+else
+	DEV_SEL=$3
+fi
+
+SECPRO=0
+if [ -n "$4" ]; then
+	if [[ "$4" == "1" ]]; then
+		SECPRO=1
+	fi
+fi
+
+MANIFEST="$(echo "$IMAGE" | cut -d'/' -f-4)/MANIFEST"
+if [ -f "$MANIFEST" ]; then
+	echo "MANIFEST: $MANIFEST"
+	if grep -qF "SECPRO" "$MANIFEST"; then
+		SECPRO=1
+	fi
+fi
+
+# Restrict to flash failover in case of SECPRO
+if [ $SECPRO == 1 ] && [ "$DEV_SEL" == 2 ]; then
+	echo "Not allow to flash the failover with SECPRO image"
+	exit
+fi
+
+if [[ $TYPE == "smpmpro" ]]; then
+	do_smpmpro_upgrade
+elif [[ $TYPE == "fru" ]]; then
+	do_fru_upgrade
+fi
diff --git a/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_flash_bios.sh b/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_flash_bios.sh
index b7f4bc5..b13e4b5 100755
--- a/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_flash_bios.sh
+++ b/meta-ampere/meta-jade/recipes-ampere/flash/ampere-flash-utils/ampere_flash_bios.sh
@@ -15,10 +15,8 @@
 # limitations under the License.
 
 do_flash () {
-        OFFSET=$1
-
 	# Check the PNOR partition available
-	HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p')
+	HOST_MTD=$(< /proc/mtd grep "pnor-uefi" | sed -n 's/^\(.*\):.*/\1/p')
 	if [ -z "$HOST_MTD" ];
 	then
 		# If the PNOR partition is not available, then bind again driver
@@ -26,7 +24,7 @@
 		echo 1e630000.spi > /sys/bus/platform/drivers/aspeed-smc/bind
 		sleep 2
 
-		HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p')
+		HOST_MTD=$(< /proc/mtd grep "pnor-uefi" | sed -n 's/^\(.*\):.*/\1/p')
 		if [ -z "$HOST_MTD" ];
 		then
 			echo "Fail to probe Host SPI-NOR device"
@@ -34,8 +32,8 @@
 		fi
 	fi
 
-	echo "--- Flashing firmware to @/dev/$HOST_MTD offset=$OFFSET"
-	flashcp -v "$IMAGE" /dev/"$HOST_MTD" "$OFFSET"
+	echo "--- Flashing firmware to @/dev/$HOST_MTD"
+	flashcp -v "$IMAGE" /dev/"$HOST_MTD"
 }
 
 
@@ -50,6 +48,12 @@
 	exit 1
 fi
 
+if [ -z "$2" ]; then
+       DEV_SEL="1"    # by default, select primary device
+else
+       DEV_SEL="$2"
+fi
+
 # Turn off the Host if it is currently ON
 chassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}')
 echo "--- Current Chassis State: $chassisstate"
@@ -74,8 +78,21 @@
 	exit 1
 fi
 
+# Switch the host SPI bus (between primary and secondary)
+# 227 is BMC_SPI0_BACKUP_SEL
+if [[ $DEV_SEL == 1 ]]; then
+	echo "Run update primary Host SPI-NOR"
+	gpioset 0 227=0       # Primary SPI
+elif [[ $DEV_SEL == 2 ]]; then
+	echo "Run update secondary Host SPI-NOR"
+	gpioset 0 227=1       # Second SPI
+else
+	echo "Please choose primary SPI (1) or second SPI (2)"
+	exit 0
+fi
+
 # Flash the firmware
-do_flash 0x400000
+do_flash
 
 # Switch the host SPI bus to HOST."
 echo "--- Switch the host SPI bus to HOST."