diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/dts/stih416.dtsi | 10 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/octeon-platform.c | 152 |
2 files changed, 68 insertions, 94 deletions
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi index fad9073ddeed..85afe01c34fa 100644 --- a/arch/arm/boot/dts/stih416.dtsi +++ b/arch/arm/boot/dts/stih416.dtsi | |||
@@ -283,21 +283,21 @@ | |||
283 | 283 | ||
284 | miphy365x_phy: phy@fe382000 { | 284 | miphy365x_phy: phy@fe382000 { |
285 | compatible = "st,miphy365x-phy"; | 285 | compatible = "st,miphy365x-phy"; |
286 | st,syscfg = <&syscfg_rear>; | 286 | st,syscfg = <&syscfg_rear 0x824 0x828>; |
287 | #address-cells = <1>; | 287 | #address-cells = <1>; |
288 | #size-cells = <1>; | 288 | #size-cells = <1>; |
289 | ranges; | 289 | ranges; |
290 | 290 | ||
291 | phy_port0: port@fe382000 { | 291 | phy_port0: port@fe382000 { |
292 | #phy-cells = <1>; | 292 | #phy-cells = <1>; |
293 | reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>; | 293 | reg = <0xfe382000 0x100>, <0xfe394000 0x100>; |
294 | reg-names = "sata", "pcie", "syscfg"; | 294 | reg-names = "sata", "pcie"; |
295 | }; | 295 | }; |
296 | 296 | ||
297 | phy_port1: port@fe38a000 { | 297 | phy_port1: port@fe38a000 { |
298 | #phy-cells = <1>; | 298 | #phy-cells = <1>; |
299 | reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>; | 299 | reg = <0xfe38a000 0x100>, <0xfe804000 0x100>; |
300 | reg-names = "sata", "pcie", "syscfg"; | 300 | reg-names = "sata", "pcie"; |
301 | }; | 301 | }; |
302 | }; | 302 | }; |
303 | 303 | ||
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index b67ddf0f8bcd..12410a2788d8 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c | |||
@@ -77,7 +77,7 @@ static DEFINE_MUTEX(octeon2_usb_clocks_mutex); | |||
77 | 77 | ||
78 | static int octeon2_usb_clock_start_cnt; | 78 | static int octeon2_usb_clock_start_cnt; |
79 | 79 | ||
80 | static void octeon2_usb_clocks_start(void) | 80 | static void octeon2_usb_clocks_start(struct device *dev) |
81 | { | 81 | { |
82 | u64 div; | 82 | u64 div; |
83 | union cvmx_uctlx_if_ena if_ena; | 83 | union cvmx_uctlx_if_ena if_ena; |
@@ -86,6 +86,8 @@ static void octeon2_usb_clocks_start(void) | |||
86 | union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; | 86 | union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status; |
87 | int i; | 87 | int i; |
88 | unsigned long io_clk_64_to_ns; | 88 | unsigned long io_clk_64_to_ns; |
89 | u32 clock_rate = 12000000; | ||
90 | bool is_crystal_clock = false; | ||
89 | 91 | ||
90 | 92 | ||
91 | mutex_lock(&octeon2_usb_clocks_mutex); | 93 | mutex_lock(&octeon2_usb_clocks_mutex); |
@@ -96,6 +98,28 @@ static void octeon2_usb_clocks_start(void) | |||
96 | 98 | ||
97 | io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); | 99 | io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate(); |
98 | 100 | ||
101 | if (dev->of_node) { | ||
102 | struct device_node *uctl_node; | ||
103 | const char *clock_type; | ||
104 | |||
105 | uctl_node = of_get_parent(dev->of_node); | ||
106 | if (!uctl_node) { | ||
107 | dev_err(dev, "No UCTL device node\n"); | ||
108 | goto exit; | ||
109 | } | ||
110 | i = of_property_read_u32(uctl_node, | ||
111 | "refclk-frequency", &clock_rate); | ||
112 | if (i) { | ||
113 | dev_err(dev, "No UCTL \"refclk-frequency\"\n"); | ||
114 | goto exit; | ||
115 | } | ||
116 | i = of_property_read_string(uctl_node, | ||
117 | "refclk-type", &clock_type); | ||
118 | |||
119 | if (!i && strcmp("crystal", clock_type) == 0) | ||
120 | is_crystal_clock = true; | ||
121 | } | ||
122 | |||
99 | /* | 123 | /* |
100 | * Step 1: Wait for voltages stable. That surely happened | 124 | * Step 1: Wait for voltages stable. That surely happened |
101 | * before starting the kernel. | 125 | * before starting the kernel. |
@@ -126,9 +150,22 @@ static void octeon2_usb_clocks_start(void) | |||
126 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); | 150 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); |
127 | 151 | ||
128 | /* 3b */ | 152 | /* 3b */ |
129 | /* 12MHz crystal. */ | 153 | clk_rst_ctl.s.p_refclk_sel = is_crystal_clock ? 0 : 1; |
130 | clk_rst_ctl.s.p_refclk_sel = 0; | 154 | switch (clock_rate) { |
131 | clk_rst_ctl.s.p_refclk_div = 0; | 155 | default: |
156 | pr_err("Invalid UCTL clock rate of %u, using 12000000 instead\n", | ||
157 | clock_rate); | ||
158 | /* Fall through */ | ||
159 | case 12000000: | ||
160 | clk_rst_ctl.s.p_refclk_div = 0; | ||
161 | break; | ||
162 | case 24000000: | ||
163 | clk_rst_ctl.s.p_refclk_div = 1; | ||
164 | break; | ||
165 | case 48000000: | ||
166 | clk_rst_ctl.s.p_refclk_div = 2; | ||
167 | break; | ||
168 | } | ||
132 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); | 169 | cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64); |
133 | 170 | ||
134 | /* 3c */ | 171 | /* 3c */ |
@@ -259,7 +296,7 @@ static void octeon2_usb_clocks_stop(void) | |||
259 | 296 | ||
260 | static int octeon_ehci_power_on(struct platform_device *pdev) | 297 | static int octeon_ehci_power_on(struct platform_device *pdev) |
261 | { | 298 | { |
262 | octeon2_usb_clocks_start(); | 299 | octeon2_usb_clocks_start(&pdev->dev); |
263 | return 0; | 300 | return 0; |
264 | } | 301 | } |
265 | 302 | ||
@@ -273,15 +310,16 @@ static struct usb_ehci_pdata octeon_ehci_pdata = { | |||
273 | #ifdef __BIG_ENDIAN | 310 | #ifdef __BIG_ENDIAN |
274 | .big_endian_mmio = 1, | 311 | .big_endian_mmio = 1, |
275 | #endif | 312 | #endif |
313 | .dma_mask_64 = 1, | ||
276 | .power_on = octeon_ehci_power_on, | 314 | .power_on = octeon_ehci_power_on, |
277 | .power_off = octeon_ehci_power_off, | 315 | .power_off = octeon_ehci_power_off, |
278 | }; | 316 | }; |
279 | 317 | ||
280 | static void __init octeon_ehci_hw_start(void) | 318 | static void __init octeon_ehci_hw_start(struct device *dev) |
281 | { | 319 | { |
282 | union cvmx_uctlx_ehci_ctl ehci_ctl; | 320 | union cvmx_uctlx_ehci_ctl ehci_ctl; |
283 | 321 | ||
284 | octeon2_usb_clocks_start(); | 322 | octeon2_usb_clocks_start(dev); |
285 | 323 | ||
286 | ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); | 324 | ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0)); |
287 | /* Use 64-bit addressing. */ | 325 | /* Use 64-bit addressing. */ |
@@ -294,64 +332,30 @@ static void __init octeon_ehci_hw_start(void) | |||
294 | octeon2_usb_clocks_stop(); | 332 | octeon2_usb_clocks_stop(); |
295 | } | 333 | } |
296 | 334 | ||
297 | static u64 octeon_ehci_dma_mask = DMA_BIT_MASK(64); | ||
298 | |||
299 | static int __init octeon_ehci_device_init(void) | 335 | static int __init octeon_ehci_device_init(void) |
300 | { | 336 | { |
301 | struct platform_device *pd; | 337 | struct platform_device *pd; |
338 | struct device_node *ehci_node; | ||
302 | int ret = 0; | 339 | int ret = 0; |
303 | 340 | ||
304 | struct resource usb_resources[] = { | 341 | ehci_node = of_find_node_by_name(NULL, "ehci"); |
305 | { | 342 | if (!ehci_node) |
306 | .flags = IORESOURCE_MEM, | ||
307 | }, { | ||
308 | .flags = IORESOURCE_IRQ, | ||
309 | } | ||
310 | }; | ||
311 | |||
312 | /* Only Octeon2 has ehci/ohci */ | ||
313 | if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) | ||
314 | return 0; | 343 | return 0; |
315 | 344 | ||
316 | if (octeon_is_simulation() || usb_disabled()) | 345 | pd = of_find_device_by_node(ehci_node); |
317 | return 0; /* No USB in the simulator. */ | 346 | if (!pd) |
318 | 347 | return 0; | |
319 | pd = platform_device_alloc("ehci-platform", 0); | ||
320 | if (!pd) { | ||
321 | ret = -ENOMEM; | ||
322 | goto out; | ||
323 | } | ||
324 | |||
325 | usb_resources[0].start = 0x00016F0000000000ULL; | ||
326 | usb_resources[0].end = usb_resources[0].start + 0x100; | ||
327 | |||
328 | usb_resources[1].start = OCTEON_IRQ_USB0; | ||
329 | usb_resources[1].end = OCTEON_IRQ_USB0; | ||
330 | |||
331 | ret = platform_device_add_resources(pd, usb_resources, | ||
332 | ARRAY_SIZE(usb_resources)); | ||
333 | if (ret) | ||
334 | goto fail; | ||
335 | 348 | ||
336 | pd->dev.dma_mask = &octeon_ehci_dma_mask; | ||
337 | pd->dev.platform_data = &octeon_ehci_pdata; | 349 | pd->dev.platform_data = &octeon_ehci_pdata; |
338 | octeon_ehci_hw_start(); | 350 | octeon_ehci_hw_start(&pd->dev); |
339 | 351 | ||
340 | ret = platform_device_add(pd); | ||
341 | if (ret) | ||
342 | goto fail; | ||
343 | |||
344 | return ret; | ||
345 | fail: | ||
346 | platform_device_put(pd); | ||
347 | out: | ||
348 | return ret; | 352 | return ret; |
349 | } | 353 | } |
350 | device_initcall(octeon_ehci_device_init); | 354 | device_initcall(octeon_ehci_device_init); |
351 | 355 | ||
352 | static int octeon_ohci_power_on(struct platform_device *pdev) | 356 | static int octeon_ohci_power_on(struct platform_device *pdev) |
353 | { | 357 | { |
354 | octeon2_usb_clocks_start(); | 358 | octeon2_usb_clocks_start(&pdev->dev); |
355 | return 0; | 359 | return 0; |
356 | } | 360 | } |
357 | 361 | ||
@@ -369,11 +373,11 @@ static struct usb_ohci_pdata octeon_ohci_pdata = { | |||
369 | .power_off = octeon_ohci_power_off, | 373 | .power_off = octeon_ohci_power_off, |
370 | }; | 374 | }; |
371 | 375 | ||
372 | static void __init octeon_ohci_hw_start(void) | 376 | static void __init octeon_ohci_hw_start(struct device *dev) |
373 | { | 377 | { |
374 | union cvmx_uctlx_ohci_ctl ohci_ctl; | 378 | union cvmx_uctlx_ohci_ctl ohci_ctl; |
375 | 379 | ||
376 | octeon2_usb_clocks_start(); | 380 | octeon2_usb_clocks_start(dev); |
377 | 381 | ||
378 | ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); | 382 | ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0)); |
379 | ohci_ctl.s.l2c_addr_msb = 0; | 383 | ohci_ctl.s.l2c_addr_msb = 0; |
@@ -387,57 +391,27 @@ static void __init octeon_ohci_hw_start(void) | |||
387 | static int __init octeon_ohci_device_init(void) | 391 | static int __init octeon_ohci_device_init(void) |
388 | { | 392 | { |
389 | struct platform_device *pd; | 393 | struct platform_device *pd; |
394 | struct device_node *ohci_node; | ||
390 | int ret = 0; | 395 | int ret = 0; |
391 | 396 | ||
392 | struct resource usb_resources[] = { | 397 | ohci_node = of_find_node_by_name(NULL, "ohci"); |
393 | { | 398 | if (!ohci_node) |
394 | .flags = IORESOURCE_MEM, | ||
395 | }, { | ||
396 | .flags = IORESOURCE_IRQ, | ||
397 | } | ||
398 | }; | ||
399 | |||
400 | /* Only Octeon2 has ehci/ohci */ | ||
401 | if (!OCTEON_IS_MODEL(OCTEON_CN63XX)) | ||
402 | return 0; | 399 | return 0; |
403 | 400 | ||
404 | if (octeon_is_simulation() || usb_disabled()) | 401 | pd = of_find_device_by_node(ohci_node); |
405 | return 0; /* No USB in the simulator. */ | 402 | if (!pd) |
406 | 403 | return 0; | |
407 | pd = platform_device_alloc("ohci-platform", 0); | ||
408 | if (!pd) { | ||
409 | ret = -ENOMEM; | ||
410 | goto out; | ||
411 | } | ||
412 | |||
413 | usb_resources[0].start = 0x00016F0000000400ULL; | ||
414 | usb_resources[0].end = usb_resources[0].start + 0x100; | ||
415 | |||
416 | usb_resources[1].start = OCTEON_IRQ_USB0; | ||
417 | usb_resources[1].end = OCTEON_IRQ_USB0; | ||
418 | |||
419 | ret = platform_device_add_resources(pd, usb_resources, | ||
420 | ARRAY_SIZE(usb_resources)); | ||
421 | if (ret) | ||
422 | goto fail; | ||
423 | 404 | ||
424 | pd->dev.platform_data = &octeon_ohci_pdata; | 405 | pd->dev.platform_data = &octeon_ohci_pdata; |
425 | octeon_ohci_hw_start(); | 406 | octeon_ohci_hw_start(&pd->dev); |
426 | |||
427 | ret = platform_device_add(pd); | ||
428 | if (ret) | ||
429 | goto fail; | ||
430 | 407 | ||
431 | return ret; | 408 | return ret; |
432 | fail: | ||
433 | platform_device_put(pd); | ||
434 | out: | ||
435 | return ret; | ||
436 | } | 409 | } |
437 | device_initcall(octeon_ohci_device_init); | 410 | device_initcall(octeon_ohci_device_init); |
438 | 411 | ||
439 | #endif /* CONFIG_USB */ | 412 | #endif /* CONFIG_USB */ |
440 | 413 | ||
414 | |||
441 | static struct of_device_id __initdata octeon_ids[] = { | 415 | static struct of_device_id __initdata octeon_ids[] = { |
442 | { .compatible = "simple-bus", }, | 416 | { .compatible = "simple-bus", }, |
443 | { .compatible = "cavium,octeon-6335-uctl", }, | 417 | { .compatible = "cavium,octeon-6335-uctl", }, |