• Home
  • Raw
  • Download

Lines Matching +full:cp110 +full:- +full:utmi +full:- +full:phy

1 // SPDX-License-Identifier: GPL-2.0
11 * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart.
23 #include <linux/phy.h>
24 #include <linux/phy/phy.h>
36 /* SATA and USB3 PHY offset compared to SATA PHY */
40 * When accessing common PHY lane registers directly, we need to shift by 1,
41 * since the registers are 16-bit.
175 * This register is not from PHY lane register space. It only exists in the
176 * indirect register space, before the actual PHY lane 2 registers. So the
178 * It is used only for SATA PHY initialization.
183 /* South Bridge PHY Configuration Registers */
184 #define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f))
187 * lane0: USB3/GbE1 PHY Configuration 1
188 * lane1: PCIe/GbE0 PHY Configuration 1
208 * lane0: USB3/GbE1 PHY Status 1
209 * lane1: PCIe/GbE0 PHY Status 1
217 /* PHY Selector */
266 spinlock_t lock; /* for PHY selector access */
301 /*-----------------------------------------------------------*/
387 /* Used for accessing lane 2 registers (SATA/USB3 PHY) */
392 priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR); in comphy_set_indirect()
393 comphy_reg_set(priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA, in comphy_set_indirect()
400 if (lane->id == 2) { in comphy_lane_reg_set()
401 /* lane 2 PHY registers are accessed indirectly */ in comphy_lane_reg_set()
402 comphy_set_indirect(lane->priv, in comphy_lane_reg_set()
406 void __iomem *base = lane->id == 1 ? in comphy_lane_reg_set()
407 lane->priv->lane1_phy_regs : in comphy_lane_reg_set()
408 lane->priv->lane0_phy_regs; in comphy_lane_reg_set()
421 if (lane->id == 2) { in comphy_lane_reg_poll()
424 /* lane 2 PHY registers are accessed indirectly */ in comphy_lane_reg_poll()
426 lane->priv->lane2_phy_indirect + in comphy_lane_reg_poll()
429 ret = readl_poll_timeout(lane->priv->lane2_phy_indirect + in comphy_lane_reg_poll()
434 void __iomem *base = lane->id == 1 ? in comphy_lane_reg_poll()
435 lane->priv->lane1_phy_regs : in comphy_lane_reg_poll()
436 lane->priv->lane0_phy_regs; in comphy_lane_reg_poll()
450 comphy_reg_set(lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg), in comphy_periph_reg_set()
460 return readl_poll_timeout(lane->priv->comphy_regs + in comphy_periph_reg_poll()
461 COMPHY_PHY_REG(lane->id, reg), in comphy_periph_reg_poll()
466 /* PHY selector configures with corresponding modes */
473 switch (lane->mode) { in mvebu_a3700_comphy_set_phy_selector()
476 if (lane->id == 2) in mvebu_a3700_comphy_set_phy_selector()
483 if (lane->id == 0) in mvebu_a3700_comphy_set_phy_selector()
485 else if (lane->id == 1) in mvebu_a3700_comphy_set_phy_selector()
492 if (lane->id == 2) in mvebu_a3700_comphy_set_phy_selector()
494 else if (lane->id == 0) in mvebu_a3700_comphy_set_phy_selector()
502 if (lane->id == 1) in mvebu_a3700_comphy_set_phy_selector()
512 spin_lock_irqsave(&lane->priv->lock, flags); in mvebu_a3700_comphy_set_phy_selector()
514 old = readl(lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); in mvebu_a3700_comphy_set_phy_selector()
516 writel(new, lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); in mvebu_a3700_comphy_set_phy_selector()
518 spin_unlock_irqrestore(&lane->priv->lock, flags); in mvebu_a3700_comphy_set_phy_selector()
520 dev_dbg(lane->dev, in mvebu_a3700_comphy_set_phy_selector()
521 "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n", in mvebu_a3700_comphy_set_phy_selector()
522 lane->id, lane->mode, old, new); in mvebu_a3700_comphy_set_phy_selector()
526 dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n", lane->id, in mvebu_a3700_comphy_set_phy_selector()
527 lane->mode); in mvebu_a3700_comphy_set_phy_selector()
528 return -EINVAL; in mvebu_a3700_comphy_set_phy_selector()
537 /* Configure phy selector for SATA */ in mvebu_a3700_comphy_sata_power_on()
542 /* Clear phy isolation mode to make it work in normal mode */ in mvebu_a3700_comphy_sata_power_on()
548 if (lane->invert_tx) in mvebu_a3700_comphy_sata_power_on()
550 if (lane->invert_rx) in mvebu_a3700_comphy_sata_power_on()
555 /* 1. Select 40-bit data width */ in mvebu_a3700_comphy_sata_power_on()
559 /* 2. Select reference clock(25M) and PHY mode (SATA) */ in mvebu_a3700_comphy_sata_power_on()
560 if (lane->priv->xtal_is_40m) in mvebu_a3700_comphy_sata_power_on()
574 comphy_set_indirect(lane->priv, COMPHY_RESERVED_REG, in mvebu_a3700_comphy_sata_power_on()
577 /* 5. Set vendor-specific configuration (It is done in sata driver) */ in mvebu_a3700_comphy_sata_power_on()
578 /* XXX: in U-Boot below sequence was executed in this place, in Linux in mvebu_a3700_comphy_sata_power_on()
579 * not. Now it is done only in U-Boot before this comphy in mvebu_a3700_comphy_sata_power_on()
580 * initialization - tests shows that it works ok, but in case of any in mvebu_a3700_comphy_sata_power_on()
594 dev_err(lane->dev, "Failed to lock SATA PLL\n"); in mvebu_a3700_comphy_sata_power_on()
608 * All PHY register values are defined in full for 3.125Gbps in comphy_gbe_phy_init()
639 * 1. Reset PHY by setting PHY input port PIN_RESET=1. in mvebu_a3700_comphy_ethernet_power_on()
640 * 2. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep in mvebu_a3700_comphy_ethernet_power_on()
641 * PHY TXP/TXN output to idle state during PHY initialization in mvebu_a3700_comphy_ethernet_power_on()
642 * 3. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0. in mvebu_a3700_comphy_ethernet_power_on()
649 /* 4. Release reset to the PHY by setting PIN_RESET=0. */ in mvebu_a3700_comphy_ethernet_power_on()
658 switch (lane->submode) { in mvebu_a3700_comphy_ethernet_power_on()
665 /* 2500Base-X, SerDes speed 3.125G */ in mvebu_a3700_comphy_ethernet_power_on()
670 dev_err(lane->dev, in mvebu_a3700_comphy_ethernet_power_on()
671 "unsupported phy speed %d on comphy lane%d\n", in mvebu_a3700_comphy_ethernet_power_on()
672 lane->submode, lane->id); in mvebu_a3700_comphy_ethernet_power_on()
673 return -EINVAL; in mvebu_a3700_comphy_ethernet_power_on()
702 if (lane->priv->xtal_is_40m) in mvebu_a3700_comphy_ethernet_power_on()
731 * default value after reset of the PHY. in mvebu_a3700_comphy_ethernet_power_on()
738 * the related GEN table during real chip bring-up. We only required to in mvebu_a3700_comphy_ethernet_power_on()
741 * 25 MHz the default values stored in PHY registers are OK. in mvebu_a3700_comphy_ethernet_power_on()
743 dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n", in mvebu_a3700_comphy_ethernet_power_on()
744 lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G"); in mvebu_a3700_comphy_ethernet_power_on()
745 if (lane->priv->xtal_is_40m) in mvebu_a3700_comphy_ethernet_power_on()
747 lane->submode != PHY_INTERFACE_MODE_2500BASEX); in mvebu_a3700_comphy_ethernet_power_on()
750 * 14. Check the PHY Polarity invert bit in mvebu_a3700_comphy_ethernet_power_on()
753 if (lane->invert_tx) in mvebu_a3700_comphy_ethernet_power_on()
755 if (lane->invert_rx) in mvebu_a3700_comphy_ethernet_power_on()
761 * 15. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1 to in mvebu_a3700_comphy_ethernet_power_on()
762 * start PHY power up sequence. All the PHY register programming should in mvebu_a3700_comphy_ethernet_power_on()
764 * for normal PHY operation from this point. in mvebu_a3700_comphy_ethernet_power_on()
771 * 16. Wait for PHY power up sequence to finish by checking output ports in mvebu_a3700_comphy_ethernet_power_on()
779 dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n", in mvebu_a3700_comphy_ethernet_power_on()
780 lane->id); in mvebu_a3700_comphy_ethernet_power_on()
792 * PHY After RX initialization is done, PIN_RX_INIT_DONE will be set to in mvebu_a3700_comphy_ethernet_power_on()
804 dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n", in mvebu_a3700_comphy_ethernet_power_on()
805 lane->id); in mvebu_a3700_comphy_ethernet_power_on()
813 dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n", in mvebu_a3700_comphy_ethernet_power_on()
814 lane->id); in mvebu_a3700_comphy_ethernet_power_on()
825 /* Set phy seclector */ in mvebu_a3700_comphy_usb3_power_on()
834 * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The in mvebu_a3700_comphy_usb3_power_on()
835 * register belong to UTMI module, so it is set in UTMI phy driver. in mvebu_a3700_comphy_usb3_power_on()
839 * 1. Set PRD_TXDEEMPH (3.5db de-emph) in mvebu_a3700_comphy_usb3_power_on()
850 * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db in mvebu_a3700_comphy_usb3_power_on()
872 * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles in mvebu_a3700_comphy_usb3_power_on()
899 if (lane->priv->xtal_is_40m) { in mvebu_a3700_comphy_usb3_power_on()
931 * 11. Set 20-bit data width in mvebu_a3700_comphy_usb3_power_on()
947 if (lane->invert_tx) in mvebu_a3700_comphy_usb3_power_on()
949 if (lane->invert_rx) in mvebu_a3700_comphy_usb3_power_on()
979 dev_err(lane->dev, "Failed to lock USB3 PLL\n"); in mvebu_a3700_comphy_usb3_power_on()
990 /* Configure phy selector for PCIe */ in mvebu_a3700_comphy_pcie_power_on()
1024 * PCI-E driver in mvebu_a3700_comphy_pcie_power_on()
1032 if (lane->priv->xtal_is_40m) in mvebu_a3700_comphy_pcie_power_on()
1049 if (lane->invert_tx) in mvebu_a3700_comphy_pcie_power_on()
1051 if (lane->invert_rx) in mvebu_a3700_comphy_pcie_power_on()
1067 dev_err(lane->dev, "Failed to lock PCIE PLL\n"); in mvebu_a3700_comphy_pcie_power_on()
1075 /* Set phy isolation mode */ in mvebu_a3700_comphy_sata_power_off()
1106 * The USB3 MAC sets the USB3 PHY to low state, so we do not in mvebu_a3700_comphy_usb3_power_off()
1107 * need to power off USB3 PHY again. in mvebu_a3700_comphy_usb3_power_off()
1117 /* Unused PHY mux value is 0x0 */ in mvebu_a3700_comphy_check_mode()
1134 static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, in mvebu_a3700_comphy_set_mode() argument
1137 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_set_mode()
1139 if (!mvebu_a3700_comphy_check_mode(lane->id, mode, submode)) { in mvebu_a3700_comphy_set_mode()
1140 dev_err(lane->dev, "invalid COMPHY mode\n"); in mvebu_a3700_comphy_set_mode()
1141 return -EINVAL; in mvebu_a3700_comphy_set_mode()
1144 /* Mode cannot be changed while the PHY is powered on */ in mvebu_a3700_comphy_set_mode()
1145 if (phy->power_count && in mvebu_a3700_comphy_set_mode()
1146 (lane->mode != mode || lane->submode != submode)) in mvebu_a3700_comphy_set_mode()
1147 return -EBUSY; in mvebu_a3700_comphy_set_mode()
1149 /* Just remember the mode, ->power_on() will do the real setup */ in mvebu_a3700_comphy_set_mode()
1150 lane->mode = mode; in mvebu_a3700_comphy_set_mode()
1151 lane->submode = submode; in mvebu_a3700_comphy_set_mode()
1156 static int mvebu_a3700_comphy_power_on(struct phy *phy) in mvebu_a3700_comphy_power_on() argument
1158 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_power_on()
1160 if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode, in mvebu_a3700_comphy_power_on()
1161 lane->submode)) { in mvebu_a3700_comphy_power_on()
1162 dev_err(lane->dev, "invalid COMPHY mode\n"); in mvebu_a3700_comphy_power_on()
1163 return -EINVAL; in mvebu_a3700_comphy_power_on()
1166 switch (lane->mode) { in mvebu_a3700_comphy_power_on()
1168 dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); in mvebu_a3700_comphy_power_on()
1171 dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); in mvebu_a3700_comphy_power_on()
1174 dev_dbg(lane->dev, "set lane %d to Ethernet mode\n", lane->id); in mvebu_a3700_comphy_power_on()
1177 dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); in mvebu_a3700_comphy_power_on()
1180 dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); in mvebu_a3700_comphy_power_on()
1181 return -EOPNOTSUPP; in mvebu_a3700_comphy_power_on()
1185 static int mvebu_a3700_comphy_power_off(struct phy *phy) in mvebu_a3700_comphy_power_off() argument
1187 struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_power_off()
1189 switch (lane->id) { in mvebu_a3700_comphy_power_off()
1203 dev_err(lane->dev, "invalid COMPHY mode\n"); in mvebu_a3700_comphy_power_off()
1204 return -EINVAL; in mvebu_a3700_comphy_power_off()
1215 static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, in mvebu_a3700_comphy_xlate()
1220 struct phy *phy; in mvebu_a3700_comphy_xlate() local
1222 phy = of_phy_simple_xlate(dev, args); in mvebu_a3700_comphy_xlate()
1223 if (IS_ERR(phy)) in mvebu_a3700_comphy_xlate()
1224 return phy; in mvebu_a3700_comphy_xlate()
1226 lane = phy_get_drvdata(phy); in mvebu_a3700_comphy_xlate()
1228 port = args->args[0]; in mvebu_a3700_comphy_xlate()
1229 if (port != 0 && (port != 1 || lane->id != 0)) { in mvebu_a3700_comphy_xlate()
1230 dev_err(lane->dev, "invalid port number %u\n", port); in mvebu_a3700_comphy_xlate()
1231 return ERR_PTR(-EINVAL); in mvebu_a3700_comphy_xlate()
1234 lane->invert_tx = args->args[1] & BIT(0); in mvebu_a3700_comphy_xlate()
1235 lane->invert_rx = args->args[1] & BIT(1); in mvebu_a3700_comphy_xlate()
1237 return phy; in mvebu_a3700_comphy_xlate()
1249 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in mvebu_a3700_comphy_probe()
1251 return -ENOMEM; in mvebu_a3700_comphy_probe()
1253 spin_lock_init(&priv->lock); in mvebu_a3700_comphy_probe()
1256 priv->comphy_regs = devm_ioremap_resource(&pdev->dev, res); in mvebu_a3700_comphy_probe()
1257 if (IS_ERR(priv->comphy_regs)) in mvebu_a3700_comphy_probe()
1258 return PTR_ERR(priv->comphy_regs); in mvebu_a3700_comphy_probe()
1262 priv->lane1_phy_regs = devm_ioremap_resource(&pdev->dev, res); in mvebu_a3700_comphy_probe()
1263 if (IS_ERR(priv->lane1_phy_regs)) in mvebu_a3700_comphy_probe()
1264 return PTR_ERR(priv->lane1_phy_regs); in mvebu_a3700_comphy_probe()
1268 priv->lane0_phy_regs = devm_ioremap_resource(&pdev->dev, res); in mvebu_a3700_comphy_probe()
1269 if (IS_ERR(priv->lane0_phy_regs)) in mvebu_a3700_comphy_probe()
1270 return PTR_ERR(priv->lane0_phy_regs); in mvebu_a3700_comphy_probe()
1274 priv->lane2_phy_indirect = devm_ioremap_resource(&pdev->dev, res); in mvebu_a3700_comphy_probe()
1275 if (IS_ERR(priv->lane2_phy_indirect)) in mvebu_a3700_comphy_probe()
1276 return PTR_ERR(priv->lane2_phy_indirect); in mvebu_a3700_comphy_probe()
1283 clk = clk_get(&pdev->dev, "xtal"); in mvebu_a3700_comphy_probe()
1285 if (PTR_ERR(clk) == -EPROBE_DEFER) in mvebu_a3700_comphy_probe()
1286 return -EPROBE_DEFER; in mvebu_a3700_comphy_probe()
1287 dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n", in mvebu_a3700_comphy_probe()
1292 dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n", in mvebu_a3700_comphy_probe()
1296 priv->xtal_is_40m = true; in mvebu_a3700_comphy_probe()
1302 dev_set_drvdata(&pdev->dev, priv); in mvebu_a3700_comphy_probe()
1304 for_each_available_child_of_node(pdev->dev.of_node, child) { in mvebu_a3700_comphy_probe()
1306 struct phy *phy; in mvebu_a3700_comphy_probe() local
1312 dev_err(&pdev->dev, "missing 'reg' property (%d)\n", in mvebu_a3700_comphy_probe()
1318 dev_err(&pdev->dev, "invalid 'reg' property\n"); in mvebu_a3700_comphy_probe()
1322 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); in mvebu_a3700_comphy_probe()
1325 return -ENOMEM; in mvebu_a3700_comphy_probe()
1328 phy = devm_phy_create(&pdev->dev, child, in mvebu_a3700_comphy_probe()
1330 if (IS_ERR(phy)) { in mvebu_a3700_comphy_probe()
1332 return PTR_ERR(phy); in mvebu_a3700_comphy_probe()
1335 lane->priv = priv; in mvebu_a3700_comphy_probe()
1336 lane->dev = &pdev->dev; in mvebu_a3700_comphy_probe()
1337 lane->mode = PHY_MODE_INVALID; in mvebu_a3700_comphy_probe()
1338 lane->submode = PHY_INTERFACE_MODE_NA; in mvebu_a3700_comphy_probe()
1339 lane->id = lane_id; in mvebu_a3700_comphy_probe()
1340 lane->invert_tx = false; in mvebu_a3700_comphy_probe()
1341 lane->invert_rx = false; in mvebu_a3700_comphy_probe()
1342 phy_set_drvdata(phy, lane); in mvebu_a3700_comphy_probe()
1348 mvebu_a3700_comphy_power_off(phy); in mvebu_a3700_comphy_probe()
1351 provider = devm_of_phy_provider_register(&pdev->dev, in mvebu_a3700_comphy_probe()
1358 { .compatible = "marvell,comphy-a3700" },
1366 .name = "mvebu-a3700-comphy",
1375 MODULE_DESCRIPTION("Common PHY driver for A3700");