#include <asm/dma-mapping.h>
#include <linux/ioport.h>
#include <dm.h>
-
+#include <generic-phy.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
+#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
+int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys)
+{
+ int i, ret, count;
+ struct phy *usb_phys;
+
+ /* Return if no phy declared */
+ if (!dev_read_prop(dev, "phys", NULL))
+ return 0;
+ count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
+ if (count <= 0)
+ return count;
+
+ usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
+ GFP_KERNEL);
+ if (!usb_phys)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ ret = generic_phy_get_by_index(dev, i, &usb_phys[i]);
+ if (ret && ret != -ENOENT) {
+ pr_err("Failed to get USB PHY%d for %s\n",
+ i, dev->name);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ ret = generic_phy_init(&usb_phys[i]);
+ if (ret) {
+ pr_err("Can't init USB PHY%d for %s\n",
+ i, dev->name);
+ goto phys_init_err;
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ ret = generic_phy_power_on(&usb_phys[i]);
+ if (ret) {
+ pr_err("Can't power USB PHY%d for %s\n",
+ i, dev->name);
+ goto phys_poweron_err;
+ }
+ }
+
+ *array = usb_phys;
+ *num_phys = count;
+ return 0;
+
+phys_poweron_err:
+ for (i = count - 1; i >= 0; i--)
+ generic_phy_power_off(&usb_phys[i]);
+
+ for (i = 0; i < count; i++)
+ generic_phy_exit(&usb_phys[i]);
+
+ return ret;
+
+phys_init_err:
+ for (; i >= 0; i--)
+ generic_phy_exit(&usb_phys[i]);
+
+ return ret;
+}
+
+int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys)
+{
+ int i, ret;
+
+ for (i = 0; i < num_phys; i++) {
+ if (!generic_phy_valid(&usb_phys[i]))
+ continue;
+
+ ret = generic_phy_power_off(&usb_phys[i]);
+ ret |= generic_phy_exit(&usb_phys[i]);
+ if (ret) {
+ pr_err("Can't shutdown USB PHY%d for %s\n",
+ i, dev->name);
+ }
+ }
+
+ return 0;
+}
+#endif
+
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
int dwc3_init(struct dwc3 *dwc)
{
dwc3_core_exit(dwc);
kfree(dwc->mem);
}
-
#endif
#include <fdtdec.h>
#include <generic-phy.h>
#include <usb.h>
+#include <dwc3-uboot.h>
#include "xhci.h"
#include <asm/io.h>
}
#if CONFIG_IS_ENABLED(DM_USB)
-static int xhci_dwc3_setup_phy(struct udevice *dev)
-{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- int i, ret, count;
-
- /* Return if no phy declared */
- if (!dev_read_prop(dev, "phys", NULL))
- return 0;
-
- count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
- if (count <= 0)
- return count;
-
- plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
- GFP_KERNEL);
- if (!plat->usb_phys)
- return -ENOMEM;
-
- for (i = 0; i < count; i++) {
- ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
- if (ret && ret != -ENOENT) {
- pr_err("Failed to get USB PHY%d for %s\n",
- i, dev->name);
- return ret;
- }
-
- ++plat->num_phys;
- }
-
- for (i = 0; i < plat->num_phys; i++) {
- ret = generic_phy_init(&plat->usb_phys[i]);
- if (ret) {
- pr_err("Can't init USB PHY%d for %s\n",
- i, dev->name);
- goto phys_init_err;
- }
- }
-
- for (i = 0; i < plat->num_phys; i++) {
- ret = generic_phy_power_on(&plat->usb_phys[i]);
- if (ret) {
- pr_err("Can't power USB PHY%d for %s\n",
- i, dev->name);
- goto phys_poweron_err;
- }
- }
-
- return 0;
-
-phys_poweron_err:
- for (; i >= 0; i--)
- generic_phy_power_off(&plat->usb_phys[i]);
-
- for (i = 0; i < plat->num_phys; i++)
- generic_phy_exit(&plat->usb_phys[i]);
-
- return ret;
-
-phys_init_err:
- for (; i >= 0; i--)
- generic_phy_exit(&plat->usb_phys[i]);
-
- return ret;
-}
-
-static int xhci_dwc3_shutdown_phy(struct udevice *dev)
-{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- int i, ret;
-
- for (i = 0; i < plat->num_phys; i++) {
- if (!generic_phy_valid(&plat->usb_phys[i]))
- continue;
-
- ret = generic_phy_power_off(&plat->usb_phys[i]);
- ret |= generic_phy_exit(&plat->usb_phys[i]);
- if (ret) {
- pr_err("Can't shutdown USB PHY%d for %s\n",
- i, dev->name);
- }
- }
-
- return 0;
-}
-
static int xhci_dwc3_probe(struct udevice *dev)
{
struct xhci_hcor *hcor;
struct xhci_hccr *hccr;
struct dwc3 *dwc3_reg;
enum usb_dr_mode dr_mode;
+ struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
int ret;
hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- ret = xhci_dwc3_setup_phy(dev);
- if (ret)
+ ret = dwc3_setup_phy(dev, &plat->usb_phys, &plat->num_phys);
+ if (ret && (ret != -ENOTSUPP))
return ret;
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
static int xhci_dwc3_remove(struct udevice *dev)
{
- xhci_dwc3_shutdown_phy(dev);
+ struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+
+ dwc3_shutdown_phy(dev, plat->usb_phys, plat->num_phys);
return xhci_deregister(dev);
}
int dwc3_uboot_init(struct dwc3_device *dev);
void dwc3_uboot_exit(int index);
void dwc3_uboot_handle_interrupt(int index);
+
+struct phy;
+#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
+int dwc3_setup_phy(struct udevice *dev, struct phy **array, int *num_phys);
+int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys);
+#else
+static inline int dwc3_setup_phy(struct udevice *dev, struct phy **array,
+ int *num_phys)
+{
+ return -ENOTSUPP;
+}
+
+static inline int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys,
+ int num_phys)
+{
+ return -ENOTSUPP;
+}
+#endif
+
#endif /* __DWC3_UBOOT_H_ */