* host only, device only or dual-role mode
* @u2_ports: number of usb2.0 host ports
* @u3_ports: number of usb3.0 host ports
+ * @u2p_dis_msk: mask of disabling usb2 ports, e.g. bit0==1 to
+ * disable u2port0, bit1==1 to disable u2port1,... etc,
+ * but when use dual-role mode, can't disable u2port0
* @u3p_dis_msk: mask of disabling usb3 ports, for example, bit0==1 to
* disable u3port0, bit1==1 to disable u3port1,... etc
* @dbgfs_root: only used when supports manual dual-role switch via debugfs
bool is_host;
int u2_ports;
int u3_ports;
+ int u2p_dis_msk;
int u3p_dis_msk;
struct dentry *dbgfs_root;
/* usb wakeup for host mode */
/* power on and enable all u2 ports */
for (i = 0; i < num_u2p; i++) {
+ if ((0x1 << i) & ssusb->u2p_dis_msk)
+ continue;
+
value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
value &= ~(SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS);
value |= SSUSB_U2_PORT_HOST_SEL;
mtu3_writel(ibase, SSUSB_U3_CTRL(i), value);
}
- /* power down and disable all u2 ports */
+ /* power down and disable u2 ports except skipped ones */
for (i = 0; i < num_u2p; i++) {
+ if ((0x1 << i) & ssusb->u2p_dis_msk)
+ continue;
+
value = mtu3_readl(ibase, SSUSB_U2_CTRL(i));
value |= SSUSB_U2_PORT_PDN;
value |= suspend ? 0 : SSUSB_U2_PORT_DIS;
/* optional property, ignore the error if it does not exist */
of_property_read_u32(node, "mediatek,u3p-dis-msk",
&ssusb->u3p_dis_msk);
+ of_property_read_u32(node, "mediatek,u2p-dis-msk",
+ &ssusb->u2p_dis_msk);
otg_sx->vbus = devm_regulator_get(dev, "vbus");
if (IS_ERR(otg_sx->vbus)) {
of_property_read_bool(node, "enable-manual-drd");
otg_sx->role_sw_used = of_property_read_bool(node, "usb-role-switch");
+ /* can't disable port0 when use dual-role mode */
+ ssusb->u2p_dis_msk &= ~0x1;
+
if (otg_sx->role_sw_used || otg_sx->manual_drd_enabled)
goto out;
}
out:
- dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk: %x, drd: %s\n",
- ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk,
+ dev_info(dev, "dr_mode: %d, is_u3_dr: %d, drd: %s\n",
+ ssusb->dr_mode, otg_sx->is_u3_drd,
otg_sx->manual_drd_enabled ? "manual" : "auto");
+ dev_info(dev, "u2p_dis_msk: %x, u3p_dis_msk: %x\n",
+ ssusb->u2p_dis_msk, ssusb->u3p_dis_msk);
return 0;
}