Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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/

authored by

Ganesan Ramalingam and committed by
Ralf Baechle
3262b21e b6ba1c52

+84 -13
+3
arch/mips/include/asm/netlogic/xlp-hal/iomap.h
··· 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)
+2
arch/mips/include/asm/netlogic/xlp-hal/xlp.h
··· 50 50 #define PIC_2XX_XHCI_0_IRQ 23 51 51 #define PIC_2XX_XHCI_1_IRQ 24 52 52 #define PIC_2XX_XHCI_2_IRQ 25 53 + #define PIC_9XX_XHCI_0_IRQ 23 54 + #define PIC_9XX_XHCI_1_IRQ 24 53 55 54 56 #define PIC_MMC_IRQ 29 55 57 #define PIC_I2C_0_IRQ 30
+4
arch/mips/netlogic/xlp/nlm_hal.c
··· 72 72 /* bypass for 9xx */ 73 73 if (cpu_is_xlp9xx()) { 74 74 switch (irq) { 75 + case PIC_9XX_XHCI_0_IRQ: 76 + return 114; 77 + case PIC_9XX_XHCI_1_IRQ: 78 + return 115; 75 79 case PIC_UART_0_IRQ: 76 80 return 133; 77 81 case PIC_UART_1_IRQ:
+75 -13
arch/mips/netlogic/xlp/usb-init-xlp2.c
··· 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 ··· 84 83 #define nlm_read_usb_reg(b, r) nlm_read_reg(b, r) 85 84 #define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v) 86 85 87 - #define nlm_xlpii_get_usb_pcibase(node, inst) \ 88 - nlm_pcicfg_base(XLP2XX_IO_USB_OFFSET(node, inst)) 86 + #define nlm_xlpii_get_usb_pcibase(node, inst) \ 87 + nlm_pcicfg_base(cpu_is_xlp9xx() ? \ 88 + XLP9XX_IO_USB_OFFSET(node, inst) : \ 89 + XLP2XX_IO_USB_OFFSET(node, inst)) 89 90 #define nlm_xlpii_get_usb_regbase(node, inst) \ 90 91 (nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ) 91 92 92 - static void xlpii_usb_ack(struct irq_data *data) 93 + static void xlp2xx_usb_ack(struct irq_data *data) 93 94 { 94 95 u64 port_addr; 95 96 ··· 107 104 break; 108 105 default: 109 106 pr_err("No matching USB irq!\n"); 107 + return; 108 + } 109 + nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff); 110 + } 111 + 112 + static void xlp9xx_usb_ack(struct irq_data *data) 113 + { 114 + u64 port_addr; 115 + int node, irq; 116 + 117 + /* Find the node and irq on the node */ 118 + irq = data->irq % NLM_IRQS_PER_NODE; 119 + node = data->irq / NLM_IRQS_PER_NODE; 120 + 121 + switch (irq) { 122 + case PIC_9XX_XHCI_0_IRQ: 123 + port_addr = nlm_xlpii_get_usb_regbase(node, 1); 124 + break; 125 + case PIC_9XX_XHCI_1_IRQ: 126 + port_addr = nlm_xlpii_get_usb_regbase(node, 2); 127 + break; 128 + default: 129 + pr_err("No matching USB irq %d node %d!\n", irq, node); 110 130 return; 111 131 } 112 132 nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff); ··· 204 178 205 179 static int __init nlm_platform_xlpii_usb_init(void) 206 180 { 181 + int node; 182 + 207 183 if (!cpu_is_xlpii()) 208 184 return 0; 209 185 210 - pr_info("Initializing 2XX USB Interface\n"); 211 - nlm_xlpii_usb_hw_reset(0, 1); 212 - nlm_xlpii_usb_hw_reset(0, 2); 213 - nlm_xlpii_usb_hw_reset(0, 3); 214 - nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlpii_usb_ack); 215 - nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlpii_usb_ack); 216 - nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlpii_usb_ack); 186 + if (!cpu_is_xlp9xx()) { 187 + /* XLP 2XX single node */ 188 + pr_info("Initializing 2XX USB Interface\n"); 189 + nlm_xlpii_usb_hw_reset(0, 1); 190 + nlm_xlpii_usb_hw_reset(0, 2); 191 + nlm_xlpii_usb_hw_reset(0, 3); 192 + nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlp2xx_usb_ack); 193 + nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlp2xx_usb_ack); 194 + nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlp2xx_usb_ack); 195 + return 0; 196 + } 217 197 198 + /* XLP 9XX, multi-node */ 199 + pr_info("Initializing 9XX USB Interface\n"); 200 + for (node = 0; node < NLM_NR_NODES; node++) { 201 + if (!nlm_node_present(node)) 202 + continue; 203 + nlm_xlpii_usb_hw_reset(node, 1); 204 + nlm_xlpii_usb_hw_reset(node, 2); 205 + nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_0_IRQ, xlp9xx_usb_ack); 206 + nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_1_IRQ, xlp9xx_usb_ack); 207 + } 218 208 return 0; 219 209 } 220 210 ··· 238 196 239 197 static u64 xlp_usb_dmamask = ~(u32)0; 240 198 241 - /* Fixup IRQ for USB devices on XLP the SoC PCIe bus */ 242 - static void nlm_usb_fixup_final(struct pci_dev *dev) 199 + /* Fixup the IRQ for USB devices which is exist on XLP9XX SOC PCIE bus */ 200 + static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev) 201 + { 202 + int node; 203 + 204 + node = xlp_socdev_to_node(dev); 205 + dev->dev.dma_mask = &xlp_usb_dmamask; 206 + dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 207 + switch (dev->devfn) { 208 + case 0x21: 209 + dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_0_IRQ); 210 + break; 211 + case 0x22: 212 + dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_1_IRQ); 213 + break; 214 + } 215 + } 216 + 217 + /* Fixup the IRQ for USB devices which is exist on XLP2XX SOC PCIE bus */ 218 + static void nlm_xlp2xx_usb_fixup_final(struct pci_dev *dev) 243 219 { 244 220 dev->dev.dma_mask = &xlp_usb_dmamask; 245 221 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); ··· 274 214 } 275 215 } 276 216 217 + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_XHCI, 218 + nlm_xlp9xx_usb_fixup_final); 277 219 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI, 278 - nlm_usb_fixup_final); 220 + nlm_xlp2xx_usb_fixup_final);