aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c274
-rw-r--r--arch/mips/configs/cavium_octeon_defconfig3
-rw-r--r--drivers/usb/host/Kconfig18
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/ehci-hcd.c5
-rw-r--r--drivers/usb/host/ehci-octeon.c182
-rw-r--r--drivers/usb/host/octeon2-common.c200
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-octeon.c196
9 files changed, 285 insertions, 599 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
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a3ca1375dd52..fafc628480e0 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -292,11 +292,15 @@ config USB_EHCI_HCD_PLATFORM
292 If unsure, say N. 292 If unsure, say N.
293 293
294config USB_OCTEON_EHCI 294config USB_OCTEON_EHCI
295 bool "Octeon on-chip EHCI support" 295 bool "Octeon on-chip EHCI support (DEPRECATED)"
296 depends on CAVIUM_OCTEON_SOC 296 depends on CAVIUM_OCTEON_SOC
297 default n 297 default n
298 select USB_EHCI_BIG_ENDIAN_MMIO 298 select USB_EHCI_BIG_ENDIAN_MMIO
299 select USB_EHCI_HCD_PLATFORM
299 help 300 help
301 This option is deprecated now and the driver was removed, use
302 USB_EHCI_HCD_PLATFORM instead.
303
300 Enable support for the Octeon II SOC's on-chip EHCI 304 Enable support for the Octeon II SOC's on-chip EHCI
301 controller. It is needed for high-speed (480Mbit/sec) 305 controller. It is needed for high-speed (480Mbit/sec)
302 USB 2.0 device support. All CN6XXX based chips with USB are 306 USB 2.0 device support. All CN6XXX based chips with USB are
@@ -575,12 +579,16 @@ config USB_OHCI_HCD_PLATFORM
575 If unsure, say N. 579 If unsure, say N.
576 580
577config USB_OCTEON_OHCI 581config USB_OCTEON_OHCI
578 bool "Octeon on-chip OHCI support" 582 bool "Octeon on-chip OHCI support (DEPRECATED)"
579 depends on CAVIUM_OCTEON_SOC 583 depends on CAVIUM_OCTEON_SOC
580 default USB_OCTEON_EHCI 584 default USB_OCTEON_EHCI
581 select USB_OHCI_BIG_ENDIAN_MMIO 585 select USB_OHCI_BIG_ENDIAN_MMIO
582 select USB_OHCI_LITTLE_ENDIAN 586 select USB_OHCI_LITTLE_ENDIAN
587 select USB_OHCI_HCD_PLATFORM
583 help 588 help
589 This option is deprecated now and the driver was removed, use
590 USB_OHCI_HCD_PLATFORM instead.
591
584 Enable support for the Octeon II SOC's on-chip OHCI 592 Enable support for the Octeon II SOC's on-chip OHCI
585 controller. It is needed for low-speed USB 1.0 device 593 controller. It is needed for low-speed USB 1.0 device
586 support. All CN6XXX based chips with USB are supported. 594 support. All CN6XXX based chips with USB are supported.
@@ -754,12 +762,6 @@ config USB_IMX21_HCD
754 To compile this driver as a module, choose M here: the 762 To compile this driver as a module, choose M here: the
755 module will be called "imx21-hcd". 763 module will be called "imx21-hcd".
756 764
757
758
759config USB_OCTEON2_COMMON
760 bool
761 default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
762
763config USB_HCD_BCMA 765config USB_HCD_BCMA
764 tristate "BCMA usb host driver" 766 tristate "BCMA usb host driver"
765 depends on BCMA 767 depends on BCMA
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 348c24321562..d6216a493bab 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -73,7 +73,6 @@ obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
73obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o 73obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
74obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o 74obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
75obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o 75obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
76obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
77obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o 76obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
78obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o 77obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
79obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o 78obj-$(CONFIG_USB_FUSBH200_HCD) += fusbh200-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index df75b8e7d157..38bfeedae1d0 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1275,11 +1275,6 @@ MODULE_LICENSE ("GPL");
1275#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver 1275#define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver
1276#endif 1276#endif
1277 1277
1278#ifdef CONFIG_USB_OCTEON_EHCI
1279#include "ehci-octeon.c"
1280#define PLATFORM_DRIVER ehci_octeon_driver
1281#endif
1282
1283#ifdef CONFIG_TILE_USB 1278#ifdef CONFIG_TILE_USB
1284#include "ehci-tilegx.c" 1279#include "ehci-tilegx.c"
1285#define PLATFORM_DRIVER ehci_hcd_tilegx_driver 1280#define PLATFORM_DRIVER ehci_hcd_tilegx_driver
diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c
deleted file mode 100644
index 2d0c4bcba579..000000000000
--- a/drivers/usb/host/ehci-octeon.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/*
2 * EHCI HCD glue for Cavium Octeon II SOCs.
3 *
4 * Loosely based on ehci-au1xxx.c
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2010 Cavium Networks
11 *
12 */
13
14#include <linux/platform_device.h>
15
16#include <asm/octeon/octeon.h>
17#include <asm/octeon/cvmx-uctlx-defs.h>
18
19#define OCTEON_EHCI_HCD_NAME "octeon-ehci"
20
21/* Common clock init code. */
22void octeon2_usb_clocks_start(void);
23void octeon2_usb_clocks_stop(void);
24
25static void ehci_octeon_start(void)
26{
27 union cvmx_uctlx_ehci_ctl ehci_ctl;
28
29 octeon2_usb_clocks_start();
30
31 ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
32 /* Use 64-bit addressing. */
33 ehci_ctl.s.ehci_64b_addr_en = 1;
34 ehci_ctl.s.l2c_addr_msb = 0;
35 ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
36 ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
37 cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
38}
39
40static void ehci_octeon_stop(void)
41{
42 octeon2_usb_clocks_stop();
43}
44
45static const struct hc_driver ehci_octeon_hc_driver = {
46 .description = hcd_name,
47 .product_desc = "Octeon EHCI",
48 .hcd_priv_size = sizeof(struct ehci_hcd),
49
50 /*
51 * generic hardware linkage
52 */
53 .irq = ehci_irq,
54 .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
55
56 /*
57 * basic lifecycle operations
58 */
59 .reset = ehci_setup,
60 .start = ehci_run,
61 .stop = ehci_stop,
62 .shutdown = ehci_shutdown,
63
64 /*
65 * managing i/o requests and associated device resources
66 */
67 .urb_enqueue = ehci_urb_enqueue,
68 .urb_dequeue = ehci_urb_dequeue,
69 .endpoint_disable = ehci_endpoint_disable,
70 .endpoint_reset = ehci_endpoint_reset,
71
72 /*
73 * scheduling support
74 */
75 .get_frame_number = ehci_get_frame,
76
77 /*
78 * root hub support
79 */
80 .hub_status_data = ehci_hub_status_data,
81 .hub_control = ehci_hub_control,
82 .bus_suspend = ehci_bus_suspend,
83 .bus_resume = ehci_bus_resume,
84 .relinquish_port = ehci_relinquish_port,
85 .port_handed_over = ehci_port_handed_over,
86
87 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
88};
89
90static u64 ehci_octeon_dma_mask = DMA_BIT_MASK(64);
91
92static int ehci_octeon_drv_probe(struct platform_device *pdev)
93{
94 struct usb_hcd *hcd;
95 struct ehci_hcd *ehci;
96 struct resource *res_mem;
97 int irq;
98 int ret;
99
100 if (usb_disabled())
101 return -ENODEV;
102
103 irq = platform_get_irq(pdev, 0);
104 if (irq < 0) {
105 dev_err(&pdev->dev, "No irq assigned\n");
106 return -ENODEV;
107 }
108
109 /*
110 * We can DMA from anywhere. But the descriptors must be in
111 * the lower 4GB.
112 */
113 pdev->dev.dma_mask = &ehci_octeon_dma_mask;
114 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
115 if (ret)
116 return ret;
117
118 hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
119 if (!hcd)
120 return -ENOMEM;
121
122 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
123 hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem);
124 if (IS_ERR(hcd->regs)) {
125 ret = PTR_ERR(hcd->regs);
126 goto err1;
127 }
128 hcd->rsrc_start = res_mem->start;
129 hcd->rsrc_len = resource_size(res_mem);
130
131 ehci_octeon_start();
132
133 ehci = hcd_to_ehci(hcd);
134
135 /* Octeon EHCI matches CPU endianness. */
136#ifdef __BIG_ENDIAN
137 ehci->big_endian_mmio = 1;
138#endif
139
140 ehci->caps = hcd->regs;
141
142 ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
143 if (ret) {
144 dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
145 goto err2;
146 }
147 device_wakeup_enable(hcd->self.controller);
148
149 platform_set_drvdata(pdev, hcd);
150
151 return 0;
152err2:
153 ehci_octeon_stop();
154
155err1:
156 usb_put_hcd(hcd);
157 return ret;
158}
159
160static int ehci_octeon_drv_remove(struct platform_device *pdev)
161{
162 struct usb_hcd *hcd = platform_get_drvdata(pdev);
163
164 usb_remove_hcd(hcd);
165
166 ehci_octeon_stop();
167 usb_put_hcd(hcd);
168
169 return 0;
170}
171
172static struct platform_driver ehci_octeon_driver = {
173 .probe = ehci_octeon_drv_probe,
174 .remove = ehci_octeon_drv_remove,
175 .shutdown = usb_hcd_platform_shutdown,
176 .driver = {
177 .name = OCTEON_EHCI_HCD_NAME,
178 .owner = THIS_MODULE,
179 }
180};
181
182MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME);
diff --git a/drivers/usb/host/octeon2-common.c b/drivers/usb/host/octeon2-common.c
deleted file mode 100644
index d9df423f3d12..000000000000
--- a/drivers/usb/host/octeon2-common.c
+++ /dev/null
@@ -1,200 +0,0 @@
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
16static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
17
18static int octeon2_usb_clock_start_cnt;
19
20void 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
173end_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);
189exit:
190 mutex_unlock(&octeon2_usb_clocks_mutex);
191}
192EXPORT_SYMBOL(octeon2_usb_clocks_start);
193
194void 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}
200EXPORT_SYMBOL(octeon2_usb_clocks_stop);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index d664edabf14e..1dab9dfbca6a 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1249,11 +1249,6 @@ MODULE_LICENSE ("GPL");
1249#define PLATFORM_DRIVER ohci_hcd_jz4740_driver 1249#define PLATFORM_DRIVER ohci_hcd_jz4740_driver
1250#endif 1250#endif
1251 1251
1252#ifdef CONFIG_USB_OCTEON_OHCI
1253#include "ohci-octeon.c"
1254#define PLATFORM_DRIVER ohci_octeon_driver
1255#endif
1256
1257#ifdef CONFIG_TILE_USB 1252#ifdef CONFIG_TILE_USB
1258#include "ohci-tilegx.c" 1253#include "ohci-tilegx.c"
1259#define PLATFORM_DRIVER ohci_hcd_tilegx_driver 1254#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c
deleted file mode 100644
index 20d861b6192f..000000000000
--- a/drivers/usb/host/ohci-octeon.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/*
2 * EHCI HCD glue for Cavium Octeon II SOCs.
3 *
4 * Loosely based on ehci-au1xxx.c
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2010 Cavium Networks
11 *
12 */
13
14#include <linux/platform_device.h>
15
16#include <asm/octeon/octeon.h>
17#include <asm/octeon/cvmx-uctlx-defs.h>
18
19#define OCTEON_OHCI_HCD_NAME "octeon-ohci"
20
21/* Common clock init code. */
22void octeon2_usb_clocks_start(void);
23void octeon2_usb_clocks_stop(void);
24
25static void ohci_octeon_hw_start(void)
26{
27 union cvmx_uctlx_ohci_ctl ohci_ctl;
28
29 octeon2_usb_clocks_start();
30
31 ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
32 ohci_ctl.s.l2c_addr_msb = 0;
33 ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
34 ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
35 cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
36
37}
38
39static void ohci_octeon_hw_stop(void)
40{
41 /* Undo ohci_octeon_start() */
42 octeon2_usb_clocks_stop();
43}
44
45static int ohci_octeon_start(struct usb_hcd *hcd)
46{
47 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
48 int ret;
49
50 ret = ohci_init(ohci);
51
52 if (ret < 0)
53 return ret;
54
55 ret = ohci_run(ohci);
56
57 if (ret < 0) {
58 ohci_err(ohci, "can't start %s", hcd->self.bus_name);
59 ohci_stop(hcd);
60 return ret;
61 }
62
63 return 0;
64}
65
66static const struct hc_driver ohci_octeon_hc_driver = {
67 .description = hcd_name,
68 .product_desc = "Octeon OHCI",
69 .hcd_priv_size = sizeof(struct ohci_hcd),
70
71 /*
72 * generic hardware linkage
73 */
74 .irq = ohci_irq,
75 .flags = HCD_USB11 | HCD_MEMORY,
76
77 /*
78 * basic lifecycle operations
79 */
80 .start = ohci_octeon_start,
81 .stop = ohci_stop,
82 .shutdown = ohci_shutdown,
83
84 /*
85 * managing i/o requests and associated device resources
86 */
87 .urb_enqueue = ohci_urb_enqueue,
88 .urb_dequeue = ohci_urb_dequeue,
89 .endpoint_disable = ohci_endpoint_disable,
90
91 /*
92 * scheduling support
93 */
94 .get_frame_number = ohci_get_frame,
95
96 /*
97 * root hub support
98 */
99 .hub_status_data = ohci_hub_status_data,
100 .hub_control = ohci_hub_control,
101
102 .start_port_reset = ohci_start_port_reset,
103};
104
105static int ohci_octeon_drv_probe(struct platform_device *pdev)
106{
107 struct usb_hcd *hcd;
108 struct ohci_hcd *ohci;
109 void *reg_base;
110 struct resource *res_mem;
111 int irq;
112 int ret;
113
114 if (usb_disabled())
115 return -ENODEV;
116
117 irq = platform_get_irq(pdev, 0);
118 if (irq < 0) {
119 dev_err(&pdev->dev, "No irq assigned\n");
120 return -ENODEV;
121 }
122
123 /* Ohci is a 32-bit device. */
124 ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
125 if (ret)
126 return ret;
127
128 hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon");
129 if (!hcd)
130 return -ENOMEM;
131
132 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
133 reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
134 if (IS_ERR(reg_base)) {
135 ret = PTR_ERR(reg_base);
136 goto err1;
137 }
138 hcd->rsrc_start = res_mem->start;
139 hcd->rsrc_len = resource_size(res_mem);
140
141 ohci_octeon_hw_start();
142
143 hcd->regs = reg_base;
144
145 ohci = hcd_to_ohci(hcd);
146
147 /* Octeon OHCI matches CPU endianness. */
148#ifdef __BIG_ENDIAN
149 ohci->flags |= OHCI_QUIRK_BE_MMIO;
150#endif
151
152 ohci_hcd_init(ohci);
153
154 ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
155 if (ret) {
156 dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret);
157 goto err2;
158 }
159
160 device_wakeup_enable(hcd->self.controller);
161
162 platform_set_drvdata(pdev, hcd);
163
164 return 0;
165
166err2:
167 ohci_octeon_hw_stop();
168
169err1:
170 usb_put_hcd(hcd);
171 return ret;
172}
173
174static int ohci_octeon_drv_remove(struct platform_device *pdev)
175{
176 struct usb_hcd *hcd = platform_get_drvdata(pdev);
177
178 usb_remove_hcd(hcd);
179
180 ohci_octeon_hw_stop();
181 usb_put_hcd(hcd);
182
183 return 0;
184}
185
186static struct platform_driver ohci_octeon_driver = {
187 .probe = ohci_octeon_drv_probe,
188 .remove = ohci_octeon_drv_remove,
189 .shutdown = usb_hcd_platform_shutdown,
190 .driver = {
191 .name = OCTEON_OHCI_HCD_NAME,
192 .owner = THIS_MODULE,
193 }
194};
195
196MODULE_ALIAS("platform:" OCTEON_OHCI_HCD_NAME);