Lines Matching +full:phy +full:- +full:imx8 +full:- +full:pcie
1 // SPDX-License-Identifier: GPL-2.0+
14 #include <linux/phy/phy.h>
15 #include <linux/phy/pcie.h>
19 #include <dt-bindings/phy/phy.h>
20 #include <dt-bindings/phy/phy-imx8-pcie.h>
25 /* Parameters for the waiting for PCIe PHY PLL to lock */
81 struct phy *phy; member
92 struct regmap *phy; member
116 static int imx_hsio_init(struct phy *phy) in imx_hsio_init() argument
119 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_init()
120 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_init()
121 struct device *dev = priv->dev; in imx_hsio_init()
124 switch (lane->phy_type) { in imx_hsio_init()
126 lane->phy_mode = PHY_MODE_PCIE; in imx_hsio_init()
127 if (lane->ctrl_index == 0) { /* PCIEA */ in imx_hsio_init()
128 lane->ctrl_off = 0; in imx_hsio_init()
129 lane->phy_off = 0; in imx_hsio_init()
132 if (lane->idx == 0) in imx_hsio_init()
133 lane->clks[i].id = lan0_pcie_clks[i]; in imx_hsio_init()
135 lane->clks[i].id = lan1_pciea_clks[i]; in imx_hsio_init()
138 if (lane->idx == 0) { /* i.MX8QXP */ in imx_hsio_init()
139 lane->ctrl_off = 0; in imx_hsio_init()
140 lane->phy_off = 0; in imx_hsio_init()
146 lane->ctrl_off = SZ_64K; in imx_hsio_init()
147 if (lane->idx == 1) in imx_hsio_init()
148 lane->phy_off = 0; in imx_hsio_init()
150 lane->phy_off = SZ_64K; in imx_hsio_init()
154 if (lane->idx == 1) in imx_hsio_init()
155 lane->clks[i].id = lan1_pcieb_clks[i]; in imx_hsio_init()
156 else if (lane->idx == 2) in imx_hsio_init()
157 lane->clks[i].id = lan2_pcieb_clks[i]; in imx_hsio_init()
159 lane->clks[i].id = lan0_pcie_clks[i]; in imx_hsio_init()
165 lane->phy_mode = PHY_MODE_SATA; in imx_hsio_init()
166 lane->ctrl_off = SZ_128K; in imx_hsio_init()
167 lane->phy_off = SZ_64K; in imx_hsio_init()
170 lane->clks[i].id = lan2_sata_clks[i]; in imx_hsio_init()
173 return -EINVAL; in imx_hsio_init()
177 ret = devm_clk_bulk_get(dev, LANE_NUM_CLKS, lane->clks); in imx_hsio_init()
180 ret = clk_bulk_prepare_enable(LANE_NUM_CLKS, lane->clks); in imx_hsio_init()
189 static int imx_hsio_exit(struct phy *phy) in imx_hsio_exit() argument
191 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_exit()
193 clk_bulk_disable_unprepare(LANE_NUM_CLKS, lane->clks); in imx_hsio_exit()
198 static void imx_hsio_pcie_phy_resets(struct phy *phy) in imx_hsio_pcie_phy_resets() argument
200 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_pcie_phy_resets()
201 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_pcie_phy_resets()
203 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_pcie_phy_resets()
205 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_pcie_phy_resets()
207 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_pcie_phy_resets()
209 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_pcie_phy_resets()
211 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_pcie_phy_resets()
213 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_pcie_phy_resets()
216 if (lane->idx == 1) { in imx_hsio_pcie_phy_resets()
217 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, in imx_hsio_pcie_phy_resets()
219 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, in imx_hsio_pcie_phy_resets()
222 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, in imx_hsio_pcie_phy_resets()
224 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, in imx_hsio_pcie_phy_resets()
229 static void imx_hsio_sata_phy_resets(struct phy *phy) in imx_hsio_sata_phy_resets() argument
231 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_sata_phy_resets()
232 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_sata_phy_resets()
234 /* clear PHY RST, then set it */ in imx_hsio_sata_phy_resets()
235 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, in imx_hsio_sata_phy_resets()
237 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, in imx_hsio_sata_phy_resets()
240 /* CTRL RST: SET -> delay 1 us -> CLEAR -> SET */ in imx_hsio_sata_phy_resets()
241 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, HSIO_RESET_N); in imx_hsio_sata_phy_resets()
243 regmap_clear_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, in imx_hsio_sata_phy_resets()
245 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, HSIO_RESET_N); in imx_hsio_sata_phy_resets()
248 static void imx_hsio_configure_clk_pad(struct phy *phy) in imx_hsio_configure_clk_pad() argument
251 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_configure_clk_pad()
252 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_configure_clk_pad()
254 if (strncmp(priv->refclk_pad, "output", 6) == 0) { in imx_hsio_configure_clk_pad()
256 regmap_update_bits(priv->misc, HSIO_CTRL0, in imx_hsio_configure_clk_pad()
260 regmap_update_bits(priv->misc, HSIO_CTRL0, in imx_hsio_configure_clk_pad()
265 regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_RXENA, in imx_hsio_configure_clk_pad()
267 regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_TXENA, in imx_hsio_configure_clk_pad()
271 static void imx_hsio_pre_set(struct phy *phy) in imx_hsio_pre_set() argument
273 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_pre_set()
274 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_pre_set()
276 if (strncmp(priv->hsio_cfg, "pciea-x2-pcieb", 14) == 0) { in imx_hsio_pre_set()
277 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PCIE_AB_SELECT); in imx_hsio_pre_set()
278 } else if (strncmp(priv->hsio_cfg, "pciea-x2-sata", 13) == 0) { in imx_hsio_pre_set()
279 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PHYX1_EPCS_SEL); in imx_hsio_pre_set()
280 } else if (strncmp(priv->hsio_cfg, "pciea-pcieb-sata", 16) == 0) { in imx_hsio_pre_set()
281 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PCIE_AB_SELECT); in imx_hsio_pre_set()
282 regmap_set_bits(priv->misc, HSIO_CTRL0, HSIO_PHYX1_EPCS_SEL); in imx_hsio_pre_set()
285 imx_hsio_configure_clk_pad(phy); in imx_hsio_pre_set()
288 static int imx_hsio_pcie_power_on(struct phy *phy) in imx_hsio_pcie_power_on() argument
292 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_pcie_power_on()
293 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_pcie_power_on()
295 imx_hsio_pcie_phy_resets(phy); in imx_hsio_pcie_power_on()
298 clk_disable_unprepare(lane->clks[0].clk); in imx_hsio_pcie_power_on()
300 ret = clk_prepare_enable(lane->clks[0].clk); in imx_hsio_pcie_power_on()
302 dev_err(priv->dev, "unable to enable phy apb_pclk\n"); in imx_hsio_pcie_power_on()
306 addr = lane->ctrl_off + HSIO_PCIE_STS0; in imx_hsio_pcie_power_on()
308 ret = regmap_read_poll_timeout(priv->ctrl, addr, val, in imx_hsio_pcie_power_on()
313 dev_err(priv->dev, "HSIO_PM_REQ_CORE_RST is set\n"); in imx_hsio_pcie_power_on()
317 static int imx_hsio_sata_power_on(struct phy *phy) in imx_hsio_sata_power_on() argument
321 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_sata_power_on()
322 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_sata_power_on()
324 regmap_set_bits(priv->phy, lane->phy_off + HSIO_CTRL0, HSIO_APB_RSTN_0); in imx_hsio_sata_power_on()
325 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, in imx_hsio_sata_power_on()
327 regmap_set_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, in imx_hsio_sata_power_on()
330 imx_hsio_sata_phy_resets(phy); in imx_hsio_sata_power_on()
336 priv->base + HSIO_REG48_PMA_STATUS); in imx_hsio_sata_power_on()
338 dev_err(priv->dev, "PHY calibration is timeout\n"); in imx_hsio_sata_power_on()
340 dev_dbg(priv->dev, "PHY calibration is done\n"); in imx_hsio_sata_power_on()
345 static int imx_hsio_power_on(struct phy *phy) in imx_hsio_power_on() argument
349 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_power_on()
350 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_power_on()
352 scoped_guard(mutex, &priv->lock) { in imx_hsio_power_on()
353 if (!priv->open_cnt) in imx_hsio_power_on()
354 imx_hsio_pre_set(phy); in imx_hsio_power_on()
355 priv->open_cnt++; in imx_hsio_power_on()
358 if (lane->phy_mode == PHY_MODE_PCIE) in imx_hsio_power_on()
359 ret = imx_hsio_pcie_power_on(phy); in imx_hsio_power_on()
361 ret = imx_hsio_sata_power_on(phy); in imx_hsio_power_on()
365 /* Polling to check the PHY is ready or not. */ in imx_hsio_power_on()
366 if (lane->idx == 1) in imx_hsio_power_on()
370 * Except the phy_off, the bit-offset of lane2 is same to lane0. in imx_hsio_power_on()
371 * Merge the lane0 and lane2 bit-operations together. in imx_hsio_power_on()
375 ret = regmap_read_poll_timeout(priv->phy, lane->phy_off + HSIO_PHY_STS0, in imx_hsio_power_on()
380 dev_err(priv->dev, "IMX8Q PHY%d PLL lock timeout\n", lane->idx); in imx_hsio_power_on()
383 dev_dbg(priv->dev, "IMX8Q PHY%d PLL is locked\n", lane->idx); in imx_hsio_power_on()
388 static int imx_hsio_power_off(struct phy *phy) in imx_hsio_power_off() argument
390 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_power_off()
391 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_power_off()
393 scoped_guard(mutex, &priv->lock) { in imx_hsio_power_off()
394 priv->open_cnt--; in imx_hsio_power_off()
395 if (priv->open_cnt == 0) { in imx_hsio_power_off()
396 regmap_clear_bits(priv->misc, HSIO_CTRL0, in imx_hsio_power_off()
398 regmap_clear_bits(priv->misc, HSIO_CTRL0, in imx_hsio_power_off()
401 if (lane->phy_mode == PHY_MODE_PCIE) { in imx_hsio_power_off()
402 regmap_clear_bits(priv->ctrl, in imx_hsio_power_off()
403 lane->ctrl_off + HSIO_CTRL2, in imx_hsio_power_off()
405 regmap_clear_bits(priv->ctrl, in imx_hsio_power_off()
406 lane->ctrl_off + HSIO_CTRL2, in imx_hsio_power_off()
408 regmap_clear_bits(priv->ctrl, in imx_hsio_power_off()
409 lane->ctrl_off + HSIO_CTRL2, in imx_hsio_power_off()
412 regmap_clear_bits(priv->ctrl, in imx_hsio_power_off()
413 lane->ctrl_off + HSIO_CTRL0, in imx_hsio_power_off()
415 regmap_clear_bits(priv->ctrl, in imx_hsio_power_off()
416 lane->ctrl_off + HSIO_CTRL0, in imx_hsio_power_off()
418 regmap_clear_bits(priv->ctrl, in imx_hsio_power_off()
419 lane->ctrl_off + HSIO_CTRL0, in imx_hsio_power_off()
423 if (lane->idx == 1) { in imx_hsio_power_off()
424 regmap_clear_bits(priv->phy, in imx_hsio_power_off()
425 lane->phy_off + HSIO_CTRL0, in imx_hsio_power_off()
427 regmap_clear_bits(priv->phy, in imx_hsio_power_off()
428 lane->phy_off + HSIO_CTRL0, in imx_hsio_power_off()
432 * Except the phy_off, the bit-offset of lane2 is same in imx_hsio_power_off()
433 * to lane0. Merge the lane0 and lane2 bit-operations in imx_hsio_power_off()
436 regmap_clear_bits(priv->phy, in imx_hsio_power_off()
437 lane->phy_off + HSIO_CTRL0, in imx_hsio_power_off()
439 regmap_clear_bits(priv->phy, in imx_hsio_power_off()
440 lane->phy_off + HSIO_CTRL0, in imx_hsio_power_off()
449 static int imx_hsio_set_mode(struct phy *phy, enum phy_mode mode, in imx_hsio_set_mode() argument
453 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_set_mode()
454 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_set_mode()
456 if (lane->phy_mode != mode) in imx_hsio_set_mode()
457 return -EINVAL; in imx_hsio_set_mode()
461 regmap_update_bits(priv->phy, lane->phy_off + HSIO_CTRL0, in imx_hsio_set_mode()
471 default: /* Support only PCIe EP and RC now. */ in imx_hsio_set_mode()
475 regmap_update_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL0, in imx_hsio_set_mode()
481 static int imx_hsio_set_speed(struct phy *phy, int speed) in imx_hsio_set_speed() argument
483 struct imx_hsio_lane *lane = phy_get_drvdata(phy); in imx_hsio_set_speed()
484 struct imx_hsio_priv *priv = lane->priv; in imx_hsio_set_speed()
486 regmap_update_bits(priv->ctrl, lane->ctrl_off + HSIO_CTRL2, in imx_hsio_set_speed()
511 {.compatible = "fsl,imx8qm-hsio", .data = &imx8qm_hsio_drvdata},
512 {.compatible = "fsl,imx8qxp-hsio", .data = &imx8qxp_hsio_drvdata},
517 static struct phy *imx_hsio_xlate(struct device *dev, in imx_hsio_xlate()
521 int idx = args->args[0]; in imx_hsio_xlate()
522 int phy_type = args->args[1]; in imx_hsio_xlate()
523 int ctrl_index = args->args[2]; in imx_hsio_xlate()
525 if (idx < 0 || idx >= priv->drvdata->lane_num) in imx_hsio_xlate()
526 return ERR_PTR(-EINVAL); in imx_hsio_xlate()
527 priv->lane[idx].idx = idx; in imx_hsio_xlate()
528 priv->lane[idx].phy_type = phy_type; in imx_hsio_xlate()
529 priv->lane[idx].ctrl_index = ctrl_index; in imx_hsio_xlate()
531 return priv->lane[idx].phy; in imx_hsio_xlate()
538 struct device *dev = &pdev->dev; in imx_hsio_probe()
539 struct device_node *np = dev->of_node; in imx_hsio_probe()
543 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in imx_hsio_probe()
545 return -ENOMEM; in imx_hsio_probe()
546 priv->dev = &pdev->dev; in imx_hsio_probe()
547 priv->drvdata = of_device_get_match_data(dev); in imx_hsio_probe()
550 if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg)) in imx_hsio_probe()
551 priv->hsio_cfg = "pciea-pcieb-sata"; in imx_hsio_probe()
552 /* Get PHY refclk pad mode */ in imx_hsio_probe()
553 if (of_property_read_string(np, "fsl,refclk-pad-mode", in imx_hsio_probe()
554 &priv->refclk_pad)) in imx_hsio_probe()
555 priv->refclk_pad = NULL; in imx_hsio_probe()
557 priv->base = devm_platform_ioremap_resource(pdev, 0); in imx_hsio_probe()
558 if (IS_ERR(priv->base)) in imx_hsio_probe()
559 return PTR_ERR(priv->base); in imx_hsio_probe()
561 off = devm_platform_ioremap_resource_byname(pdev, "phy"); in imx_hsio_probe()
562 priv->phy = devm_regmap_init_mmio(dev, off, ®map_config); in imx_hsio_probe()
563 if (IS_ERR(priv->phy)) in imx_hsio_probe()
564 return dev_err_probe(dev, PTR_ERR(priv->phy), in imx_hsio_probe()
565 "unable to find phy csr registers\n"); in imx_hsio_probe()
568 priv->ctrl = devm_regmap_init_mmio(dev, off, ®map_config); in imx_hsio_probe()
569 if (IS_ERR(priv->ctrl)) in imx_hsio_probe()
570 return dev_err_probe(dev, PTR_ERR(priv->ctrl), in imx_hsio_probe()
574 priv->misc = devm_regmap_init_mmio(dev, off, ®map_config); in imx_hsio_probe()
575 if (IS_ERR(priv->misc)) in imx_hsio_probe()
576 return dev_err_probe(dev, PTR_ERR(priv->misc), in imx_hsio_probe()
579 for (i = 0; i < priv->drvdata->lane_num; i++) { in imx_hsio_probe()
580 struct imx_hsio_lane *lane = &priv->lane[i]; in imx_hsio_probe()
581 struct phy *phy; in imx_hsio_probe() local
583 phy = devm_phy_create(&pdev->dev, NULL, &imx_hsio_ops); in imx_hsio_probe()
584 if (IS_ERR(phy)) in imx_hsio_probe()
585 return PTR_ERR(phy); in imx_hsio_probe()
587 lane->priv = priv; in imx_hsio_probe()
588 lane->phy = phy; in imx_hsio_probe()
589 lane->idx = i; in imx_hsio_probe()
590 phy_set_drvdata(phy, lane); in imx_hsio_probe()
594 dev_set_drvdata(&pdev->dev, priv); in imx_hsio_probe()
596 provider = devm_of_phy_provider_register(&pdev->dev, imx_hsio_xlate); in imx_hsio_probe()
604 .name = "imx8qm-hsio-phy",
610 MODULE_DESCRIPTION("FSL IMX8QM HSIO SERDES PHY driver");