summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-03-09 15:26:34 -0600
committerTom Rini <[email protected]>2026-03-09 15:26:34 -0600
commit1e240f7206fccde4ec73ea432ab8360d321c5fe5 (patch)
tree931d5985e8a237b5604999922f5662fc464a8817 /drivers
parent36add050eea439f0b2a15e4ea0d3a8e21216f159 (diff)
parentba7bf918dafcd093ad733b07ba490baeb20cf5da (diff)
Merge tag 'v2026.04-rc4' into next
Prepare v2026.04-rc4
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/adi/Kconfig5
-rw-r--r--drivers/clk/adi/Makefile5
-rw-r--r--drivers/clk/adi/clk-adi-pll.c2
-rw-r--r--drivers/clk/adi/clk-adi-sc57x.c2
-rw-r--r--drivers/clk/adi/clk-adi-sc58x.c2
-rw-r--r--drivers/clk/adi/clk-adi-sc594.c2
-rw-r--r--drivers/clk/adi/clk-adi-sc598.c2
-rw-r--r--drivers/clk/adi/clk-shared.c2
-rw-r--r--drivers/clk/adi/clk.h2
-rw-r--r--drivers/clk/stm32/Kconfig9
-rw-r--r--drivers/clk/stm32/Makefile1
-rw-r--r--drivers/clk/stm32/clk-stm32mp21.c709
-rw-r--r--drivers/core/ofnode.c13
-rw-r--r--drivers/cpu/Kconfig2
-rw-r--r--drivers/dma/adi_dma.c5
-rw-r--r--drivers/firmware/scmi/mailbox_agent.c2
-rw-r--r--drivers/firmware/scmi/optee_agent.c3
-rw-r--r--drivers/gpio/adp5588_gpio.c4
-rw-r--r--drivers/gpio/gpio-adi-adsp.c3
-rw-r--r--drivers/gpio/stm32_gpio.c25
-rw-r--r--drivers/gpio/stm32_gpio_priv.h5
-rw-r--r--drivers/i2c/adi_i2c.c4
-rw-r--r--drivers/iommu/iommu-uclass.c3
-rw-r--r--drivers/mmc/adi_sdhci.c4
-rw-r--r--drivers/net/dwc_eth_qos_adi.c3
-rw-r--r--drivers/pci/pcie_cdns_ti.c10
-rw-r--r--drivers/phy/Kconfig10
-rw-r--r--drivers/phy/Makefile1
-rw-r--r--drivers/phy/phy-exynos-usbdrd.c271
-rw-r--r--drivers/phy/phy-mtk-ufs.c190
-rw-r--r--drivers/pinctrl/pinctrl-adi-adsp.c3
-rw-r--r--drivers/pinctrl/pinctrl_stm32.c83
-rw-r--r--drivers/power/domain/power-domain-uclass.c3
-rw-r--r--drivers/remoteproc/adi_sc5xx_rproc.c4
-rw-r--r--drivers/reset/stm32/Kconfig7
-rw-r--r--drivers/reset/stm32/Makefile1
-rw-r--r--drivers/reset/stm32/stm32-reset-mp21.c136
-rw-r--r--drivers/serial/serial_adi_uart4.c4
-rw-r--r--drivers/spi/adi_spi3.c6
-rw-r--r--drivers/timer/adi_sc5xx_timer.c3
-rw-r--r--drivers/ufs/cdns-platform.c1
-rw-r--r--drivers/ufs/ufs-amd-versal2.c1
-rw-r--r--drivers/ufs/ufs-pci.c1
-rw-r--r--drivers/ufs/ufs-qcom.c1
-rw-r--r--drivers/ufs/ufs-renesas-rcar-gen5.c1
-rw-r--r--drivers/ufs/ufs-renesas.c1
-rw-r--r--drivers/ufs/ufs-rockchip.c1
-rw-r--r--drivers/ufs/ufs-uclass.c12
-rw-r--r--drivers/ufs/ufshcd-dwc.c1
-rw-r--r--drivers/usb/musb-new/sc5xx.c2
-rw-r--r--drivers/video/exynos/exynos_fb.c2
-rw-r--r--drivers/video/nexell/soc/s5pxx18_soc_mlc.c2
-rw-r--r--drivers/video/stm32/stm32_dsi.c164
-rw-r--r--drivers/watchdog/adi_wdt.c4
54 files changed, 1574 insertions, 171 deletions
diff --git a/drivers/clk/adi/Kconfig b/drivers/clk/adi/Kconfig
index 5745bedf88c..94cf744305f 100644
--- a/drivers/clk/adi/Kconfig
+++ b/drivers/clk/adi/Kconfig
@@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
-# Written and/or maintained by Timesys Corporation
-#
-# Contact: Nathan Barrett-Morrison <[email protected]>
-# Contact: Greg Malysa <[email protected]>
+# Written by Timesys Corporation
#
config COMMON_CLK_ADI_SHARED
diff --git a/drivers/clk/adi/Makefile b/drivers/clk/adi/Makefile
index f3f1fd92e5f..b7664fe1da0 100644
--- a/drivers/clk/adi/Makefile
+++ b/drivers/clk/adi/Makefile
@@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
-# Written and/or maintained by Timesys Corporation
-#
-# Contact: Nathan Barrett-Morrison <[email protected]>
-# Contact: Greg Malysa <[email protected]>
+# Written by Timesys Corporation
#
obj-$(CONFIG_COMMON_CLK_ADI_SHARED) += clk-shared.o clk-adi-pll.o
diff --git a/drivers/clk/adi/clk-adi-pll.c b/drivers/clk/adi/clk-adi-pll.c
index 372baa9c11b..34818cb1af0 100644
--- a/drivers/clk/adi/clk-adi-pll.c
+++ b/drivers/clk/adi/clk-adi-pll.c
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*
diff --git a/drivers/clk/adi/clk-adi-sc57x.c b/drivers/clk/adi/clk-adi-sc57x.c
index b17563f0444..3eeb3109bd6 100644
--- a/drivers/clk/adi/clk-adi-sc57x.c
+++ b/drivers/clk/adi/clk-adi-sc57x.c
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*
diff --git a/drivers/clk/adi/clk-adi-sc58x.c b/drivers/clk/adi/clk-adi-sc58x.c
index 05a0feddec7..776e4748c42 100644
--- a/drivers/clk/adi/clk-adi-sc58x.c
+++ b/drivers/clk/adi/clk-adi-sc58x.c
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*
diff --git a/drivers/clk/adi/clk-adi-sc594.c b/drivers/clk/adi/clk-adi-sc594.c
index c80bbf9728d..6749c6d0382 100644
--- a/drivers/clk/adi/clk-adi-sc594.c
+++ b/drivers/clk/adi/clk-adi-sc594.c
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*
diff --git a/drivers/clk/adi/clk-adi-sc598.c b/drivers/clk/adi/clk-adi-sc598.c
index d4a16ac9603..05176f2fa85 100644
--- a/drivers/clk/adi/clk-adi-sc598.c
+++ b/drivers/clk/adi/clk-adi-sc598.c
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*
diff --git a/drivers/clk/adi/clk-shared.c b/drivers/clk/adi/clk-shared.c
index dcadcafa9d2..afd5f46c845 100644
--- a/drivers/clk/adi/clk-shared.c
+++ b/drivers/clk/adi/clk-shared.c
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*/
diff --git a/drivers/clk/adi/clk.h b/drivers/clk/adi/clk.h
index f230205c311..acd4e384746 100644
--- a/drivers/clk/adi/clk.h
+++ b/drivers/clk/adi/clk.h
@@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
*
diff --git a/drivers/clk/stm32/Kconfig b/drivers/clk/stm32/Kconfig
index ea856be1662..4e488136eac 100644
--- a/drivers/clk/stm32/Kconfig
+++ b/drivers/clk/stm32/Kconfig
@@ -37,6 +37,15 @@ config CLK_STM32MP13
Enable the STM32 clock (RCC) driver. Enable support for
manipulating STM32MP13's on-SoC clocks.
+config CLK_STM32MP21
+ bool "Enable RCC clock driver for STM32MP21"
+ depends on ARCH_STM32MP && CLK
+ default y if STM32MP21X
+ select CLK_STM32_CORE
+ help
+ Enable the STM32 clock (RCC) driver. Enable support for
+ manipulating STM32MP21's on-SoC clocks.
+
config CLK_STM32MP25
bool "Enable RCC clock driver for STM32MP25"
depends on ARCH_STM32MP && CLK
diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile
index 56adb8a4bbb..0b849c52a3b 100644
--- a/drivers/clk/stm32/Makefile
+++ b/drivers/clk/stm32/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_CLK_STM32F) += clk-stm32f.o
obj-$(CONFIG_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_CLK_STM32MP1) += clk-stm32mp1.o
obj-$(CONFIG_CLK_STM32MP13) += clk-stm32mp13.o
+obj-$(CONFIG_CLK_STM32MP21) += clk-stm32mp21.o
obj-$(CONFIG_CLK_STM32MP25) += clk-stm32mp25.o
diff --git a/drivers/clk/stm32/clk-stm32mp21.c b/drivers/clk/stm32/clk-stm32mp21.c
new file mode 100644
index 00000000000..ad990b6ad93
--- /dev/null
+++ b/drivers/clk/stm32/clk-stm32mp21.c
@@ -0,0 +1,709 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2026, STMicroelectronics - All Rights Reserved
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-bindings/clock/st,stm32mp21-rcc.h>
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <mach/rif.h>
+
+#include "clk-stm32-core.h"
+#include "stm32mp21_rcc.h"
+
+/* Clock security definition */
+#define SECF_NONE -1
+
+#define RCC_REG_SIZE 32
+#define RCC_SECCFGR(x) (((x) / RCC_REG_SIZE) * 0x4 + RCC_SECCFGR0)
+#define RCC_CIDCFGR(x) ((x) * 0x8 + RCC_R0CIDCFGR)
+#define RCC_SEMCR(x) ((x) * 0x8 + RCC_R0SEMCR)
+#define RCC_CID1 1
+
+/* Register: RIFSC_CIDCFGR */
+#define RCC_CIDCFGR_CFEN BIT(0)
+#define RCC_CIDCFGR_SEM_EN BIT(1)
+#define RCC_CIDCFGR_SEMWLC1_EN BIT(17)
+#define RCC_CIDCFGR_SCID_MASK GENMASK(6, 4)
+
+/* Register: RIFSC_SEMCR */
+#define RCC_SEMCR_SEMCID_MASK GENMASK(6, 4)
+
+#define STM32MP21_RIFRCC_DBG_ID 73
+#define STM32MP21_RIFRCC_MCO1_ID 108
+#define STM32MP21_RIFRCC_MCO2_ID 109
+#define STM32MP21_RIFRCC_OSPI1_ID 110
+
+#define SEC_RIFSC_FLAG BIT(31)
+#define SEC_RIFRCC(_id) (STM32MP21_RIFRCC_##_id##_ID)
+#define SEC_RIFSC(_id) ((_id) | SEC_RIFSC_FLAG)
+
+/* must match scmi clock order found in DT */
+enum {
+ IDX_HSE,
+ IDX_HSI,
+ IDX_MSI,
+ IDX_LSE,
+ IDX_LSI,
+ IDX_HSE_DIV2,
+ IDX_ICN_HS_MCU,
+ IDX_ICN_LS_MCU,
+ IDX_ICN_SDMMC,
+ IDX_ICN_DDR,
+ IDX_ICN_DISPLAY,
+ IDX_ICN_HSL,
+ IDX_ICN_NIC,
+ IDX_FLEXGEN_07,
+ IDX_FLEXGEN_08,
+ IDX_FLEXGEN_09,
+ IDX_FLEXGEN_10,
+ IDX_FLEXGEN_11,
+ IDX_FLEXGEN_12,
+ IDX_FLEXGEN_13,
+ IDX_FLEXGEN_14,
+ IDX_FLEXGEN_16,
+ IDX_FLEXGEN_17,
+ IDX_FLEXGEN_18,
+ IDX_FLEXGEN_19,
+ IDX_FLEXGEN_20,
+ IDX_FLEXGEN_21,
+ IDX_FLEXGEN_22,
+ IDX_FLEXGEN_23,
+ IDX_FLEXGEN_24,
+ IDX_FLEXGEN_25,
+ IDX_FLEXGEN_26,
+ IDX_FLEXGEN_27,
+ IDX_FLEXGEN_28,
+ IDX_FLEXGEN_29,
+ IDX_FLEXGEN_30,
+ IDX_FLEXGEN_31,
+ IDX_FLEXGEN_33,
+ IDX_FLEXGEN_36,
+ IDX_FLEXGEN_37,
+ IDX_FLEXGEN_38,
+ IDX_FLEXGEN_39,
+ IDX_FLEXGEN_40,
+ IDX_FLEXGEN_41,
+ IDX_FLEXGEN_42,
+ IDX_FLEXGEN_43,
+ IDX_FLEXGEN_44,
+ IDX_FLEXGEN_45,
+ IDX_FLEXGEN_46,
+ IDX_FLEXGEN_47,
+ IDX_FLEXGEN_48,
+ IDX_FLEXGEN_50,
+ IDX_FLEXGEN_51,
+ IDX_FLEXGEN_52,
+ IDX_FLEXGEN_53,
+ IDX_FLEXGEN_54,
+ IDX_FLEXGEN_55,
+ IDX_FLEXGEN_56,
+ IDX_FLEXGEN_57,
+ IDX_FLEXGEN_58,
+ IDX_FLEXGEN_61,
+ IDX_FLEXGEN_62,
+ IDX_FLEXGEN_63,
+ IDX_ICN_APB1,
+ IDX_ICN_APB2,
+ IDX_ICN_APB3,
+ IDX_ICN_APB4,
+ IDX_ICN_APB5,
+ IDX_ICN_APBDBG,
+ IDX_TIMG1,
+ IDX_TIMG2,
+};
+
+static const struct clk_parent_data adc1_src[] = {
+ { .index = IDX_FLEXGEN_46 },
+ { .index = IDX_ICN_LS_MCU },
+};
+
+static const struct clk_parent_data adc2_src[] = {
+ { .index = IDX_FLEXGEN_47 },
+ { .index = IDX_ICN_LS_MCU },
+ { .index = IDX_FLEXGEN_46 },
+};
+
+static const struct clk_parent_data usb2phy1_src[] = {
+ { .index = IDX_FLEXGEN_57 },
+ { .index = IDX_HSE_DIV2 },
+};
+
+static const struct clk_parent_data usb2phy2_src[] = {
+ { .index = IDX_FLEXGEN_58 },
+ { .index = IDX_HSE_DIV2 },
+};
+
+static const struct clk_parent_data dts_src[] = {
+ { .index = IDX_HSI },
+ { .index = IDX_HSE },
+ { .index = IDX_MSI },
+};
+
+static const struct clk_parent_data mco1_src[] = {
+ { .index = IDX_FLEXGEN_61 },
+ { .name = "ck_obs0" },
+};
+
+static const struct clk_parent_data mco2_src[] = {
+ { .index = IDX_FLEXGEN_62 },
+ { .name = "ck_obs1" },
+};
+
+enum enum_mux_cfg {
+ MUX_MCO1,
+ MUX_MCO2,
+ MUX_ADC1,
+ MUX_ADC2,
+ MUX_USB2PHY1,
+ MUX_USB2PHY2,
+ MUX_DTS,
+ MUX_NB
+};
+
+#define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\
+ .num_parents = ARRAY_SIZE(src),\
+ .parent_data = src,\
+ .reg_off = (_offset),\
+ .shift = (_shift),\
+ .width = (_witdh),\
+}
+
+static const struct stm32_mux_cfg stm32mp21_muxes[MUX_NB] = {
+ MUX_CFG(MUX_ADC1, adc1_src, RCC_ADC1CFGR, 12, 1),
+ MUX_CFG(MUX_ADC2, adc2_src, RCC_ADC2CFGR, 12, 2),
+ MUX_CFG(MUX_DTS, dts_src, RCC_DTSCFGR, 12, 2),
+ MUX_CFG(MUX_MCO1, mco1_src, RCC_MCO1CFGR, 0, 1),
+ MUX_CFG(MUX_MCO2, mco2_src, RCC_MCO2CFGR, 0, 1),
+ MUX_CFG(MUX_USB2PHY1, usb2phy1_src, RCC_USB2PHY1CFGR, 15, 1),
+ MUX_CFG(MUX_USB2PHY2, usb2phy2_src, RCC_USB2PHY2CFGR, 15, 1),
+};
+
+enum enum_gate_cfg {
+ GATE_ADC1,
+ GATE_ADC2,
+ GATE_CRC,
+ GATE_CRYP1,
+ GATE_CRYP2,
+ GATE_CSI,
+ GATE_DBG,
+ GATE_DCMIPP,
+ GATE_DTS,
+ GATE_ETH1,
+ GATE_ETH1MAC,
+ GATE_ETH1RX,
+ GATE_ETH1STP,
+ GATE_ETH1TX,
+ GATE_ETH2,
+ GATE_ETH2MAC,
+ GATE_ETH2RX,
+ GATE_ETH2STP,
+ GATE_ETH2TX,
+ GATE_ETR,
+ GATE_FDCAN,
+ GATE_HASH1,
+ GATE_HASH2,
+ GATE_HDP,
+ GATE_I2C1,
+ GATE_I2C2,
+ GATE_I2C3,
+ GATE_I3C1,
+ GATE_I3C2,
+ GATE_I3C3,
+ GATE_IWDG1,
+ GATE_IWDG2,
+ GATE_IWDG3,
+ GATE_IWDG4,
+ GATE_LPTIM1,
+ GATE_LPTIM2,
+ GATE_LPTIM3,
+ GATE_LPTIM4,
+ GATE_LPTIM5,
+ GATE_LPUART1,
+ GATE_LTDC,
+ GATE_MCO1,
+ GATE_MCO2,
+ GATE_MDF1,
+ GATE_OSPI1,
+ GATE_PKA,
+ GATE_RNG1,
+ GATE_RNG2,
+ GATE_SAES,
+ GATE_SAI1,
+ GATE_SAI2,
+ GATE_SAI3,
+ GATE_SAI4,
+ GATE_SDMMC1,
+ GATE_SDMMC2,
+ GATE_SDMMC3,
+ GATE_SERC,
+ GATE_SPDIFRX,
+ GATE_SPI1,
+ GATE_SPI2,
+ GATE_SPI3,
+ GATE_SPI4,
+ GATE_SPI5,
+ GATE_SPI6,
+ GATE_STGEN,
+ GATE_STM,
+ GATE_TIM1,
+ GATE_TIM2,
+ GATE_TIM3,
+ GATE_TIM4,
+ GATE_TIM5,
+ GATE_TIM6,
+ GATE_TIM7,
+ GATE_TIM8,
+ GATE_TIM10,
+ GATE_TIM11,
+ GATE_TIM12,
+ GATE_TIM13,
+ GATE_TIM14,
+ GATE_TIM15,
+ GATE_TIM16,
+ GATE_TIM17,
+ GATE_TRACE,
+ GATE_UART4,
+ GATE_UART5,
+ GATE_UART7,
+ GATE_USART1,
+ GATE_USART2,
+ GATE_USART3,
+ GATE_USART6,
+ GATE_USBH,
+ GATE_USBOTG,
+ GATE_USB2PHY1,
+ GATE_USB2PHY2,
+ GATE_VREF,
+ GATE_WWDG1,
+ GATE_NB
+};
+
+#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\
+ .reg_off = (_offset),\
+ .bit_idx = (_bit_idx),\
+ .set_clr = (_offset_clr),\
+}
+
+static const struct stm32_gate_cfg stm32mp21_gates[GATE_NB] = {
+ GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 8, 0),
+ GATE_CFG(GATE_MCO2, RCC_MCO2CFGR, 8, 0),
+ GATE_CFG(GATE_OSPI1, RCC_OSPI1CFGR, 1, 0),
+ GATE_CFG(GATE_DBG, RCC_DBGCFGR, 8, 0),
+ GATE_CFG(GATE_TRACE, RCC_DBGCFGR, 9, 0),
+ GATE_CFG(GATE_STM, RCC_STMCFGR, 1, 0),
+ GATE_CFG(GATE_ETR, RCC_ETRCFGR, 1, 0),
+ GATE_CFG(GATE_TIM1, RCC_TIM1CFGR, 1, 0),
+ GATE_CFG(GATE_TIM2, RCC_TIM2CFGR, 1, 0),
+ GATE_CFG(GATE_TIM3, RCC_TIM3CFGR, 1, 0),
+ GATE_CFG(GATE_TIM4, RCC_TIM4CFGR, 1, 0),
+ GATE_CFG(GATE_TIM5, RCC_TIM5CFGR, 1, 0),
+ GATE_CFG(GATE_TIM6, RCC_TIM6CFGR, 1, 0),
+ GATE_CFG(GATE_TIM7, RCC_TIM7CFGR, 1, 0),
+ GATE_CFG(GATE_TIM8, RCC_TIM8CFGR, 1, 0),
+ GATE_CFG(GATE_TIM10, RCC_TIM10CFGR, 1, 0),
+ GATE_CFG(GATE_TIM11, RCC_TIM11CFGR, 1, 0),
+ GATE_CFG(GATE_TIM12, RCC_TIM12CFGR, 1, 0),
+ GATE_CFG(GATE_TIM13, RCC_TIM13CFGR, 1, 0),
+ GATE_CFG(GATE_TIM14, RCC_TIM14CFGR, 1, 0),
+ GATE_CFG(GATE_TIM15, RCC_TIM15CFGR, 1, 0),
+ GATE_CFG(GATE_TIM16, RCC_TIM16CFGR, 1, 0),
+ GATE_CFG(GATE_TIM17, RCC_TIM17CFGR, 1, 0),
+ GATE_CFG(GATE_LPTIM1, RCC_LPTIM1CFGR, 1, 0),
+ GATE_CFG(GATE_LPTIM2, RCC_LPTIM2CFGR, 1, 0),
+ GATE_CFG(GATE_LPTIM3, RCC_LPTIM3CFGR, 1, 0),
+ GATE_CFG(GATE_LPTIM4, RCC_LPTIM4CFGR, 1, 0),
+ GATE_CFG(GATE_LPTIM5, RCC_LPTIM5CFGR, 1, 0),
+ GATE_CFG(GATE_SPI1, RCC_SPI1CFGR, 1, 0),
+ GATE_CFG(GATE_SPI2, RCC_SPI2CFGR, 1, 0),
+ GATE_CFG(GATE_SPI3, RCC_SPI3CFGR, 1, 0),
+ GATE_CFG(GATE_SPI4, RCC_SPI4CFGR, 1, 0),
+ GATE_CFG(GATE_SPI5, RCC_SPI5CFGR, 1, 0),
+ GATE_CFG(GATE_SPI6, RCC_SPI6CFGR, 1, 0),
+ GATE_CFG(GATE_SPDIFRX, RCC_SPDIFRXCFGR, 1, 0),
+ GATE_CFG(GATE_USART1, RCC_USART1CFGR, 1, 0),
+ GATE_CFG(GATE_USART2, RCC_USART2CFGR, 1, 0),
+ GATE_CFG(GATE_USART3, RCC_USART3CFGR, 1, 0),
+ GATE_CFG(GATE_UART4, RCC_UART4CFGR, 1, 0),
+ GATE_CFG(GATE_UART5, RCC_UART5CFGR, 1, 0),
+ GATE_CFG(GATE_USART6, RCC_USART6CFGR, 1, 0),
+ GATE_CFG(GATE_UART7, RCC_UART7CFGR, 1, 0),
+ GATE_CFG(GATE_LPUART1, RCC_LPUART1CFGR, 1, 0),
+ GATE_CFG(GATE_I2C1, RCC_I2C1CFGR, 1, 0),
+ GATE_CFG(GATE_I2C2, RCC_I2C2CFGR, 1, 0),
+ GATE_CFG(GATE_I2C3, RCC_I2C3CFGR, 1, 0),
+ GATE_CFG(GATE_SAI1, RCC_SAI1CFGR, 1, 0),
+ GATE_CFG(GATE_SAI2, RCC_SAI2CFGR, 1, 0),
+ GATE_CFG(GATE_SAI3, RCC_SAI3CFGR, 1, 0),
+ GATE_CFG(GATE_SAI4, RCC_SAI4CFGR, 1, 0),
+ GATE_CFG(GATE_MDF1, RCC_MDF1CFGR, 1, 0),
+ GATE_CFG(GATE_FDCAN, RCC_FDCANCFGR, 1, 0),
+ GATE_CFG(GATE_HDP, RCC_HDPCFGR, 1, 0),
+ GATE_CFG(GATE_ADC1, RCC_ADC1CFGR, 1, 0),
+ GATE_CFG(GATE_ADC2, RCC_ADC2CFGR, 1, 0),
+ GATE_CFG(GATE_ETH1MAC, RCC_ETH1CFGR, 1, 0),
+ GATE_CFG(GATE_ETH1STP, RCC_ETH1CFGR, 4, 0),
+ GATE_CFG(GATE_ETH1, RCC_ETH1CFGR, 5, 0),
+ GATE_CFG(GATE_ETH1TX, RCC_ETH1CFGR, 8, 0),
+ GATE_CFG(GATE_ETH1RX, RCC_ETH1CFGR, 10, 0),
+ GATE_CFG(GATE_ETH2MAC, RCC_ETH2CFGR, 1, 0),
+ GATE_CFG(GATE_ETH2STP, RCC_ETH2CFGR, 4, 0),
+ GATE_CFG(GATE_ETH2, RCC_ETH2CFGR, 5, 0),
+ GATE_CFG(GATE_ETH2TX, RCC_ETH2CFGR, 8, 0),
+ GATE_CFG(GATE_ETH2RX, RCC_ETH2CFGR, 10, 0),
+ GATE_CFG(GATE_USBH, RCC_USBHCFGR, 1, 0),
+ GATE_CFG(GATE_USB2PHY1, RCC_USB2PHY1CFGR, 1, 0),
+ GATE_CFG(GATE_USBOTG, RCC_OTGCFGR, 1, 0),
+ GATE_CFG(GATE_USB2PHY2, RCC_USB2PHY2CFGR, 1, 0),
+ GATE_CFG(GATE_STGEN, RCC_STGENCFGR, 1, 0),
+ GATE_CFG(GATE_SDMMC1, RCC_SDMMC1CFGR, 1, 0),
+ GATE_CFG(GATE_SDMMC2, RCC_SDMMC2CFGR, 1, 0),
+ GATE_CFG(GATE_SDMMC3, RCC_SDMMC3CFGR, 1, 0),
+ GATE_CFG(GATE_LTDC, RCC_LTDCCFGR, 1, 0),
+ GATE_CFG(GATE_CSI, RCC_CSICFGR, 1, 0),
+ GATE_CFG(GATE_DCMIPP, RCC_DCMIPPCFGR, 1, 0),
+ GATE_CFG(GATE_RNG1, RCC_RNG1CFGR, 1, 0),
+ GATE_CFG(GATE_RNG2, RCC_RNG2CFGR, 1, 0),
+ GATE_CFG(GATE_PKA, RCC_PKACFGR, 1, 0),
+ GATE_CFG(GATE_SAES, RCC_SAESCFGR, 1, 0),
+ GATE_CFG(GATE_HASH1, RCC_HASH1CFGR, 1, 0),
+ GATE_CFG(GATE_HASH2, RCC_HASH2CFGR, 1, 0),
+ GATE_CFG(GATE_CRYP1, RCC_CRYP1CFGR, 1, 0),
+ GATE_CFG(GATE_CRYP2, RCC_CRYP2CFGR, 1, 0),
+ GATE_CFG(GATE_IWDG1, RCC_IWDG1CFGR, 1, 0),
+ GATE_CFG(GATE_IWDG2, RCC_IWDG2CFGR, 1, 0),
+ GATE_CFG(GATE_IWDG3, RCC_IWDG3CFGR, 1, 0),
+ GATE_CFG(GATE_IWDG4, RCC_IWDG4CFGR, 1, 0),
+ GATE_CFG(GATE_WWDG1, RCC_WWDG1CFGR, 1, 0),
+ GATE_CFG(GATE_VREF, RCC_VREFCFGR, 1, 0),
+ GATE_CFG(GATE_DTS, RCC_DTSCFGR, 1, 0),
+ GATE_CFG(GATE_CRC, RCC_CRCCFGR, 1, 0),
+ GATE_CFG(GATE_SERC, RCC_SERCCFGR, 1, 0),
+ GATE_CFG(GATE_I3C1, RCC_I3C1CFGR, 1, 0),
+ GATE_CFG(GATE_I3C2, RCC_I3C2CFGR, 1, 0),
+ GATE_CFG(GATE_I3C3, RCC_I3C3CFGR, 1, 0),
+};
+
+static int stm32_rcc_get_access(struct udevice *dev, u32 index)
+{
+ fdt_addr_t rcc_base = dev_read_addr(dev->parent);
+ u32 seccfgr, cidcfgr, semcr;
+ int bit, cid;
+
+ bit = index % RCC_REG_SIZE;
+
+ seccfgr = readl(rcc_base + RCC_SECCFGR(index));
+ if (seccfgr & BIT(bit))
+ return -EACCES;
+
+ cidcfgr = readl(rcc_base + RCC_CIDCFGR(index));
+ if (!(cidcfgr & RCC_CIDCFGR_CFEN))
+ /* CID filtering is turned off: access granted */
+ return 0;
+
+ if (!(cidcfgr & RCC_CIDCFGR_SEM_EN)) {
+ /* Static CID mode */
+ cid = FIELD_GET(RCC_CIDCFGR_SCID_MASK, cidcfgr);
+ if (cid != RCC_CID1)
+ return -EACCES;
+ return 0;
+ }
+
+ /* Pass-list with semaphore mode */
+ if (!(cidcfgr & RCC_CIDCFGR_SEMWLC1_EN))
+ return -EACCES;
+
+ semcr = readl(rcc_base + RCC_SEMCR(index));
+
+ cid = FIELD_GET(RCC_SEMCR_SEMCID_MASK, semcr);
+ if (cid != RCC_CID1)
+ return -EACCES;
+
+ return 0;
+}
+
+static int stm32mp21_check_security(struct udevice *dev, void __iomem *base,
+ const struct clock_config *cfg)
+{
+ int ret = 0;
+
+ if (cfg->sec_id != SECF_NONE) {
+ u32 index = (u32)cfg->sec_id;
+
+ if (index & SEC_RIFSC_FLAG)
+ ret = stm32_rifsc_grant_access_by_id(dev_ofnode(dev),
+ index & ~SEC_RIFSC_FLAG);
+ else
+ ret = stm32_rcc_get_access(dev, index);
+ }
+
+ return ret;
+}
+
+#define STM32_COMPOSITE_NODIV(_id, _name, _flags, _sec_id, _gate_id, _mux_id)\
+ STM32_COMPOSITE(_id, _name, _flags, _sec_id, _gate_id, _mux_id, NO_STM32_DIV)
+
+static const struct clock_config stm32mp21_clock_cfg[] = {
+ /* ADC */
+ STM32_GATE(CK_BUS_ADC1, "ck_icn_p_adc1", IDX_ICN_LS_MCU, 0, GATE_ADC1,
+ SEC_RIFSC(58)),
+ STM32_COMPOSITE_NODIV(CK_KER_ADC1, "ck_ker_adc12", 0, SEC_RIFSC(58),
+ GATE_ADC1, MUX_ADC1),
+ STM32_GATE(CK_BUS_ADC2, "ck_icn_p_adc2", IDX_ICN_LS_MCU, 0, GATE_ADC2, SEC_RIFSC(59)),
+ STM32_COMPOSITE_NODIV(CK_KER_ADC2, "ck_ker_adc2", 0, SEC_RIFSC(59), GATE_ADC2, MUX_ADC2),
+
+ /* CSI-HOST */
+ STM32_GATE(CK_BUS_CSI, "ck_icn_p_csi", IDX_ICN_APB4, 0, GATE_CSI, SEC_RIFSC(86)),
+ STM32_GATE(CK_KER_CSI, "ck_ker_csi", IDX_FLEXGEN_29, 0, GATE_CSI, SEC_RIFSC(86)),
+ STM32_GATE(CK_KER_CSITXESC, "ck_ker_csitxesc", IDX_FLEXGEN_30, 0, GATE_CSI,
+ SEC_RIFSC(86)),
+
+ /* CSI-PHY */
+ STM32_GATE(CK_KER_CSIPHY, "ck_ker_csiphy", IDX_FLEXGEN_31, 0, GATE_CSI,
+ SEC_RIFSC(86)),
+
+ /* DCMIPP */
+ STM32_GATE(CK_BUS_DCMIPP, "ck_icn_p_dcmipp", IDX_ICN_APB4, 0, GATE_DCMIPP,
+ SEC_RIFSC(87)),
+
+ /* CRC */
+ STM32_GATE(CK_BUS_CRC, "ck_icn_p_crc", IDX_ICN_LS_MCU, 0, GATE_CRC, SEC_RIFSC(109)),
+
+ /* CRYP */
+ STM32_GATE(CK_BUS_CRYP1, "ck_icn_p_cryp1", IDX_ICN_LS_MCU, 0, GATE_CRYP1,
+ SEC_RIFSC(98)),
+ STM32_GATE(CK_BUS_CRYP2, "ck_icn_p_cryp2", IDX_ICN_LS_MCU, 0, GATE_CRYP2,
+ SEC_RIFSC(99)),
+
+ /* DBG & TRACE*/
+ /* Trace and debug clocks are managed by SCMI */
+
+ /* Display subsystem */
+ /* LTDC */
+ STM32_GATE(CK_BUS_LTDC, "ck_icn_p_ltdc", IDX_ICN_APB4, 0, GATE_LTDC, SEC_RIFSC(80)),
+ STM32_GATE(CK_KER_LTDC, "ck_ker_ltdc", IDX_FLEXGEN_27, CLK_SET_RATE_PARENT, GATE_LTDC,
+ SEC_RIFSC(80)),
+
+ /* DTS */
+ STM32_COMPOSITE_NODIV(CK_KER_DTS, "ck_ker_dts", 0, SEC_RIFSC(107), GATE_DTS, MUX_DTS),
+
+ /* ETHERNET */
+ STM32_GATE(CK_BUS_ETH1, "ck_icn_p_eth1", IDX_ICN_LS_MCU, 0, GATE_ETH1, SEC_RIFSC(60)),
+ STM32_GATE(CK_ETH1_STP, "ck_ker_eth1stp", IDX_ICN_LS_MCU, 0, GATE_ETH1STP,
+ SEC_RIFSC(60)),
+ STM32_GATE(CK_KER_ETH1, "ck_ker_eth1", IDX_FLEXGEN_54, 0, GATE_ETH1, SEC_RIFSC(60)),
+ STM32_GATE(CK_KER_ETH1, "ck_ker_eth1ptp", IDX_FLEXGEN_56, 0, GATE_ETH1, SEC_RIFSC(60)),
+ STM32_GATE(CK_ETH1_MAC, "ck_ker_eth1mac", IDX_ICN_LS_MCU, 0, GATE_ETH1MAC,
+ SEC_RIFSC(60)),
+ STM32_GATE(CK_ETH1_TX, "ck_ker_eth1tx", IDX_ICN_LS_MCU, 0, GATE_ETH1TX, SEC_RIFSC(60)),
+ STM32_GATE(CK_ETH1_RX, "ck_ker_eth1rx", IDX_ICN_LS_MCU, 0, GATE_ETH1RX, SEC_RIFSC(60)),
+
+ STM32_GATE(CK_BUS_ETH2, "ck_icn_p_eth2", IDX_ICN_LS_MCU, 0, GATE_ETH2, SEC_RIFSC(61)),
+ STM32_GATE(CK_ETH2_STP, "ck_ker_eth2stp", IDX_ICN_LS_MCU, 0, GATE_ETH2STP,
+ SEC_RIFSC(61)),
+ STM32_GATE(CK_KER_ETH2, "ck_ker_eth2", IDX_FLEXGEN_54, 0, GATE_ETH2, SEC_RIFSC(61)),
+ STM32_GATE(CK_KER_ETH2, "ck_ker_eth2ptp", IDX_FLEXGEN_56, 0, GATE_ETH2, SEC_RIFSC(61)),
+ STM32_GATE(CK_ETH2_MAC, "ck_ker_eth2mac", IDX_ICN_LS_MCU, 0, GATE_ETH2MAC,
+ SEC_RIFSC(61)),
+ STM32_GATE(CK_ETH2_TX, "ck_ker_eth2tx", IDX_ICN_LS_MCU, 0, GATE_ETH2TX, SEC_RIFSC(61)),
+ STM32_GATE(CK_ETH2_RX, "ck_ker_eth2rx", IDX_ICN_LS_MCU, 0, GATE_ETH2RX, SEC_RIFSC(61)),
+
+ /* FDCAN */
+ STM32_GATE(CK_BUS_FDCAN, "ck_icn_p_fdcan", IDX_ICN_APB2, 0, GATE_FDCAN, SEC_RIFSC(56)),
+ STM32_GATE(CK_KER_FDCAN, "ck_ker_fdcan", IDX_FLEXGEN_26, 0, GATE_FDCAN, SEC_RIFSC(56)),
+
+ /* HASH */
+ STM32_GATE(CK_BUS_HASH1, "ck_icn_p_hash1", IDX_ICN_LS_MCU, 0, GATE_HASH1, SEC_RIFSC(96)),
+ STM32_GATE(CK_BUS_HASH2, "ck_icn_p_hash2", IDX_ICN_LS_MCU, 0, GATE_HASH2, SEC_RIFSC(97)),
+
+ /* HDP */
+ STM32_GATE(CK_BUS_HDP, "ck_icn_p_hdp", IDX_ICN_APB3, 0, GATE_HDP, SEC_RIFSC(57)),
+
+ /* I2C */
+ STM32_GATE(CK_KER_I2C1, "ck_ker_i2c1", IDX_FLEXGEN_13, 0, GATE_I2C1, SEC_RIFSC(41)),
+ STM32_GATE(CK_KER_I2C2, "ck_ker_i2c2", IDX_FLEXGEN_13, 0, GATE_I2C2, SEC_RIFSC(42)),
+ STM32_GATE(CK_KER_I2C3, "ck_ker_i2c3", IDX_FLEXGEN_38, 0, GATE_I2C3, SEC_RIFSC(43)),
+
+ /* I3C */
+ STM32_GATE(CK_KER_I3C1, "ck_ker_i3c1", IDX_FLEXGEN_14, 0, GATE_I3C1, SEC_RIFSC(114)),
+ STM32_GATE(CK_KER_I3C2, "ck_ker_i3c2", IDX_FLEXGEN_14, 0, GATE_I3C2, SEC_RIFSC(115)),
+ STM32_GATE(CK_KER_I3C3, "ck_ker_i3c3", IDX_FLEXGEN_36, 0, GATE_I3C3, SEC_RIFSC(116)),
+
+ /* IWDG */
+ STM32_GATE(CK_BUS_IWDG1, "ck_icn_p_iwdg1", IDX_ICN_APB3, 0, GATE_IWDG1, SEC_RIFSC(100)),
+ STM32_GATE(CK_BUS_IWDG2, "ck_icn_p_iwdg2", IDX_ICN_APB3, 0, GATE_IWDG2, SEC_RIFSC(101)),
+ STM32_GATE(CK_BUS_IWDG3, "ck_icn_p_iwdg3", IDX_ICN_APB3, 0, GATE_IWDG3, SEC_RIFSC(102)),
+ STM32_GATE(CK_BUS_IWDG4, "ck_icn_p_iwdg4", IDX_ICN_APB3, 0, GATE_IWDG4, SEC_RIFSC(103)),
+
+ /* LPTIM */
+ STM32_GATE(CK_KER_LPTIM1, "ck_ker_lptim1", IDX_FLEXGEN_07, 0, GATE_LPTIM1,
+ SEC_RIFSC(17)),
+ STM32_GATE(CK_KER_LPTIM2, "ck_ker_lptim2", IDX_FLEXGEN_07, 0, GATE_LPTIM2,
+ SEC_RIFSC(18)),
+ STM32_GATE(CK_KER_LPTIM3, "ck_ker_lptim3", IDX_FLEXGEN_40, 0, GATE_LPTIM3,
+ SEC_RIFSC(19)),
+ STM32_GATE(CK_KER_LPTIM4, "ck_ker_lptim4", IDX_FLEXGEN_41, 0, GATE_LPTIM4,
+ SEC_RIFSC(20)),
+ STM32_GATE(CK_KER_LPTIM5, "ck_ker_lptim5", IDX_FLEXGEN_42, 0, GATE_LPTIM5,
+ SEC_RIFSC(21)),
+
+ /* LPUART */
+ STM32_GATE(CK_KER_LPUART1, "ck_ker_lpuart1", IDX_FLEXGEN_39, 0, GATE_LPUART1,
+ SEC_RIFSC(40)),
+
+ /* MCO1 & MCO2 */
+ STM32_COMPOSITE_NODIV(CK_MCO1, "ck_mco1", 0, SEC_RIFRCC(MCO1), GATE_MCO1, MUX_MCO1),
+ STM32_COMPOSITE_NODIV(CK_MCO2, "ck_mco2", 0, SEC_RIFRCC(MCO2), GATE_MCO2, MUX_MCO2),
+
+ /* MDF */
+ STM32_GATE(CK_KER_MDF1, "ck_ker_mdf1", IDX_FLEXGEN_21, 0, GATE_MDF1, SEC_RIFSC(54)),
+
+ /* PKA */
+ STM32_GATE(CK_BUS_PKA, "ck_icn_p_pka", IDX_ICN_LS_MCU, 0, GATE_PKA, SEC_RIFSC(94)),
+
+ /* RNG */
+ STM32_GATE(CK_BUS_RNG1, "ck_icn_p_rng1", IDX_ICN_LS_MCU, CLK_IGNORE_UNUSED, GATE_RNG1,
+ SEC_RIFSC(92)),
+ STM32_GATE(CK_BUS_RNG2, "ck_icn_p_rng2", IDX_ICN_LS_MCU, CLK_IGNORE_UNUSED, GATE_RNG2,
+ SEC_RIFSC(93)),
+
+ /* SAES */
+ STM32_GATE(CK_BUS_SAES, "ck_icn_p_saes", IDX_ICN_LS_MCU, 0, GATE_SAES, SEC_RIFSC(95)),
+
+ /* SAI [1..4] */
+ STM32_GATE(CK_BUS_SAI1, "ck_icn_p_sai1", IDX_ICN_APB2, 0, GATE_SAI1, SEC_RIFSC(49)),
+ STM32_GATE(CK_BUS_SAI2, "ck_icn_p_sai2", IDX_ICN_APB2, 0, GATE_SAI2, SEC_RIFSC(50)),
+ STM32_GATE(CK_BUS_SAI3, "ck_icn_p_sai3", IDX_ICN_APB2, 0, GATE_SAI3, SEC_RIFSC(51)),
+ STM32_GATE(CK_BUS_SAI4, "ck_icn_p_sai4", IDX_ICN_APB2, 0, GATE_SAI4, SEC_RIFSC(52)),
+ STM32_GATE(CK_KER_SAI1, "ck_ker_sai1", IDX_FLEXGEN_22, 0, GATE_SAI1, SEC_RIFSC(49)),
+ STM32_GATE(CK_KER_SAI2, "ck_ker_sai2", IDX_FLEXGEN_23, 0, GATE_SAI2, SEC_RIFSC(50)),
+ STM32_GATE(CK_KER_SAI3, "ck_ker_sai3", IDX_FLEXGEN_24, 0, GATE_SAI3, SEC_RIFSC(51)),
+ STM32_GATE(CK_KER_SAI4, "ck_ker_sai4", IDX_FLEXGEN_25, 0, GATE_SAI4, SEC_RIFSC(52)),
+
+ /* SDMMC */
+ STM32_GATE(CK_KER_SDMMC1, "ck_ker_sdmmc1", IDX_FLEXGEN_51, 0, GATE_SDMMC1,
+ SEC_RIFSC(76)),
+ STM32_GATE(CK_KER_SDMMC2, "ck_ker_sdmmc2", IDX_FLEXGEN_52, 0, GATE_SDMMC2,
+ SEC_RIFSC(77)),
+ STM32_GATE(CK_KER_SDMMC3, "ck_ker_sdmmc3", IDX_FLEXGEN_53, 0, GATE_SDMMC3,
+ SEC_RIFSC(78)),
+
+ /* SERC */
+ STM32_GATE(CK_BUS_SERC, "ck_icn_p_serc", IDX_ICN_APB3, 0, GATE_SERC, SEC_RIFSC(110)),
+
+ /* SPDIF */
+ STM32_GATE(CK_KER_SPDIFRX, "ck_ker_spdifrx", IDX_FLEXGEN_12, 0, GATE_SPDIFRX,
+ SEC_RIFSC(30)),
+
+ /* SPI */
+ STM32_GATE(CK_KER_SPI1, "ck_ker_spi1", IDX_FLEXGEN_16, 0, GATE_SPI1, SEC_RIFSC(22)),
+ STM32_GATE(CK_KER_SPI2, "ck_ker_spi2", IDX_FLEXGEN_10, 0, GATE_SPI2, SEC_RIFSC(23)),
+ STM32_GATE(CK_KER_SPI3, "ck_ker_spi3", IDX_FLEXGEN_11, 0, GATE_SPI3, SEC_RIFSC(24)),
+ STM32_GATE(CK_KER_SPI4, "ck_ker_spi4", IDX_FLEXGEN_17, 0, GATE_SPI4, SEC_RIFSC(25)),
+ STM32_GATE(CK_KER_SPI5, "ck_ker_spi5", IDX_FLEXGEN_17, 0, GATE_SPI5, SEC_RIFSC(26)),
+ STM32_GATE(CK_KER_SPI6, "ck_ker_spi6", IDX_FLEXGEN_37, 0, GATE_SPI6, SEC_RIFSC(27)),
+
+ /* STGEN */
+ STM32_GATE(CK_KER_STGEN, "ck_ker_stgen", IDX_FLEXGEN_33, CLK_IGNORE_UNUSED, GATE_STGEN,
+ SEC_RIFSC(73)),
+
+ /* Timers */
+ STM32_GATE(CK_KER_TIM2, "ck_ker_tim2", IDX_TIMG1, 0, GATE_TIM2, SEC_RIFSC(1)),
+ STM32_GATE(CK_KER_TIM3, "ck_ker_tim3", IDX_TIMG1, 0, GATE_TIM3, SEC_RIFSC(2)),
+ STM32_GATE(CK_KER_TIM4, "ck_ker_tim4", IDX_TIMG1, 0, GATE_TIM4, SEC_RIFSC(3)),
+ STM32_GATE(CK_KER_TIM5, "ck_ker_tim5", IDX_TIMG1, 0, GATE_TIM5, SEC_RIFSC(4)),
+ STM32_GATE(CK_KER_TIM6, "ck_ker_tim6", IDX_TIMG1, 0, GATE_TIM6, SEC_RIFSC(5)),
+ STM32_GATE(CK_KER_TIM7, "ck_ker_tim7", IDX_TIMG1, 0, GATE_TIM7, SEC_RIFSC(6)),
+ STM32_GATE(CK_KER_TIM10, "ck_ker_tim10", IDX_TIMG1, 0, GATE_TIM10, SEC_RIFSC(8)),
+ STM32_GATE(CK_KER_TIM11, "ck_ker_tim11", IDX_TIMG1, 0, GATE_TIM11, SEC_RIFSC(9)),
+ STM32_GATE(CK_KER_TIM12, "ck_ker_tim12", IDX_TIMG1, 0, GATE_TIM12, SEC_RIFSC(10)),
+ STM32_GATE(CK_KER_TIM13, "ck_ker_tim13", IDX_TIMG1, 0, GATE_TIM13, SEC_RIFSC(11)),
+ STM32_GATE(CK_KER_TIM14, "ck_ker_tim14", IDX_TIMG1, 0, GATE_TIM14, SEC_RIFSC(12)),
+
+ STM32_GATE(CK_KER_TIM1, "ck_ker_tim1", IDX_TIMG2, 0, GATE_TIM1, SEC_RIFSC(0)),
+ STM32_GATE(CK_KER_TIM8, "ck_ker_tim8", IDX_TIMG2, 0, GATE_TIM8, SEC_RIFSC(7)),
+ STM32_GATE(CK_KER_TIM15, "ck_ker_tim15", IDX_TIMG2, 0, GATE_TIM15, SEC_RIFSC(13)),
+ STM32_GATE(CK_KER_TIM16, "ck_ker_tim16", IDX_TIMG2, 0, GATE_TIM16, SEC_RIFSC(14)),
+ STM32_GATE(CK_KER_TIM17, "ck_ker_tim17", IDX_TIMG2, 0, GATE_TIM17, SEC_RIFSC(15)),
+
+ /* UART/USART */
+ STM32_GATE(CK_KER_USART2, "ck_ker_usart2", IDX_FLEXGEN_08, 0, GATE_USART2,
+ SEC_RIFSC(32)),
+ STM32_GATE(CK_KER_UART4, "ck_ker_uart4", IDX_FLEXGEN_08, 0, GATE_UART4,
+ SEC_RIFSC(34)),
+ STM32_GATE(CK_KER_USART3, "ck_ker_usart3", IDX_FLEXGEN_09, 0, GATE_USART3,
+ SEC_RIFSC(33)),
+ STM32_GATE(CK_KER_UART5, "ck_ker_uart5", IDX_FLEXGEN_09, 0, GATE_UART5,
+ SEC_RIFSC(35)),
+ STM32_GATE(CK_KER_USART1, "ck_ker_usart1", IDX_FLEXGEN_18, 0, GATE_USART1,
+ SEC_RIFSC(31)),
+ STM32_GATE(CK_KER_USART6, "ck_ker_usart6", IDX_FLEXGEN_19, 0, GATE_USART6,
+ SEC_RIFSC(36)),
+ STM32_GATE(CK_KER_UART7, "ck_ker_uart7", IDX_FLEXGEN_20, 0, GATE_UART7,
+ SEC_RIFSC(37)),
+
+ /* USB2PHY1 */
+ STM32_COMPOSITE_NODIV(CK_KER_USB2PHY1, "ck_ker_usb2phy1", 0, SEC_RIFSC(63),
+ GATE_USB2PHY1, MUX_USB2PHY1),
+
+ /* USB2H */
+ STM32_GATE(CK_BUS_USBHOHCI, "ck_icn_m_usbhohci", IDX_ICN_HSL, 0, GATE_USBH,
+ SEC_RIFSC(63)),
+ STM32_GATE(CK_BUS_USBHEHCI, "ck_icn_m_usbhehci", IDX_ICN_HSL, 0, GATE_USBH,
+ SEC_RIFSC(63)),
+
+ /* USBOTG */
+ STM32_GATE(CK_BUS_OTG, "ck_icn_m_otg", IDX_ICN_HSL, 0, GATE_USBOTG,
+ SEC_RIFSC(66)),
+
+ /* USB2PHY2 */
+ STM32_COMPOSITE_NODIV(CK_KER_USB2PHY2EN, "ck_ker_usb2phy2_en", 0, SEC_RIFSC(66),
+ GATE_USB2PHY2, MUX_USB2PHY2),
+
+ /* VREF */
+ STM32_GATE(CK_BUS_VREF, "ck_icn_p_vref", IDX_ICN_APB3, 0, RCC_VREFCFGR,
+ SEC_RIFSC(106)),
+
+ /* WWDG */
+ STM32_GATE(CK_BUS_WWDG1, "ck_icn_p_wwdg1", IDX_ICN_APB3, 0, GATE_WWDG1,
+ SEC_RIFSC(104)),
+};
+
+static const struct stm32_clock_match_data stm32mp21_data = {
+ .tab_clocks = stm32mp21_clock_cfg,
+ .num_clocks = ARRAY_SIZE(stm32mp21_clock_cfg),
+ .clock_data = &(const struct clk_stm32_clock_data) {
+ .num_gates = ARRAY_SIZE(stm32mp21_gates),
+ .gates = stm32mp21_gates,
+ .muxes = stm32mp21_muxes,
+ },
+ .check_security = stm32mp21_check_security,
+
+};
+
+static int stm32mp21_clk_probe(struct udevice *dev)
+{
+ fdt_addr_t base = dev_read_addr(dev->parent);
+ struct udevice *scmi;
+
+ if (base == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ /* force SCMI probe to register all SCMI clocks */
+ uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(scmi_clock), &scmi);
+
+ stm32_rcc_init(dev, &stm32mp21_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(stm32mp21_clock) = {
+ .name = "stm32mp21_clk",
+ .id = UCLASS_CLK,
+ .ops = &stm32_clk_ops,
+ .priv_auto = sizeof(struct stm32mp_rcc_priv),
+ .probe = stm32mp21_clk_probe,
+};
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index cf1cf8abfbe..3a36b6fdd03 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -164,15 +164,20 @@ void *ofnode_lookup_fdt(ofnode node)
void *ofnode_to_fdt(ofnode node)
{
+ void *fdt;
+
#ifdef OF_CHECKS
if (of_live_active())
- return NULL;
+ panic("%s called with live tree in use!\n", __func__);
#endif
if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && ofnode_valid(node))
- return ofnode_lookup_fdt(node);
+ fdt = ofnode_lookup_fdt(node);
+ else
+ fdt = (void *)gd->fdt_blob;
+
+ assert(fdt);
- /* Use the control FDT by default */
- return (void *)gd->fdt_blob;
+ return fdt;
}
/**
diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig
index 4cc3679c009..6a96be94de4 100644
--- a/drivers/cpu/Kconfig
+++ b/drivers/cpu/Kconfig
@@ -3,7 +3,7 @@ config CPU
help
This allows drivers to be provided for CPUs and their type to be
specified in the board's device tree. For boards which support
- multiple CPUs, then normally have to be set up in U-Boot so that
+ multiple CPUs, they normally have to be set up in U-Boot so that
they can work correctly in the OS. This provides a framework for
finding out information about available CPUs and making changes.
diff --git a/drivers/dma/adi_dma.c b/drivers/dma/adi_dma.c
index 28afe488db0..9244ba22068 100644
--- a/drivers/dma/adi_dma.c
+++ b/drivers/dma/adi_dma.c
@@ -4,11 +4,8 @@
*
* (C) Copyright 2024 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
- * Contact: Ian Roberts <[email protected]>
*
*/
#include <dm.h>
diff --git a/drivers/firmware/scmi/mailbox_agent.c b/drivers/firmware/scmi/mailbox_agent.c
index 16a82f55ab7..cda94565de5 100644
--- a/drivers/firmware/scmi/mailbox_agent.c
+++ b/drivers/firmware/scmi/mailbox_agent.c
@@ -101,7 +101,7 @@ static int scmi_mbox_get_channel(struct udevice *dev,
struct scmi_mbox_channel *chan;
int ret;
- if (!dev_read_prop(protocol, "shmem", NULL)) {
+ if (!dev_has_ofnode(protocol) || !dev_read_prop(protocol, "shmem", NULL)) {
/* Uses agent base channel */
*channel = container_of(base_chan, struct scmi_channel, ref);
diff --git a/drivers/firmware/scmi/optee_agent.c b/drivers/firmware/scmi/optee_agent.c
index 631625d715b..7170bd1e682 100644
--- a/drivers/firmware/scmi/optee_agent.c
+++ b/drivers/firmware/scmi/optee_agent.c
@@ -331,7 +331,8 @@ static int scmi_optee_get_channel(struct udevice *dev,
u32 channel_id;
int ret;
- if (dev_read_u32(protocol, "linaro,optee-channel-id", &channel_id)) {
+ if (!dev_has_ofnode(protocol) ||
+ dev_read_u32(protocol, "linaro,optee-channel-id", &channel_id)) {
/* Uses agent base channel */
*channel = container_of(base_chan, struct scmi_channel, ref);
diff --git a/drivers/gpio/adp5588_gpio.c b/drivers/gpio/adp5588_gpio.c
index 36304e48893..a5b2ccfea17 100644
--- a/drivers/gpio/adp5588_gpio.c
+++ b/drivers/gpio/adp5588_gpio.c
@@ -5,10 +5,8 @@
*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
*
* Based on Michael Hennerich's Linux driver:
* Michael Hennerich <[email protected]>
diff --git a/drivers/gpio/gpio-adi-adsp.c b/drivers/gpio/gpio-adi-adsp.c
index 0ce00572e08..af54354fa76 100644
--- a/drivers/gpio/gpio-adi-adsp.c
+++ b/drivers/gpio/gpio-adi-adsp.c
@@ -2,10 +2,9 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
- * Additional Contact: Nathan Barrett-Morrison <[email protected]>
*/
#include <dm.h>
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c
index b8eb55465d3..e354a4148ca 100644
--- a/drivers/gpio/stm32_gpio.c
+++ b/drivers/gpio/stm32_gpio.c
@@ -32,6 +32,9 @@
#define OTYPE_BITS(gpio_pin) (gpio_pin)
#define OTYPE_MSK 1
+#define SECCFG_BITS(gpio_pin) (gpio_pin)
+#define SECCFG_MSK 1
+
static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs,
int idx,
int mode)
@@ -89,6 +92,27 @@ static bool stm32_gpio_is_mapped(struct udevice *dev, int offset)
return !!(priv->gpio_range & BIT(offset));
}
+static int stm32_gpio_request(struct udevice *dev, unsigned int offset, const char *label)
+{
+ struct stm32_gpio_priv *priv = dev_get_priv(dev);
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct stm32_gpio_regs *regs = priv->regs;
+ ulong drv_data = dev_get_driver_data(dev);
+
+ if (!stm32_gpio_is_mapped(dev, offset))
+ return -ENXIO;
+
+ /* Deny request access if IO is secured */
+ if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) &&
+ ((readl(&regs->seccfgr) >> SECCFG_BITS(offset)) & SECCFG_MSK)) {
+ dev_err(dev, "Failed to get secure IO %s %d @ %p\n",
+ uc_priv->bank_name, offset, regs);
+ return -EACCES;
+ }
+
+ return 0;
+}
+
static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct stm32_gpio_priv *priv = dev_get_priv(dev);
@@ -238,6 +262,7 @@ static int stm32_gpio_get_flags(struct udevice *dev, unsigned int offset,
}
static const struct dm_gpio_ops gpio_stm32_ops = {
+ .request = stm32_gpio_request,
.direction_input = stm32_gpio_direction_input,
.direction_output = stm32_gpio_direction_output,
.get_value = stm32_gpio_get_value,
diff --git a/drivers/gpio/stm32_gpio_priv.h b/drivers/gpio/stm32_gpio_priv.h
index 662a000fe73..d89e9b8ed60 100644
--- a/drivers/gpio/stm32_gpio_priv.h
+++ b/drivers/gpio/stm32_gpio_priv.h
@@ -51,6 +51,8 @@ enum stm32_gpio_af {
STM32_GPIO_AF15
};
+#define STM32_GPIO_FLAG_SEC_CTRL BIT(0)
+
struct stm32_gpio_dsc {
u8 port;
u8 pin;
@@ -74,6 +76,9 @@ struct stm32_gpio_regs {
u32 bsrr; /* GPIO port bit set/reset */
u32 lckr; /* GPIO port configuration lock */
u32 afr[2]; /* GPIO alternate function */
+ u32 brr; /* GPIO port bit reset */
+ u32 rfu; /* Reserved */
+ u32 seccfgr; /* GPIO secure configuration */
};
struct stm32_gpio_priv {
diff --git a/drivers/i2c/adi_i2c.c b/drivers/i2c/adi_i2c.c
index 4cddcfa6b7f..c80a1517b5f 100644
--- a/drivers/i2c/adi_i2c.c
+++ b/drivers/i2c/adi_i2c.c
@@ -2,12 +2,10 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Converted to driver model by Nathan Barrett-Morrison
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
*/
#include <clk.h>
diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c
index bb31cd519d2..31b40e5713a 100644
--- a/drivers/iommu/iommu-uclass.c
+++ b/drivers/iommu/iommu-uclass.c
@@ -79,6 +79,9 @@ int dev_iommu_enable(struct udevice *dev)
const struct iommu_ops *ops;
int i, count, ret = 0;
+ if (!dev_has_ofnode(dev))
+ return 0;
+
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
for (i = 0; i < count; i++) {
diff --git a/drivers/mmc/adi_sdhci.c b/drivers/mmc/adi_sdhci.c
index f58897b5218..2bcd16ec3ba 100644
--- a/drivers/mmc/adi_sdhci.c
+++ b/drivers/mmc/adi_sdhci.c
@@ -2,10 +2,8 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
*
* Based on Rockchip's sdhci.c file
*/
diff --git a/drivers/net/dwc_eth_qos_adi.c b/drivers/net/dwc_eth_qos_adi.c
index fee50a88156..b578225eaad 100644
--- a/drivers/net/dwc_eth_qos_adi.c
+++ b/drivers/net/dwc_eth_qos_adi.c
@@ -2,10 +2,9 @@
/**
* (C) Copyright 2024 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
- * Additional Contact: Nathan Barrett-Morrison <[email protected]>
*/
#include <clk.h>
diff --git a/drivers/pci/pcie_cdns_ti.c b/drivers/pci/pcie_cdns_ti.c
index 38804f1c09c..63d249c2506 100644
--- a/drivers/pci/pcie_cdns_ti.c
+++ b/drivers/pci/pcie_cdns_ti.c
@@ -860,6 +860,12 @@ static const struct pcie_cdns_ti_data j722s_pcie_rc_data = {
.max_lanes = 1,
};
+static const struct pcie_cdns_ti_data j784s4_pcie_rc_data = {
+ .mode = PCIE_MODE_RC,
+ .quirk_detect_quiet_flag = true,
+ .max_lanes = 4,
+};
+
static const struct udevice_id pcie_cdns_ti_ids[] = {
{
.compatible = "ti,j7200-pcie-host",
@@ -873,6 +879,10 @@ static const struct udevice_id pcie_cdns_ti_ids[] = {
.compatible = "ti,j722s-pcie-host",
.data = (ulong)&j722s_pcie_rc_data,
},
+ {
+ .compatible = "ti,j784s4-pcie-host",
+ .data = (ulong)&j784s4_pcie_rc_data,
+ },
{},
};
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 87729b479bd..09810b62b51 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -282,6 +282,16 @@ config PHY_MTK_TPHY
multi-ports is first version, otherwise is second veriosn,
so you can easily distinguish them by banks layout.
+config PHY_MTK_UFS
+ tristate "MediaTek UFS M-PHY driver"
+ depends on ARCH_MEDIATEK
+ depends on PHY
+ help
+ Support for UFS M-PHY on MediaTek chipsets.
+ Enable this to provide vendor-specific probing,
+ initialization, power on and power off flow of
+ specified M-PHYs.
+
config PHY_NPCM_USB
bool "Nuvoton NPCM USB PHY support"
depends on PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 5a6df0ecfeb..83102349669 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o
obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
obj-$(CONFIG_PHY_EXYNOS_USBDRD) += phy-exynos-usbdrd.o
obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
+obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o
obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o
obj-$(CONFIG_$(PHASE_)PHY_IMX8MQ_USB) += phy-imx8mq-usb.o
obj-$(CONFIG_PHY_IMX8M_PCIE) += phy-imx8m-pcie.o
diff --git a/drivers/phy/phy-exynos-usbdrd.c b/drivers/phy/phy-exynos-usbdrd.c
index db5815ed184..c5eed29a2c8 100644
--- a/drivers/phy/phy-exynos-usbdrd.c
+++ b/drivers/phy/phy-exynos-usbdrd.c
@@ -21,6 +21,7 @@
/* Offset of PMU register controlling USB PHY output isolation */
#define EXYNOS_USBDRD_PHY_CONTROL 0x0704
#define EXYNOS_PHY_ENABLE BIT(0)
+#define EXYNOS7870_PHY_ENABLE BIT(1)
/* Exynos USB PHY registers */
#define EXYNOS5_FSEL_9MHZ6 0x0
@@ -32,6 +33,88 @@
#define EXYNOS5_FSEL_26MHZ 0x6
#define EXYNOS5_FSEL_50MHZ 0x7
+/* Exynos5: USB DRD PHY registers */
+#define EXYNOS5_DRD_LINKSYSTEM 0x04
+#define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27)
+#define LINKSYSTEM_FORCE_VBUSVALID BIT(8)
+#define LINKSYSTEM_FORCE_BVALID BIT(7)
+#define LINKSYSTEM_FLADJ GENMASK(6, 1)
+
+#define EXYNOS5_DRD_PHYUTMI 0x08
+#define PHYUTMI_UTMI_SUSPEND_COM_N BIT(12)
+#define PHYUTMI_UTMI_L1_SUSPEND_COM_N BIT(11)
+#define PHYUTMI_VBUSVLDEXTSEL BIT(10)
+#define PHYUTMI_VBUSVLDEXT BIT(9)
+#define PHYUTMI_TXBITSTUFFENH BIT(8)
+#define PHYUTMI_TXBITSTUFFEN BIT(7)
+#define PHYUTMI_OTGDISABLE BIT(6)
+#define PHYUTMI_IDPULLUP BIT(5)
+#define PHYUTMI_DRVVBUS BIT(4)
+#define PHYUTMI_DPPULLDOWN BIT(3)
+#define PHYUTMI_DMPULLDOWN BIT(2)
+#define PHYUTMI_FORCESUSPEND BIT(1)
+#define PHYUTMI_FORCESLEEP BIT(0)
+
+#define EXYNOS5_DRD_PHYCLKRST 0x10
+#define PHYCLKRST_EN_UTMISUSPEND BIT(31)
+#define PHYCLKRST_SSC_REFCLKSEL GENMASK(30, 23)
+#define PHYCLKRST_SSC_RANGE GENMASK(22, 21)
+#define PHYCLKRST_SSC_EN BIT(20)
+#define PHYCLKRST_REF_SSP_EN BIT(19)
+#define PHYCLKRST_REF_CLKDIV2 BIT(18)
+#define PHYCLKRST_MPLL_MULTIPLIER GENMASK(17, 11)
+#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF 0x19
+#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF 0x32
+#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF 0x68
+#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF 0x7d
+#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF 0x02
+#define PHYCLKRST_FSEL_PIPE GENMASK(10, 8)
+#define PHYCLKRST_FSEL_UTMI GENMASK(7, 5)
+#define PHYCLKRST_FSEL_PAD_100MHZ 0x27
+#define PHYCLKRST_FSEL_PAD_24MHZ 0x2a
+#define PHYCLKRST_FSEL_PAD_20MHZ 0x31
+#define PHYCLKRST_FSEL_PAD_19_2MHZ 0x38
+#define PHYCLKRST_RETENABLEN BIT(4)
+#define PHYCLKRST_REFCLKSEL GENMASK(3, 2)
+#define PHYCLKRST_REFCLKSEL_PAD_REFCLK 0x2
+#define PHYCLKRST_REFCLKSEL_EXT_REFCLK 0x3
+#define PHYCLKRST_PORTRESET BIT(1)
+#define PHYCLKRST_COMMONONN BIT(0)
+
+#define EXYNOS5_DRD_PHYPARAM0 0x1c
+#define PHYPARAM0_REF_USE_PAD BIT(31)
+#define PHYPARAM0_REF_LOSLEVEL GENMASK(30, 26)
+#define PHYPARAM0_REF_LOSLEVEL_VAL 0x9
+#define PHYPARAM0_TXVREFTUNE GENMASK(25, 22)
+#define PHYPARAM0_TXRISETUNE GENMASK(21, 20)
+#define PHYPARAM0_TXRESTUNE GENMASK(19, 18)
+#define PHYPARAM0_TXPREEMPPULSETUNE BIT(17)
+#define PHYPARAM0_TXPREEMPAMPTUNE GENMASK(16, 15)
+#define PHYPARAM0_TXHSXVTUNE GENMASK(14, 13)
+#define PHYPARAM0_TXFSLSTUNE GENMASK(12, 9)
+#define PHYPARAM0_SQRXTUNE GENMASK(8, 6)
+#define PHYPARAM0_OTGTUNE GENMASK(5, 3)
+#define PHYPARAM0_COMPDISTUNE GENMASK(2, 0)
+
+#define EXYNOS5_DRD_LINKPORT 0x44
+#define LINKPORT_HOST_U3_PORT_DISABLE BIT(8)
+#define LINKPORT_HOST_U2_PORT_DISABLE BIT(7)
+#define LINKPORT_HOST_PORT_OVCR_U3 BIT(5)
+#define LINKPORT_HOST_PORT_OVCR_U2 BIT(4)
+#define LINKPORT_HOST_PORT_OVCR_U3_SEL BIT(3)
+#define LINKPORT_HOST_PORT_OVCR_U2_SEL BIT(2)
+
+/* Exynos7870: USB DRD PHY registers */
+#define EXYNOS7870_DRD_HSPHYCTRL 0x54
+#define HSPHYCTRL_PHYSWRSTALL BIT(31)
+#define HSPHYCTRL_SIDDQ BIT(6)
+#define HSPHYCTRL_PHYSWRST BIT(0)
+
+#define EXYNOS7870_DRD_HSPHYPLLTUNE 0x70
+#define HSPHYPLLTUNE_PLL_B_TUNE BIT(6)
+#define HSPHYPLLTUNE_PLL_I_TUNE GENMASK(5, 4)
+#define HSPHYPLLTUNE_PLL_P_TUNE GENMASK(3, 0)
+
/* Exynos850: USB DRD PHY registers */
#define EXYNOS850_DRD_LINKCTRL 0x04
#define LINKCTRL_FORCE_QACT BIT(8)
@@ -66,6 +149,11 @@
#define KHZ 1000
#define MHZ (KHZ * KHZ)
+enum exynos_usbdrd_phy_variant {
+ EXYNOS7870_USBDRD_PHY,
+ EXYNOS850_USBDRD_PHY,
+};
+
/**
* struct exynos_usbdrd_phy - driver data for Exynos USB PHY
* @reg_phy: USB PHY controller register memory base
@@ -73,6 +161,7 @@
* @core_clk: core clock for phy (ref clock)
* @reg_pmu: regmap for PMU block
* @extrefclk: frequency select settings when using 'separate reference clocks'
+ * @variant: ID to uniquely distinguish USB PHY variant
*/
struct exynos_usbdrd_phy {
void __iomem *reg_phy;
@@ -80,18 +169,23 @@ struct exynos_usbdrd_phy {
struct clk *core_clk;
struct regmap *reg_pmu;
u32 extrefclk;
+ enum exynos_usbdrd_phy_variant variant;
};
-static void exynos_usbdrd_phy_isol(struct regmap *reg_pmu, bool isolate)
+static void exynos_usbdrd_phy_isol(struct exynos_usbdrd_phy *phy_drd,
+ bool isolate)
{
- unsigned int val;
+ unsigned int mask = EXYNOS_PHY_ENABLE, val;
- if (!reg_pmu)
+ if (!phy_drd->reg_pmu)
return;
- val = isolate ? 0 : EXYNOS_PHY_ENABLE;
- regmap_update_bits(reg_pmu, EXYNOS_USBDRD_PHY_CONTROL,
- EXYNOS_PHY_ENABLE, val);
+ if (phy_drd->variant == EXYNOS7870_USBDRD_PHY)
+ mask = EXYNOS7870_PHY_ENABLE;
+
+ val = isolate ? 0 : mask;
+ regmap_update_bits(phy_drd->reg_pmu, EXYNOS_USBDRD_PHY_CONTROL,
+ mask, val);
}
/*
@@ -132,6 +226,111 @@ static unsigned int exynos_rate_to_clk(unsigned long rate, u32 *reg)
return 0;
}
+static void exynos7870_usbdrd_utmi_init(struct phy *phy)
+{
+ struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev);
+ void __iomem *regs_base = phy_drd->reg_phy;
+ u32 reg;
+
+ reg = readl(regs_base + EXYNOS5_DRD_PHYCLKRST);
+ /* Use PADREFCLK as ref clock */
+ reg &= ~PHYCLKRST_REFCLKSEL;
+ reg |= FIELD_PREP(PHYCLKRST_REFCLKSEL, PHYCLKRST_REFCLKSEL_PAD_REFCLK);
+ /* Select ref clock rate */
+ reg &= ~PHYCLKRST_FSEL_UTMI;
+ reg &= ~PHYCLKRST_FSEL_PIPE;
+ reg |= FIELD_PREP(PHYCLKRST_FSEL_UTMI, phy_drd->extrefclk);
+ /* Enable suspend and reset the port */
+ reg |= PHYCLKRST_EN_UTMISUSPEND;
+ reg |= PHYCLKRST_COMMONONN;
+ reg |= PHYCLKRST_PORTRESET;
+ writel(reg, regs_base + EXYNOS5_DRD_PHYCLKRST);
+ udelay(10);
+
+ /* Clear the port reset bit */
+ reg &= ~PHYCLKRST_PORTRESET;
+ writel(reg, regs_base + EXYNOS5_DRD_PHYCLKRST);
+
+ /* Change PHY PLL tune value */
+ reg = readl(regs_base + EXYNOS7870_DRD_HSPHYPLLTUNE);
+ if (phy_drd->extrefclk == EXYNOS5_FSEL_24MHZ)
+ reg |= HSPHYPLLTUNE_PLL_B_TUNE;
+ else
+ reg &= ~HSPHYPLLTUNE_PLL_B_TUNE;
+ reg &= ~HSPHYPLLTUNE_PLL_P_TUNE;
+ reg |= FIELD_PREP(HSPHYPLLTUNE_PLL_P_TUNE, 14);
+ writel(reg, regs_base + EXYNOS7870_DRD_HSPHYPLLTUNE);
+
+ /* High-Speed PHY control */
+ reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+ reg &= ~HSPHYCTRL_SIDDQ;
+ reg &= ~HSPHYCTRL_PHYSWRST;
+ reg &= ~HSPHYCTRL_PHYSWRSTALL;
+ writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+ udelay(500);
+
+ reg = readl(regs_base + EXYNOS5_DRD_LINKSYSTEM);
+ /*
+ * Setting the Frame length Adj value[6:1] to default 0x20
+ * See xHCI 1.0 spec, 5.2.4
+ */
+ reg |= LINKSYSTEM_XHCI_VERSION_CONTROL;
+ reg &= ~LINKSYSTEM_FLADJ;
+ reg |= FIELD_PREP(LINKSYSTEM_FLADJ, 0x20);
+ /* Set VBUSVALID signal as the VBUS pad is not used */
+ reg |= LINKSYSTEM_FORCE_BVALID;
+ reg |= LINKSYSTEM_FORCE_VBUSVALID;
+ writel(reg, regs_base + EXYNOS5_DRD_LINKSYSTEM);
+
+ reg = readl(regs_base + EXYNOS5_DRD_PHYUTMI);
+ /* Release force_sleep & force_suspend */
+ reg &= ~PHYUTMI_FORCESLEEP;
+ reg &= ~PHYUTMI_FORCESUSPEND;
+ /* DP/DM pull down control */
+ reg &= ~PHYUTMI_DMPULLDOWN;
+ reg &= ~PHYUTMI_DPPULLDOWN;
+ reg &= ~PHYUTMI_DRVVBUS;
+ /* Set DP-pull up as the VBUS pad is not used */
+ reg |= PHYUTMI_VBUSVLDEXTSEL;
+ reg |= PHYUTMI_VBUSVLDEXT;
+ /* Disable OTG block and VBUS valid comparator */
+ reg |= PHYUTMI_OTGDISABLE;
+ writel(reg, regs_base + EXYNOS5_DRD_PHYUTMI);
+
+ /* Configure OVC IO usage */
+ reg = readl(regs_base + EXYNOS5_DRD_LINKPORT);
+ reg |= LINKPORT_HOST_PORT_OVCR_U3_SEL | LINKPORT_HOST_PORT_OVCR_U2_SEL;
+ writel(reg, regs_base + EXYNOS5_DRD_LINKPORT);
+
+ /* High-Speed PHY swrst */
+ reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+ reg |= HSPHYCTRL_PHYSWRST;
+ writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+ udelay(20);
+
+ /* Clear the PHY swrst bit */
+ reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+ reg &= ~HSPHYCTRL_PHYSWRST;
+ writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+
+ reg = readl(regs_base + EXYNOS5_DRD_PHYPARAM0);
+ reg &= ~(PHYPARAM0_TXVREFTUNE | PHYPARAM0_TXRISETUNE |
+ PHYPARAM0_TXRESTUNE | PHYPARAM0_TXPREEMPPULSETUNE |
+ PHYPARAM0_TXPREEMPAMPTUNE | PHYPARAM0_TXHSXVTUNE |
+ PHYPARAM0_TXFSLSTUNE | PHYPARAM0_SQRXTUNE |
+ PHYPARAM0_OTGTUNE | PHYPARAM0_COMPDISTUNE);
+ reg |= FIELD_PREP_CONST(PHYPARAM0_TXVREFTUNE, 14) |
+ FIELD_PREP_CONST(PHYPARAM0_TXRISETUNE, 1) |
+ FIELD_PREP_CONST(PHYPARAM0_TXRESTUNE, 3) |
+ FIELD_PREP_CONST(PHYPARAM0_TXPREEMPAMPTUNE, 0) |
+ FIELD_PREP_CONST(PHYPARAM0_TXHSXVTUNE, 0) |
+ FIELD_PREP_CONST(PHYPARAM0_TXFSLSTUNE, 3) |
+ FIELD_PREP_CONST(PHYPARAM0_SQRXTUNE, 6) |
+ FIELD_PREP_CONST(PHYPARAM0_OTGTUNE, 2) |
+ FIELD_PREP_CONST(PHYPARAM0_COMPDISTUNE, 3);
+ writel(reg, regs_base + EXYNOS5_DRD_PHYPARAM0);
+}
+
static void exynos850_usbdrd_utmi_init(struct phy *phy)
{
struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev);
@@ -219,6 +418,33 @@ static void exynos850_usbdrd_utmi_init(struct phy *phy)
writel(reg, regs_base + EXYNOS850_DRD_HSP);
}
+static void exynos7870_usbdrd_utmi_exit(struct phy *phy)
+{
+ struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev);
+ void __iomem *regs_base = phy_drd->reg_phy;
+ u32 reg;
+
+ /*
+ * Disable the VBUS signal and the ID pull-up resistor.
+ * Enable force-suspend and force-sleep modes.
+ */
+ reg = readl(regs_base + EXYNOS5_DRD_PHYUTMI);
+ reg &= ~(PHYUTMI_DRVVBUS | PHYUTMI_VBUSVLDEXT | PHYUTMI_VBUSVLDEXTSEL);
+ reg &= ~PHYUTMI_IDPULLUP;
+ reg |= PHYUTMI_FORCESUSPEND | PHYUTMI_FORCESLEEP;
+ writel(reg, regs_base + EXYNOS5_DRD_PHYUTMI);
+
+ /* Power down PHY analog blocks */
+ reg = readl(regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+ reg |= HSPHYCTRL_SIDDQ;
+ writel(reg, regs_base + EXYNOS7870_DRD_HSPHYCTRL);
+
+ /* Clear VBUSVALID signal as the VBUS pad is not used */
+ reg = readl(regs_base + EXYNOS5_DRD_LINKSYSTEM);
+ reg &= ~(LINKSYSTEM_FORCE_BVALID | LINKSYSTEM_FORCE_VBUSVALID);
+ writel(reg, regs_base + EXYNOS5_DRD_LINKSYSTEM);
+}
+
static void exynos850_usbdrd_utmi_exit(struct phy *phy)
{
struct exynos_usbdrd_phy *phy_drd = dev_get_priv(phy->dev);
@@ -254,7 +480,16 @@ static int exynos_usbdrd_phy_init(struct phy *phy)
if (ret)
return ret;
- exynos850_usbdrd_utmi_init(phy);
+ switch (phy_drd->variant) {
+ case EXYNOS7870_USBDRD_PHY:
+ exynos7870_usbdrd_utmi_init(phy);
+ break;
+ case EXYNOS850_USBDRD_PHY:
+ exynos850_usbdrd_utmi_init(phy);
+ break;
+ default:
+ dev_err(phy->dev, "Failed to recognize phy variant\n");
+ }
clk_disable_unprepare(phy_drd->clk);
@@ -270,7 +505,16 @@ static int exynos_usbdrd_phy_exit(struct phy *phy)
if (ret)
return ret;
- exynos850_usbdrd_utmi_exit(phy);
+ switch (phy_drd->variant) {
+ case EXYNOS7870_USBDRD_PHY:
+ exynos7870_usbdrd_utmi_exit(phy);
+ break;
+ case EXYNOS850_USBDRD_PHY:
+ exynos850_usbdrd_utmi_exit(phy);
+ break;
+ default:
+ dev_err(phy->dev, "Failed to recognize phy variant\n");
+ }
clk_disable_unprepare(phy_drd->clk);
@@ -289,7 +533,7 @@ static int exynos_usbdrd_phy_power_on(struct phy *phy)
return ret;
/* Power-on PHY */
- exynos_usbdrd_phy_isol(phy_drd->reg_pmu, false);
+ exynos_usbdrd_phy_isol(phy_drd, false);
return 0;
}
@@ -301,7 +545,7 @@ static int exynos_usbdrd_phy_power_off(struct phy *phy)
dev_dbg(phy->dev, "Request to power_off usbdrd_phy phy\n");
/* Power-off the PHY */
- exynos_usbdrd_phy_isol(phy_drd->reg_pmu, true);
+ exynos_usbdrd_phy_isol(phy_drd, true);
clk_disable_unprepare(phy_drd->core_clk);
@@ -359,6 +603,8 @@ static int exynos_usbdrd_phy_probe(struct udevice *dev)
return err;
}
+ phy_drd->variant = dev_get_driver_data(dev);
+
return 0;
}
@@ -371,7 +617,12 @@ static const struct phy_ops exynos_usbdrd_phy_ops = {
static const struct udevice_id exynos_usbdrd_phy_of_match[] = {
{
+ .compatible = "samsung,exynos7870-usbdrd-phy",
+ .data = EXYNOS7870_USBDRD_PHY,
+ },
+ {
.compatible = "samsung,exynos850-usbdrd-phy",
+ .data = EXYNOS850_USBDRD_PHY,
},
{ }
};
diff --git a/drivers/phy/phy-mtk-ufs.c b/drivers/phy/phy-mtk-ufs.c
new file mode 100644
index 00000000000..1eda3df858d
--- /dev/null
+++ b/drivers/phy/phy-mtk-ufs.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 MediaTek Inc.
+ * Author: Stanley Chu <[email protected]>
+ *
+ * Copyright (c) 2025, Igor Belwon <[email protected]>
+ */
+
+#include "dm/ofnode.h"
+#include "dm/read.h"
+#include <clk.h>
+#include <dm.h>
+#include <generic-phy.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+
+#include <dt-bindings/phy/phy.h>
+
+/* mphy register and offsets */
+#define MP_GLB_DIG_8C 0x008C
+#define FRC_PLL_ISO_EN BIT(8)
+#define PLL_ISO_EN BIT(9)
+#define FRC_FRC_PWR_ON BIT(10)
+#define PLL_PWR_ON BIT(11)
+
+#define MP_LN_DIG_RX_9C 0xA09C
+#define FSM_DIFZ_FRC BIT(18)
+
+#define MP_LN_DIG_RX_AC 0xA0AC
+#define FRC_RX_SQ_EN BIT(0)
+#define RX_SQ_EN BIT(1)
+
+#define MP_LN_RX_44 0xB044
+#define FRC_CDR_PWR_ON BIT(17)
+#define CDR_PWR_ON BIT(18)
+#define FRC_CDR_ISO_EN BIT(19)
+#define CDR_ISO_EN BIT(20)
+
+#define UFSPHY_CLKS_CNT 2
+
+struct mtk_ufs_phy {
+ struct udevice *dev;
+ void __iomem *mmio;
+
+ struct clk *unipro_clk;
+ struct clk *mp_clk;
+};
+
+static void ufs_mtk_phy_set_active(struct mtk_ufs_phy *phy)
+{
+ /* release DA_MP_PLL_PWR_ON */
+ setbits_le32(phy->mmio + MP_GLB_DIG_8C, PLL_PWR_ON);
+ clrbits_le32(phy->mmio + MP_GLB_DIG_8C, FRC_FRC_PWR_ON);
+
+ /* release DA_MP_PLL_ISO_EN */
+ clrbits_le32(phy->mmio + MP_GLB_DIG_8C, PLL_ISO_EN);
+ clrbits_le32(phy->mmio + MP_GLB_DIG_8C, FRC_PLL_ISO_EN);
+
+ /* release DA_MP_CDR_PWR_ON */
+ setbits_le32(phy->mmio + MP_LN_RX_44, CDR_PWR_ON);
+ clrbits_le32(phy->mmio + MP_LN_RX_44, FRC_CDR_PWR_ON);
+
+ /* release DA_MP_CDR_ISO_EN */
+ clrbits_le32(phy->mmio + MP_LN_RX_44, CDR_ISO_EN);
+ clrbits_le32(phy->mmio + MP_LN_RX_44, FRC_CDR_ISO_EN);
+
+ /* release DA_MP_RX0_SQ_EN */
+ setbits_le32(phy->mmio + MP_LN_DIG_RX_AC, RX_SQ_EN);
+ clrbits_le32(phy->mmio + MP_LN_DIG_RX_AC, FRC_RX_SQ_EN);
+
+ /* delay 1us to wait DIFZ stable */
+ udelay(1);
+
+ /* release DIFZ */
+ clrbits_le32(phy->mmio + MP_LN_DIG_RX_9C, FSM_DIFZ_FRC);
+}
+
+static int mtk_phy_power_on(struct phy *phy)
+{
+ struct mtk_ufs_phy *ufs_phy = dev_get_priv(phy->dev);
+ int ret;
+
+ ret = clk_enable(ufs_phy->mp_clk);
+ if (ret < 0) {
+ dev_err(phy->dev, "failed to enable mp_clk\n");
+ return ret;
+ }
+
+ ret = clk_enable(ufs_phy->unipro_clk);
+ if (ret < 0) {
+ dev_err(phy->dev, "failed to enable unipro_clk %d\n", ret);
+ clk_disable(ufs_phy->unipro_clk);
+ return ret;
+ }
+
+ ufs_mtk_phy_set_active(ufs_phy);
+
+ return 0;
+}
+
+static int mtk_phy_power_off(struct phy *phy)
+{
+ struct mtk_ufs_phy *ufs_phy = dev_get_priv(phy->dev);
+
+ /* Set PHY to Deep Hibernate mode */
+ setbits_le32(ufs_phy->mmio + MP_LN_DIG_RX_9C, FSM_DIFZ_FRC);
+
+ /* force DA_MP_RX0_SQ_EN */
+ setbits_le32(ufs_phy->mmio + MP_LN_DIG_RX_AC, FRC_RX_SQ_EN);
+ clrbits_le32(ufs_phy->mmio + MP_LN_DIG_RX_AC, RX_SQ_EN);
+
+ /* force DA_MP_CDR_ISO_EN */
+ setbits_le32(ufs_phy->mmio + MP_LN_RX_44, FRC_CDR_ISO_EN);
+ setbits_le32(ufs_phy->mmio + MP_LN_RX_44, CDR_ISO_EN);
+
+ /* force DA_MP_CDR_PWR_ON */
+ setbits_le32(ufs_phy->mmio + MP_LN_RX_44, FRC_CDR_PWR_ON);
+ clrbits_le32(ufs_phy->mmio + MP_LN_RX_44, CDR_PWR_ON);
+
+ /* force DA_MP_PLL_ISO_EN */
+ setbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, FRC_PLL_ISO_EN);
+ setbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, PLL_ISO_EN);
+
+ /* force DA_MP_PLL_PWR_ON */
+ setbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, FRC_FRC_PWR_ON);
+ clrbits_le32(ufs_phy->mmio + MP_GLB_DIG_8C, PLL_PWR_ON);
+
+ return 0;
+}
+
+static const struct phy_ops mtk_ufs_phy_ops = {
+ .power_on = mtk_phy_power_on,
+ .power_off = mtk_phy_power_off,
+};
+
+static int mtk_ufs_phy_probe(struct udevice *dev)
+{
+ struct mtk_ufs_phy *phy = dev_get_priv(dev);
+ fdt_addr_t addr;
+ int ret;
+
+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return -ENOMEM;
+
+ addr = dev_read_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -ENOMEM;
+
+ phy->dev = dev;
+ phy->mmio = map_sysmem(addr, 0);
+
+ phy->mp_clk = devm_clk_get(dev, "mp");
+ if (IS_ERR(phy->mp_clk)) {
+ ret = PTR_ERR(phy->mp_clk);
+ dev_err(dev, "Failed to get mp clock (ret=%d)\n", ret);
+ return ret;
+ }
+
+ phy->unipro_clk = devm_clk_get(dev, "unipro");
+ if (IS_ERR(phy->unipro_clk)) {
+ ret = PTR_ERR(phy->unipro_clk);
+ dev_err(dev, "Failed to get unipro clock (ret=%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id mtk_ufs_phy_id_table[] = {
+ {.compatible = "mediatek,mt8183-ufsphy"},
+ {},
+};
+
+U_BOOT_DRIVER(mtk_ufs_phy) = {
+ .name = "mtk-ufs_phy",
+ .id = UCLASS_PHY,
+ .of_match = mtk_ufs_phy_id_table,
+ .ops = &mtk_ufs_phy_ops,
+ .probe = mtk_ufs_phy_probe,
+ .priv_auto = sizeof(struct mtk_ufs_phy),
+};
diff --git a/drivers/pinctrl/pinctrl-adi-adsp.c b/drivers/pinctrl/pinctrl-adi-adsp.c
index debf434212d..e39f88c8b26 100644
--- a/drivers/pinctrl/pinctrl-adi-adsp.c
+++ b/drivers/pinctrl/pinctrl-adi-adsp.c
@@ -2,10 +2,9 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Author: Greg Malysa <[email protected]>
- * Additional Contact: Nathan Barrett-Morrison <[email protected]>
*
* dm pinctrl implementation for ADI ADSP SoCs
*
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c
index fbf0271f08a..1758f9a909c 100644
--- a/drivers/pinctrl/pinctrl_stm32.c
+++ b/drivers/pinctrl/pinctrl_stm32.c
@@ -11,6 +11,7 @@
#include <malloc.h>
#include <asm/gpio.h>
#include <asm/io.h>
+#include <dm/device-internal.h>
#include <dm/device_compat.h>
#include <dm/lists.h>
#include <dm/pinctrl.h>
@@ -27,6 +28,7 @@
#define PUPD_MASK 3
#define OTYPE_MSK 1
#define AFR_MASK 0xF
+#define SECCFG_MSK 1
struct stm32_pinctrl_priv {
struct hwspinlock hws;
@@ -39,7 +41,12 @@ struct stm32_gpio_bank {
struct list_head list;
};
+struct stm32_pinctrl_data {
+ bool secure_control;
+};
+
#ifndef CONFIG_XPL_BUILD
+static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx);
static char pin_name[PINNAME_SIZE];
static const char * const pinmux_mode[GPIOF_COUNT] = {
@@ -216,6 +223,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
if (!gpio_dev)
return -ENODEV;
+ /* Check access protection */
+ if (stm32_pinctrl_get_access(gpio_dev, gpio_idx)) {
+ snprintf(buf, size, "NO ACCESS");
+ return 0;
+ }
+
mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label);
dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n",
selector, gpio_idx, mode);
@@ -252,6 +265,20 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev,
#endif
+static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx)
+{
+ struct stm32_gpio_priv *priv = dev_get_priv(gpio_dev);
+ struct stm32_gpio_regs *regs = priv->regs;
+ ulong drv_data = dev_get_driver_data(gpio_dev);
+
+ /* Deny request access if IO is secured */
+ if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) &&
+ ((readl(&regs->seccfgr) >> gpio_idx) & SECCFG_MSK))
+ return -EACCES;
+
+ return 0;
+}
+
static int stm32_pinctrl_probe(struct udevice *dev)
{
struct stm32_pinctrl_priv *priv = dev_get_priv(dev);
@@ -279,6 +306,14 @@ static int stm32_gpio_config(ofnode node,
int ret;
u32 index;
+ /* Check access protection */
+ ret = stm32_pinctrl_get_access(desc->dev, desc->offset);
+ if (ret) {
+ dev_err(desc->dev, "Failed to get secure IO %s %d @ %p\n",
+ uc_priv->bank_name, desc->offset, regs);
+ return ret;
+ }
+
if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 ||
ctl->pupd > 2 || ctl->speed > 3)
return -EINVAL;
@@ -414,8 +449,25 @@ static int stm32_pinctrl_bind(struct udevice *dev)
{
ofnode node;
const char *name;
+ struct driver *drv;
+ const struct stm32_pinctrl_data *drv_data;
+ ulong gpio_data = 0;
int ret;
+ drv = lists_driver_lookup_name("gpio_stm32");
+ if (!drv) {
+ debug("Cannot find driver 'gpio_stm32'\n");
+ return -ENOENT;
+ }
+
+ drv_data = (const struct stm32_pinctrl_data *)dev_get_driver_data(dev);
+ if (!drv_data) {
+ debug("Cannot find driver data\n");
+ return -EINVAL;
+ }
+ if (drv_data->secure_control)
+ gpio_data = STM32_GPIO_FLAG_SEC_CTRL;
+
dev_for_each_subnode(node, dev) {
dev_dbg(dev, "bind %s\n", ofnode_get_name(node));
@@ -431,8 +483,7 @@ static int stm32_pinctrl_bind(struct udevice *dev)
return -EINVAL;
/* Bind each gpio node */
- ret = device_bind_driver_to_node(dev, "gpio_stm32",
- name, node, NULL);
+ ret = device_bind_with_driver_data(dev, drv, name, gpio_data, node, NULL);
if (ret)
return ret;
@@ -495,17 +546,25 @@ static struct pinctrl_ops stm32_pinctrl_ops = {
#endif
};
+static const struct stm32_pinctrl_data stm32_pinctrl_no_sec = {
+ .secure_control = false,
+};
+
+static const struct stm32_pinctrl_data stm32_pinctrl_with_sec = {
+ .secure_control = true,
+};
+
static const struct udevice_id stm32_pinctrl_ids[] = {
- { .compatible = "st,stm32f429-pinctrl" },
- { .compatible = "st,stm32f469-pinctrl" },
- { .compatible = "st,stm32f746-pinctrl" },
- { .compatible = "st,stm32f769-pinctrl" },
- { .compatible = "st,stm32h743-pinctrl" },
- { .compatible = "st,stm32mp157-pinctrl" },
- { .compatible = "st,stm32mp157-z-pinctrl" },
- { .compatible = "st,stm32mp135-pinctrl" },
- { .compatible = "st,stm32mp257-pinctrl" },
- { .compatible = "st,stm32mp257-z-pinctrl" },
+ { .compatible = "st,stm32f429-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32f469-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32f746-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32f769-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32h743-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32mp157-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32mp157-z-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec },
+ { .compatible = "st,stm32mp135-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec },
+ { .compatible = "st,stm32mp257-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec },
+ { .compatible = "st,stm32mp257-z-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec },
{ }
};
diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c
index d9fa8ad4bd2..cea68945cbd 100644
--- a/drivers/power/domain/power-domain-uclass.c
+++ b/drivers/power/domain/power-domain-uclass.c
@@ -180,6 +180,9 @@ static int dev_power_domain_ctrl(struct udevice *dev, bool on)
struct power_domain pd;
int i, count, ret = 0;
+ if (!dev_has_ofnode(dev))
+ return 0;
+
count = dev_count_phandle_with_args(dev, "power-domains",
"#power-domain-cells", 0);
for (i = 0; i < count; i++) {
diff --git a/drivers/remoteproc/adi_sc5xx_rproc.c b/drivers/remoteproc/adi_sc5xx_rproc.c
index 86acd1b98c7..b96603263a5 100644
--- a/drivers/remoteproc/adi_sc5xx_rproc.c
+++ b/drivers/remoteproc/adi_sc5xx_rproc.c
@@ -2,10 +2,8 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
*
* Analog Devices SC5xx remoteproc driver for loading code onto SHARC cores
*/
diff --git a/drivers/reset/stm32/Kconfig b/drivers/reset/stm32/Kconfig
index fdd88a6bfae..1bafba516af 100644
--- a/drivers/reset/stm32/Kconfig
+++ b/drivers/reset/stm32/Kconfig
@@ -14,6 +14,13 @@ config RESET_STM32MP1
Support for reset controllers on STMicroelectronics STM32MP1 family SoCs.
This reset driver is compatible with STM32MP13 and STM32MP15 SoCs.
+config RESET_STM32MP21
+ bool "Enable the STM32MP21 reset"
+ default y if STM32MP21X
+ help
+ Support for reset controllers on STMicroelectronics STM32MP21 family SoCs.
+ This reset driver is compatible with STM32MP21 SoCs.
+
config RESET_STM32MP25
bool "Enable the STM32MP25 reset"
depends on STM32MP23X || STM32MP25X
diff --git a/drivers/reset/stm32/Makefile b/drivers/reset/stm32/Makefile
index c31ae524ba1..ac4d3c6fc8f 100644
--- a/drivers/reset/stm32/Makefile
+++ b/drivers/reset/stm32/Makefile
@@ -6,4 +6,5 @@ obj-y += stm32-reset-core.o
obj-$(CONFIG_RESET_STM32) += stm32-reset.o
obj-$(CONFIG_RESET_STM32MP1) += stm32-reset-mp1.o
+obj-$(CONFIG_RESET_STM32MP21) += stm32-reset-mp21.o
obj-$(CONFIG_RESET_STM32MP25) += stm32-reset-mp25.o
diff --git a/drivers/reset/stm32/stm32-reset-mp21.c b/drivers/reset/stm32/stm32-reset-mp21.c
new file mode 100644
index 00000000000..7d169d7582f
--- /dev/null
+++ b/drivers/reset/stm32/stm32-reset-mp21.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+/*
+ * Copyright (C) 2026, STMicroelectronics - All Rights Reserved
+ * Author(s): Gabriel Fernandez, <[email protected]> for STMicroelectronics.
+ */
+
+#include <dm.h>
+#include <stm32-reset-core.h>
+#include <stm32mp21_rcc.h>
+#include <dt-bindings/reset/st,stm32mp21-rcc.h>
+
+/* Reset clear offset for STM32MP RCC */
+#define RCC_CLR_OFFSET 0x4
+
+/* Timeout for deassert */
+#define STM32_DEASSERT_TIMEOUT_US 10000
+
+#define RESET(id, _offset, _bit_idx, _set_clr) \
+ [id] = &(struct stm32_reset_cfg){ \
+ .offset = (_offset), \
+ .bit_idx = (_bit_idx), \
+ .set_clr = (_set_clr), \
+ }
+
+static const struct stm32_reset_cfg *stm32mp21_reset[] = {
+ RESET(TIM1_R, RCC_TIM1CFGR, 0, 0),
+ RESET(TIM2_R, RCC_TIM2CFGR, 0, 0),
+ RESET(TIM3_R, RCC_TIM3CFGR, 0, 0),
+ RESET(TIM4_R, RCC_TIM4CFGR, 0, 0),
+ RESET(TIM5_R, RCC_TIM5CFGR, 0, 0),
+ RESET(TIM6_R, RCC_TIM6CFGR, 0, 0),
+ RESET(TIM7_R, RCC_TIM7CFGR, 0, 0),
+ RESET(TIM8_R, RCC_TIM8CFGR, 0, 0),
+ RESET(TIM10_R, RCC_TIM10CFGR, 0, 0),
+ RESET(TIM11_R, RCC_TIM11CFGR, 0, 0),
+ RESET(TIM12_R, RCC_TIM12CFGR, 0, 0),
+ RESET(TIM13_R, RCC_TIM13CFGR, 0, 0),
+ RESET(TIM14_R, RCC_TIM14CFGR, 0, 0),
+ RESET(TIM15_R, RCC_TIM15CFGR, 0, 0),
+ RESET(TIM16_R, RCC_TIM16CFGR, 0, 0),
+ RESET(TIM17_R, RCC_TIM17CFGR, 0, 0),
+ RESET(LPTIM1_R, RCC_LPTIM1CFGR, 0, 0),
+ RESET(LPTIM2_R, RCC_LPTIM2CFGR, 0, 0),
+ RESET(LPTIM3_R, RCC_LPTIM3CFGR, 0, 0),
+ RESET(LPTIM4_R, RCC_LPTIM4CFGR, 0, 0),
+ RESET(LPTIM5_R, RCC_LPTIM5CFGR, 0, 0),
+ RESET(SPI1_R, RCC_SPI1CFGR, 0, 0),
+ RESET(SPI2_R, RCC_SPI2CFGR, 0, 0),
+ RESET(SPI3_R, RCC_SPI3CFGR, 0, 0),
+ RESET(SPI4_R, RCC_SPI4CFGR, 0, 0),
+ RESET(SPI5_R, RCC_SPI5CFGR, 0, 0),
+ RESET(SPI6_R, RCC_SPI6CFGR, 0, 0),
+ RESET(SPDIFRX_R, RCC_SPDIFRXCFGR, 0, 0),
+ RESET(USART1_R, RCC_USART1CFGR, 0, 0),
+ RESET(USART2_R, RCC_USART2CFGR, 0, 0),
+ RESET(USART3_R, RCC_USART3CFGR, 0, 0),
+ RESET(UART4_R, RCC_UART4CFGR, 0, 0),
+ RESET(UART5_R, RCC_UART5CFGR, 0, 0),
+ RESET(USART6_R, RCC_USART6CFGR, 0, 0),
+ RESET(UART7_R, RCC_UART7CFGR, 0, 0),
+ RESET(LPUART1_R, RCC_LPUART1CFGR, 0, 0),
+ RESET(I2C1_R, RCC_I2C1CFGR, 0, 0),
+ RESET(I2C2_R, RCC_I2C2CFGR, 0, 0),
+ RESET(I2C3_R, RCC_I2C3CFGR, 0, 0),
+ RESET(SAI1_R, RCC_SAI1CFGR, 0, 0),
+ RESET(SAI2_R, RCC_SAI2CFGR, 0, 0),
+ RESET(SAI3_R, RCC_SAI3CFGR, 0, 0),
+ RESET(SAI4_R, RCC_SAI4CFGR, 0, 0),
+ RESET(MDF1_R, RCC_MDF1CFGR, 0, 0),
+ RESET(FDCAN_R, RCC_FDCANCFGR, 0, 0),
+ RESET(HDP_R, RCC_HDPCFGR, 0, 0),
+ RESET(ADC1_R, RCC_ADC1CFGR, 0, 0),
+ RESET(ADC2_R, RCC_ADC2CFGR, 0, 0),
+ RESET(ETH1_R, RCC_ETH1CFGR, 0, 0),
+ RESET(ETH2_R, RCC_ETH2CFGR, 0, 0),
+ RESET(USBH_R, RCC_USBHCFGR, 0, 0),
+ RESET(USB2PHY1_R, RCC_USB2PHY1CFGR, 0, 0),
+ RESET(USB2PHY2_R, RCC_USB2PHY2CFGR, 0, 0),
+ RESET(SDMMC1_R, RCC_SDMMC1CFGR, 0, 0),
+ RESET(SDMMC1DLL_R, RCC_SDMMC1CFGR, 16, 0),
+ RESET(SDMMC2_R, RCC_SDMMC2CFGR, 0, 0),
+ RESET(SDMMC2DLL_R, RCC_SDMMC2CFGR, 16, 0),
+ RESET(SDMMC3_R, RCC_SDMMC3CFGR, 0, 0),
+ RESET(SDMMC3DLL_R, RCC_SDMMC3CFGR, 16, 0),
+ RESET(LTDC_R, RCC_LTDCCFGR, 0, 0),
+ RESET(CSI_R, RCC_CSICFGR, 0, 0),
+ RESET(DCMIPP_R, RCC_DCMIPPCFGR, 0, 0),
+ RESET(DCMIPSSI_R, RCC_DCMIPSSICFGR, 0, 0),
+ RESET(WWDG1_R, RCC_WWDG1CFGR, 0, 0),
+ RESET(VREF_R, RCC_VREFCFGR, 0, 0),
+ RESET(DTS_R, RCC_DTSCFGR, 0, 0),
+ RESET(CRC_R, RCC_CRCCFGR, 0, 0),
+ RESET(SERC_R, RCC_SERCCFGR, 0, 0),
+ RESET(I3C1_R, RCC_I3C1CFGR, 0, 0),
+ RESET(I3C2_R, RCC_I3C2CFGR, 0, 0),
+ RESET(IWDG2_KER_R, RCC_IWDGC1CFGSETR, 18, 1),
+ RESET(IWDG4_KER_R, RCC_IWDGC2CFGSETR, 18, 1),
+ RESET(RNG1_R, RCC_RNG1CFGR, 0, 0),
+ RESET(RNG2_R, RCC_RNG2CFGR, 0, 0),
+ RESET(PKA_R, RCC_PKACFGR, 0, 0),
+ RESET(SAES_R, RCC_SAESCFGR, 0, 0),
+ RESET(HASH1_R, RCC_HASH1CFGR, 0, 0),
+ RESET(HASH2_R, RCC_HASH2CFGR, 0, 0),
+ RESET(CRYP1_R, RCC_CRYP1CFGR, 0, 0),
+ RESET(CRYP2_R, RCC_CRYP2CFGR, 0, 0),
+ RESET(OTG_R, RCC_OTGCFGR, 0, 0),
+};
+
+static const struct stm32_reset_cfg *stm32_get_reset_line(struct reset_ctl *reset_ctl)
+{
+ unsigned long id = reset_ctl->id;
+
+ if (id < ARRAY_SIZE(stm32mp21_reset))
+ return stm32mp21_reset[id];
+
+ return NULL;
+}
+
+static const struct stm32_reset_data stm32mp21_reset_data = {
+ .get_reset_line = stm32_get_reset_line,
+ .clear_offset = RCC_CLR_OFFSET,
+ .reset_us = STM32_DEASSERT_TIMEOUT_US,
+};
+
+static int stm32_reset_probe(struct udevice *dev)
+{
+ return stm32_reset_core_probe(dev, &stm32mp21_reset_data);
+}
+
+U_BOOT_DRIVER(stm32mp21_rcc_reset) = {
+ .name = "stm32mp21_reset",
+ .id = UCLASS_RESET,
+ .probe = stm32_reset_probe,
+ .priv_auto = sizeof(struct stm32_reset_priv),
+ .ops = &stm32_reset_ops,
+};
diff --git a/drivers/serial/serial_adi_uart4.c b/drivers/serial/serial_adi_uart4.c
index 784310ba231..8039ee4d1d8 100644
--- a/drivers/serial/serial_adi_uart4.c
+++ b/drivers/serial/serial_adi_uart4.c
@@ -2,12 +2,10 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Converted to driver model by Nathan Barrett-Morrison
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
*
*/
diff --git a/drivers/spi/adi_spi3.c b/drivers/spi/adi_spi3.c
index 2125d25561a..bc66dfbfdd6 100644
--- a/drivers/spi/adi_spi3.c
+++ b/drivers/spi/adi_spi3.c
@@ -2,14 +2,10 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Converted to driver model by Nathan Barrett-Morrison
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
- * Contact: Ian Roberts <[email protected]>
- * Contact: Piotr Wojtaszczyk <[email protected]>
*
*/
diff --git a/drivers/timer/adi_sc5xx_timer.c b/drivers/timer/adi_sc5xx_timer.c
index 11c098434a8..d9aef3da11e 100644
--- a/drivers/timer/adi_sc5xx_timer.c
+++ b/drivers/timer/adi_sc5xx_timer.c
@@ -2,12 +2,11 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Converted to driver model by Nathan Barrett-Morrison
*
* Author: Greg Malysa <[email protected]>
- * Additional Contact: Nathan Barrett-Morrison <[email protected]>
*
* dm timer implementation for ADI ADSP-SC5xx SoCs
*
diff --git a/drivers/ufs/cdns-platform.c b/drivers/ufs/cdns-platform.c
index 87d9c5bad79..40883a187b0 100644
--- a/drivers/ufs/cdns-platform.c
+++ b/drivers/ufs/cdns-platform.c
@@ -7,7 +7,6 @@
#include <clk.h>
#include <dm.h>
-#include <ufs.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
diff --git a/drivers/ufs/ufs-amd-versal2.c b/drivers/ufs/ufs-amd-versal2.c
index dd62c9819ba..6c949b2ca76 100644
--- a/drivers/ufs/ufs-amd-versal2.c
+++ b/drivers/ufs/ufs-amd-versal2.c
@@ -5,7 +5,6 @@
#include <clk.h>
#include <dm.h>
-#include <ufs.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <zynqmp_firmware.h>
diff --git a/drivers/ufs/ufs-pci.c b/drivers/ufs/ufs-pci.c
index 5b9c72a695d..e1e010d027c 100644
--- a/drivers/ufs/ufs-pci.c
+++ b/drivers/ufs/ufs-pci.c
@@ -7,7 +7,6 @@
#include <dm.h>
#include <errno.h>
#include <pci.h>
-#include <ufs.h>
#include <dm/device_compat.h>
#include "ufs.h"
diff --git a/drivers/ufs/ufs-qcom.c b/drivers/ufs/ufs-qcom.c
index ee43958d5d8..dc40ee62daf 100644
--- a/drivers/ufs/ufs-qcom.c
+++ b/drivers/ufs/ufs-qcom.c
@@ -14,7 +14,6 @@
#include <dm.h>
#include <dm/device_compat.h>
#include <generic-phy.h>
-#include <ufs.h>
#include <asm/gpio.h>
#include <interconnect.h>
diff --git a/drivers/ufs/ufs-renesas-rcar-gen5.c b/drivers/ufs/ufs-renesas-rcar-gen5.c
index cc53e91449c..a21ae3f390e 100644
--- a/drivers/ufs/ufs-renesas-rcar-gen5.c
+++ b/drivers/ufs/ufs-renesas-rcar-gen5.c
@@ -7,7 +7,6 @@
#include <clk.h>
#include <dm.h>
-#include <ufs.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/iopoll.h>
diff --git a/drivers/ufs/ufs-renesas.c b/drivers/ufs/ufs-renesas.c
index 5652309911e..a206e3c6d58 100644
--- a/drivers/ufs/ufs-renesas.c
+++ b/drivers/ufs/ufs-renesas.c
@@ -7,7 +7,6 @@
#include <clk.h>
#include <dm.h>
-#include <ufs.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
diff --git a/drivers/ufs/ufs-rockchip.c b/drivers/ufs/ufs-rockchip.c
index 0384244387d..643a6ffb9bc 100644
--- a/drivers/ufs/ufs-rockchip.c
+++ b/drivers/ufs/ufs-rockchip.c
@@ -13,7 +13,6 @@
#include <linux/err.h>
#include <linux/ioport.h>
#include <reset.h>
-#include <ufs.h>
#include "ufs.h"
#include "unipro.h"
diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c
index 3c8e4299259..7a80a9d5664 100644
--- a/drivers/ufs/ufs-uclass.c
+++ b/drivers/ufs/ufs-uclass.c
@@ -917,11 +917,13 @@ static int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
enabled_intr_status = intr_status & hba->intr_mask;
ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
- if (get_timer(start) > QUERY_REQ_TIMEOUT) {
- dev_err(hba->dev,
- "Timedout waiting for UTP response\n");
-
- return -ETIMEDOUT;
+ if (hba->max_pwr_info.info.pwr_rx != SLOWAUTO_MODE &&
+ hba->max_pwr_info.info.pwr_tx != SLOWAUTO_MODE) {
+ if (get_timer(start) > QUERY_REQ_TIMEOUT) {
+ dev_err(hba->dev,
+ "Timedout waiting for UTP response\n");
+ return -ETIMEDOUT;
+ }
}
if (enabled_intr_status & UFSHCD_ERROR_MASK) {
diff --git a/drivers/ufs/ufshcd-dwc.c b/drivers/ufs/ufshcd-dwc.c
index 3f62e59a060..98422d742a0 100644
--- a/drivers/ufs/ufshcd-dwc.c
+++ b/drivers/ufs/ufshcd-dwc.c
@@ -7,7 +7,6 @@
*/
#include <clk.h>
#include <dm.h>
-#include <ufs.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
diff --git a/drivers/usb/musb-new/sc5xx.c b/drivers/usb/musb-new/sc5xx.c
index 16201480b43..991846818a2 100644
--- a/drivers/usb/musb-new/sc5xx.c
+++ b/drivers/usb/musb-new/sc5xx.c
@@ -4,7 +4,7 @@
*
* ADI SC5XX MUSB "glue layer"
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Loosely ported from Linux driver:
* Author: Nathan Barrett-Morrison <[email protected]>
diff --git a/drivers/video/exynos/exynos_fb.c b/drivers/video/exynos/exynos_fb.c
index 0407a3f51b0..1cc1bd92e57 100644
--- a/drivers/video/exynos/exynos_fb.c
+++ b/drivers/video/exynos/exynos_fb.c
@@ -350,7 +350,7 @@ void exynos_fimd_window_off(struct exynos_fb_priv *priv, unsigned int win_id)
void exynos_fimd_disable_sysmmu(void)
{
u32 *sysmmufimd;
- unsigned int node;
+ int node;
int node_list[2];
int count;
int i;
diff --git a/drivers/video/nexell/soc/s5pxx18_soc_mlc.c b/drivers/video/nexell/soc/s5pxx18_soc_mlc.c
index c8cf833f308..2c8348bf633 100644
--- a/drivers/video/nexell/soc/s5pxx18_soc_mlc.c
+++ b/drivers/video/nexell/soc/s5pxx18_soc_mlc.c
@@ -1641,8 +1641,6 @@ void nx_mlc_set_layer_alpha256(u32 module_index, u32 layer, u32 alpha)
u32 register_data;
register struct nx_mlc_register_set *pregister;
- if (alpha < 0)
- alpha = 0;
if (alpha > 255)
alpha = 255;
diff --git a/drivers/video/stm32/stm32_dsi.c b/drivers/video/stm32/stm32_dsi.c
index 438ed41e8d5..65a91f5cff7 100644
--- a/drivers/video/stm32/stm32_dsi.c
+++ b/drivers/video/stm32/stm32_dsi.c
@@ -84,42 +84,48 @@ enum dsi_color {
/* Timeout for regulator on/off, pll lock/unlock & fifo empty */
#define TIMEOUT_US 200000
-struct stm32_dsi_priv {
+struct stm32_dsi_plat {
struct mipi_dsi_device device;
void __iomem *base;
struct udevice *panel;
+ struct udevice *vdd_reg;
+ struct udevice *dsi_host;
+ struct reset_ctl rst;
+ struct clk pclk;
+ struct clk refclk;
+};
+
+struct stm32_dsi_priv {
u32 pllref_clk;
u32 hw_version;
int lane_min_kbps;
int lane_max_kbps;
- struct udevice *vdd_reg;
- struct udevice *dsi_host;
};
-static inline void dsi_write(struct stm32_dsi_priv *dsi, u32 reg, u32 val)
+static inline void dsi_write(void __iomem *base, u32 reg, u32 val)
{
- writel(val, dsi->base + reg);
+ writel(val, base + reg);
}
-static inline u32 dsi_read(struct stm32_dsi_priv *dsi, u32 reg)
+static inline u32 dsi_read(void __iomem *base, u32 reg)
{
- return readl(dsi->base + reg);
+ return readl(base + reg);
}
-static inline void dsi_set(struct stm32_dsi_priv *dsi, u32 reg, u32 mask)
+static inline void dsi_set(void __iomem *base, u32 reg, u32 mask)
{
- dsi_write(dsi, reg, dsi_read(dsi, reg) | mask);
+ dsi_write(base, reg, dsi_read(base, reg) | mask);
}
-static inline void dsi_clear(struct stm32_dsi_priv *dsi, u32 reg, u32 mask)
+static inline void dsi_clear(void __iomem *base, u32 reg, u32 mask)
{
- dsi_write(dsi, reg, dsi_read(dsi, reg) & ~mask);
+ dsi_write(base, reg, dsi_read(base, reg) & ~mask);
}
-static inline void dsi_update_bits(struct stm32_dsi_priv *dsi, u32 reg,
+static inline void dsi_update_bits(void __iomem *base, u32 reg,
u32 mask, u32 val)
{
- dsi_write(dsi, reg, (dsi_read(dsi, reg) & ~mask) | val);
+ dsi_write(base, reg, (dsi_read(base, reg) & ~mask) | val);
}
static enum dsi_color dsi_color_from_mipi(u32 fmt)
@@ -210,14 +216,14 @@ static int dsi_phy_init(void *priv_data)
{
struct mipi_dsi_device *device = priv_data;
struct udevice *dev = device->dev;
- struct stm32_dsi_priv *dsi = dev_get_priv(dev);
+ struct stm32_dsi_plat *dsi = dev_get_plat(dev);
u32 val;
int ret;
dev_dbg(dev, "Initialize DSI physical layer\n");
/* Enable the regulator */
- dsi_set(dsi, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
+ dsi_set(dsi->base, DSI_WRPCR, WRPCR_REGEN | WRPCR_BGREN);
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_RRS,
TIMEOUT_US);
if (ret) {
@@ -226,7 +232,7 @@ static int dsi_phy_init(void *priv_data)
}
/* Enable the DSI PLL & wait for its lock */
- dsi_set(dsi, DSI_WRPCR, WRPCR_PLLEN);
+ dsi_set(dsi->base, DSI_WRPCR, WRPCR_PLLEN);
ret = readl_poll_timeout(dsi->base + DSI_WISR, val, val & WISR_PLLLS,
TIMEOUT_US);
if (ret) {
@@ -241,7 +247,7 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags)
{
struct mipi_dsi_device *device = priv_data;
struct udevice *dev = device->dev;
- struct stm32_dsi_priv *dsi = dev_get_priv(dev);
+ struct stm32_dsi_plat *dsi = dev_get_plat(dev);
dev_dbg(dev, "Set mode %p enable %ld\n", dsi,
mode_flags & MIPI_DSI_MODE_VIDEO);
@@ -256,9 +262,9 @@ static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags)
*/
if (mode_flags & MIPI_DSI_MODE_VIDEO)
- dsi_set(dsi, DSI_WCR, WCR_DSIEN);
+ dsi_set(dsi->base, DSI_WCR, WCR_DSIEN);
else
- dsi_clear(dsi, DSI_WCR, WCR_DSIEN);
+ dsi_clear(dsi->base, DSI_WCR, WCR_DSIEN);
}
static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings,
@@ -266,32 +272,33 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings,
{
struct mipi_dsi_device *device = priv_data;
struct udevice *dev = device->dev;
- struct stm32_dsi_priv *dsi = dev_get_priv(dev);
+ struct stm32_dsi_plat *plat = dev_get_plat(dev);
+ struct stm32_dsi_priv *priv = dev_get_priv(dev);
int idf, ndiv, odf, pll_in_khz, pll_out_khz;
int ret, bpp;
u32 val;
/* Update lane capabilities according to hw version */
- dsi->lane_min_kbps = LANE_MIN_KBPS;
- dsi->lane_max_kbps = LANE_MAX_KBPS;
- if (dsi->hw_version == HWVER_131) {
- dsi->lane_min_kbps *= 2;
- dsi->lane_max_kbps *= 2;
+ priv->lane_min_kbps = LANE_MIN_KBPS;
+ priv->lane_max_kbps = LANE_MAX_KBPS;
+ if (priv->hw_version == HWVER_131) {
+ priv->lane_min_kbps *= 2;
+ priv->lane_max_kbps *= 2;
}
- pll_in_khz = dsi->pllref_clk / 1000;
+ pll_in_khz = priv->pllref_clk / 1000;
/* Compute requested pll out */
bpp = mipi_dsi_pixel_format_to_bpp(format);
pll_out_khz = (timings->pixelclock.typ / 1000) * bpp / lanes;
/* Add 20% to pll out to be higher than pixel bw (burst mode only) */
pll_out_khz = (pll_out_khz * 12) / 10;
- if (pll_out_khz > dsi->lane_max_kbps) {
- pll_out_khz = dsi->lane_max_kbps;
+ if (pll_out_khz > priv->lane_max_kbps) {
+ pll_out_khz = priv->lane_max_kbps;
dev_warn(dev, "Warning max phy mbps is used\n");
}
- if (pll_out_khz < dsi->lane_min_kbps) {
- pll_out_khz = dsi->lane_min_kbps;
+ if (pll_out_khz < priv->lane_min_kbps) {
+ pll_out_khz = priv->lane_min_kbps;
dev_warn(dev, "Warning min phy mbps is used\n");
}
@@ -299,7 +306,7 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings,
idf = 0;
ndiv = 0;
odf = 0;
- ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz,
+ ret = dsi_pll_get_params(priv, pll_in_khz, pll_out_khz,
&idf, &ndiv, &odf);
if (ret) {
dev_err(dev, "Warning dsi_pll_get_params(): bad params\n");
@@ -310,18 +317,18 @@ static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings,
pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
/* Set the PLL division factors */
- dsi_update_bits(dsi, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF,
+ dsi_update_bits(plat->base, DSI_WRPCR, WRPCR_NDIV | WRPCR_IDF | WRPCR_ODF,
(ndiv << 2) | (idf << 11) | ((ffs(odf) - 1) << 16));
/* Compute uix4 & set the bit period in high-speed mode */
val = 4000000 / pll_out_khz;
- dsi_update_bits(dsi, DSI_WPCR0, WPCR0_UIX4, val);
+ dsi_update_bits(plat->base, DSI_WPCR0, WPCR0_UIX4, val);
/* Select video mode by resetting DSIM bit */
- dsi_clear(dsi, DSI_WCFGR, WCFGR_DSIM);
+ dsi_clear(plat->base, DSI_WCFGR, WCFGR_DSIM);
/* Select the color coding */
- dsi_update_bits(dsi, DSI_WCFGR, WCFGR_COLMUX,
+ dsi_update_bits(plat->base, DSI_WCFGR, WCFGR_COLMUX,
dsi_color_from_mipi(format) << 1);
*lane_mbps = pll_out_khz / 1000;
@@ -340,27 +347,27 @@ static const struct mipi_dsi_phy_ops dsi_stm_phy_ops = {
static int stm32_dsi_attach(struct udevice *dev)
{
- struct stm32_dsi_priv *priv = dev_get_priv(dev);
- struct mipi_dsi_device *device = &priv->device;
+ struct stm32_dsi_plat *plat = dev_get_plat(dev);
+ struct mipi_dsi_device *device = &plat->device;
struct mipi_dsi_panel_plat *mplat;
struct display_timing timings;
int ret;
- ret = uclass_first_device_err(UCLASS_PANEL, &priv->panel);
+ ret = uclass_first_device_err(UCLASS_PANEL, &plat->panel);
if (ret) {
dev_err(dev, "panel device error %d\n", ret);
return ret;
}
- mplat = dev_get_plat(priv->panel);
- mplat->device = &priv->device;
+ mplat = dev_get_plat(plat->panel);
+ mplat->device = &plat->device;
device->lanes = mplat->lanes;
device->format = mplat->format;
device->mode_flags = mplat->mode_flags;
- ret = panel_get_display_timing(priv->panel, &timings);
+ ret = panel_get_display_timing(plat->panel, &timings);
if (ret) {
- ret = ofnode_decode_display_timing(dev_ofnode(priv->panel),
+ ret = ofnode_decode_display_timing(dev_ofnode(plat->panel),
0, &timings);
if (ret) {
dev_err(dev, "decode display timing error %d\n", ret);
@@ -368,13 +375,13 @@ static int stm32_dsi_attach(struct udevice *dev)
}
}
- ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host);
+ ret = uclass_get_device(UCLASS_DSI_HOST, 0, &plat->dsi_host);
if (ret) {
dev_err(dev, "No video dsi host detected %d\n", ret);
return ret;
}
- ret = dsi_host_init(priv->dsi_host, device, &timings, 2,
+ ret = dsi_host_init(plat->dsi_host, device, &timings, 2,
&dsi_stm_phy_ops);
if (ret) {
dev_err(dev, "failed to initialize mipi dsi host\n");
@@ -386,17 +393,17 @@ static int stm32_dsi_attach(struct udevice *dev)
static int stm32_dsi_set_backlight(struct udevice *dev, int percent)
{
- struct stm32_dsi_priv *priv = dev_get_priv(dev);
+ struct stm32_dsi_plat *plat = dev_get_plat(dev);
int ret;
- ret = panel_enable_backlight(priv->panel);
+ ret = panel_enable_backlight(plat->panel);
if (ret) {
dev_err(dev, "panel %s enable backlight error %d\n",
- priv->panel->name, ret);
+ plat->panel->name, ret);
return ret;
}
- ret = dsi_host_enable(priv->dsi_host);
+ ret = dsi_host_enable(plat->dsi_host);
if (ret) {
dev_err(dev, "failed to enable mipi dsi host\n");
return ret;
@@ -417,66 +424,71 @@ static int stm32_dsi_bind(struct udevice *dev)
return dm_scan_fdt_dev(dev);
}
-static int stm32_dsi_probe(struct udevice *dev)
+static int stm32_dsi_of_to_plat(struct udevice *dev)
{
- struct stm32_dsi_priv *priv = dev_get_priv(dev);
- struct mipi_dsi_device *device = &priv->device;
- struct reset_ctl rst;
- struct clk clk;
+ struct stm32_dsi_plat *plat = dev_get_plat(dev);
+ struct mipi_dsi_device *device = &plat->device;
int ret;
device->dev = dev;
- priv->base = dev_read_addr_ptr(dev);
- if (!priv->base) {
+ plat->base = dev_read_addr_ptr(dev);
+ if (!plat->base) {
dev_err(dev, "dsi dt register address error\n");
return -EINVAL;
}
ret = device_get_supply_regulator(dev, "phy-dsi-supply",
- &priv->vdd_reg);
+ &plat->vdd_reg);
if (ret && ret != -ENOENT) {
dev_err(dev, "Warning: cannot get phy dsi supply\n");
return -ENODEV;
}
if (ret != -ENOENT) {
- ret = regulator_set_enable(priv->vdd_reg, true);
+ ret = regulator_set_enable(plat->vdd_reg, true);
if (ret)
return ret;
}
- ret = clk_get_by_name(device->dev, "pclk", &clk);
+ ret = clk_get_by_name(device->dev, "pclk", &plat->pclk);
if (ret) {
dev_err(dev, "peripheral clock get error %d\n", ret);
- goto err_reg;
- }
-
- ret = clk_enable(&clk);
- if (ret) {
- dev_err(dev, "peripheral clock enable error %d\n", ret);
- goto err_reg;
+ return ret;
}
- ret = clk_get_by_name(dev, "ref", &clk);
+ ret = clk_get_by_name(dev, "ref", &plat->refclk);
if (ret) {
dev_err(dev, "pll reference clock get error %d\n", ret);
- goto err_clk;
+ return ret;
}
- priv->pllref_clk = (unsigned int)clk_get_rate(&clk);
+ ret = reset_get_by_index(device->dev, 0, &plat->rst);
+ if (ret)
+ dev_err(dev, "missing dsi hardware reset\n");
+
+ return ret;
+}
- ret = reset_get_by_index(device->dev, 0, &rst);
+static int stm32_dsi_probe(struct udevice *dev)
+{
+ struct stm32_dsi_plat *plat = dev_get_plat(dev);
+ struct stm32_dsi_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = clk_enable(&plat->pclk);
if (ret) {
- dev_err(dev, "missing dsi hardware reset\n");
- goto err_clk;
+ dev_err(dev, "peripheral clock enable error %d\n", ret);
+ goto err_reg;
}
+ priv->pllref_clk = (unsigned int)clk_get_rate(&plat->refclk);
+
/* Reset */
- reset_deassert(&rst);
+ reset_deassert(&plat->rst);
/* check hardware version */
- priv->hw_version = dsi_read(priv, DSI_VERSION) & VERSION;
+ priv->hw_version = dsi_read(plat->base, DSI_VERSION) & VERSION;
if (priv->hw_version != HWVER_130 &&
priv->hw_version != HWVER_131) {
dev_err(dev, "DSI version 0x%x not supported\n", priv->hw_version);
@@ -489,9 +501,9 @@ static int stm32_dsi_probe(struct udevice *dev)
return 0;
err_clk:
- clk_disable(&clk);
+ clk_disable(&plat->pclk);
err_reg:
- regulator_set_enable(priv->vdd_reg, false);
+ regulator_set_enable(plat->vdd_reg, false);
return ret;
}
@@ -512,6 +524,8 @@ U_BOOT_DRIVER(stm32_dsi) = {
.of_match = stm32_dsi_ids,
.bind = stm32_dsi_bind,
.probe = stm32_dsi_probe,
+ .of_to_plat = stm32_dsi_of_to_plat,
.ops = &stm32_dsi_ops,
+ .plat_auto = sizeof(struct stm32_dsi_plat),
.priv_auto = sizeof(struct stm32_dsi_priv),
};
diff --git a/drivers/watchdog/adi_wdt.c b/drivers/watchdog/adi_wdt.c
index 6f5b3d5d042..7d7cf98b55e 100644
--- a/drivers/watchdog/adi_wdt.c
+++ b/drivers/watchdog/adi_wdt.c
@@ -2,12 +2,10 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
- * Written and/or maintained by Timesys Corporation
+ * Written by Timesys Corporation
*
* Converted to driver model by Nathan Barrett-Morrison
*
- * Contact: Nathan Barrett-Morrison <[email protected]>
- * Contact: Greg Malysa <[email protected]>
*
* adi_wtd.c - driver for ADI on-chip watchdog
*