1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-02-12 19:31:52 +00:00

Add kernel 6.1 support for BPI-R64

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-05-17 20:06:36 +02:00
parent 91028220c3
commit 49e5717c77
73 changed files with 7015 additions and 10 deletions

View file

@ -0,0 +1,62 @@
From: Ryder Lee <ryder.lee@mediatek.com>
Date: Sat, 18 Feb 2023 01:49:25 +0800
Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf
This is utilized to pass LDPC configurations from user space
(i.e. hostapd) to driver.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery {
* write-protected by sdata_lock and local->mtx so holding either is fine
* for read access.
* @color_change_color: the bss color that will be used after the change.
+ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability.
+ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability.
+ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability.
* @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU
* beamformer
* @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU
@@ -744,6 +747,9 @@ struct ieee80211_bss_conf {
bool color_change_active;
u8 color_change_color;
+ bool ht_ldpc;
+ bool vht_ldpc;
+ bool he_ldpc;
bool vht_su_beamformer;
bool vht_su_beamformee;
bool vht_mu_beamformer;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip
prev_beacon_int = link_conf->beacon_int;
link_conf->beacon_int = params->beacon_interval;
+ if (params->ht_cap)
+ link_conf->ht_ldpc =
+ params->ht_cap->cap_info &
+ cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING);
+
if (params->vht_cap) {
+ link_conf->vht_ldpc =
+ params->vht_cap->vht_cap_info &
+ cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC);
link_conf->vht_su_beamformer =
params->vht_cap->vht_cap_info &
cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);
@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip
}
if (params->he_cap) {
+ link_conf->he_ldpc =
+ params->he_cap->phy_cap_info[1] &
+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
link_conf->he_su_beamformer =
params->he_cap->phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;

View file

@ -8,11 +8,9 @@ PKG_LICENSE_FILES:=
PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_URL:=https://github.com/openwrt/mt76
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
#PKG_SOURCE_DATE:=2023-03-01 PKG_SOURCE_DATE:=2023-05-13
#PKG_SOURCE_VERSION:=c32d6d849c43792abd8007e13e468b12d6d6e0b7 PKG_SOURCE_VERSION:=969b7b5ebd129068ca56e4b0d831593a2f92382f
PKG_SOURCE_DATE:=2023-02-02 PKG_MIRROR_HASH:=d28869591d1cb9a967b72f5cd8215c7b2c3388b7b31147b7b18c797018ab8ffb
PKG_SOURCE_VERSION:=4b229d2da5628bc10cbeb1047f3c888bb4d98271
#PKG_MIRROR_HASH:=b7004bc920ba44cef2f7868d94beb2d288ff9d399af624ce5dad972f953723c8
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name> PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_USE_NINJA:=0 PKG_USE_NINJA:=0
@ -247,6 +245,12 @@ define KernelPackage/mt7916-firmware
TITLE:=MediaTek MT7916 firmware TITLE:=MediaTek MT7916 firmware
endef endef
define KernelPackage/mt7981-firmware
$(KernelPackage/mt76-default)
DEPENDS:=@TARGET_mediatek_filogic
TITLE:=MediaTek MT7981 firmware
endef
define KernelPackage/mt7986-firmware define KernelPackage/mt7986-firmware
$(KernelPackage/mt76-default) $(KernelPackage/mt76-default)
DEPENDS:=@TARGET_mediatek_filogic DEPENDS:=@TARGET_mediatek_filogic
@ -258,6 +262,12 @@ define KernelPackage/mt7921-firmware
TITLE:=MediaTek MT7921 firmware TITLE:=MediaTek MT7921 firmware
endef endef
define KernelPackage/mt7922-firmware
$(KernelPackage/mt76-default)
DEPENDS+=+kmod-mt7921-common
TITLE:=MediaTek MT7922 firmware
endef
define KernelPackage/mt7921-common define KernelPackage/mt7921-common
$(KernelPackage/mt76-default) $(KernelPackage/mt76-default)
TITLE:=MediaTek MT7615 wireless driver common code TITLE:=MediaTek MT7615 wireless driver common code
@ -376,8 +386,8 @@ endif
ifdef CONFIG_PACKAGE_kmod-mt7915e ifdef CONFIG_PACKAGE_kmod-mt7915e
PKG_MAKE_FLAGS += CONFIG_MT7915E=m PKG_MAKE_FLAGS += CONFIG_MT7915E=m
ifdef CONFIG_TARGET_mediatek_filogic ifdef CONFIG_TARGET_mediatek_filogic
PKG_MAKE_FLAGS += CONFIG_MT7986_WMAC=y PKG_MAKE_FLAGS += CONFIG_MT798X_WMAC=y
NOSTDINC_FLAGS += -DCONFIG_MT7986_WMAC NOSTDINC_FLAGS += -DCONFIG_MT798X_WMAC
endif endif
endif endif
ifdef CONFIG_PACKAGE_kmod-mt7921-common ifdef CONFIG_PACKAGE_kmod-mt7921-common
@ -499,6 +509,15 @@ define KernelPackage/mt7916-firmware/install
$(1)/lib/firmware/mediatek $(1)/lib/firmware/mediatek
endef endef
define KernelPackage/mt7981-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/mediatek
cp \
$(PKG_BUILD_DIR)/firmware/mt7981_wa.bin \
$(PKG_BUILD_DIR)/firmware/mt7981_wm.bin \
$(PKG_BUILD_DIR)/firmware/mt7981_rom_patch.bin \
$(1)/lib/firmware/mediatek
endef
define KernelPackage/mt7986-firmware/install define KernelPackage/mt7986-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/mediatek $(INSTALL_DIR) $(1)/lib/firmware/mediatek
cp \ cp \
@ -507,8 +526,6 @@ define KernelPackage/mt7986-firmware/install
$(PKG_BUILD_DIR)/firmware/mt7986_wm.bin \ $(PKG_BUILD_DIR)/firmware/mt7986_wm.bin \
$(PKG_BUILD_DIR)/firmware/mt7986_rom_patch_mt7975.bin \ $(PKG_BUILD_DIR)/firmware/mt7986_rom_patch_mt7975.bin \
$(PKG_BUILD_DIR)/firmware/mt7986_rom_patch.bin \ $(PKG_BUILD_DIR)/firmware/mt7986_rom_patch.bin \
$(PKG_BUILD_DIR)/firmware/mt7986_eeprom_mt7975_dual.bin \
$(PKG_BUILD_DIR)/firmware/mt7986_eeprom_mt7976_dual.bin \
$(1)/lib/firmware/mediatek $(1)/lib/firmware/mediatek
endef endef
@ -520,6 +537,14 @@ define KernelPackage/mt7921-firmware/install
$(1)/lib/firmware/mediatek $(1)/lib/firmware/mediatek
endef endef
define KernelPackage/mt7922-firmware/install
$(INSTALL_DIR) $(1)/lib/firmware/mediatek
cp \
$(PKG_BUILD_DIR)/firmware/WIFI_MT7922_patch_mcu_1_1_hdr.bin \
$(PKG_BUILD_DIR)/firmware/WIFI_RAM_CODE_MT7922_1.bin \
$(1)/lib/firmware/mediatek
endef
define Package/mt76-test/install define Package/mt76-test/install
mkdir -p $(1)/usr/sbin mkdir -p $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/mt76-test $(1)/usr/sbin $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/mt76-test $(1)/usr/sbin
@ -550,8 +575,10 @@ $(eval $(call KernelPackage,mt7663s))
$(eval $(call KernelPackage,mt7915-firmware)) $(eval $(call KernelPackage,mt7915-firmware))
$(eval $(call KernelPackage,mt7915e)) $(eval $(call KernelPackage,mt7915e))
$(eval $(call KernelPackage,mt7916-firmware)) $(eval $(call KernelPackage,mt7916-firmware))
$(eval $(call KernelPackage,mt7981-firmware))
$(eval $(call KernelPackage,mt7986-firmware)) $(eval $(call KernelPackage,mt7986-firmware))
$(eval $(call KernelPackage,mt7921-firmware)) $(eval $(call KernelPackage,mt7921-firmware))
$(eval $(call KernelPackage,mt7922-firmware))
$(eval $(call KernelPackage,mt7921-common)) $(eval $(call KernelPackage,mt7921-common))
$(eval $(call KernelPackage,mt7921u)) $(eval $(call KernelPackage,mt7921u))
$(eval $(call KernelPackage,mt7921s)) $(eval $(call KernelPackage,mt7921s))

View file

@ -0,0 +1,59 @@
From ed0b9c38becdbf9379787ca0b4db557f03a31dd7 Mon Sep 17 00:00:00 2001
From: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
Date: Mon, 23 Nov 2020 10:46:37 +0800
Subject: [PATCH] mt76: allow VHT rate on 2.4GHz
Allow chips that support 11ac to use 256QAM on 2.4GHz
Signed-off-by: DENG Qingfang <dqfext@gmail.com>
---
mac80211.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/mac80211.c b/mac80211.c
index 766681a4..06aa4228 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -282,7 +282,7 @@ static void mt76_init_stream_cap(struct mt76_phy *phy,
void mt76_set_stream_caps(struct mt76_phy *phy, bool vht)
{
if (phy->cap.has_2ghz)
- mt76_init_stream_cap(phy, &phy->sband_2g.sband, false);
+ mt76_init_stream_cap(phy, &phy->sband_2g.sband, vht);
if (phy->cap.has_5ghz)
mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht);
if (phy->cap.has_6ghz)
@@ -349,13 +349,13 @@ mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband,
static int
mt76_init_sband_2g(struct mt76_phy *phy, struct ieee80211_rate *rates,
- int n_rates)
+ int n_rates, bool vht)
{
phy->hw->wiphy->bands[NL80211_BAND_2GHZ] = &phy->sband_2g.sband;
return mt76_init_sband(phy, &phy->sband_2g, mt76_channels_2ghz,
ARRAY_SIZE(mt76_channels_2ghz), rates,
- n_rates, true, false);
+ n_rates, true, vht);
}
static int
@@ -508,7 +508,7 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
return ret;
if (phy->cap.has_2ghz) {
- ret = mt76_init_sband_2g(phy, rates, n_rates);
+ ret = mt76_init_sband_2g(phy, rates, n_rates, vht);
if (ret)
return ret;
}
@@ -691,7 +691,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
return ret;
if (phy->cap.has_2ghz) {
- ret = mt76_init_sband_2g(phy, rates, n_rates);
+ ret = mt76_init_sband_2g(phy, rates, n_rates, vht);
if (ret)
return ret;
}

View file

@ -0,0 +1,36 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 17 Nov 2022 00:58:46 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in
mtk_pending_work
Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is
set only in mtk_pending_work() and it runs holding rtnl lock
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
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
@@ -3722,11 +3722,8 @@ static void mtk_pending_work(struct work
rtnl_lock();
dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
+ set_bit(MTK_RESETTING, &eth->state);
- while (test_and_set_bit_lock(MTK_RESETTING, &eth->state))
- cpu_relax();
-
- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__);
/* stop all devices to make sure that dma is properly shut down */
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!eth->netdev[i])
@@ -3760,7 +3757,7 @@ static void mtk_pending_work(struct work
dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
- clear_bit_unlock(MTK_RESETTING, &eth->state);
+ clear_bit(MTK_RESETTING, &eth->state);
rtnl_unlock();
}

View file

@ -0,0 +1,80 @@
From: Sujuan Chen <sujuan.chen@mediatek.com>
Date: Thu, 24 Nov 2022 11:18:14 +0800
Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed
v1
All wed versions should enable the wcid overwritten feature,
since the wcid size is controlled by the wlan driver.
Tested-by: Sujuan Chen <sujuan.chen@mediatek.com>
Co-developed-by: Bo Jiao <bo.jiao@mediatek.com>
Signed-off-by: Bo Jiao <bo.jiao@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic
MTK_WED_WPDMA_RX_D_RX_DRV_EN);
wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
-
- mtk_wed_set_512_support(dev, false);
}
+
+ mtk_wed_set_512_support(dev, false);
}
static void
@@ -1290,9 +1290,10 @@ mtk_wed_start(struct mtk_wed_device *dev
if (mtk_wed_rro_cfg(dev))
return;
- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
}
+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
+
mtk_wed_dma_enable(dev);
dev->running = true;
}
@@ -1358,11 +1359,13 @@ mtk_wed_attach(struct mtk_wed_device *de
}
mtk_wed_hw_init_early(dev);
- if (hw->version == 1)
+ if (hw->version == 1) {
regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
BIT(hw->index), 0);
- else
+ } else {
+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
ret = mtk_wed_wo_init(hw);
+ }
out:
if (ret)
mtk_wed_detach(dev);
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
@@ -20,6 +20,8 @@ struct mtk_wdma_desc {
__le32 info;
} __packed __aligned(4);
+#define MTK_WED_REV_ID 0x004
+
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
#define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -85,6 +85,9 @@ struct mtk_wed_device {
int irq;
u8 version;
+ /* used by wlan driver */
+ u32 rev_id;
+
struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES];
struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
struct mtk_wed_ring txfree_ring;

View file

@ -0,0 +1,85 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:51 +0100
Subject: [PATCH] net: ethernet: mtk_wed: return status value in
mtk_wdma_rx_reset
Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine.
Increase poll timeout to 10ms in order to be aligned with vendor sdk.
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic
return wdma_r32(dev, MTK_WDMA_GLO_CFG);
}
-static void
+static int
mtk_wdma_rx_reset(struct mtk_wed_device *dev)
{
u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
- int i;
+ int i, ret;
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
- !(status & mask), 0, 1000))
+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
+ !(status & mask), 0, 10000);
+ if (ret)
dev_err(dev->hw->dev, "rx reset failed\n");
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) {
if (dev->rx_wdma[i].desc)
continue;
@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device
wdma_w32(dev,
MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
}
+
+ return ret;
}
static void
@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de
mtk_wed_stop(dev);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
+ mtk_wdma_rx_reset(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
if (mtk_wed_get_rx_capa(dev)) {
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de
mtk_wed_wo_reset(dev);
mtk_wed_free_rx_rings(dev);
mtk_wed_wo_deinit(hw);
- mtk_wdma_rx_reset(dev);
}
if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device
wed_w32(dev, MTK_WED_RESET_IDX, 0);
}
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
-
- if (mtk_wed_get_rx_capa(dev))
- mtk_wdma_rx_reset(dev);
+ mtk_wdma_rx_reset(dev);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);

View file

@ -0,0 +1,52 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:52 +0100
Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX
configuration in mtk_wdma_tx_reset
Remove duplicated code. Increase poll timeout to 10ms in order to be
aligned with vendor sdk.
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device
wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
- !(status & mask), 0, 1000))
+ !(status & mask), 0, 10000))
dev_err(dev->hw->dev, "tx reset failed\n");
- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) {
- if (dev->tx_wdma[i].desc)
- continue;
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
wdma_w32(dev,
MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0);
- }
}
static void
@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de
mtk_wdma_rx_reset(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
- if (mtk_wed_get_rx_capa(dev)) {
- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
- }
-
mtk_wed_free_tx_buffer(dev);
mtk_wed_free_tx_rings(dev);

View file

@ -0,0 +1,98 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:53 +0100
Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop
Update mtk_wed_stop routine and rename old mtk_wed_stop() to
mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet
Dispatcher reset support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic
static void
mtk_wed_stop(struct mtk_wed_device *dev)
{
- mtk_wed_dma_disable(dev);
mtk_wed_set_ext_int(dev, false);
- wed_clr(dev, MTK_WED_CTRL,
- MTK_WED_CTRL_WDMA_INT_AGENT_EN |
- MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
- MTK_WED_CTRL_WED_TX_BM_EN |
- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev)
wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+}
+
+static void
+mtk_wed_deinit(struct mtk_wed_device *dev)
+{
+ mtk_wed_stop(dev);
+ mtk_wed_dma_disable(dev);
+
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_WDMA_INT_AGENT_EN |
+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
+ MTK_WED_CTRL_WED_TX_BM_EN |
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+ if (dev->hw->version == 1)
+ return;
+
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
+ MTK_WED_CTRL_WED_RX_BM_EN |
+ MTK_WED_CTRL_RX_RRO_QM_EN);
}
static void
@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de
mutex_lock(&hw_lock);
- mtk_wed_stop(dev);
+ mtk_wed_deinit(dev);
mtk_wdma_rx_reset(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev
{
u32 mask, set;
- mtk_wed_stop(dev);
+ mtk_wed_deinit(dev);
mtk_wed_reset(dev, MTK_WED_RESET_WED);
mtk_wed_set_wpdma(dev);
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
(_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
(_dev)->ops->msg_update(_dev, _id, _msg, _len)
+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
+#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
#else
static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
{
@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active
#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
+#define mtk_wed_device_stop(_dev) do {} while (0)
+#define mtk_wed_device_dma_reset(_dev) do {} while (0)
#endif
#endif

View file

@ -0,0 +1,309 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:54 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine
Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless
Ethernet Dispatcher available on MT7986 SoC.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring *
}
static u32
-mtk_wed_check_busy(struct mtk_wed_device *dev)
+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
{
- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) &
- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) &
- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
- return true;
-
- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) &
- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY)
- return true;
-
- if (wed_r32(dev, MTK_WED_CTRL) &
- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY))
- return true;
-
- return false;
+ return !!(wed_r32(dev, reg) & mask);
}
static int
-mtk_wed_poll_busy(struct mtk_wed_device *dev)
+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
{
int sleep = 15000;
int timeout = 100 * sleep;
u32 val;
return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
- timeout, false, dev);
+ timeout, false, dev, reg, mask);
+}
+
+static int
+mtk_wed_rx_reset(struct mtk_wed_device *dev)
+{
+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
+ u8 val = MTK_WED_WO_STATE_SER_RESET;
+ int i, ret;
+
+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
+ sizeof(val), true);
+ if (ret)
+ return ret;
+
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
+ } else {
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
+
+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE |
+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE);
+
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
+ }
+
+ /* reset rro qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_RRO_QM_BUSY);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM);
+ } else {
+ wed_set(dev, MTK_WED_RROQM_RST_IDX,
+ MTK_WED_RROQM_RST_IDX_MIOD |
+ MTK_WED_RROQM_RST_IDX_FDBK);
+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
+ }
+
+ /* reset route qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY);
+ if (ret)
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
+ else
+ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
+ MTK_WED_RTQM_Q_RST);
+
+ /* reset tx wdma */
+ mtk_wdma_tx_reset(dev);
+
+ /* reset tx wdma drv */
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
+
+ /* reset wed rx dma */
+ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_RX_DMA_BUSY);
+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN);
+ if (ret) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA);
+ } else {
+ struct mtk_eth *eth = dev->hw->eth;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ wed_set(dev, MTK_WED_RESET_IDX,
+ MTK_WED_RESET_IDX_RX_V2);
+ else
+ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+ /* reset rx bm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_WED_RX_BM_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
+
+ /* wo change to enable state */
+ val = MTK_WED_WO_STATE_ENABLE;
+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO,
+ MTK_WED_WO_CMD_CHANGE_STATE, &val,
+ sizeof(val), true);
+ if (ret)
+ return ret;
+
+ /* wed_rx_ring_reset */
+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) {
+ if (!dev->rx_ring[i].desc)
+ continue;
+
+ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE,
+ false);
+ }
+ mtk_wed_free_rx_buffer(dev);
+
+ return 0;
}
static void
@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device
true);
}
- if (mtk_wed_poll_busy(dev))
- busy = mtk_wed_check_busy(dev);
-
+ /* 1. reset WED tx DMA */
+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN);
+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_TX_DMA_BUSY);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA);
} else {
- wed_w32(dev, MTK_WED_RESET_IDX,
- MTK_WED_RESET_IDX_TX |
- MTK_WED_RESET_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX);
wed_w32(dev, MTK_WED_RESET_IDX, 0);
}
- mtk_wdma_rx_reset(dev);
+ /* 2. reset WDMA rx DMA */
+ busy = !!mtk_wdma_rx_reset(dev);
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+ if (!busy)
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY);
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device
MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE);
}
+ /* 3. reset WED WPDMA tx */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
for (i = 0; i < 100; i++) {
val = wed_r32(dev, MTK_WED_TX_BM_INTF);
if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device
}
mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN);
mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
+ /* 4. reset WED WPDMA tx */
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
+ if (!busy)
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY);
+
if (busy) {
mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device
MTK_WED_WPDMA_RESET_IDX_RX);
wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0);
}
+
+ dev->init_done = false;
+ if (dev->hw->version == 1)
+ return;
+
+ if (!busy) {
+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX);
+ wed_w32(dev, MTK_WED_RESET_IDX, 0);
+ }
+
+ mtk_wed_rx_reset(dev);
}
static int
@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev
{
int i;
+ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev))
+ return;
+
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
if (!dev->rx_wdma[i].desc)
mtk_wed_wdma_rx_ring_setup(dev, i, 16);
@@ -1355,10 +1475,6 @@ mtk_wed_attach(struct mtk_wed_device *de
goto out;
if (mtk_wed_get_rx_capa(dev)) {
- ret = mtk_wed_rx_buffer_alloc(dev);
- if (ret)
- goto out;
-
ret = mtk_wed_rro_alloc(dev);
if (ret)
goto out;
--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
@@ -24,11 +24,15 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET 0x008
#define MTK_WED_RESET_TX_BM BIT(0)
+#define MTK_WED_RESET_RX_BM BIT(1)
#define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
#define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
#define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
+#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10)
#define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11)
#define MTK_WED_RESET_WED_TX_DMA BIT(12)
+#define MTK_WED_RESET_WED_RX_DMA BIT(13)
+#define MTK_WED_RESET_WDMA_TX_DRV BIT(16)
#define MTK_WED_RESET_WDMA_RX_DRV BIT(17)
#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
#define MTK_WED_RESET_RX_RRO_QM BIT(20)
@@ -158,6 +162,8 @@ struct mtk_wdma_desc {
#define MTK_WED_RESET_IDX 0x20c
#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
#define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
+#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6)
+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
#define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4)
#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4)
@@ -267,6 +273,9 @@ struct mtk_wdma_desc {
#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c
#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0)
+#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1)
+#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3)
+#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4)
#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7)
#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24)

View file

@ -0,0 +1,103 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 24 Nov 2022 16:22:55 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback
Introduce reset parameter to mtk_wed_tx_ring_setup signature.
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device
}
static int
-mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+ bool reset)
{
u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
struct mtk_wed_ring *wdma;
@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
return -EINVAL;
wdma = &dev->rx_wdma[idx];
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
- true))
+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+ desc_size, true))
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev
for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++)
if (!dev->rx_wdma[i].desc)
- mtk_wed_wdma_rx_ring_setup(dev, i, 16);
+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false);
mtk_wed_hw_init(dev);
mtk_wed_configure_irq(dev, irq_mask);
@@ -1498,7 +1499,8 @@ unlock:
}
static int
-mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
+ bool reset)
{
struct mtk_wed_ring *ring = &dev->tx_ring[idx];
@@ -1517,11 +1519,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev
if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring)))
return -EINVAL;
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
- sizeof(*ring->desc), true))
+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE,
+ sizeof(*ring->desc), true))
return -ENOMEM;
- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
+ reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_TX(idx);
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -158,7 +158,7 @@ struct mtk_wed_device {
struct mtk_wed_ops {
int (*attach)(struct mtk_wed_device *dev);
int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
+ void __iomem *regs, bool reset);
int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs);
int (*txfree_ring_setup)(struct mtk_wed_device *dev,
@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
#define mtk_wed_device_active(_dev) !!(_dev)->ops
#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
#define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask)
-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \
- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs)
+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \
+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset)
#define mtk_wed_device_txfree_ring_setup(_dev, _regs) \
(_dev)->ops->txfree_ring_setup(_dev, _regs)
#define mtk_wed_device_reg_read(_dev, _reg) \
@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active
}
#define mtk_wed_device_detach(_dev) do {} while (0)
#define mtk_wed_device_start(_dev, _mask) do {} while (0)
-#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV
+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
#define mtk_wed_device_reg_read(_dev, _reg) 0
#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)

View file

@ -0,0 +1,103 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 1 Dec 2022 16:26:53 +0100
Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in
mtk_wed_wo_queue_refill
In order to fix the following sleep while atomic bug always alloc pages
with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in
spin_lock critical section.
[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT)
[ 9.054665] Call trace:
[ 9.057096] dump_backtrace+0x0/0x154
[ 9.060751] show_stack+0x14/0x1c
[ 9.064052] dump_stack_lvl+0x64/0x7c
[ 9.067702] dump_stack+0x14/0x2c
[ 9.071001] ___might_sleep+0xec/0x120
[ 9.074736] __might_sleep+0x4c/0x9c
[ 9.078296] __alloc_pages+0x184/0x2e4
[ 9.082030] page_frag_alloc_align+0x98/0x1ac
[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234
[ 9.090974] mtk_wed_wo_init+0x174/0x2c0
[ 9.094881] mtk_wed_attach+0x7c8/0x7e0
[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e]
[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e]
[ 9.108727] pci_device_probe+0xac/0x13c
[ 9.112638] really_probe.part.0+0x98/0x2f4
[ 9.116807] __driver_probe_device+0x94/0x13c
[ 9.121147] driver_probe_device+0x40/0x114
[ 9.125314] __driver_attach+0x7c/0x180
[ 9.129133] bus_for_each_dev+0x5c/0x90
[ 9.132953] driver_attach+0x20/0x2c
[ 9.136513] bus_add_driver+0x104/0x1fc
[ 9.140333] driver_register+0x74/0x120
[ 9.144153] __pci_register_driver+0x40/0x50
[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e]
[ 9.152848] do_one_initcall+0x40/0x25c
[ 9.156669] do_init_module+0x44/0x230
[ 9.160403] load_module+0x1f30/0x2750
[ 9.164135] __do_sys_init_module+0x150/0x200
[ 9.168475] __arm64_sys_init_module+0x18/0x20
[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0
[ 9.177589] do_el0_svc+0x48/0xe0
[ 9.180889] el0_svc+0x14/0x50
[ 9.183929] el0t_64_sync_handler+0x9c/0x120
[ 9.188183] el0t_64_sync+0x158/0x15c
Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo
static int
mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q,
- gfp_t gfp, bool rx)
+ bool rx)
{
enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
int n_buf = 0;
spin_lock_bh(&q->lock);
while (q->queued < q->n_desc) {
- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp);
struct mtk_wed_wo_queue_entry *entry;
dma_addr_t addr;
+ void *buf;
+ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC);
if (!buf)
break;
@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w
mtk_wed_mcu_rx_unsolicited_event(wo, skb);
}
- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) {
+ if (mtk_wed_wo_queue_refill(wo, q, true)) {
u32 index = (q->head - 1) % q->n_desc;
mtk_wed_wo_queue_kick(wo, q, index);
@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
if (ret)
goto error;
- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false);
+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false);
mtk_wed_wo_queue_reset(wo, &wo->q_tx);
regs.desc_base = MTK_WED_WO_CCIF_DUMMY5;
@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_
if (ret)
goto error;
- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true);
+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true);
mtk_wed_wo_queue_reset(wo, &wo->q_rx);
/* rx queue irqmask */

View file

@ -0,0 +1,52 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 10 Jan 2023 10:31:26 +0100
Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue
Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and
mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher
MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization
and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in
mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been
disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill
routines can't run concurrently get rid of spinlock for mcu rx queue.
Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
int n_buf = 0;
- spin_lock_bh(&q->lock);
while (q->queued < q->n_desc) {
struct mtk_wed_wo_queue_entry *entry;
dma_addr_t addr;
@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w
q->queued++;
n_buf++;
}
- spin_unlock_bh(&q->lock);
return n_buf;
}
@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
{
struct page *page;
- spin_lock_bh(&q->lock);
for (;;) {
void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true);
@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed
skb_free_frag(buf);
}
- spin_unlock_bh(&q->lock);
if (!q->cache.va)
return;

View file

@ -0,0 +1,75 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Thu, 12 Jan 2023 10:21:29 +0100
Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue
Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue,
we do not need to protect WED MCU tx queue with a spin lock since
the tx queue is accessed in the two following routines:
- mtk_wed_wo_queue_tx_skb():
it is run at initialization and during mt7915 normal operation.
Moreover MCU messages are serialized through MCU mutex.
- mtk_wed_wo_queue_tx_clean():
it runs just at mt7915 driver module unload when no more messages
are sent to the MCU.
Remove tx queue spinlock.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c
@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo
int n_desc, int buf_size, int index,
struct mtk_wed_wo_queue_regs *regs)
{
- spin_lock_init(&q->lock);
q->regs = *regs;
q->n_desc = n_desc;
q->buf_size = buf_size;
@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
struct page *page;
int i;
- spin_lock_bh(&q->lock);
for (i = 0; i < q->n_desc; i++) {
struct mtk_wed_wo_queue_entry *entry = &q->entry[i];
@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed
skb_free_frag(entry->buf);
entry->buf = NULL;
}
- spin_unlock_bh(&q->lock);
if (!q->cache.va)
return;
@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
int ret = 0, index;
u32 ctrl;
- spin_lock_bh(&q->lock);
-
q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx);
index = (q->head + 1) % q->n_desc;
if (q->tail == index) {
@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w
mtk_wed_wo_queue_kick(wo, q, q->head);
mtk_wed_wo_kickout(wo);
out:
- spin_unlock_bh(&q->lock);
-
dev_kfree_skb(skb);
return ret;
--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue {
struct mtk_wed_wo_queue_regs regs;
struct page_frag_cache cache;
- spinlock_t lock;
struct mtk_wed_wo_queue_desc *desc;
dma_addr_t desc_dma;

View file

@ -0,0 +1,70 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:28 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility
routine
This is a preliminary patch to add Wireless Ethernet Dispatcher reset
support.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3478,6 +3478,27 @@ static void mtk_set_mcr_max_rx(struct mt
mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
}
+static void mtk_hw_reset(struct mtk_eth *eth)
+{
+ u32 val;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+ val = RSTCTRL_PPE0_V2;
+ } else {
+ val = RSTCTRL_PPE0;
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= RSTCTRL_PPE1;
+
+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+ 0x3ffffff);
+}
+
static int mtk_hw_init(struct mtk_eth *eth)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
@@ -3517,22 +3538,9 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
}
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
- val = RSTCTRL_PPE0_V2;
- } else {
- val = RSTCTRL_PPE0;
- }
-
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
- val |= RSTCTRL_PPE1;
-
- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+ mtk_hw_reset(eth);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
- 0x3ffffff);
-
/* Set FE to PDMAv2 if necessary */
val = mtk_r32(eth, MTK_FE_GLO_MISC);
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);

View file

@ -0,0 +1,107 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:29 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset
support
Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch
to align reset procedure to vendor sdk and avoid to power down the chip
during hw reset.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3499,7 +3499,54 @@ static void mtk_hw_reset(struct mtk_eth
0x3ffffff);
}
-static int mtk_hw_init(struct mtk_eth *eth)
+static u32 mtk_hw_reset_read(struct mtk_eth *eth)
+{
+ u32 val;
+
+ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val);
+ return val;
+}
+
+static void mtk_hw_warm_reset(struct mtk_eth *eth)
+{
+ u32 rst_mask, val;
+
+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE,
+ RSTCTRL_FE);
+ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val,
+ val & RSTCTRL_FE, 1, 1000)) {
+ dev_err(eth->dev, "warm reset failed\n");
+ mtk_hw_reset(eth);
+ return;
+ }
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
+ else
+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ rst_mask |= RSTCTRL_PPE1;
+
+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
+
+ udelay(1);
+ val = mtk_hw_reset_read(eth);
+ if (!(val & rst_mask))
+ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n",
+ val, rst_mask);
+
+ rst_mask |= RSTCTRL_FE;
+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask);
+
+ udelay(1);
+ val = mtk_hw_reset_read(eth);
+ if (val & rst_mask)
+ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n",
+ val, rst_mask);
+}
+
+static int mtk_hw_init(struct mtk_eth *eth, bool reset)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
ETHSYS_DMA_AG_MAP_PPE;
@@ -3538,7 +3585,12 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
}
- mtk_hw_reset(eth);
+ msleep(100);
+
+ if (reset)
+ mtk_hw_warm_reset(eth);
+ else
+ mtk_hw_reset(eth);
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
/* Set FE to PDMAv2 if necessary */
@@ -3749,7 +3801,7 @@ static void mtk_pending_work(struct work
if (eth->dev->pins)
pinctrl_select_state(eth->dev->pins->p,
eth->dev->pins->default_state);
- mtk_hw_init(eth);
+ mtk_hw_init(eth, true);
/* restart DMA and enable IRQs */
for (i = 0; i < MTK_MAC_COUNT; i++) {
@@ -4378,7 +4430,7 @@ static int mtk_probe(struct platform_dev
eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
INIT_WORK(&eth->pending_work, mtk_pending_work);
- err = mtk_hw_init(eth);
+ err = mtk_hw_init(eth, false);
if (err)
goto err_wed_exit;

View file

@ -0,0 +1,262 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:30 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor
sdk
Avoid to power-down the ethernet chip during hw reset and align reset
procedure to vendor sdk.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -2987,14 +2987,29 @@ static void mtk_dma_free(struct mtk_eth
kfree(eth->scratch_head);
}
+static bool mtk_hw_reset_check(struct mtk_eth *eth)
+{
+ u32 val = mtk_r32(eth, MTK_INT_STATUS2);
+
+ return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) ||
+ (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) ||
+ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL);
+}
+
static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
+ if (test_bit(MTK_RESETTING, &eth->state))
+ return;
+
+ if (!mtk_hw_reset_check(eth))
+ return;
+
eth->netdev[mac->id]->stats.tx_errors++;
- netif_err(eth, tx_err, dev,
- "transmit timed out\n");
+ netif_err(eth, tx_err, dev, "transmit timed out\n");
+
schedule_work(&eth->pending_work);
}
@@ -3553,15 +3568,17 @@ static int mtk_hw_init(struct mtk_eth *e
const struct mtk_reg_map *reg_map = eth->soc->reg_map;
int i, val, ret;
- if (test_and_set_bit(MTK_HW_INIT, &eth->state))
+ if (!reset && test_and_set_bit(MTK_HW_INIT, &eth->state))
return 0;
- pm_runtime_enable(eth->dev);
- pm_runtime_get_sync(eth->dev);
+ if (!reset) {
+ pm_runtime_enable(eth->dev);
+ pm_runtime_get_sync(eth->dev);
- ret = mtk_clk_enable(eth);
- if (ret)
- goto err_disable_pm;
+ ret = mtk_clk_enable(eth);
+ if (ret)
+ goto err_disable_pm;
+ }
if (eth->ethsys)
regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask,
@@ -3693,8 +3710,10 @@ static int mtk_hw_init(struct mtk_eth *e
return 0;
err_disable_pm:
- pm_runtime_put_sync(eth->dev);
- pm_runtime_disable(eth->dev);
+ if (!reset) {
+ pm_runtime_put_sync(eth->dev);
+ pm_runtime_disable(eth->dev);
+ }
return ret;
}
@@ -3773,30 +3792,53 @@ static int mtk_do_ioctl(struct net_devic
return -EOPNOTSUPP;
}
+static void mtk_prepare_for_reset(struct mtk_eth *eth)
+{
+ u32 val;
+ int i;
+
+ /* disabe FE P3 and P4 */
+ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val |= MTK_FE_LINK_DOWN_P4;
+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
+
+ /* adjust PPE configurations to prepare for reset */
+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
+ mtk_ppe_prepare_reset(eth->ppe[i]);
+
+ /* disable NETSYS interrupts */
+ mtk_w32(eth, 0, MTK_FE_INT_ENABLE);
+
+ /* force link down GMAC */
+ for (i = 0; i < 2; i++) {
+ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK;
+ mtk_w32(eth, val, MTK_MAC_MCR(i));
+ }
+}
+
static void mtk_pending_work(struct work_struct *work)
{
struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
- int err, i;
unsigned long restart = 0;
+ u32 val;
+ int i;
rtnl_lock();
-
- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__);
set_bit(MTK_RESETTING, &eth->state);
+ mtk_prepare_for_reset(eth);
+
/* stop all devices to make sure that dma is properly shut down */
for (i = 0; i < MTK_MAC_COUNT; i++) {
- if (!eth->netdev[i])
+ if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
continue;
+
mtk_stop(eth->netdev[i]);
__set_bit(i, &restart);
}
- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__);
- /* restart underlying hardware such as power, clock, pin mux
- * and the connected phy
- */
- mtk_hw_deinit(eth);
+ usleep_range(15000, 16000);
if (eth->dev->pins)
pinctrl_select_state(eth->dev->pins->p,
@@ -3807,15 +3849,19 @@ static void mtk_pending_work(struct work
for (i = 0; i < MTK_MAC_COUNT; i++) {
if (!test_bit(i, &restart))
continue;
- err = mtk_open(eth->netdev[i]);
- if (err) {
+
+ if (mtk_open(eth->netdev[i])) {
netif_alert(eth, ifup, eth->netdev[i],
- "Driver up/down cycle failed, closing device.\n");
+ "Driver up/down cycle failed\n");
dev_close(eth->netdev[i]);
}
}
- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__);
+ /* enabe FE P3 and P4 */
+ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+ val &= ~MTK_FE_LINK_DOWN_P4;
+ mtk_w32(eth, val, MTK_FE_GLO_CFG);
clear_bit(MTK_RESETTING, &eth->state);
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -75,12 +75,24 @@
#define MTK_HW_LRO_REPLACE_DELTA 1000
#define MTK_HW_LRO_SDL_REMAIN_ROOM 1522
+/* Frame Engine Global Configuration */
+#define MTK_FE_GLO_CFG 0x00
+#define MTK_FE_LINK_DOWN_P3 BIT(11)
+#define MTK_FE_LINK_DOWN_P4 BIT(12)
+
/* Frame Engine Global Reset Register */
#define MTK_RST_GL 0x04
#define RST_GL_PSE BIT(0)
/* Frame Engine Interrupt Status Register */
#define MTK_INT_STATUS2 0x08
+#define MTK_FE_INT_ENABLE 0x0c
+#define MTK_FE_INT_FQ_EMPTY BIT(8)
+#define MTK_FE_INT_TSO_FAIL BIT(12)
+#define MTK_FE_INT_TSO_ILLEGAL BIT(13)
+#define MTK_FE_INT_TSO_ALIGN BIT(14)
+#define MTK_FE_INT_RFIFO_OV BIT(18)
+#define MTK_FE_INT_RFIFO_UF BIT(19)
#define MTK_GDM1_AF BIT(28)
#define MTK_GDM2_AF BIT(29)
--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -730,6 +730,33 @@ int mtk_foe_entry_idle_time(struct mtk_p
return __mtk_foe_entry_idle_time(ppe, entry->data.ib1);
}
+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
+{
+ if (!ppe)
+ return -EINVAL;
+
+ /* disable KA */
+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
+ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0);
+ usleep_range(10000, 11000);
+
+ /* set KA timer to maximum */
+ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE);
+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff);
+
+ /* set KA tick select */
+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL);
+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE);
+ usleep_range(10000, 11000);
+
+ /* disable scan mode */
+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE);
+ usleep_range(10000, 11000);
+
+ return mtk_ppe_wait_busy(ppe);
+}
+
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
int version, int index)
{
--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
@@ -308,6 +308,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
void mtk_ppe_deinit(struct mtk_eth *eth);
void mtk_ppe_start(struct mtk_ppe *ppe);
int mtk_ppe_stop(struct mtk_ppe *ppe);
+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
@@ -58,6 +58,12 @@
#define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16)
#define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18)
#define MTK_PPE_TB_CFG_INFO_SEL BIT(20)
+#define MTK_PPE_TB_TICK_SEL BIT(24)
+
+#define MTK_PPE_BIND_LMT1 0x230
+#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16)
+
+#define MTK_PPE_KEEPALIVE 0x234
enum {
MTK_PPE_SCAN_MODE_DISABLED,

View file

@ -0,0 +1,249 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:31 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to
mtk_hw_reset_check
Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs.
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -51,6 +51,7 @@ static const struct mtk_reg_map mtk_reg_
.delay_irq = 0x0a0c,
.irq_status = 0x0a20,
.irq_mask = 0x0a28,
+ .adma_rx_dbg0 = 0x0a38,
.int_grp = 0x0a50,
},
.qdma = {
@@ -82,6 +83,8 @@ static const struct mtk_reg_map mtk_reg_
[0] = 0x2800,
[1] = 0x2c00,
},
+ .pse_iq_sta = 0x0110,
+ .pse_oq_sta = 0x0118,
};
static const struct mtk_reg_map mt7628_reg_map = {
@@ -112,6 +115,7 @@ static const struct mtk_reg_map mt7986_r
.delay_irq = 0x620c,
.irq_status = 0x6220,
.irq_mask = 0x6228,
+ .adma_rx_dbg0 = 0x6238,
.int_grp = 0x6250,
},
.qdma = {
@@ -143,6 +147,8 @@ static const struct mtk_reg_map mt7986_r
[0] = 0x4800,
[1] = 0x4c00,
},
+ .pse_iq_sta = 0x0180,
+ .pse_oq_sta = 0x01a0,
};
/* strings used by ethtool */
@@ -3561,6 +3567,102 @@ static void mtk_hw_warm_reset(struct mtk
val, rst_mask);
}
+static bool mtk_hw_check_dma_hang(struct mtk_eth *eth)
+{
+ const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+ bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx;
+ bool oq_hang, cdm1_busy, adma_busy;
+ bool wtx_busy, cdm_full, oq_free;
+ u32 wdidx, val, gdm1_fc, gdm2_fc;
+ bool qfsm_hang, qfwd_hang;
+ bool ret = false;
+
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+ return false;
+
+ /* WDMA sanity checks */
+ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc);
+
+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204);
+ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val);
+
+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230);
+ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val);
+
+ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) &&
+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) &&
+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16)));
+
+ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) {
+ if (++eth->reset.wdma_hang_count > 2) {
+ eth->reset.wdma_hang_count = 0;
+ ret = true;
+ }
+ goto out;
+ }
+
+ /* QDMA sanity checks */
+ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234);
+ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308);
+
+ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0;
+ gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0;
+ gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1;
+ gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1;
+ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24);
+ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64);
+
+ if (qfsm_hang && qfwd_hang &&
+ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) ||
+ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) {
+ if (++eth->reset.qdma_hang_count > 2) {
+ eth->reset.qdma_hang_count = 0;
+ ret = true;
+ }
+ goto out;
+ }
+
+ /* ADMA sanity checks */
+ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0));
+ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16));
+ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) &&
+ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6));
+
+ if (oq_hang && cdm1_busy && adma_busy) {
+ if (++eth->reset.adma_hang_count > 2) {
+ eth->reset.adma_hang_count = 0;
+ ret = true;
+ }
+ goto out;
+ }
+
+ eth->reset.wdma_hang_count = 0;
+ eth->reset.qdma_hang_count = 0;
+ eth->reset.adma_hang_count = 0;
+out:
+ eth->reset.wdidx = wdidx;
+
+ return ret;
+}
+
+static void mtk_hw_reset_monitor_work(struct work_struct *work)
+{
+ struct delayed_work *del_work = to_delayed_work(work);
+ struct mtk_eth *eth = container_of(del_work, struct mtk_eth,
+ reset.monitor_work);
+
+ if (test_bit(MTK_RESETTING, &eth->state))
+ goto out;
+
+ /* DMA stuck checks */
+ if (mtk_hw_check_dma_hang(eth))
+ schedule_work(&eth->pending_work);
+
+out:
+ schedule_delayed_work(&eth->reset.monitor_work,
+ MTK_DMA_MONITOR_TIMEOUT);
+}
+
static int mtk_hw_init(struct mtk_eth *eth, bool reset)
{
u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
@@ -3909,6 +4011,7 @@ static int mtk_cleanup(struct mtk_eth *e
mtk_unreg_dev(eth);
mtk_free_dev(eth);
cancel_work_sync(&eth->pending_work);
+ cancel_delayed_work_sync(&eth->reset.monitor_work);
return 0;
}
@@ -4363,6 +4466,7 @@ static int mtk_probe(struct platform_dev
eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(&eth->rx_dim.work, mtk_dim_rx);
+ INIT_DELAYED_WORK(&eth->reset.monitor_work, mtk_hw_reset_monitor_work);
eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(&eth->tx_dim.work, mtk_dim_tx);
@@ -4567,6 +4671,8 @@ static int mtk_probe(struct platform_dev
netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx);
platform_set_drvdata(pdev, eth);
+ schedule_delayed_work(&eth->reset.monitor_work,
+ MTK_DMA_MONITOR_TIMEOUT);
return 0;
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -282,6 +282,8 @@
#define MTK_RX_DONE_INT_V2 BIT(14)
+#define MTK_CDM_TXFIFO_RDY BIT(7)
+
/* QDMA Interrupt grouping registers */
#define MTK_RLS_DONE_INT BIT(0)
@@ -566,6 +568,17 @@
#define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c)
#define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110)
+#define MTK_FE_CDM1_FSM 0x220
+#define MTK_FE_CDM2_FSM 0x224
+#define MTK_FE_CDM3_FSM 0x238
+#define MTK_FE_CDM4_FSM 0x298
+#define MTK_FE_CDM5_FSM 0x318
+#define MTK_FE_CDM6_FSM 0x328
+#define MTK_FE_GDM1_FSM 0x228
+#define MTK_FE_GDM2_FSM 0x22C
+
+#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100))
+
struct mtk_rx_dma {
unsigned int rxd1;
unsigned int rxd2;
@@ -968,6 +981,7 @@ struct mtk_reg_map {
u32 delay_irq; /* delay interrupt */
u32 irq_status; /* interrupt status */
u32 irq_mask; /* interrupt mask */
+ u32 adma_rx_dbg0;
u32 int_grp;
} pdma;
struct {
@@ -996,6 +1010,8 @@ struct mtk_reg_map {
u32 gdma_to_ppe;
u32 ppe_base;
u32 wdma_base[2];
+ u32 pse_iq_sta;
+ u32 pse_oq_sta;
};
/* struct mtk_eth_data - This is the structure holding all differences
@@ -1038,6 +1054,8 @@ struct mtk_soc_data {
} txrx;
};
+#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
+
/* currently no SoC has more than 2 macs */
#define MTK_MAX_DEVS 2
@@ -1162,6 +1180,14 @@ struct mtk_eth {
struct rhashtable flow_table;
struct bpf_prog __rcu *prog;
+
+ struct {
+ struct delayed_work monitor_work;
+ u32 wdidx;
+ u8 wdma_hang_count;
+ u8 qdma_hang_count;
+ u8 adma_hang_count;
+ } reset;
};
/* struct mtk_mac - the structure that holds the info about the MACs of the

View file

@ -0,0 +1,124 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sat, 14 Jan 2023 18:01:32 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks
Introduce reset and reset_complete wlan callback to schedule WLAN driver
reset when ethernet/wed driver is resetting.
Tested-by: Daniel Golle <daniel@makrotopia.org>
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3930,6 +3930,11 @@ static void mtk_pending_work(struct work
set_bit(MTK_RESETTING, &eth->state);
mtk_prepare_for_reset(eth);
+ mtk_wed_fe_reset();
+ /* Run again reset preliminary configuration in order to avoid any
+ * possible race during FE reset since it can run releasing RTNL lock.
+ */
+ mtk_prepare_for_reset(eth);
/* stop all devices to make sure that dma is properly shut down */
for (i = 0; i < MTK_MAC_COUNT; i++) {
@@ -3967,6 +3972,8 @@ static void mtk_pending_work(struct work
clear_bit(MTK_RESETTING, &eth->state);
+ mtk_wed_fe_reset_complete();
+
rtnl_unlock();
}
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device *
iounmap(reg);
}
+void mtk_wed_fe_reset(void)
+{
+ int i;
+
+ mutex_lock(&hw_lock);
+
+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+ struct mtk_wed_hw *hw = hw_list[i];
+ struct mtk_wed_device *dev = hw->wed_dev;
+ int err;
+
+ if (!dev || !dev->wlan.reset)
+ continue;
+
+ /* reset callback blocks until WLAN reset is completed */
+ err = dev->wlan.reset(dev);
+ if (err)
+ dev_err(dev->dev, "wlan reset failed: %d\n", err);
+ }
+
+ mutex_unlock(&hw_lock);
+}
+
+void mtk_wed_fe_reset_complete(void)
+{
+ int i;
+
+ mutex_lock(&hw_lock);
+
+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+ struct mtk_wed_hw *hw = hw_list[i];
+ struct mtk_wed_device *dev = hw->wed_dev;
+
+ if (!dev || !dev->wlan.reset_complete)
+ continue;
+
+ dev->wlan.reset_complete(dev);
+ }
+
+ mutex_unlock(&hw_lock);
+}
+
static struct mtk_wed_hw *
mtk_wed_assign(struct mtk_wed_device *dev)
{
--- a/drivers/net/ethernet/mediatek/mtk_wed.h
+++ b/drivers/net/ethernet/mediatek/mtk_wed.h
@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node *
void mtk_wed_exit(void);
int mtk_wed_flow_add(int index);
void mtk_wed_flow_remove(int index);
+void mtk_wed_fe_reset(void);
+void mtk_wed_fe_reset_complete(void);
#else
static inline void
mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i
{
}
+static inline void mtk_wed_fe_reset(void)
+{
+}
+
+static inline void mtk_wed_fe_reset_complete(void)
+{
+}
#endif
#ifdef CONFIG_DEBUG_FS
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -151,6 +151,8 @@ struct mtk_wed_device {
void (*release_rx_buf)(struct mtk_wed_device *wed);
void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
struct mtk_wed_wo_rx_stats *stats);
+ int (*reset)(struct mtk_wed_device *wed);
+ void (*reset_complete)(struct mtk_wed_device *wed);
} wlan;
#endif
};

View file

@ -0,0 +1,106 @@
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Mon, 5 Dec 2022 12:34:42 +0100
Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback
This patch adds reset parameter to mtk_wed_rx_ring_setup signature
in order to align rx_ring_setup callback to tx_ring_setup one introduced
in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to
tx_ring_setup callback")'
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -1252,7 +1252,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we
}
static int
-mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size)
+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size,
+ bool reset)
{
u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version;
struct mtk_wed_ring *wdma;
@@ -1261,8 +1262,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
return -EINVAL;
wdma = &dev->tx_wdma[idx];
- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size,
- true))
+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+ desc_size, true))
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
@@ -1272,6 +1273,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0);
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
+ if (reset)
+ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true);
+
if (!idx) {
wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE,
wdma->desc_phys);
@@ -1611,18 +1615,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed
}
static int
-mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs,
+ bool reset)
{
struct mtk_wed_ring *ring = &dev->rx_ring[idx];
if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring)))
return -EINVAL;
- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
- sizeof(*ring->desc), false))
+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE,
+ sizeof(*ring->desc), false))
return -ENOMEM;
- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE))
+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE,
+ reset))
return -ENOMEM;
ring->reg_base = MTK_WED_RING_RX_DATA(idx);
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -162,7 +162,7 @@ struct mtk_wed_ops {
int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring,
void __iomem *regs, bool reset);
int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
- void __iomem *regs);
+ void __iomem *regs, bool reset);
int (*txfree_ring_setup)(struct mtk_wed_device *dev,
void __iomem *regs);
int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
(_dev)->ops->irq_get(_dev, _mask)
#define mtk_wed_device_irq_set_mask(_dev, _mask) \
(_dev)->ops->irq_set_mask(_dev, _mask)
-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \
- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs)
+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
(_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active
#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
#define mtk_wed_device_irq_get(_dev, _mask) 0
#define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0)
-#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV
+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0)
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
#define mtk_wed_device_stop(_dev) do {} while (0)

View file

@ -0,0 +1,266 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Mon, 20 Mar 2023 11:44:30 +0100
Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows
from wlan devices
WED version 2 (on MT7986 and later) can offload flows originating from wireless
devices. In order to make that work, ndo_setup_tc needs to be implemented on
the netdevs. This adds the required code to offload flows coming in from WED,
while keeping track of the incoming wed index used for selecting the correct
PPE device.
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
@@ -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);
+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
+ int ppe_index);
+void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
@@ -235,7 +235,8 @@ out:
}
static int
-mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
+mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f,
+ int ppe_index)
{
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
struct flow_action_entry *act;
@@ -452,6 +453,7 @@ mtk_flow_offload_replace(struct mtk_eth
entry->cookie = f->cookie;
memcpy(&entry->data, &foe, sizeof(entry->data));
entry->wed_index = wed_index;
+ entry->ppe_index = ppe_index;
err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
if (err < 0)
@@ -520,25 +522,15 @@ mtk_flow_offload_stats(struct mtk_eth *e
static DEFINE_MUTEX(mtk_flow_offload_mutex);
-static int
-mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls,
+ int ppe_index)
{
- struct flow_cls_offload *cls = type_data;
- struct net_device *dev = cb_priv;
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
int err;
- if (!tc_can_offload(dev))
- return -EOPNOTSUPP;
-
- if (type != TC_SETUP_CLSFLOWER)
- return -EOPNOTSUPP;
-
mutex_lock(&mtk_flow_offload_mutex);
switch (cls->command) {
case FLOW_CLS_REPLACE:
- err = mtk_flow_offload_replace(eth, cls);
+ err = mtk_flow_offload_replace(eth, cls, ppe_index);
break;
case FLOW_CLS_DESTROY:
err = mtk_flow_offload_destroy(eth, cls);
@@ -556,6 +548,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_
}
static int
+mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
+{
+ struct flow_cls_offload *cls = type_data;
+ struct net_device *dev = cb_priv;
+ struct mtk_mac *mac = netdev_priv(dev);
+ struct mtk_eth *eth = mac->hw;
+
+ if (!tc_can_offload(dev))
+ return -EOPNOTSUPP;
+
+ if (type != TC_SETUP_CLSFLOWER)
+ return -EOPNOTSUPP;
+
+ return mtk_flow_offload_cmd(eth, cls, 0);
+}
+
+static int
mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
{
struct mtk_mac *mac = netdev_priv(dev);
--- a/drivers/net/ethernet/mediatek/mtk_wed.c
+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -13,6 +13,8 @@
#include <linux/mfd/syscon.h>
#include <linux/debugfs.h>
#include <linux/soc/mediatek/mtk_wed.h>
+#include <net/flow_offload.h>
+#include <net/pkt_cls.h>
#include "mtk_eth_soc.h"
#include "mtk_wed_regs.h"
#include "mtk_wed.h"
@@ -41,6 +43,11 @@
static struct mtk_wed_hw *hw_list[2];
static DEFINE_MUTEX(hw_lock);
+struct mtk_wed_flow_block_priv {
+ struct mtk_wed_hw *hw;
+ struct net_device *dev;
+};
+
static void
wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
{
@@ -1752,6 +1759,99 @@ out:
mutex_unlock(&hw_lock);
}
+static int
+mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
+{
+ struct mtk_wed_flow_block_priv *priv = cb_priv;
+ struct flow_cls_offload *cls = type_data;
+ struct mtk_wed_hw *hw = priv->hw;
+
+ if (!tc_can_offload(priv->dev))
+ return -EOPNOTSUPP;
+
+ if (type != TC_SETUP_CLSFLOWER)
+ return -EOPNOTSUPP;
+
+ return mtk_flow_offload_cmd(hw->eth, cls, hw->index);
+}
+
+static int
+mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev,
+ struct flow_block_offload *f)
+{
+ struct mtk_wed_flow_block_priv *priv;
+ static LIST_HEAD(block_cb_list);
+ struct flow_block_cb *block_cb;
+ struct mtk_eth *eth = hw->eth;
+ flow_setup_cb_t *cb;
+
+ if (!eth->soc->offload_version)
+ return -EOPNOTSUPP;
+
+ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
+ return -EOPNOTSUPP;
+
+ cb = mtk_wed_setup_tc_block_cb;
+ f->driver_block_list = &block_cb_list;
+
+ switch (f->command) {
+ case FLOW_BLOCK_BIND:
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
+ if (block_cb) {
+ flow_block_cb_incref(block_cb);
+ return 0;
+ }
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->hw = hw;
+ priv->dev = dev;
+ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL);
+ if (IS_ERR(block_cb)) {
+ kfree(priv);
+ return PTR_ERR(block_cb);
+ }
+
+ flow_block_cb_incref(block_cb);
+ flow_block_cb_add(block_cb, f);
+ list_add_tail(&block_cb->driver_list, &block_cb_list);
+ return 0;
+ case FLOW_BLOCK_UNBIND:
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
+ if (!block_cb)
+ return -ENOENT;
+
+ if (!flow_block_cb_decref(block_cb)) {
+ flow_block_cb_remove(block_cb, f);
+ list_del(&block_cb->driver_list);
+ kfree(block_cb->cb_priv);
+ }
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int
+mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev,
+ enum tc_setup_type type, void *type_data)
+{
+ struct mtk_wed_hw *hw = wed->hw;
+
+ if (hw->version < 2)
+ return -EOPNOTSUPP;
+
+ switch (type) {
+ case TC_SETUP_BLOCK:
+ case TC_SETUP_FT:
+ return mtk_wed_setup_tc_block(hw, dev, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
void __iomem *wdma, phys_addr_t wdma_phy,
int index)
@@ -1771,6 +1871,7 @@ void mtk_wed_add_hw(struct device_node *
.irq_set_mask = mtk_wed_irq_set_mask,
.detach = mtk_wed_detach,
.ppe_check = mtk_wed_ppe_check,
+ .setup_tc = mtk_wed_setup_tc,
};
struct device_node *eth_np = eth->dev->of_node;
struct platform_device *pdev;
--- a/include/linux/soc/mediatek/mtk_wed.h
+++ b/include/linux/soc/mediatek/mtk_wed.h
@@ -6,6 +6,7 @@
#include <linux/regmap.h>
#include <linux/pci.h>
#include <linux/skbuff.h>
+#include <linux/netdevice.h>
#define MTK_WED_TX_QUEUES 2
#define MTK_WED_RX_QUEUES 2
@@ -180,6 +181,8 @@ struct mtk_wed_ops {
u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask);
void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
+ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev,
+ enum tc_setup_type type, void *type_data);
};
extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic
(_dev)->ops->msg_update(_dev, _id, _msg, _len)
#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev)
#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev)
+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \
+ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data)
#else
static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
{
@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active
#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV
#define mtk_wed_device_stop(_dev) do {} while (0)
#define mtk_wed_device_dma_reset(_dev) do {} while (0)
+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP
#endif
#endif

View file

@ -0,0 +1,597 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Weijie Gao <weijie.gao@mediatek.com>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/reset.h>
#include <linux/hrtimer.h>
#include <linux/mii.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_net.h>
#include <linux/of_irq.h>
#include <linux/phy.h>
#include "mt753x.h"
#include "mt753x_swconfig.h"
#include "mt753x_regs.h"
#include "mt753x_nl.h"
#include "mt7530.h"
#include "mt7531.h"
static u32 mt753x_id;
struct list_head mt753x_devs;
static DEFINE_MUTEX(mt753x_devs_lock);
static struct mt753x_sw_id *mt753x_sw_ids[] = {
&mt7530_id,
&mt7531_id,
};
u32 mt753x_reg_read(struct gsw_mt753x *gsw, u32 reg)
{
u32 high, low;
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);
low = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr,
(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S);
high = gsw->host_bus->read(gsw->host_bus, gsw->smi_addr, 0x10);
mutex_unlock(&gsw->host_bus->mdio_lock);
return (high << 16) | (low & 0xffff);
}
void mt753x_reg_write(struct gsw_mt753x *gsw, u32 reg, u32 val)
{
mutex_lock(&gsw->host_bus->mdio_lock);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x1f,
(reg & MT753X_REG_PAGE_ADDR_M) >> MT753X_REG_PAGE_ADDR_S);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr,
(reg & MT753X_REG_ADDR_M) >> MT753X_REG_ADDR_S, val & 0xffff);
gsw->host_bus->write(gsw->host_bus, gsw->smi_addr, 0x10, val >> 16);
mutex_unlock(&gsw->host_bus->mdio_lock);
}
/* Indirect MDIO clause 22/45 access */
static int mt753x_mii_rw(struct gsw_mt753x *gsw, int phy, int reg, u16 data,
u32 cmd, u32 st)
{
ktime_t timeout;
u32 val, timeout_us;
int ret = 0;
timeout_us = 100000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PHY_IAC);
if ((val & PHY_ACS_ST) == 0)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
val = (st << MDIO_ST_S) |
((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
val |= data & MDIO_RW_DATA_M;
mt753x_reg_write(gsw, PHY_IAC, val | PHY_ACS_ST);
timeout_us = 100000;
timeout = ktime_add_us(ktime_get(), timeout_us);
while (1) {
val = mt753x_reg_read(gsw, PHY_IAC);
if ((val & PHY_ACS_ST) == 0)
break;
if (ktime_compare(ktime_get(), timeout) > 0)
return -ETIMEDOUT;
}
if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
val = mt753x_reg_read(gsw, PHY_IAC);
ret = val & MDIO_RW_DATA_M;
}
return ret;
}
int mt753x_mii_read(struct gsw_mt753x *gsw, int phy, int reg)
{
int val;
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
val = mt753x_mii_rw(gsw, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mii_write(struct gsw_mt753x *gsw, int phy, int reg, u16 val)
{
if (phy < MT753X_NUM_PHYS)
phy = (gsw->phy_base + phy) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, phy, reg, val, MDIO_CMD_WRITE, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
}
int mt753x_mmd_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
int val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
val = mt753x_mii_rw(gsw, addr, devad, 0, MDIO_CMD_READ_C45,
MDIO_ST_C45);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mmd_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
mt753x_mii_rw(gsw, addr, devad, val, MDIO_CMD_WRITE, MDIO_ST_C45);
mutex_unlock(&gsw->mii_lock);
}
int mt753x_mmd_ind_read(struct gsw_mt753x *gsw, int addr, int devad, u16 reg)
{
u16 val;
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
val = mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, 0,
MDIO_CMD_READ, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
return val;
}
void mt753x_mmd_ind_write(struct gsw_mt753x *gsw, int addr, int devad, u16 reg,
u16 val)
{
if (addr < MT753X_NUM_PHYS)
addr = (gsw->phy_base + addr) & MT753X_SMI_ADDR_MASK;
mutex_lock(&gsw->mii_lock);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_ADDR << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, reg,
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ACC_CTL_REG,
(MMD_DATA << MMD_CMD_S) |
((devad << MMD_DEVAD_S) & MMD_DEVAD_M),
MDIO_CMD_WRITE, MDIO_ST_C22);
mt753x_mii_rw(gsw, addr, MII_MMD_ADDR_DATA_REG, val,
MDIO_CMD_WRITE, MDIO_ST_C22);
mutex_unlock(&gsw->mii_lock);
}
static inline int mt753x_get_duplex(const struct device_node *np)
{
return of_property_read_bool(np, "full-duplex");
}
static void mt753x_load_port_cfg(struct gsw_mt753x *gsw)
{
struct device_node *port_np;
struct device_node *fixed_link_node;
struct mt753x_port_cfg *port_cfg;
u32 port;
for_each_child_of_node(gsw->dev->of_node, port_np) {
if (!of_device_is_compatible(port_np, "mediatek,mt753x-port"))
continue;
if (!of_device_is_available(port_np))
continue;
if (of_property_read_u32(port_np, "reg", &port))
continue;
switch (port) {
case 5:
port_cfg = &gsw->port5_cfg;
break;
case 6:
port_cfg = &gsw->port6_cfg;
break;
default:
continue;
}
if (port_cfg->enabled) {
dev_info(gsw->dev, "duplicated node for port%d\n",
port_cfg->phy_mode);
continue;
}
port_cfg->np = port_np;
if (of_get_phy_mode(port_np, &port_cfg->phy_mode) < 0) {
dev_info(gsw->dev, "incorrect phy-mode %d\n", port);
continue;
}
fixed_link_node = of_get_child_by_name(port_np, "fixed-link");
if (fixed_link_node) {
u32 speed;
port_cfg->force_link = 1;
port_cfg->duplex = mt753x_get_duplex(fixed_link_node);
if (of_property_read_u32(fixed_link_node, "speed",
&speed)) {
speed = 0;
continue;
}
of_node_put(fixed_link_node);
switch (speed) {
case 10:
port_cfg->speed = MAC_SPD_10;
break;
case 100:
port_cfg->speed = MAC_SPD_100;
break;
case 1000:
port_cfg->speed = MAC_SPD_1000;
break;
case 2500:
port_cfg->speed = MAC_SPD_2500;
break;
default:
dev_info(gsw->dev, "incorrect speed %d\n",
speed);
continue;
}
}
port_cfg->enabled = 1;
}
}
static void mt753x_add_gsw(struct gsw_mt753x *gsw)
{
mutex_lock(&mt753x_devs_lock);
gsw->id = mt753x_id++;
INIT_LIST_HEAD(&gsw->list);
list_add_tail(&gsw->list, &mt753x_devs);
mutex_unlock(&mt753x_devs_lock);
}
static void mt753x_remove_gsw(struct gsw_mt753x *gsw)
{
mutex_lock(&mt753x_devs_lock);
list_del(&gsw->list);
mutex_unlock(&mt753x_devs_lock);
}
struct gsw_mt753x *mt753x_get_gsw(u32 id)
{
struct gsw_mt753x *dev;
mutex_lock(&mt753x_devs_lock);
list_for_each_entry(dev, &mt753x_devs, list) {
if (dev->id == id)
return dev;
}
mutex_unlock(&mt753x_devs_lock);
return NULL;
}
struct gsw_mt753x *mt753x_get_first_gsw(void)
{
struct gsw_mt753x *dev;
mutex_lock(&mt753x_devs_lock);
list_for_each_entry(dev, &mt753x_devs, list)
return dev;
mutex_unlock(&mt753x_devs_lock);
return NULL;
}
void mt753x_put_gsw(void)
{
mutex_unlock(&mt753x_devs_lock);
}
void mt753x_lock_gsw(void)
{
mutex_lock(&mt753x_devs_lock);
}
static int mt753x_hw_reset(struct gsw_mt753x *gsw)
{
struct device_node *np = gsw->dev->of_node;
struct reset_control *rstc;
int mcm;
int ret = -EINVAL;
mcm = of_property_read_bool(np, "mediatek,mcm");
if (mcm) {
rstc = devm_reset_control_get(gsw->dev, "mcm");
ret = IS_ERR(rstc);
if (IS_ERR(rstc)) {
dev_err(gsw->dev, "Missing reset ctrl of switch\n");
return ret;
}
reset_control_assert(rstc);
msleep(30);
reset_control_deassert(rstc);
gsw->reset_pin = -1;
return 0;
}
gsw->reset_pin = of_get_named_gpio(np, "reset-gpios", 0);
if (gsw->reset_pin < 0) {
dev_err(gsw->dev, "Missing reset pin of switch\n");
return ret;
}
ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mt753x-reset");
if (ret) {
dev_info(gsw->dev, "Failed to request gpio %d\n",
gsw->reset_pin);
return ret;
}
gpio_direction_output(gsw->reset_pin, 0);
msleep(30);
gpio_set_value(gsw->reset_pin, 1);
msleep(500);
return 0;
}
static irqreturn_t mt753x_irq_handler(int irq, void *dev)
{
struct gsw_mt753x *gsw = dev;
disable_irq_nosync(gsw->irq);
schedule_work(&gsw->irq_worker);
return IRQ_HANDLED;
}
static int mt753x_probe(struct platform_device *pdev)
{
struct gsw_mt753x *gsw;
struct mt753x_sw_id *sw;
struct device_node *np = pdev->dev.of_node;
struct device_node *mdio;
struct mii_bus *mdio_bus;
int ret = -EINVAL;
struct chip_rev rev;
struct mt753x_mapping *map;
int i;
mdio = of_parse_phandle(np, "mediatek,mdio", 0);
if (!mdio)
return -EINVAL;
mdio_bus = of_mdio_find_bus(mdio);
if (!mdio_bus)
return -EPROBE_DEFER;
gsw = devm_kzalloc(&pdev->dev, sizeof(struct gsw_mt753x), GFP_KERNEL);
if (!gsw)
return -ENOMEM;
gsw->host_bus = mdio_bus;
gsw->dev = &pdev->dev;
mutex_init(&gsw->mii_lock);
/* Switch hard reset */
if (mt753x_hw_reset(gsw))
goto fail;
/* Fetch the SMI address dirst */
if (of_property_read_u32(np, "mediatek,smi-addr", &gsw->smi_addr))
gsw->smi_addr = MT753X_DFL_SMI_ADDR;
/* Get LAN/WAN port mapping */
map = mt753x_find_mapping(np);
if (map) {
mt753x_apply_mapping(gsw, map);
gsw->global_vlan_enable = 1;
dev_info(gsw->dev, "LAN/WAN VLAN setting=%s\n", map->name);
}
/* Load MAC port configurations */
mt753x_load_port_cfg(gsw);
/* Check for valid switch and then initialize */
for (i = 0; i < ARRAY_SIZE(mt753x_sw_ids); i++) {
if (!mt753x_sw_ids[i]->detect(gsw, &rev)) {
sw = mt753x_sw_ids[i];
gsw->name = rev.name;
gsw->model = sw->model;
dev_info(gsw->dev, "Switch is MediaTek %s rev %d",
gsw->name, rev.rev);
/* Initialize the switch */
ret = sw->init(gsw);
if (ret)
goto fail;
break;
}
}
if (i >= ARRAY_SIZE(mt753x_sw_ids)) {
dev_err(gsw->dev, "No mt753x switch found\n");
goto fail;
}
gsw->irq = platform_get_irq(pdev, 0);
if (gsw->irq >= 0) {
ret = devm_request_irq(gsw->dev, gsw->irq, mt753x_irq_handler,
0, dev_name(gsw->dev), gsw);
if (ret) {
dev_err(gsw->dev, "Failed to request irq %d\n",
gsw->irq);
goto fail;
}
INIT_WORK(&gsw->irq_worker, mt753x_irq_worker);
}
platform_set_drvdata(pdev, gsw);
gsw->phy_status_poll = of_property_read_bool(gsw->dev->of_node,
"mediatek,phy-poll");
mt753x_add_gsw(gsw);
mt753x_swconfig_init(gsw);
if (sw->post_init)
sw->post_init(gsw);
if (gsw->irq >= 0)
mt753x_irq_enable(gsw);
return 0;
fail:
devm_kfree(&pdev->dev, gsw);
return ret;
}
static int mt753x_remove(struct platform_device *pdev)
{
struct gsw_mt753x *gsw = platform_get_drvdata(pdev);
if (gsw->irq >= 0)
cancel_work_sync(&gsw->irq_worker);
if (gsw->reset_pin >= 0)
gpio_free(gsw->reset_pin);
#ifdef CONFIG_SWCONFIG
mt753x_swconfig_destroy(gsw);
#endif
mt753x_remove_gsw(gsw);
platform_set_drvdata(pdev, NULL);
return 0;
}
static const struct of_device_id mt753x_ids[] = {
{ .compatible = "mediatek,mt753x" },
{ },
};
MODULE_DEVICE_TABLE(of, mt753x_ids);
static struct platform_driver mt753x_driver = {
.probe = mt753x_probe,
.remove = mt753x_remove,
.driver = {
.name = "mt753x",
.of_match_table = mt753x_ids,
},
};
static int __init mt753x_init(void)
{
int ret;
INIT_LIST_HEAD(&mt753x_devs);
ret = platform_driver_register(&mt753x_driver);
mt753x_nl_init();
return ret;
}
module_init(mt753x_init);
static void __exit mt753x_exit(void)
{
mt753x_nl_exit();
platform_driver_unregister(&mt753x_driver);
}
module_exit(mt753x_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch");

View file

@ -0,0 +1,312 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include "./rtl8367c/include/rtk_switch.h"
#include "./rtl8367c/include/port.h"
#include "./rtl8367c/include/vlan.h"
#include "./rtl8367c/include/rtl8367c_asicdrv_port.h"
struct rtk_gsw {
struct device *dev;
struct mii_bus *bus;
int reset_pin;
};
static struct rtk_gsw *_gsw;
extern int gsw_debug_proc_init(void);
extern void gsw_debug_proc_exit(void);
#ifdef CONFIG_SWCONFIG
extern int rtl8367s_swconfig_init( void (*reset_func)(void) );
#endif
/*mii_mgr_read/mii_mgr_write is the callback API for rtl8367 driver*/
unsigned int mii_mgr_read(unsigned int phy_addr,unsigned int phy_register,unsigned int *read_data)
{
struct mii_bus *bus = _gsw->bus;
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
*read_data = bus->read(bus, phy_addr, phy_register);
mutex_unlock(&bus->mdio_lock);
return 0;
}
unsigned int mii_mgr_write(unsigned int phy_addr,unsigned int phy_register,unsigned int write_data)
{
struct mii_bus *bus = _gsw->bus;
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
bus->write(bus, phy_addr, phy_register, write_data);
mutex_unlock(&bus->mdio_lock);
return 0;
}
static int rtl8367s_hw_reset(void)
{
struct rtk_gsw *gsw = _gsw;
int ret;
if (gsw->reset_pin < 0)
return 0;
ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mediatek,reset-pin");
if (ret)
printk("fail to devm_gpio_request\n");
gpio_direction_output(gsw->reset_pin, 0);
usleep_range(1000, 1100);
gpio_set_value(gsw->reset_pin, 1);
mdelay(500);
gpio_free(gsw->reset_pin);
return 0;
}
static int rtl8367s_vlan_config(int want_at_p0)
{
rtk_vlan_cfg_t vlan1, vlan2;
/* Set LAN/WAN VLAN partition */
memset(&vlan1, 0x00, sizeof(rtk_vlan_cfg_t));
RTK_PORTMASK_PORT_SET(vlan1.mbr, EXT_PORT0);
RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT1);
RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT2);
RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT3);
RTK_PORTMASK_PORT_SET(vlan1.untag, EXT_PORT0);
RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT1);
RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT2);
RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT3);
if (want_at_p0) {
RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT4);
RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT4);
} else {
RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT0);
RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT0);
}
vlan1.ivl_en = 1;
rtk_vlan_set(1, &vlan1);
memset(&vlan2, 0x00, sizeof(rtk_vlan_cfg_t));
RTK_PORTMASK_PORT_SET(vlan2.mbr, EXT_PORT1);
RTK_PORTMASK_PORT_SET(vlan2.untag, EXT_PORT1);
if (want_at_p0) {
RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT0);
RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT0);
} else {
RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT4);
RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT4);
}
vlan2.ivl_en = 1;
rtk_vlan_set(2, &vlan2);
rtk_vlan_portPvid_set(EXT_PORT0, 1, 0);
rtk_vlan_portPvid_set(UTP_PORT1, 1, 0);
rtk_vlan_portPvid_set(UTP_PORT2, 1, 0);
rtk_vlan_portPvid_set(UTP_PORT3, 1, 0);
rtk_vlan_portPvid_set(EXT_PORT1, 2, 0);
if (want_at_p0) {
rtk_vlan_portPvid_set(UTP_PORT0, 2, 0);
rtk_vlan_portPvid_set(UTP_PORT4, 1, 0);
} else {
rtk_vlan_portPvid_set(UTP_PORT0, 1, 0);
rtk_vlan_portPvid_set(UTP_PORT4, 2, 0);
}
return 0;
}
static int rtl8367s_hw_init(void)
{
rtl8367s_hw_reset();
if(rtk_switch_init())
return -1;
mdelay(500);
if (rtk_vlan_reset())
return -1;
if (rtk_vlan_init())
return -1;
return 0;
}
static void set_rtl8367s_sgmii(void)
{
rtk_port_mac_ability_t mac_cfg;
rtk_mode_ext_t mode;
mode = MODE_EXT_HSGMII;
mac_cfg.forcemode = MAC_FORCE;
mac_cfg.speed = PORT_SPEED_2500M;
mac_cfg.duplex = PORT_FULL_DUPLEX;
mac_cfg.link = PORT_LINKUP;
mac_cfg.nway = DISABLED;
mac_cfg.txpause = ENABLED;
mac_cfg.rxpause = ENABLED;
rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg);
rtk_port_sgmiiNway_set(EXT_PORT0, DISABLED);
rtk_port_phyEnableAll_set(ENABLED);
}
static void set_rtl8367s_rgmii(void)
{
rtk_port_mac_ability_t mac_cfg;
rtk_mode_ext_t mode;
mode = MODE_EXT_RGMII;
mac_cfg.forcemode = MAC_FORCE;
mac_cfg.speed = PORT_SPEED_1000M;
mac_cfg.duplex = PORT_FULL_DUPLEX;
mac_cfg.link = PORT_LINKUP;
mac_cfg.nway = DISABLED;
mac_cfg.txpause = ENABLED;
mac_cfg.rxpause = ENABLED;
rtk_port_macForceLinkExt_set(EXT_PORT1, mode, &mac_cfg);
rtk_port_rgmiiDelayExt_set(EXT_PORT1, 1, 3);
rtk_port_phyEnableAll_set(ENABLED);
}
void init_gsw(void)
{
rtl8367s_hw_init();
set_rtl8367s_sgmii();
set_rtl8367s_rgmii();
}
// bleow are platform driver
static const struct of_device_id rtk_gsw_match[] = {
{ .compatible = "mediatek,rtk-gsw" },
{},
};
MODULE_DEVICE_TABLE(of, rtk_gsw_match);
static int rtk_gsw_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *mdio;
struct mii_bus *mdio_bus;
struct rtk_gsw *gsw;
const char *pm;
mdio = of_parse_phandle(np, "mediatek,mdio", 0);
if (!mdio)
return -EINVAL;
mdio_bus = of_mdio_find_bus(mdio);
if (!mdio_bus)
return -EPROBE_DEFER;
gsw = devm_kzalloc(&pdev->dev, sizeof(struct rtk_gsw), GFP_KERNEL);
if (!gsw)
return -ENOMEM;
gsw->dev = &pdev->dev;
gsw->bus = mdio_bus;
gsw->reset_pin = of_get_named_gpio(np, "mediatek,reset-pin", 0);
_gsw = gsw;
init_gsw();
//init default vlan or init swocnfig
if(!of_property_read_string(pdev->dev.of_node,
"mediatek,port_map", &pm)) {
if (!strcasecmp(pm, "wllll"))
rtl8367s_vlan_config(1);
else
rtl8367s_vlan_config(0);
} else {
#ifdef CONFIG_SWCONFIG
rtl8367s_swconfig_init(&init_gsw);
#else
rtl8367s_vlan_config(0);
#endif
}
gsw_debug_proc_init();
platform_set_drvdata(pdev, gsw);
return 0;
}
static int rtk_gsw_remove(struct platform_device *pdev)
{
platform_set_drvdata(pdev, NULL);
gsw_debug_proc_exit();
return 0;
}
static struct platform_driver gsw_driver = {
.probe = rtk_gsw_probe,
.remove = rtk_gsw_remove,
.driver = {
.name = "rtk-gsw",
.owner = THIS_MODULE,
.of_match_table = rtk_gsw_match,
},
};
module_platform_driver(gsw_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mark Lee <marklee0201@gmail.com>");
MODULE_DESCRIPTION("rtl8367c switch driver for MT7622");

View file

@ -0,0 +1,504 @@
CONFIG_64BIT=y
# CONFIG_AHCI_MTK is not set
CONFIG_AQUANTIA_PHY=y
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_FORCE_MAX_ORDER=11
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MEDIATEK=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_ARCH_MMAP_RND_BITS=18
CONFIG_ARCH_MMAP_RND_BITS_MAX=24
CONFIG_ARCH_MMAP_RND_BITS_MIN=18
CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
CONFIG_ARCH_NR_GPIO=0
# CONFIG_ARCH_NXP is not set
CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_STACKWALK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
# CONFIG_ARM64_CNP is not set
# CONFIG_ARM64_ERRATUM_1742098 is not set
# CONFIG_ARM64_ERRATUM_2051678 is not set
# CONFIG_ARM64_ERRATUM_2054223 is not set
# CONFIG_ARM64_ERRATUM_2067961 is not set
# CONFIG_ARM64_ERRATUM_2077057 is not set
# CONFIG_ARM64_ERRATUM_2441007 is not set
# CONFIG_ARM64_ERRATUM_2441009 is not set
# CONFIG_ARM64_ERRATUM_2658417 is not set
CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_ERRATUM_845719=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_MODULE_PLTS=y
CONFIG_ARM64_PAGE_SHIFT=12
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
# CONFIG_ARM64_SW_TTBR0_PAN is not set
CONFIG_ARM64_TAGGED_ADDR_ABI=y
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
# CONFIG_ARMV8_DEPRECATED is not set
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
CONFIG_ARM_GIC=y
CONFIG_ARM_GIC_V2M=y
CONFIG_ARM_GIC_V3=y
CONFIG_ARM_GIC_V3_ITS=y
CONFIG_ARM_GIC_V3_ITS_PCI=y
CONFIG_ARM_MEDIATEK_CPUFREQ=y
CONFIG_ARM_PMU=y
CONFIG_ARM_PSCI_FW=y
CONFIG_ATA=y
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_MQ_PCI=y
CONFIG_BLK_PM=y
CONFIG_BLOCK_COMPAT=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_CLKSRC_MMIO=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_MEDIATEK=y
CONFIG_COMMON_CLK_MT2712=y
# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set
# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set
# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set
# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set
# CONFIG_COMMON_CLK_MT2712_MMSYS is not set
# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set
# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set
# CONFIG_COMMON_CLK_MT6779 is not set
# CONFIG_COMMON_CLK_MT6795 is not set
# CONFIG_COMMON_CLK_MT6797 is not set
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_MT7986 is not set
# CONFIG_COMMON_CLK_MT8173 is not set
# CONFIG_COMMON_CLK_MT8183 is not set
# CONFIG_COMMON_CLK_MT8186 is not set
# CONFIG_COMMON_CLK_MT8195 is not set
# CONFIG_COMMON_CLK_MT8365 is not set
# CONFIG_COMMON_CLK_MT8516 is not set
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_COMPAT=y
CONFIG_COMPAT_32BIT_TIME=y
# CONFIG_COMPAT_ALIGNMENT_FIXUPS is not set
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_COMPAT_NETLINK_MESSAGES=y
CONFIG_COMPAT_OLD_SIGACTION=y
CONFIG_CONFIGFS_FS=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
# CONFIG_CPUFREQ_DT is not set
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_THERMAL=y
CONFIG_CRC16=y
CONFIG_CRYPTO_AES_ARM64=y
CONFIG_CRYPTO_AES_ARM64_CE=y
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_CRC32=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_DRBG=y
CONFIG_CRYPTO_DRBG_HMAC=y
CONFIG_CRYPTO_DRBG_MENU=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_ECC=y
CONFIG_CRYPTO_ECDH=y
CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_HASH_INFO=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_JITTERENTROPY=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_SHA256=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_CRYPTO_LZO=y
# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_RNG_DEFAULT=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA256_ARM64=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y
CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
CONFIG_CRYPTO_ZSTD=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MISC=y
CONFIG_DIMLIB=y
CONFIG_DMADEVICES=y
CONFIG_DMA_DIRECT_REMAP=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DMA_VIRTUAL_CHANNELS=y
CONFIG_DTC=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_FIT_PARTITION=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ARCH_TOPOLOGY=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
CONFIG_GENERIC_CSUM=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOREMAP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_MSI_IRQ=y
CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_PINCTRL_GROUPS=y
CONFIG_GENERIC_PINMUX_FUNCTIONS=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GLOB=y
CONFIG_GPIO_CDEV=y
CONFIG_GRO_CELLS=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
# CONFIG_HISI_PCIE_PMU is not set
# CONFIG_HISI_PTT is not set
# CONFIG_HNS3_PMU is not set
# CONFIG_HP_WATCHDOG is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_CN10K is not set
CONFIG_HW_RANDOM_MTK=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MT65XX=y
CONFIG_ICPLUS_PHY=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_IR_MTK is not set
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_TIME_ACCOUNTING=y
CONFIG_IRQ_WORK=y
CONFIG_JBD2=y
CONFIG_JUMP_LABEL=y
# CONFIG_KEYBOARD_MT6779 is not set
# CONFIG_LEDS_PWM_MULTICOLOR is not set
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LOCK_SPIN_ON_OWNER=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEDIATEK_GE_PHY=y
CONFIG_MEDIATEK_WATCHDOG=y
CONFIG_MEMFD_CREATE=y
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_CQHCI=y
CONFIG_MMC_MTK=y
CONFIG_MODULES_TREE_LOOKUP=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_MEDIATEK=y
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_MTK=y
CONFIG_MTD_NAND_MTK_BMT=y
CONFIG_MTD_PARSER_TRX=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_FASTMAP=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
# CONFIG_MTK_CMDQ is not set
# CONFIG_MTK_CQDMA is not set
CONFIG_MTK_HSDMA=y
CONFIG_MTK_INFRACFG=y
CONFIG_MTK_PMIC_WRAP=y
CONFIG_MTK_SCPSYS=y
CONFIG_MTK_SCPSYS_PM_DOMAINS=y
CONFIG_MTK_THERMAL=y
CONFIG_MTK_TIMER=y
# CONFIG_MTK_UART_APDMA is not set
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MT7530=y
CONFIG_NET_DSA_TAG_MTK=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_MEDIATEK_SOC=y
CONFIG_NET_MEDIATEK_SOC_WED=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_VENDOR_MEDIATEK=y
CONFIG_NLS=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=2
CONFIG_NVMEM=y
# CONFIG_NVMEM_MTK_EFUSE is not set
CONFIG_NVMEM_SYSFS=y
# CONFIG_OCTEON_EP is not set
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_DYNAMIC=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OF_OVERLAY=y
CONFIG_OF_RESOLVE=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PADATA=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_POOL_STATS=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
# CONFIG_PAGE_TABLE_CHECK is not set
CONFIG_PAHOLE_HAS_SPLIT_BTF=y
CONFIG_PAHOLE_VERSION=124
CONFIG_PARTITION_PERCPU=y
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEFAULT is not set
CONFIG_PCIEASPM_PERFORMANCE=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_MEDIATEK=y
CONFIG_PCIE_PME=y
CONFIG_PCI_DEBUG=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_DOMAINS_GENERIC=y
CONFIG_PCI_MSI=y
CONFIG_PCI_MSI_IRQ_DOMAIN=y
CONFIG_PERF_EVENTS=y
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYLIB=y
CONFIG_PHYLINK=y
CONFIG_PHYS_ADDR_T_64BIT=y
# CONFIG_PHY_MTK_DP is not set
# CONFIG_PHY_MTK_PCIE is not set
CONFIG_PHY_MTK_TPHY=y
# CONFIG_PHY_MTK_UFS is not set
# CONFIG_PHY_MTK_XSPHY is not set
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_MT2712 is not set
# CONFIG_PINCTRL_MT6765 is not set
# CONFIG_PINCTRL_MT6795 is not set
# CONFIG_PINCTRL_MT6797 is not set
CONFIG_PINCTRL_MT7622=y
# CONFIG_PINCTRL_MT7986 is not set
# CONFIG_PINCTRL_MT8173 is not set
# CONFIG_PINCTRL_MT8183 is not set
# CONFIG_PINCTRL_MT8186 is not set
# CONFIG_PINCTRL_MT8188 is not set
CONFIG_PINCTRL_MT8516=y
CONFIG_PINCTRL_MTK=y
CONFIG_PINCTRL_MTK_MOORE=y
CONFIG_PINCTRL_MTK_V2=y
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_GENERIC_DOMAINS=y
CONFIG_PM_GENERIC_DOMAINS_OF=y
CONFIG_PM_OPP=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_POWER_SUPPLY=y
# CONFIG_PREEMPT_DYNAMIC is not set
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PRINTK_TIME=y
CONFIG_PSTORE=y
CONFIG_PSTORE_COMPRESS=y
CONFIG_PSTORE_COMPRESS_DEFAULT="deflate"
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_DEFLATE_COMPRESS=y
CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_RAM=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_PWM=y
# CONFIG_PWM_CLK is not set
CONFIG_PWM_MEDIATEK=y
# CONFIG_PWM_MTK_DISP is not set
CONFIG_PWM_SYSFS=y
# CONFIG_PWM_XILINX is not set
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
# CONFIG_RAVE_SP_CORE is not set
CONFIG_REALTEK_PHY=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_MT6380=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_MT7622=y
CONFIG_RTC_I2C_AND_SPI=y
CONFIG_RTL8367S_GSW=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
# CONFIG_SCHED_CLUSTER is not set
CONFIG_SCHED_MC=y
CONFIG_SCSI=y
CONFIG_SCSI_COMMON=y
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_MT6577=y
CONFIG_SERIAL_8250_NR_UARTS=3
CONFIG_SERIAL_8250_RUNTIME_UARTS=3
CONFIG_SERIAL_DEV_BUS=y
CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SGL_ALLOC=y
CONFIG_SG_POOL=y
CONFIG_SMP=y
CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
CONFIG_SPI_DYNAMIC=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SPI_MT65XX=y
CONFIG_SPI_MTK_NOR=y
CONFIG_SPI_MTK_SNFI=y
CONFIG_SRCU=y
# CONFIG_SURFACE_PLATFORMS is not set
CONFIG_SWCONFIG=y
CONFIG_SWIOTLB=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYSVIPC_COMPAT=y
# CONFIG_TEST_DYNAMIC_DEBUG is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_EMULATION=y
CONFIG_THERMAL_GOV_BANG_BANG=y
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_THERMAL_OF=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
# CONFIG_UCLAMP_TASK is not set
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
CONFIG_USB_SUPPORT=y
CONFIG_VMAP_STACK=y
# CONFIG_VMWARE_VMCI is not set
CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set
CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y
CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m
CONFIG_WATCHDOG_SYSFS=y
CONFIG_XPS=y
CONFIG_XXHASH=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
CONFIG_ZSTD_COMMON=y
CONFIG_ZSTD_COMPRESS=y
CONFIG_ZSTD_DECOMPRESS=y

View file

@ -0,0 +1,107 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -1,7 +1,6 @@
/*
- * Copyright (c) 2017 MediaTek Inc.
- * Author: Ming Huang <ming.huang@mediatek.com>
- * Sean Wang <sean.wang@mediatek.com>
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
*
* SPDX-License-Identifier: (GPL-2.0 OR MIT)
*/
@@ -23,7 +22,7 @@
chosen {
stdout-path = "serial0:115200n8";
- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
};
cpus {
@@ -44,18 +43,18 @@
key-factory {
label = "factory";
linux,code = <BTN_0>;
- gpios = <&pio 0 0>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
};
key-wps {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
- gpios = <&pio 102 0>;
+ gpios = <&pio 102 GPIO_ACTIVE_LOW>;
};
};
memory {
- reg = <0 0x40000000 0 0x20000000>;
+ reg = <0 0x40000000 0 0x40000000>;
};
reg_1p8v: regulator-1p8v {
@@ -131,22 +130,22 @@
port@0 {
reg = <0>;
- label = "lan0";
+ label = "lan1";
};
port@1 {
reg = <1>;
- label = "lan1";
+ label = "lan2";
};
port@2 {
reg = <2>;
- label = "lan2";
+ label = "lan3";
};
port@3 {
reg = <3>;
- label = "lan3";
+ label = "lan4";
};
port@4 {
@@ -239,7 +238,22 @@
status = "okay";
};
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins>;
+ status = "okay";
+};
+
&pio {
+ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and
+ * SATA functions. i.e. output-high: PCIe, output-low: SATA
+ */
+ asm_sel {
+ gpio-hog;
+ gpios = <90 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+
/* eMMC is shared pin with parallel NAND */
emmc_pins_default: emmc-pins-default {
mux {
@@ -516,11 +530,11 @@
};
&sata {
- status = "okay";
+ status = "disabled";
};
&sata_phy {
- status = "okay";
+ status = "disabled";
};
&spi0 {

View file

@ -0,0 +1,60 @@
--- a/arch/arm/boot/dts/mt7629-rfb.dts
+++ b/arch/arm/boot/dts/mt7629-rfb.dts
@@ -18,6 +18,7 @@
chosen {
stdout-path = "serial0:115200n8";
+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8";
};
gpio-keys {
@@ -70,6 +71,10 @@
compatible = "mediatek,eth-mac";
reg = <0>;
phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_factory_2a>;
+ nvmem-cell-names = "mac-address";
+
fixed-link {
speed = <2500>;
full-duplex;
@@ -82,6 +87,9 @@
reg = <1>;
phy-mode = "gmii";
phy-handle = <&phy0>;
+
+ nvmem-cells = <&macaddr_factory_24>;
+ nvmem-cell-names = "mac-address";
};
mdio: mdio-bus {
@@ -133,8 +141,9 @@
};
partition@b0000 {
- label = "kernel";
+ label = "firmware";
reg = <0xb0000 0xb50000>;
+ compatible = "denx,fit";
};
};
};
@@ -272,3 +281,17 @@
pinctrl-0 = <&watchdog_pins>;
status = "okay";
};
+
+&factory {
+ compatible = "nvmem-cells";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_24: macaddr@24 {
+ reg = <0x24 0x6>;
+ };
+
+ macaddr_factory_2a: macaddr@2a {
+ reg = <0x2a 0x6>;
+ };
+};

View file

@ -0,0 +1,20 @@
From d6a596012150960f0f3a214d31bbac4b607dbd1e Mon Sep 17 00:00:00 2001
From: Chuanhong Guo <gch981213@gmail.com>
Date: Fri, 29 Apr 2022 10:40:56 +0800
Subject: [PATCH] arm: mediatek: select arch timer for mt7623
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
arch/arm/mach-mediatek/Kconfig | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -26,6 +26,7 @@ config MACH_MT6592
config MACH_MT7623
bool "MediaTek MT7623 SoCs support"
default ARCH_MEDIATEK
+ select HAVE_ARM_ARCH_TIMER
config MACH_MT7629
bool "MediaTek MT7629 SoCs support"

View file

@ -0,0 +1,10 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -558,6 +558,7 @@
compatible = "mediatek,mt7622-nor",
"mediatek,mt8173-nor";
reg = <0 0x11014000 0 0xe0>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_LOW>;
clocks = <&pericfg CLK_PERI_FLASH_PD>,
<&topckgen CLK_TOP_FLASH_SEL>;
clock-names = "spi", "sf";

View file

@ -0,0 +1,25 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -118,7 +118,7 @@
};
psci {
- compatible = "arm,psci-0.2";
+ compatible = "arm,psci-1.0";
method = "smc";
};
@@ -134,6 +134,13 @@
#size-cells = <2>;
ranges;
+ /* 64 KiB reserved for ramoops/pstore */
+ ramoops@42ff0000 {
+ compatible = "ramoops";
+ reg = <0 0x42ff0000 0 0x10000>;
+ record-size = <0x1000>;
+ };
+
/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@43000000 {
reg = <0 0x43000000 0 0x30000>;

View file

@ -0,0 +1,10 @@
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -19,6 +19,7 @@
chosen {
stdout-path = "serial2:115200n8";
+ bootargs = "console=ttyS2,115200n8 console=tty1";
};
connector {

View file

@ -0,0 +1,11 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -22,7 +22,7 @@
chosen {
stdout-path = "serial0:115200n8";
- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512";
+ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512";
};
cpus {

View file

@ -0,0 +1,37 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -18,6 +18,7 @@
aliases {
serial0 = &uart0;
+ ethernet0 = &gmac0;
};
chosen {
@@ -160,22 +161,22 @@
port@1 {
reg = <1>;
- label = "lan0";
+ label = "lan1";
};
port@2 {
reg = <2>;
- label = "lan1";
+ label = "lan2";
};
port@3 {
reg = <3>;
- label = "lan2";
+ label = "lan3";
};
port@4 {
reg = <4>;
- label = "lan3";
+ label = "lan4";
};
port@6 {

View file

@ -0,0 +1,58 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -20,6 +20,10 @@
aliases {
serial0 = &uart0;
ethernet0 = &gmac0;
+ led-boot = &led_system_green;
+ led-failsafe = &led_system_blue;
+ led-running = &led_system_green;
+ led-upgrade = &led_system_blue;
};
chosen {
@@ -43,8 +47,8 @@
compatible = "gpio-keys";
factory-key {
- label = "factory";
- linux,code = <BTN_0>;
+ label = "reset";
+ linux,code = <KEY_RESTART>;
gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
};
@@ -58,19 +62,25 @@
leds {
compatible = "gpio-leds";
- led-0 {
- label = "bpi-r64:pio:green";
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
+ led_system_blue: blue {
+ label = "bpi-r64:pio:blue";
+ gpios = <&pio 85 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
- led-1 {
- label = "bpi-r64:pio:red";
- color = <LED_COLOR_ID_RED>;
- gpios = <&pio 88 GPIO_ACTIVE_HIGH>;
+ led_system_green: green {
+ label = "bpi-r64:pio:green";
+ gpios = <&pio 89 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
+
+/*
+ * red {
+ * label = "bpi-r64:pio:red";
+ * gpios = <&pio 88 GPIO_ACTIVE_HIGH>;
+ * default-state = "off";
+ * };
+ */
};
memory {

View file

@ -0,0 +1,21 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -564,12 +564,16 @@
status = "okay";
};
+&rtc {
+ status = "disabled";
+};
+
&sata {
- status = "disable";
+ status = "disabled";
};
&sata_phy {
- status = "disable";
+ status = "disabled";
};
&spi0 {

View file

@ -0,0 +1,50 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -259,14 +259,42 @@
status = "disabled";
};
-&nor_flash {
- pinctrl-names = "default";
- pinctrl-0 = <&spi_nor_pins>;
- status = "disabled";
+&bch {
+ status = "okay";
+};
+&snfi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&serial_nand_pins>;
+ status = "okay";
flash@0 {
- compatible = "jedec,spi-nor";
+ compatible = "spi-nand";
reg = <0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ nand-ecc-engine = <&snfi>;
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "fip";
+ reg = <0x80000 0x200000>;
+ read-only;
+ };
+
+ partition@280000 {
+ label = "ubi";
+ reg = <0x280000 0x7d80000>;
+ };
+ };
};
};

View file

@ -0,0 +1,20 @@
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -714,7 +714,7 @@ static int spinand_mtd_write(struct mtd_
static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
{
struct spinand_device *spinand = nand_to_spinand(nand);
- u8 marker[2] = { };
+ u8 marker[1] = { };
struct nand_page_io_req req = {
.pos = *pos,
.ooblen = sizeof(marker),
@@ -725,7 +725,7 @@ static bool spinand_isbad(struct nand_de
spinand_select_target(spinand, pos->target);
spinand_read_page(spinand, &req);
- if (marker[0] != 0xff || marker[1] != 0xff)
+ if (marker[0] != 0xff)
return true;
return false;

View file

@ -0,0 +1,94 @@
From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001
From: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
Date: Thu, 6 Jun 2019 16:29:04 +0800
Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629
Signed-off-by: Xiangsheng Hou <xiangsheng.hou@mediatek.com>
---
arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++
arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++
3 files changed, 79 insertions(+)
--- a/arch/arm/boot/dts/mt7629.dtsi
+++ b/arch/arm/boot/dts/mt7629.dtsi
@@ -272,6 +272,27 @@
status = "disabled";
};
+ snfi: spi@1100d000 {
+ compatible = "mediatek,mt7629-snand";
+ reg = <0x1100d000 0x1000>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_NFI_PD>, <&pericfg CLK_PERI_SNFI_PD>;
+ clock-names = "nfi_clk", "pad_clk";
+ nand-ecc-engine = <&bch>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ bch: ecc@1100e000 {
+ compatible = "mediatek,mt7622-ecc";
+ reg = <0x1100e000 0x1000>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_NFIECC_PD>;
+ clock-names = "nfiecc_clk";
+ status = "disabled";
+ };
+
spi: spi@1100a000 {
compatible = "mediatek,mt7629-spi",
"mediatek,mt7622-spi";
--- a/arch/arm/boot/dts/mt7629-rfb.dts
+++ b/arch/arm/boot/dts/mt7629-rfb.dts
@@ -254,6 +254,50 @@
};
};
+&bch {
+ status = "okay";
+};
+
+&snfi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&serial_nand_pins>;
+ status = "okay";
+ flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ nand-ecc-engine = <&snfi>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Bootloader";
+ reg = <0x00000 0x0100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "Config";
+ reg = <0x100000 0x0040000>;
+ };
+
+ partition@140000 {
+ label = "factory";
+ reg = <0x140000 0x0080000>;
+ };
+
+ partition@1c0000 {
+ label = "firmware";
+ reg = <0x1c0000 0x1000000>;
+ };
+ };
+ };
+};
+
&spi {
pinctrl-names = "default";
pinctrl-0 = <&spi_pins>;

View file

@ -0,0 +1,68 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -539,6 +539,65 @@
status = "disabled";
};
+&bch {
+ status = "okay";
+};
+
+&snfi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&serial_nand_pins>;
+ status = "okay";
+ flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ nand-ecc-engine = <&snfi>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Preloader";
+ reg = <0x00000 0x0080000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "ATF";
+ reg = <0x80000 0x0040000>;
+ };
+
+ partition@c0000 {
+ label = "Bootloader";
+ reg = <0xc0000 0x0080000>;
+ };
+
+ partition@140000 {
+ label = "Config";
+ reg = <0x140000 0x0080000>;
+ };
+
+ partition@1c0000 {
+ label = "Factory";
+ reg = <0x1c0000 0x0100000>;
+ };
+
+ partition@200000 {
+ label = "firmware";
+ reg = <0x2c0000 0x2000000>;
+ };
+
+ partition@2200000 {
+ label = "User_data";
+ reg = <0x22c0000 0x4000000>;
+ };
+ };
+ };
+};
+
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spic0_pins>;

View file

@ -0,0 +1,18 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -580,7 +580,7 @@
reg = <0x140000 0x0080000>;
};
- partition@1c0000 {
+ factory: partition@1c0000 {
label = "Factory";
reg = <0x1c0000 0x0100000>;
};
@@ -641,5 +641,6 @@
&wmac {
pinctrl-names = "default";
pinctrl-0 = <&wmac_pins>;
+ mediatek,mtd-eeprom = <&factory 0x0000>;
status = "okay";
};

View file

@ -0,0 +1,24 @@
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -951,17 +951,15 @@
};
crypto: crypto@1b240000 {
- compatible = "mediatek,eip97-crypto";
+ compatible = "inside-secure,safexcel-eip97";
reg = <0 0x1b240000 0 0x20000>;
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>,
- <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>,
- <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
+ <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "ring0", "ring1", "ring2", "ring3";
clocks = <&ethsys CLK_ETHSYS_CRYPTO>;
- clock-names = "cryp";
- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
- status = "disabled";
+ status = "okay";
};
bdpsys: syscon@1c000000 {

View file

@ -0,0 +1,11 @@
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -19,7 +19,7 @@
chosen {
stdout-path = "serial2:115200n8";
- bootargs = "console=ttyS2,115200n8 console=tty1";
+ bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8 console=tty1";
};
connector {

View file

@ -0,0 +1,11 @@
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -15,6 +15,8 @@
aliases {
serial2 = &uart2;
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
};
chosen {

View file

@ -0,0 +1,29 @@
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -17,6 +17,10 @@
serial2 = &uart2;
mmc0 = &mmc0;
mmc1 = &mmc1;
+ led-boot = &led_system_green;
+ led-failsafe = &led_system_blue;
+ led-running = &led_system_green;
+ led-upgrade = &led_system_blue;
};
chosen {
@@ -112,13 +116,13 @@
pinctrl-names = "default";
pinctrl-0 = <&led_pins_a>;
- blue {
+ led_system_blue: blue {
label = "bpi-r2:pio:blue";
gpios = <&pio 240 GPIO_ACTIVE_LOW>;
default-state = "off";
};
- green {
+ led_system_green: green {
label = "bpi-r2:pio:green";
gpios = <&pio 241 GPIO_ACTIVE_LOW>;
default-state = "off";

View file

@ -0,0 +1,10 @@
--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts
@@ -15,6 +15,7 @@
aliases {
serial2 = &uart2;
+ ethernet0 = &gmac0;
mmc0 = &mmc0;
mmc1 = &mmc1;
led-boot = &led_system_green;

View file

@ -0,0 +1,69 @@
From 21d106f15262f5a2ef7531636e0703ee61c33c61 Mon Sep 17 00:00:00 2001
From: Sungbo Eo <mans0n@gorani.run>
Date: Sun, 8 Aug 2021 21:38:40 +0900
Subject: [PATCH 2/2] arm: dts: mt7623: add musb device nodes
MT7623 has an musb controller that is compatible with the one from MT2701.
Signed-off-by: Sungbo Eo <mans0n@gorani.run>
---
arch/arm/boot/dts/mt7623.dtsi | 34 ++++++++++++++++++++++++++++++++++
arch/arm/boot/dts/mt7623a.dtsi | 4 ++++
2 files changed, 38 insertions(+)
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -585,6 +585,40 @@
status = "disabled";
};
+ usb0: usb@11200000 {
+ compatible = "mediatek,mt7623-musb",
+ "mediatek,mtk-musb";
+ reg = <0 0x11200000 0 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "mc";
+ phys = <&u2port2 PHY_TYPE_USB2>;
+ dr_mode = "otg";
+ clocks = <&pericfg CLK_PERI_USB0>,
+ <&pericfg CLK_PERI_USB0_MCU>,
+ <&pericfg CLK_PERI_USB_SLV>;
+ clock-names = "main","mcu","univpll";
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
+ status = "disabled";
+ };
+
+ u2phy1: t-phy@11210000 {
+ compatible = "mediatek,mt7623-tphy",
+ "mediatek,generic-tphy-v1";
+ reg = <0 0x11210000 0 0x0800>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ status = "disabled";
+
+ u2port2: usb-phy@11210800 {
+ reg = <0 0x11210800 0 0x0100>;
+ clocks = <&topckgen CLK_TOP_USB_PHY48M>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+ status = "okay";
+ };
+ };
+
audsys: clock-controller@11220000 {
compatible = "mediatek,mt7623-audsys",
"mediatek,mt2701-audsys",
--- a/arch/arm/boot/dts/mt7623a.dtsi
+++ b/arch/arm/boot/dts/mt7623a.dtsi
@@ -35,6 +35,10 @@
clock-names = "ethif";
};
+&usb0 {
+ power-domains = <&scpsys MT7623A_POWER_DOMAIN_IFR_MSC>;
+};
+
&usb1 {
power-domains = <&scpsys MT7623A_POWER_DOMAIN_HIF>;
};

View file

@ -0,0 +1,13 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -160,6 +160,10 @@
switch@0 {
compatible = "mediatek,mt7531";
reg = <0>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
reset-gpios = <&pio 54 0>;
ports {

View file

@ -0,0 +1,106 @@
From patchwork Tue Apr 26 19:51:36 2022
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
X-Patchwork-Id: 12827872
Return-Path:
<linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
Received: from bombadil.infradead.org (bombadil.infradead.org
[198.137.202.133])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(No client certificate requested)
by smtp.lore.kernel.org (Postfix) with ESMTPS id BACF3C433EF
for <linux-arm-kernel@archiver.kernel.org>;
Tue, 26 Apr 2022 19:53:05 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
d=lists.infradead.org; s=bombadil.20210309; h=Sender:
Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:
List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:Cc:To:
From:Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:
Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:
List-Owner; bh=OWGSxvlKoyPWz6b629RNINucULo6oOdFssAIiJETWRg=; b=T0HEjee0FX3hlb
x5jl7xLK5sKM0pkE2oRgwzthbFlNg8ST1j/2GkgcgT0S2Bi0vRfFxHeu/RKzS9RmiVnKJnPGL8ctg
WoBLyO5i+NcmosGoy6MmoOjGTNhj/+3q3Z1jRLBSJ4ySSP22X77YeuJTmVzySPUllQhWvDhjMVCR9
QBRmQdc6gCAg3IYGEbWwS2TG+UHveDCeZRWxMzrwI8UPadNCRFROwugmiQ3mdU41lHCTDpnlfuRJh
o1igLKfMBLz+D8rFYvDh7FfkcKkY6lNoswA2HKUun1MEzgoyQKmITPnG2maX/BvJJuj/B3ZJShh4k
AZHmXoQxq1mrsm2FxfnQ==;
Received: from localhost ([::1] helo=bombadil.infradead.org)
by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux))
id 1njRE5-00G05D-9z; Tue, 26 Apr 2022 19:51:57 +0000
Received: from fudo.makrotopia.org ([2a07:2ec0:3002::71])
by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux))
id 1njRE1-00G03h-9H; Tue, 26 Apr 2022 19:51:55 +0000
Received: from local
by fudo.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256)
(Exim 4.94.2) (envelope-from <daniel@makrotopia.org>)
id 1njRDu-0006aF-4F; Tue, 26 Apr 2022 21:51:46 +0200
Date: Tue, 26 Apr 2022 20:51:36 +0100
From: Daniel Golle <daniel@makrotopia.org>
To: devicetree@vger.kernel.org, linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Matthias Brugger <matthias.bgg@gmail.com>
Subject: [PATCH] arm64: dts: mediatek: mt7622: fix GICv2 range
Message-ID: <YmhNSLgp/yg8Vr1F@makrotopia.org>
MIME-Version: 1.0
Content-Disposition: inline
X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
X-CRM114-CacheID: sfid-20220426_125153_359242_EA3D452C
X-CRM114-Status: GOOD ( 12.45 )
X-BeenThere: linux-arm-kernel@lists.infradead.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: <linux-arm-kernel.lists.infradead.org>
List-Unsubscribe:
<http://lists.infradead.org/mailman/options/linux-arm-kernel>,
<mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
List-Subscribe:
<http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
<mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
Errors-To:
linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org
With the current range specified for the CPU interface there is an
error message at boot:
GIC: GICv2 detected, but range too small and irqchip.gicv2_force_probe not set
Setting irqchip.gicv2_force_probe=1 in bootargs results in:
GIC: Aliased GICv2 at 0x0000000010320000, trying to find the canonical range over 128kB
GIC: Adjusting CPU interface base to 0x000000001032f000
GIC: Using split EOI/Deactivate mode
Using the adjusted CPU interface base and 8K size results in only the
final line remaining and fully working system as well as /proc/interrupts
showing additional IPI3,4,5,6:
IPI3: 0 0 CPU stop (for crash dump) interrupts
IPI4: 0 0 Timer broadcast interrupts
IPI5: 0 0 IRQ work interrupts
IPI6: 0 0 CPU wake-up interrupts
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
arch/arm64/boot/dts/mediatek/mt7622.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -339,7 +339,7 @@
#interrupt-cells = <3>;
interrupt-parent = <&gic>;
reg = <0 0x10310000 0 0x1000>,
- <0 0x10320000 0 0x1000>,
+ <0 0x1032f000 0 0x2000>,
<0 0x10340000 0 0x2000>,
<0 0x10360000 0 0x2000>;
};

View file

@ -0,0 +1,48 @@
From 824d56e753a588fcfd650db1822e34a02a48bb77 Mon Sep 17 00:00:00 2001
From: Bruno Umuarama <anonimou_eu@hotmail.com>
Date: Thu, 13 Oct 2022 21:18:21 +0000
Subject: [PATCH] mediatek: mt7623: fix thermal zone
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Raising the temperatures for passive and active trips. @VA1DER
proposed at issue 9396 to remove passive trip. This commit relates to
his suggestion.
Without this patch. the CPU will be throttled all the way down to 98MHz
if the temperature rises even a degree above the trip point, and it was
further discovered that if the internal temperature of the device is
above the first trip point temperature when it boots then it will start
in a throttled state and even
$ echo disabled > /sys/class/thermal/thermal_zone0/mode
will have no effect.
The patch increases the passive trip point and active cooling map. The
throttling temperature will then be at 77°C and 82°C, which is still a
low enough temperature for ARM devices to not be in the real danger
zone, and gives some operational headroom.
Signed-off-by: Bruno Umuarama <anonimou_eu@hotmail.com>
---
arch/arm/boot/dts/mt7623.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm/boot/dts/mt7623.dtsi
+++ b/arch/arm/boot/dts/mt7623.dtsi
@@ -160,13 +160,13 @@
trips {
cpu_passive: cpu-passive {
- temperature = <57000>;
+ temperature = <77000>;
hysteresis = <2000>;
type = "passive";
};
cpu_active: cpu-active {
- temperature = <67000>;
+ temperature = <82000>;
hysteresis = <2000>;
type = "active";
};

View file

@ -0,0 +1,66 @@
From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001
From: Kristian Evensen <kristian.evensen@gmail.com>
Date: Mon, 30 Apr 2018 14:38:01 +0200
Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support
---
drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -17,6 +17,8 @@
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include "phy-mtk-io.h"
@@ -264,6 +266,9 @@
#define TPHY_CLKS_CNT 2
+#define HIF_SYSCFG1 0x14
+#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20)
+
enum mtk_phy_version {
MTK_PHY_V1 = 1,
MTK_PHY_V2,
@@ -331,6 +336,7 @@ struct mtk_tphy {
void __iomem *sif_base; /* only shared sif */
const struct mtk_phy_pdata *pdata;
struct mtk_phy_instance **phys;
+ struct regmap *hif;
int nphys;
int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */
int src_coef; /* coefficient for slew rate calibrate */
@@ -596,6 +602,10 @@ static void pcie_phy_instance_init(struc
if (tphy->pdata->version != MTK_PHY_V1)
return;
+ if (tphy->hif)
+ regmap_update_bits(tphy->hif, HIF_SYSCFG1,
+ HIF_SYSCFG1_PHY2_MASK, 0);
+
mtk_phy_update_bits(phya + U3P_U3_PHYA_DA_REG0,
P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) |
@@ -1241,6 +1251,16 @@ static int mtk_tphy_probe(struct platfor
&tphy->src_coef);
}
+ if (of_find_property(np, "mediatek,phy-switch", NULL)) {
+ tphy->hif = syscon_regmap_lookup_by_phandle(np,
+ "mediatek,phy-switch");
+ if (IS_ERR(tphy->hif)) {
+ dev_err(&pdev->dev,
+ "missing \"mediatek,phy-switch\" phandle\n");
+ return PTR_ERR(tphy->hif);
+ }
+ }
+
port = 0;
for_each_child_of_node(np, child_np) {
struct mtk_phy_instance *instance;

View file

@ -0,0 +1,44 @@
From 1a7963e9843f6f1e4b02a30926d20b314c03e4df Mon Sep 17 00:00:00 2001
From: Sam Shih <sam.shih@mediatek.com>
Date: Sat, 25 Jun 2022 02:10:13 +0800
Subject: [PATCH] mmc: mediatek: add support for MT7986 SoC
Adding mt7986 own characteristics and of_device_id to have support
of MT7986 SoC.
Signed-off-by: Sam Shih <sam.shih@mediatek.com>
Change-Id: I07cf8406cbe8c1a7114b304f35fc3e689e512e5a
---
drivers/mmc/host/mtk-sd.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -591,6 +591,19 @@ static const struct mtk_mmc_compatible m
.support_64g = true,
};
+static const struct mtk_mmc_compatible mt7986_compat = {
+ .clk_div_bits = 12,
+ .recheck_sdio_irq = true,
+ .hs400_tune = false,
+ .pad_tune_reg = MSDC_PAD_TUNE0,
+ .async_fifo = true,
+ .data_tune = true,
+ .busy_check = true,
+ .stop_clk_fix = true,
+ .enhance_rx = true,
+ .support_64g = true,
+};
+
static const struct mtk_mmc_compatible mt8516_compat = {
.clk_div_bits = 12,
.recheck_sdio_irq = true,
@@ -609,6 +622,7 @@ static const struct of_device_id msdc_of
{ .compatible = "mediatek,mt6795-mmc", .data = &mt6795_compat},
{ .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
{ .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
+ { .compatible = "mediatek,mt7986-mmc", .data = &mt7986_compat},
{ .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat},
{ .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat},
{ .compatible = "mediatek,mt8183-mmc", .data = &mt8183_compat},

View file

@ -0,0 +1,34 @@
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -19,6 +19,7 @@
#include <linux/string.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
+#include <linux/mtd/mtk_bmt.h>
static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
{
@@ -1333,6 +1334,7 @@ static int spinand_probe(struct spi_mem
if (ret)
return ret;
+ mtk_bmt_attach(mtd);
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
goto err_spinand_cleanup;
@@ -1340,6 +1342,7 @@ static int spinand_probe(struct spi_mem
return 0;
err_spinand_cleanup:
+ mtk_bmt_detach(mtd);
spinand_cleanup(spinand);
return ret;
@@ -1358,6 +1361,7 @@ static int spinand_remove(struct spi_mem
if (ret)
return ret;
+ mtk_bmt_detach(mtd);
spinand_cleanup(spinand);
return 0;

View file

@ -0,0 +1,10 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -553,6 +553,7 @@
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
nand-ecc-engine = <&snfi>;
+ mediatek,bmt-v2;
partitions {
compatible = "fixed-partitions";

View file

@ -0,0 +1,122 @@
From 5f49a5c9b16330e0df8f639310e4715dcad71947 Mon Sep 17 00:00:00 2001
From: Davide Fioravanti <pantanastyle@gmail.com>
Date: Fri, 8 Jan 2021 15:35:24 +0100
Subject: [PATCH] mtd: spinand: Add support for the Fidelix FM35X1GA
Datasheet: http://www.hobos.com.cn/upload/datasheet/DS35X1GAXXX_100_rev00.pdf
Signed-off-by: Davide Fioravanti <pantanastyle@gmail.com>
---
drivers/mtd/nand/spi/Makefile | 2 +-
drivers/mtd/nand/spi/core.c | 1 +
drivers/mtd/nand/spi/fidelix.c | 76 ++++++++++++++++++++++++++++++++++
include/linux/mtd/spinand.h | 1 +
4 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/nand/spi/fidelix.c
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o ato.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
+spinand-objs := core.o ato.o esmt.o etron.o fidelix.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -940,6 +940,7 @@ static const struct nand_ops spinand_ops
static const struct spinand_manufacturer *spinand_manufacturers[] = {
&ato_spinand_manufacturer,
&esmt_c8_spinand_manufacturer,
+ &fidelix_spinand_manufacturer,
&etron_spinand_manufacturer,
&gigadevice_spinand_manufacturer,
&macronix_spinand_manufacturer,
--- /dev/null
+++ b/drivers/mtd/nand/spi/fidelix.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2020 Davide Fioravanti <pantanastyle@gmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_FIDELIX 0xE5
+#define FIDELIX_ECCSR_MASK 0x0F
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int fm35x1ga_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ region->offset = (16 * section) + 8;
+ region->length = 8;
+
+ return 0;
+}
+
+static int fm35x1ga_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section > 3)
+ return -ERANGE;
+
+ region->offset = (16 * section) + 2;
+ region->length = 6;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops fm35x1ga_ooblayout = {
+ .ecc = fm35x1ga_ooblayout_ecc,
+ .free = fm35x1ga_ooblayout_free,
+};
+
+static const struct spinand_info fidelix_spinand_table[] = {
+ SPINAND_INFO("FM35X1GA",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&fm35x1ga_ooblayout, NULL)),
+};
+
+static const struct spinand_manufacturer_ops fidelix_spinand_manuf_ops = {
+};
+
+const struct spinand_manufacturer fidelix_spinand_manufacturer = {
+ .id = SPINAND_MFR_FIDELIX,
+ .name = "Fidelix",
+ .chips = fidelix_spinand_table,
+ .nchips = ARRAY_SIZE(fidelix_spinand_table),
+ .ops = &fidelix_spinand_manuf_ops,
+};
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -263,6 +263,7 @@ struct spinand_manufacturer {
extern const struct spinand_manufacturer ato_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
extern const struct spinand_manufacturer etron_spinand_manufacturer;
+extern const struct spinand_manufacturer fidelix_spinand_manufacturer;
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
extern const struct spinand_manufacturer micron_spinand_manufacturer;

View file

@ -0,0 +1,27 @@
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
@@ -600,6 +600,14 @@ static int safexcel_hw_init(struct safex
val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
}
+ /*
+ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3
+ */
+ else {
+ val = 0;
+ val |= EIP97_MST_CTRL_TX_MAX_CMD(4);
+ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
+ }
/* Configure wr/rd cache values */
writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -315,6 +315,7 @@
#define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0)
#define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4)
#define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20)
+#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4)
#define EIP197_MST_CTRL_BYTE_SWAP BIT(24)
#define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25)
#define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24)

View file

@ -0,0 +1,26 @@
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -737,6 +737,9 @@ enum safexcel_eip_version {
/* Priority we use for advertising our algorithms */
#define SAFEXCEL_CRA_PRIORITY 300
+/* System cache line size */
+#define SYSTEM_CACHELINE_SIZE 64
+
/* SM3 digest result for zero length message */
#define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \
"\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \
--- a/drivers/crypto/inside-secure/safexcel_hash.c
+++ b/drivers/crypto/inside-secure/safexcel_hash.c
@@ -55,9 +55,9 @@ struct safexcel_ahash_req {
u8 block_sz; /* block size, only set once */
u8 digest_sz; /* output digest size, only set once */
__le32 state[SHA3_512_BLOCK_SIZE /
- sizeof(__le32)] __aligned(sizeof(__le32));
+ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE);
- u64 len;
+ u64 len __aligned(SYSTEM_CACHELINE_SIZE);
u64 processed;
u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32));

View file

@ -0,0 +1,41 @@
From f6ba5e17bee38f8ffe118c47fbfef3cf90eb87ff Mon Sep 17 00:00:00 2001
From: "Mingming.Su" <Mingming.Su@mediatek.com>
Date: Wed, 30 Jun 2021 16:59:32 +0800
Subject: [PATCH] mt7986: trng: add rng support
1. Add trng compatible name for MT7986
2. Fix mtk_rng_wait_ready() function
Signed-off-by: Mingming.Su <Mingming.Su@mediatek.com>
---
drivers/char/hw_random/mtk-rng.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/char/hw_random/mtk-rng.c
+++ b/drivers/char/hw_random/mtk-rng.c
@@ -22,7 +22,7 @@
#define RNG_AUTOSUSPEND_TIMEOUT 100
#define USEC_POLL 2
-#define TIMEOUT_POLL 20
+#define TIMEOUT_POLL 60
#define RNG_CTRL 0x00
#define RNG_EN BIT(0)
@@ -77,7 +77,7 @@ static bool mtk_rng_wait_ready(struct hw
readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready,
ready & RNG_READY, USEC_POLL,
TIMEOUT_POLL);
- return !!ready;
+ return !!(ready & RNG_READY);
}
static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
@@ -179,6 +179,7 @@ static const struct dev_pm_ops mtk_rng_p
#endif /* CONFIG_PM */
static const struct of_device_id mtk_rng_match[] = {
+ { .compatible = "mediatek,mt7986-rng" },
{ .compatible = "mediatek,mt7623-rng" },
{},
};

View file

@ -0,0 +1,33 @@
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -85,6 +85,7 @@ struct serial8250_config {
#define UART_CAP_MINI BIT(17) /* Mini UART on BCM283X family lacks:
* STOP PARITY EPAR SPAR WLEN5 WLEN6
*/
+#define UART_CAP_NMOD (1 << 18) /* UART doesn't do termios */
#define UART_CAP_NOTEMT BIT(18) /* UART without interrupt on TEMT available */
#define UART_BUG_QUOT BIT(0) /* UART has buggy quot LSB */
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -286,7 +286,7 @@ static const struct serial8250_config ua
.tx_loadsz = 16,
.fcr = UART_FCR_ENABLE_FIFO |
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
- .flags = UART_CAP_FIFO,
+ .flags = UART_CAP_FIFO | UART_CAP_NMOD,
},
[PORT_NPCM] = {
.name = "Nuvoton 16550",
@@ -2754,6 +2754,11 @@ serial8250_do_set_termios(struct uart_po
unsigned long flags;
unsigned int baud, quot, frac = 0;
+ if (up->capabilities & UART_CAP_NMOD) {
+ termios->c_cflag = 0;
+ return;
+ }
+
if (up->capabilities & UART_CAP_MINI) {
termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR);
if ((termios->c_cflag & CSIZE) == CS5 ||

View file

@ -0,0 +1,27 @@
From: David Bauer <mail@david-bauer.net>
To: linux-mtd@lists.infradead.org
Subject: [PATCH] mtd: spi-nor: add support for Winbond W25Q512JV
Date: Sat, 13 Feb 2021 16:10:47 +0100
The Winbond W25Q512JV is a 512mb SPI-NOR chip. It supports 4K
sectors as well as block protection and Dual-/Quad-read.
Tested on: Ubiquiti UniFi 6 LR
Signed-off-by: David Bauer <mail@david-bauer.net>
---
drivers/mtd/spi-nor/winbond.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -130,6 +130,9 @@ static const struct flash_info winbond_n
{ "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_READ) },
+ { "w25q512jv", INFO(0xef4020, 0, 64 * 1024, 1024)
+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6 | SPI_NOR_4BIT_BP)
+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_QUAD_READ |
SPI_NOR_DUAL_READ) },

View file

@ -0,0 +1,25 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -366,6 +366,12 @@ config ROCKCHIP_PHY
help
Currently supports the integrated Ethernet PHY.
+config RTL8367S_GSW
+ tristate "rtl8367 Gigabit Switch support for mt7622"
+ depends on NET_VENDOR_MEDIATEK
+ help
+ This driver supports rtl8367s in mt7622
+
config SMSC_PHY
tristate "SMSC PHYs"
help
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_RENESAS_PHY) += uPD60620.o
obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
+obj-$(CONFIG_RTL8367S_GSW) += rtk/
obj-$(CONFIG_SMSC_PHY) += smsc.o
obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_TERANETICS_PHY) += teranetics.o

View file

@ -0,0 +1,34 @@
From: qizhong cheng <qizhong.cheng@mediatek.com>
Date: Mon, 27 Dec 2021 21:31:10 +0800
Subject: [PATCH] PCI: mediatek: Assert PERST# for 100ms for power and clock to
stabilize
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
be delayed 100ms (TPVPERL) for the power and clock to become stable.
Link: https://lore.kernel.org/r/20211227133110.14500-1-qizhong.cheng@mediatek.com
Signed-off-by: qizhong cheng <qizhong.cheng@mediatek.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Pali Rohár <pali@kernel.org>
---
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -702,6 +702,13 @@ static int mtk_pcie_startup_port_v2(stru
*/
writel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL);
+ /*
+ * Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
+ * 2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
+ * be delayed 100ms (TPVPERL) for the power and clock to become stable.
+ */
+ msleep(100);
+
/* De-assert PHY, PE, PIPE, MAC and configuration reset */
val = readl(port->base + PCIE_RST_CTRL);
val |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |

View file

@ -0,0 +1,28 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -848,6 +848,12 @@
#address-cells = <0>;
#interrupt-cells = <1>;
};
+
+ slot0: pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ };
};
pcie1: pcie@1a145000 {
@@ -886,6 +892,12 @@
#address-cells = <0>;
#interrupt-cells = <1>;
};
+
+ slot1: pcie@1,0 {
+ reg = <0x0800 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ };
};
sata: sata@1a200000 {

View file

@ -0,0 +1,23 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Fri, 4 Sep 2020 18:33:27 +0200
Subject: [PATCH] pcie-mediatek: fix clearing interrupt status
Clearing the status needs to happen after running the handler, otherwise
we will get an extra spurious interrupt after the cause has been cleared
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -614,9 +614,9 @@ static void mtk_pcie_intr_handler(struct
if (status & INTX_MASK) {
for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) {
/* Clear the INTx */
- writel(1 << bit, port->base + PCIE_INT_STATUS);
generic_handle_domain_irq(port->irq_domain,
bit - INTX_SHIFT);
+ writel(1 << bit, port->base + PCIE_INT_STATUS);
}
}

View file

@ -0,0 +1,82 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Fri, 4 Sep 2020 18:42:42 +0200
Subject: [PATCH] pci: pcie-mediatek: add support for coherent DMA
It improves performance by eliminating the need for a cache flush for DMA on
attached devices
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -836,6 +836,9 @@
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>;
status = "disabled";
+ dma-coherent;
+ mediatek,hifsys = <&hifsys>;
+ mediatek,cci-control = <&cci_control2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -880,6 +883,9 @@
bus-range = <0x00 0xff>;
ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>;
status = "disabled";
+ dma-coherent;
+ mediatek,hifsys = <&hifsys>;
+ mediatek,cci-control = <&cci_control2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -20,6 +20,7 @@
#include <linux/of_address.h>
#include <linux/of_pci.h>
#include <linux/of_platform.h>
+#include <linux/of_address.h>
#include <linux/pci.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
@@ -139,6 +140,11 @@
#define PCIE_LINK_STATUS_V2 0x804
#define PCIE_PORT_LINKUP_V2 BIT(10)
+/* DMA channel mapping */
+#define HIFSYS_DMA_AG_MAP 0x008
+#define HIFSYS_DMA_AG_MAP_PCIE0 BIT(0)
+#define HIFSYS_DMA_AG_MAP_PCIE1 BIT(1)
+
struct mtk_pcie_port;
/**
@@ -1054,6 +1060,27 @@ static int mtk_pcie_setup(struct mtk_pci
struct mtk_pcie_port *port, *tmp;
int err, slot;
+ if (of_dma_is_coherent(node)) {
+ struct regmap *con;
+ u32 mask;
+
+ con = syscon_regmap_lookup_by_phandle(node,
+ "mediatek,cci-control");
+ /* enable CPU/bus coherency */
+ if (!IS_ERR(con))
+ regmap_write(con, 0, 3);
+
+ con = syscon_regmap_lookup_by_phandle(node,
+ "mediatek,hifsys");
+ if (IS_ERR(con)) {
+ dev_err(dev, "missing hifsys node\n");
+ return PTR_ERR(con);
+ }
+
+ mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1;
+ regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask);
+ }
+
slot = of_get_pci_domain_nr(dev->of_node);
if (slot < 0) {
for_each_available_child_of_node(node, child) {

View file

@ -0,0 +1,27 @@
From: Jip de Beer <gpk6x3591g0l@opayq.com>
Date: Sun, 9 Jan 2022 13:14:04 +0100
Subject: [PATCH] mediatek mt7622: fix 300mhz typo in dts
The lowest frequency should be 300MHz, since that is the label
assigned to the OPP in the mt7622.dtsi device tree, while there is one
missing zero in the actual value.
To be clear, the lowest frequency should be 300MHz instead of 30MHz.
As mentioned @dangowrt on the OpenWrt forum there is no benefit in
leaving 30MHz as the lowest frequency.
Signed-off-by: Jip de Beer <gpk6x3591g0l@opayq.com>
Signed-off-by: Fritz D. Ansel <fdansel@yandex.ru>
---
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -24,7 +24,7 @@
compatible = "operating-points-v2";
opp-shared;
opp-300000000 {
- opp-hz = /bits/ 64 <30000000>;
+ opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <950000>;
};

View file

@ -0,0 +1,25 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -23,11 +23,17 @@
cpu_opp_table: opp-table {
compatible = "operating-points-v2";
opp-shared;
- opp-300000000 {
- opp-hz = /bits/ 64 <300000000>;
- opp-microvolt = <950000>;
- };
-
+ /* Due to the bug described at the link below, remove the 300 MHz clock to avoid a low
+ * voltage condition that can cause a hang when rebooting the RT3200/E8450.
+ *
+ * https://forum.openwrt.org/t/belkin-rt3200-linksys-e8450-wifi-ax-discussion/94302/1490
+ *
+ * opp-300000000 {
+ * opp-hz = /bits/ 64 <300000000>;
+ * opp-microvolt = <950000>;
+ * };
+ *
+ */
opp-437500000 {
opp-hz = /bits/ 64 <437500000>;
opp-microvolt = <1000000>;

View file

@ -0,0 +1,30 @@
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -431,6 +431,19 @@ static const struct mtk_i2c_compatible m
.max_dma_support = 33,
};
+static const struct mtk_i2c_compatible mt7986_compat = {
+ .quirks = &mt7622_i2c_quirks,
+ .regs = mt_i2c_regs_v1,
+ .pmic_i2c = 0,
+ .dcm = 1,
+ .auto_restart = 1,
+ .aux_len_reg = 1,
+ .max_dma_support = 32,
+ .timing_adjust = 0,
+ .dma_sync = 1,
+ .ltiming_adjust = 0,
+};
+
static const struct mtk_i2c_compatible mt8173_compat = {
.regs = mt_i2c_regs_v1,
.pmic_i2c = 0,
@@ -503,6 +516,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,mt7986-i2c", .data = &mt7986_compat },
{ .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },

View file

@ -0,0 +1,23 @@
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -302,6 +302,12 @@ static const struct pwm_mediatek_of_data
.has_ck_26m_sel = true,
};
+static const struct pwm_mediatek_of_data mt7986_pwm_data = {
+ .num_pwms = 2,
+ .pwm45_fixup = false,
+ .has_ck_26m_sel = true,
+};
+
static const struct pwm_mediatek_of_data mt8516_pwm_data = {
.num_pwms = 5,
.pwm45_fixup = false,
@@ -314,6 +320,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,mt7986-pwm", .data = &mt7986_pwm_data },
{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
{ },

View file

@ -0,0 +1,223 @@
From cd47d86ab09f1f3ec5c86441d4fe95e0cf597c06 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 13 Sep 2022 00:56:24 +0100
Subject: [PATCH] thermal/drivers/mediatek: add support for MT7986 and MT7981
Add support for V3 generation thermal found in MT7986 and MT7981 SoCs.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/thermal/mtk_thermal.c | 202 +++++++++++++++++++++++++++++++++-
1 file changed, 198 insertions(+), 4 deletions(-)
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -150,6 +150,21 @@
#define CALIB_BUF1_VALID_V2(x) (((x) >> 4) & 0x1)
#define CALIB_BUF1_O_SLOPE_SIGN_V2(x) (((x) >> 3) & 0x1)
+/*
+ * Layout of the fuses providing the calibration data
+ * These macros could be used for MT7981 and MT7986.
+ */
+#define CALIB_BUF0_ADC_GE_V3(x) (((x) >> 0) & 0x3ff)
+#define CALIB_BUF0_ADC_OE_V3(x) (((x) >> 10) & 0x3ff)
+#define CALIB_BUF0_DEGC_CALI_V3(x) (((x) >> 20) & 0x3f)
+#define CALIB_BUF0_O_SLOPE_V3(x) (((x) >> 26) & 0x3f)
+#define CALIB_BUF1_VTS_TS1_V3(x) (((x) >> 0) & 0x1ff)
+#define CALIB_BUF1_VTS_TS2_V3(x) (((x) >> 21) & 0x1ff)
+#define CALIB_BUF1_VTS_TSABB_V3(x) (((x) >> 9) & 0x1ff)
+#define CALIB_BUF1_VALID_V3(x) (((x) >> 18) & 0x1)
+#define CALIB_BUF1_O_SLOPE_SIGN_V3(x) (((x) >> 19) & 0x1)
+#define CALIB_BUF1_ID_V3(x) (((x) >> 20) & 0x1)
+
enum {
VTS1,
VTS2,
@@ -163,6 +178,7 @@ enum {
enum mtk_thermal_version {
MTK_THERMAL_V1 = 1,
MTK_THERMAL_V2,
+ MTK_THERMAL_V3,
};
/* MT2701 thermal sensors */
@@ -245,6 +261,27 @@ enum mtk_thermal_version {
/* The calibration coefficient of sensor */
#define MT8183_CALIBRATION 153
+/* AUXADC channel 11 is used for the temperature sensors */
+#define MT7986_TEMP_AUXADC_CHANNEL 11
+
+/* The total number of temperature sensors in the MT7986 */
+#define MT7986_NUM_SENSORS 1
+
+/* The number of banks in the MT7986 */
+#define MT7986_NUM_ZONES 1
+
+/* The number of sensing points per bank */
+#define MT7986_NUM_SENSORS_PER_ZONE 1
+
+/* MT7986 thermal sensors */
+#define MT7986_TS1 0
+
+/* The number of controller in the MT7986 */
+#define MT7986_NUM_CONTROLLER 1
+
+/* The calibration coefficient of sensor */
+#define MT7986_CALIBRATION 165
+
struct mtk_thermal;
struct thermal_bank_cfg {
@@ -386,6 +423,14 @@ static const int mt7622_mux_values[MT762
static const int mt7622_vts_index[MT7622_NUM_SENSORS] = { VTS1 };
static const int mt7622_tc_offset[MT7622_NUM_CONTROLLER] = { 0x0, };
+/* MT7986 thermal sensor data */
+static const int mt7986_bank_data[MT7986_NUM_SENSORS] = { MT7986_TS1, };
+static const int mt7986_msr[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_MSR0, };
+static const int mt7986_adcpnp[MT7986_NUM_SENSORS_PER_ZONE] = { TEMP_ADCPNP0, };
+static const int mt7986_mux_values[MT7986_NUM_SENSORS] = { 0, };
+static const int mt7986_vts_index[MT7986_NUM_SENSORS] = { VTS1 };
+static const int mt7986_tc_offset[MT7986_NUM_CONTROLLER] = { 0x0, };
+
/*
* The MT8173 thermal controller has four banks. Each bank can read up to
* four temperature sensors simultaneously. The MT8173 has a total of 5
@@ -549,6 +594,30 @@ static const struct mtk_thermal_data mt8
.version = MTK_THERMAL_V1,
};
+/*
+ * MT7986 uses AUXADC Channel 11 for raw data access.
+ */
+static const struct mtk_thermal_data mt7986_thermal_data = {
+ .auxadc_channel = MT7986_TEMP_AUXADC_CHANNEL,
+ .num_banks = MT7986_NUM_ZONES,
+ .num_sensors = MT7986_NUM_SENSORS,
+ .vts_index = mt7986_vts_index,
+ .cali_val = MT7986_CALIBRATION,
+ .num_controller = MT7986_NUM_CONTROLLER,
+ .controller_offset = mt7986_tc_offset,
+ .need_switch_bank = true,
+ .bank_data = {
+ {
+ .num_sensors = 1,
+ .sensors = mt7986_bank_data,
+ },
+ },
+ .msr = mt7986_msr,
+ .adcpnp = mt7986_adcpnp,
+ .sensor_mux_values = mt7986_mux_values,
+ .version = MTK_THERMAL_V3,
+};
+
/**
* raw_to_mcelsius - convert a raw ADC value to mcelsius
* @mt: The thermal controller
@@ -603,6 +672,22 @@ static int raw_to_mcelsius_v2(struct mtk
return (format_2 - tmp) * 100;
}
+static int raw_to_mcelsius_v3(struct mtk_thermal *mt, int sensno, s32 raw)
+{
+ s32 tmp;
+
+ if (raw == 0)
+ return 0;
+
+ raw &= 0xfff;
+ tmp = 100000 * 15 / 16 * 10000;
+ tmp /= 4096 - 512 + mt->adc_ge;
+ tmp /= 1490;
+ tmp *= raw - mt->vts[sensno] - 2900 - mt->adc_oe + 512;
+
+ return mt->degc_cali * 500 - tmp;
+}
+
/**
* mtk_thermal_get_bank - get bank
* @bank: The bank
@@ -659,9 +744,12 @@ static int mtk_thermal_bank_temperature(
if (mt->conf->version == MTK_THERMAL_V1) {
temp = raw_to_mcelsius_v1(
mt, conf->bank_data[bank->id].sensors[i], raw);
- } else {
+ } else if (mt->conf->version == MTK_THERMAL_V2) {
temp = raw_to_mcelsius_v2(
mt, conf->bank_data[bank->id].sensors[i], raw);
+ } else {
+ temp = raw_to_mcelsius_v3(
+ mt, conf->bank_data[bank->id].sensors[i], raw);
}
/*
@@ -887,6 +975,26 @@ static int mtk_thermal_extract_efuse_v2(
return 0;
}
+static int mtk_thermal_extract_efuse_v3(struct mtk_thermal *mt, u32 *buf)
+{
+ if (!CALIB_BUF1_VALID_V3(buf[1]))
+ return -EINVAL;
+
+ mt->adc_oe = CALIB_BUF0_ADC_OE_V3(buf[0]);
+ mt->adc_ge = CALIB_BUF0_ADC_GE_V3(buf[0]);
+ mt->degc_cali = CALIB_BUF0_DEGC_CALI_V3(buf[0]);
+ mt->o_slope = CALIB_BUF0_O_SLOPE_V3(buf[0]);
+ mt->vts[VTS1] = CALIB_BUF1_VTS_TS1_V3(buf[1]);
+ mt->vts[VTS2] = CALIB_BUF1_VTS_TS2_V3(buf[1]);
+ mt->vts[VTSABB] = CALIB_BUF1_VTS_TSABB_V3(buf[1]);
+ mt->o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN_V3(buf[1]);
+
+ if (CALIB_BUF1_ID_V3(buf[1]) == 0)
+ mt->o_slope = 0;
+
+ return 0;
+}
+
static int mtk_thermal_get_calibration_data(struct device *dev,
struct mtk_thermal *mt)
{
@@ -897,6 +1005,7 @@ static int mtk_thermal_get_calibration_d
/* Start with default values */
mt->adc_ge = 512;
+ mt->adc_oe = 512;
for (i = 0; i < mt->conf->num_sensors; i++)
mt->vts[i] = 260;
mt->degc_cali = 40;
@@ -924,8 +1033,10 @@ static int mtk_thermal_get_calibration_d
if (mt->conf->version == MTK_THERMAL_V1)
ret = mtk_thermal_extract_efuse_v1(mt, buf);
- else
+ else if (mt->conf->version == MTK_THERMAL_V2)
ret = mtk_thermal_extract_efuse_v2(mt, buf);
+ else
+ ret = mtk_thermal_extract_efuse_v3(mt, buf);
if (ret) {
dev_info(dev, "Device not calibrated, using default calibration values\n");
@@ -956,6 +1067,10 @@ static const struct of_device_id mtk_the
.data = (void *)&mt7622_thermal_data,
},
{
+ .compatible = "mediatek,mt7986-thermal",
+ .data = (void *)&mt7986_thermal_data,
+ },
+ {
.compatible = "mediatek,mt8183-thermal",
.data = (void *)&mt8183_thermal_data,
}, {
@@ -1070,7 +1185,8 @@ static int mtk_thermal_probe(struct plat
goto err_disable_clk_auxadc;
}
- if (mt->conf->version == MTK_THERMAL_V2) {
+ if (mt->conf->version == MTK_THERMAL_V2 ||
+ mt->conf->version == MTK_THERMAL_V3) {
mtk_thermal_turn_on_buffer(apmixed_base);
mtk_thermal_release_periodic_ts(mt, auxadc_base);
}

View file

@ -0,0 +1,65 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -318,7 +318,7 @@
/* Attention: GPIO 90 is used to switch between PCIe@1,0 and
* SATA functions. i.e. output-high: PCIe, output-low: SATA
*/
- asm_sel {
+ asmsel: asm_sel {
gpio-hog;
gpios = <90 GPIO_ACTIVE_HIGH>;
output-high;
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-sata.dts
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "bananapi,bpi-r64", "mediatek,mt7622";
+
+ fragment@0 {
+ target = <&asmsel>;
+ __overlay__ {
+ gpios = <90 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ fragment@1 {
+ target = <&sata>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+
+ fragment@2 {
+ target = <&sata_phy>;
+ __overlay__ {
+ status = "okay";
+ };
+ };
+};
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-pcie1.dts
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "bananapi,bpi-r64", "mediatek,mt7622";
+
+ fragment@0 {
+ target = <&asmsel>;
+ __overlay__ {
+ gpios = <90 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};

View file

@ -0,0 +1,37 @@
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1729,6 +1729,14 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
endchoice
+config CMDLINE_OVERRIDE
+ bool "Use alternative cmdline from device tree"
+ help
+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can
+ be used, this is not a good option for kernels that are shared across
+ devices. This setting enables using "chosen/cmdline-override" as the
+ cmdline if it exists in the device tree.
+
config CMDLINE
string "Default kernel command string"
default ""
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1162,6 +1162,17 @@ int __init early_init_dt_scan_chosen(uns
if (p != NULL && l > 0)
strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE));
+ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different
+ * device tree option of chosen/bootargs-override. This is
+ * helpful on boards where u-boot sets bootargs, and is unable
+ * to be modified.
+ */
+#ifdef CONFIG_CMDLINE_OVERRIDE
+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
+ if (p != NULL && l > 0)
+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE));
+#endif
+
/*
* CONFIG_CMDLINE is meant to be a default in case nothing else
* managed to set the command line, unless CONFIG_CMDLINE_FORCE

View file

@ -0,0 +1,31 @@
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -645,5 +645,28 @@
};
&wmac {
+ mediatek,eeprom-data = <0x22760500 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x44000020 0x0 0x10002000
+ 0x4400 0x4000000 0x0 0x0
+ 0x200000b3 0x40b6c3c3 0x26000000 0x41c42600
+ 0x41c4 0x26000000 0xc0c52600 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0xc6c6
+ 0xc3c3c2c1 0xc300c3 0x818181 0x83c1c182
+ 0x83838382 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x84002e00 0x90000087 0x8a000000 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0xb000009 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x0
+ 0x0 0x0 0x0 0x7707>;
+
status = "okay";
};

View file

@ -0,0 +1,240 @@
From 71fd1c93f34b21e79ef18e83ce8fd40566fd7a71 Mon Sep 17 00:00:00 2001
From: Nick Hainke <vincent@systemli.org>
Date: Mon, 7 Nov 2022 13:09:29 +0100
Subject: [PATCH] Revert "cpufreq: mediatek: Refine
mtk_cpufreq_voltage_tracking()"
This reverts commit 6a17b3876bc8303612d7ad59ecf7cbc0db418bcd.
---
drivers/cpufreq/mediatek-cpufreq.c | 147 +++++++++++++++++++----------
1 file changed, 96 insertions(+), 51 deletions(-)
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index 7f2680bc9a0f..4466d0c91a6a 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -8,7 +8,6 @@
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
-#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
@@ -16,6 +15,8 @@
#include <linux/pm_opp.h>
#include <linux/regulator/consumer.h>
+#define VOLT_TOL (10000)
+
struct mtk_cpufreq_platform_data {
int min_volt_shift;
int max_volt_shift;
@@ -55,7 +56,6 @@ struct mtk_cpu_dvfs_info {
unsigned int opp_cpu;
unsigned long current_freq;
const struct mtk_cpufreq_platform_data *soc_data;
- int vtrack_max;
bool ccifreq_bound;
};
@@ -82,7 +82,6 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
struct regulator *proc_reg = info->proc_reg;
struct regulator *sram_reg = info->sram_reg;
int pre_vproc, pre_vsram, new_vsram, vsram, vproc, ret;
- int retry = info->vtrack_max;
pre_vproc = regulator_get_voltage(proc_reg);
if (pre_vproc < 0) {
@@ -90,44 +89,91 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
"invalid Vproc value: %d\n", pre_vproc);
return pre_vproc;
}
+ /* Vsram should not exceed the maximum allowed voltage of SoC. */
+ new_vsram = min(new_vproc + soc_data->min_volt_shift,
+ soc_data->sram_max_volt);
+
+ if (pre_vproc < new_vproc) {
+ /*
+ * When scaling up voltages, Vsram and Vproc scale up step
+ * by step. At each step, set Vsram to (Vproc + 200mV) first,
+ * then set Vproc to (Vsram - 100mV).
+ * Keep doing it until Vsram and Vproc hit target voltages.
+ */
+ do {
+ pre_vsram = regulator_get_voltage(sram_reg);
+ if (pre_vsram < 0) {
+ dev_err(info->cpu_dev,
+ "invalid Vsram value: %d\n", pre_vsram);
+ return pre_vsram;
+ }
+ pre_vproc = regulator_get_voltage(proc_reg);
+ if (pre_vproc < 0) {
+ dev_err(info->cpu_dev,
+ "invalid Vproc value: %d\n", pre_vproc);
+ return pre_vproc;
+ }
- pre_vsram = regulator_get_voltage(sram_reg);
- if (pre_vsram < 0) {
- dev_err(info->cpu_dev, "invalid Vsram value: %d\n", pre_vsram);
- return pre_vsram;
- }
+ vsram = min(new_vsram,
+ pre_vproc + soc_data->min_volt_shift);
- new_vsram = clamp(new_vproc + soc_data->min_volt_shift,
- soc_data->sram_min_volt, soc_data->sram_max_volt);
+ if (vsram + VOLT_TOL >= soc_data->sram_max_volt) {
+ vsram = soc_data->sram_max_volt;
- do {
- if (pre_vproc <= new_vproc) {
- vsram = clamp(pre_vproc + soc_data->max_volt_shift,
- soc_data->sram_min_volt, new_vsram);
- ret = regulator_set_voltage(sram_reg, vsram,
- soc_data->sram_max_volt);
+ /*
+ * If the target Vsram hits the maximum voltage,
+ * try to set the exact voltage value first.
+ */
+ ret = regulator_set_voltage(sram_reg, vsram,
+ vsram);
+ if (ret)
+ ret = regulator_set_voltage(sram_reg,
+ vsram - VOLT_TOL,
+ vsram);
- if (ret)
- return ret;
-
- if (vsram == soc_data->sram_max_volt ||
- new_vsram == soc_data->sram_min_volt)
vproc = new_vproc;
- else
+ } else {
+ ret = regulator_set_voltage(sram_reg, vsram,
+ vsram + VOLT_TOL);
+
vproc = vsram - soc_data->min_volt_shift;
+ }
+ if (ret)
+ return ret;
ret = regulator_set_voltage(proc_reg, vproc,
- soc_data->proc_max_volt);
+ vproc + VOLT_TOL);
if (ret) {
regulator_set_voltage(sram_reg, pre_vsram,
- soc_data->sram_max_volt);
+ pre_vsram);
return ret;
}
- } else if (pre_vproc > new_vproc) {
+ } while (vproc < new_vproc || vsram < new_vsram);
+ } else if (pre_vproc > new_vproc) {
+ /*
+ * When scaling down voltages, Vsram and Vproc scale down step
+ * by step. At each step, set Vproc to (Vsram - 200mV) first,
+ * then set Vproc to (Vproc + 100mV).
+ * Keep doing it until Vsram and Vproc hit target voltages.
+ */
+ do {
+ pre_vproc = regulator_get_voltage(proc_reg);
+ if (pre_vproc < 0) {
+ dev_err(info->cpu_dev,
+ "invalid Vproc value: %d\n", pre_vproc);
+ return pre_vproc;
+ }
+ pre_vsram = regulator_get_voltage(sram_reg);
+ if (pre_vsram < 0) {
+ dev_err(info->cpu_dev,
+ "invalid Vsram value: %d\n", pre_vsram);
+ return pre_vsram;
+ }
+
vproc = max(new_vproc,
pre_vsram - soc_data->max_volt_shift);
ret = regulator_set_voltage(proc_reg, vproc,
- soc_data->proc_max_volt);
+ vproc + VOLT_TOL);
if (ret)
return ret;
@@ -137,24 +183,32 @@ static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
vsram = max(new_vsram,
vproc + soc_data->min_volt_shift);
- ret = regulator_set_voltage(sram_reg, vsram,
- soc_data->sram_max_volt);
+ if (vsram + VOLT_TOL >= soc_data->sram_max_volt) {
+ vsram = soc_data->sram_max_volt;
+
+ /*
+ * If the target Vsram hits the maximum voltage,
+ * try to set the exact voltage value first.
+ */
+ ret = regulator_set_voltage(sram_reg, vsram,
+ vsram);
+ if (ret)
+ ret = regulator_set_voltage(sram_reg,
+ vsram - VOLT_TOL,
+ vsram);
+ } else {
+ ret = regulator_set_voltage(sram_reg, vsram,
+ vsram + VOLT_TOL);
+ }
+
if (ret) {
regulator_set_voltage(proc_reg, pre_vproc,
- soc_data->proc_max_volt);
+ pre_vproc);
return ret;
}
- }
-
- pre_vproc = vproc;
- pre_vsram = vsram;
-
- if (--retry < 0) {
- dev_err(info->cpu_dev,
- "over loop count, failed to set voltage\n");
- return -EINVAL;
- }
- } while (vproc != new_vproc || vsram != new_vsram);
+ } while (vproc > new_vproc + VOLT_TOL ||
+ vsram > new_vsram + VOLT_TOL);
+ }
return 0;
}
@@ -250,8 +304,8 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
* If the new voltage or the intermediate voltage is higher than the
* current voltage, scale up voltage first.
*/
- target_vproc = max(inter_vproc, vproc);
- if (pre_vproc <= target_vproc) {
+ target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
+ if (pre_vproc < target_vproc) {
ret = mtk_cpufreq_set_voltage(info, target_vproc);
if (ret) {
dev_err(cpu_dev,
@@ -513,15 +567,6 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
*/
info->need_voltage_tracking = (info->sram_reg != NULL);
- /*
- * We assume min voltage is 0 and tracking target voltage using
- * min_volt_shift for each iteration.
- * The vtrack_max is 3 times of expeted iteration count.
- */
- info->vtrack_max = 3 * DIV_ROUND_UP(max(info->soc_data->sram_max_volt,
- info->soc_data->proc_max_volt),
- info->soc_data->min_volt_shift);
-
return 0;
out_disable_inter_clock:
--
2.38.1

View file

@ -661,12 +661,23 @@ if [ "$OMR_KERNEL" = "6.1" ]; then
echo "Set to kernel 6.1 for bcm27xx" echo "Set to kernel 6.1 for bcm27xx"
find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.15%KERNEL_PATCHVER:=6.1%g' {} \; find target/linux/bcm27xx -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.15%KERNEL_PATCHVER:=6.1%g' {} \;
echo "Done" echo "Done"
echo "Set to kernel 6.1 for mvebu"
find target/linux/mvebu -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.15%KERNEL_PATCHVER:=6.1%g' {} \;
echo "Done"
echo "Set to kernel 6.1 for mediatek"
find target/linux/mediatek -type f -name Makefile -exec sed -i 's%KERNEL_PATCHVER:=5.15%KERNEL_PATCHVER:=6.1%g' {} \;
echo "Done"
rm -f package/kernel/rtl8812au-ct/patches/002-* rm -f package/kernel/rtl8812au-ct/patches/002-*
rm -f package/kernel/rtl8812au-ct/patches/003-* rm -f package/kernel/rtl8812au-ct/patches/003-*
rm -f package/kernel/rtl8812au-ct/patches/004-* rm -f package/kernel/rtl8812au-ct/patches/004-*
rm -f package/kernel/rtl8812au-ct/patches/100-api_update.patch rm -f package/kernel/rtl8812au-ct/patches/100-api_update.patch
rm -f target/linux/bcm27xx/modules/sound.mk rm -f target/linux/bcm27xx/modules/sound.mk
rm -f package/libs/elfutils/patches/101-no-fts.patch rm -f package/libs/elfutils/patches/101-no-fts.patch
rm -f package/kernel/mwlwifi/patches/001-*
rm -f package/kernel/mwlwifi/patches/002-*
rm -f package/kernel/mwlwifi/patches/003-*
rm -rf package/kernel/mt76
# echo "CONFIG_DEVEL=y" >> ".config" # echo "CONFIG_DEVEL=y" >> ".config"
# echo "CONFIG_NEED_TOOLCHAIN=y" >> ".config" # echo "CONFIG_NEED_TOOLCHAIN=y" >> ".config"
# echo "CONFIG_TOOLCHAINOPTS=y" >> ".config" # echo "CONFIG_TOOLCHAINOPTS=y" >> ".config"
@ -681,7 +692,7 @@ if [ "$OMR_KERNEL" = "6.1" ]; then
if [ "$TARGET" = "bpi-r2" ]; then if [ "$TARGET" = "bpi-r2" ]; then
echo "# CONFIG_VERSION_CODE_FILENAMES is not set" >> ".config" echo "# CONFIG_VERSION_CODE_FILENAMES is not set" >> ".config"
fi fi
if [ "$OMR_TARGET" != "x86" ] && [ "$OMR_TARGET" != "x86_64" ] && [ "$OMR_TARGET" != "r4s" ] && [ "$OMR_TARGET" != "r5s" ] && [ "$OMR_TARGET" != "qnap-301w" ] && [ "$OMR_TARGET" != "rpi4" ]; then if [ "$OMR_TARGET" != "x86" ] && [ "$OMR_TARGET" != "x86_64" ] && [ "$OMR_TARGET" != "r4s" ] && [ "$OMR_TARGET" != "r5s" ] && [ "$OMR_TARGET" != "qnap-301w" ] && [ "$OMR_TARGET" != "rpi4" ] && [ "$OMR_TARGET" != "rpi3" ] && [ "$OMR_TARGET" != "wrt32x" ] && [ "$OMR_TARGET" != "wrt3200acm" ] && [ "$OMR_TARGET" != "bpi-r64" ]; then
echo "Sorry but kernel 6.1 is not supported on your arch yet" echo "Sorry but kernel 6.1 is not supported on your arch yet"
NOT_SUPPORTED="1" NOT_SUPPORTED="1"
#exit 1 #exit 1