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: mvebu-cp110-utmi: support swapping d+/d- lanes by dts property

CP11x UTMI PHY supports swapping D+/D- signals via digital control
register 1.

Add support for the "swap-dx-lanes" device-tree property, which lists
the port-ids that should swap D+ and D-.
The property is evaluated in probe and applied before power-on
during mvebu_cp110_utmi_port_setup.

Signed-off-by: Josua Mayer <josua@solid-run.com>
Link: https://lore.kernel.org/r/20241002-mvebu-utmi-phy-v4-1-83783dc89b9d@solid-run.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Josua Mayer and committed by
Vinod Koul
d6c496f0 40452520

+16
+16
drivers/phy/marvell/phy-mvebu-cp110-utmi.c
··· 62 62 #define SQ_AMP_CAL_MASK GENMASK(2, 0) 63 63 #define SQ_AMP_CAL_VAL 1 64 64 #define SQ_AMP_CAL_EN BIT(3) 65 + #define UTMI_DIG_CTRL1_REG 0x20 66 + #define SWAP_DPDM BIT(15) 65 67 #define UTMI_CTRL_STATUS0_REG 0x24 66 68 #define SUSPENDM BIT(22) 67 69 #define TEST_SEL BIT(25) ··· 101 99 * @priv: PHY driver data 102 100 * @id: PHY port ID 103 101 * @dr_mode: PHY connection: USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL 102 + * @swap_dx: whether to swap d+/d- signals 104 103 */ 105 104 struct mvebu_cp110_utmi_port { 106 105 struct mvebu_cp110_utmi *priv; 107 106 u32 id; 108 107 enum usb_dr_mode dr_mode; 108 + bool swap_dx; 109 109 }; 110 110 111 111 static void mvebu_cp110_utmi_port_setup(struct mvebu_cp110_utmi_port *port) ··· 163 159 reg &= ~(VDAT_MASK | VSRC_MASK); 164 160 reg |= (VDAT_VAL << VDAT_OFFSET) | (VSRC_VAL << VSRC_OFFSET); 165 161 writel(reg, PORT_REGS(port) + UTMI_CHGDTC_CTRL_REG); 162 + 163 + /* Swap D+/D- */ 164 + reg = readl(PORT_REGS(port) + UTMI_DIG_CTRL1_REG); 165 + reg &= ~(SWAP_DPDM); 166 + if (port->swap_dx) 167 + reg |= SWAP_DPDM; 168 + writel(reg, PORT_REGS(port) + UTMI_DIG_CTRL1_REG); 166 169 } 167 170 168 171 static int mvebu_cp110_utmi_phy_power_off(struct phy *phy) ··· 297 286 struct phy_provider *provider; 298 287 struct device_node *child; 299 288 u32 usb_devices = 0; 289 + u32 swap_dx = 0; 300 290 301 291 utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL); 302 292 if (!utmi) ··· 356 344 port->dr_mode = USB_DR_MODE_HOST; 357 345 } 358 346 } 347 + 348 + of_property_for_each_u32(dev->of_node, "swap-dx-lanes", swap_dx) 349 + if (swap_dx == port_id) 350 + port->swap_dx = 1; 359 351 360 352 /* Retrieve PHY capabilities */ 361 353 utmi->ops = &mvebu_cp110_utmi_phy_ops;