Merge remote-tracking branch 'regulator/topic/axp20x' into regulator-next
[sfrench/cifs-2.6.git] / arch / arm / mach-davinci / usb-da8xx.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DA8xx USB
4  */
5 #include <linux/clk.h>
6 #include <linux/delay.h>
7 #include <linux/dma-mapping.h>
8 #include <linux/init.h>
9 #include <linux/mfd/da8xx-cfgchip.h>
10 #include <linux/phy/phy.h>
11 #include <linux/platform_data/usb-davinci.h>
12 #include <linux/platform_device.h>
13 #include <linux/usb/musb.h>
14
15 #include <mach/clock.h>
16 #include <mach/common.h>
17 #include <mach/cputype.h>
18 #include <mach/da8xx.h>
19 #include <mach/irqs.h>
20
21 #include "clock.h"
22
23 #define DA8XX_USB0_BASE         0x01e00000
24 #define DA8XX_USB1_BASE         0x01e25000
25
26 static struct clk *usb20_clk;
27
28 static struct platform_device da8xx_usb_phy = {
29         .name           = "da8xx-usb-phy",
30         .id             = -1,
31         .dev            = {
32                 /*
33                  * Setting init_name so that clock lookup will work in
34                  * da8xx_register_usb11_phy_clk() even if this device is not
35                  * registered yet.
36                  */
37                 .init_name      = "da8xx-usb-phy",
38         },
39 };
40
41 int __init da8xx_register_usb_phy(void)
42 {
43         return platform_device_register(&da8xx_usb_phy);
44 }
45
46 static struct musb_hdrc_config musb_config = {
47         .multipoint     = true,
48         .num_eps        = 5,
49         .ram_bits       = 10,
50 };
51
52 static struct musb_hdrc_platform_data usb_data = {
53         /* OTG requires a Mini-AB connector */
54         .mode           = MUSB_OTG,
55         .clock          = "usb20",
56         .config         = &musb_config,
57 };
58
59 static struct resource da8xx_usb20_resources[] = {
60         {
61                 .start          = DA8XX_USB0_BASE,
62                 .end            = DA8XX_USB0_BASE + SZ_64K - 1,
63                 .flags          = IORESOURCE_MEM,
64         },
65         {
66                 .start          = IRQ_DA8XX_USB_INT,
67                 .flags          = IORESOURCE_IRQ,
68                 .name           = "mc",
69         },
70 };
71
72 static u64 usb_dmamask = DMA_BIT_MASK(32);
73
74 static struct platform_device da8xx_usb20_dev = {
75         .name           = "musb-da8xx",
76         .id             = -1,
77         .dev = {
78                 /*
79                  * Setting init_name so that clock lookup will work in
80                  * usb20_phy_clk_enable() even if this device is not registered.
81                  */
82                 .init_name              = "musb-da8xx",
83                 .platform_data          = &usb_data,
84                 .dma_mask               = &usb_dmamask,
85                 .coherent_dma_mask      = DMA_BIT_MASK(32),
86         },
87         .resource       = da8xx_usb20_resources,
88         .num_resources  = ARRAY_SIZE(da8xx_usb20_resources),
89 };
90
91 int __init da8xx_register_usb20(unsigned int mA, unsigned int potpgt)
92 {
93         usb_data.power  = mA > 510 ? 255 : mA / 2;
94         usb_data.potpgt = (potpgt + 1) / 2;
95
96         return platform_device_register(&da8xx_usb20_dev);
97 }
98
99 static struct resource da8xx_usb11_resources[] = {
100         [0] = {
101                 .start  = DA8XX_USB1_BASE,
102                 .end    = DA8XX_USB1_BASE + SZ_4K - 1,
103                 .flags  = IORESOURCE_MEM,
104         },
105         [1] = {
106                 .start  = IRQ_DA8XX_IRQN,
107                 .end    = IRQ_DA8XX_IRQN,
108                 .flags  = IORESOURCE_IRQ,
109         },
110 };
111
112 static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
113
114 static struct platform_device da8xx_usb11_device = {
115         .name           = "ohci-da8xx",
116         .id             = -1,
117         .dev = {
118                 .dma_mask               = &da8xx_usb11_dma_mask,
119                 .coherent_dma_mask      = DMA_BIT_MASK(32),
120         },
121         .num_resources  = ARRAY_SIZE(da8xx_usb11_resources),
122         .resource       = da8xx_usb11_resources,
123 };
124
125 int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
126 {
127         da8xx_usb11_device.dev.platform_data = pdata;
128         return platform_device_register(&da8xx_usb11_device);
129 }
130
131 static struct clk usb_refclkin = {
132         .name           = "usb_refclkin",
133         .set_rate       = davinci_simple_set_rate,
134 };
135
136 static struct clk_lookup usb_refclkin_lookup =
137         CLK(NULL, "usb_refclkin", &usb_refclkin);
138
139 /**
140  * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
141  *
142  * @rate: The clock rate in Hz
143  *
144  * This clock is only needed if the board provides an external USB_REFCLKIN
145  * signal, in which case it will be used as the parent of usb20_phy_clk and/or
146  * usb11_phy_clk.
147  */
148 int __init da8xx_register_usb_refclkin(int rate)
149 {
150         int ret;
151
152         usb_refclkin.rate = rate;
153         ret = clk_register(&usb_refclkin);
154         if (ret)
155                 return ret;
156
157         clkdev_add(&usb_refclkin_lookup);
158
159         return 0;
160 }
161
162 static void usb20_phy_clk_enable(struct clk *clk)
163 {
164         u32 val;
165         u32 timeout = 500000; /* 500 msec */
166
167         val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
168
169         /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
170         davinci_clk_enable(usb20_clk);
171
172         /*
173          * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
174          * host may use the PLL clock without USB 2.0 OTG being used.
175          */
176         val &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN);
177         val |= CFGCHIP2_PHY_PLLON;
178
179         writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
180
181         while (--timeout) {
182                 val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
183                 if (val & CFGCHIP2_PHYCLKGD)
184                         goto done;
185                 udelay(1);
186         }
187
188         pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
189 done:
190         davinci_clk_disable(usb20_clk);
191 }
192
193 static void usb20_phy_clk_disable(struct clk *clk)
194 {
195         u32 val;
196
197         val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
198         val |= CFGCHIP2_PHYPWRDN;
199         writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
200 }
201
202 static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent)
203 {
204         u32 val;
205
206         val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
207
208         /* Set the mux depending on the parent clock. */
209         if (parent == &usb_refclkin) {
210                 val &= ~CFGCHIP2_USB2PHYCLKMUX;
211         } else if (strcmp(parent->name, "pll0_aux_clk") == 0) {
212                 val |= CFGCHIP2_USB2PHYCLKMUX;
213         } else {
214                 pr_err("Bad parent on USB 2.0 PHY clock\n");
215                 return -EINVAL;
216         }
217
218         /* reference frequency also comes from parent clock */
219         val &= ~CFGCHIP2_REFFREQ_MASK;
220         switch (clk_get_rate(parent)) {
221         case 12000000:
222                 val |= CFGCHIP2_REFFREQ_12MHZ;
223                 break;
224         case 13000000:
225                 val |= CFGCHIP2_REFFREQ_13MHZ;
226                 break;
227         case 19200000:
228                 val |= CFGCHIP2_REFFREQ_19_2MHZ;
229                 break;
230         case 20000000:
231                 val |= CFGCHIP2_REFFREQ_20MHZ;
232                 break;
233         case 24000000:
234                 val |= CFGCHIP2_REFFREQ_24MHZ;
235                 break;
236         case 26000000:
237                 val |= CFGCHIP2_REFFREQ_26MHZ;
238                 break;
239         case 38400000:
240                 val |= CFGCHIP2_REFFREQ_38_4MHZ;
241                 break;
242         case 40000000:
243                 val |= CFGCHIP2_REFFREQ_40MHZ;
244                 break;
245         case 48000000:
246                 val |= CFGCHIP2_REFFREQ_48MHZ;
247                 break;
248         default:
249                 pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
250                 return -EINVAL;
251         }
252
253         writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
254
255         return 0;
256 }
257
258 static struct clk usb20_phy_clk = {
259         .name           = "usb20_phy",
260         .clk_enable     = usb20_phy_clk_enable,
261         .clk_disable    = usb20_phy_clk_disable,
262         .set_parent     = usb20_phy_clk_set_parent,
263 };
264
265 static struct clk_lookup usb20_phy_clk_lookup =
266         CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk);
267
268 /**
269  * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
270  *
271  * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
272  *      or "pll0_aux" if false.
273  */
274 int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
275 {
276         struct clk *parent;
277         int ret;
278
279         usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
280         ret = PTR_ERR_OR_ZERO(usb20_clk);
281         if (ret)
282                 return ret;
283
284         parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
285         ret = PTR_ERR_OR_ZERO(parent);
286         if (ret) {
287                 clk_put(usb20_clk);
288                 return ret;
289         }
290
291         usb20_phy_clk.parent = parent;
292         ret = clk_register(&usb20_phy_clk);
293         if (!ret)
294                 clkdev_add(&usb20_phy_clk_lookup);
295
296         clk_put(parent);
297
298         return ret;
299 }
300
301 static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent)
302 {
303         u32 val;
304
305         val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
306
307         /* Set the USB 1.1 PHY clock mux based on the parent clock. */
308         if (parent == &usb20_phy_clk) {
309                 val &= ~CFGCHIP2_USB1PHYCLKMUX;
310         } else if (parent == &usb_refclkin) {
311                 val |= CFGCHIP2_USB1PHYCLKMUX;
312         } else {
313                 pr_err("Bad parent on USB 1.1 PHY clock\n");
314                 return -EINVAL;
315         }
316
317         writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
318
319         return 0;
320 }
321
322 static struct clk usb11_phy_clk = {
323         .name           = "usb11_phy",
324         .set_parent     = usb11_phy_clk_set_parent,
325 };
326
327 static struct clk_lookup usb11_phy_clk_lookup =
328         CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk);
329
330 /**
331  * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
332  *
333  * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
334  *      or "usb20_phy" if false.
335  */
336 int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin)
337 {
338         struct clk *parent;
339         int ret = 0;
340
341         if (use_usb_refclkin)
342                 parent = clk_get(NULL, "usb_refclkin");
343         else
344                 parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy");
345         if (IS_ERR(parent))
346                 return PTR_ERR(parent);
347
348         usb11_phy_clk.parent = parent;
349         ret = clk_register(&usb11_phy_clk);
350         if (!ret)
351                 clkdev_add(&usb11_phy_clk_lookup);
352
353         clk_put(parent);
354
355         return ret;
356 }