usb: renesas_usbhs: shrink spin lock area
[pandora-kernel.git] / drivers / usb / host / octeon2-common.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2010, 2011 Cavium Networks
7  */
8
9 #include <linux/module.h>
10 #include <linux/mutex.h>
11 #include <linux/delay.h>
12
13 #include <asm/octeon/octeon.h>
14 #include <asm/octeon/cvmx-uctlx-defs.h>
15
16 static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
17
18 static int octeon2_usb_clock_start_cnt;
19
20 void octeon2_usb_clocks_start(void)
21 {
22         u64 div;
23         union cvmx_uctlx_if_ena if_ena;
24         union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
25         union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
26         union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
27         int i;
28         unsigned long io_clk_64_to_ns;
29
30
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;
36
37         io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
38
39         /*
40          * Step 1: Wait for voltages stable.  That surely happened
41          * before starting the kernel.
42          *
43          * Step 2: Enable  SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
44          */
45         if_ena.u64 = 0;
46         if_ena.s.en = 1;
47         cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
48
49         /* Step 3: Configure the reference clock, PHY, and HCLK */
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;
58         /* 3a */
59         clk_rst_ctl.s.p_por = 1;
60         clk_rst_ctl.s.hrst = 0;
61         clk_rst_ctl.s.p_prst = 0;
62         clk_rst_ctl.s.h_clkdiv_rst = 0;
63         clk_rst_ctl.s.o_clkdiv_rst = 0;
64         clk_rst_ctl.s.h_clkdiv_en = 0;
65         clk_rst_ctl.s.o_clkdiv_en = 0;
66         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
67
68         /* 3b */
69         /* 12MHz crystal. */
70         clk_rst_ctl.s.p_refclk_sel = 0;
71         clk_rst_ctl.s.p_refclk_div = 0;
72         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
73
74         /* 3c */
75         div = octeon_get_io_clock_rate() / 130000000ull;
76
77         switch (div) {
78         case 0:
79                 div = 1;
80                 break;
81         case 1:
82         case 2:
83         case 3:
84         case 4:
85                 break;
86         case 5:
87                 div = 4;
88                 break;
89         case 6:
90         case 7:
91                 div = 6;
92                 break;
93         case 8:
94         case 9:
95         case 10:
96         case 11:
97                 div = 8;
98                 break;
99         default:
100                 div = 12;
101                 break;
102         }
103         clk_rst_ctl.s.h_div = div;
104         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
105         /* Read it back, */
106         clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
107         clk_rst_ctl.s.h_clkdiv_en = 1;
108         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
109         /* 3d */
110         clk_rst_ctl.s.h_clkdiv_rst = 1;
111         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
112
113         /* 3e: delay 64 io clocks */
114         ndelay(io_clk_64_to_ns);
115
116         /*
117          * Step 4: Program the power-on reset field in the UCTL
118          * clock-reset-control register.
119          */
120         clk_rst_ctl.s.p_por = 0;
121         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
122
123         /* Step 5:    Wait 1 ms for the PHY clock to start. */
124         mdelay(1);
125
126         /*
127          * Step 6: Program the reset input from automatic test
128          * equipment field in the UPHY CSR
129          */
130         uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
131         uphy_ctl_status.s.ate_reset = 1;
132         cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
133
134         /* Step 7: Wait for at least 10ns. */
135         ndelay(10);
136
137         /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
138         uphy_ctl_status.s.ate_reset = 0;
139         cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
140
141         /*
142          * Step 9: Wait for at least 20ns for UPHY to output PHY clock
143          * signals and OHCI_CLK48
144          */
145         ndelay(20);
146
147         /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
148         /* 10a */
149         clk_rst_ctl.s.o_clkdiv_rst = 1;
150         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
151
152         /* 10b */
153         clk_rst_ctl.s.o_clkdiv_en = 1;
154         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
155
156         /* 10c */
157         ndelay(io_clk_64_to_ns);
158
159         /*
160          * Step 11: Program the PHY reset field:
161          * UCTL0_CLK_RST_CTL[P_PRST] = 1
162          */
163         clk_rst_ctl.s.p_prst = 1;
164         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
165
166         /* Step 12: Wait 1 uS. */
167         udelay(1);
168
169         /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
170         clk_rst_ctl.s.hrst = 1;
171         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
172
173 end_clock:
174         /* Now we can set some other registers.  */
175
176         for (i = 0; i <= 1; i++) {
177                 port_ctl_status.u64 =
178                         cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
179                 /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
180                 port_ctl_status.s.txvreftune = 15;
181                 port_ctl_status.s.txrisetune = 1;
182                 port_ctl_status.s.txpreemphasistune = 1;
183                 cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
184                                port_ctl_status.u64);
185         }
186
187         /* Set uSOF cycle period to 60,000 bits. */
188         cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
189 exit:
190         mutex_unlock(&octeon2_usb_clocks_mutex);
191 }
192 EXPORT_SYMBOL(octeon2_usb_clocks_start);
193
194 void octeon2_usb_clocks_stop(void)
195 {
196         mutex_lock(&octeon2_usb_clocks_mutex);
197         octeon2_usb_clock_start_cnt--;
198         mutex_unlock(&octeon2_usb_clocks_mutex);
199 }
200 EXPORT_SYMBOL(octeon2_usb_clocks_stop);