Lines Matching +full:phy +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0
9 * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart.
13 #include <linux/arm-smccc.h>
18 #include <linux/phy.h>
19 #include <linux/phy/phy.h>
29 #define COMPHY_FW_NOT_SUPPORTED (-1)
51 #define COMPHY_FW_MODE(mode) ((mode) << 12) argument
52 #define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ argument
55 #define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ argument
60 enum phy_mode mode; member
69 .mode = _mode, \
106 enum phy_mode mode; member
112 unsigned long mode) in mvebu_a3700_comphy_smc() argument
116 arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); in mvebu_a3700_comphy_smc()
122 enum phy_mode mode, in mvebu_a3700_comphy_get_fw_mode() argument
127 /* Unused PHY mux value is 0x0 */ in mvebu_a3700_comphy_get_fw_mode()
128 if (mode == PHY_MODE_INVALID) in mvebu_a3700_comphy_get_fw_mode()
129 return -EINVAL; in mvebu_a3700_comphy_get_fw_mode()
134 mvebu_a3700_comphy_modes[i].mode == mode && in mvebu_a3700_comphy_get_fw_mode()
140 return -EINVAL; in mvebu_a3700_comphy_get_fw_mode()
145 static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, in mvebu_a3700_comphy_set_mode() argument
148 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_set_mode()
154 fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, in mvebu_a3700_comphy_set_mode()
157 dev_err(lane->dev, "invalid COMPHY mode\n"); in mvebu_a3700_comphy_set_mode()
161 /* Just remember the mode, ->power_on() will do the real setup */ in mvebu_a3700_comphy_set_mode()
162 lane->mode = mode; in mvebu_a3700_comphy_set_mode()
163 lane->submode = submode; in mvebu_a3700_comphy_set_mode()
168 static int mvebu_a3700_comphy_power_on(struct phy *phy) in mvebu_a3700_comphy_power_on() argument
170 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_power_on()
175 fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, in mvebu_a3700_comphy_power_on()
176 lane->mode, lane->submode); in mvebu_a3700_comphy_power_on()
178 dev_err(lane->dev, "invalid COMPHY mode\n"); in mvebu_a3700_comphy_power_on()
182 switch (lane->mode) { in mvebu_a3700_comphy_power_on()
184 dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); in mvebu_a3700_comphy_power_on()
188 dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); in mvebu_a3700_comphy_power_on()
192 switch (lane->submode) { in mvebu_a3700_comphy_power_on()
194 dev_dbg(lane->dev, "set lane %d to SGMII mode\n", in mvebu_a3700_comphy_power_on()
195 lane->id); in mvebu_a3700_comphy_power_on()
196 fw_param = COMPHY_FW_NET(fw_mode, lane->port, in mvebu_a3700_comphy_power_on()
200 dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n", in mvebu_a3700_comphy_power_on()
201 lane->id); in mvebu_a3700_comphy_power_on()
202 fw_param = COMPHY_FW_NET(fw_mode, lane->port, in mvebu_a3700_comphy_power_on()
206 dev_err(lane->dev, "unsupported PHY submode (%d)\n", in mvebu_a3700_comphy_power_on()
207 lane->submode); in mvebu_a3700_comphy_power_on()
208 return -ENOTSUPP; in mvebu_a3700_comphy_power_on()
212 dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); in mvebu_a3700_comphy_power_on()
213 fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, in mvebu_a3700_comphy_power_on()
215 phy->attrs.bus_width); in mvebu_a3700_comphy_power_on()
218 dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); in mvebu_a3700_comphy_power_on()
219 return -ENOTSUPP; in mvebu_a3700_comphy_power_on()
222 ret = mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); in mvebu_a3700_comphy_power_on()
224 dev_err(lane->dev, in mvebu_a3700_comphy_power_on()
230 static int mvebu_a3700_comphy_power_off(struct phy *phy) in mvebu_a3700_comphy_power_off() argument
232 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_power_off()
234 return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); in mvebu_a3700_comphy_power_off()
244 static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, in mvebu_a3700_comphy_xlate()
248 struct phy *phy; in mvebu_a3700_comphy_xlate() local
250 if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) in mvebu_a3700_comphy_xlate()
251 return ERR_PTR(-EINVAL); in mvebu_a3700_comphy_xlate()
253 phy = of_phy_simple_xlate(dev, args); in mvebu_a3700_comphy_xlate()
254 if (IS_ERR(phy)) in mvebu_a3700_comphy_xlate()
255 return phy; in mvebu_a3700_comphy_xlate()
257 lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_xlate()
258 lane->port = args->args[0]; in mvebu_a3700_comphy_xlate()
260 return phy; in mvebu_a3700_comphy_xlate()
268 for_each_available_child_of_node(pdev->dev.of_node, child) { in mvebu_a3700_comphy_probe()
270 struct phy *phy; in mvebu_a3700_comphy_probe() local
276 dev_err(&pdev->dev, "missing 'reg' property (%d)\n", in mvebu_a3700_comphy_probe()
282 dev_err(&pdev->dev, "invalid 'reg' property\n"); in mvebu_a3700_comphy_probe()
286 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); in mvebu_a3700_comphy_probe()
289 return -ENOMEM; in mvebu_a3700_comphy_probe()
292 phy = devm_phy_create(&pdev->dev, child, in mvebu_a3700_comphy_probe()
294 if (IS_ERR(phy)) { in mvebu_a3700_comphy_probe()
296 return PTR_ERR(phy); in mvebu_a3700_comphy_probe()
299 lane->dev = &pdev->dev; in mvebu_a3700_comphy_probe()
300 lane->mode = PHY_MODE_INVALID; in mvebu_a3700_comphy_probe()
301 lane->submode = PHY_INTERFACE_MODE_NA; in mvebu_a3700_comphy_probe()
302 lane->id = lane_id; in mvebu_a3700_comphy_probe()
303 lane->port = -1; in mvebu_a3700_comphy_probe()
304 phy_set_drvdata(phy, lane); in mvebu_a3700_comphy_probe()
307 provider = devm_of_phy_provider_register(&pdev->dev, in mvebu_a3700_comphy_probe()
313 { .compatible = "marvell,comphy-a3700" },
321 .name = "mvebu-a3700-comphy",
328 MODULE_DESCRIPTION("Common PHY driver for A3700");