diff --git a/board/myna-player-odyssey/configs/busybox.config b/board/myna-player-odyssey/configs/busybox.config deleted file mode 100644 index d8f6d6d..0000000 --- a/board/myna-player-odyssey/configs/busybox.config +++ /dev/null @@ -1,1162 +0,0 @@ -# -# Busybox version: 1.31.1 -# Thu Jun 18 13:45:37 2020 -# -CONFIG_HAVE_DOT_CONFIG=y - -# -# Settings -# -# CONFIG_DESKTOP is not set -# CONFIG_EXTRA_COMPAT is not set -# CONFIG_FEDORA_COMPAT is not set -# CONFIG_INCLUDE_SUSv2 is not set -CONFIG_LONG_OPTS=y -# CONFIG_SHOW_USAGE is not set -# CONFIG_FEATURE_VERBOSE_USAGE is not set -# CONFIG_FEATURE_COMPRESS_USAGE is not set -CONFIG_LFS=y -# CONFIG_PAM is not set -CONFIG_FEATURE_DEVPTS=y -CONFIG_FEATURE_UTMP=y -CONFIG_FEATURE_WTMP=y -# CONFIG_FEATURE_PIDFILE is not set -CONFIG_PID_FILE_PATH="" -CONFIG_BUSYBOX=y -CONFIG_FEATURE_SHOW_SCRIPT=y -CONFIG_FEATURE_INSTALLER=y -# CONFIG_INSTALL_NO_USR is not set -CONFIG_FEATURE_SUID=y -# CONFIG_FEATURE_SUID_CONFIG is not set -# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set -# CONFIG_FEATURE_PREFER_APPLETS is not set -CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" -# CONFIG_SELINUX is not set -# CONFIG_FEATURE_CLEAN_UP is not set -CONFIG_FEATURE_SYSLOG_INFO=y -CONFIG_FEATURE_SYSLOG=y -CONFIG_PLATFORM_LINUX=y - -# -# Build Options -# -# CONFIG_STATIC is not set -# CONFIG_PIE is not set -# CONFIG_NOMMU is not set -# CONFIG_BUILD_LIBBUSYBOX is not set -# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set -# CONFIG_FEATURE_INDIVIDUAL is not set -# CONFIG_FEATURE_SHARED_BUSYBOX is not set -CONFIG_CROSS_COMPILER_PREFIX="" -CONFIG_SYSROOT="" -CONFIG_EXTRA_CFLAGS="" -CONFIG_EXTRA_LDFLAGS="" -CONFIG_EXTRA_LDLIBS="" -# CONFIG_USE_PORTABLE_CODE is not set -CONFIG_STACK_OPTIMIZATION_386=y - -# -# Installation Options ("make install" behavior) -# -CONFIG_INSTALL_APPLET_SYMLINKS=y -# CONFIG_INSTALL_APPLET_HARDLINKS is not set -# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set -# CONFIG_INSTALL_APPLET_DONT is not set -# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set -# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set -# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set -CONFIG_PREFIX="./_install" - -# -# Debugging Options -# -# CONFIG_DEBUG is not set -# CONFIG_DEBUG_PESSIMIZE is not set -# CONFIG_DEBUG_SANITIZE is not set -# CONFIG_UNIT_TEST is not set -# CONFIG_WERROR is not set -CONFIG_NO_DEBUG_LIB=y -# CONFIG_DMALLOC is not set -# CONFIG_EFENCE is not set - -# -# Library Tuning -# -# CONFIG_FEATURE_USE_BSS_TAIL is not set -CONFIG_FLOAT_DURATION=y -CONFIG_FEATURE_RTMINMAX=y -CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS=y -CONFIG_FEATURE_BUFFERS_USE_MALLOC=y -# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set -# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set -CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SMALL=1 -CONFIG_SHA3_SMALL=1 -# CONFIG_FEATURE_FAST_TOP is not set -# CONFIG_FEATURE_ETC_NETWORKS is not set -# CONFIG_FEATURE_ETC_SERVICES is not set -# CONFIG_FEATURE_EDITING is not set -CONFIG_FEATURE_EDITING_MAX_LEN=0 -# CONFIG_FEATURE_EDITING_VI is not set -CONFIG_FEATURE_EDITING_HISTORY=0 -# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set -# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set -# CONFIG_FEATURE_REVERSE_SEARCH is not set -# CONFIG_FEATURE_TAB_COMPLETION is not set -# CONFIG_FEATURE_USERNAME_COMPLETION is not set -# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set -# CONFIG_FEATURE_EDITING_WINCH is not set -# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set -# CONFIG_LOCALE_SUPPORT is not set -# CONFIG_UNICODE_SUPPORT is not set -# CONFIG_UNICODE_USING_LOCALE is not set -# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set -CONFIG_SUBST_WCHAR=0 -CONFIG_LAST_SUPPORTED_WCHAR=0 -# CONFIG_UNICODE_COMBINING_WCHARS is not set -# CONFIG_UNICODE_WIDE_WCHARS is not set -# CONFIG_UNICODE_BIDI_SUPPORT is not set -# CONFIG_UNICODE_NEUTRAL_TABLE is not set -# CONFIG_UNICODE_PRESERVE_BROKEN is not set -CONFIG_FEATURE_NON_POSIX_CP=y -# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set -CONFIG_FEATURE_USE_SENDFILE=y -CONFIG_FEATURE_COPYBUF_KB=4 -CONFIG_FEATURE_SKIP_ROOTFS=y -CONFIG_MONOTONIC_SYSCALL=y -CONFIG_IOCTL_HEX2STR_ERROR=y -CONFIG_FEATURE_HWIB=y - -# -# Applets -# - -# -# Archival Utilities -# -# CONFIG_FEATURE_SEAMLESS_XZ is not set -# CONFIG_FEATURE_SEAMLESS_LZMA is not set -# CONFIG_FEATURE_SEAMLESS_BZ2 is not set -# CONFIG_FEATURE_SEAMLESS_GZ is not set -# CONFIG_FEATURE_SEAMLESS_Z is not set -# CONFIG_AR is not set -# CONFIG_FEATURE_AR_LONG_FILENAMES is not set -# CONFIG_FEATURE_AR_CREATE is not set -# CONFIG_UNCOMPRESS is not set -# CONFIG_GUNZIP is not set -# CONFIG_ZCAT is not set -# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set -# CONFIG_BUNZIP2 is not set -# CONFIG_BZCAT is not set -# CONFIG_UNLZMA is not set -# CONFIG_LZCAT is not set -# CONFIG_LZMA is not set -# CONFIG_UNXZ is not set -# CONFIG_XZCAT is not set -# CONFIG_XZ is not set -# CONFIG_BZIP2 is not set -CONFIG_BZIP2_SMALL=0 -# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set -# CONFIG_CPIO is not set -# CONFIG_FEATURE_CPIO_O is not set -# CONFIG_FEATURE_CPIO_P is not set -# CONFIG_DPKG is not set -# CONFIG_DPKG_DEB is not set -# CONFIG_GZIP is not set -# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set -CONFIG_GZIP_FAST=0 -# CONFIG_FEATURE_GZIP_LEVELS is not set -# CONFIG_FEATURE_GZIP_DECOMPRESS is not set -# CONFIG_LZOP is not set -# CONFIG_UNLZOP is not set -# CONFIG_LZOPCAT is not set -# CONFIG_LZOP_COMPR_HIGH is not set -# CONFIG_RPM is not set -# CONFIG_RPM2CPIO is not set -# CONFIG_TAR is not set -# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set -# CONFIG_FEATURE_TAR_CREATE is not set -# CONFIG_FEATURE_TAR_AUTODETECT is not set -# CONFIG_FEATURE_TAR_FROM is not set -# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set -# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set -# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set -# CONFIG_FEATURE_TAR_TO_COMMAND is not set -# CONFIG_FEATURE_TAR_UNAME_GNAME is not set -# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set -# CONFIG_FEATURE_TAR_SELINUX is not set -# CONFIG_UNZIP is not set -# CONFIG_FEATURE_UNZIP_CDF is not set -# CONFIG_FEATURE_UNZIP_BZIP2 is not set -# CONFIG_FEATURE_UNZIP_LZMA is not set -# CONFIG_FEATURE_UNZIP_XZ is not set -# CONFIG_FEATURE_LZMA_FAST is not set - -# -# Coreutils -# -CONFIG_BASENAME=y -CONFIG_CAT=y -CONFIG_FEATURE_CATN=y -CONFIG_FEATURE_CATV=y -CONFIG_CHGRP=y -CONFIG_CHMOD=y -CONFIG_CHOWN=y -# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set -CONFIG_CHROOT=y -# CONFIG_CKSUM is not set -# CONFIG_COMM is not set -CONFIG_CP=y -# CONFIG_FEATURE_CP_LONG_OPTIONS is not set -# CONFIG_FEATURE_CP_REFLINK is not set -CONFIG_CUT=y -# CONFIG_DATE is not set -# CONFIG_FEATURE_DATE_ISOFMT is not set -# CONFIG_FEATURE_DATE_NANO is not set -# CONFIG_FEATURE_DATE_COMPAT is not set -# CONFIG_DD is not set -# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set -# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set -# CONFIG_FEATURE_DD_IBS_OBS is not set -# CONFIG_FEATURE_DD_STATUS is not set -# CONFIG_DF is not set -# CONFIG_FEATURE_DF_FANCY is not set -CONFIG_DIRNAME=y -# CONFIG_DOS2UNIX is not set -# CONFIG_UNIX2DOS is not set -# CONFIG_DU is not set -# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set -CONFIG_ECHO=y -CONFIG_FEATURE_FANCY_ECHO=y -CONFIG_ENV=y -# CONFIG_EXPAND is not set -# CONFIG_UNEXPAND is not set -CONFIG_EXPR=y -CONFIG_EXPR_MATH_SUPPORT_64=y -# CONFIG_FACTOR is not set -CONFIG_FALSE=y -# CONFIG_FOLD is not set -CONFIG_HEAD=y -CONFIG_FEATURE_FANCY_HEAD=y -CONFIG_HOSTID=y -CONFIG_ID=y -# CONFIG_GROUPS is not set -CONFIG_INSTALL=y -CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y -CONFIG_LINK=y -CONFIG_LN=y -# CONFIG_LOGNAME is not set -# CONFIG_LS is not set -# CONFIG_FEATURE_LS_FILETYPES is not set -# CONFIG_FEATURE_LS_FOLLOWLINKS is not set -# CONFIG_FEATURE_LS_RECURSIVE is not set -# CONFIG_FEATURE_LS_WIDTH is not set -# CONFIG_FEATURE_LS_SORTFILES is not set -# CONFIG_FEATURE_LS_TIMESTAMPS is not set -# CONFIG_FEATURE_LS_USERNAME is not set -# CONFIG_FEATURE_LS_COLOR is not set -# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set -# CONFIG_MD5SUM is not set -# CONFIG_SHA1SUM is not set -# CONFIG_SHA256SUM is not set -# CONFIG_SHA512SUM is not set -# CONFIG_SHA3SUM is not set -# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set -CONFIG_MKDIR=y -CONFIG_MKFIFO=y -CONFIG_MKNOD=y -CONFIG_MKTEMP=y -CONFIG_MV=y -CONFIG_NICE=y -# CONFIG_NL is not set -# CONFIG_NOHUP is not set -CONFIG_NPROC=y -# CONFIG_OD is not set -CONFIG_PASTE=y -# CONFIG_PRINTENV is not set -CONFIG_PRINTF=y -# CONFIG_PWD is not set -CONFIG_READLINK=y -CONFIG_FEATURE_READLINK_FOLLOW=y -CONFIG_REALPATH=y -CONFIG_RM=y -CONFIG_RMDIR=y -CONFIG_SEQ=y -# CONFIG_SHRED is not set -# CONFIG_SHUF is not set -CONFIG_SLEEP=y -CONFIG_FEATURE_FANCY_SLEEP=y -CONFIG_SORT=y -CONFIG_FEATURE_SORT_BIG=y -# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set -# CONFIG_SPLIT is not set -# CONFIG_FEATURE_SPLIT_FANCY is not set -# CONFIG_STAT is not set -# CONFIG_FEATURE_STAT_FORMAT is not set -# CONFIG_FEATURE_STAT_FILESYSTEM is not set -# CONFIG_STTY is not set -# CONFIG_SUM is not set -CONFIG_SYNC=y -# CONFIG_FEATURE_SYNC_FANCY is not set -# CONFIG_FSYNC is not set -# CONFIG_TAC is not set -CONFIG_TAIL=y -CONFIG_FEATURE_FANCY_TAIL=y -CONFIG_TEE=y -CONFIG_FEATURE_TEE_USE_BLOCK_IO=y -CONFIG_TEST=y -CONFIG_TEST1=y -CONFIG_TEST2=y -CONFIG_FEATURE_TEST_64=y -# CONFIG_TIMEOUT is not set -CONFIG_TOUCH=y -# CONFIG_FEATURE_TOUCH_NODEREF is not set -CONFIG_FEATURE_TOUCH_SUSV3=y -CONFIG_TR=y -CONFIG_FEATURE_TR_CLASSES=y -CONFIG_FEATURE_TR_EQUIV=y -CONFIG_TRUE=y -CONFIG_TRUNCATE=y -CONFIG_TTY=y -CONFIG_UNAME=y -CONFIG_UNAME_OSNAME="GNU/Linux" -CONFIG_BB_ARCH=y -CONFIG_UNIQ=y -CONFIG_UNLINK=y -CONFIG_USLEEP=y -CONFIG_UUDECODE=y -CONFIG_BASE64=y -CONFIG_UUENCODE=y -CONFIG_WC=y -# CONFIG_FEATURE_WC_LARGE is not set -CONFIG_WHOAMI=y -CONFIG_WHO=y -CONFIG_W=y -# CONFIG_USERS is not set -CONFIG_YES=y - -# -# Common options -# -CONFIG_FEATURE_VERBOSE=y - -# -# Common options for cp and mv -# -CONFIG_FEATURE_PRESERVE_HARDLINKS=y -# CONFIG_FEATURE_HUMAN_READABLE is not set - -# -# Console Utilities -# -# CONFIG_CHVT is not set -CONFIG_CLEAR=y -# CONFIG_DEALLOCVT is not set -CONFIG_DUMPKMAP=y -# CONFIG_FGCONSOLE is not set -# CONFIG_KBD_MODE is not set -# CONFIG_LOADFONT is not set -# CONFIG_SETFONT is not set -# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set -CONFIG_DEFAULT_SETFONT_DIR="" -# CONFIG_FEATURE_LOADFONT_PSF2 is not set -# CONFIG_FEATURE_LOADFONT_RAW is not set -# CONFIG_LOADKMAP is not set -# CONFIG_OPENVT is not set -CONFIG_RESET=y -CONFIG_RESIZE=y -CONFIG_FEATURE_RESIZE_PRINT=y -CONFIG_SETCONSOLE=y -# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set -# CONFIG_SETKEYCODES is not set -# CONFIG_SETLOGCONS is not set -# CONFIG_SHOWKEY is not set - -# -# Debian Utilities -# -# CONFIG_PIPE_PROGRESS is not set -# CONFIG_RUN_PARTS is not set -# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set -# CONFIG_FEATURE_RUN_PARTS_FANCY is not set -# CONFIG_START_STOP_DAEMON is not set -# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set -# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set -CONFIG_WHICH=y - -# -# klibc-utils -# -# CONFIG_MINIPS is not set -# CONFIG_NUKE is not set -# CONFIG_RESUME is not set -# CONFIG_RUN_INIT is not set - -# -# Editors -# -# CONFIG_AWK is not set -# CONFIG_FEATURE_AWK_LIBM is not set -# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set -# CONFIG_CMP is not set -# CONFIG_DIFF is not set -# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set -# CONFIG_FEATURE_DIFF_DIR is not set -# CONFIG_ED is not set -# CONFIG_PATCH is not set -# CONFIG_SED is not set -# CONFIG_VI is not set -CONFIG_FEATURE_VI_MAX_LEN=0 -# CONFIG_FEATURE_VI_8BIT is not set -# CONFIG_FEATURE_VI_COLON is not set -# CONFIG_FEATURE_VI_YANKMARK is not set -# CONFIG_FEATURE_VI_SEARCH is not set -# CONFIG_FEATURE_VI_REGEX_SEARCH is not set -# CONFIG_FEATURE_VI_USE_SIGNALS is not set -# CONFIG_FEATURE_VI_DOT_CMD is not set -# CONFIG_FEATURE_VI_READONLY is not set -# CONFIG_FEATURE_VI_SETOPTS is not set -# CONFIG_FEATURE_VI_SET is not set -# CONFIG_FEATURE_VI_WIN_RESIZE is not set -# CONFIG_FEATURE_VI_ASK_TERMINAL is not set -# CONFIG_FEATURE_VI_UNDO is not set -# CONFIG_FEATURE_VI_UNDO_QUEUE is not set -CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 -# CONFIG_FEATURE_ALLOW_EXEC is not set - -# -# Finding Utilities -# -CONFIG_FIND=y -CONFIG_FEATURE_FIND_PRINT0=y -CONFIG_FEATURE_FIND_MTIME=y -CONFIG_FEATURE_FIND_MMIN=y -CONFIG_FEATURE_FIND_PERM=y -CONFIG_FEATURE_FIND_TYPE=y -CONFIG_FEATURE_FIND_EXECUTABLE=y -CONFIG_FEATURE_FIND_XDEV=y -CONFIG_FEATURE_FIND_MAXDEPTH=y -CONFIG_FEATURE_FIND_NEWER=y -# CONFIG_FEATURE_FIND_INUM is not set -CONFIG_FEATURE_FIND_EXEC=y -CONFIG_FEATURE_FIND_EXEC_PLUS=y -CONFIG_FEATURE_FIND_USER=y -CONFIG_FEATURE_FIND_GROUP=y -CONFIG_FEATURE_FIND_NOT=y -CONFIG_FEATURE_FIND_DEPTH=y -CONFIG_FEATURE_FIND_PAREN=y -CONFIG_FEATURE_FIND_SIZE=y -CONFIG_FEATURE_FIND_PRUNE=y -CONFIG_FEATURE_FIND_QUIT=y -# CONFIG_FEATURE_FIND_DELETE is not set -CONFIG_FEATURE_FIND_PATH=y -CONFIG_FEATURE_FIND_REGEX=y -# CONFIG_FEATURE_FIND_CONTEXT is not set -# CONFIG_FEATURE_FIND_LINKS is not set -CONFIG_GREP=y -CONFIG_EGREP=y -CONFIG_FGREP=y -CONFIG_FEATURE_GREP_CONTEXT=y -CONFIG_XARGS=y -# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set -CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y -CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y -CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y -CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y -CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL=y -CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y - -# -# Init Utilities -# -# CONFIG_BOOTCHARTD is not set -# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set -# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set -CONFIG_HALT=y -CONFIG_POWEROFF=y -CONFIG_REBOOT=y -CONFIG_FEATURE_WAIT_FOR_INIT=y -# CONFIG_FEATURE_CALL_TELINIT is not set -CONFIG_TELINIT_PATH="" -CONFIG_INIT=y -CONFIG_LINUXRC=y -CONFIG_FEATURE_USE_INITTAB=y -CONFIG_FEATURE_KILL_REMOVED=y -CONFIG_FEATURE_KILL_DELAY=0 -CONFIG_FEATURE_INIT_SCTTY=y -CONFIG_FEATURE_INIT_SYSLOG=y -CONFIG_FEATURE_INIT_QUIET=y -# CONFIG_FEATURE_INIT_COREDUMPS is not set -CONFIG_INIT_TERMINAL_TYPE="linux" -CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y - -# -# Login/Password Management Utilities -# -CONFIG_FEATURE_SHADOWPASSWDS=y -# CONFIG_USE_BB_PWD_GRP is not set -# CONFIG_USE_BB_SHADOW is not set -CONFIG_USE_BB_CRYPT=y -CONFIG_USE_BB_CRYPT_SHA=y -# CONFIG_ADDGROUP is not set -# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set -# CONFIG_ADD_SHELL is not set -# CONFIG_REMOVE_SHELL is not set -# CONFIG_ADDUSER is not set -# CONFIG_FEATURE_CHECK_NAMES is not set -CONFIG_LAST_ID=0 -CONFIG_FIRST_SYSTEM_ID=0 -CONFIG_LAST_SYSTEM_ID=0 -# CONFIG_CHPASSWD is not set -CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" -# CONFIG_CRYPTPW is not set -CONFIG_MKPASSWD=y -# CONFIG_DELUSER is not set -# CONFIG_DELGROUP is not set -# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set -# CONFIG_GETTY is not set -# CONFIG_LOGIN is not set -# CONFIG_LOGIN_SESSION_AS_CHILD is not set -# CONFIG_LOGIN_SCRIPTS is not set -# CONFIG_FEATURE_NOLOGIN is not set -# CONFIG_FEATURE_SECURETTY is not set -# CONFIG_PASSWD is not set -# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set -# CONFIG_SU is not set -# CONFIG_FEATURE_SU_SYSLOG is not set -# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set -# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set -# CONFIG_SULOGIN is not set -# CONFIG_VLOCK is not set - -# -# Linux Ext2 FS Progs -# -# CONFIG_CHATTR is not set -CONFIG_FSCK=y -# CONFIG_LSATTR is not set -# CONFIG_TUNE2FS is not set - -# -# Linux Module Utilities -# -# CONFIG_MODPROBE_SMALL is not set -# CONFIG_DEPMOD is not set -# CONFIG_INSMOD is not set -# CONFIG_LSMOD is not set -# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set -# CONFIG_MODINFO is not set -# CONFIG_MODPROBE is not set -# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set -# CONFIG_RMMOD is not set - -# -# Options common to multiple modutils -# -# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set -# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set -# CONFIG_FEATURE_2_4_MODULES is not set -# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set -# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set -# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set -# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set -# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set -# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set -# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set -# CONFIG_FEATURE_MODUTILS_ALIAS is not set -# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set -CONFIG_DEFAULT_MODULES_DIR="" -CONFIG_DEFAULT_DEPMOD_FILE="" - -# -# Linux System Utilities -# -# CONFIG_ACPID is not set -# CONFIG_FEATURE_ACPID_COMPAT is not set -# CONFIG_BLKDISCARD is not set -# CONFIG_BLKID is not set -# CONFIG_FEATURE_BLKID_TYPE is not set -# CONFIG_BLOCKDEV is not set -# CONFIG_CAL is not set -# CONFIG_CHRT is not set -# CONFIG_DMESG is not set -# CONFIG_FEATURE_DMESG_PRETTY is not set -# CONFIG_EJECT is not set -# CONFIG_FEATURE_EJECT_SCSI is not set -# CONFIG_FALLOCATE is not set -# CONFIG_FATATTR is not set -# CONFIG_FBSET is not set -# CONFIG_FEATURE_FBSET_FANCY is not set -# CONFIG_FEATURE_FBSET_READMODE is not set -# CONFIG_FDFORMAT is not set -# CONFIG_FDISK is not set -# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set -# CONFIG_FEATURE_FDISK_WRITABLE is not set -# CONFIG_FEATURE_AIX_LABEL is not set -# CONFIG_FEATURE_SGI_LABEL is not set -# CONFIG_FEATURE_SUN_LABEL is not set -# CONFIG_FEATURE_OSF_LABEL is not set -# CONFIG_FEATURE_GPT_LABEL is not set -# CONFIG_FEATURE_FDISK_ADVANCED is not set -# CONFIG_FINDFS is not set -# CONFIG_FLOCK is not set -# CONFIG_FDFLUSH is not set -# CONFIG_FREERAMDISK is not set -# CONFIG_FSCK_MINIX is not set -CONFIG_FSFREEZE=y -CONFIG_FSTRIM=y -CONFIG_GETOPT=y -CONFIG_FEATURE_GETOPT_LONG=y -CONFIG_HEXDUMP=y -# CONFIG_FEATURE_HEXDUMP_REVERSE is not set -# CONFIG_HD is not set -CONFIG_XXD=y -# CONFIG_HWCLOCK is not set -# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set -# CONFIG_IONICE is not set -# CONFIG_IPCRM is not set -# CONFIG_IPCS is not set -# CONFIG_LAST is not set -# CONFIG_FEATURE_LAST_FANCY is not set -CONFIG_LOSETUP=y -# CONFIG_LSPCI is not set -# CONFIG_LSUSB is not set -# CONFIG_MDEV is not set -# CONFIG_FEATURE_MDEV_CONF is not set -# CONFIG_FEATURE_MDEV_RENAME is not set -# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set -# CONFIG_FEATURE_MDEV_EXEC is not set -# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set -# CONFIG_FEATURE_MDEV_DAEMON is not set -# CONFIG_MESG is not set -# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set -CONFIG_MKE2FS=y -# CONFIG_MKFS_EXT2 is not set -# CONFIG_MKFS_MINIX is not set -# CONFIG_FEATURE_MINIX2 is not set -# CONFIG_MKFS_REISER is not set -# CONFIG_MKDOSFS is not set -# CONFIG_MKFS_VFAT is not set -# CONFIG_MKSWAP is not set -# CONFIG_FEATURE_MKSWAP_UUID is not set -# CONFIG_MORE is not set -# CONFIG_MOUNT is not set -# CONFIG_FEATURE_MOUNT_FAKE is not set -# CONFIG_FEATURE_MOUNT_VERBOSE is not set -# CONFIG_FEATURE_MOUNT_HELPERS is not set -# CONFIG_FEATURE_MOUNT_LABEL is not set -# CONFIG_FEATURE_MOUNT_NFS is not set -# CONFIG_FEATURE_MOUNT_CIFS is not set -# CONFIG_FEATURE_MOUNT_FLAGS is not set -# CONFIG_FEATURE_MOUNT_FSTAB is not set -# CONFIG_FEATURE_MOUNT_OTHERTAB is not set -# CONFIG_MOUNTPOINT is not set -CONFIG_NOLOGIN=y -CONFIG_NOLOGIN_DEPENDENCIES=y -# CONFIG_NSENTER is not set -CONFIG_PIVOT_ROOT=y -# CONFIG_RDATE is not set -# CONFIG_RDEV is not set -# CONFIG_READPROFILE is not set -# CONFIG_RENICE is not set -# CONFIG_REV is not set -# CONFIG_RTCWAKE is not set -# CONFIG_SCRIPT is not set -# CONFIG_SCRIPTREPLAY is not set -# CONFIG_SETARCH is not set -# CONFIG_LINUX32 is not set -# CONFIG_LINUX64 is not set -# CONFIG_SETPRIV is not set -# CONFIG_FEATURE_SETPRIV_DUMP is not set -# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set -# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set -# CONFIG_SETSID is not set -# CONFIG_SWAPON is not set -# CONFIG_FEATURE_SWAPON_DISCARD is not set -# CONFIG_FEATURE_SWAPON_PRI is not set -# CONFIG_SWAPOFF is not set -# CONFIG_FEATURE_SWAPONOFF_LABEL is not set -CONFIG_SWITCH_ROOT=y -# CONFIG_TASKSET is not set -# CONFIG_FEATURE_TASKSET_FANCY is not set -# CONFIG_UEVENT is not set -# CONFIG_UMOUNT is not set -# CONFIG_FEATURE_UMOUNT_ALL is not set -# CONFIG_UNSHARE is not set -# CONFIG_WALL is not set -# CONFIG_FEATURE_MOUNT_LOOP is not set -# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set -# CONFIG_FEATURE_MTAB_SUPPORT is not set -# CONFIG_VOLUMEID is not set -# CONFIG_FEATURE_VOLUMEID_BCACHE is not set -# CONFIG_FEATURE_VOLUMEID_BTRFS is not set -# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set -# CONFIG_FEATURE_VOLUMEID_EXFAT is not set -# CONFIG_FEATURE_VOLUMEID_EXT is not set -# CONFIG_FEATURE_VOLUMEID_F2FS is not set -# CONFIG_FEATURE_VOLUMEID_FAT is not set -# CONFIG_FEATURE_VOLUMEID_HFS is not set -# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set -# CONFIG_FEATURE_VOLUMEID_JFS is not set -# CONFIG_FEATURE_VOLUMEID_LFS is not set -# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set -# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set -# CONFIG_FEATURE_VOLUMEID_LUKS is not set -# CONFIG_FEATURE_VOLUMEID_MINIX is not set -# CONFIG_FEATURE_VOLUMEID_NILFS is not set -# CONFIG_FEATURE_VOLUMEID_NTFS is not set -# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set -# CONFIG_FEATURE_VOLUMEID_REISERFS is not set -# CONFIG_FEATURE_VOLUMEID_ROMFS is not set -# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set -# CONFIG_FEATURE_VOLUMEID_SYSV is not set -# CONFIG_FEATURE_VOLUMEID_UBIFS is not set -# CONFIG_FEATURE_VOLUMEID_UDF is not set -# CONFIG_FEATURE_VOLUMEID_XFS is not set - -# -# Miscellaneous Utilities -# -# CONFIG_ADJTIMEX is not set -# CONFIG_BBCONFIG is not set -# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set -CONFIG_BC=y -# CONFIG_DC is not set -CONFIG_FEATURE_DC_BIG=y -# CONFIG_FEATURE_DC_LIBM is not set -CONFIG_FEATURE_BC_INTERACTIVE=y -CONFIG_FEATURE_BC_LONG_OPTIONS=y -# CONFIG_BEEP is not set -CONFIG_FEATURE_BEEP_FREQ=0 -CONFIG_FEATURE_BEEP_LENGTH_MS=0 -# CONFIG_CHAT is not set -# CONFIG_FEATURE_CHAT_NOFAIL is not set -# CONFIG_FEATURE_CHAT_TTY_HIFI is not set -# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set -# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set -# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set -# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set -# CONFIG_FEATURE_CHAT_CLR_ABORT is not set -# CONFIG_CONSPY is not set -# CONFIG_CROND is not set -# CONFIG_FEATURE_CROND_D is not set -# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set -# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set -CONFIG_FEATURE_CROND_DIR="" -# CONFIG_CRONTAB is not set -# CONFIG_DEVFSD is not set -# CONFIG_DEVFSD_MODLOAD is not set -# CONFIG_DEVFSD_FG_NP is not set -# CONFIG_DEVFSD_VERBOSE is not set -# CONFIG_FEATURE_DEVFS is not set -# CONFIG_DEVMEM is not set -# CONFIG_FBSPLASH is not set -# CONFIG_FLASHCP is not set -# CONFIG_FLASH_ERASEALL is not set -# CONFIG_FLASH_LOCK is not set -# CONFIG_FLASH_UNLOCK is not set -# CONFIG_HDPARM is not set -# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set -# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set -# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set -# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set -# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set -# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set -CONFIG_HEXEDIT=y -# CONFIG_I2CGET is not set -# CONFIG_I2CSET is not set -# CONFIG_I2CDUMP is not set -# CONFIG_I2CDETECT is not set -# CONFIG_I2CTRANSFER is not set -# CONFIG_INOTIFYD is not set -CONFIG_LESS=y -CONFIG_FEATURE_LESS_MAXLINES=9999999 -CONFIG_FEATURE_LESS_BRACKETS=y -CONFIG_FEATURE_LESS_FLAGS=y -CONFIG_FEATURE_LESS_TRUNCATE=y -# CONFIG_FEATURE_LESS_MARKS is not set -CONFIG_FEATURE_LESS_REGEXP=y -# CONFIG_FEATURE_LESS_WINCH is not set -# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set -# CONFIG_FEATURE_LESS_DASHCMD is not set -# CONFIG_FEATURE_LESS_LINENUMS is not set -# CONFIG_FEATURE_LESS_RAW is not set -# CONFIG_FEATURE_LESS_ENV is not set -# CONFIG_LSSCSI is not set -# CONFIG_MAKEDEVS is not set -# CONFIG_FEATURE_MAKEDEVS_LEAF is not set -# CONFIG_FEATURE_MAKEDEVS_TABLE is not set -# CONFIG_MAN is not set -# CONFIG_MICROCOM is not set -# CONFIG_MT is not set -# CONFIG_NANDWRITE is not set -# CONFIG_NANDDUMP is not set -CONFIG_PARTPROBE=y -# CONFIG_RAIDAUTORUN is not set -# CONFIG_READAHEAD is not set -# CONFIG_RFKILL is not set -CONFIG_RUNLEVEL=y -# CONFIG_RX is not set -CONFIG_SETFATTR=y -# CONFIG_SETSERIAL is not set -# CONFIG_STRINGS is not set -# CONFIG_TIME is not set -CONFIG_TS=y -# CONFIG_TTYSIZE is not set -# CONFIG_UBIRENAME is not set -# CONFIG_UBIATTACH is not set -# CONFIG_UBIDETACH is not set -# CONFIG_UBIMKVOL is not set -# CONFIG_UBIRMVOL is not set -# CONFIG_UBIRSVOL is not set -# CONFIG_UBIUPDATEVOL is not set -# CONFIG_VOLNAME is not set -# CONFIG_WATCHDOG is not set - -# -# Networking Utilities -# -# CONFIG_FEATURE_IPV6 is not set -# CONFIG_FEATURE_UNIX_LOCAL is not set -# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set -# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set -# CONFIG_FEATURE_TLS_SHA1 is not set -# CONFIG_ARP is not set -# CONFIG_ARPING is not set -# CONFIG_BRCTL is not set -# CONFIG_FEATURE_BRCTL_FANCY is not set -# CONFIG_FEATURE_BRCTL_SHOW is not set -# CONFIG_DNSD is not set -# CONFIG_ETHER_WAKE is not set -# CONFIG_FTPD is not set -# CONFIG_FEATURE_FTPD_WRITE is not set -# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set -# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set -# CONFIG_FTPGET is not set -# CONFIG_FTPPUT is not set -# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set -# CONFIG_HOSTNAME is not set -# CONFIG_DNSDOMAINNAME is not set -# CONFIG_HTTPD is not set -# CONFIG_FEATURE_HTTPD_RANGES is not set -# CONFIG_FEATURE_HTTPD_SETUID is not set -# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set -# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set -# CONFIG_FEATURE_HTTPD_CGI is not set -# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set -# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set -# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set -# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set -# CONFIG_FEATURE_HTTPD_PROXY is not set -# CONFIG_FEATURE_HTTPD_GZIP is not set -# CONFIG_IFCONFIG is not set -# CONFIG_FEATURE_IFCONFIG_STATUS is not set -# CONFIG_FEATURE_IFCONFIG_SLIP is not set -# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set -# CONFIG_FEATURE_IFCONFIG_HW is not set -# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set -# CONFIG_IFENSLAVE is not set -# CONFIG_IFPLUGD is not set -# CONFIG_IFUP is not set -# CONFIG_IFDOWN is not set -CONFIG_IFUPDOWN_IFSTATE_PATH="" -# CONFIG_FEATURE_IFUPDOWN_IP is not set -# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set -# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set -# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set -# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set -# CONFIG_INETD is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set -# CONFIG_FEATURE_INETD_RPC is not set -# CONFIG_IP is not set -# CONFIG_IPADDR is not set -# CONFIG_IPLINK is not set -# CONFIG_IPROUTE is not set -# CONFIG_IPTUNNEL is not set -# CONFIG_IPRULE is not set -# CONFIG_IPNEIGH is not set -# CONFIG_FEATURE_IP_ADDRESS is not set -# CONFIG_FEATURE_IP_LINK is not set -# CONFIG_FEATURE_IP_ROUTE is not set -CONFIG_FEATURE_IP_ROUTE_DIR="" -# CONFIG_FEATURE_IP_TUNNEL is not set -# CONFIG_FEATURE_IP_RULE is not set -# CONFIG_FEATURE_IP_NEIGH is not set -# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set -# CONFIG_IPCALC is not set -# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set -# CONFIG_FEATURE_IPCALC_FANCY is not set -# CONFIG_FAKEIDENTD is not set -# CONFIG_NAMEIF is not set -# CONFIG_FEATURE_NAMEIF_EXTENDED is not set -# CONFIG_NBDCLIENT is not set -# CONFIG_NC is not set -# CONFIG_NETCAT is not set -# CONFIG_NC_SERVER is not set -# CONFIG_NC_EXTRA is not set -# CONFIG_NC_110_COMPAT is not set -# CONFIG_NETSTAT is not set -# CONFIG_FEATURE_NETSTAT_WIDE is not set -# CONFIG_FEATURE_NETSTAT_PRG is not set -# CONFIG_NSLOOKUP is not set -# CONFIG_FEATURE_NSLOOKUP_BIG is not set -# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set -# CONFIG_NTPD is not set -# CONFIG_FEATURE_NTPD_SERVER is not set -# CONFIG_FEATURE_NTPD_CONF is not set -# CONFIG_FEATURE_NTP_AUTH is not set -# CONFIG_PING is not set -# CONFIG_PING6 is not set -# CONFIG_FEATURE_FANCY_PING is not set -# CONFIG_PSCAN is not set -# CONFIG_ROUTE is not set -# CONFIG_SLATTACH is not set -# CONFIG_SSL_CLIENT is not set -# CONFIG_TC is not set -# CONFIG_FEATURE_TC_INGRESS is not set -# CONFIG_TCPSVD is not set -# CONFIG_UDPSVD is not set -# CONFIG_TELNET is not set -# CONFIG_FEATURE_TELNET_TTYPE is not set -# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set -# CONFIG_FEATURE_TELNET_WIDTH is not set -# CONFIG_TELNETD is not set -# CONFIG_FEATURE_TELNETD_STANDALONE is not set -# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set -# CONFIG_TFTP is not set -# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set -# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set -# CONFIG_TFTPD is not set -# CONFIG_FEATURE_TFTP_GET is not set -# CONFIG_FEATURE_TFTP_PUT is not set -# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set -# CONFIG_TFTP_DEBUG is not set -# CONFIG_TLS is not set -# CONFIG_TRACEROUTE is not set -# CONFIG_TRACEROUTE6 is not set -# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set -# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set -# CONFIG_TUNCTL is not set -# CONFIG_FEATURE_TUNCTL_UG is not set -# CONFIG_VCONFIG is not set -# CONFIG_WGET is not set -# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set -# CONFIG_FEATURE_WGET_STATUSBAR is not set -# CONFIG_FEATURE_WGET_AUTHENTICATION is not set -# CONFIG_FEATURE_WGET_TIMEOUT is not set -# CONFIG_FEATURE_WGET_HTTPS is not set -# CONFIG_FEATURE_WGET_OPENSSL is not set -# CONFIG_WHOIS is not set -# CONFIG_ZCIP is not set -# CONFIG_UDHCPD is not set -# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set -# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set -CONFIG_DHCPD_LEASES_FILE="" -# CONFIG_DUMPLEASES is not set -# CONFIG_DHCPRELAY is not set -# CONFIG_UDHCPC is not set -# CONFIG_FEATURE_UDHCPC_ARPING is not set -# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set -CONFIG_UDHCPC_DEFAULT_SCRIPT="" -# CONFIG_UDHCPC6 is not set -# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set -# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set -# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set -# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set -# CONFIG_FEATURE_UDHCP_PORT is not set -CONFIG_UDHCP_DEBUG=0 -CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 -# CONFIG_FEATURE_UDHCP_RFC3397 is not set -# CONFIG_FEATURE_UDHCP_8021Q is not set -CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" - -# -# Print Utilities -# -# CONFIG_LPD is not set -# CONFIG_LPR is not set -# CONFIG_LPQ is not set - -# -# Mail Utilities -# -# CONFIG_MAKEMIME is not set -# CONFIG_POPMAILDIR is not set -# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set -# CONFIG_REFORMIME is not set -# CONFIG_FEATURE_REFORMIME_COMPAT is not set -# CONFIG_SENDMAIL is not set -CONFIG_FEATURE_MIME_CHARSET="" - -# -# Process Utilities -# -CONFIG_FREE=y -# CONFIG_FUSER is not set -# CONFIG_IOSTAT is not set -CONFIG_KILL=y -CONFIG_KILLALL=y -CONFIG_KILLALL5=y -CONFIG_LSOF=y -# CONFIG_MPSTAT is not set -# CONFIG_NMETER is not set -# CONFIG_PGREP is not set -# CONFIG_PKILL is not set -CONFIG_PIDOF=y -CONFIG_FEATURE_PIDOF_SINGLE=y -CONFIG_FEATURE_PIDOF_OMIT=y -# CONFIG_PMAP is not set -# CONFIG_POWERTOP is not set -# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set -CONFIG_PS=y -CONFIG_FEATURE_PS_WIDE=y -CONFIG_FEATURE_PS_LONG=y -# CONFIG_FEATURE_PS_TIME is not set -# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set -# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set -# CONFIG_PSTREE is not set -# CONFIG_PWDX is not set -# CONFIG_SMEMCAP is not set -CONFIG_BB_SYSCTL=y -# CONFIG_TOP is not set -# CONFIG_FEATURE_TOP_INTERACTIVE is not set -# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set -# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set -# CONFIG_FEATURE_TOP_SMP_CPU is not set -# CONFIG_FEATURE_TOP_DECIMALS is not set -# CONFIG_FEATURE_TOP_SMP_PROCESS is not set -# CONFIG_FEATURE_TOPMEM is not set -# CONFIG_UPTIME is not set -# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set -# CONFIG_WATCH is not set -# CONFIG_FEATURE_SHOW_THREADS is not set - -# -# Runit Utilities -# -# CONFIG_CHPST is not set -# CONFIG_SETUIDGID is not set -# CONFIG_ENVUIDGID is not set -# CONFIG_ENVDIR is not set -# CONFIG_SOFTLIMIT is not set -# CONFIG_RUNSV is not set -# CONFIG_RUNSVDIR is not set -# CONFIG_FEATURE_RUNSVDIR_LOG is not set -# CONFIG_SV is not set -CONFIG_SV_DEFAULT_SERVICE_DIR="" -# CONFIG_SVC is not set -# CONFIG_SVOK is not set -# CONFIG_SVLOGD is not set -# CONFIG_CHCON is not set -# CONFIG_GETENFORCE is not set -# CONFIG_GETSEBOOL is not set -# CONFIG_LOAD_POLICY is not set -# CONFIG_MATCHPATHCON is not set -# CONFIG_RUNCON is not set -# CONFIG_SELINUXENABLED is not set -# CONFIG_SESTATUS is not set -# CONFIG_SETENFORCE is not set -# CONFIG_SETFILES is not set -# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set -# CONFIG_RESTORECON is not set -# CONFIG_SETSEBOOL is not set - -# -# Shells -# -CONFIG_SH_IS_ASH=y -# CONFIG_SH_IS_HUSH is not set -# CONFIG_SH_IS_NONE is not set -# CONFIG_BASH_IS_ASH is not set -# CONFIG_BASH_IS_HUSH is not set -CONFIG_BASH_IS_NONE=y -CONFIG_ASH=y -CONFIG_ASH_OPTIMIZE_FOR_SIZE=y -CONFIG_ASH_INTERNAL_GLOB=y -CONFIG_ASH_BASH_COMPAT=y -# CONFIG_ASH_BASH_SOURCE_CURDIR is not set -CONFIG_ASH_BASH_NOT_FOUND_HOOK=y -CONFIG_ASH_JOB_CONTROL=y -CONFIG_ASH_ALIAS=y -CONFIG_ASH_RANDOM_SUPPORT=y -CONFIG_ASH_EXPAND_PRMT=y -CONFIG_ASH_IDLE_TIMEOUT=y -# CONFIG_ASH_MAIL is not set -CONFIG_ASH_ECHO=y -CONFIG_ASH_PRINTF=y -CONFIG_ASH_TEST=y -CONFIG_ASH_HELP=y -CONFIG_ASH_GETOPTS=y -CONFIG_ASH_CMDCMD=y -# CONFIG_CTTYHACK is not set -# CONFIG_HUSH is not set -# CONFIG_HUSH_BASH_COMPAT is not set -# CONFIG_HUSH_BRACE_EXPANSION is not set -# CONFIG_HUSH_LINENO_VAR is not set -# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set -# CONFIG_HUSH_INTERACTIVE is not set -# CONFIG_HUSH_SAVEHISTORY is not set -# CONFIG_HUSH_JOB is not set -# CONFIG_HUSH_TICK is not set -# CONFIG_HUSH_IF is not set -# CONFIG_HUSH_LOOPS is not set -# CONFIG_HUSH_CASE is not set -# CONFIG_HUSH_FUNCTIONS is not set -# CONFIG_HUSH_LOCAL is not set -# CONFIG_HUSH_RANDOM_SUPPORT is not set -# CONFIG_HUSH_MODE_X is not set -# CONFIG_HUSH_ECHO is not set -# CONFIG_HUSH_PRINTF is not set -# CONFIG_HUSH_TEST is not set -# CONFIG_HUSH_HELP is not set -# CONFIG_HUSH_EXPORT is not set -# CONFIG_HUSH_EXPORT_N is not set -# CONFIG_HUSH_READONLY is not set -# CONFIG_HUSH_KILL is not set -# CONFIG_HUSH_WAIT is not set -# CONFIG_HUSH_COMMAND is not set -# CONFIG_HUSH_TRAP is not set -# CONFIG_HUSH_TYPE is not set -# CONFIG_HUSH_TIMES is not set -# CONFIG_HUSH_READ is not set -# CONFIG_HUSH_SET is not set -# CONFIG_HUSH_UNSET is not set -# CONFIG_HUSH_ULIMIT is not set -# CONFIG_HUSH_UMASK is not set -# CONFIG_HUSH_GETOPTS is not set -# CONFIG_HUSH_MEMLEAK is not set - -# -# Options common to all shells -# -CONFIG_FEATURE_SH_MATH=y -CONFIG_FEATURE_SH_MATH_64=y -CONFIG_FEATURE_SH_MATH_BASE=y -CONFIG_FEATURE_SH_EXTRA_QUIET=y -# CONFIG_FEATURE_SH_STANDALONE is not set -# CONFIG_FEATURE_SH_NOFORK is not set -CONFIG_FEATURE_SH_READ_FRAC=y -# CONFIG_FEATURE_SH_HISTFILESIZE is not set -CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS=y - -# -# System Logging Utilities -# -# CONFIG_KLOGD is not set -# CONFIG_FEATURE_KLOGD_KLOGCTL is not set -# CONFIG_LOGGER is not set -# CONFIG_LOGREAD is not set -# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set -# CONFIG_SYSLOGD is not set -# CONFIG_FEATURE_ROTATE_LOGFILE is not set -# CONFIG_FEATURE_REMOTE_LOG is not set -# CONFIG_FEATURE_SYSLOGD_DUP is not set -# CONFIG_FEATURE_SYSLOGD_CFG is not set -CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 -# CONFIG_FEATURE_IPC_SYSLOG is not set -CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 -# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/board/myna-player-odyssey/configs/linux.config b/board/myna-player-odyssey/configs/linux.config index 6568766..7338ee4 100644 --- a/board/myna-player-odyssey/configs/linux.config +++ b/board/myna-player-odyssey/configs/linux.config @@ -26,8 +26,8 @@ CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_CHECKPOINT_RESTORE=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="${BR_BINARIES_DIR}/rootfs.cpio" +CONFIG_BLK_DEV_INITRD=n +CONFIG_INITRAMFS_SOURCE="" # CONFIG_RD_GZIP is not set # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set diff --git a/board/myna-player-odyssey/initramfs_overlay/etc/fstab b/board/myna-player-odyssey/initramfs_overlay/etc/fstab deleted file mode 100644 index e69de29..0000000 --- a/board/myna-player-odyssey/initramfs_overlay/etc/fstab +++ /dev/null diff --git a/board/myna-player-odyssey/initramfs_overlay/etc/group b/board/myna-player-odyssey/initramfs_overlay/etc/group deleted file mode 100644 index 18acc30..0000000 --- a/board/myna-player-odyssey/initramfs_overlay/etc/group +++ /dev/null @@ -1 +0,0 @@ -root:x:0:root diff --git a/board/myna-player-odyssey/initramfs_overlay/etc/initrd-release b/board/myna-player-odyssey/initramfs_overlay/etc/initrd-release deleted file mode 100644 index e69de29..0000000 --- a/board/myna-player-odyssey/initramfs_overlay/etc/initrd-release +++ /dev/null diff --git a/board/myna-player-odyssey/initramfs_overlay/etc/passwd b/board/myna-player-odyssey/initramfs_overlay/etc/passwd deleted file mode 100644 index 5183638..0000000 --- a/board/myna-player-odyssey/initramfs_overlay/etc/passwd +++ /dev/null @@ -1 +0,0 @@ -root:x:0:0:root:/:/bin/sh diff --git a/board/myna-player-odyssey/initramfs_overlay/etc/shadow b/board/myna-player-odyssey/initramfs_overlay/etc/shadow deleted file mode 100644 index 6a17be6..0000000 --- a/board/myna-player-odyssey/initramfs_overlay/etc/shadow +++ /dev/null @@ -1 +0,0 @@ -root:::::::: diff --git a/board/myna-player-odyssey/initramfs_overlay/etc/systemd/system/systemd-udevd.service.d/resolve-names.conf b/board/myna-player-odyssey/initramfs_overlay/etc/systemd/system/systemd-udevd.service.d/resolve-names.conf deleted file mode 100644 index 272dc59..0000000 --- a/board/myna-player-odyssey/initramfs_overlay/etc/systemd/system/systemd-udevd.service.d/resolve-names.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Service] -ExecStart= -ExecStart=/usr/lib/systemd/systemd-udevd --resolve-names=never diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0001-fdts-stm32mp157ca-dk1-Use-STPMIC-on-I2C2-and-eMMC-on.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0001-fdts-stm32mp157ca-dk1-Use-STPMIC-on-I2C2-and-eMMC-on.patch deleted file mode 100644 index a67ecd6..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0001-fdts-stm32mp157ca-dk1-Use-STPMIC-on-I2C2-and-eMMC-on.patch +++ /dev/null @@ -1,90 +0,0 @@ -From ce8f8385e099b5dfee521d58bba40771c072b0df Mon Sep 17 00:00:00 2001 -From: Jookia -Date: Tue, 28 Jul 2020 14:13:17 +1000 -Subject: [PATCH 1/7] fdts: stm32mp157ca-dk1: Use STPMIC on I2C2 and eMMC on - SDMMC2 - -Quick hack to get things working on the Seeed Odyssey board. ---- - fdts/stm32mp157-pinctrl.dtsi | 10 ++++++++++ - fdts/stm32mp157a-dk1.dts | 8 ++++---- - fdts/stm32mp157c.dtsi | 14 ++++++++++++++ - 3 files changed, 28 insertions(+), 4 deletions(-) - -diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi -index 8e480b2c1..4b746b225 100644 ---- a/fdts/stm32mp157-pinctrl.dtsi -+++ b/fdts/stm32mp157-pinctrl.dtsi -@@ -214,6 +214,16 @@ - }; - }; - -+ i2c2_pins_a: i2c2-0 { -+ pins { -+ pinmux = , /* I2C2_SCL */ -+ ; /* I2C2_SDA */ -+ bias-disable; -+ drive-open-drain; -+ slew-rate = <0>; -+ }; -+ }; -+ - sdmmc2_b4_pins_a: sdmmc2-b4-0 { - pins1 { - pinmux = , /* SDMMC2_D0 */ -diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts -index 4ea83f7cd..78681b0ba 100644 ---- a/fdts/stm32mp157a-dk1.dts -+++ b/fdts/stm32mp157a-dk1.dts -@@ -29,9 +29,9 @@ - st,digbypass; - }; - --&i2c4 { -+&i2c2 { - pinctrl-names = "default"; -- pinctrl-0 = <&i2c4_pins_a>; -+ pinctrl-0 = <&i2c2_pins_a>; - i2c-scl-rising-time-ns = <185>; - i2c-scl-falling-time-ns = <20>; - status = "okay"; -@@ -162,9 +162,9 @@ - status = "okay"; - }; - --&sdmmc1 { -+&sdmmc2 { - pinctrl-names = "default"; -- pinctrl-0 = <&sdmmc1_b4_pins_a>; -+ pinctrl-0 = <&sdmmc2_b4_pins_a>; - broken-cd; - st,neg-edge; - bus-width = <4>; -diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi -index 0942a91c2..faa409f2d 100644 ---- a/fdts/stm32mp157c.dtsi -+++ b/fdts/stm32mp157c.dtsi -@@ -312,6 +312,20 @@ - status = "disabled"; - }; - -+ -+ i2c2: i2c@40013000 { -+ compatible = "st,stm32f7-i2c"; -+ reg = <0x40013000 0x400>; -+ interrupt-names = "event", "error"; -+ interrupts = , -+ ; -+ clocks = <&rcc I2C2_K>; -+ resets = <&rcc I2C2_R>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ - i2c4: i2c@5c002000 { - compatible = "st,stm32f7-i2c"; - reg = <0x5c002000 0x400>; --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0002-arch-rename-CNTBaseN-register-offsets-defines.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0002-arch-rename-CNTBaseN-register-offsets-defines.patch deleted file mode 100644 index 269cda7..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0002-arch-rename-CNTBaseN-register-offsets-defines.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 3a29660ebc69c11fc841a662e8692e59c45eda10 Mon Sep 17 00:00:00 2001 -From: Yann Gautier -Date: Tue, 21 May 2019 18:32:14 +0200 -Subject: [PATCH 2/7] arch: rename CNTBaseN register offsets defines - -The CNTFRQ already has a CNTBASEN_ prefix. -To be able to use CNTP_CTL from CP15, the CNTP_CTL define is renamed -CNTBASEN_CNTP_CTL. -To keep consistency, CNTPCT_LO and CNTP_CVAL_LO are also prefixed. - -Change-Id: Ie328daa694a708130ee369218b57c0f4b08f7f44 -Signed-off-by: Yann Gautier ---- - include/arch/aarch32/arch.h | 6 +++--- - include/arch/aarch64/arch.h | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h -index 20175481f..047770e4f 100644 ---- a/include/arch/aarch32/arch.h -+++ b/include/arch/aarch32/arch.h -@@ -457,13 +457,13 @@ - * system level implementation of the Generic Timer. - ******************************************************************************/ - /* Physical Count register. */ --#define CNTPCT_LO U(0x0) -+#define CNTBASEN_CNTPCT_LO U(0x0) - /* Counter Frequency register. */ - #define CNTBASEN_CNTFRQ U(0x10) - /* Physical Timer CompareValue register. */ --#define CNTP_CVAL_LO U(0x20) -+#define CNTBASEN_CNTP_CVAL_LO U(0x20) - /* Physical Timer Control register. */ --#define CNTP_CTL U(0x2c) -+#define CNTBASEN_CNTP_CTL U(0x2c) - - /* Physical timer control register bit fields shifts and masks */ - #define CNTP_CTL_ENABLE_SHIFT 0 -diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h -index 3ff2912f1..307dad585 100644 ---- a/include/arch/aarch64/arch.h -+++ b/include/arch/aarch64/arch.h -@@ -670,13 +670,13 @@ - * system level implementation of the Generic Timer. - ******************************************************************************/ - /* Physical Count register. */ --#define CNTPCT_LO U(0x0) -+#define CNTBASEN_CNTPCT_LO U(0x0) - /* Counter Frequency register. */ - #define CNTBASEN_CNTFRQ U(0x10) - /* Physical Timer CompareValue register. */ --#define CNTP_CVAL_LO U(0x20) -+#define CNTBASEN_CNTP_CVAL_LO U(0x20) - /* Physical Timer Control register. */ --#define CNTP_CTL U(0x2c) -+#define CNTBASEN_CNTP_CTL U(0x2c) - - /* PMCR_EL0 definitions */ - #define PMCR_EL0_RESET_VAL U(0x0) --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0003-aarch32-add-virtual-timer-control-support.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0003-aarch32-add-virtual-timer-control-support.patch deleted file mode 100644 index bb79878..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0003-aarch32-add-virtual-timer-control-support.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 7e3d16e5f993271e20136e732cebc78fd90adddb Mon Sep 17 00:00:00 2001 -From: Yann Gautier -Date: Tue, 21 May 2019 18:46:27 +0200 -Subject: [PATCH 3/7] aarch32: add virtual timer control support - -Define virtual timer resources for a platform to be able to control -virtual timers, even if TF-A does not enable them. -This is required for example when the secure world wants to reset -the system. Virtual timers enabled from non-secure world can -jeopardize the reset sequence due to pending interrupts. - -Change-Id: Ieb0ce4819809ae9c4ab11f9244a6cacf9437d6b4 -Signed-off-by: Nicolas Le Bayon -Signed-off-by: Yann Gautier ---- - include/arch/aarch32/arch.h | 3 +++ - include/arch/aarch32/arch_helpers.h | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h -index 047770e4f..edf12873d 100644 ---- a/include/arch/aarch32/arch.h -+++ b/include/arch/aarch32/arch.h -@@ -522,6 +522,9 @@ - #define HSTR p15, 4, c1, c1, 3 - #define CNTHCTL p15, 4, c14, c1, 0 - #define CNTKCTL p15, 0, c14, c1, 0 -+#define CNTP_TVAL p15, 0, c14, c2, 0 -+#define CNTP_CTL p15, 0, c14, c2, 1 -+#define CNTV_CTL p15, 0, c14, c3, 1 - #define VPIDR p15, 4, c0, c0, 0 - #define VMPIDR p15, 4, c0, c0, 5 - #define ISR p15, 0, c12, c1, 0 -diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h -index cbac84b93..b060f855c 100644 ---- a/include/arch/aarch32/arch_helpers.h -+++ b/include/arch/aarch32/arch_helpers.h -@@ -246,6 +246,9 @@ DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64) - DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64) - DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR) - DEFINE_COPROCR_RW_FUNCS(hstr, HSTR) -+DEFINE_COPROCR_RW_FUNCS(cntp_tval, CNTP_TVAL) -+DEFINE_COPROCR_RW_FUNCS(cntp_ctl, CNTP_CTL) -+DEFINE_COPROCR_RW_FUNCS(cntv_ctl, CNTV_CTL) - DEFINE_COPROCR_RW_FUNCS(cnthp_ctl_el2, CNTHP_CTL) - DEFINE_COPROCR_RW_FUNCS(cnthp_tval_el2, CNTHP_TVAL) - DEFINE_COPROCR_RW_FUNCS_64(cnthp_cval_el2, CNTHP_CVAL_64) --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0004-stm32mp1-add-RTC-driver.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0004-stm32mp1-add-RTC-driver.patch deleted file mode 100644 index a9a9dc3..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0004-stm32mp1-add-RTC-driver.patch +++ /dev/null @@ -1,736 +0,0 @@ -From 50302f6ebc885c3788794587203a6a6012d48d04 Mon Sep 17 00:00:00 2001 -From: Yann Gautier -Date: Mon, 13 May 2019 18:37:00 +0200 -Subject: [PATCH 4/7] stm32mp1: add RTC driver - -This driver is responsible to manage STM32MP1 Real Time Clock IP. - -Change-Id: I8bb84cf2a2786be718944d69153f676d57bfbc37 -Signed-off-by: Yann Gautier -Signed-off-by: Nicolas Le Bayon ---- - drivers/st/clk/stm32mp1_clk.c | 37 ++ - drivers/st/rtc/stm32_rtc.c | 488 +++++++++++++++++++++ - include/drivers/st/stm32_rtc.h | 78 ++++ - include/drivers/st/stm32mp1_clk.h | 2 + - plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 1 + - plat/st/stm32mp1/sp_min/sp_min_setup.c | 34 +- - 6 files changed, 632 insertions(+), 8 deletions(-) - create mode 100644 drivers/st/rtc/stm32_rtc.c - create mode 100644 include/drivers/st/stm32_rtc.h - -diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c -index 0cc87cc71..994614f03 100644 ---- a/drivers/st/clk/stm32mp1_clk.c -+++ b/drivers/st/clk/stm32mp1_clk.c -@@ -1572,6 +1572,43 @@ void stm32mp1_stgen_increment(unsigned long long offset_in_ms) - mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); - } - -+/******************************************************************************* -+ * This function determines the number of needed RTC calendar read operations -+ * to get consistent values (1 or 2 depending on clock frequencies). -+ * If APB1 frequency is lower than 7 times the RTC one, the software has to -+ * read the calendar time and date registers twice. -+ * Returns true if read twice is needed, false else. -+ ******************************************************************************/ -+bool stm32mp1_rtc_get_read_twice(void) -+{ -+ unsigned long apb1_freq; -+ uint32_t rtc_freq; -+ uint32_t apb1_div; -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ switch ((mmio_read_32(rcc_base + RCC_BDCR) & -+ RCC_BDCR_RTCSRC_MASK) >> RCC_BDCR_RTCSRC_SHIFT) { -+ case 1: -+ rtc_freq = stm32mp_clk_get_rate(CK_LSE); -+ break; -+ case 2: -+ rtc_freq = stm32mp_clk_get_rate(CK_LSI); -+ break; -+ case 3: -+ rtc_freq = stm32mp_clk_get_rate(CK_HSE); -+ rtc_freq /= (mmio_read_32(rcc_base + RCC_RTCDIVR) & -+ RCC_DIVR_DIV_MASK) + 1U; -+ break; -+ default: -+ panic(); -+ } -+ -+ apb1_div = mmio_read_32(rcc_base + RCC_APB1DIVR) & RCC_APBXDIV_MASK; -+ apb1_freq = stm32mp_clk_get_rate(CK_MCU) >> apb1_div; -+ -+ return apb1_freq < (rtc_freq * 7U); -+} -+ - static void stm32mp1_pkcs_config(uint32_t pkcs) - { - uintptr_t address = stm32mp_rcc_base() + ((pkcs >> 4) & 0xFFFU); -diff --git a/drivers/st/rtc/stm32_rtc.c b/drivers/st/rtc/stm32_rtc.c -new file mode 100644 -index 000000000..eaa6f7508 ---- /dev/null -+++ b/drivers/st/rtc/stm32_rtc.c -@@ -0,0 +1,488 @@ -+/* -+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define RTC_COMPAT "st,stm32mp1-rtc" -+ -+#define RTC_TR_SU_MASK GENMASK(3, 0) -+#define RTC_TR_ST_MASK GENMASK(6, 4) -+#define RTC_TR_ST_SHIFT 4 -+#define RTC_TR_MNU_MASK GENMASK(11, 8) -+#define RTC_TR_MNU_SHIFT 8 -+#define RTC_TR_MNT_MASK GENMASK(14, 12) -+#define RTC_TR_MNT_SHIFT 12 -+#define RTC_TR_HU_MASK GENMASK(19, 16) -+#define RTC_TR_HU_SHIFT 16 -+#define RTC_TR_HT_MASK GENMASK(21, 20) -+#define RTC_TR_HT_SHIFT 20 -+#define RTC_TR_PM BIT(22) -+ -+#define RTC_DR_DU_MASK GENMASK(3, 0) -+#define RTC_DR_DT_MASK GENMASK(5, 4) -+#define RTC_DR_DT_SHIFT 4 -+#define RTC_DR_MU_MASK GENMASK(11, 8) -+#define RTC_DR_MU_SHIFT 8 -+#define RTC_DR_MT BIT(12) -+#define RTC_DR_MT_SHIFT 12 -+#define RTC_DR_WDU_MASK GENMASK(15, 13) -+#define RTC_DR_WDU_SHIFT 13 -+#define RTC_DR_YU_MASK GENMASK(19, 16) -+#define RTC_DR_YU_SHIFT 16 -+#define RTC_DR_YT_MASK GENMASK(23, 20) -+#define RTC_DR_YT_SHIFT 20 -+ -+#define RTC_SSR_SS_MASK GENMASK(15, 0) -+ -+#define RTC_ICSR_ALRAWF BIT(0) -+#define RTC_ICSR_RSF BIT(5) -+ -+#define RTC_PRER_PREDIV_S_MASK GENMASK(14, 0) -+ -+#define RTC_CR_BYPSHAD BIT(5) -+#define RTC_CR_BYPSHAD_SHIFT 5 -+#define RTC_CR_ALRAE BIT(8) -+#define RTC_CR_ALRAIE BIT(12) -+#define RTC_CR_TAMPTS BIT(25) -+ -+#define RTC_SMCR_TS_DPROT BIT(3) -+ -+#define RTC_TSDR_DU_MASK GENMASK(3, 0) -+#define RTC_TSDR_DU_SHIFT 0 -+#define RTC_TSDR_DT_MASK GENMASK(5, 4) -+#define RTC_TSDR_DT_SHIFT 4 -+#define RTC_TSDR_MU_MASK GENMASK(11, 8) -+#define RTC_TSDR_MU_SHIFT 8 -+ -+#define RTC_ALRMAR_DU_SHIFT 24 -+ -+#define RTC_SR_TSF BIT(3) -+#define RTC_SR_TSOVF BIT(4) -+ -+#define RTC_SCR_CTSF BIT(3) -+#define RTC_SCR_CTSOVF BIT(4) -+ -+#define RTC_WPR_KEY1 0xCA -+#define RTC_WPR_KEY2 0x53 -+#define RTC_WPR_KEY_LOCK 0xFF -+ -+static struct dt_node_info rtc_dev; -+ -+static struct spinlock lock; -+ -+void stm32_rtc_regs_lock(void) -+{ -+ if (stm32mp_lock_available()) { -+ spin_lock(&lock); -+ } -+} -+ -+void stm32_rtc_regs_unlock(void) -+{ -+ if (stm32mp_lock_available()) { -+ spin_unlock(&lock); -+ } -+} -+ -+static void stm32_rtc_write_unprotect(void) -+{ -+ mmio_write_32(rtc_dev.base + RTC_WPR, RTC_WPR_KEY1); -+ mmio_write_32(rtc_dev.base + RTC_WPR, RTC_WPR_KEY2); -+} -+ -+static void stm32_rtc_write_protect(void) -+{ -+ mmio_write_32(rtc_dev.base + RTC_WPR, RTC_WPR_KEY_LOCK); -+} -+ -+/******************************************************************************* -+ * This function gets the BYPSHAD bit value of the RTC_CR register. -+ * It will determine if we need to reset RTC_ISCR.RSF after each RTC calendar -+ * read, and also wait for RTC_ISCR.RSF=1 before next read. -+ * Returns true or false depending on the bit value. -+ ******************************************************************************/ -+static bool stm32_rtc_get_bypshad(void) -+{ -+ return ((mmio_read_32(rtc_dev.base + RTC_CR) & RTC_CR_BYPSHAD) >> -+ RTC_CR_BYPSHAD_SHIFT) != 0U; -+} -+ -+/******************************************************************************* -+ * This function reads the RTC calendar register values. -+ * If shadow registers are not bypassed, then a reset/poll is done. -+ ******************************************************************************/ -+static void stm32_rtc_read_calendar(struct stm32_rtc_calendar *calendar) -+{ -+ bool bypshad = stm32_rtc_get_bypshad(); -+ -+ if (!bypshad) { -+ mmio_clrbits_32((uint32_t)(rtc_dev.base + RTC_ICSR), -+ RTC_ICSR_RSF); -+ while ((mmio_read_32(rtc_dev.base + RTC_ICSR) & RTC_ICSR_RSF) != -+ RTC_ICSR_RSF) { -+ ; -+ } -+ } -+ -+ calendar->ssr = mmio_read_32(rtc_dev.base + RTC_SSR); -+ calendar->tr = mmio_read_32(rtc_dev.base + RTC_TR); -+ calendar->dr = mmio_read_32(rtc_dev.base + RTC_DR); -+} -+ -+/******************************************************************************* -+ * This function fill the rtc_time structure based on rtc_calendar register. -+ ******************************************************************************/ -+static void stm32_rtc_get_time(struct stm32_rtc_calendar *cal, -+ struct stm32_rtc_time *tm) -+{ -+ assert(cal != NULL); -+ assert(tm != NULL); -+ -+ tm->hour = (((cal->tr & RTC_TR_HT_MASK) >> RTC_TR_HT_SHIFT) * 10U) + -+ ((cal->tr & RTC_TR_HU_MASK) >> RTC_TR_HU_SHIFT); -+ -+ if ((cal->tr & RTC_TR_PM) != 0U) { -+ tm->hour += 12U; -+ } -+ -+ tm->min = (((cal->tr & RTC_TR_MNT_MASK) >> RTC_TR_MNT_SHIFT) * 10U) + -+ ((cal->tr & RTC_TR_MNU_MASK) >> RTC_TR_MNU_SHIFT); -+ tm->sec = (((cal->tr & RTC_TR_ST_MASK) >> RTC_TR_ST_SHIFT) * 10U) + -+ (cal->tr & RTC_TR_SU_MASK); -+} -+ -+/******************************************************************************* -+ * This function fill the rtc_time structure with the given date register. -+ ******************************************************************************/ -+static void stm32_rtc_get_date(struct stm32_rtc_calendar *cal, -+ struct stm32_rtc_time *tm) -+{ -+ assert(cal != NULL); -+ assert(tm != NULL); -+ -+ tm->wday = (((cal->dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT)); -+ -+ tm->day = (((cal->dr & RTC_DR_DT_MASK) >> RTC_DR_DT_SHIFT) * 10U) + -+ (cal->dr & RTC_DR_DU_MASK); -+ -+ tm->month = (((cal->dr & RTC_DR_MT) >> RTC_DR_MT_SHIFT) * 10U) + -+ ((cal->dr & RTC_DR_MU_MASK) >> RTC_DR_MU_SHIFT); -+ -+ tm->year = (((cal->dr & RTC_DR_YT_MASK) >> RTC_DR_YT_SHIFT) * 10U) + -+ ((cal->dr & RTC_DR_YU_MASK) >> RTC_DR_YU_SHIFT) + 2000U; -+} -+ -+/******************************************************************************* -+ * This function reads the RTC timestamp register values and update time -+ * structure with the corresponding value. -+ ******************************************************************************/ -+static void stm32_rtc_read_timestamp(struct stm32_rtc_time *time) -+{ -+ assert(time != NULL); -+ -+ struct stm32_rtc_calendar cal_tamp; -+ -+ cal_tamp.tr = mmio_read_32(rtc_dev.base + RTC_TSTR); -+ cal_tamp.dr = mmio_read_32(rtc_dev.base + RTC_TSDR); -+ stm32_rtc_get_time(&cal_tamp, time); -+ stm32_rtc_get_date(&cal_tamp, time); -+} -+ -+/******************************************************************************* -+ * This function gets the RTC calendar register values. -+ * It takes into account the need of reading twice or not, depending on -+ * frequencies previously setted, and the bypass or not of the shadow -+ * registers. This service is exposed externally. -+ ******************************************************************************/ -+void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar) -+{ -+ bool read_twice = stm32mp1_rtc_get_read_twice(); -+ -+ stm32_rtc_regs_lock(); -+ stm32mp_clk_enable(rtc_dev.clock); -+ -+ stm32_rtc_read_calendar(calendar); -+ -+ if (read_twice) { -+ uint32_t tr_save = calendar->tr; -+ -+ stm32_rtc_read_calendar(calendar); -+ -+ if (calendar->tr != tr_save) { -+ stm32_rtc_read_calendar(calendar); -+ } -+ } -+ -+ stm32mp_clk_disable(rtc_dev.clock); -+ stm32_rtc_regs_unlock(); -+} -+ -+/******************************************************************************* -+ * This function computes the second fraction in milliseconds. -+ * The returned value is a uint32_t between 0 and 1000. -+ ******************************************************************************/ -+static uint32_t stm32_rtc_get_second_fraction(struct stm32_rtc_calendar *cal) -+{ -+ uint32_t prediv_s = mmio_read_32(rtc_dev.base + RTC_PRER) & -+ RTC_PRER_PREDIV_S_MASK; -+ uint32_t ss = cal->ssr & RTC_SSR_SS_MASK; -+ -+ return ((prediv_s - ss) * 1000U) / (prediv_s + 1U); -+} -+ -+/******************************************************************************* -+ * This function computes the fraction difference between two timestamps. -+ * Here again the returned value is in milliseconds. -+ ******************************************************************************/ -+static unsigned long long stm32_rtc_diff_frac(struct stm32_rtc_calendar *cur, -+ struct stm32_rtc_calendar *ref) -+{ -+ unsigned long long val_r; -+ unsigned long long val_c; -+ -+ val_r = stm32_rtc_get_second_fraction(ref); -+ val_c = stm32_rtc_get_second_fraction(cur); -+ -+ if (val_c >= val_r) { -+ return val_c - val_r; -+ } else { -+ return 1000U - val_r + val_c; -+ } -+} -+ -+/******************************************************************************* -+ * This function computes the time difference between two timestamps. -+ * It includes seconds, minutes and hours. -+ * Here again the returned value is in milliseconds. -+ ******************************************************************************/ -+static unsigned long long stm32_rtc_diff_time(struct stm32_rtc_time *current, -+ struct stm32_rtc_time *ref) -+{ -+ signed long long diff_in_s; -+ signed long long curr_s; -+ signed long long ref_s; -+ -+ curr_s = (signed long long)current->sec + -+ (((signed long long)current->min + -+ (((signed long long)current->hour * 60))) * 60); -+ -+ ref_s = (signed long long)ref->sec + -+ (((signed long long)ref->min + -+ (((signed long long)ref->hour * 60))) * 60); -+ -+ diff_in_s = curr_s - ref_s; -+ if (diff_in_s < 0) { -+ diff_in_s += 24 * 60 * 60; -+ } -+ -+ return (unsigned long long)diff_in_s * 1000U; -+} -+ -+/******************************************************************************* -+ * This function determines if the year is leap or not. -+ * Returned value is true or false. -+ ******************************************************************************/ -+static bool stm32_is_a_leap_year(uint32_t year) -+{ -+ return ((year % 4U) == 0U) && -+ (((year % 100U) != 0U) || ((year % 400U) == 0U)); -+} -+ -+/******************************************************************************* -+ * This function computes the date difference between two timestamps. -+ * It includes days, months, years, with exceptions. -+ * Here again the returned value is in milliseconds. -+ ******************************************************************************/ -+static unsigned long long stm32_rtc_diff_date(struct stm32_rtc_time *current, -+ struct stm32_rtc_time *ref) -+{ -+ uint32_t diff_in_days = 0; -+ uint32_t m; -+ static const uint8_t month_len[NB_MONTHS] = { -+ 31, 28, 31, 30, 31, 30, -+ 31, 31, 30, 31, 30, 31 -+ }; -+ -+ /* Get the number of non-entire month days */ -+ if (current->day >= ref->day) { -+ diff_in_days += current->day - ref->day; -+ } else { -+ diff_in_days += (uint32_t)month_len[ref->month - 1U] - -+ ref->day + current->day; -+ } -+ -+ /* Get the number of entire months, and compute the related days */ -+ if (current->month > (ref->month + 1U)) { -+ for (m = (ref->month + 1U); (m < current->month) && -+ (m < 12U); m++) { -+ diff_in_days += (uint32_t)month_len[m - 1U]; -+ } -+ } -+ -+ if (current->month < (ref->month - 1U)) { -+ for (m = 1U; (m < current->month) && (m < 12U); m++) { -+ diff_in_days += (uint32_t)month_len[m - 1U]; -+ } -+ -+ for (m = (ref->month + 1U); m < 12U; m++) { -+ diff_in_days += (uint32_t)month_len[m - 1U]; -+ } -+ } -+ -+ /* Get complete years */ -+ if (current->year > (ref->year + 1U)) { -+ diff_in_days += (current->year - ref->year - 1U) * 365U; -+ } -+ -+ /* Particular cases: leap years (one day more) */ -+ if (diff_in_days > 0U) { -+ if (current->year == ref->year) { -+ if (stm32_is_a_leap_year(current->year)) { -+ if ((ref->month <= 2U) && -+ (current->month >= 3U) && -+ (current->day <= 28U)) { -+ diff_in_days++; -+ } -+ } -+ } else { -+ uint32_t y; -+ -+ /* Ref year is leap */ -+ if ((stm32_is_a_leap_year(ref->year)) && -+ (ref->month <= 2U) && (ref->day <= 28U)) { -+ diff_in_days++; -+ } -+ -+ /* Current year is leap */ -+ if ((stm32_is_a_leap_year(current->year)) && -+ (current->month >= 3U)) { -+ diff_in_days++; -+ } -+ -+ /* Interleaved years are leap */ -+ for (y = ref->year + 1U; y < current->year; y++) { -+ if (stm32_is_a_leap_year(y)) { -+ diff_in_days++; -+ } -+ } -+ } -+ } -+ -+ return (24ULL * 60U * 60U * 1000U) * (unsigned long long)diff_in_days; -+} -+ -+/******************************************************************************* -+ * This function computes the date difference between two rtc value. -+ * Here again the returned value is in milliseconds. -+ ******************************************************************************/ -+unsigned long long stm32_rtc_diff_calendar(struct stm32_rtc_calendar *cur, -+ struct stm32_rtc_calendar *ref) -+{ -+ unsigned long long diff_in_ms = 0; -+ struct stm32_rtc_time curr_t; -+ struct stm32_rtc_time ref_t; -+ -+ stm32mp_clk_enable(rtc_dev.clock); -+ -+ stm32_rtc_get_date(cur, &curr_t); -+ stm32_rtc_get_date(ref, &ref_t); -+ stm32_rtc_get_time(cur, &curr_t); -+ stm32_rtc_get_time(ref, &ref_t); -+ -+ diff_in_ms += stm32_rtc_diff_frac(cur, ref); -+ diff_in_ms += stm32_rtc_diff_time(&curr_t, &ref_t); -+ diff_in_ms += stm32_rtc_diff_date(&curr_t, &ref_t); -+ -+ stm32mp_clk_disable(rtc_dev.clock); -+ -+ return diff_in_ms; -+} -+ -+/******************************************************************************* -+ * This function fill the RTC timestamp structure. -+ ******************************************************************************/ -+void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts) -+{ -+ stm32_rtc_regs_lock(); -+ stm32mp_clk_enable(rtc_dev.clock); -+ -+ if ((mmio_read_32(rtc_dev.base + RTC_SR) & RTC_SR_TSF) != 0U) { -+ /* Print timestamp for tamper event */ -+ stm32_rtc_read_timestamp(tamp_ts); -+ mmio_setbits_32(rtc_dev.base + RTC_SCR, RTC_SCR_CTSF); -+ if ((mmio_read_32(rtc_dev.base + RTC_SR) & RTC_SR_TSOVF) != -+ 0U) { -+ /* Overflow detected */ -+ mmio_setbits_32(rtc_dev.base + RTC_SCR, RTC_SCR_CTSOVF); -+ } -+ } -+ -+ stm32mp_clk_disable(rtc_dev.clock); -+ stm32_rtc_regs_unlock(); -+} -+ -+/******************************************************************************* -+ * This function enable the timestamp bit for tamper and secure timestamp -+ * access. -+ ******************************************************************************/ -+void stm32_rtc_set_tamper_timestamp(void) -+{ -+ stm32_rtc_regs_lock(); -+ stm32mp_clk_enable(rtc_dev.clock); -+ -+ stm32_rtc_write_unprotect(); -+ -+ /* Enable tamper timestamper */ -+ mmio_setbits_32(rtc_dev.base + RTC_CR, RTC_CR_TAMPTS); -+ -+ /* Secure Timestamp bit */ -+ mmio_clrbits_32(rtc_dev.base + RTC_SMCR, RTC_SMCR_TS_DPROT); -+ -+ stm32_rtc_write_protect(); -+ -+ stm32mp_clk_disable(rtc_dev.clock); -+ stm32_rtc_regs_unlock(); -+} -+ -+/******************************************************************************* -+ * This function return state of tamper timestamp. -+ ******************************************************************************/ -+bool stm32_rtc_is_timestamp_enable(void) -+{ -+ bool ret; -+ -+ stm32mp_clk_enable(rtc_dev.clock); -+ -+ ret = (mmio_read_32(rtc_dev.base + RTC_CR) & RTC_CR_TAMPTS) != 0U; -+ -+ stm32mp_clk_disable(rtc_dev.clock); -+ -+ return ret; -+} -+ -+/******************************************************************************* -+ * RTC initialisation function. -+ ******************************************************************************/ -+int stm32_rtc_init(void) -+{ -+ int node; -+ -+ node = dt_get_node(&rtc_dev, -1, RTC_COMPAT); -+ if (node < 0) { -+ return node; -+ } -+ -+ return 0; -+} -diff --git a/include/drivers/st/stm32_rtc.h b/include/drivers/st/stm32_rtc.h -new file mode 100644 -index 000000000..128dd2d14 ---- /dev/null -+++ b/include/drivers/st/stm32_rtc.h -@@ -0,0 +1,78 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef STM32_RTC_H -+#define STM32_RTC_H -+ -+#include -+ -+#define RTC_TR 0x00U -+#define RTC_DR 0x04U -+#define RTC_SSR 0x08U -+#define RTC_ICSR 0x0CU -+#define RTC_PRER 0x10U -+#define RTC_WUTR 0x14U -+#define RTC_CR 0x18U -+#define RTC_SMCR 0x20U -+#define RTC_WPR 0x24U -+#define RTC_CALR 0x28U -+#define RTC_SHIFTR 0x2CU -+#define RTC_TSTR 0x30U -+#define RTC_TSDR 0x34U -+#define RTC_TSSSR 0x38U -+#define RTC_ALRMAR 0x40U -+#define RTC_ALRMASSR 0x44U -+#define RTC_ALRMBR 0x48U -+#define RTC_ALRMBSSR 0x4CU -+#define RTC_SR 0x50U -+#define RTC_SCR 0x5CU -+#define RTC_OR 0x60U -+ -+struct stm32_rtc_calendar { -+ uint32_t ssr; -+ uint32_t tr; -+ uint32_t dr; -+}; -+ -+enum months { -+ JANUARY = 1, -+ FEBRUARY, -+ MARCH, -+ APRIL, -+ MAY, -+ JUNE, -+ JULY, -+ AUGUST, -+ SEPTEMBER, -+ OCTOBER, -+ NOVEMBER, -+ DECEMBER, -+ NB_MONTHS = 12 -+}; -+ -+struct stm32_rtc_time { -+ uint32_t hour; -+ uint32_t min; -+ uint32_t sec; -+ uint32_t wday; -+ uint32_t day; -+ enum months month; -+ uint32_t year; -+}; -+ -+void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar); -+unsigned long long stm32_rtc_diff_calendar(struct stm32_rtc_calendar *current, -+ struct stm32_rtc_calendar *ref); -+void stm32_rtc_set_tamper_timestamp(void); -+bool stm32_rtc_is_timestamp_enable(void); -+void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts); -+int stm32_rtc_init(void); -+ -+/* SMP protection on RTC registers access */ -+void stm32_rtc_regs_lock(void); -+void stm32_rtc_regs_unlock(void); -+ -+#endif /* STM32_RTC_H */ -diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h -index 1ebd39ff7..81ae5d8ae 100644 ---- a/include/drivers/st/stm32mp1_clk.h -+++ b/include/drivers/st/stm32mp1_clk.h -@@ -53,6 +53,8 @@ static inline void stm32mp1_clk_disable_secure(unsigned long id) - - unsigned int stm32mp1_clk_get_refcount(unsigned long id); - -+bool stm32mp1_rtc_get_read_twice(void); -+ - /* SMP protection on RCC registers access */ - void stm32mp1_clk_rcc_regs_lock(void); - void stm32mp1_clk_rcc_regs_unlock(void); -diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -index 4188cc58a..6c7107ca2 100644 ---- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -@@ -7,6 +7,7 @@ - SP_MIN_WITH_SECURE_FIQ := 1 - - BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ -+ drivers/st/rtc/stm32_rtc.c \ - plat/st/stm32mp1/sp_min/sp_min_setup.c \ - plat/st/stm32mp1/stm32mp1_pm.c \ - plat/st/stm32mp1/stm32mp1_topology.c -diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c -index e10dfbfc0..ff69358e0 100644 ---- a/plat/st/stm32mp1/sp_min/sp_min_setup.c -+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -147,16 +148,11 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, - } - - /******************************************************************************* -- * Initialize the MMU, security and the GIC. -+ * Set security setup in sp_min - ******************************************************************************/ --void sp_min_platform_setup(void) -+static void stm32mp1_sp_min_security_setup(void) - { -- /* Initialize tzc400 after DDR initialization */ -- stm32mp1_security_setup(); -- -- generic_delay_timer_init(); -- -- stm32mp1_gic_init(); -+ int ret; - - /* Unlock ETZPC securable peripherals */ - #define STM32MP1_ETZPC_BASE 0x5C007000U -@@ -168,6 +164,28 @@ void sp_min_platform_setup(void) - set_gpio_secure_cfg(GPIO_BANK_Z, pin, false); - } - -+ /* Init rtc driver */ -+ ret = stm32_rtc_init(); -+ if (ret < 0) { -+ WARN("RTC driver init error %i\n", ret); -+ } -+} -+ -+/******************************************************************************* -+ * Initialize the MMU, security and the GIC. -+ ******************************************************************************/ -+void sp_min_platform_setup(void) -+{ -+ /* Initialize tzc400 after DDR initialization */ -+ stm32mp1_security_setup(); -+ -+ generic_delay_timer_init(); -+ -+ stm32mp1_gic_init(); -+ -+ /* Update security settings */ -+ stm32mp1_sp_min_security_setup(); -+ - if (stm32_iwdg_init() < 0) { - panic(); - } --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0005-stm32mp-add-function-to-protect-access-on-PWR-regist.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0005-stm32mp-add-function-to-protect-access-on-PWR-regist.patch deleted file mode 100644 index 3fc2cef..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0005-stm32mp-add-function-to-protect-access-on-PWR-regist.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 4d4214a8dea31d531df6739e6f74005090018faa Mon Sep 17 00:00:00 2001 -From: Yann Gautier -Date: Wed, 24 Apr 2019 13:38:41 +0200 -Subject: [PATCH 5/7] stm32mp: add function to protect access on PWR registers - -In SMP context, we need to add spinlocks to protect against concurrent -accesses on PWR registers. - -Change-Id: I27cb698ffa085eca7b61b042ce5ccaa1fd2daaf4 -Signed-off-by: Yann Gautier ---- - plat/st/common/include/stm32mp_common.h | 4 ++++ - plat/st/common/stm32mp_common.c | 17 +++++++++++++++++ - 2 files changed, 21 insertions(+) - -diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h -index 4f8567979..052402854 100644 ---- a/plat/st/common/include/stm32mp_common.h -+++ b/plat/st/common/include/stm32mp_common.h -@@ -33,6 +33,10 @@ uintptr_t stm32mp_rcc_base(void); - /* Check MMU status to allow spinlock use */ - bool stm32mp_lock_available(void); - -+/* SMP protection on PWR registers access */ -+void stm32mp_pwr_regs_lock(void); -+void stm32mp_pwr_regs_unlock(void); -+ - /* Get IWDG platform instance ID from peripheral IO memory base address */ - uint32_t stm32_iwdg_get_instance(uintptr_t base); - -diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c -index afa87f487..5e7c74b48 100644 ---- a/plat/st/common/stm32mp_common.c -+++ b/plat/st/common/stm32mp_common.c -@@ -12,8 +12,11 @@ - #include - #include - #include -+#include - #include - -+static struct spinlock lock; -+ - uintptr_t plat_get_ns_image_entrypoint(void) - { - return BL33_BASE; -@@ -96,6 +99,20 @@ bool stm32mp_lock_available(void) - return (read_sctlr() & c_m_bits) == c_m_bits; - } - -+void stm32mp_pwr_regs_lock(void) -+{ -+ if (stm32mp_lock_available()) { -+ spin_lock(&lock); -+ } -+} -+ -+void stm32mp_pwr_regs_unlock(void) -+{ -+ if (stm32mp_lock_available()) { -+ spin_unlock(&lock); -+ } -+} -+ - uintptr_t stm32_get_gpio_bank_base(unsigned int bank) - { - if (bank == GPIO_BANK_Z) { --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0006-ddr-stm32mp1-add-DDR-self-refresh-management.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0006-ddr-stm32mp1-add-DDR-self-refresh-management.patch deleted file mode 100644 index ca1e3c2..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0006-ddr-stm32mp1-add-DDR-self-refresh-management.patch +++ /dev/null @@ -1,801 +0,0 @@ -From 3e5e9e77b190336b040389d0a5e62bfea7e22ae4 Mon Sep 17 00:00:00 2001 -From: Yann Gautier -Date: Wed, 24 Apr 2019 13:40:04 +0200 -Subject: [PATCH 6/7] ddr: stm32mp1: add DDR self-refresh management - -In order to prepare low power use cases, functions are added to manage -the entry or exit of DDR from self-refresh mode. - -Change-Id: I8a1cbc48d613366fca69b4fc6870e53f8b917598 -Signed-off-by: Yann Gautier ---- - drivers/st/ddr/stm32mp1_ddr.c | 134 +++++- - drivers/st/ddr/stm32mp1_ddr_helpers.c | 472 ++++++++++++++++++++++ - include/drivers/st/stm32mp1_ddr.h | 6 +- - include/drivers/st/stm32mp1_ddr_helpers.h | 9 +- - plat/st/common/stm32mp_dt.c | 2 - - plat/st/stm32mp1/stm32mp1_def.h | 3 + - 6 files changed, 619 insertions(+), 7 deletions(-) - -diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c -index 7d89d027e..f5cffd887 100644 ---- a/drivers/st/ddr/stm32mp1_ddr.c -+++ b/drivers/st/ddr/stm32mp1_ddr.c -@@ -29,6 +29,7 @@ struct reg_desc { - - #define INVALID_OFFSET 0xFFU - -+#define TIMESLOT_US_1US 1U - #define TIMEOUT_US_1S 1000000U - - #define DDRCTL_REG(x, y) \ -@@ -698,6 +699,83 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, - stm32mp1_wait_sw_done_ack(ctl); - } - -+static void stm32mp1_refresh_cmd(struct stm32mp1_ddrctl *ctl) -+{ -+ uint32_t dbgstat; -+ -+ do { -+ dbgstat = mmio_read_32((uintptr_t)&ctl->dbgstat); -+ } while ((dbgstat & DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY) != 0U); -+ -+ mmio_setbits_32((uintptr_t)&ctl->dbgcmd, DDRCTRL_DBGCMD_RANK0_REFRESH); -+} -+ -+/* Refresh compensation by forcing refresh command -+ * Rule1: Tref should be always < tREFW ? R x tREBW/8 -+ * Rule2: refcomp = RU(Tref/tREFI) = RU(RxTref/tREFW) -+ */ -+static -+void stm32mp1_refresh_compensation(const struct stm32mp1_ddr_config *config, -+ struct stm32mp1_ddrctl *ctl, -+ uint64_t start) -+{ -+ uint32_t tck_ps; -+ uint64_t time_us, tref, trefi, refcomp, i; -+ -+ time_us = timeout_init_us(0) - start; -+ tck_ps = 1000000000U / config->info.speed; -+ if (tck_ps == 0U) { -+ return; -+ } -+ /* ref = refresh time in tck */ -+ tref = time_us * 1000000U / tck_ps; -+ trefi = ((mmio_read_32((uintptr_t)&ctl->rfshtmg) & -+ DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK) -+ >> DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT) * 32U; -+ if (trefi == 0U) { -+ return; -+ } -+ -+ /* div round up : number of refresh to compensate */ -+ refcomp = (tref + trefi - 1U) / trefi; -+ -+ for (i = 0; i < refcomp; i++) { -+ stm32mp1_refresh_cmd(ctl); -+ } -+} -+ -+static void stm32mp1_self_refresh_zcal(struct ddr_info *priv, uint32_t zdata) -+{ -+ /* sequence for PUBL I/O Data Retention during Power-Down */ -+ -+ /* 10. Override ZQ calibration with previously (pre-retention) -+ * calibrated values. This is done by writing 1 to ZQ0CRN.ZDEN -+ * and the override data to ZQ0CRN.ZDATA. -+ */ -+ mmio_setbits_32((uintptr_t)&priv->phy->zq0cr0, DDRPHYC_ZQ0CRN_ZDEN); -+ -+ mmio_clrsetbits_32((uintptr_t)&priv->phy->zq0cr0, -+ DDRPHYC_ZQ0CRN_ZDATA_MASK, -+ zdata << DDRPHYC_ZQ0CRN_ZDATA_SHIFT); -+ -+ /* 11. De-assert the PHY_top data retention enable signals -+ * (ret_en or ret_en_i/ret_en_n_i). -+ */ -+ mmio_setbits_32((uintptr_t)(priv->pwr) + PWR_CR3, PWR_CR3_DDRSRDIS); -+ mmio_clrbits_32((uintptr_t)(priv->pwr) + PWR_CR3, PWR_CR3_DDRRETEN); -+ -+ /* 12. Remove ZQ calibration override by writing 0 to ZQ0CRN.ZDEN. */ -+ mmio_clrbits_32((uintptr_t)&priv->phy->zq0cr0, DDRPHYC_ZQ0CRN_ZDEN); -+ -+ /* 13. Trigger ZQ calibration by writing 1 to PIR.INIT -+ * and '1' to PIR.ZCAL -+ */ -+ /* 14. Wait for ZQ calibration to finish by polling a 1 status -+ * on PGSR.IDONE. -+ */ -+ stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_ZCAL); -+} -+ - static int board_ddr_power_init(enum ddr_type ddr_type) - { - if (dt_pmic_status() > 0) { -@@ -710,8 +788,9 @@ static int board_ddr_power_init(enum ddr_type ddr_type) - void stm32mp1_ddr_init(struct ddr_info *priv, - struct stm32mp1_ddr_config *config) - { -- uint32_t pir; -+ uint32_t pir, ddr_reten; - int ret = -EINVAL; -+ uint64_t time; - - if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) { - ret = board_ddr_power_init(STM32MP_DDR3); -@@ -730,6 +809,27 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - VERBOSE("name = %s\n", config->info.name); - VERBOSE("speed = %d kHz\n", config->info.speed); - VERBOSE("size = 0x%x\n", config->info.size); -+ if (config->self_refresh) { -+ VERBOSE("sel-refresh exit (zdata = 0x%x)\n", config->zdata); -+ } -+ -+ /* Check DDR PHY pads retention */ -+ ddr_reten = mmio_read_32((uint32_t)(priv->pwr) + PWR_CR3) & -+ PWR_CR3_DDRRETEN; -+ if (config->self_refresh) { -+ if (ddr_reten == 0U) { -+ VERBOSE("self-refresh aborted: no retention\n"); -+ config->self_refresh = false; -+ } -+ } else { -+ if (ddr_reten != 0U) { -+ VERBOSE("disable DDR PHY retention\n"); -+ mmio_setbits_32((uint32_t)(priv->pwr) + PWR_CR3, -+ PWR_CR3_DDRSRDIS); -+ mmio_clrbits_32((uint32_t)(priv->pwr) + PWR_CR3, -+ PWR_CR3_DDRRETEN); -+ } -+ } - - /* DDR INIT SEQUENCE */ - -@@ -790,6 +890,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - set_reg(priv, REG_TIMING, &config->c_timing); - set_reg(priv, REG_MAP, &config->c_map); - -+ /* Keep the controller in self-refresh mode */ -+ if (config->self_refresh) { -+ mmio_setbits_32((uintptr_t)&priv->ctl->pwrctl, -+ DDRCTRL_PWRCTL_SELFREF_SW); -+ } -+ - /* Skip CTRL init, SDRAM init is done by PHY PUBL */ - mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0, - DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK, -@@ -843,8 +949,20 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - pir |= DDRPHYC_PIR_DRAMRST; /* Only for DDR3 */ - } - -+ /* Treat self-refresh exit : hot boot */ -+ if (config->self_refresh) { -+ /* DDR in self refresh mode, remove zcal & reset & init */ -+ pir &= ~(DDRPHYC_PIR_ZCAL & DDRPHYC_PIR_DRAMRST -+ & DDRPHYC_PIR_DRAMINIT); -+ pir |= DDRPHYC_PIR_ZCALBYP; -+ } -+ - stm32mp1_ddrphy_init(priv->phy, pir); - -+ if (config->self_refresh) { -+ stm32mp1_self_refresh_zcal(priv, config->zdata); -+ } -+ - /* - * 6. SET DFIMISC.dfi_init_complete_en to 1 - * Enable quasi-dynamic register programming. -@@ -865,6 +983,13 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - */ - - /* Wait uMCTL2 ready */ -+ -+ /* Trigger self-refresh exit */ -+ if (config->self_refresh) { -+ mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl, -+ DDRCTRL_PWRCTL_SELFREF_SW); -+ } -+ - stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); - - /* Switch to DLL OFF mode */ -@@ -874,6 +999,8 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - - VERBOSE("DDR DQS training : "); - -+ time = timeout_init_us(0); -+ - /* - * 8. Disable Auto refresh and power down by setting - * - RFSHCTL3.dis_au_refresh = 1 -@@ -898,6 +1025,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv, - /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */ - stm32mp1_ddrphy_idone_wait(priv->phy); - -+ /* Refresh compensation: forcing refresh command */ -+ if (config->self_refresh) { -+ stm32mp1_refresh_compensation(config, priv->ctl, time); -+ } -+ - /* - * 12. set back registers in step 8 to the orginal values if desidered - */ -diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c -index fcb4cfcfd..2071bb2a2 100644 ---- a/drivers/st/ddr/stm32mp1_ddr_helpers.c -+++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c -@@ -6,8 +6,14 @@ - - #include - -+#include -+#include -+#include - #include - #include -+#include -+ -+#define TIMEOUT_500US 500U - - void ddr_enable_clock(void) - { -@@ -22,3 +28,469 @@ void ddr_enable_clock(void) - - stm32mp1_clk_rcc_regs_unlock(); - } -+ -+static void do_sw_handshake(void) -+{ -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE); -+} -+ -+static void do_sw_ack(void) -+{ -+ uint64_t timeout; -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE); -+ -+ timeout = timeout_init_us(TIMEOUT_500US); -+ while ((mmio_read_32(ddrctrl_base + DDRCTRL_SWSTAT) & -+ DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U) { -+ if (timeout_elapsed(timeout)) { -+ panic(); -+ } -+ } -+} -+ -+static int ddr_sw_self_refresh_in(void) -+{ -+ uint64_t timeout; -+ uint32_t stat; -+ uint32_t operating_mode; -+ uint32_t selref_type; -+ uint8_t op_mode_changed = 0; -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); -+ -+ stm32mp1_clk_rcc_regs_lock(); -+ -+ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); -+ -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ /* Blocks AXI ports from taking anymore transactions */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, -+ DDRCTRL_PCTRL_N_PORT_EN); -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, -+ DDRCTRL_PCTRL_N_PORT_EN); -+ -+ /* Waits unit all AXI ports are idle -+ * Poll PSTAT.rd_port_busy_n = 0 -+ * Poll PSTAT.wr_port_busy_n = 0 -+ */ -+ timeout = timeout_init_us(TIMEOUT_500US); -+ while (mmio_read_32(ddrctrl_base + DDRCTRL_PSTAT)) { -+ if (timeout_elapsed(timeout)) { -+ goto pstat_failed; -+ } -+ } -+ /* SW Self-Refresh entry */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_SELFREF_SW); -+ -+ /* Wait operating mode change in self-refresh mode -+ * with STAT.operating_mode[1:0]==11. -+ * Ensure transition to self-refresh was due to software -+ * by checking also that STAT.selfref_type[1:0]=2. -+ */ -+ timeout = timeout_init_us(TIMEOUT_500US); -+ while (!timeout_elapsed(timeout)) { -+ stat = mmio_read_32(ddrctrl_base + DDRCTRL_STAT); -+ operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK; -+ selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK; -+ -+ if ((operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) && -+ (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) { -+ op_mode_changed = 1; -+ break; -+ } -+ } -+ -+ if (op_mode_changed == 0U) -+ goto selfref_sw_failed; -+ -+ /* IOs powering down (PUBL registers) */ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDR); -+ -+ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_ACIOCR, -+ DDRPHYC_ACIOCR_CKPDD_MASK, -+ DDRPHYC_ACIOCR_CKPDD_0); -+ -+ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_ACIOCR, -+ DDRPHYC_ACIOCR_CKPDR_MASK, -+ DDRPHYC_ACIOCR_CKPDR_0); -+ -+ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_ACIOCR, -+ DDRPHYC_ACIOCR_CSPDD_MASK, -+ DDRPHYC_ACIOCR_CSPDD_0); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR); -+ -+ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_DSGCR, -+ DDRPHYC_DSGCR_ODTPDD_MASK, -+ DDRPHYC_DSGCR_ODTPDD_0); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD); -+ -+ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_DSGCR, -+ DDRPHYC_DSGCR_CKEPDD_MASK, -+ DDRPHYC_DSGCR_CKEPDD_0); -+ -+ /* Disable PZQ cell (PUBL register) */ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD); -+ -+ /* Activate sw retention in PWRCTRL */ -+ stm32mp_pwr_regs_lock(); -+ mmio_setbits_32(pwr_base + PWR_CR3, PWR_CR3_DDRRETEN); -+ stm32mp_pwr_regs_unlock(); -+ -+ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */ -+ stm32mp1_clk_rcc_regs_lock(); -+ mmio_setbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ /* Disable all DLLs: GLITCH window */ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, -+ DDRPHYC_ACDLLCR_DLLDIS); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX0DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX1DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX2DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX3DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ stm32mp1_clk_rcc_regs_lock(); -+ -+ /* Switch controller clocks (uMCTL2/PUBL) to DLL output clock */ -+ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); -+ -+ /* Deactivate all DDR clocks */ -+ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, -+ RCC_DDRITFCR_DDRC1EN | -+ RCC_DDRITFCR_DDRC2EN | -+ RCC_DDRITFCR_DDRCAPBEN | -+ RCC_DDRITFCR_DDRPHYCAPBEN); -+ -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ return 0; -+ -+selfref_sw_failed: -+ /* This bit should be cleared to restore DDR in its previous state */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_SELFREF_SW); -+ -+pstat_failed: -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, -+ DDRCTRL_PCTRL_N_PORT_EN); -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, -+ DDRCTRL_PCTRL_N_PORT_EN); -+ -+ return -1; -+} -+ -+int ddr_sw_self_refresh_exit(void) -+{ -+ uint64_t timeout; -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); -+ -+ /* Enable all clocks */ -+ ddr_enable_clock(); -+ -+ do_sw_handshake(); -+ -+ /* Mask dfi_init_complete_en */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_DFIMISC, -+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); -+ -+ do_sw_ack(); -+ -+ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */ -+ stm32mp1_clk_rcc_regs_lock(); -+ mmio_setbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ /* Enable all DLLs: GLITCH window */ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, -+ DDRPHYC_ACDLLCR_DLLDIS); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX0DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX1DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX2DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX3DLLCR, -+ DDRPHYC_DXNDLLCR_DLLDIS); -+ -+ /* Additional delay to avoid early DLL clock switch */ -+ udelay(10); -+ -+ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */ -+ stm32mp1_clk_rcc_regs_lock(); -+ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, -+ DDRPHYC_ACDLLCR_DLLSRST); -+ -+ udelay(10); -+ -+ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, -+ DDRPHYC_ACDLLCR_DLLSRST); -+ -+ /* PHY partial init: (DLL lock and ITM reset) */ -+ mmio_write_32(ddrphyc_base + DDRPHYC_PIR, -+ DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK | -+ DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_INIT); -+ -+ /* Need to wait at least 10 clock cycles before accessing PGSR */ -+ udelay(1); -+ -+ /* Pool end of init */ -+ timeout = timeout_init_us(TIMEOUT_500US); -+ -+ while ((mmio_read_32(ddrphyc_base + DDRPHYC_PGSR) & -+ DDRPHYC_PGSR_IDONE) == 0U) { -+ if (timeout_elapsed(timeout)) { -+ return -1; -+ } -+ } -+ -+ do_sw_handshake(); -+ -+ /* Unmask dfi_init_complete_en to uMCTL2 */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_DFIMISC, -+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); -+ -+ do_sw_ack(); -+ -+ /* Deactivate sw retention in PWR */ -+ stm32mp_pwr_regs_lock(); -+ mmio_clrbits_32(pwr_base + PWR_CR3, PWR_CR3_DDRRETEN); -+ stm32mp_pwr_regs_unlock(); -+ -+ /* Enable PZQ cell (PUBL register) */ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD); -+ -+ /* Enable pad drivers */ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACIOCR, -+ DDRPHYC_ACIOCR_CKPDD_MASK); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACIOCR, -+ DDRPHYC_ACIOCR_CSPDD_MASK); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DSGCR, -+ DDRPHYC_DSGCR_ODTPDD_MASK); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD); -+ -+ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DSGCR, -+ DDRPHYC_DSGCR_CKEPDD_MASK); -+ -+ /* Remove selfrefresh */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_SELFREF_SW); -+ -+ /* Wait operating_mode == normal */ -+ timeout = timeout_init_us(TIMEOUT_500US); -+ while ((mmio_read_32(ddrctrl_base + DDRCTRL_STAT) & -+ DDRCTRL_STAT_OPERATING_MODE_MASK) != -+ DDRCTRL_STAT_OPERATING_MODE_NORMAL) { -+ if (timeout_elapsed(timeout)) { -+ return -1; -+ } -+ } -+ -+ /* AXI ports are no longer blocked from taking transactions */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, -+ DDRCTRL_PCTRL_N_PORT_EN); -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, -+ DDRCTRL_PCTRL_N_PORT_EN); -+ -+ stm32mp1_clk_rcc_regs_lock(); -+ -+ mmio_setbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); -+ -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ return 0; -+} -+ -+int ddr_standby_sr_entry(uint32_t *zq0cr0_zdata) -+{ -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); -+ -+ /* Save IOs calibration values */ -+ if (zq0cr0_zdata != NULL) { -+ *zq0cr0_zdata = mmio_read_32(ddrphyc_base + DDRPHYC_ZQ0CR0) & -+ DDRPHYC_ZQ0CRN_ZDATA_MASK; -+ } -+ -+ /* Put DDR in Self-Refresh */ -+ if (ddr_sw_self_refresh_in() != 0) { -+ return -1; -+ } -+ -+ /* Enable I/O retention mode in standby */ -+ stm32mp_pwr_regs_lock(); -+ mmio_setbits_32(pwr_base + PWR_CR3, PWR_CR3_DDRSREN); -+ stm32mp_pwr_regs_unlock(); -+ -+ return 0; -+} -+ -+void ddr_sr_mode_ssr(void) -+{ -+ uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR; -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ -+ stm32mp1_clk_rcc_regs_lock(); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1EN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2EN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBLPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCAPBLPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCAPBEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCEN); -+ -+ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN); -+ -+ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK); -+ -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ /* Disable HW LP interface of uMCTL2 */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_HWLPCTL, -+ DDRCTRL_HWLPCTL_HW_LP_EN); -+ -+ /* Configure Automatic LP modes of uMCTL2 */ -+ mmio_clrsetbits_32(ddrctrl_base + DDRCTRL_PWRTMG, -+ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK, -+ DDRCTRL_PWRTMG_SELFREF_TO_X32_0); -+ -+ /* -+ * Disable Clock disable with LP modes -+ * (used in RUN mode for LPDDR2 with specific timing). -+ */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE); -+ -+ /* Disable automatic Self-Refresh mode */ -+ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_SELFREF_EN); -+} -+ -+void ddr_sr_mode_asr(void) -+{ -+ uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR; -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ -+ stm32mp1_clk_rcc_regs_lock(); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN); -+ -+ mmio_clrsetbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK, -+ RCC_DDRITFCR_DDRCKMOD_ASR1); -+ -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ /* Enable HW LP interface of uMCTL2 */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_HWLPCTL, -+ DDRCTRL_HWLPCTL_HW_LP_EN); -+ -+ /* Configure Automatic LP modes of uMCTL2 */ -+ mmio_clrsetbits_32(ddrctrl_base + DDRCTRL_PWRTMG, -+ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK, -+ DDRCTRL_PWRTMG_SELFREF_TO_X32_0); -+ -+ /* -+ * Enable Clock disable with LP modes -+ * (used in RUN mode for LPDDR2 with specific timing). -+ */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE); -+ -+ /* Enable automatic Self-Refresh for ASR mode */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_SELFREF_EN); -+} -+ -+void ddr_sr_mode_hsr(void) -+{ -+ uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR; -+ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); -+ -+ stm32mp1_clk_rcc_regs_lock(); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN); -+ -+ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); -+ -+ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); -+ -+ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN); -+ -+ mmio_clrsetbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK, -+ RCC_DDRITFCR_DDRCKMOD_HSR1); -+ -+ stm32mp1_clk_rcc_regs_unlock(); -+ -+ /* Enable HW LP interface of uMCTL2 */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_HWLPCTL, -+ DDRCTRL_HWLPCTL_HW_LP_EN); -+ -+ /* Configure Automatic LP modes of uMCTL2 */ -+ mmio_clrsetbits_32(ddrctrl_base + DDRCTRL_PWRTMG, -+ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK, -+ DDRCTRL_PWRTMG_SELFREF_TO_X32_0); -+ -+ /* -+ * Enable Clock disable with LP modes -+ * (used in RUN mode for LPDDR2 with specific timing). -+ */ -+ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, -+ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE); -+} -diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h -index 4ab37d6b4..f52609f66 100644 ---- a/include/drivers/st/stm32mp1_ddr.h -+++ b/include/drivers/st/stm32mp1_ddr.h -@@ -8,9 +8,6 @@ - #define STM32MP1_DDR_H - - #include --#include -- --#define DT_DDR_COMPAT "st,stm32mp1-ddr" - - struct stm32mp1_ddr_size { - uint64_t base; -@@ -166,9 +163,12 @@ struct stm32mp1_ddr_config { - struct stm32mp1_ddrphy_reg p_reg; - struct stm32mp1_ddrphy_timing p_timing; - struct stm32mp1_ddrphy_cal p_cal; -+ bool self_refresh; -+ uint32_t zdata; - }; - - int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed); - void stm32mp1_ddr_init(struct ddr_info *priv, - struct stm32mp1_ddr_config *config); -+ - #endif /* STM32MP1_DDR_H */ -diff --git a/include/drivers/st/stm32mp1_ddr_helpers.h b/include/drivers/st/stm32mp1_ddr_helpers.h -index 38f24152a..80bf9de6f 100644 ---- a/include/drivers/st/stm32mp1_ddr_helpers.h -+++ b/include/drivers/st/stm32mp1_ddr_helpers.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -7,6 +7,13 @@ - #ifndef STM32MP1_DDR_HELPERS_H - #define STM32MP1_DDR_HELPERS_H - -+#include -+ - void ddr_enable_clock(void); -+int ddr_sw_self_refresh_exit(void); -+int ddr_standby_sr_entry(uint32_t *zq0cr0_zdata); -+void ddr_sr_mode_ssr(void); -+void ddr_sr_mode_asr(void); -+void ddr_sr_mode_hsr(void); - - #endif /* STM32MP1_DDR_HELPERS_H */ -diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c -index 17da4904a..863c2cc94 100644 ---- a/plat/st/common/stm32mp_dt.c -+++ b/plat/st/common/stm32mp_dt.c -@@ -13,8 +13,6 @@ - - #include - #include --#include --#include - - #include - -diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h -index a40852bde..dbe62f09d 100644 ---- a/plat/st/stm32mp1/stm32mp1_def.h -+++ b/plat/st/stm32mp1/stm32mp1_def.h -@@ -17,6 +17,8 @@ - #ifndef __ASSEMBLER__ - #include - #include -+#include -+#include - - #include - #include -@@ -336,6 +338,7 @@ static inline uint32_t tamp_bkpr(uint32_t idx) - * Device Tree defines - ******************************************************************************/ - #define DT_BSEC_COMPAT "st,stm32mp15-bsec" -+#define DT_DDR_COMPAT "st,stm32mp1-ddr" - #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" - #define DT_PWR_COMPAT "st,stm32mp1-pwr" - #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0007-stm32mp1-add-low-power-management.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0007-stm32mp1-add-low-power-management.patch deleted file mode 100644 index 5cb331b..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0007-stm32mp1-add-low-power-management.patch +++ /dev/null @@ -1,2889 +0,0 @@ -From 89dcbaa9307e004bd4f009de6554cab2632a9c15 Mon Sep 17 00:00:00 2001 -From: Yann Gautier -Date: Mon, 20 May 2019 19:20:30 +0200 -Subject: [PATCH 7/7] stm32mp1: add low power management - -Change-Id: I8e0ba794e5ded1290fb83fe8d43ce54d4dc0e320 -Signed-off-by: Yann Gautier ---- - drivers/st/ddr/stm32mp1_ram.c | 92 ++- - drivers/st/pmic/stm32mp_pmic.c | 95 +++ - drivers/st/pmic/stpmic1.c | 52 ++ - fdts/stm32mp157a-dk1.dts | 136 ++++ - fdts/stm32mp157c-ed1.dts | 150 +++++ - include/drivers/st/stm32mp1_pwr.h | 21 +- - include/drivers/st/stm32mp_pmic.h | 2 + - include/drivers/st/stpmic1.h | 4 + - include/dt-bindings/power/stm32mp1-power.h | 19 + - plat/st/stm32mp1/bl2_plat_setup.c | 33 + - plat/st/stm32mp1/include/boot_api.h | 105 ++- - plat/st/stm32mp1/include/platform_def.h | 2 + - plat/st/stm32mp1/include/stm32mp1_context.h | 13 +- - plat/st/stm32mp1/include/stm32mp1_low_power.h | 19 + - .../stm32mp1/include/stm32mp1_power_config.h | 19 + - plat/st/stm32mp1/include/stm32mp1_private.h | 3 + - plat/st/stm32mp1/plat_image_load.c | 63 +- - plat/st/stm32mp1/platform.mk | 4 + - plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 4 + - plat/st/stm32mp1/sp_min/sp_min_setup.c | 79 ++- - plat/st/stm32mp1/stm32mp1_context.c | 199 ++++++ - plat/st/stm32mp1/stm32mp1_def.h | 4 + - plat/st/stm32mp1/stm32mp1_low_power.c | 327 ++++++++++ - plat/st/stm32mp1/stm32mp1_pm.c | 88 ++- - plat/st/stm32mp1/stm32mp1_power_config.c | 130 ++++ - plat/st/stm32mp1/stm32mp1_private.c | 39 ++ - .../stm32mp1/stm32mp1_shared_resources.c.bak | 597 ++++++++++++++++++ - 27 files changed, 2268 insertions(+), 31 deletions(-) - create mode 100644 include/dt-bindings/power/stm32mp1-power.h - create mode 100644 plat/st/stm32mp1/include/stm32mp1_low_power.h - create mode 100644 plat/st/stm32mp1/include/stm32mp1_power_config.h - create mode 100644 plat/st/stm32mp1/stm32mp1_low_power.c - create mode 100644 plat/st/stm32mp1/stm32mp1_power_config.c - create mode 100644 plat/st/stm32mp1/stm32mp1_shared_resources.c.bak - -diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c -index 4ae55fcc7..f94980c94 100644 ---- a/drivers/st/ddr/stm32mp1_ram.c -+++ b/drivers/st/ddr/stm32mp1_ram.c -@@ -49,6 +49,26 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) - return 0; - } - -+/******************************************************************************* -+ * This function tests a simple read/write access to the DDR. -+ * Note that the previous content is restored after test. -+ * Returns 0 if success, and address value else. -+ ******************************************************************************/ -+static uint32_t ddr_test_rw_access(void) -+{ -+ uint32_t saved_value = mmio_read_32(STM32MP_DDR_BASE); -+ -+ mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN); -+ -+ if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { -+ return (uint32_t)STM32MP_DDR_BASE; -+ } -+ -+ mmio_write_32(STM32MP_DDR_BASE, saved_value); -+ -+ return 0; -+} -+ - /******************************************************************************* - * This function tests the DDR data bus wiring. - * This is inspired from the Data Bus Test algorithm written by Michael Barr -@@ -168,8 +188,12 @@ static int stm32mp1_ddr_setup(void) - int ret; - struct stm32mp1_ddr_config config; - int node, len; -- uint32_t uret, idx; -+ uint32_t magic, uret, idx; - void *fdt; -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); -+ uint32_t bkpr_core1_magic = -+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); - - #define PARAM(x, y) \ - { \ -@@ -237,6 +261,18 @@ static int stm32mp1_ddr_setup(void) - } - } - -+ config.self_refresh = false; -+ -+ stm32mp_clk_enable(RTCAPB); -+ -+ magic = mmio_read_32(bkpr_core1_magic); -+ if (magic == BOOT_API_A7_CORE0_MAGIC_NUMBER) { -+ config.self_refresh = true; -+ config.zdata = stm32_get_zdata_from_context(); -+ } -+ -+ stm32mp_clk_disable(RTCAPB); -+ - /* Disable axidcg clock gating during init */ - mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); - -@@ -245,6 +281,14 @@ static int stm32mp1_ddr_setup(void) - /* Enable axidcg clock gating */ - mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); - -+ /* check if DDR content is lost (self-refresh aborted) */ -+ if ((magic == BOOT_API_A7_CORE0_MAGIC_NUMBER) && !config.self_refresh) { -+ /* clear Backup register */ -+ mmio_write_32(bkpr_core1_addr, 0); -+ /* clear magic number */ -+ mmio_write_32(bkpr_core1_magic, 0); -+ } -+ - priv->info.size = config.info.size; - - VERBOSE("%s : ram size(%x, %x)\n", __func__, -@@ -253,25 +297,37 @@ static int stm32mp1_ddr_setup(void) - write_sctlr(read_sctlr() & ~SCTLR_C_BIT); - dcsw_op_all(DC_OP_CISW); - -- uret = ddr_test_data_bus(); -- if (uret != 0U) { -- ERROR("DDR data bus test: can't access memory @ 0x%x\n", -- uret); -- panic(); -- } -+ if (config.self_refresh) { -+ uret = ddr_test_rw_access(); -+ if (uret != 0U) { -+ ERROR("DDR rw test: Can't access memory @ 0x%x\n", -+ uret); -+ panic(); -+ } - -- uret = ddr_test_addr_bus(); -- if (uret != 0U) { -- ERROR("DDR addr bus test: can't access memory @ 0x%x\n", -- uret); -- panic(); -- } -+ /* Restore area overwritten by training */ -+ stm32_restore_ddr_training_area(); -+ } else { -+ uret = ddr_test_data_bus(); -+ if (uret != 0U) { -+ ERROR("DDR data bus test: can't access memory @ 0x%x\n", -+ uret); -+ panic(); -+ } - -- uret = ddr_check_size(); -- if (uret < config.info.size) { -- ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", -- uret, config.info.size); -- panic(); -+ uret = ddr_test_addr_bus(); -+ if (uret != 0U) { -+ ERROR("DDR addr bus test: can't access memory @ 0x%x\n", -+ uret); -+ panic(); -+ } -+ -+ uret = ddr_check_size(); -+ if (uret < config.info.size) { -+ ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", -+ uret, config.info.size); -+ panic(); -+ } - } - - write_sctlr(read_sctlr() | SCTLR_C_BIT); -diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c -index 9e9dddc4d..dc44b735f 100644 ---- a/drivers/st/pmic/stm32mp_pmic.c -+++ b/drivers/st/pmic/stm32mp_pmic.c -@@ -27,6 +27,8 @@ - #define STPMIC1_BUCK_OUTPUT_SHIFT 2 - #define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT) - -+#define REGULATOR_MODE_STANDBY 8U -+ - #define STPMIC1_DEFAULT_START_UP_DELAY_MS 1 - - static struct i2c_handle_s i2c_handle; -@@ -174,6 +176,99 @@ int dt_pmic_configure_boot_on_regulators(void) - return 0; - } - -+int dt_pmic_set_lp_config(const char *node_name) -+{ -+ int pmic_node, regulators_node, regulator_node; -+ int status; -+ void *fdt; -+ -+ if (node_name == NULL) { -+ return 0; -+ } -+ -+ if (fdt_get_address(&fdt) == 0) { -+ return -ENOENT; -+ } -+ -+ pmic_node = dt_get_pmic_node(fdt); -+ if (pmic_node < 0) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ status = stpmic1_powerctrl_on(); -+ if (status != 0) { -+ return status; -+ }; -+ -+ regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators"); -+ -+ fdt_for_each_subnode(regulator_node, fdt, regulators_node) { -+ const fdt32_t *cuint; -+ const char *reg_name; -+ int regulator_state_node; -+ -+ /* -+ * First, copy active configuration (Control register) to -+ * PWRCTRL Control register, even if regulator_state_node -+ * does not exist. -+ */ -+ reg_name = fdt_get_name(fdt, regulator_node, NULL); -+ status = stpmic1_lp_copy_reg(reg_name); -+ if (status != 0) { -+ return status; -+ } -+ -+ /* Then apply configs from regulator_state_node */ -+ regulator_state_node = fdt_subnode_offset(fdt, -+ regulator_node, -+ node_name); -+ if (regulator_state_node <= 0) { -+ continue; -+ } -+ -+ if (fdt_getprop(fdt, regulator_state_node, -+ "regulator-on-in-suspend", NULL) != NULL) { -+ status = stpmic1_lp_reg_on_off(reg_name, 1); -+ if (status != 0) { -+ return status; -+ } -+ } -+ -+ if (fdt_getprop(fdt, regulator_state_node, -+ "regulator-off-in-suspend", NULL) != NULL) { -+ status = stpmic1_lp_reg_on_off(reg_name, 0); -+ if (status != 0) { -+ return status; -+ } -+ } -+ -+ cuint = fdt_getprop(fdt, regulator_state_node, -+ "regulator-suspend-microvolt", NULL); -+ if (cuint != NULL) { -+ uint16_t voltage = (uint16_t)(fdt32_to_cpu(*cuint) / -+ 1000U); -+ -+ status = stpmic1_lp_set_voltage(reg_name, voltage); -+ if (status != 0) { -+ return status; -+ } -+ } -+ -+ cuint = fdt_getprop(fdt, regulator_state_node, -+ "regulator-mode", NULL); -+ if (cuint != NULL) { -+ if (fdt32_to_cpu(*cuint) == REGULATOR_MODE_STANDBY) { -+ status = stpmic1_lp_set_mode(reg_name, 1); -+ if (status != 0) { -+ return status; -+ } -+ } -+ } -+ } -+ -+ return 0; -+} -+ - bool initialize_pmic_i2c(void) - { - int ret; -diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c -index 999963054..51754fc3b 100644 ---- a/drivers/st/pmic/stpmic1.c -+++ b/drivers/st/pmic/stpmic1.c -@@ -648,6 +648,58 @@ int stpmic1_regulator_mask_reset_set(const char *name) - regul->mask_reset); - } - -+/* Low-power functions */ -+int stpmic1_lp_copy_reg(const char *name) -+{ -+ uint8_t val; -+ int status; -+ const struct regul_struct *regul = get_regulator_data(name); -+ -+ status = stpmic1_register_read(regul->control_reg, &val); -+ if (status != 0) { -+ return status; -+ } -+ -+ return stpmic1_register_write(regul->low_power_reg, val); -+} -+ -+int stpmic1_lp_reg_on_off(const char *name, uint8_t enable) -+{ -+ const struct regul_struct *regul = get_regulator_data(name); -+ -+ return stpmic1_register_update(regul->low_power_reg, enable, -+ LDO_BUCK_ENABLE_MASK); -+} -+ -+int stpmic1_lp_set_mode(const char *name, uint8_t hplp) -+{ -+ const struct regul_struct *regul = get_regulator_data(name); -+ -+ return stpmic1_register_update(regul->low_power_reg, -+ hplp << LDO_BUCK_HPLP_SHIFT, -+ LDO_BUCK_HPLP_ENABLE_MASK); -+} -+ -+int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts) -+{ -+ uint8_t voltage_index = voltage_to_index(name, millivolts); -+ const struct regul_struct *regul = get_regulator_data(name); -+ uint8_t mask; -+ -+ /* Voltage can be set for buck or ldo (except ldo4) regulators */ -+ if (strncmp(name, "buck", 4) == 0) { -+ mask = BUCK_VOLTAGE_MASK; -+ } else if ((strncmp(name, "ldo", 3) == 0) && -+ (strncmp(name, "ldo4", 4) != 0)) { -+ mask = LDO_VOLTAGE_MASK; -+ } else { -+ return 0; -+ } -+ -+ return stpmic1_register_update(regul->low_power_reg, voltage_index << 2, -+ mask); -+} -+ - int stpmic1_regulator_voltage_get(const char *name) - { - const struct regul_struct *regul = get_regulator_data(name); -diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts -index 78681b0ba..2eced8f53 100644 ---- a/fdts/stm32mp157a-dk1.dts -+++ b/fdts/stm32mp157a-dk1.dts -@@ -192,6 +192,7 @@ - - /* ATF Specific */ - #include -+#include - #include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" - #include "stm32mp157c-security.dtsi" - -@@ -309,3 +310,138 @@ - secure-status = "okay"; - }; - }; -+ -+&pwr { -+ system_suspend_supported_soc_modes = < -+ STM32_PM_CSLEEP_RUN -+ STM32_PM_CSTOP_ALLOW_LP_STOP -+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR -+ >; -+ -+ system_off_soc_mode = ; -+}; -+ -+/* Low-power states of regulators */ -+&vddcore { -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd_ddr { -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd { -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+}; -+ -+&v3v3 { -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&v1v8_audio { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&v3v3_hdmi { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vtt_ddr { -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd_usb { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdda { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&v1v2_hdmi { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vref_ddr { -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts -index 779492552..d766cc6a8 100644 ---- a/fdts/stm32mp157c-ed1.dts -+++ b/fdts/stm32mp157c-ed1.dts -@@ -196,6 +196,7 @@ - - /* ATF Specific */ - #include -+#include - #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" - #include "stm32mp157c-security.dtsi" - -@@ -315,3 +316,152 @@ - secure-status = "okay"; - }; - }; -+ -+&pwr { -+ system_suspend_supported_soc_modes = < -+ STM32_PM_CSLEEP_RUN -+ STM32_PM_CSTOP_ALLOW_LP_STOP -+ STM32_PM_CSTOP_ALLOW_LPLV_STOP -+ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR -+ >; -+ system_off_soc_mode = ; -+}; -+ -+/* Low-power states of regulators */ -+&vddcore { -+ lp-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <1200000>; -+ }; -+ lplv-stop { -+ regulator-on-in-suspend; -+ regulator-suspend-microvolt = <900000>; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd_ddr { -+ lp-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <1350000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd { -+ lp-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-suspend-microvolt = <3300000>; -+ regulator-on-in-suspend; -+ }; -+}; -+ -+&v3v3 { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdda { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&v2v8 { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vtt_ddr { -+ lp-stop { -+ regulator-off-in-suspend; -+ }; -+ lplv-stop { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd_usb { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vdd_sd { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&v1v8 { -+ standby-ddr-sr { -+ regulator-off-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -+ -+&vref_ddr { -+ lp-stop { -+ regulator-on-in-suspend; -+ }; -+ lplv-stop { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-sr { -+ regulator-on-in-suspend; -+ }; -+ standby-ddr-off { -+ regulator-off-in-suspend; -+ }; -+}; -diff --git a/include/drivers/st/stm32mp1_pwr.h b/include/drivers/st/stm32mp1_pwr.h -index e17df44fb..9b662f2d1 100644 ---- a/include/drivers/st/stm32mp1_pwr.h -+++ b/include/drivers/st/stm32mp1_pwr.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -13,20 +13,39 @@ - #define PWR_CR2 U(0x08) - #define PWR_CR3 U(0x0C) - #define PWR_MPUCR U(0x10) -+#define PWR_MCUCR U(0x14) - #define PWR_WKUPCR U(0x20) - #define PWR_MPUWKUPENR U(0x28) - -+#define PWR_OFFSET_MASK GENMASK(9, 0) -+ - #define PWR_CR1_LPDS BIT(0) - #define PWR_CR1_LPCFG BIT(1) - #define PWR_CR1_LVDS BIT(2) - #define PWR_CR1_DBP BIT(8) - -+#define PWR_CR2_BREN BIT(0) -+#define PWR_CR2_RREN BIT(1) -+#define PWR_CR2_BRRDY BIT(16) -+#define PWR_CR2_RRRDY BIT(17) -+ -+#define PWR_CR3_VBE BIT(8) -+#define PWR_CR3_VBRS BIT(9) - #define PWR_CR3_DDRSREN BIT(10) - #define PWR_CR3_DDRSRDIS BIT(11) - #define PWR_CR3_DDRRETEN BIT(12) -+#define PWR_CR3_USB33DEN BIT(24) -+#define PWR_CR3_REG18EN BIT(28) -+#define PWR_CR3_REG11EN BIT(30) - - #define PWR_MPUCR_PDDS BIT(0) - #define PWR_MPUCR_CSTDBYDIS BIT(3) - #define PWR_MPUCR_CSSF BIT(9) - -+#define PWR_MCUCR_PDDS BIT(0) -+ -+#define PWR_WKUPCR_MASK GENMASK(27, 16) | GENMASK(13, 8) | GENMASK(5, 0) -+ -+#define PWR_MPUWKUPENR_MASK GENMASK(5, 0) -+ - #endif /* STM32MP1_PWR_H */ -diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h -index 984cd6014..f5810f38c 100644 ---- a/include/drivers/st/stm32mp_pmic.h -+++ b/include/drivers/st/stm32mp_pmic.h -@@ -27,6 +27,8 @@ int dt_pmic_status(void); - */ - int dt_pmic_configure_boot_on_regulators(void); - -+int dt_pmic_set_lp_config(const char *node_name); -+ - /* - * initialize_pmic_i2c - Initialize I2C for the PMIC control - * -diff --git a/include/drivers/st/stpmic1.h b/include/drivers/st/stpmic1.h -index f7e293b18..e4ceea5e9 100644 ---- a/include/drivers/st/stpmic1.h -+++ b/include/drivers/st/stpmic1.h -@@ -161,6 +161,10 @@ int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts); - int stpmic1_regulator_voltage_get(const char *name); - int stpmic1_regulator_pull_down_set(const char *name); - int stpmic1_regulator_mask_reset_set(const char *name); -+int stpmic1_lp_copy_reg(const char *name); -+int stpmic1_lp_reg_on_off(const char *name, uint8_t enable); -+int stpmic1_lp_set_mode(const char *name, uint8_t hplp); -+int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts); - void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr); - - int stpmic1_get_version(unsigned long *version); -diff --git a/include/dt-bindings/power/stm32mp1-power.h b/include/dt-bindings/power/stm32mp1-power.h -new file mode 100644 -index 000000000..d588dd71f ---- /dev/null -+++ b/include/dt-bindings/power/stm32mp1-power.h -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ -+/* -+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved -+ * Author: Yann Gautier for STMicroelectronics. -+ */ -+ -+#ifndef DT_BINDINGS_STM32MP1_POWER_H -+#define DT_BINDINGS_STM32MP1_POWER_H -+ -+#define STM32_PM_CSLEEP_RUN 0 -+#define STM32_PM_CSTOP_ALLOW_STOP 1 -+#define STM32_PM_CSTOP_ALLOW_LP_STOP 2 -+#define STM32_PM_CSTOP_ALLOW_LPLV_STOP 3 -+#define STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR 4 -+#define STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF 5 -+#define STM32_PM_SHUTDOWN 6 -+#define STM32_PM_MAX_SOC_MODE 7 -+ -+#endif /* DT_BINDINGS_STM32MP1_POWER_H */ -diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c -index d9e29b4e8..c729c0238 100644 ---- a/plat/st/stm32mp1/bl2_plat_setup.c -+++ b/plat/st/stm32mp1/bl2_plat_setup.c -@@ -31,6 +31,8 @@ - #include - #include - -+#define PWRLP_TEMPO_5_HSI 5 -+ - static struct console_stm32 console; - static struct stm32mp_auth_ops stm32mp1_auth_ops; - -@@ -160,6 +162,10 @@ void bl2_el3_plat_arch_setup(void) - uint32_t clk_rate; - uintptr_t pwr_base; - uintptr_t rcc_base; -+ uint32_t bkpr_core1_magic = -+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); - - mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, - BL_CODE_END - BL_CODE_BASE, -@@ -204,6 +210,11 @@ void bl2_el3_plat_arch_setup(void) - pwr_base = stm32mp_pwr_base(); - rcc_base = stm32mp_rcc_base(); - -+ /* Clear Stop Request bits to correctly manage low-power exit */ -+ mmio_write_32(rcc_base + RCC_MP_SREQCLRR, -+ (uint32_t)(RCC_MP_SREQCLRR_STPREQ_P0 | -+ RCC_MP_SREQCLRR_STPREQ_P1)); -+ - /* - * Disable the backup domain write protection. - * The protection is enable at each reset by hardware -@@ -215,6 +226,12 @@ void bl2_el3_plat_arch_setup(void) - ; - } - -+ /* -+ * Configure Standby mode available for MCU by default -+ * and allow to switch in standby SoC in all case -+ */ -+ mmio_setbits_32(pwr_base + PWR_MCUCR, PWR_MCUCR_PDDS); -+ - if (bsec_probe() != 0) { - panic(); - } -@@ -231,9 +248,25 @@ void bl2_el3_plat_arch_setup(void) - mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); - } - -+ /* Wait 5 HSI periods before re-enabling PLLs after STOP modes */ -+ mmio_clrsetbits_32(rcc_base + RCC_PWRLPDLYCR, -+ RCC_PWRLPDLYCR_PWRLP_DLY_MASK, -+ PWRLP_TEMPO_5_HSI); -+ -+ /* Disable retention and backup RAM content after standby */ -+ mmio_clrbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | PWR_CR2_RREN); -+ - /* Disable MCKPROT */ - mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); - -+ if ((boot_context->boot_action != -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) && -+ (boot_context->boot_action != -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY)) { -+ mmio_write_32(bkpr_core1_addr, 0); -+ mmio_write_32(bkpr_core1_magic, 0); -+ } -+ - generic_delay_timer_init(); - - if (stm32mp1_clk_probe() < 0) { -diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h -index 2284970fa..6088b3701 100644 ---- a/plat/st/stm32mp1/include/boot_api.h -+++ b/plat/st/stm32mp1/include/boot_api.h -@@ -10,6 +10,90 @@ - #include - #include - -+/* -+ * Exported constants -+ */ -+ -+/* -+ * Boot Context related definitions -+ */ -+ -+/* -+ * Possible value of boot context field 'boot_action' -+ */ -+/* Boot action is Process Cold Boot */ -+#define BOOT_API_CTX_BOOT_ACTION_COLD_BOOT_PROCESS 0x09U -+/* Boot action is Process Wakeup from CSTANDBY */ -+#define BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY 0x0AU -+/* Boot action is Process Wakeup from STANDBY */ -+#define BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY 0x0BU -+/* Boot action is Process Engineering Boot */ -+#define BOOT_API_CTX_BOOT_ACTION_ENGI_BOOT 0x0CU -+ -+#define BOOT_API_CTX_BOOT_ACTION_MPU_CORE0_RESET_PROCESS 0x0F -+ -+/* -+ * Possible value of boot context field 'stby_exit_status' -+ */ -+ -+/* The boot reason is not a STANDBY Exit reason */ -+#define BOOT_API_CTX_STBY_EXIT_STATUS_NO_STANDBY 0x00 -+ -+/* STANDBY Exit with MPU_BEN=1, MCU_BEN=0 */ -+#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MPU_ONLY 0x01 -+ -+/* -+ * STANDBY Exit with MPU_BEN=1, MCU_BEN=1, MPU will go for cold boot -+ * MCU restarted by bootROM -+ */ -+#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_ALL_CORES 0x02 -+ -+/* -+ * STANDBY Exit with MPU_BEN=1, MCU_BEN=1, MPU will go for cold boot -+ * but MCU restart aborted (code integrity check) : have not been restarted -+ * by bootROM -+ */ -+#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_ALL_CORES_MCU_ABT 0x03 -+ -+/* -+ * STANDBY Exit with MPU_BEN=0, MCU_BEN=1, MPU gone to CSTANDBY, -+ * MCU restarted correctly by bootROM -+ * This value should never be read by FSBL, because not executed in that case -+ */ -+#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MCU_ONLY 0x04 -+ -+/* -+ * STANDBY Exit with MPU_BEN=0, MCU_BEN=1, MCU restart aborted -+ * due code integrity check, then MPU will go for cold boot despite -+ * was not planned initially -+ */ -+#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MCU_ONLY_MCU_ABT 0x05 -+ -+/* -+ * STANDBY Exit with MPU_BEN=1, MCU_BEN=1, MCU restart aborted -+ * due to MCU security perimeter issue -+ */ -+#define \ -+BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_ALL_CORES_MCU_ABT_SEC_PERIMETER_ISSUE 0x06 -+ -+/* -+ * STANDBY Exit with MPU_BEN=0, MCU_BEN=1, MCU restart aborted -+ * due to MCU security perimeter issue, then MPU will go for cold boot -+ * despite was not planned initially -+ */ -+#define \ -+BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MCU_ONLY_MCU_ABT_SEC_PERIMETER_ISSUE 0x07 -+ -+/* -+ * Possible value of boot context field 'cstby_exit_status' -+ */ -+/* The boot reason is not a CSTANDBY Exit reason */ -+#define BOOT_API_CTX_CSTBY_EXIT_STATUS_NO_CSTBY 0x00 -+/* CSTANDBY Exit with MCU detected as Not running */ -+#define BOOT_API_CTX_CSTBY_EXIT_STATUS_MCU_NOT_RUNNING 0x01 -+/* CSTANDBY Exit with MCU detected as Running */ -+#define BOOT_API_CTX_CSTBY_EXIT_STATUS_MCU_RUNNING 0x02 -+ - /* - * Possible value of boot context field 'auth_status' - */ -@@ -144,7 +228,26 @@ typedef struct { - uint16_t boot_interface_instance; - uint32_t reserved1[13]; - uint32_t otp_afmux_values[3]; -- uint32_t reserved[5]; -+ uint32_t reserved[2]; -+ /* -+ * Log to boot context, what was the kind of boot action -+ * takes values from defines BOOT_API_BOOT_ACTION_XXX above -+ */ -+ uint32_t boot_action; -+ /* -+ * STANDBY Exit status to be checked by FSBL in case -+ * field 'boot_action' == BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY -+ * take values from defines above 'BOOT_API_CTX_STBY_EXIT_STATUS_XXX' -+ * depending on encountered situation -+ */ -+ uint32_t stby_exit_status; -+ /* -+ * CSTANDBY Exit status to be checked by FSBL in case -+ * boot_action == BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY -+ * take values from defines above 'BOOT_API_CTX_CSTBY_EXIT_STATUS_XXX' -+ * depending on encountered situation -+ */ -+ uint32_t cstby_exit_status; - uint32_t auth_status; - - /* -diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h -index 263e6d6e1..2f6773e84 100644 ---- a/plat/st/stm32mp1/include/platform_def.h -+++ b/plat/st/stm32mp1/include/platform_def.h -@@ -112,6 +112,8 @@ - */ - #define ARM_IRQ_SEC_PHY_TIMER U(29) - -+#define ARM_IRQ_NON_SEC_SGI_0 U(0) -+ - #define ARM_IRQ_SEC_SGI_0 U(8) - #define ARM_IRQ_SEC_SGI_1 U(9) - #define ARM_IRQ_SEC_SGI_2 U(10) -diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h -index 698415af2..081691788 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_context.h -+++ b/plat/st/stm32mp1/include/stm32mp1_context.h -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -@@ -7,8 +7,19 @@ - #ifndef STM32MP1_CONTEXT_H - #define STM32MP1_CONTEXT_H - -+#include - #include - -+#define DDR_CRC_GRANULE 32 -+ -+void stm32_clean_context(void); -+int stm32_save_context(uint32_t zq0cr0_zdata); -+int stm32_restore_context(void); -+int stm32_restore_backup_reg(void); -+uint32_t stm32_get_zdata_from_context(void); - int stm32_save_boot_interface(uint32_t interface, uint32_t instance); -+void stm32_save_ddr_training_area(void); -+void stm32_restore_ddr_training_area(void); -+uint32_t stm32_pm_get_optee_ep(void); - - #endif /* STM32MP1_CONTEXT_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_low_power.h b/plat/st/stm32mp1/include/stm32mp1_low_power.h -new file mode 100644 -index 000000000..82b3d36c1 ---- /dev/null -+++ b/plat/st/stm32mp1/include/stm32mp1_low_power.h -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef STM32MP1_LOW_POWER_H -+#define STM32MP1_LOW_POWER_H -+ -+#include -+#include -+ -+void stm32_rcc_wakeup_update(bool state); -+void stm32_apply_pmic_suspend_config(uint32_t mode); -+void stm32_exit_cstop(void); -+void stm32_pwr_down_wfi(void); -+void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr); -+ -+#endif /* STM32MP1_LOW_POWER_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_power_config.h b/plat/st/stm32mp1/include/stm32mp1_power_config.h -new file mode 100644 -index 000000000..7c7571a5a ---- /dev/null -+++ b/plat/st/stm32mp1/include/stm32mp1_power_config.h -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#ifndef STM32MP1_POWER_CONFIG_H -+#define STM32MP1_POWER_CONFIG_H -+ -+#include -+#include -+ -+#define PSCI_MODE_SYSTEM_SUSPEND 0 -+#define PSCI_MODE_SYSTEM_OFF 1 -+ -+void stm32mp1_init_lp_states(void); -+uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode); -+ -+#endif /* STM32MP1_POWER_CONFIG_H */ -diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h -index e38fca012..7adc7f6f1 100644 ---- a/plat/st/stm32mp1/include/stm32mp1_private.h -+++ b/plat/st/stm32mp1/include/stm32mp1_private.h -@@ -11,6 +11,9 @@ - - void configure_mmu(void); - -+void stm32mp_mask_timer(void); -+void __dead2 stm32mp_wait_cpu_reset(void); -+ - void stm32mp1_arch_security_setup(void); - void stm32mp1_security_setup(void); - -diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c -index a52db6cac..1fb3ec510 100644 ---- a/plat/st/stm32mp1/plat_image_load.c -+++ b/plat/st/stm32mp1/plat_image_load.c -@@ -1,10 +1,14 @@ - /* -- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. -+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -+#include -+ -+#include - #include -+#include - #include - - /******************************************************************************* -@@ -16,11 +20,68 @@ void plat_flush_next_bl_params(void) - flush_bl_params_desc(); - } - -+#ifdef AARCH32_SP_OPTEE -+static bool addr_inside_backupsram(uintptr_t addr) -+{ -+ return (addr >= STM32MP_BACKUP_RAM_BASE) && -+ (addr < (STM32MP_BACKUP_RAM_BASE + STM32MP_BACKUP_RAM_SIZE)); -+} -+#endif -+ - /******************************************************************************* - * This function returns the list of loadable images. - ******************************************************************************/ - bl_load_info_t *plat_get_bl_image_load_info(void) - { -+ boot_api_context_t *boot_context = -+ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); -+#ifdef AARCH32_SP_OPTEE -+ bl_mem_params_node_t *bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); -+#endif -+ bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); -+ uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR); -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ -+ /* -+ * If going back from CSTANDBY / STANDBY and DDR was in Self-Refresh, -+ * BL33 must not be loaded as it would overwrite the code already -+ * in DDR. For this, the BL33 part of the bl_mem_params_desc_ptr -+ * struct should be modified to skip its loading -+ */ -+ if (((boot_context->boot_action == -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) || -+ (boot_context->boot_action == -+ BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY)) && -+ ((mmio_read_32(pwr_base + PWR_CR3) & PWR_CR3_DDRSREN) != 0U) && -+ ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U)) { -+ stm32mp_clk_enable(RTCAPB); -+ -+ if (mmio_read_32(bkpr_core1_addr) != 0U) { -+ bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -+ -+#ifdef AARCH32_SP_OPTEE -+ bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; -+ bl32->ep_info.pc = stm32_pm_get_optee_ep(); -+ -+ if (addr_inside_backupsram(bl32->ep_info.pc)) { -+ stm32mp_clk_enable(BKPSRAM); -+ } -+#else -+ /* -+ * Set ep_info PC to 0, to inform BL32 it is a reset -+ * after STANDBY -+ */ -+ bl33->ep_info.pc = 0; -+#endif -+ } -+ -+ stm32mp_clk_disable(RTCAPB); -+ } -+ -+ bl33->image_info.image_max_size = dt_get_ddr_size(); -+ - return get_bl_load_info_from_mem_params_desc(); - } - -diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk -index 90b3e3c1e..0c57c85af 100644 ---- a/plat/st/stm32mp1/platform.mk -+++ b/plat/st/stm32mp1/platform.mk -@@ -94,6 +94,10 @@ ifeq ($(AARCH32_SP),optee) - BL2_SOURCES += lib/optee/optee_utils.c - endif - -+ -+# Do not use neon in TF-A code, it leads to issues in low-power functions -+TF_CFLAGS += -mfloat-abi=soft -+ - # Macros and rules to build TF binary - STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed - STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) -diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -index 6c7107ca2..34530f181 100644 ---- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk -@@ -6,10 +6,14 @@ - - SP_MIN_WITH_SECURE_FIQ := 1 - -+BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 -+ - BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ - drivers/st/rtc/stm32_rtc.c \ - plat/st/stm32mp1/sp_min/sp_min_setup.c \ -+ plat/st/stm32mp1/stm32mp1_low_power.c \ - plat/st/stm32mp1/stm32mp1_pm.c \ -+ plat/st/stm32mp1/stm32mp1_power_config.c \ - plat/st/stm32mp1/stm32mp1_topology.c - # Generic GIC v2 - BL32_SOURCES += drivers/arm/gic/common/gic_common.c \ -diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c -index ff69358e0..62b358cb3 100644 ---- a/plat/st/stm32mp1/sp_min/sp_min_setup.c -+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -29,6 +30,7 @@ - #include - - #include -+#include - - /****************************************************************************** - * Placeholder variables for copying the arguments that have been passed to -@@ -38,6 +40,27 @@ static entry_point_info_t bl33_image_ep_info; - - static struct console_stm32 console; - -+static void stm32_sgi1_it_handler(void) -+{ -+ uint32_t id; -+ -+ stm32mp_mask_timer(); -+ -+ gicv2_end_of_interrupt(ARM_IRQ_SEC_SGI_1); -+ -+ do { -+ id = plat_ic_get_pending_interrupt_id(); -+ -+ if (id <= MAX_SPI_ID) { -+ gicv2_end_of_interrupt(id); -+ -+ plat_ic_disable_interrupt(id); -+ } -+ } while (id <= MAX_SPI_ID); -+ -+ stm32mp_wait_cpu_reset(); -+} -+ - /******************************************************************************* - * Interrupt handler for FIQ (secure IRQ) - ******************************************************************************/ -@@ -48,12 +71,15 @@ void sp_min_plat_fiq_handler(uint32_t id) - ERROR("STM32MP1_IRQ_TZC400 generated\n"); - panic(); - break; -+ case ARM_IRQ_SEC_SGI_1: -+ stm32_sgi1_it_handler(); -+ break; - case STM32MP1_IRQ_AXIERRIRQ: - ERROR("STM32MP1_IRQ_AXIERRIRQ generated\n"); - panic(); - break; - default: -- ERROR("SECURE IT handler not define for it : %u", id); -+ ERROR("SECURE IT handler not define for it : %u\n", id); - break; - } - } -@@ -67,11 +93,54 @@ void sp_min_plat_fiq_handler(uint32_t id) - entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) - { - entry_point_info_t *next_image_info; -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); -+ uint32_t bkpr_core1_magic = -+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); - - next_image_info = &bl33_image_ep_info; - -+ /* -+ * PC is set to 0 when resetting after STANDBY -+ * The context should be restored, and the image information -+ * should be filled with what what was saved -+ */ - if (next_image_info->pc == 0U) { -- return NULL; -+ void *cpu_context; -+ uint32_t magic_nb, saved_pc; -+ -+ stm32mp_clk_enable(RTCAPB); -+ -+ magic_nb = mmio_read_32(bkpr_core1_magic); -+ saved_pc = mmio_read_32(bkpr_core1_addr); -+ -+ stm32mp_clk_disable(RTCAPB); -+ -+ if (stm32_restore_context() != 0) { -+ panic(); -+ } -+ -+ cpu_context = cm_get_context(NON_SECURE); -+ -+ next_image_info->spsr = read_ctx_reg(get_regs_ctx(cpu_context), -+ CTX_SPSR); -+ -+ /* PC should be retrieved in backup register if OK, else it can -+ * be retrieved from non-secure context -+ */ -+ if (magic_nb == BOOT_API_A7_CORE0_MAGIC_NUMBER) { -+ /* BL33 return address should be in DDR */ -+ if ((saved_pc < STM32MP_DDR_BASE) || -+ (saved_pc > (STM32MP_DDR_BASE + -+ (dt_get_ddr_size() - 1U)))) { -+ panic(); -+ } -+ -+ next_image_info->pc = saved_pc; -+ } else { -+ next_image_info->pc = -+ read_ctx_reg(get_regs_ctx(cpu_context), CTX_LR); -+ } - } - - return next_image_info; -@@ -145,6 +214,12 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, - #endif - console_set_scope(&console.console, console_flags); - } -+ -+ if (dt_pmic_status() > 0) { -+ initialize_pmic(); -+ } -+ -+ stm32mp1_init_lp_states(); - } - - /******************************************************************************* -diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c -index cf8a91eb4..ed54fc625 100644 ---- a/plat/st/stm32mp1/stm32mp1_context.c -+++ b/plat/st/stm32mp1/stm32mp1_context.c -@@ -5,19 +5,171 @@ - */ - - #include -+#include - - #include - -+#include -+#include -+#include - #include -+#include - #include -+#include - #include -+#include -+#include -+#include - - #include - -+#include -+ - #define TAMP_BOOT_ITF_BACKUP_REG_ID U(20) - #define TAMP_BOOT_ITF_MASK U(0x0000FF00) - #define TAMP_BOOT_ITF_SHIFT 8 - -+#define TRAINING_AREA_SIZE 64 -+ -+#ifdef AARCH32_SP_OPTEE -+/* OPTEE_MAILBOX_MAGIC relates to struct backup_data_s as defined */ -+#define OPTEE_MAILBOX_MAGIC_V1 0x01 -+#define OPTEE_MAILBOX_MAGIC ((OPTEE_MAILBOX_MAGIC_V1 << 16) + \ -+ TRAINING_AREA_SIZE) -+#endif -+ -+struct backup_data_s { -+#ifdef AARCH32_SP_OPTEE -+ uint32_t magic; -+ uint32_t core0_resume_hint; -+ uint32_t zq0cr0_zdata; -+ uint8_t ddr_training_backup[TRAINING_AREA_SIZE]; -+#else -+ smc_ctx_t saved_smc_context[PLATFORM_CORE_COUNT]; -+ cpu_context_t saved_cpu_context[PLATFORM_CORE_COUNT]; -+ uint32_t zq0cr0_zdata; -+ struct stm32_rtc_calendar rtc; -+ uint8_t ddr_training_backup[TRAINING_AREA_SIZE]; -+#endif -+}; -+ -+#ifdef AARCH32_SP_OPTEE -+uint32_t stm32_pm_get_optee_ep(void) -+{ -+ struct backup_data_s *backup_data; -+ uint32_t ep; -+ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ /* Context & Data to be saved at the beginning of Backup SRAM */ -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ if (backup_data->magic != OPTEE_MAILBOX_MAGIC) { -+ panic(); -+ } -+ -+ ep = backup_data->core0_resume_hint; -+ -+ stm32mp_clk_disable(BKPSRAM); -+ -+ return ep; -+} -+#else /*AARCH32_SP_OPTEE*/ -+void stm32_clean_context(void) -+{ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ zeromem((void *)STM32MP_BACKUP_RAM_BASE, sizeof(struct backup_data_s)); -+ -+ stm32mp_clk_disable(BKPSRAM); -+} -+ -+int stm32_save_context(uint32_t zq0cr0_zdata) -+{ -+ void *smc_context; -+ void *cpu_context; -+ struct backup_data_s *backup_data; -+ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ /* Context & Data to be saved at the beginning of Backup SRAM */ -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ /* Retrieve smc context struct address */ -+ smc_context = smc_get_ctx(NON_SECURE); -+ -+ /* Retrieve smc context struct address */ -+ cpu_context = cm_get_context(NON_SECURE); -+ -+ /* Save context in Backup SRAM */ -+ memcpy(&backup_data->saved_smc_context[0], smc_context, -+ sizeof(smc_ctx_t) * PLATFORM_CORE_COUNT); -+ memcpy(&backup_data->saved_cpu_context[0], cpu_context, -+ sizeof(cpu_context_t) * PLATFORM_CORE_COUNT); -+ -+ backup_data->zq0cr0_zdata = zq0cr0_zdata; -+ -+ stm32_rtc_get_calendar(&backup_data->rtc); -+ -+ stm32mp_clk_disable(BKPSRAM); -+ -+ return 0; -+} -+ -+int stm32_restore_context(void) -+{ -+ void *smc_context; -+ void *cpu_context; -+ struct backup_data_s *backup_data; -+ struct stm32_rtc_calendar current_calendar; -+ unsigned long long stdby_time_in_ms; -+ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ /* Context & Data to be saved at the beginning of Backup SRAM */ -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ /* Retrieve smc context struct address */ -+ smc_context = smc_get_ctx(NON_SECURE); -+ -+ /* Retrieve smc context struct address */ -+ cpu_context = cm_get_context(NON_SECURE); -+ -+ /* Restore data from Backup SRAM */ -+ memcpy(smc_context, backup_data->saved_smc_context, -+ sizeof(smc_ctx_t) * PLATFORM_CORE_COUNT); -+ memcpy(cpu_context, backup_data->saved_cpu_context, -+ sizeof(cpu_context_t) * PLATFORM_CORE_COUNT); -+ -+ /* update STGEN counter with standby mode length */ -+ stm32_rtc_get_calendar(¤t_calendar); -+ stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, -+ &backup_data->rtc); -+ stm32mp1_stgen_increment(stdby_time_in_ms); -+ -+ stm32mp_clk_disable(BKPSRAM); -+ -+ return 0; -+} -+#endif /*AARCH32_SP_OPTEE*/ -+ -+uint32_t stm32_get_zdata_from_context(void) -+{ -+ struct backup_data_s *backup_data; -+ uint32_t zdata; -+ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ zdata = (backup_data->zq0cr0_zdata >> DDRPHYC_ZQ0CRN_ZDATA_SHIFT) & -+ DDRPHYC_ZQ0CRN_ZDATA_MASK; -+ -+ stm32mp_clk_disable(BKPSRAM); -+ -+ return zdata; -+} -+ - int stm32_save_boot_interface(uint32_t interface, uint32_t instance) - { - uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); -@@ -33,3 +185,50 @@ int stm32_save_boot_interface(uint32_t interface, uint32_t instance) - - return 0; - } -+ -+#if defined(IMAGE_BL32) -+/* -+ * When returning from STANDBY, the 64 first bytes of DDR will be overwritten -+ * during DDR DQS training. This area must then be saved before going to -+ * standby, and will be restored after -+ */ -+void stm32_save_ddr_training_area(void) -+{ -+ struct backup_data_s *backup_data; -+ int ret __unused; -+ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, -+ PAGE_SIZE, MT_MEMORY | MT_RW | MT_NS); -+ assert(ret == 0); -+ -+ memcpy(&backup_data->ddr_training_backup, -+ (const uint32_t *)STM32MP_DDR_BASE, -+ TRAINING_AREA_SIZE); -+ dsb(); -+ -+ ret = mmap_remove_dynamic_region(STM32MP_DDR_BASE, PAGE_SIZE); -+ assert(ret == 0); -+ -+ stm32mp_clk_disable(BKPSRAM); -+} -+#endif -+ -+void stm32_restore_ddr_training_area(void) -+{ -+ struct backup_data_s *backup_data; -+ -+ stm32mp_clk_enable(BKPSRAM); -+ -+ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; -+ -+ memcpy((uint32_t *)STM32MP_DDR_BASE, -+ &backup_data->ddr_training_backup, -+ TRAINING_AREA_SIZE); -+ dsb(); -+ -+ stm32mp_clk_disable(BKPSRAM); -+} -diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h -index dbe62f09d..26a194acb 100644 ---- a/plat/st/stm32mp1/stm32mp1_def.h -+++ b/plat/st/stm32mp1/stm32mp1_def.h -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #endif -@@ -58,6 +59,9 @@ - #define STM32MP_SYSRAM_BASE U(0x2FFC0000) - #define STM32MP_SYSRAM_SIZE U(0x00040000) - -+#define STM32MP_BACKUP_RAM_BASE U(0x54000000) -+#define STM32MP_BACKUP_RAM_SIZE U(0x00001000) -+ - /* DDR configuration */ - #define STM32MP_DDR_BASE U(0xC0000000) - #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ -diff --git a/plat/st/stm32mp1/stm32mp1_low_power.c b/plat/st/stm32mp1/stm32mp1_low_power.c -new file mode 100644 -index 000000000..36664c21c ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_low_power.c -@@ -0,0 +1,327 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int gicc_pmr; -+static struct stm32_rtc_calendar sleep_time, current_calendar; -+static unsigned long long stdby_time_in_ms; -+static bool enter_cstop_done; -+ -+struct pwr_lp_config { -+ uint32_t pwr_cr1; -+ uint32_t pwr_mpucr; -+ const char *regul_suspend_node_name; -+}; -+ -+#define PWR_CR1_MASK (PWR_CR1_LPDS | PWR_CR1_LPCFG | PWR_CR1_LVDS) -+#define PWR_MPUCR_MASK (PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | PWR_MPUCR_PDDS) -+ -+static const struct pwr_lp_config config_pwr[STM32_PM_MAX_SOC_MODE] = { -+ [STM32_PM_CSLEEP_RUN] = { -+ .pwr_cr1 = 0U, -+ .pwr_mpucr = PWR_MPUCR_CSSF, -+ .regul_suspend_node_name = NULL, -+ }, -+ [STM32_PM_CSTOP_ALLOW_STOP] = { -+ .pwr_cr1 = 0U, -+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF, -+ .regul_suspend_node_name = NULL, -+ }, -+ [STM32_PM_CSTOP_ALLOW_LP_STOP] = { -+ .pwr_cr1 = PWR_CR1_LPDS, -+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF, -+ .regul_suspend_node_name = "lp-stop", -+ }, -+ [STM32_PM_CSTOP_ALLOW_LPLV_STOP] = { -+ .pwr_cr1 = PWR_CR1_LVDS | PWR_CR1_LPDS | PWR_CR1_LPCFG, -+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF, -+ .regul_suspend_node_name = "lplv-stop", -+ }, -+ [STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR] = { -+ .pwr_cr1 = 0U, -+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | -+ PWR_MPUCR_PDDS, -+ .regul_suspend_node_name = "standby-ddr-sr", -+ }, -+ [STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF] = { -+ .pwr_cr1 = 0U, -+ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | -+ PWR_MPUCR_PDDS, -+ .regul_suspend_node_name = "standby-ddr-off", -+ }, -+ [STM32_PM_SHUTDOWN] = { -+ .pwr_cr1 = 0U, -+ .pwr_mpucr = 0U, -+ .regul_suspend_node_name = "standby-ddr-off", -+ }, -+}; -+ -+#define GICC_PMR_PRIORITY_8 U(0x8) -+ -+void stm32_apply_pmic_suspend_config(uint32_t mode) -+{ -+ const char *node_name = config_pwr[mode].regul_suspend_node_name; -+ -+ assert(mode < ARRAY_SIZE(config_pwr)); -+ -+ if (node_name != NULL) { -+ if (!initialize_pmic_i2c()) { -+ panic(); -+ } -+ -+ if (dt_pmic_set_lp_config(node_name) != 0) { -+ panic(); -+ } -+ -+ if (dt_pmic_configure_boot_on_regulators() != 0) { -+ panic(); -+ } -+ } -+} -+ -+/* -+ * stm32_enter_cstop - Prepare CSTOP mode -+ * -+ * @mode - Target low power mode -+ * @nsec_addr - Non secure resume entry point -+ * Return 0 if succeed to suspend, non 0 else. -+ */ -+static void enter_cstop(uint32_t mode, uint32_t nsec_addr) -+{ -+ uint32_t zq0cr0_zdata; -+ uint32_t bkpr_core1_addr = -+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); -+ uint32_t bkpr_core1_magic = -+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); -+ uint32_t pwr_cr1 = config_pwr[mode].pwr_cr1; -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ stm32mp1_syscfg_disable_io_compensation(); -+ -+ dcsw_op_all(DC_OP_CISW); -+ -+ stm32_clean_context(); -+ -+ if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { -+ /* -+ * The first 64 bytes of DDR need to be saved for DDR DQS -+ * training -+ */ -+ stm32_save_ddr_training_area(); -+ } -+ -+ if (dt_pmic_status() > 0) { -+ stm32_apply_pmic_suspend_config(mode); -+ -+ if (mode == STM32_PM_CSTOP_ALLOW_LP_STOP) { -+ pwr_cr1 |= PWR_CR1_LPCFG; -+ } -+ } -+ -+ /* Clear RCC interrupt before enabling it */ -+ mmio_setbits_32(rcc_base + RCC_MP_CIFR, RCC_MP_CIFR_WKUPF); -+ -+ /* Enable RCC Wake-up */ -+ mmio_setbits_32(rcc_base + RCC_MP_CIER, RCC_MP_CIFR_WKUPF); -+ -+ /* Configure low power mode */ -+ mmio_clrsetbits_32(pwr_base + PWR_MPUCR, PWR_MPUCR_MASK, -+ config_pwr[mode].pwr_mpucr); -+ mmio_clrsetbits_32(pwr_base + PWR_CR1, PWR_CR1_MASK, -+ pwr_cr1); -+ -+ /* Clear RCC pending interrupt flags */ -+ mmio_write_32(rcc_base + RCC_MP_CIFR, RCC_MP_CIFR_MASK); -+ -+ /* Request CSTOP mode to RCC */ -+ mmio_setbits_32(rcc_base + RCC_MP_SREQSETR, -+ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); -+ -+ stm32_iwdg_refresh(); -+ -+ gicc_pmr = plat_ic_set_priority_mask(GICC_PMR_PRIORITY_8); -+ -+ /* -+ * Set DDR in Self-refresh, even if no return address is given. -+ * This is also the procedure awaited when switching off power supply. -+ */ -+ if (ddr_standby_sr_entry(&zq0cr0_zdata) != 0) { -+ return; -+ } -+ -+ stm32mp_clk_enable(RTCAPB); -+ -+ mmio_write_32(bkpr_core1_addr, 0); -+ mmio_write_32(bkpr_core1_magic, 0); -+ -+ if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { -+ /* -+ * Save non-secure world entrypoint after standby in Backup -+ * register -+ */ -+ mmio_write_32(bkpr_core1_addr, nsec_addr); -+ mmio_write_32(bkpr_core1_magic, -+ BOOT_API_A7_CORE0_MAGIC_NUMBER); -+ -+ if (stm32_save_context(zq0cr0_zdata) != 0) { -+ panic(); -+ } -+ -+ /* Keep retention and backup RAM content in standby */ -+ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | -+ PWR_CR2_RREN); -+ while ((mmio_read_32(pwr_base + PWR_CR2) & -+ (PWR_CR2_BRRDY | PWR_CR2_RRRDY)) == 0U) { -+ ; -+ } -+ } -+ -+ stm32mp_clk_disable(RTCAPB); -+ -+ stm32_rtc_get_calendar(&sleep_time); -+ -+ enter_cstop_done = true; -+} -+ -+/* -+ * stm32_exit_cstop - Exit from CSTOP mode -+ */ -+void stm32_exit_cstop(void) -+{ -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ uintptr_t rcc_base = stm32mp_rcc_base(); -+ -+ if (!enter_cstop_done) { -+ return; -+ } -+ -+ enter_cstop_done = false; -+ -+ if (ddr_sw_self_refresh_exit() != 0) { -+ panic(); -+ } -+ -+ plat_ic_set_priority_mask(gicc_pmr); -+ -+ /* Disable RCC Wake-up */ -+ mmio_clrbits_32(rcc_base + RCC_MP_CIER, RCC_MP_CIFR_WKUPF); -+ -+ /* Disable STOP request */ -+ mmio_setbits_32(rcc_base + RCC_MP_SREQCLRR, -+ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); -+ -+ dsb(); -+ isb(); -+ -+ /* Disable retention and backup RAM content after stop */ -+ mmio_clrbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | PWR_CR2_RREN); -+ -+ /* Update STGEN counter with low power mode duration */ -+ stm32_rtc_get_calendar(¤t_calendar); -+ -+ stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, -+ &sleep_time); -+ -+ stm32mp1_stgen_increment(stdby_time_in_ms); -+ -+ stm32mp1_syscfg_enable_io_compensation(); -+} -+ -+static void enter_shutdown(void) -+{ -+ /* Set DDR in Self-refresh before shutting down the platform */ -+ if (ddr_standby_sr_entry(NULL) != 0) { -+ WARN("DDR can't be set in Self-refresh mode\n"); -+ } -+ -+ if (dt_pmic_status() > 0) { -+ if (!initialize_pmic_i2c()) { -+ panic(); -+ } -+ -+ stpmic1_switch_off(); -+ -+ udelay(100); -+ -+ /* Shouldn't be reached */ -+ panic(); -+ } -+} -+ -+static void enter_csleep(void) -+{ -+ uintptr_t pwr_base = stm32mp_pwr_base(); -+ -+ mmio_clrsetbits_32(pwr_base + PWR_MPUCR, PWR_MPUCR_MASK, -+ config_pwr[STM32_PM_CSLEEP_RUN].pwr_mpucr); -+ mmio_clrsetbits_32(pwr_base + PWR_CR1, PWR_CR1_MASK, -+ config_pwr[STM32_PM_CSLEEP_RUN].pwr_cr1); -+ -+ stm32_pwr_down_wfi(); -+} -+ -+void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr) -+{ -+ switch (mode) { -+ case STM32_PM_SHUTDOWN: -+ enter_shutdown(); -+ break; -+ -+ case STM32_PM_CSLEEP_RUN: -+ enter_csleep(); -+ break; -+ -+ default: -+ enter_cstop(mode, nsec_addr); -+ break; -+ } -+} -+ -+void stm32_pwr_down_wfi(void) -+{ -+ uint32_t interrupt = GIC_SPURIOUS_INTERRUPT; -+ -+ while (interrupt == GIC_SPURIOUS_INTERRUPT) { -+ wfi(); -+ -+ interrupt = gicv2_acknowledge_interrupt(); -+ -+ if (interrupt != GIC_SPURIOUS_INTERRUPT) { -+ gicv2_end_of_interrupt(interrupt); -+ } -+ -+ stm32_iwdg_refresh(); -+ } -+} -diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c -index cf9fa8e69..9ebea40f1 100644 ---- a/plat/st/stm32mp1/stm32mp1_pm.c -+++ b/plat/st/stm32mp1/stm32mp1_pm.c -@@ -13,14 +13,20 @@ - #include - #include - #include -+#include - #include -+#include - #include - #include - #include - #include - -+#include -+#include -+ - static uintptr_t stm32_sec_entrypoint; - static uint32_t cntfrq_core0; -+static uintptr_t saved_entrypoint; - - /******************************************************************************* - * STM32MP1 handler called when a CPU is about to enter standby. -@@ -33,11 +39,12 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state) - assert(cpu_state == ARM_LOCAL_STATE_RET); - - /* -- * Enter standby state -- * dsb is good practice before using wfi to enter low power states -+ * Enter standby state. -+ * Synchronize on memory accesses and instruction flow before the WFI -+ * instruction. - */ -- isb(); - dsb(); -+ isb(); - while (interrupt == GIC_SPURIOUS_INTERRUPT) { - wfi(); - -@@ -64,10 +71,23 @@ static int stm32_pwr_domain_on(u_register_t mpidr) - uint32_t bkpr_core1_magic = - tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); - -+ if (stm32mp_is_single_core()) { -+ return PSCI_E_INTERN_FAIL; -+ } -+ - if (mpidr == current_cpu_mpidr) { - return PSCI_E_INVALID_PARAMS; - } - -+ /* Reset backup register content */ -+ mmio_write_32(bkpr_core1_magic, 0); -+ -+ /* Need to send additional IT 0 after individual core 1 reset */ -+ gicv2_raise_sgi(ARM_IRQ_NON_SEC_SGI_0, STM32MP_SECONDARY_CPU); -+ -+ /* Wait for this IT to be acknowledged by ROM code. */ -+ udelay(10); -+ - if ((stm32_sec_entrypoint < STM32MP_SYSRAM_BASE) || - (stm32_sec_entrypoint > (STM32MP_SYSRAM_BASE + - (STM32MP_SYSRAM_SIZE - 1)))) { -@@ -107,7 +127,9 @@ static void stm32_pwr_domain_off(const psci_power_state_t *target_state) - ******************************************************************************/ - static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) - { -- /* Nothing to do, power domain is not disabled */ -+ uint32_t soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_SUSPEND); -+ -+ stm32_enter_low_power(soc_mode, saved_entrypoint); - } - - /******************************************************************************* -@@ -134,16 +156,59 @@ static void stm32_pwr_domain_suspend_finish(const psci_power_state_t - /* Nothing to do, power domain is not disabled */ - } - -+/******************************************************************************* -+ * STM32MP1 handler called when a core tries to power itself down. If this -+ * call is made by core 0, it is a return from stop mode. In this case, we -+ * should restore previous context and jump to secure entrypoint. -+ ******************************************************************************/ - static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t - *target_state) - { -- ERROR("stm32mpu1 Power Down WFI: operation not handled.\n"); -+ if (MPIDR_AFFLVL0_VAL(read_mpidr_el1()) == STM32MP_PRIMARY_CPU) { -+ void (*warm_entrypoint)(void) = -+ (void (*)(void))stm32_sec_entrypoint; -+ -+ stm32_pwr_down_wfi(); -+ -+ stm32_exit_cstop(); -+ -+ disable_mmu_icache_secure(); -+ -+ warm_entrypoint(); -+ } -+ -+ mmio_write_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, -+ RCC_MP_GRSTCSETR_MPUP1RST); -+ -+ /* -+ * Synchronize on memory accesses and instruction flow before -+ * auto-reset from the WFI instruction. -+ */ -+ dsb(); -+ isb(); -+ wfi(); -+ -+ /* This shouldn't be reached */ - panic(); - } - - static void __dead2 stm32_system_off(void) - { -- ERROR("stm32mpu1 System Off: operation not handled.\n"); -+ uint32_t soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_OFF); -+ -+ if (!stm32mp_is_single_core()) { -+ /* Prepare Core 1 reset */ -+ mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, -+ RCC_MP_GRSTCSETR_MPUP1RST); -+ /* Send IT to core 1 to put itself in WFI */ -+ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_1, STM32MP_SECONDARY_CPU); -+ } -+ -+ stm32_enter_low_power(soc_mode, 0); -+ -+ stm32_pwr_down_wfi(); -+ -+ /* This shouldn't be reached */ - panic(); - } - -@@ -188,6 +253,8 @@ static int stm32_validate_ns_entrypoint(uintptr_t entrypoint) - return PSCI_E_INVALID_ADDRESS; - } - -+ saved_entrypoint = entrypoint; -+ - return PSCI_E_SUCCESS; - } - -@@ -211,6 +278,12 @@ static int stm32_node_hw_state(u_register_t target_cpu, - return (int)HW_ON; - } - -+static void stm32_get_sys_suspend_power_state(psci_power_state_t *req_state) -+{ -+ req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_OFF; -+ req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_OFF; -+} -+ - /******************************************************************************* - * Export the platform handlers. The ARM Standard platform layer will take care - * of registering the handlers with PSCI. -@@ -227,7 +300,8 @@ static const plat_psci_ops_t stm32_psci_ops = { - .system_reset = stm32_system_reset, - .validate_power_state = stm32_validate_power_state, - .validate_ns_entrypoint = stm32_validate_ns_entrypoint, -- .get_node_hw_state = stm32_node_hw_state -+ .get_node_hw_state = stm32_node_hw_state, -+ .get_sys_suspend_power_state = stm32_get_sys_suspend_power_state, - }; - - /******************************************************************************* -diff --git a/plat/st/stm32mp1/stm32mp1_power_config.c b/plat/st/stm32mp1/stm32mp1_power_config.c -new file mode 100644 -index 000000000..93644f4ea ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_power_config.c -@@ -0,0 +1,130 @@ -+/* -+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+#define DT_PWR_COMPAT "st,stm32mp1-pwr" -+#define SYSTEM_SUSPEND_SUPPORTED_MODES "system_suspend_supported_soc_modes" -+#define SYSTEM_OFF_MODE "system_off_soc_mode" -+ -+static uint32_t deepest_system_suspend_mode; -+static uint32_t system_off_mode; -+static uint8_t stm32mp1_supported_soc_modes[STM32_PM_MAX_SOC_MODE]; -+ -+static int dt_get_pwr_node(void *fdt) -+{ -+ return fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); -+} -+ -+static void save_supported_mode(void *fdt, int pwr_node) -+{ -+ int len; -+ uint32_t count; -+ unsigned int i; -+ uint32_t supported[ARRAY_SIZE(stm32mp1_supported_soc_modes)]; -+ const void *prop; -+ -+ prop = fdt_getprop(fdt, pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, &len); -+ if (prop == NULL) { -+ panic(); -+ } -+ -+ count = (uint32_t)len / sizeof(uint32_t); -+ if (count > STM32_PM_MAX_SOC_MODE) { -+ panic(); -+ } -+ -+ if (fdt_read_uint32_array(pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, -+ &supported[0], count) < 0) { -+ ERROR("PWR DT\n"); -+ panic(); -+ } -+ -+ for (i = 0; i < count; i++) { -+ if (supported[i] >= STM32_PM_MAX_SOC_MODE) { -+ ERROR("Invalid mode\n"); -+ panic(); -+ } -+ stm32mp1_supported_soc_modes[supported[i]] = 1U; -+ } -+ -+ /* Initialize to deepest possible mode */ -+ for (i = STM32_PM_MAX_SOC_MODE - 1U; i != STM32_PM_CSLEEP_RUN; i--) { -+ if (stm32mp1_supported_soc_modes[i] == 1U) { -+ deepest_system_suspend_mode = i; -+ break; -+ } -+ } -+} -+ -+static int dt_fill_lp_state(uint32_t *lp_state_config, const char *lp_state) -+{ -+ int pwr_node; -+ void *fdt; -+ const fdt32_t *cuint; -+ -+ if (fdt_get_address(&fdt) == 0) { -+ return -ENOENT; -+ } -+ -+ pwr_node = dt_get_pwr_node(fdt); -+ if (pwr_node < 0) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ cuint = fdt_getprop(fdt, pwr_node, lp_state, NULL); -+ if (cuint == NULL) { -+ return -FDT_ERR_NOTFOUND; -+ } -+ -+ *lp_state_config = fdt32_to_cpu(*cuint); -+ -+ save_supported_mode(fdt, pwr_node); -+ -+ return 0; -+} -+ -+void stm32mp1_init_lp_states(void) -+{ -+ if (dt_fill_lp_state(&system_off_mode, SYSTEM_OFF_MODE) < 0) { -+ ERROR("Node %s not found\n", SYSTEM_OFF_MODE); -+ panic(); -+ } -+} -+ -+static bool is_allowed_mode(uint32_t soc_mode) -+{ -+ assert(soc_mode < ARRAY_SIZE(stm32mp1_supported_soc_modes)); -+ -+ return stm32mp1_supported_soc_modes[soc_mode] == 1U; -+} -+ -+uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode) -+{ -+ uint32_t mode; -+ -+ if (psci_mode == PSCI_MODE_SYSTEM_OFF) { -+ return system_off_mode; -+ } -+ -+ mode = deepest_system_suspend_mode; -+ -+ while ((mode > STM32_PM_CSLEEP_RUN) && !is_allowed_mode(mode)) { -+ mode--; -+ } -+ -+ return mode; -+} -diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c -index e2dcd2af7..3a7b22e37 100644 ---- a/plat/st/stm32mp1/stm32mp1_private.c -+++ b/plat/st/stm32mp1/stm32mp1_private.c -@@ -10,8 +10,11 @@ - - #include - -+#include -+#include - #include - #include -+#include - - /* Internal layout of the 32bit OTP word board_id */ - #define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16) -@@ -76,6 +79,42 @@ void configure_mmu(void) - enable_mmu_svc_mon(0); - } - -+#define ARM_CNTXCTL_IMASK BIT(1) -+ -+void stm32mp_mask_timer(void) -+{ -+ /* Mask timer interrupts */ -+ write_cntp_ctl(read_cntp_ctl() | ARM_CNTXCTL_IMASK); -+ write_cntv_ctl(read_cntv_ctl() | ARM_CNTXCTL_IMASK); -+} -+ -+void __dead2 stm32mp_wait_cpu_reset(void) -+{ -+ uint32_t id; -+ -+ dcsw_op_all(DC_OP_CISW); -+ write_sctlr(read_sctlr() & ~SCTLR_C_BIT); -+ dcsw_op_all(DC_OP_CISW); -+ __asm__("clrex"); -+ -+ dsb(); -+ isb(); -+ -+ for ( ; ; ) { -+ do { -+ id = plat_ic_get_pending_interrupt_id(); -+ -+ if (id <= MAX_SPI_ID) { -+ gicv2_end_of_interrupt(id); -+ -+ plat_ic_disable_interrupt(id); -+ } -+ } while (id <= MAX_SPI_ID); -+ -+ wfi(); -+ } -+} -+ - unsigned long stm32_get_gpio_bank_clock(unsigned int bank) - { - if (bank == GPIO_BANK_Z) { -diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c.bak b/plat/st/stm32mp1/stm32mp1_shared_resources.c.bak -new file mode 100644 -index 000000000..208e34a8b ---- /dev/null -+++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c.bak -@@ -0,0 +1,597 @@ -+/* -+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved -+ * -+ * SPDX-License-Identifier: BSD-3-Clause -+ */ -+ -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+/* -+ * Once one starts to get the resource registering state, one cannot register -+ * new resources. This ensures resource state cannot change. -+ */ -+static bool registering_locked; -+ -+/* -+ * Shared peripherals and resources registration -+ * -+ * Each resource assignation is stored in a table. The state defaults -+ * to PERIPH_UNREGISTERED if the resource is not explicitly assigned. -+ * -+ * Resource driver that as not embedded (a.k.a their related CFG_xxx build -+ * directive is disabled) are assigned to the non-secure world. -+ * -+ * Each pin of the GPIOZ bank can be secure or non-secure. -+ * -+ * It is the platform responsibility the ensure resource assignation -+ * matches the access permission firewalls configuration. -+ */ -+enum shres_state { -+ SHRES_UNREGISTERED = 0, -+ SHRES_SECURE, -+ SHRES_NON_SECURE, -+}; -+ -+/* Force uint8_t array for array of enum shres_state for size considerations */ -+static uint8_t shres_state[STM32MP1_SHRES_COUNT]; -+ -+static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = { -+ [STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0", -+ [STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1", -+ [STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2", -+ [STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3", -+ [STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4", -+ [STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5", -+ [STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6", -+ [STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7", -+ [STM32MP1_SHRES_IWDG1] = "IWDG1", -+ [STM32MP1_SHRES_USART1] = "USART1", -+ [STM32MP1_SHRES_SPI6] = "SPI6", -+ [STM32MP1_SHRES_I2C4] = "I2C4", -+ [STM32MP1_SHRES_RNG1] = "RNG1", -+ [STM32MP1_SHRES_HASH1] = "HASH1", -+ [STM32MP1_SHRES_CRYP1] = "CRYP1", -+ [STM32MP1_SHRES_I2C6] = "I2C6", -+ [STM32MP1_SHRES_RTC] = "RTC", -+ [STM32MP1_SHRES_MCU] = "MCU", -+ [STM32MP1_SHRES_MDMA] = "MDMA", -+ [STM32MP1_SHRES_PLL3] = "PLL3", -+}; -+ -+static const char __unused *shres2str_id(enum stm32mp_shres id) -+{ -+ assert(id < ARRAY_SIZE(shres2str_id_tbl)); -+ -+ return shres2str_id_tbl[id]; -+} -+ -+static const char __unused *shres2str_state_tbl[] = { -+ [SHRES_UNREGISTERED] = "unregistered", -+ [SHRES_NON_SECURE] = "non-secure", -+ [SHRES_SECURE] = "secure", -+}; -+ -+static const char __unused *shres2str_state(unsigned int state) -+{ -+ assert(state < ARRAY_SIZE(shres2str_state_tbl)); -+ -+ return shres2str_state_tbl[state]; -+} -+ -+/* Get resource state: these accesses lock the registering support */ -+static void lock_registering(void) -+{ -+ registering_locked = true; -+} -+ -+static bool periph_is_non_secure(enum stm32mp_shres id) -+{ -+ lock_registering(); -+ -+ return (shres_state[id] == SHRES_NON_SECURE) || -+ (shres_state[id] == SHRES_UNREGISTERED); -+} -+ -+static bool periph_is_secure(enum stm32mp_shres id) -+{ -+ return !periph_is_non_secure(id); -+} -+ -+/* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */ -+static int8_t gpioz_nbpin = -1; -+ -+static unsigned int get_gpio_nbpin(unsigned int bank) -+{ -+ if (bank != GPIO_BANK_Z) { -+ int count = fdt_get_gpio_bank_pin_count(bank); -+ -+ assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1))); -+ -+ return (unsigned int)count; -+ } -+ -+ if (gpioz_nbpin < 0) { -+ int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z); -+ -+ assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT)); -+ -+ gpioz_nbpin = count; -+ } -+ -+ return (unsigned int)gpioz_nbpin; -+} -+ -+static unsigned int get_gpioz_nbpin(void) -+{ -+ return get_gpio_nbpin(GPIO_BANK_Z); -+} -+ -+static void register_periph(enum stm32mp_shres id, unsigned int state) -+{ -+ assert((id < STM32MP1_SHRES_COUNT) && -+ ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE))); -+ -+ if (registering_locked) { -+ if (shres_state[id] == state) { -+ return; -+ } -+ panic(); -+ } -+ -+ if ((shres_state[id] != SHRES_UNREGISTERED) && -+ (shres_state[id] != state)) { -+ VERBOSE("Cannot change %s from %s to %s\n", -+ shres2str_id(id), -+ shres2str_state(shres_state[id]), -+ shres2str_state(state)); -+ panic(); -+ } -+ -+ if (shres_state[id] == SHRES_UNREGISTERED) { -+ VERBOSE("Register %s as %s\n", -+ shres2str_id(id), shres2str_state(state)); -+ } -+ -+ if ((id >= STM32MP1_SHRES_GPIOZ(0)) && -+ (id <= STM32MP1_SHRES_GPIOZ(7)) && -+ ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) { -+ ERROR("Invalid GPIO pin %u, %u pin(s) available\n", -+ id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin()); -+ panic(); -+ } -+ -+ shres_state[id] = (uint8_t)state; -+ -+ /* Explore clock tree to lock dependencies */ -+ if (state == SHRES_SECURE) { -+ enum stm32mp_shres clock_res_id; -+ -+ switch (id) { -+ case STM32MP1_SHRES_GPIOZ(0): -+ case STM32MP1_SHRES_GPIOZ(1): -+ case STM32MP1_SHRES_GPIOZ(2): -+ case STM32MP1_SHRES_GPIOZ(3): -+ case STM32MP1_SHRES_GPIOZ(4): -+ case STM32MP1_SHRES_GPIOZ(5): -+ case STM32MP1_SHRES_GPIOZ(6): -+ case STM32MP1_SHRES_GPIOZ(7): -+ clock_res_id = GPIOZ; -+ break; -+ case STM32MP1_SHRES_IWDG1: -+ clock_res_id = IWDG1; -+ break; -+ case STM32MP1_SHRES_USART1: -+ clock_res_id = USART1_K; -+ break; -+ case STM32MP1_SHRES_SPI6: -+ clock_res_id = SPI6_K; -+ break; -+ case STM32MP1_SHRES_I2C4: -+ clock_res_id = I2C4_K; -+ break; -+ case STM32MP1_SHRES_RNG1: -+ clock_res_id = RNG1_K; -+ break; -+ case STM32MP1_SHRES_HASH1: -+ clock_res_id = HASH1; -+ break; -+ case STM32MP1_SHRES_CRYP1: -+ clock_res_id = CRYP1; -+ break; -+ case STM32MP1_SHRES_I2C6: -+ clock_res_id = I2C6_K; -+ break; -+ case STM32MP1_SHRES_RTC: -+ clock_res_id = RTC; -+ break; -+ default: -+ /* No clock resource dependency */ -+ return; -+ } -+ -+ stm32mp1_register_clock_parents_secure(clock_res_id); -+ } -+} -+ -+/* Register resource by ID */ -+void stm32mp_register_secure_periph(enum stm32mp_shres id) -+{ -+ register_periph(id, SHRES_SECURE); -+} -+ -+void stm32mp_register_non_secure_periph(enum stm32mp_shres id) -+{ -+ register_periph(id, SHRES_NON_SECURE); -+} -+ -+static void register_periph_iomem(uintptr_t base, unsigned int state) -+{ -+ enum stm32mp_shres id; -+ -+ switch (base) { -+ case CRYP1_BASE: -+ id = STM32MP1_SHRES_CRYP1; -+ break; -+ case HASH1_BASE: -+ id = STM32MP1_SHRES_HASH1; -+ break; -+ case I2C4_BASE: -+ id = STM32MP1_SHRES_I2C4; -+ break; -+ case I2C6_BASE: -+ id = STM32MP1_SHRES_I2C6; -+ break; -+ case IWDG1_BASE: -+ id = STM32MP1_SHRES_IWDG1; -+ break; -+ case RNG1_BASE: -+ id = STM32MP1_SHRES_RNG1; -+ break; -+ case RTC_BASE: -+ id = STM32MP1_SHRES_RTC; -+ break; -+ case SPI6_BASE: -+ id = STM32MP1_SHRES_SPI6; -+ break; -+ case USART1_BASE: -+ id = STM32MP1_SHRES_USART1; -+ break; -+ -+ case GPIOA_BASE: -+ case GPIOB_BASE: -+ case GPIOC_BASE: -+ case GPIOD_BASE: -+ case GPIOE_BASE: -+ case GPIOF_BASE: -+ case GPIOG_BASE: -+ case GPIOH_BASE: -+ case GPIOI_BASE: -+ case GPIOJ_BASE: -+ case GPIOK_BASE: -+ case USART2_BASE: -+ case USART3_BASE: -+ case UART4_BASE: -+ case UART5_BASE: -+ case USART6_BASE: -+ case UART7_BASE: -+ case UART8_BASE: -+ case IWDG2_BASE: -+ /* Allow drivers to register some non-secure resources */ -+ VERBOSE("IO for non-secure resource 0x%x\n", -+ (unsigned int)base); -+ if (state != SHRES_NON_SECURE) { -+ panic(); -+ } -+ -+ return; -+ -+ default: -+ panic(); -+ } -+ -+ register_periph(id, state); -+} -+ -+void stm32mp_register_secure_periph_iomem(uintptr_t base) -+{ -+ register_periph_iomem(base, SHRES_SECURE); -+} -+ -+void stm32mp_register_non_secure_periph_iomem(uintptr_t base) -+{ -+ register_periph_iomem(base, SHRES_NON_SECURE); -+} -+ -+void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin) -+{ -+ switch (bank) { -+ case GPIO_BANK_Z: -+ register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE); -+ break; -+ default: -+ ERROR("GPIO bank %u cannot be secured\n", bank); -+ panic(); -+ } -+} -+ -+void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) -+{ -+ switch (bank) { -+ case GPIO_BANK_Z: -+ register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE); -+ break; -+ default: -+ break; -+ } -+} -+ -+static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) -+{ -+ unsigned int non_secure = 0U; -+ unsigned int i; -+ -+ lock_registering(); -+ -+ if (bank != GPIO_BANK_Z) { -+ return true; -+ } -+ -+ for (i = 0U; i < get_gpioz_nbpin(); i++) { -+ if (periph_is_non_secure(STM32MP1_SHRES_GPIOZ(i))) { -+ non_secure++; -+ } -+ } -+ -+ return non_secure == get_gpioz_nbpin(); -+} -+ -+static bool stm32mp_gpio_bank_is_secure(unsigned int bank) -+{ -+ unsigned int secure = 0U; -+ unsigned int i; -+ -+ lock_registering(); -+ -+ if (bank != GPIO_BANK_Z) { -+ return false; -+ } -+ -+ for (i = 0U; i < get_gpioz_nbpin(); i++) { -+ if (periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) { -+ secure++; -+ } -+ } -+ -+ return secure == get_gpioz_nbpin(); -+} -+ -+bool stm32mp_nsec_can_access_clock(unsigned long clock_id) -+{ -+ enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; -+ -+ switch (clock_id) { -+ case CK_CSI: -+ case CK_HSE: -+ case CK_HSE_DIV2: -+ case CK_HSI: -+ case CK_LSE: -+ case CK_LSI: -+ case PLL1_P: -+ case PLL1_Q: -+ case PLL1_R: -+ case PLL2_P: -+ case PLL2_Q: -+ case PLL2_R: -+ case PLL3_P: -+ case PLL3_Q: -+ case PLL3_R: -+ case RTCAPB: -+ return true; -+ case GPIOZ: -+ /* Allow clock access if at least one pin is non-secure */ -+ return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z); -+ case CRYP1: -+ shres_id = STM32MP1_SHRES_CRYP1; -+ break; -+ case HASH1: -+ shres_id = STM32MP1_SHRES_HASH1; -+ break; -+ case I2C4_K: -+ shres_id = STM32MP1_SHRES_I2C4; -+ break; -+ case I2C6_K: -+ shres_id = STM32MP1_SHRES_I2C6; -+ break; -+ case IWDG1: -+ shres_id = STM32MP1_SHRES_IWDG1; -+ break; -+ case RNG1_K: -+ shres_id = STM32MP1_SHRES_RNG1; -+ break; -+ case RTC: -+ shres_id = STM32MP1_SHRES_RTC; -+ break; -+ case SPI6_K: -+ shres_id = STM32MP1_SHRES_SPI6; -+ break; -+ case USART1_K: -+ shres_id = STM32MP1_SHRES_USART1; -+ break; -+ default: -+ return false; -+ } -+ -+ return periph_is_non_secure(shres_id); -+} -+ -+bool stm32mp_nsec_can_access_reset(unsigned int reset_id) -+{ -+ enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; -+ -+ switch (reset_id) { -+ case CRYP1_R: -+ shres_id = STM32MP1_SHRES_CRYP1; -+ break; -+ case GPIOZ_R: -+ /* GPIOZ reset mandates all pins are non-secure */ -+ return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z); -+ case HASH1_R: -+ shres_id = STM32MP1_SHRES_HASH1; -+ break; -+ case I2C4_R: -+ shres_id = STM32MP1_SHRES_I2C4; -+ break; -+ case I2C6_R: -+ shres_id = STM32MP1_SHRES_I2C6; -+ break; -+ case MCU_R: -+ shres_id = STM32MP1_SHRES_MCU; -+ break; -+ case MDMA_R: -+ shres_id = STM32MP1_SHRES_MDMA; -+ break; -+ case RNG1_R: -+ shres_id = STM32MP1_SHRES_RNG1; -+ break; -+ case SPI6_R: -+ shres_id = STM32MP1_SHRES_SPI6; -+ break; -+ case USART1_R: -+ shres_id = STM32MP1_SHRES_USART1; -+ break; -+ default: -+ return false; -+ } -+ -+ return periph_is_non_secure(shres_id); -+} -+ -+static bool mckprot_protects_periph(enum stm32mp_shres id) -+{ -+ switch (id) { -+ case STM32MP1_SHRES_MCU: -+ case STM32MP1_SHRES_PLL3: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+/* ETZPC configuration at drivers initialization completion */ -+static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id) -+{ -+ assert((id < STM32MP1_SHRES_GPIOZ(0)) || -+ (id > STM32MP1_SHRES_GPIOZ(7))); -+ -+ if (periph_is_non_secure(id)) { -+ return ETZPC_DECPROT_NS_RW; -+ } -+ -+ return ETZPC_DECPROT_S_RW; -+} -+ -+static void set_etzpc_secure_configuration(void) -+{ -+ /* Some system peripherals shall be secure */ -+ etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); -+ etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); -+ etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID, -+ ETZPC_DECPROT_NS_R_S_W); -+ etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID, -+ ETZPC_DECPROT_NS_R_S_W); -+ -+ /* Configure ETZPC with peripheral registering */ -+ etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID, -+ shres2decprot_attr(STM32MP1_SHRES_CRYP1)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID, -+ shres2decprot_attr(STM32MP1_SHRES_HASH1)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID, -+ shres2decprot_attr(STM32MP1_SHRES_I2C4)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID, -+ shres2decprot_attr(STM32MP1_SHRES_I2C6)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID, -+ shres2decprot_attr(STM32MP1_SHRES_IWDG1)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID, -+ shres2decprot_attr(STM32MP1_SHRES_RNG1)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID, -+ shres2decprot_attr(STM32MP1_SHRES_USART1)); -+ etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID, -+ shres2decprot_attr(STM32MP1_SHRES_SPI6)); -+} -+ -+static void check_rcc_secure_configuration(void) -+{ -+ uint32_t n; -+ uint32_t error = 0U; -+ bool mckprot = stm32mp1_rcc_is_mckprot(); -+ bool secure = stm32mp1_rcc_is_secure(); -+ -+ for (n = 0U; n < ARRAY_SIZE(shres_state); n++) { -+ if (shres_state[n] != SHRES_SECURE) { -+ continue; -+ } -+ -+ if (!secure || (mckprot_protects_periph(n) && (!mckprot))) { -+ ERROR("RCC %s MCKPROT %s and %s secure\n", -+ secure ? "secure" : "non-secure", -+ mckprot ? "set" : "not set", -+ shres2str_id(n)); -+ error++; -+ } -+ } -+ -+ if (error != 0U) { -+ panic(); -+ } -+} -+ -+static void set_gpio_secure_configuration(void) -+{ -+ uint32_t pin; -+ -+ for (pin = 0U; pin < get_gpioz_nbpin(); pin++) { -+ bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin)); -+ -+ set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state); -+ } -+} -+ -+static void print_shared_resources_state(void) -+{ -+ unsigned int id; -+ -+ for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) { -+ switch (shres_state[id]) { -+ case SHRES_SECURE: -+ INFO("stm32mp1 %s is secure\n", shres2str_id(id)); -+ break; -+ case SHRES_NON_SECURE: -+ case SHRES_UNREGISTERED: -+ VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id)); -+ break; -+ default: -+ VERBOSE("stm32mp %s is invalid\n", shres2str_id(id)); -+ panic(); -+ } -+ } -+} -+ -+void stm32mp_lock_periph_registering(void) -+{ -+ registering_locked = true; -+ -+ print_shared_resources_state(); -+ -+ check_rcc_secure_configuration(); -+ set_etzpc_secure_configuration(); -+ set_gpio_secure_configuration(); -+} --- -2.27.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0008-fix-for-ethernet.patch b/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0008-fix-for-ethernet.patch deleted file mode 100644 index e4f6cbb..0000000 --- a/board/myna-player-odyssey/initramfs_patches/arm-trusted-firmware/0008-fix-for-ethernet.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts -index 2eced8f53..e5b092be1 100644 ---- a/fdts/stm32mp157a-dk1.dts -+++ b/fdts/stm32mp157a-dk1.dts -@@ -245,7 +245,7 @@ - CLK_CKPER_HSE - CLK_FMC_ACLK - CLK_QSPI_ACLK -- CLK_ETH_DISABLED -+ CLK_ETH_PLL4P - CLK_SDMMC12_PLL4P - CLK_DSI_DSIPLL - CLK_STGEN_HSE -@@ -297,10 +297,15 @@ - frac = < 0x1a04 >; - }; - -- /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ -+ /* -+ * ETH_CLK required a 125MHz clock, so -+ * original: VCO = 594.0 MHz => P = 99, Q = 74, R = 74 -+ * current : VCO = 750.0 MHz => P =125, Q = 75, R = 75 -+ */ - pll4: st,pll@3 { -- cfg = < 3 98 5 7 7 PQR(1,1,1) >; -+ cfg = < 3 124 5 11 11 PQR(1,1,1) >; - }; -+ - }; - - &bsec { diff --git a/board/myna-player-odyssey/initramfs_patches/barebox/0001-dts-stm32mp157c-odyssey-add-partitions-and-state-framework-support.patch b/board/myna-player-odyssey/initramfs_patches/barebox/0001-dts-stm32mp157c-odyssey-add-partitions-and-state-framework-support.patch deleted file mode 100644 index a7137db..0000000 --- a/board/myna-player-odyssey/initramfs_patches/barebox/0001-dts-stm32mp157c-odyssey-add-partitions-and-state-framework-support.patch +++ /dev/null @@ -1,99 +0,0 @@ -From f2c72e8b170f05390896fc845f28ca77dd8ee658 Mon Sep 17 00:00:00 2001 -From: Xogium -Date: Wed, 29 Jul 2020 23:41:35 +0200 -Subject: [PATCH 1/4] dts: stm32mp157c-odyssey: add partitions and state - framework support. - ---- - arch/arm/dts/stm32mp157c-odyssey.dts | 68 ++++++++++++++++++++++++++++ - 1 file changed, 68 insertions(+) - -diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts -index 0e395bdec..8b570443b 100644 ---- a/arch/arm/dts/stm32mp157c-odyssey.dts -+++ b/arch/arm/dts/stm32mp157c-odyssey.dts -@@ -7,6 +7,10 @@ - #include "stm32mp151.dtsi" - - / { -+ aliases { -+ state = &state; -+ }; -+ - chosen { - environment-sd { - compatible = "barebox,environment"; -@@ -19,6 +23,70 @@ - device-path = &sdmmc2, "partname:barebox-environment"; - status = "disabled"; - }; -+ -+ state: state { -+ magic = <0x12222013>; -+ compatible = "barebox,state"; -+ backend-type = "raw"; -+ backend = <&state_mmc>; -+ backend-stridesize = <1024>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ bootstate { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ system0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ remaining_attempts { -+ reg = <0x0 0x4>; -+ type = "uint32"; -+ default = <3>; -+ }; -+ priority { -+ reg = <0x4 0x4>; -+ type = "uint32"; -+ default = <21>; -+ }; -+ }; -+ system1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ remaining_attempts { -+ reg = <0x10 0x4>; -+ type = "uint32"; -+ default = <3>; -+ }; -+ priority { -+ reg = <0x14 0x4>; -+ type = "uint32"; -+ default = <20>; -+ }; -+ }; -+ }; -+ last_chosen { -+ reg = <0x20 0x4>; -+ type = "uint32"; -+ }; -+ }; -+ }; -+}; -+ -+&sdmmc2 { -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ #size-cells = <1>; -+ #address-cells = <1>; -+ -+ state_mmc: partition@14400 { -+ label = "state"; -+ reg = <0x14400 0x30000>; -+ }; - }; - }; - --- -2.28.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/barebox/0001-dts-stm32mp157c-odyssey-fix-location-of-last_chosen.patch b/board/myna-player-odyssey/initramfs_patches/barebox/0001-dts-stm32mp157c-odyssey-fix-location-of-last_chosen.patch deleted file mode 100644 index 6e16fd8..0000000 --- a/board/myna-player-odyssey/initramfs_patches/barebox/0001-dts-stm32mp157c-odyssey-fix-location-of-last_chosen.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 09d292d3a1cc99047a98916a1aad8ece2ce18954 Mon Sep 17 00:00:00 2001 -From: Xogium -Date: Sun, 2 Aug 2020 12:49:35 +0200 -Subject: [PATCH 4/4] dts: stm32mp157c-odyssey.dts: fix location of last_chosen - node. - ---- - arch/arm/dts/stm32mp157c-odyssey.dts | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts -index 182a5149d..1e2510cdc 100644 ---- a/arch/arm/dts/stm32mp157c-odyssey.dts -+++ b/arch/arm/dts/stm32mp157c-odyssey.dts -@@ -67,10 +67,10 @@ - default = <20>; - }; - }; -- }; -- last_chosen { -- reg = <0x20 0x4>; -- type = "uint32"; -+ last_chosen { -+ reg = <0x20 0x4>; -+ type = "uint32"; -+ }; - }; - }; - }; --- -2.28.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/barebox/0002-Revert-fs-free-inodes-we-no-longer-need.patch b/board/myna-player-odyssey/initramfs_patches/barebox/0002-Revert-fs-free-inodes-we-no-longer-need.patch deleted file mode 100644 index 21836a5..0000000 --- a/board/myna-player-odyssey/initramfs_patches/barebox/0002-Revert-fs-free-inodes-we-no-longer-need.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 3eabdda706a8124e90cc1b2e6af918e6439dee6b Mon Sep 17 00:00:00 2001 -From: Jookia -Date: Tue, 4 Aug 2020 10:21:11 +1000 -Subject: [PATCH 2/4] Revert "fs: free inodes we no longer need" - -This reverts commit 43902e57633f5dd9bc71f1a30d69d7bc0f49dc6b. ---- - fs/fs.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/fs/fs.c b/fs/fs.c -index e04cadfe5..cecb3d70e 100644 ---- a/fs/fs.c -+++ b/fs/fs.c -@@ -1090,12 +1090,10 @@ void iput(struct inode *inode) - if (!inode) - return; - -- inode->i_count--; -+ if (!inode->i_count) -+ return; - -- if (!inode->i_count) { -- list_del(&inode->i_sb_list); -- destroy_inode(inode); -- } -+ inode->i_count--; - } - - struct inode *iget(struct inode *inode) --- -2.28.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/barebox/0003-dts-stm32mp157c-odyssey-Add-Ethernet-support.patch b/board/myna-player-odyssey/initramfs_patches/barebox/0003-dts-stm32mp157c-odyssey-Add-Ethernet-support.patch deleted file mode 100644 index cfffbb2..0000000 --- a/board/myna-player-odyssey/initramfs_patches/barebox/0003-dts-stm32mp157c-odyssey-Add-Ethernet-support.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5011a3d9cbfa734a34718cc2471ef481550b3032 Mon Sep 17 00:00:00 2001 -From: Jookia -Date: Tue, 4 Aug 2020 10:21:47 +1000 -Subject: [PATCH 3/4] dts: stm32mp157c-odyssey: Add Ethernet support - -This uses PLL4_P as the internal Ethernet clock, so ATF or U-Boot must -clock PLL4 to 750MHz for this to work. ---- - arch/arm/dts/stm32mp157c-odyssey.dts | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts -index 8b570443b..182a5149d 100644 ---- a/arch/arm/dts/stm32mp157c-odyssey.dts -+++ b/arch/arm/dts/stm32mp157c-odyssey.dts -@@ -93,3 +93,29 @@ - &phy0 { - reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; - }; -+ -+ðernet0 { -+ status = "okay"; -+ pinctrl-0 = <ðernet0_rgmii_pins_a>; -+ pinctrl-1 = <ðernet0_rgmii_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; -+ phy-mode = "rgmii-id"; -+ max-speed = <1000>; -+ phy-handle = <&phy0>; -+ assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>; -+ assigned-clock-parents = <&rcc PLL4_P>; -+ assigned-clock-rates = <125000000>; -+ st,eth-clk-sel; -+ -+ mdio0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "snps,dwmac-mdio"; -+ phy0: ethernet-phy@7 { /* KSZ9031RN */ -+ reg = <7>; -+ reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; /* ETH_RST# */ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <300>; -+ }; -+ }; -+}; --- -2.28.0 - diff --git a/board/myna-player-odyssey/initramfs_patches/linux/0001-dt-bindings-vendor-prefixes-add-Seeed-Studio.patch b/board/myna-player-odyssey/initramfs_patches/linux/0001-dt-bindings-vendor-prefixes-add-Seeed-Studio.patch deleted file mode 100644 index af9007c..0000000 --- a/board/myna-player-odyssey/initramfs_patches/linux/0001-dt-bindings-vendor-prefixes-add-Seeed-Studio.patch +++ /dev/null @@ -1,160 +0,0 @@ -From patchwork Fri Jul 31 14:30:51 2020 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Marcin Sloniewski -X-Patchwork-Id: 11695067 -Return-Path: - -Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org - [172.30.200.123]) - by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B9F21722 - for ; - Fri, 31 Jul 2020 14:31:27 +0000 (UTC) -Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by mail.kernel.org (Postfix) with ESMTPS id 92601208E4 - for ; - Fri, 31 Jul 2020 14:31:27 +0000 (UTC) -Authentication-Results: mail.kernel.org; - dkim=pass (2048-bit key) header.d=lists.infradead.org - header.i=@lists.infradead.org header.b="Lt3YNq+v"; - dkim=fail reason="signature verification failed" (2048-bit key) - header.d=gmail.com header.i=@gmail.com header.b="rooF5Y/L" -DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 92601208E4 -Authentication-Results: mail.kernel.org; - dmarc=fail (p=none dis=none) header.from=gmail.com -Authentication-Results: mail.kernel.org; - spf=none - smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: - Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: - List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: - Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender - :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; - bh=5bfzbNe1z8q22R2VERGYLDMIQrfP7PggkAr/XL6D3mw=; b=Lt3YNq+vn+BoHN23MO3PZGlHVm - dqrgDQoV1elTWeHOcV6CkwIlovqZi8lwX+gBgjtKkkV+zYUS/kZiL+xI2L6R99cHzyqzJs/1PWlmJ - 27ySLX2cDxUVywgtQHJevjS9X6HqxUcwcU0K0pjpGimxqORMfVAU+Z4oRAlFTxgPs0sv2YaqhJmvk - GMjjg/yUqXA9nc6/vRZLWs2eOj/gPJ8MHa9IW25qB6cSgaVNlSTScEdZcC1TOyRW3zRW9WXFS/aO7 - hOjOksgfh5/LdBQK58rQ8ET42v8hmowPUckNRoLYOeScRel0omz6J3Cn/lvDHdr+ghoXw0ofj0nKR - qitF9cJQ==; -Received: from localhost ([::1] helo=merlin.infradead.org) - by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) - id 1k1W43-0007vm-3P; Fri, 31 Jul 2020 14:31:15 +0000 -Received: from mail-ej1-x641.google.com ([2a00:1450:4864:20::641]) - by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) - id 1k1W3z-0007uF-H5 - for linux-arm-kernel@lists.infradead.org; Fri, 31 Jul 2020 14:31:12 +0000 -Received: by mail-ej1-x641.google.com with SMTP id f24so11136917ejx.6 - for ; - Fri, 31 Jul 2020 07:31:09 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; - h=from:to:cc:subject:date:message-id:mime-version - :content-transfer-encoding; - bh=TnSVvBPLgxOr7Okxa4+yFdbMwIKkVndKbRuepRfY/Zs=; - b=rooF5Y/LejVp6e+lkheBsBcOKwrWhHZzYXHf1m9XAOFNv87fHiPOh8t6nVxb4zVyuN - QDpyFEFyiTwlk8xKArO+TX4KUIY++pi8GQ2aMGQeJFu49tn7aim8G/kueOGS8tfEIrpQ - m8Eb/crBpL+aHjgty9b9jP36O8almuZhO0THmWfwhZOGRGmaQuoebyiVPkJPoZnWfb12 - IcMNREwMZeqv+FGO3XG63F7LBQcdiGEnQayFjSUl4e7jJzqbqQliGxVniSm03H8C3sTg - +qszh99IXLCLTlEOsKO0vTmCHnKjuYFc0sYdgnG4a917/G1WL5EJUUsElxaTKZz5mVRc - 1i7g== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20161025; - h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version - :content-transfer-encoding; - bh=TnSVvBPLgxOr7Okxa4+yFdbMwIKkVndKbRuepRfY/Zs=; - b=A2u1MUjMrLVbjxjdbxnHDqDlmYaHkw8q9FotqDJF3dCvdJvvyU2NxIeq5/j6zq3jpO - j31RaU/DPYHiSg5kplfdrgkSOZK+K0lTavU+S+ywyshX/2yCVI8nCl9OzuMkEov8bT/m - 43QDejJpL/SmgZRKu+LNQ8zDDpsj1NshF8wDd4xA0IKyL+kagoN5c00qIq3a6sIIrRJ2 - pgcyJ2akaa4WaIZIWOEMgTbYRLKi50FZSaPZWv90+dWNZxqeofPSMfNUkMWaB2FDVP/7 - 34cNkN4DkZW4PAiVWgnCAFOhW+uzvh/bb9ur5uuVgPHZlhSAXK7k6MxSqtGByrv5anj4 - 9AbQ== -X-Gm-Message-State: AOAM533qdoXA7OhRKnodwjuFemgbnuzB6M1Ezj5dK16V2RmuS2yAoxoY - Fh9bBRKH+4RTO9BMpR49AGXz1Asvs5w= -X-Google-Smtp-Source: - ABdhPJybf/XZgZB/Q/5YD/PtnotUkX1ldsL6Uu0I4qModtm+zX/Ggq7KmPlZXxlfNH2FA8a1tV0ngA== -X-Received: by 2002:a17:906:269a:: with SMTP id - t26mr4331783ejc.286.1596205867955; - Fri, 31 Jul 2020 07:31:07 -0700 (PDT) -Received: from blackhead.home ([2a01:112f:a1c:7900:7316:ce1e:7b0b:6bd7]) - by smtp.gmail.com with ESMTPSA id t19sm9749213edw.63.2020.07.31.07.31.05 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Fri, 31 Jul 2020 07:31:06 -0700 (PDT) -From: Marcin Sloniewski -To: linux-arm-kernel@lists.infradead.org -Subject: [PATCH v6 1/3] dt-bindings: vendor-prefixes: add Seeed Studio -Date: Fri, 31 Jul 2020 16:30:51 +0200 -Message-Id: <20200731143053.44866-1-marcin.sloniewski@gmail.com> -X-Mailer: git-send-email 2.27.0 -MIME-Version: 1.0 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20200731_103111_656264_F6F92A11 -X-CRM114-Status: GOOD ( 11.66 ) -X-Spam-Score: -0.2 (/) -X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: - Content analysis details: (-0.2 points) - pts rule name description - ---- ---------------------- - -------------------------------------------------- - -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, - no trust [2a00:1450:4864:20:0:0:0:641 listed in] - [list.dnswl.org] - 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail - provider [marcin.sloniewski[at]gmail.com] - -0.0 SPF_PASS SPF: sender matches SPF record - 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record - -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from - envelope-from domain - 0.1 DKIM_SIGNED Message has a DKIM or DK signature, - not necessarily - valid - -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature - -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from - author's domain -X-BeenThere: linux-arm-kernel@lists.infradead.org -X-Mailman-Version: 2.1.29 -Precedence: list -List-Id: -List-Unsubscribe: - , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: - , - -Cc: robh@kernel.org, a.fatoum@pengutronix.de, alexandre.torgue@st.com, - stephan@gerhold.net, mani@kernel.org, heiko.stuebner@theobroma-systems.com, - linus.walleij@linaro.org, linux-kernel@vger.kernel.org, lkundrak@v3.sk, - marcin.sloniewski@gmail.com, robh+dt@kernel.org, broonie@kernel.org, - mcoquelin.stm32@gmail.com, allen.chen@ite.com.tw, sam@ravnborg.org, - linux-stm32@st-md-mailman.stormreply.com, devicetree@vger.kernel.org -Sender: "linux-arm-kernel" -Errors-To: - linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org - -Add the "seeed" vendor prefix for Seeed Technology Co., Ltd -Website: https://www.seeedstudio.com/ - -Signed-off-by: Marcin Sloniewski -Acked-by: Rob Herring ---- - Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml -index 9aeab66be85f..7dd03b3e9d3c 100644 ---- a/Documentation/devicetree/bindings/vendor-prefixes.yaml -+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml -@@ -902,6 +902,8 @@ patternProperties: - description: Schindler - "^seagate,.*": - description: Seagate Technology PLC -+ "^seeed,.*": -+ description: Seeed Technology Co., Ltd - "^seirobotics,.*": - description: Shenzhen SEI Robotics Co., Ltd - "^semtech,.*": diff --git a/board/myna-player-odyssey/initramfs_patches/linux/0002-ARM-dts-stm32-add-initial-support-for-stm32mp157-odyssey-board.patch b/board/myna-player-odyssey/initramfs_patches/linux/0002-ARM-dts-stm32-add-initial-support-for-stm32mp157-odyssey-board.patch deleted file mode 100644 index 12ce50e..0000000 --- a/board/myna-player-odyssey/initramfs_patches/linux/0002-ARM-dts-stm32-add-initial-support-for-stm32mp157-odyssey-board.patch +++ /dev/null @@ -1,592 +0,0 @@ -From patchwork Fri Jul 31 14:30:53 2020 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Marcin Sloniewski -X-Patchwork-Id: 11695069 -Return-Path: - -Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org - [172.30.200.123]) - by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E2F7722 - for ; - Fri, 31 Jul 2020 14:31:41 +0000 (UTC) -Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) - (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) - (No client certificate requested) - by mail.kernel.org (Postfix) with ESMTPS id CDF28206FA - for ; - Fri, 31 Jul 2020 14:31:40 +0000 (UTC) -Authentication-Results: mail.kernel.org; - dkim=pass (2048-bit key) header.d=lists.infradead.org - header.i=@lists.infradead.org header.b="MVrwINxK"; - dkim=fail reason="signature verification failed" (2048-bit key) - header.d=gmail.com header.i=@gmail.com header.b="SZ9oG3H2" -DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CDF28206FA -Authentication-Results: mail.kernel.org; - dmarc=fail (p=none dis=none) header.from=gmail.com -Authentication-Results: mail.kernel.org; - spf=none - smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org -DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; - d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: - Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: - List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: - Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: - Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; - bh=ZqBehaVL3E9eAw7j29eP6hbbkkiJUDH1GEZqX8aJ6vw=; b=MVrwINxKoSfoJJrDJ6zIwcX37 - 1GLYn4tMDueqvtdwAOeCFeZXTUgKsF7XBTM36eEeqZl8DXUb4PcVqIl2uoaar1n07kU7g/XE5Z5Ub - fo1XQ6dROPOsp9Xyow/fq97tjuL4mnlMWy3Rc9a/KRXR/cjl0oVhK2E3KrtQjPDfDZI33QGljUs1l - 8KEu12M3vEcdIhnLMEgeUllRsw8EVOzTHWcRemhwiP0LuU8kNQri8fLuxmLiY7eyaU5HIx0Krxc5N - A39mlWUl9iBrvGgjZp9rGKHZWI8qi3eSRaEatIgFfjq5JLqzaZdAHP9/HnlCKsB6bqYDmrsmjOAp1 - GgcQA+G9A==; -Received: from localhost ([::1] helo=merlin.infradead.org) - by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) - id 1k1W4G-0007yo-4O; Fri, 31 Jul 2020 14:31:28 +0000 -Received: from mail-ed1-x544.google.com ([2a00:1450:4864:20::544]) - by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) - id 1k1W43-0007vl-7u - for linux-arm-kernel@lists.infradead.org; Fri, 31 Jul 2020 14:31:17 +0000 -Received: by mail-ed1-x544.google.com with SMTP id l23so8795737edv.11 - for ; - Fri, 31 Jul 2020 07:31:14 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; - h=from:to:cc:subject:date:message-id:in-reply-to:references - :mime-version:content-transfer-encoding; - bh=gXlatC5AsQuoD+3uBEzYu5ZAaHxOzY+84bpiZ1VQWHU=; - b=SZ9oG3H2bHMpUbOj4x4iCst17tROZ9eCea4P1DW0ECVd1hFkPes3cu0AL/XuSpPGw/ - WkesdNpda3BgS++sJrC7xXCwguI2Td+FW4uoCTNnISb4e493jpVveY05k2AgKffIwpyB - Yjq3WTBKWAXCAS/p8PqSAoqicx7Rd1ixJ9WjnfumkCj7USMzHRjmSvYObi9BFNZmd6vA - 0m8oAlHULlRwp2IpHxJtjZn9FA8CMEl4wxzxKAYMPnvJ+Pxgj+oqUIYNYQ9qQikI5Rwa - 7dJlplf1iCDpK4H3fRXRS2zmnej+aTIx/dBmtmyBrkNEKukxreR/FGM6qALVkNG3s0F5 - wAfQ== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20161025; - h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to - :references:mime-version:content-transfer-encoding; - bh=gXlatC5AsQuoD+3uBEzYu5ZAaHxOzY+84bpiZ1VQWHU=; - b=WBpvi05OfM9vbn8I/rsaI9tdORKkPgIt2QagURBkQuhQUv+MUVYxBn0lQrwLsDupfE - dTd/KSF76FM48hi9Qpw9vWPCCjN3MbbxfCubOfitA6ERYn6UPJz0oKQ/q+R2PxWUe94j - 13v3fBMuk4K/F5OqoP307+3MEm7N+VhBb1SMpb7auCFpW5s/gbyCZgCmqK+nL+2LuH3S - L162gEzFnRnh+cVWTsmQO8ncEk8H1NjpG88bKcChy+l/s8YkUJyy/jrXOMcgKPtCnMMp - nk9E7AzVcCI5q9p48caCM7IyP1PsaIQXzGf4N50iXOtl99bmfT0dMvYoItedjAf3QQgL - 0p3w== -X-Gm-Message-State: AOAM5319nwH6eaYvyTpx6i1M+SMQF/vZWNWeyp+U85+s7yi4S3itOjhy - tg/ktc9PBOlYlDo4U7GSIGyw40qPJ0Q= -X-Google-Smtp-Source: - ABdhPJw0QytN7CLiwpQs2xmXp+75EYfsbHr8vacXofDKzvnNX7QWIqKT/e3FiqX8+/8CLuUUrimiJw== -X-Received: by 2002:a05:6402:1845:: with SMTP id - v5mr4340661edy.66.1596205873413; - Fri, 31 Jul 2020 07:31:13 -0700 (PDT) -Received: from blackhead.home ([2a01:112f:a1c:7900:7316:ce1e:7b0b:6bd7]) - by smtp.gmail.com with ESMTPSA id t19sm9749213edw.63.2020.07.31.07.31.11 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Fri, 31 Jul 2020 07:31:12 -0700 (PDT) -From: Marcin Sloniewski -To: linux-arm-kernel@lists.infradead.org -Subject: [PATCH v6 3/3] ARM: dts: stm32: add initial support for - stm32mp157-odyssey board -Date: Fri, 31 Jul 2020 16:30:53 +0200 -Message-Id: <20200731143053.44866-3-marcin.sloniewski@gmail.com> -X-Mailer: git-send-email 2.27.0 -In-Reply-To: <20200731143053.44866-1-marcin.sloniewski@gmail.com> -References: <20200731143053.44866-1-marcin.sloniewski@gmail.com> -MIME-Version: 1.0 -X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 -X-CRM114-CacheID: sfid-20200731_103115_377803_90B11FBF -X-CRM114-Status: GOOD ( 22.84 ) -X-Spam-Score: -0.2 (/) -X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: - Content analysis details: (-0.2 points) - pts rule name description - ---- ---------------------- - -------------------------------------------------- - -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, - no trust [2a00:1450:4864:20:0:0:0:544 listed in] - [list.dnswl.org] - 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail - provider [marcin.sloniewski[at]gmail.com] - -0.0 SPF_PASS SPF: sender matches SPF record - 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record - -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from - envelope-from domain - 0.1 DKIM_SIGNED Message has a DKIM or DK signature, - not necessarily - valid - -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature - -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from - author's domain -X-BeenThere: linux-arm-kernel@lists.infradead.org -X-Mailman-Version: 2.1.29 -Precedence: list -List-Id: -List-Unsubscribe: - , - -List-Archive: -List-Post: -List-Help: -List-Subscribe: - , - -Cc: robh@kernel.org, a.fatoum@pengutronix.de, alexandre.torgue@st.com, - stephan@gerhold.net, mani@kernel.org, heiko.stuebner@theobroma-systems.com, - linus.walleij@linaro.org, linux-kernel@vger.kernel.org, lkundrak@v3.sk, - marcin.sloniewski@gmail.com, robh+dt@kernel.org, broonie@kernel.org, - mcoquelin.stm32@gmail.com, allen.chen@ite.com.tw, sam@ravnborg.org, - linux-stm32@st-md-mailman.stormreply.com, devicetree@vger.kernel.org -Sender: "linux-arm-kernel" -Errors-To: - linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org - -Add support for Seeed Studio's stm32mp157c odyssey board. -Board consists of SoM with stm32mp157c with 4GB eMMC and 512 MB DDR3 RAM -and carrier board with USB and ETH interfaces, SD card connector, -wifi and BT chip AP6236. - -In this patch only basic kernel boot is supported and interfacing -SD card and on-board eMMC. - -Signed-off-by: Marcin Sloniewski ---- - -Changes in v6: -- add reset pin for eth phy -- move pinctrl for sdmmc2 to stm32mp15-pinctrl.dtsi - -Changes in v5: -- fix schema for board's dts - -Changes in v4: -- add seeed,stm32mp157c-odyssey-som in compatible - for carrier board -- fix sdmmc2 interface by changing one of the pins - to use -- change eth phy address to 7 - -Changes in v3: -- fix compilation on tip of stm32-next - due to change in names for pinctrl -- fix deprecated binding for led node -- fix redundant "okay" statuses -- add phy part number for eth in comment - -Changes in v2: -- add new odyssey dts to Makefile - - - arch/arm/boot/dts/Makefile | 3 +- - arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 18 ++ - .../arm/boot/dts/stm32mp157c-odyssey-som.dtsi | 276 ++++++++++++++++++ - arch/arm/boot/dts/stm32mp157c-odyssey.dts | 76 +++++ - 4 files changed, 372 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi - create mode 100644 arch/arm/boot/dts/stm32mp157c-odyssey.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index e6a1cac0bfc7..a3ea2301c82c 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1047,7 +1047,8 @@ dtb-$(CONFIG_ARCH_STM32) += \ - stm32mp157c-dk2.dtb \ - stm32mp157c-ed1.dtb \ - stm32mp157c-ev1.dtb \ -- stm32mp157c-lxa-mc1.dtb -+ stm32mp157c-lxa-mc1.dtb \ -+ stm32mp157c-odyssey.dtb - dtb-$(CONFIG_MACH_SUN4I) += \ - sun4i-a10-a1000.dtb \ - sun4i-a10-ba10-tvbox.dtb \ -diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -index b5a66429670c..a47eaecbde42 100644 ---- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -@@ -1437,6 +1437,24 @@ pins { - }; - }; - -+ sdmmc2_d47_pins_d: sdmmc2-d47-3 { -+ pins { -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ }; -+ }; -+ -+ sdmmc2_d47_sleep_pins_d: sdmmc2-d47-sleep-3 { -+ pins { -+ pinmux = , /* SDMMC2_D4 */ -+ , /* SDMMC2_D5 */ -+ , /* SDMMC2_D6 */ -+ ; /* SDMMC2_D7 */ -+ }; -+ }; -+ - sdmmc3_b4_pins_a: sdmmc3-b4-0 { - pins1 { - pinmux = , /* SDMMC3_D0 */ -diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi -new file mode 100644 -index 000000000000..6cf49a0a9e69 ---- /dev/null -+++ b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi -@@ -0,0 +1,276 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) 2020 Marcin Sloniewski . -+ */ -+ -+/dts-v1/; -+ -+#include "stm32mp157.dtsi" -+#include "stm32mp15xc.dtsi" -+#include "stm32mp15-pinctrl.dtsi" -+#include "stm32mp15xxac-pinctrl.dtsi" -+#include -+#include -+#include -+ -+/ { -+ model = "Seeed Studio Odyssey-STM32MP157C SOM"; -+ compatible = "seeed,stm32mp157c-odyssey-som", "st,stm32mp157"; -+ -+ memory@c0000000 { -+ device_type = "memory"; -+ reg = <0xc0000000 0x20000000>; -+ }; -+ -+ reserved-memory { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ mcuram2: mcuram2@10000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10000000 0x40000>; -+ no-map; -+ }; -+ -+ vdev0vring0: vdev0vring0@10040000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10040000 0x1000>; -+ no-map; -+ }; -+ -+ vdev0vring1: vdev0vring1@10041000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10041000 0x1000>; -+ no-map; -+ }; -+ -+ vdev0buffer: vdev0buffer@10042000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x10042000 0x4000>; -+ no-map; -+ }; -+ -+ mcuram: mcuram@30000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x30000000 0x40000>; -+ no-map; -+ }; -+ -+ retram: retram@38000000 { -+ compatible = "shared-dma-pool"; -+ reg = <0x38000000 0x10000>; -+ no-map; -+ }; -+ -+ gpu_reserved: gpu@d4000000 { -+ reg = <0xd4000000 0x4000000>; -+ no-map; -+ }; -+ }; -+ -+ led { -+ compatible = "gpio-leds"; -+ led-blue { -+ color = ; -+ function = LED_FUNCTION_HEARTBEAT; -+ gpios = <&gpiog 3 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ }; -+}; -+ -+&gpu { -+ contiguous-area = <&gpu_reserved>; -+ status = "okay"; -+}; -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins_a>; -+ i2c-scl-rising-time-ns = <185>; -+ i2c-scl-falling-time-ns = <20>; -+ status = "okay"; -+ /* spare dmas for other usage */ -+ /delete-property/dmas; -+ /delete-property/dma-names; -+ -+ pmic: stpmic@33 { -+ compatible = "st,stpmic1"; -+ reg = <0x33>; -+ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ -+ regulators { -+ compatible = "st,stpmic1-regulators"; -+ ldo1-supply = <&v3v3>; -+ ldo3-supply = <&vdd_ddr>; -+ ldo6-supply = <&v3v3>; -+ pwr_sw1-supply = <&bst_out>; -+ pwr_sw2-supply = <&bst_out>; -+ -+ vddcore: buck1 { -+ regulator-name = "vddcore"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-always-on; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ }; -+ -+ vdd_ddr: buck2 { -+ regulator-name = "vdd_ddr"; -+ regulator-min-microvolt = <1350000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-always-on; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ }; -+ -+ vdd: buck3 { -+ regulator-name = "vdd"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ st,mask-reset; -+ regulator-initial-mode = <0>; -+ regulator-over-current-protection; -+ }; -+ -+ v3v3: buck4 { -+ regulator-name = "v3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ regulator-over-current-protection; -+ regulator-initial-mode = <0>; -+ }; -+ -+ v1v8_audio: ldo1 { -+ regulator-name = "v1v8_audio"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ interrupts = ; -+ }; -+ -+ v3v3_hdmi: ldo2 { -+ regulator-name = "v3v3_hdmi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ interrupts = ; -+ }; -+ -+ vtt_ddr: ldo3 { -+ regulator-name = "vtt_ddr"; -+ regulator-min-microvolt = <500000>; -+ regulator-max-microvolt = <750000>; -+ regulator-always-on; -+ regulator-over-current-protection; -+ }; -+ -+ vdd_usb: ldo4 { -+ regulator-name = "vdd_usb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ interrupts = ; -+ }; -+ -+ vdda: ldo5 { -+ regulator-name = "vdda"; -+ regulator-min-microvolt = <2900000>; -+ regulator-max-microvolt = <2900000>; -+ interrupts = ; -+ regulator-boot-on; -+ }; -+ -+ v1v2_hdmi: ldo6 { -+ regulator-name = "v1v2_hdmi"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-always-on; -+ interrupts = ; -+ }; -+ -+ vref_ddr: vref_ddr { -+ regulator-name = "vref_ddr"; -+ regulator-always-on; -+ regulator-over-current-protection; -+ }; -+ -+ bst_out: boost { -+ regulator-name = "bst_out"; -+ interrupts = ; -+ }; -+ -+ vbus_otg: pwr_sw1 { -+ regulator-name = "vbus_otg"; -+ interrupts = ; -+ }; -+ -+ vbus_sw: pwr_sw2 { -+ regulator-name = "vbus_sw"; -+ interrupts = ; -+ regulator-active-discharge; -+ }; -+ }; -+ -+ onkey { -+ compatible = "st,stpmic1-onkey"; -+ interrupts = , ; -+ interrupt-names = "onkey-falling", "onkey-rising"; -+ power-off-time-sec = <10>; -+ }; -+ -+ watchdog { -+ compatible = "st,stpmic1-wdt"; -+ status = "disabled"; -+ }; -+ }; -+}; -+ -+&ipcc { -+ status = "okay"; -+}; -+ -+&iwdg2 { -+ timeout-sec = <32>; -+ status = "okay"; -+}; -+ -+&m4_rproc { -+ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, -+ <&vdev0vring1>, <&vdev0buffer>; -+ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; -+ mbox-names = "vq0", "vq1", "shutdown"; -+ interrupt-parent = <&exti>; -+ interrupts = <68 1>; -+ status = "okay"; -+}; -+ -+&rng1 { -+ status = "okay"; -+}; -+ -+&rtc { -+ status = "okay"; -+}; -+ -+&sdmmc2 { -+ pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_d>; -+ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_d>; -+ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_d>; -+ non-removable; -+ no-sd; -+ no-sdio; -+ st,neg-edge; -+ bus-width = <8>; -+ vmmc-supply = <&v3v3>; -+ vqmmc-supply = <&v3v3>; -+ mmc-ddr-3_3v; -+ status = "okay"; -+}; -+ -diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts -new file mode 100644 -index 000000000000..f2ac92f1ad10 ---- /dev/null -+++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts -@@ -0,0 +1,76 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Copyright (C) 2020 Marcin Sloniewski . -+ */ -+ -+/dts-v1/; -+ -+#include "stm32mp157c-odyssey-som.dtsi" -+ -+/ { -+ model = "Seeed Studio Odyssey-STM32MP157C Board"; -+ compatible = "seeed,stm32mp157c-odyssey", -+ "seeed,stm32mp157c-odyssey-som", "st,stm32mp157"; -+ -+ aliases { -+ ethernet0 = ðernet0; -+ serial0 = &uart4; -+ }; -+ -+ chosen { -+ stdout-path = "serial0:115200n8"; -+ }; -+}; -+ -+ðernet0 { -+ status = "okay"; -+ pinctrl-0 = <ðernet0_rgmii_pins_a>; -+ pinctrl-1 = <ðernet0_rgmii_sleep_pins_a>; -+ pinctrl-names = "default", "sleep"; -+ phy-mode = "rgmii-id"; -+ max-speed = <1000>; -+ phy-handle = <&phy0>; -+ -+ mdio0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "snps,dwmac-mdio"; -+ phy0: ethernet-phy@7 { /* KSZ9031RN */ -+ reg = <7>; -+ reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; /* ETH_RST# */ -+ reset-assert-us = <10000>; -+ reset-deassert-us = <300>; -+ }; -+ }; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&i2c1_pins_a>; -+ pinctrl-1 = <&i2c1_sleep_pins_a>; -+ i2c-scl-rising-time-ns = <100>; -+ i2c-scl-falling-time-ns = <7>; -+ status = "okay"; -+ /delete-property/dmas; -+ /delete-property/dma-names; -+}; -+ -+&sdmmc1 { -+ pinctrl-names = "default", "opendrain", "sleep"; -+ pinctrl-0 = <&sdmmc1_b4_pins_a>; -+ pinctrl-1 = <&sdmmc1_b4_od_pins_a>; -+ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; -+ cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; -+ disable-wp; -+ st,neg-edge; -+ bus-width = <4>; -+ vmmc-supply = <&v3v3>; -+ status = "okay"; -+}; -+ -+&uart4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins_a>; -+ status = "okay"; -+}; -+ diff --git a/board/myna-player-odyssey/initramfs_patches/linux/0003-ARM-dts-stm32mp157c-odyssey-fix-ethernet.patch b/board/myna-player-odyssey/initramfs_patches/linux/0003-ARM-dts-stm32mp157c-odyssey-fix-ethernet.patch deleted file mode 100644 index 41621cf..0000000 --- a/board/myna-player-odyssey/initramfs_patches/linux/0003-ARM-dts-stm32mp157c-odyssey-fix-ethernet.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -index 2f75b631feac..afeb85ac66ca 100644 ---- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi -@@ -120,8 +120,7 @@ - - ethernet0_rgmii_pins_a: rgmii-0 { - pins1 { -- pinmux = , /* ETH_RGMII_CLK125 */ -- , /* ETH_RGMII_GTX_CLK */ -+ pinmux = , /* ETH_RGMII_GTX_CLK */ - , /* ETH_RGMII_TXD0 */ - , /* ETH_RGMII_TXD1 */ - , /* ETH_RGMII_TXD2 */ -diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts -index f2ac92f1ad10..ac9fa784419d 100644 ---- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts -+++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts -@@ -30,6 +30,22 @@ - phy-mode = "rgmii-id"; - max-speed = <1000>; - phy-handle = <&phy0>; -+ assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>; -+ assigned-clock-parents = <&rcc PLL4_P>; -+ assigned-clock-rates = <125000000>; -+ st,eth-clk-sel; -+ clock-names = "stmmaceth", -+ "mac-clk-tx", -+ "mac-clk-rx", -+ "eth-ck", -+ "syscfg-clk", -+ "ethstp"; -+ clocks = <&rcc ETHMAC>, -+ <&rcc ETHTX>, -+ <&rcc ETHRX>, -+ <&rcc ETHCK_K>, -+ <&rcc SYSCFG>, -+ <&rcc ETHSTP>; - - mdio0 { - #address-cells = <1>; diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0001-fdts-stm32mp157ca-dk1-Use-STPMIC-on-I2C2-and-eMMC-on.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0001-fdts-stm32mp157ca-dk1-Use-STPMIC-on-I2C2-and-eMMC-on.patch new file mode 100644 index 0000000..a67ecd6 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0001-fdts-stm32mp157ca-dk1-Use-STPMIC-on-I2C2-and-eMMC-on.patch @@ -0,0 +1,90 @@ +From ce8f8385e099b5dfee521d58bba40771c072b0df Mon Sep 17 00:00:00 2001 +From: Jookia +Date: Tue, 28 Jul 2020 14:13:17 +1000 +Subject: [PATCH 1/7] fdts: stm32mp157ca-dk1: Use STPMIC on I2C2 and eMMC on + SDMMC2 + +Quick hack to get things working on the Seeed Odyssey board. +--- + fdts/stm32mp157-pinctrl.dtsi | 10 ++++++++++ + fdts/stm32mp157a-dk1.dts | 8 ++++---- + fdts/stm32mp157c.dtsi | 14 ++++++++++++++ + 3 files changed, 28 insertions(+), 4 deletions(-) + +diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi +index 8e480b2c1..4b746b225 100644 +--- a/fdts/stm32mp157-pinctrl.dtsi ++++ b/fdts/stm32mp157-pinctrl.dtsi +@@ -214,6 +214,16 @@ + }; + }; + ++ i2c2_pins_a: i2c2-0 { ++ pins { ++ pinmux = , /* I2C2_SCL */ ++ ; /* I2C2_SDA */ ++ bias-disable; ++ drive-open-drain; ++ slew-rate = <0>; ++ }; ++ }; ++ + sdmmc2_b4_pins_a: sdmmc2-b4-0 { + pins1 { + pinmux = , /* SDMMC2_D0 */ +diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts +index 4ea83f7cd..78681b0ba 100644 +--- a/fdts/stm32mp157a-dk1.dts ++++ b/fdts/stm32mp157a-dk1.dts +@@ -29,9 +29,9 @@ + st,digbypass; + }; + +-&i2c4 { ++&i2c2 { + pinctrl-names = "default"; +- pinctrl-0 = <&i2c4_pins_a>; ++ pinctrl-0 = <&i2c2_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; +@@ -162,9 +162,9 @@ + status = "okay"; + }; + +-&sdmmc1 { ++&sdmmc2 { + pinctrl-names = "default"; +- pinctrl-0 = <&sdmmc1_b4_pins_a>; ++ pinctrl-0 = <&sdmmc2_b4_pins_a>; + broken-cd; + st,neg-edge; + bus-width = <4>; +diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi +index 0942a91c2..faa409f2d 100644 +--- a/fdts/stm32mp157c.dtsi ++++ b/fdts/stm32mp157c.dtsi +@@ -312,6 +312,20 @@ + status = "disabled"; + }; + ++ ++ i2c2: i2c@40013000 { ++ compatible = "st,stm32f7-i2c"; ++ reg = <0x40013000 0x400>; ++ interrupt-names = "event", "error"; ++ interrupts = , ++ ; ++ clocks = <&rcc I2C2_K>; ++ resets = <&rcc I2C2_R>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ + i2c4: i2c@5c002000 { + compatible = "st,stm32f7-i2c"; + reg = <0x5c002000 0x400>; +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0002-arch-rename-CNTBaseN-register-offsets-defines.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0002-arch-rename-CNTBaseN-register-offsets-defines.patch new file mode 100644 index 0000000..269cda7 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0002-arch-rename-CNTBaseN-register-offsets-defines.patch @@ -0,0 +1,62 @@ +From 3a29660ebc69c11fc841a662e8692e59c45eda10 Mon Sep 17 00:00:00 2001 +From: Yann Gautier +Date: Tue, 21 May 2019 18:32:14 +0200 +Subject: [PATCH 2/7] arch: rename CNTBaseN register offsets defines + +The CNTFRQ already has a CNTBASEN_ prefix. +To be able to use CNTP_CTL from CP15, the CNTP_CTL define is renamed +CNTBASEN_CNTP_CTL. +To keep consistency, CNTPCT_LO and CNTP_CVAL_LO are also prefixed. + +Change-Id: Ie328daa694a708130ee369218b57c0f4b08f7f44 +Signed-off-by: Yann Gautier +--- + include/arch/aarch32/arch.h | 6 +++--- + include/arch/aarch64/arch.h | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h +index 20175481f..047770e4f 100644 +--- a/include/arch/aarch32/arch.h ++++ b/include/arch/aarch32/arch.h +@@ -457,13 +457,13 @@ + * system level implementation of the Generic Timer. + ******************************************************************************/ + /* Physical Count register. */ +-#define CNTPCT_LO U(0x0) ++#define CNTBASEN_CNTPCT_LO U(0x0) + /* Counter Frequency register. */ + #define CNTBASEN_CNTFRQ U(0x10) + /* Physical Timer CompareValue register. */ +-#define CNTP_CVAL_LO U(0x20) ++#define CNTBASEN_CNTP_CVAL_LO U(0x20) + /* Physical Timer Control register. */ +-#define CNTP_CTL U(0x2c) ++#define CNTBASEN_CNTP_CTL U(0x2c) + + /* Physical timer control register bit fields shifts and masks */ + #define CNTP_CTL_ENABLE_SHIFT 0 +diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h +index 3ff2912f1..307dad585 100644 +--- a/include/arch/aarch64/arch.h ++++ b/include/arch/aarch64/arch.h +@@ -670,13 +670,13 @@ + * system level implementation of the Generic Timer. + ******************************************************************************/ + /* Physical Count register. */ +-#define CNTPCT_LO U(0x0) ++#define CNTBASEN_CNTPCT_LO U(0x0) + /* Counter Frequency register. */ + #define CNTBASEN_CNTFRQ U(0x10) + /* Physical Timer CompareValue register. */ +-#define CNTP_CVAL_LO U(0x20) ++#define CNTBASEN_CNTP_CVAL_LO U(0x20) + /* Physical Timer Control register. */ +-#define CNTP_CTL U(0x2c) ++#define CNTBASEN_CNTP_CTL U(0x2c) + + /* PMCR_EL0 definitions */ + #define PMCR_EL0_RESET_VAL U(0x0) +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0003-aarch32-add-virtual-timer-control-support.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0003-aarch32-add-virtual-timer-control-support.patch new file mode 100644 index 0000000..bb79878 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0003-aarch32-add-virtual-timer-control-support.patch @@ -0,0 +1,50 @@ +From 7e3d16e5f993271e20136e732cebc78fd90adddb Mon Sep 17 00:00:00 2001 +From: Yann Gautier +Date: Tue, 21 May 2019 18:46:27 +0200 +Subject: [PATCH 3/7] aarch32: add virtual timer control support + +Define virtual timer resources for a platform to be able to control +virtual timers, even if TF-A does not enable them. +This is required for example when the secure world wants to reset +the system. Virtual timers enabled from non-secure world can +jeopardize the reset sequence due to pending interrupts. + +Change-Id: Ieb0ce4819809ae9c4ab11f9244a6cacf9437d6b4 +Signed-off-by: Nicolas Le Bayon +Signed-off-by: Yann Gautier +--- + include/arch/aarch32/arch.h | 3 +++ + include/arch/aarch32/arch_helpers.h | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h +index 047770e4f..edf12873d 100644 +--- a/include/arch/aarch32/arch.h ++++ b/include/arch/aarch32/arch.h +@@ -522,6 +522,9 @@ + #define HSTR p15, 4, c1, c1, 3 + #define CNTHCTL p15, 4, c14, c1, 0 + #define CNTKCTL p15, 0, c14, c1, 0 ++#define CNTP_TVAL p15, 0, c14, c2, 0 ++#define CNTP_CTL p15, 0, c14, c2, 1 ++#define CNTV_CTL p15, 0, c14, c3, 1 + #define VPIDR p15, 4, c0, c0, 0 + #define VMPIDR p15, 4, c0, c0, 5 + #define ISR p15, 0, c12, c1, 0 +diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h +index cbac84b93..b060f855c 100644 +--- a/include/arch/aarch32/arch_helpers.h ++++ b/include/arch/aarch32/arch_helpers.h +@@ -246,6 +246,9 @@ DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64) + DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64) + DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR) + DEFINE_COPROCR_RW_FUNCS(hstr, HSTR) ++DEFINE_COPROCR_RW_FUNCS(cntp_tval, CNTP_TVAL) ++DEFINE_COPROCR_RW_FUNCS(cntp_ctl, CNTP_CTL) ++DEFINE_COPROCR_RW_FUNCS(cntv_ctl, CNTV_CTL) + DEFINE_COPROCR_RW_FUNCS(cnthp_ctl_el2, CNTHP_CTL) + DEFINE_COPROCR_RW_FUNCS(cnthp_tval_el2, CNTHP_TVAL) + DEFINE_COPROCR_RW_FUNCS_64(cnthp_cval_el2, CNTHP_CVAL_64) +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0004-stm32mp1-add-RTC-driver.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0004-stm32mp1-add-RTC-driver.patch new file mode 100644 index 0000000..a9a9dc3 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0004-stm32mp1-add-RTC-driver.patch @@ -0,0 +1,736 @@ +From 50302f6ebc885c3788794587203a6a6012d48d04 Mon Sep 17 00:00:00 2001 +From: Yann Gautier +Date: Mon, 13 May 2019 18:37:00 +0200 +Subject: [PATCH 4/7] stm32mp1: add RTC driver + +This driver is responsible to manage STM32MP1 Real Time Clock IP. + +Change-Id: I8bb84cf2a2786be718944d69153f676d57bfbc37 +Signed-off-by: Yann Gautier +Signed-off-by: Nicolas Le Bayon +--- + drivers/st/clk/stm32mp1_clk.c | 37 ++ + drivers/st/rtc/stm32_rtc.c | 488 +++++++++++++++++++++ + include/drivers/st/stm32_rtc.h | 78 ++++ + include/drivers/st/stm32mp1_clk.h | 2 + + plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 1 + + plat/st/stm32mp1/sp_min/sp_min_setup.c | 34 +- + 6 files changed, 632 insertions(+), 8 deletions(-) + create mode 100644 drivers/st/rtc/stm32_rtc.c + create mode 100644 include/drivers/st/stm32_rtc.h + +diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c +index 0cc87cc71..994614f03 100644 +--- a/drivers/st/clk/stm32mp1_clk.c ++++ b/drivers/st/clk/stm32mp1_clk.c +@@ -1572,6 +1572,43 @@ void stm32mp1_stgen_increment(unsigned long long offset_in_ms) + mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN); + } + ++/******************************************************************************* ++ * This function determines the number of needed RTC calendar read operations ++ * to get consistent values (1 or 2 depending on clock frequencies). ++ * If APB1 frequency is lower than 7 times the RTC one, the software has to ++ * read the calendar time and date registers twice. ++ * Returns true if read twice is needed, false else. ++ ******************************************************************************/ ++bool stm32mp1_rtc_get_read_twice(void) ++{ ++ unsigned long apb1_freq; ++ uint32_t rtc_freq; ++ uint32_t apb1_div; ++ uintptr_t rcc_base = stm32mp_rcc_base(); ++ ++ switch ((mmio_read_32(rcc_base + RCC_BDCR) & ++ RCC_BDCR_RTCSRC_MASK) >> RCC_BDCR_RTCSRC_SHIFT) { ++ case 1: ++ rtc_freq = stm32mp_clk_get_rate(CK_LSE); ++ break; ++ case 2: ++ rtc_freq = stm32mp_clk_get_rate(CK_LSI); ++ break; ++ case 3: ++ rtc_freq = stm32mp_clk_get_rate(CK_HSE); ++ rtc_freq /= (mmio_read_32(rcc_base + RCC_RTCDIVR) & ++ RCC_DIVR_DIV_MASK) + 1U; ++ break; ++ default: ++ panic(); ++ } ++ ++ apb1_div = mmio_read_32(rcc_base + RCC_APB1DIVR) & RCC_APBXDIV_MASK; ++ apb1_freq = stm32mp_clk_get_rate(CK_MCU) >> apb1_div; ++ ++ return apb1_freq < (rtc_freq * 7U); ++} ++ + static void stm32mp1_pkcs_config(uint32_t pkcs) + { + uintptr_t address = stm32mp_rcc_base() + ((pkcs >> 4) & 0xFFFU); +diff --git a/drivers/st/rtc/stm32_rtc.c b/drivers/st/rtc/stm32_rtc.c +new file mode 100644 +index 000000000..eaa6f7508 +--- /dev/null ++++ b/drivers/st/rtc/stm32_rtc.c +@@ -0,0 +1,488 @@ ++/* ++ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define RTC_COMPAT "st,stm32mp1-rtc" ++ ++#define RTC_TR_SU_MASK GENMASK(3, 0) ++#define RTC_TR_ST_MASK GENMASK(6, 4) ++#define RTC_TR_ST_SHIFT 4 ++#define RTC_TR_MNU_MASK GENMASK(11, 8) ++#define RTC_TR_MNU_SHIFT 8 ++#define RTC_TR_MNT_MASK GENMASK(14, 12) ++#define RTC_TR_MNT_SHIFT 12 ++#define RTC_TR_HU_MASK GENMASK(19, 16) ++#define RTC_TR_HU_SHIFT 16 ++#define RTC_TR_HT_MASK GENMASK(21, 20) ++#define RTC_TR_HT_SHIFT 20 ++#define RTC_TR_PM BIT(22) ++ ++#define RTC_DR_DU_MASK GENMASK(3, 0) ++#define RTC_DR_DT_MASK GENMASK(5, 4) ++#define RTC_DR_DT_SHIFT 4 ++#define RTC_DR_MU_MASK GENMASK(11, 8) ++#define RTC_DR_MU_SHIFT 8 ++#define RTC_DR_MT BIT(12) ++#define RTC_DR_MT_SHIFT 12 ++#define RTC_DR_WDU_MASK GENMASK(15, 13) ++#define RTC_DR_WDU_SHIFT 13 ++#define RTC_DR_YU_MASK GENMASK(19, 16) ++#define RTC_DR_YU_SHIFT 16 ++#define RTC_DR_YT_MASK GENMASK(23, 20) ++#define RTC_DR_YT_SHIFT 20 ++ ++#define RTC_SSR_SS_MASK GENMASK(15, 0) ++ ++#define RTC_ICSR_ALRAWF BIT(0) ++#define RTC_ICSR_RSF BIT(5) ++ ++#define RTC_PRER_PREDIV_S_MASK GENMASK(14, 0) ++ ++#define RTC_CR_BYPSHAD BIT(5) ++#define RTC_CR_BYPSHAD_SHIFT 5 ++#define RTC_CR_ALRAE BIT(8) ++#define RTC_CR_ALRAIE BIT(12) ++#define RTC_CR_TAMPTS BIT(25) ++ ++#define RTC_SMCR_TS_DPROT BIT(3) ++ ++#define RTC_TSDR_DU_MASK GENMASK(3, 0) ++#define RTC_TSDR_DU_SHIFT 0 ++#define RTC_TSDR_DT_MASK GENMASK(5, 4) ++#define RTC_TSDR_DT_SHIFT 4 ++#define RTC_TSDR_MU_MASK GENMASK(11, 8) ++#define RTC_TSDR_MU_SHIFT 8 ++ ++#define RTC_ALRMAR_DU_SHIFT 24 ++ ++#define RTC_SR_TSF BIT(3) ++#define RTC_SR_TSOVF BIT(4) ++ ++#define RTC_SCR_CTSF BIT(3) ++#define RTC_SCR_CTSOVF BIT(4) ++ ++#define RTC_WPR_KEY1 0xCA ++#define RTC_WPR_KEY2 0x53 ++#define RTC_WPR_KEY_LOCK 0xFF ++ ++static struct dt_node_info rtc_dev; ++ ++static struct spinlock lock; ++ ++void stm32_rtc_regs_lock(void) ++{ ++ if (stm32mp_lock_available()) { ++ spin_lock(&lock); ++ } ++} ++ ++void stm32_rtc_regs_unlock(void) ++{ ++ if (stm32mp_lock_available()) { ++ spin_unlock(&lock); ++ } ++} ++ ++static void stm32_rtc_write_unprotect(void) ++{ ++ mmio_write_32(rtc_dev.base + RTC_WPR, RTC_WPR_KEY1); ++ mmio_write_32(rtc_dev.base + RTC_WPR, RTC_WPR_KEY2); ++} ++ ++static void stm32_rtc_write_protect(void) ++{ ++ mmio_write_32(rtc_dev.base + RTC_WPR, RTC_WPR_KEY_LOCK); ++} ++ ++/******************************************************************************* ++ * This function gets the BYPSHAD bit value of the RTC_CR register. ++ * It will determine if we need to reset RTC_ISCR.RSF after each RTC calendar ++ * read, and also wait for RTC_ISCR.RSF=1 before next read. ++ * Returns true or false depending on the bit value. ++ ******************************************************************************/ ++static bool stm32_rtc_get_bypshad(void) ++{ ++ return ((mmio_read_32(rtc_dev.base + RTC_CR) & RTC_CR_BYPSHAD) >> ++ RTC_CR_BYPSHAD_SHIFT) != 0U; ++} ++ ++/******************************************************************************* ++ * This function reads the RTC calendar register values. ++ * If shadow registers are not bypassed, then a reset/poll is done. ++ ******************************************************************************/ ++static void stm32_rtc_read_calendar(struct stm32_rtc_calendar *calendar) ++{ ++ bool bypshad = stm32_rtc_get_bypshad(); ++ ++ if (!bypshad) { ++ mmio_clrbits_32((uint32_t)(rtc_dev.base + RTC_ICSR), ++ RTC_ICSR_RSF); ++ while ((mmio_read_32(rtc_dev.base + RTC_ICSR) & RTC_ICSR_RSF) != ++ RTC_ICSR_RSF) { ++ ; ++ } ++ } ++ ++ calendar->ssr = mmio_read_32(rtc_dev.base + RTC_SSR); ++ calendar->tr = mmio_read_32(rtc_dev.base + RTC_TR); ++ calendar->dr = mmio_read_32(rtc_dev.base + RTC_DR); ++} ++ ++/******************************************************************************* ++ * This function fill the rtc_time structure based on rtc_calendar register. ++ ******************************************************************************/ ++static void stm32_rtc_get_time(struct stm32_rtc_calendar *cal, ++ struct stm32_rtc_time *tm) ++{ ++ assert(cal != NULL); ++ assert(tm != NULL); ++ ++ tm->hour = (((cal->tr & RTC_TR_HT_MASK) >> RTC_TR_HT_SHIFT) * 10U) + ++ ((cal->tr & RTC_TR_HU_MASK) >> RTC_TR_HU_SHIFT); ++ ++ if ((cal->tr & RTC_TR_PM) != 0U) { ++ tm->hour += 12U; ++ } ++ ++ tm->min = (((cal->tr & RTC_TR_MNT_MASK) >> RTC_TR_MNT_SHIFT) * 10U) + ++ ((cal->tr & RTC_TR_MNU_MASK) >> RTC_TR_MNU_SHIFT); ++ tm->sec = (((cal->tr & RTC_TR_ST_MASK) >> RTC_TR_ST_SHIFT) * 10U) + ++ (cal->tr & RTC_TR_SU_MASK); ++} ++ ++/******************************************************************************* ++ * This function fill the rtc_time structure with the given date register. ++ ******************************************************************************/ ++static void stm32_rtc_get_date(struct stm32_rtc_calendar *cal, ++ struct stm32_rtc_time *tm) ++{ ++ assert(cal != NULL); ++ assert(tm != NULL); ++ ++ tm->wday = (((cal->dr & RTC_DR_WDU_MASK) >> RTC_DR_WDU_SHIFT)); ++ ++ tm->day = (((cal->dr & RTC_DR_DT_MASK) >> RTC_DR_DT_SHIFT) * 10U) + ++ (cal->dr & RTC_DR_DU_MASK); ++ ++ tm->month = (((cal->dr & RTC_DR_MT) >> RTC_DR_MT_SHIFT) * 10U) + ++ ((cal->dr & RTC_DR_MU_MASK) >> RTC_DR_MU_SHIFT); ++ ++ tm->year = (((cal->dr & RTC_DR_YT_MASK) >> RTC_DR_YT_SHIFT) * 10U) + ++ ((cal->dr & RTC_DR_YU_MASK) >> RTC_DR_YU_SHIFT) + 2000U; ++} ++ ++/******************************************************************************* ++ * This function reads the RTC timestamp register values and update time ++ * structure with the corresponding value. ++ ******************************************************************************/ ++static void stm32_rtc_read_timestamp(struct stm32_rtc_time *time) ++{ ++ assert(time != NULL); ++ ++ struct stm32_rtc_calendar cal_tamp; ++ ++ cal_tamp.tr = mmio_read_32(rtc_dev.base + RTC_TSTR); ++ cal_tamp.dr = mmio_read_32(rtc_dev.base + RTC_TSDR); ++ stm32_rtc_get_time(&cal_tamp, time); ++ stm32_rtc_get_date(&cal_tamp, time); ++} ++ ++/******************************************************************************* ++ * This function gets the RTC calendar register values. ++ * It takes into account the need of reading twice or not, depending on ++ * frequencies previously setted, and the bypass or not of the shadow ++ * registers. This service is exposed externally. ++ ******************************************************************************/ ++void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar) ++{ ++ bool read_twice = stm32mp1_rtc_get_read_twice(); ++ ++ stm32_rtc_regs_lock(); ++ stm32mp_clk_enable(rtc_dev.clock); ++ ++ stm32_rtc_read_calendar(calendar); ++ ++ if (read_twice) { ++ uint32_t tr_save = calendar->tr; ++ ++ stm32_rtc_read_calendar(calendar); ++ ++ if (calendar->tr != tr_save) { ++ stm32_rtc_read_calendar(calendar); ++ } ++ } ++ ++ stm32mp_clk_disable(rtc_dev.clock); ++ stm32_rtc_regs_unlock(); ++} ++ ++/******************************************************************************* ++ * This function computes the second fraction in milliseconds. ++ * The returned value is a uint32_t between 0 and 1000. ++ ******************************************************************************/ ++static uint32_t stm32_rtc_get_second_fraction(struct stm32_rtc_calendar *cal) ++{ ++ uint32_t prediv_s = mmio_read_32(rtc_dev.base + RTC_PRER) & ++ RTC_PRER_PREDIV_S_MASK; ++ uint32_t ss = cal->ssr & RTC_SSR_SS_MASK; ++ ++ return ((prediv_s - ss) * 1000U) / (prediv_s + 1U); ++} ++ ++/******************************************************************************* ++ * This function computes the fraction difference between two timestamps. ++ * Here again the returned value is in milliseconds. ++ ******************************************************************************/ ++static unsigned long long stm32_rtc_diff_frac(struct stm32_rtc_calendar *cur, ++ struct stm32_rtc_calendar *ref) ++{ ++ unsigned long long val_r; ++ unsigned long long val_c; ++ ++ val_r = stm32_rtc_get_second_fraction(ref); ++ val_c = stm32_rtc_get_second_fraction(cur); ++ ++ if (val_c >= val_r) { ++ return val_c - val_r; ++ } else { ++ return 1000U - val_r + val_c; ++ } ++} ++ ++/******************************************************************************* ++ * This function computes the time difference between two timestamps. ++ * It includes seconds, minutes and hours. ++ * Here again the returned value is in milliseconds. ++ ******************************************************************************/ ++static unsigned long long stm32_rtc_diff_time(struct stm32_rtc_time *current, ++ struct stm32_rtc_time *ref) ++{ ++ signed long long diff_in_s; ++ signed long long curr_s; ++ signed long long ref_s; ++ ++ curr_s = (signed long long)current->sec + ++ (((signed long long)current->min + ++ (((signed long long)current->hour * 60))) * 60); ++ ++ ref_s = (signed long long)ref->sec + ++ (((signed long long)ref->min + ++ (((signed long long)ref->hour * 60))) * 60); ++ ++ diff_in_s = curr_s - ref_s; ++ if (diff_in_s < 0) { ++ diff_in_s += 24 * 60 * 60; ++ } ++ ++ return (unsigned long long)diff_in_s * 1000U; ++} ++ ++/******************************************************************************* ++ * This function determines if the year is leap or not. ++ * Returned value is true or false. ++ ******************************************************************************/ ++static bool stm32_is_a_leap_year(uint32_t year) ++{ ++ return ((year % 4U) == 0U) && ++ (((year % 100U) != 0U) || ((year % 400U) == 0U)); ++} ++ ++/******************************************************************************* ++ * This function computes the date difference between two timestamps. ++ * It includes days, months, years, with exceptions. ++ * Here again the returned value is in milliseconds. ++ ******************************************************************************/ ++static unsigned long long stm32_rtc_diff_date(struct stm32_rtc_time *current, ++ struct stm32_rtc_time *ref) ++{ ++ uint32_t diff_in_days = 0; ++ uint32_t m; ++ static const uint8_t month_len[NB_MONTHS] = { ++ 31, 28, 31, 30, 31, 30, ++ 31, 31, 30, 31, 30, 31 ++ }; ++ ++ /* Get the number of non-entire month days */ ++ if (current->day >= ref->day) { ++ diff_in_days += current->day - ref->day; ++ } else { ++ diff_in_days += (uint32_t)month_len[ref->month - 1U] - ++ ref->day + current->day; ++ } ++ ++ /* Get the number of entire months, and compute the related days */ ++ if (current->month > (ref->month + 1U)) { ++ for (m = (ref->month + 1U); (m < current->month) && ++ (m < 12U); m++) { ++ diff_in_days += (uint32_t)month_len[m - 1U]; ++ } ++ } ++ ++ if (current->month < (ref->month - 1U)) { ++ for (m = 1U; (m < current->month) && (m < 12U); m++) { ++ diff_in_days += (uint32_t)month_len[m - 1U]; ++ } ++ ++ for (m = (ref->month + 1U); m < 12U; m++) { ++ diff_in_days += (uint32_t)month_len[m - 1U]; ++ } ++ } ++ ++ /* Get complete years */ ++ if (current->year > (ref->year + 1U)) { ++ diff_in_days += (current->year - ref->year - 1U) * 365U; ++ } ++ ++ /* Particular cases: leap years (one day more) */ ++ if (diff_in_days > 0U) { ++ if (current->year == ref->year) { ++ if (stm32_is_a_leap_year(current->year)) { ++ if ((ref->month <= 2U) && ++ (current->month >= 3U) && ++ (current->day <= 28U)) { ++ diff_in_days++; ++ } ++ } ++ } else { ++ uint32_t y; ++ ++ /* Ref year is leap */ ++ if ((stm32_is_a_leap_year(ref->year)) && ++ (ref->month <= 2U) && (ref->day <= 28U)) { ++ diff_in_days++; ++ } ++ ++ /* Current year is leap */ ++ if ((stm32_is_a_leap_year(current->year)) && ++ (current->month >= 3U)) { ++ diff_in_days++; ++ } ++ ++ /* Interleaved years are leap */ ++ for (y = ref->year + 1U; y < current->year; y++) { ++ if (stm32_is_a_leap_year(y)) { ++ diff_in_days++; ++ } ++ } ++ } ++ } ++ ++ return (24ULL * 60U * 60U * 1000U) * (unsigned long long)diff_in_days; ++} ++ ++/******************************************************************************* ++ * This function computes the date difference between two rtc value. ++ * Here again the returned value is in milliseconds. ++ ******************************************************************************/ ++unsigned long long stm32_rtc_diff_calendar(struct stm32_rtc_calendar *cur, ++ struct stm32_rtc_calendar *ref) ++{ ++ unsigned long long diff_in_ms = 0; ++ struct stm32_rtc_time curr_t; ++ struct stm32_rtc_time ref_t; ++ ++ stm32mp_clk_enable(rtc_dev.clock); ++ ++ stm32_rtc_get_date(cur, &curr_t); ++ stm32_rtc_get_date(ref, &ref_t); ++ stm32_rtc_get_time(cur, &curr_t); ++ stm32_rtc_get_time(ref, &ref_t); ++ ++ diff_in_ms += stm32_rtc_diff_frac(cur, ref); ++ diff_in_ms += stm32_rtc_diff_time(&curr_t, &ref_t); ++ diff_in_ms += stm32_rtc_diff_date(&curr_t, &ref_t); ++ ++ stm32mp_clk_disable(rtc_dev.clock); ++ ++ return diff_in_ms; ++} ++ ++/******************************************************************************* ++ * This function fill the RTC timestamp structure. ++ ******************************************************************************/ ++void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts) ++{ ++ stm32_rtc_regs_lock(); ++ stm32mp_clk_enable(rtc_dev.clock); ++ ++ if ((mmio_read_32(rtc_dev.base + RTC_SR) & RTC_SR_TSF) != 0U) { ++ /* Print timestamp for tamper event */ ++ stm32_rtc_read_timestamp(tamp_ts); ++ mmio_setbits_32(rtc_dev.base + RTC_SCR, RTC_SCR_CTSF); ++ if ((mmio_read_32(rtc_dev.base + RTC_SR) & RTC_SR_TSOVF) != ++ 0U) { ++ /* Overflow detected */ ++ mmio_setbits_32(rtc_dev.base + RTC_SCR, RTC_SCR_CTSOVF); ++ } ++ } ++ ++ stm32mp_clk_disable(rtc_dev.clock); ++ stm32_rtc_regs_unlock(); ++} ++ ++/******************************************************************************* ++ * This function enable the timestamp bit for tamper and secure timestamp ++ * access. ++ ******************************************************************************/ ++void stm32_rtc_set_tamper_timestamp(void) ++{ ++ stm32_rtc_regs_lock(); ++ stm32mp_clk_enable(rtc_dev.clock); ++ ++ stm32_rtc_write_unprotect(); ++ ++ /* Enable tamper timestamper */ ++ mmio_setbits_32(rtc_dev.base + RTC_CR, RTC_CR_TAMPTS); ++ ++ /* Secure Timestamp bit */ ++ mmio_clrbits_32(rtc_dev.base + RTC_SMCR, RTC_SMCR_TS_DPROT); ++ ++ stm32_rtc_write_protect(); ++ ++ stm32mp_clk_disable(rtc_dev.clock); ++ stm32_rtc_regs_unlock(); ++} ++ ++/******************************************************************************* ++ * This function return state of tamper timestamp. ++ ******************************************************************************/ ++bool stm32_rtc_is_timestamp_enable(void) ++{ ++ bool ret; ++ ++ stm32mp_clk_enable(rtc_dev.clock); ++ ++ ret = (mmio_read_32(rtc_dev.base + RTC_CR) & RTC_CR_TAMPTS) != 0U; ++ ++ stm32mp_clk_disable(rtc_dev.clock); ++ ++ return ret; ++} ++ ++/******************************************************************************* ++ * RTC initialisation function. ++ ******************************************************************************/ ++int stm32_rtc_init(void) ++{ ++ int node; ++ ++ node = dt_get_node(&rtc_dev, -1, RTC_COMPAT); ++ if (node < 0) { ++ return node; ++ } ++ ++ return 0; ++} +diff --git a/include/drivers/st/stm32_rtc.h b/include/drivers/st/stm32_rtc.h +new file mode 100644 +index 000000000..128dd2d14 +--- /dev/null ++++ b/include/drivers/st/stm32_rtc.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32_RTC_H ++#define STM32_RTC_H ++ ++#include ++ ++#define RTC_TR 0x00U ++#define RTC_DR 0x04U ++#define RTC_SSR 0x08U ++#define RTC_ICSR 0x0CU ++#define RTC_PRER 0x10U ++#define RTC_WUTR 0x14U ++#define RTC_CR 0x18U ++#define RTC_SMCR 0x20U ++#define RTC_WPR 0x24U ++#define RTC_CALR 0x28U ++#define RTC_SHIFTR 0x2CU ++#define RTC_TSTR 0x30U ++#define RTC_TSDR 0x34U ++#define RTC_TSSSR 0x38U ++#define RTC_ALRMAR 0x40U ++#define RTC_ALRMASSR 0x44U ++#define RTC_ALRMBR 0x48U ++#define RTC_ALRMBSSR 0x4CU ++#define RTC_SR 0x50U ++#define RTC_SCR 0x5CU ++#define RTC_OR 0x60U ++ ++struct stm32_rtc_calendar { ++ uint32_t ssr; ++ uint32_t tr; ++ uint32_t dr; ++}; ++ ++enum months { ++ JANUARY = 1, ++ FEBRUARY, ++ MARCH, ++ APRIL, ++ MAY, ++ JUNE, ++ JULY, ++ AUGUST, ++ SEPTEMBER, ++ OCTOBER, ++ NOVEMBER, ++ DECEMBER, ++ NB_MONTHS = 12 ++}; ++ ++struct stm32_rtc_time { ++ uint32_t hour; ++ uint32_t min; ++ uint32_t sec; ++ uint32_t wday; ++ uint32_t day; ++ enum months month; ++ uint32_t year; ++}; ++ ++void stm32_rtc_get_calendar(struct stm32_rtc_calendar *calendar); ++unsigned long long stm32_rtc_diff_calendar(struct stm32_rtc_calendar *current, ++ struct stm32_rtc_calendar *ref); ++void stm32_rtc_set_tamper_timestamp(void); ++bool stm32_rtc_is_timestamp_enable(void); ++void stm32_rtc_get_timestamp(struct stm32_rtc_time *tamp_ts); ++int stm32_rtc_init(void); ++ ++/* SMP protection on RTC registers access */ ++void stm32_rtc_regs_lock(void); ++void stm32_rtc_regs_unlock(void); ++ ++#endif /* STM32_RTC_H */ +diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h +index 1ebd39ff7..81ae5d8ae 100644 +--- a/include/drivers/st/stm32mp1_clk.h ++++ b/include/drivers/st/stm32mp1_clk.h +@@ -53,6 +53,8 @@ static inline void stm32mp1_clk_disable_secure(unsigned long id) + + unsigned int stm32mp1_clk_get_refcount(unsigned long id); + ++bool stm32mp1_rtc_get_read_twice(void); ++ + /* SMP protection on RCC registers access */ + void stm32mp1_clk_rcc_regs_lock(void); + void stm32mp1_clk_rcc_regs_unlock(void); +diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +index 4188cc58a..6c7107ca2 100644 +--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk ++++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +@@ -7,6 +7,7 @@ + SP_MIN_WITH_SECURE_FIQ := 1 + + BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ ++ drivers/st/rtc/stm32_rtc.c \ + plat/st/stm32mp1/sp_min/sp_min_setup.c \ + plat/st/stm32mp1/stm32mp1_pm.c \ + plat/st/stm32mp1/stm32mp1_topology.c +diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c +index e10dfbfc0..ff69358e0 100644 +--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c ++++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -147,16 +148,11 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, + } + + /******************************************************************************* +- * Initialize the MMU, security and the GIC. ++ * Set security setup in sp_min + ******************************************************************************/ +-void sp_min_platform_setup(void) ++static void stm32mp1_sp_min_security_setup(void) + { +- /* Initialize tzc400 after DDR initialization */ +- stm32mp1_security_setup(); +- +- generic_delay_timer_init(); +- +- stm32mp1_gic_init(); ++ int ret; + + /* Unlock ETZPC securable peripherals */ + #define STM32MP1_ETZPC_BASE 0x5C007000U +@@ -168,6 +164,28 @@ void sp_min_platform_setup(void) + set_gpio_secure_cfg(GPIO_BANK_Z, pin, false); + } + ++ /* Init rtc driver */ ++ ret = stm32_rtc_init(); ++ if (ret < 0) { ++ WARN("RTC driver init error %i\n", ret); ++ } ++} ++ ++/******************************************************************************* ++ * Initialize the MMU, security and the GIC. ++ ******************************************************************************/ ++void sp_min_platform_setup(void) ++{ ++ /* Initialize tzc400 after DDR initialization */ ++ stm32mp1_security_setup(); ++ ++ generic_delay_timer_init(); ++ ++ stm32mp1_gic_init(); ++ ++ /* Update security settings */ ++ stm32mp1_sp_min_security_setup(); ++ + if (stm32_iwdg_init() < 0) { + panic(); + } +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0005-stm32mp-add-function-to-protect-access-on-PWR-regist.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0005-stm32mp-add-function-to-protect-access-on-PWR-regist.patch new file mode 100644 index 0000000..3fc2cef --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0005-stm32mp-add-function-to-protect-access-on-PWR-regist.patch @@ -0,0 +1,70 @@ +From 4d4214a8dea31d531df6739e6f74005090018faa Mon Sep 17 00:00:00 2001 +From: Yann Gautier +Date: Wed, 24 Apr 2019 13:38:41 +0200 +Subject: [PATCH 5/7] stm32mp: add function to protect access on PWR registers + +In SMP context, we need to add spinlocks to protect against concurrent +accesses on PWR registers. + +Change-Id: I27cb698ffa085eca7b61b042ce5ccaa1fd2daaf4 +Signed-off-by: Yann Gautier +--- + plat/st/common/include/stm32mp_common.h | 4 ++++ + plat/st/common/stm32mp_common.c | 17 +++++++++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h +index 4f8567979..052402854 100644 +--- a/plat/st/common/include/stm32mp_common.h ++++ b/plat/st/common/include/stm32mp_common.h +@@ -33,6 +33,10 @@ uintptr_t stm32mp_rcc_base(void); + /* Check MMU status to allow spinlock use */ + bool stm32mp_lock_available(void); + ++/* SMP protection on PWR registers access */ ++void stm32mp_pwr_regs_lock(void); ++void stm32mp_pwr_regs_unlock(void); ++ + /* Get IWDG platform instance ID from peripheral IO memory base address */ + uint32_t stm32_iwdg_get_instance(uintptr_t base); + +diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c +index afa87f487..5e7c74b48 100644 +--- a/plat/st/common/stm32mp_common.c ++++ b/plat/st/common/stm32mp_common.c +@@ -12,8 +12,11 @@ + #include + #include + #include ++#include + #include + ++static struct spinlock lock; ++ + uintptr_t plat_get_ns_image_entrypoint(void) + { + return BL33_BASE; +@@ -96,6 +99,20 @@ bool stm32mp_lock_available(void) + return (read_sctlr() & c_m_bits) == c_m_bits; + } + ++void stm32mp_pwr_regs_lock(void) ++{ ++ if (stm32mp_lock_available()) { ++ spin_lock(&lock); ++ } ++} ++ ++void stm32mp_pwr_regs_unlock(void) ++{ ++ if (stm32mp_lock_available()) { ++ spin_unlock(&lock); ++ } ++} ++ + uintptr_t stm32_get_gpio_bank_base(unsigned int bank) + { + if (bank == GPIO_BANK_Z) { +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0006-ddr-stm32mp1-add-DDR-self-refresh-management.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0006-ddr-stm32mp1-add-DDR-self-refresh-management.patch new file mode 100644 index 0000000..ca1e3c2 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0006-ddr-stm32mp1-add-DDR-self-refresh-management.patch @@ -0,0 +1,801 @@ +From 3e5e9e77b190336b040389d0a5e62bfea7e22ae4 Mon Sep 17 00:00:00 2001 +From: Yann Gautier +Date: Wed, 24 Apr 2019 13:40:04 +0200 +Subject: [PATCH 6/7] ddr: stm32mp1: add DDR self-refresh management + +In order to prepare low power use cases, functions are added to manage +the entry or exit of DDR from self-refresh mode. + +Change-Id: I8a1cbc48d613366fca69b4fc6870e53f8b917598 +Signed-off-by: Yann Gautier +--- + drivers/st/ddr/stm32mp1_ddr.c | 134 +++++- + drivers/st/ddr/stm32mp1_ddr_helpers.c | 472 ++++++++++++++++++++++ + include/drivers/st/stm32mp1_ddr.h | 6 +- + include/drivers/st/stm32mp1_ddr_helpers.h | 9 +- + plat/st/common/stm32mp_dt.c | 2 - + plat/st/stm32mp1/stm32mp1_def.h | 3 + + 6 files changed, 619 insertions(+), 7 deletions(-) + +diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c +index 7d89d027e..f5cffd887 100644 +--- a/drivers/st/ddr/stm32mp1_ddr.c ++++ b/drivers/st/ddr/stm32mp1_ddr.c +@@ -29,6 +29,7 @@ struct reg_desc { + + #define INVALID_OFFSET 0xFFU + ++#define TIMESLOT_US_1US 1U + #define TIMEOUT_US_1S 1000000U + + #define DDRCTL_REG(x, y) \ +@@ -698,6 +699,83 @@ static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl, + stm32mp1_wait_sw_done_ack(ctl); + } + ++static void stm32mp1_refresh_cmd(struct stm32mp1_ddrctl *ctl) ++{ ++ uint32_t dbgstat; ++ ++ do { ++ dbgstat = mmio_read_32((uintptr_t)&ctl->dbgstat); ++ } while ((dbgstat & DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY) != 0U); ++ ++ mmio_setbits_32((uintptr_t)&ctl->dbgcmd, DDRCTRL_DBGCMD_RANK0_REFRESH); ++} ++ ++/* Refresh compensation by forcing refresh command ++ * Rule1: Tref should be always < tREFW ? R x tREBW/8 ++ * Rule2: refcomp = RU(Tref/tREFI) = RU(RxTref/tREFW) ++ */ ++static ++void stm32mp1_refresh_compensation(const struct stm32mp1_ddr_config *config, ++ struct stm32mp1_ddrctl *ctl, ++ uint64_t start) ++{ ++ uint32_t tck_ps; ++ uint64_t time_us, tref, trefi, refcomp, i; ++ ++ time_us = timeout_init_us(0) - start; ++ tck_ps = 1000000000U / config->info.speed; ++ if (tck_ps == 0U) { ++ return; ++ } ++ /* ref = refresh time in tck */ ++ tref = time_us * 1000000U / tck_ps; ++ trefi = ((mmio_read_32((uintptr_t)&ctl->rfshtmg) & ++ DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK) ++ >> DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT) * 32U; ++ if (trefi == 0U) { ++ return; ++ } ++ ++ /* div round up : number of refresh to compensate */ ++ refcomp = (tref + trefi - 1U) / trefi; ++ ++ for (i = 0; i < refcomp; i++) { ++ stm32mp1_refresh_cmd(ctl); ++ } ++} ++ ++static void stm32mp1_self_refresh_zcal(struct ddr_info *priv, uint32_t zdata) ++{ ++ /* sequence for PUBL I/O Data Retention during Power-Down */ ++ ++ /* 10. Override ZQ calibration with previously (pre-retention) ++ * calibrated values. This is done by writing 1 to ZQ0CRN.ZDEN ++ * and the override data to ZQ0CRN.ZDATA. ++ */ ++ mmio_setbits_32((uintptr_t)&priv->phy->zq0cr0, DDRPHYC_ZQ0CRN_ZDEN); ++ ++ mmio_clrsetbits_32((uintptr_t)&priv->phy->zq0cr0, ++ DDRPHYC_ZQ0CRN_ZDATA_MASK, ++ zdata << DDRPHYC_ZQ0CRN_ZDATA_SHIFT); ++ ++ /* 11. De-assert the PHY_top data retention enable signals ++ * (ret_en or ret_en_i/ret_en_n_i). ++ */ ++ mmio_setbits_32((uintptr_t)(priv->pwr) + PWR_CR3, PWR_CR3_DDRSRDIS); ++ mmio_clrbits_32((uintptr_t)(priv->pwr) + PWR_CR3, PWR_CR3_DDRRETEN); ++ ++ /* 12. Remove ZQ calibration override by writing 0 to ZQ0CRN.ZDEN. */ ++ mmio_clrbits_32((uintptr_t)&priv->phy->zq0cr0, DDRPHYC_ZQ0CRN_ZDEN); ++ ++ /* 13. Trigger ZQ calibration by writing 1 to PIR.INIT ++ * and '1' to PIR.ZCAL ++ */ ++ /* 14. Wait for ZQ calibration to finish by polling a 1 status ++ * on PGSR.IDONE. ++ */ ++ stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_ZCAL); ++} ++ + static int board_ddr_power_init(enum ddr_type ddr_type) + { + if (dt_pmic_status() > 0) { +@@ -710,8 +788,9 @@ static int board_ddr_power_init(enum ddr_type ddr_type) + void stm32mp1_ddr_init(struct ddr_info *priv, + struct stm32mp1_ddr_config *config) + { +- uint32_t pir; ++ uint32_t pir, ddr_reten; + int ret = -EINVAL; ++ uint64_t time; + + if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) { + ret = board_ddr_power_init(STM32MP_DDR3); +@@ -730,6 +809,27 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + VERBOSE("name = %s\n", config->info.name); + VERBOSE("speed = %d kHz\n", config->info.speed); + VERBOSE("size = 0x%x\n", config->info.size); ++ if (config->self_refresh) { ++ VERBOSE("sel-refresh exit (zdata = 0x%x)\n", config->zdata); ++ } ++ ++ /* Check DDR PHY pads retention */ ++ ddr_reten = mmio_read_32((uint32_t)(priv->pwr) + PWR_CR3) & ++ PWR_CR3_DDRRETEN; ++ if (config->self_refresh) { ++ if (ddr_reten == 0U) { ++ VERBOSE("self-refresh aborted: no retention\n"); ++ config->self_refresh = false; ++ } ++ } else { ++ if (ddr_reten != 0U) { ++ VERBOSE("disable DDR PHY retention\n"); ++ mmio_setbits_32((uint32_t)(priv->pwr) + PWR_CR3, ++ PWR_CR3_DDRSRDIS); ++ mmio_clrbits_32((uint32_t)(priv->pwr) + PWR_CR3, ++ PWR_CR3_DDRRETEN); ++ } ++ } + + /* DDR INIT SEQUENCE */ + +@@ -790,6 +890,12 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + set_reg(priv, REG_TIMING, &config->c_timing); + set_reg(priv, REG_MAP, &config->c_map); + ++ /* Keep the controller in self-refresh mode */ ++ if (config->self_refresh) { ++ mmio_setbits_32((uintptr_t)&priv->ctl->pwrctl, ++ DDRCTRL_PWRCTL_SELFREF_SW); ++ } ++ + /* Skip CTRL init, SDRAM init is done by PHY PUBL */ + mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0, + DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK, +@@ -843,8 +949,20 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + pir |= DDRPHYC_PIR_DRAMRST; /* Only for DDR3 */ + } + ++ /* Treat self-refresh exit : hot boot */ ++ if (config->self_refresh) { ++ /* DDR in self refresh mode, remove zcal & reset & init */ ++ pir &= ~(DDRPHYC_PIR_ZCAL & DDRPHYC_PIR_DRAMRST ++ & DDRPHYC_PIR_DRAMINIT); ++ pir |= DDRPHYC_PIR_ZCALBYP; ++ } ++ + stm32mp1_ddrphy_init(priv->phy, pir); + ++ if (config->self_refresh) { ++ stm32mp1_self_refresh_zcal(priv, config->zdata); ++ } ++ + /* + * 6. SET DFIMISC.dfi_init_complete_en to 1 + * Enable quasi-dynamic register programming. +@@ -865,6 +983,13 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + */ + + /* Wait uMCTL2 ready */ ++ ++ /* Trigger self-refresh exit */ ++ if (config->self_refresh) { ++ mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl, ++ DDRCTRL_PWRCTL_SELFREF_SW); ++ } ++ + stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL); + + /* Switch to DLL OFF mode */ +@@ -874,6 +999,8 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + + VERBOSE("DDR DQS training : "); + ++ time = timeout_init_us(0); ++ + /* + * 8. Disable Auto refresh and power down by setting + * - RFSHCTL3.dis_au_refresh = 1 +@@ -898,6 +1025,11 @@ void stm32mp1_ddr_init(struct ddr_info *priv, + /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */ + stm32mp1_ddrphy_idone_wait(priv->phy); + ++ /* Refresh compensation: forcing refresh command */ ++ if (config->self_refresh) { ++ stm32mp1_refresh_compensation(config, priv->ctl, time); ++ } ++ + /* + * 12. set back registers in step 8 to the orginal values if desidered + */ +diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c +index fcb4cfcfd..2071bb2a2 100644 +--- a/drivers/st/ddr/stm32mp1_ddr_helpers.c ++++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c +@@ -6,8 +6,14 @@ + + #include + ++#include ++#include ++#include + #include + #include ++#include ++ ++#define TIMEOUT_500US 500U + + void ddr_enable_clock(void) + { +@@ -22,3 +28,469 @@ void ddr_enable_clock(void) + + stm32mp1_clk_rcc_regs_unlock(); + } ++ ++static void do_sw_handshake(void) ++{ ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE); ++} ++ ++static void do_sw_ack(void) ++{ ++ uint64_t timeout; ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE); ++ ++ timeout = timeout_init_us(TIMEOUT_500US); ++ while ((mmio_read_32(ddrctrl_base + DDRCTRL_SWSTAT) & ++ DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U) { ++ if (timeout_elapsed(timeout)) { ++ panic(); ++ } ++ } ++} ++ ++static int ddr_sw_self_refresh_in(void) ++{ ++ uint64_t timeout; ++ uint32_t stat; ++ uint32_t operating_mode; ++ uint32_t selref_type; ++ uint8_t op_mode_changed = 0; ++ uintptr_t rcc_base = stm32mp_rcc_base(); ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); ++ ++ stm32mp1_clk_rcc_regs_lock(); ++ ++ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); ++ ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ /* Blocks AXI ports from taking anymore transactions */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, ++ DDRCTRL_PCTRL_N_PORT_EN); ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, ++ DDRCTRL_PCTRL_N_PORT_EN); ++ ++ /* Waits unit all AXI ports are idle ++ * Poll PSTAT.rd_port_busy_n = 0 ++ * Poll PSTAT.wr_port_busy_n = 0 ++ */ ++ timeout = timeout_init_us(TIMEOUT_500US); ++ while (mmio_read_32(ddrctrl_base + DDRCTRL_PSTAT)) { ++ if (timeout_elapsed(timeout)) { ++ goto pstat_failed; ++ } ++ } ++ /* SW Self-Refresh entry */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_SELFREF_SW); ++ ++ /* Wait operating mode change in self-refresh mode ++ * with STAT.operating_mode[1:0]==11. ++ * Ensure transition to self-refresh was due to software ++ * by checking also that STAT.selfref_type[1:0]=2. ++ */ ++ timeout = timeout_init_us(TIMEOUT_500US); ++ while (!timeout_elapsed(timeout)) { ++ stat = mmio_read_32(ddrctrl_base + DDRCTRL_STAT); ++ operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK; ++ selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK; ++ ++ if ((operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) && ++ (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) { ++ op_mode_changed = 1; ++ break; ++ } ++ } ++ ++ if (op_mode_changed == 0U) ++ goto selfref_sw_failed; ++ ++ /* IOs powering down (PUBL registers) */ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDR); ++ ++ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_ACIOCR, ++ DDRPHYC_ACIOCR_CKPDD_MASK, ++ DDRPHYC_ACIOCR_CKPDD_0); ++ ++ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_ACIOCR, ++ DDRPHYC_ACIOCR_CKPDR_MASK, ++ DDRPHYC_ACIOCR_CKPDR_0); ++ ++ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_ACIOCR, ++ DDRPHYC_ACIOCR_CSPDD_MASK, ++ DDRPHYC_ACIOCR_CSPDD_0); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR); ++ ++ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_DSGCR, ++ DDRPHYC_DSGCR_ODTPDD_MASK, ++ DDRPHYC_DSGCR_ODTPDD_0); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD); ++ ++ mmio_clrsetbits_32(ddrphyc_base + DDRPHYC_DSGCR, ++ DDRPHYC_DSGCR_CKEPDD_MASK, ++ DDRPHYC_DSGCR_CKEPDD_0); ++ ++ /* Disable PZQ cell (PUBL register) */ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD); ++ ++ /* Activate sw retention in PWRCTRL */ ++ stm32mp_pwr_regs_lock(); ++ mmio_setbits_32(pwr_base + PWR_CR3, PWR_CR3_DDRRETEN); ++ stm32mp_pwr_regs_unlock(); ++ ++ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */ ++ stm32mp1_clk_rcc_regs_lock(); ++ mmio_setbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ /* Disable all DLLs: GLITCH window */ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, ++ DDRPHYC_ACDLLCR_DLLDIS); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX0DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX1DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX2DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_DX3DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ stm32mp1_clk_rcc_regs_lock(); ++ ++ /* Switch controller clocks (uMCTL2/PUBL) to DLL output clock */ ++ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); ++ ++ /* Deactivate all DDR clocks */ ++ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, ++ RCC_DDRITFCR_DDRC1EN | ++ RCC_DDRITFCR_DDRC2EN | ++ RCC_DDRITFCR_DDRCAPBEN | ++ RCC_DDRITFCR_DDRPHYCAPBEN); ++ ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ return 0; ++ ++selfref_sw_failed: ++ /* This bit should be cleared to restore DDR in its previous state */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_SELFREF_SW); ++ ++pstat_failed: ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, ++ DDRCTRL_PCTRL_N_PORT_EN); ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, ++ DDRCTRL_PCTRL_N_PORT_EN); ++ ++ return -1; ++} ++ ++int ddr_sw_self_refresh_exit(void) ++{ ++ uint64_t timeout; ++ uintptr_t rcc_base = stm32mp_rcc_base(); ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); ++ ++ /* Enable all clocks */ ++ ddr_enable_clock(); ++ ++ do_sw_handshake(); ++ ++ /* Mask dfi_init_complete_en */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_DFIMISC, ++ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); ++ ++ do_sw_ack(); ++ ++ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */ ++ stm32mp1_clk_rcc_regs_lock(); ++ mmio_setbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ /* Enable all DLLs: GLITCH window */ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, ++ DDRPHYC_ACDLLCR_DLLDIS); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX0DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX1DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX2DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DX3DLLCR, ++ DDRPHYC_DXNDLLCR_DLLDIS); ++ ++ /* Additional delay to avoid early DLL clock switch */ ++ udelay(10); ++ ++ /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */ ++ stm32mp1_clk_rcc_regs_lock(); ++ mmio_clrbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL); ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, ++ DDRPHYC_ACDLLCR_DLLSRST); ++ ++ udelay(10); ++ ++ mmio_setbits_32(ddrphyc_base + DDRPHYC_ACDLLCR, ++ DDRPHYC_ACDLLCR_DLLSRST); ++ ++ /* PHY partial init: (DLL lock and ITM reset) */ ++ mmio_write_32(ddrphyc_base + DDRPHYC_PIR, ++ DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK | ++ DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_INIT); ++ ++ /* Need to wait at least 10 clock cycles before accessing PGSR */ ++ udelay(1); ++ ++ /* Pool end of init */ ++ timeout = timeout_init_us(TIMEOUT_500US); ++ ++ while ((mmio_read_32(ddrphyc_base + DDRPHYC_PGSR) & ++ DDRPHYC_PGSR_IDONE) == 0U) { ++ if (timeout_elapsed(timeout)) { ++ return -1; ++ } ++ } ++ ++ do_sw_handshake(); ++ ++ /* Unmask dfi_init_complete_en to uMCTL2 */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_DFIMISC, ++ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN); ++ ++ do_sw_ack(); ++ ++ /* Deactivate sw retention in PWR */ ++ stm32mp_pwr_regs_lock(); ++ mmio_clrbits_32(pwr_base + PWR_CR3, PWR_CR3_DDRRETEN); ++ stm32mp_pwr_regs_unlock(); ++ ++ /* Enable PZQ cell (PUBL register) */ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD); ++ ++ /* Enable pad drivers */ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACIOCR, ++ DDRPHYC_ACIOCR_CKPDD_MASK); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_ACIOCR, ++ DDRPHYC_ACIOCR_CSPDD_MASK); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DSGCR, ++ DDRPHYC_DSGCR_ODTPDD_MASK); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD); ++ ++ mmio_clrbits_32(ddrphyc_base + DDRPHYC_DSGCR, ++ DDRPHYC_DSGCR_CKEPDD_MASK); ++ ++ /* Remove selfrefresh */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_SELFREF_SW); ++ ++ /* Wait operating_mode == normal */ ++ timeout = timeout_init_us(TIMEOUT_500US); ++ while ((mmio_read_32(ddrctrl_base + DDRCTRL_STAT) & ++ DDRCTRL_STAT_OPERATING_MODE_MASK) != ++ DDRCTRL_STAT_OPERATING_MODE_NORMAL) { ++ if (timeout_elapsed(timeout)) { ++ return -1; ++ } ++ } ++ ++ /* AXI ports are no longer blocked from taking transactions */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_0, ++ DDRCTRL_PCTRL_N_PORT_EN); ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PCTRL_1, ++ DDRCTRL_PCTRL_N_PORT_EN); ++ ++ stm32mp1_clk_rcc_regs_lock(); ++ ++ mmio_setbits_32(rcc_base + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); ++ ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ return 0; ++} ++ ++int ddr_standby_sr_entry(uint32_t *zq0cr0_zdata) ++{ ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ uintptr_t ddrphyc_base = stm32mp_ddrphyc_base(); ++ ++ /* Save IOs calibration values */ ++ if (zq0cr0_zdata != NULL) { ++ *zq0cr0_zdata = mmio_read_32(ddrphyc_base + DDRPHYC_ZQ0CR0) & ++ DDRPHYC_ZQ0CRN_ZDATA_MASK; ++ } ++ ++ /* Put DDR in Self-Refresh */ ++ if (ddr_sw_self_refresh_in() != 0) { ++ return -1; ++ } ++ ++ /* Enable I/O retention mode in standby */ ++ stm32mp_pwr_regs_lock(); ++ mmio_setbits_32(pwr_base + PWR_CR3, PWR_CR3_DDRSREN); ++ stm32mp_pwr_regs_unlock(); ++ ++ return 0; ++} ++ ++void ddr_sr_mode_ssr(void) ++{ ++ uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR; ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ ++ stm32mp1_clk_rcc_regs_lock(); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1EN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2EN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBLPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCAPBLPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCAPBEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCEN); ++ ++ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN); ++ ++ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK); ++ ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ /* Disable HW LP interface of uMCTL2 */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_HWLPCTL, ++ DDRCTRL_HWLPCTL_HW_LP_EN); ++ ++ /* Configure Automatic LP modes of uMCTL2 */ ++ mmio_clrsetbits_32(ddrctrl_base + DDRCTRL_PWRTMG, ++ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK, ++ DDRCTRL_PWRTMG_SELFREF_TO_X32_0); ++ ++ /* ++ * Disable Clock disable with LP modes ++ * (used in RUN mode for LPDDR2 with specific timing). ++ */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE); ++ ++ /* Disable automatic Self-Refresh mode */ ++ mmio_clrbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_SELFREF_EN); ++} ++ ++void ddr_sr_mode_asr(void) ++{ ++ uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR; ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ ++ stm32mp1_clk_rcc_regs_lock(); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN); ++ ++ mmio_clrsetbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK, ++ RCC_DDRITFCR_DDRCKMOD_ASR1); ++ ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ /* Enable HW LP interface of uMCTL2 */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_HWLPCTL, ++ DDRCTRL_HWLPCTL_HW_LP_EN); ++ ++ /* Configure Automatic LP modes of uMCTL2 */ ++ mmio_clrsetbits_32(ddrctrl_base + DDRCTRL_PWRTMG, ++ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK, ++ DDRCTRL_PWRTMG_SELFREF_TO_X32_0); ++ ++ /* ++ * Enable Clock disable with LP modes ++ * (used in RUN mode for LPDDR2 with specific timing). ++ */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE); ++ ++ /* Enable automatic Self-Refresh for ASR mode */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_SELFREF_EN); ++} ++ ++void ddr_sr_mode_hsr(void) ++{ ++ uintptr_t rcc_ddritfcr = stm32mp_rcc_base() + RCC_DDRITFCR; ++ uintptr_t ddrctrl_base = stm32mp_ddrctrl_base(); ++ ++ stm32mp1_clk_rcc_regs_lock(); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_AXIDCGEN); ++ ++ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC1LPEN); ++ ++ mmio_clrbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRC2LPEN); ++ ++ mmio_setbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRPHYCLPEN); ++ ++ mmio_clrsetbits_32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK, ++ RCC_DDRITFCR_DDRCKMOD_HSR1); ++ ++ stm32mp1_clk_rcc_regs_unlock(); ++ ++ /* Enable HW LP interface of uMCTL2 */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_HWLPCTL, ++ DDRCTRL_HWLPCTL_HW_LP_EN); ++ ++ /* Configure Automatic LP modes of uMCTL2 */ ++ mmio_clrsetbits_32(ddrctrl_base + DDRCTRL_PWRTMG, ++ DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK, ++ DDRCTRL_PWRTMG_SELFREF_TO_X32_0); ++ ++ /* ++ * Enable Clock disable with LP modes ++ * (used in RUN mode for LPDDR2 with specific timing). ++ */ ++ mmio_setbits_32(ddrctrl_base + DDRCTRL_PWRCTL, ++ DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE); ++} +diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h +index 4ab37d6b4..f52609f66 100644 +--- a/include/drivers/st/stm32mp1_ddr.h ++++ b/include/drivers/st/stm32mp1_ddr.h +@@ -8,9 +8,6 @@ + #define STM32MP1_DDR_H + + #include +-#include +- +-#define DT_DDR_COMPAT "st,stm32mp1-ddr" + + struct stm32mp1_ddr_size { + uint64_t base; +@@ -166,9 +163,12 @@ struct stm32mp1_ddr_config { + struct stm32mp1_ddrphy_reg p_reg; + struct stm32mp1_ddrphy_timing p_timing; + struct stm32mp1_ddrphy_cal p_cal; ++ bool self_refresh; ++ uint32_t zdata; + }; + + int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed); + void stm32mp1_ddr_init(struct ddr_info *priv, + struct stm32mp1_ddr_config *config); ++ + #endif /* STM32MP1_DDR_H */ +diff --git a/include/drivers/st/stm32mp1_ddr_helpers.h b/include/drivers/st/stm32mp1_ddr_helpers.h +index 38f24152a..80bf9de6f 100644 +--- a/include/drivers/st/stm32mp1_ddr_helpers.h ++++ b/include/drivers/st/stm32mp1_ddr_helpers.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -7,6 +7,13 @@ + #ifndef STM32MP1_DDR_HELPERS_H + #define STM32MP1_DDR_HELPERS_H + ++#include ++ + void ddr_enable_clock(void); ++int ddr_sw_self_refresh_exit(void); ++int ddr_standby_sr_entry(uint32_t *zq0cr0_zdata); ++void ddr_sr_mode_ssr(void); ++void ddr_sr_mode_asr(void); ++void ddr_sr_mode_hsr(void); + + #endif /* STM32MP1_DDR_HELPERS_H */ +diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c +index 17da4904a..863c2cc94 100644 +--- a/plat/st/common/stm32mp_dt.c ++++ b/plat/st/common/stm32mp_dt.c +@@ -13,8 +13,6 @@ + + #include + #include +-#include +-#include + + #include + +diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h +index a40852bde..dbe62f09d 100644 +--- a/plat/st/stm32mp1/stm32mp1_def.h ++++ b/plat/st/stm32mp1/stm32mp1_def.h +@@ -17,6 +17,8 @@ + #ifndef __ASSEMBLER__ + #include + #include ++#include ++#include + + #include + #include +@@ -336,6 +338,7 @@ static inline uint32_t tamp_bkpr(uint32_t idx) + * Device Tree defines + ******************************************************************************/ + #define DT_BSEC_COMPAT "st,stm32mp15-bsec" ++#define DT_DDR_COMPAT "st,stm32mp1-ddr" + #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" + #define DT_PWR_COMPAT "st,stm32mp1-pwr" + #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0007-stm32mp1-add-low-power-management.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0007-stm32mp1-add-low-power-management.patch new file mode 100644 index 0000000..5cb331b --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0007-stm32mp1-add-low-power-management.patch @@ -0,0 +1,2889 @@ +From 89dcbaa9307e004bd4f009de6554cab2632a9c15 Mon Sep 17 00:00:00 2001 +From: Yann Gautier +Date: Mon, 20 May 2019 19:20:30 +0200 +Subject: [PATCH 7/7] stm32mp1: add low power management + +Change-Id: I8e0ba794e5ded1290fb83fe8d43ce54d4dc0e320 +Signed-off-by: Yann Gautier +--- + drivers/st/ddr/stm32mp1_ram.c | 92 ++- + drivers/st/pmic/stm32mp_pmic.c | 95 +++ + drivers/st/pmic/stpmic1.c | 52 ++ + fdts/stm32mp157a-dk1.dts | 136 ++++ + fdts/stm32mp157c-ed1.dts | 150 +++++ + include/drivers/st/stm32mp1_pwr.h | 21 +- + include/drivers/st/stm32mp_pmic.h | 2 + + include/drivers/st/stpmic1.h | 4 + + include/dt-bindings/power/stm32mp1-power.h | 19 + + plat/st/stm32mp1/bl2_plat_setup.c | 33 + + plat/st/stm32mp1/include/boot_api.h | 105 ++- + plat/st/stm32mp1/include/platform_def.h | 2 + + plat/st/stm32mp1/include/stm32mp1_context.h | 13 +- + plat/st/stm32mp1/include/stm32mp1_low_power.h | 19 + + .../stm32mp1/include/stm32mp1_power_config.h | 19 + + plat/st/stm32mp1/include/stm32mp1_private.h | 3 + + plat/st/stm32mp1/plat_image_load.c | 63 +- + plat/st/stm32mp1/platform.mk | 4 + + plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 4 + + plat/st/stm32mp1/sp_min/sp_min_setup.c | 79 ++- + plat/st/stm32mp1/stm32mp1_context.c | 199 ++++++ + plat/st/stm32mp1/stm32mp1_def.h | 4 + + plat/st/stm32mp1/stm32mp1_low_power.c | 327 ++++++++++ + plat/st/stm32mp1/stm32mp1_pm.c | 88 ++- + plat/st/stm32mp1/stm32mp1_power_config.c | 130 ++++ + plat/st/stm32mp1/stm32mp1_private.c | 39 ++ + .../stm32mp1/stm32mp1_shared_resources.c.bak | 597 ++++++++++++++++++ + 27 files changed, 2268 insertions(+), 31 deletions(-) + create mode 100644 include/dt-bindings/power/stm32mp1-power.h + create mode 100644 plat/st/stm32mp1/include/stm32mp1_low_power.h + create mode 100644 plat/st/stm32mp1/include/stm32mp1_power_config.h + create mode 100644 plat/st/stm32mp1/stm32mp1_low_power.c + create mode 100644 plat/st/stm32mp1/stm32mp1_power_config.c + create mode 100644 plat/st/stm32mp1/stm32mp1_shared_resources.c.bak + +diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c +index 4ae55fcc7..f94980c94 100644 +--- a/drivers/st/ddr/stm32mp1_ram.c ++++ b/drivers/st/ddr/stm32mp1_ram.c +@@ -49,6 +49,26 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed) + return 0; + } + ++/******************************************************************************* ++ * This function tests a simple read/write access to the DDR. ++ * Note that the previous content is restored after test. ++ * Returns 0 if success, and address value else. ++ ******************************************************************************/ ++static uint32_t ddr_test_rw_access(void) ++{ ++ uint32_t saved_value = mmio_read_32(STM32MP_DDR_BASE); ++ ++ mmio_write_32(STM32MP_DDR_BASE, DDR_PATTERN); ++ ++ if (mmio_read_32(STM32MP_DDR_BASE) != DDR_PATTERN) { ++ return (uint32_t)STM32MP_DDR_BASE; ++ } ++ ++ mmio_write_32(STM32MP_DDR_BASE, saved_value); ++ ++ return 0; ++} ++ + /******************************************************************************* + * This function tests the DDR data bus wiring. + * This is inspired from the Data Bus Test algorithm written by Michael Barr +@@ -168,8 +188,12 @@ static int stm32mp1_ddr_setup(void) + int ret; + struct stm32mp1_ddr_config config; + int node, len; +- uint32_t uret, idx; ++ uint32_t magic, uret, idx; + void *fdt; ++ uint32_t bkpr_core1_addr = ++ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ uint32_t bkpr_core1_magic = ++ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); + + #define PARAM(x, y) \ + { \ +@@ -237,6 +261,18 @@ static int stm32mp1_ddr_setup(void) + } + } + ++ config.self_refresh = false; ++ ++ stm32mp_clk_enable(RTCAPB); ++ ++ magic = mmio_read_32(bkpr_core1_magic); ++ if (magic == BOOT_API_A7_CORE0_MAGIC_NUMBER) { ++ config.self_refresh = true; ++ config.zdata = stm32_get_zdata_from_context(); ++ } ++ ++ stm32mp_clk_disable(RTCAPB); ++ + /* Disable axidcg clock gating during init */ + mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); + +@@ -245,6 +281,14 @@ static int stm32mp1_ddr_setup(void) + /* Enable axidcg clock gating */ + mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN); + ++ /* check if DDR content is lost (self-refresh aborted) */ ++ if ((magic == BOOT_API_A7_CORE0_MAGIC_NUMBER) && !config.self_refresh) { ++ /* clear Backup register */ ++ mmio_write_32(bkpr_core1_addr, 0); ++ /* clear magic number */ ++ mmio_write_32(bkpr_core1_magic, 0); ++ } ++ + priv->info.size = config.info.size; + + VERBOSE("%s : ram size(%x, %x)\n", __func__, +@@ -253,25 +297,37 @@ static int stm32mp1_ddr_setup(void) + write_sctlr(read_sctlr() & ~SCTLR_C_BIT); + dcsw_op_all(DC_OP_CISW); + +- uret = ddr_test_data_bus(); +- if (uret != 0U) { +- ERROR("DDR data bus test: can't access memory @ 0x%x\n", +- uret); +- panic(); +- } ++ if (config.self_refresh) { ++ uret = ddr_test_rw_access(); ++ if (uret != 0U) { ++ ERROR("DDR rw test: Can't access memory @ 0x%x\n", ++ uret); ++ panic(); ++ } + +- uret = ddr_test_addr_bus(); +- if (uret != 0U) { +- ERROR("DDR addr bus test: can't access memory @ 0x%x\n", +- uret); +- panic(); +- } ++ /* Restore area overwritten by training */ ++ stm32_restore_ddr_training_area(); ++ } else { ++ uret = ddr_test_data_bus(); ++ if (uret != 0U) { ++ ERROR("DDR data bus test: can't access memory @ 0x%x\n", ++ uret); ++ panic(); ++ } + +- uret = ddr_check_size(); +- if (uret < config.info.size) { +- ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", +- uret, config.info.size); +- panic(); ++ uret = ddr_test_addr_bus(); ++ if (uret != 0U) { ++ ERROR("DDR addr bus test: can't access memory @ 0x%x\n", ++ uret); ++ panic(); ++ } ++ ++ uret = ddr_check_size(); ++ if (uret < config.info.size) { ++ ERROR("DDR size: 0x%x does not match DT config: 0x%x\n", ++ uret, config.info.size); ++ panic(); ++ } + } + + write_sctlr(read_sctlr() | SCTLR_C_BIT); +diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c +index 9e9dddc4d..dc44b735f 100644 +--- a/drivers/st/pmic/stm32mp_pmic.c ++++ b/drivers/st/pmic/stm32mp_pmic.c +@@ -27,6 +27,8 @@ + #define STPMIC1_BUCK_OUTPUT_SHIFT 2 + #define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT) + ++#define REGULATOR_MODE_STANDBY 8U ++ + #define STPMIC1_DEFAULT_START_UP_DELAY_MS 1 + + static struct i2c_handle_s i2c_handle; +@@ -174,6 +176,99 @@ int dt_pmic_configure_boot_on_regulators(void) + return 0; + } + ++int dt_pmic_set_lp_config(const char *node_name) ++{ ++ int pmic_node, regulators_node, regulator_node; ++ int status; ++ void *fdt; ++ ++ if (node_name == NULL) { ++ return 0; ++ } ++ ++ if (fdt_get_address(&fdt) == 0) { ++ return -ENOENT; ++ } ++ ++ pmic_node = dt_get_pmic_node(fdt); ++ if (pmic_node < 0) { ++ return -FDT_ERR_NOTFOUND; ++ } ++ ++ status = stpmic1_powerctrl_on(); ++ if (status != 0) { ++ return status; ++ }; ++ ++ regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators"); ++ ++ fdt_for_each_subnode(regulator_node, fdt, regulators_node) { ++ const fdt32_t *cuint; ++ const char *reg_name; ++ int regulator_state_node; ++ ++ /* ++ * First, copy active configuration (Control register) to ++ * PWRCTRL Control register, even if regulator_state_node ++ * does not exist. ++ */ ++ reg_name = fdt_get_name(fdt, regulator_node, NULL); ++ status = stpmic1_lp_copy_reg(reg_name); ++ if (status != 0) { ++ return status; ++ } ++ ++ /* Then apply configs from regulator_state_node */ ++ regulator_state_node = fdt_subnode_offset(fdt, ++ regulator_node, ++ node_name); ++ if (regulator_state_node <= 0) { ++ continue; ++ } ++ ++ if (fdt_getprop(fdt, regulator_state_node, ++ "regulator-on-in-suspend", NULL) != NULL) { ++ status = stpmic1_lp_reg_on_off(reg_name, 1); ++ if (status != 0) { ++ return status; ++ } ++ } ++ ++ if (fdt_getprop(fdt, regulator_state_node, ++ "regulator-off-in-suspend", NULL) != NULL) { ++ status = stpmic1_lp_reg_on_off(reg_name, 0); ++ if (status != 0) { ++ return status; ++ } ++ } ++ ++ cuint = fdt_getprop(fdt, regulator_state_node, ++ "regulator-suspend-microvolt", NULL); ++ if (cuint != NULL) { ++ uint16_t voltage = (uint16_t)(fdt32_to_cpu(*cuint) / ++ 1000U); ++ ++ status = stpmic1_lp_set_voltage(reg_name, voltage); ++ if (status != 0) { ++ return status; ++ } ++ } ++ ++ cuint = fdt_getprop(fdt, regulator_state_node, ++ "regulator-mode", NULL); ++ if (cuint != NULL) { ++ if (fdt32_to_cpu(*cuint) == REGULATOR_MODE_STANDBY) { ++ status = stpmic1_lp_set_mode(reg_name, 1); ++ if (status != 0) { ++ return status; ++ } ++ } ++ } ++ } ++ ++ return 0; ++} ++ + bool initialize_pmic_i2c(void) + { + int ret; +diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c +index 999963054..51754fc3b 100644 +--- a/drivers/st/pmic/stpmic1.c ++++ b/drivers/st/pmic/stpmic1.c +@@ -648,6 +648,58 @@ int stpmic1_regulator_mask_reset_set(const char *name) + regul->mask_reset); + } + ++/* Low-power functions */ ++int stpmic1_lp_copy_reg(const char *name) ++{ ++ uint8_t val; ++ int status; ++ const struct regul_struct *regul = get_regulator_data(name); ++ ++ status = stpmic1_register_read(regul->control_reg, &val); ++ if (status != 0) { ++ return status; ++ } ++ ++ return stpmic1_register_write(regul->low_power_reg, val); ++} ++ ++int stpmic1_lp_reg_on_off(const char *name, uint8_t enable) ++{ ++ const struct regul_struct *regul = get_regulator_data(name); ++ ++ return stpmic1_register_update(regul->low_power_reg, enable, ++ LDO_BUCK_ENABLE_MASK); ++} ++ ++int stpmic1_lp_set_mode(const char *name, uint8_t hplp) ++{ ++ const struct regul_struct *regul = get_regulator_data(name); ++ ++ return stpmic1_register_update(regul->low_power_reg, ++ hplp << LDO_BUCK_HPLP_SHIFT, ++ LDO_BUCK_HPLP_ENABLE_MASK); ++} ++ ++int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts) ++{ ++ uint8_t voltage_index = voltage_to_index(name, millivolts); ++ const struct regul_struct *regul = get_regulator_data(name); ++ uint8_t mask; ++ ++ /* Voltage can be set for buck or ldo (except ldo4) regulators */ ++ if (strncmp(name, "buck", 4) == 0) { ++ mask = BUCK_VOLTAGE_MASK; ++ } else if ((strncmp(name, "ldo", 3) == 0) && ++ (strncmp(name, "ldo4", 4) != 0)) { ++ mask = LDO_VOLTAGE_MASK; ++ } else { ++ return 0; ++ } ++ ++ return stpmic1_register_update(regul->low_power_reg, voltage_index << 2, ++ mask); ++} ++ + int stpmic1_regulator_voltage_get(const char *name) + { + const struct regul_struct *regul = get_regulator_data(name); +diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts +index 78681b0ba..2eced8f53 100644 +--- a/fdts/stm32mp157a-dk1.dts ++++ b/fdts/stm32mp157a-dk1.dts +@@ -192,6 +192,7 @@ + + /* ATF Specific */ + #include ++#include + #include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" + #include "stm32mp157c-security.dtsi" + +@@ -309,3 +310,138 @@ + secure-status = "okay"; + }; + }; ++ ++&pwr { ++ system_suspend_supported_soc_modes = < ++ STM32_PM_CSLEEP_RUN ++ STM32_PM_CSTOP_ALLOW_LP_STOP ++ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR ++ >; ++ ++ system_off_soc_mode = ; ++}; ++ ++/* Low-power states of regulators */ ++&vddcore { ++ lp-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1200000>; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_ddr { ++ lp-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++}; ++ ++&v3v3 { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v1v8_audio { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v3v3_hdmi { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vtt_ddr { ++ lp-stop { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_usb { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdda { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v1v2_hdmi { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vref_ddr { ++ lp-stop { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; +diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts +index 779492552..d766cc6a8 100644 +--- a/fdts/stm32mp157c-ed1.dts ++++ b/fdts/stm32mp157c-ed1.dts +@@ -196,6 +196,7 @@ + + /* ATF Specific */ + #include ++#include + #include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" + #include "stm32mp157c-security.dtsi" + +@@ -315,3 +316,152 @@ + secure-status = "okay"; + }; + }; ++ ++&pwr { ++ system_suspend_supported_soc_modes = < ++ STM32_PM_CSLEEP_RUN ++ STM32_PM_CSTOP_ALLOW_LP_STOP ++ STM32_PM_CSTOP_ALLOW_LPLV_STOP ++ STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR ++ >; ++ system_off_soc_mode = ; ++}; ++ ++/* Low-power states of regulators */ ++&vddcore { ++ lp-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1200000>; ++ }; ++ lplv-stop { ++ regulator-on-in-suspend; ++ regulator-suspend-microvolt = <900000>; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_ddr { ++ lp-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <1350000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd { ++ lp-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-suspend-microvolt = <3300000>; ++ regulator-on-in-suspend; ++ }; ++}; ++ ++&v3v3 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdda { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v2v8 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vtt_ddr { ++ lp-stop { ++ regulator-off-in-suspend; ++ }; ++ lplv-stop { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_usb { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vdd_sd { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&v1v8 { ++ standby-ddr-sr { ++ regulator-off-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; ++ ++&vref_ddr { ++ lp-stop { ++ regulator-on-in-suspend; ++ }; ++ lplv-stop { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-sr { ++ regulator-on-in-suspend; ++ }; ++ standby-ddr-off { ++ regulator-off-in-suspend; ++ }; ++}; +diff --git a/include/drivers/st/stm32mp1_pwr.h b/include/drivers/st/stm32mp1_pwr.h +index e17df44fb..9b662f2d1 100644 +--- a/include/drivers/st/stm32mp1_pwr.h ++++ b/include/drivers/st/stm32mp1_pwr.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -13,20 +13,39 @@ + #define PWR_CR2 U(0x08) + #define PWR_CR3 U(0x0C) + #define PWR_MPUCR U(0x10) ++#define PWR_MCUCR U(0x14) + #define PWR_WKUPCR U(0x20) + #define PWR_MPUWKUPENR U(0x28) + ++#define PWR_OFFSET_MASK GENMASK(9, 0) ++ + #define PWR_CR1_LPDS BIT(0) + #define PWR_CR1_LPCFG BIT(1) + #define PWR_CR1_LVDS BIT(2) + #define PWR_CR1_DBP BIT(8) + ++#define PWR_CR2_BREN BIT(0) ++#define PWR_CR2_RREN BIT(1) ++#define PWR_CR2_BRRDY BIT(16) ++#define PWR_CR2_RRRDY BIT(17) ++ ++#define PWR_CR3_VBE BIT(8) ++#define PWR_CR3_VBRS BIT(9) + #define PWR_CR3_DDRSREN BIT(10) + #define PWR_CR3_DDRSRDIS BIT(11) + #define PWR_CR3_DDRRETEN BIT(12) ++#define PWR_CR3_USB33DEN BIT(24) ++#define PWR_CR3_REG18EN BIT(28) ++#define PWR_CR3_REG11EN BIT(30) + + #define PWR_MPUCR_PDDS BIT(0) + #define PWR_MPUCR_CSTDBYDIS BIT(3) + #define PWR_MPUCR_CSSF BIT(9) + ++#define PWR_MCUCR_PDDS BIT(0) ++ ++#define PWR_WKUPCR_MASK GENMASK(27, 16) | GENMASK(13, 8) | GENMASK(5, 0) ++ ++#define PWR_MPUWKUPENR_MASK GENMASK(5, 0) ++ + #endif /* STM32MP1_PWR_H */ +diff --git a/include/drivers/st/stm32mp_pmic.h b/include/drivers/st/stm32mp_pmic.h +index 984cd6014..f5810f38c 100644 +--- a/include/drivers/st/stm32mp_pmic.h ++++ b/include/drivers/st/stm32mp_pmic.h +@@ -27,6 +27,8 @@ int dt_pmic_status(void); + */ + int dt_pmic_configure_boot_on_regulators(void); + ++int dt_pmic_set_lp_config(const char *node_name); ++ + /* + * initialize_pmic_i2c - Initialize I2C for the PMIC control + * +diff --git a/include/drivers/st/stpmic1.h b/include/drivers/st/stpmic1.h +index f7e293b18..e4ceea5e9 100644 +--- a/include/drivers/st/stpmic1.h ++++ b/include/drivers/st/stpmic1.h +@@ -161,6 +161,10 @@ int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts); + int stpmic1_regulator_voltage_get(const char *name); + int stpmic1_regulator_pull_down_set(const char *name); + int stpmic1_regulator_mask_reset_set(const char *name); ++int stpmic1_lp_copy_reg(const char *name); ++int stpmic1_lp_reg_on_off(const char *name, uint8_t enable); ++int stpmic1_lp_set_mode(const char *name, uint8_t hplp); ++int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts); + void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr); + + int stpmic1_get_version(unsigned long *version); +diff --git a/include/dt-bindings/power/stm32mp1-power.h b/include/dt-bindings/power/stm32mp1-power.h +new file mode 100644 +index 000000000..d588dd71f +--- /dev/null ++++ b/include/dt-bindings/power/stm32mp1-power.h +@@ -0,0 +1,19 @@ ++/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ ++/* ++ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved ++ * Author: Yann Gautier for STMicroelectronics. ++ */ ++ ++#ifndef DT_BINDINGS_STM32MP1_POWER_H ++#define DT_BINDINGS_STM32MP1_POWER_H ++ ++#define STM32_PM_CSLEEP_RUN 0 ++#define STM32_PM_CSTOP_ALLOW_STOP 1 ++#define STM32_PM_CSTOP_ALLOW_LP_STOP 2 ++#define STM32_PM_CSTOP_ALLOW_LPLV_STOP 3 ++#define STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR 4 ++#define STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF 5 ++#define STM32_PM_SHUTDOWN 6 ++#define STM32_PM_MAX_SOC_MODE 7 ++ ++#endif /* DT_BINDINGS_STM32MP1_POWER_H */ +diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c +index d9e29b4e8..c729c0238 100644 +--- a/plat/st/stm32mp1/bl2_plat_setup.c ++++ b/plat/st/stm32mp1/bl2_plat_setup.c +@@ -31,6 +31,8 @@ + #include + #include + ++#define PWRLP_TEMPO_5_HSI 5 ++ + static struct console_stm32 console; + static struct stm32mp_auth_ops stm32mp1_auth_ops; + +@@ -160,6 +162,10 @@ void bl2_el3_plat_arch_setup(void) + uint32_t clk_rate; + uintptr_t pwr_base; + uintptr_t rcc_base; ++ uint32_t bkpr_core1_magic = ++ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); ++ uint32_t bkpr_core1_addr = ++ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); + + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, + BL_CODE_END - BL_CODE_BASE, +@@ -204,6 +210,11 @@ void bl2_el3_plat_arch_setup(void) + pwr_base = stm32mp_pwr_base(); + rcc_base = stm32mp_rcc_base(); + ++ /* Clear Stop Request bits to correctly manage low-power exit */ ++ mmio_write_32(rcc_base + RCC_MP_SREQCLRR, ++ (uint32_t)(RCC_MP_SREQCLRR_STPREQ_P0 | ++ RCC_MP_SREQCLRR_STPREQ_P1)); ++ + /* + * Disable the backup domain write protection. + * The protection is enable at each reset by hardware +@@ -215,6 +226,12 @@ void bl2_el3_plat_arch_setup(void) + ; + } + ++ /* ++ * Configure Standby mode available for MCU by default ++ * and allow to switch in standby SoC in all case ++ */ ++ mmio_setbits_32(pwr_base + PWR_MCUCR, PWR_MCUCR_PDDS); ++ + if (bsec_probe() != 0) { + panic(); + } +@@ -231,9 +248,25 @@ void bl2_el3_plat_arch_setup(void) + mmio_clrbits_32(rcc_base + RCC_BDCR, RCC_BDCR_VSWRST); + } + ++ /* Wait 5 HSI periods before re-enabling PLLs after STOP modes */ ++ mmio_clrsetbits_32(rcc_base + RCC_PWRLPDLYCR, ++ RCC_PWRLPDLYCR_PWRLP_DLY_MASK, ++ PWRLP_TEMPO_5_HSI); ++ ++ /* Disable retention and backup RAM content after standby */ ++ mmio_clrbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | PWR_CR2_RREN); ++ + /* Disable MCKPROT */ + mmio_clrbits_32(rcc_base + RCC_TZCR, RCC_TZCR_MCKPROT); + ++ if ((boot_context->boot_action != ++ BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) && ++ (boot_context->boot_action != ++ BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY)) { ++ mmio_write_32(bkpr_core1_addr, 0); ++ mmio_write_32(bkpr_core1_magic, 0); ++ } ++ + generic_delay_timer_init(); + + if (stm32mp1_clk_probe() < 0) { +diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h +index 2284970fa..6088b3701 100644 +--- a/plat/st/stm32mp1/include/boot_api.h ++++ b/plat/st/stm32mp1/include/boot_api.h +@@ -10,6 +10,90 @@ + #include + #include + ++/* ++ * Exported constants ++ */ ++ ++/* ++ * Boot Context related definitions ++ */ ++ ++/* ++ * Possible value of boot context field 'boot_action' ++ */ ++/* Boot action is Process Cold Boot */ ++#define BOOT_API_CTX_BOOT_ACTION_COLD_BOOT_PROCESS 0x09U ++/* Boot action is Process Wakeup from CSTANDBY */ ++#define BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY 0x0AU ++/* Boot action is Process Wakeup from STANDBY */ ++#define BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY 0x0BU ++/* Boot action is Process Engineering Boot */ ++#define BOOT_API_CTX_BOOT_ACTION_ENGI_BOOT 0x0CU ++ ++#define BOOT_API_CTX_BOOT_ACTION_MPU_CORE0_RESET_PROCESS 0x0F ++ ++/* ++ * Possible value of boot context field 'stby_exit_status' ++ */ ++ ++/* The boot reason is not a STANDBY Exit reason */ ++#define BOOT_API_CTX_STBY_EXIT_STATUS_NO_STANDBY 0x00 ++ ++/* STANDBY Exit with MPU_BEN=1, MCU_BEN=0 */ ++#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MPU_ONLY 0x01 ++ ++/* ++ * STANDBY Exit with MPU_BEN=1, MCU_BEN=1, MPU will go for cold boot ++ * MCU restarted by bootROM ++ */ ++#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_ALL_CORES 0x02 ++ ++/* ++ * STANDBY Exit with MPU_BEN=1, MCU_BEN=1, MPU will go for cold boot ++ * but MCU restart aborted (code integrity check) : have not been restarted ++ * by bootROM ++ */ ++#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_ALL_CORES_MCU_ABT 0x03 ++ ++/* ++ * STANDBY Exit with MPU_BEN=0, MCU_BEN=1, MPU gone to CSTANDBY, ++ * MCU restarted correctly by bootROM ++ * This value should never be read by FSBL, because not executed in that case ++ */ ++#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MCU_ONLY 0x04 ++ ++/* ++ * STANDBY Exit with MPU_BEN=0, MCU_BEN=1, MCU restart aborted ++ * due code integrity check, then MPU will go for cold boot despite ++ * was not planned initially ++ */ ++#define BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MCU_ONLY_MCU_ABT 0x05 ++ ++/* ++ * STANDBY Exit with MPU_BEN=1, MCU_BEN=1, MCU restart aborted ++ * due to MCU security perimeter issue ++ */ ++#define \ ++BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_ALL_CORES_MCU_ABT_SEC_PERIMETER_ISSUE 0x06 ++ ++/* ++ * STANDBY Exit with MPU_BEN=0, MCU_BEN=1, MCU restart aborted ++ * due to MCU security perimeter issue, then MPU will go for cold boot ++ * despite was not planned initially ++ */ ++#define \ ++BOOT_API_CTX_STBY_EXIT_STATUS_WKUP_MCU_ONLY_MCU_ABT_SEC_PERIMETER_ISSUE 0x07 ++ ++/* ++ * Possible value of boot context field 'cstby_exit_status' ++ */ ++/* The boot reason is not a CSTANDBY Exit reason */ ++#define BOOT_API_CTX_CSTBY_EXIT_STATUS_NO_CSTBY 0x00 ++/* CSTANDBY Exit with MCU detected as Not running */ ++#define BOOT_API_CTX_CSTBY_EXIT_STATUS_MCU_NOT_RUNNING 0x01 ++/* CSTANDBY Exit with MCU detected as Running */ ++#define BOOT_API_CTX_CSTBY_EXIT_STATUS_MCU_RUNNING 0x02 ++ + /* + * Possible value of boot context field 'auth_status' + */ +@@ -144,7 +228,26 @@ typedef struct { + uint16_t boot_interface_instance; + uint32_t reserved1[13]; + uint32_t otp_afmux_values[3]; +- uint32_t reserved[5]; ++ uint32_t reserved[2]; ++ /* ++ * Log to boot context, what was the kind of boot action ++ * takes values from defines BOOT_API_BOOT_ACTION_XXX above ++ */ ++ uint32_t boot_action; ++ /* ++ * STANDBY Exit status to be checked by FSBL in case ++ * field 'boot_action' == BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY ++ * take values from defines above 'BOOT_API_CTX_STBY_EXIT_STATUS_XXX' ++ * depending on encountered situation ++ */ ++ uint32_t stby_exit_status; ++ /* ++ * CSTANDBY Exit status to be checked by FSBL in case ++ * boot_action == BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY ++ * take values from defines above 'BOOT_API_CTX_CSTBY_EXIT_STATUS_XXX' ++ * depending on encountered situation ++ */ ++ uint32_t cstby_exit_status; + uint32_t auth_status; + + /* +diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h +index 263e6d6e1..2f6773e84 100644 +--- a/plat/st/stm32mp1/include/platform_def.h ++++ b/plat/st/stm32mp1/include/platform_def.h +@@ -112,6 +112,8 @@ + */ + #define ARM_IRQ_SEC_PHY_TIMER U(29) + ++#define ARM_IRQ_NON_SEC_SGI_0 U(0) ++ + #define ARM_IRQ_SEC_SGI_0 U(8) + #define ARM_IRQ_SEC_SGI_1 U(9) + #define ARM_IRQ_SEC_SGI_2 U(10) +diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h +index 698415af2..081691788 100644 +--- a/plat/st/stm32mp1/include/stm32mp1_context.h ++++ b/plat/st/stm32mp1/include/stm32mp1_context.h +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +@@ -7,8 +7,19 @@ + #ifndef STM32MP1_CONTEXT_H + #define STM32MP1_CONTEXT_H + ++#include + #include + ++#define DDR_CRC_GRANULE 32 ++ ++void stm32_clean_context(void); ++int stm32_save_context(uint32_t zq0cr0_zdata); ++int stm32_restore_context(void); ++int stm32_restore_backup_reg(void); ++uint32_t stm32_get_zdata_from_context(void); + int stm32_save_boot_interface(uint32_t interface, uint32_t instance); ++void stm32_save_ddr_training_area(void); ++void stm32_restore_ddr_training_area(void); ++uint32_t stm32_pm_get_optee_ep(void); + + #endif /* STM32MP1_CONTEXT_H */ +diff --git a/plat/st/stm32mp1/include/stm32mp1_low_power.h b/plat/st/stm32mp1/include/stm32mp1_low_power.h +new file mode 100644 +index 000000000..82b3d36c1 +--- /dev/null ++++ b/plat/st/stm32mp1/include/stm32mp1_low_power.h +@@ -0,0 +1,19 @@ ++/* ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32MP1_LOW_POWER_H ++#define STM32MP1_LOW_POWER_H ++ ++#include ++#include ++ ++void stm32_rcc_wakeup_update(bool state); ++void stm32_apply_pmic_suspend_config(uint32_t mode); ++void stm32_exit_cstop(void); ++void stm32_pwr_down_wfi(void); ++void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr); ++ ++#endif /* STM32MP1_LOW_POWER_H */ +diff --git a/plat/st/stm32mp1/include/stm32mp1_power_config.h b/plat/st/stm32mp1/include/stm32mp1_power_config.h +new file mode 100644 +index 000000000..7c7571a5a +--- /dev/null ++++ b/plat/st/stm32mp1/include/stm32mp1_power_config.h +@@ -0,0 +1,19 @@ ++/* ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef STM32MP1_POWER_CONFIG_H ++#define STM32MP1_POWER_CONFIG_H ++ ++#include ++#include ++ ++#define PSCI_MODE_SYSTEM_SUSPEND 0 ++#define PSCI_MODE_SYSTEM_OFF 1 ++ ++void stm32mp1_init_lp_states(void); ++uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode); ++ ++#endif /* STM32MP1_POWER_CONFIG_H */ +diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h +index e38fca012..7adc7f6f1 100644 +--- a/plat/st/stm32mp1/include/stm32mp1_private.h ++++ b/plat/st/stm32mp1/include/stm32mp1_private.h +@@ -11,6 +11,9 @@ + + void configure_mmu(void); + ++void stm32mp_mask_timer(void); ++void __dead2 stm32mp_wait_cpu_reset(void); ++ + void stm32mp1_arch_security_setup(void); + void stm32mp1_security_setup(void); + +diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c +index a52db6cac..1fb3ec510 100644 +--- a/plat/st/stm32mp1/plat_image_load.c ++++ b/plat/st/stm32mp1/plat_image_load.c +@@ -1,10 +1,14 @@ + /* +- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. ++ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + ++#include ++ ++#include + #include ++#include + #include + + /******************************************************************************* +@@ -16,11 +20,68 @@ void plat_flush_next_bl_params(void) + flush_bl_params_desc(); + } + ++#ifdef AARCH32_SP_OPTEE ++static bool addr_inside_backupsram(uintptr_t addr) ++{ ++ return (addr >= STM32MP_BACKUP_RAM_BASE) && ++ (addr < (STM32MP_BACKUP_RAM_BASE + STM32MP_BACKUP_RAM_SIZE)); ++} ++#endif ++ + /******************************************************************************* + * This function returns the list of loadable images. + ******************************************************************************/ + bl_load_info_t *plat_get_bl_image_load_info(void) + { ++ boot_api_context_t *boot_context = ++ (boot_api_context_t *)stm32mp_get_boot_ctx_address(); ++#ifdef AARCH32_SP_OPTEE ++ bl_mem_params_node_t *bl32 = get_bl_mem_params_node(BL32_IMAGE_ID); ++#endif ++ bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); ++ uint32_t rstsr = mmio_read_32(stm32mp_rcc_base() + RCC_MP_RSTSCLRR); ++ uint32_t bkpr_core1_addr = ++ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ ++ /* ++ * If going back from CSTANDBY / STANDBY and DDR was in Self-Refresh, ++ * BL33 must not be loaded as it would overwrite the code already ++ * in DDR. For this, the BL33 part of the bl_mem_params_desc_ptr ++ * struct should be modified to skip its loading ++ */ ++ if (((boot_context->boot_action == ++ BOOT_API_CTX_BOOT_ACTION_WAKEUP_CSTANDBY) || ++ (boot_context->boot_action == ++ BOOT_API_CTX_BOOT_ACTION_WAKEUP_STANDBY)) && ++ ((mmio_read_32(pwr_base + PWR_CR3) & PWR_CR3_DDRSREN) != 0U) && ++ ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U)) { ++ stm32mp_clk_enable(RTCAPB); ++ ++ if (mmio_read_32(bkpr_core1_addr) != 0U) { ++ bl33->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; ++ ++#ifdef AARCH32_SP_OPTEE ++ bl32->image_info.h.attr |= IMAGE_ATTRIB_SKIP_LOADING; ++ bl32->ep_info.pc = stm32_pm_get_optee_ep(); ++ ++ if (addr_inside_backupsram(bl32->ep_info.pc)) { ++ stm32mp_clk_enable(BKPSRAM); ++ } ++#else ++ /* ++ * Set ep_info PC to 0, to inform BL32 it is a reset ++ * after STANDBY ++ */ ++ bl33->ep_info.pc = 0; ++#endif ++ } ++ ++ stm32mp_clk_disable(RTCAPB); ++ } ++ ++ bl33->image_info.image_max_size = dt_get_ddr_size(); ++ + return get_bl_load_info_from_mem_params_desc(); + } + +diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk +index 90b3e3c1e..0c57c85af 100644 +--- a/plat/st/stm32mp1/platform.mk ++++ b/plat/st/stm32mp1/platform.mk +@@ -94,6 +94,10 @@ ifeq ($(AARCH32_SP),optee) + BL2_SOURCES += lib/optee/optee_utils.c + endif + ++ ++# Do not use neon in TF-A code, it leads to issues in low-power functions ++TF_CFLAGS += -mfloat-abi=soft ++ + # Macros and rules to build TF binary + STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed + STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=) +diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +index 6c7107ca2..34530f181 100644 +--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk ++++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +@@ -6,10 +6,14 @@ + + SP_MIN_WITH_SECURE_FIQ := 1 + ++BL32_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 ++ + BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \ + drivers/st/rtc/stm32_rtc.c \ + plat/st/stm32mp1/sp_min/sp_min_setup.c \ ++ plat/st/stm32mp1/stm32mp1_low_power.c \ + plat/st/stm32mp1/stm32mp1_pm.c \ ++ plat/st/stm32mp1/stm32mp1_power_config.c \ + plat/st/stm32mp1/stm32mp1_topology.c + # Generic GIC v2 + BL32_SOURCES += drivers/arm/gic/common/gic_common.c \ +diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c +index ff69358e0..62b358cb3 100644 +--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c ++++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -29,6 +30,7 @@ + #include + + #include ++#include + + /****************************************************************************** + * Placeholder variables for copying the arguments that have been passed to +@@ -38,6 +40,27 @@ static entry_point_info_t bl33_image_ep_info; + + static struct console_stm32 console; + ++static void stm32_sgi1_it_handler(void) ++{ ++ uint32_t id; ++ ++ stm32mp_mask_timer(); ++ ++ gicv2_end_of_interrupt(ARM_IRQ_SEC_SGI_1); ++ ++ do { ++ id = plat_ic_get_pending_interrupt_id(); ++ ++ if (id <= MAX_SPI_ID) { ++ gicv2_end_of_interrupt(id); ++ ++ plat_ic_disable_interrupt(id); ++ } ++ } while (id <= MAX_SPI_ID); ++ ++ stm32mp_wait_cpu_reset(); ++} ++ + /******************************************************************************* + * Interrupt handler for FIQ (secure IRQ) + ******************************************************************************/ +@@ -48,12 +71,15 @@ void sp_min_plat_fiq_handler(uint32_t id) + ERROR("STM32MP1_IRQ_TZC400 generated\n"); + panic(); + break; ++ case ARM_IRQ_SEC_SGI_1: ++ stm32_sgi1_it_handler(); ++ break; + case STM32MP1_IRQ_AXIERRIRQ: + ERROR("STM32MP1_IRQ_AXIERRIRQ generated\n"); + panic(); + break; + default: +- ERROR("SECURE IT handler not define for it : %u", id); ++ ERROR("SECURE IT handler not define for it : %u\n", id); + break; + } + } +@@ -67,11 +93,54 @@ void sp_min_plat_fiq_handler(uint32_t id) + entry_point_info_t *sp_min_plat_get_bl33_ep_info(void) + { + entry_point_info_t *next_image_info; ++ uint32_t bkpr_core1_addr = ++ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ uint32_t bkpr_core1_magic = ++ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); + + next_image_info = &bl33_image_ep_info; + ++ /* ++ * PC is set to 0 when resetting after STANDBY ++ * The context should be restored, and the image information ++ * should be filled with what what was saved ++ */ + if (next_image_info->pc == 0U) { +- return NULL; ++ void *cpu_context; ++ uint32_t magic_nb, saved_pc; ++ ++ stm32mp_clk_enable(RTCAPB); ++ ++ magic_nb = mmio_read_32(bkpr_core1_magic); ++ saved_pc = mmio_read_32(bkpr_core1_addr); ++ ++ stm32mp_clk_disable(RTCAPB); ++ ++ if (stm32_restore_context() != 0) { ++ panic(); ++ } ++ ++ cpu_context = cm_get_context(NON_SECURE); ++ ++ next_image_info->spsr = read_ctx_reg(get_regs_ctx(cpu_context), ++ CTX_SPSR); ++ ++ /* PC should be retrieved in backup register if OK, else it can ++ * be retrieved from non-secure context ++ */ ++ if (magic_nb == BOOT_API_A7_CORE0_MAGIC_NUMBER) { ++ /* BL33 return address should be in DDR */ ++ if ((saved_pc < STM32MP_DDR_BASE) || ++ (saved_pc > (STM32MP_DDR_BASE + ++ (dt_get_ddr_size() - 1U)))) { ++ panic(); ++ } ++ ++ next_image_info->pc = saved_pc; ++ } else { ++ next_image_info->pc = ++ read_ctx_reg(get_regs_ctx(cpu_context), CTX_LR); ++ } + } + + return next_image_info; +@@ -145,6 +214,12 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, + #endif + console_set_scope(&console.console, console_flags); + } ++ ++ if (dt_pmic_status() > 0) { ++ initialize_pmic(); ++ } ++ ++ stm32mp1_init_lp_states(); + } + + /******************************************************************************* +diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c +index cf8a91eb4..ed54fc625 100644 +--- a/plat/st/stm32mp1/stm32mp1_context.c ++++ b/plat/st/stm32mp1/stm32mp1_context.c +@@ -5,19 +5,171 @@ + */ + + #include ++#include + + #include + ++#include ++#include ++#include + #include ++#include + #include ++#include + #include ++#include ++#include ++#include + + #include + ++#include ++ + #define TAMP_BOOT_ITF_BACKUP_REG_ID U(20) + #define TAMP_BOOT_ITF_MASK U(0x0000FF00) + #define TAMP_BOOT_ITF_SHIFT 8 + ++#define TRAINING_AREA_SIZE 64 ++ ++#ifdef AARCH32_SP_OPTEE ++/* OPTEE_MAILBOX_MAGIC relates to struct backup_data_s as defined */ ++#define OPTEE_MAILBOX_MAGIC_V1 0x01 ++#define OPTEE_MAILBOX_MAGIC ((OPTEE_MAILBOX_MAGIC_V1 << 16) + \ ++ TRAINING_AREA_SIZE) ++#endif ++ ++struct backup_data_s { ++#ifdef AARCH32_SP_OPTEE ++ uint32_t magic; ++ uint32_t core0_resume_hint; ++ uint32_t zq0cr0_zdata; ++ uint8_t ddr_training_backup[TRAINING_AREA_SIZE]; ++#else ++ smc_ctx_t saved_smc_context[PLATFORM_CORE_COUNT]; ++ cpu_context_t saved_cpu_context[PLATFORM_CORE_COUNT]; ++ uint32_t zq0cr0_zdata; ++ struct stm32_rtc_calendar rtc; ++ uint8_t ddr_training_backup[TRAINING_AREA_SIZE]; ++#endif ++}; ++ ++#ifdef AARCH32_SP_OPTEE ++uint32_t stm32_pm_get_optee_ep(void) ++{ ++ struct backup_data_s *backup_data; ++ uint32_t ep; ++ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ /* Context & Data to be saved at the beginning of Backup SRAM */ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ if (backup_data->magic != OPTEE_MAILBOX_MAGIC) { ++ panic(); ++ } ++ ++ ep = backup_data->core0_resume_hint; ++ ++ stm32mp_clk_disable(BKPSRAM); ++ ++ return ep; ++} ++#else /*AARCH32_SP_OPTEE*/ ++void stm32_clean_context(void) ++{ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ zeromem((void *)STM32MP_BACKUP_RAM_BASE, sizeof(struct backup_data_s)); ++ ++ stm32mp_clk_disable(BKPSRAM); ++} ++ ++int stm32_save_context(uint32_t zq0cr0_zdata) ++{ ++ void *smc_context; ++ void *cpu_context; ++ struct backup_data_s *backup_data; ++ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ /* Context & Data to be saved at the beginning of Backup SRAM */ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ /* Retrieve smc context struct address */ ++ smc_context = smc_get_ctx(NON_SECURE); ++ ++ /* Retrieve smc context struct address */ ++ cpu_context = cm_get_context(NON_SECURE); ++ ++ /* Save context in Backup SRAM */ ++ memcpy(&backup_data->saved_smc_context[0], smc_context, ++ sizeof(smc_ctx_t) * PLATFORM_CORE_COUNT); ++ memcpy(&backup_data->saved_cpu_context[0], cpu_context, ++ sizeof(cpu_context_t) * PLATFORM_CORE_COUNT); ++ ++ backup_data->zq0cr0_zdata = zq0cr0_zdata; ++ ++ stm32_rtc_get_calendar(&backup_data->rtc); ++ ++ stm32mp_clk_disable(BKPSRAM); ++ ++ return 0; ++} ++ ++int stm32_restore_context(void) ++{ ++ void *smc_context; ++ void *cpu_context; ++ struct backup_data_s *backup_data; ++ struct stm32_rtc_calendar current_calendar; ++ unsigned long long stdby_time_in_ms; ++ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ /* Context & Data to be saved at the beginning of Backup SRAM */ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ /* Retrieve smc context struct address */ ++ smc_context = smc_get_ctx(NON_SECURE); ++ ++ /* Retrieve smc context struct address */ ++ cpu_context = cm_get_context(NON_SECURE); ++ ++ /* Restore data from Backup SRAM */ ++ memcpy(smc_context, backup_data->saved_smc_context, ++ sizeof(smc_ctx_t) * PLATFORM_CORE_COUNT); ++ memcpy(cpu_context, backup_data->saved_cpu_context, ++ sizeof(cpu_context_t) * PLATFORM_CORE_COUNT); ++ ++ /* update STGEN counter with standby mode length */ ++ stm32_rtc_get_calendar(¤t_calendar); ++ stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, ++ &backup_data->rtc); ++ stm32mp1_stgen_increment(stdby_time_in_ms); ++ ++ stm32mp_clk_disable(BKPSRAM); ++ ++ return 0; ++} ++#endif /*AARCH32_SP_OPTEE*/ ++ ++uint32_t stm32_get_zdata_from_context(void) ++{ ++ struct backup_data_s *backup_data; ++ uint32_t zdata; ++ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ zdata = (backup_data->zq0cr0_zdata >> DDRPHYC_ZQ0CRN_ZDATA_SHIFT) & ++ DDRPHYC_ZQ0CRN_ZDATA_MASK; ++ ++ stm32mp_clk_disable(BKPSRAM); ++ ++ return zdata; ++} ++ + int stm32_save_boot_interface(uint32_t interface, uint32_t instance) + { + uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID); +@@ -33,3 +185,50 @@ int stm32_save_boot_interface(uint32_t interface, uint32_t instance) + + return 0; + } ++ ++#if defined(IMAGE_BL32) ++/* ++ * When returning from STANDBY, the 64 first bytes of DDR will be overwritten ++ * during DDR DQS training. This area must then be saved before going to ++ * standby, and will be restored after ++ */ ++void stm32_save_ddr_training_area(void) ++{ ++ struct backup_data_s *backup_data; ++ int ret __unused; ++ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ ret = mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE, ++ PAGE_SIZE, MT_MEMORY | MT_RW | MT_NS); ++ assert(ret == 0); ++ ++ memcpy(&backup_data->ddr_training_backup, ++ (const uint32_t *)STM32MP_DDR_BASE, ++ TRAINING_AREA_SIZE); ++ dsb(); ++ ++ ret = mmap_remove_dynamic_region(STM32MP_DDR_BASE, PAGE_SIZE); ++ assert(ret == 0); ++ ++ stm32mp_clk_disable(BKPSRAM); ++} ++#endif ++ ++void stm32_restore_ddr_training_area(void) ++{ ++ struct backup_data_s *backup_data; ++ ++ stm32mp_clk_enable(BKPSRAM); ++ ++ backup_data = (struct backup_data_s *)STM32MP_BACKUP_RAM_BASE; ++ ++ memcpy((uint32_t *)STM32MP_DDR_BASE, ++ &backup_data->ddr_training_backup, ++ TRAINING_AREA_SIZE); ++ dsb(); ++ ++ stm32mp_clk_disable(BKPSRAM); ++} +diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h +index dbe62f09d..26a194acb 100644 +--- a/plat/st/stm32mp1/stm32mp1_def.h ++++ b/plat/st/stm32mp1/stm32mp1_def.h +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #endif +@@ -58,6 +59,9 @@ + #define STM32MP_SYSRAM_BASE U(0x2FFC0000) + #define STM32MP_SYSRAM_SIZE U(0x00040000) + ++#define STM32MP_BACKUP_RAM_BASE U(0x54000000) ++#define STM32MP_BACKUP_RAM_SIZE U(0x00001000) ++ + /* DDR configuration */ + #define STM32MP_DDR_BASE U(0xC0000000) + #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ +diff --git a/plat/st/stm32mp1/stm32mp1_low_power.c b/plat/st/stm32mp1/stm32mp1_low_power.c +new file mode 100644 +index 000000000..36664c21c +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_low_power.c +@@ -0,0 +1,327 @@ ++/* ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static unsigned int gicc_pmr; ++static struct stm32_rtc_calendar sleep_time, current_calendar; ++static unsigned long long stdby_time_in_ms; ++static bool enter_cstop_done; ++ ++struct pwr_lp_config { ++ uint32_t pwr_cr1; ++ uint32_t pwr_mpucr; ++ const char *regul_suspend_node_name; ++}; ++ ++#define PWR_CR1_MASK (PWR_CR1_LPDS | PWR_CR1_LPCFG | PWR_CR1_LVDS) ++#define PWR_MPUCR_MASK (PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | PWR_MPUCR_PDDS) ++ ++static const struct pwr_lp_config config_pwr[STM32_PM_MAX_SOC_MODE] = { ++ [STM32_PM_CSLEEP_RUN] = { ++ .pwr_cr1 = 0U, ++ .pwr_mpucr = PWR_MPUCR_CSSF, ++ .regul_suspend_node_name = NULL, ++ }, ++ [STM32_PM_CSTOP_ALLOW_STOP] = { ++ .pwr_cr1 = 0U, ++ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF, ++ .regul_suspend_node_name = NULL, ++ }, ++ [STM32_PM_CSTOP_ALLOW_LP_STOP] = { ++ .pwr_cr1 = PWR_CR1_LPDS, ++ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF, ++ .regul_suspend_node_name = "lp-stop", ++ }, ++ [STM32_PM_CSTOP_ALLOW_LPLV_STOP] = { ++ .pwr_cr1 = PWR_CR1_LVDS | PWR_CR1_LPDS | PWR_CR1_LPCFG, ++ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF, ++ .regul_suspend_node_name = "lplv-stop", ++ }, ++ [STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR] = { ++ .pwr_cr1 = 0U, ++ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | ++ PWR_MPUCR_PDDS, ++ .regul_suspend_node_name = "standby-ddr-sr", ++ }, ++ [STM32_PM_CSTOP_ALLOW_STANDBY_DDR_OFF] = { ++ .pwr_cr1 = 0U, ++ .pwr_mpucr = PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_CSSF | ++ PWR_MPUCR_PDDS, ++ .regul_suspend_node_name = "standby-ddr-off", ++ }, ++ [STM32_PM_SHUTDOWN] = { ++ .pwr_cr1 = 0U, ++ .pwr_mpucr = 0U, ++ .regul_suspend_node_name = "standby-ddr-off", ++ }, ++}; ++ ++#define GICC_PMR_PRIORITY_8 U(0x8) ++ ++void stm32_apply_pmic_suspend_config(uint32_t mode) ++{ ++ const char *node_name = config_pwr[mode].regul_suspend_node_name; ++ ++ assert(mode < ARRAY_SIZE(config_pwr)); ++ ++ if (node_name != NULL) { ++ if (!initialize_pmic_i2c()) { ++ panic(); ++ } ++ ++ if (dt_pmic_set_lp_config(node_name) != 0) { ++ panic(); ++ } ++ ++ if (dt_pmic_configure_boot_on_regulators() != 0) { ++ panic(); ++ } ++ } ++} ++ ++/* ++ * stm32_enter_cstop - Prepare CSTOP mode ++ * ++ * @mode - Target low power mode ++ * @nsec_addr - Non secure resume entry point ++ * Return 0 if succeed to suspend, non 0 else. ++ */ ++static void enter_cstop(uint32_t mode, uint32_t nsec_addr) ++{ ++ uint32_t zq0cr0_zdata; ++ uint32_t bkpr_core1_addr = ++ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX); ++ uint32_t bkpr_core1_magic = ++ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); ++ uint32_t pwr_cr1 = config_pwr[mode].pwr_cr1; ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ uintptr_t rcc_base = stm32mp_rcc_base(); ++ ++ stm32mp1_syscfg_disable_io_compensation(); ++ ++ dcsw_op_all(DC_OP_CISW); ++ ++ stm32_clean_context(); ++ ++ if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { ++ /* ++ * The first 64 bytes of DDR need to be saved for DDR DQS ++ * training ++ */ ++ stm32_save_ddr_training_area(); ++ } ++ ++ if (dt_pmic_status() > 0) { ++ stm32_apply_pmic_suspend_config(mode); ++ ++ if (mode == STM32_PM_CSTOP_ALLOW_LP_STOP) { ++ pwr_cr1 |= PWR_CR1_LPCFG; ++ } ++ } ++ ++ /* Clear RCC interrupt before enabling it */ ++ mmio_setbits_32(rcc_base + RCC_MP_CIFR, RCC_MP_CIFR_WKUPF); ++ ++ /* Enable RCC Wake-up */ ++ mmio_setbits_32(rcc_base + RCC_MP_CIER, RCC_MP_CIFR_WKUPF); ++ ++ /* Configure low power mode */ ++ mmio_clrsetbits_32(pwr_base + PWR_MPUCR, PWR_MPUCR_MASK, ++ config_pwr[mode].pwr_mpucr); ++ mmio_clrsetbits_32(pwr_base + PWR_CR1, PWR_CR1_MASK, ++ pwr_cr1); ++ ++ /* Clear RCC pending interrupt flags */ ++ mmio_write_32(rcc_base + RCC_MP_CIFR, RCC_MP_CIFR_MASK); ++ ++ /* Request CSTOP mode to RCC */ ++ mmio_setbits_32(rcc_base + RCC_MP_SREQSETR, ++ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); ++ ++ stm32_iwdg_refresh(); ++ ++ gicc_pmr = plat_ic_set_priority_mask(GICC_PMR_PRIORITY_8); ++ ++ /* ++ * Set DDR in Self-refresh, even if no return address is given. ++ * This is also the procedure awaited when switching off power supply. ++ */ ++ if (ddr_standby_sr_entry(&zq0cr0_zdata) != 0) { ++ return; ++ } ++ ++ stm32mp_clk_enable(RTCAPB); ++ ++ mmio_write_32(bkpr_core1_addr, 0); ++ mmio_write_32(bkpr_core1_magic, 0); ++ ++ if (mode == STM32_PM_CSTOP_ALLOW_STANDBY_DDR_SR) { ++ /* ++ * Save non-secure world entrypoint after standby in Backup ++ * register ++ */ ++ mmio_write_32(bkpr_core1_addr, nsec_addr); ++ mmio_write_32(bkpr_core1_magic, ++ BOOT_API_A7_CORE0_MAGIC_NUMBER); ++ ++ if (stm32_save_context(zq0cr0_zdata) != 0) { ++ panic(); ++ } ++ ++ /* Keep retention and backup RAM content in standby */ ++ mmio_setbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | ++ PWR_CR2_RREN); ++ while ((mmio_read_32(pwr_base + PWR_CR2) & ++ (PWR_CR2_BRRDY | PWR_CR2_RRRDY)) == 0U) { ++ ; ++ } ++ } ++ ++ stm32mp_clk_disable(RTCAPB); ++ ++ stm32_rtc_get_calendar(&sleep_time); ++ ++ enter_cstop_done = true; ++} ++ ++/* ++ * stm32_exit_cstop - Exit from CSTOP mode ++ */ ++void stm32_exit_cstop(void) ++{ ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ uintptr_t rcc_base = stm32mp_rcc_base(); ++ ++ if (!enter_cstop_done) { ++ return; ++ } ++ ++ enter_cstop_done = false; ++ ++ if (ddr_sw_self_refresh_exit() != 0) { ++ panic(); ++ } ++ ++ plat_ic_set_priority_mask(gicc_pmr); ++ ++ /* Disable RCC Wake-up */ ++ mmio_clrbits_32(rcc_base + RCC_MP_CIER, RCC_MP_CIFR_WKUPF); ++ ++ /* Disable STOP request */ ++ mmio_setbits_32(rcc_base + RCC_MP_SREQCLRR, ++ RCC_MP_SREQSETR_STPREQ_P0 | RCC_MP_SREQSETR_STPREQ_P1); ++ ++ dsb(); ++ isb(); ++ ++ /* Disable retention and backup RAM content after stop */ ++ mmio_clrbits_32(pwr_base + PWR_CR2, PWR_CR2_BREN | PWR_CR2_RREN); ++ ++ /* Update STGEN counter with low power mode duration */ ++ stm32_rtc_get_calendar(¤t_calendar); ++ ++ stdby_time_in_ms = stm32_rtc_diff_calendar(¤t_calendar, ++ &sleep_time); ++ ++ stm32mp1_stgen_increment(stdby_time_in_ms); ++ ++ stm32mp1_syscfg_enable_io_compensation(); ++} ++ ++static void enter_shutdown(void) ++{ ++ /* Set DDR in Self-refresh before shutting down the platform */ ++ if (ddr_standby_sr_entry(NULL) != 0) { ++ WARN("DDR can't be set in Self-refresh mode\n"); ++ } ++ ++ if (dt_pmic_status() > 0) { ++ if (!initialize_pmic_i2c()) { ++ panic(); ++ } ++ ++ stpmic1_switch_off(); ++ ++ udelay(100); ++ ++ /* Shouldn't be reached */ ++ panic(); ++ } ++} ++ ++static void enter_csleep(void) ++{ ++ uintptr_t pwr_base = stm32mp_pwr_base(); ++ ++ mmio_clrsetbits_32(pwr_base + PWR_MPUCR, PWR_MPUCR_MASK, ++ config_pwr[STM32_PM_CSLEEP_RUN].pwr_mpucr); ++ mmio_clrsetbits_32(pwr_base + PWR_CR1, PWR_CR1_MASK, ++ config_pwr[STM32_PM_CSLEEP_RUN].pwr_cr1); ++ ++ stm32_pwr_down_wfi(); ++} ++ ++void stm32_enter_low_power(uint32_t mode, uint32_t nsec_addr) ++{ ++ switch (mode) { ++ case STM32_PM_SHUTDOWN: ++ enter_shutdown(); ++ break; ++ ++ case STM32_PM_CSLEEP_RUN: ++ enter_csleep(); ++ break; ++ ++ default: ++ enter_cstop(mode, nsec_addr); ++ break; ++ } ++} ++ ++void stm32_pwr_down_wfi(void) ++{ ++ uint32_t interrupt = GIC_SPURIOUS_INTERRUPT; ++ ++ while (interrupt == GIC_SPURIOUS_INTERRUPT) { ++ wfi(); ++ ++ interrupt = gicv2_acknowledge_interrupt(); ++ ++ if (interrupt != GIC_SPURIOUS_INTERRUPT) { ++ gicv2_end_of_interrupt(interrupt); ++ } ++ ++ stm32_iwdg_refresh(); ++ } ++} +diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c +index cf9fa8e69..9ebea40f1 100644 +--- a/plat/st/stm32mp1/stm32mp1_pm.c ++++ b/plat/st/stm32mp1/stm32mp1_pm.c +@@ -13,14 +13,20 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + #include + #include + ++#include ++#include ++ + static uintptr_t stm32_sec_entrypoint; + static uint32_t cntfrq_core0; ++static uintptr_t saved_entrypoint; + + /******************************************************************************* + * STM32MP1 handler called when a CPU is about to enter standby. +@@ -33,11 +39,12 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state) + assert(cpu_state == ARM_LOCAL_STATE_RET); + + /* +- * Enter standby state +- * dsb is good practice before using wfi to enter low power states ++ * Enter standby state. ++ * Synchronize on memory accesses and instruction flow before the WFI ++ * instruction. + */ +- isb(); + dsb(); ++ isb(); + while (interrupt == GIC_SPURIOUS_INTERRUPT) { + wfi(); + +@@ -64,10 +71,23 @@ static int stm32_pwr_domain_on(u_register_t mpidr) + uint32_t bkpr_core1_magic = + tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX); + ++ if (stm32mp_is_single_core()) { ++ return PSCI_E_INTERN_FAIL; ++ } ++ + if (mpidr == current_cpu_mpidr) { + return PSCI_E_INVALID_PARAMS; + } + ++ /* Reset backup register content */ ++ mmio_write_32(bkpr_core1_magic, 0); ++ ++ /* Need to send additional IT 0 after individual core 1 reset */ ++ gicv2_raise_sgi(ARM_IRQ_NON_SEC_SGI_0, STM32MP_SECONDARY_CPU); ++ ++ /* Wait for this IT to be acknowledged by ROM code. */ ++ udelay(10); ++ + if ((stm32_sec_entrypoint < STM32MP_SYSRAM_BASE) || + (stm32_sec_entrypoint > (STM32MP_SYSRAM_BASE + + (STM32MP_SYSRAM_SIZE - 1)))) { +@@ -107,7 +127,9 @@ static void stm32_pwr_domain_off(const psci_power_state_t *target_state) + ******************************************************************************/ + static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state) + { +- /* Nothing to do, power domain is not disabled */ ++ uint32_t soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_SUSPEND); ++ ++ stm32_enter_low_power(soc_mode, saved_entrypoint); + } + + /******************************************************************************* +@@ -134,16 +156,59 @@ static void stm32_pwr_domain_suspend_finish(const psci_power_state_t + /* Nothing to do, power domain is not disabled */ + } + ++/******************************************************************************* ++ * STM32MP1 handler called when a core tries to power itself down. If this ++ * call is made by core 0, it is a return from stop mode. In this case, we ++ * should restore previous context and jump to secure entrypoint. ++ ******************************************************************************/ + static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t + *target_state) + { +- ERROR("stm32mpu1 Power Down WFI: operation not handled.\n"); ++ if (MPIDR_AFFLVL0_VAL(read_mpidr_el1()) == STM32MP_PRIMARY_CPU) { ++ void (*warm_entrypoint)(void) = ++ (void (*)(void))stm32_sec_entrypoint; ++ ++ stm32_pwr_down_wfi(); ++ ++ stm32_exit_cstop(); ++ ++ disable_mmu_icache_secure(); ++ ++ warm_entrypoint(); ++ } ++ ++ mmio_write_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, ++ RCC_MP_GRSTCSETR_MPUP1RST); ++ ++ /* ++ * Synchronize on memory accesses and instruction flow before ++ * auto-reset from the WFI instruction. ++ */ ++ dsb(); ++ isb(); ++ wfi(); ++ ++ /* This shouldn't be reached */ + panic(); + } + + static void __dead2 stm32_system_off(void) + { +- ERROR("stm32mpu1 System Off: operation not handled.\n"); ++ uint32_t soc_mode = stm32mp1_get_lp_soc_mode(PSCI_MODE_SYSTEM_OFF); ++ ++ if (!stm32mp_is_single_core()) { ++ /* Prepare Core 1 reset */ ++ mmio_setbits_32(stm32mp_rcc_base() + RCC_MP_GRSTCSETR, ++ RCC_MP_GRSTCSETR_MPUP1RST); ++ /* Send IT to core 1 to put itself in WFI */ ++ gicv2_raise_sgi(ARM_IRQ_SEC_SGI_1, STM32MP_SECONDARY_CPU); ++ } ++ ++ stm32_enter_low_power(soc_mode, 0); ++ ++ stm32_pwr_down_wfi(); ++ ++ /* This shouldn't be reached */ + panic(); + } + +@@ -188,6 +253,8 @@ static int stm32_validate_ns_entrypoint(uintptr_t entrypoint) + return PSCI_E_INVALID_ADDRESS; + } + ++ saved_entrypoint = entrypoint; ++ + return PSCI_E_SUCCESS; + } + +@@ -211,6 +278,12 @@ static int stm32_node_hw_state(u_register_t target_cpu, + return (int)HW_ON; + } + ++static void stm32_get_sys_suspend_power_state(psci_power_state_t *req_state) ++{ ++ req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_OFF; ++ req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_OFF; ++} ++ + /******************************************************************************* + * Export the platform handlers. The ARM Standard platform layer will take care + * of registering the handlers with PSCI. +@@ -227,7 +300,8 @@ static const plat_psci_ops_t stm32_psci_ops = { + .system_reset = stm32_system_reset, + .validate_power_state = stm32_validate_power_state, + .validate_ns_entrypoint = stm32_validate_ns_entrypoint, +- .get_node_hw_state = stm32_node_hw_state ++ .get_node_hw_state = stm32_node_hw_state, ++ .get_sys_suspend_power_state = stm32_get_sys_suspend_power_state, + }; + + /******************************************************************************* +diff --git a/plat/st/stm32mp1/stm32mp1_power_config.c b/plat/st/stm32mp1/stm32mp1_power_config.c +new file mode 100644 +index 000000000..93644f4ea +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_power_config.c +@@ -0,0 +1,130 @@ ++/* ++ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#define DT_PWR_COMPAT "st,stm32mp1-pwr" ++#define SYSTEM_SUSPEND_SUPPORTED_MODES "system_suspend_supported_soc_modes" ++#define SYSTEM_OFF_MODE "system_off_soc_mode" ++ ++static uint32_t deepest_system_suspend_mode; ++static uint32_t system_off_mode; ++static uint8_t stm32mp1_supported_soc_modes[STM32_PM_MAX_SOC_MODE]; ++ ++static int dt_get_pwr_node(void *fdt) ++{ ++ return fdt_node_offset_by_compatible(fdt, -1, DT_PWR_COMPAT); ++} ++ ++static void save_supported_mode(void *fdt, int pwr_node) ++{ ++ int len; ++ uint32_t count; ++ unsigned int i; ++ uint32_t supported[ARRAY_SIZE(stm32mp1_supported_soc_modes)]; ++ const void *prop; ++ ++ prop = fdt_getprop(fdt, pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, &len); ++ if (prop == NULL) { ++ panic(); ++ } ++ ++ count = (uint32_t)len / sizeof(uint32_t); ++ if (count > STM32_PM_MAX_SOC_MODE) { ++ panic(); ++ } ++ ++ if (fdt_read_uint32_array(pwr_node, SYSTEM_SUSPEND_SUPPORTED_MODES, ++ &supported[0], count) < 0) { ++ ERROR("PWR DT\n"); ++ panic(); ++ } ++ ++ for (i = 0; i < count; i++) { ++ if (supported[i] >= STM32_PM_MAX_SOC_MODE) { ++ ERROR("Invalid mode\n"); ++ panic(); ++ } ++ stm32mp1_supported_soc_modes[supported[i]] = 1U; ++ } ++ ++ /* Initialize to deepest possible mode */ ++ for (i = STM32_PM_MAX_SOC_MODE - 1U; i != STM32_PM_CSLEEP_RUN; i--) { ++ if (stm32mp1_supported_soc_modes[i] == 1U) { ++ deepest_system_suspend_mode = i; ++ break; ++ } ++ } ++} ++ ++static int dt_fill_lp_state(uint32_t *lp_state_config, const char *lp_state) ++{ ++ int pwr_node; ++ void *fdt; ++ const fdt32_t *cuint; ++ ++ if (fdt_get_address(&fdt) == 0) { ++ return -ENOENT; ++ } ++ ++ pwr_node = dt_get_pwr_node(fdt); ++ if (pwr_node < 0) { ++ return -FDT_ERR_NOTFOUND; ++ } ++ ++ cuint = fdt_getprop(fdt, pwr_node, lp_state, NULL); ++ if (cuint == NULL) { ++ return -FDT_ERR_NOTFOUND; ++ } ++ ++ *lp_state_config = fdt32_to_cpu(*cuint); ++ ++ save_supported_mode(fdt, pwr_node); ++ ++ return 0; ++} ++ ++void stm32mp1_init_lp_states(void) ++{ ++ if (dt_fill_lp_state(&system_off_mode, SYSTEM_OFF_MODE) < 0) { ++ ERROR("Node %s not found\n", SYSTEM_OFF_MODE); ++ panic(); ++ } ++} ++ ++static bool is_allowed_mode(uint32_t soc_mode) ++{ ++ assert(soc_mode < ARRAY_SIZE(stm32mp1_supported_soc_modes)); ++ ++ return stm32mp1_supported_soc_modes[soc_mode] == 1U; ++} ++ ++uint32_t stm32mp1_get_lp_soc_mode(uint32_t psci_mode) ++{ ++ uint32_t mode; ++ ++ if (psci_mode == PSCI_MODE_SYSTEM_OFF) { ++ return system_off_mode; ++ } ++ ++ mode = deepest_system_suspend_mode; ++ ++ while ((mode > STM32_PM_CSLEEP_RUN) && !is_allowed_mode(mode)) { ++ mode--; ++ } ++ ++ return mode; ++} +diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c +index e2dcd2af7..3a7b22e37 100644 +--- a/plat/st/stm32mp1/stm32mp1_private.c ++++ b/plat/st/stm32mp1/stm32mp1_private.c +@@ -10,8 +10,11 @@ + + #include + ++#include ++#include + #include + #include ++#include + + /* Internal layout of the 32bit OTP word board_id */ + #define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16) +@@ -76,6 +79,42 @@ void configure_mmu(void) + enable_mmu_svc_mon(0); + } + ++#define ARM_CNTXCTL_IMASK BIT(1) ++ ++void stm32mp_mask_timer(void) ++{ ++ /* Mask timer interrupts */ ++ write_cntp_ctl(read_cntp_ctl() | ARM_CNTXCTL_IMASK); ++ write_cntv_ctl(read_cntv_ctl() | ARM_CNTXCTL_IMASK); ++} ++ ++void __dead2 stm32mp_wait_cpu_reset(void) ++{ ++ uint32_t id; ++ ++ dcsw_op_all(DC_OP_CISW); ++ write_sctlr(read_sctlr() & ~SCTLR_C_BIT); ++ dcsw_op_all(DC_OP_CISW); ++ __asm__("clrex"); ++ ++ dsb(); ++ isb(); ++ ++ for ( ; ; ) { ++ do { ++ id = plat_ic_get_pending_interrupt_id(); ++ ++ if (id <= MAX_SPI_ID) { ++ gicv2_end_of_interrupt(id); ++ ++ plat_ic_disable_interrupt(id); ++ } ++ } while (id <= MAX_SPI_ID); ++ ++ wfi(); ++ } ++} ++ + unsigned long stm32_get_gpio_bank_clock(unsigned int bank) + { + if (bank == GPIO_BANK_Z) { +diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c.bak b/plat/st/stm32mp1/stm32mp1_shared_resources.c.bak +new file mode 100644 +index 000000000..208e34a8b +--- /dev/null ++++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c.bak +@@ -0,0 +1,597 @@ ++/* ++ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++/* ++ * Once one starts to get the resource registering state, one cannot register ++ * new resources. This ensures resource state cannot change. ++ */ ++static bool registering_locked; ++ ++/* ++ * Shared peripherals and resources registration ++ * ++ * Each resource assignation is stored in a table. The state defaults ++ * to PERIPH_UNREGISTERED if the resource is not explicitly assigned. ++ * ++ * Resource driver that as not embedded (a.k.a their related CFG_xxx build ++ * directive is disabled) are assigned to the non-secure world. ++ * ++ * Each pin of the GPIOZ bank can be secure or non-secure. ++ * ++ * It is the platform responsibility the ensure resource assignation ++ * matches the access permission firewalls configuration. ++ */ ++enum shres_state { ++ SHRES_UNREGISTERED = 0, ++ SHRES_SECURE, ++ SHRES_NON_SECURE, ++}; ++ ++/* Force uint8_t array for array of enum shres_state for size considerations */ ++static uint8_t shres_state[STM32MP1_SHRES_COUNT]; ++ ++static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = { ++ [STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0", ++ [STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1", ++ [STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2", ++ [STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3", ++ [STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4", ++ [STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5", ++ [STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6", ++ [STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7", ++ [STM32MP1_SHRES_IWDG1] = "IWDG1", ++ [STM32MP1_SHRES_USART1] = "USART1", ++ [STM32MP1_SHRES_SPI6] = "SPI6", ++ [STM32MP1_SHRES_I2C4] = "I2C4", ++ [STM32MP1_SHRES_RNG1] = "RNG1", ++ [STM32MP1_SHRES_HASH1] = "HASH1", ++ [STM32MP1_SHRES_CRYP1] = "CRYP1", ++ [STM32MP1_SHRES_I2C6] = "I2C6", ++ [STM32MP1_SHRES_RTC] = "RTC", ++ [STM32MP1_SHRES_MCU] = "MCU", ++ [STM32MP1_SHRES_MDMA] = "MDMA", ++ [STM32MP1_SHRES_PLL3] = "PLL3", ++}; ++ ++static const char __unused *shres2str_id(enum stm32mp_shres id) ++{ ++ assert(id < ARRAY_SIZE(shres2str_id_tbl)); ++ ++ return shres2str_id_tbl[id]; ++} ++ ++static const char __unused *shres2str_state_tbl[] = { ++ [SHRES_UNREGISTERED] = "unregistered", ++ [SHRES_NON_SECURE] = "non-secure", ++ [SHRES_SECURE] = "secure", ++}; ++ ++static const char __unused *shres2str_state(unsigned int state) ++{ ++ assert(state < ARRAY_SIZE(shres2str_state_tbl)); ++ ++ return shres2str_state_tbl[state]; ++} ++ ++/* Get resource state: these accesses lock the registering support */ ++static void lock_registering(void) ++{ ++ registering_locked = true; ++} ++ ++static bool periph_is_non_secure(enum stm32mp_shres id) ++{ ++ lock_registering(); ++ ++ return (shres_state[id] == SHRES_NON_SECURE) || ++ (shres_state[id] == SHRES_UNREGISTERED); ++} ++ ++static bool periph_is_secure(enum stm32mp_shres id) ++{ ++ return !periph_is_non_secure(id); ++} ++ ++/* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */ ++static int8_t gpioz_nbpin = -1; ++ ++static unsigned int get_gpio_nbpin(unsigned int bank) ++{ ++ if (bank != GPIO_BANK_Z) { ++ int count = fdt_get_gpio_bank_pin_count(bank); ++ ++ assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1))); ++ ++ return (unsigned int)count; ++ } ++ ++ if (gpioz_nbpin < 0) { ++ int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z); ++ ++ assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT)); ++ ++ gpioz_nbpin = count; ++ } ++ ++ return (unsigned int)gpioz_nbpin; ++} ++ ++static unsigned int get_gpioz_nbpin(void) ++{ ++ return get_gpio_nbpin(GPIO_BANK_Z); ++} ++ ++static void register_periph(enum stm32mp_shres id, unsigned int state) ++{ ++ assert((id < STM32MP1_SHRES_COUNT) && ++ ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE))); ++ ++ if (registering_locked) { ++ if (shres_state[id] == state) { ++ return; ++ } ++ panic(); ++ } ++ ++ if ((shres_state[id] != SHRES_UNREGISTERED) && ++ (shres_state[id] != state)) { ++ VERBOSE("Cannot change %s from %s to %s\n", ++ shres2str_id(id), ++ shres2str_state(shres_state[id]), ++ shres2str_state(state)); ++ panic(); ++ } ++ ++ if (shres_state[id] == SHRES_UNREGISTERED) { ++ VERBOSE("Register %s as %s\n", ++ shres2str_id(id), shres2str_state(state)); ++ } ++ ++ if ((id >= STM32MP1_SHRES_GPIOZ(0)) && ++ (id <= STM32MP1_SHRES_GPIOZ(7)) && ++ ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) { ++ ERROR("Invalid GPIO pin %u, %u pin(s) available\n", ++ id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin()); ++ panic(); ++ } ++ ++ shres_state[id] = (uint8_t)state; ++ ++ /* Explore clock tree to lock dependencies */ ++ if (state == SHRES_SECURE) { ++ enum stm32mp_shres clock_res_id; ++ ++ switch (id) { ++ case STM32MP1_SHRES_GPIOZ(0): ++ case STM32MP1_SHRES_GPIOZ(1): ++ case STM32MP1_SHRES_GPIOZ(2): ++ case STM32MP1_SHRES_GPIOZ(3): ++ case STM32MP1_SHRES_GPIOZ(4): ++ case STM32MP1_SHRES_GPIOZ(5): ++ case STM32MP1_SHRES_GPIOZ(6): ++ case STM32MP1_SHRES_GPIOZ(7): ++ clock_res_id = GPIOZ; ++ break; ++ case STM32MP1_SHRES_IWDG1: ++ clock_res_id = IWDG1; ++ break; ++ case STM32MP1_SHRES_USART1: ++ clock_res_id = USART1_K; ++ break; ++ case STM32MP1_SHRES_SPI6: ++ clock_res_id = SPI6_K; ++ break; ++ case STM32MP1_SHRES_I2C4: ++ clock_res_id = I2C4_K; ++ break; ++ case STM32MP1_SHRES_RNG1: ++ clock_res_id = RNG1_K; ++ break; ++ case STM32MP1_SHRES_HASH1: ++ clock_res_id = HASH1; ++ break; ++ case STM32MP1_SHRES_CRYP1: ++ clock_res_id = CRYP1; ++ break; ++ case STM32MP1_SHRES_I2C6: ++ clock_res_id = I2C6_K; ++ break; ++ case STM32MP1_SHRES_RTC: ++ clock_res_id = RTC; ++ break; ++ default: ++ /* No clock resource dependency */ ++ return; ++ } ++ ++ stm32mp1_register_clock_parents_secure(clock_res_id); ++ } ++} ++ ++/* Register resource by ID */ ++void stm32mp_register_secure_periph(enum stm32mp_shres id) ++{ ++ register_periph(id, SHRES_SECURE); ++} ++ ++void stm32mp_register_non_secure_periph(enum stm32mp_shres id) ++{ ++ register_periph(id, SHRES_NON_SECURE); ++} ++ ++static void register_periph_iomem(uintptr_t base, unsigned int state) ++{ ++ enum stm32mp_shres id; ++ ++ switch (base) { ++ case CRYP1_BASE: ++ id = STM32MP1_SHRES_CRYP1; ++ break; ++ case HASH1_BASE: ++ id = STM32MP1_SHRES_HASH1; ++ break; ++ case I2C4_BASE: ++ id = STM32MP1_SHRES_I2C4; ++ break; ++ case I2C6_BASE: ++ id = STM32MP1_SHRES_I2C6; ++ break; ++ case IWDG1_BASE: ++ id = STM32MP1_SHRES_IWDG1; ++ break; ++ case RNG1_BASE: ++ id = STM32MP1_SHRES_RNG1; ++ break; ++ case RTC_BASE: ++ id = STM32MP1_SHRES_RTC; ++ break; ++ case SPI6_BASE: ++ id = STM32MP1_SHRES_SPI6; ++ break; ++ case USART1_BASE: ++ id = STM32MP1_SHRES_USART1; ++ break; ++ ++ case GPIOA_BASE: ++ case GPIOB_BASE: ++ case GPIOC_BASE: ++ case GPIOD_BASE: ++ case GPIOE_BASE: ++ case GPIOF_BASE: ++ case GPIOG_BASE: ++ case GPIOH_BASE: ++ case GPIOI_BASE: ++ case GPIOJ_BASE: ++ case GPIOK_BASE: ++ case USART2_BASE: ++ case USART3_BASE: ++ case UART4_BASE: ++ case UART5_BASE: ++ case USART6_BASE: ++ case UART7_BASE: ++ case UART8_BASE: ++ case IWDG2_BASE: ++ /* Allow drivers to register some non-secure resources */ ++ VERBOSE("IO for non-secure resource 0x%x\n", ++ (unsigned int)base); ++ if (state != SHRES_NON_SECURE) { ++ panic(); ++ } ++ ++ return; ++ ++ default: ++ panic(); ++ } ++ ++ register_periph(id, state); ++} ++ ++void stm32mp_register_secure_periph_iomem(uintptr_t base) ++{ ++ register_periph_iomem(base, SHRES_SECURE); ++} ++ ++void stm32mp_register_non_secure_periph_iomem(uintptr_t base) ++{ ++ register_periph_iomem(base, SHRES_NON_SECURE); ++} ++ ++void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin) ++{ ++ switch (bank) { ++ case GPIO_BANK_Z: ++ register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE); ++ break; ++ default: ++ ERROR("GPIO bank %u cannot be secured\n", bank); ++ panic(); ++ } ++} ++ ++void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) ++{ ++ switch (bank) { ++ case GPIO_BANK_Z: ++ register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE); ++ break; ++ default: ++ break; ++ } ++} ++ ++static bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) ++{ ++ unsigned int non_secure = 0U; ++ unsigned int i; ++ ++ lock_registering(); ++ ++ if (bank != GPIO_BANK_Z) { ++ return true; ++ } ++ ++ for (i = 0U; i < get_gpioz_nbpin(); i++) { ++ if (periph_is_non_secure(STM32MP1_SHRES_GPIOZ(i))) { ++ non_secure++; ++ } ++ } ++ ++ return non_secure == get_gpioz_nbpin(); ++} ++ ++static bool stm32mp_gpio_bank_is_secure(unsigned int bank) ++{ ++ unsigned int secure = 0U; ++ unsigned int i; ++ ++ lock_registering(); ++ ++ if (bank != GPIO_BANK_Z) { ++ return false; ++ } ++ ++ for (i = 0U; i < get_gpioz_nbpin(); i++) { ++ if (periph_is_secure(STM32MP1_SHRES_GPIOZ(i))) { ++ secure++; ++ } ++ } ++ ++ return secure == get_gpioz_nbpin(); ++} ++ ++bool stm32mp_nsec_can_access_clock(unsigned long clock_id) ++{ ++ enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; ++ ++ switch (clock_id) { ++ case CK_CSI: ++ case CK_HSE: ++ case CK_HSE_DIV2: ++ case CK_HSI: ++ case CK_LSE: ++ case CK_LSI: ++ case PLL1_P: ++ case PLL1_Q: ++ case PLL1_R: ++ case PLL2_P: ++ case PLL2_Q: ++ case PLL2_R: ++ case PLL3_P: ++ case PLL3_Q: ++ case PLL3_R: ++ case RTCAPB: ++ return true; ++ case GPIOZ: ++ /* Allow clock access if at least one pin is non-secure */ ++ return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z); ++ case CRYP1: ++ shres_id = STM32MP1_SHRES_CRYP1; ++ break; ++ case HASH1: ++ shres_id = STM32MP1_SHRES_HASH1; ++ break; ++ case I2C4_K: ++ shres_id = STM32MP1_SHRES_I2C4; ++ break; ++ case I2C6_K: ++ shres_id = STM32MP1_SHRES_I2C6; ++ break; ++ case IWDG1: ++ shres_id = STM32MP1_SHRES_IWDG1; ++ break; ++ case RNG1_K: ++ shres_id = STM32MP1_SHRES_RNG1; ++ break; ++ case RTC: ++ shres_id = STM32MP1_SHRES_RTC; ++ break; ++ case SPI6_K: ++ shres_id = STM32MP1_SHRES_SPI6; ++ break; ++ case USART1_K: ++ shres_id = STM32MP1_SHRES_USART1; ++ break; ++ default: ++ return false; ++ } ++ ++ return periph_is_non_secure(shres_id); ++} ++ ++bool stm32mp_nsec_can_access_reset(unsigned int reset_id) ++{ ++ enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; ++ ++ switch (reset_id) { ++ case CRYP1_R: ++ shres_id = STM32MP1_SHRES_CRYP1; ++ break; ++ case GPIOZ_R: ++ /* GPIOZ reset mandates all pins are non-secure */ ++ return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z); ++ case HASH1_R: ++ shres_id = STM32MP1_SHRES_HASH1; ++ break; ++ case I2C4_R: ++ shres_id = STM32MP1_SHRES_I2C4; ++ break; ++ case I2C6_R: ++ shres_id = STM32MP1_SHRES_I2C6; ++ break; ++ case MCU_R: ++ shres_id = STM32MP1_SHRES_MCU; ++ break; ++ case MDMA_R: ++ shres_id = STM32MP1_SHRES_MDMA; ++ break; ++ case RNG1_R: ++ shres_id = STM32MP1_SHRES_RNG1; ++ break; ++ case SPI6_R: ++ shres_id = STM32MP1_SHRES_SPI6; ++ break; ++ case USART1_R: ++ shres_id = STM32MP1_SHRES_USART1; ++ break; ++ default: ++ return false; ++ } ++ ++ return periph_is_non_secure(shres_id); ++} ++ ++static bool mckprot_protects_periph(enum stm32mp_shres id) ++{ ++ switch (id) { ++ case STM32MP1_SHRES_MCU: ++ case STM32MP1_SHRES_PLL3: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++/* ETZPC configuration at drivers initialization completion */ ++static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id) ++{ ++ assert((id < STM32MP1_SHRES_GPIOZ(0)) || ++ (id > STM32MP1_SHRES_GPIOZ(7))); ++ ++ if (periph_is_non_secure(id)) { ++ return ETZPC_DECPROT_NS_RW; ++ } ++ ++ return ETZPC_DECPROT_S_RW; ++} ++ ++static void set_etzpc_secure_configuration(void) ++{ ++ /* Some system peripherals shall be secure */ ++ etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW); ++ etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW); ++ etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID, ++ ETZPC_DECPROT_NS_R_S_W); ++ etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID, ++ ETZPC_DECPROT_NS_R_S_W); ++ ++ /* Configure ETZPC with peripheral registering */ ++ etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID, ++ shres2decprot_attr(STM32MP1_SHRES_CRYP1)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID, ++ shres2decprot_attr(STM32MP1_SHRES_HASH1)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID, ++ shres2decprot_attr(STM32MP1_SHRES_I2C4)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID, ++ shres2decprot_attr(STM32MP1_SHRES_I2C6)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID, ++ shres2decprot_attr(STM32MP1_SHRES_IWDG1)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID, ++ shres2decprot_attr(STM32MP1_SHRES_RNG1)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID, ++ shres2decprot_attr(STM32MP1_SHRES_USART1)); ++ etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID, ++ shres2decprot_attr(STM32MP1_SHRES_SPI6)); ++} ++ ++static void check_rcc_secure_configuration(void) ++{ ++ uint32_t n; ++ uint32_t error = 0U; ++ bool mckprot = stm32mp1_rcc_is_mckprot(); ++ bool secure = stm32mp1_rcc_is_secure(); ++ ++ for (n = 0U; n < ARRAY_SIZE(shres_state); n++) { ++ if (shres_state[n] != SHRES_SECURE) { ++ continue; ++ } ++ ++ if (!secure || (mckprot_protects_periph(n) && (!mckprot))) { ++ ERROR("RCC %s MCKPROT %s and %s secure\n", ++ secure ? "secure" : "non-secure", ++ mckprot ? "set" : "not set", ++ shres2str_id(n)); ++ error++; ++ } ++ } ++ ++ if (error != 0U) { ++ panic(); ++ } ++} ++ ++static void set_gpio_secure_configuration(void) ++{ ++ uint32_t pin; ++ ++ for (pin = 0U; pin < get_gpioz_nbpin(); pin++) { ++ bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin)); ++ ++ set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state); ++ } ++} ++ ++static void print_shared_resources_state(void) ++{ ++ unsigned int id; ++ ++ for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) { ++ switch (shres_state[id]) { ++ case SHRES_SECURE: ++ INFO("stm32mp1 %s is secure\n", shres2str_id(id)); ++ break; ++ case SHRES_NON_SECURE: ++ case SHRES_UNREGISTERED: ++ VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id)); ++ break; ++ default: ++ VERBOSE("stm32mp %s is invalid\n", shres2str_id(id)); ++ panic(); ++ } ++ } ++} ++ ++void stm32mp_lock_periph_registering(void) ++{ ++ registering_locked = true; ++ ++ print_shared_resources_state(); ++ ++ check_rcc_secure_configuration(); ++ set_etzpc_secure_configuration(); ++ set_gpio_secure_configuration(); ++} +-- +2.27.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0008-fix-for-ethernet.patch b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0008-fix-for-ethernet.patch new file mode 100644 index 0000000..e4f6cbb --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/arm-trusted-firmware/0008-fix-for-ethernet.patch @@ -0,0 +1,31 @@ +diff --git a/fdts/stm32mp157a-dk1.dts b/fdts/stm32mp157a-dk1.dts +index 2eced8f53..e5b092be1 100644 +--- a/fdts/stm32mp157a-dk1.dts ++++ b/fdts/stm32mp157a-dk1.dts +@@ -245,7 +245,7 @@ + CLK_CKPER_HSE + CLK_FMC_ACLK + CLK_QSPI_ACLK +- CLK_ETH_DISABLED ++ CLK_ETH_PLL4P + CLK_SDMMC12_PLL4P + CLK_DSI_DSIPLL + CLK_STGEN_HSE +@@ -297,10 +297,15 @@ + frac = < 0x1a04 >; + }; + +- /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ ++ /* ++ * ETH_CLK required a 125MHz clock, so ++ * original: VCO = 594.0 MHz => P = 99, Q = 74, R = 74 ++ * current : VCO = 750.0 MHz => P =125, Q = 75, R = 75 ++ */ + pll4: st,pll@3 { +- cfg = < 3 98 5 7 7 PQR(1,1,1) >; ++ cfg = < 3 124 5 11 11 PQR(1,1,1) >; + }; ++ + }; + + &bsec { diff --git a/board/myna-player-odyssey/rootfs_patches/barebox/0001-dts-stm32mp157c-odyssey-add-partitions-and-state-framework-support.patch b/board/myna-player-odyssey/rootfs_patches/barebox/0001-dts-stm32mp157c-odyssey-add-partitions-and-state-framework-support.patch new file mode 100644 index 0000000..a7137db --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/barebox/0001-dts-stm32mp157c-odyssey-add-partitions-and-state-framework-support.patch @@ -0,0 +1,99 @@ +From f2c72e8b170f05390896fc845f28ca77dd8ee658 Mon Sep 17 00:00:00 2001 +From: Xogium +Date: Wed, 29 Jul 2020 23:41:35 +0200 +Subject: [PATCH 1/4] dts: stm32mp157c-odyssey: add partitions and state + framework support. + +--- + arch/arm/dts/stm32mp157c-odyssey.dts | 68 ++++++++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + +diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts +index 0e395bdec..8b570443b 100644 +--- a/arch/arm/dts/stm32mp157c-odyssey.dts ++++ b/arch/arm/dts/stm32mp157c-odyssey.dts +@@ -7,6 +7,10 @@ + #include "stm32mp151.dtsi" + + / { ++ aliases { ++ state = &state; ++ }; ++ + chosen { + environment-sd { + compatible = "barebox,environment"; +@@ -19,6 +23,70 @@ + device-path = &sdmmc2, "partname:barebox-environment"; + status = "disabled"; + }; ++ ++ state: state { ++ magic = <0x12222013>; ++ compatible = "barebox,state"; ++ backend-type = "raw"; ++ backend = <&state_mmc>; ++ backend-stridesize = <1024>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ bootstate { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ system0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ remaining_attempts { ++ reg = <0x0 0x4>; ++ type = "uint32"; ++ default = <3>; ++ }; ++ priority { ++ reg = <0x4 0x4>; ++ type = "uint32"; ++ default = <21>; ++ }; ++ }; ++ system1 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ remaining_attempts { ++ reg = <0x10 0x4>; ++ type = "uint32"; ++ default = <3>; ++ }; ++ priority { ++ reg = <0x14 0x4>; ++ type = "uint32"; ++ default = <20>; ++ }; ++ }; ++ }; ++ last_chosen { ++ reg = <0x20 0x4>; ++ type = "uint32"; ++ }; ++ }; ++ }; ++}; ++ ++&sdmmc2 { ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #size-cells = <1>; ++ #address-cells = <1>; ++ ++ state_mmc: partition@14400 { ++ label = "state"; ++ reg = <0x14400 0x30000>; ++ }; + }; + }; + +-- +2.28.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/barebox/0001-dts-stm32mp157c-odyssey-fix-location-of-last_chosen.patch b/board/myna-player-odyssey/rootfs_patches/barebox/0001-dts-stm32mp157c-odyssey-fix-location-of-last_chosen.patch new file mode 100644 index 0000000..6e16fd8 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/barebox/0001-dts-stm32mp157c-odyssey-fix-location-of-last_chosen.patch @@ -0,0 +1,32 @@ +From 09d292d3a1cc99047a98916a1aad8ece2ce18954 Mon Sep 17 00:00:00 2001 +From: Xogium +Date: Sun, 2 Aug 2020 12:49:35 +0200 +Subject: [PATCH 4/4] dts: stm32mp157c-odyssey.dts: fix location of last_chosen + node. + +--- + arch/arm/dts/stm32mp157c-odyssey.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts +index 182a5149d..1e2510cdc 100644 +--- a/arch/arm/dts/stm32mp157c-odyssey.dts ++++ b/arch/arm/dts/stm32mp157c-odyssey.dts +@@ -67,10 +67,10 @@ + default = <20>; + }; + }; +- }; +- last_chosen { +- reg = <0x20 0x4>; +- type = "uint32"; ++ last_chosen { ++ reg = <0x20 0x4>; ++ type = "uint32"; ++ }; + }; + }; + }; +-- +2.28.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/barebox/0002-Revert-fs-free-inodes-we-no-longer-need.patch b/board/myna-player-odyssey/rootfs_patches/barebox/0002-Revert-fs-free-inodes-we-no-longer-need.patch new file mode 100644 index 0000000..21836a5 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/barebox/0002-Revert-fs-free-inodes-we-no-longer-need.patch @@ -0,0 +1,33 @@ +From 3eabdda706a8124e90cc1b2e6af918e6439dee6b Mon Sep 17 00:00:00 2001 +From: Jookia +Date: Tue, 4 Aug 2020 10:21:11 +1000 +Subject: [PATCH 2/4] Revert "fs: free inodes we no longer need" + +This reverts commit 43902e57633f5dd9bc71f1a30d69d7bc0f49dc6b. +--- + fs/fs.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/fs/fs.c b/fs/fs.c +index e04cadfe5..cecb3d70e 100644 +--- a/fs/fs.c ++++ b/fs/fs.c +@@ -1090,12 +1090,10 @@ void iput(struct inode *inode) + if (!inode) + return; + +- inode->i_count--; ++ if (!inode->i_count) ++ return; + +- if (!inode->i_count) { +- list_del(&inode->i_sb_list); +- destroy_inode(inode); +- } ++ inode->i_count--; + } + + struct inode *iget(struct inode *inode) +-- +2.28.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/barebox/0003-dts-stm32mp157c-odyssey-Add-Ethernet-support.patch b/board/myna-player-odyssey/rootfs_patches/barebox/0003-dts-stm32mp157c-odyssey-Add-Ethernet-support.patch new file mode 100644 index 0000000..cfffbb2 --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/barebox/0003-dts-stm32mp157c-odyssey-Add-Ethernet-support.patch @@ -0,0 +1,48 @@ +From 5011a3d9cbfa734a34718cc2471ef481550b3032 Mon Sep 17 00:00:00 2001 +From: Jookia +Date: Tue, 4 Aug 2020 10:21:47 +1000 +Subject: [PATCH 3/4] dts: stm32mp157c-odyssey: Add Ethernet support + +This uses PLL4_P as the internal Ethernet clock, so ATF or U-Boot must +clock PLL4 to 750MHz for this to work. +--- + arch/arm/dts/stm32mp157c-odyssey.dts | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/arch/arm/dts/stm32mp157c-odyssey.dts b/arch/arm/dts/stm32mp157c-odyssey.dts +index 8b570443b..182a5149d 100644 +--- a/arch/arm/dts/stm32mp157c-odyssey.dts ++++ b/arch/arm/dts/stm32mp157c-odyssey.dts +@@ -93,3 +93,29 @@ + &phy0 { + reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; + }; ++ ++ðernet0 { ++ status = "okay"; ++ pinctrl-0 = <ðernet0_rgmii_pins_a>; ++ pinctrl-1 = <ðernet0_rgmii_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rgmii-id"; ++ max-speed = <1000>; ++ phy-handle = <&phy0>; ++ assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>; ++ assigned-clock-parents = <&rcc PLL4_P>; ++ assigned-clock-rates = <125000000>; ++ st,eth-clk-sel; ++ ++ mdio0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ phy0: ethernet-phy@7 { /* KSZ9031RN */ ++ reg = <7>; ++ reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; /* ETH_RST# */ ++ reset-assert-us = <10000>; ++ reset-deassert-us = <300>; ++ }; ++ }; ++}; +-- +2.28.0 + diff --git a/board/myna-player-odyssey/rootfs_patches/linux/0001-dt-bindings-vendor-prefixes-add-Seeed-Studio.patch b/board/myna-player-odyssey/rootfs_patches/linux/0001-dt-bindings-vendor-prefixes-add-Seeed-Studio.patch new file mode 100644 index 0000000..af9007c --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/linux/0001-dt-bindings-vendor-prefixes-add-Seeed-Studio.patch @@ -0,0 +1,160 @@ +From patchwork Fri Jul 31 14:30:51 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Marcin Sloniewski +X-Patchwork-Id: 11695067 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B9F21722 + for ; + Fri, 31 Jul 2020 14:31:27 +0000 (UTC) +Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id 92601208E4 + for ; + Fri, 31 Jul 2020 14:31:27 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="Lt3YNq+v"; + dkim=fail reason="signature verification failed" (2048-bit key) + header.d=gmail.com header.i=@gmail.com header.b="rooF5Y/L" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 92601208E4 +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=gmail.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: + Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: + List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: + Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender + :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; + bh=5bfzbNe1z8q22R2VERGYLDMIQrfP7PggkAr/XL6D3mw=; b=Lt3YNq+vn+BoHN23MO3PZGlHVm + dqrgDQoV1elTWeHOcV6CkwIlovqZi8lwX+gBgjtKkkV+zYUS/kZiL+xI2L6R99cHzyqzJs/1PWlmJ + 27ySLX2cDxUVywgtQHJevjS9X6HqxUcwcU0K0pjpGimxqORMfVAU+Z4oRAlFTxgPs0sv2YaqhJmvk + GMjjg/yUqXA9nc6/vRZLWs2eOj/gPJ8MHa9IW25qB6cSgaVNlSTScEdZcC1TOyRW3zRW9WXFS/aO7 + hOjOksgfh5/LdBQK58rQ8ET42v8hmowPUckNRoLYOeScRel0omz6J3Cn/lvDHdr+ghoXw0ofj0nKR + qitF9cJQ==; +Received: from localhost ([::1] helo=merlin.infradead.org) + by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1k1W43-0007vm-3P; Fri, 31 Jul 2020 14:31:15 +0000 +Received: from mail-ej1-x641.google.com ([2a00:1450:4864:20::641]) + by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1k1W3z-0007uF-H5 + for linux-arm-kernel@lists.infradead.org; Fri, 31 Jul 2020 14:31:12 +0000 +Received: by mail-ej1-x641.google.com with SMTP id f24so11136917ejx.6 + for ; + Fri, 31 Jul 2020 07:31:09 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=from:to:cc:subject:date:message-id:mime-version + :content-transfer-encoding; + bh=TnSVvBPLgxOr7Okxa4+yFdbMwIKkVndKbRuepRfY/Zs=; + b=rooF5Y/LejVp6e+lkheBsBcOKwrWhHZzYXHf1m9XAOFNv87fHiPOh8t6nVxb4zVyuN + QDpyFEFyiTwlk8xKArO+TX4KUIY++pi8GQ2aMGQeJFu49tn7aim8G/kueOGS8tfEIrpQ + m8Eb/crBpL+aHjgty9b9jP36O8almuZhO0THmWfwhZOGRGmaQuoebyiVPkJPoZnWfb12 + IcMNREwMZeqv+FGO3XG63F7LBQcdiGEnQayFjSUl4e7jJzqbqQliGxVniSm03H8C3sTg + +qszh99IXLCLTlEOsKO0vTmCHnKjuYFc0sYdgnG4a917/G1WL5EJUUsElxaTKZz5mVRc + 1i7g== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20161025; + h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version + :content-transfer-encoding; + bh=TnSVvBPLgxOr7Okxa4+yFdbMwIKkVndKbRuepRfY/Zs=; + b=A2u1MUjMrLVbjxjdbxnHDqDlmYaHkw8q9FotqDJF3dCvdJvvyU2NxIeq5/j6zq3jpO + j31RaU/DPYHiSg5kplfdrgkSOZK+K0lTavU+S+ywyshX/2yCVI8nCl9OzuMkEov8bT/m + 43QDejJpL/SmgZRKu+LNQ8zDDpsj1NshF8wDd4xA0IKyL+kagoN5c00qIq3a6sIIrRJ2 + pgcyJ2akaa4WaIZIWOEMgTbYRLKi50FZSaPZWv90+dWNZxqeofPSMfNUkMWaB2FDVP/7 + 34cNkN4DkZW4PAiVWgnCAFOhW+uzvh/bb9ur5uuVgPHZlhSAXK7k6MxSqtGByrv5anj4 + 9AbQ== +X-Gm-Message-State: AOAM533qdoXA7OhRKnodwjuFemgbnuzB6M1Ezj5dK16V2RmuS2yAoxoY + Fh9bBRKH+4RTO9BMpR49AGXz1Asvs5w= +X-Google-Smtp-Source: + ABdhPJybf/XZgZB/Q/5YD/PtnotUkX1ldsL6Uu0I4qModtm+zX/Ggq7KmPlZXxlfNH2FA8a1tV0ngA== +X-Received: by 2002:a17:906:269a:: with SMTP id + t26mr4331783ejc.286.1596205867955; + Fri, 31 Jul 2020 07:31:07 -0700 (PDT) +Received: from blackhead.home ([2a01:112f:a1c:7900:7316:ce1e:7b0b:6bd7]) + by smtp.gmail.com with ESMTPSA id t19sm9749213edw.63.2020.07.31.07.31.05 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 31 Jul 2020 07:31:06 -0700 (PDT) +From: Marcin Sloniewski +To: linux-arm-kernel@lists.infradead.org +Subject: [PATCH v6 1/3] dt-bindings: vendor-prefixes: add Seeed Studio +Date: Fri, 31 Jul 2020 16:30:51 +0200 +Message-Id: <20200731143053.44866-1-marcin.sloniewski@gmail.com> +X-Mailer: git-send-email 2.27.0 +MIME-Version: 1.0 +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200731_103111_656264_F6F92A11 +X-CRM114-Status: GOOD ( 11.66 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, + no trust [2a00:1450:4864:20:0:0:0:641 listed in] + [list.dnswl.org] + 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail + provider [marcin.sloniewski[at]gmail.com] + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain +X-BeenThere: linux-arm-kernel@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: + , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: + , + +Cc: robh@kernel.org, a.fatoum@pengutronix.de, alexandre.torgue@st.com, + stephan@gerhold.net, mani@kernel.org, heiko.stuebner@theobroma-systems.com, + linus.walleij@linaro.org, linux-kernel@vger.kernel.org, lkundrak@v3.sk, + marcin.sloniewski@gmail.com, robh+dt@kernel.org, broonie@kernel.org, + mcoquelin.stm32@gmail.com, allen.chen@ite.com.tw, sam@ravnborg.org, + linux-stm32@st-md-mailman.stormreply.com, devicetree@vger.kernel.org +Sender: "linux-arm-kernel" +Errors-To: + linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org + +Add the "seeed" vendor prefix for Seeed Technology Co., Ltd +Website: https://www.seeedstudio.com/ + +Signed-off-by: Marcin Sloniewski +Acked-by: Rob Herring +--- + Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml +index 9aeab66be85f..7dd03b3e9d3c 100644 +--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml ++++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml +@@ -902,6 +902,8 @@ patternProperties: + description: Schindler + "^seagate,.*": + description: Seagate Technology PLC ++ "^seeed,.*": ++ description: Seeed Technology Co., Ltd + "^seirobotics,.*": + description: Shenzhen SEI Robotics Co., Ltd + "^semtech,.*": diff --git a/board/myna-player-odyssey/rootfs_patches/linux/0002-ARM-dts-stm32-add-initial-support-for-stm32mp157-odyssey-board.patch b/board/myna-player-odyssey/rootfs_patches/linux/0002-ARM-dts-stm32-add-initial-support-for-stm32mp157-odyssey-board.patch new file mode 100644 index 0000000..12ce50e --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/linux/0002-ARM-dts-stm32-add-initial-support-for-stm32mp157-odyssey-board.patch @@ -0,0 +1,592 @@ +From patchwork Fri Jul 31 14:30:53 2020 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Marcin Sloniewski +X-Patchwork-Id: 11695069 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E2F7722 + for ; + Fri, 31 Jul 2020 14:31:41 +0000 (UTC) +Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id CDF28206FA + for ; + Fri, 31 Jul 2020 14:31:40 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="MVrwINxK"; + dkim=fail reason="signature verification failed" (2048-bit key) + header.d=gmail.com header.i=@gmail.com header.b="SZ9oG3H2" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CDF28206FA +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=gmail.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: + Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: + List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: + Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: + Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; + bh=ZqBehaVL3E9eAw7j29eP6hbbkkiJUDH1GEZqX8aJ6vw=; b=MVrwINxKoSfoJJrDJ6zIwcX37 + 1GLYn4tMDueqvtdwAOeCFeZXTUgKsF7XBTM36eEeqZl8DXUb4PcVqIl2uoaar1n07kU7g/XE5Z5Ub + fo1XQ6dROPOsp9Xyow/fq97tjuL4mnlMWy3Rc9a/KRXR/cjl0oVhK2E3KrtQjPDfDZI33QGljUs1l + 8KEu12M3vEcdIhnLMEgeUllRsw8EVOzTHWcRemhwiP0LuU8kNQri8fLuxmLiY7eyaU5HIx0Krxc5N + A39mlWUl9iBrvGgjZp9rGKHZWI8qi3eSRaEatIgFfjq5JLqzaZdAHP9/HnlCKsB6bqYDmrsmjOAp1 + GgcQA+G9A==; +Received: from localhost ([::1] helo=merlin.infradead.org) + by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) + id 1k1W4G-0007yo-4O; Fri, 31 Jul 2020 14:31:28 +0000 +Received: from mail-ed1-x544.google.com ([2a00:1450:4864:20::544]) + by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) + id 1k1W43-0007vl-7u + for linux-arm-kernel@lists.infradead.org; Fri, 31 Jul 2020 14:31:17 +0000 +Received: by mail-ed1-x544.google.com with SMTP id l23so8795737edv.11 + for ; + Fri, 31 Jul 2020 07:31:14 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=from:to:cc:subject:date:message-id:in-reply-to:references + :mime-version:content-transfer-encoding; + bh=gXlatC5AsQuoD+3uBEzYu5ZAaHxOzY+84bpiZ1VQWHU=; + b=SZ9oG3H2bHMpUbOj4x4iCst17tROZ9eCea4P1DW0ECVd1hFkPes3cu0AL/XuSpPGw/ + WkesdNpda3BgS++sJrC7xXCwguI2Td+FW4uoCTNnISb4e493jpVveY05k2AgKffIwpyB + Yjq3WTBKWAXCAS/p8PqSAoqicx7Rd1ixJ9WjnfumkCj7USMzHRjmSvYObi9BFNZmd6vA + 0m8oAlHULlRwp2IpHxJtjZn9FA8CMEl4wxzxKAYMPnvJ+Pxgj+oqUIYNYQ9qQikI5Rwa + 7dJlplf1iCDpK4H3fRXRS2zmnej+aTIx/dBmtmyBrkNEKukxreR/FGM6qALVkNG3s0F5 + wAfQ== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20161025; + h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to + :references:mime-version:content-transfer-encoding; + bh=gXlatC5AsQuoD+3uBEzYu5ZAaHxOzY+84bpiZ1VQWHU=; + b=WBpvi05OfM9vbn8I/rsaI9tdORKkPgIt2QagURBkQuhQUv+MUVYxBn0lQrwLsDupfE + dTd/KSF76FM48hi9Qpw9vWPCCjN3MbbxfCubOfitA6ERYn6UPJz0oKQ/q+R2PxWUe94j + 13v3fBMuk4K/F5OqoP307+3MEm7N+VhBb1SMpb7auCFpW5s/gbyCZgCmqK+nL+2LuH3S + L162gEzFnRnh+cVWTsmQO8ncEk8H1NjpG88bKcChy+l/s8YkUJyy/jrXOMcgKPtCnMMp + nk9E7AzVcCI5q9p48caCM7IyP1PsaIQXzGf4N50iXOtl99bmfT0dMvYoItedjAf3QQgL + 0p3w== +X-Gm-Message-State: AOAM5319nwH6eaYvyTpx6i1M+SMQF/vZWNWeyp+U85+s7yi4S3itOjhy + tg/ktc9PBOlYlDo4U7GSIGyw40qPJ0Q= +X-Google-Smtp-Source: + ABdhPJw0QytN7CLiwpQs2xmXp+75EYfsbHr8vacXofDKzvnNX7QWIqKT/e3FiqX8+/8CLuUUrimiJw== +X-Received: by 2002:a05:6402:1845:: with SMTP id + v5mr4340661edy.66.1596205873413; + Fri, 31 Jul 2020 07:31:13 -0700 (PDT) +Received: from blackhead.home ([2a01:112f:a1c:7900:7316:ce1e:7b0b:6bd7]) + by smtp.gmail.com with ESMTPSA id t19sm9749213edw.63.2020.07.31.07.31.11 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Fri, 31 Jul 2020 07:31:12 -0700 (PDT) +From: Marcin Sloniewski +To: linux-arm-kernel@lists.infradead.org +Subject: [PATCH v6 3/3] ARM: dts: stm32: add initial support for + stm32mp157-odyssey board +Date: Fri, 31 Jul 2020 16:30:53 +0200 +Message-Id: <20200731143053.44866-3-marcin.sloniewski@gmail.com> +X-Mailer: git-send-email 2.27.0 +In-Reply-To: <20200731143053.44866-1-marcin.sloniewski@gmail.com> +References: <20200731143053.44866-1-marcin.sloniewski@gmail.com> +MIME-Version: 1.0 +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20200731_103115_377803_90B11FBF +X-CRM114-Status: GOOD ( 22.84 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, + no trust [2a00:1450:4864:20:0:0:0:544 listed in] + [list.dnswl.org] + 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail + provider [marcin.sloniewski[at]gmail.com] + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain +X-BeenThere: linux-arm-kernel@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: + , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: + , + +Cc: robh@kernel.org, a.fatoum@pengutronix.de, alexandre.torgue@st.com, + stephan@gerhold.net, mani@kernel.org, heiko.stuebner@theobroma-systems.com, + linus.walleij@linaro.org, linux-kernel@vger.kernel.org, lkundrak@v3.sk, + marcin.sloniewski@gmail.com, robh+dt@kernel.org, broonie@kernel.org, + mcoquelin.stm32@gmail.com, allen.chen@ite.com.tw, sam@ravnborg.org, + linux-stm32@st-md-mailman.stormreply.com, devicetree@vger.kernel.org +Sender: "linux-arm-kernel" +Errors-To: + linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org + +Add support for Seeed Studio's stm32mp157c odyssey board. +Board consists of SoM with stm32mp157c with 4GB eMMC and 512 MB DDR3 RAM +and carrier board with USB and ETH interfaces, SD card connector, +wifi and BT chip AP6236. + +In this patch only basic kernel boot is supported and interfacing +SD card and on-board eMMC. + +Signed-off-by: Marcin Sloniewski +--- + +Changes in v6: +- add reset pin for eth phy +- move pinctrl for sdmmc2 to stm32mp15-pinctrl.dtsi + +Changes in v5: +- fix schema for board's dts + +Changes in v4: +- add seeed,stm32mp157c-odyssey-som in compatible + for carrier board +- fix sdmmc2 interface by changing one of the pins + to use +- change eth phy address to 7 + +Changes in v3: +- fix compilation on tip of stm32-next + due to change in names for pinctrl +- fix deprecated binding for led node +- fix redundant "okay" statuses +- add phy part number for eth in comment + +Changes in v2: +- add new odyssey dts to Makefile + + + arch/arm/boot/dts/Makefile | 3 +- + arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 18 ++ + .../arm/boot/dts/stm32mp157c-odyssey-som.dtsi | 276 ++++++++++++++++++ + arch/arm/boot/dts/stm32mp157c-odyssey.dts | 76 +++++ + 4 files changed, 372 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi + create mode 100644 arch/arm/boot/dts/stm32mp157c-odyssey.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index e6a1cac0bfc7..a3ea2301c82c 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1047,7 +1047,8 @@ dtb-$(CONFIG_ARCH_STM32) += \ + stm32mp157c-dk2.dtb \ + stm32mp157c-ed1.dtb \ + stm32mp157c-ev1.dtb \ +- stm32mp157c-lxa-mc1.dtb ++ stm32mp157c-lxa-mc1.dtb \ ++ stm32mp157c-odyssey.dtb + dtb-$(CONFIG_MACH_SUN4I) += \ + sun4i-a10-a1000.dtb \ + sun4i-a10-ba10-tvbox.dtb \ +diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +index b5a66429670c..a47eaecbde42 100644 +--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi ++++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +@@ -1437,6 +1437,24 @@ pins { + }; + }; + ++ sdmmc2_d47_pins_d: sdmmc2-d47-3 { ++ pins { ++ pinmux = , /* SDMMC2_D4 */ ++ , /* SDMMC2_D5 */ ++ , /* SDMMC2_D6 */ ++ ; /* SDMMC2_D7 */ ++ }; ++ }; ++ ++ sdmmc2_d47_sleep_pins_d: sdmmc2-d47-sleep-3 { ++ pins { ++ pinmux = , /* SDMMC2_D4 */ ++ , /* SDMMC2_D5 */ ++ , /* SDMMC2_D6 */ ++ ; /* SDMMC2_D7 */ ++ }; ++ }; ++ + sdmmc3_b4_pins_a: sdmmc3-b4-0 { + pins1 { + pinmux = , /* SDMMC3_D0 */ +diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi +new file mode 100644 +index 000000000000..6cf49a0a9e69 +--- /dev/null ++++ b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi +@@ -0,0 +1,276 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) 2020 Marcin Sloniewski . ++ */ ++ ++/dts-v1/; ++ ++#include "stm32mp157.dtsi" ++#include "stm32mp15xc.dtsi" ++#include "stm32mp15-pinctrl.dtsi" ++#include "stm32mp15xxac-pinctrl.dtsi" ++#include ++#include ++#include ++ ++/ { ++ model = "Seeed Studio Odyssey-STM32MP157C SOM"; ++ compatible = "seeed,stm32mp157c-odyssey-som", "st,stm32mp157"; ++ ++ memory@c0000000 { ++ device_type = "memory"; ++ reg = <0xc0000000 0x20000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ mcuram2: mcuram2@10000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10000000 0x40000>; ++ no-map; ++ }; ++ ++ vdev0vring0: vdev0vring0@10040000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10040000 0x1000>; ++ no-map; ++ }; ++ ++ vdev0vring1: vdev0vring1@10041000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10041000 0x1000>; ++ no-map; ++ }; ++ ++ vdev0buffer: vdev0buffer@10042000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x10042000 0x4000>; ++ no-map; ++ }; ++ ++ mcuram: mcuram@30000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x30000000 0x40000>; ++ no-map; ++ }; ++ ++ retram: retram@38000000 { ++ compatible = "shared-dma-pool"; ++ reg = <0x38000000 0x10000>; ++ no-map; ++ }; ++ ++ gpu_reserved: gpu@d4000000 { ++ reg = <0xd4000000 0x4000000>; ++ no-map; ++ }; ++ }; ++ ++ led { ++ compatible = "gpio-leds"; ++ led-blue { ++ color = ; ++ function = LED_FUNCTION_HEARTBEAT; ++ gpios = <&gpiog 3 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++}; ++ ++&gpu { ++ contiguous-area = <&gpu_reserved>; ++ status = "okay"; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins_a>; ++ i2c-scl-rising-time-ns = <185>; ++ i2c-scl-falling-time-ns = <20>; ++ status = "okay"; ++ /* spare dmas for other usage */ ++ /delete-property/dmas; ++ /delete-property/dma-names; ++ ++ pmic: stpmic@33 { ++ compatible = "st,stpmic1"; ++ reg = <0x33>; ++ interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ regulators { ++ compatible = "st,stpmic1-regulators"; ++ ldo1-supply = <&v3v3>; ++ ldo3-supply = <&vdd_ddr>; ++ ldo6-supply = <&v3v3>; ++ pwr_sw1-supply = <&bst_out>; ++ pwr_sw2-supply = <&bst_out>; ++ ++ vddcore: buck1 { ++ regulator-name = "vddcore"; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_ddr: buck2 { ++ regulator-name = "vdd_ddr"; ++ regulator-min-microvolt = <1350000>; ++ regulator-max-microvolt = <1350000>; ++ regulator-always-on; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ vdd: buck3 { ++ regulator-name = "vdd"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ st,mask-reset; ++ regulator-initial-mode = <0>; ++ regulator-over-current-protection; ++ }; ++ ++ v3v3: buck4 { ++ regulator-name = "v3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ regulator-initial-mode = <0>; ++ }; ++ ++ v1v8_audio: ldo1 { ++ regulator-name = "v1v8_audio"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ interrupts = ; ++ }; ++ ++ v3v3_hdmi: ldo2 { ++ regulator-name = "v3v3_hdmi"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ interrupts = ; ++ }; ++ ++ vtt_ddr: ldo3 { ++ regulator-name = "vtt_ddr"; ++ regulator-min-microvolt = <500000>; ++ regulator-max-microvolt = <750000>; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ vdd_usb: ldo4 { ++ regulator-name = "vdd_usb"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ interrupts = ; ++ }; ++ ++ vdda: ldo5 { ++ regulator-name = "vdda"; ++ regulator-min-microvolt = <2900000>; ++ regulator-max-microvolt = <2900000>; ++ interrupts = ; ++ regulator-boot-on; ++ }; ++ ++ v1v2_hdmi: ldo6 { ++ regulator-name = "v1v2_hdmi"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-always-on; ++ interrupts = ; ++ }; ++ ++ vref_ddr: vref_ddr { ++ regulator-name = "vref_ddr"; ++ regulator-always-on; ++ regulator-over-current-protection; ++ }; ++ ++ bst_out: boost { ++ regulator-name = "bst_out"; ++ interrupts = ; ++ }; ++ ++ vbus_otg: pwr_sw1 { ++ regulator-name = "vbus_otg"; ++ interrupts = ; ++ }; ++ ++ vbus_sw: pwr_sw2 { ++ regulator-name = "vbus_sw"; ++ interrupts = ; ++ regulator-active-discharge; ++ }; ++ }; ++ ++ onkey { ++ compatible = "st,stpmic1-onkey"; ++ interrupts = , ; ++ interrupt-names = "onkey-falling", "onkey-rising"; ++ power-off-time-sec = <10>; ++ }; ++ ++ watchdog { ++ compatible = "st,stpmic1-wdt"; ++ status = "disabled"; ++ }; ++ }; ++}; ++ ++&ipcc { ++ status = "okay"; ++}; ++ ++&iwdg2 { ++ timeout-sec = <32>; ++ status = "okay"; ++}; ++ ++&m4_rproc { ++ memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, ++ <&vdev0vring1>, <&vdev0buffer>; ++ mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; ++ mbox-names = "vq0", "vq1", "shutdown"; ++ interrupt-parent = <&exti>; ++ interrupts = <68 1>; ++ status = "okay"; ++}; ++ ++&rng1 { ++ status = "okay"; ++}; ++ ++&rtc { ++ status = "okay"; ++}; ++ ++&sdmmc2 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_d>; ++ pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_d>; ++ pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_d>; ++ non-removable; ++ no-sd; ++ no-sdio; ++ st,neg-edge; ++ bus-width = <8>; ++ vmmc-supply = <&v3v3>; ++ vqmmc-supply = <&v3v3>; ++ mmc-ddr-3_3v; ++ status = "okay"; ++}; ++ +diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts +new file mode 100644 +index 000000000000..f2ac92f1ad10 +--- /dev/null ++++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts +@@ -0,0 +1,76 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) ++/* ++ * Copyright (C) 2020 Marcin Sloniewski . ++ */ ++ ++/dts-v1/; ++ ++#include "stm32mp157c-odyssey-som.dtsi" ++ ++/ { ++ model = "Seeed Studio Odyssey-STM32MP157C Board"; ++ compatible = "seeed,stm32mp157c-odyssey", ++ "seeed,stm32mp157c-odyssey-som", "st,stm32mp157"; ++ ++ aliases { ++ ethernet0 = ðernet0; ++ serial0 = &uart4; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++}; ++ ++ðernet0 { ++ status = "okay"; ++ pinctrl-0 = <ðernet0_rgmii_pins_a>; ++ pinctrl-1 = <ðernet0_rgmii_sleep_pins_a>; ++ pinctrl-names = "default", "sleep"; ++ phy-mode = "rgmii-id"; ++ max-speed = <1000>; ++ phy-handle = <&phy0>; ++ ++ mdio0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "snps,dwmac-mdio"; ++ phy0: ethernet-phy@7 { /* KSZ9031RN */ ++ reg = <7>; ++ reset-gpios = <&gpiog 0 GPIO_ACTIVE_LOW>; /* ETH_RST# */ ++ reset-assert-us = <10000>; ++ reset-deassert-us = <300>; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default", "sleep"; ++ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-1 = <&i2c1_sleep_pins_a>; ++ i2c-scl-rising-time-ns = <100>; ++ i2c-scl-falling-time-ns = <7>; ++ status = "okay"; ++ /delete-property/dmas; ++ /delete-property/dma-names; ++}; ++ ++&sdmmc1 { ++ pinctrl-names = "default", "opendrain", "sleep"; ++ pinctrl-0 = <&sdmmc1_b4_pins_a>; ++ pinctrl-1 = <&sdmmc1_b4_od_pins_a>; ++ pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; ++ cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; ++ disable-wp; ++ st,neg-edge; ++ bus-width = <4>; ++ vmmc-supply = <&v3v3>; ++ status = "okay"; ++}; ++ ++&uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins_a>; ++ status = "okay"; ++}; ++ diff --git a/board/myna-player-odyssey/rootfs_patches/linux/0003-ARM-dts-stm32mp157c-odyssey-fix-ethernet.patch b/board/myna-player-odyssey/rootfs_patches/linux/0003-ARM-dts-stm32mp157c-odyssey-fix-ethernet.patch new file mode 100644 index 0000000..41621cf --- /dev/null +++ b/board/myna-player-odyssey/rootfs_patches/linux/0003-ARM-dts-stm32mp157c-odyssey-fix-ethernet.patch @@ -0,0 +1,41 @@ +diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +index 2f75b631feac..afeb85ac66ca 100644 +--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi ++++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +@@ -120,8 +120,7 @@ + + ethernet0_rgmii_pins_a: rgmii-0 { + pins1 { +- pinmux = , /* ETH_RGMII_CLK125 */ +- , /* ETH_RGMII_GTX_CLK */ ++ pinmux = , /* ETH_RGMII_GTX_CLK */ + , /* ETH_RGMII_TXD0 */ + , /* ETH_RGMII_TXD1 */ + , /* ETH_RGMII_TXD2 */ +diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts +index f2ac92f1ad10..ac9fa784419d 100644 +--- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts ++++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts +@@ -30,6 +30,22 @@ + phy-mode = "rgmii-id"; + max-speed = <1000>; + phy-handle = <&phy0>; ++ assigned-clocks = <&rcc ETHCK_K>, <&rcc PLL4_P>; ++ assigned-clock-parents = <&rcc PLL4_P>; ++ assigned-clock-rates = <125000000>; ++ st,eth-clk-sel; ++ clock-names = "stmmaceth", ++ "mac-clk-tx", ++ "mac-clk-rx", ++ "eth-ck", ++ "syscfg-clk", ++ "ethstp"; ++ clocks = <&rcc ETHMAC>, ++ <&rcc ETHTX>, ++ <&rcc ETHRX>, ++ <&rcc ETHCK_K>, ++ <&rcc SYSCFG>, ++ <&rcc ETHSTP>; + + mdio0 { + #address-cells = <1>; diff --git a/board/myna-player-odyssey/scripts/initramfs_postbuild.sh b/board/myna-player-odyssey/scripts/initramfs_postbuild.sh deleted file mode 100755 index 9a87431..0000000 --- a/board/myna-player-odyssey/scripts/initramfs_postbuild.sh +++ /dev/null @@ -1,259 +0,0 @@ -#!/bin/sh - -unlink "${TARGET_DIR}"/usr/lib/systemd/system/default.target -unlink "${TARGET_DIR}"/etc/systemd/system/default.target -ln -srf "${TARGET_DIR}"/usr/lib/systemd/system/initrd.target \ - "${TARGET_DIR}"/usr/lib/systemd/system/default.target -ln -srf "${TARGET_DIR}"/lib/systemd/systemd \ - "${TARGET_DIR}"/init - -dbus-uuidgen > "${BR2_EXTERNAL_MynaPlayer_PATH}"/board/myna-player-odyssey/utilities/machine-id -cp "${BR2_EXTERNAL_MynaPlayer_PATH}"/board/myna-player-odyssey/utilities/machine-id \ -"${TARGET_DIR}"/etc/machine-id - -# lets point emergency.target to reboot.target - -rm "${TARGET_DIR}"/usr/lib/systemd/system/emergency.target -ln -sr "${TARGET_DIR}"/usr/lib/systemd/system/reboot.target "${TARGET_DIR}"/usr/lib/systemd/system/emergency.target - -# lets clean up the initramfs - -cleanup() { find "${CLEANUP_DIR}" -depth -name "$1" -exec rm -rv "{}" \; ; } -CLEANUP_DIR="${TARGET_DIR}/usr/bin" -cleanup attr -cleanup busctl -cleanup chacl -cleanup choom -cleanup col -cleanup colcrt -cleanup colrm -cleanup column -cleanup dbus-* -cleanup dmesg -cleanup fincore -cleanup findmnt -cleanup flock -cleanup getfacl -cleanup getfattr -cleanup ipcmk -cleanup isosize -cleanup kernel-install -cleanup kmod -cleanup ldd -cleanup look -cleanup lsblk -cleanup lscpu -cleanup lsipc -cleanup lslocks -cleanup lsns -cleanup mcookie -cleanup namei -cleanup portablectl -cleanup prlimit -cleanup renice -cleanup rev -cleanup script -cleanup scriptlive -cleanup scriptreplay -cleanup setarch -cleanup setfacl -cleanup setsid -cleanup systemd-analyze -cleanup systemd-ask-password -cleanup systemd-cat -cleanup systemd-cgls -cleanup systemd-cgtop -cleanup systemd-delta -cleanup systemd-detect-virt -cleanup systemd-escape -cleanup systemd-id128 -cleanup systemd-machine-id-setup -cleanup systemd-mount -cleanup systemd-notify -cleanup systemd-nspawn -cleanup systemd-path -cleanup systemd-run -cleanup systemd-socket-activate -cleanup systemd-stdio-bridge -cleanup systemd-tty-ask-password-agent -cleanup systemd-umount -cleanup uuidgen -cleanup uuidparse -cleanup whereis -cleanup xmlwf - -CLEANUP_DIR="${TARGET_DIR}/usr/sbin" -cleanup depmod -cleanup fdisk -cleanup findfs -cleanup insmod -cleanup ldattach -cleanup lsmod -cleanup mkswap -cleanup modinfo -cleanup modprobe -cleanup readprofile -cleanup rmmod -cleanup rtcwake -cleanup sfdisk -cleanup swaplabel -cleanup swapoff -cleanup swapon - -CLEANUP_DIR="${TARGET_DIR}/usr/lib/systemd/system" -cleanup multi-user.target.wants -cleanup local-fs.target.wants -cleanup timers.target.wants -cleanup rescue.target.wants -cleanup graphical.target.wants -cleanup "runlevel*.target.wants" -cleanup systemd-ask-password-console.path -cleanup systemd-journal-catalog-update.service -cleanup systemd-journal-flush.service -cleanup systemd-machine-id-commit.service -cleanup systemd-sysctl.service -cleanup systemd-tmpfiles-setup.service -cleanup systemd-update-done.service -cleanup systemd-update-utmp.service -cleanup "*.mount" -cleanup dbus.socket -cleanup systemd-initctl.socket -cleanup "user*" -cleanup systemd-user-sessions.service -cleanup system-update-cleanup.service -cleanup system-update-pre.target -cleanup system-update.target -cleanup time-set.target -cleanup time-sync.target -cleanup systemd-vconsole-setup.service -cleanup systemd-update-done.service -cleanup systemd-update-utmp-runlevel.service -cleanup systemd-update-utmp.service -cleanup systemd-udev-settle.service -cleanup systemd-tmpfiles-setup.service -cleanup systemd-remount-fs.service -cleanup systemd-suspend.service -cleanup systemd-sysctl.service -cleanup systemd-tmpfiles-clean.service -cleanup systemd-tmpfiles-clean.timer -cleanup systemd-nspawn@.service -cleanup systemd-portabled.service -cleanup systemd-poweroff.service -cleanup systemd-pstore.service -cleanup systemd-journal-flush.service -cleanup systemd-kexec.service -cleanup systemd-machine-id-commit.service -cleanup systemd-halt.service -cleanup systemd-initctl.service -cleanup systemd-initctl.socket -cleanup systemd-journal-catalog-update.service -cleanup systemd-exit.service -cleanup systemd-ask-password-console.path -cleanup systemd-ask-password-console.service -cleanup systemd-ask-password-wall.path -cleanup systemd-ask-password-wall.service -cleanup systemd-boot-check-no-failures.service -cleanup syslog.socket -cleanup sound.target -cleanup suspend.target -cleanup smartcard.target -cleanup sigpwr.target -cleanup sleep.target -cleanup "runlevel*.target" -cleanup rpcbind.target -cleanup remote-fs-pre.target -cleanup remote-fs.target -cleanup multi-user.target -cleanup network-online.target -cleanup network-pre.target -cleanup network.target -cleanup nss-lookup.target -cleanup nss-user-lookup.target -cleanup poweroff.target -cleanup printer.target -cleanup rc-local.service -cleanup kexec.target -cleanup graphical.target -cleanup halt.target -cleanup exit.target -cleanup dbus-org.freedesktop.portable1.service -cleanup dbus.service -cleanup debug-shell.service -cleanup bluetooth.target -cleanup boot-complete.target -cleanup console-getty.service -cleanup container-getty@.service -cleanup autovt@.service - -CLEANUP_DIR="${TARGET_DIR}/usr/lib/systemd" -cleanup "*user*" -cleanup system-preset -cleanup system-shutdown -cleanup system-sleep -cleanup systemd-update-done -cleanup systemd-update-utmp -cleanup systemd-sleep -cleanup systemd-socket-proxyd -cleanup systemd-portabled -cleanup systemd-pstore -cleanup systemd-remount-fs -cleanup systemd-reply-password -cleanup systemd-makefs -cleanup systemd-growfs -cleanup systemd-initctl -cleanup systemd-ac-power -cleanup systemd-boot-check-no-failures -cleanup systemd-cgroups-agent -cleanup systemd-dissect -cleanup network -cleanup portable -cleanup catalog - -CLEANUP_DIR="${TARGET_DIR}/usr/lib" -cleanup tmpfiles.d -cleanup modules-load.d -cleanup sysusers.d -cleanup rpm -cleanup security -cleanup sysctl.d - -CLEANUP_DIR="${TARGET_DIR}/etc" -cleanup dbus-1 -cleanup environment -cleanup init.d -cleanup kernel -cleanup network -cleanup os-release -cleanup pam.d -cleanup profile -cleanup profile.d -cleanup protocols -cleanup resolv.conf -cleanup security -cleanup services -cleanup shells -cleanup sysctl.d -cleanup timezone -cleanup tmpfiles.d -cleanup udev -cleanup X11 -cleanup xattr.conf -cleanup xdg - -CLEANUP_DIR="${TARGET_DIR}/etc/systemd" -cleanup *.conf -cleanup user -cleanup tmpfiles.d - -CLEANUP_DIR="${TARGET_DIR}/etc/systemd/system" -cleanup boot-complete.target.requires -cleanup ctrl-alt-del.target -cleanup default.target -cleanup multi-user.target.wants -cleanup network.service -cleanup systemd-remount-fs.service.wants - -# Moving kernel modules to a well known location - -mkdir -p "${BASE_DIR}"/../kmod -mv "${TARGET_DIR}"/usr/lib/modules "${BASE_DIR}"/../kmod/modules ||true diff --git a/board/myna-player-odyssey/scripts/initramfs_postimage.sh b/board/myna-player-odyssey/scripts/initramfs_postimage.sh deleted file mode 100755 index 5d6d527..0000000 --- a/board/myna-player-odyssey/scripts/initramfs_postimage.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# copy kernel, bootloader and device tree to a well known location - -mkdir -p "${BASE_DIR}"/../kernel -cp -a "${BINARIES_DIR}"/zImage \ - "${BINARIES_DIR}"/stm32mp157c-odyssey.dtb \ - "${BINARIES_DIR}"/barebox.bin \ - "${BASE_DIR}"/../kernel diff --git a/board/myna-player-odyssey/scripts/rootfs_postbuild.sh b/board/myna-player-odyssey/scripts/rootfs_postbuild.sh index dccf42b..1df1054 100755 --- a/board/myna-player-odyssey/scripts/rootfs_postbuild.sh +++ b/board/myna-player-odyssey/scripts/rootfs_postbuild.sh @@ -4,16 +4,6 @@ . "${BR2_EXTERNAL_MynaPlayer_PATH}"/scripts/certs.sh -# copy machine-id into the target - -cp "${BR2_EXTERNAL_MynaPlayer_PATH}"/board/myna-player-odyssey/utilities/machine-id \ - "${TARGET_DIR}"/etc/machine-id - -# Moving kernel modules into place - -rsync -ar "${BASE_DIR}"/../kmod/modules/* \ - "${TARGET_DIR}"/usr/lib/modules - # lets point emergency.target to reboot.target rm "${TARGET_DIR}"/usr/lib/systemd/system/emergency.target @@ -25,13 +15,6 @@ cp "${BR2_EXTERNAL_MynaPlayer_PATH}"/changelog.md \ "${TARGET_DIR}"/etc/changelog.md -# copy the kernel and device tree - -mkdir -p "${TARGET_DIR}"/boot -cp -a "${BASE_DIR}"/../kernel/stm32mp157c-odyssey.dtb \ - "${BASE_DIR}"/../kernel/zImage \ - "${TARGET_DIR}"/boot - # grab keyring needed for rauc cp "${BR2_EXTERNAL_MynaPlayer_PATH}"/certs/keyring.pem \ diff --git a/board/myna-player-odyssey/scripts/rootfs_postimage.sh b/board/myna-player-odyssey/scripts/rootfs_postimage.sh index 151837a..ab994de 100755 --- a/board/myna-player-odyssey/scripts/rootfs_postimage.sh +++ b/board/myna-player-odyssey/scripts/rootfs_postimage.sh @@ -2,11 +2,6 @@ set -e -# copy bootloader - -cp "${BASE_DIR}"/../kernel/barebox.bin \ - "${BINARIES_DIR}"/barebox.bin - # create filesystem for rauc slot status fallocate -l 2m "${BINARIES_DIR}/rauc.ext4" diff --git a/board/myna-player-odyssey/utilities/device-table b/board/myna-player-odyssey/utilities/device-table deleted file mode 100644 index 7fddade..0000000 --- a/board/myna-player-odyssey/utilities/device-table +++ /dev/null @@ -1 +0,0 @@ -/etc/machine-id f 444 root root - - - - - diff --git a/configs/myna_player_odyssey_defconfig b/configs/myna_player_odyssey_defconfig index e547f70..25685ee 100644 --- a/configs/myna_player_odyssey_defconfig +++ b/configs/myna_player_odyssey_defconfig @@ -16,8 +16,6 @@ BR2_TARGET_GENERIC_HOSTNAME="MynaPlayer" BR2_TARGET_GENERIC_ISSUE="Welcome to MynaPlayer" BR2_INIT_SYSTEMD=y -BR2_ROOTFS_DEVICE_TABLE="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/utilities/device-table" -BR2_ROOTFS_DEVICE_TABLE_SUPPORTS_EXTENDED_ATTRIBUTES=y BR2_SYSTEM_BIN_SH_BASH=y # BR2_TARGET_GENERIC_GETTY is not set # BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set @@ -26,6 +24,17 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/scripts/rootfs_postbuild.sh" BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/scripts/rootfs_postimage.sh support/scripts/genimage.sh" BR2_ROOTFS_POST_SCRIPT_ARGS="-c $(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/utilities/genimage.cfg" +BR2_LINUX_KERNEL=y +BR2_LINUX_KERNEL_CUSTOM_VERSION=y +BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.8" +BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y +BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/configs/linux.config" +BR2_LINUX_KERNEL_LZ4=y +BR2_LINUX_KERNEL_DTS_SUPPORT=y +BR2_LINUX_KERNEL_INTREE_DTS_NAME="stm32mp157c-odyssey" +BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT=y +BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y +BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y # BR2_PACKAGE_BUSYBOX is not set BR2_PACKAGE_XZ=y BR2_PACKAGE_ZIP=y @@ -98,6 +107,19 @@ BR2_TARGET_ROOTFS_EXT2_4=y BR2_TARGET_ROOTFS_EXT2_SIZE="512M" BR2_TARGET_ROOTFS_TAR_XZ=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y +BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.2" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="stm32mp1" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="ENABLE_STACK_PROTECTOR=strong STM32MP_EMMC=1 STM32MP_MMC=1 AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-dk2.dtb" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="*.stm32" +BR2_TARGET_ARM_TRUSTED_FIRMWARE_NEEDS_DTC=y +BR2_TARGET_BAREBOX=y +BR2_TARGET_BAREBOX_CUSTOM_GIT=y +BR2_TARGET_BAREBOX_CUSTOM_GIT_REPO_URL="https://git.pengutronix.de/cgit/barebox" +BR2_TARGET_BAREBOX_CUSTOM_GIT_VERSION="d4d3e9c87" +BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG=y +BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/configs/barebox.config" BR2_PACKAGE_HOST_GENIMAGE=y BR2_PACKAGE_HOST_RAUC=y BR2_PACKAGE_DISABLED_SERVICES=y diff --git a/configs/myna_player_odyssey_initramfs_defconfig b/configs/myna_player_odyssey_initramfs_defconfig deleted file mode 100644 index 24fdede..0000000 --- a/configs/myna_player_odyssey_initramfs_defconfig +++ /dev/null @@ -1,65 +0,0 @@ -BR2_arm=y -BR2_cortex_a7=y -BR2_CCACHE=y -BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/initramfs_patches" -BR2_PER_PACKAGE_DIRECTORIES=y -BR2_SSP_ALL=y -BR2_RELRO_FULL=y -BR2_FORTIFY_SOURCE_1=y -BR2_TOOLCHAIN_EXTERNAL=y -BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y -BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y -BR2_TOOLCHAIN_EXTERNAL_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--glibc--bleeding-edge-2020.02-2.tar.bz2" -BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_19=y -BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y -BR2_TOOLCHAIN_EXTERNAL_CXX=y -BR2_INIT_SYSTEMD=y -BR2_ROOTFS_DEVICE_TABLE="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/utilities/device-table" -BR2_ROOTFS_DEVICE_TABLE_SUPPORTS_EXTENDED_ATTRIBUTES=y -# BR2_TARGET_ENABLE_ROOT_LOGIN is not set -# BR2_TARGET_GENERIC_GETTY is not set -# BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set -BR2_ENABLE_LOCALE_WHITELIST="en_US.UTF-8" -BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/initramfs_overlay" -BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/scripts/initramfs_postbuild.sh" -BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/scripts/initramfs_postimage.sh" -BR2_LINUX_KERNEL=y -BR2_LINUX_KERNEL_CUSTOM_VERSION=y -BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.8" -BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y -BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/configs/linux.config" -BR2_LINUX_KERNEL_LZ4=y -BR2_LINUX_KERNEL_DTS_SUPPORT=y -BR2_LINUX_KERNEL_INTREE_DTS_NAME="stm32mp157c-odyssey" -BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT=y -BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y -BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y -BR2_PACKAGE_BUSYBOX_CONFIG="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/configs/busybox.config" -BR2_PACKAGE_ACL=y -# BR2_PACKAGE_SYSTEMD_HOSTNAMED is not set -# BR2_PACKAGE_SYSTEMD_HWDB is not set -# BR2_PACKAGE_SYSTEMD_MYHOSTNAME is not set -# BR2_PACKAGE_SYSTEMD_NETWORKD is not set -BR2_PACKAGE_SYSTEMD_REPART=y -# BR2_PACKAGE_SYSTEMD_RESOLVED is not set -# BR2_PACKAGE_SYSTEMD_TIMEDATED is not set -# BR2_PACKAGE_SYSTEMD_TIMESYNCD is not set -BR2_PACKAGE_SYSTEMD_BOOTCHART=y -BR2_PACKAGE_UTIL_LINUX_SULOGIN=y -BR2_TARGET_ROOTFS_INITRAMFS=y -# BR2_TARGET_ROOTFS_TAR is not set -BR2_TARGET_ARM_TRUSTED_FIRMWARE=y -BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION=y -BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_VERSION_VALUE="v2.2" -BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="stm32mp1" -BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="ENABLE_STACK_PROTECTOR=strong STM32MP_EMMC=1 STM32MP_MMC=1 AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-dk2.dtb" -BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="*.stm32" -BR2_TARGET_ARM_TRUSTED_FIRMWARE_NEEDS_DTC=y -BR2_TARGET_BAREBOX=y -BR2_TARGET_BAREBOX_CUSTOM_GIT=y -BR2_TARGET_BAREBOX_CUSTOM_GIT_REPO_URL="https://git.pengutronix.de/cgit/barebox" -BR2_TARGET_BAREBOX_CUSTOM_GIT_VERSION="d4d3e9c87" -BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG=y -BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MynaPlayer_PATH)/board/myna-player-odyssey/configs/barebox.config" -BR2_PACKAGE_HOST_GENIMAGE=y -BR2_PACKAGE_DISABLED_SERVICES=y