Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: cadence: salvo: add .set_mode API

For NXP platform design, the PHY can't know VBUS well, it causes the FSM
in controller seeing the disconnection at L1 use case. With .set_mode API
introduced, the controller driver could force PHY seeing B Session VALID
when it is at the device mode (VBUS is there), and keep FSM working well.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20230517161646.3418250-5-Frank.Li@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Peter Chen and committed by
Vinod Koul
3ad5cebe fe551665

+29
+29
drivers/phy/cadence/phy-cadence-salvo.c
··· 92 92 /* USB2 PHY register definition */ 93 93 #define UTMI_REG15 0xaf 94 94 #define UTMI_AFE_RX_REG5 0x12 95 + #define UTMI_AFE_BC_REG4 0x29 95 96 96 97 /* TB_ADDR_TX_RCVDETSC_CTRL */ 97 98 #define RXDET_IN_P3_32KHZ BIT(0) ··· 105 104 #define TXVALID_GATE_THRESHOLD_HS_MASK (BIT(4) | BIT(5)) 106 105 /* 0us, txvalid is ready just after HS/FS transmitters have powered up */ 107 106 #define TXVALID_GATE_THRESHOLD_HS_0US (BIT(4) | BIT(5)) 107 + 108 + #define SET_B_SESSION_VALID (BIT(6) | BIT(5)) 109 + #define CLR_B_SESSION_VALID (BIT(6)) 108 110 109 111 struct cdns_reg_pairs { 110 112 u16 val; ··· 128 124 }; 129 125 130 126 static const struct of_device_id cdns_salvo_phy_of_match[]; 127 + static const struct cdns_salvo_data cdns_nxp_salvo_data; 128 + 129 + static bool cdns_is_nxp_phy(struct cdns_salvo_phy *salvo_phy) 130 + { 131 + return salvo_phy->data == &cdns_nxp_salvo_data; 132 + } 133 + 131 134 static u16 cdns_salvo_read(struct cdns_salvo_phy *salvo_phy, u32 offset, u32 reg) 132 135 { 133 136 return (u16)readl(salvo_phy->base + offset + ··· 283 272 return 0; 284 273 } 285 274 275 + static int cdns_salvo_set_mode(struct phy *phy, enum phy_mode mode, int submode) 276 + { 277 + struct cdns_salvo_phy *salvo_phy = phy_get_drvdata(phy); 278 + 279 + if (!cdns_is_nxp_phy(salvo_phy)) 280 + return 0; 281 + 282 + if (mode == PHY_MODE_USB_DEVICE) 283 + cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_BC_REG4, 284 + SET_B_SESSION_VALID); 285 + else 286 + cdns_salvo_write(salvo_phy, USB2_PHY_OFFSET, UTMI_AFE_BC_REG4, 287 + CLR_B_SESSION_VALID); 288 + 289 + return 0; 290 + } 291 + 286 292 static const struct phy_ops cdns_salvo_phy_ops = { 287 293 .init = cdns_salvo_phy_init, 288 294 .power_on = cdns_salvo_phy_power_on, 289 295 .power_off = cdns_salvo_phy_power_off, 290 296 .owner = THIS_MODULE, 297 + .set_mode = cdns_salvo_set_mode, 291 298 }; 292 299 293 300 static int cdns_salvo_phy_probe(struct platform_device *pdev)