Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.11-rc2 177 lines 4.3 kB view raw
1/* 2 * Copyright (C) 2016 Broadcom 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation version 2. 7 * 8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 * kind, whether express or implied; without even the implied warranty 10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14#include <linux/delay.h> 15#include <linux/io.h> 16#include <linux/kernel.h> 17#include <linux/mfd/syscon.h> 18#include <linux/mdio.h> 19#include <linux/module.h> 20#include <linux/of.h> 21#include <linux/of_address.h> 22#include <linux/phy/phy.h> 23#include <linux/regmap.h> 24 25#define NSP_USB3_RST_CTRL_OFFSET 0x3f8 26 27/* mdio reg access */ 28#define NSP_USB3_PHY_BASE_ADDR_REG 0x1f 29 30#define NSP_USB3_PHY_PLL30_BLOCK 0x8000 31#define NSP_USB3_PLL_CONTROL 0x01 32#define NSP_USB3_PLLA_CONTROL0 0x0a 33#define NSP_USB3_PLLA_CONTROL1 0x0b 34 35#define NSP_USB3_PHY_TX_PMD_BLOCK 0x8040 36#define NSP_USB3_TX_PMD_CONTROL1 0x01 37 38#define NSP_USB3_PHY_PIPE_BLOCK 0x8060 39#define NSP_USB3_LFPS_CMP 0x02 40#define NSP_USB3_LFPS_DEGLITCH 0x03 41 42struct nsp_usb3_phy { 43 struct regmap *usb3_ctrl; 44 struct phy *phy; 45 struct mdio_device *mdiodev; 46}; 47 48static int nsp_usb3_phy_init(struct phy *phy) 49{ 50 struct nsp_usb3_phy *iphy = phy_get_drvdata(phy); 51 struct mii_bus *bus = iphy->mdiodev->bus; 52 int addr = iphy->mdiodev->addr; 53 u32 data; 54 int rc; 55 56 rc = regmap_read(iphy->usb3_ctrl, 0, &data); 57 if (rc) 58 return rc; 59 data |= 1; 60 rc = regmap_write(iphy->usb3_ctrl, 0, data); 61 if (rc) 62 return rc; 63 64 rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 1); 65 if (rc) 66 return rc; 67 68 rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG, 69 NSP_USB3_PHY_PLL30_BLOCK); 70 if (rc) 71 return rc; 72 73 rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x1000); 74 if (rc) 75 return rc; 76 77 rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL0, 0x6400); 78 if (rc) 79 return rc; 80 81 rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0xc000); 82 if (rc) 83 return rc; 84 85 rc = mdiobus_write(bus, addr, NSP_USB3_PLLA_CONTROL1, 0x8000); 86 if (rc) 87 return rc; 88 89 rc = regmap_write(iphy->usb3_ctrl, NSP_USB3_RST_CTRL_OFFSET, 0); 90 if (rc) 91 return rc; 92 93 rc = mdiobus_write(bus, addr, NSP_USB3_PLL_CONTROL, 0x9000); 94 if (rc) 95 return rc; 96 97 rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG, 98 NSP_USB3_PHY_PIPE_BLOCK); 99 if (rc) 100 return rc; 101 102 rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_CMP, 0xf30d); 103 if (rc) 104 return rc; 105 106 rc = mdiobus_write(bus, addr, NSP_USB3_LFPS_DEGLITCH, 0x6302); 107 if (rc) 108 return rc; 109 110 rc = mdiobus_write(bus, addr, NSP_USB3_PHY_BASE_ADDR_REG, 111 NSP_USB3_PHY_TX_PMD_BLOCK); 112 if (rc) 113 return rc; 114 115 rc = mdiobus_write(bus, addr, NSP_USB3_TX_PMD_CONTROL1, 0x1003); 116 117 return rc; 118} 119 120static struct phy_ops nsp_usb3_phy_ops = { 121 .init = nsp_usb3_phy_init, 122 .owner = THIS_MODULE, 123}; 124 125static int nsp_usb3_phy_probe(struct mdio_device *mdiodev) 126{ 127 struct device *dev = &mdiodev->dev; 128 struct phy_provider *provider; 129 struct nsp_usb3_phy *iphy; 130 131 iphy = devm_kzalloc(dev, sizeof(*iphy), GFP_KERNEL); 132 if (!iphy) 133 return -ENOMEM; 134 iphy->mdiodev = mdiodev; 135 136 iphy->usb3_ctrl = syscon_regmap_lookup_by_phandle(dev->of_node, 137 "usb3-ctrl-syscon"); 138 if (IS_ERR(iphy->usb3_ctrl)) 139 return PTR_ERR(iphy->usb3_ctrl); 140 141 iphy->phy = devm_phy_create(dev, dev->of_node, &nsp_usb3_phy_ops); 142 if (IS_ERR(iphy->phy)) { 143 dev_err(dev, "failed to create PHY\n"); 144 return PTR_ERR(iphy->phy); 145 } 146 147 phy_set_drvdata(iphy->phy, iphy); 148 149 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 150 if (IS_ERR(provider)) { 151 dev_err(dev, "could not register PHY provider\n"); 152 return PTR_ERR(provider); 153 } 154 155 return 0; 156} 157 158static const struct of_device_id nsp_usb3_phy_of_match[] = { 159 {.compatible = "brcm,nsp-usb3-phy",}, 160 { /* sentinel */ } 161}; 162 163static struct mdio_driver nsp_usb3_phy_driver = { 164 .mdiodrv = { 165 .driver = { 166 .name = "nsp-usb3-phy", 167 .of_match_table = nsp_usb3_phy_of_match, 168 }, 169 }, 170 .probe = nsp_usb3_phy_probe, 171}; 172 173mdio_module_driver(nsp_usb3_phy_driver); 174 175MODULE_DESCRIPTION("Broadcom NSP USB3 PHY driver"); 176MODULE_LICENSE("GPL v2"); 177MODULE_AUTHOR("Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com");