|
50 | 50 | #define PHY_R5_PHY_CR_ACK BIT(16)
|
51 | 51 | #define PHY_R5_PHY_BS_OUT BIT(17)
|
52 | 52 |
|
| 53 | +#define PCIE_RESET_DELAY 500 |
| 54 | + |
53 | 55 | struct phy_g12a_usb3_pcie_priv {
|
54 | 56 | struct regmap *regmap;
|
55 | 57 | struct regmap *regmap_cr;
|
@@ -196,6 +198,10 @@ static int phy_g12a_usb3_init(struct phy *phy)
|
196 | 198 | struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
|
197 | 199 | int data, ret;
|
198 | 200 |
|
| 201 | + ret = reset_control_reset(priv->reset); |
| 202 | + if (ret) |
| 203 | + return ret; |
| 204 | + |
199 | 205 | /* Switch PHY to USB3 */
|
200 | 206 | /* TODO figure out how to handle when PCIe was set in the bootloader */
|
201 | 207 | regmap_update_bits(priv->regmap, PHY_R0,
|
@@ -272,32 +278,75 @@ static int phy_g12a_usb3_init(struct phy *phy)
|
272 | 278 | return 0;
|
273 | 279 | }
|
274 | 280 |
|
275 |
| -static int phy_g12a_usb3_pcie_init(struct phy *phy) |
| 281 | +static int phy_g12a_usb3_pcie_power_on(struct phy *phy) |
| 282 | +{ |
| 283 | + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); |
| 284 | + |
| 285 | + if (priv->mode == PHY_TYPE_USB3) |
| 286 | + return 0; |
| 287 | + |
| 288 | + regmap_update_bits(priv->regmap, PHY_R0, |
| 289 | + PHY_R0_PCIE_POWER_STATE, |
| 290 | + FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c)); |
| 291 | + |
| 292 | + return 0; |
| 293 | +} |
| 294 | + |
| 295 | +static int phy_g12a_usb3_pcie_power_off(struct phy *phy) |
| 296 | +{ |
| 297 | + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); |
| 298 | + |
| 299 | + if (priv->mode == PHY_TYPE_USB3) |
| 300 | + return 0; |
| 301 | + |
| 302 | + regmap_update_bits(priv->regmap, PHY_R0, |
| 303 | + PHY_R0_PCIE_POWER_STATE, |
| 304 | + FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1d)); |
| 305 | + |
| 306 | + return 0; |
| 307 | +} |
| 308 | + |
| 309 | +static int phy_g12a_usb3_pcie_reset(struct phy *phy) |
276 | 310 | {
|
277 | 311 | struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
|
278 | 312 | int ret;
|
279 | 313 |
|
280 |
| - ret = reset_control_reset(priv->reset); |
| 314 | + if (priv->mode == PHY_TYPE_USB3) |
| 315 | + return 0; |
| 316 | + |
| 317 | + ret = reset_control_assert(priv->reset); |
281 | 318 | if (ret)
|
282 | 319 | return ret;
|
283 | 320 |
|
| 321 | + udelay(PCIE_RESET_DELAY); |
| 322 | + |
| 323 | + ret = reset_control_deassert(priv->reset); |
| 324 | + if (ret) |
| 325 | + return ret; |
| 326 | + |
| 327 | + udelay(PCIE_RESET_DELAY); |
| 328 | + |
| 329 | + return 0; |
| 330 | +} |
| 331 | + |
| 332 | +static int phy_g12a_usb3_pcie_init(struct phy *phy) |
| 333 | +{ |
| 334 | + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); |
| 335 | + |
284 | 336 | if (priv->mode == PHY_TYPE_USB3)
|
285 | 337 | return phy_g12a_usb3_init(phy);
|
286 | 338 |
|
287 |
| - /* Power UP PCIE */ |
288 |
| - /* TODO figure out when the bootloader has set USB3 mode before */ |
289 |
| - regmap_update_bits(priv->regmap, PHY_R0, |
290 |
| - PHY_R0_PCIE_POWER_STATE, |
291 |
| - FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c)); |
292 |
| - |
293 | 339 | return 0;
|
294 | 340 | }
|
295 | 341 |
|
296 | 342 | static int phy_g12a_usb3_pcie_exit(struct phy *phy)
|
297 | 343 | {
|
298 | 344 | struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy);
|
299 | 345 |
|
300 |
| - return reset_control_reset(priv->reset); |
| 346 | + if (priv->mode == PHY_TYPE_USB3) |
| 347 | + return reset_control_reset(priv->reset); |
| 348 | + |
| 349 | + return 0; |
301 | 350 | }
|
302 | 351 |
|
303 | 352 | static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev,
|
@@ -326,6 +375,9 @@ static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev,
|
326 | 375 | static const struct phy_ops phy_g12a_usb3_pcie_ops = {
|
327 | 376 | .init = phy_g12a_usb3_pcie_init,
|
328 | 377 | .exit = phy_g12a_usb3_pcie_exit,
|
| 378 | + .power_on = phy_g12a_usb3_pcie_power_on, |
| 379 | + .power_off = phy_g12a_usb3_pcie_power_off, |
| 380 | + .reset = phy_g12a_usb3_pcie_reset, |
329 | 381 | .owner = THIS_MODULE,
|
330 | 382 | };
|
331 | 383 |
|
|
0 commit comments