@@ -311,6 +311,7 @@ struct tegra_xusb {
311
311
312
312
bool suspended ;
313
313
struct tegra_xusb_context context ;
314
+ u8 lp0_utmi_pad_mask ;
314
315
};
315
316
316
317
static struct hc_driver __read_mostly tegra_xhci_hc_driver ;
@@ -2092,10 +2093,24 @@ static void tegra_xhci_disable_phy_wake(struct tegra_xusb *tegra)
2092
2093
struct tegra_xusb_padctl * padctl = tegra -> padctl ;
2093
2094
unsigned int i ;
2094
2095
2096
+ for (i = 0 ; i < tegra -> num_usb_phys ; i ++ ) {
2097
+ struct phy * phy = tegra_xusb_get_phy (tegra , "usb2" , i );
2098
+
2099
+ if (!phy )
2100
+ continue ;
2101
+
2102
+ if (tegra_xusb_padctl_remote_wake_detected (padctl , phy ))
2103
+ tegra_phy_xusb_utmi_pad_power_on (phy );
2104
+ }
2105
+
2095
2106
for (i = 0 ; i < tegra -> num_phys ; i ++ ) {
2096
2107
if (!tegra -> phys [i ])
2097
2108
continue ;
2098
2109
2110
+ if (tegra_xusb_padctl_remote_wake_detected (padctl , tegra -> phys [i ]))
2111
+ dev_dbg (tegra -> dev , "%pOF remote wake detected\n" ,
2112
+ tegra -> phys [i ]-> dev .of_node );
2113
+
2099
2114
tegra_xusb_padctl_disable_phy_wake (padctl , tegra -> phys [i ]);
2100
2115
}
2101
2116
}
@@ -2113,6 +2128,28 @@ static void tegra_xhci_disable_phy_sleepwalk(struct tegra_xusb *tegra)
2113
2128
}
2114
2129
}
2115
2130
2131
+ static void tegra_xhci_program_utmi_power_lp0_exit (struct tegra_xusb * tegra )
2132
+ {
2133
+ unsigned int i , index_to_usb2 ;
2134
+ struct phy * phy ;
2135
+
2136
+ for (i = 0 ; i < tegra -> soc -> num_types ; i ++ ) {
2137
+ if (strcmp (tegra -> soc -> phy_types [i ].name , "usb2" ) == 0 )
2138
+ index_to_usb2 = i ;
2139
+ }
2140
+
2141
+ for (i = 0 ; i < tegra -> num_usb_phys ; i ++ ) {
2142
+ if (!is_host_mode_phy (tegra , index_to_usb2 , i ))
2143
+ continue ;
2144
+
2145
+ phy = tegra_xusb_get_phy (tegra , "usb2" , i );
2146
+ if (tegra -> lp0_utmi_pad_mask & BIT (i ))
2147
+ tegra_phy_xusb_utmi_pad_power_on (phy );
2148
+ else
2149
+ tegra_phy_xusb_utmi_pad_power_down (phy );
2150
+ }
2151
+ }
2152
+
2116
2153
static int tegra_xusb_enter_elpg (struct tegra_xusb * tegra , bool runtime )
2117
2154
{
2118
2155
struct xhci_hcd * xhci = hcd_to_xhci (tegra -> hcd );
@@ -2121,6 +2158,7 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool runtime)
2121
2158
unsigned int i ;
2122
2159
int err ;
2123
2160
u32 usbcmd ;
2161
+ u32 portsc ;
2124
2162
2125
2163
dev_dbg (dev , "entering ELPG\n" );
2126
2164
@@ -2134,6 +2172,15 @@ static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool runtime)
2134
2172
goto out ;
2135
2173
}
2136
2174
2175
+ for (i = 0 ; i < tegra -> num_usb_phys ; i ++ ) {
2176
+ if (!xhci -> usb2_rhub .ports [i ])
2177
+ continue ;
2178
+ portsc = readl (xhci -> usb2_rhub .ports [i ]-> addr );
2179
+ tegra -> lp0_utmi_pad_mask &= ~BIT (i );
2180
+ if (((portsc & PORT_PLS_MASK ) == XDEV_U3 ) || ((portsc & DEV_SPEED_MASK ) == XDEV_FS ))
2181
+ tegra -> lp0_utmi_pad_mask |= BIT (i );
2182
+ }
2183
+
2137
2184
err = xhci_suspend (xhci , wakeup );
2138
2185
if (err < 0 ) {
2139
2186
dev_err (tegra -> dev , "failed to suspend XHCI: %d\n" , err );
@@ -2207,6 +2254,8 @@ static int tegra_xusb_exit_elpg(struct tegra_xusb *tegra, bool runtime)
2207
2254
2208
2255
phy_power_on (tegra -> phys [i ]);
2209
2256
}
2257
+ if (tegra -> suspended )
2258
+ tegra_xhci_program_utmi_power_lp0_exit (tegra );
2210
2259
2211
2260
tegra_xusb_config (tegra );
2212
2261
tegra_xusb_restore_context (tegra );
@@ -2626,8 +2675,84 @@ static int tegra_xhci_setup(struct usb_hcd *hcd)
2626
2675
return xhci_gen_setup (hcd , tegra_xhci_quirks );
2627
2676
}
2628
2677
2678
+ static int tegra_xhci_hub_control (struct usb_hcd * hcd , u16 type_req , u16 value , u16 index ,
2679
+ char * buf , u16 length )
2680
+ {
2681
+ struct tegra_xusb * tegra = dev_get_drvdata (hcd -> self .controller );
2682
+ struct xhci_hcd * xhci = hcd_to_xhci (hcd );
2683
+ struct xhci_hub * rhub ;
2684
+ struct xhci_bus_state * bus_state ;
2685
+ int port = (index & 0xff ) - 1 ;
2686
+ unsigned int i ;
2687
+ struct xhci_port * * ports ;
2688
+ u32 portsc ;
2689
+ int ret ;
2690
+ struct phy * phy ;
2691
+
2692
+ rhub = & xhci -> usb2_rhub ;
2693
+ bus_state = & rhub -> bus_state ;
2694
+ if (bus_state -> resuming_ports && hcd -> speed == HCD_USB2 ) {
2695
+ ports = rhub -> ports ;
2696
+ i = rhub -> num_ports ;
2697
+ while (i -- ) {
2698
+ if (!test_bit (i , & bus_state -> resuming_ports ))
2699
+ continue ;
2700
+ portsc = readl (ports [i ]-> addr );
2701
+ if ((portsc & PORT_PLS_MASK ) == XDEV_RESUME )
2702
+ tegra_phy_xusb_utmi_pad_power_on (
2703
+ tegra_xusb_get_phy (tegra , "usb2" , (int ) i ));
2704
+ }
2705
+ }
2706
+
2707
+ if (hcd -> speed == HCD_USB2 ) {
2708
+ phy = tegra_xusb_get_phy (tegra , "usb2" , port );
2709
+ if ((type_req == ClearPortFeature ) && (value == USB_PORT_FEAT_SUSPEND )) {
2710
+ if (!index || index > rhub -> num_ports )
2711
+ return - EPIPE ;
2712
+ tegra_phy_xusb_utmi_pad_power_on (phy );
2713
+ }
2714
+ if ((type_req == SetPortFeature ) && (value == USB_PORT_FEAT_RESET )) {
2715
+ if (!index || index > rhub -> num_ports )
2716
+ return - EPIPE ;
2717
+ ports = rhub -> ports ;
2718
+ portsc = readl (ports [port ]-> addr );
2719
+ if (portsc & PORT_CONNECT )
2720
+ tegra_phy_xusb_utmi_pad_power_on (phy );
2721
+ }
2722
+ }
2723
+
2724
+ ret = xhci_hub_control (hcd , type_req , value , index , buf , length );
2725
+ if (ret < 0 )
2726
+ return ret ;
2727
+
2728
+ if (hcd -> speed == HCD_USB2 ) {
2729
+ /* Use phy where we set previously */
2730
+ if ((type_req == SetPortFeature ) && (value == USB_PORT_FEAT_SUSPEND ))
2731
+ /* We don't suspend the PAD while HNP role swap happens on the OTG port */
2732
+ if (!((hcd -> self .otg_port == (port + 1 )) && hcd -> self .b_hnp_enable ))
2733
+ tegra_phy_xusb_utmi_pad_power_down (phy );
2734
+
2735
+ if ((type_req == ClearPortFeature ) && (value == USB_PORT_FEAT_C_CONNECTION )) {
2736
+ ports = rhub -> ports ;
2737
+ portsc = readl (ports [port ]-> addr );
2738
+ if (!(portsc & PORT_CONNECT )) {
2739
+ /* We don't suspend the PAD while HNP role swap happens on the OTG
2740
+ * port
2741
+ */
2742
+ if (!((hcd -> self .otg_port == (port + 1 )) && hcd -> self .b_hnp_enable ))
2743
+ tegra_phy_xusb_utmi_pad_power_down (phy );
2744
+ }
2745
+ }
2746
+ if ((type_req == SetPortFeature ) && (value == USB_PORT_FEAT_TEST ))
2747
+ tegra_phy_xusb_utmi_pad_power_on (phy );
2748
+ }
2749
+
2750
+ return ret ;
2751
+ }
2752
+
2629
2753
static const struct xhci_driver_overrides tegra_xhci_overrides __initconst = {
2630
2754
.reset = tegra_xhci_setup ,
2755
+ .hub_control = tegra_xhci_hub_control ,
2631
2756
};
2632
2757
2633
2758
static int __init tegra_xusb_init (void )
0 commit comments