1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Renesas R-Car Gen2 PHY driver
4 *
5 * Copyright (C) 2014 Renesas Solutions Corp.
6 * Copyright (C) 2014 Cogent Embedded, Inc.
7 * Copyright (C) 2019 Renesas Electronics Corp.
8 */
9
10 #include <linux/clk.h>
11 #include <linux/delay.h>
12 #include <linux/io.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/phy/phy.h>
16 #include <linux/platform_device.h>
17 #include <linux/spinlock.h>
18 #include <linux/atomic.h>
19
20 #define USBHS_LPSTS 0x02
21 #define USBHS_UGCTRL 0x80
22 #define USBHS_UGCTRL2 0x84
23 #define USBHS_UGSTS 0x88 /* From technical update */
24
25 /* Low Power Status register (LPSTS) */
26 #define USBHS_LPSTS_SUSPM 0x4000
27
28 /* USB General control register (UGCTRL) */
29 #define USBHS_UGCTRL_CONNECT 0x00000004
30 #define USBHS_UGCTRL_PLLRESET 0x00000001
31
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
41
42 /* USB General status register (UGSTS) */
43 #define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */
44
45 #define PHYS_PER_CHANNEL 2
46
47 struct rcar_gen2_phy {
48 struct phy *phy;
49 struct rcar_gen2_channel *channel;
50 int number;
51 u32 select_value;
52 };
53
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];
58 int selected_phy;
59 u32 select_mask;
60 };
61
62 struct rcar_gen2_phy_driver {
63 void __iomem *base;
64 struct clk *clk;
65 spinlock_t lock;
66 int num_channels;
67 struct rcar_gen2_channel *channels;
68 };
69
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;
74 };
75
rcar_gen2_phy_init(struct phy * p)76 static int rcar_gen2_phy_init(struct phy *p)
77 {
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;
81 unsigned long flags;
82 u32 ugctrl2;
83
84 /*
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.
89 */
90 if (cmpxchg(&channel->selected_phy, -1, phy->number) != -1)
91 return -EBUSY;
92
93 clk_prepare_enable(drv->clk);
94
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);
101 return 0;
102 }
103
rcar_gen2_phy_exit(struct phy * p)104 static int rcar_gen2_phy_exit(struct phy *p)
105 {
106 struct rcar_gen2_phy *phy = phy_get_drvdata(p);
107 struct rcar_gen2_channel *channel = phy->channel;
108
109 clk_disable_unprepare(channel->drv->clk);
110
111 channel->selected_phy = -1;
112
113 return 0;
114 }
115
rcar_gen2_phy_power_on(struct phy * p)116 static int rcar_gen2_phy_power_on(struct phy *p)
117 {
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;
121 unsigned long flags;
122 u32 value;
123 int err = 0, i;
124
125 /* Skip if it's not USBHS */
126 if (phy->select_value != USBHS_UGCTRL2_USB0SEL_HS_USB)
127 return 0;
128
129 spin_lock_irqsave(&drv->lock, flags);
130
131 /* Power on USBHS PHY */
132 value = readl(base + USBHS_UGCTRL);
133 value &= ~USBHS_UGCTRL_PLLRESET;
134 writel(value, base + USBHS_UGCTRL);
135
136 value = readw(base + USBHS_LPSTS);
137 value |= USBHS_LPSTS_SUSPM;
138 writew(value, base + USBHS_LPSTS);
139
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);
146 goto out;
147 }
148 udelay(1);
149 }
150
151 /* Timed out waiting for the PLL lock */
152 err = -ETIMEDOUT;
153
154 out:
155 spin_unlock_irqrestore(&drv->lock, flags);
156
157 return err;
158 }
159
rcar_gen2_phy_power_off(struct phy * p)160 static int rcar_gen2_phy_power_off(struct phy *p)
161 {
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;
165 unsigned long flags;
166 u32 value;
167
168 /* Skip if it's not USBHS */
169 if (phy->select_value != USBHS_UGCTRL2_USB0SEL_HS_USB)
170 return 0;
171
172 spin_lock_irqsave(&drv->lock, flags);
173
174 /* Power off USBHS PHY */
175 value = readl(base + USBHS_UGCTRL);
176 value &= ~USBHS_UGCTRL_CONNECT;
177 writel(value, base + USBHS_UGCTRL);
178
179 value = readw(base + USBHS_LPSTS);
180 value &= ~USBHS_LPSTS_SUSPM;
181 writew(value, base + USBHS_LPSTS);
182
183 value = readl(base + USBHS_UGCTRL);
184 value |= USBHS_UGCTRL_PLLRESET;
185 writel(value, base + USBHS_UGCTRL);
186
187 spin_unlock_irqrestore(&drv->lock, flags);
188
189 return 0;
190 }
191
rz_g1c_phy_power_on(struct phy * p)192 static int rz_g1c_phy_power_on(struct phy *p)
193 {
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;
197 unsigned long flags;
198 u32 value;
199
200 spin_lock_irqsave(&drv->lock, flags);
201
202 /* Power on USBHS PHY */
203 value = readl(base + USBHS_UGCTRL);
204 value &= ~USBHS_UGCTRL_PLLRESET;
205 writel(value, base + USBHS_UGCTRL);
206
207 /* As per the data sheet wait 340 micro sec for power stable */
208 udelay(340);
209
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);
214 }
215
216 spin_unlock_irqrestore(&drv->lock, flags);
217
218 return 0;
219 }
220
rz_g1c_phy_power_off(struct phy * p)221 static int rz_g1c_phy_power_off(struct phy *p)
222 {
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;
226 unsigned long flags;
227 u32 value;
228
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);
235 }
236
237 value = readl(base + USBHS_UGCTRL);
238 value |= USBHS_UGCTRL_PLLRESET;
239 writel(value, base + USBHS_UGCTRL);
240
241 spin_unlock_irqrestore(&drv->lock, flags);
242
243 return 0;
244 }
245
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,
252 };
253
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,
260 };
261
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 },
265 };
266
267 static const u32 usb20_select_value[][PHYS_PER_CHANNEL] = {
268 { USBHS_UGCTRL2_USB0SEL_USB20, USBHS_UGCTRL2_USB0SEL_HS_USB20 },
269 };
270
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),
275 };
276
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),
281 };
282
283 static const struct of_device_id rcar_gen2_phy_match_table[] = {
284 {
285 .compatible = "renesas,usb-phy-r8a77470",
286 .data = &rz_g1c_usb_phy_data,
287 },
288 {
289 .compatible = "renesas,usb-phy-r8a7790",
290 .data = &rcar_gen2_usb_phy_data,
291 },
292 {
293 .compatible = "renesas,usb-phy-r8a7791",
294 .data = &rcar_gen2_usb_phy_data,
295 },
296 {
297 .compatible = "renesas,usb-phy-r8a7794",
298 .data = &rcar_gen2_usb_phy_data,
299 },
300 {
301 .compatible = "renesas,rcar-gen2-usb-phy",
302 .data = &rcar_gen2_usb_phy_data,
303 },
304 { /* sentinel */ },
305 };
306 MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
307
rcar_gen2_phy_xlate(struct device * dev,struct of_phandle_args * args)308 static struct phy *rcar_gen2_phy_xlate(struct device *dev,
309 struct of_phandle_args *args)
310 {
311 struct rcar_gen2_phy_driver *drv;
312 struct device_node *np = args->np;
313 int i;
314
315 drv = dev_get_drvdata(dev);
316 if (!drv)
317 return ERR_PTR(-EINVAL);
318
319 for (i = 0; i < drv->num_channels; i++) {
320 if (np == drv->channels[i].of_node)
321 break;
322 }
323
324 if (i >= drv->num_channels || args->args[0] >= 2)
325 return ERR_PTR(-ENODEV);
326
327 return drv->channels[i].phys[args->args[0]].phy;
328 }
329
330 static const u32 select_mask[] = {
331 [0] = USBHS_UGCTRL2_USB0SEL,
332 [2] = USBHS_UGCTRL2_USB2SEL,
333 };
334
rcar_gen2_phy_probe(struct platform_device * pdev)335 static int rcar_gen2_phy_probe(struct platform_device *pdev)
336 {
337 struct device *dev = &pdev->dev;
338 struct rcar_gen2_phy_driver *drv;
339 struct phy_provider *provider;
340 struct device_node *np;
341 void __iomem *base;
342 struct clk *clk;
343 const struct rcar_gen2_phy_data *data;
344 int i = 0;
345
346 if (!dev->of_node) {
347 dev_err(dev,
348 "This driver is required to be instantiated from device tree\n");
349 return -EINVAL;
350 }
351
352 clk = devm_clk_get(dev, "usbhs");
353 if (IS_ERR(clk)) {
354 dev_err(dev, "Can't get USBHS clock\n");
355 return PTR_ERR(clk);
356 }
357
358 base = devm_platform_ioremap_resource(pdev, 0);
359 if (IS_ERR(base))
360 return PTR_ERR(base);
361
362 drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
363 if (!drv)
364 return -ENOMEM;
365
366 spin_lock_init(&drv->lock);
367
368 drv->clk = clk;
369 drv->base = base;
370
371 data = of_device_get_match_data(dev);
372 if (!data)
373 return -EINVAL;
374
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),
378 GFP_KERNEL);
379 if (!drv->channels)
380 return -ENOMEM;
381
382 for_each_child_of_node(dev->of_node, np) {
383 struct rcar_gen2_channel *channel = drv->channels + i;
384 u32 channel_num;
385 int error, n;
386
387 channel->of_node = np;
388 channel->drv = drv;
389 channel->selected_phy = -1;
390
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");
394 of_node_put(np);
395 return error;
396 }
397 channel->select_mask = select_mask[channel_num];
398
399 for (n = 0; n < PHYS_PER_CHANNEL; n++) {
400 struct rcar_gen2_phy *phy = &channel->phys[n];
401
402 phy->channel = channel;
403 phy->number = n;
404 phy->select_value = data->select_value[channel_num][n];
405
406 phy->phy = devm_phy_create(dev, NULL,
407 data->gen2_phy_ops);
408 if (IS_ERR(phy->phy)) {
409 dev_err(dev, "Failed to create PHY\n");
410 of_node_put(np);
411 return PTR_ERR(phy->phy);
412 }
413 phy_set_drvdata(phy->phy, phy);
414 }
415
416 i++;
417 }
418
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);
423 }
424
425 dev_set_drvdata(dev, drv);
426
427 return 0;
428 }
429
430 static struct platform_driver rcar_gen2_phy_driver = {
431 .driver = {
432 .name = "phy_rcar_gen2",
433 .of_match_table = rcar_gen2_phy_match_table,
434 },
435 .probe = rcar_gen2_phy_probe,
436 };
437
438 module_platform_driver(rcar_gen2_phy_driver);
439
440 MODULE_LICENSE("GPL v2");
441 MODULE_DESCRIPTION("Renesas R-Car Gen2 PHY");
442 MODULE_AUTHOR("Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>");
443