blob: 1e65c24356e35bc8cad600b8b20cb5589300bbd0 [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>
Simon Glasscd93d622020-05-10 11:40:13 -060017#include <linux/bitops.h>
Simon Glassc05ed002020-05-10 11:40:11 -060018#include <linux/delay.h>
Ryder Lee235bad02019-08-22 12:26:50 +020019
20#include <dt-bindings/phy/phy.h>
21
22/* version V1 sub-banks offset base address */
23/* banks shared by multiple phys */
24#define SSUSB_SIFSLV_V1_SPLLC 0x000 /* shared by u3 phys */
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020025#define SSUSB_SIFSLV_V1_U2FREQ 0x100 /* shared by u2 phys */
Ryder Lee235bad02019-08-22 12:26:50 +020026#define SSUSB_SIFSLV_V1_CHIP 0x300 /* shared by u3 phys */
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020027/* u2 phy bank */
28#define SSUSB_SIFSLV_V1_U2PHY_COM 0x000
Ryder Lee235bad02019-08-22 12:26:50 +020029/* u3/pcie/sata phy banks */
30#define SSUSB_SIFSLV_V1_U3PHYD 0x000
31#define SSUSB_SIFSLV_V1_U3PHYA 0x200
32
Chunfeng Yund1ae8442020-05-02 11:35:16 +020033/* version V2 sub-banks offset base address */
34/* u2 phy banks */
35#define SSUSB_SIFSLV_V2_MISC 0x000
36#define SSUSB_SIFSLV_V2_U2FREQ 0x100
37#define SSUSB_SIFSLV_V2_U2PHY_COM 0x300
38/* u3/pcie/sata phy banks */
39#define SSUSB_SIFSLV_V2_SPLLC 0x000
40#define SSUSB_SIFSLV_V2_CHIP 0x100
41#define SSUSB_SIFSLV_V2_U3PHYD 0x200
42#define SSUSB_SIFSLV_V2_U3PHYA 0x400
43
Chunfeng Yunee6eabb2020-05-02 11:35:15 +020044#define U3P_USBPHYACR0 0x000
45#define PA0_RG_U2PLL_FORCE_ON BIT(15)
46#define PA0_RG_USB20_INTR_EN BIT(5)
47
48#define U3P_USBPHYACR5 0x014
49#define PA5_RG_U2_HSTX_SRCAL_EN BIT(15)
50#define PA5_RG_U2_HSTX_SRCTRL GENMASK(14, 12)
51#define PA5_RG_U2_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12)
52#define PA5_RG_U2_HS_100U_U3_EN BIT(11)
53
54#define U3P_USBPHYACR6 0x018
55#define PA6_RG_U2_BC11_SW_EN BIT(23)
56#define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20)
57#define PA6_RG_U2_SQTH GENMASK(3, 0)
58#define PA6_RG_U2_SQTH_VAL(x) (0xf & (x))
59
60#define U3P_U2PHYACR4 0x020
61#define P2C_RG_USB20_GPIO_CTL BIT(9)
62#define P2C_USB20_GPIO_MODE BIT(8)
63#define P2C_U2_GPIO_CTR_MSK \
64 (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
65
66#define U3P_U2PHYDTM0 0x068
67#define P2C_FORCE_UART_EN BIT(26)
68#define P2C_FORCE_DATAIN BIT(23)
69#define P2C_FORCE_DM_PULLDOWN BIT(21)
70#define P2C_FORCE_DP_PULLDOWN BIT(20)
71#define P2C_FORCE_XCVRSEL BIT(19)
72#define P2C_FORCE_SUSPENDM BIT(18)
73#define P2C_FORCE_TERMSEL BIT(17)
74#define P2C_RG_DATAIN GENMASK(13, 10)
75#define P2C_RG_DATAIN_VAL(x) ((0xf & (x)) << 10)
76#define P2C_RG_DMPULLDOWN BIT(7)
77#define P2C_RG_DPPULLDOWN BIT(6)
78#define P2C_RG_XCVRSEL GENMASK(5, 4)
79#define P2C_RG_XCVRSEL_VAL(x) ((0x3 & (x)) << 4)
80#define P2C_RG_SUSPENDM BIT(3)
81#define P2C_RG_TERMSEL BIT(2)
82#define P2C_DTM0_PART_MASK \
83 (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
84 P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
85 P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
86 P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
87
88#define U3P_U2PHYDTM1 0x06C
89#define P2C_RG_UART_EN BIT(16)
90#define P2C_FORCE_IDDIG BIT(9)
91#define P2C_RG_VBUSVALID BIT(5)
92#define P2C_RG_SESSEND BIT(4)
93#define P2C_RG_AVALID BIT(2)
94#define P2C_RG_IDDIG BIT(1)
95
Ryder Lee235bad02019-08-22 12:26:50 +020096#define U3P_U3_CHIP_GPIO_CTLD 0x0c
97#define P3C_REG_IP_SW_RST BIT(31)
98#define P3C_MCU_BUS_CK_GATE_EN BIT(30)
99#define P3C_FORCE_IP_SW_RST BIT(29)
100
101#define U3P_U3_CHIP_GPIO_CTLE 0x10
102#define P3C_RG_SWRST_U3_PHYD BIT(25)
103#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
104
105#define U3P_U3_PHYA_REG0 0x000
106#define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
107#define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
108
109#define U3P_U3_PHYA_REG1 0x004
110#define P3A_RG_CLKDRV_AMP GENMASK(31, 29)
111#define P3A_RG_CLKDRV_AMP_VAL(x) ((0x7 & (x)) << 29)
112
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200113#define U3P_U3_PHYA_REG6 0x018
114#define P3A_RG_TX_EIDLE_CM GENMASK(31, 28)
115#define P3A_RG_TX_EIDLE_CM_VAL(x) ((0xf & (x)) << 28)
116
117#define U3P_U3_PHYA_REG9 0x024
118#define P3A_RG_RX_DAC_MUX GENMASK(5, 1)
119#define P3A_RG_RX_DAC_MUX_VAL(x) ((0x1f & (x)) << 1)
120
Ryder Lee235bad02019-08-22 12:26:50 +0200121#define U3P_U3_PHYA_DA_REG0 0x100
122#define P3A_RG_XTAL_EXT_PE2H GENMASK(17, 16)
123#define P3A_RG_XTAL_EXT_PE2H_VAL(x) ((0x3 & (x)) << 16)
124#define P3A_RG_XTAL_EXT_PE1H GENMASK(13, 12)
125#define P3A_RG_XTAL_EXT_PE1H_VAL(x) ((0x3 & (x)) << 12)
126#define P3A_RG_XTAL_EXT_EN_U3 GENMASK(11, 10)
127#define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10)
128
129#define U3P_U3_PHYA_DA_REG4 0x108
130#define P3A_RG_PLL_DIVEN_PE2H GENMASK(21, 19)
131#define P3A_RG_PLL_BC_PE2H GENMASK(7, 6)
132#define P3A_RG_PLL_BC_PE2H_VAL(x) ((0x3 & (x)) << 6)
133
134#define U3P_U3_PHYA_DA_REG5 0x10c
135#define P3A_RG_PLL_BR_PE2H GENMASK(29, 28)
136#define P3A_RG_PLL_BR_PE2H_VAL(x) ((0x3 & (x)) << 28)
137#define P3A_RG_PLL_IC_PE2H GENMASK(15, 12)
138#define P3A_RG_PLL_IC_PE2H_VAL(x) ((0xf & (x)) << 12)
139
140#define U3P_U3_PHYA_DA_REG6 0x110
141#define P3A_RG_PLL_IR_PE2H GENMASK(19, 16)
142#define P3A_RG_PLL_IR_PE2H_VAL(x) ((0xf & (x)) << 16)
143
144#define U3P_U3_PHYA_DA_REG7 0x114
145#define P3A_RG_PLL_BP_PE2H GENMASK(19, 16)
146#define P3A_RG_PLL_BP_PE2H_VAL(x) ((0xf & (x)) << 16)
147
148#define U3P_U3_PHYA_DA_REG20 0x13c
149#define P3A_RG_PLL_DELTA1_PE2H GENMASK(31, 16)
150#define P3A_RG_PLL_DELTA1_PE2H_VAL(x) ((0xffff & (x)) << 16)
151
152#define U3P_U3_PHYA_DA_REG25 0x148
153#define P3A_RG_PLL_DELTA_PE2H GENMASK(15, 0)
154#define P3A_RG_PLL_DELTA_PE2H_VAL(x) (0xffff & (x))
155
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200156#define U3P_U3_PHYD_LFPS1 0x00c
157#define P3D_RG_FWAKE_TH GENMASK(21, 16)
158#define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
159
160#define U3P_U3_PHYD_CDR1 0x05c
161#define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
162#define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
163#define P3D_RG_CDR_BIR_LTD0 GENMASK(12, 8)
164#define P3D_RG_CDR_BIR_LTD0_VAL(x) ((0x1f & (x)) << 8)
165
Ryder Lee235bad02019-08-22 12:26:50 +0200166#define U3P_U3_PHYD_RXDET1 0x128
167#define P3D_RG_RXDET_STB2_SET GENMASK(17, 9)
168#define P3D_RG_RXDET_STB2_SET_VAL(x) ((0x1ff & (x)) << 9)
169
170#define U3P_U3_PHYD_RXDET2 0x12c
171#define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0)
172#define P3D_RG_RXDET_STB2_SET_P3_VAL(x) (0x1ff & (x))
173
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200174#define U3P_SPLLC_XTALCTL3 0x018
175#define XC3_RG_U3_XTAL_RX_PWD BIT(9)
176#define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8)
177
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200178enum mtk_phy_version {
179 MTK_TPHY_V1 = 1,
180 MTK_TPHY_V2,
181};
182
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200183struct u2phy_banks {
184 void __iomem *misc;
185 void __iomem *fmreg;
186 void __iomem *com;
187};
188
Ryder Lee235bad02019-08-22 12:26:50 +0200189struct u3phy_banks {
190 void __iomem *spllc;
191 void __iomem *chip;
192 void __iomem *phyd; /* include u3phyd_bank2 */
193 void __iomem *phya; /* include u3phya_da */
194};
195
196struct mtk_phy_instance {
197 void __iomem *port_base;
198 const struct device_node *np;
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200199 union {
200 struct u2phy_banks u2_banks;
201 struct u3phy_banks u3_banks;
202 };
Ryder Lee235bad02019-08-22 12:26:50 +0200203
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200204 struct clk ref_clk; /* reference clock of (digital) phy */
205 struct clk da_ref_clk; /* reference clock of analog phy */
Ryder Lee235bad02019-08-22 12:26:50 +0200206 u32 index;
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200207 u32 type;
Ryder Lee235bad02019-08-22 12:26:50 +0200208};
209
210struct mtk_tphy {
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200211 struct udevice *dev;
Ryder Lee235bad02019-08-22 12:26:50 +0200212 void __iomem *sif_base;
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200213 enum mtk_phy_version version;
Ryder Lee235bad02019-08-22 12:26:50 +0200214 struct mtk_phy_instance **phys;
215 int nphys;
216};
217
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200218static void u2_phy_instance_init(struct mtk_tphy *tphy,
219 struct mtk_phy_instance *instance)
220{
221 struct u2phy_banks *u2_banks = &instance->u2_banks;
222
223 /* switch to USB function, and enable usb pll */
224 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM0,
225 P2C_FORCE_UART_EN | P2C_FORCE_SUSPENDM,
226 P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0));
227
228 clrbits_le32(u2_banks->com + U3P_U2PHYDTM1, P2C_RG_UART_EN);
229 setbits_le32(u2_banks->com + U3P_USBPHYACR0, PA0_RG_USB20_INTR_EN);
230
231 /* disable switch 100uA current to SSUSB */
232 clrbits_le32(u2_banks->com + U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN);
233
234 clrbits_le32(u2_banks->com + U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK);
235
236 /* DP/DM BC1.1 path Disable */
237 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR6,
238 PA6_RG_U2_BC11_SW_EN | PA6_RG_U2_SQTH,
239 PA6_RG_U2_SQTH_VAL(2));
240
241 /* set HS slew rate */
242 clrsetbits_le32(u2_banks->com + U3P_USBPHYACR5,
243 PA5_RG_U2_HSTX_SRCTRL, PA5_RG_U2_HSTX_SRCTRL_VAL(4));
244
245 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
246}
247
248static void u2_phy_instance_power_on(struct mtk_tphy *tphy,
249 struct mtk_phy_instance *instance)
250{
251 struct u2phy_banks *u2_banks = &instance->u2_banks;
252
253 clrbits_le32(u2_banks->com + U3P_U2PHYDTM0,
254 P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
255
256 /* OTG Enable */
257 setbits_le32(u2_banks->com + U3P_USBPHYACR6,
258 PA6_RG_U2_OTG_VBUSCMP_EN);
259
260 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM1,
261 P2C_RG_SESSEND, P2C_RG_VBUSVALID | P2C_RG_AVALID);
262
263 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
264}
265
266static void u2_phy_instance_power_off(struct mtk_tphy *tphy,
267 struct mtk_phy_instance *instance)
268{
269 struct u2phy_banks *u2_banks = &instance->u2_banks;
270
271 clrbits_le32(u2_banks->com + U3P_U2PHYDTM0,
272 P2C_RG_XCVRSEL | P2C_RG_DATAIN);
273
274 /* OTG Disable */
275 clrbits_le32(u2_banks->com + U3P_USBPHYACR6,
276 PA6_RG_U2_OTG_VBUSCMP_EN);
277
278 clrsetbits_le32(u2_banks->com + U3P_U2PHYDTM1,
279 P2C_RG_VBUSVALID | P2C_RG_AVALID, P2C_RG_SESSEND);
280
281 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
282}
283
284static void u3_phy_instance_init(struct mtk_tphy *tphy,
285 struct mtk_phy_instance *instance)
286{
287 struct u3phy_banks *u3_banks = &instance->u3_banks;
288
289 /* gating PCIe Analog XTAL clock */
290 setbits_le32(u3_banks->spllc + U3P_SPLLC_XTALCTL3,
291 XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD);
292
293 /* gating XSQ */
294 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
295 P3A_RG_XTAL_EXT_EN_U3, P3A_RG_XTAL_EXT_EN_U3_VAL(2));
296
297 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG9,
298 P3A_RG_RX_DAC_MUX, P3A_RG_RX_DAC_MUX_VAL(4));
299
300 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG6,
301 P3A_RG_TX_EIDLE_CM, P3A_RG_TX_EIDLE_CM_VAL(0xe));
302
303 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_CDR1,
304 P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1,
305 P3D_RG_CDR_BIR_LTD0_VAL(0xc) |
306 P3D_RG_CDR_BIR_LTD1_VAL(0x3));
307
308 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_LFPS1,
309 P3D_RG_FWAKE_TH, P3D_RG_FWAKE_TH_VAL(0x34));
310
311 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET1,
312 P3D_RG_RXDET_STB2_SET, P3D_RG_RXDET_STB2_SET_VAL(0x10));
313
314 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET2,
315 P3D_RG_RXDET_STB2_SET_P3,
316 P3D_RG_RXDET_STB2_SET_P3_VAL(0x10));
317
318 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
319}
320
Ryder Lee235bad02019-08-22 12:26:50 +0200321static void pcie_phy_instance_init(struct mtk_tphy *tphy,
322 struct mtk_phy_instance *instance)
323{
324 struct u3phy_banks *u3_banks = &instance->u3_banks;
325
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200326 if (tphy->version != MTK_TPHY_V1)
327 return;
328
Ryder Lee235bad02019-08-22 12:26:50 +0200329 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG0,
330 P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H,
331 P3A_RG_XTAL_EXT_PE1H_VAL(0x2) |
332 P3A_RG_XTAL_EXT_PE2H_VAL(0x2));
333
334 /* ref clk drive */
335 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG1, P3A_RG_CLKDRV_AMP,
336 P3A_RG_CLKDRV_AMP_VAL(0x4));
337 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_REG0, P3A_RG_CLKDRV_OFF,
338 P3A_RG_CLKDRV_OFF_VAL(0x1));
339
340 /* SSC delta -5000ppm */
341 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG20,
342 P3A_RG_PLL_DELTA1_PE2H,
343 P3A_RG_PLL_DELTA1_PE2H_VAL(0x3c));
344
345 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG25,
346 P3A_RG_PLL_DELTA_PE2H,
347 P3A_RG_PLL_DELTA_PE2H_VAL(0x36));
348
349 /* change pll BW 0.6M */
350 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG5,
351 P3A_RG_PLL_BR_PE2H | P3A_RG_PLL_IC_PE2H,
352 P3A_RG_PLL_BR_PE2H_VAL(0x1) |
353 P3A_RG_PLL_IC_PE2H_VAL(0x1));
354 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG4,
355 P3A_RG_PLL_DIVEN_PE2H | P3A_RG_PLL_BC_PE2H,
356 P3A_RG_PLL_BC_PE2H_VAL(0x3));
357
358 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG6,
359 P3A_RG_PLL_IR_PE2H, P3A_RG_PLL_IR_PE2H_VAL(0x2));
360 clrsetbits_le32(u3_banks->phya + U3P_U3_PHYA_DA_REG7,
361 P3A_RG_PLL_BP_PE2H, P3A_RG_PLL_BP_PE2H_VAL(0xa));
362
363 /* Tx Detect Rx Timing: 10us -> 5us */
364 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET1,
365 P3D_RG_RXDET_STB2_SET,
366 P3D_RG_RXDET_STB2_SET_VAL(0x10));
367 clrsetbits_le32(u3_banks->phyd + U3P_U3_PHYD_RXDET2,
368 P3D_RG_RXDET_STB2_SET_P3,
369 P3D_RG_RXDET_STB2_SET_P3_VAL(0x10));
370
371 /* wait for PCIe subsys register to active */
372 udelay(3000);
373}
374
375static void pcie_phy_instance_power_on(struct mtk_tphy *tphy,
376 struct mtk_phy_instance *instance)
377{
378 struct u3phy_banks *bank = &instance->u3_banks;
379
380 clrbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLD,
381 P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
382 clrbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLE,
383 P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
384}
385
386static void pcie_phy_instance_power_off(struct mtk_tphy *tphy,
387 struct mtk_phy_instance *instance)
388
389{
390 struct u3phy_banks *bank = &instance->u3_banks;
391
392 setbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLD,
393 P3C_FORCE_IP_SW_RST | P3C_REG_IP_SW_RST);
394 setbits_le32(bank->chip + U3P_U3_CHIP_GPIO_CTLE,
395 P3C_RG_SWRST_U3_PHYD_FORCE_EN | P3C_RG_SWRST_U3_PHYD);
396}
397
398static void phy_v1_banks_init(struct mtk_tphy *tphy,
399 struct mtk_phy_instance *instance)
400{
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200401 struct u2phy_banks *u2_banks = &instance->u2_banks;
Ryder Lee235bad02019-08-22 12:26:50 +0200402 struct u3phy_banks *u3_banks = &instance->u3_banks;
403
404 switch (instance->type) {
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200405 case PHY_TYPE_USB2:
406 u2_banks->misc = NULL;
407 u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
408 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
409 break;
410 case PHY_TYPE_USB3:
Ryder Lee235bad02019-08-22 12:26:50 +0200411 case PHY_TYPE_PCIE:
412 u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
413 u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
414 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
415 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
416 break;
417 default:
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200418 dev_err(tphy->dev, "incompatible PHY type\n");
Ryder Lee235bad02019-08-22 12:26:50 +0200419 return;
420 }
421}
422
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200423static void phy_v2_banks_init(struct mtk_tphy *tphy,
424 struct mtk_phy_instance *instance)
425{
426 struct u2phy_banks *u2_banks = &instance->u2_banks;
427 struct u3phy_banks *u3_banks = &instance->u3_banks;
428
429 switch (instance->type) {
430 case PHY_TYPE_USB2:
431 u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
432 u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
433 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
434 break;
435 case PHY_TYPE_USB3:
436 case PHY_TYPE_PCIE:
437 u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
438 u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
439 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
440 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
441 break;
442 default:
443 dev_err(tphy->dev, "incompatible PHY type\n");
444 return;
445 }
446}
447
Ryder Lee235bad02019-08-22 12:26:50 +0200448static int mtk_phy_init(struct phy *phy)
449{
450 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
451 struct mtk_phy_instance *instance = tphy->phys[phy->id];
452 int ret;
453
Ryder Lee235bad02019-08-22 12:26:50 +0200454 ret = clk_enable(&instance->ref_clk);
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200455 if (ret < 0) {
456 dev_err(tphy->dev, "failed to enable ref_clk\n");
Ryder Lee235bad02019-08-22 12:26:50 +0200457 return ret;
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200458 }
459
460 ret = clk_enable(&instance->da_ref_clk);
461 if (ret < 0) {
462 dev_err(tphy->dev, "failed to enable da_ref_clk %d\n", ret);
463 clk_disable(&instance->ref_clk);
464 return ret;
465 }
Ryder Lee235bad02019-08-22 12:26:50 +0200466
467 switch (instance->type) {
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200468 case PHY_TYPE_USB2:
469 u2_phy_instance_init(tphy, instance);
470 break;
471 case PHY_TYPE_USB3:
472 u3_phy_instance_init(tphy, instance);
473 break;
Ryder Lee235bad02019-08-22 12:26:50 +0200474 case PHY_TYPE_PCIE:
475 pcie_phy_instance_init(tphy, instance);
476 break;
477 default:
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200478 dev_err(tphy->dev, "incompatible PHY type\n");
Ryder Lee235bad02019-08-22 12:26:50 +0200479 return -EINVAL;
480 }
481
482 return 0;
483}
484
485static int mtk_phy_power_on(struct phy *phy)
486{
487 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
488 struct mtk_phy_instance *instance = tphy->phys[phy->id];
489
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200490 if (instance->type == PHY_TYPE_USB2)
491 u2_phy_instance_power_on(tphy, instance);
492 else if (instance->type == PHY_TYPE_PCIE)
493 pcie_phy_instance_power_on(tphy, instance);
Ryder Lee235bad02019-08-22 12:26:50 +0200494
495 return 0;
496}
497
498static int mtk_phy_power_off(struct phy *phy)
499{
500 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
501 struct mtk_phy_instance *instance = tphy->phys[phy->id];
502
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200503 if (instance->type == PHY_TYPE_USB2)
504 u2_phy_instance_power_off(tphy, instance);
505 else if (instance->type == PHY_TYPE_PCIE)
506 pcie_phy_instance_power_off(tphy, instance);
Ryder Lee235bad02019-08-22 12:26:50 +0200507
508 return 0;
509}
510
511static int mtk_phy_exit(struct phy *phy)
512{
513 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
514 struct mtk_phy_instance *instance = tphy->phys[phy->id];
515
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200516 clk_disable(&instance->da_ref_clk);
Ryder Lee235bad02019-08-22 12:26:50 +0200517 clk_disable(&instance->ref_clk);
518
519 return 0;
520}
521
522static int mtk_phy_xlate(struct phy *phy,
523 struct ofnode_phandle_args *args)
524{
525 struct mtk_tphy *tphy = dev_get_priv(phy->dev);
526 struct mtk_phy_instance *instance = NULL;
527 const struct device_node *phy_np = ofnode_to_np(args->node);
528 u32 index;
529
530 if (!phy_np) {
531 dev_err(phy->dev, "null pointer phy node\n");
532 return -EINVAL;
533 }
534
535 if (args->args_count < 1) {
536 dev_err(phy->dev, "invalid number of cells in 'phy' property\n");
537 return -EINVAL;
538 }
539
540 for (index = 0; index < tphy->nphys; index++)
541 if (phy_np == tphy->phys[index]->np) {
542 instance = tphy->phys[index];
543 break;
544 }
545
546 if (!instance) {
547 dev_err(phy->dev, "failed to find appropriate phy\n");
548 return -EINVAL;
549 }
550
551 phy->id = index;
552 instance->type = args->args[1];
553 if (!(instance->type == PHY_TYPE_USB2 ||
554 instance->type == PHY_TYPE_USB3 ||
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200555 instance->type == PHY_TYPE_PCIE)) {
Ryder Lee235bad02019-08-22 12:26:50 +0200556 dev_err(phy->dev, "unsupported device type\n");
557 return -EINVAL;
558 }
559
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200560 if (tphy->version == MTK_TPHY_V1) {
561 phy_v1_banks_init(tphy, instance);
562 } else if (tphy->version == MTK_TPHY_V2) {
563 phy_v2_banks_init(tphy, instance);
564 } else {
565 dev_err(phy->dev, "phy version is not supported\n");
566 return -EINVAL;
567 }
Ryder Lee235bad02019-08-22 12:26:50 +0200568
569 return 0;
570}
571
572static const struct phy_ops mtk_tphy_ops = {
573 .init = mtk_phy_init,
574 .exit = mtk_phy_exit,
575 .power_on = mtk_phy_power_on,
576 .power_off = mtk_phy_power_off,
577 .of_xlate = mtk_phy_xlate,
578};
579
580static int mtk_tphy_probe(struct udevice *dev)
581{
582 struct mtk_tphy *tphy = dev_get_priv(dev);
583 ofnode subnode;
584 int index = 0;
585
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200586 tphy->nphys = dev_get_child_count(dev);
Ryder Lee235bad02019-08-22 12:26:50 +0200587
588 tphy->phys = devm_kcalloc(dev, tphy->nphys, sizeof(*tphy->phys),
589 GFP_KERNEL);
590 if (!tphy->phys)
591 return -ENOMEM;
592
Chunfeng Yunee6eabb2020-05-02 11:35:15 +0200593 tphy->dev = dev;
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200594 tphy->version = dev_get_driver_data(dev);
595
596 /* v1 has shared banks */
597 if (tphy->version == MTK_TPHY_V1) {
598 tphy->sif_base = dev_read_addr_ptr(dev);
599 if (!tphy->sif_base)
600 return -ENOENT;
601 }
Ryder Lee235bad02019-08-22 12:26:50 +0200602
603 dev_for_each_subnode(subnode, dev) {
604 struct mtk_phy_instance *instance;
605 fdt_addr_t addr;
606 int err;
607
608 instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
609 if (!instance)
610 return -ENOMEM;
611
612 addr = ofnode_get_addr(subnode);
613 if (addr == FDT_ADDR_T_NONE)
614 return -ENOMEM;
615
616 instance->port_base = map_sysmem(addr, 0);
617 instance->index = index;
618 instance->np = ofnode_to_np(subnode);
619 tphy->phys[index] = instance;
620 index++;
621
Chunfeng Yunce0069e2020-01-09 11:35:10 +0800622 err = clk_get_optional_nodev(subnode, "ref",
623 &instance->ref_clk);
Ryder Lee235bad02019-08-22 12:26:50 +0200624 if (err)
625 return err;
Chunfeng Yun4d4abbd2020-05-02 11:35:17 +0200626
627 err = clk_get_optional_nodev(subnode, "da_ref",
628 &instance->da_ref_clk);
629 if (err)
630 return err;
Ryder Lee235bad02019-08-22 12:26:50 +0200631 }
632
633 return 0;
634}
635
636static const struct udevice_id mtk_tphy_id_table[] = {
Chunfeng Yund1ae8442020-05-02 11:35:16 +0200637 { .compatible = "mediatek,generic-tphy-v1", .data = MTK_TPHY_V1, },
638 { .compatible = "mediatek,generic-tphy-v2", .data = MTK_TPHY_V2, },
Ryder Lee235bad02019-08-22 12:26:50 +0200639 { }
640};
641
642U_BOOT_DRIVER(mtk_tphy) = {
643 .name = "mtk-tphy",
644 .id = UCLASS_PHY,
645 .of_match = mtk_tphy_id_table,
646 .ops = &mtk_tphy_ops,
647 .probe = mtk_tphy_probe,
648 .priv_auto_alloc_size = sizeof(struct mtk_tphy),
649};