blob: 1f958e800d8806c97bb3be526ca62a76479dca30 [file] [log] [blame]
developer5d148cb2023-06-02 13:08:11 +08001From 004157ce74543694981c461e95ac0cc1fa8721d7 Mon Sep 17 00:00:00 2001
2From: Sam Shih <sam.shih@mediatek.com>
3Date: Fri, 2 Jun 2023 13:06:25 +0800
4Subject: [PATCH]
5 [high-speed-io][999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch]
developer44e1bbf2022-01-28 17:20:00 +08006
developer44e1bbf2022-01-28 17:20:00 +08007---
developer8cdcb262022-10-27 14:36:15 +08008 drivers/phy/mediatek/phy-mtk-tphy.c | 195 ++++++++++++++++++++++++++++
9 1 file changed, 195 insertions(+)
developer44e1bbf2022-01-28 17:20:00 +080010
11diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
developer5d148cb2023-06-02 13:08:11 +080012index c6e073401..fcf8c845f 100644
developer44e1bbf2022-01-28 17:20:00 +080013--- a/drivers/phy/mediatek/phy-mtk-tphy.c
14+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
developer8cdcb262022-10-27 14:36:15 +080015@@ -12,6 +12,7 @@
developer44e1bbf2022-01-28 17:20:00 +080016 #include <linux/iopoll.h>
developer8cdcb262022-10-27 14:36:15 +080017 #include <linux/mfd/syscon.h>
developer44e1bbf2022-01-28 17:20:00 +080018 #include <linux/module.h>
19+#include <linux/nvmem-consumer.h>
20 #include <linux/of_address.h>
21 #include <linux/of_device.h>
22 #include <linux/phy/phy.h>
developer5d148cb2023-06-02 13:08:11 +080023@@ -41,11 +42,16 @@
developer44e1bbf2022-01-28 17:20:00 +080024 #define SSUSB_SIFSLV_V2_U3PHYD 0x200
25 #define SSUSB_SIFSLV_V2_U3PHYA 0x400
26
27+#define U3P_MISC_REG1 0x04
28+#define MR1_EFUSE_AUTO_LOAD_DIS BIT(6)
29+
30 #define U3P_USBPHYACR0 0x000
31 #define PA0_RG_U2PLL_FORCE_ON BIT(15)
32 #define PA0_RG_USB20_INTR_EN BIT(5)
33
34 #define U3P_USBPHYACR1 0x004
35+#define PA1_RG_INTR_CAL GENMASK(23, 19)
36+#define PA1_RG_INTR_CAL_VAL(x) ((0x1f & (x)) << 19)
37 #define PA1_RG_VRT_SEL GENMASK(14, 12)
38 #define PA1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12)
39 #define PA1_RG_TERM_SEL GENMASK(10, 8)
developer5d148cb2023-06-02 13:08:11 +080040@@ -117,6 +123,8 @@
developer44e1bbf2022-01-28 17:20:00 +080041 #define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
42
43 #define U3P_U3_PHYA_REG0 0x000
44+#define P3A_RG_IEXT_INTR GENMASK(15, 10)
45+#define P3A_RG_IEXT_INTR_VAL(x) ((0x3f & (x)) << 10)
46 #define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
47 #define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
48
developer5d148cb2023-06-02 13:08:11 +080049@@ -171,6 +179,25 @@
developer44e1bbf2022-01-28 17:20:00 +080050 #define P3D_RG_FWAKE_TH GENMASK(21, 16)
51 #define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
52
53+#define U3P_U3_PHYD_IMPCAL0 0x010
54+#define P3D_RG_FORCE_TX_IMPEL BIT(31)
55+#define P3D_RG_TX_IMPEL GENMASK(28, 24)
56+#define P3D_RG_TX_IMPEL_VAL(x) ((0x1f & (x)) << 24)
57+
58+#define U3P_U3_PHYD_IMPCAL1 0x014
59+#define P3D_RG_FORCE_RX_IMPEL BIT(31)
60+#define P3D_RG_RX_IMPEL GENMASK(28, 24)
61+#define P3D_RG_RX_IMPEL_VAL(x) ((0x1f & (x)) << 24)
62+
63+#define U3P_U3_PHYD_RX0 0x02c
64+
65+#define U3P_U3_PHYD_T2RLB 0x030
66+
67+#define U3P_U3_PHYD_PIPE0 0x040
68+
69+#define U3P_U3_PHYD_RSV 0x054
70+#define P3D_RG_EFUSE_AUTO_LOAD_DIS BIT(12)
71+
72 #define U3P_U3_PHYD_CDR1 0x05c
73 #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
74 #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
developer5d148cb2023-06-02 13:08:11 +080075@@ -280,11 +307,23 @@
developer44e1bbf2022-01-28 17:20:00 +080076 enum mtk_phy_version {
77 MTK_PHY_V1 = 1,
78 MTK_PHY_V2,
79+ MTK_PHY_V3,
80 };
81
82 struct mtk_phy_pdata {
83 /* avoid RX sensitivity level degradation only for mt8173 */
84 bool avoid_rx_sen_degradation;
85+ /*
86+ * u2phy should use integer mode instead of fractional mode of
87+ * 48M PLL, fix it by switching PLL to 26M from default 48M
88+ * for mt8195
89+ */
90+ bool sx_pll_48m_to_26m;
91+ /*
92+ * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse,
93+ * support sw way, also support it for v2/v3 optionally.
94+ */
95+ bool sw_efuse_supported;
96 enum mtk_phy_version version;
97 };
98
developer5d148cb2023-06-02 13:08:11 +080099@@ -309,6 +348,10 @@ struct mtk_phy_instance {
developer44e1bbf2022-01-28 17:20:00 +0800100 struct u3phy_banks u3_banks;
101 };
102 struct clk *ref_clk; /* reference clock of anolog phy */
103+ u32 efuse_sw_en;
104+ u32 efuse_intr;
105+ u32 efuse_tx_imp;
106+ u32 efuse_rx_imp;
107 u32 index;
developer8cdcb262022-10-27 14:36:15 +0800108 u32 type;
109 struct regmap *type_sw;
developer5d148cb2023-06-02 13:08:11 +0800110@@ -970,6 +1013,139 @@ static int phy_type_set(struct mtk_phy_instance *instance)
developer8cdcb262022-10-27 14:36:15 +0800111 return 0;
developer44e1bbf2022-01-28 17:20:00 +0800112 }
113
114+static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
115+{
116+ struct device *dev = &instance->phy->dev;
117+ int ret = 0;
118+
119+ dev_err(dev, "try to get sw efuse\n");
120+
121+ /* tphy v1 doesn't support sw efuse, skip it */
122+ if (!tphy->pdata->sw_efuse_supported) {
123+ instance->efuse_sw_en = 0;
124+ return 0;
125+ }
126+
127+ /* software efuse is optional */
128+ instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells");
129+ if (!instance->efuse_sw_en)
130+ return 0;
131+
132+ dev_err(dev, "try to get sw efuse+\n");
133+
134+ switch (instance->type) {
135+ case PHY_TYPE_USB2:
136+ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
137+ if (ret) {
138+ dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
139+ break;
140+ }
141+
142+ /* no efuse, ignore it */
143+ if (!instance->efuse_intr) {
144+ dev_warn(dev, "no u2 intr efuse, but dts enable it\n");
145+ instance->efuse_sw_en = 0;
146+ break;
147+ }
148+
149+ dev_info(dev, "u2 efuse - intr %x\n", instance->efuse_intr);
150+ break;
151+ case PHY_TYPE_USB3:
152+ case PHY_TYPE_PCIE:
153+ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
154+ if (ret) {
155+ dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
156+ break;
157+ }
158+
159+ ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp);
160+ if (ret) {
161+ dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret);
162+ break;
163+ }
164+
165+ ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp);
166+ if (ret) {
167+ dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret);
168+ break;
169+ }
170+
171+ /* no efuse, ignore it */
172+ if (!instance->efuse_intr &&
173+ !instance->efuse_rx_imp &&
174+ !instance->efuse_tx_imp) {
175+ dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
176+ instance->efuse_sw_en = 0;
177+ break;
178+ }
179+
180+ dev_info(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
181+ instance->efuse_intr, instance->efuse_rx_imp,
182+ instance->efuse_tx_imp);
183+ break;
184+ default:
185+ dev_err(dev, "no sw efuse for type %d\n", instance->type);
186+ ret = -EINVAL;
187+ }
188+
189+ return ret;
190+}
191+
192+static void phy_efuse_set(struct mtk_phy_instance *instance)
193+{
194+ struct device *dev = &instance->phy->dev;
195+ struct u2phy_banks *u2_banks = &instance->u2_banks;
196+ struct u3phy_banks *u3_banks = &instance->u3_banks;
197+ u32 tmp;
198+
199+ if (!instance->efuse_sw_en)
200+ return;
201+
202+ switch (instance->type) {
203+ case PHY_TYPE_USB2:
204+ tmp = readl(u2_banks->misc + U3P_MISC_REG1);
205+ tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
206+ writel(tmp, u2_banks->misc + U3P_MISC_REG1);
207+
208+ tmp = readl(u2_banks->com + U3P_USBPHYACR1);
209+ tmp &= ~PA1_RG_INTR_CAL;
210+ tmp |= PA1_RG_INTR_CAL_VAL(instance->efuse_intr);
211+ writel(tmp, u2_banks->com + U3P_USBPHYACR1);
212+ pr_err("%s set efuse intr %x\n", __func__, instance->efuse_intr);
213+
214+ break;
215+ case PHY_TYPE_USB3:
216+ case PHY_TYPE_PCIE:
217+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
218+ tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
219+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
220+
221+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
222+ tmp &= ~P3D_RG_TX_IMPEL;
223+ tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp);
224+ tmp |= P3D_RG_FORCE_TX_IMPEL;
225+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
226+
227+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
228+ tmp &= ~P3D_RG_RX_IMPEL;
229+ tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp);
230+ tmp |= P3D_RG_FORCE_RX_IMPEL;
231+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
232+
233+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
234+ tmp &= ~P3A_RG_IEXT_INTR;
235+ tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr);
236+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
237+ pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
238+ __func__, instance->efuse_tx_imp,
239+ instance->efuse_rx_imp, instance->efuse_intr);
240+ break;
241+ default:
242+ dev_warn(dev, "no sw efuse for type %d\n", instance->type);
243+ }
244+}
245+
developer8cdcb262022-10-27 14:36:15 +0800246+
developer44e1bbf2022-01-28 17:20:00 +0800247 static int mtk_phy_init(struct phy *phy)
248 {
249 struct mtk_phy_instance *instance = phy_get_drvdata(phy);
developer5d148cb2023-06-02 13:08:11 +0800250@@ -988,6 +1164,8 @@ static int mtk_phy_init(struct phy *phy)
developer44e1bbf2022-01-28 17:20:00 +0800251 return ret;
252 }
253
254+ phy_efuse_set(instance);
255+
256 switch (instance->type) {
257 case PHY_TYPE_USB2:
258 u2_phy_instance_init(tphy, instance);
developer5d148cb2023-06-02 13:08:11 +0800259@@ -1072,6 +1250,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
developer44e1bbf2022-01-28 17:20:00 +0800260 struct mtk_phy_instance *instance = NULL;
261 struct device_node *phy_np = args->np;
262 int index;
263+ int ret;
264
265 if (args->args_count != 1) {
266 dev_err(dev, "invalid number of cells in 'phy' property\n");
developer5d148cb2023-06-02 13:08:11 +0800267@@ -1108,6 +1287,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
developer44e1bbf2022-01-28 17:20:00 +0800268 return ERR_PTR(-EINVAL);
269 }
270
271+ ret = phy_efuse_get(tphy, instance);
272+ if (ret)
273+ return ERR_PTR(ret);
274+
275 phy_parse_property(tphy, instance);
developer8cdcb262022-10-27 14:36:15 +0800276 phy_type_set(instance);
developer44e1bbf2022-01-28 17:20:00 +0800277
developer5d148cb2023-06-02 13:08:11 +0800278@@ -1130,14 +1313,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
developer44e1bbf2022-01-28 17:20:00 +0800279
280 static const struct mtk_phy_pdata tphy_v2_pdata = {
281 .avoid_rx_sen_degradation = false,
282+ .sw_efuse_supported = true,
283 .version = MTK_PHY_V2,
284 };
285
286+static const struct mtk_phy_pdata tphy_v3_pdata = {
287+ .sw_efuse_supported = true,
288+ .version = MTK_PHY_V3,
289+};
290+
291 static const struct mtk_phy_pdata mt8173_pdata = {
292 .avoid_rx_sen_degradation = true,
293 .version = MTK_PHY_V1,
294 };
295
296+static const struct mtk_phy_pdata mt8195_pdata = {
297+ .sx_pll_48m_to_26m = true,
298+ .sw_efuse_supported = true,
299+ .version = MTK_PHY_V3,
300+};
301+
302 static const struct of_device_id mtk_tphy_id_table[] = {
303 { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
304 { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
305--
developer5d148cb2023-06-02 13:08:11 +08003062.34.1
developer44e1bbf2022-01-28 17:20:00 +0800307