#include <cpu_func.h>
#include <dm.h>
#include <errno.h>
+#include <log.h>
#include <asm/byteorder.h>
+#include <asm/cache.h>
#include <asm/unaligned.h>
#include <usb.h>
#include <asm/io.h>
#include <watchdog.h>
#include <dm/device_compat.h>
#include <linux/compiler.h>
+#include <linux/delay.h>
#include "ehci.h"
-#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
-#endif
-
/*
* EHCI spec page 20 says that the HC may take up to 16 uFrames (= 4ms) to halt.
* Let's time out after 8 to have a little safety margin on top of that.
},
};
-#if defined(CONFIG_EHCI_IS_TDI)
+#if defined(CONFIG_USB_EHCI_IS_TDI)
#define ehci_is_TDI() (1)
#else
#define ehci_is_TDI() (0)
return ret;
}
+static int ehci_iaa_cycle(struct ehci_ctrl *ctrl)
+{
+ u32 cmd, status;
+ int ret;
+
+ /* Enable Interrupt on Async Advance Doorbell. */
+ cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
+ cmd |= CMD_IAAD;
+ ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+
+ ret = handshake(&ctrl->hcor->or_usbsts, STS_IAA, STS_IAA,
+ 10 * 1000); /* 10ms timeout */
+ if (ret < 0)
+ printf("EHCI fail timeout STS_IAA set\n");
+
+ status = ehci_readl(&ctrl->hcor->or_usbsts);
+ if (status & STS_IAA)
+ ehci_writel(&ctrl->hcor->or_usbsts, STS_IAA);
+
+ return ret;
+}
+
static int
ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
int length, struct devrequest *req)
flush_dcache_range((unsigned long)&ctrl->qh_list,
ALIGN_END_ADDR(struct QH, &ctrl->qh_list, 1));
+ /* Set IAAD, poll IAA */
+ ret = ehci_iaa_cycle(ctrl);
+ if (ret)
+ goto fail;
+
/*
* Invalidate the memory area occupied by buffer
* Don't try to fix the buffer alignment, if it isn't properly
debug("Exit create_int_queue\n");
return result;
fail3:
- if (result->tds)
- free(result->tds);
+ free(result->tds);
fail2:
- if (result->first)
- free(result->first);
- if (result)
- free(result);
+ free(result->first);
+ free(result);
fail1:
return NULL;
}
} else {
ret = generic_phy_init(phy);
if (ret) {
- dev_err(dev, "failed to init usb phy\n");
+ dev_dbg(dev, "failed to init usb phy\n");
return ret;
}
ret = generic_phy_power_on(phy);
if (ret) {
- dev_err(dev, "failed to power on usb phy\n");
+ dev_dbg(dev, "failed to power on usb phy\n");
return generic_phy_exit(phy);
}
}
if (generic_phy_valid(phy)) {
ret = generic_phy_power_off(phy);
if (ret) {
- dev_err(dev, "failed to power off usb phy\n");
+ dev_dbg(dev, "failed to power off usb phy\n");
return ret;
}
ret = generic_phy_exit(phy);
if (ret) {
- dev_err(dev, "failed to power off usb phy\n");
+ dev_dbg(dev, "failed to power off usb phy\n");
return ret;
}
}