[][openwrt][update the patches in accordance with the new naming rules]
[Description]
Change all mtk patches in accordance with the new naming rules
"999-20xx-" : Basic Part
"999-21xx-" : Slow Speed I/O
"999-22xx-" : Slow Speed I/O
"999-23xx-" : SPI & Storage
"999-24xx-" : SPI & Storage
"999-25xx-" : Advanced features
"999-26xx-" : High Speed I/O
"999-27xx-" : Networking
"999-28xx-" : MISC
"999-29xx-" : Uncategorized
[Release-log]
N/A
Change-Id: I245da3b0e5b7299b42473c20cc6f0899cffc1ad2
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7530987
diff --git a/target/linux/mediatek/patches-5.4/999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch b/target/linux/mediatek/patches-5.4/999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch
new file mode 100644
index 0000000..1f958e8
--- /dev/null
+++ b/target/linux/mediatek/patches-5.4/999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch
@@ -0,0 +1,307 @@
+From 004157ce74543694981c461e95ac0cc1fa8721d7 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:25 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch]
+
+---
+ drivers/phy/mediatek/phy-mtk-tphy.c | 195 ++++++++++++++++++++++++++++
+ 1 file changed, 195 insertions(+)
+
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index c6e073401..fcf8c845f 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -12,6 +12,7 @@
+ #include <linux/iopoll.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/module.h>
++#include <linux/nvmem-consumer.h>
+ #include <linux/of_address.h>
+ #include <linux/of_device.h>
+ #include <linux/phy/phy.h>
+@@ -41,11 +42,16 @@
+ #define SSUSB_SIFSLV_V2_U3PHYD 0x200
+ #define SSUSB_SIFSLV_V2_U3PHYA 0x400
+
++#define U3P_MISC_REG1 0x04
++#define MR1_EFUSE_AUTO_LOAD_DIS BIT(6)
++
+ #define U3P_USBPHYACR0 0x000
+ #define PA0_RG_U2PLL_FORCE_ON BIT(15)
+ #define PA0_RG_USB20_INTR_EN BIT(5)
+
+ #define U3P_USBPHYACR1 0x004
++#define PA1_RG_INTR_CAL GENMASK(23, 19)
++#define PA1_RG_INTR_CAL_VAL(x) ((0x1f & (x)) << 19)
+ #define PA1_RG_VRT_SEL GENMASK(14, 12)
+ #define PA1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12)
+ #define PA1_RG_TERM_SEL GENMASK(10, 8)
+@@ -117,6 +123,8 @@
+ #define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
+
+ #define U3P_U3_PHYA_REG0 0x000
++#define P3A_RG_IEXT_INTR GENMASK(15, 10)
++#define P3A_RG_IEXT_INTR_VAL(x) ((0x3f & (x)) << 10)
+ #define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
+ #define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
+
+@@ -171,6 +179,25 @@
+ #define P3D_RG_FWAKE_TH GENMASK(21, 16)
+ #define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
+
++#define U3P_U3_PHYD_IMPCAL0 0x010
++#define P3D_RG_FORCE_TX_IMPEL BIT(31)
++#define P3D_RG_TX_IMPEL GENMASK(28, 24)
++#define P3D_RG_TX_IMPEL_VAL(x) ((0x1f & (x)) << 24)
++
++#define U3P_U3_PHYD_IMPCAL1 0x014
++#define P3D_RG_FORCE_RX_IMPEL BIT(31)
++#define P3D_RG_RX_IMPEL GENMASK(28, 24)
++#define P3D_RG_RX_IMPEL_VAL(x) ((0x1f & (x)) << 24)
++
++#define U3P_U3_PHYD_RX0 0x02c
++
++#define U3P_U3_PHYD_T2RLB 0x030
++
++#define U3P_U3_PHYD_PIPE0 0x040
++
++#define U3P_U3_PHYD_RSV 0x054
++#define P3D_RG_EFUSE_AUTO_LOAD_DIS BIT(12)
++
+ #define U3P_U3_PHYD_CDR1 0x05c
+ #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
+ #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
+@@ -280,11 +307,23 @@
+ enum mtk_phy_version {
+ MTK_PHY_V1 = 1,
+ MTK_PHY_V2,
++ MTK_PHY_V3,
+ };
+
+ struct mtk_phy_pdata {
+ /* avoid RX sensitivity level degradation only for mt8173 */
+ bool avoid_rx_sen_degradation;
++ /*
++ * u2phy should use integer mode instead of fractional mode of
++ * 48M PLL, fix it by switching PLL to 26M from default 48M
++ * for mt8195
++ */
++ bool sx_pll_48m_to_26m;
++ /*
++ * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse,
++ * support sw way, also support it for v2/v3 optionally.
++ */
++ bool sw_efuse_supported;
+ enum mtk_phy_version version;
+ };
+
+@@ -309,6 +348,10 @@ struct mtk_phy_instance {
+ struct u3phy_banks u3_banks;
+ };
+ struct clk *ref_clk; /* reference clock of anolog phy */
++ u32 efuse_sw_en;
++ u32 efuse_intr;
++ u32 efuse_tx_imp;
++ u32 efuse_rx_imp;
+ u32 index;
+ u32 type;
+ struct regmap *type_sw;
+@@ -970,6 +1013,139 @@ static int phy_type_set(struct mtk_phy_instance *instance)
+ return 0;
+ }
+
++static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
++{
++ struct device *dev = &instance->phy->dev;
++ int ret = 0;
++
++ dev_err(dev, "try to get sw efuse\n");
++
++ /* tphy v1 doesn't support sw efuse, skip it */
++ if (!tphy->pdata->sw_efuse_supported) {
++ instance->efuse_sw_en = 0;
++ return 0;
++ }
++
++ /* software efuse is optional */
++ instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells");
++ if (!instance->efuse_sw_en)
++ return 0;
++
++ dev_err(dev, "try to get sw efuse+\n");
++
++ switch (instance->type) {
++ case PHY_TYPE_USB2:
++ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
++ if (ret) {
++ dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
++ break;
++ }
++
++ /* no efuse, ignore it */
++ if (!instance->efuse_intr) {
++ dev_warn(dev, "no u2 intr efuse, but dts enable it\n");
++ instance->efuse_sw_en = 0;
++ break;
++ }
++
++ dev_info(dev, "u2 efuse - intr %x\n", instance->efuse_intr);
++ break;
++ case PHY_TYPE_USB3:
++ case PHY_TYPE_PCIE:
++ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
++ if (ret) {
++ dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
++ break;
++ }
++
++ ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp);
++ if (ret) {
++ dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret);
++ break;
++ }
++
++ ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp);
++ if (ret) {
++ dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret);
++ break;
++ }
++
++ /* no efuse, ignore it */
++ if (!instance->efuse_intr &&
++ !instance->efuse_rx_imp &&
++ !instance->efuse_tx_imp) {
++ dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
++ instance->efuse_sw_en = 0;
++ break;
++ }
++
++ dev_info(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
++ instance->efuse_intr, instance->efuse_rx_imp,
++ instance->efuse_tx_imp);
++ break;
++ default:
++ dev_err(dev, "no sw efuse for type %d\n", instance->type);
++ ret = -EINVAL;
++ }
++
++ return ret;
++}
++
++static void phy_efuse_set(struct mtk_phy_instance *instance)
++{
++ struct device *dev = &instance->phy->dev;
++ struct u2phy_banks *u2_banks = &instance->u2_banks;
++ struct u3phy_banks *u3_banks = &instance->u3_banks;
++ u32 tmp;
++
++ if (!instance->efuse_sw_en)
++ return;
++
++ switch (instance->type) {
++ case PHY_TYPE_USB2:
++ tmp = readl(u2_banks->misc + U3P_MISC_REG1);
++ tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
++ writel(tmp, u2_banks->misc + U3P_MISC_REG1);
++
++ tmp = readl(u2_banks->com + U3P_USBPHYACR1);
++ tmp &= ~PA1_RG_INTR_CAL;
++ tmp |= PA1_RG_INTR_CAL_VAL(instance->efuse_intr);
++ writel(tmp, u2_banks->com + U3P_USBPHYACR1);
++ pr_err("%s set efuse intr %x\n", __func__, instance->efuse_intr);
++
++ break;
++ case PHY_TYPE_USB3:
++ case PHY_TYPE_PCIE:
++ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
++ tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
++ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
++
++ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
++ tmp &= ~P3D_RG_TX_IMPEL;
++ tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp);
++ tmp |= P3D_RG_FORCE_TX_IMPEL;
++ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
++
++ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
++ tmp &= ~P3D_RG_RX_IMPEL;
++ tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp);
++ tmp |= P3D_RG_FORCE_RX_IMPEL;
++ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
++
++ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
++ tmp &= ~P3A_RG_IEXT_INTR;
++ tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr);
++ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
++ pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
++ __func__, instance->efuse_tx_imp,
++ instance->efuse_rx_imp, instance->efuse_intr);
++ break;
++ default:
++ dev_warn(dev, "no sw efuse for type %d\n", instance->type);
++ }
++}
++
++
+ static int mtk_phy_init(struct phy *phy)
+ {
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy);
+@@ -988,6 +1164,8 @@ static int mtk_phy_init(struct phy *phy)
+ return ret;
+ }
+
++ phy_efuse_set(instance);
++
+ switch (instance->type) {
+ case PHY_TYPE_USB2:
+ u2_phy_instance_init(tphy, instance);
+@@ -1072,6 +1250,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+ struct mtk_phy_instance *instance = NULL;
+ struct device_node *phy_np = args->np;
+ int index;
++ int ret;
+
+ if (args->args_count != 1) {
+ dev_err(dev, "invalid number of cells in 'phy' property\n");
+@@ -1108,6 +1287,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+ return ERR_PTR(-EINVAL);
+ }
+
++ ret = phy_efuse_get(tphy, instance);
++ if (ret)
++ return ERR_PTR(ret);
++
+ phy_parse_property(tphy, instance);
+ phy_type_set(instance);
+
+@@ -1130,14 +1313,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
+
+ static const struct mtk_phy_pdata tphy_v2_pdata = {
+ .avoid_rx_sen_degradation = false,
++ .sw_efuse_supported = true,
+ .version = MTK_PHY_V2,
+ };
+
++static const struct mtk_phy_pdata tphy_v3_pdata = {
++ .sw_efuse_supported = true,
++ .version = MTK_PHY_V3,
++};
++
+ static const struct mtk_phy_pdata mt8173_pdata = {
+ .avoid_rx_sen_degradation = true,
+ .version = MTK_PHY_V1,
+ };
+
++static const struct mtk_phy_pdata mt8195_pdata = {
++ .sx_pll_48m_to_26m = true,
++ .sw_efuse_supported = true,
++ .version = MTK_PHY_V3,
++};
++
+ static const struct of_device_id mtk_tphy_id_table[] = {
+ { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
+ { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
+--
+2.34.1
+