1 // SPDX-License-Identifier: GPL-2.0-only
3 * Samsung Exynos5 SoC series USB DRD PHY driver
5 * Phy provider for USB 3.0 DRD controller on Exynos5 SoC series
7 * Copyright (C) 2014 Samsung Electronics Co., Ltd.
8 * Author: Vivek Gautam <gautam.vivek@samsung.com>
11 #include <linux/bitfield.h>
12 #include <linux/clk.h>
13 #include <linux/delay.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
18 #include <linux/iopoll.h>
19 #include <linux/phy/phy.h>
20 #include <linux/platform_device.h>
21 #include <linux/mutex.h>
22 #include <linux/mfd/syscon.h>
23 #include <linux/regmap.h>
24 #include <linux/regulator/consumer.h>
25 #include <linux/soc/samsung/exynos-regs-pmu.h>
27 /* Exynos USB PHY registers */
28 #define EXYNOS5_FSEL_9MHZ6 0x0
29 #define EXYNOS5_FSEL_10MHZ 0x1
30 #define EXYNOS5_FSEL_12MHZ 0x2
31 #define EXYNOS5_FSEL_19MHZ2 0x3
32 #define EXYNOS5_FSEL_20MHZ 0x4
33 #define EXYNOS5_FSEL_24MHZ 0x5
34 #define EXYNOS5_FSEL_26MHZ 0x6
35 #define EXYNOS5_FSEL_50MHZ 0x7
37 /* Exynos5: USB 3.0 DRD PHY registers */
38 #define EXYNOS5_DRD_LINKSYSTEM 0x04
39 #define LINKSYSTEM_XHCI_VERSION_CONTROL BIT(27)
40 #define LINKSYSTEM_FLADJ_MASK (0x3f << 1)
41 #define LINKSYSTEM_FLADJ(_x) ((_x) << 1)
43 #define EXYNOS5_DRD_PHYUTMI 0x08
44 #define PHYUTMI_OTGDISABLE BIT(6)
45 #define PHYUTMI_FORCESUSPEND BIT(1)
46 #define PHYUTMI_FORCESLEEP BIT(0)
48 #define EXYNOS5_DRD_PHYPIPE 0x0c
50 #define EXYNOS5_DRD_PHYCLKRST 0x10
51 #define PHYCLKRST_EN_UTMISUSPEND BIT(31)
52 #define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23)
53 #define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23)
54 #define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21)
55 #define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21)
56 #define PHYCLKRST_SSC_EN BIT(20)
57 #define PHYCLKRST_REF_SSP_EN BIT(19)
58 #define PHYCLKRST_REF_CLKDIV2 BIT(18)
59 #define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11)
60 #define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11)
61 #define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x32 << 11)
62 #define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11)
63 #define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11)
64 #define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11)
65 #define PHYCLKRST_FSEL_PIPE_MASK (0x7 << 8)
66 #define PHYCLKRST_FSEL_UTMI_MASK (0x7 << 5)
67 #define PHYCLKRST_FSEL(_x) ((_x) << 5)
68 #define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5)
69 #define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5)
70 #define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5)
71 #define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5)
72 #define PHYCLKRST_RETENABLEN BIT(4)
73 #define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2)
74 #define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2)
75 #define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2)
76 #define PHYCLKRST_PORTRESET BIT(1)
77 #define PHYCLKRST_COMMONONN BIT(0)
79 #define EXYNOS5_DRD_PHYREG0 0x14
80 #define PHYREG0_SSC_REF_CLK_SEL BIT(21)
81 #define PHYREG0_SSC_RANGE BIT(20)
82 #define PHYREG0_CR_WRITE BIT(19)
83 #define PHYREG0_CR_READ BIT(18)
84 #define PHYREG0_CR_DATA_IN(_x) ((_x) << 2)
85 #define PHYREG0_CR_CAP_DATA BIT(1)
86 #define PHYREG0_CR_CAP_ADDR BIT(0)
88 #define EXYNOS5_DRD_PHYREG1 0x18
89 #define PHYREG1_CR_DATA_OUT(_x) ((_x) << 1)
90 #define PHYREG1_CR_ACK BIT(0)
92 #define EXYNOS5_DRD_PHYPARAM0 0x1c
93 #define PHYPARAM0_REF_USE_PAD BIT(31)
94 #define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26)
95 #define PHYPARAM0_REF_LOSLEVEL (0x9 << 26)
97 #define EXYNOS5_DRD_PHYPARAM1 0x20
98 #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0)
99 #define PHYPARAM1_PCS_TXDEEMPH (0x1c)
101 #define EXYNOS5_DRD_PHYTERM 0x24
103 #define EXYNOS5_DRD_PHYTEST 0x28
104 #define PHYTEST_POWERDOWN_SSP BIT(3)
105 #define PHYTEST_POWERDOWN_HSP BIT(2)
107 #define EXYNOS5_DRD_PHYADP 0x2c
109 #define EXYNOS5_DRD_PHYUTMICLKSEL 0x30
110 #define PHYUTMICLKSEL_UTMI_CLKSEL BIT(2)
112 #define EXYNOS5_DRD_PHYRESUME 0x34
114 #define EXYNOS5_DRD_LINKPORT 0x44
116 /* USB 3.0 DRD PHY SS Function Control Reg; accessed by CR_PORT */
117 #define EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN (0x15)
118 #define LOSLEVEL_OVRD_IN_LOS_BIAS_5420 (0x5 << 13)
119 #define LOSLEVEL_OVRD_IN_LOS_BIAS_DEFAULT (0x0 << 13)
120 #define LOSLEVEL_OVRD_IN_EN (0x1 << 10)
121 #define LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT (0x9 << 0)
123 #define EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN (0x12)
124 #define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420 (0x5 << 13)
125 #define TX_VBOOSTLEVEL_OVRD_IN_VBOOST_DEFAULT (0x4 << 13)
127 #define EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG (0x1010)
128 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M (0x4 << 4)
129 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M (0x8 << 4)
130 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_25M_26M (0x8 << 4)
131 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M (0x20 << 4)
132 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_62M5 (0x20 << 4)
133 #define LANE0_TX_DEBUG_RXDET_MEAS_TIME_96M_100M (0x40 << 4)
135 /* Exynos850: USB DRD PHY registers */
136 #define EXYNOS850_DRD_LINKCTRL 0x04
137 #define LINKCTRL_FORCE_RXELECIDLE BIT(18)
138 #define LINKCTRL_FORCE_PHYSTATUS BIT(17)
139 #define LINKCTRL_FORCE_PIPE_EN BIT(16)
140 #define LINKCTRL_FORCE_QACT BIT(8)
141 #define LINKCTRL_BUS_FILTER_BYPASS(_x) ((_x) << 4)
143 #define EXYNOS850_DRD_LINKPORT 0x08
144 #define LINKPORT_HOST_NUM_U3 GENMASK(19, 16)
145 #define LINKPORT_HOST_NUM_U2 GENMASK(15, 12)
147 #define EXYNOS850_DRD_CLKRST 0x20
149 * On versions without SS ports (like E850), bit 3 is for the 2.0 phy (HS),
150 * while on versions with (like gs101), bits 2 and 3 are for the 3.0 phy (SS)
151 * and bits 12 & 13 for the 2.0 phy.
153 #define CLKRST_PHY20_SW_POR BIT(13)
154 #define CLKRST_PHY20_SW_POR_SEL BIT(12)
155 #define CLKRST_LINK_PCLK_SEL BIT(7)
156 #define CLKRST_PHY_SW_RST BIT(3)
157 #define CLKRST_PHY_RESET_SEL BIT(2)
158 #define CLKRST_PORT_RST BIT(1)
159 #define CLKRST_LINK_SW_RST BIT(0)
161 #define EXYNOS850_DRD_SSPPLLCTL 0x30
162 #define SSPPLLCTL_FSEL GENMASK(2, 0)
164 #define EXYNOS850_DRD_UTMI 0x50
165 #define UTMI_FORCE_VBUSVALID BIT(5)
166 #define UTMI_FORCE_BVALID BIT(4)
167 #define UTMI_DP_PULLDOWN BIT(3)
168 #define UTMI_DM_PULLDOWN BIT(2)
169 #define UTMI_FORCE_SUSPEND BIT(1)
170 #define UTMI_FORCE_SLEEP BIT(0)
172 #define EXYNOS850_DRD_HSP 0x54
173 #define HSP_FSV_OUT_EN BIT(24)
174 #define HSP_VBUSVLDEXTSEL BIT(13)
175 #define HSP_VBUSVLDEXT BIT(12)
176 #define HSP_EN_UTMISUSPEND BIT(9)
177 #define HSP_COMMONONN BIT(8)
179 #define EXYNOS850_DRD_HSPPARACON 0x58
180 #define HSPPARACON_TXVREF GENMASK(31, 28)
181 #define HSPPARACON_TXRISE GENMASK(25, 24)
182 #define HSPPARACON_TXRES GENMASK(22, 21)
183 #define HSPPARACON_TXPREEMPPULSE BIT(20)
184 #define HSPPARACON_TXPREEMPAMP GENMASK(19, 18)
185 #define HSPPARACON_TXHSXV GENMASK(17, 16)
186 #define HSPPARACON_TXFSLS GENMASK(15, 12)
187 #define HSPPARACON_SQRX GENMASK(10, 8)
188 #define HSPPARACON_OTG GENMASK(6, 4)
189 #define HSPPARACON_COMPDIS GENMASK(2, 0)
191 #define EXYNOS850_DRD_HSP_TEST 0x5c
192 #define HSP_TEST_SIDDQ BIT(24)
194 /* Exynos9 - GS101 */
195 #define EXYNOS850_DRD_SECPMACTL 0x48
196 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL GENMASK(13, 12)
197 #define SECPMACTL_PMA_LCPLL_REF_CLK_SEL GENMASK(11, 10)
198 #define SECPMACTL_PMA_REF_FREQ_SEL GENMASK(9, 8)
199 #define SECPMACTL_PMA_LOW_PWR BIT(4)
200 #define SECPMACTL_PMA_TRSV_SW_RST BIT(3)
201 #define SECPMACTL_PMA_CMN_SW_RST BIT(2)
202 #define SECPMACTL_PMA_INIT_SW_RST BIT(1)
203 #define SECPMACTL_PMA_APB_SW_RST BIT(0)
206 #define EXYNOS9_PMA_USBDP_CMN_REG0008 0x0020
207 #define CMN_REG0008_OVRD_AUX_EN BIT(3)
208 #define CMN_REG0008_AUX_EN BIT(2)
210 #define EXYNOS9_PMA_USBDP_CMN_REG00B8 0x02e0
211 #define CMN_REG00B8_LANE_MUX_SEL_DP GENMASK(3, 0)
213 #define EXYNOS9_PMA_USBDP_CMN_REG01C0 0x0700
214 #define CMN_REG01C0_ANA_LCPLL_LOCK_DONE BIT(7)
215 #define CMN_REG01C0_ANA_LCPLL_AFC_DONE BIT(6)
217 /* these have similar register layout, for lanes 0 and 2 */
218 #define EXYNOS9_PMA_USBDP_TRSV_REG03C3 0x0f0c
219 #define EXYNOS9_PMA_USBDP_TRSV_REG07C3 0x1f0c
220 #define TRSV_REG03C3_LN0_MON_RX_CDR_AFC_DONE BIT(3)
221 #define TRSV_REG03C3_LN0_MON_RX_CDR_CAL_DONE BIT(2)
222 #define TRSV_REG03C3_LN0_MON_RX_CDR_FLD_PLL_MODE_DONE BIT(1)
223 #define TRSV_REG03C3_LN0_MON_RX_CDR_LOCK_DONE BIT(0)
225 /* TRSV_REG0413 and TRSV_REG0813 have similar register layout */
226 #define EXYNOS9_PMA_USBDP_TRSV_REG0413 0x104c
227 #define TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN BIT(7)
228 #define TRSV_REG0413_OVRD_LN1_TX_RXD_EN BIT(5)
230 #define EXYNOS9_PMA_USBDP_TRSV_REG0813 0x204c
231 #define TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN BIT(7)
232 #define TRSV_REG0813_OVRD_LN3_TX_RXD_EN BIT(5)
235 #define EXYNOS9_PCS_NS_VEC_PS1_N1 0x010c
236 #define EXYNOS9_PCS_NS_VEC_PS2_N0 0x0110
237 #define EXYNOS9_PCS_NS_VEC_PS3_N0 0x0118
238 #define NS_VEC_NS_REQ GENMASK(31, 24)
239 #define NS_VEC_ENABLE_TIMER BIT(22)
240 #define NS_VEC_SEL_TIMEOUT GENMASK(21, 20)
241 #define NS_VEC_INV_MASK GENMASK(19, 16)
242 #define NS_VEC_COND_MASK GENMASK(11, 8)
243 #define NS_VEC_EXP_COND GENMASK(3, 0)
245 #define EXYNOS9_PCS_OUT_VEC_2 0x014c
246 #define EXYNOS9_PCS_OUT_VEC_3 0x0150
247 #define PCS_OUT_VEC_B9_DYNAMIC BIT(19)
248 #define PCS_OUT_VEC_B9_SEL_OUT BIT(18)
249 #define PCS_OUT_VEC_B8_DYNAMIC BIT(17)
250 #define PCS_OUT_VEC_B8_SEL_OUT BIT(16)
251 #define PCS_OUT_VEC_B7_DYNAMIC BIT(15)
252 #define PCS_OUT_VEC_B7_SEL_OUT BIT(14)
253 #define PCS_OUT_VEC_B6_DYNAMIC BIT(13)
254 #define PCS_OUT_VEC_B6_SEL_OUT BIT(12)
255 #define PCS_OUT_VEC_B5_DYNAMIC BIT(11)
256 #define PCS_OUT_VEC_B5_SEL_OUT BIT(10)
257 #define PCS_OUT_VEC_B4_DYNAMIC BIT(9)
258 #define PCS_OUT_VEC_B4_SEL_OUT BIT(8)
259 #define PCS_OUT_VEC_B3_DYNAMIC BIT(7)
260 #define PCS_OUT_VEC_B3_SEL_OUT BIT(6)
261 #define PCS_OUT_VEC_B2_DYNAMIC BIT(5)
262 #define PCS_OUT_VEC_B2_SEL_OUT BIT(4)
263 #define PCS_OUT_VEC_B1_DYNAMIC BIT(3)
264 #define PCS_OUT_VEC_B1_SEL_OUT BIT(2)
265 #define PCS_OUT_VEC_B0_DYNAMIC BIT(1)
266 #define PCS_OUT_VEC_B0_SEL_OUT BIT(0)
268 #define EXYNOS9_PCS_TIMEOUT_0 0x0170
270 #define EXYNOS9_PCS_TIMEOUT_3 0x017c
272 #define EXYNOS9_PCS_EBUF_PARAM 0x0304
273 #define EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE GENMASK(29, 24)
275 #define EXYNOS9_PCS_BACK_END_MODE_VEC 0x030c
276 #define BACK_END_MODE_VEC_FORCE_EBUF_EMPTY_MODE BIT(1)
277 #define BACK_END_MODE_VEC_DISABLE_DATA_MASK BIT(0)
279 #define EXYNOS9_PCS_RX_CONTROL 0x03f0
280 #define RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B BIT(22)
282 #define EXYNOS9_PCS_RX_CONTROL_DEBUG 0x03f4
283 #define RX_CONTROL_DEBUG_EN_TS_CHECK BIT(5)
284 #define RX_CONTROL_DEBUG_NUM_COM_FOUND GENMASK(3, 0)
286 #define EXYNOS9_PCS_LOCAL_COEF 0x040c
287 #define LOCAL_COEF_PMA_CENTER_COEF GENMASK(21, 16)
288 #define LOCAL_COEF_LF GENMASK(13, 8)
289 #define LOCAL_COEF_FS GENMASK(5, 0)
291 #define EXYNOS9_PCS_HS_TX_COEF_MAP_0 0x0410
292 #define HS_TX_COEF_MAP_0_SSTX_DEEMP GENMASK(17, 12)
293 #define HS_TX_COEF_MAP_0_SSTX_LEVEL GENMASK(11, 6)
294 #define HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT GENMASK(5, 0)
298 #define MHZ (KHZ * KHZ)
300 #define PHY_TUNING_ENTRY_PHY(o, m, v) { \
307 #define PHY_TUNING_ENTRY_PCS(o, m, v) { \
314 #define PHY_TUNING_ENTRY_PMA(o, m, v) { \
321 #define PHY_TUNING_ENTRY_LAST { .region = PTR_INVALID }
323 #define for_each_phy_tune(tune) \
324 for (; (tune)->region != PTR_INVALID; ++(tune))
326 struct exynos5_usbdrd_phy_tuning
{
331 #define PTR_INVALID 0
337 enum exynos5_usbdrd_phy_tuning_state
{
346 enum exynos5_usbdrd_phy_id
{
348 EXYNOS5_DRDPHY_PIPE3
,
352 struct phy_usb_instance
;
353 struct exynos5_usbdrd_phy
;
355 struct exynos5_usbdrd_phy_config
{
357 void (*phy_isol
)(struct phy_usb_instance
*inst
, bool isolate
);
358 void (*phy_init
)(struct exynos5_usbdrd_phy
*phy_drd
);
359 unsigned int (*set_refclk
)(struct phy_usb_instance
*inst
);
362 struct exynos5_usbdrd_phy_drvdata
{
363 const struct exynos5_usbdrd_phy_config
*phy_cfg
;
364 const struct exynos5_usbdrd_phy_tuning
**phy_tunes
;
365 const struct phy_ops
*phy_ops
;
366 const char * const *clk_names
;
368 const char * const *core_clk_names
;
370 const char * const *regulator_names
;
372 u32 pmu_offset_usbdrd0_phy
;
373 u32 pmu_offset_usbdrd0_phy_ss
;
374 u32 pmu_offset_usbdrd1_phy
;
378 * struct exynos5_usbdrd_phy - driver data for USB 3.0 PHY
379 * @dev: pointer to device instance of this platform device
380 * @reg_phy: usb phy controller register memory base
381 * @reg_pcs: usb phy physical coding sublayer register memory base
382 * @reg_pma: usb phy physical media attachment register memory base
383 * @clks: clocks for register access
384 * @core_clks: core clocks for phy (ref, pipe3, utmi+, ITP, etc. as required)
385 * @drv_data: pointer to SoC level driver data structure
386 * @phys: array for 'EXYNOS5_DRDPHYS_NUM' number of PHY
387 * instances each with its 'phy' and 'phy_cfg'.
388 * @extrefclk: frequency select settings when using 'separate
389 * reference clocks' for SS and HS operations
390 * @regulators: regulators for phy
392 struct exynos5_usbdrd_phy
{
394 void __iomem
*reg_phy
;
395 void __iomem
*reg_pcs
;
396 void __iomem
*reg_pma
;
397 struct clk_bulk_data
*clks
;
398 struct clk_bulk_data
*core_clks
;
399 const struct exynos5_usbdrd_phy_drvdata
*drv_data
;
400 struct phy_usb_instance
{
403 struct regmap
*reg_pmu
;
405 const struct exynos5_usbdrd_phy_config
*phy_cfg
;
406 } phys
[EXYNOS5_DRDPHYS_NUM
];
408 struct regulator_bulk_data
*regulators
;
412 struct exynos5_usbdrd_phy
*to_usbdrd_phy(struct phy_usb_instance
*inst
)
414 return container_of((inst
), struct exynos5_usbdrd_phy
,
415 phys
[(inst
)->index
]);
419 * exynos5_rate_to_clk() converts the supplied clock rate to the value that
420 * can be written to the phy register.
422 static unsigned int exynos5_rate_to_clk(unsigned long rate
, u32
*reg
)
424 /* EXYNOS5_FSEL_MASK */
428 *reg
= EXYNOS5_FSEL_9MHZ6
;
431 *reg
= EXYNOS5_FSEL_10MHZ
;
434 *reg
= EXYNOS5_FSEL_12MHZ
;
437 *reg
= EXYNOS5_FSEL_19MHZ2
;
440 *reg
= EXYNOS5_FSEL_20MHZ
;
443 *reg
= EXYNOS5_FSEL_24MHZ
;
446 *reg
= EXYNOS5_FSEL_26MHZ
;
449 *reg
= EXYNOS5_FSEL_50MHZ
;
458 static void exynos5_usbdrd_phy_isol(struct phy_usb_instance
*inst
,
466 val
= isolate
? 0 : EXYNOS4_PHY_ENABLE
;
468 regmap_update_bits(inst
->reg_pmu
, inst
->pmu_offset
,
469 EXYNOS4_PHY_ENABLE
, val
);
473 * Sets the pipe3 phy's clk as EXTREFCLK (XXTI) which is internal clock
474 * from clock core. Further sets multiplier values and spread spectrum
475 * clock settings for SuperSpeed operations.
478 exynos5_usbdrd_pipe3_set_refclk(struct phy_usb_instance
*inst
)
481 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
483 /* restore any previous reference clock settings */
484 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYCLKRST
);
486 /* Use EXTREFCLK as ref clock */
487 reg
&= ~PHYCLKRST_REFCLKSEL_MASK
;
488 reg
|= PHYCLKRST_REFCLKSEL_EXT_REFCLK
;
490 /* FSEL settings corresponding to reference clock */
491 reg
&= ~PHYCLKRST_FSEL_PIPE_MASK
|
492 PHYCLKRST_MPLL_MULTIPLIER_MASK
|
493 PHYCLKRST_SSC_REFCLKSEL_MASK
;
494 switch (phy_drd
->extrefclk
) {
495 case EXYNOS5_FSEL_50MHZ
:
496 reg
|= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF
|
497 PHYCLKRST_SSC_REFCLKSEL(0x00));
499 case EXYNOS5_FSEL_24MHZ
:
500 reg
|= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF
|
501 PHYCLKRST_SSC_REFCLKSEL(0x88));
503 case EXYNOS5_FSEL_20MHZ
:
504 reg
|= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF
|
505 PHYCLKRST_SSC_REFCLKSEL(0x00));
507 case EXYNOS5_FSEL_19MHZ2
:
508 reg
|= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF
|
509 PHYCLKRST_SSC_REFCLKSEL(0x88));
512 dev_dbg(phy_drd
->dev
, "unsupported ref clk\n");
520 * Sets the utmi phy's clk as EXTREFCLK (XXTI) which is internal clock
521 * from clock core. Further sets the FSEL values for HighSpeed operations.
524 exynos5_usbdrd_utmi_set_refclk(struct phy_usb_instance
*inst
)
527 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
529 /* restore any previous reference clock settings */
530 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYCLKRST
);
532 reg
&= ~PHYCLKRST_REFCLKSEL_MASK
;
533 reg
|= PHYCLKRST_REFCLKSEL_EXT_REFCLK
;
535 reg
&= ~PHYCLKRST_FSEL_UTMI_MASK
|
536 PHYCLKRST_MPLL_MULTIPLIER_MASK
|
537 PHYCLKRST_SSC_REFCLKSEL_MASK
;
538 reg
|= PHYCLKRST_FSEL(phy_drd
->extrefclk
);
544 exynos5_usbdrd_apply_phy_tunes(struct exynos5_usbdrd_phy
*phy_drd
,
545 enum exynos5_usbdrd_phy_tuning_state state
)
547 const struct exynos5_usbdrd_phy_tuning
*tune
;
549 tune
= phy_drd
->drv_data
->phy_tunes
[state
];
553 for_each_phy_tune(tune
) {
554 void __iomem
*reg_base
;
557 switch (tune
->region
) {
559 reg_base
= phy_drd
->reg_phy
;
562 reg_base
= phy_drd
->reg_pcs
;
565 reg_base
= phy_drd
->reg_pma
;
568 dev_warn_once(phy_drd
->dev
,
569 "unknown phy region %d\n", tune
->region
);
574 reg
= readl(reg_base
+ tune
->off
);
578 writel(reg
, reg_base
+ tune
->off
);
582 static void exynos5_usbdrd_pipe3_init(struct exynos5_usbdrd_phy
*phy_drd
)
586 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM1
);
587 /* Set Tx De-Emphasis level */
588 reg
&= ~PHYPARAM1_PCS_TXDEEMPH_MASK
;
589 reg
|= PHYPARAM1_PCS_TXDEEMPH
;
590 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM1
);
592 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYTEST
);
593 reg
&= ~PHYTEST_POWERDOWN_SSP
;
594 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYTEST
);
598 exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(struct exynos5_usbdrd_phy
*phy_drd
)
600 void __iomem
*regs_base
= phy_drd
->reg_phy
;
603 /* link pipe_clock selection to pclk of PMA */
604 reg
= readl(regs_base
+ EXYNOS850_DRD_CLKRST
);
605 reg
|= CLKRST_LINK_PCLK_SEL
;
606 writel(reg
, regs_base
+ EXYNOS850_DRD_CLKRST
);
608 reg
= readl(regs_base
+ EXYNOS850_DRD_SECPMACTL
);
609 reg
&= ~SECPMACTL_PMA_REF_FREQ_SEL
;
610 reg
|= FIELD_PREP(SECPMACTL_PMA_REF_FREQ_SEL
, 1);
612 reg
|= (SECPMACTL_PMA_LOW_PWR
| SECPMACTL_PMA_APB_SW_RST
);
613 reg
&= ~(SECPMACTL_PMA_ROPLL_REF_CLK_SEL
|
614 SECPMACTL_PMA_LCPLL_REF_CLK_SEL
);
616 reg
|= (SECPMACTL_PMA_TRSV_SW_RST
| SECPMACTL_PMA_CMN_SW_RST
|
617 SECPMACTL_PMA_INIT_SW_RST
);
618 writel(reg
, regs_base
+ EXYNOS850_DRD_SECPMACTL
);
622 reg
= readl(regs_base
+ EXYNOS850_DRD_SECPMACTL
);
623 reg
&= ~SECPMACTL_PMA_LOW_PWR
;
624 writel(reg
, regs_base
+ EXYNOS850_DRD_SECPMACTL
);
628 /* release override */
629 reg
= readl(regs_base
+ EXYNOS850_DRD_LINKCTRL
);
630 reg
&= ~LINKCTRL_FORCE_PIPE_EN
;
631 writel(reg
, regs_base
+ EXYNOS850_DRD_LINKCTRL
);
636 reg
= readl(regs_base
+ EXYNOS850_DRD_SECPMACTL
);
637 reg
&= ~SECPMACTL_PMA_APB_SW_RST
;
638 writel(reg
, regs_base
+ EXYNOS850_DRD_SECPMACTL
);
642 exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(struct exynos5_usbdrd_phy
*phy_drd
)
644 void __iomem
*regs_base
= phy_drd
->reg_pma
;
647 /* lane configuration: USB on all lanes */
648 reg
= readl(regs_base
+ EXYNOS9_PMA_USBDP_CMN_REG00B8
);
649 reg
&= ~CMN_REG00B8_LANE_MUX_SEL_DP
;
650 writel(reg
, regs_base
+ EXYNOS9_PMA_USBDP_CMN_REG00B8
);
653 * FIXME: below code supports one connector orientation only. It needs
654 * updating once we can receive connector events.
656 /* override of TX receiver detector and comparator: lane 1 */
657 reg
= readl(regs_base
+ EXYNOS9_PMA_USBDP_TRSV_REG0413
);
658 reg
&= ~TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN
;
659 reg
&= ~TRSV_REG0413_OVRD_LN1_TX_RXD_EN
;
660 writel(reg
, regs_base
+ EXYNOS9_PMA_USBDP_TRSV_REG0413
);
663 reg
= readl(regs_base
+ EXYNOS9_PMA_USBDP_TRSV_REG0813
);
664 reg
|= TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN
;
665 reg
|= TRSV_REG0813_OVRD_LN3_TX_RXD_EN
;
666 writel(reg
, regs_base
+ EXYNOS9_PMA_USBDP_TRSV_REG0813
);
670 exynos5_usbdrd_usbdp_g2_v4_pma_check_pll_lock(struct exynos5_usbdrd_phy
*phy_drd
)
672 static const unsigned int timeout_us
= 40000;
673 static const unsigned int sleep_us
= 40;
674 static const u32 locked
= (CMN_REG01C0_ANA_LCPLL_LOCK_DONE
|
675 CMN_REG01C0_ANA_LCPLL_AFC_DONE
);
679 err
= readl_poll_timeout(
680 phy_drd
->reg_pma
+ EXYNOS9_PMA_USBDP_CMN_REG01C0
,
681 reg
, (reg
& locked
) == locked
, sleep_us
, timeout_us
);
683 dev_err(phy_drd
->dev
,
684 "timed out waiting for PLL lock: %#.8x\n", reg
);
690 exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(struct exynos5_usbdrd_phy
*phy_drd
)
692 static const unsigned int timeout_us
= 40000;
693 static const unsigned int sleep_us
= 40;
694 static const u32 locked
=
695 (TRSV_REG03C3_LN0_MON_RX_CDR_AFC_DONE
696 | TRSV_REG03C3_LN0_MON_RX_CDR_CAL_DONE
697 | TRSV_REG03C3_LN0_MON_RX_CDR_FLD_PLL_MODE_DONE
698 | TRSV_REG03C3_LN0_MON_RX_CDR_LOCK_DONE
);
702 err
= readl_poll_timeout(
703 phy_drd
->reg_pma
+ EXYNOS9_PMA_USBDP_TRSV_REG03C3
,
704 reg
, (reg
& locked
) == locked
, sleep_us
, timeout_us
);
708 dev_err(phy_drd
->dev
,
709 "timed out waiting for CDR lock (l0): %#.8x, retrying\n", reg
);
711 /* based on cable orientation, this might be on the other phy port */
712 err
= readl_poll_timeout(
713 phy_drd
->reg_pma
+ EXYNOS9_PMA_USBDP_TRSV_REG07C3
,
714 reg
, (reg
& locked
) == locked
, sleep_us
, timeout_us
);
716 dev_err(phy_drd
->dev
,
717 "timed out waiting for CDR lock (l2): %#.8x\n", reg
);
720 static void exynos5_usbdrd_utmi_init(struct exynos5_usbdrd_phy
*phy_drd
)
724 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM0
);
725 /* Set Loss-of-Signal Detector sensitivity */
726 reg
&= ~PHYPARAM0_REF_LOSLEVEL_MASK
;
727 reg
|= PHYPARAM0_REF_LOSLEVEL
;
728 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM0
);
730 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM1
);
731 /* Set Tx De-Emphasis level */
732 reg
&= ~PHYPARAM1_PCS_TXDEEMPH_MASK
;
733 reg
|= PHYPARAM1_PCS_TXDEEMPH
;
734 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM1
);
736 /* UTMI Power Control */
737 writel(PHYUTMI_OTGDISABLE
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYUTMI
);
739 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYTEST
);
740 reg
&= ~PHYTEST_POWERDOWN_HSP
;
741 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYTEST
);
744 static int exynos5_usbdrd_phy_init(struct phy
*phy
)
748 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
749 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
751 ret
= clk_bulk_prepare_enable(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
755 /* Reset USB 3.0 PHY */
756 writel(0x0, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG0
);
757 writel(0x0, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYRESUME
);
760 * Setting the Frame length Adj value[6:1] to default 0x20
761 * See xHCI 1.0 spec, 5.2.4
763 reg
= LINKSYSTEM_XHCI_VERSION_CONTROL
|
764 LINKSYSTEM_FLADJ(0x20);
765 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_LINKSYSTEM
);
767 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM0
);
768 /* Select PHY CLK source */
769 reg
&= ~PHYPARAM0_REF_USE_PAD
;
770 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYPARAM0
);
772 /* This bit must be set for both HS and SS operations */
773 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYUTMICLKSEL
);
774 reg
|= PHYUTMICLKSEL_UTMI_CLKSEL
;
775 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYUTMICLKSEL
);
777 /* UTMI or PIPE3 specific init */
778 inst
->phy_cfg
->phy_init(phy_drd
);
780 /* reference clock settings */
781 reg
= inst
->phy_cfg
->set_refclk(inst
);
783 /* Digital power supply in normal operating mode */
784 reg
|= PHYCLKRST_RETENABLEN
|
785 /* Enable ref clock for SS function */
786 PHYCLKRST_REF_SSP_EN
|
787 /* Enable spread spectrum */
789 /* Power down HS Bias and PLL blocks in suspend mode */
790 PHYCLKRST_COMMONONN
|
794 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYCLKRST
);
798 reg
&= ~PHYCLKRST_PORTRESET
;
799 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYCLKRST
);
801 clk_bulk_disable_unprepare(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
806 static int exynos5_usbdrd_phy_exit(struct phy
*phy
)
810 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
811 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
813 ret
= clk_bulk_prepare_enable(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
817 reg
= PHYUTMI_OTGDISABLE
|
818 PHYUTMI_FORCESUSPEND
|
820 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYUTMI
);
822 /* Resetting the PHYCLKRST enable bits to reduce leakage current */
823 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYCLKRST
);
824 reg
&= ~(PHYCLKRST_REF_SSP_EN
|
826 PHYCLKRST_COMMONONN
);
827 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYCLKRST
);
829 /* Control PHYTEST to remove leakage current */
830 reg
= readl(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYTEST
);
831 reg
|= PHYTEST_POWERDOWN_SSP
|
832 PHYTEST_POWERDOWN_HSP
;
833 writel(reg
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYTEST
);
835 clk_bulk_disable_unprepare(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
840 static int exynos5_usbdrd_phy_power_on(struct phy
*phy
)
843 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
844 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
846 dev_dbg(phy_drd
->dev
, "Request to power_on usbdrd_phy phy\n");
848 ret
= clk_bulk_prepare_enable(phy_drd
->drv_data
->n_core_clks
,
853 /* Enable VBUS supply */
854 ret
= regulator_bulk_enable(phy_drd
->drv_data
->n_regulators
,
855 phy_drd
->regulators
);
857 dev_err(phy_drd
->dev
, "Failed to enable PHY regulator(s)\n");
862 inst
->phy_cfg
->phy_isol(inst
, false);
867 clk_bulk_disable_unprepare(phy_drd
->drv_data
->n_core_clks
,
873 static int exynos5_usbdrd_phy_power_off(struct phy
*phy
)
875 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
876 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
878 dev_dbg(phy_drd
->dev
, "Request to power_off usbdrd_phy phy\n");
880 /* Power-off the PHY */
881 inst
->phy_cfg
->phy_isol(inst
, true);
883 /* Disable VBUS supply */
884 regulator_bulk_disable(phy_drd
->drv_data
->n_regulators
,
885 phy_drd
->regulators
);
887 clk_bulk_disable_unprepare(phy_drd
->drv_data
->n_core_clks
,
893 static int crport_handshake(struct exynos5_usbdrd_phy
*phy_drd
,
899 writel(val
| cmd
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG0
);
901 err
= readl_poll_timeout(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG1
,
902 result
, (result
& PHYREG1_CR_ACK
), 1, 100);
903 if (err
== -ETIMEDOUT
) {
904 dev_err(phy_drd
->dev
, "CRPORT handshake timeout1 (0x%08x)\n", val
);
908 writel(val
, phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG0
);
910 err
= readl_poll_timeout(phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG1
,
911 result
, !(result
& PHYREG1_CR_ACK
), 1, 100);
912 if (err
== -ETIMEDOUT
) {
913 dev_err(phy_drd
->dev
, "CRPORT handshake timeout2 (0x%08x)\n", val
);
920 static int crport_ctrl_write(struct exynos5_usbdrd_phy
*phy_drd
,
926 writel(PHYREG0_CR_DATA_IN(addr
),
927 phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG0
);
928 ret
= crport_handshake(phy_drd
, PHYREG0_CR_DATA_IN(addr
),
929 PHYREG0_CR_CAP_ADDR
);
934 writel(PHYREG0_CR_DATA_IN(data
),
935 phy_drd
->reg_phy
+ EXYNOS5_DRD_PHYREG0
);
936 ret
= crport_handshake(phy_drd
, PHYREG0_CR_DATA_IN(data
),
937 PHYREG0_CR_CAP_DATA
);
941 ret
= crport_handshake(phy_drd
, PHYREG0_CR_DATA_IN(data
),
948 * Calibrate few PHY parameters using CR_PORT register to meet
949 * SuperSpeed requirements on Exynos5420 and Exynos5800 systems,
950 * which have 28nm USB 3.0 DRD PHY.
952 static int exynos5420_usbdrd_phy_calibrate(struct exynos5_usbdrd_phy
*phy_drd
)
958 * Change los_bias to (0x5) for 28nm PHY from a
959 * default value (0x0); los_level is set as default
960 * (0x9) as also reflected in los_level[30:26] bits
961 * of PHYPARAM0 register.
963 temp
= LOSLEVEL_OVRD_IN_LOS_BIAS_5420
|
964 LOSLEVEL_OVRD_IN_EN
|
965 LOSLEVEL_OVRD_IN_LOS_LEVEL_DEFAULT
;
966 ret
= crport_ctrl_write(phy_drd
,
967 EXYNOS5_DRD_PHYSS_LOSLEVEL_OVRD_IN
,
970 dev_err(phy_drd
->dev
,
971 "Failed setting Loss-of-Signal level for SuperSpeed\n");
976 * Set tx_vboost_lvl to (0x5) for 28nm PHY Tuning,
977 * to raise Tx signal level from its default value of (0x4)
979 temp
= TX_VBOOSTLEVEL_OVRD_IN_VBOOST_5420
;
980 ret
= crport_ctrl_write(phy_drd
,
981 EXYNOS5_DRD_PHYSS_TX_VBOOSTLEVEL_OVRD_IN
,
984 dev_err(phy_drd
->dev
,
985 "Failed setting Tx-Vboost-Level for SuperSpeed\n");
990 * Set proper time to wait for RxDetect measurement, for
991 * desired reference clock of PHY, by tuning the CR_PORT
992 * register LANE0.TX_DEBUG which is internal to PHY.
993 * This fixes issue with few USB 3.0 devices, which are
994 * not detected (not even generate interrupts on the bus
995 * on insertion) without this change.
996 * e.g. Samsung SUM-TSB16S 3.0 USB drive.
998 switch (phy_drd
->extrefclk
) {
999 case EXYNOS5_FSEL_50MHZ
:
1000 temp
= LANE0_TX_DEBUG_RXDET_MEAS_TIME_48M_50M_52M
;
1002 case EXYNOS5_FSEL_20MHZ
:
1003 case EXYNOS5_FSEL_19MHZ2
:
1004 temp
= LANE0_TX_DEBUG_RXDET_MEAS_TIME_19M2_20M
;
1006 case EXYNOS5_FSEL_24MHZ
:
1008 temp
= LANE0_TX_DEBUG_RXDET_MEAS_TIME_24M
;
1012 ret
= crport_ctrl_write(phy_drd
,
1013 EXYNOS5_DRD_PHYSS_LANE0_TX_DEBUG
,
1016 dev_err(phy_drd
->dev
,
1017 "Fail to set RxDet measurement time for SuperSpeed\n");
1022 static struct phy
*exynos5_usbdrd_phy_xlate(struct device
*dev
,
1023 const struct of_phandle_args
*args
)
1025 struct exynos5_usbdrd_phy
*phy_drd
= dev_get_drvdata(dev
);
1027 if (WARN_ON(args
->args
[0] >= EXYNOS5_DRDPHYS_NUM
))
1028 return ERR_PTR(-ENODEV
);
1030 return phy_drd
->phys
[args
->args
[0]].phy
;
1033 static int exynos5_usbdrd_phy_calibrate(struct phy
*phy
)
1035 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
1036 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
1038 if (inst
->phy_cfg
->id
== EXYNOS5_DRDPHY_UTMI
)
1039 return exynos5420_usbdrd_phy_calibrate(phy_drd
);
1043 static const struct phy_ops exynos5_usbdrd_phy_ops
= {
1044 .init
= exynos5_usbdrd_phy_init
,
1045 .exit
= exynos5_usbdrd_phy_exit
,
1046 .power_on
= exynos5_usbdrd_phy_power_on
,
1047 .power_off
= exynos5_usbdrd_phy_power_off
,
1048 .calibrate
= exynos5_usbdrd_phy_calibrate
,
1049 .owner
= THIS_MODULE
,
1053 exynos5_usbdrd_usb_v3p1_pipe_override(struct exynos5_usbdrd_phy
*phy_drd
)
1055 void __iomem
*regs_base
= phy_drd
->reg_phy
;
1058 /* force pipe3 signal for link */
1059 reg
= readl(regs_base
+ EXYNOS850_DRD_LINKCTRL
);
1060 reg
&= ~LINKCTRL_FORCE_PHYSTATUS
;
1061 reg
|= LINKCTRL_FORCE_PIPE_EN
| LINKCTRL_FORCE_RXELECIDLE
;
1062 writel(reg
, regs_base
+ EXYNOS850_DRD_LINKCTRL
);
1065 reg
= readl(regs_base
+ EXYNOS850_DRD_SECPMACTL
);
1066 reg
|= SECPMACTL_PMA_LOW_PWR
;
1067 writel(reg
, regs_base
+ EXYNOS850_DRD_SECPMACTL
);
1070 static void exynos850_usbdrd_utmi_init(struct exynos5_usbdrd_phy
*phy_drd
)
1072 void __iomem
*regs_base
= phy_drd
->reg_phy
;
1077 * Disable HWACG (hardware auto clock gating control). This will force
1078 * QACTIVE signal in Q-Channel interface to HIGH level, to make sure
1079 * the PHY clock is not gated by the hardware.
1081 reg
= readl(regs_base
+ EXYNOS850_DRD_LINKCTRL
);
1082 reg
|= LINKCTRL_FORCE_QACT
;
1083 writel(reg
, regs_base
+ EXYNOS850_DRD_LINKCTRL
);
1085 reg
= readl(regs_base
+ EXYNOS850_DRD_LINKPORT
);
1086 ss_ports
= FIELD_GET(LINKPORT_HOST_NUM_U3
, reg
);
1088 /* Start PHY Reset (POR=high) */
1089 reg
= readl(regs_base
+ EXYNOS850_DRD_CLKRST
);
1091 reg
|= CLKRST_PHY20_SW_POR
;
1092 reg
|= CLKRST_PHY20_SW_POR_SEL
;
1093 reg
|= CLKRST_PHY_RESET_SEL
;
1095 reg
|= CLKRST_PHY_SW_RST
;
1096 writel(reg
, regs_base
+ EXYNOS850_DRD_CLKRST
);
1099 reg
= readl(regs_base
+ EXYNOS850_DRD_UTMI
);
1100 reg
&= ~(UTMI_FORCE_SUSPEND
| UTMI_FORCE_SLEEP
| UTMI_DP_PULLDOWN
|
1102 writel(reg
, regs_base
+ EXYNOS850_DRD_UTMI
);
1104 /* Set PHY clock and control HS PHY */
1105 reg
= readl(regs_base
+ EXYNOS850_DRD_HSP
);
1106 reg
|= HSP_EN_UTMISUSPEND
| HSP_COMMONONN
;
1107 writel(reg
, regs_base
+ EXYNOS850_DRD_HSP
);
1109 /* Set VBUS Valid and D+ pull-up control by VBUS pad usage */
1110 reg
= readl(regs_base
+ EXYNOS850_DRD_LINKCTRL
);
1111 reg
|= LINKCTRL_BUS_FILTER_BYPASS(0xf);
1112 writel(reg
, regs_base
+ EXYNOS850_DRD_LINKCTRL
);
1114 reg
= readl(regs_base
+ EXYNOS850_DRD_UTMI
);
1115 reg
|= UTMI_FORCE_BVALID
| UTMI_FORCE_VBUSVALID
;
1116 writel(reg
, regs_base
+ EXYNOS850_DRD_UTMI
);
1118 reg
= readl(regs_base
+ EXYNOS850_DRD_HSP
);
1119 reg
|= HSP_VBUSVLDEXT
| HSP_VBUSVLDEXTSEL
;
1120 writel(reg
, regs_base
+ EXYNOS850_DRD_HSP
);
1122 reg
= readl(regs_base
+ EXYNOS850_DRD_SSPPLLCTL
);
1123 reg
&= ~SSPPLLCTL_FSEL
;
1124 switch (phy_drd
->extrefclk
) {
1125 case EXYNOS5_FSEL_50MHZ
:
1126 reg
|= FIELD_PREP(SSPPLLCTL_FSEL
, 7);
1128 case EXYNOS5_FSEL_26MHZ
:
1129 reg
|= FIELD_PREP(SSPPLLCTL_FSEL
, 6);
1131 case EXYNOS5_FSEL_24MHZ
:
1132 reg
|= FIELD_PREP(SSPPLLCTL_FSEL
, 2);
1134 case EXYNOS5_FSEL_20MHZ
:
1135 reg
|= FIELD_PREP(SSPPLLCTL_FSEL
, 1);
1137 case EXYNOS5_FSEL_19MHZ2
:
1138 reg
|= FIELD_PREP(SSPPLLCTL_FSEL
, 0);
1141 dev_warn(phy_drd
->dev
, "unsupported ref clk: %#.2x\n",
1142 phy_drd
->extrefclk
);
1145 writel(reg
, regs_base
+ EXYNOS850_DRD_SSPPLLCTL
);
1147 if (phy_drd
->drv_data
->phy_tunes
)
1148 exynos5_usbdrd_apply_phy_tunes(phy_drd
,
1151 /* Power up PHY analog blocks */
1152 reg
= readl(regs_base
+ EXYNOS850_DRD_HSP_TEST
);
1153 reg
&= ~HSP_TEST_SIDDQ
;
1154 writel(reg
, regs_base
+ EXYNOS850_DRD_HSP_TEST
);
1156 /* Finish PHY reset (POR=low) */
1157 fsleep(10); /* required before doing POR=low */
1158 reg
= readl(regs_base
+ EXYNOS850_DRD_CLKRST
);
1160 reg
|= CLKRST_PHY20_SW_POR_SEL
;
1161 reg
&= ~CLKRST_PHY20_SW_POR
;
1163 reg
&= ~(CLKRST_PHY_SW_RST
| CLKRST_PORT_RST
);
1164 writel(reg
, regs_base
+ EXYNOS850_DRD_CLKRST
);
1165 fsleep(75); /* required after POR=low for guaranteed PHY clock */
1167 /* Disable single ended signal out */
1168 reg
= readl(regs_base
+ EXYNOS850_DRD_HSP
);
1169 reg
&= ~HSP_FSV_OUT_EN
;
1170 writel(reg
, regs_base
+ EXYNOS850_DRD_HSP
);
1173 exynos5_usbdrd_usb_v3p1_pipe_override(phy_drd
);
1176 static int exynos850_usbdrd_phy_init(struct phy
*phy
)
1178 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
1179 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
1182 ret
= clk_bulk_prepare_enable(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
1186 /* UTMI or PIPE3 specific init */
1187 inst
->phy_cfg
->phy_init(phy_drd
);
1189 clk_bulk_disable_unprepare(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
1194 static int exynos850_usbdrd_phy_exit(struct phy
*phy
)
1196 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
1197 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
1198 void __iomem
*regs_base
= phy_drd
->reg_phy
;
1202 ret
= clk_bulk_prepare_enable(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
1206 /* Set PHY clock and control HS PHY */
1207 reg
= readl(regs_base
+ EXYNOS850_DRD_UTMI
);
1208 reg
&= ~(UTMI_DP_PULLDOWN
| UTMI_DM_PULLDOWN
);
1209 reg
|= UTMI_FORCE_SUSPEND
| UTMI_FORCE_SLEEP
;
1210 writel(reg
, regs_base
+ EXYNOS850_DRD_UTMI
);
1212 /* Power down PHY analog blocks */
1213 reg
= readl(regs_base
+ EXYNOS850_DRD_HSP_TEST
);
1214 reg
|= HSP_TEST_SIDDQ
;
1215 writel(reg
, regs_base
+ EXYNOS850_DRD_HSP_TEST
);
1218 reg
= readl(regs_base
+ EXYNOS850_DRD_CLKRST
);
1219 reg
|= CLKRST_LINK_SW_RST
;
1220 writel(reg
, regs_base
+ EXYNOS850_DRD_CLKRST
);
1221 fsleep(10); /* required before doing POR=low */
1222 reg
&= ~CLKRST_LINK_SW_RST
;
1223 writel(reg
, regs_base
+ EXYNOS850_DRD_CLKRST
);
1225 clk_bulk_disable_unprepare(phy_drd
->drv_data
->n_clks
, phy_drd
->clks
);
1230 static const struct phy_ops exynos850_usbdrd_phy_ops
= {
1231 .init
= exynos850_usbdrd_phy_init
,
1232 .exit
= exynos850_usbdrd_phy_exit
,
1233 .power_on
= exynos5_usbdrd_phy_power_on
,
1234 .power_off
= exynos5_usbdrd_phy_power_off
,
1235 .owner
= THIS_MODULE
,
1238 static void exynos5_usbdrd_gs101_pipe3_init(struct exynos5_usbdrd_phy
*phy_drd
)
1240 void __iomem
*regs_pma
= phy_drd
->reg_pma
;
1241 void __iomem
*regs_phy
= phy_drd
->reg_phy
;
1244 exynos5_usbdrd_usbdp_g2_v4_ctrl_pma_ready(phy_drd
);
1247 reg
= readl(regs_pma
+ EXYNOS9_PMA_USBDP_CMN_REG0008
);
1248 reg
&= ~CMN_REG0008_AUX_EN
;
1249 reg
|= CMN_REG0008_OVRD_AUX_EN
;
1250 writel(reg
, regs_pma
+ EXYNOS9_PMA_USBDP_CMN_REG0008
);
1252 exynos5_usbdrd_apply_phy_tunes(phy_drd
, PTS_PIPE3_PREINIT
);
1253 exynos5_usbdrd_apply_phy_tunes(phy_drd
, PTS_PIPE3_INIT
);
1254 exynos5_usbdrd_apply_phy_tunes(phy_drd
, PTS_PIPE3_POSTINIT
);
1256 exynos5_usbdrd_usbdp_g2_v4_pma_lane_mux_sel(phy_drd
);
1258 /* reset release from port */
1259 reg
= readl(regs_phy
+ EXYNOS850_DRD_SECPMACTL
);
1260 reg
&= ~(SECPMACTL_PMA_TRSV_SW_RST
| SECPMACTL_PMA_CMN_SW_RST
|
1261 SECPMACTL_PMA_INIT_SW_RST
);
1262 writel(reg
, regs_phy
+ EXYNOS850_DRD_SECPMACTL
);
1264 if (!exynos5_usbdrd_usbdp_g2_v4_pma_check_pll_lock(phy_drd
))
1265 exynos5_usbdrd_usbdp_g2_v4_pma_check_cdr_lock(phy_drd
);
1268 static int exynos5_usbdrd_gs101_phy_init(struct phy
*phy
)
1270 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
1271 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
1274 if (inst
->phy_cfg
->id
== EXYNOS5_DRDPHY_UTMI
) {
1275 /* Power-on PHY ... */
1276 ret
= regulator_bulk_enable(phy_drd
->drv_data
->n_regulators
,
1277 phy_drd
->regulators
);
1279 dev_err(phy_drd
->dev
,
1280 "Failed to enable PHY regulator(s)\n");
1285 * ... and ungate power via PMU. Without this here, we get an SError
1286 * trying to access PMA registers
1288 exynos5_usbdrd_phy_isol(inst
, false);
1290 return exynos850_usbdrd_phy_init(phy
);
1293 static int exynos5_usbdrd_gs101_phy_exit(struct phy
*phy
)
1295 struct phy_usb_instance
*inst
= phy_get_drvdata(phy
);
1296 struct exynos5_usbdrd_phy
*phy_drd
= to_usbdrd_phy(inst
);
1299 if (inst
->phy_cfg
->id
!= EXYNOS5_DRDPHY_UTMI
)
1302 ret
= exynos850_usbdrd_phy_exit(phy
);
1306 exynos5_usbdrd_phy_isol(inst
, true);
1307 return regulator_bulk_disable(phy_drd
->drv_data
->n_regulators
,
1308 phy_drd
->regulators
);
1311 static const struct phy_ops gs101_usbdrd_phy_ops
= {
1312 .init
= exynos5_usbdrd_gs101_phy_init
,
1313 .exit
= exynos5_usbdrd_gs101_phy_exit
,
1314 .owner
= THIS_MODULE
,
1317 static int exynos5_usbdrd_phy_clk_handle(struct exynos5_usbdrd_phy
*phy_drd
)
1320 struct clk
*ref_clk
;
1321 unsigned long ref_rate
;
1323 phy_drd
->clks
= devm_kcalloc(phy_drd
->dev
, phy_drd
->drv_data
->n_clks
,
1324 sizeof(*phy_drd
->clks
), GFP_KERNEL
);
1328 for (int i
= 0; i
< phy_drd
->drv_data
->n_clks
; ++i
)
1329 phy_drd
->clks
[i
].id
= phy_drd
->drv_data
->clk_names
[i
];
1331 ret
= devm_clk_bulk_get(phy_drd
->dev
, phy_drd
->drv_data
->n_clks
,
1334 return dev_err_probe(phy_drd
->dev
, ret
,
1335 "failed to get phy clock(s)\n");
1337 phy_drd
->core_clks
= devm_kcalloc(phy_drd
->dev
,
1338 phy_drd
->drv_data
->n_core_clks
,
1339 sizeof(*phy_drd
->core_clks
),
1341 if (!phy_drd
->core_clks
)
1344 for (int i
= 0; i
< phy_drd
->drv_data
->n_core_clks
; ++i
)
1345 phy_drd
->core_clks
[i
].id
= phy_drd
->drv_data
->core_clk_names
[i
];
1347 ret
= devm_clk_bulk_get(phy_drd
->dev
, phy_drd
->drv_data
->n_core_clks
,
1348 phy_drd
->core_clks
);
1350 return dev_err_probe(phy_drd
->dev
, ret
,
1351 "failed to get phy core clock(s)\n");
1354 for (int i
= 0; i
< phy_drd
->drv_data
->n_core_clks
; ++i
) {
1355 if (!strcmp(phy_drd
->core_clks
[i
].id
, "ref")) {
1356 ref_clk
= phy_drd
->core_clks
[i
].clk
;
1361 return dev_err_probe(phy_drd
->dev
, -ENODEV
,
1362 "failed to find phy reference clock\n");
1364 ref_rate
= clk_get_rate(ref_clk
);
1365 ret
= exynos5_rate_to_clk(ref_rate
, &phy_drd
->extrefclk
);
1367 return dev_err_probe(phy_drd
->dev
, ret
,
1368 "clock rate (%ld) not supported\n",
1374 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos5
[] = {
1376 .id
= EXYNOS5_DRDPHY_UTMI
,
1377 .phy_isol
= exynos5_usbdrd_phy_isol
,
1378 .phy_init
= exynos5_usbdrd_utmi_init
,
1379 .set_refclk
= exynos5_usbdrd_utmi_set_refclk
,
1382 .id
= EXYNOS5_DRDPHY_PIPE3
,
1383 .phy_isol
= exynos5_usbdrd_phy_isol
,
1384 .phy_init
= exynos5_usbdrd_pipe3_init
,
1385 .set_refclk
= exynos5_usbdrd_pipe3_set_refclk
,
1389 static const struct exynos5_usbdrd_phy_config phy_cfg_exynos850
[] = {
1391 .id
= EXYNOS5_DRDPHY_UTMI
,
1392 .phy_isol
= exynos5_usbdrd_phy_isol
,
1393 .phy_init
= exynos850_usbdrd_utmi_init
,
1397 static const char * const exynos5_clk_names
[] = {
1401 static const char * const exynos5_core_clk_names
[] = {
1405 static const char * const exynos5433_core_clk_names
[] = {
1406 "ref", "phy_pipe", "phy_utmi", "itp",
1409 static const char * const exynos5_regulator_names
[] = {
1410 "vbus", "vbus-boost",
1413 static const struct exynos5_usbdrd_phy_drvdata exynos5420_usbdrd_phy
= {
1414 .phy_cfg
= phy_cfg_exynos5
,
1415 .phy_ops
= &exynos5_usbdrd_phy_ops
,
1416 .pmu_offset_usbdrd0_phy
= EXYNOS5_USBDRD_PHY_CONTROL
,
1417 .pmu_offset_usbdrd1_phy
= EXYNOS5420_USBDRD1_PHY_CONTROL
,
1418 .clk_names
= exynos5_clk_names
,
1419 .n_clks
= ARRAY_SIZE(exynos5_clk_names
),
1420 .core_clk_names
= exynos5_core_clk_names
,
1421 .n_core_clks
= ARRAY_SIZE(exynos5_core_clk_names
),
1422 .regulator_names
= exynos5_regulator_names
,
1423 .n_regulators
= ARRAY_SIZE(exynos5_regulator_names
),
1426 static const struct exynos5_usbdrd_phy_drvdata exynos5250_usbdrd_phy
= {
1427 .phy_cfg
= phy_cfg_exynos5
,
1428 .phy_ops
= &exynos5_usbdrd_phy_ops
,
1429 .pmu_offset_usbdrd0_phy
= EXYNOS5_USBDRD_PHY_CONTROL
,
1430 .clk_names
= exynos5_clk_names
,
1431 .n_clks
= ARRAY_SIZE(exynos5_clk_names
),
1432 .core_clk_names
= exynos5_core_clk_names
,
1433 .n_core_clks
= ARRAY_SIZE(exynos5_core_clk_names
),
1434 .regulator_names
= exynos5_regulator_names
,
1435 .n_regulators
= ARRAY_SIZE(exynos5_regulator_names
),
1438 static const struct exynos5_usbdrd_phy_drvdata exynos5433_usbdrd_phy
= {
1439 .phy_cfg
= phy_cfg_exynos5
,
1440 .phy_ops
= &exynos5_usbdrd_phy_ops
,
1441 .pmu_offset_usbdrd0_phy
= EXYNOS5_USBDRD_PHY_CONTROL
,
1442 .pmu_offset_usbdrd1_phy
= EXYNOS5433_USBHOST30_PHY_CONTROL
,
1443 .clk_names
= exynos5_clk_names
,
1444 .n_clks
= ARRAY_SIZE(exynos5_clk_names
),
1445 .core_clk_names
= exynos5433_core_clk_names
,
1446 .n_core_clks
= ARRAY_SIZE(exynos5433_core_clk_names
),
1447 .regulator_names
= exynos5_regulator_names
,
1448 .n_regulators
= ARRAY_SIZE(exynos5_regulator_names
),
1451 static const struct exynos5_usbdrd_phy_drvdata exynos7_usbdrd_phy
= {
1452 .phy_cfg
= phy_cfg_exynos5
,
1453 .phy_ops
= &exynos5_usbdrd_phy_ops
,
1454 .pmu_offset_usbdrd0_phy
= EXYNOS5_USBDRD_PHY_CONTROL
,
1455 .clk_names
= exynos5_clk_names
,
1456 .n_clks
= ARRAY_SIZE(exynos5_clk_names
),
1457 .core_clk_names
= exynos5433_core_clk_names
,
1458 .n_core_clks
= ARRAY_SIZE(exynos5433_core_clk_names
),
1459 .regulator_names
= exynos5_regulator_names
,
1460 .n_regulators
= ARRAY_SIZE(exynos5_regulator_names
),
1463 static const struct exynos5_usbdrd_phy_drvdata exynos850_usbdrd_phy
= {
1464 .phy_cfg
= phy_cfg_exynos850
,
1465 .phy_ops
= &exynos850_usbdrd_phy_ops
,
1466 .pmu_offset_usbdrd0_phy
= EXYNOS5_USBDRD_PHY_CONTROL
,
1467 .clk_names
= exynos5_clk_names
,
1468 .n_clks
= ARRAY_SIZE(exynos5_clk_names
),
1469 .core_clk_names
= exynos5_core_clk_names
,
1470 .n_core_clks
= ARRAY_SIZE(exynos5_core_clk_names
),
1471 .regulator_names
= exynos5_regulator_names
,
1472 .n_regulators
= ARRAY_SIZE(exynos5_regulator_names
),
1475 static const struct exynos5_usbdrd_phy_config phy_cfg_gs101
[] = {
1477 .id
= EXYNOS5_DRDPHY_UTMI
,
1478 .phy_isol
= exynos5_usbdrd_phy_isol
,
1479 .phy_init
= exynos850_usbdrd_utmi_init
,
1482 .id
= EXYNOS5_DRDPHY_PIPE3
,
1483 .phy_isol
= exynos5_usbdrd_phy_isol
,
1484 .phy_init
= exynos5_usbdrd_gs101_pipe3_init
,
1488 static const struct exynos5_usbdrd_phy_tuning gs101_tunes_utmi_postinit
[] = {
1489 PHY_TUNING_ENTRY_PHY(EXYNOS850_DRD_HSPPARACON
,
1490 (HSPPARACON_TXVREF
| HSPPARACON_TXRES
|
1491 HSPPARACON_TXPREEMPAMP
| HSPPARACON_SQRX
|
1492 HSPPARACON_COMPDIS
),
1493 (FIELD_PREP_CONST(HSPPARACON_TXVREF
, 6) |
1494 FIELD_PREP_CONST(HSPPARACON_TXRES
, 1) |
1495 FIELD_PREP_CONST(HSPPARACON_TXPREEMPAMP
, 3) |
1496 FIELD_PREP_CONST(HSPPARACON_SQRX
, 5) |
1497 FIELD_PREP_CONST(HSPPARACON_COMPDIS
, 7))),
1498 PHY_TUNING_ENTRY_LAST
1501 static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_preinit
[] = {
1503 /* CDR data mode exit GEN1 ON / GEN2 OFF */
1504 PHY_TUNING_ENTRY_PMA(0x0c8c, -1, 0xff),
1505 PHY_TUNING_ENTRY_PMA(0x1c8c, -1, 0xff),
1506 PHY_TUNING_ENTRY_PMA(0x0c9c, -1, 0x7d),
1507 PHY_TUNING_ENTRY_PMA(0x1c9c, -1, 0x7d),
1508 /* improve EDS distribution */
1509 PHY_TUNING_ENTRY_PMA(0x0e7c, -1, 0x06),
1510 PHY_TUNING_ENTRY_PMA(0x09e0, -1, 0x00),
1511 PHY_TUNING_ENTRY_PMA(0x09e4, -1, 0x36),
1512 PHY_TUNING_ENTRY_PMA(0x1e7c, -1, 0x06),
1513 PHY_TUNING_ENTRY_PMA(0x1e90, -1, 0x00),
1514 PHY_TUNING_ENTRY_PMA(0x1e94, -1, 0x36),
1516 PHY_TUNING_ENTRY_PMA(0x08f0, -1, 0x30),
1517 PHY_TUNING_ENTRY_PMA(0x18f0, -1, 0x30),
1518 /* LFPS RX VIH shmoo hole */
1519 PHY_TUNING_ENTRY_PMA(0x0a08, -1, 0x0c),
1520 PHY_TUNING_ENTRY_PMA(0x1a08, -1, 0x0c),
1521 /* remove unrelated option for v4 phy */
1522 PHY_TUNING_ENTRY_PMA(0x0a0c, -1, 0x05),
1523 PHY_TUNING_ENTRY_PMA(0x1a0c, -1, 0x05),
1524 /* improve Gen2 LVCC */
1525 PHY_TUNING_ENTRY_PMA(0x00f8, -1, 0x1c),
1526 PHY_TUNING_ENTRY_PMA(0x00fc, -1, 0x54),
1527 /* Change Vth of RCV_DET because of TD 7.40 Polling Retry Test */
1528 PHY_TUNING_ENTRY_PMA(0x104c, -1, 0x07),
1529 PHY_TUNING_ENTRY_PMA(0x204c, -1, 0x07),
1530 /* reduce Ux Exit time, assuming 26MHz clock */
1532 PHY_TUNING_ENTRY_PMA(0x0ca8, -1, 0x00),
1533 PHY_TUNING_ENTRY_PMA(0x0cac, -1, 0x04),
1534 PHY_TUNING_ENTRY_PMA(0x1ca8, -1, 0x00),
1535 PHY_TUNING_ENTRY_PMA(0x1cac, -1, 0x04),
1537 PHY_TUNING_ENTRY_PMA(0x0cb8, -1, 0x00),
1538 PHY_TUNING_ENTRY_PMA(0x0cbc, -1, 0x04),
1539 PHY_TUNING_ENTRY_PMA(0x1cb8, -1, 0x00),
1540 PHY_TUNING_ENTRY_PMA(0x1cbc, -1, 0x04),
1541 /* RX impedance setting */
1542 PHY_TUNING_ENTRY_PMA(0x0bb0, 0x03, 0x01),
1543 PHY_TUNING_ENTRY_PMA(0x0bb4, 0xf0, 0xa0),
1544 PHY_TUNING_ENTRY_PMA(0x1bb0, 0x03, 0x01),
1545 PHY_TUNING_ENTRY_PMA(0x1bb4, 0xf0, 0xa0),
1547 PHY_TUNING_ENTRY_LAST
1550 static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_init
[] = {
1552 /* abnormal common pattern mask */
1553 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_BACK_END_MODE_VEC
,
1554 BACK_END_MODE_VEC_DISABLE_DATA_MASK
, 0),
1555 /* de-serializer enabled when U2 */
1556 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_OUT_VEC_2
, PCS_OUT_VEC_B4_DYNAMIC
,
1557 PCS_OUT_VEC_B4_SEL_OUT
),
1558 /* TX Keeper Disable, Squelch on when U3 */
1559 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_OUT_VEC_3
, PCS_OUT_VEC_B7_DYNAMIC
,
1560 PCS_OUT_VEC_B7_SEL_OUT
| PCS_OUT_VEC_B2_SEL_OUT
),
1561 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_NS_VEC_PS1_N1
, -1,
1562 (FIELD_PREP_CONST(NS_VEC_NS_REQ
, 5) |
1563 NS_VEC_ENABLE_TIMER
|
1564 FIELD_PREP_CONST(NS_VEC_SEL_TIMEOUT
, 3))),
1565 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_NS_VEC_PS2_N0
, -1,
1566 (FIELD_PREP_CONST(NS_VEC_NS_REQ
, 1) |
1567 NS_VEC_ENABLE_TIMER
|
1568 FIELD_PREP_CONST(NS_VEC_SEL_TIMEOUT
, 3) |
1569 FIELD_PREP_CONST(NS_VEC_COND_MASK
, 2) |
1570 FIELD_PREP_CONST(NS_VEC_EXP_COND
, 2))),
1571 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_NS_VEC_PS3_N0
, -1,
1572 (FIELD_PREP_CONST(NS_VEC_NS_REQ
, 1) |
1573 NS_VEC_ENABLE_TIMER
|
1574 FIELD_PREP_CONST(NS_VEC_SEL_TIMEOUT
, 3) |
1575 FIELD_PREP_CONST(NS_VEC_COND_MASK
, 7) |
1576 FIELD_PREP_CONST(NS_VEC_EXP_COND
, 7))),
1577 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_TIMEOUT_0
, -1, 112),
1578 /* Block Aligner Type B */
1579 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_RX_CONTROL
, 0,
1580 RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B
),
1581 /* Block align at TS1/TS2 for Gen2 stability (Gen2 only) */
1582 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_RX_CONTROL_DEBUG
,
1583 RX_CONTROL_DEBUG_NUM_COM_FOUND
,
1584 (RX_CONTROL_DEBUG_EN_TS_CHECK
|
1586 * increase pcs ts1 adding packet-cnt 1 --> 4
1587 * lnx_rx_valid_rstn_delay_rise_sp/ssp :
1588 * 19.6us(0x200) -> 15.3us(0x4)
1590 FIELD_PREP_CONST(RX_CONTROL_DEBUG_NUM_COM_FOUND
, 4))),
1591 /* Gen1 Tx DRIVER pre-shoot, de-emphasis, level ctrl */
1592 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_HS_TX_COEF_MAP_0
,
1593 (HS_TX_COEF_MAP_0_SSTX_DEEMP
| HS_TX_COEF_MAP_0_SSTX_LEVEL
|
1594 HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT
),
1595 (FIELD_PREP_CONST(HS_TX_COEF_MAP_0_SSTX_DEEMP
, 8) |
1596 FIELD_PREP_CONST(HS_TX_COEF_MAP_0_SSTX_LEVEL
, 0xb) |
1597 FIELD_PREP_CONST(HS_TX_COEF_MAP_0_SSTX_PRE_SHOOT
, 0))),
1598 /* Gen2 Tx DRIVER level ctrl */
1599 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_LOCAL_COEF
,
1600 LOCAL_COEF_PMA_CENTER_COEF
,
1601 FIELD_PREP_CONST(LOCAL_COEF_PMA_CENTER_COEF
, 0xb)),
1602 /* Gen2 U1 exit LFPS duration : 900ns ~ 1.2us */
1603 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_TIMEOUT_3
, -1, 4096),
1604 /* set skp_remove_th 0x2 -> 0x7 for avoiding retry problem. */
1605 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_EBUF_PARAM
,
1606 EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE
,
1607 FIELD_PREP_CONST(EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE
, 0x7)),
1609 PHY_TUNING_ENTRY_LAST
1612 static const struct exynos5_usbdrd_phy_tuning gs101_tunes_pipe3_postlock
[] = {
1613 /* Squelch off when U3 */
1614 PHY_TUNING_ENTRY_PCS(EXYNOS9_PCS_OUT_VEC_3
, PCS_OUT_VEC_B2_SEL_OUT
, 0),
1616 PHY_TUNING_ENTRY_LAST
1619 static const struct exynos5_usbdrd_phy_tuning
*gs101_tunes
[PTS_MAX
] = {
1620 [PTS_UTMI_POSTINIT
] = gs101_tunes_utmi_postinit
,
1621 [PTS_PIPE3_PREINIT
] = gs101_tunes_pipe3_preinit
,
1622 [PTS_PIPE3_INIT
] = gs101_tunes_pipe3_init
,
1623 [PTS_PIPE3_POSTLOCK
] = gs101_tunes_pipe3_postlock
,
1626 static const char * const gs101_clk_names
[] = {
1627 "phy", "ctrl_aclk", "ctrl_pclk", "scl_pclk",
1630 static const char * const gs101_regulator_names
[] = {
1632 "dvdd-usb20", "vddh-usb20", "vdd33-usb20",
1633 "vdda-usbdp", "vddh-usbdp",
1636 static const struct exynos5_usbdrd_phy_drvdata gs101_usbd31rd_phy
= {
1637 .phy_cfg
= phy_cfg_gs101
,
1638 .phy_tunes
= gs101_tunes
,
1639 .phy_ops
= &gs101_usbdrd_phy_ops
,
1640 .pmu_offset_usbdrd0_phy
= GS101_PHY_CTRL_USB20
,
1641 .pmu_offset_usbdrd0_phy_ss
= GS101_PHY_CTRL_USBDP
,
1642 .clk_names
= gs101_clk_names
,
1643 .n_clks
= ARRAY_SIZE(gs101_clk_names
),
1644 .core_clk_names
= exynos5_core_clk_names
,
1645 .n_core_clks
= ARRAY_SIZE(exynos5_core_clk_names
),
1646 .regulator_names
= gs101_regulator_names
,
1647 .n_regulators
= ARRAY_SIZE(gs101_regulator_names
),
1650 static const struct of_device_id exynos5_usbdrd_phy_of_match
[] = {
1652 .compatible
= "google,gs101-usb31drd-phy",
1653 .data
= &gs101_usbd31rd_phy
1655 .compatible
= "samsung,exynos5250-usbdrd-phy",
1656 .data
= &exynos5250_usbdrd_phy
1658 .compatible
= "samsung,exynos5420-usbdrd-phy",
1659 .data
= &exynos5420_usbdrd_phy
1661 .compatible
= "samsung,exynos5433-usbdrd-phy",
1662 .data
= &exynos5433_usbdrd_phy
1664 .compatible
= "samsung,exynos7-usbdrd-phy",
1665 .data
= &exynos7_usbdrd_phy
1667 .compatible
= "samsung,exynos850-usbdrd-phy",
1668 .data
= &exynos850_usbdrd_phy
1672 MODULE_DEVICE_TABLE(of
, exynos5_usbdrd_phy_of_match
);
1674 static int exynos5_usbdrd_phy_probe(struct platform_device
*pdev
)
1676 struct device
*dev
= &pdev
->dev
;
1677 struct device_node
*node
= dev
->of_node
;
1678 struct exynos5_usbdrd_phy
*phy_drd
;
1679 struct phy_provider
*phy_provider
;
1680 const struct exynos5_usbdrd_phy_drvdata
*drv_data
;
1681 struct regmap
*reg_pmu
;
1686 phy_drd
= devm_kzalloc(dev
, sizeof(*phy_drd
), GFP_KERNEL
);
1690 dev_set_drvdata(dev
, phy_drd
);
1693 drv_data
= of_device_get_match_data(dev
);
1696 phy_drd
->drv_data
= drv_data
;
1698 if (of_property_present(dev
->of_node
, "reg-names")) {
1701 reg
= devm_platform_ioremap_resource_byname(pdev
, "phy");
1703 return PTR_ERR(reg
);
1704 phy_drd
->reg_phy
= reg
;
1706 reg
= devm_platform_ioremap_resource_byname(pdev
, "pcs");
1708 return PTR_ERR(reg
);
1709 phy_drd
->reg_pcs
= reg
;
1711 reg
= devm_platform_ioremap_resource_byname(pdev
, "pma");
1713 return PTR_ERR(reg
);
1714 phy_drd
->reg_pma
= reg
;
1716 /* DTB with just a single region */
1717 phy_drd
->reg_phy
= devm_platform_ioremap_resource(pdev
, 0);
1718 if (IS_ERR(phy_drd
->reg_phy
))
1719 return PTR_ERR(phy_drd
->reg_phy
);
1722 ret
= exynos5_usbdrd_phy_clk_handle(phy_drd
);
1726 reg_pmu
= syscon_regmap_lookup_by_phandle(dev
->of_node
,
1727 "samsung,pmu-syscon");
1728 if (IS_ERR(reg_pmu
)) {
1729 dev_err(dev
, "Failed to lookup PMU regmap\n");
1730 return PTR_ERR(reg_pmu
);
1734 * Exynos5420 SoC has multiple channels for USB 3.0 PHY, with
1735 * each having separate power control registers.
1736 * 'channel' facilitates to set such registers.
1738 channel
= of_alias_get_id(node
, "usbdrdphy");
1740 dev_dbg(dev
, "Not a multi-controller usbdrd phy\n");
1742 /* Get regulators */
1743 phy_drd
->regulators
= devm_kcalloc(dev
,
1744 drv_data
->n_regulators
,
1745 sizeof(*phy_drd
->regulators
),
1747 if (!phy_drd
->regulators
)
1749 regulator_bulk_set_supply_names(phy_drd
->regulators
,
1750 drv_data
->regulator_names
,
1751 drv_data
->n_regulators
);
1752 ret
= devm_regulator_bulk_get(dev
, drv_data
->n_regulators
,
1753 phy_drd
->regulators
);
1755 return dev_err_probe(dev
, ret
, "failed to get regulators\n");
1757 dev_vdbg(dev
, "Creating usbdrd_phy phy\n");
1759 for (i
= 0; i
< EXYNOS5_DRDPHYS_NUM
; i
++) {
1760 struct phy
*phy
= devm_phy_create(dev
, NULL
, drv_data
->phy_ops
);
1763 dev_err(dev
, "Failed to create usbdrd_phy phy\n");
1764 return PTR_ERR(phy
);
1767 phy_drd
->phys
[i
].phy
= phy
;
1768 phy_drd
->phys
[i
].index
= i
;
1769 phy_drd
->phys
[i
].reg_pmu
= reg_pmu
;
1772 pmu_offset
= drv_data
->pmu_offset_usbdrd1_phy
;
1776 pmu_offset
= drv_data
->pmu_offset_usbdrd0_phy
;
1777 if (i
== EXYNOS5_DRDPHY_PIPE3
&& drv_data
1778 ->pmu_offset_usbdrd0_phy_ss
)
1779 pmu_offset
= drv_data
->pmu_offset_usbdrd0_phy_ss
;
1782 phy_drd
->phys
[i
].pmu_offset
= pmu_offset
;
1783 phy_drd
->phys
[i
].phy_cfg
= &drv_data
->phy_cfg
[i
];
1784 phy_set_drvdata(phy
, &phy_drd
->phys
[i
]);
1787 phy_provider
= devm_of_phy_provider_register(dev
,
1788 exynos5_usbdrd_phy_xlate
);
1789 if (IS_ERR(phy_provider
)) {
1790 dev_err(phy_drd
->dev
, "Failed to register phy provider\n");
1791 return PTR_ERR(phy_provider
);
1797 static struct platform_driver exynos5_usb3drd_phy
= {
1798 .probe
= exynos5_usbdrd_phy_probe
,
1800 .of_match_table
= exynos5_usbdrd_phy_of_match
,
1801 .name
= "exynos5_usb3drd_phy",
1802 .suppress_bind_attrs
= true,
1806 module_platform_driver(exynos5_usb3drd_phy
);
1807 MODULE_DESCRIPTION("Samsung Exynos5 SoCs USB 3.0 DRD controller PHY driver");
1808 MODULE_AUTHOR("Vivek Gautam <gautam.vivek@samsung.com>");
1809 MODULE_LICENSE("GPL v2");
1810 MODULE_ALIAS("platform:exynos5_usb3drd_phy");