void enableAllClockPower() { int i; u32 temp; g_num_u3_port = SSUSB_U3_PORT_NUM(readl((const volatile void __iomem *)SSUSB_IP_CAP)); g_num_u2_port = SSUSB_U2_PORT_NUM(readl((const volatile void __iomem *)SSUSB_IP_CAP)); //2. Enable xHC writel(readl((const volatile void __iomem *)SSUSB_IP_PW_CTRL) | (SSUSB_IP_SW_RST), (volatile void __iomem *)SSUSB_IP_PW_CTRL); writel(readl((const volatile void __iomem *)SSUSB_IP_PW_CTRL) & (~SSUSB_IP_SW_RST), (volatile void __iomem *)SSUSB_IP_PW_CTRL); writel(readl((const volatile void __iomem *)SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN), (volatile void __iomem *)SSUSB_IP_PW_CTRL_1); //1. Enable target ports for(i=0; i<g_num_u3_port; i++){ temp = readl((const volatile void __iomem *)SSUSB_U3_CTRL(i)); temp = temp & (~SSUSB_U3_PORT_PDN) & (~SSUSB_U3_PORT_DIS); writel(temp, (volatile void __iomem *)SSUSB_U3_CTRL(i)); } for(i=0; i<g_num_u2_port; i++){ temp = readl((const volatile void __iomem *)SSUSB_U2_CTRL(i)); temp = temp & (~SSUSB_U2_PORT_PDN) & (~SSUSB_U2_PORT_DIS); writel(temp, (volatile void __iomem *)SSUSB_U2_CTRL(i)); } mdelay(100); }
//if IP ctrl power is disabled, enable it //enable clock/power of a port //port_index: port number //port_rev: 0x2 - USB2.0, 0x3 - USB3.0 (SuperSpeed) void mtktest_enablePortClockPower(int port_index, int port_rev){ int i; u32 temp; int real_index; #if TEST_OTG return; #endif #if CON_HOST_DEV real_index = getRealPortIndex(port_index, port_rev); #else real_index = port_index; #endif writel(readl(SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN), SSUSB_IP_PW_CTRL_1); if(port_rev == 0x3){ temp = readl(SSUSB_U3_CTRL(real_index)); temp = temp & (~SSUSB_U3_PORT_PDN); writel(temp, SSUSB_U3_CTRL(real_index)); } else if(port_rev == 0x2){ temp = readl(SSUSB_U2_CTRL(real_index)); temp = temp & (~SSUSB_U2_PORT_PDN); writel(temp, SSUSB_U2_CTRL(real_index)); } }
/* only port0 of U2/U3 supports device mode */ static int mtu3_device_enable(struct mtu3 *mtu) { void __iomem *ibase = mtu->ippc_base; u32 check_clk = 0; mtu3_clrbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); if (mtu->is_u3_ip) { check_clk = SSUSB_U3_MAC_RST_B_STS; mtu3_clrbits(ibase, SSUSB_U3_CTRL(0), (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_HOST_SEL)); } mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_HOST_SEL)); if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) { mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL); if (mtu->is_u3_ip) mtu3_setbits(ibase, SSUSB_U3_CTRL(0), SSUSB_U3_PORT_DUAL_MODE); } return ssusb_check_clocks(mtu->ssusb, check_clk); }
void mtktest_enableAllClockPower(){ int i; u32 temp; int num_u3_port; int num_u2_port; num_u3_port = SSUSB_U3_PORT_NUM(readl(SSUSB_IP_CAP)); num_u2_port = SSUSB_U2_PORT_NUM(readl(SSUSB_IP_CAP)); //usb_phy_recover(0) ; //2. Enable xHC #if TEST_OTG writel(readl(SSUSB_IP_PW_CTRL) & (~SSUSB_IP_SW_RST), SSUSB_IP_PW_CTRL); writel(readl(SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN), SSUSB_IP_PW_CTRL_1); #else writel(readl(SSUSB_IP_PW_CTRL) | (SSUSB_IP_SW_RST), SSUSB_IP_PW_CTRL); writel(readl(SSUSB_IP_PW_CTRL) & (~SSUSB_IP_SW_RST), SSUSB_IP_PW_CTRL); writel(readl(SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN), SSUSB_IP_PW_CTRL_1); #endif //1. Enable target ports for(i=0; i<num_u3_port; i++){ temp = readl(SSUSB_U3_CTRL(i)); #if CON_HOST_DEV if(temp & SSUSB_U3_PORT_HOST_SEL){ temp = temp & (~SSUSB_U3_PORT_PDN) & (~SSUSB_U3_PORT_DIS); } #else temp = temp & (~SSUSB_U3_PORT_PDN) & (~SSUSB_U3_PORT_DIS); #endif writel(temp, SSUSB_U3_CTRL(i)); } for(i=0; i<num_u2_port; i++){ temp = readl(SSUSB_U2_CTRL(i)); #if CON_HOST_DEV if(temp & SSUSB_U2_PORT_HOST_SEL){ temp = temp & (~SSUSB_U2_PORT_PDN) & (~SSUSB_U2_PORT_DIS); } #else #if TEST_OTG temp = temp & (~SSUSB_U2_PORT_PDN) & (~SSUSB_U2_PORT_DIS) & (~SSUSB_U2_PORT_HOST_SEL); temp = temp | SSUSB_U2_PORT_OTG_SEL | SSUSB_U2_PORT_OTG_MAC_AUTO_SEL | SSUSB_U2_PORT_HOST_SEL; #else temp = temp & (~SSUSB_U2_PORT_PDN) & (~SSUSB_U2_PORT_DIS); #endif #endif writel(temp, SSUSB_U2_CTRL(i)); #if 0 writel(0xf, 0xf00447b0); writel((readl(0xf00447b4) & ~(0xffff) | (0x0001)), 0xf00447b4); writel((readl(0xf00447bc) & ~(0xff) | (0x0f)), 0xf00447bc); #endif } msleep(100); }
static void mtu3_device_disable(struct mtu3 *mtu) { void __iomem *ibase = mtu->ippc_base; if (mtu->is_u3_ip) mtu3_setbits(ibase, SSUSB_U3_CTRL(0), (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN)); mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN); if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL); mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); }
//if IP ctrl power is disabled, enable it //enable clock/power of a port //port_index: port number //port_rev: 0x2 - USB2.0, 0x3 - USB3.0 (SuperSpeed) void enablePortClockPower(int port_index, int port_rev) { u32 temp; writel(readl((const volatile void __iomem *)SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN), (volatile void __iomem *)SSUSB_IP_PW_CTRL_1); if(port_rev == 0x3){ temp = readl((const volatile void __iomem *)SSUSB_U3_CTRL(port_index)); temp = temp & (~SSUSB_U3_PORT_PDN); writel(temp, (volatile void __iomem *)SSUSB_U3_CTRL(port_index)); } else if(port_rev == 0x2){ temp = readl((const volatile void __iomem *)SSUSB_U2_CTRL(port_index)); temp = temp & (~SSUSB_U2_PORT_PDN); writel(temp, (volatile void __iomem *)SSUSB_U2_CTRL(port_index)); } }
//if IP ctrl power is disabled, enable it //enable clock/power of a port //port_index: port number //port_rev: 0x2 - USB2.0, 0x3 - USB3.0 (SuperSpeed) void enablePortClockPower(int port_index, int port_rev){ int i; u32 temp; writel(readl(SSUSB_IP_PW_CTRL_1) & (~SSUSB_IP_PDN), SSUSB_IP_PW_CTRL_1); if(port_rev == 0x3){ temp = readl(SSUSB_U3_CTRL(port_index)); temp = temp & (~SSUSB_U3_PORT_PDN); writel(temp, SSUSB_U3_CTRL(port_index)); } else if(port_rev == 0x2){ temp = readl(SSUSB_U2_CTRL(port_index)); temp = temp & (~SSUSB_U2_PORT_PDN); writel(temp, SSUSB_U2_CTRL(port_index)); } }
//(X)disable clock/power of a port //(X)if all ports are disabled, disable IP ctrl power //disable all ports and IP clock/power, this is just mention HW that the power/clock of port //and IP could be disable if suspended. //If doesn't not disable all ports at first, the IP clock/power will never be disabled //(some U2 and U3 ports are binded to the same connection, that is, they will never enter suspend at the same time //port_index: port number //port_rev: 0x2 - USB2.0, 0x3 - USB3.0 (SuperSpeed) void disablePortClockPower(void){ int i; u32 temp; g_num_u3_port = SSUSB_U3_PORT_NUM(readl(SSUSB_IP_CAP)); g_num_u2_port = SSUSB_U2_PORT_NUM(readl(SSUSB_IP_CAP)); for(i=0; i<g_num_u3_port; i++){ temp = readl(SSUSB_U3_CTRL(i)); temp = temp | (SSUSB_U3_PORT_PDN); writel(temp, SSUSB_U3_CTRL(i)); } for(i=0; i<g_num_u2_port; i++){ temp = readl(SSUSB_U2_CTRL(i)); temp = temp | (SSUSB_U2_PORT_PDN); writel(temp, SSUSB_U2_CTRL(i)); } writel(readl(SSUSB_IP_PW_CTRL_1) | (SSUSB_IP_PDN), SSUSB_IP_PW_CTRL_1); }
//called after HC initiated void mtktest_disableAllClockPower(){ int i; u32 temp; int num_u3_port; int num_u2_port; #if TEST_OTG return; #endif num_u3_port = SSUSB_U3_PORT_NUM(readl(SSUSB_IP_CAP)); num_u2_port = SSUSB_U2_PORT_NUM(readl(SSUSB_IP_CAP)); //disable target ports for(i=0; i<num_u3_port; i++){ temp = readl(SSUSB_U3_CTRL(i)); #if CON_HOST_DEV if(temp & SSUSB_U3_PORT_HOST_SEL){ temp = temp | SSUSB_U3_PORT_PDN; } #else temp = temp | SSUSB_U3_PORT_PDN; #endif writel(temp, SSUSB_U3_CTRL(i)); } for(i=0; i<num_u2_port; i++){ temp = readl(SSUSB_U2_CTRL(i)); #if CON_HOST_DEV if(temp & SSUSB_U2_PORT_HOST_SEL){ temp = temp | SSUSB_U2_PORT_PDN; } #else temp = temp | SSUSB_U2_PORT_PDN; #endif writel(temp, SSUSB_U2_CTRL(i)); } msleep(100); }
/* only port0 supports dual-role mode */ static int ssusb_port0_switch(struct ssusb_mtk *ssusb, int version, bool tohost) { void __iomem *ibase = ssusb->ippc_base; u32 value; dev_dbg(ssusb->dev, "%s (switch u%d port0 to %s)\n", __func__, version, tohost ? "host" : "device"); if (version == USB2_PORT) { /* 1. power off and disable u2 port0 */ value = mtu3_readl(ibase, SSUSB_U2_CTRL(0)); value |= SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS; mtu3_writel(ibase, SSUSB_U2_CTRL(0), value); /* 2. power on, enable u2 port0 and select its mode */ value = mtu3_readl(ibase, SSUSB_U2_CTRL(0)); value &= ~(SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_DIS); value = tohost ? (value | SSUSB_U2_PORT_HOST_SEL) : (value & (~SSUSB_U2_PORT_HOST_SEL)); mtu3_writel(ibase, SSUSB_U2_CTRL(0), value); } else { /* 1. power off and disable u3 port0 */ value = mtu3_readl(ibase, SSUSB_U3_CTRL(0)); value |= SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS; mtu3_writel(ibase, SSUSB_U3_CTRL(0), value); /* 2. power on, enable u3 port0 and select its mode */ value = mtu3_readl(ibase, SSUSB_U3_CTRL(0)); value &= ~(SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_DIS); value = tohost ? (value | SSUSB_U3_PORT_HOST_SEL) : (value & (~SSUSB_U3_PORT_HOST_SEL)); mtu3_writel(ibase, SSUSB_U3_CTRL(0), value); } return 0; }
//filter those ports assigned to device int getU2PortNumber(){ int port_num; int real_port_num; int i, temp; //check if any port assigned to device port_num = SSUSB_U2_PORT_NUM(readl(SSUSB_IP_CAP)); real_port_num = port_num; for(i=0; i<port_num; i++){ temp = readl(SSUSB_U2_CTRL(i)); if(!(temp & SSUSB_U2_PORT_HOST_SEL)){ real_port_num--; } } return real_port_num; }
//filter those ports assigned to device int getRealPortIndex(int port_index, int port_rev){ int real_port_index, tmp_port_index; int i, temp; int portNum; real_port_index = 0; tmp_port_index = 0; if(port_rev == 0x3){ //SS port portNum = getU3PortNumber(); for(i=0; i<portNum; i++){ temp = SSUSB_U3_CTRL(i); tmp_port_index++; if(temp & SSUSB_U3_PORT_HOST_SEL){ real_port_index++; if(real_port_index == port_index){ return tmp_port_index; } } } } else{ //HS port portNum = getU2PortNumber(); for(i=0; i<portNum; i++){ temp = SSUSB_U2_CTRL(i); tmp_port_index++; if(temp & SSUSB_U2_PORT_HOST_SEL){ real_port_index++; if(real_port_index == port_index){ return tmp_port_index; } } } } return port_index; }