blob: 1c6711f422c9d3205275a28942275de01e5eb97c [file] [log] [blame]
developer8cdcb262022-10-27 14:36:15 +08001From 2abe803824f0331c42eb9853199d5f147cee3a06 Mon Sep 17 00:00:00 2001
developer44e1bbf2022-01-28 17:20:00 +08002From: Zhanyong Wang <zhanyong.wang@mediatek.com>
3Date: Tue, 25 Jan 2022 16:50:47 +0800
developer8cdcb262022-10-27 14:36:15 +08004Subject: [PATCH 3/8] phy: phy-mtk-tphy: Add PCIe 2 lane efuse support
developer44e1bbf2022-01-28 17:20:00 +08005
6Add PCIe 2 lane efuse support in tphy driver.
7
8Signed-off-by: Jie Yang <jieyy.yang@mediatek.com>
9Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
10---
11 drivers/phy/mediatek/phy-mtk-tphy.c | 140 ++++++++++++++++++++++++++++
12 1 file changed, 140 insertions(+)
13
14diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
developer8cdcb262022-10-27 14:36:15 +080015index ce2731b2f5ff..b855e759b0da 100644
developer44e1bbf2022-01-28 17:20:00 +080016--- a/drivers/phy/mediatek/phy-mtk-tphy.c
17+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
developer8cdcb262022-10-27 14:36:15 +080018@@ -40,6 +40,15 @@
developer44e1bbf2022-01-28 17:20:00 +080019 #define SSUSB_SIFSLV_V2_U3PHYD 0x200
20 #define SSUSB_SIFSLV_V2_U3PHYA 0x400
21
22+/* version V4 sub-banks offset base address */
23+/* pcie phy banks */
24+#define SSUSB_SIFSLV_V4_SPLLC 0x000
25+#define SSUSB_SIFSLV_V4_CHIP 0x100
26+#define SSUSB_SIFSLV_V4_U3PHYD 0x900
27+#define SSUSB_SIFSLV_V4_U3PHYA 0xb00
28+
29+#define SSUSB_LN1_OFFSET 0x10000
30+
31 #define U3P_MISC_REG1 0x04
32 #define MR1_EFUSE_AUTO_LOAD_DIS BIT(6)
33
developer8cdcb262022-10-27 14:36:15 +080034@@ -303,6 +312,7 @@ enum mtk_phy_version {
developer44e1bbf2022-01-28 17:20:00 +080035 MTK_PHY_V1 = 1,
36 MTK_PHY_V2,
37 MTK_PHY_V3,
38+ MTK_PHY_V4,
39 };
40
41 struct mtk_phy_pdata {
developer8cdcb262022-10-27 14:36:15 +080042@@ -347,6 +357,9 @@ struct mtk_phy_instance {
developer44e1bbf2022-01-28 17:20:00 +080043 u32 efuse_intr;
44 u32 efuse_tx_imp;
45 u32 efuse_rx_imp;
46+ u32 efuse_intr_ln1;
47+ u32 efuse_tx_imp_ln1;
48+ u32 efuse_rx_imp_ln1;
49 u32 index;
developer8cdcb262022-10-27 14:36:15 +080050 u32 type;
51 struct regmap *type_sw;
52@@ -890,6 +903,36 @@ static void phy_v2_banks_init(struct mtk_tphy *tphy,
developer44e1bbf2022-01-28 17:20:00 +080053 }
54 }
55
56+static void phy_v4_banks_init(struct mtk_tphy *tphy,
57+ struct mtk_phy_instance *instance)
58+{
59+ struct u2phy_banks *u2_banks = &instance->u2_banks;
60+ struct u3phy_banks *u3_banks = &instance->u3_banks;
61+
62+ switch (instance->type) {
63+ case PHY_TYPE_USB2:
64+ u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
65+ u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
66+ u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
67+ break;
68+ case PHY_TYPE_USB3:
69+ u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
70+ u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
71+ u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
72+ u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
73+ break;
74+ case PHY_TYPE_PCIE:
75+ u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V4_SPLLC;
76+ u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V4_CHIP;
77+ u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V4_U3PHYD;
78+ u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V4_U3PHYA;
79+ break;
80+ default:
81+ dev_err(tphy->dev, "incompatible PHY type\n");
82+ return;
83+ }
84+}
85+
86 static void phy_parse_property(struct mtk_tphy *tphy,
87 struct mtk_phy_instance *instance)
88 {
developer8cdcb262022-10-27 14:36:15 +080089@@ -1072,6 +1115,40 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
developer44e1bbf2022-01-28 17:20:00 +080090 dev_info(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
91 instance->efuse_intr, instance->efuse_rx_imp,
92 instance->efuse_tx_imp);
93+
94+ if (tphy->pdata->version != MTK_PHY_V4)
95+ break;
96+
97+ ret = nvmem_cell_read_variable_le_u32(dev, "intr_ln1", &instance->efuse_intr_ln1);
98+ if (ret) {
99+ dev_err(dev, "fail to get u3 lane1 intr efuse, %d\n", ret);
100+ break;
101+ }
102+
103+ ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp_ln1", &instance->efuse_rx_imp_ln1);
104+ if (ret) {
105+ dev_err(dev, "fail to get u3 lane1 rx_imp efuse, %d\n", ret);
106+ break;
107+ }
108+
109+ ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp_ln1", &instance->efuse_tx_imp_ln1);
110+ if (ret) {
111+ dev_err(dev, "fail to get u3 lane1 tx_imp efuse, %d\n", ret);
112+ break;
113+ }
114+
115+ /* no efuse, ignore it */
116+ if (!instance->efuse_intr_ln1 &&
117+ !instance->efuse_rx_imp_ln1 &&
118+ !instance->efuse_tx_imp_ln1) {
119+ dev_warn(dev, "no u3 lane1 efuse, but dts enable it\n");
120+ instance->efuse_sw_en = 0;
121+ break;
122+ }
123+
124+ dev_info(dev, "u3 lane1 efuse - intr %x, rx_imp %x, tx_imp %x\n",
125+ instance->efuse_intr_ln1, instance->efuse_rx_imp_ln1,
126+ instance->efuse_tx_imp_ln1);
127 break;
128 default:
129 dev_err(dev, "no sw efuse for type %d\n", instance->type);
developer8cdcb262022-10-27 14:36:15 +0800130@@ -1105,6 +1182,31 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
developer44e1bbf2022-01-28 17:20:00 +0800131
132 break;
133 case PHY_TYPE_USB3:
134+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
135+ tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
136+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
137+
138+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
139+ tmp &= ~P3D_RG_TX_IMPEL;
140+ tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp);
141+ tmp |= P3D_RG_FORCE_TX_IMPEL;
142+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
143+
144+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
145+ tmp &= ~P3D_RG_RX_IMPEL;
146+ tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp);
147+ tmp |= P3D_RG_FORCE_RX_IMPEL;
148+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
149+
150+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
151+ tmp &= ~P3A_RG_IEXT_INTR;
152+ tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr);
153+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
154+ pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
155+ __func__, instance->efuse_tx_imp,
156+ instance->efuse_rx_imp, instance->efuse_intr);
157+
158+ break;
159 case PHY_TYPE_PCIE:
160 tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
161 tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
developer8cdcb262022-10-27 14:36:15 +0800162@@ -1129,6 +1231,35 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
developer44e1bbf2022-01-28 17:20:00 +0800163 pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
164 __func__, instance->efuse_tx_imp,
165 instance->efuse_rx_imp, instance->efuse_intr);
166+
167+ if (!instance->efuse_intr_ln1 &&
168+ !instance->efuse_rx_imp_ln1 &&
169+ !instance->efuse_tx_imp_ln1)
170+ break;
171+
172+ tmp = readl(u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_RSV);
173+ tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
174+ writel(tmp, u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_RSV);
175+
176+ tmp = readl(u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_IMPCAL0);
177+ tmp &= ~P3D_RG_TX_IMPEL;
178+ tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp_ln1);
179+ tmp |= P3D_RG_FORCE_TX_IMPEL;
180+ writel(tmp, u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_IMPCAL0);
181+
182+ tmp = readl(u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_IMPCAL1);
183+ tmp &= ~P3D_RG_RX_IMPEL;
184+ tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp_ln1);
185+ tmp |= P3D_RG_FORCE_RX_IMPEL;
186+ writel(tmp, u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_IMPCAL1);
187+
188+ tmp = readl(u3_banks->phya + SSUSB_LN1_OFFSET + U3P_U3_PHYA_REG0);
189+ tmp &= ~P3A_RG_IEXT_INTR;
190+ tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr_ln1);
191+ writel(tmp, u3_banks->phya + SSUSB_LN1_OFFSET + U3P_U3_PHYA_REG0);
192+ pr_err("%s set LN1 efuse, tx_imp %x, rx_imp %x intr %x\n",
193+ __func__, instance->efuse_tx_imp_ln1,
194+ instance->efuse_rx_imp_ln1, instance->efuse_intr_ln1);
195 break;
196 default:
197 dev_warn(dev, "no sw efuse for type %d\n", instance->type);
developer8cdcb262022-10-27 14:36:15 +0800198@@ -1272,6 +1403,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
developer44e1bbf2022-01-28 17:20:00 +0800199 phy_v1_banks_init(tphy, instance);
200 } else if (tphy->pdata->version == MTK_PHY_V2) {
201 phy_v2_banks_init(tphy, instance);
202+ } else if (tphy->pdata->version == MTK_PHY_V4) {
203+ phy_v4_banks_init(tphy, instance);
204 } else {
205 dev_err(dev, "phy version is not supported\n");
206 return ERR_PTR(-EINVAL);
developer8cdcb262022-10-27 14:36:15 +0800207@@ -1323,12 +1456,19 @@ static const struct mtk_phy_pdata mt8195_pdata = {
developer44e1bbf2022-01-28 17:20:00 +0800208 .version = MTK_PHY_V3,
209 };
210
211+static const struct mtk_phy_pdata tphy_v4_pdata = {
212+ .avoid_rx_sen_degradation = false,
213+ .sw_efuse_supported = true,
214+ .version = MTK_PHY_V4,
215+};
216+
217 static const struct of_device_id mtk_tphy_id_table[] = {
218 { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
219 { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
220 { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
221 { .compatible = "mediatek,generic-tphy-v1", .data = &tphy_v1_pdata },
222 { .compatible = "mediatek,generic-tphy-v2", .data = &tphy_v2_pdata },
223+ { .compatible = "mediatek,generic-tphy-v4", .data = &tphy_v4_pdata },
224 { },
225 };
226 MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
227--
2282.18.0
229