oxnas: bring in new oxnas target
[oweals/openwrt.git] / target / linux / oxnas / files / drivers / usb / host / ehci-oxnas.c
1 /*
2  * drivers/usb/host/ehci-oxnas.c
3  *
4  * Tzachi Perelstein <tzachi@marvell.com>
5  *
6  * This file is licensed under  the terms of the GNU General Public
7  * License version 2. This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16 #include <linux/of_irq.h>
17 #include <linux/mfd/syscon.h>
18 #include <linux/usb.h>
19 #include <linux/usb/hcd.h>
20 #include <linux/dma-mapping.h>
21 #include <linux/clk.h>
22 #include <linux/regmap.h>
23 #include <linux/reset.h>
24
25 #define USBHSMPH_CTRL_REGOFFSET         0x40
26 #define USBHSMPH_STAT_REGOFFSET         0x44
27 #define REF300_DIV_REGOFFSET            0xF8
28 #define USBHSPHY_CTRL_REGOFFSET         0x84
29 #define USB_CTRL_REGOFFSET              0x90
30 #define PLLB_DIV_CTRL_REGOFFSET         0x1000F8
31 #define USBHSPHY_SUSPENDM_MANUAL_ENABLE         16
32 #define USBHSPHY_SUSPENDM_MANUAL_STATE          15
33 #define USBHSPHY_ATE_ESET                       14
34 #define USBHSPHY_TEST_DIN                       6
35 #define USBHSPHY_TEST_ADD                       2
36 #define USBHSPHY_TEST_DOUT_SEL                  1
37 #define USBHSPHY_TEST_CLK                       0
38
39 #define USB_CTRL_USBAPHY_CKSEL_SHIFT    5
40 #define USB_CLK_XTAL0_XTAL1             (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
41 #define USB_CLK_XTAL0                   (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
42 #define USB_CLK_INTERNAL                (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
43
44 #define USBAMUX_DEVICE                  BIT(4)
45
46 #define USBPHY_REFCLKDIV_SHIFT          2
47 #define USB_PHY_REF_12MHZ               (0 << USBPHY_REFCLKDIV_SHIFT)
48 #define USB_PHY_REF_24MHZ               (1 << USBPHY_REFCLKDIV_SHIFT)
49 #define USB_PHY_REF_48MHZ               (2 << USBPHY_REFCLKDIV_SHIFT)
50
51 #define USB_CTRL_USB_CKO_SEL_BIT        0
52
53 #define USB_INT_CLK_XTAL                0
54 #define USB_INT_CLK_REF300              2
55 #define USB_INT_CLK_PLLB                3
56
57 #define REF300_DIV_INT_SHIFT            8
58 #define REF300_DIV_FRAC_SHIFT           0
59 #define REF300_DIV_INT(val)             ((val) << REF300_DIV_INT_SHIFT)
60 #define REF300_DIV_FRAC(val)            ((val) << REF300_DIV_FRAC_SHIFT)
61
62 #define PLLB_BYPASS                     1
63 #define PLLB_ENSAT                      3
64 #define PLLB_OUTDIV                     4
65 #define PLLB_REFDIV                     8
66 #define PLLB_DIV_INT_SHIFT              8
67 #define PLLB_DIV_FRAC_SHIFT             0
68 #define PLLB_DIV_INT(val)               ((val) << PLLB_DIV_INT_SHIFT)
69 #define PLLB_DIV_FRAC(val)              ((val) << PLLB_DIV_FRAC_SHIFT)
70
71 #include "ehci.h"
72
73 struct oxnas_hcd {
74         struct clk *clk;
75         struct clk *refsrc;
76         struct clk *phyref;
77         int use_pllb;
78         int use_phya;
79         struct reset_control *rst_host;
80         struct reset_control *rst_phya;
81         struct reset_control *rst_phyb;
82         struct regmap *syscon;
83 };
84
85 #define DRIVER_DESC "Oxnas On-Chip EHCI Host Controller"
86
87 static struct hc_driver __read_mostly oxnas_hc_driver;
88
89 static void start_oxnas_usb_ehci(struct oxnas_hcd *oxnas)
90 {
91         if (oxnas->use_pllb) {
92                 /* enable pllb */
93                 clk_prepare_enable(oxnas->refsrc);
94                 /* enable ref600 */
95                 clk_prepare_enable(oxnas->phyref);
96                 /* 600MHz pllb divider for 12MHz */
97                 regmap_write_bits(oxnas->syscon, PLLB_DIV_CTRL_REGOFFSET, 0xffff, PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0));
98         } else {
99                 /* ref 300 divider for 12MHz */
100                 regmap_write_bits(oxnas->syscon, REF300_DIV_REGOFFSET, 0xffff, REF300_DIV_INT(25) | REF300_DIV_FRAC(0));
101         }
102
103         /* Ensure the USB block is properly reset */
104         reset_control_reset(oxnas->rst_host);
105         reset_control_reset(oxnas->rst_phya);
106         reset_control_reset(oxnas->rst_phyb);
107
108         /* Force the high speed clock to be generated all the time, via serial
109          programming of the USB HS PHY */
110         regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
111                           (2UL << USBHSPHY_TEST_ADD) |
112                           (0xe0UL << USBHSPHY_TEST_DIN));
113
114         regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
115                           (1UL << USBHSPHY_TEST_CLK) |
116                           (2UL << USBHSPHY_TEST_ADD) |
117                           (0xe0UL << USBHSPHY_TEST_DIN));
118
119         regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
120                           (0xfUL << USBHSPHY_TEST_ADD) |
121                           (0xaaUL << USBHSPHY_TEST_DIN));
122
123         regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
124                           (1UL << USBHSPHY_TEST_CLK) |
125                           (0xfUL << USBHSPHY_TEST_ADD) |
126                           (0xaaUL << USBHSPHY_TEST_DIN));
127
128         if (oxnas->use_pllb) /* use pllb clock */
129                 regmap_write_bits(oxnas->syscon, USB_CTRL_REGOFFSET, 0xffff,
130                                   USB_CLK_INTERNAL | USB_INT_CLK_PLLB);
131         else /* use ref300 derived clock */
132                 regmap_write_bits(oxnas->syscon, USB_CTRL_REGOFFSET, 0xffff,
133                                   USB_CLK_INTERNAL | USB_INT_CLK_REF300);
134
135         if (oxnas->use_phya) {
136                 /* Configure USB PHYA as a host */
137                 regmap_update_bits(oxnas->syscon, USB_CTRL_REGOFFSET, USBAMUX_DEVICE, 0);
138         }
139
140         /* Enable the clock to the USB block */
141         clk_prepare_enable(oxnas->clk);
142 }
143
144 static void stop_oxnas_usb_ehci(struct oxnas_hcd *oxnas)
145 {
146         reset_control_assert(oxnas->rst_host);
147         reset_control_assert(oxnas->rst_phya);
148         reset_control_assert(oxnas->rst_phyb);
149
150         if (oxnas->use_pllb) {
151                 clk_disable_unprepare(oxnas->phyref);
152                 clk_disable_unprepare(oxnas->refsrc);
153         }
154         clk_disable_unprepare(oxnas->clk);
155 }
156
157 static int ehci_oxnas_reset(struct usb_hcd *hcd)
158 {
159         #define  txttfill_tuning        reserved2[0]
160
161         struct ehci_hcd *ehci;
162         u32 tmp;
163         int retval = ehci_setup(hcd);
164         if (retval)
165                 return retval;
166
167         ehci = hcd_to_ehci(hcd);
168         tmp = ehci_readl(ehci, &ehci->regs->txfill_tuning);
169         tmp &= ~0x00ff0000;
170         tmp |= 0x003f0000; /* set burst pre load count to 0x40 (63 * 4 bytes)  */
171         tmp |= 0x16; /* set sheduler overhead to 22 * 1.267us (HS) or 22 * 6.33us (FS/LS)*/
172         ehci_writel(ehci, tmp,  &ehci->regs->txfill_tuning);
173
174         tmp = ehci_readl(ehci, &ehci->regs->txttfill_tuning);
175         tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */
176         ehci_writel(ehci, tmp,  &ehci->regs->txttfill_tuning);
177
178         return retval;
179 }
180
181 static int ehci_oxnas_drv_probe(struct platform_device *ofdev)
182 {
183         struct device_node *np = ofdev->dev.of_node;
184         struct usb_hcd *hcd;
185         struct ehci_hcd *ehci;
186         struct resource res;
187         struct oxnas_hcd *oxnas;
188         int irq, err;
189         struct reset_control *rstc;
190
191         if (usb_disabled())
192                 return -ENODEV;
193
194         if (!ofdev->dev.dma_mask)
195                 ofdev->dev.dma_mask = &ofdev->dev.coherent_dma_mask;
196         if (!ofdev->dev.coherent_dma_mask)
197                 ofdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
198
199         hcd = usb_create_hcd(&oxnas_hc_driver,  &ofdev->dev,
200                                         dev_name(&ofdev->dev));
201         if (!hcd)
202                 return -ENOMEM;
203
204         err = of_address_to_resource(np, 0, &res);
205         if (err)
206                 goto err_res;
207
208         hcd->rsrc_start = res.start;
209         hcd->rsrc_len = resource_size(&res);
210
211         hcd->regs = devm_ioremap_resource(&ofdev->dev, &res);
212         if (IS_ERR(hcd->regs)) {
213                 dev_err(&ofdev->dev, "devm_ioremap_resource failed\n");
214                 err = PTR_ERR(hcd->regs);
215                 goto err_ioremap;
216         }
217
218         oxnas = (struct oxnas_hcd *)hcd_to_ehci(hcd)->priv;
219
220         oxnas->use_pllb = of_property_read_bool(np, "oxsemi,ehci_use_pllb");
221         oxnas->use_phya = of_property_read_bool(np, "oxsemi,ehci_use_phya");
222
223         oxnas->syscon = syscon_regmap_lookup_by_phandle(np, "oxsemi,sys-ctrl");
224         if (IS_ERR(oxnas->syscon)) {
225                 err = PTR_ERR(oxnas->syscon);
226                 goto err_syscon;
227         }
228
229         oxnas->clk = of_clk_get_by_name(np, "usb");
230         if (IS_ERR(oxnas->clk)) {
231                 err = PTR_ERR(oxnas->clk);
232                 goto err_clk;
233         }
234
235         if (oxnas->use_pllb) {
236                 oxnas->refsrc = of_clk_get_by_name(np, "refsrc");
237                 if (IS_ERR(oxnas->refsrc)) {
238                         err = PTR_ERR(oxnas->refsrc);
239                         goto err_refsrc;
240                 }
241                 oxnas->phyref = of_clk_get_by_name(np, "phyref");
242                 if (IS_ERR(oxnas->refsrc)) {
243                         err = PTR_ERR(oxnas->refsrc);
244                         goto err_phyref;
245                 }
246
247         } else {
248                 oxnas->refsrc = NULL;
249                 oxnas->phyref = NULL;
250         }
251
252         rstc = devm_reset_control_get(&ofdev->dev, "host");
253         if (IS_ERR(rstc)) {
254                 err = PTR_ERR(rstc);
255                 goto err_rst;
256         }
257         oxnas->rst_host = rstc;
258
259         rstc = devm_reset_control_get(&ofdev->dev, "phya");
260         if (IS_ERR(rstc)) {
261                 err = PTR_ERR(rstc);
262                 goto err_rst;
263         }
264         oxnas->rst_phya = rstc;
265
266         rstc = devm_reset_control_get(&ofdev->dev, "phyb");
267         if (IS_ERR(rstc)) {
268                 err = PTR_ERR(rstc);
269                 goto err_rst;
270         }
271         oxnas->rst_phyb = rstc;
272
273         irq = irq_of_parse_and_map(np, 0);
274         if (!irq) {
275                 dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
276                 err = -EBUSY;
277                 goto err_irq;
278         }
279
280         hcd->has_tt = 1;
281         ehci = hcd_to_ehci(hcd);
282         ehci->caps = hcd->regs;
283
284         start_oxnas_usb_ehci(oxnas);
285
286         err = usb_add_hcd(hcd, irq, IRQF_SHARED);
287         if (err)
288                 goto err_hcd;
289
290         return 0;
291
292 err_hcd:
293         stop_oxnas_usb_ehci(oxnas);
294 err_irq:
295 err_rst:
296         if (oxnas->phyref)
297                 clk_put(oxnas->phyref);
298 err_phyref:
299         if (oxnas->refsrc)
300                 clk_put(oxnas->refsrc);
301 err_refsrc:
302         clk_put(oxnas->clk);
303 err_syscon:
304 err_clk:
305 err_ioremap:
306 err_res:
307         usb_put_hcd(hcd);
308
309         return err;
310 }
311
312 static int ehci_oxnas_drv_remove(struct platform_device *pdev)
313 {
314         struct usb_hcd *hcd = platform_get_drvdata(pdev);
315         struct oxnas_hcd *oxnas = (struct oxnas_hcd *)hcd_to_ehci(hcd)->priv;
316
317         usb_remove_hcd(hcd);
318         if (oxnas->use_pllb) {
319                 clk_disable_unprepare(oxnas->phyref);
320                 clk_put(oxnas->phyref);
321                 clk_disable_unprepare(oxnas->refsrc);
322                 clk_put(oxnas->refsrc);
323         }
324         clk_disable_unprepare(oxnas->clk);
325         usb_put_hcd(hcd);
326
327         return 0;
328 }
329
330 static const struct of_device_id oxnas_ehci_dt_ids[] = {
331         { .compatible = "plxtech,nas782x-ehci" },
332         { /* sentinel */ }
333 };
334
335 MODULE_DEVICE_TABLE(of, oxnas_ehci_dt_ids);
336
337 static struct platform_driver ehci_oxnas_driver = {
338         .probe          = ehci_oxnas_drv_probe,
339         .remove         = ehci_oxnas_drv_remove,
340         .shutdown       = usb_hcd_platform_shutdown,
341         .driver.name    = "oxnas-ehci",
342         .driver.of_match_table  = oxnas_ehci_dt_ids,
343 };
344
345 static const struct ehci_driver_overrides oxnas_overrides __initconst = {
346         .reset = ehci_oxnas_reset,
347         .extra_priv_size = sizeof(struct oxnas_hcd),
348 };
349
350 static int __init ehci_oxnas_init(void)
351 {
352         if (usb_disabled())
353                 return -ENODEV;
354
355         ehci_init_driver(&oxnas_hc_driver, &oxnas_overrides);
356         return platform_driver_register(&ehci_oxnas_driver);
357 }
358 module_init(ehci_oxnas_init);
359
360 static void __exit ehci_oxnas_cleanup(void)
361 {
362         platform_driver_unregister(&ehci_oxnas_driver);
363 }
364 module_exit(ehci_oxnas_cleanup);
365
366 MODULE_DESCRIPTION(DRIVER_DESC);
367 MODULE_ALIAS("platform:oxnas-ehci");
368 MODULE_LICENSE("GPL");