aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ar71xx/patches-4.9/920-usb-chipidea-AR933x-platform-support.patch
blob: b33bf755e94b3c8d9f362cd84d874dfcaa8bb1d7 (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
123
124
125
126
127
128
129
130
131
132
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -659,6 +659,7 @@
 
 #define AR933X_BOOTSTRAP_MDIO_GPIO_EN	BIT(18)
 #define AR933X_BOOTSTRAP_EEPBUSY	BIT(4)
+#define AR933X_BOOTSTRAP_USB_MODE_HOST	BIT(3)
 #define AR933X_BOOTSTRAP_REF_CLK_40	BIT(0)
 
 #define AR934X_BOOTSTRAP_SW_OPTION8	BIT(23)
@@ -688,6 +689,8 @@
 
 #define QCA956X_BOOTSTRAP_REF_CLK_40	BIT(2)
 
+#define AR933X_USB_CONFIG_HOST_ONLY   BIT(8)
+
 #define AR934X_PCIE_WMAC_INT_WMAC_MISC		BIT(0)
 #define AR934X_PCIE_WMAC_INT_WMAC_TX		BIT(1)
 #define AR934X_PCIE_WMAC_INT_WMAC_RXLP		BIT(2)
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -19,6 +19,9 @@
 #include <linux/platform_device.h>
 #include <linux/usb/ehci_pdriver.h>
 #include <linux/usb/ohci_pdriver.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/chipidea.h>
+#include <linux/usb/usb_phy_generic.h>
 
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
@@ -170,6 +173,64 @@ static void __init ar913x_usb_setup(void
 			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
 }
 
+static void __init ar933x_usb_setup_ctrl_config(void)
+{
+	void __iomem *usb_ctrl_base, *usb_config_reg;
+	u32 usb_config;
+
+	usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE);
+	usb_config_reg = usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG;
+	usb_config = __raw_readl(usb_config_reg);
+	usb_config &= ~AR933X_USB_CONFIG_HOST_ONLY;
+	__raw_writel(usb_config, usb_config_reg);
+	iounmap(usb_ctrl_base);
+}
+
+static void __init ar9xxx_ci_usb_setup(int irq)
+{
+	struct ci_hdrc_platform_data ci_pdata;
+	enum usb_dr_mode dr_mode;
+	bool host_mode = true;
+
+	if (soc_is_ar933x())
+		host_mode = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP) &
+			    AR933X_BOOTSTRAP_USB_MODE_HOST;
+	else if (soc_is_ar934x() || soc_is_qca955x())
+		host_mode = !(ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP) &
+			      AR934X_BOOTSTRAP_USB_MODE_DEVICE);
+
+	if (host_mode) {
+		dr_mode = USB_DR_MODE_HOST;
+	} else {
+		dr_mode = USB_DR_MODE_PERIPHERAL;
+		if (soc_is_ar933x())
+			ar933x_usb_setup_ctrl_config();
+	}
+
+	memset(&ci_pdata, 0, sizeof(ci_pdata));
+	ci_pdata.name = "ci_hdrc_ar9xxx";
+	ci_pdata.capoffset = DEF_CAPOFFSET;
+	ci_pdata.dr_mode = dr_mode;
+	ci_pdata.flags = CI_HDRC_DUAL_ROLE_NOT_OTG | CI_HDRC_DP_ALWAYS_PULLUP;
+	ci_pdata.vbus_extcon.edev = ERR_PTR(-ENODEV);
+	ci_pdata.id_extcon.edev = ERR_PTR(-ENODEV);
+	ci_pdata.itc_setting = 1;
+
+	platform_device_register_simple("usb_phy_generic",
+					PLATFORM_DEVID_AUTO, NULL, 0);
+
+	if (!host_mode)
+		ath79_usb_register("ci_hdrc", -1,
+				   AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
+				   irq, &ci_pdata, sizeof(ci_pdata));
+	else
+		ath79_usb_register("ehci-platform", -1,
+				   AR934X_EHCI_BASE, AR934X_EHCI_SIZE,
+				   irq, &ath79_ehci_pdata_v2,
+				   sizeof(ath79_ehci_pdata_v2));
+
+}
+
 static void __init ar933x_usb_setup(void)
 {
 	ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
@@ -181,10 +242,7 @@ static void __init ar933x_usb_setup(void
 	ath79_device_reset_clear(AR933X_RESET_USB_PHY);
 	mdelay(10);
 
-	ath79_usb_register("ehci-platform", -1,
-			   AR933X_EHCI_BASE, AR933X_EHCI_SIZE,
-			   ATH79_CPU_IRQ(3),
-			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+	ar9xxx_ci_usb_setup(ATH79_CPU_IRQ(3));
 }
 
 static void enable_tx_tx_idp_violation_fix(unsigned base)
@@ -230,10 +288,7 @@ static void __init ar934x_usb_setup(void
 	if (ath79_soc_rev >= 3)
 		ath79_ehci_pdata_v2.reset_notifier = ar934x_usb_reset_notifier;
 
-	ath79_usb_register("ehci-platform", -1,
-			   AR934X_EHCI_BASE, AR934X_EHCI_SIZE,
-			   ATH79_CPU_IRQ(3),
-			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+	ar9xxx_ci_usb_setup(ATH79_CPU_IRQ(3));
 }
 
 static void __init qca953x_usb_setup(void)
@@ -285,10 +340,7 @@ static void __init qca955x_usb_setup(voi
 {
 	ath79_ehci_pdata_v2.reset_notifier = qca955x_usb_reset_notifier;
 
-	ath79_usb_register("ehci-platform", 0,
-			   QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE,
-			   ATH79_IP3_IRQ(0),
-			   &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+	ar9xxx_ci_usb_setup(ATH79_IP3_IRQ(0));
 
 	ath79_usb_register("ehci-platform", 1,
 			   QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE,