1e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein/*
2e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein * drivers/usb/host/ehci-orion.c
3e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein *
4e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein * Tzachi Perelstein <tzachi@marvell.com>
5e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein *
6e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein * This file is licensed under  the terms of the GNU General Public
7e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein * License version 2. This program is licensed "as is" without any
8e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein * warranty of any kind, whether express or implied.
9e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein */
10e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
11e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#include <linux/kernel.h>
12e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#include <linux/module.h>
13e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#include <linux/platform_device.h>
1492aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek#include <linux/mbus.h>
156f088f1d215be5250582b974f83f0e3aa6ad3a28Lennert Buytenhek#include <plat/ehci-orion.h>
16e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
17e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define rdl(off)	__raw_readl(hcd->regs + (off))
18e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define wrl(off, val)	__raw_writel((val), hcd->regs + (off))
19e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
20e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_CMD			0x140
21e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_MODE		0x1a8
2292aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek#define USB_CAUSE		0x310
2392aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek#define USB_MASK		0x314
2492aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek#define USB_WINDOW_CTRL(i)	(0x320 + ((i) << 4))
2592aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek#define USB_WINDOW_BASE(i)	(0x324 + ((i) << 4))
26e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_IPG			0x360
27e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_PHY_PWR_CTRL	0x400
28e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_PHY_TX_CTRL		0x420
29e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_PHY_RX_CTRL		0x430
30e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_PHY_IVREF_CTRL	0x440
31e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein#define USB_PHY_TST_GRP_CTRL	0x450
32e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
33e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein/*
34e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein * Implement Orion USB controller specification guidelines
35e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein */
36fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitritstatic void orion_usb_phy_v1_setup(struct usb_hcd *hcd)
37e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein{
38fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	/* The below GLs are according to the Orion Errata document */
39e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
40e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * Clear interrupt cause and mask
41e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
42e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_CAUSE, 0);
43e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_MASK, 0);
44e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
45e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
46e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * Reset controller
47e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
48e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_CMD, rdl(USB_CMD) | 0x2);
49e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	while (rdl(USB_CMD) & 0x2);
50e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
51e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
52e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-10: Set IPG for non start of frame packets
53e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * Bits[14:8]=0xc
54e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
55e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_IPG, (rdl(USB_IPG) & ~0x7f00) | 0xc00);
56e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
57e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
58e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-9: USB 2.0 Power Control
59e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * BG_VSEL[7:6]=0x1
60e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
61e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_PHY_PWR_CTRL, (rdl(USB_PHY_PWR_CTRL) & ~0xc0)| 0x40);
62e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
63e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
64e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-1: USB PHY Tx Control - force calibration to '8'
65e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * TXDATA_BLOCK_EN[21]=0x1, EXT_RCAL_EN[13]=0x1, IMP_CAL[6:3]=0x8
66e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
67e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_PHY_TX_CTRL, (rdl(USB_PHY_TX_CTRL) & ~0x78) | 0x202040);
68e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
69e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
70e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-3 GL# USB-9: USB PHY Rx Control
71e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * RXDATA_BLOCK_LENGHT[31:30]=0x3, EDGE_DET_SEL[27:26]=0,
72e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * CDR_FASTLOCK_EN[21]=0, DISCON_THRESHOLD[9:8]=0, SQ_THRESH[7:4]=0x1
73e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
74e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_PHY_RX_CTRL, (rdl(USB_PHY_RX_CTRL) & ~0xc2003f0) | 0xc0000010);
75e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
76e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
77e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-3 GL# USB-9: USB PHY IVREF Control
78e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * PLLVDD12[1:0]=0x2, RXVDD[5:4]=0x3, Reserved[19]=0
79e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
80e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_PHY_IVREF_CTRL, (rdl(USB_PHY_IVREF_CTRL) & ~0x80003 ) | 0x32);
81e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
82e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
83e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-3 GL# USB-9: USB PHY Test Group Control
84e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * REG_FIFO_SQ_RST[15]=0
85e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
86e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_PHY_TST_GRP_CTRL, rdl(USB_PHY_TST_GRP_CTRL) & ~0x8000);
87e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
88e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
89e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * Stop and reset controller
90e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
91e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_CMD, rdl(USB_CMD) & ~0x1);
92e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_CMD, rdl(USB_CMD) | 0x2);
93e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	while (rdl(USB_CMD) & 0x2);
94e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
95e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
96e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-5 Streaming disable REG_USB_MODE[4]=1
97e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * TBD: This need to be done after each reset!
98e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * GL# USB-4 Setup USB Host mode
99e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
100e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	wrl(USB_MODE, 0x13);
101e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein}
102e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
103e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinstatic int ehci_orion_setup(struct usb_hcd *hcd)
104e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein{
105e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
106e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	int retval;
107e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
108bcf40815e0cda371cecc242398fe39b873bb1047Matthieu CASTET	hcd->has_tt = 1;
109bcf40815e0cda371cecc242398fe39b873bb1047Matthieu CASTET
110e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	retval = ehci_halt(ehci);
111e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (retval)
112e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		return retval;
113e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
114e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
115e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * data structure init
116e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
117e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	retval = ehci_init(hcd);
118e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (retval)
119e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		return retval;
120e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
121bcf40815e0cda371cecc242398fe39b873bb1047Matthieu CASTET	ehci_reset(ehci);
122129bd474a80726247e5b1c61fe66a413e63053bcLennert Buytenhek
123e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	ehci_port_power(ehci, 0);
124e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
125e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	return retval;
126e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein}
127e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
128e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinstatic const struct hc_driver ehci_orion_hc_driver = {
129e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.description = hcd_name,
130e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.product_desc = "Marvell Orion EHCI",
131e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.hcd_priv_size = sizeof(struct ehci_hcd),
132e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
133e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
134e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * generic hardware linkage
135e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
136e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.irq = ehci_irq,
137e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.flags = HCD_MEMORY | HCD_USB2,
138e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
139e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
140e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * basic lifecycle operations
141e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
142e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.reset = ehci_orion_setup,
143e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.start = ehci_run,
144e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.stop = ehci_stop,
145e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.shutdown = ehci_shutdown,
146e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
147e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
148e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * managing i/o requests and associated device resources
149e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
150e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.urb_enqueue = ehci_urb_enqueue,
151e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.urb_dequeue = ehci_urb_dequeue,
152e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.endpoint_disable = ehci_endpoint_disable,
153b18ffd49e86102a9ed0a1cc83fdafe3891e844e5Alan Stern	.endpoint_reset = ehci_endpoint_reset,
154e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
155e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
156e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * scheduling support
157e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
158e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.get_frame_number = ehci_get_frame,
159e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
160e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
161e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 * root hub support
162e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
163e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.hub_status_data = ehci_hub_status_data,
164e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.hub_control = ehci_hub_control,
165e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.bus_suspend = ehci_bus_suspend,
166e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.bus_resume = ehci_bus_resume,
167a8e5177583e975fc1f7c621c93956f494df9b979Alan Stern	.relinquish_port = ehci_relinquish_port,
1683a31155cfff0935e4b178f3dca733d2d60d2eb8dAlan Stern	.port_handed_over = ehci_port_handed_over,
169914b701280a76f96890ad63eb0fa99bf204b961cAlan Stern
170914b701280a76f96890ad63eb0fa99bf204b961cAlan Stern	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
171e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein};
172e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
17392aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhekstatic void __init
17492aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhekehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
17563a9332b232bdab0df6ef18a9f39e8d58a82bda4Andrew Lunn			     const struct mbus_dram_target_info *dram)
17692aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek{
17792aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	int i;
17892aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek
17992aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	for (i = 0; i < 4; i++) {
18092aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek		wrl(USB_WINDOW_CTRL(i), 0);
18192aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek		wrl(USB_WINDOW_BASE(i), 0);
18292aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	}
18392aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek
18492aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	for (i = 0; i < dram->num_cs; i++) {
18563a9332b232bdab0df6ef18a9f39e8d58a82bda4Andrew Lunn		const struct mbus_dram_window *cs = dram->cs + i;
18692aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek
18792aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek		wrl(USB_WINDOW_CTRL(i), ((cs->size - 1) & 0xffff0000) |
18892aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek					(cs->mbus_attr << 8) |
18992aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek					(dram->mbus_dram_target_id << 4) | 1);
19092aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek		wrl(USB_WINDOW_BASE(i), cs->base);
19192aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	}
19292aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek}
19392aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek
194dc2f2b7505c195a6963fc07b549e269eee417261Uwe Kleine-Königstatic int __devinit ehci_orion_drv_probe(struct platform_device *pdev)
195e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein{
19692aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	struct orion_ehci_data *pd = pdev->dev.platform_data;
19763a9332b232bdab0df6ef18a9f39e8d58a82bda4Andrew Lunn	const struct mbus_dram_target_info *dram;
198e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	struct resource *res;
199e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	struct usb_hcd *hcd;
200e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	struct ehci_hcd *ehci;
201e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	void __iomem *regs;
202e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	int irq, err;
203e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
204e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (usb_disabled())
205e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		return -ENODEV;
206e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
207e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	pr_debug("Initializing Orion-SoC USB Host Controller\n");
208e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
209e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	irq = platform_get_irq(pdev, 0);
210e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (irq <= 0) {
211e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		dev_err(&pdev->dev,
212e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein			"Found HC with no IRQ. Check %s setup!\n",
2137071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers			dev_name(&pdev->dev));
214e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		err = -ENODEV;
215e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		goto err1;
216e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	}
217e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
218e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
219e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (!res) {
220e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		dev_err(&pdev->dev,
221e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein			"Found HC with no register addr. Check %s setup!\n",
2227071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers			dev_name(&pdev->dev));
223e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		err = -ENODEV;
224e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		goto err1;
225e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	}
226e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
2275672b7e6a99a91838c1b595a80d43006bcd9a178H Hartley Sweeten	if (!request_mem_region(res->start, resource_size(res),
228e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein				ehci_orion_hc_driver.description)) {
229e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		dev_dbg(&pdev->dev, "controller already in use\n");
230e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		err = -EBUSY;
231e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		goto err1;
232e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	}
233e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
2345672b7e6a99a91838c1b595a80d43006bcd9a178H Hartley Sweeten	regs = ioremap(res->start, resource_size(res));
235e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (regs == NULL) {
236e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		dev_dbg(&pdev->dev, "error mapping memory\n");
237e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		err = -EFAULT;
238e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		goto err2;
239e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	}
240e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
241e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	hcd = usb_create_hcd(&ehci_orion_hc_driver,
2427071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers			&pdev->dev, dev_name(&pdev->dev));
243e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (!hcd) {
244e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		err = -ENOMEM;
245e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		goto err3;
246e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	}
247e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
248e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	hcd->rsrc_start = res->start;
2495672b7e6a99a91838c1b595a80d43006bcd9a178H Hartley Sweeten	hcd->rsrc_len = resource_size(res);
250e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	hcd->regs = regs;
251e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
252e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	ehci = hcd_to_ehci(hcd);
253e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	ehci->caps = hcd->regs + 0x100;
254e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	ehci->regs = hcd->regs + 0x100 +
255c430131a02d677aa708f56342c1565edfdacb3c0Jan Andersson		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
256e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
257a8e5177583e975fc1f7c621c93956f494df9b979Alan Stern	hcd->has_tt = 1;
258e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	ehci->sbrn = 0x20;
259e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
260e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	/*
26192aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	 * (Re-)program MBUS remapping windows if we are asked to.
26292aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	 */
26363a9332b232bdab0df6ef18a9f39e8d58a82bda4Andrew Lunn	dram = mv_mbus_dram_info();
26463a9332b232bdab0df6ef18a9f39e8d58a82bda4Andrew Lunn	if (dram)
26563a9332b232bdab0df6ef18a9f39e8d58a82bda4Andrew Lunn		ehci_orion_conf_mbus_windows(hcd, dram);
26692aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek
26792aecfa95523384923b52c8ddaf948fc02a53e82Lennert Buytenhek	/*
268fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	 * setup Orion USB controller.
269e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	 */
270fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	switch (pd->phy_version) {
271fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	case EHCI_PHY_NA:	/* dont change USB phy settings */
272fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit		break;
273fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	case EHCI_PHY_ORION:
274fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit		orion_usb_phy_v1_setup(hcd);
275fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit		break;
276fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	case EHCI_PHY_DD:
277fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	case EHCI_PHY_KW:
278fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	default:
279fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit		printk(KERN_WARNING "Orion ehci -USB phy version isn't supported.\n");
280fb6f552930e52699c8ac452c5a79ec3e97e6fc73Ronen Shitrit	}
281e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
282b5dd18d8747010e3f3eb1cc76a49f94291938559Yong Zhang	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
283e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	if (err)
284e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein		goto err4;
285e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
286e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	return 0;
287e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
288e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinerr4:
289e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	usb_put_hcd(hcd);
290e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinerr3:
291e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	iounmap(regs);
292e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinerr2:
2935672b7e6a99a91838c1b595a80d43006bcd9a178H Hartley Sweeten	release_mem_region(res->start, resource_size(res));
294e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinerr1:
295e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	dev_err(&pdev->dev, "init %s fail, %d\n",
2967071a3ce0ca058ad2a9e3e8c33f30fb0bce62005Kay Sievers		dev_name(&pdev->dev), err);
297e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
298e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	return err;
299e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein}
300e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
301e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinstatic int __exit ehci_orion_drv_remove(struct platform_device *pdev)
302e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein{
303e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	struct usb_hcd *hcd = platform_get_drvdata(pdev);
304e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
305e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	usb_remove_hcd(hcd);
306e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	iounmap(hcd->regs);
307e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
308e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	usb_put_hcd(hcd);
309e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
310e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	return 0;
311e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein}
312e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
313e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi PerelsteinMODULE_ALIAS("platform:orion-ehci");
314e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein
315e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelsteinstatic struct platform_driver ehci_orion_driver = {
316e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.probe		= ehci_orion_drv_probe,
317e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.remove		= __exit_p(ehci_orion_drv_remove),
318e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.shutdown	= usb_hcd_platform_shutdown,
319e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein	.driver.name	= "orion-ehci",
320e96ffe2f9debd5fdc53144259d9e5faa514736b9Tzachi Perelstein};
321