#include <spl.h>
#include <env.h>
#include <asm/mach-imx/imx_vservice.h>
+#include <usb/ci_udc.h>
DECLARE_GLOBAL_DATA_PTR;
}
#ifdef CONFIG_USB_PORT_AUTO
-int usb_boot_index = 0xf;
-
static int usb_port_auto_check(void)
{
int ret;
}
enable_usboh3_clk(1);
- usb2_data = readl(USB_BASE_ADDR + 0x154);
+ usb2_data = ci_udc_check_bus_active(USB_BASE_ADDR, USB_PHY0_BASE_ADDR, 0);
ret = power_domain_off(&phy_pd);
if (ret) {
return -1;
}
-static void usb_port_record_index(void)
+int board_usb_gadget_port_auto(void)
{
+ int usb_boot_index;
usb_boot_index = usb_port_auto_check();
+
if (usb_boot_index < 0)
usb_boot_index = 0;
-}
-int board_usb_gadget_port_auto(void)
-{
-#if defined(CONFIG_SPL_BUILD)
- usb_port_record_index();
-#endif
+ printf("auto usb %d\n", usb_boot_index);
return usb_boot_index;
}
static void power_off_all_usb(void)
{
if (is_usb_boot()) {
-#ifdef CONFIG_USB_PORT_AUTO
- usb_port_record_index();
-#endif
/* Turn off all usb resource to let conn SS power down */
sc_pm_set_resource_power_mode(-1, SC_R_USB_0_PHY, SC_PM_PW_MODE_OFF);
sc_pm_set_resource_power_mode(-1, SC_R_USB_1_PHY, SC_PM_PW_MODE_OFF);
return !!(readl(&udc->usbsts) & STS_URI);
}
+static int ci_udc_otg_phy_mode2(ulong phy_addr)
+{
+ void *__iomem phy_ctrl, *__iomem phy_status;
+ void *__iomem phy_base = (void *__iomem)phy_addr;
+ u32 val;
+
+ if (is_mx6() || is_mx7ulp() || is_imx8()) {
+ phy_ctrl = (void __iomem *)(phy_base + USBPHY_CTRL);
+ val = readl(phy_ctrl);
+ if (val & USBPHY_CTRL_OTG_ID)
+ return USB_INIT_DEVICE;
+ else
+ return USB_INIT_HOST;
+ } else if (is_mx7() || is_imx8mm() || is_imx8mn()) {
+ phy_status = (void __iomem *)(phy_base +
+ USBNC_PHY_STATUS_OFFSET);
+ val = readl(phy_status);
+ if (val & USBNC_PHYSTATUS_ID_DIG)
+ return USB_INIT_DEVICE;
+ else
+ return USB_INIT_HOST;
+ } else {
+ return -EINVAL;
+ }
+}
+
+bool udc_irq_reset(void)
+{
+ struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor;
+ unsigned n = readl(&udc->usbsts);
+ writel(n, &udc->usbsts);
+
+ n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI);
+ if (n == 0)
+ return false;
+
+ if (n & STS_URI) {
+ DBG("-- reset --\n");
+ return true;
+ }
+
+ if (n & STS_SLI)
+ DBG("-- suspend --\n");
+
+ return false;
+}
+
+bool ci_udc_check_bus_active(ulong ehci_addr, ulong phy_addr, int index)
+{
+ struct usb_ehci *ehci = (struct usb_ehci *)ehci_addr;
+ struct ehci_ctrl ctrl;
+ int ret;
+ bool active = false;
+
+ ret = ehci_mx6_common_init(ehci, index);
+ if (ret)
+ return false;
+
+ if (ci_udc_otg_phy_mode2(phy_addr) != USB_INIT_DEVICE)
+ return false;
+
+ ctrl.hccr = (struct ehci_hccr *)((ulong)&ehci->caplength);
+ ctrl.hcor = (struct ehci_hcor *)((ulong)ctrl.hccr +
+ HC_LENGTH(ehci_readl(&(ctrl.hccr)->cr_capbase)));
+ controller.ctrl = &ctrl;
+
+ ret = ci_udc_probe();
+ if (ret) {
+ return false;
+ }
+
+ ci_pullup(NULL, 1);
+
+ int count = 100;
+ while (count > 0) {
+ if (udc_irq_reset()) {
+ active = true;
+ break;
+ }
+ mdelay(10);
+ count--;
+ }
+
+ ci_pullup(NULL, 0);
+
+ ci_ep_free_request(&controller.ep[0].ep, &controller.ep0_req->req);
+ free(controller.items_mem);
+ free(controller.epts);
+
+ return active;
+}
+
+
#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
int usb_gadget_handle_interrupts(int index)
{