Prepare v2026.04-rc4

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTzzqh0PWDgGS+bTHor4qD1Cr/kCgUCaa8k+wAKCRAr4qD1Cr/k
 Cu3PAP9NGUYzCBO5BOYYJ8nQNIyr2S/mKB25HQ54n+MiILxbTwD+MpTLhNw7Yz3M
 A9aXrmEMzMYeKPFfeP/Zjh4+7VDC7AI=
 =sEOP
 -----END PGP SIGNATURE-----

Merge tag 'v2026.04-rc4' into next

Prepare v2026.04-rc4
This commit is contained in:
Tom Rini 2026-03-09 15:26:34 -06:00
commit 1e240f7206
139 changed files with 3658 additions and 746 deletions

View File

@ -795,5 +795,5 @@ vf2:
qemu-x86_64:
variables:
ROLE: qemu-x86_64
TEST_PY_TEST_SPEC: "and not sleep"
TEST_PY_TEST_SPEC: "not sleep"
<<: *sjg_lab_dfn

View File

@ -629,15 +629,12 @@ S: Supported
F: arch/arm/dts/am335x-sancloud*
ARM SC5XX
M: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
M: Greg Malysa <malysagreg@gmail.com>
M: Ian Roberts <ian.roberts@timesys.com>
M: Vasileios Bimpikas <vasileios.bimpikas@analog.com>
M: Utsav Agarwal <utsav.agarwal@analog.com>
M: Arturs Artamonovs <arturs.artamonovs@analog.com>
L: adsp-linux@analog.com
L: linux@analog.com
S: Supported
T: git https://github.com/analogdevicesinc/lnxdsp-u-boot
T: git https://github.com/analogdevicesinc/u-boot
F: arch/arm/dts/sc5*
F: arch/arm/include/asm/arch-adi/
F: arch/arm/mach-sc5xx/
@ -1760,7 +1757,7 @@ F: drivers/mtd/nand/spi/
SPI-NOR
M: Vignesh R <vigneshr@ti.com>
R: Tudor Ambarus <tudor.ambarus@linaro.org>
R: Takahiro Kuwano <takahiro.kuwano@infineon.com>
S: Maintained
F: drivers/mtd/spi/
F: include/spi_flash.h

View File

@ -3,7 +3,7 @@
VERSION = 2026
PATCHLEVEL = 04
SUBLEVEL =
EXTRAVERSION = -rc3
EXTRAVERSION = -rc4
NAME =
# *DOCUMENTATION*

View File

@ -878,15 +878,16 @@ void flush_dcache_range(unsigned long start, unsigned long stop)
void dcache_enable(void)
{
/* The data cache is not active unless the mmu is enabled */
if (!mmu_status())
if (!mmu_status()) {
__asm_invalidate_tlb_all();
mmu_setup();
}
/* Set up page tables only once (it is done also by mmu_setup()) */
if (!gd->arch.tlb_fillptr)
setup_all_pgtables();
invalidate_dcache_all();
__asm_invalidate_tlb_all();
set_sctlr(get_sctlr() | CR_C);
}

View File

@ -0,0 +1,26 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2026 Kaustabh Chakraborty <kauschluss@disroot.org>
*/
/ {
/* These properties are required by S-BOOT. */
model_info-chip = <7870>;
model_info-hw_rev = <0>;
model_info-hw_rev_end = <255>;
chosen {
#address-cells = <2>;
#size-cells = <1>;
ranges;
framebuffer@67000000 {
compatible = "simple-framebuffer";
reg = <0x0 0x67000000 (540 * 960 * 4)>;
width = <540>;
height = <960>;
stride = <(540 * 4)>;
format = "a8r8g8b8";
};
};
};

View File

@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) Kaustabh Chakraborty <kauschluss@disroot.org>
*/
/ {
/* These properties are required by S-BOOT. */
model_info-chip = <7870>;
model_info-hw_rev = <0>;
model_info-hw_rev_end = <255>;
chosen {
#address-cells = <2>;
#size-cells = <1>;
ranges;
framebuffer@67000000 {
compatible = "simple-framebuffer";
reg = <0x0 0x67000000 (720 * 1480 * 4)>;
width = <720>;
height = <1480>;
stride = <(720 * 4)>;
format = "a8r8g8b8";
};
};
/*
* S-BOOT will populate the memory nodes stated below. Existing
* values redefine the safe memory requirements as stated in upstream
* device tree, in separate nodes for each bank.
*/
memory@40000000 {
device_type = "memory";
reg = <0x0 0x40000000 0x3d800000>;
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x40000000>;
};
memory@100000000 {
device_type = "memory";
reg = <0x1 0x00000000 0x00000000>;
};
};

View File

@ -0,0 +1,41 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2026 Kaustabh Chakraborty <kauschluss@disroot.org>
*/
/ {
/* These properties are required by S-BOOT. */
model_info-chip = <7870>;
model_info-hw_rev = <0>;
model_info-hw_rev_end = <255>;
chosen {
#address-cells = <2>;
#size-cells = <1>;
ranges;
framebuffer@67000000 {
compatible = "simple-framebuffer";
reg = <0x0 0x67000000 (1080 * 1920 * 4)>;
width = <1080>;
height = <1920>;
stride = <(1080 * 4)>;
format = "a8r8g8b8";
};
};
/*
* S-BOOT will populate the memory nodes stated below. Existing
* values redefine the safe memory requirements as stated in upstream
* device tree, in separate nodes for each bank.
*/
memory@40000000 {
device_type = "memory";
reg = <0x0 0x40000000 0x3e400000>;
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x80000000>;
};
};

View File

@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
/*
* Copyright (C) STMicroelectronics 2026 - All Rights Reserved
*/
/ {
config {
u-boot,boot-led = "led-blue";
u-boot,mmc-env-partition = "u-boot-env";
};
};
&syscfg {
bootph-all;
};
&usart2 {
bootph-all;
};

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef ARCH_ADI_SC5XX_SC5XX_H
#define ARCH_ADI_SC5XX_SC5XX_H

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef BOARD_ADI_COMMON_SOC_H

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef ARCH_ADI_SC5XX_SPL_H
#define ARCH_ADI_SC5XX_SPL_H

View File

@ -29,6 +29,22 @@ struct mm_region k3_mem_map[K3_MEM_MAP_LEN] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { /*
* PCIe 4 GB Address Window for AM64 and J722S SoCs starts
* from 0x6_0000_0000 and has a size of 0x1_0000_0000.
* Since this is already enabled by the 'Flash Peripherals'
* region above, we don't need to add it again.
*
* The PCIe 4 GB Address Windows for AM68, AM69, J7200, J721E,
* J721S2, J742S2 and J784S4 SoCs are enabled by the following
* region.
*/
.virt = 0x4000000000UL,
.phys = 0x4000000000UL,
.size = 0x400000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, [K3_MEM_MAP_FIRST_BANK_IDX] = { /* First DRAM Bank of size 2G */
.virt = CFG_SYS_SDRAM_BASE,
.phys = CFG_SYS_SDRAM_BASE,

View File

@ -407,6 +407,11 @@ void k3_fix_rproc_clock(const char *path)
path, a_core_frequency / 1000000, speed_grade);
}
__weak phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
{
return gd->ram_top;
}
void spl_enable_cache(void)
{
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
@ -420,6 +425,7 @@ void spl_enable_cache(void)
gd->arch.tlb_size = PGTABLE_SIZE;
gd->ram_top += get_effective_memsize();
gd->ram_top = board_get_usable_ram_top(0);
gd->relocaddr = gd->ram_top;
ret = spl_reserve_video_from_ram_top();

View File

@ -8,11 +8,14 @@
#include <spl.h>
/* We need 3 extra entries for:
* SoC peripherals, flash and the sentinel value.
/* We need 4 extra entries for:
* 1. SoC peripherals
* 2. Flash
* 3. PCIe 4GB Windows for AM68, AM69, J7200, J721E, J721S2, J742S2 and J784S4 SoCs
* 4. Sentinel value
*/
#define K3_MEM_MAP_LEN ((CONFIG_NR_DRAM_BANKS) + 3)
#define K3_MEM_MAP_FIRST_BANK_IDX 2
#define K3_MEM_MAP_LEN ((CONFIG_NR_DRAM_BANKS) + 4)
#define K3_MEM_MAP_FIRST_BANK_IDX 3
int dram_init(void);
int dram_init_banksize(void);

View File

@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
# Written and/or maintained by Timesys Corporation
#
# Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
# Contact: Greg Malysa <greg.malysa@timesys.com>
# Written by Timesys Corporation
#
# All 32-bit platforms require SYS_ARM_CACHE_WRITETHROUGH

View File

@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
# Written and/or maintained by Timesys Corporation
#
# Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
# Contact: Greg Malysa <greg.malysa@timesys.com>
# Written by Timesys Corporation
#
obj-y += soc.o init/

View File

@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
# Written and/or maintained by Timesys Corporation
#
# Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
# Contact: Greg Malysa <greg.malysa@timesys.com>
# Written by Timesys Corporation
#
ifdef CONFIG_XPL_BUILD

View File

@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
# Written and/or maintained by Timesys Corporation
#
# Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
# Contact: Greg Malysa <greg.malysa@timesys.com>
# Written by Timesys Corporation
#
obj-y += dmcinit.o clkinit.o

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/arch-adi/sc5xx/sc5xx.h>

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef CLKINIT_H_

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/io.h>

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef DMCINIT_H_

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef IS43TR16512BL_H

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef MT41K128M16JT_H

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef MT41K512M16HA_H

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#ifndef MT47H128M16RT_H

View File

@ -2,9 +2,8 @@
/*
* (C) Copyright 2024 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Contact: Ian Roberts <ian.roberts@timesys.com>
*/
#include <dm.h>

View File

@ -2,10 +2,8 @@
/*
* (C) Copyright 2024 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/io.h>

View File

@ -2,10 +2,8 @@
/*
* (C) Copyright 2024 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/io.h>

View File

@ -2,10 +2,8 @@
/*
* (C) Copyright 2024 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/io.h>

View File

@ -2,10 +2,8 @@
/*
* (C) Copyright 2024 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/io.h>

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <asm/arch-adi/sc5xx/sc5xx.h>

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <spl.h>

View File

@ -84,6 +84,32 @@ config STM32MP15X
STMicroelectronics MPU with core ARMv7
dual core A7 for STM32MP157/3, monocore for STM32MP151
config STM32MP21X
bool "Support STMicroelectronics STM32MP21x Soc"
select ARM64
select CLK_STM32MP21
select OF_BOARD
select PINCTRL_STM32
select STM32_RCC
select STM32_RESET
select STM32_SERIAL
select STM32MP_TAMP_NVMEM
select SYS_ARCH_TIMER
select TFABOOT
imply CLK_SCMI
imply CMD_NVEDIT_INFO
imply DM_REGULATOR
imply DM_REGULATOR_SCMI
imply OF_UPSTREAM
imply OPTEE
imply RESET_SCMI
imply SYSRESET_PSCI
imply TEE
imply VERSION_VARIABLE
help
Support of STMicroelectronics SOC STM32MP21X family
STMicroelectronics MPU with 1 A35 core and 1 M33 core
config STM32MP23X
bool "Support STMicroelectronics STM32MP23x Soc"
select ARM64
@ -195,6 +221,7 @@ config MFD_STM32_TIMERS
source "arch/arm/mach-stm32mp/Kconfig.13x"
source "arch/arm/mach-stm32mp/Kconfig.15x"
source "arch/arm/mach-stm32mp/Kconfig.21x"
source "arch/arm/mach-stm32mp/Kconfig.23x"
source "arch/arm/mach-stm32mp/Kconfig.25x"
source "arch/arm/mach-stm32mp/cmd_stm32prog/Kconfig"

View File

@ -0,0 +1,37 @@
if STM32MP21X
choice
prompt "STM32MP21X board select"
optional
config TARGET_ST_STM32MP21X
bool "STMicroelectronics STM32MP21X boards"
imply BOOTSTAGE
imply CMD_BOOTSTAGE
help
target the STMicroelectronics board with SOC STM32MP21X
managed by board/st/stm32mp2
The difference between board are managed with devicetree
endchoice
config TEXT_BASE
default 0x84000000
config PRE_CON_BUF_ADDR
default 0x84800000
config PRE_CON_BUF_SZ
default 4096
if DEBUG_UART
# debug on USART2 by default
config DEBUG_UART_BASE
default 0x400e0000
endif
source "board/st/stm32mp2/Kconfig"
endif

View File

@ -8,8 +8,9 @@ obj-y += syscon.o
obj-y += bsec.o
obj-y += soc.o
obj-$(CONFIG_STM32MP15X) += stm32mp1/
obj-$(CONFIG_STM32MP13X) += stm32mp1/
obj-$(CONFIG_STM32MP15X) += stm32mp1/
obj-$(CONFIG_STM32MP21X) += stm32mp2/
obj-$(CONFIG_STM32MP23X) += stm32mp2/
obj-$(CONFIG_STM32MP25X) += stm32mp2/

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
* Copyright (C) 2019-2024, STMicroelectronics - All Rights Reserved
*/
#include <command.h>
@ -16,21 +16,21 @@
* Closed device: OTP0
* STM32MP15x: bit 6 of OTP0
* STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device
* STM32MP25x: bit 0 of OTP18
* STM32MP2xx: bit 0 of OTP18
*/
#define STM32MP1_OTP_CLOSE_ID 0
#define STM32_OTP_STM32MP13X_CLOSE_MASK GENMASK(5, 0)
#define STM32_OTP_STM32MP15X_CLOSE_MASK BIT(6)
#define STM32MP25_OTP_WORD8 8
#define STM32_OTP_STM32MP25X_BOOTROM_CLOSE_MASK GENMASK(7, 0)
#define STM32MP25_OTP_CLOSE_ID 18
#define STM32_OTP_STM32MP25X_CLOSE_MASK GENMASK(3, 0)
#define STM32_OTP_STM32MP25X_PROVISIONING_DONE_MASK GENMASK(7, 4)
#define STM32MP25_OTP_HWCONFIG 124
#define STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK BIT(20)
#define STM32MP2X_OTP_WORD8 8
#define STM32_OTP_STM32MP2X_BOOTROM_CLOSE_MASK GENMASK(7, 0)
#define STM32MP2X_OTP_CLOSE_ID 18
#define STM32_OTP_STM32MP2X_CLOSE_MASK GENMASK(3, 0)
#define STM32_OTP_STM32MP2X_PROVISIONING_DONE_MASK GENMASK(7, 4)
#define STM32MP2X_OTP_HWCONFIG 124
#define STM32_OTP_STM32MP2X_DISABLE_SCAN_MASK BIT(20)
#define STM32MP25_OTP_BOOTROM_CONF8 17
#define STM32_OTP_STM32MP25X_OEM_KEY2_EN BIT(8)
#define STM32MP2X_OTP_BOOTROM_CONF8 17
#define STM32_OTP_STM32MP2X_OEM_KEY2_EN BIT(8)
/* PKH is the first element of the key list */
#define STM32KEY_PKH 0
@ -40,7 +40,8 @@ struct stm32key {
char *desc;
u16 start;
u8 size;
int (*post_process)(struct udevice *dev);
int (*post_process)(struct udevice *dev, const struct stm32key *key);
u32 (*key_format)(u32 value);
};
const struct stm32key stm32mp13_list[] = {
@ -67,9 +68,81 @@ const struct stm32key stm32mp15_list[] = {
}
};
static int post_process_oem_key2(struct udevice *dev);
static int post_process_oem_key2(struct udevice *dev, const struct stm32key *key);
static int post_process_edmk_128b(struct udevice *dev, const struct stm32key *key);
static u32 format1(u32 value);
static u32 format2(u32 value);
const struct stm32key stm32mp25_list[] = {
const struct stm32key stm32mp21_list[] = {
[STM32KEY_PKH] = {
.name = "OEM-KEY1",
.desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M",
.start = 152,
.size = 8,
},
{
.name = "OEM-KEY2",
.desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLM",
.start = 160,
.size = 8,
.post_process = post_process_oem_key2,
},
{
.name = "RPROC-FW-PKH",
.desc = "Hash of the Public Key for remote processor firmware",
.start = 180,
.size = 8,
.key_format = format2,
},
{
.name = "ADAC-ROTPKH",
.desc = "Authenticated Debug Access Control Root Of Trust Public Key Hash",
.start = 238,
.size = 8,
.key_format = format2,
},
{
.name = "FIP-EDMK",
.desc = "Encryption/Decryption Master Key for FIP",
.start = 260,
.size = 8,
},
{
.name = "RPROC-FW-ENC-KEY",
.desc = "Encryption/Decryption Key for remote processor firmware",
.start = 332,
.size = 8,
.key_format = format2,
},
{
.name = "EDMK1-128b",
.desc = "Encryption/Decryption Master 128b Key for FSBLA or M",
.start = 356,
.size = 4,
.post_process = post_process_edmk_128b,
},
{
.name = "EDMK1-256b",
.desc = "Encryption/Decryption Master 256b Key for FSBLA or M",
.start = 356,
.size = 8,
},
{
.name = "EDMK2-128b",
.desc = "Encryption/Decryption Master 128b Key for FSBLM",
.start = 348,
.size = 4,
.post_process = post_process_edmk_128b,
},
{
.name = "EDMK2-256b",
.desc = "Encryption/Decryption Master 256b Key for FSBLM",
.start = 348,
.size = 8,
},
};
const struct stm32key stm32mp2x_list[] = {
[STM32KEY_PKH] = {
.name = "OEM-KEY1",
.desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M",
@ -83,12 +156,26 @@ const struct stm32key stm32mp25_list[] = {
.size = 8,
.post_process = post_process_oem_key2,
},
{
.name = "RPROC-FW-PKH",
.desc = "Hash of the Public Key for remote processor firmware",
.start = 176,
.size = 8,
.key_format = format2,
},
{
.name = "FIP-EDMK",
.desc = "Encryption/Decryption Master Key for FIP",
.start = 260,
.size = 8,
},
{
.name = "RPROC-FW-ENC-KEY",
.desc = "Encryption/Decryption Key for remote processor firmware",
.start = 336,
.size = 8,
.key_format = format2,
},
{
.name = "EDMK1",
.desc = "Encryption/Decryption Master Key for FSBLA or M",
@ -138,23 +225,23 @@ const struct otp_close stm32mp15_close_state_otp[] = {
}
};
const struct otp_close stm32mp25_close_state_otp[] = {
const struct otp_close stm32mp2x_close_state_otp[] = {
{
.word = STM32MP25_OTP_WORD8,
.mask_wr = STM32_OTP_STM32MP25X_BOOTROM_CLOSE_MASK,
.word = STM32MP2X_OTP_WORD8,
.mask_wr = STM32_OTP_STM32MP2X_BOOTROM_CLOSE_MASK,
.mask_rd = 0,
.close_status_ops = NULL
},
{
.word = STM32MP25_OTP_CLOSE_ID,
.mask_wr = STM32_OTP_STM32MP25X_CLOSE_MASK |
STM32_OTP_STM32MP25X_PROVISIONING_DONE_MASK,
.mask_rd = STM32_OTP_STM32MP25X_CLOSE_MASK,
.word = STM32MP2X_OTP_CLOSE_ID,
.mask_wr = STM32_OTP_STM32MP2X_CLOSE_MASK |
STM32_OTP_STM32MP2X_PROVISIONING_DONE_MASK,
.mask_rd = STM32_OTP_STM32MP2X_CLOSE_MASK,
.close_status_ops = compare_any_bits
},
{
.word = STM32MP25_OTP_HWCONFIG,
.mask_wr = STM32_OTP_STM32MP25X_DISABLE_SCAN_MASK,
.word = STM32MP2X_OTP_HWCONFIG,
.mask_wr = STM32_OTP_STM32MP2X_DISABLE_SCAN_MASK,
.mask_rd = 0,
.close_status_ops = NULL
},
@ -171,8 +258,11 @@ static u8 get_key_nb(void)
if (IS_ENABLED(CONFIG_STM32MP15X))
return ARRAY_SIZE(stm32mp15_list);
if (IS_ENABLED(CONFIG_STM32MP21X))
return ARRAY_SIZE(stm32mp21_list);
if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X))
return ARRAY_SIZE(stm32mp25_list);
return ARRAY_SIZE(stm32mp2x_list);
}
static const struct stm32key *get_key(u8 index)
@ -183,8 +273,11 @@ static const struct stm32key *get_key(u8 index)
if (IS_ENABLED(CONFIG_STM32MP15X))
return &stm32mp15_list[index];
if (IS_ENABLED(CONFIG_STM32MP21X))
return &stm32mp21_list[index];
if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X))
return &stm32mp25_list[index];
return &stm32mp2x_list[index];
}
static u8 get_otp_close_state_nb(void)
@ -195,8 +288,9 @@ static u8 get_otp_close_state_nb(void)
if (IS_ENABLED(CONFIG_STM32MP15X))
return ARRAY_SIZE(stm32mp15_close_state_otp);
if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X))
return ARRAY_SIZE(stm32mp25_close_state_otp);
if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) ||
IS_ENABLED(CONFIG_STM32MP25X))
return ARRAY_SIZE(stm32mp2x_close_state_otp);
}
static const struct otp_close *get_otp_close_state(u8 index)
@ -207,8 +301,27 @@ static const struct otp_close *get_otp_close_state(u8 index)
if (IS_ENABLED(CONFIG_STM32MP15X))
return &stm32mp15_close_state_otp[index];
if (IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X))
return &stm32mp25_close_state_otp[index];
if (IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) ||
IS_ENABLED(CONFIG_STM32MP25X))
return &stm32mp2x_close_state_otp[index];
}
/*
* Define format wrappers based on reference manual formats
* ex for key from NIST vector AES_ECB_256b_test0:
* key (bytes) : f9 e8 38 9f ... ef 94 4b e0
* format 1 (le32) : 0xf9e8389f ... 0xef944be0
* format 2 (le32) : 0x9f38e8f9 ... 0xe04b94ef
*/
static u32 format1(u32 value)
{
return __be32_to_cpu(value);
}
static u32 format2(u32 value)
{
return __le32_to_cpu(value);
}
static int get_misc_dev(struct udevice **dev)
@ -225,15 +338,21 @@ static int get_misc_dev(struct udevice **dev)
static void read_key_value(const struct stm32key *key, unsigned long addr)
{
int i;
u32 (*format)(u32) = format1;
/* Use key_format function pointer if defined */
if (key->key_format)
format = key->key_format;
for (i = 0; i < key->size; i++) {
printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i,
(u32)addr, __be32_to_cpu(*(u32 *)addr));
(u32)addr, format(*(u32 *)addr));
addr += 4;
}
}
static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked)
static int read_key_otp(struct udevice *dev, const struct stm32key *key,
bool print, bool *locked)
{
int i, word, ret;
int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0;
@ -347,19 +466,19 @@ static int write_close_status(struct udevice *dev)
return 0;
}
static int post_process_oem_key2(struct udevice *dev)
static int post_process_oem_key2(struct udevice *dev, const struct stm32key *key)
{
int ret;
u32 val;
ret = misc_read(dev, STM32_BSEC_OTP(STM32MP25_OTP_BOOTROM_CONF8), &val, 4);
ret = misc_read(dev, STM32_BSEC_OTP(STM32MP2X_OTP_BOOTROM_CONF8), &val, 4);
if (ret != 4) {
log_err("Error %d failed to read STM32MP25_OTP_BOOTROM_CONF8\n", ret);
log_err("Error %d failed to read STM32MP2X_OTP_BOOTROM_CONF8\n", ret);
return -EIO;
}
val |= STM32_OTP_STM32MP25X_OEM_KEY2_EN;
ret = misc_write(dev, STM32_BSEC_OTP(STM32MP25_OTP_BOOTROM_CONF8), &val, 4);
val |= STM32_OTP_STM32MP2X_OEM_KEY2_EN;
ret = misc_write(dev, STM32_BSEC_OTP(STM32MP2X_OTP_BOOTROM_CONF8), &val, 4);
if (ret != 4) {
log_err("Error %d failed to write OEM_KEY2_ENABLE\n", ret);
return -EIO;
@ -368,14 +487,44 @@ static int post_process_oem_key2(struct udevice *dev)
return 0;
}
static int post_process_edmk_128b(struct udevice *dev, const struct stm32key *key)
{
int ret, word, start_otp;
u32 val;
start_otp = key->start + key->size;
/* On MP21, when using a 128bit key, program 0xffffffff and lock the unused OTPs. */
for (word = start_otp; word < (start_otp + 4); word++) {
val = GENMASK(31, 0);
ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
if (ret != 4)
log_warning("Fuse %s OTP padding %i failed, continue\n", key->name, word);
val = BSEC_LOCK_PERM;
ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4);
if (ret != 4) {
log_err("Failed to lock unused OTP : %d\n", word);
return ret;
}
}
return 0;
}
static int fuse_key_value(struct udevice *dev, const struct stm32key *key, unsigned long addr,
bool print)
{
u32 word, val;
int i, ret;
u32 (*format)(u32) = format1;
/* Use key_format function pointer if defined */
if (key->key_format)
format = key->key_format;
for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) {
val = __be32_to_cpu(*(u32 *)addr);
val = format(*(u32 *)addr);
if (print)
printf("Fuse %s OTP %i : %08x\n", key->name, word, val);
@ -546,7 +695,7 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con
return CMD_RET_FAILURE;
if (key->post_process) {
if (key->post_process(dev)) {
if (key->post_process(dev, key)) {
printf("Error: %s for post process\n", key->name);
return CMD_RET_FAILURE;
}

View File

@ -187,11 +187,3 @@ U_BOOT_CMD(stm32prog, 5, 0, do_stm32prog,
" <addr> = address of flashlayout\n"
" <size> = size of flashlayout (optional for image with STM32 header)\n"
);
bool stm32prog_get_fsbl_nor(void)
{
if (stm32prog_data)
return stm32prog_data->fsbl_nor_detected;
return false;
}

View File

@ -1010,7 +1010,6 @@ static int treat_partition_list(struct stm32prog_data *data)
INIT_LIST_HEAD(&data->dev[j].part_list);
}
data->fsbl_nor_detected = false;
for (i = 0; i < data->part_nb; i++) {
part = &data->part_array[i];
part->alt_id = -1;
@ -1055,15 +1054,6 @@ static int treat_partition_list(struct stm32prog_data *data)
stm32prog_err("Layout: too many device");
return -EINVAL;
}
switch (part->target) {
case STM32PROG_NOR:
if (!data->fsbl_nor_detected &&
!strncmp(part->name, "fsbl", 4))
data->fsbl_nor_detected = true;
/* fallthrough */
default:
break;
}
part->dev = &data->dev[j];
if (!IS_SELECT(part))
part->dev->full_update = false;

View File

@ -167,7 +167,6 @@ struct stm32prog_data {
struct stm32prog_dev_t dev[STM32PROG_MAX_DEV]; /* array of device */
int part_nb; /* nb of partition */
struct stm32prog_part_t *part_array; /* array of partition */
bool fsbl_nor_detected;
/* command internal information */
unsigned int phase;

View File

@ -165,16 +165,20 @@ enum forced_boot_mode {
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_STM32MP15X || CONFIG_STM32MP13X */
#if defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X)
#if defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X)
#define STM32_USART2_BASE 0x400E0000
#define STM32_USART3_BASE 0x400F0000
#define STM32_UART4_BASE 0x40100000
#define STM32_UART5_BASE 0x40110000
#define STM32_USART6_BASE 0x40220000
#ifdef CONFIG_STM32MP25X
#define STM32_UART9_BASE 0x402C0000
#endif
#define STM32_USART1_BASE 0x40330000
#define STM32_UART7_BASE 0x40370000
#ifdef CONFIG_STM32MP25X
#define STM32_UART8_BASE 0x40380000
#endif
#define STM32_RCC_BASE 0x44200000
#define STM32_TAMP_BASE 0x46010000
#define STM32_SDMMC1_BASE 0x48220000
@ -194,7 +198,7 @@ enum forced_boot_mode {
#define TAMP_FWU_BOOT_IDX_MASK GENMASK(3, 0)
#define TAMP_FWU_BOOT_IDX_OFFSET 0
#endif /* defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */
#endif /* defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */
/* offset used for BSEC driver: misc_read and misc_write */
#define STM32_BSEC_SHADOW_OFFSET 0x0
@ -218,14 +222,14 @@ enum forced_boot_mode {
#define BSEC_OTP_MAC 57
#define BSEC_OTP_BOARD 60
#endif
#if defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X)
#if defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X)
#define BSEC_OTP_SERIAL 5
#define BSEC_OTP_RPN 9
#define BSEC_OTP_REVID 102
#define BSEC_OTP_PKG 122
#define BSEC_OTP_BOARD 246
#define BSEC_OTP_MAC 247
#endif /* defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */
#endif /* defined(CONFIG_STM32MP21X) || defined(CONFIG_STM32MP23X) || defined(CONFIG_STM32MP25X) */
#ifndef __ASSEMBLY__
#include <asm/types.h>

View File

@ -10,5 +10,3 @@ int stm32prog_write_medium_virt(struct dfu_entity *dfu, u64 offset,
int stm32prog_read_medium_virt(struct dfu_entity *dfu, u64 offset,
void *buf, long *len);
int stm32prog_get_medium_size_virt(struct dfu_entity *dfu, u64 *size);
bool stm32prog_get_fsbl_nor(void);

View File

@ -30,6 +30,20 @@
#define CPU_STM32MP131Fxx 0x05010EC8
#define CPU_STM32MP131Dxx 0x05010EC9
/* ID for STM32MP21x = Device Part Number (RPN) (bit31:0) */
#define CPU_STM32MP211Axx 0x40073E7D
#define CPU_STM32MP211Cxx 0x0007307D
#define CPU_STM32MP211Dxx 0xC0073E7D
#define CPU_STM32MP211Fxx 0x8007307D
#define CPU_STM32MP213Axx 0x40073E1D
#define CPU_STM32MP213Cxx 0x0007301D
#define CPU_STM32MP213Dxx 0xC0073E1D
#define CPU_STM32MP213Fxx 0x8007301D
#define CPU_STM32MP215Axx 0x40033E0D
#define CPU_STM32MP215Cxx 0x0003300D
#define CPU_STM32MP215Dxx 0xC0033E0D
#define CPU_STM32MP215Fxx 0x8003300D
/* ID for STM32MP23x = Device Part Number (RPN) (bit31:0) */
#define CPU_STM32MP235Cxx 0x00082182
#define CPU_STM32MP233Cxx 0x000B318E
@ -67,6 +81,7 @@ u32 get_cpu_type(void);
#define CPU_DEV_STM32MP15 0x500
#define CPU_DEV_STM32MP13 0x501
#define CPU_DEV_STM32MP21 0x503
#define CPU_DEV_STM32MP23 0x505
#define CPU_DEV_STM32MP25 0x505
@ -102,6 +117,13 @@ u32 get_cpu_package(void);
#define STM32MP15_PKG_AD_TFBGA257 1
#define STM32MP15_PKG_UNKNOWN 0
/* package used for STM32MP21x */
#define STM32MP21_PKG_CUSTOM 0
#define STM32MP21_PKG_AL_VFBGA361 1
#define STM32MP21_PKG_AN_VFBGA273 3
#define STM32MP21_PKG_AO_VFBGA225 4
#define STM32MP21_PKG_AM_TFBGA289 5
/* package used for STM32MP23x */
#define STM32MP23_PKG_CUSTOM 0
#define STM32MP23_PKG_AL_VFBGA361 1

View File

@ -17,6 +17,7 @@
#include <dm/device.h>
#include <dm/uclass.h>
#include <linux/bitfield.h>
#include <linux/err.h>
#include <malloc.h>
/* RCC register */
@ -231,6 +232,12 @@ static u32 read_idc(void)
{
void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
if (IS_ERR(syscfg)) {
pr_err("Error, can't get SYSCON range (%ld)\n", PTR_ERR(syscfg));
return PTR_ERR(syscfg);
}
return readl(syscfg + SYSCFG_IDC_OFFSET);
}

View File

@ -6,6 +6,8 @@
obj-y += cpu.o
obj-y += arm64-mmu.o
obj-y += rifsc.o
obj-y += stm32mp2x.o
obj-$(CONFIG_OF_SYSTEM_SETUP) += fdt.o
obj-$(CONFIG_STM32MP21X) += stm32mp21x.o
obj-$(CONFIG_STM32MP23X) += stm32mp23x.o
obj-$(CONFIG_STM32MP25X) += stm32mp25x.o

View File

@ -16,6 +16,7 @@
struct mm_region stm32mp2_mem_map[MP2_MEM_MAP_MAX] = {
{
#if defined(CONFIG_STM32MP25X)
/* PCIe */
.virt = 0x10000000UL,
.phys = 0x10000000UL,
@ -24,6 +25,7 @@ struct mm_region stm32mp2_mem_map[MP2_MEM_MAP_MAX] = {
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
#endif
/* LPSRAMs, VDERAM, RETRAM, SRAMs, SYSRAM: alias1 */
.virt = 0x20000000UL,
.phys = 0x20000000UL,

View File

@ -15,6 +15,7 @@
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
#include <asm/armv8/mmu.h>
#include <asm/system.h>
#include <dm/device.h>
#include <dm/lists.h>
@ -70,8 +71,21 @@ int mach_cpu_init(void)
void enable_caches(void)
{
struct mm_region *mem = mem_map;
/* deactivate the data cache, early enabled in arch_cpu_init() */
dcache_disable();
/* Parse mem_map and find DDR entry */
while (mem->size) {
if (mem->phys == CONFIG_TEXT_BASE) {
/* update DDR entry with real DDR size */
mem->size = gd->ram_size;
break;
}
mem++;
}
/*
* Force the call of setup_all_pgtables() in mmu_setup() by clearing tlb_fillptr
* to update the TLB location udpated in board_f.c::reserve_mmu
@ -128,8 +142,10 @@ static void setup_boot_mode(void)
STM32_UART5_BASE,
STM32_USART6_BASE,
STM32_UART7_BASE,
#ifdef CONFIG_STM32MP25X
STM32_UART8_BASE,
STM32_UART9_BASE
#endif
};
const u32 sdmmc_addr[] = {
STM32_SDMMC1_BASE,
@ -148,7 +164,7 @@ static void setup_boot_mode(void)
__func__, boot_ctx, boot_mode, instance, forced_mode);
switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
case BOOT_SERIAL_UART:
if (instance > ARRAY_SIZE(serial_addr))
if (instance >= ARRAY_SIZE(serial_addr))
break;
/* serial : search associated node in devicetree */
sprintf(cmd, "serial@%x", serial_addr[instance]);
@ -178,7 +194,7 @@ static void setup_boot_mode(void)
break;
case BOOT_FLASH_SD:
case BOOT_FLASH_EMMC:
if (instance > ARRAY_SIZE(sdmmc_addr))
if (instance >= ARRAY_SIZE(sdmmc_addr))
break;
/* search associated sdmmc node in devicetree */
sprintf(cmd, "mmc@%x", sdmmc_addr[instance]);

View File

@ -141,27 +141,16 @@ static int rifsc_check_access(void *base, u32 id)
cid_reg_value = readl(base + RIFSC_RISC_PER0_CIDCFGR(id));
sem_reg_value = readl(base + RIFSC_RISC_PER0_SEMCR(id));
/*
* First check conditions for semaphore mode, which doesn't take into
* account static CID.
*/
if (cid_reg_value & CIDCFGR_SEMEN)
goto skip_cid_check;
/*
* Skip cid check if CID filtering isn't enabled or filtering is enabled on CID0, which
* corresponds to whatever CID.
*/
if (!(cid_reg_value & CIDCFGR_CFEN) ||
FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) == RIF_CID0)
goto skip_cid_check;
/* Coherency check with the CID configuration */
if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
log_debug("Invalid CID configuration for peripheral %d\n", id);
/* Check security configuration */
if (sec_reg_value & BIT(reg_offset)) {
log_debug("Invalid security configuration for peripheral %d\n", id);
return -EACCES;
}
/* Skip cid check if CID filtering isn't enabled */
if (!(cid_reg_value & CIDCFGR_CFEN))
goto skip_cid_check;
/* Check semaphore accesses */
if (cid_reg_value & CIDCFGR_SEMEN) {
if (!(FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
@ -173,15 +162,12 @@ static int rifsc_check_access(void *base, u32 id)
log_debug("Semaphore unavailable for peripheral %d\n", id);
return -EACCES;
}
}
skip_cid_check:
/* Check security configuration */
if (sec_reg_value & BIT(reg_offset)) {
log_debug("Invalid security configuration for peripheral %d\n", id);
} else if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
log_debug("Invalid CID configuration for peripheral %d\n", id);
return -EACCES;
}
skip_cid_check:
return 0;
}
@ -208,7 +194,7 @@ int stm32_rifsc_grant_access_by_id(ofnode device_node, u32 id)
* If the peripheral is in semaphore mode, take the semaphore so that
* the CID1 has the ownership.
*/
if (cid_reg_value & CIDCFGR_SEMEN &&
if (cid_reg_value & CIDCFGR_CFEN && cid_reg_value & CIDCFGR_SEMEN &&
(FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
err = stm32_rifsc_acquire_semaphore(rifsc_base, id);
if (err) {
@ -367,6 +353,7 @@ static int stm32_rifsc_remove(struct udevice *bus)
}
static const struct udevice_id stm32_rifsc_ids[] = {
{ .compatible = "st,stm32mp21-rifsc" },
{ .compatible = "st,stm32mp25-rifsc" },
{},
};

View File

@ -0,0 +1,148 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
/*
* Copyright (C) 2026, STMicroelectronics - All Rights Reserved
*/
#define LOG_CATEGORY LOGC_ARCH
#include <log.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
/* Package = bit 0:2 of OTP122 => STM32MP21_PKG defines
* - 000: Custom package
* - 001: VFBGA361 => AL = 10x10, 361 balls pith 0.5mm
* - 011: VFBGA273 => AN = 11x11, 273 balls pith 0.5mm
* - 100: VFBGA225 => AO = 8x8, 225 balls pith 0.5mm
* - 101: TFBGA289 => AM = 14x14, 289 balls pith 0.8mm
* - others: Reserved
*/
int get_eth_nb(void)
{
int nb_eth;
switch (get_cpu_type()) {
case CPU_STM32MP215Axx:
fallthrough;
case CPU_STM32MP215Cxx:
fallthrough;
case CPU_STM32MP215Dxx:
fallthrough;
case CPU_STM32MP215Fxx:
fallthrough;
case CPU_STM32MP213Axx:
fallthrough;
case CPU_STM32MP213Cxx:
fallthrough;
case CPU_STM32MP213Dxx:
fallthrough;
case CPU_STM32MP213Fxx:
nb_eth = 2; /* dual ETH */
break;
case CPU_STM32MP211Axx:
fallthrough;
case CPU_STM32MP211Cxx:
fallthrough;
case CPU_STM32MP211Dxx:
fallthrough;
case CPU_STM32MP211Fxx:
nb_eth = 1; /* single ETH */
break;
default:
nb_eth = 0;
break;
}
return nb_eth;
}
void get_soc_name(char name[SOC_NAME_SIZE])
{
char *cpu_s, *cpu_r, *package;
cpu_s = "????";
cpu_r = "?";
package = "??";
if (get_cpu_dev() == CPU_DEV_STM32MP21) {
switch (get_cpu_type()) {
case CPU_STM32MP215Fxx:
cpu_s = "215F";
break;
case CPU_STM32MP215Dxx:
cpu_s = "215D";
break;
case CPU_STM32MP215Cxx:
cpu_s = "215C";
break;
case CPU_STM32MP215Axx:
cpu_s = "215A";
break;
case CPU_STM32MP213Fxx:
cpu_s = "213F";
break;
case CPU_STM32MP213Dxx:
cpu_s = "213D";
break;
case CPU_STM32MP213Cxx:
cpu_s = "213C";
break;
case CPU_STM32MP213Axx:
cpu_s = "213A";
break;
case CPU_STM32MP211Fxx:
cpu_s = "211F";
break;
case CPU_STM32MP211Dxx:
cpu_s = "211D";
break;
case CPU_STM32MP211Cxx:
cpu_s = "211C";
break;
case CPU_STM32MP211Axx:
cpu_s = "211A";
break;
default:
cpu_s = "21??";
break;
}
/* REVISION */
switch (get_cpu_rev()) {
case OTP_REVID_1:
cpu_r = "A";
break;
case OTP_REVID_1_1:
cpu_r = "Z";
break;
case OTP_REVID_2:
cpu_r = "B";
break;
default:
break;
}
/* PACKAGE */
switch (get_cpu_package()) {
case STM32MP25_PKG_CUSTOM:
package = "XX";
break;
case STM32MP21_PKG_AL_VFBGA361:
package = "AL";
break;
case STM32MP21_PKG_AN_VFBGA273:
package = "AN";
break;
case STM32MP21_PKG_AO_VFBGA225:
package = "AO";
break;
case STM32MP21_PKG_AM_TFBGA289:
package = "AM";
break;
default:
break;
}
}
snprintf(name, SOC_NAME_SIZE, "STM32MP%s%s Rev.%s", cpu_s, package, cpu_r);
}

View File

@ -11,19 +11,6 @@
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
/* SYSCFG register */
#define SYSCFG_DEVICEID_OFFSET 0x6400
#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0)
#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0
/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/
#define REVID_SHIFT 0
#define REVID_MASK GENMASK(5, 0)
/* Device Part Number (RPN) = OTP9 */
#define RPN_SHIFT 0
#define RPN_MASK GENMASK(31, 0)
/* Package = bit 0:2 of OTP122 => STM32MP23_PKG defines
* - 000: Custom package
* - 011: TFBGA361 => AL = 10x10, 361 balls pith 0.5mm
@ -31,37 +18,6 @@
* - 101: TFBGA436 => AI = 18x18, 436 balls pith 0.5mm
* - others: Reserved
*/
#define PKG_SHIFT 0
#define PKG_MASK GENMASK(2, 0)
static u32 read_deviceid(void)
{
void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
return readl(syscfg + SYSCFG_DEVICEID_OFFSET);
}
u32 get_cpu_dev(void)
{
return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT;
}
u32 get_cpu_rev(void)
{
return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK);
}
/* Get Device Part Number (RPN) from OTP */
u32 get_cpu_type(void)
{
return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK);
}
/* Get Package options from OTP */
u32 get_cpu_package(void)
{
return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK);
}
int get_eth_nb(void)
{

View File

@ -6,24 +6,9 @@
#define LOG_CATEGORY LOGC_ARCH
#include <log.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
/* SYSCFG register */
#define SYSCFG_DEVICEID_OFFSET 0x6400
#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0)
#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0
/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/
#define REVID_SHIFT 0
#define REVID_MASK GENMASK(5, 0)
/* Device Part Number (RPN) = OTP9 */
#define RPN_SHIFT 0
#define RPN_MASK GENMASK(31, 0)
/* Package = bit 0:2 of OTP122 => STM32MP25_PKG defines
* - 000: Custom package
* - 001: VFBGA361 => AL = 10x10, 361 balls pith 0.5mm
@ -31,37 +16,6 @@
* - 101: TFBGA436 => AI = 18x18, 436 balls pith 0.5mm
* - others: Reserved
*/
#define PKG_SHIFT 0
#define PKG_MASK GENMASK(2, 0)
static u32 read_deviceid(void)
{
void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
return readl(syscfg + SYSCFG_DEVICEID_OFFSET);
}
u32 get_cpu_dev(void)
{
return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT;
}
u32 get_cpu_rev(void)
{
return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK);
}
/* Get Device Part Number (RPN) from OTP */
u32 get_cpu_type(void)
{
return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK);
}
/* Get Package options from OTP */
u32 get_cpu_package(void)
{
return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK);
}
int get_eth_nb(void)
{

View File

@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
/*
* Copyright (C) 2026, STMicroelectronics - All Rights Reserved
*/
#define LOG_CATEGORY LOGC_ARCH
#include <log.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <linux/err.h>
/* SYSCFG register */
#define SYSCFG_DEVICEID_OFFSET 0x6400
#define SYSCFG_DEVICEID_DEV_ID_MASK GENMASK(11, 0)
#define SYSCFG_DEVICEID_DEV_ID_SHIFT 0
/* Revision ID = OTP102[5:0] 6 bits : 3 for Major / 3 for Minor*/
#define REVID_SHIFT 0
#define REVID_MASK GENMASK(5, 0)
/* Device Part Number (RPN) = OTP9 */
#define RPN_SHIFT 0
#define RPN_MASK GENMASK(31, 0)
#define PKG_SHIFT 0
#define PKG_MASK GENMASK(2, 0)
static u32 read_deviceid(void)
{
void *syscfg = syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
if (IS_ERR(syscfg)) {
pr_err("Error, can't get SYSCON range (%ld)\n", PTR_ERR(syscfg));
return PTR_ERR(syscfg);
}
return readl(syscfg + SYSCFG_DEVICEID_OFFSET);
}
u32 get_cpu_dev(void)
{
return (read_deviceid() & SYSCFG_DEVICEID_DEV_ID_MASK) >> SYSCFG_DEVICEID_DEV_ID_SHIFT;
}
u32 get_cpu_rev(void)
{
return get_otp(BSEC_OTP_REVID, REVID_SHIFT, REVID_MASK);
}
/* Get Device Part Number (RPN) from OTP */
u32 get_cpu_type(void)
{
return get_otp(BSEC_OTP_RPN, RPN_SHIFT, RPN_MASK);
}
/* Get Package options from OTP */
u32 get_cpu_package(void)
{
return get_otp(BSEC_OTP_PKG, PKG_SHIFT, PKG_MASK);
}

View File

@ -10,6 +10,7 @@
static const struct udevice_id stm32mp_syscon_ids[] = {
{ .compatible = "st,stm32mp157-syscfg", .data = STM32MP_SYSCON_SYSCFG },
{ .compatible = "st,stm32mp21-syscfg", .data = STM32MP_SYSCON_SYSCFG},
{ .compatible = "st,stm32mp23-syscfg", .data = STM32MP_SYSCON_SYSCFG},
{ .compatible = "st,stm32mp25-syscfg", .data = STM32MP_SYSCON_SYSCFG},
{ }

View File

@ -10,30 +10,33 @@
#include <bootflow.h>
#include <ctype.h>
#include <dm/ofnode.h>
#include <efi.h>
#include <efi_loader.h>
#include <env.h>
#include <errno.h>
#include <init.h>
#include <limits.h>
#include <linux/sizes.h>
#include <lmb.h>
#include <part.h>
#include <stdbool.h>
#include <string.h>
DECLARE_GLOBAL_DATA_PTR;
#define lmb_alloc(size, addr) \
lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
struct exynos_board_info {
const char *name;
const char *chip;
const u64 *const dram_bank_bases;
struct efi_fw_image fw_images[] = {
{
.fw_name = u"UBOOT_BOOT_PARTITION",
.image_index = 1,
},
};
char serial[64];
int (*const match)(struct exynos_board_info *);
const char *match_model;
const u8 match_max_rev;
struct efi_capsule_update_info update_info = {
.dfu_string = NULL,
.images = fw_images,
.num_images = ARRAY_SIZE(fw_images),
};
/*
@ -54,10 +57,6 @@ static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = {
struct mm_region *mem_map = exynos_mem_map;
static const u64 exynos7870_common_dram_bank_bases[CONFIG_NR_DRAM_BANKS] = {
0x40000000, 0x80000000, 0x100000000,
};
static const char *exynos_prev_bl_get_bootargs(void)
{
void *prev_bl_fdt_base = (void *)get_prev_bl_fdt_addr();
@ -89,102 +88,11 @@ static const char *exynos_prev_bl_get_bootargs(void)
return bootargs_prop->data;
}
static int exynos7870_fdt_match(struct exynos_board_info *board_info)
{
const char *prev_bl_bootargs;
int val, ret;
prev_bl_bootargs = exynos_prev_bl_get_bootargs();
if (!prev_bl_bootargs)
return -1;
/*
* Read the cmdline property which stores the
* bootloader/firmware version. An example value of the option
* can be: "J600GDXU3ARH5". This can be used to verify the model
* of the device.
*/
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.bootloader", &val);
if (ret < 0) {
log_err("%s: unable to find property for bootloader version (%d)\n",
__func__, ret);
return -1;
}
if (strncmp(prev_bl_bootargs + val, board_info->match_model,
strlen(board_info->match_model)))
return -1;
/*
* Read the cmdline property which stores the hardware revision.
* This is required to allow selecting one of multiple dtbs
* available of a single device, varying in hardware changes in
* different revisions.
*/
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.revision", &val);
if (ret < 0)
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.hw_rev", &val);
if (ret < 0) {
log_err("%s: unable to find property for bootloader revision (%d)\n",
__func__, ret);
return -1;
}
if (strtoul(prev_bl_bootargs + val, NULL, 10) > board_info->match_max_rev)
return -1;
/*
* Read the cmdline property which stores the serial number.
* Store this in the board info struct.
*/
ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.serialno", &val);
if (ret > 0)
strlcpy(board_info->serial, prev_bl_bootargs + val, ret);
return 0;
}
/*
* This array is used for matching the models and revisions with the
* devicetree used by U-Boot. This allows a single U-Boot to work on
* multiple devices.
*
* Entries are kept in lexicographical order of board SoCs, followed by
* board names.
*/
static struct exynos_board_info exynos_board_info_match[] = {
{
/* Samsung Galaxy A2 Core */
.name = "a2corelte",
.chip = "exynos7870",
.dram_bank_bases = exynos7870_common_dram_bank_bases,
.match = exynos7870_fdt_match,
.match_model = "A260",
.match_max_rev = U8_MAX,
}, {
/* Samsung Galaxy J6 */
.name = "j6lte",
.chip = "exynos7870",
.dram_bank_bases = exynos7870_common_dram_bank_bases,
.match = exynos7870_fdt_match,
.match_model = "J600",
.match_max_rev = U8_MAX,
}, {
/* Samsung Galaxy J7 Prime */
.name = "on7xelte",
.chip = "exynos7870",
.dram_bank_bases = exynos7870_common_dram_bank_bases,
.match = exynos7870_fdt_match,
.match_model = "G610",
.match_max_rev = U8_MAX,
},
};
static void exynos_parse_dram_banks(const struct exynos_board_info *board_info,
const void *fdt_base)
static void exynos_parse_dram_banks(const void *fdt_base)
{
u64 mem_addr, mem_size = 0;
u32 na, ns, i, j;
u32 na, ns, i;
int index = 1;
int offset;
if (fdt_check_header(fdt_base) < 0)
@ -199,6 +107,9 @@ static void exynos_parse_dram_banks(const struct exynos_board_info *board_info,
continue;
for (i = 0; ; i++) {
if (index > CONFIG_NR_DRAM_BANKS)
break;
mem_addr = fdtdec_get_addr_size_fixed(fdt_base, offset,
"reg", i, na, ns,
&mem_size, false);
@ -208,21 +119,134 @@ static void exynos_parse_dram_banks(const struct exynos_board_info *board_info,
if (!mem_size)
continue;
for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) {
if (board_info->dram_bank_bases[j] != mem_addr)
continue;
mem_map[j + 1].phys = mem_addr;
mem_map[j + 1].virt = mem_addr;
mem_map[j + 1].size = mem_size;
mem_map[j + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE;
break;
}
mem_map[index].phys = mem_addr;
mem_map[index].virt = mem_addr;
mem_map[index].size = mem_size;
mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE;
index++;
}
}
}
static void exynos_env_setup(void)
{
const char *bootargs = exynos_prev_bl_get_bootargs();
const char *dev_compatible, *soc_compatible;
char *ptr;
char buf[128];
int nr_compatibles;
int offset;
int ret;
if (bootargs) {
/* Read the cmdline property which stores the serial number. */
ret = cmdline_get_arg(bootargs, "androidboot.serialno", &offset);
if (ret > 0) {
strlcpy(buf, bootargs + offset, ret);
env_set("serial#", buf);
}
}
nr_compatibles = ofnode_read_string_count(ofnode_root(), "compatible");
if (nr_compatibles < 2) {
log_warning("%s: expected 2 or more compatible strings\n",
__func__);
return;
}
ret = ofnode_read_string_index(ofnode_root(), "compatible",
nr_compatibles - 1, &soc_compatible);
if (ret) {
log_warning("%s: failed to read SoC compatible\n",
__func__);
return;
}
ret = ofnode_read_string_index(ofnode_root(), "compatible", 0,
&dev_compatible);
if (ret) {
log_warning("%s: failed to read device compatible\n",
__func__);
return;
}
/* <manufacturer>,<soc> => platform = <soc> */
ptr = strchr(soc_compatible, ',');
if (ptr)
soc_compatible = ptr + 1;
env_set("platform", soc_compatible);
/* <manufacturer>,<codename> => board = <manufacturer>-<codename> */
strlcpy(buf, dev_compatible, sizeof(buf) - 1);
ptr = strchr(buf, ',');
if (ptr)
*ptr = '-';
env_set("board", buf);
/*
* NOTE: Board name usually goes as <manufacturer>-<codename>, but
* upstream device trees for Exynos SoCs are <soc>-<codename>.
* Extraction of <codename> from the board name is required.
*/
ptr = strchr(dev_compatible, ',');
if (ptr)
dev_compatible = ptr + 1;
/* EFI booting requires the path to correct DTB, specify it here. */
snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", soc_compatible,
dev_compatible);
env_set("fdtfile", buf);
}
static int exynos_blk_env_setup(void)
{
const char *blk_ifname;
int blk_dev = 0;
struct blk_desc *blk_desc;
struct disk_partition info = {0};
unsigned long largest_part_start = 0, largest_part_size = 0;
static char dfu_string[32];
int i;
blk_ifname = "mmc";
blk_desc = blk_get_dev(blk_ifname, blk_dev);
if (!blk_desc) {
log_err("%s: required mmc device not available\n", __func__);
return -ENODEV;
}
for (i = 1; i < CONFIG_EFI_PARTITION_ENTRIES_NUMBERS; i++) {
if (part_get_info(blk_desc, i, &info))
continue;
if (!update_info.dfu_string &&
!strncasecmp(info.name, "boot", strlen("boot"))) {
snprintf(dfu_string, sizeof(dfu_string),
"mmc %d=u-boot.bin part %d %d", blk_dev,
blk_dev, i);
update_info.dfu_string = dfu_string;
}
if (info.start > largest_part_size) {
largest_part_start = info.start;
largest_part_size = info.size;
}
}
if (largest_part_size) {
env_set("blkmap_blk_ifname", blk_ifname);
env_set_ulong("blkmap_blk_dev", blk_dev);
env_set_ulong("blkmap_blk_nr", largest_part_start);
env_set_hex("blkmap_size_r", largest_part_size);
} else {
log_warning("%s: no qualified partition for blkmap, skipping\n",
__func__);
}
return 0;
}
static int exynos_fastboot_setup(void)
{
struct blk_desc *blk_dev;
@ -270,42 +294,11 @@ static int exynos_fastboot_setup(void)
return 0;
}
int board_fit_config_name_match(const char *name)
int board_fdt_blob_setup(void **fdtp)
{
struct exynos_board_info *board_info;
char buf[128];
unsigned int i;
int ret;
/*
* Iterate over exynos_board_info_match[] to select the
* appropriate board info struct. If not found, exit.
*/
for (i = 0; i < ARRAY_SIZE(exynos_board_info_match); i++) {
board_info = exynos_board_info_match + i;
snprintf(buf, sizeof(buf), "%s-%s", board_info->chip,
board_info->name);
if (!strcmp(name, buf))
break;
}
if (i == ARRAY_SIZE(exynos_board_info_match))
return -1;
/*
* Execute match logic for the target board. This is separated
* as the process may be different for multiple boards.
*/
ret = board_info->match(board_info);
if (ret)
return ret;
/*
* Store the correct board info struct in gd->board_type to
* allow other functions to access it.
*/
gd->board_type = (ulong)board_info;
log_debug("%s: device detected: %s\n", __func__, name);
/* If internal FDT is not available, use the external FDT instead. */
if (fdt_check_header(*fdtp))
*fdtp = (void *)get_prev_bl_fdt_addr();
return 0;
}
@ -328,21 +321,7 @@ int timer_init(void)
int board_early_init_f(void)
{
const struct exynos_board_info *board_info;
if (!gd->board_type)
return -ENODATA;
board_info = (const struct exynos_board_info *)gd->board_type;
exynos_parse_dram_banks(board_info, gd->fdt_blob);
/*
* Some devices have multiple variants based on the amount of
* memory and internal storage. The lowest bank base has been
* observed to have the same memory range in all board variants.
* For variants with more memory, the previous bootloader should
* overlay the devicetree with the required extra memory ranges.
*/
exynos_parse_dram_banks(board_info, (const void *)get_prev_bl_fdt_addr());
exynos_parse_dram_banks(gd->fdt_blob);
return 0;
}
@ -381,23 +360,13 @@ int board_init(void)
int misc_init_r(void)
{
const struct exynos_board_info *board_info;
char buf[128];
int ret;
if (!gd->board_type)
return -ENODATA;
board_info = (const struct exynos_board_info *)gd->board_type;
exynos_env_setup();
env_set("platform", board_info->chip);
env_set("board", board_info->name);
if (strlen(board_info->serial))
env_set("serial#", board_info->serial);
/* EFI booting requires the path to correct dtb, specify it here. */
snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", board_info->chip,
board_info->name);
env_set("fdtfile", buf);
ret = exynos_blk_env_setup();
if (ret)
return ret;
return exynos_fastboot_setup();
}

View File

@ -2,6 +2,11 @@ stdin=serial,button-kbd
stdout=serial,vidconsole
stderr=serial,vidconsole
blkmapcmd=blkmap create root;
blkmap map root 0 ${blkmap_size_r} linear ${blkmap_blk_ifname} ${blkmap_blk_dev} ${blkmap_blk_nr}
preboot=run blkmapcmd
bootdelay=0
bootcmd=bootefi bootmgr; pause; bootmenu

View File

@ -1,7 +1,7 @@
config CMD_STBOARD
bool "stboard - command for OTP board information"
depends on ARCH_STM32MP
default y if TARGET_ST_STM32MP13X || TARGET_ST_STM32MP15X || TARGET_ST_STM32MP23X || TARGET_ST_STM32MP25X
default y if TARGET_ST_STM32MP13X || TARGET_ST_STM32MP15X || TARGET_ST_STM32MP21X || TARGET_ST_STM32MP23X || TARGET_ST_STM32MP25X
help
This compile the stboard command to
read and write the board in the OTP.

View File

@ -51,6 +51,7 @@ static bool check_stboard(u16 board)
0x1605, /* stm32mp25xx-dk */
0x1635,
0x1936, /* stm32mp25xx-ev1 */
0x2059, /* stm32mp21xx-dk */
};
for (i = 0; i < ARRAY_SIZE(st_board_id); i++)
@ -91,6 +92,11 @@ static int do_stboard(struct cmd_tbl *cmdtp, int flag, int argc,
DM_DRIVER_GET(stm32mp_bsec),
&dev);
if (ret) {
puts("Can't get BSEC device\n");
return CMD_RET_FAILURE;
}
ret = misc_read(dev, STM32_BSEC_OTP(BSEC_OTP_BOARD),
&otp, sizeof(otp));

View File

@ -1,3 +1,17 @@
if TARGET_ST_STM32MP21X
config SYS_BOARD
default "stm32mp2"
config SYS_VENDOR
default "st"
config SYS_CONFIG_NAME
default "stm32mp21_st_common"
source "board/st/common/Kconfig"
endif
if TARGET_ST_STM32MP23X
config SYS_BOARD

View File

@ -18,6 +18,7 @@ DECLARE_GLOBAL_DATA_PTR;
#include <u-boot/hash-checksum.h>
#define IMAGE_MAX_HASHED_NODES 100
#define FIT_MAX_HASH_PATH_BUF 4096
/**
* fit_region_make_list() - Make a list of image regions
@ -229,6 +230,179 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset,
return 0;
}
/**
* fit_config_add_hash() - Add hash nodes for one image to the node list
*
* Adds the image path, all its hash-* subnode paths, and its cipher
* subnode path (if present) to the packed buffer.
*
* @fit: FIT blob
* @image_noffset: Image node offset (e.g. /images/kernel-1)
* @node_inc: Array of path pointers to fill
* @count: Pointer to current count (updated on return)
* @max_nodes: Maximum entries in @node_inc
* @buf: Buffer for packed path strings
* @buf_used: Pointer to bytes used in @buf (updated on return)
* @buf_len: Total size of @buf
* Return: 0 on success, -ve on error
*/
static int fit_config_add_hash(const void *fit, int image_noffset,
char **node_inc, int *count, int max_nodes,
char *buf, int *buf_used, int buf_len)
{
int noffset, hash_count, ret, len;
if (*count >= max_nodes)
return -ENOSPC;
ret = fdt_get_path(fit, image_noffset, buf + *buf_used,
buf_len - *buf_used);
if (ret < 0)
return -ENOENT;
len = strlen(buf + *buf_used) + 1;
node_inc[(*count)++] = buf + *buf_used;
*buf_used += len;
/* Add all this image's hash subnodes */
hash_count = 0;
for (noffset = fdt_first_subnode(fit, image_noffset);
noffset >= 0;
noffset = fdt_next_subnode(fit, noffset)) {
const char *name = fit_get_name(fit, noffset, NULL);
if (strncmp(name, FIT_HASH_NODENAME,
strlen(FIT_HASH_NODENAME)))
continue;
if (*count >= max_nodes)
return -ENOSPC;
ret = fdt_get_path(fit, noffset, buf + *buf_used,
buf_len - *buf_used);
if (ret < 0)
return -ENOENT;
len = strlen(buf + *buf_used) + 1;
node_inc[(*count)++] = buf + *buf_used;
*buf_used += len;
hash_count++;
}
if (!hash_count) {
printf("No hash nodes in image '%s'\n",
fdt_get_name(fit, image_noffset, NULL));
return -ENOMSG;
}
/* Add this image's cipher node if present */
noffset = fdt_subnode_offset(fit, image_noffset, FIT_CIPHER_NODENAME);
if (noffset != -FDT_ERR_NOTFOUND) {
if (noffset < 0)
return -EIO;
if (*count >= max_nodes)
return -ENOSPC;
ret = fdt_get_path(fit, noffset, buf + *buf_used,
buf_len - *buf_used);
if (ret < 0)
return -ENOENT;
len = strlen(buf + *buf_used) + 1;
node_inc[(*count)++] = buf + *buf_used;
*buf_used += len;
}
return 0;
}
/**
* fit_config_get_hash_list() - Build the list of nodes to hash
*
* Works through every image referenced by the configuration and collects the
* node paths: root + config + all referenced images with their hash and
* cipher subnodes.
*
* Properties known not to be image references (description, compatible,
* default, load-only) are skipped, so any new image type is covered by default.
*
* @fit: FIT blob
* @conf_noffset: Configuration node offset
* @node_inc: Array to fill with path string pointers
* @max_nodes: Size of @node_inc array
* @buf: Buffer for packed null-terminated path strings
* @buf_len: Size of @buf
* Return: number of entries in @node_inc, or -ve on error
*/
static int fit_config_get_hash_list(const void *fit, int conf_noffset,
char **node_inc, int max_nodes,
char *buf, int buf_len)
{
const char *conf_name;
int image_count;
int prop_offset;
int used = 0;
int count = 0;
int ret, len;
conf_name = fit_get_name(fit, conf_noffset, NULL);
/* Always include the root node and the configuration node */
if (max_nodes < 2)
return -ENOSPC;
len = 2; /* "/" + nul */
if (len > buf_len)
return -ENOSPC;
strcpy(buf, "/");
node_inc[count++] = buf;
used += len;
len = snprintf(buf + used, buf_len - used, "%s/%s", FIT_CONFS_PATH,
conf_name) + 1;
if (used + len > buf_len)
return -ENOSPC;
node_inc[count++] = buf + used;
used += len;
/* Process each image referenced by the config */
image_count = 0;
fdt_for_each_property_offset(prop_offset, fit, conf_noffset) {
const char *prop_name;
int img_count, i;
fdt_getprop_by_offset(fit, prop_offset, &prop_name, NULL);
if (!prop_name)
continue;
/* Skip properties that are not image references */
if (!strcmp(prop_name, FIT_DESC_PROP) ||
!strcmp(prop_name, FIT_COMPAT_PROP) ||
!strcmp(prop_name, FIT_DEFAULT_PROP))
continue;
img_count = fdt_stringlist_count(fit, conf_noffset, prop_name);
for (i = 0; i < img_count; i++) {
int noffset;
noffset = fit_conf_get_prop_node_index(fit,
conf_noffset,
prop_name, i);
if (noffset < 0)
continue;
ret = fit_config_add_hash(fit, noffset, node_inc,
&count, max_nodes, buf, &used,
buf_len);
if (ret < 0)
return ret;
image_count++;
}
}
if (!image_count) {
printf("No images in config '%s'\n", conf_name);
return -ENOMSG;
}
return count;
}
/**
* fit_config_check_sig() - Check the signature of a config
*
@ -269,20 +443,16 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset,
FIT_DATA_POSITION_PROP,
FIT_DATA_OFFSET_PROP,
};
const char *prop, *end, *name;
char *node_inc[IMAGE_MAX_HASHED_NODES];
char hash_buf[FIT_MAX_HASH_PATH_BUF];
struct image_sign_info info;
const uint32_t *strings;
const char *config_name;
uint8_t *fit_value;
int fit_value_len;
bool found_config;
int max_regions;
int i, prop_len;
char path[200];
int count;
config_name = fit_get_name(fit, conf_noffset, NULL);
debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, key_blob,
fit_get_name(fit, noffset, NULL),
fit_get_name(key_blob, required_keynode, NULL));
@ -297,45 +467,12 @@ static int fit_config_check_sig(const void *fit, int noffset, int conf_noffset,
return -1;
}
/* Count the number of strings in the property */
prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len);
end = prop ? prop + prop_len : prop;
for (name = prop, count = 0; name < end; name++)
if (!*name)
count++;
if (!count) {
*err_msgp = "Can't get hashed-nodes property";
return -1;
}
if (prop && prop_len > 0 && prop[prop_len - 1] != '\0') {
*err_msgp = "hashed-nodes property must be null-terminated";
return -1;
}
/* Add a sanity check here since we are using the stack */
if (count > IMAGE_MAX_HASHED_NODES) {
*err_msgp = "Number of hashed nodes exceeds maximum";
return -1;
}
/* Create a list of node names from those strings */
char *node_inc[count];
debug("Hash nodes (%d):\n", count);
found_config = false;
for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) {
debug(" '%s'\n", name);
node_inc[i] = (char *)name;
if (!strncmp(FIT_CONFS_PATH, name, strlen(FIT_CONFS_PATH)) &&
name[sizeof(FIT_CONFS_PATH) - 1] == '/' &&
!strcmp(name + sizeof(FIT_CONFS_PATH), config_name)) {
debug(" (found config node %s)", config_name);
found_config = true;
}
}
if (!found_config) {
*err_msgp = "Selected config not in hashed nodes";
/* Build the node list from the config, ignoring hashed-nodes */
count = fit_config_get_hash_list(fit, conf_noffset,
node_inc, IMAGE_MAX_HASHED_NODES,
hash_buf, sizeof(hash_buf));
if (count < 0) {
*err_msgp = "Failed to build hash node list";
return -1;
}

View File

@ -2390,6 +2390,14 @@ static int boot_get_fdt_fit_into_buffer(const void *src, ulong srclen,
fdtsrcbuf = tmp;
}
/*
* Source data comes from FIT payload. Validate the blob against
* payload length before fdt_open_into() trusts header offsets/sizes.
*/
err = fdt_check_full(fdtsrcbuf, srclen);
if (err < 0)
goto out;
newdstlen = ALIGN(fdt_totalsize(fdtsrcbuf) + extra, SZ_4K);
min_dstlen = ALIGN(min_dstlen, SZ_4K);
if (newdstlen < min_dstlen)

View File

@ -85,6 +85,8 @@ long get_ram_size(long *base, long maxsize)
addr = base + cnt;
sync();
*addr = save[--i];
if (dcache_en)
dcache_flush_invalidate(addr);
}
return (0);
}
@ -93,6 +95,8 @@ long get_ram_size(long *base, long maxsize)
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if (dcache_en)
dcache_flush_invalidate(addr);
if (val != ~cnt) {
size = cnt * sizeof(long);
/*
@ -104,6 +108,8 @@ long get_ram_size(long *base, long maxsize)
cnt <<= 1) {
addr = base + cnt;
*addr = save[--i];
if (dcache_en)
dcache_flush_invalidate(addr);
}
/* warning: don't restore save_base in this case,
* it is already done in the loop because
@ -115,6 +121,8 @@ long get_ram_size(long *base, long maxsize)
}
}
*base = save_base;
if (dcache_en)
dcache_flush_invalidate(base);
return (maxsize);
}

View File

@ -556,11 +556,6 @@ enum bootmenu_key bootmenu_conv_key(int ichar)
case ' ':
key = BKEY_SPACE;
break;
case 'A' ... 'Z':
case 'a' ... 'z':
case '0' ... '9':
key = BKEY_SHORTCUT;
break;
default:
key = BKEY_NONE;
break;
@ -591,8 +586,10 @@ enum bootmenu_key bootmenu_loop(struct bootmenu_data *menu,
key = bootmenu_conv_key(c);
if (key == BKEY_SHORTCUT)
if (key == BKEY_NONE && isalnum(c)) {
key = BKEY_SHORTCUT;
cch->shortcut_key = bootmenu_conv_shortcut_key(menu, c);
}
return key;
}

View File

@ -31,6 +31,7 @@ CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI=y
CONFIG_SYS_PCI_64BIT=y
CONFIG_PCI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_BOOTSTD_FULL=y

View File

@ -12,7 +12,12 @@ CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x80000000
CONFIG_ARMV8_CNTFRQ_BROKEN=y
# CONFIG_PSCI_RESET is not set
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_CAPSULE_ON_DISK_EARLY=y
CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
CONFIG_BUTTON_CMD=y
CONFIG_USE_PREBOOT=y
CONFIG_SAVE_PREV_BL_FDT_ADDR=y
CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR=y
CONFIG_SYS_PBSIZE=1024
@ -25,11 +30,14 @@ CONFIG_CMD_POWEROFF=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_EFI_PARTITION=y
CONFIG_OF_UPSTREAM=y
CONFIG_OF_LIST="exynos/exynos7870-a2corelte exynos/exynos7870-j6lte exynos/exynos7870-on7xelte"
CONFIG_MULTI_DTB_FIT=y
CONFIG_OF_UPSTREAM_BUILD_VENDOR=y
CONFIG_OF_BOARD=y
CONFIG_BLKMAP=y
CONFIG_BUTTON=y
CONFIG_BUTTON_REMAP_PHONE_KEYS=y
CONFIG_CLK_EXYNOS7870=y
CONFIG_DFU_MMC=y
CONFIG_SYS_DFU_DATA_BUF_SIZE=0x200000
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0xdead0000
CONFIG_FASTBOOT_FLASH=y

View File

@ -30,6 +30,7 @@ CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI=y
# CONFIG_PSCI_RESET is not set
CONFIG_SYS_PCI_64BIT=y
CONFIG_PCI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_BOOTSTD_FULL=y

View File

@ -27,6 +27,7 @@ CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI=y
CONFIG_SYS_PCI_64BIT=y
CONFIG_PCI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_BOOTSTD_FULL=y

View File

@ -28,6 +28,8 @@ CONFIG_SPL_FS_FAT=y
CONFIG_SPL_LIBDISK_SUPPORT=y
CONFIG_SPL_SPI_FLASH_SUPPORT=y
CONFIG_SPL_SPI=y
CONFIG_SYS_PCI_64BIT=y
CONFIG_PCI=y
CONFIG_EFI_SET_TIME=y
CONFIG_BOOTSTD_FULL=y
CONFIG_BOOTCOMMAND="run envboot; bootflow scan -lb"
@ -56,6 +58,7 @@ CONFIG_SPL_YMODEM_SUPPORT=y
CONFIG_CMD_BOOTEFI_SELFTEST=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_MTD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_OF_CONTROL=y
@ -123,6 +126,9 @@ CONFIG_MUX_MMIO=y
CONFIG_PHY_TI_DP83867=y
CONFIG_PHY_FIXED=y
CONFIG_TI_AM65_CPSW_NUSS=y
CONFIG_NVME_PCI=y
CONFIG_PCI_CONFIG_HOST_BRIDGE=y
CONFIG_PCIE_CDNS_TI=y
CONFIG_PCI_ENDPOINT=y
CONFIG_PCIE_CDNS_TI_EP=y
CONFIG_PHY=y

View File

@ -0,0 +1,78 @@
CONFIG_ARM=y
CONFIG_ARCH_STM32MP=y
CONFIG_SYS_MALLOC_F_LEN=0x600000
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x90000000
CONFIG_ENV_OFFSET=0x900000
CONFIG_ENV_SECT_SIZE=0x40000
CONFIG_DEFAULT_DEVICE_TREE="st/stm32mp215f-dk"
CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x84000000
CONFIG_STM32MP21X=y
CONFIG_DDR_CACHEABLE_SIZE=0x10000000
CONFIG_CMD_STM32KEY=y
CONFIG_TARGET_ST_STM32MP21X=y
CONFIG_SYS_MEMTEST_START=0x84000000
CONFIG_SYS_MEMTEST_END=0x88000000
CONFIG_API=y
CONFIG_SYS_MMC_MAX_DEVICE=3
CONFIG_FIT=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=1
CONFIG_BOOTCOMMAND="run bootcmd_stm32mp"
CONFIG_SYS_PROMPT="STM32MP> "
# CONFIG_CMD_BDI is not set
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_ADTIMG=y
# CONFIG_CMD_ELF is not set
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_CLK=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_LOADB is not set
CONFIG_CMD_MMC=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIME=y
CONFIG_CMD_RNG=y
CONFIG_CMD_TIMER=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_LOG=y
CONFIG_CMD_UBI=y
CONFIG_OF_LIVE=y
CONFIG_OF_UPSTREAM_BUILD_VENDOR=y
CONFIG_OF_UPSTREAM_VENDOR="st"
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_ENV_IS_IN_UBI=y
CONFIG_ENV_UBI_PART="UBI"
CONFIG_ENV_UBI_VOLUME="uboot_config"
CONFIG_NO_NET=y
CONFIG_SYS_64BIT_LBA=y
CONFIG_BUTTON=y
CONFIG_BUTTON_GPIO=y
CONFIG_GPIO_HOG=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_STM32F7=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_STM32_SDMMC2=y
CONFIG_MTD=y
CONFIG_USE_SYS_MAX_FLASH_BANKS=y
CONFIG_SPI_FLASH=y
CONFIG_PINCONF=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_RAM=y
# CONFIG_STM32MP1_DDR is not set
CONFIG_DM_RNG=y
CONFIG_SERIAL_RX_BUFFER=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
# CONFIG_OPTEE_TA_AVB is not set
CONFIG_WDT=y
CONFIG_WDT_STM32MP=y
CONFIG_WDT_ARM_SMC=y
# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
CONFIG_ERRNO_STR=y

View File

@ -9,6 +9,7 @@ CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x84000000
CONFIG_STM32MP25X=y
CONFIG_DDR_CACHEABLE_SIZE=0x10000000
CONFIG_CMD_STM32KEY=y
CONFIG_MFD_STM32_TIMERS=y
CONFIG_ENV_OFFSET_REDUND=0x940000
CONFIG_TARGET_ST_STM32MP25X=y

View File

@ -25,12 +25,13 @@ If a cross-compiler is required, install it and set it up like so:
export CROSS_COMPILE=aarch64-linux-gnu-
Then, run the following commands to build U-Boot:
Then, run the following commands to build U-Boot (replace ``<dtb>`` with the
upstream DTB path for the target device):
.. prompt:: bash $
make O=.output exynos-mobile_defconfig
make O=.output -j$(nproc)
make DEVICE_TREE=<dtb> O=.output -j$(nproc)
If successful, the U-Boot binary will be present in ``.output/u-boot.bin``.

View File

@ -6,54 +6,20 @@ Samsung Exynos 7870 Boards
Preparation
-----------
Create the following device tree (named ``stub.dts``)
.. code-block:: devicetree
/dts-v1/;
/ {
compatible = "samsung,exynos7870";
#address-cells = <2>;
#size-cells = <1>;
model_info-chip = <7870>;
model_info-hw_rev = <0>;
model_info-hw_rev_end = <255>;
chosen {
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0>;
};
memory@100000000 {
device_type = "memory";
reg = <0x1 0x00000000 0x0>;
};
};
The chosen node and memory ranges are populated by S-BOOT. A certain device
model may have multiple variants, with differing amounts of RAM and storage. The
RAM capacity information is graciously provided by S-BOOT's device tree
overlays.
Compile it to a device tree blob, then pack it in the QCDT format [1]_ using
``dtbTool-exynos`` [2]_ by issuing the following commands:
Pack the device tree blob in the QCDT format [1]_ using ``dtbTool-exynos`` [2]_
by issuing the following commands:
.. prompt:: bash $
dtc -I dts -O dtb -o stub.dtb stub.dts
dtbTool-exynos -o stub-dt.img stub.dtb
dtbTool-exynos -o stub-dt.img .output/u-boot.dtb
Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image:
.. prompt:: bash $
mkbootimg -o u-boot.img \
--kernel .output/u-boot.bin \
--kernel .output/u-boot-nodtb.bin \
--dt stub-dt.img
Offsets are not provided to ``mkbootimg`` as S-BOOT ignores them.

View File

@ -77,7 +77,7 @@ For the next scheduled release, release candidates were made on:
* U-Boot |next_ver|-rc3 was released on Mon 23 February 2026.
.. * U-Boot |next_ver|-rc4 was released on Mon 09 March 2026.
* U-Boot |next_ver|-rc4 was released on Mon 09 March 2026.
.. * U-Boot |next_ver|-rc5 was released on Mon 23 March 2026.

View File

@ -353,20 +353,27 @@ meantime.
Details
-------
The signature node contains a property ('hashed-nodes') which lists all the
nodes that the signature was made over. The image is walked in order and each
tag processed as follows:
nodes that the signature was made over. The signer (mkimage) writes this
property as a record of what was included in the hash. During verification,
however, U-Boot does not read 'hashed-nodes'. Instead it rebuilds the node
list from the configuration's own image references (kernel, fdt, ramdisk,
etc.), since 'hashed-nodes' is not itself covered by the signature. The
rebuilt list always includes the root node, the configuration node, each
referenced image node and its hash/cipher subnodes.
The image is walked in order and each tag processed as follows:
DTB_BEGIN_NODE
The tag and the following name are included in the signature
if the node or its parent are present in 'hashed-nodes'
if the node or its parent are present in the node list
DTB_END_NODE
The tag is included in the signature if the node or its parent
are present in 'hashed-nodes'
are present in the node list
DTB_PROPERTY
The tag, the length word, the offset in the string table, and
the data are all included if the current node is present in 'hashed-nodes'
the data are all included if the current node is present in the node list
and the property name is not 'data'.
DTB_END
@ -374,7 +381,7 @@ DTB_END
DTB_NOP
The tag is included in the signature if the current node is present
in 'hashed-nodes'
in the node list
In addition, the signature contains a property 'hashed-strings' which contains
the offset and length in the string table of the strings that are to be

View File

@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
# Written and/or maintained by Timesys Corporation
#
# Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
# Contact: Greg Malysa <greg.malysa@timesys.com>
# Written by Timesys Corporation
#
config COMMON_CLK_ADI_SHARED

View File

@ -2,10 +2,7 @@
#
# (C) Copyright 2022 - Analog Devices, Inc.
#
# Written and/or maintained by Timesys Corporation
#
# Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
# Contact: Greg Malysa <greg.malysa@timesys.com>
# Written by Timesys Corporation
#
obj-$(CONFIG_COMMON_CLK_ADI_SHARED) += clk-shared.o clk-adi-pll.o

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*/

View File

@ -2,7 +2,7 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
*

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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;
/* Use the control FDT by default */
return (void *)gd->fdt_blob;
assert(fdt);
return fdt;
}
/**

View File

@ -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.

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
* Contact: Ian Roberts <ian.roberts@timesys.com>
*
*/
#include <dm.h>

View File

@ -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);

View File

@ -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);

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*
* Based on Michael Hennerich's Linux driver:
* Michael Hennerich <michael.hennerich@analog.com>

View File

@ -2,10 +2,9 @@
/*
* (C) Copyright 2022 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
* Additional Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
*/
#include <dm.h>

View File

@ -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,

View File

@ -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 {

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*/
#include <clk.h>

View File

@ -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++) {

View File

@ -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 <nathan.morrison@timesys.com>
* Contact: Greg Malysa <greg.malysa@timesys.com>
*
* Based on Rockchip's sdhci.c file
*/

View File

@ -2,10 +2,9 @@
/**
* (C) Copyright 2024 - Analog Devices, Inc.
*
* Written and/or maintained by Timesys Corporation
* Written by Timesys Corporation
*
* Author: Greg Malysa <greg.malysa@timesys.com>
* Additional Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
*/
#include <clk.h>

View File

@ -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,
},
{},
};

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More