diff --git a/README.md b/README.md index e54ff0d52..5b14c57aa 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Digi Embedded Yocto (DEY) 4.0 -## Release 4.0-r6 +## Release 4.0-r7 This document provides information about Digi Embedded Yocto, Digi International's professional embedded Yocto development environment. @@ -21,6 +21,18 @@ OS versions: Software for the following hardware platforms is in production support: +## ConnectCore MP25 +* ConnectCore MP25 System-on-Module (SOM) + * [CC-WST-J17D-NK](https://www.digi.com/products/models/cc-wst-j17d-nk) + * [CC-ST-J17D-ZK](https://www.digi.com/products/models/cc-st-j17d-zk) +* ConnectCore MP25 Development Kit (DVK) + * [CC-WMP255-KIT](https://www.digi.com/products/models/cc-wmp255-kit) ([Get Started](https://www.digi.com/resources/documentation/digidocs/embedded/dey/4.0/ccmp25/yocto-gs_index)) + +## ConnectCore 91 +* ConnectCore 91 System-on-Module (SOM) + * [CC-WMX-F26D-L1](https://www.digi.com/products/models/cc-wmx-f26d-l1) + * [CC-MX-F26D-Z1](https://www.digi.com/products/models/cc-mx-f26d-z1) + ## ConnectCore 93 * ConnectCore 93 System-on-Module (SOM) * [CC-WMX-YC7D-KN](https://www.digi.com/products/models/cc-wmx-yc7d-kn) @@ -125,11 +137,31 @@ Documentation is available online at https://www.digi.com/resources/documentatio # Downloads -* Demo images: https://ftp1.digi.com/support/digiembeddedyocto/4.0/r6/images/ -* Software Development Kit (SDK): https://ftp1.digi.com/support/digiembeddedyocto/4.0/r6/sdk/ +* Demo images: https://ftp1.digi.com/support/digiembeddedyocto/4.0/r7/images/ +* Software Development Kit (SDK): https://ftp1.digi.com/support/digiembeddedyocto/4.0/r7/sdk/ # Release Changelog +## 4.0-r7 + +* ST-based platforms + * Added support to ConnectCore MP25 + * Trusted Firmware ARM v2.8 (based on tag 'v2.8-stm32mp25-beta-r2' by ST) + * OP-TEE v3.19.0 (based on tag '3.19.0-stm32mp25-beta-r1' by ST) + * U-Boot v2022.10 (based on tag 'v2020.10-stm32mp25-beta-r1' by ST) + * Linux kernel v6.1.28 (based on tag 'stm32mp25-beta-r1' by ST) + * Added support to create signed SDcard image for ConnectCore MP15/MP13 + * Added support to program and use hardware unique key (HUK) on OTP bits as derivative for encryption key on ConnectCore MP15 + * Enable spread-spectrum on PLL2 to mitigate emission on 533MHz frequency on ConnectCore MP15 +* NXP-based platforms + * Added support to ConnectCore 91 + * U-Boot v2024.04 + * Linux kernel v6.6.23 (based on tag 'lf-6.6.23-2.0.0' by NXP) +* Improved SWU package generation and support: + * Added software update (SWU) authentication when Trustfence is enabled +* Added support to fix Y2K38 problem on 32-bit platforms +* General bug fixing and improvements + ## 4.0-r6 * ST-based platforms @@ -311,6 +343,14 @@ updated list can be found on the online documentation. devices (ConnectCore 6UL, ConnectCore 6 Plus, and ConnectCore 8M Nano) fail to join autonomous groups. +## ConnectCore MP25 + +* ConnectCore MP2 System-on-Module (SOM) + * Power management + * Power management support is not yet implemented. + * Firmware update + * Update single file and update with rdiff don't currently work. + ## ConnectCore MP15/MP13 * ConnectCore MP1 System-on-Module (SOM) diff --git a/meta-digi-arm/classes/fip-utils-stm32mp2.bbclass b/meta-digi-arm/classes/fip-utils-stm32mp2.bbclass new file mode 100644 index 000000000..e27d65479 --- /dev/null +++ b/meta-digi-arm/classes/fip-utils-stm32mp2.bbclass @@ -0,0 +1,567 @@ +inherit sign-stm32mp2 + +DEPENDS += "tf-a-tools-native util-linux-native" + +# Configure new package to provide fiptool wrapper for SDK usage +PACKAGES =+ "${FIPTOOL_WRAPPER}" + +BBCLASSEXTEND:append = " nativesdk" + +RRECOMMENDS:${FIPTOOL_WRAPPER}:append:class-nativesdk = " nativesdk-tf-a-tools" + +# Define default TF-A FIP namings +FIP_BASENAME ?= "fip" +FIP_SUFFIX ?= "bin" + +# Set default TF-A FIP config +FIP_CONFIG ?= "" + +# Default FIP config: +# There are two options implemented to select two different firmware and each +# FIP_CONFIG should configure one: 'tfa' or 'optee' +FIP_CONFIG_FW_TFA = "tfa" +FIP_CONFIG_FW_TEE = "optee" + +# Init BL31 config +FIP_BL31_ENABLE ?= "" + +# Set CERTTOOL binary name to use +CERTTOOL ?= "cert_create" +# Set ENCTOOL binary name to use +ENCTOOL ?= "encrypt_fw" +# Set FIPTOOL binary name to use +FIPTOOL ?= "fiptool" +# Set STM32MP fiptool wrapper +FIPTOOL_WRAPPER ?= "fiptool-stm32mp" + +# Default FIP file names and suffixes +FIP_BL31 ?= "tf-a-bl31" +FIP_BL31_SUFFIX ?= "bin" +FIP_BL31_DTB ?= "bl31" +FIP_BL31_DTB_SUFFIX ?= "dtb" +FIP_TFA ?= "tf-a-bl32" +FIP_TFA_SUFFIX ?= "bin" +FIP_TFA_DTB ?= "bl32" +FIP_TFA_DTB_SUFFIX ?= "dtb" +FIP_FW_CONFIG ?= "fw-config" +FIP_FW_CONFIG_SUFFIX ?= "dtb" +FIP_FW_DDR ?= "ddr_pmu" +FIP_FW_DDR_SUFFIX ?= "bin" +FIP_OPTEE_HEADER ?= "tee-header_v2" +FIP_OPTEE_PAGER ?= "tee-pager_v2" +FIP_OPTEE_PAGEABLE ?= "tee-pageable_v2" +FIP_OPTEE_SUFFIX ?= "bin" +FIP_UBOOT ?= "u-boot-nodtb" +FIP_UBOOT_SUFFIX ?= "bin" +FIP_UBOOT_DTB ?= "u-boot" +FIP_UBOOT_DTB_SUFFIX ?= "dtb" + +# Configure default folder path for binaries to package +FIP_DEPLOYDIR_FIP ?= "${DEPLOYDIR}/fip" +FIP_DEPLOYDIR_BL31 ?= "${DEPLOYDIR}/arm-trusted-firmware/bl31" +FIP_DEPLOYDIR_TFA ?= "${DEPLOYDIR}/arm-trusted-firmware/bl32" +FIP_DEPLOYDIR_FWCONF ?= "${DEPLOYDIR}/arm-trusted-firmware/fwconfig" +FIP_DEPLOYDIR_FWDDR ?= "${DEPLOYDIR}/arm-trusted-firmware/ddr" +FIP_DEPLOYDIR_OPTEE ?= "${DEPLOY_DIR}/images/${MACHINE}/optee" +FIP_DEPLOYDIR_UBOOT ?= "${DEPLOY_DIR}/images/${MACHINE}/u-boot" + +# Set default configuration to allow FIP signing +FIP_ENCRYPT_SUFFIX ??= "${@bb.utils.contains('ENCRYPT_ENABLE', '1', '${ENCRYPT_SUFFIX}', '', d)}" +FIP_ENCRYPT_NONCE ??= "1234567890abcdef12345678" +FIP_SIGN_SUFFIX ??= "${@bb.utils.contains('SIGN_ENABLE', '1', '${SIGN_SUFFIX}', '', d)}" + +# Define FIP dependency build +FIP_DEPENDS += "virtual/bootloader" +FIP_DEPENDS += "${@bb.utils.contains('MACHINE_FEATURES', 'optee', 'virtual/optee-os', '', d)}" +FIP_DEPENDS:class-nativesdk = "" + +# ----------------------------------------------- +# Handle FIP config and set internal vars +# FIP_BL32_CONF +python () { + import re + + # Make sure that deploy class is configured + if not bb.data.inherits_class('deploy', d): + bb.fatal("The st-fip-utils class needs the deploy class to be configured on recipe side.") + + # Manage FIP binary dependencies + fip_depends = (d.getVar('FIP_DEPENDS') or "").split() + if len(fip_depends) > 0: + for depend in fip_depends: + d.appendVarFlag('do_deploy', 'depends', ' %s:do_deploy' % depend) + + # Manage FIP config settings + fipconfigflags = d.getVarFlags('FIP_CONFIG') + if fipconfigflags is not None: + # The "doc" varflag is special, we don't want to see it here + fipconfigflags.pop('doc', None) + fipconfig = (d.getVar('FIP_CONFIG') or "").split() + if not fipconfig: + raise bb.parse.SkipRecipe("FIP_CONFIG must be set in the %s machine configuration." % d.getVar("MACHINE")) + if (d.getVar('FIP_BL32_CONF') or "").split(): + raise bb.parse.SkipRecipe("You cannot use FIP_BL32_CONF as it is internal to FIP_CONFIG var expansion.") + if (d.getVar('FIP_DEVICETREE') or "").split(): + raise bb.parse.SkipRecipe("You cannot use FIP_DEVICETREE as it is internal to FIP_CONFIG var expansion.") + if len(fipconfig) > 0: + # Init internal fip firmware config + fip_config_fw_tfa = d.getVar('FIP_CONFIG_FW_TFA') or "" + fip_config_fw_tee = d.getVar('FIP_CONFIG_FW_TEE') or "" + for config in fipconfig: + for f, v in fipconfigflags.items(): + if config == f: + # Make sure to get var flag properly expanded + v = d.getVarFlag('FIP_CONFIG', config) + if not v.strip(): + bb.fatal('[FIP_CONFIG] Missing configuration for %s config' % config) + items = v.split(',') + if items[0] and len(items) > 2: + raise bb.parse.SkipRecipe('Only and can be specified!') + # Set internal vars + if items[0] == fip_config_fw_tfa or items[0] == fip_config_fw_tee: + bb.debug(1, "Appending '%s' to FIP_BL32_CONF" % items[0]) + d.appendVar('FIP_BL32_CONF', items[0] + ',') + else: + bb.fatal('[FIP_CONFIG] Wrong configuration for %s config: %s should be one of %s or %s' % (config,items[0],fip_config_fw_tfa,fip_config_fw_tee)) + bb.debug(1, "Appending '%s' to FIP_DEVICETREE" % items[1]) + d.appendVar('FIP_DEVICETREE', items[1] + ',') + break +} + +# Deploy the fip binary for current target +do_deploy:append:class-target() { + install -d ${DEPLOYDIR} + install -d ${FIP_DEPLOYDIR_FIP} + + unset i + for config in ${FIP_CONFIG}; do + i=$(expr $i + 1) + bl32_conf=$(echo ${FIP_BL32_CONF} | cut -d',' -f${i}) + dt_config=$(echo ${FIP_DEVICETREE} | cut -d',' -f${i}) + for dt in ${dt_config}; do + # Init soc suffix + soc_suffix="" + if [ -n "${STM32MP_SOC_NAME}" ]; then + for soc in ${STM32MP_SOC_NAME}; do + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && soc_suffix="-${soc}" + done + fi + # Init FIP fw-config settings + [ -f "${FIP_DEPLOYDIR_FWCONF}/${dt}-${FIP_FW_CONFIG}-${config}.${FIP_FW_CONFIG_SUFFIX}" ] || bbfatal "Missing ${dt}-${FIP_FW_CONFIG}-${config}.${FIP_FW_CONFIG_SUFFIX} file in folder: ${FIP_DEPLOYDIR_FWCONF}" + FIP_FWCONFIG="--fw-config ${FIP_DEPLOYDIR_FWCONF}/${dt}-${FIP_FW_CONFIG}-${config}.${FIP_FW_CONFIG_SUFFIX}" + # Init FIP hw-config settings + [ -f "${FIP_DEPLOYDIR_UBOOT}/${FIP_UBOOT_DTB}-${dt}.${FIP_UBOOT_DTB_SUFFIX}" ] || bbfatal "Missing ${FIP_UBOOT_DTB}-${dt}.${FIP_UBOOT_DTB_SUFFIX} file in folder: ${FIP_DEPLOYDIR_UBOOT}" + FIP_HWCONFIG="--hw-config ${FIP_DEPLOYDIR_UBOOT}/${FIP_UBOOT_DTB}-${dt}.${FIP_UBOOT_DTB_SUFFIX}" + # Init FIP nt-fw config + [ -f "${FIP_DEPLOYDIR_UBOOT}/${FIP_UBOOT}${soc_suffix}.${FIP_UBOOT_SUFFIX}" ] || bbfatal "Missing ${FIP_UBOOT}${soc_suffix}.${FIP_UBOOT_SUFFIX} file in folder: ${FIP_DEPLOYDIR_UBOOT}" + FIP_NTFW="--nt-fw ${FIP_DEPLOYDIR_UBOOT}/${FIP_UBOOT}${soc_suffix}.${FIP_UBOOT_SUFFIX}" + # Init FIP bl31 settings + if [ "${FIP_BL31_ENABLE}" = "1" ]; then + # Check for files + [ -f "${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}.${FIP_BL31_SUFFIX}" ] || bbfatal "Missing ${FIP_BL31}${soc_suffix}.${FIP_BL31_SUFFIX} file in folder: ${FIP_DEPLOYDIR_BL31}" + [ -f "${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX}" ] || bbfatal "Missing ${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX} file in folder: ${FIP_DEPLOYDIR_BL31}" + # Set CERT_BL31CONF + CERT_BL31CONF=" \ + --soc-fw ${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}.${FIP_BL31_SUFFIX} \ + --soc-fw-config ${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX} \ + " + if [ "${ENCRYPT_ENABLE}" = "1" ]; then + encrypt_key="${ENCRYPT_FIP_KEY_PATH_LIST}" + if [ -n "${STM32MP_ENCRYPT_SOC_NAME}" ]; then + unset k + for soc in ${STM32MP_ENCRYPT_SOC_NAME}; do + k=$(expr $k + 1) + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && encrypt_key=$(echo ${ENCRYPT_FIP_KEY_PATH_LIST} | cut -d',' -f${k}) + done + fi + encrypt_key="$(hexdump -e '/1 "%02x"' ${encrypt_key})" + + # encrypt bl31 binary + bbnote "${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in \"${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}.${FIP_BL31_SUFFIX}\" \ + --out \"${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}${FIP_ENCRYPT_SUFFIX}.${FIP_BL31_SUFFIX}\" " + ${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in "${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}.${FIP_BL31_SUFFIX}" \ + --out "${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}${FIP_ENCRYPT_SUFFIX}.${FIP_BL31_SUFFIX}" + # encrypt bl31 devicetree + bbnote "${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in \"${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX}\" \ + --out \"${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}${FIP_ENCRYPT_SUFFIX}.${FIP_BL31_DTB_SUFFIX} \" " + ${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in "${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX}" \ + --out "${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}${FIP_ENCRYPT_SUFFIX}.${FIP_BL31_DTB_SUFFIX}" + fi + # Set FIP_BL31CONF + FIP_BL31CONF="\ + --soc-fw ${FIP_DEPLOYDIR_BL31}/${FIP_BL31}${soc_suffix}${FIP_ENCRYPT_SUFFIX}.${FIP_BL31_SUFFIX} \ + --soc-fw-config ${FIP_DEPLOYDIR_BL31}/${dt}-${FIP_BL31_DTB}${FIP_ENCRYPT_SUFFIX}.${FIP_BL31_DTB_SUFFIX} \ + " + else + CERT_BL31CONF="" + FIP_BL31CONF="" + fi + # Init FIP extra conf settings + if [ "${bl32_conf}" = "${FIP_CONFIG_FW_TFA}" ]; then + # Check for files + [ -f "${FIP_DEPLOYDIR_TFA}/${FIP_TFA}${soc_suffix}.${FIP_TFA_SUFFIX}" ] || bbfatal "Missing ${FIP_TFA}${soc_suffix}.${FIP_TFA_SUFFIX} file in folder: ${FIP_DEPLOYDIR_TFA}" + [ -f "${FIP_DEPLOYDIR_TFA}/${dt}-${FIP_TFA_DTB}.${FIP_TFA_DTB_SUFFIX}" ] || bbfatal "Missing ${dt}-${FIP_TFA_DTB}.${FIP_TFA_DTB_SUFFIX} file in folder: ${FIP_DEPLOYDIR_TFA}" + # Set FIP_EXTRACONF + FIP_EXTRACONF="\ + --tos-fw ${FIP_DEPLOYDIR_TFA}/${FIP_TFA}${soc_suffix}.${FIP_TFA_SUFFIX} \ + --tos-fw-config ${FIP_DEPLOYDIR_TFA}/${dt}-${FIP_TFA_DTB}.${FIP_TFA_DTB_SUFFIX} \ + " + elif [ "${bl32_conf}" = "${FIP_CONFIG_FW_TEE}" ]; then + # Check for files + [ -f "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}.${FIP_OPTEE_SUFFIX}" ] || bbfatal "Missing ${FIP_OPTEE_HEADER}-${dt}.${FIP_OPTEE_SUFFIX} file in folder: ${FIP_DEPLOYDIR_OPTEE}" + [ -f "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}.${FIP_OPTEE_SUFFIX}" ] || bbfatal "Missing ${FIP_OPTEE_PAGER}-${dt}.${FIP_OPTEE_SUFFIX} file in folder: ${FIP_DEPLOYDIR_OPTEE}" + [ -f "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}.${FIP_OPTEE_SUFFIX}" ] || bbfatal "Missing ${FIP_OPTEE_PAGEABLE}-${dt}.${FIP_OPTEE_SUFFIX} file in folder: ${FIP_DEPLOYDIR_OPTEE}" + # Set CERT_EXTRACONF + CERT_EXTRACONF="\ + --tos-fw ${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}.${FIP_OPTEE_SUFFIX} \ + --tos-fw-extra1 ${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}.${FIP_OPTEE_SUFFIX} \ + --tos-fw-extra2 ${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}.${FIP_OPTEE_SUFFIX} \ + " + if [ "${ENCRYPT_ENABLE}" = "1" ]; then + encrypt_key="${ENCRYPT_FIP_KEY_PATH_LIST}" + if [ -n "${STM32MP_ENCRYPT_SOC_NAME}" ]; then + unset k + for soc in ${STM32MP_ENCRYPT_SOC_NAME}; do + k=$(expr $k + 1) + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && encrypt_key=$(echo ${ENCRYPT_FIP_KEY_PATH_LIST} | cut -d',' -f${k}) + done + fi + encrypt_key="$(hexdump -e '/1 "%02x"' ${encrypt_key})" + # encrypt optee header + bbnote "${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in \"${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}.${FIP_OPTEE_SUFFIX}\" \ + --out \"${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX}\" " + ${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}.${FIP_OPTEE_SUFFIX}" \ + --out "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX}" + # encrypt optee pager + bbnote "${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in \"${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}.${FIP_OPTEE_SUFFIX}\" \ + --out \"${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX}\" " + ${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}.${FIP_OPTEE_SUFFIX}" \ + --out "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX}" + # encrypt optee pageable + bbnote "${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in \"${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}.${FIP_OPTEE_SUFFIX}\" \ + --out \"${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX}\" " + ${ENCTOOL} --key ${encrypt_key} --nonce ${FIP_ENCRYPT_NONCE} --fw-enc-status 0 \ + --in "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}.${FIP_OPTEE_SUFFIX}" \ + --out "${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX}" + fi + # Set FIP_EXTRACONF + FIP_EXTRACONF="\ + --tos-fw ${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_HEADER}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX} \ + --tos-fw-extra1 ${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGER}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX} \ + --tos-fw-extra2 ${FIP_DEPLOYDIR_OPTEE}/${FIP_OPTEE_PAGEABLE}-${dt}${FIP_ENCRYPT_SUFFIX}.${FIP_OPTEE_SUFFIX} \ + " + else + bbfatal "Wrong configuration '${bl32_conf}' found in FIP_CONFIG for ${config} config." + fi + # Init FIP DDR config settings + if [ -f "${FIP_DEPLOYDIR_FWDDR}/${FIP_FW_DDR}-${dt}.${FIP_FW_DDR_SUFFIX}" ]; then + FIP_DDRCONF="--ddr-fw ${FIP_DEPLOYDIR_FWDDR}/${FIP_FW_DDR}-${dt}.${FIP_FW_DDR_SUFFIX}" + CERT_DDRCONF="--ddr-fw ${FIP_DEPLOYDIR_FWDDR}/${FIP_FW_DDR}-${dt}.${FIP_FW_DDR_SUFFIX}" + else + FIP_DDRCONF="" + CERT_DDRCONF="" + fi + # Init certificate settings + if [ "${SIGN_ENABLE}" = "1" ]; then + sign_key="${SIGN_KEY_PATH_LIST}" + if [ $(echo ${SIGN_KEY_PASS} | wc -w) -gt 1 ]; then + sign_single_key_pass=$(echo ${SIGN_KEY_PASS} | cut -d' ' -f1) + else + sign_single_key_pass="${SIGN_KEY_PASS}" + fi + if [ -n "${STM32MP_SOC_NAME}" ]; then + unset k + for soc in ${STM32MP_SOC_NAME}; do + k=$(expr $k + 1) + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && sign_key=$(echo ${SIGN_KEY_PATH_LIST} | cut -d',' -f${k}) + done + fi + mkdir -p ${B}/${config}-${dt} + FIP_CERTCONF="\ + --tb-fw-cert ${B}/${config}-${dt}/tb_fw.crt \ + --trusted-key-cert ${B}/${config}-${dt}/trusted_key.crt \ + --nt-fw-cert ${B}/${config}-${dt}/nt_fw_content.crt \ + --nt-fw-key-cert ${B}/${config}-${dt}/nt_fw_key.crt \ + --tos-fw-cert ${B}/${config}-${dt}/tos_fw_content.crt \ + --tos-fw-key-cert ${B}/${config}-${dt}/tos_fw_key.crt \ + --stm32mp-cfg-cert ${B}/${config}-${dt}/stm32mp_cfg_cert.crt \ + " + if [ "${FIP_BL31_ENABLE}" = "1" ]; then + FIP_CERTCONF="${FIP_CERTCONF} \ + --soc-fw-cert ${B}/${config}-${dt}/soc_fw_content.crt \ + --soc-fw-key-cert ${B}/${config}-${dt}/soc_fw_key.crt \ + " + fi + # Need fake bl2 binary to generate certificates + touch ${WORKDIR}/bl2-fake.bin + # Generate certificates + bbnote "${CERTTOOL} -n --tfw-nvctr 0 --ntfw-nvctr 0 --key-alg ecdsa --hash-alg sha256 \ + --rot-key ${sign_key} \ + --rot-key-pwd $sign_single_key_pass \ + ${FIP_FWCONFIG} \ + ${FIP_HWCONFIG} \ + ${FIP_NTFW} \ + ${FIP_CERTCONF} \ + ${CERT_EXTRACONF} \ + ${CERT_DDRCONF} \ + ${CERT_BL31CONF} \ + --tb-fw ${WORKDIR}/bl2-fake.bin" + ${CERTTOOL} -n --tfw-nvctr 0 --ntfw-nvctr 0 --key-alg ecdsa --hash-alg sha256 \ + --rot-key ${sign_key} \ + --rot-key-pwd $sign_single_key_pass \ + ${FIP_FWCONFIG} \ + ${FIP_HWCONFIG} \ + ${FIP_NTFW} \ + ${FIP_CERTCONF} \ + ${CERT_EXTRACONF} \ + ${CERT_DDRCONF} \ + ${CERT_BL31CONF} \ + --tb-fw ${WORKDIR}/bl2-fake.bin + # Remove fake bl2 binary + rm -f ${WORKDIR}/bl2-fake.bin + + # Init FIP DDR cert settings + FIP_DDRCERTCONF="--stm32mp-cfg-cert ${B}/${config}-${dt}/stm32mp_cfg_cert_ddr.crt" + # Generate FIP DDR certificates + if [ -f "${FIP_DEPLOYDIR_FWDDR}/${FIP_FW_DDR}-${dt}.${FIP_FW_DDR_SUFFIX}" ]; then + bbnote "${CERTTOOL} -n --tfw-nvctr 0 \ + --rot-key ${sign_key} \ + --rot-key-pwd $sign_single_key_pass \ + ${FIP_DDRCERTCONF} \ + ${CERT_DDRCONF}" + ${CERTTOOL} -n --tfw-nvctr 0 \ + --rot-key ${sign_key} \ + --rot-key-pwd $sign_single_key_pass \ + ${FIP_DDRCERTCONF} \ + ${CERT_DDRCONF} + fi + else + FIP_CERTCONF="" + FIP_DDRCERTCONF="" + fi + # Generate FIP binary + bbnote "${FIPTOOL} create \ + ${FIP_FWCONFIG} \ + ${FIP_HWCONFIG} \ + ${FIP_NTFW} \ + ${FIP_BL31CONF} \ + ${FIP_EXTRACONF} \ + ${FIP_DDRCONF} \ + ${FIP_CERTCONF} \ + ${FIP_DEPLOYDIR_FIP}/${FIP_BASENAME}-${dt}-${config}${FIP_ENCRYPT_SUFFIX}${FIP_SIGN_SUFFIX}.${FIP_SUFFIX}" + ${FIPTOOL} create \ + ${FIP_FWCONFIG} \ + ${FIP_HWCONFIG} \ + ${FIP_NTFW} \ + ${FIP_BL31CONF} \ + ${FIP_EXTRACONF} \ + ${FIP_DDRCONF} \ + ${FIP_CERTCONF} \ + ${FIP_DEPLOYDIR_FIP}/${FIP_BASENAME}-${dt}-${config}${FIP_ENCRYPT_SUFFIX}${FIP_SIGN_SUFFIX}.${FIP_SUFFIX} + # Generate FIP DDR binary + if [ -f "${FIP_DEPLOYDIR_FWDDR}/${FIP_FW_DDR}-${dt}.${FIP_FW_DDR_SUFFIX}" ]; then + bbnote "${FIPTOOL} create \ + ${FIP_DDRCERTCONF} \ + ${FIP_DDRCONF} \ + ${FIP_DEPLOYDIR_FIP}/${FIP_BASENAME}-${dt}-ddr${FIP_ENCRYPT_SUFFIX}${FIP_SIGN_SUFFIX}.${FIP_SUFFIX}" + ${FIPTOOL} create \ + ${FIP_DDRCERTCONF} \ + ${FIP_DDRCONF} \ + ${FIP_DEPLOYDIR_FIP}/${FIP_BASENAME}-${dt}-ddr${FIP_ENCRYPT_SUFFIX}${FIP_SIGN_SUFFIX}.${FIP_SUFFIX} + fi + done + done +} + +# Stub do_compile for nativesdk use case as we only expect to provide FIPTOOL_WRAPPER +do_compile:class-nativesdk() { + return +} + +do_install:class-nativesdk() { + # Create the FIPTOOL_WRAPPER script to use on sdk side + cat << EOF > ${WORKDIR}/${FIPTOOL_WRAPPER} +#!/bin/bash - +function bbfatal() { echo "\$*" ; exit 1 ; } + +# Set default TF-A FIP config +FIP_CONFIG="\${FIP_CONFIG:-${FIP_CONFIG}}" +FIP_BL31_ENABLE="\${FIP_BL31_ENABLE:-${FIP_BL31_ENABLE}}" +FIP_BL32_CONF="" +FIP_DEVICETREE="\${FIP_DEVICETREE:-}" + +# Set default supported configuration for devicetree and bl32 configuration +declare -A FIP_BL32_CONF_ARRAY +declare -A FIP_DEVICETREE_ARRAY +EOF + for config in ${FIP_CONFIG}; do + i=$(expr $i + 1) + cat << EOF >> ${WORKDIR}/${FIPTOOL_WRAPPER} +FIP_BL32_CONF_ARRAY[${config}]="$(echo ${FIP_BL32_CONF} | cut -d',' -f${i})" +FIP_DEVICETREE_ARRAY[${config}]="$(echo ${FIP_DEVICETREE} | cut -d',' -f${i})" +EOF + done + unset i + cat << EOF >> ${WORKDIR}/${FIPTOOL_WRAPPER} + +# Make sure about FIP_CONFIG value +if [ -z "\$FIP_CONFIG" ]; then + bbfatal "Wrong configuration 'FIP_CONFIG' is empty." +else + # Check that configuration match any of the supported ones + for config in \$FIP_CONFIG; do + CONFIG_FOUND=NO + for fip_config in ${FIP_CONFIG}; do + [ "\${config}" = "\${fip_config}" ] && { CONFIG_FOUND="YES" ; break; } + done + [ "\${CONFIG_FOUND}" = "NO" ] && bbfatal "Wrong 'FIP_CONFIG' configuration : \${config} is not one of the supported one (${FIP_CONFIG})" + done +fi +# Manage FIP_BL32_CONF default init +if [ -z "\$FIP_BL32_CONF" ]; then + # Assigned default supported value + for config in \$FIP_CONFIG; do + FIP_BL32_CONF+="\${FIP_BL32_CONF_ARRAY[\${config}]}," + done +fi +# Manage FIP_DEVICETREE default init +if [ -z "\$FIP_DEVICETREE" ]; then + # Assigned default supported value + for config in \$FIP_CONFIG; do + FIP_DEVICETREE+="\${FIP_DEVICETREE_ARRAY[\${config}]}," + done +fi + +# Configure default folder path for binaries to package +FIP_DEPLOYDIR_ROOT="\${FIP_DEPLOYDIR_ROOT:-}" +FIP_DEPLOYDIR_FIP="\${FIP_DEPLOYDIR_FIP:-\$FIP_DEPLOYDIR_ROOT/fip}" +FIP_DEPLOYDIR_TFA="\${FIP_DEPLOYDIR_TFA:-\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/bl32}" +FIP_DEPLOYDIR_BL31="\${FIP_DEPLOYDIR_BL31:-\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/bl31}" +FIP_DEPLOYDIR_FWDDR="\${FIP_DEPLOYDIR_FWDDR:-\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/ddr}" +FIP_DEPLOYDIR_FWCONF="\${FIP_DEPLOYDIR_FWCONF:-\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/fwconfig}" +FIP_DEPLOYDIR_OPTEE="\${FIP_DEPLOYDIR_OPTEE:-\$FIP_DEPLOYDIR_ROOT/optee}" +FIP_DEPLOYDIR_UBOOT="\${FIP_DEPLOYDIR_UBOOT:-\$FIP_DEPLOYDIR_ROOT/u-boot}" + +echo "" +echo "${FIPTOOL_WRAPPER} config:" +for config in \$FIP_CONFIG; do + i=\$(expr \$i + 1) + bl32_conf=\$(echo \$FIP_BL32_CONF | cut -d',' -f\$i) + dt_config=\$(echo \$FIP_DEVICETREE | cut -d',' -f\$i) + echo " \${config}:" ; \\ + echo " bl32 config value: \${bl32_conf}" + echo " devicetree config: \${dt_config}" +done +echo "" +echo "Switch configuration:" +echo " FIP_BL31_ENABLE : \$FIP_BL31_ENABLE" +echo "" +echo "Output folders:" +echo " FIP_DEPLOYDIR_ROOT : \$FIP_DEPLOYDIR_ROOT" +echo " FIP_DEPLOYDIR_FIP : \$FIP_DEPLOYDIR_FIP" +echo " FIP_DEPLOYDIR_TFA : \$FIP_DEPLOYDIR_TFA" +echo " FIP_DEPLOYDIR_BL31 : \$FIP_DEPLOYDIR_BL31" +echo " FIP_DEPLOYDIR_FWCONF: \$FIP_DEPLOYDIR_FWCONF" +echo " FIP_DEPLOYDIR_OPTEE : \$FIP_DEPLOYDIR_OPTEE" +echo " FIP_DEPLOYDIR_UBOOT : \$FIP_DEPLOYDIR_UBOOT" +echo "" +unset i +for config in \$FIP_CONFIG; do + i=\$(expr \$i + 1) + bl32_conf=\$(echo \$FIP_BL32_CONF | cut -d',' -f\$i) + dt_config=\$(echo \$FIP_DEVICETREE | cut -d',' -f\$i) + for dt in \${dt_config}; do + # Init soc suffix + soc_suffix="" + if [ -n "${STM32MP_SOC_NAME}" ]; then + for soc in ${STM32MP_SOC_NAME}; do + [ "\$(echo \${dt} | grep -c \${soc})" -eq 1 ] && soc_suffix="-\${soc}" + done + fi + # Init FIP fw-config settings + [ -f "\$FIP_DEPLOYDIR_FWCONF/\${dt}-${FIP_FW_CONFIG}-\${config}.${FIP_FW_CONFIG_SUFFIX}" ] || bbfatal "Missing \${dt}-${FIP_FW_CONFIG}-\${config}.${FIP_FW_CONFIG_SUFFIX} file in folder: \\\$FIP_DEPLOYDIR_FWCONF or '\\\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/fwconfig'" + FIP_FWCONFIG="--fw-config \$FIP_DEPLOYDIR_FWCONF/\${dt}-${FIP_FW_CONFIG}-\${config}.${FIP_FW_CONFIG_SUFFIX}" + # Init FIP hw-config settings + [ -f "\$FIP_DEPLOYDIR_UBOOT/${FIP_UBOOT_DTB}-\${dt}.${FIP_UBOOT_DTB_SUFFIX}" ] || bbfatal "Missing ${FIP_UBOOT_DTB}-\${dt}.${FIP_UBOOT_DTB_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_UBOOT' or '\\\$FIP_DEPLOYDIR_ROOT/u-boot'" + FIP_HWCONFIG="--hw-config \$FIP_DEPLOYDIR_UBOOT/${FIP_UBOOT_DTB}-\${dt}.${FIP_UBOOT_DTB_SUFFIX}" + # Init FIP nt-fw config + [ -f "\$FIP_DEPLOYDIR_UBOOT/${FIP_UBOOT}\${soc_suffix}.${FIP_UBOOT_SUFFIX}" ] || bbfatal "Missing ${FIP_UBOOT}\${soc_suffix}.${FIP_UBOOT_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_UBOOT' or '\\\$FIP_DEPLOYDIR_ROOT/u-boot'" + FIP_NTFW="--nt-fw \$FIP_DEPLOYDIR_UBOOT/${FIP_UBOOT}\${soc_suffix}.${FIP_UBOOT_SUFFIX}" + # Init FIP bl31 settings + if [ "\$FIP_BL31_ENABLE" = "1" ]; then + # Check for files + [ -f "\$FIP_DEPLOYDIR_BL31/${FIP_BL31}\${soc_suffix}.${FIP_BL31_SUFFIX}" ] || bbfatal "Missing \$FIP_DEPLOYDIR_BL31/${FIP_BL31}\${soc_suffix}.${FIP_BL31_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_BL31' or '\\\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/bl31'" + [ -f "\$FIP_DEPLOYDIR_BL31/\${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX}" ] || bbfatal "Missing \${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_BL31' or '\\\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/bl31'" + # Set FIP_BL31CONF + FIP_BL31CONF="\\ + --soc-fw \$FIP_DEPLOYDIR_BL31/${FIP_BL31}\${soc_suffix}.${FIP_BL31_SUFFIX} \\ + --soc-fw-config \$FIP_DEPLOYDIR_BL31/\${dt}-${FIP_BL31_DTB}.${FIP_BL31_DTB_SUFFIX} \\ + " + else + FIP_BL31CONF="" + fi + # Init FIP extra conf settings + if [ "\${bl32_conf}" = "${FIP_CONFIG_FW_TFA}" ]; then + # Check for files + [ -f "\$FIP_DEPLOYDIR_TFA/${FIP_TFA}\${soc_suffix}.${FIP_TFA_SUFFIX}" ] || bbfatal "Missing ${FIP_TFA}\${soc_suffix}.${FIP_TFA_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_TFA' or '\\\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/bl32'" + [ -f "\$FIP_DEPLOYDIR_TFA/\${dt}-${FIP_TFA_DTB}.${FIP_TFA_DTB_SUFFIX}" ] || bbfatal "Missing \${dt}-${FIP_TFA_DTB}.${FIP_TFA_DTB_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_TFA' or '\\\$FIP_DEPLOYDIR_ROOT/arm-trusted-firmware/bl32'" + # Set FIP_EXTRACONF + FIP_EXTRACONF="\\ + --tos-fw \$FIP_DEPLOYDIR_TFA/${FIP_TFA}\${soc_suffix}.${FIP_TFA_SUFFIX} \\ + --tos-fw-config \$FIP_DEPLOYDIR_TFA/\${dt}-${FIP_TFA_DTB}.${FIP_TFA_DTB_SUFFIX} \\ + " + elif [ "\${bl32_conf}" = "${FIP_CONFIG_FW_TEE}" ]; then + # Check for files + [ -f "\$FIP_DEPLOYDIR_OPTEE/${FIP_OPTEE_HEADER}-\${dt}.${FIP_OPTEE_SUFFIX}" ] || bbfatal "Missing ${FIP_OPTEE_HEADER}-\${dt}.${FIP_OPTEE_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_OPTEE' or '\\\$FIP_DEPLOYDIR_ROOT/optee'" + [ -f "\$FIP_DEPLOYDIR_OPTEE/${FIP_OPTEE_PAGER}-\${dt}.${FIP_OPTEE_SUFFIX}" ] || bbfatal "Missing ${FIP_OPTEE_PAGER}-\${dt}.${FIP_OPTEE_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_OPTEE' or '\\\$FIP_DEPLOYDIR_ROOT/optee'" + [ -f "\$FIP_DEPLOYDIR_OPTEE/${FIP_OPTEE_PAGEABLE}-\${dt}.${FIP_OPTEE_SUFFIX}" ] || bbfatal "Missing ${FIP_OPTEE_PAGEABLE}-\${dt}.${FIP_OPTEE_SUFFIX} file in folder: '\\\$FIP_DEPLOYDIR_OPTEE' or '\\\$FIP_DEPLOYDIR_ROOT/optee'" + # Set FIP_EXTRACONF + FIP_EXTRACONF="\\ + --tos-fw \$FIP_DEPLOYDIR_OPTEE/${FIP_OPTEE_HEADER}-\${dt}.${FIP_OPTEE_SUFFIX} \\ + --tos-fw-extra1 \$FIP_DEPLOYDIR_OPTEE/${FIP_OPTEE_PAGER}-\${dt}.${FIP_OPTEE_SUFFIX} \\ + --tos-fw-extra2 \$FIP_DEPLOYDIR_OPTEE/${FIP_OPTEE_PAGEABLE}-\${dt}.${FIP_OPTEE_SUFFIX} \\ + " + else + bbfatal "Wrong configuration '\${bl32_conf}' found in FIP_CONFIG for \${config} config." + fi + + # DRR FW + if [ -f "\$FIP_DEPLOYDIR_FWDDR/${FIP_FW_DDR}-\${dt}.${FIP_FW_DDR_SUFFIX}" ]; then + FIP_EXTRACONF="\$FIP_EXTRACONF --ddr-fw \$FIP_DEPLOYDIR_FWDDR/${FIP_FW_DDR}-\${dt}.${FIP_FW_DDR_SUFFIX} " + ${FIPTOOL} create \\ + --ddr-fw \$FIP_DEPLOYDIR_FWDDR/${FIP_FW_DDR}-\${dt}.${FIP_FW_DDR_SUFFIX} \\ + \$FIP_DEPLOYDIR_FIP/${FIP_BASENAME}-\${dt}-ddr.${FIP_SUFFIX} + echo "[${FIPTOOL}] DDR FW created" + fi + + # Generate FIP binary + echo "[${FIPTOOL}] Create ${FIP_BASENAME}-\${dt}-\${config}.${FIP_SUFFIX} fip binary into 'FIP_DEPLOYDIR_FIP' folder..." + [ -d "\$FIP_DEPLOYDIR_FIP" ] || mkdir -p "\$FIP_DEPLOYDIR_FIP" + ${FIPTOOL} create \\ + \$FIP_FWCONFIG \\ + \$FIP_HWCONFIG \\ + \$FIP_NTFW \\ + \$FIP_BL31CONF \\ + \$FIP_EXTRACONF \\ + \$FIP_DEPLOYDIR_FIP/${FIP_BASENAME}-\${dt}-\${config}.${FIP_SUFFIX} + echo "[${FIPTOOL}] Done" + done +done +EOF + + # Install the FIPTOOL_WRAPPER + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/${FIPTOOL_WRAPPER} ${D}${bindir}/ +} + +# Feed package for sdk with our fiptool wrapper +FILES:${FIPTOOL_WRAPPER}:class-nativesdk = "${bindir}/${FIPTOOL_WRAPPER}" diff --git a/meta-digi-arm/classes/image_types_digi.bbclass b/meta-digi-arm/classes/image_types_digi.bbclass index 236164dc1..8d38f572c 100644 --- a/meta-digi-arm/classes/image_types_digi.bbclass +++ b/meta-digi-arm/classes/image_types_digi.bbclass @@ -89,7 +89,7 @@ do_image_boot_ubifs[depends] += " \ IMAGE_CMD:boot.ubifs() { BOOTIMG_FILES_SYMLINK="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}.bin" - # Exclude DTB and DTBO from UBIFS image when creating a FIT image + # Exclude DTB and DTBO from final image, when creating a FIT file if [ "${KERNEL_IMAGETYPE}" != "fitImage" ]; then if [ -n "${KERNEL_DEVICETREE}" ]; then for DTB in ${KERNEL_DEVICETREE}; do @@ -116,7 +116,7 @@ IMAGE_CMD:boot.ubifs() { ln ${orig} ${TMP_BOOTDIR}/$(basename ${item}) done - # Exclude boot scripts from UBIFS image when creating a FIT image + # Exclude boot scripts from final image, when creating a FIT file if [ "${KERNEL_IMAGETYPE}" != "fitImage" ]; then # Hard-link boot scripts into the temporary folder for item in ${BOOT_SCRIPTS}; do @@ -167,8 +167,12 @@ do_image_recovery_ubifs[depends] += " \ " IMAGE_CMD:recovery.ubifs() { - RECOVERYIMG_FILES_SYMLINK="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}.bin" - # Exclude DTB and DTBO from VFAT image when creating a FIT image + if [ "${KERNEL_IMAGETYPE}" = "fitImage" ]; then + RECOVERYIMG_FILES_SYMLINK="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${RECOVERY_INITRAMFS_IMAGE}-${MACHINE}-${MACHINE}" + else + RECOVERYIMG_FILES_SYMLINK="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-${MACHINE}.bin" + fi + # Exclude DTB and DTBO from final image, when creating a FIT file if [ "${KERNEL_IMAGETYPE}" != "fitImage" ]; then if [ -n "${KERNEL_DEVICETREE}" ]; then for DTB in ${KERNEL_DEVICETREE}; do @@ -190,15 +194,17 @@ IMAGE_CMD:recovery.ubifs() { ln ${orig} ${TMP_RECOVERYDIR}/$(basename ${item}) done - # Exclude bootscript from VFAT image when creating a FIT image - if [ "${KERNEL_IMAGETYPE}" != "fitImage" ]; then + # Exclude bootscript from final image when creating a FIT file + if [ "${KERNEL_IMAGETYPE}" = "fitImage" ]; then + # rename FITimage to u-boot default kernel load name + mv ${TMP_RECOVERYDIR}/${KERNEL_IMAGETYPE}-${RECOVERY_INITRAMFS_IMAGE}-${MACHINE}-${MACHINE} ${TMP_RECOVERYDIR}/${KERNEL_IMAGETYPE}-${MACHINE}.bin + else # Hard-link boot scripts into the temporary folder for item in ${BOOT_SCRIPTS}; do src="$(echo ${item} | awk -F':' '{ print $1 }')" dst="$(echo ${item} | awk -F':' '{ print $2 }')" ln ${DEPLOY_DIR_IMAGE}/${src} ${TMP_RECOVERYDIR}/${dst} done - # Copy the recovery initramfs into the temporary folder cp ${DEPLOY_DIR_IMAGE}/${RECOVERY_INITRAMFS_IMAGE}-${MACHINE}.cpio.gz.u-boot.tf ${TMP_RECOVERYDIR}/uramdisk-recovery.img fi diff --git a/meta-digi-arm/classes/sign-stm32mp2.bbclass b/meta-digi-arm/classes/sign-stm32mp2.bbclass new file mode 100644 index 000000000..cbd754604 --- /dev/null +++ b/meta-digi-arm/classes/sign-stm32mp2.bbclass @@ -0,0 +1,125 @@ +EXTERNAL_KEY_CONF ??= "0" + +ENCRYPT_ENABLE ??= "0" +ENCRYPT_FIP_KEY ??= "" +ENCRYPT_FSBL_KEY ??= "" +ENCRYPT_SUFFIX ??= "_Encrypted" + +SIGN_ENABLE ??= "0" +SIGN_KEY ??="" +SIGN_KEY_PASS ??= "" +SIGN_SUFFIX ??= "_Signed" + +SIGN_TOOL ??= "" + +def search_path(file_search, d): + """ + Check for path availability from BBPATH + And return the absolute path + """ + search_path = d.getVar("BBPATH").split(":") + for p in search_path: + file_path = os.path.join(p, file_search) + if os.path.isfile(file_path): + return file_path + bbpaths = d.getVar('BBPATH').replace(':','\n\t') + bb.fatal('\n[sign-stm32mp] Not able to find "%s" path from current BBPATH var:\n\t%s.' % (file_search, bbpaths)) + +def init_keylist_from(keylist, keyinput, soclist, d): + """ + Build the var as a coma separated list of values, + Using either the default var value + or any defined _socname var value + (with 'socname' item comming from var value list) + """ + # Init soc name list + socname_list = (d.getVar(soclist) or "").split() + # Init key from keyinput var value + key = d.getVar(keyinput) or "" + if key: + # Check first if keyinput_ is defined to use it + if len(socname_list) > 0: + # Configure keylist according to STM32MP_SOC_NAME list + d.setVar(keylist, '') + for socname in socname_list: + key = d.getVar(keyinput + '_' + socname) or "" + if key: + if d.getVar('EXTERNAL_KEY_CONF') == '1': + key = search_path(key, d) + bb.debug(1, "[sign-stm32mp] Append '%s' path to %s (socname %s)." % (key, keylist, socname)) + d.appendVar(keylist, key + ',') + else: + bb.fatal("[sign-stm32mp] Please make sure to configure \"%s_%s\" var to key file." % (keyinput, socname)) + else: + # Default to keyinput value setting + if d.getVar('EXTERNAL_KEY_CONF') == '1': + key = search_path(key, d) + bb.debug(1, "[sign-stm32mp] Set %s to '%s' path." % (keylist, key)) + d.setVar(keylist, key) + else: + bb.debug(1, "[sign-stm32mp] Set %s to '%s' path." % (keylist, key)) + d.setVar(keylist, key) + else: + # Check first if keyinput_ is defined to use it + if len(socname_list) > 0: + # Configure keylist according to STM32MP_SOC_NAME list + d.setVar(keylist, '') + for socname in socname_list: + key = d.getVar(keyinput + '_' + socname) + if key: + if d.getVar('EXTERNAL_KEY_CONF') == '1': + key = search_path(key, d) + bb.debug(1, "[sign-stm32mp] Append '%s' path to %s (socname %s)." % (key, keylist, socname)) + d.appendVar(keylist, key + ',') + else: + bb.fatal("[sign-stm32mp] Please make sure to configure \"%s_%s\" var to key file." % (keyinput, socname)) + else: + bb.fatal("[sign-stm32mp] Please make sure to configure \"%s\" var to key file." % keyinput) + +python __anonymous() { + if d.getVar('SIGN_ENABLE') == "1" or d.getVar('ENCRYPT_ENABLE') == "1": + + # Signing process is dedicated to "target" recipe only: + # Make sure to discard native and nativesdk + for native_class in ['native', 'nativesdk']: + if bb.data.inherits_class(native_class, d): + return + + # Check for SIGN_TOOL configuration + signtool = d.getVar('SIGN_TOOL') or "" + if not signtool: + bb.fatal("[sign-stm32mp] Please make sure to configure \"SIGN_TOOL\" var to signing tool.") + # Check for SIGN_TOOL is present in PATH environment variable + if not bb.utils.which(d.getVar('PATH'), signtool): + bb.debug(1, "[sign-stm32mp] %s binary is not found in PATH." % signtool) + signtool_path = search_path(signtool, d) + bb.debug(1, "[sign-stm32mp] Set SIGN_TOOL to '%s' path." % signtool_path) + d.setVar('SIGN_TOOL', signtool_path) + + if d.getVar('SIGN_ENABLE') == "1": + # Check for internal use of SIGN_KEY_PATH_LIST + signingkey_list = d.getVar('SIGN_KEY_PATH_LIST') + if signingkey_list: + raise bb.parse.SkipRecipe("[sign-stm32mp] You cannot use SIGN_KEY_PATH_LIST as it is internal to sign-stm32mp.bbclass.") + # Init SIGN_KEY_PATH_LIST from SIGN_KEY settings + init_keylist_from('SIGN_KEY_PATH_LIST', 'SIGN_KEY', 'STM32MP_SOC_NAME', d) + + if d.getVar('ENCRYPT_ENABLE') == "1": + if d.getVar('SIGN_ENABLE') == "0": + bb.fatal("[sign-stm32mp] You need to set 'SIGN_ENABLE = 1' to encrypt and sign binaries at once.") + + # Check for internal use of ENCRYPT_FSBL_KEY_PATH_LIST + fsbl_encryptkey_list = d.getVar('ENCRYPT_FSBL_KEY_PATH_LIST') + if fsbl_encryptkey_list: + raise bb.parse.SkipRecipe("[sign-stm32mp] You cannot use ENCRYPT_FSBL_KEY_PATH_LIST as it is internal to sign-stm32mp.bbclass.") + # Init ENCRYPT_KEY_PATH_LIST from ENCRYPT_KEY settings + init_keylist_from('ENCRYPT_FSBL_KEY_PATH_LIST', 'ENCRYPT_FSBL_KEY', 'STM32MP_ENCRYPT_SOC_NAME', d) + + # Check for internal use of ENCRYPT_FIP_KEY_PATH_LIST + fip_encryptkey_list = d.getVar('ENCRYPT_FIP_KEY_PATH_LIST') + if fip_encryptkey_list: + raise bb.parse.SkipRecipe("[sign-stm32mp] You cannot use ENCRYPT_FIP_KEY_PATH_LIST as it is internal to sign-stm32mp.bbclass.") + # Init ENCRYPT_KEY_PATH_LIST from ENCRYPT_KEY settings + init_keylist_from('ENCRYPT_FIP_KEY_PATH_LIST', 'ENCRYPT_FIP_KEY', 'STM32MP_ENCRYPT_SOC_NAME', d) + +} diff --git a/meta-digi-arm/conf/layer.conf b/meta-digi-arm/conf/layer.conf index 415dc41df..5d8b7fc6a 100644 --- a/meta-digi-arm/conf/layer.conf +++ b/meta-digi-arm/conf/layer.conf @@ -30,11 +30,13 @@ FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V42 = "ea25d099982d035af85d193c FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V45 = "63a38e9f392d8813d6f1f4d0d6fbe657" FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V48 = "db4762b09b6bda63da103963e6e081de" FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V49 = "2827219e81f28aba7c6a569f7c437fa7" +FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V56 = "10c0fda810c63b052409b15a5445671a" FSL_EULA_FILE_MD5SUMS:append = " \ ${FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V42} \ ${FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V45} \ ${FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V48} \ ${FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V49} \ + ${FSL_EULA_FILE_MD5SUM_LA_OPT_NXP_SOFTWARE_LICENSE_V56} \ " # STM EULA diff --git a/meta-digi-arm/conf/machine/ccimx91-dvk.conf b/meta-digi-arm/conf/machine/ccimx91-dvk.conf new file mode 100644 index 000000000..e0c87e24d --- /dev/null +++ b/meta-digi-arm/conf/machine/ccimx91-dvk.conf @@ -0,0 +1,50 @@ +#@TYPE: Machine +#@NAME: ConnectCore 91 Development Kit +#@DESCRIPTION: Machine configuration for Digi's ConnectCore 91 DVK + +DIGI_SOM = "ccimx91" +MACHINEOVERRIDES =. "mx91:${DIGI_FAMILY}:${DIGI_SOM}:" + +# Include the machine configuration for Digi's ConnectCore 9 module +include conf/machine/include/ccimx9.inc + +IMXBOOT_TARGETS = "flash_singleboot" + +# U-Boot configurations +UBOOT_CONFIG ??= "ccimx91-dvk" +UBOOT_CONFIG[ccimx91-dvk] = "ccimx91-dvk_defconfig" + +# imx-boot configurations +ATF_PLATFORM = "imx91" +IMX_BOOT_SOC_TARGET = "iMX91" +IMXBOOT_TARGETS = "flash_singleboot" +SECO_FIRMWARE_NAME = "mx91a0-ahab-container.img" + +BOOTLOADER_SEEK_USERDATA = "32" + +KERNEL_DEVICETREE ?= " \ + digi/ccimx91-dvk.dtb \ + digi/_ov_board_enet2_ccimx9-dvk.dtbo \ + digi/_ov_board_mikroe-accel2-click_ccimx9-dvk.dtbo \ + digi/_ov_board_mikroe-gyro-click_ccimx9-dvk.dtbo \ + digi/_ov_som_bt_ccimx9.dtbo \ + digi/_ov_som_bt-dtm_ccimx9.dtbo \ + digi/_ov_som_wifi_ccimx9.dtbo \ + ${@bb.utils.contains('DISTRO_FEATURES', 'tsn', 'digi/_ov_board_eqos-tsn_ccimx9-dvk.dtbo', '', d)} \ +" + +# Default image for install scripts +DEFAULT_IMAGE_NAME ?= "core-image-base" + +# Set this platform without graphical support +IS_HEADLESS = "true" + +# Boot artifacts to be copied from the deploy dir to the installer ZIP +BOOTABLE_ARTIFACTS = " \ + imx-boot-ccimx91-dvk.bin \ +" + +# Add secure enclave +SOC_TOOLS_TEST:append:mx91-nxp-bsp = " imx-secure-enclave" +# Add AFE support +NXPAFE_INSTALL:mx91-nxp-bsp = "nxp-afe nxp-afe-voiceseeker" diff --git a/meta-digi-arm/conf/machine/ccimx93-dvk.conf b/meta-digi-arm/conf/machine/ccimx93-dvk.conf index b38c283c2..a659defa9 100644 --- a/meta-digi-arm/conf/machine/ccimx93-dvk.conf +++ b/meta-digi-arm/conf/machine/ccimx93-dvk.conf @@ -5,39 +5,38 @@ DIGI_SOM = "ccimx93" MACHINEOVERRIDES =. "mx93:${DIGI_FAMILY}:${DIGI_SOM}:" -require include/ccimx93.inc +# Include the machine configuration for Digi's ConnectCore 9 module +include conf/machine/include/ccimx9.inc # U-Boot configurations UBOOT_CONFIG ??= "ccimx93-dvk" UBOOT_CONFIG[ccimx93-dvk] = "ccimx93-dvk_defconfig" -UBOOT_DTB_NAME = "ccimx93-dvk.dtb" -BOOTLOADER_SEEK_USERDATA = "32" +# imx-boot configurations +ATF_PLATFORM = "imx93" +IMX_BOOT_SOC_TARGET = "iMX93" +IMXBOOT_TARGETS = "flash_singleboot flash_singleboot_a0" +# Generate images for all SOC revisions (keep the override as otherwise the +# one in "use-imx-security-controller-firmware.bbclass" takes precedence) +SECO_FIRMWARE_NAME:ccimx93 = "mx93??-ahab-container.img" KERNEL_DEVICETREE ?= " \ digi/ccimx93-dvk.dtb \ digi/_ov_board_dlc0200ccp04df-mipi-dsi_ccimx93-dvk.dtbo \ - digi/_ov_board_enet2_ccimx93-dvk.dtbo \ digi/_ov_board_lvds_ccimx93-dvk.dtbo \ - digi/_ov_board_mikroe-accel2-click_ccimx93-dvk.dtbo \ - digi/_ov_board_mikroe-gyro-click_ccimx93-dvk.dtbo \ - digi/_ov_board_nhd-3-5-640480ef-msxp-mipi-dsi_ccimx93-dvk.dtbo \ - digi/_ov_som_bt_ccimx93.dtbo \ - digi/_ov_som_bt-dtm_ccimx93.dtbo \ + digi/_ov_board_enet2_ccimx9-dvk.dtbo \ + digi/_ov_board_mikroe-accel2-click_ccimx9-dvk.dtbo \ + digi/_ov_board_mikroe-gyro-click_ccimx9-dvk.dtbo \ + digi/_ov_som_bt_ccimx9.dtbo \ + digi/_ov_som_bt-dtm_ccimx9.dtbo \ + digi/_ov_som_emulate-ccimx91_ccimx93.dtbo \ digi/_ov_som_npu_ccimx93.dtbo \ - digi/_ov_som_wifi_ccimx93.dtbo \ - ${@bb.utils.contains('DISTRO_FEATURES', 'tsn', 'digi/_ov_board_eqos-tsn_ccimx93-dvk.dtbo', '', d)} \ + digi/_ov_som_wifi_ccimx9.dtbo \ + ${@bb.utils.contains('DISTRO_FEATURES', 'tsn', 'digi/_ov_board_eqos-tsn_ccimx9-dvk.dtbo', '', d)} \ " -# Wireless external module -WIRELESS_MODULE ?= "" -WIRELESS_MODULE:append = " ${@oe.utils.conditional('HAVE_WIFI', '1', 'kernel-module-nxp-wlan', '', d)}" -HAS_WIFI_VIRTWLANS = "true" - -# Machine firmware -MACHINE_FIRMWARE:append = " ${@oe.utils.conditional('HAVE_WIFI', '1', 'firmware-nxp-wifi-nxpiw612 firmware-murata-nxp', '', d)}" - -MACHINE_EXTRA_RRECOMMENDS += "${WIRELESS_MODULE}" +# Add additional firmware +MACHINE_FIRMWARE:append = " ethos-u-firmware" IMAGE_BOOT_FILES:append:use-nxp-bsp = " \ imx93_m33_TCM_rpmsg_lite_pingpong_rtos_linux_remote.bin \ @@ -45,23 +44,8 @@ IMAGE_BOOT_FILES:append:use-nxp-bsp = " \ " WKS_FILE_DEPENDS:append = " imx-m33-demos" -# XBee -XBEE_RESET_N_GPIO ?= "gpio2@19" -XBEE_SLEEP_RQ_GPIO ?= "" -XBEE_TTY ?= "ttyLP3" - -# Image FS types -IMAGE_FSTYPES ?= '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", \ - "boot.vfat recovery.vfat squashfs tar.bz2", \ - "boot.vfat recovery.vfat ext4.gz tar.bz2 sdcard.gz", d)}' - # Boot artifacts to be copied from the deploy dir to the installer ZIP BOOTABLE_ARTIFACTS = " \ imx-boot-ccimx93-dvk.bin \ imx-boot-ccimx93-dvk-A0.bin \ " - -# Default overlayfs_etc mount point and type -OVERLAYFS_ETC_MOUNT_POINT ?= "/mnt/data" -OVERLAYFS_ETC_DEVICE ?= "/dev/mmcblk0p7" -OVERLAYFS_ETC_FSTYPE ?= "ext4" diff --git a/meta-digi-arm/conf/machine/ccmp25-dvk.conf b/meta-digi-arm/conf/machine/ccmp25-dvk.conf new file mode 100644 index 000000000..88b604f94 --- /dev/null +++ b/meta-digi-arm/conf/machine/ccmp25-dvk.conf @@ -0,0 +1,158 @@ +#@TYPE: Machine +#@NAME: ccmp25-dvk +#@DESCRIPTION: Configuration for Digi ConnectCore MP25 DVK +#@NEEDED_BSPLAYERS: layers/meta-digi + +# Include the machine configuration for Digi's ConnectCore MP2. +include conf/machine/include/ccmp2.inc + +# Define specific familly common machine name +DIGI_SOM = "ccmp25" +MACHINEOVERRIDES =. "stm32mp2common:stm32mp25common:${DIGI_FAMILY}:${DIGI_SOM}:" + +# ========================================================================= +# SOC +# ========================================================================= +STM32MP_SOC_NAME = "stm32mp25" + +# ========================================================================= +# Chip architecture +# ========================================================================= +DEFAULTTUNE = "cortexa35" +include conf/machine/include/arm/armv8a/tune-cortexa35.inc + +# ========================================================================= +# boot device +# ========================================================================= +# Configure the list of boards that enable EMMC/SDCARD +DEVICE_BOARD_ENABLE:EMMC += "${STM32MP_DEVICETREE}" +DEVICE_BOARD_ENABLE:SDCARD += "${@bb.utils.contains('BOOTDEVICE_LABELS', 'sdcard', '${STM32MP_DEVICETREE}', '', d)}" + +# ========================================================================= +# U-Boot configs +# ========================================================================= +# Last one is the default (the one the symlinks point at) +UBOOT_CONFIG = "ccmp25-dvk" +UBOOT_CONFIG[ccmp25-dvk] = "ccmp25-dvk_defconfig,,u-boot-dtb.${UBOOT_SUFFIX}" + +# ========================================================================= +# Machine settings +# ========================================================================= +# Define list of devicetree per supported storage +STM32MP_DEVICETREE ??= "ccmp25-dvk" +# Extra DTB for board - need to specify it with .dtb ... +STM32MP_KERNEL_DEVICETREE:ccmp25-dvk += " \ + ccmp25-dvk.dtb \ + _ov_board_e55rb-i-mw346-c-mipi-dsi_ccmp25-dvk.dtbo \ + _ov_board_g101evn010-lvds_ccmp25-dvk.dtbo \ + _ov_board_mikroe-accel2-click_ccmp25-dvk.dtbo \ + _ov_board_mikroe-gyro-click_ccmp25-dvk.dtbo \ + _ov_board_mikroe-i2c-to-spi-click_ccmp25-dvk.dtbo \ + _ov_board_mikroe-mcp2518fd-click_ccmp25-dvk.dtbo \ + _ov_board_n25q256a-spi-nor-flash_ccmp25-dvk.dtbo \ + _ov_board_nhd-3-5-640480ef-msxp-mipi-dsi_ccmp25-dvk.dtbo \ + _ov_board_usb-3-0-typec_ccmp25-dvk.dtbo \ + _ov_som_bt_ccmp25.dtbo \ + _ov_som_wifi_ccmp25.dtbo \ +" + +# ========================================================================= +# optee +# ========================================================================= +# Map OPTEE configuration to device tree list +OPTEE_CONF = "${STM32MP_DEVICETREE}" + +# ========================================================================= +# Machine features +# ========================================================================= +MACHINE_FEATURES += "splashscreen" +MACHINE_FEATURES += "watchdog" +MACHINE_FEATURES += "bluetooth" +MACHINE_FEATURES += "wifi" +MACHINE_FEATURES += "usbg0" + +# GPU +MACHINE_FEATURES += "${@'gpu' if d.getVar('ACCEPT_EULA_'+d.getVar('MACHINE')) == '1' else ''}" +MACHINE_FEATURES += "openvx" +MACHINE_FEATURES += "opencl" +MACHINE_FEATURES += "vulkan" + +# M33 +MACHINE_FEATURES += "m33copro" + +# Disable external dt +EXTERNAL_DT_ENABLED = "0" + +# Flashlayout +# No metadata generated and supported for the moment +STM32MP_METADATA_DATA ?= "" + +# GPU have vulkan +DISTRO_FEATURES:append = " ${@bb.utils.contains('DISTRO', 'openstlinux-eglfs', '', 'vulkan', d)} " +DISTRO_FEATURES:append = " opencl " + +# ========================================================================= +# Firmware +# ========================================================================= +MACHINE_FIRMWARE:append = " firmware-murata-infineon firmware-murata-infineon-mfgtest" + +MACHINE_EXTRA_RRECOMMENDS += " \ + ${MACHINE_FIRMWARE} \ +" + +# ========================================================================= +# Image +# ========================================================================= +# Image FS types +IMAGE_FSTYPES += '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", \ + "boot.vfat recovery.vfat squashfs tar.bz2", \ + "boot.vfat recovery.vfat ext4.gz tar.bz2", d)}' + +# Default image for install scripts +DEFAULT_IMAGE_NAME ?= "dey-image-webkit" + +# Wic files +WKS_FILES += " \ + ccmp2-1GB.wks.in \ +" + +# Wireless external module +HAS_WIFI_VIRTWLANS = "true" + +# Remove additional bluetooth packages +MACHINE_BLUETOOTH_EXTRA_INSTALL = "" + +# For populate_sdk, gcc-arm-none-eabi_11 has a libpython3 dependency, so we remove it. +ST_TOOLS_FOR_SDK:remove = "nativesdk-gcc-arm-none-eabi" + +# XBee +XBEE_RESET_N_GPIO ?= "GPIOD@6" +XBEE_SLEEP_RQ_GPIO ?= "" +XBEE_TTY ?= "ttySTM2" + +# ========================================================================= +# alsa +# ========================================================================= +ALSA_LIST = "" + +# Disable use of vendorfs and userfs partitions +ST_VENDORFS = "0" +ST_USERFS = "0" + +# Boot artifacts to be copied from the deploy dir to the installer ZIP +BOOTABLE_ARTIFACTS = " \ + arm-trusted-firmware/tf-a-ccmp25-dvk-emmc.stm32 \ + fip/fip-ccmp25-dvk-optee.bin \ + metadata-ccmp25-dvk.bin \ +" + +# Per-machine DISTRO_FEATURES customization +MACHINE_DISTRO_FEATURES_REMOVE = "x11" + +# Default ROOTFS max size for image being built to this value +IMAGE_ROOTFS_MAXSIZE = "1572864" + +# Default overlayfs_etc mount point and type +OVERLAYFS_ETC_MOUNT_POINT ?= "/mnt/data" +OVERLAYFS_ETC_DEVICE ?= "/dev/mmcblk0p11" +OVERLAYFS_ETC_FSTYPE ?= "ext4" diff --git a/meta-digi-arm/conf/machine/include/ccimx6.inc b/meta-digi-arm/conf/machine/include/ccimx6.inc index 4f5161631..9169db2ed 100644 --- a/meta-digi-arm/conf/machine/include/ccimx6.inc +++ b/meta-digi-arm/conf/machine/include/ccimx6.inc @@ -16,6 +16,9 @@ UBOOT_SUFFIX = "imx" BOOTABLE_FILENAME = "${UBOOT_PREFIX}-${MACHINE}.${UBOOT_SUFFIX}" SDIMG_BOOTLOADER = "${DEPLOY_DIR_IMAGE}/${BOOTABLE_FILENAME}" +# Set InitRAMDisk load address to U-boot initramfs_addr +UBOOT_RD_LOADADDRESS = "0x19000000" + # Linux kernel configuration KERNEL_DEFCONFIG ?= "arch/arm/configs/ccimx6sbc_defconfig" diff --git a/meta-digi-arm/conf/machine/include/ccimx6ul.inc b/meta-digi-arm/conf/machine/include/ccimx6ul.inc index 8bdbb3efe..69538f9a0 100644 --- a/meta-digi-arm/conf/machine/include/ccimx6ul.inc +++ b/meta-digi-arm/conf/machine/include/ccimx6ul.inc @@ -16,6 +16,9 @@ INIT_MANAGER ?= "sysvinit" UBOOT_PREFIX = "u-boot" UBOOT_SUFFIX = "imx" +# Set InitRAMDisk load address to U-boot initramfs_addr +UBOOT_RD_LOADADDRESS = "0x83800000" + STORAGE_MEDIA = "mtd" # Wireless external module diff --git a/meta-digi-arm/conf/machine/include/ccimx8m.inc b/meta-digi-arm/conf/machine/include/ccimx8m.inc index ce88fff5e..bb2d79f7c 100644 --- a/meta-digi-arm/conf/machine/include/ccimx8m.inc +++ b/meta-digi-arm/conf/machine/include/ccimx8m.inc @@ -17,6 +17,9 @@ BOOTLOADER_IMAGE_RECIPE = "imx-boot" BOOTABLE_FILENAME = "${UBOOT_PREFIX}-${MACHINE}.bin" SDIMG_BOOTLOADER = "${DEPLOY_DIR_IMAGE}/${BOOTABLE_FILENAME}" +# Set InitRAMDisk load address to U-boot initramfs_addr +UBOOT_RD_LOADADDRESS = "0x43800000" + # LPDDR4 firmware DDR_FIRMWARE_NAME = " \ lpddr4_pmu_train_1d_imem.bin \ diff --git a/meta-digi-arm/conf/machine/include/ccimx8x.inc b/meta-digi-arm/conf/machine/include/ccimx8x.inc index 36f9c1bfb..d3450bcbd 100644 --- a/meta-digi-arm/conf/machine/include/ccimx8x.inc +++ b/meta-digi-arm/conf/machine/include/ccimx8x.inc @@ -13,6 +13,9 @@ include conf/machine/include/arm/armv8a/tune-cortexa35.inc UBOOT_PREFIX = "imx-boot" UBOOT_SUFFIX = "bin" +# Set InitRAMDisk load address to U-boot initrd_addr +UBOOT_RD_LOADADDRESS = "0x8A100000" + # The bootloader image that gets flashed consists of U-Boot and several fw binaries EXTRA_IMAGEDEPENDS += "imx-boot" BOOTLOADER_IMAGE_RECIPE = "imx-boot" diff --git a/meta-digi-arm/conf/machine/include/ccimx9.inc b/meta-digi-arm/conf/machine/include/ccimx9.inc new file mode 100644 index 000000000..3079142a9 --- /dev/null +++ b/meta-digi-arm/conf/machine/include/ccimx9.inc @@ -0,0 +1,120 @@ +#@TYPE: Machine +#@NAME: ConnectCore 9 family of SOMs +#@DESCRIPTION: Machine configuration for Digi's ConnectCore 9 family of SOMs + +DIGI_FAMILY = "ccimx9" + +require conf/machine/include/imx-digi-base.inc +require conf/machine/include/arm/armv8-2a/tune-cortexa55.inc + +# Platform u-boot settings +UBOOT_DTB_LOADADDRESS = "0x83000000" +UBOOT_DTBO_LOADADDRESS = "0x83000000" +UBOOT_ENTRYPOINT = "0x80400000" +UBOOT_ENV = "boot" +UBOOT_PREFIX = "imx-boot" +UBOOT_SUFFIX = "bin" + +# Set InitRAMDisk load address to U-boot initrd_addr +UBOOT_RD_LOADADDRESS = "0x83800000" + +# Platform kernel settings (keep the override as otherwise KERNEL_IMAGETYPE +# from imx-digi-base.inc takes precedence) +KERNEL_CLASSES = "kernel-fitimage" +KERNEL_IMAGETYPE:ccimx9 = "${@oe.utils.vartrue('TRUSTFENCE_SIGN_ARTIFACTS', 'fitImage', 'Image.gz', d)}" + +# The bootloader image that gets flashed consists of U-Boot and several fw binaries +EXTRA_IMAGEDEPENDS += "imx-boot" +BOOTLOADER_IMAGE_RECIPE = "imx-boot" +BOOTABLE_FILENAME = "${UBOOT_PREFIX}-${MACHINE}.bin" +SDIMG_BOOTLOADER = "${DEPLOY_DIR_IMAGE}/${BOOTABLE_FILENAME}" +BOOTLOADER_SEEK_USERDATA = "32" + +DDR_FIRMWARE_NAME = " \ + lpddr4_dmem_1d_v202201.bin \ + lpddr4_dmem_2d_v202201.bin \ + lpddr4_imem_1d_v202201.bin \ + lpddr4_imem_2d_v202201.bin \ +" + +MACHINE_FEATURES += "pci wifi bluetooth" +MACHINE_FEATURES:append:use-nxp-bsp = " optee jailhouse" + +STORAGE_MEDIA = "mmc" +WLAN_P2P_INTERFACE = "wfd0" + +# Linux kernel configuration +KERNEL_DEFCONFIG ?= "arch/arm64/configs/ccimx9_defconfig" + +SPL_BINARY = "spl/u-boot-spl.bin" + +MACHINE_EXTRA_RDEPENDS += " \ + e2fsprogs-mke2fs \ + e2fsprogs-resize2fs \ + parted \ + xbee-init \ +" + +# TrustFence +TRUSTFENCE_SIGN_MODE = "AHAB" + +IMX_BOOT_SEEK = "32" + +SERIAL_CONSOLES = "115200;ttyLP5" + +# Bluetooth tty +BT_TTY ?= "ttyLP0" + +# Per-machine DISTRO_FEATURES customization +MACHINE_DISTRO_FEATURES_REMOVE = "vulkan" + +# SWUpdate sw-description configuration +BOOTFS_EXT ?= ".boot.vfat" +ROOTFS_EXT ?= '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", ".squashfs", ".ext4.gz", d)}' + +BOOT_DEV_NAME ?= "/dev/mmcblk0p1" +ROOTFS_DEV_NAME ?= "/dev/mmcblk0p3" +ROOTFS_ENC_DEV = "/dev/mapper/cryptrootfs" +ROOTFS_DEV_NAME_FINAL = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_ENCRYPT_ROOTFS') == '1', '${ROOTFS_ENC_DEV}', '${ROOTFS_DEV_NAME}')}" + +# Wireless external module +WIRELESS_MODULE ?= "" +WIRELESS_MODULE:append = " ${@oe.utils.conditional('HAVE_WIFI', '1', 'kernel-module-nxp-wlan', '', d)}" +HAS_WIFI_VIRTWLANS = "true" + +# Machine firmware +MACHINE_FIRMWARE:append = " ${@oe.utils.conditional('HAVE_WIFI', '1', 'firmware-nxp-wifi-nxpiw612 firmware-murata-nxp', '', d)}" + +MACHINE_EXTRA_RRECOMMENDS += "${WIRELESS_MODULE}" + +# XBee +XBEE_RESET_N_GPIO ?= "gpio2@19" +XBEE_SLEEP_RQ_GPIO ?= "" +XBEE_TTY ?= "ttyLP3" + +# Image FS types +IMAGE_FSTYPES ?= '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", \ + "boot.vfat recovery.vfat squashfs tar.bz2", \ + "boot.vfat recovery.vfat ext4.gz tar.bz2 sdcard.gz", d)}' + +# Default overlayfs_etc mount point and type +OVERLAYFS_ETC_MOUNT_POINT ?= "/mnt/data" +OVERLAYFS_ETC_DEVICE ?= "/dev/mmcblk0p7" +OVERLAYFS_ETC_FSTYPE ?= "ext4" + +PREFERRED_VERSION_gstreamer1.0:ccimx9 ?= "1.22.5.imx" +PREFERRED_VERSION_gstreamer1.0-plugins-bad:ccimx9 ?= "1.22.5.imx" +PREFERRED_VERSION_gstreamer1.0-plugins-base:ccimx9 ?= "1.22.5.imx" +PREFERRED_VERSION_gstreamer1.0-plugins-good:ccimx9 ?= "1.22.5.imx" +PREFERRED_VERSION_gstreamer1.0-plugins-ugly:ccimx9 ?= "1.22.6" + +PREFERRED_VERSION_libdrm:ccimx9 ?= "2.4.115.imx" +PREFERRED_VERSION_nativesdk-wayland:ccimx9 ?= "1.22.0.imx" +PREFERRED_VERSION_wayland:ccimx9 ?= "1.22.0.imx" +PREFERRED_VERSION_wayland-native:ccimx9 ?= "1.22.0.imx" +PREFERRED_VERSION_wayland-protocols:ccimx9 ?= "1.32.imx" +PREFERRED_VERSION_weston:ccimx9 ?= "11.0.3.imx" +PREFERRED_VERSION_xwayland:ccimx9 ?= "23.1.1.imx" + +PREFERRED_VERSION_nativesdk-trustfence-sign-tools:ccimx9 ?= "2023.04" +PREFERRED_VERSION_trustfence-sign-tools-native:ccimx9 ?= "2023.04" diff --git a/meta-digi-arm/conf/machine/include/ccimx93.inc b/meta-digi-arm/conf/machine/include/ccimx93.inc deleted file mode 100644 index 278911589..000000000 --- a/meta-digi-arm/conf/machine/include/ccimx93.inc +++ /dev/null @@ -1,104 +0,0 @@ -#@TYPE: Machine -#@NAME: ConnectCore 93 family of SOMs -#@DESCRIPTION: Machine configuration for Digi's ConnectCore 93 family of SOMs - -DIGI_FAMILY = "ccimx93" - -require conf/machine/include/imx-digi-base.inc -require conf/machine/include/arm/armv8-2a/tune-cortexa55.inc - -# Platform u-boot settings -UBOOT_DTB_LOADADDRESS = "0x83000000" -UBOOT_DTBO_LOADADDRESS = "0x83000000" -UBOOT_ENTRYPOINT = "0x80400000" -UBOOT_ENV = "boot" -UBOOT_PREFIX = "imx-boot" -UBOOT_SUFFIX = "bin" - -# Platform kernel settings (keep the override as otherwise KERNEL_IMAGETYPE -# from imx-digi-base.inc takes precedence) -KERNEL_CLASSES = "kernel-fitimage" -KERNEL_IMAGETYPE:ccimx93 = "${@oe.utils.vartrue('TRUSTFENCE_SIGN_ARTIFACTS', 'fitImage', 'Image.gz', d)}" - -# The bootloader image that gets flashed consists of U-Boot and several fw binaries -EXTRA_IMAGEDEPENDS += "imx-boot" -BOOTLOADER_IMAGE_RECIPE = "imx-boot" -BOOTABLE_FILENAME = "${UBOOT_PREFIX}-${MACHINE}.bin" -SDIMG_BOOTLOADER = "${DEPLOY_DIR_IMAGE}/${BOOTABLE_FILENAME}" - -# Generate images for all SOC revisions (keep the override as otherwise the -# one in "use-imx-security-controller-firmware.bbclass" takes precedence) -SECO_FIRMWARE_NAME:ccimx93 = "mx93??-ahab-container.img" - -DDR_FIRMWARE_NAME = " \ - lpddr4_dmem_1d_v202201.bin \ - lpddr4_dmem_2d_v202201.bin \ - lpddr4_imem_1d_v202201.bin \ - lpddr4_imem_2d_v202201.bin \ -" - -MACHINE_FEATURES += "pci wifi bluetooth" -MACHINE_FEATURES:append:use-nxp-bsp = " optee jailhouse" - -STORAGE_MEDIA = "mmc" -WLAN_P2P_INTERFACE = "wfd0" - -# Linux kernel configuration -KERNEL_DEFCONFIG ?= "arch/arm64/configs/ccimx93_defconfig" - -SPL_BINARY = "spl/u-boot-spl.bin" - -# Set ATF platform name -ATF_PLATFORM = "imx93" - -MACHINE_EXTRA_RDEPENDS += " \ - e2fsprogs-mke2fs \ - e2fsprogs-resize2fs \ - parted \ - xbee-init \ -" - -# TrustFence -TRUSTFENCE_SIGN_MODE = "AHAB" - -IMXBOOT_TARGETS = "flash_singleboot flash_singleboot_a0" - -IMX_BOOT_SOC_TARGET = "iMX9" -IMX_BOOT_SEEK = "32" - -SERIAL_CONSOLES = "115200;ttyLP5" - -# Bluetooth tty -BT_TTY ?= "ttyLP0" - -# Add additional firmware -MACHINE_FIRMWARE:append = " ethos-u-firmware" - -# Per-machine DISTRO_FEATURES customization -MACHINE_DISTRO_FEATURES_REMOVE = "vulkan" - -# SWUpdate sw-description configuration -BOOTFS_EXT ?= ".boot.vfat" -ROOTFS_EXT ?= '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", ".squashfs", ".ext4.gz", d)}' - -BOOT_DEV_NAME ?= "/dev/mmcblk0p1" -ROOTFS_DEV_NAME ?= "/dev/mmcblk0p3" -ROOTFS_ENC_DEV = "/dev/mapper/cryptrootfs" -ROOTFS_DEV_NAME_FINAL = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_ENCRYPT_ROOTFS') == '1', '${ROOTFS_ENC_DEV}', '${ROOTFS_DEV_NAME}')}" - -PREFERRED_VERSION_gstreamer1.0:ccimx93 ?= "1.22.5.imx" -PREFERRED_VERSION_gstreamer1.0-plugins-bad:ccimx93 ?= "1.22.5.imx" -PREFERRED_VERSION_gstreamer1.0-plugins-base:ccimx93 ?= "1.22.5.imx" -PREFERRED_VERSION_gstreamer1.0-plugins-good:ccimx93 ?= "1.22.5.imx" -PREFERRED_VERSION_gstreamer1.0-plugins-ugly:ccimx93 ?= "1.22.6" - -PREFERRED_VERSION_libdrm:ccimx93 ?= "2.4.115.imx" -PREFERRED_VERSION_nativesdk-wayland:ccimx93 ?= "1.22.0.imx" -PREFERRED_VERSION_wayland:ccimx93 ?= "1.22.0.imx" -PREFERRED_VERSION_wayland-native:ccimx93 ?= "1.22.0.imx" -PREFERRED_VERSION_wayland-protocols:ccimx93 ?= "1.32.imx" -PREFERRED_VERSION_weston:ccimx93 ?= "11.0.3.imx" -PREFERRED_VERSION_xwayland:ccimx93 ?= "23.1.1.imx" - -PREFERRED_VERSION_nativesdk-trustfence-sign-tools:ccimx93 ?= "2023.04" -PREFERRED_VERSION_trustfence-sign-tools-native:ccimx93 ?= "2023.04" diff --git a/meta-digi-arm/conf/machine/include/ccmp1.inc b/meta-digi-arm/conf/machine/include/ccmp1.inc index 93a33dd36..4e0b72369 100644 --- a/meta-digi-arm/conf/machine/include/ccmp1.inc +++ b/meta-digi-arm/conf/machine/include/ccmp1.inc @@ -42,6 +42,9 @@ UBOOT_ENV_SIZE ?= "0x20000" # available space in the environment partition) UBOOT_ENV_RANGE ?= "" +# Set InitRAMDisk load address to U-boot initrd_addr +UBOOT_RD_LOADADDRESS = "0xc4400000" + # OPTEE runtime packages to install OPTEE_PKGS ??= "optee-client" @@ -78,7 +81,7 @@ TRUSTFENCE_CONSOLE_DISABLE ?= "0" # TRUSTFENCE_CONSOLE_PASSPHRASE_ENABLE = "" # Disable the generation of flashlayout files -do_create_flashlayout_config[noexec] = "1" +ENABLE_FLASHLAYOUT_CONFIG = "0" # Include boot script into the FIT image UBOOT_ENV = "boot" diff --git a/meta-digi-arm/conf/machine/include/ccmp2.inc b/meta-digi-arm/conf/machine/include/ccmp2.inc new file mode 100644 index 000000000..8762a1c28 --- /dev/null +++ b/meta-digi-arm/conf/machine/include/ccmp2.inc @@ -0,0 +1,97 @@ +#@TYPE: Machine +#@NAME: ConnectCore for STM32MP2. +#@DESCRIPTION: Machine configuration for Digi's ConnectCore MP2. + +include conf/machine/include/st-machine-common-stm32mp.inc +include conf/machine/include/digi-defaults.inc + +DIGI_FAMILY = "ccmp2" + +# Platform u-boot settings +UBOOT_PREFIX = "fip" +UBOOT_SUFFIX = "bin" +# Set U-Boot FIP settings +FIP_UBOOT_DTB = "u-boot" + +# ========================================================================= +# trusted-firmware-a +# ========================================================================= +PREFERRED_PROVIDER_virtual/trusted-firmware-a = "tf-a-stm32mp" +PREFERRED_VERSION_tf-a-stm32mp ?= "v2.8%" + +# Configure use of BL31 +FIP_BL31_ENABLE = "1" + +# ========================================================================= +# optee-os +# ========================================================================= +PREFERRED_PROVIDER_virtual/optee-os = "optee-os-stm32mp" +PREFERRED_VERSION_optee-os-stm32mp ?= "3.19%" + +PREFERRED_VERSION_gcnano-driver-stm32mp ?= "6.4.15%" +PREFERRED_VERSION_gcnano-userland-multi-binary-stm32mp ?= "6.4.15%" + +PREFERRED_VERSION_nativesdk-tf-a-tools ?= "v2.8%" +PREFERRED_VERSION_tf-a-tools-native ?= "v2.8%" + +# ========================================================================= +# Kernel +# ========================================================================= +KERNEL_IMAGETYPE = "${@bb.utils.contains('TRUSTFENCE_FIT_IMG', '1', 'fitImage', 'Image.gz', d)}" +KERNEL_CLASSES = "${@bb.utils.contains('TRUSTFENCE_FIT_IMG', '1', 'kernel-fitimage', 'kernel-uimage', d)}" +KERNEL_ALT_IMAGETYPE = "vmlinux" +KERNEL_DEFCONFIG ?= "arch/arm64/configs/ccmp2_defconfig" + +STORAGE_MEDIA = "mmc" + +# Enable STM specific features +DEY_SOC_VENDOR = "STM" + +# SWUpdate sw-description configuration +BOOTFS_EXT ?= ".boot.vfat" +ROOTFS_EXT ?= '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", ".squashfs", ".ext4.gz", d)}' + +BOOT_DEV_NAME ?= "/dev/mmcblk0p6" +ROOTFS_DEV_NAME ?= "/dev/mmcblk0p8" +ROOTFS_ENC_DEV = "/dev/mapper/cryptrootfs" +ROOTFS_DEV_NAME_FINAL = "${@oe.utils.ifelse(d.getVar('TRUSTFENCE_ENCRYPT_ROOTFS') == '1', '${ROOTFS_ENC_DEV}', '${ROOTFS_DEV_NAME}')}" + +# List of supported boot devices +BOOTDEVICE_LABELS ?= "emmc" +# Supported boot schemes +BOOTSCHEME_LABELS ?= "optee" + +MACHINE_EXTRA_RRECOMMENDS:remove = "kernel-imagebootfs" + +MACHINE_EXTRA_RDEPENDS += " \ + e2fsprogs-mke2fs \ + e2fsprogs-resize2fs \ + mtd-utils-ubifs \ + parted \ + xbee-init \ +" + +# ========================================================================= +# Signing configuration +# ========================================================================= +ENCRYPT_ENABLE ?= "0" +ENCRYPT_SUFFIX ?= "_Encrypted" + +SIGN_ENABLE ?= "0" +SIGN_SUFFIX ?= "_Signed" + +# ========================================================================= +# Debug trace +# ========================================================================= +# activate/deactivate the debug and trace on boot stage +ST_DEBUG_TRACE = "0" + +# Wic files +WKS_FILE_DEPENDS ?= " \ + virtual/bootloader \ + virtual/trusted-firmware-a \ + ${@bb.utils.contains('BOOTSCHEME_LABELS', 'optee', 'virtual/optee-os', '', d)} \ +" + +# Disable the generation of flashlayout files +ENABLE_FLASHLAYOUT_CONFIG = "0" diff --git a/meta-digi-arm/conf/machine/include/digi-defaults.inc b/meta-digi-arm/conf/machine/include/digi-defaults.inc index 078ee176a..c29cf6401 100644 --- a/meta-digi-arm/conf/machine/include/digi-defaults.inc +++ b/meta-digi-arm/conf/machine/include/digi-defaults.inc @@ -16,9 +16,11 @@ PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg" # ccimx8x 5.15 2020.04 (packaged in imx-boot) # ccimx8mn 5.15 2020.04 (packaged in imx-boot) # ccimx8mm 5.15 2020.04 (packaged in imx-boot) +# ccimx91 6.6 2024.04 (packaged in imx-boot) # ccimx93 6.1 2023.04 (packaged in imx-boot) # ccmp15 5.15 2021.10 # ccmp13 5.15 2021.10 +# ccmp25 6.1 2022.10 # # Help variables used in recipes diff --git a/meta-digi-arm/conf/machine/include/imx-digi-base.inc b/meta-digi-arm/conf/machine/include/imx-digi-base.inc index d04222f3c..3b37a5ba1 100644 --- a/meta-digi-arm/conf/machine/include/imx-digi-base.inc +++ b/meta-digi-arm/conf/machine/include/imx-digi-base.inc @@ -41,6 +41,7 @@ DEFAULTTUNE:mx6-generic-bsp ?= "cortexa9thf-neon" DEFAULTTUNE:mx6ul-generic-bsp ?= "cortexa7thf-neon" DEFAULTTUNE:mx8m-generic-bsp ?= "cortexa53-crypto" DEFAULTTUNE:mx8x-generic-bsp ?= "cortexa35-crypto" +DEFAULTTUNE:mx91-generic-bsp ?= "cortexa55" DEFAULTTUNE:mx93-generic-bsp ?= "cortexa55" INHERIT += "machine-overrides-extender" @@ -56,6 +57,7 @@ MACHINEOVERRIDES_EXTENDER:mx8mn:use-nxp-bsp = "imx-generic-bsp:imx-nxp-bsp:imxd MACHINEOVERRIDES_EXTENDER:mx8mp:use-nxp-bsp = "imx-generic-bsp:imx-nxp-bsp:imxdrm:imxvpu:imxgpu:imxgpu2d:imxgpu3d:imxvulkan:mx8-generic-bsp:mx8-nxp-bsp:mx8m-generic-bsp:mx8m-nxp-bsp:mx8mp-generic-bsp:mx8mp-nxp-bsp" MACHINEOVERRIDES_EXTENDER:mx8qxp:use-nxp-bsp = "imx-generic-bsp:imx-nxp-bsp:imxdrm:imxdpu:imxgpu:imxgpu2d:imxgpu3d:imxvulkan:mx8-generic-bsp:mx8-nxp-bsp:mx8x-generic-bsp:mx8x-nxp-bsp:mx8qxp-generic-bsp:mx8qxp-nxp-bsp" MACHINEOVERRIDES_EXTENDER:mx8dx:use-nxp-bsp = "imx-generic-bsp:imx-nxp-bsp:imxdrm:imxdpu:imxgpu:imxgpu2d:imxgpu3d:imxvulkan:mx8-generic-bsp:mx8-nxp-bsp:mx8x-generic-bsp:mx8x-nxp-bsp:mx8dx-generic-bsp:mx8dx-nxp-bsp" +MACHINEOVERRIDES_EXTENDER:mx91:use-nxp-bsp = "imx-generic-bsp:imx-nxp-bsp:imxdrm:imxpxp:mx9-generic-bsp:mx9-nxp-bsp:mx91-generic-bsp:mx91-nxp-bsp" MACHINEOVERRIDES_EXTENDER:mx93:use-nxp-bsp = "imx-generic-bsp:imx-nxp-bsp:imxdrm:imxpxp:mx9-generic-bsp:mx9-nxp-bsp:mx93-generic-bsp:mx93-nxp-bsp" ####### @@ -69,6 +71,7 @@ MACHINEOVERRIDES_EXTENDER:mx8mn:use-mainline-bsp = "imx-generic-bsp:imx-mainlin MACHINEOVERRIDES_EXTENDER:mx8mp:use-mainline-bsp = "imx-generic-bsp:imx-mainline-bsp:mx8-generic-bsp:mx8-mainline-bsp:mx8m-generic-bsp:mx8m-mainline-bsp:mx8mp-generic-bsp:mx8mp-mainline-bsp" MACHINEOVERRIDES_EXTENDER:mx8qxp:use-mainline-bsp = "imx-generic-bsp:imx-mainline-bsp:mx8-generic-bsp:mx8-mainline-bsp:mx8x-generic-bsp:mx8x-mainline-bsp:mx8qxp-generic-bsp:mx8qxp-mainline-bsp" MACHINEOVERRIDES_EXTENDER:mx8dx:use-mainline-bsp = "imx-generic-bsp:imx-mainline-bsp:mx8-generic-bsp:mx8-mainline-bsp:mx8x-generic-bsp:mx8x-mainline-bsp:mx8dx-generic-bsp:mx8dx-mainline-bsp" +MACHINEOVERRIDES_EXTENDER:mx91:use-mainline-bsp = "imx-generic-bsp:imx-mainline-bsp:mx9-generic-bsp:mx9-mainline-bsp:mx91-generic-bsp:mx91-mainline-bsp" MACHINEOVERRIDES_EXTENDER:mx93:use-mainline-bsp = "imx-generic-bsp:imx-mainline-bsp:mx9-generic-bsp:mx9-mainline-bsp:mx93-generic-bsp:mx93-mainline-bsp" MACHINEOVERRIDES_EXTENDER_FILTER_OUT = " \ @@ -98,6 +101,7 @@ MACHINEOVERRIDES_EXTENDER_FILTER_OUT = " \ mx8qxp \ mx8dx \ mx8dxl \ + mx91 \ mx93 \ " @@ -113,6 +117,7 @@ MACHINE_SOCARCH_SUFFIX:mx8mn-nxp-bsp = "-mx8mn" MACHINE_SOCARCH_SUFFIX:mx8mp-nxp-bsp = "-mx8mp" MACHINE_SOCARCH_SUFFIX:mx8qxp-nxp-bsp = "-mx8" MACHINE_SOCARCH_SUFFIX:mx8dx-nxp-bsp = "-mx8" +MACHINE_SOCARCH_SUFFIX:mx91-nxp-bsp = "-mx91" MACHINE_SOCARCH_SUFFIX:mx93-nxp-bsp = "-mx93" # For Mainline we use a single SoC suffix as we don't have different build options @@ -188,6 +193,7 @@ IMX_EXTRA_FIRMWARE ?= "" IMX_EXTRA_FIRMWARE:mx8-generic-bsp = "firmware-imx-8 imx-sc-firmware imx-seco" IMX_EXTRA_FIRMWARE:mx8m-generic-bsp = "firmware-imx-8m" IMX_EXTRA_FIRMWARE:mx8x-generic-bsp = "imx-sc-firmware imx-seco" +IMX_EXTRA_FIRMWARE:mx91-generic-bsp = "imx-boot-firmware-files firmware-ele-imx" IMX_EXTRA_FIRMWARE:mx93-generic-bsp = "imx-boot-firmware-files firmware-ele-imx" # Firmware @@ -271,12 +277,15 @@ PREFERRED_VERSION_vulkan-loader:imxvulkan ??= "1.2.182.0" PREFERRED_VERSION_vulkan-tools:imxvulkan ??= "1.2.182.0" # Use i.MX optee Version -PREFERRED_VERSION_optee-os:mx8-nxp-bsp ??= "3.19.0.imx" -PREFERRED_VERSION_optee-os:mx9-nxp-bsp ??= "4.0.0.imx" -PREFERRED_VERSION_optee-client:mx8-nxp-bsp ??= "3.19.0.imx" -PREFERRED_VERSION_optee-client:mx9-nxp-bsp ??= "4.0.0.imx" -PREFERRED_VERSION_optee-test:mx8-nxp-bsp ??= "3.19.0.imx" -PREFERRED_VERSION_optee-test:mx9-nxp-bsp ??= "4.0.0.imx" +PREFERRED_VERSION_optee-os:mx8-nxp-bsp ??= "3.19.0.imx" +PREFERRED_VERSION_optee-os:mx91-nxp-bsp ??= "4.2.0.imx" +PREFERRED_VERSION_optee-os:mx93-nxp-bsp ??= "4.0.0.imx" +PREFERRED_VERSION_optee-client:mx8-nxp-bsp ??= "3.19.0.imx" +PREFERRED_VERSION_optee-client:mx91-nxp-bsp ??= "4.2.0.imx" +PREFERRED_VERSION_optee-client:mx93-nxp-bsp ??= "4.0.0.imx" +PREFERRED_VERSION_optee-test:mx8-nxp-bsp ??= "3.19.0.imx" +PREFERRED_VERSION_optee-test:mx91-nxp-bsp ??= "4.2.0.imx" +PREFERRED_VERSION_optee-test:mx93-nxp-bsp ??= "4.0.0.imx" # Machine learning backports from NXP's lf-6.1.55-2.2.0 release PREFERRED_VERSION_ethos-u-driver-stack:ccimx93 = "23.08" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.0.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.0.bb index 52beb9e36..ede95b166 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.0.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.0.bb @@ -26,4 +26,4 @@ addtask deploy after do_install before do_build FILES:${PN} += "${nonarch_base_libdir}/firmware/imx/ele/${SECO_FIRMWARE_NAME}" -COMPATIBLE_MACHINE = "(mx8ulp-nxp-bsp|mx9-nxp-bsp)" +COMPATIBLE_MACHINE = "(ccimx93)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.2.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.2.bb new file mode 100644 index 000000000..323e6b9d5 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-ele-imx_0.1.2.bb @@ -0,0 +1,32 @@ +# Copyright 2021-2023 NXP +SUMMARY = "NXP i.MX ELE firmware" +DESCRIPTION = "EdgeLock Secure Enclave firmware for i.MX series SoCs" +SECTION = "base" +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://COPYING;md5=10c0fda810c63b052409b15a5445671a" + +inherit fsl-eula-unpack use-imx-security-controller-firmware deploy + +SRC_URI = "${FSL_MIRROR}/${BP}-${IMX_SRCREV_ABBREV}.bin;fsl-eula=true" +IMX_SRCREV_ABBREV = "4ed450a" +SRC_URI[md5sum] = "1359bc7d378bddfe1d8479eba05b05ec" +SRC_URI[sha256sum] = "d858fcbb47482a898a1af5fe5f3f8be53bb21fac793b33e9bcdfd2b4dda79d3c" + +S = "${WORKDIR}/${BP}-${IMX_SRCREV_ABBREV}" + +do_compile[noexec] = "1" + +do_install() { + install -d ${D}${nonarch_base_libdir}/firmware/imx/ele + install -m 0644 ${S}/${SECO_FIRMWARE_NAME} ${D}${nonarch_base_libdir}/firmware/imx/ele +} + +do_deploy () { + # Deploy the related firmware to be package by imx-boot + install -m 0644 ${S}/${SECO_FIRMWARE_NAME} ${DEPLOYDIR} +} +addtask deploy after do_install before do_build + +FILES:${PN} += "${nonarch_base_libdir}/firmware/imx/ele/${SECO_FIRMWARE_NAME}" + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-nxp-wifi_%.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-nxp-wifi_%.bbappend index ec08272f9..aa861161c 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-nxp-wifi_%.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/firmware-imx/firmware-nxp-wifi_%.bbappend @@ -1,17 +1,20 @@ -# Copyright (C) 2023 Digi International. +# Copyright (C) 2023,2024, Digi International Inc. +LIC_FILES_CHKSUM:ccimx91 = "file://LICENSE.txt;md5=10c0fda810c63b052409b15a5445671a" LIC_FILES_CHKSUM:ccimx93 = "file://LICENSE.txt;md5=2827219e81f28aba7c6a569f7c437fa7" +SRCBRANCH:ccimx91 = "lf-6.6.23_2.0.0" +SRCREV:ccimx91 = "7e038c6afba3118bcee91608764ac3c633bce0c4" SRCBRANCH:ccimx93 = "lf-6.1.55_2.2.0" SRCREV:ccimx93 = "7be5a936ce8677962dd7b41c6c9f41dd14350bec" -do_install:append:ccimx93() { +do_install:append:ccimx9() { # Install NXP Connectivity IW612 firmware install -m 0644 nxp/FwImage_IW612_SD/sd_w61x_v1.bin.se ${D}${nonarch_base_libdir}/firmware/nxp install -m 0644 nxp/FwImage_IW612_SD/uartspi_n61x_v1.bin.se ${D}${nonarch_base_libdir}/firmware/nxp } -PACKAGES:prepend:ccimx93 = "${PN}-nxpiw612 " +PACKAGES:prepend:ccimx9 = "${PN}-nxpiw612 " FILES:${PN}-nxpiw612 = " \ ${nonarch_base_libdir}/firmware/nxp/sd_w61x_v1.bin.se \ diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf/0001-ccimx91-use-UART6-for-the-default-console.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf/0001-ccimx91-use-UART6-for-the-default-console.patch new file mode 100644 index 000000000..9890f8b71 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf/0001-ccimx91-use-UART6-for-the-default-console.patch @@ -0,0 +1,22 @@ +From: Javier Viguera +Date: Mon, 19 Aug 2024 16:50:20 +0200 +Subject: [PATCH] ccimx91: use UART6 for the default console + +Signed-off-by: Javier Viguera +--- + plat/imx/imx91/include/platform_def.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plat/imx/imx91/include/platform_def.h b/plat/imx/imx91/include/platform_def.h +index 0ddd699f5e0b..6de23d8ef06f 100644 +--- a/plat/imx/imx91/include/platform_def.h ++++ b/plat/imx/imx91/include/platform_def.h +@@ -55,7 +55,7 @@ + #define MAX_MMAP_REGIONS 17 + #endif + +-#define IMX_LPUART_BASE 0x44380000 ++#define IMX_LPUART_BASE 0x425a0000 + #define IMX_BOOT_UART_CLK_IN_HZ 24000000 /* Select 24MHz oscillator */ + #define IMX_CONSOLE_BAUDRATE 115200 + diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_%.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_%.bbappend index bf02767c5..83e975e5f 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_%.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2022,2023 Digi International +# Copyright (C) 2022-2024, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" @@ -8,6 +8,9 @@ SRC_URI:append:ccimx8m = " \ file://0003-imx8mn-Define-UART1-as-console-for-boot-stage.patch \ file://0004-imx8mn-Disable-M7-debug-console.patch \ " +SRC_URI:append:ccimx91 = " \ + file://0001-ccimx91-use-UART6-for-the-default-console.patch \ +" SRC_URI:append:ccimx93 = " \ file://0001-ccimx93-use-UART6-for-the-default-console.patch \ file://0002-imx93-bring-back-ELE-clock-workaround-for-soc-revisi.patch \ diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.10.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.10.bb new file mode 100644 index 000000000..7f089a5f2 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.10.bb @@ -0,0 +1,13 @@ +# Copyright (C) 2024, Digi International Inc. + +# +# Reuse meta-freescale's imx-atf_2.6.bb +# +require recipes-bsp/imx-atf/imx-atf_2.6.bb + +SRC_URI = "git://github.com/nxp-imx/imx-atf.git;protocol=https;branch=${SRCBRANCH}" +SRCBRANCH = "lf_v2.10" +# Tag: lf-6.6.23-2.0.0 +SRCREV = "49143a1701d9ccd3239e3f95f3042897ca889ea8" + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.8.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.8.bb index 96ea44870..52689e681 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.8.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-atf/imx-atf_2.8.bb @@ -1,4 +1,4 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. # # Reuse meta-freescale's imx-atf_2.6.bb diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-lib/imx-lib_git.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-lib/imx-lib_git.bbappend index 740cb94ef..e16eb9fff 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-lib/imx-lib_git.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-lib/imx-lib_git.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Digi International +# Copyright (C) 2023, Digi International Inc. PLATFORM:mx9-nxp-bsp = "IMX8ULP" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/files/0001-imx91-soc.mak-capture-commands-output-into-a-log-fil.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/files/0001-imx91-soc.mak-capture-commands-output-into-a-log-fil.patch new file mode 100644 index 000000000..1b5fa8adb --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/files/0001-imx91-soc.mak-capture-commands-output-into-a-log-fil.patch @@ -0,0 +1,49 @@ +From: Javier Viguera +Date: Mon, 19 Aug 2024 17:07:33 +0200 +Subject: [PATCH] imx91: soc.mak: capture commands output into a log file + +This is later used to get the needed information for the signing of the +boot artifacts. + +Signed-off-by: Javier Viguera +--- + iMX91/soc.mak | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/iMX91/soc.mak b/iMX91/soc.mak +index b87a5bef79ce..3db3760c546d 100644 +--- a/iMX91/soc.mak ++++ b/iMX91/soc.mak +@@ -1,4 +1,5 @@ + MKIMG = ../mkimage_imx8 ++MKIMAGE_LOG = "mkimage-$(firstword $(MAKECMDGOALS)).log" + + CC ?= gcc + REV ?= A0 +@@ -51,7 +52,7 @@ define append_container + @flashbin_size=`wc -c flash.bin | awk '{print $$1}'`; \ + psize=$$((0x400 * $(2))); \ + pad_cnt=$$(((flashbin_size + psize - 1) / psize)); \ +- echo "append $(1) at $$((pad_cnt * $(2))) KB, psize=$$psize"; \ ++ echo "append $(1) at $$((pad_cnt * $(2))) KB, psize=$$psize" | tee -a $(MKIMAGE_LOG); \ + dd if=$(1) of=flash.bin bs=1K seek=$$((pad_cnt * $(2))); + endef + +@@ -126,7 +127,7 @@ u-boot-atf-container.img: bl31.bin u-boot-hash.bin + -ap bl31.bin a55 $(ATF_LOAD_ADDR) \ + -ap u-boot-hash.bin a55 $(UBOOT_LOAD_ADDR) \ + -out u-boot-atf-container.img; \ +- fi ++ fi | tee $(MKIMAGE_LOG) + + u-boot-atf-container-spinand.img: bl31.bin u-boot-hash.bin + if [ -f $(TEE) ]; then \ +@@ -202,7 +203,7 @@ endif + + + flash_singleboot: $(MKIMG) $(AHAB_IMG) $(SPL_A55_IMG) u-boot-atf-container.img +- ./$(MKIMG) -soc IMX9 -append $(AHAB_IMG) -c -ap $(SPL_A55_IMG) a55 $(SPL_LOAD_ADDR) -out flash.bin ++ ./$(MKIMG) -soc IMX9 -append $(AHAB_IMG) -c -ap $(SPL_A55_IMG) a55 $(SPL_LOAD_ADDR) -out flash.bin | tee -a $(MKIMAGE_LOG) + $(call append_container,u-boot-atf-container.img,1) + + flash_singleboot_no_ahabfw: $(MKIMG) $(SPL_A55_IMG) u-boot-atf-container.img diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-boot_1.0.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-boot_1.0.bbappend index fad1a49d0..6ee203005 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-boot_1.0.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-boot_1.0.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2024 Digi International Inc. +# Copyright (C) 2022-2024, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/files:" @@ -8,15 +8,19 @@ SRC_URI:append:ccimx8m = " \ file://0003-LFU-573-1-imx8m-Generate-hash-of-FIT-FDT-structure-t.patch \ file://0004-LFU-573-2-imx8m-Reserve-new-IVT-CSF-for-FIT-FDT-sign.patch \ " - +SRC_URI:append:ccimx91 = " \ + file://0001-imx91-soc.mak-capture-commands-output-into-a-log-fil.patch \ +" SRC_URI:append:ccimx93 = " \ file://0001-imx9-soc.mak-capture-commands-output-into-a-log-file.patch \ file://0002-imx9-soc.mak-add-makefile-target-to-build-A0-revisio.patch \ " # Use NXP's lf-6.1.55-2.2.0 release for ccimx93 -SRC_URI:ccimx93 = "git://github.com/nxp-imx/imx-mkimage.git;protocol=https;branch=${SRCBRANCH}" +SRC_URI:ccimx9 = "git://github.com/nxp-imx/imx-mkimage.git;protocol=https;branch=${SRCBRANCH}" +SRCBRANCH:ccimx91 = "lf-6.6.23_2.0.0" SRCBRANCH:ccimx93 = "lf-6.1.55_2.2.0" +SRCREV:ccimx91 = "ca5d6b2d3fd9ab15825b97f7ef6f1ce9a8644966" SRCREV:ccimx93 = "c4365450fb115d87f245df2864fee1604d97c06a" DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'trustfence-sign-tools-native', '', d)}" @@ -24,6 +28,11 @@ DEPENDS += "${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', 'trustfence-sign-too # Do not tag imx-boot UUU_BOOTLOADER = "" UUU_BOOTLOADER_TAGGED = "" +BOOT_STAGING:mx91-generic-bsp = "${S}/iMX91" +BOOT_STAGING:mx93-generic-bsp = "${S}/iMX9" + +# Add SOC family +SOC_FAMILY:mx91-generic-bsp = "mx91" REV_OPTION:ccimx93 = "REV=A1" @@ -46,6 +55,11 @@ compile_mx93:append:ccimx93() { fi } +compile_mx91() { + bbnote i.MX 91 boot binary build + compile_mx93 +} + do_compile:append:ccimx8m() { bbnote "building ${IMX_BOOT_SOC_TARGET} - print_fit_hab" make SOC=${IMX_BOOT_SOC_TARGET} dtbs=${UBOOT_DTB_NAME} print_fit_hab @@ -83,6 +97,10 @@ do_install:ccimx8x () { done } +deploy_mx91() { + deploy_mx93 +} + generate_symlinks() { # imx-boot recipe in meta-freescale supports *multiple* build configurations. # We assume here only ONE build configuration for our platforms (otherwise @@ -102,6 +120,13 @@ do_deploy:append:ccimx8m() { install -m 0644 ${BOOT_STAGING}/mkimage-print_fit_hab.log ${DEPLOYDIR}/${BOOT_TOOLS} } +do_deploy:append:ccimx91() { + generate_symlinks + for target in ${IMXBOOT_TARGETS}; do + install -m 0644 ${BOOT_STAGING}/mkimage-${target}.log ${DEPLOYDIR}/${BOOT_TOOLS} + done +} + do_deploy:append:ccimx93() { generate_symlinks for target in ${IMXBOOT_TARGETS}; do diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-mkimage_git.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-mkimage_git.bbappend index 321037dc0..e9f50892d 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-mkimage_git.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-mkimage/imx-mkimage_git.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2024 Digi International Inc. +# Copyright (C) 2022-2024, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/files:" @@ -6,10 +6,10 @@ SRC_URI:append:ccimx8m = " \ file://0001-imx8m-soc.mak-preserve-dtbs-after-build.patch \ " -# Use NXP's lf-6.1.55-2.2.0 release for ccimx93 -SRC_URI:ccimx93 = "git://github.com/nxp-imx/imx-mkimage.git;protocol=https;branch=${SRCBRANCH}" -SRCBRANCH:ccimx93 = "lf-6.1.55_2.2.0" -SRCREV:ccimx93 = "c4365450fb115d87f245df2864fee1604d97c06a" +# Use NXP's lf-6.1.55-2.2.0 release for ccimx9 +SRC_URI:ccimx9 = "git://github.com/nxp-imx/imx-mkimage.git;protocol=https;branch=${SRCBRANCH}" +SRCBRANCH:ccimx9 = "lf-6.1.55_2.2.0" +SRCREV:ccimx9 = "c4365450fb115d87f245df2864fee1604d97c06a" # "fmacro-prefix-map" is not supported on old versions of GCC DEBUG_PREFIX_MAP:remove:class-nativesdk = "-fmacro-prefix-map=${WORKDIR}=/usr/src/debug/${PN}/${EXTENDPE}${PV}-${PR}" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-secure-enclave/imx-secure-enclave_git.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-secure-enclave/imx-secure-enclave_git.bb index eaebcf79a..57f6984c6 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-secure-enclave/imx-secure-enclave_git.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-secure-enclave/imx-secure-enclave_git.bb @@ -1,4 +1,4 @@ -# Copyright 2021-2022 NXP +# Copyright 2021-2024 NXP SUMMARY = "NXP i.MX SECURE ENCLAVE library" DESCRIPTION = "NXP IMX SECURE ENCLAVE library" @@ -25,4 +25,4 @@ do_install () { oe_runmake DESTDIR=${D} install_tests } -COMPATIBLE_MACHINE = "(mx8ulp-nxp-bsp|mx93-nxp-bsp)" +COMPATIBLE_MACHINE = "(mx8ulp-nxp-bsp|mx91-nxp-bsp|mx93-nxp-bsp)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-test/imx-test_git.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-test/imx-test_git.bbappend index 23d9b0e9d..ac9c768b8 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-test/imx-test_git.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-bsp/imx-test/imx-test_git.bbappend @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Digi International Inc. +# Copyright (C) 2023, Digi International Inc. DEPENDS:append:mx9-nxp-bsp = " imx-lib" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-core/udev/udev-rules-imx.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-core/udev/udev-rules-imx.bbappend index 968213bcc..3e277351f 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-core/udev/udev-rules-imx.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-core/udev/udev-rules-imx.bbappend @@ -1,3 +1,3 @@ -# Copyright (C) 2013-2021 Digi International. +# Copyright (C) 2013-2021, Digi International Inc. # Update 10-imx.rules FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-devtools/imx-usb-loader/imx-usb-loader_git.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-devtools/imx-usb-loader/imx-usb-loader_git.bbappend index c9ce7846a..b8fa123c8 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-devtools/imx-usb-loader/imx-usb-loader_git.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-devtools/imx-usb-loader/imx-usb-loader_git.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2019 Digi International. +# Copyright (C) 2019, Digi International Inc. # The most recent version of this tool is unable to boot closed devices. # Revert to the version that was used in DEY 2.4. diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/drm/libdrm_2.4.115.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/drm/libdrm_2.4.115.imx.bb index 19e42613d..76b3bc580 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/drm/libdrm_2.4.115.imx.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/drm/libdrm_2.4.115.imx.bb @@ -19,7 +19,7 @@ SRCREV = "0f889a1f9640f6210132dd565141eb19005245fb" S = "${WORKDIR}/git" DEFAULT_PREFERENCE = "-1" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" inherit meson pkgconfig manpages diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-g2d-samples_git.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-g2d-samples_git.bbappend index 9d9ee37f4..242d0948a 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-g2d-samples_git.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-g2d-samples_git.bbappend @@ -1,4 +1,4 @@ -# Copyright 2023, 2024 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. SRCREV:mx93-nxp-bsp = "4391dcda499870418bb38fe395c3cba0664c5bab" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-pxp-g2d_git.bbappend b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-pxp-g2d_git.bbappend index 55a5c18fb..439ac3e2f 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-pxp-g2d_git.bbappend +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-graphics/imx-g2d/imx-pxp-g2d_git.bbappend @@ -1,4 +1,4 @@ -# Copyright 2023, 2024 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. LIC_FILES_CHKSUM:ccimx93 = "file://LICENSE.txt;md5=2827219e81f28aba7c6a569f7c437fa7" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-kernel/linux/linux-imx-headers_6.1.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-kernel/linux/linux-imx-headers_6.1.bb index 7da3e1d78..cedc55810 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-kernel/linux/linux-imx-headers_6.1.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-kernel/linux/linux-imx-headers_6.1.bb @@ -1,4 +1,4 @@ -# Copyright 2023, 2024 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. # # Reuse meta-freescale's linux-imx-headers_5.15.bb @@ -11,4 +11,4 @@ SRCREV = "770c5fe2c1d1529fae21b7043911cd50c6cf087e" IMX_UAPI_HEADERS:remove = "isl29023.h" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.0.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.0.0.imx.bb index f4640b6e7..9d82e65df 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.0.0.imx.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.0.0.imx.bb @@ -1,4 +1,4 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. # # Reuse meta-freescale's optee-client_3.19.0.imx.bb diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.2.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.2.0.imx.bb new file mode 100644 index 000000000..b177ab20b --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-client_4.2.0.imx.bb @@ -0,0 +1,27 @@ +# Copyright (C) 2024, Digi International Inc. + +# +# Reuse meta-freescale's optee-client_3.19.0.imx.bb +# +require recipes-security/optee-imx/optee-client_3.19.0.imx.bb + +SRC_URI += "${@oe.utils.vartrue('TRUSTFENCE_FILE_BASED_ENCRYPT', 'file://tee-supplicant', '', d)}" +SRCBRANCH = "lf-6.6.23_2.0.0" +SRCREV = "3eac340a781c00ccd61b151b0e9c22a8c6e9f9f0" + +EXTRA_OEMAKE += "PKG_CONFIG=pkg-config CFG_TEE_FS_PARENT_PATH='${localstatedir}/lib/tee'" + +do_install() { + oe_runmake DESTDIR=${D} install + install -D -p -m0644 ${WORKDIR}/tee-supplicant.service ${D}${systemd_system_unitdir}/tee-supplicant.service + sed -i -e s:@sysconfdir@:${sysconfdir}:g \ + -e s:@sbindir@:${sbindir}:g \ + ${D}${systemd_system_unitdir}/tee-supplicant.service + + if ${@oe.utils.vartrue('TRUSTFENCE_FILE_BASED_ENCRYPT', 'true', 'false',d)}; then + install -d ${D}${sysconfdir}/default/ + install -m 0644 ${WORKDIR}/tee-supplicant ${D}${sysconfdir}/default/tee-supplicant + fi +} + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os/0001-core-imx-support-ccimx91-dvk.patch b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os/0001-core-imx-support-ccimx91-dvk.patch new file mode 100644 index 000000000..5596e79ad --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os/0001-core-imx-support-ccimx91-dvk.patch @@ -0,0 +1,46 @@ +From: Javier Viguera +Date: Mon, 19 Aug 2024 17:42:24 +0200 +Subject: [PATCH] core: imx: support ccimx91-dvk + +Signed-off-by: Javier Viguera +--- + core/arch/arm/plat-imx/conf.mk | 6 ++++++ + core/arch/arm/plat-imx/registers/imx93.h | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/core/arch/arm/plat-imx/conf.mk b/core/arch/arm/plat-imx/conf.mk +index 9ab3e1e95133..5128e9ee5e8e 100644 +--- a/core/arch/arm/plat-imx/conf.mk ++++ b/core/arch/arm/plat-imx/conf.mk +@@ -95,6 +95,7 @@ mx95-flavorlist = \ + mx95evk \ + + mx91-flavorlist = \ ++ ccimx91dvk \ + mx91evk \ + + ifneq (,$(filter $(PLATFORM_FLAVOR),$(mx6ul-flavorlist))) +@@ -491,6 +492,11 @@ CFG_DDR_SIZE ?= 0x80000000 + CFG_UART_BASE ?= UART1_BASE + endif + ++ifneq (,$(filter $(PLATFORM_FLAVOR),ccimx91dvk)) ++CFG_DDR_SIZE ?= 0x20000000 ++CFG_UART_BASE ?= UART6_BASE ++endif ++ + ifneq (,$(filter $(PLATFORM_FLAVOR),mx95evk)) + CFG_DDR_SIZE ?= 0x80000000 + CFG_UART_BASE ?= UART1_BASE +diff --git a/core/arch/arm/plat-imx/registers/imx93.h b/core/arch/arm/plat-imx/registers/imx93.h +index 21080da82d04..17f4d8f5755e 100644 +--- a/core/arch/arm/plat-imx/registers/imx93.h ++++ b/core/arch/arm/plat-imx/registers/imx93.h +@@ -9,6 +9,7 @@ + #define GICR_BASE 0x48040000 + + #define UART1_BASE 0x44380000 ++#define UART6_BASE 0x425a0000 + /* + * For Normal MU - Use MU_BASE as 0x47520000 + * For Trust MU - Use MU_BASE as 0x47530000 diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.0.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.0.0.imx.bb index 2338caf72..a3ad4a10b 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.0.0.imx.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.0.0.imx.bb @@ -1,4 +1,4 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. # # Reuse meta-freescale's optee-os_3.19.0.imx.bb diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.2.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.2.0.imx.bb new file mode 100644 index 000000000..ce9b5b7a8 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-os_4.2.0.imx.bb @@ -0,0 +1,27 @@ +# Copyright (C) 2024, Digi International Inc. + +# +# Reuse meta-freescale's optee-os_3.19.0.imx.bb +# +require recipes-security/optee-imx/optee-os_3.19.0.imx.bb + +SRC_URI = " \ + git://github.com/nxp-imx/imx-optee-os.git;protocol=https;branch=${SRCBRANCH} \ + file://0007-allow-setting-sysroot-for-clang.patch \ + file://0001-core-imx-support-ccimx91-dvk.patch \ + file://environment.d-optee-sdk.sh \ +" +SRCBRANCH = "lf-6.6.23_2.0.0" +# Tag: lf-6.6.23-2.0.0 +SRCREV = "c6be5b572452a2808d1a34588fd10e71715e23cf" + +PLATFORM_FLAVOR:ccimx91 = "ccimx91dvk" + +do_install:append:ccimx91 () { + mkdir -p ${D}/environment-setup.d + sed -e "s,#OPTEE_ARCH#,${OPTEE_ARCH},g" ${WORKDIR}/environment.d-optee-sdk.sh > ${D}/environment-setup.d/optee-sdk.sh +} + +FILES:${PN}-staticdev += "/environment-setup.d/" + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.0.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.0.0.imx.bb index 515dc1743..6653c2d9f 100644 --- a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.0.0.imx.bb +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.0.0.imx.bb @@ -1,4 +1,4 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. # # Reuse meta-freescale's optee-test_3.19.0.imx.bb diff --git a/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.2.0.imx.bb b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.2.0.imx.bb new file mode 100644 index 000000000..25380673b --- /dev/null +++ b/meta-digi-arm/dynamic-layers/freescale-layer/recipes-security/optee-imx/optee-test_4.2.0.imx.bb @@ -0,0 +1,13 @@ +# Copyright (C) 2024, Digi International Inc. + +# +# Reuse meta-freescale's optee-test_3.19.0.imx.bb +# +require recipes-security/optee-imx/optee-test_3.19.0.imx.bb + +DEPENDS += "openssl" + +SRCBRANCH = "lf-6.6.23_2.0.0" +SRCREV = "07682f1b1b41ec0bfa507286979b36ab8d344a96" + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/drivers/gcnano-driver-stm32mp.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/drivers/gcnano-driver-stm32mp.inc new file mode 100644 index 000000000..67dfab2b5 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/drivers/gcnano-driver-stm32mp.inc @@ -0,0 +1,14 @@ +COMPATIBLE_MACHINE = "(stm32mpcommon)" + +inherit module + +# todo manage android build (sync) +EXTRA_OEMAKE = "KERNEL_DIR=${STAGING_KERNEL_BUILDDIR}" +EXTRA_OEMAKE:append:stm32mp1common = " SOC_PLATFORM=st-mp1" +EXTRA_OEMAKE:append:stm32mp2common = " SOC_PLATFORM=st-mp2" +# Use DEBUG=1 for more traces and easier debug +EXTRA_OEMAKE:append = " DEBUG=0" +EXTRA_OEMAKE:append = " -C ${STAGING_KERNEL_BUILDDIR} M=${S}" +EXTRA_OEMAKE:append = " AQROOT=${S}" + +do_create_runtime_spdx[depends] += "virtual/kernel:do_create_runtime_spdx" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/drivers/gcnano-driver-stm32mp_6.4.15.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/drivers/gcnano-driver-stm32mp_6.4.15.bb new file mode 100644 index 000000000..1d50feca8 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/drivers/gcnano-driver-stm32mp_6.4.15.bb @@ -0,0 +1,25 @@ +SUMMARY = "GCNano kernel drivers" +LICENSE = "GPL-1.0-only & MIT" +# Note get md5sum with: $ head -n 53 Makefile | md5sum +LIC_FILES_CHKSUM = "file://Makefile;endline=53;md5=85a35fecd70aaa9c4047554f71e1407d" + +SRC_URI = "git://github.com/STMicroelectronics/gcnano-binaries;protocol=https;branch=gcnano-${GCNANO_VERSION}-binaries" +SRCREV = "bbaae49a0e4859ed53f898a250269c8a237261bc" + +GCNANO_VERSION = "6.4.15" +GCNANO_SUBVERSION:stm32mp1common = "stm32mp1" +GCNANO_SUBVERSION:stm32mp2common = "stm32mp2" +GCNANO_RELEASE = "r1" + +PV = "${GCNANO_VERSION}-${GCNANO_SUBVERSION}-${GCNANO_RELEASE}" + +S = "${WORKDIR}/git/${BPN}" + +include gcnano-driver-stm32mp.inc + +# --------------------------------- +# Configure archiver use +# --------------------------------- +include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'gcnano-driver-stm32mp-archiver.inc','')} + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2-common.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2-common.inc new file mode 100644 index 000000000..a118981d3 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2-common.inc @@ -0,0 +1,36 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/tf-a-stm32mp:" + +SECTION = "bootloaders" + +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031" +CVE_PRODUCT = "arm:trusted_firmware-a" + +SRC_URI = "git://git.trustedfirmware.org/TF-A/trusted-firmware-a.git;protocol=http;branch=lts-v2.8" +SRCREV = "f94d6db9b101d3d4cd053e54edd5b876f1cc84ec" + +SRC_URI += " \ + file://tf-a-st-ddr.tar.gz;subdir=git;name=fw \ + file://0001-v2.8-stm32mp25-beta.patch \ + " + +SRC_URI[fw.sha256sum] = "c87d8a03a8feab1f8a51818a7942deade5d31abb7f4afaa6d6dfa922383e9805" + +TF_A_VERSION = "v2.8.12" +TF_A_SUBVERSION = "stm32mp" +TF_A_RELEASE = "beta-r1" +PV = "${TF_A_VERSION}-${TF_A_SUBVERSION}-${TF_A_RELEASE}" + +ARCHIVER_ST_BRANCH = "${TF_A_VERSION}-${TF_A_SUBVERSION}" +ARCHIVER_ST_REVISION = "${PV}" +ARCHIVER_COMMUNITY_BRANCH = "master" +ARCHIVER_COMMUNITY_REVISION = "${TF_A_VERSION}" + +S = "${WORKDIR}/git" + +# --------------------------------- +# Configure default preference to manage dynamic selection between tarball and github +# --------------------------------- +STM32MP_SOURCE_SELECTION ?= "tarball" + +DEFAULT_PREFERENCE = "${@bb.utils.contains('STM32MP_SOURCE_SELECTION', 'github', '-1', '1', d)}" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2-config.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2-config.inc new file mode 100644 index 000000000..64a42bfbc --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2-config.inc @@ -0,0 +1,19 @@ +# Define config for each TF_A_CONFIG +# TF_A_CONFIG[config] ?= ",,,," + +TF_A_OPTEE_param:stm32mp1common = "AARCH32_SP=optee" +TF_A_OPTEE_param:stm32mp2common = "SPD=opteed" + +TF_A_CONFIG[optee] ?= "${STM32MP_DEVICETREE},${TF_A_OPTEE_param},,${@bb.utils.contains('FIP_BL31_ENABLE', '1', 'bl31 dtbs', 'dtbs', d)},${@bb.utils.contains('FIP_BL31_ENABLE', '1', 'bl31 fwconfig', 'fwconfig', d)}" + +TF_A_CONFIG[emmc] ?= "${DEVICE_BOARD_ENABLE:EMMC},STM32MP_EMMC=1 ${@bb.utils.contains('MACHINE_FEATURES', 'fw-update', 'PSA_FWU_SUPPORT=1', '', d)}" +TF_A_CONFIG[nand] ?= "${DEVICE_BOARD_ENABLE:NAND},STM32MP_RAW_NAND=1 ${@bb.utils.contains('MACHINE_FEATURES', 'fw-update', 'PSA_FWU_SUPPORT=1', '', d)} ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_NAND}' if ${TF_A_MTD_START_OFFSET_NAND} else ''}" +TF_A_CONFIG[nor] ?= "${DEVICE_BOARD_ENABLE:NOR},STM32MP_SPI_NOR=1 ${@bb.utils.contains('MACHINE_FEATURES', 'fw-update', 'PSA_FWU_SUPPORT=1', '', d)} ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_NOR}' if ${TF_A_MTD_START_OFFSET_NOR} else ''}" +TF_A_CONFIG[sdcard] ?= "${DEVICE_BOARD_ENABLE:SDCARD},STM32MP_SDMMC=1 ${@bb.utils.contains('MACHINE_FEATURES', 'fw-update', 'PSA_FWU_SUPPORT=1', '', d)}" +TF_A_CONFIG[spinand] ?= "${DEVICE_BOARD_ENABLE:SPINAND},STM32MP_SPI_NAND=1 ${@bb.utils.contains('MACHINE_FEATURES', 'fw-update', 'PSA_FWU_SUPPORT=1', '', d)} ${@'STM32MP_FORCE_MTD_START_OFFSET=${TF_A_MTD_START_OFFSET_SPINAND}' if ${TF_A_MTD_START_OFFSET_SPINAND} else ''}" +TF_A_CONFIG[uart] ?= "${STM32MP_DEVICETREE},STM32MP_UART_PROGRAMMER=1" +TF_A_CONFIG[usb] ?= "${STM32MP_DEVICETREE},STM32MP_USB_PROGRAMMER=1" + +# Define configuration for SSP +TF_A_CONFIG[uart-ssp] ?= "${STM32MP_DEVICETREE},STM32MP_UART_PROGRAMMER=1 STM32MP_SSP=1,tf-a-ssp" +TF_A_CONFIG[usb-ssp] ?= "${STM32MP_DEVICETREE},STM32MP_USB_PROGRAMMER=1 STM32MP_SSP=1,tf-a-ssp" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2.inc new file mode 100644 index 000000000..9ad148a23 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp2.inc @@ -0,0 +1,603 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/tf-a-stm32mp:" + +PROVIDES += "virtual/trusted-firmware-a" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +inherit deploy +#inherit sign-stm32mp +inherit fip-utils-stm32mp2 +#inherit external-dt + + +STAGING_EXTDT_DIR = "${TMPDIR}/work-shared/${MACHINE}/external-dt" + +# Include TF-A config definitions +require tf-a-stm32mp2-config.inc + +# ------------------------------------ +# Set MBEDTLS support +TFA_MBEDTLS_DIR ?= "mbedtls" +# MBEDTLS v2.28.5 +SRC_URI_MBEDTLS = "git://github.com/ARMmbed/mbedtls.git;protocol=https;destsuffix=git/${TFA_MBEDTLS_DIR};branch=mbedtls-2.28;name=mbedtls" +SRCREV_mbedtls = "47e8cc9db2e469d902b0e3093ae9e482c3d87188" +LIC_FILES_CHKSUM_MBEDTLS = "file://mbedtls/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" +LICENSE_MBEDTLS = "Apache-2.0" +# Add MBEDTLS to our sources +SRC_URI:append = " ${@bb.utils.contains('SIGN_ENABLE', '1', '${SRC_URI_MBEDTLS}', '', d)}" +# Update license variables +LICENSE:append = "${@bb.utils.contains('SIGN_ENABLE', '1', ' & ${LICENSE_MBEDTLS}', '', d)}" +LIC_FILES_CHKSUM:append = "${@bb.utils.contains('SIGN_ENABLE', '1', ' ${LIC_FILES_CHKSUM_MBEDTLS}', '', d)}" +# Add mbed TLS to version +SRCREV_FORMAT:append = "${@bb.utils.contains('SIGN_ENABLE', '1', '_mbedtls', '', d)}" +# ------------------------------------ + +B = "${WORKDIR}/build" +# Configure build dir for externalsrc class usage through devtool +EXTERNALSRC_BUILD:pn-${PN} = "${WORKDIR}/build" + +DEPENDS += "dtc-native openssl-native" +DEPENDS:append = " ${@bb.utils.contains('TF_A_ENABLE_DEBUG_WRAPPER', '1', 'stm32wrapper4dbg-native', '', d)}" + +# Default log level +ST_TF_A_DEBUG ??= "1" +ST_TF_A_DEBUG_TRACE ??= "0" +ST_TF_A_LOG_LEVEL_RELEASE ??= "20" +ST_TF_A_LOG_LEVEL_DEBUG ??= "40" + +# Configure make settings +EXTRA_OEMAKE += 'PLAT=${TFA_PLATFORM}' +EXTRA_OEMAKE += 'ARCH=${TFA_ARM_ARCH}' +EXTRA_OEMAKE += 'ARM_ARCH_MAJOR=${TFA_ARM_MAJOR}' +EXTRA_OEMAKE += 'CROSS_COMPILE=${TARGET_PREFIX}' +# Debug support +EXTRA_OEMAKE += "${@bb.utils.contains('ST_TF_A_DEBUG_TRACE', '1', 'DEBUG=${ST_TF_A_DEBUG}', '', d)}" +EXTRA_OEMAKE += "${@bb.utils.contains('ST_TF_A_DEBUG_TRACE', '1', 'LOG_LEVEL=${ST_TF_A_LOG_LEVEL_DEBUG}', 'LOG_LEVEL=${ST_TF_A_LOG_LEVEL_RELEASE}', d)}" +EXTRA_OEMAKE += "${@bb.utils.contains('EXTERNAL_DT_ENABLED', '1', 'TFA_EXTERNAL_DT=${STAGING_EXTDT_DIR}/tf-a', '', d)}" +# OPTEE in sysram +EXTRA_OEMAKE:append:stm32mp1common = " ${@bb.utils.contains('ST_OPTEE_IN_SYSRAM', '1', 'STM32MP1_OPTEE_IN_SYSRAM=1', '', d)}" + +# Define default TF-A namings +TF_A_BASENAME ?= "tf-a" +TF_A_SUFFIX ?= "stm32" + +# Output the ELF generated +ELF_DEBUG_ENABLE ?= "" +TF_A_ELF_SUFFIX = "elf" + +BL1_NAME ?= "bl1/bl1" +BL1_ELF = "${BL1_NAME}.${TF_A_ELF_SUFFIX}" +BL1_BASENAME = "${@os.path.basename(d.getVar("BL1_NAME"))}" +BL1_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL1_NAME"))}" + +BL2_NAME ?= "bl2/bl2" +BL2_ELF = "${BL2_NAME}.${TF_A_ELF_SUFFIX}" +BL2_BASENAME = "${@os.path.basename(d.getVar("BL2_NAME"))}" +BL2_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL2_NAME"))}" + +BL31_NAME ?= "bl31/bl31" +BL31_ELF = "${BL31_NAME}.${TF_A_ELF_SUFFIX}" +BL31_BASENAME = "${@os.path.basename(d.getVar("BL31_NAME"))}" +BL31_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL31_NAME"))}" +BL31_SUFFIX ?= "bin" + +BL32_NAME ?= "bl32/bl32" +BL32_ELF = "${BL32_NAME}.${TF_A_ELF_SUFFIX}" +BL32_BASENAME = "${@os.path.basename(d.getVar("BL32_NAME"))}" +BL32_BASENAME_DEPLOY ?= "${@os.path.basename(d.getVar("BL32_NAME"))}" +BL32_SUFFIX ?= "bin" + +DT_SUFFIX ?= "dtb" +FWCONFIG_NAME ?= "fw-config" + +# Output the firwmare ddr +TF_A_FWDDR ?= "0" +TF_A_FWDDR:stm32mp25common = "1" + +FWDDR_NAME ?= "ddr_pmu" +FWDDR_SUFFIX ?= "bin" + +# Set default TF-A config +TF_A_CONFIG ?= "" + +# Enable the wrapper for debug +TF_A_ENABLE_DEBUG_WRAPPER ??= "1" + +# Set default configuration to allow signing +TF_A_SIGN_SUFFIX ??= "${@bb.utils.contains('SIGN_ENABLE', '1', '${SIGN_SUFFIX}', '', d)}" +TF_A_SIGN_OF ?= "0x00000001" +TF_A_SIGN_OF:stm32mp1common ?= "0x00000001" +TF_A_SIGN_OF:stm32mp25common ?= "0x00000001" +TF_A_SIGN_OF:stm32mp25revabcommon ?= "0x00000001" + +TF_A_ENCRYPT_SUFFIX ??= "${@bb.utils.contains('ENCRYPT_ENABLE', '1', '${ENCRYPT_SUFFIX}', '', d)}" +TF_A_ENCRYPT_DC ?= "0x0E5F2025" +TF_A_ENCRYPT_DC:stm32mp1common ?= "0x0E5F2025" +TF_A_ENCRYPT_DC:stm32mp25common ?= "0x25205f0e" +TF_A_ENCRYPT_DC:stm32mp25revabcommon ?= "0x25205f0e" + +TF_A_ENCRYPT_IMGVER ?= "0" +TF_A_ENCRYPT_OF ?= "0x80000003" +TF_A_ENCRYPT_OF:stm32mp1common ?= "0x80000003" +TF_A_ENCRYPT_OF:stm32mp2common ?= "0x10000003" + + +# Set metadata generation +TF_A_ENABLE_METADATA ??= "${@bb.utils.contains('MACHINE_FEATURES', 'fw-update', '1', '0', d)}" +TF_A_METADATA_NAME ?= "metadata" +TF_A_METADATA_SUFFIX ?= "bin" +TF_A_METADATA_BINARY ??= "${TF_A_METADATA_NAME}.${TF_A_METADATA_SUFFIX}" + +TF_A_METADATA_TOOL ?= "tools/fwu_gen_metadata/fwumd_tool.py" +TF_A_METADATA_JSON ?= "plat/st/common/default_metadata.json" + +# Configure specific build flags +EXTRA_OEMAKE += "${@bb.utils.contains('SIGN_ENABLE', '1', 'TRUSTED_BOARD_BOOT=1', '', d)}" +EXTRA_OEMAKE += "${@bb.utils.contains('SIGN_ENABLE', '1', 'MBEDTLS_DIR=${TFA_MBEDTLS_DIR}', '', d)}" +EXTRA_OEMAKE:append:stm32mp2common = " ${@bb.utils.contains('SIGN_ENABLE', '1', 'BRANCH_PROTECTION=0', '', d)} " + +EXTRA_OEMAKE += "${@bb.utils.contains('ENCRYPT_ENABLE', '1', 'DECRYPTION_SUPPORT=aes_gcm ENCRYPT_BL32=1', '', d)}" +EXTRA_OEMAKE += "${@bb.utils.contains('ENCRYPT_ENABLE', '1', bb.utils.contains('FIP_BL31_ENABLE', '1', 'ENCRYPT_BL31=1', '', d), '', d)} " + +# Addons parameters for SIGN_TOOL +SIGN_TOOL_EXTRA ?= "" +SIGN_TOOL_EXTRA:stm32mp25common = "--header-version 2" +SIGN_TOOL_EXTRA:stm32mp25revabcommon = "--header-version 2" + +# Specific for revA board +EXTRA_OEMAKE:append:stm32mp25revabcommon = " CONFIG_STM32MP25X_REVA=1 " + +# ----------------------------------------------- +# Handle TF-A config and set internal vars +# TF_A_DEVICETREE +# TF_A_EXTRA_OPTFLAGS +python () { + import re + + tfaconfigflags = d.getVarFlags('TF_A_CONFIG') + # The "doc" varflag is special, we don't want to see it here + tfaconfigflags.pop('doc', None) + tfaconfig = (d.getVar('TF_A_CONFIG') or "").split() + tfabasename = d.getVar('TF_A_BASENAME') + + if not tfaconfig: + raise bb.parse.SkipRecipe("TF_A_CONFIG must be set in the %s machine configuration." % d.getVar("MACHINE")) + if (d.getVar('TF_A_DEVICETREE') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_DEVICETREE as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_EXTRA_OPTFLAGS') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_EXTRA_OPTFLAGS as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_BINARIES') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_BINARIES as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_MAKE_TARGET') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_MAKE_TARGET as it is internal to TF_A_CONFIG var expansion.") + if (d.getVar('TF_A_FILES') or "").split(): + raise bb.parse.SkipRecipe("You cannot use TF_A_FILES as it is internal to TF_A_CONFIG var expansion.") + + if len(tfaconfig) > 0: + for config in tfaconfig: + for f, v in tfaconfigflags.items(): + if config == f: + # Make sure to get var flag properly expanded + v = d.getVarFlag('TF_A_CONFIG', config) + if not v.strip(): + bb.fatal('[TF_A_CONFIG] Missing configuration for %s config' % config) + items = v.split(',') + if items[0] and len(items) > 5: + raise bb.parse.SkipRecipe('Only ,,,, can be specified!') + # Set internal vars + bb.debug(1, "Appending '%s' to TF_A_DEVICETREE" % items[0]) + d.appendVar('TF_A_DEVICETREE', items[0] + ',') + if len(items) > 1 and items[1]: + bb.debug(1, "Appending '%s' to TF_A_EXTRA_OPTFLAGS." % items[1]) + d.appendVar('TF_A_EXTRA_OPTFLAGS', items[1] + ',') + else: + d.appendVar('TF_A_EXTRA_OPTFLAGS', '' + ',') + if len(items) > 2 and items[2]: + bb.debug(1, "Appending '%s' to TF_A_BINARIES." % items[2]) + d.appendVar('TF_A_BINARIES', items[2] + ',') + else: + bb.debug(1, "Appending '%s' to TF_A_BINARIES." % tfabasename) + d.appendVar('TF_A_BINARIES', tfabasename + ',') + if len(items) > 3 and items[3]: + bb.debug(1, "Appending '%s' to TF_A_MAKE_TARGET." % items[3]) + d.appendVar('TF_A_MAKE_TARGET', items[3] + ',') + else: + d.appendVar('TF_A_MAKE_TARGET', 'all' + ',') + if len(items) > 4 and items[4]: + bb.debug(1, "Appending '%s' to TF_A_FILES." % items[4]) + d.appendVar('TF_A_FILES', items[4] + ',') + else: + d.appendVar('TF_A_FILES', 'bl2' + ',') + break + + # Manage case of signature: + if d.getVar('SIGN_ENABLE') == "1": + # If signature are activated, for winning space, the debug parameter will be remove and level of trace decrease + if d.getVar('ST_TF_A_DEBUG_TRACE') == '1': + bb.warn("TF-A SIGNATURE: force ST_TF_A_DEBUG_TRACE to '0' to disable DEBUG and decrease log level") + d.setVar('ST_TF_A_DEBUG_TRACE', "0") +} + +# ----------------------------------------------- +# Enable use of work-shared folder +TFA_SHARED_SOURCES ??= "1" +STAGING_TFA_DIR = "${TMPDIR}/work-shared/${MACHINE}/tfa-source" +# Make sure to move ${S} to STAGING_TFA_DIR. We can't just +# create the symlink in advance as the git fetcher can't cope with +# the symlink. +do_unpack[cleandirs] += "${S}" +do_unpack[cleandirs] += "${@bb.utils.contains('TFA_SHARED_SOURCES', '1', '${STAGING_TFA_DIR}', '', d)}" +do_clean[cleandirs] += "${S}" +do_clean[cleandirs] += "${@bb.utils.contains('TFA_SHARED_SOURCES', '1', '${STAGING_TFA_DIR}', '', d)}" +base_do_unpack:append () { + # Specific part to update devtool-source class + if bb.data.inherits_class('devtool-source', d): + # We don't want to move the source to STAGING_TFA_DIR here + if d.getVar('STAGING_TFA_DIR', d): + d.setVar('STAGING_TFA_DIR', '${S}') + + shared = d.getVar("TFA_SHARED_SOURCES") + if shared and oe.types.boolean(shared): + # Copy/Paste from kernel class with adaptation to TFA var + s = d.getVar("S") + if s[-1] == '/': + # drop trailing slash, so that os.symlink(tfasrc, s) doesn't use s as directory name and fail + s=s[:-1] + tfasrc = d.getVar("STAGING_TFA_DIR") + if s != tfasrc: + bb.utils.mkdirhier(tfasrc) + bb.utils.remove(tfasrc, recurse=True) + if d.getVar("EXTERNALSRC"): + # With EXTERNALSRC S will not be wiped so we can symlink to it + os.symlink(s, tfasrc) + else: + import shutil + shutil.move(s, tfasrc) + os.symlink(tfasrc, s) +} + +do_compile() { + unset LDFLAGS + unset CFLAGS + unset CPPFLAGS + + unset i + for config in ${TF_A_CONFIG}; do + i=$(expr $i + 1) + # Initialize devicetree list, extra make options and tf-a basename + dt_config=$(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) + extra_opt=$(echo ${TF_A_EXTRA_OPTFLAGS} | cut -d',' -f${i}) + tfa_basename=$(echo ${TF_A_BINARIES} | cut -d',' -f${i}) + tf_a_make_target=$(echo ${TF_A_MAKE_TARGET} | cut -d',' -f${i}) + for dt in ${dt_config}; do + # Init specific soc settings + soc_extra_opt="" + soc_suffix="" + if [ -n "${STM32MP_SOC_NAME}" ]; then + for soc in ${STM32MP_SOC_NAME}; do + if [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ]; then + soc_extra_opt="$(echo ${soc} | awk '{print toupper($0)}')=1" + soc_suffix="-${soc}" + fi + done + fi + mkdir -p ${B}/${config}${soc_suffix} + if [ "${TF_A_ENABLE_METADATA}" = "1" ]; then + ${S}/${TF_A_METADATA_TOOL} jsonparse "${S}/${TF_A_METADATA_JSON}" -b "${B}/${config}${soc_suffix}/${TF_A_METADATA_NAME}.${TF_A_METADATA_SUFFIX}" + fi + + # Init specific ddr settings + ddr_extra_opt="" + if [ "${TF_A_FWDDR}" = "1" ]; then + # Detect ddr type if it's present + oe_runmake -C "${S}" BUILD_PLAT="${B}/${config}${soc_suffix}-${dt}" DTB_FILE_NAME="${dt}.dtb" ${extra_opt} ${soc_extra_opt} dtbs + if [ -f "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-bl2.dtb" ]; then + ddr_dtb_node=$(${STAGING_BINDIR_NATIVE}/fdtget -l ${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-bl2.dtb /soc | grep ddr | head -n 1) + ddr_propertie=$(${STAGING_BINDIR_NATIVE}/fdtget ${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-bl2.dtb /soc/${ddr_dtb_node} st,mem-name || echo "none") + ddr_target="" + # potentials value of ddr_propertie: + # DDR3 16bits + # DDR4 32bits + # DDR4 8Gbits + # LPDDR4 32bits + case ${ddr_propertie} in + DDR3*) + ddr_extra_opt=" STM32MP_DDR3_TYPE=1 " + ddr_target="ddr3" + ;; + DDR4*) + ddr_extra_opt=" STM32MP_DDR4_TYPE=1 " + ddr_target="ddr4" + ;; + LPDDR4*) + ddr_extra_opt=" STM32MP_LPDDR4_TYPE=1 " + ddr_target="lpddr4" + ;; + *) + bbwarn "Missing st,mem-name information for ${dt}" + ;; + esac + bbnote "${dt}: ${tf_a_make_target} -> ${ddr_extra_opt}" + # Copy TF-A ddr binary with explicit devicetree filename + if [ -n "${ddr_target}" ]; then + if [ -s "${S}/drivers/st/ddr/phy/firmware/bin/${ddr_target}_pmu_train.bin" ]; then + cp "${S}/drivers/st/ddr/phy/firmware/bin/${ddr_target}_pmu_train.bin" "${B}/${config}${soc_suffix}-${dt}/${FWDDR_NAME}-${dt}.${FWDDR_SUFFIX}" + else + bbwarn "Missing ddr firmware file ${ddr_target}_pmu_train.bin for ${dt}" + fi + fi + fi + fi + + encrypt_extra_opt="" + if [ "${ENCRYPT_ENABLE}" = "1" ]; then + encrypt_key="${ENCRYPT_FIP_KEY_PATH_LIST}" + if [ -n "${STM32MP_ENCRYPT_SOC_NAME}" ]; then + unset k + for soc in ${STM32MP_ENCRYPT_SOC_NAME}; do + k=$(expr $k + 1) + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && encrypt_key=$(echo ${ENCRYPT_FIP_KEY_PATH_LIST} | cut -d',' -f${k}) + done + fi + encrypt_extra_opt="ENC_KEY=$(hexdump -e '/1 "%02x"' ${encrypt_key})" + fi + + oe_runmake -C "${S}" BUILD_PLAT="${B}/${config}${soc_suffix}-${dt}" DTB_FILE_NAME="${dt}.dtb" ${extra_opt} ${soc_extra_opt} ${ddr_extra_opt} ${encrypt_extra_opt} ${tf_a_make_target} + + # Copy TF-A binary with explicit devicetree filename + if [ -f "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}.${TF_A_SUFFIX}" ]; then + cp "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}.${TF_A_SUFFIX}" "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" + if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then + stm32wrapper4dbg -s "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}.${TF_A_SUFFIX}" -d "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" + fi + + if [ "${SIGN_ENABLE}" = "1" ]; then + # Init sign key for signing tools + sign_key="${SIGN_KEY_PATH_LIST}" + if [ -n "${STM32MP_SOC_NAME}" ]; then + unset k + for soc in ${STM32MP_SOC_NAME}; do + k=$(expr $k + 1) + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && sign_key=$(echo ${SIGN_KEY_PATH_LIST} | cut -d',' -f${k}) + done + fi + # Init default '-of' option for signing case + tf_a_sign_of_opt="" + dd if="${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" of=header.dump bs=1 count=4 skip=72 > /dev/null 2> /dev/null + temp_version=$(od -A o -t dI header.dump | head -n 1 | cut -d' ' -f2- | sed "s/ //g") + rm -f header.dump + [ "$(expr $temp_version / 65536)" = "2" ] && tf_a_sign_of_opt="-of ${TF_A_SIGN_OF}" + # Sign tf-a binary + echo "${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key ${sign_key} \ + --type fsbl \ + --silent \ + ${SIGN_TOOL_EXTRA} \ + ${tf_a_sign_of_opt}" + ${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key ${sign_key} \ + --type fsbl \ + --silent \ + ${SIGN_TOOL_EXTRA} \ + ${tf_a_sign_of_opt} + if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then + echo "${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key "${sign_key}" \ + --type fsbl \ + --silent \ + ${SIGN_TOOL_EXTRA} \ + ${tf_a_sign_of_opt}" + ${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key "${sign_key}" \ + --type fsbl \ + --silent \ + ${SIGN_TOOL_EXTRA} \ + ${tf_a_sign_of_opt} + fi + fi + + if [ "${ENCRYPT_ENABLE}" = "1" ]; then + # Init encrypt key for signing tools + encrypt_key="${ENCRYPT_FSBL_KEY_PATH_LIST}" + if [ -n "${STM32MP_ENCRYPT_SOC_NAME}" ]; then + unset k + for soc in ${STM32MP_ENCRYPT_SOC_NAME}; do + k=$(expr $k + 1) + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && encrypt_key=$(echo ${ENCRYPT_FSBL_KEY_PATH_LIST} | cut -d',' -f${k}) + done + fi + # Init default '-of' option for signing case + tf_a_sign_of_opt="" + dd if="${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" of=header.dump bs=1 count=4 skip=72 > /dev/null 2> /dev/null + temp_version=$(od -A o -t dI header.dump | head -n 1 | cut -d' ' -f2- | sed "s/ //g") + rm -f header.dump + [ "$(expr $temp_version / 65536)" = "2" ] && tf_a_sign_of_opt="-hv 2" + # Encrypt tf-a binary + echo '${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_ENCRYPT_SUFFIX}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key ${sign_key} \ + --type fsbl \ + --silent \ + --enc-key ${encrypt_key} \ + --enc-dc "${TF_A_ENCRYPT_DC}" \ + --image-version "${TF_A_ENCRYPT_IMGVER}" \ + -of "${TF_A_ENCRYPT_OF}" \ + ${tf_a_sign_of_opt} ' + ${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_ENCRYPT_SUFFIX}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key ${sign_key} \ + --type fsbl \ + --silent \ + --enc-key ${encrypt_key} \ + --enc-dc "${TF_A_ENCRYPT_DC}" \ + --image-version "${TF_A_ENCRYPT_IMGVER}" \ + -of "${TF_A_ENCRYPT_OF}" \ + ${tf_a_sign_of_opt} + if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then + echo '${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_ENCRYPT_SUFFIX}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key ${sign_key} \ + --type fsbl \ + --silent \ + --enc-key ${encrypt_key} \ + --enc-dc "${TF_A_ENCRYPT_DC}" \ + --image-version "${TF_A_ENCRYPT_IMGVER}" \ + -of "${TF_A_ENCRYPT_OF}" \ + ${tf_a_sign_of_opt}' + ${SIGN_TOOL} \ + -bin "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + -o "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_ENCRYPT_SUFFIX}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" \ + --password ${SIGN_KEY_PASS} \ + --public-key $(ls -1 $(dirname ${sign_key})/publicKey*.pem | tr '\n' '\t') \ + --private-key ${sign_key} \ + --type fsbl \ + --silent \ + --enc-key ${encrypt_key} \ + --enc-dc "${TF_A_ENCRYPT_DC}" \ + --image-version "${TF_A_ENCRYPT_IMGVER}" \ + -of "${TF_A_ENCRYPT_OF}"\ + ${tf_a_sign_of_opt} + fi + fi + fi + done + done + + if [ "${TF_A_ENABLE_METADATA}" = "1" ]; then + ${S}/${TF_A_METADATA_TOOL} jsonparse "${S}/${TF_A_METADATA_JSON}" -b "${B}/${TF_A_METADATA_NAME}.${TF_A_METADATA_SUFFIX}" + fi +} + +do_deploy() { + install -d ${DEPLOYDIR} + install -d ${DEPLOYDIR}/arm-trusted-firmware + + unset i + for config in ${TF_A_CONFIG}; do + i=$(expr $i + 1) + # Initialize devicetree list and tf-a basename + dt_config=$(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) + tfa_basename=$(echo ${TF_A_BINARIES} | cut -d',' -f${i}) + tfa_file_type=$(echo ${TF_A_FILES} | cut -d',' -f${i}) + for dt in ${dt_config}; do + # Init soc suffix + soc_suffix="" + if [ -n "${STM32MP_SOC_NAME}" ]; then + for soc in ${STM32MP_SOC_NAME}; do + [ "$(echo ${dt} | grep -c ${soc})" -eq 1 ] && soc_suffix="-${soc}" + done + fi + for file_type in ${tfa_file_type}; do + case "${file_type}" in + bl2) + # Install TF-A binary + if [ -f "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${tfa_basename}-${dt}-${config}${TF_A_ENCRYPT_SUFFIX}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/" + if [ "${TF_A_ENABLE_DEBUG_WRAPPER}" = "1" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware/debug" + install -m 644 "${B}/${config}${soc_suffix}-${dt}/debug-${tfa_basename}-${dt}-${config}${TF_A_ENCRYPT_SUFFIX}${TF_A_SIGN_SUFFIX}.${TF_A_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/debug/" + fi + fi + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware/debug" + if [ -f "${B}/${config}${soc_suffix}-${dt}/${BL2_ELF}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${BL2_ELF}" "${DEPLOYDIR}/arm-trusted-firmware/debug/${tfa_basename}-${BL2_BASENAME_DEPLOY}${soc_suffix}-${config}.${TF_A_ELF_SUFFIX}" + fi + fi + if [ "${TF_A_FWDDR}" = "1" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware/ddr" + # Install DDR firmware binary + if [ -f "${B}/${config}${soc_suffix}-${dt}/${FWDDR_NAME}-${dt}.${FWDDR_SUFFIX}" ]; then + if [ ! -s "${DEPLOYDIR}/arm-trusted-firmware/ddr/${FWDDR_NAME}-${dt}.${FWDDR_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${FWDDR_NAME}-${dt}.${FWDDR_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/ddr/" + fi + fi + fi + ;; + bl31) + # Install BL31 files + install -d "${DEPLOYDIR}/arm-trusted-firmware/bl31" + # Install BL31 binary + if [ -f "${B}/${config}${soc_suffix}-${dt}/${BL31_BASENAME}.${BL31_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${BL31_BASENAME}.${BL31_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/bl31/${tfa_basename}-${BL31_BASENAME_DEPLOY}${soc_suffix}.${BL31_SUFFIX}" + fi + # Install BL31 devicetree + if [ -f "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-${BL31_BASENAME}.${DT_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-${BL31_BASENAME}.${DT_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/bl31/${dt}-${BL31_BASENAME}.${DT_SUFFIX}" + fi + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware/bl31/debug" + if [ -f "${B}/${config}${soc_suffix}-${dt}/${BL31_ELF}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${BL31_ELF}" "${DEPLOYDIR}/arm-trusted-firmware/bl31/debug/${tfa_basename}-${BL31_BASENAME_DEPLOY}${soc_suffix}-${config}.${TF_A_ELF_SUFFIX}" + fi + fi + ;; + bl32) + # Install BL32 files + install -d "${DEPLOYDIR}/arm-trusted-firmware/bl32" + # Install BL32 binary + if [ -f "${B}/${config}${soc_suffix}-${dt}/${BL32_BASENAME}.${BL32_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${BL32_BASENAME}.${BL32_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/bl32/${tfa_basename}-${BL32_BASENAME_DEPLOY}${soc_suffix}.${BL32_SUFFIX}" + fi + # Install BL32 devicetree + if [ -f "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-${BL32_BASENAME}.${DT_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-${BL32_BASENAME}.${DT_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/bl32/${dt}-${BL32_BASENAME}.${DT_SUFFIX}" + fi + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware/bl32/debug" + if [ -f "${B}/${config}${soc_suffix}-${dt}/${BL32_ELF}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${BL32_ELF}" "${DEPLOYDIR}/arm-trusted-firmware/bl32/debug/${tfa_basename}-${BL32_BASENAME_DEPLOY}${soc_suffix}-${config}.${TF_A_ELF_SUFFIX}" + fi + fi + ;; + fwconfig) + # Install fwconfig + install -d "${DEPLOYDIR}/arm-trusted-firmware/fwconfig" + if [ -f "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-${FWCONFIG_NAME}.${DT_SUFFIX}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/fdts/${dt}-${FWCONFIG_NAME}.${DT_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/fwconfig/${dt}-${FWCONFIG_NAME}-${config}.${DT_SUFFIX}" + fi + ;; + esac + done # for file_type in ${tfa_file_type} + done # for dt in ${dt_config} + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware/debug" + if [ -f "${B}/${config}${soc_suffix}-${dt}/${BL1_ELF}" ]; then + install -m 644 "${B}/${config}${soc_suffix}-${dt}/${BL1_ELF}" "${DEPLOYDIR}/arm-trusted-firmware/debug/${tfa_basename}-${BL1_BASENAME_DEPLOY}-${config}.${TF_A_ELF_SUFFIX}" + fi + fi + done # for config in ${TF_A_CONFIG} + + if [ "${TF_A_ENABLE_METADATA}" = "1" ]; then + install -d "${DEPLOYDIR}/arm-trusted-firmware" + if [ -f "${B}/${TF_A_METADATA_NAME}.${TF_A_METADATA_SUFFIX}" ]; then + install -m 644 "${B}/${TF_A_METADATA_NAME}.${TF_A_METADATA_SUFFIX}" "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_METADATA_BINARY}" + fi + fi +} +addtask deploy before do_build after do_compile diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_%.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.6.bbappend similarity index 98% rename from meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_%.bbappend rename to meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.6.bbappend index 7f1acace1..6c9041b1d 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_%.bbappend +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.6.bbappend @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Digi International Inc. +# Copyright (C) 2022, Digi International Inc. # # Select internal or Github TF-A repo diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.8.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.8.bb new file mode 100644 index 000000000..d83049b77 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.8.bb @@ -0,0 +1,42 @@ +# +# Copyright (C) 2024 Digi International Inc. +# +require tf-a-stm32mp2-common.inc +require tf-a-stm32mp2.inc + +SUMMARY = "Trusted Firmware-A for STM32MP1" +LICENSE = "BSD-3-Clause" + +# Select internal or Github TF-A repo +TFA_URI_STASH = "${DIGI_MTK_GIT}/emp/arm-trusted-firmware.git;protocol=ssh" +TFA_URI_GITHUB = "${DIGI_GITHUB_GIT}/arm-trusted-firmware.git;protocol=https" +TFA_GIT_URI ?= "${@oe.utils.conditional('DIGI_INTERNAL_GIT', '1' , '${TFA_URI_STASH}', '${TFA_URI_GITHUB}', d)}" + +SRCBRANCH = "v2.8/stm32mp/master" +SRCREV = "${AUTOREV}" + +SRC_URI = " \ + ${TFA_GIT_URI};branch=${SRCBRANCH} \ +" + +TF_A_VERSION = "v2.8.12" +TF_A_RELEASE = "beta-r1" + +# Configure settings +TFA_PLATFORM = "stm32mp1" +TFA_ARM_MAJOR = "7" +TFA_ARM_ARCH = "aarch32" + +TFA_PLATFORM:aarch64 = "stm32mp2" +TFA_ARM_MAJOR:aarch64 = "8" +TFA_ARM_ARCH:aarch64 = "aarch64" + +# Enable the wrapper for debug +TF_A_ENABLE_DEBUG_WRAPPER ?= "1" + +# --------------------------------- +# Configure archiver use +# --------------------------------- +include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'tf-a-stm32mp-archiver.inc','')} + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.8.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.8.bbappend new file mode 100644 index 000000000..9412cbbac --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-stm32mp_2.8.bbappend @@ -0,0 +1,35 @@ +# Copyright (C) 2024, Digi International Inc. + +do_deploy:append() { + unset i + for config in ${TF_A_CONFIG}; do + i=$(expr $i + 1) + dt_config=$(echo ${TF_A_DEVICETREE} | cut -d',' -f${i}) + tfa_basename=$(echo ${TF_A_BINARIES} | cut -d',' -f${i}) + for dt in ${dt_config}; do + TF_A_FILENAME="${tfa_basename}-${dt}-${config}.${TF_A_SUFFIX}" + if [ -f "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_FILENAME}" ]; then + ln -s "arm-trusted-firmware/${TF_A_FILENAME}" "${DEPLOYDIR}" + fi + done + done + + # Last value of 'dt' is good for metadata binary, so use that. + if [ "${TF_A_ENABLE_METADATA}" = "1" ]; then + if [ -f "${DEPLOYDIR}/arm-trusted-firmware/${TF_A_METADATA_BINARY}" ]; then + ln -s "arm-trusted-firmware/${TF_A_METADATA_BINARY}" "${DEPLOYDIR}/${TF_A_METADATA_NAME}-${dt}.${TF_A_METADATA_SUFFIX}" + fi + fi + + unset i + for config in ${FIP_CONFIG}; do + i=$(expr $i + 1) + dt_config="$(echo ${FIP_DEVICETREE} | cut -d',' -f${i})" + for dt in ${dt_config}; do + FIP_FILENAME="${FIP_BASENAME}-${dt}-${config}${FIP_SIGN_SUFFIX}.${FIP_SUFFIX}" + if [ -f "${DEPLOYDIR}/fip/${FIP_FILENAME}" ]; then + ln -s "fip/${FIP_FILENAME}" "${DEPLOYDIR}" + fi + done + done +} diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools.inc new file mode 100644 index 000000000..5d0fe9913 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools.inc @@ -0,0 +1,48 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/tf-a-tools:" + +SRC_URI:append = " \ + file://0001-FIX-GCC-tools-overwrite.patch \ + file://0001-tools-allow-to-use-a-root-key-password-from-command-.patch \ + " + +DEPENDS += "dtc-native openssl" + +COMPATIBLE_HOST:class-target = "null" + +HOSTCC:class-native = "${BUILD_CC}" +HOSTCC:class-nativesdk = "${CC}" + +EXTRA_OEMAKE += "HOSTCC='${HOSTCC}' OPENSSL_DIR='${STAGING_EXECPREFIXDIR}'" +EXTRA_OEMAKE += "certtool enctool fiptool" +EXTRA_OEMAKE += "PLAT=${TFA_PLATFORM}" + +do_configure[noexec] = "1" + +do_compile:prepend:class-native () { + # This is still needed to have the native fiptool executing properly by + # setting the RPATH + sed -e '/^LDLIBS/ s,$, \$\{BUILD_LDFLAGS},' \ + -e '/^INCLUDE_PATHS/ s,$, \$\{BUILD_CFLAGS},' \ + -i ${S}/tools/fiptool/Makefile + # This is still needed to have the native cert_create executing properly by + # setting the RPATH + sed -e '/^LIB_DIR/ s,$, \$\{BUILD_LDFLAGS},' \ + -e '/^INC_DIR/ s,$, \$\{BUILD_CFLAGS},' \ + -i ${S}/tools/cert_create/Makefile + # This is still needed to have the native fiptool executing properly by + # setting the RPATH + sed -e '/^LIB_DIR/ s,$, \$\{BUILD_LDFLAGS},' \ + -e '/^INC_DIR/ s,$, \$\{BUILD_CFLAGS},' \ + -i ${S}/tools/encrypt_fw/Makefile +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 \ + ${B}/tools/fiptool/fiptool \ + ${B}/tools/cert_create/cert_create \ + ${B}/tools/encrypt_fw/encrypt_fw \ + ${D}${bindir} +} + +BBCLASSEXTEND += "native nativesdk" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools/0001-FIX-GCC-tools-overwrite.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools/0001-FIX-GCC-tools-overwrite.patch new file mode 100644 index 000000000..63d7dc604 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools/0001-FIX-GCC-tools-overwrite.patch @@ -0,0 +1,48 @@ +From 68a2098a3035b8374d0ce0b1feead650dadbce64 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Thu, 24 Nov 2022 16:18:27 +0100 +Subject: [PATCH] FIX GCC tools overwrite + +Signed-off-by: Christophe Priouzeau +--- + Makefile | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/Makefile b/Makefile +index 1ddb7b844..d6583dfe9 100644 +--- a/Makefile ++++ b/Makefile +@@ -183,19 +183,19 @@ endif + # Toolchain + ################################################################################ + +-HOSTCC := gcc ++HOSTCC ?= gcc + export HOSTCC + +-CC := ${CROSS_COMPILE}gcc +-CPP := ${CROSS_COMPILE}cpp +-AS := ${CROSS_COMPILE}gcc +-AR := ${CROSS_COMPILE}ar +-LINKER := ${CROSS_COMPILE}ld +-OC := ${CROSS_COMPILE}objcopy +-OD := ${CROSS_COMPILE}objdump +-NM := ${CROSS_COMPILE}nm +-PP := ${CROSS_COMPILE}gcc -E +-DTC := dtc ++#CC := ${CROSS_COMPILE}gcc ++#CPP := ${CROSS_COMPILE}cpp ++#AS := ${CROSS_COMPILE}gcc ++#AR := ${CROSS_COMPILE}ar ++#LINKER := ${CROSS_COMPILE}ld ++#OC := ${CROSS_COMPILE}objcopy ++#OD := ${CROSS_COMPILE}objdump ++#NM := ${CROSS_COMPILE}nm ++#PP := ${CROSS_COMPILE}gcc -E ++#DTC := dtc + + # Use ${LD}.bfd instead if it exists (as absolute path or together with $PATH). + ifneq ($(strip $(wildcard ${LD}.bfd) \ +-- +2.25.1 + diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools/0001-tools-allow-to-use-a-root-key-password-from-command-.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools/0001-tools-allow-to-use-a-root-key-password-from-command-.patch new file mode 100644 index 000000000..0a17ea37f --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools/0001-tools-allow-to-use-a-root-key-password-from-command-.patch @@ -0,0 +1,126 @@ +From 204cde3bd45f634e3699a42ed8f865a8385743a5 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 28 Nov 2022 12:16:38 +0100 +Subject: [PATCH] tools: allow to use a root key password from command line + +By defining the ROT_KEY_PWD, user is able to define the private +root key password. Useful for build system management. + +Signed-off-by: Lionel Debieve +--- + make_helpers/tbbr/tbbr_tools.mk | 2 ++ + tools/cert_create/include/key.h | 2 +- + tools/cert_create/src/key.c | 4 ++-- + tools/cert_create/src/main.c | 13 +++++++++++-- + 4 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk +index 5ef2d852e..147159b1a 100644 +--- a/make_helpers/tbbr/tbbr_tools.mk ++++ b/make_helpers/tbbr/tbbr_tools.mk +@@ -25,6 +25,7 @@ + # KEY_SIZE + # ROT_KEY + # PROT_KEY ++# ROT_KEY_PWD + # PLAT_KEY + # SWD_ROT_KEY + # CORE_SWD_KEY +@@ -74,6 +75,7 @@ $(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg,FWU_))) + $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key))) + $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_))) + $(if ${PROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PROT_KEY},--prot-key))) ++$(if ${ROT_KEY_PWD},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY_PWD},--rot-key-pwd))) + $(if ${PLAT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${PLAT_KEY},--plat-key))) + $(if ${SWD_ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${SWD_ROT_KEY},--swd-rot-key))) + $(if ${CORE_SWD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${CORE_SWD_KEY},--core-swd-key))) +diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h +index 312575b44..ed3654b08 100644 +--- a/tools/cert_create/include/key.h ++++ b/tools/cert_create/include/key.h +@@ -74,7 +74,7 @@ key_t *key_get_by_opt(const char *opt); + int key_new(key_t *key); + #endif + int key_create(key_t *key, int type, int key_bits); +-int key_load(key_t *key, unsigned int *err_code); ++int key_load(key_t *key, char *rot_key_pwd, unsigned int *err_code); + int key_store(key_t *key); + void key_cleanup(void); + +diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c +index 487777b67..c8f5357be 100644 +--- a/tools/cert_create/src/key.c ++++ b/tools/cert_create/src/key.c +@@ -189,7 +189,7 @@ int key_create(key_t *key, int type, int key_bits) + return 0; + } + +-int key_load(key_t *key, unsigned int *err_code) ++int key_load(key_t *key, char *rot_key_pwd, unsigned int *err_code) + { + FILE *fp; + EVP_PKEY *k; +@@ -198,7 +198,7 @@ int key_load(key_t *key, unsigned int *err_code) + /* Load key from file */ + fp = fopen(key->fn, "r"); + if (fp) { +- k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL); ++ k = PEM_read_PrivateKey(fp, &key->key, NULL, rot_key_pwd); + fclose(fp); + if (k) { + *err_code = KEY_ERR_NONE; +diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c +index 2ab6bcfd9..90bb82ba8 100644 +--- a/tools/cert_create/src/main.c ++++ b/tools/cert_create/src/main.c +@@ -292,6 +292,10 @@ static const cmd_opt_t common_cmd_opt[] = { + { "print-cert", no_argument, NULL, 'p' }, + "Print the certificates in the standard output" + } ++ ,{ ++ { "rot-key-pwd", required_argument, NULL, 'r' }, ++ "Password for the root key" ++ }, + }; + + int main(int argc, char *argv[]) +@@ -310,6 +314,7 @@ int main(int argc, char *argv[]) + unsigned char md[SHA512_DIGEST_LENGTH]; + unsigned int md_len; + const EVP_MD *md_info; ++ char *rot_key_pw = NULL; + + NOTICE("CoT Generation Tool: %s\n", build_msg); + NOTICE("Target platform: %s\n", platform_msg); +@@ -347,7 +352,7 @@ int main(int argc, char *argv[]) + + while (1) { + /* getopt_long stores the option index here. */ +- c = getopt_long(argc, argv, "a:b:hknps:", cmd_opt, &opt_idx); ++ c = getopt_long(argc, argv, "a:b:hknpr:s:", cmd_opt, &opt_idx); + + /* Detect the end of the options. */ + if (c == -1) { +@@ -381,6 +386,10 @@ int main(int argc, char *argv[]) + case 'p': + print_cert = 1; + break; ++ case 'r': ++ rot_key_pw = malloc(sizeof(char) * strlen(optarg)); ++ strncpy(rot_key_pw, optarg, strlen(optarg)); ++ break; + case 's': + hash_alg = get_hash_alg(optarg); + if (hash_alg < 0) { +@@ -441,7 +450,7 @@ int main(int argc, char *argv[]) + #endif + + /* First try to load the key from disk */ +- if (key_load(&keys[i], &err_code)) { ++ if (key_load(&keys[i], rot_key_pw, &err_code)) { + /* Key loaded successfully */ + continue; + } +-- +2.25.1 + diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools_2.8.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools_2.8.bb new file mode 100644 index 000000000..27bff1dde --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-bsp/trusted-firmware-a/tf-a-tools_2.8.bb @@ -0,0 +1,22 @@ +require tf-a-stm32mp2-common.inc +require tf-a-tools.inc + +SUMMARY = "Cert_create & Fiptool for fip generation for Trusted Firmware-A" +LICENSE = "BSD-3-Clause" + +# Select internal or Github TF-A repo +TFA_URI_STASH = "${DIGI_MTK_GIT}/emp/arm-trusted-firmware.git;protocol=ssh" +TFA_URI_GITHUB = "${DIGI_GITHUB_GIT}/arm-trusted-firmware.git;protocol=https" +TFA_GIT_URI ?= "${@oe.utils.conditional('DIGI_INTERNAL_GIT', '1' , '${TFA_URI_STASH}', '${TFA_URI_GITHUB}', d)}" + +SRCBRANCH = "v2.8/stm32mp/master" +SRCREV = "${AUTOREV}" + +SRC_URI = " \ + ${TFA_GIT_URI};branch=${SRCBRANCH} \ +" + +# Configure settings +TFA_PLATFORM = "stm32mp1" +TFA_PLATFORM:class-native = "stm32mp2" +TFA_PLATFORM:class-nativesdk = "stm32mp2" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/files/openvx_profile.sh.template b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/files/openvx_profile.sh.template new file mode 100644 index 000000000..01afb00f5 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/files/openvx_profile.sh.template @@ -0,0 +1 @@ +export VIVANTE_SDK_DIR="%VIVANTE_SDK_DIR%" \ No newline at end of file diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/files/vulkan_icd.json.template b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/files/vulkan_icd.json.template new file mode 100644 index 000000000..5321c7456 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/files/vulkan_icd.json.template @@ -0,0 +1,8 @@ +{ + "file_format_version": "1.0.0", + "ICD": + { + "library_path": "%VULKANLIB%", + "api_version": "%VULKANVERSION%" + } +} diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-binary.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-binary.inc new file mode 100644 index 000000000..ed782985e --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-binary.inc @@ -0,0 +1,70 @@ +require gcnano-userland.inc + +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://${GCNANO_TAR_FILENAME}/LICENSE;md5=0e85fa534ee3a1a7f5ccc65cd6e789f9" + +DEPENDS += " libdrm wayland " + +SRC_URI = "git://github.com/STMicroelectronics/gcnano-binaries;protocol=https;branch=gcnano-${GCNANO_VERSION}-binaries" +SRCREV = "bbaae49a0e4859ed53f898a250269c8a237261bc" + +PV = "${GCNANO_VERSION}+${GCNANO_DATE}" + +GCNANO_VERSION = "6.4.15" + +GCNANO_DATE:stm32mp1common = "20240206" +GCNANO_DATE:stm32mp2common = "20240517" + +GCNANO_PACKAGECONFIG = "egl gbm glesv1 glesv2 vg" + +GCNANO_PACKAGECONFIG:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'openvx', 'vx', '', d)}" +GCNANO_PACKAGECONFIG:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'opencl', 'cl', '', d)}" +GCNANO_PACKAGECONFIG:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'vulkan', 'vulkan', '', d)}" + +S = "${WORKDIR}/git" +B = "${S}/${GCNANO_TAR_FILENAME}" + +#------------------------------------------ +# Overwrite of do_unpack to untar the tarball +python() { + # Make sure that we're dealing with recipe that enables externalsrc class + if bb.data.inherits_class('externalsrc', d): + bb.build.addtask('gcnano_userland_binaries_unpack', 'do_populate_lic', None, d) + bb.build.addtask('gcnano_userland_binaries_unpack', 'do_configure', None, d) +} + +do_gcnano_userland_binaries_unpack[depends] += "xz-native:do_populate_sysroot" +do_gcnano_userland_binaries_unpack() { + cd ${S} + rm -rf ${GCNANO_TAR_FILENAME} + if [ -f "${GCNANO_TAR_FILENAME}.bin" ]; then + sh ${GCNANO_TAR_FILENAME}.bin --auto-accept + else + bbfatal "Missing '${GCNANO_TAR_FILENAME}.bin' file in ${S} folder." + fi +} + +do_unpack[depends] += "xz-native:do_populate_sysroot" +python do_unpack() { + eula = d.getVar('ACCEPT_EULA_'+d.getVar('MACHINE')) + eula_file = d.getVar('EULA_FILE_ST') + machine = d.getVar('MACHINE') + pkg = d.getVar('PN') + if eula == None: + bb.fatal("To use '%s' you need to accept the STMicroelectronics EULA at '%s'. " + "Please read it and in case you accept it, write: " + "ACCEPT_EULA_%s = \"1\" in your local.conf." % (pkg, eula_file, machine)) + elif eula == '0': + bb.fatal("To use '%s' you need to accept the STMicroelectronics EULA." % pkg) + else: + bb.note("STMicroelectronics EULA has been accepted for '%s'" % pkg) + + try: + externalsrc = d.getVar('EXTERNALSRC') + if not externalsrc: + bb.build.exec_func('base_do_unpack', d) + bb.build.exec_func('do_gcnano_userland_binaries_unpack', d) + except: + raise +} +do_unpack[vardepsexclude] += "EULA_FILE_ST" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp.bbappend index 669a8db6b..a121ebfa7 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp.bbappend +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023, Digi International Inc. +# Copyright (C) 2022,2023, Digi International Inc. # # Workarounds for Crank storyboard engine diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp_6.4.15.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp_6.4.15.bb new file mode 100644 index 000000000..7db05c49f --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland-multi-binary-stm32mp_6.4.15.bb @@ -0,0 +1,9 @@ +require gcnano-userland-binary.inc + +SUMMARY = "Vivante libraries OpenGL ES, OpenVG and EGL (multi backend)" +LICENSE = "Proprietary" + +GCNANO_BACKEND = "multi" +GCNANO_FLAVOUR = "release" + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland.inc new file mode 100644 index 000000000..e99a1665f --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/gcnano-userland/gcnano-userland.inc @@ -0,0 +1,443 @@ +PACKAGE_ARCH = "${MACHINE_ARCH}" + +GCNANO_PACKAGECONFIG ??= "" + +PROVIDES = "\ + gcnano-userland \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'egl', 'virtual/egl', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'gbm', 'virtual/libgbm', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv1', 'virtual/libgles1', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv2', 'virtual/libgles2', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv2', 'virtual/libgles3', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vg', 'virtual/libopenvg', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vx', 'virtual/libopenvx', '', d)} \ + " + +PACKAGES += "\ + gcnano-ldconf \ + libgal-gcnano libgal-gcnano-dev \ + \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'cl', 'libopencl-gcnano libopencl-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'egl', 'libegl-gcnano libegl-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'gbm', 'libgbm-gcnano libgbm-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv1', 'libgles1-gcnano libgles1-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv2', 'libgles2-gcnano libgles2-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv2', 'libgles3-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vg', 'libopenvg-gcnano libopenvg-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vulkan', 'libvulkan-driver-gcnano libvulkan-driver-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vx', 'libopenvx-gcnano libopenvx-gcnano-dev', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vx', 'libovxkernels-gcnano libovxkernels-gcnano-dev', '', d)} \ + \ + ${@bb.utils.contains_any('GCNANO_PACKAGECONFIG', 'glesv1 glesv2 vg vulkan', 'libglslc-gcnano libglslc-gcnano-dev', '', d)} \ + ${@bb.utils.contains_any('GCNANO_PACKAGECONFIG', 'cl vx', 'libclc-gcnano libclc-gcnano-dev', '', d)} \ + ${@bb.utils.contains_any('GCNANO_PACKAGECONFIG', 'cl vulkan', 'libspirv-gcnano libspirv-gcnano-dev', '', d)} \ + " + +GCNANO_BACKEND ??= "multi" +GCNANO_VERSION ??= "6" +GCNANO_DATE ??= "" + +GCNANO_MACHINE:stm32mp1common = "stm32mp1" +GCNANO_MACHINE:stm32mp2common = "stm32mp2" + +# Init the gcnano build type +GCNANO_FLAVOUR ??= "release" + +# Init the gcnano tarball file name +GCNANO_TAR_FILENAME ?= "gcnano-userland-${GCNANO_BACKEND}-${GCNANO_MACHINE}-${GCNANO_VERSION}-${GCNANO_DATE}" + +# Configure gcnano output library dir +GCNANO_USERLAND_OUTPUT_LIBDIR ??= "${libdir}" + +GCNANO_USERLAND_LDCONF ?= "gcnano.conf" +GCNANO_OPENCL_ICD ?= "VeriSilicon.icd" +GCNANO_VULKAN_ICD ?= "VeriSilicon_icd.json" + +# Configure the pkgconfig settings +PKGCONFIG_DV ??= "23.0.3" +PKGCONFIG_PREFIX ??= "${exec_prefix}" + +do_compile:append() { + # Generate specific conf file if required + if [ "${GCNANO_USERLAND_OUTPUT_LIBDIR}" = "${libdir}" ]; then + bbnote "gcnano-userland output libdir is default one (${libdir})" + else + bbnote "gcnano-userland output libdir set to ${GCNANO_USERLAND_OUTPUT_LIBDIR}: generate specific conf file for ldconfig" + echo ${GCNANO_USERLAND_OUTPUT_LIBDIR} > ${B}/${GCNANO_USERLAND_LDCONF} + fi +} + +# Install utility for gcano-userland: +# gcnano_install_lib \ +# \ +# +gcnano_install_lib() { + # Init for lib dir install + gcnano_libdir=$1 + gcnano_libdir_install=$2 + # Init for include dir install + gcnano_incdir=$3 + gcnano_incdir_install=$4 + # Init for package config install + gcnano_pkgdir=$5 + gcnano_pkgdir_install=$6 + + # Install libraries & headers + install -m 0755 -d ${gcnano_libdir_install} + install -m 0755 -d ${gcnano_incdir_install} + + # Install libraries + install -m 0555 ${gcnano_libdir}/libGAL.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libVSC.so ${gcnano_libdir_install}/ + # Install includes + install -m 0755 -d ${gcnano_incdir_install}/KHR + install -m 0644 ${gcnano_incdir}/KHR/* ${gcnano_incdir_install}/KHR + + # Install compiler libraries when needed + needs_clc="false" + needs_glslc="false" + needs_spirv="false" + + for lib in ${GCNANO_PACKAGECONFIG}; do + case ${lib} in + "cl") + # Install libraries + find ${gcnano_libdir}/* -type f -name libOpenCL*.so.* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + # Request CLC and SPIR-V + needs_clc="true" + needs_spirv="true" + ;; + "egl") + # Install libraries + find ${gcnano_libdir}/* -type f -name libEGL.so.* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + # Install includes + install -m 0755 -d ${gcnano_incdir_install}/EGL + install -m 0644 ${gcnano_incdir}/EGL/* ${gcnano_incdir_install}/EGL + # Install pkgconfig + install -m 0755 -d ${gcnano_pkgdir_install} + install -m 0644 ${gcnano_pkgdir}/egl.pc ${gcnano_pkgdir_install}/ + ;; + "gbm") + # Install libraries + find ${gcnano_libdir}/* -type f -name libgbm.so.* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + install -m 0755 ${gcnano_libdir}/libgbm_viv.so ${gcnano_libdir_install}/ + # Install includes + install -m 0755 -d ${gcnano_incdir_install} + install -m 0644 ${gcnano_incdir}/gbm.h ${gcnano_incdir_install}/ + # Install pkgconfig + install -m 0755 -d ${gcnano_pkgdir_install} + install -m 644 ${gcnano_pkgdir}/gbm.pc ${gcnano_pkgdir_install}/ + ;; + "glesv1") + # Install libraries + find ${gcnano_libdir}/* -type f -name libGLESv1_CM.so.* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + # Install includes + install -m 0755 -d ${gcnano_incdir_install}/GLES + install -m 0644 ${gcnano_incdir}/GLES/* ${gcnano_incdir_install}/GLES + # Install pkgconfig + install -m 0755 -d ${gcnano_pkgdir_install} + install -m 644 ${gcnano_pkgdir}/glesv1_cm.pc ${gcnano_pkgdir_install}/ + # Request GLSLC + needs_glslc="true" + ;; + "glesv2") + # Install libraries + find ${gcnano_libdir}/* -type f -name libGLESv2.so.* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + # Install includes GLESv2 and GLESv3 + install -m 0755 -d ${gcnano_incdir_install}/GLES2 + install -m 0644 ${gcnano_incdir}/GLES2/* ${gcnano_incdir_install}/GLES2 + # Hack for weston & kmscube compilation + # Weston and kmscube use GLES3 header but the decision to use gles2 or gles3 + # are made a runtime + install -m 0755 -d ${gcnano_incdir_install}/GLES3 + install -m 0644 ${gcnano_incdir}/GLES3/* ${gcnano_incdir_install}/GLES3 + # Install pkgconfig + install -m 0755 -d ${gcnano_pkgdir_install} + install -m 644 ${gcnano_pkgdir}/glesv2.pc ${gcnano_pkgdir_install}/ + # Request GLSLC + needs_glslc="true" + ;; + "vulkan") + # Install libraries + find ${gcnano_libdir}/* -type f -name libvulkan*.so* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + # Request GLSLC and SPIR-V + needs_glslc="true" + needs_spirv="true" + ;; + "vg") + # Install libraries + find ${gcnano_libdir}/* -type f -name libOpenVG*.so.* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + # Install includes + install -m 0755 -d ${gcnano_incdir_install}/VG + install -m 0644 ${gcnano_incdir}/VG/* ${gcnano_incdir_install}/VG + # Install pkgconfig + install -m 0755 -d ${gcnano_pkgdir_install} + install -m 644 ${gcnano_pkgdir}/vg.pc ${gcnano_pkgdir_install}/ + # Request GLSLC + needs_glslc="true" + ;; + "vx") + # Install libraries + find ${gcnano_libdir}/* -type f -name libOpenVX*.so* -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + install -m 0555 ${gcnano_libdir}/libArchModelSw.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libNNArchPerf.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libovxlib.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libNNGPUBinary.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libNNVXCBinary.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libOvx12VXCBinary.so ${gcnano_libdir_install}/ + install -m 0555 ${gcnano_libdir}/libOvxGPUVXCBinary.so ${gcnano_libdir_install}/ + # Install includes + install -m 0755 -d ${gcnano_incdir_install}/VX + install -m 0644 ${gcnano_incdir}/VX/* ${gcnano_incdir_install}/VX + # Request CLC + needs_clc="true" + # To allow building OpenVX kernel program from OpenCL kernel source code, + # cl_viv_vx_ext.h must be installed at runtime + install -m 0755 -d ${gcnano_incdir_install}/CL + install -m 644 ${gcnano_incdir}/CL/cl_viv_vx_ext.h ${gcnano_incdir_install}/CL + ;; + esac + done + + # Install libCLC + if [ "${needs_clc}" = "true" ]; then + find ${gcnano_libdir}/* -type f -name libCLC.so -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + fi + + # Install libGLSLC + if [ "${needs_glslc}" = "true" ]; then + find ${gcnano_libdir}/* -type f -name libGLSLC.so -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + fi + + # Install libSPIRV + if [ "${needs_spirv}" = "true" ]; then + find ${gcnano_libdir}/* -type f -name libSPIRV_viv.so -exec install -m 0555 '{}' ${gcnano_libdir_install}/ \; + fi +} + +# Install utility for gcano-userland: +# gcnano_install_symlinks +# +# Iterate other installed libraries and create appropriate symlinks if they +# don't exist as symlink or real library at that location. +# For well-formed library with ABI suffix, create a SONAME-suffixed symlink +# and dev-.so-only symlink. +# For .so-only installed library, only create dev-.so-only symlink. +gcnano_install_symlinks() { + # Init for lib dir install + gcnano_libdir=$1 + gcnano_lib_symlink_dir_install=$2 + + bbnote "Create symlinks to shared libs in ${gcnano_lib_symlink_dir_install} folder (mandatory for SDK)" + # Init relative path for symlinks + relative_path=$(realpath -m --relative-to=${gcnano_lib_symlink_dir_install} ${gcnano_libdir}) + # Move to gcnano_lib_symlink_dir_install for symlinks + cd "${gcnano_lib_symlink_dir_install}" + for sharelib in $(find ${gcnano_libdir}/ -type f -name "*.so*"); do + # Get full libname + sharelib_name=$(basename ${sharelib}) + # Get base libname + dev_lib_name=$(echo ${sharelib_name} | awk -F'.so' '{print $1}').so + # Get SONAME + soname_lib_name=$(objdump -x ${sharelib} 2>/dev/null | grep SONAME | awk -F' ' '{print $NF}') + # Create symlink + for link_name in ${soname_lib_name} ${dev_lib_name}; do + if [ -e "${link_name}" ]; then + bbnote "Already existing share lib: ${link_name}. No symlink created in ${gcnano_lib_symlink_dir_install}." + elif [ ! -e "${relative_path}/${sharelib_name}" ]; then + bbnote "Not able to find share lib: ${relative_path}/${sharelib_name}. No symlink created in ${gcnano_lib_symlink_dir_install}." + else + ln -sf ${relative_path}/${sharelib_name} ${link_name} + fi + done + done + cd "${PWD}" +} + +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" +SRC_URI:append = " ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vulkan', 'file://vulkan_icd.json.template', '', d)}" +SRC_URI:append = " ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vx', 'file://openvx_profile.sh.template', '', d)}" + +do_install() { + # Update pkgconfig files info + for pkg_file in $(find ${B}/pkgconfig/* -type f -name *.pc); do + sed -e "s;#PREFIX#;${PKGCONFIG_PREFIX};g" -e "s;#VERSION#;${PKGCONFIG_DV};g" -i ${pkg_file} + done + + # Install gcnano libraries + gcnano_install_lib "${B}/${GCNANO_FLAVOUR}/drivers" "${D}${GCNANO_USERLAND_OUTPUT_LIBDIR}" \ + "${B}/${GCNANO_FLAVOUR}/include" "${D}${includedir}" \ + "${B}/pkgconfig" "${D}${libdir}/pkgconfig" + + # Manage creation of additional development symlinks to solve missing libs issue on SDK side + gcnano_install_symlinks "${D}${GCNANO_USERLAND_OUTPUT_LIBDIR}" "${D}${libdir}" + + if [ -s "${B}/${GCNANO_USERLAND_LDCONF}" ]; then + install -d ${D}${sysconfdir}/ld.so.conf.d/ + install -m 0644 "${B}/${GCNANO_USERLAND_LDCONF}" ${D}${sysconfdir}/ld.so.conf.d/ + fi + + # Generate OpenCL ICD + if [ -n "$(echo ${GCNANO_PACKAGECONFIG} | grep 'cl')" ]; then + install -m 0755 -d "${D}${sysconfdir}/OpenCL/vendors" + find "${D}${GCNANO_USERLAND_OUTPUT_LIBDIR}" -type f -name "libOpenCL*.so*" | sed s"%${D}%%" > "${D}${sysconfdir}/OpenCL/vendors/${GCNANO_OPENCL_ICD}" + fi + + # Generate Vulkan ICD + if [ -n "$(echo ${GCNANO_PACKAGECONFIG} | grep 'vulkan')" ]; then + vklib=$(find "${D}${GCNANO_USERLAND_OUTPUT_LIBDIR}" -type f -name "libvulkan*.so*" | sed s"%${D}%%") + vkvers=$(echo ${vklib} | awk -F'.so.' '{print $2}') + + install -m 0755 -d "${D}${sysconfdir}/vulkan/icd.d" + sed -e "s#%VULKANLIB%#${vklib}#" -e "s#%VULKANVERSION%#${vkvers}#" ${WORKDIR}/vulkan_icd.json.template > ${D}${sysconfdir}/vulkan/icd.d/${GCNANO_VULKAN_ICD} + fi + + # Install profile script to export required environment variables to allow OpenVX kernel program + # to be built at runtime + if [ -n "$(echo ${GCNANO_PACKAGECONFIG} | grep 'vx')" ]; then + install -m 0755 -d "${D}${sysconfdir}/profile.d" + sed "s#%VIVANTE_SDK_DIR%#${exec_prefix}#" ${WORKDIR}/openvx_profile.sh.template > ${D}${sysconfdir}/profile.d/openvx_profile.sh + fi +} + +SYSROOT_DIRS:append = " ${GCNANO_USERLAND_OUTPUT_LIBDIR}" + +# For the packages that make up the OpenGL interfaces, inject variables so that +# they don't get Debian-renamed (which would remove the -gcnano suffix), and +# RPROVIDEs/RCONFLICTs on the generic libgl name. +python __anonymous() { + pkgconfig = (d.getVar('GCNANO_PACKAGECONFIG') or "").split() + for p in (("gbm", "libgbm",), + ("egl", "libegl", "libegl1"), + ("glesv1", "libgles1", "libglesv1-cm1"), + ("glesv2", "libgles2", "libglesv2-2"), + ("glesv2", "libgles3"), + ("vg", "libopenvg"), + ("vx", "libopenvx"), + ("cl", "libopencl"), + ("vulkan", "libvulkan-driver")): + if not p[0] in pkgconfig: + continue + + pkgs = d.getVar('PACKAGES').split() + + fullp = p[1] + "-gcnano" + if fullp in pkgs: + rpkgs = " ".join(p[1:]) + d.setVar("DEBIAN_NOAUTONAME:" + fullp, "1") + d.appendVar("RREPLACES:" + fullp, rpkgs) + d.appendVar("RPROVIDES:" + fullp, rpkgs) + d.appendVar("RCONFLICTS:" + fullp, rpkgs) + if d.getVar("GCNANO_USERLAND_OUTPUT_LIBDIR") != d.getVar("libdir"): + d.appendVar("RDEPENDS:" + fullp, " gcnano-ldconf") + + # For -dev, the first element is both the Debian and original name + fullp += "-dev" + if fullp in pkgs: + rpkgs = " ".join([f"{q}-dev" for q in p[1:]]) + d.setVar("DEBIAN_NOAUTONAME:" + fullp, "1") + d.appendVar("RREPLACES:" + fullp, rpkgs) + d.appendVar("RPROVIDES:" + fullp, rpkgs) + d.appendVar("RCONFLICTS:" + fullp, rpkgs) +} + +# EGL, GLESv1, GLESv2 and VG run-time packages embed lib*.so to allow +# GPU stack to run properly +# NOTE: it's mandatory to libEGL.so, libGLESv2.so and libOpenVG.so availabale on filesystem +# because gcnano userland library try to make a dlopen on this library (with specific .so extension) +FILES:${PN} = "" +FILES:gcnano-ldconf = "${sysconfdir}/ld.so.conf.d/*" +FILES:libgal-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libGAL.so" +FILES:libgal-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libVSC.so" +FILES:libegl-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libEGL.so.* ${libdir}/libEGL.so*" +FILES:libgbm-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libgbm.so.* ${libdir}/libgbm.so.*" +FILES:libgbm-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libgbm_viv.so" +FILES:libgles1-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libGLESv1_CM.so.* ${libdir}/libGLESv1_CM.so*" +FILES:libgles2-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libGLESv2.so.* ${libdir}/libGLESv2.so*" +FILES:libopenvg-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libOpenVG.so.* ${libdir}/libOpenVG.so*" +FILES:libopenvx-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libOpenVX*.so* ${libdir}/libOpenVX.so.*" +FILES:libopenvx-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libArchModelSw.so" +FILES:libopenvx-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libNNArchPerf.so" +FILES:libopenvx-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libovxlib.so" +FILES:libopenvx-gcnano += "${includedir}/CL/cl_viv_vx_ext.h ${sysconfdir}/profile.d/*" +FILES:libovxkernels-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libNNGPUBinary.so" +FILES:libovxkernels-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libNNVXCBinary.so" +FILES:libovxkernels-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libOvx12VXCBinary.so" +FILES:libovxkernels-gcnano += "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libOvxGPUVXCBinary.so" +FILES:libopencl-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libOpenCL_VSI.so.* ${libdir}/libOpenCL_VSI.so.*" +FILES:libopencl-gcnano += "${sysconfdir}/OpenCL/vendors/*" +FILES:libvulkan-driver-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libvulkan_VSI.so.* ${libdir}/libvulkan_VSI.so.*" +FILES:libvulkan-driver-gcnano += "${sysconfdir}/vulkan/icd.d/*" +FILES:libglslc-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libGLSLC.so" +FILES:libclc-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libCLC.so" +FILES:libspirv-gcnano = "${GCNANO_USERLAND_OUTPUT_LIBDIR}/libSPIRV_viv.so" + +FILES:${PN}-dev = "" +FILES:libgal-gcnano-dev = "${libdir}/libGAL.so ${libdir}/libVSC.so" +FILES:libegl-gcnano-dev = "${includedir}/EGL ${includedir}/KHR ${libdir}/pkgconfig/egl.pc" +FILES:libgbm-gcnano-dev = "${libdir}/libgbm.so ${libdir}/libgbm_viv.so ${includedir}/gbm.h ${libdir}/pkgconfig/gbm.pc" +FILES:libgles1-gcnano-dev = "${includedir}/GLES ${libdir}/pkgconfig/glesv1_cm.pc" +FILES:libgles2-gcnano-dev = "${includedir}/GLES2 ${libdir}/pkgconfig/glesv2.pc" +FILES:libopenvg-gcnano-dev = "${includedir}/VG ${libdir}/pkgconfig/vg.pc" +FILES:libgles3-gcnano-dev = "${includedir}/GLES3" +FILES:libopenvg-gcnano-dev = "${includedir}/VG ${libdir}/pkgconfig/vg.pc" +FILES:libopenvx-gcnano-dev = "${libdir}/libOpenVX.so ${libdir}/libOpenVXU.so ${includedir}/VX" +FILES:libopenvx-gcnano-dev += "${libdir}/libArchModelSw.so" +FILES:libopenvx-gcnano-dev += "${libdir}/libNNArchPerf.so" +FILES:libopenvx-gcnano-dev += "${libdir}/libovxlib.so" +FILES:libovxkernels-gcnano-dev += "${libdir}/libNNGPUBinary.so" +FILES:libovxkernels-gcnano-dev += "${libdir}/libNNVXCBinary.so" +FILES:libovxkernels-gcnano-dev += "${libdir}/libOvx12VXCBinary.so" +FILES:libovxkernels-gcnano-dev += "${libdir}/libOvxGPUVXCBinary.so" +FILES:libopencl-gcnano-dev = "${libdir}/libOpenCL_VSI.so" +FILES:libvulkan-driver-gcnano-dev = "${libdir}/libvulkan_VSI.so" +FILES:libglslc-gcnano-dev = "${libdir}/libGLSLC.so" +FILES:libclc-gcnano-dev += "${libdir}/libCLC.so" +FILES:libspirv-gcnano-dev = "${libdir}/libSPIRV_viv.so" + +# Set gcnano-userland package with runtime dependencies on all packages +RDEPENDS:${PN} += "\ + libgal-gcnano \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'egl', 'libegl-gcnano', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'gbm', 'libgbm-gcnano', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv1', 'libgles1-gcnano', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'glesv2', 'libgles2-gcnano', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vg', 'libopenvg-gcnano', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'cl', 'libopencl-gcnano', '', d)} \ + ${@bb.utils.contains('GCNANO_PACKAGECONFIG', 'vulkan', 'libvulkan-driver-gcnano', '', d)} \ + " + +RDEPENDS:libgles1-gcnano += "libglslc-gcnano" +RDEPENDS:libgles2-gcnano += "libglslc-gcnano" +RDEPENDS:libopenvg-gcnano += "libglslc-gcnano" + +RDEPENDS:libopencl-gcnano += "libclc-gcnano libspirv-gcnano" +RDEPENDS:libopenvx-gcnano += "libclc-gcnano libovxkernels-gcnano" +RDEPENDS:libvulkan-driver-gcnano += "libglslc-gcnano libspirv-gcnano" + +RDEPENDS:libgles2-gcnano-dev += "libgles3-gcnano-dev" + +# Generate empty gcnano-userland package to install all dependencies +ALLOW_EMPTY:${PN} = "1" + +# Avoid QA Issue: No GNU_HASH in the elf binary +INSANE_SKIP:libgal-gcnano += "ldflags" +INSANE_SKIP:libegl-gcnano += "ldflags" +INSANE_SKIP:libgbm-gcnano += "ldflags" +INSANE_SKIP:libgles1-gcnano += "ldflags" +INSANE_SKIP:libgles2-gcnano += "ldflags" +INSANE_SKIP:libopenvg-gcnano += "ldflags" +INSANE_SKIP:libopenvx-gcnano += "ldflags" +INSANE_SKIP:libovxkernels-gcnano += "ldflags" +INSANE_SKIP:libclc-gcnano += "ldflags" +INSANE_SKIP:libopencl-gcnano += "ldflags" +INSANE_SKIP:libvulkan-driver-gcnano += "ldflags" +INSANE_SKIP:libglslc-gcnano += "ldflags" +INSANE_SKIP:libspirv-gcnano += "ldflags" + +# Avoid QA Issue: non -dev/-dbg/nativesdk- package contains symlink .so +INSANE_SKIP:libegl-gcnano += "dev-so" +INSANE_SKIP:libgles1-gcnano += "dev-so" +INSANE_SKIP:libgles2-gcnano += "dev-so" +INSANE_SKIP:libopenvg-gcnano += "dev-so" +INSANE_SKIP:libopenvx-gcnano += "dev-so" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/files/0001-meson-misdetects-64bit-atomics-on-mips-clang.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/files/0001-meson-misdetects-64bit-atomics-on-mips-clang.patch new file mode 100644 index 000000000..9cd9bee2d --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/files/0001-meson-misdetects-64bit-atomics-on-mips-clang.patch @@ -0,0 +1,25 @@ +From 3ef37c63f03ad6f2af407de350486fdd25e9132a Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Mon, 13 Jan 2020 15:23:47 -0800 +Subject: [PATCH] meson misdetects 64bit atomics on mips/clang + +Upstream-Status: Pending +Signed-off-by: Khem Raj + +--- + src/util/u_atomic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/u_atomic.c b/src/util/u_atomic.c +index 5a5eab4..e499516 100644 +--- a/src/util/u_atomic.c ++++ b/src/util/u_atomic.c +@@ -21,7 +21,7 @@ + * IN THE SOFTWARE. + */ + +-#if defined(MISSING_64BIT_ATOMICS) && defined(HAVE_PTHREAD) ++#if !defined(__clang__) && defined(MISSING_64BIT_ATOMICS) && defined(HAVE_PTHREAD) + + #include + #include diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/files/0001-meson.build-check-for-all-linux-host_os-combinations.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/files/0001-meson.build-check-for-all-linux-host_os-combinations.patch new file mode 100644 index 000000000..36c33f889 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/files/0001-meson.build-check-for-all-linux-host_os-combinations.patch @@ -0,0 +1,43 @@ +From 3b4d6b89f644b43e507c08181fef06db4326f9da Mon Sep 17 00:00:00 2001 +From: Alistair Francis +Date: Thu, 14 Nov 2019 13:04:49 -0800 +Subject: [PATCH] meson.build: check for all linux host_os combinations + +Make sure that we are also looking for our host_os combinations like +linux-musl etc. when assuming support for DRM/KMS. + +Also delete a duplicate line. + +Upstream-Status: Pending + +Signed-off-by: Anuj Mittal +Signed-off-by: Fabio Berton +Signed-off-by: Otavio Salvador +Signed-off-by: Alistair Francis + +--- + meson.build | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index 172c64a..9b5294c 100644 +--- a/meson.build ++++ b/meson.build +@@ -173,7 +173,7 @@ with_any_opengl = with_opengl or with_gles1 or with_gles2 + # Only build shared_glapi if at least one OpenGL API is enabled + with_shared_glapi = with_shared_glapi and with_any_opengl + +-system_has_kms_drm = ['openbsd', 'netbsd', 'freebsd', 'gnu/kfreebsd', 'dragonfly', 'linux', 'sunos', 'android'].contains(host_machine.system()) ++system_has_kms_drm = ['openbsd', 'netbsd', 'freebsd', 'gnu/kfreebsd', 'dragonfly', 'linux', 'sunos', 'android'].contains(host_machine.system()) or host_machine.system().startswith('linux') + + with_freedreno_kgsl = get_option('freedreno-kgsl') + if with_freedreno_kgsl +@@ -1076,7 +1076,7 @@ if cc.has_function('reallocarray') + endif + + # TODO: this is very incomplete +-if ['linux', 'cygwin', 'gnu', 'freebsd', 'gnu/kfreebsd', 'haiku', 'android'].contains(host_machine.system()) ++if ['linux', 'cygwin', 'gnu', 'freebsd', 'gnu/kfreebsd', 'haiku'].contains(host_machine.system()) or host_machine.system().startswith('linux') + pre_args += '-D_GNU_SOURCE' + elif host_machine.system() == 'sunos' + pre_args += '-D__EXTENSIONS__' diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa-gl_23.0.3.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa-gl_23.0.3.bb new file mode 100644 index 000000000..824e70ed4 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa-gl_23.0.3.bb @@ -0,0 +1,16 @@ +require mesa.inc + +SUMMARY += " (OpenGL only, no EGL/GLES)" + +PROVIDES = "virtual/libgl virtual/mesa" + +S = "${WORKDIR}/mesa-${PV}" + +TARGET_CFLAGS = "-I${STAGING_INCDIR}/drm" + +# At least one DRI rendering engine is required to build mesa. +# When no X11 is available, use osmesa for the rendering engine. +PACKAGECONFIG ??= "opengl gallium ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'x11', 'osmesa', d)}" +PACKAGECONFIG:class-target = "opengl gallium ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'x11', 'osmesa', d)}" + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa.inc new file mode 100644 index 000000000..10efff96f --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa.inc @@ -0,0 +1,353 @@ +SUMMARY = "A free implementation of the OpenGL API" +DESCRIPTION = "Mesa is an open-source implementation of the OpenGL specification - \ +a system for rendering interactive 3D graphics. \ +A variety of device drivers allows Mesa to be used in many different environments \ +ranging from software emulation to complete hardware acceleration for modern GPUs. \ +Mesa is used as part of the overall Direct Rendering Infrastructure and X.org \ +environment." + +HOMEPAGE = "http://mesa3d.org" +BUGTRACKER = "https://bugs.freedesktop.org" +SECTION = "x11" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://docs/license.rst;md5=63779ec98d78d823a9dc533a0735ef10" + +PE = "2" + +SRC_URI = "https://mesa.freedesktop.org/archive/mesa-${PV}.tar.xz \ + file://0001-meson.build-check-for-all-linux-host_os-combinations.patch \ + file://0001-meson-misdetects-64bit-atomics-on-mips-clang.patch \ + " + +SRC_URI[sha256sum] = "386362a5d80df3b096636b67f340e1ce67b705b44767d5bdd11d2ed1037192d5" + +UPSTREAM_CHECK_GITTAGREGEX = "mesa-(?P\d+(\.\d+)+)" + +#because we cannot rely on the fact that all apps will use pkgconfig, +#make eglplatform.h independent of MESA_EGL_NO_X11_HEADER +do_install:append() { + # sed can't find EGL/eglplatform.h as it doesn't get installed when glvnd enabled. + # So, check if EGL/eglplatform.h exists before running sed. + if ${@bb.utils.contains('PACKAGECONFIG', 'egl', 'true', 'false', d)} && [ -f ${D}${includedir}/EGL/eglplatform.h ]; then + sed -i -e 's/^#elif defined(__unix__) && defined(EGL_NO_X11)$/#elif defined(__unix__) \&\& defined(EGL_NO_X11) || ${@bb.utils.contains('PACKAGECONFIG', 'x11', '0', '1', d)}/' ${D}${includedir}/EGL/eglplatform.h + fi +} + +DEPENDS = "expat makedepend-native flex-native bison-native libxml2-native zlib chrpath-replacement-native python3-mako-native gettext-native" +EXTRANATIVEPATH += "chrpath-native" +PROVIDES = " \ + ${@bb.utils.contains('PACKAGECONFIG', 'opengl', 'virtual/libgl', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'glvnd', 'virtual/libglx', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'gles', 'virtual/libgles1 virtual/libgles2 virtual/libgles3', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'egl', 'virtual/egl', '', d)} \ + ${@bb.utils.contains('PACKAGECONFIG', 'gbm', 'virtual/libgbm', '', d)} \ + virtual/mesa \ + " + +inherit meson pkgconfig python3native gettext features_check + +BBCLASSEXTEND = "native nativesdk" + +ANY_OF_DISTRO_FEATURES = "opengl vulkan" + +PLATFORMS ??= "${@bb.utils.filter('PACKAGECONFIG', 'x11 wayland', d)}" + +MESA_LLVM_RELEASE ?= "" + +# set the MESA_BUILD_TYPE to either 'release' (default) or 'debug' +# by default the upstream mesa sources build a debug release +# here we assume the user will want a release build by default +MESA_BUILD_TYPE ?= "release" +def check_buildtype(d): + _buildtype = d.getVar('MESA_BUILD_TYPE') + if _buildtype not in ['release', 'debug']: + bb.fatal("unknown build type (%s), please set MESA_BUILD_TYPE to either 'release' or 'debug'" % _buildtype) + if _buildtype == 'debug': + return 'debugoptimized' + return 'plain' +MESON_BUILDTYPE = "${@check_buildtype(d)}" + +EXTRA_OEMESON = " \ + -Dshared-glapi=enabled \ + -Dglx-read-only-text=true \ + -Dplatforms='${@",".join("${PLATFORMS}".split())}' \ +" + +def strip_comma(s): + return s.strip(',') + +PACKAGECONFIG = " \ + gallium \ + ${@bb.utils.filter('DISTRO_FEATURES', 'x11 vulkan wayland', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'opengl egl gles gbm virgl', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 opengl', 'dri3', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 vulkan', 'dri3', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'vulkan', 'zink', '', d)} \ + ${@bb.utils.contains('LICENSE_FLAGS_ACCEPTED', 'commercial', 'video-codecs', '', d)} \ +" + +PACKAGECONFIG:append:class-native = "gallium-llvm r600" + +# "gbm" requires "opengl" +PACKAGECONFIG[gbm] = "-Dgbm=enabled,-Dgbm=disabled" + +X11_DEPS = "xorgproto virtual/libx11 libxext libxxf86vm libxdamage libxfixes xrandr" +# "x11" requires "opengl" +PACKAGECONFIG[x11] = ",-Dglx=disabled,${X11_DEPS}" +PACKAGECONFIG[wayland] = ",,wayland-native wayland libdrm wayland-protocols" + +PACKAGECONFIG[dri3] = "-Ddri3=enabled, -Ddri3=disabled, xorgproto libxshmfence" + +# Vulkan drivers need dri3 enabled +# amd could be enabled as well but requires gallium-llvm with llvm >= 3.9 +VULKAN_DRIVERS = "" +VULKAN_DRIVERS:append:x86 = ",intel" +VULKAN_DRIVERS:append:x86-64 = ",intel" +# i686 is a 32 bit override for mesa-native +VULKAN_DRIVERS:append:i686 = ",intel" +VULKAN_DRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'freedreno', ',freedreno', '', d)}" +VULKAN_DRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'broadcom', ',broadcom', '', d)}" +PACKAGECONFIG[vulkan] = "-Dvulkan-drivers=${@strip_comma('${VULKAN_DRIVERS}')}, -Dvulkan-drivers='',glslang-native vulkan-loader vulkan-headers" + +# mesa development and testing tools support, per driver +TOOLS = "" +TOOLS_DEPS = "" +TOOLS:append = "${@bb.utils.contains('PACKAGECONFIG', 'etnaviv', ',etnaviv', '', d)}" +TOOLS:append = "${@bb.utils.contains('PACKAGECONFIG', 'freedreno', ',freedreno', '', d)}" +TOOLS:append = "${@bb.utils.contains('PACKAGECONFIG', 'lima', ',lima', '', d)}" +TOOLS:append = "${@bb.utils.contains('PACKAGECONFIG', 'panfrost', ',panfrost', '', d)}" + +# dependencies for tools. +TOOLS_DEPS:append = "${@bb.utils.contains('PACKAGECONFIG', 'freedreno', ' ncurses libxml2 ', '', d)}" + +# the fdperf tool requires libconfig (a part of meta-oe) so it needs special +# treatment in addition to the usual 'freedreno tools'. +PACKAGECONFIG[freedreno-fdperf] = ",,libconfig" + +PACKAGECONFIG[tools] = "-Dtools=${@strip_comma('${TOOLS}')}, -Dtools='', ${TOOLS_DEPS}" + +PACKAGECONFIG[opengl] = "-Dopengl=true, -Dopengl=false" +PACKAGECONFIG[glvnd] = "-Dglvnd=true, -Dglvnd=false, libglvnd" + +# "gles" requires "opengl" +PACKAGECONFIG[gles] = "-Dgles1=enabled -Dgles2=enabled, -Dgles1=disabled -Dgles2=disabled" + +# "egl" requires "opengl" +PACKAGECONFIG[egl] = "-Degl=enabled, -Degl=disabled" + +# "opencl" requires libclc from meta-clang and spirv-tools from OE-Core +OPENCL_NATIVE = "${@bb.utils.contains('PACKAGECONFIG', 'freedreno', '-Dopencl-native=true', '', d)}" +PACKAGECONFIG[opencl] = "-Dgallium-opencl=icd -Dopencl-spirv=true ${OPENCL_NATIVE},-Dgallium-opencl=disabled -Dopencl-spirv=false,libclc spirv-tools" + +PACKAGECONFIG[broadcom] = "" +PACKAGECONFIG[etnaviv] = "" +PACKAGECONFIG[freedreno] = "" +PACKAGECONFIG[kmsro] = "" +PACKAGECONFIG[vc4] = "" +PACKAGECONFIG[v3d] = "" +PACKAGECONFIG[zink] = "" + +GALLIUMDRIVERS = "swrast" +# gallium swrast was found to crash Xorg on startup in x32 qemu +GALLIUMDRIVERS:x86-x32 = "" +GALLIUMDRIVERS:append:x86 = ",i915,iris,crocus" +GALLIUMDRIVERS:append:x86-64 = ",i915,iris,crocus" +# i686 is a 32 bit override for mesa-native +GALLIUMDRIVERS:append:i686 = ",i915,iris,crocus" + +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'etnaviv', ',etnaviv', '', d)}" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'freedreno', ',freedreno', '', d)}" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'kmsro', ',kmsro', '', d)}" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'vc4', ',vc4', '', d)}" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'v3d', ',v3d', '', d)}" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'zink', ',zink', '', d)}" + +# radeonsi requires LLVM +GALLIUMDRIVERS_RADEONSI = "${@bb.utils.contains('PACKAGECONFIG', 'r600', ',radeonsi', '', d)}" +GALLIUMDRIVERS_LLVM = "r300,nouveau${GALLIUMDRIVERS_RADEONSI}" +GALLIUMDRIVERS_LLVM:append:x86 = ",svga" +GALLIUMDRIVERS_LLVM:append:x86-64 = ",svga" +# i686 is a 32 bit override for mesa-native +GALLIUMDRIVERS_LLVM:append:i686 = ",svga" + +PACKAGECONFIG[r600] = "" +PACKAGECONFIG[virgl] = "" + +GALLIUMDRIVERS:append = "${@bb.utils.contains('PACKAGECONFIG', 'gallium-llvm', ',${GALLIUMDRIVERS_LLVM}', '', d)}" +GALLIUMDRIVERS:append = "${@bb.utils.contains('PACKAGECONFIG', 'r600', ',r600', '', d)}" +GALLIUMDRIVERS:append = "${@bb.utils.contains('PACKAGECONFIG', 'virgl', ',virgl', '', d)}" + +PACKAGECONFIG[gallium] = "-Dgallium-drivers=${@strip_comma('${GALLIUMDRIVERS}')}, -Dgallium-drivers='', libdrm" +PACKAGECONFIG[gallium-llvm] = "-Dllvm=enabled -Dshared-llvm=enabled, -Dllvm=disabled, llvm${MESA_LLVM_RELEASE} llvm-native \ + elfutils" +PACKAGECONFIG[xa] = "-Dgallium-xa=enabled, -Dgallium-xa=disabled" +PACKAGECONFIG[va] = "-Dgallium-va=enabled,-Dgallium-va=disabled,libva-initial" + +PACKAGECONFIG[vdpau] = "-Dgallium-vdpau=enabled,-Dgallium-vdpau=disabled,libvdpau" + +PACKAGECONFIG[lima] = "" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'lima', ',lima', '', d)}" + +PACKAGECONFIG[panfrost] = "" +GALLIUMDRIVERS:append ="${@bb.utils.contains('PACKAGECONFIG', 'panfrost', ',panfrost', '', d)}" + +PACKAGECONFIG[vulkan-beta] = "-Dvulkan-beta=true,-Dvulkan-beta=false" + +PACKAGECONFIG[osmesa] = "-Dosmesa=true,-Dosmesa=false" + +PACKAGECONFIG[perfetto] = "-Dperfetto=true,-Dperfetto=false,libperfetto" + +PACKAGECONFIG[unwind] = "-Dlibunwind=enabled,-Dlibunwind=disabled,libunwind" + +PACKAGECONFIG[lmsensors] = "-Dlmsensors=enabled,-Dlmsensors=disabled,lmsensors" + +VIDEO_CODECS = "vc1dec,h264dec,h264enc,h265dec,h265enc" +PACKAGECONFIG[video-codecs] = "-Dvideo-codecs=${@strip_comma('${VIDEO_CODECS}')}, -Dvideo-codecs=''" + +# llvmpipe is slow if compiled with -fomit-frame-pointer (e.g. -O2) +FULL_OPTIMIZATION:append = " -fno-omit-frame-pointer" + +CFLAGS:append:armv5 = " -DMISSING_64BIT_ATOMICS" +CFLAGS:append:armv6 = " -DMISSING_64BIT_ATOMICS" + +# Remove the mesa dependency on mesa-dev, as mesa is empty +DEV_PKG_DEPENDENCY = "" + +# Khronos documentation says that include/GLES2/gl2ext.h can be used for +# OpenGL ES 3 specification as well as for OpenGL ES 2. +# There can be applications including GLES2/gl2ext.h instead of GLES3/gl3ext.h +# meaning we should probably bring in GLES2/gl2ext.h if someone asks for +# development package of libgles3. +RDEPENDS:libgles3-mesa-dev += "libgles2-mesa-dev" + +RDEPENDS:libopencl-mesa += "${@bb.utils.contains('PACKAGECONFIG', 'opencl', 'libclc spirv-tools', '', d)}" + +PACKAGES =+ "libegl-mesa libegl-mesa-dev \ + libosmesa libosmesa-dev \ + libgl-mesa libgl-mesa-dev \ + libglx-mesa libglx-mesa-dev \ + libglapi libglapi-dev \ + libgbm libgbm-dev \ + libgles1-mesa libgles1-mesa-dev \ + libgles2-mesa libgles2-mesa-dev \ + libgles3-mesa libgles3-mesa-dev \ + libopencl-mesa libopencl-mesa-dev \ + libxatracker libxatracker-dev \ + mesa-megadriver mesa-vulkan-drivers \ + mesa-vdpau-drivers mesa-tools \ + " + +do_install:append () { + # Drivers never need libtool .la files + rm -f ${D}${libdir}/dri/*.la + rm -f ${D}${libdir}/egl/*.la + rm -f ${D}${libdir}/gallium-pipe/*.la + rm -f ${D}${libdir}/gbm/*.la + + # libwayland-egl has been moved to wayland 1.15+ + rm -f ${D}${libdir}/libwayland-egl* + rm -f ${D}${libdir}/pkgconfig/wayland-egl.pc +} + +# For the packages that make up the OpenGL interfaces, inject variables so that +# they don't get Debian-renamed (which would remove the -mesa suffix), and +# RPROVIDEs/RCONFLICTs on the generic libgl name. +python __anonymous() { + pkgconfig = (d.getVar('PACKAGECONFIG') or "").split() + suffix = "" + if "-native" in d.getVar("PN"): + suffix = "-native" + for p in (("egl", "libegl", "libegl1"), + ("opengl", "libgl", "libgl1"), + ("glvnd", "libglx",), + ("gles", "libgles1", "libglesv1-cm1"), + ("gles", "libgles2", "libglesv2-2"), + ("gles", "libgles3",), + ("opencl", "libopencl",)): + if not p[0] in pkgconfig: + continue + mlprefix = d.getVar("MLPREFIX") + fullp = mlprefix + p[1] + "-mesa" + suffix + mlprefix = d.getVar("MLPREFIX") + pkgs = " " + " ".join(mlprefix + x + suffix for x in p[1:]) + d.setVar("DEBIAN_NOAUTONAME:" + fullp, "1") + d.appendVar("RREPLACES:" + fullp, pkgs) + d.appendVar("RPROVIDES:" + fullp, pkgs) + d.appendVar("RCONFLICTS:" + fullp, pkgs) + + d.appendVar("RRECOMMENDS:" + fullp, " ${MLPREFIX}mesa-megadriver" + suffix) + + # For -dev, the first element is both the Debian and original name + fullp = mlprefix + p[1] + "-mesa-dev" + suffix + pkgs = " " + mlprefix + p[1] + "-dev" + suffix + d.setVar("DEBIAN_NOAUTONAME:" + fullp, "1") + d.appendVar("RREPLACES:" + fullp, pkgs) + d.appendVar("RPROVIDES:" + fullp, pkgs) + d.appendVar("RCONFLICTS:" + fullp, pkgs) +} + +python mesa_populate_packages() { + pkgs = ['mesa', 'mesa-dev', 'mesa-dbg'] + for pkg in pkgs: + d.setVar("RPROVIDES:%s" % pkg, pkg.replace("mesa", "mesa-dri", 1)) + d.setVar("RCONFLICTS:%s" % pkg, pkg.replace("mesa", "mesa-dri", 1)) + d.setVar("RREPLACES:%s" % pkg, pkg.replace("mesa", "mesa-dri", 1)) + + import re + dri_drivers_root = oe.path.join(d.getVar('PKGD'), d.getVar('libdir'), "dri") + if os.path.isdir(dri_drivers_root): + dri_pkgs = sorted(os.listdir(dri_drivers_root)) + lib_name = d.expand("${MLPREFIX}mesa-megadriver") + for p in dri_pkgs: + m = re.match(r'^(.*)_dri\.so$', p) + if m: + pkg_name = " ${MLPREFIX}mesa-driver-%s" % legitimize_package_name(m.group(1)) + d.appendVar("RPROVIDES:%s" % lib_name, pkg_name) + d.appendVar("RCONFLICTS:%s" % lib_name, pkg_name) + d.appendVar("RREPLACES:%s" % lib_name, pkg_name) + + pipe_drivers_root = os.path.join(d.getVar('libdir'), "gallium-pipe") + do_split_packages(d, pipe_drivers_root, r'^pipe_(.*)\.so$', 'mesa-driver-pipe-%s', 'Mesa %s pipe driver', extra_depends='') +} + +PACKAGESPLITFUNCS =+ "mesa_populate_packages" + +PACKAGES_DYNAMIC += "^mesa-driver-.*" +PACKAGES_DYNAMIC:class-native = "^mesa-driver-.*-native" + +FILES:mesa-megadriver = "${libdir}/dri/* ${datadir}/drirc.d" +FILES:mesa-vulkan-drivers = "${libdir}/libvulkan_*.so ${datadir}/vulkan" +FILES:${PN}-vdpau-drivers = "${libdir}/vdpau/*.so.*" +FILES:libegl-mesa = "${libdir}/libEGL*.so.* ${datadir}/glvnd/egl_vendor.d" +FILES:libgbm = "${libdir}/libgbm.so.*" +FILES:libgles1-mesa = "${libdir}/libGLESv1*.so.*" +FILES:libgles2-mesa = "${libdir}/libGLESv2.so.*" +FILES:libgl-mesa = "${libdir}/libGL.so.*" +FILES:libglx-mesa = "${libdir}/libGLX*.so.*" +FILES:libopencl-mesa = "${libdir}/libMesaOpenCL.so.* ${libdir}/gallium-pipe/*.so ${sysconfdir}/OpenCL/vendors/mesa.icd" +FILES:libglapi = "${libdir}/libglapi.so.*" +FILES:libosmesa = "${libdir}/libOSMesa.so.*" +FILES:libxatracker = "${libdir}/libxatracker.so.*" + +FILES:${PN}-dev = "${libdir}/pkgconfig/dri.pc ${includedir}/vulkan ${libdir}/vdpau/*.so" +FILES:libegl-mesa-dev = "${libdir}/libEGL*.* ${includedir}/EGL ${includedir}/KHR ${libdir}/pkgconfig/egl.pc" +FILES:libgbm-dev = "${libdir}/libgbm.* ${libdir}/pkgconfig/gbm.pc ${includedir}/gbm.h" +FILES:libgl-mesa-dev = "${libdir}/libGL.* ${includedir}/GL ${libdir}/pkgconfig/gl.pc" +FILES:libglx-mesa-dev = "${libdir}/libGLX*.*" +FILES:libglapi-dev = "${libdir}/libglapi.*" +FILES:libgles1-mesa-dev = "${libdir}/libGLESv1*.* ${includedir}/GLES ${libdir}/pkgconfig/glesv1*.pc" +FILES:libgles2-mesa-dev = "${libdir}/libGLESv2.* ${includedir}/GLES2 ${libdir}/pkgconfig/glesv2.pc" +FILES:libgles3-mesa-dev = "${includedir}/GLES3" +FILES:libopencl-mesa-dev = "${libdir}/libMesaOpenCL.so" +FILES:libosmesa-dev = "${libdir}/libOSMesa.* ${includedir}/GL/osmesa.h ${libdir}/pkgconfig/osmesa.pc" +FILES:libxatracker-dev = "${libdir}/libxatracker.so ${libdir}/libxatracker.la \ + ${includedir}/xa_tracker.h ${includedir}/xa_composite.h ${includedir}/xa_context.h \ + ${libdir}/pkgconfig/xatracker.pc" +# catch all to get all the tools and data +FILES:${PN}-tools = "${bindir} ${datadir}" +ALLOW_EMPTY:${PN}-tools = "1" + +# Fix upgrade path from mesa to mesa-megadriver +RREPLACES:mesa-megadriver = "mesa" +RCONFLICTS:mesa-megadriver = "mesa" +RPROVIDES:mesa-megadriver = "mesa" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa_23.0.3.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa_23.0.3.bb new file mode 100644 index 000000000..7203e8ed7 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa_23.0.3.bb @@ -0,0 +1,3 @@ +require ${BPN}.inc + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa_23.0.3.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa_23.0.3.bbappend new file mode 100644 index 000000000..66bf2098a --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/mesa/mesa_23.0.3.bbappend @@ -0,0 +1,28 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/mesa:" + +PACKAGECONFIG:stm32mp1common = "${@bb.utils.filter('DISTRO_FEATURES', 'wayland ', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'opengl egl gles gbm', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 opengl', 'x11', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 vulkan', 'dri3', '', d)} \ + \ + gallium \ + " + +PACKAGECONFIG:stm32mp2common = " \ + gallium \ + ${@bb.utils.filter('DISTRO_FEATURES', 'wayland vulkan', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'opengl egl gles gbm', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 opengl', 'x11 dri3', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 vulkan', 'x11 dri3', '', d)} \ + " + +PACKAGECONFIG = " \ + gallium \ + ${@bb.utils.filter('DISTRO_FEATURES', 'x11 vulkan wayland', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'opengl egl gles gbm virgl', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 opengl', 'dri3', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'x11 vulkan', 'dri3', '', d)} \ +" + +# Enable Etnaviv support +GALLIUMDRIVERS:append:stm32mpcommon = ",etnaviv,kmsro" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/wayland/weston-init/check-gpu b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/wayland/weston-init/check-gpu index 8be15e88b..76e14cdec 100755 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/wayland/weston-init/check-gpu +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-graphics/wayland/weston-init/check-gpu @@ -9,16 +9,17 @@ #=============================================================================== check_dt_status() { - gcnano_dir=$(ls /proc/device-tree/soc/ | grep gpu) - if [ -z "$gcnano_dir" ] || [ ! -d /proc/device-tree/soc/$gcnano_dir ]; + gcnano_path=$(find /proc/device-tree/soc* | grep gpu | head -n 1) + gcnano_dir=$(basename $gcnano_path) + if [ -z "$gcnano_dir" ] || [ ! -d $gcnano_path ]; then echo "Gcnano in /proc/device-tree/soc/ is not available" > /dev/kmsg force_no_dtb_gpu="1" else - if [ ! -f /proc/device-tree/soc/$gcnano_dir/status ]; then + if [ ! -f $gcnano_path/status ]; then gcnano_status="okay" else - if $(grep -q "okay" /proc/device-tree/soc/$gcnano_dir/status); then + if $(grep -q "okay" $gcnano_path/status); then gcnano_status="okay" fi fi @@ -96,8 +97,14 @@ then sed -i "s/OPTARGS=--use-pixman/#OPTARGS=--use-pixman/g" /etc/default/weston sed -i "/#Autogenerated/d" /etc/default/weston fi + if [ ! -f /etc/default/weston ]; + then + echo "#Autogenerated" > /etc/default/weston + echo "#OPTARGS=--use-pixman" >> /etc/default/weston + echo "WESTON_USER=root" >> /etc/default/weston + fi else - if [ -f /etc/default/weston ] && $(grep -q "Autogenerated" /etc/default/weston) ; + if [ -f /etc/default/weston ] && $(grep -q "pixman" /etc/default/weston) ; then echo "Weston already configured on pixman" > /dev/kmsg else diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb index 092247394..1108d1b2e 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Digi International Inc. +# Copyright (C) 2022, Digi International Inc. # SUMMARY = "Gstreamer framework packagegroup for DEY image" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/files/fonts.tar.gz b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/files/fonts.tar.gz new file mode 100644 index 000000000..0a564c426 Binary files /dev/null and b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/files/fonts.tar.gz differ diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp2-common.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp2-common.inc new file mode 100644 index 000000000..2ccdcf72d --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp2-common.inc @@ -0,0 +1,172 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/optee-os:" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +PROVIDES += "virtual/optee-os" +RPROVIDES:${PN} += "virtual/optee-os virtual/systemd-bootconf" + +CVE_PRODUCT = "op-tee:op-tee_os" + +############################################################# +#inherit external-dt scp-firmware + +# Enable use of scp-firmware shared folder +STAGING_SCPFW_DIR = "${TMPDIR}/work-shared/${MACHINE}/scp-firmware" + +do_compile[depends] += "scp-firmware:do_configure" + + +STAGING_EXTDT_DIR = "${TMPDIR}/work-shared/${MACHINE}/external-dt" +############################################################# + +B = "${WORKDIR}/build" +# Configure build dir for externalsrc class usage through devtool +EXTERNALSRC_BUILD:pn-${PN} = "${WORKDIR}/build" + +DEPENDS += "dtc-native" +DEPENDS += "python3-pycryptodomex-native" +DEPENDS += "python3-pyelftools-native" +DEPENDS += "libgcc python3-cryptography-native" +DEPENDS += "python3-pillow-native" + +inherit deploy python3native + +OPTEEMACHINE ?= "${MACHINE}" +OPTEEOUTPUTMACHINE ?= "${MACHINE}" + +# Default log level +ST_OPTEE_DEBUG_LOG_LEVEL ??= "2" + +# default core debug +ST_OPTEE_CORE_DEBUG ??= "y" +ST_OPTEE_CORE_DEBUG:stm32mp15common ?= "n" + +EXTRA_OEMAKE = "PLATFORM=${OPTEEMACHINE}" +EXTRA_OEMAKE += "CROSS_COMPILE_core=${HOST_PREFIX}" +EXTRA_OEMAKE += "CROSS_COMPILE_ta_arm64=${HOST_PREFIX}" +EXTRA_OEMAKE += "${@bb.utils.contains('TUNE_FEATURES', 'aarch64', 'ARCH=arm CFG_ARM64_core=y', 'ARCH=arm CFG_ARM32_core=y CROSS_COMPILE_ta_arm32=${HOST_PREFIX}', d)}" +EXTRA_OEMAKE += "NOWERROR=1" +EXTRA_OEMAKE += "LDFLAGS=" +# Set external-dt support +EXTRA_OEMAKE += "${@bb.utils.contains('EXTERNAL_DT_ENABLED', '1', 'CFG_EXT_DTS=${STAGING_EXTDT_DIR}/optee', '', d)}" +# Set scp-firmware support +EXTRA_OEMAKE += "CFG_SCP_FIRMWARE=${STAGING_SCPFW_DIR}" + +# debug and trace +EXTRA_OEMAKE += "${@bb.utils.contains('ST_OPTEE_DEBUG_TRACE', '1', 'CFG_TEE_CORE_LOG_LEVEL=${ST_OPTEE_DEBUG_LOG_LEVEL} CFG_TEE_CORE_DEBUG=${ST_OPTEE_CORE_DEBUG}', '', d)}" + +# OPTEE in sysram +EXTRA_OEMAKE:append:stm32mp15common = " ${@bb.utils.contains('ST_OPTEE_IN_SYSRAM', '1', 'CFG_STM32MP1_OPTEE_IN_SYSRAM=y', '', d)}" + +# SCP firmware +#EXTRA_OEMAKE_SCP_FIRMWARE ??= "" +EXTRA_OEMAKE_SCP_FIRMWARE:stm32mp15common ??= "" +EXTRA_OEMAKE_SCP_FIRMWARE:stm32mp13common ??= "${@bb.utils.contains('ENABLE_SCMI_SCPFW', '1', 'CFG_SCMI_SCPFW=y', 'CFG_SCMI_SCPFW=n', d)}" +EXTRA_OEMAKE_SCP_FIRMWARE:stm32mp25common ??= "CFG_SCMI_SCPFW=y" +EXTRA_OEMAKE += " ${EXTRA_OEMAKE_SCP_FIRMWARE}" + +OPTEE_ARCH:armv7a = "arm32" +OPTEE_ARCH:armv7ve = "arm32" +OPTEE_ARCH:aarch64 = "arm64" + +do_configure:prepend(){ + chmod 755 ${S}/scripts/bin_to_c.py +} + +do_compile() { + export CFLAGS="${CFLAGS} --sysroot=${STAGING_DIR_HOST}" + export OPENSSL_MODULES=${STAGING_LIBDIR_NATIVE}/ossl-modules/ + if [ -n "${OPTEE_CONF}" ]; then + for conf in ${OPTEE_CONF}; do + # Configure SOC switch + soc_extra="" + for soc in ${STM32MP_SOC_NAME}; do + if [ "$(echo ${conf} | grep -c ${soc})" -eq 1 ]; then + soc_extra="$(echo CFG_${soc} | awk '{print toupper($0)}')=y" + break + fi + done + + oe_runmake -C ${S} O=${B}/${conf} CFG_EMBED_DTB_SOURCE_FILE=${conf}.dts ${soc_extra} + done + else + oe_runmake -C ${S} O=${B}/out + fi +} + +do_install:stm32mp1common() { + #install TA devkit + install -d ${D}${includedir}/optee/export-user_ta/ + + if [ -n "${OPTEE_CONF}" ]; then + for conf in ${OPTEE_CONF}; do + for f in ${B}/${conf}/export-ta_${OPTEE_ARCH}/* ; do + cp -aRf $f ${D}${includedir}/optee/export-user_ta/ + done + done + fi +} +do_install:stm32mp2common() { + #install TA devkit + install -d ${D}${includedir}/optee/export-user_ta_arm32/ + install -d ${D}${includedir}/optee/export-user_ta_arm64/ + + if [ -n "${OPTEE_CONF}" ]; then + for conf in ${OPTEE_CONF}; do + if [ -d ${B}/${conf}/export-ta_arm32 ]; then + for f in ${B}/${conf}/export-ta_arm32/* ; do + cp -aRf $f ${D}${includedir}/optee/export-user_ta_arm32/ + done + fi + if [ -d ${B}/${conf}/export-ta_arm64 ]; then + for f in ${B}/${conf}/export-ta_arm64/* ; do + cp -aRf $f ${D}${includedir}/optee/export-user_ta_arm64/ + done + fi + done + fi +} + + +# Configure optee binaries +OPTEE_HEADER = "tee-header_v2" +OPTEE_PAGEABLE = "tee-pageable_v2" +OPTEE_PAGER = "tee-pager_v2" +OPTEE_SUFFIX = "bin" +# Output the ELF generated +ELF_DEBUG_ENABLE ?= "" +OPTEE_ELF = "tee" +OPTEE_ELF_SUFFIX = "elf" + +do_deploy[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}/optee" +do_deploy() { + install -d ${DEPLOYDIR}/debug + if [ -n "${OPTEE_CONF}" ]; then + for conf in ${OPTEE_CONF}; do + install -m 644 ${B}/${conf}/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_HEADER}-${conf}.${OPTEE_SUFFIX} + install -m 644 ${B}/${conf}/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGER}-${conf}.${OPTEE_SUFFIX} + install -m 644 ${B}/${conf}/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGEABLE}-${conf}.${OPTEE_SUFFIX} + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -m 644 ${B}/${conf}/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} ${DEPLOYDIR}/debug/${OPTEE_ELF}-${conf}.${OPTEE_ELF_SUFFIX} + fi + done + else + install -m 644 ${B}/core/${OPTEE_HEADER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_HEADER}.${OPTEE_SUFFIX} + install -m 644 ${B}/core/${OPTEE_PAGER}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGER}.${OPTEE_SUFFIX} + install -m 644 ${B}/core/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} ${DEPLOYDIR}/${OPTEE_PAGEABLE}.${OPTEE_SUFFIX} + if [ -n "${ELF_DEBUG_ENABLE}" ]; then + install -m 644 ${B}/core/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} ${DEPLOYDIR}/debug/${OPTEE_ELF}.${OPTEE_ELF_SUFFIX} + fi + fi +} +addtask deploy before do_build after do_compile + +FILES:${PN} = "${nonarch_base_libdir}/firmware/" +FILES:${PN}-dev = "/usr/include/optee" + +INSANE_SKIP:${PN}-dev = "staticdev" + +INHIBIT_PACKAGE_STRIP = "1" +# --------------------------------------------------------------------- +# Avoid QA Issue: contains reference to TMPDIR [buildpaths] +INSANE_SKIP:${PN} += "buildpaths" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_%.bbappend b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_3.16.0.bbappend similarity index 71% rename from meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_%.bbappend rename to meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_3.16.0.bbappend index d3367b5ec..3a1aba0b5 100644 --- a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_%.bbappend +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_3.16.0.bbappend @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Digi International Inc. +# Copyright (C) 2022, Digi International Inc. # # Select internal or Github OPTEE repo @@ -14,3 +14,6 @@ SRC_URI = " \ ${OPTEE_GIT_URI};branch=${SRCBRANCH};name=os \ file://fonts.tar.gz;subdir=git;name=fonts \ " + +# If TF enabled, force use of HUK in OTP bits +EXTRA_OEMAKE += "${@oe.utils.conditional('TRUSTFENCE_ENABLED', '1', 'CFG_OTP_HUK=1', '', d)}" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_3.19.0.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_3.19.0.bb new file mode 100644 index 000000000..2fe62ea76 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/optee/optee-os-stm32mp_3.19.0.bb @@ -0,0 +1,62 @@ +SUMMARY = "OPTEE TA development kit for stm32mp" +LICENSE = "BSD-2-Clause & BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=c1f21c4f72f372ef38a5a4aee55ec173" + +# Select internal or Github OPTEE repo +OPTEE_URI_STASH = "${DIGI_MTK_GIT}/emp/optee_os.git;protocol=ssh" +OPTEE_URI_GITHUB = "${DIGI_GITHUB_GIT}/optee_os.git;protocol=https" +OPTEE_GIT_URI ?= "${@oe.utils.conditional('DIGI_INTERNAL_GIT', '1' , '${OPTEE_URI_STASH}', '${OPTEE_URI_GITHUB}', d)}" + +SRCBRANCH = "3.19.0/stm/master" +SRCREV = "${AUTOREV}" + +SRC_URI = " \ + ${OPTEE_GIT_URI};branch=${SRCBRANCH};name=os \ + file://fonts.tar.gz;subdir=git;name=fonts \ +" + +SRC_URI[fonts.sha256sum] = "4941e8bb6d8ac377838e27b214bf43008c496a24a8f897e0b06433988cbd53b2" + +OPTEE_VERSION = "3.19.0" +OPTEE_SUBVERSION = "stm32mp" +OPTEE_RELEASE = "beta-r1" + +PV = "${OPTEE_VERSION}-${OPTEE_SUBVERSION}-${OPTEE_RELEASE}" + +ARCHIVER_ST_BRANCH = "${OPTEE_VERSION}-${OPTEE_SUBVERSION}" +ARCHIVER_ST_REVISION = "${PV}" +ARCHIVER_COMMUNITY_BRANCH = "master" +ARCHIVER_COMMUNITY_REVISION = "${OPTEE_VERSION}" + +S = "${WORKDIR}/git" + +OPTEEMACHINE ?= "stm32mp1" +OPTEEMACHINE:stm32mp1common = "stm32mp1" +OPTEEMACHINE:stm32mp2common = "stm32mp2" + +OPTEEOUTPUTMACHINE ?= "stm32mp1" +OPTEEOUTPUTMACHINE:stm32mp1common = "stm32mp1" +OPTEEOUTPUTMACHINE:stm32mp2common = "stm32mp2" + +# The package is empty but must be generated to avoid apt-get installation issue +ALLOW_EMPTY:${PN} = "1" + +require optee-os-stm32mp2-common.inc + +# Specific for revA board +EXTRA_OEMAKE_REVA:stm32mp25revabcommon:append = " CFG_STM32MP25x_REVA=y " +EXTRA_OEMAKE += " ${EXTRA_OEMAKE_REVA}" + +# --------------------------------- +# Configure archiver use +# --------------------------------- +include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'optee-os-stm32mp-archiver.inc','')} + +# --------------------------------- +# Configure default preference to manage dynamic selection between tarball and github +# --------------------------------- +STM32MP_SOURCE_SELECTION ?= "tarball" + +DEFAULT_PREFERENCE = "${@bb.utils.contains('STM32MP_SOURCE_SELECTION', 'github', '-1', '1', d)}" + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc new file mode 100644 index 000000000..c3a587bc1 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware-archiver.inc @@ -0,0 +1,10 @@ +# +# Archiver Configuration +# +SRC_URI:append = " file://README.HOW_TO.txt " +COPYLEFT_LICENSE_INCLUDE:append = " BSD-3* " + +inherit archiver +ARCHIVER_MODE[src] = "original" + +inherit archiver_stm32mp_clean diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb new file mode 100644 index 000000000..b78447ab6 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware.bb @@ -0,0 +1,74 @@ +SUMMARY = "SCP Firmware for stm32mp" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://${S}/license.md;md5=ef610a65bfb6d16f79778877cbfd45df" + +SRC_URI = "gitsm://github.com/ARM-software/SCP-firmware;protocol=https;nobranch=1" +SRCREV = "0c7236b1851d90124210a0414fd982dc55322c7c" + +SRC_URI += " \ + file://0001-2.12-stm32mp-r1.patch \ + file://0001-Correct-git-error.patch \ +" + +SCPFW_VERSION = "2.12" +SCPFW_SUBVERSION = "stm32mp" +SCPFW_RELEASE = "r1" + +PV = "${SCPFW_VERSION}-${SCPFW_SUBVERSION}-${SCPFW_RELEASE}" + +S = "${WORKDIR}/git" + +################################################################### +#inherit scp-firmware + +# Enable use of scp-firmware shared folder +STAGING_SCPFW_DIR = "${TMPDIR}/work-shared/${MACHINE}/scp-firmware" + +do_compile[depends] += "scp-firmware:do_configure" +################################################################### + +PACKAGE_ARCH = "${MACHINE_ARCH}" +COMPATIBLE_MACHINE = "(stm32mpcommon)" + +# Do not remove source code, even if rm_work is configured +RM_WORK_EXCLUDE += "${PN}" + +# ----------------------------------------------- +# Enable use of work-shared folder +# Make sure to move ${S} to STAGING_SCPFW_DIR. We can't just +# create the symlink in advance as the git fetcher can't cope with +# the symlink. +do_unpack[cleandirs] += "${S}" +do_unpack[cleandirs] += "${STAGING_SCPFW_DIR}" +do_clean[cleandirs] += "${S}" +do_clean[cleandirs] += "${STAGING_SCPFW_DIR}" +python do_symlink_scpfirmwaresrc() { + # Specific part to update devtool-source class + if bb.data.inherits_class('devtool-source', d): + # We don't want to move the source to STAGING_SCPFW_DIR here + if d.getVar('STAGING_SCPFW_DIR', d): + d.setVar('STAGING_SCPFW_DIR', '${S}') + + # Copy/Paste from kernel class with adaptation to SCPFW var + s = d.getVar("S") + if s[-1] == '/': + # drop trailing slash, so that os.symlink(scpscr, s) doesn't use s as directory name and fail + s=s[:-1] + scpscr = d.getVar("STAGING_SCPFW_DIR") + if s != scpscr: + bb.utils.mkdirhier(scpscr) + bb.utils.remove(scpscr, recurse=True) + if d.getVar("EXTERNALSRC"): + # With EXTERNALSRC S will not be wiped so we can symlink to it + os.symlink(s, scpscr) + else: + import shutil + shutil.move(s, scpscr) + os.symlink(scpscr, s) +} +addtask symlink_scpfirmwaresrc before do_patch do_configure after do_unpack + +# --------------------------------- +# Configure archiver use +# --------------------------------- +include ${@oe.utils.ifelse(d.getVar('ST_ARCHIVER_ENABLE') == '1', 'scp-firmware-archiver.inc','')} diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch new file mode 100644 index 000000000..65c88f23a --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-2.12-stm32mp-r1.patch @@ -0,0 +1,5722 @@ +From 223bf375c59e78bd4791a3ae40eb9bdc6d361199 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Mon, 27 Nov 2023 09:44:21 +0100 +Subject: [PATCH] 2.12-stm32mp-r1 + +Signed-off-by: Christophe Priouzeau +--- + framework/include/fwk_dlist.h | 4 +- + framework/include/fwk_slist.h | 4 +- + framework/src/fwk_dlist.c | 6 +- + module/clock/include/mod_clock.h | 60 +- + module/clock/src/mod_clock.c | 33 + + module/optee/clock/src/mod_optee_clock.c | 81 +- + .../include/mod_resource_perms.h | 6 + + module/scmi/include/mod_scmi_std.h | 7 +- + .../scmi_clock/include/internal/scmi_clock.h | 71 ++ + module/scmi_clock/src/mod_scmi_clock.c | 245 ++++++ + .../include/mod_voltage_domain.h | 4 +- + product/optee-stm32mp1/fw/CMakeLists.txt | 7 +- + product/optee-stm32mp1/fw/Firmware.cmake | 15 +- + product/optee-stm32mp1/fw/config_all.c | 797 ++++++++++++++++++ + product/optee-stm32mp1/fw/config_mbx_smt.c | 68 -- + product/optee-stm32mp1/fw/config_scmi.c | 55 -- + .../optee-stm32mp1/fw/config_scmi_clocks.c | 254 ------ + .../fw/config_scmi_reset_domains.c | 204 ----- + .../fw/config_scmi_voltage_domains.c | 262 ------ + .../CMakeLists.txt | 6 +- + .../module/psu_optee_regulator/Module.cmake | 9 + + .../include/mod_psu_optee_regulator.h | 25 + + .../src/mod_psu_optee_regulator.c | 190 +++++ + .../module/stm32_pmic_regu/Module.cmake | 9 - + .../include/mod_stm32_pmic_regu.h | 24 - + .../stm32_pmic_regu/src/mod_stm32_pmic_regu.c | 367 -------- + .../module/stm32_pwr_regu/Module.cmake | 9 - + .../include/mod_stm32_pwr_regu.h | 19 - + .../stm32_pwr_regu/src/mod_stm32_pwr_regu.c | 293 ------- + .../CMakeLists.txt | 9 +- + .../module/stm32_regu_consumer/Module.cmake | 9 + + .../include/mod_stm32_regu_consumer.h | 37 + + .../src/mod_stm32_regu_consumer.c | 343 ++++++++ + product/optee-stm32mp2/fw/CMakeLists.txt | 24 + + product/optee-stm32mp2/fw/Firmware.cmake | 57 ++ + product/optee-stm32mp2/fw/Toolchain-GNU.cmake | 22 + + product/optee-stm32mp2/fw/config_all.c | 793 +++++++++++++++++ + product/optee-stm32mp2/include/fmw_io.h | 17 + + product/optee-stm32mp2/include/fmw_log.h | 16 + + .../optee-stm32mp2/include/gnu/stubs-soft.h | 0 + product/optee-stm32mp2/include/scmi_agents.h | 29 + + .../module/psu_optee_regulator/CMakeLists.txt | 17 + + .../module/psu_optee_regulator/Module.cmake | 9 + + .../include/mod_psu_optee_regulator.h | 25 + + .../src/mod_psu_optee_regulator.c | 190 +++++ + .../module/stm32_regu_consumer/CMakeLists.txt | 17 + + .../module/stm32_regu_consumer/Module.cmake | 9 + + .../include/mod_stm32_regu_consumer.h | 37 + + .../src/mod_stm32_regu_consumer.c | 345 ++++++++ + 49 files changed, 3540 insertions(+), 1599 deletions(-) + create mode 100644 product/optee-stm32mp1/fw/config_all.c + delete mode 100644 product/optee-stm32mp1/fw/config_mbx_smt.c + delete mode 100644 product/optee-stm32mp1/fw/config_scmi.c + delete mode 100644 product/optee-stm32mp1/fw/config_scmi_clocks.c + delete mode 100644 product/optee-stm32mp1/fw/config_scmi_reset_domains.c + delete mode 100644 product/optee-stm32mp1/fw/config_scmi_voltage_domains.c + rename product/optee-stm32mp1/module/{stm32_pwr_regu => psu_optee_regulator}/CMakeLists.txt (80%) + create mode 100644 product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake + create mode 100644 product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h + create mode 100644 product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c + delete mode 100644 product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake + delete mode 100644 product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h + delete mode 100644 product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c + delete mode 100644 product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake + delete mode 100644 product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h + delete mode 100644 product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c + rename product/optee-stm32mp1/module/{stm32_pmic_regu => stm32_regu_consumer}/CMakeLists.txt (64%) + create mode 100644 product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake + create mode 100644 product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h + create mode 100644 product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c + create mode 100644 product/optee-stm32mp2/fw/CMakeLists.txt + create mode 100644 product/optee-stm32mp2/fw/Firmware.cmake + create mode 100644 product/optee-stm32mp2/fw/Toolchain-GNU.cmake + create mode 100644 product/optee-stm32mp2/fw/config_all.c + create mode 100644 product/optee-stm32mp2/include/fmw_io.h + create mode 100644 product/optee-stm32mp2/include/fmw_log.h + create mode 100644 product/optee-stm32mp2/include/gnu/stubs-soft.h + create mode 100644 product/optee-stm32mp2/include/scmi_agents.h + create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt + create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake + create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h + create mode 100644 product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c + create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt + create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake + create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h + create mode 100644 product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c + +diff --git a/framework/include/fwk_dlist.h b/framework/include/fwk_dlist.h +index fc560b4e..ffe2dc56 100644 +--- a/framework/include/fwk_dlist.h ++++ b/framework/include/fwk_dlist.h +@@ -1,6 +1,6 @@ + /* + * Arm SCP/MCP Software +- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * +@@ -92,7 +92,7 @@ struct fwk_dlist_node *__fwk_dlist_pop_head(struct fwk_dlist *list) FWK_LEAF + * See fwk_list_remove(list, node) for the public interface. + */ + void __fwk_dlist_remove(struct fwk_dlist *list, struct fwk_dlist_node *node) +- FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_UNTOUCHED(1) ++ FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_ONLY1(1) + FWK_READ_WRITE1(2); + + /* +diff --git a/framework/include/fwk_slist.h b/framework/include/fwk_slist.h +index df690999..42830d20 100644 +--- a/framework/include/fwk_slist.h ++++ b/framework/include/fwk_slist.h +@@ -1,6 +1,6 @@ + /* + * Arm SCP/MCP Software +- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * +@@ -116,7 +116,7 @@ struct fwk_slist_node *__fwk_slist_pop_head(struct fwk_slist *list) FWK_LEAF + struct fwk_slist_node *__fwk_slist_next( + const struct fwk_slist *list, + const struct fwk_slist_node *node) FWK_PURE FWK_LEAF FWK_NOTHROW +- FWK_NONNULL(1) FWK_NONNULL(2) FWK_UNTOUCHED(1) FWK_READ_ONLY1(2); ++ FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_ONLY1(1) FWK_READ_ONLY1(2); + + /* + * Remove a node from a singly-linked list. +diff --git a/framework/src/fwk_dlist.c b/framework/src/fwk_dlist.c +index 6fcfd08b..e8c1ba62 100644 +--- a/framework/src/fwk_dlist.c ++++ b/framework/src/fwk_dlist.c +@@ -1,6 +1,6 @@ + /* + * Arm SCP/MCP Software +- * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * +@@ -73,7 +73,7 @@ void __fwk_dlist_remove( + fwk_assert(node->prev != NULL); + fwk_assert(node->next != NULL); + +- assert(__fwk_slist_contains( ++ fwk_assert(__fwk_slist_contains( + (struct fwk_slist *)list, + (struct fwk_slist_node *)node)); + +@@ -104,7 +104,7 @@ void __fwk_dlist_insert( + fwk_assert(node->prev != NULL); + fwk_assert(node->next != NULL); + +- assert(__fwk_slist_contains( ++ fwk_assert(__fwk_slist_contains( + (struct fwk_slist *)list, + (struct fwk_slist_node *)node)); + +diff --git a/module/clock/include/mod_clock.h b/module/clock/include/mod_clock.h +index 4d6f6ead..38bf0400 100644 +--- a/module/clock/include/mod_clock.h ++++ b/module/clock/include/mod_clock.h +@@ -175,10 +175,10 @@ struct mod_clock_config { + */ + struct mod_clock_dev_config { + /*! Reference to the device element within the associated driver module */ +- const fwk_id_t driver_id; ++ fwk_id_t driver_id; + + /*! Reference to the API provided by the device driver module */ +- const fwk_id_t api_id; ++ fwk_id_t api_id; + + /*! + * \brief Reference to the element or module that is the source of the +@@ -424,6 +424,34 @@ struct mod_clock_drv_api { + fwk_id_t clock_id, + uint64_t in_rate, + uint64_t *out_rate); ++ ++ /*! ++ * \brief Get the clock duty cycle. ++ * ++ * \param clock_id Clock device identifier. ++ * ++ * \param[out] num Numerator of the clock duty cycle. ++ * ++ * \param[out] den Denominator of the clock duty cycle. ++ * ++ * \retval ::FWK_SUCCESS The operation succeeded. ++ * \return One of the standard framework error codes. ++ */ ++ int (*get_duty_cycle)(fwk_id_t clock_id, uint32_t *num, uint32_t *den); ++ ++ /*! ++ * \brief Get the rounded rate the clock supports for requested input @rate ++ * ++ * \param clock_id Clock device identifier. ++ * ++ * \param[int] rate Requested rate in Hertz. ++ * ++ * \param[out] rounded_rate Output rounded rate supported. ++ * ++ * \retval ::FWK_SUCCESS The operation succeeded. ++ * \return One of the standard framework error codes. ++ */ ++ int (*round_rate)(fwk_id_t clock_id, uint64_t rate, uint64_t *rounded_rate); + }; + + /*! +@@ -538,6 +566,34 @@ struct mod_clock_api { + * \return One of the standard framework error codes. + */ + int (*get_info)(fwk_id_t clock_id, struct mod_clock_info *info); ++ ++ /*! ++ * \brief Get the clock duty cycle. ++ * ++ * \param clock_id Clock device identifier. ++ * ++ * \param[out] num Numerator of the clock duty cycle. ++ * ++ * \param[out] den Denominator of the clock duty cycle. ++ * ++ * \retval ::FWK_SUCCESS The operation succeeded. ++ * \return One of the standard framework error codes. ++ */ ++ int (*get_duty_cycle)(fwk_id_t clock_id, uint32_t *num, uint32_t *den); ++ ++ /*! ++ * \brief Get the rounded rate the clock supports for requested input @rate ++ * ++ * \param clock_id Clock device identifier. ++ * ++ * \param[int] rate Requested rate in Hertz. ++ * ++ * \param[out] rounded_rate Output rounded rate supported. ++ * ++ * \retval ::FWK_SUCCESS The operation succeeded. ++ * \return One of the standard framework error codes. ++ */ ++ int (*round_rate)(fwk_id_t clock_id, uint64_t rate, uint64_t *rounded_rate); + }; + + /*! +diff --git a/module/clock/src/mod_clock.c b/module/clock/src/mod_clock.c +index 15a1b331..f4b27b24 100644 +--- a/module/clock/src/mod_clock.c ++++ b/module/clock/src/mod_clock.c +@@ -345,6 +345,37 @@ static int clock_get_info(fwk_id_t clock_id, struct mod_clock_info *info) + return FWK_SUCCESS; + } + ++static int clock_get_duty_cycle(fwk_id_t clock_id, uint32_t *num, uint32_t *den) ++{ ++ struct clock_dev_ctx *ctx; ++ ++ clock_get_ctx(clock_id, &ctx); ++ ++ if (!ctx->api->get_duty_cycle) { ++ return FWK_E_SUPPORT; ++ } ++ ++ return ctx->api->get_duty_cycle(ctx->config->driver_id, num, den); ++} ++ ++static int clock_round_rate(fwk_id_t clock_id, uint64_t rate, ++ uint64_t *rounded_rate) ++{ ++ struct clock_dev_ctx *ctx; ++ ++ clock_get_ctx(clock_id, &ctx); ++ ++ if (rounded_rate == NULL) { ++ return FWK_E_PARAM; ++ } ++ ++ if (!ctx->api->round_rate) { ++ return FWK_E_SUPPORT; ++ } ++ ++ return ctx->api->round_rate(ctx->config->driver_id, rate, rounded_rate); ++} ++ + static const struct mod_clock_api clock_api = { + .set_rate = clock_set_rate, + .get_rate = clock_get_rate, +@@ -352,6 +383,8 @@ static const struct mod_clock_api clock_api = { + .set_state = clock_set_state, + .get_state = clock_get_state, + .get_info = clock_get_info, ++ .get_duty_cycle = clock_get_duty_cycle, ++ .round_rate = clock_round_rate, + }; + + /* +diff --git a/module/optee/clock/src/mod_optee_clock.c b/module/optee/clock/src/mod_optee_clock.c +index 0ccaade7..36d9fa9d 100644 +--- a/module/optee/clock/src/mod_optee_clock.c ++++ b/module/optee/clock/src/mod_optee_clock.c +@@ -179,9 +179,8 @@ static int get_range(fwk_id_t dev_id, struct mod_clock_range *range) + return FWK_E_PARAM; + } + +- range->rate_type = MOD_CLOCK_RATE_TYPE_DISCRETE; +- + if (!is_exposed(ctx)) { ++ range->rate_type = MOD_CLOCK_RATE_TYPE_DISCRETE; + range->min = 0; + range->max = 0; + range->rate_count = 1; +@@ -191,9 +190,23 @@ static int get_range(fwk_id_t dev_id, struct mod_clock_range *range) + + res = clk_get_rates_array(ctx->clk, 0, NULL, &rate_count); + if (res == TEE_ERROR_NOT_SUPPORTED) { +- range->min = clk_get_rate(ctx->clk); +- range->max = range->min; +- range->rate_count = 1; ++ unsigned long max = 0; ++ unsigned long min = 0; ++ unsigned long step = 0; ++ ++ res = clk_get_rates_steps(ctx->clk, &min, &max, &step); ++ ++ if (res == TEE_ERROR_NOT_SUPPORTED) { ++ range->rate_type = MOD_CLOCK_RATE_TYPE_DISCRETE; ++ range->min = clk_get_rate(ctx->clk); ++ range->max = range->min; ++ range->rate_count = 1; ++ } ++ ++ range->rate_type = MOD_CLOCK_RATE_TYPE_CONTINUOUS; ++ range->min = min; ++ range->max = max; ++ range->step = step; + + return FWK_SUCCESS; + } +@@ -293,6 +306,62 @@ static int get_rate_from_index(fwk_id_t dev_id, + return FWK_SUCCESS; + } + ++static int get_duty_cycle(fwk_id_t dev_id, uint32_t *num, uint32_t *den) ++{ ++ struct optee_clock_dev_ctx *ctx = elt_id_to_ctx(dev_id); ++ struct clk_duty duty = { 0 }; ++ TEE_Result res; ++ ++ if (ctx == NULL) { ++ return FWK_E_PARAM; ++ } ++ ++ if (!is_exposed(ctx)) { ++ /* Return a dummy value to prevent an error trace */ ++ *num = 1; ++ *den = 2; ++ return FWK_SUCCESS; ++ } ++ ++ res = clk_get_duty_cycle(ctx->clk, &duty); ++ ++ FWK_LOG_DEBUG( ++ MOD_NAME "SCMI optee_clock (%u/\"%s\"): %" PRIx32, ++ fwk_id_get_element_idx(dev_id), ++ clk_get_name(ctx->clk), ++ res); ++ ++ if (res == TEE_ERROR_NOT_SUPPORTED) { ++ /* Assume a 50% duty cycle */ ++ duty = (struct clk_duty){ .num = 1, .den = 2 }; ++ } else if (res != TEE_SUCCESS) { ++ return FWK_E_DEVICE; ++ } ++ ++ *num = duty.num; ++ *den = duty.den; ++ ++ return FWK_SUCCESS; ++} ++ ++static int get_rounded_rate(fwk_id_t dev_id, uint64_t rate, ++ uint64_t *rounded_rate) ++{ ++ struct optee_clock_dev_ctx *ctx = elt_id_to_ctx(dev_id); ++ ++ if (ctx == NULL) { ++ return FWK_E_PARAM; ++ } ++ ++ if (!is_exposed(ctx)) { ++ return FWK_E_SUPPORT; ++ } ++ ++ *rounded_rate = (uint64_t)clk_round_rate(ctx->clk, (unsigned long)rate); ++ ++ return FWK_SUCCESS; ++} ++ + static int stub_process_power_transition(fwk_id_t dev_id, unsigned int state) + { + return FWK_E_SUPPORT; +@@ -312,6 +381,8 @@ static const struct mod_clock_drv_api api_optee_clock = { + .get_range = get_range, + .get_rate_from_index = get_rate_from_index, + .set_rate = set_rate, ++ .get_duty_cycle = get_duty_cycle, ++ .round_rate = get_rounded_rate, + /* Not supported */ + .process_power_transition = stub_process_power_transition, + .process_pending_power_transition = stub_pending_power_transition, +diff --git a/module/resource_perms/include/mod_resource_perms.h b/module/resource_perms/include/mod_resource_perms.h +index 99d2f3d0..78da6799 100644 +--- a/module/resource_perms/include/mod_resource_perms.h ++++ b/module/resource_perms/include/mod_resource_perms.h +@@ -187,6 +187,12 @@ enum mod_res_clock_permissions_idx { + MOD_SCMI_CLOCK_RATE_GET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, + MOD_RES_PERMS_SCMI_CLOCK_CONFIG_SET_IDX = + MOD_SCMI_CLOCK_CONFIG_SET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, ++ MOD_RES_PERMS_SCMI_CLOCK_NAME_GET_IDX = ++ MOD_SCMI_CLOCK_NAME_GET - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, ++ MOD_RES_PERMS_SCMI_CLOCK_RATE_NOTIFY_IDX = ++ MOD_SCMI_CLOCK_RATE_NOTIFY - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, ++ MOD_RES_PERMS_SCMI_CLOCK_CHANGE_REQUESTED_NOTIFY_IDX = ++ MOD_SCMI_CLOCK_CHANGE_REQUESTED_NOTIFY - MOD_RES_PERMS_CLOCK_PERMS_OFFSET, + }; + + /*! +diff --git a/module/scmi/include/mod_scmi_std.h b/module/scmi/include/mod_scmi_std.h +index d212c687..1724406b 100644 +--- a/module/scmi/include/mod_scmi_std.h ++++ b/module/scmi/include/mod_scmi_std.h +@@ -161,7 +161,12 @@ enum scmi_clock_command_id { + MOD_SCMI_CLOCK_RATE_SET = 0x005, + MOD_SCMI_CLOCK_RATE_GET = 0x006, + MOD_SCMI_CLOCK_CONFIG_SET = 0x007, +- MOD_SCMI_CLOCK_COMMAND_COUNT, ++ MOD_SCMI_CLOCK_NAME_GET = 0x008, ++ MOD_SCMI_CLOCK_RATE_NOTIFY = 0x009, ++ MOD_SCMI_CLOCK_RATE_CHANGE_REQUESTED_NOTIFY = 0x00A, ++ MOD_SCMI_CLOCK_DUTY_CYCLE_GET = 0x00B, ++ MOD_SCMI_CLOCK_ROUND_RATE_GET = 0x00C, ++ MOD_SCMI_CLOCK_COMMAND_COUNT + }; + + /*! +diff --git a/module/scmi_clock/include/internal/scmi_clock.h b/module/scmi_clock/include/internal/scmi_clock.h +index f3b51e5b..7671e0e8 100644 +--- a/module/scmi_clock/include/internal/scmi_clock.h ++++ b/module/scmi_clock/include/internal/scmi_clock.h +@@ -244,4 +244,75 @@ struct scmi_clock_describe_rates_p2a { + struct scmi_clock_rate rates[]; + }; + ++/* ++ * Clock get name (extended 64byte name) ++ */ ++ ++struct scmi_clock_name_get_a2p { ++ uint32_t clock_id; ++}; ++ ++#define SCMI_CLOCK_EXTTENDED_NAME_LENGTH_MAX 64 ++ ++struct scmi_clock_name_get_p2a { ++ int32_t status; ++ uint32_t flags; ++ char clock_name[SCMI_CLOCK_EXTTENDED_NAME_LENGTH_MAX]; ++}; ++ ++/* ++ * Clock notify on clock rate change ++ */ ++ ++struct scmi_clock_rate_notify_a2p { ++ uint32_t clock_id; ++ uint32_t notify_enable; ++}; ++ ++struct scmi_clock_rate_notify_p2a { ++ int32_t status; ++}; ++ ++/* ++ * Clock notify on clock rate change requests ++ */ ++ ++struct scmi_clock_rate_change_request_notify_a2p { ++ uint32_t clock_id; ++ uint32_t notify_enable; ++}; ++ ++struct scmi_clock_rate_change_request_notify_p2a { ++ int32_t status; ++}; ++ ++/* ++ * Clock get duty cycle ++ */ ++ ++struct scmi_clock_duty_cycle_get_a2p { ++ uint32_t clock_id; ++}; ++ ++struct scmi_clock_duty_cycle_get_p2a { ++ int32_t status; ++ uint32_t numerator; ++ uint32_t denominator; ++}; ++ ++/* ++ * Clock get round rate ++ */ ++ ++struct scmi_clock_round_rate_get_a2p { ++ uint32_t flags; ++ uint32_t clock_id; ++ uint32_t rate[2]; ++}; ++ ++struct scmi_clock_round_rate_get_p2a { ++ int32_t status; ++ uint32_t rate[2]; ++}; ++ + #endif /* INTERNAL_SCMI_CLOCK_H */ +diff --git a/module/scmi_clock/src/mod_scmi_clock.c b/module/scmi_clock/src/mod_scmi_clock.c +index 59a1fb14..5999e03f 100644 +--- a/module/scmi_clock/src/mod_scmi_clock.c ++++ b/module/scmi_clock/src/mod_scmi_clock.c +@@ -128,6 +128,16 @@ static int scmi_clock_config_set_handler(fwk_id_t service_id, + const uint32_t *payload); + static int scmi_clock_describe_rates_handler(fwk_id_t service_id, + const uint32_t *payload); ++static int scmi_clock_name_get_handler(fwk_id_t service_id, ++ const uint32_t *payload); ++static int scmi_clock_rate_notify_handler(fwk_id_t service_id, ++ const uint32_t *payload); ++static int scmi_clock_rate_change_request_notify_handler(fwk_id_t service_id, ++ const uint32_t *payload); ++static int scmi_clock_duty_cycle_get_handler(fwk_id_t service_id, ++ const uint32_t *payload); ++static int scmi_clock_round_rate_get_handler(fwk_id_t service_id, ++ const uint32_t *payload); + + /* + * Internal variables. +@@ -146,6 +156,11 @@ static int (*const handler_table[MOD_SCMI_CLOCK_COMMAND_COUNT])( + [MOD_SCMI_CLOCK_RATE_SET] = scmi_clock_rate_set_handler, + [MOD_SCMI_CLOCK_CONFIG_SET] = scmi_clock_config_set_handler, + [MOD_SCMI_CLOCK_DESCRIBE_RATES] = scmi_clock_describe_rates_handler, ++ [MOD_SCMI_CLOCK_NAME_GET] = scmi_clock_name_get_handler, ++ [MOD_SCMI_CLOCK_RATE_NOTIFY] = scmi_clock_rate_notify_handler, ++ [MOD_SCMI_CLOCK_RATE_CHANGE_REQUESTED_NOTIFY] = scmi_clock_rate_change_request_notify_handler, ++ [MOD_SCMI_CLOCK_DUTY_CYCLE_GET] = scmi_clock_duty_cycle_get_handler, ++ [MOD_SCMI_CLOCK_ROUND_RATE_GET] = scmi_clock_round_rate_get_handler, + }; + + static const unsigned int payload_size_table[MOD_SCMI_CLOCK_COMMAND_COUNT] = { +@@ -163,6 +178,16 @@ static const unsigned int payload_size_table[MOD_SCMI_CLOCK_COMMAND_COUNT] = { + (unsigned int)sizeof(struct scmi_clock_config_set_a2p), + [MOD_SCMI_CLOCK_DESCRIBE_RATES] = + (unsigned int)sizeof(struct scmi_clock_describe_rates_a2p), ++ [MOD_SCMI_CLOCK_NAME_GET] = ++ (unsigned int)sizeof(struct scmi_clock_describe_rates_a2p), ++ [MOD_SCMI_CLOCK_RATE_NOTIFY] = ++ (unsigned int)sizeof(struct scmi_clock_rate_notify_a2p), ++ [MOD_SCMI_CLOCK_RATE_CHANGE_REQUESTED_NOTIFY] = ++ (unsigned int)sizeof(struct scmi_clock_rate_change_request_notify_a2p), ++ [MOD_SCMI_CLOCK_DUTY_CYCLE_GET] = ++ (unsigned int)sizeof(struct scmi_clock_duty_cycle_get_a2p), ++ [MOD_SCMI_CLOCK_ROUND_RATE_GET] = ++ (unsigned int)sizeof(struct scmi_clock_round_rate_get_a2p), + }; + + /* +@@ -1368,6 +1393,226 @@ exit: + return status; + } + ++static int scmi_clock_name_get_handler(fwk_id_t service_id, ++ const uint32_t *payload) ++{ ++ int status, respond_status; ++ const struct mod_scmi_clock_device *clock_device; ++ size_t response_size; ++ const struct scmi_clock_name_get_a2p *parameters; ++ struct scmi_clock_name_get_p2a return_values = { ++ .status = (int32_t)SCMI_GENERIC_ERROR ++ }; ++ ++ parameters = (const struct scmi_clock_name_get_a2p*)payload; ++ ++ status = scmi_clock_get_clock_device_entry( ++ service_id, parameters->clock_id, &clock_device); ++ if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_NOT_FOUND; ++ goto exit; ++ } ++ ++#ifdef BUILD_HAS_MOD_RESOURCE_PERMS ++ status = scmi_clock_permissions_handler( ++ parameters->clock_id, ++ service_id, ++ (unsigned int)MOD_SCMI_CLOCK_NAME_GET); ++ if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_DENIED; ++ goto exit; ++ } ++#endif ++ ++ fwk_str_strncpy( ++ return_values.clock_name, ++ fwk_module_get_element_name(clock_device->element_id), ++ sizeof(return_values.clock_name) - 1); ++ ++ return_values.status = (int32_t)SCMI_SUCCESS; ++ response_size = sizeof(return_values); ++ return FWK_SUCCESS; ++ ++exit: ++ response_size = sizeof(return_values.status); ++ respond_status = scmi_clock_ctx.scmi_api->respond( ++ service_id, &return_values, response_size); ++ if (respond_status != FWK_SUCCESS) { ++ FWK_LOG_DEBUG("[SCMI-CLK] %s @%d", __func__, __LINE__); ++ } ++ ++ return status; ++} ++ ++static int scmi_clock_rate_notify_handler(fwk_id_t service_id, ++ const uint32_t *payload) ++{ ++ struct scmi_clock_rate_notify_p2a return_values = { ++ .status = (int32_t)SCMI_NOT_SUPPORTED, ++ }; ++ int respond_status; ++ ++ respond_status = scmi_clock_ctx.scmi_api->respond( ++ service_id, ++ &return_values, ++ sizeof(return_values.status)); ++ ++ if (respond_status != FWK_SUCCESS) { ++ FWK_LOG_DEBUG("[SCMI-CLK] %s @%d", __func__, __LINE__); ++ } ++ ++ return FWK_SUCCESS; ++} ++ ++static int scmi_clock_rate_change_request_notify_handler(fwk_id_t service_id, ++ const uint32_t *payload) ++{ ++ struct scmi_clock_rate_change_request_notify_p2a return_values = { ++ .status = (int32_t)SCMI_NOT_SUPPORTED, ++ }; ++ int respond_status; ++ ++ respond_status = scmi_clock_ctx.scmi_api->respond( ++ service_id, ++ &return_values, ++ sizeof(return_values.status)); ++ ++ if (respond_status != FWK_SUCCESS) { ++ FWK_LOG_DEBUG("[SCMI-CLK] %s @%d", __func__, __LINE__); ++ } ++ ++ return FWK_SUCCESS; ++} ++ ++static int scmi_clock_duty_cycle_get_handler(fwk_id_t service_id, ++ const uint32_t *payload) ++ ++{ ++ const struct scmi_clock_duty_cycle_get_a2p *parameters; ++ struct scmi_clock_duty_cycle_get_p2a return_values = { ++ .status = (int32_t)SCMI_SUCCESS ++ }; ++ const struct mod_scmi_clock_device *clock_device; ++ unsigned int agent_id; ++ size_t response_size; ++ int status; ++ ++ parameters = (const struct scmi_clock_duty_cycle_get_a2p*)payload; ++ ++ status = scmi_clock_get_clock_device_entry( ++ service_id, parameters->clock_id, &clock_device); ++ if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_NOT_FOUND; ++ goto exit; ++ } ++ ++#ifdef BUILD_HAS_MOD_RESOURCE_PERMS ++ /* Test SET_RATE permission until we have a DUTY_CYCLE permission flag */ ++ status = scmi_clock_permissions_handler( ++ parameters->clock_id, ++ service_id, ++ (unsigned int)MOD_SCMI_CLOCK_RATE_SET); ++ if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_DENIED; ++ goto exit; ++ } ++#endif ++ ++ status = scmi_clock_ctx.scmi_api->get_agent_id(service_id, &agent_id); ++ if (status != FWK_SUCCESS) { ++ goto exit; ++ } ++ ++ status = scmi_clock_ctx.clock_api->get_duty_cycle(clock_device->element_id, ++ &return_values.numerator, ++ &return_values.denominator); ++ ++ if (status == FWK_E_SUPPORT) { ++ return_values.status = (int32_t)SCMI_NOT_SUPPORTED; ++ } else if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_GENERIC_ERROR; ++ } ++ ++exit: ++ response_size = (return_values.status == SCMI_SUCCESS) ? ++ sizeof(return_values) : sizeof(return_values.status); ++ return scmi_clock_ctx.scmi_api->respond( ++ service_id, &return_values, response_size); ++} ++ ++/* ++ * Use clock set rate with round nearest flag support to ++ * get rounded value. ++ */ ++static int scmi_clock_round_rate_get_handler(fwk_id_t service_id, ++ const uint32_t *payload) ++{ ++ const struct scmi_clock_round_rate_get_a2p *parameters; ++ struct scmi_clock_round_rate_get_p2a return_values = { ++ .status = (int32_t)SCMI_SUCCESS, ++ }; ++ const struct mod_scmi_clock_device *clock_device; ++ unsigned long input_rate; ++ uint64_t output_rate; ++ size_t response_size; ++ int status; ++ ++ parameters = (const struct scmi_clock_round_rate_get_a2p*)payload; ++ ++ status = scmi_clock_get_clock_device_entry( ++ service_id, ++ parameters->clock_id, ++ &clock_device); ++ ++ if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_NOT_FOUND; ++ goto exit; ++ } ++ ++#ifdef BUILD_HAS_MOD_RESOURCE_PERMS ++ status = scmi_clock_permissions_handler( ++ parameters->clock_id, ++ service_id, ++ (unsigned int)MOD_SCMI_CLOCK_RATE_SET); ++ if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_DENIED; ++ goto exit; ++ } ++#endif ++ ++ if ((parameters->flags & SCMI_CLOCK_RATE_SET_ASYNC_MASK) != 0) { ++ /* Support for async clock set commands not yet implemented */ ++ return_values.status = (int32_t)SCMI_NOT_SUPPORTED; ++ goto exit; ++ } ++ ++ input_rate = parameters->rate[0]; ++ if (parameters->rate[1]) { ++ return_values.status = (int32_t)SCMI_INVALID_PARAMETERS; ++ goto exit; ++ } ++ ++ status = scmi_clock_ctx.clock_api->round_rate(clock_device->element_id, ++ input_rate, &output_rate); ++ if (status == FWK_E_SUPPORT) { ++ return_values.status = (int32_t)SCMI_NOT_SUPPORTED; ++ } else if (status != FWK_SUCCESS) { ++ return_values.status = (int32_t)SCMI_GENERIC_ERROR; ++ } else { ++ return_values.rate[0] = (uint32_t)output_rate; ++ return_values.rate[1] = 0; ++ return_values.status = (int32_t)SCMI_SUCCESS; ++ } ++ ++exit: ++ ++ ++ response_size = (return_values.status == SCMI_SUCCESS) ? ++ sizeof(return_values) : sizeof(return_values.status); ++ return scmi_clock_ctx.scmi_api->respond( ++ service_id, &return_values, response_size); ++} ++ + /* + * SCMI module -> SCMI clock module interface + */ +diff --git a/module/voltage_domain/include/mod_voltage_domain.h b/module/voltage_domain/include/mod_voltage_domain.h +index 85b09606..cd0c21f1 100644 +--- a/module/voltage_domain/include/mod_voltage_domain.h ++++ b/module/voltage_domain/include/mod_voltage_domain.h +@@ -78,10 +78,10 @@ enum mod_voltd_voltage_level_type { + */ + struct mod_voltd_dev_config { + /*! Reference to the device element within the associated driver module */ +- const fwk_id_t driver_id; ++ fwk_id_t driver_id; + + /*! Reference to the API provided by the device driver module */ +- const fwk_id_t api_id; ++ fwk_id_t api_id; + }; + + /*! +diff --git a/product/optee-stm32mp1/fw/CMakeLists.txt b/product/optee-stm32mp1/fw/CMakeLists.txt +index c3a47b21..8674a1eb 100644 +--- a/product/optee-stm32mp1/fw/CMakeLists.txt ++++ b/product/optee-stm32mp1/fw/CMakeLists.txt +@@ -20,8 +20,5 @@ target_include_directories( + + target_sources( + ${SCP_FIRMWARE_TARGET} +- PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_mbx_smt.c" +- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi.c" +- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_clocks.c" +- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_reset_domains.c" +- "${CMAKE_CURRENT_SOURCE_DIR}/config_scmi_voltage_domains.c") ++ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_all.c" ++) +diff --git a/product/optee-stm32mp1/fw/Firmware.cmake b/product/optee-stm32mp1/fw/Firmware.cmake +index b0d55b83..0b84f335 100644 +--- a/product/optee-stm32mp1/fw/Firmware.cmake ++++ b/product/optee-stm32mp1/fw/Firmware.cmake +@@ -31,15 +31,15 @@ set(SCP_ENABLE_SCMI_RESET_INIT TRUE) + + set(SCP_ENABLE_IPO_INIT FALSE) + +-list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_pmic_regu") +-list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_pwr_regu") ++list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_regu_consumer") ++list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/psu_optee_regulator") + + # The order of the modules in the following list is the order in which the + # modules are initialized, bound, started during the pre-runtime phase. + # any change in the order will cause firmware initialization errors. + + list(APPEND SCP_MODULES "optee-mbx") +-list(APPEND SCP_MODULES "optee-smt") ++list(APPEND SCP_MODULES "msg-smt") + list(APPEND SCP_MODULES "scmi") + list(APPEND SCP_MODULES "optee-clock") + list(APPEND SCP_MODULES "clock") +@@ -47,8 +47,13 @@ list(APPEND SCP_MODULES "scmi-clock") + list(APPEND SCP_MODULES "optee-reset") + list(APPEND SCP_MODULES "reset-domain") + list(APPEND SCP_MODULES "scmi-reset-domain") +-list(APPEND SCP_MODULES "stm32-pmic-regu") +-list(APPEND SCP_MODULES "stm32-pwr-regu") ++list(APPEND SCP_MODULES "stm32-regu-consumer") + list(APPEND SCP_MODULES "voltage-domain") + list(APPEND SCP_MODULES "scmi-voltage-domain") ++if (CFG_STM32MP13) ++ list(APPEND SCP_MODULES "psu-optee-regulator") ++ list(APPEND SCP_MODULES "psu") ++ list(APPEND SCP_MODULES "dvfs") ++ list(APPEND SCP_MODULES "scmi-perf") ++endif (CFG_STM32MP13) + list(APPEND SCP_MODULES "optee-console") +diff --git a/product/optee-stm32mp1/fw/config_all.c b/product/optee-stm32mp1/fw/config_all.c +new file mode 100644 +index 00000000..afff9283 +--- /dev/null ++++ b/product/optee-stm32mp1/fw/config_all.c +@@ -0,0 +1,797 @@ ++/* ++ * Arm SCP/MCP Software ++ * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#ifdef CFG_SCPFW_MOD_DVFS ++#include ++#endif ++#include ++#include ++#include ++#include ++#ifdef CFG_SCPFW_MOD_PSU ++#include ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* SCMI agent and services (channels) */ ++static struct mod_scmi_agent *scmi_agent_table; ++static struct mod_scmi_config scmi_data; ++static struct fwk_element *scmi_service_elt; ++ ++/* SCMI channel mailbox/shmem */ ++static struct fwk_element *msg_smt_elt; ++static struct mod_msg_smt_channel_config *msg_smt_data; ++static struct fwk_element *optee_mbx_elt; ++static struct mod_optee_mbx_channel_config *optee_mbx_data; ++ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++/* SCMI clock generic */ ++static struct mod_scmi_clock_agent *scmi_clk_agent_tbl; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_CLOCK ++/* Clocks and optee/clock, same number/indices. Elements and configuration data */ ++static struct fwk_element *optee_clock_elt; /* Optee/clock elements */ ++static struct mod_optee_clock_config *optee_clock_cfg; /* Config data for optee/clock elements */ ++static struct fwk_element *clock_elt; /* Clock elements */ ++static struct mod_clock_dev_config *clock_data; /* Config data for clock elements */ ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++/* 1 DVFS (elt & data) per DVFS exposed */ ++static struct mod_dvfs_domain_config *dvfs_data; ++static struct fwk_element *dvfs_elt; ++/* A unique scmi_perf instance refers to perf domains data (DVFS instance) */ ++static struct mod_scmi_perf_domain_config *scmi_perf_domain_data; ++struct fwk_module_config config_scmi_perf; ++ ++/* PSU and optee/psu-regu, used with DVFS. Elements and configuration data */ ++static struct fwk_element *psu_optee_regu_elt; ++static struct mod_psu_optee_regulator_dev_config *psu_optee_regu_data; ++static struct fwk_element *psu_elt; ++static struct mod_psu_element_cfg *psu_data; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++/* SCMI reset domains and optee reset controller */ ++static struct mod_scmi_reset_domain_agent *scmi_reset_agent_tbl; ++static struct fwk_element *optee_reset_elt; ++static struct mod_optee_reset_dev_config *optee_reset_data; ++static struct fwk_element *reset_elt; ++static struct mod_reset_domain_dev_config *reset_data; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++/* SCMI voltage domains and optee regulators */ ++static struct mod_scmi_voltd_agent *scmi_voltd_agent_tbl; ++static struct fwk_element *optee_regu_elt; ++static struct mod_stm32_regu_consumer_dev_config *optee_regu_data; ++static struct fwk_element *voltd_elt; ++static struct mod_voltd_dev_config *voltd_data; ++#endif ++ ++/* Config data for scmi module */ ++static const struct fwk_element *get_scmi_service_table(fwk_id_t module_id) ++{ ++ return scmi_service_elt; /* scmi_service_elt filled during initialization */ ++} ++ ++struct fwk_module_config config_scmi = { ++ .data = (void *)&scmi_data, /* scmi_data filled during initialization */ ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_scmi_service_table), ++}; ++ ++/* Config data for optee_mbx module */ ++static const struct fwk_element *optee_mbx_get_element_table(fwk_id_t module_id) ++{ ++ return (const struct fwk_element *)optee_mbx_elt; ++} ++ ++struct fwk_module_config config_optee_mbx = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_mbx_get_element_table), ++}; ++ ++/* Config data for msg_smt module */ ++static const struct fwk_element *msg_smt_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_MSG_SMT); ++ return (const struct fwk_element *)msg_smt_elt; ++} ++ ++struct fwk_module_config config_msg_smt = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(msg_smt_get_element_table), ++}; ++ ++/* Config data for scmi_clock, clock and optee_clock modules */ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++struct fwk_module_config config_scmi_clock = { ++ .data = &((struct mod_scmi_clock_config){ ++ .agent_table = NULL, /* Allocated during initialization */ ++ .agent_count = 0, /* Set during initialization */ ++ }), ++}; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_CLOCK ++static const struct fwk_element *clock_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_CLOCK); ++ return (const struct fwk_element *)clock_elt; ++} ++ ++struct fwk_module_config config_clock = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(clock_get_element_table), ++}; ++ ++static const struct fwk_element *optee_clock_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_CLOCK); ++ return (const struct fwk_element *)optee_clock_elt; ++} ++ ++struct fwk_module_config config_optee_clock = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_element_table), ++}; ++#endif ++ ++/* Config data for scmi_reset_domain, reset_domain and optee_reset modules */ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++struct fwk_module_config config_scmi_reset_domain = { ++ .data = &((struct mod_scmi_reset_domain_config){ ++ .agent_table = NULL, /* Allocated during initialization */ ++ .agent_count = 0, /* Set during initialization */ ++ }), ++}; ++ ++static const struct fwk_element *reset_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_RESET_DOMAIN); ++ return (const struct fwk_element *)reset_elt; ++} ++ ++struct fwk_module_config config_reset_domain = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(reset_get_element_table), ++}; ++ ++static const struct fwk_element *optee_reset_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_RESET); ++ return (const struct fwk_element *)optee_reset_elt; ++} ++ ++struct fwk_module_config config_optee_reset = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_reset_get_element_table), ++}; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++/* Config data for scmi_voltage_domain, voltage_domain and optee_regu modules */ ++struct fwk_module_config config_scmi_voltage_domain = { ++ .data = &((struct mod_scmi_voltd_config){ ++ .agent_table = NULL, /* Allocated during initialization */ ++ .agent_count = 0, /* Set during initialization */ ++ }), ++}; ++ ++static const struct fwk_element *voltd_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_VOLTAGE_DOMAIN); ++ return (const struct fwk_element *)voltd_elt; ++} ++ ++struct fwk_module_config config_voltage_domain = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(voltd_get_element_table), ++}; ++ ++static const struct fwk_element *stm32_regu_consumer_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_STM32_REGU_CONSUMER); ++ return (const struct fwk_element *)optee_regu_elt; ++} ++ ++struct fwk_module_config config_stm32_regu_consumer = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(stm32_regu_consumer_get_element_table), ++}; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++/* Config data for scmi_perf and dvfs module */ ++struct fwk_module_config config_scmi_perf = { ++ .data = &((struct mod_scmi_perf_config){ ++ .domains = NULL, /* Allocated during initialization */ ++ .perf_doms_count = 0, /* Set during initialization */ ++ .fast_channels_alarm_id = FWK_ID_NONE_INIT, ++#ifdef BUILD_HAS_MOD_STATISTICS ++ .stats_enabled = true, ++#endif ++ }), ++}; ++ ++static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_DVFS); ++ return (const struct fwk_element *)dvfs_elt; ++} ++ ++struct fwk_module_config config_dvfs = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dvfs_get_element_table), ++}; ++ ++/* Config data for psu and optee/psu module */ ++static const struct fwk_element *psu_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU); ++ return (const struct fwk_element *)psu_elt; ++} ++ ++struct fwk_module_config config_psu = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_get_element_table), ++}; ++ ++static const struct fwk_element *psu_optee_regu_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU_OPTEE_REGULATOR); ++ return (const struct fwk_element *)psu_optee_regu_elt ; ++} ++ ++struct fwk_module_config config_psu_optee_regulator = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_optee_regu_get_element_table), ++}; ++#endif ++ ++/* ++ * Indices state when applying agents configuration ++ * @channel_count: Number of channels (mailbox/shmem links) used ++ * @clock_index: Current index for clock and optee/clock (same indices) ++ * @clock_count: Number of clocks (also number of optee/clocks) ++ * @reset_index: Current index for reset controller and optee/reset ++ * @reset_count: Number of reset controller (optee/reset) instances ++ * @regu_index: Current index for voltd and optee/regulator ++ * @regu_count: Number of voltd (optee/regulator) instances ++ * @psu_index: Current index for PSU and optee/PSU instances ++ * @psu_count: Number of PSU (optee/PSU) instances ++ * @dvfs_index: Current index for DVFS instance ++ * @dvfs_count: Number of DVFS instances ++ */ ++struct scpfw_resource_counter { ++ size_t channel_count; ++ size_t clock_index; ++ size_t clock_count; ++ size_t reset_index; ++ size_t reset_count; ++ size_t regu_index; ++ size_t regu_count; ++ size_t psu_index; ++ size_t psu_count; ++ size_t dvfs_index; ++ size_t dvfs_count; ++} scpfw_resource_counter; ++ ++/* ++ * Count once for all the several instances and allocate global resources. ++ * Global resources are clock, optee/clock, reset, optee/reset, regu, ++ * optee/regu, psu, optee/psu, dvfs, perfd, ...; ++ */ ++static void count_resources(struct scpfw_config *cfg) ++{ ++ size_t i, j; ++ ++ for (i = 0; i < cfg->agent_count; i++) { ++ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; ++ ++ scpfw_resource_counter.channel_count += agent_cfg->channel_count; ++ ++ for (j = 0; j < agent_cfg->channel_count; j++) { ++ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; ++ ++ /* Clocks for scmi_clock and for DVFS */ ++ scpfw_resource_counter.clock_count += channel_cfg->clock_count; ++ scpfw_resource_counter.clock_count += channel_cfg->perfd_count; ++ /* Reset for smci_reset only */ ++ scpfw_resource_counter.reset_count += channel_cfg->reset_count; ++ /* Regulators for smci_voltage_domain only */ ++ scpfw_resource_counter.regu_count += channel_cfg->voltd_count; ++ /* DVFS and PSU DVFS only */ ++ scpfw_resource_counter.dvfs_count += channel_cfg->perfd_count; ++ scpfw_resource_counter.psu_count += channel_cfg->perfd_count; ++ } ++ } ++ ++#ifndef CFG_SCPFW_MOD_CLOCK ++ fwk_assert(!scpfw_resource_counter.clock_count); ++#endif ++#ifndef CFG_SCPFW_MOD_RESET_DOMAIN ++ fwk_assert(!scpfw_resource_counter.reset_count); ++#endif ++#ifndef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++ fwk_assert(!scpfw_resource_counter.regu_count); ++#endif ++#ifndef CFG_SCPFW_MOD_DVFS ++ fwk_assert(!scpfw_resource_counter.dvfs_count); ++#endif ++#ifndef CFG_SCPFW_MOD_PSU ++ fwk_assert(!scpfw_resource_counter.psu_count); ++#endif ++} ++ ++/* ++ * Allocate all tables that may be needed. An optimized implementation would ++ * allocate a single piece of memory and set the pointers accordingly. ++ * */ ++static void allocate_global_resources(struct scpfw_config *cfg) ++{ ++ struct mod_scmi_reset_domain_config *scmi_reset_config __maybe_unused; ++ struct mod_scmi_voltd_config *scmi_voltd_config __maybe_unused; ++ struct mod_scmi_clock_config *scmi_clock_config __maybe_unused; ++ /* @cfg does not consider agent #0 this the reserved platform/server agent */ ++ size_t __maybe_unused scmi_agent_count = cfg->agent_count + 1; ++ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++ /* SCMI clock domains resources */ ++ scmi_clk_agent_tbl = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_clk_agent_tbl)); ++ scmi_clock_config = (void *)config_scmi_clock.data; ++ scmi_clock_config->agent_table = scmi_clk_agent_tbl; ++ scmi_clock_config->agent_count = scmi_agent_count; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_CLOCK ++ /* Clock domains resources */ ++ optee_clock_cfg = fwk_mm_calloc(scpfw_resource_counter.clock_count, ++ sizeof(*optee_clock_cfg)); ++ optee_clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, ++ sizeof(*optee_clock_elt)); ++ ++ clock_data = fwk_mm_calloc(scpfw_resource_counter.clock_count, ++ sizeof(*clock_data)); ++ clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, ++ sizeof(*clock_elt)); ++#endif ++ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++ /* SCMI reset domains resources */ ++ scmi_reset_agent_tbl = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_reset_agent_tbl)); ++ scmi_reset_config = (void *)config_scmi_reset_domain.data; ++ scmi_reset_config->agent_table = scmi_reset_agent_tbl; ++ scmi_reset_config->agent_count = scmi_agent_count; ++ ++ optee_reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, ++ sizeof(*optee_reset_data)); ++ optee_reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, ++ sizeof(*optee_reset_elt)); ++ ++ reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, ++ sizeof(*reset_data)); ++ reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, ++ sizeof(*reset_elt)); ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++ /* PSU and related optee PSU regulator resources */ ++ psu_optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, ++ sizeof(*psu_optee_regu_elt)); ++ psu_optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, ++ sizeof(*psu_optee_regu_data)); ++ ++ psu_elt = fwk_mm_calloc(scpfw_resource_counter.psu_count + 1, ++ sizeof(*psu_elt)); ++ psu_data = fwk_mm_calloc(scpfw_resource_counter.psu_count, ++ sizeof(*psu_data)); ++ ++ /* DVFS and SCMI performance management resources */ ++ dvfs_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, ++ sizeof(*dvfs_elt)); ++ dvfs_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, ++ sizeof(*dvfs_data)); ++ ++ scmi_perf_domain_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, ++ sizeof(*scmi_perf_domain_data)); ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++ /* SCMI voltage domains resources */ ++ scmi_voltd_agent_tbl = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_voltd_agent_tbl)); ++ scmi_voltd_config = (void *)config_scmi_voltage_domain.data; ++ scmi_voltd_config->agent_table = scmi_voltd_agent_tbl; ++ scmi_voltd_config->agent_count = scmi_agent_count; ++ ++ optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, ++ sizeof(*optee_regu_data)); ++ optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, ++ sizeof(*optee_regu_elt)); ++ ++ voltd_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, ++ sizeof(*voltd_data)); ++ voltd_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, ++ sizeof(*voltd_elt)); ++#endif ++} ++ ++static void set_scmi_comm_resources(struct scpfw_config *cfg) ++{ ++ unsigned int channel_index; ++ size_t i, j; ++ /* @cfg does not consider agent #0 this the reserved platform/server agent */ ++ size_t scmi_agent_count = cfg->agent_count + 1; ++ ++ scmi_agent_table = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_agent_table)); ++ ++ scmi_service_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, ++ sizeof(*scmi_service_elt)); ++ ++ msg_smt_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, ++ sizeof(*msg_smt_elt)); ++ msg_smt_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, ++ sizeof(*msg_smt_data)); ++ ++ optee_mbx_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, ++ sizeof(*optee_mbx_elt)); ++ optee_mbx_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, ++ sizeof(*optee_mbx_data)); ++ ++ /* Set now the uniqnue scmi module instance configuration data */ ++ scmi_data = (struct mod_scmi_config){ ++ .agent_table = scmi_agent_table, ++ .agent_count = scmi_agent_count, ++ .protocol_count_max = 9, ++ .vendor_identifier = "STMicroelectronics", ++ .sub_vendor_identifier = "STMicroelectronics", ++ }; ++ ++ channel_index = 0; ++ ++ for (i = 0; i < cfg->agent_count; i++) { ++ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; ++ size_t agent_index = i + 1; ++ ++ scmi_agent_table[agent_index].type = SCMI_AGENT_TYPE_OSPM; ++ scmi_agent_table[agent_index].name = agent_cfg->name; ++ ++ for (j = 0; j < agent_cfg->channel_count; j++) { ++ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; ++ struct mod_scmi_service_config *service_data; ++ ++ service_data = fwk_mm_calloc(1, sizeof(*service_data)); ++ *service_data = (struct mod_scmi_service_config){ ++ .transport_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, 0), ++ .transport_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, ++ MOD_MSG_SMT_API_IDX_SCMI_TRANSPORT), ++ .scmi_agent_id = agent_cfg->agent_id, ++ .scmi_p2a_id = FWK_ID_NONE_INIT, ++ }; ++ ++ /* Currently expect 1 agent with ID SCMI_AGENT_ID_NSEC0 (1) */ ++ fwk_assert(service_data->scmi_agent_id == SCMI_AGENT_ID_NSEC0); ++ ++ scmi_service_elt[channel_index].name = channel_cfg->name; ++ scmi_service_elt[channel_index].data = service_data; ++ ++ msg_smt_elt[channel_index].name = channel_cfg->name; ++ msg_smt_elt[channel_index].data = (void *)(msg_smt_data + channel_index); ++ ++ msg_smt_data[channel_index] = (struct mod_msg_smt_channel_config){ ++ .type = MOD_MSG_SMT_CHANNEL_TYPE_REQUESTER, ++ .mailbox_size = 128, ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_MBX, ++ channel_index), ++ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_MBX, 0), ++ }; ++ ++ optee_mbx_elt[channel_index].name = channel_cfg->name; ++ optee_mbx_elt[channel_index].data = (void *)(optee_mbx_data + channel_index); ++ ++ optee_mbx_data[channel_index] = (struct mod_optee_mbx_channel_config){ ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, channel_index), ++ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, ++ MOD_MSG_SMT_API_IDX_DRIVER_INPUT), ++ }; ++ ++ channel_index++; ++ } ++ } ++}; ++ ++static void set_resources(struct scpfw_config *cfg) ++{ ++ size_t i, j, k, l __maybe_unused; ++ ++ for (i = 0; i < cfg->agent_count; i++) { ++ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; ++ size_t agent_index = i + 1; ++ ++ if (agent_index != agent_cfg->agent_id) { ++ panic("scpfw config expects agent ID is agent index"); ++ } ++ ++ for (j = 0; j < agent_cfg->channel_count; j++) { ++ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; ++ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++ /* Add first SCMI clock. We will add later the clocks used for DVFS */ ++ if (channel_cfg->clock_count) { ++ size_t clock_index = scpfw_resource_counter.clock_index; ++ struct mod_scmi_clock_device *dev = NULL; ++ ++ /* Set SCMI clocks array for the SCMI agent */ ++ dev = fwk_mm_calloc(channel_cfg->clock_count, ++ sizeof(struct mod_scmi_clock_device)); ++ ++ fwk_assert(!scmi_clk_agent_tbl[agent_index].device_table); ++ scmi_clk_agent_tbl[agent_index].device_count = channel_cfg->clock_count; ++ scmi_clk_agent_tbl[agent_index].device_table = dev; ++ ++ /* Set clock and optee/clock elements and config data */ ++ for (k = 0; k < channel_cfg->clock_count; k++) { ++ struct scmi_clock *clock_cfg = channel_cfg->clock + k; ++ ++ dev[k].element_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); ++ ++ optee_clock_cfg[clock_index].clk = clock_cfg->clk; ++ optee_clock_cfg[clock_index].default_enabled = clock_cfg->enabled; ++ ++ optee_clock_elt[clock_index].name = clock_cfg->name; ++ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); ++ ++ clock_data[clock_index] = (struct mod_clock_dev_config){ ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ clock_index), ++ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ 0), ++ }; ++ ++ clock_elt[clock_index].name = clock_cfg->name; ++ clock_elt[clock_index].data = (void *)(clock_data + clock_index); ++ ++ clock_index++; ++ } ++ ++ scpfw_resource_counter.clock_index = clock_index; ++ } ++#endif ++ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++ if (channel_cfg->reset_count) { ++ struct mod_scmi_reset_domain_device *dev = NULL; ++ size_t reset_index = scpfw_resource_counter.reset_index; ++ ++ /* Set SCMI reset domains array for the SCMI agent */ ++ dev = fwk_mm_calloc(channel_cfg->reset_count, sizeof(*dev)); ++ ++ fwk_assert(!scmi_reset_agent_tbl[agent_index].device_table); ++ scmi_reset_agent_tbl[agent_index].agent_domain_count = channel_cfg->reset_count; ++ scmi_reset_agent_tbl[agent_index].device_table = dev; ++ ++ /* Set reset_domain and optee/reset elements and config data */ ++ for (k = 0; k < channel_cfg->reset_count; k++) { ++ struct scmi_reset *reset_cfg = channel_cfg->reset + k; ++ ++ dev[k].element_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RESET_DOMAIN, ++ reset_index); ++ ++ optee_reset_data[reset_index].rstctrl = reset_cfg->rstctrl; ++ ++ optee_reset_elt[reset_index].name = reset_cfg->name; ++ optee_reset_elt[reset_index].data = ++ (void *)(optee_reset_data + reset_index); ++ ++ reset_data[reset_index] = (struct mod_reset_domain_dev_config){ ++ .driver_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_RESET, ++ reset_index), ++ .driver_api_id = ++ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_RESET, 0), ++ .modes = MOD_RESET_DOMAIN_AUTO_RESET | ++ MOD_RESET_DOMAIN_MODE_EXPLICIT_ASSERT | ++ MOD_RESET_DOMAIN_MODE_EXPLICIT_DEASSERT, ++ }; ++ ++ reset_elt[reset_index].name = reset_cfg->name; ++ reset_elt[reset_index].data = (void *)(reset_data + reset_index); ++ ++ reset_index++; ++ } ++ ++ scpfw_resource_counter.reset_index = reset_index; ++ } ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++ if (channel_cfg->voltd_count) { ++ size_t regu_index = scpfw_resource_counter.regu_index; ++ struct mod_scmi_voltd_device *dev = NULL; ++ ++ /* Set SCMI voltage domains array for the SCMI agent */ ++ dev = fwk_mm_calloc(channel_cfg->voltd_count, ++ sizeof(struct mod_scmi_voltd_device)); ++ ++ fwk_assert(!scmi_voltd_agent_tbl[agent_index].device_table); ++ scmi_voltd_agent_tbl[agent_index].domain_count = channel_cfg->voltd_count; ++ scmi_voltd_agent_tbl[agent_index].device_table = dev; ++ ++ /* Set voltage_domain and optee/regu elements and config data */ ++ for (k = 0; k < channel_cfg->voltd_count; k++) { ++ struct scmi_voltd *voltd_cfg = channel_cfg->voltd + k; ++ static const char reserved[] = "reserved"; ++ const char *name = NULL; ++ ++ if (voltd_cfg->rdev) { ++ name = voltd_cfg->rdev->reg_name; ++ } else { ++ name = reserved; ++ } ++ ++ dev[regu_index].element_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_VOLTAGE_DOMAIN, k); ++ ++ optee_regu_elt[regu_index].name = name; ++ optee_regu_elt[regu_index].data = (void *)(optee_regu_data + regu_index); ++ optee_regu_data[regu_index].rdev = voltd_cfg->rdev; ++ optee_regu_data[regu_index].default_enabled = voltd_cfg->enabled; ++ ++ voltd_data[regu_index].driver_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, ++ regu_index); ++ voltd_data[regu_index].api_id = ++ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, 0); ++ ++ voltd_elt[regu_index].name = name; ++ voltd_elt[regu_index].data = (void *)(voltd_data + regu_index); ++ regu_index++; ++ } ++ ++ scpfw_resource_counter.regu_index = regu_index; ++ } ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++ if (channel_cfg->perfd_count) { ++ size_t clock_index = scpfw_resource_counter.clock_index; ++ size_t psu_index = scpfw_resource_counter.psu_index; ++ size_t dvfs_index = scpfw_resource_counter.dvfs_index; ++ ++ for (k = 0; k < channel_cfg->perfd_count; k++) { ++ struct mod_scmi_perf_config *scmi_perf_data = NULL; ++ struct scmi_perfd *perfd_cfg = channel_cfg->perfd + k; ++ ++ /* ++ * DVFS with SCMI performance management domains ++ * 1 initial scmi_perf instance defines the number of DVFS's ++ * For each DVFS instance: ++ * - 1 instance (elt/config) of dvfs, psu, optee/psu, clock, optee/clock ++ * Clocks and optee/clocks are already allocated but not yet set. ++ */ ++ ++ /* scmi_perf: data defines the DVFS domains indices */ ++ scmi_perf_domain_data[dvfs_index] = (struct mod_scmi_perf_domain_config){ }; ++ ++ scmi_perf_data = (void *)config_scmi_perf.data; ++ ++ scmi_perf_data[dvfs_index].domains = (void *)scmi_perf_domain_data; ++ scmi_perf_data[dvfs_index].perf_doms_count = scpfw_resource_counter.dvfs_count; ++ scmi_perf_data[dvfs_index].fast_channels_alarm_id = (fwk_id_t)FWK_ID_NONE_INIT; ++#ifdef BUILD_HAS_MOD_STATISTICS ++ scmi_perf_data[dvfs_index].stats_enabled = true; ++#endif ++ ++ /* dvfs instances: 1 instance per expose DVFS service */ ++ dvfs_data[dvfs_index].psu_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, psu_index); ++ dvfs_data[dvfs_index].clock_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); ++ dvfs_data[dvfs_index].latency = 0; /* not set, used for async access */ ++ dvfs_data[dvfs_index].opps = ++ fwk_mm_calloc(perfd_cfg->dvfs_opp_count, ++ sizeof(struct mod_dvfs_opp)); ++ ++ for (l = 0; l < perfd_cfg->dvfs_opp_count; l++) { ++ uint64_t power = 0; ++ ++ /* Quick estimation of power consumpsion */ ++ power = perfd_cfg->dvfs_opp_khz[l]; ++ power *= perfd_cfg->dvfs_opp_mv[l]; ++ power *= perfd_cfg->dvfs_opp_mv[l]; ++ power /= 100 * 1000 * 1000; ++ ++ dvfs_data[dvfs_index].opps[l] = (struct mod_dvfs_opp){ ++ .level = perfd_cfg->dvfs_opp_khz[l] * 1000UL, ++ .frequency = perfd_cfg->dvfs_opp_khz[l], ++ .voltage = perfd_cfg->dvfs_opp_mv[l], ++ .power = (uint32_t)power, ++ }; ++ } ++ ++ dvfs_elt[dvfs_index].name = perfd_cfg->name; ++ dvfs_elt[dvfs_index].data = (void *)(dvfs_data + dvfs_index); ++ ++ /* Module psu_optee module (elements and configuration data) */ ++ psu_optee_regu_elt[psu_index].name = perfd_cfg->rdev->reg_name; ++ psu_optee_regu_elt[psu_index].sub_element_count = scpfw_resource_counter.psu_count; ++ psu_optee_regu_elt[psu_index].data = (void *)(psu_optee_regu_data + psu_index); ++ ++ psu_optee_regu_data[psu_index].rdev = perfd_cfg->rdev; ++ ++ /* Module psu (elements and configuration data) */ ++ psu_elt[psu_index].name = perfd_cfg->rdev->reg_name; ++ psu_elt[psu_index].data = (void *)(psu_data + psu_index); ++ psu_data[psu_index].driver_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, psu_index); ++ psu_data[psu_index].driver_api_id = ++ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, 0); ++ ++ /* Module clock and optee_clock */ ++ fwk_assert(!clock_elt[clock_index].data); ++ ++ clock_elt[clock_index].name = perfd_cfg->clk->name; ++ clock_elt[clock_index].data = (void *)(clock_data + clock_index); ++ ++ clock_data[clock_index] = (struct mod_clock_dev_config){ ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ clock_index), ++ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ 0), ++ }; ++ ++ optee_clock_cfg[clock_index].clk = perfd_cfg->clk; ++ optee_clock_cfg[clock_index].default_enabled = false; ++ ++ optee_clock_elt[clock_index].name = perfd_cfg->clk->name; ++ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); ++ ++ clock_index++; ++ psu_index++; ++ dvfs_index++; ++ } ++ ++ scpfw_resource_counter.clock_index = clock_index; ++ scpfw_resource_counter.psu_index = psu_index; ++ scpfw_resource_counter.dvfs_index = dvfs_index; ++ } ++#endif ++ } ++ } ++} ++ ++void scpfw_configure(struct scpfw_config *cfg) ++{ ++ count_resources(cfg); ++ allocate_global_resources(cfg); ++ set_scmi_comm_resources(cfg); ++ set_resources(cfg); ++} +diff --git a/product/optee-stm32mp1/fw/config_mbx_smt.c b/product/optee-stm32mp1/fw/config_mbx_smt.c +deleted file mode 100644 +index 21d606d7..00000000 +--- a/product/optee-stm32mp1/fw/config_mbx_smt.c ++++ /dev/null +@@ -1,68 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +- +-#define OSPM0_SMT_MAILBOX_PA 0x2ffff000 +-#define OSPM0_SMT_MAILBOX_SIZE SCMI_SHMEM_SIZE +- +-static const struct fwk_element mbx_element_table[] = { +- [SCMI_CHANNEL_DEVICE_IDX_NS0] = { +- .name = "SCMI non-secure to OP-TEE channel 0", +- .data = &((struct mod_optee_mbx_channel_config){ +- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_SMT, 0), +- .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_SMT, +- MOD_OPTEE_SMT_API_IDX_DRIVER_INPUT) +- }) +- }, +- [SCMI_CHANNEL_DEVICE_IDX_COUNT] = { 0 }, +-}; +- +-static const struct fwk_element *mbx_get_element_table(fwk_id_t module_id) +-{ +- return (const struct fwk_element *)mbx_element_table; +-} +- +-struct fwk_module_config config_optee_mbx = { +- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(mbx_get_element_table), +-}; +- +-static struct fwk_element smt_elt_table[] = { +- [0] = { +- .name = "OSPM0", +- .data = &((struct mod_optee_smt_channel_config) { +- .type = MOD_OPTEE_SMT_CHANNEL_TYPE_REQUESTER, +- .mailbox_address = OSPM0_SMT_MAILBOX_PA, +- .mailbox_size = OSPM0_SMT_MAILBOX_SIZE, +- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_MBX, +- SCMI_CHANNEL_DEVICE_IDX_NS0), +- .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_MBX, 0), +- }) +- }, +- [1] = { 0 }, +-}; +- +-static const struct fwk_element *smt_get_element_table(fwk_id_t module_id) +-{ +- fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_SMT); +- +- return (const struct fwk_element *)smt_elt_table; +-} +- +-struct fwk_module_config config_optee_smt = { +- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(smt_get_element_table), +-}; +diff --git a/product/optee-stm32mp1/fw/config_scmi.c b/product/optee-stm32mp1/fw/config_scmi.c +deleted file mode 100644 +index 4f3442cc..00000000 +--- a/product/optee-stm32mp1/fw/config_scmi.c ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-static const struct fwk_element service_table[] = { +- [SCMI_SERVICE_IDX_NS_CHANNEL0] = { +- .name = "service-0", +- .data = &((struct mod_scmi_service_config) { +- .transport_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_SMT, 0), +- .transport_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_SMT, +- MOD_OPTEE_SMT_API_IDX_SCMI_TRANSPORT), +- .scmi_agent_id = SCMI_AGENT_ID_NSEC0, +- .scmi_p2a_id = FWK_ID_NONE_INIT, +- }), +- }, +- [SCMI_SERVICE_IDX_COUNT] = { 0 } +-}; +- +-static const struct fwk_element *get_scmi_service_table(fwk_id_t module_id) +-{ +- return service_table; +-} +- +-static const struct mod_scmi_agent agent_table[] = { +- [SCMI_AGENT_ID_NSEC0] = { +- .type = SCMI_AGENT_TYPE_OSPM, +- .name = "OSPM0", +- }, +-}; +- +-struct fwk_module_config config_scmi = { +- .data = &((struct mod_scmi_config) { +- .protocol_count_max = 9, +- .agent_count = FWK_ARRAY_SIZE(agent_table) - 1, +- .agent_table = agent_table, +- .vendor_identifier = "Linaro", +- .sub_vendor_identifier = "PMWG", +- }), +- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_scmi_service_table), +-}; +diff --git a/product/optee-stm32mp1/fw/config_scmi_clocks.c b/product/optee-stm32mp1/fw/config_scmi_clocks.c +deleted file mode 100644 +index 478ae588..00000000 +--- a/product/optee-stm32mp1/fw/config_scmi_clocks.c ++++ /dev/null +@@ -1,254 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-/* +- * Indices of clock elements exposed through a SCMI agent. +- * As all exposed SCMI clocks relate to a single backend dirver +- * these indices are used as indices for fwk elements for modules +- * CLOCK and STM32_CLOCK. Note these are not the clock ID values +- * exposed through SCMI. +- */ +-enum clock_elt_idx { +- /* Clocks exposed to agent SCMI */ +- CLK_IDX_SCMI_HSE, +- CLK_IDX_SCMI_HSI, +- CLK_IDX_SCMI_CSI, +- CLK_IDX_SCMI_LSE, +- CLK_IDX_SCMI_LSI, +- CLK_IDX_SCMI_PLL2_Q, +- CLK_IDX_SCMI_PLL2_R, +- CLK_IDX_SCMI_MPU, +- CLK_IDX_SCMI_AXI, +- CLK_IDX_SCMI_BSEC, +- CLK_IDX_SCMI_CRYP1, +- CLK_IDX_SCMI_GPIOZ, +- CLK_IDX_SCMI_HASH1, +- CLK_IDX_SCMI_I2C4, +- CLK_IDX_SCMI_I2C6, +- CLK_IDX_SCMI_IWDG1, +- CLK_IDX_SCMI_RNG1, +- CLK_IDX_SCMI_RTC, +- CLK_IDX_SCMI_RTCAPB, +- CLK_IDX_SCMI_SPI6, +- CLK_IDX_SCMI_USART1, +- /* Count indices */ +- CLK_IDX_COUNT +-}; +- +-struct mod_stm32_clock_dev_config { +- const char *name; +- unsigned long rcc_clk_id; +- bool default_enabled; +-}; +- +-/* +- * stm32_clock_cfg - Common configuration for exposed SCMI clocks +- * +- * Clock name defined here is used for all CLOCK and STM32_CLOCK +- * fwk elements names. +- */ +-#define STM32_CLOCK_CFG(_idx, _rcc_clk_id, _name, _default_enabled) \ +- [(_idx)] = { \ +- .rcc_clk_id = (_rcc_clk_id), \ +- .name = (_name), \ +- .default_enabled = (_default_enabled), \ +- } +- +-static const struct mod_stm32_clock_dev_config stm32_clock_cfg[] = { +- STM32_CLOCK_CFG(CLK_IDX_SCMI_HSE, CK_HSE, "ck_hse", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_HSI, CK_HSI, "ck_hsi", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_CSI, CK_CSI, "ck_csi", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_LSE, CK_LSE, "ck_lse", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_LSI, CK_LSI, "ck_lsi", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_PLL2_Q, PLL2_Q, "pll2_q", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_PLL2_R, PLL2_R, "pll2_r", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_MPU, CK_MCU, "ck_mpu", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_AXI, CK_AXI, "ck_axi", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_BSEC, BSEC, "bsec", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_CRYP1, CRYP1, "cryp1", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_GPIOZ, GPIOZ, "gpioz", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_HASH1, HASH1, "hash1", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_I2C4, I2C4_K, "i2c4_k", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_I2C6, I2C6_K, "i2c6_k", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_IWDG1, IWDG1, "iwdg1", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_RNG1, RNG1_K, "rng1_k", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_RTC, RTC, "ck_rtc", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_RTCAPB, RTCAPB, "rtcapb", true), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_SPI6, SPI6_K, "spi6_k", false), +- STM32_CLOCK_CFG(CLK_IDX_SCMI_USART1, USART1_K, "usart1_k", false), +-}; +- +-/* +- * Bindgins between SCMI clock_id value and clock module element in fwk +- */ +-#define SCMI_CLOCK_ELT_ID(_idx) \ +- { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, (_idx)) } +- +-static struct mod_scmi_clock_device scmi_clock_device[] = { +- [CK_SCMI_HSE] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HSE), +- [CK_SCMI_HSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HSI), +- [CK_SCMI_CSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_CSI), +- [CK_SCMI_LSE] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_LSE), +- [CK_SCMI_LSI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_LSI), +- [CK_SCMI_PLL2_Q] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_PLL2_Q), +- [CK_SCMI_PLL2_R] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_PLL2_R), +- [CK_SCMI_MPU] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_MPU), +- [CK_SCMI_AXI] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_AXI), +- [CK_SCMI_BSEC] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_BSEC), +- [CK_SCMI_CRYP1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_CRYP1), +- [CK_SCMI_GPIOZ] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_GPIOZ), +- [CK_SCMI_HASH1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_HASH1), +- [CK_SCMI_I2C4] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_I2C4), +- [CK_SCMI_I2C6] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_I2C6), +- [CK_SCMI_IWDG1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_IWDG1), +- [CK_SCMI_RNG1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RNG1), +- [CK_SCMI_RTC] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RTC), +- [CK_SCMI_RTCAPB] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_RTCAPB), +- [CK_SCMI_SPI6] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_SPI6), +- [CK_SCMI_USART1] = SCMI_CLOCK_ELT_ID(CLK_IDX_SCMI_USART1), +-}; +- +-/* Agents and clocks references */ +-static const struct mod_scmi_clock_agent clk_agent_tbl[SCMI_AGENT_ID_COUNT] = { +- [SCMI_AGENT_ID_NSEC0] = { +- .device_table = (void *)scmi_clock_device, +- .device_count = FWK_ARRAY_SIZE(scmi_clock_device), +- }, +-}; +- +-/* Exported configuration data for module SCMI_CLOCK */ +-struct fwk_module_config config_scmi_clock = { +- .data = &((struct mod_scmi_clock_config){ +- .agent_table = clk_agent_tbl, +- .agent_count = FWK_ARRAY_SIZE(clk_agent_tbl), +- }), +-}; +- +-/* +- * Clock backend driver configuration +- * STM32_CLOCK element index is the related CLOCK element index. +- */ +-#define CLOCK_DATA(_idx) ((struct mod_clock_dev_config){ \ +- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, \ +- (_idx)), \ +- .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, 0), \ +- }) +- +-#define CLOCK_ELT(_idx) [(_idx)] = { \ +- .name = stm32_clock_cfg[(_idx)].name, \ +- .data = &CLOCK_DATA((_idx)), \ +- } +- +-/* Element names are the clock names exposed by the SCMI service */ +-static struct fwk_element clock_elt[] = { +- /* Clocks exposed to agent SCMI */ +- CLOCK_ELT(CLK_IDX_SCMI_HSE), +- CLOCK_ELT(CLK_IDX_SCMI_HSI), +- CLOCK_ELT(CLK_IDX_SCMI_CSI), +- CLOCK_ELT(CLK_IDX_SCMI_LSE), +- CLOCK_ELT(CLK_IDX_SCMI_LSI), +- CLOCK_ELT(CLK_IDX_SCMI_PLL2_Q), +- CLOCK_ELT(CLK_IDX_SCMI_PLL2_R), +- CLOCK_ELT(CLK_IDX_SCMI_MPU), +- CLOCK_ELT(CLK_IDX_SCMI_AXI), +- CLOCK_ELT(CLK_IDX_SCMI_BSEC), +- CLOCK_ELT(CLK_IDX_SCMI_CRYP1), +- CLOCK_ELT(CLK_IDX_SCMI_GPIOZ), +- CLOCK_ELT(CLK_IDX_SCMI_HASH1), +- CLOCK_ELT(CLK_IDX_SCMI_I2C4), +- CLOCK_ELT(CLK_IDX_SCMI_I2C6), +- CLOCK_ELT(CLK_IDX_SCMI_IWDG1), +- CLOCK_ELT(CLK_IDX_SCMI_RNG1), +- CLOCK_ELT(CLK_IDX_SCMI_RTC), +- CLOCK_ELT(CLK_IDX_SCMI_RTCAPB), +- CLOCK_ELT(CLK_IDX_SCMI_SPI6), +- CLOCK_ELT(CLK_IDX_SCMI_USART1), +- /* Termination entry */ +- [CLK_IDX_COUNT] = { 0 } +-}; +- +-static_assert(FWK_ARRAY_SIZE(clock_elt) == CLK_IDX_COUNT + 1, +- "Invalid range for CLOCK and STM32_CLOCK indices"); +- +-/* Exported configuration data for module VOLTAGE_DOMAIN */ +-const struct fwk_module_config config_clock = { +- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(clock_elt), +-}; +- +-#define CLOCK_COUNT FWK_ARRAY_SIZE(stm32_clock_cfg) +-static struct mod_optee_clock_config optee_clock_cfg[CLOCK_COUNT]; +- +-#define OPTEE_CLOCK_ELT(_idx) \ +- [(_idx)] = { \ +- .name = stm32_clock_cfg[(_idx)].name, \ +- .data = &optee_clock_cfg[(_idx)], \ +- } +- +-static const struct fwk_element optee_clock_elt[] = { +- /* Clocks exposed to agent SCMI */ +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HSE), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HSI), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_CSI), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_LSE), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_LSI), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_PLL2_Q), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_PLL2_R), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_MPU), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_AXI), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_BSEC), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_CRYP1), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_GPIOZ), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_HASH1), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_I2C4), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_I2C6), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_IWDG1), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RNG1), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RTC), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_RTCAPB), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_SPI6), +- OPTEE_CLOCK_ELT(CLK_IDX_SCMI_USART1), +- /* Termination entry */ +- [CLK_IDX_COUNT] = { 0 } +-}; +- +-static_assert(FWK_ARRAY_SIZE(optee_clock_elt) == CLK_IDX_COUNT + 1, +- "Invalid range for CLOCK and STM32_CLOCK indices"); +- +-static const struct fwk_element *optee_clock_get_elt_table(fwk_id_t module_id) +-{ +- size_t n; +- +- for (n = 0; n < FWK_ARRAY_SIZE(optee_clock_cfg); n++) { +- optee_clock_cfg[n].clk = +- stm32mp_rcc_clock_id_to_clk(stm32_clock_cfg[n].rcc_clk_id); +- optee_clock_cfg[n].default_enabled = stm32_clock_cfg[n].default_enabled; +- } +- +- return optee_clock_elt; +-} +- +-struct fwk_module_config config_optee_clock = { +- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_elt_table), +-}; +diff --git a/product/optee-stm32mp1/fw/config_scmi_reset_domains.c b/product/optee-stm32mp1/fw/config_scmi_reset_domains.c +deleted file mode 100644 +index bb9794d6..00000000 +--- a/product/optee-stm32mp1/fw/config_scmi_reset_domains.c ++++ /dev/null +@@ -1,204 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ +- +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-/* +- * Indices of reset domain elements exposed through a SCMI agent. +- * As all exposed SCMI reset domains relate to a single backend dirver +- * these indices are used as indices for fwk elements for modules +- * RESET_DOMAIN and STM32_RESET. +- */ +-enum resetd_elt_idx { +- /* Reset domain exposed to agent SCMI */ +- RESETD_IDX_SCMI_SPI6, +- RESETD_IDX_SCMI_I2C4, +- RESETD_IDX_SCMI_I2C6, +- RESETD_IDX_SCMI_USART1, +- RESETD_IDX_SCMI_STGEN, +- RESETD_IDX_SCMI_GPIOZ, +- RESETD_IDX_SCMI_CRYP1, +- RESETD_IDX_SCMI_HASH1, +- RESETD_IDX_SCMI_RNG1, +- RESETD_IDX_SCMI_MDMA, +- RESETD_IDX_SCMI_MCU, +- RESETD_IDX_SCMI_MCU_HOLD_BOOT, +- RESETD_IDX_COUNT +-}; +- +-struct mod_stm32_reset_dev_config { +- const char *name; +- unsigned long rcc_rst_id; +-}; +- +-/* +- * stm32_resetd_cfg - Common configuration for exposed SCMI reset domains +- * +- * Domain names defined here are used for all RESET_DOMAIN and STM32_RESET +- * fwk elements names. +- */ +-#define STM32_RESET_CFG(_idx, _rcc_rst_id, _name) \ +- [(_idx)] = { .rcc_rst_id = (_rcc_rst_id), .name = (_name) } +- +-static const struct mod_stm32_reset_dev_config stm32_resetd_cfg[] = { +- STM32_RESET_CFG(RESETD_IDX_SCMI_SPI6, SPI6_R, "spi6"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_I2C4, I2C4_R, "i2c4"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_I2C6, I2C6_R, "i2c6"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_USART1, USART1_R, "usart1"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_STGEN, STGEN_R, "stgen"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_GPIOZ, GPIOZ_R, "gpioz"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_CRYP1, CRYP1_R, "cryp1"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_HASH1, HASH1_R, "hash1"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_RNG1, RNG1_R, "rng1"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_MDMA, MDMA_R, "mdma"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_MCU, MCU_R, "mcu"), +- STM32_RESET_CFG(RESETD_IDX_SCMI_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu-hold-boot"), +-}; +- +-/* +- * Bindgins between SCMI domain_id value and reset domain module element in fwk +- */ +-#define SCMI_RESETD_ELT_ID(_idx) \ +- { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RESET_DOMAIN, (_idx)) } +- +-static const struct mod_scmi_reset_domain_device scmi_resetd_device[] = { +- [RST_SCMI_SPI6] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_SPI6), +- [RST_SCMI_I2C4] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_I2C4), +- [RST_SCMI_I2C6] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_I2C6), +- [RST_SCMI_USART1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_USART1), +- [RST_SCMI_STGEN] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_STGEN), +- [RST_SCMI_GPIOZ] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_GPIOZ), +- [RST_SCMI_CRYP1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_CRYP1), +- [RST_SCMI_HASH1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_HASH1), +- [RST_SCMI_RNG1] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_RNG1), +- [RST_SCMI_MDMA] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_MDMA), +- [RST_SCMI_MCU] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_MCU), +- [RST_SCMI_MCU_HOLD_BOOT] = SCMI_RESETD_ELT_ID(RESETD_IDX_SCMI_MCU_HOLD_BOOT), +-}; +- +-/* Agents andreset domains references */ +-static const struct mod_scmi_reset_domain_agent resetd_agent_table[SCMI_AGENT_ID_COUNT] = { +- [SCMI_AGENT_ID_NSEC0] = { +- .device_table = (void *)scmi_resetd_device, +- .agent_domain_count = FWK_ARRAY_SIZE(scmi_resetd_device), +- }, +-}; +- +-/* Exported configuration data for module SCMI_RESET_DOMAIN */ +-struct fwk_module_config config_scmi_reset_domain = { +- .data = &((struct mod_scmi_reset_domain_config){ +- .agent_table = resetd_agent_table, +- .agent_count = FWK_ARRAY_SIZE(resetd_agent_table), +- }), +-}; +- +-/* +- * Reset controller backend driver configuration +- * STM32_RESET element index is the related RESET_DOMAIN element index. +- */ +-#define RESETD_DATA(_idx) ((struct mod_reset_domain_dev_config){ \ +- .driver_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_RESET, (_idx)), \ +- .driver_api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_RESET, 0), \ +- .modes = MOD_RESET_DOMAIN_AUTO_RESET | \ +- MOD_RESET_DOMAIN_MODE_EXPLICIT_ASSERT | \ +- MOD_RESET_DOMAIN_MODE_EXPLICIT_DEASSERT, \ +- .capabilities = 0, /* No notif, no async */ \ +- }) +- +- +-#define RESETD_ELT(_idx) [(_idx)] = { \ +- .name = stm32_resetd_cfg[(_idx)].name, \ +- .data = &RESETD_DATA((_idx)), \ +- } +- +-/* Element names are the reset domain names exposed by the SCMI service */ +-static const struct fwk_element resetd_elt[] = { +- /* Reset domains exposed to agent SCMI */ +- RESETD_ELT(RESETD_IDX_SCMI_SPI6), +- RESETD_ELT(RESETD_IDX_SCMI_I2C4), +- RESETD_ELT(RESETD_IDX_SCMI_I2C6), +- RESETD_ELT(RESETD_IDX_SCMI_USART1), +- RESETD_ELT(RESETD_IDX_SCMI_STGEN), +- RESETD_ELT(RESETD_IDX_SCMI_GPIOZ), +- RESETD_ELT(RESETD_IDX_SCMI_CRYP1), +- RESETD_ELT(RESETD_IDX_SCMI_HASH1), +- RESETD_ELT(RESETD_IDX_SCMI_RNG1), +- RESETD_ELT(RESETD_IDX_SCMI_MDMA), +- RESETD_ELT(RESETD_IDX_SCMI_MCU), +- RESETD_ELT(RESETD_IDX_SCMI_MCU_HOLD_BOOT), +- /* Termination entry */ +- [RESETD_IDX_COUNT] = { 0 } +-}; +- +-static_assert(FWK_ARRAY_SIZE(resetd_elt) == RESETD_IDX_COUNT + 1, +- "Invalid range for RESET_DOMAIN and STM32_RESET indices"); +- +-/* Exported configuration data for module VOLTAGE_DOMAIN */ +-const struct fwk_module_config config_reset_domain = { +- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(resetd_elt), +-}; +- +-/* +- * Configuration for module OPTEE_RESET +- */ +-#define RESET_COUNT FWK_ARRAY_SIZE(stm32_resetd_cfg) +-static struct mod_optee_reset_dev_config optee_reset_cfg[RESET_COUNT]; +- +-#define OPTEE_RESET_ELT(_idx) \ +- [(_idx)] = { \ +- .name = stm32_resetd_cfg[(_idx)].name, \ +- .data = &optee_reset_cfg[(_idx)], \ +- } +- +-static const struct fwk_element optee_reset_elt[] = { +- /* Reset domaines exposed to agent SCMI */ +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_SPI6), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_I2C4), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_I2C6), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_USART1), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_STGEN), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_GPIOZ), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_CRYP1), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_HASH1), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_RNG1), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_MDMA), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_MCU), +- OPTEE_RESET_ELT(RESETD_IDX_SCMI_MCU_HOLD_BOOT), +- /* Termination entry */ +- [RESETD_IDX_COUNT] = { 0 } +-}; +- +-static_assert(FWK_ARRAY_SIZE(optee_reset_elt) == RESETD_IDX_COUNT + 1, +- "Invalid range for RESET and OPTEE_RESET indices"); +- +-static const struct fwk_element *optee_reset_get_elt_table(fwk_id_t module_id) +-{ +- size_t n; +- +- for (n = 0; n < FWK_ARRAY_SIZE(optee_reset_cfg); n++) { +- optee_reset_cfg[n].rstctrl = +- stm32mp_rcc_reset_id_to_rstctrl(stm32_resetd_cfg[n].rcc_rst_id); +- } +- +- return optee_reset_elt; +-} +- +-struct fwk_module_config config_optee_reset = { +- .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_reset_get_elt_table), +-}; +diff --git a/product/optee-stm32mp1/fw/config_scmi_voltage_domains.c b/product/optee-stm32mp1/fw/config_scmi_voltage_domains.c +deleted file mode 100644 +index 54270128..00000000 +--- a/product/optee-stm32mp1/fw/config_scmi_voltage_domains.c ++++ /dev/null +@@ -1,262 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. 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 +- +-/* +- * stm32_pwr_cfg - Configuration data for PWR regulators exposed thru SCMI +- * +- * These configation data is referenced in the fwk config data of +- * fwk modules VOLTAGE_DOMAIN and STM32_PMIC_REGU. +- */ +-enum stm32_pwr_regu { +- STM32_PWR_REG11, +- STM32_PWR_REG18, +- STM32_PWR_USB33, +-}; +- +-static const struct mod_stm32_pwr_regu_dev_config stm32_pwr_cfg[] = { +- [STM32_PWR_REG11] = { .pwr_id = PWR_REG11, .regu_name = "reg11" }, +- [STM32_PWR_REG18] = { .pwr_id = PWR_REG18, .regu_name = "reg18" }, +- [STM32_PWR_USB33] = { .pwr_id = PWR_USB33, .regu_name = "usb33" }, +-}; +- +-/* +- * stm32_pmic_cfg - Configuration data for PMIC regulators exposed thru SCMI +- * +- * These configation data are referenced in the fwk config data of +- * fwk modules VOLTAGE_DOMAIN and STM32_PMIC_REGU. +- * @regu_name is used both in PMIC regulator driver API and as SCMI +- * voltage domain name. +- */ +-enum stpmic1_regu { +- STPMIC1_REGU_BUCK1, +- STPMIC1_REGU_BUCK2, +- STPMIC1_REGU_BUCK3, +- STPMIC1_REGU_BUCK4, +- STPMIC1_REGU_LDO1, +- STPMIC1_REGU_LDO2, +- STPMIC1_REGU_LDO3, +- STPMIC1_REGU_LDO4, +- STPMIC1_REGU_LDO5, +- STPMIC1_REGU_LDO6, +- STPMIC1_REGU_VREFDDR, +- STPMIC1_REGU_BOOST, +- STPMIC1_REGU_PWR_SW1, +- STPMIC1_REGU_PWR_SW2, +-}; +- +-static const struct mod_stm32_pmic_regu_dev_config stm32_pmic_cfg[] = { +- [STPMIC1_REGU_BUCK1] = { .regu_name = "buck1" }, +- [STPMIC1_REGU_BUCK2] = { .regu_name = "buck2", .read_only = true }, +- [STPMIC1_REGU_BUCK3] = { .regu_name = "buck3" }, +- [STPMIC1_REGU_BUCK4] = { .regu_name = "buck4" }, +- [STPMIC1_REGU_LDO1] = { .regu_name = "ldo1" }, +- [STPMIC1_REGU_LDO2] = { .regu_name = "ldo2" }, +- [STPMIC1_REGU_LDO3] = { .regu_name = "ldo3", .read_only = true }, +- [STPMIC1_REGU_LDO4] = { .regu_name = "ldo4" }, +- [STPMIC1_REGU_LDO5] = { .regu_name = "ldo5" }, +- [STPMIC1_REGU_LDO6] = { .regu_name = "ldo6" }, +- [STPMIC1_REGU_VREFDDR] = { .regu_name = "vref_ddr", .read_only = true }, +- [STPMIC1_REGU_BOOST] = { .regu_name = "boost" }, +- [STPMIC1_REGU_PWR_SW1] = { .regu_name = "pwr_sw1" }, +- [STPMIC1_REGU_PWR_SW2] = { .regu_name = "pwr_sw2" }, +-}; +- +-/* +- * Indices of voltage domain module elements exposed through a SCMI agent. +- */ +-enum voltd_elt_idx { +- /* Voltage domains exposed to agent SCMI */ +- VOLTD_IDX_SCMI_REG11, +- VOLTD_IDX_SCMI_REG18, +- VOLTD_IDX_SCMI_USB33, +- VOLTD_IDX_SCMI_STPMIC1_BUCK1, +- VOLTD_IDX_SCMI_STPMIC1_BUCK2, +- VOLTD_IDX_SCMI_STPMIC1_BUCK3, +- VOLTD_IDX_SCMI_STPMIC1_BUCK4, +- VOLTD_IDX_SCMI_STPMIC1_LDO1, +- VOLTD_IDX_SCMI_STPMIC1_LDO2, +- VOLTD_IDX_SCMI_STPMIC1_LDO3, +- VOLTD_IDX_SCMI_STPMIC1_LDO4, +- VOLTD_IDX_SCMI_STPMIC1_LDO5, +- VOLTD_IDX_SCMI_STPMIC1_LDO6, +- VOLTD_IDX_SCMI_STPMIC1_VREFDDR, +- VOLTD_IDX_SCMI_STPMIC1_BOOST, +- VOLTD_IDX_SCMI_STPMIC1_PWR_SW1, +- VOLTD_IDX_SCMI_STPMIC1_PWR_SW2, +- VOLTD_IDX_COUNT +-}; +- +-/* +- * SCMI Voltage Domain driver configuration +- */ +-#define SCMI_VOLTD_ELT_ID(_idx) \ +- { .element_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_VOLTAGE_DOMAIN, (_idx)) } +- +-static struct mod_scmi_voltd_device scmi_voltd_device[] = { +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_REG11), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_REG18), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_USB33), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK1), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK2), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK3), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BUCK4), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO1), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO2), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO3), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO4), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO5), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_LDO6), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_VREFDDR), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_BOOST), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_PWR_SW1), +- SCMI_VOLTD_ELT_ID(VOLTD_SCMI_STPMIC1_PWR_SW2), +-}; +- +-static const struct mod_scmi_voltd_agent voltd_agent_table[SCMI_AGENT_ID_COUNT] = { +- [SCMI_AGENT_ID_NSEC0] = { +- .device_table = scmi_voltd_device, +- .domain_count = FWK_ARRAY_SIZE(scmi_voltd_device), +- }, +-}; +- +-/* Exported configuration data for module SCMI_VOLTAGE_DOMAIN */ +-const struct fwk_module_config config_scmi_voltage_domain = { +- .data = &((struct mod_scmi_voltd_config){ +- .agent_table = voltd_agent_table, +- .agent_count = FWK_ARRAY_SIZE(voltd_agent_table), +- }), +-}; +- +-/* +- * Voltage Domain driver configuration describes STM32_PWR_REGU elements +- * and STM32_PMIC_REGU elements. +- */ +-#define VOLTD_STM32_PWR_DATA(_idx) \ +- ((struct mod_voltd_dev_config){ \ +- .driver_id = \ +- FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_PWR_REGU, (_idx)), \ +- .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_PWR_REGU, 0), \ +- }) +- +-#define VOLTD_STM32_PWR_ELT_ID(_idx) \ +- { \ +- .name = stm32_pwr_cfg[(_idx)].regu_name, \ +- .data = &VOLTD_STM32_PWR_DATA(_idx), \ +- } +- +-#define VOLTD_STM32_PMIC_DATA(_idx) \ +- ((struct mod_voltd_dev_config){ \ +- .driver_id = \ +- FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_PMIC_REGU, (_idx)), \ +- .api_id = FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_PMIC_REGU, 0), \ +- }) +- +-#define VOLTD_STM32_PMIC_ELT_ID(_dev_idx) \ +- { \ +- .name = stm32_pmic_cfg[(_dev_idx)].regu_name, \ +- .data = &VOLTD_STM32_PMIC_DATA(_dev_idx), \ +- } +- +-/* Elements names are the voltage domain names exposed by the SCMI service */ +-static const struct fwk_element voltd_elt[] = { +- [VOLTD_IDX_SCMI_REG11] = VOLTD_STM32_PWR_ELT_ID(STM32_PWR_REG11), +- [VOLTD_IDX_SCMI_REG18] = VOLTD_STM32_PWR_ELT_ID(STM32_PWR_REG18), +- [VOLTD_IDX_SCMI_USB33] = VOLTD_STM32_PWR_ELT_ID(STM32_PWR_USB33), +- [VOLTD_IDX_SCMI_STPMIC1_BUCK1] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK1), +- [VOLTD_IDX_SCMI_STPMIC1_BUCK2] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK2), +- [VOLTD_IDX_SCMI_STPMIC1_BUCK3] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK3), +- [VOLTD_IDX_SCMI_STPMIC1_BUCK4] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BUCK4), +- [VOLTD_IDX_SCMI_STPMIC1_LDO1] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO1), +- [VOLTD_IDX_SCMI_STPMIC1_LDO2] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO2), +- [VOLTD_IDX_SCMI_STPMIC1_LDO3] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO3), +- [VOLTD_IDX_SCMI_STPMIC1_LDO4] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO4), +- [VOLTD_IDX_SCMI_STPMIC1_LDO5] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO5), +- [VOLTD_IDX_SCMI_STPMIC1_LDO6] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_LDO6), +- [VOLTD_IDX_SCMI_STPMIC1_VREFDDR] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_VREFDDR), +- [VOLTD_IDX_SCMI_STPMIC1_BOOST] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_BOOST), +- [VOLTD_IDX_SCMI_STPMIC1_PWR_SW1] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_PWR_SW1), +- [VOLTD_IDX_SCMI_STPMIC1_PWR_SW2] = VOLTD_STM32_PMIC_ELT_ID(STPMIC1_REGU_PWR_SW2), +- [VOLTD_IDX_COUNT] = { 0 } /* Termination entry */ +-}; +- +-/* Exported configuration data for module VOLTAGE_DOMAIN */ +-const struct fwk_module_config config_voltage_domain = { +- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(voltd_elt), +-}; +- +-/* +- * STM32 PWR driver configuration +- */ +-#define STM32_PWR_ELT(_dev_idx) \ +- [(_dev_idx)] = { \ +- .name = stm32_pwr_cfg[(_dev_idx)].regu_name, \ +- .data = &stm32_pwr_cfg[(_dev_idx)], \ +- } +- +-static const struct fwk_element stm32_pwr_elt[] = { +- STM32_PWR_ELT(STM32_PWR_REG11), +- STM32_PWR_ELT(STM32_PWR_REG18), +- STM32_PWR_ELT(STM32_PWR_USB33), +- { 0 } /* Termination entry */ +-}; +- +-/* Exported configuration data for module STM32_PWR_REGU */ +-const struct fwk_module_config config_stm32_pwr_regu = { +- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(stm32_pwr_elt), +-}; +- +-/* +- * STM32 PMIC regulator driver configuration +- */ +-#define STM32_PMIC_ELT(_dev_idx) \ +- [(_dev_idx)] = { \ +- .name = stm32_pmic_cfg[(_dev_idx)].regu_name, \ +- .data = &stm32_pmic_cfg[(_dev_idx)], \ +- } +- +-static const struct fwk_element stm32_pmic_elt[] = { +- STM32_PMIC_ELT(STPMIC1_REGU_BUCK1), +- STM32_PMIC_ELT(STPMIC1_REGU_BUCK2), +- STM32_PMIC_ELT(STPMIC1_REGU_BUCK3), +- STM32_PMIC_ELT(STPMIC1_REGU_BUCK4), +- STM32_PMIC_ELT(STPMIC1_REGU_LDO1), +- STM32_PMIC_ELT(STPMIC1_REGU_LDO2), +- STM32_PMIC_ELT(STPMIC1_REGU_LDO3), +- STM32_PMIC_ELT(STPMIC1_REGU_LDO4), +- STM32_PMIC_ELT(STPMIC1_REGU_LDO5), +- STM32_PMIC_ELT(STPMIC1_REGU_LDO6), +- STM32_PMIC_ELT(STPMIC1_REGU_VREFDDR), +- STM32_PMIC_ELT(STPMIC1_REGU_BOOST), +- STM32_PMIC_ELT(STPMIC1_REGU_PWR_SW1), +- STM32_PMIC_ELT(STPMIC1_REGU_PWR_SW2), +- { 0 } /* Termination entry */ +-}; +- +-/* Exported configuration data for module STM32_PMIC_REGU */ +-const struct fwk_module_config config_stm32_pmic_regu = { +- .elements = FWK_MODULE_STATIC_ELEMENTS_PTR(stm32_pmic_elt), +-}; +diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/CMakeLists.txt b/product/optee-stm32mp1/module/psu_optee_regulator/CMakeLists.txt +similarity index 80% +rename from product/optee-stm32mp1/module/stm32_pwr_regu/CMakeLists.txt +rename to product/optee-stm32mp1/module/psu_optee_regulator/CMakeLists.txt +index 7471acc6..77af63f2 100644 +--- a/product/optee-stm32mp1/module/stm32_pwr_regu/CMakeLists.txt ++++ b/product/optee-stm32mp1/module/psu_optee_regulator/CMakeLists.txt +@@ -1,6 +1,6 @@ + # + # Arm SCP/MCP Software +-# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -9,9 +9,9 @@ add_library(${SCP_MODULE_TARGET} SCP_MODULE) + + target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" +- "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp1") ++ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") + + target_sources( +- ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_pwr_regu.c") ++ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_psu_optee_regulator.c") + + target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) +diff --git a/product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake b/product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake +new file mode 100644 +index 00000000..26dc706e +--- /dev/null ++++ b/product/optee-stm32mp1/module/psu_optee_regulator/Module.cmake +@@ -0,0 +1,9 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++set(SCP_MODULE "psu-optee-regulator") ++set(SCP_MODULE_TARGET "psu-optee-regulator") +diff --git a/product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h b/product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h +new file mode 100644 +index 00000000..789c9591 +--- /dev/null ++++ b/product/optee-stm32mp1/module/psu_optee_regulator/include/mod_psu_optee_regulator.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2023, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef MOD_PSU_OPTEE_REGULATOR_H ++#define MOD_PSU_OPTEE_REGULATOR_H ++ ++#include ++#include ++#include ++#include ++ ++struct rdev; ++ ++/*! ++ * \brief Platform regulator configuration. ++ */ ++struct mod_psu_optee_regulator_dev_config { ++ struct rdev *rdev; ++}; ++ ++#endif /* MOD_PSU_OPTEE_REGULATOR_H */ +diff --git a/product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c b/product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c +new file mode 100644 +index 00000000..73a82b45 +--- /dev/null ++++ b/product/optee-stm32mp1/module/psu_optee_regulator/src/mod_psu_optee_regulator.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2022, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define DEBUG_MSG(...) FMSG(__VA_ARGS__) ++ ++/* Module context */ ++struct psu_optee_regulator_ctx { ++ struct mod_psu_optee_regulator_dev_config *config; ++ unsigned int dev_count; ++}; ++ ++/* A single instance handles all voltage regulators abstracted by regulator.h */ ++static struct psu_optee_regulator_ctx module_ctx; ++ ++static char __maybe_unused *regulator_name(struct rdev *rdev) ++{ ++ if (rdev) ++ return (char *)rdev->reg_name; ++ ++ return NULL; ++} ++ ++static struct rdev *get_regulator(fwk_id_t id) ++{ ++ unsigned int elt_index; ++ ++ elt_index = fwk_id_get_element_idx(id); ++ if (elt_index >= module_ctx.dev_count) ++ return NULL; ++ ++ return module_ctx.config[elt_index].rdev; ++} ++ ++/* ++ * Driver functions for the PSU API ++ */ ++static int psu_optee_regulator_set_enabled(fwk_id_t id, bool enabled) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct rdev *regulator; ++ ++ regulator = get_regulator(id); ++ if (!regulator) { ++ return FWK_E_PARAM; ++ } ++ ++ DEBUG_MSG("PSU set %s %s", regulator_name(regulator), ++ enabled ? "ON" : "OFF"); ++ ++ if (enabled) { ++ res = regulator_enable(regulator); ++ } else { ++ res = regulator_disable(regulator); ++ } ++ ++ if (res) { ++ return FWK_E_HANDLER; ++ } else { ++ return FWK_SUCCESS; ++ } ++} ++ ++static int psu_optee_regulator_get_enabled(fwk_id_t id, bool *enabled) ++{ ++ struct rdev *regulator; ++ ++ regulator = get_regulator(id); ++ if (!regulator || (enabled == NULL)) { ++ return FWK_E_PARAM; ++ } ++ ++ *enabled = regulator_is_enabled((const struct rdev *)regulator); ++ DEBUG_MSG("PSU get %s state: %s", regulator_name(regulator), ++ enabled ? "ON" : "OFF"); ++ ++ return FWK_SUCCESS; ++} ++ ++static int psu_optee_regulator_set_voltage(fwk_id_t id, uint32_t voltage) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct rdev *regulator; ++ uint16_t level_mv = voltage; ++ ++ regulator = get_regulator(id); ++ if (!regulator) { ++ return FWK_E_PARAM; ++ } ++ ++ DEBUG_MSG("PSU set regulator %s level: %"PRIu32"mV", ++ regulator_name(regulator), (uint32_t)level_mv); ++ ++ res = regulator_set_voltage(regulator, level_mv); ++ ++ if (res) { ++ return FWK_E_HANDLER; ++ } else { ++ ++ return FWK_SUCCESS; ++ } ++} ++ ++static int psu_optee_regulator_get_voltage(fwk_id_t id, uint32_t *voltage) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct rdev *regulator; ++ uint16_t level_mv; ++ ++ regulator = get_regulator(id); ++ if (!regulator || (voltage == NULL)) { ++ return FWK_E_PARAM; ++ } ++ ++ res = regulator_get_voltage(regulator, &level_mv); ++ ++ DEBUG_MSG("PSU get regulator %s level: %"PRIu32"mV (res %#"PRIx32")", ++ regulator_name(regulator), (uint32_t)level_mv, res); ++ ++ if (res) { ++ return FWK_E_HANDLER; ++ } ++ ++ *voltage = level_mv; ++ ++ return FWK_SUCCESS; ++} ++ ++static struct mod_psu_driver_api psu_driver_api = { ++ .set_enabled = psu_optee_regulator_set_enabled, ++ .get_enabled = psu_optee_regulator_get_enabled, ++ .set_voltage = psu_optee_regulator_set_voltage, ++ .get_voltage = psu_optee_regulator_get_voltage, ++}; ++ ++static int psu_optee_regulator_init(fwk_id_t module_id, ++ unsigned int element_count, ++ const void *data) ++{ ++ return FWK_SUCCESS; ++} ++ ++static int psu_optee_regulator_element_init(fwk_id_t element_id, ++ unsigned int sub_element_count, ++ const void *data) ++{ ++ fwk_assert(data != NULL); ++ ++ module_ctx.config = (struct mod_psu_optee_regulator_dev_config *)data; ++ module_ctx.dev_count = sub_element_count; ++ ++ return FWK_SUCCESS; ++} ++ ++static int psu_optee_regulator_process_bind_request(fwk_id_t source_id, ++ fwk_id_t target_id, ++ fwk_id_t api_id, ++ const void **api) ++{ ++ *api = &psu_driver_api; ++ ++ return FWK_SUCCESS; ++} ++ ++const struct fwk_module module_psu_optee_regulator = { ++ .api_count = 1, ++ .type = FWK_MODULE_TYPE_DRIVER, ++ .init = psu_optee_regulator_init, ++ .element_init = psu_optee_regulator_element_init, ++ .process_bind_request = psu_optee_regulator_process_bind_request, ++}; +diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake b/product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake +deleted file mode 100644 +index 51bfae5b..00000000 +--- a/product/optee-stm32mp1/module/stm32_pmic_regu/Module.cmake ++++ /dev/null +@@ -1,9 +0,0 @@ +-# +-# Arm SCP/MCP Software +-# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +-# +-# SPDX-License-Identifier: BSD-3-Clause +-# +- +-set(SCP_MODULE "stm32-pmic-regu") +-set(SCP_MODULE_TARGET "module-stm32-pmic-regu") +diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h b/product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h +deleted file mode 100644 +index 120f1351..00000000 +--- a/product/optee-stm32mp1/module/stm32_pmic_regu/include/mod_stm32_pmic_regu.h ++++ /dev/null +@@ -1,24 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ +- +-#ifndef MOD_STPMIC1_REGU_H +-#define MOD_STPMIC1_REGU_H +- +-#include +-#include +- +-#include +- +-/*! +- * \brief Platform regulator configuration. +- */ +-struct mod_stm32_pmic_regu_dev_config { +- const char *regu_name; +- bool read_only; +-}; +- +-#endif /* MOD_STPMIC1_REGU_H */ +diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c b/product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c +deleted file mode 100644 +index b22702b6..00000000 +--- a/product/optee-stm32mp1/module/stm32_pmic_regu/src/mod_stm32_pmic_regu.c ++++ /dev/null +@@ -1,367 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights +- * reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- * +- * Description: +- * Interface SCP-firmare VOLTD instances with OP-TEE stm32mp1 +- * PMIC regulator driver for voltage regulator controller from +- * an external PMIC access with a I2C bus using OP-TEE resources. +- * +- * The OP-TEE drvier is accessed by API function named like +- * stpmic1_regulator_*(). They execute in a threaded interruptible, +- * and rescheduable context. +- */ +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +- +-#include +-#include +-#include +- +-#define MOD_NAME "[STM32 PMIC] " +- +-/* Device context */ +-struct stm32_pmic_regu_dev_ctx { +- const char *regu_id; /* Both name and backend regu ID */ +- bool read_only; +-}; +- +-/* Module context */ +-struct stm32_pmic_regu_ctx { +- struct stm32_pmic_regu_dev_ctx *dev_ctx_table; +- unsigned int dev_count; +-}; +- +-static struct stm32_pmic_regu_ctx module_ctx; +- +-static int32_t get_regu_voltage(const char *regu_id) +-{ +- unsigned long level_uv = 0; +- +- stm32mp_get_pmic(); +- level_uv = stpmic1_regulator_voltage_get(regu_id) * 1000; +- stm32mp_put_pmic(); +- +- return (int32_t)level_uv; +-} +- +-static int32_t set_regu_voltage(const char *regu_id, int32_t level_uv) +-{ +- int rc = 0; +- unsigned int level_mv = level_uv / 1000; +- +- FWK_LOG_DEBUG( +- MOD_NAME "Set STPMIC1 regulator %s level to %dmV", +- regu_id, +- level_uv / 1000); +- +- fwk_assert(level_mv < UINT16_MAX); +- +- stm32mp_get_pmic(); +- rc = stpmic1_regulator_voltage_set(regu_id, level_mv); +- stm32mp_put_pmic(); +- +- return rc ? SCMI_GENERIC_ERROR : SCMI_SUCCESS; +-} +- +-static bool regu_is_enable(const char *regu_id) +-{ +- bool rc = false; +- +- stm32mp_get_pmic(); +- rc = stpmic1_is_regulator_enabled(regu_id); +- stm32mp_put_pmic(); +- +- return rc; +-} +- +-static int32_t set_regu_state(const char *regu_id, bool enable) +-{ +- int rc = 0; +- +- stm32mp_get_pmic(); +- +- FWK_LOG_DEBUG( +- MOD_NAME "%sable STPMIC1 %s (was %s)", +- enable ? "En" : "Dis", +- regu_id, +- stpmic1_is_regulator_enabled(regu_id) ? "on" : "off"); +- +- if (enable) { +- rc = stpmic1_regulator_enable(regu_id); +- } else { +- rc = stpmic1_regulator_disable(regu_id); +- } +- +- stm32mp_put_pmic(); +- +- return rc ? SCMI_GENERIC_ERROR : SCMI_SUCCESS; +-} +- +-/* +- * Voltage domain driver API functions +- */ +-static int pmic_regu_get_config(fwk_id_t dev_id, uint8_t *mode_type, +- uint8_t *mode_id) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx; +- +- if (!fwk_module_is_valid_element_id(dev_id) || +- mode_id == NULL || mode_type == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; +- +- if (regu_is_enable(ctx->regu_id)) { +- *mode_id = MOD_VOLTD_MODE_ID_ON; +- } else { +- *mode_id = MOD_VOLTD_MODE_ID_OFF; +- } +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get config PMIC %s: %s", +- fwk_id_get_element_idx(dev_id), +- ctx->regu_id, +- *mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); +- +- return FWK_SUCCESS; +-} +- +-static int pmic_regu_set_config(fwk_id_t dev_id, uint8_t mode_type, +- uint8_t mode_id) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id) || +- mode_type != MOD_VOLTD_MODE_TYPE_ARCH || +- (mode_id == MOD_VOLTD_MODE_ID_ON && mode_id == MOD_VOLTD_MODE_ID_OFF)) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (ctx->read_only) { +- return FWK_E_ACCESS; +- } +- +- if (set_regu_state(ctx->regu_id, mode_id == MOD_VOLTD_MODE_ID_ON)) { +- return FWK_E_DEVICE; +- } +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: set config PMIC %s to %s", +- fwk_id_get_element_idx(dev_id), +- ctx->regu_id, +- mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); +- +- return FWK_SUCCESS; +-} +- +-static int pmic_regu_get_level(fwk_id_t dev_id, int *level_uv) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- *level_uv = get_regu_voltage(ctx->regu_id); +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get level PMIC %s = %d", +- fwk_id_get_element_idx(dev_id), +- ctx->regu_id, +- *level_uv); +- +- return FWK_SUCCESS; +-} +- +-static int pmic_regu_set_level(fwk_id_t dev_id, int level_uv) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id)) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (ctx->read_only) { +- return FWK_E_ACCESS; +- } +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: set level PMIC %s to %d", +- fwk_id_get_element_idx(dev_id), +- ctx->regu_id, +- level_uv); +- +- if (set_regu_voltage(ctx->regu_id, level_uv)) { +- return FWK_E_DEVICE; +- } +- +- return FWK_SUCCESS; +-} +- +-static void find_bound_uv(const uint16_t *levels, size_t count, +- int32_t *min, int32_t *max) +-{ +- size_t n = 0; +- +- fwk_assert((count == 0 || levels != NULL) && min != NULL && max != NULL); +- +- *min = INT32_MAX; +- *max = INT32_MIN; +- +- for (n = 0; n < count; n++) { +- if (*min > levels[n]) { +- *min = levels[n]; +- } +- if (*max < levels[n]) { +- *max = levels[n]; +- } +- } +- +- /* Convert from mV to uV */ +- *min *= 1000; +- *max *= 1000; +-} +- +-static int pmic_regu_get_info(fwk_id_t dev_id, struct mod_voltd_info *info) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx = NULL; +- const uint16_t *levels = NULL; +- size_t full_count = 0; +- +- if (!fwk_module_is_valid_element_id(dev_id) || info == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- stpmic1_regulator_levels_mv(ctx->regu_id, &levels, &full_count); +- +- memset(info, 0, sizeof(*info)); +- info->name = ctx->regu_id; +- info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; +- info->level_range.level_count = full_count; +- find_bound_uv(levels, full_count, +- &info->level_range.min_uv, &info->level_range.max_uv); +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get_info PMIC %s, range [%d %d]", +- fwk_id_get_element_idx(dev_id), +- ctx->regu_id, +- info->level_range.min_uv, +- info->level_range.max_uv); +- +- return FWK_SUCCESS; +-} +- +-static int pmic_regu_level_from_index(fwk_id_t dev_id, unsigned int index, +- int32_t *level_uv) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx = NULL; +- const uint16_t *levels = NULL; +- size_t full_count = 0; +- +- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- stpmic1_regulator_levels_mv(ctx->regu_id, &levels, &full_count); +- if (index >= full_count) { +- return FWK_E_RANGE; +- } +- +- *level_uv = (int32_t)levels[index] * 1000; +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get level PMIC %s = %d", +- fwk_id_get_element_idx(dev_id), +- ctx->regu_id, +- *level_uv); +- +- return FWK_SUCCESS; +-} +- +-static const struct mod_voltd_drv_api api_stm32_pmic_regu = { +- .get_config = pmic_regu_get_config, +- .set_config = pmic_regu_set_config, +- .get_level = pmic_regu_get_level, +- .set_level = pmic_regu_set_level, +- .get_info = pmic_regu_get_info, +- .get_level_from_index = pmic_regu_level_from_index, +-}; +- +-/* +- * Framework handler functions +- */ +- +-static int stm32_pmic_regu_init(fwk_id_t module_id, unsigned int element_count, +- const void *data) +-{ +- module_ctx.dev_count = element_count; +- +- if (element_count) { +- module_ctx.dev_ctx_table = +- fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); +- } +- +- return FWK_SUCCESS; +-} +- +-static int stm32_pmic_regu_element_init(fwk_id_t element_id, +- unsigned int unused, +- const void *data) +-{ +- struct stm32_pmic_regu_dev_ctx *ctx = NULL; +- const struct mod_stm32_pmic_regu_dev_config *dev_config = data; +- +- if (!fwk_module_is_valid_element_id(element_id)) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); +- +- ctx->regu_id = dev_config->regu_name; +- ctx->read_only = dev_config->read_only; +- +- return FWK_SUCCESS; +-} +- +-static int stm32_pmic_regu_process_bind_request(fwk_id_t requester_id, +- fwk_id_t target_id, +- fwk_id_t api_type, +- const void **api) +-{ +- *api = &api_stm32_pmic_regu; +- +- return FWK_SUCCESS; +-} +- +-const struct fwk_module module_stm32_pmic_regu = { +- .type = FWK_MODULE_TYPE_DRIVER, +- .api_count = 1, +- .init = stm32_pmic_regu_init, +- .element_init = stm32_pmic_regu_element_init, +- .process_bind_request = stm32_pmic_regu_process_bind_request, +-}; +diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake b/product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake +deleted file mode 100644 +index b8c5be8d..00000000 +--- a/product/optee-stm32mp1/module/stm32_pwr_regu/Module.cmake ++++ /dev/null +@@ -1,9 +0,0 @@ +-# +-# Arm SCP/MCP Software +-# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +-# +-# SPDX-License-Identifier: BSD-3-Clause +-# +- +-set(SCP_MODULE "stm32-pwr-regu") +-set(SCP_MODULE_TARGET "module-stm32-pwr-regu") +diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h b/product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h +deleted file mode 100644 +index 567ab18e..00000000 +--- a/product/optee-stm32mp1/module/stm32_pwr_regu/include/mod_stm32_pwr_regu.h ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- */ +- +-#ifndef MOD_STM32_PWR_REGU_H +-#define MOD_STM32_PWR_REGU_H +- +-/*! +- * \brief Platform clocks configuration. +- */ +-struct mod_stm32_pwr_regu_dev_config { +- unsigned long pwr_id; +- const char *regu_name; +-}; +- +-#endif /* MOD_STM32_PWR_REGU_H */ +diff --git a/product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c b/product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c +deleted file mode 100644 +index 65c02f43..00000000 +--- a/product/optee-stm32mp1/module/stm32_pwr_regu/src/mod_stm32_pwr_regu.c ++++ /dev/null +@@ -1,293 +0,0 @@ +-/* +- * Arm SCP/MCP Software +- * Copyright (c) 2022-2023, Linaro Limited and Contributors. All rights +- * reserved. +- * +- * SPDX-License-Identifier: BSD-3-Clause +- * +- * Description: +- * Interface SCP-firmare VOLTD instances with OP-TEE stm32mp1 +- * PWR regulator driver for SoC voltage regulator controller by +- * OP-TEE for this platform. +- * +- * The OP-TEE drvier is accessed by API function named +- * stm32mp1_regultor_*(). They execute in a threaded interruptible, +- * and rescheduable context. +- */ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +- +-#define MOD_NAME "[STM32 PWR] " +- +-/* Device context */ +-struct stm32_pwr_regu_dev_ctx { +- enum pwr_regulator pwr_id; +- const char *name; +-}; +- +-/* Module context */ +-struct stm32_pwr_regu_ctx { +- struct stm32_pwr_regu_dev_ctx *dev_ctx_table; +- unsigned int dev_count; +-}; +- +-static struct stm32_pwr_regu_ctx module_ctx; +- +-static bool nsec_can_access_pwr_regu(enum pwr_regulator pwr_id) +-{ +- /* Currently allow non-secure world to access all PWR regulators */ +- return true; +-} +- +-static int32_t pwr_regu_level(enum pwr_regulator pwr_id) +-{ +- return (int32_t)stm32mp1_pwr_regulator_mv(pwr_id) * 1000; +-} +- +-/* +- * Voltage domain driver API functions +- */ +-static int pwr_regu_get_config(fwk_id_t dev_id, uint8_t *mode_type, +- uint8_t *mode_id) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx; +- +- if (!fwk_module_is_valid_element_id(dev_id) || +- mode_type == NULL || mode_id == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { +- return FWK_E_ACCESS; +- } +- +- *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; +- +- if (stm32mp1_pwr_regulator_is_enabled(ctx->pwr_id)) { +- *mode_id = MOD_VOLTD_MODE_ID_ON; +- } else { +- *mode_id = MOD_VOLTD_MODE_ID_OFF; +- } +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get_config PWR#%u = %s", +- fwk_id_get_element_idx(dev_id), +- ctx->pwr_id, +- *mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); +- +- return FWK_SUCCESS; +-} +- +-static int pwr_regu_set_config(fwk_id_t dev_id, uint8_t mode_type, +- uint8_t mode_id) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id) || +- mode_type != MOD_VOLTD_MODE_TYPE_ARCH || +- (mode_id == MOD_VOLTD_MODE_ID_ON && mode_id == MOD_VOLTD_MODE_ID_OFF)) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { +- return FWK_E_ACCESS; +- } +- +- stm32mp1_pwr_regulator_set_state(ctx->pwr_id, +- mode_id == MOD_VOLTD_MODE_ID_ON); +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: set_config PWR#%u %s", +- fwk_id_get_element_idx(dev_id), +- ctx->pwr_id, +- mode_id == MOD_VOLTD_MODE_ID_ON ? "on" : "off"); +- +- return FWK_SUCCESS; +-} +- +-static int pwr_regu_get_level(fwk_id_t dev_id, int *level_uv) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { +- return FWK_E_ACCESS; +- } +- +- *level_uv = pwr_regu_level(ctx->pwr_id); +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get_level PWR#%u = %d", +- fwk_id_get_element_idx(dev_id), +- ctx->pwr_id, +- *level_uv); +- +- return FWK_SUCCESS; +-} +- +-static int pwr_regu_set_level(fwk_id_t dev_id, int level_uv) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id)) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { +- return FWK_E_ACCESS; +- } +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: set_level PWR#%u to %d", +- fwk_id_get_element_idx(dev_id), +- ctx->pwr_id, +- level_uv); +- +- if (level_uv != pwr_regu_level(ctx->pwr_id)) { +- return FWK_E_RANGE; +- } +- +- return FWK_SUCCESS; +-} +- +-static int pwr_regu_get_info(fwk_id_t dev_id, struct mod_voltd_info *info) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id) || info == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { +- return FWK_E_ACCESS; +- } +- +- memset(info, 0, sizeof(*info)); +- info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; +- info->level_range.min_uv = pwr_regu_level(ctx->pwr_id); +- info->level_range.max_uv = info->level_range.min_uv; +- info->level_range.level_count = 1; +- info->name = ctx->name; +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get_info PWR#%u", +- fwk_id_get_element_idx(dev_id), +- ctx->pwr_id); +- +- return FWK_SUCCESS; +-} +- +-static int pwr_regu_level_from_index(fwk_id_t dev_id, unsigned int index, +- int32_t *level_uv) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx = NULL; +- +- if (!fwk_module_is_valid_element_id(dev_id) || level_uv == NULL) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); +- +- if (!nsec_can_access_pwr_regu(ctx->pwr_id)) { +- return FWK_E_ACCESS; +- } +- +- if (index > 0) { +- return FWK_E_RANGE; +- } +- +- *level_uv = pwr_regu_level(ctx->pwr_id); +- +- FWK_LOG_DEBUG( +- MOD_NAME "SCMI voltd %u: get_level_from_index PWR#%u = %" PRId32, +- fwk_id_get_element_idx(dev_id), +- ctx->pwr_id, +- *level_uv); +- +- return FWK_SUCCESS; +-} +- +-static const struct mod_voltd_drv_api api_stm32_pwr_regu = { +- .get_config = pwr_regu_get_config, +- .set_config = pwr_regu_set_config, +- .get_level = pwr_regu_get_level, +- .set_level = pwr_regu_set_level, +- .get_info = pwr_regu_get_info, +- .get_level_from_index = pwr_regu_level_from_index, +-}; +- +-/* +- * Framework handler functions +- */ +- +-static int stm32_pwr_regu_init(fwk_id_t module_id, unsigned int element_count, +- const void *data) +-{ +- module_ctx.dev_count = element_count; +- +- if (element_count) { +- module_ctx.dev_ctx_table = +- fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); +- } +- +- return FWK_SUCCESS; +-} +- +-static int stm32_pwr_regu_element_init(fwk_id_t element_id, +- unsigned int unused, +- const void *data) +-{ +- struct stm32_pwr_regu_dev_ctx *ctx = NULL; +- const struct mod_stm32_pwr_regu_dev_config *dev_config = data; +- +- if (!fwk_module_is_valid_element_id(element_id)) { +- return FWK_E_PARAM; +- } +- +- ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); +- +- ctx->pwr_id = dev_config->pwr_id; +- ctx->name = dev_config->regu_name; +- +- return FWK_SUCCESS; +-} +- +-static int stm32_pwr_regu_process_bind_request(fwk_id_t requester_id, +- fwk_id_t target_id, +- fwk_id_t api_type, +- const void **api) +-{ +- *api = &api_stm32_pwr_regu; +- +- return FWK_SUCCESS; +-} +- +-const struct fwk_module module_stm32_pwr_regu = { +- .type = FWK_MODULE_TYPE_DRIVER, +- .api_count = 1, +- .init = stm32_pwr_regu_init, +- .element_init = stm32_pwr_regu_element_init, +- .process_bind_request = stm32_pwr_regu_process_bind_request, +-}; +diff --git a/product/optee-stm32mp1/module/stm32_pmic_regu/CMakeLists.txt b/product/optee-stm32mp1/module/stm32_regu_consumer/CMakeLists.txt +similarity index 64% +rename from product/optee-stm32mp1/module/stm32_pmic_regu/CMakeLists.txt +rename to product/optee-stm32mp1/module/stm32_regu_consumer/CMakeLists.txt +index e93bb764..adf79cfc 100644 +--- a/product/optee-stm32mp1/module/stm32_pmic_regu/CMakeLists.txt ++++ b/product/optee-stm32mp1/module/stm32_regu_consumer/CMakeLists.txt +@@ -1,6 +1,6 @@ + # + # Arm SCP/MCP Software +-# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. + # + # SPDX-License-Identifier: BSD-3-Clause + # +@@ -9,10 +9,9 @@ add_library(${SCP_MODULE_TARGET} SCP_MODULE) + + target_include_directories(${SCP_MODULE_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" +- "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp1") ++ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") + + target_sources( +- ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_pmic_regu.c") ++ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_regu_consumer.c") + +-target_link_libraries(${SCP_MODULE_TARGET} +- PUBLIC module-scmi module-voltage-domain) ++target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) +diff --git a/product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake b/product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake +new file mode 100644 +index 00000000..dc988ed3 +--- /dev/null ++++ b/product/optee-stm32mp1/module/stm32_regu_consumer/Module.cmake +@@ -0,0 +1,9 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++set(SCP_MODULE "stm32-regu-consumer") ++set(SCP_MODULE_TARGET "module-stm32-regu-consumer") +diff --git a/product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h b/product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h +new file mode 100644 +index 00000000..6671eab3 +--- /dev/null ++++ b/product/optee-stm32mp1/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2022, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef MOD_STM32_REGU_CONSUMER_H ++#define MOD_STM32_REGU_CONSUMER_H ++ ++#include ++#include ++#include ++#include ++ ++struct scmi_server_regu_channel; ++struct rdev; ++ ++/*! ++ * \brief Platform regulator configuration. ++ */ ++struct mod_stm32_regu_consumer_dev_config { ++ struct rdev *rdev; ++ bool default_enabled; ++}; ++ ++/* ++ * Build SCMI server resource tables for the voltage domains exposed ++ * by platform. ++ * ++ * @plat - reference to platform data ++ * @plat_count - Number of elements in platform data ++ */ ++void scmi_server_build_optee_regu_config(struct scmi_server_regu_channel *plat, ++ size_t plat_count); ++ ++#endif /* MOD_STM32_REGU_CONSUMER_H */ +diff --git a/product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c b/product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c +new file mode 100644 +index 00000000..76955728 +--- /dev/null ++++ b/product/optee-stm32mp1/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c +@@ -0,0 +1,343 @@ ++/* ++ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2022, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define DEBUG_MSG(...) FMSG(__VA_ARGS__) ++ ++/* Device context */ ++struct stm32_regu_consumer_dev_ctx { ++ struct rdev *rdev; ++ bool enabled; ++}; ++ ++/* Module context */ ++struct stm32_regu_consumer_ctx { ++ struct stm32_regu_consumer_dev_ctx *dev_ctx_table; ++ unsigned int dev_count; ++}; ++ ++/* A single instance handles all voltage regulators abstracted by regulator.h */ ++static struct stm32_regu_consumer_ctx module_ctx; ++ ++static char *regu_name(struct rdev *rdev) ++{ ++ if (rdev) ++ return (char *)rdev->reg_name; ++ ++ return NULL; ++} ++ ++static int find_ctx(fwk_id_t dev_id, ++ struct stm32_regu_consumer_dev_ctx **out_ctx) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ ++ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); ++ ++ if (!fwk_module_is_valid_element_id(dev_id)) ++ return FWK_E_PARAM; ++ ++ if (!ctx->rdev) ++ return FWK_E_ACCESS; ++ ++ *out_ctx = ctx; ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_get_config(fwk_id_t dev_id, uint8_t *mode_type, ++ uint8_t *mode_id) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; ++ ++ if (ctx->enabled) ++ *mode_id = MOD_VOLTD_MODE_ID_ON; ++ else ++ *mode_id = MOD_VOLTD_MODE_ID_OFF; ++ ++ DEBUG_MSG("SCMI voltd %u: get config PMIC %s = %#"PRIx8", %#"PRIx8, ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *mode_type, ++ *mode_id); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_set_config(fwk_id_t dev_id, uint8_t mode_type, ++ uint8_t mode_id) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ if (mode_type != MOD_VOLTD_MODE_TYPE_ARCH) { ++ return FWK_E_PARAM; ++ } ++ ++ switch (mode_id) { ++ case MOD_VOLTD_MODE_ID_ON: ++ if (!ctx->enabled) { ++ if (regulator_enable(ctx->rdev)) ++ return FWK_E_DEVICE; ++ ++ ctx->enabled = true; ++ } ++ break; ++ ++ case MOD_VOLTD_MODE_ID_OFF: ++ if (ctx->enabled) { ++ if (regulator_disable(ctx->rdev)) ++ return FWK_E_DEVICE; ++ ++ ctx->enabled = false; ++ } ++ break; ++ ++ default: ++ return FWK_E_PARAM; ++ } ++ ++ DEBUG_MSG("SCMI voltd %u: set config PMIC %s to type %#"PRIx8" / mode %#"PRIx8, ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), mode_type, ++ mode_id); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_get_level(fwk_id_t dev_id, int *level_uv) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ uint16_t level_mv; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ if (regulator_get_voltage(ctx->rdev, &level_mv)) ++ return FWK_E_PANIC; ++ ++ *level_uv = (int)level_mv * 1000; ++ ++ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %d", ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_set_level(fwk_id_t dev_id, int level_uv) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx = NULL; ++ int ret = FWK_E_PANIC; ++ ++ if (level_uv / 1000 > UINT16_MAX) { ++ FWK_LOG_ERR("Volatge level too high (mV shall fit in 16 bits)"); ++ return FWK_E_PARAM; ++ } ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ if (regulator_set_voltage(ctx->rdev, level_uv / 1000)) ++ return FWK_E_DEVICE; ++ ++ DEBUG_MSG("SCMI voltd %u: set level PMIC %s to %d", ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), level_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static void find_bound_uv(const uint16_t *levels, size_t count, ++ int32_t *min, int32_t *max) ++{ ++ size_t n = 0; ++ ++ *min = INT32_MAX; ++ *max = INT32_MIN; ++ ++ for (n = 0; n < count; n++) { ++ if (*min > levels[n]) ++ *min = levels[n]; ++ if (*max < levels[n]) ++ *max = levels[n]; ++ } ++ ++ /* Convert from mV to uV */ ++ *min *= 1000; ++ *max *= 1000; ++} ++ ++static int stm32_regu_consumer_get_info(fwk_id_t dev_id, ++ struct mod_voltd_info *info) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ uint16_t *levels; ++ size_t full_count; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret == FWK_E_ACCESS) { ++ static const char reserved[] = "reserved"; ++ ++ memset(info, 0, sizeof(*info)); ++ info->name = reserved; ++ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; ++ info->level_range.level_count = 1; ++ info->level_range.min_uv = 0; ++ info->level_range.max_uv = 0; ++ ++ return FWK_SUCCESS; ++ } else if (ret != FWK_SUCCESS) { ++ return ret; ++ } ++ ++ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { ++ return FWK_E_SUPPORT; ++ } ++ ++ memset(info, 0, sizeof(*info)); ++ info->name = regu_name(ctx->rdev); ++ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; ++ info->level_range.level_count = full_count; ++ find_bound_uv(levels, full_count, ++ &info->level_range.min_uv, &info->level_range.max_uv); ++ ++ DEBUG_MSG("SCMI voltd %u: get_info PMIC %s, range [%d %d]", ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), ++ info->level_range.min_uv, info->level_range.max_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_level_from_index(fwk_id_t dev_id, ++ unsigned int index, ++ int32_t *level_uv) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ uint16_t *levels; ++ size_t full_count; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret == FWK_E_ACCESS) { ++ if (index > 0) { ++ return FWK_E_RANGE; ++ } ++ *level_uv = 0; ++ ++ return FWK_SUCCESS; ++ } else if (ret != FWK_SUCCESS) { ++ return ret; ++ } ++ ++ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { ++ return FWK_E_SUPPORT; ++ } ++ ++ if (index >= full_count) ++ return FWK_E_RANGE; ++ ++ *level_uv = (int32_t)levels[index] * 1000; ++ ++ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %"PRId32, ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static const struct mod_voltd_drv_api api_optee_regu = { ++ .get_level = stm32_regu_consumer_get_level, ++ .set_level = stm32_regu_consumer_set_level, ++ .set_config = stm32_regu_consumer_set_config, ++ .get_config = stm32_regu_consumer_get_config, ++ .get_info = stm32_regu_consumer_get_info, ++ .get_level_from_index = stm32_regu_consumer_level_from_index, ++}; ++ ++/* ++ * Framework handler functions ++ */ ++ ++static int stm32_regu_consumer_init(fwk_id_t module_id, ++ unsigned int element_count, ++ const void *data) ++{ ++ module_ctx.dev_count = element_count; ++ ++ if (element_count) ++ module_ctx.dev_ctx_table = ++ fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_element_init(fwk_id_t element_id, ++ unsigned int unused, ++ const void *data) ++{ ++ const struct mod_stm32_regu_consumer_dev_config *dev_config = data; ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ ++ if (!fwk_module_is_valid_element_id(element_id)) ++ return FWK_E_PANIC; ++ ++ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); ++ ++ ctx->rdev = dev_config->rdev; ++ ctx->enabled = dev_config->default_enabled; ++ ++ if (ctx->enabled) { ++ if (!ctx->rdev) ++ return FWK_E_PARAM; ++ if (regulator_enable(ctx->rdev)) ++ return FWK_E_DEVICE; ++ } ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_process_bind_request(fwk_id_t requester_id, ++ fwk_id_t target_id, ++ fwk_id_t api_type, ++ const void **api) ++{ ++ *api = &api_optee_regu; ++ ++ return FWK_SUCCESS; ++} ++ ++const struct fwk_module module_stm32_regu_consumer = { ++ .type = FWK_MODULE_TYPE_DRIVER, ++ .api_count = 1, ++ .init = stm32_regu_consumer_init, ++ .element_init = stm32_regu_consumer_element_init, ++ .process_bind_request = stm32_regu_consumer_process_bind_request, ++}; +diff --git a/product/optee-stm32mp2/fw/CMakeLists.txt b/product/optee-stm32mp2/fw/CMakeLists.txt +new file mode 100644 +index 00000000..8674a1eb +--- /dev/null ++++ b/product/optee-stm32mp2/fw/CMakeLists.txt +@@ -0,0 +1,24 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++# ++# Create the firmware target. ++# ++ ++add_library(${SCP_FIRMWARE_TARGET}) ++ ++# cmake-lint: disable=E1122 ++ ++target_include_directories( ++ ${SCP_FIRMWARE_TARGET} ++ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include" ++ "${CMAKE_CURRENT_SOURCE_DIR}") ++ ++target_sources( ++ ${SCP_FIRMWARE_TARGET} ++ PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/config_all.c" ++) +diff --git a/product/optee-stm32mp2/fw/Firmware.cmake b/product/optee-stm32mp2/fw/Firmware.cmake +new file mode 100644 +index 00000000..0e5b0665 +--- /dev/null ++++ b/product/optee-stm32mp2/fw/Firmware.cmake +@@ -0,0 +1,57 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++# ++# Configure the build system. ++# ++ ++set(SCP_FIRMWARE "scmi-fw") ++ ++set(SCP_FIRMWARE_TARGET "scmi-fw") ++ ++set(SCP_TOOLCHAIN_INIT "GNU") ++ ++set(SCP_ARCHITECTURE "optee") ++ ++set(CMAKE_BUILD_TYPE "Release") ++ ++set(SCP_ENABLE_NOTIFICATIONS_INIT FALSE) ++ ++set(SCP_ENABLE_SCMI_NOTIFICATIONS_INIT FALSE) ++ ++set(SCP_ENABLE_SCMI_SENSOR_EVENTS_INIT FALSE) ++ ++set(SCP_ENABLE_FAST_CHANNELS_INIT FALSE) ++ ++set(SCP_ENABLE_SCMI_RESET_INIT TRUE) ++ ++set(SCP_ENABLE_IPO_INIT FALSE) ++ ++list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/stm32_regu_consumer") ++list(PREPEND SCP_MODULE_PATHS "${CMAKE_CURRENT_LIST_DIR}/../module/psu_optee_regulator") ++ ++# The order of the modules in the following list is the order in which the ++# modules are initialized, bound, started during the pre-runtime phase. ++# any change in the order will cause firmware initialization errors. ++ ++list(APPEND SCP_MODULES "optee-mbx") ++list(APPEND SCP_MODULES "msg-smt") ++list(APPEND SCP_MODULES "scmi") ++list(APPEND SCP_MODULES "optee-clock") ++list(APPEND SCP_MODULES "clock") ++list(APPEND SCP_MODULES "scmi-clock") ++list(APPEND SCP_MODULES "optee-reset") ++list(APPEND SCP_MODULES "reset-domain") ++list(APPEND SCP_MODULES "scmi-reset-domain") ++list(APPEND SCP_MODULES "stm32-regu-consumer") ++list(APPEND SCP_MODULES "voltage-domain") ++list(APPEND SCP_MODULES "scmi-voltage-domain") ++list(APPEND SCP_MODULES "psu-optee-regulator") ++list(APPEND SCP_MODULES "psu") ++list(APPEND SCP_MODULES "dvfs") ++list(APPEND SCP_MODULES "scmi-perf") ++list(APPEND SCP_MODULES "optee-console") +diff --git a/product/optee-stm32mp2/fw/Toolchain-GNU.cmake b/product/optee-stm32mp2/fw/Toolchain-GNU.cmake +new file mode 100644 +index 00000000..ab5d91f2 +--- /dev/null ++++ b/product/optee-stm32mp2/fw/Toolchain-GNU.cmake +@@ -0,0 +1,22 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++include_guard() ++ ++set(CMAKE_SYSTEM_PROCESSOR "optee") ++set(CMAKE_TOOLCHAIN_PREFIX ${CFG_CROSS_COMPILE}) ++ ++set(CMAKE_ASM_COMPILER_TARGET ${CFG_CROSS_COMPILE}) ++set(CMAKE_C_COMPILER_TARGET ${CFG_CROSS_COMPILE}) ++set(CMAKE_CXX_COMPILER_TARGET ${CFG_CROSS_COMPILE}) ++ ++include( ++ "${CMAKE_CURRENT_LIST_DIR}/../../../cmake/Toolchain/GNU-Baremetal.cmake") ++ ++foreach(language IN ITEMS ASM C CXX) ++ string(APPEND CMAKE_${language}_FLAGS_INIT ${CFG_CFLAGS_OPTEE}) ++endforeach() +diff --git a/product/optee-stm32mp2/fw/config_all.c b/product/optee-stm32mp2/fw/config_all.c +new file mode 100644 +index 00000000..3aa24d76 +--- /dev/null ++++ b/product/optee-stm32mp2/fw/config_all.c +@@ -0,0 +1,793 @@ ++/* ++ * Arm SCP/MCP Software ++ * Copyright (c) 2022-2023, Linaro Limited and Contributors. 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 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* SCMI agent and services (channels) */ ++static struct mod_scmi_agent *scmi_agent_table; ++static struct mod_scmi_config scmi_data; ++static struct fwk_element *scmi_service_elt; ++ ++/* SCMI channel mailbox/shmem */ ++static struct fwk_element *msg_smt_elt; ++static struct mod_msg_smt_channel_config *msg_smt_data; ++static struct fwk_element *optee_mbx_elt; ++static struct mod_optee_mbx_channel_config *optee_mbx_data; ++ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++/* SCMI clock generic */ ++static struct mod_scmi_clock_agent *scmi_clk_agent_tbl; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_CLOCK ++/* Clocks and optee/clock, same number/indices. Elements and configuration data */ ++static struct fwk_element *optee_clock_elt; /* Optee/clock elements */ ++static struct mod_optee_clock_config *optee_clock_cfg; /* Config data for optee/clock elements */ ++static struct fwk_element *clock_elt; /* Clock elements */ ++static struct mod_clock_dev_config *clock_data; /* Config data for clock elements */ ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++/* 1 DVFS (elt & data) per DVFS exposed */ ++static struct mod_dvfs_domain_config *dvfs_data; ++static struct fwk_element *dvfs_elt; ++/* A unique scmi_perf instance refers to perf domains data (DVFS instance) */ ++static struct mod_scmi_perf_domain_config *scmi_perf_domain_data; ++struct fwk_module_config config_scmi_perf; ++ ++/* PSU and optee/psu-regu, used with DVFS. Elements and configuration data */ ++static struct fwk_element *psu_optee_regu_elt; ++static struct mod_psu_optee_regulator_dev_config *psu_optee_regu_data; ++static struct fwk_element *psu_elt; ++static struct mod_psu_element_cfg *psu_data; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++/* SCMI reset domains and optee reset controller */ ++static struct mod_scmi_reset_domain_agent *scmi_reset_agent_tbl; ++static struct fwk_element *optee_reset_elt; ++static struct mod_optee_reset_dev_config *optee_reset_data; ++static struct fwk_element *reset_elt; ++static struct mod_reset_domain_dev_config *reset_data; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++/* SCMI voltage domains and optee regulators */ ++static struct mod_scmi_voltd_agent *scmi_voltd_agent_tbl; ++static struct fwk_element *optee_regu_elt; ++static struct mod_stm32_regu_consumer_dev_config *optee_regu_data; ++static struct fwk_element *voltd_elt; ++static struct mod_voltd_dev_config *voltd_data; ++#endif ++ ++/* Config data for scmi module */ ++static const struct fwk_element *get_scmi_service_table(fwk_id_t module_id) ++{ ++ return scmi_service_elt; /* scmi_service_elt filled during initialization */ ++} ++ ++struct fwk_module_config config_scmi = { ++ .data = (void *)&scmi_data, /* scmi_data filled during initialization */ ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(get_scmi_service_table), ++}; ++ ++/* Config data for optee_mbx module */ ++static const struct fwk_element *optee_mbx_get_element_table(fwk_id_t module_id) ++{ ++ return (const struct fwk_element *)optee_mbx_elt; ++} ++ ++struct fwk_module_config config_optee_mbx = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_mbx_get_element_table), ++}; ++ ++/* Config data for msg_smt module */ ++static const struct fwk_element *msg_smt_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_MSG_SMT); ++ return (const struct fwk_element *)msg_smt_elt; ++} ++ ++struct fwk_module_config config_msg_smt = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(msg_smt_get_element_table), ++}; ++ ++/* Config data for scmi_clock, clock and optee_clock modules */ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++struct fwk_module_config config_scmi_clock = { ++ .data = &((struct mod_scmi_clock_config){ ++ .agent_table = NULL, /* Allocated during initialization */ ++ .agent_count = 0, /* Set during initialization */ ++ }), ++}; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_CLOCK ++static const struct fwk_element *clock_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_CLOCK); ++ return (const struct fwk_element *)clock_elt; ++} ++ ++struct fwk_module_config config_clock = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(clock_get_element_table), ++}; ++ ++static const struct fwk_element *optee_clock_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_CLOCK); ++ return (const struct fwk_element *)optee_clock_elt; ++} ++ ++struct fwk_module_config config_optee_clock = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_clock_get_element_table), ++}; ++#endif ++ ++/* Config data for scmi_reset_domain, reset_domain and optee_reset modules */ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++struct fwk_module_config config_scmi_reset_domain = { ++ .data = &((struct mod_scmi_reset_domain_config){ ++ .agent_table = NULL, /* Allocated during initialization */ ++ .agent_count = 0, /* Set during initialization */ ++ }), ++}; ++ ++static const struct fwk_element *reset_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_RESET_DOMAIN); ++ return (const struct fwk_element *)reset_elt; ++} ++ ++struct fwk_module_config config_reset_domain = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(reset_get_element_table), ++}; ++ ++static const struct fwk_element *optee_reset_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_OPTEE_RESET); ++ return (const struct fwk_element *)optee_reset_elt; ++} ++ ++struct fwk_module_config config_optee_reset = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(optee_reset_get_element_table), ++}; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++/* Config data for scmi_voltage_domain, voltage_domain and optee_regu modules */ ++struct fwk_module_config config_scmi_voltage_domain = { ++ .data = &((struct mod_scmi_voltd_config){ ++ .agent_table = NULL, /* Allocated during initialization */ ++ .agent_count = 0, /* Set during initialization */ ++ }), ++}; ++ ++static const struct fwk_element *voltd_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_VOLTAGE_DOMAIN); ++ return (const struct fwk_element *)voltd_elt; ++} ++ ++struct fwk_module_config config_voltage_domain = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(voltd_get_element_table), ++}; ++ ++static const struct fwk_element *stm32_regu_consumer_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_STM32_REGU_CONSUMER); ++ return (const struct fwk_element *)optee_regu_elt; ++} ++ ++struct fwk_module_config config_stm32_regu_consumer = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(stm32_regu_consumer_get_element_table), ++}; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++/* Config data for scmi_perf and dvfs module */ ++struct fwk_module_config config_scmi_perf = { ++ .data = &((struct mod_scmi_perf_config){ ++ .domains = NULL, /* Allocated during initialization */ ++ .perf_doms_count = 0, /* Set during initialization */ ++ .fast_channels_alarm_id = FWK_ID_NONE_INIT, ++#ifdef BUILD_HAS_MOD_STATISTICS ++ .stats_enabled = true, ++#endif ++ }), ++}; ++ ++static const struct fwk_element *dvfs_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_DVFS); ++ return (const struct fwk_element *)dvfs_elt; ++} ++ ++struct fwk_module_config config_dvfs = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(dvfs_get_element_table), ++}; ++ ++/* Config data for psu and optee/psu module */ ++static const struct fwk_element *psu_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU); ++ return (const struct fwk_element *)psu_elt; ++} ++ ++struct fwk_module_config config_psu = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_get_element_table), ++}; ++ ++static const struct fwk_element *psu_optee_regu_get_element_table(fwk_id_t module_id) ++{ ++ fwk_assert(fwk_id_get_module_idx(module_id) == FWK_MODULE_IDX_PSU_OPTEE_REGULATOR); ++ return (const struct fwk_element *)psu_optee_regu_elt ; ++} ++ ++struct fwk_module_config config_psu_optee_regulator = { ++ .elements = FWK_MODULE_DYNAMIC_ELEMENTS(psu_optee_regu_get_element_table), ++}; ++#endif ++ ++/* ++ * Indices state when applying agents configuration ++ * @channel_count: Number of channels (mailbox/shmem links) used ++ * @clock_index: Current index for clock and optee/clock (same indices) ++ * @clock_count: Number of clocks (also number of optee/clocks) ++ * @reset_index: Current index for reset controller and optee/reset ++ * @reset_count: Number of reset controller (optee/reset) instances ++ * @regu_index: Current index for voltd and optee/regulator ++ * @regu_count: Number of voltd (optee/regulator) instances ++ * @psu_index: Current index for PSU and optee/PSU instances ++ * @psu_count: Number of PSU (optee/PSU) instances ++ * @dvfs_index: Current index for DVFS instance ++ * @dvfs_count: Number of DVFS instances ++ */ ++struct scpfw_resource_counter { ++ size_t channel_count; ++ size_t clock_index; ++ size_t clock_count; ++ size_t reset_index; ++ size_t reset_count; ++ size_t regu_index; ++ size_t regu_count; ++ size_t psu_index; ++ size_t psu_count; ++ size_t dvfs_index; ++ size_t dvfs_count; ++} scpfw_resource_counter; ++ ++/* ++ * Count once for all the several instances and allocate global resources. ++ * Global resources are clock, optee/clock, reset, optee/reset, regu, ++ * optee/regu, psu, optee/psu, dvfs, perfd, ...; ++ */ ++static void count_resources(struct scpfw_config *cfg) ++{ ++ size_t i, j; ++ ++ for (i = 0; i < cfg->agent_count; i++) { ++ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; ++ ++ scpfw_resource_counter.channel_count += agent_cfg->channel_count; ++ ++ for (j = 0; j < agent_cfg->channel_count; j++) { ++ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; ++ ++ /* Clocks for scmi_clock and for DVFS */ ++ scpfw_resource_counter.clock_count += channel_cfg->clock_count; ++ scpfw_resource_counter.clock_count += channel_cfg->perfd_count; ++ /* Reset for smci_reset only */ ++ scpfw_resource_counter.reset_count += channel_cfg->reset_count; ++ /* Regulators for smci_voltage_domain only */ ++ scpfw_resource_counter.regu_count += channel_cfg->voltd_count; ++ /* DVFS and PSU DVFS only */ ++ scpfw_resource_counter.dvfs_count += channel_cfg->perfd_count; ++ scpfw_resource_counter.psu_count += channel_cfg->perfd_count; ++ } ++ } ++ ++#ifndef CFG_SCPFW_MOD_CLOCK ++ fwk_assert(!scpfw_resource_counter.clock_count); ++#endif ++#ifndef CFG_SCPFW_MOD_RESET_DOMAIN ++ fwk_assert(!scpfw_resource_counter.reset_count); ++#endif ++#ifndef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++ fwk_assert(!scpfw_resource_counter.regu_count); ++#endif ++#ifndef CFG_SCPFW_MOD_DVFS ++ fwk_assert(!scpfw_resource_counter.dvfs_count); ++#endif ++#ifndef CFG_SCPFW_MOD_PSU ++ fwk_assert(!scpfw_resource_counter.psu_count); ++#endif ++} ++ ++/* ++ * Allocate all tables that may be needed. An optimized implementation would ++ * allocate a single piece of memory and set the pointers accordingly. ++ * */ ++static void allocate_global_resources(struct scpfw_config *cfg) ++{ ++ struct mod_scmi_reset_domain_config *scmi_reset_config __maybe_unused; ++ struct mod_scmi_voltd_config *scmi_voltd_config __maybe_unused; ++ struct mod_scmi_clock_config *scmi_clock_config __maybe_unused; ++ /* @cfg does not consider agent #0 this the reserved platform/server agent */ ++ size_t __maybe_unused scmi_agent_count = cfg->agent_count + 1; ++ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++ /* SCMI clock domains resources */ ++ scmi_clk_agent_tbl = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_clk_agent_tbl)); ++ scmi_clock_config = (void *)config_scmi_clock.data; ++ scmi_clock_config->agent_table = scmi_clk_agent_tbl; ++ scmi_clock_config->agent_count = scmi_agent_count; ++#endif ++ ++#ifdef CFG_SCPFW_MOD_CLOCK ++ /* Clock domains resources */ ++ optee_clock_cfg = fwk_mm_calloc(scpfw_resource_counter.clock_count, ++ sizeof(*optee_clock_cfg)); ++ optee_clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, ++ sizeof(*optee_clock_elt)); ++ ++ clock_data = fwk_mm_calloc(scpfw_resource_counter.clock_count, ++ sizeof(*clock_data)); ++ clock_elt = fwk_mm_calloc(scpfw_resource_counter.clock_count + 1, ++ sizeof(*clock_elt)); ++#endif ++ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++ /* SCMI reset domains resources */ ++ scmi_reset_agent_tbl = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_reset_agent_tbl)); ++ scmi_reset_config = (void *)config_scmi_reset_domain.data; ++ scmi_reset_config->agent_table = scmi_reset_agent_tbl; ++ scmi_reset_config->agent_count = scmi_agent_count; ++ ++ optee_reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, ++ sizeof(*optee_reset_data)); ++ optee_reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, ++ sizeof(*optee_reset_elt)); ++ ++ reset_data = fwk_mm_calloc(scpfw_resource_counter.reset_count, ++ sizeof(*reset_data)); ++ reset_elt = fwk_mm_calloc(scpfw_resource_counter.reset_count + 1, ++ sizeof(*reset_elt)); ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++ /* PSU and related optee PSU regulator resources */ ++ psu_optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, ++ sizeof(*psu_optee_regu_elt)); ++ psu_optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, ++ sizeof(*psu_optee_regu_data)); ++ ++ psu_elt = fwk_mm_calloc(scpfw_resource_counter.psu_count + 1, ++ sizeof(*psu_elt)); ++ psu_data = fwk_mm_calloc(scpfw_resource_counter.psu_count, ++ sizeof(*psu_data)); ++ ++ /* DVFS and SCMI performance management resources */ ++ dvfs_elt = fwk_mm_calloc(scpfw_resource_counter.dvfs_count + 1, ++ sizeof(*dvfs_elt)); ++ dvfs_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, ++ sizeof(*dvfs_data)); ++ ++ scmi_perf_domain_data = fwk_mm_calloc(scpfw_resource_counter.dvfs_count, ++ sizeof(*scmi_perf_domain_data)); ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++ /* SCMI voltage domains resources */ ++ scmi_voltd_agent_tbl = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_voltd_agent_tbl)); ++ scmi_voltd_config = (void *)config_scmi_voltage_domain.data; ++ scmi_voltd_config->agent_table = scmi_voltd_agent_tbl; ++ scmi_voltd_config->agent_count = scmi_agent_count; ++ ++ optee_regu_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, ++ sizeof(*optee_regu_data)); ++ optee_regu_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, ++ sizeof(*optee_regu_elt)); ++ ++ voltd_data = fwk_mm_calloc(scpfw_resource_counter.regu_count, ++ sizeof(*voltd_data)); ++ voltd_elt = fwk_mm_calloc(scpfw_resource_counter.regu_count + 1, ++ sizeof(*voltd_elt)); ++#endif ++} ++ ++static void set_scmi_comm_resources(struct scpfw_config *cfg) ++{ ++ unsigned int channel_index; ++ size_t i, j; ++ /* @cfg does not consider agent #0 this the reserved platform/server agent */ ++ size_t scmi_agent_count = cfg->agent_count + 1; ++ ++ scmi_agent_table = fwk_mm_calloc(scmi_agent_count, ++ sizeof(*scmi_agent_table)); ++ ++ scmi_service_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, ++ sizeof(*scmi_service_elt)); ++ ++ msg_smt_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, ++ sizeof(*msg_smt_elt)); ++ msg_smt_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, ++ sizeof(*msg_smt_data)); ++ ++ optee_mbx_elt = fwk_mm_calloc(scpfw_resource_counter.channel_count + 1, ++ sizeof(*optee_mbx_elt)); ++ optee_mbx_data = fwk_mm_calloc(scpfw_resource_counter.channel_count, ++ sizeof(*optee_mbx_data)); ++ ++ /* Set now the uniqnue scmi module instance configuration data */ ++ scmi_data = (struct mod_scmi_config){ ++ .agent_table = scmi_agent_table, ++ .agent_count = scmi_agent_count, ++ .protocol_count_max = 9, ++ .vendor_identifier = "STMicroelectronics", ++ .sub_vendor_identifier = "STMicroelectronics", ++ }; ++ ++ channel_index = 0; ++ ++ for (i = 0; i < cfg->agent_count; i++) { ++ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; ++ size_t agent_index = i + 1; ++ ++ scmi_agent_table[agent_index].type = SCMI_AGENT_TYPE_OSPM; ++ scmi_agent_table[agent_index].name = agent_cfg->name; ++ ++ for (j = 0; j < agent_cfg->channel_count; j++) { ++ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; ++ struct mod_scmi_service_config *service_data; ++ ++ service_data = fwk_mm_calloc(1, sizeof(*service_data)); ++ *service_data = (struct mod_scmi_service_config){ ++ .transport_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, 0), ++ .transport_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, ++ MOD_MSG_SMT_API_IDX_SCMI_TRANSPORT), ++ .scmi_agent_id = agent_cfg->agent_id, ++ .scmi_p2a_id = FWK_ID_NONE_INIT, ++ }; ++ ++ /* Currently expect 1 agent with ID SCMI_AGENT_ID_NSEC0 (1) */ ++ fwk_assert(service_data->scmi_agent_id == SCMI_AGENT_ID_NSEC0); ++ ++ scmi_service_elt[channel_index].name = channel_cfg->name; ++ scmi_service_elt[channel_index].data = service_data; ++ ++ msg_smt_elt[channel_index].name = channel_cfg->name; ++ msg_smt_elt[channel_index].data = (void *)(msg_smt_data + channel_index); ++ ++ msg_smt_data[channel_index] = (struct mod_msg_smt_channel_config){ ++ .type = MOD_MSG_SMT_CHANNEL_TYPE_REQUESTER, ++ .mailbox_size = 128, ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_MBX, ++ channel_index), ++ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_MBX, 0), ++ }; ++ ++ optee_mbx_elt[channel_index].name = channel_cfg->name; ++ optee_mbx_elt[channel_index].data = (void *)(optee_mbx_data + channel_index); ++ ++ optee_mbx_data[channel_index] = (struct mod_optee_mbx_channel_config){ ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_MSG_SMT, channel_index), ++ .driver_api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_MSG_SMT, ++ MOD_MSG_SMT_API_IDX_DRIVER_INPUT), ++ }; ++ ++ channel_index++; ++ } ++ } ++}; ++ ++static void set_resources(struct scpfw_config *cfg) ++{ ++ size_t i, j, k, l; ++ ++ for (i = 0; i < cfg->agent_count; i++) { ++ struct scpfw_agent_config *agent_cfg = cfg->agent_config + i; ++ size_t agent_index = i + 1; ++ ++ if (agent_index != agent_cfg->agent_id) { ++ panic("scpfw config expects agent ID is agent index"); ++ } ++ ++ for (j = 0; j < agent_cfg->channel_count; j++) { ++ struct scpfw_channel_config *channel_cfg = agent_cfg->channel_config + j; ++ ++#ifdef CFG_SCPFW_MOD_SCMI_CLOCK ++ /* Add first SCMI clock. We will add later the clocks used for DVFS */ ++ if (channel_cfg->clock_count) { ++ size_t clock_index = scpfw_resource_counter.clock_index; ++ struct mod_scmi_clock_device *dev = NULL; ++ ++ /* Set SCMI clocks array for the SCMI agent */ ++ dev = fwk_mm_calloc(channel_cfg->clock_count, ++ sizeof(struct mod_scmi_clock_device)); ++ ++ fwk_assert(!scmi_clk_agent_tbl[agent_index].device_table); ++ scmi_clk_agent_tbl[agent_index].device_count = channel_cfg->clock_count; ++ scmi_clk_agent_tbl[agent_index].device_table = dev; ++ ++ /* Set clock and optee/clock elements and config data */ ++ for (k = 0; k < channel_cfg->clock_count; k++) { ++ struct scmi_clock *clock_cfg = channel_cfg->clock + k; ++ ++ dev[k].element_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); ++ ++ optee_clock_cfg[clock_index].clk = clock_cfg->clk; ++ optee_clock_cfg[clock_index].default_enabled = clock_cfg->enabled; ++ ++ optee_clock_elt[clock_index].name = clock_cfg->name; ++ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); ++ ++ clock_data[clock_index] = (struct mod_clock_dev_config){ ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ clock_index), ++ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ 0), ++ }; ++ ++ clock_elt[clock_index].name = clock_cfg->name; ++ clock_elt[clock_index].data = (void *)(clock_data + clock_index); ++ ++ clock_index++; ++ } ++ ++ scpfw_resource_counter.clock_index = clock_index; ++ } ++#endif ++ ++#ifdef CFG_SCPFW_MOD_RESET_DOMAIN ++ if (channel_cfg->reset_count) { ++ struct mod_scmi_reset_domain_device *dev = NULL; ++ size_t reset_index = scpfw_resource_counter.reset_index; ++ ++ /* Set SCMI reset domains array for the SCMI agent */ ++ dev = fwk_mm_calloc(channel_cfg->reset_count, sizeof(*dev)); ++ ++ fwk_assert(!scmi_reset_agent_tbl[agent_index].device_table); ++ scmi_reset_agent_tbl[agent_index].agent_domain_count = channel_cfg->reset_count; ++ scmi_reset_agent_tbl[agent_index].device_table = dev; ++ ++ /* Set reset_domain and optee/reset elements and config data */ ++ for (k = 0; k < channel_cfg->reset_count; k++) { ++ struct scmi_reset *reset_cfg = channel_cfg->reset + k; ++ ++ dev[k].element_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_RESET_DOMAIN, ++ reset_index); ++ ++ optee_reset_data[reset_index].rstctrl = reset_cfg->rstctrl; ++ ++ optee_reset_elt[reset_index].name = reset_cfg->name; ++ optee_reset_elt[reset_index].data = ++ (void *)(optee_reset_data + reset_index); ++ ++ reset_data[reset_index] = (struct mod_reset_domain_dev_config){ ++ .driver_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_RESET, ++ reset_index), ++ .driver_api_id = ++ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_RESET, 0), ++ .modes = MOD_RESET_DOMAIN_AUTO_RESET | ++ MOD_RESET_DOMAIN_MODE_EXPLICIT_ASSERT | ++ MOD_RESET_DOMAIN_MODE_EXPLICIT_DEASSERT, ++ }; ++ ++ reset_elt[reset_index].name = reset_cfg->name; ++ reset_elt[reset_index].data = (void *)(reset_data + reset_index); ++ ++ reset_index++; ++ } ++ ++ scpfw_resource_counter.reset_index = reset_index; ++ } ++#endif ++ ++#ifdef CFG_SCPFW_MOD_VOLTAGE_DOMAIN ++ if (channel_cfg->voltd_count) { ++ size_t regu_index = scpfw_resource_counter.regu_index; ++ struct mod_scmi_voltd_device *dev = NULL; ++ ++ /* Set SCMI voltage domains array for the SCMI agent */ ++ dev = fwk_mm_calloc(channel_cfg->voltd_count, ++ sizeof(struct mod_scmi_voltd_device)); ++ ++ fwk_assert(!scmi_voltd_agent_tbl[agent_index].device_table); ++ scmi_voltd_agent_tbl[agent_index].domain_count = channel_cfg->voltd_count; ++ scmi_voltd_agent_tbl[agent_index].device_table = dev; ++ ++ /* Set voltage_domain and optee/regu elements and config data */ ++ for (k = 0; k < channel_cfg->voltd_count; k++) { ++ struct scmi_voltd *voltd_cfg = channel_cfg->voltd + k; ++ static const char reserved[] = "reserved"; ++ const char *name = NULL; ++ ++ if (voltd_cfg->rdev) { ++ name = voltd_cfg->rdev->reg_name; ++ } else { ++ name = reserved; ++ } ++ ++ dev[regu_index].element_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_VOLTAGE_DOMAIN, k); ++ ++ optee_regu_elt[regu_index].name = name; ++ optee_regu_elt[regu_index].data = (void *)(optee_regu_data + regu_index); ++ optee_regu_data[regu_index].rdev = voltd_cfg->rdev; ++ optee_regu_data[regu_index].default_enabled = voltd_cfg->enabled; ++ ++ voltd_data[regu_index].driver_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, ++ regu_index); ++ voltd_data[regu_index].api_id = ++ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_STM32_REGU_CONSUMER, 0); ++ ++ voltd_elt[regu_index].name = name; ++ voltd_elt[regu_index].data = (void *)(voltd_data + regu_index); ++ regu_index++; ++ } ++ ++ scpfw_resource_counter.regu_index = regu_index; ++ } ++#endif ++ ++#ifdef CFG_SCPFW_MOD_DVFS ++ if (channel_cfg->perfd_count) { ++ size_t clock_index = scpfw_resource_counter.clock_index; ++ size_t psu_index = scpfw_resource_counter.psu_index; ++ size_t dvfs_index = scpfw_resource_counter.dvfs_index; ++ ++ for (k = 0; k < channel_cfg->perfd_count; k++) { ++ struct mod_scmi_perf_config *scmi_perf_data = NULL; ++ struct scmi_perfd *perfd_cfg = channel_cfg->perfd + k; ++ ++ /* ++ * DVFS with SCMI performance management domains ++ * 1 initial scmi_perf instance defines the number of DVFS's ++ * For each DVFS instance: ++ * - 1 instance (elt/config) of dvfs, psu, optee/psu, clock, optee/clock ++ * Clocks and optee/clocks are already allocated but not yet set. ++ */ ++ ++ /* scmi_perf: data defines the DVFS domains indices */ ++ scmi_perf_domain_data[dvfs_index] = (struct mod_scmi_perf_domain_config){ }; ++ ++ scmi_perf_data = (void *)config_scmi_perf.data; ++ ++ scmi_perf_data[dvfs_index].domains = (void *)scmi_perf_domain_data; ++ scmi_perf_data[dvfs_index].perf_doms_count = scpfw_resource_counter.dvfs_count; ++ scmi_perf_data[dvfs_index].fast_channels_alarm_id = (fwk_id_t)FWK_ID_NONE_INIT; ++#ifdef BUILD_HAS_MOD_STATISTICS ++ scmi_perf_data[dvfs_index].stats_enabled = true; ++#endif ++ ++ /* dvfs instances: 1 instance per expose DVFS service */ ++ dvfs_data[dvfs_index].psu_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU, psu_index); ++ dvfs_data[dvfs_index].clock_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK, clock_index); ++ dvfs_data[dvfs_index].latency = 0; /* not set, used for async access */ ++ dvfs_data[dvfs_index].opps = ++ fwk_mm_calloc(perfd_cfg->dvfs_opp_count, ++ sizeof(struct mod_dvfs_opp)); ++ ++ for (l = 0; l < perfd_cfg->dvfs_opp_count; l++) { ++ uint64_t power = 0; ++ ++ /* Quick estimation of power consumpsion */ ++ power = perfd_cfg->dvfs_opp_khz[l]; ++ power *= perfd_cfg->dvfs_opp_mv[l]; ++ power *= perfd_cfg->dvfs_opp_mv[l]; ++ power /= 100 * 1000 * 1000; ++ ++ dvfs_data[dvfs_index].opps[l] = (struct mod_dvfs_opp){ ++ .level = perfd_cfg->dvfs_opp_khz[l] * 1000UL, ++ .frequency = perfd_cfg->dvfs_opp_khz[l], ++ .voltage = perfd_cfg->dvfs_opp_mv[l], ++ .power = (uint32_t)power, ++ }; ++ } ++ ++ dvfs_elt[dvfs_index].name = perfd_cfg->name; ++ dvfs_elt[dvfs_index].data = (void *)(dvfs_data + dvfs_index); ++ ++ /* Module psu_optee module (elements and configuration data) */ ++ psu_optee_regu_elt[psu_index].name = perfd_cfg->rdev->reg_name; ++ psu_optee_regu_elt[psu_index].sub_element_count = scpfw_resource_counter.psu_count; ++ psu_optee_regu_elt[psu_index].data = (void *)(psu_optee_regu_data + psu_index); ++ ++ psu_optee_regu_data[psu_index].rdev = perfd_cfg->rdev; ++ ++ /* Module psu (elements and configuration data) */ ++ psu_elt[psu_index].name = perfd_cfg->rdev->reg_name; ++ psu_elt[psu_index].data = (void *)(psu_data + psu_index); ++ psu_data[psu_index].driver_id = ++ (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, psu_index); ++ psu_data[psu_index].driver_api_id = ++ (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_PSU_OPTEE_REGULATOR, 0); ++ ++ /* Module clock and optee_clock */ ++ fwk_assert(!clock_elt[clock_index].data); ++ ++ clock_elt[clock_index].name = perfd_cfg->clk->name; ++ clock_elt[clock_index].data = (void *)(clock_data + clock_index); ++ ++ clock_data[clock_index] = (struct mod_clock_dev_config){ ++ .driver_id = (fwk_id_t)FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ clock_index), ++ .api_id = (fwk_id_t)FWK_ID_API_INIT(FWK_MODULE_IDX_OPTEE_CLOCK, ++ 0), ++ }; ++ ++ optee_clock_cfg[clock_index].clk = perfd_cfg->clk; ++ optee_clock_cfg[clock_index].default_enabled = false; ++ ++ optee_clock_elt[clock_index].name = perfd_cfg->clk->name; ++ optee_clock_elt[clock_index].data = (void *)(optee_clock_cfg + clock_index); ++ ++ clock_index++; ++ psu_index++; ++ dvfs_index++; ++ } ++ ++ scpfw_resource_counter.clock_index = clock_index; ++ scpfw_resource_counter.psu_index = psu_index; ++ scpfw_resource_counter.dvfs_index = dvfs_index; ++ } ++#endif ++ } ++ } ++} ++ ++void scpfw_configure(struct scpfw_config *cfg) ++{ ++ count_resources(cfg); ++ allocate_global_resources(cfg); ++ set_scmi_comm_resources(cfg); ++ set_resources(cfg); ++} +diff --git a/product/optee-stm32mp2/include/fmw_io.h b/product/optee-stm32mp2/include/fmw_io.h +new file mode 100644 +index 00000000..8e53e139 +--- /dev/null ++++ b/product/optee-stm32mp2/include/fmw_io.h +@@ -0,0 +1,17 @@ ++/* ++ * Arm SCP/MCP Software ++ * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef FMW_IO_H ++#define FMW_IO_H ++ ++#include ++#include ++ ++#define FMW_IO_STDIN_ID FWK_ID_NONE ++#define FMW_IO_STDOUT_ID FWK_ID_ELEMENT(FWK_MODULE_IDX_OPTEE_CONSOLE, 0) ++ ++#endif /* FMW_IO_H */ +diff --git a/product/optee-stm32mp2/include/fmw_log.h b/product/optee-stm32mp2/include/fmw_log.h +new file mode 100644 +index 00000000..4e0bdd0e +--- /dev/null ++++ b/product/optee-stm32mp2/include/fmw_log.h +@@ -0,0 +1,16 @@ ++/* ++ * Arm SCP/MCP Software ++ * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef FMW_LOG_H ++#define FMW_LOG_H ++ ++/* ++ * Disable log buffering by setting buffer size to 0. ++ */ ++#define FMW_LOG_BUFFER_SIZE 0 ++ ++#endif /* FMW_LOG_H */ +diff --git a/product/optee-stm32mp2/include/gnu/stubs-soft.h b/product/optee-stm32mp2/include/gnu/stubs-soft.h +new file mode 100644 +index 00000000..e69de29b +diff --git a/product/optee-stm32mp2/include/scmi_agents.h b/product/optee-stm32mp2/include/scmi_agents.h +new file mode 100644 +index 00000000..13d29618 +--- /dev/null ++++ b/product/optee-stm32mp2/include/scmi_agents.h +@@ -0,0 +1,29 @@ ++/* ++ * Arm SCP/MCP Software ++ * Copyright (c) 2022, Linaro Limited and Contributors. All rights reserved. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef SCMI_AGENTS_H ++#define SCMI_AGENTS_H ++ ++enum scmi_agent_id { ++ SCMI_AGENT_ID_RSV = 0, /* 0 is reserved for the platform */ ++ SCMI_AGENT_ID_NSEC0, ++ SCMI_AGENT_ID_COUNT ++}; ++ ++enum scmi_service_idx { ++ SCMI_SERVICE_IDX_NS_CHANNEL0 = 0, ++ SCMI_SERVICE_IDX_COUNT ++}; ++ ++enum scmi_channel_device_idx { ++ SCMI_CHANNEL_DEVICE_IDX_NS0 = 0, ++ SCMI_CHANNEL_DEVICE_IDX_COUNT ++}; ++ ++#define SCMI_SHMEM_SIZE 128 ++ ++#endif /* SCMI_AGENTS_H */ +diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt b/product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt +new file mode 100644 +index 00000000..77af63f2 +--- /dev/null ++++ b/product/optee-stm32mp2/module/psu_optee_regulator/CMakeLists.txt +@@ -0,0 +1,17 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++add_library(${SCP_MODULE_TARGET} SCP_MODULE) ++ ++target_include_directories(${SCP_MODULE_TARGET} ++ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ++ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") ++ ++target_sources( ++ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_psu_optee_regulator.c") ++ ++target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) +diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake b/product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake +new file mode 100644 +index 00000000..26dc706e +--- /dev/null ++++ b/product/optee-stm32mp2/module/psu_optee_regulator/Module.cmake +@@ -0,0 +1,9 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++set(SCP_MODULE "psu-optee-regulator") ++set(SCP_MODULE_TARGET "psu-optee-regulator") +diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h b/product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h +new file mode 100644 +index 00000000..5b0347c7 +--- /dev/null ++++ b/product/optee-stm32mp2/module/psu_optee_regulator/include/mod_psu_optee_regulator.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2023, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef MOD_PSU_OPTEE_REGULATOR_H ++#define MOD_PSU_OPTEE_REGULATOR_H ++ ++#include ++#include ++#include ++#include ++ ++struct rdev; ++ ++/*! ++ * \brief Platform regulator configuration. ++ */ ++struct mod_psu_optee_regulator_dev_config { ++ struct rdev *rdev; ++}; ++ ++#endif /* MOD_PSU_OPTEE_REGULATOR_H */ +diff --git a/product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c b/product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c +new file mode 100644 +index 00000000..f1e8c444 +--- /dev/null ++++ b/product/optee-stm32mp2/module/psu_optee_regulator/src/mod_psu_optee_regulator.c +@@ -0,0 +1,190 @@ ++/* ++ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2022, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define DEBUG_MSG(...) FMSG(__VA_ARGS__) ++ ++/* Module context */ ++struct psu_optee_regulator_ctx { ++ struct mod_psu_optee_regulator_dev_config *config; ++ unsigned int dev_count; ++}; ++ ++/* A single instance handles all voltage regulators abstracted by regulator.h */ ++static struct psu_optee_regulator_ctx module_ctx; ++ ++static char __maybe_unused *regulator_name(struct rdev *rdev) ++{ ++ if (rdev) ++ return (char *)rdev->reg_name; ++ ++ return NULL; ++} ++ ++static struct rdev *get_regulator(fwk_id_t id) ++{ ++ unsigned int elt_index; ++ ++ elt_index = fwk_id_get_element_idx(id); ++ if (elt_index >= module_ctx.dev_count) ++ return NULL; ++ ++ return module_ctx.config[elt_index].rdev; ++} ++ ++/* ++ * Driver functions for the PSU API ++ */ ++static int psu_optee_regulator_set_enabled(fwk_id_t id, bool enabled) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct rdev *regulator; ++ ++ regulator = get_regulator(id); ++ if (!regulator) { ++ return FWK_E_PARAM; ++ } ++ ++ DEBUG_MSG("PSU set %s %s", regulator_name(regulator), ++ enabled ? "ON" : "OFF"); ++ ++ if (enabled) { ++ res = regulator_enable(regulator); ++ } else { ++ res = regulator_disable(regulator); ++ } ++ ++ if (res) { ++ return FWK_E_HANDLER; ++ } else { ++ return FWK_SUCCESS; ++ } ++} ++ ++static int psu_optee_regulator_get_enabled(fwk_id_t id, bool *enabled) ++{ ++ struct rdev *regulator; ++ ++ regulator = get_regulator(id); ++ if (!regulator || (enabled == NULL)) { ++ return FWK_E_PARAM; ++ } ++ ++ *enabled = regulator_is_enabled((const struct rdev *)regulator); ++ DEBUG_MSG("PSU get %s state: %s", regulator_name(regulator), ++ enabled ? "ON" : "OFF"); ++ ++ return FWK_SUCCESS; ++} ++ ++static int psu_optee_regulator_set_voltage(fwk_id_t id, uint32_t voltage) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct rdev *regulator; ++ uint16_t level_mv = voltage; ++ ++ regulator = get_regulator(id); ++ if (!regulator) { ++ return FWK_E_PARAM; ++ } ++ ++ DEBUG_MSG("PSU set regulator %s level: %"PRIu32"mV", ++ regulator_name(regulator), (uint32_t)level_mv); ++ ++ res = regulator_set_voltage(regulator, level_mv); ++ ++ if (res) { ++ return FWK_E_HANDLER; ++ } else { ++ ++ return FWK_SUCCESS; ++ } ++} ++ ++static int psu_optee_regulator_get_voltage(fwk_id_t id, uint32_t *voltage) ++{ ++ TEE_Result res = TEE_ERROR_GENERIC; ++ struct rdev *regulator; ++ uint16_t level_mv; ++ ++ regulator = get_regulator(id); ++ if (!regulator || (voltage == NULL)) { ++ return FWK_E_PARAM; ++ } ++ ++ res = regulator_get_voltage(regulator, &level_mv); ++ ++ DEBUG_MSG("PSU get regulator %s level: %"PRIu32"mV (res %#"PRIx32")", ++ regulator_name(regulator), (uint32_t)level_mv, res); ++ ++ if (res) { ++ return FWK_E_HANDLER; ++ } ++ ++ *voltage = level_mv; ++ ++ return FWK_SUCCESS; ++} ++ ++static struct mod_psu_driver_api psu_driver_api = { ++ .set_enabled = psu_optee_regulator_set_enabled, ++ .get_enabled = psu_optee_regulator_get_enabled, ++ .set_voltage = psu_optee_regulator_set_voltage, ++ .get_voltage = psu_optee_regulator_get_voltage, ++}; ++ ++static int psu_optee_regulator_init(fwk_id_t module_id, ++ unsigned int element_count, ++ const void *data) ++{ ++ return FWK_SUCCESS; ++} ++ ++static int psu_optee_regulator_element_init(fwk_id_t element_id, ++ unsigned int sub_element_count, ++ const void *data) ++{ ++ fwk_assert(data != NULL); ++ ++ module_ctx.config = (struct mod_psu_optee_regulator_dev_config *)data; ++ module_ctx.dev_count = sub_element_count; ++ ++ return FWK_SUCCESS; ++} ++ ++static int psu_optee_regulator_process_bind_request(fwk_id_t source_id, ++ fwk_id_t target_id, ++ fwk_id_t api_id, ++ const void **api) ++{ ++ *api = &psu_driver_api; ++ ++ return FWK_SUCCESS; ++} ++ ++const struct fwk_module module_psu_optee_regulator = { ++ .api_count = 1, ++ .type = FWK_MODULE_TYPE_DRIVER, ++ .init = psu_optee_regulator_init, ++ .element_init = psu_optee_regulator_element_init, ++ .process_bind_request = psu_optee_regulator_process_bind_request, ++}; +diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt b/product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt +new file mode 100644 +index 00000000..adf79cfc +--- /dev/null ++++ b/product/optee-stm32mp2/module/stm32_regu_consumer/CMakeLists.txt +@@ -0,0 +1,17 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++add_library(${SCP_MODULE_TARGET} SCP_MODULE) ++ ++target_include_directories(${SCP_MODULE_TARGET} ++ PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ++ "${SCP_OPTEE_DIR}/core/arch/arm/plat-stm32mp2") ++ ++target_sources( ++ ${SCP_MODULE_TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/mod_stm32_regu_consumer.c") ++ ++target_link_libraries(${SCP_MODULE_TARGET} PUBLIC module-voltage-domain) +diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake b/product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake +new file mode 100644 +index 00000000..dc988ed3 +--- /dev/null ++++ b/product/optee-stm32mp2/module/stm32_regu_consumer/Module.cmake +@@ -0,0 +1,9 @@ ++# ++# Arm SCP/MCP Software ++# Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. ++# ++# SPDX-License-Identifier: BSD-3-Clause ++# ++ ++set(SCP_MODULE "stm32-regu-consumer") ++set(SCP_MODULE_TARGET "module-stm32-regu-consumer") +diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h b/product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h +new file mode 100644 +index 00000000..d3f3358e +--- /dev/null ++++ b/product/optee-stm32mp2/module/stm32_regu_consumer/include/mod_stm32_regu_consumer.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2022, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#ifndef MOD_STM32_REGU_CONSUMER_H ++#define MOD_STM32_REGU_CONSUMER_H ++ ++#include ++#include ++#include ++#include ++ ++struct scmi_server_regu_channel; ++struct rdev; ++ ++/*! ++ * \brief Platform regulator configuration. ++ */ ++struct mod_stm32_regu_consumer_dev_config { ++ struct rdev *rdev; ++ bool default_enabled; ++}; ++ ++/* ++ * Build SCMI server resource tables for the voltage domains exposed ++ * by platform. ++ * ++ * @plat - reference to platform data ++ * @plat_count - Number of elements in platform data ++ */ ++void scmi_server_build_optee_regu_config(struct scmi_server_regu_channel *plat, ++ size_t plat_count); ++ ++#endif /* MOD_STM32_REGU_CONSUMER_H */ +diff --git a/product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c b/product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c +new file mode 100644 +index 00000000..2a344d90 +--- /dev/null ++++ b/product/optee-stm32mp2/module/stm32_regu_consumer/src/mod_stm32_regu_consumer.c +@@ -0,0 +1,345 @@ ++/* ++ * Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved. ++ * Copyright (c) 2022, STMicroelectronics ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define DEBUG_MSG(...) FMSG(__VA_ARGS__) ++ ++/* Device context */ ++struct stm32_regu_consumer_dev_ctx { ++ struct rdev *rdev; ++ bool enabled; ++}; ++ ++/* Module context */ ++struct stm32_regu_consumer_ctx { ++ struct stm32_regu_consumer_dev_ctx *dev_ctx_table; ++ unsigned int dev_count; ++}; ++ ++/* A single instance handles all voltage regulators abstracted by regulator.h */ ++static struct stm32_regu_consumer_ctx module_ctx; ++ ++static char *regu_name(struct rdev *rdev) ++{ ++ if (rdev) ++ return (char *)rdev->reg_name; ++ ++ return NULL; ++} ++ ++static int find_ctx(fwk_id_t dev_id, ++ struct stm32_regu_consumer_dev_ctx **out_ctx) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ ++ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(dev_id); ++ ++ if (!fwk_module_is_valid_element_id(dev_id)) ++ return FWK_E_PARAM; ++ ++ if (!ctx->rdev) ++ return FWK_E_ACCESS; ++ ++ *out_ctx = ctx; ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_get_config(fwk_id_t dev_id, uint8_t *mode_type, ++ uint8_t *mode_id) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ *mode_type = MOD_VOLTD_MODE_TYPE_ARCH; ++ ++ if (ctx->enabled) ++ *mode_id = MOD_VOLTD_MODE_ID_ON; ++ else ++ *mode_id = MOD_VOLTD_MODE_ID_OFF; ++ ++ DEBUG_MSG("SCMI voltd %u: get config PMIC %s = %#"PRIx8", %#"PRIx8, ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *mode_type, ++ *mode_id); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_set_config(fwk_id_t dev_id, uint8_t mode_type, ++ uint8_t mode_id) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ if (mode_type != MOD_VOLTD_MODE_TYPE_ARCH) { ++ return FWK_E_PARAM; ++ } ++ ++ switch (mode_id) { ++ case MOD_VOLTD_MODE_ID_ON: ++ if (!ctx->enabled) { ++ if (regulator_enable(ctx->rdev)) ++ return FWK_E_DEVICE; ++ ++ ctx->enabled = true; ++ } ++ break; ++ ++ case MOD_VOLTD_MODE_ID_OFF: ++ if (ctx->enabled) { ++ if (regulator_disable(ctx->rdev)) ++ return FWK_E_DEVICE; ++ ++ ctx->enabled = false; ++ } ++ break; ++ ++ default: ++ return FWK_E_PARAM; ++ } ++ ++ DEBUG_MSG("SCMI voltd %u: set config PMIC %s to type %#"PRIx8" / mode %#"PRIx8, ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), mode_type, ++ mode_id); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_get_level(fwk_id_t dev_id, int *level_uv) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ uint16_t level_mv; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ if (regulator_get_voltage(ctx->rdev, &level_mv)) ++ return FWK_E_PANIC; ++ ++ *level_uv = (int)level_mv * 1000; ++ ++ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %d", ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_set_level(fwk_id_t dev_id, int level_uv) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx = NULL; ++ int ret = FWK_E_PANIC; ++ ++ if (level_uv / 1000 > UINT16_MAX) { ++ FWK_LOG_ERR("Volatge level too high (mV shall fit in 16 bits)"); ++ return FWK_E_PARAM; ++ } ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret) ++ return ret; ++ ++ if (regulator_set_voltage(ctx->rdev, level_uv / 1000)) ++ return FWK_E_DEVICE; ++ ++ DEBUG_MSG("SCMI voltd %u: set level PMIC %s to %d", ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), level_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static void find_bound_uv(const uint16_t *levels, size_t count, ++ int32_t *min, int32_t *max) ++{ ++ size_t n = 0; ++ ++ *min = INT32_MAX; ++ *max = INT32_MIN; ++ ++ for (n = 0; n < count; n++) { ++ if (*min > levels[n]) { ++ *min = levels[n]; ++ } ++ if (*max < levels[n]) { ++ *max = levels[n]; ++ } ++ } ++ ++ /* Convert from mV to uV */ ++ *min *= 1000; ++ *max *= 1000; ++} ++ ++static int stm32_regu_consumer_get_info(fwk_id_t dev_id, ++ struct mod_voltd_info *info) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ uint16_t *levels; ++ size_t full_count; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret == FWK_E_ACCESS) { ++ static const char reserved[] = "reserved"; ++ ++ memset(info, 0, sizeof(*info)); ++ info->name = reserved; ++ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; ++ info->level_range.level_count = 1; ++ info->level_range.min_uv = 0; ++ info->level_range.max_uv = 0; ++ ++ return FWK_SUCCESS; ++ } else if (ret != FWK_SUCCESS) { ++ return ret; ++ } ++ ++ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { ++ return FWK_E_SUPPORT; ++ } ++ ++ memset(info, 0, sizeof(*info)); ++ info->name = regu_name(ctx->rdev); ++ info->level_range.level_type = MOD_VOLTD_VOLTAGE_LEVEL_DISCRETE; ++ info->level_range.level_count = full_count; ++ find_bound_uv(levels, full_count, ++ &info->level_range.min_uv, &info->level_range.max_uv); ++ ++ DEBUG_MSG("SCMI voltd %u: get_info PMIC %s, range [%d %d]", ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), ++ info->level_range.min_uv, info->level_range.max_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_level_from_index(fwk_id_t dev_id, ++ unsigned int index, ++ int32_t *level_uv) ++{ ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ uint16_t *levels; ++ size_t full_count; ++ int ret; ++ ++ ret = find_ctx(dev_id, &ctx); ++ if (ret == FWK_E_ACCESS) { ++ if (index > 0) { ++ return FWK_E_RANGE; ++ } ++ *level_uv = 0; ++ ++ return FWK_SUCCESS; ++ } else if (ret != FWK_SUCCESS) { ++ return ret; ++ } ++ ++ if (regulator_list_voltages(ctx->rdev, &levels, &full_count)) { ++ return FWK_E_SUPPORT; ++ } ++ ++ if (index >= full_count) ++ return FWK_E_RANGE; ++ ++ *level_uv = (int32_t)levels[index] * 1000; ++ ++ DEBUG_MSG("SCMI voltd %u: get level PMIC %s = %"PRId32, ++ fwk_id_get_element_idx(dev_id), regu_name(ctx->rdev), *level_uv); ++ ++ return FWK_SUCCESS; ++} ++ ++static const struct mod_voltd_drv_api api_optee_regu = { ++ .get_level = stm32_regu_consumer_get_level, ++ .set_level = stm32_regu_consumer_set_level, ++ .set_config = stm32_regu_consumer_set_config, ++ .get_config = stm32_regu_consumer_get_config, ++ .get_info = stm32_regu_consumer_get_info, ++ .get_level_from_index = stm32_regu_consumer_level_from_index, ++}; ++ ++/* ++ * Framework handler functions ++ */ ++ ++static int stm32_regu_consumer_init(fwk_id_t module_id, ++ unsigned int element_count, ++ const void *data) ++{ ++ module_ctx.dev_count = element_count; ++ ++ if (element_count) ++ module_ctx.dev_ctx_table = ++ fwk_mm_calloc(element_count, sizeof(*module_ctx.dev_ctx_table)); ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_element_init(fwk_id_t element_id, ++ unsigned int unused, ++ const void *data) ++{ ++ const struct mod_stm32_regu_consumer_dev_config *dev_config = data; ++ struct stm32_regu_consumer_dev_ctx *ctx; ++ ++ if (!fwk_module_is_valid_element_id(element_id)) ++ return FWK_E_PANIC; ++ ++ ctx = module_ctx.dev_ctx_table + fwk_id_get_element_idx(element_id); ++ ++ ctx->rdev = dev_config->rdev; ++ ctx->enabled = dev_config->default_enabled; ++ ++ if (ctx->enabled) { ++ if (!ctx->rdev) ++ return FWK_E_PARAM; ++ if (regulator_enable(ctx->rdev)) ++ return FWK_E_DEVICE; ++ } ++ ++ return FWK_SUCCESS; ++} ++ ++static int stm32_regu_consumer_process_bind_request(fwk_id_t requester_id, ++ fwk_id_t target_id, ++ fwk_id_t api_type, ++ const void **api) ++{ ++ *api = &api_optee_regu; ++ ++ return FWK_SUCCESS; ++} ++ ++const struct fwk_module module_stm32_regu_consumer = { ++ .type = FWK_MODULE_TYPE_DRIVER, ++ .api_count = 1, ++ .init = stm32_regu_consumer_init, ++ .element_init = stm32_regu_consumer_element_init, ++ .process_bind_request = stm32_regu_consumer_process_bind_request, ++}; +-- +2.34.1 + diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch new file mode 100644 index 000000000..1943abcbb --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/0001-Correct-git-error.patch @@ -0,0 +1,32 @@ +From 27dd5642469b49aa6a94d99d97bce793f2473053 Mon Sep 17 00:00:00 2001 +From: Christophe Priouzeau +Date: Tue, 28 Nov 2023 14:18:02 +0100 +Subject: [PATCH] Correct git error + +When there is no .git for scp firmware, the git describe command +return error: +fatal: not a git repository (or any parent up to mount point /mnt) +Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set). + +To correct this kind of error, we can redirect the error on a variable + +Signed-off-by: Christophe Priouzeau +--- + framework/CMakeLists.txt | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt +index 9b9bb229..9a9f0bd4 100644 +--- a/framework/CMakeLists.txt ++++ b/framework/CMakeLists.txt +@@ -197,6 +197,7 @@ if(GIT_FOUND) + COMMAND "${GIT_EXECUTABLE}" describe --tags --dirty --always + WORKING_DIRECTORY "${SCP_SOURCE_DIR}" + OUTPUT_VARIABLE SCP_DESCRIBE ++ ERROR_VARIABLE _errorOut + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + +-- +2.34.1 + diff --git a/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt new file mode 100644 index 000000000..579be8b66 --- /dev/null +++ b/meta-digi-arm/dynamic-layers/stm-st-stm32mp/recipes-security/scp-firmware/scp-firmware/README.HOW_TO.txt @@ -0,0 +1,56 @@ +Sharing scp firmware +1. Prepare scp firmware source +2. Manage scp firmware source code with GIT +3. Configure scp firmware source code +4. Test scp firmware source code + +-------------------------------------- +1. Prepare scp-firmware source +-------------------------------------- +If not already done, extract the sources from Developer Package tarball, for example: + $ tar xf en.SOURCES-stm32mp1-*.tar.xz + +In the scp firmware source directory (sources/*/##BP##-##PR##), +you have one external dt tarball: + - ##BP##-##PR##.tar.xz + - 00*.patch + +If you would like to have a git management for the source code move to +to section 2 [Management of external dt source code with GIT]. + +Otherwise, to manage scp firmware source code without git, you must extract the +tarball now and apply the patch: + + $> tar xf ##BP##-##PR##.tar.xz + $> cd ##BP## + $> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done + +You can now move to section 3 [Configure scp firmware source code]. + +------------------------------------- +2. Manage external dt source code with GIT +------------------------------------- +If you like to have a better management of change made on external dt source, you +have following solutions to use git. + +2.1 Create Git from tarball +--------------------------- + $ cd + $ test -d .git || git init . && git add . && git commit -m "new scp-firwmare" && git gc + $ git checkout -b WORKING + NB: this is the fastest way to get your scp firmware source code ready for development + +------------------------------- +3. Configure scp firmware source code +------------------------------- +To enable use of scp firmware source code for other component, you must set the +SCPFW_DIR variable to your shell environement: + + $> export SCPFW_DIR=$PWD/##BP## + +--------------------------- +4. Test scp firmware source code +--------------------------- +Nothing to do, scp-firmware is directly used by other component. + + #> echo "*** Nothing to test ***" diff --git a/meta-digi-arm/dynamic-layers/wolfssl/recipes-examples/wolfcrypt/wolfcrypttest.bbappend b/meta-digi-arm/dynamic-layers/wolfssl/recipes-examples/wolfcrypt/wolfcrypttest.bbappend index 5f1bcbe26..b9bff6dfd 100644 --- a/meta-digi-arm/dynamic-layers/wolfssl/recipes-examples/wolfcrypt/wolfcrypttest.bbappend +++ b/meta-digi-arm/dynamic-layers/wolfssl/recipes-examples/wolfcrypt/wolfcrypttest.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Digi International +# Copyright (C) 2022, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend index ba1711a9b..daeda912b 100644 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend +++ b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2023 Digi International. +# Copyright (C) 2013-2024, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" @@ -10,12 +10,6 @@ SRC_URI:append:ccimx6 = " \ file://asound.play.state \ " -SRC_URI:append:ccimx6ul = " file://asound.state" -SRC_URI:append:ccimx8x = " file://asound.state" -SRC_URI:append:ccimx8m = " file://asound.state" -SRC_URI:append:ccimx93 = " file://asound.state" -SRC_URI:append:ccmp1 = " file://asound.state" - do_install:append:ccimx6() { ln -sf asound.micro_play.state ${D}${localstatedir}/lib/alsa/asound.state } diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx93/asound.conf b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx9/asound.conf similarity index 100% rename from meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx93/asound.conf rename to meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx9/asound.conf diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx93/asound.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx9/asound.state similarity index 100% rename from meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx93/asound.state rename to meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccimx9/asound.state diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp1/asound.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp1/asound.state index dd7d64b01..7bdf13e59 100644 --- a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp1/asound.state +++ b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp1/asound.state @@ -119,7 +119,7 @@ state.stm32max98088 { control.10 { iface MIXER name 'MIC2 Boost Volume' - value 1 + value 0 comment { access 'read write' type INTEGER @@ -127,13 +127,13 @@ state.stm32max98088 { range '0 - 2' dbmin 0 dbmax 3000 - dbvalue.0 2000 + dbvalue.0 0 } } control.11 { iface MIXER name 'INA Volume' - value 4 + value 0 comment { access 'read write' type INTEGER @@ -144,7 +144,7 @@ state.stm32max98088 { control.12 { iface MIXER name 'INB Volume' - value 0 + value 4 comment { access 'read write' type INTEGER @@ -417,7 +417,7 @@ state.stm32max98088 { } control.35 { iface MIXER - name 'REC Output Mode' + name 'Left HP Mixer Left DAC1 Switch' value true comment { access 'read write' @@ -427,8 +427,8 @@ state.stm32max98088 { } control.36 { iface MIXER - name 'Right ADC Mixer MIC1 Switch' - value false + name 'Left HP Mixer Right DAC1 Switch' + value true comment { access 'read write' type BOOLEAN @@ -436,636 +436,6 @@ state.stm32max98088 { } } control.37 { - iface MIXER - name 'Right ADC Mixer MIC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.38 { - iface MIXER - name 'Right ADC Mixer INA1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.39 { - iface MIXER - name 'Right ADC Mixer INA2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.40 { - iface MIXER - name 'Right ADC Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.41 { - iface MIXER - name 'Right ADC Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.42 { - iface MIXER - name 'Left ADC Mixer MIC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.43 { - iface MIXER - name 'Left ADC Mixer MIC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.44 { - iface MIXER - name 'Left ADC Mixer INA1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.45 { - iface MIXER - name 'Left ADC Mixer INA2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.46 { - iface MIXER - name 'Left ADC Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.47 { - iface MIXER - name 'Left ADC Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.48 { - iface MIXER - name 'Right REC Mixer Left DAC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.49 { - iface MIXER - name 'Right REC Mixer Right DAC1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.50 { - iface MIXER - name 'Right REC Mixer Left DAC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.51 { - iface MIXER - name 'Right REC Mixer Right DAC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.52 { - iface MIXER - name 'Right REC Mixer MIC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.53 { - iface MIXER - name 'Right REC Mixer MIC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.54 { - iface MIXER - name 'Right REC Mixer INA1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.55 { - iface MIXER - name 'Right REC Mixer INA2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.56 { - iface MIXER - name 'Right REC Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.57 { - iface MIXER - name 'Right REC Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.58 { - iface MIXER - name 'Left REC Mixer Left DAC1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.59 { - iface MIXER - name 'Left REC Mixer Right DAC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.60 { - iface MIXER - name 'Left REC Mixer Left DAC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.61 { - iface MIXER - name 'Left REC Mixer Right DAC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.62 { - iface MIXER - name 'Left REC Mixer MIC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.63 { - iface MIXER - name 'Left REC Mixer MIC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.64 { - iface MIXER - name 'Left REC Mixer INA1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.65 { - iface MIXER - name 'Left REC Mixer INA2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.66 { - iface MIXER - name 'Left REC Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.67 { - iface MIXER - name 'Left REC Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.68 { - iface MIXER - name 'Right SPK Mixer Left DAC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.69 { - iface MIXER - name 'Right SPK Mixer Right DAC1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.70 { - iface MIXER - name 'Right SPK Mixer Left DAC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.71 { - iface MIXER - name 'Right SPK Mixer Right DAC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.72 { - iface MIXER - name 'Right SPK Mixer MIC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.73 { - iface MIXER - name 'Right SPK Mixer MIC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.74 { - iface MIXER - name 'Right SPK Mixer INA1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.75 { - iface MIXER - name 'Right SPK Mixer INA2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.76 { - iface MIXER - name 'Right SPK Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.77 { - iface MIXER - name 'Right SPK Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.78 { - iface MIXER - name 'Left SPK Mixer Left DAC1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.79 { - iface MIXER - name 'Left SPK Mixer Right DAC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.80 { - iface MIXER - name 'Left SPK Mixer Left DAC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.81 { - iface MIXER - name 'Left SPK Mixer Right DAC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.82 { - iface MIXER - name 'Left SPK Mixer MIC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.83 { - iface MIXER - name 'Left SPK Mixer MIC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.84 { - iface MIXER - name 'Left SPK Mixer INA1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.85 { - iface MIXER - name 'Left SPK Mixer INA2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.86 { - iface MIXER - name 'Left SPK Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.87 { - iface MIXER - name 'Left SPK Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.88 { - iface MIXER - name 'Right HP Mixer Left DAC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.89 { - iface MIXER - name 'Right HP Mixer Right DAC1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.90 { - iface MIXER - name 'Right HP Mixer Left DAC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.91 { - iface MIXER - name 'Right HP Mixer Right DAC2 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.92 { - iface MIXER - name 'Right HP Mixer MIC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.93 { - iface MIXER - name 'Right HP Mixer MIC2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.94 { - iface MIXER - name 'Right HP Mixer INA1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.95 { - iface MIXER - name 'Right HP Mixer INA2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.96 { - iface MIXER - name 'Right HP Mixer INB1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.97 { - iface MIXER - name 'Right HP Mixer INB2 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.98 { - iface MIXER - name 'Left HP Mixer Left DAC1 Switch' - value true - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.99 { - iface MIXER - name 'Left HP Mixer Right DAC1 Switch' - value false - comment { - access 'read write' - type BOOLEAN - count 1 - } - } - control.100 { iface MIXER name 'Left HP Mixer Left DAC2 Switch' value true @@ -1075,17 +445,17 @@ state.stm32max98088 { count 1 } } - control.101 { + control.38 { iface MIXER name 'Left HP Mixer Right DAC2 Switch' - value false + value true comment { access 'read write' type BOOLEAN count 1 } } - control.102 { + control.39 { iface MIXER name 'Left HP Mixer MIC1 Switch' value false @@ -1095,17 +465,17 @@ state.stm32max98088 { count 1 } } - control.103 { + control.40 { iface MIXER name 'Left HP Mixer MIC2 Switch' - value false + value true comment { access 'read write' type BOOLEAN count 1 } } - control.104 { + control.41 { iface MIXER name 'Left HP Mixer INA1 Switch' value false @@ -1115,17 +485,17 @@ state.stm32max98088 { count 1 } } - control.105 { + control.42 { iface MIXER name 'Left HP Mixer INA2 Switch' - value false + value true comment { access 'read write' type BOOLEAN count 1 } } - control.106 { + control.43 { iface MIXER name 'Left HP Mixer INB1 Switch' value false @@ -1135,9 +505,19 @@ state.stm32max98088 { count 1 } } - control.107 { + control.44 { iface MIXER name 'Left HP Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.45 { + iface MIXER + name 'Right HP Mixer Left DAC1 Switch' value false comment { access 'read write' @@ -1145,4 +525,614 @@ state.stm32max98088 { count 1 } } + control.46 { + iface MIXER + name 'Right HP Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.47 { + iface MIXER + name 'Right HP Mixer Left DAC2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.48 { + iface MIXER + name 'Right HP Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.49 { + iface MIXER + name 'Right HP Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.50 { + iface MIXER + name 'Right HP Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.51 { + iface MIXER + name 'Right HP Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.52 { + iface MIXER + name 'Right HP Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.53 { + iface MIXER + name 'Right HP Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.54 { + iface MIXER + name 'Right HP Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.55 { + iface MIXER + name 'Left SPK Mixer Left DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.56 { + iface MIXER + name 'Left SPK Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.57 { + iface MIXER + name 'Left SPK Mixer Left DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.58 { + iface MIXER + name 'Left SPK Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.59 { + iface MIXER + name 'Left SPK Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.60 { + iface MIXER + name 'Left SPK Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.61 { + iface MIXER + name 'Left SPK Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.62 { + iface MIXER + name 'Left SPK Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.63 { + iface MIXER + name 'Left SPK Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.64 { + iface MIXER + name 'Left SPK Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.65 { + iface MIXER + name 'Right SPK Mixer Left DAC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.66 { + iface MIXER + name 'Right SPK Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.67 { + iface MIXER + name 'Right SPK Mixer Left DAC2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.68 { + iface MIXER + name 'Right SPK Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.69 { + iface MIXER + name 'Right SPK Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.70 { + iface MIXER + name 'Right SPK Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.71 { + iface MIXER + name 'Right SPK Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.72 { + iface MIXER + name 'Right SPK Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.73 { + iface MIXER + name 'Right SPK Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.74 { + iface MIXER + name 'Right SPK Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.75 { + iface MIXER + name 'Left REC Mixer Left DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.76 { + iface MIXER + name 'Left REC Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.77 { + iface MIXER + name 'Left REC Mixer Left DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.78 { + iface MIXER + name 'Left REC Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.79 { + iface MIXER + name 'Left REC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.80 { + iface MIXER + name 'Left REC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.81 { + iface MIXER + name 'Left REC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.82 { + iface MIXER + name 'Left REC Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.83 { + iface MIXER + name 'Left REC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.84 { + iface MIXER + name 'Left REC Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.85 { + iface MIXER + name 'Right REC Mixer Left DAC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.86 { + iface MIXER + name 'Right REC Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.87 { + iface MIXER + name 'Right REC Mixer Left DAC2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.88 { + iface MIXER + name 'Right REC Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.89 { + iface MIXER + name 'Right REC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.90 { + iface MIXER + name 'Right REC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.91 { + iface MIXER + name 'Right REC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.92 { + iface MIXER + name 'Right REC Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.93 { + iface MIXER + name 'Right REC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.94 { + iface MIXER + name 'Right REC Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.95 { + iface MIXER + name 'Left ADC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.96 { + iface MIXER + name 'Left ADC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.97 { + iface MIXER + name 'Left ADC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.98 { + iface MIXER + name 'Left ADC Mixer INA2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.99 { + iface MIXER + name 'Left ADC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.100 { + iface MIXER + name 'Left ADC Mixer INB2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.101 { + iface MIXER + name 'Right ADC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.102 { + iface MIXER + name 'Right ADC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.103 { + iface MIXER + name 'Right ADC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.104 { + iface MIXER + name 'Right ADC Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.105 { + iface MIXER + name 'Right ADC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.106 { + iface MIXER + name 'Right ADC Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } } diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp2/asound.conf b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp2/asound.conf new file mode 100644 index 000000000..ee8c123e8 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp2/asound.conf @@ -0,0 +1,9 @@ +pcm.ccmp25dvk { + type hw + card 0 +} +ctl.ccmp25dvk { + type hw + card 0 +} +ctl.!default ccmp25dvk diff --git a/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp2/asound.state b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp2/asound.state new file mode 100644 index 000000000..780b93d4d --- /dev/null +++ b/meta-digi-arm/recipes-bsp/alsa-state/alsa-state/ccmp2/asound.state @@ -0,0 +1,1149 @@ +state.ccmp25dvk { + control.1 { + iface MIXER + name 'Headphone Volume' + value.0 18 + value.1 18 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 31' + dbmin -6700 + dbmax 300 + dbvalue.0 -1100 + dbvalue.1 -1100 + } + } + control.2 { + iface MIXER + name 'Speaker Volume' + value.0 16 + value.1 16 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 31' + dbmin -6200 + dbmax 800 + dbvalue.0 -1000 + dbvalue.1 -1000 + } + } + control.3 { + iface MIXER + name 'Receiver Volume' + value.0 16 + value.1 16 + comment { + access 'read write' + type INTEGER + count 2 + range '0 - 31' + dbmin -6200 + dbmax 800 + dbvalue.0 -1000 + dbvalue.1 -1000 + } + } + control.4 { + iface MIXER + name 'Headphone Switch' + value.0 true + value.1 true + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.5 { + iface MIXER + name 'Speaker Switch' + value.0 true + value.1 true + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.6 { + iface MIXER + name 'Receiver Switch' + value.0 true + value.1 true + comment { + access 'read write' + type BOOLEAN + count 2 + } + } + control.7 { + iface MIXER + name 'MIC1 Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + } + } + control.8 { + iface MIXER + name 'MIC2 Volume' + value 15 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 31' + } + } + control.9 { + iface MIXER + name 'MIC1 Boost Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 2' + dbmin 0 + dbmax 3000 + dbvalue.0 0 + } + } + control.10 { + iface MIXER + name 'MIC2 Boost Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 2' + dbmin 0 + dbmax 3000 + dbvalue.0 0 + } + } + control.11 { + iface MIXER + name 'Noise Gate Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.12 { + iface MIXER + name 'INA Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.13 { + iface MIXER + name 'INB Volume' + value 4 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.14 { + iface MIXER + name 'ADCL Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.15 { + iface MIXER + name 'ADCR Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.16 { + iface MIXER + name 'ADCL Boost Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + } + } + control.17 { + iface MIXER + name 'ADCR Boost Volume' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 3' + } + } + control.18 { + iface MIXER + name 'EQ1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.19 { + iface MIXER + name 'EQ2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.20 { + iface MIXER + name 'EX Limiter Mode' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 '100Hz' + item.2 '400Hz' + item.3 '600Hz' + item.4 '800Hz' + item.5 '1000Hz' + item.6 '200-400Hz' + item.7 '400-600Hz' + item.8 '400-800Hz' + } + } + control.21 { + iface MIXER + name 'EX Limiter Threshold' + value '0.6' + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 '0.6' + item.1 '1.2' + item.2 '1.8' + item.3 '2.4' + item.4 '3.0' + item.5 '3.6' + item.6 '4.2' + item.7 '4.8' + } + } + control.22 { + iface MIXER + name 'DAI1 Filter Mode' + value Music + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Voice + item.1 Music + } + } + control.23 { + iface MIXER + name 'DAI1 DAC Filter' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 'fc=258/fs=16k' + item.2 'fc=500/fs=16k' + item.3 'fc=258/fs=8k' + item.4 'fc=500/fs=8k' + item.5 'fc=200' + } + } + control.24 { + iface MIXER + name 'DAI1 ADC Filter' + value Off + comment { + access 'read write' + type ENUMERATED + count 1 + item.0 Off + item.1 'fc=258/fs=16k' + item.2 'fc=500/fs=16k' + item.3 'fc=258/fs=8k' + item.4 'fc=500/fs=8k' + item.5 'fc=200' + } + } + control.25 { + iface MIXER + name 'DAI2 DC Block Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.26 { + iface MIXER + name 'ALC Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.27 { + iface MIXER + name 'ALC Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.28 { + iface MIXER + name 'ALC Multiband' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.29 { + iface MIXER + name 'ALC Release Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.30 { + iface MIXER + name 'PWR Limiter Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.31 { + iface MIXER + name 'PWR Limiter Weight' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.32 { + iface MIXER + name 'PWR Limiter Time1' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.33 { + iface MIXER + name 'PWR Limiter Time2' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.34 { + iface MIXER + name 'THD Limiter Threshold' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 15' + } + } + control.35 { + iface MIXER + name 'THD Limiter Time' + value 0 + comment { + access 'read write' + type INTEGER + count 1 + range '0 - 7' + } + } + control.36 { + iface MIXER + name 'Left HP Mixer Left DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.37 { + iface MIXER + name 'Left HP Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.38 { + iface MIXER + name 'Left HP Mixer Left DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.39 { + iface MIXER + name 'Left HP Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.40 { + iface MIXER + name 'Left HP Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.41 { + iface MIXER + name 'Left HP Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.42 { + iface MIXER + name 'Left HP Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.43 { + iface MIXER + name 'Left HP Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.44 { + iface MIXER + name 'Left HP Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.45 { + iface MIXER + name 'Left HP Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.46 { + iface MIXER + name 'Right HP Mixer Left DAC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.47 { + iface MIXER + name 'Right HP Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.48 { + iface MIXER + name 'Right HP Mixer Left DAC2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.49 { + iface MIXER + name 'Right HP Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.50 { + iface MIXER + name 'Right HP Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.51 { + iface MIXER + name 'Right HP Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.52 { + iface MIXER + name 'Right HP Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.53 { + iface MIXER + name 'Right HP Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.54 { + iface MIXER + name 'Right HP Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.55 { + iface MIXER + name 'Right HP Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.56 { + iface MIXER + name 'Left SPK Mixer Left DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.57 { + iface MIXER + name 'Left SPK Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.58 { + iface MIXER + name 'Left SPK Mixer Left DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.59 { + iface MIXER + name 'Left SPK Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.60 { + iface MIXER + name 'Left SPK Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.61 { + iface MIXER + name 'Left SPK Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.62 { + iface MIXER + name 'Left SPK Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.63 { + iface MIXER + name 'Left SPK Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.64 { + iface MIXER + name 'Left SPK Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.65 { + iface MIXER + name 'Left SPK Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.66 { + iface MIXER + name 'Right SPK Mixer Left DAC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.67 { + iface MIXER + name 'Right SPK Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.68 { + iface MIXER + name 'Right SPK Mixer Left DAC2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.69 { + iface MIXER + name 'Right SPK Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.70 { + iface MIXER + name 'Right SPK Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.71 { + iface MIXER + name 'Right SPK Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.72 { + iface MIXER + name 'Right SPK Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.73 { + iface MIXER + name 'Right SPK Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.74 { + iface MIXER + name 'Right SPK Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.75 { + iface MIXER + name 'Right SPK Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.76 { + iface MIXER + name 'Left REC Mixer Left DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.77 { + iface MIXER + name 'Left REC Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.78 { + iface MIXER + name 'Left REC Mixer Left DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.79 { + iface MIXER + name 'Left REC Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.80 { + iface MIXER + name 'Left REC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.81 { + iface MIXER + name 'Left REC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.82 { + iface MIXER + name 'Left REC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.83 { + iface MIXER + name 'Left REC Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.84 { + iface MIXER + name 'Left REC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.85 { + iface MIXER + name 'Left REC Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.86 { + iface MIXER + name 'Right REC Mixer Left DAC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.87 { + iface MIXER + name 'Right REC Mixer Right DAC1 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.88 { + iface MIXER + name 'Right REC Mixer Left DAC2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.89 { + iface MIXER + name 'Right REC Mixer Right DAC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.90 { + iface MIXER + name 'Right REC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.91 { + iface MIXER + name 'Right REC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.92 { + iface MIXER + name 'Right REC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.93 { + iface MIXER + name 'Right REC Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.94 { + iface MIXER + name 'Right REC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.95 { + iface MIXER + name 'Right REC Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.96 { + iface MIXER + name 'Left ADC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.97 { + iface MIXER + name 'Left ADC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.98 { + iface MIXER + name 'Left ADC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.99 { + iface MIXER + name 'Left ADC Mixer INA2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.100 { + iface MIXER + name 'Left ADC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.101 { + iface MIXER + name 'Left ADC Mixer INB2 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.102 { + iface MIXER + name 'Right ADC Mixer MIC1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.103 { + iface MIXER + name 'Right ADC Mixer MIC2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.104 { + iface MIXER + name 'Right ADC Mixer INA1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.105 { + iface MIXER + name 'Right ADC Mixer INA2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.106 { + iface MIXER + name 'Right ADC Mixer INB1 Switch' + value false + comment { + access 'read write' + type BOOLEAN + count 1 + } + } + control.107 { + iface MIXER + name 'Right ADC Mixer INB2 Switch' + value true + comment { + access 'read write' + type BOOLEAN + count 1 + } + } +} diff --git a/meta-digi-arm/recipes-bsp/ath-prop-tools/ath-prop-tools_3.4p4.bb b/meta-digi-arm/recipes-bsp/ath-prop-tools/ath-prop-tools_3.4p4.bb index 58b8967e4..fb677d99b 100644 --- a/meta-digi-arm/recipes-bsp/ath-prop-tools/ath-prop-tools_3.4p4.bb +++ b/meta-digi-arm/recipes-bsp/ath-prop-tools/ath-prop-tools_3.4p4.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2021 Digi International. +# Copyright (C) 2013-2021, Digi International Inc. SUMMARY = "Atheros' proprietary tools" LICENSE = "Proprietary" diff --git a/meta-digi-arm/recipes-bsp/digi-sc-firmware/digi-sc-firmware_1.15.0.1.bb b/meta-digi-arm/recipes-bsp/digi-sc-firmware/digi-sc-firmware_1.15.0.1.bb index 243bbd112..043a6d077 100644 --- a/meta-digi-arm/recipes-bsp/digi-sc-firmware/digi-sc-firmware_1.15.0.1.bb +++ b/meta-digi-arm/recipes-bsp/digi-sc-firmware/digi-sc-firmware_1.15.0.1.bb @@ -1,6 +1,6 @@ # Copyright (C) 2016 Freescale Semiconductor # Copyright 2017-2018 NXP -# Copyright (C) 2018-2024 Digi International. +# Copyright (C) 2018-2024, Digi International Inc. DESCRIPTION = "i.MX System Controller Firmware, customized for Digi platforms" LICENSE = "Proprietary" diff --git a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb index d548bb640..f90d6153c 100644 --- a/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb +++ b/meta-digi-arm/recipes-bsp/firmware-atheros/firmware-atheros.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2017 Digi International. +# Copyright (C) 2013-2017, Digi International Inc. SUMMARY = "Firmware files for Digi's platforms, such as Atheros bluetooth." SECTION = "base" diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon.bb b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon.bb index ac9f11d92..c1f4b5354 100644 --- a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon.bb +++ b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2024 Digi International Inc. +# Copyright (C) 2022-2024, Digi International Inc. SUMMARY = "Murata Infineon firmware binaries" SECTION = "base" @@ -15,6 +15,13 @@ SRC_URI = " \ file://cyfmac4373-sdio_World.clm_blob \ file://cyw4373-autocountry \ file://cyw4373-autocountry.service \ + file://cyfmac55500-sdio.txt \ + file://cyfmac55500-sdio_US.clm_blob \ + file://cyfmac55500-sdio.trxse \ + file://CYW55500A1_001.002.032.0121.0000_Generic_UART_37_4MHz_wlbga_iPA_sLNA_ANT0.hcd \ + file://cyw55512-bluetooth \ + file://cyw55512-bluetooth.service \ + file://mbt \ " SRCREV_cyw-fmac-fw="db8deb03b8d24e5069ac4581d1c35b767012e926" @@ -31,9 +38,36 @@ DEPENDS = "libnl" do_install () { bbnote "Installing Murata Infineon firmware binaries: " + install -d ${D}${sbindir} + + if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then + # Install systemd unit files + install -d ${D}${systemd_unitdir}/system/ + install -m 0644 ${WORKDIR}/cyw4373-autocountry.service ${D}${systemd_unitdir}/system/cyw4373-autocountry.service + install -m 0644 ${WORKDIR}/cyw55512-bluetooth.service ${D}${systemd_unitdir}/system/cyw55512-bluetooth.service + fi + + install -d ${D}${sysconfdir}/init.d/ + + # Install autocountry service + install -m 0755 ${WORKDIR}/cyw4373-autocountry ${D}${sysconfdir}/cyw4373-autocountry + ln -sf /etc/cyw4373-autocountry ${D}${sysconfdir}/init.d/cyw4373-autocountry + + # Install bluetooth init service + install -m 0755 ${WORKDIR}/cyw55512-bluetooth ${D}${sysconfdir}/cyw55512-bluetooth + ln -sf /etc/cyw55512-bluetooth ${D}${sysconfdir}/init.d/cyw55512-bluetooth + + # Install WLAN client utility binary based on 32-bit/64-bit arch + if [ ${TARGET_ARCH} = "aarch64" ]; then + install -m 755 ${S}/cyw-fmac-utils-imx64/wl ${D}${sbindir} + else + install -m 755 ${S}/cyw-fmac-utils-imx32/wl ${D}${sbindir} + fi +} + +do_install:append:ccmp1 () { install -d ${D}${base_libdir}/firmware/cypress install -d ${D}${base_libdir}/firmware/brcm - install -d ${D}${sbindir} # Install Bluetooth patch *.HCD file # For Murata 2AE (LBEE5PK2AE-564) @@ -49,37 +83,45 @@ do_install () { # Install NVRAM files (*.txt) # For Murata 2AE (LBEE5PK2AE-564) install -m 444 ${S}/cyw-fmac-nvram/cyfmac4373-sdio.2AE.txt ${D}${base_libdir}/firmware/cypress/cyfmac4373-sdio.txt +} - # Install WLAN client utility binary based on 32-bit/64-bit arch - if [ ${TARGET_ARCH} = "aarch64" ]; then - install -m 755 ${S}/cyw-fmac-utils-imx64/wl ${D}${sbindir} - else - install -m 755 ${S}/cyw-fmac-utils-imx32/wl ${D}${sbindir} - fi +do_install:append:ccmp2 () { + install -d ${D}${base_libdir}/firmware/cypress + install -d ${D}${base_libdir}/firmware/brcm - if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then - # Install systemd unit files - install -d ${D}${systemd_unitdir}/system/ - install -m 0644 ${WORKDIR}/cyw4373-autocountry.service ${D}${systemd_unitdir}/system/cyw4373-autocountry.service - fi + # Install Bluetooth patch *.HCD file + # For Murata 2GY (LBEE5HY2GY-SMP) + install -m 444 CYW55500A1_001.002.032.0121.0000_Generic_UART_37_4MHz_wlbga_iPA_sLNA_ANT0.hcd ${D}${base_libdir}/firmware/brcm/CYW55500A1.hcd - install -d ${D}${sysconfdir}/init.d/ - install -m 0755 ${WORKDIR}/cyw4373-autocountry ${D}${sysconfdir}/cyw4373-autocountry - ln -sf /etc/cyw4373-autocountry ${D}${sysconfdir}/init.d/cyw4373-autocountry + # Install WLAN firmware file (*.bin) and Regulatory binary file (*.clm_blob) + # For Murata 2GY (LBEE5HY2GY-SMP) + install -m 444 cyfmac55500-sdio.trxse ${D}${base_libdir}/firmware/cypress/cyfmac55500-sdio.trxse + install -m 444 cyfmac55500-sdio_US.clm_blob ${D}${base_libdir}/firmware/cypress/cyfmac55500-sdio_US.clm_blob + + # Install NVRAM files (*.txt) + # For Murata 2GY (LBEE5HY2GY-SMP) + install -m 444 cyfmac55500-sdio.txt ${D}${base_libdir}/firmware/cypress/cyfmac55500-sdio.txt + + # Install Manufacturing Bluetooth Test tool (MBT) + install -m 755 mbt ${D}${sbindir} } inherit update-rc.d systemd -INITSCRIPT_PACKAGES += "${PN}-autocountry" +INITSCRIPT_PACKAGES += "${PN}-autocountry ${PN}-bluetooth" INITSCRIPT_NAME:${PN}-autocountry = "cyw4373-autocountry" INITSCRIPT_PARAMS:${PN}-autocountry = "start 19 2 3 4 5 . stop 21 0 1 6 ." +INITSCRIPT_NAME:${PN}-bluetooth = "cyw55512-bluetooth" +INITSCRIPT_PARAMS:${PN}-bluetooth = "start 19 2 3 4 5 . stop 21 0 1 6 ." -SYSTEMD_PACKAGES = "${PN}-autocountry" +SYSTEMD_PACKAGES = "${PN}-autocountry ${PN}-bluetooth" SYSTEMD_SERVICE:${PN}-autocountry = "cyw4373-autocountry.service" +SYSTEMD_SERVICE:${PN}-bluetooth = "cyw55512-bluetooth.service" PACKAGES =+ " \ ${PN}-mfgtest \ ${PN}-autocountry \ + ${PN}-bluetooth \ " FILES:${PN} = " \ @@ -87,7 +129,7 @@ FILES:${PN} = " \ " FILES:${PN}-mfgtest = " \ - ${sbindir} \ + ${sbindir}/wl \ " FILES:${PN}-autocountry = " \ @@ -96,11 +138,19 @@ FILES:${PN}-autocountry = " \ ${systemd_unitdir}/system/cyw4373-autocountry.service \ " -RDEPENDS:${PN}:append = " ${PN}-autocountry" +FILES:${PN}-bluetooth = " \ + ${sysconfdir}/cyw55512-bluetooth \ + ${sysconfdir}/init.d/cyw55512-bluetooth \ + ${systemd_unitdir}/system/cyw55512-bluetooth.service \ + ${sbindir}/mbt \ +" + +RDEPENDS:${PN}:append:ccmp1 = " ${PN}-autocountry" RDEPENDS:${PN}-autocountry:append = " ${PN}-mfgtest" +RDEPENDS:${PN}:append:ccmp2 = " ${PN}-bluetooth" INSANE_SKIP:${PN} += "build-deps" INSANE_SKIP:${PN} += "file-rdeps" PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "(ccmp1)" +COMPATIBLE_MACHINE = "(ccmp1|ccmp2)" diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/CYW55500A1_001.002.032.0121.0000_Generic_UART_37_4MHz_wlbga_iPA_sLNA_ANT0.hcd b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/CYW55500A1_001.002.032.0121.0000_Generic_UART_37_4MHz_wlbga_iPA_sLNA_ANT0.hcd new file mode 100644 index 000000000..9b73aee34 Binary files /dev/null and b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/CYW55500A1_001.002.032.0121.0000_Generic_UART_37_4MHz_wlbga_iPA_sLNA_ANT0.hcd differ diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio.trxse b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio.trxse new file mode 100644 index 000000000..35ec566dd Binary files /dev/null and b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio.trxse differ diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio.txt b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio.txt new file mode 100644 index 000000000..f4d754f70 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio.txt @@ -0,0 +1,466 @@ +#CYW955513SDM2WLIPA_TAG215 +#802.11ax 1x1 Tri-Band HE20 WiFi 6/6e + BT/BLE 5.2 Combo with SDIO/SPI interface +#test1 +NVRAMRev=$Rev: 53b0a7a3628d2aeaac03f69abc9ffd286740aa76 $ +sromrev=11 +boardrev=0x1530 +boardtype=0x0904 +boardflags=0x00400001 +boardflags2=0x00800000 +boardflags3=0x40000100 +#boardnum=57410 +macaddr=00:90:4c:2e:c3:05 + +#Regulatory specific +ccode=0 +regrev=0 + +# Board specific +vendid=0x12be +devid=0xbd3e +manfid=0x2d0 +antswitch=0 +pdgain5g=0 +pdgain2g=0 +aa2g=1 +aa5g=1 +agbg0=2 +aga0=2 +extpagain5g=2 +extpagain2g=2 +rxgains2gelnagaina0=0 +rxgains2gtrisoa0=13 +rxgains2gtrelnabypa0=0 +rxgains5gelnagaina0=0 +rxgains5gtrisoa0=7 +rxgains5gtrelnabypa0=0 +rxgains5gmelnagaina0=0 +rxgains5gmtrisoa0=7 +rxgains5gmtrelnabypa0=0 +rxgains5ghelnagaina0=0 +rxgains5ghtrisoa0=7 +rxgains5ghtrelnabypa0=0 + +# ==== RSSI related parametes start ============================================================== +# 2G-Core0 [20MHz, 40Mhz] +rssicorrnorm_c0=-5,0 +# =================================== +# 5G-Core0 [20MHz(l), 40MHz(l), 80Mhz(l), 20MHz(ml), 40MHz(ml), 80Mhz(ml), 20MHz(mu), 40MHz(mu), 80Mhz(mu), 20MHz(h), 40MHz(h), 80Mhz(h)] +# 5170 to below 5500(ch36 to ch96) - l +# 5500 to below 5620(ch100 to ch120) - ml +# 5620 to below 5745(ch124 to ch144) - mu +# 5745 to below 5835(ch149 to ch165) - h +# =================================== +rssicorrnorm5g_c0=7,0,0,6,0,0,3,0,0,4,0,0 +# 6G-Core0 [20MHz(u5), 40MHz(u5), 80Mhz(u5), 20MHz(u6), 40MHz(u6), 80Mhz(u6), 20MHz(u7), 40MHz(u7), 80Mhz(u7), 20MHz(u8), 40MHz(u8), 80Mhz(u8)] +rssicorrnorm6g_c0=1,0,0,-4,0,0,-2,0,0,0,0,0 + +# These parameter are not required (seems obsolete), valid for fast AGC +#rssi_delta_5gl=-6 4 -8 -8 -6 4 -8 -8 -6 4 -8 -8 -3 6 -3 -4 -3 6 -3 -4 -3 6 -3 -4 +#rssi_delta_5gml=-1 3 -1 -3 -1 3 -1 -3 -1 3 -1 -3 -1 2 0 -2 -1 2 0 -2 -1 2 0 -2 +#rssi_delta_5gmu=0 3 -1 -2 0 3 -1 -2 0 3 -1 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 +#rssi_delta_5gh=2 4 2 -1 2 4 2 -1 2 4 2 -1 0 0 2 -2 0 0 2 -2 0 0 2 -2 +#rssi_delta_6gunii5=-6 4 -8 -8 -6 4 -8 -8 -6 4 -8 -8 -3 6 -3 -4 -3 6 -3 -4 -3 6 -3 -4 +#rssi_delta_6gunii6=-1 3 -1 -3 -1 3 -1 -3 -1 3 -1 -3 -1 2 0 -2 -1 2 0 -2 -1 2 0 -2 +#rssi_delta_6gunii7=0 3 -1 -2 0 3 -1 -2 0 3 -1 -2 0 2 0 -2 0 2 0 -2 0 2 0 -2 +#rssi_delta_6gunii8=2 4 2 -1 2 4 2 -1 2 4 2 -1 0 0 2 -2 0 0 2 -2 0 0 2 -2 +rssi_cal_rev=1 +rxgaincal_rssical=1 + +# Correction for low rssi region +low_pwr_rssi_thresh_qdBm_5g=-334 +low_pwr_rssi_bias_5g_c0=-2,0,0,-8,0,0,-6,0,0,-8,0,0 + +# Setting this to 255 to disable temp based compensation +gain_cal_temp=25 +rxgain_tempcoeff2g_sub=32,32,32,32,32,32,32,32,32,32 +rxgain_tempcoeff5gl=28 +rxgain_tempcoeff5gml=24 +rxgain_tempcoeff5gmu=24 +rxgain_tempcoeff5gh=24 +rxgain_tempcoeff2g_sub_elnaoff=32,32,32,32,32,32,32,32,32,32 +rxgain_tempcoeff5gl_elnaoff=28 +rxgain_tempcoeff5gml_elnaoff=22 +rxgain_tempcoeff5gmu_elnaoff=22 +rxgain_tempcoeff5gh_elnaoff=22 +rxgain_tempcoeff6g_unii5=24 +rxgain_tempcoeff6g_unii6=24 +rxgain_tempcoeff6g_unii7=28 +rxgain_tempcoeff6g_unii8=34 + +# Each nibble represent 2G channel from 1 to 14. LSB 3 bits specify group number (i.e. 0 to 4), MSB specify if ch used for calibration +rssi_cal_freq_grp_2g= 0x08,0x01,0x91,0x2a,0x23,0xb3,0xc4 +rssi_delta_2gb0=0,0,0,0 +rssi_delta_2gb1=0,0,0,0 +rssi_delta_2gb2=0,0,0,0 +rssi_delta_2gb3=0,0,0,0 +rssi_delta_2gb4=0,0,0,0 +# ==== RSSI related parametes end ============================================================== + +#Two range TSSI +tworangetssi2g=0 +tworangetssi5g=0 +# NOTE :================================================================================ +# To run TPC with Two Range TSSI ,set tworangetssi2g = 1 and lowpowerrange2g = 0 +# To run TPC with Single Range TSSI, set tworangetssi2g = 0 +# To run TPC please READ instructions near pa2ga0 and pa2ga1 as well +# To generate PA params for Low Range set tworangetssi2g = 0 and lowpowerrange2g to 1 +# To generate PA params for High Range set tworangetssi2g = 1 and lowpowerrange2g to 1 +# ====================================================================================== +#lowpowerrange2g=0 +#lowpowerrange5g=0 + +#Related to FW Download. Host may use this +nocrc=1 +#FIXME:4369 otpimagesize? Check with Rama +otpimagesize=502 + +xtalfreq=37400 + +txchain=1 +rxchain=1 + +cckdigfilttype=3 +cck_txgain_offsetval=0x18 + +#bit mask for slice capability bit 0:2G bit 1:5G +bandcap=2 + + +#FDSS Related +fdss_level_5g=9 +fdss_interp_en=0 +fdss_level_2g=4 + +#FIXME: fdss level for 6G made same as 5G for now +fdss_level_6g=9 + +#LPB related : FIXME Enable later +leg_preamble_boost=12,12,0 +lpb_comp=10 + +#PAPRR Related +paprdis=0 +paprrmcsgain2g=130,130,130,129,128,0,0,0,0,0,0,0 +paprrmcsgamma2g=550,550,550,650,700,-1,-1,-1,-1,-1,-1,-1 +paprrmcsgain5g20=130,130,130,129,128,0,0,0,0,0,0,0 +paprrmcsgamma5g20=500,500,550,650,700,-1,-1,-1,-1,-1,-1,-1 + +#PAPR params for 6G +#FIXME: papr params 6G made same as 5G for now +paprrmcsgain6g20=130,130,130,129,128,0,0,0,0,0,0,0 +paprrmcsgamma6g20=500,500,550,650,700,-1,-1,-1,-1,-1,-1,-1 + +#Tempsense Related +tempthresh=255 +tempoffset=255 +rawtempsense=0x1ff +phycal_tempdelta=15 +temps_period=15 +temps_hysteresis=15 + +#------------- TSSI Related ------------- +tssipos2g=1 +tssipos5g=1 + +AvVmid_c0=6,75,5,93,5,93,5,93,5,93,5,90,5,90,5,90,5,90 + +low_adc_rate_en=1 +#limit Tx gain index +txidxcap2g=10 +txidxcap5g=10 +txidxcap6g=10 + +# Single RANGE TPC/TSSI +#2G OFDM +pa2ga0=-83,6939,-652 +#2G CCK +pa2gccka0=-70,7733,-727 +#5G channels:36 to 48,52 to 64,100 to 144,149 to 165 +pa5ga0=-94,7296,-678,-88,7337,-671,-135,6902,-712,-110,7005,-686 +#PA Params 6G UNII-5,6,7,8 +pa6ga0=-157,6232,-665,-156,6495,-703,-145,6522,-710,-162,6115,-686 + +# Max power and offsets +maxp2ga0=86 +maxp5ga0=72,72,72,72 +#Max Power on 6G UNII-5/6 and UNII-7/8 +maxp6ga0=64,60 + +subband5gver=0x4 +paparambwver=3 +cckpwroffset0=0 + +# PD offsets for 2G,5G,6G +# 2G power offset per channel +powoffs2gtna0=0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# 5G power offset per channel for band edge channel +powoffs5g20mtna0=0,0,0,0,0,0,0 +pdoffset20ma0=0x0000 +pdoffset6g20ma0=0x0000 +pdoffset6g20ma0_group1=0x0000 + +cckbw202gpo=0 +cckbw20ul2gpo=0 +mcsbw202gpo=0x88554444 + +dot11agofdmhrbw202gpo=0x5444 +ofdmlrbw202gpo=0x0044 +mcsbw205glpo=0x55111110 +mcsbw205gmpo=0x55111110 +mcsbw205ghpo=0x55111110 + +# ppr offsets for UNII-5/6 of 6GHz band +mcsbw206glpo=0x33000000 + +# ppr offsets for UNII-7/8 of 6GHz band +mcsbw206gmpo=0x44000000 + +mcs1024qam2gpo=0x00aa +mcs1024qam5glpo=0x000077 +mcs1024qam5gmpo=0x000077 +mcs1024qam5ghpo=0x000077 +mcs1024qam5gx1po=0x000077 +mcs1024qam5gx2po=0x000077 +mcs8poexp=0 +mcs9poexp=0 +mcs10poexp=0 +mcs11poexp=0 +# 1024QAM rates' offset for 6GHz UNII-5/6 +mcs1024qam6glpo=0x555555 +# 1024QAM rates' offset for 6GHz UNII-7/8 +mcs1024qam6gmpo=0x555555 + +#UL-OFDMA PPR's accros RU's +#currently programmed same PPR accross RU's +#across QAM's the PPR are same b/w SU and RU +#each RU PPR is grouped with 5 bits +ruppr2g20bpska0=0x10842 +ruppr2g20qpska0=0x10842 +ruppr2g20qam16a0=0x10842 +ruppr2g20qam64a0=0x294A5 +ruppr2g20qam256a0=0x42108 +ruppr2g20qam1024a0=0x5294A +ruppr5g20bpska0=0x0 +ruppr5g20qpska0=0x0 +ruppr5g20qam16a0=0x10842 +ruppr5g20qam64a0=0x10842 +ruppr5g20qam256a0=0x18c63 +ruppr5g20qam1024a0=0x294A5 + +# OLPC Related +disable_olpc=0 +olpc_thresh5g=60 +olpc_anchor5g=64 +disable_olpc_2g=0 +olpc_thresh2g=56 +olpc_anchor2g=60 +#FIXME: olpc params 6G made same as 5G for now +olpc_thresh6g=60 +olpc_anchor6g=64 + +#LTE Coex Related +ltecxmux=0 +ltecxpadnum=0x0504 +ltecxfnsel=0x44 +ltecxgcigpio=0x04 +#OOB params +#device_wake_opt=1 +#host_wake_opt=0 + +# SWCTRL Related +swctrlmap_5g=0x18081808,0x12021202,0x18081808,0x000008,0x1F +swctrlmapext_5g=0x00000000,0x00000000,0x00000000,0x000000,0x000 +fem_table_init_val=0x01100110,0x00000000 +fem_table_init_val_ext=0x00000000,0x00000000 + +swctrlmap_2g=0x16061606,0x1808180C,0x16061606,0x000008,0x11F +swctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x000 + +clb2gslice0core0=0x1c +clb5gslice0core0=0x1e +#For TDM coex use the following +btc_prisel_ant_mask=0x0 +clb_swctrl_smask_ant0=0x37f +# 2 Ant hyb/par following comment above +#btc_prisel_ant_mask=0x3 +#clb_swctrl_smask_ant0=0x34f +muxenab=1 + +#BT Coex 1:TDM +btc_mode=1 + +# --- PAPD Cal related params ---- +# 0:NBPAPD 1:WBPAPD +txwbpapden=1 +# NB PAPD Cal params +# 0x5Gc02Gc0 +nb_eps_offset=0x01dd01e3 +nb_bbmult=0x5550 +nb_papdcalidx=0x050a +nb_txattn=0x0000 +nb_rxattn=0x0000 +papdgainctrl2g=0 +papdgainctrl5g=0 +pacalshift2g=5 +pacalshift5g=4 +eps_stopidx=63 +# two-core specific variables for each of UNII-5/6/7/8 bands +# u5c0,u6c0,u7c0,u8c0 +nb_txattn_6g=0,0,0,0 +nb_rxattn_6g=0,0,0,0 +nb_papdcalidx_6g=10,10,10,10 +nb_bbmult_6g=80,80,80,80 +nb_eps_offset_6g=475,475,475,475 +papdgainctrl6g=0 +pacalshift6g20=3,4,4,4 + +# WB papd cal params +# c02g,c05g20 +wb_txattn=0,1 +wb_rxattn=0,0 +wb_tia_gain_mode=2,2 +wb_eps_offset=474,462 +wb_papdcalidx=10,5 +wb_bbmult=64,90 +wb_calref_db=23,24 +wb_txbuf_offset=33,32 +wb_frac_del=255,255 +wb_g_frac_bits=10,10 + +# WB 6G cal params +# u5c0,u6c0,u7c0,u8c0 +wb_txattn_6g20=1,1,1,1 +wb_rxattn_6g20=0,0,0,0 +wb_tia_gain_mode_6g20=4,4,2,5 +wb_papdcalidx_6g20=10,10,5,30 +wb_bbmult_6g20=70,80,80,86 +wb_eps_offset_6g20=470,468,463,471 +wb_calref_db_6g20=24,24,24,28 + + +#2nd LUT parameters +wb_multipapd_en=0 +wb_PapdLutSel_idx_6g20=42,42,42,42 +wb_eps_index_offset_6g20=5,5,5,5 +wb_papdcalidx_6g20_lut1=10,10,10,10 +wb_bbmult_6g20_lut1=66,70,74,74 +wb_calref_db_6g20_lut1=26,26,26,26 + +# WBPAPD gain control params +wb_gainctrl_nvram_en=1 +wb_target_tssi_2g20=200 +wb_target_tssi_5g20=210,210,210,150 +wb_target_tssi_6g20=75,71,100,-45 +wb_fudge_factor_2g5g=1,0,-1,-1,-1 + +# 2g/5G 2nd PAPD LUT parameters applicable for -40degc +wb_eps_offset_lut1=22,10 +wb_calref_db_lut1=23,19 +wb_papdcalidx_lut1=10,10 +wb_bbmult_lut1=25,40 +wb_PapdLutSel_idx_2g5g=53,52 + +# energy detect threshold +ed_thresh2g=-65 +ed_thresh5g=-68 +ed_thresh6g=-68 +# energy detect threshold for EU +eu_edthresh2g=-65 +eu_edthresh5g=-68 +eu_edthresh6g=-68 + +btldopu=0 + +#rpcal coef for imptxbf +rpcal2g=0 +rpcal5gb0=238 +rpcal5gb1=228 +rpcal5gb2=222 +rpcal5gb3=229 + +#Enable LHL PS mode +lhl_ps_mode=3 + +#SR related params +#The min resource state during sleep +rmin=0x1 +#disable sr topoff +lpflags=0 +#disable fastlpo setting +fastlpo_pcie_dis=0 +fastlpo_dis=0 + +#PALDO settings 0=3.3 1=3.35 2=3.41 3=3.46 4=2.86, 5=2.97 6=3.08, 7=3.19 +#paldo3p3_voltage=0 + +#2G lowpwr settings 0=TOT 1=setting1 2=setting2 3=settingHE(lowpwr) +#ipa2glowpwr=3 + +#temperature throttling +# Currently tvpm is not part of H1 build, disable for initial BU +tvpm=1 +tvpm_txc_txdc=105,15 +tvpm_txc_txdc_lowlimit=1 +tvpm_txc_txdc_insert=0,0 +tvpm_monitor_period=3 +#temperature throttling, aggressive setting +tvpm_txc_txdc_burst=110,20,5 + +##Dynamic Desense Params for 2 ant hybrid coex +#btcdyn_flags=3 +#btcdyn_dflt_dsns_level=0 +#btcdyn_low_dsns_level=1 +#btcdyn_mid_dsns_level=2 +#btcdyn_high_dsns_level=4 +#btcdyn_default_btc_mode=5 +#btcdyn_dsns_rows=2 +#btcdyn_dsns_row1=5,-4,0,-50,-70 +#btcdyn_dsns_row0=5,12,0,-50,-65 + +ppr_hitemp_offset=70,10 +# idx 0: PPR temp thresh, default 150 +# idx 1: PPR temp thresh hysteresis, default 15 +cckbw202gpo_ht=0x6666 +# CCK high temp offset, 0.5dBm/step, rate(11,5.5,2,1Mbps) +ofdmbw202gpo_ht=0x66666666 +# 2G OFDM temp offset, 0.5dBm/step, rate(54,48,36,24,18,12,9,6Mbps) +mcsbw202gpo_ht=0x66666666 +# 2G BW20 VHT/HT temp offset, 0.5dBm/step, rate(C9,C8,M7,M6,M5,M4,M3,M2-0) +mcsbw202gpo_1024qam_ht=0x66 +# 2G BW20 HE/VHT temp offset, 0.5dBm/step, rate(C11,C10) +ofdmbw205gpo_ht=0x66666666 +# 5G OFDM temp offset, 0.5dBm/step, rate(54,48,36,24,18,12,9,6Mbps) +mcsbw205gpo_ht=0x66666666 +# 5G BW20 HE/VHT/HT temp offset, 0.5dBm/step, rate(C9,C8,M7,M6,M5,M4,M3,M2-0) +mcsbw205gpo_1024qam_ht=0x66 +# 5G BW20 HE/VHT temp offset, 0.5dBm/step, rate(C11,C10) +ofdmbw206gpo_ht=0x66666666 +# 6G OFDM temp offset, 0.5dBm/step, rate(54,48,36,24,18,12,9,6Mbps) +mcsbw206gpo_ht=0x66666666 +# 6G BW20 HE/VHT/HT temp offset, 0.5dBm/step, rate(C9,C8,M7,M6,M5,M4,M3,M2-0) +mcsbw206gpo_1024qam_ht=0x66 +# 6G BW20 HE/VHT temp offset, 0.5dBm/step, rate(C11,C10) + +# SWDIV related +swdiv_en=1 #To enable SW-DIV feature +swdiv_gpio=0 +swdiv_swctrl_en=2 +swdiv_swctrl_ant0=0 +swdiv_swctrl_ant1=1 +swdiv_antmap2g_main=1 +swdiv_antmap5g_main=1 + +swdiv_snrlim=290 #Only enable sw_div if the snr on present antenna is less than 290/8=36.25 +swdiv_thresh=2000 #No.of rxpkts threshold +swdiv_snrthresh=24 #Difference between antenna's snr is greater than 24/8=3dB, then shift the antennas +swdiv_timeon=10 +swdiv_timeoff=1 +swdiv_snr2g20=232 +swdiv_snr2g40=257 +swdiv_snr5g20=232 +swdiv_snr5g40=312 +swdiv_snr5g80=296 + +swdiv_ap_dead_check=0 #Enable sending of null frames at a periodicity of 1 sec to check whether the present antenna is dead +swdiv_ap_div=0 #Enabling ap_diversity diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio_US.clm_blob b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio_US.clm_blob new file mode 100644 index 000000000..286d9c164 Binary files /dev/null and b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyfmac55500-sdio_US.clm_blob differ diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyw55512-bluetooth b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyw55512-bluetooth new file mode 100644 index 000000000..f26fac2e7 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyw55512-bluetooth @@ -0,0 +1,50 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2024 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Initialize Bluetooth interface +# +#=============================================================================== + +SCRIPTNAME="$(basename ${0})" +export MBT_TRANSPORT=/dev/ttySTM1 + +log() { + if type "systemd-cat" >/dev/null 2>/dev/null; then + systemd-cat -p "${1}" -t "${SCRIPTNAME}" printf "%s" "${2}" + else + logger -p "${1}" -t "${SCRIPTNAME}" "${2}" + fi +} + +bt_power_cycle() { + #CCMP2 BT_REG_EN GPIO PZ5 + gpioset gpiochip11 5=0 + sleep 0.5 + gpioset gpiochip11 5=1 +} + +bt_init() { + bt_power_cycle + # Load Bluetooth firmware on device + mbt download /lib/firmware/brcm/CYW55500A1.hcd + # Attach serial UART to the Bluetooth stack + btattach -B /dev/ttySTM1 -P bcm -S 921600 & + sleep 2 + + # Up the interface to be able to send hci commands + if ! hciconfig hci0 up; then + log err "FAILED (hci0 up)" + exit + fi + log info "OK" +} + +bt_init diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyw55512-bluetooth.service b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyw55512-bluetooth.service new file mode 100644 index 000000000..a7f42badd --- /dev/null +++ b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/cyw55512-bluetooth.service @@ -0,0 +1,10 @@ +[Unit] +Description=CYW55512 Bluetooth Initialization +After=network.target suspend.target + +[Service] +Type=forking +ExecStart=/etc/cyw55512-bluetooth + +[Install] +WantedBy=multi-user.target suspend.target diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/mbt b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/mbt new file mode 100755 index 000000000..a3d76e83f Binary files /dev/null and b/meta-digi-arm/recipes-bsp/firmware-murata-infineon/firmware-murata-infineon/mbt differ diff --git a/meta-digi-arm/recipes-bsp/firmware-murata-nxp/firmware-murata-nxp.bb b/meta-digi-arm/recipes-bsp/firmware-murata-nxp/firmware-murata-nxp.bb index c21a9a036..253394e52 100644 --- a/meta-digi-arm/recipes-bsp/firmware-murata-nxp/firmware-murata-nxp.bb +++ b/meta-digi-arm/recipes-bsp/firmware-murata-nxp/firmware-murata-nxp.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2023-2024, Digi International. +# Copyright (C) 2023,2024, Digi International Inc. SUMMARY = "Murata NXP firmware binaries" LICENSE = "GPL-2.0-only" @@ -27,4 +27,4 @@ do_install () { FILES:${PN} = "${nonarch_base_libdir}/firmware" PACKAGE_ARCH = "${MACHINE_ARCH}" -COMPATIBLE_MACHINE = "ccimx93" +COMPATIBLE_MACHINE = "(ccimx9)" diff --git a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb index 2737a910c..608ff9ecd 100644 --- a/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb +++ b/meta-digi-arm/recipes-bsp/firmware-qualcomm/firmware-qualcomm.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2023 Digi International. +# Copyright (C) 2016-2023, Digi International Inc. SUMMARY = "Qualcomm firmware files for Digi's platforms." SECTION = "base" diff --git a/meta-digi-arm/recipes-bsp/formfactor/formfactor_0.0.bbappend b/meta-digi-arm/recipes-bsp/formfactor/formfactor_0.0.bbappend index 4a0a2d0b6..7a8f70f2a 100644 --- a/meta-digi-arm/recipes-bsp/formfactor/formfactor_0.0.bbappend +++ b/meta-digi-arm/recipes-bsp/formfactor/formfactor_0.0.bbappend @@ -1,3 +1,3 @@ -# Copyright (C) 2014 Digi International. +# Copyright (C) 2014, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" diff --git a/meta-digi-arm/recipes-bsp/libubootenv/libubootenv/ccimx93/mmc/fw_env.config b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv/mmc/fw_env_boot1_boot2.config similarity index 100% rename from meta-digi-arm/recipes-bsp/libubootenv/libubootenv/ccimx93/mmc/fw_env.config rename to meta-digi-arm/recipes-bsp/libubootenv/libubootenv/mmc/fw_env_boot1_boot2.config diff --git a/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend index 15ffa5c44..8f69db3de 100644 --- a/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend +++ b/meta-digi-arm/recipes-bsp/libubootenv/libubootenv_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2021-2024 Digi International Inc. +# Copyright (C) 2021-2024, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" @@ -15,10 +15,13 @@ FW_CONFIG_FILE:ccmp1 = "${@bb.utils.contains('IMAGE_FEATURES', 'read-only-rootfs 'ubi/fw_env.config_default', \ 'ubi/fw_env.config', d)}" +FW_CONFIG_FILE:ccimx9 = "${STORAGE_MEDIA}/fw_env_boot1_boot2.config" +FW_CONFIG_FILE:ccmp2 = "${STORAGE_MEDIA}/fw_env_boot1_boot2.config" + DEPENDS += "${@oe.utils.conditional('OPTEE_PATCHES', '', '', 'optee-client', d)}" OPTEE_PATCHES = "" -OPTEE_PATCHES:ccimx93 = "file://0004-Implement-support-for-environment-encryption-using-O.patch" +OPTEE_PATCHES:ccimx9 = "file://0004-Implement-support-for-environment-encryption-using-O.patch" OPTEE_PATCHES:ccmp1 = "file://0004-Implement-support-for-environment-encryption-using-O.patch" SRC_URI += " \ diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/nativesdk-trustfence-cst_3.3.2.bb b/meta-digi-arm/recipes-bsp/trustfence-cst/nativesdk-trustfence-cst_3.3.2.bb index 391c28e25..a52f1529c 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-cst/nativesdk-trustfence-cst_3.3.2.bb +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/nativesdk-trustfence-cst_3.3.2.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Digi International. +# Copyright (C) 2022, Digi International Inc. require trustfence-cst-${PV}.inc diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-3.3.2.inc b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-3.3.2.inc index 5406f6215..03c467195 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-3.3.2.inc +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-3.3.2.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2023 Digi International +# Copyright (C) 2017-2023, Digi International Inc. SUMMARY = "NXP Code signing Tool for the High Assurance Boot library" DESCRIPTION = "Provides software code signing support designed for use with \ diff --git a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_3.3.2.bb b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_3.3.2.bb index 5574a8987..96efddadd 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_3.3.2.bb +++ b/meta-digi-arm/recipes-bsp/trustfence-cst/trustfence-cst-native_3.3.2.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Digi International. +# Copyright (C) 2022, Digi International Inc. require trustfence-cst-${PV}.inc diff --git a/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/nativesdk-trustfence-stm-signtools_1.2.bb b/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/nativesdk-trustfence-stm-signtools_1.3.bb similarity index 52% rename from meta-digi-arm/recipes-bsp/trustfence-stm-signtools/nativesdk-trustfence-stm-signtools_1.2.bb rename to meta-digi-arm/recipes-bsp/trustfence-stm-signtools/nativesdk-trustfence-stm-signtools_1.3.bb index 65ab80168..04348cb0e 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/nativesdk-trustfence-stm-signtools_1.2.bb +++ b/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/nativesdk-trustfence-stm-signtools_1.3.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2023,2024 Digi International. +# Copyright (C) 2023,2024, Digi International Inc. require trustfence-stm-signtools.inc inherit nativesdk diff --git a/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools-native_1.2.bb b/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools-native_1.3.bb similarity index 53% rename from meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools-native_1.2.bb rename to meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools-native_1.3.bb index dace38ef7..28845926c 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools-native_1.2.bb +++ b/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools-native_1.3.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Digi International. +# Copyright (C) 2023, Digi International Inc. require trustfence-stm-signtools.inc inherit native diff --git a/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools.inc b/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools.inc index c3db046ea..7dcd1d920 100644 --- a/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools.inc +++ b/meta-digi-arm/recipes-bsp/trustfence-stm-signtools/trustfence-stm-signtools.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2023,2024 Digi International. +# Copyright (C) 2023,2024, Digi International Inc. SUMMARY = "STM key generation and signing tools" SECTION = "console/tools" @@ -10,8 +10,8 @@ PKGNAME = "trustfence-stm-signtools" # tarball SRC_URI = "${DIGI_PKG_SRC}/${PKGNAME}-${PV}.tar.gz" -SRC_URI[md5sum] = "995b612c1da7e3d9b9b402ede578f41d" -SRC_URI[sha256sum] = "b3c975c12f71acda356e086c1440398ca95256e104fd4813ef6a720237f6dd72" +SRC_URI[md5sum] = "5693ed0cd34f858dea5bc3d1a94e9eee" +SRC_URI[sha256sum] = "be3ab77b98f5f8b8508cda090cc5eeccd0cdc39ebe9cee45b5ef52528c4ce515" inherit bin_package diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc index 6ccfd5c15..83edbcf49 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2018-2024 Digi International +# Copyright (C) 2018-2024, Digi International Inc. require recipes-bsp/u-boot/u-boot.inc @@ -220,6 +220,7 @@ do_compile:append:ccmp1() { BOOT_TOOLS = "imx-boot-tools" BOOT_TOOLS:ccmp1 = "u-boot" +BOOT_TOOLS:ccmp2 = "u-boot" do_deploy:append:ccimx8m() { # Deploy u-boot-nodtb.bin and ccimx8m[m|n]-dvk.dtb, to be packaged in boot binary by imx-boot @@ -269,4 +270,16 @@ do_deploy:append:ccmp1() { fi } +do_deploy:append:ccmp2() { + # Deploy u-boot-nodtb.bin and ccmp2x-dvk-xxxx.dtb, to be packaged in fip binary by tf-a + install -d ${DEPLOYDIR}/${BOOT_TOOLS} + if [ -n "${UBOOT_DEVICETREE}" ]; then + for devicetree in ${UBOOT_DEVICETREE}; do + # Install u-boot dtb + install -m 644 ${B}/${config}/arch/arm/dts/${devicetree}.dtb ${DEPLOYDIR}/${BOOT_TOOLS}/${FIP_UBOOT_DTB}-${devicetree}.dtb + done + fi + install -m 0777 ${B}/${config}/u-boot-nodtb.bin ${DEPLOYDIR}/${BOOT_TOOLS}/u-boot-nodtb.bin +} + SYSROOT_DIRS += "/boot" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93-dvk/boot.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/boot.txt similarity index 83% rename from meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93-dvk/boot.txt rename to meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/boot.txt index 173b3b84d..eb54b8080 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93-dvk/boot.txt +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/boot.txt @@ -66,18 +66,26 @@ setexpr module_has_bt ${hwid_2} \& 40000 setexpr module_has_bt ${module_has_bt} / 40000 if test "${module_has_bt}" = "1" && test -z "${disable_bt}"; then - setenv overlays _ov_som_bt_ccimx93.dtbo,${overlays} + setenv overlays _ov_som_bt_ccimx9.dtbo,${overlays} fi if test "${module_has_wifi}" = "1" && test -z "${disable_wifi}"; then - setenv overlays _ov_som_wifi_ccimx93.dtbo,${overlays} + setenv overlays _ov_som_wifi_ccimx9.dtbo,${overlays} fi -if test "${cpu_type}" = "imx9352" || \ - test "${cpu_type}" = "imx9351" || \ - test "${cpu_type}" = "imx9322" || \ - test "${cpu_type}" = "imx9321"; then - module_has_npu="1" +if test "${soc_type}" = "imx93"; then + if test "${cpu_type}" = "imx9352" || \ + test "${cpu_type}" = "imx9351" || \ + test "${cpu_type}" = "imx9322" || \ + test "${cpu_type}" = "imx9321"; then + module_has_npu="1" + fi + if test "${emulate-cc91}" = "yes"; then + echo "Emulating a ConnectCore 91 (emulate-cc91=yes)" + module_has_npu="0" + setenv extra_bootargs ${extra_bootargs} mem=512M + setenv overlays _ov_som_emulate-ccimx91_ccimx93.dtbo,${overlays} + fi fi if test "${module_has_npu}" = "1" && test -z "${disable_npu}"; then diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_sd.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_sd.txt similarity index 96% rename from meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_sd.txt rename to meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_sd.txt index b973c36b6..1ca68a2cd 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_sd.txt +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_sd.txt @@ -8,16 +8,18 @@ install_abort=0 BASEFILENAME=0 # Determine U-Boot file to program basing on SOM's SOC revision -if test -z "${soc_rev}"; then - # Fallback to hardware version if soc_rev is empty - setexpr som_hv ${hwid_2} \& 78 - setexpr som_hv ${som_hv} / 8 - if test "${som_hv}" -lt "2"; then - SOCREV="-A0" - fi -else - if test "${soc_rev}" = "0x10"; then - SOCREV="-A0" +if test "${soc_type}" = "imx93"; then + if test -z "${soc_rev}"; then + # Fallback to hardware version if soc_rev is empty + setexpr som_hv ${hwid_2} \& 78 + setexpr som_hv ${som_hv} / 8 + if test "${som_hv}" -lt "2"; then + SOCREV="-A0" + fi + else + if test "${soc_rev}" = "0x10"; then + SOCREV="-A0" + fi fi fi setenv INSTALL_UBOOT_FILENAME imx-boot-##MACHINE##${SOCREV}.bin diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_usb.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_usb.txt similarity index 96% rename from meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_usb.txt rename to meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_usb.txt index e20b94544..9fc05dd8c 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_usb.txt +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_usb.txt @@ -8,16 +8,18 @@ install_abort=0 BASEFILENAME=0 # Determine U-Boot file to program basing on SOM's SOC revision -if test -z "${soc_rev}"; then - # Fallback to hardware version if soc_rev is empty - setexpr som_hv ${hwid_2} \& 78 - setexpr som_hv ${som_hv} / 8 - if test "${som_hv}" -lt "2"; then - SOCREV="-A0" - fi -else - if test "${soc_rev}" = "0x10"; then - SOCREV="-A0" +if test "${soc_type}" = "imx93"; then + if test -z "${soc_rev}"; then + # Fallback to hardware version if soc_rev is empty + setexpr som_hv ${hwid_2} \& 78 + setexpr som_hv ${som_hv} / 8 + if test "${som_hv}" -lt "2"; then + SOCREV="-A0" + fi + else + if test "${soc_rev}" = "0x10"; then + SOCREV="-A0" + fi fi fi setenv INSTALL_UBOOT_FILENAME imx-boot-##MACHINE##${SOCREV}.bin diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_uuu.sh b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_uuu.sh similarity index 96% rename from meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_uuu.sh rename to meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_uuu.sh index be9f15de5..bcf92552b 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx93/install_linux_fw_uuu.sh +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccimx9/install_linux_fw_uuu.sh @@ -129,15 +129,18 @@ echo "Determining image files to use..." # Determine U-Boot file to program basing on SOM's SOC revision if [ -z "${INSTALL_UBOOT_FILENAME}" ]; then - soc_rev="$(getenv soc_rev)" - if [ -n "${soc_rev}" ]; then - [ "${soc_rev}" = "0x10" ] && SOCREV="-A0" - else - # Fallback to hardware version if soc_rev is empty - hwid_2="$(getenv hwid_2)" - hwid_2="0x${hwid_2#0x}" - som_hv="$(((hwid_2 & 0x78) >> 3))" - [ "${som_hv}" -lt "2" ] && SOCREV="-A0" + soc_type="$(getenv soc_type)" + if [ "${soc_type}" = "imx93" ]; then + soc_rev="$(getenv soc_rev)" + if [ -n "${soc_rev}" ]; then + [ "${soc_rev}" = "0x10" ] && SOCREV="-A0" + else + # Fallback to hardware version if soc_rev is empty + hwid_2="$(getenv hwid_2)" + hwid_2="0x${hwid_2#0x}" + som_hv="$(((hwid_2 & 0x78) >> 3))" + [ "${som_hv}" -lt "2" ] && SOCREV="-A0" + fi fi INSTALL_UBOOT_FILENAME="imx-boot-##SIGNED##-##MACHINE##${SOCREV}.bin" fi diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_sd.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_sd.txt new file mode 100644 index 000000000..ce1f67f7a --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_sd.txt @@ -0,0 +1,311 @@ +# +# U-Boot script for installing Linux images created by Yocto from the micro SD +# card into the eMMC +# + +# Reset temp variables +install_abort=0 +BASEFILENAME=0 + +setenv INSTALL_ATF_FILENAME tf-a-##MACHINE##-emmc.stm32 +setenv INSTALL_METADATA_FILENAME metadata-##MACHINE##.bin +setenv INSTALL_FIP_FILENAME fip-##MACHINE##-optee.bin +setenv INSTALL_MMCDEV 2 + +if test -z "${image-name}"; then + setenv image-name ##DEFAULT_IMAGE_NAME## +fi +GRAPHICAL_IMAGES="##GRAPHICAL_IMAGES##" +for g in ${GRAPHICAL_IMAGES}; do + if test "${image-name}" = "${g}"; then + BASEFILENAME="${image-name}-##GRAPHICAL_BACKEND##" + fi +done +if test "${BASEFILENAME}" = "0"; then + BASEFILENAME="${image-name}" +fi +setenv INSTALL_LINUX_FILENAME ${BASEFILENAME}-##MACHINE##.boot.vfat +setenv INSTALL_RECOVERY_FILENAME ${BASEFILENAME}-##MACHINE##.recovery.vfat +setenv INSTALL_ROOTFS_FILENAME ${BASEFILENAME}-##MACHINE##.ext4 + +# Check for presence of firmware files on the SD card +FILES="${INSTALL_ATF_FILENAME} ${INSTALL_METADATA_FILENAME} ${INSTALL_FIP_FILENAME} ${INSTALL_LINUX_FILENAME}" +if test "${dualboot}" != "yes"; then + FILES="${FILES} ${INSTALL_RECOVERY_FILENAME}" +fi +for install_f in ${FILES}; do + if test ! -e mmc ${INSTALL_MMCDEV} ${install_f}; then + echo "ERROR: Could not find file ${install_f}"; + install_abort=1; + fi; +done +# Verify what kind of rootfs is going to be programmed +if test ! -e mmc ${INSTALL_MMCDEV} ${INSTALL_ROOTFS_FILENAME}; then + echo "ERROR: Could not find file ${INSTALL_ROOTFS_FILENAME}"; + setenv INSTALL_ROOTFS_FILENAME ${BASEFILENAME}-##MACHINE##.squashfs + echo "INFO: Trying with file ${INSTALL_ROOTFS_FILENAME}"; + if test ! -e mmc ${INSTALL_MMCDEV} ${INSTALL_ROOTFS_FILENAME}; then + echo "ERROR: Could not find file ${INSTALL_ROOTFS_FILENAME}"; + install_abort=1; + fi +fi +if test "${install_abort}" = "1"; then + echo "To install a different image, set variable 'image-name', e.g.:" + echo " => setenv image-name core-image-base" + echo "Aborted."; + exit; +fi + +echo "############################################################" +echo "# Linux firmware install from micro SD #" +echo "############################################################" +echo "" +echo " This process will erase your eMMC and will install the following files" +echo " on the partitions of the eMMC." +echo "" +echo " PARTITION FILENAME" +echo " --------- --------" +echo " boot1 ${INSTALL_ATF_FILENAME}" +echo " boot2 ${INSTALL_ATF_FILENAME}" +echo " metadata1 ${INSTALL_METADATA_FILENAME}" +echo " metadata2 ${INSTALL_METADATA_FILENAME}" +echo " fip-a ${INSTALL_FIP_FILENAME}" +echo " fip-b ${INSTALL_FIP_FILENAME}" +if test "${dualboot}" = "yes"; then + echo " linux_a ${INSTALL_LINUX_FILENAME}" + if test "${install_dualboot}" = "yes"; then + echo " linux_b ${INSTALL_LINUX_FILENAME}" + fi + echo " rootfs_a ${INSTALL_ROOTFS_FILENAME}" + if test "${install_dualboot}" = "yes"; then + echo " rootfs_b ${INSTALL_ROOTFS_FILENAME}" + fi +else + echo " linux ${INSTALL_LINUX_FILENAME}" + echo " recovery ${INSTALL_RECOVERY_FILENAME}" + echo " rootfs ${INSTALL_ROOTFS_FILENAME}" +fi +echo "" +echo " Press CTRL+C now if you wish to abort or wait 10 seconds" +echo " to continue." + +sleep 10 +if test $? -eq 1; then + echo "Aborted by user."; + exit; +fi + +# Skip user confirmation for U-Boot update +setenv forced_update 1 + +# Set bootdelay to zero so that firmware update is run immediately after +# the first reset. +setenv bootdelay 0 + +# Set target MMC device index to eMMC +setenv mmcdev 0 + +# Update ATF, METADATA and FIP images +echo "" +echo "" +echo ">> Installing ATF boot loader image ${INSTALL_ATF_FILENAME}" +echo "" +echo "" +update boot1 mmc ${INSTALL_MMCDEV} ${INSTALL_ATF_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update boot1!"; + echo ""; + echo "Aborted."; + exit; +fi +update boot2 mmc ${INSTALL_MMCDEV} ${INSTALL_ATF_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update boot2!"; + echo ""; + echo "Aborted."; + exit; +fi +echo "" +echo "" +echo ">> Installing METADATA boot loader image ${INSTALL_ATF_FILENAME}" +echo "" +echo "" +update metadata1 mmc ${INSTALL_MMCDEV} ${INSTALL_METADATA_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update metadata1!"; + echo ""; + echo "Aborted."; + exit; +fi +update metadata2 mmc ${INSTALL_MMCDEV} ${INSTALL_METADATA_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update metadata2!"; + echo ""; + echo "Aborted."; + exit; +fi +echo "" +echo "" +echo ">> Installing FIP boot loader image ${INSTALL_FIP_FILENAME} (target will reset)" +echo "" +echo "" +update fip-a mmc ${INSTALL_MMCDEV} ${INSTALL_FIP_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update fip-a!"; + echo ""; + echo "Aborted."; + exit; +fi +update fip-b mmc ${INSTALL_MMCDEV} ${INSTALL_FIP_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update fip-b!"; + echo ""; + echo "Aborted."; + exit; +fi + +# Set 'bootcmd' to the second part of the script that will +# - Reset environment to defaults +# - Restore 'dualboot' if previously set +# - Save the environment +# - Force on-the-fly updates to avoid possible verification errors +# - Partition the eMMC user data area for Linux +# - If Dual Boot +# - Update the system partitions: linux_a, linux_b, rootfs_a, rootfs_b +# - Set bootlimit to 3 +# - If Normal Boot: +# - Update the system partitions: linux, recovery, rootfs +# - Erase the 'update' partition +# - Configure recovery to wipe 'update' partition +# - Run 'recovery' and let the system boot after +setenv bootcmd " + env default -a; + setenv dualboot ${dualboot}; + setenv install_dualboot ${install_dualboot}; + saveenv; + setenv otf-update yes; + echo \"\"; + echo \"\"; + echo \">> Creating Linux partition table on the eMMC\"; + echo \"\"; + echo \"\"; + run partition_mmc_linux; + if test \$? -eq 1; then + echo \"[ERROR] Failed to create Linux partition table!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + if test \"\$\{dualboot\}\" = yes; then + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_LINUX_FILENAME} on linux_a\"; + echo \"\"; + echo \"\"; + update linux_a mmc ${INSTALL_MMCDEV} ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux_a!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + if test \"\$\{install_dualboot\}\" = yes; then + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_LINUX_FILENAME} on linux_b\"; + echo \"\"; + echo \"\"; + update linux_b mmc ${INSTALL_MMCDEV} ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux_b!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_ROOTFS_FILENAME} on rootfs_a\"; + echo \"\"; + echo \"\"; + update rootfs_a mmc ${INSTALL_MMCDEV} ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs_a partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + if test \"\$\{install_dualboot\}\" = yes; then + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_ROOTFS_FILENAME} on rootfs_b\"; + echo \"\"; + echo \"\"; + update rootfs_b mmc ${INSTALL_MMCDEV} ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs_b partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + fi; + setenv bootlimit 3; + else + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_LINUX_FILENAME} on linux\"; + echo \"\"; + echo \"\"; + update linux mmc ${INSTALL_MMCDEV} ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_RECOVERY_FILENAME} on recovery\"; + echo \"\"; + echo \"\"; + update recovery mmc ${INSTALL_MMCDEV} ${INSTALL_RECOVERY_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update recovery partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_ROOTFS_FILENAME} on rootfs\"; + echo \"\"; + echo \"\"; + update rootfs mmc ${INSTALL_MMCDEV} ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + setenv boot_recovery yes; + setenv recovery_command wipe_update; + fi; + setenv otf-update; + saveenv; + echo \"\"; + echo \"\"; + echo \">> Firmware installation complete.\"; + if test \"\$\{dualboot\}\" != yes; then + echo \"Rebooting into recovery mode for final deployment.\"; + fi; + echo \"\"; + echo \"\"; + sleep 1; + bootcount reset; + reset; +" + +bootcount reset +saveenv +reset diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_usb.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_usb.txt new file mode 100644 index 000000000..ba95d5915 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_usb.txt @@ -0,0 +1,312 @@ +# +# U-Boot script for installing Linux images created by Yocto from a USB stick +# into the eMMC +# + +# Reset temp variables +install_abort=0 +BASEFILENAME=0 + +setenv INSTALL_ATF_FILENAME tf-a-##MACHINE##-emmc.stm32 +setenv INSTALL_METADATA_FILENAME metadata-##MACHINE##.bin +setenv INSTALL_FIP_FILENAME fip-##MACHINE##-optee.bin +setenv INSTALL_USBDEV 0 + +if test -z "${image-name}"; then + setenv image-name ##DEFAULT_IMAGE_NAME## +fi +GRAPHICAL_IMAGES="##GRAPHICAL_IMAGES##" +for g in ${GRAPHICAL_IMAGES}; do + if test "${image-name}" = "${g}"; then + BASEFILENAME="${image-name}-##GRAPHICAL_BACKEND##" + fi +done +if test "${BASEFILENAME}" = "0"; then + BASEFILENAME="${image-name}" +fi +setenv INSTALL_LINUX_FILENAME ${BASEFILENAME}-##MACHINE##.boot.vfat +setenv INSTALL_RECOVERY_FILENAME ${BASEFILENAME}-##MACHINE##.recovery.vfat +setenv INSTALL_ROOTFS_FILENAME ${BASEFILENAME}-##MACHINE##.ext4 + +# Check for presence of firmware files on the USB +FILES="${INSTALL_ATF_FILENAME} ${INSTALL_METADATA_FILENAME} ${INSTALL_FIP_FILENAME} ${INSTALL_LINUX_FILENAME}" +if test "${dualboot}" != "yes"; then + FILES="${FILES} ${INSTALL_RECOVERY_FILENAME}" +fi +for install_f in ${FILES}; do + if test ! -e usb ${INSTALL_USBDEV} ${install_f}; then + echo "ERROR: Could not find file ${install_f}"; + install_abort=1; + fi; +done +# Verify what kind of rootfs is going to be programmed +if test ! -e usb ${INSTALL_USBDEV} ${INSTALL_ROOTFS_FILENAME}; then + echo "ERROR: Could not find file ${INSTALL_ROOTFS_FILENAME}"; + setenv INSTALL_ROOTFS_FILENAME ${BASEFILENAME}-##MACHINE##.squashfs + echo "INFO: Trying with file ${INSTALL_ROOTFS_FILENAME}"; + if test ! -e usb ${INSTALL_USBDEV} ${INSTALL_ROOTFS_FILENAME}; then + echo "ERROR: Could not find file ${INSTALL_ROOTFS_FILENAME}"; + install_abort=1; + fi +fi +if test "${install_abort}" = "1"; then + echo "To install a different image, set variable 'image-name', e.g.:" + echo " => setenv image-name core-image-base" + echo "Aborted."; + exit; +fi + +echo "############################################################" +echo "# Linux firmware install from USB #" +echo "############################################################" +echo "" +echo " This process will erase your eMMC and will install the following files" +echo " on the partitions of the eMMC." +echo "" +echo " PARTITION FILENAME" +echo " --------- --------" +echo " boot1 ${INSTALL_ATF_FILENAME}" +echo " boot2 ${INSTALL_ATF_FILENAME}" +echo " metadata1 ${INSTALL_METADATA_FILENAME}" +echo " metadata2 ${INSTALL_METADATA_FILENAME}" +echo " fip-a ${INSTALL_FIP_FILENAME}" +echo " fip-b ${INSTALL_FIP_FILENAME}" +if test "${dualboot}" = "yes"; then + echo " linux_a ${INSTALL_LINUX_FILENAME}" + if test "${install_dualboot}" = "yes"; then + echo " linux_b ${INSTALL_LINUX_FILENAME}" + fi + echo " rootfs_a ${INSTALL_ROOTFS_FILENAME}" + if test "${install_dualboot}" = "yes"; then + echo " rootfs_b ${INSTALL_ROOTFS_FILENAME}" + fi +else + echo " linux ${INSTALL_LINUX_FILENAME}" + echo " recovery ${INSTALL_RECOVERY_FILENAME}" + echo " rootfs ${INSTALL_ROOTFS_FILENAME}" +fi +echo "" +echo " Press CTRL+C now if you wish to abort or wait 10 seconds" +echo " to continue." + +sleep 10 +if test $? -eq 1; then + echo "Aborted by user."; + exit; +fi + +# Skip user confirmation for U-Boot update +setenv forced_update 1 + +# Set bootdelay to zero so that firmware update is run immediately after +# the first reset. +setenv bootdelay 0 + +# Set target MMC device index to eMMC +setenv mmcdev 0 + +# Update ATF, METADATA and FIP images +echo "" +echo "" +echo ">> Installing ATF boot loader image ${INSTALL_ATF_FILENAME}" +echo "" +echo "" +update boot1 usb ${INSTALL_USBDEV} ${INSTALL_ATF_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update boot1!"; + echo ""; + echo "Aborted."; + exit; +fi +update boot2 usb ${INSTALL_USBDEV} ${INSTALL_ATF_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update boot2!"; + echo ""; + echo "Aborted."; + exit; +fi +echo "" +echo "" +echo ">> Installing METADATA boot loader image ${INSTALL_ATF_FILENAME}" +echo "" +echo "" +update metadata1 usb ${INSTALL_USBDEV} ${INSTALL_METADATA_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update metadata1!"; + echo ""; + echo "Aborted."; + exit; +fi +update metadata2 usb ${INSTALL_USBDEV} ${INSTALL_METADATA_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update metadata2!"; + echo ""; + echo "Aborted."; + exit; +fi +echo "" +echo "" +echo ">> Installing FIP boot loader image ${INSTALL_FIP_FILENAME} (target will reset)" +echo "" +echo "" +update fip-a usb ${INSTALL_USBDEV} ${INSTALL_FIP_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update fip-a!"; + echo ""; + echo "Aborted."; + exit; +fi +update fip-b usb ${INSTALL_USBDEV} ${INSTALL_FIP_FILENAME} +if test $? -eq 1; then + echo "[ERROR] Failed to update fip-b!"; + echo ""; + echo "Aborted."; + exit; +fi + +# Set 'bootcmd' to the second part of the script that will +# - Reset environment to defaults +# - Restore 'dualboot' if previously set +# - Save the environment +# - Force on-the-fly updates to avoid possible verification errors +# - Partition the eMMC user data area for Linux +# - If Dual Boot +# - Update the system partitions: linux_a, linux_b, rootfs_a, rootfs_b +# - Set bootlimit to 3 +# - If Normal Boot: +# - Update the system partitions: linux, recovery, rootfs +# - Erase the 'update' partition +# - Configure recovery to wipe 'update' partition +# - Run 'recovery' and let the system boot after +setenv bootcmd " + env default -a; + setenv dualboot ${dualboot}; + setenv install_dualboot ${install_dualboot}; + saveenv; + setenv otf-update yes; + echo \"\"; + echo \"\"; + echo \">> Creating Linux partition table on the eMMC\"; + echo \"\"; + echo \"\"; + run partition_mmc_linux; + if test \$? -eq 1; then + echo \"[ERROR] Failed to create Linux partition table!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + usb start; + if test \"\$\{dualboot\}\" = yes; then + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_LINUX_FILENAME} on linux_a\"; + echo \"\"; + echo \"\"; + update linux_a usb ${INSTALL_USBDEV} ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux_a!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + if test \"\$\{install_dualboot\}\" = yes; then + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_LINUX_FILENAME} on linux_b\"; + echo \"\"; + echo \"\"; + update linux_b usb ${INSTALL_USBDEV} ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux_b!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_ROOTFS_FILENAME} on rootfs_a\"; + echo \"\"; + echo \"\"; + update rootfs_a usb ${INSTALL_USBDEV} ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs_a partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + if test \"\$\{install_dualboot\}\" = yes; then + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_ROOTFS_FILENAME} on rootfs_b\"; + echo \"\"; + echo \"\"; + update rootfs_b usb ${INSTALL_USBDEV} ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs_b partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + fi; + setenv bootlimit 3; + else + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_LINUX_FILENAME} on linux\"; + echo \"\"; + echo \"\"; + update linux usb ${INSTALL_USBDEV} ${INSTALL_LINUX_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update linux!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_RECOVERY_FILENAME} on recovery\"; + echo \"\"; + echo \"\"; + update recovery usb ${INSTALL_USBDEV} ${INSTALL_RECOVERY_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update recovery partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Installing file ${INSTALL_ROOTFS_FILENAME} on rootfs\"; + echo \"\"; + echo \"\"; + update rootfs usb ${INSTALL_USBDEV} ${INSTALL_ROOTFS_FILENAME}; + if test \$? -eq 1; then + echo \"[ERROR] Failed to update rootfs partition!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + setenv boot_recovery yes; + setenv recovery_command wipe_update; + fi; + setenv otf-update; + saveenv; + echo \"\"; + echo \"\"; + echo \">> Firmware installation complete.\"; + if test \"\$\{dualboot\}\" != yes; then + echo \"Rebooting into recovery mode for final deployment.\"; + fi; + echo \"\"; + echo \"\"; + sleep 1; + bootcount reset; + reset; +" + +bootcount reset +saveenv +reset diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_uuu.sh b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_uuu.sh new file mode 100644 index 000000000..09eff2c20 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp2/install_linux_fw_uuu.sh @@ -0,0 +1,325 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2024 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# Description: +# Script to flash Yocto build artifacts over USB to the target. +#=============================================================================== +# set -x + +# +# U-Boot script for installing Linux images created by Yocto +# + +# Exit on any error +set -e + +# Parse uuu cmd output +getenv() +{ + uuu -v fb: ucmd printenv "${1}" | sed -ne "s,^${1}=,,g;T;p" +} + +show_usage() +{ + echo "Usage: $0 [options]" + echo "" + echo " Options:" + echo " -a Arm-trusted-firmware filename." + echo " Auto-determined by variant if not provided." + echo " -b Activate bootcount mechanism (3 boot attempts)." + echo " -d Install firmware on dualboot partitions (system A and system B)." + echo " (Implies -b)." + echo " -f FIP filename." + echo " Auto-determined by variant if not provided." + echo " -h Show this help." + echo " -i Image name that prefixes the image filenames, such as 'dey-image-qt', " + echo " 'dey-image-webkit', 'core-image-base'..." + echo " Defaults to '##DEFAULT_IMAGE_NAME##' if not provided." + echo " -n No wait. Skips 10 seconds delay to stop script." + echo " -t Install TrustFence artifacts." + exit 2 +} + +# Update a partition +# Params: +# 1. partition +# 2. file +# 3. timeout (in ms) +part_update() +{ + printf "\033[36m\n" + printf "=====================================================================================\n" + printf "Updating '%s' partition with file: %s\n" "${1}" "${2}" + printf "=====================================================================================\n" + printf "\033[0m\n" + + if echo "${1}" | grep -qs "^boot[0-9]$"; then + uuu "fb[-t ${3}]:" flash "${1}" "${2}" + elif echo "${2}" | grep -qs "\.gz$"; then + uuu "fb[-t ${3}]:" flash -raw2sparse "${1}" "${2}/*" + else + uuu "fb[-t ${3}]:" flash -raw2sparse "${1}" "${2}" + fi +} + +clear +echo "############################################################" +echo "# Linux firmware install through USB OTG #" +echo "############################################################" + +# Command line admits the following parameters: +# -a +# -b, -d, -n (booleans) +# -f +# -i +while getopts 'a:bdf:hi:nt' c +do + case $c in + a) INSTALL_ATF_FILENAME=${OPTARG} ;; + b) BOOTCOUNT=true ;; + d) INSTALL_DUALBOOT=true && BOOTCOUNT=true ;; + f) INSTALL_FIP_FILENAME=${OPTARG} ;; + h) show_usage ;; + i) IMAGE_NAME=${OPTARG} ;; + n) NOWAIT=true ;; + t) TRUSTFENCE=true ;; + esac +done + +# Enable the redirect support to get u-boot variables values +uuu fb: ucmd setenv stdout serial,fastboot + +# Check if dualboot variable is active +dualboot=$(getenv "dualboot") +if [ "${dualboot}" = "yes" ]; then + DUALBOOT=true; +fi + +echo "" +echo "Determining image files to use..." + +# Determine ATF file to program +if [ -z "${INSTALL_ATF_FILENAME}" ]; then + INSTALL_ATF_FILENAME="tf-a-##MACHINE##-emmc.stm32##SIGNED_TFA##" +fi +INSTALL_METADATA_FILENAME="metadata-##MACHINE##.bin" + +# Determine FIP file to program +if [ -z "${INSTALL_FIP_FILENAME}" ]; then + INSTALL_FIP_FILENAME="fip-##MACHINE##-optee##SIGNED##.bin" +fi + +# remove redirect +uuu fb: ucmd setenv stdout serial + +# Determine linux, recovery, and rootfs image filenames to update +if [ -z "${IMAGE_NAME}" ]; then + IMAGE_NAME="##DEFAULT_IMAGE_NAME##" +fi +GRAPHICAL_IMAGES="##GRAPHICAL_IMAGES##" +for g in ${GRAPHICAL_IMAGES}; do + if [ "${IMAGE_NAME}" = "${g}" ]; then + BASEFILENAME="${IMAGE_NAME}-##GRAPHICAL_BACKEND##" + fi +done +if [ -z "${BASEFILENAME}" ]; then + BASEFILENAME="${IMAGE_NAME}" +fi +INSTALL_LINUX_FILENAME="${BASEFILENAME}-##MACHINE##.boot.vfat" +INSTALL_RECOVERY_FILENAME="${BASEFILENAME}-##MACHINE##.recovery.vfat" + +# Verify existence of files before starting the update +FILES="${INSTALL_ATF_FILENAME} ${INSTALL_METADATA_FILENAME} ${INSTALL_FIP_FILENAME} ${INSTALL_LINUX_FILENAME}" +if [ "${DUALBOOT}" != true ]; then + FILES="${FILES} ${INSTALL_RECOVERY_FILENAME}" +fi +for f in ${FILES}; do + if [ ! -f "${f}" ]; then + printf "\033[31m[ERROR] Could not find file '%s'\033[0m\n" "${f}" + ABORT=true + fi +done; + +# Verify what kind of rootfs is going to be programmed +ROOTFS_FILENAME="${BASEFILENAME}-##MACHINE##.ext4" +ROOTFS_FILENAME_GZ="${ROOTFS_FILENAME}.gz" +ROOTFS_FILENAME_SQFS="${BASEFILENAME}-##MACHINE##.squashfs" +if [ -f "${ROOTFS_FILENAME_GZ}" ]; then + INSTALL_ROOTFS_FILENAME="${ROOTFS_FILENAME_GZ}" +elif [ -f "${ROOTFS_FILENAME}" ]; then + INSTALL_ROOTFS_FILENAME="${ROOTFS_FILENAME}" +elif [ -f "${ROOTFS_FILENAME_SQFS}" ]; then + INSTALL_ROOTFS_FILENAME="${ROOTFS_FILENAME_SQFS}" +else + printf "\033[31m[ERROR] Could not find any rootfs image\033[0m\n" + ABORT=true +fi + +[ "${ABORT}" = true ] && exit 1 + +# Enable bootcount mechanism by setting a bootlimit +if [ "${BOOTCOUNT}" = true ]; then + bootlimit_cmd="setenv bootlimit 3" +fi + +# parts names +LINUX_NAME="linux" +RECOVERY_NAME="recovery" +ROOTFS_NAME="rootfs" +# Print warning about storage media being deleted +if [ "${NOWAIT}" != true ]; then + WAIT=10 + printf "\n" + printf " ====================\n" + printf " = IMPORTANT! =\n" + printf " ====================\n" + printf " This process will erase your eMMC and will install the following files\n" + printf " on the partitions of the eMMC.\n" + printf "\n" + printf " PARTITION\tFILENAME\n" + printf " ---------\t--------\n" + printf " boot1\t%s\n" "${INSTALL_ATF_FILENAME}" + printf " boot2\t%s\n" "${INSTALL_ATF_FILENAME}" + printf " metadata1\t%s\n" "${INSTALL_METADATA_FILENAME}" + printf " metadata2\t%s\n" "${INSTALL_METADATA_FILENAME}" + printf " fip-a\t%s\n" "${INSTALL_FIP_FILENAME}" + printf " fip-b\t%s\n" "${INSTALL_FIP_FILENAME}" + if [ "${DUALBOOT}" = true ]; then + printf " %s_a\t%s\n" "${LINUX_NAME}" "${INSTALL_LINUX_FILENAME}" + if [ "${INSTALL_DUALBOOT}" = true ]; then + printf " %s_b\t%s\n" "${LINUX_NAME}" "${INSTALL_LINUX_FILENAME}" + fi + printf " %s_a\t%s\n" "${ROOTFS_NAME}" "${INSTALL_ROOTFS_FILENAME}" + if [ "${INSTALL_DUALBOOT}" = true ]; then + printf " %s_b\t%s\n" "${ROOTFS_NAME}" "${INSTALL_ROOTFS_FILENAME}" + fi + else + printf " %s\t%s\n" "${LINUX_NAME}" "${INSTALL_LINUX_FILENAME}" + printf " %s\t%s\n" "${RECOVERY_NAME}" "${INSTALL_RECOVERY_FILENAME}" + printf " %s\t%s\n" "${ROOTFS_NAME}" "${INSTALL_ROOTFS_FILENAME}" + fi + printf "\n" + printf " Press CTRL+C now if you wish to abort.\n" + printf "\n" + while [ ${WAIT} -gt 0 ]; do + printf "\r Update process starts in %d " ${WAIT} + sleep 1 + WAIT="$((WAIT - 1))" + done + printf "\r \n" + printf " Starting update process\n" +fi + +# Skip user confirmation for U-Boot update +uuu fb: ucmd setenv forced_update 1 + +# Update ATF +part_update "boot1" "${INSTALL_ATF_FILENAME}" 5000 +part_update "boot2" "${INSTALL_ATF_FILENAME}" 5000 + +# Update metadata +part_update "metadata1" "${INSTALL_METADATA_FILENAME}" 5000 +part_update "metadata2" "${INSTALL_METADATA_FILENAME}" 5000 + +# Update FIP +part_update "fip-a" "${INSTALL_FIP_FILENAME}" 5000 +part_update "fip-b" "${INSTALL_FIP_FILENAME}" 5000 + +# Set 'bootcmd' for the second part of the script that will +# - Reset environment to defaults +# - Keep the 'dualboot' status +# - Reset the bootcount +# - Set bootlimit (if required) +# - Save the environment +# - Update the 'linux' partition(s) +# - Update the 'rootfs' partition(s) +uuu fb: ucmd setenv bootcmd " + env default -a; + setenv dualboot \${dualboot}; + bootcount reset; + ${bootlimit_cmd}; + saveenv; + echo \"\"; + echo \"\"; + echo \">> Creating Linux partition table on the eMMC\"; + echo \"\"; + echo \"\"; + run partition_mmc_linux; + if test \$? -eq 1; then + echo \"[ERROR] Failed to create Linux partition table!\"; + echo \"\"; + echo \"Aborted.\"; + exit; + fi; + echo \"\"; + echo \"\"; + echo \">> Start installation Linux firmware files\"; + echo \"\"; + echo \"\"; + saveenv; + fastboot 0; +" + +uuu fb: ucmd saveenv +uuu fb: acmd reset + +# Wait for the target to reset +sleep 3 + +# Restart fastboot with the latest MMC partition configuration +uuu fb: ucmd setenv fastboot_dev sata +uuu fb: ucmd setenv fastboot_dev mmc + +if [ "${DUALBOOT}" = true ]; then + # Update Linux A + part_update "${LINUX_NAME}_a" "${INSTALL_LINUX_FILENAME}" 15000 + # Update Linux B + if [ "${INSTALL_DUALBOOT}" = true ]; then + part_update "${LINUX_NAME}_b" "${INSTALL_LINUX_FILENAME}" 15000 + fi + # Update Rootfs A + part_update "${ROOTFS_NAME}_a" "${INSTALL_ROOTFS_FILENAME}" 120000 + # Update Rootfs B + if [ "${INSTALL_DUALBOOT}" = true ]; then + part_update "${ROOTFS_NAME}_b" "${INSTALL_ROOTFS_FILENAME}" 120000 + fi +else + # Update Linux + part_update "${LINUX_NAME}" "${INSTALL_LINUX_FILENAME}" 15000 + # Update Recovery + part_update "${RECOVERY_NAME}" "${INSTALL_RECOVERY_FILENAME}" 15000 + # Update Rootfs + part_update "${ROOTFS_NAME}" "${INSTALL_ROOTFS_FILENAME}" 120000 + # Configure u-boot to boot into recovery mode and format the + # 'update' partition + uuu fb: ucmd setenv boot_recovery yes + uuu fb: ucmd setenv recovery_command wipe_update + uuu fb: ucmd saveenv +fi + +# Set the dboot_kernel_var to fitimage if Trustfence is enabled +if [ "${TRUSTFENCE}" = "true" ] || echo "${INSTALL_UBOOT_FILENAME}" | grep -q -e "signed"; then + uuu fb: ucmd setenv dboot_kernel_var fitimage + uuu fb: ucmd saveenv +fi + +# Reset the bootcount +uuu fb: acmd bootcount reset +# Reset the target +uuu fb: acmd reset + +printf "\033[32m\n" +printf "=============================================================\n" +printf "Done! Wait for the target to complete first boot process.\n" +printf "=============================================================\n" +printf "\033[0m\n" + +exit diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp25-dvk/boot.txt b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp25-dvk/boot.txt new file mode 100644 index 000000000..d19cd4301 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey/ccmp25-dvk/boot.txt @@ -0,0 +1,82 @@ +# +# U-Boot bootscript for EMMC/SD images created by Yocto. +# + +# As the first step in the boot script, check if we are using DualBoot. This +# requires the script to change some variables and save them, while the rest +# of the script changes variables only temporarily without saving them. + +# Build boot attempt message string +if test "${bootlimit}" -gt 0 && test "${bootcount}" -gt 0; then + bootattempt="(boot attempt ${bootcount}/${bootlimit})" +fi + +# Pre step: check if we boot from uSD. +if test "${mmcbootdev}" = "1"; then + # We are booting from the SD card. + setenv mmcroot /dev/mmcblk${mmcbootdev}p2 +elif test "${dualboot}" = "yes"; then + if test "${active_system}" = "linux_a"; then + echo "Booting from system A ${bootattempt}" + part number mmc ${mmcbootdev} linux_a tmp_mmcpart + part number mmc ${mmcbootdev} rootfs_a tmp_rootfs_index + else + echo "Booting from system B ${bootattempt}" + part number mmc ${mmcbootdev} linux_b tmp_mmcpart + part number mmc ${mmcbootdev} rootfs_b tmp_rootfs_index + fi + part uuid mmc ${mmcbootdev}:${tmp_rootfs_index} tmp_mmcroot + if test "${mmcpart}" -ne "${tmp_mmcpart}"; then + setexpr mmcpart ${tmp_mmcpart} + env_save_needed="1" + fi + if test "${mmcroot}" != "PARTUUID=${tmp_mmcroot}"; then + setenv mmcroot PARTUUID=${tmp_mmcroot} + env_save_needed="1" + fi + if test "${env_save_needed}" = "1"; then + env delete tmp_mmcpart tmp_rootfs_index tmp_mmcroot + env save + fi +else + echo "Booting system ${bootattempt}" + # Get the UUID of the configured boot partition. + part uuid mmc ${mmcbootdev}:${mmcpart} bootpart + # Check the boot source. + if test "${bootpart}" = "${part5_uuid}"; then + # We are booting from the eMMC using 'linux'. + true + elif test "${bootpart}" = "${part6_uuid}"; then + # We are booting from the eMMC using 'recovery'. + setenv boot_initrd true + setenv initrd_file uramdisk-recovery.img + fi +fi + +# Back up environment variables +setenv ORIG_overlays ${overlays} + +# +# Determine overlays to apply depending on the hardware capabilities +# described by the HWID, SOM version, and carrier board version. +# +setexpr module_has_wifi ${hwid_2} \& 10000 +setexpr module_has_wifi ${module_has_wifi} / 10000 +setexpr module_has_bt ${hwid_2} \& 20000 +setexpr module_has_bt ${module_has_bt} / 20000 + +if test "${module_has_bt}" = "1" && test -z "${disable_bt}"; then + setenv overlays _ov_som_bt_ccmp25.dtbo,${overlays} +fi + +if test "${module_has_wifi}" = "1" && test -z "${disable_wifi}"; then + setenv overlays _ov_som_wifi_ccmp25.dtbo,${overlays} +fi + +dboot linux mmc ${mmcbootdev}:${mmcpart} + +# We only get here in case of an error on the dboot command. + +# Undo changes to environment variables +setenv overlays ${ORIG_overlays} +setenv ORIG_overlays diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2017.03.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2017.03.bb index 1a3fa59a3..ab6c1ce34 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2017.03.bb +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2017.03.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2018-2023 Digi International +# Copyright (C) 2018-2023, Digi International Inc. require u-boot-dey.inc diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2020.04.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2020.04.bb index 4f845bdd2..e8020ae16 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2020.04.bb +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2020.04.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2020-2023 Digi International +# Copyright (C) 2020-2023, Digi International Inc. require u-boot-dey.inc LIC_FILES_CHKSUM = "file://Licenses/README;md5=30503fd321432fc713238f582193b78e" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb index 22ee05f7d..82c0ed42d 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2024 Digi International +# Copyright (C) 2022-2024, Digi International Inc. require u-boot-dey.inc LIC_FILES_CHKSUM = "file://Licenses/README;md5=5a7450c57ffe5ae63fd732446b988025" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2022.10.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2022.10.bb new file mode 100644 index 000000000..11f0da850 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2022.10.bb @@ -0,0 +1,35 @@ +# Copyright (C) 2024 Digi International Inc. + +require u-boot-dey.inc +LIC_FILES_CHKSUM = "file://Licenses/README;md5=2ca5f2c35c8cc335f0a19756634782f1" + +DEPENDS += "flex-native bison-native" +DEPENDS += "python3-setuptools-native" + +SRCBRANCH = "v2022.10/master" +SRCREV = "${AUTOREV}" + +SRC_URI += " \ + ${@oe.utils.conditional('TRUSTFENCE_SIGN_FIT_STM', '1', 'file://fit_signature.cfg', '', d)} \ +" + +install_helper_files() { + # Install dtbs from UBOOT_DEVICETREE to datadir, so that kernel + # can use it for signing, and kernel will deploy after signs it. + if [ -n "${UBOOT_DEVICETREE}" ]; then + for devicetree in ${UBOOT_DEVICETREE}; do + install -Dm 0644 ${B}/${config}/arch/arm/dts/${devicetree}.dtb ${D}${datadir}/${devicetree}.dtb + done + else + bbwarn "${UBOOT_DEVICETREE} not found" + fi +} + +do_install:append() { + # Copy additional files, so kernel can use it when creating the FIT image + if [ "${KERNEL_IMAGETYPE}" = "fitImage" ]; then + install_helper_files + fi +} + +COMPATIBLE_MACHINE = "(ccmp2)" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2023.04.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2023.04.bb index ca022b584..e7876a683 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2023.04.bb +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2023.04.bb @@ -1,4 +1,4 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. require u-boot-dey.inc LIC_FILES_CHKSUM = "file://Licenses/README;md5=2ca5f2c35c8cc335f0a19756634782f1" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2024.04.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2024.04.bb new file mode 100644 index 000000000..f946687ee --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2024.04.bb @@ -0,0 +1,12 @@ +# Copyright (C) 2024, Digi International Inc. + +require u-boot-dey.inc + +LIC_FILES_CHKSUM = "file://Licenses/README;md5=2ca5f2c35c8cc335f0a19756634782f1" + +DEPENDS += "flex-native bison-native" + +SRCBRANCH = "v2024.04/master" +SRCREV = "${AUTOREV}" + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/recipes-bsp/usbutils/usbutils_%.bbappend b/meta-digi-arm/recipes-bsp/usbutils/usbutils_%.bbappend index 88dc03f0c..e4e0c0b50 100644 --- a/meta-digi-arm/recipes-bsp/usbutils/usbutils_%.bbappend +++ b/meta-digi-arm/recipes-bsp/usbutils/usbutils_%.bbappend @@ -1,3 +1,3 @@ -# Copyright (C) 2018 Digi International. +# Copyright (C) 2018, Digi International Inc. RRECOMMENDS:${PN}:remove = "udev-hwdb" diff --git a/meta-digi-arm/recipes-connectivity/nxp-wlan-sdk/iw612-sdk_git.bbappend b/meta-digi-arm/recipes-connectivity/nxp-wlan-sdk/iw612-sdk_git.bbappend index 3e5085c3b..c66efe31d 100644 --- a/meta-digi-arm/recipes-connectivity/nxp-wlan-sdk/iw612-sdk_git.bbappend +++ b/meta-digi-arm/recipes-connectivity/nxp-wlan-sdk/iw612-sdk_git.bbappend @@ -1,3 +1,3 @@ -# Copyright (C) 2023 Digi International. +# Copyright (C) 2023, Digi International Inc. RRECOMMENDS:${PN}:remove = "wireless-tools" diff --git a/meta-digi-arm/recipes-core/packagegroup/nativesdk-packagegroup-sdk-host.bbappend b/meta-digi-arm/recipes-core/packagegroup/nativesdk-packagegroup-sdk-host.bbappend index bd339562f..0252e6330 100644 --- a/meta-digi-arm/recipes-core/packagegroup/nativesdk-packagegroup-sdk-host.bbappend +++ b/meta-digi-arm/recipes-core/packagegroup/nativesdk-packagegroup-sdk-host.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2023 Digi International. +# Copyright (C) 2016-2023, Digi International Inc. IMX_OPTEE_SDK_RDEPENDS ?= " \ nativesdk-python3-cryptography \ diff --git a/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend b/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend index 43e98f3f2..ff0833f43 100644 --- a/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend +++ b/meta-digi-arm/recipes-core/udev/udev-extraconf_1.1.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2022 Digi International. +# Copyright (C) 2013-2022, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" diff --git a/meta-digi-arm/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb b/meta-digi-arm/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb index d9114868c..00afd665b 100644 --- a/meta-digi-arm/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb +++ b/meta-digi-arm/recipes-digi/cryptoauthlib/cryptoauthlib_git.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2023 Digi International Inc. +# Copyright (C) 2017-2023, Digi International Inc. SUMMARY = "Microchip CryptoAuthentication Library" SECTION = "libs" diff --git a/meta-digi-arm/recipes-digi/mca/mca-tool_1.25.bb b/meta-digi-arm/recipes-digi/mca/mca-tool_1.25.bb index 49a956947..bb65ade1e 100644 --- a/meta-digi-arm/recipes-digi/mca/mca-tool_1.25.bb +++ b/meta-digi-arm/recipes-digi/mca/mca-tool_1.25.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2023 Digi International. +# Copyright (C) 2016-2023, Digi International Inc. SUMMARY = "MCA firmware management tool" SECTION = "console/tools" diff --git a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-nxp.sh b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-nxp.sh index 3413d0121..d8fba2925 100755 --- a/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-nxp.sh +++ b/meta-digi-arm/recipes-digi/trustfence/trustfence-sign-tools/trustfence-sign-artifact-nxp.sh @@ -101,6 +101,7 @@ done<<-_EOF_ ccimx8mm 0x40480000 0x43800000 0x43000000 - HAB 0x2000 "-h 4 -d sha256" ccimx8mn 0x40480000 0x43800000 0x43000000 - HAB 0x2000 "-h 4 -d sha256" ccimx8x 0x80280000 0x82100000 0x82000000 - AHAB - "-a -d sha512 -s sha512" + ccimx91 - - - 0x84000000 AHAB - "-a -d sha256 -s sha512" ccimx93 - - - 0x84000000 AHAB - "-a -d sha256 -s sha512" _EOF_ @@ -127,6 +128,8 @@ eval "CONFIG_CSF_SIZE=\"\${${PLATFORM}_csf_size}\"" # Rootfs is loaded to $initrd_addr, just like the ramdisk [ "${ARTIFACT_ROOTFS}" = "y" ] && CONFIG_RAM_START="${CONFIG_RAMDISK_LOADADDR}" +# For ccimx91 do not require image type (assume FIT image) +[ "${PLATFORM}" = "ccimx91" ] && CONFIG_RAM_START="${CONFIG_FIT_LOADADDR}" # For ccimx93 do not require image type (assume FIT image) [ "${PLATFORM}" = "ccimx93" ] && CONFIG_RAM_START="${CONFIG_FIT_LOADADDR}" diff --git a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb index 29213a4a1..c4b3fcaa7 100644 --- a/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb +++ b/meta-digi-arm/recipes-kernel/kernel-module-qualcomm/kernel-module-qualcomm.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2023 Digi International. +# Copyright (C) 2016-2023, Digi International Inc. SUMMARY = "Qualcomm's wireless driver for qca65xx" DESCRIPTION = "qcacld-2.0 module" diff --git a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-nxp-wlan.bbappend b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-nxp-wlan.bbappend index c719f0fe6..42d9d536b 100644 --- a/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-nxp-wlan.bbappend +++ b/meta-digi-arm/recipes-kernel/kernel-modules/kernel-module-nxp-wlan.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Digi International. +# Copyright (C) 2023, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" @@ -7,6 +7,10 @@ SRC_URI:append = " \ file://load_iw612.sh \ " +SRCBRANCH:ccimx91 = "lf-6.6.23_2.0.0" +SRCREV:ccimx91 = "88372772badbf30152b3ad12ae251dc567095cab" +S:ccimx91 = "${WORKDIR}/git" + do_install:append () { install -d ${D}${sysconfdir}/udev/rules.d install -m 0644 ${WORKDIR}/81-iw612-wifi.rules ${D}${sysconfdir}/udev/rules.d/ diff --git a/meta-digi-arm/recipes-kernel/linux-firmware/linux-firmware_%.bbappend b/meta-digi-arm/recipes-kernel/linux-firmware/linux-firmware_%.bbappend index d48561cab..bf4f143f5 100644 --- a/meta-digi-arm/recipes-kernel/linux-firmware/linux-firmware_%.bbappend +++ b/meta-digi-arm/recipes-kernel/linux-firmware/linux-firmware_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2022 Digi International +# Copyright (C) 2022, Digi International Inc. # This is an excerpt from the *.bbappend in meta-imx, containing only the # minimum necessary changes for bitbake to use the SDMA firmware from the diff --git a/meta-digi-arm/recipes-kernel/linux-libc-headers/linux-libc-headers_5.16.bbappend b/meta-digi-arm/recipes-kernel/linux-libc-headers/linux-libc-headers_5.16.bbappend index 44b805c5a..4b2e86b69 100644 --- a/meta-digi-arm/recipes-kernel/linux-libc-headers/linux-libc-headers_5.16.bbappend +++ b/meta-digi-arm/recipes-kernel/linux-libc-headers/linux-libc-headers_5.16.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2020-2022 Digi International, Inc. +# Copyright (C) 2020-2022, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey.inc b/meta-digi-arm/recipes-kernel/linux/linux-dey.inc index 3aa8c98d7..cce001bf3 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey.inc +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2018-2024 Digi International +# Copyright (C) 2018-2024, Digi International Inc. SUMMARY = "Linux kernel for Digi boards" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb index 799c39143..a4ba1aa21 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2024 Digi International +# Copyright (C) 2022-2024, Digi International Inc. require recipes-kernel/linux/linux-dey.inc diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_6.1.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_6.1.bb index cecbac7ce..8320996c6 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_6.1.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_6.1.bb @@ -1,8 +1,11 @@ -# Copyright (C) 2023-2024 Digi International +# Copyright (C) 2023,2024, Digi International Inc. require recipes-kernel/linux/linux-dey.inc SRCBRANCH = "v6.1/nxp/dey-4.0/maint" +SRCBRANCH:stm32mp2common = "v6.1.28/stm/master" +SRCREV = "${AUTOREV}" +SRCREV:stm32mp2common = "${AUTOREV}" # Patch series for RT Kernel NXP_RT_PATCHES = " \ @@ -23,10 +26,28 @@ SRC_URI:append = " \ ${@bb.utils.contains('DISTRO_FEATURES', 'tsn', 'file://tsn_conf.cfg', '', d)} \ " -SRCREV = "${AUTOREV}" - # Blacklist btnxpuart module. It will be managed by the bluetooth-init script KERNEL_MODULE_PROBECONF += "btnxpuart" module_conf_btnxpuart = "blacklist btnxpuart" -COMPATIBLE_MACHINE = "(ccimx93)" +# --------------------------------------------------------------------- +# stub for devicetree which are located on digi directory +do_install:prepend:ccmp2() { + if [ -d "${B}/arch/${ARCH}/boot/dts/digi" ]; then + for dtbf in ${KERNEL_DEVICETREE}; do + install -m 0644 "${B}/arch/${ARCH}/boot/dts/digi/${dtbf}" "${B}/arch/${ARCH}/boot/dts/" + done + fi +} + +do_install:append:ccmp2() { + if ${@bb.utils.contains('MACHINE_FEATURES','gpu','true','false',d)}; then + # when ACCEPT_EULA are filled + install -d ${D}/${sysconfdir}/modprobe.d/ + echo "blacklist etnaviv" > ${D}/${sysconfdir}/modprobe.d/blacklist.conf + fi +} + +FILES:${KERNEL_PACKAGE_NAME}-modules:ccmp2 += "${sysconfdir}/modprobe.d" + +COMPATIBLE_MACHINE = "(ccimx93|ccmp2)" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_6.6.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_6.6.bb new file mode 100644 index 000000000..ee482354e --- /dev/null +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_6.6.bb @@ -0,0 +1,12 @@ +# Copyright (C) 2024, Digi International Inc. + +require recipes-kernel/linux/linux-dey.inc + +SRCBRANCH = "v6.6.23/nxp/master" +SRCREV = "${AUTOREV}" + +# Blacklist btnxpuart module. It will be managed by the bluetooth-init script +KERNEL_MODULE_PROBECONF += "btnxpuart" +module_conf_btnxpuart = "blacklist btnxpuart" + +COMPATIBLE_MACHINE = "(ccimx91)" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-trustfence.inc b/meta-digi-arm/recipes-kernel/linux/linux-trustfence.inc index 1a65fc204..3b6d95c59 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-trustfence.inc +++ b/meta-digi-arm/recipes-kernel/linux/linux-trustfence.inc @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Digi International +# Copyright (C) 2022,2023, Digi International Inc. DEPENDS += "${@oe.utils.vartrue('TRUSTFENCE_SIGN_ARTIFACTS', 'trustfence-sign-tools-native', '', d)}" diff --git a/meta-digi-arm/wic/ccmp1-signed-1GB.wks.in b/meta-digi-arm/wic/ccmp1-signed-1GB.wks.in new file mode 100644 index 000000000..7ff966d5d --- /dev/null +++ b/meta-digi-arm/wic/ccmp1-signed-1GB.wks.in @@ -0,0 +1,37 @@ +# short-description: Create signed SD card image with a boot partition (1GB) +# long-description: Creates a partitioned SD card image with signed artifacts (1GB) +# +# - -------- ------------- ------ ------ ------------ -------- --------- -------- +# | | TFA(2) | Metadata(2) | FIPA | FIPB | U-BOOT ENV | linux | rootfs | data | +# - -------- ------------- ------ ------ ------------ -------- --------- -------- +# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +# | | | | | | | | | | +# 0 17kB 542kB 1.06MB 5.26MB 9.45MB 9.97MB 77.1MB 898MB 1032MB +# +# Warning: the first stage of boot (here fsbl1, fsbl2, metadata1, metadata2, fipa, fipb) MUST be on GPT partition to be detected. +# + +# FSBL partitions aka TF-A BL2 +part fsbl1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbl1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-1GB-sdcard.stm32_signed" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K --align 17 +part fsbl2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbl2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-1GB-sdcard.stm32_signed" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Metadata partitions +part metadata1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K +part metadata2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Fip partitions +part fip-a --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-a --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-1GB-optee_Signed.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 4fd84c93-54ef-463f-a7ef-ae25ff887087 +part fip-b --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-b --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-1GB-optee_Signed.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 09c54952-d5bf-45af-acee-335303766fb3 + +# U-BOOT env +part u-boot-env --source empty --part-name=uboot-env --ondisk mmcblk --part-type 0x8301 --fixed-size 512K + +# linux +part --source rawcopy --sourceparams="file=${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.boot.vfat" --ondisk mmcblk --fstype=vfat --part-name=linux --active --fixed-size 64M + +# Rootfs +part / --source rootfs --ondisk mmcblk --fstype=ext4 --label rootfs --fixed-size 783M --uuid e91c4e10-16e6-4c0e-bd0e-77becf4a3582 --part-name=rootfs +# data +part data --ondisk mmcblk --fstype=ext4 --label data --fixed-size 128M --part-name=data + +bootloader --ptable gpt diff --git a/meta-digi-arm/wic/ccmp1-signed-256MB.wks.in b/meta-digi-arm/wic/ccmp1-signed-256MB.wks.in new file mode 100644 index 000000000..703f36797 --- /dev/null +++ b/meta-digi-arm/wic/ccmp1-signed-256MB.wks.in @@ -0,0 +1,37 @@ +# short-description: Create SD card image with a boot partition (1GB) +# long-description: Creates a partitioned SD card image (1GB) +# +# - -------- ------------- ------ ------ ------------ -------- --------- -------- +# | | TFA(2) | Metadata(2) | FIPA | FIPB | U-BOOT ENV | linux | rootfs | data | +# - -------- ------------- ------ ------ ------------ -------- --------- -------- +# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +# | | | | | | | | | | +# 0 17kB 542kB 1.06MB 5.26MB 9.45MB 9.97MB 77.1MB 898MB 1032MB +# +# Warning: the first stage of boot (here fsbl1, fsbl2, metadata1, metadata2, fipa, fipb) MUST be on GPT partition to be detected. +# + +# FSBL partitions aka TF-A BL2 +part fsbl1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbl1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-256MB-sdcard.stm32_signed" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K --align 17 +part fsbl2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbl2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-256MB-sdcard.stm32_signed" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Metadata partitions +part metadata1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K +part metadata2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Fip partitions +part fip-a --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-a --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-256MB-optee_Signed.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 4fd84c93-54ef-463f-a7ef-ae25ff887087 +part fip-b --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-b --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-256MB-optee_Signed.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 09c54952-d5bf-45af-acee-335303766fb3 + +# U-BOOT env +part u-boot-env --source empty --part-name=uboot-env --ondisk mmcblk --part-type 0x8301 --fixed-size 512K + +# linux +part --source rawcopy --sourceparams="file=${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.boot.vfat" --ondisk mmcblk --fstype=vfat --part-name=linux --active --fixed-size 64M + +# Rootfs +part / --source rootfs --ondisk mmcblk --fstype=ext4 --label rootfs --fixed-size 783M --uuid e91c4e10-16e6-4c0e-bd0e-77becf4a3582 --part-name=rootfs +# data +part data --ondisk mmcblk --fstype=ext4 --label data --fixed-size 128M --part-name=data + +bootloader --ptable gpt diff --git a/meta-digi-arm/wic/ccmp1-signed-512MB.wks.in b/meta-digi-arm/wic/ccmp1-signed-512MB.wks.in new file mode 100644 index 000000000..cae5964be --- /dev/null +++ b/meta-digi-arm/wic/ccmp1-signed-512MB.wks.in @@ -0,0 +1,37 @@ +# short-description: Create signed SD card image with a boot partition (1GB) +# long-description: Creates a partitioned SD card image with signed artifacts (1GB) +# +# - -------- ------------- ------ ------ ------------ -------- --------- -------- +# | | TFA(2) | Metadata(2) | FIPA | FIPB | U-BOOT ENV | linux | rootfs | data | +# - -------- ------------- ------ ------ ------------ -------- --------- -------- +# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +# | | | | | | | | | | +# 0 17kB 542kB 1.06MB 5.26MB 9.45MB 9.97MB 77.1MB 898MB 1032MB +# +# Warning: the first stage of boot (here fsbl1, fsbl2, metadata1, metadata2, fipa, fipb) MUST be on GPT partition to be detected. +# + +# FSBL partitions aka TF-A BL2 +part fsbl1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbl1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-512MB-sdcard.stm32_signed" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K --align 17 +part fsbl2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbl2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-512MB-sdcard.stm32_signed" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Metadata partitions +part metadata1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K +part metadata2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Fip partitions +part fip-a --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-a --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-512MB-optee_Signed.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 4fd84c93-54ef-463f-a7ef-ae25ff887087 +part fip-b --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-b --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-512MB-optee_Signed.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 09c54952-d5bf-45af-acee-335303766fb3 + +# U-BOOT env +part u-boot-env --source empty --part-name=uboot-env --ondisk mmcblk --part-type 0x8301 --fixed-size 512K + +# linux +part --source rawcopy --sourceparams="file=${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.boot.vfat" --ondisk mmcblk --fstype=vfat --part-name=linux --active --fixed-size 64M + +# Rootfs +part / --source rootfs --ondisk mmcblk --fstype=ext4 --label rootfs --fixed-size 783M --uuid e91c4e10-16e6-4c0e-bd0e-77becf4a3582 --part-name=rootfs +# data +part data --ondisk mmcblk --fstype=ext4 --label data --fixed-size 128M --part-name=data + +bootloader --ptable gpt diff --git a/meta-digi-arm/wic/ccmp2-1GB.wks.in b/meta-digi-arm/wic/ccmp2-1GB.wks.in new file mode 100644 index 000000000..54dbbaed4 --- /dev/null +++ b/meta-digi-arm/wic/ccmp2-1GB.wks.in @@ -0,0 +1,42 @@ +# short-description: Create SD card image with a boot partition (1GB) +# long-description: Creates a partitioned SD card image (1GB) +# +# - -------- ------------- ------ ------ ------------ -------- --------- ------------------------ +# | | TFA(2) | Metadata(2) | FIPA | FIPB | U-BOOT ENV | linux | rootfs | safe | safe2 | data | +# - -------- ------------- ------ ------ ------------ -------- --------- ------------------------ +# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +# | | | | | | | | | | | | +# 0 17kB 542kB 1.06MB 5.26MB 9.45MB 9.97MB 77.1MB 898MB 1032MB +# +# Warning: the first stage of boot (here fsbl1, fsbl2, metadata1, metadata2, fipa, fipb) MUST be on GPT partition to be detected. +# + +# FSBL partitions aka TF-A BL2 +part fsbla1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbla1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-sdcard.stm32" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K --align 17 +part fsbla2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fsbla2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/tf-a-${MACHINE}-sdcard.stm32" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Metadata partitions +part metadata1 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata1 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K +part metadata2 --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=metadata2 --sourceparams="file=${DEPLOY_DIR_IMAGE}/arm-trusted-firmware/metadata.bin" --ondisk mmcblk --part-type 0x8301 --fixed-size 256K + +# Fip partitions +part fip-a --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-a --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-optee.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 4fd84c93-54ef-463f-a7ef-ae25ff887087 +part fip-b --source rawcopy --fstype=ext4 --fsoptions "noauto" --part-name=fip-b --sourceparams="file=${DEPLOY_DIR_IMAGE}/fip/fip-${MACHINE}-optee.bin" --ondisk mmcblk --part-type 19d5df83-11b0-457b-be2c-7559c13142a5 --fixed-size 4096K --uuid 09c54952-d5bf-45af-acee-335303766fb3 + +# U-BOOT env +part u-boot-env --source empty --part-name=uboot-env --ondisk mmcblk --part-type 0x8301 --fixed-size 512K + +# linux +part --source rawcopy --sourceparams="file=${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.boot.vfat" --ondisk mmcblk --fstype=vfat --part-name=linux --active --fixed-size 64M + +# Rootfs +part / --source rootfs --ondisk mmcblk --fstype=ext4 --label rootfs --fixed-size 783M --uuid e91c4e10-16e6-4c0e-bd0e-77becf4a3582 --part-name=rootfs + +# Safe +part safe --source empty --ondisk mmcblk --fsoptions "noauto" --part-name=safe --part-type 0x8301 --fixed-size 256K +part safe2 --source empty --ondisk mmcblk --fsoptions "noauto" --part-name=safe2 --part-type 0x8301 --fixed-size 256K + +# data +part data --ondisk mmcblk --fstype=ext4 --label data --fixed-size 128M --part-name=data + +bootloader --ptable gpt diff --git a/meta-digi-dey/classes/dey-image-installer.bbclass b/meta-digi-dey/classes/dey-image-installer.bbclass index 523168e15..1211e7e70 100644 --- a/meta-digi-dey/classes/dey-image-installer.bbclass +++ b/meta-digi-dey/classes/dey-image-installer.bbclass @@ -1,7 +1,7 @@ # # Generate DEY installer ZIP package # -# Copyright 2017-2023, Digi International Inc. +# Copyright 2017-2024, Digi International Inc. # DEPENDS += "zip-native" @@ -27,8 +27,9 @@ FSTYPES_WHITELIST:ccmp1 = " \ HAS_USB_DRIVER = "false" HAS_USB_DRIVER:ccimx8m = "true" -HAS_USB_DRIVER:ccimx93 = "true" +HAS_USB_DRIVER:ccimx9 = "true" HAS_USB_DRIVER:ccmp1 = "true" +HAS_USB_DRIVER:ccmp2 = "true" generate_installer_zip () { # Get list of files to pack diff --git a/meta-digi-dey/classes/dey-swupdate-common.bbclass b/meta-digi-dey/classes/dey-swupdate-common.bbclass index bad51a542..160702af3 100644 --- a/meta-digi-dey/classes/dey-swupdate-common.bbclass +++ b/meta-digi-dey/classes/dey-swupdate-common.bbclass @@ -28,6 +28,12 @@ BOOT_DEV_NAME_B ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p2 ROOTFS_DEV_NAME_A ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p3', 'rootfs_a', d)}" ROOTFS_DEV_NAME_B ?= "${@bb.utils.contains('STORAGE_MEDIA', 'mmc', '/dev/mmcblk0p4', 'rootfs_b', d)}" +# Partition table is different in ccmp25 +BOOT_DEV_NAME_A:ccmp25 ?= "/dev/mmcblk0p5" +BOOT_DEV_NAME_B:ccmp25 ?= "/dev/mmcblk0p6" +ROOTFS_DEV_NAME_A:ccmp25 ?= "/dev/mmcblk0p7" +ROOTFS_DEV_NAME_B:ccmp25 ?= "/dev/mmcblk0p8" + ####################################### ###### SWU Update based on files ###### ####################################### @@ -93,7 +99,7 @@ SWUPDATE_UBOOT_SCRIPT_NAME = "${@os.path.basename(d.getVar('SWUPDATE_UBOOT_SCRIP # Retrieve the correct U-Boot prefix. def get_uboot_prefix(d): prefix = d.getVar('UBOOT_PREFIX') - if d.getVar('DEY_SOC_VENDOR') == "NXP" and d.getVar('TRUSTFENCE_SIGN') == "1": + if d.getVar('DEY_SOC_VENDOR') == "NXP" and d.getVar('TRUSTFENCE_ENABLED') == "1": if "ccimx6" in d.getVar('MACHINE'): prefix = f"{prefix}-dtb" if d.getVar('TRUSTFENCE_DEK_PATH') and d.getVar('TRUSTFENCE_DEK_PATH') != "0": diff --git a/meta-digi-dey/classes/trustfence.bbclass b/meta-digi-dey/classes/trustfence.bbclass index dfdc0c227..5ba8f39ad 100644 --- a/meta-digi-dey/classes/trustfence.bbclass +++ b/meta-digi-dey/classes/trustfence.bbclass @@ -33,9 +33,9 @@ TRUSTFENCE_SIGN_FIT_STM:ccmp1 ?= "1" # Partition encryption configuration TRUSTFENCE_ENCRYPT_PARTITIONS ?= "1" -TRUSTFENCE_ENCRYPT_PARTITIONS:ccimx93 ?= "0" +TRUSTFENCE_ENCRYPT_PARTITIONS:ccimx9 ?= "0" TRUSTFENCE_ENCRYPT_ROOTFS ?= "${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", "0", "1", d)}" -TRUSTFENCE_ENCRYPT_ROOTFS:ccimx93 ?= "0" +TRUSTFENCE_ENCRYPT_ROOTFS:ccimx9 ?= "0" TRUSTFENCE_FILE_BASED_ENCRYPT ?= "${TF_FILE_BASED_ENCRYPT}" # Read-only rootfs @@ -47,15 +47,15 @@ TRUSTFENCE_READ_ONLY_ROOTFS ?= "${@bb.utils.contains("IMAGE_FEATURES", "read-onl # Platform specific defaults TF_DEK_PATH = "default" -TF_DEK_PATH:ccimx93 = "0" +TF_DEK_PATH:ccimx9 = "0" TF_DEK_PATH:ccmp1 = "0" TF_FILE_BASED_ENCRYPT = "0" -TF_FILE_BASED_ENCRYPT:ccimx93 = "1" +TF_FILE_BASED_ENCRYPT:ccimx9 = "1" TF_FILE_BASED_ENCRYPT:ccmp1 = "1" # NXP-based sign a FIT-format boot artifact TRUSTFENCE_SIGN_FIT_NXP = "0" -TRUSTFENCE_SIGN_FIT_NXP:ccimx93 = "${TRUSTFENCE_SIGN_ARTIFACTS}" +TRUSTFENCE_SIGN_FIT_NXP:ccimx9 = "${TRUSTFENCE_SIGN_ARTIFACTS}" IMAGE_FEATURES += "dey-trustfence" diff --git a/meta-digi-dey/conf/distro/dey.conf b/meta-digi-dey/conf/distro/dey.conf index d83d6d05d..5639e4b7d 100644 --- a/meta-digi-dey/conf/distro/dey.conf +++ b/meta-digi-dey/conf/distro/dey.conf @@ -1,9 +1,10 @@ require conf/distro/poky.conf +require include/time64.inc # Discrete version values. YOCTO_MAJOR = "4" YOCTO_MINOR = "0" -DEY_RELEASE = "6" +DEY_RELEASE = "7" DEY_BUILD = "1" # Firmware version of the system. @@ -37,6 +38,8 @@ GRAPHICAL_BACKEND = "${@bb.utils.contains('DISTRO_FEATURES', 'x11 wayland', 'xwa # Recovery initramfs image name. RECOVERY_INITRAMFS_IMAGE ?= "dey-image-recovery-initramfs" +# Add initramfs into FIT image +INITRAMFS_IMAGE = '${@bb.utils.contains("KERNEL_IMAGETYPE", "fitImage", "${RECOVERY_INITRAMFS_IMAGE}", "", d)}' # DEY image features (alphabetical order) FEATURE_PACKAGES_dey-audio = "packagegroup-dey-audio" diff --git a/meta-digi-dey/conf/distro/include/time64.inc b/meta-digi-dey/conf/distro/include/time64.inc new file mode 100644 index 000000000..eeb4eb3bf --- /dev/null +++ b/meta-digi-dey/conf/distro/include/time64.inc @@ -0,0 +1,17 @@ +# Copyright (C) 2024, Digi International Inc. + +# Specify global CFLAGS for target to support 64 bit time +GLIBC_64BIT_TIME_FLAGS = " -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64" + +# Only needed for some 32-bit architectures +TARGET_CC_ARCH:append:arm = "${GLIBC_64BIT_TIME_FLAGS}" + +# Do not apply the 64Bit compile flag to the following packages +# to avoid build errors +GLIBC_64BIT_TIME_FLAGS:pn-alsa-lib = "" +GLIBC_64BIT_TIME_FLAGS:pn-glibc = "" +GLIBC_64BIT_TIME_FLAGS:pn-imx-gst1.0-plugin = "" +GLIBC_64BIT_TIME_FLAGS:pn-kbd = "" +GLIBC_64BIT_TIME_FLAGS:pn-pulseaudio = "" +GLIBC_64BIT_TIME_FLAGS:pn-v4l-utils = "" +GLIBC_64BIT_TIME_FLAGS:pn-zlib = "" diff --git a/meta-digi-dey/conf/layer.conf b/meta-digi-dey/conf/layer.conf index b247a724c..6427cd026 100644 --- a/meta-digi-dey/conf/layer.conf +++ b/meta-digi-dey/conf/layer.conf @@ -18,6 +18,8 @@ BBFILES_DYNAMIC += " \ stm-st-stm32mp:${LAYERDIR}/dynamic-layers/stm-st-stm32mp/*/*/*.bbappend \ stm32mpu-ai:${LAYERDIR}/dynamic-layers/stm32mpu-ai/*/*/*.bb \ stm32mpu-ai:${LAYERDIR}/dynamic-layers/stm32mpu-ai/*/*/*.bbappend \ + stm32mpu-ai:${LAYERDIR}/dynamic-layers/stm32mpu-ai/*/*/*/*.bb \ + stm32mpu-ai:${LAYERDIR}/dynamic-layers/stm32mpu-ai/*/*/*/*.bbappend \ qt5-layer:${LAYERDIR}/dynamic-layers/qt5-layer/*/*/*.bb \ qt5-layer:${LAYERDIR}/dynamic-layers/qt5-layer/*/*/*.bbappend \ qt5-layer:${LAYERDIR}/dynamic-layers/qt5-layer/${DEY_SOC_VENDOR}/*/*/*.bb \ diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.4.3.p4.6-aarch32.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.4.3.p4.6-aarch32.bbappend index 7effe3064..3bacb5d21 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.4.3.p4.6-aarch32.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/imx-gpu-viv/imx-gpu-viv_6.4.3.p4.6-aarch32.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Digi International +# Copyright (C) 2023, Digi International Inc. # We configure imx-gpu-viv driver as built-in, so there's no need to install # the module. diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/wayland-protocols_1.32.imx.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/wayland-protocols_1.32.imx.bb index 753f901ab..2dc440928 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/wayland-protocols_1.32.imx.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/wayland-protocols_1.32.imx.bb @@ -1,4 +1,4 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023, Digi International Inc. # # Reuse meta-freescale's wayland-protocols_1.25.imx.bb @@ -13,4 +13,4 @@ SRCREV = "7ece577d467f8afb2f5a2f7fff3761a1e0ee9dad" BBCLASSEXTEND = "native nativesdk" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston-init.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston-init.bbappend index 1636278eb..a547d5660 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston-init.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston-init.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2019-2023 Digi International. +# Copyright (C) 2019-2023, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston_11.0.3.imx.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston_11.0.3.imx.bb index 812675c8f..c720385a1 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston_11.0.3.imx.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-graphics/wayland/weston_11.0.3.imx.bb @@ -184,6 +184,6 @@ PACKAGECONFIG[imxg2d] = "-Drenderer-g2d=true,-Drenderer-g2d=false,virtual/libg2d LDFLAGS:append:imxgpu:libc-musl = " -Wl,--allow-shlib-undefined" PACKAGE_ARCH = "${MACHINE_SOCARCH}" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" ########### End of i.MX overrides ######### diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/alsa/imx-alsa-plugins_git.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/alsa/imx-alsa-plugins_git.bbappend index d1623a172..8c83673dc 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/alsa/imx-alsa-plugins_git.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/alsa/imx-alsa-plugins_git.bbappend @@ -1,4 +1,4 @@ -# Copyright 2023,2024 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. -SRCBRANCH:ccimx93 = "MM_04.08.02_2310_L6.1.y" -SRCREV:ccimx93 = "b2ba082e70333f187972ee4e85f63f9d2f608331" +SRCBRANCH:ccimx9 = "MM_04.08.02_2310_L6.1.y" +SRCREV:ccimx9 = "b2ba082e70333f187972ee4e85f63f9d2f608331" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gst-examples_%.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gst-examples_%.bbappend index 540d1a532..d4578d173 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gst-examples_%.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gst-examples_%.bbappend @@ -1,3 +1,3 @@ -# Copyright (C) 2021 Digi International Inc. +# Copyright (C) 2021, Digi International Inc. RRECOMMENDS:${PN}:ccimx6ul = "" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-meta-base.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-meta-base.bbappend index fbc297880..4e4f8de5f 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-meta-base.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-meta-base.bbappend @@ -1,9 +1,9 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. -RDEPENDS:gstreamer1.0-meta-base:remove:ccimx93 = " \ +RDEPENDS:gstreamer1.0-meta-base:remove:ccimx9 = " \ gstreamer1.0-plugins-base-videoscale \ gstreamer1.0-plugins-base-videoconvert \ " -RDEPENDS:gstreamer1.0-meta-base:append:ccimx93 = " \ +RDEPENDS:gstreamer1.0-meta-base:append:ccimx9 = " \ gstreamer1.0-plugins-base-videoconvertscale \ " diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.22.5.imx.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.22.5.imx.bb index d770502ad..d1c78ac9a 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.22.5.imx.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.22.5.imx.bb @@ -211,6 +211,6 @@ EXTRA_OEMESON += " \ -Dc_args="${CFLAGS} -I${STAGING_INCDIR_IMX}" \ " -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" ########### End of i.MX overrides ######### diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.22.5.imx.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.22.5.imx.bb index c4391f3c8..88f83ae68 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.22.5.imx.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.22.5.imx.bb @@ -145,6 +145,6 @@ EXTRA_OEMESON += "-Dc_args="${CFLAGS} -I${STAGING_INCDIR_IMX}"" # gcompat will address it during runtime LDFLAGS:append:imxgpu:libc-musl = " -Wl,--allow-shlib-undefined" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" ########### End of i.MX overrides ######### diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_%.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_%.bbappend index e8020d7bd..1de57bfd2 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_%.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_%.bbappend @@ -1,3 +1,3 @@ -# Copyright (C) 2021 Digi International Inc. +# Copyright (C) 2021, Digi International Inc. PACKAGECONFIG:append:ccimx6ul = " vpx" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.5.imx.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.5.imx.bb index 4fdf4408d..b51ab8433 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.5.imx.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.22.5.imx.bb @@ -114,6 +114,6 @@ SRCREV = "a4631334ad32abc513bde8f73491ef345f865a48" S = "${WORKDIR}/git" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" ########### End of i.MX overrides ######### diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.22.6.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.22.6.bb index b457a05f7..f8959cc93 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.22.6.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.22.6.bb @@ -9,4 +9,4 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343" SRC_URI[sha256sum] = "3e31454c98cb2f7f6d2d355eceb933a892fa0f1dc09bc36c9abc930d8e29ca48" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0_1.22.5.imx.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0_1.22.5.imx.bb index a4a0213e6..2fbf22457 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0_1.22.5.imx.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/gstreamer1.0_1.22.5.imx.bb @@ -107,6 +107,6 @@ S = "${WORKDIR}/git" PACKAGECONFIG[tests] = "-Dtests=enabled,-Dtests=disabled" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" ########### End of i.MX overrides ######### diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/imx-gst1.0-plugin_%.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/imx-gst1.0-plugin_%.bbappend index 00076e274..ea5aa33ce 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/imx-gst1.0-plugin_%.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/gstreamer/imx-gst1.0-plugin_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2016-2024 Digi International Inc. +# Copyright (C) 2016-2024, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" @@ -7,7 +7,7 @@ SRC_URI:append:ccimx6ul = " \ file://0002-imx-gst1.0-plugin-fix-build-using-MUSL-C-library.patch \ " -LIC_FILES_CHKSUM:ccimx93 = "file://LICENSE.txt;md5=fbc093901857fcd118f065f900982c24" -PV:ccimx93 = "4.8.2+git${SRCPV}" -SRCBRANCH:ccimx93 = "MM_04.08.02_2310_L6.1.y" -SRCREV:ccimx93 = "a72df52acfec5f849ec93906e33cb50da01b0b2e" +LIC_FILES_CHKSUM:ccimx9 = "file://LICENSE.txt;md5=fbc093901857fcd118f065f900982c24" +PV:ccimx9 = "4.8.2+git${SRCPV}" +SRCBRANCH:ccimx9 = "MM_04.08.02_2310_L6.1.y" +SRCREV:ccimx9 = "a72df52acfec5f849ec93906e33cb50da01b0b2e" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_%.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_%.bbappend index 0bf5ec55c..4256bc956 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_%.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2017, 2018 Digi International Inc. +# Copyright (C) 2017,2018, Digi International Inc. # Empirically detected binaries that are not needed for a given platform REDUNDANT_BINS ?= "" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_4.8.2.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_4.8.2.bb index 5f821d078..3a28e97bc 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_4.8.2.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-codec/imx-codec_4.8.2.bb @@ -10,4 +10,4 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=2827219e81f28aba7c6a569f7c437fa7" SRC_URI[md5sum] = "1977bab8d89972f08d9eee0122a64603" SRC_URI[sha256sum] = "b0744a91c265202a79a019c72f17cae01fd5b63a3ba451592b6c8349d95719e0" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_%.bbappend b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_%.bbappend index e0fc1b24b..2310e101b 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_%.bbappend +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2017, 2018 Digi International Inc. +# Copyright (C) 2017,2018, Digi International Inc. # Empirically detected binaries that are not needed for a given platform REDUNDANT_BINS ?= "" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_4.8.2.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_4.8.2.bb index ae755bcb1..aaf825510 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_4.8.2.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/imx-parser/imx-parser_4.8.2.bb @@ -10,4 +10,4 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=2827219e81f28aba7c6a569f7c437fa7" SRC_URI[md5sum] = "2e862fce70bc82649057ed552473d982" SRC_URI[sha256sum] = "20f326821ced5d6855f81794b66ec1f0c334e9ec7a9be1368a9b4dc501b666c6" -COMPATIBLE_MACHINE = "(ccimx93)" +COMPATIBLE_MACHINE = "(ccimx9)" diff --git a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb index ba6b63123..82e3cc426 100644 --- a/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb +++ b/meta-digi-dey/dynamic-layers/freescale-layer/recipes-multimedia/packagegroups/packagegroup-dey-gstreamer.bb @@ -1,5 +1,5 @@ # -# Copyright (C) 2012-2017 Digi International Inc. +# Copyright (C) 2012-2017, Digi International Inc. # SUMMARY = "Gstreamer framework packagegroup for DEY image" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-devtools/flatbuffers/python3-flatbuffers_2.0.7.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-devtools/flatbuffers/python3-flatbuffers_2.0.7.bbappend new file mode 100644 index 000000000..71e737265 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-devtools/flatbuffers/python3-flatbuffers_2.0.7.bbappend @@ -0,0 +1,3 @@ +# Copyright (C) 2024, Digi International Inc. + +BBCLASSEXTEND = "native" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend index ef6cbd501..8f77c9d7b 100644 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-fsl/packagegroup/packagegroup-imx-ml.bbappend @@ -1,4 +1,4 @@ -# Copyright 2023,2024 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. ML_NNSTREAMER_PKGS_LIST:remove = "nnstreamer-deepview-rt" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend index f816bd719..bd92334d8 100644 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/arm-compute-library/arm-compute-library_22.05.bbappend @@ -1,4 +1,4 @@ -# Copyright 2023,2024 Digi International Inc. +# Copyright (C) 2023,2024, Digi International Inc. SRCBRANCH:ccimx93 = "imx_22.05" SRCREV:ccimx93 = "37fc035060646db5048648da01db3738f08e3bfa" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bbappend new file mode 100644 index 000000000..b9ca14bee --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/eiq-examples_git.bbappend @@ -0,0 +1,82 @@ +# Copyright (C) 2024, Digi International Inc. + +# Directory for models. +MODELS_DIR = "models" + +# Directory for transformation tasks. +VELA_MODELS_DIR = "vela_models" + +# The Vela native tool is required to transform the models. +DEPENDS += "ethos-u-vela-native" + +SRC_URI += " \ + file://patches/0001-Customize-EiQ-demos.patch \ + file://patches/0002-dms-update-the-demo-to-use-the-landmark-full-model.patch \ + file://patches/0003-download_models-update-the-download-location-of-some.patch \ + file://scripts/launch_eiq_demo.sh \ + file://service/eiqdemo.service \ +" + +# Custom task to download and transform the models using Vela. +do_download_transform_models() { + cd "${S}" + python3 "${S}/download_models.py" +} +do_download_transform_models[network] = "1" + +# Add the custom task to download and transform the models. +addtask do_download_transform_models after do_patch before do_install + +inherit systemd + +do_install () { + # Install scripts to /usr/bin. + install -d "${D}${bindir}/${PN}-${PV}/" + cp -r "${S}/dms" "${D}${bindir}/${PN}-${PV}/" + cp -r "${S}/face_recognition" "${D}${bindir}/${PN}-${PV}/" + cp -r "${S}/object_detection" "${D}${bindir}/${PN}-${PV}/" + cp -r "${S}/gesture_detection" "${D}${bindir}/${PN}-${PV}/" + + # Install the original models. + install -d "${D}${bindir}/${PN}-${PV}/${MODELS_DIR}" + for archive in "${S}/${MODELS_DIR}"/*.tflite; do + cp "${archive}" "${D}${bindir}/${PN}-${PV}/${MODELS_DIR}" + done + + # Install the transformed Vela models. + install -d "${D}${bindir}/${PN}-${PV}/${VELA_MODELS_DIR}" + for archive in "${S}/${VELA_MODELS_DIR}"/*.tflite; do + cp "${archive}" "${D}${bindir}/${PN}-${PV}/${VELA_MODELS_DIR}" + done + + # Install the launch script. + install -d ${D}${sysconfdir}/demos/scripts + install -m 755 ${WORKDIR}/scripts/launch_eiq_demo.sh ${D}${sysconfdir}/demos/scripts/ + # Create symlinks to execute each demo. + ln -sf launch_eiq_demo.sh ${D}${sysconfdir}/demos/scripts/launch_eiq_demo_dms.sh + ln -sf launch_eiq_demo.sh ${D}${sysconfdir}/demos/scripts/launch_eiq_demo_gesture_detection.sh + ln -sf launch_eiq_demo.sh ${D}${sysconfdir}/demos/scripts/launch_eiq_demo_face_recognition.sh + ln -sf launch_eiq_demo.sh ${D}${sysconfdir}/demos/scripts/launch_eiq_demo_object_detection.sh + + # Install the systemd service. + install -d ${D}${systemd_unitdir}/system + install -m 0644 ${WORKDIR}/service/eiqdemo.service ${D}${systemd_unitdir}/system/ +} + +SYSTEMD_SERVICE:${PN} = "eiqdemo.service" + +PACKAGES += " \ + ${PN}-service \ +" + +FILES:${PN} += " \ + ${bindir}/${PN}-${PV}/* \ + ${sysconfdir}/* \ +" + +FILES:${PN}-service = " \ + ${systemd_unitdir}/system/eiqdemo.service \ +" + +# Make this recipe available only for the CC93 platform. +COMPATIBLE_MACHINE = "(ccimx93-dvk)" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0001-Customize-EiQ-demos.patch b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0001-Customize-EiQ-demos.patch new file mode 100644 index 000000000..e29c050d6 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0001-Customize-EiQ-demos.patch @@ -0,0 +1,407 @@ +From: Isaac Hermida +Date: Fri, 15 Sep 2023 17:02:43 +0200 +Subject: [PATCH] Customize EiQ demos + +Just do the changes in the scripts to: + * Always use the NPU + * Get a better performance with USB Cameras + * Add option to use a bigger camera resolution + * Option to set the window in full screen + * Fix some exceptions of the demos + +Signed-off-by: Isaac Hermida +--- + dms/main.py | 79 +++++++++++++++++++++++++++------------ + face_recognition/main.py | 44 ++++++++++++++++++---- + gesture_detection/main.py | 32 ++++++++++++++-- + object_detection/main.py | 40 ++++++++++++++++---- + 4 files changed, 153 insertions(+), 42 deletions(-) + +diff --git a/dms/main.py b/dms/main.py +index 6e04dc3..8ba99b2 100644 +--- a/dms/main.py ++++ b/dms/main.py +@@ -14,10 +14,16 @@ from eye_landmark import EyeMesher + from face_landmark import FaceMesher + from utils import * + +-MODEL_PATH = pathlib.Path("../models/") +-DETECT_MODEL = "face_detection_front_128_full_integer_quant.tflite" +-LANDMARK_MODEL = "face_landmark_192_integer_quant.tflite" +-EYE_MODEL = "iris_landmark_quant.tflite" ++WIDTH=640 ++HEIGH=480 ++FLIP=None # None, skip, 0: Flip vertically, 1: Flip horizontally (around the y-axis), -1: Flip both vertically and horizontally ++FORMAT=0 # None, skip (YUYV, default), 0 MJPG (for usb camera) ++ ++# Always enforce the Ethos NPU, use the converted vela models ++MODEL_PATH = pathlib.Path("../vela_models/") ++DETECT_MODEL = "face_detection_front_128_full_integer_quant_vela.tflite" ++LANDMARK_MODEL = "face_landmark_192_integer_quant_vela.tflite" ++EYE_MODEL = "iris_landmark_quant_vela.tflite" + + # turn on camera + parser = argparse.ArgumentParser() +@@ -29,16 +35,31 @@ parser.add_argument( + parser.add_argument( + '-d', + '--delegate', +- default='', ++ default='/usr/lib/libethosu_delegate.so', + help='delegate path') ++parser.add_argument("-f", "--fullscreen", action="store_true", help='run on full screen mode') + args = parser.parse_args() + + if args.input.isdigit(): + cap_input = int(args.input) + else: + cap_input = args.input ++ ++# This pipeline for the OV5640 camera in case the other command fails ++# cap = cv2.VideoCapture("v4l2src device=%s ! imxvideoconvert_pxp ! video/x-raw,format=RGB16,width=%d,height=%d " \ ++# "! videoconvert ! appsink" % (args.input, WIDTH, HEIGH)) ++ + cap = cv2.VideoCapture(cap_input) ++cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) ++cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGH) ++ ++if FORMAT == 0: ++ fourcc = cv2.VideoWriter_fourcc(*'MJPG') ++ cap.set(cv2.CAP_PROP_FOURCC, fourcc) ++ + ret, image = cap.read() ++if FLIP is not None: ++ image = cv2.flip(image, FLIP) + if not ret: + print("Can't read frame from source file ", args.input) + sys.exit(-1) +@@ -66,9 +87,9 @@ def draw_face_box(image, bboxes, landmarks, scores): + label_btmleft = bbox[:2].copy() + 10 + label_btmleft[0] += label_width + label_btmleft[1] += label_height +- cv2.rectangle(image, tuple(bbox[:2]), tuple(label_btmleft), color=(255, 0, 0), thickness=cv2.FILLED) +- cv2.putText(image, score_label, (bbox[0] + 5, label_btmleft[1] - 5), +- cv2.FONT_HERSHEY_SIMPLEX, fontScale=1.0, color=(255, 255, 255), thickness=2) ++ #cv2.rectangle(image, tuple(bbox[:2]), tuple(label_btmleft), color=(255, 0, 0), thickness=cv2.FILLED) ++ #cv2.putText(image, score_label, (bbox[0] + 5, label_btmleft[1] - 5), ++ #cv2.FONT_HERSHEY_SIMPLEX, fontScale=1.0, color=(255, 255, 255), thickness=2) + return image + + # detect single frame +@@ -111,8 +132,8 @@ def main(image): + right_eye_img = padded[right_box[0][1]:right_box[1][1], right_box[0][0]:right_box[1][0]] + left_eye_landmarks, left_iris_landmarks = eye_mesher.inference(left_eye_img) + right_eye_landmarks, right_iris_landmarks = eye_mesher.inference(right_eye_img) +- #cv2.rectangle(image_show, left_box[0], left_box[1], color=(255, 0, 0), thickness=2) +- #cv2.rectangle(image_show, right_box[0], right_box[1], color=(255, 0, 0), thickness=2) ++ cv2.rectangle(image_show, left_box[0], left_box[1], color=(255, 0, 0), thickness=2) ++ cv2.rectangle(image_show, right_box[0], right_box[1], color=(255, 0, 0), thickness=2) + left_eye_ratio = get_eye_ratio(left_eye_landmarks, image_show, left_box[0]) + right_eye_ratio = get_eye_ratio(right_eye_landmarks, image_show, right_box[0]) + +@@ -155,20 +176,32 @@ def main(image): + + + # endless loop ++window_name = "EiQ DMS demo" + while ret: +- image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) +- # detect single +- image_show = main(image) +- +- # put fps +- result = cv2.cvtColor(image_show, cv2.COLOR_RGB2BGR) +- +- # display the result +- cv2.imshow('demo', result) +- +- ret, image = cap.read() +- if cv2.waitKey(1) & 0xFF == ord('q'): +- break ++ try: ++ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) ++ # detect single ++ image_show = main(image) ++ ++ # put fps ++ result = cv2.cvtColor(image_show, cv2.COLOR_RGB2BGR) ++ ++ cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) ++ if args.fullscreen: ++ cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) ++ ++ # display the result ++ cv2.imshow(window_name, result) ++ ++ ret, image = cap.read() ++ if FLIP is not None: ++ image = cv2.flip(image, FLIP) ++ if cv2.waitKey(1) & 0xFF == ord('q'): ++ break ++ except Exception as err: ++ # Ignore exceptions ++ time.sleep(0.2) ++ print("Exception catched:%s\n... continuing with test" % repr(err)) + + time.sleep(2) + cap.release() +diff --git a/face_recognition/main.py b/face_recognition/main.py +index acc838e..33ffa71 100644 +--- a/face_recognition/main.py ++++ b/face_recognition/main.py +@@ -13,6 +13,11 @@ from face_detection import YoloFace + from face_recognition import Facenet + from face_database import FaceDatabase + ++WIDTH=640 ++HEIGH=480 ++FLIP=None # None, skip, 0: Flip vertically, 1: Flip horizontally (around the y-axis), -1: Flip both vertically and horizontally ++FORMAT=0 # None, skip (YUYV, default), 0 MJPG (for usb camera) ++ + parser = argparse.ArgumentParser() + parser.add_argument( + '-i', +@@ -22,12 +27,14 @@ parser.add_argument( + parser.add_argument( + '-d', + '--delegate', +- default='', ++ default='/usr/lib/libethosu_delegate.so', + help='delegate path') ++parser.add_argument("-f", "--fullscreen", action="store_true", help='run on full screen mode') + args = parser.parse_args() + +-detector = YoloFace("../models/yoloface_int8.tflite", args.delegate) +-recognizer = Facenet("../models/facenet_512_int_quantized.tflite", args.delegate) ++# Always enforce the Ethos NPU, use the converted vela models ++detector = YoloFace("../vela_models/yoloface_int8_vela.tflite", args.delegate) ++recognizer = Facenet("../vela_models/facenet_512_int_quantized_vela.tflite", args.delegate) + database = FaceDatabase() + + def ischar(c): +@@ -39,7 +46,7 @@ def get_inputs(img, msg): + cv2.rectangle(img, (0, 0), (img.shape[1], 40), (0, 0, 0), -1) + cv2.putText(img, msg + inputs, (30, 30), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) +- cv2.imshow('img', img) ++ cv2.imshow(window_name, img) + key = cv2.waitKey(20) & 0xFF + if key == 13 or key == 141: + break +@@ -68,13 +75,28 @@ if args.input.isdigit(): + cap_input = int(args.input) + else: + cap_input = args.input ++ ++# This pipeline for the OV5640 camera in case the other command fails ++# vid = cv2.VideoCapture("v4l2src device=%s ! imxvideoconvert_pxp ! video/x-raw,format=RGB16,width=%d,height=%d " \ ++# "! videoconvert ! appsink" % (args.input, WIDTH, HEIGH)) + vid = cv2.VideoCapture(cap_input) ++vid.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) ++vid.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGH) ++ ++if FORMAT == 0: ++ fourcc = cv2.VideoWriter_fourcc(*'MJPG') ++ vid.set(cv2.CAP_PROP_FOURCC, fourcc) ++ + PADDING = 10 + tips = "Press 'a' to add person, 'd' to delete person, 'p' to print database" ++ ++window_name = "Face recognition Demo" + while True: + embeddings = None + + ret, img = vid.read() ++ if FLIP is not None: ++ img = cv2.flip(img, FLIP) + if (ret == False): + break + boxes = detector.detect(img) +@@ -97,12 +119,20 @@ while True: + + cv2.putText(img, tips, (30, 30), + cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 3) +- cv2.imshow('img', img) ++ ++ cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) ++ if args.fullscreen: ++ cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) ++ ++ cv2.imshow(window_name, img) + key = cv2.waitKey(1) & 0xFF + if (key == ord('a')): + msg = "ADD. Please input name:" + name = get_inputs(img, msg) +- database.add_name(name, embeddings) ++ if embeddings: ++ database.add_name(name, embeddings) ++ else: ++ print ("Not a valid face, not adding user to database, ignoring...") + elif (key == ord('d')): + msg = "DEL. Please input name:" + name = get_inputs(img, msg) +@@ -110,7 +140,7 @@ while True: + elif (key == ord('p')): + names = ",".join(database.get_names()) + print_longtext(img, names + " Press any key to continue.") +- cv2.imshow('img', img) ++ cv2.imshow(window_name, img) + while cv2.waitKey(100) & 0xFF == 0xFF: + pass + +diff --git a/gesture_detection/main.py b/gesture_detection/main.py +index da83ce0..15b8597 100644 +--- a/gesture_detection/main.py ++++ b/gesture_detection/main.py +@@ -9,8 +9,9 @@ import time + import argparse + from hand_tracker import HandTracker + +-PALM_MODEL_PATH = "../models/palm_detection_builtin_256_integer_quant.tflite" +-LANDMARK_MODEL_PATH = "../models/hand_landmark_3d_256_integer_quant.tflite" ++# Always enforce the Ethos NPU, use the converted vela models ++PALM_MODEL_PATH = "../vela_models/palm_detection_builtin_256_integer_quant_vela.tflite" ++LANDMARK_MODEL_PATH = "../vela_models/hand_landmark_3d_256_integer_quant_vela.tflite" + ANCHORS_PATH = "anchors.csv" + + def draw_landmarks(points, frame): +@@ -52,15 +53,33 @@ parser.add_argument( + parser.add_argument( + '-d', + '--delegate', +- default='', ++ default='/usr/lib/libethosu_delegate.so', + help='delegate path') ++parser.add_argument("-f", "--fullscreen", action="store_true", help='run on full screen mode') + args = parser.parse_args() + + if args.input.isdigit(): + cap_input = int(args.input) + else: + cap_input = args.input ++ ++WIDTH=640 ++HEIGH=480 ++FLIP=None # None, skip, 0: Flip vertically, 1: Flip horizontally (around the y-axis), -1: Flip both vertically and horizontally ++FORMAT=0 # None, skip (YUYV, default), 0 MJPG (for usb camera) ++ ++# This pipeline for the OV5640 camera in case the other command fails ++# capture = cv2.VideoCapture("v4l2src device=%s ! imxvideoconvert_pxp ! video/x-raw,format=RGB16,width=%d,height=%d " \ ++# "! videoconvert ! appsink" % (args.input, WIDTH, HEIGH)) ++ + capture = cv2.VideoCapture(cap_input) ++capture.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) ++capture.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGH) ++ ++if FORMAT == 0: ++ fourcc = cv2.VideoWriter_fourcc(*'MJPG') ++ capture.set(cv2.CAP_PROP_FOURCC, fourcc) ++ + ret, frame = capture.read() + if (frame is None): + print("Can't read frame from source file ", args.input) +@@ -68,11 +87,16 @@ if (frame is None): + + detector = HandTracker(PALM_MODEL_PATH, LANDMARK_MODEL_PATH, ANCHORS_PATH, args.delegate, box_shift=0.2, box_enlarge=1.3) + ++window_name = "Hand Gesture Demo" + while ret: + image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + points, _ = detector(image) + draw_landmarks(points, frame) +- cv2.imshow("hand", frame) ++ ++ cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) ++ if args.fullscreen: ++ cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) ++ cv2.imshow(window_name, frame) + + ret, frame = capture.read() + if cv2.waitKey(1) & 0xFF == ord('q'): +diff --git a/object_detection/main.py b/object_detection/main.py +index 1356111..efa614e 100644 +--- a/object_detection/main.py ++++ b/object_detection/main.py +@@ -13,7 +13,13 @@ import argparse + + from labels import label2string + +-MODEL_PATH = "../models/ssd_mobilenet_v1_quant.tflite" ++WIDTH=640 ++HEIGH=480 ++FLIP=None # None, skip, 0: Flip vertically, 1: Flip horizontally (around the y-axis), -1: Flip both vertically and horizontally ++FORMAT=0 # None, skip (YUYV, default), 0 MJPG (for usb camera) ++ ++# Always enforce the Ethos NPU, use the converted vela models ++MODEL_PATH = "../vela_models/ssd_mobilenet_v1_quant_vela.tflite" + + parser = argparse.ArgumentParser() + parser.add_argument( +@@ -24,21 +30,31 @@ parser.add_argument( + parser.add_argument( + '-d', + '--delegate', +- default='', ++ default='/usr/lib/libethosu_delegate.so', + help='delegate path') ++parser.add_argument("-f", "--fullscreen", action="store_true", help='run on full screen mode') + args = parser.parse_args() + + if args.input.isdigit(): + cap_input = int(args.input) + else: + cap_input = args.input ++ ++# This pipeline for the OV5640 camera in case the other command fails ++# vid = cv2.VideoCapture("v4l2src device=%s ! imxvideoconvert_pxp ! video/x-raw,format=RGB16,width=%d,height=%d " \ ++# "! videoconvert ! appsink" % (args.input, WIDTH, HEIGH)) ++ + vid = cv2.VideoCapture(cap_input) ++vid.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) ++vid.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGH) + +-if(args.delegate): +- ext_delegate = [tflite.load_delegate(args.delegate)] +- interpreter = tflite.Interpreter(model_path=MODEL_PATH, experimental_delegates=ext_delegate) +-else: +- interpreter = tflite.Interpreter(model_path=MODEL_PATH) ++if FORMAT == 0: ++ fourcc = cv2.VideoWriter_fourcc(*'MJPG') ++ vid.set(cv2.CAP_PROP_FOURCC, fourcc) ++ ++# Always enforce the Ethos NPU ++ext_delegate = [tflite.load_delegate(args.delegate)] ++interpreter = tflite.Interpreter(model_path=MODEL_PATH, experimental_delegates=ext_delegate) + interpreter.allocate_tensors() + + input_details = interpreter.get_input_details() +@@ -52,10 +68,13 @@ total_fps = 0 + total_time = 0 + + ret, frame = vid.read() ++if FLIP is not None: ++ frame = cv2.flip(frame, FLIP) + if (frame is None): + print("Can't read frame from source file ", args.input) + exit(0) + ++window_name = "Object Detection Demo" + while ret: + total_fps += 1 + loop_start = time.time() +@@ -94,9 +113,14 @@ while ret: + msg = "FPS:" + str(fps) + " Invoke time:" + str(invoke_time) + "ms" + cv2.putText(frame, msg, (0, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3) + +- cv2.imshow("image", frame) ++ cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) ++ if args.fullscreen: ++ cv2.setWindowProperty(window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) ++ cv2.imshow(window_name, frame) + + ret, frame = vid.read() ++ if FLIP is not None: ++ frame = cv2.flip(frame, FLIP) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0002-dms-update-the-demo-to-use-the-landmark-full-model.patch b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0002-dms-update-the-demo-to-use-the-landmark-full-model.patch new file mode 100644 index 000000000..4cdbaba1b --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0002-dms-update-the-demo-to-use-the-landmark-full-model.patch @@ -0,0 +1,22 @@ +From: David Escalona +Date: Thu, 5 Sep 2024 11:04:19 +0200 +Subject: [PATCH] dms: update the demo to use the landmark full model + +Signed-off-by: David Escalona +--- + dms/main.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dms/main.py b/dms/main.py +index 8ba99b2..e74b6be 100644 +--- a/dms/main.py ++++ b/dms/main.py +@@ -22,7 +22,7 @@ FORMAT=0 # None, skip (YUYV, default), 0 MJPG (for usb camera) + # Always enforce the Ethos NPU, use the converted vela models + MODEL_PATH = pathlib.Path("../vela_models/") + DETECT_MODEL = "face_detection_front_128_full_integer_quant_vela.tflite" +-LANDMARK_MODEL = "face_landmark_192_integer_quant_vela.tflite" ++LANDMARK_MODEL = "face_landmark_192_full_integer_quant_vela.tflite" + EYE_MODEL = "iris_landmark_quant_vela.tflite" + + # turn on camera diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0003-download_models-update-the-download-location-of-some.patch b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0003-download_models-update-the-download-location-of-some.patch new file mode 100644 index 000000000..7f75566dd --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/patches/0003-download_models-update-the-download-location-of-some.patch @@ -0,0 +1,79 @@ +From: David Escalona +Date: Wed, 11 Sep 2024 17:25:05 +0200 +Subject: [PATCH] download_models: update the download location of some models + +Signed-off-by: David Escalona +--- + download_models.py | 43 ++++++++++++++++++++++++++----------------- + 1 file changed, 26 insertions(+), 17 deletions(-) + +diff --git a/download_models.py b/download_models.py +index 3111f29..462f7b7 100644 +--- a/download_models.py ++++ b/download_models.py +@@ -35,21 +35,33 @@ def download_all_models(model_dir, vela_dir): + os.makedirs(model_dir, exist_ok=True) + os.makedirs(vela_dir, exist_ok=True) + ++ github_url = 'https://raw.githubusercontent.com/' ++ + #Download gesture models + #https://github.com/PINTO0309/PINTO_model_zoo +- url = 'https://drive.google.com/uc?export=download&&id=1yjWyXsac5CbGWYuHWYhhnr_9cAwg3uNI' +- path = os.path.join(model_dir, 'gesture_models.tar.gz') +- download_file('gesture recognition', url, path) +- decompress(path, model_dir) ++ #url = 'https://drive.google.com/uc?export=download&&id=1yjWyXsac5CbGWYuHWYhhnr_9cAwg3uNI' ++ #path = os.path.join(model_dir, 'gesture_models.tar.gz') ++ #download_file('gesture recognition', url, path) ++ #decompress(path, model_dir) ++ ++ #Download gesture models ++ #https://github.com/terryky/tflite_gles_app ++ url = github_url + 'terryky/tflite_gles_app/master/gl2handpose/handpose_model/' ++ file_name = 'palm_detection_builtin_256_integer_quant.tflite' ++ path = os.path.join(model_dir, file_name) ++ download_file('hand landmark', url + file_name, path) ++ file_name = 'hand_landmark_3d_256_integer_quant.tflite' ++ path = os.path.join(model_dir, file_name) ++ download_file('hand detection', url + file_name, path) + + #Download face recognition models + #https://github.com/imuncle/yoloface-50k +- url = 'https://raw.githubusercontent.com/imuncle/yoloface-50k/main/tflite/yoloface_int8.tflite' ++ url = github_url + 'imuncle/yoloface-50k/main/tflite/yoloface_int8.tflite' + path = os.path.join(model_dir, 'yoloface_int8.tflite') + download_file('face detection', url, path) + + #https://github.com/shubham0204/FaceRecognition_With_FaceNet_Android +- url = 'https://raw.githubusercontent.com/shubham0204/FaceRecognition_With_FaceNet_Android/master/app/src/main/assets/facenet_512_int_quantized.tflite' ++ url = github_url + 'shubham0204/FaceRecognition_With_FaceNet_Android/master/app/src/main/assets/facenet_512_int_quantized.tflite' + path = os.path.join(model_dir, 'facenet_512_int_quantized.tflite') + download_file('face recognition', url, path) + +@@ -67,17 +79,14 @@ def download_all_models(model_dir, vela_dir): + decompress(path, model_dir) + + #Download dms models +- #https://github.com/PINTO0309/PINTO_model_zoo +- url = "https://drive.google.com/uc?export=download&id=1YEAgUuHyJ7_fTY9XyDaALDidM6Sbzhd8" +- path = os.path.join(model_dir, 'dms_face_detection.tar.gz') +- download_file('DMS face detection', url, path) +- decompress(path, model_dir) +- +- #https://github.com/PINTO0309/PINTO_model_zoo +- url = "https://s3.ap-northeast-2.wasabisys.com/pinto-model-zoo/043_face_landmark/resources.tar.gz" +- path = os.path.join(model_dir, 'dms_face_landmark.tar.gz') +- download_file('DMS face landmark', url, path) +- decompress(path, model_dir) ++ #https://github.com/terryky/tflite_gles_app ++ url = github_url + 'terryky/tflite_gles_app/master/gl2facemesh/facemesh_model/' ++ file_name = 'face_detection_front_128_full_integer_quant.tflite' ++ path = os.path.join(model_dir, file_name) ++ download_file('DMS face detection', url + file_name, path) ++ file_name = 'face_landmark_192_full_integer_quant.tflite' ++ path = os.path.join(model_dir, file_name) ++ download_file('DMS face landmark', url + file_name, path) + + #https://github.com/PINTO0309/PINTO_model_zoo + url = "https://s3.ap-northeast-2.wasabisys.com/pinto-model-zoo/049_iris_landmark/resources.tar.gz" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/scripts/launch_eiq_demo.sh b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/scripts/launch_eiq_demo.sh new file mode 100644 index 000000000..d719c2988 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/scripts/launch_eiq_demo.sh @@ -0,0 +1,39 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2024 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Launch script for NXP EIQ demos +# +#=============================================================================== + +DEFAULT_DEMO="dms" +DEMO=${DEFAULT_DEMO} + +# Try to extract the demo to launch from the script name. +DEMO_FROM_NAME="$(basename "${0}" | sed -n 's/^launch_eiq_demo_\(.*\)\.sh$/\1/p')" + +# Check if the demo to launch was passed as argument. +if [ -n "${1}" ]; then + DEMO=${1} +elif [ -n "${DEMO_FROM_NAME}" ]; then + DEMO=${DEMO_FROM_NAME} +fi + +# Build demo directory. +DEMO_DIR="/usr/bin/eiq-examples-git/${DEMO}" + +# Verify that the demo directory exists. +[ -d "${DEMO_DIR}" ] || { echo "Error: Demo ${DEMO} does not exist"; exit 1; } + +# Navigate to the demo folder +cd "${DEMO_DIR}" || exit + +# Execute the demo pre-configuring the display settings. +WAYLAND_DISPLAY=/run/wayland-0 DISPLAY=:0.0 XDG_RUNTIME_DIR=/run/user/0 python3 main.py -i /dev/video0 -f -d /usr/lib/libethosu_delegate.so & diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/service/eiqdemo.service b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/service/eiqdemo.service new file mode 100644 index 000000000..2189e5d4a --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/eiq-examples/files/service/eiqdemo.service @@ -0,0 +1,10 @@ +[Unit] +Description=Initialization of EiQ DMS demo +After=multi-user.target + +[Service] +Type=forking +ExecStart=/etc/demos/scripts/launch_eiq_demo.sh + +[Install] +WantedBy=multi-user.target diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-vela/ethos-u-vela_3.9.0.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-vela/ethos-u-vela_3.9.0.bbappend new file mode 100644 index 000000000..a5d7eb597 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-libraries/ethos-u-vela/ethos-u-vela_3.9.0.bbappend @@ -0,0 +1,9 @@ +# Copyright (C) 2024, Digi International Inc. + +BBCLASSEXTEND = "native" + +# Clear machine restriction. +COMPATIBLE_MACHINE:remove = "(mx93-nxp-bsp)" + +# Restrict the target build to specific machines. +COMPATIBLE_MACHINE:class-target = "(mx93-nxp-bsp)" diff --git a/meta-digi-dey/dynamic-layers/meta-ml/recipes-nnstreamer/nnstreamer/nnstreamer_2.2.0.bbappend b/meta-digi-dey/dynamic-layers/meta-ml/recipes-nnstreamer/nnstreamer/nnstreamer_2.2.0.bbappend index d81a7ba8a..f2680c2ae 100644 --- a/meta-digi-dey/dynamic-layers/meta-ml/recipes-nnstreamer/nnstreamer/nnstreamer_2.2.0.bbappend +++ b/meta-digi-dey/dynamic-layers/meta-ml/recipes-nnstreamer/nnstreamer/nnstreamer_2.2.0.bbappend @@ -1,3 +1,3 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023, Digi International Inc. PACKAGECONFIG_SOC:mx9-nxp-bsp:remove = "deepview-rt" diff --git a/meta-digi-dey/dynamic-layers/qt5-layer/NXP/recipes-qt/qt5/qtmultimedia_%.bbappend b/meta-digi-dey/dynamic-layers/qt5-layer/NXP/recipes-qt/qt5/qtmultimedia_%.bbappend index 8cca7bbed..5d8d99c48 100644 --- a/meta-digi-dey/dynamic-layers/qt5-layer/NXP/recipes-qt/qt5/qtmultimedia_%.bbappend +++ b/meta-digi-dey/dynamic-layers/qt5-layer/NXP/recipes-qt/qt5/qtmultimedia_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2019 Digi International +# Copyright (C) 2015-2019, Digi International Inc. PACKAGECONFIG:append = " gstreamer" diff --git a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend index f9945620b..e8a7ea024 100644 --- a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend +++ b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/demo-extrafiles/qt5-demo-extrafiles.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2021 Digi International. +# Copyright (C) 2015-2021, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" diff --git a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend index ed6fdadb7..d3fc19776 100644 --- a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend +++ b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Digi International. +# Copyright (C) 2023, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" diff --git a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/qt5everywheredemo_1.0.bbappend b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/qt5everywheredemo_1.0.bbappend index a76d04275..0ec8bac6d 100644 --- a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/qt5everywheredemo_1.0.bbappend +++ b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/examples/qt5everywheredemo_1.0.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Digi International. +# Copyright (C) 2015, Digi International Inc. LIC_FILES_CHKSUM = "file://main.cpp;md5=a3ecdc1d777da347f1bf35dd9966606f" diff --git a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-demos.bb b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-demos.bb index f893a5450..b10f67807 100644 --- a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-demos.bb +++ b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-demos.bb @@ -33,3 +33,9 @@ RDEPENDS:${PN}:append:ccmp15 = " \ cinematicexperience-rhi \ cinematicexperience-rhi-tools \ " + +RDEPENDS:${PN}:append:ccmp2 = " \ + qt5everywheredemo \ + cinematicexperience-rhi \ + cinematicexperience-rhi-tools \ +" diff --git a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-dey.bb b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-dey.bb index b16f30d14..0dcc1e794 100644 --- a/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-dey.bb +++ b/meta-digi-dey/dynamic-layers/qt5-layer/recipes-qt/packagegroups/packagegroup-qt5-dey.bb @@ -54,6 +54,10 @@ QT5_RDEPENDS:ccmp15 = " \ ${@bb.utils.contains('DISTRO_FEATURES', 'wayland', '', '${QT5_RDEPENDS_eglfs}', d)} \ " +QT5_RDEPENDS:ccmp2 = " \ + ${QT5_RDEPENDS_common} \ +" + # Add packagegroup-qt5-webengine to QT5_RDEPENDS and comment out the line below to install qtwebengine to the rootfs. QT5_RDEPENDS:remove = " packagegroup-qt5-webengine" diff --git a/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend b/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend index a683b1ad3..ae7a660f5 100644 --- a/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend +++ b/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/examples/cinematicexperience-rhi_%.bbappend @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Digi International. +# Copyright (C) 2023, Digi International Inc. FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" diff --git a/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/packagegroups/packagegroup-qt6-addons.bbappend b/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/packagegroups/packagegroup-qt6-addons.bbappend index f842dd6a5..d51d0f600 100644 --- a/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/packagegroups/packagegroup-qt6-addons.bbappend +++ b/meta-digi-dey/dynamic-layers/qt6-layer/recipes-qt/packagegroups/packagegroup-qt6-addons.bbappend @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Digi International Inc. +# Copyright (C) 2023, Digi International Inc. # qtdeviceutilities provides a networksettings module that depends # on "connman". This conflicts with NetworkManager diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake-native_3.25.2.bb b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake-native_3.25.2.bb new file mode 100644 index 000000000..c150aef5e --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake-native_3.25.2.bb @@ -0,0 +1,67 @@ +require cmake.inc +inherit native + +DEPENDS += "bzip2-replacement-native xz-native zlib-native ncurses-native zstd-native openssl-native" + +SRC_URI += "file://OEToolchainConfig.cmake \ + file://environment.d-cmake.sh \ + file://0001-CMakeDetermineSystem-use-oe-environment-vars-to-load.patch \ + file://0005-Disable-use-of-ext2fs-ext2_fs.h-by-cmake-s-internal-.patch \ + file://0001-CMakeLists.txt-disable-USE_NGHTTP2.patch \ + " + +LICENSE:append = " & BSD-1-Clause & MIT & BSD-2-Clause & curl" +LIC_FILES_CHKSUM:append = " \ + file://Utilities/cmjsoncpp/LICENSE;md5=5d73c165a0f9e86a1342f32d19ec5926 \ + file://Utilities/cmlibarchive/COPYING;md5=d499814247adaee08d88080841cb5665 \ + file://Utilities/cmexpat/COPYING;md5=9e2ce3b3c4c0f2670883a23bbd7c37a9 \ + file://Utilities/cmlibrhash/COPYING;md5=a8c2a557a5c53b1c12cddbee98c099af \ + file://Utilities/cmlibuv/LICENSE;md5=ad93ca1fffe931537fcf64f6fcce084d \ + file://Utilities/cmcurl/COPYING;md5=190c514872597083303371684954f238 \ +" + +B = "${WORKDIR}/build" +do_configure[cleandirs] = "${B}" + +CMAKE_EXTRACONF = "\ + -DCMAKE_LIBRARY_PATH=${STAGING_LIBDIR_NATIVE} \ + -DBUILD_CursesDialog=1 \ + -DCMAKE_USE_SYSTEM_LIBRARIES=1 \ + -DCMAKE_USE_SYSTEM_LIBRARY_JSONCPP=0 \ + -DCMAKE_USE_SYSTEM_LIBRARY_LIBARCHIVE=0 \ + -DCMAKE_USE_SYSTEM_LIBRARY_LIBUV=0 \ + -DCMAKE_USE_SYSTEM_LIBRARY_LIBRHASH=0 \ + -DCMAKE_USE_SYSTEM_LIBRARY_EXPAT=0 \ + -DCMAKE_USE_SYSTEM_LIBRARY_CURL=0 \ + -DENABLE_ACL=0 -DHAVE_ACL_LIBACL_H=0 \ + -DHAVE_SYS_ACL_H=0 \ +" + +do_configure () { + ${S}/configure --verbose --prefix=${prefix} \ + ${@oe.utils.parallel_make_argument(d, '--parallel=%d')} \ + ${@bb.utils.contains('CCACHE', 'ccache ', '--enable-ccache', '', d)} \ + -- ${CMAKE_EXTRACONF} +} + +do_compile() { + oe_runmake +} + +do_install() { + oe_runmake 'DESTDIR=${D}' install + + # The following codes are here because eSDK needs to provide compatibilty + # for SDK. That is, eSDK could also be used like traditional SDK. + mkdir -p ${D}${datadir}/cmake + install -m 644 ${WORKDIR}/OEToolchainConfig.cmake ${D}${datadir}/cmake/ + mkdir -p ${D}${base_prefix}/environment-setup.d + install -m 644 ${WORKDIR}/environment.d-cmake.sh ${D}${base_prefix}/environment-setup.d/cmake.sh + + # Help docs create tons of files in the native sysroot and aren't needed there + rm -rf ${D}${datadir}/cmake-*/Help +} + +do_compile[progress] = "percent" + +SYSROOT_DIRS_NATIVE += "${datadir}/cmake ${base_prefix}/environment-setup.d" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake.inc b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake.inc new file mode 100644 index 000000000..b7e674c4c --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake.inc @@ -0,0 +1,28 @@ +# Copyright (C) 2005, Koninklijke Philips Electronics NV. All Rights Reserved +# Released under the MIT license (see packages/COPYING) + +SUMMARY = "Cross-platform, open-source make system" +DESCRIPTION = "CMake is used to control the software compilation process \ +using simple platform and compiler independent configuration files. CMake \ +generates native makefiles and workspaces that can be used in the compiler \ +environment of your choice." +HOMEPAGE = "http://www.cmake.org/" +BUGTRACKER = "http://public.kitware.com/Bug/my_view_page.php" +SECTION = "console/utils" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://Copyright.txt;md5=09069e0fffe4e5eaf6dde04c3b1932e5 \ + file://Source/cmake.h;beginline=1;endline=2;md5=a5f70e1fef8614734eae0d62b4f5891b \ + " + +CMAKE_MAJOR_VERSION = "${@'.'.join(d.getVar('PV').split('.')[0:2])}" + +SRC_URI = "https://cmake.org/files/v${CMAKE_MAJOR_VERSION}/cmake-${PV}.tar.gz \ +" + +SRC_URI[sha256sum] = "c026f22cb931dd532f648f087d587f07a1843c6e66a3dfca4fb0ea21944ed33c" + +UPSTREAM_CHECK_REGEX = "cmake-(?P\d+(\.\d+)+)\.tar" + +# This is specific to the npm package that installs cmake, so isn't +# relevant to OpenEmbedded +CVE_CHECK_IGNORE += "CVE-2016-10642" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0001-CMakeDetermineSystem-use-oe-environment-vars-to-load.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0001-CMakeDetermineSystem-use-oe-environment-vars-to-load.patch new file mode 100644 index 000000000..d13c367e7 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0001-CMakeDetermineSystem-use-oe-environment-vars-to-load.patch @@ -0,0 +1,44 @@ +From 5acfcb2aba1a5641d390558fdf288373f5e39cb5 Mon Sep 17 00:00:00 2001 +From: Cody P Schafer +Date: Thu, 27 Apr 2017 11:35:05 -0400 +Subject: [PATCH] CMakeDetermineSystem: use oe environment vars to load default + toolchain file in sdk + +Passing the toolchain by: + + - shell aliases does not work if cmake is called by a script + - unconditionally by a wrapper script causes cmake to believe it is + configuring things when it is not (for example, `cmake --build` breaks). + +The OE_CMAKE_TOOLCHAIN_FILE variable is only used as a default if no +toolchain is explicitly specified. + +Setting the CMAKE_TOOLCHAIN_FILE cmake variable is marked as cached +because '-D' options are cache entries themselves. + +Upstream-Status: Inappropriate [oe-core specific] +Signed-off-by: Cody P Schafer +Signed-off-by: Otavio Salvador + +--- + Modules/CMakeDetermineSystem.cmake | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake +index 2c2c2ac3..fae4f97f 100644 +--- a/Modules/CMakeDetermineSystem.cmake ++++ b/Modules/CMakeDetermineSystem.cmake +@@ -112,6 +112,13 @@ else() + endif() + endif() + ++if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) ++ if(DEFINED ENV{OE_CMAKE_TOOLCHAIN_FILE}) ++ set(CMAKE_TOOLCHAIN_FILE "$ENV{OE_CMAKE_TOOLCHAIN_FILE}" CACHE FILEPATH "toolchain file") ++ message(STATUS "Toolchain file defaulted to '${CMAKE_TOOLCHAIN_FILE}'") ++ endif() ++endif() ++ + # if a toolchain file is used, the user wants to cross compile. + # in this case read the toolchain file and keep the CMAKE_HOST_SYSTEM_* + # variables around so they can be used in CMakeLists.txt. diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0001-CMakeLists.txt-disable-USE_NGHTTP2.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0001-CMakeLists.txt-disable-USE_NGHTTP2.patch new file mode 100644 index 000000000..d6486cb45 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0001-CMakeLists.txt-disable-USE_NGHTTP2.patch @@ -0,0 +1,31 @@ +From 3fd6082c52a8140db5995afb59fb391f7d5c19d7 Mon Sep 17 00:00:00 2001 +From: Changqing Li +Date: Wed, 28 Dec 2022 17:51:27 +0800 +Subject: [PATCH] CMakeLists.txt: disable USE_NGHTTP2 + +nghttp2 depends on cmake-native to build, to break circular +dependency, disable nghttp2. + +Upstream-Status: Inappropriate [oe specific] + +Signed-off-by: Changqing Li +--- + Utilities/cmcurl/CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt +index f842270b..17b1ce19 100644 +--- a/Utilities/cmcurl/CMakeLists.txt ++++ b/Utilities/cmcurl/CMakeLists.txt +@@ -68,7 +68,7 @@ set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support" + set(HTTP_ONLY OFF CACHE INTERNAL "Curl is not http-only") + set(PICKY_COMPILER OFF CACHE INTERNAL "Enable picky compiler options") + set(USE_LIBIDN2 ON) +-set(USE_NGHTTP2 ON) ++set(USE_NGHTTP2 OFF) + set(USE_NGTCP2 OFF) + set(USE_QUICHE OFF) + set(USE_WIN32_IDN OFF) +-- +2.25.1 + diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0005-Disable-use-of-ext2fs-ext2_fs.h-by-cmake-s-internal-.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0005-Disable-use-of-ext2fs-ext2_fs.h-by-cmake-s-internal-.patch new file mode 100644 index 000000000..d6f7308fe --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/0005-Disable-use-of-ext2fs-ext2_fs.h-by-cmake-s-internal-.patch @@ -0,0 +1,39 @@ +From fd9a04c1434e12f21c043385e306e0b52d38d749 Mon Sep 17 00:00:00 2001 +From: Otavio Salvador +Date: Thu, 5 Jul 2018 10:28:04 -0300 +Subject: [PATCH] Disable use of ext2fs/ext2_fs.h by cmake's internal + + libarchive copy +Organization: O.S. Systems Software LTDA. + +We don't want to add a dependency on e2fsprogs-native for cmake-native, +and we don't use CPack so just disable this functionality. + +Upstream-Status: Inappropriate [config] + +Signed-off-by: Paul Eggleton +Signed-off-by: Otavio Salvador + +--- + Utilities/cmlibarchive/CMakeLists.txt | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt +index bfcaf30..2960683 100644 +--- a/Utilities/cmlibarchive/CMakeLists.txt ++++ b/Utilities/cmlibarchive/CMakeLists.txt +@@ -682,12 +682,8 @@ LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H) + LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H) + LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H) + LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H) +-LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H) +- +-CHECK_C_SOURCE_COMPILES("#include +-#include +-int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS) +- ++SET(HAVE_EXT2FS_EXT2_FS_H 0) ++SET(HAVE_WORKING_EXT2_IOC_GETFLAGS 0) + LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H) + LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H) + LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H) diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/OEToolchainConfig.cmake b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/OEToolchainConfig.cmake new file mode 100644 index 000000000..d6a1e0464 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/OEToolchainConfig.cmake @@ -0,0 +1,20 @@ +set( CMAKE_SYSTEM_NAME Linux ) +set( CMAKE_C_FLAGS $ENV{CFLAGS} CACHE STRING "" FORCE ) +set( CMAKE_CXX_FLAGS $ENV{CXXFLAGS} CACHE STRING "" FORCE ) +set( CMAKE_SYSROOT $ENV{OECORE_TARGET_SYSROOT} ) + +set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} ) +set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) +set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY ) + +set(CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX "$ENV{OE_CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX}") + +set( CMAKE_SYSTEM_PROCESSOR $ENV{OECORE_TARGET_ARCH} ) + +# Include the toolchain configuration subscripts +file( GLOB toolchain_config_files "${CMAKE_CURRENT_LIST_FILE}.d/*.cmake" ) +foreach(config ${toolchain_config_files}) + include(${config}) +endforeach() diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/environment.d-cmake.sh b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/environment.d-cmake.sh new file mode 100644 index 000000000..7bdb19fb6 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/reciped-devtools/cmake/cmake/environment.d-cmake.sh @@ -0,0 +1,2 @@ +export OE_CMAKE_TOOLCHAIN_FILE="$OECORE_NATIVE_SYSROOT/usr/share/cmake/OEToolchainConfig.cmake" +export OE_CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX="`echo $OECORE_BASELIB | sed -e s/lib//`" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0001-onnxruntime-test-remove-AVX-specific-micro-benchmark.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0001-onnxruntime-test-remove-AVX-specific-micro-benchmark.patch new file mode 100644 index 000000000..7ee52241f --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0001-onnxruntime-test-remove-AVX-specific-micro-benchmark.patch @@ -0,0 +1,47 @@ +From a17c1c5d0b4957b5b3a65fc5d211f5ba6764d404 Mon Sep 17 00:00:00 2001 +From: Vincent ABRIOU +Date: Fri, 24 Mar 2023 11:09:00 +0100 +Subject: [PATCH 1/5] onnxruntime: test: remove AVX specific micro benchmark + +Signed-off-by: Vincent ABRIOU + +%% original patch: 0001-onnxruntime-test-remove-AVX-specific-micro-benchmark.patch +--- + .../test/onnx/microbenchmark/reduceminmax.cc | 24 ------------------- + 1 file changed, 24 deletions(-) + +diff --git a/onnxruntime/test/onnx/microbenchmark/reduceminmax.cc b/onnxruntime/test/onnx/microbenchmark/reduceminmax.cc +index 06a7f50c9a..eeaa9e0067 100644 +--- a/onnxruntime/test/onnx/microbenchmark/reduceminmax.cc ++++ b/onnxruntime/test/onnx/microbenchmark/reduceminmax.cc +@@ -91,28 +91,4 @@ BENCHMARK(BM_FindMinMaxMlasSSE2) + ->Arg(98304) + ->Arg(160000); + +-// MLAS avx implementation +-static void BM_FindMinMaxMlasAvx(benchmark::State& state) { +- const size_t batch_size = static_cast(state.range(0)); +- float* data = GenerateArrayWithRandomValue(batch_size, -1, 1); +- float min = std::numeric_limits::max(); +- float max = std::numeric_limits::lowest(); +- for (auto _ : state) { +- MlasReduceMinimumMaximumF32KernelAvx(data, &min, &max, batch_size); +- } +- aligned_free(data); +-} +- +-BENCHMARK(BM_FindMinMaxMlasAvx) +- ->UseRealTime() +- ->UseRealTime() +- ->Unit(benchmark::TimeUnit::kNanosecond) +- ->Arg(100) +- ->Arg(1000) +- ->Arg(10000) +- ->Arg(20000) +- ->Arg(40000) +- ->Arg(80000) +- ->Arg(98304) +- ->Arg(160000); + +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0002-onnxruntime-add-SONAME-with-MAJOR-version.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0002-onnxruntime-add-SONAME-with-MAJOR-version.patch new file mode 100644 index 000000000..6ef4e4200 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0002-onnxruntime-add-SONAME-with-MAJOR-version.patch @@ -0,0 +1,25 @@ +From cb9bd5d833845a5e12c38b5b457fd232498efeb7 Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Tue, 9 May 2023 13:33:14 +0200 +Subject: [PATCH 2/5] onnxruntime: add SONAME with MAJOR version + +Signed-off-by: Othmane AHL ZOUAOUI + +%% original patch: 0002-onnxruntime-add-SONAME-with-MAJOR-version.patch +--- + cmake/CMakeLists.txt | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt +index a5d28fb516..08a4c6af52 100644 +--- a/cmake/CMakeLists.txt ++++ b/cmake/CMakeLists.txt +@@ -1617,3 +1617,6 @@ if (onnxruntime_ENABLE_EXTERNAL_CUSTOM_OP_SCHEMAS) + COMMENT "Installing protobuf" + ) + endif() ++ ++message("ONNXRUNTIME_VERSION_MAJOR=${ONNXRUNTIME_VERSION_MAJOR}") ++set_target_properties(onnxruntime PROPERTIES SOVERSION "${ONNXRUNTIME_VERSION_MAJOR}") +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0003-onnxruntime-test-libcustom-library-remove-relative.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0003-onnxruntime-test-libcustom-library-remove-relative.patch new file mode 100644 index 000000000..7be9cb5ad --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0003-onnxruntime-test-libcustom-library-remove-relative.patch @@ -0,0 +1,59 @@ +From e13955dec97f7635cb055e86cb2db026f74e4823 Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Tue, 9 May 2023 13:50:46 +0200 +Subject: [PATCH 3/5] onnxruntime: test: libcustom library remove relative + +Signed-off-by: Othmane AHL ZOUAOUI + +%% original patch: 0003-onnxruntime-test-libcustom-library-remove-relative.patch +--- + onnxruntime/test/python/onnxruntime_test_python.py | 4 ++-- + onnxruntime/test/shared_lib/test_inference.cc | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/onnxruntime/test/python/onnxruntime_test_python.py b/onnxruntime/test/python/onnxruntime_test_python.py +index 89fd90ad3a..6bf0eb0399 100644 +--- a/onnxruntime/test/python/onnxruntime_test_python.py ++++ b/onnxruntime/test/python/onnxruntime_test_python.py +@@ -953,7 +953,7 @@ class TestInferenceSession(unittest.TestCase): + raise FileNotFoundError("Unable to find '{0}'".format(shared_library)) + + else: +- shared_library = "./libcustom_op_library.so" ++ shared_library = "/usr/lib/libcustom_op_library.so" + if not os.path.exists(shared_library): + raise FileNotFoundError("Unable to find '{0}'".format(shared_library)) + +@@ -1312,7 +1312,7 @@ class TestInferenceSession(unittest.TestCase): + return + + else: +- shared_library = "./libtest_execution_provider.so" ++ shared_library = "/usr/lib/libtest_execution_provider.so" + + if not os.path.exists(shared_library): + raise FileNotFoundError("Unable to find '{0}'".format(shared_library)) +diff --git a/onnxruntime/test/shared_lib/test_inference.cc b/onnxruntime/test/shared_lib/test_inference.cc +index 09219b40de..db4d73f4c0 100644 +--- a/onnxruntime/test/shared_lib/test_inference.cc ++++ b/onnxruntime/test/shared_lib/test_inference.cc +@@ -1302,7 +1302,7 @@ TEST(CApiTest, test_custom_op_library) { + #elif defined(__APPLE__) + lib_name = ORT_TSTR("libcustom_op_library.dylib"); + #else +- lib_name = ORT_TSTR("./libcustom_op_library.so"); ++ lib_name = ORT_TSTR("libcustom_op_library.so"); + #endif + + #ifdef USE_CUDA +@@ -1329,7 +1329,7 @@ TEST(CApiTest, test_custom_op_library_registration_error) { + #elif defined(__APPLE__) + lib_name = ORT_TSTR("libcustom_op_invalid_library.dylib"); + #else +- lib_name = ORT_TSTR("./libcustom_op_invalid_library.so"); ++ lib_name = ORT_TSTR("libcustom_op_invalid_library.so"); + #endif + + Ort::SessionOptions session_options; +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0004-onnxruntime-fix-imcompatibility-with-compiler-GCC12.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0004-onnxruntime-fix-imcompatibility-with-compiler-GCC12.patch new file mode 100644 index 000000000..613fcfcfb --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0004-onnxruntime-fix-imcompatibility-with-compiler-GCC12.patch @@ -0,0 +1,38 @@ +From 961ee9cf8510b4d9d87777105a338fa31a5d572a Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Tue, 9 May 2023 14:03:04 +0200 +Subject: [PATCH 4/5] onnxruntime: fix imcompatibility with compiler GCC12.2.1 + bug + +As stated in this issue below, the onnxruntime 14.4.0 release is +not compatible with the version 12.2.1 of the GCC cross compiler. +This patch is a workaround to fix this incompatibility bug. + +Link to onnxruntime github issue: +https://github.com/microsoft/onnxruntime/issues/14981 + +Signed-off-by: Othmane AHL ZOUAOUI + +%% original patch: 0004-onnxruntime-fix-imcompatibility-with-compiler-GCC12..patch +--- + onnxruntime/core/providers/cpu/tensor/scatter.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/onnxruntime/core/providers/cpu/tensor/scatter.cc b/onnxruntime/core/providers/cpu/tensor/scatter.cc +index 2d932dfe59..2e2f47d31f 100644 +--- a/onnxruntime/core/providers/cpu/tensor/scatter.cc ++++ b/onnxruntime/core/providers/cpu/tensor/scatter.cc +@@ -340,7 +340,11 @@ Status ScatterData( + // and so on + std::vector dim_block_size(num_dims); + ++#if __GNUC__ >= 12 ++ dim_block_size[num_dims-1] = 1; ++#else + dim_block_size.back() = 1; ++#endif + if (num_dims > 1) { + // We start at num_dims - 2 because we already pre-populated + // the last element above +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0005-onnxruntime-avoid-using-unsupported-Eigen-headers.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0005-onnxruntime-avoid-using-unsupported-Eigen-headers.patch new file mode 100644 index 000000000..034b7d8d6 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0005-onnxruntime-avoid-using-unsupported-Eigen-headers.patch @@ -0,0 +1,58 @@ +From 8195a2404f122d25814b851cd738cf0ff1e91d89 Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Wed, 10 May 2023 10:39:00 +0200 +Subject: [PATCH 5/5] onnxruntime: avoid using unsupported Eigen headers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch removes the suspected Unsupported/Eigen/CXX11 headers and +uses Onnx internal headers instead. It enables also the pragma for +HAS_CLASS_MEMACCESS to treat the class-memaccess as warnings. +This allows fixing the following build error: ‘void* memcpy(void*, +const void*, size_t)’ copying an object of non-trivial type +‘Eigen::internal::Packet4c’{aka ‘const signed char’} +[-Werror=class-memaccess] + +Signed-off-by: Othmane AHL ZOUAOUI + +%% original patch: 0006-onnxruntime-avoid-using-unsupported-Eigen-headers.patch +--- + onnxruntime/test/onnx/microbenchmark/eigen.cc | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/onnxruntime/test/onnx/microbenchmark/eigen.cc b/onnxruntime/test/onnx/microbenchmark/eigen.cc +index b3b2c55600..00c317da50 100644 +--- a/onnxruntime/test/onnx/microbenchmark/eigen.cc ++++ b/onnxruntime/test/onnx/microbenchmark/eigen.cc +@@ -6,6 +6,13 @@ + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wunused-result" + #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" ++// cmake/external/eigen/unsupported/Eigen/CXX11/../../../Eigen/src/Core/arch/NEON/PacketMath.h:1633:9: ++// error: ‘void* memcpy(void*, const void*, size_t)’ copying an object of non-trivial type ‘Eigen::internal::Packet4c’ ++// {aka ‘struct Eigen::internal::eigen_packet_wrapper’} from an array of ‘const int8_t’ ++// {aka ‘const signed char’} [-Werror=class-memaccess] ++#ifdef HAS_CLASS_MEMACCESS ++#pragma GCC diagnostic ignored "-Wclass-memaccess" ++#endif + #elif defined(_MSC_VER) + // build\windows\debug\external\eigen3\unsupported\eigen\cxx11\src/Tensor/Tensor.h(76): + // warning C4554: '&': check operator precedence for possible error; use parentheses to clarify precedence +@@ -22,9 +29,11 @@ + #define EIGEN_USE_THREADS + #endif + +-#include +-#include +-#include ++#include "core/platform/threadpool.h" ++#include "core/common/eigen_common_wrapper.h" ++#include "core/util/thread_utils.h" ++#include ++ + #if defined(__GNUC__) + #pragma GCC diagnostic pop + #elif defined(_MSC_VER) +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0006-onnxruntime-xnnpack-Fix-mcpu-compiler-build-failure.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0006-onnxruntime-xnnpack-Fix-mcpu-compiler-build-failure.patch new file mode 100644 index 000000000..3e6c53b55 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0006-onnxruntime-xnnpack-Fix-mcpu-compiler-build-failure.patch @@ -0,0 +1,43 @@ +From a313277345bb498f9a788b905ed3f4e37ba31b57 Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Tue, 30 May 2023 17:17:39 +0200 +Subject: [PATCH 6/6] onnxruntime: xnnpack: Fix -mcpu compiler build failure + +The "-mcpu=" switch is introduced externaly into CMake by Yocto +buildsystem toolchain. This switch is not compatible with XNNPACK +build mechanism and causes the XNNPACK compilation break due to +"unsupported instructions". +This switch needs to be removed for XNNPACK In order to isolate +the changes only for XNNPACK and its depencencies, a subfolder and +a fix are introduced through this patch. + +Signed-off-by: Othmane AHL ZOUAOUI +--- + cmake/external/xnnpack.cmake | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/cmake/external/xnnpack.cmake b/cmake/external/xnnpack.cmake +index 1fc2c6ccdc..62fad6ce38 100644 +--- a/cmake/external/xnnpack.cmake ++++ b/cmake/external/xnnpack.cmake +@@ -11,6 +11,18 @@ if(CMAKE_ANDROID_ARCH_ABI STREQUAL armeabi-v7a) + set(XNNPACK_ENABLE_ARM_BF16 OFF) + ENDIF() + ++string(REGEX REPLACE "-mcpu=[-a-zA-Z0-9_.^$*+?]*" "" _tmp ${CMAKE_C_FLAGS}) ++set(CMAKE_C_FLAGS ${_tmp}) ++message("CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") ++ ++string(REGEX REPLACE "-mcpu=[-a-zA-Z0-9_.^$*+?]*" "" _tmp ${CMAKE_ASM_FLAGS}) ++set(CMAKE_ASM_FLAGS ${_tmp}) ++message("CMAKE_ASM_FLAGS: ${CMAKE_ASM_FLAGS}") ++ ++string(REGEX REPLACE "-mcpu=[-a-zA-Z0-9_.^$*+?]*" "" _tmp ${CMAKE_CXX_FLAGS}) ++set(CMAKE_CXX_FLAGS ${_tmp}) ++message("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") ++ + # fp16 depends on psimd + FetchContent_Declare(psimd URL ${DEP_URL_psimd} URL_HASH SHA1=${DEP_SHA1_psimd}) + onnxruntime_fetchcontent_makeavailable(psimd) +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0007-onnxruntime-cmake-change-visibility-compilation-opti.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0007-onnxruntime-cmake-change-visibility-compilation-opti.patch new file mode 100644 index 000000000..6ae66fc2a --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/files/0007-onnxruntime-cmake-change-visibility-compilation-opti.patch @@ -0,0 +1,26 @@ +From ce4219ad77d422b9b5adc032ab911824ef212c41 Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Wed, 20 Mar 2024 15:59:12 +0100 +Subject: [PATCH 1/1] onnxruntime: cmake: change visibility compilation options + +Changing the compile options of the libonnxruntime shared lib +to export all the symbols of the lib and make them visible during +the runtime. + +Signed-off-by: Othmane AHL ZOUAOUI +--- + cmake/CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt +index 08a4c6af52..1336ceb19b 100644 +--- a/cmake/CMakeLists.txt ++++ b/cmake/CMakeLists.txt +@@ -1620,3 +1620,5 @@ endif() + + message("ONNXRUNTIME_VERSION_MAJOR=${ONNXRUNTIME_VERSION_MAJOR}") + set_target_properties(onnxruntime PROPERTIES SOVERSION "${ONNXRUNTIME_VERSION_MAJOR}") ++target_compile_options(onnxruntime PRIVATE -fvisibility=hidden) ++target_compile_options(onnxruntime PRIVATE -fvisibility=default) +-- +2.34.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/onnxruntime_git.bbappend b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/onnxruntime_git.bbappend index 7c7a3079e..6ef6386c2 100644 --- a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/onnxruntime_git.bbappend +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/onnxruntime/onnxruntime_git.bbappend @@ -1,45 +1,103 @@ -# Copyright 2023 Digi International Inc. +# Copyright (C) 2023-2024, Digi International Inc. + +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +PV = "1.14.0+git${SRCPV}" + +SRCREV = "6ccaeddefa65ccac402a47fa4d9cad8229794bb2" +SRC_URI = "gitsm://github.com/microsoft/onnxruntime.git;branch=rel-1.14.0;protocol=https" +SRC_URI += " file://0001-onnxruntime-test-remove-AVX-specific-micro-benchmark.patch " +SRC_URI += " file://0002-onnxruntime-add-SONAME-with-MAJOR-version.patch " +SRC_URI += " file://0003-onnxruntime-test-libcustom-library-remove-relative.patch " +SRC_URI += " file://0004-onnxruntime-fix-imcompatibility-with-compiler-GCC12.patch " +SRC_URI += " file://0005-onnxruntime-avoid-using-unsupported-Eigen-headers.patch " +SRC_URI += " file://0007-onnxruntime-cmake-change-visibility-compilation-opti.patch " +SRC_URI:append:stm32mp2common = " file://0006-onnxruntime-xnnpack-Fix-mcpu-compiler-build-failure.patch " + +PROTOC_VERSION = "3.20.2" +SRC_URI += "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip;name=protoc;subdir=protoc-${PROTOC_VERSION}/" +SRC_URI[protoc.sha256sum] = "d97227fd8bc840dcb1cf7332c8339a2d8f0fc381a98b028006e5c9a911d07c2a" + +S = "${WORKDIR}/git" + +inherit python3-dir cmake + +DEPENDS:append = "\ + ${PYTHON_PN}-numpy \ +" + +EXTRA_OECMAKE += " -DPython_NumPy_INCLUDE_DIR="${STAGING_LIBDIR}/${PYTHON_DIR}/site-packages/numpy/core/include" \ + -DBENCHMARK_ENABLE_GTEST_TESTS=OFF \ + -Donnxruntime_USE_XNNPACK=ON \ + -Donnxruntime_BUILD_UNIT_TESTS=ON \ +" + +ONNX_TARGET_ARCH:aarch64="${@bb.utils.contains('TUNE_FEATURES', 'cortexa35', 'aarch64', '', d)}" do_install() { # Install onnxruntime dynamic library install -d ${D}${libdir} install -d ${D}${prefix}/local/bin/${PN}-${PVB}/tools + install -d ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 0644 ${B}/libonnxruntime.so ${D}${libdir}/libonnxruntime.so.${PVB} # This shared lib is used by onnxruntime_shared_lib_test and onnxruntime_test_python.py install -m 644 ${B}/libcustom_op_library.so ${D}${libdir} + # And this one only by onnxruntime_test_python.py - install -m 644 ${B}/libtest_execution_provider.so ${D}${libdir} - install -m 644 ${B}/libonnxruntime_providers_shared.so ${D}${libdir}/libonnxruntime_providers_shared.so - install -m 644 ${B}/onnxruntime_pybind11_state.so ${D}${libdir}/onnxruntime_pybind11_state.so + install -m 644 ${B}/libtest_execution_provider.so ${D}${libdir} + install -m 644 ${B}/libonnxruntime_providers_shared.so ${D}${libdir}/libonnxruntime_providers_shared.so + install -m 644 ${B}/libcustom_op_invalid_library.so ${D}${libdir}/libcustom_op_invalid_library.so + install -m 644 ${B}/onnxruntime_pybind11_state.so ${D}${libdir}/onnxruntime_pybind11_state.so # Install the symlinks. ln -sf libonnxruntime.so.${PVB} ${D}${libdir}/libonnxruntime.so.${MAJOR} ln -sf libonnxruntime.so.${PVB} ${D}${libdir}/libonnxruntime.so - # Digi: copy instead of moving to avoid QA errors - # Copy the onnx_test_runner executable that was installed in /usr instead of /usr/local. - cp ${B}/onnx_test_runner ${D}${prefix}/local/bin/${PN}-${PVB}/tools - # These are not included in the base installation, so we install them manually. - install -m 755 ${B}/onnxruntime_perf_test ${D}${prefix}/local/bin/${PN}-${PVB}/tools - install -m 755 ${B}/onnxruntime_test_all ${D}${prefix}/local/bin/${PN}-${PVB}/tools - install -m 755 ${B}/onnxruntime_shared_lib_test ${D}${prefix}/local/bin/${PN}-${PVB}/tools - install -m 755 ${B}/onnxruntime_api_tests_without_env ${D}${prefix}/local/bin/${PN}-${PVB}/tools - install -m 755 ${B}/onnxruntime_global_thread_pools_test ${D}${prefix}/local/bin/${PN}-${PVB}/tools - install -m 755 ${B}/onnxruntime_test_python.py ${D}${prefix}/local/bin/${PN}-${PVB}/tools - install -m 755 ${B}/helper.py ${D}${prefix}/local/bin/${PN}-${PVB}/tools - cp -r ${B}/testdata ${D}${prefix}/local/bin/${PN}-${PVB}/tools + install -m 755 ${B}/onnx_test_runner ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 755 ${B}/onnxruntime_perf_test ${D}${prefix}/local/bin/${PN}-${PVB}/tools + install -m 755 ${B}/onnxruntime_test_all ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 755 ${B}/onnxruntime_shared_lib_test ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 755 ${B}/onnxruntime_api_tests_without_env ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 755 ${B}/onnxruntime_global_thread_pools_test ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 755 ${B}/onnxruntime_test_python.py ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + install -m 755 ${B}/helper.py ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests + cp -r ${B}/testdata ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests # We have to change some of the RPATH as well. chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/tools/onnxruntime_perf_test - chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/tools/onnxruntime_shared_lib_test - chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/tools/onnxruntime_api_tests_without_env - chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/tools/onnxruntime_global_thread_pools_test + chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests/onnxruntime_shared_lib_test + chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests/onnxruntime_api_tests_without_env + chrpath -r '$ORIGIN' ${D}${prefix}/local/bin/${PN}-${PVB}/unit-tests/onnxruntime_global_thread_pools_test chrpath -r '$ORIGIN' ${D}${libdir}/libtest_execution_provider.so # Install the Python package. mkdir -p ${D}${PYTHON_SITEPACKAGES_DIR}/onnxruntime cp -r ${B}/onnxruntime ${D}${PYTHON_SITEPACKAGES_DIR} + + # Install header files + install -d ${D}${includedir}/onnxruntime + cd ${S}/onnxruntime + cp --parents $(find . -name "*.h*" -not -path "*cmake_build/*") ${D}${includedir}/onnxruntime + cp ${S}/include/onnxruntime/core/session/onnxruntime_cxx_api.h ${D}${includedir}/onnxruntime + cp ${S}/include/onnxruntime/core/session/onnxruntime_c_api.h ${D}${includedir}/onnxruntime + cp ${S}/include/onnxruntime/core/session/onnxruntime_cxx_inline.h ${D}${includedir}/onnxruntime } + +# The package_qa() task does not like the fact that this library is present in both onnxruntime-tools +# and python3-onnxruntime packages (the normal /usr/lib version and a copy placed inside the Python package). +# So we simply mark the lib as a "private lib", to prevent the task from outputting an error. +PRIVATE_LIBS = "libonnxruntime_providers_shared.so" + +PACKAGES += "${PN}-unit-tests" +PROVIDES += "${PN}-unit-tests" + +FILES:${PN}-tools = "${prefix}/local/bin/${PN}-${PVB}/tools/onnxruntime_perf_test" +FILES:${PN}-unit-tests = "${prefix}/local/bin/${PN}-${PVB}/unit-tests/* ${libdir}/libcustom_op_invalid_library.so ${libdir}/libtest_execution_provider.so ${libdir}/libcustom_op_library.so" + +# onnxruntime_test_python.py unitary test requires python3-numpy and python3-onnxruntime packages +RDEPENDS:${PN}-unit-tests += "${PYTHON_PN}-${PN}" +RDEPENDS:${PYTHON_PN}-${PN} += "${PYTHON_PN}-numpy" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0006-TFLite-cmake-add-XNNPACK-delegate-u8-and-i8-definition.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0006-TFLite-cmake-add-XNNPACK-delegate-u8-and-i8-definition.patch new file mode 100644 index 000000000..6aea05595 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0006-TFLite-cmake-add-XNNPACK-delegate-u8-and-i8-definition.patch @@ -0,0 +1,25 @@ +From c8af5997f3d9b851ff81ef1fb4045ec59f80d976 Mon Sep 17 00:00:00 2001 +From: Alexis BRISSON +Date: Wed, 10 May 2023 16:44:47 +0200 +Subject: [PATCH 1/1] TFLite add XNNPACK delegate u8 and i8 definition + +Signed-off-by: Alexis BRISSON +--- + tensorflow/lite/CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/lite/CMakeLists.txt b/tensorflow/lite/CMakeLists.txt +index 073b29c4860..b3b89a4236c 100644 +--- a/tensorflow/lite/CMakeLists.txt ++++ b/tensorflow/lite/CMakeLists.txt +@@ -404,6 +404,8 @@ if(TFLITE_ENABLE_XNNPACK) + TFLITE_DELEGATES_XNNPACK_SRCS + FILTER ".*(_test|_tester)\\.(cc|h)" + ) ++ add_definitions( -DXNNPACK_DELEGATE_ENABLE_QS8=1 ) ++ add_definitions( -DXNNPACK_DELEGATE_ENABLE_QU8=1 ) + list(APPEND TFLITE_TARGET_DEPENDENCIES + XNNPACK + ) +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0007-TFLite-fix-aarch64-support-for-XNNPACK.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0007-TFLite-fix-aarch64-support-for-XNNPACK.patch new file mode 100644 index 000000000..62519cb53 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0007-TFLite-fix-aarch64-support-for-XNNPACK.patch @@ -0,0 +1,44 @@ +From 78cbe3bb1970982adf32c9966b83789301d45cd8 Mon Sep 17 00:00:00 2001 +From: Maxence GUILHIN +Date: Mon, 10 Jul 2023 15:47:59 +0200 +Subject: [PATCH 1/1] tensorflow-lite : fix aarch64 support for XNNPACK + +The "-mcpu=" switch might be introduced externaly into CMake: either in _FLAGS or +as part of CC, CXX, ASM environmental variables (to be stored in CMAKE__COMPILER_ARG1). +This switch is not compatible with XNNPACK build mechanism and causes the XNNPACK compilation +break due to "unsupported instructions". This switch needs to be removed for XNNPACK +In order to isolate the changes only for XNNPACK and its depencencies, a subfolder is +introduced. + +Signed-off-by: Maxence GUILHIN +--- + tensorflow/lite/tools/cmake/modules/xnnpack.cmake | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/tensorflow/lite/tools/cmake/modules/xnnpack.cmake b/tensorflow/lite/tools/cmake/modules/xnnpack.cmake +index 24f0674cf92..028fc3a76e2 100644 +--- a/tensorflow/lite/tools/cmake/modules/xnnpack.cmake ++++ b/tensorflow/lite/tools/cmake/modules/xnnpack.cmake +@@ -38,6 +38,20 @@ endif() + set(XNNPACK_BUILD_TESTS OFF CACHE BOOL "Disable XNNPACK test.") + set(XNNPACK_BUILD_BENCHMARKS OFF CACHE BOOL "Disable XNNPACK benchmarks.") + ++# The "-mcpu=" switch might be introduced externaly into CMake: either in _FLAGS or ++# as part of CC, CXX, ASM environmental variables (to be stored in CMAKE__COMPILER_ARG1). ++# This switch is not compatible with XNNPACK build mechanism and causes the XNNPACK compilation ++# break due to "unsupported instructions". This switch needs to be removed for XNNPACK ++# In order to isolate the changes only for XNNPACK and its depencencies, a subfolder is ++# introduced. ++ ++foreach(FLAG IN ITEMS CMAKE_ASM_FLAGS CMAKE_ASM_COMPILER_ARG1 CMAKE_C_FLAGS CMAKE_C_COMPILER_ARG1 CMAKE_CXX_FLAGS CMAKE_CXX_COMPILER_ARG1) ++ if(${FLAG}) ++ string(REGEX REPLACE "-mcpu=[-a-zA-Z0-9_.^$*+?]*" "" _tmp ${${FLAG}}) ++ set(${FLAG} ${_tmp}) ++ endif() ++endforeach() ++ + # The following line adds project of PTHREADPOOL, FP16 and XNNPACK which are + # needed to compile XNNPACK delegate of TFLite. + add_subdirectory( +-- +2.25.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0008-TFLite-cmake-change-visibility-compilation-options.patch b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0008-TFLite-cmake-change-visibility-compilation-options.patch new file mode 100644 index 000000000..714f30fbe --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/files/0008-TFLite-cmake-change-visibility-compilation-options.patch @@ -0,0 +1,30 @@ +From 0675ef8a401c5f77aeb674b006594190c7f58810 Mon Sep 17 00:00:00 2001 +From: Othmane AHL ZOUAOUI +Date: Wed, 20 Mar 2024 15:05:40 +0100 +Subject: [PATCH 8/8] TFLite: cmake: change visibility compilation options + +Changing the compile options of the libtensorflow-lite shared lib +to export all the symbols of the lib and make them visible during +the runtime. + +Change-Id: I25a88a3ba29b00d1f40336e10acb898ab8b016a5 +Signed-off-by: Othmane AHL ZOUAOUI +--- + tensorflow/lite/CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/lite/CMakeLists.txt b/tensorflow/lite/CMakeLists.txt +index 40812886306..f7bb65d894a 100644 +--- a/tensorflow/lite/CMakeLists.txt ++++ b/tensorflow/lite/CMakeLists.txt +@@ -517,6 +517,8 @@ set(_ALL_TFLITE_SRCS + add_library(tensorflow-lite SHARED EXCLUDE_FROM_ALL + ${_ALL_TFLITE_SRCS} + ) ++target_compile_options(tensorflow-lite PRIVATE -fvisibility=hidden) ++target_compile_options(tensorflow-lite PRIVATE -fvisibility=default) + set(_ALL_TFLITE_HDRS ${_ALL_TFLITE_SRCS}) + list(FILTER _ALL_TFLITE_HDRS INCLUDE REGEX ".*\\.h$") + target_include_directories(tensorflow-lite +-- +2.34.1 diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/tensorflow-lite_git.bbappend b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/tensorflow-lite_git.bbappend new file mode 100644 index 000000000..6eb361db0 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-frameworks/tensorflow-lite/tensorflow-lite_git.bbappend @@ -0,0 +1,47 @@ +# Copyright (C) 2024, Digi International Inc. + +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += " file://0006-TFLite-cmake-add-XNNPACK-delegate-u8-and-i8-definition.patch " +SRC_URI += " file://0008-TFLite-cmake-change-visibility-compilation-options.patch " +SRC_URI:append:stm32mp2common = " file://0007-TFLite-fix-aarch64-support-for-XNNPACK.patch " + +# Set building environment variables +TENSORFLOW_TARGET:aarch64="linux" +TENSORFLOW_TARGET_ARCH:aarch64="aarch64" + +# Activate -O3 optimization and disable debug symbols +OECMAKE_C_FLAGS_RELEASE = "-O3 -DNDEBUG" +OECMAKE_CXX_FLAGS_RELEASE = "-O3 -DNDEBUG" +# Build tensorflow-lite.so library, _pywrap_tensorflow_interpreter_wrapper.so library and the benchmark_model application +OECMAKE_TARGET_COMPILE = "tensorflow-lite _pywrap_tensorflow_interpreter_wrapper benchmark_model" + +EXTRA_OECMAKE += " -DTFLITE_ENABLE_XNNPACK=OFF " + +do_compile() { + # Standard CMAKE build. + cmake_runcmake_build --target ${OECMAKE_TARGET_COMPILE} + # Build the python wheel (procedure extract form the build_pip_package_with_cmake.sh) + BUILD_DIR=${WORKDIR}/build + TENSORFLOW_DIR=${S} + TENSORFLOW_LITE_DIR="${TENSORFLOW_DIR}/tensorflow/lite" + TENSORFLOW_VERSION=$(grep "_VERSION = " "${TENSORFLOW_DIR}/tensorflow/tools/pip_package/setup.py" | cut -d= -f2 | sed "s/[ '-]//g") + mkdir -p "${BUILD_DIR}/tflite_runtime" + cp -r "${TENSORFLOW_LITE_DIR}/tools/pip_package/debian" \ + "${TENSORFLOW_LITE_DIR}/tools/pip_package/MANIFEST.in" \ + "${BUILD_DIR}" + cp -r "${TENSORFLOW_LITE_DIR}/python/interpreter_wrapper" "${BUILD_DIR}" + cp "${TENSORFLOW_LITE_DIR}/tools/pip_package/setup_with_binary.py" "${BUILD_DIR}/setup.py" + cp "${TENSORFLOW_LITE_DIR}/python/interpreter.py" \ + "${TENSORFLOW_LITE_DIR}/python/metrics/metrics_interface.py" \ + "${TENSORFLOW_LITE_DIR}/python/metrics/metrics_portable.py" \ + "${BUILD_DIR}/tflite_runtime" + echo "__version__ = '${TENSORFLOW_VERSION}'" >> "${BUILD_DIR}/tflite_runtime/__init__.py" + echo "__git_version__ = '$(git -C "${TENSORFLOW_DIR}" describe)'" >> "${BUILD_DIR}/tflite_runtime/__init__.py" + + export PACKAGE_VERSION="${TENSORFLOW_VERSION}" + export PROJECT_NAME="tflite_runtime" + cp "${BUILD_DIR}/_pywrap_tensorflow_interpreter_wrapper.so" "tflite_runtime" + + setuptools3_do_compile +} diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/common/scripts/launch_npu_demo.sh b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/common/scripts/launch_npu_demo.sh new file mode 100644 index 000000000..1e6c6257a --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/common/scripts/launch_npu_demo.sh @@ -0,0 +1,72 @@ +#!/bin/sh +#=============================================================================== +# +# Copyright (C) 2024 by Digi International Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# +# !Description: Launch script for ST NPU demos +# +#=============================================================================== + +# Default demo to launch. +DEFAULT_DEMO="pose_estimation" + +# Prepare MIPI camera. +media-ctl -d /dev/media2 --set-v4l2 "'ov5640 0-003c':0[fmt:SBGGR8_1X8/1280x720]" +media-ctl -d /dev/media2 --set-v4l2 "'stm32_csi2host.48020000.csi2hos':1[fmt:SBGGR8_1X8/1280x720]" +media-ctl -d /dev/media2 --set-v4l2 "'dcmipp_main_isp':1[fmt:RGB888_1X24/1280x720 field:none]" +media-ctl -d /dev/media2 --set-v4l2 "'dcmipp_main_postproc':0[compose:(0,0)/640x480]" +media-ctl -d /dev/media2 --set-v4l2 "'dcmipp_main_postproc':1[fmt:RGB565_2X8_LE/640x480]" + +# Mirror the image. +v4l2-ctl -d /dev/v4l-subdev6 --set-ctrl "horizontal_flip=1" +#v4l2-ctl -d /dev/v4l-subdev6 --set-ctrl "vertical_flip=1" + +# Configure Wayland/Weston settings. +export "DISPLAY=:0.0" +export "XDG_RUNTIME_DIR=/run/user/0" +export "WAYLAND_DISPLAY=wayland-1" + +# Wait until Wayland framework is ready. +wait_for_wayland() { + local count=20 + local wayland_socket="/run/user/0/${WAYLAND_DISPLAY}" + + while [ ! -S "${wayland_socket}" ]; do + sleep 1 + count=$((count-1)) + if [ "${count}" = 0 ]; then + return 1 + fi + done + return 0 +} +[ -d "/usr/share/wayland" ] && wait_for_wayland + +# Try to extract the demo to launch from the script name. +DEMO=${DEFAULT_DEMO} +DEMO_FROM_NAME="$(basename "${0}" | sed -n 's/^launch_npu_demo_\(.*\)\.sh$/\1/p')" + +# Check if the demo to launch was passed as argument. +if [ -n "${1}" ]; then + DEMO=${1} +elif [ -n "${DEMO_FROM_NAME}" ]; then + DEMO=${DEMO_FROM_NAME} +fi + +# Build the demo folder name. +DEMO_FOLDER_NAME="$(echo "${DEMO}" | sed 's/_/-/g')" + +# Build the demo full path. +DEMO_DIR="/usr/local/demo-ai/${DEMO_FOLDER_NAME}" + +# Verify that the demo directory exists. +[ -d "${DEMO_DIR}" ] || { echo "Error: Demo ${DEMO} does not exist"; exit 1; } + +# Execute the demo. +"${DEMO_DIR}/tflite/launch_python_${DEMO}.sh" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/coral-image-classification-cpp_5.0.0.bb b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/coral-image-classification-cpp_5.0.0.bb new file mode 100644 index 000000000..38b4bbd6a --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/coral-image-classification-cpp_5.0.0.bb @@ -0,0 +1,63 @@ +# Copyright (C) 2022, STMicroelectronics - All Rights Reserved +SUMMARY = "TensorFlowLite C++ API Computer Vision image classification application example running on the EdgeTPU" +LICENSE = "BSD-3-Clause & Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9" +LIC_FILES_CHKSUM += "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit pkgconfig + +DEPENDS += "tensorflow-lite libedgetpu gtk+3 opencv gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad " + +SRC_URI = " file://tflite;subdir=${BPN}-${PV} " + +S = "${WORKDIR}/${BPN}-${PV}" + +do_configure[noexec] = "1" + +EXTRA_OEMAKE = 'SYSROOT="${RECIPE_SYSROOT}"' +EXTRA_OEMAKE += 'EDGETPU=TRUE' + +do_compile() { + #Check the version of OpenCV and fill OPENCV_VERSION accordingly + FILE=${RECIPE_SYSROOT}/${libdir}/pkgconfig/opencv4.pc + if [ -f "$FILE" ]; then + OPENCV_VERSION=opencv4 + else + OPENCV_VERSION=opencv + fi + + oe_runmake OPENCV_PKGCONFIG=${OPENCV_VERSION} -C ${S}/tflite/ +} + +do_install() { + install -d ${D}${prefix}/local/demo/application + install -d ${D}${prefix}/local/demo-ai/image-classification/coral/ + + # install applications into the demo launcher + install -m 0755 ${S}/tflite/111-coral-image-classification-cpp.yaml ${D}${prefix}/local/demo/application + + # install application binaries and launcher scripts + install -m 0755 ${S}/tflite/tflite_image_classification ${D}${prefix}/local/demo-ai/image-classification/coral/coral_image_classification + install -m 0755 ${S}/tflite/launch_coral_bin*.sh ${D}${prefix}/local/demo-ai/image-classification/coral +} + +FILES:${PN} += "${prefix}/local/" + +INSANE_SKIP:${PN} = "ldflags" + +RDEPENDS:${PN} += " \ + gstreamer1.0-plugins-bad-waylandsink \ + gstreamer1.0-plugins-bad-debugutilsbad \ + gstreamer1.0-plugins-base-app \ + gstreamer1.0-plugins-base-videorate \ + gstreamer1.0-plugins-good-video4linux2 \ + gstreamer1.0-plugins-base-videoconvertscale \ + gtk+3 \ + libedgetpu \ + libopencv-core \ + libopencv-imgproc \ + libopencv-imgcodecs \ + coral-models-mobilenetv1 \ + application-resources \ + bash \ +" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/coral-image-classification-python_5.0.0.bb b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/coral-image-classification-python_5.0.0.bb new file mode 100644 index 000000000..508399834 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/coral-image-classification-python_5.0.0.bb @@ -0,0 +1,39 @@ +# Copyright (C) 2022, STMicroelectronics - All Rights Reserved +SUMMARY = "TensorFlowLite Python Computer Vision image classification application examples running on the EdgeTPU" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9" + +SRC_URI = " file://tflite;subdir=${BPN}-${PV} " + +S = "${WORKDIR}/${BPN}-${PV}" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d ${D}${prefix}/local/demo/application + install -d ${D}${prefix}/local/demo-ai/image-classification/coral + install -d ${D}${prefix}/local/demo-ai/image-classification/resources + + # install applications into the demo launcher + install -m 0755 ${S}/tflite/110-coral-image-classification-python.yaml ${D}${prefix}/local/demo/application + + # install application binaries and launcher scripts + install -m 0755 ${S}/tflite/tflite_image_classification.py ${D}${prefix}/local/demo-ai/image-classification/coral/coral_image_classification.py + install -m 0755 ${S}/tflite/launch_coral_python*.sh ${D}${prefix}/local/demo-ai/image-classification/coral/ +} + +FILES:${PN} += "${prefix}/local/" + +RDEPENDS:${PN} += " \ + python3-core \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pygobject \ + python3-tensorflow-lite \ + libedgetpu \ + coral-models-mobilenetv1 \ + application-resources \ + bash \ +" diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/130-nbg-image-classification-C++.yaml b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/130-nbg-image-classification-C++.yaml new file mode 100644 index 000000000..56b587a27 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/130-nbg-image-classification-C++.yaml @@ -0,0 +1,15 @@ +Application: + Name: Image Classification + Description: Mobilenet v3 + Icon: ../demo-ai/resources/nbg_cpp.png + Board: + List: all + Type: script + Script: + Exist: + File: /usr/local/demo-ai/resources/check_camera_preview.sh + Msg_false: Camera is not connected + Start: ../demo-ai/image-classification/nbg/launch_bin_image_classification.sh + Action: + button_release_event: script_management + button_press_event: highlight_eventBox diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/Makefile b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/Makefile new file mode 100644 index 000000000..7ab7e1981 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/Makefile @@ -0,0 +1,29 @@ +OPENCV_PKGCONFIG?="opencv4" +SYSROOT?="" +TARGET_BIN = nbg_image_classification + +CXXFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0 $(OPENCV_PKGCONFIG) gstreamer-plugins-base-1.0 gstreamer-wayland-1.0) +CXXFLAGS += -std=c++17 + +LDFLAGS = $(shell pkg-config --libs gtk+-3.0 gstreamer-plugins-base-1.0 gstreamer-wayland-1.0) +LDFLAGS += -lpthread -ldl -lopencv_core -lopencv_imgproc -lopencv_imgcodecs +LDFLAGS += -L$(SYSROOT)/usr/lib -ljpeg -lovxlib -lOpenVX -lOpenVXU +LDFLAGS += -Wl,--no-as-needed + +ifeq ($(NEW_GST_WAYLAND_API), 1) + CXXFLAGS += -DNEW_GST_WAYLAND_API +endif + +SRCS = nbg_image_classification.cc vnn_utils.cc +OBJS = $(SRCS:.cc=.o) + +all: $(TARGET_BIN) + +$(TARGET_BIN): $(OBJS) + $(CXX) -o $@ $^ $(LDFLAGS) + +$(OBJS): $(SRCS) + $(CXX) $(CXXFLAGS) -c $^ + +clean: + rm -rf $(OBJS) $(TARGET_BIN) diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/launch_bin_image_classification.sh b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/launch_bin_image_classification.sh new file mode 100755 index 000000000..4a0c6813c --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/launch_bin_image_classification.sh @@ -0,0 +1,12 @@ +#!/bin/sh +weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}') + +source /usr/local/demo-ai/resources/config_board.sh +cmd="/usr/local/demo-ai/image-classification/nbg/nbg_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.nb -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL\_nbg.txt --framerate $DFPS --frame_width $DWIDTH --frame_height $DHEIGHT" + +if [ "$weston_user" != "root" ]; then + echo "user : "$weston_user + script -qc "su -l $weston_user -c '$cmd'" +else + $cmd +fi diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/launch_bin_image_classification_testdata.sh b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/launch_bin_image_classification_testdata.sh new file mode 100755 index 000000000..88601ceb5 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/launch_bin_image_classification_testdata.sh @@ -0,0 +1,12 @@ +#!/bin/sh +weston_user=$(ps aux | grep '/usr/bin/weston '|grep -v 'grep'|awk '{print $1}') + +source /usr/local/demo-ai/resources/config_board.sh +cmd="/usr/local/demo-ai/image-classification/nbg/nbg_image_classification -m /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_MODEL.nb -l /usr/local/demo-ai/image-classification/models/mobilenet/$IMAGE_CLASSIFICATION_LABEL\_nbg.txt -i /usr/local/demo-ai/image-classification/models/mobilenet/testdata/" + +if [ "$weston_user" != "root" ]; then + echo "user : "$weston_user + script -qc "su -l $weston_user -c '$cmd'" +else + $cmd +fi diff --git a/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/nbg_image_classification.cc b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/nbg_image_classification.cc new file mode 100644 index 000000000..5a7bd3739 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/stm32mpu-ai/recipes-samples/image-classification/files/nbg/nbg_image_classification.cc @@ -0,0 +1,1588 @@ +/* + * label_nbg_gst_gtk.cc + * + * This application demonstrate a computer vision use case for image + * classification where frames are grabbed from a camera input (/dev/videox) and + * analyzed by a neural network model interpreted by OpenVX stack. + * + * Gstreamer pipeline is used to stream camera frames (using v4l2src), to + * display a preview (using waylandsink) and to execute neural network inference + * (using appsink). + * + * The result of the inference is displayed on the preview. The overlay is done + * using GTK widget with cairo. + * + * This combination is quite simple and efficient in term of CPU consumption. + * + * Author: Alexis Brisson for STMicroelectronics. + * + * Copyright (c) 2020 STMicroelectronics. All rights reserved. + * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * + * http://www.opensource.org/licenses/BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef GDK_WINDOWING_WAYLAND +#include +#else +#error "Wayland is not supported in GTK+" +#endif + +#include "wrapper_nbg.hpp" + +/* Application parameters */ +std::vector dir_files; +std::string model_file_str; +std::string labels_file_str; +std::string image_dir_str; +std::string video_device_str = ""; +std::string camera_fps_str = "15"; +std::string camera_width_str = "640"; +std::string camera_height_str = "480"; +std::string val_run_str = "50"; + +bool crop = false; +bool verbose = false; +bool validation = false; + +float input_mean = 127.5f; +float input_std = 127.5f; +cv::Rect cropRect(0, 0, 0, 0); + +/* NBG variables */ +struct wrapper_nbg::NBG_Wrapper nbg_wrapper; +struct wrapper_nbg::Config config; +struct wrapper_nbg::Label_Results results; +std::vector labels; + +bool gtk_main_started = false; +bool exit_application = false; + +/* Ressource directory on board */ +#define RESOURCES_DIRECTORY "/usr/local/demo-ai/resources/" + +/* Structure that contains frame size/position on the screen*/ +typedef struct _FramePosition { + int x; + int y; + int width; + int height; +} FramePosition; + +/* Structure that contains all camera configuration information */ +typedef struct _Config_camera { + std::string video_device; + std::string camera_caps; + std::string dcmipp_sensor; +} Config_camera; + +/* Structure that contains all information to pass around */ +typedef struct _CustomData { + /* The gstreamer pipeline */ + GstElement *pipeline; + + /* The GTK window widget */ + GtkWidget *window_main; + GtkWidget *window_overlay; + + /* The drawing area where the camera stream is shown */ + GtkWidget *video; + GstVideoOverlay *video_overlay; + GtkAllocation video_allocation; + + /* Camera information */ + Config_camera camera_info; + + /* Text widget to display info about + * - either the display framerate, and the inference time + * - in fps or ms and the accuracy of the model + */ + GtkWidget *info_inf_time; + GtkWidget *overlay_draw; + GtkWidget *info_inf_time_main; + std::stringstream label_sstr; + + /* window resolution */ + int window_width; + int window_height; + + /* UI parameters (values will depends on display size) */ + int ui_cairo_font_size_label; + int ui_cairo_font_size; + int ui_icon_exit_width; + int ui_icon_exit_height; + int ui_icon_st_width; + int ui_icon_st_height; + double ui_box_line_width; + int ui_weston_panel_thickness; + + /* ST icon widget */ + GtkWidget *st_icon_main; + GtkWidget *st_icon_ov; + std::stringstream st_icon_sstr; + + /* exit icon widget */ + GtkWidget *exit_icon_main; + GtkWidget *exit_icon_ov; + std::stringstream exit_icon_sstr; + + /* Preview camera enable (else still picture use case) */ + bool preview_enabled; + + /* NN input size */ + int nn_input_width; + int nn_input_height; + + /* Frame resolution (still picture or camera) */ + int frame_width; + int frame_height; + + /* Frame resolution and scaling factor */ + float x_scale; + float y_scale; + + /* drawing area resolution */ + int widget_draw_width; + int widget_draw_height; + int offset; + + /* For validation purpose */ + int valid_timeout_id; + int valid_draw_count; + int val_run; + std::vector valid_inference_time; + std::string file; + + /* aspect ratio */ + FramePosition frame_disp_pos; + + /* Still picture variables */ + bool new_inference; + cv::Mat img_to_display; + + /* ISP configuration */ + int cpt_frame = 0; + +} CustomData; + +/* Framerate statistics */ +gdouble display_avg_fps = 0; + +/** + * This function is used to get the display resolution + */ +auto get_display_resolution(CustomData *data){ + std::stringstream cmd; + cmd << "modetest -M stm -c > /tmp/display_resolution.txt"; + system(cmd.str().c_str()); + std::string display_info_pattern = "#0"; + std::ifstream file("/tmp/display_resolution.txt"); + std::string display_information; + std::string display_resolution; + std::string display_width; + std::string display_height; + if (file.is_open()) { + std::string line; + while (std::getline(file, line)) { + int found_resolution = line.find(display_info_pattern); + if (found_resolution != -1) { + display_information = line.substr((found_resolution + display_info_pattern.length())); + } + } + file.close(); + } + system("rm -rf /tmp/display_resolution.txt"); + std::stringstream display_resolution_ss(display_information); + while(std::getline(display_resolution_ss, display_resolution, ' ')) { + int found = display_resolution.find("x"); + if (found != -1) { + display_width = display_resolution.substr(0,found); + display_height = display_resolution.substr(found + 1); + } + } + g_print("display resolution is : %s x %s \n",display_width.c_str(),display_height.c_str()); + data->window_width = std::stoi(display_width); + data->window_height = std::stoi(display_height); + return 0; +} + +/** + * This function is used to setup the camera depending on the + * parameters defined by the user + */ +auto setup_camera() { + std::stringstream config_camera; + config_camera << RESOURCES_DIRECTORY << "setup_camera.sh " << camera_width_str << " " << camera_height_str << " " << camera_fps_str << " " << video_device_str << " > /tmp/camera_device.txt"; + system(config_camera.str().c_str()); + std::string video_device_pattern = "V4L_DEVICE="; + std::string camera_caps_pattern = "V4L2_CAPS="; + std::string dcmipp_sensor_pattern = "DCMIPP_SENSOR="; + Config_camera camera_info; + std::ifstream file("/tmp/camera_device.txt"); + if (file.is_open()) { + std::string line; + while (std::getline(file, line)) { + int found_device = line.find(video_device_pattern); + if (found_device != -1) { + camera_info.video_device = line.substr((found_device + video_device_pattern.length())); + } + int found_camera = line.find(camera_caps_pattern); + if (found_camera != -1) { + camera_info.camera_caps = line.substr((found_camera + camera_caps_pattern.length())); + } + int found_dcmipp = line.find(dcmipp_sensor_pattern); + if (found_dcmipp != -1) { + camera_info.dcmipp_sensor = line.substr((found_dcmipp + dcmipp_sensor_pattern.length())); + } + } + file.close(); + } + system("rm -rf /tmp/camera_device.txt"); + return camera_info; +} + +/** + * This function is called to for updating ISP configuration + */ + +auto update_isp_config(CustomData *data) +{ + std::stringstream isp_file; + std::stringstream isp_config; + isp_file << "/usr/local/demo/application/camera/bin/isp"; + isp_config << isp_file.str().c_str() << " -w > /dev/null"; + std::ifstream file(isp_file.str().c_str()); + if (data->cpt_frame == 0 && file.good() && data->camera_info.dcmipp_sensor.compare("imx335") == 0 ){ + system(isp_config.str().c_str()); + } + return TRUE; +} + +/** + * This function is called when the ST icon image is clicked + */ +static gboolean st_icon_cb(GtkWidget *event_box, + GdkEventButton *event, + CustomData *data) +{ + if (!data->preview_enabled){ + g_print("ST icon clicked: new inference\n"); + data->new_inference = true; + } + return TRUE; +} + +/** + * This function is called when the exit icon image is clicked + */ + +static gboolean exit_icon_cb(GtkWidget *event_box, + GdkEventButton *event, + CustomData *data) +{ + g_print("Exit icon clicked: exit\n"); + gtk_main_quit(); + return TRUE; +} + +/** + * In validation mode this function is called when timeout occurs + * Exit application if this function is called + */ +gint valid_timeout_callback(gpointer data) +{ + /* If timeout occurs that means that camera preview and the gtk is not + * behaving as expected */ + g_print("Timeout: application is not behaving has expected\n"); + exit(1); +} + +/** + * This function execute an NN inference + */ +static void nn_inference(uint8_t *img) +{ + nbg_wrapper.RunInference(img, &results); +} + +/** + * This function is an helper to get frame position on the display + */ +static void compute_frame_position(CustomData *data) +{ + int window_width = data->widget_draw_width; + int window_height = data->widget_draw_height; + int offset_x = 0; + int offset_y = 0; + + float width_ratio = (float)window_width / (float)data->frame_width; + float height_ratio = (float)window_height / (float)data->frame_height; + + if (width_ratio > height_ratio) { + data->frame_disp_pos.width = (int)((float)data->frame_width * height_ratio); + data->frame_disp_pos.height = (int)((float)data->frame_height * height_ratio); + data->frame_disp_pos.x = (window_width - data->frame_disp_pos.width) / 2; + data->frame_disp_pos.y = offset_y; + } else { + data->frame_disp_pos.width = (int)((float)data->frame_width * width_ratio); + data->frame_disp_pos.height = (int)((float)data->frame_height * width_ratio); + data->frame_disp_pos.x = offset_x; + data->frame_disp_pos.y = (window_height - data->frame_disp_pos.height) / 2; + } +} + +/** + * This function get a file randomly in a directory + */ +static std::string get_files_in_directory_randomly(std::string directory) +{ + std::stringstream file_path_sstr; + /* Get the list of all the file ins the directory if the list of the + * file is empty */ + if (dir_files.size() == 0) { + DIR* dirp; + /* checking if the directory can be opened */ + if ((dirp = opendir(directory.c_str())) == NULL) { + g_printerr("Cannot open %s\n",directory.c_str()); + exit (1); + } + struct dirent * dp; + while ((dp = readdir(dirp)) != NULL) { + if ((strcmp(dp->d_name, ".") !=0) && + (strcmp(dp->d_name, "..") != 0)) + dir_files.push_back(dp->d_name); + } + closedir(dirp); + } + + /* Check if directory is empty */ + if (dir_files.size() == 0) + return ""; + + int random = rand() % dir_files.size(); + file_path_sstr << directory << dir_files[random]; + dir_files.erase(dir_files.begin() + random); + + return file_path_sstr.str(); +} + +/** + * This function is an idle function waiting for a new picture + * to be infered + */ +bool first_call_validation = true; +static gboolean infer_new_picture(CustomData *data) +{ + if (exit_application) { + gtk_main_quit(); + return FALSE; + } + + if (data->new_inference){ + /* Select a picture in the directory */ + data->file = get_files_in_directory_randomly(image_dir_str); + /* Check the read and right permission of the selected file */ + int ret = access(data->file.c_str(),R_OK); + if (ret != 0){ + g_printerr("Read permission denied to the file %s\n",data->file.c_str()); + exit(1); + } + + /* Read and format the picture */ + cv::Mat img_bgr, img_bgra, img_tdp, img_nn; + + img_bgr = cv::imread(data->file); + cv::cvtColor(img_bgr, img_bgra, cv::COLOR_BGR2BGRA); + data->frame_width = img_bgra.size().width; + data->frame_height = img_bgra.size().height; + compute_frame_position(data); + + /* Get final frame position and dimension and resize it */ + cv::Size size(data->frame_disp_pos.width,data->frame_disp_pos.height); + cv::resize(img_bgra, img_tdp , size); + data->img_to_display = img_tdp.clone(); + /* prepare the inference */ + cv::Size size_nn(data->nn_input_width, data->nn_input_height); + cv::resize(img_bgr, img_nn, size_nn); + cv::cvtColor(img_nn, img_nn, cv::COLOR_BGR2RGB); + + nn_inference(img_nn.data); + + std::stringstream label_sstr; + std::stringstream inference_fps_sstr; + std::stringstream inference_time_sstr; + std::stringstream accuracy_sstr; + label_sstr << labels[results.index[0]]; + + if (results.inference_time != 0) + { + inference_fps_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << (1000 / results.inference_time); + inference_fps_sstr << std::right << std::setw(3) << " fps "; + + inference_time_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << results.inference_time; + inference_time_sstr << std::right << std::setw(2) << " ms "; + + accuracy_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << results.accuracy[0] * 100; + accuracy_sstr << std::right << std::setw(1) << " % "; + } + + /* Update labels */ + std::stringstream info_sstr; + info_sstr << " inf.fps : " << "\n" << inference_fps_sstr.str().c_str() << "\n" << " inf.time : " << "\n" << inference_time_sstr.str().c_str() << "\n" <<" accuracy : " << "\n" << accuracy_sstr.str().c_str(); + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time),label_to_display); + g_free(label_to_display); + + if (validation) { + /* Still picture use case */ + if (first_call_validation){ + /* Skip the first inference time in hardware + * accelerated mode which is the warmup time + * The warmup time is far more important than + * classic inference time and will make average + * inference time completly false + * */ + first_call_validation = false; + } else { + data->valid_inference_time.push_back(results.inference_time); + } + /* Reload the timeout */ + g_source_remove(data->valid_timeout_id); + data->valid_timeout_id = g_timeout_add(10000, + valid_timeout_callback, + NULL); + /* Get the name of the file without extension and underscore */ + std::string file_name = std::filesystem::path(data->file).stem(); + file_name = file_name.substr(0, file_name.find('_')); + + /* Verify that the inference output result matches the file + * name. Else exit the application: validation is failing */ + std::cout << "name extract from the picture file: " + << std::left << std::setw(32) << file_name + << "label: " << label_sstr.str() << std::endl; + + if (file_name.find(label_sstr.str()) == std::string::npos){ + std::cout << "Inference result mismatch the file name\n"; + exit(5); + } + + /* Continue over all files */ + if (dir_files.size() == 0) { + auto avg_inf_time = std::accumulate(data->valid_inference_time.begin(), + data->valid_inference_time.end(), 0.0) / + data->valid_inference_time.size(); + std::cout << "\navg inference time= " << avg_inf_time << " ms\n"; + g_source_remove(data->valid_timeout_id); + gtk_widget_queue_draw(data->window_main); + gtk_widget_queue_draw(data->window_overlay); + exit_application = true; + } else { + data->new_inference = true; + } + } else { + data->new_inference = false; + } + /* Refresh main window and overlay */ + gtk_widget_queue_draw(data->window_overlay); + gtk_widget_queue_draw(data->window_main); + } + return TRUE; +} + +/** + * This function display text is a black stroke and a white fill color + */ +void gui_display_outlined_text(cairo_t *cr, + const char* text) +{ + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_text_path(cr, text); + cairo_fill_preserve(cr); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + cairo_set_line_width(cr, 0.5); + cairo_stroke(cr); +} + +/** + * This function is used to load the CSS file for UI configuration + */ +static void gui_gtk_style(CustomData *data) +{ + std::stringstream css_sstr; + css_sstr << RESOURCES_DIRECTORY; + css_sstr << "Default.css"; + + /* checking the reading permission of the file */ + int ret = access(css_sstr.str().c_str(),R_OK); + if (ret != 0){ + g_printerr("Read permission denied to the file %s\n",css_sstr.str().c_str()); + exit(1); + } + GtkCssProvider *cssProvider = gtk_css_provider_new(); + gtk_css_provider_load_from_path (cssProvider, + css_sstr.str().c_str(), + NULL); + gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), + GTK_STYLE_PROVIDER(cssProvider), + GTK_STYLE_PROVIDER_PRIORITY_USER); +} + +/** + * This function is an helper to set UI variable according to the display size + */ +static void gui_set_ui_parameters(CustomData *data) +{ + + int window_constraint = 0; + if (data->window_height > data->window_width) + window_constraint = data->window_width; + else + window_constraint = data->window_height; + + if (window_constraint <= 272) { + /* Display 480x272 */ + g_print("Display config <= 272p \n"); + data->ui_cairo_font_size_label = 15; + data->ui_cairo_font_size = 10; + data->ui_icon_exit_width = 25; + data->ui_icon_exit_height = 25; + data->ui_icon_st_width = 42; + data->ui_icon_st_height = 52; + } else if (window_constraint <= 600) { + /* Display 800x480 */ + /* Display 1024x600 */ + g_print("Display config <= 600p \n"); + data->ui_cairo_font_size_label = 26; + data->ui_cairo_font_size = 16; + data->ui_icon_exit_width = 50; + data->ui_icon_exit_height = 50; + data->ui_icon_st_width = 65; + data->ui_icon_st_height = 80; + } else if (window_constraint <= 720) { + /* Display 1280x720 */ + g_print("Display config <= 720p \n"); + data->ui_cairo_font_size = 20; + data->ui_cairo_font_size_label = 35; + data->ui_icon_exit_width = 50; + data->ui_icon_exit_height = 50; + data->ui_icon_st_width = 130; + data->ui_icon_st_height = 160; + } else if (window_constraint <= 1080) { + /* Display 1920x1080 */ + g_print("Display config <= 1080p \n"); + data->ui_cairo_font_size_label = 45; + data->ui_cairo_font_size = 30; + data->ui_icon_exit_width = 50; + data->ui_icon_exit_height = 50; + data->ui_icon_st_width = 130; + data->ui_icon_st_height = 160; + } else { + /* Default UI parameter */ + g_print("Display config fallback \n"); + data->ui_icon_exit_width = 50; + data->ui_icon_exit_height = 50; + data->ui_icon_st_width = 130; + data->ui_icon_st_height = 160; + data->ui_cairo_font_size = 20; + data->ui_cairo_font_size_label = 35; + } +} + +/** + * This function is an helper to set UI icons sizes according to the display size + */ +static void gui_set_icons_parameters(CustomData *data) +{ + /* set the icons */ + data->st_icon_sstr << RESOURCES_DIRECTORY << "nbg_st_icon_"; + + if (!data->preview_enabled) + data->st_icon_sstr << "next_inference_"; + data->st_icon_sstr << data->ui_icon_st_width << "x" << data->ui_icon_st_height << ".png"; + + /* checking the reading permission of the file */ + int ret = access(data->st_icon_sstr.str().c_str(),R_OK); + if (ret != 0){ + g_printerr("Read permission denied to the file %s\n",data->st_icon_sstr.str().c_str()); + exit(1); + } + + data->exit_icon_sstr << RESOURCES_DIRECTORY << "exit_"; + data->exit_icon_sstr << data->ui_icon_exit_width << "x" << data->ui_icon_exit_height << ".png"; + + /* checking the reading permission of the file */ + ret = access(data->exit_icon_sstr.str().c_str(),R_OK); + if (ret != 0){ + g_printerr("Read permission denied to the file %s\n",data->exit_icon_sstr.str().c_str()); + exit(1); + } +} + +/** + * This function is called each time the GTK UI is redrawn + */ +bool first_call_overlay = true; +static gboolean gui_draw_overlay_cb(GtkWidget *widget, + cairo_t *cr, + CustomData *data) +{ + /* Get drawing area informations */ + int draw_width = gtk_widget_get_allocated_width(widget); + int draw_height= gtk_widget_get_allocated_height(widget); + + /* Updating the information with the new inference results */ + std::stringstream display_fps_sstr; + std::stringstream inference_time_sstr; + std::stringstream inference_fps_sstr; + std::stringstream accuracy_sstr; + float inf_time = 0; + + if (results.inference_time != 0) + { + /* Updating the information with the new inference results */ + display_fps_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << display_avg_fps; + display_fps_sstr << std::right << std::setw(3) << " fps "; + + inference_fps_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << (1000 / results.inference_time); + inference_fps_sstr << std::right << std::setw(3) << " fps "; + + inference_time_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << results.inference_time; + inference_time_sstr << std::right << std::setw(2) << " ms "; + + accuracy_sstr << std::right << std::setw(5) << std::fixed << std::setprecision(1) << results.accuracy[0] * 100; + accuracy_sstr << std::right << std::setw(1) << " % "; + } + + /* set the font and the size for the label*/ + cairo_select_font_face (cr, "monospace", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (cr, data->ui_cairo_font_size_label); + + /* Update the gtk labels with latest information */ + if (data->preview_enabled) { + /* Camera preview use case */ + if (first_call_overlay){ + first_call_overlay = false; + return FALSE; + } else { + /* Update labels */ + std::stringstream info_sstr; + info_sstr << " disp.fps : " << "\n" << display_fps_sstr.str().c_str() << "\n" << " inf.fps : " << "\n" << inference_fps_sstr.str().c_str() << "\n" << " inf.time : " << "\n" << inference_time_sstr.str().c_str() << "\n" <<" accuracy : " << "\n" << accuracy_sstr.str().c_str(); + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time),label_to_display); + g_free(label_to_display); + } + if(exit_application) + gtk_main_quit(); + } else { + /* Still picture use case */ + if (first_call_overlay){ + first_call_overlay = false; + /* add the inference function in idlle after the initialization of + * the GUI */ + g_idle_add((GSourceFunc)infer_new_picture,data); + data->new_inference = true; + return FALSE; + } else { + /* Update labels */ + std::stringstream info_sstr; + info_sstr << " inf.fps : " << "\n" << inference_fps_sstr.str().c_str() << "\n" << " inf.time : " << "\n" << inference_time_sstr.str().c_str() << "\n" <<" accuracy : " << "\n" << accuracy_sstr.str().c_str(); + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time),label_to_display); + g_free(label_to_display); + } + } + + /* Display the label centered in the preview area */ + std::stringstream label_sstr; + cairo_text_extents_t extents; + double x, y; + label_sstr << labels[results.index[0]]; + if (!data->preview_enabled) { + draw_width = data->widget_draw_width; + draw_height= data->widget_draw_height; + } + + cairo_text_extents(cr, label_sstr.str().c_str(), &extents); + x = (draw_width/ 2) - ((extents.width / 2) + extents.x_bearing); + y = draw_height + (extents.y_bearing / 2); + cairo_move_to(cr, x, y); + gui_display_outlined_text(cr, label_sstr.str().c_str()); + cairo_fill (cr); + + /* Validation mode */ + if(validation){ + if (data->preview_enabled) { + if (data->valid_draw_count < 5){ + g_source_remove(data->valid_timeout_id); + data->valid_timeout_id = g_timeout_add(100000, + valid_timeout_callback, + NULL); + data->valid_draw_count++; + } else { + data->valid_inference_time.push_back(results.inference_time); + /* Reload the timeout */ + g_source_remove(data->valid_timeout_id); + data->valid_timeout_id = g_timeout_add(100000, + valid_timeout_callback, + NULL); + data->valid_draw_count++; + if (data->valid_draw_count > data->val_run) { + auto avg_inf_time = std::accumulate(data->valid_inference_time.begin(), + data->valid_inference_time.end(), 0.0) / + data->valid_inference_time.size(); + /* Stop the timeout and properly exit the + * application */ + std::cout << "avg display fps= " << display_avg_fps << std::endl; + std::cout << "avg inference fps= " << (1000 / avg_inf_time) << std::endl; + std::cout << "avg inference time= " << avg_inf_time << std::endl; + g_source_remove(data->valid_timeout_id); + gtk_main_quit(); + } + } + } + } + return TRUE; +} +/** + * This function is creating GTK widget to create the window to overlay UI + * information + */ +static void gui_create_overlay(CustomData *data) +{ + /*Gtk Widget used for the window */ + GtkWidget *main_box; + GtkWidget *drawing_box; + GtkWidget *drawing_area; + GtkWidget *still_pict_draw; + GtkWidget *info_box; + GtkWidget *exit_box; + GtkWidget *st_icon_event_box; + GtkWidget *exit_icon_event_box; + + /* Create the window */ + data->window_overlay = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_app_paintable(data->window_overlay, TRUE); + g_signal_connect(G_OBJECT(data->window_overlay), "delete-event", + G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(G_OBJECT(data->window_overlay), "destroy", + G_CALLBACK(gtk_main_quit), NULL); + + /* Remove title bar */ + gtk_window_set_decorated(GTK_WINDOW(data->window_overlay), FALSE); + + /* Maximize the window size */ + gtk_window_maximize(GTK_WINDOW(data->window_overlay)); + + /* Create the ST icon widget */ + data->st_icon_ov = gtk_image_new(); + st_icon_event_box = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(st_icon_event_box), data->st_icon_ov); + g_signal_connect(G_OBJECT(st_icon_event_box),"button_press_event",G_CALLBACK(st_icon_cb), data); + + /* Create the exit icon widget */ + data->exit_icon_ov = gtk_image_new(); + exit_icon_event_box = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(exit_icon_event_box), data->exit_icon_ov); + g_signal_connect(G_OBJECT(exit_icon_event_box),"button_press_event",G_CALLBACK(exit_icon_cb), data); + + gtk_image_set_from_file(GTK_IMAGE(data->st_icon_ov), data->st_icon_sstr.str().c_str()); + gtk_image_set_from_file(GTK_IMAGE(data->exit_icon_ov), data->exit_icon_sstr.str().c_str()); + + if (data->preview_enabled) { + /* Camera preview use case */ + /* Create the drawing area to draw text on it using cairo */ + drawing_area = gtk_drawing_area_new(); + gtk_widget_set_app_paintable(drawing_area, TRUE); + g_signal_connect(G_OBJECT(drawing_area), "draw", + G_CALLBACK(gui_draw_overlay_cb), data); + + data->info_inf_time = gtk_label_new(NULL); + gtk_label_set_justify(GTK_LABEL(data->info_inf_time),GTK_JUSTIFY_CENTER); + /* initialize labels */ + std::stringstream info_sstr; + info_sstr << " disp.fps : " << "\n" << " inf.fps : " << "\n" << " inf.time : " << "\n" <<" accuracy : " << "\n"; + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time),label_to_display); + g_free(label_to_display); + + } else { + /* Still picture use case */ + /* Create the video widget */ + still_pict_draw = gtk_drawing_area_new(); + gtk_widget_set_app_paintable(still_pict_draw, TRUE); + g_signal_connect(still_pict_draw, "draw", + G_CALLBACK(gui_draw_overlay_cb), data); + + data->info_inf_time = gtk_label_new(NULL); + gtk_label_set_justify(GTK_LABEL(data->info_inf_time),GTK_JUSTIFY_CENTER); + /* initialize labels */ + std::stringstream info_sstr; + info_sstr << " inf.fps : " << "\n" << " inf.time : " << "\n" <<" accuracy : " << "\n"; + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time),label_to_display); + g_free(label_to_display); + } + + /* Set the boxes */ + info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_name(info_box , "gui_overlay_stbox"); + if (data->preview_enabled){ + /* Camera preview use case */ + gtk_box_pack_start(GTK_BOX(info_box), st_icon_event_box, FALSE, FALSE, 4); + gtk_box_pack_start(GTK_BOX(info_box), data->info_inf_time, FALSE, FALSE, 4); + + } else { + /* Still picture use case */ + gtk_box_pack_start(GTK_BOX(info_box), st_icon_event_box, FALSE, FALSE, 4); + gtk_box_pack_start(GTK_BOX(info_box), data->info_inf_time, FALSE, FALSE, 4); + + } + + drawing_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_name(drawing_box, "gui_overlay_draw"); + if (data->preview_enabled){ + /* Camera preview use case */ + gtk_box_pack_start(GTK_BOX(drawing_box), drawing_area, TRUE, TRUE, 0); + } else { + /* Still picture use case */ + gtk_box_pack_start(GTK_BOX(drawing_box), still_pict_draw, TRUE, TRUE, 0); + } + + exit_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_name(exit_box , "gui_overlay_exit"); + gtk_box_pack_start(GTK_BOX(exit_box), exit_icon_event_box, FALSE, FALSE, 2); + + main_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_name(main_box, "gui_overlay"); + gtk_box_pack_start(GTK_BOX(main_box), info_box, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(main_box), drawing_box, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(main_box), exit_box , FALSE, FALSE, 2); + + /* Push the UI into the window_overlay */ + gtk_container_add(GTK_CONTAINER(data->window_overlay), main_box); + gtk_widget_show_all(data->window_overlay); +} + +static gboolean gui_draw_main_cb(GtkWidget *widget, + cairo_t *cr, + CustomData *data) +{ + int offset = 0; + if (data->preview_enabled) { + /* Camera preview use case */ + data->widget_draw_width = gtk_widget_get_allocated_width(widget); + data->widget_draw_height= gtk_widget_get_allocated_height(widget); + } else { + /* Still picture use case */ + data->widget_draw_width = gtk_widget_get_allocated_width(widget); + data->widget_draw_height = gtk_widget_get_allocated_height(widget); + data->offset = (data->widget_draw_width - data->frame_disp_pos.width)/2; + + if(data->img_to_display.data){ + /* Display the resized picture */ + /* Generate the cairo surface */ + int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, + data->frame_disp_pos.width); + + cairo_surface_t *picture = cairo_image_surface_create_for_data(data->img_to_display.data, + CAIRO_FORMAT_RGB24, + data->frame_disp_pos.width, + data->frame_disp_pos.height, + stride); + cairo_set_source_surface(cr,picture,data->offset,0); + cairo_paint(cr); + cairo_surface_destroy(picture); + } else { + /* Set the black background */ + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_paint(cr); + data->new_inference = true; + } + } + return FALSE; +} + +/** + * This function is creating GTK widget to create the main window use to render + * the preview. + * Title label are also used in the main window in order to create boxes with + * sizes that match the label width. + */ +static void gui_create_main(CustomData *data) +{ + /*Gtk Widget used for the window */ + GtkWidget *main_box; + GtkWidget *video_box; + GtkWidget *still_pict_draw; + GtkWidget *overlay; + GtkWidget *info_box; + GtkWidget *exit_box; + GtkWidget *st_icon_event_box; + GtkWidget *exit_icon_event_box; + + /* Create the window */ + data->window_main = gtk_window_new(GTK_WINDOW_TOPLEVEL); + /* Remove title bar */ + gtk_window_set_decorated(GTK_WINDOW(data->window_main), FALSE); + + /* Maximize the window size */ + gtk_window_maximize(GTK_WINDOW(data->window_main)); + + gtk_widget_set_app_paintable(data->window_main, TRUE); + g_signal_connect(G_OBJECT(data->window_main), "delete-event",G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(G_OBJECT(data->window_main), "destroy",G_CALLBACK(gtk_main_quit), NULL); + + /* Create the ST icon widget */ + data->st_icon_main = gtk_image_new(); + st_icon_event_box = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(st_icon_event_box), data->st_icon_main); + g_signal_connect(G_OBJECT(st_icon_event_box),"button_press_event",G_CALLBACK(st_icon_cb), data); + + /* Create the exit icon widget */ + data->exit_icon_main = gtk_image_new(); + exit_icon_event_box = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(exit_icon_event_box), data->exit_icon_main); + g_signal_connect(G_OBJECT(exit_icon_event_box),"button_press_event",G_CALLBACK(exit_icon_cb), data); + + gtk_image_set_from_file(GTK_IMAGE(data->st_icon_main), data->st_icon_sstr.str().c_str()); + gtk_image_set_from_file(GTK_IMAGE(data->exit_icon_main), data->exit_icon_sstr.str().c_str()); + + data->overlay_draw = gtk_drawing_area_new(); + gtk_widget_set_app_paintable(data->overlay_draw, TRUE); + if (data->preview_enabled) { + g_signal_connect(data->overlay_draw, "draw",G_CALLBACK(gui_draw_main_cb), data); + } + if (data->preview_enabled) { + /* Camera preview use case */ + /* Create the video widget */ + GstElement *sink = gst_bin_get_by_name (GST_BIN (data->pipeline), "gtkwsink"); + if (!sink && !g_strcmp0 (G_OBJECT_TYPE_NAME (data->pipeline), "GstPlayBin")) { + g_object_get (data->pipeline, "video-sink", &sink, NULL); + if (sink && g_strcmp0 (G_OBJECT_TYPE_NAME (sink), "GstGtkWaylandSink") != 0 + && GST_IS_BIN (sink)) { + GstBin *sinkbin = GST_BIN (sink); + sink = gst_bin_get_by_name (sinkbin, "gtkwsink"); + gst_object_unref (sinkbin); + } + } + g_assert (sink); + g_assert (!g_strcmp0 (G_OBJECT_TYPE_NAME (sink), "GstGtkWaylandSink")); + g_object_get (sink, "widget", &data->video, NULL); + gtk_widget_set_app_paintable(GTK_WIDGET(data->video), TRUE); + + data->info_inf_time_main = gtk_label_new(NULL); + gtk_label_set_justify(GTK_LABEL(data->info_inf_time_main),GTK_JUSTIFY_CENTER); + /* initialize labels */ + std::stringstream info_sstr; + info_sstr << " disp.fps : " << "\n" << " inf.fps : " << "\n" << " inf.time : " << "\n" << " accuracy : " << "\n"; + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time_main),label_to_display); + g_free(label_to_display); + + } else { + /* Still picture preview use case */ + /* Create the drawing widget */ + still_pict_draw = gtk_drawing_area_new(); + gtk_widget_set_app_paintable(still_pict_draw, TRUE); + g_signal_connect(still_pict_draw, "draw", + G_CALLBACK(gui_draw_main_cb), data); + + data->info_inf_time_main = gtk_label_new(NULL); + gtk_label_set_justify(GTK_LABEL(data->info_inf_time_main),GTK_JUSTIFY_CENTER); + /* initialize labels */ + std::stringstream info_sstr; + info_sstr << " inf.fps : " << "\n" << " inf.time : " << "\n" << " accuracy : " << "\n"; + char *label_to_display = g_strdup_printf ("""%s\n""",data->ui_cairo_font_size,info_sstr.str().c_str()); + gtk_label_set_markup(GTK_LABEL(data->info_inf_time_main),label_to_display); + g_free(label_to_display); + } + /* Set the boxes */ + info_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_name(info_box, "gui_main_stbox"); + if (data->preview_enabled){ + /* Camera preview use case */ + gtk_box_pack_start(GTK_BOX(info_box), st_icon_event_box, FALSE, FALSE, 4); + gtk_box_pack_start(GTK_BOX(info_box), data->info_inf_time_main, TRUE, FALSE, 4); + } else { + /* Still picture use case */ + gtk_box_pack_start(GTK_BOX(info_box), st_icon_event_box, FALSE, FALSE, 4); + gtk_box_pack_start(GTK_BOX(info_box), data->info_inf_time_main, TRUE, FALSE, 4); + } + video_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_app_paintable(GTK_WIDGET(video_box), TRUE); + gtk_widget_set_name(video_box, "gui_main_video"); + if (data->preview_enabled){ + /* Camera preview use case */ + gtk_box_pack_start(GTK_BOX(video_box), GTK_WIDGET(data->video), TRUE, TRUE, 0); + } else { + /* Still picture use case */ + gtk_box_pack_start(GTK_BOX(video_box), still_pict_draw, TRUE, TRUE, 0); + } + exit_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_name(exit_box, "gui_main_exit"); + gtk_box_pack_start(GTK_BOX(exit_box), exit_icon_event_box, FALSE, FALSE, 2); + + main_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_app_paintable(GTK_WIDGET(main_box), TRUE); + gtk_widget_set_name(main_box, "gui_main"); + gtk_box_pack_start(GTK_BOX(main_box), info_box, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(main_box), video_box, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX(main_box), exit_box, FALSE, FALSE, 2); + + overlay = gtk_overlay_new(); + gtk_container_add(GTK_CONTAINER(overlay),main_box); + gtk_overlay_add_overlay(GTK_OVERLAY(overlay), data->overlay_draw); + gtk_container_add(GTK_CONTAINER(data->window_main),overlay); + gtk_widget_show_all(data->window_main); +} + +/** + * This function is called when appsink Gstreamer element receives a buffer + */ +static GstFlowReturn gst_new_sample_cb(GstElement *sink, CustomData *data) +{ + GstSample *sample; + GstBuffer *app_buffer, *buffer; + GstMapInfo info; + + /* Retrieve the buffer */ + g_signal_emit_by_name (sink, "pull-sample", &sample); + if (sample) { + + update_isp_config(data); + data->cpt_frame += 1; + if (data->cpt_frame == 30) + data->cpt_frame = 0; + + buffer = gst_sample_get_buffer (sample); + + /* Make a copy */ + app_buffer = gst_buffer_ref (buffer); + + gst_buffer_map(app_buffer, &info, GST_MAP_READ); + + /* Execute the inference */ + nn_inference(info.data); + + gst_buffer_unmap(app_buffer, &info); + gst_buffer_unref (app_buffer); + + /* We don't need the appsink sample anymore */ + gst_sample_unref (sample); + + /* Call application callback only in playing state */ + gst_element_post_message(sink, + gst_message_new_application(GST_OBJECT(sink), + gst_structure_new_empty("inference-done"))); + return GST_FLOW_OK; + } + return GST_FLOW_ERROR; +} + +/** + * This function is called by Gstreamer fpsdisplaysink to get fps measurment + * of display + */ +void gst_fps_measure_display_cb(GstElement *fpsdisplaysink, + gdouble fps, + gdouble droprate, + gdouble avgfps, + gpointer data) +{ + display_avg_fps = avgfps; +} + +/** + * This function is called when a Gstreamer error message is posted on the bus. + */ +static void gst_error_cb (GstBus *bus, GstMessage *msg, CustomData *data) +{ + GError *err; + gchar *debug_info; + + /* Print error details on the screen */ + gst_message_parse_error (msg, &err, &debug_info); + g_printerr("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); + g_printerr("Debugging information: %s\n", debug_info ? debug_info : "none"); + g_clear_error(&err); + g_free(debug_info); + + /* Set the pipeline to READY (which stops camera streaming) */ + gst_element_set_state(data->pipeline, GST_STATE_READY); +} + +/** + * This function is called when a Gstreamer End-Of-Stream message is posted on + * the bus. We just set the pipeline to READY (which stops camera streaming). + */ +static void gst_eos_cb (GstBus *bus, GstMessage *msg, CustomData *data) +{ + g_print("End-Of-Stream reached.\n"); + gst_element_set_state(data->pipeline, GST_STATE_READY); +} + +static void gst_state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) { + GstState oldState; + GstState newState; + gst_message_parse_state_changed(msg, &oldState, &newState, 0); + if (newState == GST_STATE_PLAYING && oldState == GST_STATE_PAUSED) { + gst_debug_bin_to_dot_file(GST_BIN(data->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline_cpp_PAUSED_PLAYING"); + } +} + +/** + * This function is called when a Gstreamer "application" message is posted on + * the bus. + * Here we retrieve the message posted by the appsink gst_new_sample_cb callback. + */ +static void gst_application_cb (GstBus *bus, GstMessage *msg, CustomData *data) +{ + if (g_strcmp0(gst_structure_get_name(gst_message_get_structure(msg)), "inference-done") == 0) { + /* If the message is the "inference-done", update the GTK UI */ + gtk_widget_queue_draw(data->window_overlay); + } +} + +/** + * Construct the Gstreamer pipeline used to stream camera frame and to run + * TensorFlow Lite inference engine using appsink. + */ +static int gst_pipeline_camera_creation(CustomData *data) +{ + GstStateChangeReturn ret; + GstElement *pipeline, *source, *dispsink, *tee, *scale, *framerate; + GstElement *queue1, *queue2, *convert, *convert2, *appsink, *framecrop; + GstElement *fpsmeasure1; + GstBus *bus; + + /* Create the pipeline */ + pipeline = gst_pipeline_new("Image classification live camera"); + data->pipeline = pipeline; + + /* Create gstreamer elements */ + source = gst_element_factory_make_full("v4l2src","name","camera-source","io-mode",0,NULL); + tee = gst_element_factory_make("tee", "frame-tee"); + queue1 = gst_element_factory_make("queue", "queue-1"); + queue2 = gst_element_factory_make("queue", "queue-2"); + convert = gst_element_factory_make("videoconvert", "video-convert"); + convert2 = gst_element_factory_make("videoconvert", "video-convert-wayland"); + framecrop = gst_element_factory_make("videocrop", "videocrop"); + scale = gst_element_factory_make("videoscale", "videoscale"); + dispsink = gst_element_factory_make_full("gtkwaylandsink", "name", "gtkwsink", "drm-device",NULL,NULL); + appsink = gst_element_factory_make("appsink", "app-sink"); + framerate = gst_element_factory_make("videorate", "video-rate"); + fpsmeasure1 = gst_element_factory_make("fpsdisplaysink", "fps-measure1"); + + if (!pipeline || !source || !tee || !queue1 || !queue2 || !convert || !convert2 || + !scale || !dispsink || !appsink || !framerate || !fpsmeasure1 || !framecrop) { + g_printerr("One element could not be created. Exiting.\n"); + return -1; + } + + /* Configure the source element */ + std::stringstream device_sstr; + device_sstr << "/dev/" << data->camera_info.video_device; + g_object_set(G_OBJECT(source), "device", device_sstr.str().c_str(), NULL); + + g_print("video sink used : gtkwaylandsink \n"); + + /* Configure the queue elements */ + g_object_set(G_OBJECT(queue1), "max-size-buffers", 1, "leaky", 2 /* downstream */, NULL); + g_object_set(G_OBJECT(queue2), "max-size-buffers", 1, "leaky", 2 /* downstream */, NULL); + + /* Create caps based on application parameters */ + std::stringstream sourceCaps_sstr; + sourceCaps_sstr << data->camera_info.camera_caps << ",framerate=" << camera_fps_str << "/1"; + g_print("camera pipeline configuration : %s \n",sourceCaps_sstr.str().c_str()); + GstCaps *sourceCaps = gst_caps_from_string(sourceCaps_sstr.str().c_str()); + std::stringstream scaleCaps_sstr; + scaleCaps_sstr << "video/x-raw,format=RGB,width=" << data->nn_input_width << ",height=" << data->nn_input_height; + GstCaps *scaleCaps = gst_caps_from_string(scaleCaps_sstr.str().c_str()); + + /* Configure fspdisplaysink */ + g_object_set(fpsmeasure1, "signal-fps-measurements", TRUE, + "fps-update-interval", 2000, "text-overlay", FALSE, + "video-sink", dispsink, NULL); + g_signal_connect(fpsmeasure1, "fps-measurements", G_CALLBACK(gst_fps_measure_display_cb), NULL); + + /* Configure the videocrop */ + if (crop) { + /* Crop requested */ + int left = cropRect.x; + int right = data->frame_width - left - cropRect.width; + int top = cropRect.y; + int bottom = data->frame_height - top - cropRect.height; + g_object_set(framecrop, "left", left, "right", right, + "top", top, "bottom", bottom, NULL); + } else { + /* No crop requested */ + g_object_set(framecrop, "left", 0, "right", 0, + "top", 0, "bottom", 0, NULL); + } + + /* Configure appsink */ + g_object_set(appsink, "emit-signals", TRUE, "sync", FALSE, + "max-buffers", 1, "drop", TRUE, "caps", scaleCaps, NULL); + g_signal_connect(appsink, "new-sample", G_CALLBACK(gst_new_sample_cb), data); + + /* Add all elements into the pipeline */ + gst_bin_add_many(GST_BIN(pipeline), + source, framerate, tee, convert, convert2, queue1, queue2, scale, + framecrop, fpsmeasure1, appsink, NULL); + + /* Link the elements together */ + if (!gst_element_link_many(source, framerate, NULL)) { + g_error("Failed to link elements (1)"); + return -2; + } + if (!gst_element_link_filtered(framerate, tee, sourceCaps)) { + g_error("Failed to link elements (2)"); + return -2; + } + if (!gst_element_link_many(tee, queue2, convert, framecrop, scale, appsink, NULL)) { + g_error("Failed to link elements (3)"); + return -2; + } + if (!gst_element_link_many(tee, queue1, convert2, fpsmeasure1, NULL)) { + g_error("Failed to link elements (4)"); + return -2; + } + + gst_caps_unref(sourceCaps); + gst_caps_unref(scaleCaps); + + /* Instruct the bus to emit signals for each received message, and + * connect to the interesting signals */ + bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); + gst_bus_add_signal_watch(bus); + g_signal_connect(G_OBJECT(bus), "message::error", (GCallback)gst_error_cb, data); + g_signal_connect(G_OBJECT(bus), "message::eos", (GCallback)gst_eos_cb, data); + g_signal_connect(G_OBJECT(bus), "message::application", (GCallback)gst_application_cb, data); + g_signal_connect(G_OBJECT(bus), "message::state-changed", (GCallback)gst_state_changed_cb, data); + gst_object_unref(bus); + return 0; +} + +/** + * This function display the help when -h or --help is passed as parameter. + */ +static void print_help(int argc, char** argv) +{ + std::cout << + "Usage: " << argv[0] << " -m -l