1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas R-Car Gen2 PHY driver
5 * Copyright (C) 2014 Renesas Solutions Corp.
6 * Copyright (C) 2014 Cogent Embedded, Inc.
7 * Copyright (C) 2019 Renesas Electronics Corp.
10 #include <linux/clk.h>
11 #include <linux/delay.h>
13 #include <linux/module.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/spinlock.h>
18 #include <linux/atomic.h>
20 #define USBHS_LPSTS 0x02
21 #define USBHS_UGCTRL 0x80
22 #define USBHS_UGCTRL2 0x84
23 #define USBHS_UGSTS 0x88 /* From technical update */
25 /* Low Power Status register (LPSTS) */
26 #define USBHS_LPSTS_SUSPM 0x4000
28 /* USB General control register (UGCTRL) */
29 #define USBHS_UGCTRL_CONNECT 0x00000004
30 #define USBHS_UGCTRL_PLLRESET 0x00000001
32 /* USB General control register 2 (UGCTRL2) */
33 #define USBHS_UGCTRL2_USB2SEL 0x80000000
34 #define USBHS_UGCTRL2_USB2SEL_PCI 0x00000000
35 #define USBHS_UGCTRL2_USB2SEL_USB30 0x80000000
36 #define USBHS_UGCTRL2_USB0SEL 0x00000030
37 #define USBHS_UGCTRL2_USB0SEL_PCI 0x00000010
38 #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030
39 #define USBHS_UGCTRL2_USB0SEL_USB20 0x00000010
40 #define USBHS_UGCTRL2_USB0SEL_HS_USB20 0x00000020
42 /* USB General status register (UGSTS) */
43 #define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */
45 #define PHYS_PER_CHANNEL 2
47 struct rcar_gen2_phy
{
49 struct rcar_gen2_channel
*channel
;
54 struct rcar_gen2_channel
{
55 struct device_node
*of_node
;
56 struct rcar_gen2_phy_driver
*drv
;
57 struct rcar_gen2_phy phys
[PHYS_PER_CHANNEL
];
62 struct rcar_gen2_phy_driver
{
67 struct rcar_gen2_channel
*channels
;
70 struct rcar_gen2_phy_data
{
71 const struct phy_ops
*gen2_phy_ops
;
72 const u32 (*select_value
)[PHYS_PER_CHANNEL
];
73 const u32 num_channels
;
76 static int rcar_gen2_phy_init(struct phy
*p
)
78 struct rcar_gen2_phy
*phy
= phy_get_drvdata(p
);
79 struct rcar_gen2_channel
*channel
= phy
->channel
;
80 struct rcar_gen2_phy_driver
*drv
= channel
->drv
;
85 * Try to acquire exclusive access to PHY. The first driver calling
86 * phy_init() on a given channel wins, and all attempts to use another
87 * PHY on this channel will fail until phy_exit() is called by the first
88 * driver. Achieving this with cmpxcgh() should be SMP-safe.
90 if (cmpxchg(&channel
->selected_phy
, -1, phy
->number
) != -1)
93 clk_prepare_enable(drv
->clk
);
95 spin_lock_irqsave(&drv
->lock
, flags
);
96 ugctrl2
= readl(drv
->base
+ USBHS_UGCTRL2
);
97 ugctrl2
&= ~channel
->select_mask
;
98 ugctrl2
|= phy
->select_value
;
99 writel(ugctrl2
, drv
->base
+ USBHS_UGCTRL2
);
100 spin_unlock_irqrestore(&drv
->lock
, flags
);
104 static int rcar_gen2_phy_exit(struct phy
*p
)
106 struct rcar_gen2_phy
*phy
= phy_get_drvdata(p
);
107 struct rcar_gen2_channel
*channel
= phy
->channel
;
109 clk_disable_unprepare(channel
->drv
->clk
);
111 channel
->selected_phy
= -1;
116 static int rcar_gen2_phy_power_on(struct phy
*p
)
118 struct rcar_gen2_phy
*phy
= phy_get_drvdata(p
);
119 struct rcar_gen2_phy_driver
*drv
= phy
->channel
->drv
;
120 void __iomem
*base
= drv
->base
;
125 /* Skip if it's not USBHS */
126 if (phy
->select_value
!= USBHS_UGCTRL2_USB0SEL_HS_USB
)
129 spin_lock_irqsave(&drv
->lock
, flags
);
131 /* Power on USBHS PHY */
132 value
= readl(base
+ USBHS_UGCTRL
);
133 value
&= ~USBHS_UGCTRL_PLLRESET
;
134 writel(value
, base
+ USBHS_UGCTRL
);
136 value
= readw(base
+ USBHS_LPSTS
);
137 value
|= USBHS_LPSTS_SUSPM
;
138 writew(value
, base
+ USBHS_LPSTS
);
140 for (i
= 0; i
< 20; i
++) {
141 value
= readl(base
+ USBHS_UGSTS
);
142 if ((value
& USBHS_UGSTS_LOCK
) == USBHS_UGSTS_LOCK
) {
143 value
= readl(base
+ USBHS_UGCTRL
);
144 value
|= USBHS_UGCTRL_CONNECT
;
145 writel(value
, base
+ USBHS_UGCTRL
);
151 /* Timed out waiting for the PLL lock */
155 spin_unlock_irqrestore(&drv
->lock
, flags
);
160 static int rcar_gen2_phy_power_off(struct phy
*p
)
162 struct rcar_gen2_phy
*phy
= phy_get_drvdata(p
);
163 struct rcar_gen2_phy_driver
*drv
= phy
->channel
->drv
;
164 void __iomem
*base
= drv
->base
;
168 /* Skip if it's not USBHS */
169 if (phy
->select_value
!= USBHS_UGCTRL2_USB0SEL_HS_USB
)
172 spin_lock_irqsave(&drv
->lock
, flags
);
174 /* Power off USBHS PHY */
175 value
= readl(base
+ USBHS_UGCTRL
);
176 value
&= ~USBHS_UGCTRL_CONNECT
;
177 writel(value
, base
+ USBHS_UGCTRL
);
179 value
= readw(base
+ USBHS_LPSTS
);
180 value
&= ~USBHS_LPSTS_SUSPM
;
181 writew(value
, base
+ USBHS_LPSTS
);
183 value
= readl(base
+ USBHS_UGCTRL
);
184 value
|= USBHS_UGCTRL_PLLRESET
;
185 writel(value
, base
+ USBHS_UGCTRL
);
187 spin_unlock_irqrestore(&drv
->lock
, flags
);
192 static int rz_g1c_phy_power_on(struct phy
*p
)
194 struct rcar_gen2_phy
*phy
= phy_get_drvdata(p
);
195 struct rcar_gen2_phy_driver
*drv
= phy
->channel
->drv
;
196 void __iomem
*base
= drv
->base
;
200 spin_lock_irqsave(&drv
->lock
, flags
);
202 /* Power on USBHS PHY */
203 value
= readl(base
+ USBHS_UGCTRL
);
204 value
&= ~USBHS_UGCTRL_PLLRESET
;
205 writel(value
, base
+ USBHS_UGCTRL
);
207 /* As per the data sheet wait 340 micro sec for power stable */
210 if (phy
->select_value
== USBHS_UGCTRL2_USB0SEL_HS_USB20
) {
211 value
= readw(base
+ USBHS_LPSTS
);
212 value
|= USBHS_LPSTS_SUSPM
;
213 writew(value
, base
+ USBHS_LPSTS
);
216 spin_unlock_irqrestore(&drv
->lock
, flags
);
221 static int rz_g1c_phy_power_off(struct phy
*p
)
223 struct rcar_gen2_phy
*phy
= phy_get_drvdata(p
);
224 struct rcar_gen2_phy_driver
*drv
= phy
->channel
->drv
;
225 void __iomem
*base
= drv
->base
;
229 spin_lock_irqsave(&drv
->lock
, flags
);
230 /* Power off USBHS PHY */
231 if (phy
->select_value
== USBHS_UGCTRL2_USB0SEL_HS_USB20
) {
232 value
= readw(base
+ USBHS_LPSTS
);
233 value
&= ~USBHS_LPSTS_SUSPM
;
234 writew(value
, base
+ USBHS_LPSTS
);
237 value
= readl(base
+ USBHS_UGCTRL
);
238 value
|= USBHS_UGCTRL_PLLRESET
;
239 writel(value
, base
+ USBHS_UGCTRL
);
241 spin_unlock_irqrestore(&drv
->lock
, flags
);
246 static const struct phy_ops rcar_gen2_phy_ops
= {
247 .init
= rcar_gen2_phy_init
,
248 .exit
= rcar_gen2_phy_exit
,
249 .power_on
= rcar_gen2_phy_power_on
,
250 .power_off
= rcar_gen2_phy_power_off
,
251 .owner
= THIS_MODULE
,
254 static const struct phy_ops rz_g1c_phy_ops
= {
255 .init
= rcar_gen2_phy_init
,
256 .exit
= rcar_gen2_phy_exit
,
257 .power_on
= rz_g1c_phy_power_on
,
258 .power_off
= rz_g1c_phy_power_off
,
259 .owner
= THIS_MODULE
,
262 static const u32 pci_select_value
[][PHYS_PER_CHANNEL
] = {
263 [0] = { USBHS_UGCTRL2_USB0SEL_PCI
, USBHS_UGCTRL2_USB0SEL_HS_USB
},
264 [2] = { USBHS_UGCTRL2_USB2SEL_PCI
, USBHS_UGCTRL2_USB2SEL_USB30
},
267 static const u32 usb20_select_value
[][PHYS_PER_CHANNEL
] = {
268 { USBHS_UGCTRL2_USB0SEL_USB20
, USBHS_UGCTRL2_USB0SEL_HS_USB20
},
271 static const struct rcar_gen2_phy_data rcar_gen2_usb_phy_data
= {
272 .gen2_phy_ops
= &rcar_gen2_phy_ops
,
273 .select_value
= pci_select_value
,
274 .num_channels
= ARRAY_SIZE(pci_select_value
),
277 static const struct rcar_gen2_phy_data rz_g1c_usb_phy_data
= {
278 .gen2_phy_ops
= &rz_g1c_phy_ops
,
279 .select_value
= usb20_select_value
,
280 .num_channels
= ARRAY_SIZE(usb20_select_value
),
283 static const struct of_device_id rcar_gen2_phy_match_table
[] = {
285 .compatible
= "renesas,usb-phy-r8a77470",
286 .data
= &rz_g1c_usb_phy_data
,
289 .compatible
= "renesas,usb-phy-r8a7790",
290 .data
= &rcar_gen2_usb_phy_data
,
293 .compatible
= "renesas,usb-phy-r8a7791",
294 .data
= &rcar_gen2_usb_phy_data
,
297 .compatible
= "renesas,usb-phy-r8a7794",
298 .data
= &rcar_gen2_usb_phy_data
,
301 .compatible
= "renesas,rcar-gen2-usb-phy",
302 .data
= &rcar_gen2_usb_phy_data
,
306 MODULE_DEVICE_TABLE(of
, rcar_gen2_phy_match_table
);
308 static struct phy
*rcar_gen2_phy_xlate(struct device
*dev
,
309 const struct of_phandle_args
*args
)
311 struct rcar_gen2_phy_driver
*drv
;
312 struct device_node
*np
= args
->np
;
315 drv
= dev_get_drvdata(dev
);
317 return ERR_PTR(-EINVAL
);
319 for (i
= 0; i
< drv
->num_channels
; i
++) {
320 if (np
== drv
->channels
[i
].of_node
)
324 if (i
>= drv
->num_channels
|| args
->args
[0] >= 2)
325 return ERR_PTR(-ENODEV
);
327 return drv
->channels
[i
].phys
[args
->args
[0]].phy
;
330 static const u32 select_mask
[] = {
331 [0] = USBHS_UGCTRL2_USB0SEL
,
332 [2] = USBHS_UGCTRL2_USB2SEL
,
335 static int rcar_gen2_phy_probe(struct platform_device
*pdev
)
337 struct device
*dev
= &pdev
->dev
;
338 struct rcar_gen2_phy_driver
*drv
;
339 struct phy_provider
*provider
;
340 struct device_node
*np
;
343 const struct rcar_gen2_phy_data
*data
;
348 "This driver is required to be instantiated from device tree\n");
352 clk
= devm_clk_get(dev
, "usbhs");
354 dev_err(dev
, "Can't get USBHS clock\n");
358 base
= devm_platform_ioremap_resource(pdev
, 0);
360 return PTR_ERR(base
);
362 drv
= devm_kzalloc(dev
, sizeof(*drv
), GFP_KERNEL
);
366 spin_lock_init(&drv
->lock
);
371 data
= of_device_get_match_data(dev
);
375 drv
->num_channels
= of_get_child_count(dev
->of_node
);
376 drv
->channels
= devm_kcalloc(dev
, drv
->num_channels
,
377 sizeof(struct rcar_gen2_channel
),
382 for_each_child_of_node(dev
->of_node
, np
) {
383 struct rcar_gen2_channel
*channel
= drv
->channels
+ i
;
387 channel
->of_node
= np
;
389 channel
->selected_phy
= -1;
391 error
= of_property_read_u32(np
, "reg", &channel_num
);
392 if (error
|| channel_num
>= data
->num_channels
) {
393 dev_err(dev
, "Invalid \"reg\" property\n");
397 channel
->select_mask
= select_mask
[channel_num
];
399 for (n
= 0; n
< PHYS_PER_CHANNEL
; n
++) {
400 struct rcar_gen2_phy
*phy
= &channel
->phys
[n
];
402 phy
->channel
= channel
;
404 phy
->select_value
= data
->select_value
[channel_num
][n
];
406 phy
->phy
= devm_phy_create(dev
, NULL
,
408 if (IS_ERR(phy
->phy
)) {
409 dev_err(dev
, "Failed to create PHY\n");
411 return PTR_ERR(phy
->phy
);
413 phy_set_drvdata(phy
->phy
, phy
);
419 provider
= devm_of_phy_provider_register(dev
, rcar_gen2_phy_xlate
);
420 if (IS_ERR(provider
)) {
421 dev_err(dev
, "Failed to register PHY provider\n");
422 return PTR_ERR(provider
);
425 dev_set_drvdata(dev
, drv
);
430 static struct platform_driver rcar_gen2_phy_driver
= {
432 .name
= "phy_rcar_gen2",
433 .of_match_table
= rcar_gen2_phy_match_table
,
435 .probe
= rcar_gen2_phy_probe
,
438 module_platform_driver(rcar_gen2_phy_driver
);
440 MODULE_LICENSE("GPL v2");
441 MODULE_DESCRIPTION("Renesas R-Car Gen2 PHY");
442 MODULE_AUTHOR("Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>");