aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 17:57:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-14 17:57:16 -0500
commite7cf773d431a63a2417902696fcc9e0ebdc83bbe (patch)
tree86dbdceb7d91226507a3af0d57e03b0ca664b22e /arch/mips
parent7a02d089695a1217992434f03a78aa32bad85b5c (diff)
parent81e1dadfb5b2d47aa513ad60b1c9cf0ea17b6514 (diff)
Merge tag 'usb-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB updates from Greg KH: "Here's the big set of USB and PHY patches for 3.19-rc1. The normal churn in the USB gadget area is in here, as well as xhci and other individual USB driver updates. The PHY tree is also in here, as there were dependancies on the USB tree. All of these have been in linux-next" * tag 'usb-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (351 commits) arm: omap3: twl: remove usb phy init data usbip: fix error handling in stub_probe() usb: gadget: udc: missing curly braces USB: mos7720: delete some unneeded code wusb: replace memset by memzero_explicit usbip: remove unneeded structure usb: xhci: fix comment for PORT_DEV_REMOVE xhci: don't use the same variable for stopped and halted rings current TD xhci: clear extra bits from slot context when setting max exit latency xhci: cleanup finish_td function USB: adutux: NULL dereferences on disconnect usb: chipidea: fix platform_no_drv_owner.cocci warnings usb: chipidea: Fixed a few typos in comments Documentation: bindings: add doc for the USB2 ChipIdea USB driver usb: chipidea: add a usb2 driver for ci13xxx usb: chipidea: fix phy handling usb: chipidea: remove duplicate dev_set_drvdata for host_start usb: chipidea: parameter 'mode' isn't needed for hw_device_reset usb: chipidea: add controller reset API usb: chipidea: remove flag CI_HDRC_REQUIRE_TRANSCEIVER ...
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