• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/mips/powertv/
1/*
2 *				powertv-usb.c
3 *
4 * Description:  ASIC-specific USB device setup and shutdown
5 *
6 * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
7 * Copyright (C) 2009 Cisco Systems, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 * Author:       Ken Eppinett
24 *               David Schleef <ds@schleef.org>
25 *
26 * NOTE: The bootloader allocates persistent memory at an address which is
27 * 16 MiB below the end of the highest address in KSEG0. All fixed
28 * address memory reservations must avoid this region.
29 */
30
31#include <linux/kernel.h>
32#include <linux/ioport.h>
33#include <linux/platform_device.h>
34#include <asm/mach-powertv/asic.h>
35#include <asm/mach-powertv/interrupts.h>
36
37/* misc_clk_ctl1 values */
38#define MCC1_30MHZ_POWERUP_SELECT	(1 << 14)
39#define MCC1_DIV9			(1 << 13)
40#define MCC1_ETHMIPS_POWERUP_SELECT	(1 << 11)
41#define MCC1_USB_POWERUP_SELECT		(1 << 1)
42#define MCC1_CLOCK108_POWERUP_SELECT	(1 << 0)
43
44/* Possible values for clock select */
45#define MCC1_USB_CLOCK_HIGH_Z		(0 << 4)
46#define MCC1_USB_CLOCK_48MHZ		(1 << 4)
47#define MCC1_USB_CLOCK_24MHZ		(2 << 4)
48#define MCC1_USB_CLOCK_6MHZ		(3 << 4)
49
50#define MCC1_CONFIG	(MCC1_30MHZ_POWERUP_SELECT |		\
51			 MCC1_DIV9 |				\
52			 MCC1_ETHMIPS_POWERUP_SELECT |		\
53			 MCC1_USB_POWERUP_SELECT |		\
54			 MCC1_CLOCK108_POWERUP_SELECT)
55
56/* misc_clk_ctl2 values */
57#define MCC2_GMII_GCLK_TO_PAD		(1 << 31)
58#define MCC2_ETHER125_0_CLOCK_SELECT	(1 << 29)
59#define MCC2_RMII_0_CLOCK_SELECT	(1 << 28)
60#define MCC2_GMII_TX0_CLOCK_SELECT	(1 << 27)
61#define MCC2_GMII_RX0_CLOCK_SELECT	(1 << 26)
62#define MCC2_ETHER125_1_CLOCK_SELECT	(1 << 24)
63#define MCC2_RMII_1_CLOCK_SELECT	(1 << 23)
64#define MCC2_GMII_TX1_CLOCK_SELECT	(1 << 22)
65#define MCC2_GMII_RX1_CLOCK_SELECT	(1 << 21)
66#define MCC2_ETHER125_2_CLOCK_SELECT	(1 << 19)
67#define MCC2_RMII_2_CLOCK_SELECT	(1 << 18)
68#define MCC2_GMII_TX2_CLOCK_SELECT	(1 << 17)
69#define MCC2_GMII_RX2_CLOCK_SELECT	(1 << 16)
70
71#define ETHER_CLK_CONFIG	(MCC2_GMII_GCLK_TO_PAD |	\
72				 MCC2_ETHER125_0_CLOCK_SELECT |	\
73				 MCC2_RMII_0_CLOCK_SELECT |	\
74				 MCC2_GMII_TX0_CLOCK_SELECT |	\
75				 MCC2_GMII_RX0_CLOCK_SELECT |	\
76				 MCC2_ETHER125_1_CLOCK_SELECT |	\
77				 MCC2_RMII_1_CLOCK_SELECT |	\
78				 MCC2_GMII_TX1_CLOCK_SELECT |	\
79				 MCC2_GMII_RX1_CLOCK_SELECT |	\
80				 MCC2_ETHER125_2_CLOCK_SELECT |	\
81				 MCC2_RMII_2_CLOCK_SELECT |	\
82				 MCC2_GMII_TX2_CLOCK_SELECT |	\
83				 MCC2_GMII_RX2_CLOCK_SELECT)
84
85/* misc_clk_ctl2 definitions for Gaia */
86#define FSX4A_REF_SELECT		(1 << 16)
87#define FSX4B_REF_SELECT		(1 << 17)
88#define FSX4C_REF_SELECT		(1 << 18)
89#define DDR_PLL_REF_SELECT		(1 << 19)
90#define MIPS_PLL_REF_SELECT		(1 << 20)
91
92/* Definitions for the QAM frequency select register FS432X4A4_QAM_CTL */
93#define QAM_FS_SDIV_SHIFT		29
94#define QAM_FS_MD_SHIFT			24
95#define QAM_FS_MD_MASK			0x1f	/* Cut down to 5 bits */
96#define QAM_FS_PE_SHIFT			8
97
98#define QAM_FS_DISABLE_DIVIDE_BY_3		(1 << 5)
99#define QAM_FS_ENABLE_PROGRAM			(1 << 4)
100#define	QAM_FS_ENABLE_OUTPUT			(1 << 3)
101#define	QAM_FS_SELECT_TEST_BYPASS		(1 << 2)
102#define	QAM_FS_DISABLE_DIGITAL_STANDBY		(1 << 1)
103#define QAM_FS_CHOOSE_FS			(1 << 0)
104
105/* Definitions for fs432x4a_ctl register */
106#define QAM_FS_NSDIV_54MHZ			(1 << 2)
107
108/* Definitions for bcm1_usb2_ctl register */
109#define BCM1_USB2_CTL_BISTOK				(1 << 11)
110#define BCM1_USB2_CTL_PORT2_SHIFT_JK			(1 << 7)
111#define BCM1_USB2_CTL_PORT1_SHIFT_JK			(1 << 6)
112#define BCM1_USB2_CTL_PORT2_FAST_EDGE			(1 << 5)
113#define BCM1_USB2_CTL_PORT1_FAST_EDGE			(1 << 4)
114#define BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH		(1 << 1)
115#define BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH	(1 << 0)
116
117/* Definitions for crt_spare register */
118#define CRT_SPARE_PORT2_SHIFT_JK			(1 << 21)
119#define CRT_SPARE_PORT1_SHIFT_JK			(1 << 20)
120#define CRT_SPARE_PORT2_FAST_EDGE			(1 << 19)
121#define CRT_SPARE_PORT1_FAST_EDGE			(1 << 18)
122#define CRT_SPARE_DIVIDE_BY_9_FROM_432			(1 << 17)
123#define CRT_SPARE_USB_DIVIDE_BY_9			(1 << 16)
124
125/* Definitions for usb2_stbus_obc register */
126#define USB_STBUS_OBC_STORE32_LOAD32			0x3
127
128/* Definitions for usb2_stbus_mess_size register */
129#define USB2_STBUS_MESS_SIZE_2				0x1	/* 2 packets */
130
131/* Definitions for usb2_stbus_chunk_size register */
132#define USB2_STBUS_CHUNK_SIZE_2				0x1	/* 2 packets */
133
134/* Definitions for usb2_strap register */
135#define USB2_STRAP_HFREQ_SELECT				0x1
136
137/*
138 * USB Host Resource Definition
139 */
140
141static struct resource ehci_resources[] = {
142	{
143		.parent = &asic_resource,
144		.start  = 0,
145		.end    = 0xff,
146		.flags  = IORESOURCE_MEM,
147	},
148	{
149		.start  = irq_usbehci,
150		.end    = irq_usbehci,
151		.flags  = IORESOURCE_IRQ,
152	},
153};
154
155static u64 ehci_dmamask = 0xffffffffULL;
156
157static struct platform_device ehci_device = {
158	.name = "powertv-ehci",
159	.id = 0,
160	.num_resources = 2,
161	.resource = ehci_resources,
162	.dev = {
163		.dma_mask = &ehci_dmamask,
164		.coherent_dma_mask = 0xffffffff,
165	},
166};
167
168static struct resource ohci_resources[] = {
169	{
170		.parent = &asic_resource,
171		.start  = 0,
172		.end    = 0xff,
173		.flags  = IORESOURCE_MEM,
174	},
175	{
176		.start  = irq_usbohci,
177		.end    = irq_usbohci,
178		.flags  = IORESOURCE_IRQ,
179	},
180};
181
182static u64 ohci_dmamask = 0xffffffffULL;
183
184static struct platform_device ohci_device = {
185	.name = "powertv-ohci",
186	.id = 0,
187	.num_resources = 2,
188	.resource = ohci_resources,
189	.dev = {
190		.dma_mask = &ohci_dmamask,
191		.coherent_dma_mask = 0xffffffff,
192	},
193};
194
195static unsigned usb_users;
196static DEFINE_SPINLOCK(usb_regs_lock);
197
198/*
199 *
200 * fs_update - set frequency synthesizer for USB
201 * @pe_bits		Phase tap setting
202 * @md_bits		Coarse selector bus for algorithm of phase tap
203 * @sdiv_bits		Output divider setting
204 * @disable_div_by_3	Either QAM_FS_DISABLE_DIVIDE_BY_3 or zero
205 * @standby		Either QAM_FS_DISABLE_DIGITAL_STANDBY or zero
206 *
207 * QAM frequency selection code, which affects the frequency at which USB
208 * runs. The frequency is calculated as:
209 *                             2^15 * ndiv * Fin
210 * Fout = ------------------------------------------------------------
211 *        (sdiv * (ipe * (1 + md/32) - (ipe - 2^15)*(1 + (md + 1)/32)))
212 * where:
213 * Fin		54 MHz
214 * ndiv		QAM_FS_NSDIV_54MHZ ? 8 : 16
215 * sdiv		1 << (sdiv_bits + 1)
216 * ipe		Same as pe_bits
217 * md		A five-bit, two's-complement integer (range [-16, 15]), which
218 *		is the lower 5 bits of md_bits.
219 */
220static void fs_update(u32 pe_bits, int md_bits, u32 sdiv_bits,
221	u32 disable_div_by_3, u32 standby)
222{
223	u32 val;
224
225	val = ((sdiv_bits << QAM_FS_SDIV_SHIFT) |
226		((md_bits & QAM_FS_MD_MASK) << QAM_FS_MD_SHIFT) |
227		(pe_bits << QAM_FS_PE_SHIFT) |
228		QAM_FS_ENABLE_OUTPUT |
229		standby |
230		disable_div_by_3);
231	asic_write(val, fs432x4b4_usb_ctl);
232	asic_write(val | QAM_FS_ENABLE_PROGRAM, fs432x4b4_usb_ctl);
233	asic_write(val | QAM_FS_ENABLE_PROGRAM | QAM_FS_CHOOSE_FS,
234		fs432x4b4_usb_ctl);
235}
236
237/*
238 * usb_eye_configure - for optimizing the shape USB eye waveform
239 * @set:	Bits to set in the register
240 * @clear:	Bits to clear in the register; each bit with a one will
241 *		be set in the register, zero bits will not be modified
242 */
243static void usb_eye_configure(u32 set, u32 clear)
244{
245	u32 old;
246
247	old = asic_read(crt_spare);
248	old |= set;
249	old &= ~clear;
250	asic_write(old, crt_spare);
251}
252
253/*
254 * platform_configure_usb - usb configuration based on platform type.
255 */
256static void platform_configure_usb(void)
257{
258	u32 bcm1_usb2_ctl_value;
259	enum asic_type asic_type;
260	unsigned long flags;
261
262	spin_lock_irqsave(&usb_regs_lock, flags);
263	usb_users++;
264
265	if (usb_users != 1) {
266		spin_unlock_irqrestore(&usb_regs_lock, flags);
267		return;
268	}
269
270	asic_type = platform_get_asic();
271
272	switch (asic_type) {
273	case ASIC_ZEUS:
274		fs_update(0x0000, -15, 0x02, 0, 0);
275		bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
276			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
277		break;
278
279	case ASIC_CRONUS:
280	case ASIC_CRONUSLITE:
281		usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9);
282		fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
283			QAM_FS_DISABLE_DIGITAL_STANDBY);
284		bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
285			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
286		break;
287
288	case ASIC_CALLIOPE:
289		fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3,
290			QAM_FS_DISABLE_DIGITAL_STANDBY);
291
292		switch (platform_get_family()) {
293		case FAMILY_1500VZE:
294			break;
295
296		case FAMILY_1500VZF:
297			usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
298				CRT_SPARE_PORT1_SHIFT_JK |
299				CRT_SPARE_PORT2_FAST_EDGE |
300				CRT_SPARE_PORT1_FAST_EDGE, 0);
301			break;
302
303		default:
304			usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
305				CRT_SPARE_PORT1_SHIFT_JK, 0);
306			break;
307		}
308
309		bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
310			BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
311			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
312		break;
313
314	case ASIC_GAIA:
315		fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
316			QAM_FS_DISABLE_DIGITAL_STANDBY);
317		bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
318			BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
319			BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
320		break;
321
322	default:
323		pr_err("Unknown ASIC type: %d\n", asic_type);
324		bcm1_usb2_ctl_value = 0;
325		break;
326	}
327
328	/* turn on USB power */
329	asic_write(0, usb2_strap);
330	/* Enable all OHCI interrupts */
331	asic_write(bcm1_usb2_ctl_value, usb2_control);
332	/* usb2_stbus_obc store32/load32 */
333	asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc);
334	/* usb2_stbus_mess_size 2 packets */
335	asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size);
336	/* usb2_stbus_chunk_size 2 packets */
337	asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size);
338	spin_unlock_irqrestore(&usb_regs_lock, flags);
339}
340
341static void platform_unconfigure_usb(void)
342{
343	unsigned long flags;
344
345	spin_lock_irqsave(&usb_regs_lock, flags);
346	usb_users--;
347	if (usb_users == 0)
348		asic_write(USB2_STRAP_HFREQ_SELECT, usb2_strap);
349	spin_unlock_irqrestore(&usb_regs_lock, flags);
350}
351
352/*
353 * Set up the USB EHCI interface
354 */
355void platform_configure_usb_ehci()
356{
357	platform_configure_usb();
358}
359EXPORT_SYMBOL(platform_configure_usb_ehci);
360
361/*
362 * Set up the USB OHCI interface
363 */
364void platform_configure_usb_ohci()
365{
366	platform_configure_usb();
367}
368EXPORT_SYMBOL(platform_configure_usb_ohci);
369
370/*
371 * Shut the USB EHCI interface down
372 */
373void platform_unconfigure_usb_ehci()
374{
375	platform_unconfigure_usb();
376}
377EXPORT_SYMBOL(platform_unconfigure_usb_ehci);
378
379/*
380 * Shut the USB OHCI interface down
381 */
382void platform_unconfigure_usb_ohci()
383{
384	platform_unconfigure_usb();
385}
386EXPORT_SYMBOL(platform_unconfigure_usb_ohci);
387
388/**
389 * platform_devices_init - sets up USB device resourse.
390 */
391int __init platform_usb_devices_init(struct platform_device **ehci_dev,
392	struct platform_device **ohci_dev)
393{
394	*ehci_dev = &ehci_device;
395	ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
396	ehci_resources[0].end += ehci_resources[0].start;
397
398	*ohci_dev = &ohci_device;
399	ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
400	ohci_resources[0].end += ohci_resources[0].start;
401
402	return 0;
403}
404