uboot-omap: switch to u-boot.mk
[openwrt/staging/yousong.git] / package / boot / uboot-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 #include <common.h>
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/sysctl.h>
13 #include <asm/arch/clock.h>
14
15 #include "ehci.h"
16
17 static struct ehci_hcor *ghcor;
18
19 static int start_oxnas_usb_ehci(void)
20 {
21 #ifdef CONFIG_USB_PLLB_CLK
22 reset_block(SYS_CTRL_RST_PLLB, 0);
23 enable_clock(SYS_CTRL_CLK_REF600);
24
25 writel((1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV),
26 SEC_CTRL_PLLB_CTRL0);
27 /* 600MHz pllb divider for 12MHz */
28 writel(PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0), SEC_CTRL_PLLB_DIV_CTRL);
29 #else
30 /* ref 300 divider for 12MHz */
31 writel(REF300_DIV_INT(25) | REF300_DIV_FRAC(0), SYS_CTRL_REF300_DIV);
32 #endif
33
34 /* Ensure the USB block is properly reset */
35 reset_block(SYS_CTRL_RST_USBHS, 1);
36 reset_block(SYS_CTRL_RST_USBHS, 0);
37
38 reset_block(SYS_CTRL_RST_USBHSPHYA, 1);
39 reset_block(SYS_CTRL_RST_USBHSPHYA, 0);
40
41 reset_block(SYS_CTRL_RST_USBHSPHYB, 1);
42 reset_block(SYS_CTRL_RST_USBHSPHYB, 0);
43
44 /* Force the high speed clock to be generated all the time, via serial
45 programming of the USB HS PHY */
46 writel((2UL << USBHSPHY_TEST_ADD) |
47 (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
48
49 writel((1UL << USBHSPHY_TEST_CLK) |
50 (2UL << USBHSPHY_TEST_ADD) |
51 (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
52
53 writel((0xfUL << USBHSPHY_TEST_ADD) |
54 (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
55
56 writel((1UL << USBHSPHY_TEST_CLK) |
57 (0xfUL << USBHSPHY_TEST_ADD) |
58 (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
59
60 #ifdef CONFIG_USB_PLLB_CLK /* use pllb clock */
61 writel(USB_CLK_INTERNAL | USB_INT_CLK_PLLB, SYS_CTRL_USB_CTRL);
62 #else /* use ref300 derived clock */
63 writel(USB_CLK_INTERNAL | USB_INT_CLK_REF300, SYS_CTRL_USB_CTRL);
64 #endif
65 /* Enable the clock to the USB block */
66 enable_clock(SYS_CTRL_CLK_USBHS);
67
68 return 0;
69 }
70 int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
71 struct ehci_hcor **hcor)
72 {
73 start_oxnas_usb_ehci();
74 *hccr = (struct ehci_hccr *)(USB_HOST_BASE + 0x100);
75 *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
76 HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
77 ghcor = *hcor;
78 return 0;
79 }
80
81 int ehci_hcd_stop(int index)
82 {
83 reset_block(SYS_CTRL_RST_USBHS, 1);
84 disable_clock(SYS_CTRL_CLK_USBHS);
85 return 0;
86 }
87
88 extern void __ehci_set_usbmode(int index);
89 void ehci_set_usbmode(int index)
90 {
91 #define or_txttfill_tuning _reserved_1_[0]
92 u32 tmp;
93
94 __ehci_set_usbmode(index);
95
96 tmp = ehci_readl(&ghcor->or_txfilltuning);
97 tmp &= ~0x00ff0000;
98 tmp |= 0x003f0000; /* set burst pre load count to 0x40 (63 * 4 bytes) */
99 tmp |= 0x16; /* set sheduler overhead to 22 * 1.267us (HS) or 22 * 6.33us (FS/LS)*/
100 ehci_writel(&ghcor->or_txfilltuning, tmp);
101
102 tmp = ehci_readl(&ghcor->or_txttfill_tuning);
103 tmp |= 0x2; /* set sheduler overhead to 2 * 6.333us */
104 ehci_writel(&ghcor->or_txttfill_tuning, tmp);
105 }