[U-Boot,v4,13/15] phy: keystone-usb: handle the transition of the USB power domain
diff mbox series

Message ID 20190911093358.25290-14-jjhiblot@ti.com
State New
Delegated to: Marek Vasut
Headers show
Series
  • Improvement for the DWC3 USB generic driver and fixes for the K2 platforms
Related show

Commit Message

Jean-Jacques Hiblot Sept. 11, 2019, 9:33 a.m. UTC
There is no proper power domain support for the keystone platforms.
However we need to turn off the USB domains before jumping to linux or it
fail to boot (observed with k2e and k2l platforms).
This can be done in the PHY driver as it is dedicated only to the keystone
platforms and matches the required on/off sequence.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
---

Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/phy/keystone-usb-phy.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Patch
diff mbox series

diff --git a/drivers/phy/keystone-usb-phy.c b/drivers/phy/keystone-usb-phy.c
index e8146cabfa..14ac6bbbb2 100644
--- a/drivers/phy/keystone-usb-phy.c
+++ b/drivers/phy/keystone-usb-phy.c
@@ -9,6 +9,7 @@ 
 #include <dm/device.h>
 #include <generic-phy.h>
 #include <asm/io.h>
+#include <asm/arch/psc_defs.h>
 
 /* USB PHY control register offsets */
 #define USB_PHY_CTL_UTMI		0x0000
@@ -22,15 +23,25 @@ 
 #define PHY_REF_SSP_EN			BIT(29)
 
 struct keystone_usb_phy {
+	u32 psc_domain;
 	void __iomem *reg;
 };
 
 static int keystone_usb_init(struct phy *phy)
 {
 	u32 val;
+	int rc;
 	struct udevice *dev = phy->dev;
 	struct keystone_usb_phy *keystone = dev_get_priv(dev);
 
+	/* Release USB from reset */
+	rc = psc_enable_module(keystone->psc_domain);
+	if (rc) {
+		debug("Cannot enable USB module");
+		return -rc;
+	}
+	mdelay(10);
+
 	/*
 	 * VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't.
 	 * It should always be cleared because our USB PHY has an onchip VBUS
@@ -72,13 +83,24 @@  static int keystone_usb_power_off(struct phy *phy)
 
 static int keystone_usb_exit(struct phy *phy)
 {
+	struct udevice *dev = phy->dev;
+	struct keystone_usb_phy *keystone = dev_get_priv(dev);
+
+	if (psc_disable_module(keystone->psc_domain))
+		debug("failed to disable USB module!\n");
+
 	return 0;
 }
 
 static int keystone_usb_phy_probe(struct udevice *dev)
 {
+	int rc;
 	struct keystone_usb_phy *keystone = dev_get_priv(dev);
 
+	rc = dev_read_u32(dev, "psc-domain", &keystone->psc_domain);
+	if (rc)
+		return rc;
+
 	keystone->reg = dev_remap_addr_index(dev, 0);
 	if (!keystone->reg) {
 		pr_err("unable to remap usb phy\n");