2 * Renesas R-Car USB phy driver
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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/usb/otg.h>
15 #include <linux/platform_device.h>
16 #include <linux/spinlock.h>
17 #include <linux/module.h>
19 /* USBH common register */
20 #define USBPCTRL0 0x0800
21 #define USBPCTRL1 0x0804
25 #define USBCTL0 0x0858
30 #define PHY_RST (1 << 2)
31 #define PLL_ENB (1 << 1)
32 #define PHY_ENB (1 << 0)
35 #define ST_ACT (1 << 31)
36 #define ST_PLL (1 << 30)
38 struct rcar_usb_phy_priv
{
47 #define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy)
51 * USB initial/install operation.
53 * This function setup USB phy.
54 * The used value and setting order came from
55 * [USB :: Initial setting] on datasheet.
57 static int rcar_usb_phy_init(struct usb_phy
*phy
)
59 struct rcar_usb_phy_priv
*priv
= usb_phy_to_priv(phy
);
60 struct device
*dev
= phy
->dev
;
61 void __iomem
*reg0
= priv
->reg0
;
62 void __iomem
*reg1
= priv
->reg1
;
67 spin_lock_irqsave(&priv
->lock
, flags
);
68 if (priv
->counter
++ == 0) {
74 /* (1) USB-PHY standby release */
75 iowrite32(PHY_ENB
, (reg0
+ USBPCTRL1
));
77 /* (2) start USB-PHY internal PLL */
78 iowrite32(PHY_ENB
| PLL_ENB
, (reg0
+ USBPCTRL1
));
80 /* (3) USB module status check */
81 for (i
= 0; i
< 1024; i
++) {
83 val
= ioread32(reg0
+ USBST
);
84 if (val
== (ST_ACT
| ST_PLL
))
88 if (val
!= (ST_ACT
| ST_PLL
)) {
89 dev_err(dev
, "USB phy not ready\n");
93 /* (4) USB-PHY reset clear */
94 iowrite32(PHY_ENB
| PLL_ENB
| PHY_RST
, (reg0
+ USBPCTRL1
));
96 /* set platform specific port settings */
97 iowrite32(0x00000000, (reg0
+ USBPCTRL0
));
100 * EHCI IP internal buffer setting
101 * EHCI IP internal buffer enable
103 * These are recommended value of a datasheet
104 * see [USB :: EHCI internal buffer setting]
106 iowrite32(0x00ff0040, (reg0
+ EIIBC1
));
107 iowrite32(0x00ff0040, (reg1
+ EIIBC1
));
109 iowrite32(0x00000001, (reg0
+ EIIBC2
));
110 iowrite32(0x00000001, (reg1
+ EIIBC2
));
113 * Bus alignment settings
116 /* (1) EHCI bus alignment (little endian) */
117 iowrite32(0x00000000, (reg0
+ USBEH0
));
119 /* (1) OHCI bus alignment (little endian) */
120 iowrite32(0x00000000, (reg0
+ USBOH0
));
124 spin_unlock_irqrestore(&priv
->lock
, flags
);
129 static void rcar_usb_phy_shutdown(struct usb_phy
*phy
)
131 struct rcar_usb_phy_priv
*priv
= usb_phy_to_priv(phy
);
132 void __iomem
*reg0
= priv
->reg0
;
135 spin_lock_irqsave(&priv
->lock
, flags
);
137 if (priv
->counter
-- == 1) { /* last user */
138 iowrite32(0x00000000, (reg0
+ USBPCTRL0
));
139 iowrite32(0x00000000, (reg0
+ USBPCTRL1
));
142 spin_unlock_irqrestore(&priv
->lock
, flags
);
145 static int rcar_usb_phy_probe(struct platform_device
*pdev
)
147 struct rcar_usb_phy_priv
*priv
;
148 struct resource
*res0
, *res1
;
149 struct device
*dev
= &pdev
->dev
;
150 void __iomem
*reg0
, *reg1
;
153 res0
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
154 res1
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
155 if (!res0
|| !res1
) {
156 dev_err(dev
, "Not enough platform resources\n");
163 * Because this phy address is also mapped under OHCI/EHCI address area,
164 * this driver can't use devm_request_and_ioremap(dev, res) here
166 reg0
= devm_ioremap_nocache(dev
, res0
->start
, resource_size(res0
));
167 reg1
= devm_ioremap_nocache(dev
, res1
->start
, resource_size(res1
));
168 if (!reg0
|| !reg1
) {
169 dev_err(dev
, "ioremap error\n");
173 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
175 dev_err(dev
, "priv data allocation error\n");
183 priv
->phy
.label
= dev_name(dev
);
184 priv
->phy
.init
= rcar_usb_phy_init
;
185 priv
->phy
.shutdown
= rcar_usb_phy_shutdown
;
186 spin_lock_init(&priv
->lock
);
188 ret
= usb_add_phy(&priv
->phy
, USB_PHY_TYPE_USB2
);
190 dev_err(dev
, "usb phy addition error\n");
194 platform_set_drvdata(pdev
, priv
);
199 static int rcar_usb_phy_remove(struct platform_device
*pdev
)
201 struct rcar_usb_phy_priv
*priv
= platform_get_drvdata(pdev
);
203 usb_remove_phy(&priv
->phy
);
208 static struct platform_driver rcar_usb_phy_driver
= {
210 .name
= "rcar_usb_phy",
212 .probe
= rcar_usb_phy_probe
,
213 .remove
= rcar_usb_phy_remove
,
216 module_platform_driver(rcar_usb_phy_driver
);
218 MODULE_LICENSE("GPL v2");
219 MODULE_DESCRIPTION("Renesas R-Car USB phy");
220 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");