hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/phy/renesas/phy-rcar-gen2.c
....@@ -1,12 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Renesas R-Car Gen2 PHY driver
34 *
45 * Copyright (C) 2014 Renesas Solutions Corp.
56 * Copyright (C) 2014 Cogent Embedded, Inc.
6
- *
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.
7
+ * Copyright (C) 2019 Renesas Electronics Corp.
108 */
119
1210 #include <linux/clk.h>
....@@ -18,6 +16,7 @@
1816 #include <linux/platform_device.h>
1917 #include <linux/spinlock.h>
2018 #include <linux/atomic.h>
19
+#include <linux/of_device.h>
2120
2221 #define USBHS_LPSTS 0x02
2322 #define USBHS_UGCTRL 0x80
....@@ -38,6 +37,8 @@
3837 #define USBHS_UGCTRL2_USB0SEL 0x00000030
3938 #define USBHS_UGCTRL2_USB0SEL_PCI 0x00000010
4039 #define USBHS_UGCTRL2_USB0SEL_HS_USB 0x00000030
40
+#define USBHS_UGCTRL2_USB0SEL_USB20 0x00000010
41
+#define USBHS_UGCTRL2_USB0SEL_HS_USB20 0x00000020
4142
4243 /* USB General status register (UGSTS) */
4344 #define USBHS_UGSTS_LOCK 0x00000100 /* From technical update */
....@@ -65,6 +66,12 @@
6566 spinlock_t lock;
6667 int num_channels;
6768 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
+ const u32 num_channels;
6875 };
6976
7077 static int rcar_gen2_phy_init(struct phy *p)
....@@ -183,6 +190,60 @@
183190 return 0;
184191 }
185192
193
+static int rz_g1c_phy_power_on(struct phy *p)
194
+{
195
+ struct rcar_gen2_phy *phy = phy_get_drvdata(p);
196
+ struct rcar_gen2_phy_driver *drv = phy->channel->drv;
197
+ void __iomem *base = drv->base;
198
+ unsigned long flags;
199
+ u32 value;
200
+
201
+ spin_lock_irqsave(&drv->lock, flags);
202
+
203
+ /* Power on USBHS PHY */
204
+ value = readl(base + USBHS_UGCTRL);
205
+ value &= ~USBHS_UGCTRL_PLLRESET;
206
+ writel(value, base + USBHS_UGCTRL);
207
+
208
+ /* As per the data sheet wait 340 micro sec for power stable */
209
+ udelay(340);
210
+
211
+ if (phy->select_value == USBHS_UGCTRL2_USB0SEL_HS_USB20) {
212
+ value = readw(base + USBHS_LPSTS);
213
+ value |= USBHS_LPSTS_SUSPM;
214
+ writew(value, base + USBHS_LPSTS);
215
+ }
216
+
217
+ spin_unlock_irqrestore(&drv->lock, flags);
218
+
219
+ return 0;
220
+}
221
+
222
+static int rz_g1c_phy_power_off(struct phy *p)
223
+{
224
+ struct rcar_gen2_phy *phy = phy_get_drvdata(p);
225
+ struct rcar_gen2_phy_driver *drv = phy->channel->drv;
226
+ void __iomem *base = drv->base;
227
+ unsigned long flags;
228
+ u32 value;
229
+
230
+ spin_lock_irqsave(&drv->lock, flags);
231
+ /* Power off USBHS PHY */
232
+ if (phy->select_value == USBHS_UGCTRL2_USB0SEL_HS_USB20) {
233
+ value = readw(base + USBHS_LPSTS);
234
+ value &= ~USBHS_LPSTS_SUSPM;
235
+ writew(value, base + USBHS_LPSTS);
236
+ }
237
+
238
+ value = readl(base + USBHS_UGCTRL);
239
+ value |= USBHS_UGCTRL_PLLRESET;
240
+ writel(value, base + USBHS_UGCTRL);
241
+
242
+ spin_unlock_irqrestore(&drv->lock, flags);
243
+
244
+ return 0;
245
+}
246
+
186247 static const struct phy_ops rcar_gen2_phy_ops = {
187248 .init = rcar_gen2_phy_init,
188249 .exit = rcar_gen2_phy_exit,
....@@ -191,12 +252,57 @@
191252 .owner = THIS_MODULE,
192253 };
193254
255
+static const struct phy_ops rz_g1c_phy_ops = {
256
+ .init = rcar_gen2_phy_init,
257
+ .exit = rcar_gen2_phy_exit,
258
+ .power_on = rz_g1c_phy_power_on,
259
+ .power_off = rz_g1c_phy_power_off,
260
+ .owner = THIS_MODULE,
261
+};
262
+
263
+static const u32 pci_select_value[][PHYS_PER_CHANNEL] = {
264
+ [0] = { USBHS_UGCTRL2_USB0SEL_PCI, USBHS_UGCTRL2_USB0SEL_HS_USB },
265
+ [2] = { USBHS_UGCTRL2_USB2SEL_PCI, USBHS_UGCTRL2_USB2SEL_USB30 },
266
+};
267
+
268
+static const u32 usb20_select_value[][PHYS_PER_CHANNEL] = {
269
+ { USBHS_UGCTRL2_USB0SEL_USB20, USBHS_UGCTRL2_USB0SEL_HS_USB20 },
270
+};
271
+
272
+static const struct rcar_gen2_phy_data rcar_gen2_usb_phy_data = {
273
+ .gen2_phy_ops = &rcar_gen2_phy_ops,
274
+ .select_value = pci_select_value,
275
+ .num_channels = ARRAY_SIZE(pci_select_value),
276
+};
277
+
278
+static const struct rcar_gen2_phy_data rz_g1c_usb_phy_data = {
279
+ .gen2_phy_ops = &rz_g1c_phy_ops,
280
+ .select_value = usb20_select_value,
281
+ .num_channels = ARRAY_SIZE(usb20_select_value),
282
+};
283
+
194284 static const struct of_device_id rcar_gen2_phy_match_table[] = {
195
- { .compatible = "renesas,usb-phy-r8a7790" },
196
- { .compatible = "renesas,usb-phy-r8a7791" },
197
- { .compatible = "renesas,usb-phy-r8a7794" },
198
- { .compatible = "renesas,rcar-gen2-usb-phy" },
199
- { }
285
+ {
286
+ .compatible = "renesas,usb-phy-r8a77470",
287
+ .data = &rz_g1c_usb_phy_data,
288
+ },
289
+ {
290
+ .compatible = "renesas,usb-phy-r8a7790",
291
+ .data = &rcar_gen2_usb_phy_data,
292
+ },
293
+ {
294
+ .compatible = "renesas,usb-phy-r8a7791",
295
+ .data = &rcar_gen2_usb_phy_data,
296
+ },
297
+ {
298
+ .compatible = "renesas,usb-phy-r8a7794",
299
+ .data = &rcar_gen2_usb_phy_data,
300
+ },
301
+ {
302
+ .compatible = "renesas,rcar-gen2-usb-phy",
303
+ .data = &rcar_gen2_usb_phy_data,
304
+ },
305
+ { /* sentinel */ },
200306 };
201307 MODULE_DEVICE_TABLE(of, rcar_gen2_phy_match_table);
202308
....@@ -227,11 +333,6 @@
227333 [2] = USBHS_UGCTRL2_USB2SEL,
228334 };
229335
230
-static const u32 select_value[][PHYS_PER_CHANNEL] = {
231
- [0] = { USBHS_UGCTRL2_USB0SEL_PCI, USBHS_UGCTRL2_USB0SEL_HS_USB },
232
- [2] = { USBHS_UGCTRL2_USB2SEL_PCI, USBHS_UGCTRL2_USB2SEL_USB30 },
233
-};
234
-
235336 static int rcar_gen2_phy_probe(struct platform_device *pdev)
236337 {
237338 struct device *dev = &pdev->dev;
....@@ -241,6 +342,7 @@
241342 struct resource *res;
242343 void __iomem *base;
243344 struct clk *clk;
345
+ const struct rcar_gen2_phy_data *data;
244346 int i = 0;
245347
246348 if (!dev->of_node) {
....@@ -269,6 +371,10 @@
269371 drv->clk = clk;
270372 drv->base = base;
271373
374
+ data = of_device_get_match_data(dev);
375
+ if (!data)
376
+ return -EINVAL;
377
+
272378 drv->num_channels = of_get_child_count(dev->of_node);
273379 drv->channels = devm_kcalloc(dev, drv->num_channels,
274380 sizeof(struct rcar_gen2_channel),
....@@ -286,7 +392,7 @@
286392 channel->selected_phy = -1;
287393
288394 error = of_property_read_u32(np, "reg", &channel_num);
289
- if (error || channel_num > 2) {
395
+ if (error || channel_num >= data->num_channels) {
290396 dev_err(dev, "Invalid \"reg\" property\n");
291397 of_node_put(np);
292398 return error;
....@@ -298,10 +404,10 @@
298404
299405 phy->channel = channel;
300406 phy->number = n;
301
- phy->select_value = select_value[channel_num][n];
407
+ phy->select_value = data->select_value[channel_num][n];
302408
303409 phy->phy = devm_phy_create(dev, NULL,
304
- &rcar_gen2_phy_ops);
410
+ data->gen2_phy_ops);
305411 if (IS_ERR(phy->phy)) {
306412 dev_err(dev, "Failed to create PHY\n");
307413 of_node_put(np);