]>
Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: GPL-2.0 |
de18757e YS |
2 | /* |
3 | * Renesas USB driver R-Car Gen. 3 initialization and power control | |
4 | * | |
5 | * Copyright (C) 2016 Renesas Electronics Corporation | |
de18757e YS |
6 | */ |
7 | ||
b7603239 | 8 | #include <linux/delay.h> |
de18757e YS |
9 | #include <linux/io.h> |
10 | #include "common.h" | |
11 | #include "rcar3.h" | |
12 | ||
13 | #define LPSTS 0x102 | |
0f38672c | 14 | #define UGCTRL 0x180 /* 32-bit register */ |
de18757e | 15 | #define UGCTRL2 0x184 /* 32-bit register */ |
0f38672c | 16 | #define UGSTS 0x188 /* 32-bit register */ |
de18757e YS |
17 | |
18 | /* Low Power Status register (LPSTS) */ | |
19 | #define LPSTS_SUSPM 0x4000 | |
20 | ||
0f38672c YS |
21 | /* R-Car D3 only: USB General control register (UGCTRL) */ |
22 | #define UGCTRL_PLLRESET 0x00000001 | |
23 | #define UGCTRL_CONNECT 0x00000004 | |
24 | ||
2acecd58 YS |
25 | /* |
26 | * USB General control register 2 (UGCTRL2) | |
27 | * Remarks: bit[31:11] and bit[9:6] should be 0 | |
28 | */ | |
de18757e | 29 | #define UGCTRL2_RESERVED_3 0x00000001 /* bit[3:0] should be B'0001 */ |
0f38672c | 30 | #define UGCTRL2_USB0SEL_HSUSB 0x00000020 |
de18757e | 31 | #define UGCTRL2_USB0SEL_OTG 0x00000030 |
2acecd58 | 32 | #define UGCTRL2_VBUSSEL 0x00000400 |
de18757e | 33 | |
0f38672c YS |
34 | /* R-Car D3 only: USB General status register (UGSTS) */ |
35 | #define UGSTS_LOCK 0x00000100 | |
36 | ||
107a4b53 | 37 | static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data) |
de18757e YS |
38 | { |
39 | iowrite32(data, priv->base + reg); | |
40 | } | |
41 | ||
0f38672c YS |
42 | static u32 usbhs_read32(struct usbhs_priv *priv, u32 reg) |
43 | { | |
44 | return ioread32(priv->base + reg); | |
45 | } | |
46 | ||
05e37b62 YS |
47 | static void usbhs_rcar3_set_ugctrl2(struct usbhs_priv *priv, u32 val) |
48 | { | |
49 | usbhs_write32(priv, UGCTRL2, val | UGCTRL2_RESERVED_3); | |
50 | } | |
51 | ||
de18757e YS |
52 | static int usbhs_rcar3_power_ctrl(struct platform_device *pdev, |
53 | void __iomem *base, int enable) | |
54 | { | |
55 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | |
56 | ||
05e37b62 | 57 | usbhs_rcar3_set_ugctrl2(priv, UGCTRL2_USB0SEL_OTG | UGCTRL2_VBUSSEL); |
de18757e | 58 | |
b7603239 | 59 | if (enable) { |
de18757e | 60 | usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM); |
b7603239 YS |
61 | /* The controller on R-Car Gen3 needs to wait up to 45 usec */ |
62 | udelay(45); | |
63 | } else { | |
de18757e | 64 | usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0); |
b7603239 | 65 | } |
de18757e YS |
66 | |
67 | return 0; | |
68 | } | |
69 | ||
0f38672c YS |
70 | /* R-Car D3 needs to release UGCTRL.PLLRESET */ |
71 | static int usbhs_rcar3_power_and_pll_ctrl(struct platform_device *pdev, | |
72 | void __iomem *base, int enable) | |
73 | { | |
74 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | |
75 | u32 val; | |
76 | int timeout = 1000; | |
77 | ||
78 | if (enable) { | |
79 | usbhs_write32(priv, UGCTRL, 0); /* release PLLRESET */ | |
6b983aca YS |
80 | usbhs_rcar3_set_ugctrl2(priv, |
81 | UGCTRL2_USB0SEL_OTG | UGCTRL2_VBUSSEL); | |
0f38672c YS |
82 | |
83 | usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM); | |
84 | do { | |
85 | val = usbhs_read32(priv, UGSTS); | |
86 | udelay(1); | |
87 | } while (!(val & UGSTS_LOCK) && timeout--); | |
88 | usbhs_write32(priv, UGCTRL, UGCTRL_CONNECT); | |
89 | } else { | |
90 | usbhs_write32(priv, UGCTRL, 0); | |
91 | usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0); | |
92 | usbhs_write32(priv, UGCTRL, UGCTRL_PLLRESET); | |
93 | } | |
94 | ||
95 | return 0; | |
96 | } | |
97 | ||
de18757e YS |
98 | static int usbhs_rcar3_get_id(struct platform_device *pdev) |
99 | { | |
100 | return USBHS_GADGET; | |
101 | } | |
102 | ||
103 | const struct renesas_usbhs_platform_callback usbhs_rcar3_ops = { | |
104 | .power_ctrl = usbhs_rcar3_power_ctrl, | |
105 | .get_id = usbhs_rcar3_get_id, | |
106 | }; | |
0f38672c YS |
107 | |
108 | const struct renesas_usbhs_platform_callback usbhs_rcar3_with_pll_ops = { | |
109 | .power_ctrl = usbhs_rcar3_power_and_pll_ctrl, | |
110 | .get_id = usbhs_rcar3_get_id, | |
111 | }; |