@@ -648,14 +648,15 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl)
648648 udelay (100 );
649649 }
650650
651- if (padctl -> soc -> trk_hw_mode ) {
652- value = padctl_readl (padctl , XUSB_PADCTL_USB2_BIAS_PAD_CTL2 );
653- value |= USB2_TRK_HW_MODE ;
651+ value = padctl_readl (padctl , XUSB_PADCTL_USB2_BIAS_PAD_CTL2 );
652+ if (padctl -> soc -> trk_update_on_idle )
654653 value &= ~CYA_TRK_CODE_UPDATE_ON_IDLE ;
655- padctl_writel (padctl , value , XUSB_PADCTL_USB2_BIAS_PAD_CTL2 );
656- } else {
654+ if (padctl -> soc -> trk_hw_mode )
655+ value |= USB2_TRK_HW_MODE ;
656+ padctl_writel (padctl , value , XUSB_PADCTL_USB2_BIAS_PAD_CTL2 );
657+
658+ if (!padctl -> soc -> trk_hw_mode )
657659 clk_disable_unprepare (priv -> usb2_trk_clk );
658- }
659660}
660661
661662static void tegra186_utmi_bias_pad_power_off (struct tegra_xusb_padctl * padctl )
@@ -782,13 +783,15 @@ static int tegra186_xusb_padctl_vbus_override(struct tegra_xusb_padctl *padctl,
782783}
783784
784785static int tegra186_xusb_padctl_id_override (struct tegra_xusb_padctl * padctl ,
785- bool status )
786+ struct tegra_xusb_usb2_port * port , bool status )
786787{
787- u32 value ;
788+ u32 value , id_override ;
789+ int err = 0 ;
788790
789791 dev_dbg (padctl -> dev , "%s id override\n" , status ? "set" : "clear" );
790792
791793 value = padctl_readl (padctl , USB2_VBUS_ID );
794+ id_override = value & ID_OVERRIDE (~0 );
792795
793796 if (status ) {
794797 if (value & VBUS_OVERRIDE ) {
@@ -799,15 +802,35 @@ static int tegra186_xusb_padctl_id_override(struct tegra_xusb_padctl *padctl,
799802 value = padctl_readl (padctl , USB2_VBUS_ID );
800803 }
801804
802- value &= ~ID_OVERRIDE (~0 );
803- value |= ID_OVERRIDE_GROUNDED ;
805+ if (id_override != ID_OVERRIDE_GROUNDED ) {
806+ value &= ~ID_OVERRIDE (~0 );
807+ value |= ID_OVERRIDE_GROUNDED ;
808+ padctl_writel (padctl , value , USB2_VBUS_ID );
809+
810+ err = regulator_enable (port -> supply );
811+ if (err ) {
812+ dev_err (padctl -> dev , "Failed to enable regulator: %d\n" , err );
813+ return err ;
814+ }
815+ }
804816 } else {
805- value &= ~ID_OVERRIDE (~0 );
806- value |= ID_OVERRIDE_FLOATING ;
817+ if (id_override == ID_OVERRIDE_GROUNDED ) {
818+ /*
819+ * The regulator is disabled only when the role transitions
820+ * from USB_ROLE_HOST to USB_ROLE_NONE.
821+ */
822+ err = regulator_disable (port -> supply );
823+ if (err ) {
824+ dev_err (padctl -> dev , "Failed to disable regulator: %d\n" , err );
825+ return err ;
826+ }
827+
828+ value &= ~ID_OVERRIDE (~0 );
829+ value |= ID_OVERRIDE_FLOATING ;
830+ padctl_writel (padctl , value , USB2_VBUS_ID );
831+ }
807832 }
808833
809- padctl_writel (padctl , value , USB2_VBUS_ID );
810-
811834 return 0 ;
812835}
813836
@@ -826,27 +849,20 @@ static int tegra186_utmi_phy_set_mode(struct phy *phy, enum phy_mode mode,
826849
827850 if (mode == PHY_MODE_USB_OTG ) {
828851 if (submode == USB_ROLE_HOST ) {
829- tegra186_xusb_padctl_id_override (padctl , true);
830-
831- err = regulator_enable ( port -> supply ) ;
852+ err = tegra186_xusb_padctl_id_override (padctl , port , true);
853+ if ( err )
854+ goto out ;
832855 } else if (submode == USB_ROLE_DEVICE ) {
833856 tegra186_xusb_padctl_vbus_override (padctl , true);
834857 } else if (submode == USB_ROLE_NONE ) {
835- /*
836- * When port is peripheral only or role transitions to
837- * USB_ROLE_NONE from USB_ROLE_DEVICE, regulator is not
838- * enabled.
839- */
840- if (regulator_is_enabled (port -> supply ))
841- regulator_disable (port -> supply );
842-
843- tegra186_xusb_padctl_id_override (padctl , false);
858+ err = tegra186_xusb_padctl_id_override (padctl , port , false);
859+ if (err )
860+ goto out ;
844861 tegra186_xusb_padctl_vbus_override (padctl , false);
845862 }
846863 }
847-
864+ out :
848865 mutex_unlock (& padctl -> lock );
849-
850866 return err ;
851867}
852868
@@ -1710,7 +1726,8 @@ const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = {
17101726 .num_supplies = ARRAY_SIZE (tegra194_xusb_padctl_supply_names ),
17111727 .supports_gen2 = true,
17121728 .poll_trk_completed = true,
1713- .trk_hw_mode = true,
1729+ .trk_hw_mode = false,
1730+ .trk_update_on_idle = true,
17141731 .supports_lp_cfg_en = true,
17151732};
17161733EXPORT_SYMBOL_GPL (tegra234_xusb_padctl_soc );
0 commit comments