blob: ea9edf212c6f0e4700ccfaeaca53232b38ed4465 [file] [log] [blame]
Ryder Lee235bad02019-08-22 12:26:50 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2015 - 2019 MediaTek Inc.
4 * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
5 * Ryder Lee <ryder.lee@mediatek.com>
6 */
7
8#include <common.h>
9#include <clk.h>
10#include <dm.h>
11#include <generic-phy.h>
Simon Glass336d4612020-02-03 07:36:16 -070012#include <malloc.h>
Ryder Lee235bad02019-08-22 12:26:50 +020013#include <mapmem.h>
14#include <asm/io.h>
Simon Glass336d4612020-02-03 07:36:16 -070015#include <dm/device_compat.h>
Simon Glass61b29b82020-02-03 07:36:15 -070016#include <dm/devres.h>
Chunfeng Yun5241fc82023-02-17 17:04:08 +080017#include <linux/bitfield.h>
Simon Glasscd93d622020-05-10 11:40:13 -060018#include <linux/bitops.h>
Simon Glassc05ed002020-05-10 11:40:11 -060019#include <linux/delay.h>
Ryder Lee235bad02019-08-22 12:26:50 +020020
21#include <dt-bindings/phy/phy.h>
22
23/* version V1 sub-banks offset base address */
24/* banks shared by multiple phys */
25#define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020026#define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */
Ryder Lee235bad02019-08-22 12:26:50 +020027#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020028/* u2 phy bank */
29#define SSUSB_SIFSLV_V1_U2PHY_COM 0x000
Ryder Lee235bad02019-08-22 12:26:50 +020030/* u3/pcie/sata phy banks */
31#define SSUSB_SIFSLV_V1_U3PHYD 0x000
32#define SSUSB_SIFSLV_V1_U3PHYA 0x200
33
Chunfeng Yund1ae8442020-05-02 11:35:16 +020034/* version V2 sub-banks offset base address */
35/* u2 phy banks */
36#define SSUSB_SIFSLV_V2_MISC 0x000
37#define SSUSB_SIFSLV_V2_U2FREQ 0x100
38#define SSUSB_SIFSLV_V2_U2PHY_COM 0x300
39/* u3/pcie/sata phy banks */
40#define SSUSB_SIFSLV_V2_SPLLC 0x000
41#define SSUSB_SIFSLV_V2_CHIP 0x100
42#define SSUSB_SIFSLV_V2_U3PHYD 0x200
43#define SSUSB_SIFSLV_V2_U3PHYA 0x400
44
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020045#define U3P_USBPHYACR0 0x000
46#define PA0_RG_U2PLL_FORCE_ON BIT(15)
Chunfeng Yun39b854a2023-02-17 17:04:09 +080047#define PA0_USB20_PLL_PREDIV GENMASK(7, 6)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020048#define PA0_RG_USB20_INTR_EN BIT(5)
49
Chunfeng Yun4f6dd252023-12-13 14:41:34 +080050#define U3P_USBPHYACR1 0x004
51#define PA1_RG_INTR_CAL GENMASK(23, 19)
52#define PA1_RG_VRT_SEL GENMASK(14, 12)
53#define PA1_RG_TERM_SEL GENMASK(10, 8)
54
Chunfeng Yun39b854a2023-02-17 17:04:09 +080055#define U3P_USBPHYACR2 0x008
56#define PA2_RG_U2PLL_BW GENMASK(21, 19)
57
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020058#define U3P_USBPHYACR5 0x014
59#define PA5_RG_U2_HSTX_SRCAL_EN BIT(15)
60#define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020061#define PA5_RG_U2_HS_100U_U3_EN BIT(11)
62
63#define U3P_USBPHYACR6 0x018
Chunfeng Yun4f6dd252023-12-13 14:41:34 +080064#define PA6_RG_U2_PRE_EMP GENMASK(31, 30)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020065#define PA6_RG_U2_BC11_SW_EN BIT(23)
66#define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20)
Chunfeng Yun4f6dd252023-12-13 14:41:34 +080067#define PA6_RG_U2_DISCTH GENMASK(7, 4)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020068#define PA6_RG_U2_SQTH GENMASK(3, 0)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020069
70#define U3P_U2PHYACR4 0x020
71#define P2C_RG_USB20_GPIO_CTL BIT(9)
72#define P2C_USB20_GPIO_MODE BIT(8)
73#define P2C_U2_GPIO_CTR_MSK \
74 (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
75
Chunfeng Yun39b854a2023-02-17 17:04:09 +080076#define U3P_U2PHYA_RESV 0x030
77#define P2R_RG_U2PLL_FBDIV_26M 0x1bb13b
78#define P2R_RG_U2PLL_FBDIV_48M 0x3c0000
79
80#define U3P_U2PHYA_RESV1 0x044
81#define P2R_RG_U2PLL_REFCLK_SEL BIT(5)
82#define P2R_RG_U2PLL_FRA_EN BIT(3)
83
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020084#define U3P_U2PHYDTM0 0x068
85#define P2C_FORCE_UART_EN BIT(26)
86#define P2C_FORCE_DATAIN BIT(23)
87#define P2C_FORCE_DM_PULLDOWN BIT(21)
88#define P2C_FORCE_DP_PULLDOWN BIT(20)
89#define P2C_FORCE_XCVRSEL BIT(19)
90#define P2C_FORCE_SUSPENDM BIT(18)
91#define P2C_FORCE_TERMSEL BIT(17)
92#define P2C_RG_DATAIN GENMASK(13, 10)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020093#define P2C_RG_DMPULLDOWN BIT(7)
94#define P2C_RG_DPPULLDOWN BIT(6)
95#define P2C_RG_XCVRSEL GENMASK(5, 4)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020096#define P2C_RG_SUSPENDM BIT(3)
97#define P2C_RG_TERMSEL BIT(2)
98#define P2C_DTM0_PART_MASK \
99 (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
100 P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
101 P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
102 P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
103
104#define U3P_U2PHYDTM1 0x06C
105#define P2C_RG_UART_EN BIT(16)
106#define P2C_FORCE_IDDIG BIT(9)
107#define P2C_RG_VBUSVALID BIT(5)
108#define P2C_RG_SESSEND BIT(4)
109#define P2C_RG_AVALID BIT(2)
110#define P2C_RG_IDDIG BIT(1)
111
Ryder Lee235bad02019-08-22 12:26:50 +0200112#define U3P_U3_CHIP_GPIO_CTLD 0x0c
113#define P3C_REG_IP_SW_RST BIT(31)
114#define P3C_MCU_BUS_CK_GATE_EN BIT(30)
115#define P3C_FORCE_IP_SW_RST BIT(29)
116
117#define U3P_U3_CHIP_GPIO_CTLE 0x10
118#define P3C_RG_SWRST_U3_PHYD BIT(25)
119#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
120
121#define U3P_U3_PHYA_REG0 0x000
122#define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
Ryder Lee235bad02019-08-22 12:26:50 +0200123
124#define U3P_U3_PHYA_REG1 0x004
125#define P3A_RG_CLKDRV_AMP GENMASK(31, 29)
Ryder Lee235bad02019-08-22 12:26:50 +0200126
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200127#define U3P_U3_PHYA_REG6 0x018
128#define P3A_RG_TX_EIDLE_CM GENMASK(31, 28)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200129
130#define U3P_U3_PHYA_REG9 0x024
131#define P3A_RG_RX_DAC_MUX GENMASK(5, 1)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200132
Ryder Lee235bad02019-08-22 12:26:50 +0200133#define U3P_U3_PHYA_DA_REG0 0x100
134#define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16)
Ryder Lee235bad02019-08-22 12:26:50 +0200135#define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12)
Ryder Lee235bad02019-08-22 12:26:50 +0200136#define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10)
Ryder Lee235bad02019-08-22 12:26:50 +0200137
138#define U3P_U3_PHYA_DA_REG4 0x108
139#define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19)
140#define P3A_RG_PLL_BC_PE2H GENMASK(7, 6)
Ryder Lee235bad02019-08-22 12:26:50 +0200141
142#define U3P_U3_PHYA_DA_REG5 0x10c
143#define P3A_RG_PLL_BR_PE2H GENMASK(29, 28)
Ryder Lee235bad02019-08-22 12:26:50 +0200144#define P3A_RG_PLL_IC_PE2H GENMASK(15, 12)
Ryder Lee235bad02019-08-22 12:26:50 +0200145
146#define U3P_U3_PHYA_DA_REG6 0x110
147#define P3A_RG_PLL_IR_PE2H GENMASK(19, 16)
Ryder Lee235bad02019-08-22 12:26:50 +0200148
149#define U3P_U3_PHYA_DA_REG7 0x114
150#define P3A_RG_PLL_BP_PE2H GENMASK(19, 16)
Ryder Lee235bad02019-08-22 12:26:50 +0200151
152#define U3P_U3_PHYA_DA_REG20 0x13c
153#define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16)
Ryder Lee235bad02019-08-22 12:26:50 +0200154
155#define U3P_U3_PHYA_DA_REG25 0x148
156#define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0)
Ryder Lee235bad02019-08-22 12:26:50 +0200157
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200158#define U3P_U3_PHYD_LFPS1 0x00c
159#define P3D_RG_FWAKE_TH GENMASK(21, 16)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200160
161#define U3P_U3_PHYD_CDR1 0x05c
162#define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200163#define P3D_RG_CDR_BIR_LTD0 GENMASK(12, 8)
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200164
Ryder Lee235bad02019-08-22 12:26:50 +0200165#define U3P_U3_PHYD_RXDET1 0x128
166#define P3D_RG_RXDET_STB2_SET GENMASK(17, 9)
Ryder Lee235bad02019-08-22 12:26:50 +0200167
168#define U3P_U3_PHYD_RXDET2 0x12c
169#define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0)
Ryder Lee235bad02019-08-22 12:26:50 +0200170
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200171#define U3P_SPLLC_XTALCTL3 0x018
172#define XC3_RG_U3_XTAL_RX_PWD BIT(9)
173#define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8)
174
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200175/* SATA register setting */
176#define PHYD_CTRL_SIGNAL_MODE4 0x1c
177/* CDR Charge Pump P-path current adjustment */
178#define RG_CDR_BICLTD1_GEN1_MSK GENMASK(23, 20)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200179#define RG_CDR_BICLTD0_GEN1_MSK GENMASK(11, 8)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200180
181#define PHYD_DESIGN_OPTION2 0x24
182/* Symbol lock count selection */
183#define RG_LOCK_CNT_SEL_MSK GENMASK(5, 4)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200184
185#define PHYD_DESIGN_OPTION9 0x40
186/* COMWAK GAP width window */
187#define RG_TG_MAX_MSK GENMASK(20, 16)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200188/* COMINIT GAP width window */
189#define RG_T2_MAX_MSK GENMASK(13, 8)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200190/* COMWAK GAP width window */
191#define RG_TG_MIN_MSK GENMASK(7, 5)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200192/* COMINIT GAP width window */
193#define RG_T2_MIN_MSK GENMASK(4, 0)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200194
195#define ANA_RG_CTRL_SIGNAL1 0x4c
196/* TX driver tail current control for 0dB de-empahsis mdoe for Gen1 speed */
197#define RG_IDRV_0DB_GEN1_MSK GENMASK(13, 8)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200198
199#define ANA_RG_CTRL_SIGNAL4 0x58
200#define RG_CDR_BICLTR_GEN1_MSK GENMASK(23, 20)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200201/* Loop filter R1 resistance adjustment for Gen1 speed */
202#define RG_CDR_BR_GEN2_MSK GENMASK(10, 8)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200203
204#define ANA_RG_CTRL_SIGNAL6 0x60
205/* I-path capacitance adjustment for Gen1 */
206#define RG_CDR_BC_GEN1_MSK GENMASK(28, 24)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200207#define RG_CDR_BIRLTR_GEN1_MSK GENMASK(4, 0)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200208
209#define ANA_EQ_EYE_CTRL_SIGNAL1 0x6c
210/* RX Gen1 LEQ tuning step */
211#define RG_EQ_DLEQ_LFI_GEN1_MSK GENMASK(11, 8)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200212
213#define ANA_EQ_EYE_CTRL_SIGNAL4 0xd8
214#define RG_CDR_BIRLTD0_GEN1_MSK GENMASK(20, 16)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200215
216#define ANA_EQ_EYE_CTRL_SIGNAL5 0xdc
217#define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0)
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200218
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200219enum mtk_phy_version {
220 MTK_TPHY_V1 = 1,
221 MTK_TPHY_V2,
222};
223
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800224struct tphy_pdata {
225 enum mtk_phy_version version;
226
227 /*
228 * workaround only for mt8195:
229 * u2phy should use integer mode instead of fractional mode of
230 * 48M PLL, fix it by switching PLL to 26M from default 48M
231 */
232 bool sw_pll_48m_to_26m;
233};
234
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200235struct u2phy_banks {
236 void __iomem *misc;
237 void __iomem *fmreg;
238 void __iomem *com;
239};
240
Ryder Lee235bad02019-08-22 12:26:50 +0200241struct u3phy_banks {
242 void __iomem *spllc;
243 void __iomem *chip;
244 void __iomem *phyd; /* include u3phyd_bank2 */
245 void __iomem *phya; /* include u3phya_da */
246};
247
248struct mtk_phy_instance {
249 void __iomem *port_base;
Chunfeng Yun4f6dd252023-12-13 14:41:34 +0800250 struct device_node *np;
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200251 union {
252 struct u2phy_banks u2_banks;
253 struct u3phy_banks u3_banks;
254 };
Ryder Lee235bad02019-08-22 12:26:50 +0200255
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200256 struct clk ref_clk; /* reference clock of (digital) phy */
257 struct clk da_ref_clk; /* reference clock of analog phy */
Ryder Lee235bad02019-08-22 12:26:50 +0200258 u32 index;
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200259 u32 type;
Chunfeng Yun4f6dd252023-12-13 14:41:34 +0800260
261 u32 eye_vrt;
262 u32 eye_term;
263 u32 discth;
264 u32 pre_emphasis;
Ryder Lee235bad02019-08-22 12:26:50 +0200265};
266
267struct mtk_tphy {
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200268 struct udevice *dev;
Ryder Lee235bad02019-08-22 12:26:50 +0200269 void __iomem *sif_base;
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800270 const struct tphy_pdata *pdata;
Ryder Lee235bad02019-08-22 12:26:50 +0200271 struct mtk_phy_instance **phys;
272 int nphys;
273};
274
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800275/* workaround only for mt8195 */
276static void u2_phy_pll_26m_set(struct mtk_tphy *tphy,
277 struct mtk_phy_instance *instance)
278{
279 struct u2phy_banks *u2_banks = &instance->u2_banks;
280
281 if (!tphy->pdata->sw_pll_48m_to_26m)
282 return;
283
284 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR0, PA0_USB20_PLL_PREDIV,
285 FIELD_PREP(PA0_USB20_PLL_PREDIV, 0));
286
287 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR2, PA2_RG_U2PLL_BW,
288 FIELD_PREP(PA2_RG_U2PLL_BW, 3));
289
290 writel(P2R_RG_U2PLL_FBDIV_26M, u2_banks->com + U3P_U2PHYA_RESV);
291
292 setbits_le32(u2_banks->com + U3P_U2PHYA_RESV1,
293 P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL);
294}
295
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200296static void u2_phy_instance_init(struct mtk_tphy *tphy,
297 struct mtk_phy_instance *instance)
298{
299 struct u2phy_banks *u2_banks = &instance->u2_banks;
300
301 /* switch to USB function, and enable usb pll */
302 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM0,
303 P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800304 FIELD_PREP(P2C_RG_XCVRSEL, 1) |
305 FIELD_PREP(P2C_RG_DATAIN, 0));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200306
307 clrbits_le32(u2_banks->com + U3P_U2PHYDTM1, P2C_RG_UART_EN);
308 setbits_le32(u2_banks->com + U3P_USBPHYACR0, PA0_RG_USB20_INTR_EN);
309
310 /* disable switch 100uA current to SSUSB */
311 clrbits_le32(u2_banks->com + U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN);
312
313 clrbits_le32(u2_banks->com + U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK);
314
315 /* DP/DM BC1.1 path Disable */
316 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR6,
317 PA6_RG_U2_BC11_SW_EN | PA6_RG_U2_SQTH,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800318 FIELD_PREP(PA6_RG_U2_SQTH, 2));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200319
320 /* set HS slew rate */
321 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR5,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800322 PA5_RG_U2_HSTX_SRCTRL,
323 FIELD_PREP(PA5_RG_U2_HSTX_SRCTRL, 4));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200324
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800325 u2_phy_pll_26m_set(tphy, instance);
326
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200327 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
328}
329
330static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
331 struct mtk_phy_instance *instance)
332{
333 struct u2phy_banks *u2_banks = &instance->u2_banks;
334
335 clrbits_le32(u2_banks->com + U3P_U2PHYDTM0,
336 P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
337
338 /* OTG Enable */
339 setbits_le32(u2_banks->com + U3P_USBPHYACR6,
340 PA6_RG_U2_OTG_VBUSCMP_EN);
341
342 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM1,
343 P2C_RG_SESSEND, P2C_RG_VBUSVALID | P2C_RG_AVALID);
344
345 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
346}
347
348static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
349 struct mtk_phy_instance *instance)
350{
351 struct u2phy_banks *u2_banks = &instance->u2_banks;
352
353 clrbits_le32(u2_banks->com + U3P_U2PHYDTM0,
354 P2C_RG_XCVRSEL | P2C_RG_DATAIN);
355
356 /* OTG Disable */
357 clrbits_le32(u2_banks->com + U3P_USBPHYACR6,
358 PA6_RG_U2_OTG_VBUSCMP_EN);
359
360 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM1,
361 P2C_RG_VBUSVALID | P2C_RG_AVALID, P2C_RG_SESSEND);
362
363 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
364}
365
366static void u3_phy_instance_init(struct mtk_tphy *tphy,
367 struct mtk_phy_instance *instance)
368{
369 struct u3phy_banks *u3_banks = &instance->u3_banks;
370
371 /* gating PCIe Analog XTAL clock */
372 setbits_le32(u3_banks->spllc + U3P_SPLLC_XTALCTL3,
373 XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD);
374
375 /* gating XSQ */
376 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800377 P3A_RG_XTAL_EXT_EN_U3,
378 FIELD_PREP(P3A_RG_XTAL_EXT_EN_U3, 2));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200379
380 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG9,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800381 P3A_RG_RX_DAC_MUX, FIELD_PREP(P3A_RG_RX_DAC_MUX, 4));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200382
383 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG6,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800384 P3A_RG_TX_EIDLE_CM,
385 FIELD_PREP(P3A_RG_TX_EIDLE_CM, 0xe));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200386
387 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_CDR1,
388 P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800389 FIELD_PREP(P3D_RG_CDR_BIR_LTD0, 0xc) |
390 FIELD_PREP(P3D_RG_CDR_BIR_LTD1, 0x3));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200391
392 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_LFPS1,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800393 P3D_RG_FWAKE_TH, FIELD_PREP(P3D_RG_FWAKE_TH, 0x34));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200394
395 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET1,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800396 P3D_RG_RXDET_STB2_SET,
397 FIELD_PREP(P3D_RG_RXDET_STB2_SET, 0x10));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200398
399 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET2,
400 P3D_RG_RXDET_STB2_SET_P3,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800401 FIELD_PREP(P3D_RG_RXDET_STB2_SET_P3, 0x10));
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200402
403 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
404}
405
Ryder Lee235bad02019-08-22 12:26:50 +0200406static void pcie_phy_instance_init(struct mtk_tphy *tphy,
407 struct mtk_phy_instance *instance)
408{
409 struct u3phy_banks *u3_banks = &instance->u3_banks;
410
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800411 if (tphy->pdata->version != MTK_TPHY_V1)
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200412 return;
413
Ryder Lee235bad02019-08-22 12:26:50 +0200414 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
415 P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800416 FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) |
417 FIELD_PREP(P3A_RG_XTAL_EXT_PE2H, 0x2));
Ryder Lee235bad02019-08-22 12:26:50 +0200418
419 /* ref clk drive */
420 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG1, P3A_RG_CLKDRV_AMP,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800421 FIELD_PREP(P3A_RG_CLKDRV_AMP, 0x4));
Ryder Lee235bad02019-08-22 12:26:50 +0200422 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG0, P3A_RG_CLKDRV_OFF,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800423 FIELD_PREP(P3A_RG_CLKDRV_OFF, 0x1));
Ryder Lee235bad02019-08-22 12:26:50 +0200424
425 /* SSC delta -5000ppm */
426 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG20,
427 P3A_RG_PLL_DELTA1_PE2H,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800428 FIELD_PREP(P3A_RG_PLL_DELTA1_PE2H, 0x3c));
Ryder Lee235bad02019-08-22 12:26:50 +0200429
430 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG25,
431 P3A_RG_PLL_DELTA_PE2H,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800432 FIELD_PREP(P3A_RG_PLL_DELTA_PE2H, 0x36));
Ryder Lee235bad02019-08-22 12:26:50 +0200433
434 /* change pll BW 0.6M */
435 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG5,
436 P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800437 FIELD_PREP(P3A_RG_PLL_BR_PE2H, 0x1) |
438 FIELD_PREP(P3A_RG_PLL_IC_PE2H, 0x1));
Ryder Lee235bad02019-08-22 12:26:50 +0200439 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG4,
440 P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800441 FIELD_PREP(P3A_RG_PLL_BC_PE2H, 0x3));
Ryder Lee235bad02019-08-22 12:26:50 +0200442
443 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG6,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800444 P3A_RG_PLL_IR_PE2H,
445 FIELD_PREP(P3A_RG_PLL_IR_PE2H, 0x2));
Ryder Lee235bad02019-08-22 12:26:50 +0200446 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG7,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800447 P3A_RG_PLL_BP_PE2H,
448 FIELD_PREP(P3A_RG_PLL_BP_PE2H, 0xa));
Ryder Lee235bad02019-08-22 12:26:50 +0200449
450 /* Tx Detect Rx Timing: 10us -> 5us */
451 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET1,
452 P3D_RG_RXDET_STB2_SET,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800453 FIELD_PREP(P3D_RG_RXDET_STB2_SET, 0x10));
Ryder Lee235bad02019-08-22 12:26:50 +0200454 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET2,
455 P3D_RG_RXDET_STB2_SET_P3,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800456 FIELD_PREP(P3D_RG_RXDET_STB2_SET_P3, 0x10));
Ryder Lee235bad02019-08-22 12:26:50 +0200457
458 /* wait for PCIe subsys register to active */
459 udelay(3000);
460}
461
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200462static void sata_phy_instance_init(struct mtk_tphy *tphy,
463 struct mtk_phy_instance *instance)
464{
465 struct u3phy_banks *u3_banks = &instance->u3_banks;
466
467 clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL6,
468 RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800469 FIELD_PREP(RG_CDR_BIRLTR_GEN1_MSK, 0x6) |
470 FIELD_PREP(RG_CDR_BC_GEN1_MSK, 0x1a));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200471 clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL4,
472 RG_CDR_BIRLTD0_GEN1_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800473 FIELD_PREP(RG_CDR_BIRLTD0_GEN1_MSK, 0x18));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200474 clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL5,
475 RG_CDR_BIRLTD0_GEN3_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800476 FIELD_PREP(RG_CDR_BIRLTD0_GEN3_MSK, 0x06));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200477 clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL4,
478 RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800479 FIELD_PREP(RG_CDR_BICLTR_GEN1_MSK, 0x0c) |
480 FIELD_PREP(RG_CDR_BR_GEN2_MSK, 0x07));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200481 clrsetbits_le32(u3_banks->phyd + PHYD_CTRL_SIGNAL_MODE4,
482 RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800483 FIELD_PREP(RG_CDR_BICLTD0_GEN1_MSK, 0x08) |
484 FIELD_PREP(RG_CDR_BICLTD1_GEN1_MSK, 0x02));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200485 clrsetbits_le32(u3_banks->phyd + PHYD_DESIGN_OPTION2,
486 RG_LOCK_CNT_SEL_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800487 FIELD_PREP(RG_LOCK_CNT_SEL_MSK, 0x02));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200488 clrsetbits_le32(u3_banks->phyd + PHYD_DESIGN_OPTION9,
489 RG_T2_MIN_MSK | RG_TG_MIN_MSK |
490 RG_T2_MAX_MSK | RG_TG_MAX_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800491 FIELD_PREP(RG_T2_MIN_MSK, 0x12) |
492 FIELD_PREP(RG_TG_MIN_MSK, 0x04) |
493 FIELD_PREP(RG_T2_MAX_MSK, 0x31) |
494 FIELD_PREP(RG_TG_MAX_MSK, 0x0e));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200495 clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL1,
496 RG_IDRV_0DB_GEN1_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800497 FIELD_PREP(RG_IDRV_0DB_GEN1_MSK, 0x20));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200498 clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL1,
499 RG_EQ_DLEQ_LFI_GEN1_MSK,
Chunfeng Yun5241fc82023-02-17 17:04:08 +0800500 FIELD_PREP(RG_EQ_DLEQ_LFI_GEN1_MSK, 0x03));
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200501}
502
Ryder Lee235bad02019-08-22 12:26:50 +0200503static void pcie_phy_instance_power_on(struct mtk_tphy *tphy,
504 struct mtk_phy_instance *instance)
505{
506 struct u3phy_banks *bank = &instance->u3_banks;
507
508 clrbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLD,
509 P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
510 clrbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLE,
511 P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
512}
513
514static void pcie_phy_instance_power_off(struct mtk_tphy *tphy,
515 struct mtk_phy_instance *instance)
516
517{
518 struct u3phy_banks *bank = &instance->u3_banks;
519
520 setbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLD,
521 P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
522 setbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLE,
523 P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
524}
525
526static void phy_v1_banks_init(struct mtk_tphy *tphy,
527 struct mtk_phy_instance *instance)
528{
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200529 struct u2phy_banks *u2_banks = &instance->u2_banks;
Ryder Lee235bad02019-08-22 12:26:50 +0200530 struct u3phy_banks *u3_banks = &instance->u3_banks;
531
532 switch (instance->type) {
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200533 case PHY_TYPE_USB2:
534 u2_banks->misc = NULL;
535 u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
536 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
537 break;
538 case PHY_TYPE_USB3:
Ryder Lee235bad02019-08-22 12:26:50 +0200539 case PHY_TYPE_PCIE:
540 u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
541 u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
542 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
543 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
544 break;
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200545 case PHY_TYPE_SATA:
546 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
547 break;
Ryder Lee235bad02019-08-22 12:26:50 +0200548 default:
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200549 dev_err(tphy->dev, "incompatible PHY type\n");
Ryder Lee235bad02019-08-22 12:26:50 +0200550 return;
551 }
552}
553
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200554static void phy_v2_banks_init(struct mtk_tphy *tphy,
555 struct mtk_phy_instance *instance)
556{
557 struct u2phy_banks *u2_banks = &instance->u2_banks;
558 struct u3phy_banks *u3_banks = &instance->u3_banks;
559
560 switch (instance->type) {
561 case PHY_TYPE_USB2:
562 u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
563 u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
564 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
565 break;
566 case PHY_TYPE_USB3:
567 case PHY_TYPE_PCIE:
568 u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
569 u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
570 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
571 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
572 break;
573 default:
574 dev_err(tphy->dev, "incompatible PHY type\n");
575 return;
576 }
577}
578
Chunfeng Yun4f6dd252023-12-13 14:41:34 +0800579static void phy_parse_property(struct mtk_tphy *tphy,
580 struct mtk_phy_instance *instance)
581{
582 ofnode node = np_to_ofnode(instance->np);
583
584 if (instance->type != PHY_TYPE_USB2)
585 return;
586
587 ofnode_read_u32(node, "mediatek,eye-vrt", &instance->eye_vrt);
588 ofnode_read_u32(node, "mediatek,eye-term", &instance->eye_term);
589 ofnode_read_u32(node, "mediatek,discth", &instance->discth);
590 ofnode_read_u32(node, "mediatek,pre-emphasis", &instance->pre_emphasis);
591
592 dev_dbg(tphy->dev, "vrt:%d, term:%d, disc:%d, emp:%d\n",
593 instance->eye_vrt, instance->eye_term,
594 instance->discth, instance->pre_emphasis);
595}
596
597static void u2_phy_props_set(struct mtk_tphy *tphy,
598 struct mtk_phy_instance *instance)
599{
600 struct u2phy_banks *u2_banks = &instance->u2_banks;
601 void __iomem *com = u2_banks->com;
602
603 if (instance->eye_vrt)
604 clrsetbits_le32(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL,
605 FIELD_PREP(PA1_RG_VRT_SEL, instance->eye_vrt));
606
607 if (instance->eye_term)
608 clrsetbits_le32(com + U3P_USBPHYACR1, PA1_RG_TERM_SEL,
609 FIELD_PREP(PA1_RG_TERM_SEL, instance->eye_term));
610
611 if (instance->discth)
612 clrsetbits_le32(com + U3P_USBPHYACR6, PA6_RG_U2_DISCTH,
613 FIELD_PREP(PA6_RG_U2_DISCTH, instance->discth));
614
615 if (instance->pre_emphasis)
616 clrsetbits_le32(com + U3P_USBPHYACR6, PA6_RG_U2_PRE_EMP,
617 FIELD_PREP(PA6_RG_U2_PRE_EMP, instance->pre_emphasis));
618}
619
Ryder Lee235bad02019-08-22 12:26:50 +0200620static int mtk_phy_init(struct phy *phy)
621{
622 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
623 struct mtk_phy_instance *instance = tphy->phys[phy->id];
624 int ret;
625
Ryder Lee235bad02019-08-22 12:26:50 +0200626 ret = clk_enable(&instance->ref_clk);
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200627 if (ret < 0) {
628 dev_err(tphy->dev, "failed to enable ref_clk\n");
Ryder Lee235bad02019-08-22 12:26:50 +0200629 return ret;
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200630 }
631
632 ret = clk_enable(&instance->da_ref_clk);
633 if (ret < 0) {
634 dev_err(tphy->dev, "failed to enable da_ref_clk %d\n", ret);
635 clk_disable(&instance->ref_clk);
636 return ret;
637 }
Ryder Lee235bad02019-08-22 12:26:50 +0200638
639 switch (instance->type) {
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200640 case PHY_TYPE_USB2:
641 u2_phy_instance_init(tphy, instance);
Chunfeng Yun4f6dd252023-12-13 14:41:34 +0800642 u2_phy_props_set(tphy, instance);
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200643 break;
644 case PHY_TYPE_USB3:
645 u3_phy_instance_init(tphy, instance);
646 break;
Ryder Lee235bad02019-08-22 12:26:50 +0200647 case PHY_TYPE_PCIE:
648 pcie_phy_instance_init(tphy, instance);
649 break;
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200650 case PHY_TYPE_SATA:
651 sata_phy_instance_init(tphy, instance);
652 break;
Ryder Lee235bad02019-08-22 12:26:50 +0200653 default:
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200654 dev_err(tphy->dev, "incompatible PHY type\n");
Ryder Lee235bad02019-08-22 12:26:50 +0200655 return -EINVAL;
656 }
657
658 return 0;
659}
660
661static int mtk_phy_power_on(struct phy *phy)
662{
663 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
664 struct mtk_phy_instance *instance = tphy->phys[phy->id];
665
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200666 if (instance->type == PHY_TYPE_USB2)
667 u2_phy_instance_power_on(tphy, instance);
668 else if (instance->type == PHY_TYPE_PCIE)
669 pcie_phy_instance_power_on(tphy, instance);
Ryder Lee235bad02019-08-22 12:26:50 +0200670
671 return 0;
672}
673
674static int mtk_phy_power_off(struct phy *phy)
675{
676 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
677 struct mtk_phy_instance *instance = tphy->phys[phy->id];
678
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200679 if (instance->type == PHY_TYPE_USB2)
680 u2_phy_instance_power_off(tphy, instance);
681 else if (instance->type == PHY_TYPE_PCIE)
682 pcie_phy_instance_power_off(tphy, instance);
Ryder Lee235bad02019-08-22 12:26:50 +0200683
684 return 0;
685}
686
687static int mtk_phy_exit(struct phy *phy)
688{
689 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
690 struct mtk_phy_instance *instance = tphy->phys[phy->id];
691
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200692 clk_disable(&instance->da_ref_clk);
Ryder Lee235bad02019-08-22 12:26:50 +0200693 clk_disable(&instance->ref_clk);
694
695 return 0;
696}
697
698static int mtk_phy_xlate(struct phy *phy,
699 struct ofnode_phandle_args *args)
700{
701 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
702 struct mtk_phy_instance *instance = NULL;
703 const struct device_node *phy_np = ofnode_to_np(args->node);
704 u32 index;
705
706 if (!phy_np) {
707 dev_err(phy->dev, "null pointer phy node\n");
708 return -EINVAL;
709 }
710
711 if (args->args_count < 1) {
712 dev_err(phy->dev, "invalid number of cells in 'phy' property\n");
713 return -EINVAL;
714 }
715
716 for (index = 0; index < tphy->nphys; index++)
717 if (phy_np == tphy->phys[index]->np) {
718 instance = tphy->phys[index];
719 break;
720 }
721
722 if (!instance) {
723 dev_err(phy->dev, "failed to find appropriate phy\n");
724 return -EINVAL;
725 }
726
727 phy->id = index;
728 instance->type = args->args[1];
729 if (!(instance->type == PHY_TYPE_USB2 ||
730 instance->type == PHY_TYPE_USB3 ||
Frank Wunderlichffbcde22020-08-13 10:20:45 +0200731 instance->type == PHY_TYPE_SATA ||
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200732 instance->type == PHY_TYPE_PCIE)) {
Ryder Lee235bad02019-08-22 12:26:50 +0200733 dev_err(phy->dev, "unsupported device type\n");
734 return -EINVAL;
735 }
736
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800737 switch (tphy->pdata->version) {
738 case MTK_TPHY_V1:
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200739 phy_v1_banks_init(tphy, instance);
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800740 break;
741 case MTK_TPHY_V2:
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200742 phy_v2_banks_init(tphy, instance);
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800743 break;
744 default:
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200745 dev_err(phy->dev, "phy version is not supported\n");
746 return -EINVAL;
747 }
Ryder Lee235bad02019-08-22 12:26:50 +0200748
Chunfeng Yun4f6dd252023-12-13 14:41:34 +0800749 phy_parse_property(tphy, instance);
750
Ryder Lee235bad02019-08-22 12:26:50 +0200751 return 0;
752}
753
754static const struct phy_ops mtk_tphy_ops = {
755 .init = mtk_phy_init,
756 .exit = mtk_phy_exit,
757 .power_on = mtk_phy_power_on,
758 .power_off = mtk_phy_power_off,
759 .of_xlate = mtk_phy_xlate,
760};
761
762static int mtk_tphy_probe(struct udevice *dev)
763{
764 struct mtk_tphy *tphy = dev_get_priv(dev);
765 ofnode subnode;
766 int index = 0;
767
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200768 tphy->nphys = dev_get_child_count(dev);
Ryder Lee235bad02019-08-22 12:26:50 +0200769
770 tphy->phys = devm_kcalloc(dev, tphy->nphys, sizeof(*tphy->phys),
771 GFP_KERNEL);
772 if (!tphy->phys)
773 return -ENOMEM;
774
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200775 tphy->dev = dev;
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800776 tphy->pdata = (void *)dev_get_driver_data(dev);
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200777
Frank Wunderlich626892a2020-08-20 16:37:52 +0200778 /* v1 has shared banks for usb/pcie mode, */
779 /* but not for sata mode */
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800780 if (tphy->pdata->version == MTK_TPHY_V1)
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200781 tphy->sif_base = dev_read_addr_ptr(dev);
Ryder Lee235bad02019-08-22 12:26:50 +0200782
783 dev_for_each_subnode(subnode, dev) {
784 struct mtk_phy_instance *instance;
785 fdt_addr_t addr;
786 int err;
787
788 instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
789 if (!instance)
790 return -ENOMEM;
791
792 addr = ofnode_get_addr(subnode);
793 if (addr == FDT_ADDR_T_NONE)
794 return -ENOMEM;
795
796 instance->port_base = map_sysmem(addr, 0);
797 instance->index = index;
798 instance->np = ofnode_to_np(subnode);
799 tphy->phys[index] = instance;
800 index++;
801
Sean Anderson011bbfb2021-12-22 12:11:10 -0500802 err = clk_get_by_name_nodev_optional(subnode, "ref",
803 &instance->ref_clk);
Ryder Lee235bad02019-08-22 12:26:50 +0200804 if (err)
805 return err;
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200806
Sean Anderson011bbfb2021-12-22 12:11:10 -0500807 err = clk_get_by_name_nodev_optional(subnode, "da_ref",
808 &instance->da_ref_clk);
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200809 if (err)
810 return err;
Ryder Lee235bad02019-08-22 12:26:50 +0200811 }
812
813 return 0;
814}
815
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800816static struct tphy_pdata tphy_v1_pdata = {
817 .version = MTK_TPHY_V1,
818};
819
820static struct tphy_pdata tphy_v2_pdata = {
821 .version = MTK_TPHY_V2,
822};
823
824static struct tphy_pdata mt8195_pdata = {
825 .version = MTK_TPHY_V2,
826 .sw_pll_48m_to_26m = true,
827};
828
Ryder Lee235bad02019-08-22 12:26:50 +0200829static const struct udevice_id mtk_tphy_id_table[] = {
Chunfeng Yun39b854a2023-02-17 17:04:09 +0800830 {
831 .compatible = "mediatek,generic-tphy-v1",
832 .data = (ulong)&tphy_v1_pdata,
833 },
834 {
835 .compatible = "mediatek,generic-tphy-v2",
836 .data = (ulong)&tphy_v2_pdata,
837 },
838 {
839 .compatible = "mediatek,mt8195-tphy",
840 .data = (ulong)&mt8195_pdata,
841 },
Ryder Lee235bad02019-08-22 12:26:50 +0200842 { }
843};
844
845U_BOOT_DRIVER(mtk_tphy) = {
846 .name = "mtk-tphy",
847 .id = UCLASS_PHY,
848 .of_match = mtk_tphy_id_table,
849 .ops = &mtk_tphy_ops,
850 .probe = mtk_tphy_probe,
Simon Glass41575d82020-12-03 16:55:17 -0700851 .priv_auto = sizeof(struct mtk_tphy),
Ryder Lee235bad02019-08-22 12:26:50 +0200852};