1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/module.h> 4 #include <linux/platform_device.h> 5 #include <linux/regmap.h> 6 7 #include <linux/slab.h> 8 #include <linux/of.h> 9 #include <linux/io.h> 10 #include <linux/usb/phy_companion.h> 11 #include <linux/clk.h> 12 #include <linux/err.h> 13 #include <linux/pm_runtime.h> 14 #include <linux/delay.h> 15 #include <linux/phy/phy.h> 16 #include <linux/of_platform.h> 17 18 #include <linux/mfd/syscon.h> 19 20 /* 21 * TRM has two sets of USB_CTRL registers.. The correct register bits 22 * are in TRM section 24.9.8.2 USB_CTRL Register. The TRM documents the 23 * phy as being SR70LX Synopsys USB 2.0 OTG nanoPHY. It also seems at 24 * least dm816x rev c ignores writes to USB_CTRL register, but the TI 25 * kernel is writing to those so it's possible that later revisions 26 * have worknig USB_CTRL register. 27 * 28 * Also note that At least USB_CTRL register seems to be dm816x specific 29 * according to the TRM. It's possible that USBPHY_CTRL is more generic, 30 * but that would have to be checked against the SR70LX documentation 31 * which does not seem to be publicly available. 32 * 33 * Finally, the phy on dm814x and am335x is different from dm816x. 34 */ 35 #define DM816X_USB_CTRL_PHYCLKSRC BIT(8) /* 1 = PLL ref clock */ 36 #define DM816X_USB_CTRL_PHYSLEEP1 BIT(1) /* Enable the first phy */ 37 #define DM816X_USB_CTRL_PHYSLEEP0 BIT(0) /* Enable the second phy */ 38 39 #define DM816X_USBPHY_CTRL_TXRISETUNE 1 40 #define DM816X_USBPHY_CTRL_TXVREFTUNE 0xc 41 #define DM816X_USBPHY_CTRL_TXPREEMTUNE 0x2 42 43 struct dm816x_usb_phy { 44 struct regmap *syscon; 45 struct device *dev; 46 unsigned int instance; 47 struct clk *refclk; 48 struct usb_phy phy; 49 unsigned int usb_ctrl; /* Shared between phy0 and phy1 */ 50 unsigned int usbphy_ctrl; 51 }; 52 53 static int dm816x_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host) 54 { 55 otg->host = host; 56 if (!host) 57 otg->state = OTG_STATE_UNDEFINED; 58 59 return 0; 60 } 61 62 static int dm816x_usb_phy_set_peripheral(struct usb_otg *otg, 63 struct usb_gadget *gadget) 64 { 65 otg->gadget = gadget; 66 if (!gadget) 67 otg->state = OTG_STATE_UNDEFINED; 68 69 return 0; 70 } 71 72 static int dm816x_usb_phy_init(struct phy *x) 73 { 74 struct dm816x_usb_phy *phy = phy_get_drvdata(x); 75 unsigned int val; 76 77 if (clk_get_rate(phy->refclk) != 24000000) 78 dev_warn(phy->dev, "nonstandard phy refclk\n"); 79 80 /* Set PLL ref clock and put phys to sleep */ 81 regmap_update_bits(phy->syscon, phy->usb_ctrl, 82 DM816X_USB_CTRL_PHYCLKSRC | 83 DM816X_USB_CTRL_PHYSLEEP1 | 84 DM816X_USB_CTRL_PHYSLEEP0, 85 0); 86 regmap_read(phy->syscon, phy->usb_ctrl, &val); 87 if ((val & 3) != 0) 88 dev_info(phy->dev, 89 "Working dm816x USB_CTRL! (0x%08x)\n", 90 val); 91 92 /* 93 * TI kernel sets these values for "symmetrical eye diagram and 94 * better signal quality" so let's assume somebody checked the 95 * values with a scope and set them here too. 96 */ 97 regmap_read(phy->syscon, phy->usbphy_ctrl, &val); 98 val |= DM816X_USBPHY_CTRL_TXRISETUNE | 99 DM816X_USBPHY_CTRL_TXVREFTUNE | 100 DM816X_USBPHY_CTRL_TXPREEMTUNE; 101 regmap_write(phy->syscon, phy->usbphy_ctrl, val); 102 103 return 0; 104 } 105 106 static const struct phy_ops ops = { 107 .init = dm816x_usb_phy_init, 108 .owner = THIS_MODULE, 109 }; 110 111 static int __maybe_unused dm816x_usb_phy_runtime_suspend(struct device *dev) 112 { 113 struct dm816x_usb_phy *phy = dev_get_drvdata(dev); 114 unsigned int mask, val; 115 int error = 0; 116 117 mask = BIT(phy->instance); 118 val = ~BIT(phy->instance); 119 error = regmap_update_bits(phy->syscon, phy->usb_ctrl, 120 mask, val); 121 if (error) 122 dev_err(phy->dev, "phy%i failed to power off\n", 123 phy->instance); 124 clk_disable(phy->refclk); 125 126 return 0; 127 } 128 129 static int __maybe_unused dm816x_usb_phy_runtime_resume(struct device *dev) 130 { 131 struct dm816x_usb_phy *phy = dev_get_drvdata(dev); 132 unsigned int mask, val; 133 int error; 134 135 error = clk_enable(phy->refclk); 136 if (error) 137 return error; 138 139 /* 140 * Note that at least dm816x rev c does not seem to do 141 * anything with the USB_CTRL register. But let's follow 142 * what the TI tree is doing in case later revisions use 143 * USB_CTRL. 144 */ 145 mask = BIT(phy->instance); 146 val = BIT(phy->instance); 147 error = regmap_update_bits(phy->syscon, phy->usb_ctrl, 148 mask, val); 149 if (error) { 150 dev_err(phy->dev, "phy%i failed to power on\n", 151 phy->instance); 152 clk_disable(phy->refclk); 153 return error; 154 } 155 156 return 0; 157 } 158 159 static UNIVERSAL_DEV_PM_OPS(dm816x_usb_phy_pm_ops, 160 dm816x_usb_phy_runtime_suspend, 161 dm816x_usb_phy_runtime_resume, 162 NULL); 163 164 #ifdef CONFIG_OF 165 static const struct of_device_id dm816x_usb_phy_id_table[] = { 166 { 167 .compatible = "ti,dm8168-usb-phy", 168 }, 169 {}, 170 }; 171 MODULE_DEVICE_TABLE(of, dm816x_usb_phy_id_table); 172 #endif 173 174 static int dm816x_usb_phy_probe(struct platform_device *pdev) 175 { 176 struct dm816x_usb_phy *phy; 177 struct resource *res; 178 struct phy *generic_phy; 179 struct phy_provider *phy_provider; 180 struct usb_otg *otg; 181 const struct of_device_id *of_id; 182 int error; 183 184 of_id = of_match_device(of_match_ptr(dm816x_usb_phy_id_table), 185 &pdev->dev); 186 if (!of_id) 187 return -EINVAL; 188 189 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 190 if (!phy) 191 return -ENOMEM; 192 193 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 194 if (!res) 195 return -ENOENT; 196 197 phy->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 198 "syscon"); 199 if (IS_ERR(phy->syscon)) 200 return PTR_ERR(phy->syscon); 201 202 /* 203 * According to sprs614e.pdf, the first usb_ctrl is shared and 204 * the second instance for usb_ctrl is reserved.. Also the 205 * register bits are different from earlier TRMs. 206 */ 207 phy->usb_ctrl = 0x20; 208 phy->usbphy_ctrl = (res->start & 0xff) + 4; 209 if (phy->usbphy_ctrl == 0x2c) 210 phy->instance = 1; 211 212 otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL); 213 if (!otg) 214 return -ENOMEM; 215 216 phy->dev = &pdev->dev; 217 phy->phy.dev = phy->dev; 218 phy->phy.label = "dm8168_usb_phy"; 219 phy->phy.otg = otg; 220 phy->phy.type = USB_PHY_TYPE_USB2; 221 otg->set_host = dm816x_usb_phy_set_host; 222 otg->set_peripheral = dm816x_usb_phy_set_peripheral; 223 otg->usb_phy = &phy->phy; 224 225 platform_set_drvdata(pdev, phy); 226 227 phy->refclk = devm_clk_get(phy->dev, "refclk"); 228 if (IS_ERR(phy->refclk)) 229 return PTR_ERR(phy->refclk); 230 error = clk_prepare(phy->refclk); 231 if (error) 232 return error; 233 234 pm_runtime_enable(phy->dev); 235 generic_phy = devm_phy_create(phy->dev, NULL, &ops); 236 if (IS_ERR(generic_phy)) { 237 error = PTR_ERR(generic_phy); 238 goto clk_unprepare; 239 } 240 241 phy_set_drvdata(generic_phy, phy); 242 243 phy_provider = devm_of_phy_provider_register(phy->dev, 244 of_phy_simple_xlate); 245 if (IS_ERR(phy_provider)) { 246 error = PTR_ERR(phy_provider); 247 goto clk_unprepare; 248 } 249 250 usb_add_phy_dev(&phy->phy); 251 252 return 0; 253 254 clk_unprepare: 255 pm_runtime_disable(phy->dev); 256 clk_unprepare(phy->refclk); 257 return error; 258 } 259 260 static void dm816x_usb_phy_remove(struct platform_device *pdev) 261 { 262 struct dm816x_usb_phy *phy = platform_get_drvdata(pdev); 263 264 usb_remove_phy(&phy->phy); 265 pm_runtime_disable(phy->dev); 266 clk_unprepare(phy->refclk); 267 } 268 269 static struct platform_driver dm816x_usb_phy_driver = { 270 .probe = dm816x_usb_phy_probe, 271 .remove_new = dm816x_usb_phy_remove, 272 .driver = { 273 .name = "dm816x-usb-phy", 274 .pm = &dm816x_usb_phy_pm_ops, 275 .of_match_table = of_match_ptr(dm816x_usb_phy_id_table), 276 }, 277 }; 278 279 module_platform_driver(dm816x_usb_phy_driver); 280 281 MODULE_ALIAS("platform:dm816x_usb"); 282 MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); 283 MODULE_DESCRIPTION("dm816x usb phy driver"); 284 MODULE_LICENSE("GPL v2"); 285