blob: 5cc8a65850818ec8086f8ffc4726fc81e7137caf [file] [log] [blame]
developer44e1bbf2022-01-28 17:20:00 +08001From afb123e0f9992d35d0fb28ed875f2b7b7884652f Mon Sep 17 00:00:00 2001
2From: Zhanyong Wang <zhanyong.wang@mediatek.com>
3Date: Mon, 8 Nov 2021 14:51:38 +0800
4Subject: [PATCH 3/5] phy: phy-mtk-tphy: add support efuse setting
5
6Due to some SoCs have a bit shift issue that will drop a bit for usb3
7phy or pcie phy, fix it by adding software efuse reading and setting,
8but only support it optionally for versoin.
9
10Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
11Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
12Change-Id: Ibf88868668b3889f18c7930531981400cac732f1
13---
14 drivers/phy/mediatek/phy-mtk-tphy.c | 194 ++++++++++++++++++++++++++++
15 1 file changed, 194 insertions(+)
16
17diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
18index cb2ed3b25068..05a1ad4ff334 100644
19--- a/drivers/phy/mediatek/phy-mtk-tphy.c
20+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
21@@ -11,6 +11,7 @@
22 #include <linux/io.h>
23 #include <linux/iopoll.h>
24 #include <linux/module.h>
25+#include <linux/nvmem-consumer.h>
26 #include <linux/of_address.h>
27 #include <linux/of_device.h>
28 #include <linux/phy/phy.h>
29@@ -38,11 +39,16 @@
30 #define SSUSB_SIFSLV_V2_U3PHYD 0x200
31 #define SSUSB_SIFSLV_V2_U3PHYA 0x400
32
33+#define U3P_MISC_REG1 0x04
34+#define MR1_EFUSE_AUTO_LOAD_DIS BIT(6)
35+
36 #define U3P_USBPHYACR0 0x000
37 #define PA0_RG_U2PLL_FORCE_ON BIT(15)
38 #define PA0_RG_USB20_INTR_EN BIT(5)
39
40 #define U3P_USBPHYACR1 0x004
41+#define PA1_RG_INTR_CAL GENMASK(23, 19)
42+#define PA1_RG_INTR_CAL_VAL(x) ((0x1f & (x)) << 19)
43 #define PA1_RG_VRT_SEL GENMASK(14, 12)
44 #define PA1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12)
45 #define PA1_RG_TERM_SEL GENMASK(10, 8)
46@@ -114,6 +120,8 @@
47 #define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
48
49 #define U3P_U3_PHYA_REG0 0x000
50+#define P3A_RG_IEXT_INTR GENMASK(15, 10)
51+#define P3A_RG_IEXT_INTR_VAL(x) ((0x3f & (x)) << 10)
52 #define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
53 #define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
54
55@@ -168,6 +176,25 @@
56 #define P3D_RG_FWAKE_TH GENMASK(21, 16)
57 #define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
58
59+#define U3P_U3_PHYD_IMPCAL0 0x010
60+#define P3D_RG_FORCE_TX_IMPEL BIT(31)
61+#define P3D_RG_TX_IMPEL GENMASK(28, 24)
62+#define P3D_RG_TX_IMPEL_VAL(x) ((0x1f & (x)) << 24)
63+
64+#define U3P_U3_PHYD_IMPCAL1 0x014
65+#define P3D_RG_FORCE_RX_IMPEL BIT(31)
66+#define P3D_RG_RX_IMPEL GENMASK(28, 24)
67+#define P3D_RG_RX_IMPEL_VAL(x) ((0x1f & (x)) << 24)
68+
69+#define U3P_U3_PHYD_RX0 0x02c
70+
71+#define U3P_U3_PHYD_T2RLB 0x030
72+
73+#define U3P_U3_PHYD_PIPE0 0x040
74+
75+#define U3P_U3_PHYD_RSV 0x054
76+#define P3D_RG_EFUSE_AUTO_LOAD_DIS BIT(12)
77+
78 #define U3P_U3_PHYD_CDR1 0x05c
79 #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
80 #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
81@@ -266,11 +293,23 @@
82 enum mtk_phy_version {
83 MTK_PHY_V1 = 1,
84 MTK_PHY_V2,
85+ MTK_PHY_V3,
86 };
87
88 struct mtk_phy_pdata {
89 /* avoid RX sensitivity level degradation only for mt8173 */
90 bool avoid_rx_sen_degradation;
91+ /*
92+ * u2phy should use integer mode instead of fractional mode of
93+ * 48M PLL, fix it by switching PLL to 26M from default 48M
94+ * for mt8195
95+ */
96+ bool sx_pll_48m_to_26m;
97+ /*
98+ * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse,
99+ * support sw way, also support it for v2/v3 optionally.
100+ */
101+ bool sw_efuse_supported;
102 enum mtk_phy_version version;
103 };
104
105@@ -295,6 +334,10 @@ struct mtk_phy_instance {
106 struct u3phy_banks u3_banks;
107 };
108 struct clk *ref_clk; /* reference clock of anolog phy */
109+ u32 efuse_sw_en;
110+ u32 efuse_intr;
111+ u32 efuse_tx_imp;
112+ u32 efuse_rx_imp;
113 u32 index;
114 u8 type;
115 int eye_src;
116@@ -890,6 +933,138 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
117 }
118 }
119
120+static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
121+{
122+ struct device *dev = &instance->phy->dev;
123+ int ret = 0;
124+
125+ dev_err(dev, "try to get sw efuse\n");
126+
127+ /* tphy v1 doesn't support sw efuse, skip it */
128+ if (!tphy->pdata->sw_efuse_supported) {
129+ instance->efuse_sw_en = 0;
130+ return 0;
131+ }
132+
133+ /* software efuse is optional */
134+ instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells");
135+ if (!instance->efuse_sw_en)
136+ return 0;
137+
138+ dev_err(dev, "try to get sw efuse+\n");
139+
140+ switch (instance->type) {
141+ case PHY_TYPE_USB2:
142+ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
143+ if (ret) {
144+ dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
145+ break;
146+ }
147+
148+ /* no efuse, ignore it */
149+ if (!instance->efuse_intr) {
150+ dev_warn(dev, "no u2 intr efuse, but dts enable it\n");
151+ instance->efuse_sw_en = 0;
152+ break;
153+ }
154+
155+ dev_info(dev, "u2 efuse - intr %x\n", instance->efuse_intr);
156+ break;
157+ case PHY_TYPE_USB3:
158+ case PHY_TYPE_PCIE:
159+ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
160+ if (ret) {
161+ dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
162+ break;
163+ }
164+
165+ ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp);
166+ if (ret) {
167+ dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret);
168+ break;
169+ }
170+
171+ ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp);
172+ if (ret) {
173+ dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret);
174+ break;
175+ }
176+
177+ /* no efuse, ignore it */
178+ if (!instance->efuse_intr &&
179+ !instance->efuse_rx_imp &&
180+ !instance->efuse_tx_imp) {
181+ dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
182+ instance->efuse_sw_en = 0;
183+ break;
184+ }
185+
186+ dev_info(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
187+ instance->efuse_intr, instance->efuse_rx_imp,
188+ instance->efuse_tx_imp);
189+ break;
190+ default:
191+ dev_err(dev, "no sw efuse for type %d\n", instance->type);
192+ ret = -EINVAL;
193+ }
194+
195+ return ret;
196+}
197+
198+static void phy_efuse_set(struct mtk_phy_instance *instance)
199+{
200+ struct device *dev = &instance->phy->dev;
201+ struct u2phy_banks *u2_banks = &instance->u2_banks;
202+ struct u3phy_banks *u3_banks = &instance->u3_banks;
203+ u32 tmp;
204+
205+ if (!instance->efuse_sw_en)
206+ return;
207+
208+ switch (instance->type) {
209+ case PHY_TYPE_USB2:
210+ tmp = readl(u2_banks->misc + U3P_MISC_REG1);
211+ tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
212+ writel(tmp, u2_banks->misc + U3P_MISC_REG1);
213+
214+ tmp = readl(u2_banks->com + U3P_USBPHYACR1);
215+ tmp &= ~PA1_RG_INTR_CAL;
216+ tmp |= PA1_RG_INTR_CAL_VAL(instance->efuse_intr);
217+ writel(tmp, u2_banks->com + U3P_USBPHYACR1);
218+ pr_err("%s set efuse intr %x\n", __func__, instance->efuse_intr);
219+
220+ break;
221+ case PHY_TYPE_USB3:
222+ case PHY_TYPE_PCIE:
223+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
224+ tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
225+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
226+
227+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
228+ tmp &= ~P3D_RG_TX_IMPEL;
229+ tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp);
230+ tmp |= P3D_RG_FORCE_TX_IMPEL;
231+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
232+
233+ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
234+ tmp &= ~P3D_RG_RX_IMPEL;
235+ tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp);
236+ tmp |= P3D_RG_FORCE_RX_IMPEL;
237+ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
238+
239+ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
240+ tmp &= ~P3A_RG_IEXT_INTR;
241+ tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr);
242+ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
243+ pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
244+ __func__, instance->efuse_tx_imp,
245+ instance->efuse_rx_imp, instance->efuse_intr);
246+ break;
247+ default:
248+ dev_warn(dev, "no sw efuse for type %d\n", instance->type);
249+ }
250+}
251+
252 static int mtk_phy_init(struct phy *phy)
253 {
254 struct mtk_phy_instance *instance = phy_get_drvdata(phy);
255@@ -908,6 +1083,8 @@ static int mtk_phy_init(struct phy *phy)
256 return ret;
257 }
258
259+ phy_efuse_set(instance);
260+
261 switch (instance->type) {
262 case PHY_TYPE_USB2:
263 u2_phy_instance_init(tphy, instance);
264@@ -989,6 +1166,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
265 struct mtk_phy_instance *instance = NULL;
266 struct device_node *phy_np = args->np;
267 int index;
268+ int ret;
269
270 if (args->args_count != 1) {
271 dev_err(dev, "invalid number of cells in 'phy' property\n");
272@@ -1024,6 +1202,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
273 return ERR_PTR(-EINVAL);
274 }
275
276+ ret = phy_efuse_get(tphy, instance);
277+ if (ret)
278+ return ERR_PTR(ret);
279+
280 phy_parse_property(tphy, instance);
281
282 return instance->phy;
283@@ -1045,14 +1227,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
284
285 static const struct mtk_phy_pdata tphy_v2_pdata = {
286 .avoid_rx_sen_degradation = false,
287+ .sw_efuse_supported = true,
288 .version = MTK_PHY_V2,
289 };
290
291+static const struct mtk_phy_pdata tphy_v3_pdata = {
292+ .sw_efuse_supported = true,
293+ .version = MTK_PHY_V3,
294+};
295+
296 static const struct mtk_phy_pdata mt8173_pdata = {
297 .avoid_rx_sen_degradation = true,
298 .version = MTK_PHY_V1,
299 };
300
301+static const struct mtk_phy_pdata mt8195_pdata = {
302+ .sx_pll_48m_to_26m = true,
303+ .sw_efuse_supported = true,
304+ .version = MTK_PHY_V3,
305+};
306+
307 static const struct of_device_id mtk_tphy_id_table[] = {
308 { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
309 { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
310--
3112.18.0
312