USB: Add EHCI and OHCH glue for OCTEON II SOCs.
[firefly-linux-kernel-4.4.55.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 Cavium Networks
7  */
8
9 #include <linux/module.h>
10 #include <linux/delay.h>
11
12 #include <asm/atomic.h>
13
14 #include <asm/octeon/octeon.h>
15 #include <asm/octeon/cvmx-uctlx-defs.h>
16
17 static atomic_t  octeon2_usb_clock_start_cnt = ATOMIC_INIT(0);
18
19 void octeon2_usb_clocks_start(void)
20 {
21         u64 div;
22         union cvmx_uctlx_if_ena if_ena;
23         union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
24         union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
25         union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
26         int i;
27         unsigned long io_clk_64_to_ns;
28
29         if (atomic_inc_return(&octeon2_usb_clock_start_cnt) != 1)
30                 return;
31
32         io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
33
34         /*
35          * Step 1: Wait for voltages stable.  That surely happened
36          * before starting the kernel.
37          *
38          * Step 2: Enable  SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
39          */
40         if_ena.u64 = 0;
41         if_ena.s.en = 1;
42         cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
43
44         /* Step 3: Configure the reference clock, PHY, and HCLK */
45         clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
46         /* 3a */
47         clk_rst_ctl.s.p_por = 1;
48         clk_rst_ctl.s.hrst = 0;
49         clk_rst_ctl.s.p_prst = 0;
50         clk_rst_ctl.s.h_clkdiv_rst = 0;
51         clk_rst_ctl.s.o_clkdiv_rst = 0;
52         clk_rst_ctl.s.h_clkdiv_en = 0;
53         clk_rst_ctl.s.o_clkdiv_en = 0;
54         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
55
56         /* 3b */
57         /* 12MHz crystal. */
58         clk_rst_ctl.s.p_refclk_sel = 0;
59         clk_rst_ctl.s.p_refclk_div = 0;
60         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
61
62         /* 3c */
63         div = octeon_get_io_clock_rate() / 130000000ull;
64
65         switch (div) {
66         case 0:
67                 div = 1;
68                 break;
69         case 1:
70         case 2:
71         case 3:
72         case 4:
73                 break;
74         case 5:
75                 div = 4;
76                 break;
77         case 6:
78         case 7:
79                 div = 6;
80                 break;
81         case 8:
82         case 9:
83         case 10:
84         case 11:
85                 div = 8;
86                 break;
87         default:
88                 div = 12;
89                 break;
90         }
91         clk_rst_ctl.s.h_div = div;
92         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
93         /* Read it back, */
94         clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
95         clk_rst_ctl.s.h_clkdiv_en = 1;
96         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
97         /* 3d */
98         clk_rst_ctl.s.h_clkdiv_rst = 1;
99         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
100
101         /* 3e: delay 64 io clocks */
102         ndelay(io_clk_64_to_ns);
103
104         /*
105          * Step 4: Program the power-on reset field in the UCTL
106          * clock-reset-control register.
107          */
108         clk_rst_ctl.s.p_por = 0;
109         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
110
111         /* Step 5:    Wait 1 ms for the PHY clock to start. */
112         mdelay(1);
113
114         /*
115          * Step 6: Program the reset input from automatic test
116          * equipment field in the UPHY CSR
117          */
118         uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
119         uphy_ctl_status.s.ate_reset = 1;
120         cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
121
122         /* Step 7: Wait for at least 10ns. */
123         ndelay(10);
124
125         /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
126         uphy_ctl_status.s.ate_reset = 0;
127         cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
128
129         /*
130          * Step 9: Wait for at least 20ns for UPHY to output PHY clock
131          * signals and OHCI_CLK48
132          */
133         ndelay(20);
134
135         /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
136         /* 10a */
137         clk_rst_ctl.s.o_clkdiv_rst = 1;
138         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
139
140         /* 10b */
141         clk_rst_ctl.s.o_clkdiv_en = 1;
142         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
143
144         /* 10c */
145         ndelay(io_clk_64_to_ns);
146
147         /*
148          * Step 11: Program the PHY reset field:
149          * UCTL0_CLK_RST_CTL[P_PRST] = 1
150          */
151         clk_rst_ctl.s.p_prst = 1;
152         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
153
154         /* Step 12: Wait 1 uS. */
155         udelay(1);
156
157         /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
158         clk_rst_ctl.s.hrst = 1;
159         cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
160
161         /* Now we can set some other registers.  */
162
163         for (i = 0; i <= 1; i++) {
164                 port_ctl_status.u64 =
165                         cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
166                 /* Set txvreftune to 15 to obtain complient 'eye' diagram. */
167                 port_ctl_status.s.txvreftune = 15;
168                 cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
169                                port_ctl_status.u64);
170         }
171 }
172 EXPORT_SYMBOL(octeon2_usb_clocks_start);
173
174 void octeon2_usb_clocks_stop(void)
175 {
176         union cvmx_uctlx_if_ena if_ena;
177
178         if (atomic_dec_return(&octeon2_usb_clock_start_cnt) != 0)
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 }
185 EXPORT_SYMBOL(octeon2_usb_clocks_stop);