#include <dm.h>
#include <fdtdec.h>
#include <generic-phy.h>
+#include <log.h>
#include <reset.h>
#include <syscon.h>
#include <usb.h>
#include <asm/io.h>
+#include <dm/device_compat.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
#include <power/regulator.h>
/* USBPHYC registers */
#define MAX_PHYS 2
-#define PLL_LOCK_TIME_US 100
+/* max 100 us for PLL lock and 100 us for PHY init */
+#define PLL_INIT_TIME_US 200
#define PLL_PWR_DOWN_TIME_US 5
#define PLL_FVCO 2880 /* in MHz */
#define PLL_INFF_MIN_RATE 19200000 /* in Hz */
struct udevice *vdda1v8;
struct stm32_usbphyc_phy {
struct udevice *vdd;
+ struct udevice *vbus;
bool init;
bool powered;
} phys[MAX_PHYS];
setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
- /*
- * We must wait PLL_LOCK_TIME_US before checking that PLLEN
- * bit is still set
- */
- udelay(PLL_LOCK_TIME_US);
+ /* We must wait PLL_INIT_TIME_US before using PHY */
+ udelay(PLL_INIT_TIME_US);
if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
return -EIO;
if (ret)
return ret;
}
+ if (usbphyc_phy->vbus) {
+ ret = regulator_set_enable(usbphyc_phy->vbus, true);
+ if (ret)
+ return ret;
+ }
usbphyc_phy->powered = true;
if (stm32_usbphyc_is_powered(usbphyc))
return 0;
+ if (usbphyc_phy->vbus) {
+ ret = regulator_set_enable(usbphyc_phy->vbus, false);
+ if (ret)
+ return ret;
+ }
if (usbphyc_phy->vdd) {
- ret = regulator_set_enable(usbphyc_phy->vdd, false);
+ ret = regulator_set_enable_if_allowed(usbphyc_phy->vdd, false);
if (ret)
return ret;
}
return 0;
}
-static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
+static int stm32_usbphyc_get_regulator(ofnode node,
char *supply_name,
struct udevice **regulator)
{
ret = ofnode_parse_phandle_with_args(node, supply_name,
NULL, 0, 0,
®ulator_phandle);
- if (ret) {
- dev_err(dev, "Can't find %s property (%d)\n", supply_name, ret);
+ if (ret)
return ret;
- }
ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR,
regulator_phandle.node,
regulator);
-
- if (ret) {
- dev_err(dev, "Can't get %s regulator (%d)\n", supply_name, ret);
+ if (ret)
return ret;
- }
return 0;
}
if ((phy->id == 0 && args->args_count != 1) ||
(phy->id == 1 && args->args_count != 2)) {
- dev_err(dev, "invalid number of cells for phy port%ld\n",
+ dev_err(phy->dev, "invalid number of cells for phy port%ld\n",
phy->id);
return -EINVAL;
}
usbphyc_phy->init = false;
usbphyc_phy->powered = false;
- ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply",
+ ret = stm32_usbphyc_get_regulator(node, "phy-supply",
&usbphyc_phy->vdd);
- if (ret)
+ if (ret) {
+ dev_err(dev, "Can't get phy-supply regulator\n");
return ret;
+ }
+
+ ret = stm32_usbphyc_get_regulator(node, "vbus-supply",
+ &usbphyc_phy->vbus);
+ if (ret)
+ usbphyc_phy->vbus = NULL;
node = dev_read_next_subnode(node);
}