xref: /openbmc/linux/drivers/phy/broadcom/phy-bcm-ns2-pcie.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1*2aec85b2SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2*2aec85b2SThomas Gleixner // Copyright (C) 2016 Broadcom
30b56e9a7SVivek Gautam 
40b56e9a7SVivek Gautam #include <linux/device.h>
50b56e9a7SVivek Gautam #include <linux/module.h>
60b56e9a7SVivek Gautam #include <linux/of_mdio.h>
70b56e9a7SVivek Gautam #include <linux/mdio.h>
80b56e9a7SVivek Gautam #include <linux/phy.h>
90b56e9a7SVivek Gautam #include <linux/phy/phy.h>
100b56e9a7SVivek Gautam 
110b56e9a7SVivek Gautam #define BLK_ADDR_REG_OFFSET	0x1f
120b56e9a7SVivek Gautam #define PLL_AFE1_100MHZ_BLK	0x2100
130b56e9a7SVivek Gautam #define PLL_CLK_AMP_OFFSET	0x03
140b56e9a7SVivek Gautam #define PLL_CLK_AMP_2P05V	0x2b18
150b56e9a7SVivek Gautam 
ns2_pci_phy_init(struct phy * p)160b56e9a7SVivek Gautam static int ns2_pci_phy_init(struct phy *p)
170b56e9a7SVivek Gautam {
180b56e9a7SVivek Gautam 	struct mdio_device *mdiodev = phy_get_drvdata(p);
190b56e9a7SVivek Gautam 	int rc;
200b56e9a7SVivek Gautam 
210b56e9a7SVivek Gautam 	/* select the AFE 100MHz block page */
2265aa371eSSean Anderson 	rc = mdiodev_write(mdiodev, BLK_ADDR_REG_OFFSET, PLL_AFE1_100MHZ_BLK);
230b56e9a7SVivek Gautam 	if (rc)
240b56e9a7SVivek Gautam 		goto err;
250b56e9a7SVivek Gautam 
260b56e9a7SVivek Gautam 	/* set the 100 MHz reference clock amplitude to 2.05 v */
2765aa371eSSean Anderson 	rc = mdiodev_write(mdiodev, PLL_CLK_AMP_OFFSET, PLL_CLK_AMP_2P05V);
280b56e9a7SVivek Gautam 	if (rc)
290b56e9a7SVivek Gautam 		goto err;
300b56e9a7SVivek Gautam 
310b56e9a7SVivek Gautam 	return 0;
320b56e9a7SVivek Gautam 
330b56e9a7SVivek Gautam err:
340b56e9a7SVivek Gautam 	dev_err(&mdiodev->dev, "Error %d writing to phy\n", rc);
350b56e9a7SVivek Gautam 	return rc;
360b56e9a7SVivek Gautam }
370b56e9a7SVivek Gautam 
380b56e9a7SVivek Gautam static const struct phy_ops ns2_pci_phy_ops = {
390b56e9a7SVivek Gautam 	.init = ns2_pci_phy_init,
400b56e9a7SVivek Gautam 	.owner = THIS_MODULE,
410b56e9a7SVivek Gautam };
420b56e9a7SVivek Gautam 
ns2_pci_phy_probe(struct mdio_device * mdiodev)430b56e9a7SVivek Gautam static int ns2_pci_phy_probe(struct mdio_device *mdiodev)
440b56e9a7SVivek Gautam {
450b56e9a7SVivek Gautam 	struct device *dev = &mdiodev->dev;
460b56e9a7SVivek Gautam 	struct phy_provider *provider;
470b56e9a7SVivek Gautam 	struct phy *phy;
480b56e9a7SVivek Gautam 
490b56e9a7SVivek Gautam 	phy = devm_phy_create(dev, dev->of_node, &ns2_pci_phy_ops);
500b56e9a7SVivek Gautam 	if (IS_ERR(phy)) {
510b56e9a7SVivek Gautam 		dev_err(dev, "failed to create Phy\n");
520b56e9a7SVivek Gautam 		return PTR_ERR(phy);
530b56e9a7SVivek Gautam 	}
540b56e9a7SVivek Gautam 
550b56e9a7SVivek Gautam 	phy_set_drvdata(phy, mdiodev);
560b56e9a7SVivek Gautam 
570b56e9a7SVivek Gautam 	provider = devm_of_phy_provider_register(&phy->dev,
580b56e9a7SVivek Gautam 						 of_phy_simple_xlate);
590b56e9a7SVivek Gautam 	if (IS_ERR(provider)) {
600b56e9a7SVivek Gautam 		dev_err(dev, "failed to register Phy provider\n");
610b56e9a7SVivek Gautam 		return PTR_ERR(provider);
620b56e9a7SVivek Gautam 	}
630b56e9a7SVivek Gautam 
640b56e9a7SVivek Gautam 	dev_info(dev, "%s PHY registered\n", dev_name(dev));
650b56e9a7SVivek Gautam 
660b56e9a7SVivek Gautam 	return 0;
670b56e9a7SVivek Gautam }
680b56e9a7SVivek Gautam 
690b56e9a7SVivek Gautam static const struct of_device_id ns2_pci_phy_of_match[] = {
700b56e9a7SVivek Gautam 	{ .compatible = "brcm,ns2-pcie-phy", },
710b56e9a7SVivek Gautam 	{ /* sentinel */ },
720b56e9a7SVivek Gautam };
730b56e9a7SVivek Gautam MODULE_DEVICE_TABLE(of, ns2_pci_phy_of_match);
740b56e9a7SVivek Gautam 
750b56e9a7SVivek Gautam static struct mdio_driver ns2_pci_phy_driver = {
760b56e9a7SVivek Gautam 	.mdiodrv = {
770b56e9a7SVivek Gautam 		.driver = {
780b56e9a7SVivek Gautam 			.name = "phy-bcm-ns2-pci",
790b56e9a7SVivek Gautam 			.of_match_table = ns2_pci_phy_of_match,
800b56e9a7SVivek Gautam 		},
810b56e9a7SVivek Gautam 	},
820b56e9a7SVivek Gautam 	.probe = ns2_pci_phy_probe,
830b56e9a7SVivek Gautam };
840b56e9a7SVivek Gautam mdio_module_driver(ns2_pci_phy_driver);
850b56e9a7SVivek Gautam 
860b56e9a7SVivek Gautam MODULE_AUTHOR("Broadcom");
870b56e9a7SVivek Gautam MODULE_DESCRIPTION("Broadcom Northstar2 PCI Phy driver");
880b56e9a7SVivek Gautam MODULE_LICENSE("GPL v2");
890b56e9a7SVivek Gautam MODULE_ALIAS("platform:phy-bcm-ns2-pci");
90