From aa3a8740078d257a577c63ea7dc9494e615c5348 Mon Sep 17 00:00:00 2001 From: Christophe Priouzeau Date: Mon, 20 Feb 2023 10:34:28 +0100 Subject: [PATCH] LINUX-STM32MP: v6.1-stm32mp-r1 Change-Id: If47ceaa7d9ebee4efdaa45957f4101ad0db51e64 Signed-off-by: Romuald Jeanne --- classes/archiver_stm32mp_clean.bbclass | 2 +- recipes-kernel/linux/linux-stm32mp.inc | 37 +- .../0001-v5.15-stm32mp-r2-MACHINE.patch | 124 - .../5.15.67/0002-v5.15-stm32mp-r2-CLOCK.patch | 7300 ------- .../5.15.67/0006-v5.15-stm32mp-r2-DMA.patch | 2097 -- .../5.15.67/0007-v5.15-stm32mp-r2-DRM.patch | 2950 --- ...10-v5.15-stm32mp-r2-REMOTEPROC-RPMSG.patch | 6441 ------ .../5.15.67/0013-v5.15-stm32mp-r2-MMC.patch | 341 - .../0014-v5.15-stm32mp-r2-NET-TTY.patch | 2398 --- .../0016-v5.15-stm32mp-r2-PHY-USB.patch | 2588 --- .../5.15.67/0019-v5.15-stm32mp-r2-SCMI.patch | 1045 - .../0021-v5.15-stm32mp-r2-DEVICETREE.patch | 11345 ---------- .../6.1/6.1.28/0001-v6.1-stm32mp-r1-BUS.patch | 412 + .../6.1.28/0002-v6.1-stm32mp-r1-CLOCK.patch | 3304 +++ .../0003-v6.1-stm32mp-r1-CPUFREQ.patch} | 121 +- .../0004-v6.1-stm32mp-r1-CPUIDLE-POWER.patch} | 24 +- .../6.1.28/0005-v6.1-stm32mp-r1-CRYPTO.patch} | 1619 +- .../6.1/6.1.28/0006-v6.1-stm32mp-r1-DMA.patch | 28 + .../6.1/6.1.28/0007-v6.1-stm32mp-r1-DRM.patch | 1427 ++ .../0008-v6.1-stm32mp-r1-HWSPINLOCK.patch} | 198 +- ...009-v6.1-stm32mp-r1-I2C-IIO-IRQCHIP.patch} | 2172 +- ...010-v6.1-stm32mp-r1-REMOTEPROC-RPMSG.patch | 3661 ++++ ...1-v6.1-stm32mp-r1-MEDIA-SOC-THERMAL.patch} | 5747 +++--- .../6.1.28/0012-v6.1-stm32mp-r1-MFD.patch} | 229 +- .../6.1/6.1.28/0013-v6.1-stm32mp-r1-MMC.patch | 254 + .../6.1.28/0014-v6.1-stm32mp-r1-NET-TTY.patch | 1993 ++ .../6.1.28/0015-v6.1-stm32mp-r1-PERF.patch} | 84 +- .../6.1.28/0016-v6.1-stm32mp-r1-PHY-USB.patch | 692 + ....1-stm32mp-r1-PINCTRL-REGULATOR-SPI.patch} | 1830 +- .../0018-v6.1-stm32mp-r1-RESET-RTC.patch} | 308 +- .../6.1.28/0019-v6.1-stm32mp-r1-SCMI.patch | 724 + .../6.1.28/0020-v6.1-stm32mp-r1-SOUND.patch} | 178 +- .../6.1.28/0021-v6.1-stm32mp-r1-MISC.patch | 1089 + .../6.1.28/0022-v6.1-stm32mp-r1-MACHINE.patch | 26 + .../0023-v6.1-stm32mp-r1-DEVICETREE.patch | 17112 ++++++++++++++++ .../6.1.28/0024-v6.1-stm32mp-r1-CONFIG.patch} | 1101 +- .../{5.15 => 6.1}/fragment-03-systemd.config | 0 .../{5.15 => 6.1}/fragment-04-modules.config | 12 +- .../optional-fragment-05-signature.config} | 0 .../optional-fragment-06-nosmp.config} | 0 .../6.1/optional-fragment-07-efi.config | 13 + .../linux/linux-stm32mp/README.HOW_TO.txt | 114 +- recipes-kernel/linux/linux-stm32mp_5.15.bb | 101 - recipes-kernel/linux/linux-stm32mp_6.1.bb | 109 + 44 files changed, 36093 insertions(+), 45257 deletions(-) delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0001-v5.15-stm32mp-r2-MACHINE.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0002-v5.15-stm32mp-r2-CLOCK.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0006-v5.15-stm32mp-r2-DMA.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0007-v5.15-stm32mp-r2-DRM.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0010-v5.15-stm32mp-r2-REMOTEPROC-RPMSG.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0013-v5.15-stm32mp-r2-MMC.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0014-v5.15-stm32mp-r2-NET-TTY.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0016-v5.15-stm32mp-r2-PHY-USB.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0019-v5.15-stm32mp-r2-SCMI.patch delete mode 100644 recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0021-v5.15-stm32mp-r2-DEVICETREE.patch create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0001-v6.1-stm32mp-r1-BUS.patch create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0002-v6.1-stm32mp-r1-CLOCK.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0003-v5.15-stm32mp-r2-CPUFREQ.patch => 6.1/6.1.28/0003-v6.1-stm32mp-r1-CPUFREQ.patch} (55%) rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0004-v5.15-stm32mp-r2-CPUIDLE-POWER.patch => 6.1/6.1.28/0004-v6.1-stm32mp-r1-CPUIDLE-POWER.patch} (93%) rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0005-v5.15-stm32mp-r2-CRYPTO.patch => 6.1/6.1.28/0005-v6.1-stm32mp-r1-CRYPTO.patch} (67%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0006-v6.1-stm32mp-r1-DMA.patch create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0007-v6.1-stm32mp-r1-DRM.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0008-v5.15-stm32mp-r2-HWSPINLOCK.patch => 6.1/6.1.28/0008-v6.1-stm32mp-r1-HWSPINLOCK.patch} (54%) rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0009-v5.15-stm32mp-r2-I2C-IIO-IRQCHIP.patch => 6.1/6.1.28/0009-v6.1-stm32mp-r1-I2C-IIO-IRQCHIP.patch} (54%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0010-v6.1-stm32mp-r1-REMOTEPROC-RPMSG.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0011-v5.15-stm32mp-r2-MISC-MEDIA-SOC-THERMAL.patch => 6.1/6.1.28/0011-v6.1-stm32mp-r1-MEDIA-SOC-THERMAL.patch} (70%) rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0012-v5.15-stm32mp-r2-MFD.patch => 6.1/6.1.28/0012-v6.1-stm32mp-r1-MFD.patch} (77%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0013-v6.1-stm32mp-r1-MMC.patch create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0014-v6.1-stm32mp-r1-NET-TTY.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0015-v5.15-stm32mp-r2-PERF.patch => 6.1/6.1.28/0015-v6.1-stm32mp-r1-PERF.patch} (88%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0016-v6.1-stm32mp-r1-PHY-USB.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0017-v5.15-stm32mp-r2-PINCTRL-REGULATOR-SPI.patch => 6.1/6.1.28/0017-v6.1-stm32mp-r1-PINCTRL-REGULATOR-SPI.patch} (50%) rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0018-v5.15-stm32mp-r2-RESET-RTC.patch => 6.1/6.1.28/0018-v6.1-stm32mp-r1-RESET-RTC.patch} (71%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0019-v6.1-stm32mp-r1-SCMI.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0020-v5.15-stm32mp-r2-SOUND.patch => 6.1/6.1.28/0020-v6.1-stm32mp-r1-SOUND.patch} (50%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0021-v6.1-stm32mp-r1-MISC.patch create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0022-v6.1-stm32mp-r1-MACHINE.patch create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/6.1.28/0023-v6.1-stm32mp-r1-DEVICETREE.patch rename recipes-kernel/linux/linux-stm32mp/{5.15/5.15.67/0022-v5.15-stm32mp-r2-CONFIG.patch => 6.1/6.1.28/0024-v6.1-stm32mp-r1-CONFIG.patch} (66%) rename recipes-kernel/linux/linux-stm32mp/{5.15 => 6.1}/fragment-03-systemd.config (100%) rename recipes-kernel/linux/linux-stm32mp/{5.15 => 6.1}/fragment-04-modules.config (68%) rename recipes-kernel/linux/linux-stm32mp/{5.15/fragment-05-signature.config => 6.1/optional-fragment-05-signature.config} (100%) rename recipes-kernel/linux/linux-stm32mp/{5.15/fragment-06-nosmp.config => 6.1/optional-fragment-06-nosmp.config} (100%) create mode 100644 recipes-kernel/linux/linux-stm32mp/6.1/optional-fragment-07-efi.config delete mode 100644 recipes-kernel/linux/linux-stm32mp_5.15.bb create mode 100644 recipes-kernel/linux/linux-stm32mp_6.1.bb diff --git a/classes/archiver_stm32mp_clean.bbclass b/classes/archiver_stm32mp_clean.bbclass index 146616eb..29b3d511 100644 --- a/classes/archiver_stm32mp_clean.bbclass +++ b/classes/archiver_stm32mp_clean.bbclass @@ -45,7 +45,7 @@ archiver_git_uri() { fi if [ -e "${ARCHIVER_OUTDIR}/${ARCHIVER_README}" ]; then - sed -i -e "s|##LINUX_TARNAME##|${LINUX_TARNAME}|g" -e "s|##ARCHIVER_COMMUNITY_BRANCH##|${ARCHIVER_COMMUNITY_BRANCH}|g" -e "s|##ARCHIVER_COMMUNITY_REVISION##|${ARCHIVER_COMMUNITY_REVISION}|g" -e "s|##ARCHIVER_ST_BRANCH##|${ARCHIVER_ST_BRANCH}|g" -e "s|##ARCHIVER_ST_REVISION##|${ARCHIVER_ST_REVISION}|g" -e "s|##BP##|${BP}|g" -e "s|##PV##|${PV}|g" -e "s|##PR##|${PR}|g" "${ARCHIVER_OUTDIR}/${ARCHIVER_README}" + sed -i -e "s|##LINUX_TARNAME##|${LINUX_TARNAME}|g" -e "s|##LINUX_TARBASE##|${LINUX_TARBASE}|g" -e "s|##GCNANO_TARNAME##|${GCNANO_TARNAME}|g" -e "s|##ARCHIVER_COMMUNITY_BRANCH##|${ARCHIVER_COMMUNITY_BRANCH}|g" -e "s|##ARCHIVER_COMMUNITY_REVISION##|${ARCHIVER_COMMUNITY_REVISION}|g" -e "s|##ARCHIVER_ST_BRANCH##|${ARCHIVER_ST_BRANCH}|g" -e "s|##ARCHIVER_ST_REVISION##|${ARCHIVER_ST_REVISION}|g" -e "s|##BP##|${BP}|g" -e "s|##PV##|${PV}|g" -e "s|##PR##|${PR}|g" "${ARCHIVER_OUTDIR}/${ARCHIVER_README}" fi } do_ar_original[postfuncs] =+ "archiver_git_uri" diff --git a/recipes-kernel/linux/linux-stm32mp.inc b/recipes-kernel/linux/linux-stm32mp.inc index 3c8b8669..06343cb9 100644 --- a/recipes-kernel/linux/linux-stm32mp.inc +++ b/recipes-kernel/linux/linux-stm32mp.inc @@ -1,9 +1,10 @@ COMPATIBLE_MACHINE = "(stm32mpcommon)" +#for EFI +include ${@bb.utils.contains('MACHINE_FEATURES', 'efi', 'conf/image-uefi.conf', '', d)} inherit kernel DEPENDS += "openssl-native util-linux-native libyaml-native" -DEPENDS += "gmp-native libmpc-native" B = "${WORKDIR}/build" # Configure build dir for externalsrc class usage through devtool @@ -22,18 +23,6 @@ EXTRA_OEMAKE += "${@oe.utils.ifelse(d.getVar('KERNEL_SIGN_ENABLE') == '1', 'INST # Deploy kernel config file to deploy folder KERNEL_CONFIG_DEPLOY ??= "0" -# YoctoProject bugzilla : 140044 -# There's a race between do_symlink_kernsrc and do_populate_lic, since the latter is ordered "after do_patch"; -# -# Below a STMicroelectonics' hacks waiting for official Yocto patch: -# commit already exists in gathesgarth : -#a2b50b74d609ce079ab36b82d4c7c3539fb56485 kernel.bbclass: ensure symlink_kernsrc task gets run even with externalsrc -python () { - bb.build.deltask('do_symlink_kernsrc', d) - bb.build.addtask('do_symlink_kernsrc', 'do_patch do_configure', 'do_unpack', d) -} - - # --------------------------------------------------------------------- # Defconfig # @@ -80,15 +69,6 @@ do_configure:append() { #oe_runmake -C ${S} O=${B} savedefconfig && cp ${B}/defconfig ${WORKDIR}/defconfig.saved } -# --------------------------------------------------------------------- -do_compile_kernelmodules:append() { - if (grep -q -i -e '^CONFIG_MODULES=y$' ${B}/.config); then - # 5.10+ kernels have module.lds that we need to copy for external module builds - if [ -e "${B}/scripts/module.lds" ]; then - install -Dm 0644 ${B}/scripts/module.lds ${STAGING_KERNEL_BUILDDIR}/scripts/module.lds - fi - fi -} # --------------------------------------------------------------------- do_install:append() { # Install KERNEL_IMAGETYPE for kernel-imagebootfs package @@ -101,12 +81,20 @@ do_install:append() { #snd dependencies install -d ${D}/${sysconfdir}/modprobe.d/ echo "softdep snd-soc-cs42l51 pre: snd-soc-cs42l51-i2c" > ${D}/${sysconfdir}/modprobe.d/stm32mp1-snd.conf + + # efi + if ${@bb.utils.contains('MACHINE_FEATURES','efi','true','false',d)}; then + install -d ${D}${EFI_FILES_PATH} + install -m 0644 ${KERNEL_OUTPUT_DIR}/${KERNEL_IMAGETYPE} ${D}${EFI_FILES_PATH}/${EFI_BOOT_IMAGE} + install -d ${D}${EFI_PREFIX}/dtb + install -m 0664 ${D}${EFI_PREFIX}/*.dtb ${D}${EFI_PREFIX}/dtb/ + fi } # --------------------------------------------------------------------- do_deploy:append() { if [ ${MODULE_TARBALL_DEPLOY} = "1" ] && (grep -q -i -e '^CONFIG_MODULES=y$' .config); then mkdir -p ${D}${root_prefix}/lib - tar -cvzf $deployDir/modules-stripped-${MODULE_TARBALL_NAME}.tgz -C ${WORKDIR}/package/${root_prefix} lib + tar -cvzf $deployDir/modules-stripped-${MODULE_TARBALL_NAME}.tgz --exclude='.debug' -C ${WORKDIR}/package/${root_prefix} lib ln -sf modules-stripped-${MODULE_TARBALL_NAME}.tgz $deployDir/modules-stripped-${MODULE_TARBALL_LINK_NAME}.tgz fi if [ ${KERNEL_CONFIG_DEPLOY} = "1" ] && [ -f "${D}/boot/config-${KERNEL_VERSION}" ]; then @@ -139,3 +127,6 @@ FILES:${KERNEL_PACKAGE_NAME}-headers = "${exec_prefix}/src/linux*" FILES:${KERNEL_PACKAGE_NAME}-image += "boot/ ${KERNEL_IMAGEDEST}" FILES:${KERNEL_PACKAGE_NAME}-imagebootfs = "boot/*.dtb boot/${KERNEL_IMAGETYPE}" FILES:${KERNEL_PACKAGE_NAME}-modules += "${sysconfdir}/modprobe.d" + +PACKAGES =+ "${@bb.utils.contains('MACHINE_FEATURES', 'efi', '${KERNEL_PACKAGE_NAME}-imageefi', '', d)} " +FILES:${KERNEL_PACKAGE_NAME}-imageefi = "${EFI_PREFIX}/dtb/ ${EFI_FILES_PATH}" diff --git a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0001-v5.15-stm32mp-r2-MACHINE.patch b/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0001-v5.15-stm32mp-r2-MACHINE.patch deleted file mode 100644 index b449f038..00000000 --- a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0001-v5.15-stm32mp-r2-MACHINE.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 84827f5873b8cd852cc79177e9a42b12760b3723 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 13 Oct 2022 12:22:34 +0200 -Subject: [PATCH 01/22] v5.15-stm32mp-r2 MACHINE - -Signed-off-by: Romuald JEANNE ---- - Documentation/arm/index.rst | 1 + - .../arm/stm32/stm32mp13-overview.rst | 37 +++++++++++++++++++ - arch/arm/Kconfig.debug | 2 +- - arch/arm/mach-stm32/Kconfig | 9 +++++ - arch/arm/mach-stm32/board-dt.c | 5 +++ - 5 files changed, 53 insertions(+), 1 deletion(-) - create mode 100644 Documentation/arm/stm32/stm32mp13-overview.rst - -diff --git a/Documentation/arm/index.rst b/Documentation/arm/index.rst -index d4f34ae9e6f4..2bda5461a80b 100644 ---- a/Documentation/arm/index.rst -+++ b/Documentation/arm/index.rst -@@ -55,6 +55,7 @@ SoC-specific documents - stm32/stm32h750-overview - stm32/stm32f769-overview - stm32/stm32f429-overview -+ stm32/stm32mp13-overview - stm32/stm32mp157-overview - - sunxi -diff --git a/Documentation/arm/stm32/stm32mp13-overview.rst b/Documentation/arm/stm32/stm32mp13-overview.rst -new file mode 100644 -index 000000000000..3bb9492dad49 ---- /dev/null -+++ b/Documentation/arm/stm32/stm32mp13-overview.rst -@@ -0,0 +1,37 @@ -+=================== -+STM32MP13 Overview -+=================== -+ -+Introduction -+------------ -+ -+The STM32MP131/STM32MP133/STM32MP135 are Cortex-A MPU aimed at various applications. -+They feature: -+ -+- One Cortex-A7 application core -+- Standard memories interface support -+- Standard connectivity, widely inherited from the STM32 MCU family -+- Comprehensive security support -+ -+More details: -+ -+- Cortex-A7 core running up to @900MHz -+- FMC controller to connect SDRAM, NOR and NAND memories -+- QSPI -+- SD/MMC/SDIO support -+- 2*Ethernet controller -+- CAN -+- ADC/DAC -+- USB EHCI/OHCI controllers -+- USB OTG -+- I2C, SPI, CAN busses support -+- Several general purpose timers -+- Serial Audio interface -+- LCD controller -+- DCMIPP -+- SPDIFRX -+- DFSDM -+ -+:Authors: -+ -+- Alexandre Torgue -diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index 644875d73ba1..37b8337617d7 100644 ---- a/arch/arm/Kconfig.debug -+++ b/arch/arm/Kconfig.debug -@@ -1244,7 +1244,7 @@ choice - - config STM32MP1_DEBUG_UART - bool "Use STM32MP1 UART for low-level debug" -- depends on MACH_STM32MP157 -+ depends on MACH_STM32MP157 || MACH_STM32MP13 - select DEBUG_STM32_UART - help - Say Y here if you want kernel low-level debugging support -diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig -index 57699bd8f107..ab69784518c9 100644 ---- a/arch/arm/mach-stm32/Kconfig -+++ b/arch/arm/mach-stm32/Kconfig -@@ -46,8 +46,17 @@ if ARCH_MULTI_V7 - config MACH_STM32MP157 - bool "STMicroelectronics STM32MP157" - select ARM_ERRATA_814220 -+ select REGULATOR - default y - -+config MACH_STM32MP13 -+ bool "STMicroelectronics STM32MP13x" -+ select ARM_ERRATA_814220 -+ default y -+ help -+ Support for STM32MP13 SoCs: -+ STM32MP131, STM32MP133, STM32MP135 -+ - endif # ARMv7-A - - endif -diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c -index a766310d8dca..9ff06f2fcbf4 100644 ---- a/arch/arm/mach-stm32/board-dt.c -+++ b/arch/arm/mach-stm32/board-dt.c -@@ -18,6 +18,11 @@ static const char *const stm32_compat[] __initconst = { - "st,stm32f769", - "st,stm32h743", - "st,stm32h750", -+ "st,stm32mp131", -+ "st,stm32mp133", -+ "st,stm32mp135", -+ "st,stm32mp151", -+ "st,stm32mp153", - "st,stm32mp157", - NULL - }; --- -2.17.1 - diff --git a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0002-v5.15-stm32mp-r2-CLOCK.patch b/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0002-v5.15-stm32mp-r2-CLOCK.patch deleted file mode 100644 index 4694f8d3..00000000 --- a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0002-v5.15-stm32mp-r2-CLOCK.patch +++ /dev/null @@ -1,7300 +0,0 @@ -From 7fce50075a5475b4af7b4918076e0577457530c9 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 3 Nov 2022 15:22:35 +0100 -Subject: [PATCH 02/22] v5.15-stm32mp-r2 CLOCK - -Signed-off-by: Romuald JEANNE ---- - drivers/clk/Kconfig | 5 + - drivers/clk/Makefile | 1 + - drivers/clk/clk-composite.c | 15 + - drivers/clk/clk-scmi.c | 36 + - drivers/clk/clk-stm32mp1.c | 1656 ++++++++++++++++-- - drivers/clk/clk.c | 7 +- - drivers/clk/stm32/Makefile | 1 + - drivers/clk/stm32/clk-stm32-core.c | 864 ++++++++++ - drivers/clk/stm32/clk-stm32-core.h | 272 +++ - drivers/clk/stm32/clk-stm32mp13.c | 1760 ++++++++++++++++++++ - drivers/clk/stm32/reset-stm32.c | 161 ++ - drivers/clk/stm32/reset-stm32.h | 7 + - drivers/clk/stm32/stm32mp13_rcc.h | 1751 +++++++++++++++++++ - drivers/clocksource/timer-stm32-lp.c | 4 +- - include/dt-bindings/clock/stm32mp1-clks.h | 52 +- - include/dt-bindings/clock/stm32mp13-clks.h | 235 +++ - 16 files changed, 6619 insertions(+), 208 deletions(-) - create mode 100644 drivers/clk/stm32/Makefile - create mode 100644 drivers/clk/stm32/clk-stm32-core.c - create mode 100644 drivers/clk/stm32/clk-stm32-core.h - create mode 100644 drivers/clk/stm32/clk-stm32mp13.c - create mode 100644 drivers/clk/stm32/reset-stm32.c - create mode 100644 drivers/clk/stm32/reset-stm32.h - create mode 100644 drivers/clk/stm32/stm32mp13_rcc.h - create mode 100644 include/dt-bindings/clock/stm32mp13-clks.h - -diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig -index c5b3dc97396a..c23287f7d108 100644 ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -334,6 +334,11 @@ config COMMON_CLK_VC5 - This driver supports the IDT VersaClock 5 and VersaClock 6 - programmable clock generators. - -+config COMMON_CLK_STM32MP135 -+ def_bool COMMON_CLK && MACH_STM32MP13 -+ help -+ Support for stm32mp135 SoC family clocks -+ - config COMMON_CLK_STM32MP157 - def_bool COMMON_CLK && MACH_STM32MP157 - help -diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index e42312121e51..6172bc25bfe0 100644 ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -109,6 +109,7 @@ obj-y += socfpga/ - obj-$(CONFIG_PLAT_SPEAR) += spear/ - obj-y += sprd/ - obj-$(CONFIG_ARCH_STI) += st/ -+obj-$(CONFIG_ARCH_STM32) += stm32/ - obj-$(CONFIG_ARCH_SUNXI) += sunxi/ - obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/ - obj-$(CONFIG_ARCH_TEGRA) += tegra/ -diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c -index 510a9965633b..8fcbb34de2cd 100644 ---- a/drivers/clk/clk-composite.c -+++ b/drivers/clk/clk-composite.c -@@ -42,6 +42,18 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw, - return rate_ops->recalc_rate(rate_hw, parent_rate); - } - -+static int clk_composite_get_duty_cycle(struct clk_hw *hw, -+ struct clk_duty *duty) -+{ -+ struct clk_composite *composite = to_clk_composite(hw); -+ const struct clk_ops *rate_ops = composite->rate_ops; -+ struct clk_hw *rate_hw = composite->rate_hw; -+ -+ __clk_hw_set_clk(rate_hw, hw); -+ -+ return rate_ops->get_duty_cycle(rate_hw, duty); -+} -+ - static int clk_composite_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) - { -@@ -251,6 +263,9 @@ static struct clk_hw *__clk_hw_register_composite(struct device *dev, - } - clk_composite_ops->recalc_rate = clk_composite_recalc_rate; - -+ if (rate_ops->get_duty_cycle) -+ clk_composite_ops->get_duty_cycle = clk_composite_get_duty_cycle; -+ - if (rate_ops->determine_rate) - clk_composite_ops->determine_rate = - clk_composite_determine_rate; -diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c -index 1e357d364ca2..3e87eefa802f 100644 ---- a/drivers/clk/clk-scmi.c -+++ b/drivers/clk/clk-scmi.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -37,6 +38,37 @@ static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw, - return rate; - } - -+static unsigned long scmi_clk_round_rate_get(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ int ret; -+ u64 round_rate = rate; -+ struct scmi_clk *clk = to_scmi_clk(hw); -+ -+ ret = scmi_proto_clk_ops->round_rate_get(clk->ph, clk->id, &round_rate); -+ if (ret) -+ return 0; -+ -+ return round_rate; -+} -+ -+static int scmi_clk_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) -+{ -+ struct scmi_clk *clk = to_scmi_clk(hw); -+ int ret; -+ -+ ret = scmi_proto_clk_ops->get_duty_cycle(clk->ph, clk->id, -+ &duty->num, &duty->den); -+ if (ret) { -+ /* Assume a default value of 50% */ -+ duty->num = 1; -+ duty->den = 2; -+ } -+ -+ return 0; -+} -+ - static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) - { -@@ -59,6 +91,9 @@ static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, - else if (rate >= fmax) - return fmax; - -+ if (clk->info->range.step_size == 0) -+ return scmi_clk_round_rate_get(hw, rate, parent_rate); -+ - ftmp = rate - fmin; - ftmp += clk->info->range.step_size - 1; /* to round up */ - do_div(ftmp, clk->info->range.step_size); -@@ -100,6 +135,7 @@ static const struct clk_ops scmi_clk_ops = { - */ - .prepare = scmi_clk_enable, - .unprepare = scmi_clk_disable, -+ .get_duty_cycle = scmi_clk_get_duty_cycle, - }; - - static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk) -diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c -index 4bd1fe7d8af4..e50d27ccd9a9 100644 ---- a/drivers/clk/clk-stm32mp1.c -+++ b/drivers/clk/clk-stm32mp1.c -@@ -116,11 +116,11 @@ static const char * const ref3_parents[] = { - }; - - static const char * const ref4_parents[] = { -- "ck_hsi", "ck_hse", "ck_csi" -+ "ck_hsi", "ck_hse", "ck_csi", "i2s_ckin" - }; - - static const char * const cpu_src[] = { -- "ck_hsi", "ck_hse", "pll1_p" -+ "ck_hsi", "ck_hse", "pll1_p", "pll1_p_div" - }; - - static const char * const axi_src[] = { -@@ -294,6 +294,7 @@ static const struct clk_div_table ck_trace_div_table[] = { - struct stm32_mmux { - u8 nbr_clk; - struct clk_hw *hws[MAX_MUX_CLK]; -+ u8 saved_parent; - }; - - struct stm32_clk_mmux { -@@ -717,7 +718,7 @@ static int clk_mmux_set_parent(struct clk_hw *hw, u8 index) - - for (n = 0; n < clk_mmux->mmux->nbr_clk; n++) - if (clk_mmux->mmux->hws[n] != hw) -- clk_hw_reparent(clk_mmux->mmux->hws[n], hwp); -+ clk_hw_set_parent(clk_mmux->mmux->hws[n], hwp); - - return 0; - } -@@ -728,156 +729,212 @@ static const struct clk_ops clk_mmux_ops = { - .determine_rate = __clk_mux_determine_rate, - }; - --/* STM32 PLL */ --struct stm32_pll_obj { -- /* lock pll enable/disable registers */ -- spinlock_t *lock; -- void __iomem *reg; -- struct clk_hw hw; -- struct clk_mux mux; --}; -+static bool is_all_clk_on_switch_are_off(struct clk_hw *hw) -+{ -+ struct clk_composite *composite = to_clk_composite(hw); -+ struct clk_hw *mux_hw = composite->mux_hw; -+ struct clk_mux *mux = to_clk_mux(mux_hw); -+ struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux); -+ int i = 0; - --#define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw) -+ for (i = 0; i < clk_mmux->mmux->nbr_clk; i++) -+ if (__clk_is_enabled(clk_mmux->mmux->hws[i]->clk)) -+ return false; - --#define PLL_ON BIT(0) --#define PLL_RDY BIT(1) --#define DIVN_MASK 0x1FF --#define DIVM_MASK 0x3F --#define DIVM_SHIFT 16 --#define DIVN_SHIFT 0 --#define FRAC_OFFSET 0xC --#define FRAC_MASK 0x1FFF --#define FRAC_SHIFT 3 --#define FRACLE BIT(16) --#define PLL_MUX_SHIFT 0 --#define PLL_MUX_MASK 3 -+ return true; -+} - --static int __pll_is_enabled(struct clk_hw *hw) -+#define MMUX_SAFE_POSITION 0 -+ -+static int clk_mmux_set_safe_position(struct clk_hw *hw) - { -- struct stm32_pll_obj *clk_elem = to_pll(hw); -+ struct clk_composite *composite = to_clk_composite(hw); -+ struct clk_hw *mux_hw = composite->mux_hw; -+ struct clk_mux *mux = to_clk_mux(mux_hw); -+ struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux); - -- return readl_relaxed(clk_elem->reg) & PLL_ON; --} -+ clk_mmux->mmux->saved_parent = clk_mmux_get_parent(mux_hw); -+ clk_mux_ops.set_parent(mux_hw, MMUX_SAFE_POSITION); - --#define TIMEOUT 5 -+ return 0; -+} - --static int pll_enable(struct clk_hw *hw) -+static int clk_mmux_restore_parent(struct clk_hw *hw) - { -- struct stm32_pll_obj *clk_elem = to_pll(hw); -- u32 reg; -- unsigned long flags = 0; -- unsigned int timeout = TIMEOUT; -- int bit_status = 0; -+ struct clk_composite *composite = to_clk_composite(hw); -+ struct clk_hw *mux_hw = composite->mux_hw; -+ struct clk_mux *mux = to_clk_mux(mux_hw); -+ struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux); - -- spin_lock_irqsave(clk_elem->lock, flags); -+ clk_mux_ops.set_parent(mux_hw, clk_mmux->mmux->saved_parent); - -- if (__pll_is_enabled(hw)) -- goto unlock; -+ return 0; -+} - -- reg = readl_relaxed(clk_elem->reg); -- reg |= PLL_ON; -- writel_relaxed(reg, clk_elem->reg); -+static u8 clk_mmux_get_parent_safe(struct clk_hw *hw) -+{ -+ struct clk_mux *mux = to_clk_mux(hw); -+ struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux); - -- /* We can't use readl_poll_timeout() because we can be blocked if -- * someone enables this clock before clocksource changes. -- * Only jiffies counter is available. Jiffies are incremented by -- * interruptions and enable op does not allow to be interrupted. -- */ -- do { -- bit_status = !(readl_relaxed(clk_elem->reg) & PLL_RDY); -+ clk_mmux->mmux->saved_parent = clk_mmux_get_parent(hw); - -- if (bit_status) -- udelay(120); -+ return clk_mmux->mmux->saved_parent; -+} - -- } while (bit_status && --timeout); -+static int clk_mmux_set_parent_safe(struct clk_hw *hw, u8 index) -+{ -+ struct clk_mux *mux = to_clk_mux(hw); -+ struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux); - --unlock: -- spin_unlock_irqrestore(clk_elem->lock, flags); -+ clk_mmux_set_parent(hw, index); -+ clk_mmux->mmux->saved_parent = index; - -- return bit_status; -+ return 0; - } - --static void pll_disable(struct clk_hw *hw) --{ -- struct stm32_pll_obj *clk_elem = to_pll(hw); -- u32 reg; -- unsigned long flags = 0; -+static const struct clk_ops clk_mmux_safe_ops = { -+ .get_parent = clk_mmux_get_parent_safe, -+ .set_parent = clk_mmux_set_parent_safe, -+ .determine_rate = __clk_mux_determine_rate, -+}; - -- spin_lock_irqsave(clk_elem->lock, flags); -+static int mp1_mgate_clk_enable_safe(struct clk_hw *hw) -+{ -+ struct clk_hw *composite_hw = __clk_get_hw(hw->clk); - -- reg = readl_relaxed(clk_elem->reg); -- reg &= ~PLL_ON; -- writel_relaxed(reg, clk_elem->reg); -+ clk_mmux_restore_parent(composite_hw); -+ mp1_mgate_clk_enable(hw); - -- spin_unlock_irqrestore(clk_elem->lock, flags); -+ return 0; - } - --static u32 pll_frac_val(struct clk_hw *hw) -+static void mp1_mgate_clk_disable_safe(struct clk_hw *hw) - { -- struct stm32_pll_obj *clk_elem = to_pll(hw); -- u32 reg, frac = 0; -+ struct clk_hw *composite_hw = __clk_get_hw(hw->clk); - -- reg = readl_relaxed(clk_elem->reg + FRAC_OFFSET); -- if (reg & FRACLE) -- frac = (reg >> FRAC_SHIFT) & FRAC_MASK; -+ mp1_mgate_clk_disable(hw); - -- return frac; -+ if (is_all_clk_on_switch_are_off(composite_hw)) -+ clk_mmux_set_safe_position(composite_hw); - } - --static unsigned long pll_recalc_rate(struct clk_hw *hw, -- unsigned long parent_rate) --{ -- struct stm32_pll_obj *clk_elem = to_pll(hw); -- u32 reg; -- u32 frac, divm, divn; -- u64 rate, rate_frac = 0; -+static const struct clk_ops mp1_mgate_clk_safe_ops = { -+ .enable = mp1_mgate_clk_enable_safe, -+ .disable = mp1_mgate_clk_disable_safe, -+ .is_enabled = clk_gate_is_enabled, -+}; -+ -+/* STM32 PLL */ -+struct clk_pll_fractional_divider { -+ struct clk_hw hw; -+ void __iomem *mreg; -+ u8 mshift; -+ u8 mwidth; -+ u8 mflags; -+ void __iomem *nreg; -+ u8 nshift; -+ u8 nwidth; -+ u8 nflags; -+ void __iomem *freg; -+ u8 fshift; -+ u8 fwidth; -+ -+ /* lock pll enable/disable registers */ -+ spinlock_t *lock; -+}; - -- reg = readl_relaxed(clk_elem->reg + 4); -+#define to_pll_fractional_divider(_hw)\ -+ container_of(_hw, struct clk_pll_fractional_divider, hw) - -- divm = ((reg >> DIVM_SHIFT) & DIVM_MASK) + 1; -- divn = ((reg >> DIVN_SHIFT) & DIVN_MASK) + 1; -- rate = (u64)parent_rate * divn; -+static unsigned long clk_pll_frac_div_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_pll_fractional_divider *fd = to_pll_fractional_divider(hw); -+ u32 mmask = GENMASK(fd->mwidth - 1, 0) << fd->mshift; -+ u32 nmask = GENMASK(fd->nwidth - 1, 0) << fd->nshift; -+ u32 fmask = GENMASK(fd->fwidth - 1, 0) << fd->fshift; -+ unsigned long m, n, f; -+ u64 rate, frate = 0; -+ u32 val; -+ -+ val = readl(fd->mreg); -+ m = (val & mmask) >> fd->mshift; -+ if (fd->mflags & CLK_FRAC_DIVIDER_ZERO_BASED) -+ m++; -+ -+ val = readl(fd->nreg); -+ n = (val & nmask) >> fd->nshift; -+ if (fd->nflags & CLK_FRAC_DIVIDER_ZERO_BASED) -+ n++; -+ -+ if (!n || !m) -+ return parent_rate; - -- do_div(rate, divm); -+ rate = (u64)parent_rate * n; -+ do_div(rate, m); - -- frac = pll_frac_val(hw); -- if (frac) { -- rate_frac = (u64)parent_rate * (u64)frac; -- do_div(rate_frac, (divm * 8192)); -+ val = readl(fd->freg); -+ f = (val & fmask) >> fd->fshift; -+ if (f) { -+ frate = (u64)parent_rate * (u64)f; -+ do_div(frate, (m * (1 << fd->fwidth))); - } -- -- return rate + rate_frac; -+ return rate + frate; - } - --static int pll_is_enabled(struct clk_hw *hw) -+static const struct clk_ops clk_pll_frac_div_ops = { -+ .recalc_rate = clk_pll_frac_div_recalc_rate, -+}; -+ -+#define PLL_BIT_ON 0 -+#define PLL_BIT_RDY 1 -+#define PLL_MUX_SHIFT 0 -+#define PLL_MUX_MASK 3 -+#define PLL_DIVMN_OFFSET 4 -+#define PLL_DIVM_SHIFT 16 -+#define PLL_DIVM_WIDTH 6 -+#define PLL_DIVN_SHIFT 0 -+#define PLL_DIVN_WIDTH 9 -+#define PLL_FRAC_OFFSET 0xC -+#define PLL_FRAC_SHIFT 3 -+#define PLL_FRAC_WIDTH 13 -+ -+#define TIMEOUT 5 -+ -+static int pll_enable(struct clk_hw *hw) - { -- struct stm32_pll_obj *clk_elem = to_pll(hw); -- unsigned long flags = 0; -- int ret; -+ struct clk_gate *gate = to_clk_gate(hw); -+ u32 timeout = TIMEOUT; -+ int bit_status = 0; - -- spin_lock_irqsave(clk_elem->lock, flags); -- ret = __pll_is_enabled(hw); -- spin_unlock_irqrestore(clk_elem->lock, flags); -+ if (clk_gate_ops.is_enabled(hw)) -+ return 0; - -- return ret; -+ clk_gate_ops.enable(hw); -+ -+ do { -+ bit_status = !(readl_relaxed(gate->reg) & BIT(PLL_BIT_RDY)); -+ -+ if (bit_status) -+ udelay(120); -+ -+ } while (bit_status && --timeout); -+ -+ return bit_status; - } - --static u8 pll_get_parent(struct clk_hw *hw) -+static void pll_disable(struct clk_hw *hw) - { -- struct stm32_pll_obj *clk_elem = to_pll(hw); -- struct clk_hw *mux_hw = &clk_elem->mux.hw; -- -- __clk_hw_set_clk(mux_hw, hw); -+ if (!clk_gate_ops.is_enabled(hw)) -+ return; - -- return clk_mux_ops.get_parent(mux_hw); -+ clk_gate_ops.disable(hw); - } - --static const struct clk_ops pll_ops = { -+const struct clk_ops pll_gate_ops = { - .enable = pll_enable, - .disable = pll_disable, -- .recalc_rate = pll_recalc_rate, -- .is_enabled = pll_is_enabled, -- .get_parent = pll_get_parent, -+ .is_enabled = clk_gate_is_enabled, - }; - - static struct clk_hw *clk_register_pll(struct device *dev, const char *name, -@@ -888,39 +945,50 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name, - unsigned long flags, - spinlock_t *lock) - { -- struct stm32_pll_obj *element; -- struct clk_init_data init; -- struct clk_hw *hw; -- int err; -+ struct clk_pll_fractional_divider *frac_div; -+ struct clk_gate *gate; -+ struct clk_mux *mux; - -- element = devm_kzalloc(dev, sizeof(*element), GFP_KERNEL); -- if (!element) -+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); -+ if (!mux) - return ERR_PTR(-ENOMEM); - -- init.name = name; -- init.ops = &pll_ops; -- init.flags = flags; -- init.parent_names = parent_names; -- init.num_parents = num_parents; -+ mux->reg = mux_reg; -+ mux->shift = PLL_MUX_SHIFT; -+ mux->mask = PLL_MUX_MASK; -+ mux->flags = CLK_MUX_READ_ONLY; -+ mux->table = NULL; -+ mux->lock = lock; - -- element->mux.lock = lock; -- element->mux.reg = mux_reg; -- element->mux.shift = PLL_MUX_SHIFT; -- element->mux.mask = PLL_MUX_MASK; -- element->mux.flags = CLK_MUX_READ_ONLY; -- element->mux.reg = mux_reg; -+ gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); -+ if (!gate) -+ return ERR_PTR(-ENOMEM); - -- element->hw.init = &init; -- element->reg = reg; -- element->lock = lock; -+ gate->reg = reg; -+ gate->bit_idx = PLL_BIT_ON; -+ gate->flags = 0; -+ gate->lock = lock; - -- hw = &element->hw; -- err = clk_hw_register(dev, hw); -+ frac_div = devm_kzalloc(dev, sizeof(*frac_div), GFP_KERNEL); -+ if (!frac_div) -+ return ERR_PTR(-ENOMEM); - -- if (err) -- return ERR_PTR(err); -+ frac_div->mreg = reg + PLL_DIVMN_OFFSET; -+ frac_div->mshift = PLL_DIVM_SHIFT; -+ frac_div->mwidth = PLL_DIVM_WIDTH; -+ frac_div->mflags = CLK_FRAC_DIVIDER_ZERO_BASED; -+ frac_div->nreg = reg + PLL_DIVMN_OFFSET; -+ frac_div->nshift = PLL_DIVN_SHIFT; -+ frac_div->nwidth = PLL_DIVN_WIDTH; -+ frac_div->nflags = CLK_FRAC_DIVIDER_ZERO_BASED; -+ frac_div->freg = reg + PLL_FRAC_OFFSET; -+ frac_div->fshift = PLL_FRAC_SHIFT; -+ frac_div->fwidth = PLL_FRAC_WIDTH; - -- return hw; -+ return clk_hw_register_composite(dev, name, parent_names, num_parents, -+ &mux->hw, &clk_mux_ops, -+ &frac_div->hw, &clk_pll_frac_div_ops, -+ &gate->hw, &pll_gate_ops, flags); - } - - /* Kernel Timer */ -@@ -1090,9 +1158,49 @@ static const struct clk_ops rtc_div_clk_ops = { - .determine_rate = clk_divider_rtc_determine_rate - }; - -+static int clk_div_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) -+{ -+ struct clk_divider *divider = to_clk_divider(hw); -+ unsigned int val; -+ -+ val = readl(divider->reg) >> divider->shift; -+ val &= clk_div_mask(divider->width); -+ -+ duty->num = (val + 1) / 2; -+ duty->den = (val + 1); -+ -+ return 0; -+} -+ -+static unsigned long clk_div_duty_cycle_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ return clk_divider_ops.recalc_rate(hw, parent_rate); -+} -+ -+static long clk_div_duty_cycle_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *prate) -+{ -+ return clk_divider_ops.round_rate(hw, rate, prate); -+} -+ -+static int clk_div_duty_cycle_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ return clk_divider_ops.set_rate(hw, rate, parent_rate); -+} -+ -+static const struct clk_ops div_dc_clk_ops = { -+ .recalc_rate = clk_div_duty_cycle_recalc_rate, -+ .round_rate = clk_div_duty_cycle_round_rate, -+ .set_rate = clk_div_duty_cycle_set_rate, -+ .get_duty_cycle = clk_div_get_duty_cycle, -+}; -+ - struct stm32_pll_cfg { - u32 offset; - u32 muxoff; -+ const struct clk_ops *ops; - }; - - static struct clk_hw *_clk_register_pll(struct device *dev, -@@ -1281,7 +1389,7 @@ _clk_stm32_register_composite(struct device *dev, - NULL, &mp1_gate_clk_ops)\ - - #define _MGATE_MP1(_mgate)\ -- .gate = &per_gate_cfg[_mgate] -+ &per_gate_cfg[_mgate] - - #define GATE_MP1(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\ - STM32_GATE(_id, _name, _parent, _flags,\ -@@ -1293,7 +1401,7 @@ _clk_stm32_register_composite(struct device *dev, - - #define _STM32_DIV(_div_offset, _div_shift, _div_width,\ - _div_flags, _div_table, _ops)\ -- .div = &(struct stm32_div_cfg) {\ -+ (&(struct stm32_div_cfg) {\ - &(struct div_cfg) {\ - .reg_off = _div_offset,\ - .shift = _div_shift,\ -@@ -1302,18 +1410,23 @@ _clk_stm32_register_composite(struct device *dev, - .table = _div_table,\ - },\ - .ops = _ops,\ -- } -+ }) - - #define _DIV(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\ - _STM32_DIV(_div_offset, _div_shift, _div_width,\ -- _div_flags, _div_table, NULL)\ -+ _div_flags, _div_table, NULL) -+ -+#define _DIV_DUTY_CYCLE(_div_offset, _div_shift, _div_width, _div_flags,\ -+ _div_table)\ -+ _STM32_DIV(_div_offset, _div_shift, _div_width,\ -+ _div_flags, _div_table, &div_dc_clk_ops) - - #define _DIV_RTC(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\ - _STM32_DIV(_div_offset, _div_shift, _div_width,\ - _div_flags, _div_table, &rtc_div_clk_ops) - - #define _STM32_MUX(_offset, _shift, _width, _mux_flags, _mmux, _ops)\ -- .mux = &(struct stm32_mux_cfg) {\ -+ (&(struct stm32_mux_cfg) {\ - &(struct mux_cfg) {\ - .reg_off = _offset,\ - .shift = _shift,\ -@@ -1323,18 +1436,18 @@ _clk_stm32_register_composite(struct device *dev, - },\ - .mmux = _mmux,\ - .ops = _ops,\ -- } -+ }) - - #define _MUX(_offset, _shift, _width, _mux_flags)\ -- _STM32_MUX(_offset, _shift, _width, _mux_flags, NULL, NULL)\ -+ _STM32_MUX(_offset, _shift, _width, _mux_flags, NULL, NULL) - --#define _MMUX(_mmux) .mux = &ker_mux_cfg[_mmux] -+#define _MMUX(_mmux) &ker_mux_cfg[_mmux] - --#define PARENT(_parent) ((const char *[]) { _parent}) -+#define PARENT(_parent) ((const char *[]) { _parent}) - --#define _NO_MUX .mux = NULL --#define _NO_DIV .div = NULL --#define _NO_GATE .gate = NULL -+#define _NO_MUX NULL -+#define _NO_DIV NULL -+#define _NO_GATE NULL - - #define COMPOSITE(_id, _name, _parents, _flags, _gate, _mux, _div)\ - {\ -@@ -1344,9 +1457,9 @@ _clk_stm32_register_composite(struct device *dev, - .num_parents = ARRAY_SIZE(_parents),\ - .flags = _flags,\ - .cfg = &(struct stm32_composite_cfg) {\ -- _gate,\ -- _mux,\ -- _div,\ -+ .gate = (_gate),\ -+ .mux = (_mux),\ -+ .div = (_div),\ - },\ - .func = _clk_stm32_register_composite,\ - } -@@ -1498,6 +1611,10 @@ static struct stm32_mgate mp1_mgate[G_LAST]; - _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\ - &mp1_mgate[_id], &mp1_mgate_clk_ops) - -+#define K_MGATE_SAFE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\ -+ _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\ -+ &mp1_mgate[_id], &mp1_mgate_clk_safe_ops) -+ - /* Peripheral gates */ - static struct stm32_gate_cfg per_gate_cfg[G_LAST] = { - /* Multi gates */ -@@ -1609,10 +1726,10 @@ static struct stm32_gate_cfg per_gate_cfg[G_LAST] = { - - K_GATE(G_USBH, RCC_AHB6ENSETR, 24, 0), - K_GATE(G_CRC1, RCC_AHB6ENSETR, 20, 0), -- K_MGATE(G_SDMMC2, RCC_AHB6ENSETR, 17, 0), -- K_MGATE(G_SDMMC1, RCC_AHB6ENSETR, 16, 0), -- K_MGATE(G_QSPI, RCC_AHB6ENSETR, 14, 0), -- K_MGATE(G_FMC, RCC_AHB6ENSETR, 12, 0), -+ K_MGATE_SAFE(G_SDMMC2, RCC_AHB6ENSETR, 17, 0), -+ K_MGATE_SAFE(G_SDMMC1, RCC_AHB6ENSETR, 16, 0), -+ K_MGATE_SAFE(G_QSPI, RCC_AHB6ENSETR, 14, 0), -+ K_MGATE_SAFE(G_FMC, RCC_AHB6ENSETR, 12, 0), - K_GATE(G_ETHMAC, RCC_AHB6ENSETR, 10, 0), - K_GATE(G_ETHRX, RCC_AHB6ENSETR, 9, 0), - K_GATE(G_ETHTX, RCC_AHB6ENSETR, 8, 0), -@@ -1684,9 +1801,13 @@ static struct stm32_mmux ker_mux[M_LAST]; - _K_MUX(_id, _offset, _shift, _width, _mux_flags,\ - &ker_mux[_id], &clk_mmux_ops) - -+#define K_MMUX_SAFE(_id, _offset, _shift, _width, _mux_flags)\ -+ _K_MUX(_id, _offset, _shift, _width, _mux_flags,\ -+ &ker_mux[_id], &clk_mmux_safe_ops) -+ - static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { - /* Kernel multi mux */ -- K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0), -+ K_MMUX_SAFE(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0), - K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0), - K_MMUX(M_SPI45, RCC_SPI2S45CKSELR, 0, 3, 0), - K_MMUX(M_I2C12, RCC_I2C12CKSELR, 0, 3, 0), -@@ -1703,8 +1824,8 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { - /* Kernel simple mux */ - K_MUX(M_RNG2, RCC_RNG2CKSELR, 0, 2, 0), - K_MUX(M_SDMMC3, RCC_SDMMC3CKSELR, 0, 3, 0), -- K_MUX(M_FMC, RCC_FMCCKSELR, 0, 2, 0), -- K_MUX(M_QSPI, RCC_QSPICKSELR, 0, 2, 0), -+ K_MMUX_SAFE(M_FMC, RCC_FMCCKSELR, 0, 2, 0), -+ K_MMUX_SAFE(M_QSPI, RCC_QSPICKSELR, 0, 2, 0), - K_MUX(M_USBPHY, RCC_USBCKSELR, 0, 2, 0), - K_MUX(M_USBO, RCC_USBCKSELR, 4, 1, 0), - K_MUX(M_SPDIF, RCC_SPDIFCKSELR, 0, 2, 0), -@@ -1748,7 +1869,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = { - PLL(PLL4, "pll4", ref4_parents, 0, RCC_PLL4CR, RCC_RCK4SELR), - - /* ODF */ -- COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0, -+ COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), CLK_SET_RATE_PARENT, - _GATE(RCC_PLL1CR, 4, 0), - _NO_MUX, - _DIV(RCC_PLL1CFGR2, 0, 7, 0, NULL)), -@@ -1776,7 +1897,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = { - COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0, - _GATE(RCC_PLL3CR, 5, 0), - _NO_MUX, -- _DIV(RCC_PLL3CFGR2, 8, 7, 0, NULL)), -+ _DIV_DUTY_CYCLE(RCC_PLL3CFGR2, 8, 7, 0, NULL)), - - COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0, - _GATE(RCC_PLL3CR, 6, 0), -@@ -1796,40 +1917,40 @@ static const struct clock_config stm32mp1_clock_cfg[] = { - COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0, - _GATE(RCC_PLL4CR, 6, 0), - _NO_MUX, -- _DIV(RCC_PLL4CFGR2, 16, 7, 0, NULL)), -+ _DIV_DUTY_CYCLE(RCC_PLL4CFGR2, 16, 7, 0, NULL)), - - /* MUX system clocks */ - MUX(CK_PER, "ck_per", per_src, CLK_OPS_PARENT_ENABLE, - RCC_CPERCKSELR, 0, 2, 0), - - MUX(CK_MPU, "ck_mpu", cpu_src, CLK_OPS_PARENT_ENABLE | -- CLK_IS_CRITICAL, RCC_MPCKSELR, 0, 2, 0), -+ CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, RCC_MPCKSELR, 0, 2, 0), - - COMPOSITE(CK_AXI, "ck_axi", axi_src, CLK_IS_CRITICAL | -- CLK_OPS_PARENT_ENABLE, -- _NO_GATE, -- _MUX(RCC_ASSCKSELR, 0, 2, 0), -- _DIV(RCC_AXIDIVR, 0, 3, 0, axi_div_table)), -+ CLK_OPS_PARENT_ENABLE, -+ _NO_GATE, -+ _MUX(RCC_ASSCKSELR, 0, 2, 0), -+ _DIV(RCC_AXIDIVR, 0, 3, 0, axi_div_table)), - - COMPOSITE(CK_MCU, "ck_mcu", mcu_src, CLK_IS_CRITICAL | -- CLK_OPS_PARENT_ENABLE, -- _NO_GATE, -- _MUX(RCC_MSSCKSELR, 0, 2, 0), -- _DIV(RCC_MCUDIVR, 0, 4, 0, mcu_div_table)), -+ CLK_OPS_PARENT_ENABLE, -+ _NO_GATE, -+ _MUX(RCC_MSSCKSELR, 0, 2, 0), -+ _DIV(RCC_MCUDIVR, 0, 4, 0, mcu_div_table)), - -- DIV_TABLE(NO_ID, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0, -+ DIV_TABLE(PCLK1, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0, - 3, CLK_DIVIDER_READ_ONLY, apb_div_table), - -- DIV_TABLE(NO_ID, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0, -+ DIV_TABLE(PCLK2, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0, - 3, CLK_DIVIDER_READ_ONLY, apb_div_table), - -- DIV_TABLE(NO_ID, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0, -+ DIV_TABLE(PCLK3, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0, - 3, CLK_DIVIDER_READ_ONLY, apb_div_table), - -- DIV_TABLE(NO_ID, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0, -+ DIV_TABLE(PCLK4, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0, - 3, CLK_DIVIDER_READ_ONLY, apb_div_table), - -- DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0, -+ DIV_TABLE(PCLK5, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0, - 3, CLK_DIVIDER_READ_ONLY, apb_div_table), - - /* Kernel Timers */ -@@ -1911,8 +2032,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = { - PCLK(I2C4, "i2c4", "pclk5", 0, G_I2C4), - PCLK(I2C6, "i2c6", "pclk5", 0, G_I2C6), - PCLK(USART1, "usart1", "pclk5", 0, G_USART1), -- PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED | -- CLK_IS_CRITICAL, G_RTCAPB), -+ PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IS_CRITICAL, G_RTCAPB), - PCLK(TZC1, "tzc1", "ck_axi", CLK_IGNORE_UNUSED, G_TZC1), - PCLK(TZC2, "tzc2", "ck_axi", CLK_IGNORE_UNUSED, G_TZC2), - PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC), -@@ -1953,10 +2073,6 @@ static const struct clock_config stm32mp1_clock_cfg[] = { - PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX), - PCLK(ETHRX, "ethrx", "ck_axi", 0, G_ETHRX), - PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC), -- PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC), -- PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI), -- PCLK(SDMMC1, "sdmmc1", "ck_axi", 0, G_SDMMC1), -- PCLK(SDMMC2, "sdmmc2", "ck_axi", 0, G_SDMMC2), - PCLK(CRC1, "crc1", "ck_axi", 0, G_CRC1), - PCLK(USBH, "usbh", "ck_axi", 0, G_USBH), - PCLK(ETHSTP, "ethstp", "ck_axi", 0, G_ETHSTP), -@@ -2046,7 +2162,8 @@ static const struct clock_config stm32mp1_clock_cfg[] = { - GATE(CK_DBG, "ck_sys_dbg", "ck_axi", CLK_IGNORE_UNUSED, - RCC_DBGCFGR, 8, 0), - -- COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE, -+ COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, -+ CLK_OPS_PARENT_ENABLE | CLK_IGNORE_UNUSED, - _GATE(RCC_DBGCFGR, 9, 0), - _NO_MUX, - _DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)), -@@ -2338,6 +2455,8 @@ static int stm32_rcc_init(struct device *dev, void __iomem *base, - return 0; - } - -+static void stm32_clk_summary_debugfs_create(struct device *dev, void __iomem *base); -+ - static int stm32mp1_rcc_init(struct device *dev) - { - void __iomem *base; -@@ -2358,6 +2477,8 @@ static int stm32mp1_rcc_init(struct device *dev) - iounmap(base); - - of_node_put(dev_of_node(dev)); -+ } else { -+ stm32_clk_summary_debugfs_create(dev, base); - } - - return ret; -@@ -2429,3 +2550,1182 @@ static int __init stm32mp1_clocks_init(void) - return platform_driver_register(&stm32mp1_rcc_clocks_driver); - } - core_initcall(stm32mp1_clocks_init); -+ -+#ifdef CONFIG_DEBUG_FS -+ -+#include -+ -+#define NO_STM32_MUX 0xFFFF -+#define NO_STM32_DIV 0xFFFF -+#define NO_STM32_GATE 0xFFFF -+ -+enum enum_gate_cfg { -+ GATE_HSI, -+ GATE_CSI, -+ GATE_LSI, -+ GATE_HSE, -+ GATE_LSE, -+ GATE_PLL1, -+ GATE_PLL2, -+ GATE_PLL3, -+ GATE_PLL4, -+ GATE_PLL1_DIVP, -+ GATE_PLL1_DIVQ, -+ GATE_PLL1_DIVR, -+ GATE_PLL2_DIVP, -+ GATE_PLL2_DIVQ, -+ GATE_PLL2_DIVR, -+ GATE_PLL3_DIVP, -+ GATE_PLL3_DIVQ, -+ GATE_PLL3_DIVR, -+ GATE_PLL4_DIVP, -+ GATE_PLL4_DIVQ, -+ GATE_PLL4_DIVR, -+ GATE_RTCCK, -+ GATE_MCO1, -+ GATE_MCO2, -+ GATE_DBGCK, -+ GATE_TRACECK, -+ GATE_SAI1, -+ GATE_SAI2, -+ GATE_SAI3, -+ GATE_SAI4, -+ GATE_SPI1, -+ GATE_SPI2, -+ GATE_SPI3, -+ GATE_SPI4, -+ GATE_SPI5, -+ GATE_SPI6, -+ GATE_SPDIF, -+ GATE_I2C1, -+ GATE_I2C2, -+ GATE_I2C3, -+ GATE_I2C4, -+ GATE_I2C5, -+ GATE_I2C6, -+ GATE_USART2, -+ GATE_UART4, -+ GATE_USART3, -+ GATE_UART5, -+ GATE_USART1, -+ GATE_USART6, -+ GATE_UART7, -+ GATE_UART8, -+ GATE_LPTIM1, -+ GATE_LPTIM2, -+ GATE_LPTIM3, -+ GATE_LPTIM4, -+ GATE_LPTIM5, -+ GATE_LTDC, -+ GATE_DSI, -+ GATE_QSPI, -+ GATE_FMC, -+ GATE_SDMMC1, -+ GATE_SDMMC2, -+ GATE_SDMMC3, -+ GATE_USBO, -+ GATE_USBPHY, -+ GATE_RNG1, -+ GATE_RNG2, -+ GATE_FDCAN, -+ GATE_DAC12, -+ GATE_CEC, -+ GATE_ADC12, -+ GATE_GPU, -+ GATE_STGEN, -+ GATE_DFSDM, -+ GATE_ADFSDM, -+ GATE_TIM2, -+ GATE_TIM3, -+ GATE_TIM4, -+ GATE_TIM5, -+ GATE_TIM6, -+ GATE_TIM7, -+ GATE_TIM12, -+ GATE_TIM13, -+ GATE_TIM14, -+ GATE_MDIO, -+ GATE_TIM1, -+ GATE_TIM8, -+ GATE_TIM15, -+ GATE_TIM16, -+ GATE_TIM17, -+ GATE_SYSCFG, -+ GATE_VREF, -+ GATE_TMPSENS, -+ GATE_PMBCTRL, -+ GATE_HDP, -+ GATE_IWDG2, -+ GATE_STGENRO, -+ GATE_DMA1, -+ GATE_DMA2, -+ GATE_DMAMUX, -+ GATE_DCMI, -+ GATE_CRYP2, -+ GATE_HASH2, -+ GATE_CRC2, -+ GATE_HSEM, -+ GATE_IPCC, -+ GATE_GPIOA, -+ GATE_GPIOB, -+ GATE_GPIOC, -+ GATE_GPIOD, -+ GATE_GPIOE, -+ GATE_GPIOF, -+ GATE_GPIOG, -+ GATE_GPIOH, -+ GATE_GPIOI, -+ GATE_GPIOJ, -+ GATE_GPIOK, -+ GATE_MDMA, -+ GATE_ETHCK, -+ GATE_ETHTX, -+ GATE_ETHRX, -+ GATE_ETHMAC, -+ GATE_CRC1, -+ GATE_USBH, -+ GATE_ETHSTP, -+ GATE_RTCAPB, -+ GATE_TZC1, -+ GATE_TZC2, -+ GATE_TZPC, -+ GATE_IWDG1, -+ GATE_BSEC, -+ GATE_GPIOZ, -+ GATE_CRYP1, -+ GATE_HASH1, -+ GATE_BKPSRAM, -+ GATE_DDRPERFM, -+ -+ GATE_NB -+}; -+ -+struct cs_gate_cfg { -+ u16 offset; -+ u8 bit_idx; -+}; -+ -+#define CFG_GATE(_id, _offset, _bit_idx)\ -+ [(_id)] = {\ -+ .offset = (_offset),\ -+ .bit_idx = (_bit_idx),\ -+ } -+ -+static struct cs_gate_cfg stm32mp15_gates[] = { -+ CFG_GATE(GATE_HSI, RCC_OCENSETR, 0), -+ CFG_GATE(GATE_CSI, RCC_OCENSETR, 4), -+ CFG_GATE(GATE_LSI, RCC_RDLSICR, 0), -+ CFG_GATE(GATE_HSE, RCC_OCENSETR, 8), -+ CFG_GATE(GATE_LSE, RCC_BDCR, 0), -+ CFG_GATE(GATE_RTCCK, RCC_BDCR, 20), -+ CFG_GATE(GATE_PLL1, RCC_PLL1CR, 0), -+ CFG_GATE(GATE_PLL1_DIVP, RCC_PLL1CR, 4), -+ CFG_GATE(GATE_PLL1_DIVQ, RCC_PLL1CR, 5), -+ CFG_GATE(GATE_PLL1_DIVR, RCC_PLL1CR, 6), -+ CFG_GATE(GATE_PLL2, RCC_PLL2CR, 0), -+ CFG_GATE(GATE_PLL2_DIVP, RCC_PLL2CR, 4), -+ CFG_GATE(GATE_PLL2_DIVQ, RCC_PLL2CR, 5), -+ CFG_GATE(GATE_PLL2_DIVR, RCC_PLL2CR, 6), -+ CFG_GATE(GATE_PLL3, RCC_PLL3CR, 0), -+ CFG_GATE(GATE_PLL3_DIVP, RCC_PLL3CR, 4), -+ CFG_GATE(GATE_PLL3_DIVQ, RCC_PLL3CR, 5), -+ CFG_GATE(GATE_PLL3_DIVR, RCC_PLL3CR, 6), -+ CFG_GATE(GATE_PLL4, RCC_PLL4CR, 0), -+ CFG_GATE(GATE_PLL4_DIVP, RCC_PLL4CR, 4), -+ CFG_GATE(GATE_PLL4_DIVQ, RCC_PLL4CR, 5), -+ CFG_GATE(GATE_PLL4_DIVR, RCC_PLL4CR, 6), -+ CFG_GATE(GATE_MCO1, RCC_MCO1CFGR, 12), -+ CFG_GATE(GATE_MCO2, RCC_MCO2CFGR, 12), -+ CFG_GATE(GATE_DBGCK, RCC_DBGCFGR, 8), -+ CFG_GATE(GATE_TRACECK, RCC_DBGCFGR, 9), -+ CFG_GATE(GATE_MDIO, RCC_APB1ENSETR, 31), -+ CFG_GATE(GATE_DAC12, RCC_APB1ENSETR, 29), -+ CFG_GATE(GATE_CEC, RCC_APB1ENSETR, 27), -+ CFG_GATE(GATE_SPDIF, RCC_APB1ENSETR, 26), -+ CFG_GATE(GATE_I2C5, RCC_APB1ENSETR, 24), -+ CFG_GATE(GATE_I2C3, RCC_APB1ENSETR, 23), -+ CFG_GATE(GATE_I2C2, RCC_APB1ENSETR, 22), -+ CFG_GATE(GATE_I2C1, RCC_APB1ENSETR, 21), -+ CFG_GATE(GATE_UART8, RCC_APB1ENSETR, 19), -+ CFG_GATE(GATE_UART7, RCC_APB1ENSETR, 18), -+ CFG_GATE(GATE_UART5, RCC_APB1ENSETR, 17), -+ CFG_GATE(GATE_UART4, RCC_APB1ENSETR, 16), -+ CFG_GATE(GATE_USART3, RCC_APB1ENSETR, 15), -+ CFG_GATE(GATE_USART2, RCC_APB1ENSETR, 14), -+ CFG_GATE(GATE_SPI3, RCC_APB1ENSETR, 12), -+ CFG_GATE(GATE_SPI2, RCC_APB1ENSETR, 11), -+ CFG_GATE(GATE_LPTIM1, RCC_APB1ENSETR, 9), -+ CFG_GATE(GATE_TIM14, RCC_APB1ENSETR, 8), -+ CFG_GATE(GATE_TIM13, RCC_APB1ENSETR, 7), -+ CFG_GATE(GATE_TIM12, RCC_APB1ENSETR, 6), -+ CFG_GATE(GATE_TIM7, RCC_APB1ENSETR, 5), -+ CFG_GATE(GATE_TIM6, RCC_APB1ENSETR, 4), -+ CFG_GATE(GATE_TIM5, RCC_APB1ENSETR, 3), -+ CFG_GATE(GATE_TIM4, RCC_APB1ENSETR, 2), -+ CFG_GATE(GATE_TIM3, RCC_APB1ENSETR, 1), -+ CFG_GATE(GATE_TIM2, RCC_APB1ENSETR, 0), -+ CFG_GATE(GATE_FDCAN, RCC_APB2ENSETR, 24), -+ CFG_GATE(GATE_ADFSDM, RCC_APB2ENSETR, 21), -+ CFG_GATE(GATE_DFSDM, RCC_APB2ENSETR, 20), -+ CFG_GATE(GATE_SAI3, RCC_APB2ENSETR, 18), -+ CFG_GATE(GATE_SAI2, RCC_APB2ENSETR, 17), -+ CFG_GATE(GATE_SAI1, RCC_APB2ENSETR, 16), -+ CFG_GATE(GATE_USART6, RCC_APB2ENSETR, 13), -+ CFG_GATE(GATE_SPI5, RCC_APB2ENSETR, 10), -+ CFG_GATE(GATE_SPI4, RCC_APB2ENSETR, 9), -+ CFG_GATE(GATE_SPI1, RCC_APB2ENSETR, 8), -+ CFG_GATE(GATE_TIM17, RCC_APB2ENSETR, 4), -+ CFG_GATE(GATE_TIM16, RCC_APB2ENSETR, 3), -+ CFG_GATE(GATE_TIM15, RCC_APB2ENSETR, 2), -+ CFG_GATE(GATE_TIM8, RCC_APB2ENSETR, 1), -+ CFG_GATE(GATE_TIM1, RCC_APB2ENSETR, 0), -+ CFG_GATE(GATE_HDP, RCC_APB3ENSETR, 20), -+ CFG_GATE(GATE_PMBCTRL, RCC_APB3ENSETR, 17), -+ CFG_GATE(GATE_TMPSENS, RCC_APB3ENSETR, 16), -+ CFG_GATE(GATE_VREF, RCC_APB3ENSETR, 13), -+ CFG_GATE(GATE_SYSCFG, RCC_APB3ENSETR, 11), -+ CFG_GATE(GATE_SAI4, RCC_APB3ENSETR, 8), -+ CFG_GATE(GATE_LPTIM5, RCC_APB3ENSETR, 3), -+ CFG_GATE(GATE_LPTIM4, RCC_APB3ENSETR, 2), -+ CFG_GATE(GATE_LPTIM3, RCC_APB3ENSETR, 1), -+ CFG_GATE(GATE_LPTIM2, RCC_APB3ENSETR, 0), -+ CFG_GATE(GATE_STGENRO, RCC_APB4ENSETR, 20), -+ CFG_GATE(GATE_USBPHY, RCC_APB4ENSETR, 16), -+ CFG_GATE(GATE_IWDG2, RCC_APB4ENSETR, 15), -+ CFG_GATE(GATE_DDRPERFM, RCC_APB4ENSETR, 8), -+ CFG_GATE(GATE_DSI, RCC_APB4ENSETR, 4), -+ CFG_GATE(GATE_LTDC, RCC_APB4ENSETR, 0), -+ CFG_GATE(GATE_STGEN, RCC_APB5ENSETR, 20), -+ CFG_GATE(GATE_BSEC, RCC_APB5ENSETR, 16), -+ CFG_GATE(GATE_IWDG1, RCC_APB5ENSETR, 15), -+ CFG_GATE(GATE_TZPC, RCC_APB5ENSETR, 13), -+ CFG_GATE(GATE_TZC2, RCC_APB5ENSETR, 12), -+ CFG_GATE(GATE_TZC1, RCC_APB5ENSETR, 11), -+ CFG_GATE(GATE_RTCAPB, RCC_APB5ENSETR, 8), -+ CFG_GATE(GATE_USART1, RCC_APB5ENSETR, 4), -+ CFG_GATE(GATE_I2C6, RCC_APB5ENSETR, 3), -+ CFG_GATE(GATE_I2C4, RCC_APB5ENSETR, 2), -+ CFG_GATE(GATE_SPI6, RCC_APB5ENSETR, 0), -+ CFG_GATE(GATE_SDMMC3, RCC_AHB2ENSETR, 16), -+ CFG_GATE(GATE_USBO, RCC_AHB2ENSETR, 8), -+ CFG_GATE(GATE_ADC12, RCC_AHB2ENSETR, 5), -+ CFG_GATE(GATE_DMAMUX, RCC_AHB2ENSETR, 2), -+ CFG_GATE(GATE_DMA2, RCC_AHB2ENSETR, 1), -+ CFG_GATE(GATE_DMA1, RCC_AHB2ENSETR, 0), -+ CFG_GATE(GATE_IPCC, RCC_AHB3ENSETR, 12), -+ CFG_GATE(GATE_HSEM, RCC_AHB3ENSETR, 11), -+ CFG_GATE(GATE_CRC2, RCC_AHB3ENSETR, 7), -+ CFG_GATE(GATE_RNG2, RCC_AHB3ENSETR, 6), -+ CFG_GATE(GATE_HASH2, RCC_AHB3ENSETR, 5), -+ CFG_GATE(GATE_CRYP2, RCC_AHB3ENSETR, 4), -+ CFG_GATE(GATE_DCMI, RCC_AHB3ENSETR, 0), -+ CFG_GATE(GATE_GPIOK, RCC_AHB4ENSETR, 10), -+ CFG_GATE(GATE_GPIOJ, RCC_AHB4ENSETR, 9), -+ CFG_GATE(GATE_GPIOI, RCC_AHB4ENSETR, 8), -+ CFG_GATE(GATE_GPIOH, RCC_AHB4ENSETR, 7), -+ CFG_GATE(GATE_GPIOG, RCC_AHB4ENSETR, 6), -+ CFG_GATE(GATE_GPIOF, RCC_AHB4ENSETR, 5), -+ CFG_GATE(GATE_GPIOE, RCC_AHB4ENSETR, 4), -+ CFG_GATE(GATE_GPIOD, RCC_AHB4ENSETR, 3), -+ CFG_GATE(GATE_GPIOC, RCC_AHB4ENSETR, 2), -+ CFG_GATE(GATE_GPIOB, RCC_AHB4ENSETR, 1), -+ CFG_GATE(GATE_GPIOA, RCC_AHB4ENSETR, 0), -+ CFG_GATE(GATE_BKPSRAM, RCC_AHB5ENSETR, 8), -+ CFG_GATE(GATE_RNG1, RCC_AHB5ENSETR, 6), -+ CFG_GATE(GATE_HASH1, RCC_AHB5ENSETR, 5), -+ CFG_GATE(GATE_CRYP1, RCC_AHB5ENSETR, 4), -+ CFG_GATE(GATE_GPIOZ, RCC_AHB5ENSETR, 0), -+ CFG_GATE(GATE_USBH, RCC_AHB6ENSETR, 24), -+ CFG_GATE(GATE_CRC1, RCC_AHB6ENSETR, 20), -+ CFG_GATE(GATE_SDMMC2, RCC_AHB6ENSETR, 17), -+ CFG_GATE(GATE_SDMMC1, RCC_AHB6ENSETR, 16), -+ CFG_GATE(GATE_QSPI, RCC_AHB6ENSETR, 14), -+ CFG_GATE(GATE_FMC, RCC_AHB6ENSETR, 12), -+ CFG_GATE(GATE_ETHMAC, RCC_AHB6ENSETR, 10), -+ CFG_GATE(GATE_ETHRX, RCC_AHB6ENSETR, 9), -+ CFG_GATE(GATE_ETHTX, RCC_AHB6ENSETR, 8), -+ CFG_GATE(GATE_ETHCK, RCC_AHB6ENSETR, 7), -+ CFG_GATE(GATE_GPU, RCC_AHB6ENSETR, 5), -+ CFG_GATE(GATE_MDMA, RCC_AHB6ENSETR, 0), -+ CFG_GATE(GATE_ETHSTP, RCC_AHB6LPENSETR, 11), -+}; -+ -+enum enum_mux_cfg { -+ MUX_MPU, -+ MUX_AXI, -+ MUX_MCU, -+ MUX_PLL12, -+ MUX_PLL3, -+ MUX_PLL4, -+ MUX_CKPER, -+ MUX_RTC, -+ MUX_SDMMC12, -+ MUX_SDMMC3, -+ MUX_FMC, -+ MUX_QSPI, -+ MUX_RNG1, -+ MUX_RNG2, -+ MUX_USBPHY, -+ MUX_USBO, -+ MUX_STGEN, -+ MUX_SPDIF, -+ MUX_SPI1, -+ MUX_SPI23, -+ MUX_SPI45, -+ MUX_SPI6, -+ MUX_CEC, -+ MUX_I2C12, -+ MUX_I2C35, -+ MUX_I2C46, -+ MUX_LPTIM1, -+ MUX_LPTIM23, -+ MUX_LPTIM45, -+ MUX_USART1, -+ MUX_UART24, -+ MUX_UART35, -+ MUX_USART6, -+ MUX_UART78, -+ MUX_SAI1, -+ MUX_SAI2, -+ MUX_SAI3, -+ MUX_SAI4, -+ MUX_DSI, -+ MUX_FDCAN, -+ MUX_ADC12, -+ MUX_ETHCK, -+ MUX_MCO1, -+ MUX_MCO2, -+}; -+ -+struct cs_mux_cfg { -+ u16 offset; -+ u8 shift; -+ u8 width; -+ u8 flags; -+ u32 *table; -+}; -+ -+#define CFG_MUX(_id, _offset, _shift, _witdh, _flags)\ -+ [_id] = {\ -+ .offset = (_offset),\ -+ .shift = (_shift),\ -+ .width = (_witdh),\ -+ .flags = (_flags),\ -+ } -+ -+static const struct cs_mux_cfg stm32mp15_muxes[] = { -+ CFG_MUX(MUX_PLL12, RCC_RCK12SELR, 0, 2, 0), -+ CFG_MUX(MUX_PLL3, RCC_RCK3SELR, 0, 2, 0), -+ CFG_MUX(MUX_PLL4, RCC_RCK4SELR, 0, 2, 0), -+ CFG_MUX(MUX_CKPER, RCC_CPERCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_MPU, RCC_MPCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_AXI, RCC_ASSCKSELR, 0, 3, 0), -+ CFG_MUX(MUX_MCU, RCC_MSSCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_RTC, RCC_BDCR, 16, 2, 0), -+ CFG_MUX(MUX_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_SPI45, RCC_SPI2S45CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_I2C12, RCC_I2C12CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_I2C35, RCC_I2C35CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_LPTIM23, RCC_LPTIM23CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_LPTIM45, RCC_LPTIM45CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_UART24, RCC_UART24CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_UART35, RCC_UART35CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_UART78, RCC_UART78CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_SAI1, RCC_SAI1CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_ETHCK, RCC_ETHCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_I2C46, RCC_I2C46CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_RNG2, RCC_RNG2CKSELR, 0, 2, 0), -+ CFG_MUX(MUX_SDMMC3, RCC_SDMMC3CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_FMC, RCC_FMCCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_QSPI, RCC_QSPICKSELR, 0, 2, 0), -+ CFG_MUX(MUX_USBPHY, RCC_USBCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_USBO, RCC_USBCKSELR, 4, 1, 0), -+ CFG_MUX(MUX_SPDIF, RCC_SPDIFCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_SPI1, RCC_SPI2S1CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_CEC, RCC_CECCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_LPTIM1, RCC_LPTIM1CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_USART6, RCC_UART6CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_FDCAN, RCC_FDCANCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_SAI2, RCC_SAI2CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_SAI3, RCC_SAI3CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_SAI4, RCC_SAI4CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_ADC12, RCC_ADCCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_DSI, RCC_DSICKSELR, 0, 1, 0), -+ CFG_MUX(MUX_RNG1, RCC_RNG1CKSELR, 0, 2, 0), -+ CFG_MUX(MUX_STGEN, RCC_STGENCKSELR, 0, 2, 0), -+ CFG_MUX(MUX_USART1, RCC_UART1CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_SPI6, RCC_SPI6CKSELR, 0, 3, 0), -+ CFG_MUX(MUX_MCO1, RCC_MCO1CFGR, 0, 3, 0), -+ CFG_MUX(MUX_MCO2, RCC_MCO2CFGR, 0, 3, 0), -+}; -+ -+enum enum_div_cfg { -+ DIV_PLL1DIVP, -+ DIV_PLL2DIVP, -+ DIV_PLL2DIVQ, -+ DIV_PLL2DIVR, -+ DIV_PLL3DIVP, -+ DIV_PLL3DIVQ, -+ DIV_PLL3DIVR, -+ DIV_PLL4DIVP, -+ DIV_PLL4DIVQ, -+ DIV_PLL4DIVR, -+ DIV_MPU, -+ DIV_AXI, -+ DIV_MCU, -+ DIV_APB1, -+ DIV_APB2, -+ DIV_APB3, -+ DIV_APB4, -+ DIV_APB5, -+ DIV_RTC, -+ DIV_HSI, -+ DIV_MCO1, -+ DIV_MCO2, -+ DIV_TRACE, -+ DIV_ETHPTP, -+ DIV_NB -+}; -+ -+struct cs_div_cfg { -+ u16 offset; -+ u8 shift; -+ u8 width; -+ u8 flags; -+ const struct clk_div_table *table; -+}; -+ -+#define CFG_DIV(_id, _offset, _shift, _width, _flags, _table)\ -+ [(_id)] = {\ -+ .offset = (_offset),\ -+ .shift = (_shift),\ -+ .width = (_width),\ -+ .flags = (_flags),\ -+ .table = (_table),\ -+ } -+ -+static const struct cs_div_cfg stm32mp15_dividers[DIV_NB] = { -+ CFG_DIV(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL), -+ CFG_DIV(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table), -+ CFG_DIV(DIV_MCU, RCC_MCUDIVR, 0, 4, 0, mcu_div_table), -+ CFG_DIV(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table), -+ CFG_DIV(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table), -+ CFG_DIV(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table), -+ CFG_DIV(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table), -+ CFG_DIV(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table), -+ CFG_DIV(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL), -+ CFG_DIV(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL), -+ CFG_DIV(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL), -+ CFG_DIV(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL), -+ CFG_DIV(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL), -+ CFG_DIV(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL), -+ CFG_DIV(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL), -+ CFG_DIV(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL), -+ CFG_DIV(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL), -+ CFG_DIV(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL), -+ CFG_DIV(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL), -+ CFG_DIV(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL), -+ CFG_DIV(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL), -+ CFG_DIV(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL), -+ CFG_DIV(DIV_TRACE, RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table), -+ CFG_DIV(DIV_ETHPTP, RCC_ETHCKSELR, 4, 4, 0, NULL), -+}; -+ -+struct clk_stm32_clock_data { -+ const struct cs_gate_cfg *gates; -+ const struct cs_mux_cfg *muxes; -+ const struct cs_div_cfg *dividers; -+}; -+ -+struct clock_summary { -+ struct clk_summary *clocks; -+ int nb_clocks; -+ void __iomem *base; -+ struct clk_stm32_clock_data *clock_data; -+}; -+ -+struct clk_summary { -+ const char *name; -+ unsigned long rate; -+ int enabled; -+ int nb_parents; -+ int gate_id; -+ int mux_id; -+ int div_id; -+ void *data; -+ unsigned long (*get_rate)(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate); -+ const char * const *parent_names; -+}; -+ -+static u8 clk_stm32_get_parent_mux(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 mux_id) -+{ -+ const struct cs_mux_cfg *mux = &data->muxes[mux_id]; -+ u32 mask = BIT(mux->width) - 1; -+ u32 val; -+ -+ val = readl(base + mux->offset) >> mux->shift; -+ val &= mask; -+ -+ return val; -+} -+ -+static int clk_stm32_is_enabled_gate(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 gate_id) -+{ -+ const struct cs_gate_cfg *gate = &data->gates[gate_id]; -+ -+ return (readl(base + gate->offset) & BIT(gate->bit_idx)) != 0; -+} -+ -+static unsigned int _get_table_div(const struct clk_div_table *table, -+ unsigned int val) -+{ -+ const struct clk_div_table *clkt; -+ -+ for (clkt = table; clkt->div; clkt++) -+ if (clkt->val == val) -+ return clkt->div; -+ return 0; -+} -+ -+static unsigned int _get_div(const struct clk_div_table *table, -+ unsigned int val, unsigned long flags, u8 width) -+{ -+ if (flags & CLK_DIVIDER_ONE_BASED) -+ return val; -+ if (flags & CLK_DIVIDER_POWER_OF_TWO) -+ return 1 << val; -+ if (table) -+ return _get_table_div(table, val); -+ return val + 1; -+} -+ -+static unsigned long clk_stm32_get_rate_divider(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 div_id, -+ unsigned long parent_rate) -+{ -+ const struct cs_div_cfg *divider = &data->dividers[div_id]; -+ unsigned int val; -+ unsigned int div; -+ -+ val = readl(base + divider->offset) >> divider->shift; -+ val &= clk_div_mask(divider->width); -+ div = _get_div(divider->table, val, divider->flags, divider->width); -+ -+ if (!div) { -+ WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO), -+ "%d: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", div_id); -+ return parent_rate; -+ } -+ -+ return DIV_ROUND_UP_ULL((u64)parent_rate, div); -+} -+ -+struct cs_pll { -+ u32 offset; -+}; -+ -+static unsigned long clk_summary_pll_frac_div_recalc_rate(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ struct cs_pll *pll = (struct cs_pll *)c->data; -+ struct clk_pll_fractional_divider fracdiv; -+ struct clk_pll_fractional_divider *fd = &fracdiv; -+ void __iomem *reg; -+ u32 mmask; -+ u32 nmask; -+ u32 fmask; -+ unsigned long m, n, f; -+ u64 rate, frate = 0; -+ u32 val; -+ -+ reg = cs->base + pll->offset; -+ fd->mreg = reg + PLL_DIVMN_OFFSET; -+ fd->mshift = PLL_DIVM_SHIFT; -+ fd->mwidth = PLL_DIVM_WIDTH; -+ fd->mflags = CLK_FRAC_DIVIDER_ZERO_BASED; -+ fd->nreg = reg + PLL_DIVMN_OFFSET; -+ fd->nshift = PLL_DIVN_SHIFT; -+ fd->nwidth = PLL_DIVN_WIDTH; -+ fd->nflags = CLK_FRAC_DIVIDER_ZERO_BASED; -+ fd->freg = reg + PLL_FRAC_OFFSET; -+ fd->fshift = PLL_FRAC_SHIFT; -+ fd->fwidth = PLL_FRAC_WIDTH; -+ -+ mmask = GENMASK(fd->mwidth - 1, 0) << fd->mshift; -+ nmask = GENMASK(fd->nwidth - 1, 0) << fd->nshift; -+ fmask = GENMASK(fd->fwidth - 1, 0) << fd->fshift; -+ -+ val = readl(fd->mreg); -+ m = (val & mmask) >> fd->mshift; -+ if (fd->mflags & CLK_FRAC_DIVIDER_ZERO_BASED) -+ m++; -+ -+ val = readl(fd->nreg); -+ n = (val & nmask) >> fd->nshift; -+ if (fd->nflags & CLK_FRAC_DIVIDER_ZERO_BASED) -+ n++; -+ -+ if (!n || !m) -+ return parent_rate; -+ -+ rate = (u64)parent_rate * n; -+ do_div(rate, m); -+ -+ val = readl(fd->freg); -+ f = (val & fmask) >> fd->fshift; -+ if (f) { -+ frate = (u64)parent_rate * (u64)f; -+ do_div(frate, (m * (1 << fd->fwidth))); -+ } -+ -+ return rate + frate; -+} -+ -+static unsigned long clk_summary_hsediv2_recalc_rate(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ return parent_rate / 2; -+} -+ -+static unsigned long clk_summary_osc_recalc_rate(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ struct clk *clk = __clk_lookup(c->name); -+ -+ if (clk) -+ return clk_get_rate(clk); -+ -+ return 0; -+} -+ -+static unsigned long clk_summary_div_recalc_rate(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ return clk_stm32_get_rate_divider(cs->base, cs->clock_data, c->div_id, parent_rate); -+} -+ -+static unsigned long clk_summary_rtc_recalc_rate(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ u8 parent; -+ -+ parent = clk_stm32_get_parent_mux(cs->base, cs->clock_data, c->mux_id); -+ if (parent == HSE_RTC) -+ return clk_summary_div_recalc_rate(cs, c, parent_rate); -+ -+ return parent_rate; -+} -+ -+struct cs_stm32_timer { -+ u32 apbdiv; -+ u32 timpre; -+}; -+ -+static unsigned long clk_stm32_timer_recalc_rate(struct clock_summary *cs, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ struct cs_stm32_timer *tim = (struct cs_stm32_timer *)c->data; -+ void __iomem *rcc_base = cs->base; -+ u32 prescaler, timpre; -+ -+ prescaler = readl(rcc_base + tim->apbdiv) & APB_DIV_MASK; -+ -+ timpre = readl(rcc_base + tim->timpre) & TIM_PRE_MASK; -+ -+ if (prescaler == 0U) -+ return parent_rate; -+ -+ return parent_rate * (timpre + 1U) * 2U; -+} -+ -+#define CS_OSC(_name, _gate) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 0,\ -+ .gate_id = _gate,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = NO_STM32_DIV,\ -+ .get_rate = clk_summary_osc_recalc_rate,\ -+} -+ -+#define CS_DIV2(_name, _parent) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .gate_id = NO_STM32_GATE,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = NO_STM32_DIV,\ -+ .get_rate = clk_summary_hsediv2_recalc_rate,\ -+} -+ -+#define CS_PLL(_name, _parents, _gate, _mux, _offset)\ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = NO_STM32_DIV,\ -+ .data = &(struct cs_pll) {\ -+ .offset = _offset,\ -+ },\ -+ .get_rate = clk_summary_pll_frac_div_recalc_rate,\ -+} -+ -+#define CS_DIV(_name, _parent, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .div_id = _div,\ -+ .gate_id = NO_STM32_GATE,\ -+ .mux_id = NO_STM32_MUX,\ -+ .get_rate = clk_summary_div_recalc_rate,\ -+} -+ -+#define CS_MUX(_name, _parents, _mux) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .mux_id = _mux,\ -+ .gate_id = NO_STM32_GATE,\ -+ .div_id = NO_STM32_DIV,\ -+} -+ -+#define CS_GATE(_name, _parent, _gate) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .gate_id = _gate,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = NO_STM32_DIV,\ -+} -+ -+#define CS_GATEDIV(_name, _parent, _gate, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .gate_id = _gate,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = _div,\ -+ .get_rate = clk_summary_div_recalc_rate,\ -+} -+ -+#define CS_GATEMUX(_name, _parents, _gate, _mux) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = NO_STM32_DIV,\ -+} -+ -+#define CS_COMPOSITE(_name, _parents, _gate, _mux, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = _div,\ -+ .get_rate = clk_summary_div_recalc_rate,\ -+} -+ -+#define CS_RTC(_name, _parents, _gate, _mux, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = _div,\ -+ .get_rate = clk_summary_rtc_recalc_rate,\ -+} -+ -+#define CS_STM32_TIMER(_name, _parent, _apbdiv, _timpre) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .div_id = NO_STM32_DIV,\ -+ .gate_id = NO_STM32_GATE,\ -+ .mux_id = NO_STM32_MUX,\ -+ .data = &(struct cs_stm32_timer) {\ -+ .apbdiv = _apbdiv,\ -+ .timpre = _timpre,\ -+ },\ -+ .get_rate = clk_stm32_timer_recalc_rate,\ -+} -+ -+static struct clk_summary stm32mp15_clock_summary[] = { -+ CS_OSC("ck_hsi", GATE_HSI), -+ CS_OSC("ck_csi", GATE_CSI), -+ CS_OSC("ck_lsi", GATE_LSI), -+ CS_OSC("ck_hse", GATE_HSE), -+ CS_OSC("ck_lse", GATE_LSE), -+ CS_OSC("ck_usbo_48m", NO_STM32_GATE), -+ CS_DIV2("clk-hse-div2", "ck_hse"), -+ CS_MUX("ck_per", per_src, MUX_CKPER), -+ -+ CS_PLL("pll1", ref12_parents, GATE_PLL1, MUX_PLL12, RCC_PLL1CR), -+ CS_GATEDIV("pll1_p", "pll1", GATE_PLL1_DIVP, DIV_PLL1DIVP), -+ -+ CS_DIV("pll1_p_div", "pll1_p", DIV_MPU), -+ -+ CS_PLL("pll2", ref12_parents, GATE_PLL2, MUX_PLL12, RCC_PLL2CR), -+ CS_GATEDIV("pll2_p", "pll2", GATE_PLL2_DIVP, DIV_PLL2DIVP), -+ CS_GATEDIV("pll2_q", "pll2", GATE_PLL2_DIVQ, DIV_PLL2DIVQ), -+ CS_GATEDIV("pll2_r", "pll2", GATE_PLL2_DIVR, DIV_PLL2DIVR), -+ -+ CS_PLL("pll3", ref3_parents, GATE_PLL3, MUX_PLL3, RCC_PLL3CR), -+ CS_GATEDIV("pll3_p", "pll3", GATE_PLL3_DIVP, DIV_PLL3DIVP), -+ CS_GATEDIV("pll3_q", "pll3", GATE_PLL3_DIVQ, DIV_PLL3DIVQ), -+ CS_GATEDIV("pll3_r", "pll3", GATE_PLL3_DIVR, DIV_PLL3DIVR), -+ -+ CS_PLL("pll4", ref4_parents, GATE_PLL4, MUX_PLL4, RCC_PLL4CR), -+ CS_GATEDIV("pll4_p", "pll4", GATE_PLL4_DIVP, DIV_PLL4DIVP), -+ CS_GATEDIV("pll4_q", "pll4", GATE_PLL4_DIVQ, DIV_PLL4DIVQ), -+ CS_GATEDIV("pll4_r", "pll4", GATE_PLL4_DIVR, DIV_PLL4DIVR), -+ -+ CS_MUX("ck_mpu", cpu_src, MUX_MPU), -+ CS_MUX("ck_axi", axi_src, MUX_AXI), -+ CS_MUX("ck_mcu", mcu_src, MUX_MCU), -+ -+ CS_DIV("pclk1", "ck_mcu", DIV_APB1), -+ CS_DIV("pclk2", "ck_mcu", DIV_APB2), -+ CS_DIV("pclk3", "ck_mcu", DIV_APB3), -+ CS_DIV("pclk4", "ck_axi", DIV_APB4), -+ CS_DIV("pclk5", "ck_axi", DIV_APB5), -+ -+ CS_STM32_TIMER("ck1_tim", "pclk1", RCC_APB1DIVR, RCC_TIMG1PRER), -+ CS_STM32_TIMER("ck2_tim", "pclk2", RCC_APB2DIVR, RCC_TIMG2PRER), -+ -+ CS_GATE("tim2_k", "ck1_tim", GATE_TIM2), -+ CS_GATE("tim3_k", "ck1_tim", GATE_TIM3), -+ CS_GATE("tim4_k", "ck1_tim", GATE_TIM4), -+ CS_GATE("tim5_k", "ck1_tim", GATE_TIM5), -+ CS_GATE("tim6_k", "ck1_tim", GATE_TIM6), -+ CS_GATE("tim7_k", "ck1_tim", GATE_TIM7), -+ CS_GATE("tim12_k", "ck1_tim", GATE_TIM12), -+ CS_GATE("tim13_k", "ck1_tim", GATE_TIM13), -+ CS_GATE("tim14_k", "ck1_tim", GATE_TIM14), -+ CS_GATE("tim1_k", "ck2_tim", GATE_TIM1), -+ CS_GATE("tim8_k", "ck2_tim", GATE_TIM8), -+ CS_GATE("tim15_k", "ck2_tim", GATE_TIM15), -+ CS_GATE("tim16_k", "ck2_tim", GATE_TIM16), -+ CS_GATE("tim17_k", "ck2_tim", GATE_TIM17), -+ -+ CS_GATE("tim2", "pclk1", GATE_TIM2), -+ CS_GATE("tim3", "pclk1", GATE_TIM3), -+ CS_GATE("tim4", "pclk1", GATE_TIM4), -+ CS_GATE("tim5", "pclk1", GATE_TIM5), -+ CS_GATE("tim6", "pclk1", GATE_TIM6), -+ CS_GATE("tim7", "pclk1", GATE_TIM7), -+ CS_GATE("tim12", "pclk1", GATE_TIM12), -+ CS_GATE("tim13", "pclk1", GATE_TIM13), -+ CS_GATE("tim14", "pclk1", GATE_TIM14), -+ CS_GATE("lptim1", "pclk1", GATE_LPTIM1), -+ CS_GATE("spi2", "pclk1", GATE_SPI2), -+ CS_GATE("spi3", "pclk1", GATE_SPI3), -+ CS_GATE("usart2", "pclk1", GATE_USART2), -+ CS_GATE("usart3", "pclk1", GATE_USART3), -+ CS_GATE("uart4", "pclk1", GATE_UART4), -+ CS_GATE("uart5", "pclk1", GATE_UART5), -+ CS_GATE("uart7", "pclk1", GATE_UART7), -+ CS_GATE("uart8", "pclk1", GATE_UART8), -+ CS_GATE("i2c1", "pclk1", GATE_I2C1), -+ CS_GATE("i2c2", "pclk1", GATE_I2C2), -+ CS_GATE("i2c3", "pclk1", GATE_I2C3), -+ CS_GATE("i2c5", "pclk1", GATE_I2C5), -+ CS_GATE("spdif", "pclk1", GATE_SPDIF), -+ CS_GATE("cec", "pclk1", GATE_CEC), -+ CS_GATE("dac12", "pclk1", GATE_DAC12), -+ CS_GATE("mdio", "pclk1", GATE_MDIO), -+ CS_GATE("tim1", "pclk2", GATE_TIM1), -+ CS_GATE("tim8", "pclk2", GATE_TIM8), -+ CS_GATE("tim15", "pclk2", GATE_TIM15), -+ CS_GATE("tim16", "pclk2", GATE_TIM16), -+ CS_GATE("tim17", "pclk2", GATE_TIM17), -+ CS_GATE("spi1", "pclk2", GATE_SPI1), -+ CS_GATE("spi4", "pclk2", GATE_SPI4), -+ CS_GATE("spi5", "pclk2", GATE_SPI5), -+ CS_GATE("usart6", "pclk2", GATE_USART6), -+ CS_GATE("sai1", "pclk2", GATE_SAI1), -+ CS_GATE("sai2", "pclk2", GATE_SAI2), -+ CS_GATE("sai3", "pclk2", GATE_SAI3), -+ CS_GATE("dfsdm", "pclk2", GATE_DFSDM), -+ CS_GATE("fdcan", "pclk2", GATE_FDCAN), -+ CS_GATE("lptim2", "pclk3", GATE_LPTIM2), -+ CS_GATE("lptim3", "pclk3", GATE_LPTIM3), -+ CS_GATE("lptim4", "pclk3", GATE_LPTIM4), -+ CS_GATE("lptim5", "pclk3", GATE_LPTIM5), -+ CS_GATE("sai4", "pclk3", GATE_SAI4), -+ CS_GATE("syscfg", "pclk3", GATE_SYSCFG), -+ CS_GATE("vref", "pclk3", GATE_VREF), -+ CS_GATE("tmpsens", "pclk3", GATE_TMPSENS), -+ CS_GATE("pmbctrl", "pclk3", GATE_PMBCTRL), -+ CS_GATE("hdp", "pclk3", GATE_HDP), -+ CS_GATE("ltdc", "pclk4", GATE_LTDC), -+ CS_GATE("dsi", "pclk4", GATE_DSI), -+ CS_GATE("iwdg2", "pclk4", GATE_IWDG2), -+ CS_GATE("usbphy", "pclk4", GATE_USBPHY), -+ CS_GATE("stgenro", "pclk4", GATE_STGENRO), -+ CS_GATE("spi6", "pclk5", GATE_SPI6), -+ CS_GATE("i2c4", "pclk5", GATE_I2C4), -+ CS_GATE("i2c6", "pclk5", GATE_I2C6), -+ CS_GATE("usart1", "pclk5", GATE_USART1), -+ CS_GATE("rtcapb", "pclk5", GATE_RTCAPB), -+ CS_GATE("tzc1", "ck_axi", GATE_TZC1), -+ CS_GATE("tzc2", "ck_axi", GATE_TZC2), -+ CS_GATE("tzpc", "pclk5", GATE_TZPC), -+ CS_GATE("iwdg1", "pclk5", GATE_IWDG1), -+ CS_GATE("bsec", "pclk5", GATE_BSEC), -+ CS_GATE("stgen", "pclk5", GATE_STGEN), -+ CS_GATE("dma1", "ck_mcu", GATE_DMA1), -+ CS_GATE("dma2", "ck_mcu", GATE_DMA2), -+ CS_GATE("dmamux", "ck_mcu", GATE_DMAMUX), -+ CS_GATE("adc12", "ck_mcu", GATE_ADC12), -+ CS_GATE("usbo", "ck_mcu", GATE_USBO), -+ CS_GATE("sdmmc3", "ck_mcu", GATE_SDMMC3), -+ CS_GATE("dcmi", "ck_mcu", GATE_DCMI), -+ CS_GATE("cryp2", "ck_mcu", GATE_CRYP2), -+ CS_GATE("hash2", "ck_mcu", GATE_HASH2), -+ CS_GATE("rng2", "ck_mcu", GATE_RNG2), -+ CS_GATE("crc2", "ck_mcu", GATE_CRC2), -+ CS_GATE("hsem", "ck_mcu", GATE_HSEM), -+ CS_GATE("ipcc", "ck_mcu", GATE_IPCC), -+ CS_GATE("gpioa", "ck_mcu", GATE_GPIOA), -+ CS_GATE("gpiob", "ck_mcu", GATE_GPIOB), -+ CS_GATE("gpioc", "ck_mcu", GATE_GPIOC), -+ CS_GATE("gpiod", "ck_mcu", GATE_GPIOD), -+ CS_GATE("gpioe", "ck_mcu", GATE_GPIOE), -+ CS_GATE("gpiof", "ck_mcu", GATE_GPIOF), -+ CS_GATE("gpiog", "ck_mcu", GATE_GPIOG), -+ CS_GATE("gpioh", "ck_mcu", GATE_GPIOH), -+ CS_GATE("gpioi", "ck_mcu", GATE_GPIOI), -+ CS_GATE("gpioj", "ck_mcu", GATE_GPIOJ), -+ CS_GATE("gpiok", "ck_mcu", GATE_GPIOK), -+ CS_GATE("gpioz", "ck_axi", GATE_GPIOZ), -+ CS_GATE("cryp1", "ck_axi", GATE_CRYP1), -+ CS_GATE("hash1", "ck_axi", GATE_HASH1), -+ CS_GATE("rng1", "ck_axi", GATE_RNG1), -+ CS_GATE("bkpsram", "ck_axi", GATE_BKPSRAM), -+ CS_GATE("mdma", "ck_axi", GATE_MDMA), -+ CS_GATE("gpu", "ck_axi", GATE_GPU), -+ CS_GATE("ethtx", "ck_axi", GATE_ETHTX), -+ CS_GATE("ethrx", "ck_axi", GATE_ETHRX), -+ CS_GATE("ethmac", "ck_axi", GATE_ETHMAC), -+ CS_GATE("crc1", "ck_axi", GATE_CRC1), -+ CS_GATE("usbh", "ck_axi", GATE_USBH), -+ CS_GATE("ethstp", "ck_axi", GATE_ETHSTP), -+ CS_GATE("ddrperfm", "pclk4", GATE_DDRPERFM), -+ -+ CS_GATEMUX("sdmmc1_k", sdmmc12_src, GATE_SDMMC1, MUX_SDMMC12), -+ CS_GATEMUX("sdmmc2_k", sdmmc12_src, GATE_SDMMC2, MUX_SDMMC12), -+ CS_GATEMUX("sdmmc3_k", sdmmc3_src, GATE_SDMMC3, MUX_SDMMC3), -+ CS_GATEMUX("fmc_k", fmc_src, GATE_FMC, MUX_FMC), -+ CS_GATEMUX("qspi_k", qspi_src, GATE_QSPI, MUX_QSPI), -+ CS_GATEMUX("rng1_k", rng_src, GATE_RNG1, MUX_RNG1), -+ CS_GATEMUX("rng2_k", rng_src, GATE_RNG2, MUX_RNG2), -+ CS_GATEMUX("usbphy_k", usbphy_src, GATE_USBPHY, MUX_USBPHY), -+ CS_GATEMUX("stgen_k", stgen_src, GATE_STGEN, MUX_STGEN), -+ CS_GATEMUX("spdif_k", spdif_src, GATE_SPDIF, MUX_SPDIF), -+ CS_GATEMUX("spi1_k", spi123_src, GATE_SPI1, MUX_SPI1), -+ CS_GATEMUX("spi2_k", spi123_src, GATE_SPI2, MUX_SPI23), -+ CS_GATEMUX("spi3_k", spi123_src, GATE_SPI3, MUX_SPI23), -+ CS_GATEMUX("spi4_k", spi45_src, GATE_SPI4, MUX_SPI45), -+ CS_GATEMUX("spi5_k", spi45_src, GATE_SPI5, MUX_SPI45), -+ CS_GATEMUX("spi6_k", spi6_src, GATE_SPI6, MUX_SPI6), -+ CS_GATEMUX("cec_k", cec_src, GATE_CEC, MUX_CEC), -+ CS_GATEMUX("i2c1_k", i2c12_src, GATE_I2C1, MUX_I2C12), -+ CS_GATEMUX("i2c2_k", i2c12_src, GATE_I2C2, MUX_I2C12), -+ CS_GATEMUX("i2c3_k", i2c35_src, GATE_I2C3, MUX_I2C35), -+ CS_GATEMUX("i2c5_k", i2c35_src, GATE_I2C5, MUX_I2C35), -+ CS_GATEMUX("i2c4_k", i2c46_src, GATE_I2C4, MUX_I2C46), -+ CS_GATEMUX("i2c6_k", i2c46_src, GATE_I2C6, MUX_I2C46), -+ CS_GATEMUX("lptim1_k", lptim1_src, GATE_LPTIM1, MUX_LPTIM1), -+ CS_GATEMUX("lptim2_k", lptim23_src, GATE_LPTIM2, MUX_LPTIM23), -+ CS_GATEMUX("lptim3_k", lptim23_src, GATE_LPTIM3, MUX_LPTIM23), -+ CS_GATEMUX("lptim4_k", lptim45_src, GATE_LPTIM4, MUX_LPTIM45), -+ CS_GATEMUX("lptim5_k", lptim45_src, GATE_LPTIM5, MUX_LPTIM45), -+ CS_GATEMUX("usart1_k", usart1_src, GATE_USART1, MUX_USART1), -+ CS_GATEMUX("usart2_k", usart234578_src, GATE_USART2, MUX_UART24), -+ CS_GATEMUX("usart3_k", usart234578_src, GATE_USART3, MUX_UART35), -+ CS_GATEMUX("uart4_k", usart234578_src, GATE_UART4, MUX_UART24), -+ CS_GATEMUX("uart5_k", usart234578_src, GATE_UART5, MUX_UART35), -+ CS_GATEMUX("uart6_k", usart6_src, GATE_USART6, MUX_USART6), -+ CS_GATEMUX("uart7_k", usart234578_src, GATE_UART7, MUX_UART78), -+ CS_GATEMUX("uart8_k", usart234578_src, GATE_UART8, MUX_UART78), -+ CS_GATEMUX("fdcan_k", fdcan_src, GATE_FDCAN, MUX_FDCAN), -+ CS_GATEMUX("sai1_k", sai_src, GATE_SAI1, MUX_SAI1), -+ CS_GATEMUX("sai2_k", sai2_src, GATE_SAI2, MUX_SAI2), -+ CS_GATEMUX("sai3_k", sai_src, GATE_SAI3, MUX_SAI3), -+ CS_GATEMUX("sai4_k", sai_src, GATE_SAI4, MUX_SAI4), -+ CS_GATEMUX("adc12_k", adc12_src, GATE_ADC12, MUX_ADC12), -+ CS_GATEMUX("dsi_k", dsi_src, GATE_DSI, MUX_DSI), -+ CS_GATEMUX("adfsdm_k", sai_src, GATE_ADFSDM, MUX_SAI1), -+ CS_GATEMUX("usbo_k", usbo_src, GATE_USBO, MUX_USBO), -+ CS_GATEMUX("ethck_k", eth_src, GATE_ETHCK, MUX_ETHCK), -+ -+ CS_GATE("dfsdm_k", "ck_mcu", GATE_DFSDM), -+ CS_GATE("dsi_px", "pll4_q", GATE_DSI), -+ CS_GATE("ltdc_px", "pll4_q", GATE_LTDC), -+ CS_GATE("gpu_k", "pll2_q", GATE_GPU), -+ CS_GATE("dac12_k", "ck_lsi", GATE_DAC12), -+ -+ CS_COMPOSITE("ck_mco1", mco1_src, GATE_MCO1, MUX_MCO1, DIV_MCO1), -+ CS_COMPOSITE("ck_mco2", mco2_src, GATE_MCO2, MUX_MCO2, DIV_MCO2), -+ CS_GATE("ck_sys_dbg", "ck_axi", GATE_DBGCK), -+ -+ CS_COMPOSITE("ethptp_k", eth_src, NO_STM32_GATE, MUX_ETHCK, DIV_ETHPTP), -+ -+ CS_RTC("ck_rtc", rtc_src, GATE_RTCCK, MUX_RTC, DIV_RTC), -+ -+ CS_GATEDIV("ck_trace", "ck_axi", GATE_TRACECK, DIV_TRACE), -+}; -+ -+static void rcc_summary_show_one(struct seq_file *s, struct clk_summary *c, -+ int level) -+{ -+ char enabled; -+ -+ seq_printf(s, "%*s%-*s %11lu ", -+ level * 3 + 1, "", -+ 30 - level * 3, -+ c->name, -+ c->rate -+ ); -+ -+ switch (c->enabled) { -+ case 0: -+ enabled = 'N'; -+ break; -+ case 1: -+ enabled = 'Y'; -+ break; -+ default: -+ enabled = '?'; -+ break; -+ } -+ -+ seq_printf(s, " %9c\n", enabled); -+} -+ -+static int clock_summary_clk_is_enabled(struct clock_summary *cs, -+ struct clk_summary *c) -+{ -+ return clk_stm32_is_enabled_gate(cs->base, cs->clock_data, c->gate_id); -+} -+ -+static const char *clock_summary_get_parent_name(struct clock_summary *cs, -+ struct clk_summary *c) -+{ -+ int id = 0; -+ -+ if (c->nb_parents == 0) -+ return NULL; -+ -+ if (c->nb_parents > 1) -+ id = clk_stm32_get_parent_mux(cs->base, cs->clock_data, c->mux_id); -+ -+ return c->parent_names[id]; -+} -+ -+static void rcc_summary_show_subtree(struct seq_file *s, struct clk_summary *c, -+ unsigned long parent_rate, int level) -+{ -+ struct clock_summary *cs = (struct clock_summary *)s->private; -+ int i; -+ -+ if (c->get_rate) -+ c->rate = c->get_rate(cs, c, parent_rate); -+ else -+ c->rate = parent_rate; -+ -+ c->enabled = -1; -+ if (c->gate_id != NO_STM32_GATE) -+ c->enabled = clock_summary_clk_is_enabled(cs, c); -+ -+ rcc_summary_show_one(s, c, level); -+ -+ for (i = 0; i < cs->nb_clocks; i++) { -+ struct clk_summary *child = &cs->clocks[i]; -+ const char *parent_name = clock_summary_get_parent_name(cs, child); -+ -+ if (!parent_name) -+ continue; -+ -+ if (!strcmp(c->name, parent_name)) -+ rcc_summary_show_subtree(s, child, c->rate, level + 1); -+ } -+} -+ -+static int rcc_summary_show(struct seq_file *s, void *data) -+{ -+ struct clock_summary *cs = (struct clock_summary *)s->private; -+ int i; -+ -+ seq_puts(s, " hardware\n"); -+ seq_puts(s, " clock rate enable\n"); -+ seq_puts(s, "------------------------------------------------------\n"); -+ -+ for (i = 0; i < cs->nb_clocks; i++) { -+ struct clk_summary *c = &cs->clocks[i]; -+ -+ if (c->nb_parents == 0) -+ rcc_summary_show_subtree(s, c, 0, 0); -+ } -+ -+ return 0; -+} -+ -+DEFINE_SHOW_ATTRIBUTE(rcc_summary); -+ -+struct clk_stm32_clock_data stm32mp15_clock_data = { -+ .gates = stm32mp15_gates, -+ .muxes = stm32mp15_muxes, -+ .dividers = stm32mp15_dividers, -+}; -+ -+static struct clock_summary clock_summary_mp15 = { -+ .clocks = stm32mp15_clock_summary, -+ .nb_clocks = ARRAY_SIZE(stm32mp15_clock_summary), -+ .clock_data = &stm32mp15_clock_data, -+}; -+ -+static void stm32_clk_summary_debugfs_create(struct device *dev, void __iomem *base) -+{ -+ struct dentry *rootdir = debugfs_lookup("clk", NULL); -+ -+ clock_summary_mp15.base = base; -+ -+ debugfs_create_file("stm32_clk_summary", 0444, rootdir, -+ &clock_summary_mp15, &rcc_summary_fops); -+} -+ -+#else -+ -+static void stm32_clk_summary_debugfs_create(struct device *dev, void __iomem *base) -+{ -+} -+ -+#endif -diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c -index 0674dbc62eb5..a4ef506665df 100644 ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -1781,6 +1781,7 @@ static void clk_reparent(struct clk_core *core, struct clk_core *new_parent) - core->parent = new_parent; - } - -+static const struct clk_ops clk_nodrv_ops; - static struct clk_core *__clk_set_parent_before(struct clk_core *core, - struct clk_core *parent) - { -@@ -1809,7 +1810,8 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core, - - /* enable old_parent & parent if CLK_OPS_PARENT_ENABLE is set */ - if (core->flags & CLK_OPS_PARENT_ENABLE) { -- clk_core_prepare_enable(old_parent); -+ if (old_parent && old_parent->ops != &clk_nodrv_ops) -+ clk_core_prepare_enable(old_parent); - clk_core_prepare_enable(parent); - } - -@@ -1843,7 +1845,8 @@ static void __clk_set_parent_after(struct clk_core *core, - /* re-balance ref counting if CLK_OPS_PARENT_ENABLE is set */ - if (core->flags & CLK_OPS_PARENT_ENABLE) { - clk_core_disable_unprepare(parent); -- clk_core_disable_unprepare(old_parent); -+ if (old_parent && old_parent->ops != &clk_nodrv_ops) -+ clk_core_disable_unprepare(old_parent); - } - } - -diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile -new file mode 100644 -index 000000000000..95bd2230bba0 ---- /dev/null -+++ b/drivers/clk/stm32/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-stm32.o -diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c -new file mode 100644 -index 000000000000..e1467cfeb1bf ---- /dev/null -+++ b/drivers/clk/stm32/clk-stm32-core.c -@@ -0,0 +1,864 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved -+ * Author: Gabriel Fernandez for STMicroelectronics. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk-stm32-core.h" -+#include "reset-stm32.h" -+ -+static DEFINE_SPINLOCK(rlock); -+ -+static void stm32_clk_summary_debugfs_create(struct device *dev, -+ const struct stm32_rcc_match_data *data); -+ -+static int stm32_rcc_clock_init(struct device *dev, -+ const struct of_device_id *match, -+ void __iomem *base) -+{ -+ const struct stm32_rcc_match_data *data = match->data; -+ struct clk_hw_onecell_data *clk_data = data->hw_clks; -+ struct clk_hw **hws; -+ int n, max_binding; -+ int ret; -+ -+ max_binding = data->maxbinding; -+ -+ clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, max_binding), -+ GFP_KERNEL); -+ if (!clk_data) -+ return -ENOMEM; -+ -+ data->clock_data->base = base; -+ -+ clk_data->num = max_binding; -+ -+ hws = clk_data->hws; -+ -+ for (n = 0; n < max_binding; n++) -+ hws[n] = ERR_PTR(-ENOENT); -+ -+ for (n = 0; n < data->num_clocks; n++) { -+ const struct clock_config *cfg_clock = &data->tab_clocks[n]; -+ struct clk_hw *hw = ERR_PTR(-ENOENT); -+ -+ if (data->check_security && -+ data->check_security(base, cfg_clock)) -+ continue; -+ -+ if (cfg_clock->func) -+ hw = (*cfg_clock->func)(dev, data, base, &rlock, -+ cfg_clock); -+ -+ if (IS_ERR(hw)) { -+ dev_err(dev, "Can't register clk %d: %ld\n", n, -+ PTR_ERR(hw)); -+ return PTR_ERR(hw); -+ } -+ -+ if (cfg_clock->id < NO_ID) -+ hws[cfg_clock->id] = hw; -+ } -+ -+ ret = of_clk_add_hw_provider(dev_of_node(dev), of_clk_hw_onecell_get, clk_data); -+ if (ret) -+ return ret; -+ -+ if (data->clock_summary) -+ stm32_clk_summary_debugfs_create(dev, data); -+ -+ return ret; -+} -+ -+int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data, -+ void __iomem *base) -+{ -+ const struct of_device_id *match; -+ int err; -+ -+ match = of_match_node(match_data, dev_of_node(dev)); -+ if (!match) { -+ dev_err(dev, "match data not found\n"); -+ return -ENODEV; -+ } -+ -+ /* RCC Reset Configuration */ -+ err = stm32_rcc_reset_init(dev, match, base); -+ if (err) { -+ pr_err("stm32mp1 reset failed to initialize\n"); -+ return err; -+ } -+ -+ /* RCC Clock Configuration */ -+ err = stm32_rcc_clock_init(dev, match, base); -+ if (err) { -+ pr_err("stm32mp1 clock failed to initialize\n"); -+ return err; -+ } -+ -+ return 0; -+} -+ -+void clk_stm32_endisable_gate(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 gate_id, int enable) -+{ -+ const struct stm32_gate_cfg *gate = &data->gates[gate_id]; -+ void __iomem *addr = base + gate->offset; -+ -+ if (enable) { -+ if (data->gate_cpt[gate_id]++ > 0) -+ return; -+ -+ if (gate->set_clr != 0) -+ writel(BIT(gate->bit_idx), addr); -+ else -+ writel(readl(addr) | BIT(gate->bit_idx), addr); -+ } else { -+ if (--data->gate_cpt[gate_id] > 0) -+ return; -+ -+ if (gate->set_clr != 0) -+ writel(BIT(gate->bit_idx), addr + gate->set_clr); -+ else -+ writel(readl(addr) & ~BIT(gate->bit_idx), addr); -+ } -+} -+ -+static void clk_stm32_disable_unused_gate(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 gate_id) -+{ -+ const struct stm32_gate_cfg *gate = &data->gates[gate_id]; -+ void __iomem *addr = base + gate->offset; -+ -+ if (data->gate_cpt[gate_id] > 0) -+ return; -+ -+ if (gate->set_clr != 0) -+ writel(BIT(gate->bit_idx), addr + gate->set_clr); -+ else -+ writel(readl(addr) & ~BIT(gate->bit_idx), addr); -+} -+ -+int clk_stm32_is_enabled_gate(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 gate_id) -+{ -+ const struct stm32_gate_cfg *gate = &data->gates[gate_id]; -+ -+ return (readl(base + gate->offset) & BIT(gate->bit_idx)) != 0; -+} -+ -+void clk_stm32_gate_endisable(struct clk_hw *hw, int enable) -+{ -+ struct clk_stm32_gate *gate = to_clk_stm32_gate(hw); -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(gate->lock, flags); -+ -+ clk_stm32_endisable_gate(gate->base, gate->clock_data, -+ gate->gate_id, enable); -+ -+ spin_unlock_irqrestore(gate->lock, flags); -+} -+ -+int clk_stm32_gate_enable(struct clk_hw *hw) -+{ -+ clk_stm32_gate_endisable(hw, 1); -+ -+ return 0; -+} -+ -+void clk_stm32_gate_disable(struct clk_hw *hw) -+{ -+ clk_stm32_gate_endisable(hw, 0); -+} -+ -+int clk_stm32_gate_is_enabled(struct clk_hw *hw) -+{ -+ struct clk_stm32_gate *gate = to_clk_stm32_gate(hw); -+ -+ return clk_stm32_is_enabled_gate(gate->base, gate->clock_data, -+ gate->gate_id); -+} -+ -+static void clk_stm32_gate_disable_unused(struct clk_hw *hw) -+{ -+ struct clk_stm32_gate *gate = to_clk_stm32_gate(hw); -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(gate->lock, flags); -+ -+ clk_stm32_disable_unused_gate(gate->base, gate->clock_data, gate->gate_id); -+ -+ spin_unlock_irqrestore(gate->lock, flags); -+} -+ -+const struct clk_ops clk_stm32_gate_ops = { -+ .enable = clk_stm32_gate_enable, -+ .disable = clk_stm32_gate_disable, -+ .is_enabled = clk_stm32_gate_is_enabled, -+ .disable_unused = clk_stm32_gate_disable_unused, -+}; -+ -+#define MUX_SAFE_POSITION 0 -+ -+static int clk_stm32_has_safe_mux(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ const struct stm32_mux_cfg *mux = &composite->clock_data->muxes[composite->mux_id]; -+ -+ return !!(mux->flags & MUX_SAFE); -+} -+ -+static void clk_stm32_set_safe_position_mux(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ if (!clk_stm32_composite_is_enabled(hw)) { -+ unsigned long flags = 0; -+ -+ if (composite->clock_data->is_multi_mux) { -+ struct clk_hw *other_mux_hw = NULL; -+ -+ other_mux_hw = composite->clock_data->is_multi_mux(hw); -+ -+ if (!other_mux_hw || clk_stm32_composite_is_enabled(other_mux_hw)) -+ return; -+ } -+ -+ spin_lock_irqsave(composite->lock, flags); -+ -+ clk_stm32_set_parent_mux(composite->base, composite->clock_data, -+ composite->mux_id, MUX_SAFE_POSITION); -+ -+ spin_unlock_irqrestore(composite->lock, flags); -+ } -+} -+ -+static void clk_stm32_safe_restore_position_mux(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ int sel = clk_hw_get_parent_index(hw); -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(composite->lock, flags); -+ -+ clk_stm32_set_parent_mux(composite->base, composite->clock_data, -+ composite->mux_id, sel); -+ -+ spin_unlock_irqrestore(composite->lock, flags); -+} -+ -+void clk_stm32_composite_gate_endisable(struct clk_hw *hw, int enable) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(composite->lock, flags); -+ -+ clk_stm32_endisable_gate(composite->base, composite->clock_data, -+ composite->gate_id, enable); -+ -+ spin_unlock_irqrestore(composite->lock, flags); -+} -+ -+int clk_stm32_composite_gate_enable(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ if (composite->gate_id == NO_STM32_GATE) -+ return 0; -+ -+ clk_stm32_composite_gate_endisable(hw, 1); -+ -+ if (composite->mux_id != NO_STM32_MUX && clk_stm32_has_safe_mux(hw)) -+ clk_stm32_safe_restore_position_mux(hw); -+ -+ return 0; -+} -+ -+void clk_stm32_composite_gate_disable(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ if (composite->gate_id == NO_STM32_GATE) -+ return; -+ -+ clk_stm32_composite_gate_endisable(hw, 0); -+ -+ if (composite->mux_id != NO_STM32_MUX && clk_stm32_has_safe_mux(hw)) -+ clk_stm32_set_safe_position_mux(hw); -+} -+ -+int clk_stm32_composite_is_enabled(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ if (composite->gate_id == NO_STM32_GATE) -+ return (__clk_get_enable_count(hw->clk) > 0); -+ -+ return clk_stm32_is_enabled_gate(composite->base, composite->clock_data, -+ composite->gate_id); -+} -+ -+static void clk_stm32_composite_disable_unused(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ unsigned long flags = 0; -+ -+ if (composite->gate_id == NO_STM32_GATE) -+ return; -+ -+ spin_lock_irqsave(composite->lock, flags); -+ -+ clk_stm32_disable_unused_gate(composite->base, composite->clock_data, -+ composite->gate_id); -+ -+ spin_unlock_irqrestore(composite->lock, flags); -+} -+ -+u8 clk_stm32_get_parent_mux(void __iomem *base, -+ struct clk_stm32_clock_data *data, u16 mux_id) -+{ -+ const struct stm32_mux_cfg *mux = &data->muxes[mux_id]; -+ u32 mask = BIT(mux->width) - 1; -+ u32 val; -+ -+ val = readl(base + mux->offset) >> mux->shift; -+ val &= mask; -+ -+ return val; -+} -+ -+int clk_stm32_set_parent_mux(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 mux_id, u8 index) -+{ -+ const struct stm32_mux_cfg *mux = &data->muxes[mux_id]; -+ -+ u32 mask = BIT(mux->width) - 1; -+ u32 reg = readl(base + mux->offset); -+ u32 val = index << mux->shift; -+ -+ reg &= ~(mask << mux->shift); -+ reg |= val; -+ -+ writel(reg, base + mux->offset); -+ -+ return 0; -+} -+ -+u8 clk_stm32_composite_get_parent(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ return clk_stm32_get_parent_mux(composite->base, composite->clock_data, -+ composite->mux_id); -+} -+ -+int clk_stm32_composite_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(composite->lock, flags); -+ -+ clk_stm32_set_parent_mux(composite->base, composite->clock_data, -+ composite->mux_id, index); -+ -+ spin_unlock_irqrestore(composite->lock, flags); -+ -+ if (composite->clock_data->is_multi_mux) { -+ struct clk_hw *other_mux_hw = composite->clock_data->is_multi_mux(hw); -+ -+ if (other_mux_hw) { -+ struct clk_hw *hwp = clk_hw_get_parent_by_index(hw, index); -+ -+ clk_hw_reparent(other_mux_hw, hwp); -+ } -+ } -+ return 0; -+} -+ -+static unsigned int _get_table_div(const struct clk_div_table *table, -+ unsigned int val) -+{ -+ const struct clk_div_table *clkt; -+ -+ for (clkt = table; clkt->div; clkt++) -+ if (clkt->val == val) -+ return clkt->div; -+ return 0; -+} -+ -+static unsigned int _get_div(const struct clk_div_table *table, -+ unsigned int val, unsigned long flags, u8 width) -+{ -+ if (flags & CLK_DIVIDER_ONE_BASED) -+ return val; -+ if (flags & CLK_DIVIDER_POWER_OF_TWO) -+ return 1 << val; -+ if (table) -+ return _get_table_div(table, val); -+ return val + 1; -+} -+ -+unsigned long clk_stm32_get_rate_divider(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 div_id, unsigned long parent_rate) -+{ -+ const struct stm32_div_cfg *divider = &data->dividers[div_id]; -+ unsigned int val; -+ unsigned int div; -+ -+ val = readl(base + divider->offset) >> divider->shift; -+ val &= clk_div_mask(divider->width); -+ div = _get_div(divider->table, val, divider->flags, divider->width); -+ -+ if (!div) { -+ WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO), -+ "%d: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", -+ div_id); -+ return parent_rate; -+ } -+ -+ return DIV_ROUND_UP_ULL((u64)parent_rate, div); -+} -+ -+unsigned long clk_stm32_composite_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ if (composite->div_id == NO_STM32_DIV) -+ return parent_rate; -+ -+ return clk_stm32_get_rate_divider(composite->base, -+ composite->clock_data, -+ composite->div_id, -+ parent_rate); -+} -+ -+int clk_stm32_set_rate_divider(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 div_id, -+ unsigned long rate, -+ unsigned long parent_rate) -+{ -+ const struct stm32_div_cfg *divider = &data->dividers[div_id]; -+ int value; -+ u32 val; -+ -+ value = divider_get_val(rate, parent_rate, divider->table, -+ divider->width, divider->flags); -+ if (value < 0) -+ return value; -+ -+ if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { -+ val = clk_div_mask(divider->width) << (divider->shift + 16); -+ } else { -+ val = readl(base + divider->offset); -+ val &= ~(clk_div_mask(divider->width) << divider->shift); -+ } -+ -+ val |= (u32)value << divider->shift; -+ -+ writel(val, base + divider->offset); -+ -+ return 0; -+} -+ -+int clk_stm32_composite_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ unsigned long flags = 0; -+ int ret; -+ -+ if (composite->div_id == NO_STM32_DIV) -+ return rate; -+ -+ spin_lock_irqsave(composite->lock, flags); -+ -+ ret = clk_stm32_set_rate_divider(composite->base, composite->clock_data, -+ composite->div_id, rate, parent_rate); -+ -+ spin_unlock_irqrestore(composite->lock, flags); -+ -+ return ret; -+} -+ -+long clk_stm32_composite_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *prate) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ -+ const struct stm32_div_cfg *divider; -+ -+ if (composite->div_id == NO_STM32_DIV) -+ return rate; -+ -+ divider = &composite->clock_data->dividers[composite->div_id]; -+ -+ /* if read only, just return current value */ -+ if (divider->flags & CLK_DIVIDER_READ_ONLY) { -+ u32 val; -+ -+ val = readl(composite->base + divider->offset) >> divider->shift; -+ val &= clk_div_mask(divider->width); -+ -+ return divider_ro_round_rate(hw, rate, prate, divider->table, -+ divider->width, divider->flags, -+ val); -+ } -+ -+ return divider_round_rate_parent(hw, clk_hw_get_parent(hw), -+ rate, prate, divider->table, -+ divider->width, divider->flags); -+} -+ -+const struct clk_ops clk_stm32_composite_ops = { -+ .set_rate = clk_stm32_composite_set_rate, -+ .recalc_rate = clk_stm32_composite_recalc_rate, -+ .round_rate = clk_stm32_composite_round_rate, -+ .get_parent = clk_stm32_composite_get_parent, -+ .set_parent = clk_stm32_composite_set_parent, -+ .enable = clk_stm32_composite_gate_enable, -+ .disable = clk_stm32_composite_gate_disable, -+ .is_enabled = clk_stm32_composite_is_enabled, -+ .disable_unused = clk_stm32_composite_disable_unused, -+}; -+ -+u8 clk_stm32_mux_get_parent(struct clk_hw *hw) -+{ -+ struct clk_stm32_mux *mux = to_clk_stm32_mux(hw); -+ -+ return clk_stm32_get_parent_mux(mux->base, mux->clock_data, -+ mux->mux_id); -+} -+ -+int clk_stm32_mux_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct clk_stm32_mux *mux = to_clk_stm32_mux(hw); -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(mux->lock, flags); -+ -+ clk_stm32_set_parent_mux(mux->base, mux->clock_data, -+ mux->mux_id, index); -+ -+ spin_unlock_irqrestore(mux->lock, flags); -+ -+ return 0; -+} -+ -+const struct clk_ops clk_stm32_mux_ops = { -+ .get_parent = clk_stm32_mux_get_parent, -+ .set_parent = clk_stm32_mux_set_parent, -+}; -+ -+static int clk_stm32_divider_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_stm32_div *div = to_clk_stm32_divider(hw); -+ unsigned long flags = 0; -+ int ret; -+ -+ if (div->div_id == NO_STM32_DIV) -+ return rate; -+ -+ spin_lock_irqsave(div->lock, flags); -+ -+ ret = clk_stm32_set_rate_divider(div->base, div->clock_data, div->div_id, -+ rate, parent_rate); -+ -+ spin_unlock_irqrestore(div->lock, flags); -+ -+ return ret; -+ -+} -+ -+static long clk_stm32_divider_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *prate) -+{ -+ struct clk_stm32_div *div = to_clk_stm32_divider(hw); -+ const struct stm32_div_cfg *divider; -+ -+ if (div->div_id == NO_STM32_DIV) -+ return rate; -+ -+ divider = &div->clock_data->dividers[div->div_id]; -+ -+ /* if read only, just return current value */ -+ if (divider->flags & CLK_DIVIDER_READ_ONLY) { -+ u32 val; -+ -+ val = readl(div->base + divider->offset) >> divider->shift; -+ val &= clk_div_mask(divider->width); -+ -+ return divider_ro_round_rate(hw, rate, prate, divider->table, -+ divider->width, divider->flags, -+ val); -+ } -+ -+ return divider_round_rate_parent(hw, clk_hw_get_parent(hw), -+ rate, prate, divider->table, -+ divider->width, divider->flags); -+} -+ -+static unsigned long clk_stm32_divider_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_stm32_div *div = to_clk_stm32_divider(hw); -+ -+ if (div->div_id == NO_STM32_DIV) -+ return parent_rate; -+ -+ return clk_stm32_get_rate_divider(div->base, div->clock_data, -+ div->div_id, parent_rate); -+} -+ -+const struct clk_ops clk_stm32_divider_ops = { -+ .recalc_rate = clk_stm32_divider_recalc_rate, -+ .round_rate = clk_stm32_divider_round_rate, -+ .set_rate = clk_stm32_divider_set_rate, -+}; -+ -+/* Clock register function */ -+struct clk_hw *clk_stm32_gate_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg) -+{ -+ struct clk_stm32_gate *gate = cfg->clock_cfg; -+ struct clk_hw *hw = &gate->hw; -+ const struct clk_init_data *init_data = hw->init; -+ int err; -+ -+ gate->base = base; -+ gate->lock = lock; -+ gate->clock_data = data->clock_data; -+ -+ err = clk_hw_register(dev, hw); -+ if (err) { -+ dev_err(dev, "Can't register clk %s: %ld\n", init_data->name, PTR_ERR(hw)); -+ return ERR_PTR(err); -+ } -+ -+ return hw; -+} -+ -+struct clk_hw *clk_stm32_div_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg) -+{ -+ struct clk_stm32_div *div = cfg->clock_cfg; -+ struct clk_hw *hw = &div->hw; -+ const struct clk_init_data *init_data = hw->init; -+ int err; -+ -+ div->base = base; -+ div->lock = lock; -+ div->clock_data = data->clock_data; -+ -+ err = clk_hw_register(dev, hw); -+ if (err) { -+ dev_err(dev, "Can't register clk %s: %ld\n", init_data->name, PTR_ERR(hw)); -+ return ERR_PTR(err); -+ } -+ -+ return hw; -+} -+ -+struct clk_hw *clk_stm32_mux_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg) -+{ -+ struct clk_stm32_mux *mux = cfg->clock_cfg; -+ struct clk_hw *hw = &mux->hw; -+ const struct clk_init_data *init_data = hw->init; -+ int err; -+ -+ mux->base = base; -+ mux->lock = lock; -+ mux->clock_data = data->clock_data; -+ -+ err = clk_hw_register(dev, hw); -+ if (err) { -+ dev_err(dev, "Can't register clk %s: %ld\n", init_data->name, PTR_ERR(hw)); -+ return ERR_PTR(err); -+ } -+ -+ return hw; -+} -+ -+struct clk_hw *clk_stm32_composite_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg) -+{ -+ struct clk_stm32_composite *composite = cfg->clock_cfg; -+ struct clk_hw *hw = &composite->hw; -+ const struct clk_init_data *init_data = hw->init; -+ int err; -+ -+ composite->base = base; -+ composite->lock = lock; -+ composite->clock_data = data->clock_data; -+ -+ err = clk_hw_register(dev, hw); -+ if (err) { -+ dev_err(dev, "Can't register clk %s: %ld\n", init_data->name, PTR_ERR(hw)); -+ return ERR_PTR(err); -+ } -+ -+ return hw; -+} -+ -+#ifdef CONFIG_DEBUG_FS -+ -+#include -+ -+static void rcc_summary_show_one(struct seq_file *s, struct clk_summary *c, -+ int level) -+{ -+ char enabled; -+ -+ seq_printf(s, "%*s%-*s %11lu ", -+ level * 3 + 1, "", -+ 30 - level * 3, -+ c->name, -+ c->rate -+ ); -+ -+ switch (c->enabled) { -+ case 0: -+ enabled = 'N'; -+ break; -+ case 1: -+ enabled = 'Y'; -+ break; -+ default: -+ enabled = '?'; -+ break; -+ } -+ -+ seq_printf(s, " %9c\n", enabled); -+} -+ -+static int clock_summary_clk_is_enabled(struct clk_stm32_clock_data *data, -+ struct clk_summary *c) -+{ -+ return clk_stm32_is_enabled_gate(data->base, data, c->gate_id); -+} -+ -+static const char *clock_summary_get_parent_name(struct clk_stm32_clock_data *data, -+ struct clk_summary *c) -+{ -+ int id = 0; -+ -+ if (c->nb_parents == 0) -+ return NULL; -+ -+ if (c->nb_parents > 1) { -+ if (c->get_parent) -+ id = c->get_parent(data, c); -+ else -+ id = clk_stm32_get_parent_mux(data->base, data, c->mux_id); -+ } -+ -+ return c->parent_names[id]; -+} -+ -+static void rcc_summary_show_subtree(struct seq_file *s, struct clk_summary *c, -+ unsigned long parent_rate, int level) -+{ -+ struct stm32_rcc_match_data *match_data = (struct stm32_rcc_match_data *)s->private; -+ struct clk_stm32_clock_data *data = match_data->clock_data; -+ struct clock_summary *cs = match_data->clock_summary; -+ int i; -+ -+ if (c->get_rate) -+ c->rate = c->get_rate(data, c, parent_rate); -+ else -+ c->rate = parent_rate; -+ -+ c->enabled = -1; -+ -+ if (c->is_enabled) -+ c->enabled = c->is_enabled(data, c); -+ -+ else if (c->gate_id != NO_STM32_GATE) -+ c->enabled = clock_summary_clk_is_enabled(data, c); -+ -+ rcc_summary_show_one(s, c, level); -+ -+ for (i = 0; i < cs->nb_clocks; i++) { -+ struct clk_summary *child = &cs->clocks[i]; -+ const char *parent_name = clock_summary_get_parent_name(data, child); -+ -+ if (!parent_name) -+ continue; -+ -+ if (!strcmp(c->name, parent_name)) -+ rcc_summary_show_subtree(s, child, c->rate, level + 1); -+ } -+} -+ -+static int rcc_summary_show(struct seq_file *s, void *data) -+{ -+ struct stm32_rcc_match_data *match_data = (struct stm32_rcc_match_data *)s->private; -+ struct clock_summary *cs = match_data->clock_summary; -+ -+ int i; -+ -+ seq_puts(s, " hardware\n"); -+ seq_puts(s, " clock rate enable\n"); -+ seq_puts(s, "------------------------------------------------------\n"); -+ -+ for (i = 0; i < cs->nb_clocks; i++) { -+ struct clk_summary *c = &cs->clocks[i]; -+ -+ if (c->nb_parents == 0) -+ rcc_summary_show_subtree(s, c, 0, 0); -+ } -+ -+ return 0; -+} -+ -+DEFINE_SHOW_ATTRIBUTE(rcc_summary); -+ -+static void stm32_clk_summary_debugfs_create(struct device *dev, -+ const struct stm32_rcc_match_data *data) -+{ -+ struct dentry *rootdir = debugfs_lookup("clk", NULL); -+ -+ debugfs_create_file("stm32_clk_summary", 0444, rootdir, (void *)data, &rcc_summary_fops); -+} -+ -+#else -+ -+static void stm32_clk_summary_debugfs_create(struct device *dev, -+ const struct stm32_rcc_match_data *data) -+ -+{ -+} -+#endif -diff --git a/drivers/clk/stm32/clk-stm32-core.h b/drivers/clk/stm32/clk-stm32-core.h -new file mode 100644 -index 000000000000..2e0a73d27136 ---- /dev/null -+++ b/drivers/clk/stm32/clk-stm32-core.h -@@ -0,0 +1,272 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved -+ * Author: Gabriel Fernandez for STMicroelectronics. -+ */ -+ -+#include -+ -+struct stm32_rcc_match_data; -+ -+struct stm32_mux_cfg { -+ u16 offset; -+ u8 shift; -+ u8 width; -+ u8 flags; -+ u32 *table; -+ u8 ready; -+}; -+ -+struct stm32_gate_cfg { -+ u16 offset; -+ u8 bit_idx; -+ u8 set_clr; -+}; -+ -+struct stm32_div_cfg { -+ u16 offset; -+ u8 shift; -+ u8 width; -+ u8 flags; -+ u8 ready; -+ const struct clk_div_table *table; -+}; -+ -+struct stm32_composite_cfg { -+ int mux; -+ int gate; -+ int div; -+}; -+ -+#define NO_ID 0xFFFF0000 -+ -+#define NO_STM32_MUX 0xFFFF -+#define NO_STM32_DIV 0xFFFF -+#define NO_STM32_GATE 0xFFFF -+ -+struct clock_config { -+ unsigned long id; -+ int sec_id; -+ void *clock_cfg; -+ -+ struct clk_hw *(*func)(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg); -+}; -+ -+struct clk_stm32_clock_data { -+ void __iomem *base; -+ u16 *gate_cpt; -+ const struct stm32_gate_cfg *gates; -+ const struct stm32_mux_cfg *muxes; -+ const struct stm32_div_cfg *dividers; -+ struct clk_hw *(*is_multi_mux)(struct clk_hw *hw); -+}; -+ -+struct clock_summary { -+ struct clk_summary *clocks; -+ int nb_clocks; -+}; -+ -+struct clk_summary { -+ const char *name; -+ unsigned long rate; -+ int enabled; -+ int nb_parents; -+ int gate_id; -+ int mux_id; -+ int div_id; -+ void *data; -+ -+ bool (*is_enabled)(struct clk_stm32_clock_data *data, -+ struct clk_summary *c); -+ u8 (*get_parent)(struct clk_stm32_clock_data *data, -+ struct clk_summary *c); -+ unsigned long (*get_rate)(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate); -+ const char * const *parent_names; -+}; -+ -+struct stm32_rcc_match_data { -+ struct clk_hw_onecell_data *hw_clks; -+ unsigned int num_clocks; -+ const struct clock_config *tab_clocks; -+ unsigned int maxbinding; -+ struct clk_stm32_clock_data *clock_data; -+ int (*multi_mux)(void __iomem *base, const struct clock_config *cfg); -+ int (*check_security)(void __iomem *base, const struct clock_config *cfg); -+ u32 clear_offset; -+ u32 reset_us; -+ -+ struct clock_summary *clock_summary; -+}; -+ -+int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match, -+ void __iomem *base); -+ -+int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data, -+ void __iomem *base); -+ -+/* MUX define */ -+#define MUX_NO_RDY 0xFF -+#define MUX_SAFE BIT(7) -+ -+/* DIV define */ -+#define DIV_NO_RDY 0xFF -+ -+struct clk_stm32_gate { -+ u16 gate_id; -+ struct clk_hw hw; -+ void __iomem *base; -+ struct clk_stm32_clock_data *clock_data; -+ spinlock_t *lock; /* spin lock */ -+}; -+ -+#define to_clk_stm32_gate(_hw) container_of(_hw, struct clk_stm32_gate, hw) -+ -+struct clk_stm32_mux { -+ u16 mux_id; -+ struct clk_hw hw; -+ void __iomem *base; -+ struct clk_stm32_clock_data *clock_data; -+ spinlock_t *lock; /* spin lock */ -+}; -+ -+#define to_clk_stm32_mux(_hw) container_of(_hw, struct clk_stm32_mux, hw) -+ -+struct clk_stm32_div { -+ u16 div_id; -+ struct clk_hw hw; -+ void __iomem *base; -+ struct clk_stm32_clock_data *clock_data; -+ spinlock_t *lock; /* spin lock */ -+}; -+ -+#define to_clk_stm32_divider(_hw) container_of(_hw, struct clk_stm32_div, hw) -+ -+struct clk_stm32_composite { -+ u16 gate_id; -+ u16 mux_id; -+ u16 div_id; -+ struct clk_hw hw; -+ void __iomem *base; -+ struct clk_stm32_clock_data *clock_data; -+ spinlock_t *lock; /* spin lock */ -+}; -+ -+#define to_clk_stm32_composite(_hw) container_of(_hw, struct clk_stm32_composite, hw) -+ -+void clk_stm32_endisable_gate(void __iomem *base, -+ struct clk_stm32_clock_data *data, u16 gate_id, -+ int enable); -+int clk_stm32_is_enabled_gate(void __iomem *base, -+ struct clk_stm32_clock_data *data, u16 gate_id); -+u8 clk_stm32_get_parent_mux(void __iomem *base, -+ struct clk_stm32_clock_data *data, u16 mux_id); -+int clk_stm32_set_parent_mux(void __iomem *base, -+ struct clk_stm32_clock_data *data, u16 mux_id, -+ u8 index); -+int clk_stm32_set_rate_divider(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 div_id, unsigned long rate, -+ unsigned long parent_rate); -+unsigned long clk_stm32_get_rate_divider(void __iomem *base, -+ struct clk_stm32_clock_data *data, -+ u16 div_id, unsigned long parent_rate); -+ -+void clk_stm32_gate_endisable(struct clk_hw *hw, int enable); -+int clk_stm32_gate_enable(struct clk_hw *hw); -+void clk_stm32_gate_disable(struct clk_hw *hw); -+int clk_stm32_gate_is_enabled(struct clk_hw *hw); -+ -+u8 clk_stm32_mux_get_parent(struct clk_hw *hw); -+int clk_stm32_mux_set_parent(struct clk_hw *hw, u8 index); -+ -+void clk_stm32_composite_gate_endisable(struct clk_hw *hw, int enable); -+int clk_stm32_composite_gate_enable(struct clk_hw *hw); -+void clk_stm32_composite_gate_disable(struct clk_hw *hw); -+int clk_stm32_composite_is_enabled(struct clk_hw *hw); -+u8 clk_stm32_composite_get_parent(struct clk_hw *hw); -+int clk_stm32_composite_set_parent(struct clk_hw *hw, u8 index); -+unsigned long clk_stm32_composite_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate); -+long clk_stm32_composite_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *prate); -+int clk_stm32_composite_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate); -+ -+struct clk_hw *clk_stm32_gate_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg); -+ -+struct clk_hw *clk_stm32_div_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg); -+ -+struct clk_hw *clk_stm32_mux_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg); -+ -+struct clk_hw *clk_stm32_composite_register(struct device *dev, -+ const struct stm32_rcc_match_data *data, -+ void __iomem *base, -+ spinlock_t *lock, -+ const struct clock_config *cfg); -+ -+extern const struct clk_ops clk_stm32_gate_ops; -+extern const struct clk_ops clk_stm32_divider_ops; -+extern const struct clk_ops clk_stm32_mux_ops; -+extern const struct clk_ops clk_stm32_composite_ops; -+ -+#define PARENT(_parent) ((const char *[]) { _parent}) -+ -+#define CLK_STM32_GATE(_name, _parent, _flags, _gate_id)\ -+struct clk_stm32_gate _name = {\ -+ .gate_id = _gate_id,\ -+ .hw.init = CLK_HW_INIT(#_name, _parent, &clk_stm32_gate_ops, _flags),\ -+} -+ -+#define CLK_STM32_MUX(_name, _parents, _flags, _mux_id)\ -+struct clk_stm32_mux _name = {\ -+ .mux_id = _mux_id,\ -+ .hw.init = CLK_HW_INIT_PARENTS(#_name, _parents, &clk_stm32_mux_ops, _flags),\ -+} -+ -+#define CLK_STM32_DIV(_name, _parent, _flags, _div_id)\ -+struct clk_stm32_div _name = {\ -+ .div_id = _div_id,\ -+ .hw.init = CLK_HW_INIT(#_name, _parent, &clk_stm32_divider_ops, _flags),\ -+} -+ -+#define CLK_STM32_COMPOSITE(_name, _parents, _flags, _gate_id, _mux_id, _div_id)\ -+struct clk_stm32_composite _name = {\ -+ .gate_id = _gate_id,\ -+ .mux_id = _mux_id,\ -+ .div_id = _div_id,\ -+ .hw.init = CLK_HW_INIT_PARENTS(#_name, _parents, &clk_stm32_composite_ops, _flags),\ -+} -+ -+#define STM32_CLOCK_CFG(_binding, _clk, _sec_id, _struct, _register)\ -+{\ -+ .id = (_binding),\ -+ .sec_id = (_sec_id),\ -+ .clock_cfg = (_struct) {_clk},\ -+ .func = (_register),\ -+} -+ -+#define STM32_GATE_CFG(_binding, _clk, _sec_id)\ -+ STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_gate *,\ -+ &clk_stm32_gate_register) -+ -+#define STM32_COMPOSITE_CFG(_binding, _clk, _sec_id)\ -+ STM32_CLOCK_CFG(_binding, &(_clk), _sec_id, struct clk_stm32_composite *,\ -+ &clk_stm32_composite_register) -diff --git a/drivers/clk/stm32/clk-stm32mp13.c b/drivers/clk/stm32/clk-stm32mp13.c -new file mode 100644 -index 000000000000..15ee05df8336 ---- /dev/null -+++ b/drivers/clk/stm32/clk-stm32mp13.c -@@ -0,0 +1,1760 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved -+ * Author: Gabriel Fernandez for STMicroelectronics. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "clk-stm32-core.h" -+#include "stm32mp13_rcc.h" -+ -+#define RCC_CLR 0x4 -+ -+static const char * const adc12_src[] = { -+ "pll4_r", "ck_per", "pll3_q" -+}; -+ -+static const char * const dcmipp_src[] = { -+ "ck_axi", "pll2_q", "pll4_p", "ck_per", -+}; -+ -+static const char * const eth12_src[] = { -+ "pll4_p", "pll3_q" -+}; -+ -+static const char * const fdcan_src[] = { -+ "ck_hse", "pll3_q", "pll4_q", "pll4_r" -+}; -+ -+static const char * const fmc_src[] = { -+ "ck_axi", "pll3_r", "pll4_p", "ck_per" -+}; -+ -+static const char * const i2c12_src[] = { -+ "pclk1", "pll4_r", "ck_hsi", "ck_csi" -+}; -+ -+static const char * const i2c345_src[] = { -+ "pclk6", "pll4_r", "ck_hsi", "ck_csi" -+}; -+ -+static const char * const lptim1_src[] = { -+ "pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per" -+}; -+ -+static const char * const lptim23_src[] = { -+ "pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi" -+}; -+ -+static const char * const lptim45_src[] = { -+ "pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per" -+}; -+ -+static const char * const mco1_src[] = { -+ "ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse" -+}; -+ -+static const char * const mco2_src[] = { -+ "ck_mpu", "ck_axi", "ck_mlahb", "pll4_p", "ck_hse", "ck_hsi" -+}; -+ -+static const char * const qspi_src[] = { -+ "ck_axi", "pll3_r", "pll4_p", "ck_per" -+}; -+ -+static const char * const rng1_src[] = { -+ "ck_csi", "pll4_r", "reserved", "ck_lsi" -+}; -+ -+static const char * const saes_src[] = { -+ "ck_axi", "ck_per", "pll4_r", "ck_lsi" -+}; -+ -+static const char * const sai1_src[] = { -+ "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" -+}; -+ -+static const char * const sai2_src[] = { -+ "pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb", "pll3_r" -+}; -+ -+static const char * const sdmmc12_src[] = { -+ "ck_axi", "pll3_r", "pll4_p", "ck_hsi" -+}; -+ -+static const char * const spdif_src[] = { -+ "pll4_p", "pll3_q", "ck_hsi" -+}; -+ -+static const char * const spi123_src[] = { -+ "pll4_p", "pll3_q", "i2s_ckin", "ck_per", "pll3_r" -+}; -+ -+static const char * const spi4_src[] = { -+ "pclk6", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "i2s_ckin" -+}; -+ -+static const char * const spi5_src[] = { -+ "pclk6", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" -+}; -+ -+static const char * const stgen_src[] = { -+ "ck_hsi", "ck_hse" -+}; -+ -+static const char * const usart12_src[] = { -+ "pclk6", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse" -+}; -+ -+static const char * const usart34578_src[] = { -+ "pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" -+}; -+ -+static const char * const usart6_src[] = { -+ "pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse" -+}; -+ -+static const char * const usbo_src[] = { -+ "pll4_r", "ck_usbo_48m" -+}; -+ -+static const char * const usbphy_src[] = { -+ "ck_hse", "pll4_r", "clk-hse-div2" -+}; -+ -+enum enum_gate_cfg { -+ GATE_LSE, -+ GATE_LSE_RDY, -+ GATE_LSI, -+ GATE_LSI_RDY, -+ GATE_HSI, -+ GATE_HSI_RDY, -+ GATE_CSI, -+ GATE_CSI_RDY, -+ GATE_HSE, -+ GATE_HSE_RDY, -+ GATE_PLL1, -+ GATE_PLL1_RDY, -+ GATE_PLL2, -+ GATE_PLL2_RDY, -+ GATE_PLL3, -+ GATE_PLL3_RDY, -+ GATE_PLL4, -+ GATE_PLL4_RDY, -+ GATE_HSIDIVRDY, -+ GATE_MPUSRCRDY, -+ GATE_AXISSRCRDY, -+ GATE_MCUSSRCRDY, -+ GATE_PLL12SRCRDY, -+ GATE_PLL3SRCRDY, -+ GATE_PLL4SRCRDY, -+ GATE_MPUDIVRDY, -+ GATE_AXIDIVRDY, -+ GATE_MLAHBDIVRDY, -+ GATE_APB1DIVRDY, -+ GATE_APB2DIVRDY, -+ GATE_APB3DIVRDY, -+ GATE_APB4DIVRDY, -+ GATE_APB5DIVRDY, -+ GATE_APB6DIVRDY, -+ GATE_RTCCK, -+ GATE_RTCAPB, -+ GATE_PLL1_DIVP, -+ GATE_PLL1_DIVQ, -+ GATE_PLL1_DIVR, -+ GATE_PLL2_DIVP, -+ GATE_PLL2_DIVQ, -+ GATE_PLL2_DIVR, -+ GATE_PLL3_DIVP, -+ GATE_PLL3_DIVQ, -+ GATE_PLL3_DIVR, -+ GATE_PLL4_DIVP, -+ GATE_PLL4_DIVQ, -+ GATE_PLL4_DIVR, -+ GATE_MCO1, -+ GATE_MCO2, -+ GATE_DBGCK, -+ GATE_TRACECK, -+ GATE_DDRC1, -+ GATE_DDRC1LP, -+ GATE_DDRPHYC, -+ GATE_DDRPHYCLP, -+ GATE_DDRCAPB, -+ GATE_DDRCAPBLP, -+ GATE_AXIDCG, -+ GATE_DDRPHYCAPB, -+ GATE_DDRPHYCAPBLP, -+ GATE_TIM2, -+ GATE_TIM3, -+ GATE_TIM4, -+ GATE_TIM5, -+ GATE_TIM6, -+ GATE_TIM7, -+ GATE_LPTIM1, -+ GATE_SPI2, -+ GATE_SPI3, -+ GATE_USART3, -+ GATE_UART4, -+ GATE_UART5, -+ GATE_UART7, -+ GATE_UART8, -+ GATE_I2C1, -+ GATE_I2C2, -+ GATE_SPDIF, -+ GATE_TIM1, -+ GATE_TIM8, -+ GATE_SPI1, -+ GATE_USART6, -+ GATE_SAI1, -+ GATE_SAI2, -+ GATE_DFSDM, -+ GATE_ADFSDM, -+ GATE_FDCAN, -+ GATE_LPTIM2, -+ GATE_LPTIM3, -+ GATE_LPTIM4, -+ GATE_LPTIM5, -+ GATE_VREF, -+ GATE_DTS, -+ GATE_PMBCTRL, -+ GATE_HDP, -+ GATE_SYSCFG, -+ GATE_DCMIPP, -+ GATE_DDRPERFM, -+ GATE_IWDG2APB, -+ GATE_USBPHY, -+ GATE_STGENRO, -+ GATE_LTDC, -+ GATE_TZC, -+ GATE_ETZPC, -+ GATE_IWDG1APB, -+ GATE_BSEC, -+ GATE_STGENC, -+ GATE_USART1, -+ GATE_USART2, -+ GATE_SPI4, -+ GATE_SPI5, -+ GATE_I2C3, -+ GATE_I2C4, -+ GATE_I2C5, -+ GATE_TIM12, -+ GATE_TIM13, -+ GATE_TIM14, -+ GATE_TIM15, -+ GATE_TIM16, -+ GATE_TIM17, -+ GATE_DMA1, -+ GATE_DMA2, -+ GATE_DMAMUX1, -+ GATE_DMA3, -+ GATE_DMAMUX2, -+ GATE_ADC1, -+ GATE_ADC2, -+ GATE_USBO, -+ GATE_TSC, -+ GATE_GPIOA, -+ GATE_GPIOB, -+ GATE_GPIOC, -+ GATE_GPIOD, -+ GATE_GPIOE, -+ GATE_GPIOF, -+ GATE_GPIOG, -+ GATE_GPIOH, -+ GATE_GPIOI, -+ GATE_PKA, -+ GATE_SAES, -+ GATE_CRYP1, -+ GATE_HASH1, -+ GATE_RNG1, -+ GATE_BKPSRAM, -+ GATE_AXIMC, -+ GATE_MCE, -+ GATE_ETH1CK, -+ GATE_ETH1TX, -+ GATE_ETH1RX, -+ GATE_ETH1MAC, -+ GATE_FMC, -+ GATE_QSPI, -+ GATE_SDMMC1, -+ GATE_SDMMC2, -+ GATE_CRC1, -+ GATE_USBH, -+ GATE_ETH2CK, -+ GATE_ETH2TX, -+ GATE_ETH2RX, -+ GATE_ETH2MAC, -+ GATE_ETH1STP, -+ GATE_ETH2STP, -+ GATE_MDMA, -+ GATE_NB -+}; -+ -+#define _CFG_GATE(_id, _offset, _bit_idx, _offset_clr)\ -+ [(_id)] = {\ -+ .offset = (_offset),\ -+ .bit_idx = (_bit_idx),\ -+ .set_clr = (_offset_clr),\ -+ } -+ -+#define CFG_GATE(_id, _offset, _bit_idx)\ -+ _CFG_GATE(_id, _offset, _bit_idx, 0) -+ -+#define CFG_GATE_SETCLR(_id, _offset, _bit_idx)\ -+ _CFG_GATE(_id, _offset, _bit_idx, RCC_CLR) -+ -+static struct stm32_gate_cfg stm32mp13_gates[] = { -+ CFG_GATE(GATE_LSE, RCC_BDCR, 0), -+ CFG_GATE(GATE_LSE_RDY, RCC_BDCR, 2), -+ CFG_GATE(GATE_RTCCK, RCC_BDCR, 20), -+ CFG_GATE(GATE_LSI, RCC_RDLSICR, 0), -+ CFG_GATE(GATE_LSI_RDY, RCC_RDLSICR, 1), -+ CFG_GATE_SETCLR(GATE_HSI, RCC_OCENSETR, 0), -+ CFG_GATE(GATE_HSI_RDY, RCC_OCRDYR, 0), -+ CFG_GATE_SETCLR(GATE_CSI, RCC_OCENSETR, 4), -+ CFG_GATE(GATE_CSI_RDY, RCC_OCRDYR, 4), -+ CFG_GATE_SETCLR(GATE_HSE, RCC_OCENSETR, 8), -+ CFG_GATE(GATE_HSE_RDY, RCC_OCRDYR, 8), -+ CFG_GATE(GATE_HSIDIVRDY, RCC_OCRDYR, 2), -+ CFG_GATE(GATE_MPUSRCRDY, RCC_MPCKSELR, 31), -+ CFG_GATE(GATE_AXISSRCRDY, RCC_ASSCKSELR, 31), -+ CFG_GATE(GATE_MCUSSRCRDY, RCC_MSSCKSELR, 31), -+ CFG_GATE(GATE_PLL12SRCRDY, RCC_RCK12SELR, 31), -+ CFG_GATE(GATE_PLL3SRCRDY, RCC_RCK3SELR, 31), -+ CFG_GATE(GATE_PLL4SRCRDY, RCC_RCK4SELR, 31), -+ CFG_GATE(GATE_MPUDIVRDY, RCC_MPCKDIVR, 31), -+ CFG_GATE(GATE_AXIDIVRDY, RCC_AXIDIVR, 31), -+ CFG_GATE(GATE_MLAHBDIVRDY, RCC_MLAHBDIVR, 31), -+ CFG_GATE(GATE_APB1DIVRDY, RCC_APB1DIVR, 31), -+ CFG_GATE(GATE_APB2DIVRDY, RCC_APB2DIVR, 31), -+ CFG_GATE(GATE_APB3DIVRDY, RCC_APB3DIVR, 31), -+ CFG_GATE(GATE_APB4DIVRDY, RCC_APB4DIVR, 31), -+ CFG_GATE(GATE_APB5DIVRDY, RCC_APB5DIVR, 31), -+ CFG_GATE(GATE_APB6DIVRDY, RCC_APB6DIVR, 31), -+ CFG_GATE(GATE_PLL1, RCC_PLL1CR, 0), -+ CFG_GATE(GATE_PLL1_RDY, RCC_PLL1CR, 1), -+ CFG_GATE(GATE_PLL1_DIVP, RCC_PLL1CR, 4), -+ CFG_GATE(GATE_PLL1_DIVQ, RCC_PLL1CR, 5), -+ CFG_GATE(GATE_PLL1_DIVR, RCC_PLL1CR, 6), -+ CFG_GATE(GATE_PLL2, RCC_PLL2CR, 0), -+ CFG_GATE(GATE_PLL2_RDY, RCC_PLL2CR, 1), -+ CFG_GATE(GATE_PLL2_DIVP, RCC_PLL2CR, 4), -+ CFG_GATE(GATE_PLL2_DIVQ, RCC_PLL2CR, 5), -+ CFG_GATE(GATE_PLL2_DIVR, RCC_PLL2CR, 6), -+ CFG_GATE(GATE_PLL3, RCC_PLL3CR, 0), -+ CFG_GATE(GATE_PLL3_RDY, RCC_PLL3CR, 1), -+ CFG_GATE(GATE_PLL3_DIVP, RCC_PLL3CR, 4), -+ CFG_GATE(GATE_PLL3_DIVQ, RCC_PLL3CR, 5), -+ CFG_GATE(GATE_PLL3_DIVR, RCC_PLL3CR, 6), -+ CFG_GATE(GATE_PLL4, RCC_PLL4CR, 0), -+ CFG_GATE(GATE_PLL4_RDY, RCC_PLL4CR, 1), -+ CFG_GATE(GATE_PLL4_DIVP, RCC_PLL4CR, 4), -+ CFG_GATE(GATE_PLL4_DIVQ, RCC_PLL4CR, 5), -+ CFG_GATE(GATE_PLL4_DIVR, RCC_PLL4CR, 6), -+ CFG_GATE(GATE_MCO1, RCC_MCO1CFGR, 12), -+ CFG_GATE(GATE_MCO2, RCC_MCO2CFGR, 12), -+ CFG_GATE(GATE_DBGCK, RCC_DBGCFGR, 8), -+ CFG_GATE(GATE_TRACECK, RCC_DBGCFGR, 9), -+ CFG_GATE(GATE_DDRC1, RCC_DDRITFCR, 0), -+ CFG_GATE(GATE_DDRC1LP, RCC_DDRITFCR, 1), -+ CFG_GATE(GATE_DDRPHYC, RCC_DDRITFCR, 4), -+ CFG_GATE(GATE_DDRPHYCLP, RCC_DDRITFCR, 5), -+ CFG_GATE(GATE_DDRCAPB, RCC_DDRITFCR, 6), -+ CFG_GATE(GATE_DDRCAPBLP, RCC_DDRITFCR, 7), -+ CFG_GATE(GATE_AXIDCG, RCC_DDRITFCR, 8), -+ CFG_GATE(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9), -+ CFG_GATE(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10), -+ CFG_GATE_SETCLR(GATE_TIM2, RCC_MP_APB1ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_TIM3, RCC_MP_APB1ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_TIM4, RCC_MP_APB1ENSETR, 2), -+ CFG_GATE_SETCLR(GATE_TIM5, RCC_MP_APB1ENSETR, 3), -+ CFG_GATE_SETCLR(GATE_TIM6, RCC_MP_APB1ENSETR, 4), -+ CFG_GATE_SETCLR(GATE_TIM7, RCC_MP_APB1ENSETR, 5), -+ CFG_GATE_SETCLR(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9), -+ CFG_GATE_SETCLR(GATE_SPI2, RCC_MP_APB1ENSETR, 11), -+ CFG_GATE_SETCLR(GATE_SPI3, RCC_MP_APB1ENSETR, 12), -+ CFG_GATE_SETCLR(GATE_USART3, RCC_MP_APB1ENSETR, 15), -+ CFG_GATE_SETCLR(GATE_UART4, RCC_MP_APB1ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_UART5, RCC_MP_APB1ENSETR, 17), -+ CFG_GATE_SETCLR(GATE_UART7, RCC_MP_APB1ENSETR, 18), -+ CFG_GATE_SETCLR(GATE_UART8, RCC_MP_APB1ENSETR, 19), -+ CFG_GATE_SETCLR(GATE_I2C1, RCC_MP_APB1ENSETR, 21), -+ CFG_GATE_SETCLR(GATE_I2C2, RCC_MP_APB1ENSETR, 22), -+ CFG_GATE_SETCLR(GATE_SPDIF, RCC_MP_APB1ENSETR, 26), -+ CFG_GATE_SETCLR(GATE_TIM1, RCC_MP_APB2ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_TIM8, RCC_MP_APB2ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_SPI1, RCC_MP_APB2ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_USART6, RCC_MP_APB2ENSETR, 13), -+ CFG_GATE_SETCLR(GATE_SAI1, RCC_MP_APB2ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_SAI2, RCC_MP_APB2ENSETR, 17), -+ CFG_GATE_SETCLR(GATE_DFSDM, RCC_MP_APB2ENSETR, 20), -+ CFG_GATE_SETCLR(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21), -+ CFG_GATE_SETCLR(GATE_FDCAN, RCC_MP_APB2ENSETR, 24), -+ CFG_GATE_SETCLR(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2), -+ CFG_GATE_SETCLR(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3), -+ CFG_GATE_SETCLR(GATE_VREF, RCC_MP_APB3ENSETR, 13), -+ CFG_GATE_SETCLR(GATE_DTS, RCC_MP_APB3ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17), -+ CFG_GATE_SETCLR(GATE_HDP, RCC_MP_APB3ENSETR, 20), -+ CFG_GATE_SETCLR(GATE_SYSCFG, RCC_MP_NS_APB3ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15), -+ CFG_GATE_SETCLR(GATE_USBPHY, RCC_MP_APB4ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_STGENRO, RCC_MP_APB4ENSETR, 20), -+ CFG_GATE_SETCLR(GATE_LTDC, RCC_MP_NS_APB4ENSETR, 0), -+ CFG_GATE(GATE_RTCAPB, RCC_MP_APB5ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_TZC, RCC_MP_APB5ENSETR, 11), -+ CFG_GATE_SETCLR(GATE_ETZPC, RCC_MP_APB5ENSETR, 13), -+ CFG_GATE_SETCLR(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15), -+ CFG_GATE_SETCLR(GATE_BSEC, RCC_MP_APB5ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_STGENC, RCC_MP_APB5ENSETR, 20), -+ CFG_GATE_SETCLR(GATE_USART1, RCC_MP_APB6ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_USART2, RCC_MP_APB6ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_SPI4, RCC_MP_APB6ENSETR, 2), -+ CFG_GATE_SETCLR(GATE_SPI5, RCC_MP_APB6ENSETR, 3), -+ CFG_GATE_SETCLR(GATE_I2C3, RCC_MP_APB6ENSETR, 4), -+ CFG_GATE_SETCLR(GATE_I2C4, RCC_MP_APB6ENSETR, 5), -+ CFG_GATE_SETCLR(GATE_I2C5, RCC_MP_APB6ENSETR, 6), -+ CFG_GATE_SETCLR(GATE_TIM12, RCC_MP_APB6ENSETR, 7), -+ CFG_GATE_SETCLR(GATE_TIM13, RCC_MP_APB6ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_TIM14, RCC_MP_APB6ENSETR, 9), -+ CFG_GATE_SETCLR(GATE_TIM15, RCC_MP_APB6ENSETR, 10), -+ CFG_GATE_SETCLR(GATE_TIM16, RCC_MP_APB6ENSETR, 11), -+ CFG_GATE_SETCLR(GATE_TIM17, RCC_MP_APB6ENSETR, 12), -+ CFG_GATE_SETCLR(GATE_DMA1, RCC_MP_AHB2ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_DMA2, RCC_MP_AHB2ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2), -+ CFG_GATE_SETCLR(GATE_DMA3, RCC_MP_AHB2ENSETR, 3), -+ CFG_GATE_SETCLR(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4), -+ CFG_GATE_SETCLR(GATE_ADC1, RCC_MP_AHB2ENSETR, 5), -+ CFG_GATE_SETCLR(GATE_ADC2, RCC_MP_AHB2ENSETR, 6), -+ CFG_GATE_SETCLR(GATE_USBO, RCC_MP_AHB2ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_TSC, RCC_MP_AHB4ENSETR, 15), -+ CFG_GATE_SETCLR(GATE_GPIOA, RCC_MP_NS_AHB4ENSETR, 0), -+ CFG_GATE_SETCLR(GATE_GPIOB, RCC_MP_NS_AHB4ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_GPIOC, RCC_MP_NS_AHB4ENSETR, 2), -+ CFG_GATE_SETCLR(GATE_GPIOD, RCC_MP_NS_AHB4ENSETR, 3), -+ CFG_GATE_SETCLR(GATE_GPIOE, RCC_MP_NS_AHB4ENSETR, 4), -+ CFG_GATE_SETCLR(GATE_GPIOF, RCC_MP_NS_AHB4ENSETR, 5), -+ CFG_GATE_SETCLR(GATE_GPIOG, RCC_MP_NS_AHB4ENSETR, 6), -+ CFG_GATE_SETCLR(GATE_GPIOH, RCC_MP_NS_AHB4ENSETR, 7), -+ CFG_GATE_SETCLR(GATE_GPIOI, RCC_MP_NS_AHB4ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_PKA, RCC_MP_AHB5ENSETR, 2), -+ CFG_GATE_SETCLR(GATE_SAES, RCC_MP_AHB5ENSETR, 3), -+ CFG_GATE_SETCLR(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4), -+ CFG_GATE_SETCLR(GATE_HASH1, RCC_MP_AHB5ENSETR, 5), -+ CFG_GATE_SETCLR(GATE_RNG1, RCC_MP_AHB5ENSETR, 6), -+ CFG_GATE_SETCLR(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_MCE, RCC_MP_AHB6ENSETR, 1), -+ CFG_GATE_SETCLR(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7), -+ CFG_GATE_SETCLR(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8), -+ CFG_GATE_SETCLR(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9), -+ CFG_GATE_SETCLR(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10), -+ CFG_GATE_SETCLR(GATE_FMC, RCC_MP_AHB6ENSETR, 12), -+ CFG_GATE_SETCLR(GATE_QSPI, RCC_MP_AHB6ENSETR, 14), -+ CFG_GATE_SETCLR(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16), -+ CFG_GATE_SETCLR(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17), -+ CFG_GATE_SETCLR(GATE_CRC1, RCC_MP_AHB6ENSETR, 20), -+ CFG_GATE_SETCLR(GATE_USBH, RCC_MP_AHB6ENSETR, 24), -+ CFG_GATE_SETCLR(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27), -+ CFG_GATE_SETCLR(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28), -+ CFG_GATE_SETCLR(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29), -+ CFG_GATE_SETCLR(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30), -+ CFG_GATE_SETCLR(GATE_ETH1STP, RCC_MP_AHB6LPENSETR, 11), -+ CFG_GATE_SETCLR(GATE_ETH2STP, RCC_MP_AHB6LPENSETR, 31), -+ CFG_GATE_SETCLR(GATE_MDMA, RCC_MP_NS_AHB6ENSETR, 0), -+}; -+ -+enum enum_mux_cfg { -+ MUX_MPU, -+ MUX_AXI, -+ MUX_MLAHB, -+ MUX_PLL12, -+ MUX_PLL3, -+ MUX_PLL4, -+ MUX_RTC, -+ MUX_CKPER, -+ MUX_I2C12, -+ MUX_LPTIM45, -+ MUX_SPI23, -+ MUX_UART35, -+ MUX_UART78, -+ MUX_ADC1, -+ MUX_ADC2, -+ MUX_DCMIPP, -+ MUX_ETH1, -+ MUX_ETH2, -+ MUX_FDCAN, -+ MUX_FMC, -+ MUX_I2C3, -+ MUX_I2C4, -+ MUX_I2C5, -+ MUX_LPTIM1, -+ MUX_LPTIM2, -+ MUX_LPTIM3, -+ MUX_QSPI, -+ MUX_RNG1, -+ MUX_SAES, -+ MUX_SAI1, -+ MUX_SAI2, -+ MUX_SDMMC1, -+ MUX_SDMMC2, -+ MUX_SPDIF, -+ MUX_SPI1, -+ MUX_SPI4, -+ MUX_SPI5, -+ MUX_STGEN, -+ MUX_UART1, -+ MUX_UART2, -+ MUX_UART4, -+ MUX_UART6, -+ MUX_USBO, -+ MUX_USBPHY, -+ MUX_MCO1, -+ MUX_MCO2, -+ MUX_NB -+}; -+ -+#define _CFG_MUX(_id, _offset, _shift, _witdh, _ready, _flags)\ -+ [_id] = {\ -+ .offset = (_offset),\ -+ .shift = (_shift),\ -+ .width = (_witdh),\ -+ .ready = (_ready),\ -+ .flags = (_flags),\ -+ } -+ -+#define CFG_MUX(_id, _offset, _shift, _witdh)\ -+ _CFG_MUX(_id, _offset, _shift, _witdh, MUX_NO_RDY, 0) -+ -+#define CFG_MUX_RDY(_id, _offset, _shift, _witdh, _ready)\ -+ _CFG_MUX(_id, _offset, _shift, _witdh, _ready, 0) -+ -+#define CFG_MUX_SAFE(_id, _offset, _shift, _witdh)\ -+ _CFG_MUX(_id, _offset, _shift, _witdh, MUX_NO_RDY, MUX_SAFE) -+ -+static const struct stm32_mux_cfg stm32mp13_muxes[] = { -+ CFG_MUX(MUX_MPU, RCC_MPCKSELR, 0, 2), -+ CFG_MUX(MUX_AXI, RCC_ASSCKSELR, 0, 3), -+ CFG_MUX(MUX_MLAHB, RCC_MSSCKSELR, 0, 2), -+ CFG_MUX(MUX_PLL12, RCC_RCK12SELR, 0, 2), -+ CFG_MUX(MUX_PLL3, RCC_RCK3SELR, 0, 2), -+ CFG_MUX(MUX_PLL4, RCC_RCK4SELR, 0, 2), -+ CFG_MUX(MUX_CKPER, RCC_CPERCKSELR, 0, 2), -+ CFG_MUX(MUX_RTC, RCC_BDCR, 16, 2), -+ CFG_MUX(MUX_I2C12, RCC_I2C12CKSELR, 0, 3), -+ CFG_MUX(MUX_LPTIM45, RCC_LPTIM45CKSELR, 0, 3), -+ CFG_MUX(MUX_SPI23, RCC_SPI2S23CKSELR, 0, 3), -+ CFG_MUX(MUX_UART35, RCC_UART35CKSELR, 0, 3), -+ CFG_MUX(MUX_UART78, RCC_UART78CKSELR, 0, 3), -+ CFG_MUX(MUX_ADC1, RCC_ADC12CKSELR, 0, 2), -+ CFG_MUX(MUX_ADC2, RCC_ADC12CKSELR, 2, 2), -+ CFG_MUX(MUX_DCMIPP, RCC_DCMIPPCKSELR, 0, 2), -+ CFG_MUX(MUX_ETH1, RCC_ETH12CKSELR, 0, 2), -+ CFG_MUX(MUX_ETH2, RCC_ETH12CKSELR, 8, 2), -+ CFG_MUX(MUX_FDCAN, RCC_FDCANCKSELR, 0, 2), -+ CFG_MUX(MUX_I2C3, RCC_I2C345CKSELR, 0, 3), -+ CFG_MUX(MUX_I2C4, RCC_I2C345CKSELR, 3, 3), -+ CFG_MUX(MUX_I2C5, RCC_I2C345CKSELR, 6, 3), -+ CFG_MUX(MUX_LPTIM1, RCC_LPTIM1CKSELR, 0, 3), -+ CFG_MUX(MUX_LPTIM2, RCC_LPTIM23CKSELR, 0, 3), -+ CFG_MUX(MUX_LPTIM3, RCC_LPTIM23CKSELR, 3, 3), -+ CFG_MUX(MUX_MCO1, RCC_MCO1CFGR, 0, 3), -+ CFG_MUX(MUX_MCO2, RCC_MCO2CFGR, 0, 3), -+ CFG_MUX(MUX_RNG1, RCC_RNG1CKSELR, 0, 2), -+ CFG_MUX(MUX_SAES, RCC_SAESCKSELR, 0, 2), -+ CFG_MUX(MUX_SAI1, RCC_SAI1CKSELR, 0, 3), -+ CFG_MUX(MUX_SAI2, RCC_SAI2CKSELR, 0, 3), -+ CFG_MUX(MUX_SPDIF, RCC_SPDIFCKSELR, 0, 2), -+ CFG_MUX(MUX_SPI1, RCC_SPI2S1CKSELR, 0, 3), -+ CFG_MUX(MUX_SPI4, RCC_SPI45CKSELR, 0, 3), -+ CFG_MUX(MUX_SPI5, RCC_SPI45CKSELR, 3, 3), -+ CFG_MUX(MUX_STGEN, RCC_STGENCKSELR, 0, 2), -+ CFG_MUX(MUX_UART1, RCC_UART12CKSELR, 0, 3), -+ CFG_MUX(MUX_UART2, RCC_UART12CKSELR, 3, 3), -+ CFG_MUX(MUX_UART4, RCC_UART4CKSELR, 0, 3), -+ CFG_MUX(MUX_UART6, RCC_UART6CKSELR, 0, 3), -+ CFG_MUX(MUX_USBO, RCC_USBCKSELR, 4, 1), -+ CFG_MUX(MUX_USBPHY, RCC_USBCKSELR, 0, 2), -+ -+ CFG_MUX_SAFE(MUX_FMC, RCC_FMCCKSELR, 0, 2), -+ CFG_MUX_SAFE(MUX_QSPI, RCC_QSPICKSELR, 0, 2), -+ CFG_MUX_SAFE(MUX_SDMMC1, RCC_SDMMC12CKSELR, 0, 3), -+ CFG_MUX_SAFE(MUX_SDMMC2, RCC_SDMMC12CKSELR, 3, 3), -+}; -+ -+enum enum_div_cfg { -+ DIV_PLL1DIVP, -+ DIV_PLL2DIVP, -+ DIV_PLL2DIVQ, -+ DIV_PLL2DIVR, -+ DIV_PLL3DIVP, -+ DIV_PLL3DIVQ, -+ DIV_PLL3DIVR, -+ DIV_PLL4DIVP, -+ DIV_PLL4DIVQ, -+ DIV_PLL4DIVR, -+ DIV_MPU, -+ DIV_AXI, -+ DIV_MLAHB, -+ DIV_APB1, -+ DIV_APB2, -+ DIV_APB3, -+ DIV_APB4, -+ DIV_APB5, -+ DIV_APB6, -+ DIV_RTC, -+ DIV_HSI, -+ DIV_MCO1, -+ DIV_MCO2, -+ DIV_TRACE, -+ DIV_ETH1PTP, -+ DIV_ETH2PTP, -+ DIV_NB -+}; -+ -+static const struct clk_div_table ck_trace_div_table[] = { -+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, -+ { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, -+ { 0 }, -+}; -+ -+#define CFG_DIV(_id, _offset, _shift, _width, _flags, _table, _ready)\ -+ [(_id)] = {\ -+ .offset = (_offset),\ -+ .shift = (_shift),\ -+ .width = (_width),\ -+ .flags = (_flags),\ -+ .table = (_table),\ -+ .ready = (_ready),\ -+ } -+ -+static const struct clk_div_table axi_div_table[] = { -+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, -+ { 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 }, -+ { 0 }, -+}; -+ -+static const struct clk_div_table mlahb_div_table[] = { -+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, -+ { 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 }, -+ { 8, 256 }, { 9, 512 }, { 10, 512}, { 11, 512 }, -+ { 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 }, -+ { 0 }, -+}; -+ -+static const struct clk_div_table apb_div_table[] = { -+ { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, -+ { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, -+ { 0 }, -+}; -+ -+static const struct stm32_div_cfg stm32mp13_dividers[DIV_NB] = { -+ CFG_DIV(DIV_MPU, RCC_MPCKDIVR, 0, 4, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_AXI, RCC_AXIDIVR, 0, 3, 0, axi_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_MLAHB, RCC_MLAHBDIVR, 0, 4, 0, mlahb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_APB1, RCC_APB1DIVR, 0, 3, 0, apb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_APB2, RCC_APB2DIVR, 0, 3, 0, apb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_APB3, RCC_APB3DIVR, 0, 3, 0, apb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_APB4, RCC_APB4DIVR, 0, 3, 0, apb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_APB5, RCC_APB5DIVR, 0, 3, 0, apb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_APB6, RCC_APB6DIVR, 0, 3, 0, apb_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_HSI, RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL, DIV_NO_RDY), -+ -+ CFG_DIV(DIV_PLL1DIVP, RCC_PLL1CFGR2, 0, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL2DIVP, RCC_PLL2CFGR2, 0, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL2DIVQ, RCC_PLL2CFGR2, 8, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL2DIVR, RCC_PLL2CFGR2, 16, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL3DIVP, RCC_PLL3CFGR2, 0, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL3DIVQ, RCC_PLL3CFGR2, 8, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL3DIVR, RCC_PLL3CFGR2, 16, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL4DIVP, RCC_PLL4CFGR2, 0, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL4DIVQ, RCC_PLL4CFGR2, 8, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_PLL4DIVR, RCC_PLL4CFGR2, 16, 7, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, DIV_NO_RDY), -+ -+ CFG_DIV(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_TRACE, RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table, DIV_NO_RDY), -+ CFG_DIV(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL, DIV_NO_RDY), -+ CFG_DIV(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL, DIV_NO_RDY), -+}; -+ -+struct clk_stm32_securiy { -+ u16 offset; -+ u8 bit_idx; -+}; -+ -+enum securit_clk { -+ SECF_NONE, -+ SECF_LPTIM2, -+ SECF_LPTIM3, -+ SECF_VREF, -+ SECF_DCMIPP, -+ SECF_USBPHY, -+ SECF_RTC, -+ SECF_TZC, -+ SECF_ETZPC, -+ SECF_IWDG1, -+ SECF_BSEC, -+ SECF_STGENC, -+ SECF_STGENRO, -+ SECF_USART1, -+ SECF_USART2, -+ SECF_SPI4, -+ SECF_SPI5, -+ SECF_I2C3, -+ SECF_I2C4, -+ SECF_I2C5, -+ SECF_TIM12, -+ SECF_TIM13, -+ SECF_TIM14, -+ SECF_TIM15, -+ SECF_TIM16, -+ SECF_TIM17, -+ SECF_DMA3, -+ SECF_DMAMUX2, -+ SECF_ADC1, -+ SECF_ADC2, -+ SECF_USBO, -+ SECF_TSC, -+ SECF_PKA, -+ SECF_SAES, -+ SECF_CRYP1, -+ SECF_HASH1, -+ SECF_RNG1, -+ SECF_BKPSRAM, -+ SECF_MCE, -+ SECF_FMC, -+ SECF_QSPI, -+ SECF_SDMMC1, -+ SECF_SDMMC2, -+ SECF_ETH1CK, -+ SECF_ETH1TX, -+ SECF_ETH1RX, -+ SECF_ETH1MAC, -+ SECF_ETH1STP, -+ SECF_ETH2CK, -+ SECF_ETH2TX, -+ SECF_ETH2RX, -+ SECF_ETH2MAC, -+ SECF_ETH2STP, -+ SECF_MCO1, -+ SECF_MCO2 -+}; -+ -+#define SECF(_sec_id, _offset, _bit_idx)[_sec_id] = {\ -+ .offset = _offset,\ -+ .bit_idx = _bit_idx,\ -+} -+ -+static const struct clk_stm32_securiy stm32mp13_security[] = { -+ SECF(SECF_LPTIM2, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM2SECF), -+ SECF(SECF_LPTIM3, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM3SECF), -+ SECF(SECF_VREF, RCC_APB3SECSR, RCC_APB3SECSR_VREFSECF), -+ SECF(SECF_DCMIPP, RCC_APB4SECSR, RCC_APB4SECSR_DCMIPPSECF), -+ SECF(SECF_USBPHY, RCC_APB4SECSR, RCC_APB4SECSR_USBPHYSECF), -+ SECF(SECF_RTC, RCC_APB5SECSR, RCC_APB5SECSR_RTCSECF), -+ SECF(SECF_TZC, RCC_APB5SECSR, RCC_APB5SECSR_TZCSECF), -+ SECF(SECF_ETZPC, RCC_APB5SECSR, RCC_APB5SECSR_ETZPCSECF), -+ SECF(SECF_IWDG1, RCC_APB5SECSR, RCC_APB5SECSR_IWDG1SECF), -+ SECF(SECF_BSEC, RCC_APB5SECSR, RCC_APB5SECSR_BSECSECF), -+ SECF(SECF_STGENC, RCC_APB5SECSR, RCC_APB5SECSR_STGENCSECF), -+ SECF(SECF_STGENRO, RCC_APB5SECSR, RCC_APB5SECSR_STGENROSECF), -+ SECF(SECF_USART1, RCC_APB6SECSR, RCC_APB6SECSR_USART1SECF), -+ SECF(SECF_USART2, RCC_APB6SECSR, RCC_APB6SECSR_USART2SECF), -+ SECF(SECF_SPI4, RCC_APB6SECSR, RCC_APB6SECSR_SPI4SECF), -+ SECF(SECF_SPI5, RCC_APB6SECSR, RCC_APB6SECSR_SPI5SECF), -+ SECF(SECF_I2C3, RCC_APB6SECSR, RCC_APB6SECSR_I2C3SECF), -+ SECF(SECF_I2C4, RCC_APB6SECSR, RCC_APB6SECSR_I2C4SECF), -+ SECF(SECF_I2C5, RCC_APB6SECSR, RCC_APB6SECSR_I2C5SECF), -+ SECF(SECF_TIM12, RCC_APB6SECSR, RCC_APB6SECSR_TIM12SECF), -+ SECF(SECF_TIM13, RCC_APB6SECSR, RCC_APB6SECSR_TIM13SECF), -+ SECF(SECF_TIM14, RCC_APB6SECSR, RCC_APB6SECSR_TIM14SECF), -+ SECF(SECF_TIM15, RCC_APB6SECSR, RCC_APB6SECSR_TIM15SECF), -+ SECF(SECF_TIM16, RCC_APB6SECSR, RCC_APB6SECSR_TIM16SECF), -+ SECF(SECF_TIM17, RCC_APB6SECSR, RCC_APB6SECSR_TIM17SECF), -+ SECF(SECF_DMA3, RCC_AHB2SECSR, RCC_AHB2SECSR_DMA3SECF), -+ SECF(SECF_DMAMUX2, RCC_AHB2SECSR, RCC_AHB2SECSR_DMAMUX2SECF), -+ SECF(SECF_ADC1, RCC_AHB2SECSR, RCC_AHB2SECSR_ADC1SECF), -+ SECF(SECF_ADC2, RCC_AHB2SECSR, RCC_AHB2SECSR_ADC2SECF), -+ SECF(SECF_USBO, RCC_AHB2SECSR, RCC_AHB2SECSR_USBOSECF), -+ SECF(SECF_TSC, RCC_AHB4SECSR, RCC_AHB4SECSR_TSCSECF), -+ SECF(SECF_PKA, RCC_AHB5SECSR, RCC_AHB5SECSR_PKASECF), -+ SECF(SECF_SAES, RCC_AHB5SECSR, RCC_AHB5SECSR_SAESSECF), -+ SECF(SECF_CRYP1, RCC_AHB5SECSR, RCC_AHB5SECSR_CRYP1SECF), -+ SECF(SECF_HASH1, RCC_AHB5SECSR, RCC_AHB5SECSR_HASH1SECF), -+ SECF(SECF_RNG1, RCC_AHB5SECSR, RCC_AHB5SECSR_RNG1SECF), -+ SECF(SECF_BKPSRAM, RCC_AHB5SECSR, RCC_AHB5SECSR_BKPSRAMSECF), -+ SECF(SECF_MCE, RCC_AHB6SECSR, RCC_AHB6SECSR_MCESECF), -+ SECF(SECF_FMC, RCC_AHB6SECSR, RCC_AHB6SECSR_FMCSECF), -+ SECF(SECF_QSPI, RCC_AHB6SECSR, RCC_AHB6SECSR_QSPISECF), -+ SECF(SECF_SDMMC1, RCC_AHB6SECSR, RCC_AHB6SECSR_SDMMC1SECF), -+ SECF(SECF_SDMMC2, RCC_AHB6SECSR, RCC_AHB6SECSR_SDMMC2SECF), -+ SECF(SECF_ETH1CK, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1CKSECF), -+ SECF(SECF_ETH1TX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1TXSECF), -+ SECF(SECF_ETH1RX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1RXSECF), -+ SECF(SECF_ETH1MAC, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1MACSECF), -+ SECF(SECF_ETH1STP, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1STPSECF), -+ SECF(SECF_ETH2CK, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2CKSECF), -+ SECF(SECF_ETH2TX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2TXSECF), -+ SECF(SECF_ETH2RX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2RXSECF), -+ SECF(SECF_ETH2MAC, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2MACSECF), -+ SECF(SECF_ETH2STP, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2STPSECF), -+ SECF(SECF_MCO1, RCC_SECCFGR, RCC_SECCFGR_MCO1SECF), -+ SECF(SECF_MCO2, RCC_SECCFGR, RCC_SECCFGR_MCO2SECF), -+}; -+ -+#define CLK_KER(_name, _parents, _flags, _gate_id, _mux_id)\ -+ CLK_STM32_COMPOSITE(_name, _parents, ((_flags) | CLK_OPS_PARENT_ENABLE |\ -+ CLK_SET_RATE_NO_REPARENT), _gate_id, _mux_id, NO_STM32_DIV) -+ -+static CLK_STM32_GATE(tim2_k, "timg1_ck", CLK_SET_RATE_PARENT, GATE_TIM2); -+static CLK_STM32_GATE(tim3_k, "timg1_ck", CLK_SET_RATE_PARENT, GATE_TIM3); -+static CLK_STM32_GATE(tim4_k, "timg1_ck", CLK_SET_RATE_PARENT, GATE_TIM4); -+static CLK_STM32_GATE(tim5_k, "timg1_ck", CLK_SET_RATE_PARENT, GATE_TIM5); -+static CLK_STM32_GATE(tim6_k, "timg1_ck", CLK_SET_RATE_PARENT, GATE_TIM6); -+static CLK_STM32_GATE(tim7_k, "timg1_ck", CLK_SET_RATE_PARENT, GATE_TIM7); -+static CLK_STM32_GATE(tim1_k, "timg2_ck", CLK_SET_RATE_PARENT, GATE_TIM1); -+static CLK_STM32_GATE(tim8_k, "timg2_ck", CLK_SET_RATE_PARENT, GATE_TIM8); -+static CLK_STM32_GATE(tim12_k, "timg3_ck", CLK_SET_RATE_PARENT, GATE_TIM12); -+static CLK_STM32_GATE(tim13_k, "timg3_ck", CLK_SET_RATE_PARENT, GATE_TIM13); -+static CLK_STM32_GATE(tim14_k, "timg3_ck", CLK_SET_RATE_PARENT, GATE_TIM14); -+static CLK_STM32_GATE(tim15_k, "timg3_ck", CLK_SET_RATE_PARENT, GATE_TIM15); -+static CLK_STM32_GATE(tim16_k, "timg3_ck", CLK_SET_RATE_PARENT, GATE_TIM16); -+static CLK_STM32_GATE(tim17_k, "timg3_ck", CLK_SET_RATE_PARENT, GATE_TIM17); -+ -+static CLK_STM32_GATE(spi2, "pclk1", 0, GATE_SPI2); -+static CLK_STM32_GATE(spi3, "pclk1", 0, GATE_SPI3); -+ -+static CLK_STM32_GATE(sai1, "pclk2", 0, GATE_SAI1); -+static CLK_STM32_GATE(sai2, "pclk2", 0, GATE_SAI2); -+static CLK_STM32_GATE(spi1, "pclk2", 0, GATE_SPI1); -+ -+static CLK_STM32_GATE(syscfg, "pclk3", 0, GATE_SYSCFG); -+static CLK_STM32_GATE(vref, "pclk3", 0, GATE_VREF); -+static CLK_STM32_GATE(dts, "pclk3", 0, GATE_DTS); -+static CLK_STM32_GATE(pmbctrl, "pclk3", 0, GATE_PMBCTRL); -+static CLK_STM32_GATE(hdp, "pclk3", 0, GATE_HDP); -+ -+static CLK_STM32_GATE(iwdg2, "pclk4", 0, GATE_IWDG2APB); -+static CLK_STM32_GATE(stgenro, "pclk4", 0, GATE_STGENRO); -+static CLK_STM32_GATE(gpioa, "pclk4", 0, GATE_GPIOA); -+static CLK_STM32_GATE(gpiob, "pclk4", 0, GATE_GPIOB); -+static CLK_STM32_GATE(gpioc, "pclk4", 0, GATE_GPIOC); -+static CLK_STM32_GATE(gpiod, "pclk4", 0, GATE_GPIOD); -+static CLK_STM32_GATE(gpioe, "pclk4", 0, GATE_GPIOE); -+static CLK_STM32_GATE(gpiof, "pclk4", 0, GATE_GPIOF); -+static CLK_STM32_GATE(gpiog, "pclk4", 0, GATE_GPIOG); -+static CLK_STM32_GATE(gpioh, "pclk4", 0, GATE_GPIOH); -+static CLK_STM32_GATE(gpioi, "pclk4", 0, GATE_GPIOI); -+static CLK_STM32_GATE(tsc, "pclk4", 0, GATE_TSC); -+static CLK_STM32_GATE(ddrperfm, "pclk4", 0, GATE_DDRPERFM); -+ -+static CLK_STM32_GATE(tzpc, "pclk5", 0, GATE_TZC); -+static CLK_STM32_GATE(iwdg1, "pclk5", 0, GATE_IWDG1APB); -+static CLK_STM32_GATE(bsec, "pclk5", 0, GATE_BSEC); -+ -+static CLK_STM32_GATE(spi4, "pclk6", 0, GATE_SPI4); -+static CLK_STM32_GATE(spi5, "pclk6", 0, GATE_SPI5); -+ -+static CLK_STM32_GATE(dma1, "ck_mlahb", 0, GATE_DMA1); -+static CLK_STM32_GATE(dma2, "ck_mlahb", 0, GATE_DMA2); -+static CLK_STM32_GATE(dmamux1, "ck_mlahb", 0, GATE_DMAMUX1); -+static CLK_STM32_GATE(dma3, "ck_mlahb", 0, GATE_DMA3); -+static CLK_STM32_GATE(dmamux2, "ck_mlahb", 0, GATE_DMAMUX2); -+static CLK_STM32_GATE(adc1, "ck_mlahb", 0, GATE_ADC1); -+static CLK_STM32_GATE(adc2, "ck_mlahb", 0, GATE_ADC2); -+ -+static CLK_STM32_GATE(pka, "ck_axi", 0, GATE_PKA); -+static CLK_STM32_GATE(cryp1, "ck_axi", 0, GATE_CRYP1); -+static CLK_STM32_GATE(hash1, "ck_axi", 0, GATE_HASH1); -+static CLK_STM32_GATE(bkpsram, "ck_axi", 0, GATE_BKPSRAM); -+static CLK_STM32_GATE(mdma, "ck_axi", 0, GATE_MDMA); -+static CLK_STM32_GATE(eth1tx, "ck_axi", 0, GATE_ETH1TX); -+static CLK_STM32_GATE(eth1rx, "ck_axi", 0, GATE_ETH1RX); -+static CLK_STM32_GATE(eth1mac, "ck_axi", 0, GATE_ETH1MAC); -+static CLK_STM32_GATE(eth2tx, "ck_axi", 0, GATE_ETH2TX); -+static CLK_STM32_GATE(eth2rx, "ck_axi", 0, GATE_ETH2RX); -+static CLK_STM32_GATE(eth2mac, "ck_axi", 0, GATE_ETH2MAC); -+static CLK_STM32_GATE(crc1, "ck_axi", 0, GATE_CRC1); -+static CLK_STM32_GATE(usbh, "ck_axi", 0, GATE_USBH); -+static CLK_STM32_GATE(eth1stp, "ck_axi", 0, GATE_ETH1STP); -+static CLK_STM32_GATE(eth2stp, "ck_axi", 0, GATE_ETH2STP); -+ -+static CLK_KER(sdmmc1_k, sdmmc12_src, 0, GATE_SDMMC1, MUX_SDMMC1); -+static CLK_KER(sdmmc2_k, sdmmc12_src, 0, GATE_SDMMC2, MUX_SDMMC2); -+static CLK_KER(fmc_k, fmc_src, 0, GATE_FMC, MUX_FMC); -+static CLK_KER(qspi_k, qspi_src, 0, GATE_QSPI, MUX_QSPI); -+static CLK_KER(spi2_k, spi123_src, 0, GATE_SPI2, MUX_SPI23); -+static CLK_KER(spi3_k, spi123_src, 0, GATE_SPI3, MUX_SPI23); -+static CLK_KER(i2c1_k, i2c12_src, 0, GATE_I2C1, MUX_I2C12); -+static CLK_KER(i2c2_k, i2c12_src, 0, GATE_I2C2, MUX_I2C12); -+static CLK_KER(lptim4_k, lptim45_src, 0, GATE_LPTIM4, MUX_LPTIM45); -+static CLK_KER(lptim5_k, lptim45_src, 0, GATE_LPTIM5, MUX_LPTIM45); -+static CLK_KER(usart3_k, usart34578_src, 0, GATE_USART3, MUX_UART35); -+static CLK_KER(uart5_k, usart34578_src, 0, GATE_UART5, MUX_UART35); -+static CLK_KER(uart7_k, usart34578_src, 0, GATE_UART7, MUX_UART78); -+static CLK_KER(uart8_k, usart34578_src, 0, GATE_UART8, MUX_UART78); -+static CLK_KER(sai1_k, sai1_src, 0, GATE_SAI1, MUX_SAI1); -+static CLK_KER(adfsdm_k, sai1_src, 0, GATE_ADFSDM, MUX_SAI1); -+static CLK_KER(sai2_k, sai2_src, 0, GATE_SAI2, MUX_SAI2); -+static CLK_KER(adc1_k, adc12_src, 0, GATE_ADC1, MUX_ADC1); -+static CLK_KER(adc2_k, adc12_src, 0, GATE_ADC2, MUX_ADC2); -+static CLK_KER(rng1_k, rng1_src, 0, GATE_RNG1, MUX_RNG1); -+static CLK_KER(usbphy_k, usbphy_src, 0, GATE_USBPHY, MUX_USBPHY); -+static CLK_KER(stgen_k, stgen_src, 0, GATE_STGENC, MUX_STGEN); -+static CLK_KER(spdif_k, spdif_src, 0, GATE_SPDIF, MUX_SPDIF); -+static CLK_KER(spi1_k, spi123_src, 0, GATE_SPI1, MUX_SPI1); -+static CLK_KER(spi4_k, spi4_src, 0, GATE_SPI4, MUX_SPI4); -+static CLK_KER(spi5_k, spi5_src, 0, GATE_SPI5, MUX_SPI5); -+static CLK_KER(i2c3_k, i2c345_src, 0, GATE_I2C3, MUX_I2C3); -+static CLK_KER(i2c4_k, i2c345_src, 0, GATE_I2C4, MUX_I2C4); -+static CLK_KER(i2c5_k, i2c345_src, 0, GATE_I2C5, MUX_I2C5); -+static CLK_KER(lptim1_k, lptim1_src, 0, GATE_LPTIM1, MUX_LPTIM1); -+static CLK_KER(lptim2_k, lptim23_src, 0, GATE_LPTIM2, MUX_LPTIM2); -+static CLK_KER(lptim3_k, lptim23_src, 0, GATE_LPTIM3, MUX_LPTIM3); -+static CLK_KER(usart1_k, usart12_src, 0, GATE_USART1, MUX_UART1); -+static CLK_KER(usart2_k, usart12_src, 0, GATE_USART2, MUX_UART2); -+static CLK_KER(uart4_k, usart34578_src, 0, GATE_UART4, MUX_UART4); -+static CLK_KER(uart6_k, usart6_src, 0, GATE_USART6, MUX_UART6); -+static CLK_KER(fdcan_k, fdcan_src, 0, GATE_FDCAN, MUX_FDCAN); -+static CLK_KER(dcmipp_k, dcmipp_src, 0, GATE_DCMIPP, MUX_DCMIPP); -+static CLK_KER(usbo_k, usbo_src, 0, GATE_USBO, MUX_USBO); -+static CLK_KER(eth1ck_k, eth12_src, 0, GATE_ETH1CK, MUX_ETH1); -+static CLK_KER(eth2ck_k, eth12_src, 0, GATE_ETH2CK, MUX_ETH2); -+static CLK_KER(saes_k, saes_src, 0, GATE_SAES, MUX_SAES); -+ -+static CLK_STM32_GATE(dfsdm_k, "ck_mlahb", 0, GATE_DFSDM); -+static CLK_STM32_GATE(ltdc_px, "pll4_q", CLK_SET_RATE_PARENT, GATE_LTDC); -+ -+static CLK_STM32_COMPOSITE(eth1ptp_k, eth12_src, CLK_OPS_PARENT_ENABLE | -+ CLK_SET_RATE_NO_REPARENT, -+ NO_STM32_GATE, MUX_ETH1, DIV_ETH1PTP); -+ -+static CLK_STM32_COMPOSITE(eth2ptp_k, eth12_src, CLK_OPS_PARENT_ENABLE | -+ CLK_SET_RATE_NO_REPARENT, -+ NO_STM32_GATE, MUX_ETH2, DIV_ETH2PTP); -+ -+/* MCO clocks */ -+static CLK_STM32_COMPOSITE(ck_mco1, mco1_src, CLK_OPS_PARENT_ENABLE | -+ CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, -+ GATE_MCO1, MUX_MCO1, DIV_MCO1); -+ -+static CLK_STM32_COMPOSITE(ck_mco2, mco2_src, CLK_OPS_PARENT_ENABLE | -+ CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, -+ GATE_MCO2, MUX_MCO2, DIV_MCO2); -+ -+/* Debug clocks */ -+static CLK_STM32_GATE(ck_sys_dbg, "ck_axi", CLK_IS_CRITICAL, GATE_DBGCK); -+ -+static CLK_STM32_COMPOSITE(ck_trace, PARENT("ck_axi"), CLK_IGNORE_UNUSED, -+ GATE_TRACECK, NO_STM32_MUX, DIV_TRACE); -+ -+static const struct clock_config stm32mp13_clock_cfg[] = { -+ /* Timer clocks */ -+ STM32_GATE_CFG(TIM2_K, tim2_k, SECF_NONE), -+ STM32_GATE_CFG(TIM3_K, tim3_k, SECF_NONE), -+ STM32_GATE_CFG(TIM4_K, tim4_k, SECF_NONE), -+ STM32_GATE_CFG(TIM5_K, tim5_k, SECF_NONE), -+ STM32_GATE_CFG(TIM6_K, tim6_k, SECF_NONE), -+ STM32_GATE_CFG(TIM7_K, tim7_k, SECF_NONE), -+ STM32_GATE_CFG(TIM1_K, tim1_k, SECF_NONE), -+ STM32_GATE_CFG(TIM8_K, tim8_k, SECF_NONE), -+ STM32_GATE_CFG(TIM12_K, tim12_k, SECF_TIM12), -+ STM32_GATE_CFG(TIM13_K, tim13_k, SECF_TIM13), -+ STM32_GATE_CFG(TIM14_K, tim14_k, SECF_TIM14), -+ STM32_GATE_CFG(TIM15_K, tim15_k, SECF_TIM15), -+ STM32_GATE_CFG(TIM16_K, tim16_k, SECF_TIM16), -+ STM32_GATE_CFG(TIM17_K, tim17_k, SECF_TIM17), -+ -+ /* Peripheral clocks */ -+ STM32_GATE_CFG(SPI1, spi1, SECF_NONE), -+ STM32_GATE_CFG(SPI2, spi2, SECF_NONE), -+ STM32_GATE_CFG(SPI3, spi3, SECF_NONE), -+ STM32_GATE_CFG(SPI4, spi4, SECF_SPI4), -+ STM32_GATE_CFG(SPI5, spi5, SECF_SPI5), -+ STM32_GATE_CFG(SAI1, sai1, SECF_NONE), -+ STM32_GATE_CFG(SAI2, sai2, SECF_NONE), -+ STM32_GATE_CFG(SYSCFG, syscfg, SECF_NONE), -+ STM32_GATE_CFG(VREF, vref, SECF_VREF), -+ STM32_GATE_CFG(DTS, dts, SECF_NONE), -+ STM32_GATE_CFG(PMBCTRL, pmbctrl, SECF_NONE), -+ STM32_GATE_CFG(HDP, hdp, SECF_NONE), -+ STM32_GATE_CFG(IWDG2, iwdg2, SECF_NONE), -+ STM32_GATE_CFG(STGENRO, stgenro, SECF_STGENRO), -+ STM32_GATE_CFG(TZPC, tzpc, SECF_TZC), -+ STM32_GATE_CFG(IWDG1, iwdg1, SECF_IWDG1), -+ STM32_GATE_CFG(BSEC, bsec, SECF_BSEC), -+ STM32_GATE_CFG(DMA1, dma1, SECF_NONE), -+ STM32_GATE_CFG(DMA2, dma2, SECF_NONE), -+ STM32_GATE_CFG(DMAMUX1, dmamux1, SECF_NONE), -+ STM32_GATE_CFG(DMA3, dma3, SECF_DMA3), -+ STM32_GATE_CFG(DMAMUX2, dmamux2, SECF_DMAMUX2), -+ STM32_GATE_CFG(ADC1, adc1, SECF_ADC1), -+ STM32_GATE_CFG(ADC2, adc2, SECF_ADC2), -+ STM32_GATE_CFG(GPIOA, gpioa, SECF_NONE), -+ STM32_GATE_CFG(GPIOB, gpiob, SECF_NONE), -+ STM32_GATE_CFG(GPIOC, gpioc, SECF_NONE), -+ STM32_GATE_CFG(GPIOD, gpiod, SECF_NONE), -+ STM32_GATE_CFG(GPIOE, gpioe, SECF_NONE), -+ STM32_GATE_CFG(GPIOF, gpiof, SECF_NONE), -+ STM32_GATE_CFG(GPIOG, gpiog, SECF_NONE), -+ STM32_GATE_CFG(GPIOH, gpioh, SECF_NONE), -+ STM32_GATE_CFG(GPIOI, gpioi, SECF_NONE), -+ STM32_GATE_CFG(TSC, tsc, SECF_TZC), -+ STM32_GATE_CFG(PKA, pka, SECF_PKA), -+ STM32_GATE_CFG(CRYP1, cryp1, SECF_CRYP1), -+ STM32_GATE_CFG(HASH1, hash1, SECF_HASH1), -+ STM32_GATE_CFG(BKPSRAM, bkpsram, SECF_BKPSRAM), -+ STM32_GATE_CFG(MDMA, mdma, SECF_NONE), -+ STM32_GATE_CFG(ETH1TX, eth1tx, SECF_ETH1TX), -+ STM32_GATE_CFG(ETH1RX, eth1rx, SECF_ETH1RX), -+ STM32_GATE_CFG(ETH1MAC, eth1mac, SECF_ETH1MAC), -+ STM32_GATE_CFG(ETH2TX, eth2tx, SECF_ETH2TX), -+ STM32_GATE_CFG(ETH2RX, eth2rx, SECF_ETH2RX), -+ STM32_GATE_CFG(ETH2MAC, eth2mac, SECF_ETH2MAC), -+ STM32_GATE_CFG(CRC1, crc1, SECF_NONE), -+ STM32_GATE_CFG(USBH, usbh, SECF_NONE), -+ STM32_GATE_CFG(DDRPERFM, ddrperfm, SECF_NONE), -+ STM32_GATE_CFG(ETH1STP, eth1stp, SECF_ETH1STP), -+ STM32_GATE_CFG(ETH2STP, eth2stp, SECF_ETH2STP), -+ -+ /* Kernel clocks */ -+ STM32_COMPOSITE_CFG(SDMMC1_K, sdmmc1_k, SECF_SDMMC1), -+ STM32_COMPOSITE_CFG(SDMMC2_K, sdmmc2_k, SECF_SDMMC2), -+ STM32_COMPOSITE_CFG(FMC_K, fmc_k, SECF_FMC), -+ STM32_COMPOSITE_CFG(QSPI_K, qspi_k, SECF_QSPI), -+ STM32_COMPOSITE_CFG(SPI2_K, spi2_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(SPI3_K, spi3_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(I2C1_K, i2c1_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(I2C2_K, i2c2_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(LPTIM4_K, lptim4_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(LPTIM5_K, lptim5_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(USART3_K, usart3_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(UART5_K, uart5_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(UART7_K, uart7_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(UART8_K, uart8_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(SAI1_K, sai1_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(SAI2_K, sai2_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(ADFSDM_K, adfsdm_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(ADC1_K, adc1_k, SECF_ADC1), -+ STM32_COMPOSITE_CFG(ADC2_K, adc2_k, SECF_ADC2), -+ STM32_COMPOSITE_CFG(RNG1_K, rng1_k, SECF_RNG1), -+ STM32_COMPOSITE_CFG(USBPHY_K, usbphy_k, SECF_USBPHY), -+ STM32_COMPOSITE_CFG(STGEN_K, stgen_k, SECF_STGENC), -+ STM32_COMPOSITE_CFG(SPDIF_K, spdif_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(SPI1_K, spi1_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(SPI4_K, spi4_k, SECF_SPI4), -+ STM32_COMPOSITE_CFG(SPI5_K, spi5_k, SECF_SPI5), -+ STM32_COMPOSITE_CFG(I2C3_K, i2c3_k, SECF_I2C3), -+ STM32_COMPOSITE_CFG(I2C4_K, i2c4_k, SECF_I2C4), -+ STM32_COMPOSITE_CFG(I2C5_K, i2c5_k, SECF_I2C5), -+ STM32_COMPOSITE_CFG(LPTIM1_K, lptim1_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(LPTIM2_K, lptim2_k, SECF_LPTIM2), -+ STM32_COMPOSITE_CFG(LPTIM3_K, lptim3_k, SECF_LPTIM3), -+ STM32_COMPOSITE_CFG(USART1_K, usart1_k, SECF_USART1), -+ STM32_COMPOSITE_CFG(USART2_K, usart2_k, SECF_USART2), -+ STM32_COMPOSITE_CFG(UART4_K, uart4_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(USART6_K, uart6_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(FDCAN_K, fdcan_k, SECF_NONE), -+ STM32_COMPOSITE_CFG(DCMIPP_K, dcmipp_k, SECF_DCMIPP), -+ STM32_COMPOSITE_CFG(USBO_K, usbo_k, SECF_USBO), -+ STM32_COMPOSITE_CFG(ETH1CK_K, eth1ck_k, SECF_ETH1CK), -+ STM32_COMPOSITE_CFG(ETH2CK_K, eth2ck_k, SECF_ETH2CK), -+ STM32_COMPOSITE_CFG(SAES_K, saes_k, SECF_SAES), -+ -+ STM32_GATE_CFG(DFSDM_K, dfsdm_k, SECF_NONE), -+ STM32_GATE_CFG(LTDC_PX, ltdc_px, SECF_NONE), -+ -+ STM32_COMPOSITE_CFG(ETH1PTP_K, eth1ptp_k, SECF_ETH1CK), -+ STM32_COMPOSITE_CFG(ETH2PTP_K, eth2ptp_k, SECF_ETH2CK), -+ STM32_COMPOSITE_CFG(CK_MCO1, ck_mco1, SECF_MCO1), -+ STM32_COMPOSITE_CFG(CK_MCO2, ck_mco2, SECF_MCO2), -+ -+ STM32_GATE_CFG(CK_DBG, ck_sys_dbg, SECF_NONE), -+ -+ STM32_COMPOSITE_CFG(CK_TRACE, ck_trace, SECF_NONE), -+}; -+ -+static int stm32mp13_check_security(void __iomem *base, -+ const struct clock_config *cfg) -+{ -+ int sec_id = cfg->sec_id; -+ int secured = 0; -+ -+ if (sec_id != SECF_NONE) { -+ const struct clk_stm32_securiy *secf; -+ -+ secf = &stm32mp13_security[sec_id]; -+ secured = !!(readl(base + secf->offset) & BIT(secf->bit_idx)); -+ } -+ -+ return secured; -+} -+ -+struct multi_mux { -+ struct clk_hw *hw1; -+ struct clk_hw *hw2; -+}; -+ -+static struct multi_mux *stm32_mp13_multi_mux[MUX_NB] = { -+ [MUX_SPI23] = &(struct multi_mux){ &spi2_k.hw, &spi3_k.hw }, -+ [MUX_I2C12] = &(struct multi_mux){ &i2c1_k.hw, &i2c2_k.hw }, -+ [MUX_LPTIM45] = &(struct multi_mux){ &lptim4_k.hw, &lptim5_k.hw }, -+ [MUX_UART35] = &(struct multi_mux){ &usart3_k.hw, &uart5_k.hw }, -+ [MUX_UART78] = &(struct multi_mux){ &uart7_k.hw, &uart8_k.hw }, -+ [MUX_SAI1] = &(struct multi_mux){ &sai1_k.hw, &adfsdm_k.hw }, -+}; -+ -+static struct clk_hw *clk_stm32_is_multi_mux(struct clk_hw *hw) -+{ -+ struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); -+ struct multi_mux *mmux = stm32_mp13_multi_mux[composite->mux_id]; -+ -+ if (mmux) { -+ if (!(mmux->hw1 == hw)) -+ return mmux->hw1; -+ else -+ return mmux->hw2; -+ } -+ -+ return NULL; -+} -+ -+u16 stm32mp13_cpt_gate[GATE_NB]; -+ -+#ifdef CONFIG_DEBUG_FS -+static struct clock_summary clock_summary_mp13; -+#endif -+ -+struct clk_stm32_clock_data stm32mp13_clock_data = { -+ .gate_cpt = stm32mp13_cpt_gate, -+ .gates = stm32mp13_gates, -+ .muxes = stm32mp13_muxes, -+ .dividers = stm32mp13_dividers, -+ .is_multi_mux = clk_stm32_is_multi_mux, -+}; -+ -+static const struct stm32_rcc_match_data stm32mp13_data = { -+ .tab_clocks = stm32mp13_clock_cfg, -+ .num_clocks = ARRAY_SIZE(stm32mp13_clock_cfg), -+ .clock_data = &stm32mp13_clock_data, -+ .check_security = &stm32mp13_check_security, -+ .maxbinding = STM32MP1_LAST_CLK, -+ .clear_offset = RCC_CLR, -+ .reset_us = 2, -+#ifdef CONFIG_DEBUG_FS -+ .clock_summary = &clock_summary_mp13, -+#endif -+}; -+ -+static const struct of_device_id stm32mp13_match_data[] = { -+ { -+ .compatible = "st,stm32mp13-rcc", -+ .data = &stm32mp13_data, -+ }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, stm32mp13_match_data); -+ -+ -+static int stm32mp1_rcc_init(struct device *dev) -+{ -+ void __iomem *rcc_base; -+ int ret = -ENOMEM; -+ -+ rcc_base = of_iomap(dev_of_node(dev), 0); -+ if (!rcc_base) { -+ dev_err(dev, "%pOFn: unable to map resource", dev_of_node(dev)); -+ goto out; -+ } -+ -+ ret = stm32_rcc_init(dev, stm32mp13_match_data, rcc_base); -+out: -+ if (ret) { -+ if (rcc_base) -+ iounmap(rcc_base); -+ -+ of_node_put(dev_of_node(dev)); -+ } -+ -+ return ret; -+} -+ -+static int get_clock_deps(struct device *dev) -+{ -+ static const char * const clock_deps_name[] = { -+ "hsi", "hse", "csi", "lsi", "lse", -+ }; -+ size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name); -+ struct clk **clk_deps; -+ int i; -+ -+ clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL); -+ if (!clk_deps) -+ return -ENOMEM; -+ -+ for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) { -+ struct clk *clk = of_clk_get_by_name(dev_of_node(dev), -+ clock_deps_name[i]); -+ -+ if (IS_ERR(clk)) { -+ if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT) -+ return PTR_ERR(clk); -+ } else { -+ /* Device gets a reference count on the clock */ -+ clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk)); -+ clk_put(clk); -+ } -+ } -+ -+ return 0; -+} -+ -+static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ int ret = get_clock_deps(dev); -+ -+ if (!ret) -+ ret = stm32mp1_rcc_init(dev); -+ -+ return ret; -+} -+ -+static int stm32mp1_rcc_clocks_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *child, *np = dev_of_node(dev); -+ -+ for_each_available_child_of_node(np, child) -+ of_clk_del_provider(child); -+ -+ return 0; -+} -+ -+static struct platform_driver stm32mp13_rcc_clocks_driver = { -+ .driver = { -+ .name = "stm32mp13_rcc", -+ .of_match_table = stm32mp13_match_data, -+ }, -+ .probe = stm32mp1_rcc_clocks_probe, -+ .remove = stm32mp1_rcc_clocks_remove, -+}; -+ -+static int __init stm32mp13_clocks_init(void) -+{ -+ return platform_driver_register(&stm32mp13_rcc_clocks_driver); -+} -+core_initcall(stm32mp13_clocks_init); -+ -+#ifdef CONFIG_DEBUG_FS -+ -+/* STM32 PLL */ -+struct clk_pll_fractional_divider { -+ struct clk_hw hw; -+ void __iomem *mreg; -+ u8 mshift; -+ u8 mwidth; -+ u8 mflags; -+ void __iomem *nreg; -+ u8 nshift; -+ u8 nwidth; -+ u8 nflags; -+ void __iomem *freg; -+ u8 fshift; -+ u8 fwidth; -+ -+ /* lock pll enable/disable registers */ -+ spinlock_t *lock; -+}; -+ -+struct cs_pll { -+ u32 offset; -+}; -+ -+#define PLL_BIT_ON 0 -+#define PLL_BIT_RDY 1 -+#define PLL_MUX_SHIFT 0 -+#define PLL_MUX_MASK 3 -+#define PLL_DIVMN_OFFSET 4 -+#define PLL_DIVM_SHIFT 16 -+#define PLL_DIVM_WIDTH 6 -+#define PLL_DIVN_SHIFT 0 -+#define PLL_DIVN_WIDTH 9 -+#define PLL_FRAC_OFFSET 0xC -+#define PLL_FRAC_SHIFT 3 -+#define PLL_FRAC_WIDTH 13 -+ -+static unsigned long clk_summary_pll_frac_div_recalc_rate(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ struct cs_pll *pll = (struct cs_pll *)c->data; -+ struct clk_pll_fractional_divider fracdiv; -+ struct clk_pll_fractional_divider *fd = &fracdiv; -+ void __iomem *reg; -+ u32 mmask; -+ u32 nmask; -+ u32 fmask; -+ unsigned long m, n, f; -+ u64 rate, frate = 0; -+ u32 val; -+ -+ reg = data->base + pll->offset; -+ fd->mreg = reg + PLL_DIVMN_OFFSET; -+ fd->mshift = PLL_DIVM_SHIFT; -+ fd->mwidth = PLL_DIVM_WIDTH; -+ fd->mflags = CLK_FRAC_DIVIDER_ZERO_BASED; -+ fd->nreg = reg + PLL_DIVMN_OFFSET; -+ fd->nshift = PLL_DIVN_SHIFT; -+ fd->nwidth = PLL_DIVN_WIDTH; -+ fd->nflags = CLK_FRAC_DIVIDER_ZERO_BASED; -+ fd->freg = reg + PLL_FRAC_OFFSET; -+ fd->fshift = PLL_FRAC_SHIFT; -+ fd->fwidth = PLL_FRAC_WIDTH; -+ -+ mmask = GENMASK(fd->mwidth - 1, 0) << fd->mshift; -+ nmask = GENMASK(fd->nwidth - 1, 0) << fd->nshift; -+ fmask = GENMASK(fd->fwidth - 1, 0) << fd->fshift; -+ -+ val = readl(fd->mreg); -+ m = (val & mmask) >> fd->mshift; -+ if (fd->mflags & CLK_FRAC_DIVIDER_ZERO_BASED) -+ m++; -+ -+ val = readl(fd->nreg); -+ n = (val & nmask) >> fd->nshift; -+ if (fd->nflags & CLK_FRAC_DIVIDER_ZERO_BASED) -+ n++; -+ -+ if (!n || !m) -+ return parent_rate; -+ -+ rate = (u64)parent_rate * n; -+ do_div(rate, m); -+ -+ val = readl(fd->freg); -+ f = (val & fmask) >> fd->fshift; -+ if (f) { -+ frate = (u64)parent_rate * (u64)f; -+ do_div(frate, (m * (1 << fd->fwidth))); -+ } -+ -+ return rate + frate; -+} -+ -+static unsigned long clk_summary_hsediv2_recalc_rate(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ return parent_rate / 2; -+} -+ -+static unsigned long clk_summary_osc_recalc_rate(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ struct clk *clk = __clk_lookup(c->name); -+ -+ if (clk) -+ return clk_get_rate(clk); -+ -+ return 0; -+} -+ -+static unsigned long clk_summary_div_recalc_rate(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ return clk_stm32_get_rate_divider(data->base, data, c->div_id, parent_rate); -+} -+ -+/* The divider of RTC clock concerns only ck_hse clock */ -+#define HSE_RTC 3 -+ -+static unsigned long clk_summary_rtc_recalc_rate(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ u8 parent; -+ -+ parent = clk_stm32_get_parent_mux(data->base, data, c->mux_id); -+ if (parent == HSE_RTC) -+ return clk_summary_div_recalc_rate(data, c, parent_rate); -+ -+ return parent_rate; -+} -+ -+struct cs_stm32_timer { -+ u32 apbdiv; -+ u32 timpre; -+}; -+ -+#define APB_DIV_MASK 0x07 -+#define TIM_PRE_MASK 0x01 -+ -+static unsigned long clk_stm32_timer_recalc_rate(struct clk_stm32_clock_data *data, -+ struct clk_summary *c, -+ unsigned long parent_rate) -+{ -+ struct cs_stm32_timer *tim = (struct cs_stm32_timer *)c->data; -+ void __iomem *rcc_base = data->base; -+ u32 prescaler, timpre; -+ -+ prescaler = readl(rcc_base + tim->apbdiv) & APB_DIV_MASK; -+ -+ timpre = readl(rcc_base + tim->timpre) & TIM_PRE_MASK; -+ -+ if (prescaler == 0U) -+ return parent_rate; -+ -+ return parent_rate * (timpre + 1U) * 2U; -+} -+ -+#define CS_OSC(_name, _gate) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 0,\ -+ .gate_id = _gate,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = NO_STM32_DIV,\ -+ .get_rate = clk_summary_osc_recalc_rate,\ -+} -+#define CS_DIV2(_name, _parent) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .gate_id = NO_STM32_GATE,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = NO_STM32_DIV,\ -+ .get_rate = clk_summary_hsediv2_recalc_rate,\ -+} -+ -+#define CS_PLL(_name, _parents, _gate, _mux, _offset)\ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = NO_STM32_DIV,\ -+ .data = &(struct cs_pll) {\ -+ .offset = _offset,\ -+ },\ -+ .get_rate = clk_summary_pll_frac_div_recalc_rate,\ -+} -+ -+#define CS_DIV(_name, _parent, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .div_id = _div,\ -+ .gate_id = NO_STM32_GATE,\ -+ .mux_id = NO_STM32_MUX,\ -+ .get_rate = clk_summary_div_recalc_rate,\ -+} -+ -+#define CS_MUX(_name, _parents, _mux) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .mux_id = _mux,\ -+ .gate_id = NO_STM32_GATE,\ -+ .div_id = NO_STM32_DIV,\ -+} -+ -+#define CS_GATE(_name, _parent, _gate) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .gate_id = _gate,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = NO_STM32_DIV,\ -+} -+ -+#define CS_GATEDIV(_name, _parent, _gate, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .gate_id = _gate,\ -+ .mux_id = NO_STM32_MUX,\ -+ .div_id = _div,\ -+ .get_rate = clk_summary_div_recalc_rate,\ -+} -+ -+#define CS_GATEMUX(_name, _parents, _gate, _mux) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = NO_STM32_DIV,\ -+} -+ -+#define CS_COMPOSITE(_name, _parents, _gate, _mux, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = ARRAY_SIZE(_parents),\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = _div,\ -+ .get_rate = clk_summary_div_recalc_rate,\ -+} -+ -+#define CS_RTC(_name, _parents, _gate, _mux, _div) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 4,\ -+ .parent_names = _parents,\ -+ .gate_id = _gate,\ -+ .mux_id = _mux,\ -+ .div_id = _div,\ -+ .get_rate = clk_summary_rtc_recalc_rate,\ -+} -+ -+#define CS_STM32_TIMER(_name, _parent, _apbdiv, _timpre) \ -+{\ -+ .name = _name,\ -+ .nb_parents = 1,\ -+ .parent_names = PARENT(_parent),\ -+ .div_id = NO_STM32_DIV,\ -+ .gate_id = NO_STM32_GATE,\ -+ .mux_id = NO_STM32_MUX,\ -+ .data = &(struct cs_stm32_timer) {\ -+ .apbdiv = _apbdiv,\ -+ .timpre = _timpre,\ -+ },\ -+ .get_rate = clk_stm32_timer_recalc_rate,\ -+} -+ -+static const char * const ref12_parents[] = { -+ "ck_hsi", "ck_hse" -+}; -+ -+static const char * const ref3_parents[] = { -+ "ck_hsi", "ck_hse", "ck_csi" -+}; -+ -+static const char * const ref4_parents[] = { -+ "ck_hsi", "ck_hse", "ck_csi", "i2s_ckin" -+}; -+ -+static const char * const cpu_src[] = { -+ "ck_hsi", "ck_hse", "pll1_p", "pll1_p_div" -+}; -+ -+static const char * const axi_src[] = { -+ "ck_hsi", "ck_hse", "pll2_p" -+}; -+ -+static const char * const mlahb_src[] = { -+ "ck_hsi", "ck_hse", "ck_csi", "pll3_p" -+}; -+ -+static const char * const per_src[] = { -+ "ck_hsi", "ck_csi", "ck_hse" -+}; -+ -+static const char * const rtc_src[] = { -+ "off", "ck_lse", "ck_lsi", "ck_hse" -+}; -+ -+static struct clk_summary stm32mp13_clock_summary[] = { -+ CS_OSC("ck_hsi", GATE_HSI), -+ CS_OSC("ck_csi", GATE_CSI), -+ CS_OSC("ck_lsi", GATE_LSI), -+ CS_OSC("ck_hse", GATE_HSE), -+ CS_OSC("ck_lse", GATE_LSE), -+ -+ CS_OSC("ck_usbo_48m", NO_STM32_GATE), -+ CS_DIV2("clk-hse-div2", "ck_hse"), -+ -+ CS_PLL("pll1", ref12_parents, GATE_PLL1, MUX_PLL12, RCC_PLL1CR), -+ -+ CS_GATEDIV("pll1_p", "pll1", GATE_PLL1_DIVP, DIV_PLL1DIVP), -+ -+ CS_DIV("pll1_p_div", "pll1_p", DIV_MPU), -+ -+ CS_PLL("pll2", ref12_parents, GATE_PLL2, MUX_PLL12, RCC_PLL2CR), -+ CS_GATEDIV("pll2_p", "pll2", GATE_PLL2_DIVP, DIV_PLL2DIVP), -+ CS_GATEDIV("pll2_q", "pll2", GATE_PLL2_DIVQ, DIV_PLL2DIVQ), -+ CS_GATEDIV("pll2_r", "pll2", GATE_PLL2_DIVR, DIV_PLL2DIVR), -+ -+ CS_PLL("pll3", ref3_parents, GATE_PLL3, MUX_PLL3, RCC_PLL3CR), -+ CS_GATEDIV("pll3_p", "pll3", GATE_PLL3_DIVP, DIV_PLL3DIVP), -+ CS_GATEDIV("pll3_q", "pll3", GATE_PLL3_DIVQ, DIV_PLL3DIVQ), -+ CS_GATEDIV("pll3_r", "pll3", GATE_PLL3_DIVR, DIV_PLL3DIVR), -+ -+ CS_PLL("pll4", ref4_parents, GATE_PLL4, MUX_PLL4, RCC_PLL4CR), -+ CS_GATEDIV("pll4_p", "pll4", GATE_PLL4_DIVP, DIV_PLL4DIVP), -+ CS_GATEDIV("pll4_q", "pll4", GATE_PLL4_DIVQ, DIV_PLL4DIVQ), -+ CS_GATEDIV("pll4_r", "pll4", GATE_PLL4_DIVR, DIV_PLL4DIVR), -+ -+ CS_MUX("ck_mpu", cpu_src, MUX_MPU), -+ CS_MUX("ck_axi", axi_src, MUX_AXI), -+ CS_MUX("ck_mlahb", mlahb_src, MUX_MLAHB), -+ CS_MUX("ck_per", per_src, MUX_CKPER), -+ -+ CS_DIV("pclk1", "ck_mlahb", DIV_APB1), -+ CS_DIV("pclk2", "ck_mlahb", DIV_APB2), -+ CS_DIV("pclk3", "ck_mlahb", DIV_APB3), -+ CS_DIV("pclk4", "ck_axi", DIV_APB4), -+ CS_DIV("pclk5", "ck_axi", DIV_APB5), -+ CS_DIV("pclk6", "ck_mlahb", DIV_APB6), -+ -+ CS_STM32_TIMER("timg1_ck", "pclk1", RCC_APB1DIVR, RCC_TIMG1PRER), -+ CS_STM32_TIMER("timg2_ck", "pclk2", RCC_APB2DIVR, RCC_TIMG2PRER), -+ CS_STM32_TIMER("timg3_ck", "pclk1", RCC_APB6DIVR, RCC_TIMG3PRER), -+ -+ CS_GATE("tim2_k", "timg1_ck", GATE_TIM2), -+ CS_GATE("tim3_k", "timg1_ck", GATE_TIM3), -+ CS_GATE("tim4_k", "timg1_ck", GATE_TIM4), -+ CS_GATE("tim5_k", "timg1_ck", GATE_TIM5), -+ CS_GATE("tim6_k", "timg1_ck", GATE_TIM6), -+ CS_GATE("tim7_k", "timg1_ck", GATE_TIM7), -+ CS_GATE("tim1_k", "timg2_ck", GATE_TIM1), -+ CS_GATE("tim8_k", "timg2_ck", GATE_TIM8), -+ CS_GATE("tim12_k", "timg3_ck", GATE_TIM12), -+ CS_GATE("tim13_k", "timg3_ck", GATE_TIM13), -+ CS_GATE("tim14_k", "timg3_ck", GATE_TIM14), -+ CS_GATE("tim15_k", "timg3_ck", GATE_TIM15), -+ CS_GATE("tim16_k", "timg3_ck", GATE_TIM16), -+ CS_GATE("tim17_k", "timg3_ck", GATE_TIM17), -+ -+ CS_GATE("spi2", "pclk1", GATE_SPI2), -+ CS_GATE("spi3", "pclk1", GATE_SPI3), -+ -+ CS_GATE("sai1", "pclk2", GATE_SAI1), -+ CS_GATE("sai2", "pclk2", GATE_SAI2), -+ CS_GATE("spi1", "pclk2", GATE_SPI1), -+ -+ CS_GATE("syscfg", "pclk3", GATE_SYSCFG), -+ CS_GATE("vref", "pclk3", GATE_VREF), -+ CS_GATE("dts", "pclk3", GATE_DTS), -+ CS_GATE("pmbctrl", "pclk3", GATE_PMBCTRL), -+ CS_GATE("hdp", "pclk3", GATE_HDP), -+ -+ CS_GATE("iwdg2", "pclk4", GATE_IWDG2APB), -+ CS_GATE("stgenro", "pclk4", GATE_STGENRO), -+ CS_GATE("gpioa", "pclk4", GATE_GPIOA), -+ CS_GATE("gpiob", "pclk4", GATE_GPIOB), -+ CS_GATE("gpioc", "pclk4", GATE_GPIOC), -+ CS_GATE("gpiod", "pclk4", GATE_GPIOD), -+ CS_GATE("gpioe", "pclk4", GATE_GPIOE), -+ CS_GATE("gpiof", "pclk4", GATE_GPIOF), -+ CS_GATE("gpiog", "pclk4", GATE_GPIOG), -+ CS_GATE("gpioh", "pclk4", GATE_GPIOH), -+ CS_GATE("gpioi", "pclk4", GATE_GPIOI), -+ CS_GATE("tsc", "pclk4", GATE_TSC), -+ CS_GATE("ddrperfm", "pclk4", GATE_DDRPERFM), -+ -+ CS_GATE("tzpc", "pclk5", GATE_TZC), -+ CS_GATE("iwdg1", "pclk5", GATE_IWDG1APB), -+ CS_GATE("bsec", "pclk5", GATE_BSEC), -+ -+ CS_GATE("spi4", "pclk6", GATE_SPI4), -+ CS_GATE("spi5", "pclk6", GATE_SPI5), -+ -+ CS_GATE("dma1", "ck_mlahb", GATE_DMA1), -+ CS_GATE("dma2", "ck_mlahb", GATE_DMA2), -+ CS_GATE("dmamux1", "ck_mlahb", GATE_DMAMUX1), -+ CS_GATE("dma3", "ck_mlahb", GATE_DMA3), -+ CS_GATE("dmamux2", "ck_mlahb", GATE_DMAMUX2), -+ CS_GATE("adc1", "ck_mlahb", GATE_ADC1), -+ CS_GATE("adc2", "ck_mlahb", GATE_ADC2), -+ -+ CS_GATE("pka", "ck_axi", GATE_PKA), -+ CS_GATE("cryp1", "ck_axi", GATE_CRYP1), -+ CS_GATE("hash1", "ck_axi", GATE_HASH1), -+ CS_GATE("bkpsram", "ck_axi", GATE_BKPSRAM), -+ CS_GATE("mdma", "ck_axi", GATE_MDMA), -+ CS_GATE("eth1tx", "ck_axi", GATE_ETH1TX), -+ CS_GATE("eth1rx", "ck_axi", GATE_ETH1RX), -+ CS_GATE("eth1mac", "ck_axi", GATE_ETH1MAC), -+ CS_GATE("eth2tx", "ck_axi", GATE_ETH2TX), -+ CS_GATE("eth2rx", "ck_axi", GATE_ETH2RX), -+ CS_GATE("eth2mac", "ck_axi", GATE_ETH2MAC), -+ CS_GATE("crc1", "ck_axi", GATE_CRC1), -+ CS_GATE("usbh", "ck_axi", GATE_USBH), -+ CS_GATE("eth1stp", "ck_axi", GATE_ETH1STP), -+ CS_GATE("eth2stp", "ck_axi", GATE_ETH2STP), -+ -+ CS_GATEMUX("sdmmc1_k", sdmmc12_src, GATE_SDMMC1, MUX_SDMMC1), -+ CS_GATEMUX("sdmmc2_k", sdmmc12_src, GATE_SDMMC2, MUX_SDMMC2), -+ CS_GATEMUX("fmc_k", fmc_src, GATE_FMC, MUX_FMC), -+ CS_GATEMUX("qspi_k", qspi_src, GATE_QSPI, MUX_QSPI), -+ CS_GATEMUX("spi2_k", spi123_src, GATE_SPI2, MUX_SPI23), -+ CS_GATEMUX("spi3_k", spi123_src, GATE_SPI3, MUX_SPI23), -+ CS_GATEMUX("i2c1_k", i2c12_src, GATE_I2C1, MUX_I2C12), -+ CS_GATEMUX("i2c2_k", i2c12_src, GATE_I2C2, MUX_I2C12), -+ CS_GATEMUX("lptim4_k", lptim45_src, GATE_LPTIM4, MUX_LPTIM45), -+ CS_GATEMUX("lptim5_k", lptim45_src, GATE_LPTIM5, MUX_LPTIM45), -+ CS_GATEMUX("usart3_k", usart34578_src, GATE_USART3, MUX_UART35), -+ CS_GATEMUX("uart5_k", usart34578_src, GATE_UART5, MUX_UART35), -+ CS_GATEMUX("uart7_k", usart34578_src, GATE_UART7, MUX_UART78), -+ CS_GATEMUX("uart8_k", usart34578_src, GATE_UART8, MUX_UART78), -+ CS_GATEMUX("sai1_k", sai1_src, GATE_SAI1, MUX_SAI1), -+ CS_GATEMUX("adfsdm_k", sai1_src, GATE_ADFSDM, MUX_SAI1), -+ CS_GATEMUX("sai2_k", sai2_src, GATE_SAI2, MUX_SAI2), -+ CS_GATEMUX("adc1_k", adc12_src, GATE_ADC1, MUX_ADC1), -+ CS_GATEMUX("adc2_k", adc12_src, GATE_ADC2, MUX_ADC2), -+ CS_GATEMUX("rng1_k", rng1_src, GATE_RNG1, MUX_RNG1), -+ CS_GATEMUX("usbphy_k", usbphy_src, GATE_USBPHY, MUX_USBPHY), -+ CS_GATEMUX("stgen_k", stgen_src, GATE_STGENC, MUX_STGEN), -+ CS_GATEMUX("spdif_k", spdif_src, GATE_SPDIF, MUX_SPDIF), -+ CS_GATEMUX("spi1_k", spi123_src, GATE_SPI1, MUX_SPI1), -+ CS_GATEMUX("spi4_k", spi4_src, GATE_SPI4, MUX_SPI4), -+ CS_GATEMUX("spi5_k", spi5_src, GATE_SPI5, MUX_SPI5), -+ CS_GATEMUX("i2c3_k", i2c345_src, GATE_I2C3, MUX_I2C3), -+ CS_GATEMUX("i2c4_k", i2c345_src, GATE_I2C4, MUX_I2C4), -+ CS_GATEMUX("i2c5_k", i2c345_src, GATE_I2C5, MUX_I2C5), -+ CS_GATEMUX("lptim1_k", lptim1_src, GATE_LPTIM1, MUX_LPTIM1), -+ CS_GATEMUX("lptim2_k", lptim23_src, GATE_LPTIM2, MUX_LPTIM2), -+ CS_GATEMUX("lptim3_k", lptim23_src, GATE_LPTIM3, MUX_LPTIM3), -+ CS_GATEMUX("usart1_k", usart12_src, GATE_USART1, MUX_UART1), -+ CS_GATEMUX("usart2_k", usart12_src, GATE_USART2, MUX_UART2), -+ CS_GATEMUX("uart4_k", usart34578_src, GATE_UART4, MUX_UART4), -+ CS_GATEMUX("uart6_k", usart6_src, GATE_USART6, MUX_UART6), -+ CS_GATEMUX("fdcan_k", fdcan_src, GATE_FDCAN, MUX_FDCAN), -+ CS_GATEMUX("dcmipp_k", dcmipp_src, GATE_DCMIPP, MUX_DCMIPP), -+ CS_GATEMUX("usbo_k", usbo_src, GATE_USBO, MUX_USBO), -+ CS_GATEMUX("eth1ck_k", eth12_src, GATE_ETH1CK, MUX_ETH1), -+ CS_GATEMUX("eth2ck_k", eth12_src, GATE_ETH2CK, MUX_ETH2), -+ CS_GATEMUX("saes_k", saes_src, GATE_SAES, MUX_SAES), -+ CS_GATE("dfsdm_k", "ck_mlahb", GATE_DFSDM), -+ CS_GATE("ltdc_px", "pll4_q", GATE_LTDC), -+ CS_COMPOSITE("eth1ptp_k", eth12_src, NO_STM32_GATE, MUX_ETH1, DIV_ETH1PTP), -+ CS_COMPOSITE("eth2ptp_k", eth12_src, NO_STM32_GATE, MUX_ETH2, DIV_ETH2PTP), -+ CS_COMPOSITE("ck_mco1", mco1_src, GATE_MCO1, MUX_MCO1, DIV_MCO1), -+ CS_COMPOSITE("ck_mco2", mco2_src, GATE_MCO2, MUX_MCO2, DIV_MCO2), -+ CS_GATE("ck_sys_dbg", "ck_axi", GATE_DBGCK), -+ CS_GATEDIV("ck_trace", "ck_axi", GATE_TRACECK, DIV_TRACE), -+ CS_GATE("rtcapb", "pclk5", GATE_RTCAPB), -+ CS_RTC("ck_rtc", rtc_src, GATE_RTCCK, MUX_RTC, DIV_RTC), -+}; -+ -+static struct clock_summary clock_summary_mp13 = { -+ .clocks = stm32mp13_clock_summary, -+ .nb_clocks = ARRAY_SIZE(stm32mp13_clock_summary), -+}; -+ -+ -+#endif -diff --git a/drivers/clk/stm32/reset-stm32.c b/drivers/clk/stm32/reset-stm32.c -new file mode 100644 -index 000000000000..8239b154ad86 ---- /dev/null -+++ b/drivers/clk/stm32/reset-stm32.c -@@ -0,0 +1,161 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved -+ * Author: Gabriel Fernandez for STMicroelectronics. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk-stm32-core.h" -+ -+#define STM32_RESET_ID_MASK GENMASK(15, 0) -+ -+struct stm32_reset_data { -+ /* reset lock */ -+ spinlock_t lock; -+ struct reset_controller_dev rcdev; -+ void __iomem *membase; -+ u32 clear_offset; -+ unsigned int reset_us; -+}; -+ -+static inline struct stm32_reset_data * -+to_stm32_reset_data(struct reset_controller_dev *rcdev) -+{ -+ return container_of(rcdev, struct stm32_reset_data, rcdev); -+} -+ -+static int stm32_reset_update(struct reset_controller_dev *rcdev, -+ unsigned long id, bool assert) -+{ -+ struct stm32_reset_data *data = to_stm32_reset_data(rcdev); -+ int reg_width = sizeof(u32); -+ int bank = id / (reg_width * BITS_PER_BYTE); -+ int offset = id % (reg_width * BITS_PER_BYTE); -+ -+ if (data->clear_offset) { -+ void __iomem *addr; -+ -+ addr = data->membase + (bank * reg_width); -+ if (!assert) -+ addr += data->clear_offset; -+ -+ writel(BIT(offset), addr); -+ -+ } else { -+ unsigned long flags; -+ u32 reg; -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ reg = readl(data->membase + (bank * reg_width)); -+ -+ if (assert) -+ reg |= BIT(offset); -+ else -+ reg &= ~BIT(offset); -+ -+ writel(reg, data->membase + (bank * reg_width)); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ } -+ -+ return 0; -+} -+ -+static int stm32_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return stm32_reset_update(rcdev, id, true); -+} -+ -+static int stm32_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return stm32_reset_update(rcdev, id, false); -+} -+ -+static int stm32_reset_status(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct stm32_reset_data *data = to_stm32_reset_data(rcdev); -+ int reg_width = sizeof(u32); -+ int bank = id / (reg_width * BITS_PER_BYTE); -+ int offset = id % (reg_width * BITS_PER_BYTE); -+ u32 reg; -+ -+ reg = readl(data->membase + (bank * reg_width)); -+ -+ return !!(reg & BIT(offset)); -+} -+ -+static int stm32_check_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct stm32_reset_data *data = to_stm32_reset_data(rcdev); -+ int reg_width = sizeof(u32); -+ int bank = id / (reg_width * BITS_PER_BYTE); -+ int offset = id % (reg_width * BITS_PER_BYTE); -+ u32 reg; -+ -+ return readl_poll_timeout(data->membase + (bank * reg_width), reg, -+ !(reg & BIT(offset)), 10, 10 * USEC_PER_MSEC); -+} -+ -+static int stm32_reset(struct reset_controller_dev *rcdev, unsigned long id) -+{ -+ struct stm32_reset_data *data = to_stm32_reset_data(rcdev); -+ int ret; -+ -+ ret = stm32_reset_assert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ if (!data->reset_us) -+ usleep_range(data->reset_us, data->reset_us * 2); -+ -+ ret = stm32_reset_deassert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ ret = stm32_check_deassert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static const struct reset_control_ops stm32_reset_ops = { -+ .assert = stm32_reset_assert, -+ .deassert = stm32_reset_deassert, -+ .reset = stm32_reset, -+ .status = stm32_reset_status, -+}; -+ -+int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match, -+ void __iomem *base) -+{ -+ const struct stm32_rcc_match_data *data = match->data; -+ struct stm32_reset_data *reset_data = NULL; -+ -+ data = match->data; -+ -+ reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); -+ if (!reset_data) -+ return -ENOMEM; -+ -+ reset_data->membase = base; -+ reset_data->rcdev.owner = THIS_MODULE; -+ reset_data->rcdev.ops = &stm32_reset_ops; -+ reset_data->rcdev.of_node = dev_of_node(dev); -+ reset_data->rcdev.nr_resets = STM32_RESET_ID_MASK; -+ reset_data->clear_offset = data->clear_offset; -+ reset_data->reset_us = data->reset_us; -+ -+ return reset_controller_register(&reset_data->rcdev); -+} -diff --git a/drivers/clk/stm32/reset-stm32.h b/drivers/clk/stm32/reset-stm32.h -new file mode 100644 -index 000000000000..63a4a35b5b5a ---- /dev/null -+++ b/drivers/clk/stm32/reset-stm32.h -@@ -0,0 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) STMicroelectronics 2021 - All Rights Reserved -+ * Author: Gabriel Fernandez for STMicroelectronics. -+ */ -+ -+int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match, void __iomem *base); -diff --git a/drivers/clk/stm32/stm32mp13_rcc.h b/drivers/clk/stm32/stm32mp13_rcc.h -new file mode 100644 -index 000000000000..f01a98c8563f ---- /dev/null -+++ b/drivers/clk/stm32/stm32mp13_rcc.h -@@ -0,0 +1,1751 @@ -+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ -+/* -+ * Copyright (C) 2020, STMicroelectronics - All Rights Reserved -+ * -+ * Configuration settings for the STM32MP13x CPU -+ */ -+ -+#ifndef STM32MP13_RCC_H -+#define STM32MP13_RCC_H -+/* RCC registers */ -+#define RCC_SECCFGR 0x0 -+#define RCC_MP_SREQSETR 0x100 -+#define RCC_MP_SREQCLRR 0x104 -+#define RCC_MP_APRSTCR 0x108 -+#define RCC_MP_APRSTSR 0x10c -+#define RCC_PWRLPDLYCR 0x110 -+#define RCC_MP_GRSTCSETR 0x114 -+#define RCC_BR_RSTSCLRR 0x118 -+#define RCC_MP_RSTSSETR 0x11c -+#define RCC_MP_RSTSCLRR 0x120 -+#define RCC_MP_IWDGFZSETR 0x124 -+#define RCC_MP_IWDGFZCLRR 0x128 -+#define RCC_MP_CIER 0x200 -+#define RCC_MP_CIFR 0x204 -+#define RCC_BDCR 0x400 -+#define RCC_RDLSICR 0x404 -+#define RCC_OCENSETR 0x420 -+#define RCC_OCENCLRR 0x424 -+#define RCC_OCRDYR 0x428 -+#define RCC_HSICFGR 0x440 -+#define RCC_CSICFGR 0x444 -+#define RCC_MCO1CFGR 0x460 -+#define RCC_MCO2CFGR 0x464 -+#define RCC_DBGCFGR 0x468 -+#define RCC_RCK12SELR 0x480 -+#define RCC_RCK3SELR 0x484 -+#define RCC_RCK4SELR 0x488 -+#define RCC_PLL1CR 0x4a0 -+#define RCC_PLL1CFGR1 0x4a4 -+#define RCC_PLL1CFGR2 0x4a8 -+#define RCC_PLL1FRACR 0x4ac -+#define RCC_PLL1CSGR 0x4b0 -+#define RCC_PLL2CR 0x4d0 -+#define RCC_PLL2CFGR1 0x4d4 -+#define RCC_PLL2CFGR2 0x4d8 -+#define RCC_PLL2FRACR 0x4dc -+#define RCC_PLL2CSGR 0x4e0 -+#define RCC_PLL3CR 0x500 -+#define RCC_PLL3CFGR1 0x504 -+#define RCC_PLL3CFGR2 0x508 -+#define RCC_PLL3FRACR 0x50c -+#define RCC_PLL3CSGR 0x510 -+#define RCC_PLL4CR 0x520 -+#define RCC_PLL4CFGR1 0x524 -+#define RCC_PLL4CFGR2 0x528 -+#define RCC_PLL4FRACR 0x52c -+#define RCC_PLL4CSGR 0x530 -+#define RCC_MPCKSELR 0x540 -+#define RCC_ASSCKSELR 0x544 -+#define RCC_MSSCKSELR 0x548 -+#define RCC_CPERCKSELR 0x54c -+#define RCC_RTCDIVR 0x560 -+#define RCC_MPCKDIVR 0x564 -+#define RCC_AXIDIVR 0x568 -+#define RCC_MLAHBDIVR 0x56c -+#define RCC_APB1DIVR 0x570 -+#define RCC_APB2DIVR 0x574 -+#define RCC_APB3DIVR 0x578 -+#define RCC_APB4DIVR 0x57c -+#define RCC_APB5DIVR 0x580 -+#define RCC_APB6DIVR 0x584 -+#define RCC_TIMG1PRER 0x5a0 -+#define RCC_TIMG2PRER 0x5a4 -+#define RCC_TIMG3PRER 0x5a8 -+#define RCC_DDRITFCR 0x5c0 -+#define RCC_I2C12CKSELR 0x600 -+#define RCC_I2C345CKSELR 0x604 -+#define RCC_SPI2S1CKSELR 0x608 -+#define RCC_SPI2S23CKSELR 0x60c -+#define RCC_SPI45CKSELR 0x610 -+#define RCC_UART12CKSELR 0x614 -+#define RCC_UART35CKSELR 0x618 -+#define RCC_UART4CKSELR 0x61c -+#define RCC_UART6CKSELR 0x620 -+#define RCC_UART78CKSELR 0x624 -+#define RCC_LPTIM1CKSELR 0x628 -+#define RCC_LPTIM23CKSELR 0x62c -+#define RCC_LPTIM45CKSELR 0x630 -+#define RCC_SAI1CKSELR 0x634 -+#define RCC_SAI2CKSELR 0x638 -+#define RCC_FDCANCKSELR 0x63c -+#define RCC_SPDIFCKSELR 0x640 -+#define RCC_ADC12CKSELR 0x644 -+#define RCC_SDMMC12CKSELR 0x648 -+#define RCC_ETH12CKSELR 0x64c -+#define RCC_USBCKSELR 0x650 -+#define RCC_QSPICKSELR 0x654 -+#define RCC_FMCCKSELR 0x658 -+#define RCC_RNG1CKSELR 0x65c -+#define RCC_STGENCKSELR 0x660 -+#define RCC_DCMIPPCKSELR 0x664 -+#define RCC_SAESCKSELR 0x668 -+#define RCC_APB1RSTSETR 0x6a0 -+#define RCC_APB1RSTCLRR 0x6a4 -+#define RCC_APB2RSTSETR 0x6a8 -+#define RCC_APB2RSTCLRR 0x6ac -+#define RCC_APB3RSTSETR 0x6b0 -+#define RCC_APB3RSTCLRR 0x6b4 -+#define RCC_APB4RSTSETR 0x6b8 -+#define RCC_APB4RSTCLRR 0x6bc -+#define RCC_APB5RSTSETR 0x6c0 -+#define RCC_APB5RSTCLRR 0x6c4 -+#define RCC_APB6RSTSETR 0x6c8 -+#define RCC_APB6RSTCLRR 0x6cc -+#define RCC_AHB2RSTSETR 0x6d0 -+#define RCC_AHB2RSTCLRR 0x6d4 -+#define RCC_AHB4RSTSETR 0x6e0 -+#define RCC_AHB4RSTCLRR 0x6e4 -+#define RCC_AHB5RSTSETR 0x6e8 -+#define RCC_AHB5RSTCLRR 0x6ec -+#define RCC_AHB6RSTSETR 0x6f0 -+#define RCC_AHB6RSTCLRR 0x6f4 -+#define RCC_MP_APB1ENSETR 0x700 -+#define RCC_MP_APB1ENCLRR 0x704 -+#define RCC_MP_APB2ENSETR 0x708 -+#define RCC_MP_APB2ENCLRR 0x70c -+#define RCC_MP_APB3ENSETR 0x710 -+#define RCC_MP_APB3ENCLRR 0x714 -+#define RCC_MP_S_APB3ENSETR 0x718 -+#define RCC_MP_S_APB3ENCLRR 0x71c -+#define RCC_MP_NS_APB3ENSETR 0x720 -+#define RCC_MP_NS_APB3ENCLRR 0x724 -+#define RCC_MP_APB4ENSETR 0x728 -+#define RCC_MP_APB4ENCLRR 0x72c -+#define RCC_MP_S_APB4ENSETR 0x730 -+#define RCC_MP_S_APB4ENCLRR 0x734 -+#define RCC_MP_NS_APB4ENSETR 0x738 -+#define RCC_MP_NS_APB4ENCLRR 0x73c -+#define RCC_MP_APB5ENSETR 0x740 -+#define RCC_MP_APB5ENCLRR 0x744 -+#define RCC_MP_APB6ENSETR 0x748 -+#define RCC_MP_APB6ENCLRR 0x74c -+#define RCC_MP_AHB2ENSETR 0x750 -+#define RCC_MP_AHB2ENCLRR 0x754 -+#define RCC_MP_AHB4ENSETR 0x760 -+#define RCC_MP_AHB4ENCLRR 0x764 -+#define RCC_MP_S_AHB4ENSETR 0x768 -+#define RCC_MP_S_AHB4ENCLRR 0x76c -+#define RCC_MP_NS_AHB4ENSETR 0x770 -+#define RCC_MP_NS_AHB4ENCLRR 0x774 -+#define RCC_MP_AHB5ENSETR 0x778 -+#define RCC_MP_AHB5ENCLRR 0x77c -+#define RCC_MP_AHB6ENSETR 0x780 -+#define RCC_MP_AHB6ENCLRR 0x784 -+#define RCC_MP_S_AHB6ENSETR 0x788 -+#define RCC_MP_S_AHB6ENCLRR 0x78c -+#define RCC_MP_NS_AHB6ENSETR 0x790 -+#define RCC_MP_NS_AHB6ENCLRR 0x794 -+#define RCC_MP_APB1LPENSETR 0x800 -+#define RCC_MP_APB1LPENCLRR 0x804 -+#define RCC_MP_APB2LPENSETR 0x808 -+#define RCC_MP_APB2LPENCLRR 0x80c -+#define RCC_MP_APB3LPENSETR 0x810 -+#define RCC_MP_APB3LPENCLRR 0x814 -+#define RCC_MP_S_APB3LPENSETR 0x818 -+#define RCC_MP_S_APB3LPENCLRR 0x81c -+#define RCC_MP_NS_APB3LPENSETR 0x820 -+#define RCC_MP_NS_APB3LPENCLRR 0x824 -+#define RCC_MP_APB4LPENSETR 0x828 -+#define RCC_MP_APB4LPENCLRR 0x82c -+#define RCC_MP_S_APB4LPENSETR 0x830 -+#define RCC_MP_S_APB4LPENCLRR 0x834 -+#define RCC_MP_NS_APB4LPENSETR 0x838 -+#define RCC_MP_NS_APB4LPENCLRR 0x83c -+#define RCC_MP_APB5LPENSETR 0x840 -+#define RCC_MP_APB5LPENCLRR 0x844 -+#define RCC_MP_APB6LPENSETR 0x848 -+#define RCC_MP_APB6LPENCLRR 0x84c -+#define RCC_MP_AHB2LPENSETR 0x850 -+#define RCC_MP_AHB2LPENCLRR 0x854 -+#define RCC_MP_AHB4LPENSETR 0x858 -+#define RCC_MP_AHB4LPENCLRR 0x85c -+#define RCC_MP_S_AHB4LPENSETR 0x868 -+#define RCC_MP_S_AHB4LPENCLRR 0x86c -+#define RCC_MP_NS_AHB4LPENSETR 0x870 -+#define RCC_MP_NS_AHB4LPENCLRR 0x874 -+#define RCC_MP_AHB5LPENSETR 0x878 -+#define RCC_MP_AHB5LPENCLRR 0x87c -+#define RCC_MP_AHB6LPENSETR 0x880 -+#define RCC_MP_AHB6LPENCLRR 0x884 -+#define RCC_MP_S_AHB6LPENSETR 0x888 -+#define RCC_MP_S_AHB6LPENCLRR 0x88c -+#define RCC_MP_NS_AHB6LPENSETR 0x890 -+#define RCC_MP_NS_AHB6LPENCLRR 0x894 -+#define RCC_MP_S_AXIMLPENSETR 0x898 -+#define RCC_MP_S_AXIMLPENCLRR 0x89c -+#define RCC_MP_NS_AXIMLPENSETR 0x8a0 -+#define RCC_MP_NS_AXIMLPENCLRR 0x8a4 -+#define RCC_MP_MLAHBLPENSETR 0x8a8 -+#define RCC_MP_MLAHBLPENCLRR 0x8ac -+#define RCC_APB3SECSR 0x8c0 -+#define RCC_APB4SECSR 0x8c4 -+#define RCC_APB5SECSR 0x8c8 -+#define RCC_APB6SECSR 0x8cc -+#define RCC_AHB2SECSR 0x8d0 -+#define RCC_AHB4SECSR 0x8d4 -+#define RCC_AHB5SECSR 0x8d8 -+#define RCC_AHB6SECSR 0x8dc -+#define RCC_VERR 0xff4 -+#define RCC_IDR 0xff8 -+#define RCC_SIDR 0xffc -+ -+/* RCC_SECCFGR register fields */ -+#define RCC_SECCFGR_HSISEC BIT(0) -+#define RCC_SECCFGR_CSISEC BIT(1) -+#define RCC_SECCFGR_HSESEC BIT(2) -+#define RCC_SECCFGR_LSISEC BIT(3) -+#define RCC_SECCFGR_LSESEC BIT(4) -+#define RCC_SECCFGR_PLL12SEC BIT(8) -+#define RCC_SECCFGR_PLL3SEC BIT(9) -+#define RCC_SECCFGR_PLL4SEC BIT(10) -+#define RCC_SECCFGR_MPUSEC BIT(11) -+#define RCC_SECCFGR_AXISEC BIT(12) -+#define RCC_SECCFGR_MLAHBSEC BIT(13) -+#define RCC_SECCFGR_APB3DIVSEC BIT(16) -+#define RCC_SECCFGR_APB4DIVSEC BIT(17) -+#define RCC_SECCFGR_APB5DIVSEC BIT(18) -+#define RCC_SECCFGR_APB6DIVSEC BIT(19) -+#define RCC_SECCFGR_TIMG3SEC BIT(20) -+#define RCC_SECCFGR_CPERSEC BIT(21) -+#define RCC_SECCFGR_MCO1SEC BIT(22) -+#define RCC_SECCFGR_MCO2SEC BIT(23) -+#define RCC_SECCFGR_STPSEC BIT(24) -+#define RCC_SECCFGR_RSTSEC BIT(25) -+#define RCC_SECCFGR_PWRSEC BIT(31) -+ -+#define RCC_SECCFGR_MCO1SECF 22 -+#define RCC_SECCFGR_MCO2SECF 23 -+ -+/* RCC_MP_SREQSETR register fields */ -+#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0) -+ -+/* RCC_MP_SREQCLRR register fields */ -+#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) -+ -+/* RCC_MP_APRSTCR register fields */ -+#define RCC_MP_APRSTCR_RDCTLEN BIT(0) -+#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8) -+#define RCC_MP_APRSTCR_RSTTO_SHIFT 8 -+ -+/* RCC_MP_APRSTSR register fields */ -+#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8) -+#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8 -+ -+/* RCC_PWRLPDLYCR register fields */ -+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0) -+#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0 -+ -+/* RCC_MP_GRSTCSETR register fields */ -+#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) -+#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4) -+ -+/* RCC_BR_RSTSCLRR register fields */ -+#define RCC_BR_RSTSCLRR_PORRSTF BIT(0) -+#define RCC_BR_RSTSCLRR_BORRSTF BIT(1) -+#define RCC_BR_RSTSCLRR_PADRSTF BIT(2) -+#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3) -+#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4) -+#define RCC_BR_RSTSCLRR_VCPURSTF BIT(5) -+#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6) -+#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8) -+#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9) -+#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13) -+ -+/* RCC_MP_RSTSSETR register fields */ -+#define RCC_MP_RSTSSETR_PORRSTF BIT(0) -+#define RCC_MP_RSTSSETR_BORRSTF BIT(1) -+#define RCC_MP_RSTSSETR_PADRSTF BIT(2) -+#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3) -+#define RCC_MP_RSTSSETR_VCORERSTF BIT(4) -+#define RCC_MP_RSTSSETR_VCPURSTF BIT(5) -+#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6) -+#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8) -+#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9) -+#define RCC_MP_RSTSSETR_STP2RSTF BIT(10) -+#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11) -+#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12) -+#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13) -+#define RCC_MP_RSTSSETR_SPARE BIT(15) -+ -+/* RCC_MP_RSTSCLRR register fields */ -+#define RCC_MP_RSTSCLRR_PORRSTF BIT(0) -+#define RCC_MP_RSTSCLRR_BORRSTF BIT(1) -+#define RCC_MP_RSTSCLRR_PADRSTF BIT(2) -+#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3) -+#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4) -+#define RCC_MP_RSTSCLRR_VCPURSTF BIT(5) -+#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6) -+#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8) -+#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9) -+#define RCC_MP_RSTSCLRR_STP2RSTF BIT(10) -+#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11) -+#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12) -+#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13) -+#define RCC_MP_RSTSCLRR_SPARE BIT(15) -+ -+/* RCC_MP_IWDGFZSETR register fields */ -+#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0) -+#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1) -+ -+/* RCC_MP_IWDGFZCLRR register fields */ -+#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0) -+#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1) -+ -+/* RCC_MP_CIER register fields */ -+#define RCC_MP_CIER_LSIRDYIE BIT(0) -+#define RCC_MP_CIER_LSERDYIE BIT(1) -+#define RCC_MP_CIER_HSIRDYIE BIT(2) -+#define RCC_MP_CIER_HSERDYIE BIT(3) -+#define RCC_MP_CIER_CSIRDYIE BIT(4) -+#define RCC_MP_CIER_PLL1DYIE BIT(8) -+#define RCC_MP_CIER_PLL2DYIE BIT(9) -+#define RCC_MP_CIER_PLL3DYIE BIT(10) -+#define RCC_MP_CIER_PLL4DYIE BIT(11) -+#define RCC_MP_CIER_LSECSSIE BIT(16) -+#define RCC_MP_CIER_WKUPIE BIT(20) -+ -+/* RCC_MP_CIFR register fields */ -+#define RCC_MP_CIFR_LSIRDYF BIT(0) -+#define RCC_MP_CIFR_LSERDYF BIT(1) -+#define RCC_MP_CIFR_HSIRDYF BIT(2) -+#define RCC_MP_CIFR_HSERDYF BIT(3) -+#define RCC_MP_CIFR_CSIRDYF BIT(4) -+#define RCC_MP_CIFR_PLL1DYF BIT(8) -+#define RCC_MP_CIFR_PLL2DYF BIT(9) -+#define RCC_MP_CIFR_PLL3DYF BIT(10) -+#define RCC_MP_CIFR_PLL4DYF BIT(11) -+#define RCC_MP_CIFR_LSECSSF BIT(16) -+#define RCC_MP_CIFR_WKUPF BIT(20) -+ -+/* RCC_BDCR register fields */ -+#define RCC_BDCR_LSEON BIT(0) -+#define RCC_BDCR_LSEBYP BIT(1) -+#define RCC_BDCR_LSERDY BIT(2) -+#define RCC_BDCR_DIGBYP BIT(3) -+#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4) -+#define RCC_BDCR_LSECSSON BIT(8) -+#define RCC_BDCR_LSECSSD BIT(9) -+#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16) -+#define RCC_BDCR_RTCCKEN BIT(20) -+#define RCC_BDCR_VSWRST BIT(31) -+#define RCC_BDCR_LSEDRV_SHIFT 4 -+#define RCC_BDCR_RTCSRC_SHIFT 16 -+ -+/* RCC_RDLSICR register fields */ -+#define RCC_RDLSICR_LSION BIT(0) -+#define RCC_RDLSICR_LSIRDY BIT(1) -+#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16) -+#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24) -+#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27) -+#define RCC_RDLSICR_MRD_SHIFT 16 -+#define RCC_RDLSICR_EADLY_SHIFT 24 -+#define RCC_RDLSICR_SPARE_SHIFT 27 -+ -+/* RCC_OCENSETR register fields */ -+#define RCC_OCENSETR_HSION BIT(0) -+#define RCC_OCENSETR_HSIKERON BIT(1) -+#define RCC_OCENSETR_CSION BIT(4) -+#define RCC_OCENSETR_CSIKERON BIT(5) -+#define RCC_OCENSETR_DIGBYP BIT(7) -+#define RCC_OCENSETR_HSEON BIT(8) -+#define RCC_OCENSETR_HSEKERON BIT(9) -+#define RCC_OCENSETR_HSEBYP BIT(10) -+#define RCC_OCENSETR_HSECSSON BIT(11) -+ -+/* RCC_OCENCLRR register fields */ -+#define RCC_OCENCLRR_HSION BIT(0) -+#define RCC_OCENCLRR_HSIKERON BIT(1) -+#define RCC_OCENCLRR_CSION BIT(4) -+#define RCC_OCENCLRR_CSIKERON BIT(5) -+#define RCC_OCENCLRR_DIGBYP BIT(7) -+#define RCC_OCENCLRR_HSEON BIT(8) -+#define RCC_OCENCLRR_HSEKERON BIT(9) -+#define RCC_OCENCLRR_HSEBYP BIT(10) -+ -+/* RCC_OCRDYR register fields */ -+#define RCC_OCRDYR_HSIRDY BIT(0) -+#define RCC_OCRDYR_HSIDIVRDY BIT(2) -+#define RCC_OCRDYR_CSIRDY BIT(4) -+#define RCC_OCRDYR_HSERDY BIT(8) -+#define RCC_OCRDYR_MPUCKRDY BIT(23) -+#define RCC_OCRDYR_AXICKRDY BIT(24) -+ -+/* RCC_HSICFGR register fields */ -+#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0) -+#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8) -+#define RCC_HSICFGR_HSICAL_MASK GENMASK(27, 16) -+#define RCC_HSICFGR_HSIDIV_SHIFT 0 -+#define RCC_HSICFGR_HSITRIM_SHIFT 8 -+#define RCC_HSICFGR_HSICAL_SHIFT 16 -+ -+/* RCC_CSICFGR register fields */ -+#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8) -+#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16) -+#define RCC_CSICFGR_CSITRIM_SHIFT 8 -+#define RCC_CSICFGR_CSICAL_SHIFT 16 -+ -+/* RCC_MCO1CFGR register fields */ -+#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0) -+#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4) -+#define RCC_MCO1CFGR_MCO1ON BIT(12) -+#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0 -+#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4 -+ -+/* RCC_MCO2CFGR register fields */ -+#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0) -+#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4) -+#define RCC_MCO2CFGR_MCO2ON BIT(12) -+#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0 -+#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4 -+ -+/* RCC_DBGCFGR register fields */ -+#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0) -+#define RCC_DBGCFGR_DBGCKEN BIT(8) -+#define RCC_DBGCFGR_TRACECKEN BIT(9) -+#define RCC_DBGCFGR_DBGRST BIT(12) -+#define RCC_DBGCFGR_TRACEDIV_SHIFT 0 -+ -+/* RCC_RCK12SELR register fields */ -+#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0) -+#define RCC_RCK12SELR_PLL12SRCRDY BIT(31) -+#define RCC_RCK12SELR_PLL12SRC_SHIFT 0 -+ -+/* RCC_RCK3SELR register fields */ -+#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0) -+#define RCC_RCK3SELR_PLL3SRCRDY BIT(31) -+#define RCC_RCK3SELR_PLL3SRC_SHIFT 0 -+ -+/* RCC_RCK4SELR register fields */ -+#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0) -+#define RCC_RCK4SELR_PLL4SRCRDY BIT(31) -+#define RCC_RCK4SELR_PLL4SRC_SHIFT 0 -+ -+/* RCC_PLL1CR register fields */ -+#define RCC_PLL1CR_PLLON BIT(0) -+#define RCC_PLL1CR_PLL1RDY BIT(1) -+#define RCC_PLL1CR_SSCG_CTRL BIT(2) -+#define RCC_PLL1CR_DIVPEN BIT(4) -+#define RCC_PLL1CR_DIVQEN BIT(5) -+#define RCC_PLL1CR_DIVREN BIT(6) -+ -+/* RCC_PLL1CFGR1 register fields */ -+#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0) -+#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16) -+#define RCC_PLL1CFGR1_DIVN_SHIFT 0 -+#define RCC_PLL1CFGR1_DIVM1_SHIFT 16 -+ -+/* RCC_PLL1CFGR2 register fields */ -+#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0) -+#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8) -+#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16) -+#define RCC_PLL1CFGR2_DIVP_SHIFT 0 -+#define RCC_PLL1CFGR2_DIVQ_SHIFT 8 -+#define RCC_PLL1CFGR2_DIVR_SHIFT 16 -+ -+/* RCC_PLL1FRACR register fields */ -+#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3) -+#define RCC_PLL1FRACR_FRACLE BIT(16) -+#define RCC_PLL1FRACR_FRACV_SHIFT 3 -+ -+/* RCC_PLL1CSGR register fields */ -+#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0) -+#define RCC_PLL1CSGR_TPDFN_DIS BIT(13) -+#define RCC_PLL1CSGR_RPDFN_DIS BIT(14) -+#define RCC_PLL1CSGR_SSCG_MODE BIT(15) -+#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16) -+#define RCC_PLL1CSGR_MOD_PER_SHIFT 0 -+#define RCC_PLL1CSGR_INC_STEP_SHIFT 16 -+ -+/* RCC_PLL2CR register fields */ -+#define RCC_PLL2CR_PLLON BIT(0) -+#define RCC_PLL2CR_PLL2RDY BIT(1) -+#define RCC_PLL2CR_SSCG_CTRL BIT(2) -+#define RCC_PLL2CR_DIVPEN BIT(4) -+#define RCC_PLL2CR_DIVQEN BIT(5) -+#define RCC_PLL2CR_DIVREN BIT(6) -+ -+/* RCC_PLL2CFGR1 register fields */ -+#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0) -+#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16) -+#define RCC_PLL2CFGR1_DIVN_SHIFT 0 -+#define RCC_PLL2CFGR1_DIVM2_SHIFT 16 -+ -+/* RCC_PLL2CFGR2 register fields */ -+#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0) -+#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8) -+#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16) -+#define RCC_PLL2CFGR2_DIVP_SHIFT 0 -+#define RCC_PLL2CFGR2_DIVQ_SHIFT 8 -+#define RCC_PLL2CFGR2_DIVR_SHIFT 16 -+ -+/* RCC_PLL2FRACR register fields */ -+#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3) -+#define RCC_PLL2FRACR_FRACLE BIT(16) -+#define RCC_PLL2FRACR_FRACV_SHIFT 3 -+ -+/* RCC_PLL2CSGR register fields */ -+#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0) -+#define RCC_PLL2CSGR_TPDFN_DIS BIT(13) -+#define RCC_PLL2CSGR_RPDFN_DIS BIT(14) -+#define RCC_PLL2CSGR_SSCG_MODE BIT(15) -+#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16) -+#define RCC_PLL2CSGR_MOD_PER_SHIFT 0 -+#define RCC_PLL2CSGR_INC_STEP_SHIFT 16 -+ -+/* RCC_PLL3CR register fields */ -+#define RCC_PLL3CR_PLLON BIT(0) -+#define RCC_PLL3CR_PLL3RDY BIT(1) -+#define RCC_PLL3CR_SSCG_CTRL BIT(2) -+#define RCC_PLL3CR_DIVPEN BIT(4) -+#define RCC_PLL3CR_DIVQEN BIT(5) -+#define RCC_PLL3CR_DIVREN BIT(6) -+ -+/* RCC_PLL3CFGR1 register fields */ -+#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0) -+#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16) -+#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24) -+#define RCC_PLL3CFGR1_DIVN_SHIFT 0 -+#define RCC_PLL3CFGR1_DIVM3_SHIFT 16 -+#define RCC_PLL3CFGR1_IFRGE_SHIFT 24 -+ -+/* RCC_PLL3CFGR2 register fields */ -+#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0) -+#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8) -+#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16) -+#define RCC_PLL3CFGR2_DIVP_SHIFT 0 -+#define RCC_PLL3CFGR2_DIVQ_SHIFT 8 -+#define RCC_PLL3CFGR2_DIVR_SHIFT 16 -+ -+/* RCC_PLL3FRACR register fields */ -+#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3) -+#define RCC_PLL3FRACR_FRACLE BIT(16) -+#define RCC_PLL3FRACR_FRACV_SHIFT 3 -+ -+/* RCC_PLL3CSGR register fields */ -+#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0) -+#define RCC_PLL3CSGR_TPDFN_DIS BIT(13) -+#define RCC_PLL3CSGR_RPDFN_DIS BIT(14) -+#define RCC_PLL3CSGR_SSCG_MODE BIT(15) -+#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16) -+#define RCC_PLL3CSGR_MOD_PER_SHIFT 0 -+#define RCC_PLL3CSGR_INC_STEP_SHIFT 16 -+ -+/* RCC_PLL4CR register fields */ -+#define RCC_PLL4CR_PLLON BIT(0) -+#define RCC_PLL4CR_PLL4RDY BIT(1) -+#define RCC_PLL4CR_SSCG_CTRL BIT(2) -+#define RCC_PLL4CR_DIVPEN BIT(4) -+#define RCC_PLL4CR_DIVQEN BIT(5) -+#define RCC_PLL4CR_DIVREN BIT(6) -+ -+/* RCC_PLL4CFGR1 register fields */ -+#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0) -+#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16) -+#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24) -+#define RCC_PLL4CFGR1_DIVN_SHIFT 0 -+#define RCC_PLL4CFGR1_DIVM4_SHIFT 16 -+#define RCC_PLL4CFGR1_IFRGE_SHIFT 24 -+ -+/* RCC_PLL4CFGR2 register fields */ -+#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0) -+#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8) -+#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16) -+#define RCC_PLL4CFGR2_DIVP_SHIFT 0 -+#define RCC_PLL4CFGR2_DIVQ_SHIFT 8 -+#define RCC_PLL4CFGR2_DIVR_SHIFT 16 -+ -+/* RCC_PLL4FRACR register fields */ -+#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3) -+#define RCC_PLL4FRACR_FRACLE BIT(16) -+#define RCC_PLL4FRACR_FRACV_SHIFT 3 -+ -+/* RCC_PLL4CSGR register fields */ -+#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0) -+#define RCC_PLL4CSGR_TPDFN_DIS BIT(13) -+#define RCC_PLL4CSGR_RPDFN_DIS BIT(14) -+#define RCC_PLL4CSGR_SSCG_MODE BIT(15) -+#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16) -+#define RCC_PLL4CSGR_MOD_PER_SHIFT 0 -+#define RCC_PLL4CSGR_INC_STEP_SHIFT 16 -+ -+/* RCC_MPCKSELR register fields */ -+#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0) -+#define RCC_MPCKSELR_MPUSRCRDY BIT(31) -+#define RCC_MPCKSELR_MPUSRC_SHIFT 0 -+ -+/* RCC_ASSCKSELR register fields */ -+#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0) -+#define RCC_ASSCKSELR_AXISSRCRDY BIT(31) -+#define RCC_ASSCKSELR_AXISSRC_SHIFT 0 -+ -+/* RCC_MSSCKSELR register fields */ -+#define RCC_MSSCKSELR_MLAHBSSRC_MASK GENMASK(1, 0) -+#define RCC_MSSCKSELR_MLAHBSSRCRDY BIT(31) -+#define RCC_MSSCKSELR_MLAHBSSRC_SHIFT 0 -+ -+/* RCC_CPERCKSELR register fields */ -+#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0) -+#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0 -+ -+/* RCC_RTCDIVR register fields */ -+#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0) -+#define RCC_RTCDIVR_RTCDIV_SHIFT 0 -+ -+/* RCC_MPCKDIVR register fields */ -+#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(3, 0) -+#define RCC_MPCKDIVR_MPUDIVRDY BIT(31) -+#define RCC_MPCKDIVR_MPUDIV_SHIFT 0 -+ -+/* RCC_AXIDIVR register fields */ -+#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0) -+#define RCC_AXIDIVR_AXIDIVRDY BIT(31) -+#define RCC_AXIDIVR_AXIDIV_SHIFT 0 -+ -+/* RCC_MLAHBDIVR register fields */ -+#define RCC_MLAHBDIVR_MLAHBDIV_MASK GENMASK(3, 0) -+#define RCC_MLAHBDIVR_MLAHBDIVRDY BIT(31) -+#define RCC_MLAHBDIVR_MLAHBDIV_SHIFT 0 -+ -+/* RCC_APB1DIVR register fields */ -+#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0) -+#define RCC_APB1DIVR_APB1DIVRDY BIT(31) -+#define RCC_APB1DIVR_APB1DIV_SHIFT 0 -+ -+/* RCC_APB2DIVR register fields */ -+#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0) -+#define RCC_APB2DIVR_APB2DIVRDY BIT(31) -+#define RCC_APB2DIVR_APB2DIV_SHIFT 0 -+ -+/* RCC_APB3DIVR register fields */ -+#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0) -+#define RCC_APB3DIVR_APB3DIVRDY BIT(31) -+#define RCC_APB3DIVR_APB3DIV_SHIFT 0 -+ -+/* RCC_APB4DIVR register fields */ -+#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0) -+#define RCC_APB4DIVR_APB4DIVRDY BIT(31) -+#define RCC_APB4DIVR_APB4DIV_SHIFT 0 -+ -+/* RCC_APB5DIVR register fields */ -+#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0) -+#define RCC_APB5DIVR_APB5DIVRDY BIT(31) -+#define RCC_APB5DIVR_APB5DIV_SHIFT 0 -+ -+/* RCC_APB6DIVR register fields */ -+#define RCC_APB6DIVR_APB6DIV_MASK GENMASK(2, 0) -+#define RCC_APB6DIVR_APB6DIVRDY BIT(31) -+#define RCC_APB6DIVR_APB6DIV_SHIFT 0 -+ -+/* RCC_TIMG1PRER register fields */ -+#define RCC_TIMG1PRER_TIMG1PRE BIT(0) -+#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31) -+ -+/* RCC_TIMG2PRER register fields */ -+#define RCC_TIMG2PRER_TIMG2PRE BIT(0) -+#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31) -+ -+/* RCC_TIMG3PRER register fields */ -+#define RCC_TIMG3PRER_TIMG3PRE BIT(0) -+#define RCC_TIMG3PRER_TIMG3PRERDY BIT(31) -+ -+/* RCC_DDRITFCR register fields */ -+#define RCC_DDRITFCR_DDRC1EN BIT(0) -+#define RCC_DDRITFCR_DDRC1LPEN BIT(1) -+#define RCC_DDRITFCR_DDRPHYCEN BIT(4) -+#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5) -+#define RCC_DDRITFCR_DDRCAPBEN BIT(6) -+#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7) -+#define RCC_DDRITFCR_AXIDCGEN BIT(8) -+#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9) -+#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10) -+#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11) -+#define RCC_DDRITFCR_DDRCAPBRST BIT(14) -+#define RCC_DDRITFCR_DDRCAXIRST BIT(15) -+#define RCC_DDRITFCR_DDRCORERST BIT(16) -+#define RCC_DDRITFCR_DPHYAPBRST BIT(17) -+#define RCC_DDRITFCR_DPHYRST BIT(18) -+#define RCC_DDRITFCR_DPHYCTLRST BIT(19) -+#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20) -+#define RCC_DDRITFCR_GSKPMOD BIT(23) -+#define RCC_DDRITFCR_GSKPCTRL BIT(24) -+#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25) -+#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28) -+#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11 -+#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20 -+#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25 -+#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28 -+ -+/* RCC_I2C12CKSELR register fields */ -+#define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0) -+#define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0 -+ -+/* RCC_I2C345CKSELR register fields */ -+#define RCC_I2C345CKSELR_I2C3SRC_MASK GENMASK(2, 0) -+#define RCC_I2C345CKSELR_I2C4SRC_MASK GENMASK(5, 3) -+#define RCC_I2C345CKSELR_I2C5SRC_MASK GENMASK(8, 6) -+#define RCC_I2C345CKSELR_I2C3SRC_SHIFT 0 -+#define RCC_I2C345CKSELR_I2C4SRC_SHIFT 3 -+#define RCC_I2C345CKSELR_I2C5SRC_SHIFT 6 -+ -+/* RCC_SPI2S1CKSELR register fields */ -+#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0) -+#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0 -+ -+/* RCC_SPI2S23CKSELR register fields */ -+#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0) -+#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0 -+ -+/* RCC_SPI45CKSELR register fields */ -+#define RCC_SPI45CKSELR_SPI4SRC_MASK GENMASK(2, 0) -+#define RCC_SPI45CKSELR_SPI5SRC_MASK GENMASK(5, 3) -+#define RCC_SPI45CKSELR_SPI4SRC_SHIFT 0 -+#define RCC_SPI45CKSELR_SPI5SRC_SHIFT 3 -+ -+/* RCC_UART12CKSELR register fields */ -+#define RCC_UART12CKSELR_UART1SRC_MASK GENMASK(2, 0) -+#define RCC_UART12CKSELR_UART2SRC_MASK GENMASK(5, 3) -+#define RCC_UART12CKSELR_UART1SRC_SHIFT 0 -+#define RCC_UART12CKSELR_UART2SRC_SHIFT 3 -+ -+/* RCC_UART35CKSELR register fields */ -+#define RCC_UART35CKSELR_UART35SRC_MASK GENMASK(2, 0) -+#define RCC_UART35CKSELR_UART35SRC_SHIFT 0 -+ -+/* RCC_UART4CKSELR register fields */ -+#define RCC_UART4CKSELR_UART4SRC_MASK GENMASK(2, 0) -+#define RCC_UART4CKSELR_UART4SRC_SHIFT 0 -+ -+/* RCC_UART6CKSELR register fields */ -+#define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0) -+#define RCC_UART6CKSELR_UART6SRC_SHIFT 0 -+ -+/* RCC_UART78CKSELR register fields */ -+#define RCC_UART78CKSELR_UART78SRC_MASK GENMASK(2, 0) -+#define RCC_UART78CKSELR_UART78SRC_SHIFT 0 -+ -+/* RCC_LPTIM1CKSELR register fields */ -+#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0) -+#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0 -+ -+/* RCC_LPTIM23CKSELR register fields */ -+#define RCC_LPTIM23CKSELR_LPTIM2SRC_MASK GENMASK(2, 0) -+#define RCC_LPTIM23CKSELR_LPTIM3SRC_MASK GENMASK(5, 3) -+#define RCC_LPTIM23CKSELR_LPTIM2SRC_SHIFT 0 -+#define RCC_LPTIM23CKSELR_LPTIM3SRC_SHIFT 3 -+ -+/* RCC_LPTIM45CKSELR register fields */ -+#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0) -+#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0 -+ -+/* RCC_SAI1CKSELR register fields */ -+#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0) -+#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0 -+ -+/* RCC_SAI2CKSELR register fields */ -+#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0) -+#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0 -+ -+/* RCC_FDCANCKSELR register fields */ -+#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0) -+#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0 -+ -+/* RCC_SPDIFCKSELR register fields */ -+#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0) -+#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0 -+ -+/* RCC_ADC12CKSELR register fields */ -+#define RCC_ADC12CKSELR_ADC1SRC_MASK GENMASK(1, 0) -+#define RCC_ADC12CKSELR_ADC2SRC_MASK GENMASK(3, 2) -+#define RCC_ADC12CKSELR_ADC1SRC_SHIFT 0 -+#define RCC_ADC12CKSELR_ADC2SRC_SHIFT 2 -+ -+/* RCC_SDMMC12CKSELR register fields */ -+#define RCC_SDMMC12CKSELR_SDMMC1SRC_MASK GENMASK(2, 0) -+#define RCC_SDMMC12CKSELR_SDMMC2SRC_MASK GENMASK(5, 3) -+#define RCC_SDMMC12CKSELR_SDMMC1SRC_SHIFT 0 -+#define RCC_SDMMC12CKSELR_SDMMC2SRC_SHIFT 3 -+ -+/* RCC_ETH12CKSELR register fields */ -+#define RCC_ETH12CKSELR_ETH1SRC_MASK GENMASK(1, 0) -+#define RCC_ETH12CKSELR_ETH1PTPDIV_MASK GENMASK(7, 4) -+#define RCC_ETH12CKSELR_ETH2SRC_MASK GENMASK(9, 8) -+#define RCC_ETH12CKSELR_ETH2PTPDIV_MASK GENMASK(15, 12) -+#define RCC_ETH12CKSELR_ETH1SRC_SHIFT 0 -+#define RCC_ETH12CKSELR_ETH1PTPDIV_SHIFT 4 -+#define RCC_ETH12CKSELR_ETH2SRC_SHIFT 8 -+#define RCC_ETH12CKSELR_ETH2PTPDIV_SHIFT 12 -+ -+/* RCC_USBCKSELR register fields */ -+#define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0) -+#define RCC_USBCKSELR_USBOSRC BIT(4) -+#define RCC_USBCKSELR_USBPHYSRC_SHIFT 0 -+ -+/* RCC_QSPICKSELR register fields */ -+#define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0) -+#define RCC_QSPICKSELR_QSPISRC_SHIFT 0 -+ -+/* RCC_FMCCKSELR register fields */ -+#define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0) -+#define RCC_FMCCKSELR_FMCSRC_SHIFT 0 -+ -+/* RCC_RNG1CKSELR register fields */ -+#define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0) -+#define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0 -+ -+/* RCC_STGENCKSELR register fields */ -+#define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0) -+#define RCC_STGENCKSELR_STGENSRC_SHIFT 0 -+ -+/* RCC_DCMIPPCKSELR register fields */ -+#define RCC_DCMIPPCKSELR_DCMIPPSRC_MASK GENMASK(1, 0) -+#define RCC_DCMIPPCKSELR_DCMIPPSRC_SHIFT 0 -+ -+/* RCC_SAESCKSELR register fields */ -+#define RCC_SAESCKSELR_SAESSRC_MASK GENMASK(1, 0) -+#define RCC_SAESCKSELR_SAESSRC_SHIFT 0 -+ -+/* RCC_APB1RSTSETR register fields */ -+#define RCC_APB1RSTSETR_TIM2RST BIT(0) -+#define RCC_APB1RSTSETR_TIM3RST BIT(1) -+#define RCC_APB1RSTSETR_TIM4RST BIT(2) -+#define RCC_APB1RSTSETR_TIM5RST BIT(3) -+#define RCC_APB1RSTSETR_TIM6RST BIT(4) -+#define RCC_APB1RSTSETR_TIM7RST BIT(5) -+#define RCC_APB1RSTSETR_LPTIM1RST BIT(9) -+#define RCC_APB1RSTSETR_SPI2RST BIT(11) -+#define RCC_APB1RSTSETR_SPI3RST BIT(12) -+#define RCC_APB1RSTSETR_USART3RST BIT(15) -+#define RCC_APB1RSTSETR_UART4RST BIT(16) -+#define RCC_APB1RSTSETR_UART5RST BIT(17) -+#define RCC_APB1RSTSETR_UART7RST BIT(18) -+#define RCC_APB1RSTSETR_UART8RST BIT(19) -+#define RCC_APB1RSTSETR_I2C1RST BIT(21) -+#define RCC_APB1RSTSETR_I2C2RST BIT(22) -+#define RCC_APB1RSTSETR_SPDIFRST BIT(26) -+ -+/* RCC_APB1RSTCLRR register fields */ -+#define RCC_APB1RSTCLRR_TIM2RST BIT(0) -+#define RCC_APB1RSTCLRR_TIM3RST BIT(1) -+#define RCC_APB1RSTCLRR_TIM4RST BIT(2) -+#define RCC_APB1RSTCLRR_TIM5RST BIT(3) -+#define RCC_APB1RSTCLRR_TIM6RST BIT(4) -+#define RCC_APB1RSTCLRR_TIM7RST BIT(5) -+#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9) -+#define RCC_APB1RSTCLRR_SPI2RST BIT(11) -+#define RCC_APB1RSTCLRR_SPI3RST BIT(12) -+#define RCC_APB1RSTCLRR_USART3RST BIT(15) -+#define RCC_APB1RSTCLRR_UART4RST BIT(16) -+#define RCC_APB1RSTCLRR_UART5RST BIT(17) -+#define RCC_APB1RSTCLRR_UART7RST BIT(18) -+#define RCC_APB1RSTCLRR_UART8RST BIT(19) -+#define RCC_APB1RSTCLRR_I2C1RST BIT(21) -+#define RCC_APB1RSTCLRR_I2C2RST BIT(22) -+#define RCC_APB1RSTCLRR_SPDIFRST BIT(26) -+ -+/* RCC_APB2RSTSETR register fields */ -+#define RCC_APB2RSTSETR_TIM1RST BIT(0) -+#define RCC_APB2RSTSETR_TIM8RST BIT(1) -+#define RCC_APB2RSTSETR_SPI1RST BIT(8) -+#define RCC_APB2RSTSETR_USART6RST BIT(13) -+#define RCC_APB2RSTSETR_SAI1RST BIT(16) -+#define RCC_APB2RSTSETR_SAI2RST BIT(17) -+#define RCC_APB2RSTSETR_DFSDMRST BIT(20) -+#define RCC_APB2RSTSETR_FDCANRST BIT(24) -+ -+/* RCC_APB2RSTCLRR register fields */ -+#define RCC_APB2RSTCLRR_TIM1RST BIT(0) -+#define RCC_APB2RSTCLRR_TIM8RST BIT(1) -+#define RCC_APB2RSTCLRR_SPI1RST BIT(8) -+#define RCC_APB2RSTCLRR_USART6RST BIT(13) -+#define RCC_APB2RSTCLRR_SAI1RST BIT(16) -+#define RCC_APB2RSTCLRR_SAI2RST BIT(17) -+#define RCC_APB2RSTCLRR_DFSDMRST BIT(20) -+#define RCC_APB2RSTCLRR_FDCANRST BIT(24) -+ -+/* RCC_APB3RSTSETR register fields */ -+#define RCC_APB3RSTSETR_LPTIM2RST BIT(0) -+#define RCC_APB3RSTSETR_LPTIM3RST BIT(1) -+#define RCC_APB3RSTSETR_LPTIM4RST BIT(2) -+#define RCC_APB3RSTSETR_LPTIM5RST BIT(3) -+#define RCC_APB3RSTSETR_SYSCFGRST BIT(11) -+#define RCC_APB3RSTSETR_VREFRST BIT(13) -+#define RCC_APB3RSTSETR_DTSRST BIT(16) -+#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17) -+ -+/* RCC_APB3RSTCLRR register fields */ -+#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0) -+#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1) -+#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2) -+#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3) -+#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11) -+#define RCC_APB3RSTCLRR_VREFRST BIT(13) -+#define RCC_APB3RSTCLRR_DTSRST BIT(16) -+#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17) -+ -+/* RCC_APB4RSTSETR register fields */ -+#define RCC_APB4RSTSETR_LTDCRST BIT(0) -+#define RCC_APB4RSTSETR_DCMIPPRST BIT(1) -+#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8) -+#define RCC_APB4RSTSETR_USBPHYRST BIT(16) -+ -+/* RCC_APB4RSTCLRR register fields */ -+#define RCC_APB4RSTCLRR_LTDCRST BIT(0) -+#define RCC_APB4RSTCLRR_DCMIPPRST BIT(1) -+#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8) -+#define RCC_APB4RSTCLRR_USBPHYRST BIT(16) -+ -+/* RCC_APB5RSTSETR register fields */ -+#define RCC_APB5RSTSETR_STGENRST BIT(20) -+ -+/* RCC_APB5RSTCLRR register fields */ -+#define RCC_APB5RSTCLRR_STGENRST BIT(20) -+ -+/* RCC_APB6RSTSETR register fields */ -+#define RCC_APB6RSTSETR_USART1RST BIT(0) -+#define RCC_APB6RSTSETR_USART2RST BIT(1) -+#define RCC_APB6RSTSETR_SPI4RST BIT(2) -+#define RCC_APB6RSTSETR_SPI5RST BIT(3) -+#define RCC_APB6RSTSETR_I2C3RST BIT(4) -+#define RCC_APB6RSTSETR_I2C4RST BIT(5) -+#define RCC_APB6RSTSETR_I2C5RST BIT(6) -+#define RCC_APB6RSTSETR_TIM12RST BIT(7) -+#define RCC_APB6RSTSETR_TIM13RST BIT(8) -+#define RCC_APB6RSTSETR_TIM14RST BIT(9) -+#define RCC_APB6RSTSETR_TIM15RST BIT(10) -+#define RCC_APB6RSTSETR_TIM16RST BIT(11) -+#define RCC_APB6RSTSETR_TIM17RST BIT(12) -+ -+/* RCC_APB6RSTCLRR register fields */ -+#define RCC_APB6RSTCLRR_USART1RST BIT(0) -+#define RCC_APB6RSTCLRR_USART2RST BIT(1) -+#define RCC_APB6RSTCLRR_SPI4RST BIT(2) -+#define RCC_APB6RSTCLRR_SPI5RST BIT(3) -+#define RCC_APB6RSTCLRR_I2C3RST BIT(4) -+#define RCC_APB6RSTCLRR_I2C4RST BIT(5) -+#define RCC_APB6RSTCLRR_I2C5RST BIT(6) -+#define RCC_APB6RSTCLRR_TIM12RST BIT(7) -+#define RCC_APB6RSTCLRR_TIM13RST BIT(8) -+#define RCC_APB6RSTCLRR_TIM14RST BIT(9) -+#define RCC_APB6RSTCLRR_TIM15RST BIT(10) -+#define RCC_APB6RSTCLRR_TIM16RST BIT(11) -+#define RCC_APB6RSTCLRR_TIM17RST BIT(12) -+ -+/* RCC_AHB2RSTSETR register fields */ -+#define RCC_AHB2RSTSETR_DMA1RST BIT(0) -+#define RCC_AHB2RSTSETR_DMA2RST BIT(1) -+#define RCC_AHB2RSTSETR_DMAMUX1RST BIT(2) -+#define RCC_AHB2RSTSETR_DMA3RST BIT(3) -+#define RCC_AHB2RSTSETR_DMAMUX2RST BIT(4) -+#define RCC_AHB2RSTSETR_ADC1RST BIT(5) -+#define RCC_AHB2RSTSETR_ADC2RST BIT(6) -+#define RCC_AHB2RSTSETR_USBORST BIT(8) -+ -+/* RCC_AHB2RSTCLRR register fields */ -+#define RCC_AHB2RSTCLRR_DMA1RST BIT(0) -+#define RCC_AHB2RSTCLRR_DMA2RST BIT(1) -+#define RCC_AHB2RSTCLRR_DMAMUX1RST BIT(2) -+#define RCC_AHB2RSTCLRR_DMA3RST BIT(3) -+#define RCC_AHB2RSTCLRR_DMAMUX2RST BIT(4) -+#define RCC_AHB2RSTCLRR_ADC1RST BIT(5) -+#define RCC_AHB2RSTCLRR_ADC2RST BIT(6) -+#define RCC_AHB2RSTCLRR_USBORST BIT(8) -+ -+/* RCC_AHB4RSTSETR register fields */ -+#define RCC_AHB4RSTSETR_GPIOARST BIT(0) -+#define RCC_AHB4RSTSETR_GPIOBRST BIT(1) -+#define RCC_AHB4RSTSETR_GPIOCRST BIT(2) -+#define RCC_AHB4RSTSETR_GPIODRST BIT(3) -+#define RCC_AHB4RSTSETR_GPIOERST BIT(4) -+#define RCC_AHB4RSTSETR_GPIOFRST BIT(5) -+#define RCC_AHB4RSTSETR_GPIOGRST BIT(6) -+#define RCC_AHB4RSTSETR_GPIOHRST BIT(7) -+#define RCC_AHB4RSTSETR_GPIOIRST BIT(8) -+#define RCC_AHB4RSTSETR_TSCRST BIT(15) -+ -+/* RCC_AHB4RSTCLRR register fields */ -+#define RCC_AHB4RSTCLRR_GPIOARST BIT(0) -+#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1) -+#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2) -+#define RCC_AHB4RSTCLRR_GPIODRST BIT(3) -+#define RCC_AHB4RSTCLRR_GPIOERST BIT(4) -+#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5) -+#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6) -+#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7) -+#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8) -+#define RCC_AHB4RSTCLRR_TSCRST BIT(15) -+ -+/* RCC_AHB5RSTSETR register fields */ -+#define RCC_AHB5RSTSETR_PKARST BIT(2) -+#define RCC_AHB5RSTSETR_SAESRST BIT(3) -+#define RCC_AHB5RSTSETR_CRYP1RST BIT(4) -+#define RCC_AHB5RSTSETR_HASH1RST BIT(5) -+#define RCC_AHB5RSTSETR_RNG1RST BIT(6) -+#define RCC_AHB5RSTSETR_AXIMCRST BIT(16) -+ -+/* RCC_AHB5RSTCLRR register fields */ -+#define RCC_AHB5RSTCLRR_PKARST BIT(2) -+#define RCC_AHB5RSTCLRR_SAESRST BIT(3) -+#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4) -+#define RCC_AHB5RSTCLRR_HASH1RST BIT(5) -+#define RCC_AHB5RSTCLRR_RNG1RST BIT(6) -+#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16) -+ -+/* RCC_AHB6RSTSETR register fields */ -+#define RCC_AHB6RSTSETR_MDMARST BIT(0) -+#define RCC_AHB6RSTSETR_MCERST BIT(1) -+#define RCC_AHB6RSTSETR_ETH1MACRST BIT(10) -+#define RCC_AHB6RSTSETR_FMCRST BIT(12) -+#define RCC_AHB6RSTSETR_QSPIRST BIT(14) -+#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16) -+#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17) -+#define RCC_AHB6RSTSETR_CRC1RST BIT(20) -+#define RCC_AHB6RSTSETR_USBHRST BIT(24) -+#define RCC_AHB6RSTSETR_ETH2MACRST BIT(30) -+ -+/* RCC_AHB6RSTCLRR register fields */ -+#define RCC_AHB6RSTCLRR_MDMARST BIT(0) -+#define RCC_AHB6RSTCLRR_MCERST BIT(1) -+#define RCC_AHB6RSTCLRR_ETH1MACRST BIT(10) -+#define RCC_AHB6RSTCLRR_FMCRST BIT(12) -+#define RCC_AHB6RSTCLRR_QSPIRST BIT(14) -+#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16) -+#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17) -+#define RCC_AHB6RSTCLRR_CRC1RST BIT(20) -+#define RCC_AHB6RSTCLRR_USBHRST BIT(24) -+#define RCC_AHB6RSTCLRR_ETH2MACRST BIT(30) -+ -+/* RCC_MP_APB1ENSETR register fields */ -+#define RCC_MP_APB1ENSETR_TIM2EN BIT(0) -+#define RCC_MP_APB1ENSETR_TIM3EN BIT(1) -+#define RCC_MP_APB1ENSETR_TIM4EN BIT(2) -+#define RCC_MP_APB1ENSETR_TIM5EN BIT(3) -+#define RCC_MP_APB1ENSETR_TIM6EN BIT(4) -+#define RCC_MP_APB1ENSETR_TIM7EN BIT(5) -+#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9) -+#define RCC_MP_APB1ENSETR_SPI2EN BIT(11) -+#define RCC_MP_APB1ENSETR_SPI3EN BIT(12) -+#define RCC_MP_APB1ENSETR_USART3EN BIT(15) -+#define RCC_MP_APB1ENSETR_UART4EN BIT(16) -+#define RCC_MP_APB1ENSETR_UART5EN BIT(17) -+#define RCC_MP_APB1ENSETR_UART7EN BIT(18) -+#define RCC_MP_APB1ENSETR_UART8EN BIT(19) -+#define RCC_MP_APB1ENSETR_I2C1EN BIT(21) -+#define RCC_MP_APB1ENSETR_I2C2EN BIT(22) -+#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26) -+ -+/* RCC_MP_APB1ENCLRR register fields */ -+#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0) -+#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1) -+#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2) -+#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3) -+#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4) -+#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5) -+#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9) -+#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11) -+#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12) -+#define RCC_MP_APB1ENCLRR_USART3EN BIT(15) -+#define RCC_MP_APB1ENCLRR_UART4EN BIT(16) -+#define RCC_MP_APB1ENCLRR_UART5EN BIT(17) -+#define RCC_MP_APB1ENCLRR_UART7EN BIT(18) -+#define RCC_MP_APB1ENCLRR_UART8EN BIT(19) -+#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21) -+#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22) -+#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26) -+ -+/* RCC_MP_APB2ENSETR register fields */ -+#define RCC_MP_APB2ENSETR_TIM1EN BIT(0) -+#define RCC_MP_APB2ENSETR_TIM8EN BIT(1) -+#define RCC_MP_APB2ENSETR_SPI1EN BIT(8) -+#define RCC_MP_APB2ENSETR_USART6EN BIT(13) -+#define RCC_MP_APB2ENSETR_SAI1EN BIT(16) -+#define RCC_MP_APB2ENSETR_SAI2EN BIT(17) -+#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20) -+#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21) -+#define RCC_MP_APB2ENSETR_FDCANEN BIT(24) -+ -+/* RCC_MP_APB2ENCLRR register fields */ -+#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0) -+#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1) -+#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8) -+#define RCC_MP_APB2ENCLRR_USART6EN BIT(13) -+#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16) -+#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17) -+#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20) -+#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21) -+#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24) -+ -+/* RCC_MP_APB3ENSETR register fields */ -+#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0) -+#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1) -+#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2) -+#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3) -+#define RCC_MP_APB3ENSETR_VREFEN BIT(13) -+#define RCC_MP_APB3ENSETR_DTSEN BIT(16) -+#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17) -+#define RCC_MP_APB3ENSETR_HDPEN BIT(20) -+ -+/* RCC_MP_APB3ENCLRR register fields */ -+#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0) -+#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1) -+#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2) -+#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3) -+#define RCC_MP_APB3ENCLRR_VREFEN BIT(13) -+#define RCC_MP_APB3ENCLRR_DTSEN BIT(16) -+#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17) -+#define RCC_MP_APB3ENCLRR_HDPEN BIT(20) -+ -+/* RCC_MP_S_APB3ENSETR register fields */ -+#define RCC_MP_S_APB3ENSETR_SYSCFGEN BIT(0) -+ -+/* RCC_MP_S_APB3ENCLRR register fields */ -+#define RCC_MP_S_APB3ENCLRR_SYSCFGEN BIT(0) -+ -+/* RCC_MP_NS_APB3ENSETR register fields */ -+#define RCC_MP_NS_APB3ENSETR_SYSCFGEN BIT(0) -+ -+/* RCC_MP_NS_APB3ENCLRR register fields */ -+#define RCC_MP_NS_APB3ENCLRR_SYSCFGEN BIT(0) -+ -+/* RCC_MP_APB4ENSETR register fields */ -+#define RCC_MP_APB4ENSETR_DCMIPPEN BIT(1) -+#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8) -+#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15) -+#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16) -+#define RCC_MP_APB4ENSETR_STGENROEN BIT(20) -+ -+/* RCC_MP_APB4ENCLRR register fields */ -+#define RCC_MP_APB4ENCLRR_DCMIPPEN BIT(1) -+#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8) -+#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15) -+#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16) -+#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20) -+ -+/* RCC_MP_S_APB4ENSETR register fields */ -+#define RCC_MP_S_APB4ENSETR_LTDCEN BIT(0) -+ -+/* RCC_MP_S_APB4ENCLRR register fields */ -+#define RCC_MP_S_APB4ENCLRR_LTDCEN BIT(0) -+ -+/* RCC_MP_NS_APB4ENSETR register fields */ -+#define RCC_MP_NS_APB4ENSETR_LTDCEN BIT(0) -+ -+/* RCC_MP_NS_APB4ENCLRR register fields */ -+#define RCC_MP_NS_APB4ENCLRR_LTDCEN BIT(0) -+ -+/* RCC_MP_APB5ENSETR register fields */ -+#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8) -+#define RCC_MP_APB5ENSETR_TZCEN BIT(11) -+#define RCC_MP_APB5ENSETR_ETZPCEN BIT(13) -+#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15) -+#define RCC_MP_APB5ENSETR_BSECEN BIT(16) -+#define RCC_MP_APB5ENSETR_STGENCEN BIT(20) -+ -+/* RCC_MP_APB5ENCLRR register fields */ -+#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8) -+#define RCC_MP_APB5ENCLRR_TZCEN BIT(11) -+#define RCC_MP_APB5ENCLRR_ETZPCEN BIT(13) -+#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15) -+#define RCC_MP_APB5ENCLRR_BSECEN BIT(16) -+#define RCC_MP_APB5ENCLRR_STGENCEN BIT(20) -+ -+/* RCC_MP_APB6ENSETR register fields */ -+#define RCC_MP_APB6ENSETR_USART1EN BIT(0) -+#define RCC_MP_APB6ENSETR_USART2EN BIT(1) -+#define RCC_MP_APB6ENSETR_SPI4EN BIT(2) -+#define RCC_MP_APB6ENSETR_SPI5EN BIT(3) -+#define RCC_MP_APB6ENSETR_I2C3EN BIT(4) -+#define RCC_MP_APB6ENSETR_I2C4EN BIT(5) -+#define RCC_MP_APB6ENSETR_I2C5EN BIT(6) -+#define RCC_MP_APB6ENSETR_TIM12EN BIT(7) -+#define RCC_MP_APB6ENSETR_TIM13EN BIT(8) -+#define RCC_MP_APB6ENSETR_TIM14EN BIT(9) -+#define RCC_MP_APB6ENSETR_TIM15EN BIT(10) -+#define RCC_MP_APB6ENSETR_TIM16EN BIT(11) -+#define RCC_MP_APB6ENSETR_TIM17EN BIT(12) -+ -+/* RCC_MP_APB6ENCLRR register fields */ -+#define RCC_MP_APB6ENCLRR_USART1EN BIT(0) -+#define RCC_MP_APB6ENCLRR_USART2EN BIT(1) -+#define RCC_MP_APB6ENCLRR_SPI4EN BIT(2) -+#define RCC_MP_APB6ENCLRR_SPI5EN BIT(3) -+#define RCC_MP_APB6ENCLRR_I2C3EN BIT(4) -+#define RCC_MP_APB6ENCLRR_I2C4EN BIT(5) -+#define RCC_MP_APB6ENCLRR_I2C5EN BIT(6) -+#define RCC_MP_APB6ENCLRR_TIM12EN BIT(7) -+#define RCC_MP_APB6ENCLRR_TIM13EN BIT(8) -+#define RCC_MP_APB6ENCLRR_TIM14EN BIT(9) -+#define RCC_MP_APB6ENCLRR_TIM15EN BIT(10) -+#define RCC_MP_APB6ENCLRR_TIM16EN BIT(11) -+#define RCC_MP_APB6ENCLRR_TIM17EN BIT(12) -+ -+/* RCC_MP_AHB2ENSETR register fields */ -+#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0) -+#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1) -+#define RCC_MP_AHB2ENSETR_DMAMUX1EN BIT(2) -+#define RCC_MP_AHB2ENSETR_DMA3EN BIT(3) -+#define RCC_MP_AHB2ENSETR_DMAMUX2EN BIT(4) -+#define RCC_MP_AHB2ENSETR_ADC1EN BIT(5) -+#define RCC_MP_AHB2ENSETR_ADC2EN BIT(6) -+#define RCC_MP_AHB2ENSETR_USBOEN BIT(8) -+ -+/* RCC_MP_AHB2ENCLRR register fields */ -+#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0) -+#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1) -+#define RCC_MP_AHB2ENCLRR_DMAMUX1EN BIT(2) -+#define RCC_MP_AHB2ENCLRR_DMA3EN BIT(3) -+#define RCC_MP_AHB2ENCLRR_DMAMUX2EN BIT(4) -+#define RCC_MP_AHB2ENCLRR_ADC1EN BIT(5) -+#define RCC_MP_AHB2ENCLRR_ADC2EN BIT(6) -+#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8) -+ -+/* RCC_MP_AHB4ENSETR register fields */ -+#define RCC_MP_AHB4ENSETR_TSCEN BIT(15) -+ -+/* RCC_MP_AHB4ENCLRR register fields */ -+#define RCC_MP_AHB4ENCLRR_TSCEN BIT(15) -+ -+/* RCC_MP_S_AHB4ENSETR register fields */ -+#define RCC_MP_S_AHB4ENSETR_GPIOAEN BIT(0) -+#define RCC_MP_S_AHB4ENSETR_GPIOBEN BIT(1) -+#define RCC_MP_S_AHB4ENSETR_GPIOCEN BIT(2) -+#define RCC_MP_S_AHB4ENSETR_GPIODEN BIT(3) -+#define RCC_MP_S_AHB4ENSETR_GPIOEEN BIT(4) -+#define RCC_MP_S_AHB4ENSETR_GPIOFEN BIT(5) -+#define RCC_MP_S_AHB4ENSETR_GPIOGEN BIT(6) -+#define RCC_MP_S_AHB4ENSETR_GPIOHEN BIT(7) -+#define RCC_MP_S_AHB4ENSETR_GPIOIEN BIT(8) -+ -+/* RCC_MP_S_AHB4ENCLRR register fields */ -+#define RCC_MP_S_AHB4ENCLRR_GPIOAEN BIT(0) -+#define RCC_MP_S_AHB4ENCLRR_GPIOBEN BIT(1) -+#define RCC_MP_S_AHB4ENCLRR_GPIOCEN BIT(2) -+#define RCC_MP_S_AHB4ENCLRR_GPIODEN BIT(3) -+#define RCC_MP_S_AHB4ENCLRR_GPIOEEN BIT(4) -+#define RCC_MP_S_AHB4ENCLRR_GPIOFEN BIT(5) -+#define RCC_MP_S_AHB4ENCLRR_GPIOGEN BIT(6) -+#define RCC_MP_S_AHB4ENCLRR_GPIOHEN BIT(7) -+#define RCC_MP_S_AHB4ENCLRR_GPIOIEN BIT(8) -+ -+/* RCC_MP_NS_AHB4ENSETR register fields */ -+#define RCC_MP_NS_AHB4ENSETR_GPIOAEN BIT(0) -+#define RCC_MP_NS_AHB4ENSETR_GPIOBEN BIT(1) -+#define RCC_MP_NS_AHB4ENSETR_GPIOCEN BIT(2) -+#define RCC_MP_NS_AHB4ENSETR_GPIODEN BIT(3) -+#define RCC_MP_NS_AHB4ENSETR_GPIOEEN BIT(4) -+#define RCC_MP_NS_AHB4ENSETR_GPIOFEN BIT(5) -+#define RCC_MP_NS_AHB4ENSETR_GPIOGEN BIT(6) -+#define RCC_MP_NS_AHB4ENSETR_GPIOHEN BIT(7) -+#define RCC_MP_NS_AHB4ENSETR_GPIOIEN BIT(8) -+ -+/* RCC_MP_NS_AHB4ENCLRR register fields */ -+#define RCC_MP_NS_AHB4ENCLRR_GPIOAEN BIT(0) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOBEN BIT(1) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOCEN BIT(2) -+#define RCC_MP_NS_AHB4ENCLRR_GPIODEN BIT(3) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOEEN BIT(4) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOFEN BIT(5) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOGEN BIT(6) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOHEN BIT(7) -+#define RCC_MP_NS_AHB4ENCLRR_GPIOIEN BIT(8) -+ -+/* RCC_MP_AHB5ENSETR register fields */ -+#define RCC_MP_AHB5ENSETR_PKAEN BIT(2) -+#define RCC_MP_AHB5ENSETR_SAESEN BIT(3) -+#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4) -+#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5) -+#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6) -+#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8) -+#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16) -+ -+/* RCC_MP_AHB5ENCLRR register fields */ -+#define RCC_MP_AHB5ENCLRR_PKAEN BIT(2) -+#define RCC_MP_AHB5ENCLRR_SAESEN BIT(3) -+#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4) -+#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5) -+#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6) -+#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8) -+#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16) -+ -+/* RCC_MP_AHB6ENSETR register fields */ -+#define RCC_MP_AHB6ENSETR_MCEEN BIT(1) -+#define RCC_MP_AHB6ENSETR_ETH1CKEN BIT(7) -+#define RCC_MP_AHB6ENSETR_ETH1TXEN BIT(8) -+#define RCC_MP_AHB6ENSETR_ETH1RXEN BIT(9) -+#define RCC_MP_AHB6ENSETR_ETH1MACEN BIT(10) -+#define RCC_MP_AHB6ENSETR_FMCEN BIT(12) -+#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14) -+#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16) -+#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17) -+#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20) -+#define RCC_MP_AHB6ENSETR_USBHEN BIT(24) -+#define RCC_MP_AHB6ENSETR_ETH2CKEN BIT(27) -+#define RCC_MP_AHB6ENSETR_ETH2TXEN BIT(28) -+#define RCC_MP_AHB6ENSETR_ETH2RXEN BIT(29) -+#define RCC_MP_AHB6ENSETR_ETH2MACEN BIT(30) -+ -+/* RCC_MP_AHB6ENCLRR register fields */ -+#define RCC_MP_AHB6ENCLRR_MCEEN BIT(1) -+#define RCC_MP_AHB6ENCLRR_ETH1CKEN BIT(7) -+#define RCC_MP_AHB6ENCLRR_ETH1TXEN BIT(8) -+#define RCC_MP_AHB6ENCLRR_ETH1RXEN BIT(9) -+#define RCC_MP_AHB6ENCLRR_ETH1MACEN BIT(10) -+#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12) -+#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14) -+#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16) -+#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17) -+#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20) -+#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24) -+#define RCC_MP_AHB6ENCLRR_ETH2CKEN BIT(27) -+#define RCC_MP_AHB6ENCLRR_ETH2TXEN BIT(28) -+#define RCC_MP_AHB6ENCLRR_ETH2RXEN BIT(29) -+#define RCC_MP_AHB6ENCLRR_ETH2MACEN BIT(30) -+ -+/* RCC_MP_S_AHB6ENSETR register fields */ -+#define RCC_MP_S_AHB6ENSETR_MDMAEN BIT(0) -+ -+/* RCC_MP_S_AHB6ENCLRR register fields */ -+#define RCC_MP_S_AHB6ENCLRR_MDMAEN BIT(0) -+ -+/* RCC_MP_NS_AHB6ENSETR register fields */ -+#define RCC_MP_NS_AHB6ENSETR_MDMAEN BIT(0) -+ -+/* RCC_MP_NS_AHB6ENCLRR register fields */ -+#define RCC_MP_NS_AHB6ENCLRR_MDMAEN BIT(0) -+ -+/* RCC_MP_APB1LPENSETR register fields */ -+#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0) -+#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1) -+#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2) -+#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3) -+#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4) -+#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5) -+#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9) -+#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11) -+#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12) -+#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15) -+#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16) -+#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17) -+#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18) -+#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19) -+#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21) -+#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22) -+#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26) -+ -+/* RCC_MP_APB1LPENCLRR register fields */ -+#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0) -+#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1) -+#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2) -+#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3) -+#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4) -+#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5) -+#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9) -+#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11) -+#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12) -+#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15) -+#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16) -+#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17) -+#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18) -+#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19) -+#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21) -+#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22) -+#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26) -+ -+/* RCC_MP_APB2LPENSETR register fields */ -+#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0) -+#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1) -+#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8) -+#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13) -+#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16) -+#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17) -+#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20) -+#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21) -+#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24) -+ -+/* RCC_MP_APB2LPENCLRR register fields */ -+#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0) -+#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1) -+#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8) -+#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13) -+#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16) -+#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17) -+#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20) -+#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21) -+#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24) -+ -+/* RCC_MP_APB3LPENSETR register fields */ -+#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0) -+#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1) -+#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2) -+#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3) -+#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13) -+#define RCC_MP_APB3LPENSETR_DTSLPEN BIT(16) -+#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17) -+ -+/* RCC_MP_APB3LPENCLRR register fields */ -+#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0) -+#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1) -+#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2) -+#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3) -+#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13) -+#define RCC_MP_APB3LPENCLRR_DTSLPEN BIT(16) -+#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17) -+ -+/* RCC_MP_S_APB3LPENSETR register fields */ -+#define RCC_MP_S_APB3LPENSETR_SYSCFGLPEN BIT(0) -+ -+/* RCC_MP_S_APB3LPENCLRR register fields */ -+#define RCC_MP_S_APB3LPENCLRR_SYSCFGLPEN BIT(0) -+ -+/* RCC_MP_NS_APB3LPENSETR register fields */ -+#define RCC_MP_NS_APB3LPENSETR_SYSCFGLPEN BIT(0) -+ -+/* RCC_MP_NS_APB3LPENCLRR register fields */ -+#define RCC_MP_NS_APB3LPENCLRR_SYSCFGLPEN BIT(0) -+ -+/* RCC_MP_APB4LPENSETR register fields */ -+#define RCC_MP_APB4LPENSETR_DCMIPPLPEN BIT(1) -+#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8) -+#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15) -+#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16) -+#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20) -+#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21) -+ -+/* RCC_MP_APB4LPENCLRR register fields */ -+#define RCC_MP_APB4LPENCLRR_DCMIPPLPEN BIT(1) -+#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8) -+#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15) -+#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16) -+#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20) -+#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21) -+ -+/* RCC_MP_S_APB4LPENSETR register fields */ -+#define RCC_MP_S_APB4LPENSETR_LTDCLPEN BIT(0) -+ -+/* RCC_MP_S_APB4LPENCLRR register fields */ -+#define RCC_MP_S_APB4LPENCLRR_LTDCLPEN BIT(0) -+ -+/* RCC_MP_NS_APB4LPENSETR register fields */ -+#define RCC_MP_NS_APB4LPENSETR_LTDCLPEN BIT(0) -+ -+/* RCC_MP_NS_APB4LPENCLRR register fields */ -+#define RCC_MP_NS_APB4LPENCLRR_LTDCLPEN BIT(0) -+ -+/* RCC_MP_APB5LPENSETR register fields */ -+#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8) -+#define RCC_MP_APB5LPENSETR_TZCLPEN BIT(11) -+#define RCC_MP_APB5LPENSETR_ETZPCLPEN BIT(13) -+#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15) -+#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16) -+#define RCC_MP_APB5LPENSETR_STGENCLPEN BIT(20) -+#define RCC_MP_APB5LPENSETR_STGENCSTPEN BIT(21) -+ -+/* RCC_MP_APB5LPENCLRR register fields */ -+#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8) -+#define RCC_MP_APB5LPENCLRR_TZCLPEN BIT(11) -+#define RCC_MP_APB5LPENCLRR_ETZPCLPEN BIT(13) -+#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15) -+#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16) -+#define RCC_MP_APB5LPENCLRR_STGENCLPEN BIT(20) -+#define RCC_MP_APB5LPENCLRR_STGENCSTPEN BIT(21) -+ -+/* RCC_MP_APB6LPENSETR register fields */ -+#define RCC_MP_APB6LPENSETR_USART1LPEN BIT(0) -+#define RCC_MP_APB6LPENSETR_USART2LPEN BIT(1) -+#define RCC_MP_APB6LPENSETR_SPI4LPEN BIT(2) -+#define RCC_MP_APB6LPENSETR_SPI5LPEN BIT(3) -+#define RCC_MP_APB6LPENSETR_I2C3LPEN BIT(4) -+#define RCC_MP_APB6LPENSETR_I2C4LPEN BIT(5) -+#define RCC_MP_APB6LPENSETR_I2C5LPEN BIT(6) -+#define RCC_MP_APB6LPENSETR_TIM12LPEN BIT(7) -+#define RCC_MP_APB6LPENSETR_TIM13LPEN BIT(8) -+#define RCC_MP_APB6LPENSETR_TIM14LPEN BIT(9) -+#define RCC_MP_APB6LPENSETR_TIM15LPEN BIT(10) -+#define RCC_MP_APB6LPENSETR_TIM16LPEN BIT(11) -+#define RCC_MP_APB6LPENSETR_TIM17LPEN BIT(12) -+ -+/* RCC_MP_APB6LPENCLRR register fields */ -+#define RCC_MP_APB6LPENCLRR_USART1LPEN BIT(0) -+#define RCC_MP_APB6LPENCLRR_USART2LPEN BIT(1) -+#define RCC_MP_APB6LPENCLRR_SPI4LPEN BIT(2) -+#define RCC_MP_APB6LPENCLRR_SPI5LPEN BIT(3) -+#define RCC_MP_APB6LPENCLRR_I2C3LPEN BIT(4) -+#define RCC_MP_APB6LPENCLRR_I2C4LPEN BIT(5) -+#define RCC_MP_APB6LPENCLRR_I2C5LPEN BIT(6) -+#define RCC_MP_APB6LPENCLRR_TIM12LPEN BIT(7) -+#define RCC_MP_APB6LPENCLRR_TIM13LPEN BIT(8) -+#define RCC_MP_APB6LPENCLRR_TIM14LPEN BIT(9) -+#define RCC_MP_APB6LPENCLRR_TIM15LPEN BIT(10) -+#define RCC_MP_APB6LPENCLRR_TIM16LPEN BIT(11) -+#define RCC_MP_APB6LPENCLRR_TIM17LPEN BIT(12) -+ -+/* RCC_MP_AHB2LPENSETR register fields */ -+#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0) -+#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1) -+#define RCC_MP_AHB2LPENSETR_DMAMUX1LPEN BIT(2) -+#define RCC_MP_AHB2LPENSETR_DMA3LPEN BIT(3) -+#define RCC_MP_AHB2LPENSETR_DMAMUX2LPEN BIT(4) -+#define RCC_MP_AHB2LPENSETR_ADC1LPEN BIT(5) -+#define RCC_MP_AHB2LPENSETR_ADC2LPEN BIT(6) -+#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8) -+ -+/* RCC_MP_AHB2LPENCLRR register fields */ -+#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0) -+#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1) -+#define RCC_MP_AHB2LPENCLRR_DMAMUX1LPEN BIT(2) -+#define RCC_MP_AHB2LPENCLRR_DMA3LPEN BIT(3) -+#define RCC_MP_AHB2LPENCLRR_DMAMUX2LPEN BIT(4) -+#define RCC_MP_AHB2LPENCLRR_ADC1LPEN BIT(5) -+#define RCC_MP_AHB2LPENCLRR_ADC2LPEN BIT(6) -+#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8) -+ -+/* RCC_MP_AHB4LPENSETR register fields */ -+#define RCC_MP_AHB4LPENSETR_TSCLPEN BIT(15) -+ -+/* RCC_MP_AHB4LPENCLRR register fields */ -+#define RCC_MP_AHB4LPENCLRR_TSCLPEN BIT(15) -+ -+/* RCC_MP_S_AHB4LPENSETR register fields */ -+#define RCC_MP_S_AHB4LPENSETR_GPIOALPEN BIT(0) -+#define RCC_MP_S_AHB4LPENSETR_GPIOBLPEN BIT(1) -+#define RCC_MP_S_AHB4LPENSETR_GPIOCLPEN BIT(2) -+#define RCC_MP_S_AHB4LPENSETR_GPIODLPEN BIT(3) -+#define RCC_MP_S_AHB4LPENSETR_GPIOELPEN BIT(4) -+#define RCC_MP_S_AHB4LPENSETR_GPIOFLPEN BIT(5) -+#define RCC_MP_S_AHB4LPENSETR_GPIOGLPEN BIT(6) -+#define RCC_MP_S_AHB4LPENSETR_GPIOHLPEN BIT(7) -+#define RCC_MP_S_AHB4LPENSETR_GPIOILPEN BIT(8) -+ -+/* RCC_MP_S_AHB4LPENCLRR register fields */ -+#define RCC_MP_S_AHB4LPENCLRR_GPIOALPEN BIT(0) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOBLPEN BIT(1) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOCLPEN BIT(2) -+#define RCC_MP_S_AHB4LPENCLRR_GPIODLPEN BIT(3) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOELPEN BIT(4) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOFLPEN BIT(5) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOGLPEN BIT(6) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOHLPEN BIT(7) -+#define RCC_MP_S_AHB4LPENCLRR_GPIOILPEN BIT(8) -+ -+/* RCC_MP_NS_AHB4LPENSETR register fields */ -+#define RCC_MP_NS_AHB4LPENSETR_GPIOALPEN BIT(0) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOBLPEN BIT(1) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOCLPEN BIT(2) -+#define RCC_MP_NS_AHB4LPENSETR_GPIODLPEN BIT(3) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOELPEN BIT(4) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOFLPEN BIT(5) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOGLPEN BIT(6) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOHLPEN BIT(7) -+#define RCC_MP_NS_AHB4LPENSETR_GPIOILPEN BIT(8) -+ -+/* RCC_MP_NS_AHB4LPENCLRR register fields */ -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOALPEN BIT(0) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOBLPEN BIT(1) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOCLPEN BIT(2) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIODLPEN BIT(3) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOELPEN BIT(4) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOFLPEN BIT(5) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOGLPEN BIT(6) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOHLPEN BIT(7) -+#define RCC_MP_NS_AHB4LPENCLRR_GPIOILPEN BIT(8) -+ -+/* RCC_MP_AHB5LPENSETR register fields */ -+#define RCC_MP_AHB5LPENSETR_PKALPEN BIT(2) -+#define RCC_MP_AHB5LPENSETR_SAESLPEN BIT(3) -+#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4) -+#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5) -+#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6) -+#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8) -+ -+/* RCC_MP_AHB5LPENCLRR register fields */ -+#define RCC_MP_AHB5LPENCLRR_PKALPEN BIT(2) -+#define RCC_MP_AHB5LPENCLRR_SAESLPEN BIT(3) -+#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4) -+#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5) -+#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6) -+#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8) -+ -+/* RCC_MP_AHB6LPENSETR register fields */ -+#define RCC_MP_AHB6LPENSETR_MCELPEN BIT(1) -+#define RCC_MP_AHB6LPENSETR_ETH1CKLPEN BIT(7) -+#define RCC_MP_AHB6LPENSETR_ETH1TXLPEN BIT(8) -+#define RCC_MP_AHB6LPENSETR_ETH1RXLPEN BIT(9) -+#define RCC_MP_AHB6LPENSETR_ETH1MACLPEN BIT(10) -+#define RCC_MP_AHB6LPENSETR_ETH1STPEN BIT(11) -+#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12) -+#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14) -+#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16) -+#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17) -+#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20) -+#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24) -+#define RCC_MP_AHB6LPENSETR_ETH2CKLPEN BIT(27) -+#define RCC_MP_AHB6LPENSETR_ETH2TXLPEN BIT(28) -+#define RCC_MP_AHB6LPENSETR_ETH2RXLPEN BIT(29) -+#define RCC_MP_AHB6LPENSETR_ETH2MACLPEN BIT(30) -+#define RCC_MP_AHB6LPENSETR_ETH2STPEN BIT(31) -+ -+/* RCC_MP_AHB6LPENCLRR register fields */ -+#define RCC_MP_AHB6LPENCLRR_MCELPEN BIT(1) -+#define RCC_MP_AHB6LPENCLRR_ETH1CKLPEN BIT(7) -+#define RCC_MP_AHB6LPENCLRR_ETH1TXLPEN BIT(8) -+#define RCC_MP_AHB6LPENCLRR_ETH1RXLPEN BIT(9) -+#define RCC_MP_AHB6LPENCLRR_ETH1MACLPEN BIT(10) -+#define RCC_MP_AHB6LPENCLRR_ETH1STPEN BIT(11) -+#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12) -+#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14) -+#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16) -+#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17) -+#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20) -+#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24) -+#define RCC_MP_AHB6LPENCLRR_ETH2CKLPEN BIT(27) -+#define RCC_MP_AHB6LPENCLRR_ETH2TXLPEN BIT(28) -+#define RCC_MP_AHB6LPENCLRR_ETH2RXLPEN BIT(29) -+#define RCC_MP_AHB6LPENCLRR_ETH2MACLPEN BIT(30) -+#define RCC_MP_AHB6LPENCLRR_ETH2STPEN BIT(31) -+ -+/* RCC_MP_S_AHB6LPENSETR register fields */ -+#define RCC_MP_S_AHB6LPENSETR_MDMALPEN BIT(0) -+ -+/* RCC_MP_S_AHB6LPENCLRR register fields */ -+#define RCC_MP_S_AHB6LPENCLRR_MDMALPEN BIT(0) -+ -+/* RCC_MP_NS_AHB6LPENSETR register fields */ -+#define RCC_MP_NS_AHB6LPENSETR_MDMALPEN BIT(0) -+ -+/* RCC_MP_NS_AHB6LPENCLRR register fields */ -+#define RCC_MP_NS_AHB6LPENCLRR_MDMALPEN BIT(0) -+ -+/* RCC_MP_S_AXIMLPENSETR register fields */ -+#define RCC_MP_S_AXIMLPENSETR_SYSRAMLPEN BIT(0) -+ -+/* RCC_MP_S_AXIMLPENCLRR register fields */ -+#define RCC_MP_S_AXIMLPENCLRR_SYSRAMLPEN BIT(0) -+ -+/* RCC_MP_NS_AXIMLPENSETR register fields */ -+#define RCC_MP_NS_AXIMLPENSETR_SYSRAMLPEN BIT(0) -+ -+/* RCC_MP_NS_AXIMLPENCLRR register fields */ -+#define RCC_MP_NS_AXIMLPENCLRR_SYSRAMLPEN BIT(0) -+ -+/* RCC_MP_MLAHBLPENSETR register fields */ -+#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0) -+#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1) -+#define RCC_MP_MLAHBLPENSETR_SRAM3LPEN BIT(2) -+ -+/* RCC_MP_MLAHBLPENCLRR register fields */ -+#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0) -+#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1) -+#define RCC_MP_MLAHBLPENCLRR_SRAM3LPEN BIT(2) -+ -+/* RCC_APB3SECSR register fields */ -+#define RCC_APB3SECSR_LPTIM2SECF 0 -+#define RCC_APB3SECSR_LPTIM3SECF 1 -+#define RCC_APB3SECSR_VREFSECF 13 -+ -+/* RCC_APB4SECSR register fields */ -+#define RCC_APB4SECSR_DCMIPPSECF 1 -+#define RCC_APB4SECSR_USBPHYSECF 16 -+ -+/* RCC_APB5SECSR register fields */ -+#define RCC_APB5SECSR_RTCSECF 8 -+#define RCC_APB5SECSR_TZCSECF 11 -+#define RCC_APB5SECSR_ETZPCSECF 13 -+#define RCC_APB5SECSR_IWDG1SECF 15 -+#define RCC_APB5SECSR_BSECSECF 16 -+#define RCC_APB5SECSR_STGENCSECF_MASK GENMASK(21, 20) -+#define RCC_APB5SECSR_STGENCSECF 20 -+#define RCC_APB5SECSR_STGENROSECF 21 -+ -+/* RCC_APB6SECSR register fields */ -+#define RCC_APB6SECSR_USART1SECF 0 -+#define RCC_APB6SECSR_USART2SECF 1 -+#define RCC_APB6SECSR_SPI4SECF 2 -+#define RCC_APB6SECSR_SPI5SECF 3 -+#define RCC_APB6SECSR_I2C3SECF 4 -+#define RCC_APB6SECSR_I2C4SECF 5 -+#define RCC_APB6SECSR_I2C5SECF 6 -+#define RCC_APB6SECSR_TIM12SECF 7 -+#define RCC_APB6SECSR_TIM13SECF 8 -+#define RCC_APB6SECSR_TIM14SECF 9 -+#define RCC_APB6SECSR_TIM15SECF 10 -+#define RCC_APB6SECSR_TIM16SECF 11 -+#define RCC_APB6SECSR_TIM17SECF 12 -+ -+/* RCC_AHB2SECSR register fields */ -+#define RCC_AHB2SECSR_DMA3SECF 3 -+#define RCC_AHB2SECSR_DMAMUX2SECF 4 -+#define RCC_AHB2SECSR_ADC1SECF 5 -+#define RCC_AHB2SECSR_ADC2SECF 6 -+#define RCC_AHB2SECSR_USBOSECF 8 -+ -+/* RCC_AHB4SECSR register fields */ -+#define RCC_AHB4SECSR_TSCSECF 15 -+ -+/* RCC_AHB5SECSR register fields */ -+#define RCC_AHB5SECSR_PKASECF 2 -+#define RCC_AHB5SECSR_SAESSECF 3 -+#define RCC_AHB5SECSR_CRYP1SECF 4 -+#define RCC_AHB5SECSR_HASH1SECF 5 -+#define RCC_AHB5SECSR_RNG1SECF 6 -+#define RCC_AHB5SECSR_BKPSRAMSECF 8 -+ -+/* RCC_AHB6SECSR register fields */ -+#define RCC_AHB6SECSR_MCESECF 1 -+#define RCC_AHB6SECSR_FMCSECF 12 -+#define RCC_AHB6SECSR_QSPISECF 14 -+#define RCC_AHB6SECSR_SDMMC1SECF 16 -+#define RCC_AHB6SECSR_SDMMC2SECF 17 -+ -+#define RCC_AHB6SECSR_ETH1SECF_MASK GENMASK(11, 7) -+#define RCC_AHB6SECSR_ETH2SECF_MASK GENMASK(31, 27) -+#define RCC_AHB6SECSR_ETH1SECF_SHIFT 7 -+#define RCC_AHB6SECSR_ETH2SECF_SHIFT 27 -+ -+#define RCC_AHB6SECSR_ETH1CKSECF 7 -+#define RCC_AHB6SECSR_ETH1TXSECF 8 -+#define RCC_AHB6SECSR_ETH1RXSECF 9 -+#define RCC_AHB6SECSR_ETH1MACSECF 10 -+#define RCC_AHB6SECSR_ETH1STPSECF 11 -+ -+#define RCC_AHB6SECSR_ETH2CKSECF 27 -+#define RCC_AHB6SECSR_ETH2TXSECF 28 -+#define RCC_AHB6SECSR_ETH2RXSECF 29 -+#define RCC_AHB6SECSR_ETH2MACSECF 30 -+#define RCC_AHB6SECSR_ETH2STPSECF 31 -+ -+/* RCC_VERR register fields */ -+#define RCC_VERR_MINREV_MASK GENMASK(3, 0) -+#define RCC_VERR_MAJREV_MASK GENMASK(7, 4) -+#define RCC_VERR_MINREV_SHIFT 0 -+#define RCC_VERR_MAJREV_SHIFT 4 -+ -+/* RCC_IDR register fields */ -+#define RCC_IDR_ID_MASK GENMASK(31, 0) -+#define RCC_IDR_ID_SHIFT 0 -+ -+/* RCC_SIDR register fields */ -+#define RCC_SIDR_SID_MASK GENMASK(31, 0) -+#define RCC_SIDR_SID_SHIFT 0 -+ -+#endif /* STM32MP13_RCC_H */ -+ -diff --git a/drivers/clocksource/timer-stm32-lp.c b/drivers/clocksource/timer-stm32-lp.c -index db2841d0beb8..90c10f378df2 100644 ---- a/drivers/clocksource/timer-stm32-lp.c -+++ b/drivers/clocksource/timer-stm32-lp.c -@@ -168,9 +168,7 @@ static int stm32_clkevent_lp_probe(struct platform_device *pdev) - } - - if (of_property_read_bool(pdev->dev.parent->of_node, "wakeup-source")) { -- ret = device_init_wakeup(&pdev->dev, true); -- if (ret) -- goto out_clk_disable; -+ device_set_wakeup_capable(&pdev->dev, true); - - ret = dev_pm_set_wake_irq(&pdev->dev, irq); - if (ret) -diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h -index e02770b98e6c..2e23e0384b0a 100644 ---- a/include/dt-bindings/clock/stm32mp1-clks.h -+++ b/include/dt-bindings/clock/stm32mp1-clks.h -@@ -179,6 +179,12 @@ - #define DAC12_K 168 - #define ETHPTP_K 169 - -+#define PCLK1 170 -+#define PCLK2 171 -+#define PCLK3 172 -+#define PCLK4 173 -+#define PCLK5 174 -+ - /* PLL */ - #define PLL1 176 - #define PLL2 177 -@@ -249,30 +255,26 @@ - #define STM32MP1_LAST_CLK 232 - - /* SCMI clock identifiers */ --#define CK_SCMI0_HSE 0 --#define CK_SCMI0_HSI 1 --#define CK_SCMI0_CSI 2 --#define CK_SCMI0_LSE 3 --#define CK_SCMI0_LSI 4 --#define CK_SCMI0_PLL2_Q 5 --#define CK_SCMI0_PLL2_R 6 --#define CK_SCMI0_MPU 7 --#define CK_SCMI0_AXI 8 --#define CK_SCMI0_BSEC 9 --#define CK_SCMI0_CRYP1 10 --#define CK_SCMI0_GPIOZ 11 --#define CK_SCMI0_HASH1 12 --#define CK_SCMI0_I2C4 13 --#define CK_SCMI0_I2C6 14 --#define CK_SCMI0_IWDG1 15 --#define CK_SCMI0_RNG1 16 --#define CK_SCMI0_RTC 17 --#define CK_SCMI0_RTCAPB 18 --#define CK_SCMI0_SPI6 19 --#define CK_SCMI0_USART1 20 -- --#define CK_SCMI1_PLL3_Q 0 --#define CK_SCMI1_PLL3_R 1 --#define CK_SCMI1_MCU 2 -+#define CK_SCMI_HSE 0 -+#define CK_SCMI_HSI 1 -+#define CK_SCMI_CSI 2 -+#define CK_SCMI_LSE 3 -+#define CK_SCMI_LSI 4 -+#define CK_SCMI_PLL2_Q 5 -+#define CK_SCMI_PLL2_R 6 -+#define CK_SCMI_MPU 7 -+#define CK_SCMI_AXI 8 -+#define CK_SCMI_BSEC 9 -+#define CK_SCMI_CRYP1 10 -+#define CK_SCMI_GPIOZ 11 -+#define CK_SCMI_HASH1 12 -+#define CK_SCMI_I2C4 13 -+#define CK_SCMI_I2C6 14 -+#define CK_SCMI_IWDG1 15 -+#define CK_SCMI_RNG1 16 -+#define CK_SCMI_RTC 17 -+#define CK_SCMI_RTCAPB 18 -+#define CK_SCMI_SPI6 19 -+#define CK_SCMI_USART1 20 - - #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ -diff --git a/include/dt-bindings/clock/stm32mp13-clks.h b/include/dt-bindings/clock/stm32mp13-clks.h -new file mode 100644 -index 000000000000..2a110340ff2f ---- /dev/null -+++ b/include/dt-bindings/clock/stm32mp13-clks.h -@@ -0,0 +1,235 @@ -+/* SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause */ -+/* -+ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved -+ * Author: Gabriel Fernandez for STMicroelectronics. -+ */ -+ -+#ifndef _DT_BINDINGS_STM32MP13_CLKS_H_ -+#define _DT_BINDINGS_STM32MP13_CLKS_H_ -+ -+/* OSCILLATOR clocks */ -+#define CK_HSE 0 -+#define CK_CSI 1 -+#define CK_LSI 2 -+#define CK_LSE 3 -+#define CK_HSI 4 -+#define CK_HSE_DIV2 5 -+ -+/* PLL */ -+#define PLL1 6 -+#define PLL2 7 -+#define PLL3 8 -+#define PLL4 9 -+ -+/* ODF */ -+#define PLL1_P 10 -+#define PLL1_Q 11 -+#define PLL1_R 12 -+#define PLL2_P 13 -+#define PLL2_Q 14 -+#define PLL2_R 15 -+#define PLL3_P 16 -+#define PLL3_Q 17 -+#define PLL3_R 18 -+#define PLL4_P 19 -+#define PLL4_Q 20 -+#define PLL4_R 21 -+ -+#define PCLK1 22 -+#define PCLK2 23 -+#define PCLK3 24 -+#define PCLK4 25 -+#define PCLK5 26 -+#define PCLK6 27 -+ -+/* SYSTEM CLOCK */ -+#define CK_PER 28 -+#define CK_MPU 29 -+#define CK_AXI 30 -+#define CK_MLAHB 31 -+ -+/* BASE TIMER */ -+#define CK_TIMG1 32 -+#define CK_TIMG2 33 -+#define CK_TIMG3 34 -+ -+/* AUX */ -+#define RTC 35 -+ -+/* TRACE & DEBUG clocks */ -+#define CK_DBG 36 -+#define CK_TRACE 37 -+ -+/* MCO clocks */ -+#define CK_MCO1 38 -+#define CK_MCO2 39 -+ -+/* IP clocks */ -+#define SYSCFG 40 -+#define VREF 41 -+#define DTS 42 -+#define PMBCTRL 43 -+#define HDP 44 -+#define IWDG2 45 -+#define STGENRO 46 -+#define USART1 47 -+#define RTCAPB 48 -+#define TZC 49 -+#define TZPC 50 -+#define IWDG1 51 -+#define BSEC 52 -+#define DMA1 53 -+#define DMA2 54 -+#define DMAMUX1 55 -+#define DMAMUX2 56 -+#define GPIOA 57 -+#define GPIOB 58 -+#define GPIOC 59 -+#define GPIOD 60 -+#define GPIOE 61 -+#define GPIOF 62 -+#define GPIOG 63 -+#define GPIOH 64 -+#define GPIOI 65 -+#define CRYP1 66 -+#define HASH1 67 -+#define BKPSRAM 68 -+#define MDMA 69 -+#define CRC1 70 -+#define USBH 71 -+#define DMA3 72 -+#define TSC 73 -+#define PKA 74 -+#define AXIMC 75 -+#define MCE 76 -+#define ETH1TX 77 -+#define ETH2TX 78 -+#define ETH1RX 79 -+#define ETH2RX 80 -+#define ETH1MAC 81 -+#define ETH2MAC 82 -+#define ETH1STP 83 -+#define ETH2STP 84 -+ -+/* IP clocks with parents */ -+#define SDMMC1_K 85 -+#define SDMMC2_K 86 -+#define ADC1_K 87 -+#define ADC2_K 88 -+#define FMC_K 89 -+#define QSPI_K 90 -+#define RNG1_K 91 -+#define USBPHY_K 92 -+#define STGEN_K 93 -+#define SPDIF_K 94 -+#define SPI1_K 95 -+#define SPI2_K 96 -+#define SPI3_K 97 -+#define SPI4_K 98 -+#define SPI5_K 99 -+#define I2C1_K 100 -+#define I2C2_K 101 -+#define I2C3_K 102 -+#define I2C4_K 103 -+#define I2C5_K 104 -+#define TIM2_K 105 -+#define TIM3_K 106 -+#define TIM4_K 107 -+#define TIM5_K 108 -+#define TIM6_K 109 -+#define TIM7_K 110 -+#define TIM12_K 111 -+#define TIM13_K 112 -+#define TIM14_K 113 -+#define TIM1_K 114 -+#define TIM8_K 115 -+#define TIM15_K 116 -+#define TIM16_K 117 -+#define TIM17_K 118 -+#define LPTIM1_K 119 -+#define LPTIM2_K 120 -+#define LPTIM3_K 121 -+#define LPTIM4_K 122 -+#define LPTIM5_K 123 -+#define USART1_K 124 -+#define USART2_K 125 -+#define USART3_K 126 -+#define UART4_K 127 -+#define UART5_K 128 -+#define USART6_K 129 -+#define UART7_K 130 -+#define UART8_K 131 -+#define DFSDM_K 132 -+#define FDCAN_K 133 -+#define SAI1_K 134 -+#define SAI2_K 135 -+#define ADFSDM_K 136 -+#define USBO_K 137 -+#define LTDC_PX 138 -+#define ETH1CK_K 139 -+#define ETH1PTP_K 140 -+#define ETH2CK_K 141 -+#define ETH2PTP_K 142 -+#define DCMIPP_K 143 -+#define SAES_K 144 -+#define DTS_K 145 -+ -+/* DDR */ -+#define DDRC1 146 -+#define DDRC1LP 147 -+#define DDRC2 148 -+#define DDRC2LP 149 -+#define DDRPHYC 150 -+#define DDRPHYCLP 151 -+#define DDRCAPB 152 -+#define DDRCAPBLP 153 -+#define AXIDCG 154 -+#define DDRPHYCAPB 155 -+#define DDRPHYCAPBLP 156 -+#define DDRPERFM 157 -+ -+#define ADC1 158 -+#define ADC2 159 -+#define SAI1 160 -+#define SAI2 161 -+ -+#define SPI1 162 -+#define SPI2 163 -+#define SPI3 164 -+#define SPI4 165 -+#define SPI5 166 -+ -+#define STM32MP1_LAST_CLK 167 -+ -+/* SCMI clock identifiers */ -+#define CK_SCMI_HSE 0 -+#define CK_SCMI_HSI 1 -+#define CK_SCMI_CSI 2 -+#define CK_SCMI_LSE 3 -+#define CK_SCMI_LSI 4 -+#define CK_SCMI_HSE_DIV2 5 -+#define CK_SCMI_PLL2_Q 6 -+#define CK_SCMI_PLL2_R 7 -+#define CK_SCMI_PLL3_P 8 -+#define CK_SCMI_PLL3_Q 9 -+#define CK_SCMI_PLL3_R 10 -+#define CK_SCMI_PLL4_P 11 -+#define CK_SCMI_PLL4_Q 12 -+#define CK_SCMI_PLL4_R 13 -+#define CK_SCMI_MPU 14 -+#define CK_SCMI_AXI 15 -+#define CK_SCMI_MLAHB 16 -+#define CK_SCMI_CKPER 17 -+#define CK_SCMI_PCLK1 18 -+#define CK_SCMI_PCLK2 19 -+#define CK_SCMI_PCLK3 20 -+#define CK_SCMI_PCLK4 21 -+#define CK_SCMI_PCLK5 22 -+#define CK_SCMI_PCLK6 23 -+#define CK_SCMI_CKTIMG1 24 -+#define CK_SCMI_CKTIMG2 25 -+#define CK_SCMI_CKTIMG3 26 -+#define CK_SCMI_RTC 27 -+#define CK_SCMI_RTCAPB 28 -+ -+#endif /* _DT_BINDINGS_STM32MP13_CLKS_H_ */ --- -2.17.1 - diff --git a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0006-v5.15-stm32mp-r2-DMA.patch b/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0006-v5.15-stm32mp-r2-DMA.patch deleted file mode 100644 index 703d5425..00000000 --- a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0006-v5.15-stm32mp-r2-DMA.patch +++ /dev/null @@ -1,2097 +0,0 @@ -From 62911b17f33f57875c1b18ed211d5fa0f731ad42 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 3 Nov 2022 15:26:34 +0100 -Subject: [PATCH 06/22] v5.15-stm32mp-r2 DMA - -Signed-off-by: Romuald JEANNE ---- - .../devicetree/bindings/dma/st,stm32-dma.yaml | 47 + - .../bindings/dma/st,stm32-mdma.yaml | 12 +- - drivers/dma/stm32-dma.c | 1169 +++++++++++++++-- - drivers/dma/stm32-dmamux.c | 2 +- - drivers/dma/stm32-mdma.c | 147 ++- - 5 files changed, 1240 insertions(+), 137 deletions(-) - -diff --git a/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml b/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml -index 4bf676fd25dc..99351fe0fa17 100644 ---- a/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml -+++ b/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml -@@ -47,6 +47,14 @@ description: | - not wait for the de-assertion of the REQuest, ACK is only managed - by transfer completion. This must only be used on channels - managing transfers for STM32 USART/UART. -+ -bit 30-29: indicated SRAM Buffer size in (2^order)*PAGE_SIZE. -+ Order is given by those 2 bits starting at 0. -+ Valid only whether Intermediate M2M transfer is set. -+ For cyclic, whether Intermediate M2M transfer is chosen, any value can be set: -+ SRAM buffer size will rely on period size and not on this DT value. -+ -bit 31: Intermediate M2M transfer from/to DDR to/from SRAM throughout MDMA -+ 0: MDMA not used to generate an intermediate M2M transfer -+ 1: MDMA used to generate an intermediate M2M transfer. - - - maintainers: -@@ -82,6 +90,35 @@ properties: - description: if defined, it indicates that the controller - supports memory-to-memory transfer - -+ dmas: -+ description: A list of eight dma specifiers, one for each entry in dma-names. -+ Refer to stm32-mdma.yaml for more details. -+ items: -+ - description: DMA channel 0 connected to the MDMA channel specified -+ - description: DMA channel 1 connected to the MDMA channel specified -+ - description: DMA channel 2 connected to the MDMA channel specified -+ - description: DMA channel 3 connected to the MDMA channel specified -+ - description: DMA channel 4 connected to the MDMA channel specified -+ - description: DMA channel 5 connected to the MDMA channel specified -+ - description: DMA channel 6 connected to the MDMA channel specified -+ - description: DMA channel 7 connected to the MDMA channel specified -+ -+ dma-names: -+ description: Represents each STM32 DMA channel connected to a STM32 MDMA one. -+ items: -+ - const: ch0 -+ - const: ch1 -+ - const: ch2 -+ - const: ch3 -+ - const: ch4 -+ - const: ch5 -+ - const: ch6 -+ - const: ch7 -+ -+ memory-region: -+ description: Phandle to a node describing memory to be used for M2M intermediate transfer -+ between DMA and MDMA. -+ - required: - - compatible - - reg -@@ -111,6 +148,16 @@ examples: - st,mem2mem; - resets = <&rcc 150>; - dma-requests = <8>; -+ dmas = <&mdma1 8 0x3 0x1200000a 0x40026408 0x00000020 1>, -+ <&mdma1 9 0x3 0x1200000a 0x40026408 0x00000800 1>, -+ <&mdma1 10 0x3 0x1200000a 0x40026408 0x00200000 1>, -+ <&mdma1 11 0x3 0x1200000a 0x40026408 0x08000000 1>, -+ <&mdma1 12 0x3 0x1200000a 0x4002640C 0x00000020 1>, -+ <&mdma1 13 0x3 0x1200000a 0x4002640C 0x00000800 1>, -+ <&mdma1 14 0x3 0x1200000a 0x4002640C 0x00200000 1>, -+ <&mdma1 15 0x3 0x1200000a 0x4002640C 0x08000000 1>; -+ dma-names = "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7"; -+ memory-region = <&sram_dmapool>; - }; - - ... -diff --git a/Documentation/devicetree/bindings/dma/st,stm32-mdma.yaml b/Documentation/devicetree/bindings/dma/st,stm32-mdma.yaml -index c30be840be1c..c4bb58014374 100644 ---- a/Documentation/devicetree/bindings/dma/st,stm32-mdma.yaml -+++ b/Documentation/devicetree/bindings/dma/st,stm32-mdma.yaml -@@ -10,8 +10,8 @@ description: | - The STM32 MDMA is a general-purpose direct memory access controller capable of - supporting 64 independent DMA channels with 256 HW requests. - DMA clients connected to the STM32 MDMA controller must use the format -- described in the dma.txt file, using a five-cell specifier for each channel: -- a phandle to the MDMA controller plus the following five integer cells: -+ described in the dma.txt file, using a six-cell specifier for each channel: -+ a phandle to the MDMA controller plus the following six integer cells: - 1. The request line number - 2. The priority level - 0x0: Low -@@ -48,6 +48,10 @@ description: | - if no HW ack signal is used by the MDMA client - 5. A 32bit mask specifying the value to be written to acknowledge the request - if no HW ack signal is used by the MDMA client -+ 6. A bitfield value specifying if the MDMA client wants to generate M2M transfer -+ with HW trigger (1) or not (0). This bitfield should be only enabled for -+ M2M transfer triggered by STM32 DMA client. The memory devices involved in this -+ kind of transfer are SRAM and DDR. - - maintainers: - - Amelie Delaunay -@@ -57,7 +61,7 @@ allOf: - - properties: - "#dma-cells": -- const: 5 -+ const: 6 - - compatible: - const: st,stm32h7-mdma -@@ -97,7 +101,7 @@ examples: - interrupts = <122>; - clocks = <&timer_clk>; - resets = <&rcc 992>; -- #dma-cells = <5>; -+ #dma-cells = <6>; - dma-channels = <16>; - dma-requests = <32>; - st,ahb-addr-masks = <0x20000000>, <0x00000000>; -diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c -index 7dfc743ac433..7c6078c6c3bf 100644 ---- a/drivers/dma/stm32-dma.c -+++ b/drivers/dma/stm32-dma.c -@@ -14,12 +14,14 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -121,6 +123,7 @@ - #define STM32_DMA_FIFO_THRESHOLD_NONE 0x04 - - #define STM32_DMA_MAX_DATA_ITEMS 0xffff -+#define STM32_DMA_SRAM_GRANULARITY PAGE_SIZE - /* - * Valid transfer starts from @0 to @0xFFFE leading to unaligned scatter - * gather at boundary. Thus it's safer to round down this value on FIFO -@@ -142,6 +145,10 @@ - #define STM32_DMA_DIRECT_MODE_GET(n) (((n) & STM32_DMA_DIRECT_MODE_MASK) >> 2) - #define STM32_DMA_ALT_ACK_MODE_MASK BIT(4) - #define STM32_DMA_ALT_ACK_MODE_GET(n) (((n) & STM32_DMA_ALT_ACK_MODE_MASK) >> 4) -+#define STM32_DMA_MDMA_CHAIN_FTR_MASK BIT(31) -+#define STM32_DMA_MDMA_CHAIN_FTR_GET(n) (((n) & STM32_DMA_MDMA_CHAIN_FTR_MASK) >> 31) -+#define STM32_DMA_MDMA_SRAM_SIZE_MASK GENMASK(30, 29) -+#define STM32_DMA_MDMA_SRAM_SIZE_GET(n) (((n) & STM32_DMA_MDMA_SRAM_SIZE_MASK) >> 29) - - enum stm32_dma_width { - STM32_DMA_BYTE, -@@ -183,15 +190,31 @@ struct stm32_dma_chan_reg { - u32 dma_sfcr; - }; - -+struct stm32_dma_mdma_desc { -+ struct sg_table sgt; -+ struct dma_async_tx_descriptor *desc; -+}; -+ -+struct stm32_dma_mdma { -+ struct dma_chan *chan; -+ enum dma_transfer_direction dir; -+ dma_addr_t sram_buf; -+ u32 sram_period; -+}; -+ - struct stm32_dma_sg_req { -- u32 len; -+ struct scatterlist stm32_sgl_req; - struct stm32_dma_chan_reg chan_reg; -+ struct stm32_dma_mdma_desc m_desc; - }; - - struct stm32_dma_desc { - struct virt_dma_desc vdesc; - bool cyclic; - u32 num_sgs; -+ dma_addr_t dma_buf; -+ void *dma_buf_cpu; -+ u32 dma_buf_size; - struct stm32_dma_sg_req sg_req[]; - }; - -@@ -208,6 +231,13 @@ struct stm32_dma_chan { - u32 threshold; - u32 mem_burst; - u32 mem_width; -+ enum dma_status status; -+ struct stm32_dma_mdma mchan; -+ u32 use_mdma; -+ u32 sram_size; -+ u32 residue_after_drain; -+ struct workqueue_struct *mdma_wq; -+ struct work_struct mdma_work; - }; - - struct stm32_dma_device { -@@ -216,6 +246,7 @@ struct stm32_dma_device { - struct clk *clk; - bool mem2mem; - struct stm32_dma_chan chan[STM32_DMA_MAX_CHANNELS]; -+ struct gen_pool *sram_pool; - }; - - static struct stm32_dma_device *stm32_dma_get_dev(struct stm32_dma_chan *chan) -@@ -266,7 +297,7 @@ static int stm32_dma_get_width(struct stm32_dma_chan *chan, - } - - static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len, -- dma_addr_t buf_addr, -+ u64 buf_addr, - u32 threshold) - { - enum dma_slave_buswidth max_width; -@@ -380,6 +411,16 @@ static void stm32_dma_set_fifo_config(struct stm32_dma_chan *chan, - } - } - -+static void stm32_dma_slave_caps(struct dma_chan *c, struct dma_slave_caps *caps) -+{ -+ struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ -+ if (chan->use_mdma) -+ caps->max_sg_burst = 0; /* unlimited */ -+ else -+ caps->max_sg_burst = STM32_DMA_ALIGNED_MAX_DATA_ITEMS; -+} -+ - static int stm32_dma_slave_config(struct dma_chan *c, - struct dma_slave_config *config) - { -@@ -485,17 +526,25 @@ static void stm32_dma_stop(struct stm32_dma_chan *chan) - } - - chan->busy = false; -+ chan->status = DMA_COMPLETE; - } - - static int stm32_dma_terminate_all(struct dma_chan *c) - { - struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ struct stm32_dma_mdma *mchan = &chan->mchan; - unsigned long flags; - LIST_HEAD(head); - -- spin_lock_irqsave(&chan->vchan.lock, flags); -+ if (chan->use_mdma) { -+ spin_lock_irqsave_nested(&chan->vchan.lock, flags, SINGLE_DEPTH_NESTING); -+ dmaengine_terminate_async(mchan->chan); -+ } else { -+ spin_lock_irqsave(&chan->vchan.lock, flags); -+ } - - if (chan->desc) { -+ dma_cookie_complete(&chan->desc->vdesc.tx); - vchan_terminate_vdesc(&chan->desc->vdesc); - if (chan->busy) - stm32_dma_stop(chan); -@@ -509,9 +558,102 @@ static int stm32_dma_terminate_all(struct dma_chan *c) - return 0; - } - -+static u32 stm32_dma_get_remaining_bytes(struct stm32_dma_chan *chan) -+{ -+ u32 dma_scr, width, ndtr; -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ -+ dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); -+ width = STM32_DMA_SCR_PSIZE_GET(dma_scr); -+ ndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); -+ -+ return ndtr << width; -+} -+ -+static int stm32_dma_mdma_drain(struct stm32_dma_chan *chan) -+{ -+ struct stm32_dma_mdma *mchan = &chan->mchan; -+ struct stm32_dma_sg_req *sg_req; -+ struct dma_device *ddev = mchan->chan->device; -+ struct dma_async_tx_descriptor *desc = NULL; -+ enum dma_status status; -+ dma_addr_t src_buf, dst_buf; -+ u32 mdma_residue, mdma_wrote, dma_to_write, len; -+ struct dma_tx_state state; -+ int ret; -+ unsigned long flags; -+ -+ flush_workqueue(chan->mdma_wq); -+ -+ /* DMA/MDMA chain: drain remaining data in SRAM */ -+ -+ /* Get the residue on MDMA side */ -+ status = dmaengine_tx_status(mchan->chan, mchan->chan->cookie, &state); -+ if (status == DMA_COMPLETE) -+ return status; -+ -+ mdma_residue = state.residue; -+ sg_req = &chan->desc->sg_req[chan->next_sg - 1]; -+ len = sg_dma_len(&sg_req->stm32_sgl_req); -+ -+ /* -+ * Total = mdma blocks * sram_period + rest (< sram_period) -+ * so mdma blocks * sram_period = len - mdma residue - rest -+ */ -+ mdma_wrote = len - mdma_residue - (len % mchan->sram_period); -+ -+ /* Remaining data stuck in SRAM */ -+ dma_to_write = mchan->sram_period - stm32_dma_get_remaining_bytes(chan); -+ if (dma_to_write > 0) { -+ spin_lock_irqsave_nested(&chan->vchan.lock, flags, SINGLE_DEPTH_NESTING); -+ -+ /* Terminate current MDMA to initiate a new one */ -+ dmaengine_terminate_async(mchan->chan); -+ -+ /* Stop DMA current operation */ -+ stm32_dma_disable_chan(chan); -+ -+ spin_unlock_irqrestore(&chan->vchan.lock, flags); -+ -+ /* Double buffer management */ -+ src_buf = mchan->sram_buf + -+ ((mdma_wrote / mchan->sram_period) & 0x1) * mchan->sram_period; -+ dst_buf = sg_dma_address(&sg_req->stm32_sgl_req) + mdma_wrote; -+ -+ desc = ddev->device_prep_dma_memcpy(mchan->chan, dst_buf, src_buf, dma_to_write, -+ DMA_PREP_INTERRUPT); -+ if (!desc) -+ return -EINVAL; -+ -+ ret = dma_submit_error(dmaengine_submit(desc)); -+ if (ret < 0) -+ return ret; -+ -+ status = dma_wait_for_async_tx(desc); -+ if (status != DMA_COMPLETE) { -+ dev_err(chan2dev(chan), "%s dma_wait_for_async_tx error\n", __func__); -+ dmaengine_terminate_async(mchan->chan); -+ return -EBUSY; -+ } -+ -+ /* We need to store residue for tx_status() */ -+ chan->residue_after_drain = len - (mdma_wrote + dma_to_write); -+ } -+ -+ return 0; -+} -+ - static void stm32_dma_synchronize(struct dma_chan *c) - { - struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ struct stm32_dma_mdma *mchan = &chan->mchan; -+ -+ if (chan->desc && chan->use_mdma && mchan->dir == DMA_DEV_TO_MEM) -+ if (stm32_dma_mdma_drain(chan)) -+ dev_err(chan2dev(chan), "%s: can't drain DMA\n", __func__); -+ -+ if (chan->use_mdma) -+ dmaengine_synchronize(mchan->chan); - - vchan_synchronize(&chan->vchan); - } -@@ -534,6 +676,231 @@ static void stm32_dma_dump_reg(struct stm32_dma_chan *chan) - dev_dbg(chan2dev(chan), "SFCR: 0x%08x\n", sfcr); - } - -+static int stm32_dma_dummy_memcpy_xfer(struct stm32_dma_chan *chan) -+{ -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ struct dma_device *ddev = &dmadev->ddev; -+ struct stm32_dma_chan_reg reg; -+ u8 src_buf, dst_buf; -+ dma_addr_t dma_src_buf, dma_dst_buf; -+ u32 ndtr, status; -+ int len, ret; -+ -+ ret = 0; -+ src_buf = 0; -+ len = 1; -+ -+ dma_src_buf = dma_map_single(ddev->dev, &src_buf, len, DMA_TO_DEVICE); -+ ret = dma_mapping_error(ddev->dev, dma_src_buf); -+ if (ret < 0) { -+ dev_err(chan2dev(chan), "Source buffer map failed\n"); -+ return ret; -+ } -+ -+ dma_dst_buf = dma_map_single(ddev->dev, &dst_buf, len, DMA_FROM_DEVICE); -+ ret = dma_mapping_error(ddev->dev, dma_dst_buf); -+ if (ret < 0) { -+ dev_err(chan2dev(chan), "Destination buffer map failed\n"); -+ dma_unmap_single(ddev->dev, dma_src_buf, len, DMA_TO_DEVICE); -+ return ret; -+ } -+ -+ reg.dma_scr = STM32_DMA_SCR_DIR(STM32_DMA_MEM_TO_MEM) | -+ STM32_DMA_SCR_PBURST(STM32_DMA_BURST_SINGLE) | -+ STM32_DMA_SCR_MBURST(STM32_DMA_BURST_SINGLE) | -+ STM32_DMA_SCR_MINC | STM32_DMA_SCR_PINC | -+ STM32_DMA_SCR_TEIE; -+ reg.dma_spar = dma_src_buf; -+ reg.dma_sm0ar = dma_dst_buf; -+ reg.dma_sfcr = STM32_DMA_SFCR_MASK | STM32_DMA_SFCR_FTH(STM32_DMA_FIFO_THRESHOLD_FULL); -+ reg.dma_sm1ar = dma_dst_buf; -+ reg.dma_sndtr = 1; -+ -+ stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg.dma_scr); -+ stm32_dma_write(dmadev, STM32_DMA_SPAR(chan->id), reg.dma_spar); -+ stm32_dma_write(dmadev, STM32_DMA_SM0AR(chan->id), reg.dma_sm0ar); -+ stm32_dma_write(dmadev, STM32_DMA_SFCR(chan->id), reg.dma_sfcr); -+ stm32_dma_write(dmadev, STM32_DMA_SM1AR(chan->id), reg.dma_sm1ar); -+ stm32_dma_write(dmadev, STM32_DMA_SNDTR(chan->id), reg.dma_sndtr); -+ -+ /* Clear interrupt status if it is there */ -+ status = stm32_dma_irq_status(chan); -+ if (status) -+ stm32_dma_irq_clear(chan, status); -+ -+ stm32_dma_dump_reg(chan); -+ -+ chan->busy = true; -+ chan->status = DMA_IN_PROGRESS; -+ /* Start DMA */ -+ reg.dma_scr |= STM32_DMA_SCR_EN; -+ stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg.dma_scr); -+ -+ ret = readl_relaxed_poll_timeout_atomic(dmadev->base + STM32_DMA_SNDTR(chan->id), -+ ndtr, !ndtr, 10, 1000); -+ if (ret) { -+ dev_err(chan2dev(chan), "%s: timeout!\n", __func__); -+ ret = -EBUSY; -+ } -+ -+ chan->busy = false; -+ chan->status = DMA_COMPLETE; -+ -+ ret = stm32_dma_disable_chan(chan); -+ status = stm32_dma_irq_status(chan); -+ if (status) -+ stm32_dma_irq_clear(chan, status); -+ -+ dma_unmap_single(ddev->dev, dma_src_buf, len, DMA_TO_DEVICE); -+ dma_unmap_single(ddev->dev, dma_dst_buf, len, DMA_FROM_DEVICE); -+ -+ return ret; -+} -+ -+static int stm32_dma_mdma_flush_remaining(struct stm32_dma_chan *chan) -+{ -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ struct stm32_dma_mdma *mchan = &chan->mchan; -+ struct stm32_dma_sg_req *sg_req; -+ struct dma_device *ddev = mchan->chan->device; -+ struct dma_async_tx_descriptor *desc = NULL; -+ enum dma_status status; -+ dma_addr_t src_buf, dst_buf; -+ u32 residue, remain, len, dma_scr; -+ int ret; -+ -+ residue = stm32_dma_get_remaining_bytes(chan); -+ if (!residue) -+ return 0; -+ -+ dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); -+ if (!(dma_scr & STM32_DMA_SCR_EN)) -+ return -EPERM; -+ -+ sg_req = &chan->desc->sg_req[chan->next_sg - 1]; -+ len = sg_dma_len(&sg_req->stm32_sgl_req); -+ remain = len % mchan->sram_period; -+ -+ if (len > mchan->sram_period && ((len % mchan->sram_period) != 0)) { -+ unsigned long dma_sync_wait_timeout = jiffies + msecs_to_jiffies(5000); -+ -+ while (residue > 0 && residue > (mchan->sram_period - remain)) { -+ if (time_after_eq(jiffies, dma_sync_wait_timeout)) { -+ dev_err(chan2dev(chan), -+ "%s timeout pending last %d bytes\n", __func__, residue); -+ return -EBUSY; -+ } -+ cpu_relax(); -+ residue = stm32_dma_get_remaining_bytes(chan); -+ } -+ stm32_dma_disable_chan(chan); -+ -+ src_buf = mchan->sram_buf + ((len / mchan->sram_period) & 0x1) * mchan->sram_period; -+ dst_buf = sg_dma_address(&sg_req->stm32_sgl_req) + len - (len % mchan->sram_period); -+ -+ desc = ddev->device_prep_dma_memcpy(mchan->chan, dst_buf, src_buf, -+ len % mchan->sram_period, DMA_PREP_INTERRUPT); -+ -+ if (!desc) -+ return -EINVAL; -+ -+ ret = dma_submit_error(dmaengine_submit(desc)); -+ if (ret < 0) -+ return ret; -+ -+ status = dma_wait_for_async_tx(desc); -+ if (status != DMA_COMPLETE) { -+ dmaengine_terminate_async(mchan->chan); -+ return -EBUSY; -+ } -+ } -+ -+ return 0; -+} -+ -+static void stm32_dma_start_transfer(struct stm32_dma_chan *chan); -+ -+static void stm32_mdma_chan_complete_worker(struct work_struct *work) -+{ -+ struct stm32_dma_chan *chan = container_of(work, struct stm32_dma_chan, mdma_work); -+ unsigned long flags; -+ int ret; -+ -+ chan->busy = false; -+ chan->status = DMA_COMPLETE; -+ ret = stm32_dma_mdma_flush_remaining(chan); -+ if (ret) { -+ dev_err(chan2dev(chan), "Can't flush DMA: %d\n", ret); -+ return; -+ } -+ -+ spin_lock_irqsave_nested(&chan->vchan.lock, flags, SINGLE_DEPTH_NESTING); -+ -+ if (chan->next_sg == chan->desc->num_sgs) { -+ vchan_cookie_complete(&chan->desc->vdesc); -+ chan->desc = NULL; -+ } -+ -+ stm32_dma_start_transfer(chan); -+ -+ spin_unlock_irqrestore(&chan->vchan.lock, flags); -+} -+ -+static void stm32_mdma_chan_complete(void *param, const struct dmaengine_result *result) -+{ -+ struct stm32_dma_chan *chan = param; -+ -+ if (result->result == DMA_TRANS_NOERROR) { -+ if (!queue_work(chan->mdma_wq, &chan->mdma_work)) { -+ chan->busy = false; -+ chan->status = DMA_COMPLETE; -+ dev_warn(chan2dev(chan), "Work already queued\n"); -+ } -+ } else { -+ chan->busy = false; -+ chan->status = DMA_COMPLETE; -+ dev_err(chan2dev(chan), "MDMA transfer error: %d\n", result->result); -+ } -+} -+ -+static int stm32_dma_mdma_start(struct stm32_dma_chan *chan, struct stm32_dma_sg_req *sg_req) -+{ -+ struct stm32_dma_mdma *mchan = &chan->mchan; -+ struct stm32_dma_mdma_desc *m_desc = &sg_req->m_desc; -+ int ret; -+ -+ ret = dma_submit_error(dmaengine_submit(m_desc->desc)); -+ if (ret < 0) { -+ dev_err(chan2dev(chan), "MDMA submit failed\n"); -+ goto error; -+ } -+ -+ dma_async_issue_pending(mchan->chan); -+ -+ /* -+ * In case of M2D transfer, we have to generate dummy DMA transfer to -+ * copy 1st sg data into SRAM -+ */ -+ if (mchan->dir == DMA_MEM_TO_DEV) { -+ ret = stm32_dma_dummy_memcpy_xfer(chan); -+ if (ret < 0) { -+ dmaengine_terminate_async(mchan->chan); -+ goto error; -+ } -+ } -+ -+ return 0; -+error: -+ return ret; -+} -+ -+static void stm32_dma_sg_inc(struct stm32_dma_chan *chan) -+{ -+ chan->next_sg++; -+ if (chan->desc->cyclic && (chan->next_sg == chan->desc->num_sgs)) -+ chan->next_sg = 0; -+} -+ - static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan); - - static void stm32_dma_start_transfer(struct stm32_dma_chan *chan) -@@ -558,6 +925,8 @@ static void stm32_dma_start_transfer(struct stm32_dma_chan *chan) - - chan->desc = to_stm32_dma_desc(vdesc); - chan->next_sg = 0; -+ } else { -+ vdesc = &chan->desc->vdesc; - } - - if (chan->next_sg == chan->desc->num_sgs) -@@ -566,6 +935,53 @@ static void stm32_dma_start_transfer(struct stm32_dma_chan *chan) - sg_req = &chan->desc->sg_req[chan->next_sg]; - reg = &sg_req->chan_reg; - -+ /* Clear interrupt status if it is there */ -+ status = stm32_dma_irq_status(chan); -+ if (status) -+ stm32_dma_irq_clear(chan, status); -+ -+ if (chan->use_mdma) { -+ if (chan->next_sg == 0) { -+ struct stm32_dma_mdma_desc *m_desc; -+ -+ m_desc = &sg_req->m_desc; -+ if (chan->desc->cyclic) { -+ /* If one callback is set, it will be called by MDMA driver. */ -+ if (vdesc->tx.callback) { -+ m_desc->desc->callback = vdesc->tx.callback; -+ m_desc->desc->callback_param = vdesc->tx.callback_param; -+ vdesc->tx.callback = NULL; -+ vdesc->tx.callback_param = NULL; -+ } -+ } -+ } -+ -+ if (chan->mchan.dir == DMA_MEM_TO_DEV) { -+ ret = stm32_dma_dummy_memcpy_xfer(chan); -+ if (ret < 0) { -+ dmaengine_terminate_async(chan->mchan.chan); -+ chan->desc = NULL; -+ return; -+ } -+ } else { -+ reg->dma_scr &= ~STM32_DMA_SCR_TCIE; -+ } -+ -+ if (!chan->desc->cyclic) { -+ /* MDMA already started */ -+ if (chan->mchan.dir != DMA_MEM_TO_DEV && -+ sg_dma_len(&sg_req->stm32_sgl_req) > chan->mchan.sram_period) -+ reg->dma_scr |= STM32_DMA_SCR_DBM; -+ ret = stm32_dma_mdma_start(chan, sg_req); -+ if (ret < 0) { -+ chan->desc = NULL; -+ return; -+ } -+ } -+ } -+ -+ stm32_dma_sg_inc(chan); -+ - reg->dma_scr &= ~STM32_DMA_SCR_EN; - stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg->dma_scr); - stm32_dma_write(dmadev, STM32_DMA_SPAR(chan->id), reg->dma_spar); -@@ -574,24 +990,17 @@ static void stm32_dma_start_transfer(struct stm32_dma_chan *chan) - stm32_dma_write(dmadev, STM32_DMA_SM1AR(chan->id), reg->dma_sm1ar); - stm32_dma_write(dmadev, STM32_DMA_SNDTR(chan->id), reg->dma_sndtr); - -- chan->next_sg++; -- -- /* Clear interrupt status if it is there */ -- status = stm32_dma_irq_status(chan); -- if (status) -- stm32_dma_irq_clear(chan, status); -- - if (chan->desc->cyclic) - stm32_dma_configure_next_sg(chan); - - stm32_dma_dump_reg(chan); - - /* Start DMA */ -+ chan->busy = true; -+ chan->status = DMA_IN_PROGRESS; - reg->dma_scr |= STM32_DMA_SCR_EN; - stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg->dma_scr); - -- chan->busy = true; -- - dev_dbg(chan2dev(chan), "vchan %pK: started\n", &chan->vchan); - } - -@@ -604,41 +1013,137 @@ static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan) - id = chan->id; - dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); - -- if (dma_scr & STM32_DMA_SCR_DBM) { -- if (chan->next_sg == chan->desc->num_sgs) -- chan->next_sg = 0; -+ sg_req = &chan->desc->sg_req[chan->next_sg]; - -- sg_req = &chan->desc->sg_req[chan->next_sg]; -+ if (dma_scr & STM32_DMA_SCR_CT) { -+ dma_sm0ar = sg_req->chan_reg.dma_sm0ar; -+ stm32_dma_write(dmadev, STM32_DMA_SM0AR(id), dma_sm0ar); -+ dev_dbg(chan2dev(chan), "CT=1 <=> SM0AR: 0x%08x\n", -+ stm32_dma_read(dmadev, STM32_DMA_SM0AR(id))); -+ } else { -+ dma_sm1ar = sg_req->chan_reg.dma_sm1ar; -+ stm32_dma_write(dmadev, STM32_DMA_SM1AR(id), dma_sm1ar); -+ dev_dbg(chan2dev(chan), "CT=0 <=> SM1AR: 0x%08x\n", -+ stm32_dma_read(dmadev, STM32_DMA_SM1AR(id))); -+ } -+} - -- if (dma_scr & STM32_DMA_SCR_CT) { -- dma_sm0ar = sg_req->chan_reg.dma_sm0ar; -- stm32_dma_write(dmadev, STM32_DMA_SM0AR(id), dma_sm0ar); -- dev_dbg(chan2dev(chan), "CT=1 <=> SM0AR: 0x%08x\n", -- stm32_dma_read(dmadev, STM32_DMA_SM0AR(id))); -- } else { -- dma_sm1ar = sg_req->chan_reg.dma_sm1ar; -- stm32_dma_write(dmadev, STM32_DMA_SM1AR(id), dma_sm1ar); -- dev_dbg(chan2dev(chan), "CT=0 <=> SM1AR: 0x%08x\n", -- stm32_dma_read(dmadev, STM32_DMA_SM1AR(id))); -- } -+static void stm32_dma_handle_chan_paused(struct stm32_dma_chan *chan) -+{ -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ u32 dma_scr; -+ -+ /* -+ * Read and store current remaining data items and peripheral/memory addresses to be -+ * updated on resume -+ */ -+ dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); -+ /* -+ * Transfer can be paused while between a previous resume and reconfiguration on transfer -+ * complete. If transfer is cyclic and CIRC and DBM have been deactivated for resume, need -+ * to set it here in SCR backup to ensure a good reconfiguration on transfer complete. -+ */ -+ if (chan->desc && chan->desc->cyclic) { -+ if (chan->desc->num_sgs == 1) -+ dma_scr |= STM32_DMA_SCR_CIRC; -+ else -+ dma_scr |= STM32_DMA_SCR_DBM; -+ } -+ chan->chan_reg.dma_scr = dma_scr; -+ -+ /* -+ * Need to temporarily deactivate CIRC/DBM until next Transfer Complete interrupt, otherwise -+ * on resume NDTR autoreload value will be wrong (lower than the initial period length) -+ */ -+ if (chan->desc && chan->desc->cyclic) { -+ dma_scr &= ~(STM32_DMA_SCR_DBM | STM32_DMA_SCR_CIRC); -+ stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), dma_scr); - } -+ -+ chan->chan_reg.dma_sndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); -+ -+ chan->status = DMA_PAUSED; -+ -+ dev_dbg(chan2dev(chan), "vchan %pK: paused\n", &chan->vchan); - } - --static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan) -+static void stm32_dma_post_resume_reconfigure(struct stm32_dma_chan *chan) - { -- if (chan->desc) { -- if (chan->desc->cyclic) { -- vchan_cyclic_callback(&chan->desc->vdesc); -- chan->next_sg++; -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ struct stm32_dma_sg_req *sg_req; -+ u32 dma_scr, status, id; -+ -+ id = chan->id; -+ dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); -+ -+ /* Clear interrupt status if it is there */ -+ status = stm32_dma_irq_status(chan); -+ if (status) -+ stm32_dma_irq_clear(chan, status); -+ -+ if (!chan->next_sg) -+ sg_req = &chan->desc->sg_req[chan->desc->num_sgs - 1]; -+ else -+ sg_req = &chan->desc->sg_req[chan->next_sg - 1]; -+ -+ /* Reconfigure NDTR with the initial value */ -+ stm32_dma_write(dmadev, STM32_DMA_SNDTR(chan->id), sg_req->chan_reg.dma_sndtr); -+ -+ /* Restore SPAR */ -+ stm32_dma_write(dmadev, STM32_DMA_SPAR(id), sg_req->chan_reg.dma_spar); -+ -+ /* Restore SM0AR/SM1AR whatever DBM/CT as they may have been modified */ -+ stm32_dma_write(dmadev, STM32_DMA_SM0AR(id), sg_req->chan_reg.dma_sm0ar); -+ stm32_dma_write(dmadev, STM32_DMA_SM1AR(id), sg_req->chan_reg.dma_sm1ar); -+ -+ /* Reactivate CIRC/DBM if needed */ -+ if (chan->chan_reg.dma_scr & STM32_DMA_SCR_DBM) { -+ dma_scr |= STM32_DMA_SCR_DBM; -+ /* Restore CT */ -+ if (chan->chan_reg.dma_scr & STM32_DMA_SCR_CT) -+ dma_scr &= ~STM32_DMA_SCR_CT; -+ else -+ dma_scr |= STM32_DMA_SCR_CT; -+ } else if (chan->chan_reg.dma_scr & STM32_DMA_SCR_CIRC) { -+ dma_scr |= STM32_DMA_SCR_CIRC; -+ } -+ stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), dma_scr); -+ -+ stm32_dma_configure_next_sg(chan); -+ -+ stm32_dma_dump_reg(chan); -+ -+ dma_scr |= STM32_DMA_SCR_EN; -+ stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), dma_scr); -+ -+ dev_dbg(chan2dev(chan), "vchan %pK: reconfigured after pause/resume\n", &chan->vchan); -+} -+ -+static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan, u32 scr) -+{ -+ if (!chan->desc) -+ return; -+ -+ if (chan->desc->cyclic) { -+ vchan_cyclic_callback(&chan->desc->vdesc); -+ if (chan->use_mdma) -+ return; -+ stm32_dma_sg_inc(chan); -+ /* cyclic while CIRC/DBM disable => post resume reconfiguration needed */ -+ if (!(scr & (STM32_DMA_SCR_CIRC | STM32_DMA_SCR_DBM))) -+ stm32_dma_post_resume_reconfigure(chan); -+ else if (scr & STM32_DMA_SCR_DBM) - stm32_dma_configure_next_sg(chan); -- } else { -- chan->busy = false; -- if (chan->next_sg == chan->desc->num_sgs) { -- vchan_cookie_complete(&chan->desc->vdesc); -- chan->desc = NULL; -- } -- stm32_dma_start_transfer(chan); -+ } else { -+ if (chan->use_mdma && chan->mchan.dir != DMA_MEM_TO_DEV) -+ return; /* wait for callback */ -+ chan->busy = false; -+ chan->status = DMA_COMPLETE; -+ if (chan->next_sg == chan->desc->num_sgs) { -+ vchan_cookie_complete(&chan->desc->vdesc); -+ chan->desc = NULL; - } -+ stm32_dma_start_transfer(chan); - } - } - -@@ -674,8 +1179,10 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid) - - if (status & STM32_DMA_TCI) { - stm32_dma_irq_clear(chan, STM32_DMA_TCI); -- if (scr & STM32_DMA_SCR_TCIE) -- stm32_dma_handle_chan_done(chan); -+ if (scr & STM32_DMA_SCR_TCIE) { -+ if (chan->status != DMA_PAUSED) -+ stm32_dma_handle_chan_done(chan, scr); -+ } - status &= ~STM32_DMA_TCI; - } - -@@ -701,19 +1208,122 @@ static void stm32_dma_issue_pending(struct dma_chan *c) - struct stm32_dma_chan *chan = to_stm32_dma_chan(c); - unsigned long flags; - -- spin_lock_irqsave(&chan->vchan.lock, flags); -+ if (chan->use_mdma) -+ spin_lock_irqsave_nested(&chan->vchan.lock, flags, SINGLE_DEPTH_NESTING); -+ else -+ spin_lock_irqsave(&chan->vchan.lock, flags); -+ - if (vchan_issue_pending(&chan->vchan) && !chan->desc && !chan->busy) { - dev_dbg(chan2dev(chan), "vchan %pK: issued\n", &chan->vchan); - stm32_dma_start_transfer(chan); -- - } -+ - spin_unlock_irqrestore(&chan->vchan.lock, flags); - } - -+static int stm32_dma_pause(struct dma_chan *c) -+{ -+ struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ unsigned long flags; -+ int ret; -+ -+ if (chan->status != DMA_IN_PROGRESS || chan->use_mdma) -+ return -EPERM; -+ -+ spin_lock_irqsave(&chan->vchan.lock, flags); -+ -+ ret = stm32_dma_disable_chan(chan); -+ if (!ret) -+ stm32_dma_handle_chan_paused(chan); -+ -+ spin_unlock_irqrestore(&chan->vchan.lock, flags); -+ -+ return ret; -+} -+ -+static int stm32_dma_resume(struct dma_chan *c) -+{ -+ struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ struct stm32_dma_chan_reg chan_reg = chan->chan_reg; -+ u32 id = chan->id, scr, ndtr, offset, spar, sm0ar, sm1ar; -+ struct stm32_dma_sg_req *sg_req; -+ unsigned long flags; -+ -+ if (chan->status != DMA_PAUSED || chan->use_mdma) -+ return -EPERM; -+ -+ scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); -+ if (WARN_ON(scr & STM32_DMA_SCR_EN)) -+ return -EPERM; -+ -+ spin_lock_irqsave(&chan->vchan.lock, flags); -+ -+ /* sg_reg[prev_sg] contains original ndtr, sm0ar and sm1ar before pausing the transfer */ -+ if (!chan->next_sg) -+ sg_req = &chan->desc->sg_req[chan->desc->num_sgs - 1]; -+ else -+ sg_req = &chan->desc->sg_req[chan->next_sg - 1]; -+ -+ ndtr = sg_req->chan_reg.dma_sndtr; -+ offset = (ndtr - chan_reg.dma_sndtr) << STM32_DMA_SCR_PSIZE_GET(chan_reg.dma_scr); -+ spar = sg_req->chan_reg.dma_spar; -+ sm0ar = sg_req->chan_reg.dma_sm0ar; -+ sm1ar = sg_req->chan_reg.dma_sm1ar; -+ -+ /* -+ * The peripheral and/or memory addresses have to be updated in order to adjust the -+ * address pointers. Need to check increment. -+ */ -+ if (chan_reg.dma_scr & STM32_DMA_SCR_PINC) -+ stm32_dma_write(dmadev, STM32_DMA_SPAR(id), spar + offset); -+ else -+ stm32_dma_write(dmadev, STM32_DMA_SPAR(id), spar); -+ -+ if (!(chan_reg.dma_scr & STM32_DMA_SCR_MINC)) -+ offset = 0; -+ -+ /* -+ * In case of DBM, the current target could be SM1AR. -+ * Need to temporarily deactivate CIRC/DBM to finish the current transfer, so -+ * SM0AR becomes the current target and must be updated with SM1AR + offset if CT=1. -+ */ -+ if ((chan_reg.dma_scr & STM32_DMA_SCR_DBM) && (chan_reg.dma_scr & STM32_DMA_SCR_CT)) -+ stm32_dma_write(dmadev, STM32_DMA_SM1AR(id), sm1ar + offset); -+ else -+ stm32_dma_write(dmadev, STM32_DMA_SM0AR(id), sm0ar + offset); -+ -+ /* NDTR must be restored otherwise internal HW counter won't be correctly reset */ -+ stm32_dma_write(dmadev, STM32_DMA_SNDTR(id), chan_reg.dma_sndtr); -+ -+ /* -+ * Need to temporarily deactivate CIRC/DBM until next Transfer Complete interrupt, -+ * otherwise NDTR autoreload value will be wrong (lower than the initial period length) -+ */ -+ if (chan_reg.dma_scr & (STM32_DMA_SCR_CIRC | STM32_DMA_SCR_DBM)) -+ chan_reg.dma_scr &= ~(STM32_DMA_SCR_CIRC | STM32_DMA_SCR_DBM); -+ -+ if (chan_reg.dma_scr & STM32_DMA_SCR_DBM) -+ stm32_dma_configure_next_sg(chan); -+ -+ stm32_dma_dump_reg(chan); -+ -+ /* The stream may then be re-enabled to restart transfer from the point it was stopped */ -+ chan->status = DMA_IN_PROGRESS; -+ chan_reg.dma_scr |= STM32_DMA_SCR_EN; -+ stm32_dma_write(dmadev, STM32_DMA_SCR(id), chan_reg.dma_scr); -+ -+ spin_unlock_irqrestore(&chan->vchan.lock, flags); -+ -+ dev_dbg(chan2dev(chan), "vchan %pK: resumed\n", &chan->vchan); -+ -+ return 0; -+} -+ - static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, - enum dma_transfer_direction direction, - enum dma_slave_buswidth *buswidth, -- u32 buf_len, dma_addr_t buf_addr) -+ u32 buf_len, u64 buf_addr) - { - enum dma_slave_buswidth src_addr_width, dst_addr_width; - int src_bus_width, dst_bus_width; -@@ -862,6 +1472,151 @@ static void stm32_dma_clear_reg(struct stm32_dma_chan_reg *regs) - memset(regs, 0, sizeof(struct stm32_dma_chan_reg)); - } - -+static int stm32_dma_mdma_prep_slave_sg(struct stm32_dma_chan *chan, -+ struct scatterlist *sgl, u32 sg_len, -+ struct stm32_dma_desc *desc, unsigned long flags) -+{ -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ struct stm32_dma_mdma *mchan = &chan->mchan; -+ struct scatterlist *sg, *m_sg; -+ dma_addr_t dma_buf; -+ u32 len, num_sgs, sram_period; -+ int i, j, ret; -+ -+ desc->dma_buf_cpu = gen_pool_dma_alloc(dmadev->sram_pool, chan->sram_size, &desc->dma_buf); -+ if (!desc->dma_buf_cpu) -+ return -ENOMEM; -+ desc->dma_buf_size = chan->sram_size; -+ -+ sram_period = chan->sram_size / 2; -+ -+ for_each_sg(sgl, sg, sg_len, i) { -+ struct stm32_dma_mdma_desc *m_desc = &desc->sg_req[i].m_desc; -+ struct dma_slave_config config; -+ -+ len = sg_dma_len(sg); -+ desc->sg_req[i].stm32_sgl_req = *sg; -+ num_sgs = 1; -+ -+ if (mchan->dir == DMA_MEM_TO_DEV) { -+ if (len > chan->sram_size) { -+ dev_err(chan2dev(chan), -+ "max buf size = %d bytes\n", chan->sram_size); -+ ret = -EINVAL; -+ goto free_alloc; -+ } -+ } else { -+ /* -+ * Build new sg for MDMA transfer -+ * Scatter DMA Req into several SDRAM transfer -+ */ -+ if (len > sram_period) -+ num_sgs = len / sram_period; -+ } -+ -+ ret = sg_alloc_table(&m_desc->sgt, num_sgs, GFP_ATOMIC); -+ if (ret) { -+ dev_err(chan2dev(chan), "MDMA sg table alloc failed\n"); -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ dma_buf = sg_dma_address(sg); -+ for_each_sg(m_desc->sgt.sgl, m_sg, num_sgs, j) { -+ size_t bytes = min_t(size_t, len, sram_period); -+ -+ sg_dma_address(m_sg) = dma_buf; -+ sg_dma_len(m_sg) = bytes; -+ dma_buf += bytes; -+ len -= bytes; -+ } -+ -+ /* Configure MDMA channel */ -+ memset(&config, 0, sizeof(config)); -+ if (mchan->dir == DMA_MEM_TO_DEV) -+ config.dst_addr = desc->dma_buf; -+ else -+ config.src_addr = desc->dma_buf; -+ -+ ret = dmaengine_slave_config(mchan->chan, &config); -+ if (ret < 0) -+ goto err; -+ -+ /* Prepare MDMA descriptor */ -+ m_desc->desc = dmaengine_prep_slave_sg(mchan->chan, -+ m_desc->sgt.sgl, m_desc->sgt.nents, -+ mchan->dir, DMA_PREP_INTERRUPT); -+ -+ if (!m_desc->desc) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (flags & DMA_CTRL_REUSE) -+ dmaengine_desc_set_reuse(m_desc->desc); -+ -+ if (mchan->dir != DMA_MEM_TO_DEV) { -+ m_desc->desc->callback_result = stm32_mdma_chan_complete; -+ m_desc->desc->callback_param = chan; -+ INIT_WORK(&chan->mdma_work, stm32_mdma_chan_complete_worker); -+ } -+ } -+ -+ chan->mchan.sram_buf = desc->dma_buf; -+ chan->mchan.sram_period = sram_period; -+ -+ return 0; -+ -+err: -+ for (j = 0; j < i; j++) { -+ struct stm32_dma_mdma_desc *m_desc = &desc->sg_req[j].m_desc; -+ -+ m_desc->desc = NULL; -+ sg_free_table(&desc->sg_req[j].m_desc.sgt); -+ } -+free_alloc: -+ gen_pool_free(dmadev->sram_pool, (unsigned long)desc->dma_buf_cpu, desc->dma_buf_size); -+ return ret; -+} -+ -+static int stm32_dma_setup_sg_requests(struct stm32_dma_chan *chan, -+ struct scatterlist *sgl, unsigned int sg_len, -+ enum dma_transfer_direction direction, -+ struct stm32_dma_desc *desc) -+{ -+ struct scatterlist *sg; -+ u32 nb_data_items; -+ int i, ret; -+ enum dma_slave_buswidth buswidth; -+ -+ for_each_sg(sgl, sg, sg_len, i) { -+ ret = stm32_dma_set_xfer_param(chan, direction, &buswidth, sg_dma_len(sg), -+ (u64)sg_dma_address(sg)); -+ if (ret < 0) -+ return ret; -+ -+ nb_data_items = sg_dma_len(sg) / buswidth; -+ if (nb_data_items > STM32_DMA_ALIGNED_MAX_DATA_ITEMS) { -+ dev_err(chan2dev(chan), "nb items not supported\n"); -+ return -EINVAL; -+ } -+ -+ stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); -+ desc->sg_req[i].chan_reg.dma_scr = chan->chan_reg.dma_scr; -+ desc->sg_req[i].chan_reg.dma_sfcr = chan->chan_reg.dma_sfcr; -+ desc->sg_req[i].chan_reg.dma_spar = chan->chan_reg.dma_spar; -+ desc->sg_req[i].chan_reg.dma_sm0ar = sg_dma_address(sg); -+ desc->sg_req[i].chan_reg.dma_sm1ar = sg_dma_address(sg); -+ if (chan->use_mdma) -+ desc->sg_req[i].chan_reg.dma_sm1ar += chan->mchan.sram_period; -+ desc->sg_req[i].chan_reg.dma_sndtr = nb_data_items; -+ } -+ -+ desc->num_sgs = sg_len; -+ -+ return 0; -+} -+ - static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( - struct dma_chan *c, struct scatterlist *sgl, - u32 sg_len, enum dma_transfer_direction direction, -@@ -869,9 +1624,6 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( - { - struct stm32_dma_chan *chan = to_stm32_dma_chan(c); - struct stm32_dma_desc *desc; -- struct scatterlist *sg; -- enum dma_slave_buswidth buswidth; -- u32 nb_data_items; - int i, ret; - - if (!chan->config_init) { -@@ -894,49 +1646,130 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( - else - chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_PFCTRL; - -- for_each_sg(sgl, sg, sg_len, i) { -- ret = stm32_dma_set_xfer_param(chan, direction, &buswidth, -- sg_dma_len(sg), -- sg_dma_address(sg)); -+ if (chan->use_mdma) { -+ struct sg_table new_sgt; -+ struct scatterlist *s, *_sgl; -+ -+ chan->mchan.dir = direction; -+ ret = stm32_dma_mdma_prep_slave_sg(chan, sgl, sg_len, desc, flags); - if (ret < 0) -- goto err; -+ return NULL; - -- desc->sg_req[i].len = sg_dma_len(sg); -+ ret = sg_alloc_table(&new_sgt, sg_len, GFP_ATOMIC); -+ if (ret) -+ dev_err(chan2dev(chan), "DMA sg table alloc failed\n"); - -- nb_data_items = desc->sg_req[i].len / buswidth; -- if (nb_data_items > STM32_DMA_ALIGNED_MAX_DATA_ITEMS) { -- dev_err(chan2dev(chan), "nb items not supported\n"); -- goto err; -+ for_each_sg(new_sgt.sgl, s, sg_len, i) { -+ _sgl = sgl; -+ sg_dma_len(s) = min(sg_dma_len(_sgl), chan->mchan.sram_period); -+ s->dma_address = chan->mchan.sram_buf; -+ _sgl = sg_next(_sgl); - } - -- stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); -- desc->sg_req[i].chan_reg.dma_scr = chan->chan_reg.dma_scr; -- desc->sg_req[i].chan_reg.dma_sfcr = chan->chan_reg.dma_sfcr; -- desc->sg_req[i].chan_reg.dma_spar = chan->chan_reg.dma_spar; -- desc->sg_req[i].chan_reg.dma_sm0ar = sg_dma_address(sg); -- desc->sg_req[i].chan_reg.dma_sm1ar = sg_dma_address(sg); -- desc->sg_req[i].chan_reg.dma_sndtr = nb_data_items; -+ ret = stm32_dma_setup_sg_requests(chan, new_sgt.sgl, sg_len, direction, desc); -+ sg_free_table(&new_sgt); -+ if (ret < 0) -+ goto err; -+ } else { -+ /* Prepare a normal DMA transfer */ -+ ret = stm32_dma_setup_sg_requests(chan, sgl, sg_len, direction, desc); -+ if (ret < 0) -+ goto err; - } - -- desc->num_sgs = sg_len; - desc->cyclic = false; - - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); -- - err: -+ if (chan->use_mdma) { -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ -+ for (i = 0; i < sg_len; i++) -+ sg_free_table(&desc->sg_req[i].m_desc.sgt); -+ -+ gen_pool_free(dmadev->sram_pool, (unsigned long)desc->dma_buf_cpu, -+ desc->dma_buf_size); -+ } - kfree(desc); - return NULL; - } - -+static int stm32_dma_mdma_prep_dma_cyclic(struct stm32_dma_chan *chan, -+ dma_addr_t buf_addr, size_t buf_len, -+ size_t period_len, struct stm32_dma_desc *desc) -+{ -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ struct stm32_dma_mdma *mchan = &chan->mchan; -+ struct stm32_dma_mdma_desc *m_desc = &desc->sg_req[0].m_desc; -+ struct dma_slave_config config; -+ int ret; -+ -+ chan->sram_size = ALIGN(period_len, STM32_DMA_SRAM_GRANULARITY); -+ desc->dma_buf_cpu = gen_pool_dma_alloc(dmadev->sram_pool, 2 * chan->sram_size, -+ &desc->dma_buf); -+ if (!desc->dma_buf_cpu) -+ return -ENOMEM; -+ desc->dma_buf_size = 2 * chan->sram_size; -+ -+ memset(&config, 0, sizeof(config)); -+ -+ /* Configure MDMA channel */ -+ if (chan->mchan.dir == DMA_MEM_TO_DEV) -+ config.dst_addr = desc->dma_buf; -+ else -+ config.src_addr = desc->dma_buf; -+ ret = dmaengine_slave_config(mchan->chan, &config); -+ if (ret < 0) -+ goto err; -+ -+ /* Prepare MDMA descriptor */ -+ m_desc->desc = dmaengine_prep_dma_cyclic(mchan->chan, buf_addr, buf_len, -+ period_len, chan->mchan.dir, -+ DMA_PREP_INTERRUPT); -+ -+ if (!m_desc->desc) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ ret = dma_submit_error(dmaengine_submit(m_desc->desc)); -+ if (ret < 0) { -+ dev_err(chan2dev(chan), "MDMA submit failed\n"); -+ goto err; -+ } -+ -+ dma_async_issue_pending(mchan->chan); -+ -+ /* -+ * In case of M2D transfer, we have to generate dummy DMA transfer to -+ * copy 1 period of data into SRAM -+ */ -+ if (chan->mchan.dir == DMA_MEM_TO_DEV) { -+ ret = stm32_dma_dummy_memcpy_xfer(chan); -+ if (ret < 0) { -+ dev_err(chan2dev(chan), "stm32_dma_dummy_memcpy_xfer failed\n"); -+ dmaengine_terminate_async(mchan->chan); -+ goto err; -+ } -+ } -+ -+ return 0; -+err: -+ gen_pool_free(dmadev->sram_pool, (unsigned long)desc->dma_buf_cpu, desc->dma_buf_size); -+ return ret; -+} -+ - static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( - struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len, - size_t period_len, enum dma_transfer_direction direction, - unsigned long flags) - { - struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ struct stm32_dma_chan_reg *chan_reg = &chan->chan_reg; - struct stm32_dma_desc *desc; - enum dma_slave_buswidth buswidth; - u32 num_periods, nb_data_items; -+ dma_addr_t dma_buf = 0; - int i, ret; - - if (!buf_len || !period_len) { -@@ -965,8 +1798,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( - return NULL; - } - -- ret = stm32_dma_set_xfer_param(chan, direction, &buswidth, period_len, -- buf_addr); -+ ret = stm32_dma_set_xfer_param(chan, direction, &buswidth, period_len, (u64)buf_addr); - if (ret < 0) - return NULL; - -@@ -977,36 +1809,57 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( - } - - /* Enable Circular mode or double buffer mode */ -- if (buf_len == period_len) -+ if (buf_len == period_len) { - chan->chan_reg.dma_scr |= STM32_DMA_SCR_CIRC; -- else -+ } else { - chan->chan_reg.dma_scr |= STM32_DMA_SCR_DBM; -+ chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_CT; -+ } - - /* Clear periph ctrl if client set it */ - chan->chan_reg.dma_scr &= ~STM32_DMA_SCR_PFCTRL; - -- num_periods = buf_len / period_len; -+ if (chan->use_mdma) -+ num_periods = 1; -+ else -+ num_periods = buf_len / period_len; - - desc = kzalloc(struct_size(desc, sg_req, num_periods), GFP_NOWAIT); - if (!desc) - return NULL; - -- for (i = 0; i < num_periods; i++) { -- desc->sg_req[i].len = period_len; -+ desc->num_sgs = num_periods; -+ desc->cyclic = true; -+ -+ if (chan->use_mdma) { -+ chan->mchan.dir = direction; - -+ ret = stm32_dma_mdma_prep_dma_cyclic(chan, buf_addr, buf_len, period_len, desc); -+ if (ret < 0) -+ return NULL; -+ dma_buf = desc->dma_buf; -+ } else { -+ dma_buf = buf_addr; -+ } -+ -+ for (i = 0; i < num_periods; i++) { -+ sg_dma_len(&desc->sg_req[i].stm32_sgl_req) = period_len; -+ sg_dma_address(&desc->sg_req[i].stm32_sgl_req) = dma_buf; - stm32_dma_clear_reg(&desc->sg_req[i].chan_reg); -- desc->sg_req[i].chan_reg.dma_scr = chan->chan_reg.dma_scr; -- desc->sg_req[i].chan_reg.dma_sfcr = chan->chan_reg.dma_sfcr; -- desc->sg_req[i].chan_reg.dma_spar = chan->chan_reg.dma_spar; -- desc->sg_req[i].chan_reg.dma_sm0ar = buf_addr; -- desc->sg_req[i].chan_reg.dma_sm1ar = buf_addr; -+ desc->sg_req[i].chan_reg.dma_scr = chan_reg->dma_scr; -+ desc->sg_req[i].chan_reg.dma_sfcr = chan_reg->dma_sfcr; -+ desc->sg_req[i].chan_reg.dma_spar = chan_reg->dma_spar; -+ if (chan->use_mdma) { -+ desc->sg_req[i].chan_reg.dma_sm0ar = desc->dma_buf; -+ desc->sg_req[i].chan_reg.dma_sm1ar = desc->dma_buf + chan->sram_size; -+ } else { -+ desc->sg_req[i].chan_reg.dma_sm0ar = dma_buf; -+ desc->sg_req[i].chan_reg.dma_sm1ar = dma_buf; -+ dma_buf += period_len; -+ } - desc->sg_req[i].chan_reg.dma_sndtr = nb_data_items; -- buf_addr += period_len; - } - -- desc->num_sgs = num_periods; -- desc->cyclic = true; -- - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); - } - -@@ -1047,13 +1900,13 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( - STM32_DMA_SCR_PINC | - STM32_DMA_SCR_TCIE | - STM32_DMA_SCR_TEIE; -- desc->sg_req[i].chan_reg.dma_sfcr |= STM32_DMA_SFCR_MASK; -+ desc->sg_req[i].chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_MASK; - desc->sg_req[i].chan_reg.dma_sfcr |= - STM32_DMA_SFCR_FTH(threshold); - desc->sg_req[i].chan_reg.dma_spar = src + offset; - desc->sg_req[i].chan_reg.dma_sm0ar = dest + offset; - desc->sg_req[i].chan_reg.dma_sndtr = xfer_count; -- desc->sg_req[i].len = xfer_count; -+ sg_dma_len(&desc->sg_req[i].stm32_sgl_req) = xfer_count; - } - - desc->num_sgs = num_sgs; -@@ -1062,18 +1915,6 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); - } - --static u32 stm32_dma_get_remaining_bytes(struct stm32_dma_chan *chan) --{ -- u32 dma_scr, width, ndtr; -- struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -- -- dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(chan->id)); -- width = STM32_DMA_SCR_PSIZE_GET(dma_scr); -- ndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); -- -- return ndtr << width; --} -- - /** - * stm32_dma_is_current_sg - check that expected sg_req is currently transferred - * @chan: dma channel -@@ -1090,24 +1931,36 @@ static bool stm32_dma_is_current_sg(struct stm32_dma_chan *chan) - { - struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); - struct stm32_dma_sg_req *sg_req; -- u32 dma_scr, dma_smar, id; -+ u32 dma_scr, dma_smar, id, period_len; - - id = chan->id; - dma_scr = stm32_dma_read(dmadev, STM32_DMA_SCR(id)); - -+ /* In cyclic CIRC but not DBM, CT is not used */ - if (!(dma_scr & STM32_DMA_SCR_DBM)) - return true; - - sg_req = &chan->desc->sg_req[chan->next_sg]; -+ period_len = sg_dma_len(&sg_req->stm32_sgl_req); - -+ /* DBM - take care of a previous pause/resume not yet post reconfigured */ - if (dma_scr & STM32_DMA_SCR_CT) { - dma_smar = stm32_dma_read(dmadev, STM32_DMA_SM0AR(id)); -- return (dma_smar == sg_req->chan_reg.dma_sm0ar); -+ /* -+ * If transfer has been pause/resumed, -+ * SM0AR is in the range of [SM0AR:SM0AR+period_len] -+ */ -+ return (dma_smar >= sg_req->chan_reg.dma_sm0ar && -+ dma_smar < sg_req->chan_reg.dma_sm0ar + period_len); - } - - dma_smar = stm32_dma_read(dmadev, STM32_DMA_SM1AR(id)); -- -- return (dma_smar == sg_req->chan_reg.dma_sm1ar); -+ /* -+ * If transfer has been pause/resumed, -+ * SM1AR is in the range of [SM1AR:SM1AR+period_len] -+ */ -+ return (dma_smar >= sg_req->chan_reg.dma_sm1ar && -+ dma_smar < sg_req->chan_reg.dma_sm1ar + period_len); - } - - static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, -@@ -1120,6 +1973,10 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, - struct stm32_dma_sg_req *sg_req = &chan->desc->sg_req[chan->next_sg]; - int i; - -+ /* Drain case */ -+ if (chan->residue_after_drain) -+ return chan->residue_after_drain; -+ - /* - * Calculate the residue means compute the descriptors - * information: -@@ -1147,11 +2004,11 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, - - residue = stm32_dma_get_remaining_bytes(chan); - -- if (!stm32_dma_is_current_sg(chan)) { -+ if (chan->desc->cyclic && !stm32_dma_is_current_sg(chan)) { - n_sg++; - if (n_sg == chan->desc->num_sgs) - n_sg = 0; -- residue = sg_req->len; -+ residue = sg_dma_len(&sg_req->stm32_sgl_req); - } - - /* -@@ -1163,7 +2020,7 @@ static size_t stm32_dma_desc_residue(struct stm32_dma_chan *chan, - */ - if (!chan->desc->cyclic || n_sg != 0) - for (i = n_sg; i < desc->num_sgs; i++) -- residue += desc->sg_req[i].len; -+ residue += sg_dma_len(&desc->sg_req[i].stm32_sgl_req); - - if (!chan->mem_burst) - return residue; -@@ -1181,13 +2038,29 @@ static enum dma_status stm32_dma_tx_status(struct dma_chan *c, - struct dma_tx_state *state) - { - struct stm32_dma_chan *chan = to_stm32_dma_chan(c); -+ struct stm32_dma_mdma *mchan = &chan->mchan; - struct virt_dma_desc *vdesc; - enum dma_status status; - unsigned long flags; - u32 residue = 0; - -+ /* -+ * When DMA/MDMA chain is used, we return the status of MDMA in cyclic -+ * mode and for D2M transfer in sg mode in order to return the correct -+ * residue if any -+ */ -+ if (chan->desc && chan->use_mdma && -+ (mchan->dir != DMA_MEM_TO_DEV || chan->desc->cyclic) && -+ !chan->residue_after_drain) -+ return dmaengine_tx_status(mchan->chan, mchan->chan->cookie, state); -+ - status = dma_cookie_status(c, cookie, state); -- if (status == DMA_COMPLETE || !state) -+ if (status == DMA_COMPLETE) -+ return status; -+ -+ status = chan->status; -+ -+ if (!state) - return status; - - spin_lock_irqsave(&chan->vchan.lock, flags); -@@ -1244,29 +2117,50 @@ static void stm32_dma_free_chan_resources(struct dma_chan *c) - vchan_free_chan_resources(to_virt_chan(c)); - stm32_dma_clear_reg(&chan->chan_reg); - chan->threshold = 0; -+ chan->use_mdma = false; -+ chan->sram_size = 0; - } - - static void stm32_dma_desc_free(struct virt_dma_desc *vdesc) - { -- kfree(container_of(vdesc, struct stm32_dma_desc, vdesc)); -+ struct stm32_dma_desc *desc = to_stm32_dma_desc(vdesc); -+ struct stm32_dma_chan *chan = to_stm32_dma_chan(vdesc->tx.chan); -+ struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); -+ int i; -+ -+ if (chan->use_mdma) { -+ struct stm32_dma_mdma_desc *m_desc; -+ -+ for (i = 0; i < desc->num_sgs; i++) { -+ m_desc = &desc->sg_req[i].m_desc; -+ if (dmaengine_desc_test_reuse(&vdesc->tx)) -+ dmaengine_desc_free(m_desc->desc); -+ m_desc->desc = NULL; -+ sg_free_table(&m_desc->sgt); -+ } -+ -+ gen_pool_free(dmadev->sram_pool, (unsigned long)desc->dma_buf_cpu, -+ desc->dma_buf_size); -+ } -+ -+ kfree(desc); - } - - static void stm32_dma_set_config(struct stm32_dma_chan *chan, - struct stm32_dma_cfg *cfg) - { - stm32_dma_clear_reg(&chan->chan_reg); -- - chan->chan_reg.dma_scr = cfg->stream_config & STM32_DMA_SCR_CFG_MASK; - chan->chan_reg.dma_scr |= STM32_DMA_SCR_REQ(cfg->request_line); -- -- /* Enable Interrupts */ - chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE; -- - chan->threshold = STM32_DMA_THRESHOLD_FTR_GET(cfg->features); - if (STM32_DMA_DIRECT_MODE_GET(cfg->features)) - chan->threshold = STM32_DMA_FIFO_THRESHOLD_NONE; - if (STM32_DMA_ALT_ACK_MODE_GET(cfg->features)) - chan->chan_reg.dma_scr |= STM32_DMA_SCR_TRBUFF; -+ chan->use_mdma = STM32_DMA_MDMA_CHAIN_FTR_GET(cfg->features); -+ chan->sram_size = (1 << STM32_DMA_MDMA_SRAM_SIZE_GET(cfg->features)) * -+ STM32_DMA_SRAM_GRANULARITY; - } - - static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec, -@@ -1304,6 +2198,9 @@ static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec, - - stm32_dma_set_config(chan, &cfg); - -+ if (!dmadev->sram_pool || !chan->mchan.chan) -+ chan->use_mdma = 0; -+ - return c; - } - -@@ -1316,11 +2213,13 @@ MODULE_DEVICE_TABLE(of, stm32_dma_of_match); - static int stm32_dma_probe(struct platform_device *pdev) - { - struct stm32_dma_chan *chan; -+ struct stm32_dma_mdma *mchan; - struct stm32_dma_device *dmadev; - struct dma_device *dd; - const struct of_device_id *match; - struct resource *res; - struct reset_control *rst; -+ char name[4]; - int i, ret; - - match = of_match_device(stm32_dma_of_match, &pdev->dev); -@@ -1364,6 +2263,13 @@ static int stm32_dma_probe(struct platform_device *pdev) - reset_control_deassert(rst); - } - -+ dmadev->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0); -+ if (!dmadev->sram_pool) -+ dev_info(&pdev->dev, "no dma pool: can't use MDMA: %d\n", ret); -+ else -+ dev_dbg(&pdev->dev, -+ "SRAM pool: %zu KiB\n", gen_pool_size(dmadev->sram_pool) / 1024); -+ - dma_set_max_seg_size(&pdev->dev, STM32_DMA_ALIGNED_MAX_DATA_ITEMS); - - dma_cap_set(DMA_SLAVE, dd->cap_mask); -@@ -1375,7 +2281,10 @@ static int stm32_dma_probe(struct platform_device *pdev) - dd->device_issue_pending = stm32_dma_issue_pending; - dd->device_prep_slave_sg = stm32_dma_prep_slave_sg; - dd->device_prep_dma_cyclic = stm32_dma_prep_dma_cyclic; -+ dd->device_caps = stm32_dma_slave_caps; - dd->device_config = stm32_dma_slave_config; -+ dd->device_pause = stm32_dma_pause; -+ dd->device_resume = stm32_dma_resume; - dd->device_terminate_all = stm32_dma_terminate_all; - dd->device_synchronize = stm32_dma_synchronize; - dd->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | -@@ -1403,11 +2312,39 @@ static int stm32_dma_probe(struct platform_device *pdev) - chan->id = i; - chan->vchan.desc_free = stm32_dma_desc_free; - vchan_init(&chan->vchan, dd); -+ -+ mchan = &chan->mchan; -+ if (dmadev->sram_pool) { -+ snprintf(name, sizeof(name), "ch%d", chan->id); -+ mchan->chan = dma_request_chan(dd->dev, name); -+ if (IS_ERR(mchan->chan)) { -+ ret = PTR_ERR(mchan->chan); -+ mchan->chan = NULL; -+ if (ret == -EPROBE_DEFER) -+ goto err_dma; -+ -+ dev_info(&pdev->dev, "can't request MDMA chan for %s\n", name); -+ } else { -+ /* -+ * Allocate workqueue per channel in case of MDMA/DMA chaining, to -+ * avoid deadlock with MDMA callback stm32_mdma_chan_complete() when -+ * MDMA interrupt handler is executed in a thread (which is the -+ * case in Linux-RT kernel or if force_irqthreads is set). -+ */ -+ chan->mdma_wq = alloc_ordered_workqueue("dma_work-%s", 0, name); -+ if (!chan->mdma_wq) { -+ dma_release_channel(mchan->chan); -+ mchan->chan = NULL; -+ dev_warn(&pdev->dev, -+ "can't alloc MDMA workqueue for %s\n", name); -+ } -+ } -+ } - } - - ret = dma_async_device_register(dd); - if (ret) -- goto clk_free; -+ goto err_dma; - - for (i = 0; i < STM32_DMA_MAX_CHANNELS; i++) { - chan = &dmadev->chan[i]; -@@ -1448,6 +2385,10 @@ static int stm32_dma_probe(struct platform_device *pdev) - - err_unregister: - dma_async_device_unregister(dd); -+err_dma: -+ for (i = 0; i < STM32_DMA_MAX_CHANNELS; i++) -+ if (dmadev->chan[i].mchan.chan) -+ dma_release_channel(dmadev->chan[i].mchan.chan); - clk_free: - clk_disable_unprepare(dmadev->clk); - -@@ -1480,7 +2421,7 @@ static int stm32_dma_runtime_resume(struct device *dev) - #endif - - #ifdef CONFIG_PM_SLEEP --static int stm32_dma_suspend(struct device *dev) -+static int stm32_dma_pm_suspend(struct device *dev) - { - struct stm32_dma_device *dmadev = dev_get_drvdata(dev); - int id, ret, scr; -@@ -1504,14 +2445,14 @@ static int stm32_dma_suspend(struct device *dev) - return 0; - } - --static int stm32_dma_resume(struct device *dev) -+static int stm32_dma_pm_resume(struct device *dev) - { - return pm_runtime_force_resume(dev); - } - #endif - - static const struct dev_pm_ops stm32_dma_pm_ops = { -- SET_SYSTEM_SLEEP_PM_OPS(stm32_dma_suspend, stm32_dma_resume) -+ SET_SYSTEM_SLEEP_PM_OPS(stm32_dma_pm_suspend, stm32_dma_pm_resume) - SET_RUNTIME_PM_OPS(stm32_dma_runtime_suspend, - stm32_dma_runtime_resume, NULL) - }; -@@ -1529,4 +2470,4 @@ static int __init stm32_dma_init(void) - { - return platform_driver_register(&stm32_dma_driver); - } --subsys_initcall(stm32_dma_init); -+device_initcall(stm32_dma_init); -diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c -index d5d55732adba..eee0c5aa5fb5 100644 ---- a/drivers/dma/stm32-dmamux.c -+++ b/drivers/dma/stm32-dmamux.c -@@ -267,7 +267,7 @@ static int stm32_dmamux_probe(struct platform_device *pdev) - ret = PTR_ERR(rst); - if (ret == -EPROBE_DEFER) - goto err_clk; -- } else { -+ } else if (count > 1) { /* Don't reset if there is only one dma-master */ - reset_control_assert(rst); - udelay(2); - reset_control_deassert(rst); -diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c -index 21a7bdc88970..1335346635de 100644 ---- a/drivers/dma/stm32-mdma.c -+++ b/drivers/dma/stm32-mdma.c -@@ -78,6 +78,7 @@ - #define STM32_MDMA_CCR_WEX BIT(14) - #define STM32_MDMA_CCR_HEX BIT(13) - #define STM32_MDMA_CCR_BEX BIT(12) -+#define STM32_MDMA_CCR_SM BIT(8) - #define STM32_MDMA_CCR_PL_MASK GENMASK(7, 6) - #define STM32_MDMA_CCR_PL(n) STM32_MDMA_SET(n, \ - STM32_MDMA_CCR_PL_MASK) -@@ -200,6 +201,8 @@ - #define STM32_MDMA_MAX_BURST 128 - #define STM32_MDMA_VERY_HIGH_PRIORITY 0x3 - -+#define STM32_DMA_SRAM_GRANULARITY PAGE_SIZE -+ - enum stm32_mdma_trigger_mode { - STM32_MDMA_BUFFER, - STM32_MDMA_BLOCK, -@@ -226,6 +229,7 @@ struct stm32_mdma_chan_config { - u32 transfer_config; - u32 mask_addr; - u32 mask_data; -+ bool m2m_hw; - }; - - struct stm32_mdma_hwdesc { -@@ -251,6 +255,7 @@ struct stm32_mdma_desc { - u32 ccr; - bool cyclic; - u32 count; -+ enum dma_transfer_direction dir; - struct stm32_mdma_desc_node node[]; - }; - -@@ -275,6 +280,7 @@ struct stm32_mdma_device { - u32 nr_channels; - u32 nr_requests; - u32 nr_ahb_addr_masks; -+ u32 chan_reserved; - struct stm32_mdma_chan chan[STM32_MDMA_MAX_CHANNELS]; - u32 ahb_addr_masks[]; - }; -@@ -565,13 +571,24 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, - dst_addr = chan->dma_config.dst_addr; - - /* Set device data size */ -+ if (chan_config->m2m_hw) -+ dst_addr_width = stm32_mdma_get_max_width(dst_addr, buf_len, -+ STM32_MDMA_MAX_BUF_LEN); -+ - dst_bus_width = stm32_mdma_get_width(chan, dst_addr_width); - if (dst_bus_width < 0) - return dst_bus_width; - ctcr &= ~STM32_MDMA_CTCR_DSIZE_MASK; - ctcr |= STM32_MDMA_CTCR_DSIZE(dst_bus_width); -+ if (chan_config->m2m_hw) { -+ ctcr &= ~STM32_MDMA_CTCR_DINCOS_MASK; -+ ctcr |= STM32_MDMA_CTCR_DINCOS(dst_bus_width); -+ } - - /* Set device burst value */ -+ if (chan_config->m2m_hw) -+ dst_maxburst = STM32_MDMA_MAX_BUF_LEN / dst_addr_width; -+ - dst_best_burst = stm32_mdma_get_best_burst(buf_len, tlen, - dst_maxburst, - dst_addr_width); -@@ -614,13 +631,24 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, - src_addr = chan->dma_config.src_addr; - - /* Set device data size */ -+ if (chan_config->m2m_hw) -+ src_addr_width = stm32_mdma_get_max_width(src_addr, buf_len, -+ STM32_MDMA_MAX_BUF_LEN); -+ - src_bus_width = stm32_mdma_get_width(chan, src_addr_width); - if (src_bus_width < 0) - return src_bus_width; - ctcr &= ~STM32_MDMA_CTCR_SSIZE_MASK; - ctcr |= STM32_MDMA_CTCR_SSIZE(src_bus_width); -+ if (chan_config->m2m_hw) { -+ ctcr &= ~STM32_MDMA_CTCR_SINCOS_MASK; -+ ctcr |= STM32_MDMA_CTCR_SINCOS(src_bus_width); -+ } - - /* Set device burst value */ -+ if (chan_config->m2m_hw) -+ src_maxburst = STM32_MDMA_MAX_BUF_LEN / src_addr_width; -+ - src_best_burst = stm32_mdma_get_best_burst(buf_len, tlen, - src_maxburst, - src_addr_width); -@@ -728,6 +756,7 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan, - { - struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); - struct dma_slave_config *dma_config = &chan->dma_config; -+ struct stm32_mdma_chan_config *chan_config = &chan->chan_config; - struct scatterlist *sg; - dma_addr_t src_addr, dst_addr; - u32 ccr, ctcr, ctbr; -@@ -750,6 +779,8 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan, - } else { - src_addr = dma_config->src_addr; - dst_addr = sg_dma_address(sg); -+ if (chan_config->m2m_hw) -+ src_addr += ((i & 1) ? sg_dma_len(sg) : 0); - ret = stm32_mdma_set_xfer_param(chan, direction, &ccr, - &ctcr, &ctbr, dst_addr, - sg_dma_len(sg)); -@@ -768,8 +799,6 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan, - /* Enable interrupts */ - ccr &= ~STM32_MDMA_CCR_IRQ_MASK; - ccr |= STM32_MDMA_CCR_TEIE | STM32_MDMA_CCR_CTCIE; -- if (sg_len > 1) -- ccr |= STM32_MDMA_CCR_BTIE; - desc->ccr = ccr; - - return 0; -@@ -781,7 +810,9 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl, - unsigned long flags, void *context) - { - struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c); -+ struct stm32_mdma_chan_config *chan_config = &chan->chan_config; - struct stm32_mdma_desc *desc; -+ struct stm32_mdma_hwdesc *hwdesc; - int i, ret; - - /* -@@ -803,6 +834,20 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl, - if (ret < 0) - goto xfer_setup_err; - -+ /* -+ * In case of M2M HW transfer triggered by STM32 DMA, we do not have to -+ * clear the transfer complete flag by hardware in order to let the -+ * CPU rearm the DMA with the next sg element and update some data in -+ * dmaengine framework -+ */ -+ if (chan_config->m2m_hw && direction == DMA_MEM_TO_DEV) { -+ for (i = 0; i < sg_len; i++) { -+ hwdesc = desc->node[i].hwdesc; -+ hwdesc->cmar = 0; -+ hwdesc->cmdr = 0; -+ } -+ } -+ - desc->cyclic = false; - - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); -@@ -824,9 +869,10 @@ stm32_mdma_prep_dma_cyclic(struct dma_chan *c, dma_addr_t buf_addr, - struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c); - struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); - struct dma_slave_config *dma_config = &chan->dma_config; -+ struct stm32_mdma_chan_config *chan_config = &chan->chan_config; - struct stm32_mdma_desc *desc; - dma_addr_t src_addr, dst_addr; -- u32 ccr, ctcr, ctbr, count; -+ u32 ccr, ctcr, ctbr, count, offset; - int i, ret; - - /* -@@ -880,12 +926,29 @@ stm32_mdma_prep_dma_cyclic(struct dma_chan *c, dma_addr_t buf_addr, - desc->ccr = ccr; - - /* Configure hwdesc list */ -+ offset = ALIGN(period_len, STM32_DMA_SRAM_GRANULARITY); - for (i = 0; i < count; i++) { - if (direction == DMA_MEM_TO_DEV) { -+ /* -+ * When the DMA is configured in double buffer mode, -+ * the MDMA has to use 2 destination buffers to be -+ * compliant with this mode. -+ */ -+ if (chan_config->m2m_hw && count > 1 && i % 2) -+ dst_addr = dma_config->dst_addr + offset; -+ else -+ dst_addr = dma_config->dst_addr; - src_addr = buf_addr + i * period_len; -- dst_addr = dma_config->dst_addr; - } else { -- src_addr = dma_config->src_addr; -+ /* -+ * When the DMA is configured in double buffer mode, -+ * the MDMA has to use 2 destination buffers to be -+ * compliant with this mode. -+ */ -+ if (chan_config->m2m_hw && count > 1 && i % 2) -+ src_addr = dma_config->src_addr + offset; -+ else -+ src_addr = dma_config->src_addr; - dst_addr = buf_addr + i * period_len; - } - -@@ -895,6 +958,7 @@ stm32_mdma_prep_dma_cyclic(struct dma_chan *c, dma_addr_t buf_addr, - } - - desc->cyclic = true; -+ desc->dir = direction; - - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); - -@@ -1279,14 +1343,28 @@ static size_t stm32_mdma_desc_residue(struct stm32_mdma_chan *chan, - { - struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); - struct stm32_mdma_hwdesc *hwdesc = desc->node[0].hwdesc; -- u32 cbndtr, residue, modulo, burst_size; -+ u32 residue = 0; -+ u32 modulo, burst_size; -+ dma_addr_t next_clar; -+ u32 cbndtr; - int i; - -- residue = 0; -- for (i = curr_hwdesc + 1; i < desc->count; i++) { -+ /* -+ * Get the residue of pending descriptors -+ */ -+ /* Get the next hw descriptor to process from current transfer */ -+ next_clar = stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id)); -+ for (i = desc->count - 1; i >= 0; i--) { - hwdesc = desc->node[i].hwdesc; -+ -+ if (hwdesc->clar == next_clar) -+ break;/* Current transfer found, stop cumulating */ -+ -+ /* Cumulate residue of unprocessed hw descriptors */ - residue += STM32_MDMA_CBNDTR_BNDT(hwdesc->cbndtr); - } -+ -+ /* Read & cumulate the residue of the current transfer */ - cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); - residue += cbndtr & STM32_MDMA_CBNDTR_BNDT_MASK; - -@@ -1306,24 +1384,36 @@ static enum dma_status stm32_mdma_tx_status(struct dma_chan *c, - struct dma_tx_state *state) - { - struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c); -+ struct stm32_mdma_chan_config *chan_config = &chan->chan_config; - struct virt_dma_desc *vdesc; - enum dma_status status; - unsigned long flags; - u32 residue = 0; - - status = dma_cookie_status(c, cookie, state); -- if ((status == DMA_COMPLETE) || (!state)) -+ if (status == DMA_COMPLETE || !state) - return status; - - spin_lock_irqsave(&chan->vchan.lock, flags); - - vdesc = vchan_find_desc(&chan->vchan, cookie); -- if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) -- residue = stm32_mdma_desc_residue(chan, chan->desc, -- chan->curr_hwdesc); -- else if (vdesc) -+ if (chan->desc && cookie == chan->desc->vdesc.tx.cookie) { -+ /* -+ * In case of M2D transfer triggered by STM32 DMA, the MDMA has -+ * always one period in advance in cyclic mode. So, we have to -+ * add 1 period of data to return the good residue to the -+ * client -+ */ -+ if (chan_config->m2m_hw && -+ chan->desc->dir == DMA_MEM_TO_DEV && chan->curr_hwdesc > 1) -+ residue = stm32_mdma_desc_residue(chan, chan->desc, chan->curr_hwdesc - 1); -+ else -+ residue = stm32_mdma_desc_residue(chan, chan->desc, chan->curr_hwdesc); -+ } else if (vdesc) { - residue = stm32_mdma_desc_residue(chan, - to_stm32_mdma_desc(vdesc), 0); -+ } -+ - dma_set_residue(state, residue); - - spin_unlock_irqrestore(&chan->vchan.lock, flags); -@@ -1371,9 +1461,12 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) - - if (!(status & ien)) { - spin_unlock(&chan->vchan.lock); -- dev_warn(chan2dev(chan), -- "spurious it (status=0x%04x, ien=0x%04x)\n", -- status, ien); -+ if (chan->busy) -+ dev_warn(chan2dev(chan), -+ "spurious it (status=0x%04x, ien=0x%04x)\n", status, ien); -+ else -+ dev_dbg(chan2dev(chan), -+ "spurious it (status=0x%04x, ien=0x%04x)\n", status, ien); - return IRQ_NONE; - } - -@@ -1473,15 +1566,28 @@ static void stm32_mdma_free_chan_resources(struct dma_chan *c) - chan->desc_pool = NULL; - } - -+static bool stm32_mdma_filter_fn(struct dma_chan *c, void *fn_param) -+{ -+ struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c); -+ struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); -+ -+ /* Check if chan is marked Secure */ -+ if (dmadev->chan_reserved & BIT(chan->id)) -+ return false; -+ -+ return true; -+} -+ - static struct dma_chan *stm32_mdma_of_xlate(struct of_phandle_args *dma_spec, - struct of_dma *ofdma) - { - struct stm32_mdma_device *dmadev = ofdma->of_dma_data; -+ dma_cap_mask_t mask = dmadev->ddev.cap_mask; - struct stm32_mdma_chan *chan; - struct dma_chan *c; - struct stm32_mdma_chan_config config; - -- if (dma_spec->args_count < 5) { -+ if (dma_spec->args_count < 6) { - dev_err(mdma2dev(dmadev), "Bad number of args\n"); - return NULL; - } -@@ -1491,6 +1597,7 @@ static struct dma_chan *stm32_mdma_of_xlate(struct of_phandle_args *dma_spec, - config.transfer_config = dma_spec->args[2]; - config.mask_addr = dma_spec->args[3]; - config.mask_data = dma_spec->args[4]; -+ config.m2m_hw = dma_spec->args[5]; - - if (config.request >= dmadev->nr_requests) { - dev_err(mdma2dev(dmadev), "Bad request line\n"); -@@ -1502,7 +1609,7 @@ static struct dma_chan *stm32_mdma_of_xlate(struct of_phandle_args *dma_spec, - return NULL; - } - -- c = dma_get_any_slave_channel(&dmadev->ddev); -+ c = __dma_request_channel(&mask, stm32_mdma_filter_fn, &config, ofdma->of_node); - if (!c) { - dev_err(mdma2dev(dmadev), "No more channels available\n"); - return NULL; -@@ -1631,6 +1738,10 @@ static int stm32_mdma_probe(struct platform_device *pdev) - for (i = 0; i < dmadev->nr_channels; i++) { - chan = &dmadev->chan[i]; - chan->id = i; -+ -+ if (stm32_mdma_read(dmadev, STM32_MDMA_CCR(i)) & STM32_MDMA_CCR_SM) -+ dmadev->chan_reserved |= BIT(i); -+ - chan->vchan.desc_free = stm32_mdma_desc_free; - vchan_init(&chan->vchan, dd); - } --- -2.17.1 - diff --git a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0007-v5.15-stm32mp-r2-DRM.patch b/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0007-v5.15-stm32mp-r2-DRM.patch deleted file mode 100644 index 6d61c18a..00000000 --- a/recipes-kernel/linux/linux-stm32mp/5.15/5.15.67/0007-v5.15-stm32mp-r2-DRM.patch +++ /dev/null @@ -1,2950 +0,0 @@ -From 1f085af24db6752b0028d1aea4a451f772922b12 Mon Sep 17 00:00:00 2001 -From: Romuald JEANNE -Date: Thu, 3 Nov 2022 15:27:37 +0100 -Subject: [PATCH 07/22] v5.15-stm32mp-r2 DRM - -Signed-off-by: Romuald JEANNE ---- - drivers/gpu/drm/bridge/sii902x.c | 100 +- - drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 5 +- - drivers/gpu/drm/drm_atomic_uapi.c | 4 + - drivers/gpu/drm/drm_bridge.c | 10 +- - drivers/gpu/drm/drm_connector.c | 62 + - drivers/gpu/drm/panel/Kconfig | 9 + - drivers/gpu/drm/panel/Makefile | 1 + - .../gpu/drm/panel/panel-orisetech-otm8009a.c | 101 +- - drivers/gpu/drm/panel/panel-raydium-rm68200.c | 7 +- - drivers/gpu/drm/panel/panel-rocktech-hx8394.c | 397 ++++++ - drivers/gpu/drm/panel/panel-simple.c | 16 + - drivers/gpu/drm/stm/drv.c | 6 + - drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 118 +- - drivers/gpu/drm/stm/ltdc.c | 1118 ++++++++++++++--- - drivers/gpu/drm/stm/ltdc.h | 25 +- - drivers/video/backlight/gpio_backlight.c | 7 +- - drivers/video/fbdev/simplefb.c | 21 +- - include/drm/bridge/dw_mipi_dsi.h | 4 +- - include/drm/drm_connector.h | 14 + - 19 files changed, 1763 insertions(+), 262 deletions(-) - create mode 100644 drivers/gpu/drm/panel/panel-rocktech-hx8394.c - -diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c -index 89558e581530..69208ead5384 100644 ---- a/drivers/gpu/drm/bridge/sii902x.c -+++ b/drivers/gpu/drm/bridge/sii902x.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -162,6 +163,11 @@ - - #define SII902X_AUDIO_PORT_INDEX 3 - -+/* CEC device */ -+#define SII902X_CEC_I2C_ADDR 0x30 -+ -+#define SII902X_CEC_SETUP 0x8e -+ - struct sii902x { - struct i2c_client *i2c; - struct regmap *regmap; -@@ -170,6 +176,7 @@ struct sii902x { - struct gpio_desc *reset_gpio; - struct i2c_mux_core *i2cmux; - struct regulator_bulk_data supplies[2]; -+ struct edid *edid; - /* - * Mutex protects audio and video functions from interfering - * each other, by keeping their i2c command sequences atomic. -@@ -280,6 +287,8 @@ static int sii902x_get_modes(struct drm_connector *connector) - - mutex_lock(&sii902x->mutex); - -+ kfree(sii902x->edid); -+ sii902x->edid = NULL; - edid = drm_get_edid(connector, sii902x->i2cmux->adapter[0]); - drm_connector_update_edid_property(connector, edid); - if (edid) { -@@ -287,7 +296,7 @@ static int sii902x_get_modes(struct drm_connector *connector) - output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI; - - num = drm_add_edid_modes(connector, edid); -- kfree(edid); -+ sii902x->edid = edid; - } - - ret = drm_display_info_set_bus_formats(&connector->display_info, -@@ -337,6 +346,7 @@ static void sii902x_bridge_disable(struct drm_bridge *bridge) - static void sii902x_bridge_enable(struct drm_bridge *bridge) - { - struct sii902x *sii902x = bridge_to_sii902x(bridge); -+ u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI; - - mutex_lock(&sii902x->mutex); - -@@ -346,6 +356,14 @@ static void sii902x_bridge_enable(struct drm_bridge *bridge) - regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA, - SII902X_SYS_CTRL_PWR_DWN, 0); - -+ if (sii902x->edid) { -+ if (drm_detect_hdmi_monitor(sii902x->edid)) -+ output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI; -+ } -+ -+ regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA, -+ SII902X_SYS_CTRL_OUTPUT_MODE, output_mode); -+ - mutex_unlock(&sii902x->mutex); - } - -@@ -960,6 +978,13 @@ static int sii902x_init(struct sii902x *sii902x) - { - struct device *dev = &sii902x->i2c->dev; - unsigned int status = 0; -+ unsigned char data[2] = { SII902X_CEC_SETUP, 0}; -+ struct i2c_msg msg = { -+ .addr = SII902X_CEC_I2C_ADDR << 1, -+ .flags = 0, -+ .len = 2, -+ .buf = data, -+ }; - u8 chipid[4]; - int ret; - -@@ -982,13 +1007,22 @@ static int sii902x_init(struct sii902x *sii902x) - return -EINVAL; - } - -+ /* -+ * By default, CEC must be disabled to allow other CEC devives -+ * to bypass the bridge. -+ */ -+ ret = i2c_transfer(sii902x->i2c->adapter, &msg, 1); -+ if (ret < 0) -+ dev_warn(&sii902x->i2c->dev, "Failed to disable CEC device!\n"); -+ - /* Clear all pending interrupts */ - regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status); - regmap_write(sii902x->regmap, SII902X_INT_STATUS, status); - - if (sii902x->i2c->irq > 0) { -- regmap_write(sii902x->regmap, SII902X_INT_ENABLE, -- SII902X_HOTPLUG_EVENT); -+ regmap_update_bits(sii902x->regmap, SII902X_INT_ENABLE, -+ SII902X_HOTPLUG_EVENT, -+ SII902X_HOTPLUG_EVENT); - - ret = devm_request_threaded_irq(dev, sii902x->i2c->irq, NULL, - sii902x_interrupt, -@@ -1087,6 +1121,65 @@ static int sii902x_remove(struct i2c_client *client) - return 0; - } - -+static int sii902x_pm_suspend(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct sii902x *sii902x = i2c_get_clientdata(client); -+ -+ DRM_DEBUG_DRIVER("\n"); -+ -+ if (sii902x->reset_gpio) -+ gpiod_set_value(sii902x->reset_gpio, 1); -+ -+ regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies), -+ sii902x->supplies); -+ -+ return 0; -+} -+ -+static int sii902x_pm_resume(struct device *dev) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct sii902x *sii902x = i2c_get_clientdata(client); -+ unsigned char data[2] = { SII902X_CEC_SETUP, 0}; -+ struct i2c_msg msg = { -+ .addr = SII902X_CEC_I2C_ADDR << 1, -+ .flags = 0, -+ .len = 2, -+ .buf = data, -+ }; -+ int ret; -+ -+ DRM_DEBUG_DRIVER("\n"); -+ -+ ret = regulator_bulk_enable(ARRAY_SIZE(sii902x->supplies), -+ sii902x->supplies); -+ if (ret) { -+ DRM_ERROR("regulator_bulk_enable failed\n"); -+ return ret; -+ } -+ -+ if (sii902x->reset_gpio) -+ gpiod_set_value(sii902x->reset_gpio, 0); -+ -+ regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x00); -+ -+ ret = i2c_transfer(client->adapter, &msg, 1); -+ if (ret < 0) -+ DRM_ERROR("Failed to disable CEC device!\n"); -+ -+ if (client->irq > 0) -+ regmap_update_bits(sii902x->regmap, SII902X_INT_ENABLE, -+ SII902X_HOTPLUG_EVENT, -+ SII902X_HOTPLUG_EVENT); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops sii902x_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(sii902x_pm_suspend, sii902x_pm_resume) -+}; -+ - static const struct of_device_id sii902x_dt_ids[] = { - { .compatible = "sil,sii9022", }, - { } -@@ -1105,6 +1198,7 @@ static struct i2c_driver sii902x_driver = { - .driver = { - .name = "sii902x", - .of_match_table = sii902x_dt_ids, -+ .pm = &sii902x_pm_ops, - }, - .id_table = sii902x_i2c_ids, - }; -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -index 56c3fd08c6a0..2a58b0b7ace5 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -@@ -998,7 +998,10 @@ dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge, - enum drm_mode_status mode_status = MODE_OK; - - if (pdata->mode_valid) -- mode_status = pdata->mode_valid(pdata->priv_data, mode); -+ mode_status = pdata->mode_valid(pdata->priv_data, mode, -+ dsi->mode_flags, -+ dw_mipi_dsi_get_lanes(dsi), -+ dsi->format); - - return mode_status; - } -diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c -index f195c7013137..9301aa72e6cb 100644 ---- a/drivers/gpu/drm/drm_atomic_uapi.c -+++ b/drivers/gpu/drm/drm_atomic_uapi.c -@@ -773,6 +773,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, - state->content_type = val; - } else if (property == connector->scaling_mode_property) { - state->scaling_mode = val; -+ } else if (property == connector->dithering_property) { -+ state->dithering = val; - } else if (property == config->content_protection_property) { - if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { - DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); -@@ -862,6 +864,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, - *val = state->colorspace; - } else if (property == connector->scaling_mode_property) { - *val = state->scaling_mode; -+ } else if (property == connector->dithering_property) { -+ *val = state->dithering; - } else if (property == config->hdr_output_metadata_property) { - *val = state->hdr_output_metadata ? - state->hdr_output_metadata->base.id : 0; -diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c -index 7ee29f073857..798d2cff102f 100644 ---- a/drivers/gpu/drm/drm_bridge.c -+++ b/drivers/gpu/drm/drm_bridge.c -@@ -227,11 +227,13 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, - list_del(&bridge->chain_node); - - #ifdef CONFIG_OF -- DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n", -- bridge->of_node, encoder->name, ret); -+ if (ret != -EPROBE_DEFER) -+ DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n", -+ bridge->of_node, encoder->name, ret); - #else -- DRM_ERROR("failed to attach bridge to encoder %s: %d\n", -- encoder->name, ret); -+ if (ret != -EPROBE_DEFER) -+ DRM_ERROR("failed to attach bridge to encoder %s: %d\n", -+ encoder->name, ret); - #endif - - return ret; -diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c -index e9b7926d9b66..c035729fa995 100644 ---- a/drivers/gpu/drm/drm_connector.c -+++ b/drivers/gpu/drm/drm_connector.c -@@ -824,6 +824,12 @@ static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = { - { DRM_MODE_SCALE_ASPECT, "Full aspect" }, - }; - -+static const struct drm_prop_enum_list drm_dithering_enum_list[] = { -+ { DRM_MODE_DITHERING_OFF, "Off" }, -+ { DRM_MODE_DITHERING_ON, "On" }, -+ { DRM_MODE_DITHERING_AUTO, "Automatic" }, -+}; -+ - static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = { - { DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" }, - { DRM_MODE_PICTURE_ASPECT_4_3, "4:3" }, -@@ -1776,6 +1782,62 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, - } - EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property); - -+/** -+ * drm_connector_attach_dithering_property - attach atomic dithering property -+ * @connector: connector to attach dithering property on. -+ * @dithering_mask: or'ed mask of BIT(%DRM_MODE_DITHERING_\*). -+ * -+ * This is used to add support for dithering to atomic drivers. -+ * -+ * Returns: -+ * Zero on success, negative errno on failure. -+ */ -+int drm_connector_attach_dithering_property(struct drm_connector *connector, -+ u32 dithering_mask) -+{ -+ struct drm_device *dev = connector->dev; -+ struct drm_property *dithering_property; -+ int i; -+ const unsigned int valid_dithering_mask = -+ (1U << ARRAY_SIZE(drm_dithering_enum_list)) - 1; -+ -+ if (WARN_ON(hweight32(dithering_mask) < 2 || -+ dithering_mask & ~valid_dithering_mask)) -+ return -EINVAL; -+ -+ dithering_property = -+ drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering", -+ hweight32(dithering_mask)); -+ -+ if (!dithering_property) -+ return -ENOMEM; -+ -+ for (i = 0; i < ARRAY_SIZE(drm_dithering_enum_list); i++) { -+ int ret; -+ -+ if (!(BIT(i) & dithering_mask)) -+ continue; -+ -+ ret = drm_property_add_enum(dithering_property, -+ drm_dithering_enum_list[i].type, -+ drm_dithering_enum_list[i].name); -+ -+ if (ret) { -+ drm_property_destroy(dev, dithering_property); -+ -+ return ret; -+ } -+ } -+ -+ drm_object_attach_property(&connector->base, -+ dithering_property, 0); -+ -+ connector->dithering_property = dithering_property; -+ -+ return 0; -+} -+EXPORT_SYMBOL(drm_connector_attach_dithering_property); -+ - /** - * drm_mode_create_aspect_ratio_property - create aspect ratio property - * @dev: DRM device -diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig -index 479ffdb64486..c49fb01b1ce5 100644 ---- a/drivers/gpu/drm/panel/Kconfig -+++ b/drivers/gpu/drm/panel/Kconfig -@@ -359,6 +359,15 @@ config DRM_PANEL_RAYDIUM_RM68200 - Say Y here if you want to enable support for Raydium RM68200 - 720x1280 DSI video mode panel. - -+config DRM_PANEL_ROCKTECH_HX8394 -+ tristate "Rocktech HX8394 720x1280 DSI video mode panel" -+ depends on OF -+ depends on DRM_MIPI_DSI -+ depends on BACKLIGHT_CLASS_DEVICE -+ help -+ Say Y here if you want to enable support for Rocktech HX8394 -+ 720x1280 DSI video mode panel. -+ - config DRM_PANEL_RONBO_RB070D30 - tristate "Ronbo Electronics RB070D30 panel" - depends on OF -diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile -index c8132050bcec..57d7948975c2 100644 ---- a/drivers/gpu/drm/panel/Makefile -+++ b/drivers/gpu/drm/panel/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o - obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o - obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o - obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o -+obj-$(CONFIG_DRM_PANEL_ROCKTECH_HX8394) += panel-rocktech-hx8394.o - obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o - obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o - obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o -diff --git a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c -index f80b44a8a700..70b2bb72dbbc 100644 ---- a/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c -+++ b/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c -@@ -60,6 +60,9 @@ - #define MCS_CMD2_ENA1 0xFF00 /* Enable Access Command2 "CMD2" */ - #define MCS_CMD2_ENA2 0xFF80 /* Enable Access Orise Command2 */ - -+#define OTM8009A_HDISPLAY 480 -+#define OTM8009A_VDISPLAY 800 -+ - struct otm8009a { - struct device *dev; - struct drm_panel panel; -@@ -70,19 +73,35 @@ struct otm8009a { - bool enabled; - }; - --static const struct drm_display_mode default_mode = { -- .clock = 29700, -- .hdisplay = 480, -- .hsync_start = 480 + 98, -- .hsync_end = 480 + 98 + 32, -- .htotal = 480 + 98 + 32 + 98, -- .vdisplay = 800, -- .vsync_start = 800 + 15, -- .vsync_end = 800 + 15 + 10, -- .vtotal = 800 + 15 + 10 + 14, -- .flags = 0, -- .width_mm = 52, -- .height_mm = 86, -+static const struct drm_display_mode modes[] = { -+ { /* 50 Hz, preferred */ -+ .clock = 29700, -+ .hdisplay = 480, -+ .hsync_start = 480 + 98, -+ .hsync_end = 480 + 98 + 32, -+ .htotal = 480 + 98 + 32 + 98, -+ .vdisplay = 800, -+ .vsync_start = 800 + 15, -+ .vsync_end = 800 + 15 + 10, -+ .vtotal = 800 + 15 + 10 + 14, -+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, -+ .width_mm = 52, -+ .height_mm = 86, -+ }, -+ { /* 60 Hz */ -+ .clock = 33000, -+ .hdisplay = 480, -+ .hsync_start = 480 + 70, -+ .hsync_end = 480 + 70 + 32, -+ .htotal = 480 + 70 + 32 + 72, -+ .vdisplay = 800, -+ .vsync_start = 800 + 15, -+ .vsync_end = 800 + 15 + 10, -+ .vtotal = 800 + 15 + 10 + 16, -+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, -+ .width_mm = 52, -+ .height_mm = 86, -+ }, - }; - - static inline struct otm8009a *panel_to_otm8009a(struct drm_panel *panel) -@@ -208,12 +227,11 @@ static int otm8009a_init_sequence(struct otm8009a *ctx) - /* Default portrait 480x800 rgb24 */ - dcs_write_seq(ctx, MIPI_DCS_SET_ADDRESS_MODE, 0x00); - -- ret = mipi_dsi_dcs_set_column_address(dsi, 0, -- default_mode.hdisplay - 1); -+ ret = mipi_dsi_dcs_set_column_address(dsi, 0, OTM8009A_HDISPLAY - 1); - if (ret) - return ret; - -- ret = mipi_dsi_dcs_set_page_address(dsi, 0, default_mode.vdisplay - 1); -+ ret = mipi_dsi_dcs_set_page_address(dsi, 0, OTM8009A_VDISPLAY - 1); - if (ret) - return ret; - -@@ -337,24 +355,35 @@ static int otm8009a_get_modes(struct drm_panel *panel, - struct drm_connector *connector) - { - struct drm_display_mode *mode; -- -- mode = drm_mode_duplicate(connector->dev, &default_mode); -- if (!mode) { -- dev_err(panel->dev, "failed to add mode %ux%u@%u\n", -- default_mode.hdisplay, default_mode.vdisplay, -- drm_mode_vrefresh(&default_mode)); -- return -ENOMEM; -+ unsigned int num_modes = ARRAY_SIZE(modes); -+ unsigned int i; -+ -+ for (i = 0; i < num_modes; i++) { -+ mode = drm_mode_duplicate(connector->dev, &modes[i]); -+ if (!mode) { -+ dev_err(panel->dev, "failed to add mode %ux%u@%u\n", -+ modes[i].hdisplay, -+ modes[i].vdisplay, -+ drm_mode_vrefresh(&modes[i])); -+ return -ENOMEM; -+ } -+ -+ mode->type = DRM_MODE_TYPE_DRIVER; -+ -+ /* Setting first mode as preferred */ -+ if (!i) -+ mode->type |= DRM_MODE_TYPE_PREFERRED; -+ -+ drm_mode_set_name(mode); -+ drm_mode_probed_add(connector, mode); - } - -- drm_mode_set_name(mode); -- -- mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; -- drm_mode_probed_add(connector, mode); -- - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; -+ connector->display_info.bus_flags = DRM_BUS_FLAG_DE_HIGH | -+ DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; - -- return 1; -+ return num_modes; - } - - static const struct drm_panel_funcs otm8009a_drm_funcs = { -@@ -419,8 +448,18 @@ static int otm8009a_probe(struct mipi_dsi_device *dsi) - - ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(ctx->reset_gpio)) { -- dev_err(dev, "cannot get reset-gpio\n"); -- return PTR_ERR(ctx->reset_gpio); -+ ret = PTR_ERR(ctx->reset_gpio); -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "cannot get reset GPIO: %d\n", ret); -+ return ret; -+ } -+ -+ /* Reset the panel to avoid visual artifacts */ -+ if (ctx->reset_gpio) { -+ gpiod_set_value_cansleep(ctx->reset_gpio, 0); -+ gpiod_set_value_cansleep(ctx->reset_gpio, 1); -+ msleep(20); -+ gpiod_set_value_cansleep(ctx->reset_gpio, 0); - } - - ctx->supply = devm_regulator_get(dev, "power"); -diff --git a/drivers/gpu/drm/panel/panel-raydium-rm68200.c b/drivers/gpu/drm/panel/panel-raydium-rm68200.c -index 412c0dbcb2b6..d5542266e754 100644 ---- a/drivers/gpu/drm/panel/panel-raydium-rm68200.c -+++ b/drivers/gpu/drm/panel/panel-raydium-rm68200.c -@@ -91,7 +91,7 @@ static const struct drm_display_mode default_mode = { - .vsync_start = 1280 + 12, - .vsync_end = 1280 + 12 + 5, - .vtotal = 1280 + 12 + 5 + 12, -- .flags = 0, -+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, - .width_mm = 68, - .height_mm = 122, - }; -@@ -347,6 +347,8 @@ static int rm68200_get_modes(struct drm_panel *panel, - - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; -+ connector->display_info.bus_flags = DRM_BUS_FLAG_DE_HIGH | -+ DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE; - - return 1; - } -@@ -372,7 +374,8 @@ static int rm68200_probe(struct mipi_dsi_device *dsi) - ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(ctx->reset_gpio)) { - ret = PTR_ERR(ctx->reset_gpio); -- dev_err(dev, "cannot get reset GPIO: %d\n", ret); -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "cannot get reset GPIO: %d\n", ret); - return ret; - } - -diff --git a/drivers/gpu/drm/panel/panel-rocktech-hx8394.c b/drivers/gpu/drm/panel/panel-rocktech-hx8394.c -new file mode 100644 -index 000000000000..6a5926cc79ba ---- /dev/null -+++ b/drivers/gpu/drm/panel/panel-rocktech-hx8394.c -@@ -0,0 +1,397 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) STMicroelectronics SA 2022 -+ * -+ * Author: Yannick Fertre -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include