Skip to content
Snippets Groups Projects
Commit 851e7f77 authored by Thomas Richard's avatar Thomas Richard Committed by Hauke Mehrtens
Browse files

stm32: add new stm32 target


New stm32 target introduces support for stm32mp1 based devices.
For now it includes an initial support of the STM32MP135F-DK device.
The specifications bellow only list supported features.

Specifications
--------------

SOC: STM32MP135FAF7
RAM: 512 MiB
Storage: SD Card
Ethernet: 2x 100 Mbps
Wireless: 2.4GHz Cypress CYW43455 (802.11b/g/n)
LEDs: Heartbeat (Blue)
Buttons: 1x Reset, 1x User (USER2)
USB: 4x 2.0 Type-A

Signed-off-by: default avatarThomas Richard <thomas.richard@bootlin.com>
Link: https://github.com/openwrt/openwrt/pull/16716


Signed-off-by: default avatarHauke Mehrtens <hauke@hauke-m.de>
parent e109831e
No related branches found
No related tags found
No related merge requests found
Showing
with 3203 additions and 0 deletions
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2024 Bootlin
#
include $(TOPDIR)/rules.mk
BOARD:=stm32
BOARDNAME:=STMicroelectronics STM32
FEATURES:=boot-part emmc ext4 gpio rtc usb
SUBTARGETS:=stm32mp1
CPU_TYPE:=
KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += blockdev kmod-gpio-button-hotplug
define Target/Description
Build firmware image for STM32 devices
endef
$(eval $(call BuildTarget))
. /lib/functions/uci-defaults.sh
. /lib/functions.sh
. /lib/functions/system.sh
board_config_update
board=$(board_name)
case "$board" in
st,stm32mp135f-dk)
ucidef_set_interfaces_lan_wan "eth0" "eth1"
;;
esac
board_config_flush
exit 0
move_config() {
. /lib/upgrade/common.sh
. /lib/upgrade/platform.sh
if export_bootdevice && export_partdevice partdev 4; then
mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
if [ -f "/mnt/$BACKUP_FILE" ]; then
mv -f "/mnt/$BACKUP_FILE" /
fi
umount /mnt
fi
}
boot_hook_add preinit_mount_root move_config
REQUIRE_IMAGE_METADATA=1
UBOOT_ENV_PART=3
BOOT_PART=4
ROOTFS_PART=5
RAMFS_COPY_BIN='blockdev'
export_bootdevice() {
local cmdline uuid blockdev uevent line class
local MAJOR MINOR DEVNAME DEVTYPE
local rootpart="$(cmdline_get_var root)"
case "$rootpart" in
PARTUUID=????????-????-????-????-??????????0?/PARTNROFF=1 | \
PARTUUID=????????-????-????-????-??????????05)
uuid="${rootpart#PARTUUID=}"
uuid="${uuid%/PARTNROFF=1}"
uuid="${uuid%0?}00"
for disk in $(find /dev -type b); do
set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then
uevent="/sys/class/block/${disk##*/}/uevent"
break
fi
done
;;
esac
if [ -e "$uevent" ]; then
while read line; do
export -n "$line"
done < "$uevent"
export BOOTDEV_MAJOR=$MAJOR
export BOOTDEV_MINOR=$MINOR
return 0
fi
return 1
}
platform_check_image() {
local diskdev partdev diff
[ "$#" -gt 1 ] && return 1
export_bootdevice && export_partdevice diskdev 0 || {
v "platform_check_image: Unable to determine upgrade device"
return 1
}
get_partitions "/dev/$diskdev" bootdisk
v "Extract the boot sector from the image"
get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
get_partitions /tmp/image.bs image
#compare tables
diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
if [ -n "$diff" ]; then
echo "Partition layout has changed. Full image will be written."
ask_bool 0 "Abort" && exit 1
return 0
fi
}
platform_do_upgrade() {
local diskdev partdev diff partlabel
export_bootdevice && export_partdevice diskdev 0 || {
v "platform_do_upgrade: Unable to determine upgrade device"
return 1
}
sync
if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
get_partitions "/dev/$diskdev" bootdisk
v "Extract boot sector from the image"
get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
get_partitions /tmp/image.bs image
#compare tables
diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
else
diff=1
fi
if [ -n "$diff" ]; then
rm -rf /tmp/ubootenv
if export_partdevice partdev $UBOOT_ENV_PART; then
v "Saving u-boot env (/dev/$partdev) before to write image"
get_image_dd "/dev/$partdev" of=/tmp/ubootenv
fi
v "Writing image to /dev/$diskdev..."
get_image_dd "$1" of="/dev/$diskdev" conv=fsync
blockdev --rereadpt "/dev/$diskdev"
[ -f /tmp/ubootenv ] && {
# iterate over each partition from the image to find the
# u-boot-env partition and restore u-boot env.
while read part start size; do
if export_partdevice partdev $part; then
while read line; do
eval "local l$line"
done < "/sys/class/block/$partdev/uevent"
[ "$lPARTNAME" = "u-boot-env" ] || continue
v "Writting u-boot env to /dev/$partdev"
get_image_dd /tmp/ubootenv of="/dev/$partdev" conv=fsync
return 0
fi
done < /tmp/partmap.image
}
return 0
fi
#iterate over each partition from the image and write it to the boot disk
while read part start size; do
if export_partdevice partdev $part; then
# do not erase u-boot env
[ "$part" = "$UBOOT_ENV_PART" ] && continue
v "Writing image to /dev/$partdev..."
v "Normal partition, doing DD"
get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \
count="$size" conv=fsync
else
v "Unable to find partition $part device, skipped."
fi
done < /tmp/partmap.image
if export_partdevice partdev "$BOOT_PART"; then
mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
local partuuid="$(cmdline_get_var root)"
v "Setting rootfs ${partuuid}"
sed -i "s/PARTUUID=[a-f0-9-]\+/${partuuid}/ig" \
/mnt/extlinux/extlinux.conf
umount /mnt
fi
}
platform_copy_config() {
local partdev
# Iterate over each partition from the image to find the boot partition
# and copy the config tarball.
# The partlabel is used to find the partition.
# An hardcoded partition number cannot be used, as it could be wrong if
# the partition table changed, and the full image was written.
while read part start size; do
# config is copied in the boot partition, as for squashfs image, the
# rootfs partition is not writable.
if export_partdevice partdev "$part"; then
while read line; do
eval "local l$line"
done < "/sys/class/block/$partdev/uevent"
[ "$lPARTNAME" = "boot" ] || continue
mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
umount /mnt
return 0
else
v "ERROR: Unable to find partition to copy config data to"
fi
done < /tmp/partmap.image
}
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2024 Bootlin
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
define Build/boot-img-ext4
rm -fR $@.boot
mkdir -p $@.boot
$(foreach dts,$(DEVICE_DTS), $(CP) $(KDIR)/image-$(dts).dtb $@.boot/$(dts).dtb;)
$(CP) $(IMAGE_KERNEL) $@.boot/$(KERNEL_IMG)
$(INSTALL_DIR) $@.boot/extlinux
$(CP) ./extlinux.conf $@.boot/extlinux/
$(SED) 's/@KERNEL@/$(KERNEL_IMG)/' $@.boot/extlinux/extlinux.conf
$(SED) 's/@DEVICE@/$(DEVICE_NAME)/' $@.boot/extlinux/extlinux.conf
$(SED) 's/@DTS@/$(DEVICE_DTS)/' $@.boot/extlinux/extlinux.conf
$(SED) 's/@ROOT@/PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/05/')/' $@.boot/extlinux/extlinux.conf
make_ext4fs -J -L kernel -l $(CONFIG_TARGET_KERNEL_PARTSIZE)M \
$(if $(SOURCE_DATE_EPOCH),-T $(SOURCE_DATE_EPOCH)) \
$@.bootimg $@.boot
endef
define Build/sdcard-img
GUID=$(IMG_PART_DISKGUID) ./gen_stm32_sdcard_img.sh \
$@ $(STAGING_DIR_IMAGE)/tf-a-$(DEVICE_NAME).stm32 \
$(STAGING_DIR_IMAGE)/fip-$(DEVICE_NAME).bin $@.bootimg $(IMAGE_ROOTFS) \
$(ENV_SIZE) $(CONFIG_TARGET_KERNEL_PARTSIZE) $(CONFIG_TARGET_ROOTFS_PARTSIZE)
endef
define Device/Default
PROFILES := Default
DEVICE_VENDOR := STMicroelectronics
IMAGES := factory.img.gz sysupgrade.img.gz
IMAGE/factory.img.gz := boot-img-ext4 | sdcard-img | gzip
IMAGE/sysupgrade.img.gz := boot-img-ext4 | sdcard-img | gzip | append-metadata
KERNEL := kernel-bin
KERNEL_NAME := zImage
KERNEL_IMG := zImage
DEVICE_DTS_DIR := $(DTS_DIR)/st
ENV_SIZE := 0x200000
DEVICE_PACKAGES := kmod-brcmfmac \
murata-firmware-43430-sdio \
murata-nvram-43430-sdio \
wpad-basic-mbedtls \
kmod-phy-stm32-usbphyc \
kmod-usb2 \
kmod-usb-storage \
kmod-usb-ledtrig-usbport \
-mtd
endef
define Device/stm32mp135f-dk
DEVICE_MODEL := STM32MP135F-DK
DEVICE_DTS := stm32mp135f-dk
SUPPORTED_DEVICES := st,stm32mp135f-dk
endef
TARGET_DEVICES += stm32mp135f-dk
$(eval $(call BuildImage))
label @DEVICE@-openwrt
kernel /@KERNEL@
devicetree /@DTS@.dtb
append root=@ROOT@ rootwait
#!/bin/sh
# Copyright (C) 2024 Bootlin
set -ex
[ $# -eq 8 ] || {
echo "SYNTAX: $0 <file> <fsbl> <fip> <bootfs image> <rootfs image> <env size> <bootfs size> <rootfs size>"
exit 1
}
OUTPUT="${1}"
FSBL="${2}"
FIP="${3}"
BOOTFS="${4}"
ROOTFS="${5}"
ENVSIZE="$((${6} / 1024))"
BOOTFSSIZE="${7}"
ROOTFSSIZE="${8}"
set $(ptgen -o "${OUTPUT}" -g -a 4 -l 2048 -G ${GUID} -N fsbla -p 2M -N fip -p 3M -N u-boot-env -p "${ENVSIZE}" -N boot -p${BOOTFSSIZE}M -N rootfs -p ${ROOTFSSIZE}M)
FSBLAOFFSET="$((${1} / 512))"
FSBLASIZE="$((${2} / 512))"
FIPOFFSET="$((${3} / 512))"
FIPSIZE="$((${4} / 512))"
ENVOFFSET="$((${5} / 512))"
ENVSIZE="$((${6} / 512))"
BOOTFSOFFSET="$((${7} / 512))"
BOOTFSSIZE="$((${8} / 512))"
ROOTFSOFFSET="$((${9} / 512))"
ROOTFSSIZE="$((${10} / 512))"
dd bs=512 if="${FSBL}" of="${OUTPUT}" seek="${FSBLAOFFSET}" conv=notrunc
dd bs=512 if="${FIP}" of="${OUTPUT}" seek="${FIPOFFSET}" conv=notrunc
dd bs=512 if=/dev/zero of="${OUTPUT}" seek="${ENVOFFSET}" count="${ENVSIZE}" conv=notrunc
dd bs=512 if="${BOOTFS}" of="${OUTPUT}" seek="${BOOTFSOFFSET}" conv=notrunc
dd bs=512 if="${ROOTFS}" of="${OUTPUT}" seek="${ROOTFSOFFSET}" conv=notrunc
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2024 Bootlin
define KernelPackage/phy-stm32-usbphyc
TITLE:=STM32 USB HS PHY Controller driver
DEPENDS:=@TARGET_stm32
KCONFIG:=CONFIG_PHY_STM32_USBPHYC
FILES:=$(LINUX_DIR)/drivers/phy/st/phy-stm32-usbphyc.ko
AUTOLOAD:=$(call AutoProbe,phy-stm32-usbphyc,)
endef
define KernelPackage/phy-stm32-usbphyc/description
Kernel module for STM32 USB HS PHY Controller
endef
$(eval $(call KernelPackage,phy-stm32-usbphyc))
define KernelPackage/bxcan
TITLE:=STM32 Basic Extended CAN (bxCAN) devices
KCONFIG:=CONFIG_CAN_BXCAN
FILES=$(LINUX_DIR)/drivers/net/can/bxcan.ko
AUTOLOAD:=$(call AutoProbe,bxcan)
$(call AddDepends/can,@TARGET_stm32)
endef
$(eval $(call KernelPackage,bxcan))
define KernelPackage/spi-stm32
SUBMENU=$(SPI_MENU)
TITLE:=STM32 SPI controller
DEPENDS:=@TARGET_stm32
KCONFIG:=CONFIG_SPI_STM32 \
CONFIG_SPI=y \
CONFIG_SPI_MASTER=y \
CONFIG_SPI_SLAVE_TIME=n \
CONFIG_SPI_SLAVE_SYSTEM_CONTROL=n
FILES=$(LINUX_DIR)/drivers/spi/spi-stm32.ko
AUTOLOAD:=$(call AutoProbe,spi-stm32)
endef
define KernelPackage/spi-stm32/description
SPI driver for STMicroelectronics STM32 SoCs.
endef
$(eval $(call KernelPackage,spi-stm32))
define KernelPackage/scmi-hwmon
TITLE:=ARM SCMI Sensors
KCONFIG:=CONFIG_SENSORS_ARM_SCMI
FILES:=$(LINUX_DIR)/drivers/hwmon/scmi-hwmon.ko
AUTOLOAD:=$(call AutoProbe,scmi-hwmon)
$(call AddDepends/hwmon,@TARGET_stm32 +kmod-thermal)
endef
$(eval $(call KernelPackage,scmi-hwmon))
define KernelPackage/stm32-dcmi
TITLE:=STM32 Digital Camera Memory Interface support
KCONFIG:=CONFIG_VIDEO_STM32_DCMI
FILES:=$(LINUX_DIR)/drivers/media/platform/st/stm32/stm32-dcmi.ko
AUTOLOAD:=$(call AutoProbe,stm32-dcmi)
$(call AddDepends/video,@TARGET_stm32 +kmod-video-videobuf2 +kmod-video-dma-contig +kmod-video-async +kmod-video-fwnode)
endef
$(eval $(call KernelPackage,stm32-dcmi))
define KernelPackage/sound-soc-stm32-sai
TITLE:=STM32 SAI interface (Serial Audio Interface) support
KCONFIG:=CONFIG_SND_SOC_STM32_SAI
FILES:=$(LINUX_DIR)/sound/soc/stm/snd-soc-stm32-sai-sub.ko \
$(LINUX_DIR)/sound/soc/stm/snd-soc-stm32-sai.ko
AUTOLOAD:=$(call AutoProbe,snd-soc-stm32-sai-sub snd-soc-stm32-sai)
$(call AddDepends/sound,@TARGET_stm32 +kmod-sound-soc-core)
endef
$(eval $(call KernelPackage,sound-soc-stm32-sai))
define KernelPackage/sound-soc-stm32-i2s
TITLE:=STM32 I2S interface (SPI/I2S block) support
KCONFIG:=CONFIG_SND_SOC_STM32_I2S
FILES:=$(LINUX_DIR)/sound/soc/stm/snd-soc-stm32-i2s.ko
AUTOLOAD:=$(call AutoProbe,snd-soc-stm32-i2s)
$(call AddDepends/sound,@TARGET_stm32 +kmod-sound-soc-core)
endef
$(eval $(call KernelPackage,sound-soc-stm32-i2s))
define KernelPackage/sound-soc-stm32-spdifrx
TITLE:=STM32 S/PDIF receiver (SPDIFRX) support
KCONFIG:=CONFIG_SND_SOC_STM32_SPDIFRX
FILES:=$(LINUX_DIR)/sound/soc/stm/snd-soc-stm32-spdifrx.ko
AUTOLOAD:=$(call AutoProbe,snd-soc-stm32-spdifrx)
$(call AddDepends/sound,@TARGET_stm32 +kmod-sound-soc-core)
endef
$(eval $(call KernelPackage,sound-soc-stm32-spdifrx))
define KernelPackage/sound-soc-stm32-dfsdm
TITLE:=SoC Audio support for STM32 DFSDM
KCONFIG:=CONFIG_SND_SOC_STM32_DFSDM
FILES:=$(LINUX_DIR)/sound/soc/stm/stm32_adfsdm.ko
AUTOLOAD:=$(call AutoProbe,stm32_adfsdm)
$(call AddDepends/sound,@TARGET_stm32 +kmod-sound-soc-core +kmod-stm32-dfsdm-adc +kmod-industrialio-buffer-cb)
endef
$(eval $(call KernelPackage,sound-soc-stm32-dfsdm))
define KernelPackage/stm32-timers
TITLE:=STM32 Timers
DEPENDS:=@TARGET_stm32 +kmod-mfd
KCONFIG:=CONFIG_MFD_STM32_TIMERS
FILES:=$(LINUX_DIR)/drivers/mfd/stm32-timers.ko
AUTOLOAD:=$(call AutoProbe,stm32-timers)
endef
$(eval $(call KernelPackage,stm32-timers))
define KernelPackage/stm32-timer-trigger
TITLE:=STM32 Timer Trigger
KCONFIG:=CONFIG_IIO_STM32_TIMER_TRIGGER
FILES:=$(LINUX_DIR)/drivers/iio/trigger/stm32-timer-trigger.ko
AUTOLOAD:=$(call AutoProbe,stm32-timer-trigger)
$(call AddDepends/iio,@TARGET_stm32 +kmod-stm32-timers)
endef
$(eval $(call KernelPackage,stm32-timer-trigger))
define KernelPackage/stm32-adc
TITLE:=STM32 ADC
KCONFIG:=CONFIG_STM32_ADC_CORE \
CONFIG_STM32_ADC
FILES:=$(LINUX_DIR)/drivers/iio/adc/stm32-adc-core.ko \
$(LINUX_DIR)/drivers/iio/adc/stm32-adc.ko
AUTOLOAD:=$(call AutoProbe,stm32-adc-core stm32-adc)
$(call AddDepends/iio,@TARGET_stm32 +kmod-stm32-timer-trigger +kmod-industrialio-triggered-buffer)
endef
$(eval $(call KernelPackage,stm32-adc))
define KernelPackage/stm32-dfsdm-adc
TITLE:=STM32 DFSDM ADC
KCONFIG:=CONFIG_STM32_DFSDM_CORE \
CONFIG_STM32_DFSDM_ADC
FILES:=$(LINUX_DIR)/drivers/iio/adc/stm32-dfsdm-core.ko \
$(LINUX_DIR)/drivers/iio/adc/stm32-dfsdm-adc.ko
AUTOLOAD:=$(call AutoProbe,stm32-dfsdm-core stm32-dfsdm-adc)
$(call AddDepends/iio,@TARGET_stm32 +kmod-stm32-timer-trigger +kmod-industrialio-triggered-buffer +kmod-industrialio-hw-consumer)
endef
$(eval $(call KernelPackage,stm32-dfsdm-adc))
define KernelPackage/scmi-iio
TITLE:=IIO SCMI
KCONFIG=CONFIG_IIO_SCMI
FILES:=$(LINUX_DIR)/drivers/iio/common/scmi_sensors/scmi_iio.ko
AUTOLOAD:=$(call AutoProbe,scmi_iio)
$(call AddDepends/iio,@TARGET_stm32 +kmod-iio-kfifo-buf)
endef
$(eval $(call KernelPackage,scmi-iio))
define KernelPackage/stm32-dac
TITLE:=STM32 DAC
DEPENDS:=@TARGET_stm32
KCONFIG:=CONFIG_STM32_DAC_CORE \
CONFIG_STM32_DAC
FILES:=$(LINUX_DIR)/drivers/iio/dac/stm32-dac-core.ko \
$(LINUX_DIR)/drivers/iio/dac/stm32-dac.ko
AUTOLOAD:=$(call AutoProbe,stm32-dac-core stm32-dac)
$(call AddDepends/iio,@TARGET_stm32)
endef
$(eval $(call KernelPackage,stm32-dac))
define KernelPackage/nvmem-stm32-romem
SUBMENU:=$(OTHER_MENU)
TITLE:=STM32 factory-programmed memory support
DEPENDS:=@TARGET_stm32
KCONFIG:=CONFIG_NVMEM_STM32_ROMEM
FILES:=$(LINUX_DIR)/drivers/nvmem/nvmem_stm32_romem.ko
AUTOLOAD:=$(call AutoProbe,nvmem-stm32-romem)
endef
$(eval $(call KernelPackage,nvmem-stm32-romem))
define KernelPackage/stm32-crc32
TITLE:=Support for STM32 crc accelerators
KCONFIG:=CONFIG_CRYPTO_DEV_STM32_CRC \
CONFIG_CRYPTO_HW=y
FILES:=$(LINUX_DIR)/drivers/crypto/stm32/stm32-crc32.ko
AUTOLOAD:=$(call AutoProbe,stm32-crc32)
$(call AddDepends/crypto,@TARGET_stm32 +kmod-crypto-crc32)
endef
$(eval $(call KernelPackage,stm32-crc32))
define KernelPackage/stm32-hash
SUBMENU:=$(CRYPTO_MENU)
TITLE:=Support for STM32 hash accelerators
DEPENDS:=@TARGET_stm32 \
+kmod-crypto-md5 \
+kmod-crypto-sha1 \
+kmod-crypto-sha256 \
+kmod-crypto-sha3 \
+kmod-crypto-rsa
KCONFIG:=CONFIG_CRYPTO_DEV_STM32_HASH \
CONFIG_CRYPTO_ENGINE=y \
FILES:=$(LINUX_DIR)/drivers/crypto/stm32/stm32-hash.ko
AUTOLOAD:=$(call AutoProbe,stm32-hash)
endef
$(eval $(call KernelPackage,stm32-hash))
define KernelPackage/stm32-cryp
TITLE:=Support for STM32 cryp accelerators
KCONFIG:=CONFIG_CRYPTO_DEV_STM32_CRYP \
CONFIG_CRYPTO_LIB_DES=y
FILES:=$(LINUX_DIR)/drivers/crypto/stm32/stm32-cryp.ko
AUTOLOAD:=$(call AutoProbe,stm32-cryp)
$(call AddDepends/crypto,@TARGET_stm32 +kmod-crypto-hash +kmod-crypto-des +kmod-crypto-engine)
endef
$(eval $(call KernelPackage,stm32-cryp))
define KernelPackage/st-thermal
SUBMENU:=$(OTHER_MENU)
TITLE:=Thermal sensors on STMicroelectronics STi series of SoCs
KCONFIG:=CONFIG_ST_THERMAL \
CONFIG_ST_THERMAL_MEMMAP
DEPENDS:=@TARGET_stm32 +kmod-thermal
FILES:=$(LINUX_DIR)/drivers/thermal/st/st_thermal.ko \
$(LINUX_DIR)/drivers/thermal/st/st_thermal_memmap.ko
AUTOLOAD:=$(call AutoProbe,st_thermal st_thermal_memmap)
endef
$(eval $(call KernelPackage,st-thermal))
From 1ddced59ac1f7c739f21e930d87b126a30c561bb Mon Sep 17 00:00:00 2001
From: Jisheng Zhang <jszhang@kernel.org>
Date: Sat, 16 Sep 2023 15:58:23 +0800
Subject: [PATCH 1/8] net: stmmac: dwmac-stm32: use
devm_stmmac_probe_config_dt()
Simplify the driver's probe() function by using the devres
variant of stmmac_probe_config_dt().
Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -372,21 +372,18 @@ static int stm32_dwmac_probe(struct plat
if (ret)
return ret;
- plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+ plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
if (IS_ERR(plat_dat))
return PTR_ERR(plat_dat);
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- if (!dwmac) {
- ret = -ENOMEM;
- goto err_remove_config_dt;
- }
+ if (!dwmac)
+ return -ENOMEM;
data = of_device_get_match_data(&pdev->dev);
if (!data) {
dev_err(&pdev->dev, "no of match data provided\n");
- ret = -EINVAL;
- goto err_remove_config_dt;
+ return -EINVAL;
}
dwmac->ops = data;
@@ -395,14 +392,14 @@ static int stm32_dwmac_probe(struct plat
ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "Unable to parse OF data\n");
- goto err_remove_config_dt;
+ return ret;
}
plat_dat->bsp_priv = dwmac;
ret = stm32_dwmac_init(plat_dat);
if (ret)
- goto err_remove_config_dt;
+ return ret;
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
@@ -412,8 +409,6 @@ static int stm32_dwmac_probe(struct plat
err_clk_disable:
stm32_dwmac_clk_disable(dwmac);
-err_remove_config_dt:
- stmmac_remove_config_dt(pdev, plat_dat);
return ret;
}
From 73c350e3fb32e9598b66f61081c7e06a7fba49f8 Mon Sep 17 00:00:00 2001
From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
Date: Mon, 9 Oct 2023 10:59:04 -0400
Subject: [PATCH 2/8] net: stmmac: dwmac-stm32: refactor clock config
Currently, clock configuration is spread throughout the driver and
partially duplicated for the STM32MP1 and STM32 MCU variants. This makes
it difficult to keep track of which clocks need to be enabled or disabled
in various scenarios.
This patch adds symmetric stm32_dwmac_clk_enable/disable() functions
that handle all clock configuration, including quirks required while
suspending or resuming. syscfg_clk and clk_eth_ck are not present on
STM32 MCUs, but it is fine to try to configure them anyway since NULL
clocks are ignored.
Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 113 +++++++-----------
1 file changed, 45 insertions(+), 68 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -98,7 +98,6 @@ struct stm32_dwmac {
struct stm32_ops {
int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
- int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare);
int (*suspend)(struct stm32_dwmac *dwmac);
void (*resume)(struct stm32_dwmac *dwmac);
int (*parse_data)(struct stm32_dwmac *dwmac,
@@ -107,62 +106,55 @@ struct stm32_ops {
bool clk_rx_enable_in_suspend;
};
-static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
+static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
{
- struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
int ret;
- if (dwmac->ops->set_mode) {
- ret = dwmac->ops->set_mode(plat_dat);
- if (ret)
- return ret;
- }
-
ret = clk_prepare_enable(dwmac->clk_tx);
if (ret)
- return ret;
+ goto err_clk_tx;
- if (!dwmac->ops->clk_rx_enable_in_suspend ||
- !dwmac->dev->power.is_suspended) {
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) {
ret = clk_prepare_enable(dwmac->clk_rx);
- if (ret) {
- clk_disable_unprepare(dwmac->clk_tx);
- return ret;
- }
+ if (ret)
+ goto err_clk_rx;
}
- if (dwmac->ops->clk_prepare) {
- ret = dwmac->ops->clk_prepare(dwmac, true);
- if (ret) {
- clk_disable_unprepare(dwmac->clk_rx);
- clk_disable_unprepare(dwmac->clk_tx);
- }
+ ret = clk_prepare_enable(dwmac->syscfg_clk);
+ if (ret)
+ goto err_syscfg_clk;
+
+ if (dwmac->enable_eth_ck) {
+ ret = clk_prepare_enable(dwmac->clk_eth_ck);
+ if (ret)
+ goto err_clk_eth_ck;
}
return ret;
+
+err_clk_eth_ck:
+ clk_disable_unprepare(dwmac->syscfg_clk);
+err_syscfg_clk:
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !resume)
+ clk_disable_unprepare(dwmac->clk_rx);
+err_clk_rx:
+ clk_disable_unprepare(dwmac->clk_tx);
+err_clk_tx:
+ return ret;
}
-static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
+static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat, bool resume)
{
- int ret = 0;
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
+ int ret;
- if (prepare) {
- ret = clk_prepare_enable(dwmac->syscfg_clk);
+ if (dwmac->ops->set_mode) {
+ ret = dwmac->ops->set_mode(plat_dat);
if (ret)
return ret;
- if (dwmac->enable_eth_ck) {
- ret = clk_prepare_enable(dwmac->clk_eth_ck);
- if (ret) {
- clk_disable_unprepare(dwmac->syscfg_clk);
- return ret;
- }
- }
- } else {
- clk_disable_unprepare(dwmac->syscfg_clk);
- if (dwmac->enable_eth_ck)
- clk_disable_unprepare(dwmac->clk_eth_ck);
}
- return ret;
+
+ return stm32_dwmac_clk_enable(dwmac, resume);
}
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
@@ -252,13 +244,15 @@ static int stm32mcu_set_mode(struct plat
dwmac->ops->syscfg_eth_mask, val << 23);
}
-static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
+static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
{
clk_disable_unprepare(dwmac->clk_tx);
- clk_disable_unprepare(dwmac->clk_rx);
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !suspend)
+ clk_disable_unprepare(dwmac->clk_rx);
- if (dwmac->ops->clk_prepare)
- dwmac->ops->clk_prepare(dwmac, false);
+ clk_disable_unprepare(dwmac->syscfg_clk);
+ if (dwmac->enable_eth_ck)
+ clk_disable_unprepare(dwmac->clk_eth_ck);
}
static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
@@ -397,7 +391,7 @@ static int stm32_dwmac_probe(struct plat
plat_dat->bsp_priv = dwmac;
- ret = stm32_dwmac_init(plat_dat);
+ ret = stm32_dwmac_init(plat_dat, false);
if (ret)
return ret;
@@ -408,7 +402,7 @@ static int stm32_dwmac_probe(struct plat
return 0;
err_clk_disable:
- stm32_dwmac_clk_disable(dwmac);
+ stm32_dwmac_clk_disable(dwmac, false);
return ret;
}
@@ -421,7 +415,7 @@ static void stm32_dwmac_remove(struct pl
stmmac_dvr_remove(&pdev->dev);
- stm32_dwmac_clk_disable(priv->plat->bsp_priv);
+ stm32_dwmac_clk_disable(dwmac, false);
if (dwmac->irq_pwr_wakeup >= 0) {
dev_pm_clear_wake_irq(&pdev->dev);
@@ -431,18 +425,7 @@ static void stm32_dwmac_remove(struct pl
static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
{
- int ret = 0;
-
- ret = clk_prepare_enable(dwmac->clk_ethstp);
- if (ret)
- return ret;
-
- clk_disable_unprepare(dwmac->clk_tx);
- clk_disable_unprepare(dwmac->syscfg_clk);
- if (dwmac->enable_eth_ck)
- clk_disable_unprepare(dwmac->clk_eth_ck);
-
- return ret;
+ return clk_prepare_enable(dwmac->clk_ethstp);
}
static void stm32mp1_resume(struct stm32_dwmac *dwmac)
@@ -450,14 +433,6 @@ static void stm32mp1_resume(struct stm32
clk_disable_unprepare(dwmac->clk_ethstp);
}
-static int stm32mcu_suspend(struct stm32_dwmac *dwmac)
-{
- clk_disable_unprepare(dwmac->clk_tx);
- clk_disable_unprepare(dwmac->clk_rx);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int stm32_dwmac_suspend(struct device *dev)
{
@@ -468,6 +443,10 @@ static int stm32_dwmac_suspend(struct de
int ret;
ret = stmmac_suspend(dev);
+ if (ret)
+ return ret;
+
+ stm32_dwmac_clk_disable(dwmac, true);
if (dwmac->ops->suspend)
ret = dwmac->ops->suspend(dwmac);
@@ -485,7 +464,7 @@ static int stm32_dwmac_resume(struct dev
if (dwmac->ops->resume)
dwmac->ops->resume(dwmac);
- ret = stm32_dwmac_init(priv->plat);
+ ret = stm32_dwmac_init(priv->plat, true);
if (ret)
return ret;
@@ -500,13 +479,11 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_
static struct stm32_ops stm32mcu_dwmac_data = {
.set_mode = stm32mcu_set_mode,
- .suspend = stm32mcu_suspend,
.syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
};
static struct stm32_ops stm32mp1_dwmac_data = {
.set_mode = stm32mp1_set_mode,
- .clk_prepare = stm32mp1_clk_prepare,
.suspend = stm32mp1_suspend,
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,
From 23c08dc4ff28b5ca1aa5ee745a5e9688561e8f6a Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:00 +0200
Subject: [PATCH 3/8] net: stmmac: dwmac-stm32: Separate out external clock
rate validation
Pull the external clock frequency validation into a separate function,
to avoid conflating it with external clock DT property decoding and
clock mux register configuration. This should make the code easier to
read and understand.
This does change the code behavior slightly. The clock mux PMCR register
setting now depends solely on the DT properties which configure the clock
mux between external clock and internal RCC generated clock. The mux PMCR
register settings no longer depend on the supplied clock frequency, that
supplied clock frequency is now only validated, and if the clock frequency
is invalid for a mode, it is rejected.
Previously, the code would switch the PMCR register clock mux to internal
RCC generated clock if external clock couldn't provide suitable frequency,
without checking whether the RCC generated clock frequency is correct. Such
behavior is risky at best, user should have configured their clock correctly
in the first place, so this behavior is removed here.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 51 +++++++++++++++----
1 file changed, 41 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -157,25 +157,54 @@ static int stm32_dwmac_init(struct plat_
return stm32_dwmac_clk_enable(dwmac, resume);
}
+static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat)
+{
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
+ const u32 clk_rate = clk_get_rate(dwmac->clk_eth_ck);
+
+ switch (plat_dat->mac_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ if (clk_rate == ETH_CK_F_25M)
+ return 0;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M)
+ return 0;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M)
+ return 0;
+ break;
+ default:
+ break;
+ }
+
+ dev_err(dwmac->dev, "Mode %s does not match eth-ck frequency %d Hz",
+ phy_modes(plat_dat->mac_interface), clk_rate);
+ return -EINVAL;
+}
+
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
- u32 reg = dwmac->mode_reg, clk_rate;
- int val;
+ u32 reg = dwmac->mode_reg;
+ int val, ret;
- clk_rate = clk_get_rate(dwmac->clk_eth_ck);
dwmac->enable_eth_ck = false;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
+ if (dwmac->ext_phyclk)
dwmac->enable_eth_ck = true;
val = SYSCFG_PMCR_ETH_SEL_MII;
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
- if (clk_rate == ETH_CK_F_25M &&
- (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
dwmac->enable_eth_ck = true;
val |= SYSCFG_PMCR_ETH_CLK_SEL;
}
@@ -183,8 +212,7 @@ static int stm32mp1_set_mode(struct plat
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII;
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
- (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk) {
dwmac->enable_eth_ck = true;
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
}
@@ -195,8 +223,7 @@ static int stm32mp1_set_mode(struct plat
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = SYSCFG_PMCR_ETH_SEL_RGMII;
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
- (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
dwmac->enable_eth_ck = true;
val |= SYSCFG_PMCR_ETH_CLK_SEL;
}
@@ -209,6 +236,10 @@ static int stm32mp1_set_mode(struct plat
return -EINVAL;
}
+ ret = stm32mp1_validate_ethck_rate(plat_dat);
+ if (ret)
+ return ret;
+
/* Need to update PMCCLRR (clear register) */
regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
dwmac->ops->syscfg_eth_mask);
From d23ba64e733580db2809e6f6dbf6f093fbd1b91b Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:01 +0200
Subject: [PATCH 4/8] net: stmmac: dwmac-stm32: Separate out external clock
selector
Pull the external clock selector into a separate function, to avoid
conflating it with external clock rate validation and clock mux
register configuration. This should make the code easier to read and
understand.
The dwmac->enable_eth_ck variable in the end indicates whether the MAC
clock are supplied by external oscillator (true) or internal RCC clock
IP (false). The dwmac->enable_eth_ck value is set based on multiple DT
properties, some of them deprecated, some of them specific to bus mode.
The following DT properties and variables are taken into account. In
each case, if the property is present or true, MAC clock is supplied
by external oscillator.
- "st,ext-phyclk", assigned to variable dwmac->ext_phyclk
- Used in any mode (MII/RMII/GMII/RGMII)
- The only non-deprecated DT property of the three
- "st,eth-clk-sel", assigned to variable dwmac->eth_clk_sel_reg
- Valid only in GMII/RGMII mode
- Deprecated property, backward compatibility only
- "st,eth-ref-clk-sel", assigned to variable dwmac->eth_ref_clk_sel_reg
- Valid only in RMII mode
- Deprecated property, backward compatibility only
The stm32mp1_select_ethck_external() function handles the aforementioned
DT properties and sets dwmac->enable_eth_ck accordingly.
The stm32mp1_set_mode() is adjusted to call stm32mp1_select_ethck_external()
first and then only use dwmac->enable_eth_ck to determine hardware clock mux
settings.
No functional change intended.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 50 ++++++++++++++-----
1 file changed, 38 insertions(+), 12 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -157,6 +157,37 @@ static int stm32_dwmac_init(struct plat_
return stm32_dwmac_clk_enable(dwmac, resume);
}
+static int stm32mp1_select_ethck_external(struct plat_stmmacenet_data *plat_dat)
+{
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
+
+ switch (plat_dat->mac_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ dwmac->enable_eth_ck = dwmac->ext_phyclk;
+ return 0;
+ case PHY_INTERFACE_MODE_GMII:
+ dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
+ dwmac->ext_phyclk;
+ return 0;
+ case PHY_INTERFACE_MODE_RMII:
+ dwmac->enable_eth_ck = dwmac->eth_ref_clk_sel_reg ||
+ dwmac->ext_phyclk;
+ return 0;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
+ dwmac->ext_phyclk;
+ return 0;
+ default:
+ dwmac->enable_eth_ck = false;
+ dev_err(dwmac->dev, "Mode %s not supported",
+ phy_modes(plat_dat->mac_interface));
+ return -EINVAL;
+ }
+}
+
static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
@@ -194,28 +225,25 @@ static int stm32mp1_set_mode(struct plat
u32 reg = dwmac->mode_reg;
int val, ret;
- dwmac->enable_eth_ck = false;
+ ret = stm32mp1_select_ethck_external(plat_dat);
+ if (ret)
+ return ret;
+
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- if (dwmac->ext_phyclk)
- dwmac->enable_eth_ck = true;
val = SYSCFG_PMCR_ETH_SEL_MII;
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
- if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
- dwmac->enable_eth_ck = true;
+ if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII;
- if (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk) {
- dwmac->enable_eth_ck = true;
+ if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
case PHY_INTERFACE_MODE_RGMII:
@@ -223,10 +251,8 @@ static int stm32mp1_set_mode(struct plat
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = SYSCFG_PMCR_ETH_SEL_RGMII;
- if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
- dwmac->enable_eth_ck = true;
+ if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
break;
default:
From bb7ab910631ee0ade0758a3c4aa8dadc3b6934b6 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:02 +0200
Subject: [PATCH 5/8] net: stmmac: dwmac-stm32: Extract PMCR configuration
Pull the PMCR clock mux configuration into a separate function. This is
the final change of three, which moves external clock rate validation,
external clock selector decoding, and clock mux configuration into
separate functions. This should make the code easier to understand.
No functional change intended.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 27 ++++++++++++-------
1 file changed, 17 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -219,15 +219,11 @@ static int stm32mp1_validate_ethck_rate(
return -EINVAL;
}
-static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
+static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg;
- int val, ret;
-
- ret = stm32mp1_select_ethck_external(plat_dat);
- if (ret)
- return ret;
+ int val;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
@@ -262,10 +258,6 @@ static int stm32mp1_set_mode(struct plat
return -EINVAL;
}
- ret = stm32mp1_validate_ethck_rate(plat_dat);
- if (ret)
- return ret;
-
/* Need to update PMCCLRR (clear register) */
regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
dwmac->ops->syscfg_eth_mask);
@@ -275,6 +267,21 @@ static int stm32mp1_set_mode(struct plat
dwmac->ops->syscfg_eth_mask, val);
}
+static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
+{
+ int ret;
+
+ ret = stm32mp1_select_ethck_external(plat_dat);
+ if (ret)
+ return ret;
+
+ ret = stm32mp1_validate_ethck_rate(plat_dat);
+ if (ret)
+ return ret;
+
+ return stm32mp1_configure_pmcr(plat_dat);
+}
+
static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
From 0476213f50452446fedd1a918b7bc72eb39a4c46 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:03 +0200
Subject: [PATCH 6/8] net: stmmac: dwmac-stm32: Clean up the debug prints
Use dev_err()/dev_dbg() and phy_modes() to print PHY mode instead of
pr_debug() and hand-written PHY mode decoding. This way, each debug
print has associated device with it and duplicated mode decoding is
removed.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -228,19 +228,16 @@ static int stm32mp1_configure_pmcr(struc
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
val = SYSCFG_PMCR_ETH_SEL_MII;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII;
if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
@@ -249,15 +246,16 @@ static int stm32mp1_configure_pmcr(struc
val = SYSCFG_PMCR_ETH_SEL_RGMII;
if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
break;
default:
- pr_debug("SYSCFG init : Do not manage %d interface\n",
- plat_dat->mac_interface);
+ dev_err(dwmac->dev, "Mode %s not supported",
+ phy_modes(plat_dat->mac_interface));
/* Do not manage others interfaces */
return -EINVAL;
}
+ dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
+
/* Need to update PMCCLRR (clear register) */
regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
dwmac->ops->syscfg_eth_mask);
@@ -291,19 +289,19 @@ static int stm32mcu_set_mode(struct plat
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
val = SYSCFG_MCU_ETH_SEL_MII;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_MCU_ETH_SEL_RMII;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
default:
- pr_debug("SYSCFG init : Do not manage %d interface\n",
- plat_dat->mac_interface);
+ dev_err(dwmac->dev, "Mode %s not supported",
+ phy_modes(plat_dat->mac_interface));
/* Do not manage others interfaces */
return -EINVAL;
}
+ dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
+
return regmap_update_bits(dwmac->regmap, reg,
dwmac->ops->syscfg_eth_mask, val << 23);
}
From 796669a85c5c4fa80cb8790e9adcccbbd99750e8 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Tue, 11 Jun 2024 10:36:05 +0200
Subject: [PATCH 7/8] net: stmmac: dwmac-stm32: Mask support for PMCR
configuration
Add possibility to have second argument in syscon property to manage
mask. This mask will be used to address right BITFIELDS of PMCR register.
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 28 +++++++++++++------
1 file changed, 19 insertions(+), 9 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -90,6 +90,7 @@ struct stm32_dwmac {
int eth_ref_clk_sel_reg;
int irq_pwr_wakeup;
u32 mode_reg; /* MAC glue-logic mode register */
+ u32 mode_mask;
struct regmap *regmap;
u32 speed;
const struct stm32_ops *ops;
@@ -102,8 +103,8 @@ struct stm32_ops {
void (*resume)(struct stm32_dwmac *dwmac);
int (*parse_data)(struct stm32_dwmac *dwmac,
struct device *dev);
- u32 syscfg_eth_mask;
bool clk_rx_enable_in_suspend;
+ u32 syscfg_clr_off;
};
static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
@@ -256,13 +257,16 @@ static int stm32mp1_configure_pmcr(struc
dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
+ /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
+ val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
+
/* Need to update PMCCLRR (clear register) */
- regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
- dwmac->ops->syscfg_eth_mask);
+ regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
+ dwmac->mode_mask);
/* Update PMCSETR (set register) */
return regmap_update_bits(dwmac->regmap, reg,
- dwmac->ops->syscfg_eth_mask, val);
+ dwmac->mode_mask, val);
}
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
@@ -303,7 +307,7 @@ static int stm32mcu_set_mode(struct plat
dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
return regmap_update_bits(dwmac->regmap, reg,
- dwmac->ops->syscfg_eth_mask, val << 23);
+ SYSCFG_MCU_ETH_MASK, val << 23);
}
static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
@@ -348,8 +352,15 @@ static int stm32_dwmac_parse_data(struct
return PTR_ERR(dwmac->regmap);
err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
- if (err)
+ if (err) {
dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
+ return err;
+ }
+
+ dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
+ err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
+ if (err)
+ dev_dbg(dev, "Warning sysconfig register mask not set\n");
return err;
}
@@ -540,8 +551,7 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_
stm32_dwmac_suspend, stm32_dwmac_resume);
static struct stm32_ops stm32mcu_dwmac_data = {
- .set_mode = stm32mcu_set_mode,
- .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
+ .set_mode = stm32mcu_set_mode
};
static struct stm32_ops stm32mp1_dwmac_data = {
@@ -549,7 +559,7 @@ static struct stm32_ops stm32mp1_dwmac_d
.suspend = stm32mp1_suspend,
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,
- .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
+ .syscfg_clr_off = 0x44,
.clk_rx_enable_in_suspend = true
};
From 8d28aaf5d5dbfd1f452286fa6ac571df0bcf00ad Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Tue, 11 Jun 2024 10:36:06 +0200
Subject: [PATCH 8/8] net: stmmac: dwmac-stm32: add management of stm32mp13 for
stm32
Add Ethernet support for STM32MP13.
STM32MP13 is STM32 SOC with 2 GMACs instances.
GMAC IP version is SNPS 4.20.
GMAC IP configure with 1 RX and 1 TX queue.
DMA HW capability register supported
RX Checksum Offload Engine supported
TX Checksum insertion supported
Wake-Up On Lan supported
TSO supported
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 32 ++++++++++++++++---
1 file changed, 28 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -104,6 +104,7 @@ struct stm32_ops {
int (*parse_data)(struct stm32_dwmac *dwmac,
struct device *dev);
bool clk_rx_enable_in_suspend;
+ bool is_mp13;
u32 syscfg_clr_off;
};
@@ -224,11 +225,18 @@ static int stm32mp1_configure_pmcr(struc
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg;
- int val;
+ int val = 0;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- val = SYSCFG_PMCR_ETH_SEL_MII;
+ /*
+ * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only.
+ * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and
+ * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx
+ * supports only MII, ETH_SELMII is not present.
+ */
+ if (!dwmac->ops->is_mp13) /* Select MII mode on STM32MP15xx */
+ val |= SYSCFG_PMCR_ETH_SEL_MII;
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
@@ -359,8 +367,12 @@ static int stm32_dwmac_parse_data(struct
dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
- if (err)
- dev_dbg(dev, "Warning sysconfig register mask not set\n");
+ if (err) {
+ if (dwmac->ops->is_mp13)
+ dev_err(dev, "Sysconfig register mask must be set (%d)\n", err);
+ else
+ dev_dbg(dev, "Warning sysconfig register mask not set\n");
+ }
return err;
}
@@ -560,12 +572,24 @@ static struct stm32_ops stm32mp1_dwmac_d
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,
.syscfg_clr_off = 0x44,
+ .is_mp13 = false,
+ .clk_rx_enable_in_suspend = true
+};
+
+static struct stm32_ops stm32mp13_dwmac_data = {
+ .set_mode = stm32mp1_set_mode,
+ .suspend = stm32mp1_suspend,
+ .resume = stm32mp1_resume,
+ .parse_data = stm32mp1_parse_data,
+ .syscfg_clr_off = 0x08,
+ .is_mp13 = true,
.clk_rx_enable_in_suspend = true
};
static const struct of_device_id stm32_dwmac_match[] = {
{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
+ { .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
From 21ca3d7c59595d76237faebeff4f6a979cf7ae82 Mon Sep 17 00:00:00 2001
From: Alexandre Torgue <alexandre.torgue@foss.st.com>
Date: Fri, 5 Apr 2024 13:45:24 +0200
Subject: [PATCH 2/5] ARM: dts: stm32: put ETZPC as an access controller for
STM32MP13x boards
Reference ETZPC as an access-control-provider.
For more information on which peripheral is securable or supports MCU
isolation, please read the STM32MP13 reference manual
Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp131.dtsi | 28 ++++++++++++++++++++++++++-
arch/arm/boot/dts/st/stm32mp133.dtsi | 1 +
arch/arm/boot/dts/st/stm32mp13xc.dtsi | 1 +
arch/arm/boot/dts/st/stm32mp13xf.dtsi | 1 +
4 files changed, 30 insertions(+), 1 deletion(-)
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -886,10 +886,11 @@
};
etzpc: bus@5c007000 {
- compatible = "simple-bus";
+ compatible = "st,stm32-etzpc", "simple-bus";
reg = <0x5c007000 0x400>;
#address-cells = <1>;
#size-cells = <1>;
+ #access-controller-cells = <1>;
ranges;
adc_2: adc@48004000 {
@@ -902,6 +903,7 @@
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 33>;
status = "disabled";
adc2: adc@0 {
@@ -949,6 +951,7 @@
dr_mode = "otg";
otg-rev = <0x200>;
usb33d-supply = <&scmi_usb33>;
+ access-controllers = <&etzpc 34>;
status = "disabled";
};
@@ -962,6 +965,7 @@
dmas = <&dmamux1 41 0x400 0x5>,
<&dmamux1 42 0x400 0x1>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 16>;
status = "disabled";
};
@@ -975,6 +979,7 @@
dmas = <&dmamux1 43 0x400 0x5>,
<&dmamux1 44 0x400 0x1>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 17>;
status = "disabled";
};
@@ -986,6 +991,7 @@
dmas = <&dmamux1 83 0x400 0x01>,
<&dmamux1 84 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 13>;
status = "disabled";
};
@@ -1000,6 +1006,7 @@
dmas = <&dmamux1 83 0x400 0x01>,
<&dmamux1 84 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 18>;
status = "disabled";
};
@@ -1014,6 +1021,7 @@
dmas = <&dmamux1 85 0x400 0x01>,
<&dmamux1 86 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 19>;
status = "disabled";
};
@@ -1032,6 +1040,7 @@
dma-names = "rx", "tx";
st,syscfg-fmp = <&syscfg 0x4 0x4>;
i2c-analog-filter;
+ access-controllers = <&etzpc 20>;
status = "disabled";
};
@@ -1050,6 +1059,7 @@
dma-names = "rx", "tx";
st,syscfg-fmp = <&syscfg 0x4 0x8>;
i2c-analog-filter;
+ access-controllers = <&etzpc 21>;
status = "disabled";
};
@@ -1068,6 +1078,7 @@
dma-names = "rx", "tx";
st,syscfg-fmp = <&syscfg 0x4 0x10>;
i2c-analog-filter;
+ access-controllers = <&etzpc 22>;
status = "disabled";
};
@@ -1080,6 +1091,7 @@
interrupt-names = "global";
clocks = <&rcc TIM12_K>;
clock-names = "int";
+ access-controllers = <&etzpc 23>;
status = "disabled";
pwm {
@@ -1104,6 +1116,7 @@
interrupt-names = "global";
clocks = <&rcc TIM13_K>;
clock-names = "int";
+ access-controllers = <&etzpc 24>;
status = "disabled";
pwm {
@@ -1128,6 +1141,7 @@
interrupt-names = "global";
clocks = <&rcc TIM14_K>;
clock-names = "int";
+ access-controllers = <&etzpc 25>;
status = "disabled";
pwm {
@@ -1157,6 +1171,7 @@
<&dmamux1 107 0x400 0x1>,
<&dmamux1 108 0x400 0x1>;
dma-names = "ch1", "up", "trig", "com";
+ access-controllers = <&etzpc 26>;
status = "disabled";
pwm {
@@ -1184,6 +1199,7 @@
dmas = <&dmamux1 109 0x400 0x1>,
<&dmamux1 110 0x400 0x1>;
dma-names = "ch1", "up";
+ access-controllers = <&etzpc 27>;
status = "disabled";
pwm {
@@ -1211,6 +1227,7 @@
dmas = <&dmamux1 111 0x400 0x1>,
<&dmamux1 112 0x400 0x1>;
dma-names = "ch1", "up";
+ access-controllers = <&etzpc 28>;
status = "disabled";
pwm {
@@ -1235,6 +1252,7 @@
clocks = <&rcc LPTIM2_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 1>;
status = "disabled";
pwm {
@@ -1269,6 +1287,7 @@
clocks = <&rcc LPTIM3_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 2>;
status = "disabled";
pwm {
@@ -1297,6 +1316,7 @@
resets = <&rcc HASH1_R>;
dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
dma-names = "in";
+ access-controllers = <&etzpc 41>;
status = "disabled";
};
@@ -1305,6 +1325,7 @@
reg = <0x54004000 0x400>;
clocks = <&rcc RNG1_K>;
resets = <&rcc RNG1_R>;
+ access-controllers = <&etzpc 40>;
status = "disabled";
};
@@ -1320,6 +1341,7 @@
#size-cells = <1>;
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
+ access-controllers = <&etzpc 54>;
status = "disabled";
nand-controller@4,0 {
@@ -1353,6 +1375,7 @@
dma-names = "tx", "rx";
clocks = <&rcc QSPI_K>;
resets = <&rcc QSPI_R>;
+ access-controllers = <&etzpc 55>;
status = "disabled";
};
@@ -1367,6 +1390,7 @@
cap-sd-highspeed;
cap-mmc-highspeed;
max-frequency = <130000000>;
+ access-controllers = <&etzpc 50>;
status = "disabled";
};
@@ -1381,6 +1405,7 @@
cap-sd-highspeed;
cap-mmc-highspeed;
max-frequency = <130000000>;
+ access-controllers = <&etzpc 51>;
status = "disabled";
};
@@ -1394,6 +1419,7 @@
resets = <&rcc USBPHY_R>;
vdda1v1-supply = <&scmi_reg11>;
vdda1v8-supply = <&scmi_reg18>;
+ access-controllers = <&etzpc 5>;
status = "disabled";
usbphyc_port0: usb-phy@0 {
--- a/arch/arm/boot/dts/st/stm32mp133.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp133.dtsi
@@ -47,6 +47,7 @@
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 32>;
status = "disabled";
adc1: adc@0 {
--- a/arch/arm/boot/dts/st/stm32mp13xc.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13xc.dtsi
@@ -11,6 +11,7 @@
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CRYP1>;
resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 42>;
status = "disabled";
};
};
--- a/arch/arm/boot/dts/st/stm32mp13xf.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13xf.dtsi
@@ -11,6 +11,7 @@
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CRYP1>;
resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 42>;
status = "disabled";
};
};
From b1468a44e0c0f43a06e027efeff4183b3aee0cf7 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 10 Jun 2024 10:03:08 +0200
Subject: [PATCH 3/5] ARM: dts: stm32: add ethernet1/2 RMII pins for
STM32MP13F-DK board
Those pins are used for Ethernet 1 and 2 on STM32MP13F-DK board.
ethernet1: RMII with crystal.
ethernet2: RMII without crystal.
Add analog gpio pin configuration ("sleep") to manage power mode on
stm32mp13.
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 98 +++++++++++++++++++++
1 file changed, 98 insertions(+)
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -13,6 +13,104 @@
};
};
+ eth1_rgmii_pins_a: eth1-rgmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 5, AF10)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('C', 1, AF11)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 7, AF11)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('D', 7, AF10)>; /* ETH_RGMII_RX_CLK */
+ bias-disable;
+ };
+
+ };
+
+ eth1_rmii_pins_a: eth1-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, AF11)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, AF10)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+
+ };
+
+ eth1_rmii_sleep_pins_a: eth1-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
+ eth2_rmii_pins_a: eth2-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, AF10)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, AF13)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, AF10)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, AF10)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, AF11)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+ };
+
+ eth2_rmii_sleep_pins_a: eth2-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('F', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
i2c1_pins_a: i2c1-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
From fcf6ca2da4650d0a7a9cd62c8c72341860931159 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 10 Jun 2024 10:03:07 +0200
Subject: [PATCH 4/5] ARM: dts: stm32: add ethernet1 and ethernet2 support on
stm32mp13
Both instances ethernet based on GMAC SNPS IP on stm32mp13.
GMAC IP version is SNPS 4.20.
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp131.dtsi | 38 ++++++++++++++++++++++++++++
arch/arm/boot/dts/st/stm32mp133.dtsi | 31 +++++++++++++++++++++++
2 files changed, 69 insertions(+)
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -883,6 +883,12 @@
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
+ ethernet_mac1_address: mac1@e4 {
+ reg = <0xe4 0x6>;
+ };
+ ethernet_mac2_address: mac2@ea {
+ reg = <0xea 0x6>;
+ };
};
etzpc: bus@5c007000 {
@@ -1409,6 +1415,38 @@
status = "disabled";
};
+ ethernet1: ethernet@5800a000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800a000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 68 1>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH1MAC>,
+ <&rcc ETH1TX>,
+ <&rcc ETH1RX>,
+ <&rcc ETH1STP>,
+ <&rcc ETH1CK_K>;
+ st,syscon = <&syscfg 0x4 0xff0000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_1>;
+ snps,tso;
+ access-controllers = <&etzpc 48>;
+ status = "disabled";
+
+ stmmac_axi_config_1: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
+
usbphyc: usbphyc@5a006000 {
#address-cells = <1>;
#size-cells = <0>;
--- a/arch/arm/boot/dts/st/stm32mp133.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp133.dtsi
@@ -68,4 +68,35 @@
};
};
};
+
+ ethernet2: ethernet@5800e000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800e000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH2MAC>,
+ <&rcc ETH2TX>,
+ <&rcc ETH2RX>,
+ <&rcc ETH2STP>,
+ <&rcc ETH2CK_K>;
+ st,syscon = <&syscfg 0x4 0xff000000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_2>;
+ snps,tso;
+ access-controllers = <&etzpc 49>;
+ status = "disabled";
+
+ stmmac_axi_config_2: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment