From 8a75ed4ba07b9d64ae547ce36873e51ba54f0eaf Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Thu, 23 Sep 2021 23:44:57 -0700 Subject: [PATCH 01/23] musl-fts: remove shared libraries from host Avoids having to add rpath to the various packages using it. Also add PIC to fix compilation as static libraries do not use PIC by default. Fixes: 1fb099341e58 ("musl-fts: add host build") Signed-off-by: Rosen Penev --- package/libs/musl-fts/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/libs/musl-fts/Makefile b/package/libs/musl-fts/Makefile index e913fe167f..72341cd379 100644 --- a/package/libs/musl-fts/Makefile +++ b/package/libs/musl-fts/Makefile @@ -44,6 +44,7 @@ define Package/musl-fts/description The musl-fts package implements the fts(3) functions fts_open, fts_read, fts_children, fts_set and fts_close, which are missing in musl libc. endef +HOST_CONFIGURE_ARGS += --disable-shared --with-pic define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include From f8571749a77ea23b418c84692220083858c1df79 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 19 Mar 2022 16:18:49 -0700 Subject: [PATCH 02/23] pcre: disable shared libraries for host builds Getting rid of shared libraries for hostpkg avoids having to use rpath hacks to find the library. It also fixes compilation with host glib2 binaries. Signed-off-by: Rosen Penev --- package/libs/pcre/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/libs/pcre/Makefile b/package/libs/pcre/Makefile index 42149fc511..43267562ea 100644 --- a/package/libs/pcre/Makefile +++ b/package/libs/pcre/Makefile @@ -62,6 +62,7 @@ define Package/libpcrecpp endef HOST_CONFIGURE_ARGS += \ + --disable-shared \ --enable-utf8 \ --enable-unicode-properties \ --enable-pcre16 \ From 8a5d095969e14e8a06975e61739facd0edd835cc Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 19 Mar 2022 16:51:43 -0700 Subject: [PATCH 03/23] elfutils: fix host compilation with Alpine Linux intl is not included in libc, disable it as is done with the target package. argp is also not included. Add build depends for argp-standalone. fts is also not included. Add build depends for musl-fts. Disable shared libraries to avoid having to manually add rpath. Signed-off-by: Rosen Penev --- package/libs/elfutils/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/libs/elfutils/Makefile b/package/libs/elfutils/Makefile index 9aa78d8352..07b3ea66c6 100644 --- a/package/libs/elfutils/Makefile +++ b/package/libs/elfutils/Makefile @@ -24,6 +24,8 @@ PKG_INSTALL:=1 PKG_USE_MIPS16:=1 PKG_BUILD_DEPENDS:=!USE_GLIBC:argp-standalone +HOST_BUILD_DEPENDS:=argp-standalone/host musl-fts/host + include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/nls.mk include $(INCLUDE_DIR)/host-build.mk @@ -62,6 +64,8 @@ CONFIGURE_ARGS += --disable-nls endif HOST_CONFIGURE_ARGS += \ + --disable-shared \ + --disable-nls \ --disable-debuginfod \ --disable-libdebuginfod \ --without-lzma \ From 73683454507163703beb3bc7d9f2e1dea189aa91 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 26 Mar 2022 17:34:33 +0100 Subject: [PATCH 04/23] gpio-cdev: provide HASH values for nu801 Chen Minqiang reported that he has troubles downloading nu801. His logs showed the followin TLS Handshake failure. |Checking out files from the git repository... |Cloning into 'nu801-d9942c0c'... |fatal: unable to access 'https://github.com/chunkeey/nu801.git/': | gnutls_handshake() failed: The TLS connection was non-properly terminated. |Makefile:39: recipe for target '[...]/dl/nu801-d9942c0c.tar.xz' failed This can be fixed by providing a PKG_MIRROR_HASH. The download scripts will now be able to pull the source from OpenWrt's source archive, which should be available through HTTP. Reported-by: Chen Minqiang Signed-off-by: Christian Lamparter --- package/system/gpio-cdev/nu801/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/system/gpio-cdev/nu801/Makefile b/package/system/gpio-cdev/nu801/Makefile index b3fae616cd..ff6d36f2b4 100644 --- a/package/system/gpio-cdev/nu801/Makefile +++ b/package/system/gpio-cdev/nu801/Makefile @@ -8,7 +8,7 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/chunkeey/nu801.git PKG_SOURCE_VERSION:=d9942c0ceb949080b93366a9431028de3608e535 - +PKG_MIRROR_HASH:=859be7dec96d2a0d6ee8b80c6f1a703384940d19caeeb74a4ac0a961b2a985db PKG_MAINTAINER:=Christian Lamparter PKG_LICENSE:=GPL-3.0-or-later PKG_LICENSE_FILES:=LICENSE From eeb8fd4ce7e90ec24287c469628ae528a14daa6f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 27 Mar 2022 15:04:29 +0200 Subject: [PATCH 05/23] gpio-cdev: move kmod-leds-uleds dependency to MX100 The inclusion of the kmod-leds-uleds into the userspace nu801 package causes a circular dependency inside the buildsystem... which causes it to be picked regardless of other DEPENDS values. In case of the mx100, this could be solved by moving the kmod-leds-uled dependency to the kmod-meraki-mx100. Bonus: drop @!LINUX_5_4 from kmod-meraki-mx100 Signed-off-by: Christian Lamparter --- package/system/gpio-cdev/nu801/Makefile | 2 +- target/linux/x86/modules.mk | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package/system/gpio-cdev/nu801/Makefile b/package/system/gpio-cdev/nu801/Makefile index ff6d36f2b4..1ac5c6d510 100644 --- a/package/system/gpio-cdev/nu801/Makefile +++ b/package/system/gpio-cdev/nu801/Makefile @@ -20,7 +20,7 @@ define Package/nu801 SECTION:=utils CATEGORY:=Utilities SUBMENU:=Userspace GPIO Drivers - DEPENDS:=@TARGET_x86 +kmod-leds-uleds + DEPENDS:=@TARGET_x86 KCONFIG:=CONFIG_GPIO_CDEV=y TITLE:=NU801 LED Driver endef diff --git a/target/linux/x86/modules.mk b/target/linux/x86/modules.mk index 0071ebda41..f3226e3a60 100644 --- a/target/linux/x86/modules.mk +++ b/target/linux/x86/modules.mk @@ -87,8 +87,8 @@ $(eval $(call KernelPackage,pcengines-apuv2)) define KernelPackage/meraki-mx100 SUBMENU:=$(OTHER_MENU) TITLE:=Cisco Meraki MX100 Platform Driver - DEPENDS:=@TARGET_x86 @!LINUX_5_4 +kmod-tg3 +kmod-gpio-button-hotplug +kmod-leds-gpio \ - +kmod-usb-ledtrig-usbport +nu801 +kmod-itco-wdt + DEPENDS:=@TARGET_x86 +kmod-tg3 +kmod-gpio-button-hotplug +kmod-leds-gpio \ + +kmod-usb-ledtrig-usbport +nu801 +kmod-itco-wdt +kmod-leds-uleds KCONFIG:=CONFIG_MERAKI_MX100 FILES:=$(LINUX_DIR)/drivers/platform/x86/meraki-mx100.ko AUTOLOAD:=$(call AutoLoad,60,meraki-mx100,1) From 35d2bbc29ba7f802706bf65585aeb8808fcac622 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 27 Mar 2022 15:12:40 +0200 Subject: [PATCH 06/23] ipq40xx: stop chromium sub-target builds on the buildbots the buildbots are having troubles with the image. They seem to get "Killed" at the last step of the KERNEL rule: |/cros-vbutil -k zImage.itb.vboot -c "root=PARTUUID=%U/PARTNROFF=1" -o zImage.itb.vboot.new |make[4]: *** [Makefile:18: zImage.itb.vboot] Killed Since the Google Wifi (Gale) is currently the only target in this sub-target. So this means that subtarget has to be disabled from the time being to not be picked up by the builders. For people wanting to checkout out OpenWrt on the Google Wifi: please compile it locally. Signed-off-by: Christian Lamparter --- target/linux/ipq40xx/chromium/target.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ipq40xx/chromium/target.mk b/target/linux/ipq40xx/chromium/target.mk index 3983a9281a..3ce52d7b42 100644 --- a/target/linux/ipq40xx/chromium/target.mk +++ b/target/linux/ipq40xx/chromium/target.mk @@ -1,2 +1,2 @@ BOARDNAME:=Google Chromium -FEATURES += emmc boot-part rootfs-part +FEATURES += emmc boot-part rootfs-part source-only From f08fc0747ec43aabdc846fe159f2bb90a6fee387 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 27 Mar 2022 14:49:09 +0100 Subject: [PATCH 07/23] kernel: 5.15: add more missing symbols Add various Kconfig symbols which surfaced when building with all kernel modules enabled. Signed-off-by: Daniel Golle --- target/linux/generic/config-5.15 | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index 68addb1fca..e5023b342b 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -817,6 +817,7 @@ CONFIG_CACHE_L2X0_PMU=y # CONFIG_CAN_BCM is not set # CONFIG_CAN_DEBUG_DEVICES is not set # CONFIG_CAN_DEV is not set +# CONFIG_CAN_ETAS_ES58X is not set # CONFIG_CAN_GS_USB is not set # CONFIG_CAN_GW is not set # CONFIG_CAN_HI311X is not set @@ -1715,6 +1716,7 @@ CONFIG_DVB_MAX_ADAPTERS=16 # CONFIG_DVB_MT312 is not set # CONFIG_DVB_MT352 is not set # CONFIG_DVB_MXL5XX is not set +# CONFIG_DVB_MXL692 is not set # CONFIG_DVB_NET is not set # CONFIG_DVB_NXT200X is not set # CONFIG_DVB_NXT6000 is not set @@ -2274,7 +2276,9 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set # CONFIG_HID_EMS_FF is not set +# CONFIG_IP_VS_TWOS is not set # CONFIG_HID_EZKEY is not set +# CONFIG_HID_FT260 is not set # CONFIG_HID_GEMBIRD is not set # CONFIG_HID_GENERIC is not set # CONFIG_HID_GFRM is not set @@ -2840,6 +2844,7 @@ CONFIG_IP_ROUTE_VERBOSE=y # CONFIG_IP_VS is not set # CONFIG_IP_VS_MH is not set CONFIG_IP_VS_MH_TAB_INDEX=10 +# CONFIG_IP_VS_TWOS is not set # CONFIG_IRDA is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_IRQ_ALL_CPUS is not set @@ -3507,6 +3512,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MLX4_CORE is not set # CONFIG_MLX4_EN is not set # CONFIG_MLX5_CORE is not set +# CONFIG_MLX5_SF is not set # CONFIG_MLX90614 is not set # CONFIG_MLX90632 is not set # CONFIG_MLXFW is not set @@ -4740,6 +4746,7 @@ CONFIG_PROC_SYSCTL=y # CONFIG_PSI is not set # CONFIG_PSTORE is not set # CONFIG_PSTORE_842_COMPRESS is not set +# CONFIG_PSTORE_BLK is not set # CONFIG_PSTORE_COMPRESS is not set # CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" # CONFIG_PSTORE_CONSOLE is not set @@ -5323,11 +5330,13 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_BEL_PFE is not set # CONFIG_SENSORS_BH1770 is not set # CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BPA_RS600 is not set # CONFIG_SENSORS_CORETEMP is not set # CONFIG_SENSORS_CORSAIR_CPRO is not set # CONFIG_SENSORS_CORSAIR_PSU is not set # CONFIG_SENSORS_DELL_SMM is not set # CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DPS920AB is not set # CONFIG_SENSORS_DRIVETEMP is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_DS620 is not set @@ -5339,6 +5348,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_FAM15H_POWER is not set # CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_FSP_3Y is not set # CONFIG_SENSORS_FTSTEUTATES is not set # CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_G762 is not set @@ -5361,6 +5371,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_INA3221 is not set # CONFIG_SENSORS_INSPUR_IPSPS is not set # CONFIG_SENSORS_IR35221 is not set +# CONFIG_SENSORS_IR36021 is not set # CONFIG_SENSORS_IR38064 is not set # CONFIG_SENSORS_IRPS5401 is not set # CONFIG_SENSORS_ISL29018 is not set @@ -5407,6 +5418,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_LTQ_CPUTEMP is not set # CONFIG_SENSORS_MAX1111 is not set # CONFIG_SENSORS_MAX127 is not set +# CONFIG_SENSORS_MAX15301 is not set # CONFIG_SENSORS_MAX16064 is not set # CONFIG_SENSORS_MAX16065 is not set # CONFIG_SENSORS_MAX1619 is not set @@ -5427,6 +5439,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_MAX6697 is not set # CONFIG_SENSORS_MAX8688 is not set # CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_MP2888 is not set # CONFIG_SENSORS_MP2975 is not set # CONFIG_SENSORS_MR75203 is not set # CONFIG_SENSORS_NCT6683 is not set @@ -5441,12 +5454,15 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_PIM4328 is not set +# CONFIG_SENSORS_PM6764TR is not set # CONFIG_SENSORS_PMBUS is not set # CONFIG_SENSORS_POWR1220 is not set # CONFIG_SENSORS_PWM_FAN is not set # CONFIG_SENSORS_PXE1610 is not set # CONFIG_SENSORS_RM3100_I2C is not set # CONFIG_SENSORS_RM3100_SPI is not set +# CONFIG_SENSORS_Q54SJ108A2 is not set # CONFIG_SENSORS_SBRMI is not set # CONFIG_SENSORS_SBTSI is not set # CONFIG_SENSORS_SCH5627 is not set @@ -5462,6 +5478,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_STPDDC60 is not set # CONFIG_SENSORS_STTS751 is not set # CONFIG_SENSORS_TC654 is not set # CONFIG_SENSORS_TC74 is not set @@ -5797,6 +5814,8 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SIS7019 is not set # CONFIG_SND_SOC is not set # CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1372_I2C is not set +# CONFIG_SND_SOC_ADAU1372_SPI is not set # CONFIG_SND_SOC_ADAU1701 is not set # CONFIG_SND_SOC_ADAU1761_I2C is not set # CONFIG_SND_SOC_ADAU1761_SPI is not set @@ -5859,6 +5878,7 @@ CONFIG_SND_PROC_FS=y # CONFIG_SND_SOC_FSL_SAI is not set # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_XCVR is not set # CONFIG_SND_SOC_GTM601 is not set # CONFIG_SND_SOC_ICS43432 is not set # CONFIG_SND_SOC_IMG is not set @@ -5906,6 +5926,10 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_JZ4725B_CODEC is not set # CONFIG_SND_SOC_JZ4740_CODEC is not set # CONFIG_SND_SOC_JZ4770_CODEC is not set +# CONFIG_SND_SOC_LPASS_RX_MACRO is not set +# CONFIG_SND_SOC_LPASS_TX_MACRO is not set +# CONFIG_SND_SOC_LPASS_VA_MACRO is not set +# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set # CONFIG_SND_SOC_MA120X0P is not set # CONFIG_SND_SOC_MAX9759 is not set # CONFIG_SND_SOC_MAX98088 is not set @@ -5925,11 +5949,16 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_MT2701 is not set # CONFIG_SND_SOC_MT6351 is not set # CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_MT6359 is not set +# CONFIG_SND_SOC_MT6359_ACCDET is not set # CONFIG_SND_SOC_MT6660 is not set # CONFIG_SND_SOC_MT6797 is not set # CONFIG_SND_SOC_MT8173 is not set # CONFIG_SND_SOC_MT8183 is not set +# CONFIG_SND_SOC_MT8192 is not set +# CONFIG_SND_SOC_MT8195 is not set # CONFIG_SND_SOC_MTK_BTCVSD is not set +# CONFIG_SND_SOC_NAU8315 is not set # CONFIG_SND_SOC_NAU8540 is not set # CONFIG_SND_SOC_NAU8810 is not set # CONFIG_SND_SOC_NAU8822 is not set @@ -5951,13 +5980,17 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_RK3328 is not set # CONFIG_SND_SOC_RT5616 is not set # CONFIG_SND_SOC_RT5631 is not set +# CONFIG_SND_SOC_RT5640 is not set +# CONFIG_SND_SOC_RT5659 is not set # CONFIG_SND_SOC_RT5677_SPI is not set # CONFIG_SND_SOC_SGTL5000 is not set # CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set +# CONFIG_SND_SOC_SIMPLE_MUX is not set # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set # CONFIG_SND_SOC_SOF_TOPLEVEL is not set # CONFIG_SND_SOC_SPDIF is not set # CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2518 is not set # CONFIG_SND_SOC_SSM2602_I2C is not set # CONFIG_SND_SOC_SSM2602_SPI is not set # CONFIG_SND_SOC_SSM4567 is not set @@ -5974,9 +6007,12 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_TAS6424 is not set # CONFIG_SND_SOC_TDA7419 is not set # CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TFA989X is not set # CONFIG_SND_SOC_TLV320ADCX140 is not set # CONFIG_SND_SOC_TLV320AIC23_I2C is not set # CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set # CONFIG_SND_SOC_TLV320AIC31XX is not set # CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set # CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set @@ -6948,6 +6984,7 @@ CONFIG_USB_SERIAL_SAFE_PADDED=y # CONFIG_USB_SERIAL_WHITEHEAT is not set # CONFIG_USB_SERIAL_WISHBONE is not set # CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_XR is not set # CONFIG_USB_SERIAL_XSENS_MT is not set # CONFIG_USB_SEVSEG is not set # CONFIG_USB_SIERRA_NET is not set @@ -7060,6 +7097,7 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_BT866 is not set # CONFIG_VIDEO_CADENCE is not set # CONFIG_VIDEO_CAFE_CCIC is not set +# CONFIG_VIDEO_CCS is not set # CONFIG_VIDEO_CS3308 is not set # CONFIG_VIDEO_CS5345 is not set # CONFIG_VIDEO_CS53L32A is not set @@ -7089,7 +7127,10 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_IMX274 is not set # CONFIG_VIDEO_IMX290 is not set # CONFIG_VIDEO_IMX319 is not set +# CONFIG_VIDEO_IMX334 is not set +# CONFIG_VIDEO_IMX335 is not set # CONFIG_VIDEO_IMX355 is not set +# CONFIG_VIDEO_IMX412 is not set # CONFIG_VIDEO_IMX477 is not set # CONFIG_VIDEO_IRS1125 is not set # CONFIG_VIDEO_IR_I2C is not set @@ -7115,6 +7156,7 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_MXB is not set # CONFIG_VIDEO_NOON010PC30 is not set # CONFIG_VIDEO_OMAP2_VOUT is not set +# CONFIG_VIDEO_OV02A10 is not set # CONFIG_VIDEO_OV13858 is not set # CONFIG_VIDEO_OV2640 is not set # CONFIG_VIDEO_OV2659 is not set @@ -7122,6 +7164,7 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_OV2685 is not set # CONFIG_VIDEO_OV2740 is not set # CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5648 is not set # CONFIG_VIDEO_OV5645 is not set # CONFIG_VIDEO_OV5647 is not set # CONFIG_VIDEO_OV5670 is not set @@ -7134,11 +7177,14 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_OV772X is not set # CONFIG_VIDEO_OV7740 is not set # CONFIG_VIDEO_OV8856 is not set +# CONFIG_VIDEO_OV8865 is not set # CONFIG_VIDEO_OV9281 is not set +# CONFIG_VIDEO_OV9282 is not set # CONFIG_VIDEO_OV9640 is not set # CONFIG_VIDEO_OV9650 is not set # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_RDACM20 is not set +# CONFIG_VIDEO_RDACM21 is not set # CONFIG_VIDEO_RJ54N1 is not set # CONFIG_VIDEO_S5C73M3 is not set # CONFIG_VIDEO_S5K4ECGX is not set From f667277dd03ca0c93137b915c839a11a051d9220 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 27 Mar 2022 14:48:15 +0100 Subject: [PATCH 08/23] kernel: 5.15: add missing Kconfig symbols for NFS Add new Kconfig symbols for NFSv4.1 and NFSv4.2 to kmod-nfs-common and kmod-nfsd. Signed-off-by: Daniel Golle --- package/kernel/linux/modules/fs.mk | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk index e580a94c60..a6f808a86a 100644 --- a/package/kernel/linux/modules/fs.mk +++ b/package/kernel/linux/modules/fs.mk @@ -402,7 +402,13 @@ define KernelPackage/fs-nfs-common KCONFIG:= \ CONFIG_LOCKD \ CONFIG_SUNRPC \ - CONFIG_GRACE_PERIOD + CONFIG_GRACE_PERIOD \ + CONFIG_NFS_V4=y \ + CONFIG_NFS_V4_1=y \ + CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" \ + CONFIG_NFS_V4_1_MIGRATION=n \ + CONFIG_NFS_V4_2=y \ + CONFIG_NFS_V4_2_READ_PLUS=n FILES:= \ $(LINUX_DIR)/fs/lockd/lockd.ko \ $(LINUX_DIR)/net/sunrpc/sunrpc.ko \ @@ -488,7 +494,8 @@ define KernelPackage/fs-nfsd CONFIG_NFSD_BLOCKLAYOUT=n \ CONFIG_NFSD_SCSILAYOUT=n \ CONFIG_NFSD_FLEXFILELAYOUT=n \ - CONFIG_NFSD_FAULT_INJECTION=n + CONFIG_NFSD_FAULT_INJECTION=n \ + CONFIG_NFSD_V4_2_INTER_SSC=n FILES:=$(LINUX_DIR)/fs/nfsd/nfsd.ko AUTOLOAD:=$(call AutoLoad,40,nfsd) endef From c3029f3652cc42b059d6861ae2fa9b5bcd62fe46 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sun, 27 Mar 2022 14:47:15 +0100 Subject: [PATCH 09/23] mediatek: add 5.15 config for mt7623 and mt7629 Compile tested both with all kernel modules. Run-time tested mt7623 on BananaPi-R2. Signed-off-by: Daniel Golle --- target/linux/mediatek/mt7623/config-5.15 | 628 +++++++++++++++++++++++ target/linux/mediatek/mt7629/config-5.15 | 306 +++++++++++ 2 files changed, 934 insertions(+) create mode 100644 target/linux/mediatek/mt7623/config-5.15 create mode 100644 target/linux/mediatek/mt7629/config-5.15 diff --git a/target/linux/mediatek/mt7623/config-5.15 b/target/linux/mediatek/mt7623/config-5.15 new file mode 100644 index 0000000000..a46c883dff --- /dev/null +++ b/target/linux/mediatek/mt7623/config-5.15 @@ -0,0 +1,628 @@ +CONFIG_AF_UNIX_OOB=y +# CONFIG_AIO is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_APPENDED_DTB=y +# CONFIG_ARM_ATAG_DTB_COMPAT is not set +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 +CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_MEDIATEK_CPUFREQ=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GPIO=y +CONFIG_BACKLIGHT_LED=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_BINARY_PRINTF=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLEANCACHE=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MT2701=y +CONFIG_COMMON_CLK_MT2701_AUDSYS=y +CONFIG_COMMON_CLK_MT2701_BDPSYS=y +CONFIG_COMMON_CLK_MT2701_ETHSYS=y +CONFIG_COMMON_CLK_MT2701_G3DSYS=y +CONFIG_COMMON_CLK_MT2701_HIFSYS=y +CONFIG_COMMON_CLK_MT2701_IMGSYS=y +CONFIG_COMMON_CLK_MT2701_MMSYS=y +CONFIG_COMMON_CLK_MT2701_VDECSYS=y +# CONFIG_COMMON_CLK_MT7622 is not set +# CONFIG_COMMON_CLK_MT7629 is not set +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_COREDUMP=y +# CONFIG_CPUFREQ_DT is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_MISC=y +CONFIG_DEBUG_MT6589_UART0=y +# CONFIG_DEBUG_MT8127_UART0 is not set +# CONFIG_DEBUG_MT8135_UART3 is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_UART_8250=y +CONFIG_DEBUG_UART_8250_SHIFT=2 +CONFIG_DEBUG_UART_PHYS=0x11004000 +CONFIG_DEBUG_UART_VIRT=0xf1004000 +CONFIG_DEBUG_UNCOMPRESS=y +# CONFIG_DEVFREQ_GOV_PASSIVE is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +# CONFIG_DEVFREQ_THERMAL is not set +CONFIG_DIMLIB=y +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DRM=y +CONFIG_DRM_BRIDGE=y +CONFIG_DRM_DISPLAY_CONNECTOR=y +CONFIG_DRM_FBDEV_EMULATION=y +CONFIG_DRM_FBDEV_OVERALLOC=100 +CONFIG_DRM_GEM_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_KMS_HELPER=y +CONFIG_DRM_LIMA=y +CONFIG_DRM_LVDS_CODEC=y +CONFIG_DRM_MEDIATEK=y +CONFIG_DRM_MEDIATEK_HDMI=y +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_PANEL=y +CONFIG_DRM_PANEL_BRIDGE=y +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=y +CONFIG_DRM_SCHED=y +CONFIG_DRM_SIMPLE_BRIDGE=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_ELF_CORE=y +CONFIG_EXT4_FS=y +CONFIG_EXTCON=y +CONFIG_F2FS_FS=y +CONFIG_FB=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_CMDLINE=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_SYS_IMAGEBLIT=y +CONFIG_FIT_PARTITION=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONT_SUPPORT=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +CONFIG_FREEZER=y +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_CACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_CDEV=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HDMI=y +CONFIG_HID=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HWMON=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MT65XX=y +CONFIG_ICPLUS_PHY=y +CONFIG_IIO=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_IOMMU_API=y +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set +CONFIG_IOMMU_IO_PGTABLE=y +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_JBD2=y +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADC is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_FSIA6B is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_PSXPAD_SPI is not set +# CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_QWIIC is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_WALKERA0701 is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_XPAD is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +CONFIG_KALLSYMS=y +CONFIG_KCMP=y +CONFIG_KEYBOARD_MTK_PMIC=y +CONFIG_KMAP_LOCAL=y +CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_PLATFORM=y +CONFIG_LEDS_MT6323=y +# CONFIG_LEDS_UBNT_LEDBAR is not set +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LTO_NONE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +CONFIG_MACH_MT7623=y +# CONFIG_MACH_MT7629 is not set +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAILBOX=y +# CONFIG_MAILBOX_TEST is not set +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MDIO_GPIO=y +CONFIG_MEDIATEK_GE_PHY=y +CONFIG_MEDIATEK_MT6577_AUXADC=y +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY=y +CONFIG_MFD_CORE=y +# CONFIG_MFD_HI6421_SPMI is not set +CONFIG_MFD_MT6397=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_CQHCI=y +CONFIG_MMC_MTK=y +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_CYAPA is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTK_CMDQ=y +CONFIG_MTK_CMDQ_MBOX=y +CONFIG_MTK_CQDMA=y +CONFIG_MTK_EFUSE=y +# CONFIG_MTK_HSDMA is not set +CONFIG_MTK_INFRACFG=y +CONFIG_MTK_IOMMU=y +CONFIG_MTK_IOMMU_V1=y +CONFIG_MTK_MMSYS=y +CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_SCPSYS_PM_DOMAINS=y +CONFIG_MTK_SMI=y +# CONFIG_MTK_SPI_NAND is not set +CONFIG_MTK_THERMAL=y +CONFIG_MTK_TIMER=y +# CONFIG_MTK_UART_APDMA is not set +# CONFIG_MUSB_PIO_ONLY is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_MEDIATEK_SOC_WED=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NLS=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=y +# CONFIG_NVMEM_SPMI_SDAM is not set +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IOMMU=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_OVERLAY=y +CONFIG_OF_RESOLVE=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PAHOLE_HAS_SPLIT_BTF=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MTK_HDMI=y +CONFIG_PHY_MTK_MIPI_DSI=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT2701=y +CONFIG_PINCTRL_MT6397=y +CONFIG_PINCTRL_MT7623=y +CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PINCTRL_MTK_V2=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_DEVFREQ=y +# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PM_GENERIC_DOMAINS_SLEEP=y +CONFIG_PM_OPP=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_MT6323 is not set +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PREEMPT=y +CONFIG_PREEMPTION=y +CONFIG_PREEMPT_COUNT=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_RCU=y +CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6358 is not set +# CONFIG_REGULATOR_MT6380 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_QCOM_LABIBB is not set +# CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_RTC_DRV_MT7622 is not set +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +# CONFIG_RTL8367S_GSW is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SERIAL_8250_DMA is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +# CONFIG_SMP_ON_UP is not set +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_DYNAMIC=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +# CONFIG_SPI_MTK_NOR is not set +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +CONFIG_SRCU=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYNC_FILE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TABLET_SERIAL_WACOM4 is not set +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +# CONFIG_TABLET_USB_PEGASUS is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TOUCHSCREEN_EDT_FT5X06=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +# CONFIG_UACCE is not set +CONFIG_UBIFS_FS=y +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_F_ACM=y +CONFIG_USB_F_ECM=y +CONFIG_USB_F_MASS_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_USB_G_MULTI=y +CONFIG_USB_G_MULTI_CDC=y +# CONFIG_USB_G_MULTI_RNDIS is not set +CONFIG_USB_HID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_INVENTRA_DMA=y +CONFIG_USB_LIBCOMPOSITE=y +CONFIG_USB_MUSB_DUAL_ROLE=y +# CONFIG_USB_MUSB_GADGET is not set +CONFIG_USB_MUSB_HDRC=y +# CONFIG_USB_MUSB_HOST is not set +CONFIG_USB_MUSB_MEDIATEK=y +CONFIG_USB_OTG=y +CONFIG_USB_PHY=y +CONFIG_USB_ROLE_SWITCH=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_U_ETHER=y +CONFIG_USB_U_SERIAL=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_VIDEOMODE_HELPERS=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/mediatek/mt7629/config-5.15 b/target/linux/mediatek/mt7629/config-5.15 new file mode 100644 index 0000000000..6a6e69e582 --- /dev/null +++ b/target/linux/mediatek/mt7629/config-5.15 @@ -0,0 +1,306 @@ +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_HEAVY_MB=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_ARM_THUMB=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ATAGS=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_PM=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_CACHE_L2X0=y +# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CHR_DEV_SCH=y +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_MEDIATEK=y +# CONFIG_COMMON_CLK_MT2701 is not set +# CONFIG_COMMON_CLK_MT7622 is not set +CONFIG_COMMON_CLK_MT7629=y +CONFIG_COMMON_CLK_MT7629_ETHSYS=y +CONFIG_COMMON_CLK_MT7629_HIFSYS=y +# CONFIG_COMMON_CLK_MT8135 is not set +# CONFIG_COMMON_CLK_MT8173 is not set +CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +CONFIG_DEBUG_MISC=y +CONFIG_DEFAULT_HOSTNAME="(mt7629)" +CONFIG_DIMLIB=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DTC=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EINT_MTK=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_ARCH_TOPOLOGY=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MIGRATION=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GPIOLIB=y +CONFIG_HANDLE_DOMAIN_IRQ=y +# CONFIG_HARDENED_USERCOPY is not set +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MTK=y +CONFIG_HZ_FIXED=0 +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IO_URING=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_TIME_ACCOUNTING=y +CONFIG_IRQ_WORK=y +# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set +# CONFIG_LEDS_UBNT_LEDBAR is not set +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_MT2701 is not set +# CONFIG_MACH_MT6589 is not set +# CONFIG_MACH_MT6592 is not set +# CONFIG_MACH_MT7623 is not set +CONFIG_MACH_MT7629=y +# CONFIG_MACH_MT8127 is not set +# CONFIG_MACH_MT8135 is not set +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MEDIATEK_MT6577_AUXADC is not set +CONFIG_MEDIATEK_WATCHDOG=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_MTK=y +CONFIG_MTD_NAND_MTK_BMT=y +# CONFIG_MTD_PARSER_TRX is not set +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NAND=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_MTK_CMDQ is not set +# CONFIG_MTK_EFUSE is not set +CONFIG_MTK_INFRACFG=y +# CONFIG_MTK_PMIC_WRAP is not set +CONFIG_MTK_SCPSYS=y +CONFIG_MTK_SCPSYS_PM_DOMAINS=y +CONFIG_MTK_SPI_NAND=y +# CONFIG_MTK_THERMAL is not set +CONFIG_MTK_TIMER=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NETFILTER=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_VENDOR_MEDIATEK=y +CONFIG_NLS=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=2 +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_OF_NET=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_MEDIATEK=y +CONFIG_PCIE_PME=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MTK_TPHY=y +# CONFIG_PHY_MTK_UFS is not set +# CONFIG_PHY_MTK_XSPHY is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_MT7629=y +CONFIG_PINCTRL_MTK_MOORE=y +CONFIG_PINCTRL_MTK_V2=y +CONFIG_PM=y +CONFIG_PM_CLK=y +CONFIG_PM_GENERIC_DOMAINS=y +CONFIG_PM_GENERIC_DOMAINS_OF=y +CONFIG_PWM=y +CONFIG_PWM_MEDIATEK=y +# CONFIG_PWM_MTK_DISP is not set +CONFIG_PWM_SYSFS=y +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +# CONFIG_RTL8367S_GSW is not set +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_SCSI=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SGL_ALLOC=y +CONFIG_SG_POOL=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT65XX=y +CONFIG_SPI_MTK_NOR=y +CONFIG_SRCU=y +CONFIG_STACKTRACE=y +# CONFIG_SWAP is not set +CONFIG_SWCONFIG=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +# CONFIG_USB_XHCI_PLATFORM is not set +CONFIG_USE_OF=y +# CONFIG_VFP is not set +CONFIG_WATCHDOG_CORE=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y From 1e83d53fd96a400b2f131b8cb0e5b5e92dc546b0 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Sun, 27 Mar 2022 15:04:37 +0200 Subject: [PATCH 10/23] kernel: add more missing config symbols for 5.15 Add more disabled config options found in malta target to generic. Signed-off-by: Aleksander Jan Bajkowski --- target/linux/generic/config-5.15 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index e5023b342b..b217738cb4 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -920,6 +920,7 @@ CONFIG_CIFS_POSIX=y CONFIG_CIFS_XATTR=y # CONFIG_CIO_DAC is not set # CONFIG_CLEANCACHE is not set +# CONFIG_CLKSRC_PISTACHIO is not set # CONFIG_CLKSRC_VERSATILE is not set # CONFIG_CLK_GFM_LPASS_SM8250 is not set # CONFIG_CLK_HSDK is not set @@ -961,6 +962,7 @@ CONFIG_CMDLINE="" # CONFIG_COMMON_CLK_MT8192 is not set # CONFIG_COMMON_CLK_NXP is not set # CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_PISTACHIO is not set # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_QCOM is not set @@ -2200,6 +2202,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_TPIC2810 is not set # CONFIG_GPIO_TS4900 is not set # CONFIG_GPIO_TS5500 is not set +# CONFIG_GPIO_VIRTIO is not set # CONFIG_GPIO_VX855 is not set # CONFIG_GPIO_WATCHDOG is not set # CONFIG_GPIO_WINBOND is not set @@ -2629,6 +2632,7 @@ CONFIG_INET=y # CONFIG_INGENIC_ADC is not set # CONFIG_INGENIC_CGU_JZ4725B is not set # CONFIG_INGENIC_CGU_JZ4740 is not set +# CONFIG_INGENIC_CGU_JZ4760 is not set # CONFIG_INGENIC_CGU_JZ4770 is not set # CONFIG_INGENIC_CGU_JZ4780 is not set # CONFIG_INGENIC_CGU_X1000 is not set @@ -3200,8 +3204,10 @@ CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_MACH_LOONGSON2EF is not set # CONFIG_MACH_LOONGSON32 is not set # CONFIG_MACH_LOONGSON64 is not set +# CONFIG_MACH_NINTENDO64 is not set # CONFIG_MACH_PIC32 is not set # CONFIG_MACH_PISTACHIO is not set +# CONFIG_MACH_REALTEK_RTL is not set # CONFIG_MACH_TX39XX is not set # CONFIG_MACH_TX49XX is not set # CONFIG_MACH_VR41XX is not set @@ -4588,12 +4594,14 @@ CONFIG_PCI_SYSCALL=y # CONFIG_PHY_EXYNOS_DP_VIDEO is not set # CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set # CONFIG_PHY_FSL_IMX8MQ_USB is not set +# CONFIG_PHY_INGENIC_USB is not set # CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set # CONFIG_PHY_MAPPHONE_MDM6600 is not set # CONFIG_PHY_MIXEL_MIPI_DPHY is not set # CONFIG_PHY_MTK_HDMI is not set # CONFIG_PHY_MTK_MIPI_DSI is not set # CONFIG_PHY_OCELOT_SERDES is not set +# CONFIG_PHY_PISTACHIO_USB is not set # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_PHY_QCOM_DWC3 is not set From 26e7c2275730486a5a1201fbafe72ccdac15f6e4 Mon Sep 17 00:00:00 2001 From: Aleksander Jan Bajkowski Date: Sun, 27 Mar 2022 11:53:09 +0200 Subject: [PATCH 11/23] kernel: sort generic configuration This was done by executing these commands: $ ./scripts/kconfig.pl '+' target/linux/generic/config-5.10 /dev/null > target/linux/generic/config-5.10-new $ mv target/linux/generic/config-5.10-new target/linux/generic/config-5.10 $ ./scripts/kconfig.pl '+' target/linux/generic/config-5.15 /dev/null > target/linux/generic/config-5.15-new $ mv target/linux/generic/config-5.15-new target/linux/generic/config-5.15 Signed-off-by: Aleksander Jan Bajkowski Signed-off-by: Daniel Golle --- target/linux/generic/config-5.10 | 4 +-- target/linux/generic/config-5.15 | 55 +++++++++++++++----------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 index a093861b9d..a46fe13e64 100644 --- a/target/linux/generic/config-5.10 +++ b/target/linux/generic/config-5.10 @@ -2168,6 +2168,7 @@ CONFIG_GPIO_SYSFS=y CONFIG_HARDENED_USERCOPY=y # CONFIG_HARDENED_USERCOPY_FALLBACK is not set # CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_HARDEN_BRANCH_HISTORY=y CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_HAVE_ARM_ARCH_TIMER is not set @@ -3389,8 +3390,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MICROCHIP_T1_PHY is not set # CONFIG_MICROSEMI_PHY is not set # CONFIG_MIGRATION is not set -CONFIG_HARDEN_BRANCH_HISTORY=y -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y CONFIG_MII=y # CONFIG_MIKROTIK is not set # CONFIG_MIKROTIK_RB532 is not set @@ -3421,6 +3420,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MISDN_NETJET is not set # CONFIG_MISDN_SPEEDFAX is not set # CONFIG_MISDN_W6692 is not set +CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y # CONFIG_MKISS is not set # CONFIG_MLX4_CORE is not set # CONFIG_MLX4_EN is not set diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index b217738cb4..274bc920f6 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -50,9 +50,9 @@ CONFIG_64BIT_TIME=y # CONFIG_AD5758 is not set # CONFIG_AD5761 is not set # CONFIG_AD5764 is not set +# CONFIG_AD5766 is not set # CONFIG_AD5770R is not set # CONFIG_AD5791 is not set -# CONFIG_AD5766 is not set # CONFIG_AD5933 is not set # CONFIG_AD7091R5 is not set # CONFIG_AD7124 is not set @@ -909,13 +909,13 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y # CONFIG_CIFS_DEBUG is not set # CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_SWN_UPCALL is not set # CONFIG_CIFS_FSCACHE is not set # CONFIG_CIFS_NFSD_EXPORT is not set CONFIG_CIFS_POSIX=y # CONFIG_CIFS_SMB2 is not set # CONFIG_CIFS_STATS is not set # CONFIG_CIFS_STATS2 is not set +# CONFIG_CIFS_SWN_UPCALL is not set # CONFIG_CIFS_WEAK_PW_HASH is not set CONFIG_CIFS_XATTR=y # CONFIG_CIO_DAC is not set @@ -1072,7 +1072,9 @@ CONFIG_CRYPTO_ALGAPI2=y # CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_BLAKE2B is not set +# CONFIG_CRYPTO_BLAKE2B_NEON is not set # CONFIG_CRYPTO_BLAKE2S is not set +# CONFIG_CRYPTO_BLAKE2S_ARM is not set # CONFIG_CRYPTO_BLAKE2S_X86 is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_CAMELLIA is not set @@ -1229,8 +1231,6 @@ CONFIG_CRYPTO_PCRYPT=y # CONFIG_CRYPTO_SHA512_ARM is not set # CONFIG_CRYPTO_SHA512_ARM64 is not set # CONFIG_CRYPTO_SHA512_ARM64_CE is not set -# CONFIG_CRYPTO_BLAKE2S_ARM is not set -# CONFIG_CRYPTO_BLAKE2B_NEON is not set # CONFIG_CRYPTO_SIMD is not set CONFIG_CRYPTO_SKCIPHER=y CONFIG_CRYPTO_SKCIPHER2=y @@ -1616,8 +1616,8 @@ CONFIG_DQL=y # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set # CONFIG_DRM_SIL_SII8620 is not set -# CONFIG_DRM_SIMPLE_BRIDGE is not set # CONFIG_DRM_SIMPLEDRM is not set +# CONFIG_DRM_SIMPLE_BRIDGE is not set # CONFIG_DRM_STI is not set # CONFIG_DRM_STM is not set # CONFIG_DRM_SUN4I is not set @@ -1888,11 +1888,11 @@ CONFIG_EXTRA_TARGETS="" # CONFIG_F2FS_FAULT_INJECTION is not set # CONFIG_F2FS_FS is not set # CONFIG_F2FS_FS_COMPRESSION is not set -# CONFIG_F2FS_IOSTAT is not set # CONFIG_F2FS_FS_ENCRYPTION is not set # CONFIG_F2FS_FS_POSIX_ACL is not set # CONFIG_F2FS_FS_SECURITY is not set CONFIG_F2FS_FS_XATTR=y +# CONFIG_F2FS_IOSTAT is not set # CONFIG_F2FS_IO_TRACE is not set CONFIG_F2FS_STAT_FS=y # CONFIG_FAILOVER is not set @@ -2226,6 +2226,7 @@ CONFIG_GPIO_SYSFS=y CONFIG_HARDENED_USERCOPY=y # CONFIG_HARDENED_USERCOPY_FALLBACK is not set # CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_HARDEN_BRANCH_HISTORY=y CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_HAVE_ARM_ARCH_TIMER is not set @@ -2279,7 +2280,6 @@ CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set # CONFIG_HID_EMS_FF is not set -# CONFIG_IP_VS_TWOS is not set # CONFIG_HID_EZKEY is not set # CONFIG_HID_FT260 is not set # CONFIG_HID_GEMBIRD is not set @@ -3482,8 +3482,6 @@ CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_MICROCHIP_T1_PHY is not set # CONFIG_MICROSEMI_PHY is not set # CONFIG_MIGRATION is not set -CONFIG_HARDEN_BRANCH_HISTORY=y -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y CONFIG_MII=y # CONFIG_MIKROTIK is not set # CONFIG_MIKROTIK_RB532 is not set @@ -3514,6 +3512,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_MISDN_NETJET is not set # CONFIG_MISDN_SPEEDFAX is not set # CONFIG_MISDN_W6692 is not set +CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y # CONFIG_MKISS is not set # CONFIG_MLX4_CORE is not set # CONFIG_MLX4_EN is not set @@ -3699,6 +3698,7 @@ CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 # CONFIG_MTD_NAND_ECC_BCH is not set # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_ECC_SW_BCH is not set +# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set # CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set # CONFIG_MTD_NAND_FSL_ELBC is not set # CONFIG_MTD_NAND_FSL_IFC is not set @@ -3801,8 +3801,6 @@ CONFIG_MTD_SPLIT_SUPPORT=y # CONFIG_MTD_UBI_GLUEBI is not set # CONFIG_MTD_UIMAGE_SPLIT is not set # CONFIG_MTD_VIRT_CONCAT is not set -# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set -# CONFIG_MTD_NAND_MTK_BMT is not set # CONFIG_MTK_DEVAPC is not set # CONFIG_MTK_MMC is not set # CONFIG_MTK_MMSYS is not set @@ -3841,9 +3839,9 @@ CONFIG_NETDEVICES=y # CONFIG_NETFILTER_DEBUG is not set # CONFIG_NETFILTER_INGRESS is not set # CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_NETLINK_HOOK is not set # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_GLUE_CT is not set +# CONFIG_NETFILTER_NETLINK_HOOK is not set # CONFIG_NETFILTER_NETLINK_LOG is not set # CONFIG_NETFILTER_NETLINK_OSF is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set @@ -4194,10 +4192,10 @@ CONFIG_NFS_V3=y # CONFIG_NFT_FIB_IPV4 is not set # CONFIG_NFT_FIB_IPV6 is not set # CONFIG_NFT_FIB_NETDEV is not set -# CONFIG_NFT_REJECT_NETDEV is not set # CONFIG_NFT_FLOW_OFFLOAD is not set # CONFIG_NFT_OBJREF is not set # CONFIG_NFT_OSF is not set +# CONFIG_NFT_REJECT_NETDEV is not set # CONFIG_NFT_RT is not set # CONFIG_NFT_SET_BITMAP is not set # CONFIG_NFT_SOCKET is not set @@ -4344,10 +4342,10 @@ CONFIG_NMI_LOG_BUF_SHIFT=13 # CONFIG_NO_HZ_IDLE is not set # CONFIG_NS83820 is not set # CONFIG_NTB is not set -# CONFIG_NTFS3_FS is not set # CONFIG_NTFS3_64BIT_CLUSTER is not set -# CONFIG_NTFS3_LZX_XPRESS is not set +# CONFIG_NTFS3_FS is not set # CONFIG_NTFS3_FS_POSIX_ACL is not set +# CONFIG_NTFS3_LZX_XPRESS is not set # CONFIG_NTFS_DEBUG is not set # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set @@ -4680,8 +4678,8 @@ CONFIG_POSIX_TIMERS=y # CONFIG_POWER_RESET_LINKSTATION is not set # CONFIG_POWER_RESET_LTC2952 is not set # CONFIG_POWER_RESET_PIIX4_POWEROFF is not set -# CONFIG_POWER_RESET_REGULATOR is not set # CONFIG_POWER_RESET_QNAP is not set +# CONFIG_POWER_RESET_REGULATOR is not set # CONFIG_POWER_RESET_RESTART is not set # CONFIG_POWER_RESET_SYSCON is not set # CONFIG_POWER_RESET_SYSCON_POWEROFF is not set @@ -4756,7 +4754,6 @@ CONFIG_PROC_SYSCTL=y # CONFIG_PSTORE_842_COMPRESS is not set # CONFIG_PSTORE_BLK is not set # CONFIG_PSTORE_COMPRESS is not set -# CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" # CONFIG_PSTORE_CONSOLE is not set CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 # CONFIG_PSTORE_DEFLATE_COMPRESS is not set @@ -5468,9 +5465,9 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_POWR1220 is not set # CONFIG_SENSORS_PWM_FAN is not set # CONFIG_SENSORS_PXE1610 is not set +# CONFIG_SENSORS_Q54SJ108A2 is not set # CONFIG_SENSORS_RM3100_I2C is not set # CONFIG_SENSORS_RM3100_SPI is not set -# CONFIG_SENSORS_Q54SJ108A2 is not set # CONFIG_SENSORS_SBRMI is not set # CONFIG_SENSORS_SBTSI is not set # CONFIG_SENSORS_SCH5627 is not set @@ -6019,12 +6016,12 @@ CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y # CONFIG_SND_SOC_TLV320ADCX140 is not set # CONFIG_SND_SOC_TLV320AIC23_I2C is not set # CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set -# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set # CONFIG_SND_SOC_TLV320AIC31XX is not set # CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set # CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set # CONFIG_SND_SOC_TLV320AIC3X is not set +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set # CONFIG_SND_SOC_TPA6130A2 is not set # CONFIG_SND_SOC_TS3A227E is not set # CONFIG_SND_SOC_TSCS42XX is not set @@ -6175,6 +6172,8 @@ CONFIG_SND_X86=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_SPMI is not set # CONFIG_SPS30 is not set +# CONFIG_SPS30_I2C is not set +# CONFIG_SPS30_SERIAL is not set CONFIG_SQUASHFS=y # CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set # CONFIG_SQUASHFS_DECOMP_MULTI is not set @@ -6201,8 +6200,6 @@ CONFIG_SQUASHFS_XZ=y CONFIG_SSB_POSSIBLE=y # CONFIG_SSB_SDIOHOST is not set # CONFIG_SSB_SILENT is not set -# CONFIG_SPS30_I2C is not set -# CONFIG_SPS30_SERIAL is not set # CONFIG_SSFDC is not set # CONFIG_STACKPROTECTOR is not set # CONFIG_STACKPROTECTOR_STRONG is not set @@ -6302,10 +6299,10 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_TCG_ST33_I2C is not set # CONFIG_TCG_TIS is not set # CONFIG_TCG_TIS_I2C_ATMEL is not set +# CONFIG_TCG_TIS_I2C_CR50 is not set # CONFIG_TCG_TIS_I2C_INFINEON is not set # CONFIG_TCG_TIS_I2C_NUVOTON is not set # CONFIG_TCG_TIS_SPI is not set -# CONFIG_TCG_TIS_I2C_CR50 is not set # CONFIG_TCG_TIS_ST33ZP24_I2C is not set # CONFIG_TCG_TIS_ST33ZP24_SPI is not set # CONFIG_TCG_TPM is not set @@ -6518,10 +6515,10 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TOUCHSCREEN_MC13783 is not set # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set -# CONFIG_TOUCHSCREEN_MSG2638 is not set # CONFIG_TOUCHSCREEN_MIGOR is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MSG2638 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_MX25 is not set # CONFIG_TOUCHSCREEN_MXS_LRADC is not set @@ -6868,7 +6865,6 @@ CONFIG_USB_GADGET_VBUS_DRAW=2 # CONFIG_USB_NET2272 is not set # CONFIG_USB_NET2280 is not set # CONFIG_USB_NET_AQC111 is not set -# CONFIG_USB_RTL8153_ECM is not set # CONFIG_USB_NET_AX88179_178A is not set # CONFIG_USB_NET_AX8817X is not set # CONFIG_USB_NET_CDCETHER is not set @@ -6925,6 +6921,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_ROLE_SWITCH is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_RTL8152 is not set +# CONFIG_USB_RTL8153_ECM is not set # CONFIG_USB_S2255 is not set # CONFIG_USB_SERIAL is not set # CONFIG_USB_SERIAL_AIRCABLE is not set @@ -7172,9 +7169,9 @@ CONFIG_VHOST_MENU=y # CONFIG_VIDEO_OV2685 is not set # CONFIG_VIDEO_OV2740 is not set # CONFIG_VIDEO_OV5640 is not set -# CONFIG_VIDEO_OV5648 is not set # CONFIG_VIDEO_OV5645 is not set # CONFIG_VIDEO_OV5647 is not set +# CONFIG_VIDEO_OV5648 is not set # CONFIG_VIDEO_OV5670 is not set # CONFIG_VIDEO_OV5675 is not set # CONFIG_VIDEO_OV5695 is not set @@ -7438,10 +7435,10 @@ CONFIG_ZONE_DMA=y # CONFIG_ZPA2326 is not set # CONFIG_ZPOOL is not set # CONFIG_ZRAM is not set -# CONFIG_ZRAM_MEMORY_TRACKING is not set -# CONFIG_ZRAM_DEF_COMP_LZORLE is not set -# CONFIG_ZRAM_DEF_COMP_ZSTD is not set # CONFIG_ZRAM_DEF_COMP_LZ4 is not set # CONFIG_ZRAM_DEF_COMP_LZO is not set +# CONFIG_ZRAM_DEF_COMP_LZORLE is not set +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set +# CONFIG_ZRAM_MEMORY_TRACKING is not set # CONFIG_ZSMALLOC is not set # CONFIG_ZX_TDM is not set From 3064e76c948570a6f0930e893d25a551449df8ff Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Thu, 4 Nov 2021 21:56:41 +0100 Subject: [PATCH 12/23] ipq806x: 5:15: copy config and patch from 5.10 Copy config and patch from kernel 5.10 to kernel 5.15 Signed-off-by: Ansuel Smith --- target/linux/ipq806x/config-5.15 | 506 +++++++++ ...ings-qcom_adm-Fix-channel-specifiers.patch | 71 ++ ...ically-select-PCI_DOMAINS-if-PCI-is-.patch | 29 + ...arch-arm-force-ZRELADDR-on-arch-qcom.patch | 62 ++ .../0065-arm-override-compiler-flags.patch | 21 + ...Mangle-bootloader-s-kernel-arguments.patch | 210 ++++ .../0069-arm-boot-add-dts-files.patch | 42 + .../0072-add-ipq806x-with-no-clocks.patch | 10 + .../082-ipq8064-dtsi-tweaks.patch | 220 ++++ .../083-ipq8064-dtsi-additions.patch | 846 +++++++++++++++ .../084-ipq8064-v1.0-dtsi-cleanup.patch | 89 ++ .../085-ipq8064-v1.0-dtsi-additions.patch | 14 + .../086-ipq8064-fix-duplicate-node.patch | 145 +++ ...qcom-cpufreq-nvmem-support-specific-.patch | 51 + ...7-1-ipq806x-gcc-add-missing-clk-flag.patch | 99 ++ .../097-2-ipq806x-lcc-add-missing-reset.patch | 59 ++ ...com-krait-add-missing-enable-disable.patch | 57 ++ ...missing-clk-and-reset-for-crypto-eng.patch | 372 +++++++ ...q-add-Krait-dedicated-scaling-driver.patch | 681 ++++++++++++ ...ufreq-add-qcom-krait-cpufreq-binding.patch | 237 +++++ ...add-fab-scaling-support-with-cpufreq.patch | 243 +++++ ...m_nandc-add-boot_layout_mode-support.patch | 239 +++++ ...vicetree-mtd-qcom_nandc-document-qco.patch | 42 + ...-v5.11-dmaengine-qcom-add_ADM_driver.patch | 965 ++++++++++++++++++ ....12-mtd-parsers-Add-Qcom-SMEM-parser.patch | 217 ++++ ...-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch | 83 ++ ...conflicts-with-OpenWrt-auto-mounting.patch | 24 + ...M-dts-qcom-reduce-pci-IO-size-to-64K.patch | 46 + ...hermal-tsens-Add-VER_0-tsens-version.patch | 285 ++++++ ...al-tsens-Don-t-hardcode-sensor-slope.patch | 28 + ...l-tsens-Convert-msm8960-to-reg_field.patch | 119 +++ ...al-tsens-Use-init_common-for-msm8960.patch | 81 ++ ...tsens-Fix-bug-in-sensor-enable-for-m.patch | 66 ++ ...tsens-Replace-custom-8960-apis-with-.patch | 109 ++ ...tsens-Drop-unused-define-for-msm8960.patch | 65 ++ ...-tsens-Add-support-for-ipq8064-tsens.patch | 26 + ...rmal-tsens-Document-ipq8064-bindings.patch | 112 ++ ...al-tsens-Fix-wrong-slope-on-msm-8960.patch | 32 + ...ns-init-debugfs-only-with-successful.patch | 41 + ...tsens-simplify-debugfs-init-function.patch | 54 + ...c-explicitly-deassert-gmac-ahb-reset.patch | 75 ++ ...s-qcom-add-ahb-reset-to-ipq806x-gmac.patch | 64 ++ .../850-soc-add-qualcomm-syscon.patch | 121 +++ .../900-arm-add-cmdline-override.patch | 37 + 44 files changed, 6995 insertions(+) create mode 100644 target/linux/ipq806x/config-5.15 create mode 100644 target/linux/ipq806x/patches-5.15/0001-dtbindings-qcom_adm-Fix-channel-specifiers.patch create mode 100644 target/linux/ipq806x/patches-5.15/0033-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch create mode 100644 target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch create mode 100644 target/linux/ipq806x/patches-5.15/0065-arm-override-compiler-flags.patch create mode 100644 target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch create mode 100644 target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch create mode 100644 target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch create mode 100644 target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch create mode 100644 target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch create mode 100644 target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch create mode 100644 target/linux/ipq806x/patches-5.15/085-ipq8064-v1.0-dtsi-additions.patch create mode 100644 target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch create mode 100644 target/linux/ipq806x/patches-5.15/093-drivers-cpufreq-qcom-cpufreq-nvmem-support-specific-.patch create mode 100644 target/linux/ipq806x/patches-5.15/097-1-ipq806x-gcc-add-missing-clk-flag.patch create mode 100644 target/linux/ipq806x/patches-5.15/097-2-ipq806x-lcc-add-missing-reset.patch create mode 100644 target/linux/ipq806x/patches-5.15/097-3-clk-qcom-krait-add-missing-enable-disable.patch create mode 100644 target/linux/ipq806x/patches-5.15/097-4-ipq806x-gcc-add-missing-clk-and-reset-for-crypto-eng.patch create mode 100644 target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch create mode 100644 target/linux/ipq806x/patches-5.15/098-2-Documentation-cpufreq-add-qcom-krait-cpufreq-binding.patch create mode 100644 target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch create mode 100644 target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch create mode 100644 target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch create mode 100644 target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch create mode 100644 target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch create mode 100644 target/linux/ipq806x/patches-5.15/101-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch create mode 100644 target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch create mode 100644 target/linux/ipq806x/patches-5.15/103-ARM-dts-qcom-reduce-pci-IO-size-to-64K.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch create mode 100644 target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch create mode 100644 target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch create mode 100644 target/linux/ipq806x/patches-5.15/107-1-thermal-qcom-tsens-init-debugfs-only-with-successful.patch create mode 100644 target/linux/ipq806x/patches-5.15/107-2-thermal-qcom-tsens-simplify-debugfs-init-function.patch create mode 100644 target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch create mode 100644 target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch create mode 100644 target/linux/ipq806x/patches-5.15/850-soc-add-qualcomm-syscon.patch create mode 100644 target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch diff --git a/target/linux/ipq806x/config-5.15 b/target/linux/ipq806x/config-5.15 new file mode 100644 index 0000000000..f2880b5d66 --- /dev/null +++ b/target/linux/ipq806x/config-5.15 @@ -0,0 +1,506 @@ +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_APQ_GCC_8084 is not set +# CONFIG_APQ_MMCC_8084 is not set +CONFIG_AR8216_PHY=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +# CONFIG_ARCH_IPQ40XX is not set +CONFIG_ARCH_KEEP_MEMBLOCK=y +# CONFIG_ARCH_MDM9615 is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MSM8960=y +CONFIG_ARCH_MSM8974=y +CONFIG_ARCH_MSM8X60=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ARCH_TIMER=y +CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_ARM_CPU_SUSPEND=y +# CONFIG_ARM_CPU_TOPOLOGY is not set +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_MODULE_PLTS=y +CONFIG_ARM_PATCH_IDIV=y +CONFIG_ARM_PATCH_PHYS_VIRT=y +# CONFIG_ARM_QCOM_CPUFREQ_HW is not set +CONFIG_ARM_QCOM_CPUFREQ_KRAIT=y +CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y +CONFIG_ARM_QCOM_SPM_CPUIDLE=y +# CONFIG_ARM_SMMU is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_AT803X_PHY=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BOUNCE=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_QCOM=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE_OVERRIDE=y +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_QCOM=y +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_PM=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SPECTRE=y +CONFIG_CPU_THERMAL=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +# CONFIG_CRC32_SARWATE is not set +CONFIG_CRC32_SLICEBY8=y +CONFIG_CRYPTO_ACOMP2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DEV_QCOM_RNG=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_GPIO=y +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEVFREQ_GOV_PASSIVE is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set +# CONFIG_DEVFREQ_GOV_USERSPACE is not set +# CONFIG_DEVFREQ_THERMAL is not set +CONFIG_DMADEVICES=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_VIRTUAL_CHANNELS=y +CONFIG_DTC=y +CONFIG_DT_IDLE_STATES=y +# CONFIG_DWMAC_GENERIC is not set +CONFIG_DWMAC_IPQ806X=y +# CONFIG_DWMAC_QCOM_ETHQOS is not set +CONFIG_DYNAMIC_DEBUG=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_ETHERNET_PACKET_MANGLE=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_MSI_IRQ=y +CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_HWMON=y +CONFIG_HWSPINLOCK=y +CONFIG_HWSPINLOCK_QCOM=y +CONFIG_HW_RANDOM=y +CONFIG_HZ=100 +CONFIG_HZ_100=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_I2C_QCOM_CCI is not set +CONFIG_I2C_QUP=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_IOMMU_DEBUGFS is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +CONFIG_IOMMU_SUPPORT=y +# CONFIG_IPQ_APSS_PLL is not set +# CONFIG_IPQ_GCC_4019 is not set +# CONFIG_IPQ_GCC_6018 is not set +CONFIG_IPQ_GCC_806X=y +# CONFIG_IPQ_GCC_8074 is not set +# CONFIG_IPQ_LCC_806X is not set +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_KPSS_XCC=y +CONFIG_KRAITCC=y +CONFIG_KRAIT_CLOCKS=y +CONFIG_KRAIT_L2_ACCESSORS=y +CONFIG_LIBFDT=y +CONFIG_LLD_VERSION=0 +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MDIO_BITBANG=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_GPIO=y +CONFIG_MDIO_IPQ8064=y +# CONFIG_MDM_GCC_9615 is not set +# CONFIG_MDM_LCC_9615 is not set +CONFIG_MEMFD_CREATE=y +# CONFIG_MFD_HI6421_SPMI is not set +CONFIG_MFD_QCOM_RPM=y +# CONFIG_MFD_SPMI_PMIC is not set +CONFIG_MFD_SYSCON=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_CQHCI=y +CONFIG_MMC_QCOM_DML=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +CONFIG_MMC_SDHCI_MSM=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MSM_GCC_8660=y +# CONFIG_MSM_GCC_8916 is not set +# CONFIG_MSM_GCC_8939 is not set +# CONFIG_MSM_GCC_8960 is not set +# CONFIG_MSM_GCC_8974 is not set +# CONFIG_MSM_GCC_8994 is not set +# CONFIG_MSM_GCC_8996 is not set +# CONFIG_MSM_GCC_8998 is not set +# CONFIG_MSM_GPUCC_8998 is not set +# CONFIG_MSM_IOMMU is not set +# CONFIG_MSM_LCC_8960 is not set +# CONFIG_MSM_MMCC_8960 is not set +# CONFIG_MSM_MMCC_8974 is not set +# CONFIG_MSM_MMCC_8996 is not set +# CONFIG_MSM_MMCC_8998 is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_QCOM=y +CONFIG_MTD_QCOMSMEM_PARTS=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPLIT_FIRMWARE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEON=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_QCA8K=y +CONFIG_NET_DSA_TAG_QCA=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NLS=y +CONFIG_NO_HZ=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=2 +CONFIG_NVMEM=y +# CONFIG_NVMEM_SPMI_SDAM is not set +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_OF_NET=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PADATA=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PAGE_POOL=y +CONFIG_PCI=y +CONFIG_PCIEAER=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIE_DW=y +CONFIG_PCIE_DW_HOST=y +CONFIG_PCIE_QCOM=y +CONFIG_PCI_DEBUG=y +CONFIG_PCI_DISABLE_COMMON_QUIRKS=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MSI_IRQ_DOMAIN=y +CONFIG_PCS_XPCS=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +# CONFIG_PHY_QCOM_APQ8064_SATA is not set +# CONFIG_PHY_QCOM_IPQ4019_USB is not set +CONFIG_PHY_QCOM_IPQ806X_SATA=y +# CONFIG_PHY_QCOM_IPQ806X_USB is not set +# CONFIG_PHY_QCOM_PCIE2 is not set +# CONFIG_PHY_QCOM_QMP is not set +# CONFIG_PHY_QCOM_QUSB2 is not set +# CONFIG_PHY_QCOM_USB_HS_28NM is not set +# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set +# CONFIG_PHY_QCOM_USB_SS is not set +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_APQ8064 is not set +# CONFIG_PINCTRL_APQ8084 is not set +# CONFIG_PINCTRL_IPQ4019 is not set +# CONFIG_PINCTRL_IPQ6018 is not set +CONFIG_PINCTRL_IPQ8064=y +# CONFIG_PINCTRL_IPQ8074 is not set +# CONFIG_PINCTRL_MDM9615 is not set +CONFIG_PINCTRL_MSM=y +# CONFIG_PINCTRL_MSM8226 is not set +# CONFIG_PINCTRL_MSM8660 is not set +# CONFIG_PINCTRL_MSM8916 is not set +# CONFIG_PINCTRL_MSM8960 is not set +# CONFIG_PINCTRL_MSM8976 is not set +# CONFIG_PINCTRL_MSM8994 is not set +# CONFIG_PINCTRL_MSM8996 is not set +# CONFIG_PINCTRL_MSM8998 is not set +# CONFIG_PINCTRL_QCOM_SPMI_PMIC is not set +# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set +# CONFIG_PINCTRL_QCS404 is not set +# CONFIG_PINCTRL_SC7180 is not set +# CONFIG_PINCTRL_SDM660 is not set +# CONFIG_PINCTRL_SDM845 is not set +# CONFIG_PINCTRL_SM8150 is not set +# CONFIG_PINCTRL_SM8250 is not set +CONFIG_PM_DEVFREQ=y +# CONFIG_PM_DEVFREQ_EVENT is not set +CONFIG_PM_OPP=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_MSM=y +CONFIG_POWER_SUPPLY=y +CONFIG_PPS=y +CONFIG_PRINTK_TIME=y +CONFIG_PTP_1588_CLOCK=y +# CONFIG_QCOM_A53PLL is not set +CONFIG_QCOM_ADM=y +CONFIG_QCOM_BAM_DMA=y +CONFIG_QCOM_CLK_RPM=y +# CONFIG_QCOM_COMMAND_DB is not set +# CONFIG_QCOM_CPR is not set +# CONFIG_QCOM_EBI2 is not set +# CONFIG_QCOM_GENI_SE is not set +CONFIG_QCOM_GSBI=y +CONFIG_QCOM_HFPLL=y +# CONFIG_QCOM_IOMMU is not set +# CONFIG_QCOM_LLCC is not set +# CONFIG_QCOM_OCMEM is not set +# CONFIG_QCOM_PDC is not set +CONFIG_QCOM_QFPROM=y +# CONFIG_QCOM_RMTFS_MEM is not set +CONFIG_QCOM_RPMCC=y +# CONFIG_QCOM_RPMH is not set +CONFIG_QCOM_SCM=y +# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set +CONFIG_QCOM_SMEM=y +# CONFIG_QCOM_SMSM is not set +# CONFIG_QCOM_SOCINFO is not set +CONFIG_QCOM_TCSR=y +CONFIG_QCOM_TSENS=y +CONFIG_QCOM_WDT=y +# CONFIG_QCS_GCC_404 is not set +# CONFIG_QCS_Q6SSTOP_404 is not set +# CONFIG_QCS_TURING_404 is not set +CONFIG_RAS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_QCOM_LABIBB is not set +CONFIG_REGULATOR_QCOM_RPM=y +# CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +# CONFIG_REGULATOR_VQMMC_IPQ4019 is not set +CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_QCOM_AOSS is not set +# CONFIG_RESET_QCOM_PDC is not set +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +# CONFIG_SC_DISPCC_7180 is not set +# CONFIG_SC_GCC_7180 is not set +# CONFIG_SC_GPUCC_7180 is not set +# CONFIG_SC_LPASS_CORECC_7180 is not set +# CONFIG_SC_MSS_7180 is not set +# CONFIG_SC_VIDEOCC_7180 is not set +# CONFIG_SDM_CAMCC_845 is not set +# CONFIG_SDM_DISPCC_845 is not set +# CONFIG_SDM_GCC_660 is not set +# CONFIG_SDM_GCC_845 is not set +# CONFIG_SDM_GPUCC_845 is not set +# CONFIG_SDM_LPASSCC_845 is not set +# CONFIG_SDM_VIDEOCC_845 is not set +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +# CONFIG_SM_GCC_8150 is not set +# CONFIG_SM_GCC_8250 is not set +# CONFIG_SM_GPUCC_8150 is not set +# CONFIG_SM_GPUCC_8250 is not set +# CONFIG_SM_VIDEOCC_8150 is not set +# CONFIG_SM_VIDEOCC_8250 is not set +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_QUP=y +CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +CONFIG_SPMI_MSM_PMIC_ARB=y +# CONFIG_SPMI_PMIC_CLKDIV is not set +CONFIG_SRCU=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +# CONFIG_STMMAC_SELFTESTS is not set +CONFIG_SWCONFIG=y +CONFIG_SWCONFIG_LEDS=y +CONFIG_SWPHY=y +CONFIG_SWP_EMULATE=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_THERMAL=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_OF=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y +# CONFIG_UCLAMP_TASK is not set +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNWINDER_ARM=y +CONFIG_USB=y +CONFIG_USB_COMMON=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_WATCHDOG_CORE=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_BCJ=y +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/ipq806x/patches-5.15/0001-dtbindings-qcom_adm-Fix-channel-specifiers.patch b/target/linux/ipq806x/patches-5.15/0001-dtbindings-qcom_adm-Fix-channel-specifiers.patch new file mode 100644 index 0000000000..83d7bbc6f4 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0001-dtbindings-qcom_adm-Fix-channel-specifiers.patch @@ -0,0 +1,71 @@ +From 28d0ed88f536dd639adf1b0c7c08e04be3c8f294 Mon Sep 17 00:00:00 2001 +From: Thomas Pedersen +Date: Mon, 16 May 2016 17:58:50 -0700 +Subject: [PATCH 01/69] dtbindings: qcom_adm: Fix channel specifiers + +Original patch from Andy Gross. + +This patch removes the crci information from the dma +channel property. At least one client device requires +using more than one CRCI value for a channel. This does +not match the current binding and the crci information +needs to be removed. + +Instead, the client device will provide this information +via other means. + +Signed-off-by: Andy Gross +Signed-off-by: Thomas Pedersen +--- + Documentation/devicetree/bindings/dma/qcom_adm.txt | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +--- a/Documentation/devicetree/bindings/dma/qcom_adm.txt ++++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt +@@ -4,8 +4,7 @@ Required properties: + - compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960 + - reg: Address range for DMA registers + - interrupts: Should contain one interrupt shared by all channels +-- #dma-cells: must be <2>. First cell denotes the channel number. Second cell +- denotes CRCI (client rate control interface) flow control assignment. ++- #dma-cells: must be <1>. First cell denotes the channel number. + - clocks: Should contain the core clock and interface clock. + - clock-names: Must contain "core" for the core clock and "iface" for the + interface clock. +@@ -22,7 +21,7 @@ Example: + compatible = "qcom,adm"; + reg = <0x18300000 0x100000>; + interrupts = <0 170 0>; +- #dma-cells = <2>; ++ #dma-cells = <1>; + + clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>; + clock-names = "core", "iface"; +@@ -35,15 +34,12 @@ Example: + qcom,ee = <0>; + }; + +-DMA clients must use the format descripted in the dma.txt file, using a three ++DMA clients must use the format descripted in the dma.txt file, using a two + cell specifier for each channel. + +-Each dmas request consists of 3 cells: ++Each dmas request consists of two cells: + 1. phandle pointing to the DMA controller + 2. channel number +- 3. CRCI assignment, if applicable. If no CRCI flow control is required, use 0. +- The CRCI is used for flow control. It identifies the peripheral device that +- is the source/destination for the transferred data. + + Example: + +@@ -55,7 +51,7 @@ Example: + + cs-gpios = <&qcom_pinmux 20 0>; + +- dmas = <&adm_dma 6 9>, +- <&adm_dma 5 10>; ++ dmas = <&adm_dma 6>, ++ <&adm_dma 5>; + dma-names = "rx", "tx"; + }; diff --git a/target/linux/ipq806x/patches-5.15/0033-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch b/target/linux/ipq806x/patches-5.15/0033-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch new file mode 100644 index 0000000000..a12aa721e2 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0033-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch @@ -0,0 +1,29 @@ +From 48051ece78136e4235a2415a52797db56f8a4478 Mon Sep 17 00:00:00 2001 +From: Mathieu Olivari +Date: Tue, 21 Apr 2015 19:09:07 -0700 +Subject: [PATCH 33/69] ARM: qcom: automatically select PCI_DOMAINS if PCI is + enabled + +If multiple PCIe devices are present in the system, the kernel will +panic at boot time when trying to scan the PCI buses. This happens on +IPQ806x based platforms, which has 3 PCIe ports. + +Enabling this option allows the kernel to assign the pci-domains +according to the device-tree content. This allows multiple PCIe +controllers to coexist in the system. + +Signed-off-by: Mathieu Olivari +--- + arch/arm/mach-qcom/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm/mach-qcom/Kconfig ++++ b/arch/arm/mach-qcom/Kconfig +@@ -7,6 +7,7 @@ menuconfig ARCH_QCOM + select ARM_AMBA + select PINCTRL + select QCOM_SCM if SMP ++ select PCI_DOMAINS if PCI + help + Support for Qualcomm's devicetree based systems. + diff --git a/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch b/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch new file mode 100644 index 0000000000..b73218e71b --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch @@ -0,0 +1,62 @@ +From fa71139b55e114aa8c3c4823ff8ee7d49ee810d4 Mon Sep 17 00:00:00 2001 +From: Mathieu Olivari +Date: Wed, 29 Apr 2015 15:21:46 -0700 +Subject: [PATCH 60/69] HACK: arch: arm: force ZRELADDR on arch-qcom + +ARCH_QCOM is using the ARCH_MULTIPLATFORM option, as now recommended +on most ARM architectures. This automatically calculate ZRELADDR by +masking PHYS_OFFSET with 0xf8000000. + +However, on IPQ806x, the first ~20MB of RAM is reserved for the hardware +network accelerators, and the bootloader removes this section from the +layout passed from the ATAGS (when used). + +For newer bootloader, when DT is used, this is not a problem, we just +reserve this memory in the device tree. But if the bootloader doesn't +have DT support, then ATAGS have to be used. In this case, the ARM +decompressor will position the kernel in this low mem, which will not be +in the RAM section mapped by the bootloader, which means the kernel will +freeze in the middle of the boot process trying to map the memory. + +As a work around, this patch allows disabling AUTO_ZRELADDR when +ARCH_QCOM is selected. It makes the zImage usage possible on bootloaders +which don't support device-tree, which is the case on certain early +IPQ806x based designs. + +Signed-off-by: Mathieu Olivari +--- + arch/arm/Kconfig | 2 +- + arch/arm/Makefile | 2 ++ + arch/arm/mach-qcom/Makefile.boot | 1 + + 3 files changed, 4 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/mach-qcom/Makefile.boot + +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -322,7 +322,7 @@ config ARCH_MULTIPLATFORM + select ARCH_SELECT_MEMORY_MODEL + select ARM_HAS_SG_CHAIN + select ARM_PATCH_PHYS_VIRT +- select AUTO_ZRELADDR ++ select AUTO_ZRELADDR if !ARCH_QCOM + select TIMER_OF + select COMMON_CLK + select GENERIC_CLOCKEVENTS +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -251,9 +251,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac + else + MACHINE := + endif ++ifeq ($(CONFIG_ARCH_QCOM),) + ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y) + MACHINE := + endif ++endif + + machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) + platdirs := $(patsubst %,arch/arm/plat-%/,$(sort $(plat-y))) +--- /dev/null ++++ b/arch/arm/mach-qcom/Makefile.boot +@@ -0,0 +1 @@ ++zreladdr-y+= 0x42208000 diff --git a/target/linux/ipq806x/patches-5.15/0065-arm-override-compiler-flags.patch b/target/linux/ipq806x/patches-5.15/0065-arm-override-compiler-flags.patch new file mode 100644 index 0000000000..a1a0371fbc --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0065-arm-override-compiler-flags.patch @@ -0,0 +1,21 @@ +From 4d8e29642661397a339ac3485f212c6360445421 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 9 Mar 2017 09:33:32 +0100 +Subject: [PATCH 65/69] arm: override compiler flags + +Signed-off-by: John Crispin +--- + arch/arm/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -61,7 +61,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-i + # macro, but instead defines a whole series of macros which makes + # testing for a specific architecture or later rather impossible. + arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m +-arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -march=armv7-a ++arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -mcpu=cortex-a15 + arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 -march=armv6 + # Only override the compiler option if ARMv6. The ARMv6K extensions are + # always available in ARMv7 diff --git a/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch new file mode 100644 index 0000000000..8f669319ed --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch @@ -0,0 +1,210 @@ +From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001 +From: Adrian Panella +Date: Thu, 9 Mar 2017 09:37:17 +0100 +Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments + +The command-line arguments provided by the boot loader will be +appended to a new device tree property: bootloader-args. +If there is a property "append-rootblock" in DT under /chosen +and a root= option in bootloaders command line it will be parsed +and added to DT bootargs with the form: XX. +Only command line ATAG will be processed, the rest of the ATAGs +sent by bootloader will be ignored. +This is usefull in dual boot systems, to get the current root partition +without afecting the rest of the system. + +Signed-off-by: Adrian Panella +--- + arch/arm/Kconfig | 11 +++++ + arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++- + init/main.c | 16 ++++++++ + 3 files changed, 98 insertions(+), 1 deletion(-) + +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1781,6 +1781,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN + The command-line arguments provided by the boot loader will be + appended to the the device tree bootargs property. + ++config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE ++ bool "Append rootblock parsing bootloader's kernel arguments" ++ help ++ The command-line arguments provided by the boot loader will be ++ appended to a new device tree property: bootloader-args. ++ If there is a property "append-rootblock" in DT under /chosen ++ and a root= option in bootloaders command line it will be parsed ++ and added to DT bootargs with the form: XX. ++ Only command line ATAG will be processed, the rest of the ATAGs ++ sent by bootloader will be ignored. ++ + endchoice + + config CMDLINE +--- a/arch/arm/boot/compressed/atags_to_fdt.c ++++ b/arch/arm/boot/compressed/atags_to_fdt.c +@@ -5,6 +5,8 @@ + + #if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND) + #define do_extend_cmdline 1 ++#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) ++#define do_extend_cmdline 1 + #else + #define do_extend_cmdline 0 + #endif +@@ -69,6 +71,80 @@ static uint32_t get_cell_size(const void + return cell_size; + } + ++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) ++/** ++ * taken from arch/x86/boot/string.c ++ * local_strstr - Find the first substring in a %NUL terminated string ++ * @s1: The string to be searched ++ * @s2: The string to search for ++ */ ++static char *local_strstr(const char *s1, const char *s2) ++{ ++ size_t l1, l2; ++ ++ l2 = strlen(s2); ++ if (!l2) ++ return (char *)s1; ++ l1 = strlen(s1); ++ while (l1 >= l2) { ++ l1--; ++ if (!memcmp(s1, s2, l2)) ++ return (char *)s1; ++ s1++; ++ } ++ return NULL; ++} ++ ++static char *append_rootblock(char *dest, const char *str, int len, void *fdt) ++{ ++ char *ptr, *end, *tmp; ++ char *root="root="; ++ char *find_rootblock; ++ int i, l; ++ const char *rootblock; ++ ++ find_rootblock = getprop(fdt, "/chosen", "find-rootblock", &l); ++ if(!find_rootblock) ++ find_rootblock = root; ++ ++ //ARM doesn't have __HAVE_ARCH_STRSTR, so it was copied from x86 ++ ptr = local_strstr(str, find_rootblock); ++ ++ if(!ptr) ++ return dest; ++ ++ end = strchr(ptr, ' '); ++ end = end ? (end - 1) : (strchr(ptr, 0) - 1); ++ ++ // Some boards ubi.mtd=XX,ZZZZ, so let's check for '," too. ++ tmp = strchr(ptr, ','); ++ ++ if(tmp) ++ end = end < tmp ? end : tmp - 1; ++ ++ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX | ubi.mtd=XX,ZZZZ ) ++ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++); ++ ptr = end + 1; ++ ++ /* if append-rootblock property is set use it to append to command line */ ++ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l); ++ if(rootblock != NULL) { ++ if(*dest != ' ') { ++ *dest = ' '; ++ dest++; ++ len++; ++ } ++ if (len + l + i <= COMMAND_LINE_SIZE) { ++ memcpy(dest, rootblock, l); ++ dest += l - 1; ++ memcpy(dest, ptr, i); ++ dest += i; ++ } ++ } ++ return dest; ++} ++#endif ++ + static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) + { + char cmdline[COMMAND_LINE_SIZE]; +@@ -88,12 +164,21 @@ static void merge_fdt_bootargs(void *fdt + + /* and append the ATAG_CMDLINE */ + if (fdt_cmdline) { ++ ++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) ++ //save original bootloader args ++ //and append ubi.mtd with root partition number to current cmdline ++ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline); ++ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt); ++ ++#else + len = strlen(fdt_cmdline); + if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) { + *ptr++ = ' '; + memcpy(ptr, fdt_cmdline, len); + ptr += len; + } ++#endif + } + *ptr = '\0'; + +@@ -168,7 +253,9 @@ int atags_to_fdt(void *atag_list, void * + else + setprop_string(fdt, "/chosen", "bootargs", + atag->u.cmdline.cmdline); +- } else if (atag->hdr.tag == ATAG_MEM) { ++ } ++#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE ++ else if (atag->hdr.tag == ATAG_MEM) { + if (memcount >= sizeof(mem_reg_property)/4) + continue; + if (!atag->u.mem.size) +@@ -212,6 +299,10 @@ int atags_to_fdt(void *atag_list, void * + setprop(fdt, "/memory", "reg", mem_reg_property, + 4 * memcount * memsize); + } ++#else ++ ++ } ++#endif + + return fdt_pack(fdt); + } +--- a/init/main.c ++++ b/init/main.c +@@ -110,6 +110,10 @@ + + #include + ++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) ++#include ++#endif ++ + static int kernel_init(void *); + + extern void init_IRQ(void); +@@ -906,6 +910,18 @@ asmlinkage __visible void __init __no_sa + pr_notice("Kernel command line: %s\n", saved_command_line); + /* parameters may set static keys */ + jump_label_init(); ++ ++#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE) ++ //Show bootloader's original command line for reference ++ if(of_chosen) { ++ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL); ++ if(prop) ++ pr_notice("Bootloader command line (ignored): %s\n", prop); ++ else ++ pr_notice("Bootloader command line not present\n"); ++ } ++#endif ++ + parse_early_param(); + after_dashes = parse_args("Booting kernel", + static_command_line, __start___param, diff --git a/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch b/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch new file mode 100644 index 0000000000..49ff218040 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch @@ -0,0 +1,42 @@ +From 8f68331e14dff9a101f2d0e1d6bec84a031f27ee Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 9 Mar 2017 11:03:18 +0100 +Subject: [PATCH 69/69] arm: boot: add dts files + +Signed-off-by: John Crispin +--- + arch/arm/boot/dts/Makefile | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -907,8 +907,29 @@ dtb-$(CONFIG_ARCH_QCOM) += \ + qcom-ipq4019-ap.dk04.1-c3.dtb \ + qcom-ipq4019-ap.dk07.1-c1.dtb \ + qcom-ipq4019-ap.dk07.1-c2.dtb \ ++ qcom-ipq8062-wg2600hp3.dtb \ + qcom-ipq8064-ap148.dtb \ + qcom-ipq8064-rb3011.dtb \ ++ qcom-ipq8064-c2600.dtb \ ++ qcom-ipq8064-d7800.dtb \ ++ qcom-ipq8064-db149.dtb \ ++ qcom-ipq8064-ap161.dtb \ ++ qcom-ipq8064-ea7500-v1.dtb \ ++ qcom-ipq8064-ea8500.dtb \ ++ qcom-ipq8064-g10.dtb \ ++ qcom-ipq8064-r7500.dtb \ ++ qcom-ipq8064-r7500v2.dtb \ ++ qcom-ipq8064-unifi-ac-hd.dtb \ ++ qcom-ipq8064-wg2600hp.dtb \ ++ qcom-ipq8064-wpq864.dtb \ ++ qcom-ipq8064-wxr-2533dhp.dtb \ ++ qcom-ipq8065-nbg6817.dtb \ ++ qcom-ipq8065-r7800.dtb \ ++ qcom-ipq8065-rt4230w-rev6.dtb \ ++ qcom-ipq8065-xr500.dtb \ ++ qcom-ipq8068-ecw5410.dtb \ ++ qcom-ipq8068-mr42.dtb \ ++ qcom-ipq8068-mr52.dtb \ + qcom-msm8660-surf.dtb \ + qcom-msm8960-cdp.dtb \ + qcom-msm8974-fairphone-fp2.dtb \ diff --git a/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch b/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch new file mode 100644 index 0000000000..62bba1d72a --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch @@ -0,0 +1,10 @@ +--- a/drivers/firmware/qcom_scm.c ++++ b/drivers/firmware/qcom_scm.c +@@ -1275,6 +1275,7 @@ static const struct of_device_id qcom_sc + SCM_HAS_BUS_CLK) + }, + { .compatible = "qcom,scm-ipq4019" }, ++ { .compatible = "qcom,scm-ipq806x" }, + { .compatible = "qcom,scm-msm8660", .data = (void *) SCM_HAS_CORE_CLK }, + { .compatible = "qcom,scm-msm8960", .data = (void *) SCM_HAS_CORE_CLK }, + { .compatible = "qcom,scm-msm8916", .data = (void *)(SCM_HAS_CORE_CLK | diff --git a/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch b/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch new file mode 100644 index 0000000000..d6a4593749 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch @@ -0,0 +1,220 @@ +--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +@@ -20,7 +20,7 @@ + #address-cells = <1>; + #size-cells = <0>; + +- cpu@0 { ++ cpu0: cpu@0 { + compatible = "qcom,krait"; + enable-method = "qcom,kpss-acc-v1"; + device_type = "cpu"; +@@ -30,7 +30,7 @@ + qcom,saw = <&saw0>; + }; + +- cpu@1 { ++ cpu1: cpu@1 { + compatible = "qcom,krait"; + enable-method = "qcom,kpss-acc-v1"; + device_type = "cpu"; +@@ -67,7 +67,7 @@ + no-map; + }; + +- smem@41000000 { ++ smem: smem@41000000 { + reg = <0x41000000 0x200000>; + no-map; + }; +@@ -128,6 +128,7 @@ + gpio-ranges = <&qcom_pinmux 0 0 69>; + #gpio-cells = <2>; + interrupt-controller; ++ #address-cells = <0>; + #interrupt-cells = <2>; + interrupts = ; + +@@ -155,6 +156,7 @@ + function = "pcie3_rst"; + drive-strength = <12>; + bias-disable; ++ output-low; + }; + }; + +@@ -190,6 +192,7 @@ + intc: interrupt-controller@2000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; ++ #address-cells = <0>; + #interrupt-cells = <3>; + reg = <0x02000000 0x1000>, + <0x02002000 0x1000>; +@@ -219,21 +222,23 @@ + acc0: clock-controller@2088000 { + compatible = "qcom,kpss-acc-v1"; + reg = <0x02088000 0x1000>, <0x02008000 0x1000>; ++ clock-output-names = "acpu0_aux"; + }; + + acc1: clock-controller@2098000 { + compatible = "qcom,kpss-acc-v1"; + reg = <0x02098000 0x1000>, <0x02008000 0x1000>; ++ clock-output-names = "acpu1_aux"; + }; + + saw0: regulator@2089000 { +- compatible = "qcom,saw2"; ++ compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon"; + reg = <0x02089000 0x1000>, <0x02009000 0x1000>; + regulator; + }; + + saw1: regulator@2099000 { +- compatible = "qcom,saw2"; ++ compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon"; + reg = <0x02099000 0x1000>, <0x02009000 0x1000>; + regulator; + }; +@@ -251,7 +256,7 @@ + + syscon-tcsr = <&tcsr>; + +- serial@12490000 { ++ gsbi2_serial: serial@12490000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x12490000 0x1000>, + <0x12480000 0x1000>; +@@ -261,7 +266,7 @@ + status = "disabled"; + }; + +- i2c@124a0000 { ++ gsbi2_i2c: i2c@124a0000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x124a0000 0x1000>; + interrupts = ; +@@ -326,7 +331,7 @@ + + syscon-tcsr = <&tcsr>; + +- serial@1a240000 { ++ gsbi5_serial: serial@1a240000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x1a240000 0x1000>, + <0x1a200000 0x1000>; +@@ -397,7 +402,7 @@ + status = "disabled"; + }; + +- sata@29000000 { ++ sata: sata@29000000 { + compatible = "qcom,ipq806x-ahci", "generic-ahci"; + reg = <0x29000000 0x180>; + +@@ -430,13 +435,35 @@ + reg = <0x00700000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; ++ ++ tsens_calib: calib@400 { ++ reg = <0x400 0xb>; ++ }; ++ tsens_backup: backup@410 { ++ reg = <0x410 0xb>; ++ }; ++ speedbin_efuse: speedbin@0c0 { ++ reg = <0x0c0 0x4>; ++ }; + }; + + gcc: clock-controller@900000 { +- compatible = "qcom,gcc-ipq8064"; ++ compatible = "qcom,gcc-ipq8064", "syscon"; + reg = <0x00900000 0x4000>; + #clock-cells = <1>; + #reset-cells = <1>; ++ #power-domain-cells = <1>; ++ ++ tsens: thermal-sensor@900000 { ++ compatible = "qcom,ipq8064-tsens"; ++ ++ nvmem-cells = <&tsens_calib>, <&tsens_backup>; ++ nvmem-cell-names = "calib", "calib_backup"; ++ interrupts = ; ++ interrupt-names = "uplow"; ++ #thermal-sensor-cells = <1>; ++ #qcom,sensors = <11>; ++ }; + }; + + tcsr: syscon@1a400000 { +@@ -622,7 +649,7 @@ + + gmac0: ethernet@37000000 { + device_type = "network"; +- compatible = "qcom,ipq806x-gmac"; ++ compatible = "qcom,ipq806x-gmac", "snps,dwmac"; + reg = <0x37000000 0x200000>; + interrupts = ; + interrupt-names = "macirq"; +@@ -645,7 +672,7 @@ + + gmac1: ethernet@37200000 { + device_type = "network"; +- compatible = "qcom,ipq806x-gmac"; ++ compatible = "qcom,ipq806x-gmac", "snps,dwmac"; + reg = <0x37200000 0x200000>; + interrupts = ; + interrupt-names = "macirq"; +@@ -668,7 +695,7 @@ + + gmac2: ethernet@37400000 { + device_type = "network"; +- compatible = "qcom,ipq806x-gmac"; ++ compatible = "qcom,ipq806x-gmac", "snps,dwmac"; + reg = <0x37400000 0x200000>; + interrupts = ; + interrupt-names = "macirq"; +@@ -691,7 +718,7 @@ + + gmac3: ethernet@37600000 { + device_type = "network"; +- compatible = "qcom,ipq806x-gmac"; ++ compatible = "qcom,ipq806x-gmac", "snps,dwmac"; + reg = <0x37600000 0x200000>; + interrupts = ; + interrupt-names = "macirq"; +@@ -740,13 +767,13 @@ + qcom,ee = <0>; + }; + +- amba { +- compatible = "simple-bus"; ++ amba: amba { ++ compatible = "arm,amba-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + +- sdcc@12400000 { ++ sdcc1: sdcc@12400000 { + status = "disabled"; + compatible = "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00051180>; +@@ -760,13 +787,12 @@ + non-removable; + cap-sd-highspeed; + cap-mmc-highspeed; +- mmc-ddr-1_8v; + vmmc-supply = <&vsdcc_fixed>; + dmas = <&sdcc1bam 2>, <&sdcc1bam 1>; + dma-names = "tx", "rx"; + }; + +- sdcc@12180000 { ++ sdcc3: sdcc@12180000 { + compatible = "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00051180>; + status = "disabled"; diff --git a/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch b/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch new file mode 100644 index 0000000000..2667bd636e --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch @@ -0,0 +1,846 @@ +--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +@@ -8,6 +8,8 @@ + #include + #include + #include ++#include ++#include + + / { + #address-cells = <1>; +@@ -28,6 +30,16 @@ + next-level-cache = <&L2>; + qcom,acc = <&acc0>; + qcom,saw = <&saw0>; ++ clocks = <&kraitcc 0>, <&kraitcc 4>; ++ clock-names = "cpu", "l2"; ++ clock-latency = <100000>; ++ cpu-supply = <&smb208_s2a>; ++ operating-points-v2 = <&opp_table0>; ++ voltage-tolerance = <5>; ++ cooling-min-state = <0>; ++ cooling-max-state = <10>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SPC>; + }; + + cpu1: cpu@1 { +@@ -38,14 +50,350 @@ + next-level-cache = <&L2>; + qcom,acc = <&acc1>; + qcom,saw = <&saw1>; ++ clocks = <&kraitcc 1>, <&kraitcc 4>; ++ clock-names = "cpu", "l2"; ++ clock-latency = <100000>; ++ cpu-supply = <&smb208_s2b>; ++ operating-points-v2 = <&opp_table0>; ++ voltage-tolerance = <5>; ++ cooling-min-state = <0>; ++ cooling-max-state = <10>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SPC>; ++ }; ++ ++ idle-states { ++ CPU_SPC: spc { ++ compatible = "qcom,idle-state-spc"; ++ status = "disabled"; ++ entry-latency-us = <400>; ++ exit-latency-us = <900>; ++ min-residency-us = <3000>; ++ }; + }; ++ }; + +- L2: l2-cache { +- compatible = "cache"; +- cache-level = <2>; ++ opp_table_l2: opp_table_l2 { ++ compatible = "operating-points-v2"; ++ ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-microvolt = <1100000>; ++ clock-latency-ns = <100000>; ++ opp-level = <0>; ++ }; ++ ++ opp-1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <1100000>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1150000>; ++ clock-latency-ns = <100000>; ++ opp-level = <2>; ++ }; ++ }; ++ ++ opp_table0: opp_table0 { ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&speedbin_efuse>; ++ ++ /* ++ * Voltage thresholds are ++ */ ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1000000 950000 1050000>; ++ opp-microvolt-speed0-pvs1-v0 = <925000 878750 971250>; ++ opp-microvolt-speed0-pvs2-v0 = <875000 831250 918750>; ++ opp-microvolt-speed0-pvs3-v0 = <800000 760000 840000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <0>; ++ }; ++ ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1050000 997500 1102500>; ++ opp-microvolt-speed0-pvs1-v0 = <975000 926250 1023750>; ++ opp-microvolt-speed0-pvs2-v0 = <925000 878750 971250>; ++ opp-microvolt-speed0-pvs3-v0 = <850000 807500 892500>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1100000 1045000 1155000>; ++ opp-microvolt-speed0-pvs1-v0 = <1025000 973750 1076250>; ++ opp-microvolt-speed0-pvs2-v0 = <995000 945250 1044750>; ++ opp-microvolt-speed0-pvs3-v0 = <900000 855000 945000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1150000 1092500 1207500>; ++ opp-microvolt-speed0-pvs1-v0 = <1075000 1021250 1128750>; ++ opp-microvolt-speed0-pvs2-v0 = <1025000 973750 1076250>; ++ opp-microvolt-speed0-pvs3-v0 = <950000 902500 997500>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1200000 1140000 1260000>; ++ opp-microvolt-speed0-pvs1-v0 = <1125000 1068750 1181250>; ++ opp-microvolt-speed0-pvs2-v0 = <1075000 1021250 1128750>; ++ opp-microvolt-speed0-pvs3-v0 = <1000000 950000 1050000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <2>; ++ }; ++ ++ opp-1400000000 { ++ opp-hz = /bits/ 64 <1400000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1250000 1187500 1312500>; ++ opp-microvolt-speed0-pvs1-v0 = <1175000 1116250 1233750>; ++ opp-microvolt-speed0-pvs2-v0 = <1125000 1068750 1181250>; ++ opp-microvolt-speed0-pvs3-v0 = <1050000 997500 1102500>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <2>; + }; + }; + ++ thermal-zones { ++ tsens_tz_sensor0 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 0>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor1 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 1>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor2 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 2>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor3 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 3>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor4 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 4>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor5 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 5>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor6 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 6>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor7 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 7>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor8 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 8>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor9 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 9>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ ++ tsens_tz_sensor10 { ++ polling-delay-passive = <0>; ++ polling-delay = <0>; ++ thermal-sensors = <&tsens 10>; ++ ++ trips { ++ cpu-critical { ++ temperature = <105000>; ++ hysteresis = <2000>; ++ type = "critical"; ++ }; ++ ++ cpu-hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "hot"; ++ }; ++ }; ++ }; ++ }; ++ + memory { + device_type = "memory"; + reg = <0x0 0x0>; +@@ -93,6 +441,15 @@ + }; + }; + ++ fab-scaling { ++ compatible = "qcom,fab-scaling"; ++ clocks = <&rpmcc RPM_APPS_FABRIC_A_CLK>, <&rpmcc RPM_EBI1_A_CLK>; ++ clock-names = "apps-fab-clk", "ddr-fab-clk"; ++ fab_freq_high = <533000000>; ++ fab_freq_nominal = <400000000>; ++ cpu_freq_threshold = <1000000000>; ++ }; ++ + firmware { + scm { + compatible = "qcom,scm-ipq806x", "qcom,scm"; +@@ -120,6 +477,78 @@ + reg-names = "lpass-lpaif"; + }; + ++ L2: l2-cache { ++ compatible = "qcom,krait-cache", "cache"; ++ cache-level = <2>; ++ qcom,saw = <&saw_l2>; ++ ++ clocks = <&kraitcc 4>; ++ clock-names = "l2"; ++ l2-supply = <&smb208_s1a>; ++ operating-points-v2 = <&opp_table_l2>; ++ }; ++ ++ rpm: rpm@108000 { ++ compatible = "qcom,rpm-ipq8064"; ++ reg = <0x108000 0x1000>; ++ qcom,ipc = <&l2cc 0x8 2>; ++ ++ interrupts = , ++ , ++ ; ++ interrupt-names = "ack", "err", "wakeup"; ++ ++ clocks = <&gcc RPM_MSG_RAM_H_CLK>; ++ clock-names = "ram"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rpmcc: clock-controller { ++ compatible = "qcom,rpmcc-ipq806x", "qcom,rpmcc"; ++ #clock-cells = <1>; ++ }; ++ ++ regulators { ++ compatible = "qcom,rpm-smb208-regulators"; ++ ++ smb208_s1a: s1a { ++ regulator-min-microvolt = <1050000>; ++ regulator-max-microvolt = <1150000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ ++ smb208_s1b: s1b { ++ regulator-min-microvolt = <1050000>; ++ regulator-max-microvolt = <1150000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ ++ smb208_s2a: s2a { ++ regulator-min-microvolt = < 800000>; ++ regulator-max-microvolt = <1250000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ ++ smb208_s2b: s2b { ++ regulator-min-microvolt = < 800000>; ++ regulator-max-microvolt = <1250000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ }; ++ }; ++ ++ rng@1a500000 { ++ compatible = "qcom,prng"; ++ reg = <0x1a500000 0x200>; ++ clocks = <&gcc PRNG_CLK>; ++ clock-names = "core"; ++ }; ++ + qcom_pinmux: pinmux@800000 { + compatible = "qcom,ipq8064-pinctrl"; + reg = <0x800000 0x4000>; +@@ -160,6 +589,15 @@ + }; + }; + ++ i2c4_pins: i2c4_pinmux { ++ mux { ++ pins = "gpio12", "gpio13"; ++ function = "gsbi4"; ++ drive-strength = <12>; ++ bias-disable; ++ }; ++ }; ++ + spi_pins: spi_pins { + mux { + pins = "gpio18", "gpio19", "gpio21"; +@@ -169,6 +607,53 @@ + }; + }; + ++ nand_pins: nand_pins { ++ disable { ++ pins = "gpio34", "gpio35", "gpio36", ++ "gpio37", "gpio38"; ++ function = "nand"; ++ drive-strength = <10>; ++ bias-disable; ++ }; ++ ++ pullups { ++ pins = "gpio39"; ++ function = "nand"; ++ drive-strength = <10>; ++ bias-pull-up; ++ }; ++ ++ hold { ++ pins = "gpio40", "gpio41", "gpio42", ++ "gpio43", "gpio44", "gpio45", ++ "gpio46", "gpio47"; ++ function = "nand"; ++ drive-strength = <10>; ++ bias-bus-hold; ++ }; ++ }; ++ ++ mdio0_pins: mdio0_pins { ++ mux { ++ pins = "gpio0", "gpio1"; ++ function = "mdio"; ++ drive-strength = <8>; ++ bias-disable; ++ }; ++ }; ++ ++ rgmii2_pins: rgmii2_pins { ++ mux { ++ pins = "gpio27", "gpio28", "gpio29", ++ "gpio30", "gpio31", "gpio32", ++ "gpio51", "gpio52", "gpio59", ++ "gpio60", "gpio61", "gpio62"; ++ function = "rgmii2"; ++ drive-strength = <8>; ++ bias-disable; ++ }; ++ }; ++ + leds_pins: leds_pins { + mux { + pins = "gpio7", "gpio8", "gpio9", +@@ -231,6 +716,17 @@ + clock-output-names = "acpu1_aux"; + }; + ++ l2cc: clock-controller@2011000 { ++ compatible = "qcom,kpss-gcc", "syscon"; ++ reg = <0x2011000 0x1000>; ++ clock-output-names = "acpu_l2_aux"; ++ }; ++ ++ kraitcc: clock-controller { ++ compatible = "qcom,krait-cc-v1"; ++ #clock-cells = <1>; ++ }; ++ + saw0: regulator@2089000 { + compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon"; + reg = <0x02089000 0x1000>, <0x02009000 0x1000>; +@@ -243,6 +739,52 @@ + regulator; + }; + ++ saw_l2: regulator@02012000 { ++ compatible = "qcom,saw2", "syscon"; ++ reg = <0x02012000 0x1000>; ++ regulator; ++ }; ++ ++ sic_non_secure: sic-non-secure@12100000 { ++ compatible = "syscon"; ++ reg = <0x12100000 0x10000>; ++ }; ++ ++ gsbi1: gsbi@12440000 { ++ compatible = "qcom,gsbi-v1.0.0"; ++ cell-index = <1>; ++ reg = <0x12440000 0x100>; ++ clocks = <&gcc GSBI1_H_CLK>; ++ clock-names = "iface"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ status = "disabled"; ++ ++ syscon-tcsr = <&tcsr>; ++ ++ gsbi1_serial: serial@12450000 { ++ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; ++ reg = <0x12450000 0x100>, ++ <0x12400000 0x03>; ++ interrupts = ; ++ clocks = <&gcc GSBI1_UART_CLK>, <&gcc GSBI1_H_CLK>; ++ clock-names = "core", "iface"; ++ status = "disabled"; ++ }; ++ ++ gsbi1_i2c: i2c@12460000 { ++ compatible = "qcom,i2c-qup-v1.1.1"; ++ reg = <0x12460000 0x1000>; ++ interrupts = ; ++ clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>; ++ clock-names = "core", "iface"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + gsbi2: gsbi@12480000 { + compatible = "qcom,gsbi-v1.0.0"; + cell-index = <2>; +@@ -368,6 +910,33 @@ + }; + }; + ++ gsbi6: gsbi@16500000 { ++ status = "disabled"; ++ compatible = "qcom,gsbi-v1.0.0"; ++ cell-index = <6>; ++ reg = <0x16500000 0x100>; ++ clocks = <&gcc GSBI6_H_CLK>; ++ clock-names = "iface"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ syscon-tcsr = <&tcsr>; ++ ++ gsbi6_i2c: i2c@16580000 { ++ compatible = "qcom,i2c-qup-v1.1.1"; ++ reg = <0x16580000 0x1000>; ++ interrupts = ; ++ ++ clocks = <&gcc GSBI6_QUP_CLK>, <&gcc GSBI6_H_CLK>; ++ clock-names = "core", "iface"; ++ status = "disabled"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ + gsbi7: gsbi@16600000 { + status = "disabled"; + compatible = "qcom,gsbi-v1.0.0"; +@@ -389,6 +958,19 @@ + clock-names = "core", "iface"; + status = "disabled"; + }; ++ ++ gsbi7_i2c: i2c@16680000 { ++ compatible = "qcom,i2c-qup-v1.1.1"; ++ reg = <0x16680000 0x1000>; ++ interrupts = ; ++ ++ clocks = <&gcc GSBI7_QUP_CLK>, <&gcc GSBI7_H_CLK>; ++ clock-names = "core", "iface"; ++ status = "disabled"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; + }; + + sata_phy: sata-phy@1b400000 { +@@ -478,6 +1060,95 @@ + #reset-cells = <1>; + }; + ++ sfpb_mutex_block: syscon@1200600 { ++ compatible = "syscon"; ++ reg = <0x01200600 0x100>; ++ }; ++ ++ hs_phy_0: hs_phy_0 { ++ compatible = "qcom,ipq806x-usb-phy-hs"; ++ reg = <0x110f8800 0x30>; ++ clocks = <&gcc USB30_0_UTMI_CLK>; ++ clock-names = "ref"; ++ #phy-cells = <0>; ++ }; ++ ++ ss_phy_0: ss_phy_0 { ++ compatible = "qcom,ipq806x-usb-phy-ss"; ++ reg = <0x110f8830 0x30>; ++ clocks = <&gcc USB30_0_MASTER_CLK>; ++ clock-names = "ref"; ++ #phy-cells = <0>; ++ }; ++ ++ usb3_0: usb3@110f8800 { ++ compatible = "qcom,dwc3", "syscon"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x110f8800 0x8000>; ++ clocks = <&gcc USB30_0_MASTER_CLK>; ++ clock-names = "core"; ++ ++ ranges; ++ ++ resets = <&gcc USB30_0_MASTER_RESET>; ++ reset-names = "master"; ++ ++ status = "disabled"; ++ ++ dwc3_0: dwc3@11000000 { ++ compatible = "snps,dwc3"; ++ reg = <0x11000000 0xcd00>; ++ interrupts = ; ++ phys = <&hs_phy_0>, <&ss_phy_0>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ dr_mode = "host"; ++ snps,dis_u3_susphy_quirk; ++ }; ++ }; ++ ++ hs_phy_1: hs_phy_1 { ++ compatible = "qcom,ipq806x-usb-phy-hs"; ++ reg = <0x100f8800 0x30>; ++ clocks = <&gcc USB30_1_UTMI_CLK>; ++ clock-names = "ref"; ++ #phy-cells = <0>; ++ }; ++ ++ ss_phy_1: ss_phy_1 { ++ compatible = "qcom,ipq806x-usb-phy-ss"; ++ reg = <0x100f8830 0x30>; ++ clocks = <&gcc USB30_1_MASTER_CLK>; ++ clock-names = "ref"; ++ #phy-cells = <0>; ++ }; ++ ++ usb3_1: usb3@100f8800 { ++ compatible = "qcom,dwc3", "syscon"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x100f8800 0x8000>; ++ clocks = <&gcc USB30_1_MASTER_CLK>; ++ clock-names = "core"; ++ ++ ranges; ++ ++ resets = <&gcc USB30_1_MASTER_RESET>; ++ reset-names = "master"; ++ ++ status = "disabled"; ++ ++ dwc3_1: dwc3@10000000 { ++ compatible = "snps,dwc3"; ++ reg = <0x10000000 0xcd00>; ++ interrupts = ; ++ phys = <&hs_phy_1>, <&ss_phy_1>; ++ phy-names = "usb2-phy", "usb3-phy"; ++ dr_mode = "host"; ++ snps,dis_u3_susphy_quirk; ++ }; ++ }; ++ + pcie0: pci@1b500000 { + compatible = "qcom,pcie-ipq8064"; + reg = <0x1b500000 0x1000 +@@ -739,6 +1410,59 @@ + status = "disabled"; + }; + ++ adm_dma: dma@18300000 { ++ compatible = "qcom,adm"; ++ reg = <0x18300000 0x100000>; ++ interrupts = ; ++ #dma-cells = <1>; ++ ++ clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>; ++ clock-names = "core", "iface"; ++ ++ resets = <&gcc ADM0_RESET>, ++ <&gcc ADM0_PBUS_RESET>, ++ <&gcc ADM0_C0_RESET>, ++ <&gcc ADM0_C1_RESET>, ++ <&gcc ADM0_C2_RESET>; ++ reset-names = "clk", "pbus", "c0", "c1", "c2"; ++ qcom,ee = <0>; ++ ++ status = "disabled"; ++ }; ++ ++ nand_controller: nand-controller@1ac00000 { ++ compatible = "qcom,ipq806x-nand"; ++ reg = <0x1ac00000 0x800>; ++ ++ clocks = <&gcc EBI2_CLK>, ++ <&gcc EBI2_AON_CLK>; ++ clock-names = "core", "aon"; ++ ++ dmas = <&adm_dma 3>; ++ dma-names = "rxtx"; ++ qcom,cmd-crci = <15>; ++ qcom,data-crci = <3>; ++ ++ status = "disabled"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ mdio0: mdio@37000000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ compatible = "qcom,ipq8064-mdio", "syscon"; ++ reg = <0x37000000 0x200000>; ++ resets = <&gcc GMAC_CORE1_RESET>; ++ reset-names = "stmmaceth"; ++ clocks = <&gcc GMAC_CORE1_CLK>; ++ clock-names = "stmmaceth"; ++ ++ status = "disabled"; ++ }; ++ + vsdcc_fixed: vsdcc-regulator { + compatible = "regulator-fixed"; + regulator-name = "SDCC Power"; +@@ -814,4 +1538,17 @@ + }; + }; + }; ++ ++ sfpb_mutex: sfpb-mutex { ++ compatible = "qcom,sfpb-mutex"; ++ syscon = <&sfpb_mutex_block 4 4>; ++ ++ #hwlock-cells = <1>; ++ }; ++ ++ smem { ++ compatible = "qcom,smem"; ++ memory-region = <&smem>; ++ hwlocks = <&sfpb_mutex 3>; ++ }; + }; diff --git a/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch b/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch new file mode 100644 index 0000000000..e5ea8e6393 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch @@ -0,0 +1,89 @@ +This uses upstream qcom-ipq8064-v1.0.dtsi and modifies it by patches +instead of keeping a local version. +We drop partitions, LEDs and keys from the file as we will implement +them differently anyway. + +--- a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi +@@ -42,16 +42,6 @@ + #size-cells = <1>; + spi-max-frequency = <50000000>; + reg = <0>; +- +- partition@0 { +- label = "rootfs"; +- reg = <0x0 0x1000000>; +- }; +- +- partition@1 { +- label = "scratch"; +- reg = <0x1000000 0x1000000>; +- }; + }; + }; + }; +@@ -64,64 +54,5 @@ + ports-implemented = <0x1>; + status = "ok"; + }; +- +- gpio_keys { +- compatible = "gpio-keys"; +- pinctrl-0 = <&buttons_pins>; +- pinctrl-names = "default"; +- +- button@1 { +- label = "reset"; +- linux,code = ; +- gpios = <&qcom_pinmux 54 GPIO_ACTIVE_LOW>; +- linux,input-type = <1>; +- debounce-interval = <60>; +- }; +- button@2 { +- label = "wps"; +- linux,code = ; +- gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>; +- linux,input-type = <1>; +- debounce-interval = <60>; +- }; +- }; +- +- leds { +- compatible = "gpio-leds"; +- pinctrl-0 = <&leds_pins>; +- pinctrl-names = "default"; +- +- led@7 { +- label = "led_usb1"; +- gpios = <&qcom_pinmux 7 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "usbdev"; +- default-state = "off"; +- }; +- +- led@8 { +- label = "led_usb3"; +- gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>; +- linux,default-trigger = "usbdev"; +- default-state = "off"; +- }; +- +- led@9 { +- label = "status_led_fail"; +- gpios = <&qcom_pinmux 9 GPIO_ACTIVE_HIGH>; +- default-state = "off"; +- }; +- +- led@26 { +- label = "sata_led"; +- gpios = <&qcom_pinmux 26 GPIO_ACTIVE_HIGH>; +- default-state = "off"; +- }; +- +- led@53 { +- label = "status_led_pass"; +- gpios = <&qcom_pinmux 53 GPIO_ACTIVE_HIGH>; +- default-state = "off"; +- }; +- }; + }; + }; diff --git a/target/linux/ipq806x/patches-5.15/085-ipq8064-v1.0-dtsi-additions.patch b/target/linux/ipq806x/patches-5.15/085-ipq8064-v1.0-dtsi-additions.patch new file mode 100644 index 0000000000..58f6a46e4f --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/085-ipq8064-v1.0-dtsi-additions.patch @@ -0,0 +1,14 @@ +This uses upstream qcom-ipq8064-v1.0.dtsi and modifies it by patches +instead of keeping a local version. This patch adds our local adjustments +for the (local) additional contents of qcom-ipq8064.dtsi + +--- a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi +@@ -56,3 +56,7 @@ + }; + }; + }; ++ ++&CPU_SPC { ++ status = "okay"; ++}; diff --git a/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch b/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch new file mode 100644 index 0000000000..747fa8c019 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch @@ -0,0 +1,145 @@ +--- a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts ++++ b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts +@@ -24,73 +24,6 @@ + device_type = "memory"; + }; + +- mdio0: mdio-0 { +- status = "okay"; +- compatible = "virtual,mdio-gpio"; +- gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH>, +- <&qcom_pinmux 0 GPIO_ACTIVE_HIGH>; +- #address-cells = <1>; +- #size-cells = <0>; +- +- pinctrl-0 = <&mdio0_pins>; +- pinctrl-names = "default"; +- +- switch0: switch@10 { +- compatible = "qca,qca8337"; +- #address-cells = <1>; +- #size-cells = <0>; +- +- dsa,member = <0 0>; +- +- pinctrl-0 = <&sw0_reset_pin>; +- pinctrl-names = "default"; +- +- reset-gpios = <&qcom_pinmux 16 GPIO_ACTIVE_LOW>; +- reg = <0x10>; +- +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- switch0cpu: port@0 { +- reg = <0>; +- label = "cpu"; +- ethernet = <&gmac0>; +- phy-mode = "rgmii-id"; +- fixed-link { +- speed = <1000>; +- full-duplex; +- }; +- }; +- +- port@1 { +- reg = <1>; +- label = "sw1"; +- }; +- +- port@2 { +- reg = <2>; +- label = "sw2"; +- }; +- +- port@3 { +- reg = <3>; +- label = "sw3"; +- }; +- +- port@4 { +- reg = <4>; +- label = "sw4"; +- }; +- +- port@5 { +- reg = <5>; +- label = "sw5"; +- }; +- }; +- }; +- }; +- + mdio1: mdio-1 { + status = "okay"; + compatible = "virtual,mdio-gpio"; +@@ -216,6 +149,68 @@ + }; + }; + ++&mdio0 { ++ status = "okay"; ++ ++ pinctrl-0 = <&mdio0_pins>; ++ pinctrl-names = "default"; ++ ++ switch0: switch@10 { ++ compatible = "qca,qca8337"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ dsa,member = <0 0>; ++ ++ pinctrl-0 = <&sw0_reset_pin>; ++ pinctrl-names = "default"; ++ ++ reset-gpios = <&qcom_pinmux 16 GPIO_ACTIVE_LOW>; ++ reg = <0x10>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ switch0cpu: port@0 { ++ reg = <0>; ++ label = "cpu"; ++ ethernet = <&gmac0>; ++ phy-mode = "rgmii-id"; ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ label = "sw1"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ label = "sw2"; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "sw3"; ++ }; ++ ++ port@4 { ++ reg = <4>; ++ label = "sw4"; ++ }; ++ ++ port@5 { ++ reg = <5>; ++ label = "sw5"; ++ }; ++ }; ++ }; ++}; ++ + &gmac0 { + status = "okay"; + diff --git a/target/linux/ipq806x/patches-5.15/093-drivers-cpufreq-qcom-cpufreq-nvmem-support-specific-.patch b/target/linux/ipq806x/patches-5.15/093-drivers-cpufreq-qcom-cpufreq-nvmem-support-specific-.patch new file mode 100644 index 0000000000..19c3d096c4 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/093-drivers-cpufreq-qcom-cpufreq-nvmem-support-specific-.patch @@ -0,0 +1,51 @@ +From a206d4061f1cc2c5cd17ee45c53a0ba711e48e6d Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 7 Feb 2021 16:42:52 +0100 +Subject: [PATCH 3/3] drivers: cpufreq: qcom-cpufreq-nvmem: support specific + cpufreq driver + +Add support for specific cpufreq driver for qcom-cpufreq-nvmem driver. + +Signed-off-by: Ansuel Smith +--- + drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c ++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c +@@ -52,6 +52,7 @@ struct qcom_cpufreq_match_data { + char **pvs_name, + struct qcom_cpufreq_drv *drv); + const char **genpd_names; ++ const char *cpufreq_driver; + }; + + struct qcom_cpufreq_drv { +@@ -250,6 +251,7 @@ static const struct qcom_cpufreq_match_d + + static const struct qcom_cpufreq_match_data match_data_krait = { + .get_version = qcom_cpufreq_krait_name_version, ++ .cpufreq_driver = "krait-cpufreq", + }; + + static const char *qcs404_genpd_names[] = { "cpr", NULL }; +@@ -385,6 +387,19 @@ static int qcom_cpufreq_probe(struct pla + } + } + ++ if (drv->data->cpufreq_driver) { ++ cpufreq_dt_pdev = platform_device_register_simple( ++ drv->data->cpufreq_driver, -1, NULL, 0); ++ if (!IS_ERR(cpufreq_dt_pdev)) { ++ platform_set_drvdata(pdev, drv); ++ return 0; ++ } else { ++ dev_err(cpu_dev, ++ "Failed to register dedicated %s cpufreq\n", ++ drv->data->cpufreq_driver); ++ } ++ } ++ + cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, + NULL, 0); + if (!IS_ERR(cpufreq_dt_pdev)) { diff --git a/target/linux/ipq806x/patches-5.15/097-1-ipq806x-gcc-add-missing-clk-flag.patch b/target/linux/ipq806x/patches-5.15/097-1-ipq806x-gcc-add-missing-clk-flag.patch new file mode 100644 index 0000000000..3b4900fafb --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/097-1-ipq806x-gcc-add-missing-clk-flag.patch @@ -0,0 +1,99 @@ +From 0af44917941cbfecdc86bb9bf05ff01d22a88973 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 7 Feb 2021 16:52:56 +0100 +Subject: [PATCH 1/4] ipq806x: gcc: add missing clk flag + +Some flag are missing from the original code. +These clk can't be set using the protected-clock proprities as they +cause the malfunction of the serial interface. +These clks are needed for the rpm interface to work proprely or the +cpu regulators starts to fail as soon as they are disabled by the +kernel. + +Signed-off-by: Ansuel Smith +--- + drivers/clk/qcom/gcc-ipq806x.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq806x.c ++++ b/drivers/clk/qcom/gcc-ipq806x.c +@@ -65,6 +65,7 @@ static struct clk_pll pll3 = { + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, ++ .flags = CLK_IS_CRITICAL, + }, + }; + +@@ -782,7 +783,7 @@ static struct clk_rcg gsbi4_qup_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_PARENT_GATE, ++ .flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED, + }, + }, + }; +@@ -798,7 +799,7 @@ static struct clk_branch gsbi4_qup_clk = + .parent_names = (const char *[]){ "gsbi4_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, +- .flags = CLK_SET_RATE_PARENT, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, + }, + }; +@@ -880,7 +881,7 @@ static struct clk_rcg gsbi6_qup_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, +- .flags = CLK_SET_PARENT_GATE, ++ .flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED, + }, + }, + }; +@@ -945,7 +946,7 @@ static struct clk_branch gsbi7_qup_clk = + .parent_names = (const char *[]){ "gsbi7_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, +- .flags = CLK_SET_RATE_PARENT, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, + }, + }; +@@ -991,6 +992,7 @@ static struct clk_branch gsbi4_h_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_h_clk", + .ops = &clk_branch_ops, ++ .flags = CLK_IGNORE_UNUSED, + }, + }, + }; +@@ -1424,6 +1426,7 @@ static struct clk_rcg tsif_ref_src = { + .parent_names = gcc_pxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, ++ .flags = CLK_SET_RATE_GATE, + }, + } + }; +@@ -2694,7 +2697,8 @@ static struct clk_dyn_rcg ubi32_core1_sr + .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, + .num_parents = 5, + .ops = &clk_dyn_rcg_ops, +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, ++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | ++ CLK_IGNORE_UNUSED, + }, + }, + }; +@@ -2747,7 +2751,8 @@ static struct clk_dyn_rcg ubi32_core2_sr + .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, + .num_parents = 5, + .ops = &clk_dyn_rcg_ops, +- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, ++ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | ++ CLK_IGNORE_UNUSED, + }, + }, + }; diff --git a/target/linux/ipq806x/patches-5.15/097-2-ipq806x-lcc-add-missing-reset.patch b/target/linux/ipq806x/patches-5.15/097-2-ipq806x-lcc-add-missing-reset.patch new file mode 100644 index 0000000000..cd2cb33356 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/097-2-ipq806x-lcc-add-missing-reset.patch @@ -0,0 +1,59 @@ +From 3a5f1793c0bf4a6b536751886b0a44589fe05f35 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 7 Feb 2021 17:00:07 +0100 +Subject: [PATCH 2/4] ipq806x: lcc: add missing reset + +Add missing reset for ipq806x lcc clk + +Signed-off-by: Ansuel Smith +--- + drivers/clk/qcom/lcc-ipq806x.c | 8 ++++++++ + include/dt-bindings/clock/qcom,lcc-ipq806x.h | 1 + + 2 files changed, 9 insertions(+) + +--- a/drivers/clk/qcom/lcc-ipq806x.c ++++ b/drivers/clk/qcom/lcc-ipq806x.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include + +@@ -22,6 +23,7 @@ + #include "clk-branch.h" + #include "clk-regmap-divider.h" + #include "clk-regmap-mux.h" ++#include "reset.h" + + static struct clk_pll pll4 = { + .l_reg = 0x4, +@@ -39,6 +41,10 @@ static struct clk_pll pll4 = { + }, + }; + ++static const struct qcom_reset_map lcc_ipq806x_resets[] = { ++ [LCC_PCM_RESET] = { 0x54, 13 }, ++}; ++ + static const struct pll_config pll4_config = { + .l = 0xf, + .m = 0x91, +@@ -417,6 +423,8 @@ static const struct qcom_cc_desc lcc_ipq + .config = &lcc_ipq806x_regmap_config, + .clks = lcc_ipq806x_clks, + .num_clks = ARRAY_SIZE(lcc_ipq806x_clks), ++ .resets = lcc_ipq806x_resets, ++ .num_resets = ARRAY_SIZE(lcc_ipq806x_resets), + }; + + static const struct of_device_id lcc_ipq806x_match_table[] = { +--- a/include/dt-bindings/clock/qcom,lcc-ipq806x.h ++++ b/include/dt-bindings/clock/qcom,lcc-ipq806x.h +@@ -19,4 +19,5 @@ + #define SPDIF_CLK 10 + #define AHBIX_CLK 11 + ++#define LCC_PCM_RESET 0 + #endif diff --git a/target/linux/ipq806x/patches-5.15/097-3-clk-qcom-krait-add-missing-enable-disable.patch b/target/linux/ipq806x/patches-5.15/097-3-clk-qcom-krait-add-missing-enable-disable.patch new file mode 100644 index 0000000000..bf1c1a4a2f --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/097-3-clk-qcom-krait-add-missing-enable-disable.patch @@ -0,0 +1,57 @@ +From f8fdbecdaca97f0f2eebd77256e2eca4a8da6c39 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 7 Feb 2021 17:08:16 +0100 +Subject: [PATCH 3/4] clk: qcom: krait: add missing enable disable + +Add missing enable disable mux function. Add extra check to +div2_round_rate. + +Signed-off-by: Ansuel Smith +--- + drivers/clk/qcom/clk-krait.c | 27 +++++++++++++++++++++++++-- + 1 file changed, 25 insertions(+), 2 deletions(-) + +--- a/drivers/clk/qcom/clk-krait.c ++++ b/drivers/clk/qcom/clk-krait.c +@@ -68,7 +68,25 @@ static u8 krait_mux_get_parent(struct cl + return clk_mux_val_to_index(hw, mux->parent_map, 0, sel); + } + ++static int krait_mux_enable(struct clk_hw *hw) ++{ ++ struct krait_mux_clk *mux = to_krait_mux_clk(hw); ++ ++ __krait_mux_set_sel(mux, mux->en_mask); ++ ++ return 0; ++} ++ ++static void krait_mux_disable(struct clk_hw *hw) ++{ ++ struct krait_mux_clk *mux = to_krait_mux_clk(hw); ++ ++ __krait_mux_set_sel(mux, mux->safe_sel); ++} ++ + const struct clk_ops krait_mux_clk_ops = { ++ .enable = krait_mux_enable, ++ .disable = krait_mux_disable, + .set_parent = krait_mux_set_parent, + .get_parent = krait_mux_get_parent, + .determine_rate = __clk_mux_determine_rate_closest, +@@ -79,8 +97,13 @@ EXPORT_SYMBOL_GPL(krait_mux_clk_ops); + static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) + { +- *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2); +- return DIV_ROUND_UP(*parent_rate, 2); ++ struct clk_hw *hw_parent = clk_hw_get_parent(hw); ++ ++ if (hw_parent) { ++ *parent_rate = clk_hw_round_rate(hw_parent, rate * 2); ++ return DIV_ROUND_UP(*parent_rate, 2); ++ } else ++ return -1; + } + + static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/target/linux/ipq806x/patches-5.15/097-4-ipq806x-gcc-add-missing-clk-and-reset-for-crypto-eng.patch b/target/linux/ipq806x/patches-5.15/097-4-ipq806x-gcc-add-missing-clk-and-reset-for-crypto-eng.patch new file mode 100644 index 0000000000..d1e047cabf --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/097-4-ipq806x-gcc-add-missing-clk-and-reset-for-crypto-eng.patch @@ -0,0 +1,372 @@ +From 22a0f55b0e505fbbbb680e451a62878bc97f7ff1 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sun, 7 Feb 2021 17:23:38 +0100 +Subject: [PATCH 4/4] ipq806x: gcc: add missing clk and reset for crypto engine + +Add missing clk and reset needed for nss additional core and crypto +engine. + +Signed-off-by: Ansuel Smith +--- + drivers/clk/qcom/gcc-ipq806x.c | 250 +++++++++++++++++++ + include/dt-bindings/clock/qcom,gcc-ipq806x.h | 5 +- + include/dt-bindings/reset/qcom,gcc-ipq806x.h | 5 + + 3 files changed, 259 insertions(+), 1 deletion(-) + +--- a/drivers/clk/qcom/gcc-ipq806x.c ++++ b/drivers/clk/qcom/gcc-ipq806x.c +@@ -223,7 +223,9 @@ static struct clk_regmap pll14_vote = { + + static struct pll_freq_tbl pll18_freq_tbl[] = { + NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625), ++ NSS_PLL_RATE(600000000, 48, 0, 1, 0x01495625), + NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625), ++ NSS_PLL_RATE(800000000, 64, 0, 1, 0x01495625), + }; + + static struct clk_pll pll18 = { +@@ -245,6 +247,22 @@ static struct clk_pll pll18 = { + }, + }; + ++static struct clk_pll pll11 = { ++ .l_reg = 0x3184, ++ .m_reg = 0x3188, ++ .n_reg = 0x318c, ++ .config_reg = 0x3194, ++ .mode_reg = 0x3180, ++ .status_reg = 0x3198, ++ .status_bit = 16, ++ .clkr.hw.init = &(struct clk_init_data){ ++ .name = "pll11", ++ .parent_names = (const char *[]){ "pxo" }, ++ .num_parents = 1, ++ .ops = &clk_pll_ops, ++ }, ++}; ++ + enum { + P_PXO, + P_PLL8, +@@ -253,6 +271,7 @@ enum { + P_CXO, + P_PLL14, + P_PLL18, ++ P_PLL11, + }; + + static const struct parent_map gcc_pxo_pll8_map[] = { +@@ -320,6 +339,42 @@ static const char * const gcc_pxo_pll8_p + "pll18", + }; + ++static const struct parent_map gcc_pxo_pll8_pll0_pll14_pll18_pll11_map[] = { ++ { P_PXO, 0 }, ++ { P_PLL8, 4 }, ++ { P_PLL0, 2 }, ++ { P_PLL14, 5 }, ++ { P_PLL18, 1 }, ++ { P_PLL11, 3 }, ++}; ++ ++static const char *gcc_pxo_pll8_pll0_pll14_pll18_pll11[] = { ++ "pxo", ++ "pll8_vote", ++ "pll0_vote", ++ "pll14", ++ "pll18", ++ "pll11" ++}; ++ ++static const struct parent_map gcc_pxo_pll3_pll0_pll14_pll18_pll11_map[] = { ++ { P_PXO, 0 }, ++ { P_PLL3, 6 }, ++ { P_PLL0, 2 }, ++ { P_PLL14, 5 }, ++ { P_PLL18, 1 }, ++ { P_PLL11, 3 }, ++}; ++ ++static const char *gcc_pxo_pll3_pll0_pll14_pll18_pll11[] = { ++ "pxo", ++ "pll3", ++ "pll0_vote", ++ "pll14", ++ "pll18", ++ "pll11" ++}; ++ + static struct freq_tbl clk_tbl_gsbi_uart[] = { + { 1843200, P_PLL8, 2, 6, 625 }, + { 3686400, P_PLL8, 2, 12, 625 }, +@@ -1261,6 +1316,7 @@ static const struct freq_tbl clk_tbl_sdc + { 20210000, P_PLL8, 1, 1, 19 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 48000000, P_PLL8, 4, 1, 2 }, ++ { 52000000, P_PLL8, 1, 2, 15 }, /* 51.2 Mhz */ + { 64000000, P_PLL8, 3, 1, 2 }, + { 96000000, P_PLL8, 4, 0, 0 }, + { 192000000, P_PLL8, 2, 0, 0 }, +@@ -2645,7 +2701,9 @@ static const struct freq_tbl clk_tbl_nss + { 110000000, P_PLL18, 1, 1, 5 }, + { 275000000, P_PLL18, 2, 0, 0 }, + { 550000000, P_PLL18, 1, 0, 0 }, ++ { 600000000, P_PLL18, 1, 0, 0 }, + { 733000000, P_PLL18, 1, 0, 0 }, ++ { 800000000, P_PLL18, 1, 0, 0 }, + { } + }; + +@@ -2757,6 +2815,186 @@ static struct clk_dyn_rcg ubi32_core2_sr + }, + }; + ++static const struct freq_tbl clk_tbl_ce5_core[] = { ++ { 150000000, P_PLL3, 8, 1, 1 }, ++ { 213200000, P_PLL11, 5, 1, 1 }, ++ { } ++}; ++ ++static struct clk_dyn_rcg ce5_core_src = { ++ .ns_reg[0] = 0x36C4, ++ .ns_reg[1] = 0x36C8, ++ .bank_reg = 0x36C0, ++ .s[0] = { ++ .src_sel_shift = 0, ++ .parent_map = gcc_pxo_pll3_pll0_pll14_pll18_pll11_map, ++ }, ++ .s[1] = { ++ .src_sel_shift = 0, ++ .parent_map = gcc_pxo_pll3_pll0_pll14_pll18_pll11_map, ++ }, ++ .p[0] = { ++ .pre_div_shift = 3, ++ .pre_div_width = 4, ++ }, ++ .p[1] = { ++ .pre_div_shift = 3, ++ .pre_div_width = 4, ++ }, ++ .mux_sel_bit = 0, ++ .freq_tbl = clk_tbl_ce5_core, ++ .clkr = { ++ .enable_reg = 0x36C0, ++ .enable_mask = BIT(1), ++ .hw.init = &(struct clk_init_data){ ++ .name = "ce5_core_src", ++ .parent_names = gcc_pxo_pll3_pll0_pll14_pll18_pll11, ++ .num_parents = 6, ++ .ops = &clk_dyn_rcg_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch ce5_core_clk = { ++ .halt_reg = 0x2FDC, ++ .halt_bit = 5, ++ .hwcg_reg = 0x36CC, ++ .hwcg_bit = 6, ++ .clkr = { ++ .enable_reg = 0x36CC, ++ .enable_mask = BIT(4), ++ .hw.init = &(struct clk_init_data){ ++ .name = "ce5_core_clk", ++ .parent_names = (const char *[]){ ++ "ce5_core_src", ++ }, ++ .num_parents = 1, ++ .ops = &clk_branch_ops, ++ .flags = CLK_SET_RATE_PARENT, ++ }, ++ }, ++}; ++ ++static const struct freq_tbl clk_tbl_ce5_a_clk[] = { ++ { 160000000, P_PLL0, 5, 1, 1 }, ++ { 213200000, P_PLL11, 5, 1, 1 }, ++ { } ++}; ++ ++static struct clk_dyn_rcg ce5_a_clk_src = { ++ .ns_reg[0] = 0x3d84, ++ .ns_reg[1] = 0x3d88, ++ .bank_reg = 0x3d80, ++ .s[0] = { ++ .src_sel_shift = 0, ++ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map, ++ }, ++ .s[1] = { ++ .src_sel_shift = 0, ++ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map, ++ }, ++ .p[0] = { ++ .pre_div_shift = 3, ++ .pre_div_width = 4, ++ }, ++ .p[1] = { ++ .pre_div_shift = 3, ++ .pre_div_width = 4, ++ }, ++ .mux_sel_bit = 0, ++ .freq_tbl = clk_tbl_ce5_a_clk, ++ .clkr = { ++ .enable_reg = 0x3d80, ++ .enable_mask = BIT(1), ++ .hw.init = &(struct clk_init_data){ ++ .name = "ce5_a_clk_src", ++ .parent_names = gcc_pxo_pll8_pll0_pll14_pll18_pll11, ++ .num_parents = 6, ++ .ops = &clk_dyn_rcg_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch ce5_a_clk = { ++ .halt_reg = 0x3c20, ++ .halt_bit = 12, ++ .hwcg_reg = 0x3d8c, ++ .hwcg_bit = 6, ++ .clkr = { ++ .enable_reg = 0x3d8c, ++ .enable_mask = BIT(4), ++ .hw.init = &(struct clk_init_data){ ++ .name = "ce5_a_clk", ++ .parent_names = (const char *[]){ ++ "ce5_a_clk_src", ++ }, ++ .num_parents = 1, ++ .ops = &clk_branch_ops, ++ .flags = CLK_SET_RATE_PARENT, ++ }, ++ }, ++}; ++ ++static const struct freq_tbl clk_tbl_ce5_h_clk[] = { ++ { 160000000, P_PLL0, 5, 1, 1 }, ++ { 213200000, P_PLL11, 5, 1, 1 }, ++ { } ++}; ++ ++static struct clk_dyn_rcg ce5_h_clk_src = { ++ .ns_reg[0] = 0x3c64, ++ .ns_reg[1] = 0x3c68, ++ .bank_reg = 0x3c60, ++ .s[0] = { ++ .src_sel_shift = 0, ++ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map, ++ }, ++ .s[1] = { ++ .src_sel_shift = 0, ++ .parent_map = gcc_pxo_pll8_pll0_pll14_pll18_pll11_map, ++ }, ++ .p[0] = { ++ .pre_div_shift = 3, ++ .pre_div_width = 4, ++ }, ++ .p[1] = { ++ .pre_div_shift = 3, ++ .pre_div_width = 4, ++ }, ++ .mux_sel_bit = 0, ++ .freq_tbl = clk_tbl_ce5_h_clk, ++ .clkr = { ++ .enable_reg = 0x3c60, ++ .enable_mask = BIT(1), ++ .hw.init = &(struct clk_init_data){ ++ .name = "ce5_h_clk_src", ++ .parent_names = gcc_pxo_pll8_pll0_pll14_pll18_pll11, ++ .num_parents = 6, ++ .ops = &clk_dyn_rcg_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch ce5_h_clk = { ++ .halt_reg = 0x3c20, ++ .halt_bit = 11, ++ .hwcg_reg = 0x3c6c, ++ .hwcg_bit = 6, ++ .clkr = { ++ .enable_reg = 0x3c6c, ++ .enable_mask = BIT(4), ++ .hw.init = &(struct clk_init_data){ ++ .name = "ce5_h_clk", ++ .parent_names = (const char *[]){ ++ "ce5_h_clk_src", ++ }, ++ .num_parents = 1, ++ .ops = &clk_branch_ops, ++ .flags = CLK_SET_RATE_PARENT, ++ }, ++ }, ++}; ++ + static struct clk_regmap *gcc_ipq806x_clks[] = { + [PLL0] = &pll0.clkr, + [PLL0_VOTE] = &pll0_vote, +@@ -2764,6 +3002,7 @@ static struct clk_regmap *gcc_ipq806x_cl + [PLL4_VOTE] = &pll4_vote, + [PLL8] = &pll8.clkr, + [PLL8_VOTE] = &pll8_vote, ++ [PLL11] = &pll11.clkr, + [PLL14] = &pll14.clkr, + [PLL14_VOTE] = &pll14_vote, + [PLL18] = &pll18.clkr, +@@ -2878,6 +3117,12 @@ static struct clk_regmap *gcc_ipq806x_cl + [PLL9] = &hfpll0.clkr, + [PLL10] = &hfpll1.clkr, + [PLL12] = &hfpll_l2.clkr, ++ [CE5_A_CLK_SRC] = &ce5_a_clk_src.clkr, ++ [CE5_A_CLK] = &ce5_a_clk.clkr, ++ [CE5_H_CLK_SRC] = &ce5_h_clk_src.clkr, ++ [CE5_H_CLK] = &ce5_h_clk.clkr, ++ [CE5_CORE_CLK_SRC] = &ce5_core_src.clkr, ++ [CE5_CORE_CLK] = &ce5_core_clk.clkr, + }; + + static const struct qcom_reset_map gcc_ipq806x_resets[] = { +@@ -3009,6 +3254,11 @@ static const struct qcom_reset_map gcc_i + [GMAC_CORE3_RESET] = { 0x3cfc, 0 }, + [GMAC_CORE4_RESET] = { 0x3d1c, 0 }, + [GMAC_AHB_RESET] = { 0x3e24, 0 }, ++ [CRYPTO_ENG1_RESET] = { 0x3e00, 0}, ++ [CRYPTO_ENG2_RESET] = { 0x3e04, 0}, ++ [CRYPTO_ENG3_RESET] = { 0x3e08, 0}, ++ [CRYPTO_ENG4_RESET] = { 0x3e0c, 0}, ++ [CRYPTO_AHB_RESET] = { 0x3e10, 0}, + [NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 }, + [NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 }, + [NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 }, +--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h ++++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h +@@ -240,7 +240,7 @@ + #define PLL14 232 + #define PLL14_VOTE 233 + #define PLL18 234 +-#define CE5_SRC 235 ++#define CE5_A_CLK 235 + #define CE5_H_CLK 236 + #define CE5_CORE_CLK 237 + #define CE3_SLEEP_CLK 238 +@@ -283,5 +283,8 @@ + #define EBI2_AON_CLK 281 + #define NSSTCM_CLK_SRC 282 + #define NSSTCM_CLK 283 ++#define CE5_A_CLK_SRC 285 ++#define CE5_H_CLK_SRC 286 ++#define CE5_CORE_CLK_SRC 287 + + #endif +--- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h ++++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h +@@ -163,5 +163,10 @@ + #define NSS_CAL_PRBS_RST_N_RESET 154 + #define NSS_LCKDT_RST_N_RESET 155 + #define NSS_SRDS_N_RESET 156 ++#define CRYPTO_ENG1_RESET 157 ++#define CRYPTO_ENG2_RESET 158 ++#define CRYPTO_ENG3_RESET 159 ++#define CRYPTO_ENG4_RESET 160 ++#define CRYPTO_AHB_RESET 161 + + #endif diff --git a/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch b/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch new file mode 100644 index 0000000000..769686220b --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch @@ -0,0 +1,681 @@ +From cc41a266280cad0b55319e614167c88dff344248 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 22 Feb 2020 16:33:10 +0100 +Subject: [PATCH 1/8] cpufreq: add Krait dedicated scaling driver + +This new driver is based on generic cpufreq-dt driver. +Krait SoCs have 2-4 cpu and one shared L2 cache that can +operate at different frequency based on the maximum cpu clk +across all core. +L2 frequency and voltage are scaled on every frequency change +if needed. On Krait SoCs is present a bug that can cause +transition problem between frequency bin, to workaround this +on more than one transition, the L2 frequency is first set to the +base rate and then to the target rate. +The L2 frequency use the OPP framework and use the opp-level +bindings to link the l2 freq to different cpu freq. This is needed +as the Krait l2 clk are note mapped 1:1 to the core clks and some +of the l2 clk is set based on a range of the cpu clks. If the driver +find a broken config (for example no opp-level set) the l2 scaling is +skipped. + +Signed-off-by: Ansuel Smith +--- + drivers/cpufreq/Kconfig.arm | 14 +- + drivers/cpufreq/Makefile | 2 + + drivers/cpufreq/qcom-cpufreq-krait.c | 589 +++++++++++++++++++++++++++ + 3 files changed, 604 insertions(+), 1 deletion(-) + create mode 100644 drivers/cpufreq/qcom-cpufreq-krait.c + +--- a/drivers/cpufreq/Kconfig.arm ++++ b/drivers/cpufreq/Kconfig.arm +@@ -150,6 +150,18 @@ config ARM_QCOM_CPUFREQ_HW + The driver implements the cpufreq interface for this HW engine. + Say Y if you want to support CPUFreq HW. + ++config ARM_QCOM_CPUFREQ_KRAIT ++ tristate "CPU Frequency scaling support for Krait SoCs" ++ depends on ARCH_QCOM || COMPILE_TEST ++ select PM_OPP ++ select ARM_QCOM_CPUFREQ_NVMEM ++ help ++ This adds the CPUFreq driver for Qualcomm Krait SoC based boards. ++ This scale the cache clk and regulator based on the different cpu ++ clks when scaling the different cores clk. ++ ++ If in doubt, say N. ++ + config ARM_RASPBERRYPI_CPUFREQ + tristate "Raspberry Pi cpufreq support" + depends on CLK_RASPBERRYPI || COMPILE_TEST +@@ -339,4 +351,4 @@ config ARM_PXA2xx_CPUFREQ + help + This add the CPUFreq driver support for Intel PXA2xx SOCs. + +- If in doubt, say N. ++ If in doubt, say N. +\ No newline at end of file +--- a/drivers/cpufreq/Makefile ++++ b/drivers/cpufreq/Makefile +@@ -63,6 +63,7 @@ obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2 + obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o + obj-$(CONFIG_ARM_QCOM_CPUFREQ_HW) += qcom-cpufreq-hw.o + obj-$(CONFIG_ARM_QCOM_CPUFREQ_NVMEM) += qcom-cpufreq-nvmem.o ++obj-$(CONFIG_ARM_QCOM_CPUFREQ_KRAIT) += qcom-cpufreq-krait.o + obj-$(CONFIG_ARM_RASPBERRYPI_CPUFREQ) += raspberrypi-cpufreq.o + obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o + obj-$(CONFIG_ARM_S3C2412_CPUFREQ) += s3c2412-cpufreq.o +@@ -86,6 +87,7 @@ obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += te + obj-$(CONFIG_ARM_TEGRA194_CPUFREQ) += tegra194-cpufreq.o + obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o + obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o ++obj-$(CONFIG_ARM_KRAIT_CPUFREQ) += krait-cpufreq.o + + + ################################################################################## +--- /dev/null ++++ b/drivers/cpufreq/qcom-cpufreq-krait.c +@@ -0,0 +1,603 @@ ++// SPDX-License-Identifier: GPL-2.0 ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "cpufreq-dt.h" ++ ++static struct platform_device *l2_pdev; ++ ++struct private_data { ++ struct opp_table *opp_table; ++ struct device *cpu_dev; ++ const char *reg_name; ++ bool have_static_opps; ++}; ++ ++static int set_target(struct cpufreq_policy *policy, unsigned int index) ++{ ++ struct private_data *priv = policy->driver_data; ++ unsigned long freq = policy->freq_table[index].frequency; ++ unsigned long target_freq = freq * 1000; ++ struct dev_pm_opp *opp; ++ unsigned int level; ++ int cpu, ret; ++ ++ if (l2_pdev) { ++ int policy_cpu = policy->cpu; ++ ++ /* find the max freq across all core */ ++ for_each_present_cpu(cpu) ++ if (cpu != policy_cpu) ++ target_freq = max( ++ target_freq, ++ (unsigned long)cpufreq_quick_get(cpu)); ++ ++ opp = dev_pm_opp_find_freq_exact(priv->cpu_dev, target_freq, ++ true); ++ if (IS_ERR(opp)) { ++ dev_err(&l2_pdev->dev, "failed to find OPP for %ld\n", ++ target_freq); ++ return PTR_ERR(opp); ++ } ++ level = dev_pm_opp_get_level(opp); ++ dev_pm_opp_put(opp); ++ ++ /* ++ * Hardware constraint: ++ * Krait CPU cannot operate at 384MHz with L2 at 1Ghz. ++ * Assume index 0 with the idle freq and level > 0 as ++ * any L2 freq > 384MHz. ++ * Skip CPU freq change in this corner case. ++ */ ++ if (unlikely(index == 0 && level != 0)) { ++ dev_err(priv->cpu_dev, "Krait CPU can't operate at idle freq with L2 at 1GHz"); ++ return -EINVAL; ++ } ++ ++ opp = dev_pm_opp_find_level_exact(&l2_pdev->dev, level); ++ if (IS_ERR(opp)) { ++ dev_err(&l2_pdev->dev, ++ "failed to find level OPP for %d\n", level); ++ return PTR_ERR(opp); ++ } ++ target_freq = dev_pm_opp_get_freq(opp); ++ dev_pm_opp_put(opp); ++ ++ ret = dev_pm_opp_set_rate(&l2_pdev->dev, target_freq); ++ if (ret) ++ return ret; ++ } ++ ++ ret = dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000); ++ if (ret) ++ return ret; ++ ++ arch_set_freq_scale(policy->related_cpus, freq, ++ policy->cpuinfo.max_freq); ++ ++ return 0; ++} ++ ++/* ++ * An earlier version of opp-v1 bindings used to name the regulator ++ * "cpu0-supply", we still need to handle that for backwards compatibility. ++ */ ++static const char *find_supply_name(struct device *dev) ++{ ++ struct device_node *np; ++ struct property *pp; ++ int cpu = dev->id; ++ const char *name = NULL; ++ ++ np = of_node_get(dev->of_node); ++ ++ /* This must be valid for sure */ ++ if (WARN_ON(!np)) ++ return NULL; ++ ++ /* Try "cpu0" for older DTs */ ++ if (!cpu) { ++ pp = of_find_property(np, "cpu0-supply", NULL); ++ if (pp) { ++ name = "cpu0"; ++ goto node_put; ++ } ++ } ++ ++ pp = of_find_property(np, "cpu-supply", NULL); ++ if (pp) { ++ name = "cpu"; ++ goto node_put; ++ } ++ ++ dev_dbg(dev, "no regulator for cpu%d\n", cpu); ++node_put: ++ of_node_put(np); ++ return name; ++} ++ ++static int resources_available(void) ++{ ++ struct device *cpu_dev; ++ struct regulator *cpu_reg; ++ struct clk *cpu_clk; ++ int ret = 0; ++ const char *name; ++ ++ cpu_dev = get_cpu_device(0); ++ if (!cpu_dev) { ++ pr_err("failed to get cpu0 device\n"); ++ return -ENODEV; ++ } ++ ++ cpu_clk = clk_get(cpu_dev, NULL); ++ ret = PTR_ERR_OR_ZERO(cpu_clk); ++ if (ret) { ++ /* ++ * If cpu's clk node is present, but clock is not yet ++ * registered, we should try defering probe. ++ */ ++ if (ret == -EPROBE_DEFER) ++ dev_dbg(cpu_dev, "clock not ready, retry\n"); ++ else ++ dev_err(cpu_dev, "failed to get clock: %d\n", ret); ++ ++ return ret; ++ } ++ ++ clk_put(cpu_clk); ++ ++ name = find_supply_name(cpu_dev); ++ /* Platform doesn't require regulator */ ++ if (!name) ++ return 0; ++ ++ cpu_reg = regulator_get_optional(cpu_dev, name); ++ ret = PTR_ERR_OR_ZERO(cpu_reg); ++ if (ret) { ++ /* ++ * If cpu's regulator supply node is present, but regulator is ++ * not yet registered, we should try defering probe. ++ */ ++ if (ret == -EPROBE_DEFER) ++ dev_dbg(cpu_dev, "cpu0 regulator not ready, retry\n"); ++ else ++ dev_dbg(cpu_dev, "no regulator for cpu0: %d\n", ret); ++ ++ return ret; ++ } ++ ++ regulator_put(cpu_reg); ++ return 0; ++} ++ ++static int cpufreq_init(struct cpufreq_policy *policy) ++{ ++ struct cpufreq_frequency_table *freq_table; ++ struct opp_table *opp_table = NULL; ++ unsigned int transition_latency; ++ struct private_data *priv; ++ struct device *cpu_dev; ++ bool fallback = false; ++ struct clk *cpu_clk; ++ const char *name; ++ int ret; ++ ++ cpu_dev = get_cpu_device(policy->cpu); ++ if (!cpu_dev) { ++ pr_err("failed to get cpu%d device\n", policy->cpu); ++ return -ENODEV; ++ } ++ ++ cpu_clk = clk_get(cpu_dev, NULL); ++ if (IS_ERR(cpu_clk)) { ++ ret = PTR_ERR(cpu_clk); ++ dev_err(cpu_dev, "%s: failed to get clk: %d\n", __func__, ret); ++ return ret; ++ } ++ ++ /* Get OPP-sharing information from "operating-points-v2" bindings */ ++ ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, policy->cpus); ++ if (ret) { ++ if (ret != -ENOENT) ++ goto out_put_clk; ++ ++ /* ++ * operating-points-v2 not supported, fallback to old method of ++ * finding shared-OPPs for backward compatibility if the ++ * platform hasn't set sharing CPUs. ++ */ ++ if (dev_pm_opp_get_sharing_cpus(cpu_dev, policy->cpus)) ++ fallback = true; ++ } ++ ++ /* ++ * OPP layer will be taking care of regulators now, but it needs to know ++ * the name of the regulator first. ++ */ ++ name = find_supply_name(cpu_dev); ++ if (name) { ++ opp_table = dev_pm_opp_set_regulators(cpu_dev, &name, 1); ++ if (IS_ERR(opp_table)) { ++ ret = PTR_ERR(opp_table); ++ dev_err(cpu_dev, ++ "Failed to set regulator for cpu%d: %d\n", ++ policy->cpu, ret); ++ goto out_put_clk; ++ } ++ } ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) { ++ ret = -ENOMEM; ++ goto out_put_regulator; ++ } ++ ++ priv->reg_name = name; ++ priv->opp_table = opp_table; ++ ++ /* ++ * Initialize OPP tables for all policy->cpus. They will be shared by ++ * all CPUs which have marked their CPUs shared with OPP bindings. ++ * ++ * For platforms not using operating-points-v2 bindings, we do this ++ * before updating policy->cpus. Otherwise, we will end up creating ++ * duplicate OPPs for policy->cpus. ++ * ++ * OPPs might be populated at runtime, don't check for error here ++ */ ++ if (!dev_pm_opp_of_cpumask_add_table(policy->cpus)) ++ priv->have_static_opps = true; ++ ++ /* ++ * But we need OPP table to function so if it is not there let's ++ * give platform code chance to provide it for us. ++ */ ++ ret = dev_pm_opp_get_opp_count(cpu_dev); ++ if (ret <= 0) { ++ dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n"); ++ ret = -EPROBE_DEFER; ++ goto out_free_opp; ++ } ++ ++ if (fallback) { ++ cpumask_setall(policy->cpus); ++ ++ /* ++ * OPP tables are initialized only for policy->cpu, do it for ++ * others as well. ++ */ ++ ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus); ++ if (ret) ++ dev_err(cpu_dev, ++ "%s: failed to mark OPPs as shared: %d\n", ++ __func__, ret); ++ } ++ ++ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); ++ if (ret) { ++ dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); ++ goto out_free_opp; ++ } ++ ++ priv->cpu_dev = cpu_dev; ++ ++ policy->driver_data = priv; ++ policy->clk = cpu_clk; ++ policy->freq_table = freq_table; ++ ++ policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000; ++ ++ transition_latency = dev_pm_opp_get_max_transition_latency(cpu_dev); ++ if (!transition_latency) ++ transition_latency = CPUFREQ_ETERNAL; ++ ++ policy->cpuinfo.transition_latency = transition_latency; ++ policy->dvfs_possible_from_any_cpu = true; ++ ++ dev_pm_opp_of_register_em(cpu_dev, policy->cpus); ++ ++ return 0; ++ ++out_free_opp: ++ if (priv->have_static_opps) ++ dev_pm_opp_of_cpumask_remove_table(policy->cpus); ++ kfree(priv); ++out_put_regulator: ++ if (name) ++ dev_pm_opp_put_regulators(opp_table); ++out_put_clk: ++ clk_put(cpu_clk); ++ ++ return ret; ++} ++ ++static int cpufreq_online(struct cpufreq_policy *policy) ++{ ++ /* We did light-weight tear down earlier, nothing to do here */ ++ return 0; ++} ++ ++static int cpufreq_offline(struct cpufreq_policy *policy) ++{ ++ /* ++ * Preserve policy->driver_data and don't free resources on light-weight ++ * tear down. ++ */ ++ return 0; ++} ++ ++static int cpufreq_exit(struct cpufreq_policy *policy) ++{ ++ struct private_data *priv = policy->driver_data; ++ ++ dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); ++ if (priv->have_static_opps) ++ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); ++ if (priv->reg_name) ++ dev_pm_opp_put_regulators(priv->opp_table); ++ ++ clk_put(policy->clk); ++ kfree(priv); ++ ++ return 0; ++} ++ ++static struct cpufreq_driver krait_cpufreq_driver = { ++ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK | ++ CPUFREQ_IS_COOLING_DEV, ++ .verify = cpufreq_generic_frequency_table_verify, ++ .target_index = set_target, ++ .get = cpufreq_generic_get, ++ .init = cpufreq_init, ++ .exit = cpufreq_exit, ++ .online = cpufreq_online, ++ .offline = cpufreq_offline, ++ .name = "krait-cpufreq", ++ .suspend = cpufreq_generic_suspend, ++}; ++ ++struct krait_data { ++ unsigned long idle_freq; ++ bool regulator_enabled; ++}; ++ ++static int krait_cache_set_opp(struct dev_pm_set_opp_data *data) ++{ ++ unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate; ++ struct dev_pm_opp_supply *supply = &data->new_opp.supplies[0]; ++ struct regulator *reg = data->regulators[0]; ++ struct clk *clk = data->clk; ++ struct krait_data *kdata; ++ unsigned long idle_freq; ++ int ret; ++ ++ kdata = (struct krait_data *)dev_get_drvdata(data->dev); ++ idle_freq = kdata->idle_freq; ++ ++ /* Scaling up? Scale voltage before frequency */ ++ if (freq >= old_freq) { ++ ret = regulator_set_voltage_triplet(reg, supply->u_volt_min, ++ supply->u_volt, ++ supply->u_volt_max); ++ if (ret) ++ goto exit; ++ } ++ ++ /* ++ * Set to idle bin if switching from normal to high bin ++ * or vice versa. It has been notice that a bug is triggered ++ * in cache scaling when more than one bin is scaled, to fix ++ * this we first need to transition to the base rate and then ++ * to target rate ++ */ ++ if (likely(freq != idle_freq && old_freq != idle_freq)) { ++ ret = clk_set_rate(clk, idle_freq); ++ if (ret) ++ goto exit; ++ } ++ ++ ret = clk_set_rate(clk, freq); ++ if (ret) ++ goto exit; ++ ++ /* Scaling down? Scale voltage after frequency */ ++ if (freq < old_freq) { ++ ret = regulator_set_voltage_triplet(reg, supply->u_volt_min, ++ supply->u_volt, ++ supply->u_volt_max); ++ } ++ ++ if (unlikely(!kdata->regulator_enabled)) { ++ ret = regulator_enable(reg); ++ if (ret < 0) ++ dev_warn(data->dev, "Failed to enable regulator: %d", ret); ++ else ++ kdata->regulator_enabled = true; ++ } ++ ++exit: ++ return ret; ++}; ++ ++static int krait_cache_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct krait_data *data; ++ struct opp_table *table; ++ struct dev_pm_opp *opp; ++ struct device *cpu_dev; ++ int ret; ++ ++ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ table = dev_pm_opp_set_regulators(dev, (const char *[]){ "l2" }, 1); ++ if (IS_ERR(table)) { ++ ret = PTR_ERR(table); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "failed to set regulators %d\n", ret); ++ ++ return ret; ++ } ++ ++ ret = PTR_ERR_OR_ZERO( ++ dev_pm_opp_register_set_opp_helper(dev, krait_cache_set_opp)); ++ if (ret) ++ return ret; ++ ++ ret = dev_pm_opp_of_add_table(dev); ++ if (ret) { ++ dev_err(dev, "failed to parse L2 freq thresholds\n"); ++ return ret; ++ } ++ ++ opp = dev_pm_opp_find_freq_ceil(dev, &data->idle_freq); ++ dev_pm_opp_put(opp); ++ ++ /* ++ * Check opp-level configuration ++ * At least 2 level must be set or the cache will always be scaled ++ * the idle freq causing some performance problem ++ * ++ * In case of invalid configuration, the l2 scaling is skipped ++ */ ++ cpu_dev = get_cpu_device(0); ++ if (!cpu_dev) { ++ pr_err("failed to get cpu0 device\n"); ++ return -ENODEV; ++ } ++ ++ /* ++ * Check if we have at least opp-level 1, 0 should always be set to ++ * the idle freq ++ */ ++ opp = dev_pm_opp_find_level_exact(dev, 1); ++ if (IS_ERR(opp)) { ++ dev_err(dev, ++ "Invalid configuration found of l2 opp. Can't find opp-level 1"); ++ goto invalid_conf; ++ } ++ dev_pm_opp_put(opp); ++ ++ /* ++ * Check if we have at least opp-level 1 in the cpu opp, 0 should always ++ * be set to the idle freq ++ */ ++ opp = dev_pm_opp_find_level_exact(cpu_dev, 1); ++ if (IS_ERR(opp)) { ++ dev_err(dev, ++ "Invalid configuration found of cpu opp. Can't find opp-level 1"); ++ goto invalid_conf; ++ } ++ dev_pm_opp_put(opp); ++ ++ platform_set_drvdata(pdev, data); ++ ++ /* The l2 scaling is enabled by linking the cpufreq driver */ ++ l2_pdev = pdev; ++ ++ return 0; ++ ++invalid_conf: ++ dev_pm_opp_remove_table(dev); ++ dev_pm_opp_put_regulators(table); ++ dev_pm_opp_unregister_set_opp_helper(table); ++ ++ return -EINVAL; ++}; ++ ++static int krait_cache_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct opp_table *table = dev_pm_opp_get_opp_table(dev); ++ ++ dev_pm_opp_remove_table(dev); ++ dev_pm_opp_put_regulators(table); ++ dev_pm_opp_unregister_set_opp_helper(table); ++ ++ return 0; ++}; ++ ++static const struct of_device_id krait_cache_match_table[] = { ++ { .compatible = "qcom,krait-cache" }, ++ {} ++}; ++ ++static struct platform_driver krait_cache_driver = { ++ .driver = { ++ .name = "krait-cache", ++ .of_match_table = krait_cache_match_table, ++ }, ++ .probe = krait_cache_probe, ++ .remove = krait_cache_remove, ++}; ++module_platform_driver(krait_cache_driver); ++ ++static int krait_cpufreq_probe(struct platform_device *pdev) ++{ ++ struct cpufreq_dt_platform_data *data = dev_get_platdata(&pdev->dev); ++ int ret; ++ ++ /* ++ * All per-cluster (CPUs sharing clock/voltages) initialization is done ++ * from ->init(). In probe(), we just need to make sure that clk and ++ * regulators are available. Else defer probe and retry. ++ * ++ * FIXME: Is checking this only for CPU0 sufficient ? ++ */ ++ ret = resources_available(); ++ if (ret) ++ return ret; ++ ++ if (data) { ++ if (data->have_governor_per_policy) ++ krait_cpufreq_driver.flags |= ++ CPUFREQ_HAVE_GOVERNOR_PER_POLICY; ++ ++ krait_cpufreq_driver.resume = data->resume; ++ if (data->suspend) ++ krait_cpufreq_driver.suspend = data->suspend; ++ } ++ ++ ret = cpufreq_register_driver(&krait_cpufreq_driver); ++ if (ret) ++ dev_err(&pdev->dev, "failed register driver: %d\n", ret); ++ ++ return ret; ++} ++ ++static int krait_cpufreq_remove(struct platform_device *pdev) ++{ ++ cpufreq_unregister_driver(&krait_cpufreq_driver); ++ return 0; ++} ++ ++static struct platform_driver krait_cpufreq_platdrv = { ++ .driver = { ++ .name = "krait-cpufreq", ++ }, ++ .probe = krait_cpufreq_probe, ++ .remove = krait_cpufreq_remove, ++}; ++module_platform_driver(krait_cpufreq_platdrv); ++ ++MODULE_ALIAS("platform:krait-cpufreq"); ++MODULE_AUTHOR("Ansuel Smith "); ++MODULE_DESCRIPTION("Dedicated Krait SoC cpufreq driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/ipq806x/patches-5.15/098-2-Documentation-cpufreq-add-qcom-krait-cpufreq-binding.patch b/target/linux/ipq806x/patches-5.15/098-2-Documentation-cpufreq-add-qcom-krait-cpufreq-binding.patch new file mode 100644 index 0000000000..316e18b790 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/098-2-Documentation-cpufreq-add-qcom-krait-cpufreq-binding.patch @@ -0,0 +1,237 @@ +From c9ecd920324a647bf1f2b47f771c8f599cc7b551 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 22 Feb 2020 18:02:17 +0100 +Subject: [PATCH 2/8] Documentation: cpufreq: add qcom,krait-cache bindings + +Document dedicated cpufreq for Krait CPUs. + +Signed-off-by: Ansuel Smith +--- + .../bindings/cpufreq/qcom-cpufreq-krait.yaml | 221 ++++++++++++++++++ + 1 file changed, 221 insertions(+) + create mode 100644 Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-krait.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-krait.yaml +@@ -0,0 +1,221 @@ ++# SPDX-License-Identifier: GPL-2.0 ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/cpufreq/qcom-cpufreq-krait.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: CPU Frequency scaling driver for Krait SoCs ++ ++maintainers: ++ - Ansuel Smith ++ ++description: | ++ The krait cpufreq driver is a dedicated frequency scaling driver ++ based on cpufreq-dt generic driver that scale L2 cache and the ++ cores. TEST ++ ++ The L2 cache is scaled based on the max clk across all cores and ++ the clock is decided based on the opp-level set in the device tree. ++ ++ Different core freq can be linked to a specific l2 freq and the driver ++ on frequency change will scale the core and the l2 clk based of the ++ linked freq. ++ ++ On Krait SoC is present a bug and on every L2 clk change the driver ++ needs to set the clk to the idle freq before changing it to the new value. ++ ++ This requires the qcom cpufreq nvmem driver to parse the different opp ++ core clk and an additional opp table for the l2 scaling. ++ ++ If the driver detect broken config (for example missing opp-level) the ++ cpufreq driver skips the l2 scaling ++ ++ Referring to this example opp-level can be used to link a range of cpu freq ++ to a specific l2 freq: ++ cpu opp freq 384000000 has opp-level 0 ++ l2 opp freq 384000000 has opp-level 0 ++ The driver will scale l2 to 384000000 ++ ++ cpu opp freq 600000000-1000000000 has opp-level 1 ++ l2 opp freq 1000000000 has opp-level 1 ++ The driver will scale l2 to 1000000000 ++ ++allOf: ++ - $ref: /schemas/cache-controller.yaml# ++ ++select: ++ properties: ++ compatible: ++ items: ++ - enum: ++ - qcom,krait-cache ++ ++ required: ++ - compatible ++ ++properties: ++ compatible: ++ items: ++ - const: qcom,krait-cache ++ - const: cache ++ ++ cache-level: ++ const: 2 ++ ++ clocks: ++ maxItems: 1 ++ ++ clock-names: ++ const: l2 ++ ++ l2-supply: true ++ ++ operating-points-v2: true ++ ++required: ++ - compatible ++ - cache-level ++ - clocks ++ - clock-names ++ - l2-supply ++ - operating-points-v2 ++ ++additionalProperties: false ++ ++examples: ++ - | ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ compatible = "qcom,krait"; ++ enable-method = "qcom,kpss-acc-v1"; ++ device_type = "cpu"; ++ reg = <0>; ++ next-level-cache = <&L2>; ++ qcom,acc = <&acc0>; ++ qcom,saw = <&saw0>; ++ clocks = <&kraitcc 0>, <&kraitcc 4>; ++ clock-names = "cpu", "l2"; ++ clock-latency = <100000>; ++ cpu-supply = <&smb208_s2a>; ++ operating-points-v2 = <&opp_table0>; ++ voltage-tolerance = <5>; ++ cooling-min-state = <0>; ++ cooling-max-state = <10>; ++ #cooling-cells = <2>; ++ cpu-idle-states = <&CPU_SPC>; ++ }; ++ ++ /* ... */ ++ ++ }; ++ ++ opp_table0: opp_table0 { ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&speedbin_efuse>; ++ ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1000000>; ++ opp-microvolt-speed0-pvs1-v0 = <925000>; ++ opp-microvolt-speed0-pvs2-v0 = <875000>; ++ opp-microvolt-speed0-pvs3-v0 = <800000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <0>; ++ }; ++ ++ opp-600000000 { ++ opp-hz = /bits/ 64 <600000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1050000>; ++ opp-microvolt-speed0-pvs1-v0 = <975000>; ++ opp-microvolt-speed0-pvs2-v0 = <925000>; ++ opp-microvolt-speed0-pvs3-v0 = <850000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-800000000 { ++ opp-hz = /bits/ 64 <800000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1100000>; ++ opp-microvolt-speed0-pvs1-v0 = <1025000>; ++ opp-microvolt-speed0-pvs2-v0 = <995000>; ++ opp-microvolt-speed0-pvs3-v0 = <900000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1150000>; ++ opp-microvolt-speed0-pvs1-v0 = <1075000>; ++ opp-microvolt-speed0-pvs2-v0 = <1025000>; ++ opp-microvolt-speed0-pvs3-v0 = <950000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1200000>; ++ opp-microvolt-speed0-pvs1-v0 = <1125000>; ++ opp-microvolt-speed0-pvs2-v0 = <1075000>; ++ opp-microvolt-speed0-pvs3-v0 = <1000000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <2>; ++ }; ++ ++ opp-1400000000 { ++ opp-hz = /bits/ 64 <1400000000>; ++ opp-microvolt-speed0-pvs0-v0 = <1250000>; ++ opp-microvolt-speed0-pvs1-v0 = <1175000>; ++ opp-microvolt-speed0-pvs2-v0 = <1125000>; ++ opp-microvolt-speed0-pvs3-v0 = <1050000>; ++ opp-supported-hw = <0x1>; ++ clock-latency-ns = <100000>; ++ opp-level = <2>; ++ }; ++ }; ++ ++ opp_table_l2: opp_table_l2 { ++ compatible = "operating-points-v2"; ++ ++ opp-384000000 { ++ opp-hz = /bits/ 64 <384000000>; ++ opp-microvolt = <1100000>; ++ clock-latency-ns = <100000>; ++ opp-level = <0>; ++ }; ++ opp-1000000000 { ++ opp-hz = /bits/ 64 <1000000000>; ++ opp-microvolt = <1100000>; ++ clock-latency-ns = <100000>; ++ opp-level = <1>; ++ }; ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1150000>; ++ clock-latency-ns = <100000>; ++ opp-level = <2>; ++ }; ++ }; ++ ++ soc { ++ L2: l2-cache { ++ compatible = "qcom,krait-cache", "cache"; ++ cache-level = <2>; ++ ++ clocks = <&kraitcc 4>; ++ clock-names = "l2"; ++ l2-supply = <&smb208_s1a>; ++ operating-points-v2 = <&opp_table_l2>; ++ }; ++ }; ++ ++... diff --git a/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch b/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch new file mode 100644 index 0000000000..8ce3f062cf --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch @@ -0,0 +1,243 @@ +--- a/drivers/clk/qcom/Makefile ++++ b/drivers/clk/qcom/Makefile +@@ -15,6 +15,7 @@ clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-k + clk-qcom-y += clk-hfpll.o + clk-qcom-y += reset.o + clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o ++clk-qcom-y += fab_scaling.o + + # Keep alphabetically sorted by config + obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o +--- /dev/null ++++ b/drivers/clk/qcom/fab_scaling.c +@@ -0,0 +1,172 @@ ++/* ++ * Copyright (c) 2015, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct qcom_fab_scaling_data { ++ u32 fab_freq_high; ++ u32 fab_freq_nominal; ++ u32 cpu_freq_threshold; ++ struct clk *apps_fab_clk; ++ struct clk *ddr_fab_clk; ++}; ++ ++static struct qcom_fab_scaling_data *drv_data; ++ ++int scale_fabrics(unsigned long max_cpu_freq) ++{ ++ struct clk *apps_fab_clk = drv_data->apps_fab_clk, ++ *ddr_fab_clk = drv_data->ddr_fab_clk; ++ unsigned long target_freq, cur_freq; ++ int ret; ++ ++ /* Skip fab scaling if the driver is not ready */ ++ if (!apps_fab_clk || !ddr_fab_clk) ++ return 0; ++ ++ if (max_cpu_freq > drv_data->cpu_freq_threshold) ++ target_freq = drv_data->fab_freq_high; ++ else ++ target_freq = drv_data->fab_freq_nominal; ++ ++ cur_freq = clk_get_rate(ddr_fab_clk); ++ ++ if (target_freq != cur_freq) { ++ ret = clk_set_rate(apps_fab_clk, target_freq); ++ if (ret) ++ return ret; ++ ret = clk_set_rate(ddr_fab_clk, target_freq); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(scale_fabrics); ++ ++static int ipq806x_fab_scaling_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct clk *apps_fab_clk, *ddr_fab_clk; ++ int ret; ++ ++ if (!np) ++ return -ENODEV; ++ ++ drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); ++ if (!drv_data) ++ return -ENOMEM; ++ ++ if (of_property_read_u32(np, "fab_freq_high", &drv_data->fab_freq_high)) { ++ pr_err("FABRICS turbo freq not found. Using defaults...\n"); ++ drv_data->fab_freq_high = 533000000; ++ } ++ ++ if (of_property_read_u32(np, "fab_freq_nominal", &drv_data->fab_freq_nominal)) { ++ pr_err("FABRICS nominal freq not found. Using defaults...\n"); ++ drv_data->fab_freq_nominal = 400000000; ++ } ++ ++ if (of_property_read_u32(np, "cpu_freq_threshold", &drv_data->cpu_freq_threshold)) { ++ pr_err("FABRICS cpu freq threshold not found. Using defaults...\n"); ++ drv_data->cpu_freq_threshold = 1000000000; ++ } ++ ++ apps_fab_clk = devm_clk_get(&pdev->dev, "apps-fab-clk"); ++ ret = PTR_ERR_OR_ZERO(apps_fab_clk); ++ if (ret) { ++ /* ++ * If apps fab clk node is present, but clock is not yet ++ * registered, we should try defering probe. ++ */ ++ if (ret != -EPROBE_DEFER) { ++ pr_err("Failed to get APPS FABRIC clock: %d\n", ret); ++ ret = -ENODEV; ++ } ++ goto err; ++ } ++ ++ clk_prepare_enable(apps_fab_clk); ++ clk_set_rate(apps_fab_clk, drv_data->fab_freq_high); ++ drv_data->apps_fab_clk = apps_fab_clk; ++ ++ ddr_fab_clk = devm_clk_get(&pdev->dev, "ddr-fab-clk"); ++ ret = PTR_ERR_OR_ZERO(ddr_fab_clk); ++ if (ret) { ++ /* ++ * If ddr fab clk node is present, but clock is not yet ++ * registered, we should try defering probe. ++ */ ++ if (ret != -EPROBE_DEFER) { ++ pr_err("Failed to get DDR FABRIC clock: %d\n", ret); ++ ddr_fab_clk = NULL; ++ ret = -ENODEV; ++ } ++ goto err; ++ } ++ ++ clk_prepare_enable(ddr_fab_clk); ++ clk_set_rate(ddr_fab_clk, drv_data->fab_freq_high); ++ drv_data->ddr_fab_clk = ddr_fab_clk; ++ ++ return 0; ++err: ++ kfree(drv_data); ++ return ret; ++} ++ ++static int ipq806x_fab_scaling_remove(struct platform_device *pdev) ++{ ++ kfree(drv_data); ++ return 0; ++} ++ ++static const struct of_device_id fab_scaling_ipq806x_match_table[] = { ++ { .compatible = "qcom,fab-scaling" }, ++ { } ++}; ++ ++static struct platform_driver fab_scaling_ipq806x_driver = { ++ .probe = ipq806x_fab_scaling_probe, ++ .remove = ipq806x_fab_scaling_remove, ++ .driver = { ++ .name = "fab-scaling", ++ .of_match_table = fab_scaling_ipq806x_match_table, ++ }, ++}; ++ ++static int __init fab_scaling_ipq806x_init(void) ++{ ++ return platform_driver_register(&fab_scaling_ipq806x_driver); ++} ++late_initcall(fab_scaling_ipq806x_init); ++ ++static void __exit fab_scaling_ipq806x_exit(void) ++{ ++ platform_driver_unregister(&fab_scaling_ipq806x_driver); ++} ++module_exit(fab_scaling_ipq806x_exit); +--- /dev/null ++++ b/include/linux/fab_scaling.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2015, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++ ++#ifndef __FAB_SCALING_H ++#define __FAB_SCALING_H ++ ++/** ++ * scale_fabrics - Scale DDR and APPS FABRICS ++ * ++ * This function monitors all the registered clocks and does APPS ++ * and DDR FABRIC scaling based on the idle frequencies with which ++ * it was registered. ++ * ++ */ ++int scale_fabrics(unsigned long max_cpu_freq); ++ ++#endif +--- a/drivers/cpufreq/qcom-cpufreq-krait.c ++++ b/drivers/cpufreq/qcom-cpufreq-krait.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + #include "cpufreq-dt.h" + +@@ -68,6 +69,13 @@ static int set_target(struct cpufreq_pol + return -EINVAL; + } + ++ /* ++ * Scale fabrics with max freq across all cores ++ */ ++ ret = scale_fabrics(target_freq); ++ if (ret) ++ return ret; ++ + opp = dev_pm_opp_find_level_exact(&l2_pdev->dev, level); + if (IS_ERR(opp)) { + dev_err(&l2_pdev->dev, diff --git a/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch b/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch new file mode 100644 index 0000000000..6106dfb8dc --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch @@ -0,0 +1,239 @@ +From 6949d651e3be3ebbfedb6bbd5b541cfda6ee58a9 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 10 Feb 2021 10:40:17 +0100 +Subject: [PATCH 1/2] mtd: nand: raw: qcom_nandc: add boot_layout_mode support + +ipq806x nand have a special ecc configuration for the boot pages. The +use of the non-boot pages configuration on boot pages cause I/O error +and can cause broken data written to the nand. Add support for this +special configuration if the page to be read/write is in the size of the +boot pages set by the dts. + +Signed-off-by: Ansuel Smith +--- + drivers/mtd/nand/raw/qcom_nandc.c | 82 +++++++++++++++++++++++++++++-- + 1 file changed, 77 insertions(+), 5 deletions(-) + +--- a/drivers/mtd/nand/raw/qcom_nandc.c ++++ b/drivers/mtd/nand/raw/qcom_nandc.c +@@ -159,6 +159,11 @@ + /* NAND_CTRL bits */ + #define BAM_MODE_EN BIT(0) + ++ ++#define UD_SIZE_BYTES_MASK (0x3ff << UD_SIZE_BYTES) ++#define SPARE_SIZE_BYTES_MASK (0xf << SPARE_SIZE_BYTES) ++#define ECC_NUM_DATA_BYTES_MASK (0x3ff << ECC_NUM_DATA_BYTES) ++ + /* + * the NAND controller performs reads/writes with ECC in 516 byte chunks. + * the driver calls the chunks 'step' or 'codeword' interchangeably +@@ -430,6 +435,13 @@ struct qcom_nand_controller { + * @cfg0, cfg1, cfg0_raw..: NANDc register configurations needed for + * ecc/non-ecc mode for the current nand flash + * device ++ * ++ * @boot_pages_conf: keep track of the current ecc configuration used by ++ * the driver for read/write operation. (boot pages ++ * have different configuration than normal page) ++ * @boot_pages: number of pages starting from 0 used as boot pages ++ * where the driver will use the boot pages ecc ++ * configuration for read/write operation + */ + struct qcom_nand_host { + struct nand_chip chip; +@@ -452,6 +464,9 @@ struct qcom_nand_host { + u32 ecc_bch_cfg; + u32 clrflashstatus; + u32 clrreadstatus; ++ ++ bool boot_pages_conf; ++ u32 boot_pages; + }; + + /* +@@ -460,12 +475,14 @@ struct qcom_nand_host { + * @ecc_modes - ecc mode for NAND + * @is_bam - whether NAND controller is using BAM + * @is_qpic - whether NAND CTRL is part of qpic IP ++ * @has_boot_pages - whether NAND has different ecc settings for boot pages + * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset + */ + struct qcom_nandc_props { + u32 ecc_modes; + bool is_bam; + bool is_qpic; ++ bool has_boot_pages; + u32 dev_cmd_reg_start; + }; + +@@ -1604,7 +1621,7 @@ qcom_nandc_read_cw_raw(struct mtd_info * + data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); + oob_size1 = host->bbm_size; + +- if (cw == (ecc->steps - 1)) { ++ if (cw == (ecc->steps - 1) && !host->boot_pages_conf) { + data_size2 = ecc->size - data_size1 - + ((ecc->steps - 1) * 4); + oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw + +@@ -1685,7 +1702,7 @@ check_for_erased_page(struct qcom_nand_h + } + + for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { +- if (cw == (ecc->steps - 1)) { ++ if (cw == (ecc->steps - 1) && !host->boot_pages_conf) { + data_size = ecc->size - ((ecc->steps - 1) * 4); + oob_size = (ecc->steps * 4) + host->ecc_bytes_hw; + } else { +@@ -1844,7 +1861,7 @@ static int read_page_ecc(struct qcom_nan + for (i = 0; i < ecc->steps; i++) { + int data_size, oob_size; + +- if (i == (ecc->steps - 1)) { ++ if (i == (ecc->steps - 1) && !host->boot_pages_conf) { + data_size = ecc->size - ((ecc->steps - 1) << 2); + oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + + host->spare_bytes; +@@ -1941,6 +1958,30 @@ static int copy_last_cw(struct qcom_nand + return ret; + } + ++static void ++check_boot_pages_conf(struct qcom_nand_host *host, int page) ++{ ++ bool boot_pages_conf = page < host->boot_pages; ++ ++ /* Skip conf write if we are already in the correct mode */ ++ if (boot_pages_conf != host->boot_pages_conf) { ++ host->boot_pages_conf = boot_pages_conf; ++ ++ host->cw_data = boot_pages_conf ? 512 : 516; ++ host->spare_bytes = host->cw_size - host->ecc_bytes_hw - ++ host->bbm_size - host->cw_data; ++ ++ host->cfg0 &= ~(SPARE_SIZE_BYTES_MASK | UD_SIZE_BYTES_MASK); ++ host->cfg0 |= host->spare_bytes << SPARE_SIZE_BYTES | ++ host->cw_data << UD_SIZE_BYTES; ++ ++ host->ecc_bch_cfg &= ~ECC_NUM_DATA_BYTES_MASK; ++ host->ecc_bch_cfg |= host->cw_data << ECC_NUM_DATA_BYTES; ++ host->ecc_buf_cfg = (boot_pages_conf ? 0x1ff : 0x203) << ++ NUM_STEPS; ++ } ++} ++ + /* implements ecc->read_page() */ + static int qcom_nandc_read_page(struct nand_chip *chip, uint8_t *buf, + int oob_required, int page) +@@ -1949,6 +1990,9 @@ static int qcom_nandc_read_page(struct n + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + u8 *data_buf, *oob_buf = NULL; + ++ if (host->boot_pages) ++ check_boot_pages_conf(host, page); ++ + nand_read_page_op(chip, page, 0, NULL, 0); + data_buf = buf; + oob_buf = oob_required ? chip->oob_poi : NULL; +@@ -1968,6 +2012,9 @@ static int qcom_nandc_read_page_raw(stru + int cw, ret; + u8 *data_buf = buf, *oob_buf = chip->oob_poi; + ++ if (host->boot_pages) ++ check_boot_pages_conf(host, page); ++ + for (cw = 0; cw < ecc->steps; cw++) { + ret = qcom_nandc_read_cw_raw(mtd, chip, data_buf, oob_buf, + page, cw); +@@ -1988,6 +2035,9 @@ static int qcom_nandc_read_oob(struct na + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + struct nand_ecc_ctrl *ecc = &chip->ecc; + ++ if (host->boot_pages) ++ check_boot_pages_conf(host, page); ++ + clear_read_regs(nandc); + clear_bam_transaction(nandc); + +@@ -2008,6 +2058,9 @@ static int qcom_nandc_write_page(struct + u8 *data_buf, *oob_buf; + int i, ret; + ++ if (host->boot_pages) ++ check_boot_pages_conf(host, page); ++ + nand_prog_page_begin_op(chip, page, 0, NULL, 0); + + clear_read_regs(nandc); +@@ -2023,7 +2076,7 @@ static int qcom_nandc_write_page(struct + for (i = 0; i < ecc->steps; i++) { + int data_size, oob_size; + +- if (i == (ecc->steps - 1)) { ++ if (i == (ecc->steps - 1) && !host->boot_pages_conf) { + data_size = ecc->size - ((ecc->steps - 1) << 2); + oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + + host->spare_bytes; +@@ -2080,6 +2133,9 @@ static int qcom_nandc_write_page_raw(str + u8 *data_buf, *oob_buf; + int i, ret; + ++ if (host->boot_pages) ++ check_boot_pages_conf(host, page); ++ + nand_prog_page_begin_op(chip, page, 0, NULL, 0); + clear_read_regs(nandc); + clear_bam_transaction(nandc); +@@ -2098,7 +2154,7 @@ static int qcom_nandc_write_page_raw(str + data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); + oob_size1 = host->bbm_size; + +- if (i == (ecc->steps - 1)) { ++ if (i == (ecc->steps - 1) && !host->boot_pages_conf) { + data_size2 = ecc->size - data_size1 - + ((ecc->steps - 1) << 2); + oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + +@@ -2158,6 +2214,9 @@ static int qcom_nandc_write_oob(struct n + int data_size, oob_size; + int ret; + ++ if (host->boot_pages) ++ check_boot_pages_conf(host, page); ++ + host->use_ecc = true; + clear_bam_transaction(nandc); + +@@ -2806,6 +2865,7 @@ static int qcom_nand_host_init_and_regis + struct nand_chip *chip = &host->chip; + struct mtd_info *mtd = nand_to_mtd(chip); + struct device *dev = nandc->dev; ++ u32 boot_pages_size; + int ret; + + ret = of_property_read_u32(dn, "reg", &host->cs); +@@ -2866,6 +2926,17 @@ static int qcom_nand_host_init_and_regis + if (ret) + nand_cleanup(chip); + ++ if (nandc->props->has_boot_pages && ++ of_property_read_bool(dn, "nand-is-boot-medium")) { ++ ret = of_property_read_u32(dn, "qcom,boot_pages_size", ++ &boot_pages_size); ++ if (ret) ++ dev_warn(dev, "can't get boot pages size"); ++ else ++ /* Convert size to nand pages */ ++ host->boot_pages = boot_pages_size / mtd->writesize; ++ } ++ + return ret; + } + +@@ -3032,6 +3103,7 @@ static int qcom_nandc_remove(struct plat + static const struct qcom_nandc_props ipq806x_nandc_props = { + .ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT), + .is_bam = false, ++ .has_boot_pages = true, + .dev_cmd_reg_start = 0x0, + }; + diff --git a/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch b/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch new file mode 100644 index 0000000000..79036cb057 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch @@ -0,0 +1,42 @@ +From 6fb003a7a117f97a35b078ba726c84adeae29c4c Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 10 Feb 2021 10:54:19 +0100 +Subject: [PATCH 2/2] Documentation: devicetree: mtd: qcom_nandc: document + qcom,boot_layout_size binding + +Document new qcom,boot_layout_size binding used to apply special +read/write confituation to boots partitions. + +Signed-off-by: Ansuel Smith +--- + Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt ++++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt +@@ -52,6 +52,15 @@ Optional properties: + be used according to chip requirement and available + OOB size. + ++EBI2 specific properties: ++- nand-is-boot-medium: nand contains boot partitions and different ecc configuration ++ should be used for these partitions. ++- qcom,boot_pages_size: should contain the size of the total boot partitions ++ where the boot layout read/write specific configuration ++ should be used. The boot layout is considered from the ++ start of the nand to the value set in this binding. ++ Only used in combination with 'nand-is-boot-medium'. ++ + Each nandcs device node may optionally contain a 'partitions' sub-node, which + further contains sub-nodes describing the flash partition mapping. See + partition.txt for more detail. +@@ -80,6 +89,9 @@ nand-controller@1ac00000 { + nand-ecc-strength = <4>; + nand-bus-width = <8>; + ++ nand-is-boot-medium; ++ qcom,boot_pages_size: <0x58a0000>; ++ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; diff --git a/target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch b/target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch new file mode 100644 index 0000000000..2d24da01e4 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch @@ -0,0 +1,965 @@ +From 5c9f8c2dbdbe53818bcde6aa6695e1331e5f841f Mon Sep 17 00:00:00 2001 +From: Jonathan McDowell +Date: Sat, 14 Nov 2020 14:02:33 +0000 +Subject: dmaengine: qcom: Add ADM driver + +Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA +controller found in the MSM8x60 and IPQ/APQ8064 platforms. + +The ADM supports both memory to memory transactions and memory +to/from peripheral device transactions. The controller also provides +flow control capabilities for transactions to/from peripheral devices. + +The initial release of this driver supports slave transfers to/from +peripherals and also incorporates CRCI (client rate control interface) +flow control. + +The hardware only supports a 32 bit physical address, so specifying +!PHYS_ADDR_T_64BIT gives maximum COMPILE_TEST coverage without having to +spend effort on kludging things in the code that will never actually be +needed on real hardware. + +Signed-off-by: Andy Gross +Signed-off-by: Thomas Pedersen +Signed-off-by: Jonathan McDowell +Link: https://lore.kernel.org/r/20201114140233.GM32650@earth.li +Signed-off-by: Vinod Koul +--- + drivers/dma/qcom/Kconfig | 11 + + drivers/dma/qcom/Makefile | 1 + + drivers/dma/qcom/qcom_adm.c | 903 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 915 insertions(+) + create mode 100644 drivers/dma/qcom/qcom_adm.c + +--- a/drivers/dma/qcom/Kconfig ++++ b/drivers/dma/qcom/Kconfig +@@ -1,4 +1,15 @@ + # SPDX-License-Identifier: GPL-2.0-only ++config QCOM_ADM ++ tristate "Qualcomm ADM support" ++ depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT ++ select DMA_ENGINE ++ select DMA_VIRTUAL_CHANNELS ++ help ++ Enable support for the Qualcomm Application Data Mover (ADM) DMA ++ controller, as present on MSM8x60, APQ8064, and IPQ8064 devices. ++ This controller provides DMA capabilities for both general purpose ++ and on-chip peripheral devices. ++ + config QCOM_BAM_DMA + tristate "QCOM BAM DMA support" + depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM) +--- a/drivers/dma/qcom/Makefile ++++ b/drivers/dma/qcom/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0 ++obj-$(CONFIG_QCOM_ADM) += qcom_adm.o + obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o + obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o + hdma_mgmt-objs := hidma_mgmt.o hidma_mgmt_sys.o +--- /dev/null ++++ b/drivers/dma/qcom/qcom_adm.c +@@ -0,0 +1,903 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../dmaengine.h" ++#include "../virt-dma.h" ++ ++/* ADM registers - calculated from channel number and security domain */ ++#define ADM_CHAN_MULTI 0x4 ++#define ADM_CI_MULTI 0x4 ++#define ADM_CRCI_MULTI 0x4 ++#define ADM_EE_MULTI 0x800 ++#define ADM_CHAN_OFFS(chan) (ADM_CHAN_MULTI * (chan)) ++#define ADM_EE_OFFS(ee) (ADM_EE_MULTI * (ee)) ++#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee)) ++#define ADM_CHAN_OFFS(chan) (ADM_CHAN_MULTI * (chan)) ++#define ADM_CI_OFFS(ci) (ADM_CHAN_OFF(ci)) ++#define ADM_CH_CMD_PTR(chan, ee) (ADM_CHAN_EE_OFFS(chan, ee)) ++#define ADM_CH_RSLT(chan, ee) (0x40 + ADM_CHAN_EE_OFFS(chan, ee)) ++#define ADM_CH_FLUSH_STATE0(chan, ee) (0x80 + ADM_CHAN_EE_OFFS(chan, ee)) ++#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee)) ++#define ADM_CH_CONF(chan) (0x240 + ADM_CHAN_OFFS(chan)) ++#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee)) ++#define ADM_SEC_DOMAIN_IRQ_STATUS(ee) (0x380 + ADM_EE_OFFS(ee)) ++#define ADM_CI_CONF(ci) (0x390 + (ci) * ADM_CI_MULTI) ++#define ADM_GP_CTL 0x3d8 ++#define ADM_CRCI_CTL(crci, ee) (0x400 + (crci) * ADM_CRCI_MULTI + \ ++ ADM_EE_OFFS(ee)) ++ ++/* channel status */ ++#define ADM_CH_STATUS_VALID BIT(1) ++ ++/* channel result */ ++#define ADM_CH_RSLT_VALID BIT(31) ++#define ADM_CH_RSLT_ERR BIT(3) ++#define ADM_CH_RSLT_FLUSH BIT(2) ++#define ADM_CH_RSLT_TPD BIT(1) ++ ++/* channel conf */ ++#define ADM_CH_CONF_SHADOW_EN BIT(12) ++#define ADM_CH_CONF_MPU_DISABLE BIT(11) ++#define ADM_CH_CONF_PERM_MPU_CONF BIT(9) ++#define ADM_CH_CONF_FORCE_RSLT_EN BIT(7) ++#define ADM_CH_CONF_SEC_DOMAIN(ee) ((((ee) & 0x3) << 4) | (((ee) & 0x4) << 11)) ++ ++/* channel result conf */ ++#define ADM_CH_RSLT_CONF_FLUSH_EN BIT(1) ++#define ADM_CH_RSLT_CONF_IRQ_EN BIT(0) ++ ++/* CRCI CTL */ ++#define ADM_CRCI_CTL_MUX_SEL BIT(18) ++#define ADM_CRCI_CTL_RST BIT(17) ++ ++/* CI configuration */ ++#define ADM_CI_RANGE_END(x) ((x) << 24) ++#define ADM_CI_RANGE_START(x) ((x) << 16) ++#define ADM_CI_BURST_4_WORDS BIT(2) ++#define ADM_CI_BURST_8_WORDS BIT(3) ++ ++/* GP CTL */ ++#define ADM_GP_CTL_LP_EN BIT(12) ++#define ADM_GP_CTL_LP_CNT(x) ((x) << 8) ++ ++/* Command pointer list entry */ ++#define ADM_CPLE_LP BIT(31) ++#define ADM_CPLE_CMD_PTR_LIST BIT(29) ++ ++/* Command list entry */ ++#define ADM_CMD_LC BIT(31) ++#define ADM_CMD_DST_CRCI(n) (((n) & 0xf) << 7) ++#define ADM_CMD_SRC_CRCI(n) (((n) & 0xf) << 3) ++ ++#define ADM_CMD_TYPE_SINGLE 0x0 ++#define ADM_CMD_TYPE_BOX 0x3 ++ ++#define ADM_CRCI_MUX_SEL BIT(4) ++#define ADM_DESC_ALIGN 8 ++#define ADM_MAX_XFER (SZ_64K - 1) ++#define ADM_MAX_ROWS (SZ_64K - 1) ++#define ADM_MAX_CHANNELS 16 ++ ++struct adm_desc_hw_box { ++ u32 cmd; ++ u32 src_addr; ++ u32 dst_addr; ++ u32 row_len; ++ u32 num_rows; ++ u32 row_offset; ++}; ++ ++struct adm_desc_hw_single { ++ u32 cmd; ++ u32 src_addr; ++ u32 dst_addr; ++ u32 len; ++}; ++ ++struct adm_async_desc { ++ struct virt_dma_desc vd; ++ struct adm_device *adev; ++ ++ size_t length; ++ enum dma_transfer_direction dir; ++ dma_addr_t dma_addr; ++ size_t dma_len; ++ ++ void *cpl; ++ dma_addr_t cp_addr; ++ u32 crci; ++ u32 mux; ++ u32 blk_size; ++}; ++ ++struct adm_chan { ++ struct virt_dma_chan vc; ++ struct adm_device *adev; ++ ++ /* parsed from DT */ ++ u32 id; /* channel id */ ++ ++ struct adm_async_desc *curr_txd; ++ struct dma_slave_config slave; ++ struct list_head node; ++ ++ int error; ++ int initialized; ++}; ++ ++static inline struct adm_chan *to_adm_chan(struct dma_chan *common) ++{ ++ return container_of(common, struct adm_chan, vc.chan); ++} ++ ++struct adm_device { ++ void __iomem *regs; ++ struct device *dev; ++ struct dma_device common; ++ struct device_dma_parameters dma_parms; ++ struct adm_chan *channels; ++ ++ u32 ee; ++ ++ struct clk *core_clk; ++ struct clk *iface_clk; ++ ++ struct reset_control *clk_reset; ++ struct reset_control *c0_reset; ++ struct reset_control *c1_reset; ++ struct reset_control *c2_reset; ++ int irq; ++}; ++ ++/** ++ * adm_free_chan - Frees dma resources associated with the specific channel ++ * ++ * Free all allocated descriptors associated with this channel ++ * ++ */ ++static void adm_free_chan(struct dma_chan *chan) ++{ ++ /* free all queued descriptors */ ++ vchan_free_chan_resources(to_virt_chan(chan)); ++} ++ ++/** ++ * adm_get_blksize - Get block size from burst value ++ * ++ */ ++static int adm_get_blksize(unsigned int burst) ++{ ++ int ret; ++ ++ switch (burst) { ++ case 16: ++ case 32: ++ case 64: ++ case 128: ++ ret = ffs(burst >> 4) - 1; ++ break; ++ case 192: ++ ret = 4; ++ break; ++ case 256: ++ ret = 5; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ ++ return ret; ++} ++ ++/** ++ * adm_process_fc_descriptors - Process descriptors for flow controlled xfers ++ * ++ * @achan: ADM channel ++ * @desc: Descriptor memory pointer ++ * @sg: Scatterlist entry ++ * @crci: CRCI value ++ * @burst: Burst size of transaction ++ * @direction: DMA transfer direction ++ */ ++static void *adm_process_fc_descriptors(struct adm_chan *achan, void *desc, ++ struct scatterlist *sg, u32 crci, ++ u32 burst, ++ enum dma_transfer_direction direction) ++{ ++ struct adm_desc_hw_box *box_desc = NULL; ++ struct adm_desc_hw_single *single_desc; ++ u32 remainder = sg_dma_len(sg); ++ u32 rows, row_offset, crci_cmd; ++ u32 mem_addr = sg_dma_address(sg); ++ u32 *incr_addr = &mem_addr; ++ u32 *src, *dst; ++ ++ if (direction == DMA_DEV_TO_MEM) { ++ crci_cmd = ADM_CMD_SRC_CRCI(crci); ++ row_offset = burst; ++ src = &achan->slave.src_addr; ++ dst = &mem_addr; ++ } else { ++ crci_cmd = ADM_CMD_DST_CRCI(crci); ++ row_offset = burst << 16; ++ src = &mem_addr; ++ dst = &achan->slave.dst_addr; ++ } ++ ++ while (remainder >= burst) { ++ box_desc = desc; ++ box_desc->cmd = ADM_CMD_TYPE_BOX | crci_cmd; ++ box_desc->row_offset = row_offset; ++ box_desc->src_addr = *src; ++ box_desc->dst_addr = *dst; ++ ++ rows = remainder / burst; ++ rows = min_t(u32, rows, ADM_MAX_ROWS); ++ box_desc->num_rows = rows << 16 | rows; ++ box_desc->row_len = burst << 16 | burst; ++ ++ *incr_addr += burst * rows; ++ remainder -= burst * rows; ++ desc += sizeof(*box_desc); ++ } ++ ++ /* if leftover bytes, do one single descriptor */ ++ if (remainder) { ++ single_desc = desc; ++ single_desc->cmd = ADM_CMD_TYPE_SINGLE | crci_cmd; ++ single_desc->len = remainder; ++ single_desc->src_addr = *src; ++ single_desc->dst_addr = *dst; ++ desc += sizeof(*single_desc); ++ ++ if (sg_is_last(sg)) ++ single_desc->cmd |= ADM_CMD_LC; ++ } else { ++ if (box_desc && sg_is_last(sg)) ++ box_desc->cmd |= ADM_CMD_LC; ++ } ++ ++ return desc; ++} ++ ++/** ++ * adm_process_non_fc_descriptors - Process descriptors for non-fc xfers ++ * ++ * @achan: ADM channel ++ * @desc: Descriptor memory pointer ++ * @sg: Scatterlist entry ++ * @direction: DMA transfer direction ++ */ ++static void *adm_process_non_fc_descriptors(struct adm_chan *achan, void *desc, ++ struct scatterlist *sg, ++ enum dma_transfer_direction direction) ++{ ++ struct adm_desc_hw_single *single_desc; ++ u32 remainder = sg_dma_len(sg); ++ u32 mem_addr = sg_dma_address(sg); ++ u32 *incr_addr = &mem_addr; ++ u32 *src, *dst; ++ ++ if (direction == DMA_DEV_TO_MEM) { ++ src = &achan->slave.src_addr; ++ dst = &mem_addr; ++ } else { ++ src = &mem_addr; ++ dst = &achan->slave.dst_addr; ++ } ++ ++ do { ++ single_desc = desc; ++ single_desc->cmd = ADM_CMD_TYPE_SINGLE; ++ single_desc->src_addr = *src; ++ single_desc->dst_addr = *dst; ++ single_desc->len = (remainder > ADM_MAX_XFER) ? ++ ADM_MAX_XFER : remainder; ++ ++ remainder -= single_desc->len; ++ *incr_addr += single_desc->len; ++ desc += sizeof(*single_desc); ++ } while (remainder); ++ ++ /* set last command if this is the end of the whole transaction */ ++ if (sg_is_last(sg)) ++ single_desc->cmd |= ADM_CMD_LC; ++ ++ return desc; ++} ++ ++/** ++ * adm_prep_slave_sg - Prep slave sg transaction ++ * ++ * @chan: dma channel ++ * @sgl: scatter gather list ++ * @sg_len: length of sg ++ * @direction: DMA transfer direction ++ * @flags: DMA flags ++ * @context: transfer context (unused) ++ */ ++static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, ++ struct scatterlist *sgl, ++ unsigned int sg_len, ++ enum dma_transfer_direction direction, ++ unsigned long flags, ++ void *context) ++{ ++ struct adm_chan *achan = to_adm_chan(chan); ++ struct adm_device *adev = achan->adev; ++ struct adm_async_desc *async_desc; ++ struct scatterlist *sg; ++ dma_addr_t cple_addr; ++ u32 i, burst; ++ u32 single_count = 0, box_count = 0, crci = 0; ++ void *desc; ++ u32 *cple; ++ int blk_size = 0; ++ ++ if (!is_slave_direction(direction)) { ++ dev_err(adev->dev, "invalid dma direction\n"); ++ return NULL; ++ } ++ ++ /* ++ * get burst value from slave configuration ++ */ ++ burst = (direction == DMA_MEM_TO_DEV) ? ++ achan->slave.dst_maxburst : ++ achan->slave.src_maxburst; ++ ++ /* if using flow control, validate burst and crci values */ ++ if (achan->slave.device_fc) { ++ blk_size = adm_get_blksize(burst); ++ if (blk_size < 0) { ++ dev_err(adev->dev, "invalid burst value: %d\n", ++ burst); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ crci = achan->slave.slave_id & 0xf; ++ if (!crci || achan->slave.slave_id > 0x1f) { ++ dev_err(adev->dev, "invalid crci value\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ ++ /* iterate through sgs and compute allocation size of structures */ ++ for_each_sg(sgl, sg, sg_len, i) { ++ if (achan->slave.device_fc) { ++ box_count += DIV_ROUND_UP(sg_dma_len(sg) / burst, ++ ADM_MAX_ROWS); ++ if (sg_dma_len(sg) % burst) ++ single_count++; ++ } else { ++ single_count += DIV_ROUND_UP(sg_dma_len(sg), ++ ADM_MAX_XFER); ++ } ++ } ++ ++ async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT); ++ if (!async_desc) ++ return ERR_PTR(-ENOMEM); ++ ++ if (crci) ++ async_desc->mux = achan->slave.slave_id & ADM_CRCI_MUX_SEL ? ++ ADM_CRCI_CTL_MUX_SEL : 0; ++ async_desc->crci = crci; ++ async_desc->blk_size = blk_size; ++ async_desc->dma_len = single_count * sizeof(struct adm_desc_hw_single) + ++ box_count * sizeof(struct adm_desc_hw_box) + ++ sizeof(*cple) + 2 * ADM_DESC_ALIGN; ++ ++ async_desc->cpl = kzalloc(async_desc->dma_len, GFP_NOWAIT); ++ if (!async_desc->cpl) ++ goto free; ++ ++ async_desc->adev = adev; ++ ++ /* both command list entry and descriptors must be 8 byte aligned */ ++ cple = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN); ++ desc = PTR_ALIGN(cple + 1, ADM_DESC_ALIGN); ++ ++ for_each_sg(sgl, sg, sg_len, i) { ++ async_desc->length += sg_dma_len(sg); ++ ++ if (achan->slave.device_fc) ++ desc = adm_process_fc_descriptors(achan, desc, sg, crci, ++ burst, direction); ++ else ++ desc = adm_process_non_fc_descriptors(achan, desc, sg, ++ direction); ++ } ++ ++ async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl, ++ async_desc->dma_len, ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(adev->dev, async_desc->dma_addr)) ++ goto free; ++ ++ cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl); ++ ++ /* init cmd list */ ++ dma_sync_single_for_cpu(adev->dev, cple_addr, sizeof(*cple), ++ DMA_TO_DEVICE); ++ *cple = ADM_CPLE_LP; ++ *cple |= (async_desc->dma_addr + ADM_DESC_ALIGN) >> 3; ++ dma_sync_single_for_device(adev->dev, cple_addr, sizeof(*cple), ++ DMA_TO_DEVICE); ++ ++ return vchan_tx_prep(&achan->vc, &async_desc->vd, flags); ++ ++free: ++ kfree(async_desc); ++ return ERR_PTR(-ENOMEM); ++} ++ ++/** ++ * adm_terminate_all - terminate all transactions on a channel ++ * @achan: adm dma channel ++ * ++ * Dequeues and frees all transactions, aborts current transaction ++ * No callbacks are done ++ * ++ */ ++static int adm_terminate_all(struct dma_chan *chan) ++{ ++ struct adm_chan *achan = to_adm_chan(chan); ++ struct adm_device *adev = achan->adev; ++ unsigned long flags; ++ LIST_HEAD(head); ++ ++ spin_lock_irqsave(&achan->vc.lock, flags); ++ vchan_get_all_descriptors(&achan->vc, &head); ++ ++ /* send flush command to terminate current transaction */ ++ writel_relaxed(0x0, ++ adev->regs + ADM_CH_FLUSH_STATE0(achan->id, adev->ee)); ++ ++ spin_unlock_irqrestore(&achan->vc.lock, flags); ++ ++ vchan_dma_desc_free_list(&achan->vc, &head); ++ ++ return 0; ++} ++ ++static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) ++{ ++ struct adm_chan *achan = to_adm_chan(chan); ++ unsigned long flag; ++ ++ spin_lock_irqsave(&achan->vc.lock, flag); ++ memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config)); ++ spin_unlock_irqrestore(&achan->vc.lock, flag); ++ ++ return 0; ++} ++ ++/** ++ * adm_start_dma - start next transaction ++ * @achan - ADM dma channel ++ */ ++static void adm_start_dma(struct adm_chan *achan) ++{ ++ struct virt_dma_desc *vd = vchan_next_desc(&achan->vc); ++ struct adm_device *adev = achan->adev; ++ struct adm_async_desc *async_desc; ++ ++ lockdep_assert_held(&achan->vc.lock); ++ ++ if (!vd) ++ return; ++ ++ list_del(&vd->node); ++ ++ /* write next command list out to the CMD FIFO */ ++ async_desc = container_of(vd, struct adm_async_desc, vd); ++ achan->curr_txd = async_desc; ++ ++ /* reset channel error */ ++ achan->error = 0; ++ ++ if (!achan->initialized) { ++ /* enable interrupts */ ++ writel(ADM_CH_CONF_SHADOW_EN | ++ ADM_CH_CONF_PERM_MPU_CONF | ++ ADM_CH_CONF_MPU_DISABLE | ++ ADM_CH_CONF_SEC_DOMAIN(adev->ee), ++ adev->regs + ADM_CH_CONF(achan->id)); ++ ++ writel(ADM_CH_RSLT_CONF_IRQ_EN | ADM_CH_RSLT_CONF_FLUSH_EN, ++ adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee)); ++ ++ achan->initialized = 1; ++ } ++ ++ /* set the crci block size if this transaction requires CRCI */ ++ if (async_desc->crci) { ++ writel(async_desc->mux | async_desc->blk_size, ++ adev->regs + ADM_CRCI_CTL(async_desc->crci, adev->ee)); ++ } ++ ++ /* make sure IRQ enable doesn't get reordered */ ++ wmb(); ++ ++ /* write next command list out to the CMD FIFO */ ++ writel(ALIGN(async_desc->dma_addr, ADM_DESC_ALIGN) >> 3, ++ adev->regs + ADM_CH_CMD_PTR(achan->id, adev->ee)); ++} ++ ++/** ++ * adm_dma_irq - irq handler for ADM controller ++ * @irq: IRQ of interrupt ++ * @data: callback data ++ * ++ * IRQ handler for the bam controller ++ */ ++static irqreturn_t adm_dma_irq(int irq, void *data) ++{ ++ struct adm_device *adev = data; ++ u32 srcs, i; ++ struct adm_async_desc *async_desc; ++ unsigned long flags; ++ ++ srcs = readl_relaxed(adev->regs + ++ ADM_SEC_DOMAIN_IRQ_STATUS(adev->ee)); ++ ++ for (i = 0; i < ADM_MAX_CHANNELS; i++) { ++ struct adm_chan *achan = &adev->channels[i]; ++ u32 status, result; ++ ++ if (srcs & BIT(i)) { ++ status = readl_relaxed(adev->regs + ++ ADM_CH_STATUS_SD(i, adev->ee)); ++ ++ /* if no result present, skip */ ++ if (!(status & ADM_CH_STATUS_VALID)) ++ continue; ++ ++ result = readl_relaxed(adev->regs + ++ ADM_CH_RSLT(i, adev->ee)); ++ ++ /* no valid results, skip */ ++ if (!(result & ADM_CH_RSLT_VALID)) ++ continue; ++ ++ /* flag error if transaction was flushed or failed */ ++ if (result & (ADM_CH_RSLT_ERR | ADM_CH_RSLT_FLUSH)) ++ achan->error = 1; ++ ++ spin_lock_irqsave(&achan->vc.lock, flags); ++ async_desc = achan->curr_txd; ++ ++ achan->curr_txd = NULL; ++ ++ if (async_desc) { ++ vchan_cookie_complete(&async_desc->vd); ++ ++ /* kick off next DMA */ ++ adm_start_dma(achan); ++ } ++ ++ spin_unlock_irqrestore(&achan->vc.lock, flags); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * adm_tx_status - returns status of transaction ++ * @chan: dma channel ++ * @cookie: transaction cookie ++ * @txstate: DMA transaction state ++ * ++ * Return status of dma transaction ++ */ ++static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t cookie, ++ struct dma_tx_state *txstate) ++{ ++ struct adm_chan *achan = to_adm_chan(chan); ++ struct virt_dma_desc *vd; ++ enum dma_status ret; ++ unsigned long flags; ++ size_t residue = 0; ++ ++ ret = dma_cookie_status(chan, cookie, txstate); ++ if (ret == DMA_COMPLETE || !txstate) ++ return ret; ++ ++ spin_lock_irqsave(&achan->vc.lock, flags); ++ ++ vd = vchan_find_desc(&achan->vc, cookie); ++ if (vd) ++ residue = container_of(vd, struct adm_async_desc, vd)->length; ++ ++ spin_unlock_irqrestore(&achan->vc.lock, flags); ++ ++ /* ++ * residue is either the full length if it is in the issued list, or 0 ++ * if it is in progress. We have no reliable way of determining ++ * anything inbetween ++ */ ++ dma_set_residue(txstate, residue); ++ ++ if (achan->error) ++ return DMA_ERROR; ++ ++ return ret; ++} ++ ++/** ++ * adm_issue_pending - starts pending transactions ++ * @chan: dma channel ++ * ++ * Issues all pending transactions and starts DMA ++ */ ++static void adm_issue_pending(struct dma_chan *chan) ++{ ++ struct adm_chan *achan = to_adm_chan(chan); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&achan->vc.lock, flags); ++ ++ if (vchan_issue_pending(&achan->vc) && !achan->curr_txd) ++ adm_start_dma(achan); ++ spin_unlock_irqrestore(&achan->vc.lock, flags); ++} ++ ++/** ++ * adm_dma_free_desc - free descriptor memory ++ * @vd: virtual descriptor ++ * ++ */ ++static void adm_dma_free_desc(struct virt_dma_desc *vd) ++{ ++ struct adm_async_desc *async_desc = container_of(vd, ++ struct adm_async_desc, vd); ++ ++ dma_unmap_single(async_desc->adev->dev, async_desc->dma_addr, ++ async_desc->dma_len, DMA_TO_DEVICE); ++ kfree(async_desc->cpl); ++ kfree(async_desc); ++} ++ ++static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan, ++ u32 index) ++{ ++ achan->id = index; ++ achan->adev = adev; ++ ++ vchan_init(&achan->vc, &adev->common); ++ achan->vc.desc_free = adm_dma_free_desc; ++} ++ ++static int adm_dma_probe(struct platform_device *pdev) ++{ ++ struct adm_device *adev; ++ int ret; ++ u32 i; ++ ++ adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL); ++ if (!adev) ++ return -ENOMEM; ++ ++ adev->dev = &pdev->dev; ++ ++ adev->regs = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(adev->regs)) ++ return PTR_ERR(adev->regs); ++ ++ adev->irq = platform_get_irq(pdev, 0); ++ if (adev->irq < 0) ++ return adev->irq; ++ ++ ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &adev->ee); ++ if (ret) { ++ dev_err(adev->dev, "Execution environment unspecified\n"); ++ return ret; ++ } ++ ++ adev->core_clk = devm_clk_get(adev->dev, "core"); ++ if (IS_ERR(adev->core_clk)) ++ return PTR_ERR(adev->core_clk); ++ ++ adev->iface_clk = devm_clk_get(adev->dev, "iface"); ++ if (IS_ERR(adev->iface_clk)) ++ return PTR_ERR(adev->iface_clk); ++ ++ adev->clk_reset = devm_reset_control_get_exclusive(&pdev->dev, "clk"); ++ if (IS_ERR(adev->clk_reset)) { ++ dev_err(adev->dev, "failed to get ADM0 reset\n"); ++ return PTR_ERR(adev->clk_reset); ++ } ++ ++ adev->c0_reset = devm_reset_control_get_exclusive(&pdev->dev, "c0"); ++ if (IS_ERR(adev->c0_reset)) { ++ dev_err(adev->dev, "failed to get ADM0 C0 reset\n"); ++ return PTR_ERR(adev->c0_reset); ++ } ++ ++ adev->c1_reset = devm_reset_control_get_exclusive(&pdev->dev, "c1"); ++ if (IS_ERR(adev->c1_reset)) { ++ dev_err(adev->dev, "failed to get ADM0 C1 reset\n"); ++ return PTR_ERR(adev->c1_reset); ++ } ++ ++ adev->c2_reset = devm_reset_control_get_exclusive(&pdev->dev, "c2"); ++ if (IS_ERR(adev->c2_reset)) { ++ dev_err(adev->dev, "failed to get ADM0 C2 reset\n"); ++ return PTR_ERR(adev->c2_reset); ++ } ++ ++ ret = clk_prepare_enable(adev->core_clk); ++ if (ret) { ++ dev_err(adev->dev, "failed to prepare/enable core clock\n"); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(adev->iface_clk); ++ if (ret) { ++ dev_err(adev->dev, "failed to prepare/enable iface clock\n"); ++ goto err_disable_core_clk; ++ } ++ ++ reset_control_assert(adev->clk_reset); ++ reset_control_assert(adev->c0_reset); ++ reset_control_assert(adev->c1_reset); ++ reset_control_assert(adev->c2_reset); ++ ++ udelay(2); ++ ++ reset_control_deassert(adev->clk_reset); ++ reset_control_deassert(adev->c0_reset); ++ reset_control_deassert(adev->c1_reset); ++ reset_control_deassert(adev->c2_reset); ++ ++ adev->channels = devm_kcalloc(adev->dev, ADM_MAX_CHANNELS, ++ sizeof(*adev->channels), GFP_KERNEL); ++ ++ if (!adev->channels) { ++ ret = -ENOMEM; ++ goto err_disable_clks; ++ } ++ ++ /* allocate and initialize channels */ ++ INIT_LIST_HEAD(&adev->common.channels); ++ ++ for (i = 0; i < ADM_MAX_CHANNELS; i++) ++ adm_channel_init(adev, &adev->channels[i], i); ++ ++ /* reset CRCIs */ ++ for (i = 0; i < 16; i++) ++ writel(ADM_CRCI_CTL_RST, adev->regs + ++ ADM_CRCI_CTL(i, adev->ee)); ++ ++ /* configure client interfaces */ ++ writel(ADM_CI_RANGE_START(0x40) | ADM_CI_RANGE_END(0xb0) | ++ ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(0)); ++ writel(ADM_CI_RANGE_START(0x2a) | ADM_CI_RANGE_END(0x2c) | ++ ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(1)); ++ writel(ADM_CI_RANGE_START(0x12) | ADM_CI_RANGE_END(0x28) | ++ ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(2)); ++ writel(ADM_GP_CTL_LP_EN | ADM_GP_CTL_LP_CNT(0xf), ++ adev->regs + ADM_GP_CTL); ++ ++ ret = devm_request_irq(adev->dev, adev->irq, adm_dma_irq, ++ 0, "adm_dma", adev); ++ if (ret) ++ goto err_disable_clks; ++ ++ platform_set_drvdata(pdev, adev); ++ ++ adev->common.dev = adev->dev; ++ adev->common.dev->dma_parms = &adev->dma_parms; ++ ++ /* set capabilities */ ++ dma_cap_zero(adev->common.cap_mask); ++ dma_cap_set(DMA_SLAVE, adev->common.cap_mask); ++ dma_cap_set(DMA_PRIVATE, adev->common.cap_mask); ++ ++ /* initialize dmaengine apis */ ++ adev->common.directions = BIT(DMA_DEV_TO_MEM | DMA_MEM_TO_DEV); ++ adev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; ++ adev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ adev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ adev->common.device_free_chan_resources = adm_free_chan; ++ adev->common.device_prep_slave_sg = adm_prep_slave_sg; ++ adev->common.device_issue_pending = adm_issue_pending; ++ adev->common.device_tx_status = adm_tx_status; ++ adev->common.device_terminate_all = adm_terminate_all; ++ adev->common.device_config = adm_slave_config; ++ ++ ret = dma_async_device_register(&adev->common); ++ if (ret) { ++ dev_err(adev->dev, "failed to register dma async device\n"); ++ goto err_disable_clks; ++ } ++ ++ ret = of_dma_controller_register(pdev->dev.of_node, ++ of_dma_xlate_by_chan_id, ++ &adev->common); ++ if (ret) ++ goto err_unregister_dma; ++ ++ return 0; ++ ++err_unregister_dma: ++ dma_async_device_unregister(&adev->common); ++err_disable_clks: ++ clk_disable_unprepare(adev->iface_clk); ++err_disable_core_clk: ++ clk_disable_unprepare(adev->core_clk); ++ ++ return ret; ++} ++ ++static int adm_dma_remove(struct platform_device *pdev) ++{ ++ struct adm_device *adev = platform_get_drvdata(pdev); ++ struct adm_chan *achan; ++ u32 i; ++ ++ of_dma_controller_free(pdev->dev.of_node); ++ dma_async_device_unregister(&adev->common); ++ ++ for (i = 0; i < ADM_MAX_CHANNELS; i++) { ++ achan = &adev->channels[i]; ++ ++ /* mask IRQs for this channel/EE pair */ ++ writel(0, adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee)); ++ ++ tasklet_kill(&adev->channels[i].vc.task); ++ adm_terminate_all(&adev->channels[i].vc.chan); ++ } ++ ++ devm_free_irq(adev->dev, adev->irq, adev); ++ ++ clk_disable_unprepare(adev->core_clk); ++ clk_disable_unprepare(adev->iface_clk); ++ ++ return 0; ++} ++ ++static const struct of_device_id adm_of_match[] = { ++ { .compatible = "qcom,adm", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, adm_of_match); ++ ++static struct platform_driver adm_dma_driver = { ++ .probe = adm_dma_probe, ++ .remove = adm_dma_remove, ++ .driver = { ++ .name = "adm-dma-engine", ++ .of_match_table = adm_of_match, ++ }, ++}; ++ ++module_platform_driver(adm_dma_driver); ++ ++MODULE_AUTHOR("Andy Gross "); ++MODULE_DESCRIPTION("QCOM ADM DMA engine driver"); ++MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch b/target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch new file mode 100644 index 0000000000..a78dc82a47 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch @@ -0,0 +1,217 @@ +From 803eb124e1a64e42888542c3444bfe6dac412c7f Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam +Date: Mon, 4 Jan 2021 09:41:35 +0530 +Subject: mtd: parsers: Add Qcom SMEM parser + +NAND based Qualcomm platforms have the partition table populated in the +Shared Memory (SMEM). Hence, add a parser for parsing the partitions +from it. + +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Miquel Raynal +Link: https://lore.kernel.org/linux-mtd/20210104041137.113075-3-manivannan.sadhasivam@linaro.org +--- + drivers/mtd/parsers/Kconfig | 8 ++ + drivers/mtd/parsers/Makefile | 1 + + drivers/mtd/parsers/qcomsmempart.c | 170 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 179 insertions(+) + create mode 100644 drivers/mtd/parsers/qcomsmempart.c + +--- a/drivers/mtd/parsers/Kconfig ++++ b/drivers/mtd/parsers/Kconfig +@@ -196,6 +196,14 @@ config MTD_REDBOOT_PARTS_READONLY + + endif # MTD_REDBOOT_PARTS + ++config MTD_QCOMSMEM_PARTS ++ tristate "Qualcomm SMEM NAND flash partition parser" ++ depends on MTD_NAND_QCOM || COMPILE_TEST ++ depends on QCOM_SMEM ++ help ++ This provides support for parsing partitions from Shared Memory (SMEM) ++ for NAND flash on Qualcomm platforms. ++ + config MTD_ROUTERBOOT_PARTS + tristate "RouterBoot flash partition parser" + depends on MTD && OF +--- a/drivers/mtd/parsers/Makefile ++++ b/drivers/mtd/parsers/Makefile +@@ -13,4 +13,5 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o + obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o ++obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o + obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o +--- /dev/null ++++ b/drivers/mtd/parsers/qcomsmempart.c +@@ -0,0 +1,170 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Qualcomm SMEM NAND flash partition parser ++ * ++ * Copyright (C) 2020, Linaro Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SMEM_AARM_PARTITION_TABLE 9 ++#define SMEM_APPS 0 ++ ++#define SMEM_FLASH_PART_MAGIC1 0x55ee73aa ++#define SMEM_FLASH_PART_MAGIC2 0xe35ebddb ++#define SMEM_FLASH_PTABLE_V3 3 ++#define SMEM_FLASH_PTABLE_V4 4 ++#define SMEM_FLASH_PTABLE_MAX_PARTS_V3 16 ++#define SMEM_FLASH_PTABLE_MAX_PARTS_V4 48 ++#define SMEM_FLASH_PTABLE_HDR_LEN (4 * sizeof(u32)) ++#define SMEM_FLASH_PTABLE_NAME_SIZE 16 ++ ++/** ++ * struct smem_flash_pentry - SMEM Flash partition entry ++ * @name: Name of the partition ++ * @offset: Offset in blocks ++ * @length: Length of the partition in blocks ++ * @attr: Flags for this partition ++ */ ++struct smem_flash_pentry { ++ char name[SMEM_FLASH_PTABLE_NAME_SIZE]; ++ __le32 offset; ++ __le32 length; ++ u8 attr; ++} __packed __aligned(4); ++ ++/** ++ * struct smem_flash_ptable - SMEM Flash partition table ++ * @magic1: Partition table Magic 1 ++ * @magic2: Partition table Magic 2 ++ * @version: Partition table version ++ * @numparts: Number of partitions in this ptable ++ * @pentry: Flash partition entries belonging to this ptable ++ */ ++struct smem_flash_ptable { ++ __le32 magic1; ++ __le32 magic2; ++ __le32 version; ++ __le32 numparts; ++ struct smem_flash_pentry pentry[SMEM_FLASH_PTABLE_MAX_PARTS_V4]; ++} __packed __aligned(4); ++ ++static int parse_qcomsmem_part(struct mtd_info *mtd, ++ const struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data) ++{ ++ struct smem_flash_pentry *pentry; ++ struct smem_flash_ptable *ptable; ++ size_t len = SMEM_FLASH_PTABLE_HDR_LEN; ++ struct mtd_partition *parts; ++ int ret, i, numparts; ++ char *name, *c; ++ ++ pr_debug("Parsing partition table info from SMEM\n"); ++ ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); ++ if (IS_ERR(ptable)) { ++ pr_err("Error reading partition table header\n"); ++ return PTR_ERR(ptable); ++ } ++ ++ /* Verify ptable magic */ ++ if (le32_to_cpu(ptable->magic1) != SMEM_FLASH_PART_MAGIC1 || ++ le32_to_cpu(ptable->magic2) != SMEM_FLASH_PART_MAGIC2) { ++ pr_err("Partition table magic verification failed\n"); ++ return -EINVAL; ++ } ++ ++ /* Ensure that # of partitions is less than the max we have allocated */ ++ numparts = le32_to_cpu(ptable->numparts); ++ if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { ++ pr_err("Partition numbers exceed the max limit\n"); ++ return -EINVAL; ++ } ++ ++ /* Find out length of partition data based on table version */ ++ if (le32_to_cpu(ptable->version) <= SMEM_FLASH_PTABLE_V3) { ++ len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V3 * ++ sizeof(struct smem_flash_pentry); ++ } else if (le32_to_cpu(ptable->version) == SMEM_FLASH_PTABLE_V4) { ++ len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V4 * ++ sizeof(struct smem_flash_pentry); ++ } else { ++ pr_err("Unknown ptable version (%d)", le32_to_cpu(ptable->version)); ++ return -EINVAL; ++ } ++ ++ /* ++ * Now that the partition table header has been parsed, verified ++ * and the length of the partition table calculated, read the ++ * complete partition table ++ */ ++ ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); ++ if (IS_ERR_OR_NULL(ptable)) { ++ pr_err("Error reading partition table\n"); ++ return PTR_ERR(ptable); ++ } ++ ++ parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL); ++ if (!parts) ++ return -ENOMEM; ++ ++ for (i = 0; i < numparts; i++) { ++ pentry = &ptable->pentry[i]; ++ if (pentry->name[0] == '\0') ++ continue; ++ ++ name = kstrdup(pentry->name, GFP_KERNEL); ++ if (!name) { ++ ret = -ENOMEM; ++ goto out_free_parts; ++ } ++ ++ /* Convert name to lower case */ ++ for (c = name; *c != '\0'; c++) ++ *c = tolower(*c); ++ ++ parts[i].name = name; ++ parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; ++ parts[i].mask_flags = pentry->attr; ++ parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; ++ pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", ++ i, pentry->name, le32_to_cpu(pentry->offset), ++ le32_to_cpu(pentry->length), pentry->attr); ++ } ++ ++ pr_debug("SMEM partition table found: ver: %d len: %d\n", ++ le32_to_cpu(ptable->version), numparts); ++ *pparts = parts; ++ ++ return numparts; ++ ++out_free_parts: ++ while (--i >= 0) ++ kfree(parts[i].name); ++ kfree(parts); ++ *pparts = NULL; ++ ++ return ret; ++} ++ ++static const struct of_device_id qcomsmem_of_match_table[] = { ++ { .compatible = "qcom,smem-part" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, qcomsmem_of_match_table); ++ ++static struct mtd_part_parser mtd_parser_qcomsmem = { ++ .parse_fn = parse_qcomsmem_part, ++ .name = "qcomsmem", ++ .of_match_table = qcomsmem_of_match_table, ++}; ++module_mtd_part_parser(mtd_parser_qcomsmem); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Manivannan Sadhasivam "); ++MODULE_DESCRIPTION("Qualcomm SMEM NAND flash partition parser"); diff --git a/target/linux/ipq806x/patches-5.15/101-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch b/target/linux/ipq806x/patches-5.15/101-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch new file mode 100644 index 0000000000..2210f4e249 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/101-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch @@ -0,0 +1,83 @@ +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +@@ -64,6 +64,17 @@ + #define NSS_COMMON_CLK_DIV_SGMII_100 4 + #define NSS_COMMON_CLK_DIV_SGMII_10 49 + ++#define QSGMII_PCS_ALL_CH_CTL 0x80 ++#define QSGMII_PCS_CH_SPEED_FORCE 0x2 ++#define QSGMII_PCS_CH_SPEED_10 0x0 ++#define QSGMII_PCS_CH_SPEED_100 0x4 ++#define QSGMII_PCS_CH_SPEED_1000 0x8 ++#define QSGMII_PCS_CH_SPEED_MASK (QSGMII_PCS_CH_SPEED_FORCE | \ ++ QSGMII_PCS_CH_SPEED_10 | \ ++ QSGMII_PCS_CH_SPEED_100 | \ ++ QSGMII_PCS_CH_SPEED_1000) ++#define QSGMII_PCS_CH_SPEED_SHIFT(x) (x * 4) ++ + #define QSGMII_PCS_CAL_LCKDT_CTL 0x120 + #define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19) + +@@ -242,6 +253,36 @@ static void ipq806x_gmac_fix_mac_speed(v + ipq806x_gmac_set_speed(gmac, speed); + } + ++static int ++ipq806x_gmac_get_qsgmii_pcs_speed_val(struct platform_device *pdev) { ++ struct device_node *fixed_link_node; ++ int rv; ++ int fixed_link_speed; ++ ++ if (!of_phy_is_fixed_link(pdev->dev.of_node)) ++ return 0; ++ ++ fixed_link_node = of_get_child_by_name(pdev->dev.of_node, "fixed-link"); ++ if (!fixed_link_node) ++ return -1; ++ ++ rv = of_property_read_u32(fixed_link_node, "speed", &fixed_link_speed); ++ of_node_put(fixed_link_node); ++ if (rv) ++ return -1; ++ ++ switch (fixed_link_speed) { ++ case SPEED_1000: ++ return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_1000; ++ case SPEED_100: ++ return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_100; ++ case SPEED_10: ++ return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_10; ++ } ++ ++ return -1; ++} ++ + static int ipq806x_gmac_probe(struct platform_device *pdev) + { + struct plat_stmmacenet_data *plat_dat; +@@ -250,6 +291,7 @@ static int ipq806x_gmac_probe(struct pla + struct ipq806x_gmac *gmac; + int val; + int err; ++ int qsgmii_pcs_speed; + + val = stmmac_get_platform_resources(pdev, &stmmac_res); + if (val) +@@ -339,6 +381,17 @@ static int ipq806x_gmac_probe(struct pla + 0x1ul << QSGMII_PHY_RX_INPUT_EQU_OFFSET | + 0x2ul << QSGMII_PHY_CDR_PI_SLEW_OFFSET | + 0xCul << QSGMII_PHY_TX_DRV_AMP_OFFSET); ++ ++ qsgmii_pcs_speed = ipq806x_gmac_get_qsgmii_pcs_speed_val(pdev); ++ if (qsgmii_pcs_speed != -1) { ++ regmap_update_bits( ++ gmac->qsgmii_csr, ++ QSGMII_PCS_ALL_CH_CTL, ++ QSGMII_PCS_CH_SPEED_MASK << ++ QSGMII_PCS_CH_SPEED_SHIFT(gmac->id), ++ qsgmii_pcs_speed << ++ QSGMII_PCS_CH_SPEED_SHIFT(gmac->id)); ++ } + } + + plat_dat->has_gmac = true; diff --git a/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch b/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch new file mode 100644 index 0000000000..e83872935f --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch @@ -0,0 +1,24 @@ +From 5001f2e1a325b68dbf225bd17f69a4d3d975cca5 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 9 Mar 2017 09:31:44 +0100 +Subject: [PATCH 61/69] mtd: "rootfs" conflicts with OpenWrt auto mounting + +Signed-off-by: John Crispin +--- + drivers/mtd/parsers/qcomsmempart.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/mtd/parsers/qcomsmempart.c ++++ b/drivers/mtd/parsers/qcomsmempart.c +@@ -132,6 +132,11 @@ static int parse_qcomsmem_part(struct mt + parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; + parts[i].mask_flags = pentry->attr; + parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; ++ ++ /* "rootfs" conflicts with OpenWrt auto mounting */ ++ if (mtd_type_is_nand(mtd) && !strcmp(name, "rootfs")) ++ parts[i].name = "ubi"; ++ + pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", + i, pentry->name, le32_to_cpu(pentry->offset), + le32_to_cpu(pentry->length), pentry->attr); diff --git a/target/linux/ipq806x/patches-5.15/103-ARM-dts-qcom-reduce-pci-IO-size-to-64K.patch b/target/linux/ipq806x/patches-5.15/103-ARM-dts-qcom-reduce-pci-IO-size-to-64K.patch new file mode 100644 index 0000000000..75b53234ab --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/103-ARM-dts-qcom-reduce-pci-IO-size-to-64K.patch @@ -0,0 +1,46 @@ +From 84909e85881d67244240c9f40974ce12a51e3886 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 11 May 2021 23:09:45 +0200 +Subject: [PATCH] ARM: dts: qcom: reduce pci IO size to 64K + +The current value is probably a typo and is actually uncommon to find +1MB IO space even on a x86 arch. Also with recent changes to the pci +driver, pci1 and pci2 now fails to function as any connected device +fails any reg read/write. Reduce this to 64K as it should be more than +enough and 3 * 64K of total IO space doesn't exceed the IO_SPACE_LIMIT +hardcoded for the ARM arch. + +Signed-off-by: Ansuel Smith +--- + arch/arm/boot/dts/qcom-ipq8064.dtsi | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +@@ -1163,7 +1163,7 @@ + #address-cells = <3>; + #size-cells = <2>; + +- ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000 /* downstream I/O */ ++ ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */ + + interrupts = ; +@@ -1214,7 +1214,7 @@ + #address-cells = <3>; + #size-cells = <2>; + +- ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000 /* downstream I/O */ ++ ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */ + + interrupts = ; +@@ -1265,7 +1265,7 @@ + #address-cells = <3>; + #size-cells = <2>; + +- ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000 /* downstream I/O */ ++ ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00010000 /* downstream I/O */ + 0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */ + + interrupts = ; diff --git a/target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch b/target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch new file mode 100644 index 0000000000..8627244c59 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch @@ -0,0 +1,285 @@ +From 5c7d1181056feef0b58fb2f556f55e170ba5b479 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 25 Jul 2020 19:14:59 +0200 +Subject: [PATCH 01/10] drivers: thermal: tsens: Add VER_0 tsens version + +VER_0 is used to describe device based on tsens version before v0.1. +These device are devices based on msm8960 for example apq8064 or +ipq806x. + +Signed-off-by: Ansuel Smith +Reviewed-by: Thara Gopinath +Reported-by: kernel test robot +Reported-by: Dan Carpenter +--- + drivers/thermal/qcom/tsens.c | 150 ++++++++++++++++++++++++++++------- + drivers/thermal/qcom/tsens.h | 4 +- + 2 files changed, 124 insertions(+), 30 deletions(-) + +--- a/drivers/thermal/qcom/tsens.c ++++ b/drivers/thermal/qcom/tsens.c +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -515,6 +516,15 @@ static irqreturn_t tsens_irq_thread(int + dev_dbg(priv->dev, "[%u] %s: no violation: %d\n", + hw_id, __func__, temp); + } ++ ++ if (tsens_version(priv) < VER_0_1) { ++ /* Constraint: There is only 1 interrupt control register for all ++ * 11 temperature sensor. So monitoring more than 1 sensor based ++ * on interrupts will yield inconsistent result. To overcome this ++ * issue we will monitor only sensor 0 which is the master sensor. ++ */ ++ break; ++ } + } + + return IRQ_HANDLED; +@@ -530,6 +540,13 @@ static int tsens_set_trips(void *_sensor + int high_val, low_val, cl_high, cl_low; + u32 hw_id = s->hw_id; + ++ if (tsens_version(priv) < VER_0_1) { ++ /* Pre v0.1 IP had a single register for each type of interrupt ++ * and thresholds ++ */ ++ hw_id = 0; ++ } ++ + dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n", + hw_id, __func__, low, high); + +@@ -584,18 +601,21 @@ int get_temp_tsens_valid(const struct ts + u32 valid; + int ret; + +- ret = regmap_field_read(priv->rf[valid_idx], &valid); +- if (ret) +- return ret; +- while (!valid) { +- /* Valid bit is 0 for 6 AHB clock cycles. +- * At 19.2MHz, 1 AHB clock is ~60ns. +- * We should enter this loop very, very rarely. +- */ +- ndelay(400); ++ /* VER_0 doesn't have VALID bit */ ++ if (tsens_version(priv) >= VER_0_1) { + ret = regmap_field_read(priv->rf[valid_idx], &valid); + if (ret) + return ret; ++ while (!valid) { ++ /* Valid bit is 0 for 6 AHB clock cycles. ++ * At 19.2MHz, 1 AHB clock is ~60ns. ++ * We should enter this loop very, very rarely. ++ */ ++ ndelay(400); ++ ret = regmap_field_read(priv->rf[valid_idx], &valid); ++ if (ret) ++ return ret; ++ } + } + + /* Valid bit is set, OK to read the temperature */ +@@ -608,15 +628,29 @@ int get_temp_common(const struct tsens_s + { + struct tsens_priv *priv = s->priv; + int hw_id = s->hw_id; +- int last_temp = 0, ret; ++ int last_temp = 0, ret, trdy; ++ unsigned long timeout; + +- ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp); +- if (ret) +- return ret; ++ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); ++ do { ++ if (tsens_version(priv) == VER_0) { ++ ret = regmap_field_read(priv->rf[TRDY], &trdy); ++ if (ret) ++ return ret; ++ if (!trdy) ++ continue; ++ } + +- *temp = code_to_degc(last_temp, s) * 1000; ++ ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp); ++ if (ret) ++ return ret; + +- return 0; ++ *temp = code_to_degc(last_temp, s) * 1000; ++ ++ return 0; ++ } while (time_before(jiffies, timeout)); ++ ++ return -ETIMEDOUT; + } + + #ifdef CONFIG_DEBUG_FS +@@ -738,19 +772,34 @@ int __init init_common(struct tsens_priv + priv->tm_offset = 0x1000; + } + +- res = platform_get_resource(op, IORESOURCE_MEM, 0); +- tm_base = devm_ioremap_resource(dev, res); +- if (IS_ERR(tm_base)) { +- ret = PTR_ERR(tm_base); +- goto err_put_device; ++ if (tsens_version(priv) >= VER_0_1) { ++ res = platform_get_resource(op, IORESOURCE_MEM, 0); ++ tm_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(tm_base)) { ++ ret = PTR_ERR(tm_base); ++ goto err_put_device; ++ } ++ ++ priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config); ++ } else { /* VER_0 share the same gcc regs using a syscon */ ++ struct device *parent = priv->dev->parent; ++ ++ if (parent) ++ priv->tm_map = syscon_node_to_regmap(parent->of_node); + } + +- priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config); +- if (IS_ERR(priv->tm_map)) { +- ret = PTR_ERR(priv->tm_map); ++ if (IS_ERR_OR_NULL(priv->tm_map)) { ++ if (!priv->tm_map) ++ ret = -ENODEV; ++ else ++ ret = PTR_ERR(priv->tm_map); + goto err_put_device; + } + ++ /* VER_0 have only tm_map */ ++ if (!priv->srot_map) ++ priv->srot_map = priv->tm_map; ++ + if (tsens_version(priv) > VER_0_1) { + for (i = VER_MAJOR; i <= VER_STEP; i++) { + priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map, +@@ -771,6 +820,10 @@ int __init init_common(struct tsens_priv + ret = PTR_ERR(priv->rf[TSENS_EN]); + goto err_put_device; + } ++ /* in VER_0 TSENS need to be explicitly enabled */ ++ if (tsens_version(priv) == VER_0) ++ regmap_field_write(priv->rf[TSENS_EN], 1); ++ + ret = regmap_field_read(priv->rf[TSENS_EN], &enabled); + if (ret) + goto err_put_device; +@@ -793,6 +846,19 @@ int __init init_common(struct tsens_priv + goto err_put_device; + } + ++ priv->rf[TSENS_SW_RST] = ++ devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]); ++ if (IS_ERR(priv->rf[TSENS_SW_RST])) { ++ ret = PTR_ERR(priv->rf[TSENS_SW_RST]); ++ goto err_put_device; ++ } ++ ++ priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]); ++ if (IS_ERR(priv->rf[TRDY])) { ++ ret = PTR_ERR(priv->rf[TRDY]); ++ goto err_put_device; ++ } ++ + /* This loop might need changes if enum regfield_ids is reordered */ + for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) { + for (i = 0; i < priv->feat->max_sensors; i++) { +@@ -808,7 +874,7 @@ int __init init_common(struct tsens_priv + } + } + +- if (priv->feat->crit_int) { ++ if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) { + /* Loop might need changes if enum regfield_ids is reordered */ + for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) { + for (i = 0; i < priv->feat->max_sensors; i++) { +@@ -846,7 +912,11 @@ int __init init_common(struct tsens_priv + } + + spin_lock_init(&priv->ul_lock); +- tsens_enable_irq(priv); ++ ++ /* VER_0 interrupt doesn't need to be enabled */ ++ if (tsens_version(priv) >= VER_0_1) ++ tsens_enable_irq(priv); ++ + tsens_debug_init(op); + + err_put_device: +@@ -945,10 +1015,19 @@ static int tsens_register_irq(struct tse + if (irq == -ENXIO) + ret = 0; + } else { +- ret = devm_request_threaded_irq(&pdev->dev, irq, +- NULL, thread_fn, +- IRQF_ONESHOT, +- dev_name(&pdev->dev), priv); ++ /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */ ++ if (tsens_version(priv) == VER_0) ++ ret = devm_request_threaded_irq(&pdev->dev, irq, ++ thread_fn, NULL, ++ IRQF_TRIGGER_RISING, ++ dev_name(&pdev->dev), ++ priv); ++ else ++ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, ++ thread_fn, IRQF_ONESHOT, ++ dev_name(&pdev->dev), ++ priv); ++ + if (ret) + dev_err(&pdev->dev, "%s: failed to get irq\n", + __func__); +@@ -977,6 +1056,19 @@ static int tsens_register(struct tsens_p + priv->ops->enable(priv, i); + } + ++ /* VER_0 require to set MIN and MAX THRESH ++ * These 2 regs are set using the: ++ * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C ++ * - CRIT_THRESH_1 for MIN THRESH hardcoded to 0°C ++ */ ++ if (tsens_version(priv) < VER_0_1) { ++ regmap_field_write(priv->rf[CRIT_THRESH_0], ++ tsens_mC_to_hw(priv->sensor, 120000)); ++ ++ regmap_field_write(priv->rf[CRIT_THRESH_1], ++ tsens_mC_to_hw(priv->sensor, 0)); ++ } ++ + ret = tsens_register_irq(priv, "uplow", tsens_irq_thread); + if (ret < 0) + return ret; +--- a/drivers/thermal/qcom/tsens.h ++++ b/drivers/thermal/qcom/tsens.h +@@ -13,6 +13,7 @@ + #define CAL_DEGC_PT2 120 + #define SLOPE_FACTOR 1000 + #define SLOPE_DEFAULT 3200 ++#define TIMEOUT_US 100 + #define THRESHOLD_MAX_ADC_CODE 0x3ff + #define THRESHOLD_MIN_ADC_CODE 0x0 + +@@ -25,7 +26,8 @@ struct tsens_priv; + + /* IP version numbers in ascending order */ + enum tsens_ver { +- VER_0_1 = 0, ++ VER_0 = 0, ++ VER_0_1, + VER_1_X, + VER_2_X, + }; diff --git a/target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch b/target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch new file mode 100644 index 0000000000..109f524bbd --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch @@ -0,0 +1,28 @@ +From efa0d50a6c5ec7619371dfe4d3e6ca54b73787d5 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 25 Nov 2020 16:47:21 +0100 +Subject: [PATCH 02/10] drivers: thermal: tsens: Don't hardcode sensor slope + +Function compute_intercept_slope hardcode the sensor slope to +SLOPE_DEFAULT. Change this and use the default value only if a slope is +not defined. This is needed for tsens VER_0 that has a hardcoded slope +table. + +Signed-off-by: Ansuel Smith +Reviewed-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/thermal/qcom/tsens.c ++++ b/drivers/thermal/qcom/tsens.c +@@ -86,7 +86,8 @@ void compute_intercept_slope(struct tsen + "%s: sensor%d - data_point1:%#x data_point2:%#x\n", + __func__, i, p1[i], p2[i]); + +- priv->sensor[i].slope = SLOPE_DEFAULT; ++ if (!priv->sensor[i].slope) ++ priv->sensor[i].slope = SLOPE_DEFAULT; + if (mode == TWO_PT_CALIB) { + /* + * slope (m) = adc_code2 - adc_code1 (y2 - y1)/ diff --git a/target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch b/target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch new file mode 100644 index 0000000000..bf378107c6 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch @@ -0,0 +1,119 @@ +From 6bac2e2fa36c2d7c304768a689d8b73155b90aa2 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 25 Nov 2020 17:15:51 +0100 +Subject: [PATCH 03/10] drivers: thermal: tsens: Convert msm8960 to reg_field + +Convert msm9860 driver to reg_field to use the init_common +function. + +Signed-off-by: Ansuel Smith +Acked-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens-8960.c | 80 ++++++++++++++++++++++++++++++- + 1 file changed, 79 insertions(+), 1 deletion(-) + +--- a/drivers/thermal/qcom/tsens-8960.c ++++ b/drivers/thermal/qcom/tsens-8960.c +@@ -51,11 +51,22 @@ + #define MIN_LIMIT_TH 0x0 + #define MAX_LIMIT_TH 0xff + +-#define S0_STATUS_ADDR 0x3628 + #define INT_STATUS_ADDR 0x363c + #define TRDY_MASK BIT(7) + #define TIMEOUT_US 100 + ++#define S0_STATUS_OFF 0x3628 ++#define S1_STATUS_OFF 0x362c ++#define S2_STATUS_OFF 0x3630 ++#define S3_STATUS_OFF 0x3634 ++#define S4_STATUS_OFF 0x3638 ++#define S5_STATUS_OFF 0x3664 /* Sensors 5-10 found on apq8064/msm8960 */ ++#define S6_STATUS_OFF 0x3668 ++#define S7_STATUS_OFF 0x366c ++#define S8_STATUS_OFF 0x3670 ++#define S9_STATUS_OFF 0x3674 ++#define S10_STATUS_OFF 0x3678 ++ + static int suspend_8960(struct tsens_priv *priv) + { + int ret; +@@ -269,6 +280,71 @@ static int get_temp_8960(const struct ts + return -ETIMEDOUT; + } + ++static struct tsens_features tsens_8960_feat = { ++ .ver_major = VER_0, ++ .crit_int = 0, ++ .adc = 1, ++ .srot_split = 0, ++ .max_sensors = 11, ++}; ++ ++static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = { ++ /* ----- SROT ------ */ ++ /* No VERSION information */ ++ ++ /* CNTL */ ++ [TSENS_EN] = REG_FIELD(CNTL_ADDR, 0, 0), ++ [TSENS_SW_RST] = REG_FIELD(CNTL_ADDR, 1, 1), ++ /* 8960 has 5 sensors, 8660 has 11, we only handle 5 */ ++ [SENSOR_EN] = REG_FIELD(CNTL_ADDR, 3, 7), ++ ++ /* ----- TM ------ */ ++ /* INTERRUPT ENABLE */ ++ /* NO INTERRUPT ENABLE */ ++ ++ /* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */ ++ [LOW_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 0, 7), ++ [UP_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 8, 15), ++ /* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield ++ * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp ++ * MIN_THRESH_0 -> CRIT_THRESH_1 ++ * MAX_THRESH_0 -> CRIT_THRESH_0 ++ */ ++ [CRIT_THRESH_1] = REG_FIELD(THRESHOLD_ADDR, 16, 23), ++ [CRIT_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 24, 31), ++ ++ /* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */ ++ /* 1 == clear, 0 == normal operation */ ++ [LOW_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 9, 9), ++ [UP_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 10, 10), ++ ++ /* NO CRITICAL INTERRUPT SUPPORT on 8960 */ ++ ++ /* Sn_STATUS */ ++ [LAST_TEMP_0] = REG_FIELD(S0_STATUS_OFF, 0, 7), ++ [LAST_TEMP_1] = REG_FIELD(S1_STATUS_OFF, 0, 7), ++ [LAST_TEMP_2] = REG_FIELD(S2_STATUS_OFF, 0, 7), ++ [LAST_TEMP_3] = REG_FIELD(S3_STATUS_OFF, 0, 7), ++ [LAST_TEMP_4] = REG_FIELD(S4_STATUS_OFF, 0, 7), ++ [LAST_TEMP_5] = REG_FIELD(S5_STATUS_OFF, 0, 7), ++ [LAST_TEMP_6] = REG_FIELD(S6_STATUS_OFF, 0, 7), ++ [LAST_TEMP_7] = REG_FIELD(S7_STATUS_OFF, 0, 7), ++ [LAST_TEMP_8] = REG_FIELD(S8_STATUS_OFF, 0, 7), ++ [LAST_TEMP_9] = REG_FIELD(S9_STATUS_OFF, 0, 7), ++ [LAST_TEMP_10] = REG_FIELD(S10_STATUS_OFF, 0, 7), ++ ++ /* No VALID field on 8960 */ ++ /* TSENS_INT_STATUS bits: 1 == threshold violated */ ++ [MIN_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 0, 0), ++ [LOWER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 1, 1), ++ [UPPER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 2, 2), ++ /* No CRITICAL field on 8960 */ ++ [MAX_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 3, 3), ++ ++ /* TRDY: 1=ready, 0=in progress */ ++ [TRDY] = REG_FIELD(INT_STATUS_ADDR, 7, 7), ++}; ++ + static const struct tsens_ops ops_8960 = { + .init = init_8960, + .calibrate = calibrate_8960, +@@ -282,4 +358,6 @@ static const struct tsens_ops ops_8960 = + struct tsens_plat_data data_8960 = { + .num_sensors = 11, + .ops = &ops_8960, ++ .feat = &tsens_8960_feat, ++ .fields = tsens_8960_regfields, + }; diff --git a/target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch b/target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch new file mode 100644 index 0000000000..ae8a52c100 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch @@ -0,0 +1,81 @@ +From c04f98a496929f75d75c65115d5717423c3d0634 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 25 Nov 2020 17:16:36 +0100 +Subject: [PATCH 04/10] drivers: thermal: tsens: Use init_common for msm8960 + +Use init_common and drop custom init for msm8960. + +Signed-off-by: Ansuel Smith +Reviewed-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens-8960.c | 52 +------------------------------ + 1 file changed, 1 insertion(+), 51 deletions(-) + +--- a/drivers/thermal/qcom/tsens-8960.c ++++ b/drivers/thermal/qcom/tsens-8960.c +@@ -173,56 +173,6 @@ static void disable_8960(struct tsens_pr + regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); + } + +-static int init_8960(struct tsens_priv *priv) +-{ +- int ret, i; +- u32 reg_cntl; +- +- priv->tm_map = dev_get_regmap(priv->dev, NULL); +- if (!priv->tm_map) +- return -ENODEV; +- +- /* +- * The status registers for each sensor are discontiguous +- * because some SoCs have 5 sensors while others have more +- * but the control registers stay in the same place, i.e +- * directly after the first 5 status registers. +- */ +- for (i = 0; i < priv->num_sensors; i++) { +- if (i >= 5) +- priv->sensor[i].status = S0_STATUS_ADDR + 40; +- priv->sensor[i].status += i * 4; +- } +- +- reg_cntl = SW_RST; +- ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl); +- if (ret) +- return ret; +- +- if (priv->num_sensors > 1) { +- reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); +- reg_cntl &= ~SW_RST; +- ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR, +- CONFIG_MASK, CONFIG); +- } else { +- reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16); +- reg_cntl &= ~CONFIG_MASK_8660; +- reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660; +- } +- +- reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT; +- ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); +- if (ret) +- return ret; +- +- reg_cntl |= EN; +- ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); +- if (ret) +- return ret; +- +- return 0; +-} +- + static int calibrate_8960(struct tsens_priv *priv) + { + int i; +@@ -346,7 +296,7 @@ static const struct reg_field tsens_8960 + }; + + static const struct tsens_ops ops_8960 = { +- .init = init_8960, ++ .init = init_common, + .calibrate = calibrate_8960, + .get_temp = get_temp_8960, + .enable = enable_8960, diff --git a/target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch b/target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch new file mode 100644 index 0000000000..7b01a67d90 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch @@ -0,0 +1,66 @@ +From b3e8bd33b84a6b6c863bd1733bd15b5f1483b8ab Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 25 Nov 2020 17:06:55 +0100 +Subject: [PATCH 05/10] drivers: thermal: tsens: Fix bug in sensor enable for + msm8960 + +Device based on tsens VER_0 contains a hardware bug that results in some +problem with sensor enablement. Sensor id 6-11 can't be enabled +selectively and all of them must be enabled in one step. + +Signed-off-by: Ansuel Smith +Acked-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens-8960.c | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +--- a/drivers/thermal/qcom/tsens-8960.c ++++ b/drivers/thermal/qcom/tsens-8960.c +@@ -27,9 +27,9 @@ + #define EN BIT(0) + #define SW_RST BIT(1) + #define SENSOR0_EN BIT(3) ++#define MEASURE_PERIOD BIT(18) + #define SLP_CLK_ENA BIT(26) + #define SLP_CLK_ENA_8660 BIT(24) +-#define MEASURE_PERIOD 1 + #define SENSOR0_SHIFT 3 + + /* INT_STATUS_ADDR bitmasks */ +@@ -126,17 +126,34 @@ static int resume_8960(struct tsens_priv + static int enable_8960(struct tsens_priv *priv, int id) + { + int ret; +- u32 reg, mask; ++ u32 reg, mask = BIT(id); + + ret = regmap_read(priv->tm_map, CNTL_ADDR, ®); + if (ret) + return ret; + +- mask = BIT(id + SENSOR0_SHIFT); ++ /* HARDWARE BUG: ++ * On platforms with more than 6 sensors, all remaining sensors ++ * must be enabled together, otherwise undefined results are expected. ++ * (Sensor 6-7 disabled, Sensor 3 disabled...) In the original driver, ++ * all the sensors are enabled in one step hence this bug is not ++ * triggered. ++ */ ++ if (id > 5) ++ mask = GENMASK(10, 6); ++ ++ mask <<= SENSOR0_SHIFT; ++ ++ /* Sensors already enabled. Skip. */ ++ if ((reg & mask) == mask) ++ return 0; ++ + ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST); + if (ret) + return ret; + ++ reg |= MEASURE_PERIOD; ++ + if (priv->num_sensors > 1) + reg |= mask | SLP_CLK_ENA | EN; + else diff --git a/target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch b/target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch new file mode 100644 index 0000000000..a82f596954 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch @@ -0,0 +1,109 @@ +From 1ff9f982051759e0387e8c7e793b49c48eae291d Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Wed, 25 Nov 2020 17:11:05 +0100 +Subject: [PATCH 06/10] drivers: thermal: tsens: Replace custom 8960 apis with + generic apis + +Rework calibrate function to use common function. Derive the offset from +a missing hardcoded slope table and the data from the nvmem calib +efuses. +Drop custom get_temp function and use generic api. + +Signed-off-by: Ansuel Smith +Acked-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens-8960.c | 56 +++++++++---------------------- + 1 file changed, 15 insertions(+), 41 deletions(-) + +--- a/drivers/thermal/qcom/tsens-8960.c ++++ b/drivers/thermal/qcom/tsens-8960.c +@@ -67,6 +67,13 @@ + #define S9_STATUS_OFF 0x3674 + #define S10_STATUS_OFF 0x3678 + ++/* Original slope - 200 to compensate mC to C inaccuracy */ ++static u32 tsens_msm8960_slope[] = { ++ 976, 976, 954, 976, ++ 911, 932, 932, 999, ++ 932, 999, 932 ++ }; ++ + static int suspend_8960(struct tsens_priv *priv) + { + int ret; +@@ -194,9 +201,7 @@ static int calibrate_8960(struct tsens_p + { + int i; + char *data; +- +- ssize_t num_read = priv->num_sensors; +- struct tsens_sensor *s = priv->sensor; ++ u32 p1[11]; + + data = qfprom_read(priv->dev, "calib"); + if (IS_ERR(data)) +@@ -204,49 +209,18 @@ static int calibrate_8960(struct tsens_p + if (IS_ERR(data)) + return PTR_ERR(data); + +- for (i = 0; i < num_read; i++, s++) +- s->offset = data[i]; ++ for (i = 0; i < priv->num_sensors; i++) { ++ p1[i] = data[i]; ++ priv->sensor[i].slope = tsens_msm8960_slope[i]; ++ } ++ ++ compute_intercept_slope(priv, p1, NULL, ONE_PT_CALIB); + + kfree(data); + + return 0; + } + +-/* Temperature on y axis and ADC-code on x-axis */ +-static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s) +-{ +- int slope, offset; +- +- slope = thermal_zone_get_slope(s->tzd); +- offset = CAL_MDEGC - slope * s->offset; +- +- return adc_code * slope + offset; +-} +- +-static int get_temp_8960(const struct tsens_sensor *s, int *temp) +-{ +- int ret; +- u32 code, trdy; +- struct tsens_priv *priv = s->priv; +- unsigned long timeout; +- +- timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); +- do { +- ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy); +- if (ret) +- return ret; +- if (!(trdy & TRDY_MASK)) +- continue; +- ret = regmap_read(priv->tm_map, s->status, &code); +- if (ret) +- return ret; +- *temp = code_to_mdegC(code, s); +- return 0; +- } while (time_before(jiffies, timeout)); +- +- return -ETIMEDOUT; +-} +- + static struct tsens_features tsens_8960_feat = { + .ver_major = VER_0, + .crit_int = 0, +@@ -315,7 +289,7 @@ static const struct reg_field tsens_8960 + static const struct tsens_ops ops_8960 = { + .init = init_common, + .calibrate = calibrate_8960, +- .get_temp = get_temp_8960, ++ .get_temp = get_temp_common, + .enable = enable_8960, + .disable = disable_8960, + .suspend = suspend_8960, diff --git a/target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch b/target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch new file mode 100644 index 0000000000..77ca3cfe45 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch @@ -0,0 +1,65 @@ +From 5716a61239c6ac9ceb137e825e93c3aea06c4634 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Fri, 19 Mar 2021 00:48:23 +0100 +Subject: [PATCH 07/10] drivers: thermal: tsens: Drop unused define for msm8960 + +Drop unused define for msm8960 replaced by generic api and reg_field. + +Signed-off-by: Ansuel Smith +Reviewed-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens-8960.c | 24 +----------------------- + 1 file changed, 1 insertion(+), 23 deletions(-) + +--- a/drivers/thermal/qcom/tsens-8960.c ++++ b/drivers/thermal/qcom/tsens-8960.c +@@ -10,8 +10,6 @@ + #include + #include "tsens.h" + +-#define CAL_MDEGC 30000 +- + #define CONFIG_ADDR 0x3640 + #define CONFIG_ADDR_8660 0x3620 + /* CONFIG_ADDR bitmasks */ +@@ -21,39 +19,19 @@ + #define CONFIG_SHIFT_8660 28 + #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660) + +-#define STATUS_CNTL_ADDR_8064 0x3660 + #define CNTL_ADDR 0x3620 + /* CNTL_ADDR bitmasks */ + #define EN BIT(0) + #define SW_RST BIT(1) +-#define SENSOR0_EN BIT(3) ++ + #define MEASURE_PERIOD BIT(18) + #define SLP_CLK_ENA BIT(26) + #define SLP_CLK_ENA_8660 BIT(24) + #define SENSOR0_SHIFT 3 + +-/* INT_STATUS_ADDR bitmasks */ +-#define MIN_STATUS_MASK BIT(0) +-#define LOWER_STATUS_CLR BIT(1) +-#define UPPER_STATUS_CLR BIT(2) +-#define MAX_STATUS_MASK BIT(3) +- + #define THRESHOLD_ADDR 0x3624 +-/* THRESHOLD_ADDR bitmasks */ +-#define THRESHOLD_MAX_LIMIT_SHIFT 24 +-#define THRESHOLD_MIN_LIMIT_SHIFT 16 +-#define THRESHOLD_UPPER_LIMIT_SHIFT 8 +-#define THRESHOLD_LOWER_LIMIT_SHIFT 0 +- +-/* Initial temperature threshold values */ +-#define LOWER_LIMIT_TH 0x50 +-#define UPPER_LIMIT_TH 0xdf +-#define MIN_LIMIT_TH 0x0 +-#define MAX_LIMIT_TH 0xff + + #define INT_STATUS_ADDR 0x363c +-#define TRDY_MASK BIT(7) +-#define TIMEOUT_US 100 + + #define S0_STATUS_OFF 0x3628 + #define S1_STATUS_OFF 0x362c diff --git a/target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch b/target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch new file mode 100644 index 0000000000..127abaefc3 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch @@ -0,0 +1,26 @@ +From 0d0c22a59bf2672b57e23da9a9ea743e91b71f54 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Sat, 25 Jul 2020 19:55:57 +0200 +Subject: [PATCH 08/10] drivers: thermal: tsens: Add support for ipq8064-tsens + +Add support for tsens present in ipq806x SoCs based on generic msm8960 +tsens driver. + +Signed-off-by: Ansuel Smith +Reviewed-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/thermal/qcom/tsens.c ++++ b/drivers/thermal/qcom/tsens.c +@@ -968,6 +968,9 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, t + + static const struct of_device_id tsens_table[] = { + { ++ .compatible = "qcom,ipq8064-tsens", ++ .data = &data_8960, ++ }, { + .compatible = "qcom,msm8916-tsens", + .data = &data_8916, + }, { diff --git a/target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch b/target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch new file mode 100644 index 0000000000..382106863f --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch @@ -0,0 +1,112 @@ +From ac369071920d427dd484cf74cddba2774bba45f5 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Thu, 9 Jul 2020 22:35:54 +0200 +Subject: [PATCH 09/10] dt-bindings: thermal: tsens: Document ipq8064 bindings + +Document the use of bindings used for msm8960 tsens based devices. +msm8960 use the same gcc regs and is set as a child of the qcom gcc. + +Signed-off-by: Ansuel Smith +Reviewed-by: Rob Herring +--- + .../bindings/thermal/qcom-tsens.yaml | 56 ++++++++++++++++--- + 1 file changed, 48 insertions(+), 8 deletions(-) + +--- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml ++++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml +@@ -19,6 +19,11 @@ description: | + properties: + compatible: + oneOf: ++ - description: msm9860 TSENS based ++ items: ++ - enum: ++ - qcom,ipq8064-tsens ++ + - description: v0.1 of TSENS + items: + - enum: +@@ -73,7 +78,9 @@ properties: + maxItems: 2 + items: + - const: calib +- - const: calib_sel ++ - enum: ++ - calib_backup ++ - calib_sel + + "#qcom,sensors": + description: +@@ -88,12 +95,20 @@ properties: + Number of cells required to uniquely identify the thermal sensors. Since + we have multiple sensors this is set to 1 + ++required: ++ - compatible ++ - interrupts ++ - interrupt-names ++ - "#thermal-sensor-cells" ++ - "#qcom,sensors" ++ + allOf: + - if: + properties: + compatible: + contains: + enum: ++ - qcom,ipq8064-tsens + - qcom,msm8916-tsens + - qcom,msm8974-tsens + - qcom,msm8976-tsens +@@ -114,19 +129,44 @@ allOf: + interrupt-names: + minItems: 2 + +-required: +- - compatible +- - reg +- - "#qcom,sensors" +- - interrupts +- - interrupt-names +- - "#thermal-sensor-cells" ++ - if: ++ properties: ++ compatible: ++ contains: ++ enum: ++ - qcom,tsens-v0_1 ++ - qcom,tsens-v1 ++ - qcom,tsens-v2 ++ ++ then: ++ required: ++ - reg + + additionalProperties: false + + examples: + - | + #include ++ // Example msm9860 based SoC (ipq8064): ++ gcc: clock-controller { ++ ++ /* ... */ ++ ++ tsens: thermal-sensor { ++ compatible = "qcom,ipq8064-tsens"; ++ ++ nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>; ++ nvmem-cell-names = "calib", "calib_backup"; ++ interrupts = ; ++ interrupt-names = "uplow"; ++ ++ #qcom,sensors = <11>; ++ #thermal-sensor-cells = <1>; ++ }; ++ }; ++ ++ - | ++ #include + // Example 1 (legacy: for pre v1 IP): + tsens1: thermal-sensor@900000 { + compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1"; diff --git a/target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch b/target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch new file mode 100644 index 0000000000..6cdc0b263f --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch @@ -0,0 +1,32 @@ +From 68e720ed73c8f038c8c500e4c49c1e65a993a448 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Tue, 6 Apr 2021 04:45:31 +0200 +Subject: [PATCH 10/10] drivers: thermal: tsens: Fix wrong slope on msm-8960 + +Some user using some stats with the old legacy implementation and the +new implementation using the compute_intercept_slope reported an offset +of 3C. Fix the slope table to reflect the original temp. + +Signed-off-by: Ansuel Smith +--- + drivers/thermal/qcom/tsens-8960.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/thermal/qcom/tsens-8960.c ++++ b/drivers/thermal/qcom/tsens-8960.c +@@ -45,11 +45,11 @@ + #define S9_STATUS_OFF 0x3674 + #define S10_STATUS_OFF 0x3678 + +-/* Original slope - 200 to compensate mC to C inaccuracy */ ++/* Original slope - 350 to compensate mC to C inaccuracy */ + static u32 tsens_msm8960_slope[] = { +- 976, 976, 954, 976, +- 911, 932, 932, 999, +- 932, 999, 932 ++ 826, 826, 804, 826, ++ 761, 782, 782, 849, ++ 782, 849, 782 + }; + + static int suspend_8960(struct tsens_priv *priv) diff --git a/target/linux/ipq806x/patches-5.15/107-1-thermal-qcom-tsens-init-debugfs-only-with-successful.patch b/target/linux/ipq806x/patches-5.15/107-1-thermal-qcom-tsens-init-debugfs-only-with-successful.patch new file mode 100644 index 0000000000..1dc2d2e55e --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/107-1-thermal-qcom-tsens-init-debugfs-only-with-successful.patch @@ -0,0 +1,41 @@ +From 8f32d48a309246a80bdca505968085a484d54408 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Mon, 19 Apr 2021 03:01:53 +0200 +Subject: [thermal-next PATCH v2 1/2] thermal: qcom: tsens: init debugfs only with + successful probe + +calibrate and tsens_register can fail or PROBE_DEFER. This will cause a +double or a wrong init of the debugfs information. Init debugfs only +with successful probe fixing warning about directory already present. + +Signed-off-by: Ansuel Smith +Acked-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/thermal/qcom/tsens.c ++++ b/drivers/thermal/qcom/tsens.c +@@ -918,8 +918,6 @@ int __init init_common(struct tsens_priv + if (tsens_version(priv) >= VER_0_1) + tsens_enable_irq(priv); + +- tsens_debug_init(op); +- + err_put_device: + put_device(&op->dev); + return ret; +@@ -1155,7 +1153,12 @@ static int tsens_probe(struct platform_d + } + } + +- return tsens_register(priv); ++ ret = tsens_register(priv); ++ ++ if (!ret) ++ tsens_debug_init(pdev); ++ ++ return ret; + } + + static int tsens_remove(struct platform_device *pdev) diff --git a/target/linux/ipq806x/patches-5.15/107-2-thermal-qcom-tsens-simplify-debugfs-init-function.patch b/target/linux/ipq806x/patches-5.15/107-2-thermal-qcom-tsens-simplify-debugfs-init-function.patch new file mode 100644 index 0000000000..0fbc4bd8ca --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/107-2-thermal-qcom-tsens-simplify-debugfs-init-function.patch @@ -0,0 +1,54 @@ +From 4204f22060f7a5d42c6ccb4d4c25a6a875571099 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith +Date: Mon, 19 Apr 2021 03:08:37 +0200 +Subject: [thermal-next PATCH v2 2/2] thermal: qcom: tsens: simplify debugfs init + function + +Simplify debugfs init function. +- Add check for existing dev directory. +- Fix wrong version in dbg_version_show (with version 0.0.0, 0.1.0 was + incorrectly reported) + +Signed-off-by: Ansuel Smith +Reviewed-by: Thara Gopinath +--- + drivers/thermal/qcom/tsens.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +--- a/drivers/thermal/qcom/tsens.c ++++ b/drivers/thermal/qcom/tsens.c +@@ -692,7 +692,7 @@ static int dbg_version_show(struct seq_f + return ret; + seq_printf(s, "%d.%d.%d\n", maj_ver, min_ver, step_ver); + } else { +- seq_puts(s, "0.1.0\n"); ++ seq_printf(s, "0.%d.0\n", priv->feat->ver_major); + } + + return 0; +@@ -704,21 +704,17 @@ DEFINE_SHOW_ATTRIBUTE(dbg_sensors); + static void tsens_debug_init(struct platform_device *pdev) + { + struct tsens_priv *priv = platform_get_drvdata(pdev); +- struct dentry *root, *file; + +- root = debugfs_lookup("tsens", NULL); +- if (!root) ++ priv->debug_root = debugfs_lookup("tsens", NULL); ++ if (!priv->debug_root) + priv->debug_root = debugfs_create_dir("tsens", NULL); +- else +- priv->debug_root = root; + +- file = debugfs_lookup("version", priv->debug_root); +- if (!file) ++ if (!debugfs_lookup("version", priv->debug_root)) + debugfs_create_file("version", 0444, priv->debug_root, + pdev, &dbg_version_fops); + + /* A directory for each instance of the TSENS IP */ +- priv->debug = debugfs_create_dir(dev_name(&pdev->dev), priv->debug_root); ++ priv->debug = debugfs_lookup(dev_name(&pdev->dev), priv->debug_root); + debugfs_create_file("sensors", 0444, priv->debug, pdev, &dbg_sensors_fops); + } + #else diff --git a/target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch b/target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch new file mode 100644 index 0000000000..dd1e506e5b --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch @@ -0,0 +1,75 @@ +From e67f325e9cd67562b761e884680c0fec03a6f404 Mon Sep 17 00:00:00 2001 +From: Matthew Hagan +Date: Tue, 8 Jun 2021 19:59:06 +0100 +Subject: net: stmmac: explicitly deassert GMAC_AHB_RESET + +We are currently assuming that GMAC_AHB_RESET will already be deasserted +by the bootloader. However if this has not been done, probing of the GMAC +will fail. To remedy this we must ensure GMAC_AHB_RESET has been deasserted +prior to probing. + +v2 changes: + - remove NULL condition check for stmmac_ahb_rst in stmmac_main.c + - unwrap dev_err() message in stmmac_main.c + - add PTR_ERR() around plat->stmmac_ahb_rst in stmmac_platform.c + +v3 changes: + - add error pointer to dev_err() output + - add reset_control_assert(stmmac_ahb_rst) in stmmac_dvr_remove + - revert PTR_ERR() around plat->stmmac_ahb_rst since this is performed + on the returned value of ret by the calling function + +Signed-off-by: Matthew Hagan +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++ + drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++++ + include/linux/stmmac.h | 1 + + 3 files changed, 12 insertions(+) + +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5021,6 +5021,10 @@ int stmmac_dvr_probe(struct device *devi + reset_control_reset(priv->plat->stmmac_rst); + } + ++ ret = reset_control_deassert(priv->plat->stmmac_ahb_rst); ++ if (ret == -ENOTSUPP) ++ dev_err(priv->device, "unable to bring out of ahb reset\n"); ++ + /* Init MAC and get the capabilities */ + ret = stmmac_hw_init(priv); + if (ret) +@@ -5245,6 +5249,7 @@ int stmmac_dvr_remove(struct device *dev + phylink_destroy(priv->phylink); + if (priv->plat->stmmac_rst) + reset_control_assert(priv->plat->stmmac_rst); ++ reset_control_assert(priv->plat->stmmac_ahb_rst); + pm_runtime_put(dev); + pm_runtime_disable(dev); + if (priv->hw->pcs != STMMAC_PCS_TBI && +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +@@ -617,6 +617,12 @@ stmmac_probe_config_dt(struct platform_d + plat->stmmac_rst = NULL; + } + ++ plat->stmmac_ahb_rst = devm_reset_control_get_optional_shared( ++ &pdev->dev, "ahb"); ++ if (IS_ERR(plat->stmmac_ahb_rst)) ++ if (PTR_ERR(plat->stmmac_ahb_rst) == -EPROBE_DEFER) ++ goto error_hw_init; ++ + return plat; + + error_hw_init: +--- a/include/linux/stmmac.h ++++ b/include/linux/stmmac.h +@@ -192,6 +192,7 @@ struct plat_stmmacenet_data { + unsigned int clk_ref_rate; + s32 ptp_max_adj; + struct reset_control *stmmac_rst; ++ struct reset_control *stmmac_ahb_rst; + struct stmmac_axi *axi; + int has_gmac4; + bool has_sun8i; diff --git a/target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch b/target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch new file mode 100644 index 0000000000..4a047ed6eb --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch @@ -0,0 +1,64 @@ +From f95c4c56d65225a537a2d88735fde7ec4d37641d Mon Sep 17 00:00:00 2001 +From: Matthew Hagan +Date: Sat, 5 Jun 2021 18:35:38 +0100 +Subject: ARM: dts: qcom: add ahb reset to ipq806x-gmac + +Add GMAC_AHB_RESET to the resets property of each gmac node. + +Signed-off-by: Matthew Hagan +Link: https://lore.kernel.org/r/20210605173546.4102455-2-mnhagan88@gmail.com +Signed-off-by: Bjorn Andersson +--- + arch/arm/boot/dts/qcom-ipq8064.dtsi | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +@@ -1335,8 +1335,9 @@ + clocks = <&gcc GMAC_CORE1_CLK>; + clock-names = "stmmaceth"; + +- resets = <&gcc GMAC_CORE1_RESET>; +- reset-names = "stmmaceth"; ++ resets = <&gcc GMAC_CORE1_RESET>, ++ <&gcc GMAC_AHB_RESET>; ++ reset-names = "stmmaceth", "ahb"; + + status = "disabled"; + }; +@@ -1358,8 +1359,9 @@ + clocks = <&gcc GMAC_CORE2_CLK>; + clock-names = "stmmaceth"; + +- resets = <&gcc GMAC_CORE2_RESET>; +- reset-names = "stmmaceth"; ++ resets = <&gcc GMAC_CORE2_RESET>, ++ <&gcc GMAC_AHB_RESET>; ++ reset-names = "stmmaceth", "ahb"; + + status = "disabled"; + }; +@@ -1381,8 +1383,9 @@ + clocks = <&gcc GMAC_CORE3_CLK>; + clock-names = "stmmaceth"; + +- resets = <&gcc GMAC_CORE3_RESET>; +- reset-names = "stmmaceth"; ++ resets = <&gcc GMAC_CORE3_RESET>, ++ <&gcc GMAC_AHB_RESET>; ++ reset-names = "stmmaceth", "ahb"; + + status = "disabled"; + }; +@@ -1404,8 +1407,9 @@ + clocks = <&gcc GMAC_CORE4_CLK>; + clock-names = "stmmaceth"; + +- resets = <&gcc GMAC_CORE4_RESET>; +- reset-names = "stmmaceth"; ++ resets = <&gcc GMAC_CORE4_RESET>, ++ <&gcc GMAC_AHB_RESET>; ++ reset-names = "stmmaceth", "ahb"; + + status = "disabled"; + }; diff --git a/target/linux/ipq806x/patches-5.15/850-soc-add-qualcomm-syscon.patch b/target/linux/ipq806x/patches-5.15/850-soc-add-qualcomm-syscon.patch new file mode 100644 index 0000000000..8325e10389 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/850-soc-add-qualcomm-syscon.patch @@ -0,0 +1,121 @@ +From: Christian Lamparter +Subject: SoC: add qualcomm syscon +--- a/drivers/soc/qcom/Makefile ++++ b/drivers/soc/qcom/Makefile +@@ -21,6 +21,7 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o + obj-$(CONFIG_QCOM_SMSM) += smsm.o + obj-$(CONFIG_QCOM_SOCINFO) += socinfo.o + obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o ++obj-$(CONFIG_QCOM_TCSR) += qcom_tcsr.o + obj-$(CONFIG_QCOM_APR) += apr.o + obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o + obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o +--- a/drivers/soc/qcom/Kconfig ++++ b/drivers/soc/qcom/Kconfig +@@ -189,6 +189,13 @@ config QCOM_SOCINFO + Say yes here to support the Qualcomm socinfo driver, providing + information about the SoC to user space. + ++config QCOM_TCSR ++ tristate "QCOM Top Control and Status Registers" ++ depends on ARCH_QCOM ++ help ++ Say y here to enable TCSR support. The TCSR provides control ++ functions for various peripherals. ++ + config QCOM_WCNSS_CTRL + tristate "Qualcomm WCNSS control driver" + depends on ARCH_QCOM || COMPILE_TEST +--- /dev/null ++++ b/drivers/soc/qcom/qcom_tcsr.c +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (c) 2014, The Linux foundation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License rev 2 and ++ * only rev 2 as published by the free Software foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TCSR_USB_PORT_SEL 0xb0 ++ ++static int tcsr_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ const struct device_node *node = pdev->dev.of_node; ++ void __iomem *base; ++ u32 val; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ if (!of_property_read_u32(node, "qcom,usb-ctrl-select", &val)) { ++ dev_err(&pdev->dev, "setting usb port select = %d\n", val); ++ writel(val, base + TCSR_USB_PORT_SEL); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id tcsr_dt_match[] = { ++ { .compatible = "qcom,tcsr", }, ++ { }, ++}; ++ ++MODULE_DEVICE_TABLE(of, tcsr_dt_match); ++ ++static struct platform_driver tcsr_driver = { ++ .driver = { ++ .name = "tcsr", ++ .owner = THIS_MODULE, ++ .of_match_table = tcsr_dt_match, ++ }, ++ .probe = tcsr_probe, ++}; ++ ++module_platform_driver(tcsr_driver); ++ ++MODULE_AUTHOR("Andy Gross "); ++MODULE_DESCRIPTION("QCOM TCSR driver"); ++MODULE_LICENSE("GPL v2"); +--- /dev/null ++++ b/include/dt-bindings/soc/qcom,tcsr.h +@@ -0,0 +1,23 @@ ++/* Copyright (c) 2014, The Linux Foundation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef __DT_BINDINGS_QCOM_TCSR_H ++#define __DT_BINDINGS_QCOM_TCSR_H ++ ++#define TCSR_USB_SELECT_USB3_P0 0x1 ++#define TCSR_USB_SELECT_USB3_P1 0x2 ++#define TCSR_USB_SELECT_USB3_DUAL 0x3 ++ ++/* TCSR A/B REG */ ++#define IPQ806X_TCSR_REG_A_ADM_CRCI_MUX_SEL 0 ++#define IPQ806X_TCSR_REG_B_ADM_CRCI_MUX_SEL 1 ++ ++#endif diff --git a/target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch b/target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch new file mode 100644 index 0000000000..dba917872c --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch @@ -0,0 +1,37 @@ +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1794,6 +1794,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGL + + endchoice + ++config CMDLINE_OVERRIDE ++ bool "Use alternative cmdline from device tree" ++ help ++ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can ++ be used, this is not a good option for kernels that are shared across ++ devices. This setting enables using "chosen/cmdline-override" as the ++ cmdline if it exists in the device tree. ++ + config CMDLINE + string "Default kernel command string" + default "" +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -1059,6 +1059,17 @@ int __init early_init_dt_scan_chosen(uns + if (p != NULL && l > 0) + strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE)); + ++ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different ++ * device tree option of chosen/bootargs-override. This is ++ * helpful on boards where u-boot sets bootargs, and is unable ++ * to be modified. ++ */ ++#ifdef CONFIG_CMDLINE_OVERRIDE ++ p = of_get_flat_dt_prop(node, "bootargs-override", &l); ++ if (p != NULL && l > 0) ++ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); ++#endif ++ + /* + * CONFIG_CMDLINE is meant to be a default in case nothing else + * managed to set the command line, unless CONFIG_CMDLINE_FORCE From 4c5d5c66ca443d3570c14a6b3ccae5041d52fef0 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Sat, 6 Nov 2021 14:58:30 +0100 Subject: [PATCH 13/23] ipq806x: 5:15: refresh config Refreshed using make kernel_menuconfig CONFIG_TARGET=generic Signed-off-by: Ansuel Smith --- target/linux/ipq806x/config-5.15 | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/target/linux/ipq806x/config-5.15 b/target/linux/ipq806x/config-5.15 index f2880b5d66..5c1b641eee 100644 --- a/target/linux/ipq806x/config-5.15 +++ b/target/linux/ipq806x/config-5.15 @@ -1,3 +1,4 @@ +CONFIG_AF_UNIX_OOB=y CONFIG_ALIGNMENT_TRAP=y # CONFIG_APQ_GCC_8084 is not set # CONFIG_APQ_MMCC_8084 is not set @@ -48,12 +49,12 @@ CONFIG_ARM_THUMB=y CONFIG_ARM_UNWIND=y CONFIG_ARM_VIRT_EXT=y CONFIG_AT803X_PHY=y +CONFIG_BINARY_PRINTF=y CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_MQ_PCI=y CONFIG_BOUNCE=y # CONFIG_CACHE_L2X0 is not set -CONFIG_CLKDEV_LOOKUP=y CONFIG_CLKSRC_QCOM=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMDLINE_OVERRIDE=y @@ -98,28 +99,24 @@ CONFIG_CPU_V7=y CONFIG_CRC16=y # CONFIG_CRC32_SARWATE is not set CONFIG_CRC32_SLICEBY8=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y +CONFIG_CRC8=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_DEV_QCOM_RNG=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_HW=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ZSTD=y CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_GPIO=y @@ -144,9 +141,9 @@ CONFIG_DWMAC_IPQ806X=y CONFIG_DYNAMIC_DEBUG=y CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y -CONFIG_ETHERNET_PACKET_MANGLE=y CONFIG_FIXED_PHY=y CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_BUG=y @@ -160,6 +157,7 @@ CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y CONFIG_GENERIC_IRQ_MULTI_HANDLER=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y CONFIG_GENERIC_PCI_IOMAP=y @@ -175,6 +173,7 @@ CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_VDSO_32=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_CDEV=y CONFIG_GRO_CELLS=y CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDEN_BRANCH_PREDICTOR=y @@ -189,8 +188,6 @@ CONFIG_HWMON=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y CONFIG_HW_RANDOM=y -CONFIG_HZ=100 -CONFIG_HZ_100=y CONFIG_HZ_FIXED=0 CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y @@ -215,6 +212,7 @@ CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_IRQ_WORK=y +CONFIG_KMAP_LOCAL=y CONFIG_KPSS_XCC=y CONFIG_KRAITCC=y CONFIG_KRAIT_CLOCKS=y @@ -223,11 +221,13 @@ CONFIG_LIBFDT=y CONFIG_LLD_VERSION=0 CONFIG_LOCK_DEBUGGING_SUPPORT=y CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_LTO_NONE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_MDIO_BITBANG=y CONFIG_MDIO_BUS=y CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y CONFIG_MDIO_GPIO=y CONFIG_MDIO_IPQ8064=y # CONFIG_MDM_GCC_9615 is not set @@ -250,7 +250,6 @@ CONFIG_MMC_SDHCI_IO_ACCESSORS=y CONFIG_MMC_SDHCI_MSM=y # CONFIG_MMC_SDHCI_PCI is not set CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_TIFM_SD is not set CONFIG_MODULES_USE_ELF_REL=y CONFIG_MSM_GCC_8660=y # CONFIG_MSM_GCC_8916 is not set @@ -291,6 +290,8 @@ CONFIG_NET_DSA_QCA8K=y CONFIG_NET_DSA_TAG_QCA=y CONFIG_NET_FLOW_LIMIT=y CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y CONFIG_NET_SWITCHDEV=y CONFIG_NLS=y CONFIG_NO_HZ=y @@ -374,6 +375,7 @@ CONFIG_POWER_SUPPLY=y CONFIG_PPS=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y # CONFIG_QCOM_A53PLL is not set CONFIG_QCOM_ADM=y CONFIG_QCOM_BAM_DMA=y @@ -405,6 +407,7 @@ CONFIG_QCOM_WDT=y # CONFIG_QCS_TURING_404 is not set CONFIG_RAS=y CONFIG_RATIONAL=y +CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y CONFIG_REGULATOR=y @@ -449,6 +452,7 @@ CONFIG_SMP_ON_UP=y # CONFIG_SM_GPUCC_8250 is not set # CONFIG_SM_VIDEOCC_8150 is not set # CONFIG_SM_VIDEOCC_8250 is not set +CONFIG_SOCK_RX_QUEUE_MAPPING=y CONFIG_SPARSE_IRQ=y CONFIG_SPI=y CONFIG_SPI_MASTER=y @@ -480,9 +484,6 @@ CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UBIFS_FS_ZSTD=y # CONFIG_UCLAMP_TASK is not set CONFIG_UEVENT_HELPER_PATH="" CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" From 327677a71d74cc8230d54ecb63341347861fe065 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Tue, 11 Jan 2022 12:41:35 +0100 Subject: [PATCH 14/23] ipq806x: 5:15: drop upstream patch - Drop stmmac upstream patches - Drop tsens patches - Drop ADM driver - Drop SMEM parser Signed-off-by: Ansuel Smith --- ...-v5.11-dmaengine-qcom-add_ADM_driver.patch | 965 ------------------ ....12-mtd-parsers-Add-Qcom-SMEM-parser.patch | 217 ---- ...hermal-tsens-Add-VER_0-tsens-version.patch | 285 ------ ...al-tsens-Don-t-hardcode-sensor-slope.patch | 28 - ...l-tsens-Convert-msm8960-to-reg_field.patch | 119 --- ...al-tsens-Use-init_common-for-msm8960.patch | 81 -- ...tsens-Fix-bug-in-sensor-enable-for-m.patch | 66 -- ...tsens-Replace-custom-8960-apis-with-.patch | 109 -- ...tsens-Drop-unused-define-for-msm8960.patch | 65 -- ...-tsens-Add-support-for-ipq8064-tsens.patch | 26 - ...rmal-tsens-Document-ipq8064-bindings.patch | 112 -- ...al-tsens-Fix-wrong-slope-on-msm-8960.patch | 32 - ...c-explicitly-deassert-gmac-ahb-reset.patch | 75 -- ...s-qcom-add-ahb-reset-to-ipq806x-gmac.patch | 64 -- 14 files changed, 2244 deletions(-) delete mode 100644 target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch delete mode 100644 target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch delete mode 100644 target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch delete mode 100644 target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch delete mode 100644 target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch delete mode 100644 target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch diff --git a/target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch b/target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch deleted file mode 100644 index 2d24da01e4..0000000000 --- a/target/linux/ipq806x/patches-5.15/100-v5.11-dmaengine-qcom-add_ADM_driver.patch +++ /dev/null @@ -1,965 +0,0 @@ -From 5c9f8c2dbdbe53818bcde6aa6695e1331e5f841f Mon Sep 17 00:00:00 2001 -From: Jonathan McDowell -Date: Sat, 14 Nov 2020 14:02:33 +0000 -Subject: dmaengine: qcom: Add ADM driver - -Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA -controller found in the MSM8x60 and IPQ/APQ8064 platforms. - -The ADM supports both memory to memory transactions and memory -to/from peripheral device transactions. The controller also provides -flow control capabilities for transactions to/from peripheral devices. - -The initial release of this driver supports slave transfers to/from -peripherals and also incorporates CRCI (client rate control interface) -flow control. - -The hardware only supports a 32 bit physical address, so specifying -!PHYS_ADDR_T_64BIT gives maximum COMPILE_TEST coverage without having to -spend effort on kludging things in the code that will never actually be -needed on real hardware. - -Signed-off-by: Andy Gross -Signed-off-by: Thomas Pedersen -Signed-off-by: Jonathan McDowell -Link: https://lore.kernel.org/r/20201114140233.GM32650@earth.li -Signed-off-by: Vinod Koul ---- - drivers/dma/qcom/Kconfig | 11 + - drivers/dma/qcom/Makefile | 1 + - drivers/dma/qcom/qcom_adm.c | 903 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 915 insertions(+) - create mode 100644 drivers/dma/qcom/qcom_adm.c - ---- a/drivers/dma/qcom/Kconfig -+++ b/drivers/dma/qcom/Kconfig -@@ -1,4 +1,15 @@ - # SPDX-License-Identifier: GPL-2.0-only -+config QCOM_ADM -+ tristate "Qualcomm ADM support" -+ depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT -+ select DMA_ENGINE -+ select DMA_VIRTUAL_CHANNELS -+ help -+ Enable support for the Qualcomm Application Data Mover (ADM) DMA -+ controller, as present on MSM8x60, APQ8064, and IPQ8064 devices. -+ This controller provides DMA capabilities for both general purpose -+ and on-chip peripheral devices. -+ - config QCOM_BAM_DMA - tristate "QCOM BAM DMA support" - depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM) ---- a/drivers/dma/qcom/Makefile -+++ b/drivers/dma/qcom/Makefile -@@ -1,4 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o - obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o - obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o - hdma_mgmt-objs := hidma_mgmt.o hidma_mgmt_sys.o ---- /dev/null -+++ b/drivers/dma/qcom/qcom_adm.c -@@ -0,0 +1,903 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "../dmaengine.h" -+#include "../virt-dma.h" -+ -+/* ADM registers - calculated from channel number and security domain */ -+#define ADM_CHAN_MULTI 0x4 -+#define ADM_CI_MULTI 0x4 -+#define ADM_CRCI_MULTI 0x4 -+#define ADM_EE_MULTI 0x800 -+#define ADM_CHAN_OFFS(chan) (ADM_CHAN_MULTI * (chan)) -+#define ADM_EE_OFFS(ee) (ADM_EE_MULTI * (ee)) -+#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee)) -+#define ADM_CHAN_OFFS(chan) (ADM_CHAN_MULTI * (chan)) -+#define ADM_CI_OFFS(ci) (ADM_CHAN_OFF(ci)) -+#define ADM_CH_CMD_PTR(chan, ee) (ADM_CHAN_EE_OFFS(chan, ee)) -+#define ADM_CH_RSLT(chan, ee) (0x40 + ADM_CHAN_EE_OFFS(chan, ee)) -+#define ADM_CH_FLUSH_STATE0(chan, ee) (0x80 + ADM_CHAN_EE_OFFS(chan, ee)) -+#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee)) -+#define ADM_CH_CONF(chan) (0x240 + ADM_CHAN_OFFS(chan)) -+#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee)) -+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee) (0x380 + ADM_EE_OFFS(ee)) -+#define ADM_CI_CONF(ci) (0x390 + (ci) * ADM_CI_MULTI) -+#define ADM_GP_CTL 0x3d8 -+#define ADM_CRCI_CTL(crci, ee) (0x400 + (crci) * ADM_CRCI_MULTI + \ -+ ADM_EE_OFFS(ee)) -+ -+/* channel status */ -+#define ADM_CH_STATUS_VALID BIT(1) -+ -+/* channel result */ -+#define ADM_CH_RSLT_VALID BIT(31) -+#define ADM_CH_RSLT_ERR BIT(3) -+#define ADM_CH_RSLT_FLUSH BIT(2) -+#define ADM_CH_RSLT_TPD BIT(1) -+ -+/* channel conf */ -+#define ADM_CH_CONF_SHADOW_EN BIT(12) -+#define ADM_CH_CONF_MPU_DISABLE BIT(11) -+#define ADM_CH_CONF_PERM_MPU_CONF BIT(9) -+#define ADM_CH_CONF_FORCE_RSLT_EN BIT(7) -+#define ADM_CH_CONF_SEC_DOMAIN(ee) ((((ee) & 0x3) << 4) | (((ee) & 0x4) << 11)) -+ -+/* channel result conf */ -+#define ADM_CH_RSLT_CONF_FLUSH_EN BIT(1) -+#define ADM_CH_RSLT_CONF_IRQ_EN BIT(0) -+ -+/* CRCI CTL */ -+#define ADM_CRCI_CTL_MUX_SEL BIT(18) -+#define ADM_CRCI_CTL_RST BIT(17) -+ -+/* CI configuration */ -+#define ADM_CI_RANGE_END(x) ((x) << 24) -+#define ADM_CI_RANGE_START(x) ((x) << 16) -+#define ADM_CI_BURST_4_WORDS BIT(2) -+#define ADM_CI_BURST_8_WORDS BIT(3) -+ -+/* GP CTL */ -+#define ADM_GP_CTL_LP_EN BIT(12) -+#define ADM_GP_CTL_LP_CNT(x) ((x) << 8) -+ -+/* Command pointer list entry */ -+#define ADM_CPLE_LP BIT(31) -+#define ADM_CPLE_CMD_PTR_LIST BIT(29) -+ -+/* Command list entry */ -+#define ADM_CMD_LC BIT(31) -+#define ADM_CMD_DST_CRCI(n) (((n) & 0xf) << 7) -+#define ADM_CMD_SRC_CRCI(n) (((n) & 0xf) << 3) -+ -+#define ADM_CMD_TYPE_SINGLE 0x0 -+#define ADM_CMD_TYPE_BOX 0x3 -+ -+#define ADM_CRCI_MUX_SEL BIT(4) -+#define ADM_DESC_ALIGN 8 -+#define ADM_MAX_XFER (SZ_64K - 1) -+#define ADM_MAX_ROWS (SZ_64K - 1) -+#define ADM_MAX_CHANNELS 16 -+ -+struct adm_desc_hw_box { -+ u32 cmd; -+ u32 src_addr; -+ u32 dst_addr; -+ u32 row_len; -+ u32 num_rows; -+ u32 row_offset; -+}; -+ -+struct adm_desc_hw_single { -+ u32 cmd; -+ u32 src_addr; -+ u32 dst_addr; -+ u32 len; -+}; -+ -+struct adm_async_desc { -+ struct virt_dma_desc vd; -+ struct adm_device *adev; -+ -+ size_t length; -+ enum dma_transfer_direction dir; -+ dma_addr_t dma_addr; -+ size_t dma_len; -+ -+ void *cpl; -+ dma_addr_t cp_addr; -+ u32 crci; -+ u32 mux; -+ u32 blk_size; -+}; -+ -+struct adm_chan { -+ struct virt_dma_chan vc; -+ struct adm_device *adev; -+ -+ /* parsed from DT */ -+ u32 id; /* channel id */ -+ -+ struct adm_async_desc *curr_txd; -+ struct dma_slave_config slave; -+ struct list_head node; -+ -+ int error; -+ int initialized; -+}; -+ -+static inline struct adm_chan *to_adm_chan(struct dma_chan *common) -+{ -+ return container_of(common, struct adm_chan, vc.chan); -+} -+ -+struct adm_device { -+ void __iomem *regs; -+ struct device *dev; -+ struct dma_device common; -+ struct device_dma_parameters dma_parms; -+ struct adm_chan *channels; -+ -+ u32 ee; -+ -+ struct clk *core_clk; -+ struct clk *iface_clk; -+ -+ struct reset_control *clk_reset; -+ struct reset_control *c0_reset; -+ struct reset_control *c1_reset; -+ struct reset_control *c2_reset; -+ int irq; -+}; -+ -+/** -+ * adm_free_chan - Frees dma resources associated with the specific channel -+ * -+ * Free all allocated descriptors associated with this channel -+ * -+ */ -+static void adm_free_chan(struct dma_chan *chan) -+{ -+ /* free all queued descriptors */ -+ vchan_free_chan_resources(to_virt_chan(chan)); -+} -+ -+/** -+ * adm_get_blksize - Get block size from burst value -+ * -+ */ -+static int adm_get_blksize(unsigned int burst) -+{ -+ int ret; -+ -+ switch (burst) { -+ case 16: -+ case 32: -+ case 64: -+ case 128: -+ ret = ffs(burst >> 4) - 1; -+ break; -+ case 192: -+ ret = 4; -+ break; -+ case 256: -+ ret = 5; -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+/** -+ * adm_process_fc_descriptors - Process descriptors for flow controlled xfers -+ * -+ * @achan: ADM channel -+ * @desc: Descriptor memory pointer -+ * @sg: Scatterlist entry -+ * @crci: CRCI value -+ * @burst: Burst size of transaction -+ * @direction: DMA transfer direction -+ */ -+static void *adm_process_fc_descriptors(struct adm_chan *achan, void *desc, -+ struct scatterlist *sg, u32 crci, -+ u32 burst, -+ enum dma_transfer_direction direction) -+{ -+ struct adm_desc_hw_box *box_desc = NULL; -+ struct adm_desc_hw_single *single_desc; -+ u32 remainder = sg_dma_len(sg); -+ u32 rows, row_offset, crci_cmd; -+ u32 mem_addr = sg_dma_address(sg); -+ u32 *incr_addr = &mem_addr; -+ u32 *src, *dst; -+ -+ if (direction == DMA_DEV_TO_MEM) { -+ crci_cmd = ADM_CMD_SRC_CRCI(crci); -+ row_offset = burst; -+ src = &achan->slave.src_addr; -+ dst = &mem_addr; -+ } else { -+ crci_cmd = ADM_CMD_DST_CRCI(crci); -+ row_offset = burst << 16; -+ src = &mem_addr; -+ dst = &achan->slave.dst_addr; -+ } -+ -+ while (remainder >= burst) { -+ box_desc = desc; -+ box_desc->cmd = ADM_CMD_TYPE_BOX | crci_cmd; -+ box_desc->row_offset = row_offset; -+ box_desc->src_addr = *src; -+ box_desc->dst_addr = *dst; -+ -+ rows = remainder / burst; -+ rows = min_t(u32, rows, ADM_MAX_ROWS); -+ box_desc->num_rows = rows << 16 | rows; -+ box_desc->row_len = burst << 16 | burst; -+ -+ *incr_addr += burst * rows; -+ remainder -= burst * rows; -+ desc += sizeof(*box_desc); -+ } -+ -+ /* if leftover bytes, do one single descriptor */ -+ if (remainder) { -+ single_desc = desc; -+ single_desc->cmd = ADM_CMD_TYPE_SINGLE | crci_cmd; -+ single_desc->len = remainder; -+ single_desc->src_addr = *src; -+ single_desc->dst_addr = *dst; -+ desc += sizeof(*single_desc); -+ -+ if (sg_is_last(sg)) -+ single_desc->cmd |= ADM_CMD_LC; -+ } else { -+ if (box_desc && sg_is_last(sg)) -+ box_desc->cmd |= ADM_CMD_LC; -+ } -+ -+ return desc; -+} -+ -+/** -+ * adm_process_non_fc_descriptors - Process descriptors for non-fc xfers -+ * -+ * @achan: ADM channel -+ * @desc: Descriptor memory pointer -+ * @sg: Scatterlist entry -+ * @direction: DMA transfer direction -+ */ -+static void *adm_process_non_fc_descriptors(struct adm_chan *achan, void *desc, -+ struct scatterlist *sg, -+ enum dma_transfer_direction direction) -+{ -+ struct adm_desc_hw_single *single_desc; -+ u32 remainder = sg_dma_len(sg); -+ u32 mem_addr = sg_dma_address(sg); -+ u32 *incr_addr = &mem_addr; -+ u32 *src, *dst; -+ -+ if (direction == DMA_DEV_TO_MEM) { -+ src = &achan->slave.src_addr; -+ dst = &mem_addr; -+ } else { -+ src = &mem_addr; -+ dst = &achan->slave.dst_addr; -+ } -+ -+ do { -+ single_desc = desc; -+ single_desc->cmd = ADM_CMD_TYPE_SINGLE; -+ single_desc->src_addr = *src; -+ single_desc->dst_addr = *dst; -+ single_desc->len = (remainder > ADM_MAX_XFER) ? -+ ADM_MAX_XFER : remainder; -+ -+ remainder -= single_desc->len; -+ *incr_addr += single_desc->len; -+ desc += sizeof(*single_desc); -+ } while (remainder); -+ -+ /* set last command if this is the end of the whole transaction */ -+ if (sg_is_last(sg)) -+ single_desc->cmd |= ADM_CMD_LC; -+ -+ return desc; -+} -+ -+/** -+ * adm_prep_slave_sg - Prep slave sg transaction -+ * -+ * @chan: dma channel -+ * @sgl: scatter gather list -+ * @sg_len: length of sg -+ * @direction: DMA transfer direction -+ * @flags: DMA flags -+ * @context: transfer context (unused) -+ */ -+static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, -+ struct scatterlist *sgl, -+ unsigned int sg_len, -+ enum dma_transfer_direction direction, -+ unsigned long flags, -+ void *context) -+{ -+ struct adm_chan *achan = to_adm_chan(chan); -+ struct adm_device *adev = achan->adev; -+ struct adm_async_desc *async_desc; -+ struct scatterlist *sg; -+ dma_addr_t cple_addr; -+ u32 i, burst; -+ u32 single_count = 0, box_count = 0, crci = 0; -+ void *desc; -+ u32 *cple; -+ int blk_size = 0; -+ -+ if (!is_slave_direction(direction)) { -+ dev_err(adev->dev, "invalid dma direction\n"); -+ return NULL; -+ } -+ -+ /* -+ * get burst value from slave configuration -+ */ -+ burst = (direction == DMA_MEM_TO_DEV) ? -+ achan->slave.dst_maxburst : -+ achan->slave.src_maxburst; -+ -+ /* if using flow control, validate burst and crci values */ -+ if (achan->slave.device_fc) { -+ blk_size = adm_get_blksize(burst); -+ if (blk_size < 0) { -+ dev_err(adev->dev, "invalid burst value: %d\n", -+ burst); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ crci = achan->slave.slave_id & 0xf; -+ if (!crci || achan->slave.slave_id > 0x1f) { -+ dev_err(adev->dev, "invalid crci value\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ } -+ -+ /* iterate through sgs and compute allocation size of structures */ -+ for_each_sg(sgl, sg, sg_len, i) { -+ if (achan->slave.device_fc) { -+ box_count += DIV_ROUND_UP(sg_dma_len(sg) / burst, -+ ADM_MAX_ROWS); -+ if (sg_dma_len(sg) % burst) -+ single_count++; -+ } else { -+ single_count += DIV_ROUND_UP(sg_dma_len(sg), -+ ADM_MAX_XFER); -+ } -+ } -+ -+ async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT); -+ if (!async_desc) -+ return ERR_PTR(-ENOMEM); -+ -+ if (crci) -+ async_desc->mux = achan->slave.slave_id & ADM_CRCI_MUX_SEL ? -+ ADM_CRCI_CTL_MUX_SEL : 0; -+ async_desc->crci = crci; -+ async_desc->blk_size = blk_size; -+ async_desc->dma_len = single_count * sizeof(struct adm_desc_hw_single) + -+ box_count * sizeof(struct adm_desc_hw_box) + -+ sizeof(*cple) + 2 * ADM_DESC_ALIGN; -+ -+ async_desc->cpl = kzalloc(async_desc->dma_len, GFP_NOWAIT); -+ if (!async_desc->cpl) -+ goto free; -+ -+ async_desc->adev = adev; -+ -+ /* both command list entry and descriptors must be 8 byte aligned */ -+ cple = PTR_ALIGN(async_desc->cpl, ADM_DESC_ALIGN); -+ desc = PTR_ALIGN(cple + 1, ADM_DESC_ALIGN); -+ -+ for_each_sg(sgl, sg, sg_len, i) { -+ async_desc->length += sg_dma_len(sg); -+ -+ if (achan->slave.device_fc) -+ desc = adm_process_fc_descriptors(achan, desc, sg, crci, -+ burst, direction); -+ else -+ desc = adm_process_non_fc_descriptors(achan, desc, sg, -+ direction); -+ } -+ -+ async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl, -+ async_desc->dma_len, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(adev->dev, async_desc->dma_addr)) -+ goto free; -+ -+ cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl); -+ -+ /* init cmd list */ -+ dma_sync_single_for_cpu(adev->dev, cple_addr, sizeof(*cple), -+ DMA_TO_DEVICE); -+ *cple = ADM_CPLE_LP; -+ *cple |= (async_desc->dma_addr + ADM_DESC_ALIGN) >> 3; -+ dma_sync_single_for_device(adev->dev, cple_addr, sizeof(*cple), -+ DMA_TO_DEVICE); -+ -+ return vchan_tx_prep(&achan->vc, &async_desc->vd, flags); -+ -+free: -+ kfree(async_desc); -+ return ERR_PTR(-ENOMEM); -+} -+ -+/** -+ * adm_terminate_all - terminate all transactions on a channel -+ * @achan: adm dma channel -+ * -+ * Dequeues and frees all transactions, aborts current transaction -+ * No callbacks are done -+ * -+ */ -+static int adm_terminate_all(struct dma_chan *chan) -+{ -+ struct adm_chan *achan = to_adm_chan(chan); -+ struct adm_device *adev = achan->adev; -+ unsigned long flags; -+ LIST_HEAD(head); -+ -+ spin_lock_irqsave(&achan->vc.lock, flags); -+ vchan_get_all_descriptors(&achan->vc, &head); -+ -+ /* send flush command to terminate current transaction */ -+ writel_relaxed(0x0, -+ adev->regs + ADM_CH_FLUSH_STATE0(achan->id, adev->ee)); -+ -+ spin_unlock_irqrestore(&achan->vc.lock, flags); -+ -+ vchan_dma_desc_free_list(&achan->vc, &head); -+ -+ return 0; -+} -+ -+static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) -+{ -+ struct adm_chan *achan = to_adm_chan(chan); -+ unsigned long flag; -+ -+ spin_lock_irqsave(&achan->vc.lock, flag); -+ memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config)); -+ spin_unlock_irqrestore(&achan->vc.lock, flag); -+ -+ return 0; -+} -+ -+/** -+ * adm_start_dma - start next transaction -+ * @achan - ADM dma channel -+ */ -+static void adm_start_dma(struct adm_chan *achan) -+{ -+ struct virt_dma_desc *vd = vchan_next_desc(&achan->vc); -+ struct adm_device *adev = achan->adev; -+ struct adm_async_desc *async_desc; -+ -+ lockdep_assert_held(&achan->vc.lock); -+ -+ if (!vd) -+ return; -+ -+ list_del(&vd->node); -+ -+ /* write next command list out to the CMD FIFO */ -+ async_desc = container_of(vd, struct adm_async_desc, vd); -+ achan->curr_txd = async_desc; -+ -+ /* reset channel error */ -+ achan->error = 0; -+ -+ if (!achan->initialized) { -+ /* enable interrupts */ -+ writel(ADM_CH_CONF_SHADOW_EN | -+ ADM_CH_CONF_PERM_MPU_CONF | -+ ADM_CH_CONF_MPU_DISABLE | -+ ADM_CH_CONF_SEC_DOMAIN(adev->ee), -+ adev->regs + ADM_CH_CONF(achan->id)); -+ -+ writel(ADM_CH_RSLT_CONF_IRQ_EN | ADM_CH_RSLT_CONF_FLUSH_EN, -+ adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee)); -+ -+ achan->initialized = 1; -+ } -+ -+ /* set the crci block size if this transaction requires CRCI */ -+ if (async_desc->crci) { -+ writel(async_desc->mux | async_desc->blk_size, -+ adev->regs + ADM_CRCI_CTL(async_desc->crci, adev->ee)); -+ } -+ -+ /* make sure IRQ enable doesn't get reordered */ -+ wmb(); -+ -+ /* write next command list out to the CMD FIFO */ -+ writel(ALIGN(async_desc->dma_addr, ADM_DESC_ALIGN) >> 3, -+ adev->regs + ADM_CH_CMD_PTR(achan->id, adev->ee)); -+} -+ -+/** -+ * adm_dma_irq - irq handler for ADM controller -+ * @irq: IRQ of interrupt -+ * @data: callback data -+ * -+ * IRQ handler for the bam controller -+ */ -+static irqreturn_t adm_dma_irq(int irq, void *data) -+{ -+ struct adm_device *adev = data; -+ u32 srcs, i; -+ struct adm_async_desc *async_desc; -+ unsigned long flags; -+ -+ srcs = readl_relaxed(adev->regs + -+ ADM_SEC_DOMAIN_IRQ_STATUS(adev->ee)); -+ -+ for (i = 0; i < ADM_MAX_CHANNELS; i++) { -+ struct adm_chan *achan = &adev->channels[i]; -+ u32 status, result; -+ -+ if (srcs & BIT(i)) { -+ status = readl_relaxed(adev->regs + -+ ADM_CH_STATUS_SD(i, adev->ee)); -+ -+ /* if no result present, skip */ -+ if (!(status & ADM_CH_STATUS_VALID)) -+ continue; -+ -+ result = readl_relaxed(adev->regs + -+ ADM_CH_RSLT(i, adev->ee)); -+ -+ /* no valid results, skip */ -+ if (!(result & ADM_CH_RSLT_VALID)) -+ continue; -+ -+ /* flag error if transaction was flushed or failed */ -+ if (result & (ADM_CH_RSLT_ERR | ADM_CH_RSLT_FLUSH)) -+ achan->error = 1; -+ -+ spin_lock_irqsave(&achan->vc.lock, flags); -+ async_desc = achan->curr_txd; -+ -+ achan->curr_txd = NULL; -+ -+ if (async_desc) { -+ vchan_cookie_complete(&async_desc->vd); -+ -+ /* kick off next DMA */ -+ adm_start_dma(achan); -+ } -+ -+ spin_unlock_irqrestore(&achan->vc.lock, flags); -+ } -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+/** -+ * adm_tx_status - returns status of transaction -+ * @chan: dma channel -+ * @cookie: transaction cookie -+ * @txstate: DMA transaction state -+ * -+ * Return status of dma transaction -+ */ -+static enum dma_status adm_tx_status(struct dma_chan *chan, dma_cookie_t cookie, -+ struct dma_tx_state *txstate) -+{ -+ struct adm_chan *achan = to_adm_chan(chan); -+ struct virt_dma_desc *vd; -+ enum dma_status ret; -+ unsigned long flags; -+ size_t residue = 0; -+ -+ ret = dma_cookie_status(chan, cookie, txstate); -+ if (ret == DMA_COMPLETE || !txstate) -+ return ret; -+ -+ spin_lock_irqsave(&achan->vc.lock, flags); -+ -+ vd = vchan_find_desc(&achan->vc, cookie); -+ if (vd) -+ residue = container_of(vd, struct adm_async_desc, vd)->length; -+ -+ spin_unlock_irqrestore(&achan->vc.lock, flags); -+ -+ /* -+ * residue is either the full length if it is in the issued list, or 0 -+ * if it is in progress. We have no reliable way of determining -+ * anything inbetween -+ */ -+ dma_set_residue(txstate, residue); -+ -+ if (achan->error) -+ return DMA_ERROR; -+ -+ return ret; -+} -+ -+/** -+ * adm_issue_pending - starts pending transactions -+ * @chan: dma channel -+ * -+ * Issues all pending transactions and starts DMA -+ */ -+static void adm_issue_pending(struct dma_chan *chan) -+{ -+ struct adm_chan *achan = to_adm_chan(chan); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&achan->vc.lock, flags); -+ -+ if (vchan_issue_pending(&achan->vc) && !achan->curr_txd) -+ adm_start_dma(achan); -+ spin_unlock_irqrestore(&achan->vc.lock, flags); -+} -+ -+/** -+ * adm_dma_free_desc - free descriptor memory -+ * @vd: virtual descriptor -+ * -+ */ -+static void adm_dma_free_desc(struct virt_dma_desc *vd) -+{ -+ struct adm_async_desc *async_desc = container_of(vd, -+ struct adm_async_desc, vd); -+ -+ dma_unmap_single(async_desc->adev->dev, async_desc->dma_addr, -+ async_desc->dma_len, DMA_TO_DEVICE); -+ kfree(async_desc->cpl); -+ kfree(async_desc); -+} -+ -+static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan, -+ u32 index) -+{ -+ achan->id = index; -+ achan->adev = adev; -+ -+ vchan_init(&achan->vc, &adev->common); -+ achan->vc.desc_free = adm_dma_free_desc; -+} -+ -+static int adm_dma_probe(struct platform_device *pdev) -+{ -+ struct adm_device *adev; -+ int ret; -+ u32 i; -+ -+ adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL); -+ if (!adev) -+ return -ENOMEM; -+ -+ adev->dev = &pdev->dev; -+ -+ adev->regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(adev->regs)) -+ return PTR_ERR(adev->regs); -+ -+ adev->irq = platform_get_irq(pdev, 0); -+ if (adev->irq < 0) -+ return adev->irq; -+ -+ ret = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &adev->ee); -+ if (ret) { -+ dev_err(adev->dev, "Execution environment unspecified\n"); -+ return ret; -+ } -+ -+ adev->core_clk = devm_clk_get(adev->dev, "core"); -+ if (IS_ERR(adev->core_clk)) -+ return PTR_ERR(adev->core_clk); -+ -+ adev->iface_clk = devm_clk_get(adev->dev, "iface"); -+ if (IS_ERR(adev->iface_clk)) -+ return PTR_ERR(adev->iface_clk); -+ -+ adev->clk_reset = devm_reset_control_get_exclusive(&pdev->dev, "clk"); -+ if (IS_ERR(adev->clk_reset)) { -+ dev_err(adev->dev, "failed to get ADM0 reset\n"); -+ return PTR_ERR(adev->clk_reset); -+ } -+ -+ adev->c0_reset = devm_reset_control_get_exclusive(&pdev->dev, "c0"); -+ if (IS_ERR(adev->c0_reset)) { -+ dev_err(adev->dev, "failed to get ADM0 C0 reset\n"); -+ return PTR_ERR(adev->c0_reset); -+ } -+ -+ adev->c1_reset = devm_reset_control_get_exclusive(&pdev->dev, "c1"); -+ if (IS_ERR(adev->c1_reset)) { -+ dev_err(adev->dev, "failed to get ADM0 C1 reset\n"); -+ return PTR_ERR(adev->c1_reset); -+ } -+ -+ adev->c2_reset = devm_reset_control_get_exclusive(&pdev->dev, "c2"); -+ if (IS_ERR(adev->c2_reset)) { -+ dev_err(adev->dev, "failed to get ADM0 C2 reset\n"); -+ return PTR_ERR(adev->c2_reset); -+ } -+ -+ ret = clk_prepare_enable(adev->core_clk); -+ if (ret) { -+ dev_err(adev->dev, "failed to prepare/enable core clock\n"); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(adev->iface_clk); -+ if (ret) { -+ dev_err(adev->dev, "failed to prepare/enable iface clock\n"); -+ goto err_disable_core_clk; -+ } -+ -+ reset_control_assert(adev->clk_reset); -+ reset_control_assert(adev->c0_reset); -+ reset_control_assert(adev->c1_reset); -+ reset_control_assert(adev->c2_reset); -+ -+ udelay(2); -+ -+ reset_control_deassert(adev->clk_reset); -+ reset_control_deassert(adev->c0_reset); -+ reset_control_deassert(adev->c1_reset); -+ reset_control_deassert(adev->c2_reset); -+ -+ adev->channels = devm_kcalloc(adev->dev, ADM_MAX_CHANNELS, -+ sizeof(*adev->channels), GFP_KERNEL); -+ -+ if (!adev->channels) { -+ ret = -ENOMEM; -+ goto err_disable_clks; -+ } -+ -+ /* allocate and initialize channels */ -+ INIT_LIST_HEAD(&adev->common.channels); -+ -+ for (i = 0; i < ADM_MAX_CHANNELS; i++) -+ adm_channel_init(adev, &adev->channels[i], i); -+ -+ /* reset CRCIs */ -+ for (i = 0; i < 16; i++) -+ writel(ADM_CRCI_CTL_RST, adev->regs + -+ ADM_CRCI_CTL(i, adev->ee)); -+ -+ /* configure client interfaces */ -+ writel(ADM_CI_RANGE_START(0x40) | ADM_CI_RANGE_END(0xb0) | -+ ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(0)); -+ writel(ADM_CI_RANGE_START(0x2a) | ADM_CI_RANGE_END(0x2c) | -+ ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(1)); -+ writel(ADM_CI_RANGE_START(0x12) | ADM_CI_RANGE_END(0x28) | -+ ADM_CI_BURST_8_WORDS, adev->regs + ADM_CI_CONF(2)); -+ writel(ADM_GP_CTL_LP_EN | ADM_GP_CTL_LP_CNT(0xf), -+ adev->regs + ADM_GP_CTL); -+ -+ ret = devm_request_irq(adev->dev, adev->irq, adm_dma_irq, -+ 0, "adm_dma", adev); -+ if (ret) -+ goto err_disable_clks; -+ -+ platform_set_drvdata(pdev, adev); -+ -+ adev->common.dev = adev->dev; -+ adev->common.dev->dma_parms = &adev->dma_parms; -+ -+ /* set capabilities */ -+ dma_cap_zero(adev->common.cap_mask); -+ dma_cap_set(DMA_SLAVE, adev->common.cap_mask); -+ dma_cap_set(DMA_PRIVATE, adev->common.cap_mask); -+ -+ /* initialize dmaengine apis */ -+ adev->common.directions = BIT(DMA_DEV_TO_MEM | DMA_MEM_TO_DEV); -+ adev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; -+ adev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ adev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ adev->common.device_free_chan_resources = adm_free_chan; -+ adev->common.device_prep_slave_sg = adm_prep_slave_sg; -+ adev->common.device_issue_pending = adm_issue_pending; -+ adev->common.device_tx_status = adm_tx_status; -+ adev->common.device_terminate_all = adm_terminate_all; -+ adev->common.device_config = adm_slave_config; -+ -+ ret = dma_async_device_register(&adev->common); -+ if (ret) { -+ dev_err(adev->dev, "failed to register dma async device\n"); -+ goto err_disable_clks; -+ } -+ -+ ret = of_dma_controller_register(pdev->dev.of_node, -+ of_dma_xlate_by_chan_id, -+ &adev->common); -+ if (ret) -+ goto err_unregister_dma; -+ -+ return 0; -+ -+err_unregister_dma: -+ dma_async_device_unregister(&adev->common); -+err_disable_clks: -+ clk_disable_unprepare(adev->iface_clk); -+err_disable_core_clk: -+ clk_disable_unprepare(adev->core_clk); -+ -+ return ret; -+} -+ -+static int adm_dma_remove(struct platform_device *pdev) -+{ -+ struct adm_device *adev = platform_get_drvdata(pdev); -+ struct adm_chan *achan; -+ u32 i; -+ -+ of_dma_controller_free(pdev->dev.of_node); -+ dma_async_device_unregister(&adev->common); -+ -+ for (i = 0; i < ADM_MAX_CHANNELS; i++) { -+ achan = &adev->channels[i]; -+ -+ /* mask IRQs for this channel/EE pair */ -+ writel(0, adev->regs + ADM_CH_RSLT_CONF(achan->id, adev->ee)); -+ -+ tasklet_kill(&adev->channels[i].vc.task); -+ adm_terminate_all(&adev->channels[i].vc.chan); -+ } -+ -+ devm_free_irq(adev->dev, adev->irq, adev); -+ -+ clk_disable_unprepare(adev->core_clk); -+ clk_disable_unprepare(adev->iface_clk); -+ -+ return 0; -+} -+ -+static const struct of_device_id adm_of_match[] = { -+ { .compatible = "qcom,adm", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, adm_of_match); -+ -+static struct platform_driver adm_dma_driver = { -+ .probe = adm_dma_probe, -+ .remove = adm_dma_remove, -+ .driver = { -+ .name = "adm-dma-engine", -+ .of_match_table = adm_of_match, -+ }, -+}; -+ -+module_platform_driver(adm_dma_driver); -+ -+MODULE_AUTHOR("Andy Gross "); -+MODULE_DESCRIPTION("QCOM ADM DMA engine driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch b/target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch deleted file mode 100644 index a78dc82a47..0000000000 --- a/target/linux/ipq806x/patches-5.15/101-5.12-mtd-parsers-Add-Qcom-SMEM-parser.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 803eb124e1a64e42888542c3444bfe6dac412c7f Mon Sep 17 00:00:00 2001 -From: Manivannan Sadhasivam -Date: Mon, 4 Jan 2021 09:41:35 +0530 -Subject: mtd: parsers: Add Qcom SMEM parser - -NAND based Qualcomm platforms have the partition table populated in the -Shared Memory (SMEM). Hence, add a parser for parsing the partitions -from it. - -Signed-off-by: Manivannan Sadhasivam -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20210104041137.113075-3-manivannan.sadhasivam@linaro.org ---- - drivers/mtd/parsers/Kconfig | 8 ++ - drivers/mtd/parsers/Makefile | 1 + - drivers/mtd/parsers/qcomsmempart.c | 170 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 179 insertions(+) - create mode 100644 drivers/mtd/parsers/qcomsmempart.c - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -196,6 +196,14 @@ config MTD_REDBOOT_PARTS_READONLY - - endif # MTD_REDBOOT_PARTS - -+config MTD_QCOMSMEM_PARTS -+ tristate "Qualcomm SMEM NAND flash partition parser" -+ depends on MTD_NAND_QCOM || COMPILE_TEST -+ depends on QCOM_SMEM -+ help -+ This provides support for parsing partitions from Shared Memory (SMEM) -+ for NAND flash on Qualcomm platforms. -+ - config MTD_ROUTERBOOT_PARTS - tristate "RouterBoot flash partition parser" - depends on MTD && OF ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -13,4 +13,5 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o - obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o - obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o -+obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o - obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o ---- /dev/null -+++ b/drivers/mtd/parsers/qcomsmempart.c -@@ -0,0 +1,170 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Qualcomm SMEM NAND flash partition parser -+ * -+ * Copyright (C) 2020, Linaro Ltd. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SMEM_AARM_PARTITION_TABLE 9 -+#define SMEM_APPS 0 -+ -+#define SMEM_FLASH_PART_MAGIC1 0x55ee73aa -+#define SMEM_FLASH_PART_MAGIC2 0xe35ebddb -+#define SMEM_FLASH_PTABLE_V3 3 -+#define SMEM_FLASH_PTABLE_V4 4 -+#define SMEM_FLASH_PTABLE_MAX_PARTS_V3 16 -+#define SMEM_FLASH_PTABLE_MAX_PARTS_V4 48 -+#define SMEM_FLASH_PTABLE_HDR_LEN (4 * sizeof(u32)) -+#define SMEM_FLASH_PTABLE_NAME_SIZE 16 -+ -+/** -+ * struct smem_flash_pentry - SMEM Flash partition entry -+ * @name: Name of the partition -+ * @offset: Offset in blocks -+ * @length: Length of the partition in blocks -+ * @attr: Flags for this partition -+ */ -+struct smem_flash_pentry { -+ char name[SMEM_FLASH_PTABLE_NAME_SIZE]; -+ __le32 offset; -+ __le32 length; -+ u8 attr; -+} __packed __aligned(4); -+ -+/** -+ * struct smem_flash_ptable - SMEM Flash partition table -+ * @magic1: Partition table Magic 1 -+ * @magic2: Partition table Magic 2 -+ * @version: Partition table version -+ * @numparts: Number of partitions in this ptable -+ * @pentry: Flash partition entries belonging to this ptable -+ */ -+struct smem_flash_ptable { -+ __le32 magic1; -+ __le32 magic2; -+ __le32 version; -+ __le32 numparts; -+ struct smem_flash_pentry pentry[SMEM_FLASH_PTABLE_MAX_PARTS_V4]; -+} __packed __aligned(4); -+ -+static int parse_qcomsmem_part(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct smem_flash_pentry *pentry; -+ struct smem_flash_ptable *ptable; -+ size_t len = SMEM_FLASH_PTABLE_HDR_LEN; -+ struct mtd_partition *parts; -+ int ret, i, numparts; -+ char *name, *c; -+ -+ pr_debug("Parsing partition table info from SMEM\n"); -+ ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); -+ if (IS_ERR(ptable)) { -+ pr_err("Error reading partition table header\n"); -+ return PTR_ERR(ptable); -+ } -+ -+ /* Verify ptable magic */ -+ if (le32_to_cpu(ptable->magic1) != SMEM_FLASH_PART_MAGIC1 || -+ le32_to_cpu(ptable->magic2) != SMEM_FLASH_PART_MAGIC2) { -+ pr_err("Partition table magic verification failed\n"); -+ return -EINVAL; -+ } -+ -+ /* Ensure that # of partitions is less than the max we have allocated */ -+ numparts = le32_to_cpu(ptable->numparts); -+ if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) { -+ pr_err("Partition numbers exceed the max limit\n"); -+ return -EINVAL; -+ } -+ -+ /* Find out length of partition data based on table version */ -+ if (le32_to_cpu(ptable->version) <= SMEM_FLASH_PTABLE_V3) { -+ len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V3 * -+ sizeof(struct smem_flash_pentry); -+ } else if (le32_to_cpu(ptable->version) == SMEM_FLASH_PTABLE_V4) { -+ len = SMEM_FLASH_PTABLE_HDR_LEN + SMEM_FLASH_PTABLE_MAX_PARTS_V4 * -+ sizeof(struct smem_flash_pentry); -+ } else { -+ pr_err("Unknown ptable version (%d)", le32_to_cpu(ptable->version)); -+ return -EINVAL; -+ } -+ -+ /* -+ * Now that the partition table header has been parsed, verified -+ * and the length of the partition table calculated, read the -+ * complete partition table -+ */ -+ ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); -+ if (IS_ERR_OR_NULL(ptable)) { -+ pr_err("Error reading partition table\n"); -+ return PTR_ERR(ptable); -+ } -+ -+ parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL); -+ if (!parts) -+ return -ENOMEM; -+ -+ for (i = 0; i < numparts; i++) { -+ pentry = &ptable->pentry[i]; -+ if (pentry->name[0] == '\0') -+ continue; -+ -+ name = kstrdup(pentry->name, GFP_KERNEL); -+ if (!name) { -+ ret = -ENOMEM; -+ goto out_free_parts; -+ } -+ -+ /* Convert name to lower case */ -+ for (c = name; *c != '\0'; c++) -+ *c = tolower(*c); -+ -+ parts[i].name = name; -+ parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; -+ parts[i].mask_flags = pentry->attr; -+ parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; -+ pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", -+ i, pentry->name, le32_to_cpu(pentry->offset), -+ le32_to_cpu(pentry->length), pentry->attr); -+ } -+ -+ pr_debug("SMEM partition table found: ver: %d len: %d\n", -+ le32_to_cpu(ptable->version), numparts); -+ *pparts = parts; -+ -+ return numparts; -+ -+out_free_parts: -+ while (--i >= 0) -+ kfree(parts[i].name); -+ kfree(parts); -+ *pparts = NULL; -+ -+ return ret; -+} -+ -+static const struct of_device_id qcomsmem_of_match_table[] = { -+ { .compatible = "qcom,smem-part" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, qcomsmem_of_match_table); -+ -+static struct mtd_part_parser mtd_parser_qcomsmem = { -+ .parse_fn = parse_qcomsmem_part, -+ .name = "qcomsmem", -+ .of_match_table = qcomsmem_of_match_table, -+}; -+module_mtd_part_parser(mtd_parser_qcomsmem); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Manivannan Sadhasivam "); -+MODULE_DESCRIPTION("Qualcomm SMEM NAND flash partition parser"); diff --git a/target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch b/target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch deleted file mode 100644 index 8627244c59..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-1-drivers-thermal-tsens-Add-VER_0-tsens-version.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 5c7d1181056feef0b58fb2f556f55e170ba5b479 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 25 Jul 2020 19:14:59 +0200 -Subject: [PATCH 01/10] drivers: thermal: tsens: Add VER_0 tsens version - -VER_0 is used to describe device based on tsens version before v0.1. -These device are devices based on msm8960 for example apq8064 or -ipq806x. - -Signed-off-by: Ansuel Smith -Reviewed-by: Thara Gopinath -Reported-by: kernel test robot -Reported-by: Dan Carpenter ---- - drivers/thermal/qcom/tsens.c | 150 ++++++++++++++++++++++++++++------- - drivers/thermal/qcom/tsens.h | 4 +- - 2 files changed, 124 insertions(+), 30 deletions(-) - ---- a/drivers/thermal/qcom/tsens.c -+++ b/drivers/thermal/qcom/tsens.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -515,6 +516,15 @@ static irqreturn_t tsens_irq_thread(int - dev_dbg(priv->dev, "[%u] %s: no violation: %d\n", - hw_id, __func__, temp); - } -+ -+ if (tsens_version(priv) < VER_0_1) { -+ /* Constraint: There is only 1 interrupt control register for all -+ * 11 temperature sensor. So monitoring more than 1 sensor based -+ * on interrupts will yield inconsistent result. To overcome this -+ * issue we will monitor only sensor 0 which is the master sensor. -+ */ -+ break; -+ } - } - - return IRQ_HANDLED; -@@ -530,6 +540,13 @@ static int tsens_set_trips(void *_sensor - int high_val, low_val, cl_high, cl_low; - u32 hw_id = s->hw_id; - -+ if (tsens_version(priv) < VER_0_1) { -+ /* Pre v0.1 IP had a single register for each type of interrupt -+ * and thresholds -+ */ -+ hw_id = 0; -+ } -+ - dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n", - hw_id, __func__, low, high); - -@@ -584,18 +601,21 @@ int get_temp_tsens_valid(const struct ts - u32 valid; - int ret; - -- ret = regmap_field_read(priv->rf[valid_idx], &valid); -- if (ret) -- return ret; -- while (!valid) { -- /* Valid bit is 0 for 6 AHB clock cycles. -- * At 19.2MHz, 1 AHB clock is ~60ns. -- * We should enter this loop very, very rarely. -- */ -- ndelay(400); -+ /* VER_0 doesn't have VALID bit */ -+ if (tsens_version(priv) >= VER_0_1) { - ret = regmap_field_read(priv->rf[valid_idx], &valid); - if (ret) - return ret; -+ while (!valid) { -+ /* Valid bit is 0 for 6 AHB clock cycles. -+ * At 19.2MHz, 1 AHB clock is ~60ns. -+ * We should enter this loop very, very rarely. -+ */ -+ ndelay(400); -+ ret = regmap_field_read(priv->rf[valid_idx], &valid); -+ if (ret) -+ return ret; -+ } - } - - /* Valid bit is set, OK to read the temperature */ -@@ -608,15 +628,29 @@ int get_temp_common(const struct tsens_s - { - struct tsens_priv *priv = s->priv; - int hw_id = s->hw_id; -- int last_temp = 0, ret; -+ int last_temp = 0, ret, trdy; -+ unsigned long timeout; - -- ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp); -- if (ret) -- return ret; -+ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); -+ do { -+ if (tsens_version(priv) == VER_0) { -+ ret = regmap_field_read(priv->rf[TRDY], &trdy); -+ if (ret) -+ return ret; -+ if (!trdy) -+ continue; -+ } - -- *temp = code_to_degc(last_temp, s) * 1000; -+ ret = regmap_field_read(priv->rf[LAST_TEMP_0 + hw_id], &last_temp); -+ if (ret) -+ return ret; - -- return 0; -+ *temp = code_to_degc(last_temp, s) * 1000; -+ -+ return 0; -+ } while (time_before(jiffies, timeout)); -+ -+ return -ETIMEDOUT; - } - - #ifdef CONFIG_DEBUG_FS -@@ -738,19 +772,34 @@ int __init init_common(struct tsens_priv - priv->tm_offset = 0x1000; - } - -- res = platform_get_resource(op, IORESOURCE_MEM, 0); -- tm_base = devm_ioremap_resource(dev, res); -- if (IS_ERR(tm_base)) { -- ret = PTR_ERR(tm_base); -- goto err_put_device; -+ if (tsens_version(priv) >= VER_0_1) { -+ res = platform_get_resource(op, IORESOURCE_MEM, 0); -+ tm_base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(tm_base)) { -+ ret = PTR_ERR(tm_base); -+ goto err_put_device; -+ } -+ -+ priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config); -+ } else { /* VER_0 share the same gcc regs using a syscon */ -+ struct device *parent = priv->dev->parent; -+ -+ if (parent) -+ priv->tm_map = syscon_node_to_regmap(parent->of_node); - } - -- priv->tm_map = devm_regmap_init_mmio(dev, tm_base, &tsens_config); -- if (IS_ERR(priv->tm_map)) { -- ret = PTR_ERR(priv->tm_map); -+ if (IS_ERR_OR_NULL(priv->tm_map)) { -+ if (!priv->tm_map) -+ ret = -ENODEV; -+ else -+ ret = PTR_ERR(priv->tm_map); - goto err_put_device; - } - -+ /* VER_0 have only tm_map */ -+ if (!priv->srot_map) -+ priv->srot_map = priv->tm_map; -+ - if (tsens_version(priv) > VER_0_1) { - for (i = VER_MAJOR; i <= VER_STEP; i++) { - priv->rf[i] = devm_regmap_field_alloc(dev, priv->srot_map, -@@ -771,6 +820,10 @@ int __init init_common(struct tsens_priv - ret = PTR_ERR(priv->rf[TSENS_EN]); - goto err_put_device; - } -+ /* in VER_0 TSENS need to be explicitly enabled */ -+ if (tsens_version(priv) == VER_0) -+ regmap_field_write(priv->rf[TSENS_EN], 1); -+ - ret = regmap_field_read(priv->rf[TSENS_EN], &enabled); - if (ret) - goto err_put_device; -@@ -793,6 +846,19 @@ int __init init_common(struct tsens_priv - goto err_put_device; - } - -+ priv->rf[TSENS_SW_RST] = -+ devm_regmap_field_alloc(dev, priv->srot_map, priv->fields[TSENS_SW_RST]); -+ if (IS_ERR(priv->rf[TSENS_SW_RST])) { -+ ret = PTR_ERR(priv->rf[TSENS_SW_RST]); -+ goto err_put_device; -+ } -+ -+ priv->rf[TRDY] = devm_regmap_field_alloc(dev, priv->tm_map, priv->fields[TRDY]); -+ if (IS_ERR(priv->rf[TRDY])) { -+ ret = PTR_ERR(priv->rf[TRDY]); -+ goto err_put_device; -+ } -+ - /* This loop might need changes if enum regfield_ids is reordered */ - for (j = LAST_TEMP_0; j <= UP_THRESH_15; j += 16) { - for (i = 0; i < priv->feat->max_sensors; i++) { -@@ -808,7 +874,7 @@ int __init init_common(struct tsens_priv - } - } - -- if (priv->feat->crit_int) { -+ if (priv->feat->crit_int || tsens_version(priv) < VER_0_1) { - /* Loop might need changes if enum regfield_ids is reordered */ - for (j = CRITICAL_STATUS_0; j <= CRIT_THRESH_15; j += 16) { - for (i = 0; i < priv->feat->max_sensors; i++) { -@@ -846,7 +912,11 @@ int __init init_common(struct tsens_priv - } - - spin_lock_init(&priv->ul_lock); -- tsens_enable_irq(priv); -+ -+ /* VER_0 interrupt doesn't need to be enabled */ -+ if (tsens_version(priv) >= VER_0_1) -+ tsens_enable_irq(priv); -+ - tsens_debug_init(op); - - err_put_device: -@@ -945,10 +1015,19 @@ static int tsens_register_irq(struct tse - if (irq == -ENXIO) - ret = 0; - } else { -- ret = devm_request_threaded_irq(&pdev->dev, irq, -- NULL, thread_fn, -- IRQF_ONESHOT, -- dev_name(&pdev->dev), priv); -+ /* VER_0 interrupt is TRIGGER_RISING, VER_0_1 and up is ONESHOT */ -+ if (tsens_version(priv) == VER_0) -+ ret = devm_request_threaded_irq(&pdev->dev, irq, -+ thread_fn, NULL, -+ IRQF_TRIGGER_RISING, -+ dev_name(&pdev->dev), -+ priv); -+ else -+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ thread_fn, IRQF_ONESHOT, -+ dev_name(&pdev->dev), -+ priv); -+ - if (ret) - dev_err(&pdev->dev, "%s: failed to get irq\n", - __func__); -@@ -977,6 +1056,19 @@ static int tsens_register(struct tsens_p - priv->ops->enable(priv, i); - } - -+ /* VER_0 require to set MIN and MAX THRESH -+ * These 2 regs are set using the: -+ * - CRIT_THRESH_0 for MAX THRESH hardcoded to 120°C -+ * - CRIT_THRESH_1 for MIN THRESH hardcoded to 0°C -+ */ -+ if (tsens_version(priv) < VER_0_1) { -+ regmap_field_write(priv->rf[CRIT_THRESH_0], -+ tsens_mC_to_hw(priv->sensor, 120000)); -+ -+ regmap_field_write(priv->rf[CRIT_THRESH_1], -+ tsens_mC_to_hw(priv->sensor, 0)); -+ } -+ - ret = tsens_register_irq(priv, "uplow", tsens_irq_thread); - if (ret < 0) - return ret; ---- a/drivers/thermal/qcom/tsens.h -+++ b/drivers/thermal/qcom/tsens.h -@@ -13,6 +13,7 @@ - #define CAL_DEGC_PT2 120 - #define SLOPE_FACTOR 1000 - #define SLOPE_DEFAULT 3200 -+#define TIMEOUT_US 100 - #define THRESHOLD_MAX_ADC_CODE 0x3ff - #define THRESHOLD_MIN_ADC_CODE 0x0 - -@@ -25,7 +26,8 @@ struct tsens_priv; - - /* IP version numbers in ascending order */ - enum tsens_ver { -- VER_0_1 = 0, -+ VER_0 = 0, -+ VER_0_1, - VER_1_X, - VER_2_X, - }; diff --git a/target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch b/target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch deleted file mode 100644 index 109f524bbd..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-2-drivers-thermal-tsens-Don-t-hardcode-sensor-slope.patch +++ /dev/null @@ -1,28 +0,0 @@ -From efa0d50a6c5ec7619371dfe4d3e6ca54b73787d5 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 25 Nov 2020 16:47:21 +0100 -Subject: [PATCH 02/10] drivers: thermal: tsens: Don't hardcode sensor slope - -Function compute_intercept_slope hardcode the sensor slope to -SLOPE_DEFAULT. Change this and use the default value only if a slope is -not defined. This is needed for tsens VER_0 that has a hardcoded slope -table. - -Signed-off-by: Ansuel Smith -Reviewed-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/thermal/qcom/tsens.c -+++ b/drivers/thermal/qcom/tsens.c -@@ -86,7 +86,8 @@ void compute_intercept_slope(struct tsen - "%s: sensor%d - data_point1:%#x data_point2:%#x\n", - __func__, i, p1[i], p2[i]); - -- priv->sensor[i].slope = SLOPE_DEFAULT; -+ if (!priv->sensor[i].slope) -+ priv->sensor[i].slope = SLOPE_DEFAULT; - if (mode == TWO_PT_CALIB) { - /* - * slope (m) = adc_code2 - adc_code1 (y2 - y1)/ diff --git a/target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch b/target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch deleted file mode 100644 index bf378107c6..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-3-drivers-thermal-tsens-Convert-msm8960-to-reg_field.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 6bac2e2fa36c2d7c304768a689d8b73155b90aa2 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 25 Nov 2020 17:15:51 +0100 -Subject: [PATCH 03/10] drivers: thermal: tsens: Convert msm8960 to reg_field - -Convert msm9860 driver to reg_field to use the init_common -function. - -Signed-off-by: Ansuel Smith -Acked-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens-8960.c | 80 ++++++++++++++++++++++++++++++- - 1 file changed, 79 insertions(+), 1 deletion(-) - ---- a/drivers/thermal/qcom/tsens-8960.c -+++ b/drivers/thermal/qcom/tsens-8960.c -@@ -51,11 +51,22 @@ - #define MIN_LIMIT_TH 0x0 - #define MAX_LIMIT_TH 0xff - --#define S0_STATUS_ADDR 0x3628 - #define INT_STATUS_ADDR 0x363c - #define TRDY_MASK BIT(7) - #define TIMEOUT_US 100 - -+#define S0_STATUS_OFF 0x3628 -+#define S1_STATUS_OFF 0x362c -+#define S2_STATUS_OFF 0x3630 -+#define S3_STATUS_OFF 0x3634 -+#define S4_STATUS_OFF 0x3638 -+#define S5_STATUS_OFF 0x3664 /* Sensors 5-10 found on apq8064/msm8960 */ -+#define S6_STATUS_OFF 0x3668 -+#define S7_STATUS_OFF 0x366c -+#define S8_STATUS_OFF 0x3670 -+#define S9_STATUS_OFF 0x3674 -+#define S10_STATUS_OFF 0x3678 -+ - static int suspend_8960(struct tsens_priv *priv) - { - int ret; -@@ -269,6 +280,71 @@ static int get_temp_8960(const struct ts - return -ETIMEDOUT; - } - -+static struct tsens_features tsens_8960_feat = { -+ .ver_major = VER_0, -+ .crit_int = 0, -+ .adc = 1, -+ .srot_split = 0, -+ .max_sensors = 11, -+}; -+ -+static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = { -+ /* ----- SROT ------ */ -+ /* No VERSION information */ -+ -+ /* CNTL */ -+ [TSENS_EN] = REG_FIELD(CNTL_ADDR, 0, 0), -+ [TSENS_SW_RST] = REG_FIELD(CNTL_ADDR, 1, 1), -+ /* 8960 has 5 sensors, 8660 has 11, we only handle 5 */ -+ [SENSOR_EN] = REG_FIELD(CNTL_ADDR, 3, 7), -+ -+ /* ----- TM ------ */ -+ /* INTERRUPT ENABLE */ -+ /* NO INTERRUPT ENABLE */ -+ -+ /* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */ -+ [LOW_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 0, 7), -+ [UP_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 8, 15), -+ /* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield -+ * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp -+ * MIN_THRESH_0 -> CRIT_THRESH_1 -+ * MAX_THRESH_0 -> CRIT_THRESH_0 -+ */ -+ [CRIT_THRESH_1] = REG_FIELD(THRESHOLD_ADDR, 16, 23), -+ [CRIT_THRESH_0] = REG_FIELD(THRESHOLD_ADDR, 24, 31), -+ -+ /* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */ -+ /* 1 == clear, 0 == normal operation */ -+ [LOW_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 9, 9), -+ [UP_INT_CLEAR_0] = REG_FIELD(CNTL_ADDR, 10, 10), -+ -+ /* NO CRITICAL INTERRUPT SUPPORT on 8960 */ -+ -+ /* Sn_STATUS */ -+ [LAST_TEMP_0] = REG_FIELD(S0_STATUS_OFF, 0, 7), -+ [LAST_TEMP_1] = REG_FIELD(S1_STATUS_OFF, 0, 7), -+ [LAST_TEMP_2] = REG_FIELD(S2_STATUS_OFF, 0, 7), -+ [LAST_TEMP_3] = REG_FIELD(S3_STATUS_OFF, 0, 7), -+ [LAST_TEMP_4] = REG_FIELD(S4_STATUS_OFF, 0, 7), -+ [LAST_TEMP_5] = REG_FIELD(S5_STATUS_OFF, 0, 7), -+ [LAST_TEMP_6] = REG_FIELD(S6_STATUS_OFF, 0, 7), -+ [LAST_TEMP_7] = REG_FIELD(S7_STATUS_OFF, 0, 7), -+ [LAST_TEMP_8] = REG_FIELD(S8_STATUS_OFF, 0, 7), -+ [LAST_TEMP_9] = REG_FIELD(S9_STATUS_OFF, 0, 7), -+ [LAST_TEMP_10] = REG_FIELD(S10_STATUS_OFF, 0, 7), -+ -+ /* No VALID field on 8960 */ -+ /* TSENS_INT_STATUS bits: 1 == threshold violated */ -+ [MIN_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 0, 0), -+ [LOWER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 1, 1), -+ [UPPER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 2, 2), -+ /* No CRITICAL field on 8960 */ -+ [MAX_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 3, 3), -+ -+ /* TRDY: 1=ready, 0=in progress */ -+ [TRDY] = REG_FIELD(INT_STATUS_ADDR, 7, 7), -+}; -+ - static const struct tsens_ops ops_8960 = { - .init = init_8960, - .calibrate = calibrate_8960, -@@ -282,4 +358,6 @@ static const struct tsens_ops ops_8960 = - struct tsens_plat_data data_8960 = { - .num_sensors = 11, - .ops = &ops_8960, -+ .feat = &tsens_8960_feat, -+ .fields = tsens_8960_regfields, - }; diff --git a/target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch b/target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch deleted file mode 100644 index ae8a52c100..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-4-drivers-thermal-tsens-Use-init_common-for-msm8960.patch +++ /dev/null @@ -1,81 +0,0 @@ -From c04f98a496929f75d75c65115d5717423c3d0634 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 25 Nov 2020 17:16:36 +0100 -Subject: [PATCH 04/10] drivers: thermal: tsens: Use init_common for msm8960 - -Use init_common and drop custom init for msm8960. - -Signed-off-by: Ansuel Smith -Reviewed-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens-8960.c | 52 +------------------------------ - 1 file changed, 1 insertion(+), 51 deletions(-) - ---- a/drivers/thermal/qcom/tsens-8960.c -+++ b/drivers/thermal/qcom/tsens-8960.c -@@ -173,56 +173,6 @@ static void disable_8960(struct tsens_pr - regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); - } - --static int init_8960(struct tsens_priv *priv) --{ -- int ret, i; -- u32 reg_cntl; -- -- priv->tm_map = dev_get_regmap(priv->dev, NULL); -- if (!priv->tm_map) -- return -ENODEV; -- -- /* -- * The status registers for each sensor are discontiguous -- * because some SoCs have 5 sensors while others have more -- * but the control registers stay in the same place, i.e -- * directly after the first 5 status registers. -- */ -- for (i = 0; i < priv->num_sensors; i++) { -- if (i >= 5) -- priv->sensor[i].status = S0_STATUS_ADDR + 40; -- priv->sensor[i].status += i * 4; -- } -- -- reg_cntl = SW_RST; -- ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl); -- if (ret) -- return ret; -- -- if (priv->num_sensors > 1) { -- reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18); -- reg_cntl &= ~SW_RST; -- ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR, -- CONFIG_MASK, CONFIG); -- } else { -- reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16); -- reg_cntl &= ~CONFIG_MASK_8660; -- reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660; -- } -- -- reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT; -- ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); -- if (ret) -- return ret; -- -- reg_cntl |= EN; -- ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl); -- if (ret) -- return ret; -- -- return 0; --} -- - static int calibrate_8960(struct tsens_priv *priv) - { - int i; -@@ -346,7 +296,7 @@ static const struct reg_field tsens_8960 - }; - - static const struct tsens_ops ops_8960 = { -- .init = init_8960, -+ .init = init_common, - .calibrate = calibrate_8960, - .get_temp = get_temp_8960, - .enable = enable_8960, diff --git a/target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch b/target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch deleted file mode 100644 index 7b01a67d90..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-5-drivers-thermal-tsens-Fix-bug-in-sensor-enable-for-m.patch +++ /dev/null @@ -1,66 +0,0 @@ -From b3e8bd33b84a6b6c863bd1733bd15b5f1483b8ab Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 25 Nov 2020 17:06:55 +0100 -Subject: [PATCH 05/10] drivers: thermal: tsens: Fix bug in sensor enable for - msm8960 - -Device based on tsens VER_0 contains a hardware bug that results in some -problem with sensor enablement. Sensor id 6-11 can't be enabled -selectively and all of them must be enabled in one step. - -Signed-off-by: Ansuel Smith -Acked-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens-8960.c | 23 ++++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - ---- a/drivers/thermal/qcom/tsens-8960.c -+++ b/drivers/thermal/qcom/tsens-8960.c -@@ -27,9 +27,9 @@ - #define EN BIT(0) - #define SW_RST BIT(1) - #define SENSOR0_EN BIT(3) -+#define MEASURE_PERIOD BIT(18) - #define SLP_CLK_ENA BIT(26) - #define SLP_CLK_ENA_8660 BIT(24) --#define MEASURE_PERIOD 1 - #define SENSOR0_SHIFT 3 - - /* INT_STATUS_ADDR bitmasks */ -@@ -126,17 +126,34 @@ static int resume_8960(struct tsens_priv - static int enable_8960(struct tsens_priv *priv, int id) - { - int ret; -- u32 reg, mask; -+ u32 reg, mask = BIT(id); - - ret = regmap_read(priv->tm_map, CNTL_ADDR, ®); - if (ret) - return ret; - -- mask = BIT(id + SENSOR0_SHIFT); -+ /* HARDWARE BUG: -+ * On platforms with more than 6 sensors, all remaining sensors -+ * must be enabled together, otherwise undefined results are expected. -+ * (Sensor 6-7 disabled, Sensor 3 disabled...) In the original driver, -+ * all the sensors are enabled in one step hence this bug is not -+ * triggered. -+ */ -+ if (id > 5) -+ mask = GENMASK(10, 6); -+ -+ mask <<= SENSOR0_SHIFT; -+ -+ /* Sensors already enabled. Skip. */ -+ if ((reg & mask) == mask) -+ return 0; -+ - ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST); - if (ret) - return ret; - -+ reg |= MEASURE_PERIOD; -+ - if (priv->num_sensors > 1) - reg |= mask | SLP_CLK_ENA | EN; - else diff --git a/target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch b/target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch deleted file mode 100644 index a82f596954..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-6-drivers-thermal-tsens-Replace-custom-8960-apis-with-.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 1ff9f982051759e0387e8c7e793b49c48eae291d Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 25 Nov 2020 17:11:05 +0100 -Subject: [PATCH 06/10] drivers: thermal: tsens: Replace custom 8960 apis with - generic apis - -Rework calibrate function to use common function. Derive the offset from -a missing hardcoded slope table and the data from the nvmem calib -efuses. -Drop custom get_temp function and use generic api. - -Signed-off-by: Ansuel Smith -Acked-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens-8960.c | 56 +++++++++---------------------- - 1 file changed, 15 insertions(+), 41 deletions(-) - ---- a/drivers/thermal/qcom/tsens-8960.c -+++ b/drivers/thermal/qcom/tsens-8960.c -@@ -67,6 +67,13 @@ - #define S9_STATUS_OFF 0x3674 - #define S10_STATUS_OFF 0x3678 - -+/* Original slope - 200 to compensate mC to C inaccuracy */ -+static u32 tsens_msm8960_slope[] = { -+ 976, 976, 954, 976, -+ 911, 932, 932, 999, -+ 932, 999, 932 -+ }; -+ - static int suspend_8960(struct tsens_priv *priv) - { - int ret; -@@ -194,9 +201,7 @@ static int calibrate_8960(struct tsens_p - { - int i; - char *data; -- -- ssize_t num_read = priv->num_sensors; -- struct tsens_sensor *s = priv->sensor; -+ u32 p1[11]; - - data = qfprom_read(priv->dev, "calib"); - if (IS_ERR(data)) -@@ -204,49 +209,18 @@ static int calibrate_8960(struct tsens_p - if (IS_ERR(data)) - return PTR_ERR(data); - -- for (i = 0; i < num_read; i++, s++) -- s->offset = data[i]; -+ for (i = 0; i < priv->num_sensors; i++) { -+ p1[i] = data[i]; -+ priv->sensor[i].slope = tsens_msm8960_slope[i]; -+ } -+ -+ compute_intercept_slope(priv, p1, NULL, ONE_PT_CALIB); - - kfree(data); - - return 0; - } - --/* Temperature on y axis and ADC-code on x-axis */ --static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s) --{ -- int slope, offset; -- -- slope = thermal_zone_get_slope(s->tzd); -- offset = CAL_MDEGC - slope * s->offset; -- -- return adc_code * slope + offset; --} -- --static int get_temp_8960(const struct tsens_sensor *s, int *temp) --{ -- int ret; -- u32 code, trdy; -- struct tsens_priv *priv = s->priv; -- unsigned long timeout; -- -- timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); -- do { -- ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy); -- if (ret) -- return ret; -- if (!(trdy & TRDY_MASK)) -- continue; -- ret = regmap_read(priv->tm_map, s->status, &code); -- if (ret) -- return ret; -- *temp = code_to_mdegC(code, s); -- return 0; -- } while (time_before(jiffies, timeout)); -- -- return -ETIMEDOUT; --} -- - static struct tsens_features tsens_8960_feat = { - .ver_major = VER_0, - .crit_int = 0, -@@ -315,7 +289,7 @@ static const struct reg_field tsens_8960 - static const struct tsens_ops ops_8960 = { - .init = init_common, - .calibrate = calibrate_8960, -- .get_temp = get_temp_8960, -+ .get_temp = get_temp_common, - .enable = enable_8960, - .disable = disable_8960, - .suspend = suspend_8960, diff --git a/target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch b/target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch deleted file mode 100644 index 77ca3cfe45..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-7-drivers-thermal-tsens-Drop-unused-define-for-msm8960.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 5716a61239c6ac9ceb137e825e93c3aea06c4634 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Fri, 19 Mar 2021 00:48:23 +0100 -Subject: [PATCH 07/10] drivers: thermal: tsens: Drop unused define for msm8960 - -Drop unused define for msm8960 replaced by generic api and reg_field. - -Signed-off-by: Ansuel Smith -Reviewed-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens-8960.c | 24 +----------------------- - 1 file changed, 1 insertion(+), 23 deletions(-) - ---- a/drivers/thermal/qcom/tsens-8960.c -+++ b/drivers/thermal/qcom/tsens-8960.c -@@ -10,8 +10,6 @@ - #include - #include "tsens.h" - --#define CAL_MDEGC 30000 -- - #define CONFIG_ADDR 0x3640 - #define CONFIG_ADDR_8660 0x3620 - /* CONFIG_ADDR bitmasks */ -@@ -21,39 +19,19 @@ - #define CONFIG_SHIFT_8660 28 - #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660) - --#define STATUS_CNTL_ADDR_8064 0x3660 - #define CNTL_ADDR 0x3620 - /* CNTL_ADDR bitmasks */ - #define EN BIT(0) - #define SW_RST BIT(1) --#define SENSOR0_EN BIT(3) -+ - #define MEASURE_PERIOD BIT(18) - #define SLP_CLK_ENA BIT(26) - #define SLP_CLK_ENA_8660 BIT(24) - #define SENSOR0_SHIFT 3 - --/* INT_STATUS_ADDR bitmasks */ --#define MIN_STATUS_MASK BIT(0) --#define LOWER_STATUS_CLR BIT(1) --#define UPPER_STATUS_CLR BIT(2) --#define MAX_STATUS_MASK BIT(3) -- - #define THRESHOLD_ADDR 0x3624 --/* THRESHOLD_ADDR bitmasks */ --#define THRESHOLD_MAX_LIMIT_SHIFT 24 --#define THRESHOLD_MIN_LIMIT_SHIFT 16 --#define THRESHOLD_UPPER_LIMIT_SHIFT 8 --#define THRESHOLD_LOWER_LIMIT_SHIFT 0 -- --/* Initial temperature threshold values */ --#define LOWER_LIMIT_TH 0x50 --#define UPPER_LIMIT_TH 0xdf --#define MIN_LIMIT_TH 0x0 --#define MAX_LIMIT_TH 0xff - - #define INT_STATUS_ADDR 0x363c --#define TRDY_MASK BIT(7) --#define TIMEOUT_US 100 - - #define S0_STATUS_OFF 0x3628 - #define S1_STATUS_OFF 0x362c diff --git a/target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch b/target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch deleted file mode 100644 index 127abaefc3..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-8-drivers-thermal-tsens-Add-support-for-ipq8064-tsens.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0d0c22a59bf2672b57e23da9a9ea743e91b71f54 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 25 Jul 2020 19:55:57 +0200 -Subject: [PATCH 08/10] drivers: thermal: tsens: Add support for ipq8064-tsens - -Add support for tsens present in ipq806x SoCs based on generic msm8960 -tsens driver. - -Signed-off-by: Ansuel Smith -Reviewed-by: Thara Gopinath ---- - drivers/thermal/qcom/tsens.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/thermal/qcom/tsens.c -+++ b/drivers/thermal/qcom/tsens.c -@@ -968,6 +968,9 @@ static SIMPLE_DEV_PM_OPS(tsens_pm_ops, t - - static const struct of_device_id tsens_table[] = { - { -+ .compatible = "qcom,ipq8064-tsens", -+ .data = &data_8960, -+ }, { - .compatible = "qcom,msm8916-tsens", - .data = &data_8916, - }, { diff --git a/target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch b/target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch deleted file mode 100644 index 382106863f..0000000000 --- a/target/linux/ipq806x/patches-5.15/104-9-dt-bindings-thermal-tsens-Document-ipq8064-bindings.patch +++ /dev/null @@ -1,112 +0,0 @@ -From ac369071920d427dd484cf74cddba2774bba45f5 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 9 Jul 2020 22:35:54 +0200 -Subject: [PATCH 09/10] dt-bindings: thermal: tsens: Document ipq8064 bindings - -Document the use of bindings used for msm8960 tsens based devices. -msm8960 use the same gcc regs and is set as a child of the qcom gcc. - -Signed-off-by: Ansuel Smith -Reviewed-by: Rob Herring ---- - .../bindings/thermal/qcom-tsens.yaml | 56 ++++++++++++++++--- - 1 file changed, 48 insertions(+), 8 deletions(-) - ---- a/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml -+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.yaml -@@ -19,6 +19,11 @@ description: | - properties: - compatible: - oneOf: -+ - description: msm9860 TSENS based -+ items: -+ - enum: -+ - qcom,ipq8064-tsens -+ - - description: v0.1 of TSENS - items: - - enum: -@@ -73,7 +78,9 @@ properties: - maxItems: 2 - items: - - const: calib -- - const: calib_sel -+ - enum: -+ - calib_backup -+ - calib_sel - - "#qcom,sensors": - description: -@@ -88,12 +95,20 @@ properties: - Number of cells required to uniquely identify the thermal sensors. Since - we have multiple sensors this is set to 1 - -+required: -+ - compatible -+ - interrupts -+ - interrupt-names -+ - "#thermal-sensor-cells" -+ - "#qcom,sensors" -+ - allOf: - - if: - properties: - compatible: - contains: - enum: -+ - qcom,ipq8064-tsens - - qcom,msm8916-tsens - - qcom,msm8974-tsens - - qcom,msm8976-tsens -@@ -114,19 +129,44 @@ allOf: - interrupt-names: - minItems: 2 - --required: -- - compatible -- - reg -- - "#qcom,sensors" -- - interrupts -- - interrupt-names -- - "#thermal-sensor-cells" -+ - if: -+ properties: -+ compatible: -+ contains: -+ enum: -+ - qcom,tsens-v0_1 -+ - qcom,tsens-v1 -+ - qcom,tsens-v2 -+ -+ then: -+ required: -+ - reg - - additionalProperties: false - - examples: - - | - #include -+ // Example msm9860 based SoC (ipq8064): -+ gcc: clock-controller { -+ -+ /* ... */ -+ -+ tsens: thermal-sensor { -+ compatible = "qcom,ipq8064-tsens"; -+ -+ nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>; -+ nvmem-cell-names = "calib", "calib_backup"; -+ interrupts = ; -+ interrupt-names = "uplow"; -+ -+ #qcom,sensors = <11>; -+ #thermal-sensor-cells = <1>; -+ }; -+ }; -+ -+ - | -+ #include - // Example 1 (legacy: for pre v1 IP): - tsens1: thermal-sensor@900000 { - compatible = "qcom,msm8916-tsens", "qcom,tsens-v0_1"; diff --git a/target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch b/target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch deleted file mode 100644 index 6cdc0b263f..0000000000 --- a/target/linux/ipq806x/patches-5.15/105-10-drivers-thermal-tsens-Fix-wrong-slope-on-msm-8960.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 68e720ed73c8f038c8c500e4c49c1e65a993a448 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 6 Apr 2021 04:45:31 +0200 -Subject: [PATCH 10/10] drivers: thermal: tsens: Fix wrong slope on msm-8960 - -Some user using some stats with the old legacy implementation and the -new implementation using the compute_intercept_slope reported an offset -of 3C. Fix the slope table to reflect the original temp. - -Signed-off-by: Ansuel Smith ---- - drivers/thermal/qcom/tsens-8960.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/thermal/qcom/tsens-8960.c -+++ b/drivers/thermal/qcom/tsens-8960.c -@@ -45,11 +45,11 @@ - #define S9_STATUS_OFF 0x3674 - #define S10_STATUS_OFF 0x3678 - --/* Original slope - 200 to compensate mC to C inaccuracy */ -+/* Original slope - 350 to compensate mC to C inaccuracy */ - static u32 tsens_msm8960_slope[] = { -- 976, 976, 954, 976, -- 911, 932, 932, 999, -- 932, 999, 932 -+ 826, 826, 804, 826, -+ 761, 782, 782, 849, -+ 782, 849, 782 - }; - - static int suspend_8960(struct tsens_priv *priv) diff --git a/target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch b/target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch deleted file mode 100644 index dd1e506e5b..0000000000 --- a/target/linux/ipq806x/patches-5.15/108-v5.14-net-stmmac-explicitly-deassert-gmac-ahb-reset.patch +++ /dev/null @@ -1,75 +0,0 @@ -From e67f325e9cd67562b761e884680c0fec03a6f404 Mon Sep 17 00:00:00 2001 -From: Matthew Hagan -Date: Tue, 8 Jun 2021 19:59:06 +0100 -Subject: net: stmmac: explicitly deassert GMAC_AHB_RESET - -We are currently assuming that GMAC_AHB_RESET will already be deasserted -by the bootloader. However if this has not been done, probing of the GMAC -will fail. To remedy this we must ensure GMAC_AHB_RESET has been deasserted -prior to probing. - -v2 changes: - - remove NULL condition check for stmmac_ahb_rst in stmmac_main.c - - unwrap dev_err() message in stmmac_main.c - - add PTR_ERR() around plat->stmmac_ahb_rst in stmmac_platform.c - -v3 changes: - - add error pointer to dev_err() output - - add reset_control_assert(stmmac_ahb_rst) in stmmac_dvr_remove - - revert PTR_ERR() around plat->stmmac_ahb_rst since this is performed - on the returned value of ret by the calling function - -Signed-off-by: Matthew Hagan -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++ - drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++++ - include/linux/stmmac.h | 1 + - 3 files changed, 12 insertions(+) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -5021,6 +5021,10 @@ int stmmac_dvr_probe(struct device *devi - reset_control_reset(priv->plat->stmmac_rst); - } - -+ ret = reset_control_deassert(priv->plat->stmmac_ahb_rst); -+ if (ret == -ENOTSUPP) -+ dev_err(priv->device, "unable to bring out of ahb reset\n"); -+ - /* Init MAC and get the capabilities */ - ret = stmmac_hw_init(priv); - if (ret) -@@ -5245,6 +5249,7 @@ int stmmac_dvr_remove(struct device *dev - phylink_destroy(priv->phylink); - if (priv->plat->stmmac_rst) - reset_control_assert(priv->plat->stmmac_rst); -+ reset_control_assert(priv->plat->stmmac_ahb_rst); - pm_runtime_put(dev); - pm_runtime_disable(dev); - if (priv->hw->pcs != STMMAC_PCS_TBI && ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -@@ -617,6 +617,12 @@ stmmac_probe_config_dt(struct platform_d - plat->stmmac_rst = NULL; - } - -+ plat->stmmac_ahb_rst = devm_reset_control_get_optional_shared( -+ &pdev->dev, "ahb"); -+ if (IS_ERR(plat->stmmac_ahb_rst)) -+ if (PTR_ERR(plat->stmmac_ahb_rst) == -EPROBE_DEFER) -+ goto error_hw_init; -+ - return plat; - - error_hw_init: ---- a/include/linux/stmmac.h -+++ b/include/linux/stmmac.h -@@ -192,6 +192,7 @@ struct plat_stmmacenet_data { - unsigned int clk_ref_rate; - s32 ptp_max_adj; - struct reset_control *stmmac_rst; -+ struct reset_control *stmmac_ahb_rst; - struct stmmac_axi *axi; - int has_gmac4; - bool has_sun8i; diff --git a/target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch b/target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch deleted file mode 100644 index 4a047ed6eb..0000000000 --- a/target/linux/ipq806x/patches-5.15/109-v5.15-arm-dts-qcom-add-ahb-reset-to-ipq806x-gmac.patch +++ /dev/null @@ -1,64 +0,0 @@ -From f95c4c56d65225a537a2d88735fde7ec4d37641d Mon Sep 17 00:00:00 2001 -From: Matthew Hagan -Date: Sat, 5 Jun 2021 18:35:38 +0100 -Subject: ARM: dts: qcom: add ahb reset to ipq806x-gmac - -Add GMAC_AHB_RESET to the resets property of each gmac node. - -Signed-off-by: Matthew Hagan -Link: https://lore.kernel.org/r/20210605173546.4102455-2-mnhagan88@gmail.com -Signed-off-by: Bjorn Andersson ---- - arch/arm/boot/dts/qcom-ipq8064.dtsi | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -1335,8 +1335,9 @@ - clocks = <&gcc GMAC_CORE1_CLK>; - clock-names = "stmmaceth"; - -- resets = <&gcc GMAC_CORE1_RESET>; -- reset-names = "stmmaceth"; -+ resets = <&gcc GMAC_CORE1_RESET>, -+ <&gcc GMAC_AHB_RESET>; -+ reset-names = "stmmaceth", "ahb"; - - status = "disabled"; - }; -@@ -1358,8 +1359,9 @@ - clocks = <&gcc GMAC_CORE2_CLK>; - clock-names = "stmmaceth"; - -- resets = <&gcc GMAC_CORE2_RESET>; -- reset-names = "stmmaceth"; -+ resets = <&gcc GMAC_CORE2_RESET>, -+ <&gcc GMAC_AHB_RESET>; -+ reset-names = "stmmaceth", "ahb"; - - status = "disabled"; - }; -@@ -1381,8 +1383,9 @@ - clocks = <&gcc GMAC_CORE3_CLK>; - clock-names = "stmmaceth"; - -- resets = <&gcc GMAC_CORE3_RESET>; -- reset-names = "stmmaceth"; -+ resets = <&gcc GMAC_CORE3_RESET>, -+ <&gcc GMAC_AHB_RESET>; -+ reset-names = "stmmaceth", "ahb"; - - status = "disabled"; - }; -@@ -1404,8 +1407,9 @@ - clocks = <&gcc GMAC_CORE4_CLK>; - clock-names = "stmmaceth"; - -- resets = <&gcc GMAC_CORE4_RESET>; -- reset-names = "stmmaceth"; -+ resets = <&gcc GMAC_CORE4_RESET>, -+ <&gcc GMAC_AHB_RESET>; -+ reset-names = "stmmaceth", "ahb"; - - status = "disabled"; - }; From 8cc2caed58e79ac24f9f5a075c6a12b07453c923 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Fri, 5 Nov 2021 01:14:57 +0100 Subject: [PATCH 15/23] ipq806x: 5:15: add testing kernel version Refresh patch for 5.15 Rework tweak patch to sync with upstream ipq8064 dtsi and fix regression introduced. Rename nand_controller to nand in every dts. Signed-off-by: Ansuel Smith --- target/linux/ipq806x/Makefile | 1 + .../arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 2 +- .../arch/arm/boot/dts/qcom-ipq8064-ap161.dts | 2 +- .../arch/arm/boot/dts/qcom-ipq8064-d7800.dts | 2 +- .../arm/boot/dts/qcom-ipq8064-eax500.dtsi | 2 +- .../arch/arm/boot/dts/qcom-ipq8064-g10.dts | 2 +- .../arch/arm/boot/dts/qcom-ipq8064-r7500.dts | 2 +- .../arm/boot/dts/qcom-ipq8064-r7500v2.dts | 2 +- .../arm/boot/dts/qcom-ipq8064-unifi-ac-hd.dts | 2 +- .../arch/arm/boot/dts/qcom-ipq8064-wpq864.dts | 2 +- .../arm/boot/dts/qcom-ipq8064-wxr-2533dhp.dts | 2 +- .../arm/boot/dts/qcom-ipq8065-nighthawk.dtsi | 2 +- .../boot/dts/qcom-ipq8065-rt4230w-rev6.dts | 2 +- .../boot/dts/qcom-ipq8068-cryptid-common.dtsi | 2 +- .../arm/boot/dts/qcom-ipq8068-ecw5410.dts | 2 +- ...arch-arm-force-ZRELADDR-on-arch-qcom.patch | 2 +- ...Mangle-bootloader-s-kernel-arguments.patch | 2 +- .../0069-arm-boot-add-dts-files.patch | 6 +- .../0072-add-ipq806x-with-no-clocks.patch | 8 +- .../082-ipq8064-dtsi-tweaks.patch | 220 +++---- .../083-ipq8064-dtsi-additions.patch | 565 ++---------------- .../084-ipq8064-v1.0-dtsi-cleanup.patch | 2 +- .../086-ipq8064-fix-duplicate-node.patch | 4 +- ...q-add-Krait-dedicated-scaling-driver.patch | 2 +- ...m_nandc-add-boot_layout_mode-support.patch | 25 +- ...vicetree-mtd-qcom_nandc-document-qco.patch | 50 +- .../patches-5.15/851-add-gsbi1-dts.patch | 44 ++ .../900-arm-add-cmdline-override.patch | 37 -- 28 files changed, 274 insertions(+), 722 deletions(-) create mode 100644 target/linux/ipq806x/patches-5.15/851-add-gsbi1-dts.patch delete mode 100644 target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile index 1735235b45..665a830e34 100644 --- a/target/linux/ipq806x/Makefile +++ b/target/linux/ipq806x/Makefile @@ -11,6 +11,7 @@ CPU_SUBTYPE:=neon-vfpv4 SUBTARGETS:=generic KERNEL_PATCHVER:=5.10 +KERNEL_TESTING_PATCHVER:=5.15 KERNELNAME:=zImage Image dtbs diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap148.dts index 29476e3877..70034a50e3 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap148.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap148.dts @@ -51,7 +51,7 @@ max-link-speed = <1>; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap161.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap161.dts index 914c370552..c771a627ca 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap161.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-ap161.dts @@ -63,7 +63,7 @@ status = "okay"; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-d7800.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-d7800.dts index 2f259150fa..23487c9ca0 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-d7800.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-d7800.dts @@ -231,7 +231,7 @@ pinctrl-names = "default"; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi index 955ad97e3a..e74d2dcdbd 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi @@ -34,7 +34,7 @@ status = "okay"; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-g10.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-g10.dts index 71dc177b1f..735ccb2d53 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-g10.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-g10.dts @@ -172,7 +172,7 @@ }; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500.dts index c7d26a0772..94b7ed6277 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500.dts @@ -166,7 +166,7 @@ max-link-speed = <1>; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500v2.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500v2.dts index b3181d8857..30b56bb9d6 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500v2.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-r7500v2.dts @@ -228,7 +228,7 @@ }; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-unifi-ac-hd.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-unifi-ac-hd.dts index a50204fee1..b3e06db86d 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-unifi-ac-hd.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-unifi-ac-hd.dts @@ -218,7 +218,7 @@ status = "okay"; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wpq864.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wpq864.dts index ec5d5047aa..d7f3a7f881 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wpq864.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wpq864.dts @@ -103,7 +103,7 @@ pinctrl-names = "default"; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wxr-2533dhp.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wxr-2533dhp.dts index e7ae1a25b2..04a2261929 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wxr-2533dhp.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8064-wxr-2533dhp.dts @@ -156,7 +156,7 @@ }; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-nighthawk.dtsi b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-nighthawk.dtsi index cca887bb3b..c899fa7c75 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-nighthawk.dtsi +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-nighthawk.dtsi @@ -220,7 +220,7 @@ }; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-rt4230w-rev6.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-rt4230w-rev6.dts index 0ad2dfa57b..d700149939 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-rt4230w-rev6.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8065-rt4230w-rev6.dts @@ -98,7 +98,7 @@ }; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-cryptid-common.dtsi b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-cryptid-common.dtsi index 10ab4821e8..141c71a8aa 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-cryptid-common.dtsi +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-cryptid-common.dtsi @@ -137,7 +137,7 @@ status = "okay"; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-ecw5410.dts b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-ecw5410.dts index 377bb09616..85b0dc3b8c 100644 --- a/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-ecw5410.dts +++ b/target/linux/ipq806x/files/arch/arm/boot/dts/qcom-ipq8068-ecw5410.dts @@ -259,7 +259,7 @@ }; }; -&nand_controller { +&nand { status = "okay"; pinctrl-0 = <&nand_pins>; diff --git a/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch b/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch index b73218e71b..b56480deaa 100644 --- a/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch +++ b/target/linux/ipq806x/patches-5.15/0060-HACK-arch-arm-force-ZRELADDR-on-arch-qcom.patch @@ -33,7 +33,7 @@ Signed-off-by: Mathieu Olivari --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -322,7 +322,7 @@ config ARCH_MULTIPLATFORM +@@ -321,7 +321,7 @@ config ARCH_MULTIPLATFORM select ARCH_SELECT_MEMORY_MODEL select ARM_HAS_SG_CHAIN select ARM_PATCH_PHYS_VIRT diff --git a/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch b/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch index 8f669319ed..06bfac2a7e 100644 --- a/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch +++ b/target/linux/ipq806x/patches-5.15/0067-generic-Mangle-bootloader-s-kernel-arguments.patch @@ -22,7 +22,7 @@ Signed-off-by: Adrian Panella --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -1781,6 +1781,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN +@@ -1780,6 +1780,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN The command-line arguments provided by the boot loader will be appended to the the device tree bootargs property. diff --git a/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch b/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch index 49ff218040..e943308433 100644 --- a/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch +++ b/target/linux/ipq806x/patches-5.15/0069-arm-boot-add-dts-files.patch @@ -10,7 +10,7 @@ Signed-off-by: John Crispin --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -907,8 +907,29 @@ dtb-$(CONFIG_ARCH_QCOM) += \ +@@ -955,8 +955,29 @@ dtb-$(CONFIG_ARCH_QCOM) += \ qcom-ipq4019-ap.dk04.1-c3.dtb \ qcom-ipq4019-ap.dk07.1-c1.dtb \ qcom-ipq4019-ap.dk07.1-c2.dtb \ @@ -32,11 +32,11 @@ Signed-off-by: John Crispin + qcom-ipq8064-wxr-2533dhp.dtb \ + qcom-ipq8065-nbg6817.dtb \ + qcom-ipq8065-r7800.dtb \ -+ qcom-ipq8065-rt4230w-rev6.dtb \ + qcom-ipq8065-xr500.dtb \ ++ qcom-ipq8065-rt4230w-rev6.dtb \ + qcom-ipq8068-ecw5410.dtb \ + qcom-ipq8068-mr42.dtb \ + qcom-ipq8068-mr52.dtb \ + qcom-msm8226-samsung-s3ve3g.dtb \ qcom-msm8660-surf.dtb \ qcom-msm8960-cdp.dtb \ - qcom-msm8974-fairphone-fp2.dtb \ diff --git a/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch b/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch index 62bba1d72a..f0cda0ba8b 100644 --- a/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch +++ b/target/linux/ipq806x/patches-5.15/0072-add-ipq806x-with-no-clocks.patch @@ -1,10 +1,10 @@ --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c -@@ -1275,6 +1275,7 @@ static const struct of_device_id qcom_sc +@@ -1339,6 +1339,7 @@ static const struct of_device_id qcom_sc SCM_HAS_BUS_CLK) }, { .compatible = "qcom,scm-ipq4019" }, + { .compatible = "qcom,scm-ipq806x" }, - { .compatible = "qcom,scm-msm8660", .data = (void *) SCM_HAS_CORE_CLK }, - { .compatible = "qcom,scm-msm8960", .data = (void *) SCM_HAS_CORE_CLK }, - { .compatible = "qcom,scm-msm8916", .data = (void *)(SCM_HAS_CORE_CLK | + { .compatible = "qcom,scm-mdm9607", .data = (void *)(SCM_HAS_CORE_CLK | + SCM_HAS_IFACE_CLK | + SCM_HAS_BUS_CLK) }, diff --git a/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch b/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch index d6a4593749..8393237218 100644 --- a/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch +++ b/target/linux/ipq806x/patches-5.15/082-ipq8064-dtsi-tweaks.patch @@ -1,33 +1,6 @@ --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -20,7 +20,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- cpu@0 { -+ cpu0: cpu@0 { - compatible = "qcom,krait"; - enable-method = "qcom,kpss-acc-v1"; - device_type = "cpu"; -@@ -30,7 +30,7 @@ - qcom,saw = <&saw0>; - }; - -- cpu@1 { -+ cpu1: cpu@1 { - compatible = "qcom,krait"; - enable-method = "qcom,kpss-acc-v1"; - device_type = "cpu"; -@@ -67,7 +67,7 @@ - no-map; - }; - -- smem@41000000 { -+ smem: smem@41000000 { - reg = <0x41000000 0x200000>; - no-map; - }; -@@ -128,6 +128,7 @@ +@@ -352,6 +352,7 @@ gpio-ranges = <&qcom_pinmux 0 0 69>; #gpio-cells = <2>; interrupt-controller; @@ -35,7 +8,7 @@ #interrupt-cells = <2>; interrupts = ; -@@ -155,6 +156,7 @@ +@@ -379,6 +380,7 @@ function = "pcie3_rst"; drive-strength = <12>; bias-disable; @@ -43,7 +16,40 @@ }; }; -@@ -190,6 +192,7 @@ +@@ -411,12 +413,9 @@ + }; + + nand_pins: nand_pins { +- mux { ++ disable { + pins = "gpio34", "gpio35", "gpio36", +- "gpio37", "gpio38", "gpio39", +- "gpio40", "gpio41", "gpio42", +- "gpio43", "gpio44", "gpio45", +- "gpio46", "gpio47"; ++ "gpio37", "gpio38"; + function = "nand"; + drive-strength = <10>; + bias-disable; +@@ -424,6 +423,8 @@ + + pullups { + pins = "gpio39"; ++ function = "nand"; ++ drive-strength = <10>; + bias-pull-up; + }; + +@@ -431,6 +432,8 @@ + pins = "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", + "gpio46", "gpio47"; ++ function = "nand"; ++ drive-strength = <10>; + bias-bus-hold; + }; + }; +@@ -439,6 +442,7 @@ intc: interrupt-controller@2000000 { compatible = "qcom,msm-qgic2"; interrupt-controller; @@ -51,7 +57,7 @@ #interrupt-cells = <3>; reg = <0x02000000 0x1000>, <0x02002000 0x1000>; -@@ -219,21 +222,23 @@ +@@ -468,11 +472,13 @@ acc0: clock-controller@2088000 { compatible = "qcom,kpss-acc-v1"; reg = <0x02088000 0x1000>, <0x02008000 0x1000>; @@ -64,6 +70,10 @@ + clock-output-names = "acpu1_aux"; }; + adm_dma: dma-controller@18300000 { +@@ -496,13 +502,13 @@ + }; + saw0: regulator@2089000 { - compatible = "qcom,saw2"; + compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon"; @@ -77,16 +87,7 @@ reg = <0x02099000 0x1000>, <0x02009000 0x1000>; regulator; }; -@@ -251,7 +256,7 @@ - - syscon-tcsr = <&tcsr>; - -- serial@12490000 { -+ gsbi2_serial: serial@12490000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x12490000 0x1000>, - <0x12480000 0x1000>; -@@ -261,7 +266,7 @@ +@@ -533,7 +533,7 @@ status = "disabled"; }; @@ -95,35 +96,20 @@ compatible = "qcom,i2c-qup-v1.1.1"; reg = <0x124a0000 0x1000>; interrupts = ; -@@ -326,7 +331,7 @@ +@@ -676,9 +682,6 @@ + compatible = "qcom,ipq806x-nand"; + reg = <0x1ac00000 0x800>; - syscon-tcsr = <&tcsr>; - -- serial@1a240000 { -+ gsbi5_serial: serial@1a240000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x1a240000 0x1000>, - <0x1a200000 0x1000>; -@@ -397,7 +402,7 @@ - status = "disabled"; - }; - -- sata@29000000 { -+ sata: sata@29000000 { - compatible = "qcom,ipq806x-ahci", "generic-ahci"; - reg = <0x29000000 0x180>; - -@@ -430,13 +435,35 @@ - reg = <0x00700000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; -+ -+ tsens_calib: calib@400 { -+ reg = <0x400 0xb>; -+ }; -+ tsens_backup: backup@410 { -+ reg = <0x410 0xb>; -+ }; +- pinctrl-0 = <&nand_pins>; +- pinctrl-names = "default"; +- + clocks = <&gcc EBI2_CLK>, + <&gcc EBI2_AON_CLK>; + clock-names = "core", "aon"; +@@ -733,10 +736,13 @@ + tsens_calib_backup: calib_backup@410 { + reg = <0x410 0xb>; + }; + speedbin_efuse: speedbin@0c0 { + reg = <0x0c0 0x4>; + }; @@ -135,22 +121,53 @@ reg = <0x00900000 0x4000>; #clock-cells = <1>; #reset-cells = <1>; -+ #power-domain-cells = <1>; +@@ -768,10 +774,45 @@ + clocks = <&gcc RPM_MSG_RAM_H_CLK>; + clock-names = "ram"; + ++ #address-cells = <1>; ++ #size-cells = <0>; + -+ tsens: thermal-sensor@900000 { -+ compatible = "qcom,ipq8064-tsens"; + rpmcc: clock-controller { + compatible = "qcom,rpmcc-ipq806x", "qcom,rpmcc"; + #clock-cells = <1>; + }; + -+ nvmem-cells = <&tsens_calib>, <&tsens_backup>; -+ nvmem-cell-names = "calib", "calib_backup"; -+ interrupts = ; -+ interrupt-names = "uplow"; -+ #thermal-sensor-cells = <1>; -+ #qcom,sensors = <11>; ++ regulators { ++ compatible = "qcom,rpm-smb208-regulators"; ++ ++ smb208_s1a: s1a { ++ regulator-min-microvolt = <1050000>; ++ regulator-max-microvolt = <1150000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ ++ smb208_s1b: s1b { ++ regulator-min-microvolt = <1050000>; ++ regulator-max-microvolt = <1150000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ ++ smb208_s2a: s2a { ++ regulator-min-microvolt = < 800000>; ++ regulator-max-microvolt = <1250000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; ++ ++ smb208_s2b: s2b { ++ regulator-min-microvolt = < 800000>; ++ regulator-max-microvolt = <1250000>; ++ ++ qcom,switch-mode-frequency = <1200000>; ++ }; + }; }; tcsr: syscon@1a400000 { -@@ -622,7 +649,7 @@ +@@ -965,7 +1006,7 @@ gmac0: ethernet@37000000 { device_type = "network"; @@ -159,7 +176,7 @@ reg = <0x37000000 0x200000>; interrupts = ; interrupt-names = "macirq"; -@@ -645,7 +672,7 @@ +@@ -989,7 +1030,7 @@ gmac1: ethernet@37200000 { device_type = "network"; @@ -168,7 +185,7 @@ reg = <0x37200000 0x200000>; interrupts = ; interrupt-names = "macirq"; -@@ -668,7 +695,7 @@ +@@ -1013,7 +1054,7 @@ gmac2: ethernet@37400000 { device_type = "network"; @@ -177,7 +194,7 @@ reg = <0x37400000 0x200000>; interrupts = ; interrupt-names = "macirq"; -@@ -691,7 +718,7 @@ +@@ -1037,7 +1078,7 @@ gmac3: ethernet@37600000 { device_type = "network"; @@ -186,24 +203,34 @@ reg = <0x37600000 0x200000>; interrupts = ; interrupt-names = "macirq"; -@@ -740,13 +767,13 @@ - qcom,ee = <0>; +@@ -1050,8 +1050,6 @@ + clocks = <&gcc USB30_0_UTMI_CLK>; + clock-names = "ref"; + #phy-cells = <0>; +- +- status = "disabled"; }; -- amba { + ss_phy_0: usb3phy@100f8830 { +@@ -1055,8 +1055,6 @@ + clocks = <&gcc USB30_0_MASTER_CLK>; + clock-names = "ref"; + #phy-cells = <0>; +- +- status = "disabled"; + }; + + usb3_0: usb3@100f8800 { +@@ -1176,7 +1217,7 @@ + }; + + amba: amba { - compatible = "simple-bus"; -+ amba: amba { + compatible = "arm,amba-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - -- sdcc@12400000 { -+ sdcc1: sdcc@12400000 { - status = "disabled"; - compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00051180>; -@@ -760,13 +787,12 @@ +@@ -1195,7 +1236,6 @@ non-removable; cap-sd-highspeed; cap-mmc-highspeed; @@ -211,10 +238,3 @@ vmmc-supply = <&vsdcc_fixed>; dmas = <&sdcc1bam 2>, <&sdcc1bam 1>; dma-names = "tx", "rx"; - }; - -- sdcc@12180000 { -+ sdcc3: sdcc@12180000 { - compatible = "arm,pl18x", "arm,primecell"; - arm,primecell-periphid = <0x00051180>; - status = "disabled"; diff --git a/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch b/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch index 2667bd636e..a85f8ac818 100644 --- a/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch +++ b/target/linux/ipq806x/patches-5.15/083-ipq8064-dtsi-additions.patch @@ -1,6 +1,6 @@ --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -8,6 +8,8 @@ +@@ -10,6 +10,8 @@ #include #include #include @@ -9,7 +9,7 @@ / { #address-cells = <1>; -@@ -28,6 +30,16 @@ +@@ -30,6 +32,16 @@ next-level-cache = <&L2>; qcom,acc = <&acc0>; qcom,saw = <&saw0>; @@ -26,7 +26,7 @@ }; cpu1: cpu@1 { -@@ -38,14 +50,350 @@ +@@ -40,11 +52,125 @@ next-level-cache = <&L2>; qcom,acc = <&acc1>; qcom,saw = <&saw1>; @@ -155,232 +155,7 @@ }; }; -+ thermal-zones { -+ tsens_tz_sensor0 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 0>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor1 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 1>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor2 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 2>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor3 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 3>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor4 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 4>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor5 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 5>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor6 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 6>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor7 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 7>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor8 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 8>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor9 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 9>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ -+ tsens_tz_sensor10 { -+ polling-delay-passive = <0>; -+ polling-delay = <0>; -+ thermal-sensors = <&tsens 10>; -+ -+ trips { -+ cpu-critical { -+ temperature = <105000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ -+ cpu-hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ }; -+ }; -+ }; -+ - memory { - device_type = "memory"; - reg = <0x0 0x0>; -@@ -93,6 +441,15 @@ +@@ -317,6 +443,15 @@ }; }; @@ -396,86 +171,7 @@ firmware { scm { compatible = "qcom,scm-ipq806x", "qcom,scm"; -@@ -120,6 +477,78 @@ - reg-names = "lpass-lpaif"; - }; - -+ L2: l2-cache { -+ compatible = "qcom,krait-cache", "cache"; -+ cache-level = <2>; -+ qcom,saw = <&saw_l2>; -+ -+ clocks = <&kraitcc 4>; -+ clock-names = "l2"; -+ l2-supply = <&smb208_s1a>; -+ operating-points-v2 = <&opp_table_l2>; -+ }; -+ -+ rpm: rpm@108000 { -+ compatible = "qcom,rpm-ipq8064"; -+ reg = <0x108000 0x1000>; -+ qcom,ipc = <&l2cc 0x8 2>; -+ -+ interrupts = , -+ , -+ ; -+ interrupt-names = "ack", "err", "wakeup"; -+ -+ clocks = <&gcc RPM_MSG_RAM_H_CLK>; -+ clock-names = "ram"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rpmcc: clock-controller { -+ compatible = "qcom,rpmcc-ipq806x", "qcom,rpmcc"; -+ #clock-cells = <1>; -+ }; -+ -+ regulators { -+ compatible = "qcom,rpm-smb208-regulators"; -+ -+ smb208_s1a: s1a { -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1150000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ -+ smb208_s1b: s1b { -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1150000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ -+ smb208_s2a: s2a { -+ regulator-min-microvolt = < 800000>; -+ regulator-max-microvolt = <1250000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ -+ smb208_s2b: s2b { -+ regulator-min-microvolt = < 800000>; -+ regulator-max-microvolt = <1250000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ }; -+ }; -+ -+ rng@1a500000 { -+ compatible = "qcom,prng"; -+ reg = <0x1a500000 0x200>; -+ clocks = <&gcc PRNG_CLK>; -+ clock-names = "core"; -+ }; -+ - qcom_pinmux: pinmux@800000 { - compatible = "qcom,ipq8064-pinctrl"; - reg = <0x800000 0x4000>; -@@ -160,6 +589,15 @@ +@@ -384,6 +519,15 @@ }; }; @@ -491,35 +187,10 @@ spi_pins: spi_pins { mux { pins = "gpio18", "gpio19", "gpio21"; -@@ -169,6 +607,53 @@ +@@ -437,6 +581,27 @@ + bias-bus-hold; }; }; - -+ nand_pins: nand_pins { -+ disable { -+ pins = "gpio34", "gpio35", "gpio36", -+ "gpio37", "gpio38"; -+ function = "nand"; -+ drive-strength = <10>; -+ bias-disable; -+ }; -+ -+ pullups { -+ pins = "gpio39"; -+ function = "nand"; -+ drive-strength = <10>; -+ bias-pull-up; -+ }; -+ -+ hold { -+ pins = "gpio40", "gpio41", "gpio42", -+ "gpio43", "gpio44", "gpio45", -+ "gpio46", "gpio47"; -+ function = "nand"; -+ drive-strength = <10>; -+ bias-bus-hold; -+ }; -+ }; + + mdio0_pins: mdio0_pins { + mux { @@ -541,29 +212,10 @@ + bias-disable; + }; + }; -+ - leds_pins: leds_pins { - mux { - pins = "gpio7", "gpio8", "gpio9", -@@ -231,6 +716,17 @@ - clock-output-names = "acpu1_aux"; }; -+ l2cc: clock-controller@2011000 { -+ compatible = "qcom,kpss-gcc", "syscon"; -+ reg = <0x2011000 0x1000>; -+ clock-output-names = "acpu_l2_aux"; -+ }; -+ -+ kraitcc: clock-controller { -+ compatible = "qcom,krait-cc-v1"; -+ #clock-cells = <1>; -+ }; -+ - saw0: regulator@2089000 { - compatible = "qcom,saw2", "qcom,apq8064-saw2-v1.1-cpu", "syscon"; - reg = <0x02089000 0x1000>, <0x02009000 0x1000>; -@@ -243,6 +739,52 @@ + intc: interrupt-controller@2000000 { +@@ -513,6 +678,17 @@ regulator; }; @@ -577,46 +229,11 @@ + compatible = "syscon"; + reg = <0x12100000 0x10000>; + }; -+ -+ gsbi1: gsbi@12440000 { -+ compatible = "qcom,gsbi-v1.0.0"; -+ cell-index = <1>; -+ reg = <0x12440000 0x100>; -+ clocks = <&gcc GSBI1_H_CLK>; -+ clock-names = "iface"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ status = "disabled"; -+ -+ syscon-tcsr = <&tcsr>; -+ -+ gsbi1_serial: serial@12450000 { -+ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; -+ reg = <0x12450000 0x100>, -+ <0x12400000 0x03>; -+ interrupts = ; -+ clocks = <&gcc GSBI1_UART_CLK>, <&gcc GSBI1_H_CLK>; -+ clock-names = "core", "iface"; -+ status = "disabled"; -+ }; -+ -+ gsbi1_i2c: i2c@12460000 { -+ compatible = "qcom,i2c-qup-v1.1.1"; -+ reg = <0x12460000 0x1000>; -+ interrupts = ; -+ clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>; -+ clock-names = "core", "iface"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ }; + gsbi2: gsbi@12480000 { compatible = "qcom,gsbi-v1.0.0"; cell-index = <2>; -@@ -368,6 +910,33 @@ +@@ -568,6 +910,33 @@ }; }; @@ -650,7 +267,7 @@ gsbi7: gsbi@16600000 { status = "disabled"; compatible = "qcom,gsbi-v1.0.0"; -@@ -389,6 +958,19 @@ +@@ -589,6 +958,19 @@ clock-names = "core", "iface"; status = "disabled"; }; @@ -670,7 +287,37 @@ }; sata_phy: sata-phy@1b400000 { -@@ -478,6 +1060,95 @@ +@@ -761,6 +937,17 @@ + }; + }; + ++ L2: l2-cache { ++ compatible = "qcom,krait-cache", "cache"; ++ cache-level = <2>; ++ qcom,saw = <&saw_l2>; ++ ++ clocks = <&kraitcc 4>; ++ clock-names = "l2"; ++ l2-supply = <&smb208_s1a>; ++ operating-points-v2 = <&opp_table_l2>; ++ }; ++ + rpm: rpm@108000 { + compatible = "qcom,rpm-ipq8064"; + reg = <0x108000 0x1000>; +@@ -828,6 +1015,11 @@ + clock-output-names = "acpu_l2_aux"; + }; + ++ kraitcc: clock-controller { ++ compatible = "qcom,krait-cc-v1"; ++ #clock-cells = <1>; ++ }; ++ + lcc: clock-controller@28000000 { + compatible = "qcom,lcc-ipq8064"; + reg = <0x28000000 0x1000>; +@@ -835,6 +1027,11 @@ #reset-cells = <1>; }; @@ -678,136 +325,14 @@ + compatible = "syscon"; + reg = <0x01200600 0x100>; + }; -+ -+ hs_phy_0: hs_phy_0 { -+ compatible = "qcom,ipq806x-usb-phy-hs"; -+ reg = <0x110f8800 0x30>; -+ clocks = <&gcc USB30_0_UTMI_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ }; -+ -+ ss_phy_0: ss_phy_0 { -+ compatible = "qcom,ipq806x-usb-phy-ss"; -+ reg = <0x110f8830 0x30>; -+ clocks = <&gcc USB30_0_MASTER_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ }; -+ -+ usb3_0: usb3@110f8800 { -+ compatible = "qcom,dwc3", "syscon"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x110f8800 0x8000>; -+ clocks = <&gcc USB30_0_MASTER_CLK>; -+ clock-names = "core"; -+ -+ ranges; -+ -+ resets = <&gcc USB30_0_MASTER_RESET>; -+ reset-names = "master"; -+ -+ status = "disabled"; -+ -+ dwc3_0: dwc3@11000000 { -+ compatible = "snps,dwc3"; -+ reg = <0x11000000 0xcd00>; -+ interrupts = ; -+ phys = <&hs_phy_0>, <&ss_phy_0>; -+ phy-names = "usb2-phy", "usb3-phy"; -+ dr_mode = "host"; -+ snps,dis_u3_susphy_quirk; -+ }; -+ }; -+ -+ hs_phy_1: hs_phy_1 { -+ compatible = "qcom,ipq806x-usb-phy-hs"; -+ reg = <0x100f8800 0x30>; -+ clocks = <&gcc USB30_1_UTMI_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ }; -+ -+ ss_phy_1: ss_phy_1 { -+ compatible = "qcom,ipq806x-usb-phy-ss"; -+ reg = <0x100f8830 0x30>; -+ clocks = <&gcc USB30_1_MASTER_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ }; -+ -+ usb3_1: usb3@100f8800 { -+ compatible = "qcom,dwc3", "syscon"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ reg = <0x100f8800 0x8000>; -+ clocks = <&gcc USB30_1_MASTER_CLK>; -+ clock-names = "core"; -+ -+ ranges; -+ -+ resets = <&gcc USB30_1_MASTER_RESET>; -+ reset-names = "master"; -+ -+ status = "disabled"; -+ -+ dwc3_1: dwc3@10000000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10000000 0xcd00>; -+ interrupts = ; -+ phys = <&hs_phy_1>, <&ss_phy_1>; -+ phy-names = "usb2-phy", "usb3-phy"; -+ dr_mode = "host"; -+ snps,dis_u3_susphy_quirk; -+ }; -+ }; + pcie0: pci@1b500000 { compatible = "qcom,pcie-ipq8064"; reg = <0x1b500000 0x1000 -@@ -739,6 +1410,59 @@ - status = "disabled"; +@@ -1188,6 +1385,21 @@ + }; }; -+ adm_dma: dma@18300000 { -+ compatible = "qcom,adm"; -+ reg = <0x18300000 0x100000>; -+ interrupts = ; -+ #dma-cells = <1>; -+ -+ clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>; -+ clock-names = "core", "iface"; -+ -+ resets = <&gcc ADM0_RESET>, -+ <&gcc ADM0_PBUS_RESET>, -+ <&gcc ADM0_C0_RESET>, -+ <&gcc ADM0_C1_RESET>, -+ <&gcc ADM0_C2_RESET>; -+ reset-names = "clk", "pbus", "c0", "c1", "c2"; -+ qcom,ee = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ nand_controller: nand-controller@1ac00000 { -+ compatible = "qcom,ipq806x-nand"; -+ reg = <0x1ac00000 0x800>; -+ -+ clocks = <&gcc EBI2_CLK>, -+ <&gcc EBI2_AON_CLK>; -+ clock-names = "core", "aon"; -+ -+ dmas = <&adm_dma 3>; -+ dma-names = "rxtx"; -+ qcom,cmd-crci = <15>; -+ qcom,data-crci = <3>; -+ -+ status = "disabled"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; + + mdio0: mdio@37000000 { + #address-cells = <1>; @@ -826,7 +351,7 @@ vsdcc_fixed: vsdcc-regulator { compatible = "regulator-fixed"; regulator-name = "SDCC Power"; -@@ -814,4 +1538,17 @@ +@@ -1262,4 +1474,17 @@ }; }; }; diff --git a/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch b/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch index e5ea8e6393..44323a1561 100644 --- a/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch +++ b/target/linux/ipq806x/patches-5.15/084-ipq8064-v1.0-dtsi-cleanup.patch @@ -24,7 +24,7 @@ them differently anyway. }; @@ -64,64 +54,5 @@ ports-implemented = <0x1>; - status = "ok"; + status = "okay"; }; - - gpio_keys { diff --git a/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch b/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch index 747fa8c019..e4aefe171a 100644 --- a/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch +++ b/target/linux/ipq806x/patches-5.15/086-ipq8064-fix-duplicate-node.patch @@ -74,8 +74,8 @@ mdio1: mdio-1 { status = "okay"; compatible = "virtual,mdio-gpio"; -@@ -216,6 +149,68 @@ - }; +@@ -220,6 +153,68 @@ + status = "okay"; }; +&mdio0 { diff --git a/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch b/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch index 769686220b..f579b73b77 100644 --- a/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch +++ b/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch @@ -436,7 +436,7 @@ Signed-off-by: Ansuel Smith +} + +static struct cpufreq_driver krait_cpufreq_driver = { -+ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK | ++ .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | + CPUFREQ_IS_COOLING_DEV, + .verify = cpufreq_generic_frequency_table_verify, + .target_index = set_target, diff --git a/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch b/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch index 6106dfb8dc..f71b5cd4b0 100644 --- a/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch +++ b/target/linux/ipq806x/patches-5.15/099-1-mtd-nand-raw-qcom_nandc-add-boot_layout_mode-support.patch @@ -52,10 +52,10 @@ Signed-off-by: Ansuel Smith }; /* -@@ -460,12 +475,14 @@ struct qcom_nand_host { - * @ecc_modes - ecc mode for NAND +@@ -475,13 +490,15 @@ struct qcom_nand_host { * @is_bam - whether NAND controller is using BAM * @is_qpic - whether NAND CTRL is part of qpic IP + * @qpic_v2 - flag to indicate QPIC IP version 2 + * @has_boot_pages - whether NAND has different ecc settings for boot pages * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset */ @@ -63,6 +63,7 @@ Signed-off-by: Ansuel Smith u32 ecc_modes; bool is_bam; bool is_qpic; + bool qpic_v2; + bool has_boot_pages; u32 dev_cmd_reg_start; }; @@ -71,8 +72,8 @@ Signed-off-by: Ansuel Smith data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; -- if (cw == (ecc->steps - 1)) { -+ if (cw == (ecc->steps - 1) && !host->boot_pages_conf) { +- if (qcom_nandc_is_last_cw(ecc, cw)) { ++ if (qcom_nandc_is_last_cw(ecc, cw) && !host->boot_pages_conf) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) * 4); oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw + @@ -80,8 +81,8 @@ Signed-off-by: Ansuel Smith } for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { -- if (cw == (ecc->steps - 1)) { -+ if (cw == (ecc->steps - 1) && !host->boot_pages_conf) { +- if (qcom_nandc_is_last_cw(ecc, cw)) { ++ if (qcom_nandc_is_last_cw(ecc, cw) && !host->boot_pages_conf) { data_size = ecc->size - ((ecc->steps - 1) * 4); oob_size = (ecc->steps * 4) + host->ecc_bytes_hw; } else { @@ -89,8 +90,8 @@ Signed-off-by: Ansuel Smith for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; -- if (i == (ecc->steps - 1)) { -+ if (i == (ecc->steps - 1) && !host->boot_pages_conf) { +- if (qcom_nandc_is_last_cw(ecc, i)) { ++ if (qcom_nandc_is_last_cw(ecc, i) && !host->boot_pages_conf) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -169,8 +170,8 @@ Signed-off-by: Ansuel Smith for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; -- if (i == (ecc->steps - 1)) { -+ if (i == (ecc->steps - 1) && !host->boot_pages_conf) { +- if (qcom_nandc_is_last_cw(ecc, i)) { ++ if (qcom_nandc_is_last_cw(ecc, i) && !host->boot_pages_conf) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -188,8 +189,8 @@ Signed-off-by: Ansuel Smith data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; -- if (i == (ecc->steps - 1)) { -+ if (i == (ecc->steps - 1) && !host->boot_pages_conf) { +- if (qcom_nandc_is_last_cw(ecc, i)) { ++ if (qcom_nandc_is_last_cw(ecc, i) && !host->boot_pages_conf) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) << 2); oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + diff --git a/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch b/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch index 79036cb057..c4c7dc7d6a 100644 --- a/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch +++ b/target/linux/ipq806x/patches-5.15/099-2-Documentation-devicetree-mtd-qcom_nandc-document-qco.patch @@ -9,34 +9,32 @@ read/write confituation to boots partitions. Signed-off-by: Ansuel Smith --- - Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 11 +++++++++++ + Documentation/devicetree/bindings/mtd/qcom,nandc.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) ---- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt -+++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt -@@ -52,6 +52,15 @@ Optional properties: - be used according to chip requirement and available - OOB size. - -+EBI2 specific properties: -+- nand-is-boot-medium: nand contains boot partitions and different ecc configuration -+ should be used for these partitions. -+- qcom,boot_pages_size: should contain the size of the total boot partitions -+ where the boot layout read/write specific configuration -+ should be used. The boot layout is considered from the -+ start of the nand to the value set in this binding. -+ Only used in combination with 'nand-is-boot-medium'. +--- a/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml ++++ b/Documentation/devicetree/bindings/mtd/qcom,nandc.yaml +@@ -77,6 +77,14 @@ Optional properties: + description: + Must contain the ADM data type CRCI block instance number + specified for the NAND controller on the given platform + - Each nandcs device node may optionally contain a 'partitions' sub-node, which - further contains sub-nodes describing the flash partition mapping. See - partition.txt for more detail. -@@ -80,6 +89,9 @@ nand-controller@1ac00000 { - nand-ecc-strength = <4>; - nand-bus-width = <8>; ++ qcom,boot_pages_size: ++ description: ++ Should contain the size of the total boot partitions ++ where the boot layout read/write specific configuration ++ should be used. The boot layout is considered from the ++ start of the nand to the value set in this binding. ++ Only used in combination with 'nand-is-boot-medium'. -+ nand-is-boot-medium; -+ qcom,boot_pages_size: <0x58a0000>; + - if: + properties: +@@ -135,6 +135,9 @@ nand-controller@1ac00000 { + nand-ecc-strength = <4>; + nand-bus-width = <8>; + ++ nand-is-boot-medium; ++ qcom,boot_pages_size: <0x58a0000>; + - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; + partitions { + compatible = "fixed-partitions"; diff --git a/target/linux/ipq806x/patches-5.15/851-add-gsbi1-dts.patch b/target/linux/ipq806x/patches-5.15/851-add-gsbi1-dts.patch new file mode 100644 index 0000000000..b7c198c126 --- /dev/null +++ b/target/linux/ipq806x/patches-5.15/851-add-gsbi1-dts.patch @@ -0,0 +1,44 @@ +--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi +@@ -689,6 +689,41 @@ + reg = <0x12100000 0x10000>; + }; + ++ gsbi1: gsbi@12440000 { ++ compatible = "qcom,gsbi-v1.0.0"; ++ cell-index = <1>; ++ reg = <0x12440000 0x100>; ++ clocks = <&gcc GSBI1_H_CLK>; ++ clock-names = "iface"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ status = "disabled"; ++ ++ syscon-tcsr = <&tcsr>; ++ ++ gsbi1_serial: serial@12450000 { ++ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; ++ reg = <0x12450000 0x100>, ++ <0x12400000 0x03>; ++ interrupts = ; ++ clocks = <&gcc GSBI1_UART_CLK>, <&gcc GSBI1_H_CLK>; ++ clock-names = "core", "iface"; ++ status = "disabled"; ++ }; ++ ++ gsbi1_i2c: i2c@12460000 { ++ compatible = "qcom,i2c-qup-v1.1.1"; ++ reg = <0x12460000 0x1000>; ++ interrupts = ; ++ clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>; ++ clock-names = "core", "iface"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ }; ++ + gsbi2: gsbi@12480000 { + compatible = "qcom,gsbi-v1.0.0"; + cell-index = <2>; diff --git a/target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch b/target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch deleted file mode 100644 index dba917872c..0000000000 --- a/target/linux/ipq806x/patches-5.15/900-arm-add-cmdline-override.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -1794,6 +1794,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGL - - endchoice - -+config CMDLINE_OVERRIDE -+ bool "Use alternative cmdline from device tree" -+ help -+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can -+ be used, this is not a good option for kernels that are shared across -+ devices. This setting enables using "chosen/cmdline-override" as the -+ cmdline if it exists in the device tree. -+ - config CMDLINE - string "Default kernel command string" - default "" ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1059,6 +1059,17 @@ int __init early_init_dt_scan_chosen(uns - if (p != NULL && l > 0) - strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE)); - -+ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different -+ * device tree option of chosen/bootargs-override. This is -+ * helpful on boards where u-boot sets bootargs, and is unable -+ * to be modified. -+ */ -+#ifdef CONFIG_CMDLINE_OVERRIDE -+ p = of_get_flat_dt_prop(node, "bootargs-override", &l); -+ if (p != NULL && l > 0) -+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); -+#endif -+ - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else - * managed to set the command line, unless CONFIG_CMDLINE_FORCE From e86dfd0a44b8dece1bee04f34762888ce92732a4 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Sun, 16 Jan 2022 03:54:58 +0100 Subject: [PATCH 16/23] ipq806x: rework rootfs conflicts patch for smem Now that smem actually free the leaked parts, when a rootfs partition is detected, the kernel panics as it try to free the static space allocated for the "ubi" name. Change the logic and fix the name at the allocate_partition function to correctly free the space allocated by smem. Signed-off-by: Ansuel Smith --- ...conflicts-with-OpenWrt-auto-mounting.patch | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch b/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch index e83872935f..5055261c4b 100644 --- a/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch +++ b/target/linux/ipq806x/patches-5.15/102-mtd-rootfs-conflicts-with-OpenWrt-auto-mounting.patch @@ -5,20 +5,21 @@ Subject: [PATCH 61/69] mtd: "rootfs" conflicts with OpenWrt auto mounting Signed-off-by: John Crispin --- - drivers/mtd/parsers/qcomsmempart.c | 4 ++++ + drivers/mtd/mtdpart.c | 4 ++++ 1 file changed, 4 insertions(+) ---- a/drivers/mtd/parsers/qcomsmempart.c -+++ b/drivers/mtd/parsers/qcomsmempart.c -@@ -132,6 +132,11 @@ static int parse_qcomsmem_part(struct mt - parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize; - parts[i].mask_flags = pentry->attr; - parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize; -+ -+ /* "rootfs" conflicts with OpenWrt auto mounting */ -+ if (mtd_type_is_nand(mtd) && !strcmp(name, "rootfs")) -+ parts[i].name = "ubi"; -+ - pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n", - i, pentry->name, le32_to_cpu(pentry->offset), - le32_to_cpu(pentry->length), pentry->attr); +--- a/drivers/mtd/mtdpart.c ++++ b/drivers/mtd/mtdpart.c +@@ -139,7 +139,11 @@ + + /* allocate the partition structure */ + child = kzalloc(sizeof(*child), GFP_KERNEL); ++ /* "rootfs" conflicts with OpenWrt auto mounting */ ++ if (mtd_type_is_nand(parent) && !strcmp(part->name, "rootfs")) ++ name = "ubi"; ++ else ++ name = kstrdup(part->name, GFP_KERNEL); +- name = kstrdup(part->name, GFP_KERNEL); + if (!name || !child) { + printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n", + parent->name); From af70a27b38f12464ca840940de623918913cf0e6 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Thu, 4 Nov 2021 22:37:23 +0100 Subject: [PATCH 17/23] ipq806x: backport nand raname to kernel 5.10 Rename nand_controller to nand in kernel 5.10 to use the same dts across kernel version. Signed-off-by: Ansuel Smith --- .../linux/ipq806x/patches-5.10/083-ipq8064-dtsi-additions.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ipq806x/patches-5.10/083-ipq8064-dtsi-additions.patch b/target/linux/ipq806x/patches-5.10/083-ipq8064-dtsi-additions.patch index 2667bd636e..e74e6ad55d 100644 --- a/target/linux/ipq806x/patches-5.10/083-ipq8064-dtsi-additions.patch +++ b/target/linux/ipq806x/patches-5.10/083-ipq8064-dtsi-additions.patch @@ -790,7 +790,7 @@ + status = "disabled"; + }; + -+ nand_controller: nand-controller@1ac00000 { ++ nand: nand-controller@1ac00000 { + compatible = "qcom,ipq806x-nand"; + reg = <0x1ac00000 0x800>; + From 876a49ca621f7d7b73134f7bf93f301508e38354 Mon Sep 17 00:00:00 2001 From: Ansuel Smith Date: Fri, 5 Nov 2021 03:32:30 +0100 Subject: [PATCH 18/23] ipq806x: 5:15: fix dedicated krait cpufreq Fix dedicated cpufreq for kernel 5.15 as they changed module order and now it can happen that cpufreq probe after cache driver. Also add lock between cache scaling in set_target as it's now required by opp functions. Signed-off-by: Ansuel Smith --- ...q-add-Krait-dedicated-scaling-driver.patch | 76 +++++++++++++------ ...add-fab-scaling-support-with-cpufreq.patch | 8 +- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch b/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch index f579b73b77..da91eb5b7c 100644 --- a/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch +++ b/target/linux/ipq806x/patches-5.15/098-1-cpufreq-add-Krait-dedicated-scaling-driver.patch @@ -75,7 +75,7 @@ Signed-off-by: Ansuel Smith ################################################################################## --- /dev/null +++ b/drivers/cpufreq/qcom-cpufreq-krait.c -@@ -0,0 +1,603 @@ +@@ -0,0 +1,629 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -96,11 +96,13 @@ Signed-off-by: Ansuel Smith + +#include "cpufreq-dt.h" + -+static struct platform_device *l2_pdev; ++static struct device *l2_dev; ++static struct mutex lock; + +struct private_data { + struct opp_table *opp_table; + struct device *cpu_dev; ++ struct device *l2_dev; + const char *reg_name; + bool have_static_opps; +}; @@ -114,9 +116,11 @@ Signed-off-by: Ansuel Smith + unsigned int level; + int cpu, ret; + -+ if (l2_pdev) { ++ if (l2_dev) { + int policy_cpu = policy->cpu; + ++ mutex_lock(&lock); ++ + /* find the max freq across all core */ + for_each_present_cpu(cpu) + if (cpu != policy_cpu) @@ -127,9 +131,10 @@ Signed-off-by: Ansuel Smith + opp = dev_pm_opp_find_freq_exact(priv->cpu_dev, target_freq, + true); + if (IS_ERR(opp)) { -+ dev_err(&l2_pdev->dev, "failed to find OPP for %ld\n", ++ dev_err(l2_dev, "failed to find OPP for %ld\n", + target_freq); -+ return PTR_ERR(opp); ++ ret = PTR_ERR(opp); ++ goto l2_scale_fail; + } + level = dev_pm_opp_get_level(opp); + dev_pm_opp_put(opp); @@ -143,21 +148,25 @@ Signed-off-by: Ansuel Smith + */ + if (unlikely(index == 0 && level != 0)) { + dev_err(priv->cpu_dev, "Krait CPU can't operate at idle freq with L2 at 1GHz"); -+ return -EINVAL; ++ ret = -EINVAL; ++ goto l2_scale_fail; + } + -+ opp = dev_pm_opp_find_level_exact(&l2_pdev->dev, level); ++ opp = dev_pm_opp_find_level_exact(l2_dev, level); + if (IS_ERR(opp)) { -+ dev_err(&l2_pdev->dev, ++ dev_err(l2_dev, + "failed to find level OPP for %d\n", level); -+ return PTR_ERR(opp); ++ ret = PTR_ERR(opp); ++ goto l2_scale_fail; + } + target_freq = dev_pm_opp_get_freq(opp); + dev_pm_opp_put(opp); + -+ ret = dev_pm_opp_set_rate(&l2_pdev->dev, target_freq); ++ ret = dev_pm_opp_set_rate(l2_dev, target_freq); + if (ret) -+ return ret; ++ goto l2_scale_fail; ++ ++ mutex_unlock(&lock); + } + + ret = dev_pm_opp_set_rate(priv->cpu_dev, freq * 1000); @@ -168,6 +177,10 @@ Signed-off-by: Ansuel Smith + policy->cpuinfo.max_freq); + + return 0; ++l2_scale_fail: ++ mutex_unlock(&lock); ++ ++ return ret; +} + +/* @@ -346,7 +359,7 @@ Signed-off-by: Ansuel Smith + * give platform code chance to provide it for us. + */ + ret = dev_pm_opp_get_opp_count(cpu_dev); -+ if (ret <= 0) { ++ if (ret < 0) { + dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n"); + ret = -EPROBE_DEFER; + goto out_free_opp; @@ -549,6 +562,19 @@ Signed-off-by: Ansuel Smith + dev_pm_opp_put(opp); + + /* ++ * Check if we have at least opp-level 1, 0 should always be set to ++ * the idle freq ++ */ ++ opp = dev_pm_opp_find_level_exact(dev, 1); ++ if (IS_ERR(opp)) { ++ ret = PTR_ERR(opp); ++ dev_err(dev, ++ "Invalid configuration found of l2 opp. Can't find opp-level 1"); ++ goto invalid_conf; ++ } ++ dev_pm_opp_put(opp); ++ ++ /* + * Check opp-level configuration + * At least 2 level must be set or the cache will always be scaled + * the idle freq causing some performance problem @@ -561,17 +587,12 @@ Signed-off-by: Ansuel Smith + return -ENODEV; + } + -+ /* -+ * Check if we have at least opp-level 1, 0 should always be set to -+ * the idle freq -+ */ -+ opp = dev_pm_opp_find_level_exact(dev, 1); -+ if (IS_ERR(opp)) { -+ dev_err(dev, -+ "Invalid configuration found of l2 opp. Can't find opp-level 1"); ++ /* With opp error assume cpufreq still has to be registred. Defer probe. */ ++ ret = dev_pm_opp_get_opp_count(cpu_dev); ++ if (ret < 0) { ++ ret = -EPROBE_DEFER; + goto invalid_conf; + } -+ dev_pm_opp_put(opp); + + /* + * Check if we have at least opp-level 1 in the cpu opp, 0 should always @@ -579,16 +600,20 @@ Signed-off-by: Ansuel Smith + */ + opp = dev_pm_opp_find_level_exact(cpu_dev, 1); + if (IS_ERR(opp)) { -+ dev_err(dev, -+ "Invalid configuration found of cpu opp. Can't find opp-level 1"); ++ ret = PTR_ERR(opp); ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, ++ "Invalid configuration found of cpu opp. Can't find opp-level 1"); + goto invalid_conf; + } + dev_pm_opp_put(opp); + + platform_set_drvdata(pdev, data); + ++ mutex_init(&lock); ++ + /* The l2 scaling is enabled by linking the cpufreq driver */ -+ l2_pdev = pdev; ++ l2_dev = dev; + + return 0; + @@ -597,7 +622,7 @@ Signed-off-by: Ansuel Smith + dev_pm_opp_put_regulators(table); + dev_pm_opp_unregister_set_opp_helper(table); + -+ return -EINVAL; ++ return ret; +}; + +static int krait_cache_remove(struct platform_device *pdev) @@ -673,6 +698,7 @@ Signed-off-by: Ansuel Smith + .probe = krait_cpufreq_probe, + .remove = krait_cpufreq_remove, +}; ++ +module_platform_driver(krait_cpufreq_platdrv); + +MODULE_ALIAS("platform:krait-cpufreq"); diff --git a/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch b/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch index 8ce3f062cf..28eb22d269 100644 --- a/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch +++ b/target/linux/ipq806x/patches-5.15/098-3-add-fab-scaling-support-with-cpufreq.patch @@ -228,7 +228,7 @@ #include "cpufreq-dt.h" @@ -68,6 +69,13 @@ static int set_target(struct cpufreq_pol - return -EINVAL; + goto l2_scale_fail; } + /* @@ -236,8 +236,8 @@ + */ + ret = scale_fabrics(target_freq); + if (ret) -+ return ret; ++ goto l2_scale_fail; + - opp = dev_pm_opp_find_level_exact(&l2_pdev->dev, level); + opp = dev_pm_opp_find_level_exact(l2_dev, level); if (IS_ERR(opp)) { - dev_err(&l2_pdev->dev, + dev_err(l2_dev, From 9caa6f0aa742253901c72f43eebecd2c8da5f127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Mon, 21 Mar 2022 17:53:10 +0100 Subject: [PATCH 19/23] kernel: Backport mv88e6xxx patch to keep pvid at 0 if VLAN-unaware and remove hack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport patch 8b6836d82470 ("net: dsa: mv88e6xxx: keep the pvid at 0 when VLAN-unaware") from 5.15. Keeping the pvid at 0 when VLAN-unaware makes it possible to drop the hack introduced in commit 920eaab1d817 ("kernel: DSA roaming fix for Marvell mv88e6xxx"). Dropping the hack makes it possible to use VLAN interfaces with VID 1 on DSA ports without problems with FDB. Signed-off-by: Marek Behún --- ...x-keep-the-pvid-at-0-when-VLAN-unawa.patch | 236 ++++++++++++++++++ .../710-net-dsa-mv88e6xxx-default-VID-1.patch | 18 -- 2 files changed, 236 insertions(+), 18 deletions(-) create mode 100644 target/linux/generic/backport-5.10/774-v5.15-net-dsa-mv88e6xxx-keep-the-pvid-at-0-when-VLAN-unawa.patch delete mode 100644 target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch diff --git a/target/linux/generic/backport-5.10/774-v5.15-net-dsa-mv88e6xxx-keep-the-pvid-at-0-when-VLAN-unawa.patch b/target/linux/generic/backport-5.10/774-v5.15-net-dsa-mv88e6xxx-keep-the-pvid-at-0-when-VLAN-unawa.patch new file mode 100644 index 0000000000..c5b006493c --- /dev/null +++ b/target/linux/generic/backport-5.10/774-v5.15-net-dsa-mv88e6xxx-keep-the-pvid-at-0-when-VLAN-unawa.patch @@ -0,0 +1,236 @@ +From 675992be6f7b603b8cfda4678f173e1021fc1ab6 Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Thu, 7 Oct 2021 19:47:10 +0300 +Subject: [PATCH] net: dsa: mv88e6xxx: keep the pvid at 0 when VLAN-unaware + +The VLAN support in mv88e6xxx has a loaded history. Commit 2ea7a679ca2a +("net: dsa: Don't add vlans when vlan filtering is disabled") noticed +some issues with VLAN and decided the best way to deal with them was to +make the DSA core ignore VLANs added by the bridge while VLAN awareness +is turned off. Those issues were never explained, just presented as +"at least one corner case". + +That approach had problems of its own, presented by +commit 54a0ed0df496 ("net: dsa: provide an option for drivers to always +receive bridge VLANs") for the DSA core, followed by +commit 1fb74191988f ("net: dsa: mv88e6xxx: fix vlan setup") which +applied ds->configure_vlan_while_not_filtering = true for mv88e6xxx in +particular. + +We still don't know what corner case Andrew saw when he wrote +commit 2ea7a679ca2a ("net: dsa: Don't add vlans when vlan filtering is +disabled"), but Tobias now reports that when we use TX forwarding +offload, pinging an external station from the bridge device is broken if +the front-facing DSA user port has flooding turned off. The full +description is in the link below, but for short, when a mv88e6xxx port +is under a VLAN-unaware bridge, it inherits that bridge's pvid. +So packets ingressing a user port will be classified to e.g. VID 1 +(assuming that value for the bridge_default_pvid), whereas when +tag_dsa.c xmits towards a user port, it always sends packets using a VID +of 0 if that port is standalone or under a VLAN-unaware bridge - or at +least it did so prior to commit d82f8ab0d874 ("net: dsa: tag_dsa: +offload the bridge forwarding process"). + +In any case, when there is a conversation between the CPU and a station +connected to a user port, the station's MAC address is learned in VID 1 +but the CPU tries to transmit through VID 0. The packets reach the +intended station, but via flooding and not by virtue of matching the +existing ATU entry. + +DSA has established (and enforced in other drivers: sja1105, felix, +mt7530) that a VLAN-unaware port should use a private pvid, and not +inherit the one from the bridge. The bridge's pvid should only be +inherited when that bridge is VLAN-aware, so all state transitions need +to be handled. On the other hand, all bridge VLANs should sit in the VTU +starting with the moment when the bridge offloads them via switchdev, +they are just not used. + +This solves the problem that Tobias sees because packets ingressing on +VLAN-unaware user ports now get classified to VID 0, which is also the +VID used by tag_dsa.c on xmit. + +Fixes: d82f8ab0d874 ("net: dsa: tag_dsa: offload the bridge forwarding process") +Link: https://patchwork.kernel.org/project/netdevbpf/patch/20211003222312.284175-2-vladimir.oltean@nxp.com/#24491503 +Reported-by: Tobias Waldekranz +Signed-off-by: Vladimir Oltean +Signed-off-by: Jakub Kicinski +--- + drivers/net/dsa/mv88e6xxx/chip.c | 56 +++++++++++++++++++++++++++++--- + drivers/net/dsa/mv88e6xxx/chip.h | 6 ++++ + drivers/net/dsa/mv88e6xxx/port.c | 21 ++++++++++++ + drivers/net/dsa/mv88e6xxx/port.h | 2 ++ + 4 files changed, 81 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c +index 1992be77522a..a77c86e0321d 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.c ++++ b/drivers/net/dsa/mv88e6xxx/chip.c +@@ -1586,6 +1586,26 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, + return 0; + } + ++static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port) ++{ ++ struct dsa_port *dp = dsa_to_port(chip->ds, port); ++ struct mv88e6xxx_port *p = &chip->ports[port]; ++ bool drop_untagged = false; ++ u16 pvid = 0; ++ int err; ++ ++ if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev)) { ++ pvid = p->bridge_pvid.vid; ++ drop_untagged = !p->bridge_pvid.valid; ++ } ++ ++ err = mv88e6xxx_port_set_pvid(chip, port, pvid); ++ if (err) ++ return err; ++ ++ return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged); ++} ++ + static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, + bool vlan_filtering, + struct switchdev_trans *trans) +@@ -1599,7 +1619,16 @@ static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, + return chip->info->max_vid ? 0 : -EOPNOTSUPP; + + mv88e6xxx_reg_lock(chip); ++ + err = mv88e6xxx_port_set_8021q_mode(chip, port, mode); ++ if (err) ++ goto unlock; ++ ++ err = mv88e6xxx_port_commit_pvid(chip, port); ++ if (err) ++ goto unlock; ++ ++unlock: + mv88e6xxx_reg_unlock(chip); + + return err; +@@ -1982,8 +2011,10 @@ static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, + struct mv88e6xxx_chip *chip = ds->priv; + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; ++ struct mv88e6xxx_port *p = &chip->ports[port]; + bool warn; + u8 member; ++ int err; + u16 vid; + + if (!chip->info->max_vid) +@@ -2008,9 +2039,23 @@ static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, + dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port, + vid, untagged ? 'u' : 't'); + +- if (pvid && mv88e6xxx_port_set_pvid(chip, port, vlan->vid_end)) +- dev_err(ds->dev, "p%d: failed to set PVID %d\n", port, +- vlan->vid_end); ++ if (pvid) { ++ p->bridge_pvid.vid = vlan->vid_end; ++ p->bridge_pvid.valid = true; ++ ++ err = mv88e6xxx_port_commit_pvid(chip, port); ++ if (err) ++ dev_err(ds->dev, "p%d: failed to set PVID %d", port, ++ vlan->vid_end); ++ } else if (vlan->vid_end && p->bridge_pvid.vid == vlan->vid_end) { ++ /* The old pvid was reinstalled as a non-pvid VLAN */ ++ p->bridge_pvid.valid = false; ++ ++ err = mv88e6xxx_port_commit_pvid(chip, port); ++ if (err) ++ dev_err(ds->dev, "p%d: failed to unset PVID %d", port, ++ vlan->vid_end); ++ } + + mv88e6xxx_reg_unlock(chip); + } +@@ -2061,6 +2106,7 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) + { + struct mv88e6xxx_chip *chip = ds->priv; ++ struct mv88e6xxx_port *p = &chip->ports[port]; + u16 pvid, vid; + int err = 0; + +@@ -2079,7 +2125,9 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, + goto unlock; + + if (vid == pvid) { +- err = mv88e6xxx_port_set_pvid(chip, port, 0); ++ p->bridge_pvid.valid = false; ++ ++ err = mv88e6xxx_port_commit_pvid(chip, port); + if (err) + goto unlock; + } +diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h +index 51a7ff44478e..843803c3adf2 100644 +--- a/drivers/net/dsa/mv88e6xxx/chip.h ++++ b/drivers/net/dsa/mv88e6xxx/chip.h +@@ -224,9 +224,15 @@ struct mv88e6xxx_policy { + u16 vid; + }; + ++struct mv88e6xxx_vlan { ++ u16 vid; ++ bool valid; ++}; ++ + struct mv88e6xxx_port { + struct mv88e6xxx_chip *chip; + int port; ++ struct mv88e6xxx_vlan bridge_pvid; + u64 serdes_stats[2]; + u64 atu_member_violation; + u64 atu_miss_violation; +diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c +index dfd9e8292e9a..a7177aa254a8 100644 +--- a/drivers/net/dsa/mv88e6xxx/port.c ++++ b/drivers/net/dsa/mv88e6xxx/port.c +@@ -1062,6 +1062,27 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, + return 0; + } + ++int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port, ++ bool drop_untagged) ++{ ++ u16 old, new; ++ int err; ++ ++ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &old); ++ if (err) ++ return err; ++ ++ if (drop_untagged) ++ new = old | MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED; ++ else ++ new = old & ~MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED; ++ ++ if (new == old) ++ return 0; ++ ++ return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, new); ++} ++ + int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port) + { + u16 reg; +diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h +index 44d76ac973f6..3390517df42e 100644 +--- a/drivers/net/dsa/mv88e6xxx/port.h ++++ b/drivers/net/dsa/mv88e6xxx/port.h +@@ -364,6 +364,8 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, + phy_interface_t mode); + int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); + int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode); ++int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port, ++ bool drop_untagged); + int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port); + int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, + int upstream_port); +-- +2.34.1 + diff --git a/target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch b/target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch deleted file mode 100644 index 03725653f9..0000000000 --- a/target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -2097,6 +2097,7 @@ static int mv88e6xxx_port_fdb_add(struct - struct mv88e6xxx_chip *chip = ds->priv; - int err; - -+ vid = vid ? : 1; - mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, - MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC); -@@ -2111,6 +2112,7 @@ static int mv88e6xxx_port_fdb_del(struct - struct mv88e6xxx_chip *chip = ds->priv; - int err; - -+ vid = vid ? : 1; - mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0); - mv88e6xxx_reg_unlock(chip); From ac11f36b337da29f422d16776cf36c98013dcc77 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 27 Mar 2022 21:23:49 +0200 Subject: [PATCH 20/23] build: add support for passing C preprocessor flags for DTS builds Useful for adding #ifdefs based on build system provided definitions, or for adding extra include paths Signed-off-by: Felix Fietkau --- include/image.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/include/image.mk b/include/image.mk index 275a0adcac..e5b52d0e97 100644 --- a/include/image.mk +++ b/include/image.mk @@ -184,6 +184,7 @@ endef # $(4) extra DTC flags define Image/BuildDTB $(TARGET_CROSS)cpp -nostdinc -x assembler-with-cpp \ + $(DTS_CPPFLAGS) \ -I$(DTS_DIR) \ -I$(DTS_DIR)/include \ -I$(LINUX_DIR)/include/ \ From a3764ee29dd09394fa750c78160e300d86532561 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 27 Mar 2022 21:26:31 +0200 Subject: [PATCH 21/23] ramips: add linux 5.15 support for mt7621 Signed-off-by: Felix Fietkau --- target/linux/ramips/Makefile | 1 + target/linux/ramips/dts/mt7621.dtsi | 83 +- target/linux/ramips/image/mt7621.mk | 4 + target/linux/ramips/mt7621/config-5.15 | 315 ++++ ...ediaTek-MT7621-PCIe-host-controller-.patch | 1417 +++++++++++++++++ ...1-Rename-mt7621_pci_-to-mt7621_pcie_.patch | 134 ++ ...mt7621-Declare-mt7621_pci_ops-static.patch | 30 + ...MIPS-setup-to-pcibios_root_bridge_pr.patch | 119 ++ ...of_match_ptr-to-avoid-unused-variabl.patch | 35 + ...7621-Remove-unused-function-pcie_rmw.patch | 35 + ...root_bridge_prepare-access-bridge-wi.patch | 38 + .../110-reset_controller_driver.patch | 61 + .../patches-5.15/200-add-ralink-eth.patch | 20 + ...0-mt7620-export-chip-version-and-pkg.patch | 19 + ...e-to-enable-disable-the-cevt-r4k-irq.patch | 100 ++ ...IPS-ralink-add-cpu-frequency-scaling.patch | 195 +++ ...-MIPS-add-bootargs-override-property.patch | 63 + ...315-owrt-hack-fix-mt7688-cache-issue.patch | 28 + ...-select-illegal-access-driver-by-def.patch | 25 + ...ort-for-buggy-MT7621S-core-detection.patch | 74 + .../patches-5.15/324-mt7621-perfctr-fix.patch | 15 + ...mtd-cfi-cmdset-0002-force-word-write.patch | 20 + ...or-Add-support-for-BoHong-bh25q128as.patch | 75 + ...driver-support-for-MT7621-nand-flash.patch | 47 + ...documentation-for-mt7621-nand-driver.patch | 85 + ...ethernet-mediatek-support-net-labels.patch | 34 + .../ramips/patches-5.15/710-at803x.patch | 184 +++ ...y-simplify-phy_link_change-arguments.patch | 118 ++ .../721-NET-no-auto-carrier-off-support.patch | 47 + ...DT-Add-documentation-for-gpio-ralink.patch | 59 + ...alink-add-gpio-driver-for-ralink-SoC.patch | 416 +++++ ...support-for-GPIO-as-interrupt-contro.patch | 44 + .../patches-5.15/805-pinctrl-AW9523.patch | 72 + .../810-uvc-add-iPassion-iP2970-support.patch | 246 +++ ...-DT-Add-documentation-for-spi-rt2880.patch | 44 + ...SPI-ralink-add-Ralink-SoC-spi-driver.patch | 574 +++++++ .../825-i2c-MIPS-adds-ralink-I2C-driver.patch | 507 ++++++ ...IPS-ralink-add-sdhci-for-mt7620a-SoC.patch | 43 + .../835-asoc-add-mt7620-support.patch | 1029 ++++++++++++ ...erial-add-ugly-custom-baud-rate-hack.patch | 22 + .../845-pwm-add-mediatek-support.patch | 217 +++ .../850-awake-rt305x-dwc2-controller.patch | 15 + .../patches-5.15/855-linkit_bootstrap.patch | 97 ++ 43 files changed, 6804 insertions(+), 2 deletions(-) create mode 100644 target/linux/ramips/mt7621/config-5.15 create mode 100644 target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch create mode 100644 target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch create mode 100644 target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch create mode 100644 target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch create mode 100644 target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch create mode 100644 target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch create mode 100644 target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch create mode 100644 target/linux/ramips/patches-5.15/110-reset_controller_driver.patch create mode 100644 target/linux/ramips/patches-5.15/200-add-ralink-eth.patch create mode 100644 target/linux/ramips/patches-5.15/300-mt7620-export-chip-version-and-pkg.patch create mode 100644 target/linux/ramips/patches-5.15/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch create mode 100644 target/linux/ramips/patches-5.15/312-MIPS-ralink-add-cpu-frequency-scaling.patch create mode 100644 target/linux/ramips/patches-5.15/314-MIPS-add-bootargs-override-property.patch create mode 100644 target/linux/ramips/patches-5.15/315-owrt-hack-fix-mt7688-cache-issue.patch create mode 100644 target/linux/ramips/patches-5.15/316-arch-mips-do-not-select-illegal-access-driver-by-def.patch create mode 100644 target/linux/ramips/patches-5.15/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch create mode 100644 target/linux/ramips/patches-5.15/324-mt7621-perfctr-fix.patch create mode 100644 target/linux/ramips/patches-5.15/400-mtd-cfi-cmdset-0002-force-word-write.patch create mode 100644 target/linux/ramips/patches-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch create mode 100644 target/linux/ramips/patches-5.15/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch create mode 100644 target/linux/ramips/patches-5.15/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch create mode 100644 target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch create mode 100644 target/linux/ramips/patches-5.15/710-at803x.patch create mode 100644 target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch create mode 100644 target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch create mode 100644 target/linux/ramips/patches-5.15/801-DT-Add-documentation-for-gpio-ralink.patch create mode 100644 target/linux/ramips/patches-5.15/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch create mode 100644 target/linux/ramips/patches-5.15/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch create mode 100644 target/linux/ramips/patches-5.15/805-pinctrl-AW9523.patch create mode 100644 target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch create mode 100644 target/linux/ramips/patches-5.15/820-DT-Add-documentation-for-spi-rt2880.patch create mode 100644 target/linux/ramips/patches-5.15/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch create mode 100644 target/linux/ramips/patches-5.15/825-i2c-MIPS-adds-ralink-I2C-driver.patch create mode 100644 target/linux/ramips/patches-5.15/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch create mode 100644 target/linux/ramips/patches-5.15/835-asoc-add-mt7620-support.patch create mode 100644 target/linux/ramips/patches-5.15/840-serial-add-ugly-custom-baud-rate-hack.patch create mode 100644 target/linux/ramips/patches-5.15/845-pwm-add-mediatek-support.patch create mode 100644 target/linux/ramips/patches-5.15/850-awake-rt305x-dwc2-controller.patch create mode 100644 target/linux/ramips/patches-5.15/855-linkit_bootstrap.patch diff --git a/target/linux/ramips/Makefile b/target/linux/ramips/Makefile index c9fc1aa58a..7d34dfe676 100644 --- a/target/linux/ramips/Makefile +++ b/target/linux/ramips/Makefile @@ -11,6 +11,7 @@ SUBTARGETS:=mt7620 mt7621 mt76x8 rt288x rt305x rt3883 FEATURES:=squashfs gpio KERNEL_PATCHVER:=5.10 +KERNEL_TESTING_PATCHVER:=5.15 define Target/Description Build firmware images for Ralink RT288x/RT3xxx based boards. diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi index 09124072bd..3e86a7894a 100644 --- a/target/linux/ramips/dts/mt7621.dtsi +++ b/target/linux/ramips/dts/mt7621.dtsi @@ -41,12 +41,14 @@ bootargs = "console=ttyS0,57600"; }; +#ifdef DTS_LEGACY pll: pll { compatible = "mediatek,mt7621-pll", "syscon"; #clock-cells = <1>; clock-output-names = "cpu", "bus"; }; +#endif sysclock: sysclock { #clock-cells = <0>; @@ -65,7 +67,16 @@ #size-cells = <1>; sysc: syscon@0 { +#ifdef DTS_LEGACY compatible = "mtk,mt7621-sysc", "syscon"; +#else + compatible = "mediatek,mt7621-sysc", "syscon"; + #clock-cells = <1>; + ralink,memctl = <&memc>; + clock-output-names = "xtal", "cpu", "bus", + "50m", "125m", "150m", + "250m", "270m"; +#endif reg = <0x0 0x100>; }; @@ -79,6 +90,7 @@ #interrupt-cells = <2>; compatible = "mediatek,mt7621-gpio"; gpio-controller; + gpio-ranges = <&pinctrl 0 0 95>; interrupt-controller; reg = <0x600 0x100>; interrupt-parent = <&gic>; @@ -137,7 +149,11 @@ }; memc: syscon@5000 { +#ifdef DTS_LEGACY compatible = "mtk,mt7621-memc", "syscon"; +#else + compatible = "mediatek,mt7621-memc", "syscon"; +#endif reg = <0x5000 0x1000>; }; @@ -197,7 +213,11 @@ compatible = "ralink,mt7621-spi"; reg = <0xb00 0x100>; +#ifdef DTS_LEGACY clocks = <&pll MT7621_CLK_BUS>; +#else + clocks = <&sysc MT7621_CLK_BUS>; +#endif resets = <&rstctrl 18>; reset-names = "spi"; @@ -405,7 +425,11 @@ timer { compatible = "mti,gic-timer"; interrupts = ; +#ifdef DTS_LEGACY clocks = <&pll MT7621_CLK_CPU>; +#else + clocks = <&sysc MT7621_CLK_CPU>; +#endif }; }; @@ -442,13 +466,19 @@ compatible = "mediatek,mt7621-eth"; reg = <0x1e100000 0x10000>; +#ifdef DTS_LEGACY clocks = <&sysclock>; clock-names = "ethif"; +#else + clocks = <&sysc MT7621_CLK_FE>, + <&sysc MT7621_CLK_ETH>; + clock-names = "fe", "ethif"; +#endif #address-cells = <1>; #size-cells = <0>; - resets = <&rstctrl 6 &rstctrl 23>; + resets = <&rstctrl 6>, <&rstctrl 23>; reset-names = "fe", "eth"; interrupt-parent = <&gic>; @@ -456,8 +486,10 @@ mediatek,ethsys = <&sysc>; +#ifdef DTS_LEGACY pinctrl-names = "default"; pinctrl-0 = <&mdio_pins>, <&rgmii1_pins>, <&rgmii2_pins>; +#endif gmac0: mac@0 { compatible = "mediatek,eth-mac"; @@ -557,15 +589,22 @@ device_type = "pci"; +#ifdef DTS_LEGACY ranges = <0x02000000 0 0x00000000 0x60000000 0 0x10000000>, /* pci memory */ <0x01000000 0 0x00000000 0x1e160000 0 0x00010000>; /* io space */ +#else + ranges = <0x02000000 0 0x60000000 0x60000000 0 0x10000000>, /* pci memory */ + <0x01000000 0 0x00000000 0x1e160000 0 0x00010000>; /* io space */ +#endif + status = "disabled"; + +#ifdef DTS_LEGACY interrupt-parent = <&gic>; interrupts = ; - status = "disabled"; resets = <&rstctrl 24>, <&rstctrl 25>, <&rstctrl 26>; reset-names = "pcie0", "pcie1", "pcie2"; @@ -573,6 +612,13 @@ clock-names = "pcie0", "pcie1", "pcie2"; phys = <&pcie0_phy 1>, <&pcie2_phy 0>; phy-names = "pcie-phy0", "pcie-phy2"; +#else + #interrupt-cells = <1>; + interrupt-map-mask = <0xF800 0 0 0>; + interrupt-map = <0x0000 0 0 0 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, + <0x0800 0 0 0 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, + <0x1000 0 0 0 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; +#endif reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>; @@ -582,6 +628,15 @@ #size-cells = <2>; device_type = "pci"; ranges; +#ifndef DTS_LEGACY + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rstctrl 24>; + clocks = <&sysc MT7621_CLK_PCIE0>; + phys = <&pcie0_phy 1>; + phy-names = "pcie-phy0"; +#endif }; pcie1: pcie@1,0 { @@ -590,6 +645,15 @@ #size-cells = <2>; device_type = "pci"; ranges; +#ifndef DTS_LEGACY + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rstctrl 25>; + clocks = <&sysc MT7621_CLK_PCIE1>; + phys = <&pcie0_phy 1>; + phy-names = "pcie-phy1"; +#endif }; pcie2: pcie@2,0 { @@ -598,18 +662,33 @@ #size-cells = <2>; device_type = "pci"; ranges; +#ifndef DTS_LEGACY + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rstctrl 26>; + clocks = <&sysc MT7621_CLK_PCIE2>; + phys = <&pcie2_phy 0>; + phy-names = "pcie-phy2"; +#endif }; }; pcie0_phy: pcie-phy@1e149000 { compatible = "mediatek,mt7621-pci-phy"; reg = <0x1e149000 0x0700>; +#ifndef DTS_LEGACY + clocks = <&sysc MT7621_CLK_XTAL>; +#endif #phy-cells = <1>; }; pcie2_phy: pcie-phy@1e14a000 { compatible = "mediatek,mt7621-pci-phy"; reg = <0x1e14a000 0x0700>; +#ifndef DTS_LEGACY + clocks = <&sysc MT7621_CLK_XTAL>; +#endif #phy-cells = <1>; }; }; diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk index cd28e36917..1e9b59d74f 100644 --- a/target/linux/ramips/image/mt7621.mk +++ b/target/linux/ramips/image/mt7621.mk @@ -9,6 +9,10 @@ DEFAULT_SOC := mt7621 KERNEL_DTB += -d21 DEVICE_VARS += ELECOM_HWNAME LINKSYS_HWNAME +ifdef CONFIG_LINUX_5_10 + DTS_CPPFLAGS += -DDTS_LEGACY +endif + define Build/beeline-trx echo -ne "hsqs" > $@.hsqs $(STAGING_DIR_HOST)/bin/otrx create $@.trx -M 0x746f435d -f $@ \ diff --git a/target/linux/ramips/mt7621/config-5.15 b/target/linux/ramips/mt7621/config-5.15 new file mode 100644 index 0000000000..757d9acdcd --- /dev/null +++ b/target/linux/ramips/mt7621/config-5.15 @@ -0,0 +1,315 @@ +CONFIG_AF_UNIX_OOB=y +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MMAP_RND_BITS_MAX=15 +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 +CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_AT803X_PHY=y +CONFIG_BINARY_PRINTF=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BOARD_SCACHE=y +CONFIG_BOUNCE=y +CONFIG_CEVT_R4K=y +CONFIG_CLKSRC_MIPS_GIC=y +# CONFIG_CLKSRC_PISTACHIO is not set +CONFIG_CLK_MT7621=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CMDLINE="rootfstype=squashfs,jffs2" +CONFIG_CMDLINE_BOOL=y +# CONFIG_CMDLINE_OVERRIDE is not set +CONFIG_COMMON_CLK=y +# CONFIG_COMMON_CLK_BOSTON is not set +# CONFIG_COMMON_CLK_PISTACHIO is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CPU_GENERIC_DUMP_TLB=y +CONFIG_CPU_HAS_DIEI=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_RIXI=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_TEO=y +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_MIPSR2_IRQ_EI=y +CONFIG_CPU_MIPSR2_IRQ_VI=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_PM=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_RMAP=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRC16=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_CSRC_R4K=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DIMLIB=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_DTB_GNUBEE1 is not set +# CONFIG_DTB_GNUBEE2 is not set +CONFIG_DTB_RT_NONE=y +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_FIXED_PHY=y +CONFIG_FWNODE_MDIO=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_LIB_ASHLDI3=y +CONFIG_GENERIC_LIB_ASHRDI3=y +CONFIG_GENERIC_LIB_CMPDI2=y +CONFIG_GENERIC_LIB_LSHRDI3=y +CONFIG_GENERIC_LIB_UCMPDI2=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_MT7621=y +# CONFIG_GPIO_RALINK is not set +CONFIG_GPIO_WATCHDOG=y +# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HIGHMEM=y +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_MT7621=y +# CONFIG_INGENIC_CGU_JZ4760 is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_KMAP_LOCAL=y +CONFIG_LED_TRIGGER_PHY=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LTO_NONE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_MACH_NINTENDO64 is not set +# CONFIG_MACH_REALTEK_RTL is not set +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEDIATEK_GE_PHY=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MIKROTIK=y +CONFIG_MIKROTIK_RB_SYSFS=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +CONFIG_MIPS_CM=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_CPC=y +CONFIG_MIPS_CPS=y +CONFIG_MIPS_CPS_CPUIDLE=y +# CONFIG_MIPS_CPS_NS16550_BOOL is not set +CONFIG_MIPS_CPS_PM=y +CONFIG_MIPS_CPU_SCACHE=y +CONFIG_MIPS_EBPF_JIT=y +# CONFIG_MIPS_ELF_APPENDED_DTB is not set +CONFIG_MIPS_GIC=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_LD_CAN_LINK_VDSO=y +CONFIG_MIPS_MT=y +CONFIG_MIPS_MT_FPAFF=y +CONFIG_MIPS_MT_SMP=y +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_NR_CPU_NR_MAP=4 +CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MIPS_SPRAM=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MT7621_WDT=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_NAND_MT7621=y +CONFIG_MTD_NAND_MTK_BMT=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_ROUTERBOOT_PARTS=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_SPLIT_MINOR_FW=y +CONFIG_MTD_SPLIT_SEAMA_FW=y +CONFIG_MTD_SPLIT_TPLINK_FW=y +CONFIG_MTD_SPLIT_TRX_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_VIRT_CONCAT=y +# CONFIG_MTK_HSDMA is not set +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MT7530=y +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NET_VENDOR_MEDIATEK=y +# CONFIG_NET_VENDOR_RALINK is not set +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NR_CPUS=4 +CONFIG_NVMEM=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_PADATA=y +CONFIG_PCI=y +CONFIG_PCIE_MT7621=y +CONFIG_PCI_DISABLE_COMMON_QUIRKS=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_DRIVERS_GENERIC=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +# CONFIG_PHY_INGENIC_USB is not set +CONFIG_PHY_MT7621_PCI=y +# CONFIG_PHY_PISTACHIO_USB is not set +# CONFIG_PHY_RALINK_USB is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_AW9523=y +CONFIG_PINCTRL_MT7621=y +# CONFIG_PINCTRL_PISTACHIO is not set +CONFIG_PINCTRL_RALINK=y +CONFIG_PINCTRL_RT2880=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_SX150X=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_SUPPLY=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_QUEUED_RWLOCKS=y +CONFIG_QUEUED_SPINLOCKS=y +CONFIG_RALINK=y +# CONFIG_RALINK_WDT is not set +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RFS_ACCEL=y +CONFIG_RPS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_BQ32K=y +CONFIG_RTC_DRV_PCF8563=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +# CONFIG_SCHED_CORE is not set +CONFIG_SCHED_SMT=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SGL_ALLOC=y +CONFIG_SMP=y +CONFIG_SMP_UP=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y +CONFIG_SOC_BUS=y +# CONFIG_SOC_MT7620 is not set +CONFIG_SOC_MT7621=y +# CONFIG_SOC_RT288X is not set +# CONFIG_SOC_RT305X is not set +# CONFIG_SOC_RT3883 is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_MT7621=y +# CONFIG_SPI_RT2880 is not set +CONFIG_SRCU=y +CONFIG_SWPHY=y +CONFIG_SYNC_R4K=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_SYS_SUPPORTS_MIPS_CPS=y +CONFIG_SYS_SUPPORTS_MULTITHREADING=y +CONFIG_SYS_SUPPORTS_SCHED_SMT=y +CONFIG_SYS_SUPPORTS_SMP=y +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_TARGET_ISA_REV=2 +# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TREE_RCU=y +CONFIG_TREE_SRCU=y +CONFIG_UBIFS_FS=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_WATCHDOG_CORE=y +CONFIG_WEAK_ORDERING=y +CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch b/target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch new file mode 100644 index 0000000000..5aa69421b9 --- /dev/null +++ b/target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch @@ -0,0 +1,1417 @@ +From: Sergio Paracuellos +Date: Wed, 22 Sep 2021 07:00:34 +0200 +Subject: [PATCH] PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver + +Add driver for the PCIe controller of the MT7621 SoC. + +[bhelgaas: rename from pci-mt7621.c to pcie-mt7621.c; also rename Kconfig +symbol from PCI_MT7621 to PCIE_MT7621] +Link: https://lore.kernel.org/r/20210922050035.18162-3-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Acked-by: Greg Kroah-Hartman +--- + rename drivers/{staging/mt7621-pci/pci-mt7621.c => pci/controller/pcie-mt7621.c} (95%) + delete mode 100644 drivers/staging/mt7621-pci/Kconfig + delete mode 100644 drivers/staging/mt7621-pci/Makefile + delete mode 100644 drivers/staging/mt7621-pci/TODO + delete mode 100644 drivers/staging/mt7621-pci/mediatek,mt7621-pci.txt + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -51,7 +51,8 @@ choice + select SYS_SUPPORTS_HIGHMEM + select MIPS_GIC + select CLKSRC_MIPS_GIC +- select HAVE_PCI if PCI_MT7621 ++ select HAVE_PCI ++ select PCI_DRIVERS_GENERIC + select SOC_BUS + endchoice + +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -312,6 +312,14 @@ config PCIE_HISI_ERR + Say Y here if you want error handling support + for the PCIe controller's errors on HiSilicon HIP SoCs + ++config PCIE_MT7621 ++ tristate "MediaTek MT7621 PCIe Controller" ++ depends on (RALINK && SOC_MT7621) || (MIPS && COMPILE_TEST) ++ select PHY_MT7621_PCI ++ default SOC_MT7621 ++ help ++ This selects a driver for the MediaTek MT7621 PCIe Controller. ++ + source "drivers/pci/controller/dwc/Kconfig" + source "drivers/pci/controller/mobiveil/Kconfig" + source "drivers/pci/controller/cadence/Kconfig" +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -37,6 +37,8 @@ obj-$(CONFIG_VMD) += vmd.o + obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o + obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o + obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o ++obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o ++ + # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW + obj-y += dwc/ + obj-y += mobiveil/ +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -86,8 +86,6 @@ source "drivers/staging/vc04_services/Kc + + source "drivers/staging/pi433/Kconfig" + +-source "drivers/staging/mt7621-pci/Kconfig" +- + source "drivers/staging/mt7621-dma/Kconfig" + + source "drivers/staging/ralink-gdma/Kconfig" +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -33,7 +33,6 @@ obj-$(CONFIG_KS7010) += ks7010/ + obj-$(CONFIG_GREYBUS) += greybus/ + obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ + obj-$(CONFIG_PI433) += pi433/ +-obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ + obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ + obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ + obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ +--- a/drivers/staging/mt7621-pci/Kconfig ++++ /dev/null +@@ -1,8 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-config PCI_MT7621 +- tristate "MediaTek MT7621 PCI Controller" +- depends on RALINK +- select PCI_DRIVERS_GENERIC +- help +- This selects a driver for the MediaTek MT7621 PCI Controller. +- +--- a/drivers/staging/mt7621-pci/Makefile ++++ /dev/null +@@ -1,2 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_PCI_MT7621) += pci-mt7621.o +--- a/drivers/staging/mt7621-pci/TODO ++++ /dev/null +@@ -1,4 +0,0 @@ +- +-- general code review and cleanup +- +-Cc: NeilBrown +--- a/drivers/staging/mt7621-pci/mediatek,mt7621-pci.txt ++++ /dev/null +@@ -1,104 +0,0 @@ +-MediaTek MT7621 PCIe controller +- +-Required properties: +-- compatible: "mediatek,mt7621-pci" +-- device_type: Must be "pci" +-- reg: Base addresses and lengths of the PCIe subsys and root ports. +-- bus-range: Range of bus numbers associated with this controller. +-- #address-cells: Address representation for root ports (must be 3) +-- pinctrl-names : The pin control state names. +-- pinctrl-0: The "default" pinctrl state. +-- #size-cells: Size representation for root ports (must be 2) +-- ranges: Ranges for the PCI memory and I/O regions. +-- #interrupt-cells: Must be 1 +-- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties. +- Please refer to the standard PCI bus binding document for a more detailed +- explanation. +-- status: either "disabled" or "okay". +-- resets: Must contain an entry for each entry in reset-names. +- See ../reset/reset.txt for details. +-- reset-names: Must be "pcie0", "pcie1", "pcieN"... based on the number of +- root ports. +-- clocks: Must contain an entry for each entry in clock-names. +- See ../clocks/clock-bindings.txt for details. +-- clock-names: Must be "pcie0", "pcie1", "pcieN"... based on the number of +- root ports. +-- reset-gpios: GPIO specs for the reset pins. +- +-In addition, the device tree node must have sub-nodes describing each PCIe port +-interface, having the following mandatory properties: +- +-Required properties: +-- reg: Only the first four bytes are used to refer to the correct bus number +- and device number. +-- #address-cells: Must be 3 +-- #size-cells: Must be 2 +-- ranges: Sub-ranges distributed from the PCIe controller node. An empty +- property is sufficient. +-- bus-range: Range of bus numbers associated with this port. +- +-Example for MT7621: +- +- pcie: pcie@1e140000 { +- compatible = "mediatek,mt7621-pci"; +- reg = <0x1e140000 0x100 /* host-pci bridge registers */ +- 0x1e142000 0x100 /* pcie port 0 RC control registers */ +- 0x1e143000 0x100 /* pcie port 1 RC control registers */ +- 0x1e144000 0x100>; /* pcie port 2 RC control registers */ +- +- #address-cells = <3>; +- #size-cells = <2>; +- +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie_pins>; +- +- device_type = "pci"; +- +- bus-range = <0 255>; +- ranges = < +- 0x02000000 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */ +- 0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */ +- >; +- +- #interrupt-cells = <1>; +- interrupt-map-mask = <0xF0000 0 0 1>; +- interrupt-map = <0x10000 0 0 1 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, +- <0x20000 0 0 1 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, +- <0x30000 0 0 1 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; +- +- status = "disabled"; +- +- resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>; +- reset-names = "pcie0", "pcie1", "pcie2"; +- clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>; +- clock-names = "pcie0", "pcie1", "pcie2"; +- +- reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>, +- <&gpio 8 GPIO_ACTIVE_LOW>, +- <&gpio 7 GPIO_ACTIVE_LOW>; +- +- pcie@0,0 { +- reg = <0x0000 0 0 0 0>; +- #address-cells = <3>; +- #size-cells = <2>; +- ranges; +- bus-range = <0x00 0xff>; +- }; +- +- pcie@1,0 { +- reg = <0x0800 0 0 0 0>; +- #address-cells = <3>; +- #size-cells = <2>; +- ranges; +- bus-range = <0x00 0xff>; +- }; +- +- pcie@2,0 { +- reg = <0x1000 0 0 0 0>; +- #address-cells = <3>; +- #size-cells = <2>; +- ranges; +- bus-range = <0x00 0xff>; +- }; +- }; +- +--- a/drivers/staging/mt7621-pci/pci-mt7621.c ++++ /dev/null +@@ -1,600 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * BRIEF MODULE DESCRIPTION +- * PCI init for Ralink RT2880 solution +- * +- * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) +- * +- * May 2007 Bruce Chang +- * Initial Release +- * +- * May 2009 Bruce Chang +- * support RT2880/RT3883 PCIe +- * +- * May 2011 Bruce Chang +- * support RT6855/MT7620 PCIe +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* MediaTek specific configuration registers */ +-#define PCIE_FTS_NUM 0x70c +-#define PCIE_FTS_NUM_MASK GENMASK(15, 8) +-#define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) +- +-/* Host-PCI bridge registers */ +-#define RALINK_PCI_PCICFG_ADDR 0x0000 +-#define RALINK_PCI_PCIMSK_ADDR 0x000C +-#define RALINK_PCI_CONFIG_ADDR 0x0020 +-#define RALINK_PCI_CONFIG_DATA 0x0024 +-#define RALINK_PCI_MEMBASE 0x0028 +-#define RALINK_PCI_IOBASE 0x002C +- +-/* PCIe RC control registers */ +-#define RALINK_PCI_ID 0x0030 +-#define RALINK_PCI_CLASS 0x0034 +-#define RALINK_PCI_SUBID 0x0038 +-#define RALINK_PCI_STATUS 0x0050 +- +-/* Some definition values */ +-#define PCIE_REVISION_ID BIT(0) +-#define PCIE_CLASS_CODE (0x60400 << 8) +-#define PCIE_BAR_MAP_MAX GENMASK(30, 16) +-#define PCIE_BAR_ENABLE BIT(0) +-#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) +-#define PCIE_PORT_LINKUP BIT(0) +-#define PCIE_PORT_CNT 3 +- +-#define PERST_DELAY_MS 100 +- +-/** +- * struct mt7621_pcie_port - PCIe port information +- * @base: I/O mapped register base +- * @list: port list +- * @pcie: pointer to PCIe host info +- * @clk: pointer to the port clock gate +- * @phy: pointer to PHY control block +- * @pcie_rst: pointer to port reset control +- * @gpio_rst: gpio reset +- * @slot: port slot +- * @enabled: indicates if port is enabled +- */ +-struct mt7621_pcie_port { +- void __iomem *base; +- struct list_head list; +- struct mt7621_pcie *pcie; +- struct clk *clk; +- struct phy *phy; +- struct reset_control *pcie_rst; +- struct gpio_desc *gpio_rst; +- u32 slot; +- bool enabled; +-}; +- +-/** +- * struct mt7621_pcie - PCIe host information +- * @base: IO Mapped Register Base +- * @dev: Pointer to PCIe device +- * @ports: pointer to PCIe port information +- * @resets_inverted: depends on chip revision +- * reset lines are inverted. +- */ +-struct mt7621_pcie { +- void __iomem *base; +- struct device *dev; +- struct list_head ports; +- bool resets_inverted; +-}; +- +-static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) +-{ +- return readl_relaxed(pcie->base + reg); +-} +- +-static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) +-{ +- writel_relaxed(val, pcie->base + reg); +-} +- +-static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) +-{ +- u32 val = readl_relaxed(pcie->base + reg); +- +- val &= ~clr; +- val |= set; +- writel_relaxed(val, pcie->base + reg); +-} +- +-static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) +-{ +- return readl_relaxed(port->base + reg); +-} +- +-static inline void pcie_port_write(struct mt7621_pcie_port *port, +- u32 val, u32 reg) +-{ +- writel_relaxed(val, port->base + reg); +-} +- +-static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, +- unsigned int func, unsigned int where) +-{ +- return (((where & 0xF00) >> 8) << 24) | (bus << 16) | (slot << 11) | +- (func << 8) | (where & 0xfc) | 0x80000000; +-} +- +-static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, +- unsigned int devfn, int where) +-{ +- struct mt7621_pcie *pcie = bus->sysdata; +- u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), +- PCI_FUNC(devfn), where); +- +- writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); +- +- return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); +-} +- +-struct pci_ops mt7621_pci_ops = { +- .map_bus = mt7621_pcie_map_bus, +- .read = pci_generic_config_read, +- .write = pci_generic_config_write, +-}; +- +-static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) +-{ +- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); +- +- pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); +- return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); +-} +- +-static void write_config(struct mt7621_pcie *pcie, unsigned int dev, +- u32 reg, u32 val) +-{ +- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); +- +- pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); +- pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); +-} +- +-static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) +-{ +- if (port->gpio_rst) +- gpiod_set_value(port->gpio_rst, 1); +-} +- +-static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) +-{ +- if (port->gpio_rst) +- gpiod_set_value(port->gpio_rst, 0); +-} +- +-static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) +-{ +- return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; +-} +- +-static inline void mt7621_control_assert(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- +- if (pcie->resets_inverted) +- reset_control_assert(port->pcie_rst); +- else +- reset_control_deassert(port->pcie_rst); +-} +- +-static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- +- if (pcie->resets_inverted) +- reset_control_deassert(port->pcie_rst); +- else +- reset_control_assert(port->pcie_rst); +-} +- +-static int setup_cm_memory_region(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- struct device *dev = pcie->dev; +- struct resource_entry *entry; +- resource_size_t mask; +- +- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); +- if (!entry) { +- dev_err(dev, "Cannot get memory resource\n"); +- return -EINVAL; +- } +- +- if (mips_cps_numiocu(0)) { +- /* +- * FIXME: hardware doesn't accept mask values with 1s after +- * 0s (e.g. 0xffef), so it would be great to warn if that's +- * about to happen +- */ +- mask = ~(entry->res->end - entry->res->start); +- +- write_gcr_reg1_base(entry->res->start); +- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); +- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", +- (unsigned long long)read_gcr_reg1_base(), +- (unsigned long long)read_gcr_reg1_mask()); +- } +- +- return 0; +-} +- +-static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, +- struct device_node *node, +- int slot) +-{ +- struct mt7621_pcie_port *port; +- struct device *dev = pcie->dev; +- struct platform_device *pdev = to_platform_device(dev); +- char name[10]; +- int err; +- +- port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); +- if (!port) +- return -ENOMEM; +- +- port->base = devm_platform_ioremap_resource(pdev, slot + 1); +- if (IS_ERR(port->base)) +- return PTR_ERR(port->base); +- +- port->clk = devm_get_clk_from_child(dev, node, NULL); +- if (IS_ERR(port->clk)) { +- dev_err(dev, "failed to get pcie%d clock\n", slot); +- return PTR_ERR(port->clk); +- } +- +- port->pcie_rst = of_reset_control_get_exclusive(node, NULL); +- if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { +- dev_err(dev, "failed to get pcie%d reset control\n", slot); +- return PTR_ERR(port->pcie_rst); +- } +- +- snprintf(name, sizeof(name), "pcie-phy%d", slot); +- port->phy = devm_of_phy_get(dev, node, name); +- if (IS_ERR(port->phy)) { +- dev_err(dev, "failed to get pcie-phy%d\n", slot); +- err = PTR_ERR(port->phy); +- goto remove_reset; +- } +- +- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, +- GPIOD_OUT_LOW); +- if (IS_ERR(port->gpio_rst)) { +- dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot); +- err = PTR_ERR(port->gpio_rst); +- goto remove_reset; +- } +- +- port->slot = slot; +- port->pcie = pcie; +- +- INIT_LIST_HEAD(&port->list); +- list_add_tail(&port->list, &pcie->ports); +- +- return 0; +- +-remove_reset: +- reset_control_put(port->pcie_rst); +- return err; +-} +- +-static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) +-{ +- struct device *dev = pcie->dev; +- struct platform_device *pdev = to_platform_device(dev); +- struct device_node *node = dev->of_node, *child; +- int err; +- +- pcie->base = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(pcie->base)) +- return PTR_ERR(pcie->base); +- +- for_each_available_child_of_node(node, child) { +- int slot; +- +- err = of_pci_get_devfn(child); +- if (err < 0) { +- of_node_put(child); +- dev_err(dev, "failed to parse devfn: %d\n", err); +- return err; +- } +- +- slot = PCI_SLOT(err); +- +- err = mt7621_pcie_parse_port(pcie, child, slot); +- if (err) { +- of_node_put(child); +- return err; +- } +- } +- +- return 0; +-} +- +-static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- struct device *dev = pcie->dev; +- u32 slot = port->slot; +- int err; +- +- err = phy_init(port->phy); +- if (err) { +- dev_err(dev, "failed to initialize port%d phy\n", slot); +- return err; +- } +- +- err = phy_power_on(port->phy); +- if (err) { +- dev_err(dev, "failed to power on port%d phy\n", slot); +- phy_exit(port->phy); +- return err; +- } +- +- port->enabled = true; +- +- return 0; +-} +- +-static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) +-{ +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) { +- /* PCIe RC reset assert */ +- mt7621_control_assert(port); +- +- /* PCIe EP reset assert */ +- mt7621_rst_gpio_pcie_assert(port); +- } +- +- msleep(PERST_DELAY_MS); +-} +- +-static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) +-{ +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) +- mt7621_control_deassert(port); +-} +- +-static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) +-{ +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) +- mt7621_rst_gpio_pcie_deassert(port); +- +- msleep(PERST_DELAY_MS); +-} +- +-static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) +-{ +- struct device *dev = pcie->dev; +- struct mt7621_pcie_port *port, *tmp; +- u8 num_disabled = 0; +- int err; +- +- mt7621_pcie_reset_assert(pcie); +- mt7621_pcie_reset_rc_deassert(pcie); +- +- list_for_each_entry_safe(port, tmp, &pcie->ports, list) { +- u32 slot = port->slot; +- +- if (slot == 1) { +- port->enabled = true; +- continue; +- } +- +- err = mt7621_pcie_init_port(port); +- if (err) { +- dev_err(dev, "Initiating port %d failed\n", slot); +- list_del(&port->list); +- } +- } +- +- mt7621_pcie_reset_ep_deassert(pcie); +- +- tmp = NULL; +- list_for_each_entry(port, &pcie->ports, list) { +- u32 slot = port->slot; +- +- if (!mt7621_pcie_port_is_linkup(port)) { +- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", +- slot); +- mt7621_control_assert(port); +- port->enabled = false; +- num_disabled++; +- +- if (slot == 0) { +- tmp = port; +- continue; +- } +- +- if (slot == 1 && tmp && !tmp->enabled) +- phy_power_off(tmp->phy); +- } +- } +- +- return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; +-} +- +-static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- u32 slot = port->slot; +- u32 val; +- +- /* enable pcie interrupt */ +- val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); +- val |= PCIE_PORT_INT_EN(slot); +- pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); +- +- /* map 2G DDR region */ +- pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, +- PCI_BASE_ADDRESS_0); +- +- /* configure class code and revision ID */ +- pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, +- RALINK_PCI_CLASS); +- +- /* configure RC FTS number to 250 when it leaves L0s */ +- val = read_config(pcie, slot, PCIE_FTS_NUM); +- val &= ~PCIE_FTS_NUM_MASK; +- val |= PCIE_FTS_NUM_L0(0x50); +- write_config(pcie, slot, PCIE_FTS_NUM, val); +-} +- +-static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- struct device *dev = pcie->dev; +- struct mt7621_pcie_port *port; +- struct resource_entry *entry; +- int err; +- +- entry = resource_list_first_type(&host->windows, IORESOURCE_IO); +- if (!entry) { +- dev_err(dev, "Cannot get io resource\n"); +- return -EINVAL; +- } +- +- /* Setup MEMWIN and IOWIN */ +- pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); +- pcie_write(pcie, entry->res->start, RALINK_PCI_IOBASE); +- +- list_for_each_entry(port, &pcie->ports, list) { +- if (port->enabled) { +- err = clk_prepare_enable(port->clk); +- if (err) { +- dev_err(dev, "enabling clk pcie%d\n", +- port->slot); +- return err; +- } +- +- mt7621_pcie_enable_port(port); +- dev_info(dev, "PCIE%d enabled\n", port->slot); +- } +- } +- +- return 0; +-} +- +-static int mt7621_pcie_register_host(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- +- host->ops = &mt7621_pci_ops; +- host->sysdata = pcie; +- return pci_host_probe(host); +-} +- +-static const struct soc_device_attribute mt7621_pci_quirks_match[] = { +- { .soc_id = "mt7621", .revision = "E2" } +-}; +- +-static int mt7621_pci_probe(struct platform_device *pdev) +-{ +- struct device *dev = &pdev->dev; +- const struct soc_device_attribute *attr; +- struct mt7621_pcie_port *port; +- struct mt7621_pcie *pcie; +- struct pci_host_bridge *bridge; +- int err; +- +- if (!dev->of_node) +- return -ENODEV; +- +- bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); +- if (!bridge) +- return -ENOMEM; +- +- pcie = pci_host_bridge_priv(bridge); +- pcie->dev = dev; +- platform_set_drvdata(pdev, pcie); +- INIT_LIST_HEAD(&pcie->ports); +- +- attr = soc_device_match(mt7621_pci_quirks_match); +- if (attr) +- pcie->resets_inverted = true; +- +- err = mt7621_pcie_parse_dt(pcie); +- if (err) { +- dev_err(dev, "Parsing DT failed\n"); +- return err; +- } +- +- err = mt7621_pcie_init_ports(pcie); +- if (err) { +- dev_err(dev, "Nothing connected in virtual bridges\n"); +- return 0; +- } +- +- err = mt7621_pcie_enable_ports(bridge); +- if (err) { +- dev_err(dev, "Error enabling pcie ports\n"); +- goto remove_resets; +- } +- +- err = setup_cm_memory_region(bridge); +- if (err) { +- dev_err(dev, "Error setting up iocu mem regions\n"); +- goto remove_resets; +- } +- +- return mt7621_pcie_register_host(bridge); +- +-remove_resets: +- list_for_each_entry(port, &pcie->ports, list) +- reset_control_put(port->pcie_rst); +- +- return err; +-} +- +-static int mt7621_pci_remove(struct platform_device *pdev) +-{ +- struct mt7621_pcie *pcie = platform_get_drvdata(pdev); +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) +- reset_control_put(port->pcie_rst); +- +- return 0; +-} +- +-static const struct of_device_id mt7621_pci_ids[] = { +- { .compatible = "mediatek,mt7621-pci" }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, mt7621_pci_ids); +- +-static struct platform_driver mt7621_pci_driver = { +- .probe = mt7621_pci_probe, +- .remove = mt7621_pci_remove, +- .driver = { +- .name = "mt7621-pci", +- .of_match_table = of_match_ptr(mt7621_pci_ids), +- }, +-}; +-builtin_platform_driver(mt7621_pci_driver); +--- /dev/null ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -0,0 +1,600 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * PCI init for Ralink RT2880 solution ++ * ++ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) ++ * ++ * May 2007 Bruce Chang ++ * Initial Release ++ * ++ * May 2009 Bruce Chang ++ * support RT2880/RT3883 PCIe ++ * ++ * May 2011 Bruce Chang ++ * support RT6855/MT7620 PCIe ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* MediaTek-specific configuration registers */ ++#define PCIE_FTS_NUM 0x70c ++#define PCIE_FTS_NUM_MASK GENMASK(15, 8) ++#define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) ++ ++/* Host-PCI bridge registers */ ++#define RALINK_PCI_PCICFG_ADDR 0x0000 ++#define RALINK_PCI_PCIMSK_ADDR 0x000c ++#define RALINK_PCI_CONFIG_ADDR 0x0020 ++#define RALINK_PCI_CONFIG_DATA 0x0024 ++#define RALINK_PCI_MEMBASE 0x0028 ++#define RALINK_PCI_IOBASE 0x002c ++ ++/* PCIe RC control registers */ ++#define RALINK_PCI_ID 0x0030 ++#define RALINK_PCI_CLASS 0x0034 ++#define RALINK_PCI_SUBID 0x0038 ++#define RALINK_PCI_STATUS 0x0050 ++ ++/* Some definition values */ ++#define PCIE_REVISION_ID BIT(0) ++#define PCIE_CLASS_CODE (0x60400 << 8) ++#define PCIE_BAR_MAP_MAX GENMASK(30, 16) ++#define PCIE_BAR_ENABLE BIT(0) ++#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) ++#define PCIE_PORT_LINKUP BIT(0) ++#define PCIE_PORT_CNT 3 ++ ++#define PERST_DELAY_MS 100 ++ ++/** ++ * struct mt7621_pcie_port - PCIe port information ++ * @base: I/O mapped register base ++ * @list: port list ++ * @pcie: pointer to PCIe host info ++ * @clk: pointer to the port clock gate ++ * @phy: pointer to PHY control block ++ * @pcie_rst: pointer to port reset control ++ * @gpio_rst: gpio reset ++ * @slot: port slot ++ * @enabled: indicates if port is enabled ++ */ ++struct mt7621_pcie_port { ++ void __iomem *base; ++ struct list_head list; ++ struct mt7621_pcie *pcie; ++ struct clk *clk; ++ struct phy *phy; ++ struct reset_control *pcie_rst; ++ struct gpio_desc *gpio_rst; ++ u32 slot; ++ bool enabled; ++}; ++ ++/** ++ * struct mt7621_pcie - PCIe host information ++ * @base: IO Mapped Register Base ++ * @dev: Pointer to PCIe device ++ * @ports: pointer to PCIe port information ++ * @resets_inverted: depends on chip revision ++ * reset lines are inverted. ++ */ ++struct mt7621_pcie { ++ void __iomem *base; ++ struct device *dev; ++ struct list_head ports; ++ bool resets_inverted; ++}; ++ ++static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) ++{ ++ return readl_relaxed(pcie->base + reg); ++} ++ ++static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) ++{ ++ writel_relaxed(val, pcie->base + reg); ++} ++ ++static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) ++{ ++ u32 val = readl_relaxed(pcie->base + reg); ++ ++ val &= ~clr; ++ val |= set; ++ writel_relaxed(val, pcie->base + reg); ++} ++ ++static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) ++{ ++ return readl_relaxed(port->base + reg); ++} ++ ++static inline void pcie_port_write(struct mt7621_pcie_port *port, ++ u32 val, u32 reg) ++{ ++ writel_relaxed(val, port->base + reg); ++} ++ ++static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, ++ unsigned int func, unsigned int where) ++{ ++ return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | ++ (func << 8) | (where & 0xfc) | 0x80000000; ++} ++ ++static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, ++ unsigned int devfn, int where) ++{ ++ struct mt7621_pcie *pcie = bus->sysdata; ++ u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ PCI_FUNC(devfn), where); ++ ++ writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); ++ ++ return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); ++} ++ ++struct pci_ops mt7621_pci_ops = { ++ .map_bus = mt7621_pcie_map_bus, ++ .read = pci_generic_config_read, ++ .write = pci_generic_config_write, ++}; ++ ++static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) ++{ ++ u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ ++ pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); ++ return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); ++} ++ ++static void write_config(struct mt7621_pcie *pcie, unsigned int dev, ++ u32 reg, u32 val) ++{ ++ u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ ++ pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); ++ pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); ++} ++ ++static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) ++{ ++ if (port->gpio_rst) ++ gpiod_set_value(port->gpio_rst, 1); ++} ++ ++static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) ++{ ++ if (port->gpio_rst) ++ gpiod_set_value(port->gpio_rst, 0); ++} ++ ++static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) ++{ ++ return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; ++} ++ ++static inline void mt7621_control_assert(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ ++ if (pcie->resets_inverted) ++ reset_control_assert(port->pcie_rst); ++ else ++ reset_control_deassert(port->pcie_rst); ++} ++ ++static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ ++ if (pcie->resets_inverted) ++ reset_control_deassert(port->pcie_rst); ++ else ++ reset_control_assert(port->pcie_rst); ++} ++ ++static int setup_cm_memory_region(struct pci_host_bridge *host) ++{ ++ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); ++ struct device *dev = pcie->dev; ++ struct resource_entry *entry; ++ resource_size_t mask; ++ ++ entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); ++ if (!entry) { ++ dev_err(dev, "cannot get memory resource\n"); ++ return -EINVAL; ++ } ++ ++ if (mips_cps_numiocu(0)) { ++ /* ++ * FIXME: hardware doesn't accept mask values with 1s after ++ * 0s (e.g. 0xffef), so it would be great to warn if that's ++ * about to happen ++ */ ++ mask = ~(entry->res->end - entry->res->start); ++ ++ write_gcr_reg1_base(entry->res->start); ++ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); ++ dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", ++ (unsigned long long)read_gcr_reg1_base(), ++ (unsigned long long)read_gcr_reg1_mask()); ++ } ++ ++ return 0; ++} ++ ++static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, ++ struct device_node *node, ++ int slot) ++{ ++ struct mt7621_pcie_port *port; ++ struct device *dev = pcie->dev; ++ struct platform_device *pdev = to_platform_device(dev); ++ char name[10]; ++ int err; ++ ++ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); ++ if (!port) ++ return -ENOMEM; ++ ++ port->base = devm_platform_ioremap_resource(pdev, slot + 1); ++ if (IS_ERR(port->base)) ++ return PTR_ERR(port->base); ++ ++ port->clk = devm_get_clk_from_child(dev, node, NULL); ++ if (IS_ERR(port->clk)) { ++ dev_err(dev, "failed to get pcie%d clock\n", slot); ++ return PTR_ERR(port->clk); ++ } ++ ++ port->pcie_rst = of_reset_control_get_exclusive(node, NULL); ++ if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { ++ dev_err(dev, "failed to get pcie%d reset control\n", slot); ++ return PTR_ERR(port->pcie_rst); ++ } ++ ++ snprintf(name, sizeof(name), "pcie-phy%d", slot); ++ port->phy = devm_of_phy_get(dev, node, name); ++ if (IS_ERR(port->phy)) { ++ dev_err(dev, "failed to get pcie-phy%d\n", slot); ++ err = PTR_ERR(port->phy); ++ goto remove_reset; ++ } ++ ++ port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, ++ GPIOD_OUT_LOW); ++ if (IS_ERR(port->gpio_rst)) { ++ dev_err(dev, "failed to get GPIO for PCIe%d\n", slot); ++ err = PTR_ERR(port->gpio_rst); ++ goto remove_reset; ++ } ++ ++ port->slot = slot; ++ port->pcie = pcie; ++ ++ INIT_LIST_HEAD(&port->list); ++ list_add_tail(&port->list, &pcie->ports); ++ ++ return 0; ++ ++remove_reset: ++ reset_control_put(port->pcie_rst); ++ return err; ++} ++ ++static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct device_node *node = dev->of_node, *child; ++ int err; ++ ++ pcie->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(pcie->base)) ++ return PTR_ERR(pcie->base); ++ ++ for_each_available_child_of_node(node, child) { ++ int slot; ++ ++ err = of_pci_get_devfn(child); ++ if (err < 0) { ++ of_node_put(child); ++ dev_err(dev, "failed to parse devfn: %d\n", err); ++ return err; ++ } ++ ++ slot = PCI_SLOT(err); ++ ++ err = mt7621_pcie_parse_port(pcie, child, slot); ++ if (err) { ++ of_node_put(child); ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ ++static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ struct device *dev = pcie->dev; ++ u32 slot = port->slot; ++ int err; ++ ++ err = phy_init(port->phy); ++ if (err) { ++ dev_err(dev, "failed to initialize port%d phy\n", slot); ++ return err; ++ } ++ ++ err = phy_power_on(port->phy); ++ if (err) { ++ dev_err(dev, "failed to power on port%d phy\n", slot); ++ phy_exit(port->phy); ++ return err; ++ } ++ ++ port->enabled = true; ++ ++ return 0; ++} ++ ++static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) ++{ ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) { ++ /* PCIe RC reset assert */ ++ mt7621_control_assert(port); ++ ++ /* PCIe EP reset assert */ ++ mt7621_rst_gpio_pcie_assert(port); ++ } ++ ++ msleep(PERST_DELAY_MS); ++} ++ ++static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) ++{ ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) ++ mt7621_control_deassert(port); ++} ++ ++static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) ++{ ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) ++ mt7621_rst_gpio_pcie_deassert(port); ++ ++ msleep(PERST_DELAY_MS); ++} ++ ++static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ struct mt7621_pcie_port *port, *tmp; ++ u8 num_disabled = 0; ++ int err; ++ ++ mt7621_pcie_reset_assert(pcie); ++ mt7621_pcie_reset_rc_deassert(pcie); ++ ++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) { ++ u32 slot = port->slot; ++ ++ if (slot == 1) { ++ port->enabled = true; ++ continue; ++ } ++ ++ err = mt7621_pcie_init_port(port); ++ if (err) { ++ dev_err(dev, "initializing port %d failed\n", slot); ++ list_del(&port->list); ++ } ++ } ++ ++ mt7621_pcie_reset_ep_deassert(pcie); ++ ++ tmp = NULL; ++ list_for_each_entry(port, &pcie->ports, list) { ++ u32 slot = port->slot; ++ ++ if (!mt7621_pcie_port_is_linkup(port)) { ++ dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", ++ slot); ++ mt7621_control_assert(port); ++ port->enabled = false; ++ num_disabled++; ++ ++ if (slot == 0) { ++ tmp = port; ++ continue; ++ } ++ ++ if (slot == 1 && tmp && !tmp->enabled) ++ phy_power_off(tmp->phy); ++ } ++ } ++ ++ return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; ++} ++ ++static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ u32 slot = port->slot; ++ u32 val; ++ ++ /* enable pcie interrupt */ ++ val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); ++ val |= PCIE_PORT_INT_EN(slot); ++ pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); ++ ++ /* map 2G DDR region */ ++ pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, ++ PCI_BASE_ADDRESS_0); ++ ++ /* configure class code and revision ID */ ++ pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, ++ RALINK_PCI_CLASS); ++ ++ /* configure RC FTS number to 250 when it leaves L0s */ ++ val = read_config(pcie, slot, PCIE_FTS_NUM); ++ val &= ~PCIE_FTS_NUM_MASK; ++ val |= PCIE_FTS_NUM_L0(0x50); ++ write_config(pcie, slot, PCIE_FTS_NUM, val); ++} ++ ++static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) ++{ ++ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); ++ struct device *dev = pcie->dev; ++ struct mt7621_pcie_port *port; ++ struct resource_entry *entry; ++ int err; ++ ++ entry = resource_list_first_type(&host->windows, IORESOURCE_IO); ++ if (!entry) { ++ dev_err(dev, "cannot get io resource\n"); ++ return -EINVAL; ++ } ++ ++ /* Setup MEMWIN and IOWIN */ ++ pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); ++ pcie_write(pcie, entry->res->start, RALINK_PCI_IOBASE); ++ ++ list_for_each_entry(port, &pcie->ports, list) { ++ if (port->enabled) { ++ err = clk_prepare_enable(port->clk); ++ if (err) { ++ dev_err(dev, "enabling clk pcie%d\n", ++ port->slot); ++ return err; ++ } ++ ++ mt7621_pcie_enable_port(port); ++ dev_info(dev, "PCIE%d enabled\n", port->slot); ++ } ++ } ++ ++ return 0; ++} ++ ++static int mt7621_pcie_register_host(struct pci_host_bridge *host) ++{ ++ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); ++ ++ host->ops = &mt7621_pci_ops; ++ host->sysdata = pcie; ++ return pci_host_probe(host); ++} ++ ++static const struct soc_device_attribute mt7621_pci_quirks_match[] = { ++ { .soc_id = "mt7621", .revision = "E2" } ++}; ++ ++static int mt7621_pci_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct soc_device_attribute *attr; ++ struct mt7621_pcie_port *port; ++ struct mt7621_pcie *pcie; ++ struct pci_host_bridge *bridge; ++ int err; ++ ++ if (!dev->of_node) ++ return -ENODEV; ++ ++ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); ++ if (!bridge) ++ return -ENOMEM; ++ ++ pcie = pci_host_bridge_priv(bridge); ++ pcie->dev = dev; ++ platform_set_drvdata(pdev, pcie); ++ INIT_LIST_HEAD(&pcie->ports); ++ ++ attr = soc_device_match(mt7621_pci_quirks_match); ++ if (attr) ++ pcie->resets_inverted = true; ++ ++ err = mt7621_pcie_parse_dt(pcie); ++ if (err) { ++ dev_err(dev, "parsing DT failed\n"); ++ return err; ++ } ++ ++ err = mt7621_pcie_init_ports(pcie); ++ if (err) { ++ dev_err(dev, "nothing connected in virtual bridges\n"); ++ return 0; ++ } ++ ++ err = mt7621_pcie_enable_ports(bridge); ++ if (err) { ++ dev_err(dev, "error enabling pcie ports\n"); ++ goto remove_resets; ++ } ++ ++ err = setup_cm_memory_region(bridge); ++ if (err) { ++ dev_err(dev, "error setting up iocu mem regions\n"); ++ goto remove_resets; ++ } ++ ++ return mt7621_pcie_register_host(bridge); ++ ++remove_resets: ++ list_for_each_entry(port, &pcie->ports, list) ++ reset_control_put(port->pcie_rst); ++ ++ return err; ++} ++ ++static int mt7621_pci_remove(struct platform_device *pdev) ++{ ++ struct mt7621_pcie *pcie = platform_get_drvdata(pdev); ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) ++ reset_control_put(port->pcie_rst); ++ ++ return 0; ++} ++ ++static const struct of_device_id mt7621_pci_ids[] = { ++ { .compatible = "mediatek,mt7621-pci" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mt7621_pci_ids); ++ ++static struct platform_driver mt7621_pci_driver = { ++ .probe = mt7621_pci_probe, ++ .remove = mt7621_pci_remove, ++ .driver = { ++ .name = "mt7621-pci", ++ .of_match_table = of_match_ptr(mt7621_pci_ids), ++ }, ++}; ++builtin_platform_driver(mt7621_pci_driver); diff --git a/target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch b/target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch new file mode 100644 index 0000000000..916477511d --- /dev/null +++ b/target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch @@ -0,0 +1,134 @@ +From: Bjorn Helgaas +Date: Wed, 22 Dec 2021 19:10:48 -0600 +Subject: [PATCH] PCI: mt7621: Rename mt7621_pci_ to mt7621_pcie_ + +Rename mt7621_pci_* structs and functions to mt7621_pcie_* for consistency +with the rest of the file. + +Link: https://lore.kernel.org/r/20211223011054.1227810-18-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Sergio Paracuellos +Cc: Matthias Brugger +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -93,8 +93,8 @@ struct mt7621_pcie_port { + * reset lines are inverted. + */ + struct mt7621_pcie { +- void __iomem *base; + struct device *dev; ++ void __iomem *base; + struct list_head ports; + bool resets_inverted; + }; +@@ -129,7 +129,7 @@ static inline void pcie_port_write(struc + writel_relaxed(val, port->base + reg); + } + +-static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, ++static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot, + unsigned int func, unsigned int where) + { + return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | +@@ -140,7 +140,7 @@ static void __iomem *mt7621_pcie_map_bus + unsigned int devfn, int where) + { + struct mt7621_pcie *pcie = bus->sysdata; +- u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + + writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); +@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus + return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); + } + +-struct pci_ops mt7621_pci_ops = { ++struct pci_ops mt7621_pcie_ops = { + .map_bus = mt7621_pcie_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, +@@ -156,7 +156,7 @@ struct pci_ops mt7621_pci_ops = { + + static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) + { +- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); + + pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); + return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); +@@ -165,7 +165,7 @@ static u32 read_config(struct mt7621_pci + static void write_config(struct mt7621_pcie *pcie, unsigned int dev, + u32 reg, u32 val) + { +- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); + + pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); + pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); +@@ -505,16 +505,16 @@ static int mt7621_pcie_register_host(str + { + struct mt7621_pcie *pcie = pci_host_bridge_priv(host); + +- host->ops = &mt7621_pci_ops; ++ host->ops = &mt7621_pcie_ops; + host->sysdata = pcie; + return pci_host_probe(host); + } + +-static const struct soc_device_attribute mt7621_pci_quirks_match[] = { ++static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { + { .soc_id = "mt7621", .revision = "E2" } + }; + +-static int mt7621_pci_probe(struct platform_device *pdev) ++static int mt7621_pcie_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + const struct soc_device_attribute *attr; +@@ -535,7 +535,7 @@ static int mt7621_pci_probe(struct platf + platform_set_drvdata(pdev, pcie); + INIT_LIST_HEAD(&pcie->ports); + +- attr = soc_device_match(mt7621_pci_quirks_match); ++ attr = soc_device_match(mt7621_pcie_quirks_match); + if (attr) + pcie->resets_inverted = true; + +@@ -572,7 +572,7 @@ remove_resets: + return err; + } + +-static int mt7621_pci_remove(struct platform_device *pdev) ++static int mt7621_pcie_remove(struct platform_device *pdev) + { + struct mt7621_pcie *pcie = platform_get_drvdata(pdev); + struct mt7621_pcie_port *port; +@@ -583,18 +583,18 @@ static int mt7621_pci_remove(struct plat + return 0; + } + +-static const struct of_device_id mt7621_pci_ids[] = { ++static const struct of_device_id mt7621_pcie_ids[] = { + { .compatible = "mediatek,mt7621-pci" }, + {}, + }; +-MODULE_DEVICE_TABLE(of, mt7621_pci_ids); ++MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); + +-static struct platform_driver mt7621_pci_driver = { +- .probe = mt7621_pci_probe, +- .remove = mt7621_pci_remove, ++static struct platform_driver mt7621_pcie_driver = { ++ .probe = mt7621_pcie_probe, ++ .remove = mt7621_pcie_remove, + .driver = { + .name = "mt7621-pci", +- .of_match_table = of_match_ptr(mt7621_pci_ids), ++ .of_match_table = of_match_ptr(mt7621_pcie_ids), + }, + }; +-builtin_platform_driver(mt7621_pci_driver); ++builtin_platform_driver(mt7621_pcie_driver); diff --git a/target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch b/target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch new file mode 100644 index 0000000000..815ecc7d37 --- /dev/null +++ b/target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch @@ -0,0 +1,30 @@ +From: Sergio Paracuellos +Date: Wed, 17 Nov 2021 16:29:52 +0100 +Subject: [PATCH] PCI: mt7621: Declare mt7621_pci_ops static +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Sparse complains about mt7621_pci_ops symbol is not declared and asks if +it should be declared as static instead. Sparse is right. Hence declare +symbol as static. + +Link: https://lore.kernel.org/r/20211117152952.12271-1-sergio.paracuellos@gmail.com +Reported-by: kernel test robot +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Reviewed-by: Krzysztof WilczyÅ„ski +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus + return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); + } + +-struct pci_ops mt7621_pcie_ops = { ++static struct pci_ops mt7621_pcie_ops = { + .map_bus = mt7621_pcie_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, diff --git a/target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch b/target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch new file mode 100644 index 0000000000..3162ff8107 --- /dev/null +++ b/target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch @@ -0,0 +1,119 @@ +From: Sergio Paracuellos +Date: Tue, 7 Dec 2021 11:49:21 +0100 +Subject: [PATCH] PCI: mt7621: Move MIPS setup to pcibios_root_bridge_prepare() + +On the MIPS ralink mt7621 platform, we need to set up I/O coherency units +based on the host bridge apertures. + +To remove this arch dependency from the driver itself, move the coherency +setup from the driver to pcibios_root_bridge_prepare(). + +[bhelgaas: squash add/remove into one patch, commit log] +Link: https://lore.kernel.org/r/20211207104924.21327-3-sergio.paracuellos@gmail.com +Link: https://lore.kernel.org/r/20211207104924.21327-4-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +Reviewed-by: Guenter Roeck # arch/mips +Acked-by: Thomas Bogendoerfer # arch/mips +--- + +--- a/arch/mips/ralink/mt7621.c ++++ b/arch/mips/ralink/mt7621.c +@@ -10,6 +10,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -24,6 +26,35 @@ + + static u32 detect_magic __initdata; + ++int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) ++{ ++ struct resource_entry *entry; ++ resource_size_t mask; ++ ++ entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM); ++ if (!entry) { ++ pr_err("Cannot get memory resource\n"); ++ return -EINVAL; ++ } ++ ++ if (mips_cps_numiocu(0)) { ++ /* ++ * Hardware doesn't accept mask values with 1s after ++ * 0s (e.g. 0xffef), so warn if that's happen ++ */ ++ mask = ~(entry->res->end - entry->res->start) & CM_GCR_REGn_MASK_ADDRMASK; ++ WARN_ON(mask && BIT(ffz(~mask)) - 1 != ~mask); ++ ++ write_gcr_reg1_base(entry->res->start); ++ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); ++ pr_info("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", ++ (unsigned long long)read_gcr_reg1_base(), ++ (unsigned long long)read_gcr_reg1_mask()); ++ } ++ ++ return 0; ++} ++ + phys_addr_t mips_cpc_default_phys_base(void) + { + panic("Cannot detect cpc address"); +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -208,37 +208,6 @@ static inline void mt7621_control_deasse + reset_control_assert(port->pcie_rst); + } + +-static int setup_cm_memory_region(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- struct device *dev = pcie->dev; +- struct resource_entry *entry; +- resource_size_t mask; +- +- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); +- if (!entry) { +- dev_err(dev, "cannot get memory resource\n"); +- return -EINVAL; +- } +- +- if (mips_cps_numiocu(0)) { +- /* +- * FIXME: hardware doesn't accept mask values with 1s after +- * 0s (e.g. 0xffef), so it would be great to warn if that's +- * about to happen +- */ +- mask = ~(entry->res->end - entry->res->start); +- +- write_gcr_reg1_base(entry->res->start); +- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); +- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", +- (unsigned long long)read_gcr_reg1_base(), +- (unsigned long long)read_gcr_reg1_mask()); +- } +- +- return 0; +-} +- + static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, + struct device_node *node, + int slot) +@@ -557,12 +526,6 @@ static int mt7621_pcie_probe(struct plat + goto remove_resets; + } + +- err = setup_cm_memory_region(bridge); +- if (err) { +- dev_err(dev, "error setting up iocu mem regions\n"); +- goto remove_resets; +- } +- + return mt7621_pcie_register_host(bridge); + + remove_resets: diff --git a/target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch b/target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch new file mode 100644 index 0000000000..0913a452c6 --- /dev/null +++ b/target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch @@ -0,0 +1,35 @@ +From: Sergio Paracuellos +Date: Mon, 24 Jan 2022 12:30:02 +0100 +Subject: [PATCH] PCI: mt7621: Drop of_match_ptr() to avoid unused variable + +We have stubs for most OF interfaces even when CONFIG_OF is not set, so we +allow building of pcie-mt7621.c in that case for compile testing. + +When CONFIG_OF is not set, "of_match_ptr(mt7621_pcie_ids)" compiles to +NULL, which leaves mt7621_pcie_ids unused: + + $ make W=1 + drivers/pci/controller/pcie-mt7621.c:549:34: warning: unused variable 'mt7621_pcie_ids' [-Wunused-const-variable] + +Drop of_match_ptr() to avoid the unused variable warning. + +[bhelgaas: commit log] +Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") +Link: https://lore.kernel.org/r/20220124113003.406224-2-sergio.paracuellos@gmail.com +Link: https://lore.kernel.org/r/202201241754.igtHzgHv-lkp@intel.com +Reported-by: kernel test robot +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -557,7 +557,7 @@ static struct platform_driver mt7621_pci + .remove = mt7621_pcie_remove, + .driver = { + .name = "mt7621-pci", +- .of_match_table = of_match_ptr(mt7621_pcie_ids), ++ .of_match_table = mt7621_pcie_ids, + }, + }; + builtin_platform_driver(mt7621_pcie_driver); diff --git a/target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch b/target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch new file mode 100644 index 0000000000..0323588e5a --- /dev/null +++ b/target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch @@ -0,0 +1,35 @@ +From: Sergio Paracuellos +Date: Mon, 24 Jan 2022 12:30:03 +0100 +Subject: [PATCH] PCI: mt7621: Remove unused function pcie_rmw() + +Function pcie_rmw() is not being used at all and can be deleted. Hence get +rid of it, which fixes this warning: + + drivers/pci/controller/pcie-mt7621.c:112:20: warning: unused function 'pcie_rmw' [-Wunused-function] + +Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") +Link: https://lore.kernel.org/r/20220124113003.406224-3-sergio.paracuellos@gmail.com +Link: https://lore.kernel.org/all/202201241754.igtHzgHv-lkp@intel.com/ +Reported-by: kernel test robot +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -109,15 +109,6 @@ static inline void pcie_write(struct mt7 + writel_relaxed(val, pcie->base + reg); + } + +-static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) +-{ +- u32 val = readl_relaxed(pcie->base + reg); +- +- val &= ~clr; +- val |= set; +- writel_relaxed(val, pcie->base + reg); +-} +- + static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) + { + return readl_relaxed(port->base + reg); diff --git a/target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch b/target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch new file mode 100644 index 0000000000..2fbbf9a7aa --- /dev/null +++ b/target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch @@ -0,0 +1,38 @@ +From: Sergio Paracuellos +Date: Tue, 7 Dec 2021 11:49:20 +0100 +Subject: [PATCH] PCI: Let pcibios_root_bridge_prepare() access bridge->windows + +When pci_register_host_bridge() is called, bridge->windows are already +available. However these windows are being moved temporarily from there. + +To let pcibios_root_bridge_prepare() have access to these windows, move the +windows movement after calling this function. This is useful for the MIPS +ralink mt7621 platform so it can set up I/O coherence units and avoid +custom MIPS code in the mt7621 PCIe controller driver. + +Link: https://lore.kernel.org/r/20211207104924.21327-2-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +Acked-by: Arnd Bergmann +--- + +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -898,8 +898,6 @@ static int pci_register_host_bridge(stru + + bridge->bus = bus; + +- /* Temporarily move resources off the list */ +- list_splice_init(&bridge->windows, &resources); + bus->sysdata = bridge->sysdata; + bus->ops = bridge->ops; + bus->number = bus->busn_res.start = bridge->busnr; +@@ -925,6 +923,8 @@ static int pci_register_host_bridge(stru + if (err) + goto free; + ++ /* Temporarily move resources off the list */ ++ list_splice_init(&bridge->windows, &resources); + err = device_add(&bridge->dev); + if (err) { + put_device(&bridge->dev); diff --git a/target/linux/ramips/patches-5.15/110-reset_controller_driver.patch b/target/linux/ramips/patches-5.15/110-reset_controller_driver.patch new file mode 100644 index 0000000000..6c923d70c3 --- /dev/null +++ b/target/linux/ramips/patches-5.15/110-reset_controller_driver.patch @@ -0,0 +1,61 @@ +--- a/arch/mips/ralink/reset.c ++++ b/arch/mips/ralink/reset.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + + #include + +@@ -65,21 +66,39 @@ static const struct reset_control_ops re + .deassert = ralink_deassert_device, + }; + +-static struct reset_controller_dev reset_dev = { +- .ops = &reset_ops, +- .owner = THIS_MODULE, +- .nr_resets = 32, +- .of_reset_n_cells = 1, ++static int ralink_reset_probe(struct platform_device *pdev) ++{ ++ struct reset_controller_dev *rcdev; ++ ++ rcdev = devm_kzalloc(&pdev->dev, sizeof(*rcdev), GFP_KERNEL); ++ if (!rcdev) ++ return -ENOMEM; ++ ++ rcdev->ops = &reset_ops; ++ rcdev->owner = THIS_MODULE; ++ rcdev->nr_resets = 32; ++ rcdev->of_reset_n_cells = 1; ++ rcdev->of_node = pdev->dev.of_node; ++ ++ return devm_reset_controller_register(&pdev->dev, rcdev); ++} ++ ++static const struct of_device_id ralink_reset_dt_ids[] = { ++ { .compatible = "ralink,rt2880-reset" }, ++ {} ++}; ++ ++static struct platform_driver ralink_reset_driver = { ++ .probe = ralink_reset_probe, ++ .driver = { ++ .name = "ralink-reset", ++ .of_match_table = ralink_reset_dt_ids, ++ } + }; + + void ralink_rst_init(void) + { +- reset_dev.of_node = of_find_compatible_node(NULL, NULL, +- "ralink,rt2880-reset"); +- if (!reset_dev.of_node) +- pr_err("Failed to find reset controller node"); +- else +- reset_controller_register(&reset_dev); ++ platform_driver_register(&ralink_reset_driver); + } + + static void ralink_restart(char *command) diff --git a/target/linux/ramips/patches-5.15/200-add-ralink-eth.patch b/target/linux/ramips/patches-5.15/200-add-ralink-eth.patch new file mode 100644 index 0000000000..4a0262eaad --- /dev/null +++ b/target/linux/ramips/patches-5.15/200-add-ralink-eth.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -162,6 +162,7 @@ source "drivers/net/ethernet/pasemi/Kcon + source "drivers/net/ethernet/pensando/Kconfig" + source "drivers/net/ethernet/qlogic/Kconfig" + source "drivers/net/ethernet/qualcomm/Kconfig" ++source "drivers/net/ethernet/ralink/Kconfig" + source "drivers/net/ethernet/rdc/Kconfig" + source "drivers/net/ethernet/realtek/Kconfig" + source "drivers/net/ethernet/renesas/Kconfig" +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -73,6 +73,7 @@ obj-$(CONFIG_NET_VENDOR_PACKET_ENGINES) + obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/ + obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/ + obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/ ++obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/ + obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ + obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/ + obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ diff --git a/target/linux/ramips/patches-5.15/300-mt7620-export-chip-version-and-pkg.patch b/target/linux/ramips/patches-5.15/300-mt7620-export-chip-version-and-pkg.patch new file mode 100644 index 0000000000..c31be4a5df --- /dev/null +++ b/target/linux/ramips/patches-5.15/300-mt7620-export-chip-version-and-pkg.patch @@ -0,0 +1,19 @@ +--- a/arch/mips/include/asm/mach-ralink/mt7620.h ++++ b/arch/mips/include/asm/mach-ralink/mt7620.h +@@ -96,4 +96,16 @@ static inline int mt7620_get_eco(void) + return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK; + } + ++static inline int mt7620_get_chipver(void) ++{ ++ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) & ++ CHIP_REV_VER_MASK; ++} ++ ++static inline int mt7620_get_pkg(void) ++{ ++ return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) & ++ CHIP_REV_PKG_MASK; ++} ++ + #endif diff --git a/target/linux/ramips/patches-5.15/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch b/target/linux/ramips/patches-5.15/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch new file mode 100644 index 0000000000..172cf98ad1 --- /dev/null +++ b/target/linux/ramips/patches-5.15/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch @@ -0,0 +1,100 @@ +From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 14 Jul 2013 23:08:11 +0200 +Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k + irq + +Signed-off-by: John Crispin +--- + arch/mips/ralink/Kconfig | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -1,12 +1,17 @@ + # SPDX-License-Identifier: GPL-2.0 + if RALINK + ++config CEVT_SYSTICK_QUIRK ++ bool ++ default n ++ + config CLKEVT_RT3352 + bool + depends on SOC_RT305X || SOC_MT7620 + default y + select TIMER_OF + select CLKSRC_MMIO ++ select CEVT_SYSTICK_QUIRK + + config RALINK_ILL_ACC + bool +--- a/arch/mips/kernel/cevt-r4k.c ++++ b/arch/mips/kernel/cevt-r4k.c +@@ -16,6 +16,31 @@ + #include + #include + ++#ifdef CONFIG_CEVT_SYSTICK_QUIRK ++static int mips_state_oneshot(struct clock_event_device *evt) ++{ ++ unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED; ++ if (!cp0_timer_irq_installed) { ++ cp0_timer_irq_installed = 1; ++ if (request_irq(evt->irq, c0_compare_interrupt, flags, "timer", ++ c0_compare_interrupt)) ++ pr_err("Failed to request irq %d (timer)\n", evt->irq); ++ } ++ ++ return 0; ++} ++ ++static int mips_state_shutdown(struct clock_event_device *evt) ++{ ++ if (cp0_timer_irq_installed) { ++ cp0_timer_irq_installed = 0; ++ free_irq(evt->irq, NULL); ++ } ++ ++ return 0; ++} ++#endif ++ + static int mips_next_event(unsigned long delta, + struct clock_event_device *evt) + { +@@ -292,7 +317,9 @@ core_initcall(r4k_register_cpufreq_notif + + int r4k_clockevent_init(void) + { ++#ifndef CONFIG_CEVT_SYSTICK_QUIRK + unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED; ++#endif + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + unsigned int irq, min_delta; +@@ -322,11 +349,16 @@ int r4k_clockevent_init(void) + cd->rating = 300; + cd->irq = irq; + cd->cpumask = cpumask_of(cpu); ++#ifdef CONFIG_CEVT_SYSTICK_QUIRK ++ cd->set_state_shutdown = mips_state_shutdown; ++ cd->set_state_oneshot = mips_state_oneshot; ++#endif + cd->set_next_event = mips_next_event; + cd->event_handler = mips_event_handler; + + clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff); + ++#ifndef CONFIG_CEVT_SYSTICK_QUIRK + if (cp0_timer_irq_installed) + return 0; + +@@ -335,6 +367,7 @@ int r4k_clockevent_init(void) + if (request_irq(irq, c0_compare_interrupt, flags, "timer", + c0_compare_interrupt)) + pr_err("Failed to request irq %d (timer)\n", irq); ++#endif + + return 0; + } diff --git a/target/linux/ramips/patches-5.15/312-MIPS-ralink-add-cpu-frequency-scaling.patch b/target/linux/ramips/patches-5.15/312-MIPS-ralink-add-cpu-frequency-scaling.patch new file mode 100644 index 0000000000..0d70770941 --- /dev/null +++ b/target/linux/ramips/patches-5.15/312-MIPS-ralink-add-cpu-frequency-scaling.patch @@ -0,0 +1,195 @@ +From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 28 Jul 2013 16:26:41 +0200 +Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling + +This feature will break udelay() and cause the delay loop to have longer delays +when the frequency is scaled causing a performance hit. + +Signed-off-by: John Crispin +--- + arch/mips/ralink/cevt-rt3352.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +--- a/arch/mips/ralink/cevt-rt3352.c ++++ b/arch/mips/ralink/cevt-rt3352.c +@@ -29,6 +29,10 @@ + /* enable the counter */ + #define CFG_CNT_EN 0x1 + ++/* mt7620 frequency scaling defines */ ++#define CLK_LUT_CFG 0x40 ++#define SLEEP_EN BIT(31) ++ + struct systick_device { + void __iomem *membase; + struct clock_event_device dev; +@@ -36,21 +40,53 @@ struct systick_device { + int freq_scale; + }; + ++static void (*systick_freq_scaling)(struct systick_device *sdev, int status); ++ + static int systick_set_oneshot(struct clock_event_device *evt); + static int systick_shutdown(struct clock_event_device *evt); + ++static inline void mt7620_freq_scaling(struct systick_device *sdev, int status) ++{ ++ if (sdev->freq_scale == status) ++ return; ++ ++ sdev->freq_scale = status; ++ ++ pr_info("%s: %s autosleep mode\n", sdev->dev.name, ++ (status) ? ("enable") : ("disable")); ++ if (status) ++ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG); ++ else ++ rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG); ++} ++ ++static inline unsigned int read_count(struct systick_device *sdev) ++{ ++ return ioread32(sdev->membase + SYSTICK_COUNT); ++} ++ ++static inline unsigned int read_compare(struct systick_device *sdev) ++{ ++ return ioread32(sdev->membase + SYSTICK_COMPARE); ++} ++ ++static inline void write_compare(struct systick_device *sdev, unsigned int val) ++{ ++ iowrite32(val, sdev->membase + SYSTICK_COMPARE); ++} ++ + static int systick_next_event(unsigned long delta, + struct clock_event_device *evt) + { + struct systick_device *sdev; +- u32 count; ++ int res; + + sdev = container_of(evt, struct systick_device, dev); +- count = ioread32(sdev->membase + SYSTICK_COUNT); +- count = (count + delta) % SYSTICK_FREQ; +- iowrite32(count, sdev->membase + SYSTICK_COMPARE); ++ delta += read_count(sdev); ++ write_compare(sdev, delta); ++ res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0; + +- return 0; ++ return res; + } + + static void systick_event_handler(struct clock_event_device *dev) +@@ -60,20 +96,25 @@ static void systick_event_handler(struct + + static irqreturn_t systick_interrupt(int irq, void *dev_id) + { +- struct clock_event_device *dev = (struct clock_event_device *) dev_id; ++ int ret = 0; ++ struct clock_event_device *cdev; ++ struct systick_device *sdev; + +- dev->event_handler(dev); ++ if (read_c0_cause() & STATUSF_IP7) { ++ cdev = (struct clock_event_device *) dev_id; ++ sdev = container_of(cdev, struct systick_device, dev); ++ ++ /* Clear Count/Compare Interrupt */ ++ write_compare(sdev, read_compare(sdev)); ++ cdev->event_handler(cdev); ++ ret = 1; ++ } + +- return IRQ_HANDLED; ++ return IRQ_RETVAL(ret); + } + + static struct systick_device systick = { + .dev = { +- /* +- * cevt-r4k uses 300, make sure systick +- * gets used if available +- */ +- .rating = 310, + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_next_event = systick_next_event, + .set_state_shutdown = systick_shutdown, +@@ -91,7 +132,13 @@ static int systick_shutdown(struct clock + if (sdev->irq_requested) + free_irq(systick.dev.irq, &systick.dev); + sdev->irq_requested = 0; +- iowrite32(0, systick.membase + SYSTICK_CONFIG); ++ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG); ++ ++ if (systick_freq_scaling) ++ systick_freq_scaling(sdev, 0); ++ ++ if (systick_freq_scaling) ++ systick_freq_scaling(sdev, 1); + + return 0; + } +@@ -116,33 +163,46 @@ static int systick_set_oneshot(struct cl + return 0; + } + ++static const struct of_device_id systick_match[] = { ++ { .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling}, ++ {}, ++}; ++ + static int __init ralink_systick_init(struct device_node *np) + { +- int ret; ++ const struct of_device_id *match; ++ int rating = 200; + + systick.membase = of_iomap(np, 0); + if (!systick.membase) + return -ENXIO; + +- systick.dev.name = np->name; +- clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60); +- systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev); +- systick.dev.max_delta_ticks = 0x7fff; +- systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev); +- systick.dev.min_delta_ticks = 0x3; ++ match = of_match_node(systick_match, np); ++ if (match) { ++ systick_freq_scaling = match->data; ++ /* ++ * cevt-r4k uses 300, make sure systick ++ * gets used if available ++ */ ++ rating = 310; ++ } ++ ++ /* enable counter than register clock source */ ++ iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG); ++ clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, ++ SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up); ++ ++ /* register clock event */ + systick.dev.irq = irq_of_parse_and_map(np, 0); + if (!systick.dev.irq) { + pr_err("%pOFn: request_irq failed", np); + return -EINVAL; + } + +- ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, +- SYSTICK_FREQ, 301, 16, +- clocksource_mmio_readl_up); +- if (ret) +- return ret; +- +- clockevents_register_device(&systick.dev); ++ systick.dev.name = np->name; ++ systick.dev.rating = rating; ++ systick.dev.cpumask = cpumask_of(0); ++ clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff); + + pr_info("%pOFn: running - mult: %d, shift: %d\n", + np, systick.dev.mult, systick.dev.shift); diff --git a/target/linux/ramips/patches-5.15/314-MIPS-add-bootargs-override-property.patch b/target/linux/ramips/patches-5.15/314-MIPS-add-bootargs-override-property.patch new file mode 100644 index 0000000000..07635a9d86 --- /dev/null +++ b/target/linux/ramips/patches-5.15/314-MIPS-add-bootargs-override-property.patch @@ -0,0 +1,63 @@ +From f15d27f9c90ede4b16eb37f9ae573ef81c2b6996 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Thu, 31 Dec 2020 18:49:12 +0100 +Subject: [PATCH] MIPS: add bootargs-override property + +Add support for the bootargs-override property to the chosen node +similar to the one used on ipq806x or mpc85xx. + +This is necessary, as the U-Boot used on some boards, notably the +Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen +node leading to a kernel panic when loading OpenWrt. + +Signed-off-by: David Bauer +--- + arch/mips/kernel/setup.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -544,8 +544,28 @@ static int __init bootcmdline_scan_chose + + #endif /* CONFIG_OF_EARLY_FLATTREE */ + ++static int __init bootcmdline_scan_chosen_override(unsigned long node, const char *uname, ++ int depth, void *data) ++{ ++ bool *dt_bootargs = data; ++ const char *p; ++ int l; ++ ++ if (depth != 1 || !data || strcmp(uname, "chosen") != 0) ++ return 0; ++ ++ p = of_get_flat_dt_prop(node, "bootargs-override", &l); ++ if (p != NULL && l > 0) { ++ strlcpy(boot_command_line, p, COMMAND_LINE_SIZE); ++ *dt_bootargs = true; ++ } ++ ++ return 1; ++} ++ + static void __init bootcmdline_init(void) + { ++ bool dt_bootargs_override = false; + bool dt_bootargs = false; + + /* +@@ -559,6 +579,14 @@ static void __init bootcmdline_init(void + } + + /* ++ * If bootargs-override in the chosen node is set, use this as the ++ * command line ++ */ ++ of_scan_flat_dt(bootcmdline_scan_chosen_override, &dt_bootargs_override); ++ if (dt_bootargs_override) ++ return; ++ ++ /* + * If the user specified a built-in command line & + * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is + * prepended to arguments from the bootloader or DT so we'll copy them diff --git a/target/linux/ramips/patches-5.15/315-owrt-hack-fix-mt7688-cache-issue.patch b/target/linux/ramips/patches-5.15/315-owrt-hack-fix-mt7688-cache-issue.patch new file mode 100644 index 0000000000..f36f028cab --- /dev/null +++ b/target/linux/ramips/patches-5.15/315-owrt-hack-fix-mt7688-cache-issue.patch @@ -0,0 +1,28 @@ +From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 7 Dec 2015 17:15:32 +0100 +Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue + +Signed-off-by: John Crispin +--- + arch/mips/kernel/setup.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mips/kernel/setup.c ++++ b/arch/mips/kernel/setup.c +@@ -686,7 +686,6 @@ static void __init arch_mem_init(char ** + mips_reserve_vmcore(); + + mips_parse_crashkernel(); +- device_tree_init(); + + /* + * In order to reduce the possibility of kernel panic when failed to +@@ -803,6 +802,7 @@ void __init setup_arch(char **cmdline_p) + + cpu_cache_init(); + paging_init(); ++ device_tree_init(); + + memblock_dump_all(); + } diff --git a/target/linux/ramips/patches-5.15/316-arch-mips-do-not-select-illegal-access-driver-by-def.patch b/target/linux/ramips/patches-5.15/316-arch-mips-do-not-select-illegal-access-driver-by-def.patch new file mode 100644 index 0000000000..1dc54ccf23 --- /dev/null +++ b/target/linux/ramips/patches-5.15/316-arch-mips-do-not-select-illegal-access-driver-by-def.patch @@ -0,0 +1,25 @@ +From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 7 Dec 2015 17:18:05 +0100 +Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by + default + +Signed-off-by: John Crispin +--- + arch/mips/ralink/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -14,9 +14,9 @@ config CLKEVT_RT3352 + select CEVT_SYSTICK_QUIRK + + config RALINK_ILL_ACC +- bool ++ bool "illegal access irq" + depends on SOC_RT305X +- default y ++ default n + + config IRQ_INTC + bool diff --git a/target/linux/ramips/patches-5.15/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch b/target/linux/ramips/patches-5.15/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch new file mode 100644 index 0000000000..0eb6676414 --- /dev/null +++ b/target/linux/ramips/patches-5.15/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch @@ -0,0 +1,74 @@ +From 6decd1aad15f56b169217789630a0098b496de0e Mon Sep 17 00:00:00 2001 +From: Ilya Lipnitskiy +Date: Wed, 7 Apr 2021 13:07:38 -0700 +Subject: [PATCH] MIPS: add support for buggy MT7621S core detection + +Most MT7621 SoCs have 2 cores, which is detected and supported properly +by CPS. + +Unfortunately, MT7621 SoC has a less common S variant with only one core. +On MT7621S, GCR_CONFIG still reports 2 cores, which leads to hangs when +starting SMP. CPULAUNCH registers can be used in that case to detect the +absence of the second core and override the GCR_CONFIG PCORES field. + +Rework a long-standing OpenWrt patch to override the value of +mips_cps_numcores on single-core MT7621 systems. + +Tested on a dual-core MT7621 device (Ubiquiti ER-X) and a single-core +MT7621 device (Netgear R6220). + +Original 4.14 OpenWrt patch: +Link: https://git.openwrt.org/?p=openwrt/openwrt.git;a=commitdiff;h=4cdbc90a376dd0555201c1434a2081e055e9ceb7 +Current 5.10 OpenWrt patch: +Link: https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/ramips/patches-5.10/320-mt7621-core-detect-hack.patch;h=c63f0f4c1ec742e24d8480e80553863744b58f6a;hb=10267e17299806f9885d086147878f6c492cb904 + +Suggested-by: Felix Fietkau +Signed-off-by: Ilya Lipnitskiy +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/include/asm/mips-cps.h | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/arch/mips/include/asm/mips-cps.h ++++ b/arch/mips/include/asm/mips-cps.h +@@ -10,6 +10,8 @@ + #include + #include + ++#include ++ + extern unsigned long __cps_access_bad_size(void) + __compiletime_error("Bad size for CPS accessor"); + +@@ -165,11 +167,30 @@ static inline uint64_t mips_cps_cluster_ + */ + static inline unsigned int mips_cps_numcores(unsigned int cluster) + { ++ unsigned int ncores; ++ + if (!mips_cm_present()) + return 0; + + /* Add one before masking to handle 0xff indicating no cores */ +- return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; ++ ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; ++ ++ if (IS_ENABLED(CONFIG_SOC_MT7621)) { ++ struct cpulaunch *launch; ++ ++ /* ++ * Ralink MT7621S SoC is single core, but the GCR_CONFIG method ++ * always reports 2 cores. Check the second core's LAUNCH_FREADY ++ * flag to detect if the second core is missing. This method ++ * only works before the core has been started. ++ */ ++ launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH); ++ launch += 2; /* MT7621 has 2 VPEs per core */ ++ if (!(launch->flags & LAUNCH_FREADY)) ++ ncores = 1; ++ } ++ ++ return ncores; + } + + /** diff --git a/target/linux/ramips/patches-5.15/324-mt7621-perfctr-fix.patch b/target/linux/ramips/patches-5.15/324-mt7621-perfctr-fix.patch new file mode 100644 index 0000000000..dfeac7eb99 --- /dev/null +++ b/target/linux/ramips/patches-5.15/324-mt7621-perfctr-fix.patch @@ -0,0 +1,15 @@ +--- a/arch/mips/ralink/irq-gic.c ++++ b/arch/mips/ralink/irq-gic.c +@@ -13,6 +13,12 @@ + + int get_c0_perfcount_int(void) + { ++ /* ++ * Performance counter events are routed through GIC. ++ * Prevent them from firing on CPU IRQ7 as well ++ */ ++ clear_c0_status(IE_SW0 << 7); ++ + return gic_get_c0_perfcount_int(); + } + EXPORT_SYMBOL_GPL(get_c0_perfcount_int); diff --git a/target/linux/ramips/patches-5.15/400-mtd-cfi-cmdset-0002-force-word-write.patch b/target/linux/ramips/patches-5.15/400-mtd-cfi-cmdset-0002-force-word-write.patch new file mode 100644 index 0000000000..7011bbe50b --- /dev/null +++ b/target/linux/ramips/patches-5.15/400-mtd-cfi-cmdset-0002-force-word-write.patch @@ -0,0 +1,20 @@ +From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 15 Jul 2013 00:39:21 +0200 +Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write + +--- + drivers/mtd/chips/cfi_cmdset_0002.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -40,7 +40,7 @@ + #include + + #define AMD_BOOTLOC_BUG +-#define FORCE_WORD_WRITE 0 ++#define FORCE_WORD_WRITE 1 + + #define MAX_RETRIES 3 + diff --git a/target/linux/ramips/patches-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch b/target/linux/ramips/patches-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch new file mode 100644 index 0000000000..76b9b36b07 --- /dev/null +++ b/target/linux/ramips/patches-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch @@ -0,0 +1,75 @@ +From 52d14545d2fc276b1bf9ccf48d4612fab6edfb6a Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Thu, 6 May 2021 17:49:55 +0200 +Subject: [PATCH] mtd: spi-nor: Add support for BoHong bh25q128as + +Add MTD support for the BoHong bh25q128as SPI NOR chip. +The chip has 16MB of total capacity, divided into a total of 256 +sectors, each 64KB sized. The chip also supports 4KB sectors. +Additionally, it supports dual and quad read modes. + +Functionality was verified on an Tenbay WR1800K / MTK MT7621 board. + +Signed-off-by: David Bauer +--- + drivers/mtd/spi-nor/Makefile | 1 + + drivers/mtd/spi-nor/bohong.c | 21 +++++++++++++++++++++ + drivers/mtd/spi-nor/core.c | 1 + + drivers/mtd/spi-nor/core.h | 1 + + 4 files changed, 24 insertions(+) + create mode 100644 drivers/mtd/spi-nor/bohong.c + +--- a/drivers/mtd/spi-nor/Makefile ++++ b/drivers/mtd/spi-nor/Makefile +@@ -2,6 +2,7 @@ + + spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o + spi-nor-objs += atmel.o ++spi-nor-objs += bohong.o + spi-nor-objs += catalyst.o + spi-nor-objs += eon.o + spi-nor-objs += esmt.o +--- /dev/null ++++ b/drivers/mtd/spi-nor/bohong.c +@@ -0,0 +1,21 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2005, Intec Automation Inc. ++ * Copyright (C) 2014, Freescale Semiconductor, Inc. ++ */ ++ ++#include ++ ++#include "core.h" ++ ++static const struct flash_info bohong_parts[] = { ++ /* BoHong Microelectronics */ ++ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, ++}; ++ ++const struct spi_nor_manufacturer spi_nor_bohong = { ++ .name = "bohong", ++ .parts = bohong_parts, ++ .nparts = ARRAY_SIZE(bohong_parts), ++}; +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -1832,6 +1832,7 @@ int spi_nor_sr2_bit7_quad_enable(struct + + static const struct spi_nor_manufacturer *manufacturers[] = { + &spi_nor_atmel, ++ &spi_nor_bohong, + &spi_nor_catalyst, + &spi_nor_eon, + &spi_nor_esmt, +--- a/drivers/mtd/spi-nor/core.h ++++ b/drivers/mtd/spi-nor/core.h +@@ -473,6 +473,7 @@ struct sfdp { + + /* Manufacturer drivers. */ + extern const struct spi_nor_manufacturer spi_nor_atmel; ++extern const struct spi_nor_manufacturer spi_nor_bohong; + extern const struct spi_nor_manufacturer spi_nor_catalyst; + extern const struct spi_nor_manufacturer spi_nor_eon; + extern const struct spi_nor_manufacturer spi_nor_esmt; diff --git a/target/linux/ramips/patches-5.15/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-5.15/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch new file mode 100644 index 0000000000..33a741e531 --- /dev/null +++ b/target/linux/ramips/patches-5.15/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch @@ -0,0 +1,47 @@ +From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 1 Apr 2020 02:07:58 +0800 +Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand + flash controller + +This patch adds NAND flash controller driver for MediaTek MT7621 SoC. + +The NAND flash controller is similar with controllers described in +mtk_nand.c, except that the controller from MT7621 doesn't support DMA +transmission, and some registers' offset and fields are different. + +Signed-off-by: Weijie Gao +--- + drivers/mtd/nand/raw/Kconfig | 8 + + drivers/mtd/nand/raw/Makefile | 1 + + drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 1357 insertions(+) + create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c + +--- a/drivers/mtd/nand/raw/Kconfig ++++ b/drivers/mtd/nand/raw/Kconfig +@@ -358,6 +358,14 @@ config MTD_NAND_QCOM + Enables support for NAND flash chips on SoCs containing the EBI2 NAND + controller. This controller is found on IPQ806x SoC. + ++config MTD_NAND_MT7621 ++ tristate "MT7621 NAND controller" ++ depends on SOC_MT7621 || COMPILE_TEST ++ depends on HAS_IOMEM ++ help ++ Enables support for NAND controller on MT7621 SoC. ++ This driver uses PIO mode for data transmission instead of DMA mode. ++ + config MTD_NAND_MTK + tristate "MTK NAND controller" + depends on ARCH_MEDIATEK || COMPILE_TEST +--- a/drivers/mtd/nand/raw/Makefile ++++ b/drivers/mtd/nand/raw/Makefile +@@ -48,6 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n + obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o + obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ + obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o ++obj-$(CONFIG_MTD_NAND_MT7621) += mt7621_nand.o + obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o + obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o + obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o diff --git a/target/linux/ramips/patches-5.15/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch b/target/linux/ramips/patches-5.15/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch new file mode 100644 index 0000000000..3d122c10c0 --- /dev/null +++ b/target/linux/ramips/patches-5.15/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch @@ -0,0 +1,85 @@ +From 3d5f4da8296b23eb3abf8b13122b0d06a215e79c Mon Sep 17 00:00:00 2001 +From: Weijie Gao +Date: Wed, 1 Apr 2020 02:07:59 +0800 +Subject: [PATCH 2/2] dt-bindings: add documentation for mt7621-nand driver + +This patch adds documentation for MediaTek MT7621 NAND flash controller +driver. + +Signed-off-by: Weijie Gao +--- + .../bindings/mtd/mediatek,mt7621-nfc.yaml | 68 ++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml +@@ -0,0 +1,68 @@ ++# SPDX-License-Identifier: GPL-2.0 ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/mtd/mediatek,mt7621-nfc.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: MediaTek MT7621 SoC NAND Flash Controller (NFC) DT binding ++ ++maintainers: ++ - Weijie Gao ++ ++description: | ++ This driver uses a single node to describe both NAND Flash controller ++ interface (NFI) and ECC engine for MT7621 SoC. ++ MT7621 supports only one chip select. ++ ++properties: ++ "#address-cells": false ++ "#size-cells": false ++ ++ compatible: ++ enum: ++ - mediatek,mt7621-nfc ++ ++ reg: ++ items: ++ - description: Register base of NFI core ++ - description: Register base of ECC engine ++ ++ reg-names: ++ items: ++ - const: nfi ++ - const: ecc ++ ++ clocks: ++ items: ++ - description: Source clock for NFI core, fixed 125MHz ++ ++ clock-names: ++ items: ++ - const: nfi_clk ++ ++required: ++ - compatible ++ - reg ++ - reg-names ++ - clocks ++ - clock-names ++ ++examples: ++ - | ++ nficlock: nficlock { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ ++ clock-frequency = <125000000>; ++ }; ++ ++ nand@1e003000 { ++ compatible = "mediatek,mt7621-nfc"; ++ ++ reg = <0x1e003000 0x800 ++ 0x1e003800 0x800>; ++ reg-names = "nfi", "ecc"; ++ ++ clocks = <&nficlock>; ++ clock-names = "nfi_clk"; ++ }; diff --git a/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch new file mode 100644 index 0000000000..954cd57b67 --- /dev/null +++ b/target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch @@ -0,0 +1,34 @@ +From bd0f89de5476ca25e73fae829ba3e1dafae1d90d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= +Date: Fri, 21 Jun 2019 10:04:05 +0200 +Subject: [PATCH] net: ethernet: mediatek: support net-labels + +With this patch, device name can be set within dts file in the same way as dsa +port can. +Add: label = "wan"; to GMAC node. + +Signed-off-by: René van Dorst +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2968,6 +2968,7 @@ static const struct net_device_ops mtk_n + + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) + { ++ const char *name = of_get_property(np, "label", NULL); + const __be32 *_id = of_get_property(np, "reg", NULL); + phy_interface_t phy_mode; + struct phylink *phylink; +@@ -3063,6 +3064,9 @@ static int mtk_add_mac(struct mtk_eth *e + else + eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; + ++ if (name) ++ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ); ++ + return 0; + + free_netdev: diff --git a/target/linux/ramips/patches-5.15/710-at803x.patch b/target/linux/ramips/patches-5.15/710-at803x.patch new file mode 100644 index 0000000000..202e67a605 --- /dev/null +++ b/target/linux/ramips/patches-5.15/710-at803x.patch @@ -0,0 +1,184 @@ +From 924453aa9d2324e5611f8e2b71df746d8f0c79f1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= +Date: Fri, 13 Nov 2020 16:11:32 +0100 +Subject: [PATCH] net: phy: at803x: add support for SFP module in + RGMII-to-x-base mode +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: René van Dorst +--- + drivers/net/phy/at803x.c | 91 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 91 insertions(+) + +--- a/drivers/net/phy/at803x.c ++++ b/drivers/net/phy/at803x.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + + #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 + #define AT803X_SFC_ASSERT_CRS BIT(11) +@@ -82,9 +84,18 @@ + + #define AT803X_MODE_CFG_MASK 0x0F + #define AT803X_MODE_CFG_SGMII 0x01 ++#define AT803X_MODE_CFG_BX1000_RGMII_50 0x02 ++#define AT803X_MODE_CFG_BX1000_RGMII_75 0x03 ++#define AT803X_MODE_FIBER 0x01 ++#define AT803X_MODE_COPPER 0x00 + + #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ + #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 ++#define PSSR_LINK BIT(10) ++#define PSSR_SYNC_STATUS BIT(8) ++#define PSSR_DUPLEX BIT(13) ++#define PSSR_SPEED_1000 BIT(15) ++#define PSSR_SPEED_100 BIT(14) + + #define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 + #define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) +@@ -652,12 +663,75 @@ static int at803x_parse_dt(struct phy_de + return 0; + } + ++static int at803x_mode(struct phy_device *phydev) ++{ ++ int mode; ++ ++ mode = phy_read(phydev, AT803X_REG_CHIP_CONFIG) & AT803X_MODE_CFG_MASK; ++ ++ if (mode == AT803X_MODE_CFG_BX1000_RGMII_50 || ++ mode == AT803X_MODE_CFG_BX1000_RGMII_75) ++ return AT803X_MODE_FIBER; ++ return AT803X_MODE_COPPER; ++} ++ ++static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) ++{ ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(at803x_support) = { 0, }; ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; ++ struct phy_device *phydev = upstream; ++ phy_interface_t iface; ++ ++ phylink_set(at803x_support, 1000baseX_Full); ++ /* AT803x only support 1000baseX but SGMII works fine when module runs ++ * at 1Gbit. ++ */ ++ phylink_set(at803x_support, 1000baseT_Full); ++ ++ sfp_parse_support(phydev->sfp_bus, id, support); ++ ++ // Limit to interfaces that both sides support ++ linkmode_and(support, support, at803x_support); ++ ++ if (linkmode_empty(support)) ++ goto unsupported_mode; ++ ++ iface = sfp_select_interface(phydev->sfp_bus, support); ++ ++ if (iface != PHY_INTERFACE_MODE_SGMII && ++ iface != PHY_INTERFACE_MODE_1000BASEX) ++ goto unsupported_mode; ++ ++ dev_info(&phydev->mdio.dev, "SFP interface %s", phy_modes(iface)); ++ ++ return 0; ++ ++unsupported_mode: ++ dev_info(&phydev->mdio.dev, "incompatible SFP module inserted;" ++ "Only SGMII at 1Gbit/1000BASEX are supported!\n"); ++ return -EINVAL; ++} ++ ++static const struct sfp_upstream_ops at803x_sfp_ops = { ++ .attach = phy_sfp_attach, ++ .detach = phy_sfp_detach, ++ .module_insert = at803x_sfp_insert, ++}; ++ ++ + static int at803x_probe(struct phy_device *phydev) + { + struct device *dev = &phydev->mdio.dev; + struct at803x_priv *priv; + int ret; + ++ ++ if (at803x_mode(phydev) == AT803X_MODE_FIBER) { ++ ret = phy_sfp_probe(phydev, &at803x_sfp_ops); ++ if (ret < 0) ++ return ret; ++ } ++ + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; +@@ -674,6 +748,7 @@ static int at803x_probe(struct phy_devic + return ret; + } + ++#if 0 + /* Some bootloaders leave the fiber page selected. + * Switch to the copper page, as otherwise we read + * the PHY capabilities from the fiber side. +@@ -685,6 +760,7 @@ static int at803x_probe(struct phy_devic + if (ret) + goto err; + } ++#endif + + return 0; + +@@ -711,6 +787,7 @@ static int at803x_get_features(struct ph + if (err) + return err; + ++#if 0 + if (phydev->drv->phy_id != ATH8031_PHY_ID) + return 0; + +@@ -728,6 +805,7 @@ static int at803x_get_features(struct ph + */ + linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, + phydev->supported); ++#endif + return 0; + } + +@@ -933,6 +1011,10 @@ static int at803x_read_status(struct phy + { + int ss, err, old_link = phydev->link; + ++ /* Handle (Fiber) SGMII to RGMII mode */ ++ if (at803x_mode(phydev) == AT803X_MODE_FIBER) ++ return genphy_c37_read_status(phydev); ++ + /* Update the link, but return if there was an error */ + err = genphy_update_link(phydev); + if (err) +@@ -1033,6 +1115,12 @@ static int at803x_config_aneg(struct phy + { + int ret; + ++ /* Handle (Fiber) SerDes to RGMII mode */ ++ if (at803x_mode(phydev) == AT803X_MODE_FIBER) { ++ pr_warn("%s: fiber\n", __func__); ++ return genphy_c37_config_aneg(phydev); ++ } ++ + ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); + if (ret < 0) + return ret; +@@ -1445,6 +1533,7 @@ static struct phy_driver at803x_driver[] + /* Qualcomm Atheros AR8031/AR8033 */ + PHY_ID_MATCH_EXACT(ATH8031_PHY_ID), + .name = "Qualcomm Atheros AR8031/AR8033", ++ .config_aneg = at803x_config_aneg, + .flags = PHY_POLL_CABLE_TEST, + .probe = at803x_probe, + .remove = at803x_remove, diff --git a/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch b/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch new file mode 100644 index 0000000000..b37d590475 --- /dev/null +++ b/target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch @@ -0,0 +1,118 @@ +From ffbb1b37a3e1ce1a5c574a6bd4f5aede8bc468ac Mon Sep 17 00:00:00 2001 +From: Ilya Lipnitskiy +Date: Sat, 27 Feb 2021 20:20:07 -0800 +Subject: [PATCH] Revert "net: phy: simplify phy_link_change arguments" + +This reverts commit a307593a644443db12888f45eed0dafb5869e2cc. + +This brings back the do_carrier flags used by the (hacky) next patch, +still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c +--- + drivers/net/phy/phy.c | 12 ++++++------ + drivers/net/phy/phy_device.c | 12 +++++++----- + drivers/net/phy/phylink.c | 3 ++- + include/linux/phy.h | 2 +- + 4 files changed, 16 insertions(+), 13 deletions(-) + +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -58,13 +58,13 @@ static const char *phy_state_to_str(enum + + static void phy_link_up(struct phy_device *phydev) + { +- phydev->phy_link_change(phydev, true); ++ phydev->phy_link_change(phydev, true, true); + phy_led_trigger_change_speed(phydev); + } + +-static void phy_link_down(struct phy_device *phydev) ++static void phy_link_down(struct phy_device *phydev, bool do_carrier) + { +- phydev->phy_link_change(phydev, false); ++ phydev->phy_link_change(phydev, false, do_carrier); + phy_led_trigger_change_speed(phydev); + } + +@@ -550,7 +550,7 @@ int phy_start_cable_test(struct phy_devi + goto out; + + /* Mark the carrier down until the test is complete */ +- phy_link_down(phydev); ++ phy_link_down(phydev, true); + + netif_testing_on(dev); + err = phydev->drv->cable_test_start(phydev); +@@ -621,7 +621,7 @@ int phy_start_cable_test_tdr(struct phy_ + goto out; + + /* Mark the carrier down until the test is complete */ +- phy_link_down(phydev); ++ phy_link_down(phydev, true); + + netif_testing_on(dev); + err = phydev->drv->cable_test_tdr_start(phydev, config); +@@ -693,7 +693,7 @@ static int phy_check_link_status(struct + phy_link_up(phydev); + } else if (!phydev->link && phydev->state != PHY_NOLINK) { + phydev->state = PHY_NOLINK; +- phy_link_down(phydev); ++ phy_link_down(phydev, true); + } + + return 0; +@@ -1149,7 +1149,7 @@ void phy_state_machine(struct work_struc + case PHY_HALTED: + if (phydev->link) { + phydev->link = 0; +- phy_link_down(phydev); ++ phy_link_down(phydev, true); + } + do_suspend = true; + break; +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1000,14 +1000,16 @@ struct phy_device *phy_find_first(struct + } + EXPORT_SYMBOL(phy_find_first); + +-static void phy_link_change(struct phy_device *phydev, bool up) ++static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier) + { + struct net_device *netdev = phydev->attached_dev; + +- if (up) +- netif_carrier_on(netdev); +- else +- netif_carrier_off(netdev); ++ if (do_carrier) { ++ if (up) ++ netif_carrier_on(netdev); ++ else ++ netif_carrier_off(netdev); ++ } + phydev->adjust_link(netdev); + if (phydev->mii_ts && phydev->mii_ts->link_state) + phydev->mii_ts->link_state(phydev->mii_ts, phydev); +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -946,7 +946,8 @@ void phylink_destroy(struct phylink *pl) + } + EXPORT_SYMBOL_GPL(phylink_destroy); + +-static void phylink_phy_change(struct phy_device *phydev, bool up) ++static void phylink_phy_change(struct phy_device *phydev, bool up, ++ bool do_carrier) + { + struct phylink *pl = phydev->phylink; + bool tx_pause, rx_pause; +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -663,7 +663,7 @@ struct phy_device { + u8 mdix; + u8 mdix_ctrl; + +- void (*phy_link_change)(struct phy_device *phydev, bool up); ++ void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier); + void (*adjust_link)(struct net_device *dev); + + #if IS_ENABLED(CONFIG_MACSEC) diff --git a/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch new file mode 100644 index 0000000000..90d5dfadcb --- /dev/null +++ b/target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch @@ -0,0 +1,47 @@ +From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jul 2014 09:38:50 +0100 +Subject: [PATCH 34/53] NET: multi phy support + +Signed-off-by: John Crispin +--- + drivers/net/phy/phy.c | 9 ++++++--- + include/linux/phy.h | 1 + + 2 files changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -693,7 +693,10 @@ static int phy_check_link_status(struct + phy_link_up(phydev); + } else if (!phydev->link && phydev->state != PHY_NOLINK) { + phydev->state = PHY_NOLINK; +- phy_link_down(phydev, true); ++ if (!phydev->no_auto_carrier_off) ++ phy_link_down(phydev, true); ++ else ++ phy_link_down(phydev, false); + } + + return 0; +@@ -1149,7 +1152,10 @@ void phy_state_machine(struct work_struc + case PHY_HALTED: + if (phydev->link) { + phydev->link = 0; +- phy_link_down(phydev, true); ++ if (!phydev->no_auto_carrier_off) ++ phy_link_down(phydev, true); ++ else ++ phy_link_down(phydev, false); + } + do_suspend = true; + break; +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -582,6 +582,7 @@ struct phy_device { + unsigned downshifted_rate:1; + unsigned is_on_sfp_module:1; + unsigned mac_managed_pm:1; ++ unsigned no_auto_carrier_off:1; + + unsigned autoneg:1; + /* The most recently read link state */ diff --git a/target/linux/ramips/patches-5.15/801-DT-Add-documentation-for-gpio-ralink.patch b/target/linux/ramips/patches-5.15/801-DT-Add-documentation-for-gpio-ralink.patch new file mode 100644 index 0000000000..93dabf8776 --- /dev/null +++ b/target/linux/ramips/patches-5.15/801-DT-Add-documentation-for-gpio-ralink.patch @@ -0,0 +1,59 @@ +From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 28 Jul 2013 19:45:30 +0200 +Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink + +Describe gpio-ralink binding. + +Signed-off-by: John Crispin +Cc: linux-mips@linux-mips.org +Cc: devicetree@vger.kernel.org +Cc: linux-gpio@vger.kernel.org +--- + .../devicetree/bindings/gpio/gpio-ralink.txt | 40 ++++++++++++++++++++ + 1 file changed, 40 insertions(+) + create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt +@@ -0,0 +1,40 @@ ++Ralink SoC GPIO controller bindings ++ ++Required properties: ++- compatible: ++ - "ralink,rt2880-gpio" for Ralink controllers ++- #gpio-cells : Should be two. ++ - first cell is the pin number ++ - second cell is used to specify optional parameters (unused) ++- gpio-controller : Marks the device node as a GPIO controller ++- reg : Physical base address and length of the controller's registers ++- interrupt-parent: phandle to the INTC device node ++- interrupts : Specify the INTC interrupt number ++- ngpios : Specify the number of GPIOs ++- ralink,register-map : The register layout depends on the GPIO bank and actual ++ SoC type. Register offsets need to be in this order. ++ [ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ] ++ ++Optional properties: ++- ralink,gpio-base : Specify the GPIO chips base number ++ ++Example: ++ ++ gpio0: gpio@600 { ++ compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio"; ++ ++ #gpio-cells = <2>; ++ gpio-controller; ++ ++ reg = <0x600 0x34>; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <6>; ++ ++ ngpios = <24>; ++ ralink,gpio-base = <0>; ++ ralink,register-map = [ 00 04 08 0c ++ 20 24 28 2c ++ 30 34 ]; ++ ++ }; diff --git a/target/linux/ramips/patches-5.15/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-5.15/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch new file mode 100644 index 0000000000..02fafbdc9b --- /dev/null +++ b/target/linux/ramips/patches-5.15/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch @@ -0,0 +1,416 @@ +From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 4 Aug 2014 20:36:29 +0200 +Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC + +Add gpio driver for Ralink SoC. This driver makes the gpio core on +RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work. + +Signed-off-by: John Crispin +Cc: linux-mips@linux-mips.org +Cc: linux-gpio@vger.kernel.org +--- + arch/mips/include/asm/mach-ralink/gpio.h | 24 ++ + drivers/gpio/Kconfig | 6 + + drivers/gpio/Makefile | 1 + + drivers/gpio/gpio-ralink.c | 355 ++++++++++++++++++++++++++++++ + 4 files changed, 386 insertions(+) + create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h + create mode 100644 drivers/gpio/gpio-ralink.c + +--- /dev/null ++++ b/arch/mips/include/asm/mach-ralink/gpio.h +@@ -0,0 +1,24 @@ ++/* ++ * Ralink SoC GPIO API support ++ * ++ * Copyright (C) 2008-2009 Gabor Juhos ++ * Copyright (C) 2008 Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef __ASM_MACH_RALINK_GPIO_H ++#define __ASM_MACH_RALINK_GPIO_H ++ ++#define ARCH_NR_GPIOS 128 ++#include ++ ++#define gpio_get_value __gpio_get_value ++#define gpio_set_value __gpio_set_value ++#define gpio_cansleep __gpio_cansleep ++#define gpio_to_irq __gpio_to_irq ++ ++#endif /* __ASM_MACH_RALINK_GPIO_H */ +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -569,6 +569,12 @@ config GPIO_SNPS_CREG + where only several fields in register belong to GPIO lines and + each GPIO line owns a field with different length and on/off value. + ++config GPIO_RALINK ++ bool "Ralink GPIO Support" ++ depends on RALINK ++ help ++ Say yes here to support the Ralink SoC GPIO device ++ + config GPIO_SPEAR_SPICS + bool "ST SPEAr13xx SPI Chip Select as GPIO support" + depends on PLAT_SPEAR +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -121,6 +121,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisos + obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o + obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o + obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o ++obj-$(CONFIG_GPIO_RALINK) += gpio-ralink.o + obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o + obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o + obj-$(CONFIG_GPIO_RCAR) += gpio-rcar.o +--- /dev/null ++++ b/drivers/gpio/gpio-ralink.c +@@ -0,0 +1,341 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2009-2011 Gabor Juhos ++ * Copyright (C) 2013 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum ralink_gpio_reg { ++ GPIO_REG_INT = 0, ++ GPIO_REG_EDGE, ++ GPIO_REG_RENA, ++ GPIO_REG_FENA, ++ GPIO_REG_DATA, ++ GPIO_REG_DIR, ++ GPIO_REG_POL, ++ GPIO_REG_SET, ++ GPIO_REG_RESET, ++ GPIO_REG_TOGGLE, ++ GPIO_REG_MAX ++}; ++ ++struct ralink_gpio_chip { ++ struct gpio_chip chip; ++ u8 regs[GPIO_REG_MAX]; ++ ++ spinlock_t lock; ++ void __iomem *membase; ++ struct irq_domain *domain; ++ int irq; ++ ++ u32 rising; ++ u32 falling; ++}; ++ ++#define MAP_MAX 4 ++static struct irq_domain *irq_map[MAP_MAX]; ++static int irq_map_count; ++static atomic_t irq_refcount = ATOMIC_INIT(0); ++ ++static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip) ++{ ++ struct ralink_gpio_chip *rg; ++ ++ rg = container_of(chip, struct ralink_gpio_chip, chip); ++ ++ return rg; ++} ++ ++static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val) ++{ ++ iowrite32(val, rg->membase + rg->regs[reg]); ++} ++ ++static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg) ++{ ++ return ioread32(rg->membase + rg->regs[reg]); ++} ++ ++static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ ++ rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset)); ++} ++ ++static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ ++ return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset)); ++} ++ ++static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ unsigned long flags; ++ u32 t; ++ ++ spin_lock_irqsave(&rg->lock, flags); ++ t = rt_gpio_r32(rg, GPIO_REG_DIR); ++ t &= ~BIT(offset); ++ rt_gpio_w32(rg, GPIO_REG_DIR, t); ++ spin_unlock_irqrestore(&rg->lock, flags); ++ ++ return 0; ++} ++ ++static int ralink_gpio_direction_output(struct gpio_chip *chip, ++ unsigned offset, int value) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ unsigned long flags; ++ u32 t; ++ ++ spin_lock_irqsave(&rg->lock, flags); ++ ralink_gpio_set(chip, offset, value); ++ t = rt_gpio_r32(rg, GPIO_REG_DIR); ++ t |= BIT(offset); ++ rt_gpio_w32(rg, GPIO_REG_DIR, t); ++ spin_unlock_irqrestore(&rg->lock, flags); ++ ++ return 0; ++} ++ ++static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin) ++{ ++ struct ralink_gpio_chip *rg = to_ralink_gpio(chip); ++ ++ if (rg->irq < 1) ++ return -1; ++ ++ return irq_create_mapping(rg->domain, pin); ++} ++ ++static void ralink_gpio_irq_handler(struct irq_desc *desc) ++{ ++ int i; ++ ++ for (i = 0; i < irq_map_count; i++) { ++ struct irq_domain *domain = irq_map[i]; ++ struct ralink_gpio_chip *rg; ++ unsigned long pending; ++ int bit; ++ ++ rg = (struct ralink_gpio_chip *) domain->host_data; ++ pending = rt_gpio_r32(rg, GPIO_REG_INT); ++ ++ for_each_set_bit(bit, &pending, rg->chip.ngpio) { ++ u32 map = irq_find_mapping(domain, bit); ++ generic_handle_irq(map); ++ rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit)); ++ } ++ } ++} ++ ++static void ralink_gpio_irq_unmask(struct irq_data *d) ++{ ++ struct ralink_gpio_chip *rg; ++ unsigned long flags; ++ u32 rise, fall; ++ ++ rg = (struct ralink_gpio_chip *) d->domain->host_data; ++ rise = rt_gpio_r32(rg, GPIO_REG_RENA); ++ fall = rt_gpio_r32(rg, GPIO_REG_FENA); ++ ++ spin_lock_irqsave(&rg->lock, flags); ++ rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising)); ++ rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling)); ++ spin_unlock_irqrestore(&rg->lock, flags); ++} ++ ++static void ralink_gpio_irq_mask(struct irq_data *d) ++{ ++ struct ralink_gpio_chip *rg; ++ unsigned long flags; ++ u32 rise, fall; ++ ++ rg = (struct ralink_gpio_chip *) d->domain->host_data; ++ rise = rt_gpio_r32(rg, GPIO_REG_RENA); ++ fall = rt_gpio_r32(rg, GPIO_REG_FENA); ++ ++ spin_lock_irqsave(&rg->lock, flags); ++ rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq)); ++ rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq)); ++ spin_unlock_irqrestore(&rg->lock, flags); ++} ++ ++static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type) ++{ ++ struct ralink_gpio_chip *rg; ++ u32 mask = BIT(d->hwirq); ++ ++ rg = (struct ralink_gpio_chip *) d->domain->host_data; ++ ++ if (type == IRQ_TYPE_PROBE) { ++ if ((rg->rising | rg->falling) & mask) ++ return 0; ++ ++ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; ++ } ++ ++ if (type & IRQ_TYPE_EDGE_RISING) ++ rg->rising |= mask; ++ else ++ rg->rising &= ~mask; ++ ++ if (type & IRQ_TYPE_EDGE_FALLING) ++ rg->falling |= mask; ++ else ++ rg->falling &= ~mask; ++ ++ return 0; ++} ++ ++static struct irq_chip ralink_gpio_irq_chip = { ++ .name = "GPIO", ++ .irq_unmask = ralink_gpio_irq_unmask, ++ .irq_mask = ralink_gpio_irq_mask, ++ .irq_mask_ack = ralink_gpio_irq_mask, ++ .irq_set_type = ralink_gpio_irq_type, ++}; ++ ++static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) ++{ ++ irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq); ++ irq_set_handler_data(irq, d); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops irq_domain_ops = { ++ .xlate = irq_domain_xlate_onecell, ++ .map = gpio_map, ++}; ++ ++static void ralink_gpio_irq_init(struct device_node *np, ++ struct ralink_gpio_chip *rg) ++{ ++ if (irq_map_count >= MAP_MAX) ++ return; ++ ++ rg->irq = irq_of_parse_and_map(np, 0); ++ if (!rg->irq) ++ return; ++ ++ rg->domain = irq_domain_add_linear(np, rg->chip.ngpio, ++ &irq_domain_ops, rg); ++ if (!rg->domain) { ++ dev_err(rg->chip.parent, "irq_domain_add_linear failed\n"); ++ return; ++ } ++ ++ irq_map[irq_map_count++] = rg->domain; ++ ++ rt_gpio_w32(rg, GPIO_REG_RENA, 0x0); ++ rt_gpio_w32(rg, GPIO_REG_FENA, 0x0); ++ ++ if (!atomic_read(&irq_refcount)) ++ irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler); ++ atomic_inc(&irq_refcount); ++ ++ dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio); ++} ++ ++static int ralink_gpio_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ struct ralink_gpio_chip *rg; ++ const __be32 *ngpio, *gpiobase; ++ ++ if (!res) { ++ dev_err(&pdev->dev, "failed to find resource\n"); ++ return -ENOMEM; ++ } ++ ++ rg = devm_kzalloc(&pdev->dev, ++ sizeof(struct ralink_gpio_chip), GFP_KERNEL); ++ if (!rg) ++ return -ENOMEM; ++ ++ rg->membase = devm_ioremap_resource(&pdev->dev, res); ++ if (!rg->membase) { ++ dev_err(&pdev->dev, "cannot remap I/O memory region\n"); ++ return -ENOMEM; ++ } ++ ++ if (of_property_read_u8_array(np, "ralink,register-map", ++ rg->regs, GPIO_REG_MAX)) { ++ dev_err(&pdev->dev, "failed to read register definition\n"); ++ return -EINVAL; ++ } ++ ++ ngpio = of_get_property(np, "ngpios", NULL); ++ if (!ngpio) { ++ dev_err(&pdev->dev, "failed to read number of pins\n"); ++ return -EINVAL; ++ } ++ ++ gpiobase = of_get_property(np, "ralink,gpio-base", NULL); ++ if (gpiobase) ++ rg->chip.base = be32_to_cpu(*gpiobase); ++ else ++ rg->chip.base = -1; ++ ++ spin_lock_init(&rg->lock); ++ ++ rg->chip.parent = &pdev->dev; ++ rg->chip.label = dev_name(&pdev->dev); ++ rg->chip.of_node = np; ++ rg->chip.ngpio = be32_to_cpu(*ngpio); ++ rg->chip.direction_input = ralink_gpio_direction_input; ++ rg->chip.direction_output = ralink_gpio_direction_output; ++ rg->chip.get = ralink_gpio_get; ++ rg->chip.set = ralink_gpio_set; ++ rg->chip.request = gpiochip_generic_request; ++ rg->chip.to_irq = ralink_gpio_to_irq; ++ rg->chip.free = gpiochip_generic_free; ++ ++ /* set polarity to low for all lines */ ++ rt_gpio_w32(rg, GPIO_REG_POL, 0); ++ ++ dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio); ++ ++ ralink_gpio_irq_init(np, rg); ++ ++ return gpiochip_add(&rg->chip); ++} ++ ++static const struct of_device_id ralink_gpio_match[] = { ++ { .compatible = "ralink,rt2880-gpio" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_gpio_match); ++ ++static struct platform_driver ralink_gpio_driver = { ++ .probe = ralink_gpio_probe, ++ .driver = { ++ .name = "rt2880_gpio", ++ .owner = THIS_MODULE, ++ .of_match_table = ralink_gpio_match, ++ }, ++}; ++ ++static int __init ralink_gpio_init(void) ++{ ++ return platform_driver_register(&ralink_gpio_driver); ++} ++ ++subsys_initcall(ralink_gpio_init); diff --git a/target/linux/ramips/patches-5.15/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch b/target/linux/ramips/patches-5.15/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch new file mode 100644 index 0000000000..8520ce32ff --- /dev/null +++ b/target/linux/ramips/patches-5.15/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch @@ -0,0 +1,44 @@ +From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001 +From: Daniel Santos +Date: Sun, 4 Nov 2018 20:24:32 -0600 +Subject: gpio-ralink: Add support for GPIO as interrupt-controller + +Signed-off-by: Daniel Santos +--- + Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++ + drivers/gpio/gpio-ralink.c | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt ++++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt +@@ -17,6 +17,9 @@ Required properties: + + Optional properties: + - ralink,gpio-base : Specify the GPIO chips base number ++- interrupt-controller : marks this as an interrupt controller ++- #interrupt-cells : a standard two-cell interrupt flag, see ++ interrupt-controller/interrupts.txt + + Example: + +@@ -28,6 +31,9 @@ Example: + + reg = <0x600 0x34>; + ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ + interrupt-parent = <&intc>; + interrupts = <6>; + +--- a/drivers/gpio/gpio-ralink.c ++++ b/drivers/gpio/gpio-ralink.c +@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d + } + + static const struct irq_domain_ops irq_domain_ops = { +- .xlate = irq_domain_xlate_onecell, ++ .xlate = irq_domain_xlate_twocell, + .map = gpio_map, + }; + diff --git a/target/linux/ramips/patches-5.15/805-pinctrl-AW9523.patch b/target/linux/ramips/patches-5.15/805-pinctrl-AW9523.patch new file mode 100644 index 0000000000..34220acdd1 --- /dev/null +++ b/target/linux/ramips/patches-5.15/805-pinctrl-AW9523.patch @@ -0,0 +1,72 @@ +From: AngeloGioacchino Del Regno + +To: linus.walleij@linaro.org +Cc: linux-kernel@vger.kernel.org, konrad.dybcio@somainline.org, + marijn.suijten@somainline.org, martin.botka@somainline.org, + phone-devel@vger.kernel.org, linux-gpio@vger.kernel.org, + devicetree@vger.kernel.org, robh+dt@kernel.org, + AngeloGioacchino Del Regno + +Subject: [PATCH v5 1/2] pinctrl: Add driver for Awinic AW9523/B I2C GPIO + Expander +Date: Mon, 25 Jan 2021 19:22:18 +0100 + +The Awinic AW9523(B) is a multi-function I2C gpio expander in a +TQFN-24L package, featuring PWM (max 37mA per pin, or total max +power 3.2Watts) for LED driving capability. + +It has two ports with 8 pins per port (for a total of 16 pins), +configurable as either PWM with 1/256 stepping or GPIO input/output, +1.8V logic input; each GPIO can be configured as input or output +independently from each other. + +This IC also has an internal interrupt controller, which is capable +of generating an interrupt for each GPIO, depending on the +configuration, and will raise an interrupt on the INTN pin to +advertise this to an external interrupt controller. + +Signed-off-by: AngeloGioacchino Del Regno +--- + drivers/pinctrl/Kconfig | 17 + + drivers/pinctrl/Makefile | 1 + + drivers/pinctrl/pinctrl-aw9523.c | 1122 ++++++++++++++++++++++++++++++ + 3 files changed, 1140 insertions(+) + create mode 100644 drivers/pinctrl/pinctrl-aw9523.c + +--- a/drivers/pinctrl/Kconfig ++++ b/drivers/pinctrl/Kconfig +@@ -111,6 +111,24 @@ config PINCTRL_AMD + Requires ACPI/FDT device enumeration code to set up a platform + device. + ++config PINCTRL_AW9523 ++ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver" ++ depends on OF && I2C ++ select PINMUX ++ select PINCONF ++ select GENERIC_PINCONF ++ select GPIOLIB ++ select GPIOLIB_IRQCHIP ++ select REGMAP ++ select REGMAP_I2C ++ help ++ The Awinic AW9523/AW9523B is a multi-function I2C GPIO ++ expander with PWM functionality. This driver bundles a ++ pinctrl driver to select the function muxing and a GPIO ++ driver to handle GPIO, when the GPIO function is selected. ++ ++ Say yes to enable pinctrl and GPIO support for the AW9523(B). ++ + config PINCTRL_BM1880 + bool "Bitmain BM1880 Pinctrl driver" + depends on OF && (ARCH_BITMAIN || COMPILE_TEST) +--- a/drivers/pinctrl/Makefile ++++ b/drivers/pinctrl/Makefile +@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_AXP209) += pinctrl- + obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o + obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o + obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o ++obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o + obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o + obj-$(CONFIG_PINCTRL_DA850_PUPD) += pinctrl-da850-pupd.o + obj-$(CONFIG_PINCTRL_DA9062) += pinctrl-da9062.o diff --git a/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch new file mode 100644 index 0000000000..ae7e886f94 --- /dev/null +++ b/target/linux/ramips/patches-5.15/810-uvc-add-iPassion-iP2970-support.patch @@ -0,0 +1,246 @@ +From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 19 Sep 2013 01:50:59 +0200 +Subject: [PATCH 31/53] uvc: add iPassion iP2970 support + +Signed-off-by: John Crispin +--- + drivers/media/usb/uvc/uvc_driver.c | 12 +++ + drivers/media/usb/uvc/uvc_status.c | 2 + + drivers/media/usb/uvc/uvc_video.c | 147 ++++++++++++++++++++++++++++++++++++ + drivers/media/usb/uvc/uvcvideo.h | 5 +- + 4 files changed, 165 insertions(+), 1 deletion(-) + +--- a/drivers/media/usb/uvc/uvc_driver.c ++++ b/drivers/media/usb/uvc/uvc_driver.c +@@ -3164,6 +3164,18 @@ static const struct usb_device_id uvc_id + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, ++ /* iPassion iP2970 */ ++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE ++ | USB_DEVICE_ID_MATCH_INT_INFO, ++ .idVendor = 0x1B3B, ++ .idProduct = 0x2970, ++ .bInterfaceClass = USB_CLASS_VIDEO, ++ .bInterfaceSubClass = 1, ++ .bInterfaceProtocol = 0, ++ .driver_info = UVC_QUIRK_PROBE_MINMAX ++ | UVC_QUIRK_STREAM_NO_FID ++ | UVC_QUIRK_MOTION ++ | UVC_QUIRK_SINGLE_ISO }, + /* Generic USB Video Class */ + { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) }, + { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) }, +--- a/drivers/media/usb/uvc/uvc_status.c ++++ b/drivers/media/usb/uvc/uvc_status.c +@@ -223,6 +223,7 @@ static void uvc_status_complete(struct u + if (uvc_event_control(urb, status, len)) + /* The URB will be resubmitted in work context. */ + return; ++ dev->motion = 1; + break; + } + +@@ -271,6 +272,7 @@ int uvc_status_init(struct uvc_device *d + } + + pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress); ++ dev->motion = 0; + + /* For high-speed interrupt endpoints, the bInterval value is used as + * an exponent of two. Some developers forgot about it. +--- a/drivers/media/usb/uvc/uvc_video.c ++++ b/drivers/media/usb/uvc/uvc_video.c +@@ -19,6 +19,11 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include + + #include + +@@ -1214,9 +1219,149 @@ static void uvc_video_decode_data(struct + uvc_urb->async_operations++; + } + ++struct bh_priv { ++ unsigned long seen; ++}; ++ ++struct bh_event { ++ const char *name; ++ struct sk_buff *skb; ++ struct work_struct work; ++}; ++ ++#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args ) ++#define BH_DBG(fmt, args...) do {} while (0) ++#define BH_SKB_SIZE 2048 ++ ++extern u64 uevent_next_seqnum(void); ++static int seen = 0; ++ ++static int bh_event_add_var(struct bh_event *event, int argv, ++ const char *format, ...) ++{ ++ static char buf[128]; ++ char *s; ++ va_list args; ++ int len; ++ ++ if (argv) ++ return 0; ++ ++ va_start(args, format); ++ len = vsnprintf(buf, sizeof(buf), format, args); ++ va_end(args); ++ ++ if (len >= sizeof(buf)) { ++ BH_ERR("buffer size too small\n"); ++ WARN_ON(1); ++ return -ENOMEM; ++ } ++ ++ s = skb_put(event->skb, len + 1); ++ strcpy(s, buf); ++ ++ BH_DBG("added variable '%s'\n", s); ++ ++ return 0; ++} ++ ++static int motion_hotplug_fill_event(struct bh_event *event) ++{ ++ int s = jiffies; ++ int ret; ++ ++ if (!seen) ++ seen = jiffies; ++ ++ ret = bh_event_add_var(event, 0, "HOME=%s", "/"); ++ if (ret) ++ return ret; ++ ++ ret = bh_event_add_var(event, 0, "PATH=%s", ++ "/sbin:/bin:/usr/sbin:/usr/bin"); ++ if (ret) ++ return ret; ++ ++ ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb"); ++ if (ret) ++ return ret; ++ ++ ret = bh_event_add_var(event, 0, "ACTION=motion"); ++ if (ret) ++ return ret; ++ ++ ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen); ++ if (ret) ++ return ret; ++ seen = s; ++ ++ ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum()); ++ ++ return ret; ++} ++ ++static void motion_hotplug_work(struct work_struct *work) ++{ ++ struct bh_event *event = container_of(work, struct bh_event, work); ++ int ret = 0; ++ ++ event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL); ++ if (!event->skb) ++ goto out_free_event; ++ ++ ret = bh_event_add_var(event, 0, "%s@", "add"); ++ if (ret) ++ goto out_free_skb; ++ ++ ret = motion_hotplug_fill_event(event); ++ if (ret) ++ goto out_free_skb; ++ ++ NETLINK_CB(event->skb).dst_group = 1; ++ broadcast_uevent(event->skb, 0, 1, GFP_KERNEL); ++ ++out_free_skb: ++ if (ret) { ++ BH_ERR("work error %d\n", ret); ++ kfree_skb(event->skb); ++ } ++out_free_event: ++ kfree(event); ++} ++ ++static int motion_hotplug_create_event(void) ++{ ++ struct bh_event *event; ++ ++ event = kzalloc(sizeof(*event), GFP_KERNEL); ++ if (!event) ++ return -ENOMEM; ++ ++ event->name = "motion"; ++ ++ INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work); ++ schedule_work(&event->work); ++ ++ return 0; ++} ++ ++#define MOTION_FLAG_OFFSET 4 + static void uvc_video_decode_end(struct uvc_streaming *stream, + struct uvc_buffer *buf, const u8 *data, int len) + { ++ if ((stream->dev->quirks & UVC_QUIRK_MOTION) && ++ (data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) { ++ u8 *mem; ++ buf->state = UVC_BUF_STATE_READY; ++ mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET); ++ if ( stream->dev->motion ) { ++ stream->dev->motion = 0; ++ motion_hotplug_create_event(); ++ } else { ++ *mem &= 0x7f; ++ } ++ } ++ + /* Mark the buffer as done if the EOF marker is set. */ + if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { + uvc_dbg(stream->dev, FRAME, "Frame complete (EOF found)\n"); +@@ -1799,6 +1944,8 @@ static int uvc_init_video_isoc(struct uv + if (npackets == 0) + return -ENOMEM; + ++ if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO) ++ npackets = 1; + size = npackets * psize; + + for_each_uvc_urb(uvc_urb, stream) { +--- a/drivers/media/usb/uvc/uvcvideo.h ++++ b/drivers/media/usb/uvc/uvcvideo.h +@@ -209,7 +209,9 @@ + #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 + #define UVC_QUIRK_FORCE_Y8 0x00000800 + #define UVC_QUIRK_FORCE_BPP 0x00001000 +- ++#define UVC_QUIRK_MOTION 0x00001000 ++#define UVC_QUIRK_SINGLE_ISO 0x00002000 ++ + /* Format flags */ + #define UVC_FMT_FLAG_COMPRESSED 0x00000001 + #define UVC_FMT_FLAG_STREAM 0x00000002 +@@ -700,6 +702,7 @@ struct uvc_device { + u8 *status; + struct input_dev *input; + char input_phys[64]; ++ int motion; + + struct uvc_ctrl_work { + struct work_struct work; diff --git a/target/linux/ramips/patches-5.15/820-DT-Add-documentation-for-spi-rt2880.patch b/target/linux/ramips/patches-5.15/820-DT-Add-documentation-for-spi-rt2880.patch new file mode 100644 index 0000000000..e2643e3f25 --- /dev/null +++ b/target/linux/ramips/patches-5.15/820-DT-Add-documentation-for-spi-rt2880.patch @@ -0,0 +1,44 @@ +From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 9 Aug 2013 20:12:59 +0200 +Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880 + +Describe the SPI master found on the MIPS based Ralink RT2880 SoC. + +Signed-off-by: John Crispin +--- + .../devicetree/bindings/spi/spi-rt2880.txt | 28 ++++++++++++++++++++ + 1 file changed, 28 insertions(+) + create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt + +--- /dev/null ++++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt +@@ -0,0 +1,28 @@ ++Ralink SoC RT2880 SPI master controller. ++ ++This SPI controller is found on most wireless SoCs made by ralink. ++ ++Required properties: ++- compatible : "ralink,rt2880-spi" ++- reg : The register base for the controller. ++- #address-cells : <1>, as required by generic SPI binding. ++- #size-cells : <0>, also as required by generic SPI binding. ++ ++Child nodes as per the generic SPI binding. ++ ++Example: ++ ++ spi@b00 { ++ compatible = "ralink,rt2880-spi"; ++ reg = <0xb00 0x100>; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ m25p80@0 { ++ compatible = "m25p80"; ++ reg = <0>; ++ spi-max-frequency = <10000000>; ++ }; ++ }; ++ diff --git a/target/linux/ramips/patches-5.15/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-5.15/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch new file mode 100644 index 0000000000..342350d0c6 --- /dev/null +++ b/target/linux/ramips/patches-5.15/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch @@ -0,0 +1,574 @@ +From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jul 2014 11:15:12 +0100 +Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver + +Add the driver needed to make SPI work on Ralink SoC. + +Signed-off-by: Gabor Juhos +Acked-by: John Crispin +--- + drivers/spi/Kconfig | 6 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-rt2880.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 537 insertions(+) + create mode 100644 drivers/spi/spi-rt2880.c + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -719,6 +719,12 @@ config SPI_QCOM_GENI + This driver can also be built as a module. If so, the module + will be called spi-geni-qcom. + ++config SPI_RT2880 ++ tristate "Ralink RT288x SPI Controller" ++ depends on RALINK ++ help ++ This selects a driver for the Ralink RT288x/RT305x SPI Controller. ++ + config SPI_S3C24XX + tristate "Samsung S3C24XX series SPI" + depends on ARCH_S3C24XX +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -100,6 +100,7 @@ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o + obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o + obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o + obj-$(CONFIG_SPI_RSPI) += spi-rspi.o ++obj-$(CONFIG_SPI_RT2880) += spi-rt2880.o + obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o + spi-s3c24xx-hw-y := spi-s3c24xx.o + obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o +--- /dev/null ++++ b/drivers/spi/spi-rt2880.c +@@ -0,0 +1,530 @@ ++/* ++ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver ++ * ++ * Copyright (C) 2011 Sergiy ++ * Copyright (C) 2011-2013 Gabor Juhos ++ * ++ * Some parts are based on spi-orion.c: ++ * Author: Shadi Ammouri ++ * Copyright (C) 2007-2008 Marvell Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "spi-rt2880" ++ ++#define RAMIPS_SPI_STAT 0x00 ++#define RAMIPS_SPI_CFG 0x10 ++#define RAMIPS_SPI_CTL 0x14 ++#define RAMIPS_SPI_DATA 0x20 ++#define RAMIPS_SPI_ADDR 0x24 ++#define RAMIPS_SPI_BS 0x28 ++#define RAMIPS_SPI_USER 0x2C ++#define RAMIPS_SPI_TXFIFO 0x30 ++#define RAMIPS_SPI_RXFIFO 0x34 ++#define RAMIPS_SPI_FIFO_STAT 0x38 ++#define RAMIPS_SPI_MODE 0x3C ++#define RAMIPS_SPI_DEV_OFFSET 0x40 ++#define RAMIPS_SPI_DMA 0x80 ++#define RAMIPS_SPI_DMASTAT 0x84 ++#define RAMIPS_SPI_ARBITER 0xF0 ++ ++/* SPISTAT register bit field */ ++#define SPISTAT_BUSY BIT(0) ++ ++/* SPICFG register bit field */ ++#define SPICFG_ADDRMODE BIT(12) ++#define SPICFG_RXENVDIS BIT(11) ++#define SPICFG_RXCAP BIT(10) ++#define SPICFG_SPIENMODE BIT(9) ++#define SPICFG_MSBFIRST BIT(8) ++#define SPICFG_SPICLKPOL BIT(6) ++#define SPICFG_RXCLKEDGE_FALLING BIT(5) ++#define SPICFG_TXCLKEDGE_FALLING BIT(4) ++#define SPICFG_HIZSPI BIT(3) ++#define SPICFG_SPICLK_PRESCALE_MASK 0x7 ++#define SPICFG_SPICLK_DIV2 0 ++#define SPICFG_SPICLK_DIV4 1 ++#define SPICFG_SPICLK_DIV8 2 ++#define SPICFG_SPICLK_DIV16 3 ++#define SPICFG_SPICLK_DIV32 4 ++#define SPICFG_SPICLK_DIV64 5 ++#define SPICFG_SPICLK_DIV128 6 ++#define SPICFG_SPICLK_DISABLE 7 ++ ++/* SPICTL register bit field */ ++#define SPICTL_START BIT(4) ++#define SPICTL_HIZSDO BIT(3) ++#define SPICTL_STARTWR BIT(2) ++#define SPICTL_STARTRD BIT(1) ++#define SPICTL_SPIENA BIT(0) ++ ++/* SPIUSER register bit field */ ++#define SPIUSER_USERMODE BIT(21) ++#define SPIUSER_INSTR_PHASE BIT(20) ++#define SPIUSER_ADDR_PHASE_MASK 0x7 ++#define SPIUSER_ADDR_PHASE_OFFSET 17 ++#define SPIUSER_MODE_PHASE BIT(16) ++#define SPIUSER_DUMMY_PHASE_MASK 0x3 ++#define SPIUSER_DUMMY_PHASE_OFFSET 14 ++#define SPIUSER_DATA_PHASE_MASK 0x3 ++#define SPIUSER_DATA_PHASE_OFFSET 12 ++#define SPIUSER_DATA_READ (BIT(0) << SPIUSER_DATA_PHASE_OFFSET) ++#define SPIUSER_DATA_WRITE (BIT(1) << SPIUSER_DATA_PHASE_OFFSET) ++#define SPIUSER_ADDR_TYPE_OFFSET 9 ++#define SPIUSER_MODE_TYPE_OFFSET 6 ++#define SPIUSER_DUMMY_TYPE_OFFSET 3 ++#define SPIUSER_DATA_TYPE_OFFSET 0 ++#define SPIUSER_TRANSFER_MASK 0x7 ++#define SPIUSER_TRANSFER_SINGLE BIT(0) ++#define SPIUSER_TRANSFER_DUAL BIT(1) ++#define SPIUSER_TRANSFER_QUAD BIT(2) ++ ++#define SPIUSER_TRANSFER_TYPE(type) ( \ ++ (type << SPIUSER_ADDR_TYPE_OFFSET) | \ ++ (type << SPIUSER_MODE_TYPE_OFFSET) | \ ++ (type << SPIUSER_DUMMY_TYPE_OFFSET) | \ ++ (type << SPIUSER_DATA_TYPE_OFFSET) \ ++) ++ ++/* SPIFIFOSTAT register bit field */ ++#define SPIFIFOSTAT_TXEMPTY BIT(19) ++#define SPIFIFOSTAT_RXEMPTY BIT(18) ++#define SPIFIFOSTAT_TXFULL BIT(17) ++#define SPIFIFOSTAT_RXFULL BIT(16) ++#define SPIFIFOSTAT_FIFO_MASK 0xff ++#define SPIFIFOSTAT_TX_OFFSET 8 ++#define SPIFIFOSTAT_RX_OFFSET 0 ++ ++#define SPI_FIFO_DEPTH 16 ++ ++/* SPIMODE register bit field */ ++#define SPIMODE_MODE_OFFSET 24 ++#define SPIMODE_DUMMY_OFFSET 0 ++ ++/* SPIARB register bit field */ ++#define SPICTL_ARB_EN BIT(31) ++#define SPICTL_CSCTL1 BIT(16) ++#define SPI1_POR BIT(1) ++#define SPI0_POR BIT(0) ++ ++#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \ ++ SPI_CS_HIGH) ++ ++static atomic_t hw_reset_count = ATOMIC_INIT(0); ++ ++struct rt2880_spi { ++ struct spi_master *master; ++ void __iomem *base; ++ u32 speed; ++ u16 wait_loops; ++ u16 mode; ++ struct clk *clk; ++}; ++ ++static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi) ++{ ++ return spi_master_get_devdata(spi->master); ++} ++ ++static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg) ++{ ++ return ioread32(rs->base + reg); ++} ++ ++static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg, ++ const u32 val) ++{ ++ iowrite32(val, rs->base + reg); ++} ++ ++static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask) ++{ ++ void __iomem *addr = rs->base + reg; ++ ++ iowrite32((ioread32(addr) | mask), addr); ++} ++ ++static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask) ++{ ++ void __iomem *addr = rs->base + reg; ++ ++ iowrite32((ioread32(addr) & ~mask), addr); ++} ++ ++static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed) ++{ ++ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); ++ u32 rate; ++ u32 prescale; ++ ++ /* ++ * the supported rates are: 2, 4, 8, ... 128 ++ * round up as we look for equal or less speed ++ */ ++ rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed); ++ rate = roundup_pow_of_two(rate); ++ ++ /* Convert the rate to SPI clock divisor value. */ ++ prescale = ilog2(rate / 2); ++ ++ /* some tolerance. double and add 100 */ ++ rs->wait_loops = (8 * HZ * loops_per_jiffy) / ++ (clk_get_rate(rs->clk) / rate); ++ rs->wait_loops = (rs->wait_loops << 1) + 100; ++ rs->speed = speed; ++ ++ dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n", ++ clk_get_rate(rs->clk) / rate, speed, rate, prescale, ++ rs->wait_loops); ++ ++ return prescale; ++} ++ ++static u32 get_arbiter_offset(struct spi_master *master) ++{ ++ u32 offset; ++ ++ offset = RAMIPS_SPI_ARBITER; ++ if (master->bus_num == 1) ++ offset -= RAMIPS_SPI_DEV_OFFSET; ++ ++ return offset; ++} ++ ++static void rt2880_spi_set_cs(struct spi_device *spi, bool enable) ++{ ++ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); ++ ++ if (enable) ++ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); ++ else ++ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); ++} ++ ++static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len) ++{ ++ int loop = rs->wait_loops * len; ++ ++ while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop) ++ cpu_relax(); ++ ++ if (loop) ++ return 0; ++ ++ return -ETIMEDOUT; ++} ++ ++static void rt2880_dump_reg(struct spi_master *master) ++{ ++ struct rt2880_spi *rs = spi_master_get_devdata(master); ++ ++ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \ ++ "data: %08x, arb: %08x\n", ++ rt2880_spi_read(rs, RAMIPS_SPI_STAT), ++ rt2880_spi_read(rs, RAMIPS_SPI_CFG), ++ rt2880_spi_read(rs, RAMIPS_SPI_CTL), ++ rt2880_spi_read(rs, RAMIPS_SPI_DATA), ++ rt2880_spi_read(rs, get_arbiter_offset(master))); ++} ++ ++static int rt2880_spi_transfer_one(struct spi_master *master, ++ struct spi_device *spi, struct spi_transfer *xfer) ++{ ++ struct rt2880_spi *rs = spi_master_get_devdata(master); ++ unsigned len; ++ const u8 *tx = xfer->tx_buf; ++ u8 *rx = xfer->rx_buf; ++ int err = 0; ++ ++ /* change clock speed */ ++ if (unlikely(rs->speed != xfer->speed_hz)) { ++ u32 reg; ++ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG); ++ reg &= ~SPICFG_SPICLK_PRESCALE_MASK; ++ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz); ++ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg); ++ } ++ ++ if (tx) { ++ len = xfer->len; ++ while (len-- > 0) { ++ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++); ++ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR); ++ err = rt2880_spi_wait_ready(rs, 1); ++ if (err) { ++ dev_err(&spi->dev, "TX failed, err=%d\n", err); ++ goto out; ++ } ++ } ++ } ++ ++ if (rx) { ++ len = xfer->len; ++ while (len-- > 0) { ++ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD); ++ err = rt2880_spi_wait_ready(rs, 1); ++ if (err) { ++ dev_err(&spi->dev, "RX failed, err=%d\n", err); ++ goto out; ++ } ++ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA); ++ } ++ } ++ ++out: ++ return err; ++} ++ ++/* copy from spi.c */ ++static void spi_set_cs(struct spi_device *spi, bool enable) ++{ ++ if (spi->mode & SPI_CS_HIGH) ++ enable = !enable; ++ ++ if (spi->cs_gpio >= 0) ++ gpio_set_value(spi->cs_gpio, !enable); ++ else if (spi->master->set_cs) ++ spi->master->set_cs(spi, !enable); ++} ++ ++static int rt2880_spi_setup(struct spi_device *spi) ++{ ++ struct spi_master *master = spi->master; ++ struct rt2880_spi *rs = spi_master_get_devdata(master); ++ u32 reg, old_reg, arbit_off; ++ ++ if ((spi->max_speed_hz > master->max_speed_hz) || ++ (spi->max_speed_hz < master->min_speed_hz)) { ++ dev_err(&spi->dev, "invalide requested speed %d Hz\n", ++ spi->max_speed_hz); ++ return -EINVAL; ++ } ++ ++ if (!(master->bits_per_word_mask & ++ BIT(spi->bits_per_word - 1))) { ++ dev_err(&spi->dev, "invalide bits_per_word %d\n", ++ spi->bits_per_word); ++ return -EINVAL; ++ } ++ ++ /* the hardware seems can't work on mode0 force it to mode3 */ ++ if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) { ++ dev_warn(&spi->dev, "force spi mode3\n"); ++ spi->mode |= SPI_MODE_3; ++ } ++ ++ /* chip polarity */ ++ arbit_off = get_arbiter_offset(master); ++ reg = old_reg = rt2880_spi_read(rs, arbit_off); ++ if (spi->mode & SPI_CS_HIGH) { ++ switch (master->bus_num) { ++ case 1: ++ reg |= SPI1_POR; ++ break; ++ default: ++ reg |= SPI0_POR; ++ break; ++ } ++ } else { ++ switch (master->bus_num) { ++ case 1: ++ reg &= ~SPI1_POR; ++ break; ++ default: ++ reg &= ~SPI0_POR; ++ break; ++ } ++ } ++ ++ /* enable spi1 */ ++ if (master->bus_num == 1) ++ reg |= SPICTL_ARB_EN; ++ ++ if (reg != old_reg) ++ rt2880_spi_write(rs, arbit_off, reg); ++ ++ /* deselected the spi device */ ++ spi_set_cs(spi, false); ++ ++ rt2880_dump_reg(master); ++ ++ return 0; ++} ++ ++static int rt2880_spi_prepare_message(struct spi_master *master, ++ struct spi_message *msg) ++{ ++ struct rt2880_spi *rs = spi_master_get_devdata(master); ++ struct spi_device *spi = msg->spi; ++ u32 reg; ++ ++ if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz)) ++ return 0; ++ ++#if 0 ++ /* set spido to tri-state */ ++ rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO); ++#endif ++ ++ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG); ++ ++ reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL | ++ SPICFG_RXCLKEDGE_FALLING | ++ SPICFG_TXCLKEDGE_FALLING | ++ SPICFG_SPICLK_PRESCALE_MASK); ++ ++ /* MSB */ ++ if (!(spi->mode & SPI_LSB_FIRST)) ++ reg |= SPICFG_MSBFIRST; ++ ++ /* spi mode */ ++ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) { ++ case SPI_MODE_0: ++ reg |= SPICFG_TXCLKEDGE_FALLING; ++ break; ++ case SPI_MODE_1: ++ reg |= SPICFG_RXCLKEDGE_FALLING; ++ break; ++ case SPI_MODE_2: ++ reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING; ++ break; ++ case SPI_MODE_3: ++ reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING; ++ break; ++ } ++ rs->mode = spi->mode; ++ ++#if 0 ++ /* set spiclk and spiena to tri-state */ ++ reg |= SPICFG_HIZSPI; ++#endif ++ ++ /* clock divide */ ++ reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz); ++ ++ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg); ++ ++ return 0; ++} ++ ++static int rt2880_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct rt2880_spi *rs; ++ void __iomem *base; ++ struct resource *r; ++ struct clk *clk; ++ int ret; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ base = devm_ioremap_resource(&pdev->dev, r); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "unable to get SYS clock\n"); ++ return PTR_ERR(clk); ++ } ++ ++ ret = clk_prepare_enable(clk); ++ if (ret) ++ goto err_clk; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*rs)); ++ if (master == NULL) { ++ dev_dbg(&pdev->dev, "master allocation failed\n"); ++ ret = -ENOMEM; ++ goto err_clk; ++ } ++ ++ master->dev.of_node = pdev->dev.of_node; ++ master->mode_bits = RT2880_SPI_MODE_BITS; ++ master->bits_per_word_mask = SPI_BPW_MASK(8); ++ master->min_speed_hz = clk_get_rate(clk) / 128; ++ master->max_speed_hz = clk_get_rate(clk) / 2; ++ master->flags = SPI_MASTER_HALF_DUPLEX; ++ master->setup = rt2880_spi_setup; ++ master->prepare_message = rt2880_spi_prepare_message; ++ master->set_cs = rt2880_spi_set_cs; ++ master->transfer_one = rt2880_spi_transfer_one, ++ ++ dev_set_drvdata(&pdev->dev, master); ++ ++ rs = spi_master_get_devdata(master); ++ rs->master = master; ++ rs->base = base; ++ rs->clk = clk; ++ ++ if (atomic_inc_return(&hw_reset_count) == 1) ++ device_reset(&pdev->dev); ++ ++ ret = devm_spi_register_master(&pdev->dev, master); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "devm_spi_register_master error.\n"); ++ goto err_master; ++ } ++ ++ return ret; ++ ++err_master: ++ spi_master_put(master); ++ kfree(master); ++err_clk: ++ clk_disable_unprepare(clk); ++ ++ return ret; ++} ++ ++static int rt2880_spi_remove(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct rt2880_spi *rs; ++ ++ master = dev_get_drvdata(&pdev->dev); ++ rs = spi_master_get_devdata(master); ++ ++ clk_disable_unprepare(rs->clk); ++ atomic_dec(&hw_reset_count); ++ ++ return 0; ++} ++ ++MODULE_ALIAS("platform:" DRIVER_NAME); ++ ++static const struct of_device_id rt2880_spi_match[] = { ++ { .compatible = "ralink,rt2880-spi" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rt2880_spi_match); ++ ++static struct platform_driver rt2880_spi_driver = { ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = rt2880_spi_match, ++ }, ++ .probe = rt2880_spi_probe, ++ .remove = rt2880_spi_remove, ++}; ++ ++module_platform_driver(rt2880_spi_driver); ++ ++MODULE_DESCRIPTION("Ralink SPI driver"); ++MODULE_AUTHOR("Sergiy "); ++MODULE_AUTHOR("Gabor Juhos "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/ramips/patches-5.15/825-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-5.15/825-i2c-MIPS-adds-ralink-I2C-driver.patch new file mode 100644 index 0000000000..5a4491c95a --- /dev/null +++ b/target/linux/ramips/patches-5.15/825-i2c-MIPS-adds-ralink-I2C-driver.patch @@ -0,0 +1,507 @@ +From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jul 2014 09:52:56 +0100 +Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver + +Signed-off-by: John Crispin +--- + .../devicetree/bindings/i2c/i2c-ralink.txt | 27 ++ + drivers/i2c/busses/Kconfig | 4 + + drivers/i2c/busses/Makefile | 1 + + drivers/i2c/busses/i2c-ralink.c | 327 ++++++++++++++++++++ + 4 files changed, 359 insertions(+) + create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt + create mode 100644 drivers/i2c/busses/i2c-ralink.c + +--- /dev/null ++++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt +@@ -0,0 +1,27 @@ ++I2C for Ralink platforms ++ ++Required properties : ++- compatible : Must be "link,rt3052-i2c" ++- reg: physical base address of the controller and length of memory mapped ++ region. ++- #address-cells = <1>; ++- #size-cells = <0>; ++ ++Optional properties: ++- Child nodes conforming to i2c bus binding ++ ++Example : ++ ++palmbus@10000000 { ++ i2c@900 { ++ compatible = "link,rt3052-i2c"; ++ reg = <0x900 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hwmon@4b { ++ compatible = "national,lm92"; ++ reg = <0x4b>; ++ }; ++ }; ++}; +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -949,6 +949,11 @@ config I2C_RK3X + This driver can also be built as a module. If so, the module will + be called i2c-rk3x. + ++config I2C_RALINK ++ tristate "Ralink I2C Controller" ++ depends on RALINK && !SOC_MT7621 ++ select OF_I2C ++ + config HAVE_S3C2410_I2C + bool + help +--- a/drivers/i2c/busses/Makefile ++++ b/drivers/i2c/busses/Makefile +@@ -89,6 +89,7 @@ obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pc + obj-$(CONFIG_I2C_PNX) += i2c-pnx.o + obj-$(CONFIG_I2C_PXA) += i2c-pxa.o + obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o ++obj-$(CONFIG_I2C_RALINK) += i2c-ralink.o + obj-$(CONFIG_I2C_QCOM_CCI) += i2c-qcom-cci.o + obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom-geni.o + obj-$(CONFIG_I2C_QUP) += i2c-qup.o +--- /dev/null ++++ b/drivers/i2c/busses/i2c-ralink.c +@@ -0,0 +1,435 @@ ++/* ++ * drivers/i2c/busses/i2c-ralink.c ++ * ++ * Copyright (C) 2013 Steven Liu ++ * Copyright (C) 2016 Michael Lee ++ * ++ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus. ++ * (C) 2014 Sittisak ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define REG_CONFIG_REG 0x00 ++#define REG_CLKDIV_REG 0x04 ++#define REG_DEVADDR_REG 0x08 ++#define REG_ADDR_REG 0x0C ++#define REG_DATAOUT_REG 0x10 ++#define REG_DATAIN_REG 0x14 ++#define REG_STATUS_REG 0x18 ++#define REG_STARTXFR_REG 0x1C ++#define REG_BYTECNT_REG 0x20 ++ ++/* REG_CONFIG_REG */ ++#define I2C_ADDRLEN_OFFSET 5 ++#define I2C_DEVADLEN_OFFSET 2 ++#define I2C_ADDRLEN_MASK 0x3 ++#define I2C_ADDR_DIS BIT(1) ++#define I2C_DEVADDR_DIS BIT(0) ++#define I2C_ADDRLEN_8 (7 << I2C_ADDRLEN_OFFSET) ++#define I2C_DEVADLEN_7 (6 << I2C_DEVADLEN_OFFSET) ++#define I2C_CONF_DEFAULT (I2C_ADDRLEN_8 | I2C_DEVADLEN_7) ++ ++/* REG_CLKDIV_REG */ ++#define I2C_CLKDIV_MASK 0xffff ++ ++/* REG_DEVADDR_REG */ ++#define I2C_DEVADDR_MASK 0x7f ++ ++/* REG_ADDR_REG */ ++#define I2C_ADDR_MASK 0xff ++ ++/* REG_STATUS_REG */ ++#define I2C_STARTERR BIT(4) ++#define I2C_ACKERR BIT(3) ++#define I2C_DATARDY BIT(2) ++#define I2C_SDOEMPTY BIT(1) ++#define I2C_BUSY BIT(0) ++ ++/* REG_STARTXFR_REG */ ++#define NOSTOP_CMD BIT(2) ++#define NODATA_CMD BIT(1) ++#define READ_CMD BIT(0) ++ ++/* REG_BYTECNT_REG */ ++#define BYTECNT_MAX 64 ++#define SET_BYTECNT(x) (x - 1) ++ ++/* timeout waiting for I2C devices to respond (clock streching) */ ++#define TIMEOUT_MS 1000 ++#define DELAY_INTERVAL_US 100 ++ ++struct rt_i2c { ++ void __iomem *base; ++ struct clk *clk; ++ struct device *dev; ++ struct i2c_adapter adap; ++ u32 cur_clk; ++ u32 clk_div; ++ u32 flags; ++}; ++ ++static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg) ++{ ++ iowrite32(val, i2c->base + reg); ++} ++ ++static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg) ++{ ++ return ioread32(i2c->base + reg); ++} ++ ++static int poll_down_timeout(void __iomem *addr, u32 mask) ++{ ++ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); ++ ++ do { ++ if (!(readl_relaxed(addr) & mask)) ++ return 0; ++ ++ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); ++ } while (time_before(jiffies, timeout)); ++ ++ return (readl_relaxed(addr) & mask) ? -EAGAIN : 0; ++} ++ ++static int rt_i2c_wait_idle(struct rt_i2c *i2c) ++{ ++ int ret; ++ ++ ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY); ++ if (ret < 0) ++ dev_dbg(i2c->dev, "idle err(%d)\n", ret); ++ ++ return ret; ++} ++ ++static int poll_up_timeout(void __iomem *addr, u32 mask) ++{ ++ unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS); ++ u32 status; ++ ++ do { ++ status = readl_relaxed(addr); ++ ++ /* check error status */ ++ if (status & I2C_STARTERR) ++ return -EAGAIN; ++ else if (status & I2C_ACKERR) ++ return -ENXIO; ++ else if (status & mask) ++ return 0; ++ ++ usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); ++ } while (time_before(jiffies, timeout)); ++ ++ return -ETIMEDOUT; ++} ++ ++static int rt_i2c_wait_rx_done(struct rt_i2c *i2c) ++{ ++ int ret; ++ ++ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY); ++ if (ret < 0) ++ dev_dbg(i2c->dev, "rx err(%d)\n", ret); ++ ++ return ret; ++} ++ ++static int rt_i2c_wait_tx_done(struct rt_i2c *i2c) ++{ ++ int ret; ++ ++ ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY); ++ if (ret < 0) ++ dev_dbg(i2c->dev, "tx err(%d)\n", ret); ++ ++ return ret; ++} ++ ++static void rt_i2c_reset(struct rt_i2c *i2c) ++{ ++ device_reset(i2c->adap.dev.parent); ++ barrier(); ++ rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG); ++} ++ ++static void rt_i2c_dump_reg(struct rt_i2c *i2c) ++{ ++ dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \ ++ "addr %08x, dataout %08x, datain %08x, " \ ++ "status %08x, startxfr %08x, bytecnt %08x\n", ++ rt_i2c_r32(i2c, REG_CONFIG_REG), ++ rt_i2c_r32(i2c, REG_CLKDIV_REG), ++ rt_i2c_r32(i2c, REG_DEVADDR_REG), ++ rt_i2c_r32(i2c, REG_ADDR_REG), ++ rt_i2c_r32(i2c, REG_DATAOUT_REG), ++ rt_i2c_r32(i2c, REG_DATAIN_REG), ++ rt_i2c_r32(i2c, REG_STATUS_REG), ++ rt_i2c_r32(i2c, REG_STARTXFR_REG), ++ rt_i2c_r32(i2c, REG_BYTECNT_REG)); ++} ++ ++static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, ++ int num) ++{ ++ struct rt_i2c *i2c; ++ struct i2c_msg *pmsg; ++ unsigned char addr; ++ int i, j, ret; ++ u32 cmd; ++ ++ i2c = i2c_get_adapdata(adap); ++ ++ for (i = 0; i < num; i++) { ++ pmsg = &msgs[i]; ++ if (i == (num - 1)) ++ cmd = 0; ++ else ++ cmd = NOSTOP_CMD; ++ ++ dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n", ++ pmsg->addr, pmsg->len, pmsg->flags, ++ (cmd == 0)? 1 : 0); ++ ++ /* wait hardware idle */ ++ if ((ret = rt_i2c_wait_idle(i2c))) ++ goto err_timeout; ++ ++ if (pmsg->flags & I2C_M_TEN) { ++ rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG); ++ /* 10 bits address */ ++ addr = 0x78 | ((pmsg->addr >> 8) & 0x03); ++ rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK, ++ REG_DEVADDR_REG); ++ rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK, ++ REG_ADDR_REG); ++ } else { ++ rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS, ++ REG_CONFIG_REG); ++ /* 7 bits address */ ++ rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK, ++ REG_DEVADDR_REG); ++ } ++ ++ /* buffer length */ ++ if (pmsg->len == 0) ++ cmd |= NODATA_CMD; ++ else ++ rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len), ++ REG_BYTECNT_REG); ++ ++ j = 0; ++ if (pmsg->flags & I2C_M_RD) { ++ cmd |= READ_CMD; ++ /* start transfer */ ++ barrier(); ++ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG); ++ do { ++ /* wait */ ++ if ((ret = rt_i2c_wait_rx_done(i2c))) ++ goto err_timeout; ++ /* read data */ ++ if (pmsg->len) ++ pmsg->buf[j] = rt_i2c_r32(i2c, ++ REG_DATAIN_REG); ++ j++; ++ } while (j < pmsg->len); ++ } else { ++ do { ++ /* write data */ ++ if (pmsg->len) ++ rt_i2c_w32(i2c, pmsg->buf[j], ++ REG_DATAOUT_REG); ++ /* start transfer */ ++ if (j == 0) { ++ barrier(); ++ rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG); ++ } ++ /* wait */ ++ if ((ret = rt_i2c_wait_tx_done(i2c))) ++ goto err_timeout; ++ j++; ++ } while (j < pmsg->len); ++ } ++ } ++ /* the return value is number of executed messages */ ++ ret = i; ++ ++ return ret; ++ ++err_timeout: ++ rt_i2c_dump_reg(i2c); ++ rt_i2c_reset(i2c); ++ return ret; ++} ++ ++static u32 rt_i2c_func(struct i2c_adapter *a) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm rt_i2c_algo = { ++ .master_xfer = rt_i2c_master_xfer, ++ .functionality = rt_i2c_func, ++}; ++ ++static const struct of_device_id i2c_rt_dt_ids[] = { ++ { .compatible = "ralink,rt2880-i2c" }, ++ { /* sentinel */ } ++}; ++ ++MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids); ++ ++static struct i2c_adapter_quirks rt_i2c_quirks = { ++ .max_write_len = BYTECNT_MAX, ++ .max_read_len = BYTECNT_MAX, ++}; ++ ++static int rt_i2c_init(struct rt_i2c *i2c) ++{ ++ u32 reg; ++ ++ /* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */ ++ i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) / ++ (2 * i2c->cur_clk); ++ if (i2c->clk_div < 8) ++ i2c->clk_div = 8; ++ if (i2c->clk_div > I2C_CLKDIV_MASK) ++ i2c->clk_div = I2C_CLKDIV_MASK; ++ ++ /* check support combinde/repeated start message */ ++ rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG); ++ reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD; ++ ++ rt_i2c_reset(i2c); ++ ++ return reg; ++} ++ ++static int rt_i2c_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ struct rt_i2c *i2c; ++ struct i2c_adapter *adap; ++ const struct of_device_id *match; ++ int ret, restart; ++ ++ match = of_match_device(i2c_rt_dt_ids, &pdev->dev); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "no memory resource found\n"); ++ return -ENODEV; ++ } ++ ++ i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL); ++ if (!i2c) { ++ dev_err(&pdev->dev, "failed to allocate i2c_adapter\n"); ++ return -ENOMEM; ++ } ++ ++ i2c->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(i2c->base)) ++ return PTR_ERR(i2c->base); ++ ++ i2c->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(i2c->clk)) { ++ dev_err(&pdev->dev, "no clock defined\n"); ++ return -ENODEV; ++ } ++ clk_prepare_enable(i2c->clk); ++ i2c->dev = &pdev->dev; ++ ++ if (of_property_read_u32(pdev->dev.of_node, ++ "clock-frequency", &i2c->cur_clk)) ++ i2c->cur_clk = 100000; ++ ++ adap = &i2c->adap; ++ adap->owner = THIS_MODULE; ++ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; ++ adap->algo = &rt_i2c_algo; ++ adap->retries = 3; ++ adap->dev.parent = &pdev->dev; ++ i2c_set_adapdata(adap, i2c); ++ adap->dev.of_node = pdev->dev.of_node; ++ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); ++ adap->quirks = &rt_i2c_quirks; ++ ++ platform_set_drvdata(pdev, i2c); ++ ++ restart = rt_i2c_init(i2c); ++ ++ ret = i2c_add_adapter(adap); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to add adapter\n"); ++ clk_disable_unprepare(i2c->clk); ++ return ret; ++ } ++ ++ dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n", ++ i2c->cur_clk/1000, restart ? "" : "not "); ++ ++ return ret; ++} ++ ++static int rt_i2c_remove(struct platform_device *pdev) ++{ ++ struct rt_i2c *i2c = platform_get_drvdata(pdev); ++ ++ i2c_del_adapter(&i2c->adap); ++ clk_disable_unprepare(i2c->clk); ++ ++ return 0; ++} ++ ++static struct platform_driver rt_i2c_driver = { ++ .probe = rt_i2c_probe, ++ .remove = rt_i2c_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "i2c-ralink", ++ .of_match_table = i2c_rt_dt_ids, ++ }, ++}; ++ ++static int __init i2c_rt_init (void) ++{ ++ return platform_driver_register(&rt_i2c_driver); ++} ++subsys_initcall(i2c_rt_init); ++ ++static void __exit i2c_rt_exit (void) ++{ ++ platform_driver_unregister(&rt_i2c_driver); ++} ++module_exit(i2c_rt_exit); ++ ++MODULE_AUTHOR("Steven Liu "); ++MODULE_DESCRIPTION("Ralink I2c host driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:Ralink-I2C"); diff --git a/target/linux/ramips/patches-5.15/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-5.15/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch new file mode 100644 index 0000000000..1992850d81 --- /dev/null +++ b/target/linux/ramips/patches-5.15/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch @@ -0,0 +1,43 @@ +From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 13 Nov 2014 19:08:40 +0100 +Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC + +Signed-off-by: John Crispin +--- + drivers/mmc/host/Kconfig | 2 + + drivers/mmc/host/Makefile | 1 + + drivers/mmc/host/mtk-mmc/Kconfig | 16 + + drivers/mmc/host/mtk-mmc/Makefile | 42 + + drivers/mmc/host/mtk-mmc/board.h | 137 ++ + drivers/mmc/host/mtk-mmc/dbg.c | 347 ++++ + drivers/mmc/host/mtk-mmc/dbg.h | 156 ++ + drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++ + drivers/mmc/host/mtk-mmc/sd.c | 3060 ++++++++++++++++++++++++++++++++++ + 9 files changed, 4762 insertions(+) + create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig + create mode 100644 drivers/mmc/host/mtk-mmc/Makefile + create mode 100644 drivers/mmc/host/mtk-mmc/board.h + create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c + create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h + create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h + create mode 100644 drivers/mmc/host/mtk-mmc/sd.c + +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -1091,3 +1091,5 @@ config MMC_OWL + + config MMC_SDHCI_EXTERNAL_DMA + bool ++ ++source "drivers/mmc/host/mtk-mmc/Kconfig" +--- a/drivers/mmc/host/Makefile ++++ b/drivers/mmc/host/Makefile +@@ -3,6 +3,7 @@ + # Makefile for MMC/SD host controller drivers + # + ++obj-$(CONFIG_MTK_MMC) += mtk-mmc/ + obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o + armmmci-y := mmci.o + armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o diff --git a/target/linux/ramips/patches-5.15/835-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-5.15/835-asoc-add-mt7620-support.patch new file mode 100644 index 0000000000..bacce79e30 --- /dev/null +++ b/target/linux/ramips/patches-5.15/835-asoc-add-mt7620-support.patch @@ -0,0 +1,1029 @@ +From 7f29222b1731e8182ba94a331531dec18865a1e4 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jul 2014 09:31:47 +0100 +Subject: [PATCH 48/53] asoc: add mt7620 support + +Signed-off-by: John Crispin +--- + arch/mips/ralink/of.c | 2 + + sound/soc/Kconfig | 1 + + sound/soc/Makefile | 1 + + sound/soc/ralink/Kconfig | 15 ++ + sound/soc/ralink/Makefile | 11 + + sound/soc/ralink/mt7620-i2s.c | 436 ++++++++++++++++++++++++++++++++++++++ + sound/soc/ralink/mt7620-wm8960.c | 233 ++++++++++++++++++++ + 7 files changed, 699 insertions(+) + create mode 100644 sound/soc/ralink/Kconfig + create mode 100644 sound/soc/ralink/Makefile + create mode 100644 sound/soc/ralink/mt7620-i2s.c + create mode 100644 sound/soc/ralink/mt7620-wm8960.c + +--- a/sound/soc/Kconfig ++++ b/sound/soc/Kconfig +@@ -78,6 +78,7 @@ source "sound/soc/mxs/Kconfig" + source "sound/soc/pxa/Kconfig" + source "sound/soc/qcom/Kconfig" + source "sound/soc/rockchip/Kconfig" ++source "sound/soc/ralink/Kconfig" + source "sound/soc/samsung/Kconfig" + source "sound/soc/sh/Kconfig" + source "sound/soc/sof/Kconfig" +--- a/sound/soc/Makefile ++++ b/sound/soc/Makefile +@@ -48,6 +48,7 @@ obj-$(CONFIG_SND_SOC) += kirkwood/ + obj-$(CONFIG_SND_SOC) += pxa/ + obj-$(CONFIG_SND_SOC) += qcom/ + obj-$(CONFIG_SND_SOC) += rockchip/ ++obj-$(CONFIG_SND_SOC) += ralink/ + obj-$(CONFIG_SND_SOC) += samsung/ + obj-$(CONFIG_SND_SOC) += sh/ + obj-$(CONFIG_SND_SOC) += sof/ +--- /dev/null ++++ b/sound/soc/ralink/Kconfig +@@ -0,0 +1,8 @@ ++config SND_RALINK_SOC_I2S ++ depends on RALINK && SND_SOC && !SOC_RT288X ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ select REGMAP_MMIO ++ tristate "SoC Audio (I2S protocol) for Ralink SoC" ++ help ++ Say Y if you want to use I2S protocol and I2S codec on Ralink/MediaTek ++ based boards. +--- /dev/null ++++ b/sound/soc/ralink/Makefile +@@ -0,0 +1,6 @@ ++# ++# Ralink/MediaTek Platform Support ++# ++snd-soc-ralink-i2s-objs := ralink-i2s.o ++ ++obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o +--- /dev/null ++++ b/sound/soc/ralink/ralink-i2s.c +@@ -0,0 +1,966 @@ ++/* ++ * Copyright (C) 2010, Lars-Peter Clausen ++ * Copyright (C) 2016 Michael Lee ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DRV_NAME "ralink-i2s" ++ ++#define I2S_REG_CFG0 0x00 ++#define I2S_REG_INT_STATUS 0x04 ++#define I2S_REG_INT_EN 0x08 ++#define I2S_REG_FF_STATUS 0x0c ++#define I2S_REG_WREG 0x10 ++#define I2S_REG_RREG 0x14 ++#define I2S_REG_CFG1 0x18 ++#define I2S_REG_DIVCMP 0x20 ++#define I2S_REG_DIVINT 0x24 ++ ++/* I2S_REG_CFG0 */ ++#define I2S_REG_CFG0_EN BIT(31) ++#define I2S_REG_CFG0_DMA_EN BIT(30) ++#define I2S_REG_CFG0_BYTE_SWAP BIT(28) ++#define I2S_REG_CFG0_TX_EN BIT(24) ++#define I2S_REG_CFG0_RX_EN BIT(20) ++#define I2S_REG_CFG0_SLAVE BIT(16) ++#define I2S_REG_CFG0_RX_THRES 12 ++#define I2S_REG_CFG0_TX_THRES 4 ++#define I2S_REG_CFG0_THRES_MASK (0xf << I2S_REG_CFG0_RX_THRES) | \ ++ (4 << I2S_REG_CFG0_TX_THRES) ++#define I2S_REG_CFG0_DFT_THRES (4 << I2S_REG_CFG0_RX_THRES) | \ ++ (4 << I2S_REG_CFG0_TX_THRES) ++/* RT305x */ ++#define I2S_REG_CFG0_CLK_DIS BIT(8) ++#define I2S_REG_CFG0_TXCH_SWAP BIT(3) ++#define I2S_REG_CFG0_TXCH1_OFF BIT(2) ++#define I2S_REG_CFG0_TXCH0_OFF BIT(1) ++#define I2S_REG_CFG0_SLAVE_EN BIT(0) ++/* RT3883 */ ++#define I2S_REG_CFG0_RXCH_SWAP BIT(11) ++#define I2S_REG_CFG0_RXCH1_OFF BIT(10) ++#define I2S_REG_CFG0_RXCH0_OFF BIT(9) ++#define I2S_REG_CFG0_WS_INV BIT(0) ++/* MT7628 */ ++#define I2S_REG_CFG0_FMT_LE BIT(29) ++#define I2S_REG_CFG0_SYS_BE BIT(28) ++#define I2S_REG_CFG0_NORM_24 BIT(18) ++#define I2S_REG_CFG0_DATA_24 BIT(17) ++ ++/* I2S_REG_INT_STATUS */ ++#define I2S_REG_INT_RX_FAULT BIT(7) ++#define I2S_REG_INT_RX_OVRUN BIT(6) ++#define I2S_REG_INT_RX_UNRUN BIT(5) ++#define I2S_REG_INT_RX_THRES BIT(4) ++#define I2S_REG_INT_TX_FAULT BIT(3) ++#define I2S_REG_INT_TX_OVRUN BIT(2) ++#define I2S_REG_INT_TX_UNRUN BIT(1) ++#define I2S_REG_INT_TX_THRES BIT(0) ++#define I2S_REG_INT_TX_MASK 0xf ++#define I2S_REG_INT_RX_MASK 0xf0 ++ ++/* I2S_REG_INT_STATUS */ ++#define I2S_RX_AVCNT(x) ((x >> 4) & 0xf) ++#define I2S_TX_AVCNT(x) (x & 0xf) ++/* MT7628 */ ++#define MT7628_I2S_RX_AVCNT(x) ((x >> 8) & 0x1f) ++#define MT7628_I2S_TX_AVCNT(x) (x & 0x1f) ++ ++/* I2S_REG_CFG1 */ ++#define I2S_REG_CFG1_LBK BIT(31) ++#define I2S_REG_CFG1_EXTLBK BIT(30) ++/* RT3883 */ ++#define I2S_REG_CFG1_LEFT_J BIT(0) ++#define I2S_REG_CFG1_RIGHT_J BIT(1) ++#define I2S_REG_CFG1_FMT_MASK 0x3 ++ ++/* I2S_REG_DIVCMP */ ++#define I2S_REG_DIVCMP_CLKEN BIT(31) ++#define I2S_REG_DIVCMP_DIVCOMP_MASK 0x1ff ++ ++/* I2S_REG_DIVINT */ ++#define I2S_REG_DIVINT_MASK 0x3ff ++ ++/* BCLK dividers */ ++#define RALINK_I2S_DIVCMP 0 ++#define RALINK_I2S_DIVINT 1 ++ ++/* FIFO */ ++#define RALINK_I2S_FIFO_SIZE 32 ++ ++/* feature flags */ ++#define RALINK_FLAGS_TXONLY BIT(0) ++#define RALINK_FLAGS_LEFT_J BIT(1) ++#define RALINK_FLAGS_RIGHT_J BIT(2) ++#define RALINK_FLAGS_ENDIAN BIT(3) ++#define RALINK_FLAGS_24BIT BIT(4) ++ ++#define RALINK_I2S_INT_EN 0 ++ ++struct ralink_i2s_stats { ++ u32 dmafault; ++ u32 overrun; ++ u32 underrun; ++ u32 belowthres; ++}; ++ ++struct ralink_i2s { ++ struct device *dev; ++ void __iomem *regs; ++ struct clk *clk; ++ struct regmap *regmap; ++ u32 flags; ++ unsigned int fmt; ++ u16 txdma_req; ++ u16 rxdma_req; ++ ++ struct snd_dmaengine_dai_dma_data playback_dma_data; ++ struct snd_dmaengine_dai_dma_data capture_dma_data; ++ ++ struct dentry *dbg_dir; ++ struct dentry *dbg_stats; ++ struct ralink_i2s_stats txstats; ++ struct ralink_i2s_stats rxstats; ++}; ++ ++static void ralink_i2s_dump_regs(struct ralink_i2s *i2s) ++{ ++ u32 buf[10]; ++ int ret; ++ ++ ret = regmap_bulk_read(i2s->regmap, I2S_REG_CFG0, ++ buf, ARRAY_SIZE(buf)); ++ ++ dev_dbg(i2s->dev, "CFG0: %08x, INTSTAT: %08x, INTEN: %08x, " \ ++ "FFSTAT: %08x, WREG: %08x, RREG: %08x, " \ ++ "CFG1: %08x, DIVCMP: %08x, DIVINT: %08x\n", ++ buf[0], buf[1], buf[2], buf[3], buf[4], ++ buf[5], buf[6], buf[8], buf[9]); ++} ++ ++static int ralink_i2s_set_sysclk(struct snd_soc_dai *dai, ++ int clk_id, unsigned int freq, int dir) ++{ ++ return 0; ++} ++ ++static int ralink_i2s_set_sys_bclk(struct snd_soc_dai *dai, int width, int rate) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ unsigned long clk = clk_get_rate(i2s->clk); ++ int div; ++ uint32_t data; ++ ++ /* disable clock at slave mode */ ++ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) == ++ SND_SOC_DAIFMT_CBM_CFM) { ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_CLK_DIS, ++ I2S_REG_CFG0_CLK_DIS); ++ return 0; ++ } ++ ++ /* FREQOUT = FREQIN / (I2S_CLK_DIV + 1) */ ++ div = (clk / rate ) - 1; ++ ++ data = rt_sysc_r32(0x30); ++ data &= (0xff << 8); ++ data |= (0x1 << 15) | (div << 8); ++ rt_sysc_w32(data, 0x30); ++ ++ /* enable clock */ ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_CLK_DIS, 0); ++ ++ dev_dbg(i2s->dev, "clk: %lu, rate: %u, div: %d\n", ++ clk, rate, div); ++ ++ return 0; ++} ++ ++static int ralink_i2s_set_bclk(struct snd_soc_dai *dai, int width, int rate) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ unsigned long clk = clk_get_rate(i2s->clk); ++ int divint, divcomp; ++ ++ /* disable clock at slave mode */ ++ if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) == ++ SND_SOC_DAIFMT_CBM_CFM) { ++ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, ++ I2S_REG_DIVCMP_CLKEN, 0); ++ return 0; ++ } ++ ++ /* FREQOUT = FREQIN * (1/2) * (1/(DIVINT + DIVCOMP/512)) */ ++ clk = clk / (2 * 2 * width); ++ divint = clk / rate; ++ divcomp = ((clk % rate) * 512) / rate; ++ ++ if ((divint > I2S_REG_DIVINT_MASK) || ++ (divcomp > I2S_REG_DIVCMP_DIVCOMP_MASK)) ++ return -EINVAL; ++ ++ regmap_update_bits(i2s->regmap, I2S_REG_DIVINT, ++ I2S_REG_DIVINT_MASK, divint); ++ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, ++ I2S_REG_DIVCMP_DIVCOMP_MASK, divcomp); ++ ++ /* enable clock */ ++ regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, I2S_REG_DIVCMP_CLKEN, ++ I2S_REG_DIVCMP_CLKEN); ++ ++ dev_dbg(i2s->dev, "clk: %lu, rate: %u, int: %d, comp: %d\n", ++ clk_get_rate(i2s->clk), rate, divint, divcomp); ++ ++ return 0; ++} ++ ++static int ralink_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ unsigned int cfg0 = 0, cfg1 = 0; ++ ++ /* set master/slave audio interface */ ++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBM_CFM: ++ if (i2s->flags & RALINK_FLAGS_TXONLY) ++ cfg0 |= I2S_REG_CFG0_SLAVE_EN; ++ else ++ cfg0 |= I2S_REG_CFG0_SLAVE; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFS: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* interface format */ ++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ break; ++ case SND_SOC_DAIFMT_RIGHT_J: ++ if (i2s->flags & RALINK_FLAGS_RIGHT_J) { ++ cfg1 |= I2S_REG_CFG1_RIGHT_J; ++ break; ++ } ++ return -EINVAL; ++ case SND_SOC_DAIFMT_LEFT_J: ++ if (i2s->flags & RALINK_FLAGS_LEFT_J) { ++ cfg1 |= I2S_REG_CFG1_LEFT_J; ++ break; ++ } ++ return -EINVAL; ++ default: ++ return -EINVAL; ++ } ++ ++ /* clock inversion */ ++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_NB_NF: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (i2s->flags & RALINK_FLAGS_TXONLY) { ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_SLAVE_EN, cfg0); ++ } else { ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_SLAVE, cfg0); ++ } ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG1, ++ I2S_REG_CFG1_FMT_MASK, cfg1); ++ i2s->fmt = fmt; ++ ++ return 0; ++} ++ ++static int ralink_i2s_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ ++ if (snd_soc_dai_active(dai)) ++ return 0; ++ ++ /* setup status interrupt */ ++#if (RALINK_I2S_INT_EN) ++ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0xff); ++#else ++ regmap_write(i2s->regmap, I2S_REG_INT_EN, 0x0); ++#endif ++ ++ /* enable */ ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN | ++ I2S_REG_CFG0_THRES_MASK, ++ I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN | ++ I2S_REG_CFG0_DFT_THRES); ++ ++ return 0; ++} ++ ++static void ralink_i2s_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ ++ /* If both streams are stopped, disable module and clock */ ++ if (snd_soc_dai_active(dai)) ++ return; ++ ++ /* ++ * datasheet mention when disable all control regs are cleared ++ * to initial values. need reinit at startup. ++ */ ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_EN, 0); ++} ++ ++static int ralink_i2s_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ int width; ++ int ret; ++ ++ width = params_width(params); ++ switch (width) { ++ case 16: ++ if (i2s->flags & RALINK_FLAGS_24BIT) ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_DATA_24, 0); ++ break; ++ case 24: ++ if (i2s->flags & RALINK_FLAGS_24BIT) { ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_DATA_24, ++ I2S_REG_CFG0_DATA_24); ++ break; ++ } ++ return -EINVAL; ++ default: ++ return -EINVAL; ++ } ++ ++ switch (params_channels(params)) { ++ case 2: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (i2s->flags & RALINK_FLAGS_ENDIAN) { ++ /* system endian */ ++#ifdef SNDRV_LITTLE_ENDIAN ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_SYS_BE, 0); ++#else ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_SYS_BE, ++ I2S_REG_CFG0_SYS_BE); ++#endif ++ ++ /* data endian */ ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ case SNDRV_PCM_FORMAT_S24_LE: ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_FMT_LE, ++ I2S_REG_CFG0_FMT_LE); ++ break; ++ case SNDRV_PCM_FORMAT_S16_BE: ++ case SNDRV_PCM_FORMAT_S24_BE: ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, ++ I2S_REG_CFG0_FMT_LE, 0); ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ /* setup bclk rate */ ++ if (i2s->flags & RALINK_FLAGS_TXONLY) ++ ret = ralink_i2s_set_sys_bclk(dai, width, params_rate(params)); ++ else ++ ret = ralink_i2s_set_bclk(dai, width, params_rate(params)); ++ ++ return ret; ++} ++ ++static int ralink_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ unsigned int mask, val; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ mask = I2S_REG_CFG0_TX_EN; ++ else ++ mask = I2S_REG_CFG0_RX_EN; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ val = mask; ++ break; ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ val = 0; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(i2s->regmap, I2S_REG_CFG0, mask, val); ++ ++ return 0; ++} ++ ++static void ralink_i2s_init_dma_data(struct ralink_i2s *i2s, ++ struct resource *res) ++{ ++ struct snd_dmaengine_dai_dma_data *dma_data; ++ ++ /* Playback */ ++ dma_data = &i2s->playback_dma_data; ++ dma_data->addr = res->start + I2S_REG_WREG; ++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dma_data->maxburst = 1; ++ dma_data->slave_id = i2s->txdma_req; ++ ++ if (i2s->flags & RALINK_FLAGS_TXONLY) ++ return; ++ ++ /* Capture */ ++ dma_data = &i2s->capture_dma_data; ++ dma_data->addr = res->start + I2S_REG_RREG; ++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dma_data->maxburst = 1; ++ dma_data->slave_id = i2s->rxdma_req; ++} ++ ++static int ralink_i2s_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai); ++ ++ snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, ++ &i2s->capture_dma_data); ++ ++ return 0; ++} ++ ++static int ralink_i2s_dai_remove(struct snd_soc_dai *dai) ++{ ++ return 0; ++} ++ ++static const struct snd_soc_dai_ops ralink_i2s_dai_ops = { ++ .set_sysclk = ralink_i2s_set_sysclk, ++ .set_fmt = ralink_i2s_set_fmt, ++ .startup = ralink_i2s_startup, ++ .shutdown = ralink_i2s_shutdown, ++ .hw_params = ralink_i2s_hw_params, ++ .trigger = ralink_i2s_trigger, ++}; ++ ++static struct snd_soc_dai_driver ralink_i2s_dai = { ++ .name = DRV_NAME, ++ .probe = ralink_i2s_dai_probe, ++ .remove = ralink_i2s_dai_remove, ++ .ops = &ralink_i2s_dai_ops, ++ .capture = { ++ .stream_name = "I2S Capture", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rate_min = 5512, ++ .rate_max = 192000, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ }, ++ .playback = { ++ .stream_name = "I2S Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rate_min = 5512, ++ .rate_max = 192000, ++ .rates = SNDRV_PCM_RATE_CONTINUOUS, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ }, ++ .symmetric_rates = 1, ++}; ++ ++static struct snd_pcm_hardware ralink_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .channels_min = 2, ++ .channels_max = 2, ++ .period_bytes_min = PAGE_SIZE, ++ .period_bytes_max = PAGE_SIZE * 2, ++ .periods_min = 2, ++ .periods_max = 128, ++ .buffer_bytes_max = 128 * 1024, ++ .fifo_size = RALINK_I2S_FIFO_SIZE, ++}; ++ ++static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = { ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++ .pcm_hardware = &ralink_pcm_hardware, ++ .prealloc_buffer_size = 256 * PAGE_SIZE, ++}; ++ ++static const struct snd_soc_component_driver ralink_i2s_component = { ++ .name = DRV_NAME, ++}; ++ ++static bool ralink_i2s_readable_reg(struct device *dev, unsigned int reg) ++{ ++ return true; ++} ++ ++static bool ralink_i2s_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case I2S_REG_INT_STATUS: ++ case I2S_REG_FF_STATUS: ++ return true; ++ } ++ return false; ++} ++ ++static bool ralink_i2s_writeable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case I2S_REG_FF_STATUS: ++ case I2S_REG_RREG: ++ return false; ++ } ++ return true; ++} ++ ++static const struct regmap_config ralink_i2s_regmap_config = { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .writeable_reg = ralink_i2s_writeable_reg, ++ .readable_reg = ralink_i2s_readable_reg, ++ .volatile_reg = ralink_i2s_volatile_reg, ++ .max_register = I2S_REG_DIVINT, ++}; ++ ++#if (RALINK_I2S_INT_EN) ++static irqreturn_t ralink_i2s_irq(int irq, void *devid) ++{ ++ struct ralink_i2s *i2s = devid; ++ u32 status; ++ ++ regmap_read(i2s->regmap, I2S_REG_INT_STATUS, &status); ++ if (unlikely(!status)) ++ return IRQ_NONE; ++ ++ /* tx stats */ ++ if (status & I2S_REG_INT_TX_MASK) { ++ if (status & I2S_REG_INT_TX_THRES) ++ i2s->txstats.belowthres++; ++ if (status & I2S_REG_INT_TX_UNRUN) ++ i2s->txstats.underrun++; ++ if (status & I2S_REG_INT_TX_OVRUN) ++ i2s->txstats.overrun++; ++ if (status & I2S_REG_INT_TX_FAULT) ++ i2s->txstats.dmafault++; ++ } ++ ++ /* rx stats */ ++ if (status & I2S_REG_INT_RX_MASK) { ++ if (status & I2S_REG_INT_RX_THRES) ++ i2s->rxstats.belowthres++; ++ if (status & I2S_REG_INT_RX_UNRUN) ++ i2s->rxstats.underrun++; ++ if (status & I2S_REG_INT_RX_OVRUN) ++ i2s->rxstats.overrun++; ++ if (status & I2S_REG_INT_RX_FAULT) ++ i2s->rxstats.dmafault++; ++ } ++ ++ /* clean status bits */ ++ regmap_write(i2s->regmap, I2S_REG_INT_STATUS, status); ++ ++ return IRQ_HANDLED; ++} ++#endif ++ ++#if IS_ENABLED(CONFIG_DEBUG_FS) ++static int ralink_i2s_stats_show(struct seq_file *s, void *unused) ++{ ++ struct ralink_i2s *i2s = s->private; ++ ++ seq_printf(s, "tx stats\n"); ++ seq_printf(s, "\tbelow threshold\t%u\n", i2s->txstats.belowthres); ++ seq_printf(s, "\tunder run\t%u\n", i2s->txstats.underrun); ++ seq_printf(s, "\tover run\t%u\n", i2s->txstats.overrun); ++ seq_printf(s, "\tdma fault\t%u\n", i2s->txstats.dmafault); ++ ++ seq_printf(s, "rx stats\n"); ++ seq_printf(s, "\tbelow threshold\t%u\n", i2s->rxstats.belowthres); ++ seq_printf(s, "\tunder run\t%u\n", i2s->rxstats.underrun); ++ seq_printf(s, "\tover run\t%u\n", i2s->rxstats.overrun); ++ seq_printf(s, "\tdma fault\t%u\n", i2s->rxstats.dmafault); ++ ++ ralink_i2s_dump_regs(i2s); ++ ++ return 0; ++} ++ ++static int ralink_i2s_stats_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, ralink_i2s_stats_show, inode->i_private); ++} ++ ++static const struct file_operations ralink_i2s_stats_ops = { ++ .open = ralink_i2s_stats_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s) ++{ ++ i2s->dbg_dir = debugfs_create_dir(dev_name(i2s->dev), NULL); ++ if (!i2s->dbg_dir) ++ return -ENOMEM; ++ ++ i2s->dbg_stats = debugfs_create_file("stats", S_IRUGO, ++ i2s->dbg_dir, i2s, &ralink_i2s_stats_ops); ++ if (!i2s->dbg_stats) { ++ debugfs_remove(i2s->dbg_dir); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s) ++{ ++ debugfs_remove(i2s->dbg_stats); ++ debugfs_remove(i2s->dbg_dir); ++} ++#else ++static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s) ++{ ++ return 0; ++} ++ ++static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s) ++{ ++} ++#endif ++ ++/* ++ * TODO: these refclk setup functions should use ++ * clock framework instead. hardcode it now. ++ */ ++static void rt3350_refclk_setup(void) ++{ ++ uint32_t data; ++ ++ /* set refclk output 12Mhz clock */ ++ data = rt_sysc_r32(0x2c); ++ data |= (0x1 << 8); ++ rt_sysc_w32(data, 0x2c); ++} ++ ++static void rt3883_refclk_setup(void) ++{ ++ uint32_t data; ++ ++ /* set refclk output 12Mhz clock */ ++ data = rt_sysc_r32(0x2c); ++ data &= ~(0x3 << 13); ++ data |= (0x1 << 13); ++ rt_sysc_w32(data, 0x2c); ++} ++ ++static void rt3552_refclk_setup(void) ++{ ++ uint32_t data; ++ ++ /* set refclk output 12Mhz clock */ ++ data = rt_sysc_r32(0x2c); ++ data &= ~(0xf << 8); ++ data |= (0x3 << 8); ++ rt_sysc_w32(data, 0x2c); ++} ++ ++static void mt7620_refclk_setup(void) ++{ ++ uint32_t data; ++ ++ /* set refclk output 12Mhz clock */ ++ data = rt_sysc_r32(0x2c); ++ data &= ~(0x7 << 9); ++ data |= 0x1 << 9; ++ rt_sysc_w32(data, 0x2c); ++} ++ ++static void mt7621_refclk_setup(void) ++{ ++ uint32_t data; ++ ++ /* set refclk output 12Mhz clock */ ++ data = rt_sysc_r32(0x2c); ++ data &= ~(0x1f << 18); ++ data |= (0x19 << 18); ++ data &= ~(0x1f << 12); ++ data |= (0x1 << 12); ++ data &= ~(0x7 << 9); ++ data |= (0x5 << 9); ++ rt_sysc_w32(data, 0x2c); ++} ++ ++static void mt7628_refclk_setup(void) ++{ ++ uint32_t data; ++ ++ /* set i2s and refclk digital pad */ ++ data = rt_sysc_r32(0x3c); ++ data |= 0x1f; ++ rt_sysc_w32(data, 0x3c); ++ ++ /* Adjust REFCLK0's driving strength */ ++ data = rt_sysc_r32(0x1354); ++ data &= ~(0x1 << 5); ++ rt_sysc_w32(data, 0x1354); ++ data = rt_sysc_r32(0x1364); ++ data |= ~(0x1 << 5); ++ rt_sysc_w32(data, 0x1364); ++ ++ /* set refclk output 12Mhz clock */ ++ data = rt_sysc_r32(0x2c); ++ data &= ~(0x7 << 9); ++ data |= 0x1 << 9; ++ rt_sysc_w32(data, 0x2c); ++} ++ ++struct rt_i2s_data { ++ u32 flags; ++ void (*refclk_setup)(void); ++}; ++ ++struct rt_i2s_data rt3050_i2s_data = { .flags = RALINK_FLAGS_TXONLY }; ++struct rt_i2s_data rt3350_i2s_data = { .flags = RALINK_FLAGS_TXONLY, ++ .refclk_setup = rt3350_refclk_setup }; ++struct rt_i2s_data rt3883_i2s_data = { ++ .flags = (RALINK_FLAGS_LEFT_J | RALINK_FLAGS_RIGHT_J), ++ .refclk_setup = rt3883_refclk_setup }; ++struct rt_i2s_data rt3352_i2s_data = { .refclk_setup = rt3552_refclk_setup}; ++struct rt_i2s_data mt7620_i2s_data = { .refclk_setup = mt7620_refclk_setup}; ++struct rt_i2s_data mt7621_i2s_data = { .refclk_setup = mt7621_refclk_setup}; ++struct rt_i2s_data mt7628_i2s_data = { ++ .flags = (RALINK_FLAGS_ENDIAN | RALINK_FLAGS_24BIT | ++ RALINK_FLAGS_LEFT_J), ++ .refclk_setup = mt7628_refclk_setup}; ++ ++static const struct of_device_id ralink_i2s_match_table[] = { ++ { .compatible = "ralink,rt3050-i2s", ++ .data = (void *)&rt3050_i2s_data }, ++ { .compatible = "ralink,rt3350-i2s", ++ .data = (void *)&rt3350_i2s_data }, ++ { .compatible = "ralink,rt3883-i2s", ++ .data = (void *)&rt3883_i2s_data }, ++ { .compatible = "ralink,rt3352-i2s", ++ .data = (void *)&rt3352_i2s_data }, ++ { .compatible = "mediatek,mt7620-i2s", ++ .data = (void *)&mt7620_i2s_data }, ++ { .compatible = "mediatek,mt7621-i2s", ++ .data = (void *)&mt7621_i2s_data }, ++ { .compatible = "mediatek,mt7628-i2s", ++ .data = (void *)&mt7628_i2s_data }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ralink_i2s_match_table); ++ ++static int ralink_i2s_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *match; ++ struct device_node *np = pdev->dev.of_node; ++ struct ralink_i2s *i2s; ++ struct resource *res; ++ int irq, ret; ++ u32 dma_req; ++ struct rt_i2s_data *data; ++ ++ i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); ++ if (!i2s) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, i2s); ++ i2s->dev = &pdev->dev; ++ ++ match = of_match_device(ralink_i2s_match_table, &pdev->dev); ++ if (!match) ++ return -EINVAL; ++ data = (struct rt_i2s_data *)match->data; ++ i2s->flags = data->flags; ++ /* setup out 12Mhz refclk to codec as mclk */ ++ if (data->refclk_setup) ++ data->refclk_setup(); ++ ++ if (of_property_read_u32(np, "txdma-req", &dma_req)) { ++ dev_err(&pdev->dev, "no txdma-req define\n"); ++ return -EINVAL; ++ } ++ i2s->txdma_req = (u16)dma_req; ++ if (!(i2s->flags & RALINK_FLAGS_TXONLY)) { ++ if (of_property_read_u32(np, "rxdma-req", &dma_req)) { ++ dev_err(&pdev->dev, "no rxdma-req define\n"); ++ return -EINVAL; ++ } ++ i2s->rxdma_req = (u16)dma_req; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ i2s->regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(i2s->regs)) ++ return PTR_ERR(i2s->regs); ++ ++ i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->regs, ++ &ralink_i2s_regmap_config); ++ if (IS_ERR(i2s->regmap)) { ++ dev_err(&pdev->dev, "regmap init failed\n"); ++ return PTR_ERR(i2s->regmap); ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(&pdev->dev, "failed to get irq\n"); ++ return -EINVAL; ++ } ++ ++#if (RALINK_I2S_INT_EN) ++ ret = devm_request_irq(&pdev->dev, irq, ralink_i2s_irq, ++ 0, dev_name(&pdev->dev), i2s); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to request irq\n"); ++ return ret; ++ } ++#endif ++ ++ i2s->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(i2s->clk)) { ++ dev_err(&pdev->dev, "no clock defined\n"); ++ return PTR_ERR(i2s->clk); ++ } ++ ++ ret = clk_prepare_enable(i2s->clk); ++ if (ret) ++ return ret; ++ ++ ralink_i2s_init_dma_data(i2s, res); ++ ++ device_reset(&pdev->dev); ++ ++ ret = ralink_i2s_debugfs_create(i2s); ++ if (ret) { ++ dev_err(&pdev->dev, "create debugfs failed\n"); ++ goto err_clk_disable; ++ } ++ ++ /* enable 24bits support */ ++ if (i2s->flags & RALINK_FLAGS_24BIT) { ++ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S24_LE; ++ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S24_LE; ++ } ++ ++ /* enable big endian support */ ++ if (i2s->flags & RALINK_FLAGS_ENDIAN) { ++ ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S16_BE; ++ ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S16_BE; ++ ralink_pcm_hardware.formats |= SNDRV_PCM_FMTBIT_S16_BE; ++ if (i2s->flags & RALINK_FLAGS_24BIT) { ++ ralink_i2s_dai.capture.formats |= ++ SNDRV_PCM_FMTBIT_S24_BE; ++ ralink_i2s_dai.playback.formats |= ++ SNDRV_PCM_FMTBIT_S24_BE; ++ ralink_pcm_hardware.formats |= ++ SNDRV_PCM_FMTBIT_S24_BE; ++ } ++ } ++ ++ /* disable capture support */ ++ if (i2s->flags & RALINK_FLAGS_TXONLY) ++ memset(&ralink_i2s_dai.capture, sizeof(ralink_i2s_dai.capture), ++ 0); ++ ++ ret = devm_snd_soc_register_component(&pdev->dev, &ralink_i2s_component, ++ &ralink_i2s_dai, 1); ++ if (ret) ++ goto err_debugfs; ++ ++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, ++ &ralink_dmaengine_pcm_config, ++ SND_DMAENGINE_PCM_FLAG_COMPAT); ++ if (ret) ++ goto err_debugfs; ++ ++ dev_info(i2s->dev, "mclk %luMHz\n", clk_get_rate(i2s->clk) / 1000000); ++ ++ return 0; ++ ++err_debugfs: ++ ralink_i2s_debugfs_remove(i2s); ++ ++err_clk_disable: ++ clk_disable_unprepare(i2s->clk); ++ ++ return ret; ++} ++ ++static int ralink_i2s_remove(struct platform_device *pdev) ++{ ++ struct ralink_i2s *i2s = platform_get_drvdata(pdev); ++ ++ ralink_i2s_debugfs_remove(i2s); ++ clk_disable_unprepare(i2s->clk); ++ ++ return 0; ++} ++ ++static struct platform_driver ralink_i2s_driver = { ++ .probe = ralink_i2s_probe, ++ .remove = ralink_i2s_remove, ++ .driver = { ++ .name = DRV_NAME, ++ .of_match_table = ralink_i2s_match_table, ++ }, ++}; ++module_platform_driver(ralink_i2s_driver); ++ ++MODULE_AUTHOR("Lars-Peter Clausen, "); ++MODULE_DESCRIPTION("Ralink/MediaTek I2S driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:" DRV_NAME); diff --git a/target/linux/ramips/patches-5.15/840-serial-add-ugly-custom-baud-rate-hack.patch b/target/linux/ramips/patches-5.15/840-serial-add-ugly-custom-baud-rate-hack.patch new file mode 100644 index 0000000000..d7cf2dfd48 --- /dev/null +++ b/target/linux/ramips/patches-5.15/840-serial-add-ugly-custom-baud-rate-hack.patch @@ -0,0 +1,22 @@ +From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 7 Dec 2015 17:31:08 +0100 +Subject: [PATCH 51/53] serial: add ugly custom baud rate hack + +Signed-off-by: John Crispin +--- + drivers/tty/serial/serial_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -401,6 +401,9 @@ uart_get_baud_rate(struct uart_port *por + break; + } + ++ if (tty_termios_baud_rate(termios) == 2500000) ++ return 250000; ++ + for (try = 0; try < 2; try++) { + baud = tty_termios_baud_rate(termios); + diff --git a/target/linux/ramips/patches-5.15/845-pwm-add-mediatek-support.patch b/target/linux/ramips/patches-5.15/845-pwm-add-mediatek-support.patch new file mode 100644 index 0000000000..7792b7d63c --- /dev/null +++ b/target/linux/ramips/patches-5.15/845-pwm-add-mediatek-support.patch @@ -0,0 +1,217 @@ +From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 7 Dec 2015 17:16:50 +0100 +Subject: [PATCH 52/53] pwm: add mediatek support + +Signed-off-by: John Crispin +--- + drivers/pwm/Kconfig | 9 +++ + drivers/pwm/Makefile | 1 + + drivers/pwm/pwm-mediatek.c | 173 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 183 insertions(+) + create mode 100644 drivers/pwm/pwm-mediatek.c + +--- a/drivers/pwm/Kconfig ++++ b/drivers/pwm/Kconfig +@@ -383,6 +383,15 @@ config PWM_MEDIATEK + To compile this driver as a module, choose M here: the module + will be called pwm-mediatek. + ++config PWM_MEDIATEK_RAMIPS ++ tristate "Mediatek PWM support" ++ depends on RALINK && OF ++ help ++ Generic PWM framework driver for Mediatek ARM SoC. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called pwm-mxs. ++ + config PWM_MXS + tristate "Freescale MXS PWM support" + depends on ARCH_MXS || COMPILE_TEST +--- a/drivers/pwm/Makefile ++++ b/drivers/pwm/Makefile +@@ -33,6 +33,7 @@ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-p + obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o + obj-$(CONFIG_PWM_MESON) += pwm-meson.o + obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o ++obj-$(CONFIG_PWM_MEDIATEK_RAMIPS) += pwm-mediatek-ramips.o + obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o + obj-$(CONFIG_PWM_MXS) += pwm-mxs.o + obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o +--- /dev/null ++++ b/drivers/pwm/pwm-mediatek-ramips.c +@@ -0,0 +1,173 @@ ++/* ++ * Mediatek Pulse Width Modulator driver ++ * ++ * Copyright (C) 2015 John Crispin ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define NUM_PWM 4 ++ ++/* PWM registers and bits definitions */ ++#define PWMCON 0x00 ++#define PWMHDUR 0x04 ++#define PWMLDUR 0x08 ++#define PWMGDUR 0x0c ++#define PWMWAVENUM 0x28 ++#define PWMDWIDTH 0x2c ++#define PWMTHRES 0x30 ++ ++/** ++ * struct mtk_pwm_chip - struct representing pwm chip ++ * ++ * @mmio_base: base address of pwm chip ++ * @chip: linux pwm chip representation ++ */ ++struct mtk_pwm_chip { ++ void __iomem *mmio_base; ++ struct pwm_chip chip; ++}; ++ ++static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip) ++{ ++ return container_of(chip, struct mtk_pwm_chip, chip); ++} ++ ++static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num, ++ unsigned long offset) ++{ ++ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset); ++} ++ ++static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip, ++ unsigned int num, unsigned long offset, ++ unsigned long val) ++{ ++ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset); ++} ++ ++static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ++ int duty_ns, int period_ns) ++{ ++ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); ++ u32 resolution = 100 / 4; ++ u32 clkdiv = 0; ++ ++ while (period_ns / resolution > 8191) { ++ clkdiv++; ++ resolution *= 2; ++ } ++ ++ if (clkdiv > 7) ++ return -1; ++ ++ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv); ++ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution); ++ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution); ++ return 0; ++} ++ ++static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); ++ u32 val; ++ ++ val = ioread32(pc->mmio_base); ++ val |= BIT(pwm->hwpwm); ++ iowrite32(val, pc->mmio_base); ++ ++ return 0; ++} ++ ++static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); ++ u32 val; ++ ++ val = ioread32(pc->mmio_base); ++ val &= ~BIT(pwm->hwpwm); ++ iowrite32(val, pc->mmio_base); ++} ++ ++static const struct pwm_ops mtk_pwm_ops = { ++ .config = mtk_pwm_config, ++ .enable = mtk_pwm_enable, ++ .disable = mtk_pwm_disable, ++ .owner = THIS_MODULE, ++}; ++ ++static int mtk_pwm_probe(struct platform_device *pdev) ++{ ++ struct mtk_pwm_chip *pc; ++ struct resource *r; ++ int ret; ++ ++ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); ++ if (!pc) ++ return -ENOMEM; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); ++ if (IS_ERR(pc->mmio_base)) ++ return PTR_ERR(pc->mmio_base); ++ ++ platform_set_drvdata(pdev, pc); ++ ++ pc->chip.dev = &pdev->dev; ++ pc->chip.ops = &mtk_pwm_ops; ++ pc->chip.base = -1; ++ pc->chip.npwm = NUM_PWM; ++ ++ ret = pwmchip_add(&pc->chip); ++ if (ret < 0) ++ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int mtk_pwm_remove(struct platform_device *pdev) ++{ ++ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < NUM_PWM; i++) ++ pwm_disable(&pc->chip.pwms[i]); ++ ++ return pwmchip_remove(&pc->chip); ++} ++ ++static const struct of_device_id mtk_pwm_of_match[] = { ++ { .compatible = "mediatek,mt7628-pwm" }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(of, mtk_pwm_of_match); ++ ++static struct platform_driver mtk_pwm_driver = { ++ .driver = { ++ .name = "mtk-pwm", ++ .owner = THIS_MODULE, ++ .of_match_table = mtk_pwm_of_match, ++ }, ++ .probe = mtk_pwm_probe, ++ .remove = mtk_pwm_remove, ++}; ++ ++module_platform_driver(mtk_pwm_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("John Crispin "); ++MODULE_ALIAS("platform:mtk-pwm"); diff --git a/target/linux/ramips/patches-5.15/850-awake-rt305x-dwc2-controller.patch b/target/linux/ramips/patches-5.15/850-awake-rt305x-dwc2-controller.patch new file mode 100644 index 0000000000..28f72a23ea --- /dev/null +++ b/target/linux/ramips/patches-5.15/850-awake-rt305x-dwc2-controller.patch @@ -0,0 +1,15 @@ +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -510,6 +510,12 @@ static int dwc2_driver_probe(struct plat + if (retval) + return retval; + ++ /* Enable USB port before any regs access */ ++ if (readl(hsotg->regs + PCGCTL) & 0x0f) { ++ writel(0x00, hsotg->regs + PCGCTL); ++ /* TODO: mdelay(25) here? vendor driver don't use it */ ++ } ++ + hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg); + + retval = dwc2_get_dr_mode(hsotg); diff --git a/target/linux/ramips/patches-5.15/855-linkit_bootstrap.patch b/target/linux/ramips/patches-5.15/855-linkit_bootstrap.patch new file mode 100644 index 0000000000..cd81601a72 --- /dev/null +++ b/target/linux/ramips/patches-5.15/855-linkit_bootstrap.patch @@ -0,0 +1,97 @@ +--- a/drivers/misc/Makefile ++++ b/drivers/misc/Makefile +@@ -50,6 +50,7 @@ obj-$(CONFIG_ECHO) += echo/ + obj-$(CONFIG_CXL_BASE) += cxl/ + obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o + obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o ++obj-$(CONFIG_SOC_MT7620) += linkit.o + obj-$(CONFIG_OCXL) += ocxl/ + obj-$(CONFIG_BCM_VK) += bcm-vk/ + obj-y += cardreader/ +--- /dev/null ++++ b/drivers/misc/linkit.c +@@ -0,0 +1,84 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * publishhed by the Free Software Foundation. ++ * ++ * Copyright (C) 2015 John Crispin ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define LINKIT_LATCH_GPIO 11 ++ ++struct linkit_hw_data { ++ char board[16]; ++ char rev[16]; ++}; ++ ++static void sanify_string(char *s) ++{ ++ int i; ++ ++ for (i = 0; i < 15; i++) ++ if (s[i] <= 0x20) ++ s[i] = '\0'; ++ s[15] = '\0'; ++} ++ ++static int linkit_probe(struct platform_device *pdev) ++{ ++ struct linkit_hw_data hw; ++ struct mtd_info *mtd; ++ size_t retlen; ++ int ret; ++ ++ mtd = get_mtd_device_nm("factory"); ++ if (IS_ERR(mtd)) ++ return PTR_ERR(mtd); ++ ++ ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw); ++ put_mtd_device(mtd); ++ ++ sanify_string(hw.board); ++ sanify_string(hw.rev); ++ ++ dev_info(&pdev->dev, "Version : %s\n", hw.board); ++ dev_info(&pdev->dev, "Revision : %s\n", hw.rev); ++ ++ if (!strcmp(hw.board, "LINKITS7688")) { ++ dev_info(&pdev->dev, "setting up bootstrap latch\n"); ++ ++ if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) { ++ dev_err(&pdev->dev, "failed to setup bootstrap gpio\n"); ++ return -1; ++ } ++ gpio_direction_output(LINKIT_LATCH_GPIO, 0); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id linkit_match[] = { ++ { .compatible = "mediatek,linkit" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, linkit_match); ++ ++static struct platform_driver linkit_driver = { ++ .probe = linkit_probe, ++ .driver = { ++ .name = "mtk-linkit", ++ .owner = THIS_MODULE, ++ .of_match_table = linkit_match, ++ }, ++}; ++ ++int __init linkit_init(void) ++{ ++ return platform_driver_register(&linkit_driver); ++} ++late_initcall_sync(linkit_init); From 044ca149f36a08f56fe827a20aa113837c58cb40 Mon Sep 17 00:00:00 2001 From: Huangbin Zhan Date: Sat, 30 Oct 2021 15:28:28 +0800 Subject: [PATCH 22/23] build: autotools: fix cache path the cache directory should be autom4te.cache in all $(PKG_AUTOMAKE_PATHS) rather than $(PKG_BUILD_DIR)/autom4te.cache only Signed-off-by: Huangbin Zhan --- include/autotools.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/autotools.mk b/include/autotools.mk index 0f0d608b26..e9a7a82248 100644 --- a/include/autotools.mk +++ b/include/autotools.mk @@ -35,7 +35,7 @@ define autoreconf $(patsubst %,rm -f %;,$(2)) \ $(foreach p,$(3), \ if [ -f $(p)/configure.ac ] || [ -f $(p)/configure.in ]; then \ - [ -d $(p)/autom4te.cache ] && rm -rf autom4te.cache; \ + [ -d $(p)/autom4te.cache ] && rm -rf $(p)/autom4te.cache; \ [ -e $(p)/config.rpath ] || \ ln -s $(SCRIPT_DIR)/config.rpath $(p)/config.rpath; \ touch NEWS AUTHORS COPYING ABOUT-NLS ChangeLog; \ From 09f620019867365ed82a4b3d1d264f7a282f0941 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 28 Mar 2022 01:58:16 +0100 Subject: [PATCH 23/23] malta: enable testing kernel 5.15 Nothing special is needed here, just add KERNEL_TESTING_PATCHVER. Signed-off-by: Daniel Golle --- target/linux/malta/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/malta/Makefile b/target/linux/malta/Makefile index ab443fda09..7259cff4e9 100644 --- a/target/linux/malta/Makefile +++ b/target/linux/malta/Makefile @@ -11,6 +11,7 @@ INITRAMFS_EXTRA_FILES:= FEATURES:=cpiogz ext4 ramdisk squashfs targz KERNEL_PATCHVER:=5.10 +KERNEL_TESTING_PATCHVER:=5.15 include $(INCLUDE_DIR)/target.mk