aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/octeon2-common.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:33:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-23 15:33:02 -0400
commitc44dead70a841d90ddc01968012f323c33217c9e (patch)
tree85489ebe9b9a3413cd8ee197ffb40c8aa8d97e63 /drivers/usb/host/octeon2-common.c
parent99dff5856220a02b8711f2e8746413ea6e53ccf6 (diff)
parentd5f6db9e1aff6ccf1876224f152c0268b0c8a992 (diff)
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (205 commits) USB: EHCI: Remove SPARC_LEON {read,write}_be definitions from ehci.h USB: UHCI: Support big endian GRUSBHC HC sparc: add {read,write}*_be routines USB: UHCI: Add support for big endian descriptors USB: UHCI: Use ACCESS_ONCE rather than using a full compiler barrier USB: UHCI: Add support for big endian mmio usb-storage: Correct adjust_quirks to include latest flags usb/isp1760: Fix possible unlink problems usb/isp1760: Move function isp1760_endpoint_disable() within file. USB: remove remaining usages of hcd->state from usbcore and fix regression usb: musb: ux500: add configuration and build options for ux500 dma usb: musb: ux500: add dma glue layer for ux500 usb: musb: ux500: add dma name for ux500 usb: musb: ux500: add ux500 specific code for gadget side usb: musb: fix compile error usb-storage: fix up the unusual_realtek device list USB: gadget: f_audio: Fix invalid dereference of initdata EHCI: don't rescan interrupt QHs needlessly OHCI: fix regression caused by nVidia shutdown workaround USB: OTG: msm: Free VCCCX regulator even if we can't set the voltage ...
Diffstat (limited to 'drivers/usb/host/octeon2-common.c')
-rw-r--r--drivers/usb/host/octeon2-common.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c
index 72d672cfcf3..d9df423f3d1 100644
--- a/drivers/usb/host/octeon2-common.c
+++ b/drivers/usb/host/octeon2-common.c
@@ -3,18 +3,19 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2010 Cavium Networks 6 * Copyright (C) 2010, 2011 Cavium Networks
7 */ 7 */
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/mutex.h>
10#include <linux/delay.h> 11#include <linux/delay.h>
11 12
12#include <asm/atomic.h>
13
14#include <asm/octeon/octeon.h> 13#include <asm/octeon/octeon.h>
15#include <asm/octeon/cvmx-uctlx-defs.h> 14#include <asm/octeon/cvmx-uctlx-defs.h>
16 15
17static atomic_t octeon2_usb_clock_start_cnt = ATOMIC_INIT(0); 16static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
17
18static int octeon2_usb_clock_start_cnt;
18 19
19void octeon2_usb_clocks_start(void) 20void octeon2_usb_clocks_start(void)
20{ 21{
@@ -26,8 +27,12 @@ void octeon2_usb_clocks_start(void)
26 int i; 27 int i;
27 unsigned long io_clk_64_to_ns; 28 unsigned long io_clk_64_to_ns;
28 29
29 if (atomic_inc_return(&octeon2_usb_clock_start_cnt) != 1) 30
30 return; 31 mutex_lock(&octeon2_usb_clocks_mutex);
32
33 octeon2_usb_clock_start_cnt++;
34 if (octeon2_usb_clock_start_cnt != 1)
35 goto exit;
31 36
32 io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); 37 io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
33 38
@@ -43,6 +48,13 @@ void octeon2_usb_clocks_start(void)
43 48
44 /* Step 3: Configure the reference clock, PHY, and HCLK */ 49 /* Step 3: Configure the reference clock, PHY, and HCLK */
45 clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); 50 clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
51
52 /*
53 * If the UCTL looks like it has already been started, skip
54 * the initialization, otherwise bus errors are obtained.
55 */
56 if (clk_rst_ctl.s.hrst)
57 goto end_clock;
46 /* 3a */ 58 /* 3a */
47 clk_rst_ctl.s.p_por = 1; 59 clk_rst_ctl.s.p_por = 1;
48 clk_rst_ctl.s.hrst = 0; 60 clk_rst_ctl.s.hrst = 0;
@@ -158,28 +170,31 @@ void octeon2_usb_clocks_start(void)
158 clk_rst_ctl.s.hrst = 1; 170 clk_rst_ctl.s.hrst = 1;
159 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); 171 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
160 172
173end_clock:
161 /* Now we can set some other registers. */ 174 /* Now we can set some other registers. */
162 175
163 for (i = 0; i <= 1; i++) { 176 for (i = 0; i <= 1; i++) {
164 port_ctl_status.u64 = 177 port_ctl_status.u64 =
165 cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0)); 178 cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
166 /* Set txvreftune to 15 to obtain complient 'eye' diagram. */ 179 /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
167 port_ctl_status.s.txvreftune = 15; 180 port_ctl_status.s.txvreftune = 15;
181 port_ctl_status.s.txrisetune = 1;
182 port_ctl_status.s.txpreemphasistune = 1;
168 cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), 183 cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
169 port_ctl_status.u64); 184 port_ctl_status.u64);
170 } 185 }
186
187 /* Set uSOF cycle period to 60,000 bits. */
188 cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
189exit:
190 mutex_unlock(&octeon2_usb_clocks_mutex);
171} 191}
172EXPORT_SYMBOL(octeon2_usb_clocks_start); 192EXPORT_SYMBOL(octeon2_usb_clocks_start);
173 193
174void octeon2_usb_clocks_stop(void) 194void octeon2_usb_clocks_stop(void)
175{ 195{
176 union cvmx_uctlx_if_ena if_ena; 196 mutex_lock(&octeon2_usb_clocks_mutex);
177 197 octeon2_usb_clock_start_cnt--;
178 if (atomic_dec_return(&octeon2_usb_clock_start_cnt) != 0) 198 mutex_unlock(&octeon2_usb_clocks_mutex);
179 return;
180
181 if_ena.u64 = 0;
182 if_ena.s.en = 0;
183 cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
184} 199}
185EXPORT_SYMBOL(octeon2_usb_clocks_stop); 200EXPORT_SYMBOL(octeon2_usb_clocks_stop);