Commit 4b12783c8e011859e70ba5811654a21ee1a22237
Committed by
Marek Vasut
1 parent
d53653f3f9
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
PHY: Add phy driver for the keystone USB PHY
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
Showing 3 changed files with 120 additions and 0 deletions Side-by-side Diff
drivers/phy/Kconfig
... | ... | @@ -164,5 +164,15 @@ |
164 | 164 | |
165 | 165 | This PHY is found on OMAP devices supporting USB2. |
166 | 166 | |
167 | + | |
168 | +config KEYSTONE_USB_PHY | |
169 | + bool "Support TI Keystone USB PHY" | |
170 | + depends on PHY | |
171 | + depends on ARCH_KEYSTONE | |
172 | + help | |
173 | + Support for the USB PHY found on some Keystone (k2) processors | |
174 | + | |
175 | + This PHY is found on some Keystone (K2) devices supporting USB. | |
176 | + | |
167 | 177 | endmenu |
drivers/phy/Makefile
drivers/phy/keystone-usb-phy.c
1 | +// SPDX-License-Identifier: GPL-2.0+ | |
2 | +/* | |
3 | + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ | |
4 | + * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <dm.h> | |
9 | +#include <dm/device.h> | |
10 | +#include <generic-phy.h> | |
11 | +#include <asm/io.h> | |
12 | + | |
13 | +/* USB PHY control register offsets */ | |
14 | +#define USB_PHY_CTL_UTMI 0x0000 | |
15 | +#define USB_PHY_CTL_PIPE 0x0004 | |
16 | +#define USB_PHY_CTL_PARAM_1 0x0008 | |
17 | +#define USB_PHY_CTL_PARAM_2 0x000c | |
18 | +#define USB_PHY_CTL_CLOCK 0x0010 | |
19 | +#define USB_PHY_CTL_PLL 0x0014 | |
20 | + | |
21 | +#define PHY_OTG_VBUSVLDECTSEL BIT(16) | |
22 | +#define PHY_REF_SSP_EN BIT(29) | |
23 | + | |
24 | +struct keystone_usb_phy { | |
25 | + void __iomem *reg; | |
26 | +}; | |
27 | + | |
28 | +static int keystone_usb_init(struct phy *phy) | |
29 | +{ | |
30 | + u32 val; | |
31 | + struct udevice *dev = phy->dev; | |
32 | + struct keystone_usb_phy *keystone = dev_get_priv(dev); | |
33 | + | |
34 | + /* | |
35 | + * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't. | |
36 | + * It should always be cleared because our USB PHY has an onchip VBUS | |
37 | + * analog comparator. | |
38 | + */ | |
39 | + val = readl(keystone->reg + USB_PHY_CTL_CLOCK); | |
40 | + /* quit selecting the vbusvldextsel by default! */ | |
41 | + val &= ~PHY_OTG_VBUSVLDECTSEL; | |
42 | + writel(val, keystone->reg + USB_PHY_CTL_CLOCK); | |
43 | + | |
44 | + return 0; | |
45 | +} | |
46 | + | |
47 | +static int keystone_usb_power_on(struct phy *phy) | |
48 | +{ | |
49 | + u32 val; | |
50 | + struct udevice *dev = phy->dev; | |
51 | + struct keystone_usb_phy *keystone = dev_get_priv(dev); | |
52 | + | |
53 | + val = readl(keystone->reg + USB_PHY_CTL_CLOCK); | |
54 | + val |= PHY_REF_SSP_EN; | |
55 | + writel(val, keystone->reg + USB_PHY_CTL_CLOCK); | |
56 | + | |
57 | + return 0; | |
58 | +} | |
59 | + | |
60 | +static int keystone_usb_power_off(struct phy *phy) | |
61 | +{ | |
62 | + u32 val; | |
63 | + struct udevice *dev = phy->dev; | |
64 | + struct keystone_usb_phy *keystone = dev_get_priv(dev); | |
65 | + | |
66 | + val = readl(keystone->reg + USB_PHY_CTL_CLOCK); | |
67 | + val &= ~PHY_REF_SSP_EN; | |
68 | + writel(val, keystone->reg + USB_PHY_CTL_CLOCK); | |
69 | + | |
70 | + return 0; | |
71 | +} | |
72 | + | |
73 | +static int keystone_usb_exit(struct phy *phy) | |
74 | +{ | |
75 | + return 0; | |
76 | +} | |
77 | + | |
78 | +static int keystone_usb_phy_probe(struct udevice *dev) | |
79 | +{ | |
80 | + struct keystone_usb_phy *keystone = dev_get_priv(dev); | |
81 | + | |
82 | + keystone->reg = dev_remap_addr_index(dev, 0); | |
83 | + if (!keystone->reg) { | |
84 | + pr_err("unable to remap usb phy\n"); | |
85 | + return -EINVAL; | |
86 | + } | |
87 | + return 0; | |
88 | +} | |
89 | + | |
90 | +static const struct udevice_id keystone_usb_phy_ids[] = { | |
91 | + { .compatible = "ti,keystone-usbphy" }, | |
92 | + { } | |
93 | +}; | |
94 | + | |
95 | +static struct phy_ops keystone_usb_phy_ops = { | |
96 | + .init = keystone_usb_init, | |
97 | + .power_on = keystone_usb_power_on, | |
98 | + .power_off = keystone_usb_power_off, | |
99 | + .exit = keystone_usb_exit, | |
100 | +}; | |
101 | + | |
102 | +U_BOOT_DRIVER(keystone_usb_phy) = { | |
103 | + .name = "keystone_usb_phy", | |
104 | + .id = UCLASS_PHY, | |
105 | + .of_match = keystone_usb_phy_ids, | |
106 | + .ops = &keystone_usb_phy_ops, | |
107 | + .probe = keystone_usb_phy_probe, | |
108 | + .priv_auto_alloc_size = sizeof(struct keystone_usb_phy), | |
109 | +}; |