aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>2015-11-29 20:44:31 -0500
committerKishon Vijay Abraham I <kishon@ti.com>2015-12-20 04:51:37 -0500
commit1114e2d3173190be3e7339449c45ef11302d905a (patch)
treea377620c97fa9ce3a7f27ee0c55141a0e7af8d9d /drivers/phy
parentf3b5a8d9b50d71b8c9fb72aa9c8ea948ad1a4ef9 (diff)
phy: rcar-gen3-usb2: change the mode to OTG on the combined channel
To use the channel 0 of R-Car gen3 as periperal mode, This patch changes the mode to OTG instead of HOST. Then, this driver needs to set some registers to enable host mode and detects ID pin and VBUS pin at phy_init() timing. For now, the channel 0 can be used as host mode only. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-rcar-gen3-usb2.c124
1 files changed, 122 insertions, 2 deletions
diff --git a/drivers/phy/phy-rcar-gen3-usb2.c b/drivers/phy/phy-rcar-gen3-usb2.c
index 269615228b1b..2b5d890554ad 100644
--- a/drivers/phy/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/phy-rcar-gen3-usb2.c
@@ -24,6 +24,10 @@
24#define USB2_USBCTR 0x00c 24#define USB2_USBCTR 0x00c
25#define USB2_SPD_RSM_TIMSET 0x10c 25#define USB2_SPD_RSM_TIMSET 0x10c
26#define USB2_OC_TIMSET 0x110 26#define USB2_OC_TIMSET 0x110
27#define USB2_COMMCTRL 0x600
28#define USB2_VBCTRL 0x60c
29#define USB2_LINECTRL1 0x610
30#define USB2_ADPCTRL 0x630
27 31
28/* INT_ENABLE */ 32/* INT_ENABLE */
29#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) 33#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2)
@@ -41,6 +45,24 @@
41/* OC_TIMSET */ 45/* OC_TIMSET */
42#define USB2_OC_TIMSET_INIT 0x000209ab 46#define USB2_OC_TIMSET_INIT 0x000209ab
43 47
48/* COMMCTRL */
49#define USB2_COMMCTRL_OTG_PERI BIT(31) /* 1 = Peripheral mode */
50
51/* VBCTRL */
52#define USB2_VBCTRL_DRVVBUSSEL BIT(8)
53
54/* LINECTRL1 */
55#define USB2_LINECTRL1_DPRPD_EN BIT(19)
56#define USB2_LINECTRL1_DP_RPD BIT(18)
57#define USB2_LINECTRL1_DMRPD_EN BIT(17)
58#define USB2_LINECTRL1_DM_RPD BIT(16)
59
60/* ADPCTRL */
61#define USB2_ADPCTRL_OTGSESSVLD BIT(20)
62#define USB2_ADPCTRL_IDDIG BIT(19)
63#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */
64#define USB2_ADPCTRL_DRVVBUS BIT(4)
65
44/******* HSUSB registers (original offset is +0x100) *******/ 66/******* HSUSB registers (original offset is +0x100) *******/
45#define HSUSB_LPSTS 0x02 67#define HSUSB_LPSTS 0x02
46#define HSUSB_UGCTRL2 0x84 68#define HSUSB_UGCTRL2 0x84
@@ -66,6 +88,102 @@ struct rcar_gen3_chan {
66 struct phy *phy; 88 struct phy *phy;
67}; 89};
68 90
91static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
92{
93 void __iomem *usb2_base = ch->usb2.base;
94 u32 val = readl(usb2_base + USB2_COMMCTRL);
95
96 dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, host);
97 if (host)
98 val &= ~USB2_COMMCTRL_OTG_PERI;
99 else
100 val |= USB2_COMMCTRL_OTG_PERI;
101 writel(val, usb2_base + USB2_COMMCTRL);
102}
103
104static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
105{
106 void __iomem *usb2_base = ch->usb2.base;
107 u32 val = readl(usb2_base + USB2_LINECTRL1);
108
109 dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm);
110 val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
111 if (dp)
112 val |= USB2_LINECTRL1_DP_RPD;
113 if (dm)
114 val |= USB2_LINECTRL1_DM_RPD;
115 writel(val, usb2_base + USB2_LINECTRL1);
116}
117
118static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
119{
120 void __iomem *usb2_base = ch->usb2.base;
121 u32 val = readl(usb2_base + USB2_ADPCTRL);
122
123 dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, vbus);
124 if (vbus)
125 val |= USB2_ADPCTRL_DRVVBUS;
126 else
127 val &= ~USB2_ADPCTRL_DRVVBUS;
128 writel(val, usb2_base + USB2_ADPCTRL);
129}
130
131static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
132{
133 rcar_gen3_set_linectrl(ch, 1, 1);
134 rcar_gen3_set_host_mode(ch, 1);
135 rcar_gen3_enable_vbus_ctrl(ch, 1);
136}
137
138static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
139{
140 rcar_gen3_set_linectrl(ch, 0, 1);
141 rcar_gen3_set_host_mode(ch, 0);
142 rcar_gen3_enable_vbus_ctrl(ch, 0);
143}
144
145static bool rcar_gen3_check_vbus(struct rcar_gen3_chan *ch)
146{
147 return !!(readl(ch->usb2.base + USB2_ADPCTRL) &
148 USB2_ADPCTRL_OTGSESSVLD);
149}
150
151static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
152{
153 return !!(readl(ch->usb2.base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
154}
155
156static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
157{
158 bool is_host = true;
159
160 /* B-device? */
161 if (rcar_gen3_check_id(ch) && rcar_gen3_check_vbus(ch))
162 is_host = false;
163
164 if (is_host)
165 rcar_gen3_init_for_host(ch);
166 else
167 rcar_gen3_init_for_peri(ch);
168}
169
170static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
171{
172 void __iomem *usb2_base = ch->usb2.base;
173 u32 val;
174
175 val = readl(usb2_base + USB2_VBCTRL);
176 writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
177 val = readl(usb2_base + USB2_ADPCTRL);
178 writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
179 val = readl(usb2_base + USB2_LINECTRL1);
180 rcar_gen3_set_linectrl(ch, 0, 0);
181 writel(val | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN,
182 usb2_base + USB2_LINECTRL1);
183
184 rcar_gen3_device_recognition(ch);
185}
186
69static int rcar_gen3_phy_usb2_init(struct phy *p) 187static int rcar_gen3_phy_usb2_init(struct phy *p)
70{ 188{
71 struct rcar_gen3_chan *channel = phy_get_drvdata(p); 189 struct rcar_gen3_chan *channel = phy_get_drvdata(p);
@@ -80,11 +198,13 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
80 198
81 /* Initialize HSUSB part */ 199 /* Initialize HSUSB part */
82 if (hsusb_base) { 200 if (hsusb_base) {
83 /* TODO: support "OTG" mode */
84 val = readl(hsusb_base + HSUSB_UGCTRL2); 201 val = readl(hsusb_base + HSUSB_UGCTRL2);
85 val = (val & ~HSUSB_UGCTRL2_USB0SEL) | 202 val = (val & ~HSUSB_UGCTRL2_USB0SEL) |
86 HSUSB_UGCTRL2_USB0SEL_HOST; 203 HSUSB_UGCTRL2_USB0SEL_OTG;
87 writel(val & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2); 204 writel(val & HSUSB_UGCTRL2_MASK, hsusb_base + HSUSB_UGCTRL2);
205
206 /* Initialize otg part */
207 rcar_gen3_init_otg(channel);
88 } 208 }
89 209
90 return 0; 210 return 0;