Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
62b1521045
@ -363,7 +363,7 @@ config KERNEL_DEBUG_INFO
|
||||
config KERNEL_DEBUG_INFO_BTF
|
||||
|
||||
bool "Enable additional BTF type information"
|
||||
default y if TARGET_armvirt || TARGET_bcm27xx || TARGET_ipq807x || TARGET_mediatek_filogic || TARGET_mvebu || TARGET_rockchip || TARGET_sunxi || TARGET_x86
|
||||
default y if TARGET_bcm27xx || TARGET_ipq807x || TARGET_mediatek_filogic || TARGET_mvebu_cortexa53 || TARGET_mvebu_cortexa72 || TARGET_rockchip || TARGET_sunxi || TARGET_x86
|
||||
depends on !HOST_OS_MACOS
|
||||
depends on KERNEL_DEBUG_INFO && !KERNEL_DEBUG_INFO_REDUCED
|
||||
select DWARVES
|
||||
@ -376,7 +376,7 @@ config KERNEL_DEBUG_INFO_BTF
|
||||
|
||||
config KERNEL_DEBUG_INFO_REDUCED
|
||||
bool "Reduce debugging information"
|
||||
default y if !(TARGET_armvirt || TARGET_bcm27xx || TARGET_ipq807x || TARGET_mediatek_filogic || TARGET_mvebu || TARGET_rockchip || TARGET_sunxi || TARGET_x86)
|
||||
default y if !(TARGET_bcm27xx || TARGET_ipq807x || TARGET_mediatek_filogic || TARGET_mvebu_cortexa53 || TARGET_mvebu_cortexa72 || TARGET_rockchip || TARGET_sunxi || TARGET_x86)
|
||||
depends on KERNEL_DEBUG_INFO
|
||||
help
|
||||
If you say Y here gcc is instructed to generate less debugging
|
||||
|
||||
@ -6,9 +6,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware/qca-wireless.git
|
||||
PKG_SOURCE_DATE:=2023-03-20
|
||||
PKG_SOURCE_VERSION:=f9cece02724b8ca2c1a166a46f0afa89e632d431
|
||||
PKG_MIRROR_HASH:=89c20798c7ec83114aa69467f2467fe32cbb74ebeca277c60a033af960ca6c04
|
||||
PKG_SOURCE_DATE:=2023-03-27
|
||||
PKG_SOURCE_VERSION:=ccd7e460cc798d90148a10539b6d94a5fd761004
|
||||
PKG_MIRROR_HASH:=e51d28c741aeb0867493a7bfc801b8b1977c942ed5d51d62c1aa8729c91cce32
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17530,6 +17530,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||
@@ -17538,6 +17538,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
|
||||
F: drivers/media/i2c/imx412.c
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
|
||||
+...
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17544,6 +17544,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
||||
@@ -17552,6 +17552,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
||||
@ -132,7 +132,7 @@ Signed-off-by: Lee Jackson <info@arducam.com>
|
||||
+...
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17548,6 +17548,14 @@ F: Documentation/devicetree/bindings/med
|
||||
@@ -17556,6 +17556,14 @@ F: Documentation/devicetree/bindings/med
|
||||
F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
|
||||
F: drivers/media/i2c/imx477.c
|
||||
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
From 86fc59ef818beb0e1945d17f8e734898baba7e4e Mon Sep 17 00:00:00 2001
|
||||
From: Colin Foster <colin.foster@in-advantage.com>
|
||||
Date: Sun, 13 Mar 2022 15:45:23 -0700
|
||||
Subject: [PATCH 1/2] regmap: add configurable downshift for addresses
|
||||
|
||||
Add an additional reg_downshift to be applied to register addresses before
|
||||
any register accesses. An example of a device that uses this is a VSC7514
|
||||
chip, which require each register address to be downshifted by two if the
|
||||
access is performed over a SPI bus.
|
||||
|
||||
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
|
||||
Link: https://lore.kernel.org/r/20220313224524.399947-2-colin.foster@in-advantage.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/base/regmap/internal.h | 1 +
|
||||
drivers/base/regmap/regmap.c | 5 +++++
|
||||
include/linux/regmap.h | 3 +++
|
||||
3 files changed, 9 insertions(+)
|
||||
|
||||
--- a/drivers/base/regmap/internal.h
|
||||
+++ b/drivers/base/regmap/internal.h
|
||||
@@ -31,6 +31,7 @@ struct regmap_format {
|
||||
size_t buf_size;
|
||||
size_t reg_bytes;
|
||||
size_t pad_bytes;
|
||||
+ size_t reg_downshift;
|
||||
size_t val_bytes;
|
||||
void (*format_write)(struct regmap *map,
|
||||
unsigned int reg, unsigned int val);
|
||||
--- a/drivers/base/regmap/regmap.c
|
||||
+++ b/drivers/base/regmap/regmap.c
|
||||
@@ -823,6 +823,7 @@ struct regmap *__regmap_init(struct devi
|
||||
|
||||
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
|
||||
map->format.pad_bytes = config->pad_bits / 8;
|
||||
+ map->format.reg_downshift = config->reg_downshift;
|
||||
map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
|
||||
map->format.buf_size = DIV_ROUND_UP(config->reg_bits +
|
||||
config->val_bits + config->pad_bits, 8);
|
||||
@@ -1735,6 +1736,7 @@ static int _regmap_raw_write_impl(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
map->format.format_reg(map->work_buf, reg, map->reg_shift);
|
||||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
|
||||
map->write_flag_mask);
|
||||
@@ -1905,6 +1907,7 @@ static int _regmap_bus_formatted_write(v
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
map->format.format_write(map, reg, val);
|
||||
|
||||
trace_regmap_hw_write_start(map, reg, 1);
|
||||
@@ -2346,6 +2349,7 @@ static int _regmap_raw_multi_reg_write(s
|
||||
unsigned int reg = regs[i].reg;
|
||||
unsigned int val = regs[i].def;
|
||||
trace_regmap_hw_write_start(map, reg, 1);
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
map->format.format_reg(u8, reg, map->reg_shift);
|
||||
u8 += reg_bytes + pad_bytes;
|
||||
map->format.format_val(u8, val, 0);
|
||||
@@ -2673,6 +2677,7 @@ static int _regmap_raw_read(struct regma
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
map->format.format_reg(map->work_buf, reg, map->reg_shift);
|
||||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
|
||||
map->read_flag_mask);
|
||||
--- a/include/linux/regmap.h
|
||||
+++ b/include/linux/regmap.h
|
||||
@@ -237,6 +237,8 @@ typedef void (*regmap_unlock)(void *);
|
||||
* @reg_stride: The register address stride. Valid register addresses are a
|
||||
* multiple of this value. If set to 0, a value of 1 will be
|
||||
* used.
|
||||
+ * @reg_downshift: The number of bits to downshift the register before
|
||||
+ * performing any operations.
|
||||
* @pad_bits: Number of bits of padding between register and value.
|
||||
* @val_bits: Number of bits in a register value, mandatory.
|
||||
*
|
||||
@@ -360,6 +362,7 @@ struct regmap_config {
|
||||
|
||||
int reg_bits;
|
||||
int reg_stride;
|
||||
+ int reg_downshift;
|
||||
int pad_bits;
|
||||
int val_bits;
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
From 0074f3f2b1e43d3cedd97e47fb6980db6d2ba79e Mon Sep 17 00:00:00 2001
|
||||
From: Colin Foster <colin.foster@in-advantage.com>
|
||||
Date: Sun, 13 Mar 2022 15:45:24 -0700
|
||||
Subject: [PATCH 2/2] regmap: allow a defined reg_base to be added to every
|
||||
address
|
||||
|
||||
There's an inconsistency that arises when a register set can be accessed
|
||||
internally via MMIO, or externally via SPI. The VSC7514 chip allows both
|
||||
modes of operation. When internally accessed, the system utilizes __iomem,
|
||||
devm_ioremap_resource, and devm_regmap_init_mmio.
|
||||
|
||||
For SPI it isn't possible to utilize memory-mapped IO. To properly operate,
|
||||
the resource base must be added to the register before every operation.
|
||||
|
||||
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
|
||||
Link: https://lore.kernel.org/r/20220313224524.399947-3-colin.foster@in-advantage.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/base/regmap/internal.h | 1 +
|
||||
drivers/base/regmap/regmap.c | 6 ++++++
|
||||
include/linux/regmap.h | 3 +++
|
||||
3 files changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/base/regmap/internal.h
|
||||
+++ b/drivers/base/regmap/internal.h
|
||||
@@ -63,6 +63,7 @@ struct regmap {
|
||||
regmap_unlock unlock;
|
||||
void *lock_arg; /* This is passed to lock/unlock functions */
|
||||
gfp_t alloc_flags;
|
||||
+ unsigned int reg_base;
|
||||
|
||||
struct device *dev; /* Device we do I/O on */
|
||||
void *work_buf; /* Scratch buffer used to format I/O */
|
||||
--- a/drivers/base/regmap/regmap.c
|
||||
+++ b/drivers/base/regmap/regmap.c
|
||||
@@ -821,6 +821,8 @@ struct regmap *__regmap_init(struct devi
|
||||
else
|
||||
map->alloc_flags = GFP_KERNEL;
|
||||
|
||||
+ map->reg_base = config->reg_base;
|
||||
+
|
||||
map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
|
||||
map->format.pad_bytes = config->pad_bits / 8;
|
||||
map->format.reg_downshift = config->reg_downshift;
|
||||
@@ -1736,6 +1738,7 @@ static int _regmap_raw_write_impl(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ reg += map->reg_base;
|
||||
reg >>= map->format.reg_downshift;
|
||||
map->format.format_reg(map->work_buf, reg, map->reg_shift);
|
||||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
|
||||
@@ -1907,6 +1910,7 @@ static int _regmap_bus_formatted_write(v
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ reg += map->reg_base;
|
||||
reg >>= map->format.reg_downshift;
|
||||
map->format.format_write(map, reg, val);
|
||||
|
||||
@@ -2349,6 +2353,7 @@ static int _regmap_raw_multi_reg_write(s
|
||||
unsigned int reg = regs[i].reg;
|
||||
unsigned int val = regs[i].def;
|
||||
trace_regmap_hw_write_start(map, reg, 1);
|
||||
+ reg += map->reg_base;
|
||||
reg >>= map->format.reg_downshift;
|
||||
map->format.format_reg(u8, reg, map->reg_shift);
|
||||
u8 += reg_bytes + pad_bytes;
|
||||
@@ -2677,6 +2682,7 @@ static int _regmap_raw_read(struct regma
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ reg += map->reg_base;
|
||||
reg >>= map->format.reg_downshift;
|
||||
map->format.format_reg(map->work_buf, reg, map->reg_shift);
|
||||
regmap_set_work_buf_flag_mask(map, map->format.reg_bytes,
|
||||
--- a/include/linux/regmap.h
|
||||
+++ b/include/linux/regmap.h
|
||||
@@ -239,6 +239,8 @@ typedef void (*regmap_unlock)(void *);
|
||||
* used.
|
||||
* @reg_downshift: The number of bits to downshift the register before
|
||||
* performing any operations.
|
||||
+ * @reg_base: Value to be added to every register address before performing any
|
||||
+ * operation.
|
||||
* @pad_bits: Number of bits of padding between register and value.
|
||||
* @val_bits: Number of bits in a register value, mandatory.
|
||||
*
|
||||
@@ -363,6 +365,7 @@ struct regmap_config {
|
||||
int reg_bits;
|
||||
int reg_stride;
|
||||
int reg_downshift;
|
||||
+ unsigned int reg_base;
|
||||
int pad_bits;
|
||||
int val_bits;
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 697c3892d825fb78f42ec8e53bed065dd728db3e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 30 Jan 2023 02:04:57 +0000
|
||||
Subject: [PATCH] regmap: apply reg_base and reg_downshift for single register
|
||||
ops
|
||||
|
||||
reg_base and reg_downshift currently don't have any effect if used with
|
||||
a regmap_bus or regmap_config which only offers single register
|
||||
operations (ie. reg_read, reg_write and optionally reg_update_bits).
|
||||
|
||||
Fix that and take them into account also for regmap_bus with only
|
||||
reg_read and read_write operations by applying reg_base and
|
||||
reg_downshift in _regmap_bus_reg_write, _regmap_bus_reg_read.
|
||||
|
||||
Also apply reg_base and reg_downshift in _regmap_update_bits, but only
|
||||
in case the operation is carried out with a reg_update_bits call
|
||||
defined in either regmap_bus or regmap_config.
|
||||
|
||||
Fixes: 0074f3f2b1e43d ("regmap: allow a defined reg_base to be added to every address")
|
||||
Fixes: 86fc59ef818beb ("regmap: add configurable downshift for addresses")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Colin Foster <colin.foster@in-advantage.com>
|
||||
Link: https://lore.kernel.org/r/Y9clyVS3tQEHlUhA@makrotopia.org
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
drivers/base/regmap/regmap.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/base/regmap/regmap.c
|
||||
+++ b/drivers/base/regmap/regmap.c
|
||||
@@ -1929,6 +1929,8 @@ static int _regmap_bus_reg_write(void *c
|
||||
{
|
||||
struct regmap *map = context;
|
||||
|
||||
+ reg += map->reg_base;
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
return map->bus->reg_write(map->bus_context, reg, val);
|
||||
}
|
||||
|
||||
@@ -2703,6 +2705,8 @@ static int _regmap_bus_reg_read(void *co
|
||||
{
|
||||
struct regmap *map = context;
|
||||
|
||||
+ reg += map->reg_base;
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
return map->bus->reg_read(map->bus_context, reg, val);
|
||||
}
|
||||
|
||||
@@ -3078,6 +3082,8 @@ static int _regmap_update_bits(struct re
|
||||
*change = false;
|
||||
|
||||
if (regmap_volatile(map, reg) && map->reg_update_bits) {
|
||||
+ reg += map->reg_base;
|
||||
+ reg >>= map->format.reg_downshift;
|
||||
ret = map->reg_update_bits(map->bus_context, reg, mask, val);
|
||||
if (ret == 0 && change)
|
||||
*change = true;
|
||||
@ -0,0 +1,35 @@
|
||||
From ebed787a0becb9354f0a23620a5130cccd6c730c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 19 Jan 2023 03:45:43 +0000
|
||||
Subject: [PATCH] mtd: spinand: macronix: use scratch buffer for DMA operation
|
||||
|
||||
The mx35lf1ge4ab_get_eccsr() function uses an SPI DMA operation to
|
||||
read the eccsr, hence the buffer should not be on stack. Since commit
|
||||
380583227c0c7f ("spi: spi-mem: Add extra sanity checks on the op param")
|
||||
the kernel emmits a warning and blocks such operations.
|
||||
|
||||
Use the scratch buffer to get eccsr instead of trying to directly read
|
||||
into a stack-allocated variable.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Dhruva Gole <d-gole@ti.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/Y8i85zM0u4XdM46z@makrotopia.org
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -83,9 +83,10 @@ static int mx35lf1ge4ab_ecc_get_status(s
|
||||
* in order to avoid forcing the wear-leveling layer to move
|
||||
* data around if it's not necessary.
|
||||
*/
|
||||
- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
|
||||
+ if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf))
|
||||
return nanddev_get_ecc_conf(nand)->strength;
|
||||
|
||||
+ eccsr = *spinand->scratchbuf;
|
||||
if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength ||
|
||||
!eccsr))
|
||||
return nanddev_get_ecc_conf(nand)->strength;
|
||||
@ -0,0 +1,394 @@
|
||||
From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 19 Mar 2023 12:57:50 +0000
|
||||
Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS
|
||||
|
||||
The SGMII core found in several MediaTek SoCs is identical to what can
|
||||
also be found in MediaTek's MT7531 Ethernet switch IC.
|
||||
As this has not always been clear, both drivers developed different
|
||||
implementations to deal with the PCS.
|
||||
Recently Alexander Couzens pointed out this fact which lead to the
|
||||
development of this shared driver.
|
||||
|
||||
Add a dedicated driver, mostly by copying the code now found in the
|
||||
Ethernet driver. The now redundant code will be removed by a follow-up
|
||||
commit.
|
||||
|
||||
Suggested-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
Suggested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
MAINTAINERS | 8 +
|
||||
drivers/net/pcs/Kconfig | 7 +
|
||||
drivers/net/pcs/Makefile | 1 +
|
||||
drivers/net/pcs/pcs-mtk-lynxi.c | 305 ++++++++++++++++++++++++++++++
|
||||
include/linux/pcs/pcs-mtk-lynxi.h | 13 ++
|
||||
5 files changed, 334 insertions(+)
|
||||
create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
|
||||
create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -11790,6 +11790,14 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/mediatek/
|
||||
|
||||
+MEDIATEK ETHERNET PCS DRIVER
|
||||
+M: Alexander Couzens <lynxis@fe80.eu>
|
||||
+M: Daniel Golle <daniel@makrotopia.org>
|
||||
+L: netdev@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: drivers/net/pcs/pcs-mtk-lynxi.c
|
||||
+F: include/linux/pcs/pcs-mtk-lynxi.h
|
||||
+
|
||||
MEDIATEK I2C CONTROLLER DRIVER
|
||||
M: Qii Wang <qii.wang@mediatek.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
--- a/drivers/net/pcs/Kconfig
|
||||
+++ b/drivers/net/pcs/Kconfig
|
||||
@@ -18,4 +18,11 @@ config PCS_LYNX
|
||||
This module provides helpers to phylink for managing the Lynx PCS
|
||||
which is part of the Layerscape and QorIQ Ethernet SERDES.
|
||||
|
||||
+config PCS_MTK_LYNXI
|
||||
+ tristate
|
||||
+ select REGMAP
|
||||
+ help
|
||||
+ This module provides helpers to phylink for managing the LynxI PCS
|
||||
+ which is part of MediaTek's SoC and Ethernet switch ICs.
|
||||
+
|
||||
endmenu
|
||||
--- a/drivers/net/pcs/Makefile
|
||||
+++ b/drivers/net/pcs/Makefile
|
||||
@@ -5,3 +5,4 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.
|
||||
|
||||
obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
|
||||
obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
|
||||
+obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
|
||||
@@ -0,0 +1,305 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+// Copyright (c) 2018-2019 MediaTek Inc.
|
||||
+/* A library for MediaTek SGMII circuit
|
||||
+ *
|
||||
+ * Author: Sean Wang <sean.wang@mediatek.com>
|
||||
+ * Author: Alexander Couzens <lynxis@fe80.eu>
|
||||
+ * Author: Daniel Golle <daniel@makrotopia.org>
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/mdio.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
+#include <linux/phylink.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+/* SGMII subsystem config registers */
|
||||
+/* BMCR (low 16) BMSR (high 16) */
|
||||
+#define SGMSYS_PCS_CONTROL_1 0x0
|
||||
+#define SGMII_BMCR GENMASK(15, 0)
|
||||
+#define SGMII_BMSR GENMASK(31, 16)
|
||||
+
|
||||
+#define SGMSYS_PCS_DEVICE_ID 0x4
|
||||
+#define SGMII_LYNXI_DEV_ID 0x4d544950
|
||||
+
|
||||
+#define SGMSYS_PCS_ADVERTISE 0x8
|
||||
+#define SGMII_ADVERTISE GENMASK(15, 0)
|
||||
+#define SGMII_LPA GENMASK(31, 16)
|
||||
+
|
||||
+#define SGMSYS_PCS_SCRATCH 0x14
|
||||
+#define SGMII_DEV_VERSION GENMASK(31, 16)
|
||||
+
|
||||
+/* Register to programmable link timer, the unit in 2 * 8ns */
|
||||
+#define SGMSYS_PCS_LINK_TIMER 0x18
|
||||
+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
|
||||
+#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \
|
||||
+ ((ns) / 2 / 8))
|
||||
+
|
||||
+/* Register to control remote fault */
|
||||
+#define SGMSYS_SGMII_MODE 0x20
|
||||
+#define SGMII_IF_MODE_SGMII BIT(0)
|
||||
+#define SGMII_SPEED_DUPLEX_AN BIT(1)
|
||||
+#define SGMII_SPEED_MASK GENMASK(3, 2)
|
||||
+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
|
||||
+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
|
||||
+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
|
||||
+#define SGMII_DUPLEX_HALF BIT(4)
|
||||
+#define SGMII_REMOTE_FAULT_DIS BIT(8)
|
||||
+
|
||||
+/* Register to reset SGMII design */
|
||||
+#define SGMSYS_RESERVED_0 0x34
|
||||
+#define SGMII_SW_RESET BIT(0)
|
||||
+
|
||||
+/* Register to set SGMII speed, ANA RG_ Control Signals III */
|
||||
+#define SGMII_PHY_SPEED_MASK GENMASK(3, 2)
|
||||
+#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0)
|
||||
+#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1)
|
||||
+
|
||||
+/* Register to power up QPHY */
|
||||
+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
|
||||
+#define SGMII_PHYA_PWD BIT(4)
|
||||
+
|
||||
+/* Register to QPHY wrapper control */
|
||||
+#define SGMSYS_QPHY_WRAP_CTRL 0xec
|
||||
+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
|
||||
+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
|
||||
+
|
||||
+/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated
|
||||
+ * data
|
||||
+ * @regmap: The register map pointing at the range used to setup
|
||||
+ * SGMII modes
|
||||
+ * @dev: Pointer to device owning the PCS
|
||||
+ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap
|
||||
+ * @interface: Currently configured interface mode
|
||||
+ * @pcs: Phylink PCS structure
|
||||
+ * @flags: Flags indicating hardware properties
|
||||
+ */
|
||||
+struct mtk_pcs_lynxi {
|
||||
+ struct regmap *regmap;
|
||||
+ u32 ana_rgc3;
|
||||
+ phy_interface_t interface;
|
||||
+ struct phylink_pcs pcs;
|
||||
+ u32 flags;
|
||||
+};
|
||||
+
|
||||
+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ return container_of(pcs, struct mtk_pcs_lynxi, pcs);
|
||||
+}
|
||||
+
|
||||
+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
|
||||
+ unsigned int bm, adv;
|
||||
+
|
||||
+ /* Read the BMSR and LPA */
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
|
||||
+
|
||||
+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
|
||||
+ FIELD_GET(SGMII_LPA, adv));
|
||||
+}
|
||||
+
|
||||
+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
+ phy_interface_t interface,
|
||||
+ const unsigned long *advertising,
|
||||
+ bool permit_pause_to_mac)
|
||||
+{
|
||||
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
|
||||
+ bool mode_changed = false, changed, use_an;
|
||||
+ unsigned int rgc3, sgm_mode, bmcr;
|
||||
+ int advertise, link_timer;
|
||||
+
|
||||
+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
|
||||
+ advertising);
|
||||
+ if (advertise < 0)
|
||||
+ return advertise;
|
||||
+
|
||||
+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
|
||||
+ * we assume that fixes it's speed at bitrate = line rate (in
|
||||
+ * other words, 1000Mbps or 2500Mbps).
|
||||
+ */
|
||||
+ if (interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
+ sgm_mode = SGMII_IF_MODE_SGMII;
|
||||
+ if (phylink_autoneg_inband(mode)) {
|
||||
+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
|
||||
+ SGMII_SPEED_DUPLEX_AN;
|
||||
+ use_an = true;
|
||||
+ } else {
|
||||
+ use_an = false;
|
||||
+ }
|
||||
+ } else if (phylink_autoneg_inband(mode)) {
|
||||
+ /* 1000base-X or 2500base-X autoneg */
|
||||
+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
|
||||
+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
|
||||
+ advertising);
|
||||
+ } else {
|
||||
+ /* 1000base-X or 2500base-X without autoneg */
|
||||
+ sgm_mode = 0;
|
||||
+ use_an = false;
|
||||
+ }
|
||||
+
|
||||
+ if (use_an)
|
||||
+ bmcr = BMCR_ANENABLE;
|
||||
+ else
|
||||
+ bmcr = 0;
|
||||
+
|
||||
+ if (mpcs->interface != interface) {
|
||||
+ link_timer = phylink_get_link_timer_ns(interface);
|
||||
+ if (link_timer < 0)
|
||||
+ return link_timer;
|
||||
+
|
||||
+ /* PHYA power down */
|
||||
+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
+ SGMII_PHYA_PWD);
|
||||
+
|
||||
+ /* Reset SGMII PCS state */
|
||||
+ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0,
|
||||
+ SGMII_SW_RESET);
|
||||
+
|
||||
+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
|
||||
+ SGMII_PN_SWAP_MASK,
|
||||
+ SGMII_PN_SWAP_TX_RX);
|
||||
+
|
||||
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
+ rgc3 = SGMII_PHY_SPEED_3_125G;
|
||||
+ else
|
||||
+ rgc3 = SGMII_PHY_SPEED_1_25G;
|
||||
+
|
||||
+ /* Configure the underlying interface speed */
|
||||
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
+ SGMII_PHY_SPEED_MASK, rgc3);
|
||||
+
|
||||
+ /* Setup the link timer */
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
+ SGMII_LINK_TIMER_VAL(link_timer));
|
||||
+
|
||||
+ mpcs->interface = interface;
|
||||
+ mode_changed = true;
|
||||
+ }
|
||||
+
|
||||
+ /* Update the advertisement, noting whether it has changed */
|
||||
+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
||||
+ SGMII_ADVERTISE, advertise, &changed);
|
||||
+
|
||||
+ /* Update the sgmsys mode register */
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
|
||||
+ SGMII_IF_MODE_SGMII, sgm_mode);
|
||||
+
|
||||
+ /* Update the BMCR */
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
+ BMCR_ANENABLE, bmcr);
|
||||
+
|
||||
+ /* Release PHYA power down state
|
||||
+ * Only removing bit SGMII_PHYA_PWD isn't enough.
|
||||
+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
|
||||
+ * prevents SGMII from working. The SGMII still shows link but no traffic
|
||||
+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
|
||||
+ * taken from a good working state of the SGMII interface.
|
||||
+ * Unknown how much the QPHY needs but it is racy without a sleep.
|
||||
+ * Tested on mt7622 & mt7986.
|
||||
+ */
|
||||
+ usleep_range(50, 100);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
|
||||
+
|
||||
+ return changed || mode_changed;
|
||||
+}
|
||||
+
|
||||
+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
|
||||
+
|
||||
+ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART);
|
||||
+}
|
||||
+
|
||||
+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode,
|
||||
+ phy_interface_t interface, int speed,
|
||||
+ int duplex)
|
||||
+{
|
||||
+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
|
||||
+ unsigned int sgm_mode;
|
||||
+
|
||||
+ if (!phylink_autoneg_inband(mode)) {
|
||||
+ /* Force the speed and duplex setting */
|
||||
+ if (speed == SPEED_10)
|
||||
+ sgm_mode = SGMII_SPEED_10;
|
||||
+ else if (speed == SPEED_100)
|
||||
+ sgm_mode = SGMII_SPEED_100;
|
||||
+ else
|
||||
+ sgm_mode = SGMII_SPEED_1000;
|
||||
+
|
||||
+ if (duplex != DUPLEX_FULL)
|
||||
+ sgm_mode |= SGMII_DUPLEX_HALF;
|
||||
+
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
|
||||
+ sgm_mode);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
|
||||
+ .pcs_get_state = mtk_pcs_lynxi_get_state,
|
||||
+ .pcs_config = mtk_pcs_lynxi_config,
|
||||
+ .pcs_an_restart = mtk_pcs_lynxi_restart_an,
|
||||
+ .pcs_link_up = mtk_pcs_lynxi_link_up,
|
||||
+};
|
||||
+
|
||||
+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
|
||||
+ struct regmap *regmap, u32 ana_rgc3,
|
||||
+ u32 flags)
|
||||
+{
|
||||
+ struct mtk_pcs_lynxi *mpcs;
|
||||
+ u32 id, ver;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id);
|
||||
+ if (ret < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (id != SGMII_LYNXI_DEV_ID) {
|
||||
+ dev_err(dev, "unknown PCS device id %08x\n", id);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver);
|
||||
+ if (ret < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ver = FIELD_GET(SGMII_DEV_VERSION, ver);
|
||||
+ if (ver != 0x1) {
|
||||
+ dev_err(dev, "unknown PCS device version %04x\n", ver);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id,
|
||||
+ ver);
|
||||
+
|
||||
+ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL);
|
||||
+ if (!mpcs)
|
||||
+ return NULL;
|
||||
+
|
||||
+ mpcs->ana_rgc3 = ana_rgc3;
|
||||
+ mpcs->regmap = regmap;
|
||||
+ mpcs->flags = flags;
|
||||
+ mpcs->pcs.ops = &mtk_pcs_lynxi_ops;
|
||||
+ mpcs->pcs.poll = true;
|
||||
+ mpcs->interface = PHY_INTERFACE_MODE_NA;
|
||||
+
|
||||
+ return &mpcs->pcs;
|
||||
+}
|
||||
+EXPORT_SYMBOL(mtk_pcs_lynxi_create);
|
||||
+
|
||||
+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs)
|
||||
+{
|
||||
+ if (!pcs)
|
||||
+ return;
|
||||
+
|
||||
+ kfree(pcs_to_mtk_pcs_lynxi(pcs));
|
||||
+}
|
||||
+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- /dev/null
|
||||
+++ b/include/linux/pcs/pcs-mtk-lynxi.h
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef __LINUX_PCS_MTK_LYNXI_H
|
||||
+#define __LINUX_PCS_MTK_LYNXI_H
|
||||
+
|
||||
+#include <linux/phylink.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
|
||||
+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
|
||||
+ struct regmap *regmap,
|
||||
+ u32 ana_rgc3, u32 flags);
|
||||
+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
|
||||
+#endif
|
||||
@ -0,0 +1,55 @@
|
||||
From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:10:42 +0100
|
||||
Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS
|
||||
|
||||
As a result of help from Frank Wunderlich to investigate and test, we
|
||||
know a bit more about the PCS on the Mediatek platforms. Update the
|
||||
definitions from this investigation.
|
||||
|
||||
This PCS appears similar, but not identical to the Lynx PCS.
|
||||
|
||||
Although not included in this patch, but for future reference, the PHY
|
||||
ID registers at offset 4 read as 0x4d544950 'MTIP'.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++---
|
||||
1 file changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -501,8 +501,10 @@
|
||||
#define ETHSYS_DMA_AG_MAP_PPE BIT(2)
|
||||
|
||||
/* SGMII subsystem config registers */
|
||||
-/* Register to auto-negotiation restart */
|
||||
+/* BMCR (low 16) BMSR (high 16) */
|
||||
#define SGMSYS_PCS_CONTROL_1 0x0
|
||||
+#define SGMII_BMCR GENMASK(15, 0)
|
||||
+#define SGMII_BMSR GENMASK(31, 16)
|
||||
#define SGMII_AN_RESTART BIT(9)
|
||||
#define SGMII_ISOLATE BIT(10)
|
||||
#define SGMII_AN_ENABLE BIT(12)
|
||||
@@ -512,13 +514,18 @@
|
||||
#define SGMII_PCS_FAULT BIT(23)
|
||||
#define SGMII_AN_EXPANSION_CLR BIT(30)
|
||||
|
||||
+#define SGMSYS_PCS_ADVERTISE 0x8
|
||||
+#define SGMII_ADVERTISE GENMASK(15, 0)
|
||||
+#define SGMII_LPA GENMASK(31, 16)
|
||||
+
|
||||
/* Register to programmable link timer, the unit in 2 * 8ns */
|
||||
#define SGMSYS_PCS_LINK_TIMER 0x18
|
||||
-#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0))
|
||||
+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
|
||||
+#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
|
||||
|
||||
/* Register to control remote fault */
|
||||
#define SGMSYS_SGMII_MODE 0x20
|
||||
-#define SGMII_IF_MODE_BIT0 BIT(0)
|
||||
+#define SGMII_IF_MODE_SGMII BIT(0)
|
||||
#define SGMII_SPEED_DUPLEX_AN BIT(1)
|
||||
#define SGMII_SPEED_MASK GENMASK(3, 2)
|
||||
#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
|
||||
@ -0,0 +1,74 @@
|
||||
From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:10:47 +0100
|
||||
Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling
|
||||
|
||||
The functions called by the pcs_config() method always return zero, so
|
||||
there is no point trying to handle an error from these functions. Make
|
||||
these functions void, eliminate the "err" variable and simply return
|
||||
zero from the pcs_config() function itself.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------
|
||||
1 file changed, 6 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -20,7 +20,7 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
|
||||
}
|
||||
|
||||
/* For SGMII interface mode */
|
||||
-static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
+static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct
|
||||
regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
val &= ~SGMII_PHYA_PWD;
|
||||
regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
}
|
||||
|
||||
/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
* fixed speed.
|
||||
*/
|
||||
-static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
|
||||
- phy_interface_t interface)
|
||||
+static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
|
||||
+ phy_interface_t interface)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru
|
||||
regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
val &= ~SGMII_PHYA_PWD;
|
||||
regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink
|
||||
bool permit_pause_to_mac)
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
- int err = 0;
|
||||
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
- err = mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
+ mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
else if (phylink_autoneg_inband(mode))
|
||||
- err = mtk_pcs_setup_mode_an(mpcs);
|
||||
+ mtk_pcs_setup_mode_an(mpcs);
|
||||
|
||||
- return err;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
@ -0,0 +1,46 @@
|
||||
From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:10:52 +0100
|
||||
Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation
|
||||
|
||||
Add a pcs_get_state() implementation which uses the advertisements
|
||||
to compute the resulting link modes, and BMSR contents to determine
|
||||
negotiation and link status.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
|
||||
return container_of(pcs, struct mtk_pcs, pcs);
|
||||
}
|
||||
|
||||
+static void mtk_pcs_get_state(struct phylink_pcs *pcs,
|
||||
+ struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
+ unsigned int bm, adv;
|
||||
+
|
||||
+ /* Read the BMSR and LPA */
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
|
||||
+
|
||||
+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
|
||||
+ FIELD_GET(SGMII_LPA, adv));
|
||||
+}
|
||||
+
|
||||
/* For SGMII interface mode */
|
||||
static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
{
|
||||
@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli
|
||||
}
|
||||
|
||||
static const struct phylink_pcs_ops mtk_pcs_ops = {
|
||||
+ .pcs_get_state = mtk_pcs_get_state,
|
||||
.pcs_config = mtk_pcs_config,
|
||||
.pcs_an_restart = mtk_pcs_restart_an,
|
||||
.pcs_link_up = mtk_pcs_link_up,
|
||||
@ -0,0 +1,130 @@
|
||||
From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:10:58 +0100
|
||||
Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use
|
||||
regmap_update_bits()
|
||||
|
||||
mtk_sgmii does a lot of read-modify-write operations, for which there
|
||||
is a specific regmap function. Use this function instead of open-coding
|
||||
the operations.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++-------------
|
||||
1 file changed, 26 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy
|
||||
/* For SGMII interface mode */
|
||||
static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
{
|
||||
- unsigned int val;
|
||||
-
|
||||
/* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
SGMII_LINK_TIMER_DEFAULT);
|
||||
|
||||
- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
- val |= SGMII_REMOTE_FAULT_DIS;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
-
|
||||
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
- val |= SGMII_AN_RESTART;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
-
|
||||
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
- val &= ~SGMII_PHYA_PWD;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
|
||||
+
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
+ SGMII_AN_RESTART, SGMII_AN_RESTART);
|
||||
+
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
+ SGMII_PHYA_PWD, 0);
|
||||
}
|
||||
|
||||
/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct
|
||||
static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- unsigned int val;
|
||||
+ unsigned int rgc3;
|
||||
|
||||
- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
|
||||
- val &= ~RG_PHY_SPEED_MASK;
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
- val |= RG_PHY_SPEED_3_125G;
|
||||
- regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
|
||||
+ rgc3 = RG_PHY_SPEED_3_125G;
|
||||
+
|
||||
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
+ RG_PHY_SPEED_3_125G, rgc3);
|
||||
|
||||
/* Disable SGMII AN */
|
||||
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
- val &= ~SGMII_AN_ENABLE;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
+ SGMII_AN_ENABLE, 0);
|
||||
|
||||
/* Set the speed etc but leave the duplex unchanged */
|
||||
- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
|
||||
- val |= SGMII_SPEED_1000;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
|
||||
+ SGMII_SPEED_1000);
|
||||
|
||||
/* Release PHYA power down state */
|
||||
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
- val &= ~SGMII_PHYA_PWD;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
+ SGMII_PHYA_PWD, 0);
|
||||
}
|
||||
|
||||
static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink
|
||||
static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
- unsigned int val;
|
||||
|
||||
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
- val |= SGMII_AN_RESTART;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
+ SGMII_AN_RESTART, SGMII_AN_RESTART);
|
||||
}
|
||||
|
||||
static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
|
||||
phy_interface_t interface, int speed, int duplex)
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
- unsigned int val;
|
||||
+ unsigned int sgm_mode;
|
||||
|
||||
if (!phy_interface_mode_is_8023z(interface))
|
||||
return;
|
||||
|
||||
/* SGMII force duplex setting */
|
||||
- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
- val &= ~SGMII_DUPLEX_FULL;
|
||||
if (duplex == DUPLEX_FULL)
|
||||
- val |= SGMII_DUPLEX_FULL;
|
||||
+ sgm_mode = SGMII_DUPLEX_FULL;
|
||||
+ else
|
||||
+ sgm_mode = 0;
|
||||
|
||||
- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_DUPLEX_FULL, sgm_mode);
|
||||
}
|
||||
|
||||
static const struct phylink_pcs_ops mtk_pcs_ops = {
|
||||
@ -0,0 +1,52 @@
|
||||
From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:11:03 +0100
|
||||
Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and
|
||||
duplex in pcs_link_up
|
||||
|
||||
Add support for forcing the link speed and duplex setting in the
|
||||
pcs_link_up() method for out of band modes, which will be useful when
|
||||
we finish converting the pcs_config() method. Until then, we still have
|
||||
to force duplex for 802.3z modes to work correctly.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++---------
|
||||
1 file changed, 17 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
unsigned int sgm_mode;
|
||||
|
||||
- if (!phy_interface_mode_is_8023z(interface))
|
||||
- return;
|
||||
+ if (!phylink_autoneg_inband(mode) ||
|
||||
+ phy_interface_mode_is_8023z(interface)) {
|
||||
+ /* Force the speed and duplex setting */
|
||||
+ if (speed == SPEED_10)
|
||||
+ sgm_mode = SGMII_SPEED_10;
|
||||
+ else if (speed == SPEED_100)
|
||||
+ sgm_mode = SGMII_SPEED_100;
|
||||
+ else
|
||||
+ sgm_mode = SGMII_SPEED_1000;
|
||||
|
||||
- /* SGMII force duplex setting */
|
||||
- if (duplex == DUPLEX_FULL)
|
||||
- sgm_mode = SGMII_DUPLEX_FULL;
|
||||
- else
|
||||
- sgm_mode = 0;
|
||||
+ if (duplex == DUPLEX_FULL)
|
||||
+ sgm_mode |= SGMII_DUPLEX_FULL;
|
||||
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
- SGMII_DUPLEX_FULL, sgm_mode);
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
|
||||
+ sgm_mode);
|
||||
+ }
|
||||
}
|
||||
|
||||
static const struct phylink_pcs_ops mtk_pcs_ops = {
|
||||
@ -0,0 +1,48 @@
|
||||
From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:11:08 +0100
|
||||
Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up
|
||||
|
||||
The PHY power up is common to both configuration paths, so move it into
|
||||
the parent function. We need to do this for all serdes modes.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++-------
|
||||
1 file changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct
|
||||
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
SGMII_AN_RESTART, SGMII_AN_RESTART);
|
||||
-
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
- SGMII_PHYA_PWD, 0);
|
||||
}
|
||||
|
||||
/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
|
||||
SGMII_SPEED_1000);
|
||||
-
|
||||
- /* Release PHYA power down state */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
- SGMII_PHYA_PWD, 0);
|
||||
}
|
||||
|
||||
static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink
|
||||
else if (phylink_autoneg_inband(mode))
|
||||
mtk_pcs_setup_mode_an(mpcs);
|
||||
|
||||
+ /* Release PHYA power down state */
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
+ SGMII_PHYA_PWD, 0);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:11:13 +0100
|
||||
Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection
|
||||
|
||||
Move the selection of the underlying interface speed to the pcs_config
|
||||
function, so we always program the interface speed.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct
|
||||
static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
- unsigned int rgc3;
|
||||
-
|
||||
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
- rgc3 = RG_PHY_SPEED_3_125G;
|
||||
-
|
||||
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
- RG_PHY_SPEED_3_125G, rgc3);
|
||||
-
|
||||
/* Disable SGMII AN */
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
SGMII_AN_ENABLE, 0);
|
||||
@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink
|
||||
bool permit_pause_to_mac)
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
+ unsigned int rgc3;
|
||||
+
|
||||
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
+ rgc3 = RG_PHY_SPEED_3_125G;
|
||||
+ else
|
||||
+ rgc3 = 0;
|
||||
+
|
||||
+ /* Configure the underlying interface speed */
|
||||
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
+ RG_PHY_SPEED_3_125G, rgc3);
|
||||
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
@ -0,0 +1,52 @@
|
||||
From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:11:18 +0100
|
||||
Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming
|
||||
|
||||
Program the advertisement into the mtk PCS block.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
unsigned int rgc3;
|
||||
+ int advertise;
|
||||
+ bool changed;
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
rgc3 = RG_PHY_SPEED_3_125G;
|
||||
else
|
||||
rgc3 = 0;
|
||||
|
||||
+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
|
||||
+ advertising);
|
||||
+ if (advertise < 0)
|
||||
+ return advertise;
|
||||
+
|
||||
/* Configure the underlying interface speed */
|
||||
regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
RG_PHY_SPEED_3_125G, rgc3);
|
||||
|
||||
+ /* Update the advertisement, noting whether it has changed */
|
||||
+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
||||
+ SGMII_ADVERTISE, advertise, &changed);
|
||||
+
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
SGMII_PHYA_PWD, 0);
|
||||
|
||||
- return 0;
|
||||
+ return changed;
|
||||
}
|
||||
|
||||
static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
@ -0,0 +1,63 @@
|
||||
From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:11:23 +0100
|
||||
Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer
|
||||
programming
|
||||
|
||||
Program the link timer appropriately for the interface mode being
|
||||
used, using the newly introduced phylink helper that provides the
|
||||
nanosecond link timer interval.
|
||||
|
||||
The intervals are 1.6ms for SGMII based protocols and 10ms for
|
||||
802.3z based protocols.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy
|
||||
/* For SGMII interface mode */
|
||||
static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
{
|
||||
- /* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
- SGMII_LINK_TIMER_DEFAULT);
|
||||
-
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
|
||||
|
||||
@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink
|
||||
bool permit_pause_to_mac)
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
+ int advertise, link_timer;
|
||||
unsigned int rgc3;
|
||||
- int advertise;
|
||||
bool changed;
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink
|
||||
if (advertise < 0)
|
||||
return advertise;
|
||||
|
||||
+ link_timer = phylink_get_link_timer_ns(interface);
|
||||
+ if (link_timer < 0)
|
||||
+ return link_timer;
|
||||
+
|
||||
/* Configure the underlying interface speed */
|
||||
regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
RG_PHY_SPEED_3_125G, rgc3);
|
||||
@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink
|
||||
regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
||||
SGMII_ADVERTISE, advertise, &changed);
|
||||
|
||||
+ /* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
|
||||
+
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
@ -0,0 +1,132 @@
|
||||
From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
||||
Date: Thu, 27 Oct 2022 14:11:28 +0100
|
||||
Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z
|
||||
negotiation
|
||||
|
||||
As a result of help from Frank Wunderlich to investigate and test, we
|
||||
now know how to program this PCS for in-band 802.3z negotiation. Add
|
||||
support for this by moving the contents of the two functions into the
|
||||
common mtk_pcs_config() function and adding the register settings for
|
||||
802.3z negotiation.
|
||||
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++-----------
|
||||
1 file changed, 42 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy
|
||||
FIELD_GET(SGMII_LPA, adv));
|
||||
}
|
||||
|
||||
-/* For SGMII interface mode */
|
||||
-static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
-{
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS);
|
||||
-
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
- SGMII_AN_RESTART, SGMII_AN_RESTART);
|
||||
-}
|
||||
-
|
||||
-/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
|
||||
- * fixed speed.
|
||||
- */
|
||||
-static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
|
||||
- phy_interface_t interface)
|
||||
-{
|
||||
- /* Disable SGMII AN */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
- SGMII_AN_ENABLE, 0);
|
||||
-
|
||||
- /* Set the speed etc but leave the duplex unchanged */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL,
|
||||
- SGMII_SPEED_1000);
|
||||
-}
|
||||
-
|
||||
static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
const unsigned long *advertising,
|
||||
bool permit_pause_to_mac)
|
||||
{
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
+ unsigned int rgc3, sgm_mode, bmcr;
|
||||
int advertise, link_timer;
|
||||
- unsigned int rgc3;
|
||||
- bool changed;
|
||||
+ bool changed, use_an;
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
rgc3 = RG_PHY_SPEED_3_125G;
|
||||
@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink
|
||||
if (link_timer < 0)
|
||||
return link_timer;
|
||||
|
||||
+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
|
||||
+ * we assume that fixes it's speed at bitrate = line rate (in
|
||||
+ * other words, 1000Mbps or 2500Mbps).
|
||||
+ */
|
||||
+ if (interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
+ sgm_mode = SGMII_IF_MODE_SGMII;
|
||||
+ if (phylink_autoneg_inband(mode)) {
|
||||
+ sgm_mode |= SGMII_REMOTE_FAULT_DIS |
|
||||
+ SGMII_SPEED_DUPLEX_AN;
|
||||
+ use_an = true;
|
||||
+ } else {
|
||||
+ use_an = false;
|
||||
+ }
|
||||
+ } else if (phylink_autoneg_inband(mode)) {
|
||||
+ /* 1000base-X or 2500base-X autoneg */
|
||||
+ sgm_mode = SGMII_REMOTE_FAULT_DIS;
|
||||
+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
|
||||
+ advertising);
|
||||
+ } else {
|
||||
+ /* 1000base-X or 2500base-X without autoneg */
|
||||
+ sgm_mode = 0;
|
||||
+ use_an = false;
|
||||
+ }
|
||||
+
|
||||
+ if (use_an) {
|
||||
+ /* FIXME: Do we need to set AN_RESTART here? */
|
||||
+ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
|
||||
+ } else {
|
||||
+ bmcr = 0;
|
||||
+ }
|
||||
+
|
||||
/* Configure the underlying interface speed */
|
||||
regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
RG_PHY_SPEED_3_125G, rgc3);
|
||||
@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink
|
||||
/* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
|
||||
|
||||
- /* Setup SGMIISYS with the determined property */
|
||||
- if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
- mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
- else if (phylink_autoneg_inband(mode))
|
||||
- mtk_pcs_setup_mode_an(mpcs);
|
||||
+ /* Update the sgmsys mode register */
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
|
||||
+ SGMII_IF_MODE_SGMII, sgm_mode);
|
||||
+
|
||||
+ /* Update the BMCR */
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
+ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
|
||||
|
||||
/* Release PHYA power down state */
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
unsigned int sgm_mode;
|
||||
|
||||
- if (!phylink_autoneg_inband(mode) ||
|
||||
- phy_interface_mode_is_8023z(interface)) {
|
||||
+ if (!phylink_autoneg_inband(mode)) {
|
||||
/* Force the speed and duplex setting */
|
||||
if (speed == SPEED_10)
|
||||
sgm_mode = SGMII_SPEED_10;
|
||||
@ -1,8 +1,8 @@
|
||||
From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Wed, 1 Feb 2023 19:23:29 +0100
|
||||
Subject: [PATCH] net: mediatek: sgmii: ensure the SGMII PHY is powered down on
|
||||
configuration
|
||||
Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered
|
||||
down on configuration
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1063,11 +1063,13 @@ struct mtk_soc_data {
|
||||
@@ -1070,11 +1070,13 @@ struct mtk_soc_data {
|
||||
* @regmap: The register map pointing at the range used to setup
|
||||
* SGMII modes
|
||||
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
||||
@ -50,57 +50,51 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -24,6 +24,10 @@ static int mtk_pcs_setup_mode_an(struct
|
||||
{
|
||||
unsigned int val;
|
||||
@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink
|
||||
int advertise, link_timer;
|
||||
bool changed, use_an;
|
||||
|
||||
+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
|
||||
+ val &= ~RG_PHY_SPEED_MASK;
|
||||
+ regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
|
||||
+
|
||||
/* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
SGMII_LINK_TIMER_DEFAULT);
|
||||
@@ -36,9 +40,6 @@ static int mtk_pcs_setup_mode_an(struct
|
||||
val |= SGMII_AN_RESTART;
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
|
||||
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
- val &= ~SGMII_PHYA_PWD;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -69,11 +70,6 @@ static int mtk_pcs_setup_mode_force(stru
|
||||
val |= SGMII_SPEED_1000;
|
||||
regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
|
||||
- /* Release PHYA power down state */
|
||||
- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
|
||||
- val &= ~SGMII_PHYA_PWD;
|
||||
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
|
||||
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
- rgc3 = RG_PHY_SPEED_3_125G;
|
||||
- else
|
||||
- rgc3 = 0;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -85,12 +81,32 @@ static int mtk_pcs_config(struct phylink
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
int err = 0;
|
||||
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
|
||||
advertising);
|
||||
if (advertise < 0)
|
||||
@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink
|
||||
bmcr = 0;
|
||||
}
|
||||
|
||||
- /* Configure the underlying interface speed */
|
||||
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
- RG_PHY_SPEED_3_125G, rgc3);
|
||||
+ if (mpcs->interface != interface) {
|
||||
+ /* PHYA power down */
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
+ SGMII_PHYA_PWD, SGMII_PHYA_PWD);
|
||||
+
|
||||
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
+ rgc3 = RG_PHY_SPEED_3_125G;
|
||||
+ else
|
||||
+ rgc3 = 0;
|
||||
+
|
||||
+ /* Configure the underlying interface speed */
|
||||
+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
+ RG_PHY_SPEED_3_125G, rgc3);
|
||||
+
|
||||
+ mpcs->interface = interface;
|
||||
+ }
|
||||
+
|
||||
/* Setup SGMIISYS with the determined property */
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
err = mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
else if (phylink_autoneg_inband(mode))
|
||||
err = mtk_pcs_setup_mode_an(mpcs);
|
||||
|
||||
/* Update the advertisement, noting whether it has changed */
|
||||
regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
||||
@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
|
||||
|
||||
- /* Release PHYA power down state */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
- SGMII_PHYA_PWD, 0);
|
||||
+ /* Release PHYA power down state
|
||||
+ * Only removing bit SGMII_PHYA_PWD isn't enough.
|
||||
+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
|
||||
@ -112,11 +106,10 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
+ */
|
||||
+ usleep_range(50, 100);
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -145,6 +161,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
return changed;
|
||||
}
|
||||
@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
return PTR_ERR(ss->pcs[i].regmap);
|
||||
|
||||
ss->pcs[i].pcs.ops = &mtk_pcs_ops;
|
||||
@ -1,7 +1,7 @@
|
||||
From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
|
||||
Date: Wed, 1 Feb 2023 19:23:30 +0100
|
||||
Subject: [PATCH] net: mediatek: sgmii: fix duplex configuration
|
||||
Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -524,7 +524,7 @@
|
||||
@@ -531,7 +531,7 @@
|
||||
#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
|
||||
#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
|
||||
#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
|
||||
@ -35,26 +35,18 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
#define SGMII_CODE_SYNC_SET_VAL BIT(9)
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -66,7 +66,7 @@ static int mtk_pcs_setup_mode_force(stru
|
||||
@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli
|
||||
else
|
||||
sgm_mode = SGMII_SPEED_1000;
|
||||
|
||||
/* Set the speed etc but leave the duplex unchanged */
|
||||
regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
|
||||
+ val &= SGMII_DUPLEX_HALF | ~SGMII_IF_MODE_MASK;
|
||||
val |= SGMII_SPEED_1000;
|
||||
regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
- if (duplex == DUPLEX_FULL)
|
||||
- sgm_mode |= SGMII_DUPLEX_FULL;
|
||||
+ if (duplex != DUPLEX_FULL)
|
||||
+ sgm_mode |= SGMII_DUPLEX_HALF;
|
||||
|
||||
@@ -131,9 +131,10 @@ static void mtk_pcs_link_up(struct phyli
|
||||
|
||||
/* SGMII force duplex setting */
|
||||
regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
- val &= ~SGMII_DUPLEX_FULL;
|
||||
- if (duplex == DUPLEX_FULL)
|
||||
- val |= SGMII_DUPLEX_FULL;
|
||||
+
|
||||
+ val &= ~SGMII_DUPLEX_HALF;
|
||||
+ if (duplex != DUPLEX_FULL)
|
||||
+ val |= SGMII_DUPLEX_HALF;
|
||||
|
||||
regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK,
|
||||
+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
|
||||
sgm_mode);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Wed, 1 Feb 2023 19:23:31 +0100
|
||||
Subject: [PATCH] mtk_sgmii: enable PCS polling to allow SFP work
|
||||
Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -162,6 +162,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
@@ -187,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
return PTR_ERR(ss->pcs[i].regmap);
|
||||
|
||||
ss->pcs[i].pcs.ops = &mtk_pcs_ops;
|
||||
@ -1,16 +1,20 @@
|
||||
From b66105968b8c37c26a75b9da9281cbc1c8f73594 Mon Sep 17 00:00:00 2001
|
||||
From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 22 Jan 2023 23:58:36 +0000
|
||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: reset PCS state
|
||||
Date: Tue, 14 Mar 2023 00:34:26 +0000
|
||||
Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reset PCS state when changing interface mode.
|
||||
Reset the internal PCS state machine when changing interface mode.
|
||||
This prevents confusing the state machine when changing interface
|
||||
modes, e.g. from SGMII to 2500Base-X or vice-versa.
|
||||
|
||||
Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Bjørn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++
|
||||
@ -18,7 +22,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -530,6 +530,10 @@
|
||||
@@ -539,6 +539,10 @@
|
||||
#define SGMII_SEND_AN_ERROR_EN BIT(11)
|
||||
#define SGMII_IF_MODE_MASK GENMASK(5, 1)
|
||||
|
||||
@ -31,7 +35,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -90,6 +90,10 @@ static int mtk_pcs_config(struct phylink
|
||||
@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
|
||||
|
||||
@ -39,6 +43,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
|
||||
+ SGMII_SW_RESET, SGMII_SW_RESET);
|
||||
+
|
||||
mpcs->interface = interface;
|
||||
}
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
rgc3 = RG_PHY_SPEED_3_125G;
|
||||
else
|
||||
@ -0,0 +1,103 @@
|
||||
From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 14 Mar 2023 00:34:45 +0000
|
||||
Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Only restart auto-negotiation and write link timer if actually
|
||||
necessary. This prevents losing the link in case of minor
|
||||
changes.
|
||||
|
||||
Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Bjørn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
|
||||
1 file changed, 12 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink
|
||||
const unsigned long *advertising,
|
||||
bool permit_pause_to_mac)
|
||||
{
|
||||
+ bool mode_changed = false, changed, use_an;
|
||||
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
unsigned int rgc3, sgm_mode, bmcr;
|
||||
int advertise, link_timer;
|
||||
- bool changed, use_an;
|
||||
|
||||
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
|
||||
advertising);
|
||||
if (advertise < 0)
|
||||
return advertise;
|
||||
|
||||
- link_timer = phylink_get_link_timer_ns(interface);
|
||||
- if (link_timer < 0)
|
||||
- return link_timer;
|
||||
-
|
||||
/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
|
||||
* we assume that fixes it's speed at bitrate = line rate (in
|
||||
* other words, 1000Mbps or 2500Mbps).
|
||||
@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink
|
||||
}
|
||||
|
||||
if (use_an) {
|
||||
- /* FIXME: Do we need to set AN_RESTART here? */
|
||||
- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
|
||||
+ bmcr = SGMII_AN_ENABLE;
|
||||
} else {
|
||||
bmcr = 0;
|
||||
}
|
||||
|
||||
if (mpcs->interface != interface) {
|
||||
+ link_timer = phylink_get_link_timer_ns(interface);
|
||||
+ if (link_timer < 0)
|
||||
+ return link_timer;
|
||||
+
|
||||
/* PHYA power down */
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
|
||||
@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink
|
||||
regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
RG_PHY_SPEED_3_125G, rgc3);
|
||||
|
||||
+ /* Setup the link timer */
|
||||
+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
|
||||
+
|
||||
mpcs->interface = interface;
|
||||
+ mode_changed = true;
|
||||
}
|
||||
|
||||
/* Update the advertisement, noting whether it has changed */
|
||||
regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
||||
SGMII_ADVERTISE, advertise, &changed);
|
||||
|
||||
- /* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
|
||||
-
|
||||
/* Update the sgmsys mode register */
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
|
||||
@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink
|
||||
|
||||
/* Update the BMCR */
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
|
||||
+ SGMII_AN_ENABLE, bmcr);
|
||||
|
||||
/* Release PHYA power down state
|
||||
* Only removing bit SGMII_PHYA_PWD isn't enough.
|
||||
@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink
|
||||
usleep_range(50, 100);
|
||||
regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
|
||||
|
||||
- return changed;
|
||||
+ return changed || mode_changed;
|
||||
}
|
||||
|
||||
static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
@ -0,0 +1,183 @@
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy(
|
||||
|
||||
static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
|
||||
{
|
||||
- unsigned int val = 0;
|
||||
+ unsigned int val = 0, mask = 0, reg = 0;
|
||||
bool updated = true;
|
||||
|
||||
switch (path) {
|
||||
case MTK_ETH_PATH_GMAC2_SGMII:
|
||||
- val = CO_QPHY_SEL;
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
|
||||
+ reg = USB_PHY_SWITCH_REG;
|
||||
+ val = SGMII_QPHY_SEL;
|
||||
+ mask = QPHY_SEL_MASK;
|
||||
+ } else {
|
||||
+ reg = INFRA_MISC2;
|
||||
+ val = CO_QPHY_SEL;
|
||||
+ mask = val;
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
updated = false;
|
||||
@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
|
||||
}
|
||||
|
||||
if (updated)
|
||||
- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
|
||||
+ regmap_update_bits(eth->infra, reg, mask, val);
|
||||
|
||||
dev_dbg(eth->dev, "path %s in %s updated = %d\n",
|
||||
mtk_eth_path_name(path), __func__, updated);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -4757,6 +4757,26 @@ static const struct mtk_soc_data mt7629_
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct mtk_soc_data mt7981_data = {
|
||||
+ .reg_map = &mt7986_reg_map,
|
||||
+ .ana_rgc3 = 0x128,
|
||||
+ .caps = MT7981_CAPS,
|
||||
+ .hw_features = MTK_HW_FEATURES,
|
||||
+ .required_clks = MT7981_CLKS_BITMAP,
|
||||
+ .required_pctl = false,
|
||||
+ .offload_version = 2,
|
||||
+ .hash_offset = 4,
|
||||
+ .foe_entry_size = sizeof(struct mtk_foe_entry),
|
||||
+ .txrx = {
|
||||
+ .txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
+ .dma_len_offset = 8,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct mtk_soc_data mt7986_data = {
|
||||
.reg_map = &mt7986_reg_map,
|
||||
.ana_rgc3 = 0x128,
|
||||
@@ -4799,6 +4819,7 @@ const struct of_device_id of_mtk_match[]
|
||||
{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
|
||||
{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
|
||||
{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
|
||||
+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
|
||||
{ .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
|
||||
{ .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
|
||||
{},
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -553,11 +553,22 @@
|
||||
#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
|
||||
#define SGMII_PHYA_PWD BIT(4)
|
||||
|
||||
+/* Register to QPHY wrapper control */
|
||||
+#define SGMSYS_QPHY_WRAP_CTRL 0xec
|
||||
+#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
|
||||
+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
|
||||
+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
|
||||
+
|
||||
/* Infrasys subsystem config registers */
|
||||
#define INFRA_MISC2 0x70c
|
||||
#define CO_QPHY_SEL BIT(0)
|
||||
#define GEPHY_MAC_SEL BIT(1)
|
||||
|
||||
+/* Top misc registers */
|
||||
+#define USB_PHY_SWITCH_REG 0x218
|
||||
+#define QPHY_SEL_MASK GENMASK(1, 0)
|
||||
+#define SGMII_QPHY_SEL 0x2
|
||||
+
|
||||
/* MT7628/88 specific stuff */
|
||||
#define MT7628_PDMA_OFFSET 0x0800
|
||||
#define MT7628_SDM_OFFSET 0x0c00
|
||||
@@ -738,6 +749,17 @@ enum mtk_clks_map {
|
||||
BIT(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
BIT(MTK_CLK_SGMII_CK) | \
|
||||
BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
|
||||
+#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
|
||||
+ BIT(MTK_CLK_WOCPU0) | \
|
||||
+ BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
+ BIT(MTK_CLK_SGMII_CK))
|
||||
#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
|
||||
BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
|
||||
BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
@@ -851,6 +873,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_NETSYS_V2_BIT,
|
||||
MTK_SOC_MT7628_BIT,
|
||||
MTK_RSTCTRL_PPE1_BIT,
|
||||
+ MTK_U3_COPHY_V2_BIT,
|
||||
|
||||
/* MUX BITS*/
|
||||
MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
|
||||
@@ -885,6 +908,7 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
|
||||
|
||||
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
|
||||
BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
|
||||
@@ -963,6 +987,11 @@ enum mkt_eth_capabilities {
|
||||
MTK_MUX_U3_GMAC2_TO_QPHY | \
|
||||
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
|
||||
|
||||
+#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
|
||||
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
||||
+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
|
||||
+ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
|
||||
+
|
||||
#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
||||
MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
|
||||
@@ -1076,12 +1105,14 @@ struct mtk_soc_data {
|
||||
* @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
||||
* @interface: Currently configured interface mode
|
||||
* @pcs: Phylink PCS structure
|
||||
+ * @flags: Flags indicating hardware properties
|
||||
*/
|
||||
struct mtk_pcs {
|
||||
struct regmap *regmap;
|
||||
u32 ana_rgc3;
|
||||
phy_interface_t interface;
|
||||
struct phylink_pcs pcs;
|
||||
+ u32 flags;
|
||||
};
|
||||
|
||||
/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -87,6 +87,11 @@ static int mtk_pcs_config(struct phylink
|
||||
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
|
||||
|
||||
+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
|
||||
+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
|
||||
+ SGMII_PN_SWAP_MASK,
|
||||
+ SGMII_PN_SWAP_TX_RX);
|
||||
+
|
||||
/* Reset SGMII PCS state */
|
||||
regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
|
||||
SGMII_SW_RESET, SGMII_SW_RESET);
|
||||
@@ -186,6 +191,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
|
||||
|
||||
ss->pcs[i].ana_rgc3 = ana_rgc3;
|
||||
ss->pcs[i].regmap = syscon_node_to_regmap(np);
|
||||
+
|
||||
+ ss->pcs[i].flags = 0;
|
||||
+ if (of_property_read_bool(np, "mediatek,pnswap"))
|
||||
+ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
|
||||
+
|
||||
of_node_put(np);
|
||||
if (IS_ERR(ss->pcs[i].regmap))
|
||||
return PTR_ERR(ss->pcs[i].regmap);
|
||||
@ -0,0 +1,76 @@
|
||||
From c0a440031d4314d1023c1b87f43a4233634eebdb Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 19 Mar 2023 12:57:15 +0000
|
||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: set MDIO bus clock frequency
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Set MDIO bus clock frequency and allow setting a custom maximum
|
||||
frequency from device tree.
|
||||
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
||||
Tested-by: Bjørn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++
|
||||
2 files changed, 28 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -704,8 +704,10 @@ static const struct phylink_mac_ops mtk_
|
||||
|
||||
static int mtk_mdio_init(struct mtk_eth *eth)
|
||||
{
|
||||
+ unsigned int max_clk = 2500000, divider;
|
||||
struct device_node *mii_np;
|
||||
int ret;
|
||||
+ u32 val;
|
||||
|
||||
mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
|
||||
if (!mii_np) {
|
||||
@@ -731,6 +733,25 @@ static int mtk_mdio_init(struct mtk_eth
|
||||
eth->mii_bus->parent = eth->dev;
|
||||
|
||||
snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
|
||||
+
|
||||
+ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) {
|
||||
+ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
|
||||
+ dev_err(eth->dev, "MDIO clock frequency out of range");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_put_node;
|
||||
+ }
|
||||
+ max_clk = val;
|
||||
+ }
|
||||
+ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
|
||||
+
|
||||
+ /* Configure MDC Divider */
|
||||
+ val = mtk_r32(eth, MTK_PPSC);
|
||||
+ val &= ~PPSC_MDC_CFG;
|
||||
+ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
|
||||
+ mtk_w32(eth, val, MTK_PPSC);
|
||||
+
|
||||
+ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
|
||||
+
|
||||
ret = of_mdiobus_register(eth->mii_bus, mii_np);
|
||||
|
||||
err_put_node:
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -363,6 +363,13 @@
|
||||
#define RX_DMA_VTAG_V2 BIT(0)
|
||||
#define RX_DMA_L4_VALID_V2 BIT(2)
|
||||
|
||||
+/* PHY Polling and SMI Master Control registers */
|
||||
+#define MTK_PPSC 0x10000
|
||||
+#define PPSC_MDC_CFG GENMASK(29, 24)
|
||||
+#define PPSC_MDC_TURBO BIT(20)
|
||||
+#define MDC_MAX_FREQ 25000000
|
||||
+#define MDC_MAX_DIVIDER 63
|
||||
+
|
||||
/* PHY Indirect Access Control registers */
|
||||
#define MTK_PHY_IAC 0x10004
|
||||
#define PHY_IAC_ACCESS BIT(31)
|
||||
@ -0,0 +1,512 @@
|
||||
From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 19 Mar 2023 12:58:02 +0000
|
||||
Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver
|
||||
|
||||
Now that we got a PCS driver, use it and remove the now redundant
|
||||
PCS code and it's header macros from the Ethernet driver.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/Kconfig | 2 +
|
||||
drivers/net/ethernet/mediatek/Makefile | 2 +-
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++-
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +--------
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 --------------------
|
||||
5 files changed, 56 insertions(+), 319 deletions(-)
|
||||
delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/Kconfig
|
||||
+++ b/drivers/net/ethernet/mediatek/Kconfig
|
||||
@@ -18,6 +18,8 @@ config NET_MEDIATEK_SOC
|
||||
select DIMLIB
|
||||
select PAGE_POOL
|
||||
select PAGE_POOL_STATS
|
||||
+ select PCS_MTK_LYNXI
|
||||
+ select REGMAP_MMIO
|
||||
help
|
||||
This driver supports the gigabit ethernet MACs in the
|
||||
MediaTek SoC family.
|
||||
--- a/drivers/net/ethernet/mediatek/Makefile
|
||||
+++ b/drivers/net/ethernet/mediatek/Makefile
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
|
||||
-mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
|
||||
+mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
|
||||
mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
|
||||
ifdef CONFIG_DEBUG_FS
|
||||
mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pinctrl/devinfo.h>
|
||||
#include <linux/phylink.h>
|
||||
+#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
#include <linux/jhash.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <net/dsa.h>
|
||||
@@ -357,7 +358,7 @@ static struct phylink_pcs *mtk_mac_selec
|
||||
sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
|
||||
0 : mac->id;
|
||||
|
||||
- return mtk_sgmii_select_pcs(eth->sgmii, sid);
|
||||
+ return eth->sgmii_pcs[sid];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -3979,8 +3980,17 @@ static int mtk_unreg_dev(struct mtk_eth
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void mtk_sgmii_destroy(struct mtk_eth *eth)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MTK_MAX_DEVS; i++)
|
||||
+ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
|
||||
+}
|
||||
+
|
||||
static int mtk_cleanup(struct mtk_eth *eth)
|
||||
{
|
||||
+ mtk_sgmii_destroy(eth);
|
||||
mtk_unreg_dev(eth);
|
||||
mtk_free_dev(eth);
|
||||
cancel_work_sync(ð->pending_work);
|
||||
@@ -4410,6 +4420,36 @@ void mtk_eth_set_dma_device(struct mtk_e
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
+static int mtk_sgmii_init(struct mtk_eth *eth)
|
||||
+{
|
||||
+ struct device_node *np;
|
||||
+ struct regmap *regmap;
|
||||
+ u32 flags;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
+ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
|
||||
+ if (!np)
|
||||
+ break;
|
||||
+
|
||||
+ regmap = syscon_node_to_regmap(np);
|
||||
+ flags = 0;
|
||||
+ if (of_property_read_bool(np, "mediatek,pnswap"))
|
||||
+ flags |= MTK_SGMII_FLAG_PN_SWAP;
|
||||
+
|
||||
+ of_node_put(np);
|
||||
+
|
||||
+ if (IS_ERR(regmap))
|
||||
+ return PTR_ERR(regmap);
|
||||
+
|
||||
+ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap,
|
||||
+ eth->soc->ana_rgc3,
|
||||
+ flags);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int mtk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res = NULL;
|
||||
@@ -4473,13 +4513,7 @@ static int mtk_probe(struct platform_dev
|
||||
}
|
||||
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
|
||||
- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii),
|
||||
- GFP_KERNEL);
|
||||
- if (!eth->sgmii)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
|
||||
- eth->soc->ana_rgc3);
|
||||
+ err = mtk_sgmii_init(eth);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
@@ -4490,14 +4524,17 @@ static int mtk_probe(struct platform_dev
|
||||
"mediatek,pctl");
|
||||
if (IS_ERR(eth->pctl)) {
|
||||
dev_err(&pdev->dev, "no pctl regmap found\n");
|
||||
- return PTR_ERR(eth->pctl);
|
||||
+ err = PTR_ERR(eth->pctl);
|
||||
+ goto err_destroy_sgmii;
|
||||
}
|
||||
}
|
||||
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- if (!res)
|
||||
- return -EINVAL;
|
||||
+ if (!res) {
|
||||
+ err = -EINVAL;
|
||||
+ goto err_destroy_sgmii;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (eth->soc->offload_version) {
|
||||
@@ -4657,6 +4694,8 @@ err_deinit_hw:
|
||||
mtk_hw_deinit(eth);
|
||||
err_wed_exit:
|
||||
mtk_wed_exit();
|
||||
+err_destroy_sgmii:
|
||||
+ mtk_sgmii_destroy(eth);
|
||||
|
||||
return err;
|
||||
}
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -507,65 +507,6 @@
|
||||
#define ETHSYS_DMA_AG_MAP_QDMA BIT(1)
|
||||
#define ETHSYS_DMA_AG_MAP_PPE BIT(2)
|
||||
|
||||
-/* SGMII subsystem config registers */
|
||||
-/* BMCR (low 16) BMSR (high 16) */
|
||||
-#define SGMSYS_PCS_CONTROL_1 0x0
|
||||
-#define SGMII_BMCR GENMASK(15, 0)
|
||||
-#define SGMII_BMSR GENMASK(31, 16)
|
||||
-#define SGMII_AN_RESTART BIT(9)
|
||||
-#define SGMII_ISOLATE BIT(10)
|
||||
-#define SGMII_AN_ENABLE BIT(12)
|
||||
-#define SGMII_LINK_STATYS BIT(18)
|
||||
-#define SGMII_AN_ABILITY BIT(19)
|
||||
-#define SGMII_AN_COMPLETE BIT(21)
|
||||
-#define SGMII_PCS_FAULT BIT(23)
|
||||
-#define SGMII_AN_EXPANSION_CLR BIT(30)
|
||||
-
|
||||
-#define SGMSYS_PCS_ADVERTISE 0x8
|
||||
-#define SGMII_ADVERTISE GENMASK(15, 0)
|
||||
-#define SGMII_LPA GENMASK(31, 16)
|
||||
-
|
||||
-/* Register to programmable link timer, the unit in 2 * 8ns */
|
||||
-#define SGMSYS_PCS_LINK_TIMER 0x18
|
||||
-#define SGMII_LINK_TIMER_MASK GENMASK(19, 0)
|
||||
-#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK)
|
||||
-
|
||||
-/* Register to control remote fault */
|
||||
-#define SGMSYS_SGMII_MODE 0x20
|
||||
-#define SGMII_IF_MODE_SGMII BIT(0)
|
||||
-#define SGMII_SPEED_DUPLEX_AN BIT(1)
|
||||
-#define SGMII_SPEED_MASK GENMASK(3, 2)
|
||||
-#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0)
|
||||
-#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1)
|
||||
-#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2)
|
||||
-#define SGMII_DUPLEX_HALF BIT(4)
|
||||
-#define SGMII_IF_MODE_BIT5 BIT(5)
|
||||
-#define SGMII_REMOTE_FAULT_DIS BIT(8)
|
||||
-#define SGMII_CODE_SYNC_SET_VAL BIT(9)
|
||||
-#define SGMII_CODE_SYNC_SET_EN BIT(10)
|
||||
-#define SGMII_SEND_AN_ERROR_EN BIT(11)
|
||||
-#define SGMII_IF_MODE_MASK GENMASK(5, 1)
|
||||
-
|
||||
-/* Register to reset SGMII design */
|
||||
-#define SGMII_RESERVED_0 0x34
|
||||
-#define SGMII_SW_RESET BIT(0)
|
||||
-
|
||||
-/* Register to set SGMII speed, ANA RG_ Control Signals III*/
|
||||
-#define SGMSYS_ANA_RG_CS3 0x2028
|
||||
-#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
|
||||
-#define RG_PHY_SPEED_1_25G 0x0
|
||||
-#define RG_PHY_SPEED_3_125G BIT(2)
|
||||
-
|
||||
-/* Register to power up QPHY */
|
||||
-#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
|
||||
-#define SGMII_PHYA_PWD BIT(4)
|
||||
-
|
||||
-/* Register to QPHY wrapper control */
|
||||
-#define SGMSYS_QPHY_WRAP_CTRL 0xec
|
||||
-#define SGMII_PN_SWAP_MASK GENMASK(1, 0)
|
||||
-#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1))
|
||||
-#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
|
||||
-
|
||||
/* Infrasys subsystem config registers */
|
||||
#define INFRA_MISC2 0x70c
|
||||
#define CO_QPHY_SEL BIT(0)
|
||||
@@ -1105,31 +1046,6 @@ struct mtk_soc_data {
|
||||
/* currently no SoC has more than 2 macs */
|
||||
#define MTK_MAX_DEVS 2
|
||||
|
||||
-/* struct mtk_pcs - This structure holds each sgmii regmap and associated
|
||||
- * data
|
||||
- * @regmap: The register map pointing at the range used to setup
|
||||
- * SGMII modes
|
||||
- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap
|
||||
- * @interface: Currently configured interface mode
|
||||
- * @pcs: Phylink PCS structure
|
||||
- * @flags: Flags indicating hardware properties
|
||||
- */
|
||||
-struct mtk_pcs {
|
||||
- struct regmap *regmap;
|
||||
- u32 ana_rgc3;
|
||||
- phy_interface_t interface;
|
||||
- struct phylink_pcs pcs;
|
||||
- u32 flags;
|
||||
-};
|
||||
-
|
||||
-/* struct mtk_sgmii - This is the structure holding sgmii regmap and its
|
||||
- * characteristics
|
||||
- * @pcs Array of individual PCS structures
|
||||
- */
|
||||
-struct mtk_sgmii {
|
||||
- struct mtk_pcs pcs[MTK_MAX_DEVS];
|
||||
-};
|
||||
-
|
||||
/* struct mtk_eth - This is the main datasructure for holding the state
|
||||
* of the driver
|
||||
* @dev: The device pointer
|
||||
@@ -1149,6 +1065,7 @@ struct mtk_sgmii {
|
||||
* MII modes
|
||||
* @infra: The register map pointing at the range used to setup
|
||||
* SGMII and GePHY path
|
||||
+ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances
|
||||
* @pctl: The register map pointing at the range used to setup
|
||||
* GMAC port drive/slew values
|
||||
* @dma_refcnt: track how many netdevs are using the DMA engine
|
||||
@@ -1189,8 +1106,8 @@ struct mtk_eth {
|
||||
u32 msg_enable;
|
||||
unsigned long sysclk;
|
||||
struct regmap *ethsys;
|
||||
- struct regmap *infra;
|
||||
- struct mtk_sgmii *sgmii;
|
||||
+ struct regmap *infra;
|
||||
+ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
|
||||
struct regmap *pctl;
|
||||
bool hwlro;
|
||||
refcount_t dma_refcnt;
|
||||
@@ -1352,10 +1269,6 @@ void mtk_stats_update_mac(struct mtk_mac
|
||||
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
|
||||
u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
|
||||
|
||||
-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
|
||||
-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
|
||||
- u32 ana_rgc3);
|
||||
-
|
||||
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ /dev/null
|
||||
@@ -1,217 +0,0 @@
|
||||
-// SPDX-License-Identifier: GPL-2.0
|
||||
-// Copyright (c) 2018-2019 MediaTek Inc.
|
||||
-
|
||||
-/* A library for MediaTek SGMII circuit
|
||||
- *
|
||||
- * Author: Sean Wang <sean.wang@mediatek.com>
|
||||
- *
|
||||
- */
|
||||
-
|
||||
-#include <linux/mfd/syscon.h>
|
||||
-#include <linux/of.h>
|
||||
-#include <linux/phylink.h>
|
||||
-#include <linux/regmap.h>
|
||||
-
|
||||
-#include "mtk_eth_soc.h"
|
||||
-
|
||||
-static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
|
||||
-{
|
||||
- return container_of(pcs, struct mtk_pcs, pcs);
|
||||
-}
|
||||
-
|
||||
-static void mtk_pcs_get_state(struct phylink_pcs *pcs,
|
||||
- struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
- unsigned int bm, adv;
|
||||
-
|
||||
- /* Read the BMSR and LPA */
|
||||
- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
|
||||
- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
|
||||
-
|
||||
- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
|
||||
- FIELD_GET(SGMII_LPA, adv));
|
||||
-}
|
||||
-
|
||||
-static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
- phy_interface_t interface,
|
||||
- const unsigned long *advertising,
|
||||
- bool permit_pause_to_mac)
|
||||
-{
|
||||
- bool mode_changed = false, changed, use_an;
|
||||
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
- unsigned int rgc3, sgm_mode, bmcr;
|
||||
- int advertise, link_timer;
|
||||
-
|
||||
- advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
|
||||
- advertising);
|
||||
- if (advertise < 0)
|
||||
- return advertise;
|
||||
-
|
||||
- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
|
||||
- * we assume that fixes it's speed at bitrate = line rate (in
|
||||
- * other words, 1000Mbps or 2500Mbps).
|
||||
- */
|
||||
- if (interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
- sgm_mode = SGMII_IF_MODE_SGMII;
|
||||
- if (phylink_autoneg_inband(mode)) {
|
||||
- sgm_mode |= SGMII_REMOTE_FAULT_DIS |
|
||||
- SGMII_SPEED_DUPLEX_AN;
|
||||
- use_an = true;
|
||||
- } else {
|
||||
- use_an = false;
|
||||
- }
|
||||
- } else if (phylink_autoneg_inband(mode)) {
|
||||
- /* 1000base-X or 2500base-X autoneg */
|
||||
- sgm_mode = SGMII_REMOTE_FAULT_DIS;
|
||||
- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
|
||||
- advertising);
|
||||
- } else {
|
||||
- /* 1000base-X or 2500base-X without autoneg */
|
||||
- sgm_mode = 0;
|
||||
- use_an = false;
|
||||
- }
|
||||
-
|
||||
- if (use_an) {
|
||||
- bmcr = SGMII_AN_ENABLE;
|
||||
- } else {
|
||||
- bmcr = 0;
|
||||
- }
|
||||
-
|
||||
- if (mpcs->interface != interface) {
|
||||
- link_timer = phylink_get_link_timer_ns(interface);
|
||||
- if (link_timer < 0)
|
||||
- return link_timer;
|
||||
-
|
||||
- /* PHYA power down */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
|
||||
- SGMII_PHYA_PWD, SGMII_PHYA_PWD);
|
||||
-
|
||||
- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
|
||||
- SGMII_PN_SWAP_MASK,
|
||||
- SGMII_PN_SWAP_TX_RX);
|
||||
-
|
||||
- /* Reset SGMII PCS state */
|
||||
- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
|
||||
- SGMII_SW_RESET, SGMII_SW_RESET);
|
||||
-
|
||||
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
- rgc3 = RG_PHY_SPEED_3_125G;
|
||||
- else
|
||||
- rgc3 = 0;
|
||||
-
|
||||
- /* Configure the underlying interface speed */
|
||||
- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
|
||||
- RG_PHY_SPEED_3_125G, rgc3);
|
||||
-
|
||||
- /* Setup the link timer */
|
||||
- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
|
||||
-
|
||||
- mpcs->interface = interface;
|
||||
- mode_changed = true;
|
||||
- }
|
||||
-
|
||||
- /* Update the advertisement, noting whether it has changed */
|
||||
- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
|
||||
- SGMII_ADVERTISE, advertise, &changed);
|
||||
-
|
||||
- /* Update the sgmsys mode register */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
|
||||
- SGMII_IF_MODE_SGMII, sgm_mode);
|
||||
-
|
||||
- /* Update the BMCR */
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
- SGMII_AN_ENABLE, bmcr);
|
||||
-
|
||||
- /* Release PHYA power down state
|
||||
- * Only removing bit SGMII_PHYA_PWD isn't enough.
|
||||
- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
|
||||
- * prevents SGMII from working. The SGMII still shows link but no traffic
|
||||
- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
|
||||
- * taken from a good working state of the SGMII interface.
|
||||
- * Unknown how much the QPHY needs but it is racy without a sleep.
|
||||
- * Tested on mt7622 & mt7986.
|
||||
- */
|
||||
- usleep_range(50, 100);
|
||||
- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
|
||||
-
|
||||
- return changed || mode_changed;
|
||||
-}
|
||||
-
|
||||
-static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
|
||||
-{
|
||||
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
-
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
|
||||
- SGMII_AN_RESTART, SGMII_AN_RESTART);
|
||||
-}
|
||||
-
|
||||
-static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
|
||||
- phy_interface_t interface, int speed, int duplex)
|
||||
-{
|
||||
- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
- unsigned int sgm_mode;
|
||||
-
|
||||
- if (!phylink_autoneg_inband(mode)) {
|
||||
- /* Force the speed and duplex setting */
|
||||
- if (speed == SPEED_10)
|
||||
- sgm_mode = SGMII_SPEED_10;
|
||||
- else if (speed == SPEED_100)
|
||||
- sgm_mode = SGMII_SPEED_100;
|
||||
- else
|
||||
- sgm_mode = SGMII_SPEED_1000;
|
||||
-
|
||||
- if (duplex != DUPLEX_FULL)
|
||||
- sgm_mode |= SGMII_DUPLEX_HALF;
|
||||
-
|
||||
- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
|
||||
- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
|
||||
- sgm_mode);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static const struct phylink_pcs_ops mtk_pcs_ops = {
|
||||
- .pcs_get_state = mtk_pcs_get_state,
|
||||
- .pcs_config = mtk_pcs_config,
|
||||
- .pcs_an_restart = mtk_pcs_restart_an,
|
||||
- .pcs_link_up = mtk_pcs_link_up,
|
||||
-};
|
||||
-
|
||||
-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
|
||||
-{
|
||||
- struct device_node *np;
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
- np = of_parse_phandle(r, "mediatek,sgmiisys", i);
|
||||
- if (!np)
|
||||
- break;
|
||||
-
|
||||
- ss->pcs[i].ana_rgc3 = ana_rgc3;
|
||||
- ss->pcs[i].regmap = syscon_node_to_regmap(np);
|
||||
-
|
||||
- ss->pcs[i].flags = 0;
|
||||
- if (of_property_read_bool(np, "mediatek,pnswap"))
|
||||
- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
|
||||
-
|
||||
- of_node_put(np);
|
||||
- if (IS_ERR(ss->pcs[i].regmap))
|
||||
- return PTR_ERR(ss->pcs[i].regmap);
|
||||
-
|
||||
- ss->pcs[i].pcs.ops = &mtk_pcs_ops;
|
||||
- ss->pcs[i].pcs.poll = true;
|
||||
- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
|
||||
-{
|
||||
- if (!ss->pcs[id].regmap)
|
||||
- return NULL;
|
||||
-
|
||||
- return &ss->pcs[id].pcs;
|
||||
-}
|
||||
@ -0,0 +1,514 @@
|
||||
From patchwork Thu Mar 9 10:57:44 2023
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 8bit
|
||||
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
|
||||
X-Patchwork-Id: 13167235
|
||||
X-Patchwork-Delegate: kuba@kernel.org
|
||||
Return-Path: <netdev-owner@vger.kernel.org>
|
||||
Date: Thu, 9 Mar 2023 10:57:44 +0000
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org,
|
||||
linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Heiner Kallweit <hkallweit1@gmail.com>,
|
||||
Lorenzo Bianconi <lorenzo@kernel.org>,
|
||||
Mark Lee <Mark-MC.Lee@mediatek.com>,
|
||||
John Crispin <john@phrozen.org>, Felix Fietkau <nbd@nbd.name>,
|
||||
AngeloGioacchino Del Regno
|
||||
<angelogioacchino.delregno@collabora.com>,
|
||||
Matthias Brugger <matthias.bgg@gmail.com>,
|
||||
DENG Qingfang <dqfext@gmail.com>,
|
||||
Landen Chao <Landen.Chao@mediatek.com>,
|
||||
Sean Wang <sean.wang@mediatek.com>,
|
||||
Paolo Abeni <pabeni@redhat.com>,
|
||||
Jakub Kicinski <kuba@kernel.org>,
|
||||
Eric Dumazet <edumazet@google.com>,
|
||||
"David S. Miller" <davem@davemloft.net>,
|
||||
Vladimir Oltean <olteanv@gmail.com>,
|
||||
Florian Fainelli <f.fainelli@gmail.com>,
|
||||
Andrew Lunn <andrew@lunn.ch>,
|
||||
Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
Cc: =?iso-8859-1?q?Bj=F8rn?= Mork <bjorn@mork.no>,
|
||||
Frank Wunderlich <frank-w@public-files.de>,
|
||||
Alexander Couzens <lynxis@fe80.eu>
|
||||
Subject: [PATCH net-next v13 11/16] net: dsa: mt7530: use external PCS driver
|
||||
Message-ID:
|
||||
<2ac2ee40d3b0e705461b50613fda6a7edfdbc4b3.1678357225.git.daniel@makrotopia.org>
|
||||
References: <cover.1678357225.git.daniel@makrotopia.org>
|
||||
MIME-Version: 1.0
|
||||
Content-Disposition: inline
|
||||
In-Reply-To: <cover.1678357225.git.daniel@makrotopia.org>
|
||||
Precedence: bulk
|
||||
List-ID: <netdev.vger.kernel.org>
|
||||
X-Mailing-List: netdev@vger.kernel.org
|
||||
X-Patchwork-Delegate: kuba@kernel.org
|
||||
|
||||
Implement regmap access wrappers, for now only to be used by the
|
||||
pcs-mtk driver.
|
||||
Make use of external PCS driver and drop the reduntant implementation
|
||||
in mt7530.c.
|
||||
As a nice side effect the SGMII registers can now also more easily be
|
||||
inspected for debugging via /sys/kernel/debug/regmap.
|
||||
|
||||
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Tested-by: Bjørn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Tested-by: Frank Wunderlich <frank-w@public-files.de>
|
||||
---
|
||||
drivers/net/dsa/Kconfig | 1 +
|
||||
drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
|
||||
drivers/net/dsa/mt7530.h | 47 +------
|
||||
3 files changed, 71 insertions(+), 254 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -37,6 +37,7 @@ config NET_DSA_MT7530
|
||||
tristate "MediaTek MT753x and MT7621 Ethernet switch support"
|
||||
select NET_DSA_TAG_MTK
|
||||
select MEDIATEK_GE_PHY
|
||||
+ select PCS_MTK_LYNXI
|
||||
help
|
||||
This enables support for the MediaTek MT7530, MT7531, and MT7621
|
||||
Ethernet switch chips.
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_platform.h>
|
||||
+#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@@ -2568,128 +2569,11 @@ static int mt7531_rgmii_setup(struct mt7
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
|
||||
- phy_interface_t interface, int speed, int duplex)
|
||||
-{
|
||||
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
- int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
- unsigned int val;
|
||||
-
|
||||
- /* For adjusting speed and duplex of SGMII force mode. */
|
||||
- if (interface != PHY_INTERFACE_MODE_SGMII ||
|
||||
- phylink_autoneg_inband(mode))
|
||||
- return;
|
||||
-
|
||||
- /* SGMII force mode setting */
|
||||
- val = mt7530_read(priv, MT7531_SGMII_MODE(port));
|
||||
- val &= ~MT7531_SGMII_IF_MODE_MASK;
|
||||
-
|
||||
- switch (speed) {
|
||||
- case SPEED_10:
|
||||
- val |= MT7531_SGMII_FORCE_SPEED_10;
|
||||
- break;
|
||||
- case SPEED_100:
|
||||
- val |= MT7531_SGMII_FORCE_SPEED_100;
|
||||
- break;
|
||||
- case SPEED_1000:
|
||||
- val |= MT7531_SGMII_FORCE_SPEED_1000;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* MT7531 SGMII 1G force mode can only work in full duplex mode,
|
||||
- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
|
||||
- *
|
||||
- * The speed check is unnecessary as the MAC capabilities apply
|
||||
- * this restriction. --rmk
|
||||
- */
|
||||
- if ((speed == SPEED_10 || speed == SPEED_100) &&
|
||||
- duplex != DUPLEX_FULL)
|
||||
- val |= MT7531_SGMII_FORCE_HALF_DUPLEX;
|
||||
-
|
||||
- mt7530_write(priv, MT7531_SGMII_MODE(port), val);
|
||||
-}
|
||||
-
|
||||
static bool mt753x_is_mac_port(u32 port)
|
||||
{
|
||||
return (port == 5 || port == 6);
|
||||
}
|
||||
|
||||
-static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
|
||||
- phy_interface_t interface)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- if (!mt753x_is_mac_port(port))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
|
||||
- MT7531_SGMII_PHYA_PWD);
|
||||
-
|
||||
- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
|
||||
- val &= ~MT7531_RG_TPHY_SPEED_MASK;
|
||||
- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B
|
||||
- * encoding.
|
||||
- */
|
||||
- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ?
|
||||
- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G;
|
||||
- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
|
||||
-
|
||||
- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
|
||||
-
|
||||
- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex
|
||||
- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
|
||||
- */
|
||||
- mt7530_rmw(priv, MT7531_SGMII_MODE(port),
|
||||
- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS,
|
||||
- MT7531_SGMII_FORCE_SPEED_1000);
|
||||
-
|
||||
- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
|
||||
- phy_interface_t interface)
|
||||
-{
|
||||
- if (!mt753x_is_mac_port(port))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
|
||||
- MT7531_SGMII_PHYA_PWD);
|
||||
-
|
||||
- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
|
||||
- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G);
|
||||
-
|
||||
- mt7530_set(priv, MT7531_SGMII_MODE(port),
|
||||
- MT7531_SGMII_REMOTE_FAULT_DIS |
|
||||
- MT7531_SGMII_SPEED_DUPLEX_AN);
|
||||
-
|
||||
- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port),
|
||||
- MT7531_SGMII_TX_CONFIG_MASK, 1);
|
||||
-
|
||||
- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE);
|
||||
-
|
||||
- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART);
|
||||
-
|
||||
- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
|
||||
-{
|
||||
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
- int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
- u32 val;
|
||||
-
|
||||
- /* Only restart AN when AN is enabled */
|
||||
- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
|
||||
- if (val & MT7531_SGMII_AN_ENABLE) {
|
||||
- val |= MT7531_SGMII_AN_RESTART;
|
||||
- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static int
|
||||
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
@@ -2712,11 +2596,11 @@ mt7531_mac_config(struct dsa_switch *ds,
|
||||
phydev = dp->slave->phydev;
|
||||
return mt7531_rgmii_setup(priv, port, interface, phydev);
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
- return mt7531_sgmii_setup_mode_an(priv, port, interface);
|
||||
case PHY_INTERFACE_MODE_NA:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- return mt7531_sgmii_setup_mode_force(priv, port, interface);
|
||||
+ /* handled in SGMII PCS driver */
|
||||
+ return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2741,11 +2625,11 @@ mt753x_phylink_mac_select_pcs(struct dsa
|
||||
|
||||
switch (interface) {
|
||||
case PHY_INTERFACE_MODE_TRGMII:
|
||||
+ return &priv->pcs[port].pcs;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
- return &priv->pcs[port].pcs;
|
||||
-
|
||||
+ return priv->ports[port].sgmii_pcs;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -2986,86 +2870,6 @@ static void mt7530_pcs_get_state(struct
|
||||
state->pause |= MLO_PAUSE_TX;
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
|
||||
- struct phylink_link_state *state)
|
||||
-{
|
||||
- u32 status, val;
|
||||
- u16 config_reg;
|
||||
-
|
||||
- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
|
||||
- state->link = !!(status & MT7531_SGMII_LINK_STATUS);
|
||||
- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
|
||||
- if (state->interface == PHY_INTERFACE_MODE_SGMII &&
|
||||
- (status & MT7531_SGMII_AN_ENABLE)) {
|
||||
- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
|
||||
- config_reg = val >> 16;
|
||||
-
|
||||
- switch (config_reg & LPA_SGMII_SPD_MASK) {
|
||||
- case LPA_SGMII_1000:
|
||||
- state->speed = SPEED_1000;
|
||||
- break;
|
||||
- case LPA_SGMII_100:
|
||||
- state->speed = SPEED_100;
|
||||
- break;
|
||||
- case LPA_SGMII_10:
|
||||
- state->speed = SPEED_10;
|
||||
- break;
|
||||
- default:
|
||||
- dev_err(priv->dev, "invalid sgmii PHY speed\n");
|
||||
- state->link = false;
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (config_reg & LPA_SGMII_FULL_DUPLEX)
|
||||
- state->duplex = DUPLEX_FULL;
|
||||
- else
|
||||
- state->duplex = DUPLEX_HALF;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
|
||||
- struct phylink_link_state *state)
|
||||
-{
|
||||
- unsigned int val;
|
||||
-
|
||||
- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
|
||||
- state->link = !!(val & MT7531_SGMII_LINK_STATUS);
|
||||
- if (!state->link)
|
||||
- return;
|
||||
-
|
||||
- state->an_complete = state->link;
|
||||
-
|
||||
- if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
- state->speed = SPEED_2500;
|
||||
- else
|
||||
- state->speed = SPEED_1000;
|
||||
-
|
||||
- state->duplex = DUPLEX_FULL;
|
||||
- state->pause = MLO_PAUSE_NONE;
|
||||
-}
|
||||
-
|
||||
-static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
|
||||
- struct phylink_link_state *state)
|
||||
-{
|
||||
- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
|
||||
- int port = pcs_to_mt753x_pcs(pcs)->port;
|
||||
-
|
||||
- if (state->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
- mt7531_sgmii_pcs_get_state_an(priv, port, state);
|
||||
- return;
|
||||
- } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
|
||||
- (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
|
||||
- mt7531_sgmii_pcs_get_state_inband(priv, port, state);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- state->link = false;
|
||||
-}
|
||||
-
|
||||
static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
const unsigned long *advertising,
|
||||
@@ -3085,18 +2889,57 @@ static const struct phylink_pcs_ops mt75
|
||||
.pcs_an_restart = mt7530_pcs_an_restart,
|
||||
};
|
||||
|
||||
-static const struct phylink_pcs_ops mt7531_pcs_ops = {
|
||||
- .pcs_validate = mt753x_pcs_validate,
|
||||
- .pcs_get_state = mt7531_pcs_get_state,
|
||||
- .pcs_config = mt753x_pcs_config,
|
||||
- .pcs_an_restart = mt7531_pcs_an_restart,
|
||||
- .pcs_link_up = mt7531_pcs_link_up,
|
||||
+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+
|
||||
+ *val = mt7530_read(priv, reg);
|
||||
+ return 0;
|
||||
+};
|
||||
+
|
||||
+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+
|
||||
+ mt7530_write(priv, reg, val);
|
||||
+ return 0;
|
||||
+};
|
||||
+
|
||||
+static int mt7530_regmap_update_bits(void *context, unsigned int reg,
|
||||
+ unsigned int mask, unsigned int val)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = context;
|
||||
+
|
||||
+ mt7530_rmw(priv, reg, mask, val);
|
||||
+ return 0;
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_bus mt7531_regmap_bus = {
|
||||
+ .reg_write = mt7530_regmap_write,
|
||||
+ .reg_read = mt7530_regmap_read,
|
||||
+ .reg_update_bits = mt7530_regmap_update_bits,
|
||||
+};
|
||||
+
|
||||
+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
|
||||
+ { \
|
||||
+ .name = _name, \
|
||||
+ .reg_bits = 16, \
|
||||
+ .val_bits = 32, \
|
||||
+ .reg_stride = 4, \
|
||||
+ .reg_base = _reg_base, \
|
||||
+ .max_register = 0x17c, \
|
||||
+ }
|
||||
+
|
||||
+static const struct regmap_config mt7531_pcs_config[] = {
|
||||
+ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
|
||||
+ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
|
||||
};
|
||||
|
||||
static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
+ struct regmap *regmap;
|
||||
int i, ret;
|
||||
|
||||
/* Initialise the PCS devices */
|
||||
@@ -3104,8 +2947,6 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
priv->pcs[i].pcs.ops = priv->info->pcs_ops;
|
||||
priv->pcs[i].priv = priv;
|
||||
priv->pcs[i].port = i;
|
||||
- if (mt753x_is_mac_port(i))
|
||||
- priv->pcs[i].pcs.poll = 1;
|
||||
}
|
||||
|
||||
ret = priv->info->sw_setup(ds);
|
||||
@@ -3120,6 +2961,16 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
+ if (priv->id == ID_MT7531)
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ regmap = devm_regmap_init(ds->dev,
|
||||
+ &mt7531_regmap_bus, priv,
|
||||
+ &mt7531_pcs_config[i]);
|
||||
+ priv->ports[5 + i].sgmii_pcs =
|
||||
+ mtk_pcs_lynxi_create(ds->dev, regmap,
|
||||
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3211,7 +3062,7 @@ static const struct mt753x_info mt753x_t
|
||||
},
|
||||
[ID_MT7531] = {
|
||||
.id = ID_MT7531,
|
||||
- .pcs_ops = &mt7531_pcs_ops,
|
||||
+ .pcs_ops = &mt7530_pcs_ops,
|
||||
.sw_setup = mt7531_setup,
|
||||
.phy_read = mt7531_ind_phy_read,
|
||||
.phy_write = mt7531_ind_phy_write,
|
||||
@@ -3319,7 +3170,7 @@ static void
|
||||
mt7530_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
- int ret = 0;
|
||||
+ int ret = 0, i;
|
||||
|
||||
if (!priv)
|
||||
return;
|
||||
@@ -3338,6 +3189,10 @@ mt7530_remove(struct mdio_device *mdiode
|
||||
mt7530_free_irq(priv);
|
||||
|
||||
dsa_unregister_switch(priv->ds);
|
||||
+
|
||||
+ for (i = 0; i < 2; ++i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
+
|
||||
mutex_destroy(&priv->reg_mutex);
|
||||
|
||||
dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -364,47 +364,8 @@ enum mt7530_vlan_port_acc_frm {
|
||||
CCR_TX_OCT_CNT_BAD)
|
||||
|
||||
/* MT7531 SGMII register group */
|
||||
-#define MT7531_SGMII_REG_BASE 0x5000
|
||||
-#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
|
||||
- ((p) - 5) * 0x1000 + (r))
|
||||
-
|
||||
-/* Register forSGMII PCS_CONTROL_1 */
|
||||
-#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00)
|
||||
-#define MT7531_SGMII_LINK_STATUS BIT(18)
|
||||
-#define MT7531_SGMII_AN_ENABLE BIT(12)
|
||||
-#define MT7531_SGMII_AN_RESTART BIT(9)
|
||||
-#define MT7531_SGMII_AN_COMPLETE BIT(21)
|
||||
-
|
||||
-/* Register for SGMII PCS_SPPED_ABILITY */
|
||||
-#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
|
||||
-#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0)
|
||||
-#define MT7531_SGMII_TX_CONFIG BIT(0)
|
||||
-
|
||||
-/* Register for SGMII_MODE */
|
||||
-#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20)
|
||||
-#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8)
|
||||
-#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1)
|
||||
-#define MT7531_SGMII_FORCE_DUPLEX BIT(4)
|
||||
-#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2)
|
||||
-#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3)
|
||||
-#define MT7531_SGMII_FORCE_SPEED_100 BIT(2)
|
||||
-#define MT7531_SGMII_FORCE_SPEED_10 0
|
||||
-#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1)
|
||||
-
|
||||
-enum mt7531_sgmii_force_duplex {
|
||||
- MT7531_SGMII_FORCE_FULL_DUPLEX = 0,
|
||||
- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10,
|
||||
-};
|
||||
-
|
||||
-/* Fields of QPHY_PWR_STATE_CTRL */
|
||||
-#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
|
||||
-#define MT7531_SGMII_PHYA_PWD BIT(4)
|
||||
-
|
||||
-/* Values of SGMII SPEED */
|
||||
-#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128)
|
||||
-#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3))
|
||||
-#define MT7531_RG_TPHY_SPEED_1_25G 0x0
|
||||
-#define MT7531_RG_TPHY_SPEED_3_125G BIT(2)
|
||||
+#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000)
|
||||
+#define MT7531_PHYA_CTRL_SIGNAL3 0x128
|
||||
|
||||
/* Register for system reset */
|
||||
#define MT7530_SYS_CTRL 0x7000
|
||||
@@ -703,13 +664,13 @@ struct mt7530_fdb {
|
||||
* @pm: The matrix used to show all connections with the port.
|
||||
* @pvid: The VLAN specified is to be considered a PVID at ingress. Any
|
||||
* untagged frames will be assigned to the related VLAN.
|
||||
- * @vlan_filtering: The flags indicating whether the port that can recognize
|
||||
- * VLAN-tagged frames.
|
||||
+ * @sgmii_pcs: Pointer to PCS instance for SerDes ports
|
||||
*/
|
||||
struct mt7530_port {
|
||||
bool enable;
|
||||
u32 pm;
|
||||
u16 pvid;
|
||||
+ struct phylink_pcs *sgmii_pcs;
|
||||
};
|
||||
|
||||
/* Port 5 interface select definitions */
|
||||
@ -19,7 +19,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17954,6 +17954,11 @@ L: netdev@vger.kernel.org
|
||||
@@ -17962,6 +17962,11 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/dlink/sundance.c
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -12354,6 +12354,14 @@ S: Supported
|
||||
@@ -12362,6 +12362,14 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/mtd/atmel-nand.txt
|
||||
F: drivers/mtd/nand/raw/atmel/*
|
||||
|
||||
|
||||
@ -125,7 +125,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/property.h>
|
||||
@@ -3341,3 +3342,5 @@ static int __init regmap_initcall(void)
|
||||
@@ -3358,3 +3359,5 @@ static int __init regmap_initcall(void)
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(regmap_initcall);
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
|
||||
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
|
||||
@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(stru
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
|
||||
- unsigned int bm, adv;
|
||||
+ unsigned int bm, bmsr, adv;
|
||||
|
||||
/* Read the BMSR and LPA */
|
||||
regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
|
||||
- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
|
||||
+ bmsr = FIELD_GET(SGMII_BMSR, bm);
|
||||
+
|
||||
+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
|
||||
+ state->link = !!(bmsr & BMSR_LSTATUS);
|
||||
+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
|
||||
+ state->speed = SPEED_2500;
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
|
||||
- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
|
||||
- FIELD_GET(SGMII_LPA, adv));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
|
||||
+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
|
||||
}
|
||||
|
||||
static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
|
||||
@@ -134,7 +143,8 @@ static int mtk_pcs_lynxi_config(struct p
|
||||
/* 1000base-X or 2500base-X autoneg */
|
||||
sgm_mode = SGMII_REMOTE_FAULT_DIS;
|
||||
use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
|
||||
- advertising);
|
||||
+ advertising) &&
|
||||
+ !(interface == PHY_INTERFACE_MODE_2500BASEX);
|
||||
} else {
|
||||
/* 1000base-X or 2500base-X without autoneg */
|
||||
sgm_mode = 0;
|
||||
@ -0,0 +1,150 @@
|
||||
--- a/include/linux/phylink.h
|
||||
+++ b/include/linux/phylink.h
|
||||
@@ -584,10 +584,37 @@ int phylink_speed_up(struct phylink *pl)
|
||||
#define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
|
||||
|
||||
void phylink_set_port_modes(unsigned long *bits);
|
||||
+
|
||||
+/**
|
||||
+ * phylink_get_link_timer_ns - return the PCS link timer value
|
||||
+ * @interface: link &typedef phy_interface_t mode
|
||||
+ *
|
||||
+ * Return the PCS link timer setting in nanoseconds for the PHY @interface
|
||||
+ * mode, or -EINVAL if not appropriate.
|
||||
+ */
|
||||
+static inline int phylink_get_link_timer_ns(phy_interface_t interface)
|
||||
+{
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ return 1600000;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ return 10000000;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void phylink_helper_basex_speed(struct phylink_link_state *state);
|
||||
|
||||
+void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
|
||||
+ u16 bmsr, u16 lpa);
|
||||
void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
|
||||
struct phylink_link_state *state);
|
||||
+int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
|
||||
+ const unsigned long *advertising);
|
||||
int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
|
||||
phy_interface_t interface,
|
||||
const unsigned long *advertising);
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -885,7 +885,6 @@ static int phylink_change_inband_advert(
|
||||
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
static void phylink_mac_pcs_get_state(struct phylink *pl,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
@@ -2966,6 +2965,52 @@ void phylink_mii_c22_pcs_get_state(struc
|
||||
EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
|
||||
|
||||
/**
|
||||
+ * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
|
||||
+ * @state: a pointer to a &struct phylink_link_state.
|
||||
+ * @bmsr: The value of the %MII_BMSR register
|
||||
+ * @lpa: The value of the %MII_LPA register
|
||||
+ *
|
||||
+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
|
||||
+ * clause 37 negotiation and/or SGMII control.
|
||||
+ *
|
||||
+ * Parse the Clause 37 or Cisco SGMII link partner negotiation word into
|
||||
+ * the phylink @state structure. This is suitable to be used for implementing
|
||||
+ * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if
|
||||
+ * accessing @bmsr and @lpa cannot be done with MDIO directly.
|
||||
+ */
|
||||
+void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
|
||||
+ u16 bmsr, u16 lpa)
|
||||
+{
|
||||
+ state->link = !!(bmsr & BMSR_LSTATUS);
|
||||
+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
|
||||
+ /* If there is no link or autonegotiation is disabled, the LP advertisement
|
||||
+ * data is not meaningful, so don't go any further.
|
||||
+ */
|
||||
+ if (!state->link || !state->an_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ switch (state->interface) {
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ phylink_decode_c37_word(state, lpa, SPEED_1000);
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ phylink_decode_c37_word(state, lpa, SPEED_2500);
|
||||
+ break;
|
||||
+
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_QSGMII:
|
||||
+ phylink_decode_sgmii_word(state, lpa);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ state->link = false;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state);
|
||||
+
|
||||
+/**
|
||||
* phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
|
||||
* advertisement
|
||||
* @pcs: a pointer to a &struct mdio_device.
|
||||
@@ -3037,6 +3082,46 @@ int phylink_mii_c22_pcs_set_advertisemen
|
||||
EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
|
||||
|
||||
/**
|
||||
+ * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
|
||||
+ * advertisement
|
||||
+ * @interface: the PHY interface mode being configured
|
||||
+ * @advertising: the ethtool advertisement mask
|
||||
+ *
|
||||
+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for
|
||||
+ * clause 37 negotiation and/or SGMII control.
|
||||
+ *
|
||||
+ * Encode the clause 37 PCS advertisement as specified by @interface and
|
||||
+ * @advertising.
|
||||
+ *
|
||||
+ * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
|
||||
+ */
|
||||
+int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
|
||||
+ const unsigned long *advertising)
|
||||
+{
|
||||
+ u16 adv;
|
||||
+
|
||||
+ switch (interface) {
|
||||
+ case PHY_INTERFACE_MODE_1000BASEX:
|
||||
+ case PHY_INTERFACE_MODE_2500BASEX:
|
||||
+ adv = ADVERTISE_1000XFULL;
|
||||
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
|
||||
+ advertising))
|
||||
+ adv |= ADVERTISE_1000XPAUSE;
|
||||
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
|
||||
+ advertising))
|
||||
+ adv |= ADVERTISE_1000XPSE_ASYM;
|
||||
+ return adv;
|
||||
+ case PHY_INTERFACE_MODE_SGMII:
|
||||
+ case PHY_INTERFACE_MODE_QSGMII:
|
||||
+ return 0x0001;
|
||||
+ default:
|
||||
+ /* Nothing to do for other modes */
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement);
|
||||
+
|
||||
+/**
|
||||
* phylink_mii_c22_pcs_config() - configure clause 22 PCS
|
||||
* @pcs: a pointer to a &struct mdio_device.
|
||||
* @mode: link autonegotiation mode
|
||||
@ -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
|
||||
@@ -2972,8 +2972,8 @@ static irqreturn_t mtk_handle_irq_rx(int
|
||||
@@ -2994,8 +2994,8 @@ static irqreturn_t mtk_handle_irq_rx(int
|
||||
|
||||
eth->rx_events++;
|
||||
if (likely(napi_schedule_prep(ð->rx_napi))) {
|
||||
@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -2985,8 +2985,8 @@ static irqreturn_t mtk_handle_irq_tx(int
|
||||
@@ -3007,8 +3007,8 @@ static irqreturn_t mtk_handle_irq_tx(int
|
||||
|
||||
eth->tx_events++;
|
||||
if (likely(napi_schedule_prep(ð->tx_napi))) {
|
||||
@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -4617,6 +4617,8 @@ static int mtk_probe(struct platform_dev
|
||||
@@ -4675,6 +4675,8 @@ static int mtk_probe(struct platform_dev
|
||||
* for NAPI to work
|
||||
*/
|
||||
init_dummy_netdev(ð->dummy_dev);
|
||||
|
||||
@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2341,6 +2341,10 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
@@ -2342,6 +2342,10 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
From cbfed00575d15eafd85efd9619b7ecc0836a4aa7 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Sat, 13 Aug 2022 14:42:12 +0200
|
||||
Subject: [PATCH 04/10] net: mtk_sgmii: implement mtk_pcs_ops
|
||||
|
||||
Implement mtk_pcs_ops for the SGMII pcs to read the current state
|
||||
of the hardware.
|
||||
|
||||
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
[added DUPLEX_FULL]
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -139,10 +139,28 @@ static void mtk_pcs_link_up(struct phyli
|
||||
regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
}
|
||||
|
||||
+static void mtk_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state)
|
||||
+{
|
||||
+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
+ state->an_complete = !!(val & SGMII_AN_COMPLETE);
|
||||
+ state->link = !!(val & SGMII_LINK_STATYS);
|
||||
+ if (!state->link)
|
||||
+ return;
|
||||
+
|
||||
+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
|
||||
+ state->speed = val & RG_PHY_SPEED_3_125G ? SPEED_2500 : SPEED_1000;
|
||||
+ state->duplex = DUPLEX_FULL;
|
||||
+ state->pause = 0;
|
||||
+}
|
||||
+
|
||||
static const struct phylink_pcs_ops mtk_pcs_ops = {
|
||||
.pcs_config = mtk_pcs_config,
|
||||
.pcs_an_restart = mtk_pcs_restart_an,
|
||||
.pcs_link_up = mtk_pcs_link_up,
|
||||
+ .pcs_get_state = mtk_pcs_get_state,
|
||||
};
|
||||
|
||||
int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
|
||||
@ -1,31 +0,0 @@
|
||||
From e4dca7affb8c03438b63bdb5fddefd6ad2431cfd Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Mon, 15 Aug 2022 14:59:29 +0200
|
||||
Subject: [PATCH 07/10] net: mtk_sgmii: mtk_pcs_setup_mode_an: don't rely on
|
||||
register defaults
|
||||
|
||||
Ensure autonegotiation is enabled.
|
||||
|
||||
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -32,12 +32,13 @@ static int mtk_pcs_setup_mode_an(struct
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
|
||||
SGMII_LINK_TIMER_DEFAULT);
|
||||
|
||||
+ /* disable remote fault & enable auto neg */
|
||||
regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
- val |= SGMII_REMOTE_FAULT_DIS;
|
||||
+ val |= SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN;
|
||||
regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
|
||||
|
||||
regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
|
||||
- val |= SGMII_AN_RESTART;
|
||||
+ val |= SGMII_AN_RESTART | SGMII_AN_ENABLE;
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
From 952b64575613d26163a5afa5ff8bfdb57840091b Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Mon, 15 Aug 2022 15:00:14 +0200
|
||||
Subject: [PATCH 08/10] net: mtk_sgmii: set the speed according to the phy
|
||||
interface in AN
|
||||
|
||||
The non auto-negotioting code path is setting the correct speed for the
|
||||
interface. Ensure auto-negotiation code path is doing it as well.
|
||||
|
||||
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -20,12 +20,14 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st
|
||||
}
|
||||
|
||||
/* For SGMII interface mode */
|
||||
-static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
|
||||
+static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs, phy_interface_t interface)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
|
||||
val &= ~RG_PHY_SPEED_MASK;
|
||||
+ if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
+ val |= RG_PHY_SPEED_3_125G;
|
||||
regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
|
||||
|
||||
/* Setup the link timer and QPHY power up inside SGMIISYS */
|
||||
@@ -94,7 +96,7 @@ static int mtk_pcs_config(struct phylink
|
||||
if (interface != PHY_INTERFACE_MODE_SGMII)
|
||||
err = mtk_pcs_setup_mode_force(mpcs, interface);
|
||||
else if (phylink_autoneg_inband(mode))
|
||||
- err = mtk_pcs_setup_mode_an(mpcs);
|
||||
+ err = mtk_pcs_setup_mode_an(mpcs, interface);
|
||||
|
||||
/* Release PHYA power down state
|
||||
* Only removing bit SGMII_PHYA_PWD isn't enough.
|
||||
@ -1,22 +0,0 @@
|
||||
From 06773f19cffd6c9d34dcbc8320169afef5ab60ba Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Couzens <lynxis@fe80.eu>
|
||||
Date: Mon, 15 Aug 2022 13:58:07 +0200
|
||||
Subject: [PATCH 09/10] net: mtk_eth_soc: improve comment
|
||||
|
||||
Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_sgmii.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
|
||||
@@ -67,7 +67,8 @@ static int mtk_pcs_setup_mode_force(stru
|
||||
val &= ~SGMII_AN_ENABLE;
|
||||
regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
|
||||
|
||||
- /* Set the speed etc but leave the duplex unchanged */
|
||||
+ /* Set the speed etc but leave the duplex unchanged.
|
||||
+ * The SGMII mode for 2.5gbit is the same as for 1gbit, expect the speed in ANA_RGC3 */
|
||||
regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
|
||||
val &= SGMII_DUPLEX_HALF | ~SGMII_IF_MODE_MASK;
|
||||
val |= SGMII_SPEED_1000;
|
||||
@ -53,7 +53,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -4586,8 +4586,8 @@ static int mtk_probe(struct platform_dev
|
||||
@@ -4644,8 +4644,8 @@ static int mtk_probe(struct platform_dev
|
||||
for (i = 0; i < num_ppe; i++) {
|
||||
u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
|
||||
|
||||
@ -64,7 +64,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
|
||||
if (!eth->ppe[i]) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_dev;
|
||||
@@ -4712,6 +4712,7 @@ static const struct mtk_soc_data mt7622_
|
||||
@@ -4772,6 +4772,7 @@ static const struct mtk_soc_data mt7622_
|
||||
.required_pctl = false,
|
||||
.offload_version = 2,
|
||||
.hash_offset = 2,
|
||||
@ -72,7 +72,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4749,6 +4750,7 @@ static const struct mtk_soc_data mt7629_
|
||||
@@ -4809,6 +4810,7 @@ static const struct mtk_soc_data mt7629_
|
||||
.hw_features = MTK_HW_FEATURES,
|
||||
.required_clks = MT7629_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
@ -80,7 +80,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -4769,6 +4771,7 @@ static const struct mtk_soc_data mt7986_
|
||||
@@ -4829,6 +4831,7 @@ static const struct mtk_soc_data mt7981_
|
||||
.offload_version = 2,
|
||||
.hash_offset = 4,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry),
|
||||
@ -90,7 +90,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
|
||||
.rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1026,6 +1026,8 @@ struct mtk_reg_map {
|
||||
@@ -1014,6 +1014,8 @@ struct mtk_reg_map {
|
||||
* the extra setup for those pins used by GMAC.
|
||||
* @hash_offset Flow table hash offset.
|
||||
* @foe_entry_size Foe table entry size.
|
||||
@ -99,7 +99,7 @@ v2: fix wrong variable name in return value check spotted by Denis Kirjanov
|
||||
* @txd_size Tx DMA descriptor size.
|
||||
* @rxd_size Rx DMA descriptor size.
|
||||
* @rx_irq_done_mask Rx irq done register mask.
|
||||
@@ -1043,6 +1045,7 @@ struct mtk_soc_data {
|
||||
@@ -1031,6 +1033,7 @@ struct mtk_soc_data {
|
||||
u8 hash_offset;
|
||||
u16 foe_entry_size;
|
||||
netdev_features_t hw_features;
|
||||
|
||||
@ -17,7 +17,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
|
||||
@@ -1830,9 +1830,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
@@ -1852,9 +1852,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
|
||||
while (done < budget) {
|
||||
unsigned int pktlen, *rxdcsum;
|
||||
@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
dma_addr_t dma_addr;
|
||||
u32 hash, reason;
|
||||
int mac = 0;
|
||||
@@ -1967,36 +1965,21 @@ static int mtk_poll_rx(struct napi_struc
|
||||
@@ -1989,36 +1987,21 @@ static int mtk_poll_rx(struct napi_struc
|
||||
skb_checksum_none_assert(skb);
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
|
||||
@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
skb_record_rx_queue(skb, 0);
|
||||
napi_gro_receive(napi, skb);
|
||||
|
||||
@@ -2811,29 +2794,11 @@ static netdev_features_t mtk_fix_feature
|
||||
@@ -2833,29 +2816,11 @@ static netdev_features_t mtk_fix_feature
|
||||
|
||||
static int mtk_set_features(struct net_device *dev, netdev_features_t features)
|
||||
{
|
||||
@ -100,7 +100,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3147,30 +3112,6 @@ static int mtk_open(struct net_device *d
|
||||
@@ -3169,30 +3134,6 @@ static int mtk_open(struct net_device *d
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
int i, err;
|
||||
|
||||
@ -131,7 +131,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
|
||||
if (err) {
|
||||
netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
|
||||
@@ -3211,6 +3152,35 @@ static int mtk_open(struct net_device *d
|
||||
@@ -3233,6 +3174,35 @@ static int mtk_open(struct net_device *d
|
||||
phylink_start(mac->phylink);
|
||||
netif_tx_start_all_queues(dev);
|
||||
|
||||
@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3695,10 +3665,9 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
@@ -3717,10 +3687,9 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
|
||||
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
|
||||
@ -180,7 +180,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
/* set interrupt delays based on current Net DIM sample */
|
||||
mtk_dim_rx(ð->rx_dim.work);
|
||||
@@ -4336,7 +4305,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
@@ -4367,7 +4336,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
eth->netdev[id]->hw_features |= NETIF_F_LRO;
|
||||
|
||||
eth->netdev[id]->vlan_features = eth->soc->hw_features &
|
||||
|
||||
@ -16,7 +16,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
|
||||
@@ -1403,12 +1403,28 @@ static void mtk_wake_queue(struct mtk_et
|
||||
@@ -1425,12 +1425,28 @@ static void mtk_wake_queue(struct mtk_et
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
bool gso = false;
|
||||
int tx_num;
|
||||
|
||||
@@ -1430,6 +1446,18 @@ static netdev_tx_t mtk_start_xmit(struct
|
||||
@@ -1452,6 +1468,18 @@ static netdev_tx_t mtk_start_xmit(struct
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/* TSO: fill MSS info in tcp checksum field */
|
||||
if (skb_is_gso(skb)) {
|
||||
if (skb_cow_head(skb, 0)) {
|
||||
@@ -1445,8 +1473,14 @@ static netdev_tx_t mtk_start_xmit(struct
|
||||
@@ -1467,8 +1495,14 @@ static netdev_tx_t mtk_start_xmit(struct
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1319,6 +1319,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
|
||||
@@ -1277,6 +1277,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
|
||||
int mtk_eth_offload_init(struct mtk_eth *eth);
|
||||
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
|
||||
void *type_data);
|
||||
|
||||
@ -0,0 +1,766 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Sam.Shih <sam.shih@mediatek.com>
|
||||
* Author: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <dt-bindings/clock/mediatek,mt7981-clk.h>
|
||||
#include <dt-bindings/reset/mt7986-resets.h>
|
||||
#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
#include <dt-bindings/input/linux-event-codes.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/mux/mux.h>
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,mt7981";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a53";
|
||||
enable-method = "psci";
|
||||
reg = <0x0>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a53";
|
||||
enable-method = "psci";
|
||||
reg = <0x1>;
|
||||
};
|
||||
};
|
||||
|
||||
pwm: pwm@10048000 {
|
||||
compatible = "mediatek,mt7981-pwm";
|
||||
reg = <0 0x10048000 0 0x1000>;
|
||||
#pwm-cells = <2>;
|
||||
clocks = <&infracfg CLK_INFRA_PWM_STA>,
|
||||
<&infracfg CLK_INFRA_PWM_HCK>,
|
||||
<&infracfg CLK_INFRA_PWM1_CK>,
|
||||
<&infracfg CLK_INFRA_PWM2_CK>,
|
||||
<&infracfg CLK_INFRA_PWM3_CK>;
|
||||
clock-names = "top", "main", "pwm1", "pwm2", "pwm3";
|
||||
};
|
||||
|
||||
fan: pwm-fan {
|
||||
compatible = "pwm-fan";
|
||||
/* cooling level (0, 1, 2, 3) : (0% duty, 50% duty, 75% duty, 100% duty) */
|
||||
cooling-levels = <0 128 192 255>;
|
||||
#cooling-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
cpu_thermal: cpu-thermal {
|
||||
polling-delay-passive = <1000>;
|
||||
polling-delay = <1000>;
|
||||
thermal-sensors = <&thermal 0>;
|
||||
trips {
|
||||
cpu_trip_crit: crit {
|
||||
temperature = <125000>;
|
||||
hysteresis = <2000>;
|
||||
type = "critical";
|
||||
};
|
||||
|
||||
cpu_trip_hot: hot {
|
||||
temperature = <120000>;
|
||||
hysteresis = <2000>;
|
||||
type = "hot";
|
||||
};
|
||||
|
||||
cpu_trip_active_high: active-high {
|
||||
temperature = <115000>;
|
||||
hysteresis = <2000>;
|
||||
type = "active";
|
||||
};
|
||||
|
||||
cpu_trip_active_med: active-med {
|
||||
temperature = <85000>;
|
||||
hysteresis = <2000>;
|
||||
type = "active";
|
||||
};
|
||||
|
||||
cpu_trip_active_low: active-low {
|
||||
temperature = <60000>;
|
||||
hysteresis = <2000>;
|
||||
type = "active";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
cpu-active-high {
|
||||
/* active: set fan to cooling level 3 */
|
||||
cooling-device = <&fan 3 3>;
|
||||
trip = <&cpu_trip_active_high>;
|
||||
};
|
||||
|
||||
cpu-active-med {
|
||||
/* active: set fan to cooling level 2 */
|
||||
cooling-device = <&fan 2 2>;
|
||||
trip = <&cpu_trip_active_med>;
|
||||
};
|
||||
|
||||
cpu-active-low {
|
||||
/* passive: set fan to cooling level 1 */
|
||||
cooling-device = <&fan 1 1>;
|
||||
trip = <&cpu_trip_active_low>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
thermal: thermal@1100c800 {
|
||||
#thermal-sensor-cells = <1>;
|
||||
compatible = "mediatek,mt7981-thermal", "mediatek,mt7986-thermal";
|
||||
reg = <0 0x1100c800 0 0x800>;
|
||||
interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_THERM_CK>,
|
||||
<&infracfg CLK_INFRA_ADC_26M_CK>;
|
||||
clock-names = "therm", "auxadc";
|
||||
mediatek,auxadc = <&auxadc>;
|
||||
mediatek,apmixedsys = <&apmixedsys>;
|
||||
nvmem-cells = <&thermal_calibration>;
|
||||
nvmem-cell-names = "calibration-data";
|
||||
};
|
||||
|
||||
auxadc: adc@1100d000 {
|
||||
compatible = "mediatek,mt7981-auxadc",
|
||||
"mediatek,mt7986-auxadc",
|
||||
"mediatek,mt7622-auxadc";
|
||||
reg = <0 0x1100d000 0 0x1000>;
|
||||
clocks = <&infracfg CLK_INFRA_ADC_26M_CK>,
|
||||
<&infracfg CLK_INFRA_ADC_FRC_CK>;
|
||||
clock-names = "main", "32k";
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
|
||||
wdma: wdma@15104800 {
|
||||
compatible = "mediatek,wed-wdma";
|
||||
reg = <0 0x15104800 0 0x400>,
|
||||
<0 0x15104c00 0 0x400>;
|
||||
};
|
||||
|
||||
ap2woccif: ap2woccif@151a5000 {
|
||||
compatible = "mediatek,ap2woccif";
|
||||
reg = <0 0x151a5000 0 0x1000>,
|
||||
<0 0x151ad000 0 0x1000>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
|
||||
secmon_reserved: secmon@43000000 {
|
||||
reg = <0 0x43000000 0 0x30000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wmcpu_emi: wmcpu-reserved@47c80000 {
|
||||
reg = <0 0x47c80000 0 0x100000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wo_emi0: wo-emi@47d80000 {
|
||||
reg = <0 0x47d80000 0 0x40000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wo_data: wo-data@47dc0000 {
|
||||
reg = <0 0x47dc0000 0 0x240000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wo_ilm0: wo-ilm@151e0000 {
|
||||
reg = <0 0x151e0000 0 0x8000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wo_dlm0: wo-dlm@151e8000 {
|
||||
reg = <0 0x151e8000 0 0x2000>;
|
||||
no-map;
|
||||
};
|
||||
|
||||
wo_boot: wo-boot@15194000 {
|
||||
reg = <0 0x15194000 0 0x1000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-0.2";
|
||||
method = "smc";
|
||||
};
|
||||
|
||||
trng {
|
||||
compatible = "mediatek,mt7981-rng";
|
||||
};
|
||||
|
||||
clk40m: oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <40000000>;
|
||||
clock-output-names = "clkxtal";
|
||||
};
|
||||
|
||||
infracfg: infracfg@10001000 {
|
||||
compatible = "mediatek,mt7981-infracfg", "syscon";
|
||||
reg = <0 0x10001000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
topckgen: topckgen@1001B000 {
|
||||
compatible = "mediatek,mt7981-topckgen", "syscon";
|
||||
reg = <0 0x1001B000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
apmixedsys: apmixedsys@1001E000 {
|
||||
compatible = "mediatek,mt7981-apmixedsys", "mediatek,mt7986-apmixedsys", "syscon";
|
||||
reg = <0 0x1001E000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupt-parent = <&gic>;
|
||||
clock-frequency = <13000000>;
|
||||
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
};
|
||||
|
||||
watchdog: watchdog@1001c000 {
|
||||
compatible = "mediatek,mt7986-wdt",
|
||||
"mediatek,mt6589-wdt";
|
||||
reg = <0 0x1001c000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#reset-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gic: interrupt-controller@c000000 {
|
||||
compatible = "arm,gic-v3";
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-controller;
|
||||
reg = <0 0x0c000000 0 0x40000>, /* GICD */
|
||||
<0 0x0c080000 0 0x200000>; /* GICR */
|
||||
|
||||
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
uart0: serial@11002000 {
|
||||
compatible = "mediatek,mt6577-uart";
|
||||
reg = <0 0x11002000 0 0x400>;
|
||||
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_UART0_SEL>,
|
||||
<&infracfg CLK_INFRA_UART0_CK>;
|
||||
clock-names = "baud", "bus";
|
||||
assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&infracfg CLK_INFRA_UART0_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_CKSQ_40M>,
|
||||
<&topckgen CLK_TOP_UART_SEL>;
|
||||
pinctrl-0 = <&uart0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart1: serial@11003000 {
|
||||
compatible = "mediatek,mt6577-uart";
|
||||
reg = <0 0x11003000 0 0x400>;
|
||||
interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_UART1_SEL>,
|
||||
<&infracfg CLK_INFRA_UART1_CK>;
|
||||
clock-names = "baud", "bus";
|
||||
assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&infracfg CLK_INFRA_UART1_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_CKSQ_40M>,
|
||||
<&topckgen CLK_TOP_UART_SEL>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: serial@11004000 {
|
||||
compatible = "mediatek,mt6577-uart";
|
||||
reg = <0 0x11004000 0 0x400>;
|
||||
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_UART2_SEL>,
|
||||
<&infracfg CLK_INFRA_UART2_CK>;
|
||||
clock-names = "baud", "bus";
|
||||
assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&infracfg CLK_INFRA_UART2_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_CKSQ_40M>,
|
||||
<&topckgen CLK_TOP_UART_SEL>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c0: i2c@11007000 {
|
||||
compatible = "mediatek,mt7981-i2c";
|
||||
reg = <0 0x11007000 0 0x1000>,
|
||||
<0 0x10217080 0 0x80>;
|
||||
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-div = <1>;
|
||||
clocks = <&infracfg CLK_INFRA_I2C0_CK>,
|
||||
<&infracfg CLK_INFRA_AP_DMA_CK>;
|
||||
clock-names = "main", "dma";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcie: pcie@11280000 {
|
||||
compatible = "mediatek,mt7981-pcie",
|
||||
"mediatek,mt7986-pcie";
|
||||
device_type = "pci";
|
||||
reg = <0 0x11280000 0 0x4000>;
|
||||
reg-names = "pcie-mac";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x82000000 0 0x20000000
|
||||
0x0 0x20000000 0 0x10000000>;
|
||||
status = "disabled";
|
||||
|
||||
clocks = <&infracfg CLK_INFRA_IPCIE_CK>,
|
||||
<&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
|
||||
<&infracfg CLK_INFRA_IPCIER_CK>,
|
||||
<&infracfg CLK_INFRA_IPCIEB_CK>;
|
||||
|
||||
phys = <&u3port0 PHY_TYPE_PCIE>;
|
||||
phy-names = "pcie-phy";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc 0>,
|
||||
<0 0 0 2 &pcie_intc 1>,
|
||||
<0 0 0 3 &pcie_intc 2>,
|
||||
<0 0 0 4 &pcie_intc 3>;
|
||||
pcie_intc: interrupt-controller {
|
||||
interrupt-controller;
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
crypto: crypto@10320000 {
|
||||
compatible = "inside-secure,safexcel-eip97";
|
||||
reg = <0 0x10320000 0 0x40000>;
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "ring0", "ring1", "ring2", "ring3";
|
||||
clocks = <&topckgen CLK_TOP_EIP97B>;
|
||||
clock-names = "top_eip97_ck";
|
||||
assigned-clocks = <&topckgen CLK_TOP_EIP97B_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_NET1_D5>;
|
||||
};
|
||||
|
||||
pio: pinctrl@11d00000 {
|
||||
compatible = "mediatek,mt7981-pinctrl";
|
||||
reg = <0 0x11d00000 0 0x1000>,
|
||||
<0 0x11c00000 0 0x1000>,
|
||||
<0 0x11c10000 0 0x1000>,
|
||||
<0 0x11d20000 0 0x1000>,
|
||||
<0 0x11e00000 0 0x1000>,
|
||||
<0 0x11e20000 0 0x1000>,
|
||||
<0 0x11f00000 0 0x1000>,
|
||||
<0 0x11f10000 0 0x1000>,
|
||||
<0 0x1000b000 0 0x1000>;
|
||||
reg-names = "gpio", "iocfg_rt", "iocfg_rm",
|
||||
"iocfg_rb", "iocfg_lb", "iocfg_bl",
|
||||
"iocfg_tm", "iocfg_tl", "eint";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&pio 0 0 56>;
|
||||
interrupt-controller;
|
||||
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-parent = <&gic>;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
mdio_pins: mdc-mdio-pins {
|
||||
mux {
|
||||
function = "eth";
|
||||
groups = "smi_mdc_mdio";
|
||||
};
|
||||
};
|
||||
|
||||
uart0_pins: uart0-pins {
|
||||
mux {
|
||||
function = "uart";
|
||||
groups = "uart0";
|
||||
};
|
||||
};
|
||||
|
||||
wifi_dbdc_pins: wifi-dbdc-pins {
|
||||
mux {
|
||||
function = "eth";
|
||||
groups = "wf0_mode1";
|
||||
};
|
||||
conf {
|
||||
pins = "WF_HB1", "WF_HB2", "WF_HB3", "WF_HB4",
|
||||
"WF_HB0", "WF_HB0_B", "WF_HB5", "WF_HB6",
|
||||
"WF_HB7", "WF_HB8", "WF_HB9", "WF_HB10",
|
||||
"WF_TOP_CLK", "WF_TOP_DATA", "WF_XO_REQ",
|
||||
"WF_CBA_RESETB", "WF_DIG_RESETB";
|
||||
drive-strength = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ethsys: syscon@15000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "mediatek,mt7981-ethsys",
|
||||
"mediatek,mt7986-ethsys",
|
||||
"syscon";
|
||||
reg = <0 0x15000000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
wed: wed@15010000 {
|
||||
compatible = "mediatek,mt7981-wed",
|
||||
"mediatek,mt7986-wed",
|
||||
"syscon";
|
||||
reg = <0 0x15010000 0 0x1000>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
|
||||
memory-region = <&wo_emi0>, <&wo_ilm0>, <&wo_dlm0>,
|
||||
<&wo_data>, <&wo_boot>;
|
||||
memory-region-names = "wo-emi", "wo-ilm", "wo-dlm",
|
||||
"wo-data", "wo-boot";
|
||||
mediatek,wo-ccif = <&wo_ccif0>;
|
||||
};
|
||||
|
||||
eth: ethernet@15100000 {
|
||||
compatible = "mediatek,mt7981-eth";
|
||||
reg = <0 0x15100000 0 0x80000>;
|
||||
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <ðsys CLK_ETH_FE_EN>,
|
||||
<ðsys CLK_ETH_GP2_EN>,
|
||||
<ðsys CLK_ETH_GP1_EN>,
|
||||
<ðsys CLK_ETH_WOCPU0_EN>,
|
||||
<&sgmiisys0 CLK_SGM0_TX_EN>,
|
||||
<&sgmiisys0 CLK_SGM0_RX_EN>,
|
||||
<&sgmiisys0 CLK_SGM0_CK0_EN>,
|
||||
<&sgmiisys0 CLK_SGM0_CDR_CK0_EN>,
|
||||
<&sgmiisys1 CLK_SGM1_TX_EN>,
|
||||
<&sgmiisys1 CLK_SGM1_RX_EN>,
|
||||
<&sgmiisys1 CLK_SGM1_CK1_EN>,
|
||||
<&sgmiisys1 CLK_SGM1_CDR_CK1_EN>,
|
||||
<&topckgen CLK_TOP_SGM_REG>,
|
||||
<&topckgen CLK_TOP_NETSYS_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_500M_SEL>;
|
||||
clock-names = "fe", "gp2", "gp1", "wocpu0",
|
||||
"sgmii_tx250m", "sgmii_rx250m",
|
||||
"sgmii_cdr_ref", "sgmii_cdr_fb",
|
||||
"sgmii2_tx250m", "sgmii2_rx250m",
|
||||
"sgmii2_cdr_ref", "sgmii2_cdr_fb",
|
||||
"sgmii_ck", "netsys0", "netsys1";
|
||||
assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_325M_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_NET2_800M>,
|
||||
<&topckgen CLK_TOP_CB_SGM_325M>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
|
||||
mediatek,infracfg = <&topmisc>;
|
||||
mediatek,wed = <&wed>;
|
||||
#reset-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
||||
mdio_bus: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
int_gbe_phy: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
phy-mode = "gmii";
|
||||
phy-is-integrated;
|
||||
nvmem-cells = <&phy_calibration>;
|
||||
nvmem-cell-names = "phy-cal-data";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
wo_ccif0: syscon@151a5000 {
|
||||
compatible = "mediatek,mt7986-wo-ccif", "syscon";
|
||||
reg = <0 0x151a5000 0 0x1000>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
sgmiisys0: syscon@10060000 {
|
||||
compatible = "mediatek,mt7981-sgmiisys_0", "mediatek,mt7986-sgmiisys_0", "syscon";
|
||||
reg = <0 0x10060000 0 0x1000>;
|
||||
mediatek,pnswap;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
sgmiisys1: syscon@10070000 {
|
||||
compatible = "mediatek,mt7981-sgmiisys_1", "mediatek,mt7986-sgmiisys_1", "syscon";
|
||||
reg = <0 0x10070000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
topmisc: topmisc@11d10000 {
|
||||
compatible = "mediatek,mt7981-topmisc", "syscon";
|
||||
reg = <0 0x11d10000 0 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
snand: snfi@11005000 {
|
||||
compatible = "mediatek,mt7986-snand";
|
||||
reg = <0 0x11005000 0 0x1000>, <0 0x11006000 0 0x1000>;
|
||||
reg-names = "nfi", "ecc";
|
||||
interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_SPINFI1_CK>,
|
||||
<&infracfg CLK_INFRA_NFI1_CK>,
|
||||
<&infracfg CLK_INFRA_NFI_HCK_CK>;
|
||||
clock-names = "pad_clk", "nfi_clk", "nfi_hclk";
|
||||
assigned-clocks = <&topckgen CLK_TOP_SPINFI_SEL>,
|
||||
<&topckgen CLK_TOP_NFI1X_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D8>,
|
||||
<&topckgen CLK_TOP_CB_M_D8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mmc0: mmc@11230000 {
|
||||
compatible = "mediatek,mt7986-mmc",
|
||||
"mediatek,mt7981-mmc";
|
||||
reg = <0 0x11230000 0 0x1000>, <0 0x11c20000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&topckgen CLK_TOP_EMMC_208M>,
|
||||
<&topckgen CLK_TOP_EMMC_400M>,
|
||||
<&infracfg CLK_INFRA_MSDC_CK>;
|
||||
assigned-clocks = <&topckgen CLK_TOP_EMMC_208M_SEL>,
|
||||
<&topckgen CLK_TOP_EMMC_400M_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
|
||||
<&topckgen CLK_TOP_CB_NET2_D2>;
|
||||
clock-names = "source", "hclk", "source_cg";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
wed_pcie: wed_pcie@10003000 {
|
||||
compatible = "mediatek,wed_pcie";
|
||||
reg = <0 0x10003000 0 0x10>;
|
||||
};
|
||||
|
||||
spi0: spi@1100a000 {
|
||||
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0 0x1100a000 0 0x100>;
|
||||
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&topckgen CLK_TOP_CB_M_D2>,
|
||||
<&topckgen CLK_TOP_SPI_SEL>,
|
||||
<&infracfg CLK_INFRA_SPI0_CK>,
|
||||
<&infracfg CLK_INFRA_SPI0_HCK_CK>;
|
||||
|
||||
clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi1: spi@1100b000 {
|
||||
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0 0x1100b000 0 0x100>;
|
||||
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&topckgen CLK_TOP_CB_M_D2>,
|
||||
<&topckgen CLK_TOP_SPIM_MST_SEL>,
|
||||
<&infracfg CLK_INFRA_SPI1_CK>,
|
||||
<&infracfg CLK_INFRA_SPI1_HCK_CK>;
|
||||
clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi2: spi@11009000 {
|
||||
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0 0x11009000 0 0x100>;
|
||||
interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&topckgen CLK_TOP_CB_M_D2>,
|
||||
<&topckgen CLK_TOP_SPI_SEL>,
|
||||
<&infracfg CLK_INFRA_SPI2_CK>,
|
||||
<&infracfg CLK_INFRA_SPI2_HCK_CK>;
|
||||
clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
consys: consys@10000000 {
|
||||
compatible = "mediatek,mt7981-consys";
|
||||
reg = <0 0x10000000 0 0x8600000>;
|
||||
memory-region = <&wmcpu_emi>;
|
||||
};
|
||||
|
||||
xhci: usb@11200000 {
|
||||
compatible = "mediatek,mt7986-xhci",
|
||||
"mediatek,mtk-xhci";
|
||||
reg = <0 0x11200000 0 0x2e00>,
|
||||
<0 0x11203e00 0 0x0100>;
|
||||
reg-names = "mac", "ippc";
|
||||
interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
|
||||
<&infracfg CLK_INFRA_IUSB_CK>,
|
||||
<&infracfg CLK_INFRA_IUSB_133_CK>,
|
||||
<&infracfg CLK_INFRA_IUSB_66M_CK>,
|
||||
<&topckgen CLK_TOP_U2U3_XHCI_SEL>;
|
||||
clock-names = "sys_ck",
|
||||
"ref_ck",
|
||||
"mcu_ck",
|
||||
"dma_ck",
|
||||
"xhci_ck";
|
||||
phys = <&u2port0 PHY_TYPE_USB2>,
|
||||
<&u3port0 PHY_TYPE_USB3>;
|
||||
vusb33-supply = <®_3p3v>;
|
||||
mediatek,u3p-dis-msk = <0x01>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb_phy: usb-phy@11e10000 {
|
||||
compatible = "mediatek,mt7981",
|
||||
"mediatek,generic-tphy-v2";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0 0x11e10000 0x1700>;
|
||||
status = "disabled";
|
||||
|
||||
u2port0: usb-phy@0 {
|
||||
reg = <0x0 0x700>;
|
||||
clocks = <&topckgen CLK_TOP_USB_FRMCNT_SEL>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
|
||||
u3port0: usb-phy@700 {
|
||||
reg = <0x700 0x900>;
|
||||
clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <1>;
|
||||
mediatek,syscon-type = <&topmisc 0x218 0>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
reg_3p3v: regulator-3p3v {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-3.3V";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
efuse: efuse@11f20000 {
|
||||
compatible = "mediatek,mt7981-efuse",
|
||||
"mediatek,efuse";
|
||||
reg = <0 0x11f20000 0 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
status = "okay";
|
||||
|
||||
thermal_calibration: thermal-calib@274 {
|
||||
reg = <0x274 0xc>;
|
||||
};
|
||||
|
||||
phy_calibration: phy-calib@8dc {
|
||||
reg = <0x8dc 0x10>;
|
||||
};
|
||||
|
||||
comb_rx_imp_p0: usb3-rx-imp@8c8 {
|
||||
reg = <0x8c8 1>;
|
||||
bits = <0 5>;
|
||||
};
|
||||
|
||||
comb_tx_imp_p0: usb3-tx-imp@8c8 {
|
||||
reg = <0x8c8 2>;
|
||||
bits = <5 5>;
|
||||
};
|
||||
|
||||
comb_intr_p0: usb3-intr@8c9 {
|
||||
reg = <0x8c9 1>;
|
||||
bits = <2 6>;
|
||||
};
|
||||
};
|
||||
|
||||
afe: audio-controller@11210000 {
|
||||
compatible = "mediatek,mt79xx-audio";
|
||||
reg = <0 0x11210000 0 0x9000>;
|
||||
interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&infracfg CLK_INFRA_AUD_BUS_CK>,
|
||||
<&infracfg CLK_INFRA_AUD_26M_CK>,
|
||||
<&infracfg CLK_INFRA_AUD_L_CK>,
|
||||
<&infracfg CLK_INFRA_AUD_AUD_CK>,
|
||||
<&infracfg CLK_INFRA_AUD_EG2_CK>,
|
||||
<&topckgen CLK_TOP_AUD_SEL>;
|
||||
clock-names = "aud_bus_ck",
|
||||
"aud_26m_ck",
|
||||
"aud_l_ck",
|
||||
"aud_aud_ck",
|
||||
"aud_eg2_ck",
|
||||
"aud_sel";
|
||||
assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>,
|
||||
<&topckgen CLK_TOP_A1SYS_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_L_SEL>,
|
||||
<&topckgen CLK_TOP_A_TUNER_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_APLL2_196M>,
|
||||
<&topckgen CLK_TOP_APLL2_D4>,
|
||||
<&topckgen CLK_TOP_CB_APLL2_196M>,
|
||||
<&topckgen CLK_TOP_APLL2_D4>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ice: ice_debug {
|
||||
compatible = "mediatek,mt7981-ice_debug",
|
||||
"mediatek,mt2701-ice_debug";
|
||||
clocks = <&infracfg CLK_INFRA_DBG_CK>;
|
||||
clock-names = "ice_dbg";
|
||||
};
|
||||
|
||||
wifi: wifi@18000000 {
|
||||
compatible = "mediatek,mt7981-wmac";
|
||||
resets = <&watchdog MT7986_TOPRGU_CONSYS_RST>;
|
||||
reset-names = "consys";
|
||||
pinctrl-0 = <&wifi_dbdc_pins>;
|
||||
pinctrl-names = "dbdc";
|
||||
clocks = <&topckgen CLK_TOP_NETSYS_MCU_SEL>,
|
||||
<&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
|
||||
clock-names = "mcu", "ap2conn";
|
||||
reg = <0 0x18000000 0 0x1000000>,
|
||||
<0 0x10003000 0 0x1000>,
|
||||
<0 0x11d10000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>;
|
||||
memory-region = <&wmcpu_emi>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
|
||||
* Author: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
* Author: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mux.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt7981-clk.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#define MT7981_PLL_FMAX (2500UL * MHZ)
|
||||
#define CON0_MT7981_RST_BAR BIT(27)
|
||||
|
||||
#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
|
||||
_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, \
|
||||
_div_table, _parent_name) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg, \
|
||||
.en_mask = _en_mask, .flags = _flags, \
|
||||
.rst_bar_mask = CON0_MT7981_RST_BAR, .fmax = MT7981_PLL_FMAX, \
|
||||
.pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
|
||||
.tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg, \
|
||||
.pcw_shift = _pcw_shift, .div_table = _div_table, \
|
||||
.parent_name = _parent_name, \
|
||||
}
|
||||
|
||||
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
|
||||
_pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) \
|
||||
PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, \
|
||||
_pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL, \
|
||||
"clkxtal")
|
||||
|
||||
static const struct mtk_pll_data plls[] = {
|
||||
PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, PLL_AO,
|
||||
32, 0x0200, 4, 0, 0x0204, 0),
|
||||
PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
|
||||
0x0210, 4, 0, 0x0214, 0),
|
||||
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
|
||||
0x0220, 4, 0, 0x0224, 0),
|
||||
PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023C, 0x00000001, 0, 32,
|
||||
0x0230, 4, 0, 0x0234, 0),
|
||||
PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024C, 0x00000001, 0, 32,
|
||||
0x0240, 4, 0, 0x0244, 0),
|
||||
PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025C, 0x00000001, 0, 32,
|
||||
0x0250, 4, 0, 0x0254, 0),
|
||||
PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32,
|
||||
0x0260, 4, 0, 0x0264, 0),
|
||||
PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
|
||||
0x0278, 4, 0, 0x027C, 0),
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7981_apmixed[] = {
|
||||
{ .compatible = "mediatek,mt7981-apmixedsys", },
|
||||
{}
|
||||
};
|
||||
|
||||
static int clk_mt7981_apmixed_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
|
||||
|
||||
clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_apmixed_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_apmixed_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct platform_driver clk_mt7981_apmixed_drv = {
|
||||
.probe = clk_mt7981_apmixed_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7981-apmixed",
|
||||
.of_match_table = of_match_clk_mt7981_apmixed,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7981_apmixed_drv);
|
||||
@ -0,0 +1,139 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
|
||||
* Author: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
* Author: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt7981-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs sgmii0_cg_regs = {
|
||||
.set_ofs = 0xE4,
|
||||
.clr_ofs = 0xE4,
|
||||
.sta_ofs = 0xE4,
|
||||
};
|
||||
|
||||
#define GATE_SGMII0(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &sgmii0_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate sgmii0_clks[] __initconst = {
|
||||
GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2),
|
||||
GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3),
|
||||
GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4),
|
||||
GATE_SGMII0(CLK_SGM0_CDR_CK0_EN, "sgm0_cdr_ck0_en", "usb_cdr", 5),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs sgmii1_cg_regs = {
|
||||
.set_ofs = 0xE4,
|
||||
.clr_ofs = 0xE4,
|
||||
.sta_ofs = 0xE4,
|
||||
};
|
||||
|
||||
#define GATE_SGMII1(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &sgmii1_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate sgmii1_clks[] __initconst = {
|
||||
GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2),
|
||||
GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3),
|
||||
GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4),
|
||||
GATE_SGMII1(CLK_SGM1_CDR_CK1_EN, "sgm1_cdr_ck1_en", "usb_cdr", 5),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs eth_cg_regs = {
|
||||
.set_ofs = 0x30,
|
||||
.clr_ofs = 0x30,
|
||||
.sta_ofs = 0x30,
|
||||
};
|
||||
|
||||
#define GATE_ETH(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = ð_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate eth_clks[] __initconst = {
|
||||
GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6),
|
||||
GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7),
|
||||
GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8),
|
||||
GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_wed_mcu", 15),
|
||||
};
|
||||
|
||||
static void __init mtk_sgmiisys_0_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
|
||||
|
||||
mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_sgmiisys_0, "mediatek,mt7981-sgmiisys_0",
|
||||
mtk_sgmiisys_0_init);
|
||||
|
||||
static void __init mtk_sgmiisys_1_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
|
||||
|
||||
mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_sgmiisys_1, "mediatek,mt7981-sgmiisys_1",
|
||||
mtk_sgmiisys_1_init);
|
||||
|
||||
static void __init mtk_ethsys_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
|
||||
|
||||
mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7981-ethsys", mtk_ethsys_init);
|
||||
@ -0,0 +1,235 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
|
||||
* Author: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
* Author: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mux.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt7981-clk.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
static DEFINE_SPINLOCK(mt7981_clk_lock);
|
||||
|
||||
static const struct mtk_fixed_factor infra_divs[] = {
|
||||
FACTOR(CLK_INFRA_66M_MCK, "infra_66m_mck", "sysaxi_sel", 1, 2),
|
||||
};
|
||||
|
||||
static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
|
||||
"uart_sel" };
|
||||
|
||||
static const char *const infra_spi0_parents[] __initconst = { "i2c_sel",
|
||||
"spi_sel" };
|
||||
|
||||
static const char *const infra_spi1_parents[] __initconst = { "i2c_sel",
|
||||
"spim_mst_sel" };
|
||||
|
||||
static const char *const infra_pwm1_parents[] __initconst = { "pwm_sel" };
|
||||
|
||||
static const char *const infra_pwm_bsel_parents[] __initconst = {
|
||||
"cb_rtc_32p7k", "csw_f26m_sel", "infra_66m_mck", "pwm_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_pcie_parents[] __initconst = {
|
||||
"cb_rtc_32p7k", "csw_f26m_sel", "cb_cksq_40m", "pextp_tl_ck_sel"
|
||||
};
|
||||
|
||||
static const struct mtk_mux infra_muxes[] = {
|
||||
/* MODULE_CLK_SEL_0 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
|
||||
infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
|
||||
infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
|
||||
infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
|
||||
infra_spi0_parents, 0x0018, 0x0010, 0x0014, 4, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
|
||||
infra_spi1_parents, 0x0018, 0x0010, 0x0014, 5, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI2_SEL, "infra_spi2_sel",
|
||||
infra_spi0_parents, 0x0018, 0x0010, 0x0014, 6, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
|
||||
infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 9, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
|
||||
infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 11, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM3_SEL, "infra_pwm3_sel",
|
||||
infra_pwm1_parents, 0x0018, 0x0010, 0x0014, 15, 1,
|
||||
-1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
|
||||
infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
|
||||
2, -1, -1, -1),
|
||||
/* MODULE_CLK_SEL_1 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
|
||||
infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
|
||||
-1, -1, -1),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra0_cg_regs = {
|
||||
.set_ofs = 0x40,
|
||||
.clr_ofs = 0x44,
|
||||
.sta_ofs = 0x48,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra1_cg_regs = {
|
||||
.set_ofs = 0x50,
|
||||
.clr_ofs = 0x54,
|
||||
.sta_ofs = 0x58,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra2_cg_regs = {
|
||||
.set_ofs = 0x60,
|
||||
.clr_ofs = 0x64,
|
||||
.sta_ofs = 0x68,
|
||||
};
|
||||
|
||||
#define GATE_INFRA0(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra0_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
#define GATE_INFRA1(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra1_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
#define GATE_INFRA2(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra2_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate infra_clks[] = {
|
||||
/* INFRA0 */
|
||||
GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_66m_mck", 0),
|
||||
GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_66m_mck", 1),
|
||||
GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
|
||||
GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
|
||||
GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
|
||||
GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi", 6),
|
||||
|
||||
GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi", 8),
|
||||
GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
|
||||
GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l", 10),
|
||||
GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys", 11),
|
||||
GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner", 13),
|
||||
GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
|
||||
14),
|
||||
GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_66m_mck", 15),
|
||||
GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_66m_mck", 16),
|
||||
GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_66m_mck", 24),
|
||||
GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
|
||||
GATE_INFRA0(CLK_INFRA_PWM3_CK, "infra_pwm3", "infra_pwm3_sel", 27),
|
||||
/* INFRA1 */
|
||||
GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
|
||||
GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_bck", 1),
|
||||
GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
|
||||
GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
|
||||
GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
|
||||
GATE_INFRA1(CLK_INFRA_SPI2_CK, "infra_spi2", "infra_spi2_sel", 6),
|
||||
GATE_INFRA1(CLK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", "infra_66m_mck", 7),
|
||||
GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x", 8),
|
||||
GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_bck", 9),
|
||||
GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_66m_mck", 10),
|
||||
GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
|
||||
GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
|
||||
GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_66m_mck",
|
||||
13),
|
||||
GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_66m_mck",
|
||||
14),
|
||||
GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "cb_rtc_32k", 15),
|
||||
GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_400m", 16),
|
||||
GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_208m", 17),
|
||||
GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi", 18),
|
||||
GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "sysaxi", 19),
|
||||
GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20),
|
||||
GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m", 21),
|
||||
GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x", 23),
|
||||
GATE_INFRA1(CLK_INFRA_I2C_MCK_CK, "infra_i2c_mck", "sysaxi", 25),
|
||||
GATE_INFRA1(CLK_INFRA_I2C_PCK_CK, "infra_i2c_pck", "infra_66m_mck", 26),
|
||||
/* INFRA2 */
|
||||
GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi", 0),
|
||||
GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "sysaxi", 1),
|
||||
GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys", 2),
|
||||
GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_ref", 3),
|
||||
GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl", 12),
|
||||
GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "cb_cksq_40m",
|
||||
13),
|
||||
GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m", 14),
|
||||
GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi", 15),
|
||||
};
|
||||
|
||||
static int clk_mt7981_infracfg_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
int nr = ARRAY_SIZE(infra_divs) + ARRAY_SIZE(infra_muxes) +
|
||||
ARRAY_SIZE(infra_clks);
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(nr);
|
||||
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
|
||||
mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
|
||||
&mt7981_clk_lock, clk_data);
|
||||
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_infracfg_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_infracfg_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7981_infracfg[] = {
|
||||
{ .compatible = "mediatek,mt7981-infracfg", },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7981_infracfg_drv = {
|
||||
.probe = clk_mt7981_infracfg_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7981-infracfg",
|
||||
.of_match_table = of_match_clk_mt7981_infracfg,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7981_infracfg_drv);
|
||||
@ -0,0 +1,450 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
|
||||
* Author: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mux.h"
|
||||
|
||||
#include <dt-bindings/clock/mediatek,mt7981-clk.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
static DEFINE_SPINLOCK(mt7981_clk_lock);
|
||||
|
||||
static const struct mtk_fixed_factor top_divs[] = {
|
||||
FACTOR(CLK_TOP_CB_CKSQ_40M, "cb_cksq_40m", "clkxtal", 1, 1),
|
||||
FACTOR(CLK_TOP_CB_M_416M, "cb_m_416m", "mpll", 1, 1),
|
||||
FACTOR(CLK_TOP_CB_M_D2, "cb_m_d2", "mpll", 1, 2),
|
||||
FACTOR(CLK_TOP_CB_M_D3, "cb_m_d3", "mpll", 1, 3),
|
||||
FACTOR(CLK_TOP_M_D3_D2, "m_d3_d2", "mpll", 1, 2),
|
||||
FACTOR(CLK_TOP_CB_M_D4, "cb_m_d4", "mpll", 1, 4),
|
||||
FACTOR(CLK_TOP_CB_M_D8, "cb_m_d8", "mpll", 1, 8),
|
||||
FACTOR(CLK_TOP_M_D8_D2, "m_d8_d2", "mpll", 1, 16),
|
||||
FACTOR(CLK_TOP_CB_MM_720M, "cb_mm_720m", "mmpll", 1, 1),
|
||||
FACTOR(CLK_TOP_CB_MM_D2, "cb_mm_d2", "mmpll", 1, 2),
|
||||
FACTOR(CLK_TOP_CB_MM_D3, "cb_mm_d3", "mmpll", 1, 3),
|
||||
FACTOR(CLK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", "mmpll", 1, 15),
|
||||
FACTOR(CLK_TOP_CB_MM_D4, "cb_mm_d4", "mmpll", 1, 4),
|
||||
FACTOR(CLK_TOP_CB_MM_D6, "cb_mm_d6", "mmpll", 1, 6),
|
||||
FACTOR(CLK_TOP_MM_D6_D2, "mm_d6_d2", "mmpll", 1, 12),
|
||||
FACTOR(CLK_TOP_CB_MM_D8, "cb_mm_d8", "mmpll", 1, 8),
|
||||
FACTOR(CLK_TOP_CB_APLL2_196M, "cb_apll2_196m", "apll2", 1, 1),
|
||||
FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2),
|
||||
FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
|
||||
FACTOR(CLK_TOP_NET1_2500M, "net1_2500m", "net1pll", 1, 1),
|
||||
FACTOR(CLK_TOP_CB_NET1_D4, "cb_net1_d4", "net1pll", 1, 4),
|
||||
FACTOR(CLK_TOP_CB_NET1_D5, "cb_net1_d5", "net1pll", 1, 5),
|
||||
FACTOR(CLK_TOP_NET1_D5_D2, "net1_d5_d2", "net1pll", 1, 10),
|
||||
FACTOR(CLK_TOP_NET1_D5_D4, "net1_d5_d4", "net1pll", 1, 20),
|
||||
FACTOR(CLK_TOP_CB_NET1_D8, "cb_net1_d8", "net1pll", 1, 8),
|
||||
FACTOR(CLK_TOP_NET1_D8_D2, "net1_d8_d2", "net1pll", 1, 16),
|
||||
FACTOR(CLK_TOP_NET1_D8_D4, "net1_d8_d4", "net1pll", 1, 32),
|
||||
FACTOR(CLK_TOP_CB_NET2_800M, "cb_net2_800m", "net2pll", 1, 1),
|
||||
FACTOR(CLK_TOP_CB_NET2_D2, "cb_net2_d2", "net2pll", 1, 2),
|
||||
FACTOR(CLK_TOP_CB_NET2_D4, "cb_net2_d4", "net2pll", 1, 4),
|
||||
FACTOR(CLK_TOP_NET2_D4_D2, "net2_d4_d2", "net2pll", 1, 8),
|
||||
FACTOR(CLK_TOP_NET2_D4_D4, "net2_d4_d4", "net2pll", 1, 16),
|
||||
FACTOR(CLK_TOP_CB_NET2_D6, "cb_net2_d6", "net2pll", 1, 6),
|
||||
FACTOR(CLK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m", "wedmcupll", 1, 1),
|
||||
FACTOR(CLK_TOP_CB_SGM_325M, "cb_sgm_325m", "sgmpll", 1, 1),
|
||||
FACTOR(CLK_TOP_CKSQ_40M_D2, "cksq_40m_d2", "cb_cksq_40m", 1, 2),
|
||||
FACTOR(CLK_TOP_CB_RTC_32K, "cb_rtc_32k", "cb_cksq_40m", 1, 1250),
|
||||
FACTOR(CLK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", "cb_cksq_40m", 1, 1220),
|
||||
FACTOR(CLK_TOP_USB_TX250M, "usb_tx250m", "cb_cksq_40m", 1, 1),
|
||||
FACTOR(CLK_TOP_FAUD, "faud", "aud_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_NFI1X, "nfi1x", "nfi1x_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", "cb_cksq_40m", 1, 1),
|
||||
FACTOR(CLK_TOP_USB_CDR_CK, "usb_cdr", "cb_cksq_40m", 1, 1),
|
||||
FACTOR(CLK_TOP_USB_LN0_CK, "usb_ln0", "cb_cksq_40m", 1, 1),
|
||||
FACTOR(CLK_TOP_SPINFI_BCK, "spinfi_bck", "spinfi_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_SPI, "spi", "spi_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_SPIM_MST, "spim_mst", "spim_mst_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_UART_BCK, "uart_bck", "uart_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_PWM_BCK, "pwm_bck", "pwm_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_I2C_BCK, "i2c_bck", "i2c_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_PEXTP_TL, "pextp_tl", "pextp_tl_ck_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_EMMC_208M, "emmc_208m", "emmc_208m_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_EMMC_400M, "emmc_400m", "emmc_400m_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_DRAMC_REF, "dramc_ref", "dramc_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_DRAMC_MD32, "dramc_md32", "dramc_md32_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_SYSAXI, "sysaxi", "sysaxi_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_SYSAPB, "sysapb", "sysapb_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_ARM_DB_MAIN, "arm_db_main", "arm_db_main_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_AP2CNN_HOST, "ap2cnn_host", "ap2cnn_host_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_NETSYS, "netsys", "netsys_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_NETSYS_500M, "netsys_500m", "netsys_500m_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", "netsys_mcu_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_NETSYS_2X, "netsys_2x", "netsys_2x_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_SGM_325M, "sgm_325m", "sgm_325m_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_SGM_REG, "sgm_reg", "sgm_reg_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_F26M, "csw_f26m", "csw_f26m_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_EIP97B, "eip97b", "eip97b_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_USB3_PHY, "usb3_phy", "usb3_phy_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_AUD, "aud", "faud", 1, 1),
|
||||
FACTOR(CLK_TOP_A1SYS, "a1sys", "a1sys_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_AUD_L, "aud_l", "aud_l_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_A_TUNER, "a_tuner", "a_tuner_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_U2U3_REF, "u2u3_ref", "u2u3_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_U2U3_SYS, "u2u3_sys", "u2u3_sys_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_U2U3_XHCI, "u2u3_xhci", "u2u3_xhci_sel", 1, 1),
|
||||
FACTOR(CLK_TOP_USB_FRMCNT, "usb_frmcnt", "usb_frmcnt_sel", 1, 1),
|
||||
};
|
||||
|
||||
static const char * const nfi1x_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_mm_d4",
|
||||
"net1_d8_d2",
|
||||
"cb_net2_d6",
|
||||
"cb_m_d4",
|
||||
"cb_mm_d8",
|
||||
"net1_d8_d4",
|
||||
"cb_m_d8"
|
||||
};
|
||||
|
||||
static const char * const spinfi_parents[] __initconst = {
|
||||
"cksq_40m_d2",
|
||||
"cb_cksq_40m",
|
||||
"net1_d5_d4",
|
||||
"cb_m_d4",
|
||||
"cb_mm_d8",
|
||||
"net1_d8_d4",
|
||||
"mm_d6_d2",
|
||||
"cb_m_d8"
|
||||
};
|
||||
|
||||
static const char * const spi_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_m_d2",
|
||||
"cb_mm_d4",
|
||||
"net1_d8_d2",
|
||||
"cb_net2_d6",
|
||||
"net1_d5_d4",
|
||||
"cb_m_d4",
|
||||
"net1_d8_d4"
|
||||
};
|
||||
|
||||
static const char * const uart_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_m_d8",
|
||||
"m_d8_d2"
|
||||
};
|
||||
|
||||
static const char * const pwm_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"net1_d8_d2",
|
||||
"net1_d5_d4",
|
||||
"cb_m_d4",
|
||||
"m_d8_d2",
|
||||
"cb_rtc_32k"
|
||||
};
|
||||
|
||||
static const char * const i2c_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"net1_d5_d4",
|
||||
"cb_m_d4",
|
||||
"net1_d8_d4"
|
||||
};
|
||||
|
||||
static const char * const pextp_tl_ck_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"net1_d5_d4",
|
||||
"cb_m_d4",
|
||||
"cb_rtc_32k"
|
||||
};
|
||||
|
||||
static const char * const emmc_208m_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_m_d2",
|
||||
"cb_net2_d4",
|
||||
"cb_apll2_196m",
|
||||
"cb_mm_d4",
|
||||
"net1_d8_d2",
|
||||
"cb_mm_d6"
|
||||
};
|
||||
|
||||
static const char * const emmc_400m_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_net2_d2",
|
||||
"cb_mm_d2",
|
||||
"cb_net2_d2"
|
||||
};
|
||||
|
||||
static const char * const csw_f26m_parents[] __initconst = {
|
||||
"cksq_40m_d2",
|
||||
"m_d8_d2"
|
||||
};
|
||||
|
||||
static const char * const dramc_md32_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_m_d2",
|
||||
"cb_wedmcu_208m"
|
||||
};
|
||||
|
||||
static const char * const sysaxi_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"net1_d8_d2"
|
||||
};
|
||||
|
||||
static const char * const sysapb_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"m_d3_d2"
|
||||
};
|
||||
|
||||
static const char * const arm_db_main_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_net2_d6"
|
||||
};
|
||||
|
||||
static const char * const ap2cnn_host_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"net1_d8_d4"
|
||||
};
|
||||
|
||||
static const char * const netsys_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_mm_d2"
|
||||
};
|
||||
|
||||
static const char * const netsys_500m_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_net1_d5"
|
||||
};
|
||||
|
||||
static const char * const netsys_mcu_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_mm_720m",
|
||||
"cb_net1_d4",
|
||||
"cb_net1_d5",
|
||||
"cb_m_416m"
|
||||
};
|
||||
|
||||
static const char * const netsys_2x_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_net2_800m",
|
||||
"cb_mm_720m"
|
||||
};
|
||||
|
||||
static const char * const sgm_325m_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_sgm_325m"
|
||||
};
|
||||
|
||||
static const char * const sgm_reg_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_net2_d4"
|
||||
};
|
||||
|
||||
static const char * const eip97b_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_net1_d5",
|
||||
"cb_m_416m",
|
||||
"cb_mm_d2",
|
||||
"net1_d5_d2"
|
||||
};
|
||||
|
||||
static const char * const aud_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_apll2_196m"
|
||||
};
|
||||
|
||||
static const char * const a1sys_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"apll2_d4"
|
||||
};
|
||||
|
||||
static const char * const aud_l_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_apll2_196m",
|
||||
"m_d8_d2"
|
||||
};
|
||||
|
||||
static const char * const a_tuner_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"apll2_d4",
|
||||
"m_d8_d2"
|
||||
};
|
||||
|
||||
static const char * const u2u3_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"m_d8_d2"
|
||||
};
|
||||
|
||||
static const char * const u2u3_sys_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"net1_d5_d4"
|
||||
};
|
||||
|
||||
static const char * const usb_frmcnt_parents[] __initconst = {
|
||||
"cb_cksq_40m",
|
||||
"cb_mm_d3_d5"
|
||||
};
|
||||
|
||||
static const struct mtk_mux top_muxes[] = {
|
||||
/* CLK_CFG_0 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
|
||||
0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
|
||||
0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents,
|
||||
0x000, 0x004, 0x008, 16, 3, 23, 0x1C0, 2),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
|
||||
0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
|
||||
/* CLK_CFG_1 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
|
||||
0x010, 0x014, 0x018, 0, 2, 7, 0x1C0, 4),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
|
||||
0x010, 0x014, 0x018, 8, 3, 15, 0x1C0, 5),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents,
|
||||
0x010, 0x014, 0x018, 16, 2, 23, 0x1C0, 6),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
|
||||
pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2, 31,
|
||||
0x1C0, 7),
|
||||
/* CLK_CFG_2 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_208M_SEL, "emmc_208m_sel",
|
||||
emmc_208m_parents, 0x020, 0x024, 0x028, 0, 3, 7,
|
||||
0x1C0, 8),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel",
|
||||
emmc_400m_parents, 0x020, 0x024, 0x028, 8, 2, 15,
|
||||
0x1C0, 9),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_F26M_SEL, "csw_f26m_sel",
|
||||
csw_f26m_parents, 0x020, 0x024, 0x028, 16, 1, 23,
|
||||
0x1C0, 10,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
|
||||
csw_f26m_parents, 0x020, 0x024, 0x028, 24, 1,
|
||||
31, 0x1C0, 11,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
|
||||
/* CLK_CFG_3 */
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
|
||||
dramc_md32_parents, 0x030, 0x034, 0x038, 0, 2,
|
||||
7, 0x1C0, 12,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
|
||||
sysaxi_parents, 0x030, 0x034, 0x038, 8, 1, 15,
|
||||
0x1C0, 13,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
|
||||
sysapb_parents, 0x030, 0x034, 0x038, 16, 1,
|
||||
23, 0x1C0, 14,
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
|
||||
arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1, 31,
|
||||
0x1C0, 15),
|
||||
/* CLK_CFG_4 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
|
||||
ap2cnn_host_parents, 0x040, 0x044, 0x048, 0, 1, 7,
|
||||
0x1C0, 16),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
|
||||
0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
|
||||
netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1, 23,
|
||||
0x1C0, 18),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
|
||||
netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
|
||||
0x1C0, 19),
|
||||
/* CLK_CFG_5 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
|
||||
netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
|
||||
0x1C0, 20),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
|
||||
sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
|
||||
0x1C0, 21),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
|
||||
0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
|
||||
0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
|
||||
/* CLK_CFG_6 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
|
||||
csw_f26m_parents, 0x060, 0x064, 0x068, 0, 1,
|
||||
7, 0x1C0, 24),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x060,
|
||||
0x064, 0x068, 8, 1, 15, 0x1C0, 25),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
|
||||
0x060, 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
|
||||
0x060, 0x064, 0x068, 24, 2, 31, 0x1C0, 27),
|
||||
/* CLK_CFG_7 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
|
||||
a_tuner_parents, 0x070, 0x074, 0x078, 0, 2, 7,
|
||||
0x1C0, 28),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x070,
|
||||
0x074, 0x078, 8, 1, 15, 0x1C0, 29),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
|
||||
u2u3_sys_parents, 0x070, 0x074, 0x078, 16, 1, 23,
|
||||
0x1C0, 30),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
|
||||
u2u3_sys_parents, 0x070, 0x074, 0x078, 24, 1, 31,
|
||||
0x1C4, 0),
|
||||
/* CLK_CFG_8 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel",
|
||||
usb_frmcnt_parents, 0x080, 0x084, 0x088, 0, 1, 7,
|
||||
0x1C4, 1),
|
||||
};
|
||||
|
||||
static struct mtk_composite top_aud_divs[] = {
|
||||
DIV_GATE(CLK_TOP_AUD_I2S_M, "aud_i2s_m", "aud",
|
||||
0x0420, 0, 0x0420, 8, 8),
|
||||
};
|
||||
|
||||
static int clk_mt7981_topckgen_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
int nr = ARRAY_SIZE(top_divs) + ARRAY_SIZE(top_muxes) +
|
||||
ARRAY_SIZE(top_aud_divs);
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(nr);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
|
||||
mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
|
||||
&mt7981_clk_lock, clk_data);
|
||||
mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), base,
|
||||
&mt7981_clk_lock, clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_topckgen_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_topckgen_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7981_topckgen[] = {
|
||||
{ .compatible = "mediatek,mt7981-topckgen", },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7981_topckgen_drv = {
|
||||
.probe = clk_mt7981_topckgen_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7981-topckgen",
|
||||
.of_match_table = of_match_clk_mt7981_topckgen,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7981_topckgen_drv);
|
||||
@ -0,0 +1,993 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* The MT7981 driver based on Linux generic pinctrl binding.
|
||||
*
|
||||
* Copyright (C) 2020 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
*/
|
||||
|
||||
#include "pinctrl-moore.h"
|
||||
|
||||
#define MT7981_PIN(_number, _name) \
|
||||
MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
|
||||
|
||||
#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, _x_bits) \
|
||||
PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
|
||||
_x_bits, 32, 0)
|
||||
|
||||
#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, _x_bits) \
|
||||
PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
|
||||
_x_bits, 32, 1)
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = {
|
||||
PIN_FIELD(0, 56, 0x300, 0x10, 0, 4),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = {
|
||||
PIN_FIELD(0, 56, 0x0, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_di_range[] = {
|
||||
PIN_FIELD(0, 56, 0x200, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_do_range[] = {
|
||||
PIN_FIELD(0, 56, 0x100, 0x10, 0, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = {
|
||||
PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1),
|
||||
|
||||
PIN_FIELD_BASE(9, 9, 5, 0x20, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1),
|
||||
|
||||
PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1),
|
||||
|
||||
PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1),
|
||||
|
||||
PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1),
|
||||
|
||||
PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1),
|
||||
|
||||
PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1),
|
||||
|
||||
PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = {
|
||||
PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1),
|
||||
|
||||
PIN_FIELD_BASE(9, 9, 5, 0x90, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1),
|
||||
|
||||
PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1),
|
||||
|
||||
PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1),
|
||||
|
||||
PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1),
|
||||
|
||||
PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1),
|
||||
|
||||
PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1),
|
||||
|
||||
PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = {
|
||||
PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1),
|
||||
|
||||
PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = {
|
||||
PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1),
|
||||
|
||||
PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = {
|
||||
PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3),
|
||||
PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3),
|
||||
|
||||
PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3),
|
||||
|
||||
PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1),
|
||||
PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3),
|
||||
PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3),
|
||||
|
||||
PIN_FIELD_BASE(9, 9, 5, 0x00, 0x10, 27, 3),
|
||||
PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3),
|
||||
PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3),
|
||||
PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3),
|
||||
|
||||
PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3),
|
||||
|
||||
PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3),
|
||||
PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3),
|
||||
PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3),
|
||||
PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3),
|
||||
PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3),
|
||||
PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3),
|
||||
PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3),
|
||||
PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3),
|
||||
|
||||
PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3),
|
||||
PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3),
|
||||
PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3),
|
||||
PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3),
|
||||
|
||||
PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3),
|
||||
|
||||
PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3),
|
||||
PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3),
|
||||
|
||||
PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3),
|
||||
PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3),
|
||||
|
||||
PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3),
|
||||
PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3),
|
||||
PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3),
|
||||
PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3),
|
||||
PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3),
|
||||
PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3),
|
||||
PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3),
|
||||
PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3),
|
||||
|
||||
PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3),
|
||||
PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3),
|
||||
PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3),
|
||||
PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3),
|
||||
PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3),
|
||||
PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3),
|
||||
PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = {
|
||||
PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1),
|
||||
|
||||
PIN_FIELD_BASE(9, 9, 5, 0x30, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1),
|
||||
|
||||
PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1),
|
||||
|
||||
PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1),
|
||||
|
||||
PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1),
|
||||
|
||||
PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = {
|
||||
PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1),
|
||||
|
||||
PIN_FIELD_BASE(9, 9, 5, 0x40, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1),
|
||||
|
||||
PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1),
|
||||
|
||||
PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1),
|
||||
|
||||
PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1),
|
||||
|
||||
PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = {
|
||||
PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1),
|
||||
|
||||
PIN_FIELD_BASE(9, 9, 5, 0x50, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1),
|
||||
PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1),
|
||||
|
||||
PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1),
|
||||
PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1),
|
||||
PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1),
|
||||
PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1),
|
||||
PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1),
|
||||
|
||||
PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1),
|
||||
PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1),
|
||||
PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1),
|
||||
|
||||
PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1),
|
||||
|
||||
PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1),
|
||||
PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1),
|
||||
|
||||
PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1),
|
||||
PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1),
|
||||
PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1),
|
||||
PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_reg_calc mt7981_reg_cals[] = {
|
||||
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range),
|
||||
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range),
|
||||
[PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range),
|
||||
[PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range),
|
||||
[PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range),
|
||||
[PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range),
|
||||
[PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range),
|
||||
[PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range),
|
||||
[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range),
|
||||
[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range),
|
||||
[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range),
|
||||
[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_desc mt7981_pins[] = {
|
||||
MT7981_PIN(0, "GPIO_WPS"),
|
||||
MT7981_PIN(1, "GPIO_RESET"),
|
||||
MT7981_PIN(2, "SYS_WATCHDOG"),
|
||||
MT7981_PIN(3, "PCIE_PERESET_N"),
|
||||
MT7981_PIN(4, "JTAG_JTDO"),
|
||||
MT7981_PIN(5, "JTAG_JTDI"),
|
||||
MT7981_PIN(6, "JTAG_JTMS"),
|
||||
MT7981_PIN(7, "JTAG_JTCLK"),
|
||||
MT7981_PIN(8, "JTAG_JTRST_N"),
|
||||
MT7981_PIN(9, "WO_JTAG_JTDO"),
|
||||
MT7981_PIN(10, "WO_JTAG_JTDI"),
|
||||
MT7981_PIN(11, "WO_JTAG_JTMS"),
|
||||
MT7981_PIN(12, "WO_JTAG_JTCLK"),
|
||||
MT7981_PIN(13, "WO_JTAG_JTRST_N"),
|
||||
MT7981_PIN(14, "USB_VBUS"),
|
||||
MT7981_PIN(15, "PWM0"),
|
||||
MT7981_PIN(16, "SPI0_CLK"),
|
||||
MT7981_PIN(17, "SPI0_MOSI"),
|
||||
MT7981_PIN(18, "SPI0_MISO"),
|
||||
MT7981_PIN(19, "SPI0_CS"),
|
||||
MT7981_PIN(20, "SPI0_HOLD"),
|
||||
MT7981_PIN(21, "SPI0_WP"),
|
||||
MT7981_PIN(22, "SPI1_CLK"),
|
||||
MT7981_PIN(23, "SPI1_MOSI"),
|
||||
MT7981_PIN(24, "SPI1_MISO"),
|
||||
MT7981_PIN(25, "SPI1_CS"),
|
||||
MT7981_PIN(26, "SPI2_CLK"),
|
||||
MT7981_PIN(27, "SPI2_MOSI"),
|
||||
MT7981_PIN(28, "SPI2_MISO"),
|
||||
MT7981_PIN(29, "SPI2_CS"),
|
||||
MT7981_PIN(30, "SPI2_HOLD"),
|
||||
MT7981_PIN(31, "SPI2_WP"),
|
||||
MT7981_PIN(32, "UART0_RXD"),
|
||||
MT7981_PIN(33, "UART0_TXD"),
|
||||
MT7981_PIN(34, "PCIE_CLK_REQ"),
|
||||
MT7981_PIN(35, "PCIE_WAKE_N"),
|
||||
MT7981_PIN(36, "SMI_MDC"),
|
||||
MT7981_PIN(37, "SMI_MDIO"),
|
||||
MT7981_PIN(38, "GBE_INT"),
|
||||
MT7981_PIN(39, "GBE_RESET"),
|
||||
MT7981_PIN(40, "WF_DIG_RESETB"),
|
||||
MT7981_PIN(41, "WF_CBA_RESETB"),
|
||||
MT7981_PIN(42, "WF_XO_REQ"),
|
||||
MT7981_PIN(43, "WF_TOP_CLK"),
|
||||
MT7981_PIN(44, "WF_TOP_DATA"),
|
||||
MT7981_PIN(45, "WF_HB1"),
|
||||
MT7981_PIN(46, "WF_HB2"),
|
||||
MT7981_PIN(47, "WF_HB3"),
|
||||
MT7981_PIN(48, "WF_HB4"),
|
||||
MT7981_PIN(49, "WF_HB0"),
|
||||
MT7981_PIN(50, "WF_HB0_B"),
|
||||
MT7981_PIN(51, "WF_HB5"),
|
||||
MT7981_PIN(52, "WF_HB6"),
|
||||
MT7981_PIN(53, "WF_HB7"),
|
||||
MT7981_PIN(54, "WF_HB8"),
|
||||
MT7981_PIN(55, "WF_HB9"),
|
||||
MT7981_PIN(56, "WF_HB10"),
|
||||
};
|
||||
|
||||
/* List all groups consisting of these pins dedicated to the enablement of
|
||||
* certain hardware block and the corresponding mode for all of the pins.
|
||||
* The hardware probably has multiple combinations of these pinouts.
|
||||
*/
|
||||
|
||||
/* WA_AICE */
|
||||
static int mt7981_wa_aice1_pins[] = { 0, 1, };
|
||||
static int mt7981_wa_aice1_funcs[] = { 2, 2, };
|
||||
|
||||
static int mt7981_wa_aice2_pins[] = { 0, 1, };
|
||||
static int mt7981_wa_aice2_funcs[] = { 3, 3, };
|
||||
|
||||
static int mt7981_wa_aice3_pins[] = { 28, 29, };
|
||||
static int mt7981_wa_aice3_funcs[] = { 3, 3, };
|
||||
|
||||
static int mt7981_wm_aice1_pins[] = { 9, 10, };
|
||||
static int mt7981_wm_aice1_funcs[] = { 2, 2, };
|
||||
|
||||
static int mt7981_wm_aice2_pins[] = { 30, 31, };
|
||||
static int mt7981_wm_aice2_funcs[] = { 5, 5, };
|
||||
|
||||
/* WM_UART */
|
||||
static int mt7981_wm_uart_0_pins[] = { 0, 1, };
|
||||
static int mt7981_wm_uart_0_funcs[] = { 5, 5, };
|
||||
|
||||
static int mt7981_wm_uart_1_pins[] = { 20, 21, };
|
||||
static int mt7981_wm_uart_1_funcs[] = { 4, 4, };
|
||||
|
||||
static int mt7981_wm_uart_2_pins[] = { 30, 31, };
|
||||
static int mt7981_wm_uart_2_funcs[] = { 3, 3, };
|
||||
|
||||
/* DFD */
|
||||
static int mt7981_dfd_pins[] = { 0, 1, 4, 5, };
|
||||
static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, };
|
||||
|
||||
/* SYS_WATCHDOG */
|
||||
static int mt7981_watchdog_pins[] = { 2, };
|
||||
static int mt7981_watchdog_funcs[] = { 1, };
|
||||
|
||||
static int mt7981_watchdog1_pins[] = { 13, };
|
||||
static int mt7981_watchdog1_funcs[] = { 5, };
|
||||
|
||||
/* PCIE_PERESET_N */
|
||||
static int mt7981_pcie_pereset_pins[] = { 3, };
|
||||
static int mt7981_pcie_pereset_funcs[] = { 1, };
|
||||
|
||||
/* JTAG */
|
||||
static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, };
|
||||
static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, };
|
||||
|
||||
/* WM_JTAG */
|
||||
static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, };
|
||||
static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, };
|
||||
|
||||
static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, };
|
||||
static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
|
||||
|
||||
/* WO0_JTAG */
|
||||
static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, };
|
||||
static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, };
|
||||
|
||||
static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, };
|
||||
static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, };
|
||||
|
||||
/* UART2 */
|
||||
static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, };
|
||||
static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, };
|
||||
|
||||
/* GBE_LED0 */
|
||||
static int mt7981_gbe_led0_pins[] = { 8, };
|
||||
static int mt7981_gbe_led0_funcs[] = { 3, };
|
||||
|
||||
/* PTA_EXT */
|
||||
static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, };
|
||||
static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, };
|
||||
|
||||
static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, };
|
||||
static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, };
|
||||
|
||||
/* PWM2 */
|
||||
static int mt7981_pwm2_pins[] = { 7, };
|
||||
static int mt7981_pwm2_funcs[] = { 4, };
|
||||
|
||||
/* NET_WO0_UART_TXD */
|
||||
static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, };
|
||||
static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, };
|
||||
|
||||
static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, };
|
||||
static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, };
|
||||
|
||||
static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, };
|
||||
static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, };
|
||||
|
||||
/* SPI1 */
|
||||
static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, };
|
||||
static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, };
|
||||
|
||||
/* I2C */
|
||||
static int mt7981_i2c0_0_pins[] = { 6, 7, };
|
||||
static int mt7981_i2c0_0_funcs[] = { 6, 6, };
|
||||
|
||||
static int mt7981_i2c0_1_pins[] = { 30, 31, };
|
||||
static int mt7981_i2c0_1_funcs[] = { 4, 4, };
|
||||
|
||||
static int mt7981_i2c0_2_pins[] = { 36, 37, };
|
||||
static int mt7981_i2c0_2_funcs[] = { 2, 2, };
|
||||
|
||||
static int mt7981_u2_phy_i2c_pins[] = { 30, 31, };
|
||||
static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, };
|
||||
|
||||
static int mt7981_u3_phy_i2c_pins[] = { 32, 33, };
|
||||
static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, };
|
||||
|
||||
static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, };
|
||||
static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, };
|
||||
|
||||
static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, };
|
||||
static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, };
|
||||
|
||||
/* DFD_NTRST */
|
||||
static int mt7981_dfd_ntrst_pins[] = { 8, };
|
||||
static int mt7981_dfd_ntrst_funcs[] = { 6, };
|
||||
|
||||
/* PWM0 */
|
||||
static int mt7981_pwm0_0_pins[] = { 13, };
|
||||
static int mt7981_pwm0_0_funcs[] = { 2, };
|
||||
|
||||
static int mt7981_pwm0_1_pins[] = { 15, };
|
||||
static int mt7981_pwm0_1_funcs[] = { 1, };
|
||||
|
||||
/* PWM1 */
|
||||
static int mt7981_pwm1_0_pins[] = { 14, };
|
||||
static int mt7981_pwm1_0_funcs[] = { 2, };
|
||||
|
||||
static int mt7981_pwm1_1_pins[] = { 15, };
|
||||
static int mt7981_pwm1_1_funcs[] = { 3, };
|
||||
|
||||
/* GBE_LED1 */
|
||||
static int mt7981_gbe_led1_pins[] = { 13, };
|
||||
static int mt7981_gbe_led1_funcs[] = { 3, };
|
||||
|
||||
/* PCM */
|
||||
static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 };
|
||||
static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, };
|
||||
|
||||
/* UDI */
|
||||
static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, };
|
||||
static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, };
|
||||
|
||||
/* DRV_VBUS */
|
||||
static int mt7981_drv_vbus_pins[] = { 14, };
|
||||
static int mt7981_drv_vbus_funcs[] = { 1, };
|
||||
|
||||
/* EMMC */
|
||||
static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, };
|
||||
static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
|
||||
|
||||
/* SNFI */
|
||||
static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, };
|
||||
static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, };
|
||||
|
||||
/* SPI0 */
|
||||
static int mt7981_spi0_pins[] = { 16, 17, 18, 19, };
|
||||
static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, };
|
||||
|
||||
/* SPI0 */
|
||||
static int mt7981_spi0_wp_hold_pins[] = { 20, 21, };
|
||||
static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, };
|
||||
|
||||
/* SPI1 */
|
||||
static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, };
|
||||
static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, };
|
||||
|
||||
/* SPI2 */
|
||||
static int mt7981_spi2_pins[] = { 26, 27, 28, 29, };
|
||||
static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, };
|
||||
|
||||
/* SPI2 */
|
||||
static int mt7981_spi2_wp_hold_pins[] = { 30, 31, };
|
||||
static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, };
|
||||
|
||||
/* UART1 */
|
||||
static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, };
|
||||
static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, };
|
||||
|
||||
static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, };
|
||||
static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, };
|
||||
|
||||
/* UART2 */
|
||||
static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, };
|
||||
static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, };
|
||||
|
||||
/* UART0 */
|
||||
static int mt7981_uart0_pins[] = { 32, 33, };
|
||||
static int mt7981_uart0_funcs[] = { 1, 1, };
|
||||
|
||||
/* PCIE_CLK_REQ */
|
||||
static int mt7981_pcie_clk_pins[] = { 34, };
|
||||
static int mt7981_pcie_clk_funcs[] = { 2, };
|
||||
|
||||
/* PCIE_WAKE_N */
|
||||
static int mt7981_pcie_wake_pins[] = { 35, };
|
||||
static int mt7981_pcie_wake_funcs[] = { 2, };
|
||||
|
||||
/* MDC_MDIO */
|
||||
static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, };
|
||||
static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, };
|
||||
|
||||
static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, };
|
||||
static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, };
|
||||
|
||||
/* WF0_MODE1 */
|
||||
static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 };
|
||||
static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
|
||||
/* WF0_MODE3 */
|
||||
static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 };
|
||||
static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 };
|
||||
|
||||
/* WF2G_LED */
|
||||
static int mt7981_wf2g_led0_pins[] = { 30, };
|
||||
static int mt7981_wf2g_led0_funcs[] = { 2, };
|
||||
|
||||
static int mt7981_wf2g_led1_pins[] = { 34, };
|
||||
static int mt7981_wf2g_led1_funcs[] = { 1, };
|
||||
|
||||
/* WF5G_LED */
|
||||
static int mt7981_wf5g_led0_pins[] = { 31, };
|
||||
static int mt7981_wf5g_led0_funcs[] = { 2, };
|
||||
|
||||
static int mt7981_wf5g_led1_pins[] = { 35, };
|
||||
static int mt7981_wf5g_led1_funcs[] = { 1, };
|
||||
|
||||
/* MT7531_INT */
|
||||
static int mt7981_mt7531_int_pins[] = { 38, };
|
||||
static int mt7981_mt7531_int_funcs[] = { 1, };
|
||||
|
||||
/* ANT_SEL */
|
||||
static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 };
|
||||
static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
|
||||
|
||||
static const struct group_desc mt7981_groups[] = {
|
||||
/* @GPIO(0,1): WA_AICE(2) */
|
||||
PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1),
|
||||
/* @GPIO(0,1): WA_AICE(3) */
|
||||
PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2),
|
||||
/* @GPIO(0,1): WM_UART(5) */
|
||||
PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0),
|
||||
/* @GPIO(0,1,4,5): DFD(6) */
|
||||
PINCTRL_PIN_GROUP("dfd", mt7981_dfd),
|
||||
/* @GPIO(2): SYS_WATCHDOG(1) */
|
||||
PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog),
|
||||
/* @GPIO(3): PCIE_PERESET_N(1) */
|
||||
PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset),
|
||||
/* @GPIO(4,8) JTAG(1) */
|
||||
PINCTRL_PIN_GROUP("jtag", mt7981_jtag),
|
||||
/* @GPIO(4,8) WM_JTAG(2) */
|
||||
PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0),
|
||||
/* @GPIO(9,13) WO0_JTAG(1) */
|
||||
PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0),
|
||||
/* @GPIO(4,7) WM_JTAG(3) */
|
||||
PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0),
|
||||
/* @GPIO(8) GBE_LED0(3) */
|
||||
PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0),
|
||||
/* @GPIO(4,6) PTA_EXT(4) */
|
||||
PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0),
|
||||
/* @GPIO(7) PWM2(4) */
|
||||
PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2),
|
||||
/* @GPIO(8) NET_WO0_UART_TXD(4) */
|
||||
PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0),
|
||||
/* @GPIO(4,7) SPI1(5) */
|
||||
PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0),
|
||||
/* @GPIO(6,7) I2C(5) */
|
||||
PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0),
|
||||
/* @GPIO(0,1,4,5): DFD_NTRST(6) */
|
||||
PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst),
|
||||
/* @GPIO(9,10): WM_AICE(2) */
|
||||
PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1),
|
||||
/* @GPIO(13): PWM0(2) */
|
||||
PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0),
|
||||
/* @GPIO(15): PWM0(1) */
|
||||
PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1),
|
||||
/* @GPIO(14): PWM1(2) */
|
||||
PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0),
|
||||
/* @GPIO(15): PWM1(3) */
|
||||
PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1),
|
||||
/* @GPIO(14) NET_WO0_UART_TXD(3) */
|
||||
PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1),
|
||||
/* @GPIO(15) NET_WO0_UART_TXD(4) */
|
||||
PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2),
|
||||
/* @GPIO(13) GBE_LED0(3) */
|
||||
PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1),
|
||||
/* @GPIO(9,13) PCM(4) */
|
||||
PINCTRL_PIN_GROUP("pcm", mt7981_pcm),
|
||||
/* @GPIO(13): SYS_WATCHDOG1(5) */
|
||||
PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1),
|
||||
/* @GPIO(9,13) UDI(4) */
|
||||
PINCTRL_PIN_GROUP("udi", mt7981_udi),
|
||||
/* @GPIO(14) DRV_VBUS(1) */
|
||||
PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus),
|
||||
/* @GPIO(15,25): EMMC(2) */
|
||||
PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45),
|
||||
/* @GPIO(16,21): SNFI(3) */
|
||||
PINCTRL_PIN_GROUP("snfi", mt7981_snfi),
|
||||
/* @GPIO(16,19): SPI0(1) */
|
||||
PINCTRL_PIN_GROUP("spi0", mt7981_spi0),
|
||||
/* @GPIO(20,21): SPI0(1) */
|
||||
PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold),
|
||||
/* @GPIO(22,25) SPI1(1) */
|
||||
PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1),
|
||||
/* @GPIO(26,29): SPI2(1) */
|
||||
PINCTRL_PIN_GROUP("spi2", mt7981_spi2),
|
||||
/* @GPIO(30,31): SPI0(1) */
|
||||
PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold),
|
||||
/* @GPIO(16,19): UART1(4) */
|
||||
PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0),
|
||||
/* @GPIO(26,29): UART1(2) */
|
||||
PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1),
|
||||
/* @GPIO(22,25): UART1(3) */
|
||||
PINCTRL_PIN_GROUP("uart2_1", mt7981_uart2_1),
|
||||
/* @GPIO(22,24) PTA_EXT(4) */
|
||||
PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1),
|
||||
/* @GPIO(20,21): WM_UART(4) */
|
||||
PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1),
|
||||
/* @GPIO(30,31): WM_UART(3) */
|
||||
PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2),
|
||||
/* @GPIO(20,24) WM_JTAG(5) */
|
||||
PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1),
|
||||
/* @GPIO(25,29) WO0_JTAG(5) */
|
||||
PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1),
|
||||
/* @GPIO(28,29): WA_AICE(3) */
|
||||
PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3),
|
||||
/* @GPIO(30,31): WM_AICE(5) */
|
||||
PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2),
|
||||
/* @GPIO(30,31): I2C(4) */
|
||||
PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1),
|
||||
/* @GPIO(30,31): I2C(6) */
|
||||
PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c),
|
||||
/* @GPIO(32,33): I2C(1) */
|
||||
PINCTRL_PIN_GROUP("uart0", mt7981_uart0),
|
||||
/* @GPIO(32,33): I2C(2) */
|
||||
PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c),
|
||||
/* @GPIO(32,33): I2C(3) */
|
||||
PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c),
|
||||
/* @GPIO(32,33): I2C(5) */
|
||||
PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c),
|
||||
/* @GPIO(34): PCIE_CLK_REQ(2) */
|
||||
PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk),
|
||||
/* @GPIO(35): PCIE_WAKE_N(2) */
|
||||
PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake),
|
||||
/* @GPIO(36,37): I2C(2) */
|
||||
PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2),
|
||||
/* @GPIO(36,37): MDC_MDIO(1) */
|
||||
PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio),
|
||||
/* @GPIO(36,37): MDC_MDIO(3) */
|
||||
PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio),
|
||||
/* @GPIO(69,85): WF0_MODE1(1) */
|
||||
PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1),
|
||||
/* @GPIO(74,80): WF0_MODE3(3) */
|
||||
PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3),
|
||||
/* @GPIO(30): WF2G_LED(2) */
|
||||
PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0),
|
||||
/* @GPIO(34): WF2G_LED(1) */
|
||||
PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1),
|
||||
/* @GPIO(31): WF5G_LED(2) */
|
||||
PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0),
|
||||
/* @GPIO(35): WF5G_LED(1) */
|
||||
PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1),
|
||||
/* @GPIO(38): MT7531_INT(1) */
|
||||
PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int),
|
||||
/* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */
|
||||
PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel),
|
||||
};
|
||||
|
||||
/* Joint those groups owning the same capability in user point of view which
|
||||
* allows that people tend to use through the device tree.
|
||||
*/
|
||||
static const char *mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", "wm_aice1_1",
|
||||
"wa_aice3", "wm_aice1_2", };
|
||||
static const char *mt7981_uart_groups[] = { "wm_uart_0", "uart2_0",
|
||||
"net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2",
|
||||
"uart1_0", "uart1_1", "uart2_1", "wm_aurt_1", "wm_aurt_2", "uart0", };
|
||||
static const char *mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", };
|
||||
static const char *mt7981_wdt_groups[] = { "watchdog", "watchdog1", };
|
||||
static const char *mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", "pcie_wake", };
|
||||
static const char *mt7981_jtag_groups[] = { "jtag", "wm_jtag_0", "wo0_jtag_0",
|
||||
"wo0_jtag_1", "wm_jtag_1", };
|
||||
static const char *mt7981_led_groups[] = { "gbe_led0", "gbe_led1", "wf2g_led0",
|
||||
"wf2g_led1", "wf5g_led0", "wf5g_led1", };
|
||||
static const char *mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", };
|
||||
static const char *mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1",
|
||||
"pwm1_0", "pwm1_1", };
|
||||
static const char *mt7981_spi_groups[] = { "spi1_0", "spi0", "spi0_wp_hold", "spi1_1", "spi2",
|
||||
"spi2_wp_hold", };
|
||||
static const char *mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", "u2_phy_i2c",
|
||||
"sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c", "i2c0_2", };
|
||||
static const char *mt7981_pcm_groups[] = { "pcm", };
|
||||
static const char *mt7981_udi_groups[] = { "udi", };
|
||||
static const char *mt7981_usb_groups[] = { "drv_vbus", };
|
||||
static const char *mt7981_flash_groups[] = { "emmc_45", "snfi", };
|
||||
static const char *mt7981_ethernet_groups[] = { "smi_mdc_mdio", "gbe_ext_mdc_mdio",
|
||||
"wf0_mode1", "wf0_mode3", "mt7531_int", };
|
||||
static const char *mt7981_ant_groups[] = { "ant_sel", };
|
||||
|
||||
static const struct function_desc mt7981_functions[] = {
|
||||
{"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)},
|
||||
{"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)},
|
||||
{"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)},
|
||||
{"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)},
|
||||
{"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)},
|
||||
{"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)},
|
||||
{"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)},
|
||||
{"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)},
|
||||
{"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)},
|
||||
{"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)},
|
||||
{"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)},
|
||||
{"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)},
|
||||
{"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)},
|
||||
{"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)},
|
||||
{"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)},
|
||||
{"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)},
|
||||
{"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)},
|
||||
};
|
||||
|
||||
static const struct mtk_eint_hw mt7981_eint_hw = {
|
||||
.port_mask = 7,
|
||||
.ports = 7,
|
||||
.ap_num = ARRAY_SIZE(mt7981_pins),
|
||||
.db_cnt = 16,
|
||||
};
|
||||
|
||||
static const char * const mt7981_pinctrl_register_base_names[] = {
|
||||
"gpio", "iocfg_rt", "iocfg_rm", "iocfg_rb",
|
||||
"iocfg_lb", "iocfg_bl", "iocfg_tm", "iocfg_tl",
|
||||
};
|
||||
|
||||
static struct mtk_pin_soc mt7981_data = {
|
||||
.reg_cal = mt7981_reg_cals,
|
||||
.pins = mt7981_pins,
|
||||
.npins = ARRAY_SIZE(mt7981_pins),
|
||||
.grps = mt7981_groups,
|
||||
.ngrps = ARRAY_SIZE(mt7981_groups),
|
||||
.funcs = mt7981_functions,
|
||||
.nfuncs = ARRAY_SIZE(mt7981_functions),
|
||||
.eint_hw = &mt7981_eint_hw,
|
||||
.gpio_m = 0,
|
||||
.ies_present = false,
|
||||
.base_names = mt7981_pinctrl_register_base_names,
|
||||
.nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names),
|
||||
.bias_set_combo = mtk_pinconf_bias_set_combo,
|
||||
.bias_get_combo = mtk_pinconf_bias_get_combo,
|
||||
.drive_set = mtk_pinconf_drive_set_rev1,
|
||||
.drive_get = mtk_pinconf_drive_get_rev1,
|
||||
.adv_pull_get = mtk_pinconf_adv_pull_get,
|
||||
.adv_pull_set = mtk_pinconf_adv_pull_set,
|
||||
};
|
||||
|
||||
static const struct of_device_id mt7981_pinctrl_of_match[] = {
|
||||
{ .compatible = "mediatek,mt7981-pinctrl", },
|
||||
{}
|
||||
};
|
||||
|
||||
static int mt7981_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
return mtk_moore_pinctrl_probe(pdev, &mt7981_data);
|
||||
}
|
||||
|
||||
static struct platform_driver mt7981_pinctrl_driver = {
|
||||
.driver = {
|
||||
.name = "mt7981-pinctrl",
|
||||
.of_match_table = mt7981_pinctrl_of_match,
|
||||
},
|
||||
.probe = mt7981_pinctrl_probe,
|
||||
};
|
||||
|
||||
static int __init mt7981_pinctrl_init(void)
|
||||
{
|
||||
return platform_driver_register(&mt7981_pinctrl_driver);
|
||||
}
|
||||
arch_initcall(mt7981_pinctrl_init);
|
||||
@ -0,0 +1,215 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (c) 2021 MediaTek Inc.
|
||||
* Author: Wenzhen.Yu <wenzhen.yu@mediatek.com>
|
||||
* Author: Jianhui Zhao <zhaojh329@gmail.com>
|
||||
* Author: Daniel Golle <daniel@makrotopia.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT7981_H
|
||||
#define _DT_BINDINGS_CLK_MT7981_H
|
||||
|
||||
/* TOPCKGEN */
|
||||
#define CLK_TOP_CB_CKSQ_40M 0
|
||||
#define CLK_TOP_CB_M_416M 1
|
||||
#define CLK_TOP_CB_M_D2 2
|
||||
#define CLK_TOP_CB_M_D3 3
|
||||
#define CLK_TOP_M_D3_D2 4
|
||||
#define CLK_TOP_CB_M_D4 5
|
||||
#define CLK_TOP_CB_M_D8 6
|
||||
#define CLK_TOP_M_D8_D2 7
|
||||
#define CLK_TOP_CB_MM_720M 8
|
||||
#define CLK_TOP_CB_MM_D2 9
|
||||
#define CLK_TOP_CB_MM_D3 10
|
||||
#define CLK_TOP_CB_MM_D3_D5 11
|
||||
#define CLK_TOP_CB_MM_D4 12
|
||||
#define CLK_TOP_CB_MM_D6 13
|
||||
#define CLK_TOP_MM_D6_D2 14
|
||||
#define CLK_TOP_CB_MM_D8 15
|
||||
#define CLK_TOP_CB_APLL2_196M 16
|
||||
#define CLK_TOP_APLL2_D2 17
|
||||
#define CLK_TOP_APLL2_D4 18
|
||||
#define CLK_TOP_NET1_2500M 19
|
||||
#define CLK_TOP_CB_NET1_D4 20
|
||||
#define CLK_TOP_CB_NET1_D5 21
|
||||
#define CLK_TOP_NET1_D5_D2 22
|
||||
#define CLK_TOP_NET1_D5_D4 23
|
||||
#define CLK_TOP_CB_NET1_D8 24
|
||||
#define CLK_TOP_NET1_D8_D2 25
|
||||
#define CLK_TOP_NET1_D8_D4 26
|
||||
#define CLK_TOP_CB_NET2_800M 27
|
||||
#define CLK_TOP_CB_NET2_D2 28
|
||||
#define CLK_TOP_CB_NET2_D4 29
|
||||
#define CLK_TOP_NET2_D4_D2 30
|
||||
#define CLK_TOP_NET2_D4_D4 31
|
||||
#define CLK_TOP_CB_NET2_D6 32
|
||||
#define CLK_TOP_CB_WEDMCU_208M 33
|
||||
#define CLK_TOP_CB_SGM_325M 34
|
||||
#define CLK_TOP_CKSQ_40M_D2 35
|
||||
#define CLK_TOP_CB_RTC_32K 36
|
||||
#define CLK_TOP_CB_RTC_32P7K 37
|
||||
#define CLK_TOP_USB_TX250M 38
|
||||
#define CLK_TOP_FAUD 39
|
||||
#define CLK_TOP_NFI1X 40
|
||||
#define CLK_TOP_USB_EQ_RX250M 41
|
||||
#define CLK_TOP_USB_CDR_CK 42
|
||||
#define CLK_TOP_USB_LN0_CK 43
|
||||
#define CLK_TOP_SPINFI_BCK 44
|
||||
#define CLK_TOP_SPI 45
|
||||
#define CLK_TOP_SPIM_MST 46
|
||||
#define CLK_TOP_UART_BCK 47
|
||||
#define CLK_TOP_PWM_BCK 48
|
||||
#define CLK_TOP_I2C_BCK 49
|
||||
#define CLK_TOP_PEXTP_TL 50
|
||||
#define CLK_TOP_EMMC_208M 51
|
||||
#define CLK_TOP_EMMC_400M 52
|
||||
#define CLK_TOP_DRAMC_REF 53
|
||||
#define CLK_TOP_DRAMC_MD32 54
|
||||
#define CLK_TOP_SYSAXI 55
|
||||
#define CLK_TOP_SYSAPB 56
|
||||
#define CLK_TOP_ARM_DB_MAIN 57
|
||||
#define CLK_TOP_AP2CNN_HOST 58
|
||||
#define CLK_TOP_NETSYS 59
|
||||
#define CLK_TOP_NETSYS_500M 60
|
||||
#define CLK_TOP_NETSYS_WED_MCU 61
|
||||
#define CLK_TOP_NETSYS_2X 62
|
||||
#define CLK_TOP_SGM_325M 63
|
||||
#define CLK_TOP_SGM_REG 64
|
||||
#define CLK_TOP_F26M 65
|
||||
#define CLK_TOP_EIP97B 66
|
||||
#define CLK_TOP_USB3_PHY 67
|
||||
#define CLK_TOP_AUD 68
|
||||
#define CLK_TOP_A1SYS 69
|
||||
#define CLK_TOP_AUD_L 70
|
||||
#define CLK_TOP_A_TUNER 71
|
||||
#define CLK_TOP_U2U3_REF 72
|
||||
#define CLK_TOP_U2U3_SYS 73
|
||||
#define CLK_TOP_U2U3_XHCI 74
|
||||
#define CLK_TOP_USB_FRMCNT 75
|
||||
#define CLK_TOP_NFI1X_SEL 76
|
||||
#define CLK_TOP_SPINFI_SEL 77
|
||||
#define CLK_TOP_SPI_SEL 78
|
||||
#define CLK_TOP_SPIM_MST_SEL 79
|
||||
#define CLK_TOP_UART_SEL 80
|
||||
#define CLK_TOP_PWM_SEL 81
|
||||
#define CLK_TOP_I2C_SEL 82
|
||||
#define CLK_TOP_PEXTP_TL_SEL 83
|
||||
#define CLK_TOP_EMMC_208M_SEL 84
|
||||
#define CLK_TOP_EMMC_400M_SEL 85
|
||||
#define CLK_TOP_F26M_SEL 86
|
||||
#define CLK_TOP_DRAMC_SEL 87
|
||||
#define CLK_TOP_DRAMC_MD32_SEL 88
|
||||
#define CLK_TOP_SYSAXI_SEL 89
|
||||
#define CLK_TOP_SYSAPB_SEL 90
|
||||
#define CLK_TOP_ARM_DB_MAIN_SEL 91
|
||||
#define CLK_TOP_AP2CNN_HOST_SEL 92
|
||||
#define CLK_TOP_NETSYS_SEL 93
|
||||
#define CLK_TOP_NETSYS_500M_SEL 94
|
||||
#define CLK_TOP_NETSYS_MCU_SEL 95
|
||||
#define CLK_TOP_NETSYS_2X_SEL 96
|
||||
#define CLK_TOP_SGM_325M_SEL 97
|
||||
#define CLK_TOP_SGM_REG_SEL 98
|
||||
#define CLK_TOP_EIP97B_SEL 99
|
||||
#define CLK_TOP_USB3_PHY_SEL 100
|
||||
#define CLK_TOP_AUD_SEL 101
|
||||
#define CLK_TOP_A1SYS_SEL 102
|
||||
#define CLK_TOP_AUD_L_SEL 103
|
||||
#define CLK_TOP_A_TUNER_SEL 104
|
||||
#define CLK_TOP_U2U3_SEL 105
|
||||
#define CLK_TOP_U2U3_SYS_SEL 106
|
||||
#define CLK_TOP_U2U3_XHCI_SEL 107
|
||||
#define CLK_TOP_USB_FRMCNT_SEL 108
|
||||
#define CLK_TOP_AUD_I2S_M 109
|
||||
|
||||
/* INFRACFG */
|
||||
#define CLK_INFRA_66M_MCK 0
|
||||
#define CLK_INFRA_UART0_SEL 1
|
||||
#define CLK_INFRA_UART1_SEL 2
|
||||
#define CLK_INFRA_UART2_SEL 3
|
||||
#define CLK_INFRA_SPI0_SEL 4
|
||||
#define CLK_INFRA_SPI1_SEL 5
|
||||
#define CLK_INFRA_SPI2_SEL 6
|
||||
#define CLK_INFRA_PWM1_SEL 7
|
||||
#define CLK_INFRA_PWM2_SEL 8
|
||||
#define CLK_INFRA_PWM3_SEL 9
|
||||
#define CLK_INFRA_PWM_BSEL 10
|
||||
#define CLK_INFRA_PCIE_SEL 11
|
||||
#define CLK_INFRA_GPT_STA 12
|
||||
#define CLK_INFRA_PWM_HCK 13
|
||||
#define CLK_INFRA_PWM_STA 14
|
||||
#define CLK_INFRA_PWM1_CK 15
|
||||
#define CLK_INFRA_PWM2_CK 16
|
||||
#define CLK_INFRA_PWM3_CK 17
|
||||
#define CLK_INFRA_CQ_DMA_CK 18
|
||||
#define CLK_INFRA_AUD_BUS_CK 19
|
||||
#define CLK_INFRA_AUD_26M_CK 20
|
||||
#define CLK_INFRA_AUD_L_CK 21
|
||||
#define CLK_INFRA_AUD_AUD_CK 22
|
||||
#define CLK_INFRA_AUD_EG2_CK 23
|
||||
#define CLK_INFRA_DRAMC_26M_CK 24
|
||||
#define CLK_INFRA_DBG_CK 25
|
||||
#define CLK_INFRA_AP_DMA_CK 26
|
||||
#define CLK_INFRA_SEJ_CK 27
|
||||
#define CLK_INFRA_SEJ_13M_CK 28
|
||||
#define CLK_INFRA_THERM_CK 29
|
||||
#define CLK_INFRA_I2C0_CK 30
|
||||
#define CLK_INFRA_UART0_CK 31
|
||||
#define CLK_INFRA_UART1_CK 32
|
||||
#define CLK_INFRA_UART2_CK 33
|
||||
#define CLK_INFRA_SPI2_CK 34
|
||||
#define CLK_INFRA_SPI2_HCK_CK 35
|
||||
#define CLK_INFRA_NFI1_CK 36
|
||||
#define CLK_INFRA_SPINFI1_CK 37
|
||||
#define CLK_INFRA_NFI_HCK_CK 38
|
||||
#define CLK_INFRA_SPI0_CK 39
|
||||
#define CLK_INFRA_SPI1_CK 40
|
||||
#define CLK_INFRA_SPI0_HCK_CK 41
|
||||
#define CLK_INFRA_SPI1_HCK_CK 42
|
||||
#define CLK_INFRA_FRTC_CK 43
|
||||
#define CLK_INFRA_MSDC_CK 44
|
||||
#define CLK_INFRA_MSDC_HCK_CK 45
|
||||
#define CLK_INFRA_MSDC_133M_CK 46
|
||||
#define CLK_INFRA_MSDC_66M_CK 47
|
||||
#define CLK_INFRA_ADC_26M_CK 48
|
||||
#define CLK_INFRA_ADC_FRC_CK 49
|
||||
#define CLK_INFRA_FBIST2FPC_CK 50
|
||||
#define CLK_INFRA_I2C_MCK_CK 51
|
||||
#define CLK_INFRA_I2C_PCK_CK 52
|
||||
#define CLK_INFRA_IUSB_133_CK 53
|
||||
#define CLK_INFRA_IUSB_66M_CK 54
|
||||
#define CLK_INFRA_IUSB_SYS_CK 55
|
||||
#define CLK_INFRA_IUSB_CK 56
|
||||
#define CLK_INFRA_IPCIE_CK 57
|
||||
#define CLK_INFRA_IPCIE_PIPE_CK 58
|
||||
#define CLK_INFRA_IPCIER_CK 59
|
||||
#define CLK_INFRA_IPCIEB_CK 60
|
||||
|
||||
/* APMIXEDSYS */
|
||||
#define CLK_APMIXED_ARMPLL 0
|
||||
#define CLK_APMIXED_NET2PLL 1
|
||||
#define CLK_APMIXED_MMPLL 2
|
||||
#define CLK_APMIXED_SGMPLL 3
|
||||
#define CLK_APMIXED_WEDMCUPLL 4
|
||||
#define CLK_APMIXED_NET1PLL 5
|
||||
#define CLK_APMIXED_MPLL 6
|
||||
#define CLK_APMIXED_APLL2 7
|
||||
|
||||
/* SGMIISYS_0 */
|
||||
#define CLK_SGM0_TX_EN 0
|
||||
#define CLK_SGM0_RX_EN 1
|
||||
#define CLK_SGM0_CK0_EN 2
|
||||
#define CLK_SGM0_CDR_CK0_EN 3
|
||||
|
||||
/* SGMIISYS_1 */
|
||||
#define CLK_SGM1_TX_EN 0
|
||||
#define CLK_SGM1_RX_EN 1
|
||||
#define CLK_SGM1_CK1_EN 2
|
||||
#define CLK_SGM1_CDR_CK1_EN 3
|
||||
|
||||
/* ETHSYS */
|
||||
#define CLK_ETH_FE_EN 0
|
||||
#define CLK_ETH_GP2_EN 1
|
||||
#define CLK_ETH_GP1_EN 2
|
||||
#define CLK_ETH_WOCPU0_EN 3
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT7981_H */
|
||||
@ -57,6 +57,8 @@ CONFIG_COMMON_CLK_MEDIATEK=y
|
||||
# CONFIG_COMMON_CLK_MT6779 is not set
|
||||
# CONFIG_COMMON_CLK_MT6797 is not set
|
||||
# CONFIG_COMMON_CLK_MT7622 is not set
|
||||
CONFIG_COMMON_CLK_MT7981=y
|
||||
CONFIG_COMMON_CLK_MT7981_ETHSYS=y
|
||||
CONFIG_COMMON_CLK_MT7986=y
|
||||
CONFIG_COMMON_CLK_MT7986_ETHSYS=y
|
||||
# CONFIG_COMMON_CLK_MT8173 is not set
|
||||
@ -205,6 +207,7 @@ CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
CONFIG_MEDIATEK_GE_PHY_SOC=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
|
||||
@ -307,6 +310,7 @@ CONFIG_PINCTRL=y
|
||||
# CONFIG_PINCTRL_MT6765 is not set
|
||||
# CONFIG_PINCTRL_MT6797 is not set
|
||||
# CONFIG_PINCTRL_MT7622 is not set
|
||||
CONFIG_PINCTRL_MT7981=y
|
||||
CONFIG_PINCTRL_MT7986=y
|
||||
# CONFIG_PINCTRL_MT8173 is not set
|
||||
# CONFIG_PINCTRL_MT8183 is not set
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
ARCH:=aarch64
|
||||
SUBTARGET:=filogic
|
||||
BOARDNAME:=Filogic 830 (MT7986)
|
||||
BOARDNAME:=Filogic 8x0 (MT798x)
|
||||
CPU_TYPE:=cortex-a53
|
||||
DEFAULT_PACKAGES += kmod-crypto-hw-safexcel kmod-mt7915e kmod-mt7986-firmware wpad-basic-openssl uboot-envtools mt7986-wo-firmware
|
||||
DEFAULT_PACKAGES += kmod-crypto-hw-safexcel kmod-mt7915e wpad-basic-openssl uboot-envtools
|
||||
KERNELNAME:=Image dtbs
|
||||
|
||||
define Target/Description
|
||||
|
||||
@ -63,7 +63,7 @@ define Device/bananapi_bpi-r3
|
||||
DEVICE_DTS_CONFIG := config-mt7986a-bananapi-bpi-r3
|
||||
DEVICE_DTS_OVERLAY:= mt7986a-bananapi-bpi-r3-nor mt7986a-bananapi-bpi-r3-emmc-nor mt7986a-bananapi-bpi-r3-emmc-snand mt7986a-bananapi-bpi-r3-snand
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
DEVICE_PACKAGES := kmod-hwmon-pwmfan kmod-i2c-gpio kmod-sfp kmod-usb3 e2fsprogs f2fsck mkf2fs
|
||||
DEVICE_PACKAGES := kmod-hwmon-pwmfan kmod-i2c-gpio kmod-mt7986-firmware kmod-sfp kmod-usb3 e2fsprogs f2fsck mkf2fs mt7986-wo-firmware
|
||||
IMAGES := sysupgrade.itb
|
||||
KERNEL_INITRAMFS_SUFFIX := -recovery.itb
|
||||
ARTIFACTS := \
|
||||
@ -107,6 +107,7 @@ define Device/mediatek_mt7986a-rfb-nand
|
||||
DEVICE_MODEL := MT7986 rfba AP (NAND)
|
||||
DEVICE_DTS := mt7986a-rfb-spim-nand
|
||||
DEVICE_DTS_DIR := $(DTS_DIR)/
|
||||
DEVICE_PACKAGES := kmod-mt7986-firmware mt7986-wo-firmware
|
||||
KERNEL_LOADADDR := 0x48000000
|
||||
SUPPORTED_DEVICES := mediatek,mt7986a-rfb-snand
|
||||
UBINIZE_OPTS := -E 5
|
||||
@ -130,6 +131,7 @@ define Device/mediatek_mt7986b-rfb
|
||||
DEVICE_MODEL := MTK7986 rfbb AP
|
||||
DEVICE_DTS := mt7986b-rfb
|
||||
DEVICE_DTS_DIR := $(DTS_DIR)/
|
||||
DEVICE_PACKAGES := kmod-mt7986-firmware mt7986-wo-firmware
|
||||
KERNEL_LOADADDR := 0x48000000
|
||||
SUPPORTED_DEVICES := mediatek,mt7986b-rfb
|
||||
UBINIZE_OPTS := -E 5
|
||||
@ -163,7 +165,7 @@ define Device/xiaomi_redmi-router-ax6000-stock
|
||||
DEVICE_MODEL := Redmi Router AX6000 (stock layout)
|
||||
DEVICE_DTS := mt7986a-xiaomi-redmi-router-ax6000-stock
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
DEVICE_PACKAGES := kmod-leds-ws2812b
|
||||
DEVICE_PACKAGES := kmod-leds-ws2812b kmod-mt7986-firmware mt7986-wo-firmware
|
||||
KERNEL_LOADADDR := 0x48000000
|
||||
UBINIZE_OPTS := -E 5
|
||||
BLOCKSIZE := 128k
|
||||
@ -181,7 +183,7 @@ define Device/xiaomi_redmi-router-ax6000-ubootmod
|
||||
DEVICE_MODEL := Redmi Router AX6000 (OpenWrt U-Boot layout)
|
||||
DEVICE_DTS := mt7986a-xiaomi-redmi-router-ax6000-ubootmod
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
DEVICE_PACKAGES := kmod-leds-ws2812b
|
||||
DEVICE_PACKAGES := kmod-leds-ws2812b kmod-mt7986-firmware mt7986-wo-firmware
|
||||
KERNEL_INITRAMFS_SUFFIX := -recovery.itb
|
||||
IMAGES := sysupgrade.itb
|
||||
KERNEL_LOADADDR := 0x48000000
|
||||
|
||||
@ -71,6 +71,7 @@ CONFIG_COMMON_CLK_MT7622=y
|
||||
CONFIG_COMMON_CLK_MT7622_AUDSYS=y
|
||||
CONFIG_COMMON_CLK_MT7622_ETHSYS=y
|
||||
CONFIG_COMMON_CLK_MT7622_HIFSYS=y
|
||||
# CONFIG_COMMON_CLK_MT7981 is not set
|
||||
# CONFIG_COMMON_CLK_MT7986 is not set
|
||||
# CONFIG_COMMON_CLK_MT8173 is not set
|
||||
# CONFIG_COMMON_CLK_MT8183 is not set
|
||||
@ -232,6 +233,7 @@ CONFIG_MDIO_BUS=y
|
||||
CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
# CONFIG_MEDIATEK_GE_PHY_SOC is not set
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
|
||||
@ -333,6 +335,7 @@ CONFIG_PINCTRL=y
|
||||
# CONFIG_PINCTRL_MT6765 is not set
|
||||
# CONFIG_PINCTRL_MT6797 is not set
|
||||
CONFIG_PINCTRL_MT7622=y
|
||||
# CONFIG_PINCTRL_MT7981 is not set
|
||||
# CONFIG_PINCTRL_MT7986 is not set
|
||||
# CONFIG_PINCTRL_MT8173 is not set
|
||||
# CONFIG_PINCTRL_MT8183 is not set
|
||||
|
||||
@ -68,6 +68,7 @@ CONFIG_COMMON_CLK_MT2701_MMSYS=y
|
||||
CONFIG_COMMON_CLK_MT2701_VDECSYS=y
|
||||
# CONFIG_COMMON_CLK_MT7622 is not set
|
||||
# CONFIG_COMMON_CLK_MT7629 is not set
|
||||
# CONFIG_COMMON_CLK_MT7981 is not set
|
||||
# CONFIG_COMMON_CLK_MT7986 is not set
|
||||
# CONFIG_COMMON_CLK_MT8135 is not set
|
||||
# CONFIG_COMMON_CLK_MT8173 is not set
|
||||
@ -321,6 +322,7 @@ CONFIG_MDIO_DEVICE=y
|
||||
CONFIG_MDIO_DEVRES=y
|
||||
CONFIG_MDIO_GPIO=y
|
||||
CONFIG_MEDIATEK_GE_PHY=y
|
||||
# CONFIG_MEDIATEK_GE_PHY_SOC is not set
|
||||
CONFIG_MEDIATEK_MT6577_AUXADC=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
|
||||
@ -52,6 +52,7 @@ CONFIG_COMMON_CLK_MEDIATEK=y
|
||||
CONFIG_COMMON_CLK_MT7629=y
|
||||
CONFIG_COMMON_CLK_MT7629_ETHSYS=y
|
||||
CONFIG_COMMON_CLK_MT7629_HIFSYS=y
|
||||
# CONFIG_COMMON_CLK_MT7981 is not set
|
||||
# CONFIG_COMMON_CLK_MT7986 is not set
|
||||
# CONFIG_COMMON_CLK_MT8135 is not set
|
||||
# CONFIG_COMMON_CLK_MT8173 is not set
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
--- a/drivers/clk/mediatek/Kconfig
|
||||
+++ b/drivers/clk/mediatek/Kconfig
|
||||
@@ -344,6 +344,23 @@ config COMMON_CLK_MT7629_HIFSYS
|
||||
This driver supports MediaTek MT7629 HIFSYS clocks providing
|
||||
to PCI-E and USB.
|
||||
|
||||
+config COMMON_CLK_MT7981
|
||||
+ bool "Clock driver for MediaTek MT7981"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ select COMMON_CLK_MEDIATEK
|
||||
+ default ARCH_MEDIATEK
|
||||
+ help
|
||||
+ This driver supports MediaTek MT7981 basic clocks and clocks
|
||||
+ required for various periperals found on MediaTek.
|
||||
+
|
||||
+config COMMON_CLK_MT7981_ETHSYS
|
||||
+ bool "Clock driver for MediaTek MT7981 ETHSYS"
|
||||
+ depends on COMMON_CLK_MT7981
|
||||
+ default COMMON_CLK_MT7981
|
||||
+ help
|
||||
+ This driver add support for clocks for Ethernet and SGMII
|
||||
+ required on MediaTek MT7981 SoC.
|
||||
+
|
||||
config COMMON_CLK_MT7986
|
||||
bool "Clock driver for MediaTek MT7986"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
--- a/drivers/clk/mediatek/Makefile
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -46,6 +46,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) +
|
||||
obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-apmixed.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-topckgen.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-infracfg.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MT7981_ETHSYS) += clk-mt7981-eth.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
|
||||
@ -0,0 +1,26 @@
|
||||
--- a/drivers/pinctrl/mediatek/Kconfig
|
||||
+++ b/drivers/pinctrl/mediatek/Kconfig
|
||||
@@ -120,6 +120,13 @@ config PINCTRL_MT7622
|
||||
default ARM64 && ARCH_MEDIATEK
|
||||
select PINCTRL_MTK_MOORE
|
||||
|
||||
+config PINCTRL_MT7981
|
||||
+ bool "Mediatek MT7981 pin control"
|
||||
+ depends on OF
|
||||
+ depends on ARM64 || COMPILE_TEST
|
||||
+ default ARM64 && ARCH_MEDIATEK
|
||||
+ select PINCTRL_MTK_MOORE
|
||||
+
|
||||
config PINCTRL_MT7986
|
||||
bool "Mediatek MT7986 pin control"
|
||||
depends on OF
|
||||
--- a/drivers/pinctrl/mediatek/Makefile
|
||||
+++ b/drivers/pinctrl/mediatek/Makefile
|
||||
@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-
|
||||
obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
|
||||
obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
|
||||
obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
|
||||
+obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7981.o
|
||||
obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
|
||||
obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o
|
||||
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
|
||||
@ -0,0 +1,130 @@
|
||||
From bfd3acc428085742d754a6d328d1a93ebf9451df Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Thu, 23 Jun 2022 18:29:51 +0800
|
||||
Subject: [PATCH 1/6] drivers: spi-mt65xx: Move chip_config to driver's private
|
||||
data
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/spi/spi-mt65xx.c | 29 +++++++++---------------
|
||||
include/linux/platform_data/spi-mt65xx.h | 17 --------------
|
||||
2 files changed, 11 insertions(+), 35 deletions(-)
|
||||
delete mode 100644 include/linux/platform_data/spi-mt65xx.h
|
||||
|
||||
--- a/drivers/spi/spi-mt65xx.c
|
||||
+++ b/drivers/spi/spi-mt65xx.c
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
-#include <linux/platform_data/spi-mt65xx.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi-mem.h>
|
||||
@@ -142,6 +141,8 @@ struct mtk_spi {
|
||||
struct device *dev;
|
||||
dma_addr_t tx_dma;
|
||||
dma_addr_t rx_dma;
|
||||
+ u32 sample_sel;
|
||||
+ u32 get_tick_dly;
|
||||
};
|
||||
|
||||
static const struct mtk_spi_compatible mtk_common_compat;
|
||||
@@ -187,15 +188,6 @@ static const struct mtk_spi_compatible m
|
||||
.no_need_unprepare = true,
|
||||
};
|
||||
|
||||
-/*
|
||||
- * A piece of default chip info unless the platform
|
||||
- * supplies it.
|
||||
- */
|
||||
-static const struct mtk_chip_config mtk_default_chip_info = {
|
||||
- .sample_sel = 0,
|
||||
- .tick_delay = 0,
|
||||
-};
|
||||
-
|
||||
static const struct of_device_id mtk_spi_of_match[] = {
|
||||
{ .compatible = "mediatek,spi-ipm",
|
||||
.data = (void *)&mtk_ipm_compat,
|
||||
@@ -323,7 +315,6 @@ static int mtk_spi_hw_init(struct spi_ma
|
||||
{
|
||||
u16 cpha, cpol;
|
||||
u32 reg_val;
|
||||
- struct mtk_chip_config *chip_config = spi->controller_data;
|
||||
struct mtk_spi *mdata = spi_master_get_devdata(master);
|
||||
|
||||
cpha = spi->mode & SPI_CPHA ? 1 : 0;
|
||||
@@ -373,7 +364,7 @@ static int mtk_spi_hw_init(struct spi_ma
|
||||
else
|
||||
reg_val &= ~SPI_CMD_CS_POL;
|
||||
|
||||
- if (chip_config->sample_sel)
|
||||
+ if (mdata->sample_sel)
|
||||
reg_val |= SPI_CMD_SAMPLE_SEL;
|
||||
else
|
||||
reg_val &= ~SPI_CMD_SAMPLE_SEL;
|
||||
@@ -400,20 +391,20 @@ static int mtk_spi_hw_init(struct spi_ma
|
||||
if (mdata->dev_comp->ipm_design) {
|
||||
reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK;
|
||||
- reg_val |= ((chip_config->tick_delay & 0x7)
|
||||
+ reg_val |= ((mdata->get_tick_dly & 0x7)
|
||||
<< SPI_CMD_IPM_GET_TICKDLY_OFFSET);
|
||||
writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
} else {
|
||||
reg_val = readl(mdata->base + SPI_CFG1_REG);
|
||||
reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK;
|
||||
- reg_val |= ((chip_config->tick_delay & 0x7)
|
||||
+ reg_val |= ((mdata->get_tick_dly & 0x7)
|
||||
<< SPI_CFG1_GET_TICK_DLY_OFFSET);
|
||||
writel(reg_val, mdata->base + SPI_CFG1_REG);
|
||||
}
|
||||
} else {
|
||||
reg_val = readl(mdata->base + SPI_CFG1_REG);
|
||||
reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK_V1;
|
||||
- reg_val |= ((chip_config->tick_delay & 0x3)
|
||||
+ reg_val |= ((mdata->get_tick_dly & 0x3)
|
||||
<< SPI_CFG1_GET_TICK_DLY_OFFSET_V1);
|
||||
writel(reg_val, mdata->base + SPI_CFG1_REG);
|
||||
}
|
||||
@@ -700,9 +691,6 @@ static int mtk_spi_setup(struct spi_devi
|
||||
{
|
||||
struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
|
||||
|
||||
- if (!spi->controller_data)
|
||||
- spi->controller_data = (void *)&mtk_default_chip_info;
|
||||
-
|
||||
if (mdata->dev_comp->need_pad_sel && spi->cs_gpiod)
|
||||
/* CS de-asserted, gpiolib will handle inversion */
|
||||
gpiod_direction_output(spi->cs_gpiod, 0);
|
||||
@@ -1115,6 +1103,10 @@ static int mtk_spi_probe(struct platform
|
||||
mdata = spi_master_get_devdata(master);
|
||||
mdata->dev_comp = of_id->data;
|
||||
|
||||
+ /* Set device configs to default first. Calibrate it later. */
|
||||
+ mdata->sample_sel = 0;
|
||||
+ mdata->get_tick_dly = 2;
|
||||
+
|
||||
if (mdata->dev_comp->enhance_timing)
|
||||
master->mode_bits |= SPI_CS_HIGH;
|
||||
|
||||
--- a/include/linux/platform_data/spi-mt65xx.h
|
||||
+++ /dev/null
|
||||
@@ -1,17 +0,0 @@
|
||||
-/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
-/*
|
||||
- * MTK SPI bus driver definitions
|
||||
- *
|
||||
- * Copyright (c) 2015 MediaTek Inc.
|
||||
- * Author: Leilk Liu <leilk.liu@mediatek.com>
|
||||
- */
|
||||
-
|
||||
-#ifndef ____LINUX_PLATFORM_DATA_SPI_MTK_H
|
||||
-#define ____LINUX_PLATFORM_DATA_SPI_MTK_H
|
||||
-
|
||||
-/* Board specific platform_data */
|
||||
-struct mtk_chip_config {
|
||||
- u32 sample_sel;
|
||||
- u32 tick_delay;
|
||||
-};
|
||||
-#endif
|
||||
@ -0,0 +1,236 @@
|
||||
From 2ade0172154e50c8a2bfd8634c6eff943cffea29 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Thu, 23 Jun 2022 18:35:52 +0800
|
||||
Subject: [PATCH 2/6] drivers: spi: Add support for dynamic calibration
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/spi/spi.c | 137 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/spi/spi.h | 42 ++++++++++++
|
||||
2 files changed, 179 insertions(+)
|
||||
|
||||
--- a/drivers/spi/spi.c
|
||||
+++ b/drivers/spi/spi.c
|
||||
@@ -1234,6 +1234,70 @@ static int spi_transfer_wait(struct spi_
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int spi_do_calibration(struct spi_controller *ctlr, struct spi_device *spi,
|
||||
+ int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen), void *drv_priv)
|
||||
+{
|
||||
+ int datalen = ctlr->cal_rule->datalen;
|
||||
+ int addrlen = ctlr->cal_rule->addrlen;
|
||||
+ u8 *buf;
|
||||
+ int ret;
|
||||
+ int i;
|
||||
+ struct list_head *cal_head, *listptr;
|
||||
+ struct spi_cal_target *target;
|
||||
+
|
||||
+ /* Calculate calibration result */
|
||||
+ int hit_val, total_hit, origin;
|
||||
+ bool hit;
|
||||
+
|
||||
+ /* Make sure we can start calibration */
|
||||
+ if(!ctlr->cal_target || !ctlr->cal_rule || !ctlr->append_caldata)
|
||||
+ return 0;
|
||||
+
|
||||
+ buf = kzalloc(datalen * sizeof(u8), GFP_KERNEL);
|
||||
+ if(!buf)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = ctlr->append_caldata(ctlr);
|
||||
+ if (ret)
|
||||
+ goto cal_end;
|
||||
+
|
||||
+ cal_head = ctlr->cal_target;
|
||||
+ list_for_each(listptr, cal_head) {
|
||||
+ target = list_entry(listptr, struct spi_cal_target, list);
|
||||
+
|
||||
+ hit = false;
|
||||
+ hit_val = 0;
|
||||
+ total_hit = 0;
|
||||
+ origin = *target->cal_item;
|
||||
+
|
||||
+ for(i=target->cal_min; i<=target->cal_max; i+=target->step) {
|
||||
+ *target->cal_item = i;
|
||||
+ ret = (*cal_read)(drv_priv, ctlr->cal_rule->addr, addrlen, buf, datalen);
|
||||
+ if(ret)
|
||||
+ break;
|
||||
+ dev_dbg(&spi->dev, "controller cal item value: 0x%x\n", i);
|
||||
+ if(memcmp(ctlr->cal_rule->match_data, buf, datalen * sizeof(u8)) == 0) {
|
||||
+ hit = true;
|
||||
+ hit_val += i;
|
||||
+ total_hit++;
|
||||
+ dev_dbg(&spi->dev, "golden data matches data read!\n");
|
||||
+ }
|
||||
+ }
|
||||
+ if(hit) {
|
||||
+ *target->cal_item = DIV_ROUND_CLOSEST(hit_val, total_hit);
|
||||
+ dev_info(&spi->dev, "calibration result: 0x%x", *target->cal_item);
|
||||
+ } else {
|
||||
+ *target->cal_item = origin;
|
||||
+ dev_warn(&spi->dev, "calibration failed, fallback to default: 0x%x", origin);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+cal_end:
|
||||
+ kfree(buf);
|
||||
+ return ret? ret: 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(spi_do_calibration);
|
||||
+
|
||||
static void _spi_transfer_delay_ns(u32 ns)
|
||||
{
|
||||
if (!ns)
|
||||
@@ -2021,6 +2085,75 @@ void spi_flush_queue(struct spi_controll
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
+static inline void alloc_cal_data(struct list_head **cal_target,
|
||||
+ struct spi_cal_rule **cal_rule, bool enable)
|
||||
+{
|
||||
+ if(enable) {
|
||||
+ *cal_target = kmalloc(sizeof(struct list_head), GFP_KERNEL);
|
||||
+ INIT_LIST_HEAD(*cal_target);
|
||||
+ *cal_rule = kmalloc(sizeof(struct spi_cal_rule), GFP_KERNEL);
|
||||
+ } else {
|
||||
+ kfree(*cal_target);
|
||||
+ kfree(*cal_rule);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int of_spi_parse_cal_dt(struct spi_controller *ctlr, struct spi_device *spi,
|
||||
+ struct device_node *nc)
|
||||
+{
|
||||
+ u32 value;
|
||||
+ int rc;
|
||||
+ const char *cal_mode;
|
||||
+
|
||||
+ rc = of_property_read_bool(nc, "spi-cal-enable");
|
||||
+ if (rc)
|
||||
+ alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, true);
|
||||
+ else
|
||||
+ return 0;
|
||||
+
|
||||
+ rc = of_property_read_string(nc, "spi-cal-mode", &cal_mode);
|
||||
+ if(!rc) {
|
||||
+ if(strcmp("read-data", cal_mode) == 0){
|
||||
+ ctlr->cal_rule->mode = SPI_CAL_READ_DATA;
|
||||
+ } else if(strcmp("read-pp", cal_mode) == 0) {
|
||||
+ ctlr->cal_rule->mode = SPI_CAL_READ_PP;
|
||||
+ return 0;
|
||||
+ } else if(strcmp("read-sfdp", cal_mode) == 0){
|
||||
+ ctlr->cal_rule->mode = SPI_CAL_READ_SFDP;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ } else
|
||||
+ goto err;
|
||||
+
|
||||
+ ctlr->cal_rule->datalen = 0;
|
||||
+ rc = of_property_read_u32(nc, "spi-cal-datalen", &value);
|
||||
+ if(!rc && value > 0) {
|
||||
+ ctlr->cal_rule->datalen = value;
|
||||
+
|
||||
+ ctlr->cal_rule->match_data = kzalloc(value * sizeof(u8), GFP_KERNEL);
|
||||
+ rc = of_property_read_u8_array(nc, "spi-cal-data",
|
||||
+ ctlr->cal_rule->match_data, value);
|
||||
+ if(rc)
|
||||
+ kfree(ctlr->cal_rule->match_data);
|
||||
+ }
|
||||
+
|
||||
+ rc = of_property_read_u32(nc, "spi-cal-addrlen", &value);
|
||||
+ if(!rc && value > 0) {
|
||||
+ ctlr->cal_rule->addrlen = value;
|
||||
+
|
||||
+ ctlr->cal_rule->addr = kzalloc(value * sizeof(u32), GFP_KERNEL);
|
||||
+ rc = of_property_read_u32_array(nc, "spi-cal-addr",
|
||||
+ ctlr->cal_rule->addr, value);
|
||||
+ if(rc)
|
||||
+ kfree(ctlr->cal_rule->addr);
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+err:
|
||||
+ alloc_cal_data(&ctlr->cal_target, &ctlr->cal_rule, false);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
|
||||
struct device_node *nc)
|
||||
{
|
||||
@@ -2139,6 +2272,10 @@ of_register_spi_device(struct spi_contro
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
+ rc = of_spi_parse_cal_dt(ctlr, spi, nc);
|
||||
+ if (rc)
|
||||
+ goto err_out;
|
||||
+
|
||||
/* Store a pointer to the node in the device structure */
|
||||
of_node_get(nc);
|
||||
spi->dev.of_node = nc;
|
||||
--- a/include/linux/spi/spi.h
|
||||
+++ b/include/linux/spi/spi.h
|
||||
@@ -290,6 +290,40 @@ struct spi_driver {
|
||||
struct device_driver driver;
|
||||
};
|
||||
|
||||
+enum {
|
||||
+ SPI_CAL_READ_DATA = 0,
|
||||
+ SPI_CAL_READ_PP = 1, /* only for SPI-NAND */
|
||||
+ SPI_CAL_READ_SFDP = 2, /* only for SPI-NOR */
|
||||
+};
|
||||
+
|
||||
+struct nand_addr {
|
||||
+ unsigned int lun;
|
||||
+ unsigned int plane;
|
||||
+ unsigned int eraseblock;
|
||||
+ unsigned int page;
|
||||
+ unsigned int dataoffs;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * Read calibration rule from device dts node.
|
||||
+ * Once calibration result matches the rule, we regard is as success.
|
||||
+ */
|
||||
+struct spi_cal_rule {
|
||||
+ int datalen;
|
||||
+ u8 *match_data;
|
||||
+ int addrlen;
|
||||
+ u32 *addr;
|
||||
+ int mode;
|
||||
+};
|
||||
+
|
||||
+struct spi_cal_target {
|
||||
+ u32 *cal_item;
|
||||
+ int cal_min; /* min of cal_item */
|
||||
+ int cal_max; /* max of cal_item */
|
||||
+ int step; /* Increase/decrease cal_item */
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
static inline struct spi_driver *to_spi_driver(struct device_driver *drv)
|
||||
{
|
||||
return drv ? container_of(drv, struct spi_driver, driver) : NULL;
|
||||
@@ -665,6 +699,11 @@ struct spi_controller {
|
||||
void *dummy_rx;
|
||||
void *dummy_tx;
|
||||
|
||||
+ /* For calibration */
|
||||
+ int (*append_caldata)(struct spi_controller *ctlr);
|
||||
+ struct list_head *cal_target;
|
||||
+ struct spi_cal_rule *cal_rule;
|
||||
+
|
||||
int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
|
||||
|
||||
/*
|
||||
@@ -1477,6 +1516,9 @@ spi_register_board_info(struct spi_board
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
+extern int spi_do_calibration(struct spi_controller *ctlr,
|
||||
+ struct spi_device *spi, int (*cal_read)(void *, u32 *, int, u8 *, int), void *drv_priv);
|
||||
+
|
||||
/* If you're hotplugging an adapter with devices (parport, usb, etc)
|
||||
* use spi_new_device() to describe each device. You can also call
|
||||
* spi_unregister_device() to start making that device vanish, but
|
||||
@ -0,0 +1,41 @@
|
||||
From 06640a5da2973318c06e516da16a5b579622e7c5 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Thu, 23 Jun 2022 18:37:55 +0800
|
||||
Subject: [PATCH 3/6] drivers: spi-mem: Add spi calibration hook
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/spi/spi-mem.c | 8 ++++++++
|
||||
include/linux/spi/spi-mem.h | 4 ++++
|
||||
2 files changed, 12 insertions(+)
|
||||
|
||||
--- a/drivers/spi/spi-mem.c
|
||||
+++ b/drivers/spi/spi-mem.c
|
||||
@@ -410,6 +410,14 @@ int spi_mem_exec_op(struct spi_mem *mem,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_mem_exec_op);
|
||||
|
||||
+int spi_mem_do_calibration(struct spi_mem *mem,
|
||||
+ int (*cal_read)(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen),
|
||||
+ void *priv)
|
||||
+{
|
||||
+ return spi_do_calibration(mem->spi->controller, mem->spi, cal_read, priv);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(spi_mem_do_calibration);
|
||||
+
|
||||
/**
|
||||
* spi_mem_get_name() - Return the SPI mem device name to be used by the
|
||||
* upper layer if necessary
|
||||
--- a/include/linux/spi/spi-mem.h
|
||||
+++ b/include/linux/spi/spi-mem.h
|
||||
@@ -366,6 +366,10 @@ bool spi_mem_supports_op(struct spi_mem
|
||||
int spi_mem_exec_op(struct spi_mem *mem,
|
||||
const struct spi_mem_op *op);
|
||||
|
||||
+int spi_mem_do_calibration(struct spi_mem *mem,
|
||||
+ int (*cal_read)(void *, u32 *, int, u8 *, int),
|
||||
+ void *priv);
|
||||
+
|
||||
const char *spi_mem_get_name(struct spi_mem *mem);
|
||||
|
||||
struct spi_mem_dirmap_desc *
|
||||
@ -0,0 +1,43 @@
|
||||
From d278c7a0bf730318a7ccf8d0a8b434c813e23fd0 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Thu, 23 Jun 2022 18:39:03 +0800
|
||||
Subject: [PATCH 4/6] drivers: spi-mt65xx: Add controller's calibration
|
||||
paramter
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/spi/spi-mt65xx.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
--- a/drivers/spi/spi-mt65xx.c
|
||||
+++ b/drivers/spi/spi-mt65xx.c
|
||||
@@ -800,6 +800,21 @@ static irqreturn_t mtk_spi_interrupt(int
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static int mtk_spi_append_caldata(struct spi_controller *ctlr)
|
||||
+{
|
||||
+ struct spi_cal_target *cal_target = kmalloc(sizeof(*cal_target), GFP_KERNEL);
|
||||
+ struct mtk_spi *mdata = spi_master_get_devdata(ctlr);
|
||||
+
|
||||
+ cal_target->cal_item = &mdata->get_tick_dly;
|
||||
+ cal_target->cal_min = 0;
|
||||
+ cal_target->cal_max = 7;
|
||||
+ cal_target->step = 1;
|
||||
+
|
||||
+ list_add(&cal_target->list, ctlr->cal_target);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
|
||||
struct spi_mem_op *op)
|
||||
{
|
||||
@@ -1092,6 +1107,7 @@ static int mtk_spi_probe(struct platform
|
||||
master->setup = mtk_spi_setup;
|
||||
master->set_cs_timing = mtk_spi_set_hw_cs_timing;
|
||||
master->use_gpio_descriptors = true;
|
||||
+ master->append_caldata = mtk_spi_append_caldata;
|
||||
|
||||
of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node);
|
||||
if (!of_id) {
|
||||
@ -0,0 +1,81 @@
|
||||
From 7670ec4a14891a1a182b98a9c403ffbf6b49e4b1 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Thu, 23 Jun 2022 18:39:56 +0800
|
||||
Subject: [PATCH 5/6] drivers: mtd: spinand: Add calibration support for
|
||||
spinand
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/mtd/nand/spi/core.c | 54 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 54 insertions(+)
|
||||
|
||||
--- a/drivers/mtd/nand/spi/core.c
|
||||
+++ b/drivers/mtd/nand/spi/core.c
|
||||
@@ -967,6 +967,56 @@ static int spinand_manufacturer_match(st
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
+int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) {
|
||||
+ struct spinand_device *spinand = (struct spinand_device *)priv;
|
||||
+ struct device *dev = &spinand->spimem->spi->dev;
|
||||
+ struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen);
|
||||
+ struct nand_pos pos;
|
||||
+ struct nand_page_io_req req;
|
||||
+ u8 status;
|
||||
+ int ret;
|
||||
+
|
||||
+ if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) {
|
||||
+ dev_err(dev, "Must provide correct addr(length) for spinand calibration\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = spinand_reset_op(spinand);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* We should store our golden data in first target because
|
||||
+ * we can't switch target at this moment.
|
||||
+ */
|
||||
+ pos = (struct nand_pos){
|
||||
+ .target = 0,
|
||||
+ .lun = *addr,
|
||||
+ .plane = *(addr+1),
|
||||
+ .eraseblock = *(addr+2),
|
||||
+ .page = *(addr+3),
|
||||
+ };
|
||||
+
|
||||
+ req = (struct nand_page_io_req){
|
||||
+ .pos = pos,
|
||||
+ .dataoffs = *(addr+4),
|
||||
+ .datalen = readlen,
|
||||
+ .databuf.in = buf,
|
||||
+ .mode = MTD_OPS_AUTO_OOB,
|
||||
+ };
|
||||
+
|
||||
+ ret = spinand_load_page_op(spinand, &req);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = spinand_wait(spinand, &status);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = spi_mem_exec_op(spinand->spimem, &op);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int spinand_id_detect(struct spinand_device *spinand)
|
||||
{
|
||||
u8 *id = spinand->id.data;
|
||||
@@ -1217,6 +1267,10 @@ static int spinand_init(struct spinand_d
|
||||
if (!spinand->scratchbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
+ ret = spi_mem_do_calibration(spinand->spimem, spinand_cal_read, spinand);
|
||||
+ if (ret)
|
||||
+ dev_err(dev, "Failed to calibrate SPI-NAND (err = %d)\n", ret);
|
||||
+
|
||||
ret = spinand_detect(spinand);
|
||||
if (ret)
|
||||
goto err_free_bufs;
|
||||
@ -0,0 +1,57 @@
|
||||
From f3fe3b15eca7908eaac57f9b8387a5dbc45ec5b2 Mon Sep 17 00:00:00 2001
|
||||
From: "SkyLake.Huang" <skylake.huang@mediatek.com>
|
||||
Date: Thu, 23 Jun 2022 18:40:59 +0800
|
||||
Subject: [PATCH 6/6] drivers: mtd: spi-nor: Add calibration support for
|
||||
spi-nor
|
||||
|
||||
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
---
|
||||
drivers/mtd/nand/spi/core.c | 5 ++++-
|
||||
drivers/mtd/spi-nor/core.c | 15 +++++++++++++++
|
||||
2 files changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/mtd/nand/spi/core.c
|
||||
+++ b/drivers/mtd/nand/spi/core.c
|
||||
@@ -1008,7 +1008,10 @@ int spinand_cal_read(void *priv, u32 *ad
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = spinand_wait(spinand, &status);
|
||||
+ ret = spinand_wait(spinand,
|
||||
+ SPINAND_READ_INITIAL_DELAY_US,
|
||||
+ SPINAND_READ_POLL_DELAY_US,
|
||||
+ &status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
--- a/drivers/mtd/spi-nor/core.c
|
||||
+++ b/drivers/mtd/spi-nor/core.c
|
||||
@@ -3060,6 +3060,18 @@ static void spi_nor_debugfs_init(struct
|
||||
info->id_len, info->id);
|
||||
}
|
||||
|
||||
+static int spi_nor_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen)
|
||||
+{
|
||||
+ struct spi_nor *nor = (struct spi_nor *)priv;
|
||||
+
|
||||
+ nor->reg_proto = SNOR_PROTO_1_1_1;
|
||||
+ nor->read_proto = SNOR_PROTO_1_1_1;
|
||||
+ nor->read_opcode = SPINOR_OP_READ;
|
||||
+ nor->read_dummy = 0;
|
||||
+
|
||||
+ return nor->controller_ops->read(nor, *addr, readlen, buf);
|
||||
+}
|
||||
+
|
||||
static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
|
||||
const char *name)
|
||||
{
|
||||
@@ -3133,6 +3145,9 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
if (!nor->bouncebuf)
|
||||
return -ENOMEM;
|
||||
|
||||
+ if(nor->spimem)
|
||||
+ spi_mem_do_calibration(nor->spimem, spi_nor_cal_read, nor);
|
||||
+
|
||||
info = spi_nor_get_flash_info(nor, name);
|
||||
if (IS_ERR(info))
|
||||
return PTR_ERR(info);
|
||||
@ -20,7 +20,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -230,13 +230,35 @@ static int _mtk_mdio_write(struct mtk_et
|
||||
@@ -231,13 +231,35 @@ static int _mtk_mdio_write(struct mtk_et
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -63,7 +63,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
ret = mtk_mdio_busy_wait(eth);
|
||||
if (ret < 0)
|
||||
@@ -253,12 +275,33 @@ static int _mtk_mdio_read(struct mtk_eth
|
||||
@@ -254,12 +276,33 @@ static int _mtk_mdio_read(struct mtk_eth
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -103,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
ret = mtk_mdio_busy_wait(eth);
|
||||
if (ret < 0)
|
||||
@@ -727,6 +770,7 @@ static int mtk_mdio_init(struct mtk_eth
|
||||
@@ -730,6 +773,7 @@ static int mtk_mdio_init(struct mtk_eth
|
||||
eth->mii_bus->name = "mdio";
|
||||
eth->mii_bus->read = mtk_mdio_read;
|
||||
eth->mii_bus->write = mtk_mdio_write;
|
||||
@ -113,7 +113,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -369,9 +369,12 @@
|
||||
@@ -376,9 +376,12 @@
|
||||
#define PHY_IAC_ADDR_MASK GENMASK(24, 20)
|
||||
#define PHY_IAC_ADDR(x) FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
|
||||
#define PHY_IAC_CMD_MASK GENMASK(19, 18)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,166 @@
|
||||
--- a/drivers/net/phy/mxl-gpy.c
|
||||
+++ b/drivers/net/phy/mxl-gpy.c
|
||||
@@ -126,6 +126,12 @@ static int gpy_config_init(struct phy_de
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ /* Disable SGMII auto-negotiation */
|
||||
+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
|
||||
+ VSPEC1_SGMII_CTRL_ANEN, 0);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
return gpy_led_write(phydev);
|
||||
}
|
||||
|
||||
@@ -151,65 +157,6 @@ static int gpy_probe(struct phy_device *
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static bool gpy_sgmii_need_reaneg(struct phy_device *phydev)
|
||||
-{
|
||||
- int fw_ver, fw_type, fw_minor;
|
||||
- size_t i;
|
||||
-
|
||||
- fw_ver = phy_read(phydev, PHY_FWV);
|
||||
- if (fw_ver < 0)
|
||||
- return true;
|
||||
-
|
||||
- fw_type = FIELD_GET(PHY_FWV_TYPE_MASK, fw_ver);
|
||||
- fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_ver);
|
||||
-
|
||||
- for (i = 0; i < ARRAY_SIZE(ver_need_sgmii_reaneg); i++) {
|
||||
- if (fw_type != ver_need_sgmii_reaneg[i].type)
|
||||
- continue;
|
||||
- if (fw_minor < ver_need_sgmii_reaneg[i].minor)
|
||||
- return true;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-static bool gpy_2500basex_chk(struct phy_device *phydev)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = phy_read(phydev, PHY_MIISTAT);
|
||||
- if (ret < 0) {
|
||||
- phydev_err(phydev, "Error: MDIO register access failed: %d\n",
|
||||
- ret);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- if (!(ret & PHY_MIISTAT_LS) ||
|
||||
- FIELD_GET(PHY_MIISTAT_SPD_MASK, ret) != PHY_MIISTAT_SPD_2500)
|
||||
- return false;
|
||||
-
|
||||
- phydev->speed = SPEED_2500;
|
||||
- phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
- phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
|
||||
- VSPEC1_SGMII_CTRL_ANEN, 0);
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
-static bool gpy_sgmii_aneg_en(struct phy_device *phydev)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL);
|
||||
- if (ret < 0) {
|
||||
- phydev_err(phydev, "Error: MMD register access failed: %d\n",
|
||||
- ret);
|
||||
- return true;
|
||||
- }
|
||||
-
|
||||
- return (ret & VSPEC1_SGMII_CTRL_ANEN) ? true : false;
|
||||
-}
|
||||
-
|
||||
static int gpy_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
bool changed = false;
|
||||
@@ -248,53 +195,11 @@ static int gpy_config_aneg(struct phy_de
|
||||
phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
|
||||
return 0;
|
||||
|
||||
- /* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is
|
||||
- * disabled.
|
||||
- */
|
||||
- if (!gpy_sgmii_need_reaneg(phydev) || gpy_2500basex_chk(phydev) ||
|
||||
- !gpy_sgmii_aneg_en(phydev))
|
||||
- return 0;
|
||||
-
|
||||
- /* There is a design constraint in GPY2xx device where SGMII AN is
|
||||
- * only triggered when there is change of speed. If, PHY link
|
||||
- * partner`s speed is still same even after PHY TPI is down and up
|
||||
- * again, SGMII AN is not triggered and hence no new in-band message
|
||||
- * from GPY to MAC side SGMII.
|
||||
- * This could cause an issue during power up, when PHY is up prior to
|
||||
- * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII
|
||||
- * wouldn`t receive new in-band message from GPY with correct link
|
||||
- * status, speed and duplex info.
|
||||
- *
|
||||
- * 1) If PHY is already up and TPI link status is still down (such as
|
||||
- * hard reboot), TPI link status is polled for 4 seconds before
|
||||
- * retriggerring SGMII AN.
|
||||
- * 2) If PHY is already up and TPI link status is also up (such as soft
|
||||
- * reboot), polling of TPI link status is not needed and SGMII AN is
|
||||
- * immediately retriggered.
|
||||
- * 3) Other conditions such as PHY is down, speed change etc, skip
|
||||
- * retriggering SGMII AN. Note: in case of speed change, GPY FW will
|
||||
- * initiate SGMII AN.
|
||||
- */
|
||||
-
|
||||
- if (phydev->state != PHY_UP)
|
||||
- return 0;
|
||||
-
|
||||
- ret = phy_read_poll_timeout(phydev, MII_BMSR, ret, ret & BMSR_LSTATUS,
|
||||
- 20000, 4000000, false);
|
||||
- if (ret == -ETIMEDOUT)
|
||||
- return 0;
|
||||
- else if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- /* Trigger SGMII AN. */
|
||||
- return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
|
||||
- VSPEC1_SGMII_CTRL_ANRS, VSPEC1_SGMII_CTRL_ANRS);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void gpy_update_interface(struct phy_device *phydev)
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
/* Interface mode is fixed for USXGMII and integrated PHY */
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_USXGMII ||
|
||||
phydev->interface == PHY_INTERFACE_MODE_INTERNAL)
|
||||
@@ -306,29 +211,11 @@ static void gpy_update_interface(struct
|
||||
switch (phydev->speed) {
|
||||
case SPEED_2500:
|
||||
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
|
||||
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
|
||||
- VSPEC1_SGMII_CTRL_ANEN, 0);
|
||||
- if (ret < 0)
|
||||
- phydev_err(phydev,
|
||||
- "Error: Disable of SGMII ANEG failed: %d\n",
|
||||
- ret);
|
||||
break;
|
||||
case SPEED_1000:
|
||||
case SPEED_100:
|
||||
case SPEED_10:
|
||||
phydev->interface = PHY_INTERFACE_MODE_SGMII;
|
||||
- if (gpy_sgmii_aneg_en(phydev))
|
||||
- break;
|
||||
- /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed
|
||||
- * if ANEG is disabled (in 2500-BaseX mode).
|
||||
- */
|
||||
- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_SGMII_CTRL,
|
||||
- VSPEC1_SGMII_ANEN_ANRS,
|
||||
- VSPEC1_SGMII_ANEN_ANRS);
|
||||
- if (ret < 0)
|
||||
- phydev_err(phydev,
|
||||
- "Error: Enable of SGMII ANEG failed: %d\n",
|
||||
- ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
From bd4f7dae6a1f2fd65bb2112783c92ffe0839bc77 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 28 Feb 2023 23:53:56 +0000
|
||||
Subject: [PATCH] i2c: mediatek: add support for MT7981 SoC
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/i2c/busses/i2c-mt65xx.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
--- a/drivers/i2c/busses/i2c-mt65xx.c
|
||||
+++ b/drivers/i2c/busses/i2c-mt65xx.c
|
||||
@@ -202,6 +202,34 @@ static const u16 mt_i2c_regs_v2[] = {
|
||||
[OFFSET_DCM_EN] = 0xf88,
|
||||
};
|
||||
|
||||
+static const u16 mt_i2c_regs_v3[] = {
|
||||
+ [OFFSET_DATA_PORT] = 0x0,
|
||||
+ [OFFSET_INTR_MASK] = 0x8,
|
||||
+ [OFFSET_INTR_STAT] = 0xc,
|
||||
+ [OFFSET_CONTROL] = 0x10,
|
||||
+ [OFFSET_TRANSFER_LEN] = 0x14,
|
||||
+ [OFFSET_TRANSAC_LEN] = 0x18,
|
||||
+ [OFFSET_DELAY_LEN] = 0x1c,
|
||||
+ [OFFSET_TIMING] = 0x20,
|
||||
+ [OFFSET_START] = 0x24,
|
||||
+ [OFFSET_EXT_CONF] = 0x28,
|
||||
+ [OFFSET_LTIMING] = 0x2c,
|
||||
+ [OFFSET_HS] = 0x30,
|
||||
+ [OFFSET_IO_CONFIG] = 0x34,
|
||||
+ [OFFSET_FIFO_ADDR_CLR] = 0x38,
|
||||
+ [OFFSET_SDA_TIMING] = 0x3c,
|
||||
+ [OFFSET_TRANSFER_LEN_AUX] = 0x44,
|
||||
+ [OFFSET_CLOCK_DIV] = 0x48,
|
||||
+ [OFFSET_SOFTRESET] = 0x50,
|
||||
+ [OFFSET_SCL_MIS_COMP_POINT] = 0x90,
|
||||
+ [OFFSET_SLAVE_ADDR] = 0x94,
|
||||
+ [OFFSET_DEBUGSTAT] = 0xe4,
|
||||
+ [OFFSET_DEBUGCTRL] = 0xe8,
|
||||
+ [OFFSET_FIFO_STAT] = 0xf4,
|
||||
+ [OFFSET_FIFO_THRESH] = 0xf8,
|
||||
+ [OFFSET_DCM_EN] = 0xf88,
|
||||
+};
|
||||
+
|
||||
struct mtk_i2c_compatible {
|
||||
const struct i2c_adapter_quirks *quirks;
|
||||
const u16 *regs;
|
||||
@@ -365,6 +393,18 @@ static const struct mtk_i2c_compatible m
|
||||
.max_dma_support = 32,
|
||||
};
|
||||
|
||||
+static const struct mtk_i2c_compatible mt7981_compat = {
|
||||
+ .regs = mt_i2c_regs_v3,
|
||||
+ .pmic_i2c = 0,
|
||||
+ .dcm = 0,
|
||||
+ .auto_restart = 1,
|
||||
+ .aux_len_reg = 1,
|
||||
+ .timing_adjust = 1,
|
||||
+ .dma_sync = 1,
|
||||
+ .ltiming_adjust = 1,
|
||||
+ .max_dma_support = 33
|
||||
+};
|
||||
+
|
||||
static const struct mtk_i2c_compatible mt7986_compat = {
|
||||
.quirks = &mt7622_i2c_quirks,
|
||||
.regs = mt_i2c_regs_v1,
|
||||
@@ -424,6 +464,7 @@ static const struct of_device_id mtk_i2c
|
||||
{ .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
|
||||
{ .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
|
||||
{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
|
||||
+ { .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },
|
||||
{ .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
|
||||
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
|
||||
{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
|
||||
@ -0,0 +1,212 @@
|
||||
From 947b535ebfe161e1725f1030a09de10d1460371c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 23 Jan 2023 20:47:34 +0000
|
||||
Subject: [PATCH] pwm: mediatek: Add support for MT7981
|
||||
|
||||
The PWM unit on MT7981 uses different register offsets than previous
|
||||
MediaTek PWM units. Add support for these new offsets and add support
|
||||
for PWM on MT7981 which has 3 PWM channels, one of them is typically
|
||||
used for a temperature controlled fan.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/pwm/pwm-mediatek.c | 54 ++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 46 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/pwm/pwm-mediatek.c
|
||||
+++ b/drivers/pwm/pwm-mediatek.c
|
||||
@@ -34,10 +34,14 @@
|
||||
|
||||
#define PWM_CLK_DIV_MAX 7
|
||||
|
||||
+#define REG_V1 1
|
||||
+#define REG_V2 2
|
||||
+
|
||||
struct pwm_mediatek_of_data {
|
||||
unsigned int num_pwms;
|
||||
bool pwm45_fixup;
|
||||
bool has_ck_26m_sel;
|
||||
+ u8 reg_ver;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -59,10 +63,14 @@ struct pwm_mediatek_chip {
|
||||
const struct pwm_mediatek_of_data *soc;
|
||||
};
|
||||
|
||||
-static const unsigned int pwm_mediatek_reg_offset[] = {
|
||||
+static const unsigned int mtk_pwm_reg_offset_v1[] = {
|
||||
0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220
|
||||
};
|
||||
|
||||
+static const unsigned int mtk_pwm_reg_offset_v2[] = {
|
||||
+ 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x1c0, 0x200, 0x0240
|
||||
+};
|
||||
+
|
||||
static inline struct pwm_mediatek_chip *
|
||||
to_pwm_mediatek_chip(struct pwm_chip *chip)
|
||||
{
|
||||
@@ -111,7 +119,19 @@ static inline void pwm_mediatek_writel(s
|
||||
unsigned int num, unsigned int offset,
|
||||
u32 value)
|
||||
{
|
||||
- writel(value, chip->regs + pwm_mediatek_reg_offset[num] + offset);
|
||||
+ u32 pwm_offset;
|
||||
+
|
||||
+ switch (chip->soc->reg_ver) {
|
||||
+ case REG_V2:
|
||||
+ pwm_offset = mtk_pwm_reg_offset_v2[num];
|
||||
+ break;
|
||||
+
|
||||
+ case REG_V1:
|
||||
+ default:
|
||||
+ pwm_offset = mtk_pwm_reg_offset_v1[num];
|
||||
+ }
|
||||
+
|
||||
+ writel(value, chip->regs + pwm_offset + offset);
|
||||
}
|
||||
|
||||
static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
@@ -146,7 +166,7 @@ static int pwm_mediatek_config(struct pw
|
||||
|
||||
if (clkdiv > PWM_CLK_DIV_MAX) {
|
||||
pwm_mediatek_clk_disable(chip, pwm);
|
||||
- dev_err(chip->dev, "period %d not supported\n", period_ns);
|
||||
+ dev_err(chip->dev, "period of %d ns not supported\n", period_ns);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -221,24 +241,20 @@ static int pwm_mediatek_probe(struct pla
|
||||
if (IS_ERR(pc->regs))
|
||||
return PTR_ERR(pc->regs);
|
||||
|
||||
- pc->clk_pwms = devm_kcalloc(&pdev->dev, pc->soc->num_pwms,
|
||||
+ pc->clk_pwms = devm_kmalloc_array(&pdev->dev, pc->soc->num_pwms,
|
||||
sizeof(*pc->clk_pwms), GFP_KERNEL);
|
||||
if (!pc->clk_pwms)
|
||||
return -ENOMEM;
|
||||
|
||||
pc->clk_top = devm_clk_get(&pdev->dev, "top");
|
||||
- if (IS_ERR(pc->clk_top)) {
|
||||
- dev_err(&pdev->dev, "clock: top fail: %ld\n",
|
||||
- PTR_ERR(pc->clk_top));
|
||||
- return PTR_ERR(pc->clk_top);
|
||||
- }
|
||||
+ if (IS_ERR(pc->clk_top))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk_top),
|
||||
+ "Failed to get top clock\n");
|
||||
|
||||
pc->clk_main = devm_clk_get(&pdev->dev, "main");
|
||||
- if (IS_ERR(pc->clk_main)) {
|
||||
- dev_err(&pdev->dev, "clock: main fail: %ld\n",
|
||||
- PTR_ERR(pc->clk_main));
|
||||
- return PTR_ERR(pc->clk_main);
|
||||
- }
|
||||
+ if (IS_ERR(pc->clk_main))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk_main),
|
||||
+ "Failed to get main clock\n");
|
||||
|
||||
for (i = 0; i < pc->soc->num_pwms; i++) {
|
||||
char name[8];
|
||||
@@ -246,11 +262,9 @@ static int pwm_mediatek_probe(struct pla
|
||||
snprintf(name, sizeof(name), "pwm%d", i + 1);
|
||||
|
||||
pc->clk_pwms[i] = devm_clk_get(&pdev->dev, name);
|
||||
- if (IS_ERR(pc->clk_pwms[i])) {
|
||||
- dev_err(&pdev->dev, "clock: %s fail: %ld\n",
|
||||
- name, PTR_ERR(pc->clk_pwms[i]));
|
||||
- return PTR_ERR(pc->clk_pwms[i]);
|
||||
- }
|
||||
+ if (IS_ERR(pc->clk_pwms[i]))
|
||||
+ return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk_pwms[i]),
|
||||
+ "Failed to get %s clock\n", name);
|
||||
}
|
||||
|
||||
pc->chip.dev = &pdev->dev;
|
||||
@@ -258,10 +272,8 @@ static int pwm_mediatek_probe(struct pla
|
||||
pc->chip.npwm = pc->soc->num_pwms;
|
||||
|
||||
ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
|
||||
- if (ret < 0) {
|
||||
- dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
+ if (ret < 0)
|
||||
+ return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -270,48 +282,63 @@ static const struct pwm_mediatek_of_data
|
||||
.num_pwms = 8,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = false,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7622_pwm_data = {
|
||||
.num_pwms = 6,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = true,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7623_pwm_data = {
|
||||
.num_pwms = 5,
|
||||
.pwm45_fixup = true,
|
||||
.has_ck_26m_sel = false,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7628_pwm_data = {
|
||||
.num_pwms = 4,
|
||||
.pwm45_fixup = true,
|
||||
.has_ck_26m_sel = false,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7629_pwm_data = {
|
||||
.num_pwms = 1,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = false,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
-static const struct pwm_mediatek_of_data mt8183_pwm_data = {
|
||||
- .num_pwms = 4,
|
||||
+static const struct pwm_mediatek_of_data mt7981_pwm_data = {
|
||||
+ .num_pwms = 3,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = true,
|
||||
+ .reg_ver = REG_V2,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt7986_pwm_data = {
|
||||
.num_pwms = 2,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = true,
|
||||
+ .reg_ver = REG_V1,
|
||||
+};
|
||||
+
|
||||
+static const struct pwm_mediatek_of_data mt8183_pwm_data = {
|
||||
+ .num_pwms = 4,
|
||||
+ .pwm45_fixup = false,
|
||||
+ .has_ck_26m_sel = true,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
static const struct pwm_mediatek_of_data mt8516_pwm_data = {
|
||||
.num_pwms = 5,
|
||||
.pwm45_fixup = false,
|
||||
.has_ck_26m_sel = true,
|
||||
+ .reg_ver = REG_V1,
|
||||
};
|
||||
|
||||
static const struct of_device_id pwm_mediatek_of_match[] = {
|
||||
@@ -320,6 +347,7 @@ static const struct of_device_id pwm_med
|
||||
{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
|
||||
{ .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
|
||||
{ .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
|
||||
+ { .compatible = "mediatek,mt7981-pwm", .data = &mt7981_pwm_data },
|
||||
{ .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
|
||||
{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
|
||||
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/drivers/spi/spi-mt65xx.c
|
||||
+++ b/drivers/spi/spi-mt65xx.c
|
||||
@@ -1223,10 +1223,16 @@ static int mtk_spi_probe(struct platform
|
||||
@@ -1231,10 +1231,16 @@ static int mtk_spi_probe(struct platform
|
||||
goto err_disable_spi_hclk;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
mdata->spi_clk_hz = clk_get_rate(mdata->spi_clk);
|
||||
@@ -1277,6 +1283,8 @@ static int mtk_spi_probe(struct platform
|
||||
@@ -1285,6 +1291,8 @@ static int mtk_spi_probe(struct platform
|
||||
|
||||
err_disable_runtime_pm:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
@ -14,7 +14,7 @@ Signed-off-by: René van Dorst <opensource@vdorst.com>
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -4228,6 +4228,7 @@ static const struct net_device_ops mtk_n
|
||||
@@ -4259,6 +4259,7 @@ static const struct net_device_ops mtk_n
|
||||
|
||||
static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
|
||||
{
|
||||
@ -22,7 +22,7 @@ Signed-off-by: René van Dorst <opensource@vdorst.com>
|
||||
const __be32 *_id = of_get_property(np, "reg", NULL);
|
||||
phy_interface_t phy_mode;
|
||||
struct phylink *phylink;
|
||||
@@ -4356,6 +4357,9 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
@@ -4387,6 +4388,9 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
register_netdevice_notifier(&mac->device_notifier);
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
|
||||
phydev->mii_ts->link_state(phydev->mii_ts, phydev);
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -1323,7 +1323,8 @@ void phylink_destroy(struct phylink *pl)
|
||||
@@ -1322,7 +1322,8 @@ void phylink_destroy(struct phylink *pl)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phylink_destroy);
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -15891,6 +15891,13 @@ S: Maintained
|
||||
@@ -15899,6 +15899,13 @@ S: Maintained
|
||||
F: include/sound/rt*.h
|
||||
F: sound/soc/codecs/rt*
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ Submitted-by: John Crispin <john@phrozen.org>
|
||||
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -60,6 +60,8 @@ source "drivers/net/dsa/sja1105/Kconfig"
|
||||
@@ -61,6 +61,8 @@ source "drivers/net/dsa/sja1105/Kconfig"
|
||||
|
||||
source "drivers/net/dsa/xrs700x/Kconfig"
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ Submitted-by: John Crispin <john@phrozen.org>
|
||||
|
||||
--- a/drivers/net/phy/phylink.c
|
||||
+++ b/drivers/net/phy/phylink.c
|
||||
@@ -1943,6 +1943,11 @@ int phylink_ethtool_ksettings_set(struct
|
||||
@@ -1942,6 +1942,11 @@ int phylink_ethtool_ksettings_set(struct
|
||||
* the presence of a PHY, this should not be changed as that
|
||||
* should be determined from the media side advertisement.
|
||||
*/
|
||||
@ -33,7 +33,7 @@ Submitted-by: John Crispin <john@phrozen.org>
|
||||
return phy_ethtool_ksettings_set(pl->phydev, kset);
|
||||
}
|
||||
|
||||
@@ -2246,8 +2251,11 @@ int phylink_ethtool_get_eee(struct phyli
|
||||
@@ -2245,8 +2250,11 @@ int phylink_ethtool_get_eee(struct phyli
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@ -46,7 +46,7 @@ Submitted-by: John Crispin <john@phrozen.org>
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2264,8 +2272,11 @@ int phylink_ethtool_set_eee(struct phyli
|
||||
@@ -2263,8 +2271,11 @@ int phylink_ethtool_set_eee(struct phyli
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user