Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2025-11-12 21:36:37 +08:00
commit 2048a2e8ac
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
51 changed files with 3049 additions and 1281 deletions

View File

@ -3,6 +3,7 @@
# Copyright (C) 2022-2023 Enéas Ulir de Queiroz
ENGINES_DIR=engines-3
MODULES_DIR=ossl-modules
define Package/openssl/module/Default
SECTION:=libs
@ -74,6 +75,6 @@ endef
# 1 = provider name
# 2 = [ package name, defaults to libopenssl-$(1) ]
define Package/openssl/add-provider
$(call Package/openssl/add-module,provider,$(1),/usr/lib/ossl-modules,$(2))
$(call Package/openssl/add-module,provider,$(1),/usr/lib/$(MODULES_DIR),$(2))
endef

View File

@ -187,6 +187,7 @@ $(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \
perl --version | grep "perl.*v5"))
$(eval $(call SetupHostCommand,python,Please install Python >= 3.7, \
python3.13 -V 2>&1 | grep 'Python 3', \
python3.12 -V 2>&1 | grep 'Python 3', \
python3.11 -V 2>&1 | grep 'Python 3', \
python3.10 -V 2>&1 | grep 'Python 3', \
@ -196,6 +197,7 @@ $(eval $(call SetupHostCommand,python,Please install Python >= 3.7, \
python3 -V 2>&1 | grep -E 'Python 3\.([7-9]|[0-9][0-9])\.?'))
$(eval $(call SetupHostCommand,python3,Please install Python >= 3.7, \
python3.13 -V 2>&1 | grep 'Python 3', \
python3.12 -V 2>&1 | grep 'Python 3', \
python3.11 -V 2>&1 | grep 'Python 3', \
python3.10 -V 2>&1 | grep 'Python 3', \

View File

@ -8,6 +8,7 @@ touch /etc/config/ubootenv
board=$(board_name)
case "$board" in
cmcc,pz-l8|\
elecom,wrc-x3000gs2|\
iodata,wn-dax3000gr)
ubootenv_add_mtd "0:appsblenv" "0x0" "0x40000" "0x20000"

View File

@ -288,8 +288,11 @@ function setup() {
wdev_data[v.config.ifname] = config;
}
supplicant.setup(supplicant_data, data);
hostapd.setup(data);
if (fs.access('/usr/sbin/wpa_supplicant', 'x'))
supplicant.setup(supplicant_data, data);
if (fs.access('/usr/sbin/hostapd', 'x'))
hostapd.setup(data);
system(`ucode /usr/share/hostap/wdev.uc ${data.phy}${data.phy_suffix} set_config '${printf("%J", wdev_data)}' ${join(' ', active_ifnames)}`);

View File

@ -385,6 +385,11 @@ function device_htmode_append(config) {
config.he_oper_centr_freq_seg0_idx = config.vht_oper_centr_freq_seg0_idx;
}
if (config.band == "6g") {
config.stationary_ap = true;
append_vars(config, [ 'he_6ghz_reg_pwr_type', ]);
}
if (config.he_bss_color_enabled) {
if (config.he_spr_non_srg_obss_pd_max_offset)
config.he_spr_sr_control |= 1 << 2;
@ -425,11 +430,6 @@ function device_htmode_append(config) {
if (config.hw_mode == 'a')
append_vars(config, [ 'eht_oper_chwidth', 'eht_oper_centr_freq_seg0_idx' ]);
if (config.band == "6g") {
config.stationary_ap = true;
append_vars(config, [ 'he_6ghz_reg_pwr_type', ]);
}
}
append_vars(config, [ 'tx_queue_data2_burst', 'stationary_ap' ]);
@ -571,10 +571,12 @@ export function setup(data) {
config: has_ap ? file_name : "",
prev_config: file_name + '.prev'
};
if (!global.ubus.list('hostapd'))
system('ubus wait_for hostapd');
let ret = global.ubus.call('hostapd', 'config_set', msg);
if (ret)
netifd.add_process('/usr/sbin/hostapd', ret.pid, true, true);
else if (fs.access('/usr/sbin/hostapd', 'x'))
else
netifd.setup_failed('HOSTAPD_START_FAILED');
};

View File

@ -270,6 +270,8 @@ export function generate(config_list, data, interface) {
};
export function setup(config, data) {
if (!global.ubus.list('wpa_supplicant'))
system('ubus wait_for wpa_supplicant');
let ret = global.ubus.call('wpa_supplicant', 'config_set', {
phy: data.phy,
radio: data.config.radio,
@ -281,7 +283,7 @@ export function setup(config, data) {
if (ret)
netifd.add_process('/usr/sbin/wpa_supplicant', ret.pid, true, true);
else if (fs.access('/usr/sbin/wpa_supplicant', 'x'))
else
netifd.setup_failed('SUPPLICANT_START_FAILED');
};

View File

@ -7,9 +7,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware-utils.git
PKG_SOURCE_DATE:=2025-10-01
PKG_SOURCE_VERSION:=0782d243d23e64d8420f8c067a4169eb69a55f92
PKG_MIRROR_HASH:=70496cec3110fbf602b529e42d0646b3dc26495a6bf1e436504c6d39a92f20bc
PKG_SOURCE_DATE:=2025-11-11
PKG_SOURCE_VERSION:=c42a3bc53da869d02c8ae4d62b3b08a95ff5833f
PKG_MIRROR_HASH:=c9cbe9aafc3476dac9d9bd1b26f932048f895bce775e8220f82fae097463c539
PKG_FLAGS:=nonshared
PKG_BUILD_DEPENDS:=openssl zlib

View File

@ -12,9 +12,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/jow-/ucode.git
PKG_SOURCE_DATE:=2025-09-29
PKG_SOURCE_VERSION:=1090abb125490d2f541f68453cc251daf94f8b04
PKG_MIRROR_HASH:=b68d893867add47b92d519a631c4e3bacec52eafae088b6a64ba3935f169bb15
PKG_SOURCE_DATE:=2025-11-07
PKG_SOURCE_VERSION:=ea579046a619e5325b994780bf2ce1ffde448794
PKG_MIRROR_HASH:=4c152c337963eda588650f439f7633fc1ead20864d8939e45fd95563ea2b0b4f
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_LICENSE:=ISC

View File

@ -1,29 +0,0 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Sun, 5 Oct 2025 11:25:15 +0200
Subject: [PATCH] lexer: fix parsing \xHH and \0OOO escape sequences
Both need to add add bytes, not UTF-8 sequences.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/lexer.c
+++ b/lexer.c
@@ -277,7 +277,7 @@ parse_escape(uc_lexer_t *lex, const char
code = code * 16 + hex(ch);
}
- append_utf8(lex, code);
+ uc_vector_push(&lex->buffer, code);
}
/* octal or letter */
@@ -293,7 +293,7 @@ parse_escape(uc_lexer_t *lex, const char
if (code > 255)
return emit_op(lex, -3, TK_ERROR, ucv_string_new("Invalid escape sequence"));
- append_utf8(lex, code);
+ uc_vector_push(&lex->buffer, code);
}
/* ... no octal sequence, handle potential regex macros */

View File

@ -1,75 +0,0 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Wed, 8 Oct 2025 22:15:42 +0200
Subject: [PATCH] fs: add dup2() function
Add dup2() function to duplicate file descriptors, useful for redirecting
standard streams in child processes.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -1278,6 +1278,54 @@ uc_fs_fdopen(uc_vm_t *vm, size_t nargs)
return ucv_resource_create(vm, "fs.file", fp);
}
+/**
+ * Duplicates a file descriptor.
+ *
+ * This function duplicates the file descriptor `oldfd` to `newfd`. If `newfd`
+ * was previously open, it is silently closed before being reused.
+ *
+ * Returns `true` on success.
+ * Returns `null` on error.
+ *
+ * @function module:fs#dup2
+ *
+ * @param {number} oldfd
+ * The file descriptor to duplicate.
+ *
+ * @param {number} newfd
+ * The file descriptor number to duplicate to.
+ *
+ * @returns {?boolean}
+ *
+ * @example
+ * // Redirect stderr to a log file
+ * const logfile = open('/tmp/error.log', 'w');
+ * dup2(logfile.fileno(), 2);
+ * logfile.close();
+ */
+static uc_value_t *
+uc_fs_dup2(uc_vm_t *vm, size_t nargs)
+{
+ uc_value_t *oldfd_arg = uc_fn_arg(0);
+ uc_value_t *newfd_arg = uc_fn_arg(1);
+ int oldfd, newfd;
+
+ oldfd = get_fd(vm, oldfd_arg);
+
+ if (oldfd == -1)
+ err_return(errno ? errno : EBADF);
+
+ newfd = get_fd(vm, newfd_arg);
+
+ if (newfd == -1)
+ err_return(errno ? errno : EBADF);
+
+ if (dup2(oldfd, newfd) == -1)
+ err_return(errno);
+
+ return ucv_boolean_new(true);
+}
+
/**
* Represents a handle for interacting with a directory opened by `opendir()`.
@@ -2890,6 +2938,7 @@ static const uc_function_list_t global_f
{ "error", uc_fs_error },
{ "open", uc_fs_open },
{ "fdopen", uc_fs_fdopen },
+ { "dup2", uc_fs_dup2 },
{ "opendir", uc_fs_opendir },
{ "popen", uc_fs_popen },
{ "readlink", uc_fs_readlink },

View File

@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -674,6 +674,116 @@ uc_fs_read(uc_vm_t *vm, size_t nargs)
@@ -675,6 +675,116 @@ uc_fs_read(uc_vm_t *vm, size_t nargs)
}
/**
@ -127,7 +127,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
* Writes a chunk of data to the file handle.
*
* In case the given data is not a string, it is converted to a string before
@@ -2910,6 +3020,7 @@ static const uc_function_list_t proc_fns
@@ -2991,6 +3101,7 @@ static const uc_function_list_t proc_fns
static const uc_function_list_t file_fns[] = {
{ "read", uc_fs_read },

View File

@ -1,107 +0,0 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Thu, 9 Oct 2025 14:11:55 +0200
Subject: [PATCH] fs: add mkdtemp() method for creating temporary directories
Returns the directory path as a string, following the same template
handling pattern as mkstemp().
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -2636,6 +2636,86 @@ uc_fs_mkstemp(uc_vm_t *vm, size_t nargs)
}
/**
+ * Creates a unique temporary directory based on the given template.
+ *
+ * If the template argument is given and contains a relative path, the created
+ * directory will be placed relative to the current working directory.
+ *
+ * If the template argument is given and contains an absolute path, the created
+ * directory will be placed relative to the given directory.
+ *
+ * If the template argument is given but does not contain a directory separator,
+ * the directory will be placed in `/tmp/`.
+ *
+ * If no template argument is given, the default `/tmp/XXXXXX` is used.
+ *
+ * The template argument must end with six consecutive X characters (`XXXXXX`),
+ * which will be replaced with a random string to create the unique directory name.
+ * If the template does not end with `XXXXXX`, it will be automatically appended.
+ *
+ * Returns a string containing the path of the created directory on success.
+ *
+ * Returns `null` if an error occurred, e.g. on insufficient permissions or
+ * inaccessible directory.
+ *
+ * @function module:fs#mkdtemp
+ *
+ * @param {string} [template="/tmp/XXXXXX"]
+ * The path template to use when forming the temporary directory name.
+ *
+ * @returns {?string}
+ *
+ * @example
+ * // Create a unique temporary directory in the current working directory
+ * const tempDir = mkdtemp('./data-XXXXXX');
+ */
+static uc_value_t *
+uc_fs_mkdtemp(uc_vm_t *vm, size_t nargs)
+{
+ uc_value_t *template = uc_fn_arg(0);
+ bool ends_with_template = false;
+ char *path, *t, *result;
+ uc_value_t *rv;
+ size_t l;
+
+ if (template && ucv_type(template) != UC_STRING)
+ err_return(EINVAL);
+
+ t = ucv_string_get(template);
+ l = ucv_string_length(template);
+
+ ends_with_template = (l >= 6 && strcmp(&t[l - 6], "XXXXXX") == 0);
+
+ if (t && strchr(t, '/')) {
+ if (ends_with_template)
+ xasprintf(&path, "%s", t);
+ else
+ xasprintf(&path, "%s.XXXXXX", t);
+ }
+ else if (t) {
+ if (ends_with_template)
+ xasprintf(&path, "/tmp/%s", t);
+ else
+ xasprintf(&path, "/tmp/%s.XXXXXX", t);
+ }
+ else {
+ xasprintf(&path, "/tmp/XXXXXX");
+ }
+
+ result = mkdtemp(path);
+
+ if (!result) {
+ free(path);
+ err_return(errno);
+ }
+
+ rv = ucv_string_new(result);
+ free(path);
+
+ return rv;
+}
+
+/**
* Checks the accessibility of a file or directory.
*
* The optional modes argument specifies the access modes which should be
@@ -3069,6 +3149,7 @@ static const uc_function_list_t global_f
{ "basename", uc_fs_basename },
{ "lsdir", uc_fs_lsdir },
{ "mkstemp", uc_fs_mkstemp },
+ { "mkdtemp", uc_fs_mkdtemp },
{ "access", uc_fs_access },
{ "readfile", uc_fs_readfile },
{ "writefile", uc_fs_writefile },

View File

@ -128,8 +128,14 @@ sub update_index($)
-d "./feeds/$name.tmp/info" or mkdir "./feeds/$name.tmp/info" or return 1;
system("$mk -s prepare-mk OPENWRT_BUILD= TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
system("$mk -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
system("$mk -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"targetinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"target\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" SCAN_MAKEOPTS=\"TARGET_BUILD=1\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
my $is_tty = $ENV{IS_TTY};
$is_tty = defined $is_tty ? $is_tty : $ENV{MAKE_TERMOUT};
$is_tty = defined $is_tty ? $is_tty : 1;
system("$mk -s -f include/scan.mk IS_TTY=$is_tty SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
system("$mk -s -f include/scan.mk IS_TTY=$is_tty SCAN_TARGET=\"targetinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"target\" SCAN_DEPTH=5 SCAN_EXTRA=\"\" SCAN_MAKEOPTS=\"TARGET_BUILD=1\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
system("ln -sf $name.tmp/.packageinfo ./feeds/$name.index");
system("ln -sf $name.tmp/.targetinfo ./feeds/$name.targetindex");

View File

@ -194,7 +194,7 @@ ifeq ($(CONFIG_USE_APK),)
if [ -d "$(PACKAGE_DIR)" ] && ( \
[ ! -f "$(PACKAGE_DIR)/Packages" ] || \
[ ! -f "$(PACKAGE_DIR)/Packages.gz" ] || \
[ "`find $(PACKAGE_DIR) -cnewer $(PACKAGE_DIR)/Packages.gz`" ] ); then \
[ "`find $(PACKAGE_DIR) -cnewer $(PACKAGE_DIR)/Packages.gz ! -name Packages.sig`" ] ); then \
echo "Package list missing or not up-to-date, generating it." >&2 ;\
$(MAKE) package_index; \
else \

View File

@ -1,8 +1,8 @@
From e77c958d8eab1c29008ab57a2be82daefe886e0a Mon Sep 17 00:00:00 2001
From 4043b0c45f8555a079bdac69a19ed08695a47a7b Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sun, 25 May 2025 19:25:20 +0200
Subject: [PATCH 2/5] pinctrl: mediatek: airoha: generalize
pins/group/function/confs handling
Date: Fri, 7 Nov 2025 00:57:04 +0100
Subject: [PATCH 1/5] pinctrl: airoha: generalize pins/group/function/confs
handling
In preparation for support of Airoha AN7583, generalize
pins/group/function/confs handling and move them in match_data.
@ -12,9 +12,10 @@ relying on hardcoded struct.
This permits to use different PIN data while keeping the same logic.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mediatek/pinctrl-airoha.c | 569 ++++++++++++----------
1 file changed, 319 insertions(+), 250 deletions(-)
drivers/pinctrl/mediatek/pinctrl-airoha.c | 567 ++++++++++++----------
1 file changed, 318 insertions(+), 249 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
@ -32,10 +33,9 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
{ \
.desc = { \
.func = { \
- .name = #id, \
.name = #id, \
- .groups = id##_groups, \
- .ngroups = ARRAY_SIZE(id##_groups), \
+ .name = id, \
+ .groups = table##_groups, \
+ .ngroups = ARRAY_SIZE(table##_groups), \
} \

View File

@ -1,7 +1,7 @@
From ee980d96b6ecd385691f101e641f3e15513ce8c3 Mon Sep 17 00:00:00 2001
From 579839c9548cf2a85e873ad787bc2fa6610bf8ab Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sun, 25 May 2025 20:28:34 +0200
Subject: [PATCH 3/5] pinctrl: airoha: convert PHY LED GPIO to macro
Date: Fri, 7 Nov 2025 00:57:05 +0100
Subject: [PATCH 2/5] pinctrl: airoha: convert PHY LED GPIO to macro
PHY LED GPIO pinctrl struct definition is very similar across the
different 4 PHY and 2 LED and it can be generelized to a macro.
@ -9,17 +9,18 @@ different 4 PHY and 2 LED and it can be generelized to a macro.
To reduce code size, convert them to a common macro.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mediatek/pinctrl-airoha.c | 570 ++++------------------
1 file changed, 82 insertions(+), 488 deletions(-)
drivers/pinctrl/mediatek/pinctrl-airoha.c | 588 ++++------------------
1 file changed, 100 insertions(+), 488 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
@@ -1478,516 +1478,110 @@ static const struct airoha_pinctrl_func_
@@ -1478,516 +1478,128 @@ static const struct airoha_pinctrl_func_
},
};
+#define AIROHA_PINCTRL_PHY_LED(gpio, mux_val, map_mask, map_val) \
+#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
@ -36,6 +37,24 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+ }, \
+ .regmap_size = 2, \
+ }
+
+#define AIROHA_PINCTRL_PHY_LED1(gpio, mux_val, map_mask, map_val) \
+ { \
+ .name = (gpio), \
+ .regmap[0] = { \
+ AIROHA_FUNC_MUX, \
+ REG_GPIO_2ND_I2C_MODE, \
+ (mux_val), \
+ (mux_val), \
+ }, \
+ .regmap[1] = { \
+ AIROHA_FUNC_MUX, \
+ REG_LAN_LED1_MAPPING, \
+ (map_mask), \
+ (map_val), \
+ }, \
+ .regmap_size = 2, \
+ }
+
static const struct airoha_pinctrl_func_group phy1_led0_func_group[] = {
- {
@ -99,14 +118,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
};
static const struct airoha_pinctrl_func_group phy2_led0_func_group[] = {
@ -171,14 +190,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
};
static const struct airoha_pinctrl_func_group phy3_led0_func_group[] = {
@ -243,14 +262,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
};
static const struct airoha_pinctrl_func_group phy4_led0_func_group[] = {
@ -315,14 +334,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio33", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio34", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio35", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio42", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
};
static const struct airoha_pinctrl_func_group phy1_led1_func_group[] = {
@ -387,14 +406,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
};
static const struct airoha_pinctrl_func_group phy2_led1_func_group[] = {
@ -459,14 +478,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
};
static const struct airoha_pinctrl_func_group phy3_led1_func_group[] = {
@ -531,14 +550,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
};
static const struct airoha_pinctrl_func_group phy4_led1_func_group[] = {
@ -603,14 +622,14 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
- },
- .regmap_size = 2,
- },
+ AIROHA_PINCTRL_PHY_LED("gpio33", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio34", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio35", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio42", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio43", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio44", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio45", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio46", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
};
static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = {

View File

@ -1,7 +1,7 @@
From 83c79d127c610063e1b86c3f7f8d5e0145ffe9c6 Mon Sep 17 00:00:00 2001
From 1552ad5d649cff9d170e5bc1d13ab1487333b4b7 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sun, 25 May 2025 20:43:47 +0200
Subject: [PATCH 4/5] pinctrl: airoha: convert PWM GPIO to macro
Date: Fri, 7 Nov 2025 00:57:06 +0100
Subject: [PATCH 3/5] pinctrl: airoha: convert PWM GPIO to macro
The PWM GPIO struct definition follow the same pattern for every GPIO
pin hence it can be converted to a macro.
@ -10,6 +10,7 @@ Create 2 macro one for normal mux and one for ext mux and convert all
the entry to these new macro to reduce code size.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mediatek/pinctrl-airoha.c | 465 ++++------------------
1 file changed, 68 insertions(+), 397 deletions(-)
@ -488,4 +489,4 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+ AIROHA_PINCTRL_PWM_EXT("gpio47", GPIO47_FLASH_MODE_CFG),
};
#define AIROHA_PINCTRL_PHY_LED(gpio, mux_val, map_mask, map_val) \
#define AIROHA_PINCTRL_PHY_LED0(gpio, mux_val, map_mask, map_val) \

View File

@ -1,6 +1,6 @@
From cc92581b44cc3a6821c540ddbe27d4c009a7d312 Mon Sep 17 00:00:00 2001
From 3ffeb17a9a27a668efb6fbd074835e187910a9bb Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Sun, 25 May 2025 21:32:25 +0200
Date: Fri, 7 Nov 2025 00:57:08 +0100
Subject: [PATCH 5/5] pinctrl: airoha: add support for Airoha AN7583 PINs
Add all the required entry to add suppot for Airoha AN7583 PINs.
@ -9,9 +9,10 @@ Where possible the same function group are used from Airoha EN7581 to
reduce code duplication.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/mediatek/pinctrl-airoha.c | 733 ++++++++++++++++++++++
1 file changed, 733 insertions(+)
drivers/pinctrl/mediatek/pinctrl-airoha.c | 747 +++++++++++++++++++++-
1 file changed, 740 insertions(+), 7 deletions(-)
--- a/drivers/pinctrl/mediatek/pinctrl-airoha.c
+++ b/drivers/pinctrl/mediatek/pinctrl-airoha.c
@ -339,21 +340,21 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static const char *const phy4_led1_groups[] = { "gpio43", "gpio44",
"gpio45", "gpio46" };
+static const char *const an7583_phy1_led0_groups[] = { "gpio1", "gpio2",
+ "gpio3", "gpio4" };
+ "gpio3", "gpio4" };
+static const char *const an7583_phy2_led0_groups[] = { "gpio1", "gpio2",
+ "gpio3", "gpio4" };
+ "gpio3", "gpio4" };
+static const char *const an7583_phy3_led0_groups[] = { "gpio1", "gpio2",
+ "gpio3", "gpio4" };
+ "gpio3", "gpio4" };
+static const char *const an7583_phy4_led0_groups[] = { "gpio1", "gpio2",
+ "gpio3", "gpio4" };
+ "gpio3", "gpio4" };
+static const char *const an7583_phy1_led1_groups[] = { "gpio8", "gpio9",
+ "gpio10", "gpio11" };
+ "gpio10", "gpio11" };
+static const char *const an7583_phy2_led1_groups[] = { "gpio8", "gpio9",
+ "gpio10", "gpio11" };
+ "gpio10", "gpio11" };
+static const char *const an7583_phy3_led1_groups[] = { "gpio8", "gpio9",
+ "gpio10", "gpio11" };
+ "gpio10", "gpio11" };
+static const char *const an7583_phy4_led1_groups[] = { "gpio8", "gpio9",
+ "gpio10", "gpio11" };
+ "gpio10", "gpio11" };
static const struct airoha_pinctrl_func_group pon_func_group[] = {
{
@ -486,102 +487,102 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
/* PWM */
#define AIROHA_PINCTRL_PWM(gpio, mux_val) \
{ \
@@ -1255,6 +1614,94 @@ static const struct airoha_pinctrl_func_
LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
@@ -1273,6 +1632,94 @@ static const struct airoha_pinctrl_func_
LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
};
+static const struct airoha_pinctrl_func_group an7583_phy1_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy2_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy3_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy4_led0_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio1", GPIO_LAN0_LED0_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio2", GPIO_LAN1_LED0_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio3", GPIO_LAN2_LED0_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(3)),
+ AIROHA_PINCTRL_PHY_LED0("gpio4", GPIO_LAN3_LED0_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(3)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy1_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED("gpio1", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(0)),
+ AIROHA_PINCTRL_PHY_LED1("gpio1", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(0)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy2_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(1)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(1)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy3_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
+static const struct airoha_pinctrl_func_group an7583_phy4_led1_func_group[] = {
+ AIROHA_PINCTRL_PHY_LED("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio8", GPIO_LAN0_LED1_MODE_MASK,
+ LAN0_LED_MAPPING_MASK, LAN0_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio9", GPIO_LAN1_LED1_MODE_MASK,
+ LAN1_LED_MAPPING_MASK, LAN1_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio10", GPIO_LAN2_LED1_MODE_MASK,
+ LAN2_LED_MAPPING_MASK, LAN2_PHY_LED_MAP(2)),
+ AIROHA_PINCTRL_PHY_LED1("gpio11", GPIO_LAN3_LED1_MODE_MASK,
+ LAN3_LED_MAPPING_MASK, LAN3_PHY_LED_MAP(2)),
+};
+
static const struct airoha_pinctrl_func en7581_pinctrl_funcs[] = {
PINCTRL_FUNC_DESC("pon", pon),
PINCTRL_FUNC_DESC("tod_1pps", tod_1pps),
@@ -1281,6 +1728,31 @@ static const struct airoha_pinctrl_func
@@ -1299,6 +1746,31 @@ static const struct airoha_pinctrl_func
PINCTRL_FUNC_DESC("phy4_led1", phy4_led1),
};
@ -613,7 +614,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static const struct airoha_pinctrl_conf en7581_pinctrl_pullup_conf[] = {
PINCTRL_CONF_DESC(0, REG_I2C_SDA_PU, UART1_TXD_PU_MASK),
PINCTRL_CONF_DESC(1, REG_I2C_SDA_PU, UART1_RXD_PU_MASK),
@@ -1342,6 +1814,62 @@ static const struct airoha_pinctrl_conf
@@ -1360,6 +1832,62 @@ static const struct airoha_pinctrl_conf
PINCTRL_CONF_DESC(63, REG_I2C_SDA_PU, PCIE2_RESET_PU_MASK),
};
@ -676,7 +677,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static const struct airoha_pinctrl_conf en7581_pinctrl_pulldown_conf[] = {
PINCTRL_CONF_DESC(0, REG_I2C_SDA_PD, UART1_TXD_PD_MASK),
PINCTRL_CONF_DESC(1, REG_I2C_SDA_PD, UART1_RXD_PD_MASK),
@@ -1403,6 +1931,62 @@ static const struct airoha_pinctrl_conf
@@ -1421,6 +1949,62 @@ static const struct airoha_pinctrl_conf
PINCTRL_CONF_DESC(63, REG_I2C_SDA_PD, PCIE2_RESET_PD_MASK),
};
@ -739,7 +740,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e2_conf[] = {
PINCTRL_CONF_DESC(0, REG_I2C_SDA_E2, UART1_TXD_E2_MASK),
PINCTRL_CONF_DESC(1, REG_I2C_SDA_E2, UART1_RXD_E2_MASK),
@@ -1464,6 +2048,62 @@ static const struct airoha_pinctrl_conf
@@ -1482,6 +2066,62 @@ static const struct airoha_pinctrl_conf
PINCTRL_CONF_DESC(63, REG_I2C_SDA_E2, PCIE2_RESET_E2_MASK),
};
@ -802,7 +803,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static const struct airoha_pinctrl_conf en7581_pinctrl_drive_e4_conf[] = {
PINCTRL_CONF_DESC(0, REG_I2C_SDA_E4, UART1_TXD_E4_MASK),
PINCTRL_CONF_DESC(1, REG_I2C_SDA_E4, UART1_RXD_E4_MASK),
@@ -1525,12 +2165,73 @@ static const struct airoha_pinctrl_conf
@@ -1543,12 +2183,73 @@ static const struct airoha_pinctrl_conf
PINCTRL_CONF_DESC(63, REG_I2C_SDA_E4, PCIE2_RESET_E4_MASK),
};
@ -876,7 +877,56 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static int airoha_convert_pin_to_reg_offset(struct pinctrl_dev *pctrl_dev,
struct pinctrl_gpio_range *range,
int pin)
@@ -2267,8 +2968,40 @@ static const struct airoha_pinctrl_match
@@ -1714,7 +2415,7 @@ static const struct irq_chip airoha_gpio
};
static int airoha_pinctrl_add_gpiochip(struct airoha_pinctrl *pinctrl,
- struct platform_device *pdev)
+ struct platform_device *pdev)
{
struct airoha_pinctrl_gpiochip *chip = &pinctrl->gpiochip;
struct gpio_chip *gc = &chip->chip;
@@ -1749,7 +2450,7 @@ static int airoha_pinctrl_add_gpiochip(s
return irq;
err = devm_request_irq(dev, irq, airoha_irq_handler, IRQF_SHARED,
- dev_name(dev), pinctrl);
+ dev_name(dev), pinctrl);
if (err) {
dev_err(dev, "error requesting irq %d: %d\n", irq, err);
return err;
@@ -1813,8 +2514,8 @@ static int airoha_pinmux_set_mux(struct
}
static int airoha_pinmux_set_direction(struct pinctrl_dev *pctrl_dev,
- struct pinctrl_gpio_range *range,
- unsigned int p, bool input)
+ struct pinctrl_gpio_range *range,
+ unsigned int p, bool input)
{
struct airoha_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
u32 mask, index;
@@ -1904,7 +2605,7 @@ static int airoha_pinctrl_set_conf(struc
if (regmap_update_bits(pinctrl->chip_scu, reg->offset, reg->mask,
- val << __ffs(reg->mask)))
+ val << __ffs(reg->mask)))
return -EINVAL;
return 0;
@@ -2123,8 +2824,8 @@ static int airoha_pinconf_group_get(stru
for (i = 0; i < pinctrl->grps[group].npins; i++) {
if (airoha_pinconf_get(pctrl_dev,
- pinctrl->grps[group].pins[i],
- config))
+ pinctrl->grps[group].pins[i],
+ config))
return -ENOTSUPP;
if (i && cur_config != *config)
@@ -2285,8 +2986,40 @@ static const struct airoha_pinctrl_match
},
};

View File

@ -37,7 +37,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
.glo_cfg = 0x4604,
.rst_idx = 0x4608,
.delay_irq = 0x460c,
@@ -4053,6 +4056,56 @@ static void mtk_set_mcr_max_rx(struct mt
@@ -4060,6 +4063,56 @@ static void mtk_set_mcr_max_rx(struct mt
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
}
@ -94,7 +94,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
static void mtk_hw_reset(struct mtk_eth *eth)
{
u32 val;
@@ -4532,6 +4585,8 @@ static void mtk_pending_work(struct work
@@ -4539,6 +4592,8 @@ static void mtk_pending_work(struct work
rtnl_lock();
set_bit(MTK_RESETTING, &eth->state);

View File

@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#include <net/page_pool/helpers.h>
#include "mtk_eth_soc.h"
@@ -1404,119 +1407,244 @@ static void mtk_tx_set_dma_desc(struct n
@@ -1404,119 +1407,251 @@ static void mtk_tx_set_dma_desc(struct n
mtk_tx_set_dma_desc_v1(dev, txd, info);
}
@ -148,9 +148,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct sk_buff *cur_skb, *next_skb;
int queue = skb_get_queue_mapping(skb);
- int k = 0;
+ int i, frag_size = skb_headlen(skb);
+ bool gso_v4, gso_fraglist;
+ int offset = 0;
+ int i, frag_size;
+ bool gso_v4;
txq = netdev_get_tx_queue(dev, queue);
itxd = ring->next_free;
@ -164,6 +164,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ next_skb = skb_shinfo(skb)->frag_list;
+ mtk_tx_map_set_txd(&state, ring, soc, itxd);
+ gso_v4 = skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4;
+ gso_fraglist = skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST;
- txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
- DMA_TO_DEVICE);
@ -180,17 +181,35 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ };
- mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+ offset = 0;
+ frag_size = skb_headlen(cur_skb);
+ if (cur_skb != skb) {
+ struct tcphdr *th, *th2;
+
- itx_buf->mac_id = mac->id;
- setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
- k++);
-
- /* TX SG offload */
- txd = itxd;
- txd_pdma = qdma_to_pdma(ring, txd);
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- unsigned int offset = 0;
- int frag_size = skb_frag_size(frag);
+ if (skb_cow_head(cur_skb, header_len))
+ goto err_dma;
+
- while (frag_size) {
- bool new_desc = true;
+ memcpy(cur_skb->data - header_len, skb->data,
+ skb_network_offset(skb));
+
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
- (i & 0x1)) {
- txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
- txd_pdma = qdma_to_pdma(ring, txd);
- if (txd == ring->last_free)
- goto err_dma;
+ th = tcp_hdr(cur_skb);
+ th2 = tcp_hdr(skb);
+ if (gso_v4) {
@ -205,47 +224,28 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ struct ipv6hdr *iph = ipv6_hdr(cur_skb);
+ struct ipv6hdr *iph2 = ipv6_hdr(skb);
- itx_buf->mac_id = mac->id;
- setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
- k++);
-
- /* TX SG offload */
- txd = itxd;
- txd_pdma = qdma_to_pdma(ring, txd);
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- unsigned int offset = 0;
- int frag_size = skb_frag_size(frag);
- n_desc++;
- } else {
- new_desc = false;
- }
+ mtk_tx_update_ip6addr(skb, iph, th, &iph->saddr,
+ &iph2->saddr);
+ mtk_tx_update_ip6addr(skb, iph, th, &iph->daddr,
+ &iph2->daddr);
+ }
- while (frag_size) {
- bool new_desc = true;
+
+ mtk_tx_update_port(skb, th, &th->source, th2->source);
+ mtk_tx_update_port(skb, th, &th->dest, th2->dest);
- if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) ||
- (i & 0x1)) {
- txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
- txd_pdma = qdma_to_pdma(ring, txd);
- if (txd == ring->last_free)
- goto err_dma;
+
+ offset = -header_len;
+ frag_size += header_len;
+ } else if (next_skb) {
+ } else if (next_skb && gso_fraglist) {
+ unsigned int ip_len = skb_pagelen(skb) - skb_network_offset(skb);
+ if (gso_v4) {
+ struct iphdr *iph = ip_hdr(cur_skb);
+ __be16 ip_len_val = cpu_to_be16(ip_len);
- n_desc++;
- } else {
- new_desc = false;
- }
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
+ csum_replace2(&iph->check, iph->tot_len, ip_len_val);
+ iph->tot_len = ip_len_val;
+ } else {
@ -255,8 +255,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ iph->payload_len = ip_len_val;
+ }
+ }
- memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
+
+next_frag:
+ while (frag_size) {
+ txd_info.size = min_t(unsigned int, frag_size,
+ soc->tx.dma_max_len);
@ -267,7 +267,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+ frag_size -= txd_info.size;
+ offset += txd_info.size;
+ txd_info.last = !frag_size && !skb_shinfo(cur_skb)->nr_frags;
+ txd_info.last = !frag_size && !skb_shinfo(cur_skb)->nr_frags &&
+ (gso_fraglist || !next_skb);
+ if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0)
+ goto err_dma;
+ }
@ -308,7 +309,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
frag_size -= txd_info.size;
offset += txd_info.size;
+ txd_info.last = i == skb_shinfo(cur_skb)->nr_frags - 1 &&
+ !frag_size;
+ !frag_size && (gso_fraglist || !next_skb);
+ if (mtk_tx_map_info(eth, ring, dev, &state, &txd_info) < 0)
+ goto err_dma;
}
@ -317,12 +318,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
- /* store skb to cleanup */
- itx_buf->type = MTK_TYPE_SKB;
- itx_buf->data = skb;
-
if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- if (k & 0x1)
- txd_pdma->txd2 |= TX_DMA_LS0;
- else
- txd_pdma->txd2 |= TX_DMA_LS1;
+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA) &&
+ (gso_fraglist || !next_skb)) {
+ if (state.nbuf & 0x1) {
+ state.txd_pdma->txd2 |= TX_DMA_LS0;
+ state.nbuf++;
@ -334,6 +331,16 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ if (next_skb) {
+ cur_skb = next_skb;
+ next_skb = cur_skb->next;
+ offset = 0;
+ frag_size = skb_headlen(cur_skb);
+ if (!gso_fraglist)
+ goto next_frag;
- if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
- if (k & 0x1)
- txd_pdma->txd2 |= TX_DMA_LS0;
- else
- txd_pdma->txd2 |= TX_DMA_LS1;
+ goto next;
}
@ -351,7 +358,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* make sure that all changes to the dma ring are flushed before we
* continue
@@ -1525,11 +1653,11 @@ static int mtk_tx_map(struct sk_buff *sk
@@ -1525,11 +1660,11 @@ static int mtk_tx_map(struct sk_buff *sk
if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) {
if (netif_xmit_stopped(txq) || !netdev_xmit_more())
@ -365,7 +372,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
ring->dma_size);
mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
}
@@ -1538,18 +1666,20 @@ static int mtk_tx_map(struct sk_buff *sk
@@ -1538,18 +1673,20 @@ static int mtk_tx_map(struct sk_buff *sk
err_dma:
do {
@ -390,7 +397,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return -ENOMEM;
}
@@ -1569,6 +1699,9 @@ static int mtk_cal_txd_req(struct mtk_et
@@ -1569,6 +1706,9 @@ static int mtk_cal_txd_req(struct mtk_et
nfrags += skb_shinfo(skb)->nr_frags;
}
@ -400,7 +407,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return nfrags;
}
@@ -1609,9 +1742,29 @@ static bool mtk_skb_has_small_frag(struc
@@ -1609,9 +1749,29 @@ static bool mtk_skb_has_small_frag(struc
if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size)
return true;
@ -430,7 +437,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct mtk_mac *mac = netdev_priv(dev);
@@ -1619,6 +1772,7 @@ static netdev_tx_t mtk_start_xmit(struct
@@ -1619,6 +1779,7 @@ static netdev_tx_t mtk_start_xmit(struct
struct mtk_tx_ring *ring = &eth->tx_ring;
struct net_device_stats *stats = &dev->stats;
struct sk_buff *segs, *next;
@ -438,7 +445,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
bool gso = false;
int tx_num;
@@ -1647,37 +1801,42 @@ static netdev_tx_t mtk_start_xmit(struct
@@ -1647,37 +1808,42 @@ static netdev_tx_t mtk_start_xmit(struct
return NETDEV_TX_BUSY;
}

View File

@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2305,7 +2305,7 @@ static int mtk_poll_rx(struct napi_struc
@@ -2312,7 +2312,7 @@ static int mtk_poll_rx(struct napi_struc
if (ret != XDP_PASS)
goto skip_rx;
@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (unlikely(!skb)) {
page_pool_put_full_page(ring->page_pool,
page, true);
@@ -2343,7 +2343,7 @@ static int mtk_poll_rx(struct napi_struc
@@ -2350,7 +2350,7 @@ static int mtk_poll_rx(struct napi_struc
dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
ring->buf_size, DMA_FROM_DEVICE);

View File

@ -25,7 +25,7 @@ Signed-off-by: Chad Monroe <chad@monroe.io>
/* QDMA Flow Control Register */
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3476,12 +3476,14 @@ static int mtk_start_dma(struct mtk_eth
@@ -3483,12 +3483,14 @@ static int mtk_start_dma(struct mtk_eth
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;

View File

@ -477,7 +477,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
.mac_finish = mtk_mac_finish,
.mac_link_down = mtk_mac_link_down,
.mac_link_up = mtk_mac_link_up,
@@ -3584,6 +3729,9 @@ static int mtk_open(struct net_device *d
@@ -3591,6 +3736,9 @@ static int mtk_open(struct net_device *d
ppe_num = eth->soc->ppe_num;
@ -487,7 +487,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
if (err) {
netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
@@ -3731,6 +3879,9 @@ static int mtk_stop(struct net_device *d
@@ -3738,6 +3886,9 @@ static int mtk_stop(struct net_device *d
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
mtk_ppe_stop(eth->ppe[i]);
@ -497,7 +497,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
return 0;
}
@@ -4821,6 +4972,7 @@ static const struct net_device_ops mtk_n
@@ -4828,6 +4979,7 @@ static const struct net_device_ops mtk_n
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
{
const __be32 *_id = of_get_property(np, "reg", NULL);
@ -505,7 +505,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phy_interface_t phy_mode;
struct phylink *phylink;
struct mtk_mac *mac;
@@ -4859,16 +5011,41 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4866,16 +5018,41 @@ static int mtk_add_mac(struct mtk_eth *e
mac->id = id;
mac->hw = eth;
mac->of_node = np;
@ -555,7 +555,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
}
memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
@@ -4951,8 +5128,21 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4958,8 +5135,21 @@ static int mtk_add_mac(struct mtk_eth *e
phy_interface_zero(mac->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
mac->phylink_config.supported_interfaces);
@ -577,7 +577,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, &mtk_phylink_ops);
@@ -5003,6 +5193,26 @@ free_netdev:
@@ -5010,6 +5200,26 @@ free_netdev:
return err;
}
@ -604,7 +604,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)
{
struct net_device *dev, *tmp;
@@ -5149,7 +5359,8 @@ static int mtk_probe(struct platform_dev
@@ -5156,7 +5366,8 @@ static int mtk_probe(struct platform_dev
regmap_write(cci, 0, 3);
}
@ -614,7 +614,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
err = mtk_sgmii_init(eth);
if (err)
@@ -5260,6 +5471,24 @@ static int mtk_probe(struct platform_dev
@@ -5267,6 +5478,24 @@ static int mtk_probe(struct platform_dev
}
}
@ -639,7 +639,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) {
err = devm_request_irq(eth->dev, eth->irq[0],
mtk_handle_irq, 0,
@@ -5370,6 +5599,11 @@ static void mtk_remove(struct platform_d
@@ -5377,6 +5606,11 @@ static void mtk_remove(struct platform_d
mtk_stop(eth->netdev[i]);
mac = netdev_priv(eth->netdev[i]);
phylink_disconnect_phy(mac->phylink);

View File

@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -5637,7 +5637,7 @@ static const struct mtk_soc_data mt2701_
@@ -5644,7 +5644,7 @@ static const struct mtk_soc_data mt2701_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5665,7 +5665,7 @@ static const struct mtk_soc_data mt7621_
@@ -5672,7 +5672,7 @@ static const struct mtk_soc_data mt7621_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -48,7 +48,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5695,7 +5695,7 @@ static const struct mtk_soc_data mt7622_
@@ -5702,7 +5702,7 @@ static const struct mtk_soc_data mt7622_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -57,7 +57,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5724,7 +5724,7 @@ static const struct mtk_soc_data mt7623_
@@ -5731,7 +5731,7 @@ static const struct mtk_soc_data mt7623_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5750,7 +5750,7 @@ static const struct mtk_soc_data mt7629_
@@ -5757,7 +5757,7 @@ static const struct mtk_soc_data mt7629_
DESC_SIZE(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
@ -75,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
@@ -5782,7 +5782,7 @@ static const struct mtk_soc_data mt7981_
@@ -5789,7 +5789,7 @@ static const struct mtk_soc_data mt7981_
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
},
};
@@ -5812,7 +5812,7 @@ static const struct mtk_soc_data mt7986_
@@ -5819,7 +5819,7 @@ static const struct mtk_soc_data mt7986_
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
},
};
@@ -5865,7 +5865,7 @@ static const struct mtk_soc_data rt5350_
@@ -5872,7 +5872,7 @@ static const struct mtk_soc_data rt5350_
.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,

View File

@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
help
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4740,6 +4740,7 @@ static int mtk_get_sset_count(struct net
@@ -4747,6 +4747,7 @@ static int mtk_get_sset_count(struct net
static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data)
{
@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct page_pool_stats stats = {};
int i;
@@ -4752,6 +4753,7 @@ static void mtk_ethtool_pp_stats(struct
@@ -4759,6 +4760,7 @@ static void mtk_ethtool_pp_stats(struct
page_pool_get_stats(ring->page_pool, &stats);
}
page_pool_ethtool_stats_get(data, &stats);

View File

@ -106,7 +106,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
mdelay(20);
mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
@@ -2901,10 +2931,16 @@ static int mtk_tx_alloc(struct mtk_eth *
@@ -2908,10 +2938,16 @@ static int mtk_tx_alloc(struct mtk_eth *
mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs);
val = MTK_QTX_SCH_MIN_RATE_EN |
@ -126,7 +126,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
if (mtk_is_netsys_v1(eth))
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
@@ -5873,6 +5909,36 @@ static const struct mtk_soc_data mt7986_
@@ -5880,6 +5916,36 @@ static const struct mtk_soc_data mt7986_
},
};
@ -163,7 +163,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
static const struct mtk_soc_data mt7988_data = {
.reg_map = &mt7988_reg_map,
.ana_rgc3 = 0x128,
@@ -5934,6 +6000,7 @@ const struct of_device_id of_mtk_match[]
@@ -5941,6 +6007,7 @@ const struct of_device_id of_mtk_match[]
{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
{ .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
{ .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },

View File

@ -15,7 +15,7 @@ Signed-off-by: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4445,27 +4445,40 @@ static int mtk_hw_init(struct mtk_eth *e
@@ -4452,27 +4452,40 @@ static int mtk_hw_init(struct mtk_eth *e
mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) | PSE_DUMMY_WORK_GDM(2) |
PSE_DUMMY_WORK_GDM(3) | DUMMY_PAGE_THR, PSE_DUMY_REQ);

View File

@ -0,0 +1,481 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include "ipq5018.dtsi"
#include "ipq5018-ess.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
/ {
model = "CMCC PZ-L8";
compatible = "cmcc,pz-l8", "qcom,ipq5018";
aliases {
serial0 = &blsp1_uart1;
led-boot = &led_wan;
led-failsafe = &led_lan;
led-running = &led_wan;
led-upgrade = &led_lan;
label-mac-device = <&dp1>;
};
chosen {
bootargs-append = " root=/dev/ubiblock0_1 swiotlb=1 coherent_pool=2M";
stdout-path = "serial0:115200n8";
};
keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
reset-button {
label = "reset";
gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
wps-button {
label = "wps";
gpios = <&tlmm 34 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WPS_BUTTON>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led_wan: led-0 {
gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
color = <LED_COLOR_ID_GREEN>;
function = LED_FUNCTION_WAN;
default-state = "off";
};
led_lan: led-1 {
gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
color = <LED_COLOR_ID_RED>;
function = LED_FUNCTION_LAN;
};
};
reserved-memory {
q6_mem_regions: q6_mem_regions@4b000000 {
no-map;
reg = <0x0 0x4b000000 0x0 0x3000000>;
status = "disabled";
};
};
};
&sleep_clk {
clock-frequency = <32000>;
};
&xo_board_clk {
clock-div = <4>;
clock-mult = <1>;
};
&blsp1_uart1 {
status = "okay";
pinctrl-0 = <&serial_0_pins>;
pinctrl-names = "default";
};
&crypto {
status = "okay";
};
&cryptobam {
status = "okay";
};
&prng {
status = "okay";
};
&qfprom {
status = "okay";
};
&qpic_bam {
status = "okay";
};
&qpic_nand {
pinctrl-0 = <&qpic_pins>;
pinctrl-names = "default";
status = "okay";
nand@0 {
compatible = "spi-nand";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
nand-ecc-engine = <&qpic_nand>;
nand-bus-width = <8>;
partitions {
compatible = "qcom,smem-part";
partition-art {
label = "0:art";
read-only;
nvmem-layout {
compatible = "fixed-layout";
#address-cells = <1>;
#size-cells = <1>;
hw_mac_addr: mac-address@0 {
compatible = "mac-base";
reg = <0x0 0x6>;
#nvmem-cell-cells = <1>;
};
};
};
};
};
};
&switch {
status = "okay";
switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;
qcom,port_phyinfo {
// MAC0 -> GE Phy --- MDI --- QCA8337 Phy4(Port5)
port@0 {
port_id = <1>;
mdiobus = <&mdio0>;
phy_address = <7>;
};
// MAC1 -> Uniphy --- SGMII --- QCA8337 SerDes(Port6)
port@1 {
port_id = <2>;
mdiobus = <&mdio1>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
};
// MAC0 -> GE Phy
&dp1 {
status = "okay";
nvmem-cells = <&hw_mac_addr 0>;
nvmem-cell-names = "mac-address";
};
// MAC1 -> SGMII
&dp2 {
status = "okay";
nvmem-cells = <&hw_mac_addr 1>;
nvmem-cell-names = "mac-address";
fixed-link {
speed = <1000>;
full-duplex;
};
};
&mdio0 {
status = "okay";
};
// MAC0 -> GE Phy -> QCA8337 Phy4
&ge_phy {
qcom,dac-preset-short-cable;
};
&mdio1 {
status = "okay";
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
reset-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;
// QCA8337 Phy0 -> LAN3
qca8337_0: ethernet-phy@0 {
reg = <0>;
};
// QCA8337 Phy1 -> LAN2
qca8337_1: ethernet-phy@1 {
reg = <1>;
};
// QCA8337 Phy2 -> LAN1
qca8337_2: ethernet-phy@2 {
reg = <2>;
};
// QCA8337 Phy3 -> WAN
qca8337_3: ethernet-phy@3 {
reg = <3>;
};
// QCA8337 Phy4 -> IPQ5018 GE Phy
qca8337_4: ethernet-phy@4 {
reg = <4>;
};
// QCA8337 switch
switch1: ethernet-switch@17 {
compatible = "qca,qca8337";
reg = <17>;
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
label = "lan3";
phy-handle = <&qca8337_0>;
};
port@2 {
reg = <2>;
label = "lan2";
phy-handle = <&qca8337_1>;
};
port@3 {
reg = <3>;
label = "lan1";
phy-handle = <&qca8337_2>;
};
port@4 {
reg = <4>;
label = "wan";
phy-handle = <&qca8337_3>;
};
/*
* WAN cannot work if added
* port@5 {
* reg = <5>;
* phy-handle = <&qca8337_4>;
* phy-mode = "gmii";
* ethernet = <&dp1>;
* };
*/
port@6 {
reg = <6>;
phy-mode = "sgmii";
ethernet = <&dp2>;
qca,sgmii-enable-pll;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
};
&tlmm {
button_pins: button-state {
button-pins {
pins = "gpio34", "gpio33";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
led_pins: led-state {
pins = "gpio35", "gpio30";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
mdio1_pins: mdio-state {
mdc-pins {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mdio-pins {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
qpic_pins: qpic-state {
clock-pins {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
cs-pins {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
data-pins {
pins = "gpio4", "gpio5", "gpio6", "gpio7";
function = "qspi_data";
drive-strength = <8>;
bias-disable;
};
};
serial_0_pins: uart0-state {
pins = "gpio28", "gpio29";
function = "blsp0_uart1";
drive-strength = <8>;
bias-disable;
};
switch_reset_pins: switch-reset-state {
pins = "gpio26";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
/*
* ath11k Wi-Fi consumes too large memory spaces and too few spaces are
* available for users. To prevent OOM when using LuCI or other softwares,
* disable Wi-Fi related peripherals at the moment.
*/
&q6v5_wcss {
status = "disabled";
memory-region = <&q6_mem_regions>;
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt",
"ath11k/IPQ5018/hw1.0/m3_fw.mdt",
"ath11k/QCN6122/hw1.0/m3_fw.mdt";
/* The QCN6102 radio should map to UPD ID 2. Without */
/* bootargs, the firmware will expect it to be on UPD ID 3 */
boot-args = <0x2 4 2 27 0 0>; /* pcie:2, len:4, updid:2, reset:gpio27 */
// IPQ5018
q6_wcss_pd1: pd-1 {
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";
resets =
<&gcc GCC_WCSSAON_RESET>,
<&gcc GCC_WCSS_BCR>,
<&gcc GCC_CE_BCR>;
reset-names =
"wcss_aon_reset",
"wcss_reset",
"ce_reset";
clocks =
<&gcc GCC_WCSS_AHB_S_CLK>,
<&gcc GCC_WCSS_ACMT_CLK>,
<&gcc GCC_WCSS_AXI_M_CLK>;
clock-names =
"gcc_wcss_ahb_s_clk",
"gcc_wcss_acmt_clk",
"gcc_wcss_axi_m_clk";
interrupts-extended =
<&wcss_smp2p_in 8 IRQ_TYPE_NONE>,
<&wcss_smp2p_in 9 IRQ_TYPE_NONE>,
<&wcss_smp2p_in 12 IRQ_TYPE_NONE>,
<&wcss_smp2p_in 11 IRQ_TYPE_NONE>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
status = "disabled";
};
// QCN6102 5G
q6_wcss_pd2: pd-2 {
firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";
interrupts-extended =
<&wcss_smp2p_in 16 IRQ_TYPE_NONE>,
<&wcss_smp2p_in 17 IRQ_TYPE_NONE>,
<&wcss_smp2p_in 20 IRQ_TYPE_NONE>,
<&wcss_smp2p_in 19 IRQ_TYPE_NONE>;
interrupt-names =
"fatal",
"ready",
"spawn-ack",
"stop-ack";
qcom,smem-states =
<&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names =
"shutdown",
"stop",
"spawn";
status = "disabled";
};
};
&wifi0 {
// IPQ5018
qcom,rproc = <&q6_wcss_pd1>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
qcom,ath11k-calibration-variant = "CMCC-PZ-L8";
qcom,ath11k-fw-memory-mode = <1>;
qcom,bdf-addr = <0x4c400000>;
ieee80211-freq-limit = <2400000 2483000>;
status = "disabled";
};
&wifi1 {
// QCN6102 5G
qcom,rproc = <&q6_wcss_pd2>;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
qcom,ath11k-calibration-variant = "CMCC-PZ-L8";
qcom,ath11k-fw-memory-mode = <1>;
qcom,bdf-addr = <0x4d100000>;
qcom,m3-dump-addr = <0x4df00000>;
ieee80211-freq-limit = <5150000 5730000>;
status = "disabled";
};

View File

@ -18,6 +18,20 @@ define Build/mstc-header
rm -f $@.crclen
endef
define Device/cmcc_pz-l8
$(call Device/FitImageLzma)
$(call Device/UbiFit)
DEVICE_VENDOR := CMCC
DEVICE_MODEL := PZ-L8
DEVICE_DTS_CONFIG := config@mp02.1
SOC := ipq5018
BLOCKSIZE := 128k
PAGESIZE := 2048
IMAGE_SIZE := 59392k
NAND_SIZE := 128m
endef
TARGET_DEVICES += cmcc_pz-l8
define Device/elecom_wrc-x3000gs2
$(call Device/FitImageLzma)
DEVICE_VENDOR := ELECOM

View File

@ -9,6 +9,7 @@ board_config_update
board=$(board_name)
case "$board" in
cmcc,pz-l8|\
elecom,wrc-x3000gs2|\
iodata,wn-dax3000gr)
ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan" "tx rx link_10 link_100 link_1000"

View File

@ -15,6 +15,7 @@ ipq50xx_setup_interfaces()
glinet,gl-b3000)
ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
;;
cmcc,pz-l8|\
linksys,mx2000|\
linksys,mx5500|\
linksys,spnmx56|\

View File

@ -102,6 +102,7 @@ platform_pre_upgrade() {
platform_do_upgrade() {
case "$(board_name)" in
cmcc,pz-l8|\
elecom,wrc-x3000gs2|\
iodata,wn-dax3000gr)
local delay

View File

@ -0,0 +1,524 @@
From 986ec7ee75f2f1f7f93eb0e05f61f297f6123fce Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Mon, 3 Mar 2025 21:14:02 +0100
Subject: [PATCH] v6.15: net: phy: move PHY package code from phy_device.c to
own source file
This patch is the first step in moving the PHY package related code
to its own source file. No functional change intended.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://patch.msgid.link/57df5c19-fbcd-45a7-9afd-cd4f74d7fa76@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/Makefile | 3 +-
drivers/net/phy/phy_device.c | 237 ---------------------------------
drivers/net/phy/phy_package.c | 244 ++++++++++++++++++++++++++++++++++
3 files changed, 246 insertions(+), 238 deletions(-)
create mode 100644 drivers/net/phy/phy_package.c
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -2,7 +2,8 @@
# Makefile for Linux PHY drivers
libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \
- linkmode.o phy_link_topology.o
+ linkmode.o phy_link_topology.o \
+ phy_package.o
mdio-bus-y += mdio_bus.o mdio_device.o
ifdef CONFIG_MDIO_DEVICE
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1783,243 +1783,6 @@ bool phy_driver_is_genphy_10g(struct phy
EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g);
/**
- * phy_package_join - join a common PHY group
- * @phydev: target phy_device struct
- * @base_addr: cookie and base PHY address of PHY package for offset
- * calculation of global register access
- * @priv_size: if non-zero allocate this amount of bytes for private data
- *
- * This joins a PHY group and provides a shared storage for all phydevs in
- * this group. This is intended to be used for packages which contain
- * more than one PHY, for example a quad PHY transceiver.
- *
- * The base_addr parameter serves as cookie which has to have the same values
- * for all members of one group and as the base PHY address of the PHY package
- * for offset calculation to access generic registers of a PHY package.
- * Usually, one of the PHY addresses of the different PHYs in the package
- * provides access to these global registers.
- * The address which is given here, will be used in the phy_package_read()
- * and phy_package_write() convenience functions as base and added to the
- * passed offset in those functions.
- *
- * This will set the shared pointer of the phydev to the shared storage.
- * If this is the first call for a this cookie the shared storage will be
- * allocated. If priv_size is non-zero, the given amount of bytes are
- * allocated for the priv member.
- *
- * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
- * with the same cookie but a different priv_size is an error.
- */
-int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
-{
- struct mii_bus *bus = phydev->mdio.bus;
- struct phy_package_shared *shared;
- int ret;
-
- if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
- return -EINVAL;
-
- mutex_lock(&bus->shared_lock);
- shared = bus->shared[base_addr];
- if (!shared) {
- ret = -ENOMEM;
- shared = kzalloc(sizeof(*shared), GFP_KERNEL);
- if (!shared)
- goto err_unlock;
- if (priv_size) {
- shared->priv = kzalloc(priv_size, GFP_KERNEL);
- if (!shared->priv)
- goto err_free;
- shared->priv_size = priv_size;
- }
- shared->base_addr = base_addr;
- shared->np = NULL;
- refcount_set(&shared->refcnt, 1);
- bus->shared[base_addr] = shared;
- } else {
- ret = -EINVAL;
- if (priv_size && priv_size != shared->priv_size)
- goto err_unlock;
- refcount_inc(&shared->refcnt);
- }
- mutex_unlock(&bus->shared_lock);
-
- phydev->shared = shared;
-
- return 0;
-
-err_free:
- kfree(shared);
-err_unlock:
- mutex_unlock(&bus->shared_lock);
- return ret;
-}
-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
- *
- * This leaves a PHY group created by phy_package_join(). If this phydev
- * was the last user of the shared data between the group, this data is
- * freed. Resets the phydev->shared pointer to NULL.
- */
-void phy_package_leave(struct phy_device *phydev)
-{
- struct phy_package_shared *shared = phydev->shared;
- struct mii_bus *bus = phydev->mdio.bus;
-
- 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);
- kfree(shared->priv);
- kfree(shared);
- }
-
- phydev->shared = NULL;
-}
-EXPORT_SYMBOL_GPL(phy_package_leave);
-
-static void devm_phy_package_leave(struct device *dev, void *res)
-{
- phy_package_leave(*(struct phy_device **)res);
-}
-
-/**
- * devm_phy_package_join - resource managed phy_package_join()
- * @dev: device that is registering this PHY package
- * @phydev: target phy_device struct
- * @base_addr: cookie and base PHY address of PHY package for offset
- * calculation of global register access
- * @priv_size: if non-zero allocate this amount of bytes for private data
- *
- * Managed phy_package_join(). Shared storage fetched by this function,
- * phy_package_leave() is automatically called on driver detach. See
- * phy_package_join() for more information.
- */
-int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
- int base_addr, 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 = phy_package_join(phydev, base_addr, priv_size);
-
- if (!ret) {
- *ptr = phydev;
- devres_add(dev, ptr);
- } else {
- devres_free(ptr);
- }
-
- return ret;
-}
-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
*
--- /dev/null
+++ b/drivers/net/phy/phy_package.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * PHY package support
+ */
+
+#include <linux/of.h>
+#include <linux/phy.h>
+
+/**
+ * phy_package_join - join a common PHY group
+ * @phydev: target phy_device struct
+ * @base_addr: cookie and base PHY address of PHY package for offset
+ * calculation of global register access
+ * @priv_size: if non-zero allocate this amount of bytes for private data
+ *
+ * This joins a PHY group and provides a shared storage for all phydevs in
+ * this group. This is intended to be used for packages which contain
+ * more than one PHY, for example a quad PHY transceiver.
+ *
+ * The base_addr parameter serves as cookie which has to have the same values
+ * for all members of one group and as the base PHY address of the PHY package
+ * for offset calculation to access generic registers of a PHY package.
+ * Usually, one of the PHY addresses of the different PHYs in the package
+ * provides access to these global registers.
+ * The address which is given here, will be used in the phy_package_read()
+ * and phy_package_write() convenience functions as base and added to the
+ * passed offset in those functions.
+ *
+ * This will set the shared pointer of the phydev to the shared storage.
+ * If this is the first call for a this cookie the shared storage will be
+ * allocated. If priv_size is non-zero, the given amount of bytes are
+ * allocated for the priv member.
+ *
+ * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
+ * with the same cookie but a different priv_size is an error.
+ */
+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size)
+{
+ struct mii_bus *bus = phydev->mdio.bus;
+ struct phy_package_shared *shared;
+ int ret;
+
+ if (base_addr < 0 || base_addr >= PHY_MAX_ADDR)
+ return -EINVAL;
+
+ mutex_lock(&bus->shared_lock);
+ shared = bus->shared[base_addr];
+ if (!shared) {
+ ret = -ENOMEM;
+ shared = kzalloc(sizeof(*shared), GFP_KERNEL);
+ if (!shared)
+ goto err_unlock;
+ if (priv_size) {
+ shared->priv = kzalloc(priv_size, GFP_KERNEL);
+ if (!shared->priv)
+ goto err_free;
+ shared->priv_size = priv_size;
+ }
+ shared->base_addr = base_addr;
+ shared->np = NULL;
+ refcount_set(&shared->refcnt, 1);
+ bus->shared[base_addr] = shared;
+ } else {
+ ret = -EINVAL;
+ if (priv_size && priv_size != shared->priv_size)
+ goto err_unlock;
+ refcount_inc(&shared->refcnt);
+ }
+ mutex_unlock(&bus->shared_lock);
+
+ phydev->shared = shared;
+
+ return 0;
+
+err_free:
+ kfree(shared);
+err_unlock:
+ mutex_unlock(&bus->shared_lock);
+ return ret;
+}
+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
+ *
+ * This leaves a PHY group created by phy_package_join(). If this phydev
+ * was the last user of the shared data between the group, this data is
+ * freed. Resets the phydev->shared pointer to NULL.
+ */
+void phy_package_leave(struct phy_device *phydev)
+{
+ struct phy_package_shared *shared = phydev->shared;
+ struct mii_bus *bus = phydev->mdio.bus;
+
+ 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);
+ kfree(shared->priv);
+ kfree(shared);
+ }
+
+ phydev->shared = NULL;
+}
+EXPORT_SYMBOL_GPL(phy_package_leave);
+
+static void devm_phy_package_leave(struct device *dev, void *res)
+{
+ phy_package_leave(*(struct phy_device **)res);
+}
+
+/**
+ * devm_phy_package_join - resource managed phy_package_join()
+ * @dev: device that is registering this PHY package
+ * @phydev: target phy_device struct
+ * @base_addr: cookie and base PHY address of PHY package for offset
+ * calculation of global register access
+ * @priv_size: if non-zero allocate this amount of bytes for private data
+ *
+ * Managed phy_package_join(). Shared storage fetched by this function,
+ * phy_package_leave() is automatically called on driver detach. See
+ * phy_package_join() for more information.
+ */
+int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
+ int base_addr, 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 = phy_package_join(phydev, base_addr, priv_size);
+
+ if (!ret) {
+ *ptr = phydev;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return ret;
+}
+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);

View File

@ -0,0 +1,60 @@
From e9ee1dd2ff2c130b2fb2bd01936224a8a6b49a7e Mon Sep 17 00:00:00 2001
From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Mon, 3 Mar 2025 21:15:09 +0100
Subject: [PATCH] v6.15: net: phy: add getters for public members in struct
phy_package_shared
Add getters for public members, this prepares for making struct
phy_package_shared private to phylib. Declare the getters in a new header
file phylib.h, which will be used by PHY drivers only.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Link: https://patch.msgid.link/c6da0b27-4479-4717-9e16-643821b76bd8@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/phy_package.c | 14 ++++++++++++++
drivers/net/phy/phylib.h | 15 +++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 drivers/net/phy/phylib.h
--- a/drivers/net/phy/phy_package.c
+++ b/drivers/net/phy/phy_package.c
@@ -6,6 +6,20 @@
#include <linux/of.h>
#include <linux/phy.h>
+#include "phylib.h"
+
+struct device_node *phy_package_get_node(struct phy_device *phydev)
+{
+ return phydev->shared->np;
+}
+EXPORT_SYMBOL_GPL(phy_package_get_node);
+
+void *phy_package_get_priv(struct phy_device *phydev)
+{
+ return phydev->shared->priv;
+}
+EXPORT_SYMBOL_GPL(phy_package_get_priv);
+
/**
* phy_package_join - join a common PHY group
* @phydev: target phy_device struct
--- /dev/null
+++ b/drivers/net/phy/phylib.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * phylib header
+ */
+
+#ifndef __PHYLIB_H
+#define __PHYLIB_H
+
+struct device_node;
+struct phy_device;
+
+struct device_node *phy_package_get_node(struct phy_device *phydev);
+void *phy_package_get_priv(struct phy_device *phydev);
+
+#endif /* __PHYLIB_H */

View File

@ -1,4 +1,4 @@
From ae682f13d308682232069e5150e884fc10160598 Mon Sep 17 00:00:00 2001
From 7b1c4e22532ded6b20ee41936fa38b5ca1e61ff9 Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Mon, 29 Jan 2024 17:57:20 +0800
Subject: [PATCH] dt-bindings: net: Document Qualcomm QCA8084 PHY package
@ -17,16 +17,18 @@ also be integrated to the switch chip named as QCA8386.
Change-Id: Idb2338d2673152cbd3c57e95968faa59e9d4a80f
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Alex G: Update to match the patches that will be upstream.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
.../devicetree/bindings/net/qcom,qca8084.yaml | 198 ++++++++++++++++++
include/dt-bindings/net/qcom,qca808x.h | 14 ++
2 files changed, 212 insertions(+)
.../devicetree/bindings/net/qcom,qca8084.yaml | 488 ++++++++++++++++++
include/dt-bindings/net/qcom,qca808x.h | 14 +
2 files changed, 502 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/qcom,qca8084.yaml
create mode 100644 include/dt-bindings/net/qcom,qca808x.h
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/qcom,qca8084.yaml
@@ -0,0 +1,198 @@
@@ -0,0 +1,488 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
@ -39,8 +41,8 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ - Luo Jie <quic_luoj@quicinc.com>
+
+description:
+ Qualcomm QCA8084 is a four-port Ethernet transceiver, the
+ Ethernet port supports link speed 10/100/1000/2500 Mbps.
+ Qualcomm QCA8084 is PHY package of four-port Ethernet transceiver,
+ the Ethernet port supports link speed 10/100/1000/2500 Mbps.
+ There are two PCSes (PCS0 and PCS1) integrated in the PHY
+ package, PCS1 includes XPCS and PCS to support the interface
+ mode 10G-QXGMII and SGMII, PCS0 includes a PCS to support the
@ -63,7 +65,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ | | |
+ Ref 50M clk +--------+ | |
+ ------------>| | clk & rst | |
+ GPIO Reset |QCA8K_CC+------------+ |
+ GPIO Reset |QCA8K-CC+------------+ |
+ ------------>| | | |
+ +--------+ | |
+ | V |
@ -71,17 +73,15 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ | PHY0 | PHY1 | PHY2 | PHY3 |
+ +--------+--------+--------+--------+
+
+$ref: ethernet-phy-package.yaml#
+
+properties:
+ compatible:
+ const: qcom,qca8084-package
+
+ clocks:
+ description: PHY package level initial common clocks, which are
+ needed to be enabled after GPIO reset on the PHY package, these
+ clocks are supplied from the PHY integrated clock controller
+ (QCA8K-CC).
+ description:
+ PHY package level initial common clocks, which are needed to
+ be enabled after GPIO reset on the PHY package, these clocks
+ are supplied from the PHY integrated clock controller (QCA8K-CC).
+ items:
+ - description: APB bridge clock
+ - description: AHB clock
@ -102,10 +102,11 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ - const: mdio_ahb
+
+ resets:
+ description: PHY package level initial common reset, which are
+ needed to be deasserted after GPIO reset on the PHY package,
+ this reset is provided by the PHY integrated clock controller
+ to do PHY DSP reset.
+ description:
+ PHY package level initial common reset, which are needed to
+ be deasserted after GPIO reset on the PHY package, this reset
+ is provided by the PHY integrated clock controller to do PHY
+ DSP reset.
+ maxItems: 1
+
+ qcom,package-mode:
@ -130,30 +131,168 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ default: 0
+
+ qcom,phy-addr-fixup:
+ description: MDIO address for PHY0-PHY3, PCS0 and PCS1 including
+ PCS and XPCS, which can be optionally customized by programming
+ the security control register of PHY package. The hardware default
+ MDIO address of PHY0-PHY3, PCS0 and PCS1 including PCS and XPCS is
+ 0-6.
+ description:
+ MDIO address for PHY0-PHY3, PCS0 and PCS1 including PCS and XPCS,
+ which can be optionally customized by programming the security
+ control register of PHY package. The hardware default MDIO address
+ of PHY0-PHY3, PCS0 and PCS1 including PCS and XPCS is 0-6.
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ minItems: 7
+ maxItems: 7
+
+patternProperties:
+ ^ethernet-phy(@[a-f0-9]+)?$:
+ ^ethernet-phy@[a-f0-9]+$:
+ unevaluatedProperties: false
+ $ref: ethernet-phy.yaml#
+
+ properties:
+ compatible:
+ const: ethernet-phy-id004d.d180
+
+ qcom,xpcs-channel:
+ description:
+ When PCS1 works on the interface mode 10G-QXGMII, the integrated
+ XPCS including 4 channels is used to connected with the Quad PHYs,
+ each PHY needs to be specified the XPCS channel ID to deliver the
+ PHY link status to the XPCS.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3]
+
+ required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+
+ unevaluatedProperties: false
+ ^pcs-phy@[a-f0-9]+$:
+ type: object
+ additionalProperties: false
+ description:
+ PCS device has the independent MDIO address, which controls
+ the interface mode used and provides the clocks such as
+ 312.5 MHZ as RX and TX root clocks to the integrated clock
+ controller.
+ properties:
+ compatible:
+ const: qcom,qca8k-pcs-phy
+
+ reg:
+ items:
+ - description: PCS MDIO address.
+
+ clocks:
+ items:
+ - description: PCS clock.
+ - description: PCS RX root clock.
+ - description: PCS TX root clock.
+
+ clock-names:
+ items:
+ - const: pcs
+ - const: pcs_rx_root
+ - const: pcs_tx_root
+
+ resets:
+ items:
+ - description: PCS reset.
+
+ required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+
+ ^xpcs-phy@[a-f0-9]+$:
+ type: object
+ additionalProperties: false
+ description:
+ XPCS device has the independent MDIO address, which includes 4
+ channels to connect with Quad PHYs.
+ properties:
+ compatible:
+ const: qcom,qca8k-xpcs-phy
+
+ reg:
+ items:
+ - description: XPCS MDIO address.
+
+ resets:
+ items:
+ - description: XPCS reset.
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ required:
+ - compatible
+ - reg
+ - resets
+ - '#address-cells'
+ - '#size-cells'
+
+ patternProperties:
+ "^channel@[0-3]+$":
+ type: object
+ additionalProperties: false
+ description:
+ XPCS is used to support 10G-QXGMII mode, which inlcudes 4 channels
+ to be connected with Quad PHYs, each channels has the dedicated
+ clocks and resets from the integrated clock controller of QCA8084.
+
+ properties:
+ reg:
+ items:
+ - description: XPCS channel ID
+
+ clocks:
+ items:
+ - description: XPCS XGMII RX clock
+ - description: XPCS XGMII TX clock
+ - description: XPCS RX clock
+ - description: XPCS TX clock
+ - description: Port RX clock
+ - description: Port TX clock
+ - description: RX source clock
+ - description: TX source clock
+
+ clock-names:
+ items:
+ - const: xgmii_rx
+ - const: xgmii_tx
+ - const: xpcs_rx
+ - const: xpcs_tx
+ - const: port_rx
+ - const: port_tx
+ - const: rx_src
+ - const: tx_src
+
+ resets:
+ items:
+ - description: XPCS XGMII RX reset
+ - description: XPCS XGMII TX reset
+ - description: XPCS RX reset
+ - description: XPCS TX reset
+ - description: Port RX reset
+ - description: Port TX reset
+
+ reset-names:
+ items:
+ - const: xgmii_rx
+ - const: xgmii_tx
+ - const: xpcs_rx
+ - const: xpcs_tx
+ - const: port_rx
+ - const: port_tx
+
+ required:
+ - reg
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+required:
+ - compatible
@ -161,6 +300,9 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ - clock-names
+ - resets
+
+allOf:
+ - $ref: ethernet-phy-package.yaml#
+
+unevaluatedProperties: false
+
+examples:
@ -193,7 +335,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ "cnoc_ahb",
+ "mdio_ahb";
+ resets = <&qca8k_nsscc NSS_CC_GEPHY_FULL_ARES>;
+ qcom,package-mode = <QCA808X_PCS1_SGMII_MAC_PCS0_SGMII_MAC>;
+ qcom,package-mode = <QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED>;
+ qcom,phy-addr-fixup = <1 2 3 4 5 6 7>;
+
+ ethernet-phy@1 {
@ -201,6 +343,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ reg = <1>;
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_CLK>;
+ resets = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_ARES>;
+ qcom,xpcs-channel = <0>;
+ };
+
+ ethernet-phy@2 {
@ -208,6 +351,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ reg = <2>;
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_CLK>;
+ resets = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_ARES>;
+ qcom,xpcs-channel = <1>;
+ };
+
+ ethernet-phy@3 {
@ -215,6 +359,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ reg = <3>;
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_CLK>;
+ resets = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_ARES>;
+ qcom,xpcs-channel = <2>;
+ };
+
+ ethernet-phy@4 {
@ -222,6 +367,153 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ reg = <4>;
+ clocks = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_CLK>;
+ resets = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_ARES>;
+ qcom,xpcs-channel = <3>;
+ };
+
+ pcs-phy@6 {
+ compatible = "qcom,qca8k-pcs-phy";
+ reg = <6>;
+ clocks = <&qca8k_nsscc NSS_CC_SRDS1_SYS_CLK>,
+ <&qca8k_uniphy1_tx312p5m>,
+ <&qca8k_uniphy1_rx312p5m>;
+ clock-names = "pcs", "pcs_rx_root", "pcs_tx_root";
+ resets = <&qca8k_nsscc NSS_CC_SRDS1_SYS_ARES>;
+ };
+
+ xpcs-phy@7 {
+ compatible = "qcom,qca8k-xpcs-phy";
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ resets = <&qca8k_nsscc NSS_CC_XPCS_ARES>;
+
+ channel@0 {
+ reg = <0>;
+ clocks = <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC1_RX_CLK_SRC>,
+ <&qca8k_nsscc NSS_CC_MAC1_TX_CLK_SRC>;
+ clock-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx",
+ "rx_src",
+ "tx_src";
+ resets = <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_XGMII_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC1_SRDS1_CH0_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC1_GEPHY0_TX_ARES>;
+ reset-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx";
+ };
+
+ channel@1 {
+ reg = <1>;
+ clocks = <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC2_RX_CLK_SRC>,
+ <&qca8k_nsscc NSS_CC_MAC2_TX_CLK_SRC>;
+ clock-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx",
+ "rx_src",
+ "tx_src";
+ resets = <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_XGMII_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC2_SRDS1_CH1_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC2_GEPHY1_TX_ARES>;
+ reset-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx";
+ };
+
+ channel@2 {
+ reg = <2>;
+ clocks = <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC3_RX_CLK_SRC>,
+ <&qca8k_nsscc NSS_CC_MAC3_TX_CLK_SRC>;
+ clock-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx",
+ "rx_src",
+ "tx_src";
+ resets = <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_XGMII_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC3_SRDS1_CH2_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC3_GEPHY2_TX_ARES>;
+ reset-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx";
+ };
+
+ channel@3 {
+ reg = <3>;
+ clocks = <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_RX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_TX_CLK>,
+ <&qca8k_nsscc NSS_CC_MAC4_RX_CLK_SRC>,
+ <&qca8k_nsscc NSS_CC_MAC4_TX_CLK_SRC>;
+ clock-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx",
+ "rx_src",
+ "tx_src";
+ resets = <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_XGMII_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_TX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC4_SRDS1_CH3_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_RX_ARES>,
+ <&qca8k_nsscc NSS_CC_MAC4_GEPHY3_TX_ARES>;
+ reset-names = "xgmii_rx",
+ "xgmii_tx",
+ "xpcs_rx",
+ "xpcs_tx",
+ "port_rx",
+ "port_tx";
+ };
+ };
+ };
+ };

View File

@ -1,4 +1,4 @@
From 816bff9bcd2ff7c1e84dd14fc81c9c1bdaa609e7 Mon Sep 17 00:00:00 2001
From 60c44842f9611be237ab3f68afe8ebf2d9595fb2 Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Thu, 6 Apr 2023 18:09:07 +0800
Subject: [PATCH] net: phy: qca808x: Add QCA8084 ethernet phy support
@ -20,9 +20,11 @@ with QCA8081.
Change-Id: I12555fa70662682474ab4432204405b5e752fef6
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Alex G: Update to match the patches that will be upstream.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/net/phy/qcom/qca808x.c | 62 ++++++++++++++++++++++++++++++++--
1 file changed, 60 insertions(+), 2 deletions(-)
drivers/net/phy/qcom/qca808x.c | 65 ++++++++++++++++++++++++++++++++--
1 file changed, 63 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@ -44,7 +46,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
MODULE_LICENSE("GPL");
struct qca808x_priv {
@@ -153,7 +160,9 @@ static bool qca808x_is_prefer_master(str
@@ -153,13 +160,18 @@ static bool qca808x_is_prefer_master(str
static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
{
@ -55,7 +57,16 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
}
static bool qca808x_is_1g_only(struct phy_device *phydev)
@@ -273,6 +282,23 @@ static int qca808x_read_status(struct ph
{
int ret;
+ if (!phydev_id_compare(phydev, QCA8081_PHY_ID))
+ return false;
+
ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE);
if (ret < 0)
return true;
@@ -273,6 +285,23 @@ static int qca808x_read_status(struct ph
return ret;
if (phydev->link) {
@ -79,7 +90,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
if (phydev->speed == SPEED_2500)
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
else
@@ -352,6 +378,18 @@ static int qca808x_cable_test_start(stru
@@ -352,6 +381,18 @@ static int qca808x_cable_test_start(stru
phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
@ -98,7 +109,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
return 0;
}
@@ -651,12 +689,32 @@ static struct phy_driver qca808x_driver[
@@ -651,12 +692,32 @@ static struct phy_driver qca808x_driver[
.led_hw_control_set = qca808x_led_hw_control_set,
.led_hw_control_get = qca808x_led_hw_control_get,
.led_polarity_set = qca808x_led_polarity_set,

View File

@ -1,4 +1,4 @@
From 5a57611512593212b7fd9c23b4d96486bab6dee3 Mon Sep 17 00:00:00 2001
From c052b9a4ab869cc54976402b3f9dbdef5bdb9f27 Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Wed, 8 Nov 2023 16:18:02 +0800
Subject: [PATCH] net: phy: qca808x: Add config_init function for QCA8084
@ -40,7 +40,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
MODULE_LICENSE("GPL");
@@ -660,6 +669,34 @@ static int qca808x_led_polarity_set(stru
@@ -663,6 +672,34 @@ static int qca808x_led_polarity_set(stru
active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
}
@ -75,7 +75,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
static struct phy_driver qca808x_driver[] = {
{
/* Qualcomm QCA8081 */
@@ -708,6 +745,7 @@ static struct phy_driver qca808x_driver[
@@ -711,6 +748,7 @@ static struct phy_driver qca808x_driver[
.soft_reset = qca808x_soft_reset,
.cable_test_start = qca808x_cable_test_start,
.cable_test_get_status = qca808x_cable_test_get_status,

View File

@ -1,4 +1,4 @@
From d1f2a1810af1833196934977f57607432fda46b4 Mon Sep 17 00:00:00 2001
From aec49c172cd9c739c1d97ff2d42b9718bb20b609 Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Wed, 8 Nov 2023 18:01:14 +0800
Subject: [PATCH] net: phy: qca808x: Add link_change_notify function for
@ -30,7 +30,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
MODULE_LICENSE("GPL");
@@ -697,6 +705,49 @@ static int qca8084_config_init(struct ph
@@ -700,6 +708,49 @@ static int qca8084_config_init(struct ph
QCA8084_MSE_THRESHOLD_2P5G_VAL);
}
@ -80,7 +80,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
static struct phy_driver qca808x_driver[] = {
{
/* Qualcomm QCA8081 */
@@ -746,6 +797,7 @@ static struct phy_driver qca808x_driver[
@@ -749,6 +800,7 @@ static struct phy_driver qca808x_driver[
.cable_test_start = qca808x_cable_test_start,
.cable_test_get_status = qca808x_cable_test_get_status,
.config_init = qca8084_config_init,

View File

@ -1,4 +1,4 @@
From c17f19be3bec0bf5467f4e14a21573836910f671 Mon Sep 17 00:00:00 2001
From cea8043def0c0867370c2efd5a1cd73bf4d3e5ba Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Wed, 29 Nov 2023 15:21:22 +0800
Subject: [PATCH] net: phy: qca808x: Add register access support routines for

View File

@ -1,4 +1,4 @@
From 485f973c5b1d889bd1f48a188137d80d45004991 Mon Sep 17 00:00:00 2001
From a7fe2c13f3188bf01b60fb15063d028c76dd2f1a Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Mon, 29 Jan 2024 10:51:38 +0800
Subject: [PATCH] net: phy: qca808x: Add QCA8084 probe function
@ -13,22 +13,45 @@ accessed, and the features of PHY can be acquired.
Change-Id: I2251b9c5c398a21a4ef547a727189a934ad3a44c
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
drivers/net/phy/qcom/qca808x.c | 91 ++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
Alex G: include <linux/reset.h>
include "phylib.h" for phy_package_*() declarations
select PHY_PACKAGE in Kconfig
use phy_package_get_node() instead of phylib->shared->np
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
freckup c89414adf2ec7c
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/net/phy/qcom/Kconfig | 1 +
drivers/net/phy/qcom/qca808x.c | 92 ++++++++++++++++++++++++++++++++++
2 files changed, 93 insertions(+)
--- a/drivers/net/phy/qcom/Kconfig
+++ b/drivers/net/phy/qcom/Kconfig
@@ -18,6 +18,7 @@ config QCA83XX_PHY
config QCA808X_PHY
tristate "Qualcomm QCA808x PHYs"
select QCOM_NET_PHYLIB
+ select PHY_PACKAGE
help
Currently supports the QCA8081 model
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@@ -2,6 +2,8 @@
@@ -2,7 +2,11 @@
#include <linux/phy.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include "../phylib.h"
#include "qcom.h"
@@ -127,6 +129,21 @@
/* ADC threshold */
@@ -127,6 +131,21 @@
#define QCA8084_MII_SW_ADDR_MASK GENMASK(31, 24)
#define QCA8084_MII_REG_DATA_UPPER_16_BITS BIT(1)
@ -50,21 +73,20 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
MODULE_LICENSE("GPL");
@@ -836,6 +853,79 @@ static void qca8084_link_change_notify(s
@@ -839,6 +858,78 @@ static void qca8084_link_change_notify(s
QCA8084_IPG_10_TO_11_EN : 0);
}
+static int qca8084_phy_package_probe_once(struct phy_device *phydev)
+{
+ int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
+ struct phy_package_shared *shared = phydev->shared;
+ struct device_node *np = phy_package_get_node(phydev);
+ int ret, clear, set;
+
+ /* Program the MDIO address of PHY and PCS optionally, the MDIO
+ * address 0-6 is used for PHY and PCS MDIO devices by default.
+ */
+ ret = of_property_read_u32_array(shared->np,
+ "qcom,phy-addr-fixup",
+ ret = of_property_read_u32_array(np, "qcom,phy-addr-fixup",
+ addr, ARRAY_SIZE(addr));
+ if (ret && ret != -EINVAL)
+ return ret;
@ -130,7 +152,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
static struct phy_driver qca808x_driver[] = {
{
/* Qualcomm QCA8081 */
@@ -886,6 +976,7 @@ static struct phy_driver qca808x_driver[
@@ -889,6 +980,7 @@ static struct phy_driver qca808x_driver[
.cable_test_get_status = qca808x_cable_test_get_status,
.config_init = qca8084_config_init,
.link_change_notify = qca8084_link_change_notify,

View File

@ -1,4 +1,4 @@
From 685566f8b765f522b7f4d4deb06bf84a557dc4ac Mon Sep 17 00:00:00 2001
From 57379fe257895b374d35ce6578ecd62ce1cc1a4d Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Tue, 9 Apr 2024 16:30:55 +0800
Subject: [PATCH] net: phy: qca808x: Add package clocks and resets for QCA8084
@ -12,21 +12,16 @@ the PHY registers.
Change-Id: I254d0aa0a1155d3618c6f1fc7d7a5b6ecadccbaa
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Alex G: Use accessors for struct phy_package_shared
Update to match the patches that will be upstream.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/net/phy/qcom/qca808x.c | 67 ++++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 3 deletions(-)
drivers/net/phy/qcom/qca808x.c | 74 ++++++++++++++++++++++++++++++++--
1 file changed, 71 insertions(+), 3 deletions(-)
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/clk.h>
+#include <linux/reset.h>
#include "qcom.h"
@@ -148,10 +149,35 @@ MODULE_DESCRIPTION("Qualcomm Atheros QCA
@@ -150,10 +150,39 @@ MODULE_DESCRIPTION("Qualcomm Atheros QCA
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
MODULE_LICENSE("GPL");
@ -38,6 +33,8 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ TLMM_AHB_CLK,
+ CNOC_AHB_CLK,
+ MDIO_AHB_CLK,
+ MDIO_MASTER_AHB_CLK,
+ SWITCH_CORE_CLK,
+ PACKAGE_CLK_MAX
+};
+
@ -57,12 +54,14 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ [TLMM_AHB_CLK] = "tlmm_ahb",
+ [CNOC_AHB_CLK] = "cnoc_ahb",
+ [MDIO_AHB_CLK] = "mdio_ahb",
+ [MDIO_MASTER_AHB_CLK] = "mdio_master_ahb",
+ [SWITCH_CORE_CLK] = "switch_core",
+};
+
static int __qca8084_set_page(struct mii_bus *bus, u16 sw_addr, u16 page)
{
return __mdiobus_write(bus, QCA8084_HIGH_ADDR_PREFIX | (sw_addr >> 5),
@@ -853,11 +879,24 @@ static void qca8084_link_change_notify(s
@@ -858,11 +887,24 @@ static void qca8084_link_change_notify(s
QCA8084_IPG_10_TO_11_EN : 0);
}
@ -79,7 +78,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
static int qca8084_phy_package_probe_once(struct phy_device *phydev)
{
int addr[QCA8084_MDIO_DEVICE_NUM] = {0, 1, 2, 3, 4, 5, 6};
struct phy_package_shared *shared = phydev->shared;
struct device_node *np = phy_package_get_node(phydev);
- int ret, clear, set;
+ struct qca808x_shared_priv *shared_priv;
+ struct reset_control *rstc;
@ -88,7 +87,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
/* Program the MDIO address of PHY and PCS optionally, the MDIO
* address 0-6 is used for PHY and PCS MDIO devices by default.
@@ -889,17 +928,39 @@ static int qca8084_phy_package_probe_onc
@@ -893,17 +935,43 @@ static int qca8084_phy_package_probe_onc
set |= FIELD_PREP(QCA8084_PCS_ADDR1_MASK, addr[5]);
set |= FIELD_PREP(QCA8084_PCS_ADDR2_MASK, addr[6]);
@ -97,18 +96,22 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ if (ret)
+ return ret;
+
+ shared_priv = shared->priv;
+ shared_priv = phy_package_get_priv(phydev);
+ for (i = 0; i < ARRAY_SIZE(qca8084_package_clk_name); i++) {
+ clk = of_clk_get_by_name(shared->np,
+ qca8084_package_clk_name[i]);
+ if (IS_ERR(clk))
+ return dev_err_probe(&phydev->mdio.dev, PTR_ERR(clk),
+ "package clock %s not ready\n",
+ qca8084_package_clk_name[i]);
+ clk = of_clk_get_by_name(np, qca8084_package_clk_name[i]);
+ if (IS_ERR(clk)) {
+ if (PTR_ERR(clk) == -EINVAL)
+ clk = NULL;
+ else
+ return dev_err_probe(&phydev->mdio.dev, PTR_ERR(clk),
+ "package clock %s not ready\n",
+ qca8084_package_clk_name[i]);
+ }
+
+ shared_priv->clk[i] = clk;
+ }
+
+ rstc = of_reset_control_get_exclusive(shared->np, NULL);
+ rstc = of_reset_control_get_exclusive(np, NULL);
+ if (IS_ERR(rstc))
+ return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
+ "package reset not ready\n");

View File

@ -1,4 +1,4 @@
From bf779b10b00fd79267d0ef625ae246df59ee23bd Mon Sep 17 00:00:00 2001
From d39dc53424bcc778f1e468015490577e7bf0c7b6 Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Thu, 25 Jan 2024 17:13:24 +0800
Subject: [PATCH] net: phy: qca808x: Add QCA8084 package init function
@ -10,9 +10,12 @@ The PHY package level clocks are enabled and their rates configured.
Change-Id: I63d4b22d2a70ee713cc6a6818b0f3c7aa098a5f5
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Alex G: Use phy_package_get_*() accessors
Update to match the patches that will be upstream.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/net/phy/qcom/qca808x.c | 115 +++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
drivers/net/phy/qcom/qca808x.c | 118 +++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@ -23,21 +26,20 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
#include <linux/phy.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -145,6 +146,13 @@
@@ -146,6 +147,12 @@
#define QCA8084_EPHY_ADDR3_MASK GENMASK(19, 15)
#define QCA8084_EPHY_LDO_EN GENMASK(21, 20)
+#define QCA8084_WORK_MODE_CFG 0xc90f030
+#define QCA8084_WORK_MODE_MASK GENMASK(5, 0)
+#define QCA8084_WORK_MODE_QXGMII (BIT(5) | GENMASK(3, 0))
+#define QCA8084_WORK_MODE_QXGMII_PORT4_SGMII (BIT(5) | GENMASK(2, 0))
+#define QCA8084_WORK_MODE_SWITCH BIT(4)
+#define QCA8084_WORK_MODE_SWITCH_PORT4_SGMII BIT(5)
+
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi, Luo Jie");
MODULE_LICENSE("GPL");
@@ -165,6 +173,7 @@ struct qca808x_priv {
@@ -168,6 +175,7 @@ struct qca808x_priv {
};
struct qca808x_shared_priv {
@ -45,7 +47,7 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
struct clk *clk[PACKAGE_CLK_MAX];
};
@@ -808,10 +817,107 @@ static int qca808x_led_polarity_set(stru
@@ -816,10 +824,111 @@ static int qca808x_led_polarity_set(stru
active_low ? 0 : QCA808X_LED_ACTIVE_HIGH);
}
@ -60,6 +62,10 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(shared_priv->clk[SWITCH_CORE_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(shared_priv->clk[APB_BRIDGE_CLK]);
+ if (ret)
+ return ret;
@ -91,16 +97,19 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(shared_priv->clk[MDIO_MASTER_AHB_CLK]);
+ if (ret)
+ return ret;
+
+ return clk_prepare_enable(shared_priv->clk[MDIO_AHB_CLK]);
+}
+
+static int qca8084_phy_package_config_init_once(struct phy_device *phydev)
+{
+ struct phy_package_shared *shared = phydev->shared;
+ struct qca808x_shared_priv *shared_priv;
+ int ret, mode;
+
+ shared_priv = shared->priv;
+ shared_priv = phy_package_get_priv(phydev);
+ switch (shared_priv->package_mode) {
+ case QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED:
+ mode = QCA8084_WORK_MODE_QXGMII;
@ -123,13 +132,6 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ if (ret)
+ return ret;
+
+ /* Initialize the PHY package clock and reset, which is the
+ * necessary config sequence after GPIO reset on the PHY package.
+ */
+ ret = qca8084_package_clock_init(shared_priv);
+ if (ret)
+ return ret;
+
+ /* Enable efuse loading into analog circuit */
+ ret = qca8084_mii_modify(phydev, QCA8084_EPHY_CFG,
+ QCA8084_EPHY_LDO_EN, 0);
@ -137,7 +139,11 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
+ return ret;
+
+ usleep_range(10000, 11000);
+ return ret;
+
+ /* Initialize the PHY package clock and reset, which is the
+ * necessary config sequence after GPIO reset on the PHY package.
+ */
+ return qca8084_package_clock_init(shared_priv);
+}
+
static int qca8084_config_init(struct phy_device *phydev)
@ -153,19 +159,19 @@ Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
__set_bit(PHY_INTERFACE_MODE_10G_QXGMII,
phydev->possible_interfaces);
@@ -948,6 +1054,15 @@ static int qca8084_phy_package_probe_onc
return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
"package reset not ready\n");
@@ -954,6 +1063,15 @@ static int qca8084_phy_package_probe_onc
shared_priv->clk[i] = clk;
}
+ /* The package mode 10G-QXGMII of PCS1 is used for Quad PHY and
+ * PCS0 is unused by default.
+ */
+ shared_priv->package_mode = QCA808X_PCS1_10G_QXGMII_PCS0_UNUNSED;
+ ret = of_property_read_u32(shared->np, "qcom,package-mode",
+ ret = of_property_read_u32(np, "qcom,package-mode",
+ &shared_priv->package_mode);
+ if (ret && ret != -EINVAL)
+ return ret;
+
/* Deassert PHY package. */
return reset_control_deassert(rstc);
}
rstc = of_reset_control_get_exclusive(np, NULL);
if (IS_ERR(rstc))
return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),

View File

@ -0,0 +1,36 @@
From d11eba3e178a9d42a579c656b2c9b643f4ce3e1e Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Mon, 23 Sep 2024 18:46:34 +0800
Subject: [PATCH] net: phy: Add phy_package_remove_once helper
QCA8084 PHY package needs to do the PHY package clean up,
add phy_package_remove_once helper to support.
Change-Id: I3cd73bc7be1b1d531435ef72f48db0682548decf
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
include/linux/phy.h | 6 ++++++
1 file changed, 6 insertions(+)
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -366,6 +366,7 @@ struct phy_package_shared {
/* used as bit number in atomic bitops */
#define PHY_SHARED_F_INIT_DONE 0
#define PHY_SHARED_F_PROBE_DONE 1
+#define PHY_SHARED_F_REMOVE_DONE 2
/**
* struct mii_bus - Represents an MDIO bus
@@ -2245,6 +2246,11 @@ static inline bool phy_package_probe_onc
return __phy_package_set_once(phydev, PHY_SHARED_F_PROBE_DONE);
}
+static inline bool phy_package_remove_once(struct phy_device *phydev)
+{
+ return __phy_package_set_once(phydev, PHY_SHARED_F_REMOVE_DONE);
+}
+
extern const struct bus_type mdio_bus_type;
struct mdio_board_info {

View File

@ -0,0 +1,437 @@
From c12b79af730116936504afe97234f9afb6ac8fc0 Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Mon, 23 Sep 2024 20:28:24 +0800
Subject: [PATCH] net: phy: qca808x: Add QCA8084 SerDes probe and remove
functions
QCA8084 PHY package integrates the XPCS and PCS, which is used
to support 10G-QXGMII. XPCS includes 4 channels to connect with
Quad PHY, and PCS controls the interface mode configured.
XPCS and PCS are probed and removed by PHY package.
Change-Id: Ided0a5cd4c996dc2a2a0d0598e930fab060caaf8
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Alex G: Use phy_package_get_*() accessors
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/net/phy/qcom/Makefile | 2 +-
drivers/net/phy/qcom/qca8084_serdes.c | 249 ++++++++++++++++++++++++++
drivers/net/phy/qcom/qca8084_serdes.h | 18 ++
drivers/net/phy/qcom/qca808x.c | 53 ++++++
4 files changed, 321 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/phy/qcom/qca8084_serdes.c
create mode 100644 drivers/net/phy/qcom/qca8084_serdes.h
--- a/drivers/net/phy/qcom/Makefile
+++ b/drivers/net/phy/qcom/Makefile
@@ -2,5 +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_QCA808X_PHY) += qca808x.o
+obj-$(CONFIG_QCA808X_PHY) += qca808x.o qca8084_serdes.o
obj-$(CONFIG_QCA807X_PHY) += qca807x.o
--- /dev/null
+++ b/drivers/net/phy/qcom/qca8084_serdes.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/dev_printk.h>
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/phy.h>
+#include <linux/property.h>
+#include <linux/reset.h>
+
+#include "qca8084_serdes.h"
+
+/* XPCS includes 4 channels, each channel has the different MMD ID for
+ * configuring auto-negotiation complete interrupt, mii-4bit, auto-
+ * negotiation capabilities and TX configuration for the connected PHY.
+ *
+ * MMD31 is for channel 0;
+ * MMD26 is for channel 1;
+ * MMD27 is for channel 2;
+ * MMD28 is for channel 3;
+ */
+#define QCA8084_CHANNEL_MAX 4
+
+enum pcs_clk_id {
+ PCS_CLK,
+ PCS_RX_ROOT_CLK,
+ PCS_TX_ROOT_CLK,
+ PCS_CLK_MAX
+};
+
+enum xpcs_clk_id {
+ XPCS_XGMII_RX_CLK,
+ XPCS_XGMII_TX_CLK,
+ XPCS_RX_CLK,
+ XPCS_TX_CLK,
+ XPCS_PORT_RX_CLK,
+ XPCS_PORT_TX_CLK,
+ XPCS_RX_SRC_CLK,
+ XPCS_TX_SRC_CLK,
+ XPCS_CLK_MAX
+};
+
+struct qca8084_xpcs_channel_priv {
+ int ch_id;
+ struct reset_control *rstcs;
+ struct clk *clks[XPCS_CLK_MAX];
+};
+
+struct qca8084_pcs_data {
+ struct reset_control *rstc;
+ struct clk *clks[PCS_CLK_MAX];
+};
+
+struct qca8084_xpcs_data {
+ struct reset_control *rstc;
+ struct qca8084_xpcs_channel_priv xpcs_ch[QCA8084_CHANNEL_MAX];
+};
+
+static const char *const xpcs_clock_names[XPCS_CLK_MAX] = {
+ [XPCS_XGMII_RX_CLK] = "xgmii_rx",
+ [XPCS_XGMII_TX_CLK] = "xgmii_tx",
+ [XPCS_RX_CLK] = "xpcs_rx",
+ [XPCS_TX_CLK] = "xpcs_tx",
+ [XPCS_PORT_RX_CLK] = "port_rx",
+ [XPCS_PORT_TX_CLK] = "port_tx",
+ [XPCS_RX_SRC_CLK] = "rx_src",
+ [XPCS_TX_SRC_CLK] = "tx_src",
+};
+
+static const char *const pcs_clock_names[PCS_CLK_MAX] = {
+ [PCS_CLK] = "pcs",
+ [PCS_RX_ROOT_CLK] = "pcs_rx_root",
+ [PCS_TX_ROOT_CLK] = "pcs_tx_root",
+};
+
+struct mdio_device *qca8084_package_pcs_probe(struct device_node *pcs_np)
+{
+ struct qca8084_pcs_data *pcs_data;
+ struct mdio_device *mdiodev;
+ struct reset_control *rstc;
+ struct device *dev;
+ struct clk *clk;
+ int i;
+
+ mdiodev = fwnode_mdio_find_device(of_fwnode_handle(pcs_np));
+ if (!mdiodev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ dev = &mdiodev->dev;
+ pcs_data = devm_kzalloc(dev, sizeof(*pcs_data), GFP_KERNEL);
+ if (!pcs_data) {
+ dev_err(dev, "Allocate PCS data failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ rstc = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(rstc)) {
+ dev_err(dev, "Get PCS reset failed\n");
+ return ERR_CAST(rstc);
+ }
+
+ pcs_data->rstc = rstc;
+
+ for (i = 0; i < ARRAY_SIZE(pcs_clock_names); i++) {
+ clk = devm_clk_get(dev, pcs_clock_names[i]);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "Failed to get the PCS clock ID %s\n",
+ pcs_clock_names[i]);
+ return ERR_CAST(clk);
+ }
+ pcs_data->clks[i] = clk;
+ }
+
+ mdiodev_set_drvdata(mdiodev, pcs_data);
+
+ return mdiodev;
+}
+
+struct mdio_device *qca8084_package_xpcs_probe(struct device_node *xpcs_np)
+{
+ struct qca8084_xpcs_data *xpcs_data;
+ struct mdio_device *mdiodev;
+ struct reset_control *rstc;
+ struct device_node *child;
+ struct device *dev;
+ struct clk *clk;
+ int i, j, node;
+
+ mdiodev = fwnode_mdio_find_device(of_fwnode_handle(xpcs_np));
+ if (!mdiodev)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ dev = &mdiodev->dev;
+
+ xpcs_data = devm_kzalloc(dev, sizeof(*xpcs_data), GFP_KERNEL);
+ if (!xpcs_data) {
+ dev_err(dev, "Allocate XPCS data failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ rstc = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(rstc)) {
+ dev_err(dev, "Get XPCS reset failed\n");
+ return ERR_CAST(rstc);
+ }
+
+ xpcs_data->rstc = rstc;
+
+ /* Sanity check the number of channel sub nodes */
+ node = of_get_available_child_count(xpcs_np);
+ if (node != QCA8084_CHANNEL_MAX)
+ return ERR_PTR(-EINVAL);
+
+ node = 0;
+ for_each_available_child_of_node(xpcs_np, child) {
+ struct qca8084_xpcs_channel_priv *ch_data;
+ u32 channel;
+
+ /* The subnode name must be 'channel'. */
+ if (!(of_node_name_eq(child, "channel")))
+ continue;
+
+ if (of_property_read_u32(child, "reg", &channel)) {
+ dev_err(dev, "%s: Failed to get reg\n",
+ child->full_name);
+
+ mdiodev = ERR_PTR(-EINVAL);
+ goto put_ch_clk_rst;
+ }
+
+ if (channel >= QCA8084_CHANNEL_MAX) {
+ dev_err(dev, "%s: Invalid reg %d\n",
+ child->full_name, channel);
+
+ mdiodev = ERR_PTR(-EINVAL);
+ goto put_ch_clk_rst;
+ }
+
+ ch_data = &xpcs_data->xpcs_ch[node];
+ ch_data->ch_id = channel;
+
+ ch_data->rstcs = of_reset_control_array_get_exclusive(child);
+ if (IS_ERR(ch_data->rstcs)) {
+ dev_err(dev, "%s: Failed to get reset\n",
+ child->full_name);
+
+ mdiodev = ERR_CAST(ch_data->rstcs);
+ goto put_ch_clk_rst;
+ }
+
+ for (j = 0; j < ARRAY_SIZE(xpcs_clock_names); j++) {
+ clk = of_clk_get_by_name(child, xpcs_clock_names[j]);
+ if (IS_ERR(clk)) {
+ dev_err(dev, "Failed to get the clock ID %s\n",
+ xpcs_clock_names[j]);
+ mdiodev = ERR_CAST(clk);
+ goto put_ch_child;
+ }
+ ch_data->clks[j] = clk;
+ }
+
+ node++;
+ }
+
+ mdiodev_set_drvdata(mdiodev, xpcs_data);
+
+ return mdiodev;
+
+put_ch_child:
+ node++;
+
+put_ch_clk_rst:
+ for (i = 0; i < node; i++) {
+ j--;
+ while (j >= 0) {
+ clk_put(xpcs_data->xpcs_ch[i].clks[j]);
+ j--;
+ }
+
+ j = ARRAY_SIZE(xpcs_clock_names);
+ }
+
+ for (i = 0; i < node; i++)
+ reset_control_put(xpcs_data->xpcs_ch[i].rstcs);
+
+ of_node_put(child);
+
+ return mdiodev;
+}
+
+void qca8084_package_xpcs_and_pcs_remove(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev)
+{
+ struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(xpcs_data->xpcs_ch); i++) {
+ reset_control_put(xpcs_data->xpcs_ch[i].rstcs);
+
+ for (j = 0; j < ARRAY_SIZE(xpcs_data->xpcs_ch[i].clks); j++)
+ clk_put(xpcs_data->xpcs_ch[i].clks[j]);
+ }
+
+ mdio_device_put(xpcs_mdiodev);
+ mdio_device_put(pcs_mdiodev);
+}
--- /dev/null
+++ b/drivers/net/phy/qcom/qca8084_serdes.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for QCA8084 SerDes
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCA8084_SERDES_H_
+#define _QCA8084_SERDES_H_
+
+#include <linux/mdio.h>
+#include <linux/of.h>
+
+struct mdio_device *qca8084_package_pcs_probe(struct device_node *pcs_np);
+struct mdio_device *qca8084_package_xpcs_probe(struct device_node *xpcs_np);
+void qca8084_package_xpcs_and_pcs_remove(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev);
+#endif /* _QCA8084_SERDES_H_ */
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@@ -8,6 +8,7 @@
#include <linux/clk.h>
#include "../phylib.h"
+#include "qca8084_serdes.h"
#include "qcom.h"
/* ADC threshold */
@@ -172,11 +173,13 @@ enum {
struct qca808x_priv {
int led_polarity_mode;
+ int channel_id;
};
struct qca808x_shared_priv {
int package_mode;
struct clk *clk[PACKAGE_CLK_MAX];
+ struct mdio_device *mdiodev[2]; /* PCS and XPCS mdio device */
};
static const char *const qca8084_package_clk_name[PACKAGE_CLK_MAX] = {
@@ -354,6 +357,8 @@ static int qca808x_probe(struct phy_devi
{
struct device *dev = &phydev->mdio.dev;
struct qca808x_priv *priv;
+ u32 ch_id = 0;
+ int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -362,6 +367,14 @@ static int qca808x_probe(struct phy_devi
/* Init LED polarity mode to -1 */
priv->led_polarity_mode = -1;
+ /* DT property qcom,xpcs-channel" is optional and only available for
+ * 10G-QXGMII mode.
+ */
+ ret = of_property_read_u32(dev->of_node, "qcom,xpcs-channel", &ch_id);
+ if (ret && ret != -EINVAL)
+ return ret;
+
+ priv->channel_id = ch_id;
phydev->priv = priv;
return 0;
@@ -1012,6 +1025,7 @@ static int qca8084_phy_package_probe_onc
struct device_node *np = phy_package_get_node(phydev);
struct qca808x_shared_priv *shared_priv;
struct reset_control *rstc;
+ struct device_node *child;
int i, ret, clear, set;
struct clk *clk;
@@ -1072,6 +1086,26 @@ static int qca8084_phy_package_probe_onc
if (ret && ret != -EINVAL)
return ret;
+ for_each_available_child_of_node(np, child) {
+ struct mdio_device *mdiodev;
+
+ if (of_node_name_eq(child, "pcs-phy")) {
+ mdiodev = qca8084_package_pcs_probe(child);
+ if (IS_ERR(mdiodev))
+ return PTR_ERR(mdiodev);
+
+ shared_priv->mdiodev[0] = mdiodev;
+ }
+
+ if (of_node_name_eq(child, "xpcs-phy")) {
+ mdiodev = qca8084_package_xpcs_probe(child);
+ if (IS_ERR(mdiodev))
+ return PTR_ERR(mdiodev);
+
+ shared_priv->mdiodev[1] = mdiodev;
+ }
+ }
+
rstc = of_reset_control_get_exclusive(np, NULL);
if (IS_ERR(rstc))
return dev_err_probe(&phydev->mdio.dev, PTR_ERR(rstc),
@@ -1081,6 +1115,14 @@ static int qca8084_phy_package_probe_onc
return reset_control_deassert(rstc);
}
+static void qca8084_phy_package_remove_once(struct phy_device *phydev)
+{
+ struct qca808x_shared_priv *shared_priv = phy_package_get_priv(phydev);;
+
+ qca8084_package_xpcs_and_pcs_remove(shared_priv->mdiodev[1],
+ shared_priv->mdiodev[0]);
+}
+
static int qca8084_probe(struct phy_device *phydev)
{
struct qca808x_shared_priv *shared_priv;
@@ -1099,6 +1141,10 @@ static int qca8084_probe(struct phy_devi
return ret;
}
+ ret = qca808x_probe(phydev);
+ if (ret)
+ return ret;
+
/* Enable clock of PHY device, so that the PHY register
* can be accessed to get PHY features.
*/
@@ -1116,6 +1162,12 @@ static int qca8084_probe(struct phy_devi
return reset_control_deassert(rstc);
}
+static void qca8084_remove(struct phy_device *phydev)
+{
+ if (phy_package_remove_once(phydev))
+ qca8084_phy_package_remove_once(phydev);
+}
+
static struct phy_driver qca808x_driver[] = {
{
/* Qualcomm QCA8081 */
@@ -1167,6 +1219,7 @@ static struct phy_driver qca808x_driver[
.config_init = qca8084_config_init,
.link_change_notify = qca8084_link_change_notify,
.probe = qca8084_probe,
+ .remove = qca8084_remove,
}, };
module_phy_driver(qca808x_driver);

View File

@ -0,0 +1,446 @@
From d137b725f8f4a7d49a809dcd73c5b836495ec44d Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Mon, 23 Sep 2024 20:59:40 +0800
Subject: [PATCH] net: phy: qca808x: Add QCA8084 SerDes init function
When QCA8084 works on 10G-QXGMII, the XPCS and PCS need to be
configured in the PHY package init function.
Change-Id: Iac48c44f0e80adf055fa9c2095e99a04ba24c4bb
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
---
drivers/net/phy/qcom/qca8084_serdes.c | 374 ++++++++++++++++++++++++++
drivers/net/phy/qcom/qca8084_serdes.h | 2 +
drivers/net/phy/qcom/qca808x.c | 11 +
3 files changed, 387 insertions(+)
--- a/drivers/net/phy/qcom/qca8084_serdes.c
+++ b/drivers/net/phy/qcom/qca8084_serdes.c
@@ -24,6 +24,92 @@
*/
#define QCA8084_CHANNEL_MAX 4
+/* MII registers */
+#define PLL_POWER_ON_AND_RESET 0x0
+#define PCS_ANA_SW_RESET BIT(6)
+
+#define PLL_CONTROL 6
+#define PLL_CONTROL_CMLDIV2_IBSEL_MASK GENMASK(5, 4)
+
+/* MMD_PMAPMD registers */
+#define CDR_CONTRL 0x20
+#define SSC_FIX_MODE BIT(3)
+
+#define CALIBRATION4 0x78
+#define CALIBRATION_DONE BIT(7)
+
+#define MODE_CONTROL 0x11b
+#define MODE_CONTROL_SEL_MASK GENMASK(12, 8)
+#define MODE_CONTROL_XPCS 0x10
+#define MODE_CONTROL_SGMII_PLUS 0x8
+#define MODE_CONTROL_SGMII 0x4
+#define MODE_CONTROL_SGMII_SEL_MASK GENMASK(6, 4)
+#define MODE_CONTROL_SGMII_PHY 1
+#define MODE_CONTROL_SGMII_MAC 2
+
+#define QP_USXG_OPTION1 0x180
+#define QP_USXG_OPTION1_DATAPASS BIT(0)
+#define QP_USXG_OPTION1_DATAPASS_SGMII 0
+#define QP_USXG_OPTION1_DATAPASS_USXGMII 1
+
+#define BYPASS_TUNNING_IPG 0x189
+#define BYPASS_TUNNING_IPG_MASK GENMASK(11, 0)
+
+/* MDIO_MMD_PCS register */
+#define PCS_CONTROL2 0x7
+#define PCS_TYPE_MASK GENMASK(3, 0)
+#define PCS_TYPE_BASER 0
+
+#define PCS_EEE_CONTROL 0x14
+#define EEE_CAPABILITY BIT(6)
+
+#define PCS_STATUS1 0x20
+#define PCS_BASER_UP BIT(12)
+
+#define DIG_CTRL1 0x8000
+#define DIG_CTRL1_USXGMII_EN BIT(9)
+#define DIG_CTRL1_XPCS_RESET BIT(15)
+#define FIFO_RESET_CH0 BIT(10)
+#define FIFO_RESET_CH1_CH2_CH3 BIT(5)
+
+#define EEE_MODE_CONTROL 0x8006
+#define EEE_LCT_RES GENMASK(11, 8)
+#define EEE_SIGN BIT(6)
+#define EEE_LRX_EN BIT(1)
+#define EEE_LTX_EN BIT(0)
+
+#define PCS_TPC 0x8007
+#define PCS_QXGMII_MODE_MASK GENMASK(12, 10)
+#define PCS_QXGMII_EN 0x5
+
+#define EEE_RX_TIMER 0x8009
+#define EEE_RX_TIMER_100US_RES GENMASK(7, 0)
+#define EEE_RX_TIMER_RWR_RES GENMASK(12, 8)
+
+#define AM_LINK_TIMER 0x800a
+#define AM_LINK_TIMER_VAL 0x6018
+
+#define EEE_MODE_CONTROL1 0x800b
+#define TRANS_LPI_MODE BIT(0)
+#define TRANS_RX_LPI_MODE BIT(8)
+
+/* QXGMII channel MMD register */
+#define MII_CONTROL 0x0
+#define AUTO_NEGOTIATION_EN BIT(12)
+#define AUTO_NEGOTIATION_RESTART BIT(9)
+#define PCS_SPEED_2500 BIT(5)
+#define PCS_SPEED_1000 BIT(6)
+#define PCS_SPEED_100 BIT(13)
+#define PCS_SPEED_10 0
+
+#define DIG_CONTROL2 0x8001
+#define MII_BIT_CONTROL BIT(8)
+#define TX_CONFIG BIT(3)
+#define AUTO_NEGOTIATION_CMPLT_INTR BIT(0)
+
+#define XAUI_CONTROL 0x8004
+#define TX_IPG_CHECK_DISABLE BIT(0)
+
enum pcs_clk_id {
PCS_CLK,
PCS_RX_ROOT_CLK,
@@ -76,6 +162,8 @@ static const char *const pcs_clock_names
[PCS_TX_ROOT_CLK] = "pcs_tx_root",
};
+static const int qca8084_xpcs_ch_mmd[QCA8084_CHANNEL_MAX] = { 31, 26, 27, 28 };
+
struct mdio_device *qca8084_package_pcs_probe(struct device_node *pcs_np)
{
struct qca8084_pcs_data *pcs_data;
@@ -247,3 +335,289 @@ void qca8084_package_xpcs_and_pcs_remove
mdio_device_put(xpcs_mdiodev);
mdio_device_put(pcs_mdiodev);
}
+
+static int qca8084_pcs_set_interface_mode(struct mdio_device *mdio_dev,
+ phy_interface_t ifmode)
+{
+ int ret, hw_ifmode, data;
+
+ switch (ifmode) {
+ case PHY_INTERFACE_MODE_SGMII:
+ hw_ifmode = MODE_CONTROL_SGMII;
+ data = QP_USXG_OPTION1_DATAPASS_SGMII;
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ hw_ifmode = MODE_CONTROL_SGMII_PLUS;
+ data = QP_USXG_OPTION1_DATAPASS_SGMII;
+ break;
+ case PHY_INTERFACE_MODE_10G_QXGMII:
+ hw_ifmode = MODE_CONTROL_XPCS;
+ data = QP_USXG_OPTION1_DATAPASS_USXGMII;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* For PLL stable under high temperature */
+ ret = mdiodev_modify(mdio_dev, PLL_CONTROL,
+ PLL_CONTROL_CMLDIV2_IBSEL_MASK,
+ FIELD_PREP(PLL_CONTROL_CMLDIV2_IBSEL_MASK, 3));
+ if (ret)
+ return ret;
+
+ /* Configure the interface mode of PCS */
+ ret = mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, MODE_CONTROL,
+ MODE_CONTROL_SEL_MASK,
+ FIELD_PREP(MODE_CONTROL_SEL_MASK, hw_ifmode));
+ if (ret)
+ return ret;
+
+ /* Data pass selects SGMII or USXGMII */
+ return mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, QP_USXG_OPTION1,
+ QP_USXG_OPTION1_DATAPASS,
+ FIELD_PREP(QP_USXG_OPTION1_DATAPASS, data));
+}
+
+static int qca8084_do_calibration(struct mdio_device *mdio_dev)
+{
+ int ret;
+
+ ret = mdiodev_modify(mdio_dev, PLL_POWER_ON_AND_RESET,
+ PCS_ANA_SW_RESET, 0);
+ if (ret)
+ return ret;
+
+ usleep_range(10000, 11000);
+ ret = mdiodev_modify(mdio_dev, PLL_POWER_ON_AND_RESET,
+ PCS_ANA_SW_RESET, PCS_ANA_SW_RESET);
+ if (ret)
+ return ret;
+
+ /* Wait calibration done */
+ return read_poll_timeout(mdiodev_c45_read, ret,
+ (ret & CALIBRATION_DONE),
+ 100, 100000, true, mdio_dev,
+ MDIO_MMD_PMAPMD, CALIBRATION4);
+}
+
+
+static int qca8084_xpcs_set_mode(struct mdio_device *xpcs_mdiodev)
+{
+ int ret, val, i;
+
+ /* Configure BaseR mode */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, PCS_CONTROL2,
+ PCS_TYPE_MASK,
+ FIELD_PREP(PCS_TYPE_MASK, PCS_TYPE_BASER));
+ if (ret)
+ return ret;
+
+ /* Wait BaseR link up */
+ ret = read_poll_timeout(mdiodev_c45_read, val,
+ (val & PCS_BASER_UP), 1000, 100000, true,
+ xpcs_mdiodev,
+ MDIO_MMD_PCS, PCS_STATUS1);
+ if (ret) {
+ dev_err(&xpcs_mdiodev->dev, "BaseR link failed!\n");
+ return ret;
+ }
+
+ /* Enable USXGMII mode */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, DIG_CTRL1,
+ DIG_CTRL1_USXGMII_EN,
+ DIG_CTRL1_USXGMII_EN);
+ if (ret)
+ return ret;
+
+ /* Configure QXGMII mode */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, PCS_TPC,
+ PCS_QXGMII_MODE_MASK,
+ FIELD_PREP(PCS_QXGMII_MODE_MASK,
+ PCS_QXGMII_EN));
+ if (ret)
+ return ret;
+
+ /* Configure AM interval */
+ ret = mdiodev_c45_write(xpcs_mdiodev, MDIO_MMD_PCS, AM_LINK_TIMER,
+ AM_LINK_TIMER_VAL);
+ if (ret)
+ return ret;
+
+ /* Reset XPCS */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, DIG_CTRL1,
+ DIG_CTRL1_XPCS_RESET,
+ DIG_CTRL1_XPCS_RESET);
+ if (ret)
+ return ret;
+
+ /* Wait XPCS reset done */
+ ret = read_poll_timeout(mdiodev_c45_read, val,
+ !(val & DIG_CTRL1_XPCS_RESET),
+ 1000, 100000, true, xpcs_mdiodev,
+ MDIO_MMD_PCS, DIG_CTRL1);
+ if (ret) {
+ dev_err(&xpcs_mdiodev->dev, "XPCS reset failed!\n");
+ return ret;
+ }
+
+ /* Enable auto-negotiation complete interrupt, using mii-4bit
+ * and TX configureation of PHY side on all XPCS channels.
+ */
+ for (i = 0; i < QCA8084_CHANNEL_MAX; i++) {
+ ret = mdiodev_c45_modify(xpcs_mdiodev, qca8084_xpcs_ch_mmd[i],
+ DIG_CONTROL2,
+ (MII_BIT_CONTROL | TX_CONFIG |
+ AUTO_NEGOTIATION_CMPLT_INTR),
+ (TX_CONFIG | AUTO_NEGOTIATION_CMPLT_INTR));
+ if (ret)
+ return ret;
+
+ /* Enable auto-negotiation capability */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, qca8084_xpcs_ch_mmd[i],
+ MII_CONTROL,
+ AUTO_NEGOTIATION_EN,
+ AUTO_NEGOTIATION_EN);
+ if (ret)
+ return ret;
+
+ /* Disable TX IPG check */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, qca8084_xpcs_ch_mmd[i],
+ XAUI_CONTROL,
+ TX_IPG_CHECK_DISABLE,
+ TX_IPG_CHECK_DISABLE);
+ if (ret)
+ return ret;
+ }
+
+ /* Check EEE capability supported or not */
+ ret = mdiodev_c45_read(xpcs_mdiodev, MDIO_MMD_PCS, PCS_EEE_CONTROL);
+ if (ret < 0)
+ return ret;
+
+ if (ret & EEE_CAPABILITY) {
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
+ EEE_MODE_CONTROL,
+ EEE_LCT_RES | EEE_SIGN,
+ FIELD_PREP(EEE_LCT_RES, 1) | EEE_SIGN);
+ if (ret)
+ return ret;
+
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
+ EEE_RX_TIMER,
+ EEE_RX_TIMER_100US_RES | EEE_RX_TIMER_RWR_RES,
+ FIELD_PREP(EEE_RX_TIMER_100US_RES, 0xc8) |
+ FIELD_PREP(EEE_RX_TIMER_RWR_RES, 0x1c));
+ if (ret)
+ return ret;
+
+ /* Enable EEE LPI */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
+ EEE_MODE_CONTROL1,
+ TRANS_LPI_MODE | TRANS_RX_LPI_MODE,
+ TRANS_LPI_MODE | TRANS_RX_LPI_MODE);
+ if (ret)
+ return ret;
+
+ /* Enable TX/RX LPI pattern */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS,
+ EEE_MODE_CONTROL,
+ EEE_LRX_EN | EEE_LTX_EN,
+ EEE_LRX_EN | EEE_LTX_EN);
+ }
+
+ return ret;
+}
+
+static int qca8084_pcs_set_mode(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev)
+{
+ struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
+ struct qca8084_pcs_data *pcs_data = mdiodev_get_drvdata(pcs_mdiodev);
+ struct qca8084_xpcs_channel_priv xpcs_ch;
+ int ret, channel;
+
+ /* Enable clock and de-assert for PCS. */
+ ret = clk_prepare_enable(pcs_data->clks[PCS_CLK]);
+ if (ret)
+ return ret;
+
+ ret = reset_control_deassert(pcs_data->rstc);
+ if (ret)
+ return ret;
+
+ /* IPG tunning selection for RX, TX and XGMII of all channels. */
+ ret = mdiodev_c45_modify(pcs_mdiodev, MDIO_MMD_PMAPMD,
+ BYPASS_TUNNING_IPG,
+ BYPASS_TUNNING_IPG_MASK, 0);
+ if (ret)
+ return ret;
+
+ reset_control_assert(xpcs_data->rstc);
+
+ ret = qca8084_pcs_set_interface_mode(pcs_mdiodev,
+ PHY_INTERFACE_MODE_10G_QXGMII);
+ if (ret)
+ return ret;
+
+ /* Reset of 4 channels */
+ for (channel = 0; channel < QCA8084_CHANNEL_MAX; channel++) {
+ xpcs_ch = xpcs_data->xpcs_ch[channel];
+ ret = reset_control_reset(xpcs_ch.rstcs);
+ if (ret)
+ return ret;
+ }
+
+ ret = qca8084_do_calibration(pcs_mdiodev);
+ if (ret) {
+ dev_err(&pcs_mdiodev->dev, "PCS calibration timeout!\n");
+ return ret;
+ }
+
+ /* Enable PCS SSC to fix mode */
+ ret = mdiodev_c45_modify(pcs_mdiodev, MDIO_MMD_PMAPMD,
+ CDR_CONTRL, SSC_FIX_MODE, SSC_FIX_MODE);
+ if (ret)
+ return ret;
+
+ return reset_control_deassert(xpcs_data->rstc);
+}
+
+static int qca8084_xpcs_clock_parent_set(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev)
+{
+ struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
+ struct qca8084_pcs_data *pcs_data = mdiodev_get_drvdata(pcs_mdiodev);
+ struct qca8084_xpcs_channel_priv xpcs_ch;
+ int ret, channel;
+
+ for (channel = 0; channel < QCA8084_CHANNEL_MAX; channel++) {
+ xpcs_ch = xpcs_data->xpcs_ch[channel];
+ ret = clk_set_parent(xpcs_ch.clks[XPCS_RX_SRC_CLK],
+ pcs_data->clks[PCS_RX_ROOT_CLK]);
+ if (ret)
+ return ret;
+
+ ret = clk_set_parent(xpcs_ch.clks[XPCS_TX_SRC_CLK],
+ pcs_data->clks[PCS_TX_ROOT_CLK]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int qca8084_qxgmii_set_mode(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev)
+{
+ int ret;
+
+ ret = qca8084_xpcs_clock_parent_set(xpcs_mdiodev, pcs_mdiodev);
+ if (ret)
+ return ret;
+
+ ret = qca8084_pcs_set_mode(xpcs_mdiodev, pcs_mdiodev);
+ if (ret)
+ return ret;
+
+ return qca8084_xpcs_set_mode(xpcs_mdiodev);
+}
--- a/drivers/net/phy/qcom/qca8084_serdes.h
+++ b/drivers/net/phy/qcom/qca8084_serdes.h
@@ -15,4 +15,6 @@ struct mdio_device *qca8084_package_pcs_
struct mdio_device *qca8084_package_xpcs_probe(struct device_node *xpcs_np);
void qca8084_package_xpcs_and_pcs_remove(struct mdio_device *xpcs_mdiodev,
struct mdio_device *pcs_mdiodev);
+int qca8084_qxgmii_set_mode(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev);
#endif /* _QCA8084_SERDES_H_ */
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@@ -926,6 +926,14 @@ static int qca8084_phy_package_config_in
usleep_range(10000, 11000);
+ /* Configure PCS working on 10G-QXGMII mode */
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII) {
+ ret = qca8084_qxgmii_set_mode(shared_priv->mdiodev[1],
+ shared_priv->mdiodev[0]);
+ if (ret)
+ return ret;
+ }
+
/* Initialize the PHY package clock and reset, which is the
* necessary config sequence after GPIO reset on the PHY package.
*/
@@ -1164,6 +1172,9 @@ static int qca8084_probe(struct phy_devi
static void qca8084_remove(struct phy_device *phydev)
{
+ if (phydev->interface != PHY_INTERFACE_MODE_10G_QXGMII)
+ return;
+
if (phy_package_remove_once(phydev))
qca8084_phy_package_remove_once(phydev);
}

View File

@ -0,0 +1,251 @@
From 2f5b7e167d847a5b5b74a91f991d48635453c55f Mon Sep 17 00:00:00 2001
From: Luo Jie <quic_luoj@quicinc.com>
Date: Mon, 23 Sep 2024 21:24:56 +0800
Subject: [PATCH] net: phy: qca808x: Add QCA8084 SerDes speed config
When the link of PHY is changed, the XPCS channel needs to be
configured to adapt the current link status.
Change-Id: I50d8973691dff133fc6bec1e9a1043bb646811fc
Signed-off-by: Luo Jie <quic_luoj@quicinc.com>
Alex G: Use phy_package_get_*() accessors
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/net/phy/qcom/qca8084_serdes.c | 159 ++++++++++++++++++++++++++
drivers/net/phy/qcom/qca8084_serdes.h | 3 +
drivers/net/phy/qcom/qca808x.c | 15 ++-
3 files changed, 175 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/qcom/qca8084_serdes.c
+++ b/drivers/net/phy/qcom/qca8084_serdes.c
@@ -4,6 +4,7 @@
*/
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/dev_printk.h>
#include <linux/mdio.h>
#include <linux/of.h>
@@ -55,6 +56,13 @@
#define BYPASS_TUNNING_IPG 0x189
#define BYPASS_TUNNING_IPG_MASK GENMASK(11, 0)
+#define QP_USXG_RESET 0x18c
+#define QP_USXG_SGMII_FUNC_RESET BIT(4)
+#define QP_USXG_P3_FUNC_RESET BIT(3)
+#define QP_USXG_P2_FUNC_RESET BIT(2)
+#define QP_USXG_P1_FUNC_RESET BIT(1)
+#define QP_USXG_P0_FUNC_RESET BIT(0)
+
/* MDIO_MMD_PCS register */
#define PCS_CONTROL2 0x7
#define PCS_TYPE_MASK GENMASK(3, 0)
@@ -107,6 +115,9 @@
#define TX_CONFIG BIT(3)
#define AUTO_NEGOTIATION_CMPLT_INTR BIT(0)
+#define PCS_ERR_SEL 0x8002
+#define PCS_AN_COMPLETE BIT(0)
+
#define XAUI_CONTROL 0x8004
#define TX_IPG_CHECK_DISABLE BIT(0)
@@ -621,3 +632,151 @@ int qca8084_qxgmii_set_mode(struct mdio_
return qca8084_xpcs_set_mode(xpcs_mdiodev);
}
+
+static int qca8084_pcs_ipg_tune_reset(struct mdio_device *mdio_dev,
+ int reset_function)
+{
+ int ret;
+
+ ret = mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, QP_USXG_RESET,
+ reset_function, 0);
+ if (ret)
+ return ret;
+
+ usleep_range(1000, 1100);
+
+ return mdiodev_c45_modify(mdio_dev, MDIO_MMD_PMAPMD, QP_USXG_RESET,
+ reset_function, reset_function);
+}
+
+static int qca8084_xpcs_an_restart(struct mdio_device *xpcs_mdiodev,
+ int channel)
+{
+ int ret, mmd;
+
+ mmd = qca8084_xpcs_ch_mmd[channel];
+
+ /* Restart auto-negotiation */
+ ret = mdiodev_c45_modify(xpcs_mdiodev, mmd, MII_CONTROL,
+ AUTO_NEGOTIATION_RESTART,
+ AUTO_NEGOTIATION_RESTART);
+ if (ret)
+ return ret;
+
+ usleep_range(1000, 1100);
+
+ /* Clear pcs auto-negotiation complete interrupt */
+ return mdiodev_c45_modify(xpcs_mdiodev, mmd, PCS_ERR_SEL,
+ PCS_AN_COMPLETE, 0);
+}
+
+void qca8084_qxgmii_set_speed(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev,
+ int channel, int speed)
+{
+ struct qca8084_xpcs_data *xpcs_data = mdiodev_get_drvdata(xpcs_mdiodev);
+ struct qca8084_xpcs_channel_priv *xpcs_ch;
+ int mmd, i, ret, xpcs_rate;
+ unsigned long rate;
+
+ for (i = 0; i < QCA8084_CHANNEL_MAX; i++) {
+ xpcs_ch = &(xpcs_data->xpcs_ch[channel]);
+ if (channel == xpcs_ch->ch_id)
+ break;
+ }
+
+ if (i == QCA8084_CHANNEL_MAX) {
+ dev_err(&xpcs_mdiodev->dev, "Invalid channel %d\n", channel);
+ return;
+ }
+
+ mmd = qca8084_xpcs_ch_mmd[channel];
+
+ ret = qca8084_xpcs_an_restart(xpcs_mdiodev, channel);
+ if (ret)
+ return;
+
+ switch (speed) {
+ case SPEED_2500:
+ rate = 312500000;
+ xpcs_rate = PCS_SPEED_2500;
+ break;
+ case SPEED_1000:
+ rate = 125000000;
+ xpcs_rate = PCS_SPEED_1000;
+ break;
+ case SPEED_100:
+ rate = 25000000;
+ xpcs_rate = PCS_SPEED_100;
+ break;
+ case SPEED_10:
+ default:
+ rate = 2500000;
+ xpcs_rate = PCS_SPEED_10;
+ break;
+ }
+
+ clk_set_rate(xpcs_ch->clks[XPCS_RX_CLK], rate);
+ clk_set_rate(xpcs_ch->clks[XPCS_TX_CLK], rate);
+
+ /* XGMII takes the different clock rate 78.125Mhz from XPCS clock
+ * when linked at 2500M.
+ */
+ if (speed == SPEED_2500)
+ rate = 78125000;
+
+ clk_set_rate(xpcs_ch->clks[XPCS_XGMII_RX_CLK], rate);
+ clk_set_rate(xpcs_ch->clks[XPCS_XGMII_TX_CLK], rate);
+
+ ret = mdiodev_c45_modify(xpcs_mdiodev, mmd, MII_CONTROL,
+ PCS_SPEED_2500 | PCS_SPEED_1000 |
+ PCS_SPEED_100 | PCS_SPEED_10,
+ xpcs_rate);
+ if (ret)
+ return;
+
+ /* Disable clocks if link down with unknown speed. The channel clocks
+ * are disabled by default, __clk_is_enabled() is used to avoid
+ * disabling the clocks that is already in the disabled status.
+ */
+ if (speed == SPEED_UNKNOWN) {
+ if (__clk_is_enabled(xpcs_ch->clks[XPCS_RX_CLK]))
+ clk_disable_unprepare(xpcs_ch->clks[XPCS_RX_CLK]);
+ if (__clk_is_enabled(xpcs_ch->clks[XPCS_TX_CLK]))
+ clk_disable_unprepare(xpcs_ch->clks[XPCS_TX_CLK]);
+ if (__clk_is_enabled(xpcs_ch->clks[XPCS_PORT_RX_CLK]))
+ clk_disable_unprepare(xpcs_ch->clks[XPCS_PORT_RX_CLK]);
+ if (__clk_is_enabled(xpcs_ch->clks[XPCS_PORT_TX_CLK]))
+ clk_disable_unprepare(xpcs_ch->clks[XPCS_PORT_TX_CLK]);
+ if (__clk_is_enabled(xpcs_ch->clks[XPCS_XGMII_RX_CLK]))
+ clk_disable_unprepare(xpcs_ch->clks[XPCS_XGMII_RX_CLK]);
+ if (__clk_is_enabled(xpcs_ch->clks[XPCS_XGMII_TX_CLK]))
+ clk_disable_unprepare(xpcs_ch->clks[XPCS_XGMII_TX_CLK]);
+ } else {
+ clk_prepare_enable(xpcs_ch->clks[XPCS_RX_CLK]);
+ clk_prepare_enable(xpcs_ch->clks[XPCS_TX_CLK]);
+ clk_prepare_enable(xpcs_ch->clks[XPCS_PORT_RX_CLK]);
+ clk_prepare_enable(xpcs_ch->clks[XPCS_PORT_TX_CLK]);
+ clk_prepare_enable(xpcs_ch->clks[XPCS_XGMII_RX_CLK]);
+ clk_prepare_enable(xpcs_ch->clks[XPCS_XGMII_TX_CLK]);
+ }
+
+ msleep(100);
+
+ ret = reset_control_reset(xpcs_ch->rstcs);
+ if (ret)
+ return;
+
+ /* Reset IPG tune of PCS device. */
+ ret = qca8084_pcs_ipg_tune_reset(pcs_mdiodev, BIT(channel));
+ if (ret)
+ return;
+
+ if (channel == 0)
+ mdiodev_c45_modify(xpcs_mdiodev, MDIO_MMD_PCS, DIG_CTRL1,
+ FIFO_RESET_CH0, FIFO_RESET_CH0);
+ else
+ mdiodev_c45_modify(xpcs_mdiodev, mmd, DIG_CTRL1,
+ FIFO_RESET_CH1_CH2_CH3,
+ FIFO_RESET_CH1_CH2_CH3);
+}
--- a/drivers/net/phy/qcom/qca8084_serdes.h
+++ b/drivers/net/phy/qcom/qca8084_serdes.h
@@ -17,4 +17,7 @@ void qca8084_package_xpcs_and_pcs_remove
struct mdio_device *pcs_mdiodev);
int qca8084_qxgmii_set_mode(struct mdio_device *xpcs_mdiodev,
struct mdio_device *pcs_mdiodev);
+void qca8084_qxgmii_set_speed(struct mdio_device *xpcs_mdiodev,
+ struct mdio_device *pcs_mdiodev,
+ int channel, int speed);
#endif /* _QCA8084_SERDES_H_ */
--- a/drivers/net/phy/qcom/qca808x.c
+++ b/drivers/net/phy/qcom/qca808x.c
@@ -976,6 +976,7 @@ static int qca8084_config_init(struct ph
static void qca8084_link_change_notify(struct phy_device *phydev)
{
+ struct qca808x_shared_priv *shared_priv;
int ret;
/* Assert the FIFO between PHY and MAC. */
@@ -1007,14 +1008,24 @@ static void qca8084_link_change_notify(s
}
}
- /* Enable IPG level 10 to 11 tuning for link speed 1000M in the
+ /* Enable IPG level 10 to 11 tuning for link speed 1000M and
+ * configure the related XPCS channel with the phydev in the
* 10G_QXGMII mode.
*/
- if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII) {
+ shared_priv = phy_package_get_priv(phydev);
+ struct qca808x_priv *priv = phydev->priv;
+
phy_modify_mmd(phydev, MDIO_MMD_AN, QCA8084_MMD7_IPG_OP,
QCA8084_IPG_10_TO_11_EN,
phydev->speed == SPEED_1000 ?
QCA8084_IPG_10_TO_11_EN : 0);
+
+ qca8084_qxgmii_set_speed(shared_priv->mdiodev[1],
+ shared_priv->mdiodev[0],
+ priv->channel_id,
+ phydev->speed);
+ }
}
/* QCA8084 is a four-port PHY, which integrates the clock controller,

View File

@ -12,8 +12,7 @@ CPU_TYPE := cortex-a9
CPU_SUBTYPE := vfpv3-d16
SUBTARGETS := generic
KERNEL_PATCHVER := 6.6
KERNEL_TESTING_PATCHVER := 6.12
KERNEL_PATCHVER := 6.12
include $(INCLUDE_DIR)/target.mk

View File

@ -1,577 +0,0 @@
CONFIG_AC97_BUS=y
# CONFIG_AHCI_TEGRA is not set
CONFIG_ALIGNMENT_TRAP=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_TEGRA=y
# CONFIG_ARCH_TEGRA_114_SOC is not set
# CONFIG_ARCH_TEGRA_124_SOC is not set
CONFIG_ARCH_TEGRA_2x_SOC=y
# CONFIG_ARCH_TEGRA_3x_SOC is not set
CONFIG_ARM=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_ERRATA_720789=y
CONFIG_ARM_ERRATA_754327=y
CONFIG_ARM_ERRATA_764369=y
CONFIG_ARM_GIC=y
CONFIG_ARM_HAS_GROUP_RELOCS=y
CONFIG_ARM_HEAVY_MB=y
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
CONFIG_ARM_PATCH_IDIV=y
CONFIG_ARM_PATCH_PHYS_VIRT=y
# CONFIG_ARM_PL172_MPMC is not set
# CONFIG_ARM_SMMU is not set
# CONFIG_ARM_TEGRA124_CPUFREQ is not set
CONFIG_ARM_TEGRA20_CPUFREQ=y
CONFIG_ARM_TEGRA_CPUIDLE=y
CONFIG_ARM_THUMB=y
CONFIG_ARM_THUMBEE=y
CONFIG_ARM_UNWIND=y
CONFIG_ARM_VIRT_EXT=y
CONFIG_ASN1=y
CONFIG_ATA=y
CONFIG_ATAGS=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_BSG_COMMON=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BOUNCE=y
CONFIG_BUFFER_HEAD=y
CONFIG_CACHE_L2X0=y
CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CLZ_TAB=y
CONFIG_CMA=y
CONFIG_CMA_ALIGNMENT=8
CONFIG_CMA_AREAS=7
# CONFIG_CMA_DEBUG is not set
# CONFIG_CMA_DEBUGFS is not set
CONFIG_CMA_SIZE_MBYTES=16
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
# CONFIG_CMA_SYSFS 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_CONTIG_ALLOC=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
# CONFIG_CPU_FREQ_STAT is not set
CONFIG_CPU_HAS_ASID=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_PM=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_SPECTRE=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_CRYPTO_AES_ARM=y
CONFIG_CRYPTO_CRC32=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECHAINIV=y
CONFIG_CRYPTO_GENIV=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZ4=y
CONFIG_CRYPTO_LZ4HC=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_RSA=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA1_ARM=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA256_ARM=y
CONFIG_CRYPTO_SHA3=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SHA512_ARM=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DDR=y
CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
CONFIG_DEVFREQ_THERMAL=y
# CONFIG_DEVPORT is not set
CONFIG_DMADEVICES=y
CONFIG_DMA_CMA=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DMA_OPS=y
CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DNOTIFY=y
CONFIG_DRM=y
CONFIG_DRM_BRIDGE=y
CONFIG_DRM_DISPLAY_DP_HELPER=y
CONFIG_DRM_DISPLAY_HDMI_HELPER=y
CONFIG_DRM_DISPLAY_HELPER=y
CONFIG_DRM_DP_AUX_BUS=y
CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_KMS_HELPER=y
CONFIG_DRM_MIPI_DSI=y
CONFIG_DRM_PANEL=y
CONFIG_DRM_PANEL_BRIDGE=y
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
CONFIG_DRM_TEGRA=y
# CONFIG_DRM_TEGRA_DEBUG is not set
# CONFIG_DRM_TEGRA_STAGING is not set
CONFIG_DTC=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
CONFIG_FB_CORE=y
CONFIG_FB_DEFERRED_IO=y
CONFIG_FB_DMAMEM_HELPERS=y
CONFIG_FB_IOMEM_FOPS=y
CONFIG_FB_SYSMEM_HELPERS=y
CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_VDSO_32=y
CONFIG_GLOB=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_TEGRA=y
CONFIG_HARDEN_BRANCH_PREDICTOR=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAVE_SMP=y
CONFIG_HDMI=y
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CPU=y
CONFIG_HWMON=y
CONFIG_HZ_FIXED=0
CONFIG_HZ_PERIODIC=y
CONFIG_I2C=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_TEGRA=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INPUT=y
CONFIG_INPUT_KEYBOARD=y
CONFIG_INPUT_VIVALDIFMAP=y
CONFIG_INTERCONNECT=y
# CONFIG_IOMMUFD is not set
CONFIG_IOMMU_API=y
# CONFIG_IOMMU_DEBUGFS is not set
# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
CONFIG_IOMMU_IOVA=y
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
CONFIG_IOMMU_SUPPORT=y
CONFIG_IRQCHIP=y
CONFIG_IRQSTACKS=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_KCMP=y
CONFIG_KEYBOARD_ATKBD=y
CONFIG_KMAP_LOCAL=y
CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LZ4HC_COMPRESS=y
CONFIG_LZ4_COMPRESS=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_MEDIA_CONTROLLER_REQUEST_API=y
CONFIG_MEDIA_PLATFORM_DRIVERS=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_SUPPORT_FILTER=y
CONFIG_MEMORY=y
CONFIG_MEMORY_ISOLATION=y
# CONFIG_MFD_ACER_A500_EC is not set
# CONFIG_MFD_NVEC is not set
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
# CONFIG_MMC_SDHCI_PCI is not set
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MPILIB=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SRCU_NMI_SAFE=y
# CONFIG_NEON is not set
CONFIG_NET_EGRESS=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_INGRESS=y
CONFIG_NET_XGRESS=y
CONFIG_NLS=y
CONFIG_NR_CPUS=4
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IOMMU=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OUTER_CACHE=y
CONFIG_OUTER_CACHE_SYNC=y
CONFIG_PADATA=y
CONFIG_PAGE_OFFSET=0xC0000000
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_PCIEAER=y
CONFIG_PCIEASPM=y
CONFIG_PCIEASPM_DEFAULT=y
# CONFIG_PCIEASPM_PERFORMANCE is not set
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
CONFIG_PCI_TEGRA=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHY_TEGRA_XUSB=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_TEGRA=y
CONFIG_PINCTRL_TEGRA20=y
CONFIG_PINCTRL_TEGRA_XUSB=y
CONFIG_PL310_ERRATA_727915=y
CONFIG_PL310_ERRATA_769419=y
CONFIG_PL353_SMC=y
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_DEVFREQ=y
# CONFIG_PM_DEVFREQ_EVENT is not set
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
CONFIG_PM_OPP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_SUPPLY=y
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
CONFIG_PWM_SYSFS=y
CONFIG_PWM_TEGRA=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_SPI=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_GPIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_CMOS is not set
CONFIG_RTC_DRV_TEGRA=y
CONFIG_RTC_I2C_AND_SPI=y
CONFIG_RTC_NVMEM=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SCSI=y
CONFIG_SCSI_COMMON=y
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_PROC_FS is not set
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_TEGRA=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_TEGRA=y
CONFIG_SERIO=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SGL_ALLOC=y
CONFIG_SG_POOL=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_SND=y
CONFIG_SND_AUDIO_GRAPH_CARD=y
# CONFIG_SND_COMPRESS_OFFLOAD is not set
CONFIG_SND_DMAENGINE_PCM=y
# CONFIG_SND_HDA_TEGRA is not set
CONFIG_SND_JACK=y
CONFIG_SND_JACK_INPUT_DEV=y
# CONFIG_SND_PCI is not set
CONFIG_SND_PCM=y
CONFIG_SND_PCM_ELD=y
CONFIG_SND_PCM_IEC958=y
# CONFIG_SND_PROC_FS is not set
CONFIG_SND_SIMPLE_CARD=y
CONFIG_SND_SIMPLE_CARD_UTILS=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
CONFIG_SND_SOC_HDMI_CODEC=y
CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_SOC_TEGRA=y
# CONFIG_SND_SOC_TEGRA186_ASRC is not set
# CONFIG_SND_SOC_TEGRA186_DSPK is not set
CONFIG_SND_SOC_TEGRA20_AC97=y
CONFIG_SND_SOC_TEGRA20_DAS=y
CONFIG_SND_SOC_TEGRA20_I2S=y
CONFIG_SND_SOC_TEGRA20_SPDIF=y
# CONFIG_SND_SOC_TEGRA210_ADMAIF is not set
# CONFIG_SND_SOC_TEGRA210_ADX is not set
# CONFIG_SND_SOC_TEGRA210_AHUB is not set
# CONFIG_SND_SOC_TEGRA210_AMX is not set
# CONFIG_SND_SOC_TEGRA210_DMIC is not set
# CONFIG_SND_SOC_TEGRA210_I2S is not set
# CONFIG_SND_SOC_TEGRA210_MIXER is not set
# CONFIG_SND_SOC_TEGRA210_MVC is not set
# CONFIG_SND_SOC_TEGRA210_OPE is not set
# CONFIG_SND_SOC_TEGRA210_SFC is not set
# CONFIG_SND_SOC_TEGRA30_AHUB is not set
# CONFIG_SND_SOC_TEGRA30_I2S is not set
# CONFIG_SND_SOC_TEGRA_ALC5632 is not set
# CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD is not set
CONFIG_SND_SOC_TEGRA_MACHINE_DRV=y
# CONFIG_SND_SOC_TEGRA_MAX98088 is not set
# CONFIG_SND_SOC_TEGRA_MAX98090 is not set
# CONFIG_SND_SOC_TEGRA_RT5631 is not set
# CONFIG_SND_SOC_TEGRA_RT5640 is not set
# CONFIG_SND_SOC_TEGRA_RT5677 is not set
# CONFIG_SND_SOC_TEGRA_SGTL5000 is not set
CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
# CONFIG_SND_SOC_TEGRA_WM8753 is not set
# CONFIG_SND_SOC_TEGRA_WM8903 is not set
# CONFIG_SND_SOC_TEGRA_WM9712 is not set
CONFIG_SND_SOC_TLV320AIC23=y
CONFIG_SND_SOC_TLV320AIC23_I2C=y
# CONFIG_SND_USB is not set
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOC_BUS=y
CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER=y
CONFIG_SOC_TEGRA_FLOWCTRL=y
CONFIG_SOC_TEGRA_FUSE=y
CONFIG_SOC_TEGRA_PMC=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
# CONFIG_SPI_TEGRA114 is not set
CONFIG_SPI_TEGRA20_SFLASH=y
CONFIG_SPI_TEGRA20_SLINK=y
# CONFIG_SPI_TEGRA210_QUAD is not set
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SRAM=y
CONFIG_SRAM_EXEC=y
CONFIG_SWP_EMULATE=y
CONFIG_SYNC_FILE=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_TEGRA186_TIMER is not set
CONFIG_TEGRA20_APB_DMA=y
CONFIG_TEGRA20_EMC=y
# CONFIG_TEGRA210_ADMA is not set
# CONFIG_TEGRA_ACONNECT is not set
CONFIG_TEGRA_AHB=y
CONFIG_TEGRA_GMI=y
CONFIG_TEGRA_HOST1X=y
CONFIG_TEGRA_HOST1X_CONTEXT_BUS=y
CONFIG_TEGRA_HOST1X_FIREWALL=y
CONFIG_TEGRA_IOMMU_GART=y
# CONFIG_TEGRA_IOMMU_SMMU is not set
# CONFIG_TEGRA_IVC is not set
CONFIG_TEGRA_MC=y
CONFIG_TEGRA_SOCTHERM=y
CONFIG_TEGRA_TIMER=y
CONFIG_TEGRA_WATCHDOG=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
# CONFIG_UCLAMP_TASK is not set
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNWINDER_ARM=y
CONFIG_USB=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_HOST=y
CONFIG_USB_CHIPIDEA_TEGRA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_COMMON=y
CONFIG_USB_CONN_GPIO=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
CONFIG_USB_EHCI_TEGRA=y
CONFIG_USB_GADGET=y
CONFIG_USB_PHY=y
CONFIG_USB_ROLE_SWITCH=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_TEGRA_PHY=y
# CONFIG_USB_TEGRA_XUDC is not set
CONFIG_USB_ULPI=y
CONFIG_USB_ULPI_BUS=y
CONFIG_USB_ULPI_VIEWPORT=y
# CONFIG_USB_XHCI_TEGRA is not set
CONFIG_USE_OF=y
CONFIG_V4L2_H264=y
CONFIG_V4L2_MEM2MEM_DEV=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_VIDEOBUF2_CORE=y
CONFIG_VIDEOBUF2_DMA_CONTIG=y
CONFIG_VIDEOBUF2_DMA_SG=y
CONFIG_VIDEOBUF2_MEMOPS=y
CONFIG_VIDEOBUF2_V4L2=y
CONFIG_VIDEO_CMDLINE=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_NOMODESET=y
CONFIG_VIDEO_TEGRA_VDE=y
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_WATCHDOG_CORE=y
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XPS=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y

View File

@ -1,77 +0,0 @@
From patchwork Fri Jul 13 11:32:42 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: serial8250 on tegra hsuart: recover from spurious interrupts due to
tegra2 silicon bug
X-Patchwork-Submitter: "David R. Piegdon" <lkml@p23q.org>
X-Patchwork-Id: 943440
Message-Id: <4676ea34-69ce-5422-1ded-94218b89f7d9@p23q.org>
To: linux-tegra@vger.kernel.org
Date: Fri, 13 Jul 2018 11:32:42 +0000
From: "David R. Piegdon" <lkml@p23q.org>
List-Id: <linux-tegra.vger.kernel.org>
Hi,
a while back I sent a few mails regarding spurious interrupts in the
UARTA (hsuart) block of the Tegra2 SoC, when using the 8250 driver for
it instead of the hsuart driver. After going down a pretty deep
debugging/testing hole, I think I found a patch that fixes the issue. So
far testing in a reboot-cycle suggests that the error frequency dropped
from >3% of all reboots to at least <0.05% of all reboots. Tests
continue to run over the weekend.
The patch below already is a second iteration; the first did not reset
the MCR or contain the lines below '// clear interrupts'. This resulted
in no more spurious interrupts, but in a few % of spurious interrupts
that were recovered the UART block did not receive any characters any
more. So further resetting was required to fully reacquire operational
state of the UART block.
I'd love any comments/suggestions on this!
Cheers,
David
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -134,6 +134,38 @@ static irqreturn_t serial8250_interrupt(
if (l == i->head && pass_counter++ > PASS_LIMIT)
break;
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ if (!handled && (port->type == PORT_TEGRA)) {
+ /*
+ * Fix Tegra 2 CPU silicon bug where sometimes
+ * "TX holding register empty" interrupts result in a
+ * bad (metastable?) state in Tegras HSUART IP core.
+ * Only way to recover seems to be to reset all
+ * interrupts as well as the TX queue and the MCR.
+ * But we don't want to loose any outgoing characters,
+ * so only do it if the RX and TX queues are empty.
+ */
+ unsigned char lsr = port->serial_in(port, UART_LSR);
+ const unsigned char fifo_empty_mask =
+ (UART_LSR_TEMT | UART_LSR_THRE);
+ if (((lsr & (UART_LSR_DR | fifo_empty_mask)) ==
+ fifo_empty_mask)) {
+ port->serial_out(port, UART_IER, 0);
+ port->serial_out(port, UART_MCR, 0);
+ serial8250_clear_and_reinit_fifos(up);
+ port->serial_out(port, UART_MCR, up->mcr);
+ port->serial_out(port, UART_IER, up->ier);
+ // clear interrupts
+ serial_port_in(port, UART_LSR);
+ serial_port_in(port, UART_RX);
+ serial_port_in(port, UART_IIR);
+ serial_port_in(port, UART_MSR);
+ up->lsr_saved_flags = 0;
+ up->msr_saved_flags = 0;
+ }
+ }
+#endif
} while (l != end);
spin_unlock(&i->lock);

View File

@ -1,46 +0,0 @@
--- a/arch/arm/boot/dts/nvidia/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/nvidia/tegra20-trimslice.dts
@@ -201,16 +201,17 @@
conf_ata {
nvidia,pins = "ata", "atc", "atd", "ate",
"crtp", "dap2", "dap3", "dap4", "dta",
- "dtb", "dtc", "dtd", "dte", "gmb",
- "gme", "i2cp", "pta", "slxc", "slxd",
- "spdi", "spdo", "uda";
+ "dtb", "dtc", "dtd", "gmb", "gme",
+ "i2cp", "pta", "slxc", "slxd", "spdi",
+ "spdo", "uda";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf_atb {
nvidia,pins = "atb", "cdev1", "cdev2", "dap1",
- "gma", "gmc", "gmd", "gpu", "gpu7",
- "gpv", "sdio1", "slxa", "slxk", "uac";
+ "dte", "gma", "gmc", "gmd", "gpu",
+ "gpu7", "gpv", "sdio1", "slxa", "slxk",
+ "uac";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
@@ -408,6 +409,20 @@
};
};
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ ds2 {
+ label = "trimslice:green:right";
+ gpios = <&gpio TEGRA_GPIO(D, 2) GPIO_ACTIVE_LOW>;
+ };
+
+ ds3 {
+ label = "trimslice:green:left";
+ gpios = <&gpio TEGRA_GPIO(BB, 5) GPIO_ACTIVE_LOW>;
+ };
+ };
+
poweroff {
compatible = "gpio-poweroff";
gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>;

View File

@ -11,9 +11,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware-utils.git
PKG_SOURCE_DATE:=2025-10-20
PKG_SOURCE_VERSION:=313f344d8436955b4c0baad595d450f5350908c6
PKG_MIRROR_HASH:=63a5b34fd618811923f3c397da54fac6b25b83a0d1e4d83ce6504550bbbb7520
PKG_SOURCE_DATE:=2025-11-11
PKG_SOURCE_VERSION:=c42a3bc53da869d02c8ae4d62b3b08a95ff5833f
PKG_MIRROR_HASH:=c9cbe9aafc3476dac9d9bd1b26f932048f895bce775e8220f82fae097463c539
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/cmake.mk