aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2014-11-25 06:28:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-11-25 12:19:28 -0500
commit2193dda5eec60373c7a061c129c6ab9d658f78e9 (patch)
treec474b5df7c45575c22ec35be3f9f1f6574272530 /arch/mips
parentf910b6cba27af4c5e1b0de1225a268448c2e82be (diff)
USB: host: Remove ehci-octeon and ohci-octeon drivers
Remove special-purpose octeon drivers and instead use ehci-platform and ohci-platform as suggested with http://marc.info/?l=linux-mips&m=140139694721623&w=2 [andreas.herrmann: fixed compile error] Cc: David Daney <david.daney@cavium.com> Cc: Alex Smith <alex.smith@imgtec.com> Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com> Acked-by: Ralf Baechle <ralf@linux-mips.org> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c274
-rw-r--r--arch/mips/configs/cavium_octeon_defconfig3
2 files changed, 275 insertions, 2 deletions
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 6df0f4d8f197..b67ddf0f8bcd 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -7,22 +7,27 @@
7 * Copyright (C) 2008 Wind River Systems 7 * Copyright (C) 2008 Wind River Systems
8 */ 8 */
9 9
10#include <linux/delay.h>
10#include <linux/init.h> 11#include <linux/init.h>
11#include <linux/irq.h> 12#include <linux/irq.h>
12#include <linux/i2c.h> 13#include <linux/i2c.h>
13#include <linux/usb.h> 14#include <linux/usb.h>
14#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
15#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/mutex.h>
16#include <linux/slab.h> 18#include <linux/slab.h>
17#include <linux/platform_device.h> 19#include <linux/platform_device.h>
18#include <linux/of_platform.h> 20#include <linux/of_platform.h>
19#include <linux/of_fdt.h> 21#include <linux/of_fdt.h>
20#include <linux/libfdt.h> 22#include <linux/libfdt.h>
23#include <linux/usb/ehci_pdriver.h>
24#include <linux/usb/ohci_pdriver.h>
21 25
22#include <asm/octeon/octeon.h> 26#include <asm/octeon/octeon.h>
23#include <asm/octeon/cvmx-rnm-defs.h> 27#include <asm/octeon/cvmx-rnm-defs.h>
24#include <asm/octeon/cvmx-helper.h> 28#include <asm/octeon/cvmx-helper.h>
25#include <asm/octeon/cvmx-helper-board.h> 29#include <asm/octeon/cvmx-helper-board.h>
30#include <asm/octeon/cvmx-uctlx-defs.h>
26 31
27/* Octeon Random Number Generator. */ 32/* Octeon Random Number Generator. */
28static int __init octeon_rng_device_init(void) 33static int __init octeon_rng_device_init(void)
@@ -68,6 +73,229 @@ device_initcall(octeon_rng_device_init);
68 73
69#ifdef CONFIG_USB 74#ifdef CONFIG_USB
70 75
76static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
77
78static int octeon2_usb_clock_start_cnt;
79
80static void octeon2_usb_clocks_start(void)
81{
82 u64 div;
83 union cvmx_uctlx_if_ena if_ena;
84 union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
85 union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
86 union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
87 int i;
88 unsigned long io_clk_64_to_ns;
89
90
91 mutex_lock(&octeon2_usb_clocks_mutex);
92
93 octeon2_usb_clock_start_cnt++;
94 if (octeon2_usb_clock_start_cnt != 1)
95 goto exit;
96
97 io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
98
99 /*
100 * Step 1: Wait for voltages stable. That surely happened
101 * before starting the kernel.
102 *
103 * Step 2: Enable SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
104 */
105 if_ena.u64 = 0;
106 if_ena.s.en = 1;
107 cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
108
109 /* Step 3: Configure the reference clock, PHY, and HCLK */
110 clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
111
112 /*
113 * If the UCTL looks like it has already been started, skip
114 * the initialization, otherwise bus errors are obtained.
115 */
116 if (clk_rst_ctl.s.hrst)
117 goto end_clock;
118 /* 3a */
119 clk_rst_ctl.s.p_por = 1;
120 clk_rst_ctl.s.hrst = 0;
121 clk_rst_ctl.s.p_prst = 0;
122 clk_rst_ctl.s.h_clkdiv_rst = 0;
123 clk_rst_ctl.s.o_clkdiv_rst = 0;
124 clk_rst_ctl.s.h_clkdiv_en = 0;
125 clk_rst_ctl.s.o_clkdiv_en = 0;
126 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
127
128 /* 3b */
129 /* 12MHz crystal. */
130 clk_rst_ctl.s.p_refclk_sel = 0;
131 clk_rst_ctl.s.p_refclk_div = 0;
132 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
133
134 /* 3c */
135 div = octeon_get_io_clock_rate() / 130000000ull;
136
137 switch (div) {
138 case 0:
139 div = 1;
140 break;
141 case 1:
142 case 2:
143 case 3:
144 case 4:
145 break;
146 case 5:
147 div = 4;
148 break;
149 case 6:
150 case 7:
151 div = 6;
152 break;
153 case 8:
154 case 9:
155 case 10:
156 case 11:
157 div = 8;
158 break;
159 default:
160 div = 12;
161 break;
162 }
163 clk_rst_ctl.s.h_div = div;
164 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
165 /* Read it back, */
166 clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
167 clk_rst_ctl.s.h_clkdiv_en = 1;
168 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
169 /* 3d */
170 clk_rst_ctl.s.h_clkdiv_rst = 1;
171 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
172
173 /* 3e: delay 64 io clocks */
174 ndelay(io_clk_64_to_ns);
175
176 /*
177 * Step 4: Program the power-on reset field in the UCTL
178 * clock-reset-control register.
179 */
180 clk_rst_ctl.s.p_por = 0;
181 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
182
183 /* Step 5: Wait 1 ms for the PHY clock to start. */
184 mdelay(1);
185
186 /*
187 * Step 6: Program the reset input from automatic test
188 * equipment field in the UPHY CSR
189 */
190 uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
191 uphy_ctl_status.s.ate_reset = 1;
192 cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
193
194 /* Step 7: Wait for at least 10ns. */
195 ndelay(10);
196
197 /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
198 uphy_ctl_status.s.ate_reset = 0;
199 cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
200
201 /*
202 * Step 9: Wait for at least 20ns for UPHY to output PHY clock
203 * signals and OHCI_CLK48
204 */
205 ndelay(20);
206
207 /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
208 /* 10a */
209 clk_rst_ctl.s.o_clkdiv_rst = 1;
210 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
211
212 /* 10b */
213 clk_rst_ctl.s.o_clkdiv_en = 1;
214 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
215
216 /* 10c */
217 ndelay(io_clk_64_to_ns);
218
219 /*
220 * Step 11: Program the PHY reset field:
221 * UCTL0_CLK_RST_CTL[P_PRST] = 1
222 */
223 clk_rst_ctl.s.p_prst = 1;
224 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
225
226 /* Step 12: Wait 1 uS. */
227 udelay(1);
228
229 /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
230 clk_rst_ctl.s.hrst = 1;
231 cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
232
233end_clock:
234 /* Now we can set some other registers. */
235
236 for (i = 0; i <= 1; i++) {
237 port_ctl_status.u64 =
238 cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
239 /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
240 port_ctl_status.s.txvreftune = 15;
241 port_ctl_status.s.txrisetune = 1;
242 port_ctl_status.s.txpreemphasistune = 1;
243 cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
244 port_ctl_status.u64);
245 }
246
247 /* Set uSOF cycle period to 60,000 bits. */
248 cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
249exit:
250 mutex_unlock(&octeon2_usb_clocks_mutex);
251}
252
253static void octeon2_usb_clocks_stop(void)
254{
255 mutex_lock(&octeon2_usb_clocks_mutex);
256 octeon2_usb_clock_start_cnt--;
257 mutex_unlock(&octeon2_usb_clocks_mutex);
258}
259
260static int octeon_ehci_power_on(struct platform_device *pdev)
261{
262 octeon2_usb_clocks_start();
263 return 0;
264}
265
266static void octeon_ehci_power_off(struct platform_device *pdev)
267{
268 octeon2_usb_clocks_stop();
269}
270
271static struct usb_ehci_pdata octeon_ehci_pdata = {
272 /* Octeon EHCI matches CPU endianness. */
273#ifdef __BIG_ENDIAN
274 .big_endian_mmio = 1,
275#endif
276 .power_on = octeon_ehci_power_on,
277 .power_off = octeon_ehci_power_off,
278};
279
280static void __init octeon_ehci_hw_start(void)
281{
282 union cvmx_uctlx_ehci_ctl ehci_ctl;
283
284 octeon2_usb_clocks_start();
285
286 ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
287 /* Use 64-bit addressing. */
288 ehci_ctl.s.ehci_64b_addr_en = 1;
289 ehci_ctl.s.l2c_addr_msb = 0;
290 ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
291 ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
292 cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
293
294 octeon2_usb_clocks_stop();
295}
296
297static u64 octeon_ehci_dma_mask = DMA_BIT_MASK(64);
298
71static int __init octeon_ehci_device_init(void) 299static int __init octeon_ehci_device_init(void)
72{ 300{
73 struct platform_device *pd; 301 struct platform_device *pd;
@@ -88,7 +316,7 @@ static int __init octeon_ehci_device_init(void)
88 if (octeon_is_simulation() || usb_disabled()) 316 if (octeon_is_simulation() || usb_disabled())
89 return 0; /* No USB in the simulator. */ 317 return 0; /* No USB in the simulator. */
90 318
91 pd = platform_device_alloc("octeon-ehci", 0); 319 pd = platform_device_alloc("ehci-platform", 0);
92 if (!pd) { 320 if (!pd) {
93 ret = -ENOMEM; 321 ret = -ENOMEM;
94 goto out; 322 goto out;
@@ -105,6 +333,10 @@ static int __init octeon_ehci_device_init(void)
105 if (ret) 333 if (ret)
106 goto fail; 334 goto fail;
107 335
336 pd->dev.dma_mask = &octeon_ehci_dma_mask;
337 pd->dev.platform_data = &octeon_ehci_pdata;
338 octeon_ehci_hw_start();
339
108 ret = platform_device_add(pd); 340 ret = platform_device_add(pd);
109 if (ret) 341 if (ret)
110 goto fail; 342 goto fail;
@@ -117,6 +349,41 @@ out:
117} 349}
118device_initcall(octeon_ehci_device_init); 350device_initcall(octeon_ehci_device_init);
119 351
352static int octeon_ohci_power_on(struct platform_device *pdev)
353{
354 octeon2_usb_clocks_start();
355 return 0;
356}
357
358static void octeon_ohci_power_off(struct platform_device *pdev)
359{
360 octeon2_usb_clocks_stop();
361}
362
363static struct usb_ohci_pdata octeon_ohci_pdata = {
364 /* Octeon OHCI matches CPU endianness. */
365#ifdef __BIG_ENDIAN
366 .big_endian_mmio = 1,
367#endif
368 .power_on = octeon_ohci_power_on,
369 .power_off = octeon_ohci_power_off,
370};
371
372static void __init octeon_ohci_hw_start(void)
373{
374 union cvmx_uctlx_ohci_ctl ohci_ctl;
375
376 octeon2_usb_clocks_start();
377
378 ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
379 ohci_ctl.s.l2c_addr_msb = 0;
380 ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
381 ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
382 cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
383
384 octeon2_usb_clocks_stop();
385}
386
120static int __init octeon_ohci_device_init(void) 387static int __init octeon_ohci_device_init(void)
121{ 388{
122 struct platform_device *pd; 389 struct platform_device *pd;
@@ -137,7 +404,7 @@ static int __init octeon_ohci_device_init(void)
137 if (octeon_is_simulation() || usb_disabled()) 404 if (octeon_is_simulation() || usb_disabled())
138 return 0; /* No USB in the simulator. */ 405 return 0; /* No USB in the simulator. */
139 406
140 pd = platform_device_alloc("octeon-ohci", 0); 407 pd = platform_device_alloc("ohci-platform", 0);
141 if (!pd) { 408 if (!pd) {
142 ret = -ENOMEM; 409 ret = -ENOMEM;
143 goto out; 410 goto out;
@@ -154,6 +421,9 @@ static int __init octeon_ohci_device_init(void)
154 if (ret) 421 if (ret)
155 goto fail; 422 goto fail;
156 423
424 pd->dev.platform_data = &octeon_ohci_pdata;
425 octeon_ohci_hw_start();
426
157 ret = platform_device_add(pd); 427 ret = platform_device_add(pd);
158 if (ret) 428 if (ret)
159 goto fail; 429 goto fail;
diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig
index b2476a1c4aaa..e57058d4ec22 100644
--- a/arch/mips/configs/cavium_octeon_defconfig
+++ b/arch/mips/configs/cavium_octeon_defconfig
@@ -120,6 +120,9 @@ CONFIG_SPI_OCTEON=y
120# CONFIG_HWMON is not set 120# CONFIG_HWMON is not set
121CONFIG_WATCHDOG=y 121CONFIG_WATCHDOG=y
122# CONFIG_USB_SUPPORT is not set 122# CONFIG_USB_SUPPORT is not set
123CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
124CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
125CONFIG_USB_OHCI_LITTLE_ENDIAN=y
123CONFIG_RTC_CLASS=y 126CONFIG_RTC_CLASS=y
124CONFIG_RTC_DRV_DS1307=y 127CONFIG_RTC_DRV_DS1307=y
125CONFIG_STAGING=y 128CONFIG_STAGING=y