aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic
diff options
context:
space:
mode:
authorGanesan Ramalingam <ganesanr@broadcom.com>2013-12-21 06:22:28 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-01-24 16:39:49 -0500
commit3262b21ef8523175f0758f4deccec048e73d5b18 (patch)
tree0728cd36407fcd39c3c21c2698ff859cba3c78fd /arch/mips/netlogic
parentb6ba1c5294c3f51fd4cf8b0d60de4ba82ef2a1c9 (diff)
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/
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c4
-rw-r--r--arch/mips/netlogic/xlp/usb-init-xlp2.c88
2 files changed, 79 insertions, 13 deletions
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index e7ff2d37a464..997cd9ee10de 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -72,6 +72,10 @@ int nlm_irq_to_irt(int irq)
72 /* bypass for 9xx */ 72 /* bypass for 9xx */
73 if (cpu_is_xlp9xx()) { 73 if (cpu_is_xlp9xx()) {
74 switch (irq) { 74 switch (irq) {
75 case PIC_9XX_XHCI_0_IRQ:
76 return 114;
77 case PIC_9XX_XHCI_1_IRQ:
78 return 115;
75 case PIC_UART_0_IRQ: 79 case PIC_UART_0_IRQ:
76 return 133; 80 return 133;
77 case PIC_UART_1_IRQ: 81 case PIC_UART_1_IRQ:
diff --git a/arch/mips/netlogic/xlp/usb-init-xlp2.c b/arch/mips/netlogic/xlp/usb-init-xlp2.c
index 36e9c22afc46..17ade1ce5dfd 100644
--- a/arch/mips/netlogic/xlp/usb-init-xlp2.c
+++ b/arch/mips/netlogic/xlp/usb-init-xlp2.c
@@ -37,6 +37,7 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/pci_ids.h>
40#include <linux/platform_device.h> 41#include <linux/platform_device.h>
41#include <linux/irq.h> 42#include <linux/irq.h>
42 43
@@ -83,12 +84,14 @@
83#define nlm_read_usb_reg(b, r) nlm_read_reg(b, r) 84#define nlm_read_usb_reg(b, r) nlm_read_reg(b, r)
84#define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v) 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#define nlm_xlpii_get_usb_pcibase(node, inst) \
87 nlm_pcicfg_base(XLP2XX_IO_USB_OFFSET(node, inst)) 88 nlm_pcicfg_base(cpu_is_xlp9xx() ? \
89 XLP9XX_IO_USB_OFFSET(node, inst) : \
90 XLP2XX_IO_USB_OFFSET(node, inst))
88#define nlm_xlpii_get_usb_regbase(node, inst) \ 91#define nlm_xlpii_get_usb_regbase(node, inst) \
89 (nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ) 92 (nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
90 93
91static void xlpii_usb_ack(struct irq_data *data) 94static void xlp2xx_usb_ack(struct irq_data *data)
92{ 95{
93 u64 port_addr; 96 u64 port_addr;
94 97
@@ -109,6 +112,29 @@ static void xlpii_usb_ack(struct irq_data *data)
109 nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff); 112 nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
110} 113}
111 114
115static 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
112static void nlm_xlpii_usb_hw_reset(int node, int port) 138static void nlm_xlpii_usb_hw_reset(int node, int port)
113{ 139{
114 u64 port_addr, xhci_base, pci_base; 140 u64 port_addr, xhci_base, pci_base;
@@ -178,17 +204,33 @@ static void nlm_xlpii_usb_hw_reset(int node, int port)
178 204
179static int __init nlm_platform_xlpii_usb_init(void) 205static int __init nlm_platform_xlpii_usb_init(void)
180{ 206{
207 int node;
208
181 if (!cpu_is_xlpii()) 209 if (!cpu_is_xlpii())
182 return 0; 210 return 0;
183 211
184 pr_info("Initializing 2XX USB Interface\n"); 212 if (!cpu_is_xlp9xx()) {
185 nlm_xlpii_usb_hw_reset(0, 1); 213 /* XLP 2XX single node */
186 nlm_xlpii_usb_hw_reset(0, 2); 214 pr_info("Initializing 2XX USB Interface\n");
187 nlm_xlpii_usb_hw_reset(0, 3); 215 nlm_xlpii_usb_hw_reset(0, 1);
188 nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlpii_usb_ack); 216 nlm_xlpii_usb_hw_reset(0, 2);
189 nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlpii_usb_ack); 217 nlm_xlpii_usb_hw_reset(0, 3);
190 nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlpii_usb_ack); 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 return 0; 234 return 0;
193} 235}
194 236
@@ -196,8 +238,26 @@ arch_initcall(nlm_platform_xlpii_usb_init);
196 238
197static u64 xlp_usb_dmamask = ~(u32)0; 239static u64 xlp_usb_dmamask = ~(u32)0;
198 240
199/* Fixup IRQ for USB devices on XLP the SoC PCIe bus */ 241/* Fixup the IRQ for USB devices which is exist on XLP9XX SOC PCIE bus */
200static void nlm_usb_fixup_final(struct pci_dev *dev) 242static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev)
243{
244 int node;
245
246 node = xlp_socdev_to_node(dev);
247 dev->dev.dma_mask = &xlp_usb_dmamask;
248 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
249 switch (dev->devfn) {
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 */
260static void nlm_xlp2xx_usb_fixup_final(struct pci_dev *dev)
201{ 261{
202 dev->dev.dma_mask = &xlp_usb_dmamask; 262 dev->dev.dma_mask = &xlp_usb_dmamask;
203 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); 263 dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
@@ -214,5 +274,7 @@ static void nlm_usb_fixup_final(struct pci_dev *dev)
214 } 274 }
215} 275}
216 276
277DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_XHCI,
278 nlm_xlp9xx_usb_fixup_final);
217DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI, 279DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI,
218 nlm_usb_fixup_final); 280 nlm_xlp2xx_usb_fixup_final);