summaryrefslogtreecommitdiffstats
path: root/target/linux/bcm53xx/patches-3.18/190-bcma_hcd_add_bcm5301x_support.patch
blob: 2e528b6a0b08e0f89728d0cd0a1903e95ef5105a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
Subject: [PATCH] bcma-hcd: add BCM5301x platform support

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -88,7 +88,7 @@ static void bcma_hcd_4716wa(struct bcma_
 }
 
 /* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
-static void bcma_hcd_init_chip(struct bcma_device *dev)
+static void bcma_hcd_init_chip_mips(struct bcma_device *dev)
 {
 	u32 tmp;
 
@@ -159,6 +159,52 @@ static void bcma_hcd_init_chip(struct bc
 	}
 }
 
+static void bcma_hcd_init_chip_arm(struct bcma_device *dev)
+{
+	struct bcma_device *arm_core;
+	void __iomem *dmu;
+	u32 val;
+
+	bcma_core_disable(dev, 0);
+	bcma_core_enable(dev, 0);
+
+	msleep(1);
+
+	/* Set packet buffer OUT threshold */
+	val = bcma_read32(dev, 0x94);
+	val &= 0xffff;
+	val |= 0x80 << 16;
+	bcma_write32(dev, 0x94, val);
+
+	/* Enable break memory transfer */
+	val = bcma_read32(dev, 0x9c);
+	val |= 1;
+	bcma_write32(dev, 0x9c, val);
+
+	if (dev->bus->chipinfo.pkg != BCMA_PKG_ID_BCM4707 &&
+	    dev->bus->chipinfo.pkg != BCMA_PKG_ID_BCM4708)
+		return;
+
+	arm_core = bcma_find_core(dev->bus, BCMA_CORE_ARMCA9);
+	if (!arm_core)
+		return;
+
+	dmu = ioremap_nocache(arm_core->addr_s[0], 0x1000);
+	if (!dmu)
+		return;
+
+	/* Unlock DMU PLL settings */
+	iowrite32(0x0000ea68, dmu + 0x180);
+
+	/* Write USB 2.0 PLL control setting */
+	iowrite32(0x00dd10c3, dmu + 0x164);
+
+	/* Lock DMU PLL settings */
+	iowrite32(0x00000000, dmu + 0x180);
+
+	iounmap(dmu);
+}
+
 static const struct usb_ehci_pdata ehci_pdata = {
 };
 
@@ -222,7 +268,8 @@ static int bcma_hcd_probe(struct bcma_de
 	chipinfo = &dev->bus->chipinfo;
 	/* USBcores are only connected on embedded devices. */
 	chipid_top = (chipinfo->id & 0xFF00);
-	if (chipid_top != 0x4700 && chipid_top != 0x5300)
+	if (chipid_top != 0x4700 && chipid_top != 0x5300 &&
+	    chipinfo->id != BCMA_CHIP_ID_BCM4707)
 		return -ENODEV;
 
 	/* TODO: Probably need checks here; is the core connected? */
@@ -234,18 +281,23 @@ static int bcma_hcd_probe(struct bcma_de
 	if (!usb_dev)
 		return -ENOMEM;
 
-	bcma_hcd_init_chip(dev);
-
-	/* In AI chips EHCI is addrspace 0, OHCI is 1 */
-	ohci_addr = dev->addr_s[0];
-	if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
-	    && chipinfo->rev == 0)
-		ohci_addr = 0x18009000;
-
-	usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
-	if (IS_ERR(usb_dev->ohci_dev)) {
-		err = PTR_ERR(usb_dev->ohci_dev);
-		goto err_free_usb_dev;
+	if (IS_BUILTIN(CONFIG_ARCH_BCM_5301X) &&
+	    chipinfo->id == BCMA_CHIP_ID_BCM4707) {
+		bcma_hcd_init_chip_arm(dev);
+	} else if(IS_BUILTIN(CONFIG_BCM47XX)) {
+		bcma_hcd_init_chip_mips(dev);
+
+		/* In AI chips EHCI is addrspace 0, OHCI is 1 */
+		ohci_addr = dev->addr_s[0];
+		if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
+			&& chipinfo->rev == 0)
+			ohci_addr = 0x18009000;
+
+		usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
+		if (IS_ERR(usb_dev->ohci_dev)) {
+			err = PTR_ERR(usb_dev->ohci_dev);
+			goto err_free_usb_dev;
+		}
 	}
 
 	usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
@@ -306,6 +358,7 @@ static int bcma_hcd_resume(struct bcma_d
 
 static const struct bcma_device_id bcma_hcd_table[] = {
 	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
+	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),
 	BCMA_CORETABLE_END
 };
 MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);