Lines Matching +full:syscon +full:- +full:phy +full:- +full:power
1 // SPDX-License-Identifier: GPL-2.0
8 * Marvell CP110 UTMI PHY driver
13 #include <linux/mfd/syscon.h>
16 #include <linux/phy/phy.h>
81 #define PORT_REGS(p) ((p)->priv->regs + (p)->id * 0x1000)
84 * struct mvebu_cp110_utmi - PHY driver data
86 * @regs: PHY registers
87 * @syscon: Regmap with system controller registers
89 * @ops: phy ops
93 struct regmap *syscon; member
99 * struct mvebu_cp110_utmi_port - PHY port data
101 * @priv: PHY driver data
102 * @id: PHY port ID
103 * @dr_mode: PHY connection: USB_DR_MODE_HOST or USB_DR_MODE_PERIPHERAL
104 * @swap_dx: whether to swap d+/d- signals
159 * Set Control VDAT Reference Voltage - 0.325V and in mvebu_cp110_utmi_port_setup()
160 * Control VSRC Reference Voltage - 0.6V in mvebu_cp110_utmi_port_setup()
167 /* Swap D+/D- */ in mvebu_cp110_utmi_port_setup()
170 if (port->swap_dx) in mvebu_cp110_utmi_port_setup()
175 static int mvebu_cp110_utmi_phy_power_off(struct phy *phy) in mvebu_cp110_utmi_phy_power_off() argument
177 struct mvebu_cp110_utmi_port *port = phy_get_drvdata(phy); in mvebu_cp110_utmi_phy_power_off()
178 struct mvebu_cp110_utmi *utmi = port->priv; in mvebu_cp110_utmi_phy_power_off()
181 /* Power down UTMI PHY port */ in mvebu_cp110_utmi_phy_power_off()
182 regmap_clear_bits(utmi->syscon, SYSCON_UTMI_CFG_REG(port->id), in mvebu_cp110_utmi_phy_power_off()
186 int test = regmap_test_bits(utmi->syscon, in mvebu_cp110_utmi_phy_power_off()
189 /* skip PLL shutdown if there are active UTMI PHY ports */ in mvebu_cp110_utmi_phy_power_off()
194 /* PLL Power down if all UTMI PHYs are down */ in mvebu_cp110_utmi_phy_power_off()
195 regmap_clear_bits(utmi->syscon, SYSCON_USB_CFG_REG, USB_CFG_PLL_MASK); in mvebu_cp110_utmi_phy_power_off()
200 static int mvebu_cp110_utmi_phy_power_on(struct phy *phy) in mvebu_cp110_utmi_phy_power_on() argument
202 struct mvebu_cp110_utmi_port *port = phy_get_drvdata(phy); in mvebu_cp110_utmi_phy_power_on()
203 struct mvebu_cp110_utmi *utmi = port->priv; in mvebu_cp110_utmi_phy_power_on()
204 struct device *dev = &phy->dev; in mvebu_cp110_utmi_phy_power_on()
208 /* It is necessary to power off UTMI before configuration */ in mvebu_cp110_utmi_phy_power_on()
209 ret = mvebu_cp110_utmi_phy_power_off(phy); in mvebu_cp110_utmi_phy_power_on()
211 dev_err(dev, "UTMI power OFF before power ON failed\n"); in mvebu_cp110_utmi_phy_power_on()
217 * configure the USB MUX prior to UTMI PHY initialization. in mvebu_cp110_utmi_phy_power_on()
219 * to UTMI0 or to UTMI1 PHY port, but not to both. in mvebu_cp110_utmi_phy_power_on()
221 if (port->dr_mode == USB_DR_MODE_PERIPHERAL) { in mvebu_cp110_utmi_phy_power_on()
222 regmap_update_bits(utmi->syscon, SYSCON_USB_CFG_REG, in mvebu_cp110_utmi_phy_power_on()
225 (port->id << USB_CFG_DEVICE_MUX_OFFSET)); in mvebu_cp110_utmi_phy_power_on()
233 /* Wait for UTMI power down */ in mvebu_cp110_utmi_phy_power_on()
236 /* PHY port setup first */ in mvebu_cp110_utmi_phy_power_on()
239 /* Power UP UTMI PHY */ in mvebu_cp110_utmi_phy_power_on()
240 regmap_set_bits(utmi->syscon, SYSCON_UTMI_CFG_REG(port->id), in mvebu_cp110_utmi_phy_power_on()
275 /* PLL Power up */ in mvebu_cp110_utmi_phy_power_on()
276 regmap_set_bits(utmi->syscon, SYSCON_USB_CFG_REG, USB_CFG_PLL_MASK); in mvebu_cp110_utmi_phy_power_on()
288 { .compatible = "marvell,cp110-utmi-phy" },
295 struct device *dev = &pdev->dev; in mvebu_cp110_utmi_phy_probe()
304 return -ENOMEM; in mvebu_cp110_utmi_phy_probe()
306 utmi->dev = dev; in mvebu_cp110_utmi_phy_probe()
309 utmi->syscon = syscon_regmap_lookup_by_phandle(dev->of_node, in mvebu_cp110_utmi_phy_probe()
310 "marvell,system-controller"); in mvebu_cp110_utmi_phy_probe()
311 if (IS_ERR(utmi->syscon)) { in mvebu_cp110_utmi_phy_probe()
313 return PTR_ERR(utmi->syscon); in mvebu_cp110_utmi_phy_probe()
317 utmi->regs = devm_platform_ioremap_resource(pdev, 0); in mvebu_cp110_utmi_phy_probe()
318 if (IS_ERR(utmi->regs)) in mvebu_cp110_utmi_phy_probe()
319 return PTR_ERR(utmi->regs); in mvebu_cp110_utmi_phy_probe()
321 for_each_available_child_of_node(dev->of_node, child) { in mvebu_cp110_utmi_phy_probe()
323 struct phy *phy; in mvebu_cp110_utmi_phy_probe() local
338 return -ENOMEM; in mvebu_cp110_utmi_phy_probe()
341 port->dr_mode = of_usb_get_dr_mode_by_phy(child, -1); in mvebu_cp110_utmi_phy_probe()
342 if ((port->dr_mode != USB_DR_MODE_HOST) && in mvebu_cp110_utmi_phy_probe()
343 (port->dr_mode != USB_DR_MODE_PERIPHERAL)) { in mvebu_cp110_utmi_phy_probe()
344 dev_err(&pdev->dev, in mvebu_cp110_utmi_phy_probe()
347 port->dr_mode = USB_DR_MODE_HOST; in mvebu_cp110_utmi_phy_probe()
350 if (port->dr_mode == USB_DR_MODE_PERIPHERAL) { in mvebu_cp110_utmi_phy_probe()
356 port->dr_mode = USB_DR_MODE_HOST; in mvebu_cp110_utmi_phy_probe()
360 of_property_for_each_u32(dev->of_node, "swap-dx-lanes", swap_dx) in mvebu_cp110_utmi_phy_probe()
362 port->swap_dx = 1; in mvebu_cp110_utmi_phy_probe()
364 /* Retrieve PHY capabilities */ in mvebu_cp110_utmi_phy_probe()
365 utmi->ops = &mvebu_cp110_utmi_phy_ops; in mvebu_cp110_utmi_phy_probe()
367 /* Instantiate the PHY */ in mvebu_cp110_utmi_phy_probe()
368 phy = devm_phy_create(dev, child, utmi->ops); in mvebu_cp110_utmi_phy_probe()
369 if (IS_ERR(phy)) { in mvebu_cp110_utmi_phy_probe()
370 dev_err(dev, "Failed to create the UTMI PHY\n"); in mvebu_cp110_utmi_phy_probe()
372 return PTR_ERR(phy); in mvebu_cp110_utmi_phy_probe()
375 port->priv = utmi; in mvebu_cp110_utmi_phy_probe()
376 port->id = port_id; in mvebu_cp110_utmi_phy_probe()
377 phy_set_drvdata(phy, port); in mvebu_cp110_utmi_phy_probe()
379 /* Ensure the PHY is powered off */ in mvebu_cp110_utmi_phy_probe()
380 mvebu_cp110_utmi_phy_power_off(phy); in mvebu_cp110_utmi_phy_probe()
392 .name = "mvebu-cp110-utmi-phy",
399 MODULE_DESCRIPTION("Marvell Armada CP110 UTMI PHY driver");