]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - drivers/phy/renesas/phy-rcar-gen2.c
8dc5710d9c9876195de4efc8e454afa0e2c8acaf
[mirror_ubuntu-focal-kernel.git] / drivers / phy / renesas / phy-rcar-gen2.c
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 #include <linux/of_device.h>
20
21 #define USBHS_LPSTS 0x02
22 #define USBHS_UGCTRL 0x80
23 #define USBHS_UGCTRL2 0x84
24 #define USBHS_UGSTS 0x88 /* From technical update */
25
26 /* Low Power Status register (LPSTS) */
27 #define USBHS_LPSTS_SUSPM 0x4000
28
29 /* USB General control register (UGCTRL) */
30 #define USBHS_UGCTRL_CONNECT 0x00000004
31 #define USBHS_UGCTRL_PLLRESET 0x00000001
32
33 /* USB General control register 2 (UGCTRL2) */
34 #define USBHS_UGCTRL2_USB2SEL 0x80000000
35 #define USBHS_UGCTRL2_USB2SEL_PCI 0x00000000
36 #define USBHS_UGCTRL2_USB2SEL_USB30 0x80000000
37 #define USBHS_UGCTRL2_USB0SEL 0x00000030
38 #define USBHS_UGCTRL2_USB0SEL_PCI 0x00000010
39 #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030
40 #define USBHS_UGCTRL2_USB0SEL_USB20 0x00000010
41 #define USBHS_UGCTRL2_USB0SEL_HS_USB20 0x00000020
42
43 /* USB General status register (UGSTS) */
44 #define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */
45
46 #define PHYS_PER_CHANNEL 2
47
48 struct rcar_gen2_phy {
49 struct phy *phy;
50 struct rcar_gen2_channel *channel;
51 int number;
52 u32 select_value;
53 };
54
55 struct rcar_gen2_channel {
56 struct device_node *of_node;
57 struct rcar_gen2_phy_driver *drv;
58 struct rcar_gen2_phy phys[PHYS_PER_CHANNEL];
59 int selected_phy;
60 u32 select_mask;
61 };
62
63 struct rcar_gen2_phy_driver {
64 void __iomem *base;
65 struct clk *clk;
66 spinlock_t lock;
67 int num_channels;
68 struct rcar_gen2_channel *channels;
69 };
70
71 struct rcar_gen2_phy_data {
72 const struct phy_ops *gen2_phy_ops;
73 const u32 (*select_value)[PHYS_PER_CHANNEL];
74 };
75
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
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
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
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
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
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 };
275
276 static const struct rcar_gen2_phy_data rz_g1c_usb_phy_data = {
277 .gen2_phy_ops = &rz_g1c_phy_ops,
278 .select_value = usb20_select_value,
279 };
280
281 static const struct of_device_id rcar_gen2_phy_match_table[] = {
282 {
283 .compatible = "renesas,usb-phy-r8a77470",
284 .data = &rz_g1c_usb_phy_data,
285 },
286 {
287 .compatible = "renesas,usb-phy-r8a7790",
288 .data = &rcar_gen2_usb_phy_data,
289 },
290 {
291 .compatible = "renesas,usb-phy-r8a7791",
292 .data = &rcar_gen2_usb_phy_data,
293 },
294 {
295 .compatible = "renesas,usb-phy-r8a7794",
296 .data = &rcar_gen2_usb_phy_data,
297 },
298 {
299 .compatible = "renesas,rcar-gen2-usb-phy",
300 .data = &rcar_gen2_usb_phy_data,
301 },
302 { /* sentinel */ },
303 };
304 MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
305
306 static struct phy *rcar_gen2_phy_xlate(struct device *dev,
307 struct of_phandle_args *args)
308 {
309 struct rcar_gen2_phy_driver *drv;
310 struct device_node *np = args->np;
311 int i;
312
313 drv = dev_get_drvdata(dev);
314 if (!drv)
315 return ERR_PTR(-EINVAL);
316
317 for (i = 0; i < drv->num_channels; i++) {
318 if (np == drv->channels[i].of_node)
319 break;
320 }
321
322 if (i >= drv->num_channels || args->args[0] >= 2)
323 return ERR_PTR(-ENODEV);
324
325 return drv->channels[i].phys[args->args[0]].phy;
326 }
327
328 static const u32 select_mask[] = {
329 [0] = USBHS_UGCTRL2_USB0SEL,
330 [2] = USBHS_UGCTRL2_USB2SEL,
331 };
332
333 static int rcar_gen2_phy_probe(struct platform_device *pdev)
334 {
335 struct device *dev = &pdev->dev;
336 struct rcar_gen2_phy_driver *drv;
337 struct phy_provider *provider;
338 struct device_node *np;
339 struct resource *res;
340 void __iomem *base;
341 struct clk *clk;
342 const struct rcar_gen2_phy_data *data;
343 int i = 0;
344
345 if (!dev->of_node) {
346 dev_err(dev,
347 "This driver is required to be instantiated from device tree\n");
348 return -EINVAL;
349 }
350
351 clk = devm_clk_get(dev, "usbhs");
352 if (IS_ERR(clk)) {
353 dev_err(dev, "Can't get USBHS clock\n");
354 return PTR_ERR(clk);
355 }
356
357 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
358 base = devm_ioremap_resource(dev, res);
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 > 2) {
393 dev_err(dev, "Invalid \"reg\" property\n");
394 return error;
395 }
396 channel->select_mask = select_mask[channel_num];
397
398 for (n = 0; n < PHYS_PER_CHANNEL; n++) {
399 struct rcar_gen2_phy *phy = &channel->phys[n];
400
401 phy->channel = channel;
402 phy->number = n;
403 phy->select_value = data->select_value[channel_num][n];
404
405 phy->phy = devm_phy_create(dev, NULL,
406 data->gen2_phy_ops);
407 if (IS_ERR(phy->phy)) {
408 dev_err(dev, "Failed to create PHY\n");
409 return PTR_ERR(phy->phy);
410 }
411 phy_set_drvdata(phy->phy, phy);
412 }
413
414 i++;
415 }
416
417 provider = devm_of_phy_provider_register(dev, rcar_gen2_phy_xlate);
418 if (IS_ERR(provider)) {
419 dev_err(dev, "Failed to register PHY provider\n");
420 return PTR_ERR(provider);
421 }
422
423 dev_set_drvdata(dev, drv);
424
425 return 0;
426 }
427
428 static struct platform_driver rcar_gen2_phy_driver = {
429 .driver = {
430 .name = "phy_rcar_gen2",
431 .of_match_table = rcar_gen2_phy_match_table,
432 },
433 .probe = rcar_gen2_phy_probe,
434 };
435
436 module_platform_driver(rcar_gen2_phy_driver);
437
438 MODULE_LICENSE("GPL v2");
439 MODULE_DESCRIPTION("Renesas R-Car Gen2 PHY");
440 MODULE_AUTHOR("Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>");