From d4dfb566e27e4c67c86d163262719dfa52406a59 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 01/50] dropbear: bump to 2022.83 - update dropbear to latest stable 2022.83; for the changes see https://matt.ucc.asn.au/dropbear/CHANGES - drop patches: - 001-fix-MAX_UNAUTH_CLIENTS-regression.patch - rework patches: - 901-bundled-libs-cflags.patch - refresh remaining patches Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 9 +- ...01-fix-MAX_UNAUTH_CLIENTS-regression.patch | 134 ------------------ .../dropbear/patches/100-pubkey_path.patch | 6 +- .../patches/130-ssh_ignore_x_args.patch | 6 +- .../patches/900-configure-hardening.patch | 35 ++--- .../patches/901-bundled-libs-cflags.patch | 71 ++++------ 6 files changed, 56 insertions(+), 205 deletions(-) delete mode 100644 package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index e98e995ba7..5339bbd108 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -8,14 +8,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dropbear -PKG_VERSION:=2022.82 -PKG_RELEASE:=5 +PKG_VERSION:=2022.83 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ https://matt.ucc.asn.au/dropbear/releases/ \ https://dropbear.nl/mirror/releases/ -PKG_HASH:=3a038d2bbc02bf28bbdd20c012091f741a3ec5cbe460691811d714876aad75d1 +PKG_HASH:=bc5a121ffbc94b5171ad5ebe01be42746d50aa797c9549a4639894a16749443b PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE @@ -114,6 +114,7 @@ DB_OPT_COMMON = \ DEFAULT_PATH|"$(TARGET_INIT_PATH)" \ !!LOCAL_IDENT|"SSH-2.0-dropbear" \ DROPBEAR_CLI_NETCAT|0 \ + !!DROPBEAR_DSS|0 \ DROPBEAR_DSS|0 \ DO_MOTD|0 \ @@ -181,10 +182,12 @@ endef define Build/Compile +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ $(TARGET_CONFIGURE_OPTS) \ + IGNORE_SPEED=1 \ PROGRAMS="dropbear $(if $(CONFIG_DROPBEAR_DBCLIENT),dbclient,) dropbearkey $(if $(CONFIG_DROPBEAR_SCP),scp,)" \ MULTI=1 SCPPROGRESS=1 +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \ $(TARGET_CONFIGURE_OPTS) \ + IGNORE_SPEED=1 \ PROGRAMS="dropbearconvert" endef diff --git a/package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch b/package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch deleted file mode 100644 index e0dca544ec..0000000000 --- a/package/network/services/dropbear/patches/001-fix-MAX_UNAUTH_CLIENTS-regression.patch +++ /dev/null @@ -1,134 +0,0 @@ -From: Matt Johnston -Date: Wed, 8 Jun 2022 21:26:20 +0800 -Subject: Fix MAX_UNAUTH_CLIENTS regression - -Since re-exec change in 2022.82 Dropbear count -treat authenticated sessions towards the unauthenticated -session limit. This is fixed by passing the childpipe FD -through to the re-execed process. ---- - runopts.h | 5 +++-- - svr-main.c | 21 +++++++++++---------- - svr-runopts.c | 15 ++++++++++++--- - 3 files changed, 26 insertions(+), 15 deletions(-) - ---- a/runopts.h -+++ b/runopts.h -@@ -79,8 +79,9 @@ typedef struct svr_runopts { - char *addresses[DROPBEAR_MAX_PORTS]; - - int inetdmode; -- /* Hidden "-2" flag indicates it's re-executing itself */ -- int reexec_child; -+ /* Hidden "-2 childpipe_fd" flag indicates it's re-executing itself, -+ stores the childpipe preauth file descriptor. Set to -1 otherwise. */ -+ int reexec_childpipe; - - /* Flags indicating whether to use ipv4 and ipv6 */ - /* not used yet ---- a/svr-main.c -+++ b/svr-main.c -@@ -71,7 +71,7 @@ int main(int argc, char ** argv) - #endif - - #if DROPBEAR_DO_REEXEC -- if (svr_opts.reexec_child) { -+ if (svr_opts.reexec_childpipe >= 0) { - #ifdef PR_SET_NAME - /* Fix the "Name:" in /proc/pid/status, otherwise it's - a FD number from fexecve. -@@ -102,7 +102,7 @@ static void main_inetd() { - - seedrandom(); - -- if (!svr_opts.reexec_child) { -+ if (svr_opts.reexec_childpipe < 0) { - /* In case our inetd was lax in logging source addresses */ - get_socket_address(0, NULL, NULL, &host, &port, 0); - dropbear_log(LOG_INFO, "Child connection from %s:%s", host, port); -@@ -115,10 +115,8 @@ static void main_inetd() { - setsid(); - } - -- /* Start service program -- * -1 is a dummy childpipe, just something we can close() without -- * mattering. */ -- svr_session(0, -1); -+ /* -1 for childpipe in the inetd case is discarded */ -+ svr_session(0, svr_opts.reexec_childpipe); - - /* notreached */ - } -@@ -347,9 +345,10 @@ static void main_noinetd(int argc, char - - if (execfd >= 0) { - #if DROPBEAR_DO_REEXEC -- /* Add "-2" to the args and re-execute ourself. */ -- char **new_argv = m_malloc(sizeof(char*) * (argc+3)); -- int pos0 = 0, new_argc = argc+1; -+ /* Add "-2 childpipe[1]" to the args and re-execute ourself. */ -+ char **new_argv = m_malloc(sizeof(char*) * (argc+4)); -+ char buf[10]; -+ int pos0 = 0, new_argc = argc+2; - - /* We need to specially handle "dropbearmulti dropbear". */ - if (multipath) { -@@ -359,7 +358,9 @@ static void main_noinetd(int argc, char - } - - memcpy(&new_argv[pos0], argv, sizeof(char*) * argc); -- new_argv[new_argc-1] = "-2"; -+ new_argv[new_argc-2] = "-2"; -+ snprintf(buf, sizeof(buf), "%d", childpipe[1]); -+ new_argv[new_argc-1] = buf; - new_argv[new_argc] = NULL; - - if ((dup2(childsock, STDIN_FILENO) < 0)) { ---- a/svr-runopts.c -+++ b/svr-runopts.c -@@ -138,6 +138,7 @@ void svr_getopts(int argc, char ** argv) - char* keepalive_arg = NULL; - char* idle_timeout_arg = NULL; - char* maxauthtries_arg = NULL; -+ char* reexec_fd_arg = NULL; - char* keyfile = NULL; - char c; - #if DROPBEAR_PLUGIN -@@ -175,6 +176,7 @@ void svr_getopts(int argc, char ** argv) - svr_opts.pubkey_plugin_options = NULL; - #endif - svr_opts.pass_on_env = 0; -+ svr_opts.reexec_childpipe = -1; - - #ifndef DISABLE_ZLIB - opts.compress_mode = DROPBEAR_COMPRESS_DELAYED; -@@ -250,12 +252,12 @@ void svr_getopts(int argc, char ** argv) - #if DROPBEAR_DO_REEXEC && NON_INETD_MODE - /* For internal use by re-exec */ - case '2': -- svr_opts.reexec_child = 1; -+ next = &reexec_fd_arg; - break; - #endif - case 'p': -- nextisport = 1; -- break; -+ nextisport = 1; -+ break; - case 'P': - next = &svr_opts.pidfile; - break; -@@ -426,6 +428,13 @@ void svr_getopts(int argc, char ** argv) - dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command); - } - -+ if (reexec_fd_arg) { -+ if (m_str_to_uint(reexec_fd_arg, &svr_opts.reexec_childpipe) == DROPBEAR_FAILURE -+ || svr_opts.reexec_childpipe < 0) { -+ dropbear_exit("Bad -2"); -+ } -+ } -+ - #if INETD_MODE - if (svr_opts.inetdmode && ( - opts.usingsyslog == 0 diff --git a/package/network/services/dropbear/patches/100-pubkey_path.patch b/package/network/services/dropbear/patches/100-pubkey_path.patch index 0403198062..b1075f8464 100644 --- a/package/network/services/dropbear/patches/100-pubkey_path.patch +++ b/package/network/services/dropbear/patches/100-pubkey_path.patch @@ -1,6 +1,6 @@ --- a/svr-authpubkey.c +++ b/svr-authpubkey.c -@@ -77,6 +77,13 @@ static void send_msg_userauth_pk_ok(cons +@@ -78,6 +78,13 @@ static void send_msg_userauth_pk_ok(cons const unsigned char* keyblob, unsigned int keybloblen); static int checkfileperm(char * filename); @@ -14,7 +14,7 @@ /* process a pubkey auth request, sending success or failure message as * appropriate */ void svr_auth_pubkey(int valid_user) { -@@ -439,14 +446,21 @@ static int checkpubkey(const char* keyal +@@ -462,14 +469,21 @@ static int checkpubkey(const char* keyal if (checkpubkeyperms() == DROPBEAR_FAILURE) { TRACE(("bad authorized_keys permissions, or file doesn't exist")) } else { @@ -44,7 +44,7 @@ authfile = fopen(filename, "r"); if (!authfile) { -@@ -520,27 +534,41 @@ static int checkpubkeyperms() { +@@ -543,27 +557,41 @@ static int checkpubkeyperms() { goto out; } diff --git a/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch b/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch index d7f589801d..a26f33dfbc 100644 --- a/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch +++ b/package/network/services/dropbear/patches/130-ssh_ignore_x_args.patch @@ -1,8 +1,8 @@ --- a/cli-runopts.c +++ b/cli-runopts.c -@@ -325,6 +325,10 @@ void cli_getopts(int argc, char ** argv) - case 'b': - next = &bind_arg; +@@ -329,6 +329,10 @@ void cli_getopts(int argc, char ** argv) + case 'z': + opts.disable_ip_tos = 1; break; + case 'x': + /* compatibility with openssh cli diff --git a/package/network/services/dropbear/patches/900-configure-hardening.patch b/package/network/services/dropbear/patches/900-configure-hardening.patch index 4f806f8b25..5dc84849be 100644 --- a/package/network/services/dropbear/patches/900-configure-hardening.patch +++ b/package/network/services/dropbear/patches/900-configure-hardening.patch @@ -1,6 +1,6 @@ --- a/configure.ac +++ b/configure.ac -@@ -74,53 +74,6 @@ AC_ARG_ENABLE(harden, +@@ -87,54 +87,6 @@ AC_ARG_ENABLE(harden, if test "$hardenbuild" -eq 1; then AC_MSG_NOTICE(Checking for available hardened build flags:) @@ -11,15 +11,15 @@ - - OLDLDFLAGS="$LDFLAGS" - TESTFLAGS="-Wl,-pie" -- LDFLAGS="$LDFLAGS $TESTFLAGS" -- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], -- [AC_MSG_NOTICE([Setting $TESTFLAGS])], +- LDFLAGS="$TESTFLAGS $LDFLAGS" +- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], +- [AC_MSG_NOTICE([Setting $TESTFLAGS])], - [ - LDFLAGS="$OLDLDFLAGS" - TESTFLAGS="-pie" -- LDFLAGS="$LDFLAGS $TESTFLAGS" -- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], -- [AC_MSG_NOTICE([Setting $TESTFLAGS])], +- LDFLAGS="$TESTFLAGS $LDFLAGS" +- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], +- [AC_MSG_NOTICE([Setting $TESTFLAGS])], - [AC_MSG_NOTICE([Not setting $TESTFLAGS]); LDFLAGS="$OLDLDFLAGS" ] - ) - ] @@ -27,30 +27,31 @@ - # readonly elf relocation sections (relro) - OLDLDFLAGS="$LDFLAGS" - TESTFLAGS="-Wl,-z,now -Wl,-z,relro" -- LDFLAGS="$LDFLAGS $TESTFLAGS" -- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], -- [AC_MSG_NOTICE([Setting $TESTFLAGS])], +- LDFLAGS="$TESTFLAGS $LDFLAGS" +- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], +- [AC_MSG_NOTICE([Setting $TESTFLAGS])], - [AC_MSG_NOTICE([Not setting $TESTFLAGS]); LDFLAGS="$OLDLDFLAGS" ] - ) - fi # non-static - # stack protector. -strong is good but only in gcc 4.9 or later - OLDCFLAGS="$CFLAGS" - TESTFLAGS="-fstack-protector-strong" -- CFLAGS="$CFLAGS $TESTFLAGS" -- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], -- [AC_MSG_NOTICE([Setting $TESTFLAGS])], +- CFLAGS="$TESTFLAGS $CFLAGS" +- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], +- [AC_MSG_NOTICE([Setting $TESTFLAGS])], - [ - CFLAGS="$OLDCFLAGS" - TESTFLAGS="-fstack-protector --param=ssp-buffer-size=4" -- CFLAGS="$CFLAGS $TESTFLAGS" -- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], -- [AC_MSG_NOTICE([Setting $TESTFLAGS])], +- CFLAGS="$TESTFLAGS $CFLAGS" +- AC_LINK_IFELSE([AC_LANG_PROGRAM([])], +- [AC_MSG_NOTICE([Setting $TESTFLAGS])], - [AC_MSG_NOTICE([Not setting $TESTFLAGS]); CFLAGS="$OLDCFLAGS" ] - ) - ] - ) - # FORTIFY_SOURCE - DB_TRYADDCFLAGS([-D_FORTIFY_SOURCE=2]) - +- # Spectre v2 mitigations DB_TRYADDCFLAGS([-mfunction-return=thunk]) + DB_TRYADDCFLAGS([-mindirect-branch=thunk]) diff --git a/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch b/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch index 2432b4ef72..a9a441ce76 100644 --- a/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch +++ b/package/network/services/dropbear/patches/901-bundled-libs-cflags.patch @@ -1,48 +1,29 @@ ---- a/libtomcrypt/makefile_include.mk -+++ b/libtomcrypt/makefile_include.mk -@@ -94,6 +94,13 @@ endif +--- a/configure.ac ++++ b/configure.ac +@@ -45,11 +45,8 @@ fi + # LTM_CFLAGS is given to ./configure by the user, + # DROPBEAR_LTM_CFLAGS is substituted in the LTM Makefile.in + DROPBEAR_LTM_CFLAGS="$LTM_CFLAGS" +-if test -z "$DROPBEAR_LTM_CFLAGS"; then +- DROPBEAR_LTM_CFLAGS="-O3 -funroll-loops -fomit-frame-pointer" +-fi +-AC_MSG_NOTICE(Setting LTM_CFLAGS to $DROPBEAR_LTM_CFLAGS) +-AC_ARG_VAR(LTM_CFLAGS, CFLAGS for bundled libtommath. Default -O3 -funroll-loops -fomit-frame-pointer) ++AC_MSG_NOTICE(Setting LTM_CFLAGS to '$DROPBEAR_LTM_CFLAGS') ++AC_ARG_VAR(LTM_CFLAGS, CFLAGS for bundled libtommath. Defaults to empty string) + AC_SUBST(DROPBEAR_LTM_CFLAGS) - LTC_CFLAGS += -Wno-type-limits + AC_MSG_NOTICE([Checking if compiler '$CC' supports -Wno-pointer-sign]) +--- a/libtomcrypt/src/headers/tomcrypt_dropbear.h ++++ b/libtomcrypt/src/headers/tomcrypt_dropbear.h +@@ -7,8 +7,10 @@ -+ifdef OPENWRT_BUILD -+ ifeq (-Os,$(filter -Os,$(CFLAGS))) -+ LTC_CFLAGS += -DLTC_SMALL_CODE -+ endif -+else -+ ### ! OPENWRT_BUILD -+ - ifdef LTC_DEBUG - $(info Debug build) - # compile for DEBUGGING (required for ccmalloc checking!!!) -@@ -121,6 +128,9 @@ endif - endif # COMPILE_SMALL - endif # COMPILE_DEBUG + /* Use small code where possible */ + #if DROPBEAR_SMALL_CODE ++#ifndef LTC_SMALL_CODE + #define LTC_SMALL_CODE + #endif ++#endif -+ ### ! OPENWRT_BUILD -+endif -+ - - ifneq ($(findstring clang,$(CC)),) - LTC_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header -Wno-missing-field-initializers ---- a/libtommath/makefile_include.mk -+++ b/libtommath/makefile_include.mk -@@ -70,6 +70,9 @@ else - LTM_CFLAGS += -Wsystem-headers - endif - -+ifndef OPENWRT_BUILD -+ ### ! OPENWRT_BUILD -+ - ifdef COMPILE_DEBUG - #debug - LTM_CFLAGS += -g3 -@@ -90,6 +93,9 @@ endif - - endif # COMPILE_SIZE - -+ ### ! OPENWRT_BUILD -+endif -+ - ifneq ($(findstring clang,$(CC)),) - LTM_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header - endif + /* Fewer entries needed */ + #define TAB_SIZE 5 From b5cde260487eae86db1661a53e5e5e0823936aab Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 02/50] dropbear: cherry-pick upstream patches critical fixes: - libtommath: possible integer overflow (CVE-2023-36328) - implement Strict KEX mode (CVE-2023-48795) various fixes: - fix DROPBEAR_DSS and DROPBEAR_RSA config options - y2038 issues - remove SO_LINGER socket option - make banner reading failure non-fatal - fix "noremotetcp" behavior - don't try to shutdown a pty - fix test for multiuser kernels adds new features: - option to bind to interface - allow inetd with non-syslog - ignore unsupported command line options with dropbearkey Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 1 - .../001-add-if-DROPBEAR_RSA-guards.patch | 104 +++++++++ .../patches/002-fix-y2038-issues.patch | 198 ++++++++++++++++ .../patches/003-fix-DROPBEAR_DSS.patch | 25 ++ ...rs-s-own-gid-in-pty-permission-check.patch | 24 ++ .../patches/005-const-parameter-mp_int.patch | 123 ++++++++++ ...pbearkey-add-missing-break-in-switch.patch | 21 ++ ...7-fix-building-only-client-or-server.patch | 29 +++ ...e-rsa-signatures-when-no-rsa-hostkey.patch | 94 ++++++++ ...-rather-than-fprintf-in-segv-handler.patch | 27 +++ .../patches/010-remove-SO_LINGER.patch | 39 ++++ .../011-add-option-to-bind-to-interface.patch | 147 ++++++++++++ ...add-ifdef-guards-for-SO_BINDTODEVICE.patch | 50 ++++ ...ake-banner-reading-failure-non-fatal.patch | 74 ++++++ ...nore-unsupported-command-line-option.patch | 60 +++++ ...ommath-fix-possible-integer-overflow.patch | 121 ++++++++++ ...-svr-tcpfwd-Fix-noremotetcp-behavior.patch | 35 +++ .../017-Don-t-try-to-shutdown-a-pty.patch | 32 +++ ...-dropbearkey-add-alias-to-ssh-keygen.patch | 33 +++ .../019-Allow-inetd-with-non-syslog.patch | 34 +++ .../020-Fix-test-for-multiuser-kernels.patch | 33 +++ .../021-Implement-Strict-KEX-mode.patch | 216 ++++++++++++++++++ ...nkey-fix-use-of-rsa-sha2-256-pubkeys.patch | 2 +- 23 files changed, 1520 insertions(+), 2 deletions(-) create mode 100644 package/network/services/dropbear/patches/001-add-if-DROPBEAR_RSA-guards.patch create mode 100644 package/network/services/dropbear/patches/002-fix-y2038-issues.patch create mode 100644 package/network/services/dropbear/patches/003-fix-DROPBEAR_DSS.patch create mode 100644 package/network/services/dropbear/patches/004-allow-users-s-own-gid-in-pty-permission-check.patch create mode 100644 package/network/services/dropbear/patches/005-const-parameter-mp_int.patch create mode 100644 package/network/services/dropbear/patches/006-dropbearkey-add-missing-break-in-switch.patch create mode 100644 package/network/services/dropbear/patches/007-fix-building-only-client-or-server.patch create mode 100644 package/network/services/dropbear/patches/008-disable-rsa-signatures-when-no-rsa-hostkey.patch create mode 100644 package/network/services/dropbear/patches/009-use-write-rather-than-fprintf-in-segv-handler.patch create mode 100644 package/network/services/dropbear/patches/010-remove-SO_LINGER.patch create mode 100644 package/network/services/dropbear/patches/011-add-option-to-bind-to-interface.patch create mode 100644 package/network/services/dropbear/patches/012-add-ifdef-guards-for-SO_BINDTODEVICE.patch create mode 100644 package/network/services/dropbear/patches/013-make-banner-reading-failure-non-fatal.patch create mode 100644 package/network/services/dropbear/patches/014-dropbearkey-ignore-unsupported-command-line-option.patch create mode 100644 package/network/services/dropbear/patches/015-libtommath-fix-possible-integer-overflow.patch create mode 100644 package/network/services/dropbear/patches/016-src-svr-tcpfwd-Fix-noremotetcp-behavior.patch create mode 100644 package/network/services/dropbear/patches/017-Don-t-try-to-shutdown-a-pty.patch create mode 100644 package/network/services/dropbear/patches/018-dropbearkey-add-alias-to-ssh-keygen.patch create mode 100644 package/network/services/dropbear/patches/019-Allow-inetd-with-non-syslog.patch create mode 100644 package/network/services/dropbear/patches/020-Fix-test-for-multiuser-kernels.patch create mode 100644 package/network/services/dropbear/patches/021-Implement-Strict-KEX-mode.patch diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 5339bbd108..d0b0e01646 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -114,7 +114,6 @@ DB_OPT_COMMON = \ DEFAULT_PATH|"$(TARGET_INIT_PATH)" \ !!LOCAL_IDENT|"SSH-2.0-dropbear" \ DROPBEAR_CLI_NETCAT|0 \ - !!DROPBEAR_DSS|0 \ DROPBEAR_DSS|0 \ DO_MOTD|0 \ diff --git a/package/network/services/dropbear/patches/001-add-if-DROPBEAR_RSA-guards.patch b/package/network/services/dropbear/patches/001-add-if-DROPBEAR_RSA-guards.patch new file mode 100644 index 0000000000..ad1a20c520 --- /dev/null +++ b/package/network/services/dropbear/patches/001-add-if-DROPBEAR_RSA-guards.patch @@ -0,0 +1,104 @@ +From 36a03132634a17c667c0fac0a8e1519b3d1b71c6 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Mon, 28 Nov 2022 21:12:23 +0800 +Subject: Add #if DROPBEAR_RSA guards + +Fixes building with DROPBEAR_RSA disabled. +Closes #197 +--- + signkey.c | 8 +++++++- + signkey.h | 2 ++ + sysoptions.h | 5 +---- + 3 files changed, 10 insertions(+), 5 deletions(-) + +--- a/signkey.c ++++ b/signkey.c +@@ -120,6 +120,7 @@ enum signkey_type signkey_type_from_name + /* Special case for rsa-sha2-256. This could be generalised if more + signature names are added that aren't 1-1 with public key names */ + const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) { ++#if DROPBEAR_RSA + #if DROPBEAR_RSA_SHA256 + if (type == DROPBEAR_SIGNATURE_RSA_SHA256) { + if (namelen) { +@@ -136,11 +137,13 @@ const char* signature_name_from_type(enu + return SSH_SIGNKEY_RSA; + } + #endif ++#endif /* DROPBEAR_RSA */ + return signkey_name_from_type((enum signkey_type)type, namelen); + } + + /* Returns DROPBEAR_SIGNATURE_NONE if none match */ + enum signature_type signature_type_from_name(const char* name, unsigned int namelen) { ++#if DROPBEAR_RSA + #if DROPBEAR_RSA_SHA256 + if (namelen == strlen(SSH_SIGNATURE_RSA_SHA256) + && memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) { +@@ -153,10 +156,11 @@ enum signature_type signature_type_from_ + return DROPBEAR_SIGNATURE_RSA_SHA1; + } + #endif ++#endif /* DROPBEAR_RSA */ + return (enum signature_type)signkey_type_from_name(name, namelen); + } + +-/* Returns the signature type from a key type. Must not be called ++/* Returns the signature type from a key type. Must not be called + with RSA keytype */ + enum signature_type signature_type_from_signkey(enum signkey_type keytype) { + #if DROPBEAR_RSA +@@ -167,6 +171,7 @@ enum signature_type signature_type_from_ + } + + enum signkey_type signkey_type_from_signature(enum signature_type sigtype) { ++#if DROPBEAR_RSA + #if DROPBEAR_RSA_SHA256 + if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) { + return DROPBEAR_SIGNKEY_RSA; +@@ -177,6 +182,7 @@ enum signkey_type signkey_type_from_sign + return DROPBEAR_SIGNKEY_RSA; + } + #endif ++#endif /* DROPBEAR_RSA */ + assert((int)sigtype < (int)DROPBEAR_SIGNKEY_NUM_NAMED); + return (enum signkey_type)sigtype; + } +--- a/signkey.h ++++ b/signkey.h +@@ -79,12 +79,14 @@ enum signature_type { + DROPBEAR_SIGNATURE_SK_ED25519 = DROPBEAR_SIGNKEY_SK_ED25519, + #endif + #endif ++#if DROPBEAR_RSA + #if DROPBEAR_RSA_SHA1 + DROPBEAR_SIGNATURE_RSA_SHA1 = 100, /* ssh-rsa signature (sha1) */ + #endif + #if DROPBEAR_RSA_SHA256 + DROPBEAR_SIGNATURE_RSA_SHA256 = 101, /* rsa-sha2-256 signature. has a ssh-rsa key */ + #endif ++#endif /* DROPBEAR_RSA */ + DROPBEAR_SIGNATURE_NONE = DROPBEAR_SIGNKEY_NONE, + }; + +--- a/sysoptions.h ++++ b/sysoptions.h +@@ -137,7 +137,7 @@ + + /* Debian doesn't define this in system headers */ + #if !defined(LTM_DESC) && (DROPBEAR_ECC) +-#define LTM_DESC ++#define LTM_DESC + #endif + + #define DROPBEAR_ECC_256 (DROPBEAR_ECC) +@@ -151,9 +151,6 @@ + * signing operations slightly slower. */ + #define DROPBEAR_RSA_BLINDING 1 + +-#ifndef DROPBEAR_RSA_SHA1 +-#define DROPBEAR_RSA_SHA1 DROPBEAR_RSA +-#endif + #ifndef DROPBEAR_RSA_SHA256 + #define DROPBEAR_RSA_SHA256 DROPBEAR_RSA + #endif diff --git a/package/network/services/dropbear/patches/002-fix-y2038-issues.patch b/package/network/services/dropbear/patches/002-fix-y2038-issues.patch new file mode 100644 index 0000000000..0654e3b98b --- /dev/null +++ b/package/network/services/dropbear/patches/002-fix-y2038-issues.patch @@ -0,0 +1,198 @@ +From ec2215726cffb976019d08ebf569edd2229e9dba Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Thu, 1 Dec 2022 11:34:43 +0800 +Subject: Fix y2038 issues with time_t conversion + +These changes were identified by building with and without +-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 +on 32-bit arm, logging warnings to files. +-Wconversion was added to CFLAGS in both builds. + +Then a "diff -I Wconversion log1 log2" shows new warnings that appear +with the 64-bit time_t. There are a few false positives that have been +fixed for quietness. + +struct logininfo and struct wtmp are still problematic, those will +need to be handled by libc. +--- + common-session.c | 43 +++++++++++++++++++++++++++---------------- + dbutil.c | 2 +- + loginrec.c | 2 ++ + loginrec.h | 4 ++-- + runopts.h | 4 ++-- + svr-auth.c | 2 +- + 6 files changed, 35 insertions(+), 22 deletions(-) + +--- a/common-session.c ++++ b/common-session.c +@@ -519,15 +519,24 @@ static void send_msg_keepalive() { + ses.last_packet_time_idle = old_time_idle; + } + ++/* Returns the difference in seconds, clamped to LONG_MAX */ ++static long elapsed(time_t now, time_t prev) { ++ time_t del = now - prev; ++ if (del > LONG_MAX) { ++ return LONG_MAX; ++ } ++ return (long)del; ++} ++ + /* Check all timeouts which are required. Currently these are the time for + * user authentication, and the automatic rekeying. */ + static void checktimeouts() { + + time_t now; + now = monotonic_now(); +- ++ + if (IS_DROPBEAR_SERVER && ses.connect_time != 0 +- && now - ses.connect_time >= AUTH_TIMEOUT) { ++ && elapsed(now, ses.connect_time) >= AUTH_TIMEOUT) { + dropbear_close("Timeout before auth"); + } + +@@ -537,45 +546,47 @@ static void checktimeouts() { + } + + if (!ses.kexstate.sentkexinit +- && (now - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT ++ && (elapsed(now, ses.kexstate.lastkextime) >= KEX_REKEY_TIMEOUT + || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)) { + TRACE(("rekeying after timeout or max data reached")) + send_msg_kexinit(); + } +- ++ + if (opts.keepalive_secs > 0 && ses.authstate.authdone) { + /* Avoid sending keepalives prior to auth - those are + not valid pre-auth packet types */ + + /* Send keepalives if we've been idle */ +- if (now - ses.last_packet_time_any_sent >= opts.keepalive_secs) { ++ if (elapsed(now, ses.last_packet_time_any_sent) >= opts.keepalive_secs) { + send_msg_keepalive(); + } + + /* Also send an explicit keepalive message to trigger a response + if the remote end hasn't sent us anything */ +- if (now - ses.last_packet_time_keepalive_recv >= opts.keepalive_secs +- && now - ses.last_packet_time_keepalive_sent >= opts.keepalive_secs) { ++ if (elapsed(now, ses.last_packet_time_keepalive_recv) >= opts.keepalive_secs ++ && elapsed(now, ses.last_packet_time_keepalive_sent) >= opts.keepalive_secs) { + send_msg_keepalive(); + } + +- if (now - ses.last_packet_time_keepalive_recv ++ if (elapsed(now, ses.last_packet_time_keepalive_recv) + >= opts.keepalive_secs * DEFAULT_KEEPALIVE_LIMIT) { + dropbear_exit("Keepalive timeout"); + } + } + +- if (opts.idle_timeout_secs > 0 +- && now - ses.last_packet_time_idle >= opts.idle_timeout_secs) { ++ if (opts.idle_timeout_secs > 0 ++ && elapsed(now, ses.last_packet_time_idle) >= opts.idle_timeout_secs) { + dropbear_close("Idle timeout"); + } + } + +-static void update_timeout(long limit, long now, long last_event, long * timeout) { +- TRACE2(("update_timeout limit %ld, now %ld, last %ld, timeout %ld", +- limit, now, last_event, *timeout)) ++static void update_timeout(long limit, time_t now, time_t last_event, long * timeout) { ++ TRACE2(("update_timeout limit %ld, now %llu, last %llu, timeout %ld", ++ limit, ++ (unsigned long long)now, ++ (unsigned long long)last_event, *timeout)) + if (last_event > 0 && limit > 0) { +- *timeout = MIN(*timeout, last_event+limit-now); ++ *timeout = MIN(*timeout, elapsed(now, last_event) + limit); + TRACE2(("new timeout %ld", *timeout)) + } + } +@@ -584,7 +595,7 @@ static long select_timeout() { + /* determine the minimum timeout that might be required, so + as to avoid waking when unneccessary */ + long timeout = KEX_REKEY_TIMEOUT; +- long now = monotonic_now(); ++ time_t now = monotonic_now(); + + if (!ses.kexstate.sentkexinit) { + update_timeout(KEX_REKEY_TIMEOUT, now, ses.kexstate.lastkextime, &timeout); +@@ -596,7 +607,7 @@ static long select_timeout() { + } + + if (ses.authstate.authdone) { +- update_timeout(opts.keepalive_secs, now, ++ update_timeout(opts.keepalive_secs, now, + MAX(ses.last_packet_time_keepalive_recv, ses.last_packet_time_keepalive_sent), + &timeout); + } +--- a/dbutil.c ++++ b/dbutil.c +@@ -724,7 +724,7 @@ void gettime_wrapper(struct timespec *no + /* Fallback for everything else - this will sometimes go backwards */ + gettimeofday(&tv, NULL); + now->tv_sec = tv.tv_sec; +- now->tv_nsec = 1000*tv.tv_usec; ++ now->tv_nsec = 1000*(long)tv.tv_usec; + } + + /* second-resolution monotonic timestamp */ +--- a/loginrec.c ++++ b/loginrec.c +@@ -459,6 +459,7 @@ line_abbrevname(char *dst, const char *s + void + set_utmp_time(struct logininfo *li, struct utmp *ut) + { ++ /* struct utmp in glibc isn't y2038 safe yet */ + # ifdef HAVE_STRUCT_UTMP_UT_TV + ut->ut_tv.tv_sec = li->tv_sec; + ut->ut_tv.tv_usec = li->tv_usec; +@@ -1272,6 +1273,7 @@ lastlog_construct(struct logininfo *li, + (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); + strlcpy(last->ll_host, li->hostname, + MIN_SIZEOF(last->ll_host, li->hostname)); ++ /* struct lastlog in glibc isn't y2038 safe yet */ + last->ll_time = li->tv_sec; + } + +--- a/loginrec.h ++++ b/loginrec.h +@@ -139,8 +139,8 @@ struct logininfo { + /* struct timeval (sys/time.h) isn't always available, if it isn't we'll + * use time_t's value as tv_sec and set tv_usec to 0 + */ +- unsigned int tv_sec; +- unsigned int tv_usec; ++ time_t tv_sec; ++ suseconds_t tv_usec; + union login_netinfo hostaddr; /* caller's host address(es) */ + }; /* struct logininfo */ + +--- a/runopts.h ++++ b/runopts.h +@@ -39,8 +39,8 @@ typedef struct runopts { + int listen_fwd_all; + #endif + unsigned int recv_window; +- time_t keepalive_secs; /* Time between sending keepalives. 0 is off */ +- time_t idle_timeout_secs; /* Exit if no traffic is sent/received in this time */ ++ long keepalive_secs; /* Time between sending keepalives. 0 is off */ ++ long idle_timeout_secs; /* Exit if no traffic is sent/received in this time */ + int usingsyslog; + + #ifndef DISABLE_ZLIB +--- a/svr-auth.c ++++ b/svr-auth.c +@@ -389,7 +389,7 @@ void send_msg_userauth_failure(int parti + Beware of integer overflow if increasing these values */ + const unsigned int mindelay = 250000000; + const unsigned int vardelay = 100000000; +- unsigned int rand_delay; ++ suseconds_t rand_delay; + struct timespec delay; + + gettime_wrapper(&delay); diff --git a/package/network/services/dropbear/patches/003-fix-DROPBEAR_DSS.patch b/package/network/services/dropbear/patches/003-fix-DROPBEAR_DSS.patch new file mode 100644 index 0000000000..6789800e12 --- /dev/null +++ b/package/network/services/dropbear/patches/003-fix-DROPBEAR_DSS.patch @@ -0,0 +1,25 @@ +From c043efb47c3173072fa636ca0da0d19875d4511f Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 6 Dec 2022 22:34:11 +0800 +Subject: Fix so DROPBEAR_DSS is only forced for fuzzing + +Regression from 787391ea3b5af2acf5e3c83372510f0c79477ad7, +was missing fuzzing conditional +--- + sysoptions.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sysoptions.h ++++ b/sysoptions.h +@@ -380,9 +380,11 @@ + #endif + + /* Fuzzing expects all key types to be enabled */ ++#if DROPBEAR_FUZZ + #if defined(DROPBEAR_DSS) + #undef DROPBEAR_DSS + #endif + #define DROPBEAR_DSS 1 ++#endif + + /* no include guard for this file */ diff --git a/package/network/services/dropbear/patches/004-allow-users-s-own-gid-in-pty-permission-check.patch b/package/network/services/dropbear/patches/004-allow-users-s-own-gid-in-pty-permission-check.patch new file mode 100644 index 0000000000..bcb43aed2a --- /dev/null +++ b/package/network/services/dropbear/patches/004-allow-users-s-own-gid-in-pty-permission-check.patch @@ -0,0 +1,24 @@ +From 860721558837441ab45019858e710a2625ffa46e Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Wed, 7 Dec 2022 13:04:10 +0800 +Subject: Allow users's own gid in pty permission check + +This allows non-root Dropbear to work even without devpts gid=5 mount +option on Linux. +--- + sshpty.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/sshpty.c ++++ b/sshpty.c +@@ -380,7 +380,9 @@ pty_setowner(struct passwd *pw, const ch + tty_name, strerror(errno)); + } + +- if (st.st_uid != pw->pw_uid || st.st_gid != gid) { ++ /* Allow either "tty" gid or user's own gid. On Linux with openpty() ++ * this varies depending on the devpts mount options */ ++ if (st.st_uid != pw->pw_uid || !(st.st_gid == gid || st.st_gid == pw->pw_gid)) { + if (chown(tty_name, pw->pw_uid, gid) < 0) { + if (errno == EROFS && + (st.st_uid == pw->pw_uid || st.st_uid == 0)) { diff --git a/package/network/services/dropbear/patches/005-const-parameter-mp_int.patch b/package/network/services/dropbear/patches/005-const-parameter-mp_int.patch new file mode 100644 index 0000000000..0d23c9c416 --- /dev/null +++ b/package/network/services/dropbear/patches/005-const-parameter-mp_int.patch @@ -0,0 +1,123 @@ +From 01415ef8269e594a647f67ea0729ca8b590679de Mon Sep 17 00:00:00 2001 +From: Francois Perrad +Date: Thu, 22 Dec 2022 10:19:54 +0100 +Subject: const parameter mp_int + +--- + bignum.c | 2 +- + bignum.h | 2 +- + buffer.c | 2 +- + buffer.h | 2 +- + dbrandom.c | 2 +- + dbrandom.h | 2 +- + dbutil.c | 2 +- + dbutil.h | 2 +- + genrsa.c | 4 ++-- + 9 files changed, 10 insertions(+), 10 deletions(-) + +--- a/bignum.c ++++ b/bignum.c +@@ -93,7 +93,7 @@ void bytes_to_mp(mp_int *mp, const unsig + + /* hash the ssh representation of the mp_int mp */ + void hash_process_mp(const struct ltc_hash_descriptor *hash_desc, +- hash_state *hs, mp_int *mp) { ++ hash_state *hs, const mp_int *mp) { + buffer * buf; + + buf = buf_new(512 + 20); /* max buffer is a 4096 bit key, +--- a/bignum.h ++++ b/bignum.h +@@ -33,6 +33,6 @@ void m_mp_alloc_init_multi(mp_int **mp, + void m_mp_free_multi(mp_int **mp, ...) ATTRIB_SENTINEL; + void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len); + void hash_process_mp(const struct ltc_hash_descriptor *hash_desc, +- hash_state *hs, mp_int *mp); ++ hash_state *hs, const mp_int *mp); + + #endif /* DROPBEAR_BIGNUM_H_ */ +--- a/buffer.c ++++ b/buffer.c +@@ -299,7 +299,7 @@ void buf_putbytes(buffer *buf, const uns + + /* for our purposes we only need positive (or 0) numbers, so will + * fail if we get negative numbers */ +-void buf_putmpint(buffer* buf, mp_int * mp) { ++void buf_putmpint(buffer* buf, const mp_int * mp) { + size_t written; + unsigned int len, pad = 0; + TRACE2(("enter buf_putmpint")) +--- a/buffer.h ++++ b/buffer.h +@@ -65,7 +65,7 @@ void buf_putint(buffer* buf, unsigned in + void buf_putstring(buffer* buf, const char* str, unsigned int len); + void buf_putbufstring(buffer *buf, const buffer* buf_str); + void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len); +-void buf_putmpint(buffer* buf, mp_int * mp); ++void buf_putmpint(buffer* buf, const mp_int * mp); + int buf_getmpint(buffer* buf, mp_int* mp); + unsigned int buf_getint(buffer* buf); + +--- a/dbrandom.c ++++ b/dbrandom.c +@@ -347,7 +347,7 @@ void genrandom(unsigned char* buf, unsig + * rand must be an initialised *mp_int for the result. + * the result rand satisfies: 0 < rand < max + * */ +-void gen_random_mpint(mp_int *max, mp_int *rand) { ++void gen_random_mpint(const mp_int *max, mp_int *rand) { + + unsigned char *randbuf = NULL; + unsigned int len = 0; +--- a/dbrandom.h ++++ b/dbrandom.h +@@ -30,6 +30,6 @@ + void seedrandom(void); + void genrandom(unsigned char* buf, unsigned int len); + void addrandom(const unsigned char * buf, unsigned int len); +-void gen_random_mpint(mp_int *max, mp_int *rand); ++void gen_random_mpint(const mp_int *max, mp_int *rand); + + #endif /* DROPBEAR_RANDOM_H_ */ +--- a/dbutil.c ++++ b/dbutil.c +@@ -442,7 +442,7 @@ void printhex(const char * label, const + } + } + +-void printmpint(const char *label, mp_int *mp) { ++void printmpint(const char *label, const mp_int *mp) { + buffer *buf = buf_new(1000); + buf_putmpint(buf, mp); + fprintf(stderr, "%d bits ", mp_count_bits(mp)); +--- a/dbutil.h ++++ b/dbutil.h +@@ -53,7 +53,7 @@ void dropbear_trace3(const char* format, + void dropbear_trace4(const char* format, ...) ATTRIB_PRINTF(1,2); + void dropbear_trace5(const char* format, ...) ATTRIB_PRINTF(1,2); + void printhex(const char * label, const unsigned char * buf, int len); +-void printmpint(const char *label, mp_int *mp); ++void printmpint(const char *label, const mp_int *mp); + void debug_start_net(void); + extern int debug_trace; + #endif +--- a/genrsa.c ++++ b/genrsa.c +@@ -34,7 +34,7 @@ + #if DROPBEAR_RSA + + static void getrsaprime(mp_int* prime, mp_int *primeminus, +- mp_int* rsa_e, unsigned int size_bytes); ++ const mp_int* rsa_e, unsigned int size_bytes); + + /* mostly taken from libtomcrypt's rsa key generation routine */ + dropbear_rsa_key * gen_rsa_priv_key(unsigned int size) { +@@ -89,7 +89,7 @@ dropbear_rsa_key * gen_rsa_priv_key(unsi + + /* return a prime suitable for p or q */ + static void getrsaprime(mp_int* prime, mp_int *primeminus, +- mp_int* rsa_e, unsigned int size_bytes) { ++ const mp_int* rsa_e, unsigned int size_bytes) { + + unsigned char *buf; + int trials; diff --git a/package/network/services/dropbear/patches/006-dropbearkey-add-missing-break-in-switch.patch b/package/network/services/dropbear/patches/006-dropbearkey-add-missing-break-in-switch.patch new file mode 100644 index 0000000000..c7011021c1 --- /dev/null +++ b/package/network/services/dropbear/patches/006-dropbearkey-add-missing-break-in-switch.patch @@ -0,0 +1,21 @@ +From 39d955c49f31fc155e885447ee2be61c869d8c2d Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 3 Jan 2023 22:05:14 +0800 +Subject: Add missing break in switch + +Has no effect on execution, the fallthrough does nothing +Closes #208 +--- + dropbearkey.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/dropbearkey.c ++++ b/dropbearkey.c +@@ -139,6 +139,7 @@ static void check_signkey_bits(enum sign + dropbear_exit("DSS keys have a fixed size of 1024 bits\n"); + exit(EXIT_FAILURE); + } ++ break; + #endif + default: + (void)0; /* quiet, compiler. ecdsa handles checks itself */ diff --git a/package/network/services/dropbear/patches/007-fix-building-only-client-or-server.patch b/package/network/services/dropbear/patches/007-fix-building-only-client-or-server.patch new file mode 100644 index 0000000000..5fcfaad180 --- /dev/null +++ b/package/network/services/dropbear/patches/007-fix-building-only-client-or-server.patch @@ -0,0 +1,29 @@ +From 7a53c7f0f4b3eb23e002819553cb45558642c01d Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Wed, 4 Jan 2023 20:32:23 +0800 +Subject: Fix building only client or server + +Regressed when -Wundef was added + +Fixes #210 +--- + sysoptions.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/sysoptions.h ++++ b/sysoptions.h +@@ -10,6 +10,14 @@ + #define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION + #define PROGNAME "dropbear" + ++#ifndef DROPBEAR_CLIENT ++#define DROPBEAR_CLIENT 0 ++#endif ++ ++#ifndef DROPBEAR_SERVER ++#define DROPBEAR_SERVER 0 ++#endif ++ + /* Spec recommends after one hour or 1 gigabyte of data. One hour + * is a bit too verbose, so we try 8 hours */ + #ifndef KEX_REKEY_TIMEOUT diff --git a/package/network/services/dropbear/patches/008-disable-rsa-signatures-when-no-rsa-hostkey.patch b/package/network/services/dropbear/patches/008-disable-rsa-signatures-when-no-rsa-hostkey.patch new file mode 100644 index 0000000000..4f675234ff --- /dev/null +++ b/package/network/services/dropbear/patches/008-disable-rsa-signatures-when-no-rsa-hostkey.patch @@ -0,0 +1,94 @@ +From a113381c12a2da3c9b7bd594f47a1b2657bdfdf2 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Sun, 12 Feb 2023 22:44:32 +0800 +Subject: Disable rsa signatures when no rsa hostkey + +Otherwise Dropbear will offer RSA as a hostkey signature option, but the +session will exit with an assertion or NULL pointer dereference once +that algorithm is negotiated. + +This likely regressed in 2020.79 when signature vs key type enums were +split, for rsa-sha256. + +Fixes #219 on github +--- + svr-runopts.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +--- a/svr-runopts.c ++++ b/svr-runopts.c +@@ -505,11 +505,11 @@ static void addportandaddress(const char + svr_opts.portcount++; + } + +-static void disablekey(int type) { ++static void disablekey(enum signature_type type) { + int i; + TRACE(("Disabling key type %d", type)) + for (i = 0; sigalgs[i].name != NULL; i++) { +- if (sigalgs[i].val == type) { ++ if ((int)sigalgs[i].val == (int)type) { + sigalgs[i].usable = 0; + break; + } +@@ -624,7 +624,8 @@ void load_all_hostkeys() { + + #if DROPBEAR_RSA + if (!svr_opts.delay_hostkey && !svr_opts.hostkey->rsakey) { +- disablekey(DROPBEAR_SIGNKEY_RSA); ++ disablekey(DROPBEAR_SIGNATURE_RSA_SHA256); ++ disablekey(DROPBEAR_SIGNATURE_RSA_SHA1); + } else { + any_keys = 1; + } +@@ -632,7 +633,7 @@ void load_all_hostkeys() { + + #if DROPBEAR_DSS + if (!svr_opts.delay_hostkey && !svr_opts.hostkey->dsskey) { +- disablekey(DROPBEAR_SIGNKEY_DSS); ++ disablekey(DROPBEAR_SIGNATURE_DSS); + } else { + any_keys = 1; + } +@@ -666,35 +667,35 @@ void load_all_hostkeys() { + #if DROPBEAR_ECC_256 + if (!svr_opts.hostkey->ecckey256 + && (!svr_opts.delay_hostkey || loaded_any_ecdsa || ECDSA_DEFAULT_SIZE != 256 )) { +- disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP256); ++ disablekey(DROPBEAR_SIGNATURE_ECDSA_NISTP256); + } + #endif + #if DROPBEAR_ECC_384 + if (!svr_opts.hostkey->ecckey384 + && (!svr_opts.delay_hostkey || loaded_any_ecdsa || ECDSA_DEFAULT_SIZE != 384 )) { +- disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP384); ++ disablekey(DROPBEAR_SIGNATURE_ECDSA_NISTP384); + } + #endif + #if DROPBEAR_ECC_521 + if (!svr_opts.hostkey->ecckey521 + && (!svr_opts.delay_hostkey || loaded_any_ecdsa || ECDSA_DEFAULT_SIZE != 521 )) { +- disablekey(DROPBEAR_SIGNKEY_ECDSA_NISTP521); ++ disablekey(DROPBEAR_SIGNATURE_ECDSA_NISTP521); + } + #endif + #endif /* DROPBEAR_ECDSA */ + + #if DROPBEAR_ED25519 + if (!svr_opts.delay_hostkey && !svr_opts.hostkey->ed25519key) { +- disablekey(DROPBEAR_SIGNKEY_ED25519); ++ disablekey(DROPBEAR_SIGNATURE_ED25519); + } else { + any_keys = 1; + } + #endif + #if DROPBEAR_SK_ECDSA +- disablekey(DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256); ++ disablekey(DROPBEAR_SIGNATURE_SK_ECDSA_NISTP256); + #endif + #if DROPBEAR_SK_ED25519 +- disablekey(DROPBEAR_SIGNKEY_SK_ED25519); ++ disablekey(DROPBEAR_SIGNATURE_SK_ED25519); + #endif + + if (!any_keys) { diff --git a/package/network/services/dropbear/patches/009-use-write-rather-than-fprintf-in-segv-handler.patch b/package/network/services/dropbear/patches/009-use-write-rather-than-fprintf-in-segv-handler.patch new file mode 100644 index 0000000000..e1538a4c1f --- /dev/null +++ b/package/network/services/dropbear/patches/009-use-write-rather-than-fprintf-in-segv-handler.patch @@ -0,0 +1,27 @@ +From 3292b8c6f1e5fcc405fa0f7a20e90a60f74037b2 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Sun, 12 Feb 2023 23:00:00 +0800 +Subject: Use write() rather than fprintf() in segv handler + +fprintf isn't guaranteed safe (though hasn't had any problems reported). +--- + svr-main.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/svr-main.c ++++ b/svr-main.c +@@ -420,8 +420,12 @@ static void sigchld_handler(int UNUSED(u + + /* catch any segvs */ + static void sigsegv_handler(int UNUSED(unused)) { +- fprintf(stderr, "Aiee, segfault! You should probably report " +- "this as a bug to the developer\n"); ++ int i; ++ const char *msg = "Aiee, segfault! You should probably report " ++ "this as a bug to the developer\n"; ++ i = write(STDERR_FILENO, msg, strlen(msg)); ++ /* ignore short writes */ ++ (void)i; + _exit(EXIT_FAILURE); + } + diff --git a/package/network/services/dropbear/patches/010-remove-SO_LINGER.patch b/package/network/services/dropbear/patches/010-remove-SO_LINGER.patch new file mode 100644 index 0000000000..12b1843ee2 --- /dev/null +++ b/package/network/services/dropbear/patches/010-remove-SO_LINGER.patch @@ -0,0 +1,39 @@ +From 5040f21cb4ee6ade966e60c6d5a3c270d03de1f1 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Mon, 1 May 2023 22:05:43 +0800 +Subject: Remove SO_LINGER + +It could cause channels to take up to 5 seconds to close(), which would block +the entire process. On busy TCP forwarding sessions this would result in +channels seeming stuck and new connections not being accepted. + +We don't need to monitor for flushing failures since we can't report errors, so +SO_LINGER wasn't useful. + +Thanks to GektorUA for reporting and testing + +Fixes #230 +--- + netio.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/netio.c ++++ b/netio.c +@@ -472,7 +472,6 @@ int dropbear_listen(const char* address, + struct addrinfo hints, *res = NULL, *res0 = NULL; + int err; + unsigned int nsock; +- struct linger linger; + int val; + int sock; + uint16_t *allocated_lport_p = NULL; +@@ -551,9 +550,6 @@ int dropbear_listen(const char* address, + val = 1; + /* set to reuse, quick timeout */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); +- linger.l_onoff = 1; +- linger.l_linger = 5; +- setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger)); + + #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + if (res->ai_family == AF_INET6) { diff --git a/package/network/services/dropbear/patches/011-add-option-to-bind-to-interface.patch b/package/network/services/dropbear/patches/011-add-option-to-bind-to-interface.patch new file mode 100644 index 0000000000..d1c1fa4cce --- /dev/null +++ b/package/network/services/dropbear/patches/011-add-option-to-bind-to-interface.patch @@ -0,0 +1,147 @@ +From fb64db9eac3fdc6434f2dc7b5ea407fe5df76e6f Mon Sep 17 00:00:00 2001 +From: Diederik De Coninck +Date: Tue, 11 Apr 2023 15:38:04 +0200 +Subject: Add option to bind to interface + +--- + netio.c | 13 +++++++++++-- + netio.h | 2 +- + runopts.h | 1 + + svr-main.c | 2 +- + svr-runopts.c | 9 +++++++++ + svr-tcpfwd.c | 1 + + tcp-accept.c | 2 +- + tcpfwd.h | 1 + + 8 files changed, 26 insertions(+), 5 deletions(-) + +--- a/netio.c ++++ b/netio.c +@@ -467,7 +467,7 @@ int get_sock_port(int sock) { + * failure, if errstring wasn't NULL, it'll be a newly malloced error + * string.*/ + int dropbear_listen(const char* address, const char* port, +- int *socks, unsigned int sockcount, char **errstring, int *maxfd) { ++ int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface) { + + struct addrinfo hints, *res = NULL, *res0 = NULL; + int err; +@@ -497,7 +497,11 @@ int dropbear_listen(const char* address, + TRACE(("dropbear_listen: local loopback")) + } else { + if (address[0] == '\0') { +- TRACE(("dropbear_listen: all interfaces")) ++ if (interface) { ++ TRACE(("dropbear_listen: %s", interface)) ++ } else { ++ TRACE(("dropbear_listen: all interfaces")) ++ } + address = NULL; + } + hints.ai_flags = AI_PASSIVE; +@@ -551,6 +555,11 @@ int dropbear_listen(const char* address, + /* set to reuse, quick timeout */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); + ++ if(interface && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0) { ++ dropbear_log(LOG_WARNING, "Couldn't set SO_BINDTODEVICE"); ++ TRACE(("Failed setsockopt with errno failure, %d %s", errno, strerror(errno))) ++ } ++ + #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + if (res->ai_family == AF_INET6) { + int on = 1; +--- a/netio.h ++++ b/netio.h +@@ -19,7 +19,7 @@ void get_socket_address(int fd, char **l + void getaddrstring(struct sockaddr_storage* addr, + char **ret_host, char **ret_port, int host_lookup); + int dropbear_listen(const char* address, const char* port, +- int *socks, unsigned int sockcount, char **errstring, int *maxfd); ++ int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface); + + struct dropbear_progress_connection; + +--- a/runopts.h ++++ b/runopts.h +@@ -128,6 +128,7 @@ typedef struct svr_runopts { + char * pidfile; + + char * forced_command; ++ char* interface; + + #if DROPBEAR_PLUGIN + /* malloced */ +--- a/svr-main.c ++++ b/svr-main.c +@@ -488,7 +488,7 @@ static size_t listensockets(int *socks, + + nsock = dropbear_listen(svr_opts.addresses[i], svr_opts.ports[i], &socks[sockpos], + sockcount - sockpos, +- &errstring, maxfd); ++ &errstring, maxfd, svr_opts.interface); + + if (nsock < 0) { + dropbear_log(LOG_WARNING, "Failed listening on '%s': %s", +--- a/svr-runopts.c ++++ b/svr-runopts.c +@@ -98,6 +98,8 @@ static void printhelp(const char * progn + " (default port is %s if none specified)\n" + "-P PidFile Create pid file PidFile\n" + " (default %s)\n" ++ "-l \n" ++ " interface to bind on\n" + #if INETD_MODE + "-i Start for inetd\n" + #endif +@@ -265,6 +267,9 @@ void svr_getopts(int argc, char ** argv) + case 'P': + next = &svr_opts.pidfile; + break; ++ case 'l': ++ next = &svr_opts.interface; ++ break; + #if DO_MOTD + /* motd is displayed by default, -m turns it off */ + case 'm': +@@ -438,6 +443,10 @@ void svr_getopts(int argc, char ** argv) + dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command); + } + ++ if (svr_opts.interface) { ++ dropbear_log(LOG_INFO, "Binding to interface '%s'", svr_opts.interface); ++ } ++ + if (reexec_fd_arg) { + if (m_str_to_uint(reexec_fd_arg, &svr_opts.reexec_childpipe) == DROPBEAR_FAILURE + || svr_opts.reexec_childpipe < 0) { +--- a/svr-tcpfwd.c ++++ b/svr-tcpfwd.c +@@ -205,6 +205,7 @@ static int svr_remotetcpreq(int *allocat + tcpinfo->listenport = port; + tcpinfo->chantype = &svr_chan_tcpremote; + tcpinfo->tcp_type = forwarded; ++ tcpinfo->interface = svr_opts.interface; + + tcpinfo->request_listenaddr = request_addr; + if (!opts.listen_fwd_all || (strcmp(request_addr, "localhost") == 0) ) { +--- a/tcp-accept.c ++++ b/tcp-accept.c +@@ -117,7 +117,7 @@ int listen_tcpfwd(struct TCPListener* tc + snprintf(portstring, sizeof(portstring), "%u", tcpinfo->listenport); + + nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks, +- DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd); ++ DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd, tcpinfo->interface); + if (nsocks < 0) { + dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring); + m_free(errstring); +--- a/tcpfwd.h ++++ b/tcpfwd.h +@@ -42,6 +42,7 @@ struct TCPListener { + unsigned int listenport; + /* The address that the remote host asked to listen on */ + char *request_listenaddr; ++ char* interface; + + const struct ChanType *chantype; + enum {direct, forwarded} tcp_type; diff --git a/package/network/services/dropbear/patches/012-add-ifdef-guards-for-SO_BINDTODEVICE.patch b/package/network/services/dropbear/patches/012-add-ifdef-guards-for-SO_BINDTODEVICE.patch new file mode 100644 index 0000000000..11f902bf90 --- /dev/null +++ b/package/network/services/dropbear/patches/012-add-ifdef-guards-for-SO_BINDTODEVICE.patch @@ -0,0 +1,50 @@ +From 031d09b47912b2401f4934667c0b6f857ede61ee Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Tue, 18 Jul 2023 23:20:16 +0800 +Subject: Add ifdef guards for SO_BINDTODEVICE + +--- + netio.c | 2 ++ + svr-runopts.c | 4 ++++ + 2 files changed, 6 insertions(+) + +--- a/netio.c ++++ b/netio.c +@@ -555,10 +555,12 @@ int dropbear_listen(const char* address, + /* set to reuse, quick timeout */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val)); + ++#ifdef SO_BINDTODEVICE + if(interface && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0) { + dropbear_log(LOG_WARNING, "Couldn't set SO_BINDTODEVICE"); + TRACE(("Failed setsockopt with errno failure, %d %s", errno, strerror(errno))) + } ++#endif + + #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) + if (res->ai_family == AF_INET6) { +--- a/svr-runopts.c ++++ b/svr-runopts.c +@@ -98,8 +98,10 @@ static void printhelp(const char * progn + " (default port is %s if none specified)\n" + "-P PidFile Create pid file PidFile\n" + " (default %s)\n" ++#ifdef SO_BINDTODEVICE + "-l \n" + " interface to bind on\n" ++#endif + #if INETD_MODE + "-i Start for inetd\n" + #endif +@@ -267,9 +269,11 @@ void svr_getopts(int argc, char ** argv) + case 'P': + next = &svr_opts.pidfile; + break; ++#ifdef SO_BINDTODEVICE + case 'l': + next = &svr_opts.interface; + break; ++#endif + #if DO_MOTD + /* motd is displayed by default, -m turns it off */ + case 'm': diff --git a/package/network/services/dropbear/patches/013-make-banner-reading-failure-non-fatal.patch b/package/network/services/dropbear/patches/013-make-banner-reading-failure-non-fatal.patch new file mode 100644 index 0000000000..531215c757 --- /dev/null +++ b/package/network/services/dropbear/patches/013-make-banner-reading-failure-non-fatal.patch @@ -0,0 +1,74 @@ +From 62a06cd95f58060a59359f8769c3f35cd680d4fd Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Sun, 23 Jul 2023 21:01:48 +0800 +Subject: Make banner reading failure non-fatal + +--- + svr-runopts.c | 45 ++++++++++++++++++++++++++++----------------- + 1 file changed, 28 insertions(+), 17 deletions(-) + +--- a/svr-runopts.c ++++ b/svr-runopts.c +@@ -38,6 +38,7 @@ static void printhelp(const char * progn + static void addportandaddress(const char* spec); + static void loadhostkey(const char *keyfile, int fatal_duplicate); + static void addhostkey(const char *keyfile); ++static void load_banner(); + + static void printhelp(const char * progname) { + +@@ -382,23 +383,7 @@ void svr_getopts(int argc, char ** argv) + } + + if (svr_opts.bannerfile) { +- struct stat buf; +- if (stat(svr_opts.bannerfile, &buf) != 0) { +- dropbear_exit("Error opening banner file '%s'", +- svr_opts.bannerfile); +- } +- +- if (buf.st_size > MAX_BANNER_SIZE) { +- dropbear_exit("Banner file too large, max is %d bytes", +- MAX_BANNER_SIZE); +- } +- +- svr_opts.banner = buf_new(buf.st_size); +- if (buf_readfile(svr_opts.banner, svr_opts.bannerfile)!=DROPBEAR_SUCCESS) { +- dropbear_exit("Error reading banner file '%s'", +- svr_opts.bannerfile); +- } +- buf_setpos(svr_opts.banner, 0); ++ load_banner(); + } + + #ifdef HAVE_GETGROUPLIST +@@ -715,3 +700,29 @@ void load_all_hostkeys() { + dropbear_exit("No hostkeys available. 'dropbear -R' may be useful or run dropbearkey."); + } + } ++ ++static void load_banner() { ++ struct stat buf; ++ if (stat(svr_opts.bannerfile, &buf) != 0) { ++ dropbear_log(LOG_WARNING, "Error opening banner file '%s'", ++ svr_opts.bannerfile); ++ return; ++ } ++ ++ if (buf.st_size > MAX_BANNER_SIZE) { ++ dropbear_log(LOG_WARNING, "Banner file too large, max is %d bytes", ++ MAX_BANNER_SIZE); ++ return; ++ } ++ ++ svr_opts.banner = buf_new(buf.st_size); ++ if (buf_readfile(svr_opts.banner, svr_opts.bannerfile) != DROPBEAR_SUCCESS) { ++ dropbear_log(LOG_WARNING, "Error reading banner file '%s'", ++ svr_opts.bannerfile); ++ buf_free(svr_opts.banner); ++ svr_opts.banner = NULL; ++ return; ++ } ++ buf_setpos(svr_opts.banner, 0); ++ ++} diff --git a/package/network/services/dropbear/patches/014-dropbearkey-ignore-unsupported-command-line-option.patch b/package/network/services/dropbear/patches/014-dropbearkey-ignore-unsupported-command-line-option.patch new file mode 100644 index 0000000000..ff130f8be0 --- /dev/null +++ b/package/network/services/dropbear/patches/014-dropbearkey-ignore-unsupported-command-line-option.patch @@ -0,0 +1,60 @@ +From ec26975d442163b66d1646a48e022bc8c2f1607a Mon Sep 17 00:00:00 2001 +From: Sergey Ponomarev +Date: Sun, 27 Aug 2023 00:07:05 +0300 +Subject: dropbearkey.c Ignore unsupported command line options + +To generate non interactively a key with OpenSSH the simplest command is: + +ssh-keygen -t ed25519 -q -N '' -f ~/.ssh/id_ed25519 + +The command has two options -q quiet and -N passphrase which aren't supported by the dropbearkey. + +To improve interoperability add explicit ignoring of the -q and -N with empty passphrase. +Also ignore the -v even if the DEBUG_TRACE is not set. + +Signed-off-by: Sergey Ponomarev +--- + dropbearkey.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/dropbearkey.c ++++ b/dropbearkey.c +@@ -159,6 +159,7 @@ int main(int argc, char ** argv) { + enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; + char * typetext = NULL; + char * sizetext = NULL; ++ char * passphrase = NULL; + unsigned int bits = 0, genbits; + int printpub = 0; + +@@ -194,11 +195,16 @@ int main(int argc, char ** argv) { + printhelp(argv[0]); + exit(EXIT_SUCCESS); + break; +-#if DEBUG_TRACE + case 'v': ++#if DEBUG_TRACE + debug_trace = DROPBEAR_VERBOSE_LEVEL; +- break; + #endif ++ break; ++ case 'q': ++ break; /* quiet is default */ ++ case 'N': ++ next = &passphrase; ++ break; + default: + fprintf(stderr, "Unknown argument %s\n", argv[i]); + printhelp(argv[0]); +@@ -266,6 +272,11 @@ int main(int argc, char ** argv) { + check_signkey_bits(keytype, bits);; + } + ++ if (passphrase && *passphrase != '\0') { ++ fprintf(stderr, "Only empty passphrase is supported\n"); ++ exit(EXIT_FAILURE); ++ } ++ + genbits = signkey_generate_get_bits(keytype, bits); + fprintf(stderr, "Generating %u bit %s key, this may take a while...\n", genbits, typetext); + if (signkey_generate(keytype, bits, filename, 0) == DROPBEAR_FAILURE) diff --git a/package/network/services/dropbear/patches/015-libtommath-fix-possible-integer-overflow.patch b/package/network/services/dropbear/patches/015-libtommath-fix-possible-integer-overflow.patch new file mode 100644 index 0000000000..f39417adb7 --- /dev/null +++ b/package/network/services/dropbear/patches/015-libtommath-fix-possible-integer-overflow.patch @@ -0,0 +1,121 @@ +From 3b576d95dcf791d7b945e75f639da8f89c1685a2 Mon Sep 17 00:00:00 2001 +From: czurnieden +Date: Tue, 9 May 2023 17:17:12 +0200 +Subject: Fix possible integer overflow + +--- + libtommath/bn_mp_2expt.c | 4 ++++ + libtommath/bn_mp_grow.c | 4 ++++ + libtommath/bn_mp_init_size.c | 5 +++++ + libtommath/bn_mp_mul_2d.c | 4 ++++ + libtommath/bn_s_mp_mul_digs.c | 4 ++++ + libtommath/bn_s_mp_mul_digs_fast.c | 4 ++++ + libtommath/bn_s_mp_mul_high_digs.c | 4 ++++ + libtommath/bn_s_mp_mul_high_digs_fast.c | 4 ++++ + 8 files changed, 33 insertions(+) + +--- a/libtommath/bn_mp_2expt.c ++++ b/libtommath/bn_mp_2expt.c +@@ -12,6 +12,10 @@ mp_err mp_2expt(mp_int *a, int b) + { + mp_err err; + ++ if (b < 0) { ++ return MP_VAL; ++ } ++ + /* zero a as per default */ + mp_zero(a); + +--- a/libtommath/bn_mp_grow.c ++++ b/libtommath/bn_mp_grow.c +@@ -9,6 +9,10 @@ mp_err mp_grow(mp_int *a, int size) + int i; + mp_digit *tmp; + ++ if (size < 0) { ++ return MP_VAL; ++ } ++ + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* reallocate the array a->dp +--- a/libtommath/bn_mp_init_size.c ++++ b/libtommath/bn_mp_init_size.c +@@ -6,6 +6,11 @@ + /* init an mp_init for a given size */ + mp_err mp_init_size(mp_int *a, int size) + { ++ ++ if (size < 0) { ++ return MP_VAL; ++ } ++ + size = MP_MAX(MP_MIN_PREC, size); + + /* alloc mem */ +--- a/libtommath/bn_mp_mul_2d.c ++++ b/libtommath/bn_mp_mul_2d.c +@@ -9,6 +9,10 @@ mp_err mp_mul_2d(const mp_int *a, int b, + mp_digit d; + mp_err err; + ++ if (b < 0) { ++ return MP_VAL; ++ } ++ + /* copy */ + if (a != c) { + if ((err = mp_copy(a, c)) != MP_OKAY) { +--- a/libtommath/bn_s_mp_mul_digs.c ++++ b/libtommath/bn_s_mp_mul_digs.c +@@ -16,6 +16,10 @@ mp_err s_mp_mul_digs(const mp_int *a, co + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + ++ if (digs < 0) { ++ return MP_VAL; ++ } ++ + /* can we use the fast multiplier? */ + if ((digs < MP_WARRAY) && + (MP_MIN(a->used, b->used) < MP_MAXFAST)) { +--- a/libtommath/bn_s_mp_mul_digs_fast.c ++++ b/libtommath/bn_s_mp_mul_digs_fast.c +@@ -26,6 +26,10 @@ mp_err s_mp_mul_digs_fast(const mp_int * + mp_digit W[MP_WARRAY]; + mp_word _W; + ++ if (digs < 0) { ++ return MP_VAL; ++ } ++ + /* grow the destination as required */ + if (c->alloc < digs) { + if ((err = mp_grow(c, digs)) != MP_OKAY) { +--- a/libtommath/bn_s_mp_mul_high_digs.c ++++ b/libtommath/bn_s_mp_mul_high_digs.c +@@ -15,6 +15,10 @@ mp_err s_mp_mul_high_digs(const mp_int * + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + ++ if (digs < 0) { ++ return MP_VAL; ++ } ++ + /* can we use the fast multiplier? */ + if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST) + && ((a->used + b->used + 1) < MP_WARRAY) +--- a/libtommath/bn_s_mp_mul_high_digs_fast.c ++++ b/libtommath/bn_s_mp_mul_high_digs_fast.c +@@ -19,6 +19,10 @@ mp_err s_mp_mul_high_digs_fast(const mp_ + mp_digit W[MP_WARRAY]; + mp_word _W; + ++ if (digs < 0) { ++ return MP_VAL; ++ } ++ + /* grow the destination as required */ + pa = a->used + b->used; + if (c->alloc < pa) { diff --git a/package/network/services/dropbear/patches/016-src-svr-tcpfwd-Fix-noremotetcp-behavior.patch b/package/network/services/dropbear/patches/016-src-svr-tcpfwd-Fix-noremotetcp-behavior.patch new file mode 100644 index 0000000000..b6933120e6 --- /dev/null +++ b/package/network/services/dropbear/patches/016-src-svr-tcpfwd-Fix-noremotetcp-behavior.patch @@ -0,0 +1,35 @@ +From 3cf8344769eda55e26eee53c1898b2c66544f188 Mon Sep 17 00:00:00 2001 +From: Justin Chen +Date: Fri, 8 Sep 2023 11:35:18 -0700 +Subject: src: svr-tcpfwd: Fix noremotetcp behavior + +If noremotetcp is set, we should still reply with +send_msg_request_failed. This matches the behavior +of !DROPBEAR_SVR_REMOTETCPFWD. + +We were seeing keepalive packets being ignored when +the "-k" option was used. +--- + svr-tcpfwd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/svr-tcpfwd.c ++++ b/svr-tcpfwd.c +@@ -79,14 +79,14 @@ void recv_msg_global_request_remotetcp() + + TRACE(("enter recv_msg_global_request_remotetcp")) + ++ reqname = buf_getstring(ses.payload, &namelen); ++ wantreply = buf_getbool(ses.payload); ++ + if (svr_opts.noremotetcp || !svr_pubkey_allows_tcpfwd()) { + TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled")) + goto out; + } + +- reqname = buf_getstring(ses.payload, &namelen); +- wantreply = buf_getbool(ses.payload); +- + if (namelen > MAX_NAME_LEN) { + TRACE(("name len is wrong: %d", namelen)) + goto out; diff --git a/package/network/services/dropbear/patches/017-Don-t-try-to-shutdown-a-pty.patch b/package/network/services/dropbear/patches/017-Don-t-try-to-shutdown-a-pty.patch new file mode 100644 index 0000000000..603c61d6fb --- /dev/null +++ b/package/network/services/dropbear/patches/017-Don-t-try-to-shutdown-a-pty.patch @@ -0,0 +1,32 @@ +From e28ba1b9975eab48799aa3ed77d3cd91627d7b27 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Sat, 9 Dec 2023 23:10:41 +0800 +Subject: Don't try to shutdown() a pty + +shutdown() of a pty doesn't work (ENOTSOCK), so we should close +it instead. + +This will ensure that PTY controlling terminals are closed when a +session exits, including when multiple sessions run over a single SSH +connection. In the normal case of a single session, the PTY controlling +terminal would be closed when the Dropbear server process exits anyway. + +This possibly fixes #264 on github + +It is possible that there could be subtle changes to PTY flushing +behaviour, though nothing caught by tests at present. +--- + svr-chansession.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/svr-chansession.c ++++ b/svr-chansession.c +@@ -910,7 +910,7 @@ static int ptycommand(struct Channel *ch + channel->readfd = chansess->master; + /* don't need to set stderr here */ + ses.maxfd = MAX(ses.maxfd, chansess->master); +- channel->bidir_fd = 1; ++ channel->bidir_fd = 0; + + setnonblocking(chansess->master); + diff --git a/package/network/services/dropbear/patches/018-dropbearkey-add-alias-to-ssh-keygen.patch b/package/network/services/dropbear/patches/018-dropbearkey-add-alias-to-ssh-keygen.patch new file mode 100644 index 0000000000..9c70c3141c --- /dev/null +++ b/package/network/services/dropbear/patches/018-dropbearkey-add-alias-to-ssh-keygen.patch @@ -0,0 +1,33 @@ +From 806586b585806cbe32013bcd3af3847278972060 Mon Sep 17 00:00:00 2001 +From: Sergey Ponomarev +Date: Sun, 10 Dec 2023 10:31:56 +0200 +Subject: dropbearkey: add alias to ssh-keygen + +The dropbearkey is partially compatible with ssh-keygen and can be used as an alias. + +Closes: #263 +--- + dbmulti.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/dbmulti.c ++++ b/dbmulti.c +@@ -41,7 +41,8 @@ static int runprog(const char *multipath + } + #endif + #ifdef DBMULTI_dropbearkey +- if (strcmp(progname, "dropbearkey") == 0) { ++ if (strcmp(progname, "dropbearkey") == 0 ++ || strcmp(progname, "ssh-keygen") == 0) { + return dropbearkey_main(argc, argv); + } + #endif +@@ -88,7 +89,7 @@ int main(int argc, char ** argv) { + "'dbclient' or 'ssh' - the Dropbear client\n" + #endif + #ifdef DBMULTI_dropbearkey +- "'dropbearkey' - the key generator\n" ++ "'dropbearkey' or 'ssh-keygen' - the key generator\n" + #endif + #ifdef DBMULTI_dropbearconvert + "'dropbearconvert' - the key converter\n" diff --git a/package/network/services/dropbear/patches/019-Allow-inetd-with-non-syslog.patch b/package/network/services/dropbear/patches/019-Allow-inetd-with-non-syslog.patch new file mode 100644 index 0000000000..3544f2123c --- /dev/null +++ b/package/network/services/dropbear/patches/019-Allow-inetd-with-non-syslog.patch @@ -0,0 +1,34 @@ +From 383cc8c97a9420aad9cf93d88e77ec636b183a9d Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Mon, 11 Dec 2023 23:18:09 +0800 +Subject: Allow inetd with non-syslog + +An inetd-alike should be able to distinguish stdout and stderr, so +it's a valid configuration. + +Fixes #218 on github +--- + svr-runopts.c | 12 ------------ + 1 file changed, 12 deletions(-) + +--- a/svr-runopts.c ++++ b/svr-runopts.c +@@ -443,18 +443,6 @@ void svr_getopts(int argc, char ** argv) + } + } + +-#if INETD_MODE +- if (svr_opts.inetdmode && ( +- opts.usingsyslog == 0 +-#if DEBUG_TRACE +- || debug_trace +-#endif +- )) { +- /* log output goes to stderr which would get sent over the inetd network socket */ +- dropbear_exit("Dropbear inetd mode is incompatible with debug -v or non-syslog"); +- } +-#endif +- + if (svr_opts.multiauthmethod && svr_opts.noauthpass) { + dropbear_exit("-t and -s are incompatible"); + } diff --git a/package/network/services/dropbear/patches/020-Fix-test-for-multiuser-kernels.patch b/package/network/services/dropbear/patches/020-Fix-test-for-multiuser-kernels.patch new file mode 100644 index 0000000000..8d016faa9c --- /dev/null +++ b/package/network/services/dropbear/patches/020-Fix-test-for-multiuser-kernels.patch @@ -0,0 +1,33 @@ +From 9ac650401ffc2fb05c9328d26e76a5e7ae39152a Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Mon, 11 Dec 2023 23:31:22 +0800 +Subject: Fix test for multiuser kernels + +getuid() succeeds even on non-multiuser kernels. Instead +getgroups() is a valid test. + +Fixes #214 on github +--- + common-session.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/common-session.c ++++ b/common-session.c +@@ -71,10 +71,13 @@ void common_session_init(int sock_in, in + #if !DROPBEAR_SVR_MULTIUSER + /* A sanity check to prevent an accidental configuration option + leaving multiuser systems exposed */ +- errno = 0; +- getuid(); +- if (errno != ENOSYS) { +- dropbear_exit("Non-multiuser Dropbear requires a non-multiuser kernel"); ++ { ++ int ret; ++ errno = 0; ++ ret = getgroups(0, NULL); ++ if (!(ret == -1 && errno == ENOSYS)) { ++ dropbear_exit("Non-multiuser Dropbear requires a non-multiuser kernel"); ++ } + } + #endif + diff --git a/package/network/services/dropbear/patches/021-Implement-Strict-KEX-mode.patch b/package/network/services/dropbear/patches/021-Implement-Strict-KEX-mode.patch new file mode 100644 index 0000000000..d490d9545a --- /dev/null +++ b/package/network/services/dropbear/patches/021-Implement-Strict-KEX-mode.patch @@ -0,0 +1,216 @@ +From 6e43be5c7b99dbee49dc72b6f989f29fdd7e9356 Mon Sep 17 00:00:00 2001 +From: Matt Johnston +Date: Mon, 20 Nov 2023 14:02:47 +0800 +Subject: Implement Strict KEX mode + +As specified by OpenSSH with kex-strict-c-v00@openssh.com and +kex-strict-s-v00@openssh.com. +--- + cli-session.c | 11 +++++++++++ + common-algo.c | 6 ++++++ + common-kex.c | 26 +++++++++++++++++++++++++- + kex.h | 3 +++ + process-packet.c | 34 +++++++++++++++++++--------------- + ssh.h | 4 ++++ + svr-session.c | 3 +++ + 7 files changed, 71 insertions(+), 16 deletions(-) + +--- a/cli-session.c ++++ b/cli-session.c +@@ -46,6 +46,7 @@ static void cli_finished(void) ATTRIB_NO + static void recv_msg_service_accept(void); + static void cli_session_cleanup(void); + static void recv_msg_global_request_cli(void); ++static void cli_algos_initialise(void); + + struct clientsession cli_ses; /* GLOBAL */ + +@@ -117,6 +118,7 @@ void cli_session(int sock_in, int sock_o + } + + chaninitialise(cli_chantypes); ++ cli_algos_initialise(); + + /* Set up cli_ses vars */ + cli_session_init(proxy_cmd_pid); +@@ -487,3 +489,12 @@ void cli_dropbear_log(int priority, cons + fflush(stderr); + } + ++static void cli_algos_initialise(void) { ++ algo_type *algo; ++ for (algo = sshkex; algo->name; algo++) { ++ if (strcmp(algo->name, SSH_STRICT_KEX_S) == 0) { ++ algo->usable = 0; ++ } ++ } ++} ++ +--- a/common-algo.c ++++ b/common-algo.c +@@ -308,6 +308,12 @@ algo_type sshkex[] = { + {SSH_EXT_INFO_C, 0, NULL, 1, NULL}, + #endif + #endif ++#if DROPBEAR_CLIENT ++ {SSH_STRICT_KEX_C, 0, NULL, 1, NULL}, ++#endif ++#if DROPBEAR_SERVER ++ {SSH_STRICT_KEX_S, 0, NULL, 1, NULL}, ++#endif + {NULL, 0, NULL, 0, NULL} + }; + +--- a/common-kex.c ++++ b/common-kex.c +@@ -183,6 +183,10 @@ void send_msg_newkeys() { + gen_new_keys(); + switch_keys(); + ++ if (ses.kexstate.strict_kex) { ++ ses.transseq = 0; ++ } ++ + TRACE(("leave send_msg_newkeys")) + } + +@@ -193,7 +197,11 @@ void recv_msg_newkeys() { + + ses.kexstate.recvnewkeys = 1; + switch_keys(); +- ++ ++ if (ses.kexstate.strict_kex) { ++ ses.recvseq = 0; ++ } ++ + TRACE(("leave recv_msg_newkeys")) + } + +@@ -550,6 +558,10 @@ void recv_msg_kexinit() { + + ses.kexstate.recvkexinit = 1; + ++ if (ses.kexstate.strict_kex && !ses.kexstate.donefirstkex && ses.recvseq != 1) { ++ dropbear_exit("First packet wasn't kexinit"); ++ } ++ + TRACE(("leave recv_msg_kexinit")) + } + +@@ -859,6 +871,18 @@ static void read_kex_algos() { + } + #endif + ++ if (!ses.kexstate.donefirstkex) { ++ const char* strict_name; ++ if (IS_DROPBEAR_CLIENT) { ++ strict_name = SSH_STRICT_KEX_S; ++ } else { ++ strict_name = SSH_STRICT_KEX_C; ++ } ++ if (buf_has_algo(ses.payload, strict_name) == DROPBEAR_SUCCESS) { ++ ses.kexstate.strict_kex = 1; ++ } ++ } ++ + algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess); + allgood &= goodguess; + if (algo == NULL || algo->data == NULL) { +--- a/kex.h ++++ b/kex.h +@@ -83,6 +83,9 @@ struct KEXState { + + unsigned our_first_follows_matches : 1; + ++ /* Boolean indicating that strict kex mode is in use */ ++ unsigned int strict_kex; ++ + time_t lastkextime; /* time of the last kex */ + unsigned int datatrans; /* data transmitted since last kex */ + unsigned int datarecv; /* data received since last kex */ +--- a/process-packet.c ++++ b/process-packet.c +@@ -44,6 +44,7 @@ void process_packet() { + + unsigned char type; + unsigned int i; ++ unsigned int first_strict_kex = ses.kexstate.strict_kex && !ses.kexstate.donefirstkex; + time_t now; + + TRACE2(("enter process_packet")) +@@ -54,22 +55,24 @@ void process_packet() { + now = monotonic_now(); + ses.last_packet_time_keepalive_recv = now; + +- /* These packets we can receive at any time */ +- switch(type) { + +- case SSH_MSG_IGNORE: +- goto out; +- case SSH_MSG_DEBUG: +- goto out; +- +- case SSH_MSG_UNIMPLEMENTED: +- /* debugging XXX */ +- TRACE(("SSH_MSG_UNIMPLEMENTED")) +- goto out; +- +- case SSH_MSG_DISCONNECT: +- /* TODO cleanup? */ +- dropbear_close("Disconnect received"); ++ if (type == SSH_MSG_DISCONNECT) { ++ /* Allowed at any time */ ++ dropbear_close("Disconnect received"); ++ } ++ ++ /* These packets may be received at any time, ++ except during first kex with strict kex */ ++ if (!first_strict_kex) { ++ switch(type) { ++ case SSH_MSG_IGNORE: ++ goto out; ++ case SSH_MSG_DEBUG: ++ goto out; ++ case SSH_MSG_UNIMPLEMENTED: ++ TRACE(("SSH_MSG_UNIMPLEMENTED")) ++ goto out; ++ } + } + + /* Ignore these packet types so that keepalives don't interfere with +@@ -98,7 +101,8 @@ void process_packet() { + if (type >= 1 && type <= 49 + && type != SSH_MSG_SERVICE_REQUEST + && type != SSH_MSG_SERVICE_ACCEPT +- && type != SSH_MSG_KEXINIT) ++ && type != SSH_MSG_KEXINIT ++ && !first_strict_kex) + { + TRACE(("unknown allowed packet during kexinit")) + recv_unimplemented(); +--- a/ssh.h ++++ b/ssh.h +@@ -100,6 +100,10 @@ + #define SSH_EXT_INFO_C "ext-info-c" + #define SSH_SERVER_SIG_ALGS "server-sig-algs" + ++/* OpenSSH strict KEX feature */ ++#define SSH_STRICT_KEX_S "kex-strict-s-v00@openssh.com" ++#define SSH_STRICT_KEX_C "kex-strict-c-v00@openssh.com" ++ + /* service types */ + #define SSH_SERVICE_USERAUTH "ssh-userauth" + #define SSH_SERVICE_USERAUTH_LEN 12 +--- a/svr-session.c ++++ b/svr-session.c +@@ -370,6 +370,9 @@ static void svr_algos_initialise(void) { + algo->usable = 0; + } + #endif ++ if (strcmp(algo->name, SSH_STRICT_KEX_C) == 0) { ++ algo->usable = 0; ++ } + } + } + diff --git a/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch b/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch index f078814403..442fdcfc75 100644 --- a/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch +++ b/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch @@ -21,7 +21,7 @@ Signed-off-by: Petr Štetiar --- a/signkey.c +++ b/signkey.c -@@ -646,8 +646,12 @@ int buf_verify(buffer * buf, sign_key *k +@@ -652,8 +652,12 @@ int buf_verify(buffer * buf, sign_key *k sigtype = signature_type_from_name(type_name, type_name_len); m_free(type_name); From f2b229366301282509b92ff10073e8262432a856 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 03/50] dropbear: allow more complex configuration - switch DB_OPT_COMMON and DB_OPT_CONFIG to comma-separated lists: this allows to have values with "|" in DB_OPT_COMMON and DB_OPT_CONFIG which is more likely to be than values with commas; use $(comma) variable for values with commas. - sort DB_OPT_COMMON and DB_OPT_CONFIG to have "overrides" on top of list. - allow DB_OPT_COMMON to have values with commas. - allow to replace multiline definitions in sysoptions.h. improves e1bd9645 Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 62 +++++++++++----------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index d0b0e01646..1859aab7f4 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -99,8 +99,8 @@ CONFIGURE_ARGS += \ ############################################################################## # -# option|value - add option to localoptions.h -# !!option|value - replace option in sysoptions.h +# option,value - add option to localoptions.h +# !!option,value - replace option in sysoptions.h # ############################################################################## @@ -111,63 +111,65 @@ CONFIGURE_ARGS += \ # - DROPBEAR_DSS # - DO_MOTD DB_OPT_COMMON = \ - DEFAULT_PATH|"$(TARGET_INIT_PATH)" \ - !!LOCAL_IDENT|"SSH-2.0-dropbear" \ - DROPBEAR_CLI_NETCAT|0 \ - DROPBEAR_DSS|0 \ - DO_MOTD|0 \ + !!LOCAL_IDENT,"SSH-2.0-dropbear" \ + DEFAULT_PATH,"$(TARGET_INIT_PATH)" \ + DROPBEAR_DSS,0 \ + DROPBEAR_CLI_NETCAT,0 \ + DO_MOTD,0 \ ############################################################################## # -# option|config|enabled|disabled = add option to localoptions.h -# !!option|config|enabled|disabled = replace option in sysoptions.h +# option,config,enabled,disabled = add option to localoptions.h +# !!option,config,enabled,disabled = replace option in sysoptions.h # # option := (config) ? enabled : disabled # ############################################################################## DB_OPT_CONFIG = \ - DROPBEAR_CURVE25519|CONFIG_DROPBEAR_CURVE25519|1|0 \ - DROPBEAR_ED25519|CONFIG_DROPBEAR_ED25519|1|0 \ - DROPBEAR_SK_ED25519|CONFIG_DROPBEAR_ED25519|1|0 \ - DROPBEAR_CHACHA20POLY1305|CONFIG_DROPBEAR_CHACHA20POLY1305|1|0 \ - DROPBEAR_ECDSA|CONFIG_DROPBEAR_ECC|1|0 \ - DROPBEAR_SK_ECDSA|CONFIG_DROPBEAR_ECC|1|0 \ - DROPBEAR_ECDH|CONFIG_DROPBEAR_ECC|1|0 \ - !!DROPBEAR_ECC_384|CONFIG_DROPBEAR_ECC_FULL|1|0 \ - !!DROPBEAR_ECC_521|CONFIG_DROPBEAR_ECC_FULL|1|0 \ - DROPBEAR_CLI_ASKPASS_HELPER|CONFIG_DROPBEAR_ASKPASS|1|0 \ - DROPBEAR_CLI_AGENTFWD|CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD|1|0 \ - DROPBEAR_SVR_AGENTFWD|CONFIG_DROPBEAR_AGENTFORWARD|1|0 \ + !!DROPBEAR_ECC_384,CONFIG_DROPBEAR_ECC_FULL,1,0 \ + !!DROPBEAR_ECC_521,CONFIG_DROPBEAR_ECC_FULL,1,0 \ + DROPBEAR_CURVE25519,CONFIG_DROPBEAR_CURVE25519,1,0 \ + DROPBEAR_CHACHA20POLY1305,CONFIG_DROPBEAR_CHACHA20POLY1305,1,0 \ + DROPBEAR_ED25519,CONFIG_DROPBEAR_ED25519,1,0 \ + DROPBEAR_SK_ED25519,CONFIG_DROPBEAR_ED25519,1,0 \ + DROPBEAR_ECDSA,CONFIG_DROPBEAR_ECC,1,0 \ + DROPBEAR_SK_ECDSA,CONFIG_DROPBEAR_ECC,1,0 \ + DROPBEAR_ECDH,CONFIG_DROPBEAR_ECC,1,0 \ + DROPBEAR_CLI_ASKPASS_HELPER,CONFIG_DROPBEAR_ASKPASS,1,0 \ + DROPBEAR_CLI_AGENTFWD,CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD,1,0 \ + DROPBEAR_SVR_AGENTFWD,CONFIG_DROPBEAR_AGENTFORWARD,1,0 \ TARGET_CFLAGS += -DARGTYPE=3 +xsedx:=$(shell printf '\027') + db_opt_add =echo '\#define $(1) $(2)' >> $(PKG_BUILD_DIR)/localoptions.h -db_opt_replace =$(ESED) 's,^(\#define $(1)) .*$$$$,\1 $(2),g' $(PKG_BUILD_DIR)/sysoptions.h +db_opt_replace =$(ESED) '/^\#define $(1) .*$$$$/{h;:a;$$$$!n;/^\#.+$$$$/bb;/^$$$$/bb;H;ba;:b;x;s$(xsedx)^.+$$$$$(xsedx)\#define $(1) $(2)$(xsedx)p;x};p' -n $(PKG_BUILD_DIR)/sysoptions.h define Build/Configure/dropbear_headers $(strip $(foreach s,$(DB_OPT_COMMON), \ - $(if $(filter !!%,$(word 1,$(subst |, ,$(s)))), \ - $(call db_opt_replace,$(patsubst !!%,%,$(word 1,$(subst |, ,$(s)))),$(word 2,$(subst |, ,$(s)))), \ - $(call db_opt_add,$(word 1,$(subst |, ,$(s))),$(word 2,$(subst |, ,$(s)))) \ + $(if $(filter !!%,$(word 1,$(subst $(comma),$(space),$(s)))), \ + $(call db_opt_replace,$(patsubst !!%,%,$(word 1,$(subst $(comma),$(space),$(s)))),$(subst $(space),$(comma),$(wordlist 2,$(words $(subst $(comma),$(space),$(s))),$(subst $(comma),$(space),$(s))))), \ + $(call db_opt_add,$(word 1,$(subst $(comma),$(space),$(s))),$(subst $(space),$(comma),$(wordlist 2,$(words $(subst $(comma),$(space),$(s))),$(subst $(comma),$(space),$(s))))) \ ) ; \ )) $(strip $(foreach s,$(DB_OPT_CONFIG), \ - $(if $(filter !!%,$(word 1,$(subst |, ,$(s)))), \ - $(call db_opt_replace,$(patsubst !!%,%,$(word 1,$(subst |, ,$(s)))),$(if $($(word 2,$(subst |, ,$(s)))),$(word 3,$(subst |, ,$(s))),$(word 4,$(subst |, ,$(s))))), \ - $(call db_opt_add,$(word 1,$(subst |, ,$(s))),$(if $($(word 2,$(subst |, ,$(s)))),$(word 3,$(subst |, ,$(s))),$(word 4,$(subst |, ,$(s))))) \ + $(if $(filter !!%,$(word 1,$(subst $(comma),$(space),$(s)))), \ + $(call db_opt_replace,$(patsubst !!%,%,$(word 1,$(subst $(comma),$(space),$(s)))),$(if $($(word 2,$(subst $(comma),$(space),$(s)))),$(word 3,$(subst $(comma),$(space),$(s))),$(word 4,$(subst $(comma),$(space),$(s))))), \ + $(call db_opt_add,$(word 1,$(subst $(comma),$(space),$(s))),$(if $($(word 2,$(subst $(comma),$(space),$(s)))),$(word 3,$(subst $(comma),$(space),$(s))),$(word 4,$(subst $(comma),$(space),$(s))))) \ ) ; \ )) endef define Build/Configure - : > $(PKG_BUILD_DIR)/localoptions.h - + rm -f $(PKG_BUILD_DIR)/localoptions.h $(Build/Configure/Default) + : > $(PKG_BUILD_DIR)/localoptions.h $(Build/Configure/dropbear_headers) # Enforce rebuild of svr-chansession.c From fa849fd41150d375017ebe7add34824b62f4cdd4 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 04/50] dropbear: better object cleanup improves b78aae79 Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 1859aab7f4..75dee77af0 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -165,6 +165,11 @@ define Build/Configure/dropbear_headers )) endef +define Build/Configure/dropbear_objects + grep -ERZl -e '($(subst $(space),|,$(strip $(sort $(patsubst !!%,%,$(foreach s,$(DB_OPT_COMMON) $(DB_OPT_CONFIG),$(word 1,$(subst $(comma),$(space),$(s)))))))))' \ + $(PKG_BUILD_DIR)/ | sed -zE 's/^(.+)\.[^.]+$$$$/\1.o/' | sort -uV | xargs -0 -r rm -fv || : +endef + define Build/Configure rm -f $(PKG_BUILD_DIR)/localoptions.h $(Build/Configure/Default) @@ -172,8 +177,8 @@ define Build/Configure : > $(PKG_BUILD_DIR)/localoptions.h $(Build/Configure/dropbear_headers) - # Enforce rebuild of svr-chansession.c - rm -f $(PKG_BUILD_DIR)/svr-chansession.o + # Enforce rebuild of files depending on configured options + $(Build/Configure/dropbear_objects) # Rebuild them on config change +$(MAKE) -C $(PKG_BUILD_DIR)/libtomcrypt clean From 0b277f8659806f32d08dad081836523b93eee6b8 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 05/50] dropbear: minor config clarification - "default n" is not needed: options are not selected by default - wrap config on 80 characters width (assuming tab is 8 characters long) - add feature cost size and security notes for DROPBEAR_AGENTFORWARD and DROPBEAR_DBCLIENT_AGENTFORWARD: describe why and where it should be disabled Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Config.in | 55 +++++++++++++++------ 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/package/network/services/dropbear/Config.in b/package/network/services/dropbear/Config.in index d4644fc88f..449cc2a421 100644 --- a/package/network/services/dropbear/Config.in +++ b/package/network/services/dropbear/Config.in @@ -12,7 +12,6 @@ config DROPBEAR_CURVE25519 config DROPBEAR_ECC bool "Elliptic curve cryptography (ECC)" - default n help Enables basic support for elliptic curve cryptography (ECC) in key exchange and public key authentication. @@ -25,11 +24,10 @@ config DROPBEAR_ECC Increases binary size by about 24 kB (MIPS). - If full ECC support is required, also select DROPBEAR_ECC_FULL. + Note: select DROPBEAR_ECC_FULL if full ECC support is required. config DROPBEAR_ECC_FULL bool "Elliptic curve cryptography (ECC), full support" - default n depends on DROPBEAR_ECC help Enables full support for elliptic curve cryptography (ECC) @@ -69,36 +67,50 @@ config DROPBEAR_CHACHA20POLY1305 config DROPBEAR_ZLIB bool "Enable compression" - default n help Enables compression using shared zlib library. - Increases binary size by about 0.1 kB (MIPS) and requires additional 62 kB (MIPS) - for a shared zlib library. + Increases binary size by about 0.1 kB (MIPS) and requires + additional 62 kB (MIPS) for a shared zlib library. config DROPBEAR_UTMP bool "Utmp support" - default n depends on BUSYBOX_CONFIG_FEATURE_UTMP help - This enables dropbear utmp support, the file /var/run/utmp is used to - track who is currently logged in. + This enables dropbear utmp support, the file /var/run/utmp is + used to track who is currently logged in. config DROPBEAR_PUTUTLINE bool "Pututline support" - default n depends on DROPBEAR_UTMP help - Dropbear will use pututline() to write the utmp structure into the utmp file. + Dropbear will use pututline() to write the utmp structure into + the utmp file. config DROPBEAR_DBCLIENT bool "Build dropbear with dbclient" default y config DROPBEAR_DBCLIENT_AGENTFORWARD - bool "Enable agent forwarding in dbclient" + bool "Enable agent forwarding in dbclient [LEGACY/SECURITY]" default y depends on DROPBEAR_DBCLIENT + help + Increases binary size by about 0.1 kB (MIPS). + + Security notes: + + SSH agent forwarding might cause security issues (locally and + on the jump machine). + + Hovewer, it's enabled by default for compatibility with + previous OpenWrt/dropbear releases. + + Consider DISABLING this option if you're building own OpenWrt + image. + + Also see DROPBEAR_AGENTFORWARD (agent forwarding in dropbear + server itself). config DROPBEAR_SCP bool "Build dropbear with scp" @@ -106,7 +118,6 @@ config DROPBEAR_SCP config DROPBEAR_ASKPASS bool "Enable askpass helper support" - default n depends on DROPBEAR_DBCLIENT help This enables support for ssh-askpass helper in dropbear client @@ -115,7 +126,23 @@ config DROPBEAR_ASKPASS Increases binary size by about 0.1 kB (MIPS). config DROPBEAR_AGENTFORWARD - bool "Enable agent forwarding" + bool "Enable agent forwarding [LEGACY/SECURITY]" default y + help + Increases binary size by about 0.1 kB (MIPS). + + Security notes: + + SSH agent forwarding might cause security issues (locally and + on the jump machine). + + Hovewer, it's enabled by default for compatibility with + previous OpenWrt/dropbear releases. + + Consider DISABLING this option if you're building own OpenWrt + image. + + Also see DROPBEAR_DBCLIENT_AGENTFORWARD (agent forwarding in + dropbear client) if DROPBEAR_DBCLIENT is selected. endmenu From 2d9a0be307b534ceb717267c95402d1d707cd2c3 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 06/50] dropbear: disable two weak kex/mac algorithms hmac-sha1 and diffie-hellman-group14-sha1 are weak algorithms. A future deprecation notice of ssh-rsa (2048-bit) has been issued. [1] It has no place in a potentially internet-facing daemon like dropbear. Upstream has acknowledged this and offered this solution to disable these two until this is made to be the default in the next release of dropbear next year. [2] 1. https://www.openssh.com/txt/release-8.2 2. https://github.com/mkj/dropbear/issues/138 Signed-off-by: John Audia Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 75dee77af0..51961d3c3d 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -110,12 +110,16 @@ CONFIGURE_ARGS += \ # - DROPBEAR_CLI_NETCAT # - DROPBEAR_DSS # - DO_MOTD +# - DROPBEAR_DH_GROUP14_SHA1 +# - DROPBEAR_SHA1_HMAC DB_OPT_COMMON = \ !!LOCAL_IDENT,"SSH-2.0-dropbear" \ DEFAULT_PATH,"$(TARGET_INIT_PATH)" \ DROPBEAR_DSS,0 \ DROPBEAR_CLI_NETCAT,0 \ DO_MOTD,0 \ + DROPBEAR_DH_GROUP14_SHA1,0 \ + DROPBEAR_SHA1_HMAC,0 \ ############################################################################## From 7f6fcaa3bf89ded78886e0b2238fe019cd9705cd Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 07/50] dropbear: honor CONFIG_TARGET_INIT_PATH fixes 65256aee Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 51961d3c3d..77104431db 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -115,6 +115,7 @@ CONFIGURE_ARGS += \ DB_OPT_COMMON = \ !!LOCAL_IDENT,"SSH-2.0-dropbear" \ DEFAULT_PATH,"$(TARGET_INIT_PATH)" \ + DEFAULT_ROOT_PATH,"$(TARGET_INIT_PATH)" \ DROPBEAR_DSS,0 \ DROPBEAR_CLI_NETCAT,0 \ DO_MOTD,0 \ From 88c8053d47fb5ecc53e46d8ba261df2932dd5649 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 08/50] dropbear: adjust allowed shell list this takes an effect only if getusershell(3) is missing Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 77104431db..ef67371e1d 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -104,6 +104,8 @@ CONFIGURE_ARGS += \ # ############################################################################## +# adjust allowed shell list (if getusershell(3) is missing): +# - COMPAT_USER_SHELLS # remove protocol idented software version number: # - LOCAL_IDENT # disable legacy/unsafe methods and unused functionality: @@ -114,6 +116,7 @@ CONFIGURE_ARGS += \ # - DROPBEAR_SHA1_HMAC DB_OPT_COMMON = \ !!LOCAL_IDENT,"SSH-2.0-dropbear" \ + COMPAT_USER_SHELLS,"/bin/ash","/bin/sh" \ DEFAULT_PATH,"$(TARGET_INIT_PATH)" \ DEFAULT_ROOT_PATH,"$(TARGET_INIT_PATH)" \ DROPBEAR_DSS,0 \ From bf900e02c7102601be2e9280231711e70f065877 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 09/50] dropbear: add option to enable modern crypto only reduces binary/package size and increases overall performance also: - adjust 910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch to build without DROPBEAR_RSA/DROPBEAR_RSA_SHA256 Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Config.in | 21 +++++++++++++++++++ package/network/services/dropbear/Makefile | 8 ++++++- ...nkey-fix-use-of-rsa-sha2-256-pubkeys.patch | 16 +++++++++----- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/package/network/services/dropbear/Config.in b/package/network/services/dropbear/Config.in index 449cc2a421..fd4d5f3c7a 100644 --- a/package/network/services/dropbear/Config.in +++ b/package/network/services/dropbear/Config.in @@ -145,4 +145,25 @@ config DROPBEAR_AGENTFORWARD Also see DROPBEAR_DBCLIENT_AGENTFORWARD (agent forwarding in dropbear client) if DROPBEAR_DBCLIENT is selected. +config DROPBEAR_MODERN_ONLY + bool "Use modern crypto only [BREAKS COMPATIBILITY]" + select DROPBEAR_ED25519 + select DROPBEAR_CURVE25519 + select DROPBEAR_CHACHA20POLY1305 + help + This option enables: + - Chacha20-Poly1305 + - Curve25519 + - Ed25519 + and disables: + - AES + - RSA + - SHA1 + + Reduces binary size by about 64 kB (MIPS) from default + configuration. + + Consider enabling this option if you're building own OpenWrt + image and using modern SSH software everywhere. + endmenu diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index ef67371e1d..653911b764 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -33,7 +33,8 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_DROPBEAR_ED25519 CONFIG_DROPBEAR_CHACHA20POLY1305 \ CONFIG_DROPBEAR_UTMP CONFIG_DROPBEAR_PUTUTLINE \ CONFIG_DROPBEAR_DBCLIENT CONFIG_DROPBEAR_SCP CONFIG_DROPBEAR_ASKPASS \ - CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD CONFIG_DROPBEAR_AGENTFORWARD + CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD CONFIG_DROPBEAR_AGENTFORWARD \ + CONFIG_DROPBEAR_MODERN_ONLY include $(INCLUDE_DIR)/package.mk @@ -148,6 +149,11 @@ DB_OPT_CONFIG = \ DROPBEAR_CLI_ASKPASS_HELPER,CONFIG_DROPBEAR_ASKPASS,1,0 \ DROPBEAR_CLI_AGENTFWD,CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD,1,0 \ DROPBEAR_SVR_AGENTFWD,CONFIG_DROPBEAR_AGENTFORWARD,1,0 \ + DROPBEAR_AES128,CONFIG_DROPBEAR_MODERN_ONLY,0,1 \ + DROPBEAR_AES256,CONFIG_DROPBEAR_MODERN_ONLY,0,1 \ + DROPBEAR_ENABLE_CTR_MODE,CONFIG_DROPBEAR_MODERN_ONLY,0,1 \ + DROPBEAR_RSA,CONFIG_DROPBEAR_MODERN_ONLY,0,1 \ + DROPBEAR_RSA_SHA1,CONFIG_DROPBEAR_MODERN_ONLY,0,1 \ TARGET_CFLAGS += -DARGTYPE=3 diff --git a/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch b/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch index 442fdcfc75..059177a1c5 100644 --- a/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch +++ b/package/network/services/dropbear/patches/910-signkey-fix-use-of-rsa-sha2-256-pubkeys.patch @@ -21,7 +21,7 @@ Signed-off-by: Petr Štetiar --- a/signkey.c +++ b/signkey.c -@@ -652,8 +652,12 @@ int buf_verify(buffer * buf, sign_key *k +@@ -652,10 +652,18 @@ int buf_verify(buffer * buf, sign_key *k sigtype = signature_type_from_name(type_name, type_name_len); m_free(type_name); @@ -29,10 +29,16 @@ Signed-off-by: Petr Štetiar - dropbear_exit("Non-matching signing type"); + if (sigtype == DROPBEAR_SIGNATURE_NONE) { + dropbear_exit("No signature type"); -+ } -+ -+ if ((expect_sigtype != DROPBEAR_SIGNATURE_RSA_SHA256) && (expect_sigtype != sigtype)) { -+ dropbear_exit("Non-matching signing type"); } ++#if DROPBEAR_RSA ++#if DROPBEAR_RSA_SHA256 ++ if ((expect_sigtype != DROPBEAR_SIGNATURE_RSA_SHA256) && (expect_sigtype != sigtype)) { ++ dropbear_exit("Non-matching signing type"); ++ } ++#endif ++#endif ++ keytype = signkey_type_from_signature(sigtype); + #if DROPBEAR_DSS + if (keytype == DROPBEAR_SIGNKEY_DSS) { From c87a192386e8470f68e8340a23f9293976211114 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:01 +0300 Subject: [PATCH 10/50] dropbear: split U2F/FIDO support these options allow one to configure U2F/FIDO support in more granular way inspired by upstream commit aa6559db Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Config.in | 28 +++++++++++++++++++++ package/network/services/dropbear/Makefile | 6 +++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/package/network/services/dropbear/Config.in b/package/network/services/dropbear/Config.in index fd4d5f3c7a..a59ca911a0 100644 --- a/package/network/services/dropbear/Config.in +++ b/package/network/services/dropbear/Config.in @@ -65,6 +65,34 @@ config DROPBEAR_CHACHA20POLY1305 Increases binary size by about 4 kB (MIPS). +config DROPBEAR_U2F + bool "U2F/FIDO support" + default y + help + This option itself doesn't enable any support for U2F/FIDO + but subordinate options do: + + - DROPBEAR_ECDSA_SK - ecdsa-sk keys support + depends on DROPBEAR_ECC ("Elliptic curve cryptography (ECC)") + - DROPBEAR_ED25519_SK - ed25519-sk keys support + depends on DROPBEAR_ED25519 ("Ed25519 support") + +config DROPBEAR_ECDSA_SK + bool "ECDSA-SK support" + default y + depends on DROPBEAR_U2F && DROPBEAR_ECC + help + This enables the following public key algorithm: + sk-ecdsa-sha2-nistp256@openssh.com + +config DROPBEAR_ED25519_SK + bool "Ed25519-SK support" + default y + depends on DROPBEAR_U2F && DROPBEAR_ED25519 + help + This enables the following public key algorithm: + sk-ssh-ed25519@openssh.com + config DROPBEAR_ZLIB bool "Enable compression" help diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index 653911b764..c00f64006e 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -31,6 +31,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_TARGET_INIT_PATH CONFIG_DROPBEAR_ECC CONFIG_DROPBEAR_ECC_FULL \ CONFIG_DROPBEAR_CURVE25519 CONFIG_DROPBEAR_ZLIB \ CONFIG_DROPBEAR_ED25519 CONFIG_DROPBEAR_CHACHA20POLY1305 \ + CONFIG_DROPBEAR_U2F CONFIG_DROPBEAR_ECDSA_SK CONFIG_DROPBEAR_ED25519_SK \ CONFIG_DROPBEAR_UTMP CONFIG_DROPBEAR_PUTUTLINE \ CONFIG_DROPBEAR_DBCLIENT CONFIG_DROPBEAR_SCP CONFIG_DROPBEAR_ASKPASS \ CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD CONFIG_DROPBEAR_AGENTFORWARD \ @@ -142,10 +143,11 @@ DB_OPT_CONFIG = \ DROPBEAR_CURVE25519,CONFIG_DROPBEAR_CURVE25519,1,0 \ DROPBEAR_CHACHA20POLY1305,CONFIG_DROPBEAR_CHACHA20POLY1305,1,0 \ DROPBEAR_ED25519,CONFIG_DROPBEAR_ED25519,1,0 \ - DROPBEAR_SK_ED25519,CONFIG_DROPBEAR_ED25519,1,0 \ DROPBEAR_ECDSA,CONFIG_DROPBEAR_ECC,1,0 \ - DROPBEAR_SK_ECDSA,CONFIG_DROPBEAR_ECC,1,0 \ DROPBEAR_ECDH,CONFIG_DROPBEAR_ECC,1,0 \ + DROPBEAR_SK_KEYS,CONFIG_DROPBEAR_U2F,1,0 \ + DROPBEAR_SK_ECDSA,CONFIG_DROPBEAR_ECDSA_SK,1,0 \ + DROPBEAR_SK_ED25519,CONFIG_DROPBEAR_ED25519_SK,1,0 \ DROPBEAR_CLI_ASKPASS_HELPER,CONFIG_DROPBEAR_ASKPASS,1,0 \ DROPBEAR_CLI_AGENTFWD,CONFIG_DROPBEAR_DBCLIENT_AGENTFORWARD,1,0 \ DROPBEAR_SVR_AGENTFWD,CONFIG_DROPBEAR_AGENTFORWARD,1,0 \ From 55218bcedb3ffb830391d9a4e72b7ae8481ba760 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:02 +0300 Subject: [PATCH 11/50] dropbear: minor config reorder move DROPBEAR_ASKPASS under DROPBEAR_DBCLIENT (in all meanings) Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Config.in | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package/network/services/dropbear/Config.in b/package/network/services/dropbear/Config.in index a59ca911a0..7ffe7684d4 100644 --- a/package/network/services/dropbear/Config.in +++ b/package/network/services/dropbear/Config.in @@ -119,6 +119,15 @@ config DROPBEAR_DBCLIENT bool "Build dropbear with dbclient" default y +config DROPBEAR_ASKPASS + bool "Enable askpass helper support" + depends on DROPBEAR_DBCLIENT + help + This enables support for ssh-askpass helper in dropbear client + in order to authenticate on remote hosts. + + Increases binary size by about 0.1 kB (MIPS). + config DROPBEAR_DBCLIENT_AGENTFORWARD bool "Enable agent forwarding in dbclient [LEGACY/SECURITY]" default y @@ -144,15 +153,6 @@ config DROPBEAR_SCP bool "Build dropbear with scp" default y -config DROPBEAR_ASKPASS - bool "Enable askpass helper support" - depends on DROPBEAR_DBCLIENT - help - This enables support for ssh-askpass helper in dropbear client - in order to authenticate on remote hosts. - - Increases binary size by about 0.1 kB (MIPS). - config DROPBEAR_AGENTFORWARD bool "Enable agent forwarding [LEGACY/SECURITY]" default y From ff1ccd85e88d54724ea9c034ec355e7805356fb2 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:02 +0300 Subject: [PATCH 12/50] dropbear: failsafe: handle all supported key types dropbear may be configured and compiled with support for different host key types Signed-off-by: Konstantin Demin --- .../services/dropbear/files/dropbear.failsafe | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/package/network/services/dropbear/files/dropbear.failsafe b/package/network/services/dropbear/files/dropbear.failsafe index 97bd12d58a..417265babe 100755 --- a/package/network/services/dropbear/files/dropbear.failsafe +++ b/package/network/services/dropbear/files/dropbear.failsafe @@ -1,9 +1,61 @@ #!/bin/sh +_dropbear() +{ + /usr/sbin/dropbear "$@" /dev/null 2>&1 +} + +_dropbearkey() +{ + /usr/bin/dropbearkey "$@" /dev/null 2>&1 +} + +_ensurekey() +{ + _dropbearkey -y -f "$1" && return + rm -f "$1" + _dropbearkey -f "$@" || { + rm -f "$1" + return 1 + } +} + +ktype_all='ed25519 ecdsa rsa' + failsafe_dropbear () { - dropbearkey -t rsa -s 1024 -f /tmp/dropbear_rsa_failsafe_host_key - dropbearkey -t ed25519 -f /tmp/dropbear_ed25519_failsafe_host_key - dropbear -r /tmp/dropbear_rsa_failsafe_host_key -r /tmp/dropbear_ed25519_failsafe_host_key <> /dev/null 2>&1 + local kargs kcount ktype tkey + + kargs= + kcount=0 + for ktype in ${ktype_all} ; do + tkey="/tmp/dropbear_failsafe_${ktype}_host_key" + + case "${ktype}" in + ed25519) _ensurekey "${tkey}" -t ed25519 ;; + ecdsa) _ensurekey "${tkey}" -t ecdsa -s 256 ;; + rsa) _ensurekey "${tkey}" -t rsa -s 1024 ;; + *) + echo "unknown key type: ${ktype}" >&2 + continue + ;; + esac + + [ -s "${tkey}" ] || { + rm -f "${tkey}" + continue + } + + chmod 0400 "${tkey}" + kargs="${kargs}${kargs:+ }-r ${tkey}" + kcount=$((kcount+1)) + done + + [ "${kcount}" != 0 ] || { + echo 'DROPBEAR IS BROKEN' >&2 + return 1 + } + + _dropbear ${kargs} } boot_hook_add failsafe failsafe_dropbear From a97e0dad6ef90d9cfee288a9f2035b33353c7ca0 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:02 +0300 Subject: [PATCH 13/50] dropbear: 'rsakeyfile' -> 'keyfile' transition end users should have done this since OpenWrt 19.07. if they didn't do this yet - perform auto-transition. schedule 'rsakeyfile' removal for next year release. Signed-off-by: Konstantin Demin --- package/network/services/dropbear/files/dropbear.init | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index a40b5f7bae..18273e63d0 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -168,13 +168,16 @@ dropbear_instance() [ -n "${ForceCommand}" ] && procd_append_param command -c "${ForceCommand}" [ "${RootPasswordAuth}" -eq 0 ] && procd_append_param command -g [ "${RootLogin}" -eq 0 ] && procd_append_param command -w + config_list_foreach "$1" 'keyfile' hk_config__keyfile if [ -n "${rsakeyfile}" ]; then - logger -t ${NAME} -p daemon.warn \ - "option 'rsakeyfile' is considered to be deprecated and" \ - "will be removed in future releases, use 'keyfile' instead" + logger -s -t "${NAME}" -p daemon.crit \ + "Option 'rsakeyfile' is considered to be DEPRECATED and will be REMOVED in future releases, use 'keyfile' list instead" + sed -i.before-upgrade -E -e 's/option(\s+)rsakeyfile/list keyfile/' \ + "/etc/config/${NAME}" + logger -s -t "${NAME}" -p daemon.crit \ + "Auto-transition 'option rsakeyfile' => 'list keyfile' in /etc/config/${NAME} is done, please verify your configuration" hk_config 'rsakeyfile' "${rsakeyfile}" fi - config_list_foreach "$1" "keyfile" hk_config__keyfile [ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}" append_ports "${ipaddrs}" "${Port}" [ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}" From 05100d865158a5d6eaf8b34a8deb0d447cc73301 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:02 +0300 Subject: [PATCH 14/50] dropbear: adjust file permissions runtime: - adjust ownership/permissions while starting dropbear build time: - correct file permissions for preseed files in $(TOPDIR)/files/etc/dropbear/ (if any) closes #10849 Signed-off-by: Konstantin Demin --- package/network/services/dropbear/Makefile | 11 +- .../services/dropbear/files/dropbear.init | 130 ++++++++++++------ 2 files changed, 95 insertions(+), 46 deletions(-) diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index c00f64006e..2d7ce75b8d 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -70,10 +70,11 @@ define Package/dropbear/description endef define Package/dropbear/conffiles -$(if $(CONFIG_DROPBEAR_ED25519),/etc/dropbear/dropbear_ed25519_host_key) -$(if $(CONFIG_DROPBEAR_ECC),/etc/dropbear/dropbear_ecdsa_host_key) -/etc/dropbear/dropbear_rsa_host_key /etc/config/dropbear +/etc/dropbear/authorized_keys +/etc/dropbear/dropbear_ecdsa_host_key +/etc/dropbear/dropbear_ed25519_host_key +/etc/dropbear/dropbear_rsa_host_key endef define Package/dropbearconvert @@ -227,9 +228,7 @@ define Package/dropbear/install $(INSTALL_DIR) $(1)/etc/dropbear $(INSTALL_DIR) $(1)/lib/preinit $(INSTALL_DATA) ./files/dropbear.failsafe $(1)/lib/preinit/99_10_failsafe_dropbear - $(if $(CONFIG_DROPBEAR_ED25519),touch $(1)/etc/dropbear/dropbear_ed25519_host_key) - $(if $(CONFIG_DROPBEAR_ECC),touch $(1)/etc/dropbear/dropbear_ecdsa_host_key) - touch $(1)/etc/dropbear/dropbear_rsa_host_key + $(foreach f,$(filter /etc/dropbear/%,$(Package/dropbear/conffiles)),$(if $(wildcard $(TOPDIR)/files/$(f)),chmod 0600 $(TOPDIR)/files/$(f) || :; )) endef define Package/dropbearconvert/install diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 18273e63d0..6a0fc67351 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -12,28 +12,52 @@ PIDCOUNT=0 extra_command "killclients" "Kill ${NAME} processes except servers and yourself" +# most of time real_stat() will be failing +# due to missing "stat" binary (by default) +real_stat() { env stat -L "$@" 2>/dev/null ; } +dumb_stat() { ls -Ldln "$1" | tr -s '\t ' ' ' ; } +stat_perm() { real_stat -c '%A' "$1" || dumb_stat "$1" | cut -d ' ' -f 1 ; } +stat_owner() { real_stat -c '%u' "$1" || dumb_stat "$1" | cut -d ' ' -f 3 ; } + _dropbearkey() { - /usr/bin/dropbearkey "$@" 0<&- 1>&- 2>&- + /usr/bin/dropbearkey "$@" /dev/null 2>&1 } -# $1 - host key file name -hk_verify() +# $1 - file name (host key or config) +file_verify() { [ -f "$1" ] || return 1 - [ -s "$1" ] || return 2 - _dropbearkey -y -f "$1" || return 3 + # checking file ownership + [ "$(stat_owner "$1")" = "0" ] || { + chown 0 "$1" + [ "$(stat_owner "$1")" = "0" ] || return 2 + } + # checking file permissions + [ "$(stat_perm "$1")" = "-rw-------" ] || { + chmod 0600 "$1" + [ "$(stat_perm "$1")" = "-rw-------" ] || return 3 + } + # file is host key or not? + # if $2 is empty string - file is "host key" + # if $2 is non-empty string - file is "config" + [ -z "$2" ] || return 0 + # checking file contents (finally) + [ -s "$1" ] || return 4 + _dropbearkey -y -f "$1" || return 5 return 0 } -# $1 - hk_verify() return code -hk_errmsg() +# $1 - file_verify() return code +file_errmsg() { case "$1" in 0) ;; 1) echo "file does not exist" ;; - 2) echo "file has zero length" ;; - 3) echo "file is not valid host key or not supported" ;; + 2) echo "file has wrong owner (must be owned by root)" ;; + 3) echo "file has wrong permissions (must not have group/other write bit)" ;; + 4) echo "file has zero length" ;; + 5) echo "file is not valid host key or not supported" ;; *) echo "unknown error" ;; esac } @@ -43,58 +67,83 @@ hk_errmsg() hk_config() { local x m - hk_verify "$2"; x=$? - case "$x" in - 0) procd_append_param command -r "$2" - ;; - *) m=$(hk_errmsg "$x") - logger -t "${NAME}" -p daemon.warn \ - "option '$1', value '$2': $m, skipping" - ;; - esac + file_verify "$2" ; x=$? + if [ "$x" = 0 ] ; then + procd_append_param command -r "$2" + return + fi + m=$(file_errmsg "$x") + logger -s -t "${NAME}" -p daemon.warn \ + "Option '$1', skipping '$2': $m" } # $1 - host key file name -hk_config__keyfile() -{ - hk_config 'keyfile' "$1" -} +hk_config__keyfile() { hk_config keyfile "$1" ; } + +ktype_all='ed25519 ecdsa rsa' hk_generate_as_needed() { - local kdir kgen ktype tdir kcount tfile - kdir='/etc/dropbear' + local hk_cfg_dir kgen ktype kfile hk_tmp_dir + hk_cfg_dir='/etc/dropbear' - kgen='' - for ktype in ed25519 ecdsa rsa; do - hk_verify "${kdir}/dropbear_${ktype}_host_key" && continue + [ -d "${hk_cfg_dir}" ] || mkdir -p "${hk_cfg_dir}" - kgen="${kgen} ${ktype}" + kgen= + for ktype in ${ktype_all} ; do + kfile="${hk_cfg_dir}/dropbear_${ktype}_host_key" + + if file_verify "${kfile}" ; then continue ; fi + + kgen="${kgen}${kgen:+ }${ktype}" done - [ -z "${kgen}" ] && return + # all keys are sane? + [ -n "${kgen}" ] || return 0 - tdir=$(mktemp -d); chmod 0700 "${tdir}" + hk_tmp_dir=$(mktemp -d) + # system in bad state? + [ -n "${hk_tmp_dir}" ] || return 1 - kcount=0 - for ktype in ${kgen}; do - tfile="${tdir}/dropbear_${ktype}_host_key" + chmod 0700 "${hk_tmp_dir}" - if ! _dropbearkey -t ${ktype} -f "${tfile}"; then + for ktype in ${kgen} ; do + kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key" + + if ! _dropbearkey -t ${ktype} -f "${kfile}" ; then # unsupported key type - rm -f "${tfile}" + rm -f "${kfile}" continue fi - kcount=$((kcount+1)) + chmod 0600 "${kfile}" done - if [ ${kcount} -ne 0 ]; then - mkdir -p "${kdir}"; chmod 0700 "${kdir}"; chown root "${kdir}" - mv -f "${tdir}/"* "${kdir}/" + kgen= + for ktype in ${ktype_all} ; do + kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key" + + [ -s "${kfile}" ] || continue + + kgen="${kgen}${kgen:+ }${ktype}" + done + + if [ -n "${kgen}" ] ; then + for ktype in ${kgen} ; do + kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key" + [ -s "${kfile}" ] || continue + mv -f "${kfile}" "${hk_cfg_dir}/" + done fi - rm -rf "${tdir}" + rm -rf "${hk_tmp_dir}" + + # cleanup empty files + for ktype in ${ktype_all} ; do + kfile="${hk_cfg_dir}/dropbear_${ktype}_host_key" + + [ -s "${kfile}" ] || rm -f "${kfile}" + done } append_ports() @@ -207,6 +256,7 @@ boot() start_service() { hk_generate_as_needed + file_verify /etc/dropbear/authorized_keys config . /lib/functions.sh . /lib/functions/network.sh From 865ae1c10c65001813413da95eb1b8cd06a7e1c1 Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Tue, 9 Jan 2024 03:40:02 +0300 Subject: [PATCH 15/50] dropbear: better handle receive window size - correct maximum receive window size - adjust receive window size against maximum allowed value - warn about too high receive window size in syslog improves f95eecfb Signed-off-by: Konstantin Demin --- .../services/dropbear/files/dropbear.init | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 6a0fc67351..34d3b8a31d 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -178,7 +178,7 @@ validate_section_dropbear() 'SSHKeepAlive:uinteger:300' \ 'IdleTimeout:uinteger:0' \ 'MaxAuthTries:uinteger:3' \ - 'RecvWindowSize:uinteger:0' \ + 'RecvWindowSize:uinteger:262144' \ 'mdns:bool:1' } @@ -204,12 +204,6 @@ dropbear_instance() PIDCOUNT="$(( ${PIDCOUNT} + 1))" local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid" - # Increase default receive window size to increase - # throughput on high latency links - if [ "${RecvWindowSize}" -eq "0" ]; then - RecvWindowSize="262144" - fi - procd_open_instance procd_set_param command "$PROG" -F -P "$pid_file" [ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s @@ -232,8 +226,23 @@ dropbear_instance() [ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}" [ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}" [ "${MaxAuthTries}" -ne 0 ] && procd_append_param command -T "${MaxAuthTries}" - [ "${RecvWindowSize}" -gt 0 -a "${RecvWindowSize}" -le 1048576 ] && \ + [ "${RecvWindowSize}" -gt 0 ] && { + # NB: OpenWrt increases receive window size to increase throughput on high latency links + # ref: validate_section_dropbear() + # default receive window size is 24576 (DEFAULT_RECV_WINDOW in default_options.h) + + # sysoptions.h + local MAX_RECV_WINDOW=10485760 + if [ "${RecvWindowSize}" -gt ${MAX_RECV_WINDOW} ] ; then + # separate logging is required because syslog misses dropbear's message + # Bad recv window '${RecvWindowSize}', using ${MAX_RECV_WINDOW} + # it's probably dropbear issue but we should handle this and notify user + logger -s -t "${NAME}" -p daemon.warn \ + "Option 'RecvWindowSize' is too high (${RecvWindowSize}), limiting to ${MAX_RECV_WINDOW}" + RecvWindowSize=${MAX_RECV_WINDOW} + fi procd_append_param command -W "${RecvWindowSize}" + } [ "${mdns}" -ne 0 ] && procd_add_mdns "ssh" "tcp" "$Port" "daemon=dropbear" procd_set_param respawn procd_close_instance From 3f96246e97215c4c76ca407a8bca8f3f5de32e1c Mon Sep 17 00:00:00 2001 From: Konstantin Demin Date: Mon, 15 Jan 2024 10:38:59 +0300 Subject: [PATCH 16/50] dropbear: better handle interfaces - introduce 'DirectInterface' option to bind exactly to specified interface; fixes #9666 and late IPv4/IPv6 address assignment - option 'DirectInterface' takes precedence over 'Interface' - improve interface/address handling, e.g. verify count of listening endpoints due to dropbear limit (10 for now) Signed-off-by: Konstantin Demin --- .../services/dropbear/files/dropbear.init | 176 +++++++++++++++--- 1 file changed, 149 insertions(+), 27 deletions(-) diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 34d3b8a31d..21570987c4 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -146,19 +146,18 @@ hk_generate_as_needed() done } -append_ports() +# $1 - list with whitespace-separated elements +normalize_list() { - local ipaddrs="$1" - local port="$2" + printf '%s' "$1" | tr -s ' \r\n\t' ' ' | sed -E 's/^ //;s/ $//' +} - [ -z "$ipaddrs" ] && { - procd_append_param command -p "$port" - return - } - - for addr in $ipaddrs; do - procd_append_param command -p "$addr:$port" - done +warn_multiple_interfaces() +{ + logger -t "${NAME}" -p daemon.warn \ + "Option '$1' should specify SINGLE interface but instead it lists interfaces: $2" + logger -t "${NAME}" -p daemon.warn \ + "Consider creating per-interface instances instead!" } validate_section_dropbear() @@ -166,6 +165,7 @@ validate_section_dropbear() uci_load_validate dropbear dropbear "$1" "$2" \ 'PasswordAuth:bool:1' \ 'enable:bool:1' \ + 'DirectInterface:string' \ 'Interface:string' \ 'GatewayPorts:bool:0' \ 'ForceCommand:string' \ @@ -184,28 +184,139 @@ validate_section_dropbear() dropbear_instance() { - local ipaddrs - [ "$2" = 0 ] || { echo "validation failed" return 1 } - [ -n "${Interface}" ] && { - [ -n "${BOOT}" ] && return 0 + [ "${enable}" = "1" ] || return 1 - network_get_ipaddrs_all ipaddrs "${Interface}" || { - echo "interface ${Interface} has no physdev or physdev has no suitable ip" - return 1 - } - } + local iface ndev ipaddrs + + # 'DirectInterface' should specify single interface + # but end users may misinterpret this setting + DirectInterface=$(normalize_list "${DirectInterface}") + + # 'Interface' should specify single interface + # but end users are often misinterpret this setting + Interface=$(normalize_list "${Interface}") + + if [ -n "${Interface}" ] ; then + if [ -n "${DirectInterface}" ] ; then + logger -t "${NAME}" -p daemon.warn \ + "Option 'DirectInterface' takes precedence over 'Interface'" + else + logger -t "${NAME}" -p daemon.info \ + "Option 'Interface' binds to address(es) but not to interface" + logger -t "${NAME}" -p daemon.info \ + "Consider using option 'DirectInterface' to bind directly to interface" + fi + fi + + # handle 'DirectInterface' + iface=$(echo "${DirectInterface}" | awk '{print $1}') + case "${DirectInterface}" in + *\ *) + warn_multiple_interfaces DirectInterface "${DirectInterface}" + logger -t "${NAME}" -p daemon.warn \ + "Using network interface '${iface}' for direct binding" + ;; + esac + while [ -n "${iface}" ] ; do + # if network is available (even during boot) - proceed + if network_is_up "${iface}" ; then break ; fi + # skip during boot + [ -z "${BOOT}" ] || return 0 + + logger -t "${NAME}" -p daemon.crit \ + "Network interface '${iface}' is not available!" + return 1 + done + while [ -n "${iface}" ] ; do + # ${iface} is logical (higher level) interface name + # ${ndev} is 'real' interface name + # e.g.: if ${iface} is 'lan' (default LAN interface) then ${ndev} is 'br-lan' + network_get_device ndev "${iface}" + [ -z "${ndev}" ] || break + + logger -t "${NAME}" -p daemon.crit \ + "Missing network device for network interface '${iface}'!" + return 1 + done + if [ -n "${iface}" ] ; then + logger -t "${NAME}" -p daemon.info \ + "Using network interface '${iface}' (network device '${ndev}') for direct binding" + fi + # handle 'Interface' + while [ -z "${iface}" ] ; do + [ -n "${Interface}" ] || break + + # skip during boot + [ -z "${BOOT}" ] || return 0 + + case "${Interface}" in + *\ *) + warn_multiple_interfaces Interface "${Interface}" + ;; + esac + + local c=0 + # sysoptions.h + local DROPBEAR_MAX_PORTS=10 + + local a n if_ipaddrs + for n in ${Interface} ; do + [ -n "$n" ] || continue + + if_ipaddrs= + network_get_ipaddrs_all if_ipaddrs "$n" + [ -n "${if_ipaddrs}" ] || { + logger -s -t "${NAME}" -p daemon.err \ + "Network interface '$n' has no suitable IP address(es)!" + continue + } + + [ $c -le ${DROPBEAR_MAX_PORTS} ] || { + logger -s -t "${NAME}" -p daemon.err \ + "Network interface '$n' is NOT listened due to option limit exceed!" + continue + } + + for a in ${if_ipaddrs} ; do + [ -n "$a" ] || continue + + c=$((c+1)) + if [ $c -le ${DROPBEAR_MAX_PORTS} ] ; then + ipaddrs="${ipaddrs} $a" + continue + fi + + logger -t "${NAME}" -p daemon.err \ + "Endpoint '$a:${Port}' on network interface '$n' is NOT listened due to option limit exceed!" + done + done + break + done - [ "${enable}" = "0" ] && return 1 PIDCOUNT="$(( ${PIDCOUNT} + 1))" local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid" procd_open_instance procd_set_param command "$PROG" -F -P "$pid_file" + if [ -n "${iface}" ] ; then + # if ${iface} is non-empty then ${ndev} is non-empty too + procd_append_param command -l "${ndev}" -p "${Port}" + else + if [ -z "${ipaddrs}" ] ; then + procd_append_param command -p "${Port}" + else + local a + for a in ${ipaddrs} ; do + [ -n "$a" ] || continue + procd_append_param command -p "$a:${Port}" + done + fi + fi [ "${PasswordAuth}" -eq 0 ] && procd_append_param command -s [ "${GatewayPorts}" -eq 1 ] && procd_append_param command -a [ -n "${ForceCommand}" ] && procd_append_param command -c "${ForceCommand}" @@ -222,7 +333,6 @@ dropbear_instance() hk_config 'rsakeyfile' "${rsakeyfile}" fi [ -n "${BannerFile}" ] && procd_append_param command -b "${BannerFile}" - append_ports "${ipaddrs}" "${Port}" [ "${IdleTimeout}" -ne 0 ] && procd_append_param command -I "${IdleTimeout}" [ "${SSHKeepAlive}" -ne 0 ] && procd_append_param command -K "${SSHKeepAlive}" [ "${MaxAuthTries}" -ne 0 ] && procd_append_param command -T "${MaxAuthTries}" @@ -250,10 +360,21 @@ dropbear_instance() load_interfaces() { - config_get interface "$1" Interface + local enable config_get enable "$1" enable 1 + [ "${enable}" = "1" ] || return 0 - [ "${enable}" = "1" ] && interfaces=" ${interface} ${interfaces}" + local direct_iface iface + config_get direct_iface "$1" DirectInterface + direct_iface=$(normalize_list "${direct_iface}") + # 'DirectInterface' takes precedence over 'Interface' + if [ -n "${direct_iface}" ] ; then + iface=$(echo "${direct_iface}" | awk '{print $1}') + else + config_get iface "$1" Interface + iface=$(normalize_list "${iface}") + fi + interfaces="${interfaces} ${iface}" } boot() @@ -278,13 +399,14 @@ service_triggers() { local interfaces - procd_add_config_trigger "config.change" "dropbear" /etc/init.d/dropbear reload + procd_add_config_trigger "config.change" "${NAME}" /etc/init.d/dropbear reload config_load "${NAME}" - config_foreach load_interfaces dropbear + config_foreach load_interfaces "${NAME}" [ -n "${interfaces}" ] && { - for n in $interfaces ; do + local n + for n in $(printf '%s\n' ${interfaces} | sort -u) ; do procd_add_interface_trigger "interface.*" $n /etc/init.d/dropbear reload done } From 2b4941a6f16fa1c045cb2f4a8fc09adc64fecd63 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 9 Feb 2024 12:18:57 +0100 Subject: [PATCH 17/50] wifi-scripts: fix fullmac phy detection Checking for AP_VLAN misdetects ath10k-ath12k as fullmac, because of software crypto limitations. Check for monitor mode support instead, which is more reliable. Fixes: https://github.com/openwrt/openwrt/issues/14575 Signed-off-by: Felix Fietkau --- .../config/wifi-scripts/files/usr/share/hostap/common.uc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc b/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc index 4c33779af9..750e3ae71c 100644 --- a/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc +++ b/package/network/config/wifi-scripts/files/usr/share/hostap/common.uc @@ -49,7 +49,7 @@ function __phy_is_fullmac(phyidx) { let data = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, 0, { wiphy: phyidx }); - return !data.software_iftypes.ap_vlan; + return !data.software_iftypes.monitor; } function phy_is_fullmac(phy) From 5a016cc3af3ee96a0df6bc45debb8394e6e7067d Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Mon, 29 Jan 2024 19:38:20 +0100 Subject: [PATCH 18/50] uboot-envtools: update to 2024.01 Update to latest version. Refresh patches: - 002-Revert-tools-env-use-run-to-store-lockfile.patch Signed-off-by: Nick Hainke --- package/boot/uboot-envtools/Makefile | 6 +++--- .../002-Revert-tools-env-use-run-to-store-lockfile.patch | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile index 9647b38385..4ea93f9c79 100644 --- a/package/boot/uboot-envtools/Makefile +++ b/package/boot/uboot-envtools/Makefile @@ -9,15 +9,15 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot -PKG_VERSION:=2023.07.02 -PKG_RELEASE:=3 +PKG_VERSION:=2024.01 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ https://ftp.denx.de/pub/u-boot \ https://mirror.cyberbits.eu/u-boot \ ftp://ftp.denx.de/pub/u-boot -PKG_HASH:=6b6a48581c14abb0f95bd87c1af4d740922406d7b801002a9f94727fdde021d5 +PKG_HASH:=b99611f1ed237bf3541bdc8434b68c96a6e05967061f992443cb30aabebef5b3 PKG_SOURCE_SUBDIR:=$(PKG_DISTNAME)-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_DISTNAME)-$(PKG_VERSION) diff --git a/package/boot/uboot-envtools/patches/002-Revert-tools-env-use-run-to-store-lockfile.patch b/package/boot/uboot-envtools/patches/002-Revert-tools-env-use-run-to-store-lockfile.patch index ace7cdc681..e843e4252b 100644 --- a/package/boot/uboot-envtools/patches/002-Revert-tools-env-use-run-to-store-lockfile.patch +++ b/package/boot/uboot-envtools/patches/002-Revert-tools-env-use-run-to-store-lockfile.patch @@ -10,8 +10,6 @@ This reverts upstream commit tools/env/fw_env_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c -index 0b201b9e62..1d193bd437 100644 --- a/tools/env/fw_env_main.c +++ b/tools/env/fw_env_main.c @@ -73,7 +73,7 @@ void usage_printenv(void) @@ -32,7 +30,7 @@ index 0b201b9e62..1d193bd437 100644 " -s, --script batch mode to minimize writes\n" "\n" "Examples:\n" -@@ -206,7 +206,7 @@ int parse_setenv_args(int argc, char *argv[]) +@@ -206,7 +206,7 @@ int parse_setenv_args(int argc, char *ar int main(int argc, char *argv[]) { @@ -41,4 +39,3 @@ index 0b201b9e62..1d193bd437 100644 int lockfd = -1; int retval = EXIT_SUCCESS; char *_cmdname; - From a79efe4cdf4531f4fef2bc0b73ad25046151673b Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sat, 14 Oct 2023 20:48:28 +0200 Subject: [PATCH 19/50] qca-ssdk: add support for ipq60xx IPQ60xx uses a different codename for SSDK, so lets pass the correct one as otherwise SSDK asumes we are building for the old MIPS SoC-s. Signed-off-by: Robert Marko [ drop outdated commit description info ] Signed-off-by: Christian Marangi --- package/kernel/qca-ssdk/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index 2517b80069..7eccdaa1d7 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qca-ssdk -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git PKG_SOURCE_PROTO:=git @@ -53,6 +53,10 @@ ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") MAKE_FLAGS+= CHIP_TYPE=HPPE endif +ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq60xx") + MAKE_FLAGS+= CHIP_TYPE=CPPE +endif + define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include/qca-ssdk $(INSTALL_DIR) $(1)/usr/include/qca-ssdk/api From 23deb4ac90e16277e9d779856e77d0ed22142bc5 Mon Sep 17 00:00:00 2001 From: Mantas Pucka Date: Sat, 14 Oct 2023 19:36:38 +0200 Subject: [PATCH 20/50] qualcommax: add ipq60xx support Introduce support for the Qualcomm IPQ60xx SoC. WiFi support still has to be handled and correctly fix hence this is currently marked as source-only to have a solid base to progress on correct support of this and hope Upstream QUIC publish newers ath11k drivers for this SoC. Co-developed-by: Robert Marko Signed-off-by: Robert Marko Signed-off-by: Mantas Pucka [ improve commit description, add SoB for Robert, make it source-only ] Signed-off-by: Christian Marangi --- target/linux/qualcommax/Makefile | 2 +- .../arm64/boot/dts/qcom/ipq6018-cp-cpu.dtsi | 19 + .../boot/dts/qcom/ipq6018-cpr-regulator.dtsi | 124 +++++ .../arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi | 507 ++++++++++++++++++ target/linux/qualcommax/image/ipq60xx.mk | 0 .../linux/qualcommax/ipq60xx/config-default | 11 + target/linux/qualcommax/ipq60xx/target.mk | 8 + ...-gcc-ipq6018-drop-redundant-F-define.patch | 27 + ...lk-qcom-gcc-ipq6018-update-UBI32-PLL.patch | 39 ++ ...pq6018-remove-duplicate-initializers.patch | 38 ++ ...-fix-serdes-init-sequence-for-IPQ601.patch | 102 ++++ ...6018-add-qdss_at-clock-needed-for-wi.patch | 50 ++ ...m64-dts-qcom-ipq6018-add-QFPROM-node.patch | 34 ++ ...q-qcom-nvmem-add-support-for-IPQ6018.patch | 123 +++++ ...pq6018-include-the-GPLL0-as-clock-pr.patch | 32 ++ ...wcss-populate-driver-data-for-IPQ601.patch | 61 +++ ...rm64-dts-qcom-ipq6018-add-SDHCI-node.patch | 45 ++ ...Remove-IPQ6018-SOC-specific-compatib.patch | 34 ++ ...dts-qcom-ipq6018-add-LDOA2-regulator.patch | 27 + ...rm64-dts-qcom-ipq6018-add-tsens-node.patch | 32 ++ ...4-dts-qcom-ipq6018-add-thermal-zones.patch | 178 ++++++ ...4-dts-qcom-ipq6018-use-CPUFreq-NVMEM.patch | 85 +++ ...nt-advertise-OSI-support-for-IPQ6018.patch | 40 ++ ...-workaround-networking-clock-parenti.patch | 109 ++++ ...wcss-change-ssr-name-for-ipq6018-wif.patch | 40 ++ ...arm64-dts-qcom-ipq6018-add-wifi-node.patch | 120 +++++ ...07-soc-qcom-fix-smp2p-ack-on-ipq6018.patch | 53 ++ ...q6v5_wcss-add-optional-qdss_at-clock.patch | 55 ++ ...pq6018-assign-QDSS_AT-clock-to-wifi-.patch | 26 + ...pq6018-change-voltage-to-perf-levels.patch | 65 +++ 30 files changed, 2085 insertions(+), 1 deletion(-) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cp-cpu.dtsi create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cpr-regulator.dtsi create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi create mode 100644 target/linux/qualcommax/image/ipq60xx.mk create mode 100644 target/linux/qualcommax/ipq60xx/config-default create mode 100644 target/linux/qualcommax/ipq60xx/target.mk create mode 100644 target/linux/qualcommax/patches-6.1/0026-v6.5-clk-qcom-gcc-ipq6018-drop-redundant-F-define.patch create mode 100644 target/linux/qualcommax/patches-6.1/0033-v6.5-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch create mode 100644 target/linux/qualcommax/patches-6.1/0034-v6.5-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch create mode 100644 target/linux/qualcommax/patches-6.1/0035-v6.9-phy-qcom-qmp-usb-fix-serdes-init-sequence-for-IPQ601.patch create mode 100644 target/linux/qualcommax/patches-6.1/0036-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch create mode 100644 target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch create mode 100644 target/linux/qualcommax/patches-6.1/0038-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch create mode 100644 target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch create mode 100644 target/linux/qualcommax/patches-6.1/0136-remoteproc-qcom-wcss-populate-driver-data-for-IPQ601.patch create mode 100644 target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-add-SDHCI-node.patch create mode 100644 target/linux/qualcommax/patches-6.1/0138-hwspinlock-qcom-Remove-IPQ6018-SOC-specific-compatib.patch create mode 100644 target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch create mode 100644 target/linux/qualcommax/patches-6.1/0140-arm64-dts-qcom-ipq6018-add-tsens-node.patch create mode 100644 target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch create mode 100644 target/linux/qualcommax/patches-6.1/0142-arm64-dts-qcom-ipq6018-use-CPUFreq-NVMEM.patch create mode 100644 target/linux/qualcommax/patches-6.1/0903-psci-dont-advertise-OSI-support-for-IPQ6018.patch create mode 100644 target/linux/qualcommax/patches-6.1/0904-clk-qcom-ipq6018-workaround-networking-clock-parenti.patch create mode 100644 target/linux/qualcommax/patches-6.1/0905-remoteproc-q6v5_wcss-change-ssr-name-for-ipq6018-wif.patch create mode 100644 target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch create mode 100644 target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch create mode 100644 target/linux/qualcommax/patches-6.1/0908-remoteproc-qcom_q6v5_wcss-add-optional-qdss_at-clock.patch create mode 100644 target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch create mode 100644 target/linux/qualcommax/patches-6.1/0910-arm64-dts-qcom-ipq6018-change-voltage-to-perf-levels.patch diff --git a/target/linux/qualcommax/Makefile b/target/linux/qualcommax/Makefile index a9d4c06b77..1ce391ad22 100644 --- a/target/linux/qualcommax/Makefile +++ b/target/linux/qualcommax/Makefile @@ -6,7 +6,7 @@ BOARDNAME:=Qualcomm Atheros 802.11ax WiSoC-s FEATURES:=squashfs ramdisk fpu nand rtc emmc KERNELNAME:=Image dtbs CPU_TYPE:=cortex-a53 -SUBTARGETS:=ipq807x +SUBTARGETS:=ipq807x ipq60xx KERNEL_PATCHVER:=6.1 diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cp-cpu.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cp-cpu.dtsi new file mode 100644 index 0000000000..2dee366e1e --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cp-cpu.dtsi @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "ipq6018-cpr-regulator.dtsi" + +&CPU0 { + cpu-supply = <&apc_vreg>; +}; + +&CPU1 { + cpu-supply = <&apc_vreg>; +}; + +&CPU2 { + cpu-supply = <&apc_vreg>; +}; + +&CPU3 { + cpu-supply = <&apc_vreg>; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cpr-regulator.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cpr-regulator.dtsi new file mode 100644 index 0000000000..738123296f --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-cpr-regulator.dtsi @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2019-2020 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. + */ + +&soc { + apc_apm: apm@b111000 { + compatible = "qcom,ipq807x-apm"; + reg = <0x0 0xb111000 0x0 0x1000>; + reg-names = "pm-apcc-glb"; + qcom,apm-post-halt-delay = <0x2>; + qcom,apm-halt-clk-delay = <0x11>; + qcom,apm-resume-clk-delay = <0x10>; + qcom,apm-sel-switch-delay = <0x01>; + }; + + apc_cpr: cpr4-ctrl@b018000 { + compatible = "qcom,cpr4-ipq6018-apss-regulator"; + reg = <0x0 0xb018000 0x0 0x4000>, <0x0 0xa4000 0x0 0x1000>, <0x0 0x0193d008 0x0 0x4>; + reg-names = "cpr_ctrl", "fuse_base", "cpr_tcsr_reg"; + interrupts = ; + interrupt-names = "cpr"; + qcom,cpr-ctrl-name = "apc"; + qcom,cpr-sensor-time = <1000>; + qcom,cpr-loop-time = <5000000>; + qcom,cpr-idle-cycles = <15>; + qcom,cpr-step-quot-init-min = <0>; + qcom,cpr-step-quot-init-max = <15>; + qcom,cpr-count-mode = <0>; /* All-at-once */ + qcom,cpr-count-repeat = <1>; + qcom,cpr-down-error-step-limit = <1>; + qcom,cpr-up-error-step-limit = <1>; + qcom,apm-ctrl = <&apc_apm>; + qcom,apm-threshold-voltage = <850000>; + vdd-supply = <&ipq6018_s2>; + qcom,voltage-step = <12500>; + + thread@0 { + qcom,cpr-thread-id = <0>; + qcom,cpr-consecutive-up = <2>; + qcom,cpr-consecutive-down = <2>; + qcom,cpr-up-threshold = <2>; + qcom,cpr-down-threshold = <2>; + + apc_vreg: regulator { + regulator-name = "apc_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <6>; + qcom,cpr-fuse-corners = <4>; + qcom,cpr-fuse-combos = <8>; + qcom,cpr-corners = <6>; + qcom,cpr-speed-bins = <1>; + qcom,cpr-speed-bin-corners = <6>; + qcom,cpr-corner-fmax-map = <1 3 5 6>; + qcom,allow-voltage-interpolation; + qcom,allow-quotient-interpolation; + qcom,cpr-voltage-ceiling = + <725000 787500 862500 + 925000 987500 1062500>; + qcom,cpr-voltage-floor = + <587500 650000 712500 + 750000 787500 850000>; + qcom,corner-frequencies = + <864000000 1056000000 1320000000 + 1440000000 1608000000 1800000000>; + qcom,cpr-ro-sel = + /* Speed bin 0; CPR rev 0..7 */ + < 0 0 0 0>, + < 7 7 7 7>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>; + + qcom,cpr-open-loop-voltage-fuse-adjustment = + /* Speed bin 0; CPR rev 0..7 */ + /* SVS Nominal Turbo Turbo_L1 */ + < 0 0 0 0>, + < 0 0 15000 0>, + < 0 0 15000 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>; + + qcom,cpr-closed-loop-voltage-fuse-adjustment = + /* Speed bin 0; CPR rev 0..7 */ + < 0 0 0 0>, + < 13000 0 13000 13000>, + < 13000 0 13000 13000>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>, + < 0 0 0 0>; + + qcom,cpr-ro-scaling-factor = + < 2000 1770 1900 1670 1930 1770 1910 1800 + 1870 1730 2000 1840 1800 2030 1700 1890 >, + < 2000 1770 1900 1670 1930 1770 1910 1800 + 1870 1730 2000 1840 1800 2030 1700 1890 >, + < 2000 1770 1900 1670 1930 1770 1910 1800 + 1870 1730 2000 1840 1800 2030 1700 1890 >, + < 2000 1770 1900 1670 1930 1770 1910 1800 + 1870 1730 2000 1840 1800 2030 1700 1890 >; + regulator-always-on; + }; + }; + }; +}; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi new file mode 100644 index 0000000000..92ff7c2a5a --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-ess.dtsi @@ -0,0 +1,507 @@ +#include + +&soc { + bias_pll_cc_clk: bias-pll-cc-clk { + compatible = "fixed-clock"; + clock-frequency = <300000000>; + clock-output-names = "bias_pll_cc_clk"; + #clock-cells = <0>; + }; + + bias_pll_nss_noc_clk: bias-pll-nss-noc-clk { + compatible = "fixed-clock"; + clock-frequency = <416500000>; + clock-output-names = "bias_pll_nss_noc_clk"; + #clock-cells = <0>; + }; + + edma: edma@3ab00000 { + compatible = "qcom,edma"; + reg = <0x0 0x3ab00000 0x0 0xabe00>; + reg-names = "edma-reg-base"; + qcom,txdesc-ring-start = <23>; + qcom,txdesc-rings = <1>; + qcom,txcmpl-ring-start = <23>; + qcom,txcmpl-rings = <1>; + qcom,rxfill-ring-start = <7>; + qcom,rxfill-rings = <1>; + qcom,rxdesc-ring-start = <15>; + qcom,rxdesc-rings = <1>; + interrupts = , + , + , + ; + resets = <&gcc GCC_EDMA_HW_RESET>; + reset-names = "edma_rst"; + status = "disabled"; + }; + + ess_instance: ess-instance { + #address-cells = <1>; + #size-cells = <1>; + num_devices = <1>; + + switch: ess-switch@3a000000 { + compatible = "qcom,ess-switch-ipq60xx"; + reg = <0x3a000000 0x1000000>; + switch_access_mode = "local bus"; + clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>, + <&gcc GCC_CMN_12GPLL_SYS_CLK>, + <&gcc GCC_UNIPHY0_AHB_CLK>, + <&gcc GCC_UNIPHY0_SYS_CLK>, + <&gcc GCC_UNIPHY1_AHB_CLK>, + <&gcc GCC_UNIPHY1_SYS_CLK>, + <&gcc GCC_PORT1_MAC_CLK>, + <&gcc GCC_PORT2_MAC_CLK>, + <&gcc GCC_PORT3_MAC_CLK>, + <&gcc GCC_PORT4_MAC_CLK>, + <&gcc GCC_PORT5_MAC_CLK>, + <&gcc GCC_NSS_PPE_CLK>, + <&gcc GCC_NSS_PPE_CFG_CLK>, + <&gcc GCC_NSSNOC_PPE_CLK>, + <&gcc GCC_NSSNOC_PPE_CFG_CLK>, + <&gcc GCC_NSS_EDMA_CLK>, + <&gcc GCC_NSS_EDMA_CFG_CLK>, + <&gcc GCC_NSS_PPE_IPE_CLK>, + <&gcc GCC_MDIO_AHB_CLK>, + <&gcc GCC_NSS_NOC_CLK>, + <&gcc GCC_NSSNOC_SNOC_CLK>, + <&gcc GCC_NSS_CRYPTO_CLK>, + <&gcc GCC_NSS_PTP_REF_CLK>, + <&gcc GCC_NSS_PORT1_RX_CLK>, + <&gcc GCC_NSS_PORT1_TX_CLK>, + <&gcc GCC_NSS_PORT2_RX_CLK>, + <&gcc GCC_NSS_PORT2_TX_CLK>, + <&gcc GCC_NSS_PORT3_RX_CLK>, + <&gcc GCC_NSS_PORT3_TX_CLK>, + <&gcc GCC_NSS_PORT4_RX_CLK>, + <&gcc GCC_NSS_PORT4_TX_CLK>, + <&gcc GCC_NSS_PORT5_RX_CLK>, + <&gcc GCC_NSS_PORT5_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT1_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT1_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT2_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT3_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT4_TX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY0_PORT5_TX_CLK>, + <&gcc GCC_UNIPHY1_PORT5_RX_CLK>, + <&gcc GCC_UNIPHY1_PORT5_TX_CLK>, + <&gcc NSS_PORT5_RX_CLK_SRC>, + <&gcc NSS_PORT5_TX_CLK_SRC>, + <&gcc GCC_SNOC_NSSNOC_CLK>; + clock-names = "cmn_ahb_clk", "cmn_sys_clk", + "uniphy0_ahb_clk", "uniphy0_sys_clk", + "uniphy1_ahb_clk", "uniphy1_sys_clk", + "port1_mac_clk", "port2_mac_clk", + "port3_mac_clk", "port4_mac_clk", + "port5_mac_clk", + "nss_ppe_clk", "nss_ppe_cfg_clk", + "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk", + "nss_edma_clk", "nss_edma_cfg_clk", + "nss_ppe_ipe_clk", + "gcc_mdio_ahb_clk", "gcc_nss_noc_clk", + "gcc_nssnoc_snoc_clk", + "gcc_nss_crypto_clk", + "gcc_nss_ptp_ref_clk", + "nss_port1_rx_clk", "nss_port1_tx_clk", + "nss_port2_rx_clk", "nss_port2_tx_clk", + "nss_port3_rx_clk", "nss_port3_tx_clk", + "nss_port4_rx_clk", "nss_port4_tx_clk", + "nss_port5_rx_clk", "nss_port5_tx_clk", + "uniphy0_port1_rx_clk", + "uniphy0_port1_tx_clk", + "uniphy0_port2_rx_clk", + "uniphy0_port2_tx_clk", + "uniphy0_port3_rx_clk", + "uniphy0_port3_tx_clk", + "uniphy0_port4_rx_clk", + "uniphy0_port4_tx_clk", + "uniphy0_port5_rx_clk", + "uniphy0_port5_tx_clk", + "uniphy1_port5_rx_clk", + "uniphy1_port5_tx_clk", + "nss_port5_rx_clk_src", + "nss_port5_tx_clk_src", + "gcc_snoc_nssnoc_clk"; + resets = <&gcc GCC_PPE_FULL_RESET>, + <&gcc GCC_UNIPHY0_SOFT_RESET>, + <&gcc GCC_UNIPHY0_XPCS_RESET>, + <&gcc GCC_UNIPHY1_SOFT_RESET>, + <&gcc GCC_UNIPHY1_XPCS_RESET>, + <&gcc GCC_NSSPORT1_RESET>, + <&gcc GCC_NSSPORT2_RESET>, + <&gcc GCC_NSSPORT3_RESET>, + <&gcc GCC_NSSPORT4_RESET>, + <&gcc GCC_NSSPORT5_RESET>, + <&gcc GCC_UNIPHY0_PORT1_ARES>, + <&gcc GCC_UNIPHY0_PORT2_ARES>, + <&gcc GCC_UNIPHY0_PORT3_ARES>, + <&gcc GCC_UNIPHY0_PORT4_ARES>, + <&gcc GCC_UNIPHY0_PORT5_ARES>, + <&gcc GCC_UNIPHY0_PORT_4_5_RESET>, + <&gcc GCC_UNIPHY0_PORT_4_RESET>; + reset-names = "ppe_rst", "uniphy0_soft_rst", + "uniphy0_xpcs_rst", "uniphy1_soft_rst", + "uniphy1_xpcs_rst", "nss_port1_rst", + "nss_port2_rst", "nss_port3_rst", + "nss_port4_rst", "nss_port5_rst", + "uniphy0_port1_dis", + "uniphy0_port2_dis", + "uniphy0_port3_dis", + "uniphy0_port4_dis", + "uniphy0_port5_dis", + "uniphy0_port_4_5_rst", + "uniphy0_port_4_rst"; + mdio-bus = <&mdio>; + + switch_cpu_bmp = ; /* cpu port bitmap */ + switch_inner_bmp = <(ESS_PORT6 | ESS_PORT7)>; /*inner port bitmap*/ + switch_mac_mode = ; /* MAC mode for UNIPHY instance 0 */ + switch_mac_mode1 = ; /* MAC mode for UNIPHY instance 1 */ + switch_mac_mode2 = ; /* MAC mode for UNIPHY instance 2 */ + + status = "disabled"; + + bm_tick_mode = <0>; /* bm tick mode */ + tm_tick_mode = <0>; /* tm tick mode */ + + port_scheduler_resource { + port@0 { + port_id = <0>; + ucast_queue = <0 143>; + mcast_queue = <256 271>; + l0sp = <0 35>; + l0cdrr = <0 47>; + l0edrr = <0 47>; + l1cdrr = <0 7>; + l1edrr = <0 7>; + }; + port@1 { + port_id = <1>; + ucast_queue = <144 159>; + mcast_queue = <272 275>; + l0sp = <36 39>; + l0cdrr = <48 63>; + l0edrr = <48 63>; + l1cdrr = <8 11>; + l1edrr = <8 11>; + }; + port@2 { + port_id = <2>; + ucast_queue = <160 175>; + mcast_queue = <276 279>; + l0sp = <40 43>; + l0cdrr = <64 79>; + l0edrr = <64 79>; + l1cdrr = <12 15>; + l1edrr = <12 15>; + }; + port@3 { + port_id = <3>; + ucast_queue = <176 191>; + mcast_queue = <280 283>; + l0sp = <44 47>; + l0cdrr = <80 95>; + l0edrr = <80 95>; + l1cdrr = <16 19>; + l1edrr = <16 19>; + }; + port@4 { + port_id = <4>; + ucast_queue = <192 207>; + mcast_queue = <284 287>; + l0sp = <48 51>; + l0cdrr = <96 111>; + l0edrr = <96 111>; + l1cdrr = <20 23>; + l1edrr = <20 23>; + }; + port@5 { + port_id = <5>; + ucast_queue = <208 223>; + mcast_queue = <288 291>; + l0sp = <52 55>; + l0cdrr = <112 127>; + l0edrr = <112 127>; + l1cdrr = <24 27>; + l1edrr = <24 27>; + }; + port@6 { + port_id = <6>; + ucast_queue = <224 239>; + mcast_queue = <292 295>; + l0sp = <56 59>; + l0cdrr = <128 143>; + l0edrr = <128 143>; + l1cdrr = <28 31>; + l1edrr = <28 31>; + }; + port@7 { + port_id = <7>; + ucast_queue = <240 255>; + mcast_queue = <296 299>; + l0sp = <60 63>; + l0cdrr = <144 159>; + l0edrr = <144 159>; + l1cdrr = <32 35>; + l1edrr = <32 35>; + }; + }; + port_scheduler_config { + port@0 { + port_id = <0>; + l1scheduler { + group@0 { + sp = <0 1>; /*L0 SPs*/ + /*cpri cdrr epri edrr*/ + cfg = <0 0 0 0>; + }; + }; + l0scheduler { + group@0 { + /*unicast queues*/ + ucast_queue = <0 4 8>; + /*multicast queues*/ + mcast_queue = <256 260>; + /*sp cpricdrrepriedrr*/ + cfg = <0 0 0 0 0>; + }; + group@1 { + ucast_queue = <1 5 9>; + mcast_queue = <257 261>; + cfg = <0 1 1 1 1>; + }; + group@2 { + ucast_queue = <2 6 10>; + mcast_queue = <258 262>; + cfg = <0 2 2 2 2>; + }; + group@3 { + ucast_queue = <3 7 11>; + mcast_queue = <259 263>; + cfg = <0 3 3 3 3>; + }; + }; + }; + port@1 { + port_id = <1>; + l1scheduler { + group@0 { + sp = <36>; + cfg = <0 8 0 8>; + }; + group@1 { + sp = <37>; + cfg = <1 9 1 9>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <144>; + ucast_loop_pri = <16>; + mcast_queue = <272>; + mcast_loop_pri = <4>; + cfg = <36 0 48 0 48>; + }; + }; + }; + port@2 { + port_id = <2>; + l1scheduler { + group@0 { + sp = <40>; + cfg = <0 12 0 12>; + }; + group@1 { + sp = <41>; + cfg = <1 13 1 13>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <160>; + ucast_loop_pri = <16>; + mcast_queue = <276>; + mcast_loop_pri = <4>; + cfg = <40 0 64 0 64>; + }; + }; + }; + port@3 { + port_id = <3>; + l1scheduler { + group@0 { + sp = <44>; + cfg = <0 16 0 16>; + }; + group@1 { + sp = <45>; + cfg = <1 17 1 17>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <176>; + ucast_loop_pri = <16>; + mcast_queue = <280>; + mcast_loop_pri = <4>; + cfg = <44 0 80 0 80>; + }; + }; + }; + port@4 { + port_id = <4>; + l1scheduler { + group@0 { + sp = <48>; + cfg = <0 20 0 20>; + }; + group@1 { + sp = <49>; + cfg = <1 21 1 21>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <192>; + ucast_loop_pri = <16>; + mcast_queue = <284>; + mcast_loop_pri = <4>; + cfg = <48 0 96 0 96>; + }; + }; + }; + port@5 { + port_id = <5>; + l1scheduler { + group@0 { + sp = <52>; + cfg = <0 24 0 24>; + }; + group@1 { + sp = <53>; + cfg = <1 25 1 25>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <208>; + ucast_loop_pri = <16>; + mcast_queue = <288>; + mcast_loop_pri = <4>; + cfg = <52 0 112 0 112>; + }; + }; + }; + port@6 { + port_id = <6>; + l1scheduler { + group@0 { + sp = <56>; + cfg = <0 28 0 28>; + }; + group@1 { + sp = <57>; + cfg = <1 29 1 29>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <224>; + ucast_loop_pri = <16>; + mcast_queue = <292>; + mcast_loop_pri = <4>; + cfg = <56 0 128 0 128>; + }; + }; + }; + port@7 { + port_id = <7>; + l1scheduler { + group@0 { + sp = <60>; + cfg = <0 32 0 32>; + }; + group@1 { + sp = <61>; + cfg = <1 33 1 33>; + }; + }; + l0scheduler { + group@0 { + ucast_queue = <240>; + ucast_loop_pri = <16>; + mcast_queue = <296>; + cfg = <60 0 144 0 144>; + }; + }; + }; + }; + }; + + ess-uniphy@7a00000 { + compatible = "qcom,ess-uniphy"; + reg = <0x7a00000 0x30000>; + uniphy_access_mode = "local bus"; + }; + }; + + dp1: dp1 { + device_type = "network"; + compatible = "qcom,nss-dp"; + qcom,id = <1>; + reg = <0x0 0x3a001000 0x0 0x200>; + qcom,mactype = <0>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + status = "disabled"; + }; + + dp2: dp2 { + device_type = "network"; + compatible = "qcom,nss-dp"; + qcom,id = <2>; + reg = <0x0 0x3a001200 0x0 0x200>; + qcom,mactype = <0>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + status = "disabled"; + }; + + dp3: dp3 { + device_type = "network"; + compatible = "qcom,nss-dp"; + qcom,id = <3>; + reg = <0x0 0x3a001400 0x0 0x200>; + qcom,mactype = <0>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + status = "disabled"; + }; + + dp4: dp4 { + device_type = "network"; + compatible = "qcom,nss-dp"; + qcom,id = <4>; + reg = <0x0 0x3a001600 0x0 0x200>; + qcom,mactype = <0>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + status = "disabled"; + }; + + dp5: dp5 { + device_type = "network"; + compatible = "qcom,nss-dp"; + qcom,id = <5>; + reg = <0x0 0x3a001800 0x0 0x200>; + qcom,mactype = <0>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + status = "disabled"; + }; +}; diff --git a/target/linux/qualcommax/image/ipq60xx.mk b/target/linux/qualcommax/image/ipq60xx.mk new file mode 100644 index 0000000000..e69de29bb2 diff --git a/target/linux/qualcommax/ipq60xx/config-default b/target/linux/qualcommax/ipq60xx/config-default new file mode 100644 index 0000000000..9ce4b04293 --- /dev/null +++ b/target/linux/qualcommax/ipq60xx/config-default @@ -0,0 +1,11 @@ +CONFIG_IPQ_GCC_6018=y +CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_PINCTRL_IPQ6018=y +CONFIG_QCOM_APM=y +# CONFIG_QCOM_CLK_SMD_RPM is not set +# CONFIG_QCOM_RPMPD is not set +CONFIG_QCOM_SMD_RPM=y +CONFIG_REGULATOR_CPR3=y +# CONFIG_REGULATOR_CPR3_NPU is not set +CONFIG_REGULATOR_CPR4_APSS=y +CONFIG_REGULATOR_QCOM_SMD_RPM=y diff --git a/target/linux/qualcommax/ipq60xx/target.mk b/target/linux/qualcommax/ipq60xx/target.mk new file mode 100644 index 0000000000..dc3a2ceff6 --- /dev/null +++ b/target/linux/qualcommax/ipq60xx/target.mk @@ -0,0 +1,8 @@ +SUBTARGET:=ipq60xx +FEATURES += source-only +BOARDNAME:=Qualcomm Atheros IPQ60xx +DEFAULT_PACKAGES += ath11k-firmware-ipq6018 + +define Target/Description + Build firmware images for Qualcomm Atheros IPQ60xx based boards. +endef diff --git a/target/linux/qualcommax/patches-6.1/0026-v6.5-clk-qcom-gcc-ipq6018-drop-redundant-F-define.patch b/target/linux/qualcommax/patches-6.1/0026-v6.5-clk-qcom-gcc-ipq6018-drop-redundant-F-define.patch new file mode 100644 index 0000000000..30da78f08e --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0026-v6.5-clk-qcom-gcc-ipq6018-drop-redundant-F-define.patch @@ -0,0 +1,27 @@ +From 1e8a314a1b87eaba496fcc6dc0efef573b3c186d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Mon, 17 Apr 2023 19:44:07 +0200 +Subject: [PATCH] clk: qcom: gcc-ipq6018: drop redundant F define + +The same exact F frequency table entry is defined in clk-rcg.h +Drop the redundant define to cleanup code. + +Signed-off-by: Christian Marangi +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230417174408.23722-1-ansuelsmth@gmail.com +--- + drivers/clk/qcom/gcc-ipq6018.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -26,8 +26,6 @@ + #include "clk-regmap-mux.h" + #include "reset.h" + +-#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } +- + enum { + P_XO, + P_BIAS_PLL, diff --git a/target/linux/qualcommax/patches-6.1/0033-v6.5-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch b/target/linux/qualcommax/patches-6.1/0033-v6.5-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch new file mode 100644 index 0000000000..7f53734f29 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0033-v6.5-clk-qcom-gcc-ipq6018-update-UBI32-PLL.patch @@ -0,0 +1,39 @@ +From 91e7c87f0ec1d644afb65cf3a16ded874c9d4ab9 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Fri, 26 May 2023 21:08:54 +0200 +Subject: [PATCH] clk: qcom: gcc-ipq6018: update UBI32 PLL + +Update the UBI32 alpha PLL config to the latest values from the downstream +QCA 5.4 kernel. + +Signed-off-by: Robert Marko +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526190855.2941291-1-robimarko@gmail.com +--- + drivers/clk/qcom/gcc-ipq6018.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -4143,15 +4143,20 @@ static struct clk_branch gcc_dcc_clk = { + + static const struct alpha_pll_config ubi32_pll_config = { + .l = 0x3e, +- .alpha = 0x57, ++ .alpha = 0x6667, + .config_ctl_val = 0x240d6aa8, + .config_ctl_hi_val = 0x3c2, ++ .config_ctl_val = 0x240d4828, ++ .config_ctl_hi_val = 0x6, + .main_output_mask = BIT(0), + .aux_output_mask = BIT(1), + .pre_div_val = 0x0, + .pre_div_mask = BIT(12), + .post_div_val = 0x0, + .post_div_mask = GENMASK(9, 8), ++ .alpha_en_mask = BIT(24), ++ .test_ctl_val = 0x1C0000C0, ++ .test_ctl_hi_val = 0x4000, + }; + + static const struct alpha_pll_config nss_crypto_pll_config = { diff --git a/target/linux/qualcommax/patches-6.1/0034-v6.5-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch b/target/linux/qualcommax/patches-6.1/0034-v6.5-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch new file mode 100644 index 0000000000..2de9efd376 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0034-v6.5-clk-qcom-gcc-ipq6018-remove-duplicate-initializers.patch @@ -0,0 +1,38 @@ +From 3f2fbfe6e4f6f2bdd1da8ef5aceba3945c4ada57 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Thu, 1 Jun 2023 23:34:12 +0200 +Subject: [PATCH] clk: qcom: gcc-ipq6018: remove duplicate initializers + +A recent change added new initializers for .config_ctl_val and +.config_ctl_hi_val but left the old values in place: + +drivers/clk/qcom/gcc-ipq6018.c:4155:27: error: initialized field overwritten [-Werror=override-init] + 4155 | .config_ctl_val = 0x240d4828, + | ^~~~~~~~~~ +drivers/clk/qcom/gcc-ipq6018.c:4156:30: error: initialized field overwritten [-Werror=override-init] + 4156 | .config_ctl_hi_val = 0x6, + | ^~~ + +Remove the unused ones now to avoid confusion. + +Fixes: f4f0c8acee0e4 ("clk: qcom: gcc-ipq6018: update UBI32 PLL") +Signed-off-by: Arnd Bergmann +Reviewed-by: Robert Marko +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230601213416.3373599-1-arnd@kernel.org +--- + drivers/clk/qcom/gcc-ipq6018.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -4144,8 +4144,6 @@ static struct clk_branch gcc_dcc_clk = { + static const struct alpha_pll_config ubi32_pll_config = { + .l = 0x3e, + .alpha = 0x6667, +- .config_ctl_val = 0x240d6aa8, +- .config_ctl_hi_val = 0x3c2, + .config_ctl_val = 0x240d4828, + .config_ctl_hi_val = 0x6, + .main_output_mask = BIT(0), diff --git a/target/linux/qualcommax/patches-6.1/0035-v6.9-phy-qcom-qmp-usb-fix-serdes-init-sequence-for-IPQ601.patch b/target/linux/qualcommax/patches-6.1/0035-v6.9-phy-qcom-qmp-usb-fix-serdes-init-sequence-for-IPQ601.patch new file mode 100644 index 0000000000..97b46f74ef --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0035-v6.9-phy-qcom-qmp-usb-fix-serdes-init-sequence-for-IPQ601.patch @@ -0,0 +1,102 @@ +From 62a5df451ab911421da96655fcc4d1e269ff6e2f Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 23 Jan 2024 18:09:20 +0200 +Subject: [PATCH] phy: qcom-qmp-usb: fix serdes init sequence for IPQ6018 + +Commit 23fd679249df ("phy: qcom-qmp: add USB3 PHY support for IPQ6018") +noted that IPQ6018 init is identical to IPQ8074. Yet downstream uses +separate serdes init sequence for IPQ6018. Since already existing IPQ9574 +serdes init sequence is identical, just reuse it and fix failing USB3 mode +in IPQ6018. + +Fixes: 23fd679249df ("phy: qcom-qmp: add USB3 PHY support for IPQ6018") +Signed-off-by: Mantas Pucka +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/1706026160-17520-3-git-send-email-mantas@8devices.com +Signed-off-by: Vinod Koul +--- + drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c ++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +@@ -233,6 +233,43 @@ static const struct qmp_phy_init_tbl ipq + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f), + }; + ++static const struct qmp_phy_init_tbl ipq9574_usb3_serdes_tbl[] = { ++ QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a), ++ QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), ++ QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), ++ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f), ++ QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06), ++ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), ++ /* PLL and Loop filter settings */ ++ QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x68), ++ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0xab), ++ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0xaa), ++ QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x02), ++ QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x09), ++ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), ++ QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), ++ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0xa0), ++ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xaa), ++ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x29), ++ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), ++ /* SSC settings */ ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x7d), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x0a), ++ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x05), ++}; ++ + static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), + QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), +@@ -1591,6 +1628,26 @@ static const char * const qmp_phy_vreg_l + "vdda-phy", "vdda-pll", + }; + ++static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = { ++ .lanes = 1, ++ ++ .serdes_tbl = ipq9574_usb3_serdes_tbl, ++ .serdes_tbl_num = ARRAY_SIZE(ipq9574_usb3_serdes_tbl), ++ .tx_tbl = msm8996_usb3_tx_tbl, ++ .tx_tbl_num = ARRAY_SIZE(msm8996_usb3_tx_tbl), ++ .rx_tbl = ipq8074_usb3_rx_tbl, ++ .rx_tbl_num = ARRAY_SIZE(ipq8074_usb3_rx_tbl), ++ .pcs_tbl = ipq8074_usb3_pcs_tbl, ++ .pcs_tbl_num = ARRAY_SIZE(ipq8074_usb3_pcs_tbl), ++ .clk_list = msm8996_phy_clk_l, ++ .num_clks = ARRAY_SIZE(msm8996_phy_clk_l), ++ .reset_list = msm8996_usb3phy_reset_l, ++ .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), ++ .vreg_list = qmp_phy_vreg_l, ++ .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), ++ .regs = qmp_v3_usb3phy_regs_layout, ++}; ++ + static const struct qmp_phy_cfg ipq8074_usb3phy_cfg = { + .lanes = 1, + +@@ -2534,7 +2591,7 @@ static const struct of_device_id qmp_usb + .data = &msm8996_usb3phy_cfg, + }, { + .compatible = "qcom,ipq6018-qmp-usb3-phy", +- .data = &ipq8074_usb3phy_cfg, ++ .data = &ipq6018_usb3phy_cfg, + }, { + .compatible = "qcom,sc7180-qmp-usb3-phy", + .data = &sc7180_usb3phy_cfg, diff --git a/target/linux/qualcommax/patches-6.1/0036-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch b/target/linux/qualcommax/patches-6.1/0036-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch new file mode 100644 index 0000000000..bbe8b19c46 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0036-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch @@ -0,0 +1,50 @@ +From fd712118aa1aa758da1fd1546b3f8a1b00e42cbc Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 23 Jan 2024 11:26:09 +0200 +Subject: [PATCH] clk: qcom: gcc-ipq6018: add qdss_at clock needed for wifi + operation + +Without it system hangs upon wifi firmware load. It should be enabled by +remoteproc/wifi driver. Bindings already exist for it, so add it based +on vendor code. + +Signed-off-by: Mantas Pucka +Link: https://lore.kernel.org/r/1706001970-26032-1-git-send-email-mantas@8devices.com +Signed-off-by: Bjorn Andersson +--- + drivers/clk/qcom/gcc-ipq6018.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -3503,6 +3503,22 @@ static struct clk_branch gcc_prng_ahb_cl + }, + }; + ++static struct clk_branch gcc_qdss_at_clk = { ++ .halt_reg = 0x29024, ++ .clkr = { ++ .enable_reg = 0x29024, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_at_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_at_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_qdss_dap_clk = { + .halt_reg = 0x29084, + .clkr = { +@@ -4341,6 +4357,7 @@ static struct clk_regmap *gcc_ipq6018_cl + [GCC_SYS_NOC_PCIE0_AXI_CLK] = &gcc_sys_noc_pcie0_axi_clk.clkr, + [GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, ++ [GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, + [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, diff --git a/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch b/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch new file mode 100644 index 0000000000..5b467ee029 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch @@ -0,0 +1,34 @@ +From 546f0617a22a481f3ca1f7e058aea0c40517c64e Mon Sep 17 00:00:00 2001 +From: Kathiravan T +Date: Fri, 26 May 2023 18:23:04 +0530 +Subject: [PATCH] arm64: dts: qcom: ipq6018: add QFPROM node + +IPQ6018 has efuse region to determine the various HW quirks. Lets +add the initial support and the individual fuses will be added as they +are required. + +Signed-off-by: Kathiravan T +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230526125305.19626-4-quic_kathirav@quicinc.com +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -179,6 +179,13 @@ + dma-ranges; + compatible = "simple-bus"; + ++ qfprom: efuse@a4000 { ++ compatible = "qcom,ipq6018-qfprom", "qcom,qfprom"; ++ reg = <0x0 0x000a4000 0x0 0x2000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++ + prng: qrng@e1000 { + compatible = "qcom,prng-ee"; + reg = <0x0 0xe3000 0x0 0x1000>; diff --git a/target/linux/qualcommax/patches-6.1/0038-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch b/target/linux/qualcommax/patches-6.1/0038-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch new file mode 100644 index 0000000000..ffd9cf030a --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0038-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch @@ -0,0 +1,123 @@ +From 47e161a7873b0891f4e01a69a839f6161d816ea8 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Wed, 25 Oct 2023 14:57:57 +0530 +Subject: [PATCH] cpufreq: qcom-nvmem: add support for IPQ6018 + +IPQ6018 SoC series comes in multiple SKU-s, and not all of them support +high frequency OPP points. + +SoC itself does however have a single bit in QFPROM to indicate the CPU +speed-bin. +That bit is used to indicate frequency limit of 1.5GHz, but that alone is +not enough as IPQ6000 only goes up to 1.2GHz, but SMEM ID can be used to +limit it further. + +IPQ6018 compatible is blacklisted from DT platdev as the cpufreq device +will get created by NVMEM CPUFreq driver. + +Signed-off-by: Robert Marko +[ Viresh: Fixed rebase conflict. ] +Signed-off-by: Viresh Kumar +--- + drivers/cpufreq/cpufreq-dt-platdev.c | 1 + + drivers/cpufreq/qcom-cpufreq-nvmem.c | 58 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 59 insertions(+) + +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -163,6 +163,7 @@ static const struct of_device_id blockli + { .compatible = "ti,dra7", }, + { .compatible = "ti,omap3", }, + ++ { .compatible = "qcom,ipq6018", }, + { .compatible = "qcom,ipq8064", }, + { .compatible = "qcom,ipq8074", }, + { .compatible = "qcom,apq8064", }, +--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c ++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c +@@ -36,6 +36,8 @@ enum ipq8074_versions { + IPQ8074_ACORN_VERSION, + }; + ++#define IPQ6000_VERSION BIT(2) ++ + struct qcom_cpufreq_drv; + + struct qcom_cpufreq_match_data { +@@ -209,6 +211,57 @@ len_error: + return ret; + } + ++static int qcom_cpufreq_ipq6018_name_version(struct device *cpu_dev, ++ struct nvmem_cell *speedbin_nvmem, ++ char **pvs_name, ++ struct qcom_cpufreq_drv *drv) ++{ ++ u32 msm_id; ++ int ret; ++ u8 *speedbin; ++ *pvs_name = NULL; ++ ++ ret = qcom_smem_get_soc_id(&msm_id); ++ if (ret) ++ return ret; ++ ++ speedbin = nvmem_cell_read(speedbin_nvmem, NULL); ++ if (IS_ERR(speedbin)) ++ return PTR_ERR(speedbin); ++ ++ switch (msm_id) { ++ case QCOM_ID_IPQ6005: ++ case QCOM_ID_IPQ6010: ++ case QCOM_ID_IPQ6018: ++ case QCOM_ID_IPQ6028: ++ /* Fuse Value Freq BIT to set ++ * --------------------------------- ++ * 2’b0 No Limit BIT(0) ++ * 2’b1 1.5 GHz BIT(1) ++ */ ++ drv->versions = 1 << (unsigned int)(*speedbin); ++ break; ++ case QCOM_ID_IPQ6000: ++ /* ++ * IPQ6018 family only has one bit to advertise the CPU ++ * speed-bin, but that is not enough for IPQ6000 which ++ * is only rated up to 1.2GHz. ++ * So for IPQ6000 manually set BIT(2) based on SMEM ID. ++ */ ++ drv->versions = IPQ6000_VERSION; ++ break; ++ default: ++ dev_err(cpu_dev, ++ "SoC ID %u is not part of IPQ6018 family, limiting to 1.2GHz!\n", ++ msm_id); ++ drv->versions = IPQ6000_VERSION; ++ break; ++ } ++ ++ kfree(speedbin); ++ return 0; ++} ++ + static int qcom_cpufreq_ipq8074_name_version(struct device *cpu_dev, + struct nvmem_cell *speedbin_nvmem, + char **pvs_name, +@@ -265,6 +318,10 @@ static const struct qcom_cpufreq_match_d + .get_version = qcom_cpufreq_ipq8074_name_version, + }; + ++static const struct qcom_cpufreq_match_data match_data_ipq6018 = { ++ .get_version = qcom_cpufreq_ipq6018_name_version, ++}; ++ + static int qcom_cpufreq_probe(struct platform_device *pdev) + { + struct qcom_cpufreq_drv *drv; +@@ -409,6 +466,7 @@ static const struct of_device_id qcom_cp + { .compatible = "qcom,apq8096", .data = &match_data_kryo }, + { .compatible = "qcom,msm8996", .data = &match_data_kryo }, + { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, ++ { .compatible = "qcom,ipq6018", .data = &match_data_ipq6018 }, + { .compatible = "qcom,ipq8064", .data = &match_data_krait }, + { .compatible = "qcom,ipq8074", .data = &match_data_ipq8074 }, + { .compatible = "qcom,apq8064", .data = &match_data_krait }, diff --git a/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch b/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch new file mode 100644 index 0000000000..eed2522198 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch @@ -0,0 +1,32 @@ +From a120815200adaf3ac28ccf3a1813c78b4be02cc4 Mon Sep 17 00:00:00 2001 +From: Kathiravan Thirumoorthy +Date: Thu, 14 Sep 2023 12:29:59 +0530 +Subject: [PATCH] arm64: dts: qcom: ipq6018: include the GPLL0 as clock + provider for mailbox + +While the kernel is booting up, APSS PLL will be running at 800MHz with +GPLL0 as source. Once the cpufreq driver is available, APSS PLL will be +configured to the rate based on the opp table and the source also will +be changed to APSS_PLL_EARLY. So allow the mailbox to consume the GPLL0, +with this inclusion, CPU Freq correctly reports that CPU is running at +800MHz rather than 24MHz. + +Signed-off-by: Kathiravan Thirumoorthy +Reviewed-by: Konrad Dybcio +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -503,8 +503,8 @@ + compatible = "qcom,ipq6018-apcs-apps-global"; + reg = <0x0 0x0b111000 0x0 0x1000>; + #clock-cells = <1>; +- clocks = <&a53pll>, <&xo>; +- clock-names = "pll", "xo"; ++ clocks = <&a53pll>, <&xo>, <&gcc GPLL0>; ++ clock-names = "pll", "xo", "gpll0"; + #mbox-cells = <1>; + }; + diff --git a/target/linux/qualcommax/patches-6.1/0136-remoteproc-qcom-wcss-populate-driver-data-for-IPQ601.patch b/target/linux/qualcommax/patches-6.1/0136-remoteproc-qcom-wcss-populate-driver-data-for-IPQ601.patch new file mode 100644 index 0000000000..9a5a3407e1 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0136-remoteproc-qcom-wcss-populate-driver-data-for-IPQ601.patch @@ -0,0 +1,61 @@ +From 9dd19a9ae36bc60d58287d0c52e53024d484e64d Mon Sep 17 00:00:00 2001 +From: Gokul Sriram Palanisamy +Date: Fri, 29 Jan 2021 22:41:59 +0530 +Subject: [PATCH 2/3] remoteproc: qcom: wcss: populate driver data for IPQ6018 + +Populate hardcoded param using driver data for IPQ6018 SoCs. + +Signed-off-by: Gokul Sriram Palanisamy +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -970,7 +970,7 @@ static int q6v5_alloc_memory_region(stru + return 0; + } + +-static int ipq8074_init_clock(struct q6v5_wcss *wcss) ++static int ipq_init_clock(struct q6v5_wcss *wcss) + { + int ret; + +@@ -1179,7 +1179,7 @@ static int q6v5_wcss_remove(struct platf + } + + static const struct wcss_data wcss_ipq8074_res_init = { +- .init_clock = ipq8074_init_clock, ++ .init_clock = ipq_init_clock, + .q6_firmware_name = "IPQ8074/q6_fw.mdt", + .m3_firmware_name = "IPQ8074/m3_fw.mdt", + .crash_reason_smem = WCSS_CRASH_REASON, +@@ -1193,6 +1193,20 @@ static const struct wcss_data wcss_ipq80 + .need_auto_boot = false, + }; + ++static const struct wcss_data wcss_ipq6018_res_init = { ++ .init_clock = ipq_init_clock, ++ .q6_firmware_name = "IPQ6018/q6_fw.mdt", ++ .m3_firmware_name = "IPQ6018/m3_fw.mdt", ++ .crash_reason_smem = WCSS_CRASH_REASON, ++ .aon_reset_required = true, ++ .wcss_q6_reset_required = true, ++ .bcr_reset_required = false, ++ .ssr_name = "q6wcss", ++ .ops = &q6v5_wcss_ipq8074_ops, ++ .requires_force_stop = true, ++ .need_mem_protection = true, ++}; ++ + static const struct wcss_data wcss_qcs404_res_init = { + .init_clock = qcs404_init_clock, + .init_regulator = qcs404_init_regulator, +@@ -1212,6 +1226,7 @@ static const struct wcss_data wcss_qcs40 + + static const struct of_device_id q6v5_wcss_of_match[] = { + { .compatible = "qcom,ipq8074-wcss-pil", .data = &wcss_ipq8074_res_init }, ++ { .compatible = "qcom,ipq6018-wcss-pil", .data = &wcss_ipq6018_res_init }, + { .compatible = "qcom,qcs404-wcss-pil", .data = &wcss_qcs404_res_init }, + { }, + }; diff --git a/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-add-SDHCI-node.patch b/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-add-SDHCI-node.patch new file mode 100644 index 0000000000..329c83a653 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0137-arm64-dts-qcom-ipq6018-add-SDHCI-node.patch @@ -0,0 +1,45 @@ +From e4d7544ce092807e8c5aeb618cec30e2eb9b40c2 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Mon, 24 Apr 2023 15:13:32 +0300 +Subject: [PATCH 3/3] arm64: dts: qcom: ipq6018: add SDHCI node + +IPQ6018 has one SD/eMMC controller, add node for it. + +Signed-off-by: Mantas Pucka +Tested-by: Robert Marko +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -264,6 +264,29 @@ + reg = <0x0 0x01937000 0x0 0x21000>; + }; + ++ sdhc_1: mmc@7804000 { ++ compatible = "qcom,ipq6018-sdhci", "qcom,sdhci-msm-v5"; ++ reg = <0x0 0x07804000 0x0 0x1000>, ++ <0x0 0x07805000 0x0 0x1000>, ++ <0x0 0x07808000 0x0 0x2000>; ++ reg-names = "hc", "cqhci", "ice"; ++ ++ interrupts = , ++ ; ++ interrupt-names = "hc_irq", "pwr_irq"; ++ ++ clocks = <&gcc GCC_SDCC1_AHB_CLK>, ++ <&gcc GCC_SDCC1_APPS_CLK>, ++ <&xo>, ++ <&gcc GCC_SDCC1_ICE_CORE_CLK>; ++ clock-names = "iface", "core", "xo", "ice"; ++ ++ resets = <&gcc GCC_SDCC1_BCR>; ++ supports-cqe; ++ bus-width = <8>; ++ status = "disabled"; ++ }; ++ + blsp_dma: dma-controller@7884000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x0 0x07884000 0x0 0x2b000>; diff --git a/target/linux/qualcommax/patches-6.1/0138-hwspinlock-qcom-Remove-IPQ6018-SOC-specific-compatib.patch b/target/linux/qualcommax/patches-6.1/0138-hwspinlock-qcom-Remove-IPQ6018-SOC-specific-compatib.patch new file mode 100644 index 0000000000..21e60c6327 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0138-hwspinlock-qcom-Remove-IPQ6018-SOC-specific-compatib.patch @@ -0,0 +1,34 @@ +From a120815200adaf3ac28ccf3a1813c78b4be02cc4 Mon Sep 17 00:00:00 2001 +From: Vignesh Viswanathan +Date: Tue, 5 Sep 2023 15:25:35 +0530 +Subject: [PATCH v2 2/2] hwspinlock: qcom: Remove IPQ6018 SOC specific compatible + +IPQ6018 has 32 tcsr_mutex hwlock registers with stride 0x1000. +The compatible string qcom,ipq6018-tcsr-mutex is mapped to +of_msm8226_tcsr_mutex which has 32 locks configured with stride of 0x80 +and doesn't match the HW present in IPQ6018. + +Remove IPQ6018 specific compatible string so that it fallsback to +of_tcsr_mutex data which maps to the correct configuration for IPQ6018. + +Changes in v2: + - Updated commit message + - Added Fixes and stable tags + +Cc: stable@vger.kernel.org +Fixes: 5d4753f741d8 ("hwspinlock: qcom: add support for MMIO on older SoCs") +Signed-off-by: Vignesh Viswanathan +--- + drivers/hwspinlock/qcom_hwspinlock.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/hwspinlock/qcom_hwspinlock.c ++++ b/drivers/hwspinlock/qcom_hwspinlock.c +@@ -115,7 +115,6 @@ static const struct of_device_id qcom_hw + { .compatible = "qcom,sfpb-mutex", .data = &of_sfpb_mutex }, + { .compatible = "qcom,tcsr-mutex", .data = &of_tcsr_mutex }, + { .compatible = "qcom,apq8084-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, +- { .compatible = "qcom,ipq6018-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, + { .compatible = "qcom,msm8226-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, + { .compatible = "qcom,msm8974-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, + { .compatible = "qcom,msm8994-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, diff --git a/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch b/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch new file mode 100644 index 0000000000..0e0c6e87d8 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch @@ -0,0 +1,27 @@ +From d24bc08bfc66f47d6e0a294a080d62893a7696b5 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Thu, 18 Jan 2024 21:30:21 +0800 +Subject: [PATCH] arm64: dts: qcom: ipq6018: add LDOA2 regulator + +Add LDOA2 regulator of MP5496 to support SDCC voltage scaling. + +Suggested-by: Robert Marko +Signed-off-by: Chukun Pan +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -840,6 +840,11 @@ + regulator-max-microvolt = <1062500>; + regulator-always-on; + }; ++ ++ ipq6018_l2: l2 { ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ }; + }; + }; + }; diff --git a/target/linux/qualcommax/patches-6.1/0140-arm64-dts-qcom-ipq6018-add-tsens-node.patch b/target/linux/qualcommax/patches-6.1/0140-arm64-dts-qcom-ipq6018-add-tsens-node.patch new file mode 100644 index 0000000000..f3fa4fe6c8 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0140-arm64-dts-qcom-ipq6018-add-tsens-node.patch @@ -0,0 +1,32 @@ +From 946b1a565a60a04f8e5171a79a463f99485a3531 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Wed, 24 Jan 2024 15:07:24 +0200 +Subject: [PATCH 2/3] arm64: dts: qcom: ipq6018: add tsens node + +IPQ6018 has temperature sensing HW block compatible with IPQ8074. Add +node for it. + +Signed-off-by: Mantas Pucka +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -193,6 +193,16 @@ + clock-names = "core"; + }; + ++ tsens: thermal-sensor@4a9000 { ++ compatible = "qcom,ipq6018-tsens", "qcom,ipq8074-tsens"; ++ reg = <0x0 0x004a9000 0x0 0x1000>, ++ <0x0 0x004a8000 0x0 0x1000>; ++ interrupts = ; ++ interrupt-names = "combined"; ++ #qcom,sensors = <16>; ++ #thermal-sensor-cells = <1>; ++ }; ++ + cryptobam: dma-controller@704000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x0 0x00704000 0x0 0x20000>; diff --git a/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch b/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch new file mode 100644 index 0000000000..a41ecd8b62 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch @@ -0,0 +1,178 @@ +From 92c65f959ec2b8d1ab26efe246b29ed538b45c86 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Wed, 24 Jan 2024 15:10:43 +0200 +Subject: [PATCH 3/3] arm64: dts: qcom: ipq6018: add thermal zones + +Add thermal zones to make use of thermal sensors data. For CPU zone, +add cooling device that uses CPU frequency scaling. + +Signed-off-by: Mantas Pucka +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 121 ++++++++++++++++++++++++++++++++++ + 1 file changed, 121 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + / { + #address-cells = <2>; +@@ -43,6 +44,7 @@ + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; ++ #cooling-cells = <2>; + }; + + CPU1: cpu@1 { +@@ -55,6 +57,7 @@ + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; ++ #cooling-cells = <2>; + }; + + CPU2: cpu@2 { +@@ -67,6 +70,7 @@ + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; ++ #cooling-cells = <2>; + }; + + CPU3: cpu@3 { +@@ -79,6 +83,7 @@ + clock-names = "cpu"; + operating-points-v2 = <&cpu_opp_table>; + cpu-supply = <&ipq6018_s2>; ++ #cooling-cells = <2>; + }; + + L2_0: l2-cache { +@@ -807,6 +812,122 @@ + }; + }; + }; ++ ++ thermal-zones { ++ nss-top-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 4>; ++ ++ trips { ++ nss-top-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ nss-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 5>; ++ ++ trips { ++ nss-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ wcss-phya0-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 7>; ++ ++ trips { ++ wcss-phya0-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ wcss-phya1-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 8>; ++ ++ trips { ++ wcss-phya1-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ cpu-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 13>; ++ ++ trips { ++ cpu-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ ++ cpu_alert: cpu-passive { ++ temperature = <110000>; ++ hysteresis = <1000>; ++ type = "passive"; ++ }; ++ }; ++ ++ cooling-maps { ++ map0 { ++ trip = <&cpu_alert>; ++ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, ++ <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ }; ++ }; ++ }; ++ ++ lpass-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 14>; ++ ++ trips { ++ lpass-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ ++ ddrss-top-thermal { ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&tsens 15>; ++ ++ trips { ++ ddrss-top-critical { ++ temperature = <125000>; ++ hysteresis = <1000>; ++ type = "critical"; ++ }; ++ }; ++ }; ++ }; + + wcss: wcss-smp2p { + compatible = "qcom,smp2p"; diff --git a/target/linux/qualcommax/patches-6.1/0142-arm64-dts-qcom-ipq6018-use-CPUFreq-NVMEM.patch b/target/linux/qualcommax/patches-6.1/0142-arm64-dts-qcom-ipq6018-use-CPUFreq-NVMEM.patch new file mode 100644 index 0000000000..0eb21a4f90 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0142-arm64-dts-qcom-ipq6018-use-CPUFreq-NVMEM.patch @@ -0,0 +1,85 @@ +From 83afcf14edb9217e58837eb119da96d734a4b3b1 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sat, 21 Oct 2023 14:00:07 +0200 +Subject: [PATCH] arm64: dts: qcom: ipq6018: use CPUFreq NVMEM + +IPQ6018 comes in multiple SKU-s and some of them dont support all of the +OPP-s that are current set, so lets utilize CPUFreq NVMEM to allow only +supported OPP-s based on the SoC dynamically. + +As an example, IPQ6018 is generaly rated at 1.8GHz but some silicon only +goes up to 1.5GHz and is marked as such via an eFuse. + +Signed-off-by: Robert Marko +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20231021120048.231239-1-robimarko@gmail.com +Signed-off-by: Bjorn Andersson +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -93,37 +93,49 @@ + }; + + cpu_opp_table: opp-table-cpu { +- compatible = "operating-points-v2"; ++ compatible = "operating-points-v2-kryo-cpu"; ++ nvmem-cells = <&cpu_speed_bin>; + opp-shared; + + opp-864000000 { + opp-hz = /bits/ 64 <864000000>; + opp-microvolt = <725000>; ++ opp-supported-hw = <0xf>; + clock-latency-ns = <200000>; + }; ++ + opp-1056000000 { + opp-hz = /bits/ 64 <1056000000>; + opp-microvolt = <787500>; ++ opp-supported-hw = <0xf>; + clock-latency-ns = <200000>; + }; ++ + opp-1320000000 { + opp-hz = /bits/ 64 <1320000000>; + opp-microvolt = <862500>; ++ opp-supported-hw = <0x3>; + clock-latency-ns = <200000>; + }; ++ + opp-1440000000 { + opp-hz = /bits/ 64 <1440000000>; + opp-microvolt = <925000>; ++ opp-supported-hw = <0x3>; + clock-latency-ns = <200000>; + }; ++ + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <987500>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; ++ + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1062500>; ++ opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + }; +@@ -189,6 +201,11 @@ + reg = <0x0 0x000a4000 0x0 0x2000>; + #address-cells = <1>; + #size-cells = <1>; ++ ++ cpu_speed_bin: cpu-speed-bin@135 { ++ reg = <0x135 0x1>; ++ bits = <7 1>; ++ }; + }; + + prng: qrng@e1000 { diff --git a/target/linux/qualcommax/patches-6.1/0903-psci-dont-advertise-OSI-support-for-IPQ6018.patch b/target/linux/qualcommax/patches-6.1/0903-psci-dont-advertise-OSI-support-for-IPQ6018.patch new file mode 100644 index 0000000000..5fcb90098f --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0903-psci-dont-advertise-OSI-support-for-IPQ6018.patch @@ -0,0 +1,40 @@ +From 563db68137475d011b355bfe674d1b7a24778091 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Sat, 8 Oct 2022 22:26:31 +0200 +Subject: [PATCH] psci: dont advertise OSI support for IPQ6018 + +Some older IPQ60xx SoC series boards ship with TrustZone/QSEE firmware +older than TZ.WNS.5.1-00084 which will advertise OSI[1] but are broken +and trying to use OSI will cause the board to hang until WDT kicks in. + +So workaround it by checking for SoC compatible and returning false so +OSI is not used. + +[1] https://www.spinics.net/lists/linux-arm-msm/msg79916.html + +Signed-off-by: Robert Marko +--- + drivers/firmware/psci/psci.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/firmware/psci/psci.c ++++ b/drivers/firmware/psci/psci.c +@@ -87,6 +87,18 @@ static inline bool psci_has_ext_power_st + + bool psci_has_osi_support(void) + { ++ /* ++ * Some older IPQ60xx SoC series boards ship with ++ * TrustZone/QSEE firmware older than TZ.WNS.5.1-00084 ++ * which will advertise OSI but is broken and trying ++ * to use OSI will cause the board to hang until WDT ++ * kicks in. ++ * So workaround it by checking for SoC compatible ++ * and returning false so OSI is not used. ++ */ ++ if (of_machine_is_compatible("qcom,ipq6018")) ++ return false; ++ + return psci_cpu_suspend_feature & PSCI_1_0_OS_INITIATED; + } + diff --git a/target/linux/qualcommax/patches-6.1/0904-clk-qcom-ipq6018-workaround-networking-clock-parenti.patch b/target/linux/qualcommax/patches-6.1/0904-clk-qcom-ipq6018-workaround-networking-clock-parenti.patch new file mode 100644 index 0000000000..175d475849 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0904-clk-qcom-ipq6018-workaround-networking-clock-parenti.patch @@ -0,0 +1,109 @@ +From 0c5b5243ad55ae744e790ba90c5ad37a93bd1377 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 11 Oct 2022 23:38:45 +0200 +Subject: [PATCH] clk: qcom: ipq6018: workaround networking clock parenting + +Currently, networking clocks are only looked up by fw_name however, +these are registered and setup by SSDK and are not available to the +GCC driver at all, so work around that by providing a global name +fallback. + +While we are here, provide global fallback for bias_pll_cc_clk and +bias_pll_nss_noc_clk as well as these are fixed clocks also not available +to the driver. + +Signed-off-by: Robert Marko +--- + drivers/clk/qcom/gcc-ipq6018.c | 39 +++++++++++++++++----------------- + 1 file changed, 19 insertions(+), 20 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -361,7 +361,7 @@ static const struct freq_tbl ftbl_nss_pp + + static const struct clk_parent_data gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = { + { .fw_name = "xo" }, +- { .fw_name = "bias_pll_cc_clk" }, ++ { .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll4.clkr.hw }, + { .hw = &nss_crypto_pll.clkr.hw }, +@@ -527,12 +527,12 @@ static const struct freq_tbl ftbl_nss_po + static const struct clk_parent_data + gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = { + { .fw_name = "xo" }, +- { .fw_name = "uniphy0_gcc_rx_clk" }, +- { .fw_name = "uniphy0_gcc_tx_clk" }, +- { .fw_name = "uniphy1_gcc_rx_clk" }, +- { .fw_name = "uniphy1_gcc_tx_clk" }, ++ { .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" }, ++ { .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" }, ++ { .fw_name = "uniphy1_gcc_rx_clk", .name = "uniphy1_gcc_rx_clk" }, ++ { .fw_name = "uniphy1_gcc_tx_clk", .name = "uniphy1_gcc_tx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, +- { .fw_name = "bias_pll_cc_clk" }, ++ { .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" }, + }; + + static const struct parent_map +@@ -574,12 +574,12 @@ static const struct freq_tbl ftbl_nss_po + static const struct clk_parent_data + gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = { + { .fw_name = "xo" }, +- { .fw_name = "uniphy0_gcc_tx_clk" }, +- { .fw_name = "uniphy0_gcc_rx_clk" }, +- { .fw_name = "uniphy1_gcc_tx_clk" }, +- { .fw_name = "uniphy1_gcc_rx_clk" }, ++ { .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" }, ++ { .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" }, ++ { .fw_name = "uniphy1_gcc_tx_clk", .name = "uniphy1_gcc_tx_clk" }, ++ { .fw_name = "uniphy1_gcc_rx_clk", .name = "uniphy1_gcc_rx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, +- { .fw_name = "bias_pll_cc_clk" }, ++ { .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" }, + }; + + static const struct parent_map +@@ -715,10 +715,10 @@ static const struct freq_tbl ftbl_nss_po + + static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_ubi32_bias[] = { + { .fw_name = "xo" }, +- { .fw_name = "uniphy0_gcc_rx_clk" }, +- { .fw_name = "uniphy0_gcc_tx_clk" }, ++ { .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" }, ++ { .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, +- { .fw_name = "bias_pll_cc_clk" }, ++ { .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" }, + }; + + static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = { +@@ -751,10 +751,10 @@ static const struct freq_tbl ftbl_nss_po + + static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_ubi32_bias[] = { + { .fw_name = "xo" }, +- { .fw_name = "uniphy0_gcc_tx_clk" }, +- { .fw_name = "uniphy0_gcc_rx_clk" }, ++ { .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" }, ++ { .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" }, + { .hw = &ubi32_pll.clkr.hw }, +- { .fw_name = "bias_pll_cc_clk" }, ++ { .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" }, + }; + + static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = { +@@ -1898,12 +1898,11 @@ static const struct freq_tbl ftbl_ubi32_ + { } + }; + +-static const struct clk_parent_data +- gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk[] = { ++static const struct clk_parent_data gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, +- { .fw_name = "bias_pll_nss_noc_clk" }, ++ { .fw_name = "bias_pll_nss_noc_clk", .name = "bias_pll_nss_noc_clk" }, + }; + + static const struct parent_map gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk_map[] = { diff --git a/target/linux/qualcommax/patches-6.1/0905-remoteproc-q6v5_wcss-change-ssr-name-for-ipq6018-wif.patch b/target/linux/qualcommax/patches-6.1/0905-remoteproc-q6v5_wcss-change-ssr-name-for-ipq6018-wif.patch new file mode 100644 index 0000000000..58bea43892 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0905-remoteproc-q6v5_wcss-change-ssr-name-for-ipq6018-wif.patch @@ -0,0 +1,40 @@ +From 505f9c8653fc218ca47a153ec58ebc16bef5502f Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 16 Jan 2024 10:42:40 +0200 +Subject: [PATCH 16/19] remoteproc: q6v5_wcss: change ssr name for ipq6018 wifi + subsystem + +On IPQ6018 this string ends up being sent to RPM when remoteproc stops +(on crash or rmmod ath11k). "q6wcss" is not a valid name (not found by +`strings` in rpm.mbn), so this causes RPM do 'something' (presumably crash) +causing a system reboot followed by hang in XBL, with no WDT running. +Let's change ssr_name to a more sensible 'wcnss', that does not cause such +issues. + +Signed-off-by: Mantas Pucka +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -1143,8 +1143,8 @@ static int q6v5_wcss_probe(struct platfo + if (ret) + goto free_rproc; + +- qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss"); +- qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss"); ++ qcom_add_glink_subdev(rproc, &wcss->glink_subdev, desc->ssr_name); ++ qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, desc->ssr_name); + + if (desc->ssctl_id) + wcss->sysmon = qcom_add_sysmon_subdev(rproc, +@@ -1201,7 +1201,7 @@ static const struct wcss_data wcss_ipq60 + .aon_reset_required = true, + .wcss_q6_reset_required = true, + .bcr_reset_required = false, +- .ssr_name = "q6wcss", ++ .ssr_name = "wcnss", + .ops = &q6v5_wcss_ipq8074_ops, + .requires_force_stop = true, + .need_mem_protection = true, diff --git a/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch b/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch new file mode 100644 index 0000000000..96b418f464 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch @@ -0,0 +1,120 @@ +From 153c74fc80b9f33ed1a50d7790bf6979fdceb370 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 16 Jan 2024 11:41:06 +0200 +Subject: [PATCH 19/19] arm64: dts: qcom: ipq6018: add wifi node + +IPQ6018 has a AHB based Q6v5 802.11ax radios that are supported +by the ath11k. + +Add the required DT node to enable the built-in radios. + +Signed-off-by: Mantas Pucka +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 96 +++++++++++++++++++++++++++++++++++ + 1 file changed, 96 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -637,6 +637,102 @@ + }; + }; + ++ wifi: wifi@c000000 { ++ compatible = "qcom,ipq6018-wifi"; ++ reg = <0x0 0xc000000 0x0 0x1000000>; ++ qcom,rproc = <&q6v5_wcss>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = "misc-pulse1", "misc-latch", "sw-exception", ++ "watchdog", "ce0", "ce1", "ce2", "ce3", "ce4", ++ "ce5", "ce6", "ce7", "ce8", "ce9", "ce10", ++ "ce11", "host2wbm-desc-feed", ++ "host2reo-re-injection", "host2reo-command", ++ "host2rxdma-monitor-ring3", ++ "host2rxdma-monitor-ring2", ++ "host2rxdma-monitor-ring1", ++ "reo2ost-exception", "wbm2host-rx-release", ++ "reo2host-status", ++ "reo2host-destination-ring4", ++ "reo2host-destination-ring3", ++ "reo2host-destination-ring2", ++ "reo2host-destination-ring1", ++ "rxdma2host-monitor-destination-mac3", ++ "rxdma2host-monitor-destination-mac2", ++ "rxdma2host-monitor-destination-mac1", ++ "ppdu-end-interrupts-mac3", ++ "ppdu-end-interrupts-mac2", ++ "ppdu-end-interrupts-mac1", ++ "rxdma2host-monitor-status-ring-mac3", ++ "rxdma2host-monitor-status-ring-mac2", ++ "rxdma2host-monitor-status-ring-mac1", ++ "host2rxdma-host-buf-ring-mac3", ++ "host2rxdma-host-buf-ring-mac2", ++ "host2rxdma-host-buf-ring-mac1", ++ "rxdma2host-destination-ring-mac3", ++ "rxdma2host-destination-ring-mac2", ++ "rxdma2host-destination-ring-mac1", ++ "host2tcl-input-ring4", ++ "host2tcl-input-ring3", ++ "host2tcl-input-ring2", ++ "host2tcl-input-ring1", ++ "wbm2host-tx-completions-ring3", ++ "wbm2host-tx-completions-ring2", ++ "wbm2host-tx-completions-ring1", ++ "tcl2host-status-ring"; ++ status = "disabled"; ++ }; ++ + q6v5_wcss: remoteproc@cd00000 { + compatible = "qcom,ipq6018-wcss-pil"; + reg = <0x0 0x0cd00000 0x0 0x4040>, diff --git a/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch b/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch new file mode 100644 index 0000000000..18a597e07d --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch @@ -0,0 +1,53 @@ +From d93936f175bd914067df8f63f5fbe6e3b77bb4d2 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 23 May 2023 14:46:28 +0300 +Subject: [PATCH 11/19] soc: qcom: fix smp2p ack on ipq6018 + +IPQ6018 seem to need different ack mechanism for smp2p messaging. This +fixes q6v5_wcss remoteproc firmware reloading. Without this first load +is OK, but subsequent loads would hang and fail to complete. + +Signed-off-by: Mantas Pucka +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 1 + + drivers/soc/qcom/smp2p.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -1056,6 +1056,7 @@ + + wcss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; ++ qcom,smp2p-feature-ssr-ack; + #qcom,smem-state-cells = <1>; + }; + +--- a/drivers/soc/qcom/smp2p.c ++++ b/drivers/soc/qcom/smp2p.c +@@ -158,6 +158,8 @@ struct qcom_smp2p { + + struct list_head inbound; + struct list_head outbound; ++ ++ bool need_ssr_ack; + }; + + static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) +@@ -306,7 +308,7 @@ static irqreturn_t qcom_smp2p_intr(int i + ack_restart = qcom_smp2p_check_ssr(smp2p); + qcom_smp2p_notify_in(smp2p); + +- if (ack_restart) ++ if (ack_restart || smp2p->need_ssr_ack) + qcom_smp2p_do_ssr_ack(smp2p); + } + +@@ -427,6 +429,7 @@ static int qcom_smp2p_outbound_entry(str + + /* Make the logical entry reference the physical value */ + entry->value = &out->entries[out->valid_entries].value; ++ smp2p->need_ssr_ack = of_property_read_bool(node, "qcom,smp2p-feature-ssr-ack"); + + out->valid_entries++; + diff --git a/target/linux/qualcommax/patches-6.1/0908-remoteproc-qcom_q6v5_wcss-add-optional-qdss_at-clock.patch b/target/linux/qualcommax/patches-6.1/0908-remoteproc-qcom_q6v5_wcss-add-optional-qdss_at-clock.patch new file mode 100644 index 0000000000..cfc9adda04 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0908-remoteproc-qcom_q6v5_wcss-add-optional-qdss_at-clock.patch @@ -0,0 +1,55 @@ +From 87dbcc69a7e3fe6ccddf4fe9bdbf51330f5e4a77 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 23 Jan 2024 11:04:04 +0200 +Subject: [PATCH] remoteproc: qcom_q6v5_wcss: add optional qdss_at clock + +IPQ6018 needs QDSS_AT clock enabled when loading wifi. Optionally enable it +when provided by DT. + +Signed-off-by: Mantas Pucka +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -120,6 +120,7 @@ struct q6v5_wcss { + struct clk *qdsp6ss_core_gfmux; + struct clk *lcc_bcr_sleep; + struct clk *prng_clk; ++ struct clk *qdss_clk; + struct regulator *cx_supply; + struct qcom_sysmon *sysmon; + +@@ -259,6 +260,9 @@ static int q6v5_wcss_start(struct rproc + return ret; + } + ++ if (wcss->qdss_clk) ++ clk_prepare_enable(wcss->qdss_clk); ++ + qcom_q6v5_prepare(&wcss->q6v5); + + if (wcss->need_mem_protection) { +@@ -772,6 +776,8 @@ static int q6v5_wcss_stop(struct rproc * + } + + pas_done: ++ if (wcss->qdss_clk) ++ clk_disable_unprepare(wcss->qdss_clk); + clk_disable_unprepare(wcss->prng_clk); + qcom_q6v5_unprepare(&wcss->q6v5); + +@@ -981,6 +987,12 @@ static int ipq_init_clock(struct q6v5_wc + dev_err(wcss->dev, "Failed to get prng clock\n"); + return ret; + } ++ ++ wcss->qdss_clk = devm_clk_get(wcss->dev, "qdss"); ++ if (IS_ERR(wcss->qdss_clk)) { ++ wcss->qdss_clk = NULL; ++ } ++ + return 0; + } + diff --git a/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch b/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch new file mode 100644 index 0000000000..eb89ded7f2 --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch @@ -0,0 +1,26 @@ +From 71f30e25d21ae4981ecef6653a4ba7dfeb80db7b Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 23 Jan 2024 11:04:57 +0200 +Subject: [PATCH] arm64: dts: qcom: ipq6018: assign QDSS_AT clock to wifi remoteproc + +IPQ6018 needs to enable QDSS_AT clock when loading wifi firmware, +add it to wifi remoteproc clock list. + +Signed-off-by: Mantas Pucka +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 15 ++++++++------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -758,8 +758,8 @@ + "wcss_reset", + "wcss_q6_reset"; + +- clocks = <&gcc GCC_PRNG_AHB_CLK>; +- clock-names = "prng"; ++ clocks = <&gcc GCC_PRNG_AHB_CLK>, <&gcc GCC_QDSS_AT_CLK>; ++ clock-names = "prng", "qdss" ; + + qcom,halt-regs = <&tcsr 0x18000 0x1b000 0xe000>; + diff --git a/target/linux/qualcommax/patches-6.1/0910-arm64-dts-qcom-ipq6018-change-voltage-to-perf-levels.patch b/target/linux/qualcommax/patches-6.1/0910-arm64-dts-qcom-ipq6018-change-voltage-to-perf-levels.patch new file mode 100644 index 0000000000..8d2aff1dca --- /dev/null +++ b/target/linux/qualcommax/patches-6.1/0910-arm64-dts-qcom-ipq6018-change-voltage-to-perf-levels.patch @@ -0,0 +1,65 @@ +From c67a1814bb1d0df290cf1e3f9c966f04aa41b9b9 Mon Sep 17 00:00:00 2001 +From: Mantas Pucka +Date: Tue, 30 Jan 2024 12:43:56 +0200 +Subject: [PATCH] arm64: dts: qcom: ipq6018: change voltage to perf levels for + CPR4 driver + +Current CPR4 driver requires opp-microvolt to be an abstract +performance level instead of actual voltage level. + +Signed-off-by: Mantas Pucka +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -99,42 +99,42 @@ + + opp-864000000 { + opp-hz = /bits/ 64 <864000000>; +- opp-microvolt = <725000>; ++ opp-microvolt = <1>; + opp-supported-hw = <0xf>; + clock-latency-ns = <200000>; + }; + + opp-1056000000 { + opp-hz = /bits/ 64 <1056000000>; +- opp-microvolt = <787500>; ++ opp-microvolt = <2>; + opp-supported-hw = <0xf>; + clock-latency-ns = <200000>; + }; + + opp-1320000000 { + opp-hz = /bits/ 64 <1320000000>; +- opp-microvolt = <862500>; ++ opp-microvolt = <3>; + opp-supported-hw = <0x3>; + clock-latency-ns = <200000>; + }; + + opp-1440000000 { + opp-hz = /bits/ 64 <1440000000>; +- opp-microvolt = <925000>; ++ opp-microvolt = <4>; + opp-supported-hw = <0x3>; + clock-latency-ns = <200000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; +- opp-microvolt = <987500>; ++ opp-microvolt = <5>; + opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; +- opp-microvolt = <1062500>; ++ opp-microvolt = <6>; + opp-supported-hw = <0x1>; + clock-latency-ns = <200000>; + }; From fe98cc1baf85c0a05bc8d8b8743cc4ff85092892 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Sat, 14 Oct 2023 20:15:22 +0200 Subject: [PATCH 21/50] qualcommax: move generic image recipes to target Makefile These recipes are generic and will be used for other subtargets, so lets move them to the target Makefile so they can reused. Signed-off-by: Robert Marko --- target/linux/qualcommax/image/Makefile | 25 ++++++++++++++++++++++++ target/linux/qualcommax/image/ipq807x.mk | 25 ------------------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/target/linux/qualcommax/image/Makefile b/target/linux/qualcommax/image/Makefile index f59ad0c15f..6841693194 100644 --- a/target/linux/qualcommax/image/Makefile +++ b/target/linux/qualcommax/image/Makefile @@ -12,6 +12,31 @@ define Device/Default IMAGE/sysupgrade.bin/squashfs := endef +define Device/FitImage + KERNEL_SUFFIX := -uImage.itb + KERNEL = kernel-bin | libdeflate-gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/FitImageLzma + KERNEL_SUFFIX := -uImage.itb + KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb + KERNEL_NAME := Image +endef + +define Device/EmmcImage + IMAGES += factory.bin sysupgrade.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to 64k | sysupgrade-tar rootfs=$$$$@ | append-metadata +endef + +define Device/UbiFit + KERNEL_IN_UBI := 1 + IMAGES := factory.ubi sysupgrade.bin + IMAGE/factory.ubi := append-ubi + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef + include $(SUBTARGET).mk $(eval $(call BuildImage)) diff --git a/target/linux/qualcommax/image/ipq807x.mk b/target/linux/qualcommax/image/ipq807x.mk index f5f0e26140..3a30b161b4 100644 --- a/target/linux/qualcommax/image/ipq807x.mk +++ b/target/linux/qualcommax/image/ipq807x.mk @@ -1,28 +1,3 @@ -define Device/FitImage - KERNEL_SUFFIX := -uImage.itb - KERNEL = kernel-bin | libdeflate-gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb - KERNEL_NAME := Image -endef - -define Device/FitImageLzma - KERNEL_SUFFIX := -uImage.itb - KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb - KERNEL_NAME := Image -endef - -define Device/EmmcImage - IMAGES += factory.bin sysupgrade.bin - IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k - IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to 64k | sysupgrade-tar rootfs=$$$$@ | append-metadata -endef - -define Device/UbiFit - KERNEL_IN_UBI := 1 - IMAGES := factory.ubi sysupgrade.bin - IMAGE/factory.ubi := append-ubi - IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata -endef - define Build/wax6xx-netgear-tar mkdir $@.tmp mv $@ $@.tmp/nand-ipq807x-apps.img From f0e732f4880f63a31137eb805b30a71397145ccf Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 9 Feb 2024 14:33:43 +0100 Subject: [PATCH 22/50] qualcommax: refresh kernel patches Refresh kernel patches changed from the just introduced ipq60xx new subtarget. Patch automatically refreshed with make target/linux/refresh. Signed-off-by: Christian Marangi --- .../0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch | 2 +- ...5-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch | 2 +- .../0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch | 2 +- .../0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch | 2 +- .../patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch | 2 +- .../patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch | 2 +- ...9-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch b/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch index 5b467ee029..552f2568b5 100644 --- a/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch +++ b/target/linux/qualcommax/patches-6.1/0037-v6.5-arm64-dts-qcom-ipq6018-add-QFPROM-node.patch @@ -31,4 +31,4 @@ Link: https://lore.kernel.org/r/20230526125305.19626-4-quic_kathirav@quicinc.com + prng: qrng@e1000 { compatible = "qcom,prng-ee"; - reg = <0x0 0xe3000 0x0 0x1000>; + reg = <0x0 0x000e3000 0x0 0x1000>; diff --git a/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch b/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch index eed2522198..bfa04cd02d 100644 --- a/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch +++ b/target/linux/qualcommax/patches-6.1/0135-arm64-dts-qcom-ipq6018-include-the-GPLL0-as-clock-pr.patch @@ -19,7 +19,7 @@ Reviewed-by: Konrad Dybcio --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -503,8 +503,8 @@ +@@ -504,8 +504,8 @@ compatible = "qcom,ipq6018-apcs-apps-global"; reg = <0x0 0x0b111000 0x0 0x1000>; #clock-cells = <1>; diff --git a/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch b/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch index 0e0c6e87d8..6549211689 100644 --- a/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch +++ b/target/linux/qualcommax/patches-6.1/0139-arm64-dts-qcom-ipq6018-add-LDOA2-regulator.patch @@ -13,7 +13,7 @@ Signed-off-by: Chukun Pan --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -840,6 +840,11 @@ +@@ -841,6 +841,11 @@ regulator-max-microvolt = <1062500>; regulator-always-on; }; diff --git a/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch b/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch index a41ecd8b62..9b4ab43b62 100644 --- a/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch +++ b/target/linux/qualcommax/patches-6.1/0141-arm64-dts-qcom-ipq6018-add-thermal-zones.patch @@ -53,7 +53,7 @@ Signed-off-by: Mantas Pucka }; L2_0: l2-cache { -@@ -807,6 +812,122 @@ +@@ -808,6 +813,122 @@ }; }; }; diff --git a/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch b/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch index 96b418f464..8c1b7cc6c5 100644 --- a/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch +++ b/target/linux/qualcommax/patches-6.1/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch @@ -15,7 +15,7 @@ Signed-off-by: Mantas Pucka --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -637,6 +637,102 @@ +@@ -638,6 +638,102 @@ }; }; diff --git a/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch b/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch index 18a597e07d..afb2361120 100644 --- a/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch +++ b/target/linux/qualcommax/patches-6.1/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch @@ -15,7 +15,7 @@ Signed-off-by: Mantas Pucka --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -1056,6 +1056,7 @@ +@@ -1057,6 +1057,7 @@ wcss_smp2p_out: master-kernel { qcom,entry-name = "master-kernel"; diff --git a/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch b/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch index eb89ded7f2..5261f3fd96 100644 --- a/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch +++ b/target/linux/qualcommax/patches-6.1/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch @@ -13,7 +13,7 @@ Signed-off-by: Mantas Pucka --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi -@@ -758,8 +758,8 @@ +@@ -759,8 +759,8 @@ "wcss_reset", "wcss_q6_reset"; From 2ef5714277ce32d0dc7d59e59f20591004f070c4 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Wed, 7 Feb 2024 21:30:52 +0100 Subject: [PATCH 23/50] toolchain: glibc: Update glibc 2.37 to recent HEAD 512e30fd56 Revert "elf: Remove unused l_text_end field from struct link_map" 55d3dfadf8 Revert "elf: Always call destructors in reverse constructor order (bug 30785)" 8e20aedfd7 Revert "elf: Move l_init_called_next to old place of l_text_end in link map" 5014fb12f4 elf: Fix wrong break removal from 8ee878592c 874d418697 elf: Fix TLS modid reuse generation assignment (BZ 29039) 8bd00f5b6d x86-64: Fix the dtv field load for x32 [BZ #31184] d052665f35 x86-64: Fix the tcb field load for x32 [BZ #31185] 0ca9ba3a9e NEWS: Mention bug fixes for 29039/30745/30843 9b90e763db getaddrinfo: translate ENOMEM to EAI_MEMORY (bug 31163) bd9f194c34 libio: Check remaining buffer size in _IO_wdo_write (bug 31183) 8b8a3f0aaf sunrpc: Fix netname build with older gcc 97a4292aa4 syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6246) 67062eccd9 syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) 2b58cba076 syslog: Fix integer overflow in __vsyslog_internal (CVE-2023-6780) 1d8bb622df i386: Use pthread_barrier for synchronization on tst-bz21269 32450f6e8d sysdeps: tst-bz21269: fix test parameter f7e97cea20 sysdeps: tst-bz21269: handle ENOSYS & skip appropriately d97929eadc sysdeps: tst-bz21269: fix -Wreturn-type 5bbe7e0da5 x86_64: Optimize ffsll function code size. 98ec3e004e sparc: Fix broken memset for sparc32 [BZ #31068] 2ce7abef67 sparc64: Remove unwind information from signal return stubs [BZ#31244] 18da90677c sparc: Fix sparc64 memmove length comparison (BZ 31266) 8b849f70b3 sparc: Remove unwind information from signal return stubs [BZ #31244] eee7525d35 arm: Remove wrong ldr from _dl_start_user (BZ 31339) Signed-off-by: Hauke Mehrtens --- toolchain/glibc/common.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolchain/glibc/common.mk b/toolchain/glibc/common.mk index 6b237f5478..65e9e0c324 100644 --- a/toolchain/glibc/common.mk +++ b/toolchain/glibc/common.mk @@ -12,8 +12,8 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=b4e23c75aea756b4bddc4abcf27a1c6dca8b6bd3 -PKG_MIRROR_HASH:=4d5b3de6ec7b47427700f74fdb529e32083b54a512f6ca86ec824a61092ecdd4 +PKG_SOURCE_VERSION:=eee7525d35ec16bbe81435e41079ab72519d825c +PKG_MIRROR_HASH:=fad5a67d9622b75bce5e3e8c91b07a6df0bf8b21cb001a6d06019a6ce4cff31f PKG_SOURCE_URL:=https://sourceware.org/git/glibc.git PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz PKG_CPE_ID:=cpe:/a:gnu:glibc From 0dcbe4e93171dfc87f395cd148e420d8fc023ee6 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Fri, 26 May 2023 18:50:15 +0200 Subject: [PATCH 24/50] ramips: 6.1: copy config and patches Copy config and patches from 5.15. This simplifies reviewing process. Signed-off-by: Nick Hainke --- target/linux/ramips/mt7620/config-6.1 | 201 + target/linux/ramips/mt7621/config-6.1 | 297 ++ target/linux/ramips/mt76x8/config-6.1 | 200 + ...t-add-dt-binding-header-for-Mediatek.patch | 60 + ...ts-align-resets-with-binding-documen.patch | 114 + ...k-mediatek-mt7621-sysc-add-reset-cel.patch | 52 + ...system-controller-node-a-reset-provi.patch | 148 + ...21-avoid-to-init-common-ralink-reset.patch | 43 + ...-fix-mt7621_gate_is_enabled-function.patch | 77 + ...ck-add-mtmips-SoCs-system-controller.patch | 86 + ...lock-and-reset-driver-for-MTMIPS-SoC.patch | 1221 ++++++ ...ink-rt288x-remove-clock-related-code.patch | 81 + ...ink-rt305x-remove-clock-related-code.patch | 145 + ...ink-rt3883-remove-clock-related-code.patch | 85 + ...ink-mt7620-remove-clock-related-code.patch | 327 ++ ...ips-ralink-remove-reset-related-code.patch | 121 + ...nk-get-cpu-rate-from-new-driver-code.patch | 102 + ...add-Mediatek-MTMIPS-Clock-maintainer.patch | 28 + ...oduce-commonly-used-remap-node-funct.patch | 189 + ...s-Fix-uninitialized-use-of-ret-in-mt.patch | 56 + ...h-all-supported-system-controller-co.patch | 40 + ...wdt-avoid-static-global-declarations.patch | 213 ++ ...wdt-avoid-ralink-architecture-depend.patch | 104 + ...do-not-print-NFTS-register-value-as-.patch | 32 + ...use-dev_info-to-log-PCIe-device-dete.patch | 39 + ...ediaTek-MT7621-PCIe-host-controller-.patch | 1418 +++++++ ...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 + ...-mt7621-Add-sentinel-to-quirks-table.patch | 38 + ...t7621-Delay-phy-ports-initialization.patch | 52 + ...1-dma-handle-error-from-device_reset.patch | 31 + ...-dev_info-to-log-PCIe-card-detection.patch | 31 + .../patches-6.1/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-6.1/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 + ...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-6.1/805-pinctrl-AW9523.patch | 72 + ...upport-requesting-different-function.patch | 45 + .../810-uvc-add-iPassion-iP2970-support.patch | 244 ++ ...-DT-Add-documentation-for-spi-rt2880.patch | 44 + ...SPI-ralink-add-Ralink-SoC-spi-driver.patch | 579 +++ .../825-i2c-MIPS-adds-ralink-I2C-driver.patch | 512 +++ ...IPS-ralink-add-sdhci-for-mt7620a-SoC.patch | 43 + .../835-asoc-add-mt7620-support.patch | 1033 ++++++ ...erial-add-ugly-custom-baud-rate-hack.patch | 22 + .../845-pwm-add-mediatek-support.patch | 219 ++ .../850-awake-rt305x-dwc2-controller.patch | 15 + .../patches-6.1/855-linkit_bootstrap.patch | 97 + .../860-ramips-add-eip93-driver.patch | 3276 +++++++++++++++++ target/linux/ramips/rt288x/config-6.1 | 187 + target/linux/ramips/rt305x/config-6.1 | 182 + target/linux/ramips/rt3883/config-6.1 | 182 + 71 files changed, 14258 insertions(+) create mode 100644 target/linux/ramips/mt7620/config-6.1 create mode 100644 target/linux/ramips/mt7621/config-6.1 create mode 100644 target/linux/ramips/mt76x8/config-6.1 create mode 100644 target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch create mode 100644 target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch create mode 100644 target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch create mode 100644 target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch create mode 100644 target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch create mode 100644 target/linux/ramips/patches-6.1/003-v6.3-clk-ralink-fix-mt7621_gate_is_enabled-function.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-01-dt-bindings-clock-add-mtmips-SoCs-system-controller.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-02-clk-ralink-add-clock-and-reset-driver-for-MTMIPS-SoC.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-03-mips-ralink-rt288x-remove-clock-related-code.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-04-mips-ralink-rt305x-remove-clock-related-code.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-05-mips-ralink-rt3883-remove-clock-related-code.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-06-mips-ralink-mt7620-remove-clock-related-code.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-08-mips-ralink-get-cpu-rate-from-new-driver-code.patch create mode 100644 target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch create mode 100644 target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch create mode 100644 target/linux/ramips/patches-6.1/007-v6.5-clk-ralink-mtmips-Fix-uninitialized-use-of-ret-in-mt.patch create mode 100644 target/linux/ramips/patches-6.1/008-v6.5-mips-ralink-match-all-supported-system-controller-co.patch create mode 100644 target/linux/ramips/patches-6.1/009-v6.3-01-watchdog-mt7621-wdt-avoid-static-global-declarations.patch create mode 100644 target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch create mode 100644 target/linux/ramips/patches-6.1/010-v6.5-01-mips-pci-mt7620-do-not-print-NFTS-register-value-as-.patch create mode 100644 target/linux/ramips/patches-6.1/010-v6.5-02-mips-pci-mt7620-use-dev_info-to-log-PCIe-device-dete.patch create mode 100644 target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch create mode 100644 target/linux/ramips/patches-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch create mode 100644 target/linux/ramips/patches-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch create mode 100644 target/linux/ramips/patches-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch create mode 100644 target/linux/ramips/patches-6.1/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch create mode 100644 target/linux/ramips/patches-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch create mode 100644 target/linux/ramips/patches-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch create mode 100644 target/linux/ramips/patches-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch create mode 100644 target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch create mode 100644 target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch create mode 100644 target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch create mode 100644 target/linux/ramips/patches-6.1/200-add-ralink-eth.patch create mode 100644 target/linux/ramips/patches-6.1/300-mt7620-export-chip-version-and-pkg.patch create mode 100644 target/linux/ramips/patches-6.1/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch create mode 100644 target/linux/ramips/patches-6.1/312-MIPS-ralink-add-cpu-frequency-scaling.patch create mode 100644 target/linux/ramips/patches-6.1/314-MIPS-add-bootargs-override-property.patch create mode 100644 target/linux/ramips/patches-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch create mode 100644 target/linux/ramips/patches-6.1/316-arch-mips-do-not-select-illegal-access-driver-by-def.patch create mode 100644 target/linux/ramips/patches-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch create mode 100644 target/linux/ramips/patches-6.1/324-mt7621-perfctr-fix.patch create mode 100644 target/linux/ramips/patches-6.1/400-mtd-cfi-cmdset-0002-force-word-write.patch create mode 100644 target/linux/ramips/patches-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch create mode 100644 target/linux/ramips/patches-6.1/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch create mode 100644 target/linux/ramips/patches-6.1/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch create mode 100644 target/linux/ramips/patches-6.1/700-net-ethernet-mediatek-support-net-labels.patch create mode 100644 target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch create mode 100644 target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch create mode 100644 target/linux/ramips/patches-6.1/801-DT-Add-documentation-for-gpio-ralink.patch create mode 100644 target/linux/ramips/patches-6.1/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch create mode 100644 target/linux/ramips/patches-6.1/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch create mode 100644 target/linux/ramips/patches-6.1/805-pinctrl-AW9523.patch create mode 100644 target/linux/ramips/patches-6.1/808-pinctrl-mtmips-support-requesting-different-function.patch create mode 100644 target/linux/ramips/patches-6.1/810-uvc-add-iPassion-iP2970-support.patch create mode 100644 target/linux/ramips/patches-6.1/820-DT-Add-documentation-for-spi-rt2880.patch create mode 100644 target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch create mode 100644 target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch create mode 100644 target/linux/ramips/patches-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch create mode 100644 target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch create mode 100644 target/linux/ramips/patches-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch create mode 100644 target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch create mode 100644 target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch create mode 100644 target/linux/ramips/patches-6.1/855-linkit_bootstrap.patch create mode 100644 target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch create mode 100644 target/linux/ramips/rt288x/config-6.1 create mode 100644 target/linux/ramips/rt305x/config-6.1 create mode 100644 target/linux/ramips/rt3883/config-6.1 diff --git a/target/linux/ramips/mt7620/config-6.1 b/target/linux/ramips/mt7620/config-6.1 new file mode 100644 index 0000000000..641b93e582 --- /dev/null +++ b/target/linux/ramips/mt7620/config-6.1 @@ -0,0 +1,201 @@ +CONFIG_AR8216_PHY=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_SUSPEND_POSSIBLE=y +CONFIG_BLK_MQ_PCI=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_SYSTICK_QUIRK=y +CONFIG_CLKEVT_RT3352=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLK_MTMIPS=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_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_LITTLE_ENDIAN=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_VI=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_RNG2=y +CONFIG_CSRC_R4K=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_DTB_MT7620A_EVAL is not set +# CONFIG_DTB_OMEGA2P is not set +CONFIG_DTB_RT_NONE=y +# CONFIG_DTB_VOCORE2 is not set +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_ETHERNET_PACKET_MANGLE=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_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_GPIO_CDEV=y +# CONFIG_GPIO_MT7621 is not set +CONFIG_GPIO_RALINK=y +CONFIG_GPIO_WATCHDOG=y +# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HZ_PERIODIC=y +CONFIG_ICPLUS_PHY=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_INTC=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_MARVELL_PHY=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_EBPF_JIT=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_LD_CAN_LINK_VDSO=y +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MIPS_SPRAM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MT7621_WDT is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y +CONFIG_MTD_SPLIT_JIMAGE_FW=y +CONFIG_MTD_SPLIT_SEAMA_FW=y +CONFIG_MTD_SPLIT_TPLINK_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_VIRT_CONCAT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_RALINK_GSW_MT7620=y +CONFIG_NET_RALINK_MDIO=y +CONFIG_NET_RALINK_MDIO_MT7620=y +CONFIG_NET_RALINK_MT7620=y +# CONFIG_NET_RALINK_RT3050 is not set +CONFIG_NET_RALINK_SOC=y +CONFIG_NET_SELFTESTS=y +# CONFIG_NET_VENDOR_MEDIATEK is not set +CONFIG_NET_VENDOR_RALINK=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +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_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +# CONFIG_PHY_MT7621_PCI is not set +CONFIG_PHY_RALINK_USB=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_AW9523 is not set +CONFIG_PINCTRL_MT7620=y +CONFIG_PINCTRL_RALINK=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_RALINK=y +CONFIG_RALINK_WDT=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_RESET_CONTROLLER=y +CONFIG_SERIAL_8250_RT288X=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SOC_MT7620=y +# CONFIG_SOC_MT7621 is not set +# 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 is not set +CONFIG_SPI_RT2880=y +CONFIG_SRCU=y +CONFIG_SWCONFIG=y +CONFIG_SWCONFIG_LEDS=y +CONFIG_SWPHY=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_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_TARGET_ISA_REV=2 +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_WATCHDOG_CORE=y diff --git a/target/linux/ramips/mt7621/config-6.1 b/target/linux/ramips/mt7621/config-6.1 new file mode 100644 index 0000000000..05e4c1ce87 --- /dev/null +++ b/target/linux/ramips/mt7621/config-6.1 @@ -0,0 +1,297 @@ +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_SUSPEND_POSSIBLE=y +CONFIG_AT803X_PHY=y +CONFIG_BLK_MQ_PCI=y +CONFIG_BOARD_SCACHE=y +CONFIG_CEVT_R4K=y +CONFIG_CLKSRC_MIPS_GIC=y +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_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_LITTLE_ENDIAN=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_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_BLAKE2S_GENERIC=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_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_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_I2C=y +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_MT7621=y +CONFIG_ICPLUS_PHY=y +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_LED_TRIGGER_PHY=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +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_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_CPC=y +CONFIG_MIPS_CPS=y +# CONFIG_MIPS_CPS_NS16550_BOOL is not set +CONFIG_MIPS_CPU_SCACHE=y +CONFIG_MIPS_EBPF_JIT=y +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_PARSER_TPLINK_SAFELOADER is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_ROUTERBOOT_PARTS=y +CONFIG_MTD_SERCOMM_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_MT7530_MDIO=y +# CONFIG_NET_DSA_MT7530_MMIO is not set +CONFIG_NET_DSA_TAG_MTK=y +CONFIG_NET_FLOW_LIMIT=y +CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_SELFTESTS=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_PAGE_POOL=y +CONFIG_PAGE_POOL_STATS=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_PCS_MTK_LYNXI=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PHY_MT7621_PCI=y +# CONFIG_PHY_RALINK_USB is not set +CONFIG_PINCTRL=y +CONFIG_PINCTRL_AW9523=y +CONFIG_PINCTRL_MT7621=y +CONFIG_PINCTRL_RALINK=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_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/mt76x8/config-6.1 b/target/linux/ramips/mt76x8/config-6.1 new file mode 100644 index 0000000000..6d6759a7c5 --- /dev/null +++ b/target/linux/ramips/mt76x8/config-6.1 @@ -0,0 +1,200 @@ +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_SUSPEND_POSSIBLE=y +CONFIG_AT803X_PHY=y +CONFIG_BLK_MQ_PCI=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_SYSTICK_QUIRK=y +CONFIG_CLKEVT_RT3352=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLK_MTMIPS=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_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_LITTLE_ENDIAN=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_VI=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_RNG2=y +CONFIG_CSRC_R4K=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_DTB_MT7620A_EVAL is not set +# CONFIG_DTB_OMEGA2P is not set +CONFIG_DTB_RT_NONE=y +# CONFIG_DTB_VOCORE2 is not set +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_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_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_MT7621=y +# CONFIG_GPIO_RALINK is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HZ_PERIODIC=y +CONFIG_ICPLUS_PHY=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_INTC=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_EBPF_JIT=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_LD_CAN_LINK_VDSO=y +# CONFIG_MIPS_NO_APPENDED_DTB is not set +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_PARSER_TPLINK_SAFELOADER is not set +CONFIG_MTD_PARSER_TRX=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y +CONFIG_MTD_SPLIT_TPLINK_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_VIRT_CONCAT=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_RALINK_ESW_RT3050=y +# CONFIG_NET_RALINK_MT7620 is not set +CONFIG_NET_RALINK_RT3050=y +CONFIG_NET_RALINK_SOC=y +CONFIG_NET_SELFTESTS=y +# CONFIG_NET_VENDOR_MEDIATEK is not set +CONFIG_NET_VENDOR_RALINK=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +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_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +# CONFIG_PHY_MT7621_PCI is not set +CONFIG_PHY_RALINK_USB=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_AW9523 is not set +CONFIG_PINCTRL_MT7620=y +CONFIG_PINCTRL_RALINK=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_RALINK=y +# CONFIG_RALINK_WDT is not set +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RTC_CLASS=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SOC_MT7620=y +# CONFIG_SOC_MT7621 is not set +# 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_SWCONFIG=y +CONFIG_SWCONFIG_LEDS=y +CONFIG_SWPHY=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_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_TARGET_ISA_REV=2 +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_WATCHDOG_CORE=y diff --git a/target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch b/target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch new file mode 100644 index 0000000000..a102c607b6 --- /dev/null +++ b/target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch @@ -0,0 +1,60 @@ +From f383b0770612838e78986231710c0a3afee4db42 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 10 Jan 2022 12:49:27 +0100 +Subject: [PATCH 1/2] dt-bindings: reset: add dt binding header for Mediatek MT7621 resets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add dt binding header for resets lines in Mediatek MT7621 SoCs. + +Acked-by: Rob Herring +Tested-by: Arınç ÜNAL +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20220110114930.1406665-2-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + include/dt-bindings/reset/mt7621-reset.h | 37 ++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + create mode 100644 include/dt-bindings/reset/mt7621-reset.h + +--- /dev/null ++++ b/include/dt-bindings/reset/mt7621-reset.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ ++/* ++ * Copyright (c) 2021 Sergio Paracuellos ++ * Author: Sergio Paracuellos ++ */ ++ ++#ifndef DT_BINDING_MT7621_RESET_H ++#define DT_BINDING_MT7621_RESET_H ++ ++#define MT7621_RST_SYS 0 ++#define MT7621_RST_MCM 2 ++#define MT7621_RST_HSDMA 5 ++#define MT7621_RST_FE 6 ++#define MT7621_RST_SPDIFTX 7 ++#define MT7621_RST_TIMER 8 ++#define MT7621_RST_INT 9 ++#define MT7621_RST_MC 10 ++#define MT7621_RST_PCM 11 ++#define MT7621_RST_PIO 13 ++#define MT7621_RST_GDMA 14 ++#define MT7621_RST_NFI 15 ++#define MT7621_RST_I2C 16 ++#define MT7621_RST_I2S 17 ++#define MT7621_RST_SPI 18 ++#define MT7621_RST_UART1 19 ++#define MT7621_RST_UART2 20 ++#define MT7621_RST_UART3 21 ++#define MT7621_RST_ETH 23 ++#define MT7621_RST_PCIE0 24 ++#define MT7621_RST_PCIE1 25 ++#define MT7621_RST_PCIE2 26 ++#define MT7621_RST_AUX_STCK 28 ++#define MT7621_RST_CRYPTO 29 ++#define MT7621_RST_SDXC 30 ++#define MT7621_RST_PPE 31 ++ ++#endif /* DT_BINDING_MT7621_RESET_H */ diff --git a/target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch b/target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch new file mode 100644 index 0000000000..e4fd34b28c --- /dev/null +++ b/target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch @@ -0,0 +1,114 @@ +From 64b2d6ffff862c0e7278198b4229e42e1abb3bb1 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 10 Jan 2022 12:49:30 +0100 +Subject: [PATCH 2/2] staging: mt7621-dts: align resets with binding documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Binding documentation for compatible 'mediatek,mt7621-sysc' has been updated +to be used as a reset provider. Align reset related bits and system controller +node with binding documentation along the dtsi file. + +Tested-by: Arınç ÜNAL +Reviewed-by: Philipp Zabel +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20220110114930.1406665-5-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/staging/mt7621-dts/mt7621.dtsi | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +--- a/drivers/staging/mt7621-dts/mt7621.dtsi ++++ b/drivers/staging/mt7621-dts/mt7621.dtsi +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + + / { + #address-cells = <1>; +@@ -59,6 +60,7 @@ + compatible = "mediatek,mt7621-sysc", "syscon"; + reg = <0x0 0x100>; + #clock-cells = <1>; ++ #reset-cells = <1>; + ralink,memctl = <&memc>; + clock-output-names = "xtal", "cpu", "bus", + "50m", "125m", "150m", +@@ -88,7 +90,7 @@ + + clocks = <&sysc MT7621_CLK_I2C>; + clock-names = "i2c"; +- resets = <&rstctrl 16>; ++ resets = <&sysc MT7621_RST_I2C>; + reset-names = "i2c"; + + #address-cells = <1>; +@@ -161,7 +163,7 @@ + clocks = <&sysc MT7621_CLK_SPI>; + clock-names = "spi"; + +- resets = <&rstctrl 18>; ++ resets = <&sysc MT7621_RST_SPI>; + reset-names = "spi"; + + #address-cells = <1>; +@@ -296,11 +298,6 @@ + }; + }; + +- rstctrl: rstctrl { +- compatible = "ralink,rt2880-reset"; +- #reset-cells = <1>; +- }; +- + sdhci: sdhci@1e130000 { + status = "disabled"; + +@@ -383,7 +380,7 @@ + #address-cells = <1>; + #size-cells = <0>; + +- resets = <&rstctrl 6 &rstctrl 23>; ++ resets = <&sysc MT7621_RST_FE &sysc MT7621_RST_ETH>; + reset-names = "fe", "eth"; + + interrupt-parent = <&gic>; +@@ -423,7 +420,7 @@ + #size-cells = <0>; + reg = <0>; + mediatek,mcm; +- resets = <&rstctrl 2>; ++ resets = <&sysc MT7621_RST_MCM>; + reset-names = "mcm"; + interrupt-controller; + #interrupt-cells = <1>; +@@ -516,7 +513,7 @@ + #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>; ++ resets = <&sysc MT7621_RST_PCIE0>; + clocks = <&sysc MT7621_CLK_PCIE0>; + phys = <&pcie0_phy 1>; + phy-names = "pcie-phy0"; +@@ -531,7 +528,7 @@ + #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>; ++ resets = <&sysc MT7621_RST_PCIE1>; + clocks = <&sysc MT7621_CLK_PCIE1>; + phys = <&pcie0_phy 1>; + phy-names = "pcie-phy1"; +@@ -546,7 +543,7 @@ + #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>; ++ resets = <&sysc MT7621_RST_PCIE2>; + clocks = <&sysc MT7621_CLK_PCIE2>; + phys = <&pcie2_phy 0>; + phy-names = "pcie-phy2"; diff --git a/target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch b/target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch new file mode 100644 index 0000000000..7fb95064f0 --- /dev/null +++ b/target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch @@ -0,0 +1,52 @@ +From 478b09fa2c00cbc40d25bc061befdf11f04a27ad Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Thu, 10 Feb 2022 10:48:58 +0100 +Subject: [PATCH 1/2] dt-bindings: clock: mediatek,mt7621-sysc: add '#reset-cells' property + +Make system controller a reset provider for all the peripherals in the +MT7621 SoC adding '#reset-cells' property. + +Acked-by: Rob Herring +Acked-by: Stephen Boyd +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20220210094859.927868-2-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + .../devicetree/bindings/clock/mediatek,mt7621-sysc.yaml | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml ++++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml +@@ -22,6 +22,11 @@ description: | + + The clocks are provided inside a system controller node. + ++ This node is also a reset provider for all the peripherals. ++ ++ Reset related bits are defined in: ++ [2]: . ++ + properties: + compatible: + items: +@@ -37,6 +42,12 @@ properties: + clocks. + const: 1 + ++ "#reset-cells": ++ description: ++ The first cell indicates the reset bit within the register, see ++ [2] for available resets. ++ const: 1 ++ + ralink,memctl: + $ref: /schemas/types.yaml#/definitions/phandle + description: +@@ -61,6 +72,7 @@ examples: + compatible = "mediatek,mt7621-sysc", "syscon"; + reg = <0x0 0x100>; + #clock-cells = <1>; ++ #reset-cells = <1>; + ralink,memctl = <&memc>; + clock-output-names = "xtal", "cpu", "bus", + "50m", "125m", "150m", diff --git a/target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch b/target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch new file mode 100644 index 0000000000..c70a1c9bbc --- /dev/null +++ b/target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch @@ -0,0 +1,148 @@ +From 38a8553b0a22ed54f014d8402fedd268b529175c Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Thu, 10 Feb 2022 10:48:59 +0100 +Subject: [PATCH 2/2] clk: ralink: make system controller node a reset provider + +MT7621 system controller node is already providing the clocks for the whole +system but must also serve as a reset provider. Hence, add reset controller +related code to the clock driver itself. To get resets properly ready for +the rest of the world we need to move platform driver initialization process +to 'arch_initcall'. + +CC: Philipp Zabel +Reviewed-by: Philipp Zabel +Acked-by: Stephen Boyd +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20220210094859.927868-3-sergio.paracuellos@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/clk/ralink/clk-mt7621.c | 92 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 91 insertions(+), 1 deletion(-) + +--- a/drivers/clk/ralink/clk-mt7621.c ++++ b/drivers/clk/ralink/clk-mt7621.c +@@ -11,14 +11,17 @@ + #include + #include + #include ++#include + #include + #include ++#include + + /* Configuration registers */ + #define SYSC_REG_SYSTEM_CONFIG0 0x10 + #define SYSC_REG_SYSTEM_CONFIG1 0x14 + #define SYSC_REG_CLKCFG0 0x2c + #define SYSC_REG_CLKCFG1 0x30 ++#define SYSC_REG_RESET_CTRL 0x34 + #define SYSC_REG_CUR_CLK_STS 0x44 + #define MEMC_REG_CPU_PLL 0x648 + +@@ -398,6 +401,82 @@ free_clk_priv: + } + CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init); + ++struct mt7621_rst { ++ struct reset_controller_dev rcdev; ++ struct regmap *sysc; ++}; ++ ++static struct mt7621_rst *to_mt7621_rst(struct reset_controller_dev *dev) ++{ ++ return container_of(dev, struct mt7621_rst, rcdev); ++} ++ ++static int mt7621_assert_device(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mt7621_rst *data = to_mt7621_rst(rcdev); ++ struct regmap *sysc = data->sysc; ++ ++ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id)); ++} ++ ++static int mt7621_deassert_device(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mt7621_rst *data = to_mt7621_rst(rcdev); ++ struct regmap *sysc = data->sysc; ++ ++ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0); ++} ++ ++static int mt7621_reset_device(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = mt7621_assert_device(rcdev, id); ++ if (ret < 0) ++ return ret; ++ ++ return mt7621_deassert_device(rcdev, id); ++} ++ ++static int mt7621_rst_xlate(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec) ++{ ++ unsigned long id = reset_spec->args[0]; ++ ++ if (id == MT7621_RST_SYS || id >= rcdev->nr_resets) ++ return -EINVAL; ++ ++ return id; ++} ++ ++static const struct reset_control_ops reset_ops = { ++ .reset = mt7621_reset_device, ++ .assert = mt7621_assert_device, ++ .deassert = mt7621_deassert_device ++}; ++ ++static int mt7621_reset_init(struct device *dev, struct regmap *sysc) ++{ ++ struct mt7621_rst *rst_data; ++ ++ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); ++ if (!rst_data) ++ return -ENOMEM; ++ ++ rst_data->sysc = sysc; ++ rst_data->rcdev.ops = &reset_ops; ++ rst_data->rcdev.owner = THIS_MODULE; ++ rst_data->rcdev.nr_resets = 32; ++ rst_data->rcdev.of_reset_n_cells = 1; ++ rst_data->rcdev.of_xlate = mt7621_rst_xlate; ++ rst_data->rcdev.of_node = dev_of_node(dev); ++ ++ return devm_reset_controller_register(dev, &rst_data->rcdev); ++} ++ + static int mt7621_clk_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; +@@ -424,6 +503,12 @@ static int mt7621_clk_probe(struct platf + return ret; + } + ++ ret = mt7621_reset_init(dev, priv->sysc); ++ if (ret) { ++ dev_err(dev, "Could not init reset controller\n"); ++ return ret; ++ } ++ + count = ARRAY_SIZE(mt7621_clks_base) + + ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates); + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count), +@@ -485,4 +570,9 @@ static struct platform_driver mt7621_clk + .of_match_table = mt7621_clk_of_match, + }, + }; +-builtin_platform_driver(mt7621_clk_driver); ++ ++static int __init mt7621_clk_reset_init(void) ++{ ++ return platform_driver_register(&mt7621_clk_driver); ++} ++arch_initcall(mt7621_clk_reset_init); diff --git a/target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch b/target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch new file mode 100644 index 0000000000..cef73c6eae --- /dev/null +++ b/target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch @@ -0,0 +1,43 @@ +From bb3ababe7f986900672e0048153c31aa4a21f96b Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Sat, 17 Dec 2022 08:48:06 +0100 +Subject: [PATCH] MIPS: ralink: mt7621: avoid to init common ralink reset controller + +[ Upstream commit 76ce51798cb16738a4a28a6662e7344aaf7ef769 ] + +Commit 38a8553b0a22 ("clk: ralink: make system controller node a reset provider") +make system controller a reset provider for mt7621 ralink SoCs. Ralink init code +also tries to start previous common reset controller which at the end tries to +find device tree node 'ralink,rt2880-reset'. mt7621 device tree file is not +using at all this node anymore. Hence avoid to init this common reset controller +for mt7621 ralink SoCs to avoid 'Failed to find reset controller node' boot +error trace error. + +Fixes: 64b2d6ffff86 ("staging: mt7621-dts: align resets with binding documentation") +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Sasha Levin +--- + arch/mips/ralink/of.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "common.h" + +@@ -95,7 +96,8 @@ static int __init plat_of_setup(void) + __dt_register_buses(soc_info.compatible, "palmbus"); + + /* make sure that the reset controller is setup early */ +- ralink_rst_init(); ++ if (ralink_soc != MT762X_SOC_MT7621AT) ++ ralink_rst_init(); + + return 0; + } diff --git a/target/linux/ramips/patches-6.1/003-v6.3-clk-ralink-fix-mt7621_gate_is_enabled-function.patch b/target/linux/ramips/patches-6.1/003-v6.3-clk-ralink-fix-mt7621_gate_is_enabled-function.patch new file mode 100644 index 0000000000..4574f7977f --- /dev/null +++ b/target/linux/ramips/patches-6.1/003-v6.3-clk-ralink-fix-mt7621_gate_is_enabled-function.patch @@ -0,0 +1,77 @@ +From 35dcae535afc153fa83f2fe51c0812536c192c58 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 6 Feb 2023 09:33:05 +0100 +Subject: [PATCH] clk: ralink: fix 'mt7621_gate_is_enabled()' function + +Compiling clock driver with CONFIG_UBSAN enabled shows the following trace: + +UBSAN: shift-out-of-bounds in drivers/clk/ralink/clk-mt7621.c:121:15 +shift exponent 131072 is too large for 32-bit type 'long unsigned int' +CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.86 #0 +Stack : ... + +Call Trace: +[<80009a58>] show_stack+0x38/0x118 +[<8045ce04>] dump_stack_lvl+0x60/0x80 +[<80458868>] ubsan_epilogue+0x10/0x54 +[<804590e0>] __ubsan_handle_shift_out_of_bounds+0x118/0x190 +[<804c9a10>] mt7621_gate_is_enabled+0x98/0xa0 +[<804bb774>] clk_core_is_enabled+0x34/0x90 +[<80aad73c>] clk_disable_unused_subtree+0x98/0x1e4 +[<80aad6d4>] clk_disable_unused_subtree+0x30/0x1e4 +[<80aad6d4>] clk_disable_unused_subtree+0x30/0x1e4 +[<80aad900>] clk_disable_unused+0x78/0x120 +[<80002030>] do_one_initcall+0x54/0x1f0 +[<80a922a4>] kernel_init_freeable+0x280/0x31c +[<808047c4>] kernel_init+0x20/0x118 +[<80003e58>] ret_from_kernel_thread+0x14/0x1c + +Shifting a value (131032) larger than the type (32 bit unsigned integer) +is undefined behaviour in C. + +The problem is in 'mt7621_gate_is_enabled()' function which is using the +'BIT()' kernel macro with the bit index for the clock gate to check if the +bit is set. When the clock gates structure is created driver is already +setting 'bit_idx' using 'BIT()' macro, so we are wrongly applying an extra +'BIT()' mask here. Removing it solve the problem and makes this function +correct. However when clock gating is correctly working, the kernel starts +disabling those clocks that are not requested. Some drivers for this SoC +are older than this clock driver itself. So to avoid the kernel to disable +clocks that have been enabled until now, we must apply 'CLK_IS_CRITICAL' +flag on gates initialization code. + +Fixes: 48df7a26f470 ("clk: ralink: add clock driver for mt7621 SoC") +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20230206083305.147582-1-sergio.paracuellos@gmail.com +Signed-off-by: Stephen Boyd +--- + drivers/clk/ralink/clk-mt7621.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/clk/ralink/clk-mt7621.c ++++ b/drivers/clk/ralink/clk-mt7621.c +@@ -121,7 +121,7 @@ static int mt7621_gate_is_enabled(struct + if (regmap_read(sysc, SYSC_REG_CLKCFG1, &val)) + return 0; + +- return val & BIT(clk_gate->bit_idx); ++ return val & clk_gate->bit_idx; + } + + static const struct clk_ops mt7621_gate_ops = { +@@ -133,8 +133,14 @@ static const struct clk_ops mt7621_gate_ + static int mt7621_gate_ops_init(struct device *dev, + struct mt7621_gate *sclk) + { ++ /* ++ * There are drivers for this SoC that are older ++ * than clock driver and are not prepared for the clock. ++ * We don't want the kernel to disable anything so we ++ * add CLK_IS_CRITICAL flag here. ++ */ + struct clk_init_data init = { +- .flags = CLK_SET_RATE_PARENT, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .num_parents = 1, + .parent_names = &sclk->parent_name, + .ops = &mt7621_gate_ops, diff --git a/target/linux/ramips/patches-6.1/005-v6.5-01-dt-bindings-clock-add-mtmips-SoCs-system-controller.patch b/target/linux/ramips/patches-6.1/005-v6.5-01-dt-bindings-clock-add-mtmips-SoCs-system-controller.patch new file mode 100644 index 0000000000..94784f7885 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-01-dt-bindings-clock-add-mtmips-SoCs-system-controller.patch @@ -0,0 +1,86 @@ +From 612616e6381929e7f9e303f8b8ad3655cc101516 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:33 +0200 +Subject: [PATCH 1/9] dt-bindings: clock: add mtmips SoCs system controller + +Adds device tree binding documentation for system controller node present +in Mediatek MIPS and Ralink SOCs. This node is a clock and reset provider +for the rest of the world. This covers RT2880, RT3050, RT3052, RT3350, +RT3883, RT5350, MT7620, MT7628 and MT7688 SoCs. + +Reviewed-by: Rob Herring +Acked-by: Stephen Boyd +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + .../bindings/clock/mediatek,mtmips-sysc.yaml | 64 ++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + create mode 100644 Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml + +--- /dev/null ++++ b/Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml +@@ -0,0 +1,64 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/clock/mediatek,mtmips-sysc.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: MTMIPS SoCs System Controller ++ ++maintainers: ++ - Sergio Paracuellos ++ ++description: | ++ MediaTek MIPS and Ralink SoCs provides a system controller to allow ++ to access to system control registers. These registers include clock ++ and reset related ones so this node is both clock and reset provider ++ for the rest of the world. ++ ++ These SoCs have an XTAL from where the cpu clock is ++ provided as well as derived clocks for the bus and the peripherals. ++ ++properties: ++ compatible: ++ items: ++ - enum: ++ - ralink,mt7620-sysc ++ - ralink,mt7628-sysc ++ - ralink,mt7688-sysc ++ - ralink,rt2880-sysc ++ - ralink,rt3050-sysc ++ - ralink,rt3052-sysc ++ - ralink,rt3352-sysc ++ - ralink,rt3883-sysc ++ - ralink,rt5350-sysc ++ - const: syscon ++ ++ reg: ++ maxItems: 1 ++ ++ '#clock-cells': ++ description: ++ The first cell indicates the clock number. ++ const: 1 ++ ++ '#reset-cells': ++ description: ++ The first cell indicates the reset bit within the register. ++ const: 1 ++ ++required: ++ - compatible ++ - reg ++ - '#clock-cells' ++ - '#reset-cells' ++ ++additionalProperties: false ++ ++examples: ++ - | ++ syscon@0 { ++ compatible = "ralink,rt5350-sysc", "syscon"; ++ reg = <0x0 0x100>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; diff --git a/target/linux/ramips/patches-6.1/005-v6.5-02-clk-ralink-add-clock-and-reset-driver-for-MTMIPS-SoC.patch b/target/linux/ramips/patches-6.1/005-v6.5-02-clk-ralink-add-clock-and-reset-driver-for-MTMIPS-SoC.patch new file mode 100644 index 0000000000..cef39978e0 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-02-clk-ralink-add-clock-and-reset-driver-for-MTMIPS-SoC.patch @@ -0,0 +1,1221 @@ +From 6f3b15586eef736831abe6a14f2a6906bc0dc074 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:34 +0200 +Subject: [PATCH 2/9] clk: ralink: add clock and reset driver for MTMIPS SoCs + +Until now, clock related code for old ralink SoCs was based in fixed clocks +using 'clk_register_fixed_rate' and 'clkdev_create' directly doing in code +and not using device tree at all for their definition. Including this driver +is an effort to be able to define proper clocks using device tree and also +cleaning all the clock and reset related code from 'arch/mips/ralink' dir. +This clock and reset driver covers all the ralink SoCs but MT7621 which is +the newest and provides gating and some differences that make it different +from its predecesors. It has its own driver since some time ago. The ralink +SoCs we are taking about are RT2880, RT3050, RT3052, RT3350, RT3352, RT3883, +RT5350, MT7620, MT7628 and MT7688. Mostly the code in this new driver has +been extracted from 'arch/mips/ralink' and cleanly put using kernel clock +driver APIs. The clock plans for this SoCs only talks about relation between +CPU frequency and BUS frequency. This relation is different depending on the +particular SoC. CPU clock is derived from XTAL frequencies. + +Depending on the SoC we have the following frequencies: +* RT2880 SoC: + - XTAL: 40 MHz. + - CPU: 250, 266, 280 or 300 MHz. + - BUS: CPU / 2 MHz. +* RT3050, RT3052, RT3350: + - XTAL: 40 MHz. + - CPU: 320 or 384 MHz. + - BUS: CPU / 3 MHz. +* RT3352: + - XTAL: 40 MHz. + - CPU: 384 or 400 MHz. + - BUS: CPU / 3 MHz. + - PERIPH: 40 MHz. +* RT3383: + - XTAL: 40 MHz. + - CPU: 250, 384, 480 or 500 MHz. + - BUS: Depends on RAM Type and CPU: + + RAM DDR2: 125. ELSE 83 MHz. + + RAM DDR2: 128. ELSE 96 MHz. + + RAM DDR2: 160. ELSE 120 MHz. + + RAM DDR2: 166. ELSE 125 MHz. +* RT5350: + - XTAL: 40 MHz. + - CPU: 300, 320 or 360 MHz. + - BUS: CPU / 3, CPU / 4, CPU / 3 MHz. + - PERIPH: 40 MHz. +* MT7628 and MT7688: + - XTAL: 20 MHz or 40 MHz. + - CPU: 575 or 580 MHz. + - BUS: CPU / 3. + - PCMI2S: 480 MHz. + - PERIPH: 40 MHz. +* MT7620: + - XTAL: 20 MHz or 40 MHz. + - PLL: XTAL, 480, 600 MHz. + - CPU: depends on PLL and some mult and dividers. + - BUS: depends on PLL and some mult and dividers. + - PERIPH: 40 or XTAL MHz. + +MT7620 is a bit more complex deriving CPU clock from a PLL and an bunch of +register reads and predividers. To derive CPU and BUS frequencies in the +MT7620 SoC 'mt7620_calc_rate()' helper is used. + +In the case XTAL can have different frequencies and we need a different +clock frequency for peripherals 'periph' clock in introduced. + +The rest of the peripherals present in the SoC just follow their parent +frequencies. + +With this information the clk driver will provide all the clock and reset +functionality from a set of hardcoded clocks allowing to define a nice +device tree without fixed clocks. + +Acked-by: Stephen Boyd +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + drivers/clk/ralink/Kconfig | 7 + + drivers/clk/ralink/Makefile | 1 + + drivers/clk/ralink/clk-mtmips.c | 1115 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 1123 insertions(+) + create mode 100644 drivers/clk/ralink/clk-mtmips.c + +--- a/drivers/clk/ralink/Kconfig ++++ b/drivers/clk/ralink/Kconfig +@@ -9,3 +9,10 @@ config CLK_MT7621 + select MFD_SYSCON + help + This driver supports MediaTek MT7621 basic clocks. ++ ++config CLK_MTMIPS ++ bool "Clock driver for MTMIPS SoCs" ++ depends on SOC_RT305X || SOC_RT288X || SOC_RT3883 || SOC_MT7620 || COMPILE_TEST ++ select MFD_SYSCON ++ help ++ This driver supports MTMIPS basic clocks. +--- a/drivers/clk/ralink/Makefile ++++ b/drivers/clk/ralink/Makefile +@@ -1,2 +1,3 @@ + # SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_CLK_MT7621) += clk-mt7621.o ++obj-$(CONFIG_CLK_MTMIPS) += clk-mtmips.o +--- /dev/null ++++ b/drivers/clk/ralink/clk-mtmips.c +@@ -0,0 +1,1115 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * MTMIPS SoCs Clock Driver ++ * Author: Sergio Paracuellos ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Configuration registers */ ++#define SYSC_REG_SYSTEM_CONFIG 0x10 ++#define SYSC_REG_CLKCFG0 0x2c ++#define SYSC_REG_RESET_CTRL 0x34 ++#define SYSC_REG_CPU_SYS_CLKCFG 0x3c ++#define SYSC_REG_CPLL_CONFIG0 0x54 ++#define SYSC_REG_CPLL_CONFIG1 0x58 ++ ++/* RT2880 SoC */ ++#define RT2880_CONFIG_CPUCLK_SHIFT 20 ++#define RT2880_CONFIG_CPUCLK_MASK 0x3 ++#define RT2880_CONFIG_CPUCLK_250 0x0 ++#define RT2880_CONFIG_CPUCLK_266 0x1 ++#define RT2880_CONFIG_CPUCLK_280 0x2 ++#define RT2880_CONFIG_CPUCLK_300 0x3 ++ ++/* RT305X SoC */ ++#define RT305X_SYSCFG_CPUCLK_SHIFT 18 ++#define RT305X_SYSCFG_CPUCLK_MASK 0x1 ++#define RT305X_SYSCFG_CPUCLK_LOW 0x0 ++#define RT305X_SYSCFG_CPUCLK_HIGH 0x1 ++ ++/* RT3352 SoC */ ++#define RT3352_SYSCFG0_CPUCLK_SHIFT 8 ++#define RT3352_SYSCFG0_CPUCLK_MASK 0x1 ++#define RT3352_SYSCFG0_CPUCLK_LOW 0x0 ++#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1 ++ ++/* RT3383 SoC */ ++#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17) ++#define RT3883_SYSCFG0_CPUCLK_SHIFT 8 ++#define RT3883_SYSCFG0_CPUCLK_MASK 0x3 ++#define RT3883_SYSCFG0_CPUCLK_250 0x0 ++#define RT3883_SYSCFG0_CPUCLK_384 0x1 ++#define RT3883_SYSCFG0_CPUCLK_480 0x2 ++#define RT3883_SYSCFG0_CPUCLK_500 0x3 ++ ++/* RT5350 SoC */ ++#define RT5350_CLKCFG0_XTAL_SEL BIT(20) ++#define RT5350_SYSCFG0_CPUCLK_SHIFT 8 ++#define RT5350_SYSCFG0_CPUCLK_MASK 0x3 ++#define RT5350_SYSCFG0_CPUCLK_360 0x0 ++#define RT5350_SYSCFG0_CPUCLK_320 0x2 ++#define RT5350_SYSCFG0_CPUCLK_300 0x3 ++ ++/* MT7620 and MT76x8 SoCs */ ++#define MT7620_XTAL_FREQ_SEL BIT(6) ++#define CPLL_CFG0_SW_CFG BIT(31) ++#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 16 ++#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x7 ++#define CPLL_CFG0_LC_CURFCK BIT(15) ++#define CPLL_CFG0_BYPASS_REF_CLK BIT(14) ++#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 10 ++#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x3 ++#define CPLL_CFG1_CPU_AUX1 BIT(25) ++#define CPLL_CFG1_CPU_AUX0 BIT(24) ++#define CLKCFG0_PERI_CLK_SEL BIT(4) ++#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16 ++#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf ++#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */ ++#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */ ++#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 8 ++#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f ++#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 0 ++#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f ++ ++/* clock scaling */ ++#define CLKCFG_FDIV_MASK 0x1f00 ++#define CLKCFG_FDIV_USB_VAL 0x0300 ++#define CLKCFG_FFRAC_MASK 0x001f ++#define CLKCFG_FFRAC_USB_VAL 0x0003 ++ ++struct mtmips_clk; ++struct mtmips_clk_fixed; ++struct mtmips_clk_factor; ++ ++struct mtmips_clk_data { ++ struct mtmips_clk *clk_base; ++ size_t num_clk_base; ++ struct mtmips_clk_fixed *clk_fixed; ++ size_t num_clk_fixed; ++ struct mtmips_clk_factor *clk_factor; ++ size_t num_clk_factor; ++ struct mtmips_clk *clk_periph; ++ size_t num_clk_periph; ++}; ++ ++struct mtmips_clk_priv { ++ struct regmap *sysc; ++ const struct mtmips_clk_data *data; ++}; ++ ++struct mtmips_clk { ++ struct clk_hw hw; ++ struct mtmips_clk_priv *priv; ++}; ++ ++struct mtmips_clk_fixed { ++ const char *name; ++ const char *parent; ++ unsigned long rate; ++ struct clk_hw *hw; ++}; ++ ++struct mtmips_clk_factor { ++ const char *name; ++ const char *parent; ++ int mult; ++ int div; ++ unsigned long flags; ++ struct clk_hw *hw; ++}; ++ ++static unsigned long mtmips_pherip_clk_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return parent_rate; ++} ++ ++static const struct clk_ops mtmips_periph_clk_ops = { ++ .recalc_rate = mtmips_pherip_clk_rate, ++}; ++ ++#define CLK_PERIPH(_name, _parent) { \ ++ .init = &(const struct clk_init_data) { \ ++ .name = _name, \ ++ .ops = &mtmips_periph_clk_ops, \ ++ .parent_data = &(const struct clk_parent_data) {\ ++ .name = _parent, \ ++ .fw_name = _parent \ ++ }, \ ++ .num_parents = 1, \ ++ /* \ ++ * There are drivers for these SoCs that are \ ++ * older than clock driver and are not prepared \ ++ * for the clock. We don't want the kernel to \ ++ * disable anything so we add CLK_IS_CRITICAL \ ++ * flag here. \ ++ */ \ ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL \ ++ }, \ ++} ++ ++static struct mtmips_clk rt2880_pherip_clks[] = { ++ { CLK_PERIPH("300100.timer", "bus") }, ++ { CLK_PERIPH("300120.watchdog", "bus") }, ++ { CLK_PERIPH("300500.uart", "bus") }, ++ { CLK_PERIPH("300900.i2c", "bus") }, ++ { CLK_PERIPH("300c00.uartlite", "bus") }, ++ { CLK_PERIPH("400000.ethernet", "bus") }, ++ { CLK_PERIPH("480000.wmac", "xtal") } ++}; ++ ++static struct mtmips_clk rt305x_pherip_clks[] = { ++ { CLK_PERIPH("10000100.timer", "bus") }, ++ { CLK_PERIPH("10000120.watchdog", "bus") }, ++ { CLK_PERIPH("10000500.uart", "bus") }, ++ { CLK_PERIPH("10000900.i2c", "bus") }, ++ { CLK_PERIPH("10000a00.i2s", "bus") }, ++ { CLK_PERIPH("10000b00.spi", "bus") }, ++ { CLK_PERIPH("10000b40.spi", "bus") }, ++ { CLK_PERIPH("10000c00.uartlite", "bus") }, ++ { CLK_PERIPH("10100000.ethernet", "bus") }, ++ { CLK_PERIPH("10180000.wmac", "xtal") } ++}; ++ ++static struct mtmips_clk rt5350_pherip_clks[] = { ++ { CLK_PERIPH("10000100.timer", "bus") }, ++ { CLK_PERIPH("10000120.watchdog", "bus") }, ++ { CLK_PERIPH("10000500.uart", "periph") }, ++ { CLK_PERIPH("10000900.i2c", "periph") }, ++ { CLK_PERIPH("10000a00.i2s", "periph") }, ++ { CLK_PERIPH("10000b00.spi", "bus") }, ++ { CLK_PERIPH("10000b40.spi", "bus") }, ++ { CLK_PERIPH("10000c00.uartlite", "periph") }, ++ { CLK_PERIPH("10100000.ethernet", "bus") }, ++ { CLK_PERIPH("10180000.wmac", "xtal") } ++}; ++ ++static struct mtmips_clk mt7620_pherip_clks[] = { ++ { CLK_PERIPH("10000100.timer", "periph") }, ++ { CLK_PERIPH("10000120.watchdog", "periph") }, ++ { CLK_PERIPH("10000500.uart", "periph") }, ++ { CLK_PERIPH("10000900.i2c", "periph") }, ++ { CLK_PERIPH("10000a00.i2s", "periph") }, ++ { CLK_PERIPH("10000b00.spi", "bus") }, ++ { CLK_PERIPH("10000b40.spi", "bus") }, ++ { CLK_PERIPH("10000c00.uartlite", "periph") }, ++ { CLK_PERIPH("10180000.wmac", "xtal") } ++}; ++ ++static struct mtmips_clk mt76x8_pherip_clks[] = { ++ { CLK_PERIPH("10000100.timer", "periph") }, ++ { CLK_PERIPH("10000120.watchdog", "periph") }, ++ { CLK_PERIPH("10000900.i2c", "periph") }, ++ { CLK_PERIPH("10000a00.i2s", "pcmi2s") }, ++ { CLK_PERIPH("10000b00.spi", "bus") }, ++ { CLK_PERIPH("10000b40.spi", "bus") }, ++ { CLK_PERIPH("10000c00.uart0", "periph") }, ++ { CLK_PERIPH("10000d00.uart1", "periph") }, ++ { CLK_PERIPH("10000e00.uart2", "periph") }, ++ { CLK_PERIPH("10300000.wmac", "xtal") } ++}; ++ ++static int mtmips_register_pherip_clocks(struct device_node *np, ++ struct clk_hw_onecell_data *clk_data, ++ struct mtmips_clk_priv *priv) ++{ ++ struct clk_hw **hws = clk_data->hws; ++ struct mtmips_clk *sclk; ++ size_t idx_start = priv->data->num_clk_base + priv->data->num_clk_fixed + ++ priv->data->num_clk_factor; ++ int ret, i; ++ ++ for (i = 0; i < priv->data->num_clk_periph; i++) { ++ int idx = idx_start + i; ++ ++ sclk = &priv->data->clk_periph[i]; ++ ret = of_clk_hw_register(np, &sclk->hw); ++ if (ret) { ++ pr_err("Couldn't register peripheral clock %d\n", idx); ++ goto err_clk_unreg; ++ } ++ ++ hws[idx] = &sclk->hw; ++ } ++ ++ return 0; ++ ++err_clk_unreg: ++ while (--i >= 0) { ++ sclk = &priv->data->clk_periph[i]; ++ clk_hw_unregister(&sclk->hw); ++ } ++ return ret; ++} ++ ++#define CLK_FIXED(_name, _parent, _rate) \ ++ { \ ++ .name = _name, \ ++ .parent = _parent, \ ++ .rate = _rate \ ++ } ++ ++static struct mtmips_clk_fixed rt305x_fixed_clocks[] = { ++ CLK_FIXED("xtal", NULL, 40000000) ++}; ++ ++static struct mtmips_clk_fixed rt3352_fixed_clocks[] = { ++ CLK_FIXED("periph", "xtal", 40000000) ++}; ++ ++static struct mtmips_clk_fixed mt76x8_fixed_clocks[] = { ++ CLK_FIXED("pcmi2s", "xtal", 480000000), ++ CLK_FIXED("periph", "xtal", 40000000) ++}; ++ ++static int mtmips_register_fixed_clocks(struct clk_hw_onecell_data *clk_data, ++ struct mtmips_clk_priv *priv) ++{ ++ struct clk_hw **hws = clk_data->hws; ++ struct mtmips_clk_fixed *sclk; ++ size_t idx_start = priv->data->num_clk_base; ++ int ret, i; ++ ++ for (i = 0; i < priv->data->num_clk_fixed; i++) { ++ int idx = idx_start + i; ++ ++ sclk = &priv->data->clk_fixed[i]; ++ sclk->hw = clk_hw_register_fixed_rate(NULL, sclk->name, ++ sclk->parent, 0, ++ sclk->rate); ++ if (IS_ERR(sclk->hw)) { ++ pr_err("Couldn't register fixed clock %d\n", idx); ++ goto err_clk_unreg; ++ } ++ ++ hws[idx] = sclk->hw; ++ } ++ ++ return 0; ++ ++err_clk_unreg: ++ while (--i >= 0) { ++ sclk = &priv->data->clk_fixed[i]; ++ clk_hw_unregister_fixed_rate(sclk->hw); ++ } ++ return ret; ++} ++ ++#define CLK_FACTOR(_name, _parent, _mult, _div) \ ++ { \ ++ .name = _name, \ ++ .parent = _parent, \ ++ .mult = _mult, \ ++ .div = _div, \ ++ .flags = CLK_SET_RATE_PARENT \ ++ } ++ ++static struct mtmips_clk_factor rt2880_factor_clocks[] = { ++ CLK_FACTOR("bus", "cpu", 1, 2) ++}; ++ ++static struct mtmips_clk_factor rt305x_factor_clocks[] = { ++ CLK_FACTOR("bus", "cpu", 1, 3) ++}; ++ ++static int mtmips_register_factor_clocks(struct clk_hw_onecell_data *clk_data, ++ struct mtmips_clk_priv *priv) ++{ ++ struct clk_hw **hws = clk_data->hws; ++ struct mtmips_clk_factor *sclk; ++ size_t idx_start = priv->data->num_clk_base + priv->data->num_clk_fixed; ++ int ret, i; ++ ++ for (i = 0; i < priv->data->num_clk_factor; i++) { ++ int idx = idx_start + i; ++ ++ sclk = &priv->data->clk_factor[i]; ++ sclk->hw = clk_hw_register_fixed_factor(NULL, sclk->name, ++ sclk->parent, sclk->flags, ++ sclk->mult, sclk->div); ++ if (IS_ERR(sclk->hw)) { ++ pr_err("Couldn't register factor clock %d\n", idx); ++ goto err_clk_unreg; ++ } ++ ++ hws[idx] = sclk->hw; ++ } ++ ++ return 0; ++ ++err_clk_unreg: ++ while (--i >= 0) { ++ sclk = &priv->data->clk_factor[i]; ++ clk_hw_unregister_fixed_factor(sclk->hw); ++ } ++ return ret; ++} ++ ++static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw) ++{ ++ return container_of(hw, struct mtmips_clk, hw); ++} ++ ++static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 val; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &val); ++ if (!(val & RT5350_CLKCFG0_XTAL_SEL)) ++ return 20000000; ++ ++ return 40000000; ++} ++ ++static unsigned long rt5350_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long xtal_clk) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) & RT5350_SYSCFG0_CPUCLK_MASK; ++ ++ switch (t) { ++ case RT5350_SYSCFG0_CPUCLK_360: ++ return 360000000; ++ case RT5350_SYSCFG0_CPUCLK_320: ++ return 320000000; ++ case RT5350_SYSCFG0_CPUCLK_300: ++ return 300000000; ++ default: ++ BUG(); ++ } ++} ++ ++static unsigned long rt5350_bus_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ if (parent_rate == 320000000) ++ return parent_rate / 4; ++ ++ return parent_rate / 3; ++} ++ ++static unsigned long rt3352_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long xtal_clk) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) & RT3352_SYSCFG0_CPUCLK_MASK; ++ ++ switch (t) { ++ case RT3352_SYSCFG0_CPUCLK_LOW: ++ return 384000000; ++ case RT3352_SYSCFG0_CPUCLK_HIGH: ++ return 400000000; ++ default: ++ BUG(); ++ } ++} ++ ++static unsigned long rt305x_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long xtal_clk) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) & RT305X_SYSCFG_CPUCLK_MASK; ++ ++ switch (t) { ++ case RT305X_SYSCFG_CPUCLK_LOW: ++ return 320000000; ++ case RT305X_SYSCFG_CPUCLK_HIGH: ++ return 384000000; ++ default: ++ BUG(); ++ } ++} ++ ++static unsigned long rt3883_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long xtal_clk) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ t = (t >> RT3883_SYSCFG0_CPUCLK_SHIFT) & RT3883_SYSCFG0_CPUCLK_MASK; ++ ++ switch (t) { ++ case RT3883_SYSCFG0_CPUCLK_250: ++ return 250000000; ++ case RT3883_SYSCFG0_CPUCLK_384: ++ return 384000000; ++ case RT3883_SYSCFG0_CPUCLK_480: ++ return 480000000; ++ case RT3883_SYSCFG0_CPUCLK_500: ++ return 500000000; ++ default: ++ BUG(); ++ } ++} ++ ++static unsigned long rt3883_bus_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 ddr2; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ ddr2 = t & RT3883_SYSCFG0_DRAM_TYPE_DDR2; ++ ++ switch (parent_rate) { ++ case 250000000: ++ return (ddr2) ? 125000000 : 83000000; ++ case 384000000: ++ return (ddr2) ? 128000000 : 96000000; ++ case 480000000: ++ return (ddr2) ? 160000000 : 120000000; ++ case 500000000: ++ return (ddr2) ? 166000000 : 125000000; ++ default: ++ WARN_ON_ONCE(parent_rate == 0); ++ return parent_rate / 4; ++ } ++} ++ ++static unsigned long rt2880_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long xtal_clk) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ t = (t >> RT2880_CONFIG_CPUCLK_SHIFT) & RT2880_CONFIG_CPUCLK_MASK; ++ ++ switch (t) { ++ case RT2880_CONFIG_CPUCLK_250: ++ return 250000000; ++ case RT2880_CONFIG_CPUCLK_266: ++ return 266000000; ++ case RT2880_CONFIG_CPUCLK_280: ++ return 280000000; ++ case RT2880_CONFIG_CPUCLK_300: ++ return 300000000; ++ default: ++ BUG(); ++ } ++} ++ ++static u32 mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div) ++{ ++ u64 t; ++ ++ t = ref_rate; ++ t *= mul; ++ t = div_u64(t, div); ++ ++ return t; ++} ++ ++static unsigned long mt7620_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ static const u32 clk_divider[] = { 2, 3, 4, 8 }; ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ unsigned long cpu_pll; ++ u32 t; ++ u32 mul; ++ u32 div; ++ ++ regmap_read(sysc, SYSC_REG_CPLL_CONFIG0, &t); ++ if (t & CPLL_CFG0_BYPASS_REF_CLK) { ++ cpu_pll = parent_rate; ++ } else if ((t & CPLL_CFG0_SW_CFG) == 0) { ++ cpu_pll = 600000000; ++ } else { ++ mul = (t >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) & ++ CPLL_CFG0_PLL_MULT_RATIO_MASK; ++ mul += 24; ++ if (t & CPLL_CFG0_LC_CURFCK) ++ mul *= 2; ++ ++ div = (t >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) & ++ CPLL_CFG0_PLL_DIV_RATIO_MASK; ++ ++ WARN_ON_ONCE(div >= ARRAY_SIZE(clk_divider)); ++ ++ cpu_pll = mt7620_calc_rate(parent_rate, mul, clk_divider[div]); ++ } ++ ++ regmap_read(sysc, SYSC_REG_CPLL_CONFIG1, &t); ++ if (t & CPLL_CFG1_CPU_AUX1) ++ return parent_rate; ++ ++ if (t & CPLL_CFG1_CPU_AUX0) ++ return 480000000; ++ ++ return cpu_pll; ++} ++ ++static unsigned long mt7620_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ u32 mul; ++ u32 div; ++ ++ regmap_read(sysc, SYSC_REG_CPU_SYS_CLKCFG, &t); ++ mul = t & CPU_SYS_CLKCFG_CPU_FFRAC_MASK; ++ div = (t >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) & ++ CPU_SYS_CLKCFG_CPU_FDIV_MASK; ++ ++ return mt7620_calc_rate(parent_rate, mul, div); ++} ++ ++static unsigned long mt7620_bus_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ static const u32 ocp_dividers[16] = { ++ [CPU_SYS_CLKCFG_OCP_RATIO_2] = 2, ++ [CPU_SYS_CLKCFG_OCP_RATIO_3] = 3, ++ [CPU_SYS_CLKCFG_OCP_RATIO_4] = 4, ++ [CPU_SYS_CLKCFG_OCP_RATIO_5] = 5, ++ [CPU_SYS_CLKCFG_OCP_RATIO_10] = 10, ++ }; ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ u32 ocp_ratio; ++ u32 div; ++ ++ regmap_read(sysc, SYSC_REG_CPU_SYS_CLKCFG, &t); ++ ocp_ratio = (t >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) & ++ CPU_SYS_CLKCFG_OCP_RATIO_MASK; ++ ++ if (WARN_ON_ONCE(ocp_ratio >= ARRAY_SIZE(ocp_dividers))) ++ return parent_rate; ++ ++ div = ocp_dividers[ocp_ratio]; ++ ++ if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio)) ++ return parent_rate; ++ ++ return parent_rate / div; ++} ++ ++static unsigned long mt7620_periph_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_CLKCFG0, &t); ++ if (t & CLKCFG0_PERI_CLK_SEL) ++ return parent_rate; ++ ++ return 40000000; ++} ++ ++static unsigned long mt76x8_xtal_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtmips_clk *clk = to_mtmips_clk(hw); ++ struct regmap *sysc = clk->priv->sysc; ++ u32 t; ++ ++ regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t); ++ if (t & MT7620_XTAL_FREQ_SEL) ++ return 40000000; ++ ++ return 20000000; ++} ++ ++static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw, ++ unsigned long xtal_clk) ++{ ++ if (xtal_clk == 40000000) ++ return 580000000; ++ ++ return 575000000; ++} ++ ++#define CLK_BASE(_name, _parent, _recalc) { \ ++ .init = &(const struct clk_init_data) { \ ++ .name = _name, \ ++ .ops = &(const struct clk_ops) { \ ++ .recalc_rate = _recalc, \ ++ }, \ ++ .parent_data = &(const struct clk_parent_data) { \ ++ .name = _parent, \ ++ .fw_name = _parent \ ++ }, \ ++ .num_parents = _parent ? 1 : 0 \ ++ }, \ ++} ++ ++static struct mtmips_clk rt2880_clks_base[] = { ++ { CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) } ++}; ++ ++static struct mtmips_clk rt305x_clks_base[] = { ++ { CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) } ++}; ++ ++static struct mtmips_clk rt3352_clks_base[] = { ++ { CLK_BASE("xtal", NULL, rt5350_xtal_recalc_rate) }, ++ { CLK_BASE("cpu", "xtal", rt3352_cpu_recalc_rate) } ++}; ++ ++static struct mtmips_clk rt3883_clks_base[] = { ++ { CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) }, ++ { CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) } ++}; ++ ++static struct mtmips_clk rt5350_clks_base[] = { ++ { CLK_BASE("xtal", NULL, rt5350_xtal_recalc_rate) }, ++ { CLK_BASE("cpu", "xtal", rt5350_cpu_recalc_rate) }, ++ { CLK_BASE("bus", "cpu", rt5350_bus_recalc_rate) } ++}; ++ ++static struct mtmips_clk mt7620_clks_base[] = { ++ { CLK_BASE("xtal", NULL, mt76x8_xtal_recalc_rate) }, ++ { CLK_BASE("pll", "xtal", mt7620_pll_recalc_rate) }, ++ { CLK_BASE("cpu", "pll", mt7620_cpu_recalc_rate) }, ++ { CLK_BASE("periph", "xtal", mt7620_periph_recalc_rate) }, ++ { CLK_BASE("bus", "cpu", mt7620_bus_recalc_rate) } ++}; ++ ++static struct mtmips_clk mt76x8_clks_base[] = { ++ { CLK_BASE("xtal", NULL, mt76x8_xtal_recalc_rate) }, ++ { CLK_BASE("cpu", "xtal", mt76x8_cpu_recalc_rate) } ++}; ++ ++static int mtmips_register_clocks(struct device_node *np, ++ struct clk_hw_onecell_data *clk_data, ++ struct mtmips_clk_priv *priv) ++{ ++ struct clk_hw **hws = clk_data->hws; ++ struct mtmips_clk *sclk; ++ int ret, i; ++ ++ for (i = 0; i < priv->data->num_clk_base; i++) { ++ sclk = &priv->data->clk_base[i]; ++ sclk->priv = priv; ++ ret = of_clk_hw_register(np, &sclk->hw); ++ if (ret) { ++ pr_err("Couldn't register top clock %i\n", i); ++ goto err_clk_unreg; ++ } ++ ++ hws[i] = &sclk->hw; ++ } ++ ++ return 0; ++ ++err_clk_unreg: ++ while (--i >= 0) { ++ sclk = &priv->data->clk_base[i]; ++ clk_hw_unregister(&sclk->hw); ++ } ++ return ret; ++} ++ ++static const struct mtmips_clk_data rt2880_clk_data = { ++ .clk_base = rt2880_clks_base, ++ .num_clk_base = ARRAY_SIZE(rt2880_clks_base), ++ .clk_fixed = rt305x_fixed_clocks, ++ .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks), ++ .clk_factor = rt2880_factor_clocks, ++ .num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks), ++ .clk_periph = rt2880_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(rt2880_pherip_clks), ++}; ++ ++static const struct mtmips_clk_data rt305x_clk_data = { ++ .clk_base = rt305x_clks_base, ++ .num_clk_base = ARRAY_SIZE(rt305x_clks_base), ++ .clk_fixed = rt305x_fixed_clocks, ++ .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks), ++ .clk_factor = rt305x_factor_clocks, ++ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks), ++ .clk_periph = rt305x_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(rt305x_pherip_clks), ++}; ++ ++static const struct mtmips_clk_data rt3352_clk_data = { ++ .clk_base = rt3352_clks_base, ++ .num_clk_base = ARRAY_SIZE(rt3352_clks_base), ++ .clk_fixed = rt3352_fixed_clocks, ++ .num_clk_fixed = ARRAY_SIZE(rt3352_fixed_clocks), ++ .clk_factor = rt305x_factor_clocks, ++ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks), ++ .clk_periph = rt5350_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks), ++}; ++ ++static const struct mtmips_clk_data rt3883_clk_data = { ++ .clk_base = rt3883_clks_base, ++ .num_clk_base = ARRAY_SIZE(rt3883_clks_base), ++ .clk_fixed = rt305x_fixed_clocks, ++ .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks), ++ .clk_factor = NULL, ++ .num_clk_factor = 0, ++ .clk_periph = rt5350_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks), ++}; ++ ++static const struct mtmips_clk_data rt5350_clk_data = { ++ .clk_base = rt5350_clks_base, ++ .num_clk_base = ARRAY_SIZE(rt5350_clks_base), ++ .clk_fixed = rt3352_fixed_clocks, ++ .num_clk_fixed = ARRAY_SIZE(rt3352_fixed_clocks), ++ .clk_factor = NULL, ++ .num_clk_factor = 0, ++ .clk_periph = rt5350_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks), ++}; ++ ++static const struct mtmips_clk_data mt7620_clk_data = { ++ .clk_base = mt7620_clks_base, ++ .num_clk_base = ARRAY_SIZE(mt7620_clks_base), ++ .clk_fixed = NULL, ++ .num_clk_fixed = 0, ++ .clk_factor = NULL, ++ .num_clk_factor = 0, ++ .clk_periph = mt7620_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(mt7620_pherip_clks), ++}; ++ ++static const struct mtmips_clk_data mt76x8_clk_data = { ++ .clk_base = mt76x8_clks_base, ++ .num_clk_base = ARRAY_SIZE(mt76x8_clks_base), ++ .clk_fixed = mt76x8_fixed_clocks, ++ .num_clk_fixed = ARRAY_SIZE(mt76x8_fixed_clocks), ++ .clk_factor = rt305x_factor_clocks, ++ .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks), ++ .clk_periph = mt76x8_pherip_clks, ++ .num_clk_periph = ARRAY_SIZE(mt76x8_pherip_clks), ++}; ++ ++static const struct of_device_id mtmips_of_match[] = { ++ { ++ .compatible = "ralink,rt2880-sysc", ++ .data = &rt2880_clk_data, ++ }, ++ { ++ .compatible = "ralink,rt3050-sysc", ++ .data = &rt305x_clk_data, ++ }, ++ { ++ .compatible = "ralink,rt3052-sysc", ++ .data = &rt305x_clk_data, ++ }, ++ { ++ .compatible = "ralink,rt3352-sysc", ++ .data = &rt3352_clk_data, ++ }, ++ { ++ .compatible = "ralink,rt3883-sysc", ++ .data = &rt3883_clk_data, ++ }, ++ { ++ .compatible = "ralink,rt5350-sysc", ++ .data = &rt5350_clk_data, ++ }, ++ { ++ .compatible = "ralink,mt7620-sysc", ++ .data = &mt7620_clk_data, ++ }, ++ { ++ .compatible = "ralink,mt7628-sysc", ++ .data = &mt76x8_clk_data, ++ }, ++ { ++ .compatible = "ralink,mt7688-sysc", ++ .data = &mt76x8_clk_data, ++ }, ++ {} ++}; ++ ++static void __init mtmips_clk_regs_init(struct device_node *node, ++ struct mtmips_clk_priv *priv) ++{ ++ u32 t; ++ ++ if (!of_device_is_compatible(node, "ralink,mt7620-sysc")) ++ return; ++ ++ /* ++ * When the CPU goes into sleep mode, the BUS ++ * clock will be too low for USB to function properly. ++ * Adjust the busses fractional divider to fix this ++ */ ++ regmap_read(priv->sysc, SYSC_REG_CPU_SYS_CLKCFG, &t); ++ t &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK); ++ t |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL; ++ regmap_write(priv->sysc, SYSC_REG_CPU_SYS_CLKCFG, t); ++} ++ ++static void __init mtmips_clk_init(struct device_node *node) ++{ ++ const struct of_device_id *match; ++ const struct mtmips_clk_data *data; ++ struct mtmips_clk_priv *priv; ++ struct clk_hw_onecell_data *clk_data; ++ int ret, i, count; ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return; ++ ++ priv->sysc = syscon_node_to_regmap(node); ++ if (IS_ERR(priv->sysc)) { ++ pr_err("Could not get sysc syscon regmap\n"); ++ goto free_clk_priv; ++ } ++ ++ mtmips_clk_regs_init(node, priv); ++ ++ match = of_match_node(mtmips_of_match, node); ++ if (WARN_ON(!match)) ++ return; ++ ++ data = match->data; ++ priv->data = data; ++ count = priv->data->num_clk_base + priv->data->num_clk_fixed + ++ priv->data->num_clk_factor + priv->data->num_clk_periph; ++ clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL); ++ if (!clk_data) ++ goto free_clk_priv; ++ ++ ret = mtmips_register_clocks(node, clk_data, priv); ++ if (ret) { ++ pr_err("Couldn't register top clocks\n"); ++ goto free_clk_data; ++ } ++ ++ ret = mtmips_register_fixed_clocks(clk_data, priv); ++ if (ret) { ++ pr_err("Couldn't register fixed clocks\n"); ++ goto unreg_clk_top; ++ } ++ ++ ret = mtmips_register_factor_clocks(clk_data, priv); ++ if (ret) { ++ pr_err("Couldn't register factor clocks\n"); ++ goto unreg_clk_fixed; ++ } ++ ++ ret = mtmips_register_pherip_clocks(node, clk_data, priv); ++ if (ret) { ++ pr_err("Couldn't register peripheral clocks\n"); ++ goto unreg_clk_factor; ++ } ++ ++ clk_data->num = count; ++ ++ ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); ++ if (ret) { ++ pr_err("Couldn't add clk hw provider\n"); ++ goto unreg_clk_periph; ++ } ++ ++ return; ++ ++unreg_clk_periph: ++ for (i = 0; i < priv->data->num_clk_periph; i++) { ++ struct mtmips_clk *sclk = &priv->data->clk_periph[i]; ++ ++ clk_hw_unregister(&sclk->hw); ++ } ++ ++unreg_clk_factor: ++ for (i = 0; i < priv->data->num_clk_factor; i++) { ++ struct mtmips_clk_factor *sclk = &priv->data->clk_factor[i]; ++ ++ clk_hw_unregister_fixed_factor(sclk->hw); ++ } ++ ++unreg_clk_fixed: ++ for (i = 0; i < priv->data->num_clk_fixed; i++) { ++ struct mtmips_clk_fixed *sclk = &priv->data->clk_fixed[i]; ++ ++ clk_hw_unregister_fixed_rate(sclk->hw); ++ } ++ ++unreg_clk_top: ++ for (i = 0; i < priv->data->num_clk_base; i++) { ++ struct mtmips_clk *sclk = &priv->data->clk_base[i]; ++ ++ clk_hw_unregister(&sclk->hw); ++ } ++ ++free_clk_data: ++ kfree(clk_data); ++ ++free_clk_priv: ++ kfree(priv); ++} ++CLK_OF_DECLARE_DRIVER(rt2880_clk, "ralink,rt2880-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(rt3050_clk, "ralink,rt3050-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(rt3052_clk, "ralink,rt3052-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(rt3352_clk, "ralink,rt3352-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(rt3883_clk, "ralink,rt3883-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(rt5350_clk, "ralink,rt5350-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(mt7620_clk, "ralink,mt7620-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(mt7628_clk, "ralink,mt7628-sysc", mtmips_clk_init); ++CLK_OF_DECLARE_DRIVER(mt7688_clk, "ralink,mt7688-sysc", mtmips_clk_init); ++ ++struct mtmips_rst { ++ struct reset_controller_dev rcdev; ++ struct regmap *sysc; ++}; ++ ++static struct mtmips_rst *to_mtmips_rst(struct reset_controller_dev *dev) ++{ ++ return container_of(dev, struct mtmips_rst, rcdev); ++} ++ ++static int mtmips_assert_device(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mtmips_rst *data = to_mtmips_rst(rcdev); ++ struct regmap *sysc = data->sysc; ++ ++ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id)); ++} ++ ++static int mtmips_deassert_device(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mtmips_rst *data = to_mtmips_rst(rcdev); ++ struct regmap *sysc = data->sysc; ++ ++ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0); ++} ++ ++static int mtmips_reset_device(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = mtmips_assert_device(rcdev, id); ++ if (ret < 0) ++ return ret; ++ ++ return mtmips_deassert_device(rcdev, id); ++} ++ ++static int mtmips_rst_xlate(struct reset_controller_dev *rcdev, ++ const struct of_phandle_args *reset_spec) ++{ ++ unsigned long id = reset_spec->args[0]; ++ ++ if (id == 0 || id >= rcdev->nr_resets) ++ return -EINVAL; ++ ++ return id; ++} ++ ++static const struct reset_control_ops reset_ops = { ++ .reset = mtmips_reset_device, ++ .assert = mtmips_assert_device, ++ .deassert = mtmips_deassert_device ++}; ++ ++static int mtmips_reset_init(struct device *dev, struct regmap *sysc) ++{ ++ struct mtmips_rst *rst_data; ++ ++ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); ++ if (!rst_data) ++ return -ENOMEM; ++ ++ rst_data->sysc = sysc; ++ rst_data->rcdev.ops = &reset_ops; ++ rst_data->rcdev.owner = THIS_MODULE; ++ rst_data->rcdev.nr_resets = 32; ++ rst_data->rcdev.of_reset_n_cells = 1; ++ rst_data->rcdev.of_xlate = mtmips_rst_xlate; ++ rst_data->rcdev.of_node = dev_of_node(dev); ++ ++ return devm_reset_controller_register(dev, &rst_data->rcdev); ++} ++ ++static int mtmips_clk_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device *dev = &pdev->dev; ++ struct mtmips_clk_priv *priv; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->sysc = syscon_node_to_regmap(np); ++ if (IS_ERR(priv->sysc)) ++ return dev_err_probe(dev, PTR_ERR(priv->sysc), ++ "Could not get sysc syscon regmap\n"); ++ ++ ret = mtmips_reset_init(dev, priv->sysc); ++ if (ret) ++ return dev_err_probe(dev, ret, "Could not init reset controller\n"); ++ ++ return 0; ++} ++ ++static const struct of_device_id mtmips_clk_of_match[] = { ++ { .compatible = "ralink,rt2880-reset" }, ++ { .compatible = "ralink,rt2880-sysc" }, ++ { .compatible = "ralink,rt3050-sysc" }, ++ { .compatible = "ralink,rt3052-sysc" }, ++ { .compatible = "ralink,rt3352-sysc" }, ++ { .compatible = "ralink,rt3883-sysc" }, ++ { .compatible = "ralink,rt5350-sysc" }, ++ { .compatible = "ralink,mt7620-sysc" }, ++ { .compatible = "ralink,mt7628-sysc" }, ++ { .compatible = "ralink,mt7688-sysc" }, ++ {} ++}; ++ ++static struct platform_driver mtmips_clk_driver = { ++ .probe = mtmips_clk_probe, ++ .driver = { ++ .name = "mtmips-clk", ++ .of_match_table = mtmips_clk_of_match, ++ }, ++}; ++ ++static int __init mtmips_clk_reset_init(void) ++{ ++ return platform_driver_register(&mtmips_clk_driver); ++} ++arch_initcall(mtmips_clk_reset_init); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-03-mips-ralink-rt288x-remove-clock-related-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-03-mips-ralink-rt288x-remove-clock-related-code.patch new file mode 100644 index 0000000000..df4208b23d --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-03-mips-ralink-rt288x-remove-clock-related-code.patch @@ -0,0 +1,81 @@ +From ffcdf47379eae86dc8f8f02c62994dacf2c9038e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:35 +0200 +Subject: [PATCH 3/9] mips: ralink: rt288x: remove clock related code + +A properly clock driver for ralink SoCs has been added. Hence there is no +need to have clock related code in 'arch/mips/ralink' folder anymore. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/include/asm/mach-ralink/rt288x.h | 10 ---------- + arch/mips/ralink/rt288x.c | 31 ------------------------------ + 2 files changed, 41 deletions(-) + +--- a/arch/mips/include/asm/mach-ralink/rt288x.h ++++ b/arch/mips/include/asm/mach-ralink/rt288x.h +@@ -17,7 +17,6 @@ + #define SYSC_REG_CHIP_NAME1 0x04 + #define SYSC_REG_CHIP_ID 0x0c + #define SYSC_REG_SYSTEM_CONFIG 0x10 +-#define SYSC_REG_CLKCFG 0x30 + + #define RT2880_CHIP_NAME0 0x38325452 + #define RT2880_CHIP_NAME1 0x20203038 +@@ -26,15 +25,6 @@ + #define CHIP_ID_ID_SHIFT 8 + #define CHIP_ID_REV_MASK 0xff + +-#define SYSTEM_CONFIG_CPUCLK_SHIFT 20 +-#define SYSTEM_CONFIG_CPUCLK_MASK 0x3 +-#define SYSTEM_CONFIG_CPUCLK_250 0x0 +-#define SYSTEM_CONFIG_CPUCLK_266 0x1 +-#define SYSTEM_CONFIG_CPUCLK_280 0x2 +-#define SYSTEM_CONFIG_CPUCLK_300 0x3 +- +-#define CLKCFG_SRAM_CS_N_WDT BIT(9) +- + #define RT2880_SDRAM_BASE 0x08000000 + #define RT2880_MEM_SIZE_MIN 2 + #define RT2880_MEM_SIZE_MAX 128 +--- a/arch/mips/ralink/rt288x.c ++++ b/arch/mips/ralink/rt288x.c +@@ -17,37 +17,6 @@ + + #include "common.h" + +-void __init ralink_clk_init(void) +-{ +- unsigned long cpu_rate, wmac_rate = 40000000; +- u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); +- t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); +- +- switch (t) { +- case SYSTEM_CONFIG_CPUCLK_250: +- cpu_rate = 250000000; +- break; +- case SYSTEM_CONFIG_CPUCLK_266: +- cpu_rate = 266666667; +- break; +- case SYSTEM_CONFIG_CPUCLK_280: +- cpu_rate = 280000000; +- break; +- case SYSTEM_CONFIG_CPUCLK_300: +- cpu_rate = 300000000; +- break; +- } +- +- ralink_clk_add("cpu", cpu_rate); +- ralink_clk_add("300100.timer", cpu_rate / 2); +- ralink_clk_add("300120.watchdog", cpu_rate / 2); +- ralink_clk_add("300500.uart", cpu_rate / 2); +- ralink_clk_add("300900.i2c", cpu_rate / 2); +- ralink_clk_add("300c00.uartlite", cpu_rate / 2); +- ralink_clk_add("400000.ethernet", cpu_rate / 2); +- ralink_clk_add("480000.wmac", wmac_rate); +-} +- + void __init ralink_of_remap(void) + { + rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc"); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-04-mips-ralink-rt305x-remove-clock-related-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-04-mips-ralink-rt305x-remove-clock-related-code.patch new file mode 100644 index 0000000000..12b4623b73 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-04-mips-ralink-rt305x-remove-clock-related-code.patch @@ -0,0 +1,145 @@ +From daf73c70f69386fb15960526772ef584a4efcaf2 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:36 +0200 +Subject: [PATCH 4/9] mips: ralink: rt305x: remove clock related code + +A properly clock driver for ralink SoCs has been added. Hence there is no +need to have clock related code in 'arch/mips/ralink' folder anymore. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/include/asm/mach-ralink/rt305x.h | 21 -------- + arch/mips/ralink/rt305x.c | 78 ------------------------------ + 2 files changed, 99 deletions(-) + +--- a/arch/mips/include/asm/mach-ralink/rt305x.h ++++ b/arch/mips/include/asm/mach-ralink/rt305x.h +@@ -66,26 +66,9 @@ static inline int soc_is_rt5350(void) + #define CHIP_ID_ID_SHIFT 8 + #define CHIP_ID_REV_MASK 0xff + +-#define RT305X_SYSCFG_CPUCLK_SHIFT 18 +-#define RT305X_SYSCFG_CPUCLK_MASK 0x1 +-#define RT305X_SYSCFG_CPUCLK_LOW 0x0 +-#define RT305X_SYSCFG_CPUCLK_HIGH 0x1 +- + #define RT305X_SYSCFG_SRAM_CS0_MODE_SHIFT 2 +-#define RT305X_SYSCFG_CPUCLK_MASK 0x1 + #define RT305X_SYSCFG_SRAM_CS0_MODE_WDT 0x1 + +-#define RT3352_SYSCFG0_CPUCLK_SHIFT 8 +-#define RT3352_SYSCFG0_CPUCLK_MASK 0x1 +-#define RT3352_SYSCFG0_CPUCLK_LOW 0x0 +-#define RT3352_SYSCFG0_CPUCLK_HIGH 0x1 +- +-#define RT5350_SYSCFG0_CPUCLK_SHIFT 8 +-#define RT5350_SYSCFG0_CPUCLK_MASK 0x3 +-#define RT5350_SYSCFG0_CPUCLK_360 0x0 +-#define RT5350_SYSCFG0_CPUCLK_320 0x2 +-#define RT5350_SYSCFG0_CPUCLK_300 0x3 +- + #define RT5350_SYSCFG0_DRAM_SIZE_SHIFT 12 + #define RT5350_SYSCFG0_DRAM_SIZE_MASK 7 + #define RT5350_SYSCFG0_DRAM_SIZE_2M 0 +@@ -116,13 +99,9 @@ static inline int soc_is_rt5350(void) + + #define RT3352_SYSC_REG_SYSCFG0 0x010 + #define RT3352_SYSC_REG_SYSCFG1 0x014 +-#define RT3352_SYSC_REG_CLKCFG1 0x030 + #define RT3352_SYSC_REG_RSTCTRL 0x034 + #define RT3352_SYSC_REG_USB_PS 0x05c + +-#define RT3352_CLKCFG0_XTAL_SEL BIT(20) +-#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18) +-#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20) + #define RT3352_RSTCTRL_UHST BIT(22) + #define RT3352_RSTCTRL_UDEV BIT(25) + #define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10) +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -53,84 +53,6 @@ static unsigned long rt5350_get_mem_size + return ret; + } + +-void __init ralink_clk_init(void) +-{ +- unsigned long cpu_rate, sys_rate, wdt_rate, uart_rate; +- unsigned long wmac_rate = 40000000; +- +- u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); +- +- if (soc_is_rt305x() || soc_is_rt3350()) { +- t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) & +- RT305X_SYSCFG_CPUCLK_MASK; +- switch (t) { +- case RT305X_SYSCFG_CPUCLK_LOW: +- cpu_rate = 320000000; +- break; +- case RT305X_SYSCFG_CPUCLK_HIGH: +- cpu_rate = 384000000; +- break; +- } +- sys_rate = uart_rate = wdt_rate = cpu_rate / 3; +- } else if (soc_is_rt3352()) { +- t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) & +- RT3352_SYSCFG0_CPUCLK_MASK; +- switch (t) { +- case RT3352_SYSCFG0_CPUCLK_LOW: +- cpu_rate = 384000000; +- break; +- case RT3352_SYSCFG0_CPUCLK_HIGH: +- cpu_rate = 400000000; +- break; +- } +- sys_rate = wdt_rate = cpu_rate / 3; +- uart_rate = 40000000; +- } else if (soc_is_rt5350()) { +- t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) & +- RT5350_SYSCFG0_CPUCLK_MASK; +- switch (t) { +- case RT5350_SYSCFG0_CPUCLK_360: +- cpu_rate = 360000000; +- sys_rate = cpu_rate / 3; +- break; +- case RT5350_SYSCFG0_CPUCLK_320: +- cpu_rate = 320000000; +- sys_rate = cpu_rate / 4; +- break; +- case RT5350_SYSCFG0_CPUCLK_300: +- cpu_rate = 300000000; +- sys_rate = cpu_rate / 3; +- break; +- default: +- BUG(); +- } +- uart_rate = 40000000; +- wdt_rate = sys_rate; +- } else { +- BUG(); +- } +- +- if (soc_is_rt3352() || soc_is_rt5350()) { +- u32 val = rt_sysc_r32(RT3352_SYSC_REG_SYSCFG0); +- +- if (!(val & RT3352_CLKCFG0_XTAL_SEL)) +- wmac_rate = 20000000; +- } +- +- ralink_clk_add("cpu", cpu_rate); +- ralink_clk_add("sys", sys_rate); +- ralink_clk_add("10000900.i2c", uart_rate); +- ralink_clk_add("10000a00.i2s", uart_rate); +- ralink_clk_add("10000b00.spi", sys_rate); +- ralink_clk_add("10000b40.spi", sys_rate); +- ralink_clk_add("10000100.timer", wdt_rate); +- ralink_clk_add("10000120.watchdog", wdt_rate); +- ralink_clk_add("10000500.uart", uart_rate); +- ralink_clk_add("10000c00.uartlite", uart_rate); +- ralink_clk_add("10100000.ethernet", sys_rate); +- ralink_clk_add("10180000.wmac", wmac_rate); +-} +- + void __init ralink_of_remap(void) + { + rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc"); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-05-mips-ralink-rt3883-remove-clock-related-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-05-mips-ralink-rt3883-remove-clock-related-code.patch new file mode 100644 index 0000000000..c13c4215f3 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-05-mips-ralink-rt3883-remove-clock-related-code.patch @@ -0,0 +1,85 @@ +From 7cd1bb48885449a9323c7ff0f10012925e93b4e1 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:37 +0200 +Subject: [PATCH 5/9] mips: ralink: rt3883: remove clock related code + +A properly clock driver for ralink SoCs has been added. Hence there is no +need to have clock related code in 'arch/mips/ralink' folder anymore. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/include/asm/mach-ralink/rt3883.h | 8 ------ + arch/mips/ralink/rt3883.c | 44 ------------------------------ + 2 files changed, 52 deletions(-) + +--- a/arch/mips/include/asm/mach-ralink/rt3883.h ++++ b/arch/mips/include/asm/mach-ralink/rt3883.h +@@ -90,14 +90,6 @@ + #define RT3883_REVID_VER_ID_SHIFT 8 + #define RT3883_REVID_ECO_ID_MASK 0x0f + +-#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17) +-#define RT3883_SYSCFG0_CPUCLK_SHIFT 8 +-#define RT3883_SYSCFG0_CPUCLK_MASK 0x3 +-#define RT3883_SYSCFG0_CPUCLK_250 0x0 +-#define RT3883_SYSCFG0_CPUCLK_384 0x1 +-#define RT3883_SYSCFG0_CPUCLK_480 0x2 +-#define RT3883_SYSCFG0_CPUCLK_500 0x3 +- + #define RT3883_SYSCFG1_USB0_HOST_MODE BIT(10) + #define RT3883_SYSCFG1_PCIE_RC_MODE BIT(8) + #define RT3883_SYSCFG1_PCI_HOST_MODE BIT(7) +--- a/arch/mips/ralink/rt3883.c ++++ b/arch/mips/ralink/rt3883.c +@@ -17,50 +17,6 @@ + + #include "common.h" + +-void __init ralink_clk_init(void) +-{ +- unsigned long cpu_rate, sys_rate; +- u32 syscfg0; +- u32 clksel; +- u32 ddr2; +- +- syscfg0 = rt_sysc_r32(RT3883_SYSC_REG_SYSCFG0); +- clksel = ((syscfg0 >> RT3883_SYSCFG0_CPUCLK_SHIFT) & +- RT3883_SYSCFG0_CPUCLK_MASK); +- ddr2 = syscfg0 & RT3883_SYSCFG0_DRAM_TYPE_DDR2; +- +- switch (clksel) { +- case RT3883_SYSCFG0_CPUCLK_250: +- cpu_rate = 250000000; +- sys_rate = (ddr2) ? 125000000 : 83000000; +- break; +- case RT3883_SYSCFG0_CPUCLK_384: +- cpu_rate = 384000000; +- sys_rate = (ddr2) ? 128000000 : 96000000; +- break; +- case RT3883_SYSCFG0_CPUCLK_480: +- cpu_rate = 480000000; +- sys_rate = (ddr2) ? 160000000 : 120000000; +- break; +- case RT3883_SYSCFG0_CPUCLK_500: +- cpu_rate = 500000000; +- sys_rate = (ddr2) ? 166000000 : 125000000; +- break; +- } +- +- ralink_clk_add("cpu", cpu_rate); +- ralink_clk_add("10000100.timer", sys_rate); +- ralink_clk_add("10000120.watchdog", sys_rate); +- ralink_clk_add("10000500.uart", 40000000); +- ralink_clk_add("10000900.i2c", 40000000); +- ralink_clk_add("10000a00.i2s", 40000000); +- ralink_clk_add("10000b00.spi", sys_rate); +- ralink_clk_add("10000b40.spi", sys_rate); +- ralink_clk_add("10000c00.uartlite", 40000000); +- ralink_clk_add("10100000.ethernet", sys_rate); +- ralink_clk_add("10180000.wmac", 40000000); +-} +- + void __init ralink_of_remap(void) + { + rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc"); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-06-mips-ralink-mt7620-remove-clock-related-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-06-mips-ralink-mt7620-remove-clock-related-code.patch new file mode 100644 index 0000000000..7b83cf54b4 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-06-mips-ralink-mt7620-remove-clock-related-code.patch @@ -0,0 +1,327 @@ +From 04b153abdfcbaba70ceef5a846067d4447fd0078 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:38 +0200 +Subject: [PATCH 6/9] mips: ralink: mt7620: remove clock related code + +A proper clock driver for ralink SoCs has been added. Hence there is no +need to have clock related code in 'arch/mips/ralink' folder anymore. +Since this is the last clock related code removal, remove also remaining +prototypes in 'common.h' header file. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/include/asm/mach-ralink/mt7620.h | 35 ----- + arch/mips/ralink/common.h | 3 - + arch/mips/ralink/mt7620.c | 226 ----------------------------- + 3 files changed, 264 deletions(-) + +--- a/arch/mips/include/asm/mach-ralink/mt7620.h ++++ b/arch/mips/include/asm/mach-ralink/mt7620.h +@@ -19,52 +19,17 @@ + #define SYSC_REG_CHIP_REV 0x0c + #define SYSC_REG_SYSTEM_CONFIG0 0x10 + #define SYSC_REG_SYSTEM_CONFIG1 0x14 +-#define SYSC_REG_CLKCFG0 0x2c +-#define SYSC_REG_CPU_SYS_CLKCFG 0x3c +-#define SYSC_REG_CPLL_CONFIG0 0x54 +-#define SYSC_REG_CPLL_CONFIG1 0x58 + + #define MT7620_CHIP_NAME0 0x3637544d + #define MT7620_CHIP_NAME1 0x20203032 + #define MT7628_CHIP_NAME1 0x20203832 + +-#define SYSCFG0_XTAL_FREQ_SEL BIT(6) +- + #define CHIP_REV_PKG_MASK 0x1 + #define CHIP_REV_PKG_SHIFT 16 + #define CHIP_REV_VER_MASK 0xf + #define CHIP_REV_VER_SHIFT 8 + #define CHIP_REV_ECO_MASK 0xf + +-#define CLKCFG0_PERI_CLK_SEL BIT(4) +- +-#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 16 +-#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf +-#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */ +-#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */ +-#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 8 +-#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f +-#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 0 +-#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f +- +-#define CPLL_CFG0_SW_CFG BIT(31) +-#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 16 +-#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x7 +-#define CPLL_CFG0_LC_CURFCK BIT(15) +-#define CPLL_CFG0_BYPASS_REF_CLK BIT(14) +-#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 10 +-#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x3 +- +-#define CPLL_CFG1_CPU_AUX1 BIT(25) +-#define CPLL_CFG1_CPU_AUX0 BIT(24) +- + #define SYSCFG0_DRAM_TYPE_MASK 0x3 + #define SYSCFG0_DRAM_TYPE_SHIFT 4 + #define SYSCFG0_DRAM_TYPE_SDRAM 0 +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -23,9 +23,6 @@ extern struct ralink_soc_info soc_info; + + extern void ralink_of_remap(void); + +-extern void ralink_clk_init(void); +-extern void ralink_clk_add(const char *dev, unsigned long rate); +- + extern void ralink_rst_init(void); + + extern void __init prom_soc_init(struct ralink_soc_info *soc_info); +--- a/arch/mips/ralink/mt7620.c ++++ b/arch/mips/ralink/mt7620.c +@@ -34,12 +34,6 @@ + #define PMU1_CFG 0x8C + #define DIG_SW_SEL BIT(25) + +-/* clock scaling */ +-#define CLKCFG_FDIV_MASK 0x1f00 +-#define CLKCFG_FDIV_USB_VAL 0x0300 +-#define CLKCFG_FFRAC_MASK 0x001f +-#define CLKCFG_FFRAC_USB_VAL 0x0003 +- + /* EFUSE bits */ + #define EFUSE_MT7688 0x100000 + +@@ -49,226 +43,6 @@ + /* does the board have sdram or ddram */ + static int dram_type; + +-static __init u32 +-mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div) +-{ +- u64 t; +- +- t = ref_rate; +- t *= mul; +- do_div(t, div); +- +- return t; +-} +- +-#define MHZ(x) ((x) * 1000 * 1000) +- +-static __init unsigned long +-mt7620_get_xtal_rate(void) +-{ +- u32 reg; +- +- reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0); +- if (reg & SYSCFG0_XTAL_FREQ_SEL) +- return MHZ(40); +- +- return MHZ(20); +-} +- +-static __init unsigned long +-mt7620_get_periph_rate(unsigned long xtal_rate) +-{ +- u32 reg; +- +- reg = rt_sysc_r32(SYSC_REG_CLKCFG0); +- if (reg & CLKCFG0_PERI_CLK_SEL) +- return xtal_rate; +- +- return MHZ(40); +-} +- +-static const u32 mt7620_clk_divider[] __initconst = { 2, 3, 4, 8 }; +- +-static __init unsigned long +-mt7620_get_cpu_pll_rate(unsigned long xtal_rate) +-{ +- u32 reg; +- u32 mul; +- u32 div; +- +- reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG0); +- if (reg & CPLL_CFG0_BYPASS_REF_CLK) +- return xtal_rate; +- +- if ((reg & CPLL_CFG0_SW_CFG) == 0) +- return MHZ(600); +- +- mul = (reg >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) & +- CPLL_CFG0_PLL_MULT_RATIO_MASK; +- mul += 24; +- if (reg & CPLL_CFG0_LC_CURFCK) +- mul *= 2; +- +- div = (reg >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) & +- CPLL_CFG0_PLL_DIV_RATIO_MASK; +- +- WARN_ON(div >= ARRAY_SIZE(mt7620_clk_divider)); +- +- return mt7620_calc_rate(xtal_rate, mul, mt7620_clk_divider[div]); +-} +- +-static __init unsigned long +-mt7620_get_pll_rate(unsigned long xtal_rate, unsigned long cpu_pll_rate) +-{ +- u32 reg; +- +- reg = rt_sysc_r32(SYSC_REG_CPLL_CONFIG1); +- if (reg & CPLL_CFG1_CPU_AUX1) +- return xtal_rate; +- +- if (reg & CPLL_CFG1_CPU_AUX0) +- return MHZ(480); +- +- return cpu_pll_rate; +-} +- +-static __init unsigned long +-mt7620_get_cpu_rate(unsigned long pll_rate) +-{ +- u32 reg; +- u32 mul; +- u32 div; +- +- reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG); +- +- mul = reg & CPU_SYS_CLKCFG_CPU_FFRAC_MASK; +- div = (reg >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) & +- CPU_SYS_CLKCFG_CPU_FDIV_MASK; +- +- return mt7620_calc_rate(pll_rate, mul, div); +-} +- +-static const u32 mt7620_ocp_dividers[16] __initconst = { +- [CPU_SYS_CLKCFG_OCP_RATIO_2] = 2, +- [CPU_SYS_CLKCFG_OCP_RATIO_3] = 3, +- [CPU_SYS_CLKCFG_OCP_RATIO_4] = 4, +- [CPU_SYS_CLKCFG_OCP_RATIO_5] = 5, +- [CPU_SYS_CLKCFG_OCP_RATIO_10] = 10, +-}; +- +-static __init unsigned long +-mt7620_get_dram_rate(unsigned long pll_rate) +-{ +- if (dram_type == SYSCFG0_DRAM_TYPE_SDRAM) +- return pll_rate / 4; +- +- return pll_rate / 3; +-} +- +-static __init unsigned long +-mt7620_get_sys_rate(unsigned long cpu_rate) +-{ +- u32 reg; +- u32 ocp_ratio; +- u32 div; +- +- reg = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG); +- +- ocp_ratio = (reg >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) & +- CPU_SYS_CLKCFG_OCP_RATIO_MASK; +- +- if (WARN_ON(ocp_ratio >= ARRAY_SIZE(mt7620_ocp_dividers))) +- return cpu_rate; +- +- div = mt7620_ocp_dividers[ocp_ratio]; +- if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio)) +- return cpu_rate; +- +- return cpu_rate / div; +-} +- +-void __init ralink_clk_init(void) +-{ +- unsigned long xtal_rate; +- unsigned long cpu_pll_rate; +- unsigned long pll_rate; +- unsigned long cpu_rate; +- unsigned long sys_rate; +- unsigned long dram_rate; +- unsigned long periph_rate; +- unsigned long pcmi2s_rate; +- +- xtal_rate = mt7620_get_xtal_rate(); +- +-#define RFMT(label) label ":%lu.%03luMHz " +-#define RINT(x) ((x) / 1000000) +-#define RFRAC(x) (((x) / 1000) % 1000) +- +- if (is_mt76x8()) { +- if (xtal_rate == MHZ(40)) +- cpu_rate = MHZ(580); +- else +- cpu_rate = MHZ(575); +- dram_rate = sys_rate = cpu_rate / 3; +- periph_rate = MHZ(40); +- pcmi2s_rate = MHZ(480); +- +- ralink_clk_add("10000d00.uartlite", periph_rate); +- ralink_clk_add("10000e00.uartlite", periph_rate); +- } else { +- cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); +- pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); +- +- cpu_rate = mt7620_get_cpu_rate(pll_rate); +- dram_rate = mt7620_get_dram_rate(pll_rate); +- sys_rate = mt7620_get_sys_rate(cpu_rate); +- periph_rate = mt7620_get_periph_rate(xtal_rate); +- pcmi2s_rate = periph_rate; +- +- pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), +- RINT(xtal_rate), RFRAC(xtal_rate), +- RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), +- RINT(pll_rate), RFRAC(pll_rate)); +- +- ralink_clk_add("10000500.uart", periph_rate); +- } +- +- pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), +- RINT(cpu_rate), RFRAC(cpu_rate), +- RINT(dram_rate), RFRAC(dram_rate), +- RINT(sys_rate), RFRAC(sys_rate), +- RINT(periph_rate), RFRAC(periph_rate)); +-#undef RFRAC +-#undef RINT +-#undef RFMT +- +- ralink_clk_add("cpu", cpu_rate); +- ralink_clk_add("10000100.timer", periph_rate); +- ralink_clk_add("10000120.watchdog", periph_rate); +- ralink_clk_add("10000900.i2c", periph_rate); +- ralink_clk_add("10000a00.i2s", pcmi2s_rate); +- ralink_clk_add("10000b00.spi", sys_rate); +- ralink_clk_add("10000b40.spi", sys_rate); +- ralink_clk_add("10000c00.uartlite", periph_rate); +- ralink_clk_add("10000d00.uart1", periph_rate); +- ralink_clk_add("10000e00.uart2", periph_rate); +- ralink_clk_add("10180000.wmac", xtal_rate); +- +- if (IS_ENABLED(CONFIG_USB) && !is_mt76x8()) { +- /* +- * When the CPU goes into sleep mode, the BUS clock will be +- * too low for USB to function properly. Adjust the busses +- * fractional divider to fix this +- */ +- u32 val = rt_sysc_r32(SYSC_REG_CPU_SYS_CLKCFG); +- +- val &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK); +- val |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL; +- +- rt_sysc_w32(val, SYSC_REG_CPU_SYS_CLKCFG); +- } +-} +- + void __init ralink_of_remap(void) + { + rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc"); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch new file mode 100644 index 0000000000..bdd9fcfd33 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch @@ -0,0 +1,121 @@ +From 201ddc05777cd8e084b508bcdda22214bfe2895e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:39 +0200 +Subject: [PATCH 7/9] mips: ralink: remove reset related code + +A proper clock driver for ralink SoCs has been added. This driver is also +a reset provider for the SoC. Hence there is no need to have reset related +code in 'arch/mips/ralink' folder anymore. The only code that remains is +the one related with mips_reboot_setup where a PCI reset is performed. +We maintain this because I cannot test old ralink board with PCI to be +sure all works if we remove also this code. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/ralink/common.h | 2 -- + arch/mips/ralink/of.c | 4 ---- + arch/mips/ralink/reset.c | 61 ----------------------------------------------- + 3 files changed, 67 deletions(-) + +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -23,8 +23,6 @@ extern struct ralink_soc_info soc_info; + + extern void ralink_of_remap(void); + +-extern void ralink_rst_init(void); +- + extern void __init prom_soc_init(struct ralink_soc_info *soc_info); + + __iomem void *plat_of_remap_node(const char *node); +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -95,10 +95,6 @@ static int __init plat_of_setup(void) + { + __dt_register_buses(soc_info.compatible, "palmbus"); + +- /* make sure that the reset controller is setup early */ +- if (ralink_soc != MT762X_SOC_MT7621AT) +- ralink_rst_init(); +- + return 0; + } + +--- a/arch/mips/ralink/reset.c ++++ b/arch/mips/ralink/reset.c +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + + #include + +@@ -22,66 +21,6 @@ + #define RSTCTL_RESET_PCI BIT(26) + #define RSTCTL_RESET_SYSTEM BIT(0) + +-static int ralink_assert_device(struct reset_controller_dev *rcdev, +- unsigned long id) +-{ +- u32 val; +- +- if (id == 0) +- return -1; +- +- val = rt_sysc_r32(SYSC_REG_RESET_CTRL); +- val |= BIT(id); +- rt_sysc_w32(val, SYSC_REG_RESET_CTRL); +- +- return 0; +-} +- +-static int ralink_deassert_device(struct reset_controller_dev *rcdev, +- unsigned long id) +-{ +- u32 val; +- +- if (id == 0) +- return -1; +- +- val = rt_sysc_r32(SYSC_REG_RESET_CTRL); +- val &= ~BIT(id); +- rt_sysc_w32(val, SYSC_REG_RESET_CTRL); +- +- return 0; +-} +- +-static int ralink_reset_device(struct reset_controller_dev *rcdev, +- unsigned long id) +-{ +- ralink_assert_device(rcdev, id); +- return ralink_deassert_device(rcdev, id); +-} +- +-static const struct reset_control_ops reset_ops = { +- .reset = ralink_reset_device, +- .assert = ralink_assert_device, +- .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, +-}; +- +-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); +-} +- + static void ralink_restart(char *command) + { + if (IS_ENABLED(CONFIG_PCI)) { diff --git a/target/linux/ramips/patches-6.1/005-v6.5-08-mips-ralink-get-cpu-rate-from-new-driver-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-08-mips-ralink-get-cpu-rate-from-new-driver-code.patch new file mode 100644 index 0000000000..2430c1f375 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-08-mips-ralink-get-cpu-rate-from-new-driver-code.patch @@ -0,0 +1,102 @@ +From ad38c17b0c26ae2108b50ac1eb0281a2e1ce08e9 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:40 +0200 +Subject: [PATCH 8/9] mips: ralink: get cpu rate from new driver code + +At very early stage on boot, there is a need to set 'mips_hpt_frequency'. +This timer frequency is a half of the CPU frequency. To get clocks properly +set we need to call to 'of_clk_init()' and properly get cpu clock frequency +afterwards. Depending on the SoC, CPU clock index and compatible differs, so +use them to get the proper clock frm the clock provider. Hence, adapt code +to be aligned with new clock driver. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/ralink/clk.c | 61 ++++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 52 insertions(+), 9 deletions(-) + +--- a/arch/mips/ralink/clk.c ++++ b/arch/mips/ralink/clk.c +@@ -11,29 +11,72 @@ + #include + #include + #include ++#include + + #include + + #include "common.h" + +-void ralink_clk_add(const char *dev, unsigned long rate) ++static const char *clk_cpu(int *idx) + { +- struct clk *clk = clk_register_fixed_rate(NULL, dev, NULL, 0, rate); +- +- if (!clk) +- panic("failed to add clock"); +- +- clkdev_create(clk, NULL, "%s", dev); ++ switch (ralink_soc) { ++ case RT2880_SOC: ++ *idx = 0; ++ return "ralink,rt2880-sysc"; ++ case RT3883_SOC: ++ *idx = 0; ++ return "ralink,rt3883-sysc"; ++ case RT305X_SOC_RT3050: ++ *idx = 0; ++ return "ralink,rt3050-sysc"; ++ case RT305X_SOC_RT3052: ++ *idx = 0; ++ return "ralink,rt3052-sysc"; ++ case RT305X_SOC_RT3350: ++ *idx = 1; ++ return "ralink,rt3350-sysc"; ++ case RT305X_SOC_RT3352: ++ *idx = 1; ++ return "ralink,rt3352-sysc"; ++ case RT305X_SOC_RT5350: ++ *idx = 1; ++ return "ralink,rt5350-sysc"; ++ case MT762X_SOC_MT7620A: ++ *idx = 2; ++ return "ralink,mt7620-sysc"; ++ case MT762X_SOC_MT7620N: ++ *idx = 2; ++ return "ralink,mt7620-sysc"; ++ case MT762X_SOC_MT7628AN: ++ *idx = 1; ++ return "ralink,mt7628-sysc"; ++ case MT762X_SOC_MT7688: ++ *idx = 1; ++ return "ralink,mt7688-sysc"; ++ default: ++ *idx = -1; ++ return "invalid"; ++ } + } + + void __init plat_time_init(void) + { ++ struct of_phandle_args clkspec; ++ const char *compatible; + struct clk *clk; ++ int cpu_clk_idx; + + ralink_of_remap(); + +- ralink_clk_init(); +- clk = clk_get_sys("cpu", NULL); ++ compatible = clk_cpu(&cpu_clk_idx); ++ if (cpu_clk_idx == -1) ++ panic("unable to get CPU clock index"); ++ ++ of_clk_init(NULL); ++ clkspec.np = of_find_compatible_node(NULL, NULL, compatible); ++ clkspec.args_count = 1; ++ clkspec.args[0] = cpu_clk_idx; ++ clk = of_clk_get_from_provider(&clkspec); + if (IS_ERR(clk)) + panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); + pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch b/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch new file mode 100644 index 0000000000..d05c1954f7 --- /dev/null +++ b/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch @@ -0,0 +1,28 @@ +From fc15a7193a4d37d79e873fa06cc423180ddd2ddf Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Mon, 19 Jun 2023 06:09:41 +0200 +Subject: [PATCH 9/9] MAINTAINERS: add Mediatek MTMIPS Clock maintainer + +Adding myself as maintainer for Mediatek MTMIPS clock driver. + +Signed-off-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + MAINTAINERS | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -11859,6 +11859,12 @@ S: Maintained + F: Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml + F: drivers/clk/ralink/clk-mt7621.c + ++MEDIATEK MTMIPS CLOCK DRIVER ++M: Sergio Paracuellos ++S: Maintained ++F: Documentation/devicetree/bindings/clock/mediatek,mtmips-sysc.yaml ++F: drivers/clk/ralink/clk-mtmips.c ++ + MEDIATEK MT7621/28/88 I2C DRIVER + M: Stefan Roese + L: linux-i2c@vger.kernel.org diff --git a/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch b/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch new file mode 100644 index 0000000000..429b9feb9d --- /dev/null +++ b/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch @@ -0,0 +1,189 @@ +From fd99ac5055d4705e91c73d1adba18bc71c8511a8 Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Tue, 20 Jun 2023 19:44:32 +0800 +Subject: [PATCH] mips: ralink: introduce commonly used remap node function + +The ralink_of_remap() function is repeated several times on SoC specific +source files. They have the same structure, but just differ in compatible +strings. In order to make commonly use of these codes, this patch +introduces a newly designed mtmips_of_remap_node() function to match and +remap all supported system controller and memory controller nodes. + +Build and run tested on MT7620 and MT7628. + +Signed-off-by: Shiji Yang +Reviewed-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/ralink/common.h | 2 -- + arch/mips/ralink/mt7620.c | 9 --------- + arch/mips/ralink/mt7621.c | 9 --------- + arch/mips/ralink/of.c | 42 +++++++++++++++++++++++++++++++++++------- + arch/mips/ralink/rt288x.c | 9 --------- + arch/mips/ralink/rt305x.c | 9 --------- + arch/mips/ralink/rt3883.c | 9 --------- + 7 files changed, 35 insertions(+), 54 deletions(-) + +--- a/arch/mips/ralink/common.h ++++ b/arch/mips/ralink/common.h +@@ -25,6 +25,4 @@ extern void ralink_of_remap(void); + + extern void __init prom_soc_init(struct ralink_soc_info *soc_info); + +-__iomem void *plat_of_remap_node(const char *node); +- + #endif /* _RALINK_COMMON_H__ */ +--- a/arch/mips/ralink/mt7620.c ++++ b/arch/mips/ralink/mt7620.c +@@ -43,15 +43,6 @@ + /* does the board have sdram or ddram */ + static int dram_type; + +-void __init ralink_of_remap(void) +-{ +- rt_sysc_membase = plat_of_remap_node("ralink,mt7620a-sysc"); +- rt_memc_membase = plat_of_remap_node("ralink,mt7620a-memc"); +- +- if (!rt_sysc_membase || !rt_memc_membase) +- panic("Failed to remap core resources"); +-} +- + static __init void + mt7620_dram_init(struct ralink_soc_info *soc_info) + { +--- a/arch/mips/ralink/mt7621.c ++++ b/arch/mips/ralink/mt7621.c +@@ -58,15 +58,6 @@ static void __init mt7621_memory_detect( + memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE); + } + +-void __init ralink_of_remap(void) +-{ +- rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc"); +- rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc"); +- +- if (!rt_sysc_membase || !rt_memc_membase) +- panic("Failed to remap core resources"); +-} +- + static unsigned int __init mt7621_get_soc_name0(void) + { + return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0); +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -29,26 +29,56 @@ __iomem void *rt_sysc_membase; + __iomem void *rt_memc_membase; + EXPORT_SYMBOL_GPL(rt_sysc_membase); + +-__iomem void *plat_of_remap_node(const char *node) ++static const struct of_device_id mtmips_memc_match[] = { ++ { .compatible = "mediatek,mt7621-memc" }, ++ { .compatible = "ralink,mt7620a-memc" }, ++ { .compatible = "ralink,rt2880-memc" }, ++ { .compatible = "ralink,rt3050-memc" }, ++ { .compatible = "ralink,rt3883-memc" }, ++ {} ++}; ++ ++static const struct of_device_id mtmips_sysc_match[] = { ++ { .compatible = "mediatek,mt7621-sysc" }, ++ { .compatible = "ralink,mt7620a-sysc" }, ++ { .compatible = "ralink,rt2880-sysc" }, ++ { .compatible = "ralink,rt3050-sysc" }, ++ { .compatible = "ralink,rt3883-sysc" }, ++ {} ++}; ++ ++static __iomem void * ++mtmips_of_remap_node(const struct of_device_id *match, const char *type) + { + struct resource res; + struct device_node *np; + +- np = of_find_compatible_node(NULL, NULL, node); ++ np = of_find_matching_node(NULL, match); + if (!np) +- panic("Failed to find %s node", node); ++ panic("Failed to find %s controller node", type); + + if (of_address_to_resource(np, 0, &res)) +- panic("Failed to get resource for %s", node); ++ panic("Failed to get resource for %s node", np->name); + + if (!request_mem_region(res.start, + resource_size(&res), + res.name)) +- panic("Failed to request resources for %s", node); ++ panic("Failed to request resources for %s node", np->name); ++ ++ of_node_put(np); + + return ioremap(res.start, resource_size(&res)); + } + ++void __init ralink_of_remap(void) ++{ ++ rt_sysc_membase = mtmips_of_remap_node(mtmips_sysc_match, "system"); ++ rt_memc_membase = mtmips_of_remap_node(mtmips_memc_match, "memory"); ++ ++ if (!rt_sysc_membase || !rt_memc_membase) ++ panic("Failed to remap core resources"); ++} ++ + void __init device_tree_init(void) + { + unflatten_and_copy_device_tree(); +--- a/arch/mips/ralink/rt288x.c ++++ b/arch/mips/ralink/rt288x.c +@@ -17,15 +17,6 @@ + + #include "common.h" + +-void __init ralink_of_remap(void) +-{ +- rt_sysc_membase = plat_of_remap_node("ralink,rt2880-sysc"); +- rt_memc_membase = plat_of_remap_node("ralink,rt2880-memc"); +- +- if (!rt_sysc_membase || !rt_memc_membase) +- panic("Failed to remap core resources"); +-} +- + void __init prom_soc_init(struct ralink_soc_info *soc_info) + { + void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT2880_SYSC_BASE); +--- a/arch/mips/ralink/rt305x.c ++++ b/arch/mips/ralink/rt305x.c +@@ -53,15 +53,6 @@ static unsigned long rt5350_get_mem_size + return ret; + } + +-void __init ralink_of_remap(void) +-{ +- rt_sysc_membase = plat_of_remap_node("ralink,rt3050-sysc"); +- rt_memc_membase = plat_of_remap_node("ralink,rt3050-memc"); +- +- if (!rt_sysc_membase || !rt_memc_membase) +- panic("Failed to remap core resources"); +-} +- + void __init prom_soc_init(struct ralink_soc_info *soc_info) + { + void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); +--- a/arch/mips/ralink/rt3883.c ++++ b/arch/mips/ralink/rt3883.c +@@ -17,15 +17,6 @@ + + #include "common.h" + +-void __init ralink_of_remap(void) +-{ +- rt_sysc_membase = plat_of_remap_node("ralink,rt3883-sysc"); +- rt_memc_membase = plat_of_remap_node("ralink,rt3883-memc"); +- +- if (!rt_sysc_membase || !rt_memc_membase) +- panic("Failed to remap core resources"); +-} +- + void __init prom_soc_init(struct ralink_soc_info *soc_info) + { + void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT3883_SYSC_BASE); diff --git a/target/linux/ramips/patches-6.1/007-v6.5-clk-ralink-mtmips-Fix-uninitialized-use-of-ret-in-mt.patch b/target/linux/ramips/patches-6.1/007-v6.5-clk-ralink-mtmips-Fix-uninitialized-use-of-ret-in-mt.patch new file mode 100644 index 0000000000..c0c2a6e204 --- /dev/null +++ b/target/linux/ramips/patches-6.1/007-v6.5-clk-ralink-mtmips-Fix-uninitialized-use-of-ret-in-mt.patch @@ -0,0 +1,56 @@ +From 6e68dae946e3a0333fbde5487ce163142ca10ae0 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Thu, 22 Jun 2023 15:56:19 +0000 +Subject: clk: ralink: mtmips: Fix uninitialized use of ret in + mtmips_register_{fixed,factor}_clocks() + +Clang warns: + + drivers/clk/ralink/clk-mtmips.c:309:9: error: variable 'ret' is uninitialized when used here [-Werror,-Wuninitialized] + 309 | return ret; + | ^~~ + drivers/clk/ralink/clk-mtmips.c:285:9: note: initialize the variable 'ret' to silence this warning + 285 | int ret, i; + | ^ + | = 0 + drivers/clk/ralink/clk-mtmips.c:359:9: error: variable 'ret' is uninitialized when used here [-Werror,-Wuninitialized] + 359 | return ret; + | ^~~ + drivers/clk/ralink/clk-mtmips.c:335:9: note: initialize the variable 'ret' to silence this warning + 335 | int ret, i; + | ^ + | = 0 + 2 errors generated. + +Set ret to the return value of clk_hw_register_fixed_rate() using the +PTR_ERR() macro, which ensures ret is not used uninitialized, clearing +up the warning. + +Fixes: 6f3b15586eef ("clk: ralink: add clock and reset driver for MTMIPS SoCs") +Closes: https://github.com/ClangBuiltLinux/linux/issues/1879 +Signed-off-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Acked-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + drivers/clk/ralink/clk-mtmips.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/clk/ralink/clk-mtmips.c ++++ b/drivers/clk/ralink/clk-mtmips.c +@@ -292,6 +292,7 @@ static int mtmips_register_fixed_clocks( + sclk->parent, 0, + sclk->rate); + if (IS_ERR(sclk->hw)) { ++ ret = PTR_ERR(sclk->hw); + pr_err("Couldn't register fixed clock %d\n", idx); + goto err_clk_unreg; + } +@@ -342,6 +343,7 @@ static int mtmips_register_factor_clocks + sclk->parent, sclk->flags, + sclk->mult, sclk->div); + if (IS_ERR(sclk->hw)) { ++ ret = PTR_ERR(sclk->hw); + pr_err("Couldn't register factor clock %d\n", idx); + goto err_clk_unreg; + } diff --git a/target/linux/ramips/patches-6.1/008-v6.5-mips-ralink-match-all-supported-system-controller-co.patch b/target/linux/ramips/patches-6.1/008-v6.5-mips-ralink-match-all-supported-system-controller-co.patch new file mode 100644 index 0000000000..6940a2b4b9 --- /dev/null +++ b/target/linux/ramips/patches-6.1/008-v6.5-mips-ralink-match-all-supported-system-controller-co.patch @@ -0,0 +1,40 @@ +From 670f77f76f650b1b341d31d009cc2fb03a4d1fcf Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Fri, 23 Jun 2023 08:17:48 +0800 +Subject: mips: ralink: match all supported system controller compatible + strings + +Recently, A new clock and reset controller driver has been introduced to +the ralink mips target[1]. It provides proper system control and adds more +SoC specific compatible strings. In order to better initialize CPUs, this +patch removes the outdated "ralink,mt7620a-sysc" and add all dt-binding +documented compatible strings to the system controller match table. + +[1] https://lore.kernel.org/all/20230619040941.1340372-1-sergio.paracuellos@gmail.com/ + +Signed-off-by: Shiji Yang +Reviewed-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/ralink/of.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -40,10 +40,15 @@ static const struct of_device_id mtmips_ + + static const struct of_device_id mtmips_sysc_match[] = { + { .compatible = "mediatek,mt7621-sysc" }, +- { .compatible = "ralink,mt7620a-sysc" }, ++ { .compatible = "ralink,mt7620-sysc" }, ++ { .compatible = "ralink,mt7628-sysc" }, ++ { .compatible = "ralink,mt7688-sysc" }, + { .compatible = "ralink,rt2880-sysc" }, + { .compatible = "ralink,rt3050-sysc" }, ++ { .compatible = "ralink,rt3052-sysc" }, ++ { .compatible = "ralink,rt3352-sysc" }, + { .compatible = "ralink,rt3883-sysc" }, ++ { .compatible = "ralink,rt5350-sysc" }, + {} + }; + diff --git a/target/linux/ramips/patches-6.1/009-v6.3-01-watchdog-mt7621-wdt-avoid-static-global-declarations.patch b/target/linux/ramips/patches-6.1/009-v6.3-01-watchdog-mt7621-wdt-avoid-static-global-declarations.patch new file mode 100644 index 0000000000..e06d5621e1 --- /dev/null +++ b/target/linux/ramips/patches-6.1/009-v6.3-01-watchdog-mt7621-wdt-avoid-static-global-declarations.patch @@ -0,0 +1,213 @@ +From 783c7cb4659b53b5e1b809dac5e8cdf250145919 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Tue, 14 Feb 2023 11:39:35 +0100 +Subject: [PATCH 1/2] watchdog: mt7621-wdt: avoid static global declarations + +Instead of using static global definitions in driver code, refactor code +introducing a new watchdog driver data structure and use it along the +code. + +Reviewed-by: Guenter Roeck +Signed-off-by: Sergio Paracuellos +Link: https://lore.kernel.org/r/20230214103936.1061078-5-sergio.paracuellos@gmail.com +[groeck: unsigned -> unsigned int] +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +--- + drivers/watchdog/mt7621_wdt.c | 102 +++++++++++++++++++++++++++--------------- + 1 file changed, 65 insertions(+), 37 deletions(-) + +--- a/drivers/watchdog/mt7621_wdt.c ++++ b/drivers/watchdog/mt7621_wdt.c +@@ -31,8 +31,11 @@ + #define TMR1CTL_RESTART BIT(9) + #define TMR1CTL_PRESCALE_SHIFT 16 + +-static void __iomem *mt7621_wdt_base; +-static struct reset_control *mt7621_wdt_reset; ++struct mt7621_wdt_data { ++ void __iomem *base; ++ struct reset_control *rst; ++ struct watchdog_device wdt; ++}; + + static bool nowayout = WATCHDOG_NOWAYOUT; + module_param(nowayout, bool, 0); +@@ -40,27 +43,31 @@ MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +-static inline void rt_wdt_w32(unsigned reg, u32 val) ++static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val) + { +- iowrite32(val, mt7621_wdt_base + reg); ++ iowrite32(val, base + reg); + } + +-static inline u32 rt_wdt_r32(unsigned reg) ++static inline u32 rt_wdt_r32(void __iomem *base, unsigned int reg) + { +- return ioread32(mt7621_wdt_base + reg); ++ return ioread32(base + reg); + } + + static int mt7621_wdt_ping(struct watchdog_device *w) + { +- rt_wdt_w32(TIMER_REG_TMRSTAT, TMR1CTL_RESTART); ++ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); ++ ++ rt_wdt_w32(drvdata->base, TIMER_REG_TMRSTAT, TMR1CTL_RESTART); + + return 0; + } + + static int mt7621_wdt_set_timeout(struct watchdog_device *w, unsigned int t) + { ++ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); ++ + w->timeout = t; +- rt_wdt_w32(TIMER_REG_TMR1LOAD, t * 1000); ++ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1LOAD, t * 1000); + mt7621_wdt_ping(w); + + return 0; +@@ -68,29 +75,31 @@ static int mt7621_wdt_set_timeout(struct + + static int mt7621_wdt_start(struct watchdog_device *w) + { ++ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); + u32 t; + + /* set the prescaler to 1ms == 1000us */ +- rt_wdt_w32(TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT); ++ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, 1000 << TMR1CTL_PRESCALE_SHIFT); + + mt7621_wdt_set_timeout(w, w->timeout); + +- t = rt_wdt_r32(TIMER_REG_TMR1CTL); ++ t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); + t |= TMR1CTL_ENABLE; +- rt_wdt_w32(TIMER_REG_TMR1CTL, t); ++ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); + + return 0; + } + + static int mt7621_wdt_stop(struct watchdog_device *w) + { ++ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); + u32 t; + + mt7621_wdt_ping(w); + +- t = rt_wdt_r32(TIMER_REG_TMR1CTL); ++ t = rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL); + t &= ~TMR1CTL_ENABLE; +- rt_wdt_w32(TIMER_REG_TMR1CTL, t); ++ rt_wdt_w32(drvdata->base, TIMER_REG_TMR1CTL, t); + + return 0; + } +@@ -105,7 +114,9 @@ static int mt7621_wdt_bootcause(void) + + static int mt7621_wdt_is_running(struct watchdog_device *w) + { +- return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE); ++ struct mt7621_wdt_data *drvdata = watchdog_get_drvdata(w); ++ ++ return !!(rt_wdt_r32(drvdata->base, TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE); + } + + static const struct watchdog_info mt7621_wdt_info = { +@@ -121,30 +132,39 @@ static const struct watchdog_ops mt7621_ + .set_timeout = mt7621_wdt_set_timeout, + }; + +-static struct watchdog_device mt7621_wdt_dev = { +- .info = &mt7621_wdt_info, +- .ops = &mt7621_wdt_ops, +- .min_timeout = 1, +- .max_timeout = 0xfffful / 1000, +-}; +- + static int mt7621_wdt_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +- mt7621_wdt_base = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(mt7621_wdt_base)) +- return PTR_ERR(mt7621_wdt_base); +- +- mt7621_wdt_reset = devm_reset_control_get_exclusive(dev, NULL); +- if (!IS_ERR(mt7621_wdt_reset)) +- reset_control_deassert(mt7621_wdt_reset); +- +- mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause(); +- +- watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout, +- dev); +- watchdog_set_nowayout(&mt7621_wdt_dev, nowayout); +- if (mt7621_wdt_is_running(&mt7621_wdt_dev)) { ++ struct watchdog_device *mt7621_wdt; ++ struct mt7621_wdt_data *drvdata; ++ int err; ++ ++ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); ++ if (!drvdata) ++ return -ENOMEM; ++ ++ drvdata->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(drvdata->base)) ++ return PTR_ERR(drvdata->base); ++ ++ drvdata->rst = devm_reset_control_get_exclusive(dev, NULL); ++ if (!IS_ERR(drvdata->rst)) ++ reset_control_deassert(drvdata->rst); ++ ++ mt7621_wdt = &drvdata->wdt; ++ mt7621_wdt->info = &mt7621_wdt_info; ++ mt7621_wdt->ops = &mt7621_wdt_ops; ++ mt7621_wdt->min_timeout = 1; ++ mt7621_wdt->max_timeout = 0xfffful / 1000; ++ mt7621_wdt->parent = dev; ++ ++ mt7621_wdt->bootstatus = mt7621_wdt_bootcause(); ++ ++ watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev); ++ watchdog_set_nowayout(mt7621_wdt, nowayout); ++ watchdog_set_drvdata(mt7621_wdt, drvdata); ++ ++ if (mt7621_wdt_is_running(mt7621_wdt)) { + /* + * Make sure to apply timeout from watchdog core, taking + * the prescaler of this driver here into account (the +@@ -154,17 +174,25 @@ static int mt7621_wdt_probe(struct platf + * we first disable the watchdog, set the new prescaler + * and timeout, and then re-enable the watchdog. + */ +- mt7621_wdt_stop(&mt7621_wdt_dev); +- mt7621_wdt_start(&mt7621_wdt_dev); +- set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status); ++ mt7621_wdt_stop(mt7621_wdt); ++ mt7621_wdt_start(mt7621_wdt); ++ set_bit(WDOG_HW_RUNNING, &mt7621_wdt->status); + } + +- return devm_watchdog_register_device(dev, &mt7621_wdt_dev); ++ err = devm_watchdog_register_device(dev, &drvdata->wdt); ++ if (err) ++ return err; ++ ++ platform_set_drvdata(pdev, drvdata); ++ ++ return 0; + } + + static void mt7621_wdt_shutdown(struct platform_device *pdev) + { +- mt7621_wdt_stop(&mt7621_wdt_dev); ++ struct mt7621_wdt_data *drvdata = platform_get_drvdata(pdev); ++ ++ mt7621_wdt_stop(&drvdata->wdt); + } + + static const struct of_device_id mt7621_wdt_match[] = { diff --git a/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch b/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch new file mode 100644 index 0000000000..8e6265404b --- /dev/null +++ b/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch @@ -0,0 +1,104 @@ +From ff8ec4ac39ad413b580d611dbf68e1d8a82eba56 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Tue, 14 Feb 2023 11:39:36 +0100 +Subject: [PATCH 2/2] watchdog: mt7621-wdt: avoid ralink architecture dependent code + +MT7621 SoC has a system controller node. Watchdog need to access to reset +status register. Ralink architecture and related driver are old and from +the beggining they are using some architecture dependent operations for +accessing this shared registers through 'asm/mach-ralink/ralink_regs.h' +header file. However this is not ideal from a driver perspective which can +just access to the system controller registers in an arch independent way +using regmap syscon APIs. Update Kconfig accordingly to select new added +dependencies and allow driver to be compile tested. + +Signed-off-by: Sergio Paracuellos +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20230214103936.1061078-6-sergio.paracuellos@gmail.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +--- + drivers/watchdog/Kconfig | 4 +++- + drivers/watchdog/mt7621_wdt.c | 22 +++++++++++++++++----- + 2 files changed, 20 insertions(+), 6 deletions(-) + +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -1799,7 +1799,9 @@ config RALINK_WDT + config MT7621_WDT + tristate "Mediatek SoC watchdog" + select WATCHDOG_CORE +- depends on SOC_MT7620 || SOC_MT7621 ++ select REGMAP_MMIO ++ select MFD_SYSCON ++ depends on SOC_MT7620 || SOC_MT7621 || COMPILE_TEST + help + Hardware driver for the Mediatek/Ralink MT7621/8 SoC Watchdog Timer. + +--- a/drivers/watchdog/mt7621_wdt.c ++++ b/drivers/watchdog/mt7621_wdt.c +@@ -15,8 +15,8 @@ + #include + #include + #include +- +-#include ++#include ++#include + + #define SYSC_RSTSTAT 0x38 + #define WDT_RST_CAUSE BIT(1) +@@ -34,6 +34,7 @@ + struct mt7621_wdt_data { + void __iomem *base; + struct reset_control *rst; ++ struct regmap *sysc; + struct watchdog_device wdt; + }; + +@@ -104,9 +105,12 @@ static int mt7621_wdt_stop(struct watchd + return 0; + } + +-static int mt7621_wdt_bootcause(void) ++static int mt7621_wdt_bootcause(struct mt7621_wdt_data *d) + { +- if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE) ++ u32 val; ++ ++ regmap_read(d->sysc, SYSC_RSTSTAT, &val); ++ if (val & WDT_RST_CAUSE) + return WDIOF_CARDRESET; + + return 0; +@@ -134,6 +138,7 @@ static const struct watchdog_ops mt7621_ + + static int mt7621_wdt_probe(struct platform_device *pdev) + { ++ struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct watchdog_device *mt7621_wdt; + struct mt7621_wdt_data *drvdata; +@@ -143,6 +148,13 @@ static int mt7621_wdt_probe(struct platf + if (!drvdata) + return -ENOMEM; + ++ drvdata->sysc = syscon_regmap_lookup_by_phandle(np, "mediatek,sysctl"); ++ if (IS_ERR(drvdata->sysc)) { ++ drvdata->sysc = syscon_regmap_lookup_by_compatible("mediatek,mt7621-sysc"); ++ if (IS_ERR(drvdata->sysc)) ++ return PTR_ERR(drvdata->sysc); ++ } ++ + drvdata->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(drvdata->base)) + return PTR_ERR(drvdata->base); +@@ -158,7 +170,7 @@ static int mt7621_wdt_probe(struct platf + mt7621_wdt->max_timeout = 0xfffful / 1000; + mt7621_wdt->parent = dev; + +- mt7621_wdt->bootstatus = mt7621_wdt_bootcause(); ++ mt7621_wdt->bootstatus = mt7621_wdt_bootcause(drvdata); + + watchdog_init_timeout(mt7621_wdt, mt7621_wdt->max_timeout, dev); + watchdog_set_nowayout(mt7621_wdt, nowayout); diff --git a/target/linux/ramips/patches-6.1/010-v6.5-01-mips-pci-mt7620-do-not-print-NFTS-register-value-as-.patch b/target/linux/ramips/patches-6.1/010-v6.5-01-mips-pci-mt7620-do-not-print-NFTS-register-value-as-.patch new file mode 100644 index 0000000000..704e861b82 --- /dev/null +++ b/target/linux/ramips/patches-6.1/010-v6.5-01-mips-pci-mt7620-do-not-print-NFTS-register-value-as-.patch @@ -0,0 +1,32 @@ +From 9f9a035e6156a57d9da062b26d2a48d031744a1e Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Tue, 20 Jun 2023 18:43:22 +0800 +Subject: [PATCH 1/2] mips: pci-mt7620: do not print NFTS register value as + error log + +These codes are used to read NFTS_TIMEOUT_DELAY register value and +write it into kernel log after writing the register. they are only +used for debugging during driver development, so there is no need +to keep them now. + +Tested on MT7628AN router Motorola MWR03. + +Signed-off-by: Shiji Yang +Reviewed-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/pci/pci-mt7620.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/arch/mips/pci/pci-mt7620.c ++++ b/arch/mips/pci/pci-mt7620.c +@@ -274,9 +274,6 @@ static int mt7628_pci_hw_init(struct pla + val |= 0x50 << 8; + pci_config_write(NULL, 0, 0x70c, 4, val); + +- pci_config_read(NULL, 0, 0x70c, 4, &val); +- dev_err(&pdev->dev, "Port 0 N_FTS = %x\n", (unsigned int) val); +- + return 0; + } + diff --git a/target/linux/ramips/patches-6.1/010-v6.5-02-mips-pci-mt7620-use-dev_info-to-log-PCIe-device-dete.patch b/target/linux/ramips/patches-6.1/010-v6.5-02-mips-pci-mt7620-use-dev_info-to-log-PCIe-device-dete.patch new file mode 100644 index 0000000000..5898a110ea --- /dev/null +++ b/target/linux/ramips/patches-6.1/010-v6.5-02-mips-pci-mt7620-use-dev_info-to-log-PCIe-device-dete.patch @@ -0,0 +1,39 @@ +From 89ec9bbe60b61cc6ae3eddd6d4f43e128f8a88de Mon Sep 17 00:00:00 2001 +From: Shiji Yang +Date: Tue, 20 Jun 2023 18:43:23 +0800 +Subject: [PATCH 2/2] mips: pci-mt7620: use dev_info() to log PCIe device + detection result + +Usually, We only need to print the error log when there is a PCIe card but +initialization fails. Whether the driver finds the PCIe card or not is the +expected behavior. So it's better to log these information with dev_info(). + +Tested on MT7628AN router Motorola MWR03. + +Signed-off-by: Shiji Yang +Reviewed-by: Sergio Paracuellos +Signed-off-by: Thomas Bogendoerfer +--- + arch/mips/pci/pci-mt7620.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/pci/pci-mt7620.c ++++ b/arch/mips/pci/pci-mt7620.c +@@ -331,7 +331,7 @@ static int mt7620_pci_probe(struct platf + rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1); + if (ralink_soc == MT762X_SOC_MT7620A) + rt_sysc_m32(LC_CKDRVPD, PDRV_SW_SET, PPLL_DRV); +- dev_err(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n"); ++ dev_info(&pdev->dev, "PCIE0 no card, disable it(RST&CLK)\n"); + return -1; + } + +@@ -374,7 +374,7 @@ int pcibios_map_irq(const struct pci_dev + dev->bus->number, slot); + return 0; + } +- dev_err(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n", ++ dev_info(&dev->dev, "card - bus=0x%x, slot = 0x%x irq=%d\n", + dev->bus->number, slot, irq); + + /* configure the cache line size to 0x14 */ diff --git a/target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch b/target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch new file mode 100644 index 0000000000..1c8c7cd3d0 --- /dev/null +++ b/target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch @@ -0,0 +1,1418 @@ +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,601 +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 { +- struct device *dev; +- void __iomem *base; +- 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_pcie_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_pcie_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_pcie_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_pcie_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_pcie_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_pcie_ops; +- host->sysdata = pcie; +- return pci_host_probe(host); +-} +- +-static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { +- { .soc_id = "mt7621", .revision = "E2" }, +- { /* sentinel */ } +-}; +- +-static int mt7621_pcie_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_pcie_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_pcie_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_pcie_ids[] = { +- { .compatible = "mediatek,mt7621-pci" }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); +- +-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_pcie_ids), +- }, +-}; +-builtin_platform_driver(mt7621_pcie_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-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch b/target/linux/ramips/patches-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch new file mode 100644 index 0000000000..916477511d --- /dev/null +++ b/target/linux/ramips/patches-6.1/101-v5.17-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-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch b/target/linux/ramips/patches-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch new file mode 100644 index 0000000000..815ecc7d37 --- /dev/null +++ b/target/linux/ramips/patches-6.1/102-v5.17-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-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch b/target/linux/ramips/patches-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch new file mode 100644 index 0000000000..4b46b3e3f6 --- /dev/null +++ b/target/linux/ramips/patches-6.1/103-v5.17-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 +@@ -25,6 +27,35 @@ + static u32 detect_magic __initdata; + static struct ralink_soc_info *soc_info_ptr; + ++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-6.1/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch b/target/linux/ramips/patches-6.1/104-v5.17-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-6.1/104-v5.17-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-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch b/target/linux/ramips/patches-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch new file mode 100644 index 0000000000..0323588e5a --- /dev/null +++ b/target/linux/ramips/patches-6.1/105-v5.17-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-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch b/target/linux/ramips/patches-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch new file mode 100644 index 0000000000..2fbbf9a7aa --- /dev/null +++ b/target/linux/ramips/patches-6.1/106-v5.17-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-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch b/target/linux/ramips/patches-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch new file mode 100644 index 0000000000..c055f0096d --- /dev/null +++ b/target/linux/ramips/patches-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch @@ -0,0 +1,38 @@ +From 19098934f910b4d47cb30251dd39ffa57bef9523 Mon Sep 17 00:00:00 2001 +From: John Thomson +Date: Tue, 6 Dec 2022 06:46:45 +1000 +Subject: [PATCH] PCI: mt7621: Add sentinel to quirks table + +Current driver is missing a sentinel in the struct soc_device_attribute +array, which causes an oops when assessed by the +soc_device_match(mt7621_pcie_quirks_match) call. + +This was only exposed once the CONFIG_SOC_MT7621 mt7621 soc_dev_attr +was fixed to register the SOC as a device, in: + +commit 7c18b64bba3b ("mips: ralink: mt7621: do not use kzalloc too early") + +Fix it by adding the required sentinel. + +Link: https://lore.kernel.org/lkml/26ebbed1-0fe9-4af9-8466-65f841d0b382@app.fastmail.com +Link: https://lore.kernel.org/r/20221205204645.301301-1-git@johnthomson.fastmail.com.au +Fixes: b483b4e4d3f6 ("staging: mt7621-pci: add quirks for 'E2' revision using 'soc_device_attribute'") +Signed-off-by: John Thomson +Signed-off-by: Lorenzo Pieralisi +Acked-by: Sergio Paracuellos +--- + drivers/pci/controller/pcie-mt7621.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(str + } + + static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { +- { .soc_id = "mt7621", .revision = "E2" } ++ { .soc_id = "mt7621", .revision = "E2" }, ++ { /* sentinel */ } + }; + + static int mt7621_pcie_probe(struct platform_device *pdev) diff --git a/target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch b/target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch new file mode 100644 index 0000000000..de1d4cfc12 --- /dev/null +++ b/target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch @@ -0,0 +1,52 @@ +From 0cb2a8f3456ff1cc51d571e287a48e8fddc98ec2 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Sat, 31 Dec 2022 08:40:41 +0100 +Subject: PCI: mt7621: Delay phy ports initialization + +Some devices like ZBT WE1326 and ZBT WF3526-P and some Netgear models need +to delay phy port initialization after calling the mt7621_pcie_init_port() +driver function to get into reliable boots for both warm and hard resets. + +The delay required to detect the ports seems to be in the range [75-100] +milliseconds. + +If the ports are not detected the controller is not functional. + +There is no datasheet or something similar to really understand why this +extra delay is needed only for these devices and it is not for most of +the boards that are built on mt7621 SoC. + +This issue has been reported by openWRT community and the complete +discussion is in [0]. The 100 milliseconds delay has been tested in all +devices to validate it. + +Add the extra 100 milliseconds delay to fix the issue. + +[0]: https://github.com/openwrt/openwrt/pull/11220 + +Link: https://lore.kernel.org/r/20221231074041.264738-1-sergio.paracuellos@gmail.com +Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +--- + drivers/pci/controller/pcie-mt7621.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -58,6 +58,7 @@ + #define PCIE_PORT_LINKUP BIT(0) + #define PCIE_PORT_CNT 3 + ++#define INIT_PORTS_DELAY_MS 100 + #define PERST_DELAY_MS 100 + + /** +@@ -374,6 +375,7 @@ static int mt7621_pcie_init_ports(struct + } + } + ++ msleep(INIT_PORTS_DELAY_MS); + mt7621_pcie_reset_ep_deassert(pcie); + + tmp = NULL; diff --git a/target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch b/target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch new file mode 100644 index 0000000000..a4543337ff --- /dev/null +++ b/target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch @@ -0,0 +1,31 @@ +From 3f6dfa25128e428acfba20792bc7506d58806baa Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sun, 7 May 2023 01:06:17 +0200 +Subject: [PATCH] drivers: mt7621-dma: handle error from device_reset + +Handle error from device reset to fix compilation warning. +Fix compilation warning: +drivers/staging/mt7621-dma/hsdma-mt7621.c: In function 'mtk_hsdma_probe': +drivers/staging/mt7621-dma/hsdma-mt7621.c:685:9: error: ignoring return value of 'device_reset' declared with attribute 'warn_unused_result' [-Werror=unused-result] + 685 | device_reset(&pdev->dev); + | ^~~~~~~~~~~~~~~~~~~~~~~~ +cc1: all warnings being treated as errors + +Signed-off-by: Christian Marangi +--- + drivers/staging/mt7621-dma/hsdma-mt7621.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/staging/mt7621-dma/hsdma-mt7621.c ++++ b/drivers/staging/mt7621-dma/hsdma-mt7621.c +@@ -682,7 +682,9 @@ static int mtk_hsdma_probe(struct platfo + return ret; + } + +- device_reset(&pdev->dev); ++ ret = device_reset(&pdev->dev); ++ if (ret) ++ dev_err(&pdev->dev, "failed to reset device\n"); + + dd = &hsdma->ddev; + dma_cap_set(DMA_MEMCPY, dd->cap_mask); diff --git a/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch b/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch new file mode 100644 index 0000000000..94519b9c01 --- /dev/null +++ b/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch @@ -0,0 +1,31 @@ +From 50233e105a0332ec0f3bc83180c416e6b200471e Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Fri, 24 Mar 2023 08:37:33 +0100 +Subject: PCI: mt7621: Use dev_info() to log PCIe card detection + +When there is no card plugged on a PCIe port a log reporting that +the port will be disabled is flagged as an error (dev_err()). + +Since this is not an error at all, change the log level by using +dev_info() instead. + +Link: https://lore.kernel.org/r/20230324073733.1596231-1-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +--- + drivers/pci/controller/pcie-mt7621.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -383,8 +383,8 @@ static int mt7621_pcie_init_ports(struct + u32 slot = port->slot; + + if (!mt7621_pcie_port_is_linkup(port)) { +- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", +- slot); ++ dev_info(dev, "pcie%d no card, disable it (RST & CLK)\n", ++ slot); + mt7621_control_assert(port); + port->enabled = false; + num_disabled++; diff --git a/target/linux/ramips/patches-6.1/200-add-ralink-eth.patch b/target/linux/ramips/patches-6.1/200-add-ralink-eth.patch new file mode 100644 index 0000000000..63c864ff7c --- /dev/null +++ b/target/linux/ramips/patches-6.1/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/pensando/Kc + source "drivers/net/ethernet/qlogic/Kconfig" + source "drivers/net/ethernet/brocade/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-6.1/300-mt7620-export-chip-version-and-pkg.patch b/target/linux/ramips/patches-6.1/300-mt7620-export-chip-version-and-pkg.patch new file mode 100644 index 0000000000..4f4fe9018a --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -61,4 +61,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-6.1/311-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch b/target/linux/ramips/patches-6.1/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-6.1/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-6.1/312-MIPS-ralink-add-cpu-frequency-scaling.patch b/target/linux/ramips/patches-6.1/312-MIPS-ralink-add-cpu-frequency-scaling.patch new file mode 100644 index 0000000000..0d70770941 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/314-MIPS-add-bootargs-override-property.patch b/target/linux/ramips/patches-6.1/314-MIPS-add-bootargs-override-property.patch new file mode 100644 index 0000000000..e7dca7af88 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -547,8 +547,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; + + /* +@@ -562,6 +582,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-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch b/target/linux/ramips/patches-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch new file mode 100644 index 0000000000..4f9eec7271 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -689,7 +689,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 +@@ -806,6 +805,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-6.1/316-arch-mips-do-not-select-illegal-access-driver-by-def.patch b/target/linux/ramips/patches-6.1/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-6.1/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-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch b/target/linux/ramips/patches-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch new file mode 100644 index 0000000000..0eb6676414 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/324-mt7621-perfctr-fix.patch b/target/linux/ramips/patches-6.1/324-mt7621-perfctr-fix.patch new file mode 100644 index 0000000000..dfeac7eb99 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/400-mtd-cfi-cmdset-0002-force-word-write.patch b/target/linux/ramips/patches-6.1/400-mtd-cfi-cmdset-0002-force-word-write.patch new file mode 100644 index 0000000000..7011bbe50b --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch b/target/linux/ramips/patches-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch new file mode 100644 index 0000000000..4cbb84efc6 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -1844,6 +1844,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-6.1/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-6.1/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-6.1/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-6.1/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch b/target/linux/ramips/patches-6.1/411-dt-bindings-add-documentation-for-mt7621-nand-driver.patch new file mode 100644 index 0000000000..3d122c10c0 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/700-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-6.1/700-net-ethernet-mediatek-support-net-labels.patch new file mode 100644 index 0000000000..d9fc379bed --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -4558,6 +4558,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; +@@ -4729,6 +4730,9 @@ static int mtk_add_mac(struct mtk_eth *e + register_netdevice_notifier(&mac->device_notifier); + } + ++ if (name) ++ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ); ++ + return 0; + + free_netdev: diff --git a/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch b/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch new file mode 100644 index 0000000000..1262e9498d --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -71,13 +71,13 @@ static void phy_process_state_change(str + + 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); + } + +@@ -591,7 +591,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); +@@ -662,7 +662,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); +@@ -734,7 +734,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; +@@ -1220,7 +1220,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 +@@ -1035,14 +1035,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 +@@ -1373,7 +1373,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 +@@ -716,7 +716,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-6.1/721-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch new file mode 100644 index 0000000000..fc7873a01b --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -734,7 +734,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; +@@ -1220,7 +1223,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 +@@ -630,6 +630,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-6.1/801-DT-Add-documentation-for-gpio-ralink.patch b/target/linux/ramips/patches-6.1/801-DT-Add-documentation-for-gpio-ralink.patch new file mode 100644 index 0000000000..93dabf8776 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-6.1/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-6.1/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-6.1/803-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch b/target/linux/ramips/patches-6.1/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-6.1/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-6.1/805-pinctrl-AW9523.patch b/target/linux/ramips/patches-6.1/805-pinctrl-AW9523.patch new file mode 100644 index 0000000000..34220acdd1 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/808-pinctrl-mtmips-support-requesting-different-function.patch b/target/linux/ramips/patches-6.1/808-pinctrl-mtmips-support-requesting-different-function.patch new file mode 100644 index 0000000000..047808f1e6 --- /dev/null +++ b/target/linux/ramips/patches-6.1/808-pinctrl-mtmips-support-requesting-different-function.patch @@ -0,0 +1,45 @@ +From: Shiji Yang +Date: Wed, 26 Jul 2023 01:32:55 +0800 +Subject: [PATCH] pinctrl: mtmips: support requesting different functions for + same group + +Sometimes pinctrl consumers may request different functions for the +same pin group in different situations. This patch can help to reset +the group function flag when requesting a different function. + +Signed-off-by: Shiji Yang +--- + drivers/pinctrl/ralink/pinctrl-ralink.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/pinctrl/ralink/pinctrl-ralink.c ++++ b/drivers/pinctrl/ralink/pinctrl-ralink.c +@@ -123,11 +123,24 @@ static int ralink_pmx_group_enable(struc + int i; + int shift; + +- /* dont allow double use */ ++ /* ++ * for the same pin group, if request a different function, ++ * then clear the group function flag and continue, else exit. ++ */ + if (p->groups[group].enabled) { +- dev_err(p->dev, "%s is already enabled\n", +- p->groups[group].name); +- return 0; ++ for (i = 0; i < p->groups[group].func_count; i++) { ++ if (p->groups[group].func[i].enabled == 1) { ++ if (!strcmp(p->func[func]->name, ++ p->groups[group].func[i].name)) ++ return 0; ++ p->groups[group].func[i].enabled = 0; ++ break; ++ } ++ } ++ ++ /* exit if request the "gpio" function again */ ++ if (i == p->groups[group].func_count && func == 0) ++ return 0; + } + + p->groups[group].enabled = 1; diff --git a/target/linux/ramips/patches-6.1/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-6.1/810-uvc-add-iPassion-iP2970-support.patch new file mode 100644 index 0000000000..88809ae68d --- /dev/null +++ b/target/linux/ramips/patches-6.1/810-uvc-add-iPassion-iP2970-support.patch @@ -0,0 +1,244 @@ +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 +@@ -3158,6 +3158,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 +@@ -224,6 +224,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; + } + +@@ -272,6 +273,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"); +@@ -1801,6 +1946,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 +@@ -210,6 +210,8 @@ + #define UVC_QUIRK_FORCE_Y8 0x00000800 + #define UVC_QUIRK_FORCE_BPP 0x00001000 + #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 ++#define UVC_QUIRK_MOTION 0x00004000 ++#define UVC_QUIRK_SINGLE_ISO 0x00008000 + + /* Format flags */ + #define UVC_FMT_FLAG_COMPRESSED 0x00000001 +@@ -701,6 +703,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-6.1/820-DT-Add-documentation-for-spi-rt2880.patch b/target/linux/ramips/patches-6.1/820-DT-Add-documentation-for-spi-rt2880.patch new file mode 100644 index 0000000000..e2643e3f25 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch new file mode 100644 index 0000000000..fa119ab211 --- /dev/null +++ b/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch @@ -0,0 +1,579 @@ +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 +@@ -718,6 +718,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,535 @@ ++/* ++ * 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) { ++ ret = device_reset(&pdev->dev); ++ if (ret) { ++ dev_err(&pdev->dev, "device_reset error.\n"); ++ goto err_master; ++ } ++ } ++ ++ 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-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch new file mode 100644 index 0000000000..da6f8e5a1e --- /dev/null +++ b/target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch @@ -0,0 +1,512 @@ +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,440 @@ ++/* ++ * 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) ++{ ++ int ret; ++ ++ ret = device_reset(i2c->adap.dev.parent); ++ if (ret) ++ dev_err(i2c->dev, "Failed to reset device"); ++ ++ 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-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch new file mode 100644 index 0000000000..9a0dbd7bb8 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -1095,3 +1095,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-6.1/835-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch new file mode 100644 index 0000000000..551fdd8b3c --- /dev/null +++ b/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch @@ -0,0 +1,1033 @@ +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,970 @@ ++/* ++ * 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_rate = 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); ++ ++ ret = device_reset(&pdev->dev); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to reset device\n"); ++ goto err_clk_disable; ++ } ++ ++ 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-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch b/target/linux/ramips/patches-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch new file mode 100644 index 0000000000..7148bb16f3 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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 +@@ -393,6 +393,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-6.1/845-pwm-add-mediatek-support.patch b/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch new file mode 100644 index 0000000000..06074d6031 --- /dev/null +++ b/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch @@ -0,0 +1,219 @@ +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,175 @@ ++/* ++ * 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]); ++ ++ pwmchip_remove(&pc->chip); ++ ++ return 0; ++} ++ ++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-6.1/850-awake-rt305x-dwc2-controller.patch b/target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch new file mode 100644 index 0000000000..5fb3664ae5 --- /dev/null +++ b/target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch @@ -0,0 +1,15 @@ +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -508,6 +508,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-6.1/855-linkit_bootstrap.patch b/target/linux/ramips/patches-6.1/855-linkit_bootstrap.patch new file mode 100644 index 0000000000..cd81601a72 --- /dev/null +++ b/target/linux/ramips/patches-6.1/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); diff --git a/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch b/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch new file mode 100644 index 0000000000..4008d5fe7c --- /dev/null +++ b/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch @@ -0,0 +1,3276 @@ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/Kconfig +@@ -0,0 +1,64 @@ ++# SPDX-License-Identifier: GPL-2.0 ++config CRYPTO_DEV_EIP93_SKCIPHER ++ tristate ++ ++config CRYPTO_DEV_EIP93_HMAC ++ tristate ++ ++config CRYPTO_DEV_EIP93 ++ tristate "Support for EIP93 crypto HW accelerators" ++ depends on SOC_MT7621 || COMPILE_TEST ++ help ++ EIP93 have various crypto HW accelerators. Select this if ++ you want to use the EIP93 modules for any of the crypto algorithms. ++ ++if CRYPTO_DEV_EIP93 ++ ++config CRYPTO_DEV_EIP93_AES ++ bool "Register AES algorithm implementations with the Crypto API" ++ default y ++ select CRYPTO_DEV_EIP93_SKCIPHER ++ select CRYPTO_LIB_AES ++ select CRYPTO_SKCIPHER ++ help ++ Selecting this will offload AES - ECB, CBC and CTR crypto ++ to the EIP-93 crypto engine. ++ ++config CRYPTO_DEV_EIP93_DES ++ bool "Register legacy DES / 3DES algorithm with the Crypto API" ++ default y ++ select CRYPTO_DEV_EIP93_SKCIPHER ++ select CRYPTO_LIB_DES ++ select CRYPTO_SKCIPHER ++ help ++ Selecting this will offload DES and 3DES ECB and CBC ++ crypto to the EIP-93 crypto engine. ++ ++config CRYPTO_DEV_EIP93_AEAD ++ bool "Register AEAD algorithm with the Crypto API" ++ default y ++ select CRYPTO_DEV_EIP93_HMAC ++ select CRYPTO_AEAD ++ select CRYPTO_AUTHENC ++ select CRYPTO_MD5 ++ select CRYPTO_SHA1 ++ select CRYPTO_SHA256 ++ help ++ Selecting this will offload AEAD authenc(hmac(x), cipher(y)) ++ crypto to the EIP-93 crypto engine. ++ ++config CRYPTO_DEV_EIP93_GENERIC_SW_MAX_LEN ++ int "Max skcipher software fallback length" ++ default 256 ++ help ++ Max length of crypt request which ++ will fallback to software crypt of skcipher *except* AES-128. ++ ++config CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN ++ int "Max AES-128 skcipher software fallback length" ++ default 512 ++ help ++ Max length of crypt request which ++ will fallback to software crypt of AES-128 skcipher. ++ ++endif +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/Makefile +@@ -0,0 +1,7 @@ ++obj-$(CONFIG_CRYPTO_DEV_EIP93) += crypto-hw-eip93.o ++ ++crypto-hw-eip93-y += eip93-main.o eip93-common.o ++ ++crypto-hw-eip93-$(CONFIG_CRYPTO_DEV_EIP93_SKCIPHER) += eip93-cipher.o ++crypto-hw-eip93-$(CONFIG_CRYPTO_DEV_EIP93_AEAD) += eip93-aead.o ++ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-aead.c +@@ -0,0 +1,768 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++#include ++#endif ++ ++#include ++#include ++ ++#include "eip93-aead.h" ++#include "eip93-cipher.h" ++#include "eip93-common.h" ++#include "eip93-regs.h" ++ ++void mtk_aead_handle_result(struct crypto_async_request *async, int err) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm); ++ struct mtk_device *mtk = ctx->mtk; ++ struct aead_request *req = aead_request_cast(async); ++ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req); ++ ++ mtk_unmap_dma(mtk, rctx, req->src, req->dst); ++ mtk_handle_result(mtk, rctx, req->iv); ++ ++ if (err == 1) ++ err = -EBADMSG; ++ /* let software handle anti-replay errors */ ++ if (err == 4) ++ err = 0; ++ ++ aead_request_complete(req, err); ++} ++ ++static int mtk_aead_send_req(struct crypto_async_request *async) ++{ ++ struct aead_request *req = aead_request_cast(async); ++ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req); ++ int err; ++ ++ err = check_valid_request(rctx); ++ if (err) { ++ aead_request_complete(req, err); ++ return err; ++ } ++ ++ return mtk_send_req(async, req->iv, rctx); ++} ++ ++/* Crypto aead API functions */ ++static int mtk_aead_cra_init(struct crypto_tfm *tfm) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg, ++ struct mtk_alg_template, alg.aead.base); ++ u32 flags = tmpl->flags; ++ char *alg_base; ++ ++ crypto_aead_set_reqsize(__crypto_aead_cast(tfm), ++ sizeof(struct mtk_cipher_reqctx)); ++ ++ ctx->mtk = tmpl->mtk; ++ ctx->in_first = true; ++ ctx->out_first = true; ++ ++ ctx->sa_in = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL); ++ if (!ctx->sa_in) ++ return -ENOMEM; ++ ++ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ++ ctx->sa_out = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL); ++ if (!ctx->sa_out) ++ return -ENOMEM; ++ ++ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ++ /* software workaround for now */ ++ if (IS_HASH_MD5(flags)) ++ alg_base = "md5"; ++ if (IS_HASH_SHA1(flags)) ++ alg_base = "sha1"; ++ if (IS_HASH_SHA224(flags)) ++ alg_base = "sha224"; ++ if (IS_HASH_SHA256(flags)) ++ alg_base = "sha256"; ++ ++ ctx->shash = crypto_alloc_shash(alg_base, 0, CRYPTO_ALG_NEED_FALLBACK); ++ ++ if (IS_ERR(ctx->shash)) { ++ dev_err(ctx->mtk->dev, "base driver %s could not be loaded.\n", ++ alg_base); ++ return PTR_ERR(ctx->shash); ++ } ++ ++ return 0; ++} ++ ++static void mtk_aead_cra_exit(struct crypto_tfm *tfm) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ if (ctx->shash) ++ crypto_free_shash(ctx->shash); ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ kfree(ctx->sa_in); ++ kfree(ctx->sa_out); ++} ++ ++static int mtk_aead_setkey(struct crypto_aead *ctfm, const u8 *key, ++ unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg, ++ struct mtk_alg_template, alg.skcipher.base); ++ u32 flags = tmpl->flags; ++ u32 nonce = 0; ++ struct crypto_authenc_keys keys; ++ struct crypto_aes_ctx aes; ++ struct saRecord_s *saRecord = ctx->sa_out; ++ int sa_size = sizeof(struct saRecord_s); ++ int err = -EINVAL; ++ ++ ++ if (crypto_authenc_extractkeys(&keys, key, len)) ++ return err; ++ ++ if (IS_RFC3686(flags)) { ++ if (keys.enckeylen < CTR_RFC3686_NONCE_SIZE) ++ return err; ++ ++ keys.enckeylen -= CTR_RFC3686_NONCE_SIZE; ++ memcpy(&nonce, keys.enckey + keys.enckeylen, ++ CTR_RFC3686_NONCE_SIZE); ++ } ++ ++ switch ((flags & MTK_ALG_MASK)) { ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++ case MTK_ALG_DES: ++ err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen); ++ break; ++ case MTK_ALG_3DES: ++ if (keys.enckeylen != DES3_EDE_KEY_SIZE) ++ return -EINVAL; ++ ++ err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen); ++ break; ++#endif ++ case MTK_ALG_AES: ++ err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); ++ } ++ if (err) ++ return err; ++ ++ ctx->blksize = crypto_aead_blocksize(ctfm); ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, sa_size, ++ DMA_TO_DEVICE); ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, sa_size, ++ DMA_TO_DEVICE); ++ /* Encryption key */ ++ mtk_set_saRecord(saRecord, keys.enckeylen, flags); ++ saRecord->saCmd0.bits.opCode = 1; ++ saRecord->saCmd0.bits.digestLength = ctx->authsize >> 2; ++ ++ memcpy(saRecord->saKey, keys.enckey, keys.enckeylen); ++ ctx->saNonce = nonce; ++ saRecord->saNonce = nonce; ++ ++ /* authentication key */ ++ err = mtk_authenc_setkey(ctx->shash, saRecord, keys.authkey, ++ keys.authkeylen); ++ ++ saRecord->saCmd0.bits.direction = 0; ++ memcpy(ctx->sa_in, saRecord, sa_size); ++ ctx->sa_in->saCmd0.bits.direction = 1; ++ ctx->sa_in->saCmd1.bits.copyDigest = 0; ++ ++ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, sa_size, ++ DMA_TO_DEVICE); ++ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, sa_size, ++ DMA_TO_DEVICE); ++ ctx->in_first = true; ++ ctx->out_first = true; ++ ++ return err; ++} ++ ++static int mtk_aead_setauthsize(struct crypto_aead *ctfm, ++ unsigned int authsize) ++{ ++ struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ++ ctx->authsize = authsize; ++ ctx->sa_in->saCmd0.bits.digestLength = ctx->authsize >> 2; ++ ctx->sa_out->saCmd0.bits.digestLength = ctx->authsize >> 2; ++ ++ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ return 0; ++} ++ ++static void mtk_aead_setassoc(struct mtk_crypto_ctx *ctx, ++ struct aead_request *req, bool in) ++{ ++ struct saRecord_s *saRecord; ++ ++ if (in) { ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ saRecord = ctx->sa_in; ++ saRecord->saCmd1.bits.hashCryptOffset = req->assoclen >> 2; ++ ++ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ctx->assoclen_in = req->assoclen; ++ } else { ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ saRecord = ctx->sa_out; ++ saRecord->saCmd1.bits.hashCryptOffset = req->assoclen >> 2; ++ ++ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ctx->assoclen_out = req->assoclen; ++ } ++} ++ ++static int mtk_aead_crypt(struct aead_request *req) ++{ ++ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req); ++ struct crypto_async_request *async = &req->base; ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ ++ rctx->textsize = req->cryptlen; ++ rctx->blksize = ctx->blksize; ++ rctx->assoclen = req->assoclen; ++ rctx->authsize = ctx->authsize; ++ rctx->sg_src = req->src; ++ rctx->sg_dst = req->dst; ++ rctx->ivsize = crypto_aead_ivsize(aead); ++ rctx->flags |= MTK_DESC_AEAD; ++ ++ if IS_DECRYPT(rctx->flags) ++ rctx->textsize -= rctx->authsize; ++ ++ return mtk_aead_send_req(async); ++} ++ ++static int mtk_aead_encrypt(struct aead_request *req) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); ++ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req); ++ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg, ++ struct mtk_alg_template, alg.aead.base); ++ ++ rctx->flags = tmpl->flags; ++ rctx->flags |= MTK_ENCRYPT; ++ if (ctx->out_first) { ++ mtk_aead_setassoc(ctx, req, false); ++ ctx->out_first = false; ++ } ++ ++ if (req->assoclen != ctx->assoclen_out) { ++ dev_err(ctx->mtk->dev, "Request AAD length error\n"); ++ return -EINVAL; ++ } ++ ++ rctx->saRecord_base = ctx->sa_base_out; ++ ++ return mtk_aead_crypt(req); ++} ++ ++static int mtk_aead_decrypt(struct aead_request *req) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); ++ struct mtk_cipher_reqctx *rctx = aead_request_ctx(req); ++ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg, ++ struct mtk_alg_template, alg.aead.base); ++ ++ rctx->flags = tmpl->flags; ++ rctx->flags |= MTK_DECRYPT; ++ if (ctx->in_first) { ++ mtk_aead_setassoc(ctx, req, true); ++ ctx->in_first = false; ++ } ++ ++ if (req->assoclen != ctx->assoclen_in) { ++ dev_err(ctx->mtk->dev, "Request AAD length error\n"); ++ return -EINVAL; ++ } ++ ++ rctx->saRecord_base = ctx->sa_base_in; ++ ++ return mtk_aead_crypt(req); ++} ++ ++/* Available authenc algorithms in this module */ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | MTK_MODE_CBC | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = AES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = MD5_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(md5),cbc(aes))", ++ .cra_driver_name = ++ "authenc(hmac(md5-eip93), cbc(aes-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | MTK_MODE_CBC | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = AES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),cbc(aes))", ++ .cra_driver_name = ++ "authenc(hmac(sha1-eip93),cbc(aes-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | MTK_MODE_CBC | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = AES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA224_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha224),cbc(aes))", ++ .cra_driver_name = ++ "authenc(hmac(sha224-eip93),cbc(aes-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | MTK_MODE_CBC | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = AES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA256_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha256),cbc(aes))", ++ .cra_driver_name = ++ "authenc(hmac(sha256-eip93),cbc(aes-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_md5_rfc3686_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | ++ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = MD5_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(md5),rfc3686(ctr(aes)))", ++ .cra_driver_name = ++ "authenc(hmac(md5-eip93),rfc3686(ctr(aes-eip93)))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha1_rfc3686_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | ++ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))", ++ .cra_driver_name = ++ "authenc(hmac(sha1-eip93),rfc3686(ctr(aes-eip93)))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha224_rfc3686_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | ++ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA224_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))", ++ .cra_driver_name = ++ "authenc(hmac(sha224-eip93),rfc3686(ctr(aes-eip93)))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha256_rfc3686_aes = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | ++ MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA256_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))", ++ .cra_driver_name = ++ "authenc(hmac(sha256-eip93),rfc3686(ctr(aes-eip93)))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | MTK_MODE_CBC | MTK_ALG_DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = MD5_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(md5),cbc(des))", ++ .cra_driver_name = ++ "authenc(hmac(md5-eip93),cbc(des-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | MTK_MODE_CBC | MTK_ALG_DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),cbc(des))", ++ .cra_driver_name = ++ "authenc(hmac(sha1-eip93),cbc(des-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | MTK_MODE_CBC | MTK_ALG_DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA224_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha224),cbc(des))", ++ .cra_driver_name = ++ "authenc(hmac(sha224-eip93),cbc(des-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | MTK_MODE_CBC | MTK_ALG_DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA256_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha256),cbc(des))", ++ .cra_driver_name = ++ "authenc(hmac(sha256-eip93),cbc(des-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des3_ede = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_MD5 | MTK_MODE_CBC | MTK_ALG_3DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = MD5_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(md5),cbc(des3_ede))", ++ .cra_driver_name = ++ "authenc(hmac(md5-eip93),cbc(des3_ede-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0x0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des3_ede = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA1 | MTK_MODE_CBC | MTK_ALG_3DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA1_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", ++ .cra_driver_name = ++ "authenc(hmac(sha1-eip93),cbc(des3_ede-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0x0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des3_ede = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA224 | MTK_MODE_CBC | MTK_ALG_3DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA224_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha224),cbc(des3_ede))", ++ .cra_driver_name = ++ "authenc(hmac(sha224-eip93),cbc(des3_ede-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0x0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des3_ede = { ++ .type = MTK_ALG_TYPE_AEAD, ++ .flags = MTK_HASH_HMAC | MTK_HASH_SHA256 | MTK_MODE_CBC | MTK_ALG_3DES, ++ .alg.aead = { ++ .setkey = mtk_aead_setkey, ++ .encrypt = mtk_aead_encrypt, ++ .decrypt = mtk_aead_decrypt, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .setauthsize = mtk_aead_setauthsize, ++ .maxauthsize = SHA256_DIGEST_SIZE, ++ .base = { ++ .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", ++ .cra_driver_name = ++ "authenc(hmac(sha256-eip93),cbc(des3_ede-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0x0, ++ .cra_init = mtk_aead_cra_init, ++ .cra_exit = mtk_aead_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++#endif +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-aead.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++#ifndef _EIP93_AEAD_H_ ++#define _EIP93_AEAD_H_ ++ ++extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_rfc3686_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_rfc3686_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_rfc3686_aes; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_rfc3686_aes; ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_md5_cbc_des3_ede; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha1_cbc_des3_ede; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha224_cbc_des3_ede; ++extern struct mtk_alg_template mtk_alg_authenc_hmac_sha256_cbc_des3_ede; ++#endif ++ ++void mtk_aead_handle_result(struct crypto_async_request *async, int err); ++ ++#endif /* _EIP93_AEAD_H_ */ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-aes.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++#ifndef _EIP93_AES_H_ ++#define _EIP93_AES_H_ ++ ++extern struct mtk_alg_template mtk_alg_ecb_aes; ++extern struct mtk_alg_template mtk_alg_cbc_aes; ++extern struct mtk_alg_template mtk_alg_ctr_aes; ++extern struct mtk_alg_template mtk_alg_rfc3686_aes; ++ ++#endif /* _EIP93_AES_H_ */ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-cipher.c +@@ -0,0 +1,483 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++#include ++#include ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++#include ++#endif ++#include ++ ++#include "eip93-cipher.h" ++#include "eip93-common.h" ++#include "eip93-regs.h" ++ ++void mtk_skcipher_handle_result(struct crypto_async_request *async, int err) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm); ++ struct mtk_device *mtk = ctx->mtk; ++ struct skcipher_request *req = skcipher_request_cast(async); ++ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req); ++ ++ mtk_unmap_dma(mtk, rctx, req->src, req->dst); ++ mtk_handle_result(mtk, rctx, req->iv); ++ ++ skcipher_request_complete(req, err); ++} ++ ++static inline bool mtk_skcipher_is_fallback(const struct crypto_tfm *tfm, ++ u32 flags) ++{ ++ return (tfm->__crt_alg->cra_flags & CRYPTO_ALG_NEED_FALLBACK) && ++ !IS_RFC3686(flags); ++} ++ ++static int mtk_skcipher_send_req(struct crypto_async_request *async) ++{ ++ struct skcipher_request *req = skcipher_request_cast(async); ++ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req); ++ int err; ++ ++ err = check_valid_request(rctx); ++ ++ if (err) { ++ skcipher_request_complete(req, err); ++ return err; ++ } ++ ++ return mtk_send_req(async, req->iv, rctx); ++} ++ ++/* Crypto skcipher API functions */ ++static int mtk_skcipher_cra_init(struct crypto_tfm *tfm) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg, ++ struct mtk_alg_template, alg.skcipher.base); ++ bool fallback = mtk_skcipher_is_fallback(tfm, tmpl->flags); ++ ++ if (fallback) { ++ ctx->fallback = crypto_alloc_skcipher( ++ crypto_tfm_alg_name(tfm), 0, CRYPTO_ALG_NEED_FALLBACK); ++ if (IS_ERR(ctx->fallback)) ++ return PTR_ERR(ctx->fallback); ++ } ++ ++ crypto_skcipher_set_reqsize( ++ __crypto_skcipher_cast(tfm), ++ sizeof(struct mtk_cipher_reqctx) + ++ (fallback ? crypto_skcipher_reqsize(ctx->fallback) : ++ 0)); ++ ++ ctx->mtk = tmpl->mtk; ++ ++ ctx->sa_in = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL); ++ if (!ctx->sa_in) ++ return -ENOMEM; ++ ++ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ ++ ctx->sa_out = kzalloc(sizeof(struct saRecord_s), GFP_KERNEL); ++ if (!ctx->sa_out) ++ return -ENOMEM; ++ ++ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ return 0; ++} ++ ++static void mtk_skcipher_cra_exit(struct crypto_tfm *tfm) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, ++ sizeof(struct saRecord_s), DMA_TO_DEVICE); ++ kfree(ctx->sa_in); ++ kfree(ctx->sa_out); ++ ++ crypto_free_skcipher(ctx->fallback); ++} ++ ++static int mtk_skcipher_setkey(struct crypto_skcipher *ctfm, const u8 *key, ++ unsigned int len) ++{ ++ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(tfm); ++ struct mtk_alg_template *tmpl = container_of(tfm->__crt_alg, ++ struct mtk_alg_template, alg.skcipher.base); ++ struct saRecord_s *saRecord = ctx->sa_out; ++ u32 flags = tmpl->flags; ++ u32 nonce = 0; ++ unsigned int keylen = len; ++ int sa_size = sizeof(struct saRecord_s); ++ int err = -EINVAL; ++ ++ if (!key || !keylen) ++ return err; ++ ++ ctx->keylen = keylen; ++ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++ if (IS_RFC3686(flags)) { ++ if (len < CTR_RFC3686_NONCE_SIZE) ++ return err; ++ ++ keylen = len - CTR_RFC3686_NONCE_SIZE; ++ memcpy(&nonce, key + keylen, CTR_RFC3686_NONCE_SIZE); ++ } ++#endif ++ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++ if (flags & MTK_ALG_DES) { ++ ctx->blksize = DES_BLOCK_SIZE; ++ err = verify_skcipher_des_key(ctfm, key); ++ } ++ if (flags & MTK_ALG_3DES) { ++ ctx->blksize = DES3_EDE_BLOCK_SIZE; ++ err = verify_skcipher_des3_key(ctfm, key); ++ } ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++ if (flags & MTK_ALG_AES) { ++ struct crypto_aes_ctx aes; ++ bool fallback = mtk_skcipher_is_fallback(tfm, flags); ++ ++ if (fallback && !IS_RFC3686(flags)) { ++ err = crypto_skcipher_setkey(ctx->fallback, key, ++ keylen); ++ if (err) ++ return err; ++ } ++ ++ ctx->blksize = AES_BLOCK_SIZE; ++ err = aes_expandkey(&aes, key, keylen); ++ } ++#endif ++ if (err) ++ return err; ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_in, sa_size, ++ DMA_TO_DEVICE); ++ ++ dma_unmap_single(ctx->mtk->dev, ctx->sa_base_out, sa_size, ++ DMA_TO_DEVICE); ++ ++ mtk_set_saRecord(saRecord, keylen, flags); ++ ++ memcpy(saRecord->saKey, key, keylen); ++ ctx->saNonce = nonce; ++ saRecord->saNonce = nonce; ++ saRecord->saCmd0.bits.direction = 0; ++ ++ memcpy(ctx->sa_in, saRecord, sa_size); ++ ctx->sa_in->saCmd0.bits.direction = 1; ++ ++ ctx->sa_base_out = dma_map_single(ctx->mtk->dev, ctx->sa_out, sa_size, ++ DMA_TO_DEVICE); ++ ++ ctx->sa_base_in = dma_map_single(ctx->mtk->dev, ctx->sa_in, sa_size, ++ DMA_TO_DEVICE); ++ return err; ++} ++ ++static int mtk_skcipher_crypt(struct skcipher_request *req, bool encrypt) ++{ ++ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req); ++ struct crypto_async_request *async = &req->base; ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); ++ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); ++ bool fallback = mtk_skcipher_is_fallback(req->base.tfm, rctx->flags); ++ ++ if (!req->cryptlen) ++ return 0; ++ ++ /* ++ * ECB and CBC algorithms require message lengths to be ++ * multiples of block size. ++ */ ++ if (IS_ECB(rctx->flags) || IS_CBC(rctx->flags)) ++ if (!IS_ALIGNED(req->cryptlen, ++ crypto_skcipher_blocksize(skcipher))) ++ return -EINVAL; ++ ++ if (fallback && ++ req->cryptlen <= (AES_KEYSIZE_128 ? ++ CONFIG_CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN : ++ CONFIG_CRYPTO_DEV_EIP93_GENERIC_SW_MAX_LEN)) { ++ skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); ++ skcipher_request_set_callback(&rctx->fallback_req, ++ req->base.flags, ++ req->base.complete, ++ req->base.data); ++ skcipher_request_set_crypt(&rctx->fallback_req, req->src, ++ req->dst, req->cryptlen, req->iv); ++ return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) : ++ crypto_skcipher_decrypt(&rctx->fallback_req); ++ } ++ ++ rctx->assoclen = 0; ++ rctx->textsize = req->cryptlen; ++ rctx->authsize = 0; ++ rctx->sg_src = req->src; ++ rctx->sg_dst = req->dst; ++ rctx->ivsize = crypto_skcipher_ivsize(skcipher); ++ rctx->blksize = ctx->blksize; ++ rctx->flags |= MTK_DESC_SKCIPHER; ++ if (!IS_ECB(rctx->flags)) ++ rctx->flags |= MTK_DESC_DMA_IV; ++ ++ return mtk_skcipher_send_req(async); ++} ++ ++static int mtk_skcipher_encrypt(struct skcipher_request *req) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); ++ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req); ++ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg, ++ struct mtk_alg_template, alg.skcipher.base); ++ ++ rctx->flags = tmpl->flags; ++ rctx->flags |= MTK_ENCRYPT; ++ rctx->saRecord_base = ctx->sa_base_out; ++ ++ return mtk_skcipher_crypt(req, true); ++} ++ ++static int mtk_skcipher_decrypt(struct skcipher_request *req) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(req->base.tfm); ++ struct mtk_cipher_reqctx *rctx = skcipher_request_ctx(req); ++ struct mtk_alg_template *tmpl = container_of(req->base.tfm->__crt_alg, ++ struct mtk_alg_template, alg.skcipher.base); ++ ++ rctx->flags = tmpl->flags; ++ rctx->flags |= MTK_DECRYPT; ++ rctx->saRecord_base = ctx->sa_base_in; ++ ++ return mtk_skcipher_crypt(req, false); ++} ++ ++/* Available algorithms in this module */ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++struct mtk_alg_template mtk_alg_ecb_aes = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_ECB | MTK_ALG_AES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = 0, ++ .base = { ++ .cra_name = "ecb(aes)", ++ .cra_driver_name = "ecb(aes-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0xf, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_cbc_aes = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_CBC | MTK_ALG_AES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, ++ .base = { ++ .cra_name = "cbc(aes)", ++ .cra_driver_name = "cbc(aes-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = AES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0xf, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_ctr_aes = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_CTR | MTK_ALG_AES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE, ++ .ivsize = AES_BLOCK_SIZE, ++ .base = { ++ .cra_name = "ctr(aes)", ++ .cra_driver_name = "ctr(aes-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0xf, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_rfc3686_aes = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_CTR | MTK_MODE_RFC3686 | MTK_ALG_AES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE, ++ .ivsize = CTR_RFC3686_IV_SIZE, ++ .base = { ++ .cra_name = "rfc3686(ctr(aes))", ++ .cra_driver_name = "rfc3686(ctr(aes-eip93))", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_NEED_FALLBACK | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = 1, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0xf, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++struct mtk_alg_template mtk_alg_ecb_des = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_ECB | MTK_ALG_DES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = DES_KEY_SIZE, ++ .max_keysize = DES_KEY_SIZE, ++ .ivsize = 0, ++ .base = { ++ .cra_name = "ecb(des)", ++ .cra_driver_name = "ebc(des-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_cbc_des = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_CBC | MTK_ALG_DES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = DES_KEY_SIZE, ++ .max_keysize = DES_KEY_SIZE, ++ .ivsize = DES_BLOCK_SIZE, ++ .base = { ++ .cra_name = "cbc(des)", ++ .cra_driver_name = "cbc(des-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_ecb_des3_ede = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_ECB | MTK_ALG_3DES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = DES3_EDE_KEY_SIZE, ++ .max_keysize = DES3_EDE_KEY_SIZE, ++ .ivsize = 0, ++ .base = { ++ .cra_name = "ecb(des3_ede)", ++ .cra_driver_name = "ecb(des3_ede-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++ ++struct mtk_alg_template mtk_alg_cbc_des3_ede = { ++ .type = MTK_ALG_TYPE_SKCIPHER, ++ .flags = MTK_MODE_CBC | MTK_ALG_3DES, ++ .alg.skcipher = { ++ .setkey = mtk_skcipher_setkey, ++ .encrypt = mtk_skcipher_encrypt, ++ .decrypt = mtk_skcipher_decrypt, ++ .min_keysize = DES3_EDE_KEY_SIZE, ++ .max_keysize = DES3_EDE_KEY_SIZE, ++ .ivsize = DES3_EDE_BLOCK_SIZE, ++ .base = { ++ .cra_name = "cbc(des3_ede)", ++ .cra_driver_name = "cbc(des3_ede-eip93)", ++ .cra_priority = MTK_CRA_PRIORITY, ++ .cra_flags = CRYPTO_ALG_ASYNC | ++ CRYPTO_ALG_KERN_DRIVER_ONLY, ++ .cra_blocksize = DES3_EDE_BLOCK_SIZE, ++ .cra_ctxsize = sizeof(struct mtk_crypto_ctx), ++ .cra_alignmask = 0, ++ .cra_init = mtk_skcipher_cra_init, ++ .cra_exit = mtk_skcipher_cra_exit, ++ .cra_module = THIS_MODULE, ++ }, ++ }, ++}; ++#endif +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-cipher.h +@@ -0,0 +1,66 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++#ifndef _EIP93_CIPHER_H_ ++#define _EIP93_CIPHER_H_ ++ ++#include "eip93-main.h" ++ ++struct mtk_crypto_ctx { ++ struct mtk_device *mtk; ++ struct saRecord_s *sa_in; ++ dma_addr_t sa_base_in; ++ struct saRecord_s *sa_out; ++ dma_addr_t sa_base_out; ++ uint32_t saNonce; ++ int blksize; ++ /* AEAD specific */ ++ unsigned int authsize; ++ unsigned int assoclen_in; ++ unsigned int assoclen_out; ++ bool in_first; ++ bool out_first; ++ struct crypto_shash *shash; ++ unsigned int keylen; ++ struct crypto_skcipher *fallback; ++}; ++ ++struct mtk_cipher_reqctx { ++ unsigned long flags; ++ unsigned int blksize; ++ unsigned int ivsize; ++ unsigned int textsize; ++ unsigned int assoclen; ++ unsigned int authsize; ++ dma_addr_t saRecord_base; ++ struct saState_s *saState; ++ dma_addr_t saState_base; ++ uint32_t saState_idx; ++ struct eip93_descriptor_s *cdesc; ++ struct scatterlist *sg_src; ++ struct scatterlist *sg_dst; ++ int src_nents; ++ int dst_nents; ++ struct saState_s *saState_ctr; ++ dma_addr_t saState_base_ctr; ++ uint32_t saState_ctr_idx; ++ struct skcipher_request fallback_req; // keep at the end ++}; ++ ++int check_valid_request(struct mtk_cipher_reqctx *rctx); ++ ++void mtk_unmap_dma(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx, ++ struct scatterlist *reqsrc, struct scatterlist *reqdst); ++ ++void mtk_skcipher_handle_result(struct crypto_async_request *async, int err); ++ ++int mtk_send_req(struct crypto_async_request *async, ++ const u8 *reqiv, struct mtk_cipher_reqctx *rctx); ++ ++void mtk_handle_result(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx, ++ u8 *reqiv); ++ ++#endif /* _EIP93_CIPHER_H_ */ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-common.c +@@ -0,0 +1,749 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "eip93-cipher.h" ++#include "eip93-common.h" ++#include "eip93-main.h" ++#include "eip93-regs.h" ++ ++inline void *mtk_ring_next_wptr(struct mtk_device *mtk, ++ struct mtk_desc_ring *ring) ++{ ++ void *ptr = ring->write; ++ ++ if ((ring->write == ring->read - ring->offset) || ++ (ring->read == ring->base && ring->write == ring->base_end)) ++ return ERR_PTR(-ENOMEM); ++ ++ if (ring->write == ring->base_end) ++ ring->write = ring->base; ++ else ++ ring->write += ring->offset; ++ ++ return ptr; ++} ++ ++inline void *mtk_ring_next_rptr(struct mtk_device *mtk, ++ struct mtk_desc_ring *ring) ++{ ++ void *ptr = ring->read; ++ ++ if (ring->write == ring->read) ++ return ERR_PTR(-ENOENT); ++ ++ if (ring->read == ring->base_end) ++ ring->read = ring->base; ++ else ++ ring->read += ring->offset; ++ ++ return ptr; ++} ++ ++inline int mtk_put_descriptor(struct mtk_device *mtk, ++ struct eip93_descriptor_s *desc) ++{ ++ struct eip93_descriptor_s *cdesc; ++ struct eip93_descriptor_s *rdesc; ++ unsigned long irqflags; ++ ++ spin_lock_irqsave(&mtk->ring->write_lock, irqflags); ++ ++ rdesc = mtk_ring_next_wptr(mtk, &mtk->ring->rdr); ++ ++ if (IS_ERR(rdesc)) { ++ spin_unlock_irqrestore(&mtk->ring->write_lock, irqflags); ++ return -ENOENT; ++ } ++ ++ cdesc = mtk_ring_next_wptr(mtk, &mtk->ring->cdr); ++ ++ if (IS_ERR(cdesc)) { ++ spin_unlock_irqrestore(&mtk->ring->write_lock, irqflags); ++ return -ENOENT; ++ } ++ ++ memset(rdesc, 0, sizeof(struct eip93_descriptor_s)); ++ memcpy(cdesc, desc, sizeof(struct eip93_descriptor_s)); ++ ++ atomic_dec(&mtk->ring->free); ++ spin_unlock_irqrestore(&mtk->ring->write_lock, irqflags); ++ ++ return 0; ++} ++ ++inline void *mtk_get_descriptor(struct mtk_device *mtk) ++{ ++ struct eip93_descriptor_s *cdesc; ++ void *ptr; ++ unsigned long irqflags; ++ ++ spin_lock_irqsave(&mtk->ring->read_lock, irqflags); ++ ++ cdesc = mtk_ring_next_rptr(mtk, &mtk->ring->cdr); ++ ++ if (IS_ERR(cdesc)) { ++ spin_unlock_irqrestore(&mtk->ring->read_lock, irqflags); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ memset(cdesc, 0, sizeof(struct eip93_descriptor_s)); ++ ++ ptr = mtk_ring_next_rptr(mtk, &mtk->ring->rdr); ++ if (IS_ERR(ptr)) { ++ spin_unlock_irqrestore(&mtk->ring->read_lock, irqflags); ++ return ERR_PTR(-ENOENT); ++ } ++ ++ atomic_inc(&mtk->ring->free); ++ spin_unlock_irqrestore(&mtk->ring->read_lock, irqflags); ++ ++ return ptr; ++} ++ ++inline int mtk_get_free_saState(struct mtk_device *mtk) ++{ ++ struct mtk_state_pool *saState_pool; ++ int i; ++ ++ for (i = 0; i < MTK_RING_SIZE; i++) { ++ saState_pool = &mtk->ring->saState_pool[i]; ++ if (saState_pool->in_use == false) { ++ saState_pool->in_use = true; ++ return i; ++ } ++ ++ } ++ ++ return -ENOENT; ++} ++ ++static inline void mtk_free_sg_copy(const int len, struct scatterlist **sg) ++{ ++ if (!*sg || !len) ++ return; ++ ++ free_pages((unsigned long)sg_virt(*sg), get_order(len)); ++ kfree(*sg); ++ *sg = NULL; ++} ++ ++static inline int mtk_make_sg_copy(struct scatterlist *src, ++ struct scatterlist **dst, ++ const uint32_t len, const bool copy) ++{ ++ void *pages; ++ ++ *dst = kmalloc(sizeof(**dst), GFP_KERNEL); ++ if (!*dst) ++ return -ENOMEM; ++ ++ ++ pages = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, ++ get_order(len)); ++ ++ if (!pages) { ++ kfree(*dst); ++ *dst = NULL; ++ return -ENOMEM; ++ } ++ ++ sg_init_table(*dst, 1); ++ sg_set_buf(*dst, pages, len); ++ ++ /* copy only as requested */ ++ if (copy) ++ sg_copy_to_buffer(src, sg_nents(src), pages, len); ++ ++ return 0; ++} ++ ++static inline bool mtk_is_sg_aligned(struct scatterlist *sg, u32 len, ++ const int blksize) ++{ ++ int nents; ++ ++ for (nents = 0; sg; sg = sg_next(sg), ++nents) { ++ if (!IS_ALIGNED(sg->offset, 4)) ++ return false; ++ ++ if (len <= sg->length) { ++ if (!IS_ALIGNED(len, blksize)) ++ return false; ++ ++ return true; ++ } ++ ++ if (!IS_ALIGNED(sg->length, blksize)) ++ return false; ++ ++ len -= sg->length; ++ } ++ return false; ++} ++ ++int check_valid_request(struct mtk_cipher_reqctx *rctx) ++{ ++ struct scatterlist *src = rctx->sg_src; ++ struct scatterlist *dst = rctx->sg_dst; ++ uint32_t src_nents, dst_nents; ++ u32 textsize = rctx->textsize; ++ u32 authsize = rctx->authsize; ++ u32 blksize = rctx->blksize; ++ u32 totlen_src = rctx->assoclen + rctx->textsize; ++ u32 totlen_dst = rctx->assoclen + rctx->textsize; ++ u32 copy_len; ++ bool src_align, dst_align; ++ int err = -EINVAL; ++ ++ if (!IS_CTR(rctx->flags)) { ++ if (!IS_ALIGNED(textsize, blksize)) ++ return err; ++ } ++ ++ if (authsize) { ++ if (IS_ENCRYPT(rctx->flags)) ++ totlen_dst += authsize; ++ else ++ totlen_src += authsize; ++ } ++ ++ src_nents = sg_nents_for_len(src, totlen_src); ++ dst_nents = sg_nents_for_len(dst, totlen_dst); ++ ++ if (src == dst) { ++ src_nents = max(src_nents, dst_nents); ++ dst_nents = src_nents; ++ if (unlikely((totlen_src || totlen_dst) && (src_nents <= 0))) ++ return err; ++ ++ } else { ++ if (unlikely(totlen_src && (src_nents <= 0))) ++ return err; ++ ++ if (unlikely(totlen_dst && (dst_nents <= 0))) ++ return err; ++ } ++ ++ if (authsize) { ++ if (dst_nents == 1 && src_nents == 1) { ++ src_align = mtk_is_sg_aligned(src, totlen_src, blksize); ++ if (src == dst) ++ dst_align = src_align; ++ else ++ dst_align = mtk_is_sg_aligned(dst, ++ totlen_dst, blksize); ++ } else { ++ src_align = false; ++ dst_align = false; ++ } ++ } else { ++ src_align = mtk_is_sg_aligned(src, totlen_src, blksize); ++ if (src == dst) ++ dst_align = src_align; ++ else ++ dst_align = mtk_is_sg_aligned(dst, totlen_dst, blksize); ++ } ++ ++ copy_len = max(totlen_src, totlen_dst); ++ if (!src_align) { ++ err = mtk_make_sg_copy(src, &rctx->sg_src, copy_len, true); ++ if (err) ++ return err; ++ } ++ ++ if (!dst_align) { ++ err = mtk_make_sg_copy(dst, &rctx->sg_dst, copy_len, false); ++ if (err) ++ return err; ++ } ++ ++ rctx->src_nents = sg_nents_for_len(rctx->sg_src, totlen_src); ++ rctx->dst_nents = sg_nents_for_len(rctx->sg_dst, totlen_dst); ++ ++ return 0; ++} ++/* ++ * Set saRecord function: ++ * Even saRecord is set to "0", keep " = 0" for readability. ++ */ ++void mtk_set_saRecord(struct saRecord_s *saRecord, const unsigned int keylen, ++ const u32 flags) ++{ ++ saRecord->saCmd0.bits.ivSource = 2; ++ if (IS_ECB(flags)) ++ saRecord->saCmd0.bits.saveIv = 0; ++ else ++ saRecord->saCmd0.bits.saveIv = 1; ++ ++ saRecord->saCmd0.bits.opGroup = 0; ++ saRecord->saCmd0.bits.opCode = 0; ++ ++ switch ((flags & MTK_ALG_MASK)) { ++ case MTK_ALG_AES: ++ saRecord->saCmd0.bits.cipher = 3; ++ saRecord->saCmd1.bits.aesKeyLen = keylen >> 3; ++ break; ++ case MTK_ALG_3DES: ++ saRecord->saCmd0.bits.cipher = 1; ++ break; ++ case MTK_ALG_DES: ++ saRecord->saCmd0.bits.cipher = 0; ++ break; ++ default: ++ saRecord->saCmd0.bits.cipher = 15; ++ } ++ ++ switch ((flags & MTK_HASH_MASK)) { ++ case MTK_HASH_SHA256: ++ saRecord->saCmd0.bits.hash = 3; ++ break; ++ case MTK_HASH_SHA224: ++ saRecord->saCmd0.bits.hash = 2; ++ break; ++ case MTK_HASH_SHA1: ++ saRecord->saCmd0.bits.hash = 1; ++ break; ++ case MTK_HASH_MD5: ++ saRecord->saCmd0.bits.hash = 0; ++ break; ++ default: ++ saRecord->saCmd0.bits.hash = 15; ++ } ++ ++ saRecord->saCmd0.bits.hdrProc = 0; ++ saRecord->saCmd0.bits.padType = 3; ++ saRecord->saCmd0.bits.extPad = 0; ++ saRecord->saCmd0.bits.scPad = 0; ++ ++ switch ((flags & MTK_MODE_MASK)) { ++ case MTK_MODE_CBC: ++ saRecord->saCmd1.bits.cipherMode = 1; ++ break; ++ case MTK_MODE_CTR: ++ saRecord->saCmd1.bits.cipherMode = 2; ++ break; ++ case MTK_MODE_ECB: ++ saRecord->saCmd1.bits.cipherMode = 0; ++ break; ++ } ++ ++ saRecord->saCmd1.bits.byteOffset = 0; ++ saRecord->saCmd1.bits.hashCryptOffset = 0; ++ saRecord->saCmd0.bits.digestLength = 0; ++ saRecord->saCmd1.bits.copyPayload = 0; ++ ++ if (IS_HMAC(flags)) { ++ saRecord->saCmd1.bits.hmac = 1; ++ saRecord->saCmd1.bits.copyDigest = 1; ++ saRecord->saCmd1.bits.copyHeader = 1; ++ } else { ++ saRecord->saCmd1.bits.hmac = 0; ++ saRecord->saCmd1.bits.copyDigest = 0; ++ saRecord->saCmd1.bits.copyHeader = 0; ++ } ++ ++ saRecord->saCmd1.bits.seqNumCheck = 0; ++ saRecord->saSpi = 0x0; ++ saRecord->saSeqNumMask[0] = 0xFFFFFFFF; ++ saRecord->saSeqNumMask[1] = 0x0; ++} ++ ++/* ++ * Poor mans Scatter/gather function: ++ * Create a Descriptor for every segment to avoid copying buffers. ++ * For performance better to wait for hardware to perform multiple DMA ++ * ++ */ ++static inline int mtk_scatter_combine(struct mtk_device *mtk, ++ struct mtk_cipher_reqctx *rctx, ++ u32 datalen, u32 split, int offsetin) ++{ ++ struct eip93_descriptor_s *cdesc = rctx->cdesc; ++ struct scatterlist *sgsrc = rctx->sg_src; ++ struct scatterlist *sgdst = rctx->sg_dst; ++ unsigned int remainin = sg_dma_len(sgsrc); ++ unsigned int remainout = sg_dma_len(sgdst); ++ dma_addr_t saddr = sg_dma_address(sgsrc); ++ dma_addr_t daddr = sg_dma_address(sgdst); ++ dma_addr_t stateAddr; ++ u32 srcAddr, dstAddr, len, n; ++ bool nextin = false; ++ bool nextout = false; ++ int offsetout = 0; ++ int ndesc_cdr = 0, err; ++ ++ if (IS_ECB(rctx->flags)) ++ rctx->saState_base = 0; ++ ++ if (split < datalen) { ++ stateAddr = rctx->saState_base_ctr; ++ n = split; ++ } else { ++ stateAddr = rctx->saState_base; ++ n = datalen; ++ } ++ ++ do { ++ if (nextin) { ++ sgsrc = sg_next(sgsrc); ++ remainin = sg_dma_len(sgsrc); ++ if (remainin == 0) ++ continue; ++ ++ saddr = sg_dma_address(sgsrc); ++ offsetin = 0; ++ nextin = false; ++ } ++ ++ if (nextout) { ++ sgdst = sg_next(sgdst); ++ remainout = sg_dma_len(sgdst); ++ if (remainout == 0) ++ continue; ++ ++ daddr = sg_dma_address(sgdst); ++ offsetout = 0; ++ nextout = false; ++ } ++ srcAddr = saddr + offsetin; ++ dstAddr = daddr + offsetout; ++ ++ if (remainin == remainout) { ++ len = remainin; ++ if (len > n) { ++ len = n; ++ remainin -= n; ++ remainout -= n; ++ offsetin += n; ++ offsetout += n; ++ } else { ++ nextin = true; ++ nextout = true; ++ } ++ } else if (remainin < remainout) { ++ len = remainin; ++ if (len > n) { ++ len = n; ++ remainin -= n; ++ remainout -= n; ++ offsetin += n; ++ offsetout += n; ++ } else { ++ offsetout += len; ++ remainout -= len; ++ nextin = true; ++ } ++ } else { ++ len = remainout; ++ if (len > n) { ++ len = n; ++ remainin -= n; ++ remainout -= n; ++ offsetin += n; ++ offsetout += n; ++ } else { ++ offsetin += len; ++ remainin -= len; ++ nextout = true; ++ } ++ } ++ n -= len; ++ ++ cdesc->srcAddr = srcAddr; ++ cdesc->dstAddr = dstAddr; ++ cdesc->stateAddr = stateAddr; ++ cdesc->peLength.bits.peReady = 0; ++ cdesc->peLength.bits.byPass = 0; ++ cdesc->peLength.bits.length = len; ++ cdesc->peLength.bits.hostReady = 1; ++ ++ if (n == 0) { ++ n = datalen - split; ++ split = datalen; ++ stateAddr = rctx->saState_base; ++ } ++ ++ if (n == 0) ++ cdesc->userId |= MTK_DESC_LAST; ++ ++ /* Loop - Delay - No need to rollback ++ * Maybe refine by slowing down at MTK_RING_BUSY ++ */ ++again: ++ err = mtk_put_descriptor(mtk, cdesc); ++ if (err) { ++ udelay(500); ++ goto again; ++ } ++ /* Writing new descriptor count starts DMA action */ ++ writel(1, mtk->base + EIP93_REG_PE_CD_COUNT); ++ ++ ndesc_cdr++; ++ } while (n); ++ ++ return -EINPROGRESS; ++} ++ ++int mtk_send_req(struct crypto_async_request *async, ++ const u8 *reqiv, struct mtk_cipher_reqctx *rctx) ++{ ++ struct mtk_crypto_ctx *ctx = crypto_tfm_ctx(async->tfm); ++ struct mtk_device *mtk = ctx->mtk; ++ struct scatterlist *src = rctx->sg_src; ++ struct scatterlist *dst = rctx->sg_dst; ++ struct saState_s *saState; ++ struct mtk_state_pool *saState_pool; ++ struct eip93_descriptor_s cdesc; ++ u32 flags = rctx->flags; ++ int idx; ++ int offsetin = 0, err = -ENOMEM; ++ u32 datalen = rctx->assoclen + rctx->textsize; ++ u32 split = datalen; ++ u32 start, end, ctr, blocks; ++ u32 iv[AES_BLOCK_SIZE / sizeof(u32)]; ++ ++ rctx->saState_ctr = NULL; ++ rctx->saState = NULL; ++ ++ if (IS_ECB(flags)) ++ goto skip_iv; ++ ++ memcpy(iv, reqiv, rctx->ivsize); ++ ++ if (!IS_ALIGNED((u32)reqiv, rctx->ivsize) || IS_RFC3686(flags)) { ++ rctx->flags &= ~MTK_DESC_DMA_IV; ++ flags = rctx->flags; ++ } ++ ++ if (IS_DMA_IV(flags)) { ++ rctx->saState = (void *)reqiv; ++ } else { ++ idx = mtk_get_free_saState(mtk); ++ if (idx < 0) ++ goto send_err; ++ saState_pool = &mtk->ring->saState_pool[idx]; ++ rctx->saState_idx = idx; ++ rctx->saState = saState_pool->base; ++ rctx->saState_base = saState_pool->base_dma; ++ memcpy(rctx->saState->stateIv, iv, rctx->ivsize); ++ } ++ ++ saState = rctx->saState; ++ ++ if (IS_RFC3686(flags)) { ++ saState->stateIv[0] = ctx->saNonce; ++ saState->stateIv[1] = iv[0]; ++ saState->stateIv[2] = iv[1]; ++ saState->stateIv[3] = cpu_to_be32(1); ++ } else if (!IS_HMAC(flags) && IS_CTR(flags)) { ++ /* Compute data length. */ ++ blocks = DIV_ROUND_UP(rctx->textsize, AES_BLOCK_SIZE); ++ ctr = be32_to_cpu(iv[3]); ++ /* Check 32bit counter overflow. */ ++ start = ctr; ++ end = start + blocks - 1; ++ if (end < start) { ++ split = AES_BLOCK_SIZE * -start; ++ /* ++ * Increment the counter manually to cope with ++ * the hardware counter overflow. ++ */ ++ iv[3] = 0xffffffff; ++ crypto_inc((u8 *)iv, AES_BLOCK_SIZE); ++ idx = mtk_get_free_saState(mtk); ++ if (idx < 0) ++ goto free_state; ++ saState_pool = &mtk->ring->saState_pool[idx]; ++ rctx->saState_ctr_idx = idx; ++ rctx->saState_ctr = saState_pool->base; ++ rctx->saState_base_ctr = saState_pool->base_dma; ++ ++ memcpy(rctx->saState_ctr->stateIv, reqiv, rctx->ivsize); ++ memcpy(saState->stateIv, iv, rctx->ivsize); ++ } ++ } ++ ++ if (IS_DMA_IV(flags)) { ++ rctx->saState_base = dma_map_single(mtk->dev, (void *)reqiv, ++ rctx->ivsize, DMA_TO_DEVICE); ++ if (dma_mapping_error(mtk->dev, rctx->saState_base)) ++ goto free_state; ++ } ++skip_iv: ++ cdesc.peCrtlStat.bits.hostReady = 1; ++ cdesc.peCrtlStat.bits.prngMode = 0; ++ cdesc.peCrtlStat.bits.hashFinal = 0; ++ cdesc.peCrtlStat.bits.padCrtlStat = 0; ++ cdesc.peCrtlStat.bits.peReady = 0; ++ cdesc.saAddr = rctx->saRecord_base; ++ cdesc.arc4Addr = (uint32_t)async; ++ cdesc.userId = flags; ++ rctx->cdesc = &cdesc; ++ ++ /* map DMA_BIDIRECTIONAL to invalidate cache on destination ++ * implies __dma_cache_wback_inv ++ */ ++ dma_map_sg(mtk->dev, dst, rctx->dst_nents, DMA_BIDIRECTIONAL); ++ if (src != dst) ++ dma_map_sg(mtk->dev, src, rctx->src_nents, DMA_TO_DEVICE); ++ ++ err = mtk_scatter_combine(mtk, rctx, datalen, split, offsetin); ++ ++ return err; ++ ++free_state: ++ if (rctx->saState) { ++ saState_pool = &mtk->ring->saState_pool[rctx->saState_idx]; ++ saState_pool->in_use = false; ++ } ++ ++ if (rctx->saState_ctr) { ++ saState_pool = &mtk->ring->saState_pool[rctx->saState_ctr_idx]; ++ saState_pool->in_use = false; ++ } ++send_err: ++ return err; ++} ++ ++void mtk_unmap_dma(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx, ++ struct scatterlist *reqsrc, struct scatterlist *reqdst) ++{ ++ u32 len = rctx->assoclen + rctx->textsize; ++ u32 authsize = rctx->authsize; ++ u32 flags = rctx->flags; ++ u32 *otag; ++ int i; ++ ++ if (rctx->sg_src == rctx->sg_dst) { ++ dma_unmap_sg(mtk->dev, rctx->sg_dst, rctx->dst_nents, ++ DMA_BIDIRECTIONAL); ++ goto process_tag; ++ } ++ ++ dma_unmap_sg(mtk->dev, rctx->sg_src, rctx->src_nents, ++ DMA_TO_DEVICE); ++ ++ if (rctx->sg_src != reqsrc) ++ mtk_free_sg_copy(len + rctx->authsize, &rctx->sg_src); ++ ++ dma_unmap_sg(mtk->dev, rctx->sg_dst, rctx->dst_nents, ++ DMA_BIDIRECTIONAL); ++ ++ /* SHA tags need conversion from net-to-host */ ++process_tag: ++ if (IS_DECRYPT(flags)) ++ authsize = 0; ++ ++ if (authsize) { ++ if (!IS_HASH_MD5(flags)) { ++ otag = sg_virt(rctx->sg_dst) + len; ++ for (i = 0; i < (authsize / 4); i++) ++ otag[i] = ntohl(otag[i]); ++ } ++ } ++ ++ if (rctx->sg_dst != reqdst) { ++ sg_copy_from_buffer(reqdst, sg_nents(reqdst), ++ sg_virt(rctx->sg_dst), len + authsize); ++ mtk_free_sg_copy(len + rctx->authsize, &rctx->sg_dst); ++ } ++} ++ ++void mtk_handle_result(struct mtk_device *mtk, struct mtk_cipher_reqctx *rctx, ++ u8 *reqiv) ++{ ++ struct mtk_state_pool *saState_pool; ++ ++ if (IS_DMA_IV(rctx->flags)) ++ dma_unmap_single(mtk->dev, rctx->saState_base, rctx->ivsize, ++ DMA_TO_DEVICE); ++ ++ if (!IS_ECB(rctx->flags)) ++ memcpy(reqiv, rctx->saState->stateIv, rctx->ivsize); ++ ++ if ((rctx->saState) && !(IS_DMA_IV(rctx->flags))) { ++ saState_pool = &mtk->ring->saState_pool[rctx->saState_idx]; ++ saState_pool->in_use = false; ++ } ++ ++ if (rctx->saState_ctr) { ++ saState_pool = &mtk->ring->saState_pool[rctx->saState_ctr_idx]; ++ saState_pool->in_use = false; ++ } ++} ++ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_HMAC) ++/* basically this is set hmac - key */ ++int mtk_authenc_setkey(struct crypto_shash *cshash, struct saRecord_s *sa, ++ const u8 *authkey, unsigned int authkeylen) ++{ ++ int bs = crypto_shash_blocksize(cshash); ++ int ds = crypto_shash_digestsize(cshash); ++ int ss = crypto_shash_statesize(cshash); ++ u8 *ipad, *opad; ++ unsigned int i, err; ++ ++ SHASH_DESC_ON_STACK(shash, cshash); ++ ++ shash->tfm = cshash; ++ ++ /* auth key ++ * ++ * EIP93 can only authenticate with hash of the key ++ * do software shash until EIP93 hash function complete. ++ */ ++ ipad = kcalloc(2, SHA256_BLOCK_SIZE + ss, GFP_KERNEL); ++ if (!ipad) ++ return -ENOMEM; ++ ++ opad = ipad + SHA256_BLOCK_SIZE + ss; ++ ++ if (authkeylen > bs) { ++ err = crypto_shash_digest(shash, authkey, ++ authkeylen, ipad); ++ if (err) ++ return err; ++ ++ authkeylen = ds; ++ } else ++ memcpy(ipad, authkey, authkeylen); ++ ++ memset(ipad + authkeylen, 0, bs - authkeylen); ++ memcpy(opad, ipad, bs); ++ ++ for (i = 0; i < bs; i++) { ++ ipad[i] ^= HMAC_IPAD_VALUE; ++ opad[i] ^= HMAC_OPAD_VALUE; ++ } ++ ++ err = crypto_shash_init(shash) ?: ++ crypto_shash_update(shash, ipad, bs) ?: ++ crypto_shash_export(shash, ipad) ?: ++ crypto_shash_init(shash) ?: ++ crypto_shash_update(shash, opad, bs) ?: ++ crypto_shash_export(shash, opad); ++ ++ if (err) ++ return err; ++ ++ /* add auth key */ ++ memcpy(&sa->saIDigest, ipad, SHA256_DIGEST_SIZE); ++ memcpy(&sa->saODigest, opad, SHA256_DIGEST_SIZE); ++ ++ kfree(ipad); ++ return 0; ++} ++#endif +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-common.h +@@ -0,0 +1,28 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++ ++#ifndef _EIP93_COMMON_H_ ++#define _EIP93_COMMON_H_ ++ ++#include "eip93-main.h" ++ ++inline int mtk_put_descriptor(struct mtk_device *mtk, ++ struct eip93_descriptor_s *desc); ++ ++inline void *mtk_get_descriptor(struct mtk_device *mtk); ++ ++inline int mtk_get_free_saState(struct mtk_device *mtk); ++ ++void mtk_set_saRecord(struct saRecord_s *saRecord, const unsigned int keylen, ++ const u32 flags); ++ ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_HMAC) ++int mtk_authenc_setkey(struct crypto_shash *cshash, struct saRecord_s *sa, ++ const u8 *authkey, unsigned int authkeylen); ++#endif ++ ++#endif /* _EIP93_COMMON_H_ */ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-des.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++#ifndef _EIP93_DES_H_ ++#define _EIP93_DES_H_ ++ ++extern struct mtk_alg_template mtk_alg_ecb_des; ++extern struct mtk_alg_template mtk_alg_cbc_des; ++extern struct mtk_alg_template mtk_alg_ecb_des3_ede; ++extern struct mtk_alg_template mtk_alg_cbc_des3_ede; ++ ++#endif /* _EIP93_DES_H_ */ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-main.c +@@ -0,0 +1,467 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "eip93-main.h" ++#include "eip93-regs.h" ++#include "eip93-common.h" ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_SKCIPHER) ++#include "eip93-cipher.h" ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++#include "eip93-aes.h" ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++#include "eip93-des.h" ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AEAD) ++#include "eip93-aead.h" ++#endif ++ ++static struct mtk_alg_template *mtk_algs[] = { ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++ &mtk_alg_ecb_des, ++ &mtk_alg_cbc_des, ++ &mtk_alg_ecb_des3_ede, ++ &mtk_alg_cbc_des3_ede, ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++ &mtk_alg_ecb_aes, ++ &mtk_alg_cbc_aes, ++ &mtk_alg_ctr_aes, ++ &mtk_alg_rfc3686_aes, ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AEAD) ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++ &mtk_alg_authenc_hmac_md5_cbc_des, ++ &mtk_alg_authenc_hmac_sha1_cbc_des, ++ &mtk_alg_authenc_hmac_sha224_cbc_des, ++ &mtk_alg_authenc_hmac_sha256_cbc_des, ++ &mtk_alg_authenc_hmac_md5_cbc_des3_ede, ++ &mtk_alg_authenc_hmac_sha1_cbc_des3_ede, ++ &mtk_alg_authenc_hmac_sha224_cbc_des3_ede, ++ &mtk_alg_authenc_hmac_sha256_cbc_des3_ede, ++#endif ++ &mtk_alg_authenc_hmac_md5_cbc_aes, ++ &mtk_alg_authenc_hmac_sha1_cbc_aes, ++ &mtk_alg_authenc_hmac_sha224_cbc_aes, ++ &mtk_alg_authenc_hmac_sha256_cbc_aes, ++ &mtk_alg_authenc_hmac_md5_rfc3686_aes, ++ &mtk_alg_authenc_hmac_sha1_rfc3686_aes, ++ &mtk_alg_authenc_hmac_sha224_rfc3686_aes, ++ &mtk_alg_authenc_hmac_sha256_rfc3686_aes, ++#endif ++}; ++ ++inline void mtk_irq_disable(struct mtk_device *mtk, u32 mask) ++{ ++ __raw_writel(mask, mtk->base + EIP93_REG_MASK_DISABLE); ++} ++ ++inline void mtk_irq_enable(struct mtk_device *mtk, u32 mask) ++{ ++ __raw_writel(mask, mtk->base + EIP93_REG_MASK_ENABLE); ++} ++ ++inline void mtk_irq_clear(struct mtk_device *mtk, u32 mask) ++{ ++ __raw_writel(mask, mtk->base + EIP93_REG_INT_CLR); ++} ++ ++static void mtk_unregister_algs(unsigned int i) ++{ ++ unsigned int j; ++ ++ for (j = 0; j < i; j++) { ++ switch (mtk_algs[j]->type) { ++ case MTK_ALG_TYPE_SKCIPHER: ++ crypto_unregister_skcipher(&mtk_algs[j]->alg.skcipher); ++ break; ++ case MTK_ALG_TYPE_AEAD: ++ crypto_unregister_aead(&mtk_algs[j]->alg.aead); ++ break; ++ } ++ } ++} ++ ++static int mtk_register_algs(struct mtk_device *mtk) ++{ ++ unsigned int i; ++ int err = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(mtk_algs); i++) { ++ mtk_algs[i]->mtk = mtk; ++ ++ switch (mtk_algs[i]->type) { ++ case MTK_ALG_TYPE_SKCIPHER: ++ err = crypto_register_skcipher(&mtk_algs[i]->alg.skcipher); ++ break; ++ case MTK_ALG_TYPE_AEAD: ++ err = crypto_register_aead(&mtk_algs[i]->alg.aead); ++ break; ++ } ++ if (err) ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ mtk_unregister_algs(i); ++ ++ return err; ++} ++ ++static void mtk_handle_result_descriptor(struct mtk_device *mtk) ++{ ++ struct crypto_async_request *async; ++ struct eip93_descriptor_s *rdesc; ++ bool last_entry; ++ u32 flags; ++ int handled, ready, err; ++ union peCrtlStat_w done1; ++ union peLength_w done2; ++ ++get_more: ++ handled = 0; ++ ++ ready = readl(mtk->base + EIP93_REG_PE_RD_COUNT) & GENMASK(10, 0); ++ ++ if (!ready) { ++ mtk_irq_clear(mtk, EIP93_INT_PE_RDRTHRESH_REQ); ++ mtk_irq_enable(mtk, EIP93_INT_PE_RDRTHRESH_REQ); ++ return; ++ } ++ ++ last_entry = false; ++ ++ while (ready) { ++ rdesc = mtk_get_descriptor(mtk); ++ if (IS_ERR(rdesc)) { ++ dev_err(mtk->dev, "Ndesc: %d nreq: %d\n", ++ handled, ready); ++ err = -EIO; ++ break; ++ } ++ /* make sure DMA is finished writing */ ++ do { ++ done1.word = READ_ONCE(rdesc->peCrtlStat.word); ++ done2.word = READ_ONCE(rdesc->peLength.word); ++ } while ((!done1.bits.peReady) || (!done2.bits.peReady)); ++ ++ err = rdesc->peCrtlStat.bits.errStatus; ++ ++ flags = rdesc->userId; ++ async = (struct crypto_async_request *)rdesc->arc4Addr; ++ ++ writel(1, mtk->base + EIP93_REG_PE_RD_COUNT); ++ mtk_irq_clear(mtk, EIP93_INT_PE_RDRTHRESH_REQ); ++ ++ handled++; ++ ready--; ++ ++ if (flags & MTK_DESC_LAST) { ++ last_entry = true; ++ break; ++ } ++ } ++ ++ if (!last_entry) ++ goto get_more; ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_SKCIPHER) ++ if (flags & MTK_DESC_SKCIPHER) ++ mtk_skcipher_handle_result(async, err); ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AEAD) ++ if (flags & MTK_DESC_AEAD) ++ mtk_aead_handle_result(async, err); ++#endif ++ goto get_more; ++} ++ ++static void mtk_done_task(unsigned long data) ++{ ++ struct mtk_device *mtk = (struct mtk_device *)data; ++ ++ mtk_handle_result_descriptor(mtk); ++} ++ ++static irqreturn_t mtk_irq_handler(int irq, void *dev_id) ++{ ++ struct mtk_device *mtk = (struct mtk_device *)dev_id; ++ u32 irq_status; ++ ++ irq_status = readl(mtk->base + EIP93_REG_INT_MASK_STAT); ++ ++ if (irq_status & EIP93_INT_PE_RDRTHRESH_REQ) { ++ mtk_irq_disable(mtk, EIP93_INT_PE_RDRTHRESH_REQ); ++ tasklet_schedule(&mtk->ring->done_task); ++ return IRQ_HANDLED; ++ } ++ ++ mtk_irq_clear(mtk, irq_status); ++ if (irq_status) ++ mtk_irq_disable(mtk, irq_status); ++ ++ return IRQ_NONE; ++} ++ ++static void mtk_initialize(struct mtk_device *mtk) ++{ ++ union peConfig_w peConfig; ++ union peEndianCfg_w peEndianCfg; ++ union peIntCfg_w peIntCfg; ++ union peClockCfg_w peClockCfg; ++ union peBufThresh_w peBufThresh; ++ union peRingThresh_w peRingThresh; ++ ++ /* Reset Engine and setup Mode */ ++ peConfig.word = 0; ++ peConfig.bits.resetPE = 1; ++ peConfig.bits.resetRing = 1; ++ peConfig.bits.peMode = 3; ++ peConfig.bits.enCDRupdate = 1; ++ ++ writel(peConfig.word, mtk->base + EIP93_REG_PE_CONFIG); ++ ++ udelay(10); ++ ++ peConfig.bits.resetPE = 0; ++ peConfig.bits.resetRing = 0; ++ ++ writel(peConfig.word, mtk->base + EIP93_REG_PE_CONFIG); ++ ++ /* Initialize the BYTE_ORDER_CFG register */ ++ peEndianCfg.word = 0; ++ writel(peEndianCfg.word, mtk->base + EIP93_REG_PE_ENDIAN_CONFIG); ++ ++ /* Initialize the INT_CFG register */ ++ peIntCfg.word = 0; ++ writel(peIntCfg.word, mtk->base + EIP93_REG_INT_CFG); ++ ++ /* Config Clocks */ ++ peClockCfg.word = 0; ++ peClockCfg.bits.enPEclk = 1; ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_DES) ++ peClockCfg.bits.enDESclk = 1; ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_AES) ++ peClockCfg.bits.enAESclk = 1; ++#endif ++#if IS_ENABLED(CONFIG_CRYPTO_DEV_EIP93_HMAC) ++ peClockCfg.bits.enHASHclk = 1; ++#endif ++ writel(peClockCfg.word, mtk->base + EIP93_REG_PE_CLOCK_CTRL); ++ ++ /* Config DMA thresholds */ ++ peBufThresh.word = 0; ++ peBufThresh.bits.inputBuffer = 128; ++ peBufThresh.bits.outputBuffer = 128; ++ ++ writel(peBufThresh.word, mtk->base + EIP93_REG_PE_BUF_THRESH); ++ ++ /* Clear/ack all interrupts before disable all */ ++ mtk_irq_clear(mtk, 0xFFFFFFFF); ++ mtk_irq_disable(mtk, 0xFFFFFFFF); ++ ++ /* Config Ring Threshold */ ++ peRingThresh.word = 0; ++ peRingThresh.bits.CDRThresh = MTK_RING_SIZE - MTK_RING_BUSY; ++ peRingThresh.bits.RDRThresh = 0; ++ peRingThresh.bits.RDTimeout = 5; ++ peRingThresh.bits.enTimeout = 1; ++ ++ writel(peRingThresh.word, mtk->base + EIP93_REG_PE_RING_THRESH); ++} ++ ++static void mtk_desc_free(struct mtk_device *mtk) ++{ ++ writel(0, mtk->base + EIP93_REG_PE_RING_CONFIG); ++ writel(0, mtk->base + EIP93_REG_PE_CDR_BASE); ++ writel(0, mtk->base + EIP93_REG_PE_RDR_BASE); ++} ++ ++static int mtk_set_ring(struct mtk_device *mtk, struct mtk_desc_ring *ring, ++ int Offset) ++{ ++ ring->offset = Offset; ++ ring->base = dmam_alloc_coherent(mtk->dev, Offset * MTK_RING_SIZE, ++ &ring->base_dma, GFP_KERNEL); ++ if (!ring->base) ++ return -ENOMEM; ++ ++ ring->write = ring->base; ++ ring->base_end = ring->base + Offset * (MTK_RING_SIZE - 1); ++ ring->read = ring->base; ++ ++ return 0; ++} ++ ++static int mtk_desc_init(struct mtk_device *mtk) ++{ ++ struct mtk_state_pool *saState_pool; ++ struct mtk_desc_ring *cdr = &mtk->ring->cdr; ++ struct mtk_desc_ring *rdr = &mtk->ring->rdr; ++ union peRingCfg_w peRingCfg; ++ int RingOffset, err, i; ++ ++ RingOffset = sizeof(struct eip93_descriptor_s); ++ ++ err = mtk_set_ring(mtk, cdr, RingOffset); ++ if (err) ++ return err; ++ ++ err = mtk_set_ring(mtk, rdr, RingOffset); ++ if (err) ++ return err; ++ ++ writel((u32)cdr->base_dma, mtk->base + EIP93_REG_PE_CDR_BASE); ++ writel((u32)rdr->base_dma, mtk->base + EIP93_REG_PE_RDR_BASE); ++ ++ peRingCfg.word = 0; ++ peRingCfg.bits.ringSize = MTK_RING_SIZE - 1; ++ peRingCfg.bits.ringOffset = RingOffset / 4; ++ ++ writel(peRingCfg.word, mtk->base + EIP93_REG_PE_RING_CONFIG); ++ ++ atomic_set(&mtk->ring->free, MTK_RING_SIZE - 1); ++ /* Create State record DMA pool */ ++ RingOffset = sizeof(struct saState_s); ++ mtk->ring->saState = dmam_alloc_coherent(mtk->dev, ++ RingOffset * MTK_RING_SIZE, ++ &mtk->ring->saState_dma, GFP_KERNEL); ++ if (!mtk->ring->saState) ++ return -ENOMEM; ++ ++ mtk->ring->saState_pool = devm_kcalloc(mtk->dev, 1, ++ sizeof(struct mtk_state_pool) * MTK_RING_SIZE, ++ GFP_KERNEL); ++ ++ for (i = 0; i < MTK_RING_SIZE; i++) { ++ saState_pool = &mtk->ring->saState_pool[i]; ++ saState_pool->base = mtk->ring->saState + (i * RingOffset); ++ saState_pool->base_dma = mtk->ring->saState_dma + (i * RingOffset); ++ saState_pool->in_use = false; ++ } ++ ++ return 0; ++} ++ ++static void mtk_cleanup(struct mtk_device *mtk) ++{ ++ tasklet_kill(&mtk->ring->done_task); ++ ++ /* Clear/ack all interrupts before disable all */ ++ mtk_irq_clear(mtk, 0xFFFFFFFF); ++ mtk_irq_disable(mtk, 0xFFFFFFFF); ++ ++ writel(0, mtk->base + EIP93_REG_PE_CLOCK_CTRL); ++ ++ mtk_desc_free(mtk); ++} ++ ++static int mtk_crypto_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mtk_device *mtk; ++ struct resource *res; ++ int err; ++ ++ mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL); ++ if (!mtk) ++ return -ENOMEM; ++ ++ mtk->dev = dev; ++ platform_set_drvdata(pdev, mtk); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ mtk->base = devm_ioremap_resource(&pdev->dev, res); ++ ++ if (IS_ERR(mtk->base)) ++ return PTR_ERR(mtk->base); ++ ++ mtk->irq = platform_get_irq(pdev, 0); ++ ++ if (mtk->irq < 0) ++ return mtk->irq; ++ ++ err = devm_request_threaded_irq(mtk->dev, mtk->irq, mtk_irq_handler, ++ NULL, IRQF_ONESHOT, ++ dev_name(mtk->dev), mtk); ++ ++ mtk->ring = devm_kcalloc(mtk->dev, 1, sizeof(*mtk->ring), GFP_KERNEL); ++ ++ if (!mtk->ring) ++ return -ENOMEM; ++ ++ err = mtk_desc_init(mtk); ++ if (err) ++ return err; ++ ++ tasklet_init(&mtk->ring->done_task, mtk_done_task, (unsigned long)mtk); ++ ++ spin_lock_init(&mtk->ring->read_lock); ++ spin_lock_init(&mtk->ring->write_lock); ++ ++ mtk_initialize(mtk); ++ ++ /* Init. finished, enable RDR interupt */ ++ mtk_irq_enable(mtk, EIP93_INT_PE_RDRTHRESH_REQ); ++ ++ err = mtk_register_algs(mtk); ++ if (err) { ++ mtk_cleanup(mtk); ++ return err; ++ } ++ ++ dev_info(mtk->dev, "EIP93 Crypto Engine Initialized."); ++ ++ return 0; ++} ++ ++static int mtk_crypto_remove(struct platform_device *pdev) ++{ ++ struct mtk_device *mtk = platform_get_drvdata(pdev); ++ ++ mtk_unregister_algs(ARRAY_SIZE(mtk_algs)); ++ mtk_cleanup(mtk); ++ dev_info(mtk->dev, "EIP93 removed.\n"); ++ ++ return 0; ++} ++ ++#if defined(CONFIG_OF) ++static const struct of_device_id mtk_crypto_of_match[] = { ++ { .compatible = "mediatek,mtk-eip93", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, mtk_crypto_of_match); ++#endif ++ ++static struct platform_driver mtk_crypto_driver = { ++ .probe = mtk_crypto_probe, ++ .remove = mtk_crypto_remove, ++ .driver = { ++ .name = "mtk-eip93", ++ .of_match_table = of_match_ptr(mtk_crypto_of_match), ++ }, ++}; ++module_platform_driver(mtk_crypto_driver); ++ ++MODULE_AUTHOR("Richard van Schagen "); ++MODULE_ALIAS("platform:" KBUILD_MODNAME); ++MODULE_DESCRIPTION("Mediatek EIP-93 crypto engine driver"); ++MODULE_LICENSE("GPL v2"); +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-main.h +@@ -0,0 +1,146 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++#ifndef _EIP93_MAIN_H_ ++#define _EIP93_MAIN_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MTK_RING_SIZE 512 ++#define MTK_RING_BUSY 32 ++#define MTK_CRA_PRIORITY 1500 ++ ++/* cipher algorithms */ ++#define MTK_ALG_DES BIT(0) ++#define MTK_ALG_3DES BIT(1) ++#define MTK_ALG_AES BIT(2) ++#define MTK_ALG_MASK GENMASK(2, 0) ++/* hash and hmac algorithms */ ++#define MTK_HASH_MD5 BIT(3) ++#define MTK_HASH_SHA1 BIT(4) ++#define MTK_HASH_SHA224 BIT(5) ++#define MTK_HASH_SHA256 BIT(6) ++#define MTK_HASH_HMAC BIT(7) ++#define MTK_HASH_MASK GENMASK(6, 3) ++/* cipher modes */ ++#define MTK_MODE_CBC BIT(8) ++#define MTK_MODE_ECB BIT(9) ++#define MTK_MODE_CTR BIT(10) ++#define MTK_MODE_RFC3686 BIT(11) ++#define MTK_MODE_MASK GENMASK(10, 8) ++ ++/* cipher encryption/decryption operations */ ++#define MTK_ENCRYPT BIT(12) ++#define MTK_DECRYPT BIT(13) ++ ++#define MTK_BUSY BIT(14) ++ ++/* descriptor flags */ ++#define MTK_DESC_ASYNC BIT(31) ++#define MTK_DESC_SKCIPHER BIT(30) ++#define MTK_DESC_AEAD BIT(29) ++#define MTK_DESC_AHASH BIT(28) ++#define MTK_DESC_PRNG BIT(27) ++#define MTK_DESC_FAKE_HMAC BIT(26) ++#define MTK_DESC_LAST BIT(25) ++#define MTK_DESC_FINISH BIT(24) ++#define MTK_DESC_IPSEC BIT(23) ++#define MTK_DESC_DMA_IV BIT(22) ++ ++#define IS_DES(flags) (flags & MTK_ALG_DES) ++#define IS_3DES(flags) (flags & MTK_ALG_3DES) ++#define IS_AES(flags) (flags & MTK_ALG_AES) ++ ++#define IS_HASH_MD5(flags) (flags & MTK_HASH_MD5) ++#define IS_HASH_SHA1(flags) (flags & MTK_HASH_SHA1) ++#define IS_HASH_SHA224(flags) (flags & MTK_HASH_SHA224) ++#define IS_HASH_SHA256(flags) (flags & MTK_HASH_SHA256) ++#define IS_HMAC(flags) (flags & MTK_HASH_HMAC) ++ ++#define IS_CBC(mode) (mode & MTK_MODE_CBC) ++#define IS_ECB(mode) (mode & MTK_MODE_ECB) ++#define IS_CTR(mode) (mode & MTK_MODE_CTR) ++#define IS_RFC3686(mode) (mode & MTK_MODE_RFC3686) ++ ++#define IS_BUSY(flags) (flags & MTK_BUSY) ++#define IS_DMA_IV(flags) (flags & MTK_DESC_DMA_IV) ++ ++#define IS_ENCRYPT(dir) (dir & MTK_ENCRYPT) ++#define IS_DECRYPT(dir) (dir & MTK_DECRYPT) ++ ++#define IS_CIPHER(flags) (flags & (MTK_ALG_DES || \ ++ MTK_ALG_3DES || \ ++ MTK_ALG_AES)) ++ ++#define IS_HASH(flags) (flags & (MTK_HASH_MD5 || \ ++ MTK_HASH_SHA1 || \ ++ MTK_HASH_SHA224 || \ ++ MTK_HASH_SHA256)) ++ ++/** ++ * struct mtk_device - crypto engine device structure ++ */ ++struct mtk_device { ++ void __iomem *base; ++ struct device *dev; ++ struct clk *clk; ++ int irq; ++ struct mtk_ring *ring; ++ struct mtk_state_pool *saState_pool; ++}; ++ ++struct mtk_desc_ring { ++ void *base; ++ void *base_end; ++ dma_addr_t base_dma; ++ /* write and read pointers */ ++ void *read; ++ void *write; ++ /* descriptor element offset */ ++ u32 offset; ++}; ++ ++struct mtk_state_pool { ++ void *base; ++ dma_addr_t base_dma; ++ bool in_use; ++}; ++ ++struct mtk_ring { ++ struct tasklet_struct done_task; ++ /* command/result rings */ ++ struct mtk_desc_ring cdr; ++ struct mtk_desc_ring rdr; ++ spinlock_t write_lock; ++ spinlock_t read_lock; ++ atomic_t free; ++ /* saState */ ++ struct mtk_state_pool *saState_pool; ++ void *saState; ++ dma_addr_t saState_dma; ++}; ++ ++enum mtk_alg_type { ++ MTK_ALG_TYPE_AEAD, ++ MTK_ALG_TYPE_SKCIPHER, ++}; ++ ++struct mtk_alg_template { ++ struct mtk_device *mtk; ++ enum mtk_alg_type type; ++ u32 flags; ++ union { ++ struct aead_alg aead; ++ struct skcipher_alg skcipher; ++ } alg; ++}; ++ ++#endif /* _EIP93_MAIN_H_ */ +--- /dev/null ++++ b/drivers/crypto/mtk-eip93/eip93-regs.h +@@ -0,0 +1,382 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2019 - 2021 ++ * ++ * Richard van Schagen ++ */ ++#ifndef REG_EIP93_H ++#define REG_EIP93_H ++ ++#define EIP93_REG_WIDTH 4 ++/*----------------------------------------------------------------------------- ++ * Register Map ++ */ ++#define DESP_BASE 0x0000000 ++#define EIP93_REG_PE_CTRL_STAT ((DESP_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_SOURCE_ADDR ((DESP_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_DEST_ADDR ((DESP_BASE)+(0x02 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_SA_ADDR ((DESP_BASE)+(0x03 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_ADDR ((DESP_BASE)+(0x04 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_USER_ID ((DESP_BASE)+(0x06 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_LENGTH ((DESP_BASE)+(0x07 * EIP93_REG_WIDTH)) ++ ++//PACKET ENGINE RING configuration registers ++#define PE_RNG_BASE 0x0000080 ++ ++#define EIP93_REG_PE_CDR_BASE ((PE_RNG_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_RDR_BASE ((PE_RNG_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_RING_CONFIG ((PE_RNG_BASE)+(0x02 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_RING_THRESH ((PE_RNG_BASE)+(0x03 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_CD_COUNT ((PE_RNG_BASE)+(0x04 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_RD_COUNT ((PE_RNG_BASE)+(0x05 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_RING_RW_PNTR ((PE_RNG_BASE)+(0x06 * EIP93_REG_WIDTH)) ++ ++//PACKET ENGINE configuration registers ++#define PE_CFG_BASE 0x0000100 ++#define EIP93_REG_PE_CONFIG ((PE_CFG_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_STATUS ((PE_CFG_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_BUF_THRESH ((PE_CFG_BASE)+(0x03 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_INBUF_COUNT ((PE_CFG_BASE)+(0x04 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_OUTBUF_COUNT ((PE_CFG_BASE)+(0x05 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_BUF_RW_PNTR ((PE_CFG_BASE)+(0x06 * EIP93_REG_WIDTH)) ++ ++//PACKET ENGINE endian config ++#define EN_CFG_BASE 0x00001CC ++#define EIP93_REG_PE_ENDIAN_CONFIG ((EN_CFG_BASE)+(0x00 * EIP93_REG_WIDTH)) ++ ++//EIP93 CLOCK control registers ++#define CLOCK_BASE 0x01E8 ++#define EIP93_REG_PE_CLOCK_CTRL ((CLOCK_BASE)+(0x00 * EIP93_REG_WIDTH)) ++ ++//EIP93 Device Option and Revision Register ++#define REV_BASE 0x01F4 ++#define EIP93_REG_PE_OPTION_1 ((REV_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_OPTION_0 ((REV_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PE_REVISION ((REV_BASE)+(0x02 * EIP93_REG_WIDTH)) ++ ++//EIP93 Interrupt Control Register ++#define INT_BASE 0x0200 ++#define EIP93_REG_INT_UNMASK_STAT ((INT_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_INT_MASK_STAT ((INT_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_INT_CLR ((INT_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_INT_MASK ((INT_BASE)+(0x02 * EIP93_REG_WIDTH)) ++#define EIP93_REG_INT_CFG ((INT_BASE)+(0x03 * EIP93_REG_WIDTH)) ++#define EIP93_REG_MASK_ENABLE ((INT_BASE)+(0X04 * EIP93_REG_WIDTH)) ++#define EIP93_REG_MASK_DISABLE ((INT_BASE)+(0X05 * EIP93_REG_WIDTH)) ++ ++//EIP93 SA Record register ++#define SA_BASE 0x0400 ++#define EIP93_REG_SA_CMD_0 ((SA_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_SA_CMD_1 ((SA_BASE)+(0x01 * EIP93_REG_WIDTH)) ++ ++//#define EIP93_REG_SA_READY ((SA_BASE)+(31 * EIP93_REG_WIDTH)) ++ ++//State save register ++#define STATE_BASE 0x0500 ++#define EIP93_REG_STATE_IV_0 ((STATE_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_STATE_IV_1 ((STATE_BASE)+(0x01 * EIP93_REG_WIDTH)) ++ ++#define EIP93_PE_ARC4STATE_BASEADDR_REG 0x0700 ++ ++//RAM buffer start address ++#define EIP93_INPUT_BUFFER 0x0800 ++#define EIP93_OUTPUT_BUFFER 0x0800 ++ ++//EIP93 PRNG Configuration Register ++#define PRNG_BASE 0x0300 ++#define EIP93_REG_PRNG_STAT ((PRNG_BASE)+(0x00 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_CTRL ((PRNG_BASE)+(0x01 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_SEED_0 ((PRNG_BASE)+(0x02 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_SEED_1 ((PRNG_BASE)+(0x03 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_SEED_2 ((PRNG_BASE)+(0x04 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_SEED_3 ((PRNG_BASE)+(0x05 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_KEY_0 ((PRNG_BASE)+(0x06 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_KEY_1 ((PRNG_BASE)+(0x07 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_KEY_2 ((PRNG_BASE)+(0x08 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_KEY_3 ((PRNG_BASE)+(0x09 * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_RES_0 ((PRNG_BASE)+(0x0A * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_RES_1 ((PRNG_BASE)+(0x0B * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_RES_2 ((PRNG_BASE)+(0x0C * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_RES_3 ((PRNG_BASE)+(0x0D * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_LFSR_0 ((PRNG_BASE)+(0x0E * EIP93_REG_WIDTH)) ++#define EIP93_REG_PRNG_LFSR_1 ((PRNG_BASE)+(0x0F * EIP93_REG_WIDTH)) ++ ++/*----------------------------------------------------------------------------- ++ * Constants & masks ++ */ ++ ++#define EIP93_SUPPORTED_INTERRUPTS_MASK 0xffff7f00 ++#define EIP93_PRNG_DT_TEXT_LOWERHALF 0xDEAD ++#define EIP93_PRNG_DT_TEXT_UPPERHALF 0xC0DE ++#define EIP93_10BITS_MASK 0X3FF ++#define EIP93_12BITS_MASK 0XFFF ++#define EIP93_4BITS_MASK 0X04 ++#define EIP93_20BITS_MASK 0xFFFFF ++ ++#define EIP93_MIN_DESC_DONE_COUNT 0 ++#define EIP93_MAX_DESC_DONE_COUNT 15 ++ ++#define EIP93_MIN_DESC_PENDING_COUNT 0 ++#define EIP93_MAX_DESC_PENDING_COUNT 1023 ++ ++#define EIP93_MIN_TIMEOUT_COUNT 0 ++#define EIP93_MAX_TIMEOUT_COUNT 15 ++ ++#define EIP93_MIN_PE_INPUT_THRESHOLD 1 ++#define EIP93_MAX_PE_INPUT_THRESHOLD 511 ++ ++#define EIP93_MIN_PE_OUTPUT_THRESHOLD 1 ++#define EIP93_MAX_PE_OUTPUT_THRESHOLD 432 ++ ++#define EIP93_MIN_PE_RING_SIZE 1 ++#define EIP93_MAX_PE_RING_SIZE 1023 ++ ++#define EIP93_MIN_PE_DESCRIPTOR_SIZE 7 ++#define EIP93_MAX_PE_DESCRIPTOR_SIZE 15 ++ ++//3DES keys,seed,known data and its result ++#define EIP93_KEY_0 0x133b3454 ++#define EIP93_KEY_1 0x5e5b890b ++#define EIP93_KEY_2 0x5eb30757 ++#define EIP93_KEY_3 0x93ab15f7 ++#define EIP93_SEED_0 0x62c4bf5e ++#define EIP93_SEED_1 0x972667c8 ++#define EIP93_SEED_2 0x6345bf67 ++#define EIP93_SEED_3 0xcb3482bf ++#define EIP93_LFSR_0 0xDEADC0DE ++#define EIP93_LFSR_1 0xBEEFF00D ++ ++/*----------------------------------------------------------------------------- ++ * EIP93 device initialization specifics ++ */ ++ ++/*---------------------------------------------------------------------------- ++ * Byte Order Reversal Mechanisms Supported in EIP93 ++ * EIP93_BO_REVERSE_HALF_WORD : reverse the byte order within a half-word ++ * EIP93_BO_REVERSE_WORD : reverse the byte order within a word ++ * EIP93_BO_REVERSE_DUAL_WORD : reverse the byte order within a dual-word ++ * EIP93_BO_REVERSE_QUAD_WORD : reverse the byte order within a quad-word ++ */ ++enum EIP93_Byte_Order_Value_t { ++ EIP93_BO_REVERSE_HALF_WORD = 1, ++ EIP93_BO_REVERSE_WORD = 2, ++ EIP93_BO_REVERSE_DUAL_WORD = 4, ++ EIP93_BO_REVERSE_QUAD_WORD = 8, ++}; ++ ++/*---------------------------------------------------------------------------- ++ * Byte Order Reversal Mechanisms Supported in EIP93 for Target Data ++ * EIP93_BO_REVERSE_HALF_WORD : reverse the byte order within a half-word ++ * EIP93_BO_REVERSE_WORD : reverse the byte order within a word ++ */ ++enum EIP93_Byte_Order_Value_TD_t { ++ EIP93_BO_REVERSE_HALF_WORD_TD = 1, ++ EIP93_BO_REVERSE_WORD_TD = 2, ++}; ++ ++// BYTE_ORDER_CFG register values ++#define EIP93_BYTE_ORDER_PD EIP93_BO_REVERSE_WORD ++#define EIP93_BYTE_ORDER_SA EIP93_BO_REVERSE_WORD ++#define EIP93_BYTE_ORDER_DATA EIP93_BO_REVERSE_WORD ++#define EIP93_BYTE_ORDER_TD EIP93_BO_REVERSE_WORD_TD ++ ++// INT_CFG register values ++#define EIP93_INT_HOST_OUTPUT_TYPE 0 ++#define EIP93_INT_PULSE_CLEAR 0 ++ ++/* ++ * Interrupts of EIP93 ++ */ ++ ++enum EIP93_InterruptSource_t { ++ EIP93_INT_PE_CDRTHRESH_REQ = BIT(0), ++ EIP93_INT_PE_RDRTHRESH_REQ = BIT(1), ++ EIP93_INT_PE_OPERATION_DONE = BIT(9), ++ EIP93_INT_PE_INBUFTHRESH_REQ = BIT(10), ++ EIP93_INT_PE_OUTBURTHRSH_REQ = BIT(11), ++ EIP93_INT_PE_PRNG_IRQ = BIT(12), ++ EIP93_INT_PE_ERR_REG = BIT(13), ++ EIP93_INT_PE_RD_DONE_IRQ = BIT(16), ++}; ++ ++union peConfig_w { ++ u32 word; ++ struct { ++ u32 resetPE :1; ++ u32 resetRing :1; ++ u32 reserved :6; ++ u32 peMode :2; ++ u32 enCDRupdate :1; ++ u32 reserved2 :5; ++ u32 swapCDRD :1; ++ u32 swapSA :1; ++ u32 swapData :1; ++ u32 reserved3 :13; ++ } bits; ++} __packed; ++ ++union peEndianCfg_w { ++ u32 word; ++ struct { ++ u32 masterByteSwap :8; ++ u32 reserved :8; ++ u32 targetByteSwap :8; ++ u32 reserved2 :8; ++ } bits; ++} __packed; ++ ++union peIntCfg_w { ++ u32 word; ++ struct { ++ u32 PulseClear :1; ++ u32 IntType :1; ++ u32 reserved :30; ++ } bits; ++} __packed; ++ ++union peClockCfg_w { ++ u32 word; ++ struct { ++ u32 enPEclk :1; ++ u32 enDESclk :1; ++ u32 enAESclk :1; ++ u32 reserved :1; ++ u32 enHASHclk :1; ++ u32 reserved2 :27; ++ } bits; ++} __packed; ++ ++union peBufThresh_w { ++ u32 word; ++ struct { ++ u32 inputBuffer :8; ++ u32 reserved :8; ++ u32 outputBuffer :8; ++ u32 reserved2 :8; ++ } bits; ++} __packed; ++ ++union peRingThresh_w { ++ u32 word; ++ struct { ++ u32 CDRThresh :10; ++ u32 reserved :6; ++ u32 RDRThresh :10; ++ u32 RDTimeout :4; ++ u32 reserved2 :1; ++ u32 enTimeout :1; ++ } bits; ++} __packed; ++ ++union peRingCfg_w { ++ u32 word; ++ struct { ++ u32 ringSize :10; ++ u32 reserved :6; ++ u32 ringOffset :8; ++ u32 reserved2 :8; ++ } bits; ++} __packed; ++ ++union saCmd0 { ++ u32 word; ++ struct { ++ u32 opCode :3; ++ u32 direction :1; ++ u32 opGroup :2; ++ u32 padType :2; ++ u32 cipher :4; ++ u32 hash :4; ++ u32 reserved2 :1; ++ u32 scPad :1; ++ u32 extPad :1; ++ u32 hdrProc :1; ++ u32 digestLength :4; ++ u32 ivSource :2; ++ u32 hashSource :2; ++ u32 saveIv :1; ++ u32 saveHash :1; ++ u32 reserved1 :2; ++ } bits; ++} __packed; ++ ++union saCmd1 { ++ u32 word; ++ struct { ++ u32 copyDigest :1; ++ u32 copyHeader :1; ++ u32 copyPayload :1; ++ u32 copyPad :1; ++ u32 reserved4 :4; ++ u32 cipherMode :2; ++ u32 reserved3 :1; ++ u32 sslMac :1; ++ u32 hmac :1; ++ u32 byteOffset :1; ++ u32 reserved2 :2; ++ u32 hashCryptOffset :8; ++ u32 aesKeyLen :3; ++ u32 reserved1 :1; ++ u32 aesDecKey :1; ++ u32 seqNumCheck :1; ++ u32 reserved0 :2; ++ } bits; ++} __packed; ++ ++struct saRecord_s { ++ union saCmd0 saCmd0; ++ union saCmd1 saCmd1; ++ u32 saKey[8]; ++ u32 saIDigest[8]; ++ u32 saODigest[8]; ++ u32 saSpi; ++ u32 saSeqNum[2]; ++ u32 saSeqNumMask[2]; ++ u32 saNonce; ++} __packed; ++ ++struct saState_s { ++ u32 stateIv[4]; ++ u32 stateByteCnt[2]; ++ u32 stateIDigest[8]; ++} __packed; ++ ++union peCrtlStat_w { ++ u32 word; ++ struct { ++ u32 hostReady :1; ++ u32 peReady :1; ++ u32 reserved :1; ++ u32 initArc4 :1; ++ u32 hashFinal :1; ++ u32 haltMode :1; ++ u32 prngMode :2; ++ u32 padValue :8; ++ u32 errStatus :8; ++ u32 padCrtlStat :8; ++ } bits; ++} __packed; ++ ++union peLength_w { ++ u32 word; ++ struct { ++ u32 length :20; ++ u32 reserved :2; ++ u32 hostReady :1; ++ u32 peReady :1; ++ u32 byPass :8; ++ } bits; ++} __packed; ++ ++struct eip93_descriptor_s { ++ union peCrtlStat_w peCrtlStat; ++ u32 srcAddr; ++ u32 dstAddr; ++ u32 saAddr; ++ u32 stateAddr; ++ u32 arc4Addr; ++ u32 userId; ++ union peLength_w peLength; ++} __packed; ++ ++#endif +--- a/drivers/crypto/Kconfig ++++ b/drivers/crypto/Kconfig +@@ -918,4 +918,6 @@ config CRYPTO_DEV_SA2UL + + source "drivers/crypto/keembay/Kconfig" + ++source "drivers/crypto/mtk-eip93/Kconfig" ++ + endif # CRYPTO_HW +--- a/drivers/crypto/Makefile ++++ b/drivers/crypto/Makefile +@@ -51,3 +51,4 @@ obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += x + obj-y += hisilicon/ + obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ + obj-y += keembay/ ++obj-$(CONFIG_CRYPTO_DEV_EIP93) += mtk-eip93/ diff --git a/target/linux/ramips/rt288x/config-6.1 b/target/linux/ramips/rt288x/config-6.1 new file mode 100644 index 0000000000..9f502c220f --- /dev/null +++ b/target/linux/ramips/rt288x/config-6.1 @@ -0,0 +1,187 @@ +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_SUSPEND_POSSIBLE=y +CONFIG_BLK_MQ_PCI=y +CONFIG_CEVT_R4K=y +CONFIG_CLK_MTMIPS=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_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_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_RNG2=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_DTB_RT2880_EVAL 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_ALLOCATOR=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=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_PINCONF=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_RALINK=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HZ_PERIODIC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IP17XX_PHY=y +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_INTC=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_AUTO_PFN_OFFSET=y +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_EBPF_JIT=y +CONFIG_MIPS_L1_CACHE_SHIFT=4 +CONFIG_MIPS_L1_CACHE_SHIFT_4=y +CONFIG_MIPS_LD_CAN_LINK_VDSO=y +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MIPS_SPRAM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y +CONFIG_MTD_SPLIT_LZMA_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_MTD_SPLIT_WRGG_FW=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_RALINK_MDIO=y +CONFIG_NET_RALINK_MDIO_RT2880=y +CONFIG_NET_RALINK_RT2880=y +CONFIG_NET_RALINK_SOC=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_VENDOR_RALINK=y +CONFIG_NLS=m +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +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_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +# CONFIG_PHY_MT7621_PCI is not set +# CONFIG_PHY_RALINK_USB is not set +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_AW9523 is not set +CONFIG_PINCTRL_RALINK=y +CONFIG_PINCTRL_RT288X=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_RALINK=y +CONFIG_RALINK_WDT=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_RESET_CONTROLLER=y +CONFIG_SERIAL_8250_RT288X=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SOC_MT7620 is not set +# CONFIG_SOC_MT7621 is not set +CONFIG_SOC_RT288X=y +# 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 is not set +CONFIG_SPI_RT2880=y +CONFIG_SRCU=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=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_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_TARGET_ISA_REV=2 +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TINY_SRCU=y +CONFIG_USB=m +CONFIG_USB_COMMON=m +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_HCD_PLATFORM=m +CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PLATFORM=m +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_WATCHDOG_CORE=y diff --git a/target/linux/ramips/rt305x/config-6.1 b/target/linux/ramips/rt305x/config-6.1 new file mode 100644 index 0000000000..5af80adca6 --- /dev/null +++ b/target/linux/ramips/rt305x/config-6.1 @@ -0,0 +1,182 @@ +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_SUSPEND_POSSIBLE=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_SYSTICK_QUIRK=y +CONFIG_CLKEVT_RT3352=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLK_MTMIPS=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_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_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_RNG2=y +CONFIG_CSRC_R4K=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_DTB_RT305X_EVAL 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_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_GPIO_CDEV=y +CONFIG_GPIO_RALINK=y +CONFIG_GPIO_WATCHDOG=y +# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HZ_PERIODIC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_INTC=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_EBPF_JIT=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_LD_CAN_LINK_VDSO=y +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MIPS_SPRAM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y +CONFIG_MTD_SPLIT_JIMAGE_FW=y +CONFIG_MTD_SPLIT_SEAMA_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_RALINK_ESW_RT3050=y +CONFIG_NET_RALINK_RT3050=y +CONFIG_NET_RALINK_SOC=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_VENDOR_RALINK=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +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_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +# CONFIG_PHY_MT7621_PCI is not set +CONFIG_PHY_RALINK_USB=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_AW9523 is not set +CONFIG_PINCTRL_RALINK=y +CONFIG_PINCTRL_RT305X=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_RALINK=y +# CONFIG_RALINK_ILL_ACC is not set +CONFIG_RALINK_WDT=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_RESET_CONTROLLER=y +CONFIG_SERIAL_8250_RT288X=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SOC_MT7620 is not set +# CONFIG_SOC_MT7621 is not set +# CONFIG_SOC_RT288X is not set +CONFIG_SOC_RT305X=y +# CONFIG_SOC_RT3883 is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +# CONFIG_SPI_MT7621 is not set +CONFIG_SPI_RT2880=y +CONFIG_SRCU=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=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_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_TARGET_ISA_REV=2 +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_WATCHDOG_CORE=y diff --git a/target/linux/ramips/rt3883/config-6.1 b/target/linux/ramips/rt3883/config-6.1 new file mode 100644 index 0000000000..2977a3b531 --- /dev/null +++ b/target/linux/ramips/rt3883/config-6.1 @@ -0,0 +1,182 @@ +CONFIG_AR8216_PHY=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_SUSPEND_POSSIBLE=y +CONFIG_BLK_MQ_PCI=y +CONFIG_CEVT_R4K=y +CONFIG_CLK_MTMIPS=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_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_LITTLE_ENDIAN=y +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MIPSR2=y +CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y +CONFIG_CPU_R4K_CACHE_TLB=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CPU_SUPPORTS_MSA=y +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_RNG2=y +CONFIG_CSRC_R4K=y +CONFIG_DEBUG_PINCTRL=y +CONFIG_DMA_NONCOHERENT=y +# CONFIG_DTB_RT3883_EVAL is not set +CONFIG_DTB_RT_NONE=y +CONFIG_DTC=y +CONFIG_EARLY_PRINTK=y +CONFIG_ETHERNET_PACKET_MANGLE=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_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_GPIO_CDEV=y +CONFIG_GPIO_RALINK=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HZ_PERIODIC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_INTC=y +CONFIG_IRQ_MIPS_CPU=y +CONFIG_IRQ_WORK=y +CONFIG_LIBFDT=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEMFD_CREATE=y +CONFIG_MFD_SYSCON=y +CONFIG_MIGRATION=y +CONFIG_MIPS=y +CONFIG_MIPS_ASID_BITS=8 +CONFIG_MIPS_ASID_SHIFT=0 +CONFIG_MIPS_CLOCK_VSYSCALL=y +# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set +# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set +CONFIG_MIPS_CMDLINE_FROM_DTB=y +CONFIG_MIPS_EBPF_JIT=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +CONFIG_MIPS_LD_CAN_LINK_VDSO=y +# CONFIG_MIPS_NO_APPENDED_DTB is not set +CONFIG_MIPS_RAW_APPENDED_DTB=y +CONFIG_MIPS_SPRAM=y +CONFIG_MODULES_USE_ELF_REL=y +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_SPI_NOR=y +CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y +CONFIG_MTD_SPLIT_SEAMA_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NET_RALINK_MDIO=y +CONFIG_NET_RALINK_MDIO_RT2880=y +CONFIG_NET_RALINK_RT3883=y +CONFIG_NET_RALINK_SOC=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_VENDOR_RALINK=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +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_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DRIVERS_LEGACY=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +# CONFIG_PHY_MT7621_PCI is not set +CONFIG_PHY_RALINK_USB=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_AW9523 is not set +CONFIG_PINCTRL_RALINK=y +CONFIG_PINCTRL_RT3883=y +# CONFIG_PINCTRL_SINGLE is not set +CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_RALINK=y +CONFIG_RALINK_WDT=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_MMIO=y +CONFIG_RESET_CONTROLLER=y +CONFIG_RTL8366_SMI=y +CONFIG_RTL8367B_PHY=y +CONFIG_RTL8367_PHY=y +CONFIG_SERIAL_8250_RT288X=y +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_SOC_MT7620 is not set +# CONFIG_SOC_MT7621 is not set +# CONFIG_SOC_RT288X is not set +# CONFIG_SOC_RT305X is not set +CONFIG_SOC_RT3883=y +CONFIG_SPI=y +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +# CONFIG_SPI_MT7621 is not set +CONFIG_SPI_RT2880=y +CONFIG_SRCU=y +CONFIG_SWCONFIG=y +CONFIG_SWPHY=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_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_MIPS16=y +CONFIG_SYS_SUPPORTS_ZBOOT=y +CONFIG_TARGET_ISA_REV=2 +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TINY_SRCU=y +CONFIG_USB_SUPPORT=y +CONFIG_USE_OF=y +CONFIG_WATCHDOG_CORE=y From 88d982e3bd872dc7fd0de26042afa0a690688100 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Fri, 26 May 2023 20:01:38 +0200 Subject: [PATCH 25/50] ramips: 6.1: mt7621-dma: add hsdma driver to files Commit 87dd67f496f7 ("staging: mt7621-dma: remove driver from tree") removed the mt7621-dma driver. Maintain the driver downstream in the folder of the other mediatek drivers. Signed-off-by: Nick Hainke --- .../files/drivers/dma/mediatek/hsdma-mt7621.c | 758 ++++++++++++++++++ target/linux/ramips/modules.mk | 2 +- ...ediatek-add-HSDMA-support-for-mt7621.patch | 44 + 3 files changed, 803 insertions(+), 1 deletion(-) create mode 100644 target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c create mode 100644 target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch diff --git a/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c b/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c new file mode 100644 index 0000000000..8aebced277 --- /dev/null +++ b/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c @@ -0,0 +1,758 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015, Michael Lee + * MTK HSDMA support + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../virt-dma.h" + +#define HSDMA_BASE_OFFSET 0x800 + +#define HSDMA_REG_TX_BASE 0x00 +#define HSDMA_REG_TX_CNT 0x04 +#define HSDMA_REG_TX_CTX 0x08 +#define HSDMA_REG_TX_DTX 0x0c +#define HSDMA_REG_RX_BASE 0x100 +#define HSDMA_REG_RX_CNT 0x104 +#define HSDMA_REG_RX_CRX 0x108 +#define HSDMA_REG_RX_DRX 0x10c +#define HSDMA_REG_INFO 0x200 +#define HSDMA_REG_GLO_CFG 0x204 +#define HSDMA_REG_RST_CFG 0x208 +#define HSDMA_REG_DELAY_INT 0x20c +#define HSDMA_REG_FREEQ_THRES 0x210 +#define HSDMA_REG_INT_STATUS 0x220 +#define HSDMA_REG_INT_MASK 0x228 +#define HSDMA_REG_SCH_Q01 0x280 +#define HSDMA_REG_SCH_Q23 0x284 + +#define HSDMA_DESCS_MAX 0xfff +#define HSDMA_DESCS_NUM 8 +#define HSDMA_DESCS_MASK (HSDMA_DESCS_NUM - 1) +#define HSDMA_NEXT_DESC(x) (((x) + 1) & HSDMA_DESCS_MASK) + +/* HSDMA_REG_INFO */ +#define HSDMA_INFO_INDEX_MASK 0xf +#define HSDMA_INFO_INDEX_SHIFT 24 +#define HSDMA_INFO_BASE_MASK 0xff +#define HSDMA_INFO_BASE_SHIFT 16 +#define HSDMA_INFO_RX_MASK 0xff +#define HSDMA_INFO_RX_SHIFT 8 +#define HSDMA_INFO_TX_MASK 0xff +#define HSDMA_INFO_TX_SHIFT 0 + +/* HSDMA_REG_GLO_CFG */ +#define HSDMA_GLO_TX_2B_OFFSET BIT(31) +#define HSDMA_GLO_CLK_GATE BIT(30) +#define HSDMA_GLO_BYTE_SWAP BIT(29) +#define HSDMA_GLO_MULTI_DMA BIT(10) +#define HSDMA_GLO_TWO_BUF BIT(9) +#define HSDMA_GLO_32B_DESC BIT(8) +#define HSDMA_GLO_BIG_ENDIAN BIT(7) +#define HSDMA_GLO_TX_DONE BIT(6) +#define HSDMA_GLO_BT_MASK 0x3 +#define HSDMA_GLO_BT_SHIFT 4 +#define HSDMA_GLO_RX_BUSY BIT(3) +#define HSDMA_GLO_RX_DMA BIT(2) +#define HSDMA_GLO_TX_BUSY BIT(1) +#define HSDMA_GLO_TX_DMA BIT(0) + +#define HSDMA_BT_SIZE_16BYTES (0 << HSDMA_GLO_BT_SHIFT) +#define HSDMA_BT_SIZE_32BYTES (1 << HSDMA_GLO_BT_SHIFT) +#define HSDMA_BT_SIZE_64BYTES (2 << HSDMA_GLO_BT_SHIFT) +#define HSDMA_BT_SIZE_128BYTES (3 << HSDMA_GLO_BT_SHIFT) + +#define HSDMA_GLO_DEFAULT (HSDMA_GLO_MULTI_DMA | \ + HSDMA_GLO_RX_DMA | HSDMA_GLO_TX_DMA | HSDMA_BT_SIZE_32BYTES) + +/* HSDMA_REG_RST_CFG */ +#define HSDMA_RST_RX_SHIFT 16 +#define HSDMA_RST_TX_SHIFT 0 + +/* HSDMA_REG_DELAY_INT */ +#define HSDMA_DELAY_INT_EN BIT(15) +#define HSDMA_DELAY_PEND_OFFSET 8 +#define HSDMA_DELAY_TIME_OFFSET 0 +#define HSDMA_DELAY_TX_OFFSET 16 +#define HSDMA_DELAY_RX_OFFSET 0 + +#define HSDMA_DELAY_INIT(x) (HSDMA_DELAY_INT_EN | \ + ((x) << HSDMA_DELAY_PEND_OFFSET)) +#define HSDMA_DELAY(x) ((HSDMA_DELAY_INIT(x) << \ + HSDMA_DELAY_TX_OFFSET) | HSDMA_DELAY_INIT(x)) + +/* HSDMA_REG_INT_STATUS */ +#define HSDMA_INT_DELAY_RX_COH BIT(31) +#define HSDMA_INT_DELAY_RX_INT BIT(30) +#define HSDMA_INT_DELAY_TX_COH BIT(29) +#define HSDMA_INT_DELAY_TX_INT BIT(28) +#define HSDMA_INT_RX_MASK 0x3 +#define HSDMA_INT_RX_SHIFT 16 +#define HSDMA_INT_RX_Q0 BIT(16) +#define HSDMA_INT_TX_MASK 0xf +#define HSDMA_INT_TX_SHIFT 0 +#define HSDMA_INT_TX_Q0 BIT(0) + +/* tx/rx dma desc flags */ +#define HSDMA_PLEN_MASK 0x3fff +#define HSDMA_DESC_DONE BIT(31) +#define HSDMA_DESC_LS0 BIT(30) +#define HSDMA_DESC_PLEN0(_x) (((_x) & HSDMA_PLEN_MASK) << 16) +#define HSDMA_DESC_TAG BIT(15) +#define HSDMA_DESC_LS1 BIT(14) +#define HSDMA_DESC_PLEN1(_x) ((_x) & HSDMA_PLEN_MASK) + +/* align 4 bytes */ +#define HSDMA_ALIGN_SIZE 3 +/* align size 128bytes */ +#define HSDMA_MAX_PLEN 0x3f80 + +struct hsdma_desc { + u32 addr0; + u32 flags; + u32 addr1; + u32 unused; +}; + +struct mtk_hsdma_sg { + dma_addr_t src_addr; + dma_addr_t dst_addr; + u32 len; +}; + +struct mtk_hsdma_desc { + struct virt_dma_desc vdesc; + unsigned int num_sgs; + struct mtk_hsdma_sg sg[1]; +}; + +struct mtk_hsdma_chan { + struct virt_dma_chan vchan; + unsigned int id; + dma_addr_t desc_addr; + int tx_idx; + int rx_idx; + struct hsdma_desc *tx_ring; + struct hsdma_desc *rx_ring; + struct mtk_hsdma_desc *desc; + unsigned int next_sg; +}; + +struct mtk_hsdam_engine { + struct dma_device ddev; + struct device_dma_parameters dma_parms; + void __iomem *base; + struct tasklet_struct task; + volatile unsigned long chan_issued; + + struct mtk_hsdma_chan chan[1]; +}; + +static inline struct mtk_hsdam_engine *mtk_hsdma_chan_get_dev(struct mtk_hsdma_chan *chan) +{ + return container_of(chan->vchan.chan.device, struct mtk_hsdam_engine, + ddev); +} + +static inline struct mtk_hsdma_chan *to_mtk_hsdma_chan(struct dma_chan *c) +{ + return container_of(c, struct mtk_hsdma_chan, vchan.chan); +} + +static inline struct mtk_hsdma_desc *to_mtk_hsdma_desc(struct virt_dma_desc *vdesc) +{ + return container_of(vdesc, struct mtk_hsdma_desc, vdesc); +} + +static inline u32 mtk_hsdma_read(struct mtk_hsdam_engine *hsdma, u32 reg) +{ + return readl(hsdma->base + reg); +} + +static inline void mtk_hsdma_write(struct mtk_hsdam_engine *hsdma, + unsigned int reg, u32 val) +{ + writel(val, hsdma->base + reg); +} + +static void mtk_hsdma_reset_chan(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + chan->tx_idx = 0; + chan->rx_idx = HSDMA_DESCS_NUM - 1; + + mtk_hsdma_write(hsdma, HSDMA_REG_TX_CTX, chan->tx_idx); + mtk_hsdma_write(hsdma, HSDMA_REG_RX_CRX, chan->rx_idx); + + mtk_hsdma_write(hsdma, HSDMA_REG_RST_CFG, + 0x1 << (chan->id + HSDMA_RST_TX_SHIFT)); + mtk_hsdma_write(hsdma, HSDMA_REG_RST_CFG, + 0x1 << (chan->id + HSDMA_RST_RX_SHIFT)); +} + +static void hsdma_dump_reg(struct mtk_hsdam_engine *hsdma) +{ + dev_dbg(hsdma->ddev.dev, + "tbase %08x, tcnt %08x, tctx %08x, tdtx: %08x, rbase %08x, rcnt %08x, rctx %08x, rdtx %08x\n", + mtk_hsdma_read(hsdma, HSDMA_REG_TX_BASE), + mtk_hsdma_read(hsdma, HSDMA_REG_TX_CNT), + mtk_hsdma_read(hsdma, HSDMA_REG_TX_CTX), + mtk_hsdma_read(hsdma, HSDMA_REG_TX_DTX), + mtk_hsdma_read(hsdma, HSDMA_REG_RX_BASE), + mtk_hsdma_read(hsdma, HSDMA_REG_RX_CNT), + mtk_hsdma_read(hsdma, HSDMA_REG_RX_CRX), + mtk_hsdma_read(hsdma, HSDMA_REG_RX_DRX)); + + dev_dbg(hsdma->ddev.dev, + "info %08x, glo %08x, delay %08x, intr_stat %08x, intr_mask %08x\n", + mtk_hsdma_read(hsdma, HSDMA_REG_INFO), + mtk_hsdma_read(hsdma, HSDMA_REG_GLO_CFG), + mtk_hsdma_read(hsdma, HSDMA_REG_DELAY_INT), + mtk_hsdma_read(hsdma, HSDMA_REG_INT_STATUS), + mtk_hsdma_read(hsdma, HSDMA_REG_INT_MASK)); +} + +static void hsdma_dump_desc(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + struct hsdma_desc *tx_desc; + struct hsdma_desc *rx_desc; + int i; + + dev_dbg(hsdma->ddev.dev, "tx idx: %d, rx idx: %d\n", + chan->tx_idx, chan->rx_idx); + + for (i = 0; i < HSDMA_DESCS_NUM; i++) { + tx_desc = &chan->tx_ring[i]; + rx_desc = &chan->rx_ring[i]; + + dev_dbg(hsdma->ddev.dev, + "%d tx addr0: %08x, flags %08x, tx addr1: %08x, rx addr0 %08x, flags %08x\n", + i, tx_desc->addr0, tx_desc->flags, + tx_desc->addr1, rx_desc->addr0, rx_desc->flags); + } +} + +static void mtk_hsdma_reset(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + int i; + + /* disable dma */ + mtk_hsdma_write(hsdma, HSDMA_REG_GLO_CFG, 0); + + /* disable intr */ + mtk_hsdma_write(hsdma, HSDMA_REG_INT_MASK, 0); + + /* init desc value */ + for (i = 0; i < HSDMA_DESCS_NUM; i++) { + chan->tx_ring[i].addr0 = 0; + chan->tx_ring[i].flags = HSDMA_DESC_LS0 | HSDMA_DESC_DONE; + } + for (i = 0; i < HSDMA_DESCS_NUM; i++) { + chan->rx_ring[i].addr0 = 0; + chan->rx_ring[i].flags = 0; + } + + /* reset */ + mtk_hsdma_reset_chan(hsdma, chan); + + /* enable intr */ + mtk_hsdma_write(hsdma, HSDMA_REG_INT_MASK, HSDMA_INT_RX_Q0); + + /* enable dma */ + mtk_hsdma_write(hsdma, HSDMA_REG_GLO_CFG, HSDMA_GLO_DEFAULT); +} + +static int mtk_hsdma_terminate_all(struct dma_chan *c) +{ + struct mtk_hsdma_chan *chan = to_mtk_hsdma_chan(c); + struct mtk_hsdam_engine *hsdma = mtk_hsdma_chan_get_dev(chan); + unsigned long timeout; + LIST_HEAD(head); + + spin_lock_bh(&chan->vchan.lock); + chan->desc = NULL; + clear_bit(chan->id, &hsdma->chan_issued); + vchan_get_all_descriptors(&chan->vchan, &head); + spin_unlock_bh(&chan->vchan.lock); + + vchan_dma_desc_free_list(&chan->vchan, &head); + + /* wait dma transfer complete */ + timeout = jiffies + msecs_to_jiffies(2000); + while (mtk_hsdma_read(hsdma, HSDMA_REG_GLO_CFG) & + (HSDMA_GLO_RX_BUSY | HSDMA_GLO_TX_BUSY)) { + if (time_after_eq(jiffies, timeout)) { + hsdma_dump_desc(hsdma, chan); + mtk_hsdma_reset(hsdma, chan); + dev_err(hsdma->ddev.dev, "timeout, reset it\n"); + break; + } + cpu_relax(); + } + + return 0; +} + +static int mtk_hsdma_start_transfer(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + dma_addr_t src, dst; + size_t len, tlen; + struct hsdma_desc *tx_desc, *rx_desc; + struct mtk_hsdma_sg *sg; + unsigned int i; + int rx_idx; + + sg = &chan->desc->sg[0]; + len = sg->len; + chan->desc->num_sgs = DIV_ROUND_UP(len, HSDMA_MAX_PLEN); + + /* tx desc */ + src = sg->src_addr; + for (i = 0; i < chan->desc->num_sgs; i++) { + tx_desc = &chan->tx_ring[chan->tx_idx]; + + if (len > HSDMA_MAX_PLEN) + tlen = HSDMA_MAX_PLEN; + else + tlen = len; + + if (i & 0x1) { + tx_desc->addr1 = src; + tx_desc->flags |= HSDMA_DESC_PLEN1(tlen); + } else { + tx_desc->addr0 = src; + tx_desc->flags = HSDMA_DESC_PLEN0(tlen); + + /* update index */ + chan->tx_idx = HSDMA_NEXT_DESC(chan->tx_idx); + } + + src += tlen; + len -= tlen; + } + if (i & 0x1) + tx_desc->flags |= HSDMA_DESC_LS0; + else + tx_desc->flags |= HSDMA_DESC_LS1; + + /* rx desc */ + rx_idx = HSDMA_NEXT_DESC(chan->rx_idx); + len = sg->len; + dst = sg->dst_addr; + for (i = 0; i < chan->desc->num_sgs; i++) { + rx_desc = &chan->rx_ring[rx_idx]; + if (len > HSDMA_MAX_PLEN) + tlen = HSDMA_MAX_PLEN; + else + tlen = len; + + rx_desc->addr0 = dst; + rx_desc->flags = HSDMA_DESC_PLEN0(tlen); + + dst += tlen; + len -= tlen; + + /* update index */ + rx_idx = HSDMA_NEXT_DESC(rx_idx); + } + + /* make sure desc and index all up to date */ + wmb(); + mtk_hsdma_write(hsdma, HSDMA_REG_TX_CTX, chan->tx_idx); + + return 0; +} + +static int gdma_next_desc(struct mtk_hsdma_chan *chan) +{ + struct virt_dma_desc *vdesc; + + vdesc = vchan_next_desc(&chan->vchan); + if (!vdesc) { + chan->desc = NULL; + return 0; + } + chan->desc = to_mtk_hsdma_desc(vdesc); + chan->next_sg = 0; + + return 1; +} + +static void mtk_hsdma_chan_done(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + struct mtk_hsdma_desc *desc; + int chan_issued; + + chan_issued = 0; + spin_lock_bh(&chan->vchan.lock); + desc = chan->desc; + if (likely(desc)) { + if (chan->next_sg == desc->num_sgs) { + list_del(&desc->vdesc.node); + vchan_cookie_complete(&desc->vdesc); + chan_issued = gdma_next_desc(chan); + } + } else { + dev_dbg(hsdma->ddev.dev, "no desc to complete\n"); + } + + if (chan_issued) + set_bit(chan->id, &hsdma->chan_issued); + spin_unlock_bh(&chan->vchan.lock); +} + +static irqreturn_t mtk_hsdma_irq(int irq, void *devid) +{ + struct mtk_hsdam_engine *hsdma = devid; + u32 status; + + status = mtk_hsdma_read(hsdma, HSDMA_REG_INT_STATUS); + if (unlikely(!status)) + return IRQ_NONE; + + if (likely(status & HSDMA_INT_RX_Q0)) + tasklet_schedule(&hsdma->task); + else + dev_dbg(hsdma->ddev.dev, "unhandle irq status %08x\n", status); + /* clean intr bits */ + mtk_hsdma_write(hsdma, HSDMA_REG_INT_STATUS, status); + + return IRQ_HANDLED; +} + +static void mtk_hsdma_issue_pending(struct dma_chan *c) +{ + struct mtk_hsdma_chan *chan = to_mtk_hsdma_chan(c); + struct mtk_hsdam_engine *hsdma = mtk_hsdma_chan_get_dev(chan); + + spin_lock_bh(&chan->vchan.lock); + if (vchan_issue_pending(&chan->vchan) && !chan->desc) { + if (gdma_next_desc(chan)) { + set_bit(chan->id, &hsdma->chan_issued); + tasklet_schedule(&hsdma->task); + } else { + dev_dbg(hsdma->ddev.dev, "no desc to issue\n"); + } + } + spin_unlock_bh(&chan->vchan.lock); +} + +static struct dma_async_tx_descriptor *mtk_hsdma_prep_dma_memcpy( + struct dma_chan *c, dma_addr_t dest, dma_addr_t src, + size_t len, unsigned long flags) +{ + struct mtk_hsdma_chan *chan = to_mtk_hsdma_chan(c); + struct mtk_hsdma_desc *desc; + + if (len <= 0) + return NULL; + + desc = kzalloc(sizeof(*desc), GFP_ATOMIC); + if (!desc) { + dev_err(c->device->dev, "alloc memcpy decs error\n"); + return NULL; + } + + desc->sg[0].src_addr = src; + desc->sg[0].dst_addr = dest; + desc->sg[0].len = len; + + return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); +} + +static enum dma_status mtk_hsdma_tx_status(struct dma_chan *c, + dma_cookie_t cookie, + struct dma_tx_state *state) +{ + return dma_cookie_status(c, cookie, state); +} + +static void mtk_hsdma_free_chan_resources(struct dma_chan *c) +{ + vchan_free_chan_resources(to_virt_chan(c)); +} + +static void mtk_hsdma_desc_free(struct virt_dma_desc *vdesc) +{ + kfree(container_of(vdesc, struct mtk_hsdma_desc, vdesc)); +} + +static void mtk_hsdma_tx(struct mtk_hsdam_engine *hsdma) +{ + struct mtk_hsdma_chan *chan; + + if (test_and_clear_bit(0, &hsdma->chan_issued)) { + chan = &hsdma->chan[0]; + if (chan->desc) + mtk_hsdma_start_transfer(hsdma, chan); + else + dev_dbg(hsdma->ddev.dev, "chan 0 no desc to issue\n"); + } +} + +static void mtk_hsdma_rx(struct mtk_hsdam_engine *hsdma) +{ + struct mtk_hsdma_chan *chan; + int next_idx, drx_idx, cnt; + + chan = &hsdma->chan[0]; + next_idx = HSDMA_NEXT_DESC(chan->rx_idx); + drx_idx = mtk_hsdma_read(hsdma, HSDMA_REG_RX_DRX); + + cnt = (drx_idx - next_idx) & HSDMA_DESCS_MASK; + if (!cnt) + return; + + chan->next_sg += cnt; + chan->rx_idx = (chan->rx_idx + cnt) & HSDMA_DESCS_MASK; + + /* update rx crx */ + wmb(); + mtk_hsdma_write(hsdma, HSDMA_REG_RX_CRX, chan->rx_idx); + + mtk_hsdma_chan_done(hsdma, chan); +} + +static void mtk_hsdma_tasklet(struct tasklet_struct *t) +{ + struct mtk_hsdam_engine *hsdma = from_tasklet(hsdma, t, task); + + mtk_hsdma_rx(hsdma); + mtk_hsdma_tx(hsdma); +} + +static int mtk_hsdam_alloc_desc(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + int i; + + chan->tx_ring = dma_alloc_coherent(hsdma->ddev.dev, + 2 * HSDMA_DESCS_NUM * + sizeof(*chan->tx_ring), + &chan->desc_addr, GFP_ATOMIC | __GFP_ZERO); + if (!chan->tx_ring) + goto no_mem; + + chan->rx_ring = &chan->tx_ring[HSDMA_DESCS_NUM]; + + /* init tx ring value */ + for (i = 0; i < HSDMA_DESCS_NUM; i++) + chan->tx_ring[i].flags = HSDMA_DESC_LS0 | HSDMA_DESC_DONE; + + return 0; +no_mem: + return -ENOMEM; +} + +static void mtk_hsdam_free_desc(struct mtk_hsdam_engine *hsdma, + struct mtk_hsdma_chan *chan) +{ + if (chan->tx_ring) { + dma_free_coherent(hsdma->ddev.dev, + 2 * HSDMA_DESCS_NUM * sizeof(*chan->tx_ring), + chan->tx_ring, chan->desc_addr); + chan->tx_ring = NULL; + chan->rx_ring = NULL; + } +} + +static int mtk_hsdma_init(struct mtk_hsdam_engine *hsdma) +{ + struct mtk_hsdma_chan *chan; + int ret; + u32 reg; + + /* init desc */ + chan = &hsdma->chan[0]; + ret = mtk_hsdam_alloc_desc(hsdma, chan); + if (ret) + return ret; + + /* tx */ + mtk_hsdma_write(hsdma, HSDMA_REG_TX_BASE, chan->desc_addr); + mtk_hsdma_write(hsdma, HSDMA_REG_TX_CNT, HSDMA_DESCS_NUM); + /* rx */ + mtk_hsdma_write(hsdma, HSDMA_REG_RX_BASE, chan->desc_addr + + (sizeof(struct hsdma_desc) * HSDMA_DESCS_NUM)); + mtk_hsdma_write(hsdma, HSDMA_REG_RX_CNT, HSDMA_DESCS_NUM); + /* reset */ + mtk_hsdma_reset_chan(hsdma, chan); + + /* enable rx intr */ + mtk_hsdma_write(hsdma, HSDMA_REG_INT_MASK, HSDMA_INT_RX_Q0); + + /* enable dma */ + mtk_hsdma_write(hsdma, HSDMA_REG_GLO_CFG, HSDMA_GLO_DEFAULT); + + /* hardware info */ + reg = mtk_hsdma_read(hsdma, HSDMA_REG_INFO); + dev_info(hsdma->ddev.dev, "rx: %d, tx: %d\n", + (reg >> HSDMA_INFO_RX_SHIFT) & HSDMA_INFO_RX_MASK, + (reg >> HSDMA_INFO_TX_SHIFT) & HSDMA_INFO_TX_MASK); + + hsdma_dump_reg(hsdma); + + return ret; +} + +static void mtk_hsdma_uninit(struct mtk_hsdam_engine *hsdma) +{ + struct mtk_hsdma_chan *chan; + + /* disable dma */ + mtk_hsdma_write(hsdma, HSDMA_REG_GLO_CFG, 0); + + /* disable intr */ + mtk_hsdma_write(hsdma, HSDMA_REG_INT_MASK, 0); + + /* free desc */ + chan = &hsdma->chan[0]; + mtk_hsdam_free_desc(hsdma, chan); + + /* tx */ + mtk_hsdma_write(hsdma, HSDMA_REG_TX_BASE, 0); + mtk_hsdma_write(hsdma, HSDMA_REG_TX_CNT, 0); + /* rx */ + mtk_hsdma_write(hsdma, HSDMA_REG_RX_BASE, 0); + mtk_hsdma_write(hsdma, HSDMA_REG_RX_CNT, 0); + /* reset */ + mtk_hsdma_reset_chan(hsdma, chan); +} + +static const struct of_device_id mtk_hsdma_of_match[] = { + { .compatible = "mediatek,mt7621-hsdma" }, + { }, +}; + +static int mtk_hsdma_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct mtk_hsdma_chan *chan; + struct mtk_hsdam_engine *hsdma; + struct dma_device *dd; + int ret; + int irq; + void __iomem *base; + + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + match = of_match_device(mtk_hsdma_of_match, &pdev->dev); + if (!match) + return -EINVAL; + + hsdma = devm_kzalloc(&pdev->dev, sizeof(*hsdma), GFP_KERNEL); + if (!hsdma) + return -EINVAL; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + hsdma->base = base + HSDMA_BASE_OFFSET; + tasklet_setup(&hsdma->task, mtk_hsdma_tasklet); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -EINVAL; + ret = devm_request_irq(&pdev->dev, irq, mtk_hsdma_irq, + 0, dev_name(&pdev->dev), hsdma); + if (ret) { + dev_err(&pdev->dev, "failed to request irq\n"); + return ret; + } + + device_reset(&pdev->dev); + + dd = &hsdma->ddev; + dma_cap_set(DMA_MEMCPY, dd->cap_mask); + dd->copy_align = HSDMA_ALIGN_SIZE; + dd->device_free_chan_resources = mtk_hsdma_free_chan_resources; + dd->device_prep_dma_memcpy = mtk_hsdma_prep_dma_memcpy; + dd->device_terminate_all = mtk_hsdma_terminate_all; + dd->device_tx_status = mtk_hsdma_tx_status; + dd->device_issue_pending = mtk_hsdma_issue_pending; + dd->dev = &pdev->dev; + dd->dev->dma_parms = &hsdma->dma_parms; + dma_set_max_seg_size(dd->dev, HSDMA_MAX_PLEN); + INIT_LIST_HEAD(&dd->channels); + + chan = &hsdma->chan[0]; + chan->id = 0; + chan->vchan.desc_free = mtk_hsdma_desc_free; + vchan_init(&chan->vchan, dd); + + /* init hardware */ + ret = mtk_hsdma_init(hsdma); + if (ret) { + dev_err(&pdev->dev, "failed to alloc ring descs\n"); + return ret; + } + + ret = dma_async_device_register(dd); + if (ret) { + dev_err(&pdev->dev, "failed to register dma device\n"); + goto err_uninit_hsdma; + } + + ret = of_dma_controller_register(pdev->dev.of_node, + of_dma_xlate_by_chan_id, hsdma); + if (ret) { + dev_err(&pdev->dev, "failed to register of dma controller\n"); + goto err_unregister; + } + + platform_set_drvdata(pdev, hsdma); + + return 0; + +err_unregister: + dma_async_device_unregister(dd); +err_uninit_hsdma: + mtk_hsdma_uninit(hsdma); + return ret; +} + +static int mtk_hsdma_remove(struct platform_device *pdev) +{ + struct mtk_hsdam_engine *hsdma = platform_get_drvdata(pdev); + + mtk_hsdma_uninit(hsdma); + + of_dma_controller_free(pdev->dev.of_node); + dma_async_device_unregister(&hsdma->ddev); + + return 0; +} + +static struct platform_driver mtk_hsdma_driver = { + .probe = mtk_hsdma_probe, + .remove = mtk_hsdma_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = mtk_hsdma_of_match, + }, +}; +module_platform_driver(mtk_hsdma_driver); + +MODULE_AUTHOR("Michael Lee "); +MODULE_DESCRIPTION("MTK HSDMA driver"); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk index 1127a8f8ab..429bb2cd26 100644 --- a/target/linux/ramips/modules.mk +++ b/target/linux/ramips/modules.mk @@ -101,7 +101,7 @@ define KernelPackage/hsdma-mtk CONFIG_MTK_HSDMA FILES:= \ $(LINUX_DIR)/drivers/dma/virt-dma.ko \ - $(LINUX_DIR)/drivers/staging/mt7621-dma/hsdma-mt7621.ko + $(LINUX_DIR)/drivers/dma/mediatek/hsdma-mt7621.ko AUTOLOAD:=$(call AutoLoad,53,hsdma-mt7621) endef diff --git a/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch b/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch new file mode 100644 index 0000000000..e77f398c5d --- /dev/null +++ b/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch @@ -0,0 +1,44 @@ +From d94fc5ce1dc395747c3934ecffcdec0396583755 Mon Sep 17 00:00:00 2001 +From: Nick Hainke +Date: Fri, 26 May 2023 19:46:33 +0200 +Subject: [PATCH] dmaengine: mediatek: add HSDMA support for mt7621 + +Commit 87dd67f496f7 ("staging: mt7621-dma: remove driver from tree") +removed the mt7621-dma driver. Move the driver from staging to the +folder "drivers/dma/mediatek" containing already other mediatek dma +driver implementations and maintain it downstream in OpenWrt. + +This patch will not be sent to upstream linux. It is just a workaround. + +Signed-off-by: Nick Hainke +--- + drivers/dma/mediatek/Kconfig | 6 ++++++ + drivers/dma/mediatek/Makefile | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig +index 7a46a5455957..1a24d73ce87f 100644 +--- a/drivers/dma/mediatek/Kconfig ++++ b/drivers/dma/mediatek/Kconfig +@@ -36,3 +36,9 @@ config MTK_UART_APDMA + When SERIAL_8250_MT6577 is enabled, and if you want to use DMA, + you can enable the config. The DMA engine can only be used + with MediaTek SoCs. ++ ++config MTK_HSDMA ++ tristate "MTK HSDMA support" ++ depends on RALINK && SOC_MT7621 ++ select DMA_ENGINE ++ select DMA_VIRTUAL_CHANNELS +diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile +index 5ba39a5edc13..784af039b7c0 100644 +--- a/drivers/dma/mediatek/Makefile ++++ b/drivers/dma/mediatek/Makefile +@@ -2,3 +2,4 @@ + obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o + obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o + obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o ++obj-$(CONFIG_MTK_HSDMA) += hsdma-mt7621.o +-- +2.40.1 + From 0561613319f403dc139c339790511682785e2cfc Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Fri, 26 May 2023 20:04:25 +0200 Subject: [PATCH 26/50] ramips: 6.1: mt7621-dma: apply dma handle error from device_reset patch Apply the "109-drivers-mt7621-dma-handle-error-from-device_reset.patch" directly on the downstream maintained dma driver. Signed-off-by: Nick Hainke --- .../files/drivers/dma/mediatek/hsdma-mt7621.c | 4 ++- ...1-dma-handle-error-from-device_reset.patch | 31 ------------------- 2 files changed, 3 insertions(+), 32 deletions(-) delete mode 100644 target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch diff --git a/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c b/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c index 8aebced277..a3a9a7f4ae 100644 --- a/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c +++ b/target/linux/ramips/files/drivers/dma/mediatek/hsdma-mt7621.c @@ -680,7 +680,9 @@ static int mtk_hsdma_probe(struct platform_device *pdev) return ret; } - device_reset(&pdev->dev); + ret = device_reset(&pdev->dev); + if (ret) + dev_err(&pdev->dev, "failed to reset device\n"); dd = &hsdma->ddev; dma_cap_set(DMA_MEMCPY, dd->cap_mask); diff --git a/target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch b/target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch deleted file mode 100644 index a4543337ff..0000000000 --- a/target/linux/ramips/patches-6.1/109-drivers-mt7621-dma-handle-error-from-device_reset.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3f6dfa25128e428acfba20792bc7506d58806baa Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 7 May 2023 01:06:17 +0200 -Subject: [PATCH] drivers: mt7621-dma: handle error from device_reset - -Handle error from device reset to fix compilation warning. -Fix compilation warning: -drivers/staging/mt7621-dma/hsdma-mt7621.c: In function 'mtk_hsdma_probe': -drivers/staging/mt7621-dma/hsdma-mt7621.c:685:9: error: ignoring return value of 'device_reset' declared with attribute 'warn_unused_result' [-Werror=unused-result] - 685 | device_reset(&pdev->dev); - | ^~~~~~~~~~~~~~~~~~~~~~~~ -cc1: all warnings being treated as errors - -Signed-off-by: Christian Marangi ---- - drivers/staging/mt7621-dma/hsdma-mt7621.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/staging/mt7621-dma/hsdma-mt7621.c -+++ b/drivers/staging/mt7621-dma/hsdma-mt7621.c -@@ -682,7 +682,9 @@ static int mtk_hsdma_probe(struct platfo - return ret; - } - -- device_reset(&pdev->dev); -+ ret = device_reset(&pdev->dev); -+ if (ret) -+ dev_err(&pdev->dev, "failed to reset device\n"); - - dd = &hsdma->ddev; - dma_cap_set(DMA_MEMCPY, dd->cap_mask); From 3358045d1db3c50f252f19d0c2f0e0ccaae396ae Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Fri, 26 May 2023 21:01:01 +0200 Subject: [PATCH 27/50] ramips: 6.1: pinctrl: fix compilation with 6.1 Upstream changed in ed5c2f5fd10d ("i2c: Make remove callback return void") the i2c driver's remove function to return no value. Adapt the driver code to compile with 5.15 and 6.1 like it is done in other projects [0]. Fixes errors in the form of: make[8]: Leaving directory '/home/nick/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-6.1.29' CC drivers/pinctrl/pinctrl-aw9523.o drivers/pinctrl/pinctrl-aw9523.c:1117:19: error: initialization of 'void (*)(struct i2c_client *)' from incompatible pointer type 'int (*)(struct i2c_client *)' [-Werror=incompatible-pointer-types] 1117 | .remove = aw9523_remove, | ^~~~~~~~~~~~~ drivers/pinctrl/pinctrl-aw9523.c:1117:19: note: (near initialization for 'aw9523_driver.remove') cc1: all warnings being treated as errors [0] - https://gitlab.com/ddcci-driver-linux/ddcci-driver-linux/-/merge_requests/10/diffs Signed-off-by: Nick Hainke --- .../ramips/files/drivers/pinctrl/pinctrl-aw9523.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c b/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c index 4900c5a0c0..e151f44590 100644 --- a/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c +++ b/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c @@ -1097,6 +1097,13 @@ static int aw9523_remove(struct i2c_client *client) return 0; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) +static void aw9523_remove_void(struct i2c_client *client) +{ + aw9523_remove(client); +} +#endif + static const struct i2c_device_id aw9523_i2c_id_table[] = { { "aw9523_i2c", 0 }, { } @@ -1114,7 +1121,11 @@ static struct i2c_driver aw9523_driver = { .of_match_table = of_aw9523_i2c_match, }, .probe = aw9523_probe, + #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) + .remove = aw9523_remove_void, + #else .remove = aw9523_remove, + #endif .id_table = aw9523_i2c_id_table, }; module_i2c_driver(aw9523_driver); From 31b3e61d77eccf62b13340013eae6aea40940444 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Thu, 8 Feb 2024 14:15:40 +0100 Subject: [PATCH 28/50] ramips: 6.1: dai_dma: drop dma_data->slave_id in mt7620 support patch Upstream dropped slave_id in dai_dma [0]. So drop it also in the mt7620 support patch. Fixes errors in the form of: sound/soc/ralink/ralink-i2s.c: In function 'ralink_i2s_init_dma_data': sound/soc/ralink/ralink-i2s.c:452:17: error: 'struct snd_dmaengine_dai_dma_data' has no member named 'slave_id' 452 | dma_data->slave_id = i2s->txdma_req; | ^~ sound/soc/ralink/ralink-i2s.c:462:17: error: 'struct snd_dmaengine_dai_dma_data' has no member named 'slave_id' 462 | dma_data->slave_id = i2s->rxdma_req; | ^~ [0] - https://lore.kernel.org/r/20211122222203.4103644-3-arnd@kernel.org Signed-off-by: Nick Hainke --- .../ramips/patches-6.1/835-asoc-add-mt7620-support.patch | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch index 551fdd8b3c..ef202ca474 100644 --- a/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch +++ b/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch @@ -60,7 +60,7 @@ Signed-off-by: John Crispin +obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o --- /dev/null +++ b/sound/soc/ralink/ralink-i2s.c -@@ -0,0 +1,970 @@ +@@ -0,0 +1,968 @@ +/* + * Copyright (C) 2010, Lars-Peter Clausen + * Copyright (C) 2016 Michael Lee @@ -512,7 +512,6 @@ Signed-off-by: John Crispin + 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; @@ -522,7 +521,6 @@ Signed-off-by: John Crispin + 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) From eeeb0b53494ec08da8b5c746890158834b5ff263 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Thu, 8 Feb 2024 15:08:18 +0100 Subject: [PATCH 29/50] ramips: 6.1: pwm: rewrite mtk_pwm_ops to fix pwm driver Upstream dropped support for legacy driver [0]. Rewrite the driver like the renesas pwm driver [1]. Fixes erros in the form of: make: *** [/__w/openwrt/openwrt/openwrt/include/toplevel.mk:232: target/compile] Error 1 ====== Make errors from logs/target/linux/compile.txt ====== | ^~~~~~~~~~~~~~ drivers/pwm/pwm-mediatek-ramips.c:107:19: note: (near initialization for 'mtk_pwm_ops.free') drivers/pwm/pwm-mediatek-ramips.c:108:10: error: 'const struct pwm_ops' has no member named 'disable' 108 | .disable = mtk_pwm_disable, | ^~~~~~~ drivers/pwm/pwm-mediatek-ramips.c:108:20: error: initialization of 'int (*)(struct pwm_chip *, struct pwm_device *, struct pwm_capture *, long unsigned int)' from incompatible pointer type 'void (*)(struct pwm_chip *, struct pwm_device *)' [-Werror=incompatible-pointer-types] 108 | .disable = mtk_pwm_disable, | ^~~~~~~~~~~~~~~ drivers/pwm/pwm-mediatek-ramips.c:108:20: note: (near initialization for 'mtk_pwm_ops.capture') cc1: all warnings being treated as errors [0] - https://github.com/torvalds/linux/commit/0829c35dc5346e90f428de61896362b51ab58296 [1] - https://github.com/torvalds/linux/commit/ec00cd5e63f05461ab48128775c73c851c3c2b18 Signed-off-by: Nick Hainke --- .../845-pwm-add-mediatek-support.patch | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch b/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch index 06074d6031..15c7cf39a2 100644 --- a/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch +++ b/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch @@ -41,7 +41,7 @@ Signed-off-by: John Crispin obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o --- /dev/null +++ b/drivers/pwm/pwm-mediatek-ramips.c -@@ -0,0 +1,175 @@ +@@ -0,0 +1,197 @@ +/* + * Mediatek Pulse Width Modulator driver + * @@ -146,10 +146,32 @@ Signed-off-by: John Crispin + iowrite32(val, pc->mmio_base); +} + ++static int mtk_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ++ const struct pwm_state *state) ++{ ++ int err; ++ bool enabled = pwm->state.enabled; ++ ++ if (!state->enabled) { ++ if (enabled) ++ mtk_pwm_disable(chip, pwm); ++ ++ return 0; ++ } ++ ++ err = mtk_pwm_config(pwm->chip, pwm, ++ state->duty_cycle, state->period); ++ if (err) ++ return err; ++ ++ if (!enabled) ++ err = mtk_pwm_enable(chip, pwm); ++ ++ return err; ++} ++ +static const struct pwm_ops mtk_pwm_ops = { -+ .config = mtk_pwm_config, -+ .enable = mtk_pwm_enable, -+ .disable = mtk_pwm_disable, ++ .apply = mtk_pwm_apply, + .owner = THIS_MODULE, +}; + From 31c4fc7414a6c01a4a8341692f1ee181bf10b436 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Thu, 8 Feb 2024 14:48:50 +0100 Subject: [PATCH 30/50] ramips: 6.1: ralink: fix const warning in the ethernet driver Change fe_hw_set_macaddr and the set_mac parameter to const to fix errors in the form of: drivers/net/ethernet/ralink/mtk_eth_soc.c: In function 'fe_set_mac_address': drivers/net/ethernet/ralink/mtk_eth_soc.c:174:53: error: passing argument 2 of 'priv->soc->set_mac' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] 174 | priv->soc->set_mac(priv, dev->dev_addr); | ~~~^~~~~~~~~~ drivers/net/ethernet/ralink/mtk_eth_soc.c:174:53: note: expected 'unsigned char *' but argument is of type 'const unsigned char *' drivers/net/ethernet/ralink/mtk_eth_soc.c: In function 'fe_hw_init': drivers/net/ethernet/ralink/mtk_eth_soc.c:1220:45: error: passing argument 2 of 'priv->soc->set_mac' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] 1220 | priv->soc->set_mac(priv, dev->dev_addr); | ~~~^~~~~~~~~~ drivers/net/ethernet/ralink/mtk_eth_soc.c:1220:45: note: expected 'unsigned char *' but argument is of type 'const unsigned char *' drivers/net/ethernet/ralink/mtk_eth_soc.c:1222:44: error: passing argument 2 of 'fe_hw_set_macaddr' discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers] 1222 | fe_hw_set_macaddr(priv, dev->dev_addr); | ~~~^~~~~~~~~~ drivers/net/ethernet/ralink/mtk_eth_soc.c:155:75: note: expected 'unsigned char *' but argument is of type 'const unsigned char *' 155 | static inline void fe_hw_set_macaddr(struct fe_priv *priv, unsigned char *mac) | ~~~~~~~~~~~~~~~^~~ cc1: all warnings being treated as errors Signed-off-by: Nick Hainke --- .../ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c | 2 +- .../ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h | 2 +- .../linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c | 2 +- .../linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c index c741c85f4a..03e65a0c8a 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c @@ -152,7 +152,7 @@ static inline void fe_int_enable(u32 mask) fe_reg_r32(FE_REG_FE_INT_ENABLE); } -static inline void fe_hw_set_macaddr(struct fe_priv *priv, unsigned char *mac) +static inline void fe_hw_set_macaddr(struct fe_priv *priv, const unsigned char *mac) { unsigned long flags; diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h index 7b291ff43e..364dd54a58 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h @@ -378,7 +378,7 @@ struct fe_soc_data { const u16 *reg_table; void (*init_data)(struct fe_soc_data *data, struct net_device *netdev); - void (*set_mac)(struct fe_priv *priv, unsigned char *mac); + void (*set_mac)(struct fe_priv *priv, const unsigned char *mac); int (*fwd_config)(struct fe_priv *priv); void (*tx_dma)(struct fe_tx_dma *txd); int (*switch_init)(struct fe_priv *priv); diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c index 172dda11b7..e2b2aceff9 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c @@ -107,7 +107,7 @@ static int mt7620_gsw_config(struct fe_priv *priv) return 0; } -static void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac) +static void mt7620_set_mac(struct fe_priv *priv, const unsigned char *mac) { struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv; unsigned long flags; diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c index 435f007477..3f961797ed 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c @@ -76,7 +76,7 @@ static void rt5350_init_data(struct fe_soc_data *data, netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM; } -static void rt5350_set_mac(struct fe_priv *priv, unsigned char *mac) +static void rt5350_set_mac(struct fe_priv *priv, const unsigned char *mac) { unsigned long flags; From 10452ea407b997542c4b629300ffffac677c4bc8 Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Thu, 8 Feb 2024 21:57:12 +0100 Subject: [PATCH 31/50] ramips: 6.1: spi: fix patch by replacing cs_gpio with cs_gpiod Upstream commit f48dc6b96649 ("spi: Retire legacy GPIO handling") [0] removed support using GPIOs as chip select. Fix it by replacing cs_gpio with cs_gpiod. [0] - https://github.com/torvalds/linux/commit/f48dc6b9664963107e500aecfc2f4df27dc5afb6 Signed-off-by: Mieczyslaw Nalewaj [split commit and rewrite commit message] Signed-off-by: Nick Hainke --- .../821-SPI-ralink-add-Ralink-SoC-spi-driver.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch index fa119ab211..7815ecf5a0 100644 --- a/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch +++ b/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch @@ -339,8 +339,8 @@ Acked-by: John Crispin + if (spi->mode & SPI_CS_HIGH) + enable = !enable; + -+ if (spi->cs_gpio >= 0) -+ gpio_set_value(spi->cs_gpio, !enable); ++ if (spi->cs_gpiod) ++ gpiod_set_value(spi->cs_gpiod, !enable); + else if (spi->master->set_cs) + spi->master->set_cs(spi, !enable); +} From cc4d01cd6043edbe8191cbddea8133b6879b25ef Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Thu, 8 Feb 2024 22:13:50 +0100 Subject: [PATCH 32/50] ramips: 6.1: ralink: fix ethernet driver with 6.1 Fixes errors in the form of: make[9]: Entering directory '/home/nick/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7620/linux-6.1.77' CC drivers/net/ethernet/ralink/mtk_eth_soc.o drivers/net/ethernet/ralink/mtk_eth_soc.c: In function 'fe_init': drivers/net/ethernet/ralink/mtk_eth_soc.c:1368:51: warning: passing argument 2 of 'of_get_mac_address' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 1368 | of_get_mac_address(priv->dev->of_node, dev->dev_addr); | ~~~^~~~~~~~~~ In file included from drivers/net/ethernet/ralink/mtk_eth_soc.c:26: ./include/linux/of_net.h:16:59: note: expected 'u8 *' {aka 'unsigned char *'} but argument is of type 'const unsigned char *' 16 | extern int of_get_mac_address(struct device_node *np, u8 *mac); | ~~~~^~~ drivers/net/ethernet/ralink/mtk_eth_soc.c: In function 'fe_probe': drivers/net/ethernet/ralink/mtk_eth_soc.c:1641:9: error: too many arguments to function 'netif_napi_add' 1641 | netif_napi_add(netdev, &priv->rx_napi, fe_poll, napi_weight); | ^~~~~~~~~~~~~~ In file included from ./include/linux/etherdevice.h:21, from drivers/net/ethernet/ralink/mtk_eth_soc.c:21: ./include/linux/netdevice.h:2611:1: note: declared here 2611 | netif_napi_add(struct net_device *dev, struct napi_struct *napi, | ^~~~~~~~~~~~~~ Signed-off-by: Mieczyslaw Nalewaj [split commit and rewrite commit message] Signed-off-by: Nick Hainke --- .../files/drivers/net/ethernet/ralink/ethtool.c | 14 ++++++++++++++ .../drivers/net/ethernet/ralink/mtk_eth_soc.c | 10 ++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c index a3abf30c71..92cf0ef717 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c @@ -125,8 +125,15 @@ out_get_link: return ethtool_op_get_link(dev); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) +static int fe_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_rp, + struct netlink_ext_ack *extack) +#else static int fe_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) +#endif { struct fe_priv *priv = netdev_priv(dev); @@ -146,8 +153,15 @@ static int fe_set_ringparam(struct net_device *dev, return 0; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) +static void fe_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_rp, + struct netlink_ext_ack *extack) +#else static void fe_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) +#endif { struct fe_priv *priv = netdev_priv(dev); diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c index 03e65a0c8a..35a3113804 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c @@ -1365,10 +1365,8 @@ static int __init fe_init(struct net_device *dev) fe_reset_phy(priv); - of_get_mac_address(priv->dev->of_node, dev->dev_addr); - - /* If the mac address is invalid, use random mac address */ - if (!is_valid_ether_addr(dev->dev_addr)) { + /* Set the MAC address if it is correct, if not use a random MAC address */ + if (of_get_ethdev_address(priv->dev->of_node, dev)) { eth_hw_addr_random(dev); dev_err(priv->dev, "generated random MAC address %pM\n", dev->dev_addr); @@ -1638,7 +1636,11 @@ static int fe_probe(struct platform_device *pdev) priv->tx_ring.tx_ring_size *= 4; priv->rx_ring.rx_ring_size *= 4; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) + netif_napi_add_weight(netdev, &priv->rx_napi, fe_poll, napi_weight); +#else netif_napi_add(netdev, &priv->rx_napi, fe_poll, napi_weight); +#endif fe_set_ethtool_ops(netdev); err = register_netdev(netdev); From 7181eb9f814cabffc10ec94dba36c7fa3450d8d0 Mon Sep 17 00:00:00 2001 From: Nick Hainke Date: Fri, 26 May 2023 20:07:15 +0200 Subject: [PATCH 33/50] ramips: add support for 6.1 kernel Remove upstreamed patches: - 000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch - 000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch - 001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch - 001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch - 002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch - 100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch - 101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch - 102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch - 103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch - 104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch - 105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch - 106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch - 107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch - 108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch Manually refresh: - 006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch - 320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch - 405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch - 410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch - 805-pinctrl-AW9523.patch - 825-i2c-MIPS-adds-ralink-I2C-driver.patch - 830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch Automatically refresh: - 200-add-ralink-eth.patch - 314-MIPS-add-bootargs-override-property.patch - 315-owrt-hack-fix-mt7688-cache-issue.patch - 700-net-ethernet-mediatek-support-net-labels.patch - 720-Revert-net-phy-simplify-phy_link_change-arguments.patch - 721-NET-no-auto-carrier-off-support.patch - 800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch - 802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch - 810-uvc-add-iPassion-iP2970-support.patch - 821-SPI-ralink-add-Ralink-SoC-spi-driver.patch - 835-asoc-add-mt7620-support.patch - 840-serial-add-ugly-custom-baud-rate-hack.patch - 845-pwm-add-mediatek-support.patch - 850-awake-rt305x-dwc2-controller.patch Tested-by: Andre Heider # netgear,wac124 Tested-by: Andrey Jr. Melnikov # Xiaomi Mi Router 3G Tested-by: Timo Dorfner # mt7621/mir3g mt7621/rm2100 Reviewed-by: Shiji Yang Co-Developed-by: Mieczyslaw Nalewaj Signed-off-by: Nick Hainke --- target/linux/ramips/Makefile | 1 + target/linux/ramips/mt7620/config-6.1 | 22 +- target/linux/ramips/mt7621/config-6.1 | 29 +- target/linux/ramips/mt76x8/config-6.1 | 25 +- ...t-add-dt-binding-header-for-Mediatek.patch | 60 - ...ts-align-resets-with-binding-documen.patch | 114 -- ...k-mediatek-mt7621-sysc-add-reset-cel.patch | 52 - ...system-controller-node-a-reset-provi.patch | 148 -- ...21-avoid-to-init-common-ralink-reset.patch | 43 - ...ips-ralink-remove-reset-related-code.patch | 2 +- ...add-Mediatek-MTMIPS-Clock-maintainer.patch | 2 +- ...oduce-commonly-used-remap-node-funct.patch | 10 +- ...wdt-avoid-ralink-architecture-depend.patch | 2 +- ...ediaTek-MT7621-PCIe-host-controller-.patch | 1418 ----------------- ...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 - ...-mt7621-Add-sentinel-to-quirks-table.patch | 38 - ...t7621-Delay-phy-ports-initialization.patch | 52 - ...-dev_info-to-log-PCIe-card-detection.patch | 2 +- .../patches-6.1/200-add-ralink-eth.patch | 4 +- ...-MIPS-add-bootargs-override-property.patch | 4 +- ...315-owrt-hack-fix-mt7688-cache-issue.patch | 6 +- ...ort-for-buggy-MT7621S-core-detection.patch | 9 +- ...or-Add-support-for-BoHong-bh25q128as.patch | 8 +- ...driver-support-for-MT7621-nand-flash.patch | 6 +- ...ethernet-mediatek-support-net-labels.patch | 4 +- ...y-simplify-phy_link_change-arguments.patch | 20 +- .../721-NET-no-auto-carrier-off-support.patch | 6 +- ...ediatek-add-HSDMA-support-for-mt7621.patch | 7 - ...alink-add-gpio-driver-for-ralink-SoC.patch | 4 +- .../patches-6.1/805-pinctrl-AW9523.patch | 20 +- .../810-uvc-add-iPassion-iP2970-support.patch | 18 +- ...SPI-ralink-add-Ralink-SoC-spi-driver.patch | 4 +- .../825-i2c-MIPS-adds-ralink-I2C-driver.patch | 10 +- ...IPS-ralink-add-sdhci-for-mt7620a-SoC.patch | 9 +- .../835-asoc-add-mt7620-support.patch | 4 +- ...erial-add-ugly-custom-baud-rate-hack.patch | 2 +- .../845-pwm-add-mediatek-support.patch | 4 +- .../850-awake-rt305x-dwc2-controller.patch | 2 +- .../860-ramips-add-eip93-driver.patch | 6 +- target/linux/ramips/rt288x/config-6.1 | 24 +- target/linux/ramips/rt305x/config-6.1 | 22 +- target/linux/ramips/rt3883/config-6.1 | 22 +- 47 files changed, 204 insertions(+), 2432 deletions(-) delete mode 100644 target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch delete mode 100644 target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch delete mode 100644 target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch delete mode 100644 target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch delete mode 100644 target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch delete mode 100644 target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch delete mode 100644 target/linux/ramips/patches-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch delete mode 100644 target/linux/ramips/patches-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch delete mode 100644 target/linux/ramips/patches-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch delete mode 100644 target/linux/ramips/patches-6.1/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch delete mode 100644 target/linux/ramips/patches-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch delete mode 100644 target/linux/ramips/patches-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch delete mode 100644 target/linux/ramips/patches-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch delete mode 100644 target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch diff --git a/target/linux/ramips/Makefile b/target/linux/ramips/Makefile index 77b82d5334..1aaa847345 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.15 +KERNEL_TESTING_PATCHVER:=6.1 define Target/Description Build firmware images for Ralink RT288x/RT3xxx based boards. diff --git a/target/linux/ramips/mt7620/config-6.1 b/target/linux/ramips/mt7620/config-6.1 index 641b93e582..111a59ab00 100644 --- a/target/linux/ramips/mt7620/config-6.1 +++ b/target/linux/ramips/mt7620/config-6.1 @@ -6,6 +6,8 @@ CONFIG_ARCH_MMAP_RND_BITS_MAX=15 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_BLK_MQ_PCI=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CEVT_SYSTICK_QUIRK=y CONFIG_CLKEVT_RT3352=y @@ -16,6 +18,7 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_BOOL=y # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CPU_GENERIC_DUMP_TLB=y CONFIG_CPU_HAS_DIEI=y @@ -35,8 +38,11 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG2=y CONFIG_CSRC_R4K=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y # CONFIG_DTB_MT7620A_EVAL is not set @@ -46,18 +52,19 @@ CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y CONFIG_ETHERNET_PACKET_MANGLE=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_FIXED_PHY=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=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 @@ -75,7 +82,6 @@ CONFIG_GPIO_CDEV=y CONFIG_GPIO_RALINK=y CONFIG_GPIO_WATCHDOG=y # CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -105,7 +111,6 @@ CONFIG_MIPS_CLOCK_VSYSCALL=y # CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_MIPS_LD_CAN_LINK_VDSO=y # CONFIG_MIPS_NO_APPENDED_DTB is not set @@ -137,6 +142,7 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_VENDOR_RALINK=y CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -145,12 +151,17 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y # CONFIG_PHY_MT7621_PCI is not set CONFIG_PHY_RALINK_USB=y CONFIG_PINCTRL=y @@ -158,9 +169,11 @@ CONFIG_PINCTRL=y CONFIG_PINCTRL_MT7620=y CONFIG_PINCTRL_RALINK=y # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_RALINK=y CONFIG_RALINK_WDT=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y @@ -199,3 +212,4 @@ CONFIG_TINY_SRCU=y CONFIG_USB_SUPPORT=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y +CONFIG_ZBOOT_LOAD_ADDRESS=0x0 diff --git a/target/linux/ramips/mt7621/config-6.1 b/target/linux/ramips/mt7621/config-6.1 index 05e4c1ce87..8f2355c564 100644 --- a/target/linux/ramips/mt7621/config-6.1 +++ b/target/linux/ramips/mt7621/config-6.1 @@ -7,16 +7,22 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_AT803X_PHY=y CONFIG_BLK_MQ_PCI=y CONFIG_BOARD_SCACHE=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CLKSRC_MIPS_GIC=y CONFIG_CLK_MT7621=y CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 CONFIG_CLONE_BACKWARDS=y CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_BOOL=y # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y CONFIG_CPU_GENERIC_DUMP_TLB=y CONFIG_CPU_HAS_DIEI=y CONFIG_CPU_HAS_PREFETCH=y @@ -40,26 +46,28 @@ CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_ZSTD=y CONFIG_CSRC_R4K=y +CONFIG_DEBUG_INFO=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_EXCLUSIVE_SYSTEM_RAM=y CONFIG_FIXED_PHY=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=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 @@ -85,7 +93,6 @@ CONFIG_GPIO_MT7621=y 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 @@ -130,7 +137,6 @@ CONFIG_MIPS_CPC=y CONFIG_MIPS_CPS=y # CONFIG_MIPS_CPS_NS16550_BOOL is not set CONFIG_MIPS_CPU_SCACHE=y -CONFIG_MIPS_EBPF_JIT=y CONFIG_MIPS_GIC=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_MIPS_LD_CAN_LINK_VDSO=y @@ -169,7 +175,6 @@ 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 @@ -187,6 +192,7 @@ CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=4 CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -198,6 +204,9 @@ CONFIG_OF_MDIO=y CONFIG_PADATA=y CONFIG_PAGE_POOL=y CONFIG_PAGE_POOL_STATS=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PCI=y CONFIG_PCIE_MT7621=y CONFIG_PCI_DISABLE_COMMON_QUIRKS=y @@ -208,6 +217,7 @@ CONFIG_PCS_MTK_LYNXI=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y CONFIG_PHYLINK=y CONFIG_PHY_MT7621_PCI=y # CONFIG_PHY_RALINK_USB is not set @@ -220,11 +230,14 @@ CONFIG_PINCTRL_SX150X=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_GPIO=y CONFIG_POWER_SUPPLY=y +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_QCOM_NET_PHYLIB=y CONFIG_QUEUED_RWLOCKS=y CONFIG_QUEUED_SPINLOCKS=y CONFIG_RALINK=y # CONFIG_RALINK_WDT is not set +CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y @@ -291,7 +304,9 @@ CONFIG_WATCHDOG_CORE=y CONFIG_WEAK_ORDERING=y CONFIG_XPS=y CONFIG_XXHASH=y +CONFIG_ZBOOT_LOAD_ADDRESS=0x0 CONFIG_ZLIB_DEFLATE=y CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMMON=y CONFIG_ZSTD_COMPRESS=y CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/ramips/mt76x8/config-6.1 b/target/linux/ramips/mt76x8/config-6.1 index 6d6759a7c5..a1ae10c926 100644 --- a/target/linux/ramips/mt76x8/config-6.1 +++ b/target/linux/ramips/mt76x8/config-6.1 @@ -6,6 +6,8 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_AT803X_PHY=y CONFIG_BLK_MQ_PCI=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CEVT_SYSTICK_QUIRK=y CONFIG_CLKEVT_RT3352=y @@ -16,6 +18,7 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_BOOL=y # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CPU_GENERIC_DUMP_TLB=y CONFIG_CPU_HAS_DIEI=y @@ -35,8 +38,11 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG2=y CONFIG_CSRC_R4K=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y # CONFIG_DTB_MT7620A_EVAL is not set @@ -45,18 +51,19 @@ CONFIG_DTB_RT_NONE=y # CONFIG_DTB_VOCORE2 is not set CONFIG_DTC=y CONFIG_EARLY_PRINTK=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_FIXED_PHY=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=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 @@ -74,7 +81,6 @@ CONFIG_GPIO_CDEV=y CONFIG_GPIO_GENERIC=y CONFIG_GPIO_MT7621=y # CONFIG_GPIO_RALINK is not set -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -103,7 +109,6 @@ CONFIG_MIPS_CLOCK_VSYSCALL=y # CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_MIPS_LD_CAN_LINK_VDSO=y # CONFIG_MIPS_NO_APPENDED_DTB is not set @@ -132,6 +137,7 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_VENDOR_RALINK=y CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -140,12 +146,17 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y # CONFIG_PHY_MT7621_PCI is not set CONFIG_PHY_RALINK_USB=y CONFIG_PINCTRL=y @@ -153,9 +164,12 @@ CONFIG_PINCTRL=y CONFIG_PINCTRL_MT7620=y CONFIG_PINCTRL_RALINK=y # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_QCOM_NET_PHYLIB=y CONFIG_RALINK=y # CONFIG_RALINK_WDT is not set +CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y @@ -163,6 +177,8 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_RESET_CONTROLLER=y CONFIG_RTC_CLASS=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y CONFIG_SERIAL_8250_NR_UARTS=3 CONFIG_SERIAL_8250_RUNTIME_UARTS=3 CONFIG_SERIAL_MCTRL_GPIO=y @@ -198,3 +214,4 @@ CONFIG_TINY_SRCU=y CONFIG_USB_SUPPORT=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y +CONFIG_ZBOOT_LOAD_ADDRESS=0x0 diff --git a/target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch b/target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch deleted file mode 100644 index a102c607b6..0000000000 --- a/target/linux/ramips/patches-6.1/000-v5.18-01-dt-bindings-reset-add-dt-binding-header-for-Mediatek.patch +++ /dev/null @@ -1,60 +0,0 @@ -From f383b0770612838e78986231710c0a3afee4db42 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Mon, 10 Jan 2022 12:49:27 +0100 -Subject: [PATCH 1/2] dt-bindings: reset: add dt binding header for Mediatek MT7621 resets -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add dt binding header for resets lines in Mediatek MT7621 SoCs. - -Acked-by: Rob Herring -Tested-by: Arınç ÜNAL -Signed-off-by: Sergio Paracuellos -Link: https://lore.kernel.org/r/20220110114930.1406665-2-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - include/dt-bindings/reset/mt7621-reset.h | 37 ++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - create mode 100644 include/dt-bindings/reset/mt7621-reset.h - ---- /dev/null -+++ b/include/dt-bindings/reset/mt7621-reset.h -@@ -0,0 +1,37 @@ -+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ -+/* -+ * Copyright (c) 2021 Sergio Paracuellos -+ * Author: Sergio Paracuellos -+ */ -+ -+#ifndef DT_BINDING_MT7621_RESET_H -+#define DT_BINDING_MT7621_RESET_H -+ -+#define MT7621_RST_SYS 0 -+#define MT7621_RST_MCM 2 -+#define MT7621_RST_HSDMA 5 -+#define MT7621_RST_FE 6 -+#define MT7621_RST_SPDIFTX 7 -+#define MT7621_RST_TIMER 8 -+#define MT7621_RST_INT 9 -+#define MT7621_RST_MC 10 -+#define MT7621_RST_PCM 11 -+#define MT7621_RST_PIO 13 -+#define MT7621_RST_GDMA 14 -+#define MT7621_RST_NFI 15 -+#define MT7621_RST_I2C 16 -+#define MT7621_RST_I2S 17 -+#define MT7621_RST_SPI 18 -+#define MT7621_RST_UART1 19 -+#define MT7621_RST_UART2 20 -+#define MT7621_RST_UART3 21 -+#define MT7621_RST_ETH 23 -+#define MT7621_RST_PCIE0 24 -+#define MT7621_RST_PCIE1 25 -+#define MT7621_RST_PCIE2 26 -+#define MT7621_RST_AUX_STCK 28 -+#define MT7621_RST_CRYPTO 29 -+#define MT7621_RST_SDXC 30 -+#define MT7621_RST_PPE 31 -+ -+#endif /* DT_BINDING_MT7621_RESET_H */ diff --git a/target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch b/target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch deleted file mode 100644 index e4fd34b28c..0000000000 --- a/target/linux/ramips/patches-6.1/000-v5.18-02-staging-mt7621-dts-align-resets-with-binding-documen.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 64b2d6ffff862c0e7278198b4229e42e1abb3bb1 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Mon, 10 Jan 2022 12:49:30 +0100 -Subject: [PATCH 2/2] staging: mt7621-dts: align resets with binding documentation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Binding documentation for compatible 'mediatek,mt7621-sysc' has been updated -to be used as a reset provider. Align reset related bits and system controller -node with binding documentation along the dtsi file. - -Tested-by: Arınç ÜNAL -Reviewed-by: Philipp Zabel -Signed-off-by: Sergio Paracuellos -Link: https://lore.kernel.org/r/20220110114930.1406665-5-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/mt7621-dts/mt7621.dtsi | 21 +++++++++------------ - 1 file changed, 9 insertions(+), 12 deletions(-) - ---- a/drivers/staging/mt7621-dts/mt7621.dtsi -+++ b/drivers/staging/mt7621-dts/mt7621.dtsi -@@ -1,6 +1,7 @@ - #include - #include - #include -+#include - - / { - #address-cells = <1>; -@@ -59,6 +60,7 @@ - compatible = "mediatek,mt7621-sysc", "syscon"; - reg = <0x0 0x100>; - #clock-cells = <1>; -+ #reset-cells = <1>; - ralink,memctl = <&memc>; - clock-output-names = "xtal", "cpu", "bus", - "50m", "125m", "150m", -@@ -88,7 +90,7 @@ - - clocks = <&sysc MT7621_CLK_I2C>; - clock-names = "i2c"; -- resets = <&rstctrl 16>; -+ resets = <&sysc MT7621_RST_I2C>; - reset-names = "i2c"; - - #address-cells = <1>; -@@ -161,7 +163,7 @@ - clocks = <&sysc MT7621_CLK_SPI>; - clock-names = "spi"; - -- resets = <&rstctrl 18>; -+ resets = <&sysc MT7621_RST_SPI>; - reset-names = "spi"; - - #address-cells = <1>; -@@ -296,11 +298,6 @@ - }; - }; - -- rstctrl: rstctrl { -- compatible = "ralink,rt2880-reset"; -- #reset-cells = <1>; -- }; -- - sdhci: sdhci@1e130000 { - status = "disabled"; - -@@ -383,7 +380,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- resets = <&rstctrl 6 &rstctrl 23>; -+ resets = <&sysc MT7621_RST_FE &sysc MT7621_RST_ETH>; - reset-names = "fe", "eth"; - - interrupt-parent = <&gic>; -@@ -423,7 +420,7 @@ - #size-cells = <0>; - reg = <0>; - mediatek,mcm; -- resets = <&rstctrl 2>; -+ resets = <&sysc MT7621_RST_MCM>; - reset-names = "mcm"; - interrupt-controller; - #interrupt-cells = <1>; -@@ -516,7 +513,7 @@ - #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>; -+ resets = <&sysc MT7621_RST_PCIE0>; - clocks = <&sysc MT7621_CLK_PCIE0>; - phys = <&pcie0_phy 1>; - phy-names = "pcie-phy0"; -@@ -531,7 +528,7 @@ - #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>; -+ resets = <&sysc MT7621_RST_PCIE1>; - clocks = <&sysc MT7621_CLK_PCIE1>; - phys = <&pcie0_phy 1>; - phy-names = "pcie-phy1"; -@@ -546,7 +543,7 @@ - #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>; -+ resets = <&sysc MT7621_RST_PCIE2>; - clocks = <&sysc MT7621_CLK_PCIE2>; - phys = <&pcie2_phy 0>; - phy-names = "pcie-phy2"; diff --git a/target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch b/target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch deleted file mode 100644 index 7fb95064f0..0000000000 --- a/target/linux/ramips/patches-6.1/001-v5.18-01-dt-bindings-clock-mediatek-mt7621-sysc-add-reset-cel.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 478b09fa2c00cbc40d25bc061befdf11f04a27ad Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Thu, 10 Feb 2022 10:48:58 +0100 -Subject: [PATCH 1/2] dt-bindings: clock: mediatek,mt7621-sysc: add '#reset-cells' property - -Make system controller a reset provider for all the peripherals in the -MT7621 SoC adding '#reset-cells' property. - -Acked-by: Rob Herring -Acked-by: Stephen Boyd -Signed-off-by: Sergio Paracuellos -Link: https://lore.kernel.org/r/20220210094859.927868-2-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - .../devicetree/bindings/clock/mediatek,mt7621-sysc.yaml | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml -+++ b/Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml -@@ -22,6 +22,11 @@ description: | - - The clocks are provided inside a system controller node. - -+ This node is also a reset provider for all the peripherals. -+ -+ Reset related bits are defined in: -+ [2]: . -+ - properties: - compatible: - items: -@@ -37,6 +42,12 @@ properties: - clocks. - const: 1 - -+ "#reset-cells": -+ description: -+ The first cell indicates the reset bit within the register, see -+ [2] for available resets. -+ const: 1 -+ - ralink,memctl: - $ref: /schemas/types.yaml#/definitions/phandle - description: -@@ -61,6 +72,7 @@ examples: - compatible = "mediatek,mt7621-sysc", "syscon"; - reg = <0x0 0x100>; - #clock-cells = <1>; -+ #reset-cells = <1>; - ralink,memctl = <&memc>; - clock-output-names = "xtal", "cpu", "bus", - "50m", "125m", "150m", diff --git a/target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch b/target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch deleted file mode 100644 index c70a1c9bbc..0000000000 --- a/target/linux/ramips/patches-6.1/001-v5.18-02-clk-ralink-make-system-controller-node-a-reset-provi.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 38a8553b0a22ed54f014d8402fedd268b529175c Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Thu, 10 Feb 2022 10:48:59 +0100 -Subject: [PATCH 2/2] clk: ralink: make system controller node a reset provider - -MT7621 system controller node is already providing the clocks for the whole -system but must also serve as a reset provider. Hence, add reset controller -related code to the clock driver itself. To get resets properly ready for -the rest of the world we need to move platform driver initialization process -to 'arch_initcall'. - -CC: Philipp Zabel -Reviewed-by: Philipp Zabel -Acked-by: Stephen Boyd -Signed-off-by: Sergio Paracuellos -Link: https://lore.kernel.org/r/20220210094859.927868-3-sergio.paracuellos@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/clk/ralink/clk-mt7621.c | 92 ++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 91 insertions(+), 1 deletion(-) - ---- a/drivers/clk/ralink/clk-mt7621.c -+++ b/drivers/clk/ralink/clk-mt7621.c -@@ -11,14 +11,17 @@ - #include - #include - #include -+#include - #include - #include -+#include - - /* Configuration registers */ - #define SYSC_REG_SYSTEM_CONFIG0 0x10 - #define SYSC_REG_SYSTEM_CONFIG1 0x14 - #define SYSC_REG_CLKCFG0 0x2c - #define SYSC_REG_CLKCFG1 0x30 -+#define SYSC_REG_RESET_CTRL 0x34 - #define SYSC_REG_CUR_CLK_STS 0x44 - #define MEMC_REG_CPU_PLL 0x648 - -@@ -398,6 +401,82 @@ free_clk_priv: - } - CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init); - -+struct mt7621_rst { -+ struct reset_controller_dev rcdev; -+ struct regmap *sysc; -+}; -+ -+static struct mt7621_rst *to_mt7621_rst(struct reset_controller_dev *dev) -+{ -+ return container_of(dev, struct mt7621_rst, rcdev); -+} -+ -+static int mt7621_assert_device(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct mt7621_rst *data = to_mt7621_rst(rcdev); -+ struct regmap *sysc = data->sysc; -+ -+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id)); -+} -+ -+static int mt7621_deassert_device(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct mt7621_rst *data = to_mt7621_rst(rcdev); -+ struct regmap *sysc = data->sysc; -+ -+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0); -+} -+ -+static int mt7621_reset_device(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ int ret; -+ -+ ret = mt7621_assert_device(rcdev, id); -+ if (ret < 0) -+ return ret; -+ -+ return mt7621_deassert_device(rcdev, id); -+} -+ -+static int mt7621_rst_xlate(struct reset_controller_dev *rcdev, -+ const struct of_phandle_args *reset_spec) -+{ -+ unsigned long id = reset_spec->args[0]; -+ -+ if (id == MT7621_RST_SYS || id >= rcdev->nr_resets) -+ return -EINVAL; -+ -+ return id; -+} -+ -+static const struct reset_control_ops reset_ops = { -+ .reset = mt7621_reset_device, -+ .assert = mt7621_assert_device, -+ .deassert = mt7621_deassert_device -+}; -+ -+static int mt7621_reset_init(struct device *dev, struct regmap *sysc) -+{ -+ struct mt7621_rst *rst_data; -+ -+ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); -+ if (!rst_data) -+ return -ENOMEM; -+ -+ rst_data->sysc = sysc; -+ rst_data->rcdev.ops = &reset_ops; -+ rst_data->rcdev.owner = THIS_MODULE; -+ rst_data->rcdev.nr_resets = 32; -+ rst_data->rcdev.of_reset_n_cells = 1; -+ rst_data->rcdev.of_xlate = mt7621_rst_xlate; -+ rst_data->rcdev.of_node = dev_of_node(dev); -+ -+ return devm_reset_controller_register(dev, &rst_data->rcdev); -+} -+ - static int mt7621_clk_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; -@@ -424,6 +503,12 @@ static int mt7621_clk_probe(struct platf - return ret; - } - -+ ret = mt7621_reset_init(dev, priv->sysc); -+ if (ret) { -+ dev_err(dev, "Could not init reset controller\n"); -+ return ret; -+ } -+ - count = ARRAY_SIZE(mt7621_clks_base) + - ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates); - clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count), -@@ -485,4 +570,9 @@ static struct platform_driver mt7621_clk - .of_match_table = mt7621_clk_of_match, - }, - }; --builtin_platform_driver(mt7621_clk_driver); -+ -+static int __init mt7621_clk_reset_init(void) -+{ -+ return platform_driver_register(&mt7621_clk_driver); -+} -+arch_initcall(mt7621_clk_reset_init); diff --git a/target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch b/target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch deleted file mode 100644 index cef73c6eae..0000000000 --- a/target/linux/ramips/patches-6.1/002-v6.0-MIPS-ralink-mt7621-avoid-to-init-common-ralink-reset.patch +++ /dev/null @@ -1,43 +0,0 @@ -From bb3ababe7f986900672e0048153c31aa4a21f96b Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Sat, 17 Dec 2022 08:48:06 +0100 -Subject: [PATCH] MIPS: ralink: mt7621: avoid to init common ralink reset controller - -[ Upstream commit 76ce51798cb16738a4a28a6662e7344aaf7ef769 ] - -Commit 38a8553b0a22 ("clk: ralink: make system controller node a reset provider") -make system controller a reset provider for mt7621 ralink SoCs. Ralink init code -also tries to start previous common reset controller which at the end tries to -find device tree node 'ralink,rt2880-reset'. mt7621 device tree file is not -using at all this node anymore. Hence avoid to init this common reset controller -for mt7621 ralink SoCs to avoid 'Failed to find reset controller node' boot -error trace error. - -Fixes: 64b2d6ffff86 ("staging: mt7621-dts: align resets with binding documentation") -Signed-off-by: Sergio Paracuellos -Signed-off-by: Thomas Bogendoerfer -Signed-off-by: Sasha Levin ---- - arch/mips/ralink/of.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/arch/mips/ralink/of.c -+++ b/arch/mips/ralink/of.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include "common.h" - -@@ -95,7 +96,8 @@ static int __init plat_of_setup(void) - __dt_register_buses(soc_info.compatible, "palmbus"); - - /* make sure that the reset controller is setup early */ -- ralink_rst_init(); -+ if (ralink_soc != MT762X_SOC_MT7621AT) -+ ralink_rst_init(); - - return 0; - } diff --git a/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch b/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch index bdd9fcfd33..e96a9084a6 100644 --- a/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch +++ b/target/linux/ramips/patches-6.1/005-v6.5-07-mips-ralink-remove-reset-related-code.patch @@ -31,7 +31,7 @@ Signed-off-by: Thomas Bogendoerfer __iomem void *plat_of_remap_node(const char *node); --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c -@@ -95,10 +95,6 @@ static int __init plat_of_setup(void) +@@ -81,10 +81,6 @@ static int __init plat_of_setup(void) { __dt_register_buses(soc_info.compatible, "palmbus"); diff --git a/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch b/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch index d05c1954f7..35a1c91f7c 100644 --- a/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch +++ b/target/linux/ramips/patches-6.1/005-v6.5-09-MAINTAINERS-add-Mediatek-MTMIPS-Clock-maintainer.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Bogendoerfer --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -11859,6 +11859,12 @@ S: Maintained +@@ -13012,6 +13012,12 @@ S: Maintained F: Documentation/devicetree/bindings/clock/mediatek,mt7621-sysc.yaml F: drivers/clk/ralink/clk-mt7621.c diff --git a/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch b/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch index 429b9feb9d..f5c148101f 100644 --- a/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch +++ b/target/linux/ramips/patches-6.1/006-v6.5-mips-ralink-introduce-commonly-used-remap-node-funct.patch @@ -53,7 +53,7 @@ Signed-off-by: Thomas Bogendoerfer { --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c -@@ -58,15 +58,6 @@ static void __init mt7621_memory_detect( +@@ -89,15 +89,6 @@ static void __init mt7621_memory_detect( memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE); } @@ -71,7 +71,7 @@ Signed-off-by: Thomas Bogendoerfer return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0); --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c -@@ -29,26 +29,56 @@ __iomem void *rt_sysc_membase; +@@ -29,28 +29,56 @@ __iomem void *rt_sysc_membase; __iomem void *rt_memc_membase; EXPORT_SYMBOL_GPL(rt_sysc_membase); @@ -108,6 +108,8 @@ Signed-off-by: Thomas Bogendoerfer if (of_address_to_resource(np, 0, &res)) - panic("Failed to get resource for %s", node); +- +- of_node_put(np); + panic("Failed to get resource for %s node", np->name); if (!request_mem_region(res.start, @@ -130,9 +132,9 @@ Signed-off-by: Thomas Bogendoerfer + panic("Failed to remap core resources"); +} + - void __init device_tree_init(void) + void __init plat_mem_setup(void) { - unflatten_and_copy_device_tree(); + void *dtb; --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c @@ -17,15 +17,6 @@ diff --git a/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch b/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch index 8e6265404b..7e4e45df13 100644 --- a/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch +++ b/target/linux/ramips/patches-6.1/009-v6.3-02-watchdog-mt7621-wdt-avoid-ralink-architecture-depend.patch @@ -24,7 +24,7 @@ Signed-off-by: Wim Van Sebroeck --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -1799,7 +1799,9 @@ config RALINK_WDT +@@ -1865,7 +1865,9 @@ config GXP_WATCHDOG config MT7621_WDT tristate "Mediatek SoC watchdog" select WATCHDOG_CORE diff --git a/target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch b/target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch deleted file mode 100644 index 1c8c7cd3d0..0000000000 --- a/target/linux/ramips/patches-6.1/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch +++ /dev/null @@ -1,1418 +0,0 @@ -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,601 +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 { -- struct device *dev; -- void __iomem *base; -- 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_pcie_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_pcie_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_pcie_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_pcie_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_pcie_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_pcie_ops; -- host->sysdata = pcie; -- return pci_host_probe(host); --} -- --static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { -- { .soc_id = "mt7621", .revision = "E2" }, -- { /* sentinel */ } --}; -- --static int mt7621_pcie_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_pcie_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_pcie_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_pcie_ids[] = { -- { .compatible = "mediatek,mt7621-pci" }, -- {}, --}; --MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); -- --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_pcie_ids), -- }, --}; --builtin_platform_driver(mt7621_pcie_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-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch b/target/linux/ramips/patches-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch deleted file mode 100644 index 916477511d..0000000000 --- a/target/linux/ramips/patches-6.1/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch +++ /dev/null @@ -1,134 +0,0 @@ -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-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch b/target/linux/ramips/patches-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch deleted file mode 100644 index 815ecc7d37..0000000000 --- a/target/linux/ramips/patches-6.1/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch +++ /dev/null @@ -1,30 +0,0 @@ -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-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch b/target/linux/ramips/patches-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch deleted file mode 100644 index 4b46b3e3f6..0000000000 --- a/target/linux/ramips/patches-6.1/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch +++ /dev/null @@ -1,119 +0,0 @@ -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 -@@ -25,6 +27,35 @@ - static u32 detect_magic __initdata; - static struct ralink_soc_info *soc_info_ptr; - -+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-6.1/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch b/target/linux/ramips/patches-6.1/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch deleted file mode 100644 index 0913a452c6..0000000000 --- a/target/linux/ramips/patches-6.1/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch +++ /dev/null @@ -1,35 +0,0 @@ -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-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch b/target/linux/ramips/patches-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch deleted file mode 100644 index 0323588e5a..0000000000 --- a/target/linux/ramips/patches-6.1/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch +++ /dev/null @@ -1,35 +0,0 @@ -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-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch b/target/linux/ramips/patches-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch deleted file mode 100644 index 2fbbf9a7aa..0000000000 --- a/target/linux/ramips/patches-6.1/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch +++ /dev/null @@ -1,38 +0,0 @@ -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-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch b/target/linux/ramips/patches-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch deleted file mode 100644 index c055f0096d..0000000000 --- a/target/linux/ramips/patches-6.1/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 19098934f910b4d47cb30251dd39ffa57bef9523 Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Tue, 6 Dec 2022 06:46:45 +1000 -Subject: [PATCH] PCI: mt7621: Add sentinel to quirks table - -Current driver is missing a sentinel in the struct soc_device_attribute -array, which causes an oops when assessed by the -soc_device_match(mt7621_pcie_quirks_match) call. - -This was only exposed once the CONFIG_SOC_MT7621 mt7621 soc_dev_attr -was fixed to register the SOC as a device, in: - -commit 7c18b64bba3b ("mips: ralink: mt7621: do not use kzalloc too early") - -Fix it by adding the required sentinel. - -Link: https://lore.kernel.org/lkml/26ebbed1-0fe9-4af9-8466-65f841d0b382@app.fastmail.com -Link: https://lore.kernel.org/r/20221205204645.301301-1-git@johnthomson.fastmail.com.au -Fixes: b483b4e4d3f6 ("staging: mt7621-pci: add quirks for 'E2' revision using 'soc_device_attribute'") -Signed-off-by: John Thomson -Signed-off-by: Lorenzo Pieralisi -Acked-by: Sergio Paracuellos ---- - drivers/pci/controller/pcie-mt7621.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(str - } - - static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { -- { .soc_id = "mt7621", .revision = "E2" } -+ { .soc_id = "mt7621", .revision = "E2" }, -+ { /* sentinel */ } - }; - - static int mt7621_pcie_probe(struct platform_device *pdev) diff --git a/target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch b/target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch deleted file mode 100644 index de1d4cfc12..0000000000 --- a/target/linux/ramips/patches-6.1/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0cb2a8f3456ff1cc51d571e287a48e8fddc98ec2 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Sat, 31 Dec 2022 08:40:41 +0100 -Subject: PCI: mt7621: Delay phy ports initialization - -Some devices like ZBT WE1326 and ZBT WF3526-P and some Netgear models need -to delay phy port initialization after calling the mt7621_pcie_init_port() -driver function to get into reliable boots for both warm and hard resets. - -The delay required to detect the ports seems to be in the range [75-100] -milliseconds. - -If the ports are not detected the controller is not functional. - -There is no datasheet or something similar to really understand why this -extra delay is needed only for these devices and it is not for most of -the boards that are built on mt7621 SoC. - -This issue has been reported by openWRT community and the complete -discussion is in [0]. The 100 milliseconds delay has been tested in all -devices to validate it. - -Add the extra 100 milliseconds delay to fix the issue. - -[0]: https://github.com/openwrt/openwrt/pull/11220 - -Link: https://lore.kernel.org/r/20221231074041.264738-1-sergio.paracuellos@gmail.com -Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") -Signed-off-by: Sergio Paracuellos -Signed-off-by: Lorenzo Pieralisi ---- - drivers/pci/controller/pcie-mt7621.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -58,6 +58,7 @@ - #define PCIE_PORT_LINKUP BIT(0) - #define PCIE_PORT_CNT 3 - -+#define INIT_PORTS_DELAY_MS 100 - #define PERST_DELAY_MS 100 - - /** -@@ -374,6 +375,7 @@ static int mt7621_pcie_init_ports(struct - } - } - -+ msleep(INIT_PORTS_DELAY_MS); - mt7621_pcie_reset_ep_deassert(pcie); - - tmp = NULL; diff --git a/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch b/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch index 94519b9c01..ad2191e655 100644 --- a/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch +++ b/target/linux/ramips/patches-6.1/110-v6.4-PCI-mt7621-Use-dev_info-to-log-PCIe-card-detection.patch @@ -18,7 +18,7 @@ Signed-off-by: Lorenzo Pieralisi --- a/drivers/pci/controller/pcie-mt7621.c +++ b/drivers/pci/controller/pcie-mt7621.c -@@ -383,8 +383,8 @@ static int mt7621_pcie_init_ports(struct +@@ -378,8 +378,8 @@ static int mt7621_pcie_init_ports(struct u32 slot = port->slot; if (!mt7621_pcie_port_is_linkup(port)) { diff --git a/target/linux/ramips/patches-6.1/200-add-ralink-eth.patch b/target/linux/ramips/patches-6.1/200-add-ralink-eth.patch index 63c864ff7c..cd18fe7dd4 100644 --- a/target/linux/ramips/patches-6.1/200-add-ralink-eth.patch +++ b/target/linux/ramips/patches-6.1/200-add-ralink-eth.patch @@ -1,6 +1,6 @@ --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig -@@ -162,6 +162,7 @@ source "drivers/net/ethernet/pensando/Kc +@@ -167,6 +167,7 @@ source "drivers/net/ethernet/pensando/Kc source "drivers/net/ethernet/qlogic/Kconfig" source "drivers/net/ethernet/brocade/Kconfig" source "drivers/net/ethernet/qualcomm/Kconfig" @@ -10,7 +10,7 @@ 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) +@@ -77,6 +77,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/ diff --git a/target/linux/ramips/patches-6.1/314-MIPS-add-bootargs-override-property.patch b/target/linux/ramips/patches-6.1/314-MIPS-add-bootargs-override-property.patch index e7dca7af88..26a28167c6 100644 --- a/target/linux/ramips/patches-6.1/314-MIPS-add-bootargs-override-property.patch +++ b/target/linux/ramips/patches-6.1/314-MIPS-add-bootargs-override-property.patch @@ -17,7 +17,7 @@ Signed-off-by: David Bauer --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c -@@ -547,8 +547,28 @@ static int __init bootcmdline_scan_chose +@@ -557,8 +557,28 @@ static int __init bootcmdline_scan_chose #endif /* CONFIG_OF_EARLY_FLATTREE */ @@ -46,7 +46,7 @@ Signed-off-by: David Bauer bool dt_bootargs = false; /* -@@ -562,6 +582,14 @@ static void __init bootcmdline_init(void +@@ -572,6 +592,14 @@ static void __init bootcmdline_init(void } /* diff --git a/target/linux/ramips/patches-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch b/target/linux/ramips/patches-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch index 4f9eec7271..c31e6d7cde 100644 --- a/target/linux/ramips/patches-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch +++ b/target/linux/ramips/patches-6.1/315-owrt-hack-fix-mt7688-cache-issue.patch @@ -10,7 +10,7 @@ Signed-off-by: John Crispin --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c -@@ -689,7 +689,6 @@ static void __init arch_mem_init(char ** +@@ -699,7 +699,6 @@ static void __init arch_mem_init(char ** mips_reserve_vmcore(); mips_parse_crashkernel(); @@ -18,11 +18,11 @@ Signed-off-by: John Crispin /* * In order to reduce the possibility of kernel panic when failed to -@@ -806,6 +805,7 @@ void __init setup_arch(char **cmdline_p) +@@ -834,6 +833,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-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch b/target/linux/ramips/patches-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch index 0eb6676414..ef54835f89 100644 --- a/target/linux/ramips/patches-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch +++ b/target/linux/ramips/patches-6.1/320-MIPS-add-support-for-buggy-MT7621S-core-detection.patch @@ -31,7 +31,7 @@ Signed-off-by: Thomas Bogendoerfer --- a/arch/mips/include/asm/mips-cps.h +++ b/arch/mips/include/asm/mips-cps.h -@@ -10,6 +10,8 @@ +@@ -11,6 +11,8 @@ #include #include @@ -40,7 +40,7 @@ Signed-off-by: Thomas Bogendoerfer 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_ +@@ -162,12 +164,31 @@ static inline uint64_t mips_cps_cluster_ */ static inline unsigned int mips_cps_numcores(unsigned int cluster) { @@ -50,8 +50,9 @@ Signed-off-by: Thomas Bogendoerfer 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; +- return FIELD_GET(CM_GCR_CONFIG_PCORES, ++ ncores = FIELD_GET(CM_GCR_CONFIG_PCORES, + mips_cps_cluster_config(cluster) + 1); + + if (IS_ENABLED(CONFIG_SOC_MT7621)) { + struct cpulaunch *launch; diff --git a/target/linux/ramips/patches-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch b/target/linux/ramips/patches-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch index 4cbb84efc6..3b88f78602 100644 --- a/target/linux/ramips/patches-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch +++ b/target/linux/ramips/patches-6.1/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch @@ -44,8 +44,8 @@ Signed-off-by: David Bauer + +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) }, ++ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256) ++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +}; + +const struct spi_nor_manufacturer spi_nor_bohong = { @@ -55,7 +55,7 @@ Signed-off-by: David Bauer +}; --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c -@@ -1844,6 +1844,7 @@ int spi_nor_sr2_bit7_quad_enable(struct +@@ -1620,6 +1620,7 @@ int spi_nor_sr2_bit7_quad_enable(struct static const struct spi_nor_manufacturer *manufacturers[] = { &spi_nor_atmel, @@ -65,7 +65,7 @@ Signed-off-by: David Bauer &spi_nor_esmt, --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h -@@ -473,6 +473,7 @@ struct sfdp { +@@ -617,6 +617,7 @@ struct sfdp { /* Manufacturer drivers. */ extern const struct spi_nor_manufacturer spi_nor_atmel; diff --git a/target/linux/ramips/patches-6.1/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-6.1/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch index 33a741e531..438cc1ea8f 100644 --- a/target/linux/ramips/patches-6.1/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch +++ b/target/linux/ramips/patches-6.1/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch @@ -20,7 +20,7 @@ Signed-off-by: Weijie Gao --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig -@@ -358,6 +358,14 @@ config MTD_NAND_QCOM +@@ -352,6 +352,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. @@ -34,7 +34,7 @@ Signed-off-by: Weijie Gao + config MTD_NAND_MTK tristate "MTK NAND controller" - depends on ARCH_MEDIATEK || COMPILE_TEST + depends on MTD_NAND_ECC_MEDIATEK --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n @@ -42,6 +42,6 @@ Signed-off-by: Weijie Gao 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_MTK) += 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-6.1/700-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-6.1/700-net-ethernet-mediatek-support-net-labels.patch index d9fc379bed..ac8585b74f 100644 --- a/target/linux/ramips/patches-6.1/700-net-ethernet-mediatek-support-net-labels.patch +++ b/target/linux/ramips/patches-6.1/700-net-ethernet-mediatek-support-net-labels.patch @@ -14,7 +14,7 @@ Signed-off-by: René van Dorst --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4558,6 +4558,7 @@ static const struct net_device_ops mtk_n +@@ -4612,6 +4612,7 @@ static const struct net_device_ops mtk_n static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) { @@ -22,7 +22,7 @@ Signed-off-by: René van Dorst const __be32 *_id = of_get_property(np, "reg", NULL); phy_interface_t phy_mode; struct phylink *phylink; -@@ -4729,6 +4730,9 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4783,6 +4784,9 @@ static int mtk_add_mac(struct mtk_eth *e register_netdevice_notifier(&mac->device_notifier); } diff --git a/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch b/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch index 1262e9498d..26d66d6d4a 100644 --- a/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch +++ b/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch @@ -33,7 +33,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c phy_led_trigger_change_speed(phydev); } -@@ -591,7 +591,7 @@ int phy_start_cable_test(struct phy_devi +@@ -595,7 +595,7 @@ int phy_start_cable_test(struct phy_devi goto out; /* Mark the carrier down until the test is complete */ @@ -42,7 +42,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c netif_testing_on(dev); err = phydev->drv->cable_test_start(phydev); -@@ -662,7 +662,7 @@ int phy_start_cable_test_tdr(struct phy_ +@@ -666,7 +666,7 @@ int phy_start_cable_test_tdr(struct phy_ goto out; /* Mark the carrier down until the test is complete */ @@ -51,7 +51,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c netif_testing_on(dev); err = phydev->drv->cable_test_tdr_start(phydev, config); -@@ -734,7 +734,7 @@ static int phy_check_link_status(struct +@@ -738,7 +738,7 @@ static int phy_check_link_status(struct phy_link_up(phydev); } else if (!phydev->link && phydev->state != PHY_NOLINK) { phydev->state = PHY_NOLINK; @@ -60,7 +60,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c } return 0; -@@ -1220,7 +1220,7 @@ void phy_state_machine(struct work_struc +@@ -1224,7 +1224,7 @@ void phy_state_machine(struct work_struc case PHY_HALTED: if (phydev->link) { phydev->link = 0; @@ -71,7 +71,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c break; --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1035,14 +1035,16 @@ struct phy_device *phy_find_first(struct +@@ -1039,14 +1039,16 @@ struct phy_device *phy_find_first(struct } EXPORT_SYMBOL(phy_find_first); @@ -95,9 +95,9 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c phydev->mii_ts->link_state(phydev->mii_ts, phydev); --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c -@@ -1373,7 +1373,8 @@ void phylink_destroy(struct phylink *pl) +@@ -1602,7 +1602,8 @@ bool phylink_expects_phy(struct phylink } - EXPORT_SYMBOL_GPL(phylink_destroy); + EXPORT_SYMBOL_GPL(phylink_expects_phy); -static void phylink_phy_change(struct phy_device *phydev, bool up) +static void phylink_phy_change(struct phy_device *phydev, bool up, @@ -107,9 +107,9 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c bool tx_pause, rx_pause; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -716,7 +716,7 @@ struct phy_device { - u8 mdix; - u8 mdix_ctrl; +@@ -736,7 +736,7 @@ struct phy_device { + + int pma_extable; - void (*phy_link_change)(struct phy_device *phydev, bool up); + void (*phy_link_change)(struct phy_device *, bool up, bool do_carrier); diff --git a/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch index fc7873a01b..9f1c3e05f1 100644 --- a/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch +++ b/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch @@ -11,7 +11,7 @@ Signed-off-by: John Crispin --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c -@@ -734,7 +734,10 @@ static int phy_check_link_status(struct +@@ -738,7 +738,10 @@ static int phy_check_link_status(struct phy_link_up(phydev); } else if (!phydev->link && phydev->state != PHY_NOLINK) { phydev->state = PHY_NOLINK; @@ -23,7 +23,7 @@ Signed-off-by: John Crispin } return 0; -@@ -1220,7 +1223,10 @@ void phy_state_machine(struct work_struc +@@ -1224,7 +1227,10 @@ void phy_state_machine(struct work_struc case PHY_HALTED: if (phydev->link) { phydev->link = 0; @@ -37,7 +37,7 @@ Signed-off-by: John Crispin break; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -630,6 +630,7 @@ struct phy_device { +@@ -644,6 +644,7 @@ struct phy_device { unsigned downshifted_rate:1; unsigned is_on_sfp_module:1; unsigned mac_managed_pm:1; diff --git a/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch b/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch index e77f398c5d..a793011223 100644 --- a/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch +++ b/target/linux/ramips/patches-6.1/800-dmaengine-mediatek-add-HSDMA-support-for-mt7621.patch @@ -16,8 +16,6 @@ Signed-off-by: Nick Hainke drivers/dma/mediatek/Makefile | 1 + 2 files changed, 7 insertions(+) -diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig -index 7a46a5455957..1a24d73ce87f 100644 --- a/drivers/dma/mediatek/Kconfig +++ b/drivers/dma/mediatek/Kconfig @@ -36,3 +36,9 @@ config MTK_UART_APDMA @@ -30,8 +28,6 @@ index 7a46a5455957..1a24d73ce87f 100644 + depends on RALINK && SOC_MT7621 + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS -diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile -index 5ba39a5edc13..784af039b7c0 100644 --- a/drivers/dma/mediatek/Makefile +++ b/drivers/dma/mediatek/Makefile @@ -2,3 +2,4 @@ @@ -39,6 +35,3 @@ index 5ba39a5edc13..784af039b7c0 100644 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o +obj-$(CONFIG_MTK_HSDMA) += hsdma-mt7621.o --- -2.40.1 - diff --git a/target/linux/ramips/patches-6.1/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-6.1/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch index 02fafbdc9b..ff60b33cd4 100644 --- a/target/linux/ramips/patches-6.1/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch +++ b/target/linux/ramips/patches-6.1/802-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch @@ -47,7 +47,7 @@ Cc: linux-gpio@vger.kernel.org +#endif /* __ASM_MACH_RALINK_GPIO_H */ --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig -@@ -569,6 +569,12 @@ config GPIO_SNPS_CREG +@@ -585,6 +585,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. @@ -62,7 +62,7 @@ Cc: linux-gpio@vger.kernel.org depends on PLAT_SPEAR --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile -@@ -121,6 +121,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisos +@@ -122,6 +122,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 diff --git a/target/linux/ramips/patches-6.1/805-pinctrl-AW9523.patch b/target/linux/ramips/patches-6.1/805-pinctrl-AW9523.patch index 34220acdd1..f9fa791fe1 100644 --- a/target/linux/ramips/patches-6.1/805-pinctrl-AW9523.patch +++ b/target/linux/ramips/patches-6.1/805-pinctrl-AW9523.patch @@ -35,9 +35,9 @@ Signed-off-by: AngeloGioacchino Del Regno --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c -@@ -3158,6 +3158,18 @@ static const struct usb_device_id uvc_id +@@ -2981,6 +2981,18 @@ static const struct usb_device_id uvc_id .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) }, @@ -34,7 +34,7 @@ Signed-off-by: John Crispin { 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 -@@ -224,6 +224,7 @@ static void uvc_status_complete(struct u +@@ -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; @@ -42,14 +42,14 @@ Signed-off-by: John Crispin break; } -@@ -272,6 +273,7 @@ int uvc_status_init(struct uvc_device *d +@@ -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. + /* + * For high-speed interrupt endpoints, the bInterval value is used as --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -19,6 +19,11 @@ @@ -64,7 +64,7 @@ Signed-off-by: John Crispin #include -@@ -1214,9 +1219,149 @@ static void uvc_video_decode_data(struct +@@ -1231,9 +1236,149 @@ static void uvc_video_decode_data(struct uvc_urb->async_operations++; } @@ -214,7 +214,7 @@ Signed-off-by: John Crispin /* 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"); -@@ -1801,6 +1946,8 @@ static int uvc_init_video_isoc(struct uv +@@ -1815,6 +1960,8 @@ static int uvc_init_video_isoc(struct uv if (npackets == 0) return -ENOMEM; @@ -225,7 +225,7 @@ Signed-off-by: John Crispin for_each_uvc_urb(uvc_urb, stream) { --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h -@@ -210,6 +210,8 @@ +@@ -75,6 +75,8 @@ #define UVC_QUIRK_FORCE_Y8 0x00000800 #define UVC_QUIRK_FORCE_BPP 0x00001000 #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 @@ -234,7 +234,7 @@ Signed-off-by: John Crispin /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 -@@ -701,6 +703,7 @@ struct uvc_device { +@@ -562,6 +564,7 @@ struct uvc_device { u8 *status; struct input_dev *input; char input_phys[64]; diff --git a/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch index 7815ecf5a0..9aaf86ffc7 100644 --- a/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch +++ b/target/linux/ramips/patches-6.1/821-SPI-ralink-add-Ralink-SoC-spi-driver.patch @@ -16,7 +16,7 @@ Acked-by: John Crispin --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -718,6 +718,12 @@ config SPI_QCOM_GENI +@@ -823,6 +823,12 @@ config SPI_QCOM_GENI This driver can also be built as a module. If so, the module will be called spi-geni-qcom. @@ -31,7 +31,7 @@ Acked-by: John Crispin depends on ARCH_S3C24XX --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile -@@ -100,6 +100,7 @@ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o +@@ -110,6 +110,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 diff --git a/target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch index da6f8e5a1e..09f62ad51b 100644 --- a/target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch +++ b/target/linux/ramips/patches-6.1/825-i2c-MIPS-adds-ralink-I2C-driver.patch @@ -45,7 +45,7 @@ Signed-off-by: John Crispin +}; --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig -@@ -949,6 +949,11 @@ config I2C_RK3X +@@ -998,6 +998,11 @@ config I2C_RK3X This driver can also be built as a module. If so, the module will be called i2c-rk3x. @@ -54,12 +54,12 @@ Signed-off-by: John Crispin + depends on RALINK && !SOC_MT7621 + select OF_I2C + - config HAVE_S3C2410_I2C - bool - help + config I2C_RZV2M + tristate "Renesas RZ/V2M adapter" + depends on ARCH_RENESAS || COMPILE_TEST --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile -@@ -89,6 +89,7 @@ obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pc +@@ -97,6 +97,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 diff --git a/target/linux/ramips/patches-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch index 9a0dbd7bb8..37a10589a3 100644 --- a/target/linux/ramips/patches-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch +++ b/target/linux/ramips/patches-6.1/830-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch @@ -25,12 +25,15 @@ Signed-off-by: John Crispin --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig -@@ -1095,3 +1095,5 @@ config MMC_OWL - +@@ -1102,6 +1102,8 @@ config MMC_OWL config MMC_SDHCI_EXTERNAL_DMA bool -+ + +source "drivers/mmc/host/mtk-mmc/Kconfig" ++ + config MMC_LITEX + tristate "LiteX MMC Host Controller support" + depends on ((PPC_MICROWATT || LITEX) && OF && HAVE_CLK) || COMPILE_TEST --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -3,6 +3,7 @@ diff --git a/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch index ef202ca474..57f0ec2c50 100644 --- a/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch +++ b/target/linux/ramips/patches-6.1/835-asoc-add-mt7620-support.patch @@ -20,7 +20,7 @@ Signed-off-by: John Crispin --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig -@@ -78,6 +78,7 @@ source "sound/soc/mxs/Kconfig" +@@ -86,6 +86,7 @@ source "sound/soc/mxs/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/qcom/Kconfig" source "sound/soc/rockchip/Kconfig" @@ -30,7 +30,7 @@ Signed-off-by: John Crispin source "sound/soc/sof/Kconfig" --- a/sound/soc/Makefile +++ b/sound/soc/Makefile -@@ -48,6 +48,7 @@ obj-$(CONFIG_SND_SOC) += kirkwood/ +@@ -54,6 +54,7 @@ obj-$(CONFIG_SND_SOC) += kirkwood/ obj-$(CONFIG_SND_SOC) += pxa/ obj-$(CONFIG_SND_SOC) += qcom/ obj-$(CONFIG_SND_SOC) += rockchip/ diff --git a/target/linux/ramips/patches-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch b/target/linux/ramips/patches-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch index 7148bb16f3..42a15a935c 100644 --- a/target/linux/ramips/patches-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch +++ b/target/linux/ramips/patches-6.1/840-serial-add-ugly-custom-baud-rate-hack.patch @@ -10,7 +10,7 @@ Signed-off-by: John Crispin --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c -@@ -393,6 +393,9 @@ uart_get_baud_rate(struct uart_port *por +@@ -445,6 +445,9 @@ uart_get_baud_rate(struct uart_port *por break; } diff --git a/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch b/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch index 15c7cf39a2..ab164f5ab8 100644 --- a/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch +++ b/target/linux/ramips/patches-6.1/845-pwm-add-mediatek-support.patch @@ -13,7 +13,7 @@ Signed-off-by: John Crispin --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig -@@ -383,6 +383,15 @@ config PWM_MEDIATEK +@@ -393,6 +393,15 @@ config PWM_MEDIATEK To compile this driver as a module, choose M here: the module will be called pwm-mediatek. @@ -31,7 +31,7 @@ Signed-off-by: John Crispin 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 +@@ -34,6 +34,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 diff --git a/target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch b/target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch index 5fb3664ae5..01ce44d700 100644 --- a/target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch +++ b/target/linux/ramips/patches-6.1/850-awake-rt305x-dwc2-controller.patch @@ -1,6 +1,6 @@ --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c -@@ -508,6 +508,12 @@ static int dwc2_driver_probe(struct plat +@@ -462,6 +462,12 @@ static int dwc2_driver_probe(struct plat if (retval) return retval; diff --git a/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch b/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch index 4008d5fe7c..275b81e715 100644 --- a/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch +++ b/target/linux/ramips/patches-6.1/860-ramips-add-eip93-driver.patch @@ -3260,16 +3260,16 @@ +#endif --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig -@@ -918,4 +918,6 @@ config CRYPTO_DEV_SA2UL - +@@ -824,4 +824,6 @@ config CRYPTO_DEV_SA2UL source "drivers/crypto/keembay/Kconfig" + source "drivers/crypto/aspeed/Kconfig" +source "drivers/crypto/mtk-eip93/Kconfig" + endif # CRYPTO_HW --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile -@@ -51,3 +51,4 @@ obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += x +@@ -53,3 +53,4 @@ obj-y += xilinx/ obj-y += hisilicon/ obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ obj-y += keembay/ diff --git a/target/linux/ramips/rt288x/config-6.1 b/target/linux/ramips/rt288x/config-6.1 index 9f502c220f..d8b89934b9 100644 --- a/target/linux/ramips/rt288x/config-6.1 +++ b/target/linux/ramips/rt288x/config-6.1 @@ -5,6 +5,8 @@ CONFIG_ARCH_MMAP_RND_BITS_MAX=15 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_BLK_MQ_PCI=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CLK_MTMIPS=y CONFIG_CLONE_BACKWARDS=y @@ -12,6 +14,7 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_BOOL=y # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CPU_GENERIC_DUMP_TLB=y CONFIG_CPU_HAS_DIEI=y @@ -30,26 +33,30 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG2=y CONFIG_CSRC_R4K=y +CONFIG_DEBUG_INFO=y CONFIG_DMA_NONCOHERENT=y # CONFIG_DTB_RT2880_EVAL is not set CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_FIXED_PHY=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=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 @@ -63,7 +70,6 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_RALINK=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -93,7 +99,6 @@ CONFIG_MIPS_CLOCK_VSYSCALL=y # CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y CONFIG_MIPS_L1_CACHE_SHIFT=4 CONFIG_MIPS_L1_CACHE_SHIFT_4=y CONFIG_MIPS_LD_CAN_LINK_VDSO=y @@ -120,6 +125,7 @@ CONFIG_NET_VENDOR_RALINK=y CONFIG_NLS=m CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -128,22 +134,29 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y # CONFIG_PHY_MT7621_PCI is not set # CONFIG_PHY_RALINK_USB is not set CONFIG_PINCTRL=y # CONFIG_PINCTRL_AW9523 is not set CONFIG_PINCTRL_RALINK=y -CONFIG_PINCTRL_RT288X=y +CONFIG_PINCTRL_RT2880=y # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_RALINK=y CONFIG_RALINK_WDT=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y @@ -185,3 +198,4 @@ CONFIG_USB_OHCI_HCD_PLATFORM=m CONFIG_USB_SUPPORT=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y +CONFIG_ZBOOT_LOAD_ADDRESS=0x0 diff --git a/target/linux/ramips/rt305x/config-6.1 b/target/linux/ramips/rt305x/config-6.1 index 5af80adca6..8b1b17033a 100644 --- a/target/linux/ramips/rt305x/config-6.1 +++ b/target/linux/ramips/rt305x/config-6.1 @@ -4,6 +4,8 @@ CONFIG_ARCH_KEEP_MEMBLOCK=y CONFIG_ARCH_MMAP_RND_BITS_MAX=15 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CEVT_SYSTICK_QUIRK=y CONFIG_CLKEVT_RT3352=y @@ -14,6 +16,7 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_BOOL=y # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CPU_GENERIC_DUMP_TLB=y CONFIG_CPU_HAS_DIEI=y @@ -32,26 +35,30 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG2=y CONFIG_CSRC_R4K=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y # CONFIG_DTB_RT305X_EVAL is not set CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_FIXED_PHY=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=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 @@ -68,7 +75,6 @@ CONFIG_GPIO_CDEV=y CONFIG_GPIO_RALINK=y CONFIG_GPIO_WATCHDOG=y # CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -96,7 +102,6 @@ CONFIG_MIPS_CLOCK_VSYSCALL=y # CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_MIPS_LD_CAN_LINK_VDSO=y # CONFIG_MIPS_NO_APPENDED_DTB is not set @@ -120,6 +125,7 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_VENDOR_RALINK=y CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -128,10 +134,15 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y # CONFIG_PHY_MT7621_PCI is not set CONFIG_PHY_RALINK_USB=y CONFIG_PINCTRL=y @@ -139,10 +150,12 @@ CONFIG_PINCTRL=y CONFIG_PINCTRL_RALINK=y CONFIG_PINCTRL_RT305X=y # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_RALINK=y # CONFIG_RALINK_ILL_ACC is not set CONFIG_RALINK_WDT=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y @@ -180,3 +193,4 @@ CONFIG_TINY_SRCU=y CONFIG_USB_SUPPORT=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y +CONFIG_ZBOOT_LOAD_ADDRESS=0x0 diff --git a/target/linux/ramips/rt3883/config-6.1 b/target/linux/ramips/rt3883/config-6.1 index 2977a3b531..2aaebdc702 100644 --- a/target/linux/ramips/rt3883/config-6.1 +++ b/target/linux/ramips/rt3883/config-6.1 @@ -6,6 +6,8 @@ CONFIG_ARCH_MMAP_RND_BITS_MAX=15 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_BLK_MQ_PCI=y +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CEVT_R4K=y CONFIG_CLK_MTMIPS=y CONFIG_CLONE_BACKWARDS=y @@ -13,6 +15,7 @@ CONFIG_CMDLINE="rootfstype=squashfs,jffs2" CONFIG_CMDLINE_BOOL=y # CONFIG_CMDLINE_OVERRIDE is not set CONFIG_COMMON_CLK=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 CONFIG_COMPAT_32BIT_TIME=y CONFIG_CPU_GENERIC_DUMP_TLB=y CONFIG_CPU_HAS_DIEI=y @@ -31,8 +34,11 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CPU_SUPPORTS_MSA=y CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_RNG2=y CONFIG_CSRC_R4K=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_PINCTRL=y CONFIG_DMA_NONCOHERENT=y # CONFIG_DTB_RT3883_EVAL is not set @@ -40,18 +46,19 @@ CONFIG_DTB_RT_NONE=y CONFIG_DTC=y CONFIG_EARLY_PRINTK=y CONFIG_ETHERNET_PACKET_MANGLE=y +CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_FIXED_PHY=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_FW_LOADER_SYSFS=y +CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=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 @@ -66,7 +73,6 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_RALINK=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_HARDWARE_WATCHPOINTS=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y @@ -94,7 +100,6 @@ CONFIG_MIPS_CLOCK_VSYSCALL=y # CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set # CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y CONFIG_MIPS_L1_CACHE_SHIFT=5 CONFIG_MIPS_LD_CAN_LINK_VDSO=y # CONFIG_MIPS_NO_APPENDED_DTB is not set @@ -118,6 +123,7 @@ CONFIG_NET_SELFTESTS=y CONFIG_NET_VENDOR_RALINK=y CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_OF=y CONFIG_OF_ADDRESS=y CONFIG_OF_EARLY_FLATTREE=y @@ -126,12 +132,17 @@ CONFIG_OF_GPIO=y CONFIG_OF_IRQ=y CONFIG_OF_KOBJ=y CONFIG_OF_MDIO=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PERF_USE_VMALLOC=y CONFIG_PGTABLE_LEVELS=2 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y # CONFIG_PHY_MT7621_PCI is not set CONFIG_PHY_RALINK_USB=y CONFIG_PINCTRL=y @@ -139,9 +150,11 @@ CONFIG_PINCTRL=y CONFIG_PINCTRL_RALINK=y CONFIG_PINCTRL_RT3883=y # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_RALINK=y CONFIG_RALINK_WDT=y +CONFIG_RANDSTRUCT_NONE=y CONFIG_RATIONAL=y CONFIG_REGMAP=y CONFIG_REGMAP_MMIO=y @@ -180,3 +193,4 @@ CONFIG_TINY_SRCU=y CONFIG_USB_SUPPORT=y CONFIG_USE_OF=y CONFIG_WATCHDOG_CORE=y +CONFIG_ZBOOT_LOAD_ADDRESS=0x0 From 00586674e4aa2e1a7124cca08d0b29cfbfd10c78 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sun, 11 Feb 2024 11:50:32 +0800 Subject: [PATCH 34/50] ramips: hsdma-mtk: fix build on 5.15 kernel In the 5.15 kernel, we use the staging driver version instead of the downstream file. Fixes: 88d982e3bd87 ("ramips: 6.1: mt7621-dma: add hsdma driver to files") Signed-off-by: Shiji Yang --- target/linux/ramips/modules.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk index 429bb2cd26..4a8739fe5c 100644 --- a/target/linux/ramips/modules.mk +++ b/target/linux/ramips/modules.mk @@ -101,7 +101,8 @@ define KernelPackage/hsdma-mtk CONFIG_MTK_HSDMA FILES:= \ $(LINUX_DIR)/drivers/dma/virt-dma.ko \ - $(LINUX_DIR)/drivers/dma/mediatek/hsdma-mt7621.ko + $(LINUX_DIR)/drivers/staging/mt7621-dma/hsdma-mt7621.ko@lt5.17 \ + $(LINUX_DIR)/drivers/dma/mediatek/hsdma-mt7621.ko@ge5.17 AUTOLOAD:=$(call AutoLoad,53,hsdma-mt7621) endef From 3b74ae780cd3bb2a6f83251a2aa0ca1575c4b3d3 Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sat, 10 Feb 2024 13:47:40 +0000 Subject: [PATCH 35/50] uboot-envtools: backport some usefull patches from v2024.04-rc1 Highlights: - Silence small page read warning. - Autodetect NAND erase size and env sectors. Signed-off-by: Shiji Yang --- package/boot/uboot-envtools/Makefile | 2 +- ...ing-read-until-whole-flash-block-is-.patch | 75 +++++++++++++++++++ ...tect-NAND-erase-size-and-env-sectors.patch | 49 ++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch create mode 100644 package/boot/uboot-envtools/patches/012-fw_env-autodetect-NAND-erase-size-and-env-sectors.patch diff --git a/package/boot/uboot-envtools/Makefile b/package/boot/uboot-envtools/Makefile index 4ea93f9c79..00aa424162 100644 --- a/package/boot/uboot-envtools/Makefile +++ b/package/boot/uboot-envtools/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uboot-envtools PKG_DISTNAME:=u-boot PKG_VERSION:=2024.01 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:= \ diff --git a/package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch b/package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch new file mode 100644 index 0000000000..af1c32fe91 --- /dev/null +++ b/package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch @@ -0,0 +1,75 @@ +From 9e3003f79d168eac7ee65cd457e3904e2fb4eea8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 13 Dec 2023 13:13:54 +0100 +Subject: [PATCH] fw_env: keep calling read() until whole flash block is read +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's totally valid for read() to provide less bytes than requested +maximum. It may happen if there is no more data available yet or source +pushes data in small chunks. + +This actually happens when trying to read env data from NVMEM device. +Kernel may provide NVMEM content in page size parts (like 4096 B). + +This fixes warnings like: +Warning on /sys/bus/nvmem/devices/u-boot-env0/nvmem: Attempted to read 16384 bytes but got 4096 +Warning on /sys/bus/nvmem/devices/u-boot-env0/nvmem: Attempted to read 12288 bytes but got 4096 +Warning on /sys/bus/nvmem/devices/u-boot-env0/nvmem: Attempted to read 8192 bytes but got 4096 + +Since the main loop in flash_read_buf() is used to read blocks this +patch adds a new nested one. + +Signed-off-by: Rafał Miłecki +--- + tools/env/fw_env.c | 34 +++++++++++++++------------------- + 1 file changed, 15 insertions(+), 19 deletions(-) + +--- a/tools/env/fw_env.c ++++ b/tools/env/fw_env.c +@@ -948,29 +948,25 @@ static int flash_read_buf(int dev, int f + */ + lseek(fd, blockstart + block_seek, SEEK_SET); + +- rc = read(fd, buf + processed, readlen); +- if (rc == -1) { +- fprintf(stderr, "Read error on %s: %s\n", +- DEVNAME(dev), strerror(errno)); +- return -1; +- } ++ while (readlen) { ++ rc = read(fd, buf + processed, readlen); ++ if (rc == -1) { ++ fprintf(stderr, "Read error on %s: %s\n", ++ DEVNAME(dev), strerror(errno)); ++ return -1; ++ } + #ifdef DEBUG +- fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n", +- rc, (unsigned long long)blockstart + block_seek, +- DEVNAME(dev)); ++ fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n", ++ rc, (unsigned long long)blockstart + block_seek, ++ DEVNAME(dev)); + #endif +- processed += rc; +- if (rc != readlen) { +- fprintf(stderr, +- "Warning on %s: Attempted to read %zd bytes but got %d\n", +- DEVNAME(dev), readlen, rc); ++ processed += rc; + readlen -= rc; +- block_seek += rc; +- } else { +- blockstart += blocklen; +- readlen = min(blocklen, count - processed); +- block_seek = 0; + } ++ ++ blockstart += blocklen; ++ readlen = min(blocklen, count - processed); ++ block_seek = 0; + } + + return processed; diff --git a/package/boot/uboot-envtools/patches/012-fw_env-autodetect-NAND-erase-size-and-env-sectors.patch b/package/boot/uboot-envtools/patches/012-fw_env-autodetect-NAND-erase-size-and-env-sectors.patch new file mode 100644 index 0000000000..78f555fb1f --- /dev/null +++ b/package/boot/uboot-envtools/patches/012-fw_env-autodetect-NAND-erase-size-and-env-sectors.patch @@ -0,0 +1,49 @@ +From d73a6641868029b5cae53ed00c5766921c9d8b1f Mon Sep 17 00:00:00 2001 +From: Anthony Loiseau +Date: Thu, 21 Dec 2023 23:44:38 +0100 +Subject: [PATCH] fw_env: autodetect NAND erase size and env sectors + +As already done for NOR chips, if device ESIZE and ENVSECTORS static +configurations are both zero, then autodetect them at runtime. + +Cc: Joe Hershberger +cc: Stefan Agner +cc: Rasmus Villemoes +Signed-off-by: Anthony Loiseau +--- + tools/env/README | 3 +++ + tools/env/fw_env.c | 11 +++++++++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +--- a/tools/env/README ++++ b/tools/env/README +@@ -58,6 +58,9 @@ DEVICEx_ENVSECTORS defines the number of + this environment instance. On NAND this is used to limit the range + within which bad blocks are skipped, on NOR it is not used. + ++If DEVICEx_ESIZE and DEVICEx_ENVSECTORS are both zero, then a runtime ++detection is attempted for NOR and NAND mtd types. ++ + To prevent losing changes to the environment and to prevent confusing the MTD + drivers, a lock file at /run/fw_printenv.lock is used to serialize access + to the environment. +--- a/tools/env/fw_env.c ++++ b/tools/env/fw_env.c +@@ -1655,8 +1655,15 @@ static int check_device_config(int dev) + } + DEVTYPE(dev) = mtdinfo.type; + if (DEVESIZE(dev) == 0 && ENVSECTORS(dev) == 0 && +- mtdinfo.type == MTD_NORFLASH) +- DEVESIZE(dev) = mtdinfo.erasesize; ++ mtdinfo.erasesize > 0) { ++ if (mtdinfo.type == MTD_NORFLASH) ++ DEVESIZE(dev) = mtdinfo.erasesize; ++ else if (mtdinfo.type == MTD_NANDFLASH) { ++ DEVESIZE(dev) = mtdinfo.erasesize; ++ ENVSECTORS(dev) = ++ mtdinfo.size / mtdinfo.erasesize; ++ } ++ } + if (DEVESIZE(dev) == 0) + /* Assume the erase size is the same as the env-size */ + DEVESIZE(dev) = ENVSIZE(dev); From 88d1322fcfb1ce20613d520aa70e3a1ef63e042d Mon Sep 17 00:00:00 2001 From: Shiji Yang Date: Sat, 10 Feb 2024 20:35:46 +0800 Subject: [PATCH 36/50] ramips: mtk_eth_soc: fix NULL pointer dereference for syncp u64_stats_init() has been unable to handle NULL pointer since 6.1 kernel. This patch fixes kernel oops on mt76x8 and rt305x sub-target. Signed-off-by: Shiji Yang --- .../ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c index 35a3113804..dda9abee49 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c @@ -1601,6 +1601,7 @@ static int fe_probe(struct platform_device *pdev) goto err_free_dev; } spin_lock_init(&priv->hw_stats->stats_lock); + u64_stats_init(&priv->hw_stats->syncp); } sysclk = devm_clk_get(&pdev->dev, NULL); @@ -1628,7 +1629,6 @@ static int fe_probe(struct platform_device *pdev) priv->tx_ring.tx_ring_size = NUM_DMA_DESC; priv->rx_ring.rx_ring_size = NUM_DMA_DESC; INIT_WORK(&priv->pending_work, fe_pending_work); - u64_stats_init(&priv->hw_stats->syncp); napi_weight = 16; if (priv->flags & FE_FLAG_NAPI_WEIGHT) { From b589434a0b38435bd1ce3a9be3af75ed188e88e0 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sun, 11 Feb 2024 14:44:08 +0100 Subject: [PATCH 37/50] mediatek: fix failsafe ethernet for NWA50AX Pro The NWA50AX Pro only has a eth0 interface for its only ethernet port. Use this port for preinit. Fixes non-working network in failsafe mode. Signed-off-by: David Bauer --- .../linux/mediatek/base-files/lib/preinit/05_set_preinit_iface | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface index 9daf1ef26b..da9c4e7f40 100644 --- a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface +++ b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface @@ -9,7 +9,8 @@ set_preinit_iface() { ip link set eth1 up ifname=eth1 ;; - ubnt,unifi-6-lr) + ubnt,unifi-6-lr|\ + zyxel,nwa50ax-pro) ip link set eth0 up ifname=eth0 ;; From 0222e48d7374127c51c8113a29ec3a98274d519b Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sun, 11 Feb 2024 15:58:21 +0100 Subject: [PATCH 38/50] qualcommax: fix wrong PHY node definition for Buffalo WXR-5950AX12 Commit d737ae99cb36 ("qualcommax: Fix Buffalo WXR-5950AX12 Ethernet DTS") reverted the switch bmp to the original OEM definition and added the malibu_first_phy_addr property. Problem is that OEM bmp definition is wrong and actually doesn't make sense, probably caused by copy-paste of the QCOM reference DTS without actually setting real values. What actually fixed the regression was adding the malibu_first_phy_addr as without it the MALIBU PHY was actually not correctly configured and the Aquantia PHY were actually configured as MALIBU PHY. Fix all these wrong PHY definition. The BPM is reverted and the following fixes are applied: - Drop ESS_PORT1 as it's not actually attached in HW. - Move ESS_PORT5 AGAIN from lan to wan. This refer to the first Aquantia PHY that is labelled "wan" - Move ESS_PORT6 AGAIN from wan to lan. This refer to the second Aquantia PHY that is labelled "lan1". Also PHY tag in MDIO node are renumbered to start from 0 following the tagging standard used also in other dts and the not attached one (reg 0x18 and reg 0x1c) are correctly dropped. Definition for port@1 in phyinfo is dropped as it doesn't exist. dp nodes are updated to reference the new PHY tag numbering. Fixes: d737ae99cb36 ("qualcommax: Fix Buffalo WXR-5950AX12 Ethernet DTS") Signed-off-by: Christian Marangi --- .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts index aefa9e3b9b..cc6eafe532 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts @@ -230,48 +230,33 @@ reg = <0x8>; }; - qca8075_1: ethernet-phy@18 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x18>; - }; - - qca8075_2: ethernet-phy@19 { + qca8075_1: ethernet-phy@19 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0x19>; }; - qca8075_3: ethernet-phy@1a { + qca8075_2: ethernet-phy@1a { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0x1a>; }; - qca8075_4: ethernet-phy@1b { + qca8075_3: ethernet-phy@1b { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0x1b>; }; - - qca8075_5: ethernet-phy@1c { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x1c>; - }; }; &switch { status = "okay"; - switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT5)>; - switch_wan_bmp = ; + switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT6)>; + switch_wan_bmp = ; malibu_first_phy_addr = <0x18>; switch_mac_mode = ; switch_mac_mode1 = ; switch_mac_mode2 = ; qcom,port_phyinfo { - port@1 { - port_id = <1>; - phy_address = <0x18>; - }; - port@2 { port_id = <2>; phy_address = <0x19>; @@ -307,7 +292,7 @@ &dp2 { status = "okay"; - phy-handle = <&qca8075_2>; + phy-handle = <&qca8075_1>; label = "lan4"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; nvmem-cell-names = "mac-address"; @@ -315,7 +300,7 @@ &dp3 { status = "okay"; - phy-handle = <&qca8075_3>; + phy-handle = <&qca8075_2>; label = "lan3"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; nvmem-cell-names = "mac-address"; @@ -323,7 +308,7 @@ &dp4 { status = "okay"; - phy-handle = <&qca8075_4>; + phy-handle = <&qca8075_3>; label = "lan2"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; nvmem-cell-names = "mac-address"; From cb42c2e307aca97fef42e8f76ca89dda4bd3f047 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sun, 11 Feb 2024 16:28:16 +0100 Subject: [PATCH 39/50] generic: 6.1: backport Aquantia PHY endianess patch Backport Aquantia PHY endianess patch. While the current implementation works ok for Little-Endian targets, backport patch to prevent any kind of malfunction if in the future we will have Big-Endian target with Aquantia PHYs. Signed-off-by: Christian Marangi --- ...-drop-wrong-endianness-conversion-fo.patch | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch diff --git a/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch b/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch new file mode 100644 index 0000000000..d32a7edf93 --- /dev/null +++ b/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch @@ -0,0 +1,92 @@ +From 7edce370d87a23e8ed46af5b76a9fef1e341b67b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 28 Nov 2023 14:59:28 +0100 +Subject: [PATCH] net: phy: aquantia: drop wrong endianness conversion for addr + and CRC + +On further testing on BE target with kernel test robot, it was notice +that the endianness conversion for addr and CRC in fw_load_memory was +wrong. + +Drop the cpu_to_le32 conversion for addr load as it's not needed. + +Use get_unaligned_le32 instead of get_unaligned for FW data word load to +correctly convert data in the correct order to follow system endian. + +Also drop the cpu_to_be32 for CRC calculation as it's wrong and would +cause different CRC on BE system. +The loaded word is swapped internally and MAILBOX calculates the CRC on +the swapped word. To correctly calculate the CRC to be later matched +with the one from MAILBOX, use an u8 struct and swap the word there to +keep the same order on both LE and BE for crc_ccitt_false function. +Also add additional comments on how the CRC verification for the loaded +section works. + +CRC is calculated as we load the section and verified with the MAILBOX +only after the entire section is loaded to skip additional slowdown by +loop the section data again. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202311210414.sEJZjlcD-lkp@intel.com/ +Fixes: e93984ebc1c8 ("net: phy: aquantia: add firmware load support") +Tested-by: Robert Marko # ipq8072 LE device +Signed-off-by: Christian Marangi +Link: https://lore.kernel.org/r/20231128135928.9841-1-ansuelsmth@gmail.com +Signed-off-by: Jakub Kicinski +--- + drivers/net/phy/aquantia/aquantia_firmware.c | 24 ++++++++++++-------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/drivers/net/phy/aquantia/aquantia_firmware.c ++++ b/drivers/net/phy/aquantia/aquantia_firmware.c +@@ -93,9 +93,6 @@ static int aqr_fw_load_memory(struct phy + u16 crc = 0, up_crc; + size_t pos; + +- /* PHY expect addr in LE */ +- addr = (__force u32)cpu_to_le32(addr); +- + phy_write_mmd(phydev, MDIO_MMD_VEND1, + VEND1_GLOBAL_MAILBOX_INTERFACE1, + VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET); +@@ -110,10 +107,11 @@ static int aqr_fw_load_memory(struct phy + * If a firmware that is not word aligned is found, please report upstream. + */ + for (pos = 0; pos < len; pos += sizeof(u32)) { ++ u8 crc_data[4]; + u32 word; + + /* FW data is always stored in little-endian */ +- word = get_unaligned((const u32 *)(data + pos)); ++ word = get_unaligned_le32((const u32 *)(data + pos)); + + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5, + VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word)); +@@ -124,15 +122,21 @@ static int aqr_fw_load_memory(struct phy + VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE | + VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE); + +- /* calculate CRC as we load data to the mailbox. +- * We convert word to big-endian as PHY is BE and mailbox will +- * return a BE CRC. ++ /* Word is swapped internally and MAILBOX CRC is calculated ++ * using big-endian order. Mimic what the PHY does to have a ++ * matching CRC... + */ +- word = (__force u32)cpu_to_be32(word); +- crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word)); +- } ++ crc_data[0] = word >> 24; ++ crc_data[1] = word >> 16; ++ crc_data[2] = word >> 8; ++ crc_data[3] = word; + ++ /* ...calculate CRC as we load data... */ ++ crc = crc_ccitt_false(crc, crc_data, sizeof(crc_data)); ++ } ++ /* ...gets CRC from MAILBOX after we have loaded the entire section... */ + up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2); ++ /* ...and make sure it does match our calculated CRC */ + if (crc != up_crc) { + phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n", + crc, up_crc); From 2253645411d98621466e4ba5e92595aeff3b413d Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sun, 11 Feb 2024 16:37:18 +0100 Subject: [PATCH 40/50] generic: 6.1: move LEDs netdev trigger patch from pending to backport Move LEDs netdev trigger patch from pending to backport as it has been merged upstream. Signed-off-by: Christian Marangi --- ...-trigger-netdev-Fix-kernel-panic-on-interface-re.patch} | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) rename target/linux/generic/{pending-6.1/830-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch => backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch} (88%) diff --git a/target/linux/generic/pending-6.1/830-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch b/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch similarity index 88% rename from target/linux/generic/pending-6.1/830-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch rename to target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch index 8006bdb2b4..8d391678ff 100644 --- a/target/linux/generic/pending-6.1/830-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch +++ b/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch @@ -1,6 +1,6 @@ -From 9e2a0a8bd7a392b5af6bf2cfa0b07d96d1fb6719 Mon Sep 17 00:00:00 2001 +From 12ce20e02e532f101b725d71c52a36c5cc8ad1e6 Mon Sep 17 00:00:00 2001 From: Christian Marangi -Date: Sun, 4 Feb 2024 00:32:04 +0100 +Date: Sun, 4 Feb 2024 00:54:01 +0100 Subject: [PATCH] leds: trigger: netdev: Fix kernel panic on interface rename trig notify @@ -29,6 +29,9 @@ case) and correctly parse the new dev. Fixes: d5e01266e7f5 ("leds: trigger: netdev: add additional specific link speed mode") Cc: stable@vger.kernel.org Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Link: https://lore.kernel.org/r/20240203235413.1146-1-ansuelsmth@gmail.com +Signed-off-by: Lee Jones --- drivers/leds/trigger/ledtrig-netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) From 16364e410039a3806301338e3649d557a23deabd Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 10 Feb 2024 19:27:33 +0100 Subject: [PATCH 41/50] generic: 6.1: backport QCA807x PHY patches Backport QCA807x PHY patches merged upstream that introduce the new concept of PHY package. Also add in generic config the new Kconfig CONFIG_QCA807X_PHY. All affected patch automatically refreshed with make target/linux/refresh. Signed-off-by: Christian Marangi --- ...it-out-the-BCM54213PE-from-the-BCM54.patch | 6 +- ...late-phy-driver-block-for-BCM54213PE.patch | 2 +- ...ort-for-scanning-PHY-in-PHY-packages.patch | 211 ++++++ ...-add-devm-of_phy_package_join-helper.patch | 185 +++++ ...move-more-function-to-shared-library.patch | 583 +++++++++++++++ ...whether-link-has-changed-in-c37_read.patch | 100 +++ ...m-add-support-for-QCA807x-PHY-Family.patch | 668 ++++++++++++++++++ ...e-common-qca808x-LED-define-to-share.patch | 179 +++++ ...eneralize-some-qca808x-LED-functions.patch | 172 +++++ ...07x-add-support-for-configurable-LED.patch | 326 +++++++++ ...5-net-phy-Add-a-binding-for-PHY-LEDs.patch | 10 +- ...ce-Call-into-the-PHY-driver-to-set-L.patch | 8 +- ...ce-Call-into-the-PHY-driver-to-set-L.patch | 6 +- ...fix-circular-LEDS_CLASS-dependencies.patch | 2 +- ...net-phy-Fix-reading-LED-reg-property.patch | 4 +- ...emove-LEDs-to-ensure-correct-orderin.patch | 8 +- ...ce-Call-into-the-PHY-driver-to-set-L.patch | 6 +- ...-support-for-PHY-LEDs-polarity-modes.patch | 8 +- target/linux/generic/config-6.1 | 1 + ...detach-callback-to-struct-phy_driver.patch | 4 +- ...y-simplify-phy_link_change-arguments.patch | 2 +- .../721-NET-no-auto-carrier-off-support.patch | 2 +- 22 files changed, 2459 insertions(+), 34 deletions(-) create mode 100644 target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch create mode 100644 target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch diff --git a/target/linux/bcm27xx/patches-6.1/950-0286-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch b/target/linux/bcm27xx/patches-6.1/950-0286-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch index ec4cd0993e..55c881286e 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0286-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0286-phy-broadcom-split-out-the-BCM54213PE-from-the-BCM54.patch @@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell return; val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3); -@@ -905,7 +906,7 @@ static struct phy_driver broadcom_driver +@@ -906,7 +907,7 @@ static struct phy_driver broadcom_driver .link_change_notify = bcm54xx_link_change_notify, }, { .phy_id = PHY_ID_BCM54210E, @@ -35,7 +35,7 @@ Signed-off-by: Jonathan Bell .name = "Broadcom BCM54210E", /* PHY_GBIT_FEATURES */ .get_sset_count = bcm_phy_get_sset_count, -@@ -919,6 +920,13 @@ static struct phy_driver broadcom_driver +@@ -920,6 +921,13 @@ static struct phy_driver broadcom_driver .suspend = bcm54xx_suspend, .resume = bcm54xx_resume, }, { @@ -49,7 +49,7 @@ Signed-off-by: Jonathan Bell .phy_id = PHY_ID_BCM5461, .phy_id_mask = 0xfffffff0, .name = "Broadcom BCM5461", -@@ -1155,7 +1163,8 @@ module_phy_driver(broadcom_drivers); +@@ -1156,7 +1164,8 @@ module_phy_driver(broadcom_drivers); static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM5411, 0xfffffff0 }, { PHY_ID_BCM5421, 0xfffffff0 }, diff --git a/target/linux/bcm27xx/patches-6.1/950-0427-Populate-phy-driver-block-for-BCM54213PE.patch b/target/linux/bcm27xx/patches-6.1/950-0427-Populate-phy-driver-block-for-BCM54213PE.patch index 18e654071c..cdfc996abf 100644 --- a/target/linux/bcm27xx/patches-6.1/950-0427-Populate-phy-driver-block-for-BCM54213PE.patch +++ b/target/linux/bcm27xx/patches-6.1/950-0427-Populate-phy-driver-block-for-BCM54213PE.patch @@ -16,7 +16,7 @@ Signed-off-by: Jonathan Lemon --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c -@@ -932,8 +932,14 @@ static struct phy_driver broadcom_driver +@@ -933,8 +933,14 @@ static struct phy_driver broadcom_driver .phy_id_mask = 0xffffffff, .name = "Broadcom BCM54213PE", /* PHY_GBIT_FEATURES */ diff --git a/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch b/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch new file mode 100644 index 0000000000..b355031aa5 --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch @@ -0,0 +1,211 @@ +From 385ef48f468696d6d172eb367656a3466fa0408d Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:05 +0100 +Subject: [PATCH 02/10] net: phy: add support for scanning PHY in PHY packages + nodes + +Add support for scanning PHY in PHY package nodes. PHY packages nodes +are just container for actual PHY on the MDIO bus. + +Their PHY address defined in the PHY package node are absolute and +reflect the address on the MDIO bus. + +mdio_bus.c and of_mdio.c is updated to now support and parse also +PHY package subnode by checking if the node name match +"ethernet-phy-package". + +As PHY package reg is mandatory and each PHY in the PHY package must +have a reg, every invalid PHY Package node is ignored and will be +skipped by the autoscan fallback. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/mdio/of_mdio.c | 79 +++++++++++++++++++++++++++----------- + drivers/net/phy/mdio_bus.c | 44 +++++++++++++++++---- + 2 files changed, 92 insertions(+), 31 deletions(-) + +--- a/drivers/net/mdio/of_mdio.c ++++ b/drivers/net/mdio/of_mdio.c +@@ -138,6 +138,53 @@ bool of_mdiobus_child_is_phy(struct devi + } + EXPORT_SYMBOL(of_mdiobus_child_is_phy); + ++static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np, ++ bool *scanphys) ++{ ++ struct device_node *child; ++ int addr, rc = 0; ++ ++ /* Loop over the child nodes and register a phy_device for each phy */ ++ for_each_available_child_of_node(np, child) { ++ if (of_node_name_eq(child, "ethernet-phy-package")) { ++ /* Ignore invalid ethernet-phy-package node */ ++ if (!of_find_property(child, "reg", NULL)) ++ continue; ++ ++ rc = __of_mdiobus_parse_phys(mdio, child, NULL); ++ if (rc && rc != -ENODEV) ++ goto exit; ++ ++ continue; ++ } ++ ++ addr = of_mdio_parse_addr(&mdio->dev, child); ++ if (addr < 0) { ++ /* Skip scanning for invalid ethernet-phy-package node */ ++ if (scanphys) ++ *scanphys = true; ++ continue; ++ } ++ ++ if (of_mdiobus_child_is_phy(child)) ++ rc = of_mdiobus_register_phy(mdio, child, addr); ++ else ++ rc = of_mdiobus_register_device(mdio, child, addr); ++ ++ if (rc == -ENODEV) ++ dev_err(&mdio->dev, ++ "MDIO device at address %d is missing.\n", ++ addr); ++ else if (rc) ++ goto exit; ++ } ++ ++ return 0; ++exit: ++ of_node_put(child); ++ return rc; ++} ++ + /** + * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree + * @mdio: pointer to mii_bus structure +@@ -179,33 +226,18 @@ int __of_mdiobus_register(struct mii_bus + return rc; + + /* Loop over the child nodes and register a phy_device for each phy */ +- for_each_available_child_of_node(np, child) { +- addr = of_mdio_parse_addr(&mdio->dev, child); +- if (addr < 0) { +- scanphys = true; +- continue; +- } +- +- if (of_mdiobus_child_is_phy(child)) +- rc = of_mdiobus_register_phy(mdio, child, addr); +- else +- rc = of_mdiobus_register_device(mdio, child, addr); +- +- if (rc == -ENODEV) +- dev_err(&mdio->dev, +- "MDIO device at address %d is missing.\n", +- addr); +- else if (rc) +- goto unregister; +- } ++ rc = __of_mdiobus_parse_phys(mdio, np, &scanphys); ++ if (rc) ++ goto unregister; + + if (!scanphys) + return 0; + + /* auto scan for PHYs with empty reg property */ + for_each_available_child_of_node(np, child) { +- /* Skip PHYs with reg property set */ +- if (of_find_property(child, "reg", NULL)) ++ /* Skip PHYs with reg property set or ethernet-phy-package node */ ++ if (of_find_property(child, "reg", NULL) || ++ of_node_name_eq(child, "ethernet-phy-package")) + continue; + + for (addr = 0; addr < PHY_MAX_ADDR; addr++) { +@@ -226,15 +258,16 @@ int __of_mdiobus_register(struct mii_bus + if (!rc) + break; + if (rc != -ENODEV) +- goto unregister; ++ goto put_unregister; + } + } + } + + return 0; + +-unregister: ++put_unregister: + of_node_put(child); ++unregister: + mdiobus_unregister(mdio); + return rc; + } +--- a/drivers/net/phy/mdio_bus.c ++++ b/drivers/net/phy/mdio_bus.c +@@ -448,19 +448,34 @@ EXPORT_SYMBOL(of_mdio_find_bus); + * found, set the of_node pointer for the mdio device. This allows + * auto-probed phy devices to be supplied with information passed in + * via DT. ++ * If a PHY package is found, PHY is searched also there. + */ +-static void of_mdiobus_link_mdiodev(struct mii_bus *bus, +- struct mdio_device *mdiodev) ++static int of_mdiobus_find_phy(struct device *dev, struct mdio_device *mdiodev, ++ struct device_node *np) + { +- struct device *dev = &mdiodev->dev; + struct device_node *child; + +- if (dev->of_node || !bus->dev.of_node) +- return; +- +- for_each_available_child_of_node(bus->dev.of_node, child) { ++ for_each_available_child_of_node(np, child) { + int addr; + ++ if (of_node_name_eq(child, "ethernet-phy-package")) { ++ /* Validate PHY package reg presence */ ++ if (!of_find_property(child, "reg", NULL)) { ++ of_node_put(child); ++ return -EINVAL; ++ } ++ ++ if (!of_mdiobus_find_phy(dev, mdiodev, child)) { ++ /* The refcount for the PHY package will be ++ * incremented later when PHY join the Package. ++ */ ++ of_node_put(child); ++ return 0; ++ } ++ ++ continue; ++ } ++ + addr = of_mdio_parse_addr(dev, child); + if (addr < 0) + continue; +@@ -470,9 +485,22 @@ static void of_mdiobus_link_mdiodev(stru + /* The refcount on "child" is passed to the mdio + * device. Do _not_ use of_node_put(child) here. + */ +- return; ++ return 0; + } + } ++ ++ return -ENODEV; ++} ++ ++static void of_mdiobus_link_mdiodev(struct mii_bus *bus, ++ struct mdio_device *mdiodev) ++{ ++ struct device *dev = &mdiodev->dev; ++ ++ if (dev->of_node || !bus->dev.of_node) ++ return; ++ ++ of_mdiobus_find_phy(dev, mdiodev, bus->dev.of_node); + } + #else /* !IS_ENABLED(CONFIG_OF_MDIO) */ + static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio, diff --git a/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch b/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch new file mode 100644 index 0000000000..2e38269060 --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch @@ -0,0 +1,185 @@ +From 471e8fd3afcef5a9f9089f0bd21965ad9ba35c91 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:06 +0100 +Subject: [PATCH 03/10] net: phy: add devm/of_phy_package_join helper + +Add devm/of_phy_package_join helper to join PHYs in a PHY package. These +are variant of the manual phy_package_join with the difference that +these will use DT nodes to derive the base_addr instead of manually +passing an hardcoded value. + +An additional value is added in phy_package_shared, "np" to reference +the PHY package node pointer in specific PHY driver probe_once and +config_init_once functions to make use of additional specific properties +defined in the PHY package node in DT. + +The np value is filled only with of_phy_package_join if a valid PHY +package node is found. A valid PHY package node must have the node name +set to "ethernet-phy-package". + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/phy_device.c | 96 ++++++++++++++++++++++++++++++++++++ + include/linux/phy.h | 6 +++ + 2 files changed, 102 insertions(+) + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1650,6 +1650,7 @@ int phy_package_join(struct phy_device * + shared->priv_size = priv_size; + } + shared->base_addr = base_addr; ++ shared->np = NULL; + refcount_set(&shared->refcnt, 1); + bus->shared[base_addr] = shared; + } else { +@@ -1673,6 +1674,63 @@ err_unlock: + EXPORT_SYMBOL_GPL(phy_package_join); + + /** ++ * of_phy_package_join - join a common PHY group in PHY package ++ * @phydev: target phy_device struct ++ * @priv_size: if non-zero allocate this amount of bytes for private data ++ * ++ * This is a variant of phy_package_join for PHY package defined in DT. ++ * ++ * The parent node of the @phydev is checked as a valid PHY package node ++ * structure (by matching the node name "ethernet-phy-package") and the ++ * base_addr for the PHY package is passed to phy_package_join. ++ * ++ * With this configuration the shared struct will also have the np value ++ * filled to use additional DT defined properties in PHY specific ++ * probe_once and config_init_once PHY package OPs. ++ * ++ * Returns < 0 on error, 0 on success. Esp. calling phy_package_join() ++ * with the same cookie but a different priv_size is an error. Or a parent ++ * node is not detected or is not valid or doesn't match the expected node ++ * name for PHY package. ++ */ ++int of_phy_package_join(struct phy_device *phydev, size_t priv_size) ++{ ++ struct device_node *node = phydev->mdio.dev.of_node; ++ struct device_node *package_node; ++ u32 base_addr; ++ int ret; ++ ++ if (!node) ++ return -EINVAL; ++ ++ package_node = of_get_parent(node); ++ if (!package_node) ++ return -EINVAL; ++ ++ if (!of_node_name_eq(package_node, "ethernet-phy-package")) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ if (of_property_read_u32(package_node, "reg", &base_addr)) { ++ ret = -EINVAL; ++ goto exit; ++ } ++ ++ ret = phy_package_join(phydev, base_addr, priv_size); ++ if (ret) ++ goto exit; ++ ++ phydev->shared->np = package_node; ++ ++ return 0; ++exit: ++ of_node_put(package_node); ++ return ret; ++} ++EXPORT_SYMBOL_GPL(of_phy_package_join); ++ ++/** + * phy_package_leave - leave a common PHY group + * @phydev: target phy_device struct + * +@@ -1688,6 +1746,10 @@ void phy_package_leave(struct phy_device + if (!shared) + return; + ++ /* Decrease the node refcount on leave if present */ ++ if (shared->np) ++ of_node_put(shared->np); ++ + if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) { + bus->shared[shared->base_addr] = NULL; + mutex_unlock(&bus->shared_lock); +@@ -1741,6 +1803,40 @@ int devm_phy_package_join(struct device + EXPORT_SYMBOL_GPL(devm_phy_package_join); + + /** ++ * devm_of_phy_package_join - resource managed of_phy_package_join() ++ * @dev: device that is registering this PHY package ++ * @phydev: target phy_device struct ++ * @priv_size: if non-zero allocate this amount of bytes for private data ++ * ++ * Managed of_phy_package_join(). Shared storage fetched by this function, ++ * phy_package_leave() is automatically called on driver detach. See ++ * of_phy_package_join() for more information. ++ */ ++int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev, ++ size_t priv_size) ++{ ++ struct phy_device **ptr; ++ int ret; ++ ++ ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr), ++ GFP_KERNEL); ++ if (!ptr) ++ return -ENOMEM; ++ ++ ret = of_phy_package_join(phydev, priv_size); ++ ++ if (!ret) { ++ *ptr = phydev; ++ devres_add(dev, ptr); ++ } else { ++ devres_free(ptr); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(devm_of_phy_package_join); ++ ++/** + * phy_detach - detach a PHY device from its network device + * @phydev: target phy_device struct + * +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -321,6 +321,7 @@ struct mdio_bus_stats { + * struct phy_package_shared - Shared information in PHY packages + * @base_addr: Base PHY address of PHY package used to combine PHYs + * in one package and for offset calculation of phy_package_read/write ++ * @np: Pointer to the Device Node if PHY package defined in DT + * @refcnt: Number of PHYs connected to this shared data + * @flags: Initialization of PHY package + * @priv_size: Size of the shared private data @priv +@@ -332,6 +333,8 @@ struct mdio_bus_stats { + */ + struct phy_package_shared { + u8 base_addr; ++ /* With PHY package defined in DT this points to the PHY package node */ ++ struct device_node *np; + refcount_t refcnt; + unsigned long flags; + size_t priv_size; +@@ -1765,9 +1768,12 @@ int phy_ethtool_set_link_ksettings(struc + const struct ethtool_link_ksettings *cmd); + int phy_ethtool_nway_reset(struct net_device *ndev); + int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size); ++int of_phy_package_join(struct phy_device *phydev, size_t priv_size); + void phy_package_leave(struct phy_device *phydev); + int devm_phy_package_join(struct device *dev, struct phy_device *phydev, + int base_addr, size_t priv_size); ++int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev, ++ size_t priv_size); + + #if IS_ENABLED(CONFIG_PHYLIB) + int __init mdio_bus_init(void); diff --git a/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch b/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch new file mode 100644 index 0000000000..e935725630 --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch @@ -0,0 +1,583 @@ +From 737eb75a815f9c08dcbb6631db57f4f4b0540a5b Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:07 +0100 +Subject: [PATCH 04/10] net: phy: qcom: move more function to shared library + +Move more function to shared library in preparation for introduction of +new PHY Family qca807x that will make use of both functions from at803x +and qca808x as it's a transition PHY with some implementation of at803x +and some from the new qca808x. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/qcom/at803x.c | 35 ----- + drivers/net/phy/qcom/qca808x.c | 205 ---------------------------- + drivers/net/phy/qcom/qcom-phy-lib.c | 193 ++++++++++++++++++++++++++ + drivers/net/phy/qcom/qcom.h | 51 +++++++ + 4 files changed, 244 insertions(+), 240 deletions(-) + +--- a/drivers/net/phy/qcom/at803x.c ++++ b/drivers/net/phy/qcom/at803x.c +@@ -504,41 +504,6 @@ static void at803x_link_change_notify(st + } + } + +-static int at803x_read_status(struct phy_device *phydev) +-{ +- struct at803x_ss_mask ss_mask = { 0 }; +- int err, old_link = phydev->link; +- +- /* Update the link, but return if there was an error */ +- err = genphy_update_link(phydev); +- if (err) +- return err; +- +- /* why bother the PHY if nothing can have changed */ +- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) +- return 0; +- +- phydev->speed = SPEED_UNKNOWN; +- phydev->duplex = DUPLEX_UNKNOWN; +- phydev->pause = 0; +- phydev->asym_pause = 0; +- +- err = genphy_read_lpa(phydev); +- if (err < 0) +- return err; +- +- ss_mask.speed_mask = AT803X_SS_SPEED_MASK; +- ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); +- err = at803x_read_specific_status(phydev, ss_mask); +- if (err < 0) +- return err; +- +- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) +- phy_resolve_aneg_pause(phydev); +- +- return 0; +-} +- + static int at803x_config_aneg(struct phy_device *phydev) + { + struct at803x_priv *priv = phydev->priv; +--- a/drivers/net/phy/qcom/qca808x.c ++++ b/drivers/net/phy/qcom/qca808x.c +@@ -2,7 +2,6 @@ + + #include + #include +-#include + + #include "qcom.h" + +@@ -63,55 +62,6 @@ + #define QCA808X_DBG_AN_TEST 0xb + #define QCA808X_HIBERNATION_EN BIT(15) + +-#define QCA808X_CDT_ENABLE_TEST BIT(15) +-#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) +-#define QCA808X_CDT_STATUS BIT(11) +-#define QCA808X_CDT_LENGTH_UNIT BIT(10) +- +-#define QCA808X_MMD3_CDT_STATUS 0x8064 +-#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 +-#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 +-#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 +-#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 +-#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) +-#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) +- +-#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) +-#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) +-#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) +-#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) +- +-#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) +-#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) +-#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) +-#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) +-#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) +- +-#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) +-#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) +-#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) +-#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) +- +-/* NORMAL are MDI with type set to 0 */ +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ +- QCA808X_CDT_STATUS_STAT_MDI1) +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ +- QCA808X_CDT_STATUS_STAT_MDI1) +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ +- QCA808X_CDT_STATUS_STAT_MDI2) +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ +- QCA808X_CDT_STATUS_STAT_MDI2) +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ +- QCA808X_CDT_STATUS_STAT_MDI3) +-#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ +- QCA808X_CDT_STATUS_STAT_MDI3) +- +-/* Added for reference of existence but should be handled by wait_for_completion already */ +-#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) +- + #define QCA808X_MMD7_LED_GLOBAL 0x8073 + #define QCA808X_LED_BLINK_1 GENMASK(11, 6) + #define QCA808X_LED_BLINK_2 GENMASK(5, 0) +@@ -406,86 +356,6 @@ static int qca808x_soft_reset(struct phy + return ret; + } + +-static bool qca808x_cdt_fault_length_valid(int cdt_code) +-{ +- switch (cdt_code) { +- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: +- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: +- return true; +- default: +- return false; +- } +-} +- +-static int qca808x_cable_test_result_trans(int cdt_code) +-{ +- switch (cdt_code) { +- case QCA808X_CDT_STATUS_STAT_NORMAL: +- return ETHTOOL_A_CABLE_RESULT_CODE_OK; +- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: +- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; +- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: +- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: +- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: +- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; +- case QCA808X_CDT_STATUS_STAT_FAIL: +- default: +- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; +- } +-} +- +-static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, +- int result) +-{ +- int val; +- u32 cdt_length_reg = 0; +- +- switch (pair) { +- case ETHTOOL_A_CABLE_PAIR_A: +- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; +- break; +- case ETHTOOL_A_CABLE_PAIR_B: +- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; +- break; +- case ETHTOOL_A_CABLE_PAIR_C: +- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; +- break; +- case ETHTOOL_A_CABLE_PAIR_D: +- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; +- break; +- default: +- return -EINVAL; +- } +- +- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); +- if (val < 0) +- return val; +- +- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) +- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); +- else +- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); +- +- return at803x_cdt_fault_length(val); +-} +- + static int qca808x_cable_test_start(struct phy_device *phydev) + { + int ret; +@@ -526,81 +396,6 @@ static int qca808x_cable_test_start(stru + + return 0; + } +- +-static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, +- u16 status) +-{ +- int length, result; +- u16 pair_code; +- +- switch (pair) { +- case ETHTOOL_A_CABLE_PAIR_A: +- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); +- break; +- case ETHTOOL_A_CABLE_PAIR_B: +- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); +- break; +- case ETHTOOL_A_CABLE_PAIR_C: +- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); +- break; +- case ETHTOOL_A_CABLE_PAIR_D: +- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); +- break; +- default: +- return -EINVAL; +- } +- +- result = qca808x_cable_test_result_trans(pair_code); +- ethnl_cable_test_result(phydev, pair, result); +- +- if (qca808x_cdt_fault_length_valid(pair_code)) { +- length = qca808x_cdt_fault_length(phydev, pair, result); +- ethnl_cable_test_fault_length(phydev, pair, length); +- } +- +- return 0; +-} +- +-static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) +-{ +- int ret, val; +- +- *finished = false; +- +- val = QCA808X_CDT_ENABLE_TEST | +- QCA808X_CDT_LENGTH_UNIT; +- ret = at803x_cdt_start(phydev, val); +- if (ret) +- return ret; +- +- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); +- if (ret) +- return ret; +- +- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); +- if (val < 0) +- return val; +- +- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); +- if (ret) +- return ret; +- +- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); +- if (ret) +- return ret; +- +- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); +- if (ret) +- return ret; +- +- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); +- if (ret) +- return ret; +- +- *finished = true; +- +- return 0; +-} + + static int qca808x_get_features(struct phy_device *phydev) + { +--- a/drivers/net/phy/qcom/qcom-phy-lib.c ++++ b/drivers/net/phy/qcom/qcom-phy-lib.c +@@ -5,6 +5,7 @@ + + #include + #include ++#include + + #include "qcom.h" + +@@ -311,6 +312,42 @@ int at803x_prepare_config_aneg(struct ph + } + EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg); + ++int at803x_read_status(struct phy_device *phydev) ++{ ++ struct at803x_ss_mask ss_mask = { 0 }; ++ int err, old_link = phydev->link; ++ ++ /* Update the link, but return if there was an error */ ++ err = genphy_update_link(phydev); ++ if (err) ++ return err; ++ ++ /* why bother the PHY if nothing can have changed */ ++ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) ++ return 0; ++ ++ phydev->speed = SPEED_UNKNOWN; ++ phydev->duplex = DUPLEX_UNKNOWN; ++ phydev->pause = 0; ++ phydev->asym_pause = 0; ++ ++ err = genphy_read_lpa(phydev); ++ if (err < 0) ++ return err; ++ ++ ss_mask.speed_mask = AT803X_SS_SPEED_MASK; ++ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); ++ err = at803x_read_specific_status(phydev, ss_mask); ++ if (err < 0) ++ return err; ++ ++ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) ++ phy_resolve_aneg_pause(phydev); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(at803x_read_status); ++ + static int at803x_get_downshift(struct phy_device *phydev, u8 *d) + { + int val; +@@ -427,3 +464,159 @@ int at803x_cdt_wait_for_completion(struc + return ret < 0 ? ret : 0; + } + EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion); ++ ++static bool qca808x_cdt_fault_length_valid(int cdt_code) ++{ ++ switch (cdt_code) { ++ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: ++ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static int qca808x_cable_test_result_trans(int cdt_code) ++{ ++ switch (cdt_code) { ++ case QCA808X_CDT_STATUS_STAT_NORMAL: ++ return ETHTOOL_A_CABLE_RESULT_CODE_OK; ++ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: ++ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; ++ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: ++ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: ++ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: ++ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; ++ case QCA808X_CDT_STATUS_STAT_FAIL: ++ default: ++ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; ++ } ++} ++ ++static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, ++ int result) ++{ ++ int val; ++ u32 cdt_length_reg = 0; ++ ++ switch (pair) { ++ case ETHTOOL_A_CABLE_PAIR_A: ++ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; ++ break; ++ case ETHTOOL_A_CABLE_PAIR_B: ++ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; ++ break; ++ case ETHTOOL_A_CABLE_PAIR_C: ++ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; ++ break; ++ case ETHTOOL_A_CABLE_PAIR_D: ++ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); ++ if (val < 0) ++ return val; ++ ++ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) ++ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); ++ else ++ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); ++ ++ return at803x_cdt_fault_length(val); ++} ++ ++static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, ++ u16 status) ++{ ++ int length, result; ++ u16 pair_code; ++ ++ switch (pair) { ++ case ETHTOOL_A_CABLE_PAIR_A: ++ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); ++ break; ++ case ETHTOOL_A_CABLE_PAIR_B: ++ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); ++ break; ++ case ETHTOOL_A_CABLE_PAIR_C: ++ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); ++ break; ++ case ETHTOOL_A_CABLE_PAIR_D: ++ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ result = qca808x_cable_test_result_trans(pair_code); ++ ethnl_cable_test_result(phydev, pair, result); ++ ++ if (qca808x_cdt_fault_length_valid(pair_code)) { ++ length = qca808x_cdt_fault_length(phydev, pair, result); ++ ethnl_cable_test_fault_length(phydev, pair, length); ++ } ++ ++ return 0; ++} ++ ++int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) ++{ ++ int ret, val; ++ ++ *finished = false; ++ ++ val = QCA808X_CDT_ENABLE_TEST | ++ QCA808X_CDT_LENGTH_UNIT; ++ ret = at803x_cdt_start(phydev, val); ++ if (ret) ++ return ret; ++ ++ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); ++ if (ret) ++ return ret; ++ ++ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); ++ if (val < 0) ++ return val; ++ ++ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); ++ if (ret) ++ return ret; ++ ++ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); ++ if (ret) ++ return ret; ++ ++ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); ++ if (ret) ++ return ret; ++ ++ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); ++ if (ret) ++ return ret; ++ ++ *finished = true; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status); +--- a/drivers/net/phy/qcom/qcom.h ++++ b/drivers/net/phy/qcom/qcom.h +@@ -54,6 +54,55 @@ + #define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) + #define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) + ++#define QCA808X_CDT_ENABLE_TEST BIT(15) ++#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) ++#define QCA808X_CDT_STATUS BIT(11) ++#define QCA808X_CDT_LENGTH_UNIT BIT(10) ++ ++#define QCA808X_MMD3_CDT_STATUS 0x8064 ++#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 ++#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 ++#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 ++#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 ++#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) ++#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) ++ ++#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) ++#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) ++#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) ++#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) ++ ++#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) ++#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) ++#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) ++#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) ++#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) ++ ++#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) ++#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) ++#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) ++#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) ++ ++/* NORMAL are MDI with type set to 0 */ ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ ++ QCA808X_CDT_STATUS_STAT_MDI1) ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ ++ QCA808X_CDT_STATUS_STAT_MDI1) ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ ++ QCA808X_CDT_STATUS_STAT_MDI2) ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ ++ QCA808X_CDT_STATUS_STAT_MDI2) ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ ++ QCA808X_CDT_STATUS_STAT_MDI3) ++#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ ++ QCA808X_CDT_STATUS_STAT_MDI3) ++ ++/* Added for reference of existence but should be handled by wait_for_completion already */ ++#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) ++ + #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C + #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B + #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A +@@ -110,6 +159,7 @@ int at803x_read_specific_status(struct p + struct at803x_ss_mask ss_mask); + int at803x_config_mdix(struct phy_device *phydev, u8 ctrl); + int at803x_prepare_config_aneg(struct phy_device *phydev); ++int at803x_read_status(struct phy_device *phydev); + int at803x_get_tunable(struct phy_device *phydev, + struct ethtool_tunable *tuna, void *data); + int at803x_set_tunable(struct phy_device *phydev, +@@ -118,3 +168,4 @@ int at803x_cdt_fault_length(int dt); + int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start); + int at803x_cdt_wait_for_completion(struct phy_device *phydev, + u32 cdt_en); ++int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished); diff --git a/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch b/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch new file mode 100644 index 0000000000..4371599f4a --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch @@ -0,0 +1,100 @@ +From 9b1d5e055508393561e26bd1720f4c2639b03b1a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:09 +0100 +Subject: [PATCH 06/10] net: phy: provide whether link has changed in + c37_read_status + +Some PHY driver might require additional regs call after +genphy_c37_read_status() is called. + +Expand genphy_c37_read_status to provide a bool wheather the link has +changed or not to permit PHY driver to skip additional regs call if +nothing has changed. + +Every user of genphy_c37_read_status() is updated with the new +additional bool. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/broadcom.c | 3 ++- + drivers/net/phy/phy_device.c | 11 +++++++++-- + drivers/net/phy/qcom/at803x.c | 3 ++- + include/linux/phy.h | 2 +- + 4 files changed, 14 insertions(+), 5 deletions(-) + +--- a/drivers/net/phy/broadcom.c ++++ b/drivers/net/phy/broadcom.c +@@ -609,10 +609,11 @@ static int bcm54616s_config_aneg(struct + static int bcm54616s_read_status(struct phy_device *phydev) + { + struct bcm54616s_phy_priv *priv = phydev->priv; ++ bool changed; + int err; + + if (priv->mode_1000bx_en) +- err = genphy_c37_read_status(phydev); ++ err = genphy_c37_read_status(phydev, &changed); + else + err = genphy_read_status(phydev); + +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -2551,12 +2551,15 @@ EXPORT_SYMBOL(genphy_read_status); + /** + * genphy_c37_read_status - check the link status and update current link state + * @phydev: target phy_device struct ++ * @changed: pointer where to store if link changed + * + * Description: Check the link, then figure out the current state + * by comparing what we advertise with what the link partner + * advertises. This function is for Clause 37 1000Base-X mode. ++ * ++ * If link has changed, @changed is set to true, false otherwise. + */ +-int genphy_c37_read_status(struct phy_device *phydev) ++int genphy_c37_read_status(struct phy_device *phydev, bool *changed) + { + int lpa, err, old_link = phydev->link; + +@@ -2566,9 +2569,13 @@ int genphy_c37_read_status(struct phy_de + return err; + + /* why bother the PHY if nothing can have changed */ +- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) ++ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) { ++ *changed = false; + return 0; ++ } + ++ /* Signal link has changed */ ++ *changed = true; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; +--- a/drivers/net/phy/qcom/at803x.c ++++ b/drivers/net/phy/qcom/at803x.c +@@ -912,9 +912,10 @@ static int at8031_config_intr(struct phy + static int at8031_read_status(struct phy_device *phydev) + { + struct at803x_priv *priv = phydev->priv; ++ bool changed; + + if (priv->is_1000basex) +- return genphy_c37_read_status(phydev); ++ return genphy_c37_read_status(phydev, &changed); + + return at803x_read_status(phydev); + } +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -1660,7 +1660,7 @@ int genphy_write_mmd_unsupported(struct + + /* Clause 37 */ + int genphy_c37_config_aneg(struct phy_device *phydev); +-int genphy_c37_read_status(struct phy_device *phydev); ++int genphy_c37_read_status(struct phy_device *phydev, bool *changed); + + /* Clause 45 PHY */ + int genphy_c45_restart_aneg(struct phy_device *phydev); diff --git a/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch b/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch new file mode 100644 index 0000000000..bbf0f76d68 --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch @@ -0,0 +1,668 @@ +From d1cb613efbd3cd7d0c000167816beb3f248f5eb8 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 6 Feb 2024 18:31:10 +0100 +Subject: [PATCH 07/10] net: phy: qcom: add support for QCA807x PHY Family + +This adds driver for the Qualcomm QCA8072 and QCA8075 PHY-s. + +They are 2 or 5 port IEEE 802.3 clause 22 compliant 10BASE-Te, +100BASE-TX and 1000BASE-T PHY-s. + +They feature 2 SerDes, one for PSGMII or QSGMII connection with +MAC, while second one is SGMII for connection to MAC or fiber. + +Both models have a combo port that supports 1000BASE-X and +100BASE-FX fiber. + +PHY package can be configured in 3 mode following this table: + + First Serdes mode Second Serdes mode +Option 1 PSGMII for copper Disabled + ports 0-4 +Option 2 PSGMII for copper 1000BASE-X / 100BASE-FX + ports 0-4 +Option 3 QSGMII for copper SGMII for + ports 0-3 copper port 4 + +Each PHY inside of QCA807x series has 4 digitally controlled +output only pins that natively drive LED-s. +But some vendors used these to driver generic LED-s controlled +by userspace, so lets enable registering each PHY as GPIO +controller and add driver for it. + +These are commonly used in Qualcomm IPQ40xx, IPQ60xx and IPQ807x +boards. + +Co-developed-by: Christian Marangi +Signed-off-by: Robert Marko +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/qcom/Kconfig | 8 + + drivers/net/phy/qcom/Makefile | 1 + + drivers/net/phy/qcom/qca807x.c | 597 +++++++++++++++++++++++++++++++++ + 3 files changed, 606 insertions(+) + create mode 100644 drivers/net/phy/qcom/qca807x.c + +--- a/drivers/net/phy/qcom/Kconfig ++++ b/drivers/net/phy/qcom/Kconfig +@@ -20,3 +20,11 @@ config QCA808X_PHY + select QCOM_NET_PHYLIB + help + Currently supports the QCA8081 model ++ ++config QCA807X_PHY ++ tristate "Qualcomm QCA807x PHYs" ++ select QCOM_NET_PHYLIB ++ depends on OF_MDIO ++ help ++ Currently supports the Qualcomm QCA8072, QCA8075 and the PSGMII ++ control PHY. +--- a/drivers/net/phy/qcom/Makefile ++++ b/drivers/net/phy/qcom/Makefile +@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-ph + obj-$(CONFIG_AT803X_PHY) += at803x.o + obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o + obj-$(CONFIG_QCA808X_PHY) += qca808x.o ++obj-$(CONFIG_QCA807X_PHY) += qca807x.o +--- /dev/null ++++ b/drivers/net/phy/qcom/qca807x.c +@@ -0,0 +1,597 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (c) 2023 Sartura Ltd. ++ * ++ * Author: Robert Marko ++ * Christian Marangi ++ * ++ * Qualcomm QCA8072 and QCA8075 PHY driver ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qcom.h" ++ ++#define QCA807X_CHIP_CONFIGURATION 0x1f ++#define QCA807X_BT_BX_REG_SEL BIT(15) ++#define QCA807X_BT_BX_REG_SEL_FIBER 0 ++#define QCA807X_BT_BX_REG_SEL_COPPER 1 ++#define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0) ++#define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4 ++#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3 ++#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0 ++ ++#define QCA807X_MEDIA_SELECT_STATUS 0x1a ++#define QCA807X_MEDIA_DETECTED_COPPER BIT(5) ++#define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4) ++#define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3) ++ ++#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e ++#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0) ++ ++#define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a ++#define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) ++/* List of tweaks enabled by this bit: ++ * - With both FULL amplitude and FULL bias current: bias current ++ * is set to half. ++ * - With only DSP amplitude: bias current is set to half and ++ * is set to 1/4 with cable < 10m. ++ * - With DSP bias current (included both DSP amplitude and ++ * DSP bias current): bias current is half the detected current ++ * with cable < 10m. ++ */ ++#define QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK BIT(2) ++#define QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT BIT(1) ++#define QCA807X_CONTROL_DAC_DSP_AMPLITUDE BIT(0) ++ ++#define QCA807X_MMD7_LED_100N_1 0x8074 ++#define QCA807X_MMD7_LED_100N_2 0x8075 ++#define QCA807X_MMD7_LED_1000N_1 0x8076 ++#define QCA807X_MMD7_LED_1000N_2 0x8077 ++ ++#define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) ++#define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) ++ ++#define QCA807X_GPIO_FORCE_EN BIT(15) ++#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) ++ ++#define QCA807X_FUNCTION_CONTROL 0x10 ++#define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) ++#define QCA807X_FC_MDI_CROSSOVER_AUTO 3 ++#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1 ++#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0 ++ ++/* PQSGMII Analog PHY specific */ ++#define PQSGMII_CTRL_REG 0x0 ++#define PQSGMII_ANALOG_SW_RESET BIT(6) ++#define PQSGMII_DRIVE_CONTROL_1 0xb ++#define PQSGMII_TX_DRIVER_MASK GENMASK(7, 4) ++#define PQSGMII_TX_DRIVER_140MV 0x0 ++#define PQSGMII_TX_DRIVER_160MV 0x1 ++#define PQSGMII_TX_DRIVER_180MV 0x2 ++#define PQSGMII_TX_DRIVER_200MV 0x3 ++#define PQSGMII_TX_DRIVER_220MV 0x4 ++#define PQSGMII_TX_DRIVER_240MV 0x5 ++#define PQSGMII_TX_DRIVER_260MV 0x6 ++#define PQSGMII_TX_DRIVER_280MV 0x7 ++#define PQSGMII_TX_DRIVER_300MV 0x8 ++#define PQSGMII_TX_DRIVER_320MV 0x9 ++#define PQSGMII_TX_DRIVER_400MV 0xa ++#define PQSGMII_TX_DRIVER_500MV 0xb ++#define PQSGMII_TX_DRIVER_600MV 0xc ++#define PQSGMII_MODE_CTRL 0x6d ++#define PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0) ++#define PQSGMII_MMD3_SERDES_CONTROL 0x805a ++ ++#define PHY_ID_QCA8072 0x004dd0b2 ++#define PHY_ID_QCA8075 0x004dd0b1 ++ ++#define QCA807X_COMBO_ADDR_OFFSET 4 ++#define QCA807X_PQSGMII_ADDR_OFFSET 5 ++#define SERDES_RESET_SLEEP 100 ++ ++enum qca807x_global_phy { ++ QCA807X_COMBO_ADDR = 4, ++ QCA807X_PQSGMII_ADDR = 5, ++}; ++ ++struct qca807x_shared_priv { ++ unsigned int package_mode; ++ u32 tx_drive_strength; ++}; ++ ++struct qca807x_gpio_priv { ++ struct phy_device *phy; ++}; ++ ++struct qca807x_priv { ++ bool dac_full_amplitude; ++ bool dac_full_bias_current; ++ bool dac_disable_bias_current_tweak; ++}; ++ ++static int qca807x_cable_test_start(struct phy_device *phydev) ++{ ++ /* we do all the (time consuming) work later */ ++ return 0; ++} ++ ++#ifdef CONFIG_GPIOLIB ++static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) ++{ ++ return GPIO_LINE_DIRECTION_OUT; ++} ++ ++static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) ++{ ++ struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); ++ u16 reg; ++ int val; ++ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); ++ val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); ++ ++ return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); ++} ++ ++static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) ++{ ++ struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); ++ u16 reg; ++ int val; ++ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); ++ ++ val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); ++ val &= ~QCA807X_GPIO_FORCE_MODE_MASK; ++ val |= QCA807X_GPIO_FORCE_EN; ++ val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); ++ ++ phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val); ++} ++ ++static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) ++{ ++ qca807x_gpio_set(gc, offset, value); ++ ++ return 0; ++} ++ ++static int qca807x_gpio(struct phy_device *phydev) ++{ ++ struct device *dev = &phydev->mdio.dev; ++ struct qca807x_gpio_priv *priv; ++ struct gpio_chip *gc; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->phy = phydev; ++ ++ gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); ++ if (!gc) ++ return -ENOMEM; ++ ++ gc->label = dev_name(dev); ++ gc->base = -1; ++ gc->ngpio = 2; ++ gc->parent = dev; ++ gc->owner = THIS_MODULE; ++ gc->can_sleep = true; ++ gc->get_direction = qca807x_gpio_get_direction; ++ gc->direction_output = qca807x_gpio_dir_out; ++ gc->get = qca807x_gpio_get; ++ gc->set = qca807x_gpio_set; ++ ++ return devm_gpiochip_add_data(dev, gc, priv); ++} ++#endif ++ ++static int qca807x_read_fiber_status(struct phy_device *phydev) ++{ ++ bool changed; ++ int ss, err; ++ ++ err = genphy_c37_read_status(phydev, &changed); ++ if (err || !changed) ++ return err; ++ ++ /* Read the QCA807x PHY-Specific Status register fiber page, ++ * which indicates the speed and duplex that the PHY is actually ++ * using, irrespective of whether we are in autoneg mode or not. ++ */ ++ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); ++ if (ss < 0) ++ return ss; ++ ++ phydev->speed = SPEED_UNKNOWN; ++ phydev->duplex = DUPLEX_UNKNOWN; ++ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { ++ switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) { ++ case AT803X_SS_SPEED_100: ++ phydev->speed = SPEED_100; ++ break; ++ case AT803X_SS_SPEED_1000: ++ phydev->speed = SPEED_1000; ++ break; ++ } ++ ++ if (ss & AT803X_SS_DUPLEX) ++ phydev->duplex = DUPLEX_FULL; ++ else ++ phydev->duplex = DUPLEX_HALF; ++ } ++ ++ return 0; ++} ++ ++static int qca807x_read_status(struct phy_device *phydev) ++{ ++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) { ++ switch (phydev->port) { ++ case PORT_FIBRE: ++ return qca807x_read_fiber_status(phydev); ++ case PORT_TP: ++ return at803x_read_status(phydev); ++ default: ++ return -EINVAL; ++ } ++ } ++ ++ return at803x_read_status(phydev); ++} ++ ++static int qca807x_phy_package_probe_once(struct phy_device *phydev) ++{ ++ struct phy_package_shared *shared = phydev->shared; ++ struct qca807x_shared_priv *priv = shared->priv; ++ unsigned int tx_drive_strength; ++ const char *package_mode_name; ++ ++ /* Default to 600mw if not defined */ ++ if (of_property_read_u32(shared->np, "qcom,tx-drive-strength-milliwatt", ++ &tx_drive_strength)) ++ tx_drive_strength = 600; ++ ++ switch (tx_drive_strength) { ++ case 140: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_140MV; ++ break; ++ case 160: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_160MV; ++ break; ++ case 180: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_180MV; ++ break; ++ case 200: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_200MV; ++ break; ++ case 220: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_220MV; ++ break; ++ case 240: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_240MV; ++ break; ++ case 260: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_260MV; ++ break; ++ case 280: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_280MV; ++ break; ++ case 300: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_300MV; ++ break; ++ case 320: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_320MV; ++ break; ++ case 400: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_400MV; ++ break; ++ case 500: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_500MV; ++ break; ++ case 600: ++ priv->tx_drive_strength = PQSGMII_TX_DRIVER_600MV; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ priv->package_mode = PHY_INTERFACE_MODE_NA; ++ if (!of_property_read_string(shared->np, "qcom,package-mode", ++ &package_mode_name)) { ++ if (!strcasecmp(package_mode_name, ++ phy_modes(PHY_INTERFACE_MODE_PSGMII))) ++ priv->package_mode = PHY_INTERFACE_MODE_PSGMII; ++ else if (!strcasecmp(package_mode_name, ++ phy_modes(PHY_INTERFACE_MODE_QSGMII))) ++ priv->package_mode = PHY_INTERFACE_MODE_QSGMII; ++ else ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int qca807x_phy_package_config_init_once(struct phy_device *phydev) ++{ ++ struct phy_package_shared *shared = phydev->shared; ++ struct qca807x_shared_priv *priv = shared->priv; ++ int val, ret; ++ ++ phy_lock_mdio_bus(phydev); ++ ++ /* Set correct PHY package mode */ ++ val = __phy_package_read(phydev, QCA807X_COMBO_ADDR, ++ QCA807X_CHIP_CONFIGURATION); ++ val &= ~QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK; ++ /* package_mode can be QSGMII or PSGMII and we validate ++ * this in probe_once. ++ * With package_mode to NA, we default to PSGMII. ++ */ ++ switch (priv->package_mode) { ++ case PHY_INTERFACE_MODE_QSGMII: ++ val |= QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII; ++ break; ++ case PHY_INTERFACE_MODE_PSGMII: ++ default: ++ val |= QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER; ++ } ++ ret = __phy_package_write(phydev, QCA807X_COMBO_ADDR, ++ QCA807X_CHIP_CONFIGURATION, val); ++ if (ret) ++ goto exit; ++ ++ /* After mode change Serdes reset is required */ ++ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, ++ PQSGMII_CTRL_REG); ++ val &= ~PQSGMII_ANALOG_SW_RESET; ++ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, ++ PQSGMII_CTRL_REG, val); ++ if (ret) ++ goto exit; ++ ++ msleep(SERDES_RESET_SLEEP); ++ ++ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, ++ PQSGMII_CTRL_REG); ++ val |= PQSGMII_ANALOG_SW_RESET; ++ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, ++ PQSGMII_CTRL_REG, val); ++ if (ret) ++ goto exit; ++ ++ /* Workaround to enable AZ transmitting ability */ ++ val = __phy_package_read_mmd(phydev, QCA807X_PQSGMII_ADDR, ++ MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL); ++ val &= ~PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK; ++ ret = __phy_package_write_mmd(phydev, QCA807X_PQSGMII_ADDR, ++ MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL, val); ++ if (ret) ++ goto exit; ++ ++ /* Set PQSGMII TX AMP strength */ ++ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, ++ PQSGMII_DRIVE_CONTROL_1); ++ val &= ~PQSGMII_TX_DRIVER_MASK; ++ val |= FIELD_PREP(PQSGMII_TX_DRIVER_MASK, priv->tx_drive_strength); ++ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, ++ PQSGMII_DRIVE_CONTROL_1, val); ++ if (ret) ++ goto exit; ++ ++ /* Prevent PSGMII going into hibernation via PSGMII self test */ ++ val = __phy_package_read_mmd(phydev, QCA807X_COMBO_ADDR, ++ MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL); ++ val &= ~BIT(1); ++ ret = __phy_package_write_mmd(phydev, QCA807X_COMBO_ADDR, ++ MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL, val); ++ ++exit: ++ phy_unlock_mdio_bus(phydev); ++ ++ return ret; ++} ++ ++static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) ++{ ++ struct phy_device *phydev = upstream; ++ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; ++ phy_interface_t iface; ++ int ret; ++ DECLARE_PHY_INTERFACE_MASK(interfaces); ++ ++ sfp_parse_support(phydev->sfp_bus, id, support, interfaces); ++ iface = sfp_select_interface(phydev->sfp_bus, support); ++ ++ dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); ++ ++ switch (iface) { ++ case PHY_INTERFACE_MODE_1000BASEX: ++ case PHY_INTERFACE_MODE_100BASEX: ++ /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */ ++ ret = phy_modify(phydev, ++ QCA807X_CHIP_CONFIGURATION, ++ QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK, ++ QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER); ++ /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */ ++ ret = phy_set_bits_mmd(phydev, ++ MDIO_MMD_AN, ++ QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION, ++ QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN); ++ /* Select fiber page */ ++ ret = phy_clear_bits(phydev, ++ QCA807X_CHIP_CONFIGURATION, ++ QCA807X_BT_BX_REG_SEL); ++ ++ phydev->port = PORT_FIBRE; ++ break; ++ default: ++ dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n"); ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static void qca807x_sfp_remove(void *upstream) ++{ ++ struct phy_device *phydev = upstream; ++ ++ /* Select copper page */ ++ phy_set_bits(phydev, ++ QCA807X_CHIP_CONFIGURATION, ++ QCA807X_BT_BX_REG_SEL); ++ ++ phydev->port = PORT_TP; ++} ++ ++static const struct sfp_upstream_ops qca807x_sfp_ops = { ++ .attach = phy_sfp_attach, ++ .detach = phy_sfp_detach, ++ .module_insert = qca807x_sfp_insert, ++ .module_remove = qca807x_sfp_remove, ++}; ++ ++static int qca807x_probe(struct phy_device *phydev) ++{ ++ struct device_node *node = phydev->mdio.dev.of_node; ++ struct qca807x_shared_priv *shared_priv; ++ struct device *dev = &phydev->mdio.dev; ++ struct phy_package_shared *shared; ++ struct qca807x_priv *priv; ++ int ret; ++ ++ ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv)); ++ if (ret) ++ return ret; ++ ++ if (phy_package_probe_once(phydev)) { ++ ret = qca807x_phy_package_probe_once(phydev); ++ if (ret) ++ return ret; ++ } ++ ++ shared = phydev->shared; ++ shared_priv = shared->priv; ++ ++ /* Make sure PHY follow PHY package mode if enforced */ ++ if (shared_priv->package_mode != PHY_INTERFACE_MODE_NA && ++ phydev->interface != shared_priv->package_mode) ++ return -EINVAL; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->dac_full_amplitude = of_property_read_bool(node, "qcom,dac-full-amplitude"); ++ priv->dac_full_bias_current = of_property_read_bool(node, "qcom,dac-full-bias-current"); ++ priv->dac_disable_bias_current_tweak = of_property_read_bool(node, ++ "qcom,dac-disable-bias-current-tweak"); ++ ++ if (IS_ENABLED(CONFIG_GPIOLIB)) { ++ /* Do not register a GPIO controller unless flagged for it */ ++ if (of_property_read_bool(node, "gpio-controller")) { ++ ret = qca807x_gpio(phydev); ++ if (ret) ++ return ret; ++ } ++ } ++ ++ /* Attach SFP bus on combo port*/ ++ if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { ++ ret = phy_sfp_probe(phydev, &qca807x_sfp_ops); ++ if (ret) ++ return ret; ++ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); ++ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising); ++ } ++ ++ phydev->priv = priv; ++ ++ return 0; ++} ++ ++static int qca807x_config_init(struct phy_device *phydev) ++{ ++ struct qca807x_priv *priv = phydev->priv; ++ u16 control_dac; ++ int ret; ++ ++ if (phy_package_init_once(phydev)) { ++ ret = qca807x_phy_package_config_init_once(phydev); ++ if (ret) ++ return ret; ++ } ++ ++ control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, ++ QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); ++ control_dac &= ~QCA807X_CONTROL_DAC_MASK; ++ if (!priv->dac_full_amplitude) ++ control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE; ++ if (!priv->dac_full_amplitude) ++ control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT; ++ if (!priv->dac_disable_bias_current_tweak) ++ control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK; ++ return phy_write_mmd(phydev, MDIO_MMD_AN, ++ QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH, ++ control_dac); ++} ++ ++static struct phy_driver qca807x_drivers[] = { ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), ++ .name = "Qualcomm QCA8072", ++ .flags = PHY_POLL_CABLE_TEST, ++ /* PHY_GBIT_FEATURES */ ++ .probe = qca807x_probe, ++ .config_init = qca807x_config_init, ++ .read_status = qca807x_read_status, ++ .config_intr = at803x_config_intr, ++ .handle_interrupt = at803x_handle_interrupt, ++ .soft_reset = genphy_soft_reset, ++ .get_tunable = at803x_get_tunable, ++ .set_tunable = at803x_set_tunable, ++ .resume = genphy_resume, ++ .suspend = genphy_suspend, ++ .cable_test_start = qca807x_cable_test_start, ++ .cable_test_get_status = qca808x_cable_test_get_status, ++ }, ++ { ++ PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), ++ .name = "Qualcomm QCA8075", ++ .flags = PHY_POLL_CABLE_TEST, ++ /* PHY_GBIT_FEATURES */ ++ .probe = qca807x_probe, ++ .config_init = qca807x_config_init, ++ .read_status = qca807x_read_status, ++ .config_intr = at803x_config_intr, ++ .handle_interrupt = at803x_handle_interrupt, ++ .soft_reset = genphy_soft_reset, ++ .get_tunable = at803x_get_tunable, ++ .set_tunable = at803x_set_tunable, ++ .resume = genphy_resume, ++ .suspend = genphy_suspend, ++ .cable_test_start = qca807x_cable_test_start, ++ .cable_test_get_status = qca808x_cable_test_get_status, ++ }, ++}; ++module_phy_driver(qca807x_drivers); ++ ++static struct mdio_device_id __maybe_unused qca807x_tbl[] = { ++ { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, ++ { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, ++ { } ++}; ++ ++MODULE_AUTHOR("Robert Marko "); ++MODULE_AUTHOR("Christian Marangi "); ++MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver"); ++MODULE_DEVICE_TABLE(mdio, qca807x_tbl); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch b/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch new file mode 100644 index 0000000000..cf4d74e8c5 --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch @@ -0,0 +1,179 @@ +From ee9d9807bee0e6af8ca2a4db6f0d1dc0e5b41f44 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:11 +0100 +Subject: [PATCH 08/10] net: phy: qcom: move common qca808x LED define to + shared header + +The LED implementation of qca808x and qca807x is the same but qca807x +supports also Fiber port and have different hw control bits for Fiber +port. + +In preparation for qca807x introduction, move all the common define to +shared header. + +Signed-off-by: Christian Marangi +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +--- + drivers/net/phy/qcom/qca808x.c | 65 ---------------------------------- + drivers/net/phy/qcom/qcom.h | 65 ++++++++++++++++++++++++++++++++++ + 2 files changed, 65 insertions(+), 65 deletions(-) + +--- a/drivers/net/phy/qcom/qca808x.c ++++ b/drivers/net/phy/qcom/qca808x.c +@@ -62,29 +62,6 @@ + #define QCA808X_DBG_AN_TEST 0xb + #define QCA808X_HIBERNATION_EN BIT(15) + +-#define QCA808X_MMD7_LED_GLOBAL 0x8073 +-#define QCA808X_LED_BLINK_1 GENMASK(11, 6) +-#define QCA808X_LED_BLINK_2 GENMASK(5, 0) +-/* Values are the same for both BLINK_1 and BLINK_2 */ +-#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) +-#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) +-#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) +-#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) +-#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) +-#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) +-#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) +-#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) +-#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) +-#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) +-#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) +-#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) +-#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) +-#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) +-#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) +-#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) +-#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) +-#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) +- + #define QCA808X_MMD7_LED2_CTRL 0x8074 + #define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 + #define QCA808X_MMD7_LED1_CTRL 0x8076 +@@ -92,51 +69,9 @@ + #define QCA808X_MMD7_LED0_CTRL 0x8078 + #define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) + +-/* LED hw control pattern is the same for every LED */ +-#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) +-#define QCA808X_LED_SPEED2500_ON BIT(15) +-#define QCA808X_LED_SPEED2500_BLINK BIT(14) +-/* Follow blink trigger even if duplex or speed condition doesn't match */ +-#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) +-#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) +-#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) +-#define QCA808X_LED_TX_BLINK BIT(10) +-#define QCA808X_LED_RX_BLINK BIT(9) +-#define QCA808X_LED_TX_ON_10MS BIT(8) +-#define QCA808X_LED_RX_ON_10MS BIT(7) +-#define QCA808X_LED_SPEED1000_ON BIT(6) +-#define QCA808X_LED_SPEED100_ON BIT(5) +-#define QCA808X_LED_SPEED10_ON BIT(4) +-#define QCA808X_LED_COLLISION_BLINK BIT(3) +-#define QCA808X_LED_SPEED1000_BLINK BIT(2) +-#define QCA808X_LED_SPEED100_BLINK BIT(1) +-#define QCA808X_LED_SPEED10_BLINK BIT(0) +- + #define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 + #define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) + +-/* LED force ctrl is the same for every LED +- * No documentation exist for this, not even internal one +- * with NDA as QCOM gives only info about configuring +- * hw control pattern rules and doesn't indicate any way +- * to force the LED to specific mode. +- * These define comes from reverse and testing and maybe +- * lack of some info or some info are not entirely correct. +- * For the basic LED control and hw control these finding +- * are enough to support LED control in all the required APIs. +- * +- * On doing some comparison with implementation with qca807x, +- * it was found that it's 1:1 equal to it and confirms all the +- * reverse done. It was also found further specification with the +- * force mode and the blink modes. +- */ +-#define QCA808X_LED_FORCE_EN BIT(15) +-#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) +-#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) +-#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) +-#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) +-#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) +- + #define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a + /* QSDK sets by default 0x46 to this reg that sets BIT 6 for + * LED to active high. It's not clear what BIT 3 and BIT 4 does. +--- a/drivers/net/phy/qcom/qcom.h ++++ b/drivers/net/phy/qcom/qcom.h +@@ -103,6 +103,71 @@ + /* Added for reference of existence but should be handled by wait_for_completion already */ + #define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) + ++#define QCA808X_MMD7_LED_GLOBAL 0x8073 ++#define QCA808X_LED_BLINK_1 GENMASK(11, 6) ++#define QCA808X_LED_BLINK_2 GENMASK(5, 0) ++/* Values are the same for both BLINK_1 and BLINK_2 */ ++#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) ++#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) ++#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) ++#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) ++#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) ++#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) ++#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) ++#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) ++#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) ++#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) ++#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) ++#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) ++#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) ++#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) ++#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) ++#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) ++#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) ++#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) ++ ++/* LED hw control pattern is the same for every LED */ ++#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) ++#define QCA808X_LED_SPEED2500_ON BIT(15) ++#define QCA808X_LED_SPEED2500_BLINK BIT(14) ++/* Follow blink trigger even if duplex or speed condition doesn't match */ ++#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) ++#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) ++#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) ++#define QCA808X_LED_TX_BLINK BIT(10) ++#define QCA808X_LED_RX_BLINK BIT(9) ++#define QCA808X_LED_TX_ON_10MS BIT(8) ++#define QCA808X_LED_RX_ON_10MS BIT(7) ++#define QCA808X_LED_SPEED1000_ON BIT(6) ++#define QCA808X_LED_SPEED100_ON BIT(5) ++#define QCA808X_LED_SPEED10_ON BIT(4) ++#define QCA808X_LED_COLLISION_BLINK BIT(3) ++#define QCA808X_LED_SPEED1000_BLINK BIT(2) ++#define QCA808X_LED_SPEED100_BLINK BIT(1) ++#define QCA808X_LED_SPEED10_BLINK BIT(0) ++ ++/* LED force ctrl is the same for every LED ++ * No documentation exist for this, not even internal one ++ * with NDA as QCOM gives only info about configuring ++ * hw control pattern rules and doesn't indicate any way ++ * to force the LED to specific mode. ++ * These define comes from reverse and testing and maybe ++ * lack of some info or some info are not entirely correct. ++ * For the basic LED control and hw control these finding ++ * are enough to support LED control in all the required APIs. ++ * ++ * On doing some comparison with implementation with qca807x, ++ * it was found that it's 1:1 equal to it and confirms all the ++ * reverse done. It was also found further specification with the ++ * force mode and the blink modes. ++ */ ++#define QCA808X_LED_FORCE_EN BIT(15) ++#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) ++#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) ++#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) ++#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) ++#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) ++ + #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C + #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B + #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A diff --git a/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch b/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch new file mode 100644 index 0000000000..da73c1d3b8 --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch @@ -0,0 +1,172 @@ +From 47b930d0dd437af927145dba50a2e2ea1ba97c67 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:12 +0100 +Subject: [PATCH 09/10] net: phy: qcom: generalize some qca808x LED functions + +Generalize some qca808x LED functions in preparation for qca807x LED +support. + +The LED implementation of qca808x and qca807x is the same but qca807x +supports also Fiber port and have different hw control bits for Fiber +port. To limit code duplication introduce micro functions that takes reg +instead of LED index to tweak all the supported LED modes. + +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/phy/qcom/qca808x.c | 38 +++----------------- + drivers/net/phy/qcom/qcom-phy-lib.c | 54 +++++++++++++++++++++++++++++ + drivers/net/phy/qcom/qcom.h | 7 ++++ + 3 files changed, 65 insertions(+), 34 deletions(-) + +--- a/drivers/net/phy/qcom/qca808x.c ++++ b/drivers/net/phy/qcom/qca808x.c +@@ -437,9 +437,7 @@ static int qca808x_led_hw_control_enable + return -EINVAL; + + reg = QCA808X_MMD7_LED_FORCE_CTRL(index); +- +- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, +- QCA808X_LED_FORCE_EN); ++ return qca808x_led_reg_hw_control_enable(phydev, reg); + } + + static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, +@@ -480,16 +478,12 @@ static int qca808x_led_hw_control_set(st + static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) + { + u16 reg; +- int val; + + if (index > 2) + return false; + + reg = QCA808X_MMD7_LED_FORCE_CTRL(index); +- +- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); +- +- return !(val & QCA808X_LED_FORCE_EN); ++ return qca808x_led_reg_hw_control_status(phydev, reg); + } + + static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, +@@ -557,44 +551,20 @@ static int qca808x_led_brightness_set(st + } + + reg = QCA808X_MMD7_LED_FORCE_CTRL(index); +- +- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, +- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, +- QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON : +- QCA808X_LED_FORCE_OFF)); ++ return qca808x_led_reg_brightness_set(phydev, reg, value); + } + + static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, + unsigned long *delay_on, + unsigned long *delay_off) + { +- int ret; + u16 reg; + + if (index > 2) + return -EINVAL; + + reg = QCA808X_MMD7_LED_FORCE_CTRL(index); +- +- /* Set blink to 50% off, 50% on at 4Hz by default */ +- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, +- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, +- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); +- if (ret) +- return ret; +- +- /* We use BLINK_1 for normal blinking */ +- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, +- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, +- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); +- if (ret) +- return ret; +- +- /* We set blink to 4Hz, aka 250ms */ +- *delay_on = 250 / 2; +- *delay_off = 250 / 2; +- +- return 0; ++ return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); + } + + static int qca808x_led_polarity_set(struct phy_device *phydev, int index, +--- a/drivers/net/phy/qcom/qcom-phy-lib.c ++++ b/drivers/net/phy/qcom/qcom-phy-lib.c +@@ -620,3 +620,57 @@ int qca808x_cable_test_get_status(struct + return 0; + } + EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status); ++ ++int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg) ++{ ++ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, ++ QCA808X_LED_FORCE_EN); ++} ++EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_enable); ++ ++bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg) ++{ ++ int val; ++ ++ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); ++ return !(val & QCA808X_LED_FORCE_EN); ++} ++EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_status); ++ ++int qca808x_led_reg_brightness_set(struct phy_device *phydev, ++ u16 reg, enum led_brightness value) ++{ ++ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, ++ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, ++ QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON : ++ QCA808X_LED_FORCE_OFF)); ++} ++EXPORT_SYMBOL_GPL(qca808x_led_reg_brightness_set); ++ ++int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ int ret; ++ ++ /* Set blink to 50% off, 50% on at 4Hz by default */ ++ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, ++ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, ++ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); ++ if (ret) ++ return ret; ++ ++ /* We use BLINK_1 for normal blinking */ ++ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, ++ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, ++ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); ++ if (ret) ++ return ret; ++ ++ /* We set blink to 4Hz, aka 250ms */ ++ *delay_on = 250 / 2; ++ *delay_off = 250 / 2; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(qca808x_led_reg_blink_set); +--- a/drivers/net/phy/qcom/qcom.h ++++ b/drivers/net/phy/qcom/qcom.h +@@ -234,3 +234,10 @@ int at803x_cdt_start(struct phy_device * + int at803x_cdt_wait_for_completion(struct phy_device *phydev, + u32 cdt_en); + int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished); ++int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg); ++bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg); ++int qca808x_led_reg_brightness_set(struct phy_device *phydev, ++ u16 reg, enum led_brightness value); ++int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg, ++ unsigned long *delay_on, ++ unsigned long *delay_off); diff --git a/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch b/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch new file mode 100644 index 0000000000..3bd36f6ffe --- /dev/null +++ b/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch @@ -0,0 +1,326 @@ +From f508a226b517a6a8afd78a317de46bc83e3e3d51 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Tue, 6 Feb 2024 18:31:13 +0100 +Subject: [PATCH 10/10] net: phy: qca807x: add support for configurable LED + +QCA8072/5 have up to 2 LEDs attached for PHY. + +LEDs can be configured to be ON/hw blink or be set to HW control. + +Hw blink mode is set to blink at 4Hz or 250ms. + +PHY can support both copper (TP) or fiber (FIBRE) kind and supports +different HW control modes based on the port type. + +HW control modes supported for netdev trigger for copper ports are: +- LINK_10 +- LINK_100 +- LINK_1000 +- TX +- RX +- FULL_DUPLEX +- HALF_DUPLEX + +HW control modes supported for netdev trigger for fiber ports are: +- LINK_100 +- LINK_1000 +- TX +- RX +- FULL_DUPLEX +- HALF_DUPLEX + +LED support conflicts with GPIO controller feature and must be disabled +if gpio-controller is used for the PHY. + +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/phy/qcom/qca807x.c | 256 ++++++++++++++++++++++++++++++++- + 1 file changed, 254 insertions(+), 2 deletions(-) + +--- a/drivers/net/phy/qcom/qca807x.c ++++ b/drivers/net/phy/qcom/qca807x.c +@@ -57,8 +57,18 @@ + #define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) + #define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) + +-#define QCA807X_GPIO_FORCE_EN BIT(15) +-#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) ++/* LED hw control pattern for fiber port */ ++#define QCA807X_LED_FIBER_PATTERN_MASK GENMASK(11, 1) ++#define QCA807X_LED_FIBER_TXACT_BLK_EN BIT(10) ++#define QCA807X_LED_FIBER_RXACT_BLK_EN BIT(9) ++#define QCA807X_LED_FIBER_FDX_ON_EN BIT(6) ++#define QCA807X_LED_FIBER_HDX_ON_EN BIT(5) ++#define QCA807X_LED_FIBER_1000BX_ON_EN BIT(2) ++#define QCA807X_LED_FIBER_100FX_ON_EN BIT(1) ++ ++/* Some device repurpose the LED as GPIO out */ ++#define QCA807X_GPIO_FORCE_EN QCA808X_LED_FORCE_EN ++#define QCA807X_GPIO_FORCE_MODE_MASK QCA808X_LED_FORCE_MODE_MASK + + #define QCA807X_FUNCTION_CONTROL 0x10 + #define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) +@@ -121,6 +131,233 @@ static int qca807x_cable_test_start(stru + return 0; + } + ++static int qca807x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, ++ u16 *offload_trigger) ++{ ++ /* Parsing specific to netdev trigger */ ++ switch (phydev->port) { ++ case PORT_TP: ++ if (test_bit(TRIGGER_NETDEV_TX, &rules)) ++ *offload_trigger |= QCA808X_LED_TX_BLINK; ++ if (test_bit(TRIGGER_NETDEV_RX, &rules)) ++ *offload_trigger |= QCA808X_LED_RX_BLINK; ++ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) ++ *offload_trigger |= QCA808X_LED_SPEED10_ON; ++ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) ++ *offload_trigger |= QCA808X_LED_SPEED100_ON; ++ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) ++ *offload_trigger |= QCA808X_LED_SPEED1000_ON; ++ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) ++ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; ++ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) ++ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; ++ break; ++ case PORT_FIBRE: ++ if (test_bit(TRIGGER_NETDEV_TX, &rules)) ++ *offload_trigger |= QCA807X_LED_FIBER_TXACT_BLK_EN; ++ if (test_bit(TRIGGER_NETDEV_RX, &rules)) ++ *offload_trigger |= QCA807X_LED_FIBER_RXACT_BLK_EN; ++ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) ++ *offload_trigger |= QCA807X_LED_FIBER_100FX_ON_EN; ++ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) ++ *offload_trigger |= QCA807X_LED_FIBER_1000BX_ON_EN; ++ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) ++ *offload_trigger |= QCA807X_LED_FIBER_HDX_ON_EN; ++ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) ++ *offload_trigger |= QCA807X_LED_FIBER_FDX_ON_EN; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ if (rules && !*offload_trigger) ++ return -EOPNOTSUPP; ++ ++ return 0; ++} ++ ++static int qca807x_led_hw_control_enable(struct phy_device *phydev, u8 index) ++{ ++ u16 reg; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ return qca808x_led_reg_hw_control_enable(phydev, reg); ++} ++ ++static int qca807x_led_hw_is_supported(struct phy_device *phydev, u8 index, ++ unsigned long rules) ++{ ++ u16 offload_trigger = 0; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ return qca807x_led_parse_netdev(phydev, rules, &offload_trigger); ++} ++ ++static int qca807x_led_hw_control_set(struct phy_device *phydev, u8 index, ++ unsigned long rules) ++{ ++ u16 reg, mask, offload_trigger = 0; ++ int ret; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ ret = qca807x_led_parse_netdev(phydev, rules, &offload_trigger); ++ if (ret) ++ return ret; ++ ++ ret = qca807x_led_hw_control_enable(phydev, index); ++ if (ret) ++ return ret; ++ ++ switch (phydev->port) { ++ case PORT_TP: ++ reg = QCA807X_MMD7_LED_CTRL(index); ++ mask = QCA808X_LED_PATTERN_MASK; ++ break; ++ case PORT_FIBRE: ++ /* HW control pattern bits are in LED FORCE reg */ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ mask = QCA807X_LED_FIBER_PATTERN_MASK; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, mask, ++ offload_trigger); ++} ++ ++static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index) ++{ ++ u16 reg; ++ ++ if (index > 1) ++ return false; ++ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ return qca808x_led_reg_hw_control_status(phydev, reg); ++} ++ ++static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index, ++ unsigned long *rules) ++{ ++ u16 reg; ++ int val; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ /* Check if we have hw control enabled */ ++ if (qca807x_led_hw_control_status(phydev, index)) ++ return -EINVAL; ++ ++ /* Parsing specific to netdev trigger */ ++ switch (phydev->port) { ++ case PORT_TP: ++ reg = QCA807X_MMD7_LED_CTRL(index); ++ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); ++ if (val & QCA808X_LED_TX_BLINK) ++ set_bit(TRIGGER_NETDEV_TX, rules); ++ if (val & QCA808X_LED_RX_BLINK) ++ set_bit(TRIGGER_NETDEV_RX, rules); ++ if (val & QCA808X_LED_SPEED10_ON) ++ set_bit(TRIGGER_NETDEV_LINK_10, rules); ++ if (val & QCA808X_LED_SPEED100_ON) ++ set_bit(TRIGGER_NETDEV_LINK_100, rules); ++ if (val & QCA808X_LED_SPEED1000_ON) ++ set_bit(TRIGGER_NETDEV_LINK_1000, rules); ++ if (val & QCA808X_LED_HALF_DUPLEX_ON) ++ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); ++ if (val & QCA808X_LED_FULL_DUPLEX_ON) ++ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); ++ break; ++ case PORT_FIBRE: ++ /* HW control pattern bits are in LED FORCE reg */ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); ++ if (val & QCA807X_LED_FIBER_TXACT_BLK_EN) ++ set_bit(TRIGGER_NETDEV_TX, rules); ++ if (val & QCA807X_LED_FIBER_RXACT_BLK_EN) ++ set_bit(TRIGGER_NETDEV_RX, rules); ++ if (val & QCA807X_LED_FIBER_100FX_ON_EN) ++ set_bit(TRIGGER_NETDEV_LINK_100, rules); ++ if (val & QCA807X_LED_FIBER_1000BX_ON_EN) ++ set_bit(TRIGGER_NETDEV_LINK_1000, rules); ++ if (val & QCA807X_LED_FIBER_HDX_ON_EN) ++ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); ++ if (val & QCA807X_LED_FIBER_FDX_ON_EN) ++ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int qca807x_led_hw_control_reset(struct phy_device *phydev, u8 index) ++{ ++ u16 reg, mask; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ switch (phydev->port) { ++ case PORT_TP: ++ reg = QCA807X_MMD7_LED_CTRL(index); ++ mask = QCA808X_LED_PATTERN_MASK; ++ break; ++ case PORT_FIBRE: ++ /* HW control pattern bits are in LED FORCE reg */ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ mask = QCA807X_LED_FIBER_PATTERN_MASK; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, mask); ++} ++ ++static int qca807x_led_brightness_set(struct phy_device *phydev, ++ u8 index, enum led_brightness value) ++{ ++ u16 reg; ++ int ret; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ /* If we are setting off the LED reset any hw control rule */ ++ if (!value) { ++ ret = qca807x_led_hw_control_reset(phydev, index); ++ if (ret) ++ return ret; ++ } ++ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ return qca808x_led_reg_brightness_set(phydev, reg, value); ++} ++ ++static int qca807x_led_blink_set(struct phy_device *phydev, u8 index, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ u16 reg; ++ ++ if (index > 1) ++ return -EINVAL; ++ ++ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); ++ return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); ++} ++ + #ifdef CONFIG_GPIOLIB + static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) + { +@@ -496,6 +733,16 @@ static int qca807x_probe(struct phy_devi + "qcom,dac-disable-bias-current-tweak"); + + if (IS_ENABLED(CONFIG_GPIOLIB)) { ++ /* Make sure we don't have mixed leds node and gpio-controller ++ * to prevent registering leds and having gpio-controller usage ++ * conflicting with them. ++ */ ++ if (of_find_property(node, "leds", NULL) && ++ of_find_property(node, "gpio-controller", NULL)) { ++ phydev_err(phydev, "Invalid property detected. LEDs and gpio-controller are mutually exclusive."); ++ return -EINVAL; ++ } ++ + /* Do not register a GPIO controller unless flagged for it */ + if (of_property_read_bool(node, "gpio-controller")) { + ret = qca807x_gpio(phydev); +@@ -580,6 +827,11 @@ static struct phy_driver qca807x_drivers + .suspend = genphy_suspend, + .cable_test_start = qca807x_cable_test_start, + .cable_test_get_status = qca808x_cable_test_get_status, ++ .led_brightness_set = qca807x_led_brightness_set, ++ .led_blink_set = qca807x_led_blink_set, ++ .led_hw_is_supported = qca807x_led_hw_is_supported, ++ .led_hw_control_set = qca807x_led_hw_control_set, ++ .led_hw_control_get = qca807x_led_hw_control_get, + }, + }; + module_phy_driver(qca807x_drivers); diff --git a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch index c958362e96..70a3a4ad5c 100644 --- a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch +++ b/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch @@ -56,7 +56,7 @@ Signed-off-by: David S. Miller mutex_init(&dev->lock); INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); -@@ -2934,6 +2937,74 @@ static bool phy_drv_supports_irq(struct +@@ -3037,6 +3040,74 @@ static bool phy_drv_supports_irq(struct return phydrv->config_intr && phydrv->handle_interrupt; } @@ -131,7 +131,7 @@ Signed-off-by: David S. Miller /** * fwnode_mdio_find_device - Given a fwnode, find the mdio_device * @fwnode: pointer to the mdio_device's fwnode -@@ -3112,6 +3183,11 @@ static int phy_probe(struct device *dev) +@@ -3215,6 +3286,11 @@ static int phy_probe(struct device *dev) /* Set the state to READY by default */ phydev->state = PHY_READY; @@ -153,7 +153,7 @@ Signed-off-by: David S. Miller #include #include #include -@@ -603,6 +604,7 @@ struct macsec_ops; +@@ -606,6 +607,7 @@ struct macsec_ops; * @phy_num_led_triggers: Number of triggers in @phy_led_triggers * @led_link_trigger: LED trigger for link up/down * @last_triggered: last LED trigger for link speed @@ -161,7 +161,7 @@ Signed-off-by: David S. Miller * @master_slave_set: User requested master/slave configuration * @master_slave_get: Current master/slave advertisement * @master_slave_state: Current master/slave configuration -@@ -695,6 +697,7 @@ struct phy_device { +@@ -698,6 +700,7 @@ struct phy_device { struct phy_led_trigger *led_link_trigger; #endif @@ -169,7 +169,7 @@ Signed-off-by: David S. Miller /* * Interrupt number for this PHY -@@ -769,6 +772,19 @@ struct phy_tdr_config { +@@ -772,6 +775,19 @@ struct phy_tdr_config { #define PHY_PAIR_ALL -1 /** diff --git a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch index 3c2477a63a..e2e7bd65b1 100644 --- a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ b/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -20,7 +20,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -2937,11 +2937,18 @@ static bool phy_drv_supports_irq(struct +@@ -3040,11 +3040,18 @@ static bool phy_drv_supports_irq(struct return phydrv->config_intr && phydrv->handle_interrupt; } @@ -41,7 +41,7 @@ Signed-off-by: David S. Miller } static int of_phy_led(struct phy_device *phydev, -@@ -2958,12 +2965,14 @@ static int of_phy_led(struct phy_device +@@ -3061,12 +3068,14 @@ static int of_phy_led(struct phy_device return -ENOMEM; cdev = &phyled->led_cdev; @@ -59,7 +59,7 @@ Signed-off-by: David S. Miller init_data.fwnode = of_fwnode_handle(led); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -775,15 +775,19 @@ struct phy_tdr_config { +@@ -778,15 +778,19 @@ struct phy_tdr_config { * struct phy_led: An LED driven by the PHY * * @list: List of LEDs @@ -79,7 +79,7 @@ Signed-off-by: David S. Miller /** * struct phy_driver - Driver structure for a particular PHY type * -@@ -998,6 +1002,15 @@ struct phy_driver { +@@ -1001,6 +1005,15 @@ struct phy_driver { int (*get_sqi)(struct phy_device *dev); /** @get_sqi_max: Get the maximum signal quality indication */ int (*get_sqi_max)(struct phy_device *dev); diff --git a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch index 35d83d8a6a..804caf5d35 100644 --- a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ b/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -18,7 +18,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -2951,6 +2951,22 @@ static int phy_led_set_brightness(struct +@@ -3054,6 +3054,22 @@ static int phy_led_set_brightness(struct return err; } @@ -41,7 +41,7 @@ Signed-off-by: David S. Miller static int of_phy_led(struct phy_device *phydev, struct device_node *led) { -@@ -2973,6 +2989,8 @@ static int of_phy_led(struct phy_device +@@ -3076,6 +3092,8 @@ static int of_phy_led(struct phy_device if (phydev->drv->led_brightness_set) cdev->brightness_set_blocking = phy_led_set_brightness; @@ -52,7 +52,7 @@ Signed-off-by: David S. Miller init_data.fwnode = of_fwnode_handle(led); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -1011,6 +1011,18 @@ struct phy_driver { +@@ -1014,6 +1014,18 @@ struct phy_driver { */ int (*led_brightness_set)(struct phy_device *dev, u8 index, enum led_brightness value); diff --git a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch b/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch index 66dbcb8a90..226c135f3c 100644 --- a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch +++ b/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch @@ -53,7 +53,7 @@ Signed-off-by: Jakub Kicinski tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs" --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -3213,7 +3213,8 @@ static int phy_probe(struct device *dev) +@@ -3316,7 +3316,8 @@ static int phy_probe(struct device *dev) /* Get the LEDs from the device tree, and instantiate standard * LEDs for them. */ diff --git a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch b/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch index 3710cfade2..5bb92bc946 100644 --- a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch +++ b/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch @@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -2974,6 +2974,7 @@ static int of_phy_led(struct phy_device +@@ -3077,6 +3077,7 @@ static int of_phy_led(struct phy_device struct led_init_data init_data = {}; struct led_classdev *cdev; struct phy_led *phyled; @@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski int err; phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); -@@ -2983,10 +2984,13 @@ static int of_phy_led(struct phy_device +@@ -3086,10 +3087,13 @@ static int of_phy_led(struct phy_device cdev = &phyled->led_cdev; phyled->phydev = phydev; diff --git a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch b/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch index 80ac785cdb..f7952d9f0c 100644 --- a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch +++ b/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch @@ -22,7 +22,7 @@ Signed-off-by: David S. Miller --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -2967,6 +2967,15 @@ static int phy_led_blink_set(struct led_ +@@ -3070,6 +3070,15 @@ static int phy_led_blink_set(struct led_ return err; } @@ -38,7 +38,7 @@ Signed-off-by: David S. Miller static int of_phy_led(struct phy_device *phydev, struct device_node *led) { -@@ -3000,7 +3009,7 @@ static int of_phy_led(struct phy_device +@@ -3103,7 +3112,7 @@ static int of_phy_led(struct phy_device init_data.fwnode = of_fwnode_handle(led); init_data.devname_mandatory = true; @@ -47,7 +47,7 @@ Signed-off-by: David S. Miller if (err) return err; -@@ -3029,6 +3038,7 @@ static int of_phy_leds(struct phy_device +@@ -3132,6 +3141,7 @@ static int of_phy_leds(struct phy_device err = of_phy_led(phydev, led); if (err) { of_node_put(led); @@ -55,7 +55,7 @@ Signed-off-by: David S. Miller return err; } } -@@ -3234,6 +3244,9 @@ static int phy_remove(struct device *dev +@@ -3337,6 +3347,9 @@ static int phy_remove(struct device *dev cancel_delayed_work_sync(&phydev->state_queue); diff --git a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch index 0bf1e03c49..947db79f06 100644 --- a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ b/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch @@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -2967,6 +2967,61 @@ static int phy_led_blink_set(struct led_ +@@ -3070,6 +3070,61 @@ static int phy_led_blink_set(struct led_ return err; } @@ -85,7 +85,7 @@ Signed-off-by: Jakub Kicinski static void phy_leds_unregister(struct phy_device *phydev) { struct phy_led *phyled; -@@ -3004,6 +3059,19 @@ static int of_phy_led(struct phy_device +@@ -3107,6 +3162,19 @@ static int of_phy_led(struct phy_device cdev->brightness_set_blocking = phy_led_set_brightness; if (phydev->drv->led_blink_set) cdev->blink_set = phy_led_blink_set; @@ -107,7 +107,7 @@ Signed-off-by: Jakub Kicinski init_data.fwnode = of_fwnode_handle(led); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -1023,6 +1023,39 @@ struct phy_driver { +@@ -1026,6 +1026,39 @@ struct phy_driver { int (*led_blink_set)(struct phy_device *dev, u8 index, unsigned long *delay_on, unsigned long *delay_off); diff --git a/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch b/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch index 97fbd2bfc5..1f49b3af0c 100644 --- a/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch +++ b/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch @@ -28,7 +28,7 @@ Signed-off-by: Jakub Kicinski --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -3037,6 +3037,7 @@ static int of_phy_led(struct phy_device +@@ -3140,6 +3140,7 @@ static int of_phy_led(struct phy_device struct device *dev = &phydev->mdio.dev; struct led_init_data init_data = {}; struct led_classdev *cdev; @@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski struct phy_led *phyled; u32 index; int err; -@@ -3054,6 +3055,21 @@ static int of_phy_led(struct phy_device +@@ -3157,6 +3158,21 @@ static int of_phy_led(struct phy_device if (index > U8_MAX) return -EINVAL; @@ -60,7 +60,7 @@ Signed-off-by: Jakub Kicinski cdev->brightness_set_blocking = phy_led_set_brightness; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -788,6 +788,15 @@ struct phy_led { +@@ -791,6 +791,15 @@ struct phy_led { #define to_phy_led(d) container_of(d, struct phy_led, led_cdev) @@ -76,7 +76,7 @@ Signed-off-by: Jakub Kicinski /** * struct phy_driver - Driver structure for a particular PHY type * -@@ -1056,6 +1065,19 @@ struct phy_driver { +@@ -1059,6 +1068,19 @@ struct phy_driver { int (*led_hw_control_get)(struct phy_device *dev, u8 index, unsigned long *rules); diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index 3730e584ac..7da5f21532 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -5078,6 +5078,7 @@ CONFIG_PWRSEQ_SIMPLE=y # CONFIG_QCA7000_SPI is not set # CONFIG_QCA7000_UART is not set # CONFIG_QCA83XX_PHY is not set +# CONFIG_QCA807X_PHY is not set # CONFIG_QCA808X_PHY is not set # CONFIG_QCOM_A7PLL is not set # CONFIG_QCOM_BAM_DMUX is not set diff --git a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch index b658d5205e..0c88109192 100644 --- a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch @@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c -@@ -1756,6 +1756,9 @@ void phy_detach(struct phy_device *phyde +@@ -1852,6 +1852,9 @@ void phy_detach(struct phy_device *phyde struct module *ndev_owner = NULL; struct mii_bus *bus; @@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos sysfs_remove_link(&dev->dev.kobj, "phydev"); --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -897,6 +897,12 @@ struct phy_driver { +@@ -900,6 +900,12 @@ struct phy_driver { /** @handle_interrupt: Override default interrupt handling */ irqreturn_t (*handle_interrupt)(struct phy_device *phydev); diff --git a/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch b/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch index 26d66d6d4a..73ed55a085 100644 --- a/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch +++ b/target/linux/ramips/patches-6.1/720-Revert-net-phy-simplify-phy_link_change-arguments.patch @@ -107,7 +107,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c bool tx_pause, rx_pause; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -736,7 +736,7 @@ struct phy_device { +@@ -739,7 +739,7 @@ struct phy_device { int pma_extable; diff --git a/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch index 9f1c3e05f1..2594c66048 100644 --- a/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch +++ b/target/linux/ramips/patches-6.1/721-NET-no-auto-carrier-off-support.patch @@ -37,7 +37,7 @@ Signed-off-by: John Crispin break; --- a/include/linux/phy.h +++ b/include/linux/phy.h -@@ -644,6 +644,7 @@ struct phy_device { +@@ -647,6 +647,7 @@ struct phy_device { unsigned downshifted_rate:1; unsigned is_on_sfp_module:1; unsigned mac_managed_pm:1; From 1b931c33a28ee58cc1926420332197a506a53411 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 10 Feb 2024 23:39:32 +0100 Subject: [PATCH 42/50] ipq40xx: adapt to new Upstream QCA807x PHY driver Adapt patches to new Upstream QCA807x PHY driver. Rework the PHY patch to new PHY Package nodes. Signed-off-by: Christian Marangi --- .../files/drivers/net/phy/qcom/qca807x.c | 844 ------------------ .../708-dt-bindings-net-add-QCA807x-PHY.patch | 61 -- ...pq4019-add-QCA8075-PHY-Package-nodes.patch | 67 ++ ...9-net-phy-Add-Qualcom-QCA807x-driver.patch | 49 - ...0-arm-dts-ipq4019-QCA807x-properties.patch | 50 +- 5 files changed, 74 insertions(+), 997 deletions(-) delete mode 100644 target/linux/ipq40xx/files/drivers/net/phy/qcom/qca807x.c delete mode 100644 target/linux/ipq40xx/patches-6.1/708-dt-bindings-net-add-QCA807x-PHY.patch create mode 100644 target/linux/ipq40xx/patches-6.1/709-ARM-dts-qcom-ipq4019-add-QCA8075-PHY-Package-nodes.patch delete mode 100644 target/linux/ipq40xx/patches-6.1/709-net-phy-Add-Qualcom-QCA807x-driver.patch diff --git a/target/linux/ipq40xx/files/drivers/net/phy/qcom/qca807x.c b/target/linux/ipq40xx/files/drivers/net/phy/qcom/qca807x.c deleted file mode 100644 index abfc11e121..0000000000 --- a/target/linux/ipq40xx/files/drivers/net/phy/qcom/qca807x.c +++ /dev/null @@ -1,844 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2020 Sartura Ltd. - * - * Author: Robert Marko - * - * Qualcomm QCA8072 and QCA8075 PHY driver - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define PHY_ID_QCA8072 0x004dd0b2 -#define PHY_ID_QCA8075 0x004dd0b1 -#define PHY_ID_QCA807X_PSGMII 0x06820805 - -/* Downshift */ -#define QCA807X_SMARTSPEED_EN BIT(5) -#define QCA807X_SMARTSPEED_RETRY_LIMIT_MASK GENMASK(4, 2) -#define QCA807X_SMARTSPEED_RETRY_LIMIT_DEFAULT 5 -#define QCA807X_SMARTSPEED_RETRY_LIMIT_MIN 2 -#define QCA807X_SMARTSPEED_RETRY_LIMIT_MAX 9 - -/* Cable diagnostic test (CDT) */ -#define QCA807X_CDT 0x16 -#define QCA807X_CDT_ENABLE BIT(15) -#define QCA807X_CDT_ENABLE_INTER_PAIR_SHORT BIT(13) -#define QCA807X_CDT_STATUS BIT(11) -#define QCA807X_CDT_MMD3_STATUS 0x8064 -#define QCA807X_CDT_MDI0_STATUS_MASK GENMASK(15, 12) -#define QCA807X_CDT_MDI1_STATUS_MASK GENMASK(11, 8) -#define QCA807X_CDT_MDI2_STATUS_MASK GENMASK(7, 4) -#define QCA807X_CDT_MDI3_STATUS_MASK GENMASK(3, 0) -#define QCA807X_CDT_RESULTS_INVALID 0x0 -#define QCA807X_CDT_RESULTS_OK 0x1 -#define QCA807X_CDT_RESULTS_OPEN 0x2 -#define QCA807X_CDT_RESULTS_SAME_SHORT 0x3 -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OK 0x4 -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OK 0x8 -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OK 0xc -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OPEN 0x6 -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OPEN 0xa -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OPEN 0xe -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_SHORT 0x7 -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_SHORT 0xb -#define QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_SHORT 0xf -#define QCA807X_CDT_RESULTS_BUSY 0x9 -#define QCA807X_CDT_MMD3_MDI0_LENGTH 0x8065 -#define QCA807X_CDT_MMD3_MDI1_LENGTH 0x8066 -#define QCA807X_CDT_MMD3_MDI2_LENGTH 0x8067 -#define QCA807X_CDT_MMD3_MDI3_LENGTH 0x8068 -#define QCA807X_CDT_SAME_SHORT_LENGTH_MASK GENMASK(15, 8) -#define QCA807X_CDT_CROSS_SHORT_LENGTH_MASK GENMASK(7, 0) - -#define QCA807X_CHIP_CONFIGURATION 0x1f -#define QCA807X_BT_BX_REG_SEL BIT(15) -#define QCA807X_BT_BX_REG_SEL_FIBER 0 -#define QCA807X_BT_BX_REG_SEL_COPPER 1 -#define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0) -#define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4 -#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3 -#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0 - -#define QCA807X_MEDIA_SELECT_STATUS 0x1a -#define QCA807X_MEDIA_DETECTED_COPPER BIT(5) -#define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4) -#define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3) - -#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e -#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0) - -#define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a -#define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) - -#define QCA807X_MMD7_LED_100N_1 0x8074 -#define QCA807X_MMD7_LED_100N_2 0x8075 -#define QCA807X_MMD7_LED_1000N_1 0x8076 -#define QCA807X_MMD7_LED_1000N_2 0x8077 -#define QCA807X_LED_TXACT_BLK_EN_2 BIT(10) -#define QCA807X_LED_RXACT_BLK_EN_2 BIT(9) -#define QCA807X_LED_GT_ON_EN_2 BIT(6) -#define QCA807X_LED_HT_ON_EN_2 BIT(5) -#define QCA807X_LED_BT_ON_EN_2 BIT(4) -#define QCA807X_GPIO_FORCE_EN BIT(15) -#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) - -#define QCA807X_INTR_ENABLE 0x12 -#define QCA807X_INTR_STATUS 0x13 -#define QCA807X_INTR_ENABLE_AUTONEG_ERR BIT(15) -#define QCA807X_INTR_ENABLE_SPEED_CHANGED BIT(14) -#define QCA807X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) -#define QCA807X_INTR_ENABLE_LINK_FAIL BIT(11) -#define QCA807X_INTR_ENABLE_LINK_SUCCESS BIT(10) - -#define QCA807X_FUNCTION_CONTROL 0x10 -#define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) -#define QCA807X_FC_MDI_CROSSOVER_AUTO 3 -#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1 -#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0 - -#define QCA807X_PHY_SPECIFIC_STATUS 0x11 -#define QCA807X_SS_SPEED_AND_DUPLEX_RESOLVED BIT(11) -#define QCA807X_SS_SPEED_MASK GENMASK(15, 14) -#define QCA807X_SS_SPEED_1000 2 -#define QCA807X_SS_SPEED_100 1 -#define QCA807X_SS_SPEED_10 0 -#define QCA807X_SS_DUPLEX BIT(13) -#define QCA807X_SS_MDIX BIT(6) - -/* PSGMII PHY specific */ -#define PSGMII_QSGMII_DRIVE_CONTROL_1 0xb -#define PSGMII_QSGMII_TX_DRIVER_MASK GENMASK(7, 4) -#define PSGMII_MODE_CTRL 0x6d -#define PSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0) -#define PSGMII_MMD3_SERDES_CONTROL 0x805a - -struct qca807x_gpio_priv { - struct phy_device *phy; -}; - -static int qca807x_get_downshift(struct phy_device *phydev, u8 *data) -{ - int val, cnt, enable; - - val = phy_read(phydev, MII_NWAYTEST); - if (val < 0) - return val; - - enable = FIELD_GET(QCA807X_SMARTSPEED_EN, val); - cnt = FIELD_GET(QCA807X_SMARTSPEED_RETRY_LIMIT_MASK, val) + 2; - - *data = enable ? cnt : DOWNSHIFT_DEV_DISABLE; - - return 0; -} - -static int qca807x_set_downshift(struct phy_device *phydev, u8 cnt) -{ - int ret, val; - - if (cnt > QCA807X_SMARTSPEED_RETRY_LIMIT_MAX || - (cnt < QCA807X_SMARTSPEED_RETRY_LIMIT_MIN && cnt != DOWNSHIFT_DEV_DISABLE)) - return -EINVAL; - - if (!cnt) { - ret = phy_clear_bits(phydev, MII_NWAYTEST, QCA807X_SMARTSPEED_EN); - } else { - val = QCA807X_SMARTSPEED_EN; - val |= FIELD_PREP(QCA807X_SMARTSPEED_RETRY_LIMIT_MASK, cnt - 2); - - phy_modify(phydev, MII_NWAYTEST, - QCA807X_SMARTSPEED_EN | - QCA807X_SMARTSPEED_RETRY_LIMIT_MASK, - val); - } - - ret = genphy_soft_reset(phydev); - - return ret; -} - -static int qca807x_get_tunable(struct phy_device *phydev, - struct ethtool_tunable *tuna, void *data) -{ - switch (tuna->id) { - case ETHTOOL_PHY_DOWNSHIFT: - return qca807x_get_downshift(phydev, data); - default: - return -EOPNOTSUPP; - } -} - -static int qca807x_set_tunable(struct phy_device *phydev, - struct ethtool_tunable *tuna, const void *data) -{ - switch (tuna->id) { - case ETHTOOL_PHY_DOWNSHIFT: - return qca807x_set_downshift(phydev, *(const u8 *)data); - default: - return -EOPNOTSUPP; - } -} - -static bool qca807x_distance_valid(int result) -{ - switch (result) { - case QCA807X_CDT_RESULTS_OPEN: - case QCA807X_CDT_RESULTS_SAME_SHORT: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OK: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OK: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OK: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OPEN: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OPEN: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OPEN: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_SHORT: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_SHORT: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_SHORT: - return true; - } - return false; -} - -static int qca807x_report_length(struct phy_device *phydev, - int pair, int result) -{ - int length; - int ret; - - ret = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA807X_CDT_MMD3_MDI0_LENGTH + pair); - if (ret < 0) - return ret; - - switch (result) { - case ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT: - length = (FIELD_GET(QCA807X_CDT_SAME_SHORT_LENGTH_MASK, ret) * 800) / 10; - break; - case ETHTOOL_A_CABLE_RESULT_CODE_OPEN: - case ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT: - length = (FIELD_GET(QCA807X_CDT_CROSS_SHORT_LENGTH_MASK, ret) * 800) / 10; - break; - } - - ethnl_cable_test_fault_length(phydev, pair, length); - - return 0; -} - -static int qca807x_cable_test_report_trans(int result) -{ - switch (result) { - case QCA807X_CDT_RESULTS_OK: - return ETHTOOL_A_CABLE_RESULT_CODE_OK; - case QCA807X_CDT_RESULTS_OPEN: - return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; - case QCA807X_CDT_RESULTS_SAME_SHORT: - return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OK: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OK: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OK: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_OPEN: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_OPEN: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_OPEN: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI1_SAME_SHORT: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI2_SAME_SHORT: - case QCA807X_CDT_RESULTS_CROSS_SHORT_WITH_MDI3_SAME_SHORT: - return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; - default: - return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; - } -} - -static int qca807x_cable_test_report(struct phy_device *phydev) -{ - int pair0, pair1, pair2, pair3; - int ret; - - ret = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA807X_CDT_MMD3_STATUS); - if (ret < 0) - return ret; - - pair0 = FIELD_GET(QCA807X_CDT_MDI0_STATUS_MASK, ret); - pair1 = FIELD_GET(QCA807X_CDT_MDI1_STATUS_MASK, ret); - pair2 = FIELD_GET(QCA807X_CDT_MDI2_STATUS_MASK, ret); - pair3 = FIELD_GET(QCA807X_CDT_MDI3_STATUS_MASK, ret); - - ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, - qca807x_cable_test_report_trans(pair0)); - ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B, - qca807x_cable_test_report_trans(pair1)); - ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C, - qca807x_cable_test_report_trans(pair2)); - ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D, - qca807x_cable_test_report_trans(pair3)); - - if (qca807x_distance_valid(pair0)) - qca807x_report_length(phydev, 0, qca807x_cable_test_report_trans(pair0)); - if (qca807x_distance_valid(pair1)) - qca807x_report_length(phydev, 1, qca807x_cable_test_report_trans(pair1)); - if (qca807x_distance_valid(pair2)) - qca807x_report_length(phydev, 2, qca807x_cable_test_report_trans(pair2)); - if (qca807x_distance_valid(pair3)) - qca807x_report_length(phydev, 3, qca807x_cable_test_report_trans(pair3)); - - return 0; -} - -static int qca807x_cable_test_get_status(struct phy_device *phydev, - bool *finished) -{ - int val; - - *finished = false; - - val = phy_read(phydev, QCA807X_CDT); - if (!((val & QCA807X_CDT_ENABLE) && (val & QCA807X_CDT_STATUS))) { - *finished = true; - - return qca807x_cable_test_report(phydev); - } - - return 0; -} - -static int qca807x_cable_test_start(struct phy_device *phydev) -{ - int val, ret; - - val = phy_read(phydev, QCA807X_CDT); - /* Enable inter-pair short check as well */ - val &= ~QCA807X_CDT_ENABLE_INTER_PAIR_SHORT; - val |= QCA807X_CDT_ENABLE; - ret = phy_write(phydev, QCA807X_CDT, val); - - return ret; -} - -#ifdef CONFIG_GPIOLIB -static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) -{ - return GPIO_LINE_DIRECTION_OUT; -} - -static int qca807x_gpio_get_reg(unsigned int offset) -{ - return QCA807X_MMD7_LED_100N_2 + (offset % 2) * 2; -} - -static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) -{ - struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); - int val; - - val = phy_read_mmd(priv->phy, MDIO_MMD_AN, qca807x_gpio_get_reg(offset)); - - return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); -} - -static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) -{ - struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); - int val; - - val = phy_read_mmd(priv->phy, MDIO_MMD_AN, qca807x_gpio_get_reg(offset)); - val &= ~QCA807X_GPIO_FORCE_MODE_MASK; - val |= QCA807X_GPIO_FORCE_EN; - val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); - - phy_write_mmd(priv->phy, MDIO_MMD_AN, qca807x_gpio_get_reg(offset), val); -} - -static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) -{ - qca807x_gpio_set(gc, offset, value); - - return 0; -} - -static int qca807x_gpio(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - struct qca807x_gpio_priv *priv; - struct gpio_chip *gc; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->phy = phydev; - - gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); - if (!gc) - return -ENOMEM; - - gc->label = dev_name(dev); - gc->base = -1; - gc->ngpio = 2; - gc->parent = dev; - gc->owner = THIS_MODULE; - gc->can_sleep = true; - gc->get_direction = qca807x_gpio_get_direction; - gc->direction_output = qca807x_gpio_dir_out; - gc->get = qca807x_gpio_get; - gc->set = qca807x_gpio_set; - - return devm_gpiochip_add_data(dev, gc, priv); -} -#endif - -static int qca807x_read_copper_status(struct phy_device *phydev) -{ - int ss, err, old_link = phydev->link; - - /* Update the link, but return if there was an error */ - err = genphy_update_link(phydev); - if (err) - return err; - - /* why bother the PHY if nothing can have changed */ - if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) - return 0; - - phydev->speed = SPEED_UNKNOWN; - phydev->duplex = DUPLEX_UNKNOWN; - phydev->pause = 0; - phydev->asym_pause = 0; - - err = genphy_read_lpa(phydev); - if (err < 0) - return err; - - /* Read the QCA807x PHY-Specific Status register copper page, - * which indicates the speed and duplex that the PHY is actually - * using, irrespective of whether we are in autoneg mode or not. - */ - ss = phy_read(phydev, QCA807X_PHY_SPECIFIC_STATUS); - if (ss < 0) - return ss; - - if (ss & QCA807X_SS_SPEED_AND_DUPLEX_RESOLVED) { - int sfc; - - sfc = phy_read(phydev, QCA807X_FUNCTION_CONTROL); - if (sfc < 0) - return sfc; - - switch (FIELD_GET(QCA807X_SS_SPEED_MASK, ss)) { - case QCA807X_SS_SPEED_10: - phydev->speed = SPEED_10; - break; - case QCA807X_SS_SPEED_100: - phydev->speed = SPEED_100; - break; - case QCA807X_SS_SPEED_1000: - phydev->speed = SPEED_1000; - break; - } - if (ss & QCA807X_SS_DUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - - if (ss & QCA807X_SS_MDIX) - phydev->mdix = ETH_TP_MDI_X; - else - phydev->mdix = ETH_TP_MDI; - - switch (FIELD_GET(QCA807X_FC_MDI_CROSSOVER_MODE_MASK, sfc)) { - case QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI: - phydev->mdix_ctrl = ETH_TP_MDI; - break; - case QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX: - phydev->mdix_ctrl = ETH_TP_MDI_X; - break; - case QCA807X_FC_MDI_CROSSOVER_AUTO: - phydev->mdix_ctrl = ETH_TP_MDI_AUTO; - break; - } - } - - if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) - phy_resolve_aneg_pause(phydev); - - return 0; -} - -static int qca807x_read_fiber_status(struct phy_device *phydev) -{ - int ss, err, lpa, old_link = phydev->link; - - /* Update the link, but return if there was an error */ - err = genphy_update_link(phydev); - if (err) - return err; - - /* why bother the PHY if nothing can have changed */ - if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) - return 0; - - phydev->speed = SPEED_UNKNOWN; - phydev->duplex = DUPLEX_UNKNOWN; - phydev->pause = 0; - phydev->asym_pause = 0; - - if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { - lpa = phy_read(phydev, MII_LPA); - if (lpa < 0) - return lpa; - - linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, - phydev->lp_advertising, lpa & LPA_LPACK); - linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, - phydev->lp_advertising, lpa & LPA_1000XFULL); - linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, - phydev->lp_advertising, lpa & LPA_1000XPAUSE); - linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, - phydev->lp_advertising, - lpa & LPA_1000XPAUSE_ASYM); - - phy_resolve_aneg_linkmode(phydev); - } - - /* Read the QCA807x PHY-Specific Status register fiber page, - * which indicates the speed and duplex that the PHY is actually - * using, irrespective of whether we are in autoneg mode or not. - */ - ss = phy_read(phydev, QCA807X_PHY_SPECIFIC_STATUS); - if (ss < 0) - return ss; - - if (ss & QCA807X_SS_SPEED_AND_DUPLEX_RESOLVED) { - switch (FIELD_GET(QCA807X_SS_SPEED_MASK, ss)) { - case QCA807X_SS_SPEED_100: - phydev->speed = SPEED_100; - break; - case QCA807X_SS_SPEED_1000: - phydev->speed = SPEED_1000; - break; - } - - if (ss & QCA807X_SS_DUPLEX) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - } - - return 0; -} - -static int qca807x_read_status(struct phy_device *phydev) -{ - if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) { - switch (phydev->port) { - case PORT_FIBRE: - return qca807x_read_fiber_status(phydev); - case PORT_TP: - return qca807x_read_copper_status(phydev); - default: - return -EINVAL; - } - } else - return qca807x_read_copper_status(phydev); -} - -static int qca807x_config_intr(struct phy_device *phydev) -{ - int ret, val; - - val = phy_read(phydev, QCA807X_INTR_ENABLE); - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { - /* Check for combo port as it has fewer interrupts */ - if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { - val |= QCA807X_INTR_ENABLE_SPEED_CHANGED; - val |= QCA807X_INTR_ENABLE_LINK_FAIL; - val |= QCA807X_INTR_ENABLE_LINK_SUCCESS; - } else { - val |= QCA807X_INTR_ENABLE_AUTONEG_ERR; - val |= QCA807X_INTR_ENABLE_SPEED_CHANGED; - val |= QCA807X_INTR_ENABLE_DUPLEX_CHANGED; - val |= QCA807X_INTR_ENABLE_LINK_FAIL; - val |= QCA807X_INTR_ENABLE_LINK_SUCCESS; - } - ret = phy_write(phydev, QCA807X_INTR_ENABLE, val); - } else { - ret = phy_write(phydev, QCA807X_INTR_ENABLE, 0); - } - - return ret; -} - -static irqreturn_t qca807x_handle_interrupt(struct phy_device *phydev) -{ - int irq_status, int_enabled; - - irq_status = phy_read(phydev, QCA807X_INTR_STATUS); - if (irq_status < 0) { - phy_error(phydev); - return IRQ_NONE; - } - - /* Read the current enabled interrupts */ - int_enabled = phy_read(phydev, QCA807X_INTR_ENABLE); - if (int_enabled < 0) { - phy_error(phydev); - return IRQ_NONE; - } - - /* See if this was one of our enabled interrupts */ - if (!(irq_status & int_enabled)) - return IRQ_NONE; - - phy_trigger_machine(phydev); - - return IRQ_HANDLED; -} - -static int qca807x_led_config(struct phy_device *phydev) -{ - struct device_node *node = phydev->mdio.dev.of_node; - bool led_config = false; - int val; - - val = phy_read_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_LED_1000N_1); - if (val < 0) - return val; - - if (of_property_read_bool(node, "qcom,single-led-1000")) { - val |= QCA807X_LED_TXACT_BLK_EN_2; - val |= QCA807X_LED_RXACT_BLK_EN_2; - val |= QCA807X_LED_GT_ON_EN_2; - - led_config = true; - } - - if (of_property_read_bool(node, "qcom,single-led-100")) { - val |= QCA807X_LED_HT_ON_EN_2; - - led_config = true; - } - - if (of_property_read_bool(node, "qcom,single-led-10")) { - val |= QCA807X_LED_BT_ON_EN_2; - - led_config = true; - } - - if (led_config) - return phy_write_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_LED_1000N_1, val); - else - return 0; -} - -static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -{ - struct phy_device *phydev = upstream; - __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; - phy_interface_t iface; - int ret; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) - DECLARE_PHY_INTERFACE_MASK(interfaces); - - sfp_parse_support(phydev->sfp_bus, id, support, interfaces); -#else - sfp_parse_support(phydev->sfp_bus, id, support); -#endif - iface = sfp_select_interface(phydev->sfp_bus, support); - - dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); - - switch (iface) { - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_100BASEX: - /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */ - ret = phy_modify(phydev, - QCA807X_CHIP_CONFIGURATION, - QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK, - QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER); - /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */ - ret = phy_set_bits_mmd(phydev, - MDIO_MMD_AN, - QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION, - QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN); - /* Select fiber page */ - ret = phy_clear_bits(phydev, - QCA807X_CHIP_CONFIGURATION, - QCA807X_BT_BX_REG_SEL); - - phydev->port = PORT_FIBRE; - break; - default: - dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n"); - return -EINVAL; - } - - return ret; -} - -static void qca807x_sfp_remove(void *upstream) -{ - struct phy_device *phydev = upstream; - - /* Select copper page */ - phy_set_bits(phydev, - QCA807X_CHIP_CONFIGURATION, - QCA807X_BT_BX_REG_SEL); - - phydev->port = PORT_TP; -} - -static const struct sfp_upstream_ops qca807x_sfp_ops = { - .attach = phy_sfp_attach, - .detach = phy_sfp_detach, - .module_insert = qca807x_sfp_insert, - .module_remove = qca807x_sfp_remove, -}; - -static int qca807x_config(struct phy_device *phydev) -{ - struct device_node *node = phydev->mdio.dev.of_node; - int control_dac, ret = 0; - u32 of_control_dac; - - /* Check for Combo port */ - if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { - int psgmii_serdes; - - /* Prevent PSGMII going into hibernation via PSGMII self test */ - psgmii_serdes = phy_read_mmd(phydev, MDIO_MMD_PCS, PSGMII_MMD3_SERDES_CONTROL); - psgmii_serdes &= ~BIT(1); - ret = phy_write_mmd(phydev, MDIO_MMD_PCS, - PSGMII_MMD3_SERDES_CONTROL, - psgmii_serdes); - } - - if (!of_property_read_u32(node, "qcom,control-dac", &of_control_dac)) { - control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, - QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); - control_dac &= ~QCA807X_CONTROL_DAC_MASK; - control_dac |= FIELD_PREP(QCA807X_CONTROL_DAC_MASK, of_control_dac); - ret = phy_write_mmd(phydev, MDIO_MMD_AN, - QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH, - control_dac); - } - - /* Optionally configure LED-s */ - if (IS_ENABLED(CONFIG_GPIOLIB)) { - /* Check whether PHY-s pins are used as GPIO-s */ - if (!of_property_read_bool(node, "gpio-controller")) - ret = qca807x_led_config(phydev); - } else { - ret = qca807x_led_config(phydev); - } - - return ret; -} - -static int qca807x_probe(struct phy_device *phydev) -{ - struct device_node *node = phydev->mdio.dev.of_node; - int ret = 0; - - if (IS_ENABLED(CONFIG_GPIOLIB)) { - /* Do not register a GPIO controller unless flagged for it */ - if (of_property_read_bool(node, "gpio-controller")) - ret = qca807x_gpio(phydev); - } - - /* Attach SFP bus on combo port*/ - if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { - ret = phy_sfp_probe(phydev, &qca807x_sfp_ops); - linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); - linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising); - } - - return ret; -} - -static int qca807x_psgmii_config(struct phy_device *phydev) -{ - struct device_node *node = phydev->mdio.dev.of_node; - int tx_amp, ret = 0; - u32 tx_driver_strength; - - /* Workaround to enable AZ transmitting ability */ - ret = phy_clear_bits_mmd(phydev, - MDIO_MMD_PMAPMD, - PSGMII_MODE_CTRL, - PSGMII_MODE_CTRL_AZ_WORKAROUND_MASK); - - /* PSGMII/QSGMII TX amp set to DT defined value instead of default 600mV */ - if (!of_property_read_u32(node, "qcom,tx-driver-strength", &tx_driver_strength)) { - tx_amp = phy_read(phydev, PSGMII_QSGMII_DRIVE_CONTROL_1); - tx_amp &= ~PSGMII_QSGMII_TX_DRIVER_MASK; - tx_amp |= FIELD_PREP(PSGMII_QSGMII_TX_DRIVER_MASK, tx_driver_strength); - ret = phy_write(phydev, PSGMII_QSGMII_DRIVE_CONTROL_1, tx_amp); - } - - return ret; -} - -static struct phy_driver qca807x_drivers[] = { - { - PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), - .name = "Qualcomm QCA8072", - .flags = PHY_POLL_CABLE_TEST, - /* PHY_GBIT_FEATURES */ - .probe = qca807x_probe, - .config_init = qca807x_config, - .read_status = qca807x_read_status, - .config_intr = qca807x_config_intr, - .handle_interrupt = qca807x_handle_interrupt, - .soft_reset = genphy_soft_reset, - .get_tunable = qca807x_get_tunable, - .set_tunable = qca807x_set_tunable, - .resume = genphy_resume, - .suspend = genphy_suspend, - .cable_test_start = qca807x_cable_test_start, - .cable_test_get_status = qca807x_cable_test_get_status, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), - .name = "Qualcomm QCA8075", - .flags = PHY_POLL_CABLE_TEST, - /* PHY_GBIT_FEATURES */ - .probe = qca807x_probe, - .config_init = qca807x_config, - .read_status = qca807x_read_status, - .config_intr = qca807x_config_intr, - .handle_interrupt = qca807x_handle_interrupt, - .soft_reset = genphy_soft_reset, - .get_tunable = qca807x_get_tunable, - .set_tunable = qca807x_set_tunable, - .resume = genphy_resume, - .suspend = genphy_suspend, - .cable_test_start = qca807x_cable_test_start, - .cable_test_get_status = qca807x_cable_test_get_status, - }, - { - PHY_ID_MATCH_EXACT(PHY_ID_QCA807X_PSGMII), - .name = "Qualcomm QCA807x PSGMII", - .probe = qca807x_psgmii_config, - }, -}; -module_phy_driver(qca807x_drivers); - -static struct mdio_device_id __maybe_unused qca807x_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, - { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, - { PHY_ID_MATCH_MODEL(PHY_ID_QCA807X_PSGMII) }, - { } -}; - -MODULE_AUTHOR("Robert Marko"); -MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver"); -MODULE_DEVICE_TABLE(mdio, qca807x_tbl); -MODULE_LICENSE("GPL"); diff --git a/target/linux/ipq40xx/patches-6.1/708-dt-bindings-net-add-QCA807x-PHY.patch b/target/linux/ipq40xx/patches-6.1/708-dt-bindings-net-add-QCA807x-PHY.patch deleted file mode 100644 index b325d9e535..0000000000 --- a/target/linux/ipq40xx/patches-6.1/708-dt-bindings-net-add-QCA807x-PHY.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 96eb388c082bd0086b128d82def9daaab1617951 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Thu, 1 Oct 2020 15:05:35 +0200 -Subject: [PATCH] dt-bindings: net: add QCA807x PHY - -Add DT bindings for Qualcomm QCA807x PHY series. - -Signed-off-by: Robert Marko ---- - include/dt-bindings/net/qcom-qca807x.h | 45 ++++++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - create mode 100644 include/dt-bindings/net/qcom-qca807x.h - ---- /dev/null -+++ b/include/dt-bindings/net/qcom-qca807x.h -@@ -0,0 +1,45 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Device Tree constants for the Qualcomm QCA807X PHYs -+ */ -+ -+#ifndef _DT_BINDINGS_QCOM_QCA807X_H -+#define _DT_BINDINGS_QCOM_QCA807X_H -+ -+#define PSGMII_QSGMII_TX_DRIVER_140MV 0 -+#define PSGMII_QSGMII_TX_DRIVER_160MV 1 -+#define PSGMII_QSGMII_TX_DRIVER_180MV 2 -+#define PSGMII_QSGMII_TX_DRIVER_200MV 3 -+#define PSGMII_QSGMII_TX_DRIVER_220MV 4 -+#define PSGMII_QSGMII_TX_DRIVER_240MV 5 -+#define PSGMII_QSGMII_TX_DRIVER_260MV 6 -+#define PSGMII_QSGMII_TX_DRIVER_280MV 7 -+#define PSGMII_QSGMII_TX_DRIVER_300MV 8 -+#define PSGMII_QSGMII_TX_DRIVER_320MV 9 -+#define PSGMII_QSGMII_TX_DRIVER_400MV 10 -+#define PSGMII_QSGMII_TX_DRIVER_500MV 11 -+/* Default value */ -+#define PSGMII_QSGMII_TX_DRIVER_600MV 12 -+ -+/* Full amplitude, full bias current */ -+#define QCA807X_CONTROL_DAC_FULL_VOLT_BIAS 0 -+/* Amplitude follow DSP (amplitude is adjusted based on cable length), half bias current */ -+#define QCA807X_CONTROL_DAC_DSP_VOLT_HALF_BIAS 1 -+/* Full amplitude, bias current follow DSP (bias current is adjusted based on cable length) */ -+#define QCA807X_CONTROL_DAC_FULL_VOLT_DSP_BIAS 2 -+/* Both amplitude and bias current follow DSP */ -+#define QCA807X_CONTROL_DAC_DSP_VOLT_BIAS 3 -+/* Full amplitude, half bias current */ -+#define QCA807X_CONTROL_DAC_FULL_VOLT_HALF_BIAS 4 -+/* Amplitude follow DSP setting; 1/4 bias current when cable<10m, -+ * otherwise half bias current -+ */ -+#define QCA807X_CONTROL_DAC_DSP_VOLT_QUARTER_BIAS 5 -+/* Full amplitude; same bias current setting with “010” and “011”, -+ * but half more bias is reduced when cable <10m -+ */ -+#define QCA807X_CONTROL_DAC_FULL_VOLT_HALF_BIAS_SHORT 6 -+/* Amplitude follow DSP; same bias current setting with “110”, default value */ -+#define QCA807X_CONTROL_DAC_DSP_VOLT_HALF_BIAS_SHORT 7 -+ -+#endif diff --git a/target/linux/ipq40xx/patches-6.1/709-ARM-dts-qcom-ipq4019-add-QCA8075-PHY-Package-nodes.patch b/target/linux/ipq40xx/patches-6.1/709-ARM-dts-qcom-ipq4019-add-QCA8075-PHY-Package-nodes.patch new file mode 100644 index 0000000000..e8b89647ce --- /dev/null +++ b/target/linux/ipq40xx/patches-6.1/709-ARM-dts-qcom-ipq4019-add-QCA8075-PHY-Package-nodes.patch @@ -0,0 +1,67 @@ +From 5ac078c8fe18f3e8318547b8ed0ed782730c5039 Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Sat, 10 Feb 2024 22:28:27 +0100 +Subject: [PATCH] ARM: dts: qcom: ipq4019: add QCA8075 PHY Package nodes + +Add QCA8075 PHY Package nodes. The PHY nodes that were previously +defined never worked and actually never had a driver to correctly setup +these PHY. Now that we have a correct driver, correctly add the PHY +Package node and set the default value of 300mw for tx driver strength +following specification of ipq4019 SoC. + +Signed-off-by: Christian Marangi +--- + arch/arm/boot/dts//qcom-ipq4019.dtsi | 35 +++++++++++++++--------- + 1 file changed, 22 insertions(+), 13 deletions(-) + +--- a/arch/arm/boot/dts/qcom-ipq4019.dtsi ++++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi +@@ -725,24 +725,33 @@ + reg = <0x90000 0x64>; + status = "disabled"; + +- ethphy0: ethernet-phy@0 { ++ ethernet-phy-package@0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "qcom,qca8075-package"; + reg = <0>; +- }; +- +- ethphy1: ethernet-phy@1 { +- reg = <1>; +- }; + +- ethphy2: ethernet-phy@2 { +- reg = <2>; +- }; +- +- ethphy3: ethernet-phy@3 { +- reg = <3>; +- }; ++ qcom,tx-drive-strength-milliwatt = <300>; + +- ethphy4: ethernet-phy@4 { +- reg = <4>; ++ ethphy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ ++ ethphy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ ++ ethphy2: ethernet-phy@2 { ++ reg = <2>; ++ }; ++ ++ ethphy3: ethernet-phy@3 { ++ reg = <3>; ++ }; ++ ++ ethphy4: ethernet-phy@4 { ++ reg = <4>; ++ }; + }; + }; + diff --git a/target/linux/ipq40xx/patches-6.1/709-net-phy-Add-Qualcom-QCA807x-driver.patch b/target/linux/ipq40xx/patches-6.1/709-net-phy-Add-Qualcom-QCA807x-driver.patch deleted file mode 100644 index 80b066c31c..0000000000 --- a/target/linux/ipq40xx/patches-6.1/709-net-phy-Add-Qualcom-QCA807x-driver.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 876bb5b69c1e083be526c0ea261982d5eb78556f Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 9 Sep 2022 23:44:42 +0200 -Subject: [PATCH] net: phy: Add Qualcom QCA807x driver - -This adds driver for the Qualcomm QCA8072 and QCA8075 PHY-s. - -They are 2 or 5 port IEEE 802.3 clause 22 compliant 10BASE-Te, 100BASE-TX and 1000BASE-T PHY-s. - -They feature 2 SerDes, one for PSGMII or QSGMII connection with MAC, while second one is SGMII for connection to MAC or fiber. - -Both models have a combo port that supports 1000BASE-X and 100BASE-FX fiber. - -Each PHY inside of QCA807x series has 4 digitally controlled output only pins that natively drive LED-s. -But some vendors used these to driver generic LED-s controlled by userspace, -so lets enable registering each PHY as GPIO controller and add driver for it. - -These are commonly used in Qualcomm IPQ40xx, IPQ60xx and IPQ807x boards. - -Signed-off-by: Robert Marko ---- - drivers/net/phy/Kconfig | 7 +++++++ - drivers/net/phy/Makefile | 1 + - 2 files changed, 8 insertions(+) - ---- a/drivers/net/phy/qcom/Kconfig -+++ b/drivers/net/phy/qcom/Kconfig -@@ -15,6 +15,13 @@ config QCA83XX_PHY - help - Currently supports the internal QCA8337(Internal qca8k PHY) model - -+config QCA807X_PHY -+ tristate "Qualcomm QCA807x PHYs" -+ depends on OF_MDIO -+ help -+ Currently supports the Qualcomm QCA8072, QCA8075 and the PSGMII -+ control PHY. -+ - config QCA808X_PHY - tristate "Qualcomm QCA808x PHYs" - select QCOM_NET_PHYLIB ---- a/drivers/net/phy/qcom/Makefile -+++ b/drivers/net/phy/qcom/Makefile -@@ -2,4 +2,5 @@ - obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o - obj-$(CONFIG_AT803X_PHY) += at803x.o - obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o -+obj-$(CONFIG_QCA807X_PHY) += qca807x.o - obj-$(CONFIG_QCA808X_PHY) += qca808x.o diff --git a/target/linux/ipq40xx/patches-6.1/710-arm-dts-ipq4019-QCA807x-properties.patch b/target/linux/ipq40xx/patches-6.1/710-arm-dts-ipq4019-QCA807x-properties.patch index 92fb8a6a02..a9ba70ff2f 100644 --- a/target/linux/ipq40xx/patches-6.1/710-arm-dts-ipq4019-QCA807x-properties.patch +++ b/target/linux/ipq40xx/patches-6.1/710-arm-dts-ipq4019-QCA807x-properties.patch @@ -12,50 +12,14 @@ Signed-off-by: Robert Marko --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - / { - #address-cells = <1>; -@@ -727,22 +728,38 @@ - - ethphy0: ethernet-phy@0 { - reg = <0>; +@@ -752,6 +752,10 @@ + ethphy4: ethernet-phy@4 { + reg = <4>; + }; + -+ qcom,control-dac = ; - }; - - ethphy1: ethernet-phy@1 { - reg = <1>; -+ -+ qcom,control-dac = ; - }; - - ethphy2: ethernet-phy@2 { - reg = <2>; -+ -+ qcom,control-dac = ; - }; - - ethphy3: ethernet-phy@3 { - reg = <3>; -+ -+ qcom,control-dac = ; - }; - - ethphy4: ethernet-phy@4 { - reg = <4>; -+ -+ qcom,control-dac = ; -+ }; -+ -+ psgmiiphy: psgmii-phy@5 { -+ reg = <5>; -+ -+ qcom,tx-driver-strength = ; ++ psgmiiphy: psgmii-phy@5 { ++ reg = <5>; ++ }; }; }; From 8d7f747757a27c6f254ac08336980161c6a96062 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 01:07:18 +0100 Subject: [PATCH 43/50] qca-ssdk: disable Malibu PHY in favor of upstream version Disable Malibu PHY driver in Qca SSDK in favor of the upstream version. The same workaround are applied and the version upstream is just a drop in replacement and is well tested from the ipq40xx target. Also using the upstream version permits further support for LEDs. Signed-off-by: Christian Marangi --- package/kernel/qca-ssdk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/kernel/qca-ssdk/Makefile b/package/kernel/qca-ssdk/Makefile index 7eccdaa1d7..f1fb09c52a 100644 --- a/package/kernel/qca-ssdk/Makefile +++ b/package/kernel/qca-ssdk/Makefile @@ -46,7 +46,7 @@ MAKE_FLAGS+= \ SoC=$(CONFIG_TARGET_SUBTARGET) \ PTP_FEATURE=disable SWCONFIG_FEATURE=disable \ ISISC_ENABLE=disable IN_QCA803X_PHY=FALSE \ - IN_QCA808X_PHY=FALSE \ + IN_QCA808X_PHY=FALSE IN_MALIBU_PHY=FALSE \ $(LNX_CONFIG_OPTS) ifeq ($(CONFIG_TARGET_SUBTARGET), "ipq807x") From a627e13d12dd74ffadf689b4b70630e16624577d Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 01:08:37 +0100 Subject: [PATCH 44/50] qualcommax: enable qca807x PHY driver IPQ807x have integrated qca8074 PHY supported by the upstream qca807x driver. Enable it to use it instead of the downstream qca SSDK variant. Signed-off-by: Christian Marangi --- target/linux/qualcommax/config-6.1 | 1 + 1 file changed, 1 insertion(+) diff --git a/target/linux/qualcommax/config-6.1 b/target/linux/qualcommax/config-6.1 index a336d3df05..35275ff0ce 100644 --- a/target/linux/qualcommax/config-6.1 +++ b/target/linux/qualcommax/config-6.1 @@ -355,6 +355,7 @@ CONFIG_POWER_SUPPLY=y CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_QCA807X_PHY=y CONFIG_QCA808X_PHY=y # CONFIG_QCM_DISPCC_2290 is not set # CONFIG_QCM_GCC_2290 is not set From c8aded65c12abd527f88e71cd7e386cdbd07b8eb Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 01:04:06 +0100 Subject: [PATCH 45/50] qca-ssdk: add patch to support detection of PSGMII mode for PHY If a PHY doesn't use the integrated driver, SSDK use poll the phydev to get the real PHY mode. qca807x use PSGMII as PHY mode and this specific mode is not detected in qca SSDK while used in the entire driver. Add support for it in the hsl_port_phydev_interface_mode_status_get function used to translate PHY mode to the internal SSDK value. Signed-off-by: Christian Marangi --- ...upport-for-detection-PSGMII-PHY-mode.patch | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch diff --git a/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch b/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch new file mode 100644 index 0000000000..c27902c4ce --- /dev/null +++ b/package/kernel/qca-ssdk/patches/101-hsl_phy-add-support-for-detection-PSGMII-PHY-mode.patch @@ -0,0 +1,25 @@ +From e3763fd77e41b2f2495672c6a5898d69892fbf9f Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 15 Nov 2023 00:57:41 +0100 +Subject: [PATCH] hsl_phy: add support for detection PSGMII PHY mode + +Add support for detection of PSGMII PHY mode to correctly detect qca807x +PHY upstream driver. + +Signed-off-by: Christian Marangi +--- + src/hsl/phy/hsl_phy.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/src/hsl/phy/hsl_phy.c ++++ b/src/hsl/phy/hsl_phy.c +@@ -1335,6 +1335,9 @@ hsl_port_phydev_interface_mode_status_ge + case PHY_INTERFACE_MODE_10GKR: + *interface_mode_status = PORT_10GBASE_R; + break; ++ case PHY_INTERFACE_MODE_PSGMII: ++ *interface_mode_status = PHY_PSGMII_BASET; ++ break; + case PHY_INTERFACE_MODE_QSGMII: + *interface_mode_status = PORT_QSGMII; + break; From 8ed390ac768606c0072602701c0723debb54282f Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 00:59:59 +0100 Subject: [PATCH 46/50] qualcommax: set correct PHY mode for port 0-4 Port 0-4 have the mode set to SGMII instead of PSGMII. Now that we use the upstream qca807x driver, this conflicts with the qca SSDK driver that expects the mode to be PSGMII as for not integrated driver, it does refer to the real PHY mode. Update the entry for port 0-4 to PSGMII to solve warning from qca SSDK in ipq8074-ess.dtsi. Signed-off-by: Christian Marangi --- .../files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi index d3f4211ecf..a1e2d01e8f 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi @@ -476,7 +476,7 @@ reg = <0x3a001000 0x200>; qcom,mactype = <0>; local-mac-address = [000000000000]; - phy-mode = "sgmii"; + phy-mode = "psgmii"; status = "disabled"; }; @@ -487,7 +487,7 @@ reg = <0x3a001200 0x200>; qcom,mactype = <0>; local-mac-address = [000000000000]; - phy-mode = "sgmii"; + phy-mode = "psgmii"; status = "disabled"; }; @@ -498,7 +498,7 @@ reg = <0x3a001400 0x200>; qcom,mactype = <0>; local-mac-address = [000000000000]; - phy-mode = "sgmii"; + phy-mode = "psgmii"; status = "disabled"; }; @@ -509,7 +509,7 @@ reg = <0x3a001600 0x200>; qcom,mactype = <0>; local-mac-address = [000000000000]; - phy-mode = "sgmii"; + phy-mode = "psgmii"; status = "disabled"; }; From 0ab4b9201e44f244383b7b77d6032b400c75ecb5 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 17 Nov 2023 17:52:42 +0100 Subject: [PATCH 47/50] qualcommax: convert qca807x PHY to PHY package implementation Convert every qca807x PHY definition in DT to new PHY package implementation to correctly support applying fixup for the correct PHY mode. Signed-off-by: Christian Marangi --- .../arm64/boot/dts/qcom/ipq8070-cax1800.dts | 15 ++++-- .../arm64/boot/dts/qcom/ipq8071-ax3600.dtsi | 37 ++++++++------ .../arch/arm64/boot/dts/qcom/ipq8072-301w.dts | 41 ++++++++++----- .../arm64/boot/dts/qcom/ipq8072-ax9000.dts | 41 ++++++++++----- .../arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts | 41 ++++++++++----- .../arch/arm64/boot/dts/qcom/ipq8072-haze.dts | 43 +++++++++------- .../arm64/boot/dts/qcom/ipq8072-wpq873.dts | 29 +++++++---- .../arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi | 2 +- .../arm64/boot/dts/qcom/ipq8074-nbg7815.dts | 51 +++++++++++-------- .../arm64/boot/dts/qcom/ipq8074-rax120v2.dts | 44 +++++++++------- .../arm64/boot/dts/qcom/ipq8074-wax630.dts | 15 ++++-- .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts | 35 ++++++++----- 12 files changed, 247 insertions(+), 147 deletions(-) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts index 0ca2edcb2c..e62ae314fb 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts @@ -262,9 +262,16 @@ reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075: ethernet-phy@4 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <4>; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; + reg = <0>; + + qca8075_4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + }; }; }; @@ -288,7 +295,7 @@ &dp5 { status = "okay"; - phy-handle = <&qca8075>; + phy-handle = <&qca8075_4>; label = "lan"; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi index 2bb2cce157..6afafb3554 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi @@ -213,24 +213,31 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; + reg = <0>; - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; - }; + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; - qca8075_4: ethernet-phy@4 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <4>; + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; + + qca8075_4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + }; }; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts index 497a18714a..4dcacdf297 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts @@ -366,24 +366,33 @@ nvmem-cells = <&aqr1_fw>; }; - qca8075_16: ethernet-phy@16 { - compatible = "ethernet-phy-ieee802.3-c22"; + ethernet-phy-package@16 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; reg = <16>; - }; - qca8075_17: ethernet-phy@17 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <17>; - }; + qcom,package-mode = "qsgmii"; - qca8075_18: ethernet-phy@18 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <18>; - }; + qca8075_16: ethernet-phy@16 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <16>; + }; - qca8075_19: ethernet-phy@19 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <19>; + qca8075_17: ethernet-phy@17 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <17>; + }; + + qca8075_18: ethernet-phy@18 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <18>; + }; + + qca8075_19: ethernet-phy@19 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <19>; + }; }; }; @@ -448,24 +457,28 @@ &dp1 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_16>; label = "lan4"; }; &dp2 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_17>; label = "lan3"; }; &dp3 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_18>; label = "lan2"; }; &dp4 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_19>; label = "lan1"; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts index d6be71b8cf..c0c21f6d79 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts @@ -347,24 +347,33 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075_0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; reg = <0>; - }; - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; + qcom,package-mode = "qsgmii"; - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; + qca8075_0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; }; qca8081: ethernet-phy@24 { @@ -426,6 +435,7 @@ &dp1 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_0>; label = "lan4"; nvmem-cells = <&macaddr_dp1>; @@ -434,6 +444,7 @@ &dp2 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_1>; label = "lan3"; nvmem-cells = <&macaddr_dp2>; @@ -442,6 +453,7 @@ &dp3 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_2>; label = "lan2"; nvmem-cells = <&macaddr_dp3>; @@ -450,6 +462,7 @@ &dp4 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_3>; label = "lan1"; nvmem-cells = <&macaddr_dp4>; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts index 66a14232d7..c5c089c00f 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts @@ -137,24 +137,33 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075_0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; reg = <0>; - }; - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; + qcom,package-mode = "qsgmii"; - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; + qca8075_0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; }; qca8081: ethernet-phy@28 { @@ -223,24 +232,28 @@ &dp1 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_0>; label = "lan4"; }; &dp2 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_1>; label = "lan3"; }; &dp3 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_2>; label = "lan2"; }; &dp4 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_3>; label = "lan1"; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts index 8fdfe981f9..70cc2921c7 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts @@ -161,24 +161,31 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 22 GPIO_ACTIVE_LOW>; - qca8075_1: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; reg = <0>; - }; - qca8075_2: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; + qca8075_0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; - qca8075_3: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; - qca8075_4: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; }; aqr113c: ethernet-phy@5 { @@ -236,25 +243,25 @@ /* Dummy LAN port */ &dp1 { status = "disabled"; - phy-handle = <&qca8075_1>; + phy-handle = <&qca8075_0>; label = "lan4"; }; &dp2 { status = "okay"; - phy-handle = <&qca8075_2>; + phy-handle = <&qca8075_1>; label = "lan3"; }; &dp3 { status = "okay"; - phy-handle = <&qca8075_3>; + phy-handle = <&qca8075_2>; label = "lan2"; }; &dp4 { status = "okay"; - phy-handle = <&qca8075_4>; + phy-handle = <&qca8075_3>; label = "lan1"; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts index e4bd72c532..7d7f54ea62 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-wpq873.dts @@ -357,19 +357,26 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; + reg = <0>; - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; }; qca8081: ethernet-phy@28 { diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi index a1e2d01e8f..6f98e01b9a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi @@ -520,7 +520,7 @@ reg = <0x3a001800 0x200>; qcom,mactype = <0>; local-mac-address = [000000000000]; - phy-mode = "sgmii"; + phy-mode = "psgmii"; status = "disabled"; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts index be6953f942..5d7d84ac52 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts @@ -271,27 +271,34 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075_1: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; reg = <0>; + + qca8075_0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; }; - qca8075_2: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; - - qca8075_3: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; - - qca8075_4: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; - }; - - qca8081: ethernet-phy@4{ + qca8081: ethernet-phy@28 { compatible = "ethernet-phy-id004d.d101"; reg = <28>; reset-deassert-us = <10000>; @@ -358,7 +365,7 @@ &dp1 { status = "okay"; - phy-handle = <&qca8075_1>; + phy-handle = <&qca8075_0>; label = "lan1"; nvmem-cells = <&macaddr_lan 0>; nvmem-cell-names = "mac-address"; @@ -366,7 +373,7 @@ &dp2 { status = "okay"; - phy-handle = <&qca8075_2>; + phy-handle = <&qca8075_1>; label = "lan2"; nvmem-cells = <&macaddr_lan 0>; nvmem-cell-names = "mac-address"; @@ -374,7 +381,7 @@ &dp3 { status = "okay"; - phy-handle = <&qca8075_3>; + phy-handle = <&qca8075_2>; label = "lan3"; nvmem-cells = <&macaddr_lan 0>; nvmem-cell-names = "mac-address"; @@ -382,7 +389,7 @@ &dp4 { status = "okay"; - phy-handle = <&qca8075_4>; + phy-handle = <&qca8075_3>; label = "lan4"; nvmem-cells = <&macaddr_lan 0>; nvmem-cell-names = "mac-address"; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts index 39e0cfabf7..5b9a45e961 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-rax120v2.dts @@ -150,29 +150,37 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075_0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; reg = <0>; - }; - qca8075_1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; + compatible = "qcom,qca8075-package"; - qca8075_2: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <2>; - }; + qca8075_0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; - qca8075_3: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; - }; + qca8075_1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; - qca8075_4: ethernet-phy@4 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <4>; + qca8075_2: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + }; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; + + qca8075_4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + }; }; aqr111b0: ethernet-phy@7 { diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts index 48b1fee1ea..91561e5c2a 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wax630.dts @@ -194,9 +194,16 @@ pinctrl-names = "default"; reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; - qca8075: ethernet-phy@3 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <3>; + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; + reg = <0>; + + qca8075_3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <3>; + }; }; qca8081: ethernet-phy@28 { @@ -209,7 +216,7 @@ &dp4 { status = "okay"; - phy-handle = <&qca8075>; + phy-handle = <&qca8075_3>; label = "lan2"; }; diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts index cc6eafe532..a0631b3b71 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts @@ -230,19 +230,28 @@ reg = <0x8>; }; - qca8075_1: ethernet-phy@19 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x19>; - }; + ethernet-phy-package@17 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; + reg = <0x18>; - qca8075_2: ethernet-phy@1a { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x1a>; - }; + qcom,package-mode = "qsgmii"; - qca8075_3: ethernet-phy@1b { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x1b>; + qca8075_1: ethernet-phy@19 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x19>; + }; + + qca8075_2: ethernet-phy@1a { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1a>; + }; + + qca8075_3: ethernet-phy@1b { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1b>; + }; }; }; @@ -251,7 +260,6 @@ switch_lan_bmp = <(ESS_PORT2 | ESS_PORT3 | ESS_PORT4 | ESS_PORT6)>; switch_wan_bmp = ; - malibu_first_phy_addr = <0x18>; switch_mac_mode = ; switch_mac_mode1 = ; switch_mac_mode2 = ; @@ -292,6 +300,7 @@ &dp2 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_1>; label = "lan4"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; @@ -300,6 +309,7 @@ &dp3 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_2>; label = "lan3"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; @@ -308,6 +318,7 @@ &dp4 { status = "okay"; + phy-mode = "qsgmii"; phy-handle = <&qca8075_3>; label = "lan2"; nvmem-cells = <&macaddr_appsblenv_ethaddr>; From 4d7b1f92a488cb37aa7005f6856340833520eb1d Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 01:35:04 +0100 Subject: [PATCH 48/50] qualcommax: apply special PHY LEDs configuration for Xiaomi AX3600 Xiaomi AX3600 apply a special PHY LEDs configuration where the unique green LED for each qca807x PHY port is turned on also on 1000Mbps link. Apply this special configuration to reflect original implementation. Also enable CONFIG_PHYLIB_LEDS to actually expose the PHY LEDs if defined in DT. Signed-off-by: Christian Marangi --- .../arm64/boot/dts/qcom/ipq8071-ax3600.dts | 57 +++++++++++++++++++ .../ipq807x/base-files/etc/board.d/01_leds | 8 ++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts index f3e82e2251..c6889df25d 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts @@ -4,6 +4,7 @@ /dts-v1/; #include "ipq8071-ax3600.dtsi" +#include / { model = "Xiaomi AX3600"; @@ -71,3 +72,59 @@ &wifi { qcom,ath11k-calibration-variant = "Xiaomi-AX3600"; }; + +&qca8075_1 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_WAN; + default-state = "keep"; + }; + }; +}; + +&qca8075_2 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; +}; + +&qca8075_3 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; +}; + +&qca8075_4 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; +}; diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds index f3e67311c3..fc965bc445 100644 --- a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds +++ b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds @@ -32,8 +32,14 @@ netgear,wax630) ucidef_set_led_netdev "lan1" "LAN1" "lan1:green" "lan1" ucidef_set_led_netdev "lan2" "LAN2" "lan2:green" "lan2" ;; -redmi,ax6|\ +redmi,ax6) + ucidef_set_led_netdev "wan" "WAN" "blue:network" "wan" + ;; xiaomi,ax3600) + ucidef_set_led_netdev "wan-port-link" "WAN-PORT-LINK" "90000.mdio-1:01:green:wan" "wan" "tx rx link_10 link_100 link_1000" + ucidef_set_led_netdev "lan1-port-link" "LAN1-PORT-LINK" "90000.mdio-1:02:green:lan" "lan1" "tx rx link_10 link_100 link_1000" + ucidef_set_led_netdev "lan2-port-link" "LAN2-PORT-LINK" "90000.mdio-1:03:green:lan" "lan2" "tx rx link_10 link_100 link_1000" + ucidef_set_led_netdev "lan3-port-link" "LAN3-PORT-LINK" "90000.mdio-1:04:green:lan" "lan3" "tx rx link_10 link_100 link_1000" ucidef_set_led_netdev "wan" "WAN" "blue:network" "wan" ;; xiaomi,ax9000) From e4f438b9ddd45413f2f1320fb79d19c6378bd16c Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 01:31:14 +0100 Subject: [PATCH 49/50] qualcommax: apply special PHY LEDs configuration for Xiaomi AX9000 Xiaomi AX9000 apply a special PHY LEDs configuration where the unique green LED for each qca807x PHY port is turned on also on 1000Mbps link. Apply this special configuration to reflect original implementation. Signed-off-by: Christian Marangi --- .../arm64/boot/dts/qcom/ipq8072-ax9000.dts | 48 +++++++++++++++++++ .../ipq807x/base-files/etc/board.d/01_leds | 4 ++ 2 files changed, 52 insertions(+) diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts index c0c21f6d79..805a2fc0bc 100644 --- a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts @@ -358,21 +358,69 @@ qca8075_0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; }; qca8075_1: ethernet-phy@1 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; }; qca8075_2: ethernet-phy@2 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <2>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; }; qca8075_3: ethernet-phy@3 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <3>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; }; }; diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds index fc965bc445..8bf1ea8fa2 100644 --- a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds +++ b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/01_leds @@ -44,6 +44,10 @@ xiaomi,ax3600) ;; xiaomi,ax9000) ucidef_set_led_netdev "wan-port-link" "WAN-PORT-LINK" "90000.mdio-1:18:green:wan" "wan" "tx rx link_10 link_100 link_1000 link_2500" + ucidef_set_led_netdev "lan1-port-link" "LAN1-PORT-LINK" "90000.mdio-1:03:green:lan" "lan1" "tx rx link_10 link_100 link_1000" + ucidef_set_led_netdev "lan2-port-link" "LAN2-PORT-LINK" "90000.mdio-1:02:green:lan" "lan2" "tx rx link_10 link_100 link_1000" + ucidef_set_led_netdev "lan3-port-link" "LAN3-PORT-LINK" "90000.mdio-1:01:green:lan" "lan3" "tx rx link_10 link_100 link_1000" + ucidef_set_led_netdev "lan4-port-link" "LAN4-PORT-LINK" "90000.mdio-1:00:green:lan" "lan4" "tx rx link_10 link_100 link_1000" ;; qnap,301w) ucidef_set_led_netdev "lan1" "LAN1" "green:lan1" "lan1" From dfc1e8cfeea51106b988cd2a924644976ad01fe7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Wed, 15 Nov 2023 01:36:35 +0100 Subject: [PATCH 50/50] qca-ssdk: drop deprecated Xiaomi LEDs quirk patch Drop deprecated Xiaomi LEDs quirk patches as they are not needed anymore as LEDs are now supported by the upstream qca807x driver. Signed-off-by: Christian Marangi --- ...7x-add-a-LED-quirk-for-Xiaomi-AX9000.patch | 65 ------------------- ...7x-add-a-LED-quirk-for-Xiaomi-AX3600.patch | 29 --------- 2 files changed, 94 deletions(-) delete mode 100644 package/kernel/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch delete mode 100644 package/kernel/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch diff --git a/package/kernel/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch b/package/kernel/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch deleted file mode 100644 index c627c82898..0000000000 --- a/package/kernel/qca-ssdk/patches/0001-qca807x-add-a-LED-quirk-for-Xiaomi-AX9000.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 1d37f4ee9b9588a62bfc87419c8a6d9ef989aa9c Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 7 Nov 2023 12:23:09 +0100 -Subject: [PATCH 1/3] qca807x: add a LED quirk for Xiaomi AX9000 - -Xiaomi AX9000 has a single LED for each of 4 gigabit ethernet ports that -are connected to QCA8075, and that LED is connected to the 100M LED pin. - -So, by default it will only work when in 10 or 100Mbit mode, this is quite -annoying and makes no sense(If they have connected it to the 1000Mbit LED -pin then it would have worked for 10/100 by default as well). - -So, to solve this add a check for system compatible as we cant parse if -from DTS in any other way and set the 100M LED to blink on 1000Base-T -as well. - -Signed-off-by: Robert Marko ---- - include/hsl/phy/malibu_phy.h | 2 ++ - src/hsl/phy/malibu_phy.c | 9 +++++++++ - 2 files changed, 11 insertions(+) - ---- a/include/hsl/phy/malibu_phy.h -+++ b/include/hsl/phy/malibu_phy.h -@@ -94,6 +94,7 @@ extern "C" - #define MALIBU_DAC_CTRL_MASK 0x380 - #define MALIBU_DAC_CTRL_VALUE 0x280 - #define MALIBU_LED_1000_CTRL1_100_10_MASK 0x30 -+#define MALIBU_LED_100_CTRL1_1000_MASK 0x40 - - #define MALIBU_PHY_EEE_ADV_100M 0x0002 - #define MALIBU_PHY_EEE_ADV_1000M 0x0004 -@@ -118,6 +119,7 @@ extern "C" - #define MALIBU_PHY_MMD7_EGRESS_COUNTER_HIGH 0x802d - #define MALIBU_PHY_MMD7_EGRESS_COUNTER_LOW 0x802e - #define MALIBU_PHY_MMD7_EGRESS_ERROR_COUNTER 0x802f -+#define MALIBU_PHY_MMD7_LED_100_CTRL1 0x8074 - #define MALIBU_PHY_MMD7_LED_1000_CTRL1 0x8076 - - ---- a/src/hsl/phy/malibu_phy.c -+++ b/src/hsl/phy/malibu_phy.c -@@ -15,6 +15,8 @@ - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -+#include -+ - #include "sw.h" - #include "fal_port_ctrl.h" - #include "hsl_api.h" -@@ -1809,6 +1811,13 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_ - hsl_phy_modify_mmd(dev_id, phy_addr, A_FALSE, MALIBU_PHY_MMD7_NUM, - MALIBU_PHY_MMD7_LED_1000_CTRL1, MALIBU_LED_1000_CTRL1_100_10_MASK, - MALIBU_LED_1000_CTRL1_100_10_MASK); -+ if (of_machine_is_compatible("xiaomi,ax9000")) { -+ /* add 1000M link LED behavior for Xiaomi AX9000 */ -+ hsl_phy_modify_mmd(dev_id, phy_addr, A_FALSE, MALIBU_PHY_MMD7_NUM, -+ MALIBU_PHY_MMD7_LED_100_CTRL1, -+ MALIBU_LED_100_CTRL1_1000_MASK, -+ MALIBU_LED_100_CTRL1_1000_MASK); -+ } - /*disable Extended next page*/ - hsl_phy_modify_mii(dev_id, phy_addr, MALIBU_AUTONEG_ADVERT, - MALIBU_EXTENDED_NEXT_PAGE_EN, 0); diff --git a/package/kernel/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch b/package/kernel/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch deleted file mode 100644 index cfbb6cc771..0000000000 --- a/package/kernel/qca-ssdk/patches/0002-qca807x-add-a-LED-quirk-for-Xiaomi-AX3600.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 957ee476ddec289973e0af07917da7bfee660af0 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 7 Nov 2023 12:24:17 +0100 -Subject: [PATCH 2/3] qca807x: add a LED quirk for Xiaomi AX3600 - -AX3600 requires the same LED quirk so that PHY LED-s will blink even -once Linux resets the PHY. - -So, just check for its compatible. - -Signed-off-by: Robert Marko ---- - src/hsl/phy/malibu_phy.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/src/hsl/phy/malibu_phy.c -+++ b/src/hsl/phy/malibu_phy.c -@@ -1811,8 +1811,9 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_ - hsl_phy_modify_mmd(dev_id, phy_addr, A_FALSE, MALIBU_PHY_MMD7_NUM, - MALIBU_PHY_MMD7_LED_1000_CTRL1, MALIBU_LED_1000_CTRL1_100_10_MASK, - MALIBU_LED_1000_CTRL1_100_10_MASK); -- if (of_machine_is_compatible("xiaomi,ax9000")) { -- /* add 1000M link LED behavior for Xiaomi AX9000 */ -+ if (of_machine_is_compatible("xiaomi,ax9000") || -+ of_machine_is_compatible("xiaomi,ax3600")) { -+ /* add 1000M link LED behavior for Xiaomi boards */ - hsl_phy_modify_mmd(dev_id, phy_addr, A_FALSE, MALIBU_PHY_MMD7_NUM, - MALIBU_PHY_MMD7_LED_100_CTRL1, - MALIBU_LED_100_CTRL1_1000_MASK,