blob: 0a45dc586297415380742220a47563dd3795b135 [file] [log] [blame]
developer7b27b8d2019-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
developer7b27b8d2019-08-22 12:26:50 +02008#include <clk.h>
9#include <dm.h>
10#include <generic-phy.h>
Simon Glass9bc15642020-02-03 07:36:16 -070011#include <malloc.h>
developer7b27b8d2019-08-22 12:26:50 +020012#include <mapmem.h>
Christian Marangi198a3782024-06-24 23:03:27 +020013#include <regmap.h>
14#include <syscon.h>
developer7b27b8d2019-08-22 12:26:50 +020015#include <asm/io.h>
Simon Glass9bc15642020-02-03 07:36:16 -070016#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070017#include <dm/devres.h>
developerad4890f2023-02-17 17:04:08 +080018#include <linux/bitfield.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060019#include <linux/bitops.h>
Simon Glassdbd79542020-05-10 11:40:11 -060020#include <linux/delay.h>
developer7b27b8d2019-08-22 12:26:50 +020021
22#include <dt-bindings/phy/phy.h>
23
24/* version V1 sub-banks offset base address */
25/* banks shared by multiple phys */
26#define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */
developer8a17d5f2020-05-02 11:35:15 +020027#define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */
developer7b27b8d2019-08-22 12:26:50 +020028#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */
developer8a17d5f2020-05-02 11:35:15 +020029/* u2 phy bank */
30#define SSUSB_SIFSLV_V1_U2PHY_COM 0x000
developer7b27b8d2019-08-22 12:26:50 +020031/* u3/pcie/sata phy banks */
32#define SSUSB_SIFSLV_V1_U3PHYD 0x000
33#define SSUSB_SIFSLV_V1_U3PHYA 0x200
34
developer8b302602020-05-02 11:35:16 +020035/* version V2 sub-banks offset base address */
36/* u2 phy banks */
37#define SSUSB_SIFSLV_V2_MISC 0x000
38#define SSUSB_SIFSLV_V2_U2FREQ 0x100
39#define SSUSB_SIFSLV_V2_U2PHY_COM 0x300
40/* u3/pcie/sata phy banks */
41#define SSUSB_SIFSLV_V2_SPLLC 0x000
42#define SSUSB_SIFSLV_V2_CHIP 0x100
43#define SSUSB_SIFSLV_V2_U3PHYD 0x200
44#define SSUSB_SIFSLV_V2_U3PHYA 0x400
45
developer8a17d5f2020-05-02 11:35:15 +020046#define U3P_USBPHYACR0 0x000
47#define PA0_RG_U2PLL_FORCE_ON BIT(15)
developer53cecc02023-02-17 17:04:09 +080048#define PA0_USB20_PLL_PREDIV GENMASK(7, 6)
developer8a17d5f2020-05-02 11:35:15 +020049#define PA0_RG_USB20_INTR_EN BIT(5)
50
developer9a9c3342023-12-13 14:41:34 +080051#define U3P_USBPHYACR1 0x004
52#define PA1_RG_INTR_CAL GENMASK(23, 19)
53#define PA1_RG_VRT_SEL GENMASK(14, 12)
54#define PA1_RG_TERM_SEL GENMASK(10, 8)
55
developer53cecc02023-02-17 17:04:09 +080056#define U3P_USBPHYACR2 0x008
57#define PA2_RG_U2PLL_BW GENMASK(21, 19)
58
developer8a17d5f2020-05-02 11:35:15 +020059#define U3P_USBPHYACR5 0x014
60#define PA5_RG_U2_HSTX_SRCAL_EN BIT(15)
61#define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12)
developer8a17d5f2020-05-02 11:35:15 +020062#define PA5_RG_U2_HS_100U_U3_EN BIT(11)
63
64#define U3P_USBPHYACR6 0x018
developer9a9c3342023-12-13 14:41:34 +080065#define PA6_RG_U2_PRE_EMP GENMASK(31, 30)
developer8a17d5f2020-05-02 11:35:15 +020066#define PA6_RG_U2_BC11_SW_EN BIT(23)
67#define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20)
developer9a9c3342023-12-13 14:41:34 +080068#define PA6_RG_U2_DISCTH GENMASK(7, 4)
developer8a17d5f2020-05-02 11:35:15 +020069#define PA6_RG_U2_SQTH GENMASK(3, 0)
developer8a17d5f2020-05-02 11:35:15 +020070
71#define U3P_U2PHYACR4 0x020
72#define P2C_RG_USB20_GPIO_CTL BIT(9)
73#define P2C_USB20_GPIO_MODE BIT(8)
74#define P2C_U2_GPIO_CTR_MSK \
75 (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
76
developer53cecc02023-02-17 17:04:09 +080077#define U3P_U2PHYA_RESV 0x030
78#define P2R_RG_U2PLL_FBDIV_26M 0x1bb13b
79#define P2R_RG_U2PLL_FBDIV_48M 0x3c0000
80
81#define U3P_U2PHYA_RESV1 0x044
82#define P2R_RG_U2PLL_REFCLK_SEL BIT(5)
83#define P2R_RG_U2PLL_FRA_EN BIT(3)
84
developer8a17d5f2020-05-02 11:35:15 +020085#define U3P_U2PHYDTM0 0x068
86#define P2C_FORCE_UART_EN BIT(26)
87#define P2C_FORCE_DATAIN BIT(23)
88#define P2C_FORCE_DM_PULLDOWN BIT(21)
89#define P2C_FORCE_DP_PULLDOWN BIT(20)
90#define P2C_FORCE_XCVRSEL BIT(19)
91#define P2C_FORCE_SUSPENDM BIT(18)
92#define P2C_FORCE_TERMSEL BIT(17)
93#define P2C_RG_DATAIN GENMASK(13, 10)
developer8a17d5f2020-05-02 11:35:15 +020094#define P2C_RG_DMPULLDOWN BIT(7)
95#define P2C_RG_DPPULLDOWN BIT(6)
96#define P2C_RG_XCVRSEL GENMASK(5, 4)
developer8a17d5f2020-05-02 11:35:15 +020097#define P2C_RG_SUSPENDM BIT(3)
98#define P2C_RG_TERMSEL BIT(2)
99#define P2C_DTM0_PART_MASK \
100 (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
101 P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
102 P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
103 P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
104
105#define U3P_U2PHYDTM1 0x06C
106#define P2C_RG_UART_EN BIT(16)
107#define P2C_FORCE_IDDIG BIT(9)
108#define P2C_RG_VBUSVALID BIT(5)
109#define P2C_RG_SESSEND BIT(4)
110#define P2C_RG_AVALID BIT(2)
111#define P2C_RG_IDDIG BIT(1)
112
developer7b27b8d2019-08-22 12:26:50 +0200113#define U3P_U3_CHIP_GPIO_CTLD 0x0c
114#define P3C_REG_IP_SW_RST BIT(31)
115#define P3C_MCU_BUS_CK_GATE_EN BIT(30)
116#define P3C_FORCE_IP_SW_RST BIT(29)
117
118#define U3P_U3_CHIP_GPIO_CTLE 0x10
119#define P3C_RG_SWRST_U3_PHYD BIT(25)
120#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
121
122#define U3P_U3_PHYA_REG0 0x000
123#define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
developer7b27b8d2019-08-22 12:26:50 +0200124
125#define U3P_U3_PHYA_REG1 0x004
126#define P3A_RG_CLKDRV_AMP GENMASK(31, 29)
developer7b27b8d2019-08-22 12:26:50 +0200127
developer8a17d5f2020-05-02 11:35:15 +0200128#define U3P_U3_PHYA_REG6 0x018
129#define P3A_RG_TX_EIDLE_CM GENMASK(31, 28)
developer8a17d5f2020-05-02 11:35:15 +0200130
131#define U3P_U3_PHYA_REG9 0x024
132#define P3A_RG_RX_DAC_MUX GENMASK(5, 1)
developer8a17d5f2020-05-02 11:35:15 +0200133
developer7b27b8d2019-08-22 12:26:50 +0200134#define U3P_U3_PHYA_DA_REG0 0x100
135#define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16)
developer7b27b8d2019-08-22 12:26:50 +0200136#define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12)
developer7b27b8d2019-08-22 12:26:50 +0200137#define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10)
developer7b27b8d2019-08-22 12:26:50 +0200138
139#define U3P_U3_PHYA_DA_REG4 0x108
140#define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19)
141#define P3A_RG_PLL_BC_PE2H GENMASK(7, 6)
developer7b27b8d2019-08-22 12:26:50 +0200142
143#define U3P_U3_PHYA_DA_REG5 0x10c
144#define P3A_RG_PLL_BR_PE2H GENMASK(29, 28)
developer7b27b8d2019-08-22 12:26:50 +0200145#define P3A_RG_PLL_IC_PE2H GENMASK(15, 12)
developer7b27b8d2019-08-22 12:26:50 +0200146
147#define U3P_U3_PHYA_DA_REG6 0x110
148#define P3A_RG_PLL_IR_PE2H GENMASK(19, 16)
developer7b27b8d2019-08-22 12:26:50 +0200149
150#define U3P_U3_PHYA_DA_REG7 0x114
151#define P3A_RG_PLL_BP_PE2H GENMASK(19, 16)
developer7b27b8d2019-08-22 12:26:50 +0200152
153#define U3P_U3_PHYA_DA_REG20 0x13c
154#define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16)
developer7b27b8d2019-08-22 12:26:50 +0200155
156#define U3P_U3_PHYA_DA_REG25 0x148
157#define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0)
developer7b27b8d2019-08-22 12:26:50 +0200158
developer8a17d5f2020-05-02 11:35:15 +0200159#define U3P_U3_PHYD_LFPS1 0x00c
160#define P3D_RG_FWAKE_TH GENMASK(21, 16)
developer8a17d5f2020-05-02 11:35:15 +0200161
162#define U3P_U3_PHYD_CDR1 0x05c
163#define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
developer8a17d5f2020-05-02 11:35:15 +0200164#define P3D_RG_CDR_BIR_LTD0 GENMASK(12, 8)
developer8a17d5f2020-05-02 11:35:15 +0200165
developer7b27b8d2019-08-22 12:26:50 +0200166#define U3P_U3_PHYD_RXDET1 0x128
167#define P3D_RG_RXDET_STB2_SET GENMASK(17, 9)
developer7b27b8d2019-08-22 12:26:50 +0200168
169#define U3P_U3_PHYD_RXDET2 0x12c
170#define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0)
developer7b27b8d2019-08-22 12:26:50 +0200171
developer8a17d5f2020-05-02 11:35:15 +0200172#define U3P_SPLLC_XTALCTL3 0x018
173#define XC3_RG_U3_XTAL_RX_PWD BIT(9)
174#define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8)
175
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200176/* SATA register setting */
177#define PHYD_CTRL_SIGNAL_MODE4 0x1c
178/* CDR Charge Pump P-path current adjustment */
179#define RG_CDR_BICLTD1_GEN1_MSK GENMASK(23, 20)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200180#define RG_CDR_BICLTD0_GEN1_MSK GENMASK(11, 8)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200181
182#define PHYD_DESIGN_OPTION2 0x24
183/* Symbol lock count selection */
184#define RG_LOCK_CNT_SEL_MSK GENMASK(5, 4)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200185
186#define PHYD_DESIGN_OPTION9 0x40
187/* COMWAK GAP width window */
188#define RG_TG_MAX_MSK GENMASK(20, 16)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200189/* COMINIT GAP width window */
190#define RG_T2_MAX_MSK GENMASK(13, 8)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200191/* COMWAK GAP width window */
192#define RG_TG_MIN_MSK GENMASK(7, 5)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200193/* COMINIT GAP width window */
194#define RG_T2_MIN_MSK GENMASK(4, 0)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200195
196#define ANA_RG_CTRL_SIGNAL1 0x4c
197/* TX driver tail current control for 0dB de-empahsis mdoe for Gen1 speed */
198#define RG_IDRV_0DB_GEN1_MSK GENMASK(13, 8)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200199
200#define ANA_RG_CTRL_SIGNAL4 0x58
201#define RG_CDR_BICLTR_GEN1_MSK GENMASK(23, 20)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200202/* Loop filter R1 resistance adjustment for Gen1 speed */
203#define RG_CDR_BR_GEN2_MSK GENMASK(10, 8)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200204
205#define ANA_RG_CTRL_SIGNAL6 0x60
206/* I-path capacitance adjustment for Gen1 */
207#define RG_CDR_BC_GEN1_MSK GENMASK(28, 24)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200208#define RG_CDR_BIRLTR_GEN1_MSK GENMASK(4, 0)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200209
210#define ANA_EQ_EYE_CTRL_SIGNAL1 0x6c
211/* RX Gen1 LEQ tuning step */
212#define RG_EQ_DLEQ_LFI_GEN1_MSK GENMASK(11, 8)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200213
214#define ANA_EQ_EYE_CTRL_SIGNAL4 0xd8
215#define RG_CDR_BIRLTD0_GEN1_MSK GENMASK(20, 16)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200216
217#define ANA_EQ_EYE_CTRL_SIGNAL5 0xdc
218#define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0)
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200219
Christian Marangi198a3782024-06-24 23:03:27 +0200220/* PHY switch between pcie/usb3/sgmii/sata */
221#define USB_PHY_SWITCH_CTRL 0x0
222#define RG_PHY_SW_TYPE GENMASK(3, 0)
223#define RG_PHY_SW_PCIE 0x0
224#define RG_PHY_SW_USB3 0x1
225#define RG_PHY_SW_SGMII 0x2
226#define RG_PHY_SW_SATA 0x3
227
developer8b302602020-05-02 11:35:16 +0200228enum mtk_phy_version {
229 MTK_TPHY_V1 = 1,
230 MTK_TPHY_V2,
231};
232
developer53cecc02023-02-17 17:04:09 +0800233struct tphy_pdata {
234 enum mtk_phy_version version;
235
236 /*
237 * workaround only for mt8195:
238 * u2phy should use integer mode instead of fractional mode of
239 * 48M PLL, fix it by switching PLL to 26M from default 48M
240 */
241 bool sw_pll_48m_to_26m;
242};
243
developer8a17d5f2020-05-02 11:35:15 +0200244struct u2phy_banks {
245 void __iomem *misc;
246 void __iomem *fmreg;
247 void __iomem *com;
248};
249
developer7b27b8d2019-08-22 12:26:50 +0200250struct u3phy_banks {
251 void __iomem *spllc;
252 void __iomem *chip;
253 void __iomem *phyd; /* include u3phyd_bank2 */
254 void __iomem *phya; /* include u3phya_da */
255};
256
257struct mtk_phy_instance {
258 void __iomem *port_base;
developer9a9c3342023-12-13 14:41:34 +0800259 struct device_node *np;
developer8a17d5f2020-05-02 11:35:15 +0200260 union {
261 struct u2phy_banks u2_banks;
262 struct u3phy_banks u3_banks;
263 };
developer7b27b8d2019-08-22 12:26:50 +0200264
developer54acbc32020-05-02 11:35:17 +0200265 struct clk ref_clk; /* reference clock of (digital) phy */
266 struct clk da_ref_clk; /* reference clock of analog phy */
developer7b27b8d2019-08-22 12:26:50 +0200267 u32 index;
developer8a17d5f2020-05-02 11:35:15 +0200268 u32 type;
developer9a9c3342023-12-13 14:41:34 +0800269
Christian Marangi198a3782024-06-24 23:03:27 +0200270 struct regmap *type_sw;
271 u32 type_sw_reg;
272 u32 type_sw_index;
273
developer9a9c3342023-12-13 14:41:34 +0800274 u32 eye_vrt;
275 u32 eye_term;
276 u32 discth;
277 u32 pre_emphasis;
developer7b27b8d2019-08-22 12:26:50 +0200278};
279
280struct mtk_tphy {
developer8a17d5f2020-05-02 11:35:15 +0200281 struct udevice *dev;
developer7b27b8d2019-08-22 12:26:50 +0200282 void __iomem *sif_base;
developer53cecc02023-02-17 17:04:09 +0800283 const struct tphy_pdata *pdata;
developer7b27b8d2019-08-22 12:26:50 +0200284 struct mtk_phy_instance **phys;
285 int nphys;
286};
287
developer53cecc02023-02-17 17:04:09 +0800288/* workaround only for mt8195 */
289static void u2_phy_pll_26m_set(struct mtk_tphy *tphy,
290 struct mtk_phy_instance *instance)
291{
292 struct u2phy_banks *u2_banks = &instance->u2_banks;
293
294 if (!tphy->pdata->sw_pll_48m_to_26m)
295 return;
296
297 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR0, PA0_USB20_PLL_PREDIV,
298 FIELD_PREP(PA0_USB20_PLL_PREDIV, 0));
299
300 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR2, PA2_RG_U2PLL_BW,
301 FIELD_PREP(PA2_RG_U2PLL_BW, 3));
302
303 writel(P2R_RG_U2PLL_FBDIV_26M, u2_banks->com + U3P_U2PHYA_RESV);
304
305 setbits_le32(u2_banks->com + U3P_U2PHYA_RESV1,
306 P2R_RG_U2PLL_FRA_EN | P2R_RG_U2PLL_REFCLK_SEL);
307}
308
developer8a17d5f2020-05-02 11:35:15 +0200309static void u2_phy_instance_init(struct mtk_tphy *tphy,
310 struct mtk_phy_instance *instance)
311{
312 struct u2phy_banks *u2_banks = &instance->u2_banks;
313
314 /* switch to USB function, and enable usb pll */
315 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM0,
316 P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM,
developerad4890f2023-02-17 17:04:08 +0800317 FIELD_PREP(P2C_RG_XCVRSEL, 1) |
318 FIELD_PREP(P2C_RG_DATAIN, 0));
developer8a17d5f2020-05-02 11:35:15 +0200319
320 clrbits_le32(u2_banks->com + U3P_U2PHYDTM1, P2C_RG_UART_EN);
321 setbits_le32(u2_banks->com + U3P_USBPHYACR0, PA0_RG_USB20_INTR_EN);
322
323 /* disable switch 100uA current to SSUSB */
324 clrbits_le32(u2_banks->com + U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN);
325
326 clrbits_le32(u2_banks->com + U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK);
327
328 /* DP/DM BC1.1 path Disable */
329 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR6,
330 PA6_RG_U2_BC11_SW_EN | PA6_RG_U2_SQTH,
developerad4890f2023-02-17 17:04:08 +0800331 FIELD_PREP(PA6_RG_U2_SQTH, 2));
developer8a17d5f2020-05-02 11:35:15 +0200332
333 /* set HS slew rate */
334 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR5,
developerad4890f2023-02-17 17:04:08 +0800335 PA5_RG_U2_HSTX_SRCTRL,
336 FIELD_PREP(PA5_RG_U2_HSTX_SRCTRL, 4));
developer8a17d5f2020-05-02 11:35:15 +0200337
developer53cecc02023-02-17 17:04:09 +0800338 u2_phy_pll_26m_set(tphy, instance);
339
developer8a17d5f2020-05-02 11:35:15 +0200340 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
341}
342
343static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
344 struct mtk_phy_instance *instance)
345{
346 struct u2phy_banks *u2_banks = &instance->u2_banks;
347
348 clrbits_le32(u2_banks->com + U3P_U2PHYDTM0,
349 P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
350
351 /* OTG Enable */
352 setbits_le32(u2_banks->com + U3P_USBPHYACR6,
353 PA6_RG_U2_OTG_VBUSCMP_EN);
354
355 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM1,
356 P2C_RG_SESSEND, P2C_RG_VBUSVALID | P2C_RG_AVALID);
357
358 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
359}
360
361static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
362 struct mtk_phy_instance *instance)
363{
364 struct u2phy_banks *u2_banks = &instance->u2_banks;
365
366 clrbits_le32(u2_banks->com + U3P_U2PHYDTM0,
367 P2C_RG_XCVRSEL | P2C_RG_DATAIN);
368
369 /* OTG Disable */
370 clrbits_le32(u2_banks->com + U3P_USBPHYACR6,
371 PA6_RG_U2_OTG_VBUSCMP_EN);
372
373 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM1,
374 P2C_RG_VBUSVALID | P2C_RG_AVALID, P2C_RG_SESSEND);
375
376 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
377}
378
379static void u3_phy_instance_init(struct mtk_tphy *tphy,
380 struct mtk_phy_instance *instance)
381{
382 struct u3phy_banks *u3_banks = &instance->u3_banks;
383
384 /* gating PCIe Analog XTAL clock */
385 setbits_le32(u3_banks->spllc + U3P_SPLLC_XTALCTL3,
386 XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD);
387
388 /* gating XSQ */
389 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
developerad4890f2023-02-17 17:04:08 +0800390 P3A_RG_XTAL_EXT_EN_U3,
391 FIELD_PREP(P3A_RG_XTAL_EXT_EN_U3, 2));
developer8a17d5f2020-05-02 11:35:15 +0200392
393 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG9,
developerad4890f2023-02-17 17:04:08 +0800394 P3A_RG_RX_DAC_MUX, FIELD_PREP(P3A_RG_RX_DAC_MUX, 4));
developer8a17d5f2020-05-02 11:35:15 +0200395
396 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG6,
developerad4890f2023-02-17 17:04:08 +0800397 P3A_RG_TX_EIDLE_CM,
398 FIELD_PREP(P3A_RG_TX_EIDLE_CM, 0xe));
developer8a17d5f2020-05-02 11:35:15 +0200399
400 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_CDR1,
401 P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1,
developerad4890f2023-02-17 17:04:08 +0800402 FIELD_PREP(P3D_RG_CDR_BIR_LTD0, 0xc) |
403 FIELD_PREP(P3D_RG_CDR_BIR_LTD1, 0x3));
developer8a17d5f2020-05-02 11:35:15 +0200404
405 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_LFPS1,
developerad4890f2023-02-17 17:04:08 +0800406 P3D_RG_FWAKE_TH, FIELD_PREP(P3D_RG_FWAKE_TH, 0x34));
developer8a17d5f2020-05-02 11:35:15 +0200407
408 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET1,
developerad4890f2023-02-17 17:04:08 +0800409 P3D_RG_RXDET_STB2_SET,
410 FIELD_PREP(P3D_RG_RXDET_STB2_SET, 0x10));
developer8a17d5f2020-05-02 11:35:15 +0200411
412 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET2,
413 P3D_RG_RXDET_STB2_SET_P3,
developerad4890f2023-02-17 17:04:08 +0800414 FIELD_PREP(P3D_RG_RXDET_STB2_SET_P3, 0x10));
developer8a17d5f2020-05-02 11:35:15 +0200415
416 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
417}
418
developer7b27b8d2019-08-22 12:26:50 +0200419static void pcie_phy_instance_init(struct mtk_tphy *tphy,
420 struct mtk_phy_instance *instance)
421{
422 struct u3phy_banks *u3_banks = &instance->u3_banks;
423
developer53cecc02023-02-17 17:04:09 +0800424 if (tphy->pdata->version != MTK_TPHY_V1)
developer8b302602020-05-02 11:35:16 +0200425 return;
426
developer7b27b8d2019-08-22 12:26:50 +0200427 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
428 P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
developerad4890f2023-02-17 17:04:08 +0800429 FIELD_PREP(P3A_RG_XTAL_EXT_PE1H, 0x2) |
430 FIELD_PREP(P3A_RG_XTAL_EXT_PE2H, 0x2));
developer7b27b8d2019-08-22 12:26:50 +0200431
432 /* ref clk drive */
433 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG1, P3A_RG_CLKDRV_AMP,
developerad4890f2023-02-17 17:04:08 +0800434 FIELD_PREP(P3A_RG_CLKDRV_AMP, 0x4));
developer7b27b8d2019-08-22 12:26:50 +0200435 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG0, P3A_RG_CLKDRV_OFF,
developerad4890f2023-02-17 17:04:08 +0800436 FIELD_PREP(P3A_RG_CLKDRV_OFF, 0x1));
developer7b27b8d2019-08-22 12:26:50 +0200437
438 /* SSC delta -5000ppm */
439 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG20,
440 P3A_RG_PLL_DELTA1_PE2H,
developerad4890f2023-02-17 17:04:08 +0800441 FIELD_PREP(P3A_RG_PLL_DELTA1_PE2H, 0x3c));
developer7b27b8d2019-08-22 12:26:50 +0200442
443 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG25,
444 P3A_RG_PLL_DELTA_PE2H,
developerad4890f2023-02-17 17:04:08 +0800445 FIELD_PREP(P3A_RG_PLL_DELTA_PE2H, 0x36));
developer7b27b8d2019-08-22 12:26:50 +0200446
447 /* change pll BW 0.6M */
448 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG5,
449 P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H,
developerad4890f2023-02-17 17:04:08 +0800450 FIELD_PREP(P3A_RG_PLL_BR_PE2H, 0x1) |
451 FIELD_PREP(P3A_RG_PLL_IC_PE2H, 0x1));
developer7b27b8d2019-08-22 12:26:50 +0200452 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG4,
453 P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H,
developerad4890f2023-02-17 17:04:08 +0800454 FIELD_PREP(P3A_RG_PLL_BC_PE2H, 0x3));
developer7b27b8d2019-08-22 12:26:50 +0200455
456 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG6,
developerad4890f2023-02-17 17:04:08 +0800457 P3A_RG_PLL_IR_PE2H,
458 FIELD_PREP(P3A_RG_PLL_IR_PE2H, 0x2));
developer7b27b8d2019-08-22 12:26:50 +0200459 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG7,
developerad4890f2023-02-17 17:04:08 +0800460 P3A_RG_PLL_BP_PE2H,
461 FIELD_PREP(P3A_RG_PLL_BP_PE2H, 0xa));
developer7b27b8d2019-08-22 12:26:50 +0200462
463 /* Tx Detect Rx Timing: 10us -> 5us */
464 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET1,
465 P3D_RG_RXDET_STB2_SET,
developerad4890f2023-02-17 17:04:08 +0800466 FIELD_PREP(P3D_RG_RXDET_STB2_SET, 0x10));
developer7b27b8d2019-08-22 12:26:50 +0200467 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET2,
468 P3D_RG_RXDET_STB2_SET_P3,
developerad4890f2023-02-17 17:04:08 +0800469 FIELD_PREP(P3D_RG_RXDET_STB2_SET_P3, 0x10));
developer7b27b8d2019-08-22 12:26:50 +0200470
471 /* wait for PCIe subsys register to active */
472 udelay(3000);
473}
474
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200475static void sata_phy_instance_init(struct mtk_tphy *tphy,
476 struct mtk_phy_instance *instance)
477{
478 struct u3phy_banks *u3_banks = &instance->u3_banks;
479
480 clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL6,
481 RG_CDR_BIRLTR_GEN1_MSK | RG_CDR_BC_GEN1_MSK,
developerad4890f2023-02-17 17:04:08 +0800482 FIELD_PREP(RG_CDR_BIRLTR_GEN1_MSK, 0x6) |
483 FIELD_PREP(RG_CDR_BC_GEN1_MSK, 0x1a));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200484 clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL4,
485 RG_CDR_BIRLTD0_GEN1_MSK,
developerad4890f2023-02-17 17:04:08 +0800486 FIELD_PREP(RG_CDR_BIRLTD0_GEN1_MSK, 0x18));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200487 clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL5,
488 RG_CDR_BIRLTD0_GEN3_MSK,
developerad4890f2023-02-17 17:04:08 +0800489 FIELD_PREP(RG_CDR_BIRLTD0_GEN3_MSK, 0x06));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200490 clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL4,
491 RG_CDR_BICLTR_GEN1_MSK | RG_CDR_BR_GEN2_MSK,
developerad4890f2023-02-17 17:04:08 +0800492 FIELD_PREP(RG_CDR_BICLTR_GEN1_MSK, 0x0c) |
493 FIELD_PREP(RG_CDR_BR_GEN2_MSK, 0x07));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200494 clrsetbits_le32(u3_banks->phyd + PHYD_CTRL_SIGNAL_MODE4,
495 RG_CDR_BICLTD0_GEN1_MSK | RG_CDR_BICLTD1_GEN1_MSK,
developerad4890f2023-02-17 17:04:08 +0800496 FIELD_PREP(RG_CDR_BICLTD0_GEN1_MSK, 0x08) |
497 FIELD_PREP(RG_CDR_BICLTD1_GEN1_MSK, 0x02));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200498 clrsetbits_le32(u3_banks->phyd + PHYD_DESIGN_OPTION2,
499 RG_LOCK_CNT_SEL_MSK,
developerad4890f2023-02-17 17:04:08 +0800500 FIELD_PREP(RG_LOCK_CNT_SEL_MSK, 0x02));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200501 clrsetbits_le32(u3_banks->phyd + PHYD_DESIGN_OPTION9,
502 RG_T2_MIN_MSK | RG_TG_MIN_MSK |
503 RG_T2_MAX_MSK | RG_TG_MAX_MSK,
developerad4890f2023-02-17 17:04:08 +0800504 FIELD_PREP(RG_T2_MIN_MSK, 0x12) |
505 FIELD_PREP(RG_TG_MIN_MSK, 0x04) |
506 FIELD_PREP(RG_T2_MAX_MSK, 0x31) |
507 FIELD_PREP(RG_TG_MAX_MSK, 0x0e));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200508 clrsetbits_le32(u3_banks->phyd + ANA_RG_CTRL_SIGNAL1,
509 RG_IDRV_0DB_GEN1_MSK,
developerad4890f2023-02-17 17:04:08 +0800510 FIELD_PREP(RG_IDRV_0DB_GEN1_MSK, 0x20));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200511 clrsetbits_le32(u3_banks->phyd + ANA_EQ_EYE_CTRL_SIGNAL1,
512 RG_EQ_DLEQ_LFI_GEN1_MSK,
developerad4890f2023-02-17 17:04:08 +0800513 FIELD_PREP(RG_EQ_DLEQ_LFI_GEN1_MSK, 0x03));
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200514}
515
developer7b27b8d2019-08-22 12:26:50 +0200516static void pcie_phy_instance_power_on(struct mtk_tphy *tphy,
517 struct mtk_phy_instance *instance)
518{
519 struct u3phy_banks *bank = &instance->u3_banks;
520
521 clrbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLD,
522 P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
523 clrbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLE,
524 P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
525}
526
527static void pcie_phy_instance_power_off(struct mtk_tphy *tphy,
528 struct mtk_phy_instance *instance)
529
530{
531 struct u3phy_banks *bank = &instance->u3_banks;
532
533 setbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLD,
534 P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
535 setbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLE,
536 P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
537}
538
539static void phy_v1_banks_init(struct mtk_tphy *tphy,
540 struct mtk_phy_instance *instance)
541{
developer8a17d5f2020-05-02 11:35:15 +0200542 struct u2phy_banks *u2_banks = &instance->u2_banks;
developer7b27b8d2019-08-22 12:26:50 +0200543 struct u3phy_banks *u3_banks = &instance->u3_banks;
544
545 switch (instance->type) {
developer8a17d5f2020-05-02 11:35:15 +0200546 case PHY_TYPE_USB2:
547 u2_banks->misc = NULL;
548 u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
549 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
550 break;
551 case PHY_TYPE_USB3:
developer7b27b8d2019-08-22 12:26:50 +0200552 case PHY_TYPE_PCIE:
553 u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
554 u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
555 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
556 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
557 break;
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200558 case PHY_TYPE_SATA:
559 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
560 break;
developer7b27b8d2019-08-22 12:26:50 +0200561 default:
developer8a17d5f2020-05-02 11:35:15 +0200562 dev_err(tphy->dev, "incompatible PHY type\n");
developer7b27b8d2019-08-22 12:26:50 +0200563 return;
564 }
565}
566
developer8b302602020-05-02 11:35:16 +0200567static void phy_v2_banks_init(struct mtk_tphy *tphy,
568 struct mtk_phy_instance *instance)
569{
570 struct u2phy_banks *u2_banks = &instance->u2_banks;
571 struct u3phy_banks *u3_banks = &instance->u3_banks;
572
573 switch (instance->type) {
574 case PHY_TYPE_USB2:
575 u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
576 u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
577 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
578 break;
579 case PHY_TYPE_USB3:
580 case PHY_TYPE_PCIE:
581 u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
582 u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
583 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
584 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
585 break;
586 default:
587 dev_err(tphy->dev, "incompatible PHY type\n");
588 return;
589 }
590}
591
developer9a9c3342023-12-13 14:41:34 +0800592static void phy_parse_property(struct mtk_tphy *tphy,
593 struct mtk_phy_instance *instance)
594{
595 ofnode node = np_to_ofnode(instance->np);
596
597 if (instance->type != PHY_TYPE_USB2)
598 return;
599
600 ofnode_read_u32(node, "mediatek,eye-vrt", &instance->eye_vrt);
601 ofnode_read_u32(node, "mediatek,eye-term", &instance->eye_term);
602 ofnode_read_u32(node, "mediatek,discth", &instance->discth);
603 ofnode_read_u32(node, "mediatek,pre-emphasis", &instance->pre_emphasis);
604
605 dev_dbg(tphy->dev, "vrt:%d, term:%d, disc:%d, emp:%d\n",
606 instance->eye_vrt, instance->eye_term,
607 instance->discth, instance->pre_emphasis);
608}
609
610static void u2_phy_props_set(struct mtk_tphy *tphy,
611 struct mtk_phy_instance *instance)
612{
613 struct u2phy_banks *u2_banks = &instance->u2_banks;
614 void __iomem *com = u2_banks->com;
615
616 if (instance->eye_vrt)
617 clrsetbits_le32(com + U3P_USBPHYACR1, PA1_RG_VRT_SEL,
618 FIELD_PREP(PA1_RG_VRT_SEL, instance->eye_vrt));
619
620 if (instance->eye_term)
621 clrsetbits_le32(com + U3P_USBPHYACR1, PA1_RG_TERM_SEL,
622 FIELD_PREP(PA1_RG_TERM_SEL, instance->eye_term));
623
624 if (instance->discth)
625 clrsetbits_le32(com + U3P_USBPHYACR6, PA6_RG_U2_DISCTH,
626 FIELD_PREP(PA6_RG_U2_DISCTH, instance->discth));
627
628 if (instance->pre_emphasis)
629 clrsetbits_le32(com + U3P_USBPHYACR6, PA6_RG_U2_PRE_EMP,
630 FIELD_PREP(PA6_RG_U2_PRE_EMP, instance->pre_emphasis));
631}
632
Christian Marangi198a3782024-06-24 23:03:27 +0200633/* type switch for usb3/pcie/sgmii/sata */
634static int phy_type_syscon_get(struct udevice *dev, struct mtk_phy_instance *instance,
635 ofnode dn)
636{
637 struct ofnode_phandle_args args;
638 int err;
639
640 if (!ofnode_read_bool(dn, "mediatek,syscon-type"))
641 return 0;
642
643 err = ofnode_parse_phandle_with_args(dn, "mediatek,syscon-type",
644 NULL, 2, 0, &args);
645 if (err)
646 return err;
647
648 instance->type_sw_reg = args.args[0];
649 instance->type_sw_index = args.args[1] & 0x3; /* <=3 */
650 instance->type_sw = syscon_node_to_regmap(args.node);
651 if (IS_ERR(instance->type_sw))
652 return PTR_ERR(instance->type_sw);
653
654 debug("phy-%s.%d: type_sw - reg %#x, index %d\n",
655 dev->name, instance->index, instance->type_sw_reg,
656 instance->type_sw_index);
657
658 return 0;
659}
660
661static int phy_type_set(struct mtk_phy_instance *instance)
662{
663 int type;
664 u32 offset;
665
666 if (!instance->type_sw)
667 return 0;
668
669 switch (instance->type) {
670 case PHY_TYPE_USB3:
671 type = RG_PHY_SW_USB3;
672 break;
673 case PHY_TYPE_PCIE:
674 type = RG_PHY_SW_PCIE;
675 break;
676 case PHY_TYPE_SGMII:
677 type = RG_PHY_SW_SGMII;
678 break;
679 case PHY_TYPE_SATA:
680 type = RG_PHY_SW_SATA;
681 break;
682 case PHY_TYPE_USB2:
683 default:
684 return 0;
685 }
686
687 offset = instance->type_sw_index * BITS_PER_BYTE;
688 regmap_update_bits(instance->type_sw, instance->type_sw_reg,
689 RG_PHY_SW_TYPE << offset, type << offset);
690
691 return 0;
692}
693
developer7b27b8d2019-08-22 12:26:50 +0200694static int mtk_phy_init(struct phy *phy)
695{
696 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
697 struct mtk_phy_instance *instance = tphy->phys[phy->id];
698 int ret;
699
developer7b27b8d2019-08-22 12:26:50 +0200700 ret = clk_enable(&instance->ref_clk);
developer54acbc32020-05-02 11:35:17 +0200701 if (ret < 0) {
702 dev_err(tphy->dev, "failed to enable ref_clk\n");
developer7b27b8d2019-08-22 12:26:50 +0200703 return ret;
developer54acbc32020-05-02 11:35:17 +0200704 }
705
706 ret = clk_enable(&instance->da_ref_clk);
707 if (ret < 0) {
708 dev_err(tphy->dev, "failed to enable da_ref_clk %d\n", ret);
709 clk_disable(&instance->ref_clk);
710 return ret;
711 }
developer7b27b8d2019-08-22 12:26:50 +0200712
713 switch (instance->type) {
developer8a17d5f2020-05-02 11:35:15 +0200714 case PHY_TYPE_USB2:
715 u2_phy_instance_init(tphy, instance);
developer9a9c3342023-12-13 14:41:34 +0800716 u2_phy_props_set(tphy, instance);
developer8a17d5f2020-05-02 11:35:15 +0200717 break;
718 case PHY_TYPE_USB3:
719 u3_phy_instance_init(tphy, instance);
720 break;
developer7b27b8d2019-08-22 12:26:50 +0200721 case PHY_TYPE_PCIE:
722 pcie_phy_instance_init(tphy, instance);
723 break;
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200724 case PHY_TYPE_SATA:
725 sata_phy_instance_init(tphy, instance);
726 break;
developer7b27b8d2019-08-22 12:26:50 +0200727 default:
developer8a17d5f2020-05-02 11:35:15 +0200728 dev_err(tphy->dev, "incompatible PHY type\n");
developer7b27b8d2019-08-22 12:26:50 +0200729 return -EINVAL;
730 }
731
732 return 0;
733}
734
735static int mtk_phy_power_on(struct phy *phy)
736{
737 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
738 struct mtk_phy_instance *instance = tphy->phys[phy->id];
739
developer8a17d5f2020-05-02 11:35:15 +0200740 if (instance->type == PHY_TYPE_USB2)
741 u2_phy_instance_power_on(tphy, instance);
742 else if (instance->type == PHY_TYPE_PCIE)
743 pcie_phy_instance_power_on(tphy, instance);
developer7b27b8d2019-08-22 12:26:50 +0200744
745 return 0;
746}
747
748static int mtk_phy_power_off(struct phy *phy)
749{
750 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
751 struct mtk_phy_instance *instance = tphy->phys[phy->id];
752
developer8a17d5f2020-05-02 11:35:15 +0200753 if (instance->type == PHY_TYPE_USB2)
754 u2_phy_instance_power_off(tphy, instance);
755 else if (instance->type == PHY_TYPE_PCIE)
756 pcie_phy_instance_power_off(tphy, instance);
developer7b27b8d2019-08-22 12:26:50 +0200757
758 return 0;
759}
760
761static int mtk_phy_exit(struct phy *phy)
762{
763 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
764 struct mtk_phy_instance *instance = tphy->phys[phy->id];
765
developer54acbc32020-05-02 11:35:17 +0200766 clk_disable(&instance->da_ref_clk);
developer7b27b8d2019-08-22 12:26:50 +0200767 clk_disable(&instance->ref_clk);
768
769 return 0;
770}
771
772static int mtk_phy_xlate(struct phy *phy,
773 struct ofnode_phandle_args *args)
774{
775 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
776 struct mtk_phy_instance *instance = NULL;
777 const struct device_node *phy_np = ofnode_to_np(args->node);
778 u32 index;
779
780 if (!phy_np) {
781 dev_err(phy->dev, "null pointer phy node\n");
782 return -EINVAL;
783 }
784
785 if (args->args_count < 1) {
786 dev_err(phy->dev, "invalid number of cells in 'phy' property\n");
787 return -EINVAL;
788 }
789
790 for (index = 0; index < tphy->nphys; index++)
791 if (phy_np == tphy->phys[index]->np) {
792 instance = tphy->phys[index];
793 break;
794 }
795
796 if (!instance) {
797 dev_err(phy->dev, "failed to find appropriate phy\n");
798 return -EINVAL;
799 }
800
801 phy->id = index;
802 instance->type = args->args[1];
803 if (!(instance->type == PHY_TYPE_USB2 ||
804 instance->type == PHY_TYPE_USB3 ||
Frank Wunderliche84a29f2020-08-13 10:20:45 +0200805 instance->type == PHY_TYPE_SATA ||
developer8a17d5f2020-05-02 11:35:15 +0200806 instance->type == PHY_TYPE_PCIE)) {
developer7b27b8d2019-08-22 12:26:50 +0200807 dev_err(phy->dev, "unsupported device type\n");
808 return -EINVAL;
809 }
810
developer53cecc02023-02-17 17:04:09 +0800811 switch (tphy->pdata->version) {
812 case MTK_TPHY_V1:
developer8b302602020-05-02 11:35:16 +0200813 phy_v1_banks_init(tphy, instance);
developer53cecc02023-02-17 17:04:09 +0800814 break;
815 case MTK_TPHY_V2:
developer8b302602020-05-02 11:35:16 +0200816 phy_v2_banks_init(tphy, instance);
developer53cecc02023-02-17 17:04:09 +0800817 break;
818 default:
developer8b302602020-05-02 11:35:16 +0200819 dev_err(phy->dev, "phy version is not supported\n");
820 return -EINVAL;
821 }
developer7b27b8d2019-08-22 12:26:50 +0200822
developer9a9c3342023-12-13 14:41:34 +0800823 phy_parse_property(tphy, instance);
Christian Marangi198a3782024-06-24 23:03:27 +0200824 phy_type_set(instance);
developer9a9c3342023-12-13 14:41:34 +0800825
developer7b27b8d2019-08-22 12:26:50 +0200826 return 0;
827}
828
829static const struct phy_ops mtk_tphy_ops = {
830 .init = mtk_phy_init,
831 .exit = mtk_phy_exit,
832 .power_on = mtk_phy_power_on,
833 .power_off = mtk_phy_power_off,
834 .of_xlate = mtk_phy_xlate,
835};
836
837static int mtk_tphy_probe(struct udevice *dev)
838{
839 struct mtk_tphy *tphy = dev_get_priv(dev);
840 ofnode subnode;
841 int index = 0;
842
developer8a17d5f2020-05-02 11:35:15 +0200843 tphy->nphys = dev_get_child_count(dev);
developer7b27b8d2019-08-22 12:26:50 +0200844
845 tphy->phys = devm_kcalloc(dev, tphy->nphys, sizeof(*tphy->phys),
846 GFP_KERNEL);
847 if (!tphy->phys)
848 return -ENOMEM;
849
developer8a17d5f2020-05-02 11:35:15 +0200850 tphy->dev = dev;
developer53cecc02023-02-17 17:04:09 +0800851 tphy->pdata = (void *)dev_get_driver_data(dev);
developer8b302602020-05-02 11:35:16 +0200852
Frank Wunderlich6acdc952020-08-20 16:37:52 +0200853 /* v1 has shared banks for usb/pcie mode, */
854 /* but not for sata mode */
developer53cecc02023-02-17 17:04:09 +0800855 if (tphy->pdata->version == MTK_TPHY_V1)
developer8b302602020-05-02 11:35:16 +0200856 tphy->sif_base = dev_read_addr_ptr(dev);
developer7b27b8d2019-08-22 12:26:50 +0200857
858 dev_for_each_subnode(subnode, dev) {
859 struct mtk_phy_instance *instance;
860 fdt_addr_t addr;
861 int err;
862
863 instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
864 if (!instance)
865 return -ENOMEM;
866
867 addr = ofnode_get_addr(subnode);
868 if (addr == FDT_ADDR_T_NONE)
869 return -ENOMEM;
870
871 instance->port_base = map_sysmem(addr, 0);
872 instance->index = index;
873 instance->np = ofnode_to_np(subnode);
874 tphy->phys[index] = instance;
875 index++;
876
Sean Andersond7e85d52021-12-22 12:11:10 -0500877 err = clk_get_by_name_nodev_optional(subnode, "ref",
878 &instance->ref_clk);
developer7b27b8d2019-08-22 12:26:50 +0200879 if (err)
880 return err;
developer54acbc32020-05-02 11:35:17 +0200881
Sean Andersond7e85d52021-12-22 12:11:10 -0500882 err = clk_get_by_name_nodev_optional(subnode, "da_ref",
883 &instance->da_ref_clk);
developer54acbc32020-05-02 11:35:17 +0200884 if (err)
885 return err;
Christian Marangi198a3782024-06-24 23:03:27 +0200886
887 err = phy_type_syscon_get(dev, instance, subnode);
888 if (err)
889 return err;
developer7b27b8d2019-08-22 12:26:50 +0200890 }
891
892 return 0;
893}
894
developer53cecc02023-02-17 17:04:09 +0800895static struct tphy_pdata tphy_v1_pdata = {
896 .version = MTK_TPHY_V1,
897};
898
899static struct tphy_pdata tphy_v2_pdata = {
900 .version = MTK_TPHY_V2,
901};
902
903static struct tphy_pdata mt8195_pdata = {
904 .version = MTK_TPHY_V2,
905 .sw_pll_48m_to_26m = true,
906};
907
developer7b27b8d2019-08-22 12:26:50 +0200908static const struct udevice_id mtk_tphy_id_table[] = {
developer53cecc02023-02-17 17:04:09 +0800909 {
910 .compatible = "mediatek,generic-tphy-v1",
911 .data = (ulong)&tphy_v1_pdata,
912 },
913 {
914 .compatible = "mediatek,generic-tphy-v2",
915 .data = (ulong)&tphy_v2_pdata,
916 },
917 {
918 .compatible = "mediatek,mt8195-tphy",
919 .data = (ulong)&mt8195_pdata,
920 },
developer7b27b8d2019-08-22 12:26:50 +0200921 { }
922};
923
924U_BOOT_DRIVER(mtk_tphy) = {
925 .name = "mtk-tphy",
926 .id = UCLASS_PHY,
927 .of_match = mtk_tphy_id_table,
928 .ops = &mtk_tphy_ops,
929 .probe = mtk_tphy_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700930 .priv_auto = sizeof(struct mtk_tphy),
developer7b27b8d2019-08-22 12:26:50 +0200931};