#!/bin/bash
#
# Copyright 2020-present Facebook. All rights reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

#
# The script is designed to access BACKUP_BIOS and OOB_SWITCH_EEPROM. The
# 2 devices should never be accessed simultaneously because they share
# exactly the same SPI pins/lines. Chip select is done by external bus
# switch (controlled by GPIO), and details as below:
#
# - BACKUP_BIOS:
#   The flash is registered under spi1 and paired with aspeed-spi master
#   for better performance.
#   The chip is selected by setting COM_SPI_SEL (aspeed GPIOO0) to 1.
#
# - OOB_SWITCH_EEPROM:
#   The eeprom is registered under spi2 and controlled by spi-gpio. It's
#   not compatible with aspeed-spi controller due to clock/speed mismatch:
#   aspeed-spi controller's mimimum frequency is greater than the eeprom's
#   max frequency.
#   The chip is selected by setting SWITCH_EEPROM1_WRT (aspeed GPIOE2)
#   to 1.
#
# WARNING:
#   Please DO NOT invent new scripts to operate above 2 devices, because
#   concurrent access could potentially corrupt the devices. Check S221767
#   for details.
#

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh
. /usr/local/bin/flashrom-utils.sh

PID_FILE='/var/run/spi_util.pid'

#
# Kernel modules used to talk to backup BIOS.
# The module name is changed to spi_aspeed_user since linux-aspeed-5.15.
#
if modinfo spi_aspeed_user > /dev/null 2>&1; then
    SPI_ASPEED_MODULE=spi_aspeed_user
else
    SPI_ASPEED_MODULE=spi_aspeed
fi

#
# Kernel modules for eeprom access. We decided to use the legacy script
# to read/write eeprom, so these modules will be unloaded. For details,
# please check S235340.
#
SPI_GPIO_MODULE=spi_gpio
SPI_EEPROM_MODULE=eeprom_93xx46

if uname -r | grep "4\.1\.*" > /dev/null 2>&1; then
    LEGACY_KERNEL="true"
fi

check_duplicate_process() {
    exec 99>"$PID_FILE"
    if ! flock -n 99; then
        echo "Another instance is running. Exiting!!"
        exit 1
    fi
}

#
# Helper function to generate pathname of a temporary file.
# Please always use this function to generate temp files so they can be
# removed at cleanup.
#
# $1 - reference file name.
#
spi_tmp_file() {
    name=$(basename "$1")
    echo "/tmp/.spitmp_$name"
}

#
# Helper function to append more bytes to the given file.
#
# $1 - file to be updated.
# $2 - pad size
#
pad_file() {
    out_file="$1"
    pad_size="$2"
    if ! dd if=/dev/zero bs="$pad_size" count=1 | tr "\000" "\377" >> "$out_file"; then
        echo "Error: failed to pad $out_file (pad_size=$pad_size)!"
        exit 1
    fi
}

#
# Helper function to resize a file ($1) to target size ($3).
#
# $1 - input/reference file
# $2 - output file
# $3 - expected size of the output file.
#
resize_file() {
    in_file="$1"
    out_file="$2"
    target_size="$3"

    in_file_sz=$(stat -c%s "$in_file")
    if [ "$in_file_sz" -lt "$target_size" ]; then
        cp "$in_file" "$out_file"
        pad_size=$((target_size - in_file_sz))
        pad_file "$out_file" "$pad_size"
    elif [ "$in_file_sz" -eq "$target_size" ]; then
        ln -s "$(realpath "$in_file")" "$out_file"
    else
        echo "Input file too big: $in_file_sz > $target_size"
        exit 1
    fi
}

kmod_unload() {
    if lsmod | grep "$1" > /dev/null 2>&1; then
        modprobe -r "$1"
    fi
}

kmod_reload() {
    kmod_unload "$1"
    modprobe "$1"
}

#
############################################################
# Functions to deal with spi1.0: the backup BIOS flash.
############################################################
#

spi1_connect() {
    echo "enable spi1 (bios) connection.."

    # Enable SPI master in SCU register
    devmem_set_bit "$(scu_addr 70)" 12

    gpio_set_value COM6_BUF_EN 0

    if [ ! -L "${SHADOW_GPIO}/COM_SPI_SEL" ]; then
        gpio_export_by_name "$ASPEED_GPIO" GPIOO0 COM_SPI_SEL
    fi
    gpio_set_value COM_SPI_SEL 1

    if [ -z "$LEGACY_KERNEL" ]; then
        kmod_reload "$SPI_ASPEED_MODULE"
    fi
}

spi1_disconnect() {
    echo "disable spi1 (bios) connection.."
    if [ -L "${SHADOW_GPIO}/COM_SPI_SEL" ]; then
        gpio_set_value COM_SPI_SEL 0
        gpio_unexport COM_SPI_SEL
    fi

    kmod_unload "$SPI_ASPEED_MODULE"

    # Disable SPI interface
    devmem_clear_bit "$(scu_addr 70)" 12
}

spi1_flash_write() {
    flash_dev="$1"
    in_file="$2"
    flash_model="$3"

    out_file=$(spi_tmp_file "$in_file")
    rm -rf "$out_file"

    if ! flash_size=$(flash_get_size "$flash_dev"); then
        exit 1
    fi

    target_size=$((flash_size * 1024))
    resize_file "$in_file" "$out_file" "$target_size"

    flash_write "$flash_dev" "$out_file" "$flash_model"
}

spi1_flash_detect() {
    if ! flash_dump_summary "$1"; then
        exit 1
    fi
}

spi1_launch_io() {
    op="$1"
    flash_dev="$2"
    image_file="$3"

    if ! flash_model=$(flash_get_model "$flash_dev"); then
        exit 1
    fi

    case "$op" in
        "read")
            flash_read "$flash_dev" "$image_file" "$flash_model"
        ;;
        "write")
            spi1_flash_write "$flash_dev" "$image_file" "$flash_model"
        ;;
        "erase")
            flash_erase "$flash_dev" "$flash_model"
        ;;
        "detect")
            spi1_flash_detect "$flash_dev"
        ;;
        *)
            echo "Operation $op is not supported!"
            exit 1
        ;;
    esac
}

#
############################################################
# Functions to deal with spi2.0: the internal switch eeprom.
############################################################
#

spi2_setup_bitbang() {
    if [ ! -L "${SHADOW_GPIO}/BMC_EEPROM1_SPI_SS" ]; then
        gpio_export_by_name "$ASPEED_GPIO" GPIOI4 BMC_EEPROM1_SPI_SS
        gpio_export_by_name "$ASPEED_GPIO" GPIOI5 BMC_EEPROM1_SPI_SCK
        gpio_export_by_name "$ASPEED_GPIO" GPIOI6 BMC_EEPROM1_SPI_MOSI
        gpio_export_by_name "$ASPEED_GPIO" GPIOI7 BMC_EEPROM1_SPI_MISO
    fi
}

spi2_connect() {
    echo "enable spi2 (eeprom) connection.."

    kmod_unload "$SPI_EEPROM_MODULE"
    kmod_unload "$SPI_GPIO_MODULE"

    if [ ! -L "${SHADOW_GPIO}/SWITCH_EEPROM1_WRT" ]; then
        gpio_export_by_name "$ASPEED_GPIO" GPIOE2 SWITCH_EEPROM1_WRT
    fi

    gpio_set_value SWITCH_EEPROM1_WRT 1
    if [ "$(gpio_get_value SWITCH_EEPROM1_WRT)" -ne "1" ]; then
        echo "Error: unable to set SWITCH_EEPROM1_WRT pin"
        exit 1
    fi

    spi2_setup_bitbang
}

spi2_disconnect() {
    echo "disable spi2 (eeprom) connection.."

    if [ -L "${SHADOW_GPIO}/BMC_EEPROM1_SPI_SS" ]; then
        gpio_unexport BMC_EEPROM1_SPI_SS
        gpio_unexport BMC_EEPROM1_SPI_SCK
        gpio_unexport BMC_EEPROM1_SPI_MOSI
        gpio_unexport BMC_EEPROM1_SPI_MISO
    fi

    kmod_unload "$SPI_EEPROM_MODULE"
    kmod_unload "$SPI_GPIO_MODULE"

    if [ -L "${SHADOW_GPIO}/SWITCH_EEPROM1_WRT" ]; then
        gpio_set_value SWITCH_EEPROM1_WRT 0
        gpio_set_direction SWITCH_EEPROM1_WRT "in"
        gpio_unexport SWITCH_EEPROM1_WRT
    fi
}

spi2_legacy_io() {
    echo "running at93cx6_util_py3.py.."
    /usr/local/bin/at93cx6_util_py3.py --cs BMC_EEPROM1_SPI_SS \
                                       --clk BMC_EEPROM1_SPI_SCK \
                                       --mosi BMC_EEPROM1_SPI_MOSI \
                                       --miso BMC_EEPROM1_SPI_MISO $@
}

cleanup_spi() {
    spi1_disconnect
    spi2_disconnect

    rm -rf /tmp/.spitmp_*
}

ui() {
    op="$1"
    spi_bus="$2"
    file="$4"

    case "$spi_bus" in
        "spi1")
            spi2_disconnect
            spi1_connect

            flash_dev=$(flash_device_name 1 0)
            flash_path="/dev/$flash_dev"
            if [ ! -e "$flash_path" ]; then
                echo "Error: unable to find $flash_path!"
                exit 1
            fi

            spi1_launch_io "$op" "$flash_dev" "$file"
        ;;
        "spi2")
            spi1_disconnect
            spi2_connect

            spi2_legacy_io chip "$op" --file "$file"
        ;;
        *)
            echo "Error: no such SPI bus ($spi_bus)!"
            exit 1
        ;;
    esac
}

usage() {
    local prog
    prog=$(basename "$0")
    echo "Usage:"
    echo "$prog <op> spi1/spi2 <spi device> <file>"
    echo "  <op>          : read, write, erase, detect"
    echo "  <spi1 device> : BACKUP_BIOS"
    echo "  <spi2 device> : OOB_SWITCH_EEPROM"
    echo "Examples:"
    echo "  $prog write spi1 BACKUP_BIOS bios.bin"
    echo "  $prog read spi2 OOB_SWITCH_EEPROM eeprom.bin"
    echo ""
}

check_parameter() {
    op="$1"
    spi="$2"
    dev="$3"
    file="$4"

    case "$op" in
        "read")
            if [ $# -ne 4 ]; then
                echo "Error: <image-file> argument is required!"
                return 1
            fi
            ;;
        "write")
            if [ $# -ne 4 ] || [ ! -f "$file" ]; then
                echo "Error: unable to find image file ${file}!"
                return 1
            fi
            ;;
        "erase" | "detect")
            if [ $# -ne 3 ]; then
                echo "Error: please specific spi device!"
                return 1
            fi
            ;;
        *)
            return 1
            ;;
    esac

    case "$spi" in
        "spi1")
            if [ "$dev" != "BACKUP_BIOS" ]; then
                echo "Error: supported spi1 devices: BACKUP_BIOS!"
                return 1
            fi
            ;;
        "spi2")
            if [ "$dev" != "OOB_SWITCH_EEPROM" ]; then
                echo "Error: supported spi2 devices: OOB_SWITCH_EEPROM!"
                return 1
            fi
            ;;
        *)
            return 1
            ;;
    esac

    return 0
}

check_duplicate_process

if ! check_parameter "$@"; then
    usage
    exit 1
fi

trap cleanup_spi INT TERM QUIT EXIT

ui "$@"


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

prog="$0"

PWD1014A_SYSFS_DIR=$(i2c_device_sysfs_abspath 2-003a)
PWR_SYSTEM_SYSFS="${SYSCPLD_SYSFS_DIR}/pwr_cyc_all_n"
PWR_USRV_RST_SYSFS="${SYSCPLD_SYSFS_DIR}/usrv_rst_n"
PWR_TH_RST_SYSFS="${SYSCPLD_SYSFS_DIR}/th_sys_rst_n"
ALT_SYSRESET_SYSFS="${PWD1014A_SYSFS_DIR}/mod_hard_powercycle"

usage() {
    echo "Usage: $prog <command> [command options]"
    echo
    echo "Commands:"
    echo "  status: Get the current power status"
    echo
    echo "  on: Power on microserver and main power if not powered on already"
    echo "    options:"
    echo "      -f: Re-do power on sequence no matter if microserver has "
    echo "          been powered on or not."
    echo
    echo "  off: Power off microserver and main power ungracefully"
    echo
    echo "  reset: Power reset microserver ungracefully"
    echo "    options:"
    echo "      -s: Power reset whole wedge system ungracefully"
    echo
}

is_main_power_on() {
  status=$(cat $PWR_MAIN_SYSFS | head -1 )
  if [ "$status" == "0x1" ]; then
      return 0            # powered on
  else
      return 1
  fi
}

do_status() {
    return_code=0

    echo -n "Microserver power is "
    if wedge_is_us_on; then
        echo "on"
    else
        echo "off"
        return_code=1
    fi

    echo -n "System main power is "
    if is_main_power_on; then
        echo "on"
    else
        echo "off"
        return_code=1
    fi

    return $return_code
}

do_on_com_e() {
    logger -p user.crit "Powering on microserver..."
    echo 1 > $PWR_USRV_SYSFS
}

do_on_main_pwr() {
    logger -p user.crit "Turning on main power..."
    echo 1 > $PWR_MAIN_SYSFS
}

do_on() {
    local force opt ret
    ret=0
    force=0
    while getopts "f" opt; do
        case $opt in
            f)
                force=1
                ;;
            *)
                usage
                exit -1
                ;;

        esac
    done

    if [ $force -eq 0 ]; then
        # need to check if uS is on or not
        if wedge_is_us_on 10 "."; then
            echo "Skipping because microserver is already on. Use -f to force."
            return 1
        fi
    fi

    # reset TH
    reset_brcm.sh

    # power on sequence
    if ! is_main_power_on; then
      do_on_main_pwr || ret=1
    fi

    do_on_com_e || ret=1

    return $ret
}

do_off_com_e() {
    logger -p user.crit "Powering off microserver..."
    echo 0 > $PWR_USRV_SYSFS
}

do_off_main_pwr() {
    logger -p user.crit "Turning off main power..."
    echo 0 > $PWR_MAIN_SYSFS
}

do_off() {
    local ret
    ret=0

    do_off_com_e || ret=1
    do_off_main_pwr || ret=1

    return $ret
}

do_reset() {
    local system opt pulse_us
    system=0
    while getopts "s" opt; do
        case $opt in
            s)
                system=1
                ;;
            *)
                usage
                exit -1
                ;;
        esac
    done
    if [ $system -eq 1 ]; then
        pulse_us=100000             # 100ms
        logger -p user.crit "Power reset the whole system..."
        echo -n "Power reset the whole system ..."
        sleep 1
        echo 0 > $PWR_SYSTEM_SYSFS
        # Echo 0 above should work already. However, after CPLD upgrade,
        # We need to re-generate the pulse to make this work
        usleep $pulse_us
        echo 1 > $PWR_SYSTEM_SYSFS
        usleep $pulse_us
        echo 0 > $PWR_SYSTEM_SYSFS
        usleep $pulse_us
        echo 1 > $PWR_SYSTEM_SYSFS
        logger -p user.crit "Chassis power failed through CPLD. Will try pwr1014a in 5 sec..."
        sleep 5
        echo 0 > $ALT_SYSRESET_SYSFS
        sleep 1
    else
        if ! wedge_is_us_on; then
            echo "Power resetting microserver that is powered off has no effect."
            echo "Use '$prog on' to power the microserver on"
            return -1
        fi
        # reset TH first
        reset_brcm.sh

        logger -p user.crit "Power reset microserver..."
        echo -n "Power reset microserver ..."
        echo 0 > $PWR_USRV_RST_SYSFS
        sleep 1
        echo 1 > $PWR_USRV_RST_SYSFS
        logger "Successfully power reset micro-server"
    fi
    echo " Done"
    return 0
}

if [ $# -lt 1 ]; then
    usage
    exit -1
fi

command="$1"
shift

case "$command" in
    status)
        do_status $@
        ;;
    on)
        do_on $@
        ;;
    off)
        do_off $@
        ;;
    reset)
        do_reset $@
        ;;
    *)
        usage
        exit -1
        ;;
esac


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

# SAMPLE_SIZE reached by testing in several wedge100 with noisy mac address results
SAMPLE_SIZE=18

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

. /usr/local/bin/openbmc-utils.sh

if ! wedge_is_us_on; then
    echo "Cannot retrive microserver MAC when microserver is powered off." 1>&2
    exit -2
fi

# Workaround wedge100 noisy mac address hw bug (in which some mac octets sometimes
# are 'ff') by querying for the mac address several times and getting the min()
# of each octet
sample="$(for i in $(seq 1 ${SAMPLE_SIZE}); do
  cat "${COME_SYSFS_DIR}/mac"
done)"

mac=""
for i in {1..6}; do
  min_octet=$(echo "$sample" | cut -f$i -d':' | sort | head -n1)
  mac+=":$min_octet"
done
mac="${mac:1}" # strip leading ':'

if [ -n "$mac" -a "${mac/X/}" = "${mac}" ]; then
    echo $mac
    exit 0
else
    echo "Cannot find out the microserver MAC" 1>&2
    exit -1
fi


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          sensor-setup
# Required-Start:    power-on
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Power on micro-server
### END INIT INFO

. /usr/local/bin/openbmc-utils.sh

SENSORS_CONF_PATH="/etc/sensors.d"

if uname -r | grep "4\.1\.*" > /dev/null 2>&1; then
    LEGACY_KERNEL="true"
fi

#
# Configure ADC channels: the step is only needed in kernel 4.1 because
# ADC channels have been configured in device tree in kernel 5.x.
#
config_adc_channels() {
    echo "Configure ADC Channels.."

    modprobe ast_adc

    # channel 5: r1:  1.0K; r2:  1.0K; v2: 1000mv
    # channel 6: r1:  1.0K; r2:  1.0K; v2: 1000mv
    # channel 7: r1:  1.0K; r2:  1.0K; v2: 0mv
    # channel 8: r1:  1.0K; r2:  1.0K; v2: 0mv
    # channel 9: r1:  1.0K; r2:  1.0K; v2: 0mv
    ast_config_adc 5  1 1 1000
    ast_config_adc 6  1 1 1000
    ast_config_adc 7  1 1 0
    ast_config_adc 8  1 1 0
    ast_config_adc 9  1 1 0

    # Enable the ADC inputs;  adc5 - adc9 should be connected to
    # 1V, 1.03V, 5V, 3.3V, and 2.5V.
    echo 1 > /sys/devices/platform/ast_adc.0/adc5_en
    echo 1 > /sys/devices/platform/ast_adc.0/adc6_en
    echo 1 > /sys/devices/platform/ast_adc.0/adc7_en
    echo 1 > /sys/devices/platform/ast_adc.0/adc8_en
    echo 1 > /sys/devices/platform/ast_adc.0/adc9_en
}

#
# Some I2C devices may not get power until after power-on.sh, and it
# usually happens when the chassis is power cycled. Let's probe such devices
# again in this case.
#
fixup_i2c_devices() {
    mux_driver="pca954x"
    mux_device="7-0070"

    if [ ! -e "${SYSFS_I2C_DRIVERS}/${mux_driver}/${mux_device}" ]; then
        echo "Re-probe i2c switch $mux_device.."
        i2c_bind_driver "$mux_driver" "$mux_device"
    fi
}

get_ltc4151_version() {
    bus="$1"
    addr="$2"

    i2cset -f -y "$bus" "$addr" 0x00 2> /dev/null
    usleep 50000
    i2cset -f -y "$bus" "$addr" 0x4D 2> /dev/null
    usleep 50000
    if output=$(i2cget -f -y "$bus" "$addr" 2> /dev/null); then
        echo "$output"
    else
        echo "-1"
    fi
}

#
# Adjust LTC4151 Rsense value depending on hardware version.
# Kernel driver use Rsense equal to 1 milliohm. We need to correct Rsense
# value, and all the value are from hardware team.
#
pem_sensor_calibration() {
    echo "Calibrate PEM sensors..."

    # mux-channel-1 (14-0056) and mux-channel-2 (15-0055)
    fru1_version="$(get_ltc4151_version 14 0x56)"
    fru2_version="$(get_ltc4151_version 15 0x55)"

    if [ "$((fru1_version))" -ge "$((0x02))" ] || \
       [ "$((fru2_version))" -ge "$((0x02))" ]; then
        rsense_val=1.55
        rsense_val2=1.55
    else
        rsense_val=1.465
        rsense_val2=1.35
    fi

    sed "s/rsense/$rsense_val/1" "${SENSORS_CONF_PATH}/custom/ltc4151.conf" \
        > "/tmp/ltc4151.conf"

    sed "s/rsense/$rsense_val2/1" "/tmp/ltc4151.conf" \
         > "${SENSORS_CONF_PATH}/ltc4151.conf"

    # remove temporary file
    rm -rf /tmp/ltc4151.conf

}

#
# Main entry starts here
#
if [ -n "$LEGACY_KERNEL" ]; then
    config_adc_channels
fi

fixup_i2c_devices

pem_sensor_calibration


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

fcb_ver=$(head -n1 "$FCMCPLD_SYSFS_DIR/cpld_ver" 2> /dev/null)

usage() {
    echo "Usage: $0 [Fan Unit (1..4)]" >&2
}

# FCB    PWM 1 ~ 4 control Fantray 1 2 3 4
show_pwm()
{
    pwm="$FCMCPLD_SYSFS_DIR/fan$1_pwm"
    val=$(head -n 1 "$pwm")

    if [ "$fcb_ver" = "0x0" ]; then
        echo "$((val * 100 / 31))%"
    else
        # Convert the percentage to our 1/64th level (0-63) and round.
        echo "$(( (val * 1000 / 63 + 5) /10 ))%"
    fi
}

show_rpm()
{
    front_rpm="$FCMCPLD_SYSFS_DIR/fan$((($1 * 2 - 1)))_input"
    rear_rpm="$FCMCPLD_SYSFS_DIR/fan$((($1 * 2)))_input"
    echo "$(cat "$front_rpm"), $(cat "$rear_rpm")"
}

set -e

# refer to the comments in init_pwn.sh regarding
# the fan unit and tacho mapping
if [ "$#" -eq 0 ]; then
    FANS="1 2 3 4"
elif [ "$#" -eq 1 ]; then
    if [ "$1" -le 0 ] || [ "$1" -ge 9 ]; then
        echo "Fan $1: not a valid Fan Unit"
        exit 1
    fi
    FANS="$1"
else
    usage
    exit 1
fi

for fan in $FANS; do
    FAN="${fan}"
    UNIT=${FAN}

    echo "Fan $fan RPMs: $(show_rpm "$UNIT"), ($(show_pwm "$UNIT"))"
done


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-fan
# Required-Start:    board-id
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set fan speed
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# if fcm version or higher, enable fscd
FSCD_ENABLE_FCM_MAJ=3
FSCD_ENABLE_FCM_MIN=5

default_fsc_config="/etc/fsc-config.json"
fcm_maj=$((FCM_CPLD_VER))
fcm_min=$((FCM_CPLD_SUB_VER))

echo -n "Setup fan speed... "

if [ $(wedge_board_type) -eq 0 ]; then
    echo "Run FSC Wedge400 Config"
    cp /etc/FSC-W400-config.json ${default_fsc_config}
elif [ $(wedge_board_type) -eq 1 ]; then
    echo "Run FSC Wedge400C Config"
    cp /etc/FSC-W400C-config.json ${default_fsc_config}
fi
echo "Setting fan speed to 50%..."
/usr/local/bin/set_fan_speed.sh 50
echo "Done setting fan speed"

if fw_printenv | grep "disable_fscd=yes" > /dev/null 2>&1; then
    echo "fscd is disabled in uboot_env: fans are running at fixed speed."
    exit 0
fi

# Currently, fcmcpld version 0.xx will cause BMC to
# run into crash loop, due to fscd's own logic and
# its failure to disarm bootup watchdog.
# (this problem is only for fcmcpld 0.xx. Fcmcpld 3.5 and
# above works well without any problem.)
# Until we have fix, we will run fscd only if fcmcpld is 3.5 or higher.
fcm_compatible=0
if [ $((fcm_maj)) -eq $FSCD_ENABLE_FCM_MAJ ] &&
   [ $((fcm_min)) -ge $FSCD_ENABLE_FCM_MIN ] ||
   [ $((fcm_maj)) -ge $((FSCD_ENABLE_FCM_MAJ + 1)) ]; then
   fcm_compatible=1
fi

#WEDGE400 EVT   wedge_board_rev = 0  smb_board_rev = 00 disable
#WEDGE400 EVT3  wedge_board_rev = 0  smb_board_rev = 01 enable
if [ "$(wedge_board_type)" = "0" ] &&
   [ "$(wedge_board_rev)" = "0" ] &&
   [ "$SMB_CPLD_BOARD_REV" = "0x0" ]; then #WEDGE400 EVT
    fcm_compatible=0
#WEDGE400-C EVT wedge_board_rev = 0  disable
elif [ "$(wedge_board_type)" = "1" ] &&
     [ "$(wedge_board_rev)" = "0" ]; then #WEDGE400C EVT
    fcm_compatible=0 #fcm_compatible = 0 means fscd not ready.
fi

if [ $fcm_compatible -eq 0 ]; then
    echo "Running fan at the fixed speed."
    /usr/local/bin/wdtcli stop
else
    echo "Starting fscd..."
    runsv /etc/sv/fscd > /dev/null 2>&1 &
fi
echo "done."


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

fcb_ver=$(head -n1 "$FCMCPLD_SYSFS_DIR/cpld_ver" 2> /dev/null)

usage() {
    echo "Usage: $0 <PERCENT (0..100)> <Fan Unit (1..4)> " >&2
}

set -e

if [ "$#" -ne 2 ] && [ "$#" -ne 1 ]; then
    usage
    exit 1
fi

# check percent argument be number
check_number=$(echo "$1" | grep -E "^[0-9]+$")
if [ "$check_number" = '' ]; then
    echo "Percent argument can be only integer number"
    usage
    exit 1
fi
# check percent in range 0-100
if [ "$1" -lt 0 ] || [ "$1" -gt 100 ]; then
    echo "Percent argument out of range"
    usage
    exit 1
fi

# FCB    PWM 1 ~ 4 control Fantray 1 2 3 4
if [ "$#" -eq 1 ]; then
    FAN_UNIT="1 2 3 4"
else
    if [ "$2" -le 0 ] || [ "$2" -gt 4 ]; then
        echo "Fan $2: not a valid Fan Unit"
        exit 1
    fi

    FAN="$2"
    FAN_UNIT=$((FAN / 1))
fi

if [ "$fcb_ver" = "0x0" ]; then
    # Convert the percentage to our 1/32th level (0-31).
    step=$((($1 * 31) / 100))
else
    # Convert the percentage to our 1/64th level (0-63) and round.
    step=$(( ($1 * 630 + 5) / 1000 ))
fi
cnt=1

for unit in ${FAN_UNIT}; do
    pwm="$FCMCPLD_SYSFS_DIR/fan${unit}_pwm"
    echo "$step" > "${pwm}"
    if [ "$#" -eq 1 ]; then
        echo "Successfully set fan $cnt speed to $1%"
        cnt=$((cnt + 1))
    else
        echo "Successfully set fan $2 speed to $1%"
    fi
done


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

#shellcheck disable=SC1091,SC2034
# Do not change this line to openbmc-utils.sh, or it will generate a source loop.
. /usr/local/bin/i2c-utils.sh

SCMCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 2-003e)
SMBCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 12-003e)
if [[ ${KERNEL_VERSION} != 4.1.* ]]; then
    PWRCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 31-003e)
    FCMCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 32-003e)
else
    PWRCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 33-003e)
    FCMCPLD_SYSFS_DIR=$(i2c_device_sysfs_abspath 34-003e)
fi
PWR_USRV_SYSFS="${SCMCPLD_SYSFS_DIR}/com_exp_pwr_enable"
PWR_USRV_FORCE_OFF="${SCMCPLD_SYSFS_DIR}/com_exp_pwr_force_off"
PWR_TH_RST_SYSFS="${SMBCPLD_SYSFS_DIR}/mac_reset_n"

# CPLD version
SMB_CPLD_VER=$(head -n 1 "$SMBCPLD_SYSFS_DIR/cpld_ver" 2> /dev/null)
SMB_CPLD_SUB_VER=$(head -n 1 "$SMBCPLD_SYSFS_DIR/cpld_sub_ver" 2> /dev/null)
PWR_CPLD_VER=$(head -n 1 "$PWRCPLD_SYSFS_DIR/cpld_ver" 2> /dev/null)
PWR_CPLD_SUB_VER=$(head -n 1 "$PWRCPLD_SYSFS_DIR/cpld_sub_ver" 2> /dev/null)
SCM_CPLD_VER=$(head -n 1 "$SCMCPLD_SYSFS_DIR/cpld_ver" 2> /dev/null)
SCM_CPLD_SUB_VER=$(head -n 1 "$SCMCPLD_SYSFS_DIR/cpld_sub_ver" 2> /dev/null)
FCM_CPLD_VER=$(head -n 1 "$FCMCPLD_SYSFS_DIR/cpld_ver" 2> /dev/null)
FCM_CPLD_SUB_VER=$(head -n 1 "$FCMCPLD_SYSFS_DIR/cpld_sub_ver" 2> /dev/null)

# SMB Board Rev
SMB_CPLD_BOARD_REV=$(head -n 1 "$SMBCPLD_SYSFS_DIR/board_ver" 2> /dev/null)

# 48V DC PSU P/N
DELTA_48V="0x45 0x43 0x44 0x32 0x35 0x30 0x31 0x30 0x30 0x31 0x35"
LITEON_48V="0x44 0x44 0x2d 0x32 0x31 0x35 0x32 0x2d 0x32 0x4c"

wedge_is_us_on() {
    local val0 val1

    val0=$(head -n 1 < "$PWR_USRV_SYSFS" 2> /dev/null)
    val1=$(head -n 1 < "$PWR_USRV_FORCE_OFF" 2> /dev/null)

    if [ "$val0" == "0x1" ] && [ "$val1" == "0x1" ] ; then
        return 0            # powered on
    else
        return 1
    fi

    return 0
}

wedge_board_type_rev(){
    full_board_type=$(wedge_full_board_type)
    board_type=$(wedge_board_type)
    rev=$(wedge_board_rev)
    if [ $((board_type)) -eq 0 ]; then
        if [ $(( full_board_type&2 )) -ne 0 ]; then
            case $rev in
                6)
                    echo "WEDGE400_MP_RESPIN"
                    ;;
                *)
                    echo "WEDGE400 (Undefine $rev)"
                    ;;
            esac
        else
            case $rev in
                0)
                    echo "WEDGE400_EVT/EVT3"
                    ;;
                2)
                    echo "WEDGE400_DVT"
                    ;;
                3)
                    echo "WEDGE400_DVT2/PVT1/PV2"
                    ;;
                4)
                    echo "WEDGE400_PVT3"
                    ;;
                5)
                    echo "WEDGE400_MP"
                    ;;
                *)
                    echo "WEDGE400 (Undefine $rev)"
                    ;;
            esac
        fi
    elif [ $((board_type)) -eq 1 ]; then
        if [ $(( full_board_type&2 )) -ne 0 ]; then
            case $rev in
                4)
                    echo "WEDGE400-C_MP_RESPIN"
                    ;;
                *)
                    echo "WEDGE400-C (Undefine $rev)"
                    ;;
            esac
        else
            case $rev in
                0)
                    echo "WEDGE400-C_EVT"
                    ;;
                1)
                    echo "WEDGE400-C_EVT2"
                    ;;
                2)
                    echo "WEDGE400-C_DVT"
                    ;;
                3)
                    echo "WEDGE400-C_DVT2"
                    ;;
                *)
                    echo "WEDGE400-C_(Undefine $rev)"
                    ;;
            esac
        fi
    else
        echo "Undefine_($board_type,$rev)"
    fi
}

wedge_board_type() {
    rev=$(gpio_get BMC_CPLD_BOARD_TYPE_0)
    if [ $((rev)) -eq 0 ]; then
        echo 1  # Wedge400-C
    else
        echo 0  # Wedge400
    fi
}

wedge_full_board_type() {
    # Wedge400 MP respin or later is added more 2 pins to indicate new board type
    local val0 val1 val2
    val0=$(gpio_get BMC_CPLD_BOARD_TYPE_0)
    val1=$(gpio_get BMC_CPLD_BOARD_TYPE_1)
    val2=$(gpio_get BMC_CPLD_BOARD_TYPE_2)
    echo $((val0 | (val1 << 1) | (val2 << 2)))
}

wedge_slot_id() {
    printf "1\n"
}

wedge_board_rev() {
    local val0 val1 val2
    val0=$(gpio_get BMC_CPLD_BOARD_REV_ID0)
    val1=$(gpio_get BMC_CPLD_BOARD_REV_ID1)
    val2=$(gpio_get BMC_CPLD_BOARD_REV_ID2)
    echo $((val0 | (val1 << 1) | (val2 << 2)))
}

board_type_is_wedge400() {
    brd_type=$(wedge_board_type)
    if [ "$brd_type" -eq "0" ]; then
        return 0
    fi

    return 1
}

board_type_is_wedge400c() {
    brd_type=$(wedge_board_type)
    if [ "$brd_type" -eq "1" ]; then
        return 0
    fi

    return 1
}

wedge400_rev_is_mp() {
    if ! board_type_is_wedge400; then
        return 1
    fi

    brd_rev=$(wedge_board_rev)
    if [ "$brd_rev" -ge "6" ]; then
        return 1
    fi

    return 0
}

wedge400_rev_is_respin() {
    if ! board_type_is_wedge400; then
        return 1
    fi

    brd_rev=$(wedge_board_rev)
    if [ "$brd_rev" -lt "6" ]; then
        return 1
    fi

    return 0
}

wedge400c_rev_is_mp() {
    if ! board_type_is_wedge400c; then
        return 1
    fi

    brd_rev=$(wedge_board_rev)
    if [ "$brd_rev" -ge "4" ]; then
        return 1
    fi

    return 0
}

wedge400c_rev_is_respin() {
    if ! board_type_is_wedge400c; then
        return 1
    fi

    brd_rev=$(wedge_board_rev)
    if [ "$brd_rev" -lt "4" ]; then
        return 1
    fi

    return 0
}

board_rev_is_respin() {
    if wedge400_rev_is_respin || wedge400c_rev_is_respin; then
        return 0
    fi

    return 1
}

wedge_power_on_board() {
    # wedge400 SCM power is controlled by SCMCPLD
    return 0
}

wedge_prepare_cpld_update() {
    echo "Stop fscd service."
    sv stop fscd

    # from stress test found sometime sv stop fscd has timeout
    # and wdtcli can't stop watchdog, that do BMC reboot while CPLD updating.
    # Add fuser to check /dev/watchdog ready to used after fscd release it.
    watchdog_ok=0
    MAX_RETRY=5
    for ((retry=1; retry <= MAX_RETRY; retry++))
    do
        /usr/bin/fuser /dev/watchdog &> /dev/null
        # return code is 1 when no one hold /dev/watchdog
        if [ $? -eq 1 ]; then
            echo "/dev/watchdog available"
            watchdog_ok=1
            break
        fi
        echo "waiting for /dev/watchdog, retry $retry/$MAX_RETRY"
        sleep 2
    done;
    if [ $watchdog_ok -ne 1 ]; then
        echo "Watchdog could not be stopped. Retry later"
        return 1;
    fi

    echo "Disable watchdog."
    /usr/local/bin/wdtcli stop

    echo "Set fan speed 40%."
    set_fan_speed.sh 40

    return 0
}

wedge_power_supply_type() {
    # Only PEM has max6615 which I2C slave address is 0x18
    is_pem1=$(i2cget -f -y 24 0x18 0x0 &> /dev/null; echo $?)
    is_pem2=$(i2cget -f -y 25 0x18 0x0 &> /dev/null; echo $?)
    if i2cget -y -f 24 0x58 0x9a s &> /dev/null;then    # PSU1
        is_psu1_48v=$(i2cget -y -f 24 0x58 0x9a s)
    elif i2cget -y -f 25 0x58 0x9a s &> /dev/null;then  # PSU2
        is_psu2_48v=$(i2cget -y -f 25 0x58 0x9a s)
    fi
    power_type=""
    if [ $# -eq 1 ]; then
        if [ "$1" = "1" ]; then
            if [ "$is_pem1" -eq 0 ]; then
                power_type="PEM"
            else
                power_type="PSU"
            fi
        elif [ "$1" = "2" ]; then
            if [ "$is_pem2" -eq 0 ]; then
                power_type="PEM"
            else
                power_type="PSU"
            fi
        else
            echo "wedge_power_supply_type < 1 | 2 >"
            return
        fi
    else
        if [ "$is_pem1" -eq 0 ] || [ "$is_pem2" -eq 0 ]; then
            power_type="PEM"
        else
            power_type="PSU"
        fi
    fi

    # Detect 48V DC PSU
    if [[ "$is_psu1_48v" = "$DELTA_48V" ||
        "$is_psu1_48v" = "$LITEON_48V" ||
        "$is_psu2_48v" = "$DELTA_48V" ||
        "$is_psu2_48v" = "$LITEON_48V" ]];then
            power_type="PSU48"
    fi
    echo $power_type
}


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/bin/openbmc-utils.sh

echo "SMB_SYSCPLD: $((SMB_CPLD_VER)).$((SMB_CPLD_SUB_VER))"
echo "SMB_PWRCPLD: $((PWR_CPLD_VER)).$((PWR_CPLD_SUB_VER))"
echo "SCMCPLD: $((SCM_CPLD_VER)).$((SCM_CPLD_SUB_VER))"
echo "FCMCPLD: $((FCM_CPLD_VER)).$((FCM_CPLD_SUB_VER))"


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

prog="$0"
img="$1"

DLL_PATH=/usr/lib/libcpldupdate_dll_ast_jtag.so

usage() {
    echo "Usage: $prog <img_file> <options: hw|sw>"
    echo
    echo "img_file: Image file for lattice CPLD"
    echo "  VME file for software mode"
    echo "  JED file for hardware mode"
    echo "options:"
    echo "  hw: Program the CPLD using JTAG hardware mode"
    echo "  sw: Program the CPLD using JTAG software mode"
    echo
    echo
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

enable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN        1
    gpio_set PWR_CPLD_JTAG_EN_N     1
    gpio_set SYS_CPLD_JTAG_EN_N     1
    gpio_set SCM_CPLD_JTAG_EN_N     1
    gpio_set FCM_CPLD_JTAG_EN_N     0
    gpio_set PWR_CPLD_HITLESS       0
    gpio_set FCM_CPLD_HITLESS       1
    gpio_set SCM_CPLD_HITLESS       0
    gpio_set SMB_CPLD_HITLESS       0
    gpio_set BMC_FCM_SEL            0
    gpio_set BMC_SCM_CPLD_EN        1
}

disable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN        0
    gpio_set PWR_CPLD_JTAG_EN_N     1
    gpio_set SYS_CPLD_JTAG_EN_N     1
    gpio_set SCM_CPLD_JTAG_EN_N     1
    gpio_set FCM_CPLD_JTAG_EN_N     1
    gpio_set PWR_CPLD_HITLESS       0
    gpio_set FCM_CPLD_HITLESS       0
    gpio_set SCM_CPLD_HITLESS       0
    gpio_set SMB_CPLD_HITLESS       0
    gpio_set BMC_FCM_SEL            1
    gpio_set BMC_SCM_CPLD_EN        1
}

trap 'rm -rf /tmp/fcmcpld_update' INT TERM QUIT EXIT

echo 1 > /tmp/fcmcpld_update

if ! wedge_prepare_cpld_update; then
    echo "Aborting CPLD upgrade"
    echo "The FSCD may be closed incompletely,"
    echo "Please check the watchdog timeout, to prevent system reboot."
    exit 1
fi

enable_jtag_chain

case $2 in
    hw)
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -f 12000000
        ;;
    sw)
        ispvm -f 1000 dll $DLL_PATH "${img}"
        ;;
    *)
        # default: hw mode
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -f 12000000
        ;;
esac

result=$?

if [ "$2" = "sw" ]; then
    expect=1
else
    expect=0
fi

disable_jtag_chain

# 0 is returned upon upgrade success
if [ $result -eq $expect ]; then
    echo "Upgrade successful."
    echo "Re-start fscd service."
    sv start fscd
    exit 0
else
    echo "Upgrade failure. Return code from utility : $result"
    echo "To prevent system reboot. Keep fscd stop & watchdog disable."
    exit 1
fi


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

dump_fpga_version() {
    local fpga_dir=$1
    local fpga_name=$2

    fpga_ver=`head -n 1 ${fpga_dir}/fpga_ver 2> /dev/null`
    if [ $? -ne 0 ]; then
        echo "${fpga_name} is not detected"
        return
    fi
    fpga_sub_ver=`head -n 1 ${fpga_dir}/fpga_sub_ver 2> /dev/null`
    if [ $? -ne 0 ]; then
        echo "${fpga_name} is not detected"
        return
    fi

    echo "${fpga_name}: $(($fpga_ver)).$(($fpga_sub_ver))"
}

echo -n "DOMFPGA1: "
bus=13
addr=0x60
dom_fpga1_ver=$(i2cget -f -y $bus $addr 0x01 2>/dev/null)
dom_fpga1_ver_sub=$(i2cget -f -y $bus $addr 0x02 2>/dev/null)
if [ ! -z $dom_fpga1_ver ]; then
    echo "$(($dom_fpga1_ver)).$(($dom_fpga1_ver_sub))"
else
    echo "Not found"
fi

echo -n "DOMFPGA2: "
bus=5
addr=0x60
dom_fpga2_ver=$(i2cget -f -y $bus $addr 0x01 2>/dev/null)
dom_fpga2_ver_sub=$(i2cget -f -y $bus $addr 0x02 2>/dev/null)
if [ ! -z $dom_fpga2_ver ]; then
    echo "$(($dom_fpga2_ver)).$(($dom_fpga2_ver_sub))"
else
    echo "Not found"
fi


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

### BEGIN INIT INFO
# Provides:          power-on
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Power on micro-server
### END INIT INFO
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

wedge_power_on_board

echo -n "Checking microserver power status ... "
if wedge_is_us_on 10 "."; then
    echo "on"
    on=1
else
    echo "off"
    on=0
fi

if [ $on -eq 0 ]; then
    # Power on now
    wedge_power.sh on -f
fi


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

SMB_DIR=$SMBCPLD_SYSFS_DIR
SCM_CMD=$SMB_DIR"/scm_present_int_status"
FAN_CMD=$FCMCPLD_SYSFS_DIR
DEBUG_CARD_PRSNT_GPIO="/tmp/gpionames/DEBUG_PRESENT_N/value"

function usage
{
  program=$(basename "$0")
  echo "Usage:"
  echo "     $program "
  echo "     $program <TYPE>"
  echo "     <TYPE>: scm/fan/psu/pem/debug_card"
}

# Will return <key> : <val>
# eg - scm : 1
function get_presence
{
  local file=$1 key=$2
  val=$(head -n1 "$file" | awk '{print substr($0,0,3) }' | sed "s/.x//")
  if [ "$val" = "0" ]; then
      val=1
  else
      val=0
  fi
  echo "$key : $val"
}

# SCM
function get_scm_presence
{
  key="scm"
  get_presence "$SCM_CMD" "$key"
}

# FANs
function get_fan_presence
{
  local num=1
  while [ $num -le 4 ]; do
      key="fan${num}"
      file="$FAN_CMD/fan${num}_present"
      get_presence "$file" "$key"
      (( num++ ))
  done
}

# Power supplies
function get_psu_presence
{
  for i in {1..2}; do
    key="psu${i}"
    file="$SMB_DIR/psu_present_${i}_N_int_status"
    val=$(head -n1 "$file" | awk '{print substr($0,0,3) }' | sed "s/.x//")
    if [ "$val" = "0" ]; then
      type=$(wedge_power_supply_type "$i")
      if [[ "$type" = "PSU" || "$type" = "PSU48" ]]; then
        echo "$key : 1"
        continue
      fi
    fi
    echo "$key : 0"
  done
}

# Pem
function get_pem_presence
{
  for i in {1..2}; do
    key="pem${i}"
    file="$SMB_DIR/psu_present_${i}_N_int_status"
    val=$(head -n1 "$file" | awk '{print substr($0,0,3) }' | sed "s/.x//")
    if [ "$val" = "0" ]; then
      type=$(wedge_power_supply_type "$i")
      if [ "$type" = "PEM" ]; then
        echo "$key : 1"
        continue
      fi
    fi
    echo "$key : 0"
  done
}

# Debug card
function get_debug_card_presence
{
  key="debug_card"
  val=$(head -n1 $DEBUG_CARD_PRSNT_GPIO | awk '{print substr($0,0,3) }' | sed "s/.x//")
  if [ "$val" = "0" ]; then
      val=0
  else
      val=1
  fi
  echo $key ":" $val
}

# get all info
if [[ $1 = "" ]]; then
  echo "CARDS"
  get_scm_presence

  echo "FANS"
  get_fan_presence

  echo "POWER SUPPLIES"
  get_psu_presence
  get_pem_presence

  echo "DEBUG CARD"
  get_debug_card_presence

  exit 0
else
  if [[ $1 = "scm" ]]; then
    get_scm_presence
  elif [[ $1 = "fan" ]]; then
    get_fan_presence
  elif [[ $1 = "psu" ]]; then
    get_psu_presence
  elif [[ $1 = "pem" ]]; then
    get_pem_presence
  elif [[ $1 = "debug_card" ]]; then
    get_debug_card_presence
  else
    usage
  fi
  exit 0
fi


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

prog="$0"
img="$1"

DLL_PATH=/usr/lib/libcpldupdate_dll_ast_jtag.so

usage() {
    echo "Usage: $prog <img_file> <options: hw|sw>"
    echo
    echo "img_file: Image file for lattice CPLD"
    echo "  VME file for software mode"
    echo "  JED file for hardware mode"
    echo "options:"
    echo "  hw: Program the CPLD using JTAG hardware mode"
    echo "  sw: Program the CPLD using JTAG software mode"
    echo
    echo
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

enable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN        1
    gpio_set PWR_CPLD_JTAG_EN_N     0
    gpio_set SYS_CPLD_JTAG_EN_N     1
    gpio_set SCM_CPLD_JTAG_EN_N     1
    gpio_set FCM_CPLD_JTAG_EN_N     1
    gpio_set PWR_CPLD_HITLESS       1
    gpio_set FCM_CPLD_HITLESS       0
    gpio_set SCM_CPLD_HITLESS       0
    gpio_set SMB_CPLD_HITLESS       0
    gpio_set BMC_FCM_SEL            1
    gpio_set BMC_SCM_CPLD_EN        1
}

disable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN        0
    gpio_set PWR_CPLD_JTAG_EN_N     1
    gpio_set SYS_CPLD_JTAG_EN_N     1
    gpio_set SCM_CPLD_JTAG_EN_N     1
    gpio_set FCM_CPLD_JTAG_EN_N     1
    gpio_set PWR_CPLD_HITLESS       0
    gpio_set FCM_CPLD_HITLESS       0
    gpio_set SCM_CPLD_HITLESS       0
    gpio_set SMB_CPLD_HITLESS       0
    gpio_set BMC_FCM_SEL            1
    gpio_set BMC_SCM_CPLD_EN        1
}

trap 'rm -rf /tmp/pwrcpld_update' INT TERM QUIT EXIT

echo 1 > /tmp/pwrcpld_update

if ! wedge_prepare_cpld_update; then
    echo "Aborting CPLD upgrade"
    echo "The FSCD may be closed incompletely,"
    echo "Please check the watchdog timeout, to prevent system reboot."
    exit 1
fi

enable_jtag_chain

case $2 in
    hw)
        # enable CPLD immediately after cpld update done
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -R -f 12000000
        ;;
    sw)
        ispvm -f 1000 dll $DLL_PATH "${img}"
        ;;
    *)
        # default: hw mode
        # enable CPLD immediately after cpld update done
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -R -f 12000000
        ;;
esac

result=$?

if [ "$2" = "sw" ]; then
    expect=1
else
    expect=0
fi

disable_jtag_chain

# 0 is returned upon upgrade success
if [ $result -eq $expect ]; then
    echo "Upgrade successful."
    echo "Re-start fscd service."
    sv start fscd
    exit 0
else
    echo "Upgrade failure. Return code from utility : $result"
    echo "To prevent system reboot. Keep fscd stop & watchdog disable."
    exit 1
fi


#!/bin/bash
#
# Copyright 2021-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#

# This script is a workaround for the I2C PMBUS vout sensor reading issue given
# the root cause has not been found. When the issue happened, we measured the voltage
# and it was normal, also reload the pmbus device driver will fix the issue.

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

printf "Check special sensors and rebind driver..."

retry=0
while [ $retry -lt 5 ]; do
    sensor_ok=$(/usr/local/bin/sensor-util smb 0x55 --force | grep ok &> /dev/null; echo $?)
    if [ $((sensor_ok)) -eq 0 ]; then
        echo "Done"
        exit 0
    fi
    retry=$((retry + 1))
    echo "trying rebind driver pxe1211 for i2c device 1-0e, time $retry"
    i2c_device_delete 1 0x0e
    i2c_device_add 1 0x0e pxe1211
done


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/bin/openbmc-utils.sh

# There are two reset pins to ASIC. System reset and PCI reset.
#
# When PWR_TH_RST_SYSFS is set to 0, CPLD will drive both reset pins to trigger
# reset.
#
# When PWR_TH_RST_SYSFS is set to 1, CPLD will drive system reset, followed by
# PCI reset following the reset sequeence.
#
# There is another sysfs file, 'cpld_mac_pcie_perst_l', which can be used
# to control the PCI reset pin separately. However, we don't use it for now
# as we depend on the CPLD for the correct reset sequence.

echo 0 > $PWR_TH_RST_SYSFS
sleep 1
echo 1 > $PWR_TH_RST_SYSFS

logger "Reset Tomahawk"


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

prog="$0"
img="$1"

DLL_PATH=/usr/lib/libcpldupdate_dll_ast_jtag.so

usage() {
    echo "Usage: $prog <img_file> <options: hw|sw>"
    echo
    echo "img_file: Image file for lattice CPLD"
    echo "  VME file for software mode"
    echo "  JED file for hardware mode"
    echo "options:"
    echo "  hw: Program the CPLD using JTAG hardware mode"
    echo "  sw: Program the CPLD using JTAG software mode"
    echo
    echo
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

enable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN  1
    gpio_set PWR_CPLD_JTAG_EN_N  1
    gpio_set SYS_CPLD_JTAG_EN_N  1
    gpio_set SCM_CPLD_JTAG_EN_N  0
    gpio_set FCM_CPLD_JTAG_EN_N  1
    gpio_set PWR_CPLD_HITLESS  0
    gpio_set FCM_CPLD_HITLESS  0
    gpio_set SCM_CPLD_HITLESS  1
    gpio_set SMB_CPLD_HITLESS  0
    gpio_set BMC_FCM_SEL  1
    gpio_set BMC_SCM_CPLD_EN 0
}

disable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN  0
    gpio_set PWR_CPLD_JTAG_EN_N  1
    gpio_set SYS_CPLD_JTAG_EN_N  1
    gpio_set SCM_CPLD_JTAG_EN_N  1
    gpio_set FCM_CPLD_JTAG_EN_N  1
    gpio_set PWR_CPLD_HITLESS  0
    gpio_set FCM_CPLD_HITLESS  0
    gpio_set SCM_CPLD_HITLESS  0
    gpio_set SMB_CPLD_HITLESS  0
    gpio_set BMC_FCM_SEL  1
    gpio_set BMC_SCM_CPLD_EN 1
}

trap 'rm -rf /tmp/scmcpld_update' INT TERM QUIT EXIT

echo 1 > /tmp/scmcpld_update

if ! wedge_prepare_cpld_update; then
    echo "Aborting CPLD upgrade"
    echo "The FSCD may be closed incompletely,"
    echo "Please check the watchdog timeout, to prevent system reboot."
    exit 1
fi

enable_jtag_chain

case $2 in
    hw)
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -f 12000000
        ;;
    sw)
        ispvm -f 1000 dll $DLL_PATH "${img}"
        ;;
    *)
        # default: hw mode
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -f 12000000
        ;;
esac

result=$?

if [ "$2" = "sw" ]; then
    expect=1
else
    expect=0
fi

disable_jtag_chain

# 0 is returned upon upgrade success
if [ $result -eq $expect ]; then
    echo "Upgrade successful."
    echo "Re-start fscd service."
    sv start fscd
    exit 0
else
    echo "Upgrade failure. Return code from utility : $result"
    echo "To prevent system reboot. Keep fscd service stop & watchdog disable."
    exit 1
fi


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

#shellcheck disable=SC1091
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
. /usr/local/bin/openbmc-utils.sh

# Skip AVS setup on Wedge400C unit
if [ "$(wedge_board_type)" != "0" ]; then
    exit 0
fi

VID_START=1.6 # Unit Voltage
VID_STEP=0.00625 # Unit Voltage
ISL_VOUT_PMBUS_COMMAND=0x21

VALID_MAX=0x8A
VALID_MIN=0x72

MAX_RETRY=5
power_count=0
avs_count=0
while true; do
    th3_power_on=$(head -n 1 "$SMBCPLD_SYSFS_DIR/th3_turn_on" 2> /dev/null)
    th3_power_good=$(head -n 1 "$SMBCPLD_SYSFS_DIR/vddcore_th3_power_good" 2> /dev/null)
    if [ "$((th3_power_good))" != "1" ] || [ "$((th3_power_on))" != "1" ]; then
        sleep 1
        power_count=$((power_count + 1))
        if [ $power_count -ge $MAX_RETRY ]; then
            if [ $power_count -eq $MAX_RETRY ]; then
                echo "$0 timeout, set AVS directly"
            fi
        else
            continue
        fi
    fi

    sleep 0.5

    TH3_ROV=$(i2cget -f -y 12 0x3e 0x46) # Get TH3 AVS value from SYSCPLD
    if [ $((TH3_ROV)) -lt $((VALID_MIN)) ] || [ $((TH3_ROV)) -gt $((VALID_MAX)) ]; then
        avs_count=$((avs_count + 1))
        if [ $avs_count -ge $MAX_RETRY ]; then
            echo "Invalid AVS value: $TH3_ROV out of range: ($VALID_MIN - $VALID_MAX)"
            echo "Will not set AVS voltage, use ISL68317 default output voltage"
            exit 1
        else
            continue
        fi
    fi

    TH3_ROV_DEC=$(printf "%d" "$TH3_ROV")

    VRM_VCC_MAX=$(echo $VID_START "$TH3_ROV_DEC" $VID_STEP | awk '{printf "%.5f", $1-(($2-2)*$3)}')

    ISL_VOUT_mV=$(echo "$VRM_VCC_MAX" | awk '{printf "%d", $1*1000}') # Convert to mV

    ISL_VOUT_PMBUS_VALUE=$(printf "0x%04x" "$ISL_VOUT_mV") # Convert to HEX

    # Set VOUT to ISL68317
    # AVS connect to isl68137 channel 2
    i2cset -f -y 1 0x60 0x0 0x1
    if [ "$(i2cset -f -y 1 0x60 $ISL_VOUT_PMBUS_COMMAND $((ISL_VOUT_PMBUS_VALUE)) w)" ]; then
        echo "Cannot communicate with ISL68317."
        continue
    fi

    ISL_VOUT_READBACK=$(i2cget -f -y 1 0x60 0x21 w | awk '{printf "%d", $1}') # Readback ISL68317 VOUT

    if [ $((ISL_VOUT_READBACK)) -ne $((ISL_VOUT_mV)) ]; then
        echo "Failed to write the value to ISL68317."
        continue
    fi
    echo "Set AVS voltage to $ISL_VOUT_mV mV, read back is $ISL_VOUT_READBACK mV"
    exit 0
done


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

cmd_bic_ver="bic-util scm 0xe2 0x0b 0x15 0xa0 0x00 0x02"
COUNTER=0
MAX_RETRY=10
rex='^[0-9]+$'

echo "Initializing Bridge-IC I2C Frequency..."
while [ $COUNTER -lt $MAX_RETRY ]; do
    readarray -td ' ' bic_data <<<"$($cmd_bic_ver)"
    if [[ ${bic_data[4]} =~ $rex ]] ; then
        break
    fi
    sleep 3
    ((COUNTER+=1))
done

if [ $COUNTER -eq $MAX_RETRY ];then
    echo "Error: Cannot access Bridge-IC." >&2; exit 1
fi

bic_major=$(( 10#${bic_data[3]} ))
bic_minor=$(( 10#${bic_data[4]} ))
bic_ver="$bic_major.${bic_data[4]}"

echo Bridge-IC version is v"$bic_ver".

if [ "$bic_major" -ge 1 ];then
    if [ "$bic_minor" -ge 11 ];then
        ret=$(bic-util scm 0xe0 0x2a 0x15 0xa0 0x00 0x01)
        IANA="15 A0 00"
        if [ -z "${ret##*$IANA*}" ];then
                echo Bridge-IC is initialized SCL to 1Mhz.
        else
                echo "Error: Cannot access Bridge-IC." >&2; exit 1
        fi
    fi
fi

exit 0


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

### BEGIN INIT INFO
# Provides:          setup_board.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup the board
### END INIT INFO

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# Make the backup BIOS flash connect to COMe instead of BMC
#echo 0 > ${SCMCPLD_SYSFS_DIR}/com_spi_oe_n
#echo 0 > ${SCMCPLD_SYSFS_DIR}/com_spi_sel

# Setup management port LED
/usr/local/bin/setup_mgmt.sh led &

# Setup USB Serial to RS485
echo 0 > "${SMBCPLD_SYSFS_DIR}/cpld_usb_mux_sel_0"
echo 0 > "${SMBCPLD_SYSFS_DIR}/cpld_usb_mux_sel_1"

# Init server_por_cfg
#if [ ! -f "/mnt/data/kv_store/server_por_cfg" ]; then
#    /usr/bin/kv set server_por_cfg on persistent
#fi

# Force COMe's UART connect to BMC UART-5 and FB USB debug
# UART connect to BMC UART-2
echo 0x3 > "$SMBCPLD_SYSFS_DIR/uart_selection"

# Read board type from Board type GPIO pin and save to cache
brd_type=$(wedge_board_type)
brd_rev=$(wedge_board_rev)

#Read PSU type from eeprom and save to cache
pwr_type=$(wedge_power_supply_type)

/usr/bin/kv set "board_type" "$brd_type"
/usr/bin/kv set "power_type" "$pwr_type"

# Check board type to select lmsensor configuration
if [ $((brd_type)) -eq 0 ]; then
  cp /etc/sensors.d/custom/wedge400.conf /etc/sensors.d/wedge400.conf
  # Check board revision
  if [ $((brd_rev)) -ge 6 ]; then # for respin or newer
    cp /etc/sensors.d/custom/wedge400-respin.conf /etc/sensors.d/wedge400-respin.conf
  else
    cp /etc/sensors.d/custom/wedge400-evt-mp.conf /etc/sensors.d/wedge400-evt-mp.conf
  fi;
elif  [ $((brd_type)) -eq 1 ]; then
  cp /etc/sensors.d/custom/wedge400c.conf /etc/sensors.d/wedge400c.conf
  # Check board revision
  if [ $((brd_rev)) -ge 4 ]; then # for respin or newer
    cp /etc/sensors.d/custom/wedge400c-respin.conf /etc/sensors.d/wedge400c-respin.conf
  else
    cp /etc/sensors.d/custom/wedge400c-evt-dvt2.conf /etc/sensors.d/wedge400c-evt-dvt2.conf
  fi;
fi

# For the time being, we set GB VDD Core to 825mv, to take care of
# some of the early DVT W400c devices whose VRD default value upon power-up
# is NOT 825. This will not harm newer devices with correct default value.
if [ $((brd_type)) -eq 1 ]; then
  echo "Running GB VDD Core fix routine."
  /usr/local/bin/set_vdd.sh 825
fi

# export_gpio_pin for PCA9555 4-0027
gpiocli export -c 4-0027 -o 8 --shadow ISO_DEBUG_RST_BTN_N
gpiocli export -c 4-0027 -o 9 --shadow ISO_PWR_BTN_N
gpiocli export -c 4-0027 -o 10 --shadow PWRGD_PCH_PWROK
gpiocli export -c 4-0027 -o 11 --shadow ISO_CB_RESET_N
gpiocli export -c 4-0027 -o 12 --shadow COM_PWROK
gpiocli export -c 4-0027 -o 13 --shadow CPU_CATERR_MSMI_EXT
gpiocli export -c 4-0027 -o 14 --shadow ISO_COM_SUS_S3_N
gpiocli export -c 4-0027 -o 15 --shadow DEBUG_UART_SELECT


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

### BEGIN INIT INFO
# Provides:          setup_board.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup the board
### END INIT INFO

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

echo -n "Setting up Default GPIOs value... "

# Set all reset pin to high, keep in normal mode
gpio_set_value BMC_EMMC_RST_N_R 1
gpio_set_value SYS_CPLD_RST_N 1
gpio_set_value BMC_DOM_FPGA1_RST 1
gpio_set_value BMC_DOM_FPGA2_RST 1

echo "done."


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

i2c_detect_address() {
   bus="$1"
   addr="$2"
   if [ -n "$3" ]; then
      retries="$3"
   else
      retries=5
   fi

   retry=0

   while [ "$retry" -lt "$retries" ]; do
      if i2cget -y -f "$bus" "$addr" &> /dev/null; then
         return 0
      fi
      usleep 50000
      retry=$((retry + 1))
   done

   echo "setup-i2c : i2c_detect not found $bus - $addr" > /dev/kmsg
   return 1
}

get_mux_bus_num() {
    i2c_switch=$1
    channel=$2

    if [ "$i2c_switch" = "2-0070" ]; then
        start_bus_num=16
    elif [ "$i2c_switch" = "8-0070" ]; then
        start_bus_num=24
    elif [ "$i2c_switch" = "11-0076" ]; then
        start_bus_num=32
    else
        echo "Error: i2c switch $i2c_switch does not exist"
        start_bus_num=200
    fi

    echo $((start_bus_num + channel))
}

brd_type_rev=$(wedge_board_type_rev)
echo "Board Type/Revision: $brd_type_rev"

brd_type=$(wedge_board_type)
brd_rev=$(wedge_board_rev)

# # Bus 2
i2c_device_add 2 0x3e scmcpld          # SCMCPLD

# # Bus 12
i2c_device_add 12 0x3e smb_syscpld     # SMB_SYSCPLD

# # i2c-mux 8-0070, channel 8
i2c_device_add "$(get_mux_bus_num 8-0070 7)" 0x3e smb_pwrcpld # SMB_PWRCPLD

# # Bus 13
i2c_device_add 13 0x60 domfpga        # DOM FPGA 1

# # Bus 4
i2c_device_add 4 0x27 pca9555         # PCA9555

# # Bus 5
i2c_device_add 5 0x60 domfpga         # DOM FPGA 2

# # Bus 6
i2c_device_add 6 0x51 24c64            # SMB EEPROM
i2c_device_add 6 0x21 pca9534          # PCA9534

# # Bus 1
i2c_device_add 1 0x3a powr1220          # SMB power sequencer
i2c_device_add 1 0x4d ir35215           # TH3 serdes voltage/current monitor on the left
i2c_device_add 1 0x47 ir35215           # TH3 serdes voltage/current monitor on the right

# # Bus 3
i2c_device_add 3 0x48 tmp75            # SMB temp. sensor
i2c_device_add 3 0x4b tmp75            # SMB temp. sensor

# # i2c-mux 2-0070, channel 1, support dual footprint
if i2c_detect_address "$(get_mux_bus_num 2-0070 0)" 0x10; then
    i2c_device_add "$(get_mux_bus_num 2-0070 0)" 0x10 adm1278 # SCM Hotswap
else
    i2c_device_add "$(get_mux_bus_num 2-0070 0)" 0x44 lm25066 # SCM Hotswap
fi

# # i2c-mux 2-0070, channel 2
i2c_device_add "$(get_mux_bus_num 2-0070 1)" 0x4d tmp75   # SCM temp. sensor

# # i2c-mux 2-0070, channel 4
i2c_device_add "$(get_mux_bus_num 2-0070 3)" 0x52 24c64   # EEPROM

# # i2c-mux 2, channel 5
i2c_device_add "$(get_mux_bus_num 2-0070 4)" 0x50 24c02   # BMC54616S EEPROM

# # i2c-mux 8-0070, channel 1
if [ "$(wedge_power_supply_type 1)" = "PSU" ] ||
   [ "$(wedge_power_supply_type 1)" = "PSU48" ]; then
    i2c_device_add "$(get_mux_bus_num 8-0070 0)" 0x58 psu_driver   # PSU1 Driver
else
    i2c_device_add "$(get_mux_bus_num 8-0070 0)" 0x58 ltc4282      # PEM1 Driver
    i2c_device_add "$(get_mux_bus_num 8-0070 0)" 0x18 max6615      # PEM1 Driver
fi

# # i2c-mux 8-0070, channel 2
if [ "$(wedge_power_supply_type 2)" = "PSU" ] ||
   [ "$(wedge_power_supply_type 2)" = "PSU48" ]; then
    i2c_device_add "$(get_mux_bus_num 8-0070 1)" 0x58 psu_driver   # PSU2 Driver
else
    i2c_device_add "$(get_mux_bus_num 8-0070 1)" 0x58 ltc4282      # PEM2 Driver
    i2c_device_add "$(get_mux_bus_num 8-0070 1)" 0x18 max6615      # PEM2 Driver
fi

# # i2c-mux 11-0076, channel 1
i2c_device_add "$(get_mux_bus_num 11-0076 0)" 0x3e fcbcpld # FCB CPLD

# # i2c-mux 11-0076, channel 2
i2c_device_add "$(get_mux_bus_num 11-0076 1)" 0x51 24c64           # FCM EEPROM

# # i2c-mux 11-0076, channel 3
i2c_device_add "$(get_mux_bus_num 11-0076 2)" 0x48 tmp75           # Temp. sensor
i2c_device_add "$(get_mux_bus_num 11-0076 2)" 0x49 tmp75           # Temp. sensor

# # i2c-mux 11-0076, channel 4, support dual footprint
if i2c_detect_address "$(get_mux_bus_num 11-0076 3)" 0x10; then
    i2c_device_add "$(get_mux_bus_num 11-0076 3)" 0x10 adm1278     # FCB hot swap
else
    i2c_device_add "$(get_mux_bus_num 11-0076 3)" 0x44 lm25066     # FCB hot swap
fi

# # i2c-mux 11-0076, channel 5
i2c_device_add "$(get_mux_bus_num 11-0076 4)" 0x52 24c64           # FAN tray

# # i2c-mux 11-0076, channel 6
i2c_device_add "$(get_mux_bus_num 11-0076 5)" 0x52 24c64           # FAN tray

# # i2c-mux 11-0076, channel 7
i2c_device_add "$(get_mux_bus_num 11-0076 6)" 0x52 24c64           # FAN tray

# # i2c-mux 11-0076, channel 8
i2c_device_add "$(get_mux_bus_num 11-0076 7)" 0x52 24c64           # FAN tray

fixup_board_revisions() {
    if board_rev_is_respin; then
        # RACKMON EEPROM, added in Wedge400 MP Respin and Wedge400C Respin
        i2c_device_add 6 0x50 24c64            # RACKMON EEPROM
    else
        # below sensors are removed from Wedge400 MP Respin (type=0,rev=6)
        # and Wedge400C Respin (type=1,rev=4).
        i2c_device_add 3 0x4c tmp421           # SMB temp. sensor
        i2c_device_add 3 0x4e tmp421           # SMB temp. sensor
        i2c_device_add "$(get_mux_bus_num 2-0070 1)" 0x4c tmp75  # SCM temp sensor

        # TH3 EEPROM is removed from Wedge400 MP Respin (type=0,rev=6) and
        # Wedge400C Respin (type=1,rev=4).
        i2c_device_add "$(get_mux_bus_num 8-0070 4)" 0x54 24c02  # TH3 EEPROM
    fi

    if board_type_is_wedge400; then         # Only Wedge400 (type=0)
        i2c_device_add 1 0x60 isl68137      # TH3 core voltage/current monitor
        if wedge400_rev_is_mp; then
            i2c_device_add 3 0x4f tmp422    # TH3 temp. sensor Remove from Respin version(rev=6)
        fi
    else                                    # Only Wedge400-C (type=1)
        i2c_device_add 1 0x40 xdpe132g5c    # Wedge400-C GB core voltage/current monitor
        i2c_device_add 3 0x2a net_casic     # GB temp. sensor
        if [  $((brd_rev)) -eq 0 ]; then
            i2c_device_add 1 0x43 ir35215   # Wedge400-C GB serdes voltage/current monitor
        else
            i2c_device_add 1 0x0e pxe1211   # Wedge400-C EVT2(rev=0) or later GB serdes voltage/current monitor
        fi
    fi

    #
    # For wedge400 MP respin(type=0,rev=6) and later.
    # Dual footprint will mount either one temp sensor for each bus.
    # i2c-mux 8-0070, channel 3-5 and 7
    #
    if wedge400_rev_is_respin; then
        # i2c-mux 8-0070, channel 3
        if i2c_detect_address "$(get_mux_bus_num 8-0070 2)" 0x4d; then
            i2c_device_add "$(get_mux_bus_num 8-0070 2)" 0x4d tmp421      # TMP421_4
        else
            i2c_device_add "$(get_mux_bus_num 8-0070 2)" 0x4c adm1032     # ADM1032_4
        fi

        # i2c-mux 8-0070, channel 4
        if i2c_detect_address "$(get_mux_bus_num 8-0070 3)" 0x4d; then
            i2c_device_add "$(get_mux_bus_num 8-0070 3)" 0x4d tmp421      # TMP421_3
        else
            i2c_device_add "$(get_mux_bus_num 8-0070 3)" 0x4c adm1032     # ADM1032_3
        fi

        # i2c-mux 8-0070, channel 5
        if i2c_detect_address "$(get_mux_bus_num 8-0070 4)" 0x4d; then
            i2c_device_add "$(get_mux_bus_num 8-0070 4)" 0x4d tmp421      # TMP421_2
        else
            i2c_device_add "$(get_mux_bus_num 8-0070 4)" 0x4c adm1032     # ADM1032_2
        fi

        # i2c-mux 8-0070, channel 7
        if i2c_detect_address "$(get_mux_bus_num 8-0070 6)" 0x4d; then
            i2c_device_add "$(get_mux_bus_num 8-0070 6)" 0x4d tmp421      # TMP421_1
        else
            i2c_device_add "$(get_mux_bus_num 8-0070 6)" 0x4c adm1032     # ADM1032_1
        fi
    else
        i2c_device_add 3 0x49 tmp75            # SMB temp. sensor
        i2c_device_add 3 0x4a tmp75            # SMB temp. sensor
    fi

    # BCM54616 EEPROMs are removed physically from:
    #   - Wedge400 MP Respin(type=0,rev=6) and later
    #   - Wedge400-C DVT(type=1,rev=2) and later
    if [[ "$brd_type" -eq 0 && "$brd_rev" -lt 6 ]] || \
       [[ "$brd_type" -eq 1 && "$brd_rev" -lt 2 ]]; then
        # # i2c-mux 8-0070, channel 3
        i2c_device_add "$(get_mux_bus_num 8-0070 2)" 0x50 24c02          # BCM54616 EEPROM
        # # i2c-mux 8-0070, channel 4
        i2c_device_add "$(get_mux_bus_num 8-0070 3)" 0x50 24c02          # BCM54616 EEPROM
    fi

    # BSM EEPROM were added:
    #   - Wedge400 DVT2(type=0,rev=3) or later,
    #   - Wedge400c EVT2(type=1,rev=1) or later
    if [[ "$brd_type" -eq 0 && "$brd_rev" -ge 3 ]] || \
       [[ "$brd_type" -eq 1 && "$brd_rev" -ge 1 ]]; then
        i2c_device_add "$(get_mux_bus_num 2-0070 6)" 0x56 24c64   # BSM EEPROM
    fi
}

fixup_board_revisions

# Hack only needed for wedge400c.
if board_type_is_wedge400c; then
    /usr/local/bin/rebind-driver.sh
fi

#
# Check if I2C devices are bound to drivers. A summary message (total #
# of devices and # of devices without drivers) will be dumped at the end
# of this function.
#
i2c_check_driver_binding


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

COM_E_PWRGD=$(head -n 1 "${SCMCPLD_SYSFS_DIR}/pwrgd_pch_pwrok")

usage(){
    program=$(basename "$0")
    echo "Usage:"
    echo "     $program led"
}

if [ $# -ne 1 ]; then
    usage
    exit 1
fi

# When COM-e power is not ready, it doesn't work to set PHY register.
# Therefore, waiting for COM-e power ready, then start to set PHY register.
while [ "$COM_E_PWRGD" = "0x0" ];
do
    COM_E_PWRGD=$(head -n 1 "${SCMCPLD_SYSFS_DIR}/pwrgd_pch_pwrok")
    sleep 5
done

# Enable MAC#1 Clock, refer to ast2500-v16.pdf Page 355
# SCU 0x04 register: Bit[11] Reset MAC1 controller
#     0: No operation, 1: Reset MAC1 controller
# SCU 0x0C register: Bit20 MAC#1 Clock:
#     0 Enable clock running, 1 disable clock running
devmem_set_bit "$(scu_addr 04)" 11
devmem_clear_bit "$(scu_addr 0C)" 20
devmem_clear_bit "$(scu_addr 04)" 11

# Enable MAC#1 MDIO function, refer to ast2500-v16.pdf Page 376
# SCU 0x88 register: Bit31 Enable MAC#1 MDIO1 function pin
# SCU 0x88 register: Bit30 Enable MAC#1 MDC1 function pin
devmem_set_bit "$(scu_addr 88)" 30
devmem_set_bit "$(scu_addr 88)" 31

if [ "$1" = "led" ]; then
    echo -n "Wait a few seconds to setup management port LED..."

    # Because the addresses of the PHY and OOB switch are different, so not need to differentiate
    # the platform

    # configure the platform with Marvell PHY and OOB swich:

    # Setup Port 3 MGMT
    mdio-util -m 1 -p 0x12 -w 0x1 -d 0x8088    # Write Config LED mode Data into Reg 0x01
    mdio-util -m 1 -p 0x12 -w 0x0 -d 0x9676    #  Read Port3.Reg 0x16
    mdio-util -m 1 -p 0x12 -w 0x0 -d 0x9a76    # Config Reg 0x01 value into Port3.Reg 0x16
    mdio-util -m 1 -p 0x12 -r 0x1    # Read Reg 0x01

    # Setup Port4 Rackmon port
    mdio-util -m 1 -p 0x12 -w 0x1 -d 0x8088
    mdio-util -m 1 -p 0x12 -w 0x0 -d 0x9696
    mdio-util -m 1 -p 0x12 -w 0x0 -d 0x9a96
    mdio-util -m 1 -p 0x12 -r 0x1

    # Setup Copper Mode for SCM Management Port
    mdio-util -m 1 -p 0x1 -w 0x16 -d 0x12
    mdio-util -m 1 -p 0x1 -w 0x14 -d 0x8001
    mdio-util -m 1 -p 0x1 -w 0x16 -d 0x0

    #  configure the platform with Broadcom OOB swich:

    # refer to BCM54616S Section 5, register 1C access
    # Register 1C (Shadow 00010): Spare Control 1
    # Bit0: 1: Enable link LED mode.
    mdio-util -m 1 -p 0xe -w 0x1c -d 0x8801 &> /dev/null

    # Register 1C (Shadow 01110): LED Selector 2
    # Bit7~4: LED4 Selector, b0011: Activity LED
    # Bit3~0: LED4 Selector, b0101: Slave
    mdio-util -m 1 -p 0xe -w 0x1c -d 0xb435 &> /dev/null
    echo "Done!"
else
    usage
    exit 1
fi


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

# Set all IO direction to output
i2cset -f -y 6 0x20 0x06 0x00
i2cset -f -y 6 0x20 0x07 0x00

IO0=$(i2cget -f -y 6 0x20 0x2)
IO1=$(i2cget -f -y 6 0x20 0x3)

color=$2
name=$1

usage(){
    program=$(basename "$0")
    echo "Usage:"
    echo "     $program <dev> <color>"
    echo ""
    echo "     <dev>: sts/smb/psu/fan"
    echo "     <color>: off/red/blue/yellow/green"
}

brd_type=$(wedge_board_type)
brd_rev=$(wedge_board_rev)
# In Wedge400 MP Respin and Wedge400C Respin
# the led location are swaped
if [ $((brd_type)) -eq 0 ] && [ $((brd_rev)) -ge 6 ] ||
   [ $((brd_type)) -eq 1 ] && [ $((brd_rev)) -ge 4 ]; then
  case $name in
    "sts")
      led_id=2
    ;;
    "fan")
      led_id=4
    ;;
    "psu")
      led_id=3
    ;;
    "smb")
      led_id=1
    ;;
    *)
      usage
      exit 1
    ;;
  esac
else
  case $name in
    "sts")
      led_id=1
    ;;
    "fan")
      led_id=2
    ;;
    "psu")
      led_id=3
    ;;
    "smb")
      led_id=4
    ;;
    *)
      usage
      exit 1
    ;;
  esac
fi

case $color in
    "red")
        val=0x6
    ;;
    "blue")
        val=0x3
    ;;
    "yellow")
        val=0x4
    ;;
    "green")
        val=0x5
    ;;
    "off")
        val=0x7
    ;;
    *)
    usage
    exit 1
    ;;
esac

if [ $((led_id)) -eq 2 ] || [ $((led_id)) -eq 4 ]; then
  val=$((val << 3))
  IO0_VAL=$(((IO0 & 0x7) | val))
  IO1_VAL=$(((IO1 & 0x7) | val))
elif [ $((led_id)) -eq 1 ] || [ $((led_id)) -eq 3 ]; then
  IO0_VAL=$(((IO0 & 0x38) | val))
  IO1_VAL=$(((IO1 & 0x38) | val))
else
  usage
  exit 1
fi

if [ $((led_id)) -eq 1 ] || [ $((led_id)) -eq 2 ]; then
  i2cset -f -y 6 0x20 0x2 $IO0_VAL
else
  i2cset -f -y 6 0x20 0x3 $IO1_VAL
fi


#!/bin/sh

usage()
{
  echo "usage :"
  echo "   $0 <voltage in mv>"
  echo "   eg. $0 850"
  echo " limit : max 930 mV"
}

if [ $# -ne 1 ]; then
  usage
  exit 255
fi

if [ $(($1)) -gt 931 ]; then
  usage
  exit 255
fi

i2cset -f -y 1 0x40 0x00 0x00
i2cset -f -y 1 0x40 0x20 0x14    # linear mode  ,, N = 0x12
value=$(( $1 * 1000 / 244 ))
i2cset -f -y 1 0x40 0x21 $value w

if [ $? -eq 0 ]; then
  echo "$1"
  exit 0
else
  echo "setting error"
  exit 254
fi


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

prog="$0"
img="$1"

DLL_PATH=/usr/lib/libcpldupdate_dll_ast_jtag.so

usage() {
    echo "Usage: $prog <img_file> <options: hw|sw>"
    echo
    echo "img_file: Image file for lattice CPLD"
    echo "  VME file for software mode"
    echo "  JED file for hardware mode"
    echo "options:"
    echo "  hw: Program the CPLD using JTAG hardware mode"
    echo "  sw: Program the CPLD using JTAG software mode"
    echo
    echo
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

enable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN        1
    gpio_set PWR_CPLD_JTAG_EN_N     1
    gpio_set SYS_CPLD_JTAG_EN_N     0
    gpio_set SCM_CPLD_JTAG_EN_N     1
    gpio_set FCM_CPLD_JTAG_EN_N     1
    gpio_set PWR_CPLD_HITLESS       0
    gpio_set FCM_CPLD_HITLESS       0
    gpio_set SCM_CPLD_HITLESS       0
    gpio_set SMB_CPLD_HITLESS       1
    gpio_set BMC_FCM_SEL            1
    gpio_set BMC_SCM_CPLD_EN        1
}

disable_jtag_chain(){
    gpio_set BMC_JTAG_MUX_IN        0
    gpio_set PWR_CPLD_JTAG_EN_N     1
    gpio_set SYS_CPLD_JTAG_EN_N     1
    gpio_set SCM_CPLD_JTAG_EN_N     1
    gpio_set FCM_CPLD_JTAG_EN_N     1
    gpio_set PWR_CPLD_HITLESS       0
    gpio_set FCM_CPLD_HITLESS       0
    gpio_set SCM_CPLD_HITLESS       0
    gpio_set SMB_CPLD_HITLESS       0
    gpio_set BMC_FCM_SEL            1
    gpio_set BMC_SCM_CPLD_EN        1
}

trap 'rm -rf /tmp/smbcpld_update' INT TERM QUIT EXIT

echo 1 > /tmp/smbcpld_update

if ! wedge_prepare_cpld_update; then
    echo "Aborting CPLD upgrade"
    echo "The FSCD may be closed incompletely,"
    echo "Please check the watchdog timeout, to prevent system reboot."
    exit 1
fi

enable_jtag_chain

case $2 in
    hw)
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -f 12000000
        ;;
    sw)
        ispvm -f 1000 dll $DLL_PATH "${img}"
        ;;
    *)
        # default: hw mode
        # CPLD update randomly failed with kernel 5.6, the issue can be fixed by
        # customizing jtag frequency to 12MHz.
        cpldprog -p "${img}" -f 12000000
        ;;
esac

result=$?

if [ "$2" = "sw" ]; then
    expect=1
else
    expect=0
fi

disable_jtag_chain

# 0 is returned upon upgrade success
if [ $result -eq $expect ]; then
    echo "Upgrade successful."
    echo "Re-start fscd service."
    sv start fscd
    exit 0
else
    echo "Upgrade failure. Return code from utility : $result"
    echo "To prevent system reboot. Keep fscd stop & watchdog disable."
    exit 1
fi


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
. /usr/local/bin/openbmc-utils.sh

CONSOLE_SH=/usr/local/bin/us_console.sh
FILE=/etc/us_pseudo_tty
TTY=/dev/ttyS0

mTerm_server_running() {
  pid=$(ps | grep -v grep | grep '/usr/local/bin/mTerm_server' -m 1 |
      awk '{print $1}')
  if [ $pid ] ; then
    return 0
  fi
  return 1
}

start_sol_session() {
  if [ -a $FILE ]
    then
      read -r TTY<$FILE
  fi
  $CONSOLE_SH connect

  echo "You are in SOL session."
  echo "Use ctrl-x to quit."
  echo "-----------------------"
  echo

  trap '"$CONSOLE_SH" disconnect' INT TERM QUIT EXIT

  /usr/bin/microcom -s 57600 $TTY

  echo
  echo
  echo "-----------------------"
  echo "Exit from SOL session."
}

# if mTerm server is running use mTerm_client to connect to userver
# otherwise fallback to the old method
echo 0x3 > $SMBCPLD_SYSFS_DIR/uart_selection
if mTerm_server_running; then
  exec /usr/local/bin/mTerm_client wedge
else
  start_sol_session
fi