1 // SPDX-License-Identifier: GPL-2.0
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>
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>
23 #define DA8XX_USB0_BASE 0x01e00000
24 #define DA8XX_USB1_BASE 0x01e25000
26 static struct clk
*usb20_clk
;
28 static struct platform_device da8xx_usb_phy
= {
29 .name
= "da8xx-usb-phy",
33 * Setting init_name so that clock lookup will work in
34 * da8xx_register_usb11_phy_clk() even if this device is not
37 .init_name
= "da8xx-usb-phy",
41 int __init
da8xx_register_usb_phy(void)
43 return platform_device_register(&da8xx_usb_phy
);
46 static struct musb_hdrc_config musb_config
= {
52 static struct musb_hdrc_platform_data usb_data
= {
53 /* OTG requires a Mini-AB connector */
56 .config
= &musb_config
,
59 static struct resource da8xx_usb20_resources
[] = {
61 .start
= DA8XX_USB0_BASE
,
62 .end
= DA8XX_USB0_BASE
+ SZ_64K
- 1,
63 .flags
= IORESOURCE_MEM
,
66 .start
= IRQ_DA8XX_USB_INT
,
67 .flags
= IORESOURCE_IRQ
,
72 static u64 usb_dmamask
= DMA_BIT_MASK(32);
74 static struct platform_device da8xx_usb20_dev
= {
79 * Setting init_name so that clock lookup will work in
80 * usb20_phy_clk_enable() even if this device is not registered.
82 .init_name
= "musb-da8xx",
83 .platform_data
= &usb_data
,
84 .dma_mask
= &usb_dmamask
,
85 .coherent_dma_mask
= DMA_BIT_MASK(32),
87 .resource
= da8xx_usb20_resources
,
88 .num_resources
= ARRAY_SIZE(da8xx_usb20_resources
),
91 int __init
da8xx_register_usb20(unsigned int mA
, unsigned int potpgt
)
93 usb_data
.power
= mA
> 510 ? 255 : mA
/ 2;
94 usb_data
.potpgt
= (potpgt
+ 1) / 2;
96 return platform_device_register(&da8xx_usb20_dev
);
99 static struct resource da8xx_usb11_resources
[] = {
101 .start
= DA8XX_USB1_BASE
,
102 .end
= DA8XX_USB1_BASE
+ SZ_4K
- 1,
103 .flags
= IORESOURCE_MEM
,
106 .start
= IRQ_DA8XX_IRQN
,
107 .end
= IRQ_DA8XX_IRQN
,
108 .flags
= IORESOURCE_IRQ
,
112 static u64 da8xx_usb11_dma_mask
= DMA_BIT_MASK(32);
114 static struct platform_device da8xx_usb11_device
= {
115 .name
= "ohci-da8xx",
118 .dma_mask
= &da8xx_usb11_dma_mask
,
119 .coherent_dma_mask
= DMA_BIT_MASK(32),
121 .num_resources
= ARRAY_SIZE(da8xx_usb11_resources
),
122 .resource
= da8xx_usb11_resources
,
125 int __init
da8xx_register_usb11(struct da8xx_ohci_root_hub
*pdata
)
127 da8xx_usb11_device
.dev
.platform_data
= pdata
;
128 return platform_device_register(&da8xx_usb11_device
);
131 static struct clk usb_refclkin
= {
132 .name
= "usb_refclkin",
133 .set_rate
= davinci_simple_set_rate
,
136 static struct clk_lookup usb_refclkin_lookup
=
137 CLK(NULL
, "usb_refclkin", &usb_refclkin
);
140 * da8xx_register_usb_refclkin - register USB_REFCLKIN clock
142 * @rate: The clock rate in Hz
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
148 int __init
da8xx_register_usb_refclkin(int rate
)
152 usb_refclkin
.rate
= rate
;
153 ret
= clk_register(&usb_refclkin
);
157 clkdev_add(&usb_refclkin_lookup
);
162 static void usb20_phy_clk_enable(struct clk
*clk
)
165 u32 timeout
= 500000; /* 500 msec */
167 val
= readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
169 /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
170 davinci_clk_enable(usb20_clk
);
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.
176 val
&= ~(CFGCHIP2_RESET
| CFGCHIP2_PHYPWRDN
);
177 val
|= CFGCHIP2_PHY_PLLON
;
179 writel(val
, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
182 val
= readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
183 if (val
& CFGCHIP2_PHYCLKGD
)
188 pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
190 davinci_clk_disable(usb20_clk
);
193 static void usb20_phy_clk_disable(struct clk
*clk
)
197 val
= readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
198 val
|= CFGCHIP2_PHYPWRDN
;
199 writel(val
, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
202 static int usb20_phy_clk_set_parent(struct clk
*clk
, struct clk
*parent
)
206 val
= readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
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
;
214 pr_err("Bad parent on USB 2.0 PHY clock\n");
218 /* reference frequency also comes from parent clock */
219 val
&= ~CFGCHIP2_REFFREQ_MASK
;
220 switch (clk_get_rate(parent
)) {
222 val
|= CFGCHIP2_REFFREQ_12MHZ
;
225 val
|= CFGCHIP2_REFFREQ_13MHZ
;
228 val
|= CFGCHIP2_REFFREQ_19_2MHZ
;
231 val
|= CFGCHIP2_REFFREQ_20MHZ
;
234 val
|= CFGCHIP2_REFFREQ_24MHZ
;
237 val
|= CFGCHIP2_REFFREQ_26MHZ
;
240 val
|= CFGCHIP2_REFFREQ_38_4MHZ
;
243 val
|= CFGCHIP2_REFFREQ_40MHZ
;
246 val
|= CFGCHIP2_REFFREQ_48MHZ
;
249 pr_err("Bad parent clock rate on USB 2.0 PHY clock\n");
253 writel(val
, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
258 static struct clk usb20_phy_clk
= {
260 .clk_enable
= usb20_phy_clk_enable
,
261 .clk_disable
= usb20_phy_clk_disable
,
262 .set_parent
= usb20_phy_clk_set_parent
,
265 static struct clk_lookup usb20_phy_clk_lookup
=
266 CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk
);
269 * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock
271 * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
272 * or "pll0_aux" if false.
274 int __init
da8xx_register_usb20_phy_clk(bool use_usb_refclkin
)
279 usb20_clk
= clk_get(&da8xx_usb20_dev
.dev
, "usb20");
280 ret
= PTR_ERR_OR_ZERO(usb20_clk
);
284 parent
= clk_get(NULL
, use_usb_refclkin
? "usb_refclkin" : "pll0_aux");
285 ret
= PTR_ERR_OR_ZERO(parent
);
291 usb20_phy_clk
.parent
= parent
;
292 ret
= clk_register(&usb20_phy_clk
);
294 clkdev_add(&usb20_phy_clk_lookup
);
301 static int usb11_phy_clk_set_parent(struct clk
*clk
, struct clk
*parent
)
305 val
= readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
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
;
313 pr_err("Bad parent on USB 1.1 PHY clock\n");
317 writel(val
, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG
));
322 static struct clk usb11_phy_clk
= {
324 .set_parent
= usb11_phy_clk_set_parent
,
327 static struct clk_lookup usb11_phy_clk_lookup
=
328 CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk
);
331 * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock
333 * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true
334 * or "usb20_phy" if false.
336 int __init
da8xx_register_usb11_phy_clk(bool use_usb_refclkin
)
341 if (use_usb_refclkin
)
342 parent
= clk_get(NULL
, "usb_refclkin");
344 parent
= clk_get(&da8xx_usb_phy
.dev
, "usb20_phy");
346 return PTR_ERR(parent
);
348 usb11_phy_clk
.parent
= parent
;
349 ret
= clk_register(&usb11_phy_clk
);
351 clkdev_add(&usb11_phy_clk_lookup
);