2 * Samsung SoC USB 1.1/2.0 PHY driver - Exynos 4x12 support
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * Author: Kamil Debski <k.debski@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/delay.h>
14 #include <linux/phy/phy.h>
15 #include <linux/regmap.h>
16 #include "phy-samsung-usb2.h"
18 /* Exynos USB PHY registers */
20 /* PHY power control */
21 #define EXYNOS_4x12_UPHYPWR 0x0
23 #define EXYNOS_4x12_UPHYPWR_PHY0_SUSPEND BIT(0)
24 #define EXYNOS_4x12_UPHYPWR_PHY0_PWR BIT(3)
25 #define EXYNOS_4x12_UPHYPWR_PHY0_OTG_PWR BIT(4)
26 #define EXYNOS_4x12_UPHYPWR_PHY0_SLEEP BIT(5)
27 #define EXYNOS_4x12_UPHYPWR_PHY0 ( \
28 EXYNOS_4x12_UPHYPWR_PHY0_SUSPEND | \
29 EXYNOS_4x12_UPHYPWR_PHY0_PWR | \
30 EXYNOS_4x12_UPHYPWR_PHY0_OTG_PWR | \
31 EXYNOS_4x12_UPHYPWR_PHY0_SLEEP)
33 #define EXYNOS_4x12_UPHYPWR_PHY1_SUSPEND BIT(6)
34 #define EXYNOS_4x12_UPHYPWR_PHY1_PWR BIT(7)
35 #define EXYNOS_4x12_UPHYPWR_PHY1_SLEEP BIT(8)
36 #define EXYNOS_4x12_UPHYPWR_PHY1 ( \
37 EXYNOS_4x12_UPHYPWR_PHY1_SUSPEND | \
38 EXYNOS_4x12_UPHYPWR_PHY1_PWR | \
39 EXYNOS_4x12_UPHYPWR_PHY1_SLEEP)
41 #define EXYNOS_4x12_UPHYPWR_HSIC0_SUSPEND BIT(9)
42 #define EXYNOS_4x12_UPHYPWR_HSIC0_PWR BIT(10)
43 #define EXYNOS_4x12_UPHYPWR_HSIC0_SLEEP BIT(11)
44 #define EXYNOS_4x12_UPHYPWR_HSIC0 ( \
45 EXYNOS_4x12_UPHYPWR_HSIC0_SUSPEND | \
46 EXYNOS_4x12_UPHYPWR_HSIC0_PWR | \
47 EXYNOS_4x12_UPHYPWR_HSIC0_SLEEP)
49 #define EXYNOS_4x12_UPHYPWR_HSIC1_SUSPEND BIT(12)
50 #define EXYNOS_4x12_UPHYPWR_HSIC1_PWR BIT(13)
51 #define EXYNOS_4x12_UPHYPWR_HSIC1_SLEEP BIT(14)
52 #define EXYNOS_4x12_UPHYPWR_HSIC1 ( \
53 EXYNOS_4x12_UPHYPWR_HSIC1_SUSPEND | \
54 EXYNOS_4x12_UPHYPWR_HSIC1_PWR | \
55 EXYNOS_4x12_UPHYPWR_HSIC1_SLEEP)
57 /* PHY clock control */
58 #define EXYNOS_4x12_UPHYCLK 0x4
60 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK (0x7 << 0)
61 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET 0
62 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_9MHZ6 (0x0 << 0)
63 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_10MHZ (0x1 << 0)
64 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_12MHZ (0x2 << 0)
65 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_19MHZ2 (0x3 << 0)
66 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_20MHZ (0x4 << 0)
67 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ (0x5 << 0)
68 #define EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ (0x7 << 0)
70 #define EXYNOS_4x12_UPHYCLK_PHY0_ID_PULLUP BIT(3)
71 #define EXYNOS_4x12_UPHYCLK_PHY0_COMMON_ON BIT(4)
72 #define EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON BIT(7)
74 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_MASK (0x7f << 10)
75 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_OFFSET 10
76 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_12MHZ (0x24 << 10)
77 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_15MHZ (0x1c << 10)
78 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_16MHZ (0x1a << 10)
79 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_19MHZ2 (0x15 << 10)
80 #define EXYNOS_4x12_UPHYCLK_HSIC_REFCLK_20MHZ (0x14 << 10)
82 /* PHY reset control */
83 #define EXYNOS_4x12_UPHYRST 0x8
85 #define EXYNOS_4x12_URSTCON_PHY0 BIT(0)
86 #define EXYNOS_4x12_URSTCON_OTG_HLINK BIT(1)
87 #define EXYNOS_4x12_URSTCON_OTG_PHYLINK BIT(2)
88 #define EXYNOS_4x12_URSTCON_HOST_PHY BIT(3)
89 #define EXYNOS_4x12_URSTCON_PHY1 BIT(4)
90 #define EXYNOS_4x12_URSTCON_HSIC0 BIT(5)
91 #define EXYNOS_4x12_URSTCON_HSIC1 BIT(6)
92 #define EXYNOS_4x12_URSTCON_HOST_LINK_ALL BIT(7)
93 #define EXYNOS_4x12_URSTCON_HOST_LINK_P0 BIT(8)
94 #define EXYNOS_4x12_URSTCON_HOST_LINK_P1 BIT(9)
95 #define EXYNOS_4x12_URSTCON_HOST_LINK_P2 BIT(10)
97 /* Isolation, configured in the power management unit */
98 #define EXYNOS_4x12_USB_ISOL_OFFSET 0x704
99 #define EXYNOS_4x12_USB_ISOL_OTG BIT(0)
100 #define EXYNOS_4x12_USB_ISOL_HSIC0_OFFSET 0x708
101 #define EXYNOS_4x12_USB_ISOL_HSIC0 BIT(0)
102 #define EXYNOS_4x12_USB_ISOL_HSIC1_OFFSET 0x70c
103 #define EXYNOS_4x12_USB_ISOL_HSIC1 BIT(0)
105 /* Mode switching SUB Device <-> Host */
106 #define EXYNOS_4x12_MODE_SWITCH_OFFSET 0x21c
107 #define EXYNOS_4x12_MODE_SWITCH_MASK 1
108 #define EXYNOS_4x12_MODE_SWITCH_DEVICE 0
109 #define EXYNOS_4x12_MODE_SWITCH_HOST 1
111 enum exynos4x12_phy_id
{
120 * exynos4x12_rate_to_clk() converts the supplied clock rate to the value that
121 * can be written to the phy register.
123 static int exynos4x12_rate_to_clk(unsigned long rate
, u32
*reg
)
125 /* EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK */
129 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_9MHZ6
;
132 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_10MHZ
;
135 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_12MHZ
;
138 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_19MHZ2
;
141 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_20MHZ
;
144 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_24MHZ
;
147 *reg
= EXYNOS_4x12_UPHYCLK_PHYFSEL_50MHZ
;
156 static void exynos4x12_isol(struct samsung_usb2_phy_instance
*inst
, bool on
)
158 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
162 switch (inst
->cfg
->id
) {
163 case EXYNOS4x12_DEVICE
:
164 case EXYNOS4x12_HOST
:
165 offset
= EXYNOS_4x12_USB_ISOL_OFFSET
;
166 mask
= EXYNOS_4x12_USB_ISOL_OTG
;
168 case EXYNOS4x12_HSIC0
:
169 offset
= EXYNOS_4x12_USB_ISOL_HSIC0_OFFSET
;
170 mask
= EXYNOS_4x12_USB_ISOL_HSIC0
;
172 case EXYNOS4x12_HSIC1
:
173 offset
= EXYNOS_4x12_USB_ISOL_HSIC1_OFFSET
;
174 mask
= EXYNOS_4x12_USB_ISOL_HSIC1
;
180 regmap_update_bits(drv
->reg_pmu
, offset
, mask
, on
? 0 : mask
);
183 static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance
*inst
)
185 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
188 clk
= readl(drv
->reg_phy
+ EXYNOS_4x12_UPHYCLK
);
189 clk
&= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK
;
190 clk
|= drv
->ref_reg_val
<< EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET
;
191 writel(clk
, drv
->reg_phy
+ EXYNOS_4x12_UPHYCLK
);
194 static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance
*inst
, bool on
)
196 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
204 switch (inst
->cfg
->id
) {
205 case EXYNOS4x12_DEVICE
:
206 phypwr
= EXYNOS_4x12_UPHYPWR_PHY0
;
207 rstbits
= EXYNOS_4x12_URSTCON_PHY0
;
208 mode
= EXYNOS_4x12_MODE_SWITCH_DEVICE
;
211 case EXYNOS4x12_HOST
:
212 phypwr
= EXYNOS_4x12_UPHYPWR_PHY1
;
213 rstbits
= EXYNOS_4x12_URSTCON_HOST_PHY
;
214 mode
= EXYNOS_4x12_MODE_SWITCH_HOST
;
217 case EXYNOS4x12_HSIC0
:
218 phypwr
= EXYNOS_4x12_UPHYPWR_HSIC0
;
219 rstbits
= EXYNOS_4x12_URSTCON_HSIC1
|
220 EXYNOS_4x12_URSTCON_HOST_LINK_P0
|
221 EXYNOS_4x12_URSTCON_HOST_PHY
;
223 case EXYNOS4x12_HSIC1
:
224 phypwr
= EXYNOS_4x12_UPHYPWR_HSIC1
;
225 rstbits
= EXYNOS_4x12_URSTCON_HSIC1
|
226 EXYNOS_4x12_URSTCON_HOST_LINK_P1
;
232 regmap_update_bits(drv
->reg_sys
,
233 EXYNOS_4x12_MODE_SWITCH_OFFSET
,
234 EXYNOS_4x12_MODE_SWITCH_MASK
, mode
);
236 pwr
= readl(drv
->reg_phy
+ EXYNOS_4x12_UPHYPWR
);
238 writel(pwr
, drv
->reg_phy
+ EXYNOS_4x12_UPHYPWR
);
240 rst
= readl(drv
->reg_phy
+ EXYNOS_4x12_UPHYRST
);
242 writel(rst
, drv
->reg_phy
+ EXYNOS_4x12_UPHYRST
);
245 writel(rst
, drv
->reg_phy
+ EXYNOS_4x12_UPHYRST
);
246 /* The following delay is necessary for the reset sequence to be
250 pwr
= readl(drv
->reg_phy
+ EXYNOS_4x12_UPHYPWR
);
252 writel(pwr
, drv
->reg_phy
+ EXYNOS_4x12_UPHYPWR
);
256 static int exynos4x12_power_on(struct samsung_usb2_phy_instance
*inst
)
258 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
261 exynos4x12_setup_clk(inst
);
262 exynos4x12_phy_pwr(inst
, 1);
263 exynos4x12_isol(inst
, 0);
265 /* Power on the device, as it is necessary for HSIC to work */
266 if (inst
->cfg
->id
== EXYNOS4x12_HSIC0
) {
267 struct samsung_usb2_phy_instance
*device
=
268 &drv
->instances
[EXYNOS4x12_DEVICE
];
269 exynos4x12_phy_pwr(device
, 1);
270 exynos4x12_isol(device
, 0);
276 static int exynos4x12_power_off(struct samsung_usb2_phy_instance
*inst
)
278 struct samsung_usb2_phy_driver
*drv
= inst
->drv
;
279 struct samsung_usb2_phy_instance
*device
=
280 &drv
->instances
[EXYNOS4x12_DEVICE
];
283 exynos4x12_isol(inst
, 1);
284 exynos4x12_phy_pwr(inst
, 0);
286 if (inst
->cfg
->id
== EXYNOS4x12_HSIC0
&& !device
->enabled
) {
287 exynos4x12_isol(device
, 1);
288 exynos4x12_phy_pwr(device
, 0);
295 static const struct samsung_usb2_common_phy exynos4x12_phys
[] = {
298 .id
= EXYNOS4x12_DEVICE
,
299 .power_on
= exynos4x12_power_on
,
300 .power_off
= exynos4x12_power_off
,
304 .id
= EXYNOS4x12_HOST
,
305 .power_on
= exynos4x12_power_on
,
306 .power_off
= exynos4x12_power_off
,
310 .id
= EXYNOS4x12_HSIC0
,
311 .power_on
= exynos4x12_power_on
,
312 .power_off
= exynos4x12_power_off
,
316 .id
= EXYNOS4x12_HSIC1
,
317 .power_on
= exynos4x12_power_on
,
318 .power_off
= exynos4x12_power_off
,
323 const struct samsung_usb2_phy_config exynos4x12_usb2_phy_config
= {
324 .has_mode_switch
= 1,
325 .num_phys
= EXYNOS4x12_NUM_PHYS
,
326 .phys
= exynos4x12_phys
,
327 .rate_to_clk
= exynos4x12_rate_to_clk
,