Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2023-05-30 12:29:22 +08:00
58 changed files with 6322 additions and 501 deletions

View File

@@ -10,6 +10,7 @@ FEATURES:=fpu dt gpio ramdisk squashfs usb
SUBTARGETS:=nand sata
KERNEL_PATCHVER:=5.15
KERNEL_TESTING_PATCHVER:=6.1
define Target/Description
Build images for AppliedMicro APM821xx based boards.
@@ -20,6 +21,7 @@ include $(INCLUDE_DIR)/target.mk
KERNELNAME:=uImage
DEFAULT_PACKAGES += \
kmod-leds-gpio kmod-i2c-core kmod-gpio-button-hotplug uboot-envtools
kmod-leds-gpio kmod-i2c-core kmod-gpio-button-hotplug uboot-envtools \
kmod-hw-crypto-4xx
$(eval $(call BuildTarget))

View File

@@ -39,15 +39,11 @@ CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DEV_PPC4XX=y
CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
CONFIG_CRYPTO_LZO=y
# CONFIG_CRYPTO_MD5_PPC is not set
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
# CONFIG_CRYPTO_SHA1_PPC is not set
CONFIG_DATA_SHIFT=12
CONFIG_DMADEVICES=y
@@ -96,8 +92,6 @@ CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_PPC4XX=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y

View File

@@ -0,0 +1,250 @@
# CONFIG_40x is not set
# CONFIG_440_CPU is not set
CONFIG_44x=y
CONFIG_464_CPU=y
CONFIG_4xx=y
CONFIG_4xx_SOC=y
# CONFIG_ADVANCED_OPTIONS is not set
CONFIG_APM821xx=y
# CONFIG_APOLLO3G is not set
# CONFIG_ARCHES is not set
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_FORCE_MAX_ORDER=11
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_ARCH_MMAP_RND_BITS=11
CONFIG_ARCH_MMAP_RND_BITS_MAX=17
CONFIG_ARCH_MMAP_RND_BITS_MIN=11
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
CONFIG_ARCH_SPLIT_ARG64=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
CONFIG_AUDIT_ARCH=y
# CONFIG_BAMBOO is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_BLK_MQ_PCI=y
CONFIG_BLUESTONE=y
CONFIG_BOOKE=y
CONFIG_BOOKE_OR_40x=y
CONFIG_BOOKE_WDT=y
# CONFIG_CANYONLANDS is not set
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="rootfstype=squashfs noinitrd"
CONFIG_CMDLINE_FROM_BOOTLOADER=y
CONFIG_COMMON_CLK=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZO=y
# CONFIG_CRYPTO_MD5_PPC is not set
# CONFIG_CRYPTO_SHA1_PPC is not set
CONFIG_DATA_SHIFT=12
CONFIG_DMADEVICES=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DTC=y
CONFIG_DW_DMAC=y
CONFIG_DW_DMAC_CORE=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EBONY is not set
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
# CONFIG_EIGER is not set
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXTRA_TARGETS="uImage"
CONFIG_FIXED_PHY=y
CONFIG_FORCE_PCI=y
# CONFIG_FSL_LBC is not set
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
# CONFIG_GEN_RTC is not set
# CONFIG_GLACIER is not set
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IBM_IIC=y
CONFIG_IBM_EMAC=y
CONFIG_IBM_EMAC_EMAC4=y
CONFIG_IBM_EMAC_POLL_WEIGHT=32
CONFIG_IBM_EMAC_RGMII=y
CONFIG_IBM_EMAC_RXB=128
CONFIG_IBM_EMAC_RX_COPY_THRESHOLD=256
CONFIG_IBM_EMAC_TAH=y
CONFIG_IBM_EMAC_TXB=128
# CONFIG_ICON is not set
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_ISA_DMA_API=y
# CONFIG_JFFS2_FS is not set
# CONFIG_KATMAI is not set
CONFIG_KERNEL_START=0xc0000000
CONFIG_LEDS_TRIGGER_MTD=y
CONFIG_LEDS_TRIGGER_PATTERN=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOWMEM_SIZE=0x30000000
# CONFIG_MATH_EMULATION is not set
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MMU_GATHER_PAGE_SIZE=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_GEOMETRY is not set
# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NET_SELFTESTS=y
CONFIG_NOT_COHERENT_CACHE=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=1
CONFIG_NR_IRQS=512
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND=y
CONFIG_PACKING=y
CONFIG_PAGE_OFFSET=0xc0000000
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_ARCH_FALLBACKS=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYSICAL_START=0x00000000
CONFIG_PHYS_64BIT=y
CONFIG_PHYS_ADDR_T_64BIT=y
# CONFIG_PMU_SYSFS is not set
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_PPC44x_SIMPLE=y
CONFIG_PPC4xx_GPIO=y
CONFIG_PPC4xx_PCI_EXPRESS=y
# CONFIG_PPC64 is not set
# CONFIG_PPC_47x is not set
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_8xx is not set
CONFIG_PPC_ADV_DEBUG_DACS=2
CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y
CONFIG_PPC_ADV_DEBUG_DVCS=2
CONFIG_PPC_ADV_DEBUG_IACS=4
CONFIG_PPC_ADV_DEBUG_REGS=y
# CONFIG_PPC_BOOK3S_32 is not set
CONFIG_PPC_DCR=y
CONFIG_PPC_DCR_NATIVE=y
# CONFIG_PPC_EARLY_DEBUG is not set
CONFIG_PPC_FPU=y
CONFIG_PPC_FPU_REGS=y
CONFIG_PPC_INDIRECT_PCI=y
CONFIG_PPC_KUAP=y
# CONFIG_PPC_KUAP_DEBUG is not set
CONFIG_PPC_KUEP=y
CONFIG_PPC_MMU_NOHASH=y
CONFIG_PPC_PAGE_SHIFT=12
# CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT is not set
CONFIG_PPC_UDBG_16550=y
CONFIG_PPC_WERROR=y
CONFIG_PTE_64BIT=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
# CONFIG_RAINIER is not set
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGULATOR=y
CONFIG_RSEQ=y
# CONFIG_SAM440EP is not set
# CONFIG_SCOM_DEBUGFS is not set
# CONFIG_SEQUOIA is not set
# CONFIG_SERIAL_8250_FSL is not set
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SPARSE_IRQ=y
CONFIG_SRCU=y
# CONFIG_STATIC_CALL_SELFTEST is not set
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
# CONFIG_TAISHAN is not set
CONFIG_TARGET_CPU="464"
CONFIG_TARGET_CPU_BOOL=y
CONFIG_TASK_SIZE=0xc0000000
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_THREAD_SHIFT=13
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
CONFIG_USB_SUPPORT=y
CONFIG_VDSO32=y
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
# CONFIG_WARP is not set
CONFIG_WATCHDOG_CORE=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_POWERPC=y
# CONFIG_YOSEMITE is not set
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y

View File

@@ -47,8 +47,6 @@
status = "okay";
nand {
nand-is-boot-medium;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;

View File

@@ -100,7 +100,7 @@ define Device/netgear_wndr4700
kmod-dm kmod-fs-ext4 kmod-fs-vfat kmod-usb-ledtrig-usbport \
kmod-md-mod kmod-nls-cp437 kmod-nls-iso8859-1 kmod-nls-iso8859-15 \
kmod-nls-utf8 kmod-usb3 kmod-usb-dwc2 kmod-usb-storage \
partx-utils
partx-utils kmod-ata-dwc
BOARD_NAME := wndr4700
PAGESIZE := 2048
SUBPAGESIZE := 512

View File

@@ -0,0 +1,33 @@
define KernelPackage/ata-dwc
TITLE:=DesignWare Cores SATA support
KCONFIG:=CONFIG_SATA_DWC
FILES:=$(LINUX_DIR)/drivers/ata/sata_dwc_460ex.ko
AUTOLOAD:=$(call AutoLoad,40,sata_dwc_460ex,1)
$(call AddDepends/ata)
endef
define KernelPackage/ata-dwc/description
Platform support for the on-chip SATA controller.
endef
$(eval $(call KernelPackage,ata-dwc))
define KernelPackage/hw-crypto-4xx
TITLE:=Driver AMCC PPC4xx crypto accelerator
KCONFIG:= \
CONFIG_CRYPTO_HW=y \
CONFIG_HW_RANDOM=y \
CONFIG_CRYPTO_DEV_PPC4XX \
CONFIG_HW_RANDOM_PPC4XX=y
DEPENDS:=+kmod-random-core +kmod-crypto-manager \
+kmod-crypto-ccm +kmod-crypto-gcm \
+kmod-crypto-sha1 +kmod-crypto-sha256 +kmod-crypto-sha512
FILES:=$(LINUX_DIR)/drivers/crypto/amcc/crypto4xx.ko
AUTOLOAD:=$(call AutoLoad,09,sata_dwc_460ex,1)
endef
define KernelPackage/hw-crypto-4xx/description
Platform support for the on-chip crypto acceleration.
endef
$(eval $(call KernelPackage,hw-crypto-4xx))

View File

@@ -2,14 +2,8 @@ CONFIG_AT803X_PHY=y
CONFIG_AR8216_PHY=y
# CONFIG_SATA_DWC_OLD_DMA is not set
CONFIG_IKAREM=y
CONFIG_ATA=y
CONFIG_ATA_SFF=y
CONFIG_ATA_BMDMA=y
# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
CONFIG_SATA_PMP=y
CONFIG_GENERIC_PHY=y
CONFIG_SATA_DWC=y
# CONFIG_SATA_DWC_DEBUG is not set
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_GPIO_GENERIC=y

View File

@@ -0,0 +1,30 @@
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -118,6 +118,17 @@ config CANYONLANDS
help
This option enables support for the AMCC PPC460EX evaluation board.
+config APOLLO3G
+ bool "Apollo3G"
+ depends on 44x
+ default n
+ select PPC44x_SIMPLE
+ select APM821xx
+ select IBM_EMAC_RGMII
+ select 460EX
+ help
+ This option enables support for the AMCC Apollo 3G board.
+
config GLACIER
bool "Glacier"
depends on 44x
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -46,6 +46,7 @@ machine_device_initcall(ppc44x_simple, p
* board.c file for it rather than adding it to this list.
*/
static char *board[] __initdata = {
+ "amcc,apollo3g",
"amcc,arches",
"amcc,bamboo",
"apm,bluestone",

View File

@@ -0,0 +1,51 @@
--- a/arch/powerpc/platforms/4xx/pci.c
+++ b/arch/powerpc/platforms/4xx/pci.c
@@ -1061,15 +1061,24 @@ static int __init apm821xx_pciex_init_po
u32 val;
/*
- * Do a software reset on PCIe ports.
- * This code is to fix the issue that pci drivers doesn't re-assign
- * bus number for PCIE devices after Uboot
- * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
- * PT quad port, SAS LSI 1064E)
+ * Only reset the PHY when no link is currently established.
+ * This is for the Atheros PCIe board which has problems to establish
+ * the link (again) after this PHY reset. All other currently tested
+ * PCIe boards don't show this problem.
*/
-
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
- mdelay(10);
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
+ if (!(val & 0x00001000)) {
+ /*
+ * Do a software reset on PCIe ports.
+ * This code is to fix the issue that pci drivers doesn't re-assign
+ * bus number for PCIE devices after Uboot
+ * scanned and configured all the buses (eg. PCIE NIC IntelPro/1000
+ * PT quad port, SAS LSI 1064E)
+ */
+
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x0);
+ mdelay(10);
+ }
if (port->endpoint)
val = PTYPE_LEGACY_ENDPOINT << 20;
@@ -1086,9 +1095,12 @@ static int __init apm821xx_pciex_init_po
mtdcri(SDR0, PESDR0_460EX_L0DRV, 0x00000130);
mtdcri(SDR0, PESDR0_460EX_L0CLK, 0x00000006);
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
- mdelay(50);
- mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP);
+ if (!(val & 0x00001000)) {
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x10000000);
+ mdelay(50);
+ mtdcri(SDR0, PESDR0_460EX_PHY_CTL_RST, 0x30000000);
+ }
mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) |

View File

@@ -0,0 +1,14 @@
--- a/arch/powerpc/platforms/4xx/pci.c
+++ b/arch/powerpc/platforms/4xx/pci.c
@@ -1903,9 +1903,9 @@ static void __init ppc4xx_configure_pcie
* if it works
*/
out_le32(mbase + PECFG_PIM0LAL, 0x00000000);
- out_le32(mbase + PECFG_PIM0LAH, 0x00000000);
+ out_le32(mbase + PECFG_PIM0LAH, 0x00000008);
out_le32(mbase + PECFG_PIM1LAL, 0x00000000);
- out_le32(mbase + PECFG_PIM1LAH, 0x00000000);
+ out_le32(mbase + PECFG_PIM1LAH, 0x0000000c);
out_le32(mbase + PECFG_PIM01SAH, 0xffff0000);
out_le32(mbase + PECFG_PIM01SAL, 0x00000000);

View File

@@ -0,0 +1,29 @@
From c9395ad54e2cabb87d408becc37566f3d8248933 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <chunkeey@gmail.com>
Date: Sun, 1 Dec 2019 02:08:23 +0100
Subject: [PATCH] powerpc: bootwrapper: force gzip as mkimage's compression
method
Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
instruct the mkimage to use the xz compression, which isn't
supported. This patch forces the gzip compression, which is
supported and doesn't matter because the generated uImage for
the apm821xx target gets ignored as the OpenWrt toolchain will
do separate U-Boot kernel images for each device individually.
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
---
arch/powerpc/boot/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -272,7 +272,7 @@ compressor-$(CONFIG_KERNEL_LZO) := lzo
# args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd
quiet_cmd_wrap = WRAP $@
- cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z $(compressor-y) -c -o $@ -p $2 \
+ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -Z gzip -c -o $@ -p $2 \
$(CROSSWRAP) $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) \
vmlinux

View File

@@ -40,12 +40,14 @@ CONFIG_PM=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_CLK=y
CONFIG_PM_SLEEP=y
# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PPC_EARLY_DEBUG=y
CONFIG_PPC_EARLY_DEBUG_44x=y
# CONFIG_PPC_EARLY_DEBUG_MEMCONS is not set
# CONFIG_PPC_EARLY_DEBUG_16550 is not set
CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x4
CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
CONFIG_PPC4xx_CPM=y

View File

@@ -126,11 +126,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/workingset.c | 4 ++--
4 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index e8ed225d8f7ca..f63968bd7de59 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(struct lruvec *lruvec, struct folio *foli
@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(s
int zone = folio_zonenum(folio);
int delta = folio_nr_pages(folio);
enum lru_list lru = type * LRU_INACTIVE_FILE;
@@ -139,7 +137,7 @@ index e8ed225d8f7ca..f63968bd7de59 100644
VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(str
int gen = folio_lru_gen(folio);
int type = folio_is_file_lru(folio);
int zone = folio_zonenum(folio);
@@ -148,8 +146,6 @@ index e8ed225d8f7ca..f63968bd7de59 100644
VM_WARN_ON_ONCE_FOLIO(gen != -1, folio);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 5f74891556f33..bd3e4689f72dc 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -404,7 +404,7 @@ enum {
@@ -179,11 +175,9 @@ index 5f74891556f33..bd3e4689f72dc 100644
/* to concurrently iterate lru_gen_mm_list */
struct lru_gen_mm_state mm_state;
#endif
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d18296109aa7e..27142caf284c1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lruvec, int type)
@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lr
static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
{
@@ -201,7 +195,7 @@ index d18296109aa7e..27142caf284c1 100644
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
pos->refaulted = lrugen->avg_refaulted[type][tier] +
@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec
static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover)
{
int hist, tier;
@@ -210,7 +204,7 @@ index d18296109aa7e..27142caf284c1 100644
bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1;
@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio *folio, int gen)
@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio
static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
{
int type = folio_is_file_lru(folio);
@@ -219,7 +213,7 @@ index d18296109aa7e..27142caf284c1 100644
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
unsigned long new_flags, old_flags = READ_ONCE(folio->flags);
@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru_gen_mm_walk *walk, struct folio *folio,
@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru
static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
{
int gen, type, zone;
@@ -228,7 +222,7 @@ index d18296109aa7e..27142caf284c1 100644
walk->batched = 0;
@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *l
{
int zone;
int remaining = MAX_LRU_BATCH;
@@ -237,7 +231,7 @@ index d18296109aa7e..27142caf284c1 100644
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
if (type == LRU_GEN_ANON && !can_swap)
@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lr
{
int gen, type, zone;
bool success = false;
@@ -246,7 +240,7 @@ index d18296109aa7e..27142caf284c1 100644
DEFINE_MIN_SEQ(lruvec);
VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
@@ -4307,7 +4307,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
@@ -4307,7 +4307,7 @@ next:
;
}
@@ -255,7 +249,7 @@ index d18296109aa7e..27142caf284c1 100644
if (can_swap) {
min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan)
@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *l
{
int prev, next;
int type, zone;
@@ -264,7 +258,7 @@ index d18296109aa7e..27142caf284c1 100644
spin_lock_irq(&lruvec->lru_lock);
@@ -4387,7 +4387,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4387,7 +4387,7 @@ static bool try_to_inc_max_seq(struct lr
bool success;
struct lru_gen_mm_walk *walk;
struct mm_struct *mm = NULL;
@@ -273,7 +267,7 @@ index d18296109aa7e..27142caf284c1 100644
VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq));
@@ -4452,7 +4452,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
@@ -4452,7 +4452,7 @@ static bool should_run_aging(struct lruv
unsigned long old = 0;
unsigned long young = 0;
unsigned long total = 0;
@@ -282,7 +276,7 @@ index d18296109aa7e..27142caf284c1 100644
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
for (type = !can_swap; type < ANON_AND_FILE; type++) {
@@ -4737,7 +4737,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
@@ -4737,7 +4737,7 @@ static bool sort_folio(struct lruvec *lr
int delta = folio_nr_pages(folio);
int refs = folio_lru_refs(folio);
int tier = lru_tier_from_refs(refs);
@@ -291,7 +285,7 @@ index d18296109aa7e..27142caf284c1 100644
VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio);
@@ -4837,7 +4837,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
@@ -4837,7 +4837,7 @@ static int scan_folios(struct lruvec *lr
int scanned = 0;
int isolated = 0;
int remaining = MAX_LRU_BATCH;
@@ -300,7 +294,7 @@ index d18296109aa7e..27142caf284c1 100644
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
VM_WARN_ON_ONCE(!list_empty(list));
@@ -5237,7 +5237,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5237,7 +5237,7 @@ done:
static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
{
@@ -309,7 +303,7 @@ index d18296109aa7e..27142caf284c1 100644
if (lrugen->enabled) {
enum lru_list lru;
@@ -5519,7 +5519,7 @@ static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
@@ -5519,7 +5519,7 @@ static void lru_gen_seq_show_full(struct
int i;
int type, tier;
int hist = lru_hist_from_seq(seq);
@@ -318,7 +312,7 @@ index d18296109aa7e..27142caf284c1 100644
for (tier = 0; tier < MAX_NR_TIERS; tier++) {
seq_printf(m, " %10d", tier);
@@ -5569,7 +5569,7 @@ static int lru_gen_seq_show(struct seq_file *m, void *v)
@@ -5569,7 +5569,7 @@ static int lru_gen_seq_show(struct seq_f
unsigned long seq;
bool full = !debugfs_real_fops(m->file)->write;
struct lruvec *lruvec = v;
@@ -327,7 +321,7 @@ index d18296109aa7e..27142caf284c1 100644
int nid = lruvec_pgdat(lruvec)->node_id;
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
DEFINE_MAX_SEQ(lruvec);
@@ -5823,7 +5823,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
@@ -5823,7 +5823,7 @@ void lru_gen_init_lruvec(struct lruvec *
{
int i;
int gen, type, zone;
@@ -336,11 +330,9 @@ index d18296109aa7e..27142caf284c1 100644
lrugen->max_seq = MIN_NR_GENS + 1;
lrugen->enabled = lru_gen_enabled();
diff --git a/mm/workingset.c b/mm/workingset.c
index ae7e984b23c6b..688aaa73f64e8 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct folio *folio)
@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct fol
unsigned long token;
unsigned long min_seq;
struct lruvec *lruvec;
@@ -349,7 +341,7 @@ index ae7e984b23c6b..688aaa73f64e8 100644
int type = folio_is_file_lru(folio);
int delta = folio_nr_pages(folio);
int refs = folio_lru_refs(folio);
@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio *folio, void *shadow)
@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio
unsigned long token;
unsigned long min_seq;
struct lruvec *lruvec;
@@ -358,6 +350,3 @@ index ae7e984b23c6b..688aaa73f64e8 100644
struct mem_cgroup *memcg;
struct pglist_data *pgdat;
int type = folio_is_file_lru(folio);
--
2.40.1

View File

@@ -28,8 +28,6 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 20 ++++++++++----------
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
index d7062c6a89464..d8f721f98868a 100644
--- a/Documentation/mm/multigen_lru.rst
+++ b/Documentation/mm/multigen_lru.rst
@@ -89,15 +89,15 @@ variables are monotonically increasing.
@@ -51,7 +49,7 @@ index d7062c6a89464..d8f721f98868a 100644
contrast to moving across generations, which requires the LRU lock,
moving across tiers only involves atomic operations on
``folio->flags`` and therefore has a negligible cost. A feedback loop
@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MAX_NR_GENS)+1``.
@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MA
Eviction
--------
The eviction consumes old generations. Given an ``lruvec``, it
@@ -60,11 +58,9 @@ index d7062c6a89464..d8f721f98868a 100644
``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to
evict from, it first compares ``min_seq[]`` to select the older type.
If both types are equally old, it selects the one whose first tier has
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index f63968bd7de59..da38e3d962e2f 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(str
lru_gen_update_size(lruvec, folio, -1, gen);
/* for folio_rotate_reclaimable() */
if (reclaiming)
@@ -76,8 +72,6 @@ index f63968bd7de59..da38e3d962e2f 100644
return true;
}
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index bd3e4689f72dc..02e4323744715 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -312,7 +312,7 @@ enum lruvec_flags {
@@ -109,11 +103,9 @@ index bd3e4689f72dc..02e4323744715 100644
/* the multi-gen LRU sizes, eventually consistent */
long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
/* the exponential moving average of refaulted */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 27142caf284c1..b02fed912f742 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *l
/* prevent cold/hot inversion if force_scan is true */
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
@@ -122,7 +114,7 @@ index 27142caf284c1..b02fed912f742 100644
while (!list_empty(head)) {
struct folio *folio = lru_to_folio(head);
@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *l
VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio);
new_gen = folio_inc_gen(lruvec, folio, false);
@@ -131,7 +123,7 @@ index 27142caf284c1..b02fed912f742 100644
if (!--remaining)
return false;
@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lr
gen = lru_gen_from_seq(min_seq[type]);
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
@@ -140,7 +132,7 @@ index 27142caf284c1..b02fed912f742 100644
goto next;
}
@@ -4762,7 +4762,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
@@ -4762,7 +4762,7 @@ static bool sort_folio(struct lruvec *lr
/* promoted */
if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
@@ -149,7 +141,7 @@ index 27142caf284c1..b02fed912f742 100644
return true;
}
@@ -4771,7 +4771,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
@@ -4771,7 +4771,7 @@ static bool sort_folio(struct lruvec *lr
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
gen = folio_inc_gen(lruvec, folio, false);
@@ -158,7 +150,7 @@ index 27142caf284c1..b02fed912f742 100644
WRITE_ONCE(lrugen->protected[hist][type][tier - 1],
lrugen->protected[hist][type][tier - 1] + delta);
@@ -4783,7 +4783,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
@@ -4783,7 +4783,7 @@ static bool sort_folio(struct lruvec *lr
if (folio_test_locked(folio) || folio_test_writeback(folio) ||
(type == LRU_GEN_FILE && folio_test_dirty(folio))) {
gen = folio_inc_gen(lruvec, folio, true);
@@ -167,7 +159,7 @@ index 27142caf284c1..b02fed912f742 100644
return true;
}
@@ -4850,7 +4850,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
@@ -4850,7 +4850,7 @@ static int scan_folios(struct lruvec *lr
for (zone = sc->reclaim_idx; zone >= 0; zone--) {
LIST_HEAD(moved);
int skipped = 0;
@@ -176,7 +168,7 @@ index 27142caf284c1..b02fed912f742 100644
while (!list_empty(head)) {
struct folio *folio = lru_to_folio(head);
@@ -5250,7 +5250,7 @@ static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
@@ -5250,7 +5250,7 @@ static bool __maybe_unused state_is_vali
int gen, type, zone;
for_each_gen_type_zone(gen, type, zone) {
@@ -185,7 +177,7 @@ index 27142caf284c1..b02fed912f742 100644
return false;
}
}
@@ -5295,7 +5295,7 @@ static bool drain_evictable(struct lruvec *lruvec)
@@ -5295,7 +5295,7 @@ static bool drain_evictable(struct lruve
int remaining = MAX_LRU_BATCH;
for_each_gen_type_zone(gen, type, zone) {
@@ -194,7 +186,7 @@ index 27142caf284c1..b02fed912f742 100644
while (!list_empty(head)) {
bool success;
@@ -5832,7 +5832,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
@@ -5832,7 +5832,7 @@ void lru_gen_init_lruvec(struct lruvec *
lrugen->timestamps[i] = jiffies;
for_each_gen_type_zone(gen, type, zone)
@@ -203,6 +195,3 @@ index 27142caf284c1..b02fed912f742 100644
lruvec->mm_state.seq = MIN_NR_GENS;
init_waitqueue_head(&lruvec->mm_state.wait);
--
2.40.1

View File

@@ -40,11 +40,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 81 +++++++++++++++--------------------------------------
1 file changed, 23 insertions(+), 58 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b02fed912f742..991961180b320 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_control *sc)
@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_c
return sc->target_mem_cgroup;
}
@@ -56,7 +54,7 @@ index b02fed912f742..991961180b320 100644
/**
* writeback_throttling_sane - is the usual dirty throttling mechanism available?
* @sc: scan_control in question
@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_control *sc)
@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_c
return false;
}
@@ -68,7 +66,7 @@ index b02fed912f742..991961180b320 100644
static bool writeback_throttling_sane(struct scan_control *sc)
{
return true;
@@ -4993,8 +5003,7 @@ static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int sw
@@ -4993,8 +5003,7 @@ static int isolate_folios(struct lruvec
return scanned;
}
@@ -78,7 +76,7 @@ index b02fed912f742..991961180b320 100644
{
int type;
int scanned;
@@ -5083,9 +5092,6 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
@@ -5083,9 +5092,6 @@ retry:
goto retry;
}
@@ -88,7 +86,7 @@ index b02fed912f742..991961180b320 100644
return scanned;
}
@@ -5124,67 +5130,26 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *
@@ -5124,67 +5130,26 @@ done:
return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
}
@@ -165,7 +163,7 @@ index b02fed912f742..991961180b320 100644
lru_add_drain();
@@ -5208,7 +5173,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5208,7 +5173,7 @@ static void lru_gen_shrink_lruvec(struct
if (!nr_to_scan)
goto done;
@@ -174,7 +172,7 @@ index b02fed912f742..991961180b320 100644
if (!delta)
goto done;
@@ -5216,7 +5181,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5216,7 +5181,7 @@ static void lru_gen_shrink_lruvec(struct
if (scanned >= nr_to_scan)
break;
@@ -183,7 +181,7 @@ index b02fed912f742..991961180b320 100644
break;
cond_resched();
@@ -5666,7 +5631,7 @@ static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_co
@@ -5666,7 +5631,7 @@ static int run_eviction(struct lruvec *l
if (sc->nr_reclaimed >= nr_to_reclaim)
return 0;
@@ -192,6 +190,3 @@ index b02fed912f742..991961180b320 100644
return 0;
cond_resched();
--
2.40.1

View File

@@ -42,8 +42,6 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 126 ++++++++++++++++++++++++----------------------------
1 file changed, 59 insertions(+), 67 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 991961180b320..5a2e83e673232 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -136,7 +136,6 @@ struct scan_control {
@@ -54,7 +52,7 @@ index 991961180b320..5a2e83e673232 100644
unsigned long last_reclaimed;
#endif
@@ -4455,7 +4454,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4455,7 +4454,7 @@ done:
return true;
}
@@ -63,7 +61,7 @@ index 991961180b320..5a2e83e673232 100644
struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
{
int gen, type, zone;
@@ -4464,6 +4463,13 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
@@ -4464,6 +4463,13 @@ static bool should_run_aging(struct lruv
unsigned long total = 0;
struct lru_gen_folio *lrugen = &lruvec->lrugen;
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
@@ -77,7 +75,7 @@ index 991961180b320..5a2e83e673232 100644
for (type = !can_swap; type < ANON_AND_FILE; type++) {
unsigned long seq;
@@ -4492,8 +4498,6 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
@@ -4492,8 +4498,6 @@ static bool should_run_aging(struct lruv
* stalls when the number of generations reaches MIN_NR_GENS. Hence, the
* ideal number of generations is MIN_NR_GENS+1.
*/
@@ -86,7 +84,7 @@ index 991961180b320..5a2e83e673232 100644
if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
return false;
@@ -4512,40 +4516,54 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
@@ -4512,40 +4516,54 @@ static bool should_run_aging(struct lruv
return false;
}
@@ -162,7 +160,7 @@ index 991961180b320..5a2e83e673232 100644
}
/* to protect the working set of the last N jiffies */
@@ -4554,46 +4572,32 @@ static unsigned long lru_gen_min_ttl __read_mostly;
@@ -4554,46 +4572,32 @@ static unsigned long lru_gen_min_ttl __r
static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
{
struct mem_cgroup *memcg;
@@ -216,7 +214,7 @@ index 991961180b320..5a2e83e673232 100644
*/
if (mutex_trylock(&oom_lock)) {
struct oom_control oc = {
@@ -5101,33 +5105,27 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
@@ -5101,33 +5105,27 @@ retry:
* reclaim.
*/
static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
@@ -256,7 +254,7 @@ index 991961180b320..5a2e83e673232 100644
}
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
@@ -5146,9 +5144,7 @@ static unsigned long get_nr_to_reclaim(struct scan_control *sc)
@@ -5146,9 +5144,7 @@ static unsigned long get_nr_to_reclaim(s
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
{
struct blk_plug plug;
@@ -266,7 +264,7 @@ index 991961180b320..5a2e83e673232 100644
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
lru_add_drain();
@@ -5169,13 +5165,13 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5169,13 +5165,13 @@ static void lru_gen_shrink_lruvec(struct
else
swappiness = 0;
@@ -283,7 +281,7 @@ index 991961180b320..5a2e83e673232 100644
scanned += delta;
if (scanned >= nr_to_scan)
@@ -5187,10 +5183,6 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5187,10 +5183,6 @@ static void lru_gen_shrink_lruvec(struct
cond_resched();
}
@@ -294,6 +292,3 @@ index 991961180b320..5a2e83e673232 100644
clear_mm_walk();
blk_finish_plug(&plug);
--
2.40.1

View File

@@ -24,11 +24,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 124 ++++++++++++++++++++++++++--------------------------
1 file changed, 62 insertions(+), 62 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5a2e83e673232..0c47952714b26 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4454,68 +4454,6 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4454,68 +4454,6 @@ done:
return true;
}
@@ -97,7 +95,7 @@ index 5a2e83e673232..0c47952714b26 100644
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
{
int gen, type, zone;
@@ -5099,6 +5037,68 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
@@ -5099,6 +5037,68 @@ retry:
return scanned;
}
@@ -166,6 +164,3 @@ index 5a2e83e673232..0c47952714b26 100644
/*
* For future optimizations:
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
--
2.40.1

View File

@@ -74,11 +74,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 374 +++++++++++++++++++++++++++++++++----
6 files changed, 500 insertions(+), 35 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index e039763029563..82d28b052a9e5 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct obj_cgroup *objcg)
@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct
percpu_ref_put(&objcg->refcnt);
}
@@ -90,7 +88,7 @@ index e039763029563..82d28b052a9e5 100644
static inline void mem_cgroup_put(struct mem_cgroup *memcg)
{
if (memcg)
@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct obj_cgroup *objcg)
@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct
{
}
@@ -102,11 +100,9 @@ index e039763029563..82d28b052a9e5 100644
static inline void mem_cgroup_put(struct mem_cgroup *memcg)
{
}
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index da38e3d962e2f..c1fd3922dc5dd 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void)
@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void
return current->in_lru_fault;
}
@@ -125,7 +121,7 @@ index da38e3d962e2f..c1fd3922dc5dd 100644
static inline int lru_gen_from_seq(unsigned long seq)
{
return seq % MAX_NR_GENS;
@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void)
@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void
return false;
}
@@ -137,8 +133,6 @@ index da38e3d962e2f..c1fd3922dc5dd 100644
static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
{
return false;
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 02e4323744715..66e067a635682 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -7,6 +7,7 @@
@@ -180,7 +174,7 @@ index 02e4323744715..66e067a635682 100644
};
enum {
@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *lruvec);
@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *
void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
#ifdef CONFIG_MEMCG
@@ -269,7 +263,7 @@ index 02e4323744715..66e067a635682 100644
static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
{
}
@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(s
}
#ifdef CONFIG_MEMCG
@@ -277,7 +271,7 @@ index 02e4323744715..66e067a635682 100644
static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
{
}
@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(st
static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
{
}
@@ -312,11 +306,9 @@ index 02e4323744715..66e067a635682 100644
#endif
CACHELINE_PADDING(_pad2_);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3e8f1ad0fe9db..7815d556e38cc 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, int nid)
@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struc
struct mem_cgroup_per_node *mz;
struct mem_cgroup_tree_per_node *mctz;
@@ -333,7 +325,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
mctz = soft_limit_tree.rb_tree_per_node[nid];
if (!mctz)
return;
@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_recl
struct mem_cgroup_tree_per_node *mctz;
unsigned long excess;
@@ -343,7 +335,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
if (order > 0)
return 0;
@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct
if (unlikely(mem_cgroup_is_root(memcg)))
queue_delayed_work(system_unbound_wq, &stats_flush_dwork,
2UL*HZ);
@@ -351,7 +343,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
return 0;
offline_kmem:
memcg_offline_kmem(memcg);
@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struc
memcg_offline_kmem(memcg);
reparent_shrinker_deferred(memcg);
wb_memcg_offline(memcg);
@@ -359,7 +351,7 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
drain_all_stock(memcg);
@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(stru
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
invalidate_reclaim_iterators(memcg);
@@ -367,11 +359,9 @@ index 3e8f1ad0fe9db..7815d556e38cc 100644
}
static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 69668817fed37..473057b81a9df 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(int nid)
@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(i
pgdat_set_deferred_range(pgdat);
free_area_init_core(pgdat);
@@ -379,8 +369,6 @@ index 69668817fed37..473057b81a9df 100644
}
static void __init free_area_init_memoryless_node(int nid)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0c47952714b26..65eb28448f216 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -54,6 +54,8 @@
@@ -404,7 +392,7 @@ index 0c47952714b26..65eb28448f216 100644
/* Allocation order */
s8 order;
@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_caps, NR_LRU_GEN_CAPS);
@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca
for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
@@ -414,7 +402,7 @@ index 0c47952714b26..65eb28448f216 100644
static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
{
struct pglist_data *pgdat = NODE_DATA(nid);
@@ -4440,8 +4440,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4440,8 +4440,7 @@ done:
if (sc->priority <= DEF_PRIORITY - 2)
wait_event_killable(lruvec->mm_state.wait,
max_seq < READ_ONCE(lrugen->max_seq));
@@ -424,7 +412,7 @@ index 0c47952714b26..65eb28448f216 100644
}
VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
@@ -4514,8 +4513,6 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
@@ -4514,8 +4513,6 @@ static void lru_gen_age_node(struct pgli
VM_WARN_ON_ONCE(!current_is_kswapd());
@@ -433,7 +421,7 @@ index 0c47952714b26..65eb28448f216 100644
/* check the order to exclude compaction-induced reclaim */
if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
return;
@@ -5104,8 +5101,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
@@ -5104,8 +5101,7 @@ static bool should_run_aging(struct lruv
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
* reclaim.
*/
@@ -443,7 +431,7 @@ index 0c47952714b26..65eb28448f216 100644
{
unsigned long nr_to_scan;
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
@@ -5122,10 +5118,8 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *
@@ -5122,10 +5118,8 @@ static unsigned long get_nr_to_scan(stru
if (sc->priority == DEF_PRIORITY)
return nr_to_scan;
@@ -455,7 +443,7 @@ index 0c47952714b26..65eb28448f216 100644
}
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
@@ -5134,29 +5128,18 @@ static unsigned long get_nr_to_reclaim(struct scan_control *sc)
@@ -5134,29 +5128,18 @@ static unsigned long get_nr_to_reclaim(s
if (!global_reclaim(sc))
return -1;
@@ -487,7 +475,7 @@ index 0c47952714b26..65eb28448f216 100644
if (sc->may_swap)
swappiness = get_swappiness(lruvec, sc);
@@ -5166,7 +5149,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5166,7 +5149,7 @@ static void lru_gen_shrink_lruvec(struct
swappiness = 0;
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
@@ -496,7 +484,7 @@ index 0c47952714b26..65eb28448f216 100644
break;
delta = evict_folios(lruvec, sc, swappiness);
@@ -5183,11 +5166,252 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5183,10 +5166,251 @@ static void lru_gen_shrink_lruvec(struct
cond_resched();
}
@@ -621,11 +609,11 @@ index 0c47952714b26..65eb28448f216 100644
+ if (try_to_shrink_lruvec(lruvec, sc))
+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
+
clear_mm_walk();
blk_finish_plug(&plug);
}
+ clear_mm_walk();
+
+ blk_finish_plug(&plug);
+}
+
+#else /* !CONFIG_MEMCG */
+
+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
@@ -691,9 +679,9 @@ index 0c47952714b26..65eb28448f216 100644
+ if (current_is_kswapd())
+ sc->nr_reclaimed += reclaimed;
+
+ clear_mm_walk();
+
+ blk_finish_plug(&plug);
clear_mm_walk();
blk_finish_plug(&plug);
+
+ /* kswapd should never fail */
+ pgdat->kswapd_failures = 0;
@@ -743,13 +731,12 @@ index 0c47952714b26..65eb28448f216 100644
+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
+
+ spin_unlock(&pgdat->memcg_lru.lock);
+}
}
+#endif
+
/******************************************************************************
* state change
******************************************************************************/
@@ -5644,11 +5868,11 @@ static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq,
@@ -5644,11 +5868,11 @@ static int run_cmd(char cmd, int memcg_i
if (!mem_cgroup_disabled()) {
rcu_read_lock();
@@ -764,7 +751,7 @@ index 0c47952714b26..65eb28448f216 100644
rcu_read_unlock();
if (!memcg)
@@ -5796,6 +6020,19 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
@@ -5796,6 +6020,19 @@ void lru_gen_init_lruvec(struct lruvec *
}
#ifdef CONFIG_MEMCG
@@ -784,7 +771,7 @@ index 0c47952714b26..65eb28448f216 100644
void lru_gen_init_memcg(struct mem_cgroup *memcg)
{
INIT_LIST_HEAD(&memcg->mm_list.fifo);
@@ -5819,7 +6056,69 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
@@ -5819,7 +6056,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
}
}
}
@@ -855,7 +842,7 @@ index 0c47952714b26..65eb28448f216 100644
static int __init init_lru_gen(void)
{
@@ -5846,6 +6145,10 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5846,6 +6145,10 @@ static void lru_gen_shrink_lruvec(struct
{
}
@@ -866,7 +853,7 @@ index 0c47952714b26..65eb28448f216 100644
#endif /* CONFIG_LRU_GEN */
static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
@@ -5859,7 +6162,7 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
@@ -5859,7 +6162,7 @@ static void shrink_lruvec(struct lruvec
bool proportional_reclaim;
struct blk_plug plug;
@@ -875,7 +862,7 @@ index 0c47952714b26..65eb28448f216 100644
lru_gen_shrink_lruvec(lruvec, sc);
return;
}
@@ -6102,6 +6405,11 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
@@ -6102,6 +6405,11 @@ static void shrink_node(pg_data_t *pgdat
struct lruvec *target_lruvec;
bool reclaimable = false;
@@ -887,6 +874,3 @@ index 0c47952714b26..65eb28448f216 100644
target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
again:
--
2.40.1

View File

@@ -39,11 +39,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 55 +++++++++++++++++++++++++++--------------------------
1 file changed, 28 insertions(+), 27 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 65eb28448f216..0a0e1250ffc87 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
@@ -53,7 +51,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
if (!can_demote(pgdat->node_id, sc) &&
mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
return 0;
@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_
@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruve
} while (err == -EAGAIN);
}
@@ -62,7 +60,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
{
struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_wa
VM_WARN_ON_ONCE(walk);
walk = &pgdat->mm_walk;
@@ -71,7 +69,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
VM_WARN_ON_ONCE(current_is_kswapd());
walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
@@ -4417,7 +4420,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4417,7 +4420,7 @@ static bool try_to_inc_max_seq(struct lr
goto done;
}
@@ -80,7 +78,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
if (!walk) {
success = iterate_mm_list_nowalk(lruvec, max_seq);
goto done;
@@ -4486,8 +4489,6 @@ static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc
@@ -4486,8 +4489,6 @@ static bool lruvec_is_reclaimable(struct
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
DEFINE_MIN_SEQ(lruvec);
@@ -89,7 +87,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
/* see the comment on lru_gen_folio */
gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
@@ -4743,12 +4744,8 @@ static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct sca
@@ -4743,12 +4744,8 @@ static bool isolate_folio(struct lruvec
{
bool success;
@@ -103,7 +101,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
(folio_test_dirty(folio) ||
(folio_test_anon(folio) && !folio_test_swapcache(folio))))
return false;
@@ -4845,9 +4842,8 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
@@ -4845,9 +4842,8 @@ static int scan_folios(struct lruvec *lr
__count_vm_events(PGSCAN_ANON + type, isolated);
/*
@@ -115,7 +113,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
*/
return isolated || !remaining ? scanned : 0;
}
@@ -5107,8 +5103,7 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool
@@ -5107,8 +5103,7 @@ static long get_nr_to_scan(struct lruvec
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
DEFINE_MAX_SEQ(lruvec);
@@ -125,7 +123,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
return 0;
if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
@@ -5136,17 +5131,14 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
@@ -5136,17 +5131,14 @@ static bool try_to_shrink_lruvec(struct
long nr_to_scan;
unsigned long scanned = 0;
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
@@ -148,7 +146,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
if (nr_to_scan <= 0)
@@ -5277,12 +5269,13 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
@@ -5277,12 +5269,13 @@ static void lru_gen_shrink_lruvec(struct
struct blk_plug plug;
VM_WARN_ON_ONCE(global_reclaim(sc));
@@ -163,7 +161,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
if (try_to_shrink_lruvec(lruvec, sc))
lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
@@ -5338,11 +5331,19 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
@@ -5338,11 +5331,19 @@ static void lru_gen_shrink_node(struct p
VM_WARN_ON_ONCE(!global_reclaim(sc));
@@ -184,7 +182,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
set_initial_priority(pgdat, sc);
@@ -5360,7 +5361,7 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
@@ -5360,7 +5361,7 @@ static void lru_gen_shrink_node(struct p
clear_mm_walk();
blk_finish_plug(&plug);
@@ -193,7 +191,7 @@ index 65eb28448f216..0a0e1250ffc87 100644
/* kswapd should never fail */
pgdat->kswapd_failures = 0;
}
@@ -5932,7 +5933,7 @@ static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
@@ -5932,7 +5933,7 @@ static ssize_t lru_gen_seq_write(struct
set_task_reclaim_state(current, &sc.reclaim_state);
flags = memalloc_noreclaim_save();
blk_start_plug(&plug);
@@ -202,6 +200,3 @@ index 65eb28448f216..0a0e1250ffc87 100644
err = -ENOMEM;
goto done;
}
--
2.40.1

View File

@@ -25,11 +25,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0a0e1250ffc87..aa9746f2bc80b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4415,7 +4415,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4415,7 +4415,7 @@ static bool try_to_inc_max_seq(struct lr
* handful of PTEs. Spreading the work out over a period of time usually
* is less efficient, but it avoids bursty page faults.
*/
@@ -38,6 +36,3 @@ index 0a0e1250ffc87..aa9746f2bc80b 100644
success = iterate_mm_list_nowalk(lruvec, max_seq);
goto done;
}
--
2.40.1

View File

@@ -27,11 +27,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index aa9746f2bc80b..49da02f841c81 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lru
static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
{
@@ -54,7 +52,7 @@ index aa9746f2bc80b..49da02f841c81 100644
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
rcu_read_lock();
@@ -5241,14 +5243,22 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
@@ -5241,14 +5243,22 @@ restart:
op = shrink_one(lruvec, sc);
@@ -80,7 +78,7 @@ index aa9746f2bc80b..49da02f841c81 100644
/* restart if raced with lru_gen_rotate_memcg() */
if (gen != get_nulls_value(pos))
goto restart;
@@ -5257,11 +5267,6 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
@@ -5257,11 +5267,6 @@ restart:
bin = get_memcg_bin(bin + 1);
if (bin != first_bin)
goto restart;
@@ -92,6 +90,3 @@ index aa9746f2bc80b..49da02f841c81 100644
}
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
--
2.40.1

View File

@@ -60,11 +60,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 5 ++++-
4 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index c1fd3922dc5dd..7bb2e5f94734c 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -595,4 +595,12 @@ pte_install_uffd_wp_if_needed(struct vm_area_struct *vma, unsigned long addr,
@@ -595,4 +595,12 @@ pte_install_uffd_wp_if_needed(struct vm_
#endif
}
@@ -77,11 +75,9 @@ index c1fd3922dc5dd..7bb2e5f94734c 100644
+}
+
#endif
diff --git a/mm/memory.c b/mm/memory.c
index 747b7ea30f890..c2f48f8003c2e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1435,8 +1435,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
@@ -1435,8 +1435,7 @@ again:
force_flush = 1;
set_page_dirty(page);
}
@@ -91,7 +87,7 @@ index 747b7ea30f890..c2f48f8003c2e 100644
mark_page_accessed(page);
}
rss[mm_counter(page)]--;
@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(struct pt_regs *regs,
@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(stru
#ifdef CONFIG_LRU_GEN
static void lru_gen_enter_fault(struct vm_area_struct *vma)
{
@@ -102,11 +98,9 @@ index 747b7ea30f890..c2f48f8003c2e 100644
}
static void lru_gen_exit_fault(void)
diff --git a/mm/rmap.c b/mm/rmap.c
index 7da2d8d097d9b..825dac3caa1e5 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct folio *folio,
@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct
}
if (pvmw.pte) {
@@ -135,7 +129,7 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
} else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
if (pmdp_clear_flush_young_notify(vma, address,
pvmw.pmd))
@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma(struct vm_area_struct *vma, void *arg)
@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma
struct folio_referenced_arg *pra = arg;
struct mem_cgroup *memcg = pra->memcg;
@@ -157,7 +151,7 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
return true;
return false;
@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio, int is_locked,
@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio
.arg = (void *)&pra,
.anon_lock = folio_lock_anon_vma_read,
.try_lock = true,
@@ -165,7 +159,7 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
};
*vm_flags = 0;
@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio, int is_locked,
@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio
return 1;
}
@@ -181,11 +175,9 @@ index 7da2d8d097d9b..825dac3caa1e5 100644
rmap_walk(folio, &rwc);
*vm_flags = pra.vm_flags;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 49da02f841c81..596fed6ae0439 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long start, unsigned long end, struct mm_wal
@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long
if (is_vm_hugetlb_page(vma))
return true;
@@ -197,6 +189,3 @@ index 49da02f841c81..596fed6ae0439 100644
return true;
if (vma == get_gate_vma(vma->vm_mm))
--
2.40.1

View File

@@ -83,11 +83,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/fadvise.c | 5 ++++-
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f14ecbeab2a9d..97f9c41c1a43a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb
/* File supports DIRECT IO */
#define FMODE_CAN_ODIRECT ((__force fmode_t)0x400000)
@@ -96,11 +94,9 @@ index f14ecbeab2a9d..97f9c41c1a43a 100644
/* File was opened by fanotify and shouldn't generate fanotify events */
#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 7bb2e5f94734c..9a8e2049333c0 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -600,6 +600,9 @@ static inline bool vma_has_recency(struct vm_area_struct *vma)
@@ -600,6 +600,9 @@ static inline bool vma_has_recency(struc
if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
return false;
@@ -110,11 +106,9 @@ index 7bb2e5f94734c..9a8e2049333c0 100644
return true;
}
diff --git a/mm/fadvise.c b/mm/fadvise.c
index c76ee665355a4..2ba24d865bf5f 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l
case POSIX_FADV_NORMAL:
file->f_ra.ra_pages = bdi->ra_pages;
spin_lock(&file->f_lock);
@@ -123,7 +117,7 @@ index c76ee665355a4..2ba24d865bf5f 100644
spin_unlock(&file->f_lock);
break;
case POSIX_FADV_RANDOM:
@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l
force_page_cache_readahead(mapping, file, start_index, nrpages);
break;
case POSIX_FADV_NOREUSE:
@@ -133,6 +127,3 @@ index c76ee665355a4..2ba24d865bf5f 100644
break;
case POSIX_FADV_DONTNEED:
__filemap_fdatawrite_range(mapping, offset, endbyte,
--
2.40.1

View File

@@ -28,11 +28,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 4 ++++
2 files changed, 19 insertions(+)
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
index d8f721f98868a..6e1483e70fdca 100644
--- a/Documentation/mm/multigen_lru.rst
+++ b/Documentation/mm/multigen_lru.rst
@@ -141,6 +141,21 @@ loop has detected outlying refaults from the tier this page is in. To
@@ -141,6 +141,21 @@ loop has detected outlying refaults from
this end, the feedback loop uses the first tier as the baseline, for
the reason stated earlier.
@@ -54,11 +52,9 @@ index d8f721f98868a..6e1483e70fdca 100644
Summary
-------
The multi-gen LRU can be disassembled into the following parts:
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 596fed6ae0439..ab0b8d3b9d88f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4459,6 +4459,10 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4459,6 +4459,10 @@ done:
return true;
}
@@ -69,6 +65,3 @@ index 596fed6ae0439..ab0b8d3b9d88f 100644
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
{
int gen, type, zone;
--
2.40.1

View File

@@ -19,11 +19,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 4 ++++
2 files changed, 18 insertions(+)
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
index 6e1483e70fdca..bd988a142bc2f 100644
--- a/Documentation/mm/multigen_lru.rst
+++ b/Documentation/mm/multigen_lru.rst
@@ -156,6 +156,20 @@ This time-based approach has the following advantages:
@@ -156,6 +156,20 @@ This time-based approach has the followi
and memory sizes.
2. It is more reliable because it is directly wired to the OOM killer.
@@ -44,11 +42,9 @@ index 6e1483e70fdca..bd988a142bc2f 100644
Summary
-------
The multi-gen LRU can be disassembled into the following parts:
diff --git a/mm/vmscan.c b/mm/vmscan.c
index ab0b8d3b9d88f..8fa82630240d6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4553,6 +4553,10 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
@@ -4553,6 +4553,10 @@ static void lru_gen_age_node(struct pgli
}
}
@@ -59,6 +55,3 @@ index ab0b8d3b9d88f..8fa82630240d6 100644
/*
* This function exploits spatial locality when shrink_folio_list() walks the
* rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If
--
2.40.1

View File

@@ -20,11 +20,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 180 +++++++++++++++---------------
2 files changed, 108 insertions(+), 88 deletions(-)
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
index bd988a142bc2f..770b5d539856c 100644
--- a/Documentation/mm/multigen_lru.rst
+++ b/Documentation/mm/multigen_lru.rst
@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done cacheline efficiently, it
@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done
adds the PMD entry pointing to the PTE table to the Bloom filter. This
forms a feedback loop between the eviction and the aging.
@@ -47,15 +45,12 @@ index bd988a142bc2f..770b5d539856c 100644
Summary
-------
The multi-gen LRU can be disassembled into the following parts:
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 8fa82630240d6..74b4f9d660b56 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3208,6 +3208,98 @@ static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS;
@@ -3209,6 +3209,98 @@ static bool __maybe_unused seq_is_valid(
}
+/******************************************************************************
/******************************************************************************
+ * Bloom filters
+ ******************************************************************************/
+
@@ -147,10 +142,11 @@ index 8fa82630240d6..74b4f9d660b56 100644
+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
+}
+
/******************************************************************************
+/******************************************************************************
* mm_struct list
******************************************************************************/
@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct *mm)
@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct
}
#endif
@@ -245,6 +241,3 @@ index 8fa82630240d6..74b4f9d660b56 100644
static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last)
{
int i;
--
2.40.1

View File

@@ -22,11 +22,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 250 +++++++++++++++++-------------
5 files changed, 178 insertions(+), 143 deletions(-)
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
index 770b5d539856c..5f1f6ecbb79b9 100644
--- a/Documentation/mm/multigen_lru.rst
+++ b/Documentation/mm/multigen_lru.rst
@@ -186,9 +186,40 @@ is false positive, the cost is an additional scan of a range of PTEs,
@@ -186,9 +186,40 @@ is false positive, the cost is an additi
which may yield hot pages anyway. Parameters of the filter itself can
control the false positive rate in the limit.
@@ -68,11 +66,9 @@ index 770b5d539856c..5f1f6ecbb79b9 100644
* Generations
* Rmap walks
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 9a8e2049333c0..5567f4850243b 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void)
@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void
return current->in_lru_fault;
}
@@ -91,7 +87,7 @@ index 9a8e2049333c0..5567f4850243b 100644
static inline int lru_gen_from_seq(unsigned long seq)
{
return seq % MAX_NR_GENS;
@@ -309,11 +297,6 @@ static inline bool lru_gen_in_fault(void)
@@ -309,11 +297,6 @@ static inline bool lru_gen_in_fault(void
return false;
}
@@ -103,8 +99,6 @@ index 9a8e2049333c0..5567f4850243b 100644
static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
{
return false;
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 66e067a635682..403c7461e7a70 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -368,15 +368,6 @@ struct page_vma_mapped_walk;
@@ -123,7 +117,7 @@ index 66e067a635682..403c7461e7a70 100644
#ifdef CONFIG_LRU_GEN
enum {
@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg);
@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgrou
void lru_gen_online_memcg(struct mem_cgroup *memcg);
void lru_gen_offline_memcg(struct mem_cgroup *memcg);
void lru_gen_release_memcg(struct mem_cgroup *memcg);
@@ -132,7 +126,7 @@ index 66e067a635682..403c7461e7a70 100644
#else /* !CONFIG_MEMCG */
@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg
{
}
@@ -141,11 +135,9 @@ index 66e067a635682..403c7461e7a70 100644
{
}
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 7815d556e38cc..5397aeb43986d 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, int nid)
@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struc
struct mem_cgroup_tree_per_node *mctz;
if (lru_gen_enabled()) {
@@ -160,15 +152,12 @@ index 7815d556e38cc..5397aeb43986d 100644
return;
}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 74b4f9d660b56..ccde215c084ca 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4689,6 +4689,148 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
mem_cgroup_unlock_pages();
@@ -4690,6 +4690,148 @@ void lru_gen_look_around(struct page_vma
}
+/******************************************************************************
/******************************************************************************
+ * memcg LRU
+ ******************************************************************************/
+
@@ -310,10 +299,11 @@ index 74b4f9d660b56..ccde215c084ca 100644
+
+#endif
+
/******************************************************************************
+/******************************************************************************
* the eviction
******************************************************************************/
@@ -5386,53 +5528,6 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
@@ -5386,53 +5528,6 @@ done:
pgdat->kswapd_failures = 0;
}
@@ -367,7 +357,7 @@ index 74b4f9d660b56..ccde215c084ca 100644
/******************************************************************************
* state change
******************************************************************************/
@@ -6078,67 +6173,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
@@ -6078,67 +6173,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
}
}
@@ -435,6 +425,3 @@ index 74b4f9d660b56..ccde215c084ca 100644
#endif /* CONFIG_MEMCG */
static int __init init_lru_gen(void)
--
2.40.1

View File

@@ -18,11 +18,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index ccde215c084ca..d5d6f8d94f58a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -6160,12 +6160,17 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
@@ -6160,12 +6160,17 @@ void lru_gen_exit_memcg(struct mem_cgrou
int i;
int nid;
@@ -40,6 +38,3 @@ index ccde215c084ca..d5d6f8d94f58a 100644
for (i = 0; i < NR_BLOOM_FILTERS; i++) {
bitmap_free(lruvec->mm_state.filters[i]);
lruvec->mm_state.filters[i] = NULL;
--
2.40.1

View File

@@ -17,11 +17,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d5d6f8d94f58a..8f496c2e670a9 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3980,8 +3980,8 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
@@ -3980,8 +3980,8 @@ restart:
}
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
@@ -32,7 +30,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
{
int i;
pmd_t *pmd;
@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t
VM_WARN_ON_ONCE(pud_leaf(*pud));
/* try to batch at most 1+MIN_LRU_BATCH+1 entries */
@@ -56,7 +54,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
ptl = pmd_lockptr(args->mm, pmd);
if (!spin_trylock(ptl))
@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t
do {
unsigned long pfn;
struct folio *folio;
@@ -76,7 +74,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
pmdp_test_and_clear_young(vma, addr, pmd + i);
goto next;
}
@@ -4053,12 +4055,11 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
@@ -4053,12 +4055,11 @@ next:
arch_leave_lazy_mmu_mode();
spin_unlock(ptl);
done:
@@ -92,7 +90,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
{
}
#endif
@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, u
unsigned long next;
unsigned long addr;
struct vm_area_struct *vma;
@@ -104,7 +102,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
VM_WARN_ON_ONCE(pud_leaf(*pud));
@@ -4115,18 +4116,17 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
@@ -4115,18 +4116,17 @@ restart:
if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
continue;
@@ -126,7 +124,7 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
}
if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
@@ -4143,7 +4143,7 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
@@ -4143,7 +4143,7 @@ restart:
update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i);
}
@@ -135,6 +133,3 @@ index d5d6f8d94f58a..8f496c2e670a9 100644
if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end))
goto restart;
--
2.40.1

View File

@@ -24,11 +24,9 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mm/vmscan.c | 73 +++++++++++++++++------------------------------------
1 file changed, 23 insertions(+), 50 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 8f496c2e670a9..f6ce7a1fd78a3 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4571,13 +4571,12 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
@@ -4571,13 +4571,12 @@ static void lru_gen_age_node(struct pgli
void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
{
int i;
@@ -44,7 +42,7 @@ index 8f496c2e670a9..f6ce7a1fd78a3 100644
struct folio *folio = pfn_folio(pvmw->pfn);
struct mem_cgroup *memcg = folio_memcg(folio);
struct pglist_data *pgdat = folio_pgdat(folio);
@@ -4594,25 +4593,28 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
@@ -4594,25 +4593,28 @@ void lru_gen_look_around(struct page_vma
/* avoid taking the LRU lock under the PTL when possible */
walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
@@ -81,7 +79,7 @@ index 8f496c2e670a9..f6ce7a1fd78a3 100644
for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
unsigned long pfn;
@@ -4637,56 +4639,27 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
@@ -4637,56 +4639,27 @@ void lru_gen_look_around(struct page_vma
!folio_test_swapcache(folio)))
folio_mark_dirty(folio);
@@ -148,6 +146,3 @@ index 8f496c2e670a9..f6ce7a1fd78a3 100644
}
/******************************************************************************
--
2.40.1

View File

@@ -46,8 +46,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/vmscan.c | 112 +++++++++++++++--------------------------
2 files changed, 42 insertions(+), 78 deletions(-)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 403c7461e7a70..d62a5accf1be4 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -453,18 +453,14 @@ enum {
@@ -71,11 +69,9 @@ index 403c7461e7a70..d62a5accf1be4 100644
};
struct lru_gen_mm_walk {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f6ce7a1fd78a3..851758303dbf4 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm)
@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm
if (!lruvec)
continue;
@@ -99,7 +95,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
}
list_del_init(&mm->lru_gen.list);
@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruve
struct mm_struct **iter)
{
bool first = false;
@@ -191,7 +187,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
if (*iter || last)
reset_mm_stats(lruvec, walk, last);
@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struct lruvec *lruvec, unsigned long max_seq)
@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struc
VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
@@ -204,7 +200,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
reset_mm_stats(lruvec, NULL, true);
success = true;
@@ -4172,10 +4153,6 @@ static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
@@ -4172,10 +4153,6 @@ restart:
walk_pmd_range(&val, addr, next, args);
@@ -215,7 +211,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
end = (addr | ~PUD_MASK) + 1;
goto done;
@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_
@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruve
walk->next_addr = FIRST_USER_ADDRESS;
do {
@@ -230,7 +226,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
/* folio_update_gen() requires stable folio_memcg() */
if (!mem_cgroup_trylock_pages(memcg))
break;
@@ -4442,25 +4425,12 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
@@ -4442,25 +4425,12 @@ static bool try_to_inc_max_seq(struct lr
success = iterate_mm_list(lruvec, walk, &mm);
if (mm)
walk_mm(lruvec, mm, walk);
@@ -259,7 +255,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
}
/******************************************************************************
@@ -6105,7 +6075,6 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
@@ -6105,7 +6075,6 @@ void lru_gen_init_lruvec(struct lruvec *
INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]);
lruvec->mm_state.seq = MIN_NR_GENS;
@@ -267,7 +263,7 @@ index f6ce7a1fd78a3..851758303dbf4 100644
}
#ifdef CONFIG_MEMCG
@@ -6138,7 +6107,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
@@ -6138,7 +6107,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
for_each_node(nid) {
struct lruvec *lruvec = get_lruvec(memcg, nid);
@@ -275,6 +271,3 @@ index f6ce7a1fd78a3..851758303dbf4 100644
VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
sizeof(lruvec->lrugen.nr_pages)));
--
2.40.1

View File

@@ -0,0 +1,32 @@
From c3552d3f85f06cf4b4818bd84c4fcc09d8d45165 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:17:19 +0100
Subject: [PATCH 01/13] net: dsa: mt7530: make some noise if register read
fails
Simply returning the negative error value instead of the read value
doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1)
so this kind of error will not go unnoticed.
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -224,9 +224,10 @@ mt7530_mii_read(struct mt7530_priv *priv
/* MT7530 uses 31 as the pseudo port */
ret = bus->write(bus, 0x1f, 0x1f, page);
if (ret < 0) {
+ WARN_ON_ONCE(1);
dev_err(&bus->dev,
"failed to read mt7530 register\n");
- return ret;
+ return 0;
}
lo = bus->read(bus, 0x1f, r);

View File

@@ -0,0 +1,111 @@
From b896355fc4988216d4f38582d07add9252a795ae Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:17:30 +0100
Subject: [PATCH 02/13] net: dsa: mt7530: refactor SGMII PCS creation
Instead of macro templates use a dedidated function and allocated
regmap_config when creating the regmaps for the pcs-mtk-lynxi
instances.
This is in preparation to switching to use unlocked regmap accessors
and have regmap's locking API handle locking for us.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++-------------
1 file changed, 50 insertions(+), 24 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2950,26 +2950,56 @@ static const struct regmap_bus mt7531_re
.reg_update_bits = mt7530_regmap_update_bits,
};
-#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
- { \
- .name = _name, \
- .reg_bits = 16, \
- .val_bits = 32, \
- .reg_stride = 4, \
- .reg_base = _reg_base, \
- .max_register = 0x17c, \
+static int
+mt7531_create_sgmii(struct mt7530_priv *priv)
+{
+ struct regmap_config *mt7531_pcs_config[2];
+ struct phylink_pcs *pcs;
+ struct regmap *regmap;
+ int i, ret = 0;
+
+ for (i = 0; i < 2; i++) {
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
+ sizeof(struct regmap_config),
+ GFP_KERNEL);
+ if (!mt7531_pcs_config[i]) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
+ mt7531_pcs_config[i]->reg_bits = 16;
+ mt7531_pcs_config[i]->val_bits = 32;
+ mt7531_pcs_config[i]->reg_stride = 4;
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
+ mt7531_pcs_config[i]->max_register = 0x17c;
+
+ regmap = devm_regmap_init(priv->dev,
+ &mt7531_regmap_bus, priv,
+ mt7531_pcs_config[i]);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ break;
+ }
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
+ if (!pcs) {
+ ret = -ENXIO;
+ break;
+ }
+ priv->ports[5 + i].sgmii_pcs = pcs;
}
-static const struct regmap_config mt7531_pcs_config[] = {
- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
-};
+ if (ret && i)
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
+
+ return ret;
+}
static int
mt753x_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
- struct regmap *regmap;
int i, ret;
/* Initialise the PCS devices */
@@ -2991,15 +3021,11 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
- if (priv->id == ID_MT7531)
- for (i = 0; i < 2; i++) {
- regmap = devm_regmap_init(ds->dev,
- &mt7531_regmap_bus, priv,
- &mt7531_pcs_config[i]);
- priv->ports[5 + i].sgmii_pcs =
- mtk_pcs_lynxi_create(ds->dev, regmap,
- MT7531_PHYA_CTRL_SIGNAL3, 0);
- }
+ if (priv->id == ID_MT7531) {
+ ret = mt7531_create_sgmii(priv);
+ if (ret && priv->irq)
+ mt7530_free_irq_common(priv);
+ }
return ret;
}

View File

@@ -0,0 +1,74 @@
From 33396408776385f3d2f6069646169a6b5b28e3b3 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:17:40 +0100
Subject: [PATCH 03/13] net: dsa: mt7530: use unlocked regmap accessors
Instead of wrapping the locked register accessor functions, use the
unlocked variants and add locking wrapper functions to let regmap
handle the locking.
This is a preparation towards being able to always use regmap to
access switch registers instead of open-coded accessor functions.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2923,7 +2923,7 @@ static int mt7530_regmap_read(void *cont
{
struct mt7530_priv *priv = context;
- *val = mt7530_read(priv, reg);
+ *val = mt7530_mii_read(priv, reg);
return 0;
};
@@ -2931,23 +2931,25 @@ static int mt7530_regmap_write(void *con
{
struct mt7530_priv *priv = context;
- mt7530_write(priv, reg, val);
+ mt7530_mii_write(priv, reg, val);
return 0;
};
-static int mt7530_regmap_update_bits(void *context, unsigned int reg,
- unsigned int mask, unsigned int val)
+static void
+mt7530_mdio_regmap_lock(void *mdio_lock)
{
- struct mt7530_priv *priv = context;
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
+}
- mt7530_rmw(priv, reg, mask, val);
- return 0;
-};
+static void
+mt7530_mdio_regmap_unlock(void *mdio_lock)
+{
+ mutex_unlock(mdio_lock);
+}
static const struct regmap_bus mt7531_regmap_bus = {
.reg_write = mt7530_regmap_write,
.reg_read = mt7530_regmap_read,
- .reg_update_bits = mt7530_regmap_update_bits,
};
static int
@@ -2973,6 +2975,9 @@ mt7531_create_sgmii(struct mt7530_priv *
mt7531_pcs_config[i]->reg_stride = 4;
mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
mt7531_pcs_config[i]->max_register = 0x17c;
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
regmap = devm_regmap_init(priv->dev,
&mt7531_regmap_bus, priv,

View File

@@ -0,0 +1,224 @@
From 743cba4345cb366248f9d375c6a9e50243dc0677 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:17:52 +0100
Subject: [PATCH 04/13] net: dsa: mt7530: use regmap to access switch register
space
Use regmap API to access the switch register space.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++----------------
drivers/net/dsa/mt7530.h | 2 +
2 files changed, 62 insertions(+), 39 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -183,9 +183,9 @@ core_clear(struct mt7530_priv *priv, u32
}
static int
-mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
{
- struct mii_bus *bus = priv->bus;
+ struct mii_bus *bus = context;
u16 page, r, lo, hi;
int ret;
@@ -197,24 +197,34 @@ mt7530_mii_write(struct mt7530_priv *pri
/* MT7530 uses 31 as the pseudo port */
ret = bus->write(bus, 0x1f, 0x1f, page);
if (ret < 0)
- goto err;
+ return ret;
ret = bus->write(bus, 0x1f, r, lo);
if (ret < 0)
- goto err;
+ return ret;
ret = bus->write(bus, 0x1f, 0x10, hi);
-err:
+ return ret;
+}
+
+static int
+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
+{
+ int ret;
+
+ ret = regmap_write(priv->regmap, reg, val);
+
if (ret < 0)
- dev_err(&bus->dev,
+ dev_err(priv->dev,
"failed to write mt7530 register\n");
+
return ret;
}
-static u32
-mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
+static int
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
{
- struct mii_bus *bus = priv->bus;
+ struct mii_bus *bus = context;
u16 page, r, lo, hi;
int ret;
@@ -223,17 +233,32 @@ mt7530_mii_read(struct mt7530_priv *priv
/* MT7530 uses 31 as the pseudo port */
ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0) {
+ if (ret < 0)
+ return ret;
+
+ lo = bus->read(bus, 0x1f, r);
+ hi = bus->read(bus, 0x1f, 0x10);
+
+ *val = (hi << 16) | (lo & 0xffff);
+
+ return 0;
+}
+
+static u32
+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
+{
+ int ret;
+ u32 val;
+
+ ret = regmap_read(priv->regmap, reg, &val);
+ if (ret) {
WARN_ON_ONCE(1);
- dev_err(&bus->dev,
+ dev_err(priv->dev,
"failed to read mt7530 register\n");
return 0;
}
- lo = bus->read(bus, 0x1f, r);
- hi = bus->read(bus, 0x1f, 0x10);
-
- return (hi << 16) | (lo & 0xffff);
+ return val;
}
static void
@@ -283,14 +308,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32
u32 mask, u32 set)
{
struct mii_bus *bus = priv->bus;
- u32 val;
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
- val = mt7530_mii_read(priv, reg);
- val &= ~mask;
- val |= set;
- mt7530_mii_write(priv, reg, val);
+ regmap_update_bits(priv->regmap, reg, mask, set);
mutex_unlock(&bus->mdio_lock);
}
@@ -298,7 +319,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32
static void
mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
{
- mt7530_rmw(priv, reg, 0, val);
+ mt7530_rmw(priv, reg, val, val);
}
static void
@@ -2919,22 +2940,6 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
-static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-{
- struct mt7530_priv *priv = context;
-
- *val = mt7530_mii_read(priv, reg);
- return 0;
-};
-
-static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-{
- struct mt7530_priv *priv = context;
-
- mt7530_mii_write(priv, reg, val);
- return 0;
-};
-
static void
mt7530_mdio_regmap_lock(void *mdio_lock)
{
@@ -2947,7 +2952,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
mutex_unlock(mdio_lock);
}
-static const struct regmap_bus mt7531_regmap_bus = {
+static const struct regmap_bus mt7530_regmap_bus = {
.reg_write = mt7530_regmap_write,
.reg_read = mt7530_regmap_read,
};
@@ -2980,7 +2985,7 @@ mt7531_create_sgmii(struct mt7530_priv *
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
regmap = devm_regmap_init(priv->dev,
- &mt7531_regmap_bus, priv,
+ &mt7530_regmap_bus, priv->bus,
mt7531_pcs_config[i]);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
@@ -3145,6 +3150,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
static int
mt7530_probe(struct mdio_device *mdiodev)
{
+ static struct regmap_config *regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
@@ -3224,6 +3230,21 @@ mt7530_probe(struct mdio_device *mdiodev
mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv);
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
+ GFP_KERNEL);
+ if (!regmap_config)
+ return -ENOMEM;
+
+ regmap_config->reg_bits = 16;
+ regmap_config->val_bits = 32;
+ regmap_config->reg_stride = 4;
+ regmap_config->max_register = MT7530_CREV;
+ regmap_config->disable_locking = true;
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
+ priv->bus, regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
return dsa_register_switch(priv->ds);
}
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -747,6 +747,7 @@ struct mt753x_info {
* @dev: The device pointer
* @ds: The pointer to the dsa core structure
* @bus: The bus used for the device and built-in PHY
+ * @regmap: The regmap instance representing all switch registers
* @rstc: The pointer to reset control used by MCM
* @core_pwr: The power supplied into the core
* @io_pwr: The power supplied into the I/O
@@ -767,6 +768,7 @@ struct mt7530_priv {
struct device *dev;
struct dsa_switch *ds;
struct mii_bus *bus;
+ struct regmap *regmap;
struct reset_control *rstc;
struct regulator *core_pwr;
struct regulator *io_pwr;

View File

@@ -0,0 +1,54 @@
From f3cf1d06e2aef644b426c23b4bb570780b1f8d47 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:18:04 +0100
Subject: [PATCH 05/13] net: dsa: mt7530: move SGMII PCS creation to
mt7530_probe function
Move creating the SGMII PCS from mt753x_setup() to the more appropriate
mt7530_probe() function.
This is done also in preparation of moving all functions related to
MDIO-connected MT753x switches to a separate module.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3031,12 +3031,6 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
- if (priv->id == ID_MT7531) {
- ret = mt7531_create_sgmii(priv);
- if (ret && priv->irq)
- mt7530_free_irq_common(priv);
- }
-
return ret;
}
@@ -3153,6 +3147,7 @@ mt7530_probe(struct mdio_device *mdiodev
static struct regmap_config *regmap_config;
struct mt7530_priv *priv;
struct device_node *dn;
+ int ret;
dn = mdiodev->dev.of_node;
@@ -3245,6 +3240,12 @@ mt7530_probe(struct mdio_device *mdiodev
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
+ if (priv->id == ID_MT7531) {
+ ret = mt7531_create_sgmii(priv);
+ if (ret)
+ return ret;
+ }
+
return dsa_register_switch(priv->ds);
}

View File

@@ -0,0 +1,273 @@
From e4729ae7c095c0c87794bff47ea43e35d69de986 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:18:16 +0100
Subject: [PATCH 06/13] net: dsa: mt7530: introduce mutex helpers
As the MDIO bus lock only needs to be involved if actually operating
on an MDIO-connected switch we will need to skip locking for built-in
switches which are accessed via MMIO.
Create helper functions which simplify that upcoming change.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 37 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -143,31 +143,40 @@ err:
}
static void
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+mt7530_mutex_lock(struct mt7530_priv *priv)
{
- struct mii_bus *bus = priv->bus;
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+}
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+static void
+mt7530_mutex_unlock(struct mt7530_priv *priv)
+{
+ mutex_unlock(&priv->bus->mdio_lock);
+}
+
+static void
+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+{
+ mt7530_mutex_lock(priv);
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static void
core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
{
- struct mii_bus *bus = priv->bus;
u32 val;
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
val &= ~mask;
val |= set;
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static void
@@ -264,13 +273,11 @@ mt7530_mii_read(struct mt7530_priv *priv
static void
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
- struct mii_bus *bus = priv->bus;
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
mt7530_mii_write(priv, reg, val);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static u32
@@ -282,14 +289,13 @@ _mt7530_unlocked_read(struct mt7530_dumm
static u32
_mt7530_read(struct mt7530_dummy_poll *p)
{
- struct mii_bus *bus = p->priv->bus;
u32 val;
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(p->priv);
val = mt7530_mii_read(p->priv, p->reg);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(p->priv);
return val;
}
@@ -307,13 +313,11 @@ static void
mt7530_rmw(struct mt7530_priv *priv, u32 reg,
u32 mask, u32 set)
{
- struct mii_bus *bus = priv->bus;
-
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
regmap_update_bits(priv->regmap, reg, mask, set);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static void
@@ -645,14 +649,13 @@ static int
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
int regnum)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
u32 reg, val;
int ret;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -685,7 +688,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -694,14 +697,13 @@ static int
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
int regnum, u32 data)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
u32 val, reg;
int ret;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -733,7 +735,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
}
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -741,14 +743,13 @@ out:
static int
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
int ret;
u32 val;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
!(val & MT7531_PHY_ACS_ST), 20, 100000);
@@ -771,7 +772,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
ret = val & MT7531_MDIO_RW_DATA_MASK;
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -780,14 +781,13 @@ static int
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
u16 data)
{
- struct mii_bus *bus = priv->bus;
struct mt7530_dummy_poll p;
int ret;
u32 reg;
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
@@ -809,7 +809,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
}
out:
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return ret;
}
@@ -1109,7 +1109,6 @@ static int
mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{
struct mt7530_priv *priv = ds->priv;
- struct mii_bus *bus = priv->bus;
int length;
u32 val;
@@ -1120,7 +1119,7 @@ mt7530_port_change_mtu(struct dsa_switch
if (!dsa_is_cpu_port(ds, port))
return 0;
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
val = mt7530_mii_read(priv, MT7530_GMACCR);
val &= ~MAX_RX_PKT_LEN_MASK;
@@ -1141,7 +1140,7 @@ mt7530_port_change_mtu(struct dsa_switch
mt7530_mii_write(priv, MT7530_GMACCR, val);
- mutex_unlock(&bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
return 0;
}
@@ -1942,10 +1941,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
u32 val;
int p;
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
- mutex_unlock(&priv->bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
for (p = 0; p < MT7530_NUM_PHYS; p++) {
if (BIT(p) & val) {
@@ -1981,7 +1980,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
{
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+ mt7530_mutex_lock(priv);
}
static void
@@ -1990,7 +1989,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
- mutex_unlock(&priv->bus->mdio_lock);
+ mt7530_mutex_unlock(priv);
}
static struct irq_chip mt7530_irq_chip = {

View File

@@ -0,0 +1,75 @@
From 0d7ae94a0c581f86939bebec0b6ccd66e640d1d8 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:18:28 +0100
Subject: [PATCH 07/13] net: dsa: mt7530: move p5_intf_modes() function to
mt7530.c
In preparation of splitting mt7530.c into a driver for MDIO-connected
as well as MDIO-accessed built-in switches on one hand and MMIO-accessed
built-in switches move the p5_inft_modes() function from mt7530.h to
mt7530.c. The function is only needed there and will trigger a compiler
warning about a defined but unused function otherwise when including
mt7530.h in the to-be-introduced bus-specific drivers.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++
drivers/net/dsa/mt7530.h | 18 ------------------
2 files changed, 18 insertions(+), 18 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -950,6 +950,24 @@ mt7530_set_ageing_time(struct dsa_switch
return 0;
}
+static const char *p5_intf_modes(unsigned int p5_interface)
+{
+ switch (p5_interface) {
+ case P5_DISABLED:
+ return "DISABLED";
+ case P5_INTF_SEL_PHY_P0:
+ return "PHY P0";
+ case P5_INTF_SEL_PHY_P4:
+ return "PHY P4";
+ case P5_INTF_SEL_GMAC5:
+ return "GMAC5";
+ case P5_INTF_SEL_GMAC5_SGMII:
+ return "GMAC5_SGMII";
+ default:
+ return "unknown";
+ }
+}
+
static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
{
struct mt7530_priv *priv = ds->priv;
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -682,24 +682,6 @@ enum p5_interface_select {
P5_INTF_SEL_GMAC5_SGMII,
};
-static const char *p5_intf_modes(unsigned int p5_interface)
-{
- switch (p5_interface) {
- case P5_DISABLED:
- return "DISABLED";
- case P5_INTF_SEL_PHY_P0:
- return "PHY P0";
- case P5_INTF_SEL_PHY_P4:
- return "PHY P4";
- case P5_INTF_SEL_GMAC5:
- return "GMAC5";
- case P5_INTF_SEL_GMAC5_SGMII:
- return "GMAC5_SGMII";
- default:
- return "unknown";
- }
-}
-
struct mt7530_priv;
struct mt753x_pcs {

View File

@@ -0,0 +1,155 @@
From 4d632005c90e253c000d0db73b7cdb9d8dc2e2dd Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:18:39 +0100
Subject: [PATCH 08/13] net: dsa: mt7530: introduce mt7530_probe_common helper
function
Move commonly used parts from mt7530_probe into new mt7530_probe_common
helper function which will be used by both, mt7530_probe and the
to-be-introduced mt7988_probe.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 44 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3159,44 +3159,21 @@ static const struct of_device_id mt7530_
MODULE_DEVICE_TABLE(of, mt7530_of_match);
static int
-mt7530_probe(struct mdio_device *mdiodev)
+mt7530_probe_common(struct mt7530_priv *priv)
{
- static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
- int ret;
+ struct device *dev = priv->dev;
- dn = mdiodev->dev.of_node;
-
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
if (!priv->ds)
return -ENOMEM;
- priv->ds->dev = &mdiodev->dev;
+ priv->ds->dev = dev;
priv->ds->num_ports = MT7530_NUM_PORTS;
- /* Use medatek,mcm property to distinguish hardware type that would
- * casues a little bit differences on power-on sequence.
- */
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
- if (priv->mcm) {
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
- if (IS_ERR(priv->rstc)) {
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
- return PTR_ERR(priv->rstc);
- }
- }
-
/* Get the hardware identifier from the devicetree node.
* We will need it for some of the clock and regulator setup.
*/
- priv->info = of_device_get_match_data(&mdiodev->dev);
+ priv->info = of_device_get_match_data(dev);
if (!priv->info)
return -EINVAL;
@@ -3210,23 +3187,53 @@ mt7530_probe(struct mdio_device *mdiodev
return -EINVAL;
priv->id = priv->info->id;
+ priv->dev = dev;
+ priv->ds->priv = priv;
+ priv->ds->ops = &mt7530_switch_ops;
+ mutex_init(&priv->reg_mutex);
+ dev_set_drvdata(dev, priv);
- if (priv->id == ID_MT7530) {
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
- if (IS_ERR(priv->core_pwr))
- return PTR_ERR(priv->core_pwr);
+ return 0;
+}
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
- if (IS_ERR(priv->io_pwr))
- return PTR_ERR(priv->io_pwr);
- }
+static int
+mt7530_probe(struct mdio_device *mdiodev)
+{
+ static struct regmap_config *regmap_config;
+ struct mt7530_priv *priv;
+ struct device_node *dn;
+ int ret;
+
+ dn = mdiodev->dev.of_node;
+
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- /* Not MCM that indicates switch works as the remote standalone
+ priv->bus = mdiodev->bus;
+ priv->dev = &mdiodev->dev;
+
+ ret = mt7530_probe_common(priv);
+ if (ret)
+ return ret;
+
+ /* Use medatek,mcm property to distinguish hardware type that would
+ * cause a little bit differences on power-on sequence.
+ * Not MCM that indicates switch works as the remote standalone
* integrated circuit so the GPIO pin would be used to complete
* the reset, otherwise memory-mapped register accessing used
* through syscon provides in the case of MCM.
*/
- if (!priv->mcm) {
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
+ if (priv->mcm) {
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
+
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
+ if (IS_ERR(priv->rstc)) {
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->rstc);
+ }
+ } else {
priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(priv->reset)) {
@@ -3235,12 +3242,15 @@ mt7530_probe(struct mdio_device *mdiodev
}
}
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
- priv->ds->priv = priv;
- priv->ds->ops = &mt7530_switch_ops;
- mutex_init(&priv->reg_mutex);
- dev_set_drvdata(&mdiodev->dev, priv);
+ if (priv->id == ID_MT7530) {
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
+ if (IS_ERR(priv->core_pwr))
+ return PTR_ERR(priv->core_pwr);
+
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
+ if (IS_ERR(priv->io_pwr))
+ return PTR_ERR(priv->io_pwr);
+ }
regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
GFP_KERNEL);

View File

@@ -0,0 +1,54 @@
From 69b838d2629e6b82bcd9e0ab3c1c03f46e5e01d3 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:18:50 +0100
Subject: [PATCH 09/13] net: dsa: mt7530: introduce mt7530_remove_common helper
function
Move commonly used parts from mt7530_remove into new
mt7530_remove_common helper function which will be used by both,
mt7530_remove and the to-be-introduced mt7988_remove.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3277,6 +3277,17 @@ mt7530_probe(struct mdio_device *mdiodev
}
static void
+mt7530_remove_common(struct mt7530_priv *priv)
+{
+ if (priv->irq)
+ mt7530_free_irq(priv);
+
+ dsa_unregister_switch(priv->ds);
+
+ mutex_destroy(&priv->reg_mutex);
+}
+
+static void
mt7530_remove(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
@@ -3295,15 +3306,10 @@ mt7530_remove(struct mdio_device *mdiode
dev_err(priv->dev, "Failed to disable io pwr: %d\n",
ret);
- if (priv->irq)
- mt7530_free_irq(priv);
-
- dsa_unregister_switch(priv->ds);
+ mt7530_remove_common(priv);
for (i = 0; i < 2; ++i)
mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-
- mutex_destroy(&priv->reg_mutex);
}
static void mt7530_shutdown(struct mdio_device *mdiodev)

View File

@@ -0,0 +1,691 @@
From 8eceed6dbd74067dbf4d8e39f14734f4d2f35176 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:19:13 +0100
Subject: [PATCH 10/13] net: dsa: mt7530: introduce separate MDIO driver
Split MT7530 switch driver into a common part and a part specific
for MDIO connected switches and multi-chip modules.
Move MDIO-specific functions to newly introduced mt7530-mdio.c while
keeping the common parts in mt7530.c.
Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
implied by CONFIG_NET_DSA_MT7530.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
MAINTAINERS | 1 +
drivers/net/dsa/Kconfig | 16 +-
drivers/net/dsa/Makefile | 1 +
drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
drivers/net/dsa/mt7530.c | 264 +--------------------------------
drivers/net/dsa/mt7530.h | 6 +
6 files changed, 301 insertions(+), 258 deletions(-)
create mode 100644 drivers/net/dsa/mt7530-mdio.c
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13060,6 +13060,7 @@ M: Landen Chao <Landen.Chao@mediatek.com
M: DENG Qingfang <dqfext@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
+F: drivers/net/dsa/mt7530-mdio.c
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -37,10 +37,22 @@ config NET_DSA_MT7530
tristate "MediaTek MT753x and MT7621 Ethernet switch support"
select NET_DSA_TAG_MTK
select MEDIATEK_GE_PHY
+ imply NET_DSA_MT7530_MDIO
+ help
+ This enables support for the MediaTek MT7530 and MT7531 Ethernet
+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
+ supported as well.
+
+config NET_DSA_MT7530_MDIO
+ tristate "MediaTek MT7530 MDIO interface driver"
+ depends on NET_DSA_MT7530
select PCS_MTK_LYNXI
help
- This enables support for the MediaTek MT7530, MT7531, and MT7621
- Ethernet switch chips.
+ This enables support for the MediaTek MT7530 and MT7531 switch
+ chips which are connected via MDIO, as well as multi-chip
+ module MT7530 which can be found in the MT7621AT, MT7621DAT,
+ MT7621ST and MT7623AI SoCs.
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
endif
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
--- /dev/null
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/gpio/consumer.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/regulator/consumer.h>
+#include <net/dsa.h>
+
+#include "mt7530.h"
+
+static int
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct mii_bus *bus = context;
+ u16 page, r, lo, hi;
+ int ret;
+
+ page = (reg >> 6) & 0x3ff;
+ r = (reg >> 2) & 0xf;
+ lo = val & 0xffff;
+ hi = val >> 16;
+
+ /* MT7530 uses 31 as the pseudo port */
+ ret = bus->write(bus, 0x1f, 0x1f, page);
+ if (ret < 0)
+ return ret;
+
+ ret = bus->write(bus, 0x1f, r, lo);
+ if (ret < 0)
+ return ret;
+
+ ret = bus->write(bus, 0x1f, 0x10, hi);
+ return ret;
+}
+
+static int
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct mii_bus *bus = context;
+ u16 page, r, lo, hi;
+ int ret;
+
+ page = (reg >> 6) & 0x3ff;
+ r = (reg >> 2) & 0xf;
+
+ /* MT7530 uses 31 as the pseudo port */
+ ret = bus->write(bus, 0x1f, 0x1f, page);
+ if (ret < 0)
+ return ret;
+
+ lo = bus->read(bus, 0x1f, r);
+ hi = bus->read(bus, 0x1f, 0x10);
+
+ *val = (hi << 16) | (lo & 0xffff);
+
+ return 0;
+}
+
+static void
+mt7530_mdio_regmap_lock(void *mdio_lock)
+{
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
+}
+
+static void
+mt7530_mdio_regmap_unlock(void *mdio_lock)
+{
+ mutex_unlock(mdio_lock);
+}
+
+static const struct regmap_bus mt7530_regmap_bus = {
+ .reg_write = mt7530_regmap_write,
+ .reg_read = mt7530_regmap_read,
+};
+
+static int
+mt7531_create_sgmii(struct mt7530_priv *priv)
+{
+ struct regmap_config *mt7531_pcs_config[2];
+ struct phylink_pcs *pcs;
+ struct regmap *regmap;
+ int i, ret = 0;
+
+ for (i = 0; i < 2; i++) {
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
+ sizeof(struct regmap_config),
+ GFP_KERNEL);
+ if (!mt7531_pcs_config[i]) {
+ ret = -ENOMEM;
+ break;
+ }
+
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
+ mt7531_pcs_config[i]->reg_bits = 16;
+ mt7531_pcs_config[i]->val_bits = 32;
+ mt7531_pcs_config[i]->reg_stride = 4;
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
+ mt7531_pcs_config[i]->max_register = 0x17c;
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
+
+ regmap = devm_regmap_init(priv->dev,
+ &mt7530_regmap_bus, priv->bus,
+ mt7531_pcs_config[i]);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ break;
+ }
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
+ if (!pcs) {
+ ret = -ENXIO;
+ break;
+ }
+ priv->ports[5 + i].sgmii_pcs = pcs;
+ }
+
+ if (ret && i)
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
+
+ return ret;
+}
+
+static const struct of_device_id mt7530_of_match[] = {
+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
+
+static int
+mt7530_probe(struct mdio_device *mdiodev)
+{
+ static struct regmap_config *regmap_config;
+ struct mt7530_priv *priv;
+ struct device_node *dn;
+ int ret;
+
+ dn = mdiodev->dev.of_node;
+
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = mdiodev->bus;
+ priv->dev = &mdiodev->dev;
+
+ ret = mt7530_probe_common(priv);
+ if (ret)
+ return ret;
+
+ /* Use medatek,mcm property to distinguish hardware type that would
+ * cause a little bit differences on power-on sequence.
+ * Not MCM that indicates switch works as the remote standalone
+ * integrated circuit so the GPIO pin would be used to complete
+ * the reset, otherwise memory-mapped register accessing used
+ * through syscon provides in the case of MCM.
+ */
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
+ if (priv->mcm) {
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
+
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
+ if (IS_ERR(priv->rstc)) {
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->rstc);
+ }
+ } else {
+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(priv->reset)) {
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->reset);
+ }
+ }
+
+ if (priv->id == ID_MT7530) {
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
+ if (IS_ERR(priv->core_pwr))
+ return PTR_ERR(priv->core_pwr);
+
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
+ if (IS_ERR(priv->io_pwr))
+ return PTR_ERR(priv->io_pwr);
+ }
+
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
+ GFP_KERNEL);
+ if (!regmap_config)
+ return -ENOMEM;
+
+ regmap_config->reg_bits = 16;
+ regmap_config->val_bits = 32;
+ regmap_config->reg_stride = 4;
+ regmap_config->max_register = MT7530_CREV;
+ regmap_config->disable_locking = true;
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
+ priv->bus, regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ if (priv->id == ID_MT7531) {
+ ret = mt7531_create_sgmii(priv);
+ if (ret)
+ return ret;
+ }
+
+ return dsa_register_switch(priv->ds);
+}
+
+static void
+mt7530_remove(struct mdio_device *mdiodev)
+{
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
+ int ret = 0, i;
+
+ if (!priv)
+ return;
+
+ ret = regulator_disable(priv->core_pwr);
+ if (ret < 0)
+ dev_err(priv->dev,
+ "Failed to disable core power: %d\n", ret);
+
+ ret = regulator_disable(priv->io_pwr);
+ if (ret < 0)
+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
+ ret);
+
+ mt7530_remove_common(priv);
+
+ for (i = 0; i < 2; ++i)
+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
+}
+
+static void mt7530_shutdown(struct mdio_device *mdiodev)
+{
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
+
+ if (!priv)
+ return;
+
+ dsa_switch_shutdown(priv->ds);
+
+ dev_set_drvdata(&mdiodev->dev, NULL);
+}
+
+static struct mdio_driver mt7530_mdio_driver = {
+ .probe = mt7530_probe,
+ .remove = mt7530_remove,
+ .shutdown = mt7530_shutdown,
+ .mdiodrv.driver = {
+ .name = "mt7530-mdio",
+ .of_match_table = mt7530_of_match,
+ },
+};
+
+mdio_module_driver(mt7530_mdio_driver);
+
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
+MODULE_LICENSE("GPL");
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -14,7 +14,6 @@
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
-#include <linux/pcs/pcs-mtk-lynxi.h>
#include <linux/phylink.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
@@ -192,31 +191,6 @@ core_clear(struct mt7530_priv *priv, u32
}
static int
-mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
-{
- struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
- page = (reg >> 6) & 0x3ff;
- r = (reg >> 2) & 0xf;
- lo = val & 0xffff;
- hi = val >> 16;
-
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0)
- return ret;
-
- ret = bus->write(bus, 0x1f, r, lo);
- if (ret < 0)
- return ret;
-
- ret = bus->write(bus, 0x1f, 0x10, hi);
- return ret;
-}
-
-static int
mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
int ret;
@@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *pri
return ret;
}
-static int
-mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
-{
- struct mii_bus *bus = context;
- u16 page, r, lo, hi;
- int ret;
-
- page = (reg >> 6) & 0x3ff;
- r = (reg >> 2) & 0xf;
-
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0)
- return ret;
-
- lo = bus->read(bus, 0x1f, r);
- hi = bus->read(bus, 0x1f, 0x10);
-
- *val = (hi << 16) | (lo & 0xffff);
-
- return 0;
-}
-
static u32
mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
{
@@ -2957,72 +2908,6 @@ static const struct phylink_pcs_ops mt75
.pcs_an_restart = mt7530_pcs_an_restart,
};
-static void
-mt7530_mdio_regmap_lock(void *mdio_lock)
-{
- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
-}
-
-static void
-mt7530_mdio_regmap_unlock(void *mdio_lock)
-{
- mutex_unlock(mdio_lock);
-}
-
-static const struct regmap_bus mt7530_regmap_bus = {
- .reg_write = mt7530_regmap_write,
- .reg_read = mt7530_regmap_read,
-};
-
-static int
-mt7531_create_sgmii(struct mt7530_priv *priv)
-{
- struct regmap_config *mt7531_pcs_config[2];
- struct phylink_pcs *pcs;
- struct regmap *regmap;
- int i, ret = 0;
-
- for (i = 0; i < 2; i++) {
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
- sizeof(struct regmap_config),
- GFP_KERNEL);
- if (!mt7531_pcs_config[i]) {
- ret = -ENOMEM;
- break;
- }
-
- mt7531_pcs_config[i]->name = i ? "port6" : "port5";
- mt7531_pcs_config[i]->reg_bits = 16;
- mt7531_pcs_config[i]->val_bits = 32;
- mt7531_pcs_config[i]->reg_stride = 4;
- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
- mt7531_pcs_config[i]->max_register = 0x17c;
- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
-
- regmap = devm_regmap_init(priv->dev,
- &mt7530_regmap_bus, priv->bus,
- mt7531_pcs_config[i]);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
- break;
- }
- pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
- MT7531_PHYA_CTRL_SIGNAL3, 0);
- if (!pcs) {
- ret = -ENXIO;
- break;
- }
- priv->ports[5 + i].sgmii_pcs = pcs;
- }
-
- if (ret && i)
- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
-
- return ret;
-}
-
static int
mt753x_setup(struct dsa_switch *ds)
{
@@ -3081,7 +2966,7 @@ static int mt753x_set_mac_eee(struct dsa
return 0;
}
-static const struct dsa_switch_ops mt7530_switch_ops = {
+const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
.get_strings = mt7530_get_strings,
@@ -3115,8 +3000,9 @@ static const struct dsa_switch_ops mt753
.get_mac_eee = mt753x_get_mac_eee,
.set_mac_eee = mt753x_set_mac_eee,
};
+EXPORT_SYMBOL_GPL(mt7530_switch_ops);
-static const struct mt753x_info mt753x_table[] = {
+const struct mt753x_info mt753x_table[] = {
[ID_MT7621] = {
.id = ID_MT7621,
.pcs_ops = &mt7530_pcs_ops,
@@ -3149,16 +3035,9 @@ static const struct mt753x_info mt753x_t
.mac_port_config = mt7531_mac_config,
},
};
+EXPORT_SYMBOL_GPL(mt753x_table);
-static const struct of_device_id mt7530_of_match[] = {
- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, mt7530_of_match);
-
-static int
+int
mt7530_probe_common(struct mt7530_priv *priv)
{
struct device *dev = priv->dev;
@@ -3195,88 +3074,9 @@ mt7530_probe_common(struct mt7530_priv *
return 0;
}
+EXPORT_SYMBOL_GPL(mt7530_probe_common);
-static int
-mt7530_probe(struct mdio_device *mdiodev)
-{
- static struct regmap_config *regmap_config;
- struct mt7530_priv *priv;
- struct device_node *dn;
- int ret;
-
- dn = mdiodev->dev.of_node;
-
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->bus = mdiodev->bus;
- priv->dev = &mdiodev->dev;
-
- ret = mt7530_probe_common(priv);
- if (ret)
- return ret;
-
- /* Use medatek,mcm property to distinguish hardware type that would
- * cause a little bit differences on power-on sequence.
- * Not MCM that indicates switch works as the remote standalone
- * integrated circuit so the GPIO pin would be used to complete
- * the reset, otherwise memory-mapped register accessing used
- * through syscon provides in the case of MCM.
- */
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
- if (priv->mcm) {
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
-
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
- if (IS_ERR(priv->rstc)) {
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
- return PTR_ERR(priv->rstc);
- }
- } else {
- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
- GPIOD_OUT_LOW);
- if (IS_ERR(priv->reset)) {
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
- return PTR_ERR(priv->reset);
- }
- }
-
- if (priv->id == ID_MT7530) {
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
- if (IS_ERR(priv->core_pwr))
- return PTR_ERR(priv->core_pwr);
-
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
- if (IS_ERR(priv->io_pwr))
- return PTR_ERR(priv->io_pwr);
- }
-
- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
- GFP_KERNEL);
- if (!regmap_config)
- return -ENOMEM;
-
- regmap_config->reg_bits = 16;
- regmap_config->val_bits = 32;
- regmap_config->reg_stride = 4;
- regmap_config->max_register = MT7530_CREV;
- regmap_config->disable_locking = true;
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
- priv->bus, regmap_config);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
- if (priv->id == ID_MT7531) {
- ret = mt7531_create_sgmii(priv);
- if (ret)
- return ret;
- }
-
- return dsa_register_switch(priv->ds);
-}
-
-static void
+void
mt7530_remove_common(struct mt7530_priv *priv)
{
if (priv->irq)
@@ -3286,55 +3086,7 @@ mt7530_remove_common(struct mt7530_priv
mutex_destroy(&priv->reg_mutex);
}
-
-static void
-mt7530_remove(struct mdio_device *mdiodev)
-{
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
- int ret = 0, i;
-
- if (!priv)
- return;
-
- ret = regulator_disable(priv->core_pwr);
- if (ret < 0)
- dev_err(priv->dev,
- "Failed to disable core power: %d\n", ret);
-
- ret = regulator_disable(priv->io_pwr);
- if (ret < 0)
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
- ret);
-
- mt7530_remove_common(priv);
-
- for (i = 0; i < 2; ++i)
- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
-}
-
-static void mt7530_shutdown(struct mdio_device *mdiodev)
-{
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
-
- if (!priv)
- return;
-
- dsa_switch_shutdown(priv->ds);
-
- dev_set_drvdata(&mdiodev->dev, NULL);
-}
-
-static struct mdio_driver mt7530_mdio_driver = {
- .probe = mt7530_probe,
- .remove = mt7530_remove,
- .shutdown = mt7530_shutdown,
- .mdiodrv.driver = {
- .name = "mt7530",
- .of_match_table = mt7530_of_match,
- },
-};
-
-mdio_module_driver(mt7530_mdio_driver);
+EXPORT_SYMBOL_GPL(mt7530_remove_common);
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -807,4 +807,10 @@ static inline void INIT_MT7530_DUMMY_POL
p->reg = reg;
}
+int mt7530_probe_common(struct mt7530_priv *priv);
+void mt7530_remove_common(struct mt7530_priv *priv);
+
+extern const struct dsa_switch_ops mt7530_switch_ops;
+extern const struct mt753x_info mt753x_table[];
+
#endif /* __MT7530_H */

View File

@@ -0,0 +1,47 @@
From a52cadbf76593f8fcb2f4f62cb006e3f2a22ad06 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:19:28 +0100
Subject: [PATCH 11/13] net: dsa: mt7530: skip locking if MDIO bus isn't
present
As MT7530 and MT7531 internally use 32-bit wide registers, each access
to any register of the switch requires several operations on the MDIO
bus. Hence if there is congruent access, e.g. due to PCS or PHY
polling, this can mess up and interfere with another ongoing register
access sequence.
However, the MDIO bus mutex is only relevant for MDIO-connected
switches. Prepare switches which have there registers directly mapped
into the SoCs register space via MMIO which do not require such
locking. There we can simply use regmap's default locking mechanism.
Hence guard mutex operations to only be performed in case of MDIO
connected switches.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/dsa/mt7530.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -144,13 +144,15 @@ err:
static void
mt7530_mutex_lock(struct mt7530_priv *priv)
{
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+ if (priv->bus)
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
}
static void
mt7530_mutex_unlock(struct mt7530_priv *priv)
{
- mutex_unlock(&priv->bus->mdio_lock);
+ if (priv->bus)
+ mutex_unlock(&priv->bus->mdio_lock);
}
static void

View File

@@ -0,0 +1,421 @@
From b361015763fedea439f13b336b15ef7bdf1f7d4f Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 3 Apr 2023 02:19:40 +0100
Subject: [PATCH 12/13] net: dsa: mt7530: introduce driver for MT7988 built-in
switch
Add driver for the built-in Gigabit Ethernet switch which can be found
in the MediaTek MT7988 SoC.
The switch shares most of its design with MT7530 and MT7531, but has
it's registers mapped into the SoCs register space rather than being
connected externally or internally via MDIO.
Introduce a new platform driver to support that.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
MAINTAINERS | 2 +
drivers/net/dsa/Kconfig | 12 +++
drivers/net/dsa/Makefile | 1 +
drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++-
drivers/net/dsa/mt7530.h | 12 +--
6 files changed, 255 insertions(+), 10 deletions(-)
create mode 100644 drivers/net/dsa/mt7530-mmio.c
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13058,9 +13058,11 @@ MEDIATEK SWITCH DRIVER
M: Sean Wang <sean.wang@mediatek.com>
M: Landen Chao <Landen.Chao@mediatek.com>
M: DENG Qingfang <dqfext@gmail.com>
+M: Daniel Golle <daniel@makrotopia.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/dsa/mt7530-mdio.c
+F: drivers/net/dsa/mt7530-mmio.c
F: drivers/net/dsa/mt7530.*
F: net/dsa/tag_mtk.c
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -38,6 +38,7 @@ config NET_DSA_MT7530
select NET_DSA_TAG_MTK
select MEDIATEK_GE_PHY
imply NET_DSA_MT7530_MDIO
+ imply NET_DSA_MT7530_MMIO
help
This enables support for the MediaTek MT7530 and MT7531 Ethernet
switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO
module MT7530 which can be found in the MT7621AT, MT7621DAT,
MT7621ST and MT7623AI SoCs.
+config NET_DSA_MT7530_MMIO
+ tristate "MediaTek MT7530 MMIO interface driver"
+ depends on NET_DSA_MT7530
+ depends on HAS_IOMEM
+ help
+ This enables support for the built-in Ethernet switch found
+ in the MediaTek MT7988 SoC.
+ The switch is a similar design as MT7531, but the switch registers
+ are directly mapped into the SoCs register space rather than being
+ accessible via MDIO.
+
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
select NET_DSA_TAG_TRAILER
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -8,6 +8,7 @@ endif
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
--- /dev/null
+++ b/drivers/net/dsa/mt7530-mmio.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <net/dsa.h>
+
+#include "mt7530.h"
+
+static const struct of_device_id mt7988_of_match[] = {
+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt7988_of_match);
+
+static int
+mt7988_probe(struct platform_device *pdev)
+{
+ static struct regmap_config *sw_regmap_config;
+ struct mt7530_priv *priv;
+ void __iomem *base_addr;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = NULL;
+ priv->dev = &pdev->dev;
+
+ ret = mt7530_probe_common(priv);
+ if (ret)
+ return ret;
+
+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->rstc)) {
+ dev_err(&pdev->dev, "Couldn't get our reset line\n");
+ return PTR_ERR(priv->rstc);
+ }
+
+ base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base_addr)) {
+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
+ return -ENXIO;
+ }
+
+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL);
+ if (!sw_regmap_config)
+ return -ENOMEM;
+
+ sw_regmap_config->name = "switch";
+ sw_regmap_config->reg_bits = 16;
+ sw_regmap_config->val_bits = 32;
+ sw_regmap_config->reg_stride = 4;
+ sw_regmap_config->max_register = MT7530_CREV;
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ return dsa_register_switch(priv->ds);
+}
+
+static int
+mt7988_remove(struct platform_device *pdev)
+{
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
+
+ if (priv)
+ mt7530_remove_common(priv);
+
+ return 0;
+}
+
+static void mt7988_shutdown(struct platform_device *pdev)
+{
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
+
+ if (!priv)
+ return;
+
+ dsa_switch_shutdown(priv->ds);
+
+ dev_set_drvdata(&pdev->dev, NULL);
+}
+
+static struct platform_driver mt7988_platform_driver = {
+ .probe = mt7988_probe,
+ .remove = mt7988_remove,
+ .shutdown = mt7988_shutdown,
+ .driver = {
+ .name = "mt7530-mmio",
+ .of_match_table = mt7988_of_match,
+ },
+};
+module_platform_driver(mt7988_platform_driver);
+
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)");
+MODULE_LICENSE("GPL");
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1989,6 +1989,47 @@ static const struct irq_domain_ops mt753
};
static void
+mt7988_irq_mask(struct irq_data *d)
+{
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
+
+ priv->irq_enable &= ~BIT(d->hwirq);
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
+}
+
+static void
+mt7988_irq_unmask(struct irq_data *d)
+{
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
+
+ priv->irq_enable |= BIT(d->hwirq);
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
+}
+
+static struct irq_chip mt7988_irq_chip = {
+ .name = KBUILD_MODNAME,
+ .irq_mask = mt7988_irq_mask,
+ .irq_unmask = mt7988_irq_unmask,
+};
+
+static int
+mt7988_irq_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ irq_set_chip_data(irq, domain->host_data);
+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq);
+ irq_set_nested_thread(irq, true);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops mt7988_irq_domain_ops = {
+ .map = mt7988_irq_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static void
mt7530_setup_mdio_irq(struct mt7530_priv *priv)
{
struct dsa_switch *ds = priv->ds;
@@ -2022,8 +2063,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
return priv->irq ? : -EINVAL;
}
- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
- &mt7530_irq_domain_ops, priv);
+ if (priv->id == ID_MT7988)
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
+ &mt7988_irq_domain_ops,
+ priv);
+ else
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
+ &mt7530_irq_domain_ops,
+ priv);
+
if (!priv->irq_domain) {
dev_err(dev, "failed to create IRQ domain\n");
return -ENOMEM;
@@ -2520,6 +2568,25 @@ static void mt7531_mac_port_get_caps(str
}
}
+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ phy_interface_zero(config->supported_interfaces);
+
+ switch (port) {
+ case 0 ... 4: /* Internal phy */
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ break;
+
+ case 6:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+ MAC_10000FD;
+ }
+}
+
static int
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
{
@@ -2596,6 +2663,17 @@ static bool mt753x_is_mac_port(u32 port)
}
static int
+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+ phy_interface_t interface)
+{
+ if (dsa_is_cpu_port(ds, port) &&
+ interface == PHY_INTERFACE_MODE_INTERNAL)
+ return 0;
+
+ return -EINVAL;
+}
+
+static int
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
{
@@ -2665,7 +2743,8 @@ mt753x_phylink_mac_config(struct dsa_swi
switch (port) {
case 0 ... 4: /* Internal phy */
- if (state->interface != PHY_INTERFACE_MODE_GMII)
+ if (state->interface != PHY_INTERFACE_MODE_GMII &&
+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
goto unsupported;
break;
case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
@@ -2743,7 +2822,8 @@ static void mt753x_phylink_mac_link_up(s
/* MT753x MAC works in 1G full duplex mode for all up-clocked
* variants.
*/
- if (interface == PHY_INTERFACE_MODE_TRGMII ||
+ if (interface == PHY_INTERFACE_MODE_INTERNAL ||
+ interface == PHY_INTERFACE_MODE_TRGMII ||
(phy_interface_mode_is_8023z(interface))) {
speed = SPEED_1000;
duplex = DUPLEX_FULL;
@@ -2823,6 +2903,21 @@ mt7531_cpu_port_config(struct dsa_switch
return 0;
}
+static int
+mt7988_cpu_port_config(struct dsa_switch *ds, int port)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ mt7530_write(priv, MT7530_PMCR_P(port),
+ PMCR_CPU_PORT_SETTING(priv->id));
+
+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
+ PHY_INTERFACE_MODE_INTERNAL, NULL,
+ SPEED_10000, DUPLEX_FULL, true, true);
+
+ return 0;
+}
+
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config)
{
@@ -2968,6 +3063,27 @@ static int mt753x_set_mac_eee(struct dsa
return 0;
}
+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
+{
+ return 0;
+}
+
+static int mt7988_setup(struct dsa_switch *ds)
+{
+ struct mt7530_priv *priv = ds->priv;
+
+ /* Reset the switch */
+ reset_control_assert(priv->rstc);
+ usleep_range(20, 50);
+ reset_control_deassert(priv->rstc);
+ usleep_range(20, 50);
+
+ /* Reset the switch PHYs */
+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
+
+ return mt7531_setup_common(ds);
+}
+
const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
@@ -3036,6 +3152,17 @@ const struct mt753x_info mt753x_table[]
.mac_port_get_caps = mt7531_mac_port_get_caps,
.mac_port_config = mt7531_mac_config,
},
+ [ID_MT7988] = {
+ .id = ID_MT7988,
+ .pcs_ops = &mt7530_pcs_ops,
+ .sw_setup = mt7988_setup,
+ .phy_read = mt7531_ind_phy_read,
+ .phy_write = mt7531_ind_phy_write,
+ .pad_setup = mt7988_pad_setup,
+ .cpu_port_config = mt7988_cpu_port_config,
+ .mac_port_get_caps = mt7988_mac_port_get_caps,
+ .mac_port_config = mt7988_mac_config,
+ },
};
EXPORT_SYMBOL_GPL(mt753x_table);
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -18,6 +18,7 @@ enum mt753x_id {
ID_MT7530 = 0,
ID_MT7621 = 1,
ID_MT7531 = 2,
+ ID_MT7988 = 3,
};
#define NUM_TRGMII_CTRL 5
@@ -54,11 +55,11 @@ enum mt753x_id {
#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
-#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_CFC : MT7530_MFC)
-#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_MIRROR_EN : MIRROR_EN)
-#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_MIRROR_MASK : MIRROR_MASK)
/* Registers for BPDU and PAE frame control*/
@@ -295,9 +296,8 @@ enum mt7530_vlan_port_acc_frm {
MT7531_FORCE_DPX | \
MT7531_FORCE_RX_FC | \
MT7531_FORCE_TX_FC)
-#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
- MT7531_FORCE_MODE : \
- PMCR_FORCE_MODE)
+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
+ MT7531_FORCE_MODE : PMCR_FORCE_MODE)
#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \

View File

@@ -0,0 +1,118 @@
From eb1dd407b4be7ca38166a38c56c8edf52c6a399f Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Sun, 16 Apr 2023 13:08:14 +0100
Subject: [PATCH 13/13] net: dsa: mt7530: fix support for MT7531BE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are two variants of the MT7531 switch IC which got different
features (and pins) regarding port 5:
* MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS
* MT7531BE: RGMII
Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe
with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation
to mt7530_probe function") works fine for MT7531AE which got two
instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup
to setup clocks before the single PCS on port 6 (usually used as CPU
port) starts to work and hence the PCS creation failed on MT7531BE.
Fix this by introducing a pointer to mt7531_create_sgmii function in
struct mt7530_priv and call it again at the end of mt753x_setup like it
was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS
creation to mt7530_probe function").
Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/dsa/mt7530-mdio.c | 16 ++++++++--------
drivers/net/dsa/mt7530.c | 6 ++++++
drivers/net/dsa/mt7530.h | 4 ++--
3 files changed, 16 insertions(+), 10 deletions(-)
--- a/drivers/net/dsa/mt7530-mdio.c
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re
};
static int
-mt7531_create_sgmii(struct mt7530_priv *priv)
+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
{
- struct regmap_config *mt7531_pcs_config[2];
+ struct regmap_config *mt7531_pcs_config[2] = {};
struct phylink_pcs *pcs;
struct regmap *regmap;
int i, ret = 0;
- for (i = 0; i < 2; i++) {
+ /* MT7531AE has two SGMII units for port 5 and port 6
+ * MT7531BE has only one SGMII unit for port 6
+ */
+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
sizeof(struct regmap_config),
GFP_KERNEL);
@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
- if (priv->id == ID_MT7531) {
- ret = mt7531_create_sgmii(priv);
- if (ret)
- return ret;
- }
+ if (priv->id == ID_MT7531)
+ priv->create_sgmii = mt7531_create_sgmii;
return dsa_register_switch(priv->ds);
}
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3030,6 +3030,12 @@ mt753x_setup(struct dsa_switch *ds)
if (ret && priv->irq)
mt7530_free_irq_common(priv);
+ if (priv->create_sgmii) {
+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
+ if (ret && priv->irq)
+ mt7530_free_irq(priv);
+ }
+
return ret;
}
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -741,10 +741,10 @@ struct mt753x_info {
* registers
* @p6_interface Holding the current port 6 interface
* @p5_intf_sel: Holding the current port 5 interface select
- *
* @irq: IRQ number of the switch
* @irq_domain: IRQ domain of the switch irq_chip
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
*/
struct mt7530_priv {
struct device *dev;
@@ -763,7 +763,6 @@ struct mt7530_priv {
unsigned int p5_intf_sel;
u8 mirror_rx;
u8 mirror_tx;
-
struct mt7530_port ports[MT7530_NUM_PORTS];
struct mt753x_pcs pcs[MT7530_NUM_PORTS];
/* protect among processes for registers access*/
@@ -771,6 +770,7 @@ struct mt7530_priv {
int irq;
struct irq_domain *irq_domain;
u32 irq_enable;
+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
};
struct mt7530_hw_vlan_entry {

View File

@@ -21,7 +21,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13959,6 +13959,7 @@ F: include/uapi/linux/meye.h
@@ -13962,6 +13962,7 @@ F: include/uapi/linux/meye.h
MOTORCOMM PHY DRIVER
M: Peter Geis <pgwipeout@gmail.com>

View File

@@ -5246,6 +5246,8 @@ CONFIG_RXKAD=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_AHCI_PLATFORM is not set
# CONFIG_SATA_DWC is not set
# CONFIG_SATA_DWC_DEBUG is not set
# CONFIG_SATA_DWC_OLD_DMA is not set
# CONFIG_SATA_FSL is not set
# CONFIG_SATA_HIGHBANK is not set
# CONFIG_SATA_HOST is not set

View File

@@ -150,6 +150,7 @@ CONFIG_AF_UNIX_OOB=y
# CONFIG_AHCI_BRCM is not set
# CONFIG_AHCI_CEVA is not set
# CONFIG_AHCI_DWC is not set
# CONFIG_SATA_DWC_OLD_DMA is not set
# CONFIG_AHCI_IMX is not set
# CONFIG_AHCI_MVEBU is not set
# CONFIG_AHCI_QORIQ is not set
@@ -1712,6 +1713,7 @@ CONFIG_DQL=y
# CONFIG_DRM_RCAR_LVDS is not set
# CONFIG_DRM_RCAR_USE_LVDS is not set
# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set
# CONFIG_DRM_ROCKCHIP is not set
# CONFIG_DRM_SII902X is not set
# CONFIG_DRM_SII9234 is not set
# CONFIG_DRM_SIL_SII8620 is not set
@@ -2188,7 +2190,6 @@ CONFIG_FSNOTIFY=y
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_FTR_FIXUP_SELFTEST is not set
# CONFIG_FTWDT010_WATCHDOG is not set
# CONFIG_FUNCTION_ERROR_INJECTION is not set
# CONFIG_FUJITSU_ERRATUM_010001 is not set
# CONFIG_FUJITSU_ES is not set
# CONFIG_FUJITSU_LAPTOP is not set
@@ -6312,6 +6313,8 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
# CONFIG_SND_SOC_PCM512x_SPI is not set
# CONFIG_SND_SOC_QCOM is not set
# CONFIG_SND_SOC_RK3328 is not set
# CONFIG_SND_SOC_RK817 is not set
# CONFIG_SND_SOC_ROCKCHIP is not set
# CONFIG_SND_SOC_RT5616 is not set
# CONFIG_SND_SOC_RT5631 is not set
# CONFIG_SND_SOC_RT5640 is not set
@@ -6990,6 +6993,7 @@ CONFIG_TTY=y
# CONFIG_TWL6040_CORE is not set
# CONFIG_TXGBE is not set
# CONFIG_TYPEC is not set
# CONFIG_TYPEC_DP_ALTMODE is not set
# CONFIG_TYPEC_TCPM is not set
# CONFIG_TYPEC_UCSI is not set
# CONFIG_TYPHOON is not set

View File

@@ -1054,6 +1054,9 @@ static struct genl_family switch_fam = {
.module = THIS_MODULE,
.ops = swconfig_ops,
.n_ops = ARRAY_SIZE(swconfig_ops),
#if LINUX_VERSION_CODE > KERNEL_VERSION(6,0,0)
.resv_start_op = SWITCH_CMD_SET_VLAN + 1,
#endif
};
#ifdef CONFIG_OF

View File

@@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2196,6 +2196,10 @@ mt7530_setup(struct dsa_switch *ds)
@@ -2236,6 +2236,10 @@ mt7530_setup(struct dsa_switch *ds)
return -ENODEV;
}

View File

@@ -0,0 +1,223 @@
From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:55:13 +0000
Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability
bit
Introduce MTK_NETSYS_V1 bit in the device capabilities for
MT7621/MT7622/MT7623/MT7628/MT7629 SoCs.
Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase.
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++-------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++---------
2 files changed, 41 insertions(+), 34 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -640,7 +640,7 @@ static void mtk_set_queue_speed(struct m
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
if (IS_ENABLED(CONFIG_SOC_MT7621)) {
@@ -1018,7 +1018,7 @@ static bool mtk_rx_get_desc(struct mtk_e
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
}
@@ -1076,7 +1076,7 @@ static int mtk_init_fq_dma(struct mtk_et
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
txd->txd4 = 0;
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
txd->txd5 = 0;
txd->txd6 = 0;
txd->txd7 = 0;
@@ -1267,7 +1267,7 @@ static void mtk_tx_set_dma_desc(struct n
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
mtk_tx_set_dma_desc_v2(dev, txd, info);
else
mtk_tx_set_dma_desc_v1(dev, txd, info);
@@ -1950,7 +1950,7 @@ static int mtk_poll_rx(struct napi_struc
break;
/* find out which mac the packet come from. values start at 1 */
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
@@ -2046,7 +2046,7 @@ static int mtk_poll_rx(struct napi_struc
skb->dev = netdev;
bytes += skb->len;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
if (hash != MTK_RXD5_FOE_ENTRY)
@@ -2071,7 +2071,7 @@ static int mtk_poll_rx(struct napi_struc
/* When using VLAN untagging in combination with DSA, the
* hardware treats the MTK special tag as a VLAN and untags it.
*/
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) &&
(trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
@@ -2382,7 +2382,7 @@ static int mtk_tx_alloc(struct mtk_eth *
txd->txd2 = next_ptr;
txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
txd->txd4 = 0;
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
txd->txd5 = 0;
txd->txd6 = 0;
txd->txd7 = 0;
@@ -2435,7 +2435,7 @@ static int mtk_tx_alloc(struct mtk_eth *
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
ofs += MTK_QTX_OFFSET;
@@ -2571,7 +2571,7 @@ static int mtk_rx_alloc(struct mtk_eth *
rxd->rxd3 = 0;
rxd->rxd4 = 0;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
rxd->rxd5 = 0;
rxd->rxd6 = 0;
rxd->rxd7 = 0;
@@ -3119,7 +3119,7 @@ static int mtk_start_dma(struct mtk_eth
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
@@ -3529,7 +3529,7 @@ static void mtk_hw_reset(struct mtk_eth
{
u32 val;
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
val = RSTCTRL_PPE0_V2;
} else {
@@ -3541,7 +3541,7 @@ static void mtk_hw_reset(struct mtk_eth
ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
0x3ffffff);
}
@@ -3737,7 +3737,7 @@ static int mtk_hw_init(struct mtk_eth *e
else
mtk_hw_reset(eth);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
/* Set FE to PDMAv2 if necessary */
val = mtk_r32(eth, MTK_FE_GLO_MISC);
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
@@ -3774,7 +3774,7 @@ static int mtk_hw_init(struct mtk_eth *e
*/
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -819,6 +819,7 @@ enum mkt_eth_capabilities {
MTK_SHARED_INT_BIT,
MTK_TRGMII_MT7621_CLK_BIT,
MTK_QDMA_BIT,
+ MTK_NETSYS_V1_BIT,
MTK_NETSYS_V2_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
@@ -854,6 +855,7 @@ enum mkt_eth_capabilities {
#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
#define MTK_QDMA BIT(MTK_QDMA_BIT)
+#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
@@ -916,25 +918,30 @@ enum mkt_eth_capabilities {
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
-#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
- MTK_GMAC2_RGMII | MTK_SHARED_INT | \
- MTK_TRGMII_MT7621_CLK | MTK_QDMA)
-
-#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \
- MTK_GMAC2_SGMII | MTK_GDM1_ESW | \
- MTK_MUX_GDM1_TO_GMAC1_ESW | \
- MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA)
-
-#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \
- MTK_QDMA)
-
-#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628)
-
-#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
- MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
- MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
- MTK_MUX_U3_GMAC2_TO_QPHY | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
+#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
+ MTK_GMAC2_RGMII | MTK_SHARED_INT | \
+ MTK_TRGMII_MT7621_CLK | MTK_QDMA | \
+ MTK_NETSYS_V1)
+
+#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | \
+ MTK_GMAC2_RGMII | MTK_GMAC2_SGMII | \
+ MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\
+ MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | \
+ MTK_QDMA | MTK_NETSYS_V1)
+
+#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
+ MTK_GMAC2_RGMII | MTK_QDMA | \
+ MTK_NETSYS_V1)
+
+#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628 | \
+ MTK_NETSYS_V1)
+
+#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+ MTK_GMAC2_GEPHY | MTK_GDM1_ESW | \
+ MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \
+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\
+ MTK_MUX_GDM1_TO_GMAC1_ESW | \
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII)
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \

View File

@@ -0,0 +1,181 @@
From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:55:24 +0000
Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
This is a preliminary patch to add MT7988 SoC support since it runs 3
macs instead of 2.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++--
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++----
2 files changed, 36 insertions(+), 9 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4043,7 +4043,10 @@ static void mtk_sgmii_destroy(struct mtk
{
int i;
- for (i = 0; i < MTK_MAX_DEVS; i++)
+ if (!eth->sgmii_pcs)
+ return;
+
+ for (i = 0; i < eth->soc->num_devs; i++)
mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
}
@@ -4486,7 +4489,12 @@ static int mtk_sgmii_init(struct mtk_eth
u32 flags;
int i;
- for (i = 0; i < MTK_MAX_DEVS; i++) {
+ eth->sgmii_pcs = devm_kzalloc(eth->dev,
+ sizeof(*eth->sgmii_pcs) *
+ eth->soc->num_devs,
+ GFP_KERNEL);
+
+ for (i = 0; i < eth->soc->num_devs; i++) {
np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
if (!np)
break;
@@ -4531,6 +4539,18 @@ static int mtk_probe(struct platform_dev
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
eth->ip_align = NET_IP_ALIGN;
+ eth->netdev = devm_kzalloc(eth->dev,
+ sizeof(*eth->netdev) * eth->soc->num_devs,
+ GFP_KERNEL);
+ if (!eth->netdev)
+ return -ENOMEM;
+
+ eth->mac = devm_kzalloc(eth->dev,
+ sizeof(*eth->mac) * eth->soc->num_devs,
+ GFP_KERNEL);
+ if (!eth->mac)
+ return -ENOMEM;
+
spin_lock_init(&eth->page_lock);
spin_lock_init(&eth->tx_irq_lock);
spin_lock_init(&eth->rx_irq_lock);
@@ -4716,7 +4736,7 @@ static int mtk_probe(struct platform_dev
goto err_deinit_ppe;
}
- for (i = 0; i < MTK_MAX_DEVS; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
@@ -4792,6 +4812,7 @@ static const struct mtk_soc_data mt2701_
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4810,6 +4831,7 @@ static const struct mtk_soc_data mt7621_
.required_pctl = false,
.offload_version = 1,
.hash_offset = 2,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4831,6 +4853,7 @@ static const struct mtk_soc_data mt7622_
.offload_version = 2,
.hash_offset = 2,
.has_accounting = true,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4850,6 +4873,7 @@ static const struct mtk_soc_data mt7623_
.required_pctl = true,
.offload_version = 1,
.hash_offset = 2,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
@@ -4869,6 +4893,7 @@ static const struct mtk_soc_data mt7629_
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_accounting = true,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4890,6 +4915,7 @@ static const struct mtk_soc_data mt7981_
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
.has_accounting = true,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4908,6 +4934,7 @@ static const struct mtk_soc_data mt7986_
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.hash_offset = 4,
+ .num_devs = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry),
.has_accounting = true,
.txrx = {
@@ -4926,6 +4953,7 @@ static const struct mtk_soc_data rt5350_
.hw_features = MTK_HW_FEATURES_MT7628,
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
+ .num_devs = 2,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1021,6 +1021,7 @@ struct mtk_reg_map {
* @required_pctl A bool value to show whether the SoC requires
* the extra setup for those pins used by GMAC.
* @hash_offset Flow table hash offset.
+ * @num_devs SoC number of macs.
* @foe_entry_size Foe table entry size.
* @has_accounting Bool indicating support for accounting of
* offloaded flows.
@@ -1039,6 +1040,7 @@ struct mtk_soc_data {
bool required_pctl;
u8 offload_version;
u8 hash_offset;
+ u8 num_devs;
u16 foe_entry_size;
netdev_features_t hw_features;
bool has_accounting;
@@ -1054,9 +1056,6 @@ struct mtk_soc_data {
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
-/* currently no SoC has more than 2 macs */
-#define MTK_MAX_DEVS 2
-
/* struct mtk_eth - This is the main datasructure for holding the state
* of the driver
* @dev: The device pointer
@@ -1111,14 +1110,14 @@ struct mtk_eth {
spinlock_t tx_irq_lock;
spinlock_t rx_irq_lock;
struct net_device dummy_dev;
- struct net_device *netdev[MTK_MAX_DEVS];
- struct mtk_mac *mac[MTK_MAX_DEVS];
+ struct net_device **netdev;
+ struct mtk_mac **mac;
int irq[3];
u32 msg_enable;
unsigned long sysclk;
struct regmap *ethsys;
struct regmap *infra;
- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
+ struct phylink_pcs **sgmii_pcs;
struct regmap *pctl;
bool hwlro;
refcount_t dma_refcnt;

View File

@@ -0,0 +1,153 @@
From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:55:35 +0000
Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove
MTK_MAC_COUNT
Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
2 files changed, 15 insertions(+), 16 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -944,7 +944,7 @@ static void mtk_stats_update(struct mtk_
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->mac[i] || !eth->mac[i]->hw_stats)
continue;
if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
@@ -1449,7 +1449,7 @@ static int mtk_queue_stopped(struct mtk_
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
if (netif_queue_stopped(eth->netdev[i]))
@@ -1463,7 +1463,7 @@ static void mtk_wake_queue(struct mtk_et
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
netif_tx_wake_all_queues(eth->netdev[i]);
@@ -1956,7 +1956,7 @@ static int mtk_poll_rx(struct napi_struc
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
!eth->netdev[mac]))
goto release_desc;
@@ -2993,7 +2993,7 @@ static void mtk_dma_free(struct mtk_eth
const struct mtk_soc_data *soc = eth->soc;
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++)
+ for (i = 0; i < soc->num_devs; i++)
if (eth->netdev[i])
netdev_reset_queue(eth->netdev[i]);
if (eth->scratch_ring) {
@@ -3147,7 +3147,7 @@ static void mtk_gdm_config(struct mtk_et
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
return;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
/* default setup the forward port to send frame to PDMA */
@@ -3758,7 +3758,7 @@ static int mtk_hw_init(struct mtk_eth *e
* up with the more appropriate value when mtk_mac_config call is being
* invoked.
*/
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
struct net_device *dev = eth->netdev[i];
mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
@@ -3963,7 +3963,7 @@ static void mtk_pending_work(struct work
mtk_prepare_for_reset(eth);
/* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
continue;
@@ -3979,7 +3979,7 @@ static void mtk_pending_work(struct work
mtk_hw_init(eth, true);
/* restart DMA and enable IRQs */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!test_bit(i, &restart))
continue;
@@ -4007,7 +4007,7 @@ static int mtk_free_dev(struct mtk_eth *
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
free_netdev(eth->netdev[i]);
@@ -4026,7 +4026,7 @@ static int mtk_unreg_dev(struct mtk_eth
{
int i;
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
struct mtk_mac *mac;
if (!eth->netdev[i])
continue;
@@ -4331,7 +4331,7 @@ static int mtk_add_mac(struct mtk_eth *e
}
id = be32_to_cpup(_id);
- if (id >= MTK_MAC_COUNT) {
+ if (id >= eth->soc->num_devs) {
dev_err(eth->dev, "%d is not a valid mac id\n", id);
return -EINVAL;
}
@@ -4461,7 +4461,7 @@ void mtk_eth_set_dma_device(struct mtk_e
rtnl_lock();
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
dev = eth->netdev[i];
if (!dev || !(dev->flags & IFF_UP))
@@ -4787,7 +4787,7 @@ static int mtk_remove(struct platform_de
int i;
/* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
+ for (i = 0; i < eth->soc->num_devs; i++) {
if (!eth->netdev[i])
continue;
mtk_stop(eth->netdev[i]);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -33,7 +33,6 @@
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
#define MTK_QDMA_RING_SIZE 2048
#define MTK_DMA_SIZE 512
-#define MTK_MAC_COUNT 2
#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
#define MTK_DMA_DUMMY_DESC 0xffffffff

View File

@@ -0,0 +1,292 @@
From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:55:47 +0000
Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability
bit
Introduce MTK_NETSYS_V3 bit in the device capabilities.
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++-
2 files changed, 134 insertions(+), 25 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -924,17 +924,32 @@ void mtk_stats_update_mac(struct mtk_mac
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
hw_stats->rx_flow_control_packets +=
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
- hw_stats->tx_skip +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
- hw_stats->tx_collisions +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
- hw_stats->tx_bytes +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
- if (stats)
- hw_stats->tx_bytes += (stats << 32);
- hw_stats->tx_packets +=
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ hw_stats->tx_skip +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
+ hw_stats->tx_collisions +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
+ hw_stats->tx_bytes +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
+ if (stats)
+ hw_stats->tx_bytes += (stats << 32);
+ hw_stats->tx_packets +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
+ } else {
+ hw_stats->tx_skip +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
+ hw_stats->tx_collisions +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
+ hw_stats->tx_bytes +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
+ if (stats)
+ hw_stats->tx_bytes += (stats << 32);
+ hw_stats->tx_packets +=
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
+ }
}
u64_stats_update_end(&hw_stats->syncp);
@@ -1238,7 +1253,10 @@ static void mtk_tx_set_dma_desc_v2(struc
data |= TX_DMA_LS0;
WRITE_ONCE(desc->txd3, data);
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+ if (mac->id == MTK_GMAC3_ID)
+ data = PSE_GDM3_PORT;
+ else
+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
WRITE_ONCE(desc->txd4, data);
@@ -1249,6 +1267,9 @@ static void mtk_tx_set_dma_desc_v2(struc
/* tx checksum offload */
if (info->csum)
data |= TX_DMA_CHKSUM_V2;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
+ netdev_uses_dsa(dev))
+ data |= TX_DMA_SPTAG_V3;
}
WRITE_ONCE(desc->txd5, data);
@@ -1314,8 +1335,13 @@ static int mtk_tx_map(struct sk_buff *sk
mtk_tx_set_dma_desc(dev, itxd, &txd_info);
itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
+ if (mac->id == MTK_GMAC1_ID)
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+ else if (mac->id == MTK_GMAC2_ID)
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+ else
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
+
setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
k++);
@@ -1363,8 +1389,13 @@ static int mtk_tx_map(struct sk_buff *sk
memset(tx_buf, 0, sizeof(*tx_buf));
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
- MTK_TX_FLAGS_FPORT1;
+
+ if (mac->id == MTK_GMAC1_ID)
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
+ else if (mac->id == MTK_GMAC2_ID)
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
+ else
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
txd_info.size, k++);
@@ -1950,11 +1981,24 @@ static int mtk_poll_rx(struct napi_struc
break;
/* find out which mac the packet come from. values start at 1 */
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
+
+ switch (val) {
+ case PSE_GDM1_PORT:
+ case PSE_GDM2_PORT:
+ mac = val - 1;
+ break;
+ case PSE_GDM3_PORT:
+ mac = MTK_GMAC3_ID;
+ break;
+ default:
+ break;
+ }
+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+ }
if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
!eth->netdev[mac]))
@@ -2185,7 +2229,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
tx_buf = mtk_desc_to_tx_buf(ring, desc,
eth->soc->txrx.txd_size);
if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
- mac = 1;
+ mac = MTK_GMAC2_ID;
+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
+ mac = MTK_GMAC3_ID;
if (!tx_buf->data)
break;
@@ -3796,7 +3842,26 @@ static int mtk_hw_init(struct mtk_eth *e
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
+ /* PSE should not drop port1, port8 and port9 packets */
+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
+
+ /* GDM and CDM Threshold */
+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
+
+ /* Disable GDM1 RX CRC stripping */
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
+ val &= ~MTK_GDMA_STRP_CRC;
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
+
+ /* PSE GDM3 MIB counter has incorrect hw default values,
+ * so the driver ought to read clear the values beforehand
+ * in case ethtool retrieve wrong mib values.
+ */
+ for (i = 0; i < 0x80; i += 0x4)
+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
/* PSE should not drop port8 and port9 packets from WDMA Tx */
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
@@ -4368,7 +4433,11 @@ static int mtk_add_mac(struct mtk_eth *e
}
spin_lock_init(&mac->hw_stats->stats_lock);
u64_stats_init(&mac->hw_stats->syncp);
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
+ mac->hw_stats->reg_offset = id * 0x80;
+ else
+ mac->hw_stats->reg_offset = id * 0x40;
/* phylink create */
err = of_get_phy_mode(np, &phy_mode);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -121,6 +121,7 @@
#define MTK_GDMA_ICS_EN BIT(22)
#define MTK_GDMA_TCS_EN BIT(21)
#define MTK_GDMA_UCS_EN BIT(20)
+#define MTK_GDMA_STRP_CRC BIT(16)
#define MTK_GDMA_TO_PDMA 0x0
#define MTK_GDMA_DROP_ALL 0x7777
@@ -286,8 +287,6 @@
/* QDMA Interrupt grouping registers */
#define MTK_RLS_DONE_INT BIT(0)
-#define MTK_STAT_OFFSET 0x40
-
/* QDMA TX NUM */
#define QID_BITS_V2(x) (((x) & 0x3f) << 16)
#define MTK_QDMA_GMAC2_QID 8
@@ -300,6 +299,8 @@
#define TX_DMA_CHKSUM_V2 (0x7 << 28)
#define TX_DMA_TSO_V2 BIT(31)
+#define TX_DMA_SPTAG_V3 BIT(27)
+
/* QDMA V2 descriptor txd4 */
#define TX_DMA_FPORT_SHIFT_V2 8
#define TX_DMA_FPORT_MASK_V2 0xf
@@ -639,6 +640,7 @@ enum mtk_tx_flags {
*/
MTK_TX_FLAGS_FPORT0 = 0x04,
MTK_TX_FLAGS_FPORT1 = 0x08,
+ MTK_TX_FLAGS_FPORT2 = 0x10,
};
/* This enum allows us to identify how the clock is defined on the array of the
@@ -724,6 +726,42 @@ enum mtk_dev_state {
MTK_RESETTING
};
+/* PSE Port Definition */
+enum mtk_pse_port {
+ PSE_ADMA_PORT = 0,
+ PSE_GDM1_PORT,
+ PSE_GDM2_PORT,
+ PSE_PPE0_PORT,
+ PSE_PPE1_PORT,
+ PSE_QDMA_TX_PORT,
+ PSE_QDMA_RX_PORT,
+ PSE_DROP_PORT,
+ PSE_WDMA0_PORT,
+ PSE_WDMA1_PORT,
+ PSE_TDMA_PORT,
+ PSE_NONE_PORT,
+ PSE_PPE2_PORT,
+ PSE_WDMA2_PORT,
+ PSE_EIP197_PORT,
+ PSE_GDM3_PORT,
+ PSE_PORT_MAX
+};
+
+/* GMAC Identifier */
+enum mtk_gmac_id {
+ MTK_GMAC1_ID = 0,
+ MTK_GMAC2_ID,
+ MTK_GMAC3_ID,
+ MTK_GMAC_ID_MAX
+};
+
+/* GDM Type */
+enum mtk_gdm_type {
+ MTK_GDM_TYPE = 0,
+ MTK_XGDM_TYPE,
+ MTK_GDM_TYPE_MAX
+};
+
enum mtk_tx_buf_type {
MTK_TYPE_SKB,
MTK_TYPE_XDP_TX,
@@ -820,6 +858,7 @@ enum mkt_eth_capabilities {
MTK_QDMA_BIT,
MTK_NETSYS_V1_BIT,
MTK_NETSYS_V2_BIT,
+ MTK_NETSYS_V3_BIT,
MTK_SOC_MT7628_BIT,
MTK_RSTCTRL_PPE1_BIT,
MTK_U3_COPHY_V2_BIT,
@@ -856,6 +895,7 @@ enum mkt_eth_capabilities {
#define MTK_QDMA BIT(MTK_QDMA_BIT)
#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)

View File

@@ -0,0 +1,197 @@
From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 7 Mar 2023 15:56:00 +0000
Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data
struct to u64
This is a preliminary patch to introduce support for MT7988 SoC.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++----
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 62 ++++++++++----------
2 files changed, 42 insertions(+), 42 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -15,10 +15,10 @@
struct mtk_eth_muxc {
const char *name;
int cap_bit;
- int (*set_path)(struct mtk_eth *eth, int path);
+ int (*set_path)(struct mtk_eth *eth, u64 path);
};
-static const char *mtk_eth_path_name(int path)
+static const char *mtk_eth_path_name(u64 path)
{
switch (path) {
case MTK_ETH_PATH_GMAC1_RGMII:
@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
}
}
-static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
{
bool updated = true;
u32 val, mask, set;
@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
return 0;
}
-static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0;
bool updated = true;
@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
return 0;
}
-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0, mask = 0, reg = 0;
bool updated = true;
@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
return 0;
}
-static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0;
bool updated = true;
@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
return 0;
}
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
{
unsigned int val = 0;
bool updated = true;
@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
},
};
-static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
{
int i, err = 0;
@@ -249,7 +249,7 @@ out:
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
{
- int path;
+ u64 path;
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
MTK_ETH_PATH_GMAC2_SGMII;
@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
{
- int path = 0;
+ u64 path = 0;
if (mac_id == 1)
path = MTK_ETH_PATH_GMAC2_GEPHY;
@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
{
- int path;
+ u64 path;
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII :
MTK_ETH_PATH_GMAC2_RGMII;
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -881,44 +881,44 @@ enum mkt_eth_capabilities {
};
/* Supported hardware group on SoCs */
-#define MTK_RGMII BIT(MTK_RGMII_BIT)
-#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
-#define MTK_SGMII BIT(MTK_SGMII_BIT)
-#define MTK_ESW BIT(MTK_ESW_BIT)
-#define MTK_GEPHY BIT(MTK_GEPHY_BIT)
-#define MTK_MUX BIT(MTK_MUX_BIT)
-#define MTK_INFRA BIT(MTK_INFRA_BIT)
-#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT)
-#define MTK_HWLRO BIT(MTK_HWLRO_BIT)
-#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
-#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
-#define MTK_QDMA BIT(MTK_QDMA_BIT)
-#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
-#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
-#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
-#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
-#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
+#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
+#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
+#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
+#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
+#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
+#define MTK_INFRA BIT_ULL(MTK_INFRA_BIT)
+#define MTK_SHARED_SGMII BIT_ULL(MTK_SHARED_SGMII_BIT)
+#define MTK_HWLRO BIT_ULL(MTK_HWLRO_BIT)
+#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT)
+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
+#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
+#define MTK_NETSYS_V1 BIT_ULL(MTK_NETSYS_V1_BIT)
+#define MTK_NETSYS_V2 BIT_ULL(MTK_NETSYS_V2_BIT)
+#define MTK_NETSYS_V3 BIT_ULL(MTK_NETSYS_V3_BIT)
+#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
#define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \
- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
#define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
#define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
/* Supported path present on SoCs */
-#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
-#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
-#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
-#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
@@ -1074,7 +1074,7 @@ struct mtk_reg_map {
struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;
- u32 caps;
+ u64 caps;
u32 required_clks;
bool required_pctl;
u8 offload_version;

View File

@@ -0,0 +1,495 @@
From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 25 Feb 2023 00:08:24 +0100
Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC
Introduce support for ethernet chip available in MT7988 SoC to
mtk_eth_soc driver.
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++--
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------
2 files changed, 279 insertions(+), 67 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
.pse_oq_sta = 0x01a0,
};
+static const struct mtk_reg_map mt7988_reg_map = {
+ .tx_irq_mask = 0x461c,
+ .tx_irq_status = 0x4618,
+ .pdma = {
+ .rx_ptr = 0x6900,
+ .rx_cnt_cfg = 0x6904,
+ .pcrx_ptr = 0x6908,
+ .glo_cfg = 0x6a04,
+ .rst_idx = 0x6a08,
+ .delay_irq = 0x6a0c,
+ .irq_status = 0x6a20,
+ .irq_mask = 0x6a28,
+ .adma_rx_dbg0 = 0x6a38,
+ .int_grp = 0x6a50,
+ },
+ .qdma = {
+ .qtx_cfg = 0x4400,
+ .qtx_sch = 0x4404,
+ .rx_ptr = 0x4500,
+ .rx_cnt_cfg = 0x4504,
+ .qcrx_ptr = 0x4508,
+ .glo_cfg = 0x4604,
+ .rst_idx = 0x4608,
+ .delay_irq = 0x460c,
+ .fc_th = 0x4610,
+ .int_grp = 0x4620,
+ .hred = 0x4644,
+ .ctx_ptr = 0x4700,
+ .dtx_ptr = 0x4704,
+ .crx_ptr = 0x4710,
+ .drx_ptr = 0x4714,
+ .fq_head = 0x4720,
+ .fq_tail = 0x4724,
+ .fq_count = 0x4728,
+ .fq_blen = 0x472c,
+ .tx_sch_rate = 0x4798,
+ },
+ .gdm1_cnt = 0x1c00,
+ .gdma_to_ppe = 0x3333,
+ .ppe_base = 0x2200,
+ .wdma_base = {
+ [0] = 0x4800,
+ [1] = 0x4c00,
+ },
+ .pse_iq_sta = 0x0180,
+ .pse_oq_sta = 0x01a0,
+};
+
/* strings used by ethtool */
static const struct mtk_ethtool_stats {
char str[ETH_GSTRING_LEN];
@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
};
static const char * const mtk_clks_source_name[] = {
- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
+ "ethif",
+ "sgmiitop",
+ "esw",
+ "gp0",
+ "gp1",
+ "gp2",
+ "gp3",
+ "xgp1",
+ "xgp2",
+ "xgp3",
+ "crypto",
+ "fe",
+ "trgpll",
+ "sgmii_tx250m",
+ "sgmii_rx250m",
+ "sgmii_cdr_ref",
+ "sgmii_cdr_fb",
+ "sgmii2_tx250m",
+ "sgmii2_rx250m",
+ "sgmii2_cdr_ref",
+ "sgmii2_cdr_fb",
+ "sgmii_ck",
+ "eth2pll",
+ "wocpu0",
+ "wocpu1",
+ "netsys0",
+ "netsys1",
+ "ethwarp_wocpu2",
+ "ethwarp_wocpu1",
+ "ethwarp_wocpu0",
+ "top_usxgmii0_sel",
+ "top_usxgmii1_sel",
+ "top_sgm0_sel",
+ "top_sgm1_sel",
+ "top_xfi_phy0_xtal_sel",
+ "top_xfi_phy1_xtal_sel",
+ "top_eth_gmii_sel",
+ "top_eth_refck_50m_sel",
+ "top_eth_sys_200m_sel",
+ "top_eth_sys_sel",
+ "top_eth_xgmii_sel",
+ "top_eth_mii_sel",
+ "top_netsys_sel",
+ "top_netsys_500m_sel",
+ "top_netsys_pao_2x_sel",
+ "top_netsys_sync_250m_sel",
+ "top_netsys_ppefb_250m_sel",
+ "top_netsys_warp_sel",
};
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
@@ -1253,10 +1345,19 @@ static void mtk_tx_set_dma_desc_v2(struc
data |= TX_DMA_LS0;
WRITE_ONCE(desc->txd3, data);
- if (mac->id == MTK_GMAC3_ID)
- data = PSE_GDM3_PORT;
- else
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+ /* set forward port */
+ switch (mac->id) {
+ case MTK_GMAC1_ID:
+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
+ break;
+ case MTK_GMAC2_ID:
+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
+ break;
+ case MTK_GMAC3_ID:
+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
+ break;
+ }
+
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
WRITE_ONCE(desc->txd4, data);
@@ -5016,6 +5117,25 @@ static const struct mtk_soc_data mt7986_
},
};
+static const struct mtk_soc_data mt7988_data = {
+ .reg_map = &mt7988_reg_map,
+ .ana_rgc3 = 0x128,
+ .caps = MT7988_CAPS,
+ .hw_features = MTK_HW_FEATURES,
+ .required_clks = MT7988_CLKS_BITMAP,
+ .required_pctl = false,
+ .num_devs = 3,
+ .txrx = {
+ .txd_size = sizeof(struct mtk_tx_dma_v2),
+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+ .dma_len_offset = 8,
+ },
+};
+
+
static const struct mtk_soc_data rt5350_data = {
.reg_map = &mt7628_reg_map,
.caps = MT7628_CAPS,
@@ -5034,14 +5154,15 @@ static const struct mtk_soc_data rt5350_
};
const struct of_device_id of_mtk_match[] = {
- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
{},
};
MODULE_DEVICE_TABLE(of, of_mtk_match);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -116,7 +116,8 @@
#define MTK_CDMP_EG_CTRL 0x404
/* GDM Exgress Control Register */
-#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
+#define MTK_GDMA_FWD_CFG(x) ((x == MTK_GMAC3_ID) ? \
+ 0x540 : 0x500 + (x * 0x1000))
#define MTK_GDMA_SPECIAL_TAG BIT(24)
#define MTK_GDMA_ICS_EN BIT(22)
#define MTK_GDMA_TCS_EN BIT(21)
@@ -653,6 +654,11 @@ enum mtk_clks_map {
MTK_CLK_GP0,
MTK_CLK_GP1,
MTK_CLK_GP2,
+ MTK_CLK_GP3,
+ MTK_CLK_XGP1,
+ MTK_CLK_XGP2,
+ MTK_CLK_XGP3,
+ MTK_CLK_CRYPTO,
MTK_CLK_FE,
MTK_CLK_TRGPLL,
MTK_CLK_SGMII_TX_250M,
@@ -669,57 +675,108 @@ enum mtk_clks_map {
MTK_CLK_WOCPU1,
MTK_CLK_NETSYS0,
MTK_CLK_NETSYS1,
+ MTK_CLK_ETHWARP_WOCPU2,
+ MTK_CLK_ETHWARP_WOCPU1,
+ MTK_CLK_ETHWARP_WOCPU0,
+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
+ MTK_CLK_TOP_SGM_0_SEL,
+ MTK_CLK_TOP_SGM_1_SEL,
+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
+ MTK_CLK_TOP_ETH_GMII_SEL,
+ MTK_CLK_TOP_ETH_REFCK_50M_SEL,
+ MTK_CLK_TOP_ETH_SYS_200M_SEL,
+ MTK_CLK_TOP_ETH_SYS_SEL,
+ MTK_CLK_TOP_ETH_XGMII_SEL,
+ MTK_CLK_TOP_ETH_MII_SEL,
+ MTK_CLK_TOP_NETSYS_SEL,
+ MTK_CLK_TOP_NETSYS_500M_SEL,
+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
+ MTK_CLK_TOP_NETSYS_WARP_SEL,
MTK_CLK_MAX
};
-#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
- BIT(MTK_CLK_TRGPLL))
-#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_GP2) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL))
+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_TRGPLL))
+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
+ BIT_ULL(MTK_CLK_ETH2PLL))
#define MT7621_CLKS_BITMAP (0)
#define MT7628_CLKS_BITMAP (0)
-#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII2_TX_250M) | \
- BIT(MTK_CLK_SGMII2_RX_250M) | \
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK) | \
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
-#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_WOCPU0) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII2_TX_250M) | \
- BIT(MTK_CLK_SGMII2_RX_250M) | \
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
- BIT(MTK_CLK_SGMII_CK))
-#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
- BIT(MTK_CLK_SGMII_TX_250M) | \
- BIT(MTK_CLK_SGMII_RX_250M) | \
- BIT(MTK_CLK_SGMII_CDR_REF) | \
- BIT(MTK_CLK_SGMII_CDR_FB) | \
- BIT(MTK_CLK_SGMII2_TX_250M) | \
- BIT(MTK_CLK_SGMII2_RX_250M) | \
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
- BIT(MTK_CLK_SGMII2_CDR_FB))
+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_WOCPU0) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII_CK))
+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
+ BIT_ULL(MTK_CLK_CRYPTO) | \
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
enum mtk_dev_state {
MTK_HW_INIT,
@@ -847,6 +904,7 @@ enum mkt_eth_capabilities {
MTK_RGMII_BIT = 0,
MTK_TRGMII_BIT,
MTK_SGMII_BIT,
+ MTK_USXGMII_BIT,
MTK_ESW_BIT,
MTK_GEPHY_BIT,
MTK_MUX_BIT,
@@ -869,6 +927,8 @@ enum mkt_eth_capabilities {
MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
/* PATH BITS */
MTK_ETH_PATH_GMAC1_RGMII_BIT,
@@ -877,13 +937,18 @@ enum mkt_eth_capabilities {
MTK_ETH_PATH_GMAC2_RGMII_BIT,
MTK_ETH_PATH_GMAC2_SGMII_BIT,
MTK_ETH_PATH_GMAC2_GEPHY_BIT,
+ MTK_ETH_PATH_GMAC3_SGMII_BIT,
MTK_ETH_PATH_GDM1_ESW_BIT,
+ MTK_ETH_PATH_GMAC1_USXGMII_BIT,
+ MTK_ETH_PATH_GMAC2_USXGMII_BIT,
+ MTK_ETH_PATH_GMAC3_USXGMII_BIT,
};
/* Supported hardware group on SoCs */
#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT)
#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
@@ -910,6 +975,10 @@ enum mkt_eth_capabilities {
BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
/* Supported path present on SoCs */
#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
@@ -918,7 +987,11 @@ enum mkt_eth_capabilities {
#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
@@ -926,7 +999,11 @@ enum mkt_eth_capabilities {
#define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
#define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
#define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
#define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
/* MUXes present on SoCs */
/* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
@@ -949,6 +1026,12 @@ enum mkt_eth_capabilities {
#define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \
+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
+
+#define MTK_MUX_GMAC123_TO_USXGMII \
+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
+
#ifdef CONFIG_SOC_MT7621
#define MTK_CAP_MASK MTK_NETSYS_V2
#else
@@ -987,9 +1070,17 @@ enum mkt_eth_capabilities {
MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | \
+ MTK_QDMA | MTK_NETSYS_V2 | \
+ MTK_RSTCTRL_PPE1)
+
+#define MT7988_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+ MTK_GMAC3_SGMII | MTK_QDMA | \
+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
+ MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \
+ MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \
+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
struct mtk_tx_dma_desc_info {
dma_addr_t addr;
@@ -1075,7 +1166,7 @@ struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;
u64 caps;
- u32 required_clks;
+ u64 required_clks;
bool required_pctl;
u8 offload_version;
u8 hash_offset;

View File

@@ -16,7 +16,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2086,10 +2086,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
@@ -2126,10 +2126,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
{
struct dsa_switch *ds = priv->ds;
struct device *dev = priv->dev;
@@ -30,7 +30,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
bus = devm_mdiobus_alloc(dev);
if (!bus)
return -ENOMEM;
@@ -2106,7 +2109,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
@@ -2146,7 +2149,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
if (priv->irq)
mt7530_setup_mdio_irq(priv);

View File

@@ -1,178 +0,0 @@
--- a/drivers/cpufreq/rockchip-cpufreq.c
+++ b/drivers/cpufreq/rockchip-cpufreq.c
@@ -332,13 +332,13 @@ static int rockchip_cpufreq_cluster_init
reg_table_token = dev_pm_opp_set_regulators(dev, reg_names);
if (reg_table_token < 0) {
ret = reg_table_token;
- dev_err_probe(dev, ret, "Failed to set opp regulators\n");
+ dev_err(dev, "Failed to set opp regulators\n");
goto np_err;
}
ret = dev_pm_opp_of_get_sharing_cpus(dev, &cluster->cpus);
if (ret) {
- dev_err_probe(dev, ret, "Failed to get sharing cpus\n");
+ dev_err(dev, "Failed to get sharing cpus\n");
goto np_err;
}
@@ -519,67 +519,10 @@ static int rockchip_cpufreq_init(struct
return 0;
}
-static void rockchip_cpufreq_free_list(void *data)
-{
- struct cluster_info *cluster, *pos;
-
- list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
- list_del(&cluster->list_head);
- }
-}
-
-static int rockchip_cpufreq_init_list(struct device *dev)
-{
- struct cluster_info *cluster;
- int cpu, ret;
-
- for_each_possible_cpu(cpu) {
- cluster = rockchip_cluster_info_lookup(cpu);
- if (cluster)
- continue;
-
- cluster = devm_kzalloc(dev, sizeof(*cluster), GFP_KERNEL);
- if (!cluster) {
- ret = -ENOMEM;
- goto release_cluster_info;
- }
-
- ret = rockchip_cpufreq_cluster_init(cpu, cluster);
- if (ret) {
- dev_err_probe(dev, ret, "Failed to initialize dvfs info cpu%d\n", cpu);
- goto release_cluster_info;
- }
- list_add(&cluster->list_head, &cluster_info_list);
- }
-
- return 0;
-
-release_cluster_info:
- rockchip_cpufreq_free_list(NULL);
- return ret;
-}
-
-static void rockchip_cpufreq_unregister(void *data)
-{
- cpufreq_unregister_driver(&rockchip_cpufreq_driver);
-}
-
static int rockchip_cpufreq_probe(struct platform_device *pdev)
{
int ret, cpu;
- ret = rockchip_cpufreq_init_list(&pdev->dev);
- if (ret)
- return ret;
-
- ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_free_list, NULL);
- if (ret)
- return ret;
-
- ret = devm_register_reboot_notifier(&pdev->dev, &rockchip_cpufreq_reboot_notifier);
- if (ret)
- return dev_err_probe(&pdev->dev, ret, "Failed to register reboot handler\n");
-
for_each_possible_cpu(cpu) {
ret = rockchip_cpufreq_init(&pdev->dev, cpu);
if (ret)
@@ -590,10 +533,12 @@ static int rockchip_cpufreq_probe(struct
if (ret)
return dev_err_probe(&pdev->dev, ret, "failed register driver\n");
- ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_unregister, NULL);
- if (ret)
- return ret;
+ return 0;
+}
+static int rockchip_cpufreq_remove(struct platform_device *pdev)
+{
+ cpufreq_unregister_driver(&rockchip_cpufreq_driver);
return 0;
}
@@ -602,15 +547,42 @@ static struct platform_driver rockchip_c
.name = "rockchip-cpufreq",
},
.probe = rockchip_cpufreq_probe,
+ .remove = rockchip_cpufreq_remove,
};
static int __init rockchip_cpufreq_driver_init(void)
{
- int ret;
+ struct cluster_info *cluster, *pos;
+ int cpu, ret;
+
+ for_each_possible_cpu(cpu) {
+ cluster = rockchip_cluster_info_lookup(cpu);
+ if (cluster)
+ continue;
+
+ cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);
+ if (!cluster) {
+ ret = -ENOMEM;
+ goto release_cluster_info;
+ }
+
+ ret = rockchip_cpufreq_cluster_init(cpu, cluster);
+ if (ret) {
+ pr_err("Failed to initialize dvfs info cpu%d\n", cpu);
+ goto release_cluster_info;
+ }
+ list_add(&cluster->list_head, &cluster_info_list);
+ }
+
+ ret = register_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
+ if (ret) {
+ pr_err("Failed to register reboot handler\n");
+ goto release_cluster_info;
+ }
ret = platform_driver_register(&rockchip_cpufreq_platdrv);
if (ret)
- return ret;
+ goto remove_reboot_notifier;
cpufreq_pdev = platform_device_register_data(NULL, "rockchip-cpufreq", -1,
NULL, 0);
@@ -624,14 +596,30 @@ static int __init rockchip_cpufreq_drive
unregister_platform_driver:
platform_driver_unregister(&rockchip_cpufreq_platdrv);
+
+remove_reboot_notifier:
+ unregister_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
+
+release_cluster_info:
+ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
+ list_del(&cluster->list_head);
+ kfree(cluster);
+ }
return ret;
}
module_init(rockchip_cpufreq_driver_init);
static void __exit rockchip_cpufreq_driver_exit(void)
{
+ struct cluster_info *cluster, *pos;
+
platform_device_unregister(cpufreq_pdev);
platform_driver_unregister(&rockchip_cpufreq_platdrv);
+ unregister_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
+ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
+ list_del(&cluster->list_head);
+ kfree(cluster);
+ }
}
module_exit(rockchip_cpufreq_driver_exit)