From f5ced99725d05f521ef0f597e688c19835e59c55 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Apr 2011 10:54:20 -0700 Subject: USB: octeon2-common: Don't reinitialize the clocks. The UCTL clock initialization will cause the ehci and ohci blocks to become inoperable if the clocks are reinitialized. Check to see if the clocks have already been initialized. Also use a mutex to protect the clock initialization code so that there can be no attempt to use the clocks before they are fully configured. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/octeon2-common.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'drivers/usb/host/octeon2-common.c') diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c index 72d672cfcf39..5a0feed03561 100644 --- a/drivers/usb/host/octeon2-common.c +++ b/drivers/usb/host/octeon2-common.c @@ -3,18 +3,19 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2010 Cavium Networks + * Copyright (C) 2010, 2011 Cavium Networks */ #include +#include #include -#include - #include #include -static atomic_t octeon2_usb_clock_start_cnt = ATOMIC_INIT(0); +static DEFINE_MUTEX(octeon2_usb_clocks_mutex); + +static int octeon2_usb_clock_start_cnt; void octeon2_usb_clocks_start(void) { @@ -26,8 +27,12 @@ void octeon2_usb_clocks_start(void) int i; unsigned long io_clk_64_to_ns; - if (atomic_inc_return(&octeon2_usb_clock_start_cnt) != 1) - return; + + mutex_lock(&octeon2_usb_clocks_mutex); + + octeon2_usb_clock_start_cnt++; + if (octeon2_usb_clock_start_cnt != 1) + goto exit; io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); @@ -43,6 +48,13 @@ void octeon2_usb_clocks_start(void) /* Step 3: Configure the reference clock, PHY, and HCLK */ clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0)); + + /* + * If the UCTL looks like it has already been started, skip + * the initialization, otherwise bus errors are obtained. + */ + if (clk_rst_ctl.s.hrst) + goto end_clock; /* 3a */ clk_rst_ctl.s.p_por = 1; clk_rst_ctl.s.hrst = 0; @@ -158,6 +170,7 @@ void octeon2_usb_clocks_start(void) clk_rst_ctl.s.hrst = 1; cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); +end_clock: /* Now we can set some other registers. */ for (i = 0; i <= 1; i++) { @@ -168,18 +181,15 @@ void octeon2_usb_clocks_start(void) cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), port_ctl_status.u64); } +exit: + mutex_unlock(&octeon2_usb_clocks_mutex); } EXPORT_SYMBOL(octeon2_usb_clocks_start); void octeon2_usb_clocks_stop(void) { - union cvmx_uctlx_if_ena if_ena; - - if (atomic_dec_return(&octeon2_usb_clock_start_cnt) != 0) - return; - - if_ena.u64 = 0; - if_ena.s.en = 0; - cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64); + mutex_lock(&octeon2_usb_clocks_mutex); + octeon2_usb_clock_start_cnt--; + mutex_unlock(&octeon2_usb_clocks_mutex); } EXPORT_SYMBOL(octeon2_usb_clocks_stop); -- cgit v1.2.3 From bf5417152154038bbae429e2357731b1dad03328 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Apr 2011 10:54:21 -0700 Subject: usb: octeon2-common.c: Configure ports for proper electrical characteristics. Additional PHY tuning is needed to obtain compliant 'eye' diagram electrical characteristics. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/octeon2-common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host/octeon2-common.c') diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c index 5a0feed03561..aef6364d6314 100644 --- a/drivers/usb/host/octeon2-common.c +++ b/drivers/usb/host/octeon2-common.c @@ -176,8 +176,10 @@ end_clock: for (i = 0; i <= 1; i++) { port_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0)); - /* Set txvreftune to 15 to obtain complient 'eye' diagram. */ + /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */ port_ctl_status.s.txvreftune = 15; + port_ctl_status.s.txrisetune = 1; + port_ctl_status.s.txpreemphasistune = 1; cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), port_ctl_status.u64); } -- cgit v1.2.3 From 14be249c969817e05c4f1ce042906e1c5be68873 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Apr 2011 10:54:22 -0700 Subject: usb: Configure octeon2 glue logic for proper uSOF cycle period. The reset value of the uSOF cycle period is incorrect. Set it to 60,000 bits. Without this, several commercial USB flash memory devices and hubs fail to work properly. Signed-off-by: David Daney Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/octeon2-common.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/usb/host/octeon2-common.c') diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c index aef6364d6314..d9df423f3d12 100644 --- a/drivers/usb/host/octeon2-common.c +++ b/drivers/usb/host/octeon2-common.c @@ -183,6 +183,9 @@ end_clock: cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0), port_ctl_status.u64); } + + /* Set uSOF cycle period to 60,000 bits. */ + cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull); exit: mutex_unlock(&octeon2_usb_clocks_mutex); } -- cgit v1.2.3