2 * EHCI HCD glue for Cavium Octeon II SOCs.
4 * Loosely based on ehci-au1xxx.c
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
10 * Copyright (C) 2010 Cavium Networks
14 #include <linux/platform_device.h>
16 #include <asm/octeon/octeon.h>
17 #include <asm/octeon/cvmx-uctlx-defs.h>
19 #define OCTEON_EHCI_HCD_NAME "octeon-ehci"
21 /* Common clock init code. */
22 void octeon2_usb_clocks_start(void);
23 void octeon2_usb_clocks_stop(void);
25 static void ehci_octeon_start(void)
27 union cvmx_uctlx_ehci_ctl ehci_ctl
;
29 octeon2_usb_clocks_start();
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
);
40 static void ehci_octeon_stop(void)
42 octeon2_usb_clocks_stop();
45 static 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
),
51 * generic hardware linkage
54 .flags
= HCD_MEMORY
| HCD_USB2
| HCD_BH
,
57 * basic lifecycle operations
62 .shutdown
= ehci_shutdown
,
65 * managing i/o requests and associated device resources
67 .urb_enqueue
= ehci_urb_enqueue
,
68 .urb_dequeue
= ehci_urb_dequeue
,
69 .endpoint_disable
= ehci_endpoint_disable
,
70 .endpoint_reset
= ehci_endpoint_reset
,
75 .get_frame_number
= ehci_get_frame
,
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
,
87 .clear_tt_buffer_complete
= ehci_clear_tt_buffer_complete
,
90 static u64 ehci_octeon_dma_mask
= DMA_BIT_MASK(64);
92 static int ehci_octeon_drv_probe(struct platform_device
*pdev
)
95 struct ehci_hcd
*ehci
;
96 struct resource
*res_mem
;
103 irq
= platform_get_irq(pdev
, 0);
105 dev_err(&pdev
->dev
, "No irq assigned\n");
109 res_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
110 if (res_mem
== NULL
) {
111 dev_err(&pdev
->dev
, "No register space assigned\n");
116 * We can DMA from anywhere. But the descriptors must be in
119 pdev
->dev
.dma_mask
= &ehci_octeon_dma_mask
;
120 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
124 hcd
= usb_create_hcd(&ehci_octeon_hc_driver
, &pdev
->dev
, "octeon");
128 hcd
->rsrc_start
= res_mem
->start
;
129 hcd
->rsrc_len
= resource_size(res_mem
);
131 hcd
->regs
= devm_ioremap_resource(&pdev
->dev
, res_mem
);
132 if (IS_ERR(hcd
->regs
)) {
133 ret
= PTR_ERR(hcd
->regs
);
139 ehci
= hcd_to_ehci(hcd
);
141 /* Octeon EHCI matches CPU endianness. */
143 ehci
->big_endian_mmio
= 1;
146 ehci
->caps
= hcd
->regs
;
148 ret
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
150 dev_dbg(&pdev
->dev
, "failed to add hcd with err %d\n", ret
);
153 device_wakeup_enable(hcd
->self
.controller
);
155 platform_set_drvdata(pdev
, hcd
);
166 static int ehci_octeon_drv_remove(struct platform_device
*pdev
)
168 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
178 static struct platform_driver ehci_octeon_driver
= {
179 .probe
= ehci_octeon_drv_probe
,
180 .remove
= ehci_octeon_drv_remove
,
181 .shutdown
= usb_hcd_platform_shutdown
,
183 .name
= OCTEON_EHCI_HCD_NAME
,
184 .owner
= THIS_MODULE
,
188 MODULE_ALIAS("platform:" OCTEON_EHCI_HCD_NAME
);