Skip to content

Commit

Permalink
meta-ampere: mtmitchell: add handshake support for Host SPI NOR acces…
Browse files Browse the repository at this point in the history
…s between BMC and CPU

Add ampere_spi_util.sh script to handshake SPI-NOR between BMC and host:
- GIPOM2(soc-spi-nor-access): This input indicates that the host is
accessing the SPINOR. The BMC does not access the SPI-NOR when
this pin is asserted.
- GPIOS5(spi-nor-access): This output indicates that the BMC is
accessing the SPINOR. The host does not access the SPI-NOR when
this pin is asserted.

A mutex file /run/platform/spi.lock is also created to handshake
between multiple processes of BMC.

Signed-off-by: Dung Cao <[email protected]>
  • Loading branch information
dcao-ampere authored and thangqn-ampere committed May 19, 2023
1 parent 15c096e commit 7abcb6e
Show file tree
Hide file tree
Showing 2 changed files with 245 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SRC_URI:append = " \
file://ampere_firmware_version.sh \
file://ampere_fanctrl.sh \
file://ampere_pldm_effecter_trigger.sh \
file://ampere_spi_util.sh \
"

do_install:append() {
Expand All @@ -21,4 +22,5 @@ do_install:append() {
install -m 0755 ${WORKDIR}/ampere_firmware_version.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_fanctrl.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_pldm_effecter_trigger.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_spi_util.sh ${D}/${sbindir}/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
#!/bin/bash

# shellcheck disable=SC2046
# shellcheck source=/dev/null

source /usr/sbin/gpio-lib.sh

spi_address="1e630000.spi"
spi_bind="/sys/bus/platform/drivers/spi-aspeed-smc/bind"
spi_unbind="/sys/bus/platform/drivers/spi-aspeed-smc/unbind"
spi_lock="/run/platform/spi.lock"
spi_lock_dir="/run/platform"

bind_aspeed_smc_driver() {
if [ -f "${spi_lock}" ]; then
pid=$1
pid_lock=$(cat "${spi_lock}")
if [[ "${pid}" != "${pid_lock}" ]]; then
echo "SPI-NOR resoure is lock by process $pid_lock"
return 1
fi
fi

# BMC access SPI-NOR resource
gpio_name_set spi0-program-sel 1
sleep 0.1
echo "Bind the ASpeed SMC driver"
echo "${spi_address}" > "${spi_bind}" 2>/dev/null
# Check the HNOR partition available
HOST_MTD=$(< /proc/mtd grep "hnor" | sed -n 's/^\(.*\):.*/\1/p')
if [ -z "$HOST_MTD" ]; then
echo "${spi_address}" > "${spi_unbind}"
sleep 0.1
echo "${spi_address}" > "${spi_bind}"
fi
# BMC release SPI-NOR resource
gpio_name_set spi0-program-sel 0
return 0
}

unbind_aspeed_smc_driver() {
if [ -f "${spi_lock}" ]; then
pid=$1
pid_lock=$(cat "${spi_lock}")
if [[ "${pid}" != "${pid_lock}" ]]; then
echo "SPI-NOR resoure is lock by process $pid_lock . Wait 10s"
# Wait maximum 10 seconds for unlock SPI-NOR
cnt=10
while [ $cnt -gt 0 ]
do
if [ -f "${spi_lock}" ]; then
sleep 1
cnt=$((cnt - 1))
else
break
fi
done
if [ "$cnt" -eq "0" ]; then
echo "Timeout 10 seconds, SPI-NOR still busy. Force unlock to access SPI"
rm -f "${spi_lock}"
fi
fi
fi

HOST_MTD=$(< /proc/mtd grep "hnor" | sed -n 's/^\(.*\):.*/\1/p')
if [ -n "$HOST_MTD" ]; then
# If the HNOR partition is available, then unbind driver
# BMC access SPI-NOR resource
gpio_name_set spi0-program-sel 1
sleep 0.1
echo "Unbind the ASpeed SMC driver"
echo "${spi_address}" > "${spi_unbind}"
fi
# BMC release SPI-NOR resource
gpio_name_set spi0-program-sel 0
# Deassert BMC access SPI-NOR pin
gpio_name_set spi-nor-access 0
sleep 0.5
return 0
}

lock_spi_resource() {
# Wait maximum 10 seconds to lock SPI-NOR
cnt=10
while [ $cnt -gt 0 ]
do
if [ -f "${spi_lock}" ]; then
sleep 1
cnt=$((cnt - 1))
else
echo "$1" > "${spi_lock}"
break
fi
done

if [ "$cnt" -eq "0" ]; then
echo "Timeout 10 seconds, SPI-NOR is still locked by another process"
return 1
fi
return 0
}

unlock_spi_resource() {
if [ ! -f "${spi_lock}" ]; then
echo "SPI-NOR is already unlocked"
return 0
fi

pid=$1
pid_lock=$(cat "${spi_lock}")
if [[ "${pid}" == "${pid_lock}" ]]; then
rm -f "${spi_lock}"
else
echo "Cannot unlock, SPI-NOR is locked by another process"
return 1
fi
return 0
}

start_handshake_spi() {
if [ -f "${spi_lock}" ]; then
pid=$1
pid_lock=$(cat "${spi_lock}")
if [[ "${pid}" != "${pid_lock}" ]]; then
echo "SPI-NOR resoure is lock by process $pid_lock"
return 1
fi
fi

# Wait maximum 10 seconds to grant access SPI
cnt=10
while [ $cnt -gt 0 ]
do
spinor_access=$(gpio_name_get soc-spi-nor-access)
if [ "$spinor_access" == "1" ]; then
sleep 1
cnt=$((cnt - 1))
else
break
fi
done

if [ "$cnt" -eq "0" ]; then
echo "Timeout 10 seconds, host is still hold SPI-NOR."
return 1
fi
echo "Start handshake SPI-NOR"
# Grant BMC access SPI-NOR. The process call the scripts should only
# claim the bus for only maximum period 500ms.
gpio_name_set spi-nor-access 1
# Switch the Host SPI-NOR to BMC
gpio_name_set spi0-program-sel 1
}

stop_handshake_spi() {
if [ -f "${spi_lock}" ]; then
pid=$1
pid_lock=$(cat "${spi_lock}")
if [[ "${pid}" != "${pid_lock}" ]]; then
echo "SPI-NOR resoure is lock by process $pid_lock"
return 1
fi
fi
echo "Stop handshake SPI-NOR"
# Switch the Host SPI-NOR to HOST
gpio_name_set spi0-program-sel 0
# Deassert BMC access SPI-NOR pin
gpio_name_set spi-nor-access 0
}


if [ $# -eq 0 ]; then
echo "Usage:"
echo " - Handshake access SPI-NOR "
echo " $(basename "$0") cmd pid"
echo " <cmd>:"
echo " lock - lock the SPI-NOR resource"
echo " unlock - unlock the SPI-NOR resource"
echo " bind - bind the SPI-NOR resource"
echo " unbind - unbind the SPI-NOR resource"
echo " start_handshake - start handshake between BMC and Host"
echo " stop_handshake - release handshake between BMC and Host"
echo " <pid>: Optional - PID of the process call script"
exit 0
fi

CMD=$1

if [ ! -d "${spi_lock_dir}" ]; then
mkdir -p "${spi_lock_dir}"
fi

if [ -z "$2" ]; then
PID=$$
else
PID=$2
fi

if [[ "${CMD}" == "lock" ]]; then
lock_spi_resource "${PID}"
ret=$?
if [[ "${ret}" == "1" ]]; then
echo "Cannot lock SPI-NOR, the resource is busy"
exit 1
fi
elif [[ "${CMD}" == "unlock" ]]; then
unlock_spi_resource "${PID}"
ret=$?
if [[ "${ret}" == "1" ]]; then
echo "Cannot unlock SPI-NOR, the resource is busy"
exit 1
fi
elif [[ "${CMD}" == "bind" ]]; then
bind_aspeed_smc_driver "${PID}"
ret=$?
if [[ "${ret}" == "1" ]]; then
echo "Cannot bind SPI-NOR, the resource is busy"
exit 1
fi
elif [[ "${CMD}" == "unbind" ]]; then
unbind_aspeed_smc_driver "${PID}"
ret=$?
if [[ "${ret}" == "1" ]]; then
echo "Cannot unbind SPI-NOR, the resource is busy"
exit 1
fi
elif [[ "${CMD}" == "start_handshake" ]]; then
start_handshake_spi "${PID}"
ret=$?
if [[ "${ret}" == "1" ]]; then
echo "Cannot start handshake SPI-NOR"
exit 1
fi
elif [[ "${CMD}" == "stop_handshake" ]]; then
stop_handshake_spi "${PID}"
ret=$?
if [[ "${ret}" == "1" ]]; then
echo "Cannot stop handshake SPI-NOR"
exit 1
fi
fi

exit 0

0 comments on commit 7abcb6e

Please sign in to comment.