Commit 3262b21ef8523175f0758f4deccec048e73d5b18
Committed by
Ralf Baechle
1 parent
b6ba1c5294
Exists in
master
and in
16 other branches
MIPS: Netlogic: XLP9XX USB support
XLP9XX has a USB 3.0 controller on-chip with 2 xHCI ports. The USB block is similar to the one on XLP2XX, so update usb-init-xlp2.c to handle XLP9XX as well. Signed-off-by: Ganesan Ramalingam <ganesanr@broadcom.com> Signed-off-by: Jayachandran C <jchandra@broadcom.com> Signed-off-by: John Crispin <blogic@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/6285/
Showing 4 changed files with 84 additions and 13 deletions Side-by-side Diff
arch/mips/include/asm/netlogic/xlp-hal/iomap.h
... | ... | @@ -188,6 +188,9 @@ |
188 | 188 | #define PCI_DEVICE_ID_NLM_MMC 0x1018 |
189 | 189 | #define PCI_DEVICE_ID_NLM_XHCI 0x101d |
190 | 190 | |
191 | +#define PCI_DEVICE_ID_XLP9XX_SATA 0x901A | |
192 | +#define PCI_DEVICE_ID_XLP9XX_XHCI 0x901D | |
193 | + | |
191 | 194 | #ifndef __ASSEMBLY__ |
192 | 195 | |
193 | 196 | #define nlm_read_pci_reg(b, r) nlm_read_reg(b, r) |
arch/mips/include/asm/netlogic/xlp-hal/xlp.h
arch/mips/netlogic/xlp/nlm_hal.c
arch/mips/netlogic/xlp/usb-init-xlp2.c
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #include <linux/delay.h> |
38 | 38 | #include <linux/init.h> |
39 | 39 | #include <linux/pci.h> |
40 | +#include <linux/pci_ids.h> | |
40 | 41 | #include <linux/platform_device.h> |
41 | 42 | #include <linux/irq.h> |
42 | 43 | |
43 | 44 | |
... | ... | @@ -83,12 +84,14 @@ |
83 | 84 | #define nlm_read_usb_reg(b, r) nlm_read_reg(b, r) |
84 | 85 | #define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v) |
85 | 86 | |
86 | -#define nlm_xlpii_get_usb_pcibase(node, inst) \ | |
87 | - nlm_pcicfg_base(XLP2XX_IO_USB_OFFSET(node, inst)) | |
87 | +#define nlm_xlpii_get_usb_pcibase(node, inst) \ | |
88 | + nlm_pcicfg_base(cpu_is_xlp9xx() ? \ | |
89 | + XLP9XX_IO_USB_OFFSET(node, inst) : \ | |
90 | + XLP2XX_IO_USB_OFFSET(node, inst)) | |
88 | 91 | #define nlm_xlpii_get_usb_regbase(node, inst) \ |
89 | 92 | (nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ) |
90 | 93 | |
91 | -static void xlpii_usb_ack(struct irq_data *data) | |
94 | +static void xlp2xx_usb_ack(struct irq_data *data) | |
92 | 95 | { |
93 | 96 | u64 port_addr; |
94 | 97 | |
... | ... | @@ -109,6 +112,29 @@ |
109 | 112 | nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff); |
110 | 113 | } |
111 | 114 | |
115 | +static void xlp9xx_usb_ack(struct irq_data *data) | |
116 | +{ | |
117 | + u64 port_addr; | |
118 | + int node, irq; | |
119 | + | |
120 | + /* Find the node and irq on the node */ | |
121 | + irq = data->irq % NLM_IRQS_PER_NODE; | |
122 | + node = data->irq / NLM_IRQS_PER_NODE; | |
123 | + | |
124 | + switch (irq) { | |
125 | + case PIC_9XX_XHCI_0_IRQ: | |
126 | + port_addr = nlm_xlpii_get_usb_regbase(node, 1); | |
127 | + break; | |
128 | + case PIC_9XX_XHCI_1_IRQ: | |
129 | + port_addr = nlm_xlpii_get_usb_regbase(node, 2); | |
130 | + break; | |
131 | + default: | |
132 | + pr_err("No matching USB irq %d node %d!\n", irq, node); | |
133 | + return; | |
134 | + } | |
135 | + nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff); | |
136 | +} | |
137 | + | |
112 | 138 | static void nlm_xlpii_usb_hw_reset(int node, int port) |
113 | 139 | { |
114 | 140 | u64 port_addr, xhci_base, pci_base; |
115 | 141 | |
116 | 142 | |
... | ... | @@ -178,17 +204,33 @@ |
178 | 204 | |
179 | 205 | static int __init nlm_platform_xlpii_usb_init(void) |
180 | 206 | { |
207 | + int node; | |
208 | + | |
181 | 209 | if (!cpu_is_xlpii()) |
182 | 210 | return 0; |
183 | 211 | |
184 | - pr_info("Initializing 2XX USB Interface\n"); | |
185 | - nlm_xlpii_usb_hw_reset(0, 1); | |
186 | - nlm_xlpii_usb_hw_reset(0, 2); | |
187 | - nlm_xlpii_usb_hw_reset(0, 3); | |
188 | - nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlpii_usb_ack); | |
189 | - nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlpii_usb_ack); | |
190 | - nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlpii_usb_ack); | |
212 | + if (!cpu_is_xlp9xx()) { | |
213 | + /* XLP 2XX single node */ | |
214 | + pr_info("Initializing 2XX USB Interface\n"); | |
215 | + nlm_xlpii_usb_hw_reset(0, 1); | |
216 | + nlm_xlpii_usb_hw_reset(0, 2); | |
217 | + nlm_xlpii_usb_hw_reset(0, 3); | |
218 | + nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlp2xx_usb_ack); | |
219 | + nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlp2xx_usb_ack); | |
220 | + nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlp2xx_usb_ack); | |
221 | + return 0; | |
222 | + } | |
191 | 223 | |
224 | + /* XLP 9XX, multi-node */ | |
225 | + pr_info("Initializing 9XX USB Interface\n"); | |
226 | + for (node = 0; node < NLM_NR_NODES; node++) { | |
227 | + if (!nlm_node_present(node)) | |
228 | + continue; | |
229 | + nlm_xlpii_usb_hw_reset(node, 1); | |
230 | + nlm_xlpii_usb_hw_reset(node, 2); | |
231 | + nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_0_IRQ, xlp9xx_usb_ack); | |
232 | + nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_1_IRQ, xlp9xx_usb_ack); | |
233 | + } | |
192 | 234 | return 0; |
193 | 235 | } |
194 | 236 | |
195 | 237 | |
196 | 238 | |
... | ... | @@ -196,13 +238,31 @@ |
196 | 238 | |
197 | 239 | static u64 xlp_usb_dmamask = ~(u32)0; |
198 | 240 | |
199 | -/* Fixup IRQ for USB devices on XLP the SoC PCIe bus */ | |
200 | -static void nlm_usb_fixup_final(struct pci_dev *dev) | |
241 | +/* Fixup the IRQ for USB devices which is exist on XLP9XX SOC PCIE bus */ | |
242 | +static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev) | |
201 | 243 | { |
244 | + int node; | |
245 | + | |
246 | + node = xlp_socdev_to_node(dev); | |
202 | 247 | dev->dev.dma_mask = &xlp_usb_dmamask; |
203 | 248 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
204 | 249 | switch (dev->devfn) { |
205 | 250 | case 0x21: |
251 | + dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_0_IRQ); | |
252 | + break; | |
253 | + case 0x22: | |
254 | + dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_1_IRQ); | |
255 | + break; | |
256 | + } | |
257 | +} | |
258 | + | |
259 | +/* Fixup the IRQ for USB devices which is exist on XLP2XX SOC PCIE bus */ | |
260 | +static void nlm_xlp2xx_usb_fixup_final(struct pci_dev *dev) | |
261 | +{ | |
262 | + dev->dev.dma_mask = &xlp_usb_dmamask; | |
263 | + dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | |
264 | + switch (dev->devfn) { | |
265 | + case 0x21: | |
206 | 266 | dev->irq = PIC_2XX_XHCI_0_IRQ; |
207 | 267 | break; |
208 | 268 | case 0x22: |
209 | 269 | |
... | ... | @@ -214,6 +274,8 @@ |
214 | 274 | } |
215 | 275 | } |
216 | 276 | |
277 | +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_XHCI, | |
278 | + nlm_xlp9xx_usb_fixup_final); | |
217 | 279 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI, |
218 | - nlm_usb_fixup_final); | |
280 | + nlm_xlp2xx_usb_fixup_final); |