6ab05c511618132cd0fdc3aba15ec9f6db391d16
2 * drivers/usb/host/ehci-oxnas.c
4 * Tzachi Perelstein <tzachi@marvell.com>
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.
11 #include <asm/arch/hardware.h>
12 #include <asm/arch/sysctl.h>
13 #include <asm/arch/clock.h>
17 static struct ehci_hcor
*ghcor
;
19 static int start_oxnas_usb_ehci(void)
21 #ifdef CONFIG_USB_PLLB_CLK
22 reset_block(SYS_CTRL_RST_PLLB
, 0);
23 enable_clock(SYS_CTRL_CLK_REF600
);
25 writel((1 << PLLB_ENSAT
) | (1 << PLLB_OUTDIV
) | (2 << PLLB_REFDIV
),
27 /* 600MHz pllb divider for 12MHz */
28 writel(PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0), SEC_CTRL_PLLB_DIV_CTRL
);
30 /* ref 300 divider for 12MHz */
31 writel(REF300_DIV_INT(25) | REF300_DIV_FRAC(0), SYS_CTRL_REF300_DIV
);
34 /* Ensure the USB block is properly reset */
35 reset_block(SYS_CTRL_RST_USBHS
, 1);
36 reset_block(SYS_CTRL_RST_USBHS
, 0);
38 reset_block(SYS_CTRL_RST_USBHSPHYA
, 1);
39 reset_block(SYS_CTRL_RST_USBHSPHYA
, 0);
41 reset_block(SYS_CTRL_RST_USBHSPHYB
, 1);
42 reset_block(SYS_CTRL_RST_USBHSPHYB
, 0);
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
);
49 writel((1UL << USBHSPHY_TEST_CLK
) |
50 (2UL << USBHSPHY_TEST_ADD
) |
51 (0xe0UL
<< USBHSPHY_TEST_DIN
), SYS_CTRL_USBHSPHY_CTRL
);
53 writel((0xfUL
<< USBHSPHY_TEST_ADD
) |
54 (0xaaUL
<< USBHSPHY_TEST_DIN
), SYS_CTRL_USBHSPHY_CTRL
);
56 writel((1UL << USBHSPHY_TEST_CLK
) |
57 (0xfUL
<< USBHSPHY_TEST_ADD
) |
58 (0xaaUL
<< USBHSPHY_TEST_DIN
), SYS_CTRL_USBHSPHY_CTRL
);
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
);
65 /* Enable the clock to the USB block */
66 enable_clock(SYS_CTRL_CLK_USBHS
);
70 int ehci_hcd_init(int index
, enum usb_init_type init
, struct ehci_hccr
**hccr
,
71 struct ehci_hcor
**hcor
)
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
)));
81 int ehci_hcd_stop(int index
)
83 reset_block(SYS_CTRL_RST_USBHS
, 1);
84 disable_clock(SYS_CTRL_CLK_USBHS
);
88 extern void __ehci_set_usbmode(int index
);
89 void ehci_set_usbmode(int index
)
91 #define or_txttfill_tuning _reserved_1_[0]
94 __ehci_set_usbmode(index
);
96 tmp
= ehci_readl(&ghcor
->or_txfilltuning
);
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
);
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
);