x86: refresh kernel patches
[openwrt/openwrt.git] / target / linux / ramips / patches-3.14 / 0037-USB-phy-add-ralink-SoC-driver.patch
1 From 900fa0abfea0cb7562c523769981dadc25f1f8cd Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sun, 27 Jul 2014 09:43:42 +0100
4 Subject: [PATCH 37/57] USB: phy: add ralink SoC driver
5
6 Signed-off-by: John Crispin <blogic@openwrt.org>
7 ---
8 drivers/usb/phy/Kconfig | 8 ++
9 drivers/usb/phy/Makefile | 1 +
10 drivers/usb/phy/ralink-phy.c | 190 ++++++++++++++++++++++++++++++++++++++++++
11 3 files changed, 199 insertions(+)
12 create mode 100644 drivers/usb/phy/ralink-phy.c
13
14 --- a/drivers/usb/phy/Kconfig
15 +++ b/drivers/usb/phy/Kconfig
16 @@ -251,6 +251,14 @@ config USB_RCAR_GEN2_PHY
17 To compile this driver as a module, choose M here: the
18 module will be called phy-rcar-gen2-usb.
19
20 +config RALINK_USBPHY
21 + bool "Ralink USB PHY controller Driver"
22 + depends on MIPS && RALINK
23 + select USB_PHY
24 + help
25 + Enable this to support ralink USB phy controller for ralink
26 + SoCs.
27 +
28 config USB_ULPI
29 bool "Generic ULPI Transceiver Driver"
30 depends on ARM
31 --- a/drivers/usb/phy/Makefile
32 +++ b/drivers/usb/phy/Makefile
33 @@ -33,3 +33,4 @@ obj-$(CONFIG_USB_RCAR_GEN2_PHY) += phy-
34 obj-$(CONFIG_USB_ULPI) += phy-ulpi.o
35 obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o
36 obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o
37 +obj-$(CONFIG_RALINK_USBPHY) += ralink-phy.o
38 --- /dev/null
39 +++ b/drivers/usb/phy/ralink-phy.c
40 @@ -0,0 +1,193 @@
41 +/*
42 + * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
43 + *
44 + * based on: Renesas R-Car USB phy driver
45 + *
46 + * This program is free software; you can redistribute it and/or modify
47 + * it under the terms of the GNU General Public License version 2 as
48 + * published by the Free Software Foundation.
49 + */
50 +
51 +#include <linux/delay.h>
52 +#include <linux/io.h>
53 +#include <linux/usb/otg.h>
54 +#include <linux/of_platform.h>
55 +#include <linux/platform_device.h>
56 +#include <linux/spinlock.h>
57 +#include <linux/module.h>
58 +#include <linux/reset.h>
59 +
60 +#include <asm/mach-ralink/ralink_regs.h>
61 +
62 +#define RT_SYSC_REG_SYSCFG1 0x014
63 +#define RT_SYSC_REG_CLKCFG1 0x030
64 +#define RT_SYSC_REG_USB_PHY_CFG 0x05c
65 +
66 +#define RT_RSTCTRL_UDEV BIT(25)
67 +#define RT_RSTCTRL_UHST BIT(22)
68 +#define RT_SYSCFG1_USB0_HOST_MODE BIT(10)
69 +
70 +#define MT7620_CLKCFG1_UPHY0_CLK_EN BIT(25)
71 +#define MT7620_CLKCFG1_UPHY1_CLK_EN BIT(22)
72 +#define RT_CLKCFG1_UPHY1_CLK_EN BIT(20)
73 +#define RT_CLKCFG1_UPHY0_CLK_EN BIT(18)
74 +
75 +#define USB_PHY_UTMI_8B60M BIT(1)
76 +#define UDEV_WAKEUP BIT(0)
77 +
78 +static atomic_t usb_pwr_ref = ATOMIC_INIT(0);
79 +static struct reset_control *rstdev;
80 +static struct reset_control *rsthost;
81 +static u32 phy_clk;
82 +
83 +static void usb_phy_enable(int state)
84 +{
85 + if (state)
86 + rt_sysc_m32(0, phy_clk, RT_SYSC_REG_CLKCFG1);
87 + else
88 + rt_sysc_m32(phy_clk, 0, RT_SYSC_REG_CLKCFG1);
89 + mdelay(100);
90 +}
91 +
92 +static int usb_power_on(struct usb_phy *phy)
93 +{
94 + if (atomic_inc_return(&usb_pwr_ref) == 1) {
95 + u32 t;
96 +
97 + usb_phy_enable(1);
98 +
99 +// reset_control_assert(rstdev);
100 +// reset_control_assert(rsthost);
101 +
102 + if (OTG_STATE_B_HOST) {
103 + rt_sysc_m32(0, RT_SYSCFG1_USB0_HOST_MODE, RT_SYSC_REG_SYSCFG1);
104 + if (!IS_ERR(rsthost))
105 + reset_control_deassert(rsthost);
106 + if (!IS_ERR(rstdev))
107 + reset_control_deassert(rstdev);
108 + } else {
109 + rt_sysc_m32(RT_SYSCFG1_USB0_HOST_MODE, 0, RT_SYSC_REG_SYSCFG1);
110 + if (!IS_ERR(rstdev))
111 + reset_control_deassert(rstdev);
112 + }
113 + mdelay(100);
114 +
115 + t = rt_sysc_r32(RT_SYSC_REG_USB_PHY_CFG);
116 + dev_info(phy->dev, "remote usb device wakeup %s\n",
117 + (t & UDEV_WAKEUP) ? ("enabbled") : ("disabled"));
118 + if (t & USB_PHY_UTMI_8B60M)
119 + dev_info(phy->dev, "UTMI 8bit 60MHz\n");
120 + else
121 + dev_info(phy->dev, "UTMI 16bit 30MHz\n");
122 + }
123 +
124 + return 0;
125 +}
126 +
127 +static void usb_power_off(struct usb_phy *phy)
128 +{
129 + if (atomic_dec_return(&usb_pwr_ref) == 0) {
130 + usb_phy_enable(0);
131 + if (!IS_ERR(rstdev))
132 + reset_control_assert(rstdev);
133 + if (!IS_ERR(rsthost))
134 + reset_control_assert(rsthost);
135 + }
136 +}
137 +
138 +static int usb_set_host(struct usb_otg *otg, struct usb_bus *host)
139 +{
140 + otg->gadget = NULL;
141 + otg->host = host;
142 +
143 + return 0;
144 +}
145 +
146 +static int usb_set_peripheral(struct usb_otg *otg,
147 + struct usb_gadget *gadget)
148 +{
149 + otg->host = NULL;
150 + otg->gadget = gadget;
151 +
152 + return 0;
153 +}
154 +
155 +static const struct of_device_id ralink_usbphy_dt_match[] = {
156 + { .compatible = "ralink,rt3xxx-usbphy", .data = (void *) (RT_CLKCFG1_UPHY1_CLK_EN | RT_CLKCFG1_UPHY0_CLK_EN) },
157 + { .compatible = "ralink,mt7620a-usbphy", .data = (void *) (MT7620_CLKCFG1_UPHY1_CLK_EN | MT7620_CLKCFG1_UPHY0_CLK_EN) },
158 + {},
159 +};
160 +MODULE_DEVICE_TABLE(of, ralink_usbphy_dt_match);
161 +
162 +static int usb_phy_probe(struct platform_device *pdev)
163 +{
164 + const struct of_device_id *match;
165 + struct device *dev = &pdev->dev;
166 + struct usb_otg *otg;
167 + struct usb_phy *phy;
168 + int ret;
169 +
170 + match = of_match_device(ralink_usbphy_dt_match, &pdev->dev);
171 + phy_clk = (int) match->data;
172 +
173 + rsthost = devm_reset_control_get(&pdev->dev, "host");
174 + rstdev = devm_reset_control_get(&pdev->dev, "device");
175 +
176 + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
177 + if (!phy) {
178 + dev_err(&pdev->dev, "unable to allocate memory for USB PHY\n");
179 + return -ENOMEM;
180 + }
181 +
182 + otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
183 + if (!otg) {
184 + dev_err(&pdev->dev, "unable to allocate memory for USB OTG\n");
185 + return -ENOMEM;
186 + }
187 +
188 + phy->dev = dev;
189 + phy->label = dev_name(dev);
190 + phy->init = usb_power_on;
191 + phy->shutdown = usb_power_off;
192 + otg->set_host = usb_set_host;
193 + otg->set_peripheral = usb_set_peripheral;
194 + otg->phy = phy;
195 + phy->otg = otg;
196 + ret = usb_add_phy(phy, USB_PHY_TYPE_USB2);
197 +
198 + if (ret < 0) {
199 + dev_err(dev, "usb phy addition error\n");
200 + return ret;
201 + }
202 +
203 + platform_set_drvdata(pdev, phy);
204 +
205 + dev_info(&pdev->dev, "loaded\n");
206 +
207 + return ret;
208 +}
209 +
210 +static int usb_phy_remove(struct platform_device *pdev)
211 +{
212 + struct usb_phy *phy = platform_get_drvdata(pdev);
213 +
214 + usb_remove_phy(phy);
215 +
216 + return 0;
217 +}
218 +
219 +static struct platform_driver usb_phy_driver = {
220 + .driver = {
221 + .owner = THIS_MODULE,
222 + .name = "rt3xxx-usbphy",
223 + .of_match_table = of_match_ptr(ralink_usbphy_dt_match),
224 + },
225 + .probe = usb_phy_probe,
226 + .remove = usb_phy_remove,
227 +};
228 +
229 +module_platform_driver(usb_phy_driver);
230 +
231 +MODULE_LICENSE("GPL v2");
232 +MODULE_DESCRIPTION("Ralink USB phy");
233 +MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");