+void rk_usb_power_up(void)
+{
+ struct dwc_otg_platform_data *pldata_otg;
+#ifdef CONFIG_USB20_HOST
+ struct dwc_otg_platform_data *pldata_host;
+#endif
+#ifdef CONFIG_USB_EHCI_RK
+ struct rkehci_platform_data *pldata_ehci;
+#endif
+
+ if (is_rk3288_usb()) {
+#ifdef CONFIG_RK_USB_UART
+ /* enable USB bypass UART function */
+ writel_relaxed(0x00c00000 | usb_to_uart_status,
+ RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
+
+#endif
+ /* unset siddq,the analog blocks are powered up */
+#ifdef CONFIG_USB20_OTG
+ pldata_otg = &usb20otg_pdata_rk3288;
+ if (pldata_otg) {
+ if (pldata_otg->phy_status == USB_PHY_SUSPEND)
+ writel_relaxed((0x01 << 13) << 16,
+ RK_GRF_VIRT +
+ RK3288_GRF_UOC0_CON0);
+ }
+#endif
+#ifdef CONFIG_USB20_HOST
+ pldata_host = &usb20host_pdata_rk3288;
+ if (pldata_host) {
+ if (pldata_host->phy_status == USB_PHY_SUSPEND)
+ writel_relaxed((0x01 << 13) << 16,
+ RK_GRF_VIRT +
+ RK3288_GRF_UOC2_CON0);
+ }
+#endif
+#ifdef CONFIG_USB_EHCI_RK
+ pldata_ehci = &rkehci_pdata_rk3288;
+ if (pldata_ehci) {
+ if (pldata_ehci->phy_status == USB_PHY_SUSPEND)
+ writel_relaxed((0x01 << 13) << 16,
+ RK_GRF_VIRT +
+ RK3288_GRF_UOC1_CON0);
+ }
+#endif
+
+ } else {
+ dwc_otg_device_t *otg_dev = g_otgdev;
+
+ if (!otg_dev)
+ return;
+
+ pldata_otg = otg_dev->pldata;
+ if (pldata_otg && pldata_otg->phy_power_down)
+ pldata_otg->phy_power_down(PHY_POWER_UP);
+ }
+}
+
+void rk_usb_power_down(void)
+{
+ struct dwc_otg_platform_data *pldata_otg;
+#ifdef CONFIG_USB20_HOST
+ struct dwc_otg_platform_data *pldata_host;
+#endif
+#ifdef CONFIG_USB_EHCI_RK
+ struct rkehci_platform_data *pldata_ehci;
+#endif
+
+ if (is_rk3288_usb()) {
+#ifdef CONFIG_RK_USB_UART
+ /* disable USB bypass UART function */
+ usb_to_uart_status =
+ readl_relaxed(RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
+ writel_relaxed(0x00c00000, RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
+#endif
+ /* set siddq,the analog blocks are powered down
+ * note:
+ * 1. Before asserting SIDDQ, ensure that VDATSRCENB0,
+ * VDATDETENB0, DCDENB0, BYPASSSEL0, ADPPRBENB0,
+ * and TESTBURNIN are set to 1'b0.
+ * 2. Before asserting SIDDQ, ensure that phy enter suspend.*/
+#ifdef CONFIG_USB20_OTG
+ pldata_otg = &usb20otg_pdata_rk3288;
+ if (pldata_otg) {
+ if (pldata_otg->phy_status == USB_PHY_SUSPEND)
+ writel_relaxed((0x01 << 13) |
+ ((0x01 << 13) << 16),
+ RK_GRF_VIRT +
+ RK3288_GRF_UOC0_CON0);
+ }
+#endif
+#ifdef CONFIG_USB20_HOST
+ pldata_host = &usb20host_pdata_rk3288;
+ if (pldata_host) {
+ if (pldata_host->phy_status == USB_PHY_SUSPEND)
+ writel_relaxed((0x01 << 13) |
+ ((0x01 << 13) << 16),
+ RK_GRF_VIRT +
+ RK3288_GRF_UOC2_CON0);
+ }
+#endif
+#ifdef CONFIG_USB_EHCI_RK
+ pldata_ehci = &rkehci_pdata_rk3288;
+ if (pldata_ehci) {
+ if (pldata_ehci->phy_status == USB_PHY_SUSPEND)
+ writel_relaxed((0x01 << 13) |
+ ((0x01 << 13) << 16),
+ RK_GRF_VIRT +
+ RK3288_GRF_UOC1_CON0);
+ }
+#endif
+ } else {
+ dwc_otg_device_t *otg_dev = g_otgdev;
+
+ if (!otg_dev)
+ return;
+
+ pldata_otg = otg_dev->pldata;
+ if (pldata_otg && pldata_otg->phy_power_down)
+ pldata_otg->phy_power_down(PHY_POWER_DOWN);
+ }
+}
+
+EXPORT_SYMBOL(rk_usb_power_up);
+EXPORT_SYMBOL(rk_usb_power_down);